Gnumed.wxpython.gmGuiHelpers

Package Gnumed :: Package wxpython :: Module gmGuiHelpers |
[frames] | no frames]

# Source Code for Module Gnumed.wxpython.gmGuiHelpers

      1  """GNUmed GUI helper classes and functions.
      2
      3  This module provides some convenient wxPython GUI
      4  helper thingies that are widely used throughout
      5  GNUmed.
      6  """
      7  # ========================================================================
      8  __author__  = "K. Hilbert <Karsten.Hilbert@gmx.net>"
      9  __license__ = "GPL v2 or later (details at http://www.gnu.org)"
     10
     11  import os
     12  import logging
     13  import sys
     14  import io
     15  import time
     16  import datetime as pyDT
     17
     18
     19  import wx
     20
     21
     22  if __name__ == '__main__':
     23          sys.path.insert(0, '../../')
     24  from Gnumed.pycommon import gmMatchProvider
     25  from Gnumed.pycommon import gmExceptions
     26  from Gnumed.pycommon import gmLog2
     27  from Gnumed.pycommon import gmTools
     28  from Gnumed.pycommon import gmDispatcher
     29  from Gnumed.wxpython import gmPhraseWheel
     30
     31
     32  _log = logging.getLogger('gm.main')
     33  # ========================================================================
     34 -class cThreeValuedLogicPhraseWheel(gmPhraseWheel.cPhraseWheel):
     35
     36 -        def __init__(self, *args, **kwargs):
     37
     38                  gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
     39
     40                  items = [
     41                          {'list_label': _('Yes: + / ! / 1'), 'field_label': _('yes'), 'data': True, 'weight': 0},
     42                          {'list_label': _('No: - / 0'), 'field_label': _('no'), 'data': False, 'weight': 1},
     43                          {'list_label': _('Unknown: ?'), 'field_label': _('unknown'), 'data': None, 'weight': 2},
     44                  ]
     45                  mp = gmMatchProvider.cMatchProvider_FixedList(items)
     46                  mp.setThresholds(1, 1, 2)
     47                  mp.word_separators = '[ :/]+'
     48                  mp.word_separators = None
     49                  mp.ignored_chars = r"[.'\\(){}\[\]<>~#*$%^_=&@\t23456]+" + r'"'
     50
     51                  self.matcher = mp
     52  # ========================================================================
     53  from Gnumed.wxGladeWidgets import wxg2ButtonQuestionDlg
     54
     55 -class c2ButtonQuestionDlg(wxg2ButtonQuestionDlg.wxg2ButtonQuestionDlg):
     56
     57 -        def __init__(self, *args, **kwargs):
     58
     59                  caption = kwargs['caption']
     60                  question = kwargs['question']
     61                  button_defs = kwargs['button_defs'][:2]
     62                  del kwargs['caption']
     63                  del kwargs['question']
     64                  del kwargs['button_defs']
     65
     66                  try:
     67                          show_checkbox = kwargs['show_checkbox']
     68                          del kwargs['show_checkbox']
     69                  except KeyError:
     70                          show_checkbox = False
     71
     72                  try:
     73                          checkbox_msg = kwargs['checkbox_msg']
     74                          del kwargs['checkbox_msg']
     75                  except KeyError:
     76                          checkbox_msg = None
     77
     78                  try:
     79                          checkbox_tooltip = kwargs['checkbox_tooltip']
     80                          del kwargs['checkbox_tooltip']
     81                  except KeyError:
     82                          checkbox_tooltip = None
     83
     84                  wxg2ButtonQuestionDlg.wxg2ButtonQuestionDlg.__init__(self, *args, **kwargs)
     85
     86                  self.SetTitle(title = gmTools.decorate_window_title(caption))
     87                  self._LBL_question.SetLabel(label = question)
     88
     89                  if not show_checkbox:
     90                          self._CHBOX_dont_ask_again.Hide()
     91                  else:
     92                          if checkbox_msg is not None:
     93                                  self._CHBOX_dont_ask_again.SetLabel(checkbox_msg)
     94                          if checkbox_tooltip is not None:
     95                                  self._CHBOX_dont_ask_again.SetToolTip(checkbox_tooltip)
     96
     97                  buttons = [self._BTN_1, self._BTN_2]
     98                  for idx in range(len(button_defs)):
     99                          buttons[idx].SetLabel(label = button_defs[idx]['label'])
    100                          buttons[idx].SetToolTip(button_defs[idx]['tooltip'])
    101                          try:
    102                                  if button_defs[idx]['default'] is True:
    103                                          buttons[idx].SetDefault()
    104                                          buttons[idx].SetFocus()
    105                          except KeyError:
    106                                  pass
    107
    108                  self.Fit()
    109          #--------------------------------------------------------
    110 -        def checkbox_is_checked(self):
    111                  return self._CHBOX_dont_ask_again.IsChecked()
    112          #--------------------------------------------------------
    113          # event handlers
    114          #--------------------------------------------------------
    115 -        def _on_BTN_1_pressed(self, evt):
    116                  if self.IsModal():
    117                          self.EndModal(wx.ID_YES)
    118                  else:
    119                          self.Close()
    120          #--------------------------------------------------------
    121 -        def _on_BTN_2_pressed(self, evt):
    122                  if self.IsModal():
    123                          self.EndModal(wx.ID_NO)
    124                  else:
    125                          self.Close()
    126
    127  # ========================================================================
    128  from Gnumed.wxGladeWidgets import wxg3ButtonQuestionDlg
    129
    130 -class c3ButtonQuestionDlg(wxg3ButtonQuestionDlg.wxg3ButtonQuestionDlg):
    131
    132 -        def __init__(self, *args, **kwargs):
    133                  """Initialize.
    134
    135          button_defs = [
    136                  # tooltip and default are optional
    137                  {'label': _(''), 'tooltip': _(''), 'default': True/False},
    138                  {'label': _(''), 'tooltip': _(''), 'default': True/False},
    139                  {'label': _(''), 'tooltip': _(''), 'default': True/False}
    140          ]
    141                  """
    142                  caption = kwargs['caption']
    143                  question = kwargs['question']
    144                  button_defs = kwargs['button_defs'][:3]
    145                  del kwargs['caption']
    146                  del kwargs['question']
    147                  del kwargs['button_defs']
    148
    149                  try:
    150                          show_checkbox = kwargs['show_checkbox']
    151                          del kwargs['show_checkbox']
    152                  except KeyError:
    153                          show_checkbox = False
    154
    155                  try:
    156                          checkbox_msg = kwargs['checkbox_msg']
    157                          del kwargs['checkbox_msg']
    158                  except KeyError:
    159                          checkbox_msg = None
    160
    161                  try:
    162                          checkbox_tooltip = kwargs['checkbox_tooltip']
    163                          del kwargs['checkbox_tooltip']
    164                  except KeyError:
    165                          checkbox_tooltip = None
    166
    167                  wxg3ButtonQuestionDlg.wxg3ButtonQuestionDlg.__init__(self, *args, **kwargs)
    168
    169                  self.SetTitle(title = gmTools.decorate_window_title(caption))
    170                  self._LBL_question.SetLabel(label = question)
    171
    172                  if not show_checkbox:
    173                          self._CHBOX_dont_ask_again.Hide()
    174                  else:
    175                          if checkbox_msg is not None:
    176                                  self._CHBOX_dont_ask_again.SetLabel(checkbox_msg)
    177                          if checkbox_tooltip is not None:
    178                                  self._CHBOX_dont_ask_again.SetToolTip(checkbox_tooltip)
    179
    180                  buttons = [self._BTN_1, self._BTN_2, self._BTN_3]
    181                  for idx in range(len(button_defs)):
    182                          buttons[idx].SetLabel(label = button_defs[idx]['label'])
    183                          try:
    184                                  buttons[idx].SetToolTip(button_defs[idx]['tooltip'])
    185                          except KeyError:
    186                                  pass
    187                          try:
    188                                  if button_defs[idx]['default'] is True:
    189                                          buttons[idx].SetDefault()
    190                                          buttons[idx].SetFocus()
    191                          except KeyError:
    192                                  pass
    193
    194                  self.Fit()
    195          #--------------------------------------------------------
    196 -        def checkbox_is_checked(self):
    197                  return self._CHBOX_dont_ask_again.IsChecked()
    198
    199          #--------------------------------------------------------
    200          # event handlers
    201          #--------------------------------------------------------
    202 -        def _on_BTN_1_pressed(self, evt):
    203                  if self.IsModal():
    204                          self.EndModal(wx.ID_YES)
    205                  else:
    206                          self.Close()
    207
    208          #--------------------------------------------------------
    209 -        def _on_BTN_2_pressed(self, evt):
    210                  if self.IsModal():
    211                          self.EndModal(wx.ID_NO)
    212                  else:
    213                          self.Close()
    214
    215  # ========================================================================
    216  from Gnumed.wxGladeWidgets import wxgMultilineTextEntryDlg
    217
    218 -class cMultilineTextEntryDlg(wxgMultilineTextEntryDlg.wxgMultilineTextEntryDlg):
    219          """Editor for a bit of text."""
    220
    221 -        def __init__(self, *args, **kwargs):
    222
    223                  try:
    224                          title = kwargs['title']
    225                          del kwargs['title']
    226                  except KeyError:
    227                          title = None
    228
    229                  try:
    230                          msg = kwargs['msg']
    231                          del kwargs['msg']
    232                  except KeyError:
    233                          msg = None
    234
    235                  try:
    236                          data = kwargs['data']
    237                          del kwargs['data']
    238                  except KeyError:
    239                          data = None
    240
    241                  try:
    242                          self.original_text = kwargs['text']
    243                          del kwargs['text']
    244                  except KeyError:
    245                          self.original_text = None
    246
    247                  wxgMultilineTextEntryDlg.wxgMultilineTextEntryDlg.__init__(self, *args, **kwargs)
    248
    249                  if title is not None:
    250                          self.SetTitle(gmTools.decorate_window_title(title))
    251
    252                  if self.original_text is not None:
    253                          self._TCTRL_text.SetValue(self.original_text)
    254                          self._BTN_restore.Enable(True)
    255
    256                  if msg is None:
    257                          self._LBL_msg.Hide()
    258                  else:
    259                          self._LBL_msg.SetLabel(msg)
    260                          self.Layout()
    261                          self.Refresh()
    262
    263                  if data is None:
    264                          self._TCTRL_data.Hide()
    265                  else:
    266                          self._TCTRL_data.SetValue(data)
    267                          self.Layout()
    268                          self.Refresh()
    269
    270                  self._TCTRL_text.SetFocus()
    271          #--------------------------------------------------------
    272          # properties
    273          #--------------------------------------------------------
    274 -        def _get_value(self):
    275                  return self._TCTRL_text.GetValue()
    276
    277          value = property(_get_value, lambda x:x)
    278          #--------------------------------------------------------
    279 -        def _get_is_user_formatted(self):
    280                  return self._CHBOX_is_already_formatted.IsChecked()
    281
    282          is_user_formatted = property(_get_is_user_formatted, lambda x:x)
    283          #--------------------------------------------------------
    284 -        def _set_enable_user_formatting(self, value):
    285                  self._CHBOX_is_already_formatted.Enable(value)
    286
    287          enable_user_formatting = property(lambda x:x, _set_enable_user_formatting)
    288          #--------------------------------------------------------
    289          # event handlers
    290          #--------------------------------------------------------
    291 -        def _on_save_button_pressed(self, evt):
    292
    293                  if self.IsModal():
    294                          self.EndModal(wx.ID_SAVE)
    295                  else:
    296                          self.Close()
    297          #--------------------------------------------------------
    298 -        def _on_clear_button_pressed(self, evt):
    299                  self._TCTRL_text.SetValue('')
    300          #--------------------------------------------------------
    301 -        def _on_restore_button_pressed(self, evt):
    302                  if self.original_text is not None:
    303                          self._TCTRL_text.SetValue(self.original_text)
    304
    305  # ========================================================================
    306 -def clipboard2text():
    307
    308          if wx.TheClipboard.IsOpened():
    309                  return False
    310
    311          if not wx.TheClipboard.Open():
    312                  return False
    313
    314          data_obj = wx.TextDataObject()
    315          got_it = wx.TheClipboard.GetData(data_obj)
    316          if got_it:
    317                  txt = data_obj.Text
    318                  wx.TheClipboard.Close()
    319                  return txt
    320
    321          wx.TheClipboard.Close()
    322          return None
    323
    324  #-------------------------------------------------------------------------
    325 -def clipboard2file(check_for_filename=False):
    326
    327          if wx.TheClipboard.IsOpened():
    328                  return False
    329
    330          if not wx.TheClipboard.Open():
    331                  return False
    332
    333          data_obj = wx.TextDataObject()
    334          got_it = wx.TheClipboard.GetData(data_obj)
    335          if got_it:
    336                  clipboard_text_content = data_obj.Text
    337                  wx.TheClipboard.Close()
    338                  if check_for_filename:
    339                          try:
    340                                  io.open(clipboard_text_content).close()
    341                                  return clipboard_text_content
    342                          except IOError:
    343                                  _log.exception('clipboard does not seem to hold filename: %s', clipboard_text_content)
    344                  fname = gmTools.get_unique_filename(prefix = 'gm-clipboard-', suffix = '.txt')
    345                  target_file = io.open(fname, mode = 'wt', encoding = 'utf8')
    346                  target_file.write(clipboard_text_content)
    347                  target_file.close()
    348                  return fname
    349
    350          data_obj = wx.BitmapDataObject()
    351          got_it = wx.TheClipboard.GetData(data_obj)
    352          if got_it:
    353                  fname = gmTools.get_unique_filename(prefix = 'gm-clipboard-', suffix = '.png')
    354                  bmp = data_obj.Bitmap.SaveFile(fname, wx.BITMAP_TYPE_PNG)
    355                  wx.TheClipboard.Close()
    356                  return fname
    357
    358          wx.TheClipboard.Close()
    359          return None
    360
    361  #-------------------------------------------------------------------------
    362 -def text2clipboard(text=None, announce_result=False):
    363          if wx.TheClipboard.IsOpened():
    364                  return False
    365          if not wx.TheClipboard.Open():
    366                  return False
    367          data_obj = wx.TextDataObject()
    368          data_obj.SetText(text)
    369          wx.TheClipboard.SetData(data_obj)
    370          wx.TheClipboard.Close()
    371          if announce_result:
    372                  gmDispatcher.send(signal = 'statustext', msg = _('The text has been copied into the clipboard.'), beep = False)
    373          return True
    374
    375  #-------------------------------------------------------------------------
    376 -def file2clipboard(filename=None, announce_result=False):
    377          f = io.open(filename, mode = 'rt', encoding = 'utf8')
    378          result = text2clipboard(text = f.read(), announce_result = False)
    379          f.close()
    380          if announce_result:
    381                  gm_show_info (
    382                          title = _('file2clipboard'),
    383                          info = _('The file [%s] has been copied into the clipboard.') % filename
    384                  )
    385          return result
    386
    387  # ========================================================================
    388 -class cFileDropTarget(wx.FileDropTarget):
    389          """Generic file drop target class.
    390
    391          Protocol:
    392                  Widgets being declared file drop targets
    393                  must provide the method:
    394
    395                          def _drop_target_consume_filenames(self, filenames)
    396
    397                  or declare a callback during __init__() of this class.
    398          """
    399          #-----------------------------------------------
    400 -        def __init__(self, target=None, on_drop_callback=None):
    401                  if target is not None:
    402                          on_drop_callback = getattr(target, '_drop_target_consume_filenames')
    403                  if not callable(on_drop_callback):
    404                          _log.error('[%s] not callable, cannot set as drop target callback', on_drop_callback)
    405                          raise AttributeError('[%s] not callable, cannot set as drop target callback', on_drop_callback)
    406
    407                  self._on_drop_callback = on_drop_callback
    408                  wx.FileDropTarget.__init__(self)
    409                  _log.debug('setting up [%s] as file drop target', self._on_drop_callback)
    410
    411          #-----------------------------------------------
    412 -        def OnDropFiles(self, x, y, filenames):
    413                  self._on_drop_callback(filenames)
    414
    415  # ========================================================================
    416 -def file2scaled_image(filename=None, height=100):
    417          img_data = None
    418          bitmap = None
    419          rescaled_height = height
    420          try:
    421                  img_data = wx.Image(filename, wx.BITMAP_TYPE_ANY)
    422                  current_width = img_data.GetWidth()
    423                  current_height = img_data.GetHeight()
    424  #               if current_width == 0:
    425  #                       current_width = 1
    426  #               if current_height == 0:
    427  #                       current_height = 1
    428                  rescaled_width = (float(current_width) / current_height) * rescaled_height
    429                  img_data.Rescale(rescaled_width, rescaled_height, quality = wx.IMAGE_QUALITY_HIGH)              # w, h
    430                  bitmap = wx.Bitmap(img_data)
    431                  del img_data
    432          except Exception:
    433                  _log.exception('cannot load image from [%s]', filename)
    434                  del img_data
    435                  del bitmap
    436                  return None
    437          return bitmap
    438
    439  # ========================================================================
    440 -def save_screenshot_to_file(filename=None, widget=None, settle_time=None):
    441          """Take screenshot of widget.
    442
    443          <settle_time> in milliseconds
    444          """
    445          assert (isinstance(widget, wx.Window)), '<widget> must be (sub)class of wx.Window'
    446
    447          if filename is None:
    448                  filename = gmTools.get_unique_filename (
    449                          prefix = 'gm-screenshot-%s-' % pyDT.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'),
    450                          suffix = '.png'
    451                          # for testing:
    452                          #,tmp_dir = os.path.join(gmTools.gmPaths().home_dir, 'gnumed')
    453                  )
    454          else:
    455                  filename = gmTools.fname_sanitize(filename)
    456
    457          _log.debug('filename: %s', filename)
    458          _log.debug('widget: %s', widget)
    459          _log.debug('display size: %s', wx.DisplaySize())
    460
    461          # let it settle a bit for, say, tooltips
    462          if settle_time is not None:
    463                  for wait_slice in range(int(settle_time // 100)):
    464                          wx.SafeYield()
    465                          time.sleep(0.1)
    466
    467          widget_rect_on_screen = widget.GetScreenRect()
    468          client_area_origin_on_screen = widget.ClientToScreen((0, 0))
    469          widget_rect_local = widget.GetRect()
    470          widget_rect_client_area = widget.GetClientRect()
    471          client_area_origin_local = widget.GetClientAreaOrigin()
    472
    473          _log.debug('widget.GetScreenRect(): %s', widget_rect_on_screen)
    474          _log.debug('widget.ClientToScreen(0, 0): %s', client_area_origin_on_screen)
    475          _log.debug('widget.GetRect(): %s', widget_rect_local)
    476          _log.debug('widget.GetClientRect(): %s', widget_rect_client_area)
    477          _log.debug('widget.GetClientAreaOrigin(): %s', client_area_origin_local)
    478
    479          width2snap = widget_rect_local.width
    480          height2snap = widget_rect_local.height
    481          border_x = client_area_origin_on_screen.x - widget_rect_local.x
    482          x2snap_from = 0 - border_x
    483          title_and_menu_height = client_area_origin_on_screen.y - widget_rect_on_screen.y
    484          y2snap_from = 0 - title_and_menu_height
    485
    486          # those are the correct dimensions but we don't get to
    487          # *see* the window decorations on a WindowDC or ClientDC :-(
    488          # (and a screendc doesn't work either)
    489          _log.debug('left (x) border: %s', border_x)
    490          _log.debug('top (y) border: %s', title_and_menu_height)
    491          _log.debug('x2snap_from: %s', x2snap_from)
    492          _log.debug('y2snap_from: %s', y2snap_from)
    493          _log.debug('width2snap: %s', width2snap)
    494          _log.debug('height2snap: %s', height2snap)
    495
    496          # WindowDC includes decorations, supposedly, but Windows only
    497          window_dc = wx.WindowDC(widget)
    498          wxbmp = __snapshot_to_bitmap (
    499                  source_dc = window_dc,
    500                  x2snap_from = x2snap_from,
    501                  y2snap_from = y2snap_from,
    502                  width2snap = width2snap,
    503                  height2snap = height2snap
    504          )
    505          window_dc.Destroy()
    506          del window_dc
    507          wxbmp.SaveFile(filename, wx.BITMAP_TYPE_PNG)
    508          del wxbmp
    509
    510          x2snap_on_screen = widget_rect_on_screen.x
    511          y2snap_on_screen = widget_rect_on_screen.y                      # adjust for menu/title ?
    512          sane_x2snap_on_screen = max(0, x2snap_on_screen)
    513          sane_y2snap_on_screen = max(0, y2snap_on_screen)
    514
    515          _log.debug('x2snap_on_screen: %s', x2snap_on_screen)
    516          _log.debug('y2snap_on_screen: %s', y2snap_on_screen)
    517          _log.debug('sane x2snap_on_screen: %s', sane_x2snap_on_screen)
    518          _log.debug('sane x2snap_on_screen: %s', sane_y2snap_on_screen)
    519
    520          screen_dc = wx.ScreenDC()
    521          # not implemented:
    522          #wxbmp = screen_dc.GetAsBitmap()                # can use subrect=...
    523          wxbmp = __snapshot_to_bitmap (
    524                  source_dc = screen_dc,
    525                  x2snap_from = sane_x2snap_on_screen,
    526                  y2snap_from = sane_y2snap_on_screen,
    527                  width2snap = width2snap,
    528                  height2snap = height2snap
    529          )
    530          screen_dc.Destroy()
    531          del screen_dc
    532          wxbmp.SaveFile(filename + '.screendc.png', wx.BITMAP_TYPE_PNG)
    533          del wxbmp
    534
    535          # ClientDC does not include decorations, only client area
    536          #client_dc = wx.ClientDC(widget)
    537          #wxbmp = __snapshot_to_bitmap (
    538          #       source_dc = client_dc,
    539          #       x2snap_from = x2snap_from,
    540          #       y2snap_from = y2snap_from,
    541          #       width2snap = width2snap,
    542          #       height2snap = height2snap
    543          #)
    544          #client_dc.Destroy()
    545          #del client_dc
    546          #wxbmp.SaveFile(filename + '.clientdc.png', wx.BITMAP_TYPE_PNG)
    547          #del wxbmp
    548
    549          # adjust for window decoration on Linux
    550          #if sys.platform == 'linux':
    551          # If the widget has a menu bar, remove that from the title bar height.
    552          #if hasattr(widget, 'GetMenuBar'):
    553          #       if widget.GetMenuBar():
    554          #               title_bar_height /= 2
    555          #               print('title bar height:', title_bar_height)
    556          #width2snap += (border_width * 2)
    557          #height2snap += title_bar_height + border_width
    558
    559          gmDispatcher.send(signal = 'statustext', msg = _('Saved screenshot to file [%s].') % filename)
    560          return filename
    561
    562  #-------------------------------------------------------------------------
    563 -def __snapshot_to_bitmap(source_dc=None, x2snap_from=0, y2snap_from=0, width2snap=1, height2snap=1):
    564          _log.debug('taking screenshot from %sx%s for %sx%s on [%s]', x2snap_from, y2snap_from, width2snap, height2snap, source_dc)
    565          target_dc = wx.MemoryDC()
    566          _log.debug('target DC: %s', target_dc)
    567          wxbmp = wx.Bitmap(width2snap, height2snap)
    568          target_dc.SelectObject(wxbmp)
    569          target_dc.Clear()                                               # wipe anything that might have been there in memory ?  taken from wxWidgets source
    570          target_dc.Blit (                                                # copy into this memory DC ...
    571                  0, 0,                                                           # ... to here in the memory DC (= target) ...
    572                  width2snap, height2snap,                        # ... that much ...
    573                  source_dc,                                                      # ... from the source DC ...
    574                  x2snap_from, y2snap_from                        # ... starting here
    575          )
    576          target_dc.SelectObject(wx.NullBitmap)   # disassociate wxbmp so it can safely be handled further
    577          target_dc.Destroy()                                             # destroy C++ object
    578          del target_dc
    579          return wxbmp
    580
    581  # ========================================================================
    582 -def gm_show_error(aMessage=None, aTitle = None, error=None, title=None):
    583
    584          if error is None:
    585                  error = aMessage
    586          if error is None:
    587                  error = _('programmer forgot to specify error message')
    588          error += _("\n\nPlease consult the error log for all the gory details !")
    589          if title is None:
    590                  title = aTitle
    591          if title is None:
    592                  title = _('generic error message')
    593          dlg = wx.MessageDialog (
    594                  parent = None,
    595                  message = error,
    596                  caption = gmTools.decorate_window_title(title),
    597                  style = wx.OK | wx.ICON_ERROR | wx.STAY_ON_TOP
    598          )
    599          dlg.ShowModal()
    600          dlg.DestroyLater()
    601          return True
    602
    603  #-------------------------------------------------------------------------
    604 -def gm_show_info(aMessage=None, aTitle=None, info=None, title=None):
    605
    606          if info is None:
    607                  info = aMessage
    608          if info is None:
    609                  info = _('programmer forgot to specify info message')
    610          if title is None:
    611                  title = aTitle
    612          if title is None:
    613                  title = _('generic info message')
    614          dlg = wx.MessageDialog (
    615                  parent = None,
    616                  message = info,
    617                  caption = gmTools.decorate_window_title(title),
    618                  style = wx.OK | wx.ICON_INFORMATION | wx.STAY_ON_TOP
    619          )
    620          dlg.ShowModal()
    621          dlg.DestroyLater()
    622          return True
    623
    624  #-------------------------------------------------------------------------
    625 -def gm_show_warning(aMessage=None, aTitle=None):
    626          if aMessage is None:
    627                  aMessage = _('programmer forgot to specify warning')
    628          if aTitle is None:
    629                  aTitle = _('generic warning message')
    630
    631          dlg = wx.MessageDialog (
    632                  parent = None,
    633                  message = aMessage,
    634                  caption = gmTools.decorate_window_title(aTitle),
    635                  style = wx.OK | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP
    636          )
    637          dlg.ShowModal()
    638          dlg.DestroyLater()
    639          return True
    640
    641  #-------------------------------------------------------------------------
    642 -def gm_show_question(aMessage='programmer forgot to specify question', aTitle='generic user question dialog', cancel_button=False, question=None, title=None):
    643          if cancel_button:
    644                  style = wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION | wx.STAY_ON_TOP
    645          else:
    646                  style = wx.YES_NO | wx.ICON_QUESTION | wx.STAY_ON_TOP
    647
    648          if question is None:
    649                  question = aMessage
    650          if title is None:
    651                  title = aTitle
    652          title = gmTools.decorate_window_title(title)
    653
    654          dlg = wx.MessageDialog(None, question, title, style)
    655          btn_pressed = dlg.ShowModal()
    656          dlg.DestroyLater()
    657
    658          if btn_pressed == wx.ID_YES:
    659                  return True
    660          elif btn_pressed == wx.ID_NO:
    661                  return False
    662          else:
    663                  return None
    664
    665  #======================================================================
    666  if __name__ == '__main__':
    667
    668          if len(sys.argv) < 2:
    669                  sys.exit()
    670
    671          if sys.argv[1] != 'test':
    672                  sys.exit()
    673
    674          from Gnumed.pycommon import gmI18N
    675          gmI18N.activate_locale()
    676          gmI18N.install_domain(domain='gnumed')
    677
    678          #------------------------------------------------------------------
    679 -        def test_scale_img():
    680                  app = wx.App()
    681                  img = file2scaled_image(filename = sys.argv[2])
    682                  print(img)
    683                  print(img.Height)
    684                  print(img.Width)
    685          #------------------------------------------------------------------
    686 -        def test_sql_logic_prw():
    687                  app = wx.PyWidgetTester(size = (200, 50))
    688                  prw = cThreeValuedLogicPhraseWheel(app.frame, -1)
    689                  app.frame.Show(True)
    690                  app.MainLoop()
    691
    692                  return True
    693          #------------------------------------------------------------------
    694 -        def test_clipboard():
    695                  app = wx.PyWidgetTester(size = (200, 50))
    696                  result = clipboard2file()
    697                  if result is False:
    698                          print("problem opening clipboard")
    699                          return
    700                  if result is None:
    701                          print("no data in clipboard")
    702                          return
    703                  print("file:", result)
    704          #------------------------------------------------------------------
    705          #test_scale_img()
    706          #test_sql_logic_prw()
    707          test_clipboard()
    708
    709  #======================================================================
    710