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

# Source Code for Module Gnumed.wxpython.gmKeywordExpansionWidgets

      1  # -*- coding: utf-8 -*-
      2  """GNUmed keyword expansion widgets."""
      3  #================================================================
      4  __author__ = "Karsten Hilbert <Karsten.Hilbert@gmx.net>"
      5  __license__ = "GPL v2 or later"
      6
      7  import logging
      8  import sys
      9  import re as regex
     10  import os.path
     11
     12
     13  import wx
     14  import wx.stc
     15
     16
     17  if __name__ == '__main__':
     18          sys.path.insert(0, '../../')
     19  from Gnumed.pycommon import gmDispatcher
     20  from Gnumed.pycommon import gmPG2
     21  from Gnumed.pycommon import gmTools
     22  from Gnumed.business import gmKeywordExpansion
     23  from Gnumed.wxpython import gmEditArea
     24  from Gnumed.wxpython import gmListWidgets
     25
     26
     27  _log = logging.getLogger('gm.ui')
     28
     29  _text_expansion_fillin_regex = r'\$\[[^]]*\]\$'
     30
     31  #============================================================
     32 -class cKeywordExpansion_TextCtrlMixin():
     33
     34 -        def __init__(self, *args, **kwargs):
     35                  if not isinstance(self, (wx.TextCtrl, wx.stc.StyledTextCtrl)):
     36                          raise TypeError('[%s]: can only be applied to wx.TextCtrl or wx.stc.StyledTextCtrl, not [%s]' % (cKeywordExpansion_TextCtrlMixin, self.__class__.__name__))
     37
     38          #--------------------------------------------------------
     39 -        def enable_keyword_expansions(self):
     40                  self.__keyword_separators = regex.compile("[!?'\".,:;)}\]\r\n\s\t]+")
     41                  self.Bind(wx.EVT_CHAR, self.__on_char_in_keyword_expansion_mixin)
     42
     43          #--------------------------------------------------------
     44 -        def disable_keyword_expansions(self):
     45                  self.Unbind(wx.EVT_CHAR)
     46
     47          #--------------------------------------------------------
     48 -        def attempt_expansion(self, show_list_if_needed=False):
     49
     50                  visible, caret_pos_in_line, line_no = self.PositionToXY(self.InsertionPoint)
     51                  line = self.GetLineText(line_no)
     52                  keyword_candidate = self.__keyword_separators.split(line[:caret_pos_in_line])[-1]
     53
     54                  if (
     55                          (show_list_if_needed is False)
     56                                  and
     57                          (keyword_candidate != '$$steffi')                       # Easter Egg ;-)
     58                                  and
     59                          (keyword_candidate not in [ r[0] for r in gmKeywordExpansion.get_textual_expansion_keywords() ])
     60                  ):
     61                          return
     62
     63                  # why does this work despite the wx.TextCtrl docs saying that
     64                  # InsertionPoint values cannot be used as indices into strings ?
     65                  # because we never cross an EOL which is the only documented
     66                  # reason for insertion point to be off the string index
     67                  start = self.InsertionPoint - len(keyword_candidate)
     68                  wx.CallAfter(self.__replace_keyword_with_expansion, keyword = keyword_candidate, position = start, show_list_if_needed = show_list_if_needed)
     69                  return
     70
     71          #--------------------------------------------------------
     72          # event handling
     73          #--------------------------------------------------------
     74 -        def __on_char_in_keyword_expansion_mixin(self, evt):
     75                  evt.Skip()
     76
     77                  # empty ?
     78                  if self.LastPosition == 1:
     79                          return
     80
     81                  char = chr(evt.GetUnicodeKey())
     82
     83                  user_wants_expansion_attempt = False
     84                  if evt.GetModifiers() == (wx.MOD_CMD | wx.MOD_ALT):     # portable CTRL-ALT-...
     85                          if evt.GetKeyCode() == wx.WXK_RETURN:                   # CTRL-ALT-ENTER
     86                                  user_wants_expansion_attempt = True
     87                          elif evt.GetKeyCode() == 20:                                    # CTRL-ALT-T
     88                                  user_wants_expansion_attempt = True
     89                          else:
     90                                  return
     91
     92                  if user_wants_expansion_attempt is False:
     93                          # user did not press CTRL-ALT-ENTER,
     94                          # however, did they last enter a
     95                          # "keyword separator", active character ?
     96                          if self.__keyword_separators.match(char) is None:
     97                                  return
     98
     99                  self.attempt_expansion(show_list_if_needed = user_wants_expansion_attempt)
    100
    101          #--------------------------------------------------------
    102          # internal helpers
    103          #--------------------------------------------------------
    104 -        def __replace_keyword_with_expansion(self, keyword=None, position=None, show_list_if_needed=False):
    105
    106                  expansion = expand_keyword(parent = self, keyword = keyword, show_list_if_needed = show_list_if_needed)
    107                  if expansion is None:
    108                          return
    109                  if expansion == '':
    110                          return
    111
    112                  if not self.IsMultiLine():
    113                          expansion_lines = gmTools.strip_leading_empty_lines (
    114                                  lines = gmTools.strip_trailing_empty_lines (
    115                                          text = expansion,
    116                                          return_list = True
    117                                  ),
    118                                  return_list = True
    119                          )
    120                          if len(expansion_lines) == 0:
    121                                  return
    122                          if len(expansion_lines) == 1:
    123                                  expansion = expansion_lines[0]
    124                          else:
    125                                  msg = _(
    126                                          'The fragment <%s> expands to multiple lines !\n'
    127                                          '\n'
    128                                          'This text field can hold one line only, hwoever.\n'
    129                                          '\n'
    130                                          'Please select the line you want to insert:'
    131                                  ) % keyword
    132                                  expansion = gmListWidgets.get_choices_from_list (
    133                                          parent = self,
    134                                          msg = msg,
    135                                          caption = _('Adapting multi-line expansion to single-line text field'),
    136                                          choices = expansion_lines,
    137                                          selections = [0],
    138                                          columns = [_('Keyword expansion lines')],
    139                                          single_selection = True,
    140                                          can_return_empty = False
    141                                  )
    142                                  if expansion is None:
    143                                          return
    144
    145                  self.Replace (
    146                          position,
    147                          position + len(keyword),
    148                          expansion
    149                  )
    150
    151                  self.SetInsertionPoint(position + len(expansion) + 1)
    152                  self.ShowPosition(position + len(expansion) + 1)
    153
    154                  return
    155
    156  #============================================================
    157  from Gnumed.wxGladeWidgets import wxgTextExpansionEditAreaPnl
    158
    159 -class cTextExpansionEditAreaPnl(wxgTextExpansionEditAreaPnl.wxgTextExpansionEditAreaPnl, gmEditArea.cGenericEditAreaMixin):
    160
    161 -        def __init__(self, *args, **kwds):
    162
    163                  try:
    164                          data = kwds['expansion']
    165                          del kwds['expansion']
    166                  except KeyError:
    167                          data = None
    168
    169                  wxgTextExpansionEditAreaPnl.wxgTextExpansionEditAreaPnl.__init__(self, *args, **kwds)
    170                  gmEditArea.cGenericEditAreaMixin.__init__(self)
    171
    172                  self.mode = 'new'
    173                  self.data = data
    174                  if data is not None:
    175                          self.mode = 'edit'
    176
    177  #               self.__init_ui()
    178                  self.__register_interests()
    179
    180                  self.__data_filename = None
    181
    182          #--------------------------------------------------------
    183  #       def __init_ui(self, expansion=None):
    184  #               self._BTN_select_data_file.Enable(False)
    185
    186          #----------------------------------------------------------------
    187          # generic Edit Area mixin API
    188          #----------------------------------------------------------------
    189 -        def _valid_for_save(self):
    190                  validity = True
    191
    192                  has_expansion = (
    193                          (self._TCTRL_expansion.GetValue().strip() != '')
    194                                  or
    195                          (self.__data_filename is not None)
    196                                  or
    197                          ((self.data is not None) and (self.data['is_textual'] is False))
    198                  )
    199
    200                  if has_expansion:
    201                          self.display_tctrl_as_valid(tctrl = self._TCTRL_expansion, valid = True)
    202                          self.display_tctrl_as_valid(tctrl = self._TCTRL_data_file, valid = True)
    203                  else:
    204                          validity = False
    205                          self.StatusText = _('Cannot save keyword expansion without text or data expansion.')
    206                          self.display_tctrl_as_valid(tctrl = self._TCTRL_expansion, valid = False)
    207                          self.display_tctrl_as_valid(tctrl = self._TCTRL_data_file, valid = False)
    208                          if self.data is None:
    209                                  self._TCTRL_expansion.SetFocus()
    210                          else:
    211                                  if self.data['is_textual']:
    212                                          self._TCTRL_expansion.SetFocus()
    213                                  else:
    214                                          self._BTN_select_data_file.SetFocus()
    215
    216                  if self._TCTRL_keyword.GetValue().strip() == '':
    217                          validity = False
    218                          self.display_tctrl_as_valid(tctrl = self._TCTRL_keyword, valid = False)
    219                          self.StatusText = _('Cannot save keyword expansion without keyword.')
    220                          self._TCTRL_keyword.SetFocus()
    221                  else:
    222                          self.display_tctrl_as_valid(tctrl = self._TCTRL_keyword, valid = True)
    223
    224                  return validity
    225
    226          #----------------------------------------------------------------
    227 -        def _save_as_new(self):
    228                  expansion = gmKeywordExpansion.create_keyword_expansion (
    229                          keyword = self._TCTRL_keyword.GetValue().strip(),
    230                          text = self._TCTRL_expansion.GetValue(),
    231                          data_file = self.__data_filename,
    232                          public = self._RBTN_public.GetValue()
    233                  )
    234
    235                  if expansion is False:
    236                          return False
    237
    238                  expansion['is_encrypted'] = self._CHBOX_is_encrypted.IsChecked()
    239                  expansion.save()
    240
    241                  self.data = expansion
    242                  return True
    243
    244          #----------------------------------------------------------------
    245 -        def _save_as_update(self):
    246
    247                  self.data['expansion'] = self._TCTRL_expansion.GetValue().strip()
    248                  self.data['is_encrypted'] = self._CHBOX_is_encrypted.IsChecked()
    249                  self.data.save()
    250
    251                  if self.__data_filename is not None:
    252                          self.data.update_data_from_file(filename = self.__data_filename)
    253
    254                  return True
    255          #----------------------------------------------------------------
    256          #----------------------------------------------------------------
    257 -        def _refresh_as_new(self):
    258                  self.__data_filename = None
    259
    260                  self._TCTRL_keyword.SetValue('')
    261                  self._TCTRL_keyword.Enable(True)
    262
    263                  self._LBL_data.Enable(False)
    264                  self._BTN_select_data_file.Enable(False)
    265                  self._TCTRL_data_file.SetValue('')
    266                  self._CHBOX_is_encrypted.SetValue(False)
    267                  self._CHBOX_is_encrypted.Enable(False)
    268
    269                  self._LBL_text.Enable(False)
    270                  self._TCTRL_expansion.SetValue('')
    271                  self._TCTRL_expansion.Enable(False)
    272
    273                  self._RBTN_public.Enable(False)
    274                  self._RBTN_private.Enable(False)
    275                  self._RBTN_public.SetValue(1)
    276
    277                  self._TCTRL_keyword.SetFocus()
    278          #----------------------------------------------------------------
    279 -        def _refresh_as_new_from_existing(self):
    280                  self._refresh_from_existing()
    281
    282                  self._TCTRL_keyword.SetValue('%s%s' % (self.data, _('___copy')))
    283                  self._TCTRL_keyword.Enable(True)
    284
    285                  self._RBTN_public.Enable(True)
    286                  self._RBTN_private.Enable(True)
    287
    288                  self._TCTRL_keyword.SetFocus()
    289          #----------------------------------------------------------------
    290 -        def _refresh_from_existing(self):
    291                  self.__data_filename = None
    292
    293                  self._TCTRL_keyword.SetValue(self.data['keyword'])
    294                  self._TCTRL_keyword.Enable(False)
    295
    296                  if self.data['is_textual']:
    297                          self._LBL_text.Enable(True)
    298                          self._TCTRL_expansion.SetValue(gmTools.coalesce(self.data['expansion'], ''))
    299
    300                          self._LBL_data.Enable(False)
    301                          self._BTN_select_data_file.Enable(False)
    302                          self._TCTRL_data_file.SetValue('')
    303                          self._CHBOX_is_encrypted.SetValue(False)
    304                          self._CHBOX_is_encrypted.Enable(False)
    305                  else:
    306                          self._LBL_text.Enable(False)
    307                          self._TCTRL_expansion.SetValue('')
    308
    309                          self._LBL_data.Enable(True)
    310                          self._BTN_select_data_file.Enable(True)
    311                          self._TCTRL_data_file.SetValue(_('Size: %s') % gmTools.size2str(self.data['data_size']))
    312                          self._CHBOX_is_encrypted.SetValue(self.data['is_encrypted'])
    313                          self._CHBOX_is_encrypted.Enable(True)
    314
    315                  self._RBTN_public.Enable(False)
    316                  self._RBTN_private.Enable(False)
    317                  if self.data['public_expansion']:
    318                          self._RBTN_public.SetValue(1)
    319                  else:
    320                          self._RBTN_private.SetValue(1)
    321
    322                  if self.data['is_textual']:
    323                          self._TCTRL_expansion.SetFocus()
    324                  else:
    325                          self._BTN_select_data_file.SetFocus()
    326          #----------------------------------------------------------------
    327          # event handling
    328          #----------------------------------------------------------------
    329 -        def __register_interests(self):
    330                  self._TCTRL_keyword.Bind(wx.EVT_TEXT, self._on_keyword_modified)
    331                  self._TCTRL_expansion.Bind(wx.EVT_TEXT, self._on_expansion_modified)
    332          #----------------------------------------------------------------
    333 -        def _on_keyword_modified(self, evt):
    334                  if self._TCTRL_keyword.GetValue().strip() == '':
    335                          self._LBL_text.Enable(False)
    336                          self._TCTRL_expansion.Enable(False)
    337                          self._LBL_data.Enable(False)
    338                          self._BTN_select_data_file.Enable(False)
    339                          self._CHBOX_is_encrypted.Enable(False)
    340                          self._RBTN_public.Enable(False)
    341                          self._RBTN_private.Enable(False)
    342                          return
    343
    344                  # keyword is not empty
    345                  # mode must be new(_from_existing) or else
    346                  # we cannot modify the keyword in the first place
    347                  self._LBL_text.Enable(True)
    348                  self._TCTRL_expansion.Enable(True)
    349                  self._LBL_data.Enable(True)
    350                  self._BTN_select_data_file.Enable(True)
    351                  self._RBTN_public.Enable(True)
    352                  self._RBTN_private.Enable(True)
    353          #----------------------------------------------------------------
    354 -        def _on_expansion_modified(self, evt):
    355                  if self._TCTRL_expansion.GetValue().strip() == '':
    356                          self._LBL_data.Enable(True)
    357                          self._BTN_select_data_file.Enable(True)
    358                          return
    359
    360                  self.__data_filename = None
    361                  self._LBL_data.Enable(False)
    362                  self._BTN_select_data_file.Enable(False)
    363                  self._TCTRL_data_file.SetValue('')
    364                  self._CHBOX_is_encrypted.Enable(False)
    365          #----------------------------------------------------------------
    366 -        def _on_select_data_file_button_pressed(self, event):
    367                  wildcards = [
    368                          "%s (*)|*" % _('all files'),
    369                          "%s (*.*)|*.*" % _('all files (Windows)')
    370                  ]
    371
    372                  dlg = wx.FileDialog (
    373                          parent = self,
    374                          message = _('Choose the file containing the data snippet'),
    375                          wildcard = '|'.join(wildcards),
    376                          style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
    377                  )
    378                  result = dlg.ShowModal()
    379                  if result != wx.ID_CANCEL:
    380                          self.__data_filename = dlg.GetPath()
    381                          self._TCTRL_data_file.SetValue(self.__data_filename)
    382                          self._CHBOX_is_encrypted.SetValue(False)
    383                          self._CHBOX_is_encrypted.Enable(True)
    384
    385                  dlg.DestroyLater()
    386
    387  #============================================================
    388 -def configure_keyword_text_expansion(parent=None):
    389
    390          if parent is None:
    391                  parent = wx.GetApp().GetTopWindow()
    392
    393          #----------------------
    394          def delete(expansion=None):
    395                  gmKeywordExpansion.delete_keyword_expansion(pk = expansion['pk_expansion'])
    396                  return True
    397          #----------------------
    398          def edit(expansion=None):
    399                  ea = cTextExpansionEditAreaPnl(parent, -1, expansion = expansion)
    400                  dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea)
    401                  if expansion is None:
    402                          title = _('Adding keyword expansion')
    403                  else:
    404                          title = _('Editing keyword expansion "%s"') % expansion['keyword']
    405                  dlg.SetTitle(title)
    406                  if dlg.ShowModal() == wx.ID_OK:
    407                          return True
    408
    409                  return False
    410          #----------------------
    411          def tooltip(expansion):
    412                  return expansion.format()
    413          #----------------------
    414          def refresh(lctrl=None):
    415                  expansions = gmKeywordExpansion.get_keyword_expansions(order_by = 'is_textual DESC, keyword, public_expansion', force_reload = True)
    416                  items = [[
    417                                  e['keyword'],
    418                                  gmTools.bool2subst(e['is_textual'], _('text'), _('data')),
    419                                  gmTools.bool2subst(e['public_expansion'], _('public'), _('private'))
    420                          ] for e in expansions
    421                  ]
    422                  lctrl.set_string_items(items)
    423                  lctrl.set_data(expansions)
    424          #----------------------
    425
    426          gmListWidgets.get_choices_from_list (
    427                  parent = parent,
    428                  msg = _('\nSelect the keyword you want to edit !\n'),
    429                  caption = _('Editing keyword-based expansions ...'),
    430                  columns = [_('Keyword'), _('Type'), _('Scope')],
    431                  single_selection = True,
    432                  edit_callback = edit,
    433                  new_callback = edit,
    434                  delete_callback = delete,
    435                  refresh_callback = refresh,
    436                  list_tooltip_callback = tooltip
    437          )
    438
    439  #============================================================
    440  from Gnumed.wxGladeWidgets import wxgTextExpansionFillInDlg
    441
    442 -class cTextExpansionFillInDlg(wxgTextExpansionFillInDlg.wxgTextExpansionFillInDlg):
    443
    444 -        def __init__(self, *args, **kwds):
    445                  wxgTextExpansionFillInDlg.wxgTextExpansionFillInDlg.__init__(self, *args, **kwds)
    446
    447                  self.__expansion = None
    448                  self.__init_ui()
    449          #---------------------------------------------
    450 -        def __init_ui(self):
    451                  self._LBL_top_part.SetLabel('')
    452                  font = self._LBL_left_part.GetFont()
    453                  font.SetPointSize(pointSize = font.GetPointSize() + 1)
    454                  self._LBL_left_part.SetFont(font)
    455                  self._LBL_left_part.SetLabel('')
    456                  self._LBL_left_part.Hide()
    457                  font = self._TCTRL_fillin.GetFont()
    458                  font.SetPointSize(pointSize = font.GetPointSize() + 1)
    459                  self._TCTRL_fillin.SetFont(font)
    460                  self._TCTRL_fillin.SetValue('')
    461                  self._TCTRL_fillin.SetBackgroundColour('yellow')
    462                  self._TCTRL_fillin.Disable()
    463                  self._TCTRL_fillin.Hide()
    464                  font = self._LBL_right_part.GetFont()
    465                  font.SetPointSize(pointSize = font.GetPointSize() + 1)
    466                  self._LBL_right_part.SetFont(font)
    467                  self._LBL_right_part.SetLabel('')
    468                  self._LBL_right_part.Hide()
    469                  self._LBL_bottom_part.SetLabel('')
    470                  self._BTN_OK.Disable()
    471                  self._BTN_forward.Disable()
    472                  self._BTN_cancel.SetFocus()
    473                  self._LBL_hint.SetLabel('')
    474          #---------------------------------------------
    475 -        def __goto_next_fillin(self):
    476                  if self.__expansion is None:
    477                          return
    478
    479                  if self.__new_expansion:
    480                          self.__filled_in = self.__expansion
    481                          self.__new_expansion = False
    482                  else:
    483                          self.__filled_in = (
    484                                  self._LBL_top_part.GetLabel() +
    485                                  self.__left_splitter +
    486                                  self._LBL_left_part.GetLabel() +
    487                                  self._TCTRL_fillin.GetValue().strip() +
    488                                  self._LBL_right_part.GetLabel() +
    489                                  self.__right_splitter +
    490                                  self._LBL_bottom_part.GetLabel()
    491                          )
    492
    493                  # anything to fill in ?
    494                  if regex.search(_text_expansion_fillin_regex, self.__filled_in) is None:
    495                          # no
    496                          self._LBL_top_part.SetLabel(self.__filled_in)
    497                          self._LBL_left_part.SetLabel('')
    498                          self._LBL_left_part.Hide()
    499                          self._TCTRL_fillin.SetValue('')
    500                          self._TCTRL_fillin.Disable()
    501                          self._TCTRL_fillin.Hide()
    502                          self._LBL_right_part.SetLabel('')
    503                          self._LBL_right_part.Hide()
    504                          self._LBL_bottom_part.SetLabel('')
    505                          self._BTN_OK.Enable()
    506                          self._BTN_forward.Disable()
    507                          self._BTN_OK.SetDefault()
    508                          return
    509
    510                  # yes
    511                  top, fillin, bottom = regex.split(r'(' + _text_expansion_fillin_regex + r')', self.__filled_in, maxsplit = 1)
    512                  top_parts = top.rsplit('\n', 1)
    513                  top_part = top_parts[0]
    514                  if len(top_parts) == 1:
    515                          self.__left_splitter = ''
    516                          left_part = ''
    517                  else:
    518                          self.__left_splitter = '\n'
    519                          left_part = top_parts[1]
    520                  bottom_parts = bottom.split('\n', 1)
    521                  if len(bottom_parts) == 1:
    522                          parts = bottom_parts[0].split(' ', 1)
    523                          right_part = parts[0]
    524                          if len(parts) == 1:
    525                                  self.__right_splitter = ''
    526                                  bottom_part = ''
    527                          else:
    528                                  self.__right_splitter = ' '
    529                                  bottom_part = parts[1]
    530                  else:
    531                          self.__right_splitter = '\n'
    532                          right_part = bottom_parts[0]
    533                          bottom_part =  bottom_parts[1]
    534                  hint = fillin.strip('$').strip('[').strip(']').strip()
    535                  self._LBL_top_part.SetLabel(top_part)
    536                  self._LBL_left_part.SetLabel(left_part)
    537                  self._LBL_left_part.Show()
    538                  self._TCTRL_fillin.Enable()
    539                  self._TCTRL_fillin.SetValue('')
    540                  self._TCTRL_fillin.Show()
    541                  self._LBL_right_part.SetLabel(right_part)
    542                  self._LBL_right_part.Show()
    543                  self._LBL_bottom_part.SetLabel(bottom_part)
    544                  self._BTN_OK.Disable()
    545                  self._BTN_forward.Enable()
    546                  self._BTN_forward.SetDefault()
    547                  self._LBL_hint.SetLabel(hint)
    548                  self._TCTRL_fillin.SetFocus()
    549
    550                  self.Layout()
    551                  self.Fit()
    552          #---------------------------------------------
    553          # properties
    554          #---------------------------------------------
    555 -        def _get_expansion(self):
    556                  return self.__expansion
    557
    558 -        def _set_expansion(self, expansion):
    559                  self.__expansion = expansion
    560                  self.__new_expansion = True
    561                  self.__goto_next_fillin()
    562                  return
    563
    564          expansion = property(_get_expansion, _set_expansion)
    565          #---------------------------------------------
    566 -        def _get_filled_in(self):
    567                  return self.__filled_in
    568
    569          filled_in_expansion = property(_get_filled_in, lambda x:x)
    570          #---------------------------------------------
    571 -        def _set_keyword(self, keyword):
    572                  self.SetTitle(_('Expanding <%s>') % keyword)
    573
    574          keyword = property(lambda x:x, _set_keyword)
    575          #---------------------------------------------
    576          # event handlers
    577          #---------------------------------------------
    578 -        def _on_forward_button_pressed(self, event):
    579                  self.__goto_next_fillin()
    580
    581  #============================================================
    582 -def expand_keyword(parent=None, keyword=None, show_list_if_needed=False):
    583          """Expand keyword and replace inside it.
    584
    585          Returns:
    586                  None: aborted or no expansion available
    587                  u'': empty expansion
    588                  u'<text>' the expansion
    589          """
    590          if keyword is None:
    591                  return None
    592          if parent is None:
    593                  parent = wx.GetApp().GetTopWindow()
    594
    595          if show_list_if_needed:
    596                  candidates = gmKeywordExpansion.get_matching_textual_keywords(fragment = keyword)
    597                  if len(candidates) == 0:
    598                          return None
    599                  if len(candidates) == 1:
    600                          keyword = candidates[0]
    601                  else:
    602                          keyword = gmListWidgets.get_choices_from_list (
    603                                  parent = parent,
    604                                  msg = _(
    605                                          'Several macro keywords match the fragment [%s].\n'
    606                                          '\n'
    607                                          'Please select the expansion you want to happen.'
    608                                  ) % keyword,
    609                                  caption = _('Selecting text macro'),
    610                                  choices = candidates,
    611                                  columns = [_('Keyword')],
    612                                  single_selection = True,
    613                                  can_return_empty = False
    614                          )
    615                          if keyword is None:
    616                                  return None
    617
    618          expansion = gmKeywordExpansion.expand_keyword(keyword = keyword)
    619
    620          # not found
    621          if expansion is None:
    622                  return None
    623
    624          # no replacement necessary:
    625          if expansion.strip() == '':
    626                  return expansion
    627
    628          if regex.search(_text_expansion_fillin_regex, expansion) is not None:
    629                  dlg = cTextExpansionFillInDlg(None, -1)
    630                  dlg.keyword = keyword
    631                  dlg.expansion = expansion
    632                  button = dlg.ShowModal()
    633                  if button == wx.ID_OK:
    634                          expansion = dlg.filled_in_expansion
    635                  dlg.DestroyLater()
    636
    637          return expansion
    638
    639  #============================================================
    640  # main
    641  #------------------------------------------------------------
    642  if __name__ == '__main__':
    643
    644          if len(sys.argv) < 2:
    645                  sys.exit()
    646
    647          if sys.argv[1] != 'test':
    648                  sys.exit()
    649
    650          from Gnumed.pycommon import gmI18N
    651          gmI18N.activate_locale()
    652          gmI18N.install_domain(domain = 'gnumed')
    653
    654          #----------------------------------------
    655 -        def test_fillin():
    656                  expansion = """HEMORR²HAGES: Blutungsrisiko unter OAK
    657  --------------------------------------
    658  Am Heart J. 2006 Mar;151(3):713-9.
    659
    660  $[1 oder 0 eingeben]$ H epatische oder Nierenerkrankung
    661  $[1 oder 0 eingeben]$ E thanolabusus
    662  $[1 oder 0 eingeben]$ M alignom
    663  $[1 oder 0 eingeben]$ O ld patient (> 75 Jahre)
    664  $[1 oder 0 eingeben]$ R eduzierte Thrombozytenzahl/-funktion
    665  $[2 oder 0 eingeben]$ R²ekurrente (frühere) große Blutung
    666  $[1 oder 0 eingeben]$ H ypertonie (unkontrolliert)
    667  $[1 oder 0 eingeben]$ A nämie
    668  $[1 oder 0 eingeben]$ G enetische Faktoren
    669  $[1 oder 0 eingeben]$ E xzessives Sturzrisiko
    670  $[1 oder 0 eingeben]$ S Schlaganfall in der Anamnese
    671  --------------------------------------
    672  Summe   Rate großer Blutungen
    673          pro 100 Patientenjahre
    674   0          1.9
    675   1          2.5
    676   2          5.3
    677   3          8.4
    678   4         10.4
    679  >4         12.3
    680
    681  Bewertung: Summe = $[Summe ausrechnen und bewerten]$"""
    682
    683                  app = wx.PyWidgetTester(size = (600, 600))
    684                  dlg = cTextExpansionFillInDlg(None, -1)
    685                  dlg.expansion = expansion
    686                  dlg.ShowModal()
    687                  #app.MainLoop()
    688          #----------------------------------------
    689          test_fillin()
    690