Gnumed.wxpython.gmDateTimeInput

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

# Source Code for Module Gnumed.wxpython.gmDateTimeInput

      1  """GNUmed date input widget
      2
      3  All GNUmed date input should happen via classes in
      4  this module.
      5
      6  @copyright: author(s)
      7  """
      8  #==============================================================================
      9  __version__ = "$Revision: 1.66 $"
     10  __author__  = "K. Hilbert <Karsten.Hilbert@gmx.net>"
     11  __licence__ = "GPL v2 or later (details at http://www.gnu.org)"
     12
     13  # standard libary
     14  import re, string, sys, time, datetime as pyDT, logging
     15
     16
     17  # 3rd party
     18  import mx.DateTime as mxDT
     19  import wx
     20  import wx.calendar
     21
     22
     23  # GNUmed specific
     24  if __name__ == '__main__':
     25          sys.path.insert(0, '../../')
     26  from Gnumed.pycommon import gmMatchProvider
     27  from Gnumed.pycommon import gmDateTime
     28  from Gnumed.pycommon import gmI18N
     29  from Gnumed.wxpython import gmPhraseWheel
     30  from Gnumed.wxpython import gmGuiHelpers
     31
     32  _log = logging.getLogger('gm.ui')
     33
     34  #============================================================
     35  #class cIntervalMatchProvider(gmMatchProvider.cMatchProvider):
     36  #       """Turns strings into candidate intervals."""
     37  #       def __init__(self):
     38  #
     39  #               gmMatchProvider.cMatchProvider.__init__(self)
     40  #
     41  #               self.setThresholds(aPhrase = 1, aWord = 998, aSubstring = 999)
     42  #               self.word_separators = None
     43  ##              self.ignored_chars("""[?!."'\\(){}\[\]<>~#*$%^_]+""")
     44  #       #--------------------------------------------------------
     45  #       # external API
     46  #       #--------------------------------------------------------
     47  #       #--------------------------------------------------------
     48  #       # base class API
     49  #       #--------------------------------------------------------
     50  #       def getMatchesByPhrase(self, aFragment):
     51  #               intv = gmDateTime.str2interval(str_interval = aFragment)
     52  #
     53  #               if intv is None:
     54  #                       return (False, [])
     55  #
     56  #               items = [{
     57  #                       'data': intv,
     58  #                       'field_label': gmDateTime.format_interval(intv, gmDateTime.acc_minutes),
     59  #                       'list_label': gmDateTime.format_interval(intv, gmDateTime.acc_minutes)
     60  #               }]
     61  #
     62  #               return (True, items)
     63  #       #--------------------------------------------------------
     64  #       def getMatchesByWord(self, aFragment):
     65  #               return self.getMatchesByPhrase(aFragment)
     66  #       #--------------------------------------------------------
     67  #       def getMatchesBySubstr(self, aFragment):
     68  #               return self.getMatchesByPhrase(aFragment)
     69  #       #--------------------------------------------------------
     70  #       def getAllMatches(self):
     71  #               matches = (False, [])
     72  #               return matches
     73  #============================================================
     74 -class cIntervalPhraseWheel(gmPhraseWheel.cPhraseWheel):
     75
     76 -        def __init__(self, *args, **kwargs):
     77
     78                  gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
     79                  self.phrase_separators = None
     80                  self.display_accuracy = None
     81          #--------------------------------------------------------
     82          # phrasewheel internal API
     83          #--------------------------------------------------------
     84 -        def _update_candidates_in_picklist(self, val):
     85                  intv = gmDateTime.str2interval(str_interval = val)
     86                  if intv is None:
     87                          self._current_match_candidates = []
     88                  else:
     89                          self._current_match_candidates = [{
     90                                  'data': intv,
     91                                  'field_label': gmDateTime.format_interval(intv, gmDateTime.acc_minutes),
     92                                  'list_label': gmDateTime.format_interval(intv, gmDateTime.acc_minutes)
     93                          }]
     94                  self._picklist.SetItems(self._current_match_candidates)
     95          #---------------------------------------------------------
     96  #       def _on_lose_focus(self, event):
     97  #               # are we valid ?
     98  #               if len(self._data) == 0:
     99  #                       self._set_data_to_first_match()
    100  #
    101  #               # let the base class do its thing
    102  #               super(cIntervalPhraseWheel, self)._on_lose_focus(event)
    103          #--------------------------------------------------------
    104 -        def _picklist_item2display_string(self, item=None):
    105                  intv = item['data']
    106                  if intv is not None:
    107                          return gmDateTime.format_interval (
    108                                  interval = intv,
    109                                  accuracy_wanted = self.display_accuracy
    110                          )
    111                  return item['field_label']
    112          #--------------------------------------------------------
    113 -        def _get_data_tooltip(self):
    114                  intv = self.GetData()
    115                  if intv is None:
    116                          return u''
    117                  return gmDateTime.format_interval (
    118                          interval = intv,
    119                          accuracy_wanted = self.display_accuracy
    120                  )
    121          #--------------------------------------------------------
    122          # external API
    123          #--------------------------------------------------------
    124 -        def SetValue(self, value):
    125
    126                  if isinstance(value, pyDT.timedelta):
    127                          self.SetText(data = value, suppress_smarts = True)
    128                          return
    129
    130                  if value is None:
    131                          value = u''
    132
    133                  super(cIntervalPhraseWheel, self).SetValue(value)
    134          #--------------------------------------------------------
    135 -        def SetText(self, value=u'', data=None, suppress_smarts=False):
    136
    137                  if data is not None:
    138                          if value.strip() == u'':
    139                                  value = gmDateTime.format_interval (
    140                                          interval = data,
    141                                          accuracy_wanted = self.display_accuracy
    142                                  )
    143
    144                  super(cIntervalPhraseWheel, self).SetText(value = value, data = data, suppress_smarts = suppress_smarts)
    145          #--------------------------------------------------------
    146 -        def SetData(self, data=None):
    147                  if data is None:
    148                          super(cIntervalPhraseWheel, self).SetText(u'', None)
    149                          return
    150
    151                  value = gmDateTime.format_interval (
    152                          interval = data,
    153                          accuracy_wanted = self.display_accuracy
    154                  )
    155                  super(cIntervalPhraseWheel, self).SetText(value = value, data = data)
    156          #--------------------------------------------------------
    157 -        def GetData(self):
    158                  if len(self._data) == 0:
    159                          self._set_data_to_first_match()
    160
    161                  return super(cIntervalPhraseWheel, self).GetData()
    162  #============================================================
    163 -class cCalendarDatePickerDlg(wx.Dialog):
    164          """Shows a calendar control from which the user can pick a date."""
    165 -        def __init__(self, parent):
    166
    167                  wx.Dialog.__init__(self, parent, title = _('Pick a date ...'))
    168                  panel = wx.Panel(self, -1)
    169
    170                  sizer = wx.BoxSizer(wx.VERTICAL)
    171                  panel.SetSizer(sizer)
    172
    173                  cal = wx.calendar.CalendarCtrl(panel)
    174
    175                  if sys.platform != 'win32':
    176                          # gtk truncates the year - this fixes it
    177                          w, h = cal.Size
    178                          cal.Size = (w+25, h)
    179                          cal.MinSize = cal.Size
    180
    181                  sizer.Add(cal, 0)
    182
    183                  button_sizer = wx.BoxSizer(wx.HORIZONTAL)
    184                  button_sizer.Add((0, 0), 1)
    185                  btn_ok = wx.Button(panel, wx.ID_OK)
    186                  btn_ok.SetDefault()
    187                  button_sizer.Add(btn_ok, 0, wx.ALL, 2)
    188                  button_sizer.Add((0, 0), 1)
    189                  btn_can = wx.Button(panel, wx.ID_CANCEL)
    190                  button_sizer.Add(btn_can, 0, wx.ALL, 2)
    191                  button_sizer.Add((0, 0), 1)
    192                  sizer.Add(button_sizer, 1, wx.EXPAND | wx.ALL, 10)
    193                  sizer.Fit(panel)
    194                  self.ClientSize = panel.Size
    195
    196                  cal.Bind(wx.EVT_KEY_DOWN, self.__on_key_down)
    197                  cal.SetFocus()
    198                  self.cal = cal
    199          #-----------------------------------------------------------
    200 -        def __on_key_down(self, evt):
    201                  code = evt.KeyCode
    202                  if code == wx.WXK_TAB:
    203                          self.cal.Navigate()
    204                  elif code in (wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER):
    205                          self.EndModal(wx.ID_OK)
    206                  elif code == wx.WXK_ESCAPE:
    207                          self.EndModal(wx.ID_CANCEL)
    208                  else:
    209                          evt.Skip()
    210
    211  #============================================================
    212 -class cDateMatchProvider(gmMatchProvider.cMatchProvider):
    213          """Turns strings into candidate dates.
    214
    215          Matching on "all" (*, '') will pop up a calendar :-)
    216          """
    217 -        def __init__(self):
    218
    219                  gmMatchProvider.cMatchProvider.__init__(self)
    220
    221                  self.setThresholds(aPhrase = 1, aWord = 998, aSubstring = 999)
    222                  self.word_separators = None
    223  #               self.ignored_chars("""[?!."'\\(){}\[\]<>~#*$%^_]+""")
    224          #--------------------------------------------------------
    225          # external API
    226          #--------------------------------------------------------
    227          #--------------------------------------------------------
    228          # base class API
    229          #--------------------------------------------------------
    230          # internal matching algorithms
    231          #
    232          # if we end up here:
    233          #       - aFragment will not be "None"
    234          #   - aFragment will be lower case
    235          #       - we _do_ deliver matches (whether we find any is a different story)
    236          #--------------------------------------------------------
    237 -        def getMatchesByPhrase(self, aFragment):
    238                  """Return matches for aFragment at start of phrases."""
    239                  matches = gmDateTime.str2pydt_matches(str2parse = aFragment.strip())
    240
    241                  if len(matches) == 0:
    242                          return (False, [])
    243
    244                  items = []
    245                  for match in matches:
    246                          if match['data'] is None:
    247                                  items.append ({
    248                                          'data': None,
    249                                          'field_label': match['label'],
    250                                          'list_label': match['label']
    251                                  })
    252                                  continue
    253
    254                          data = match['data'].replace (
    255                                  hour = 11,
    256                                  minute = 11,
    257                                  second = 11,
    258                                  microsecond = 111111
    259                          )
    260                          list_label = gmDateTime.pydt_strftime (
    261                                  data,
    262                                  format = '%A, %d. %B %Y (%x)',
    263                                  accuracy = gmDateTime.acc_days
    264                          )
    265                          items.append ({
    266                                  'data': data,
    267                                  'field_label': match['label'],
    268                                  'list_label': list_label
    269                          })
    270
    271                  return (True, items)
    272          #--------------------------------------------------------
    273 -        def getMatchesByWord(self, aFragment):
    274                  """Return matches for aFragment at start of words inside phrases."""
    275                  return self.getMatchesByPhrase(aFragment)
    276          #--------------------------------------------------------
    277 -        def getMatchesBySubstr(self, aFragment):
    278                  """Return matches for aFragment as a true substring."""
    279                  return self.getMatchesByPhrase(aFragment)
    280          #--------------------------------------------------------
    281 -        def getAllMatches(self):
    282                  """Return all items."""
    283
    284                  matches = (False, [])
    285                  return matches
    286
    287  #               # consider this:
    288  #               dlg = cCalendarDatePickerDlg(None)
    289  #               # FIXME: show below parent
    290  #               dlg.CentreOnScreen()
    291  #
    292  #               if dlg.ShowModal() == wx.ID_OK:
    293  #                       date = dlg.cal.Date
    294  #                       if date is not None:
    295  #                               if date.IsValid():
    296  #                                       date = gmDateTime.wxDate2py_dt(wxDate = date).replace (
    297  #                                               hour = 11,
    298  #                                               minute = 11,
    299  #                                               second = 11,
    300  #                                               microsecond = 111111
    301  #                                       )
    302  #                                       lbl = gmDateTime.pydt_strftime(date, format = '%Y-%m-%d', accuracy = gmDateTime.acc_days)
    303  #                                       matches = (True, [{'data': date, 'label': lbl}])
    304  #               dlg.Destroy()
    305  #
    306  #               return matches
    307  #============================================================
    308 -class cDateInputPhraseWheel(gmPhraseWheel.cPhraseWheel):
    309
    310 -        def __init__(self, *args, **kwargs):
    311
    312                  gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
    313
    314                  self.matcher = cDateMatchProvider()
    315                  self.phrase_separators = None
    316
    317                  self.static_tooltip_extra = _('<ALT-C/K>: pick from (c/k)alendar')
    318          #--------------------------------------------------------
    319          # internal helpers
    320          #--------------------------------------------------------
    321  #       def __text2timestamp(self):
    322  #
    323  #               self._update_candidates_in_picklist(val = self.GetValue().strip())
    324  #
    325  #               if len(self._current_match_candidates) == 1:
    326  #                       return self._current_match_candidates[0]['data']
    327  #
    328  #               return None
    329          #--------------------------------------------------------
    330 -        def __pick_from_calendar(self):
    331                  dlg = cCalendarDatePickerDlg(self)
    332                  # FIXME: show below parent
    333                  dlg.CentreOnScreen()
    334                  decision = dlg.ShowModal()
    335                  date = dlg.cal.Date
    336                  dlg.Destroy()
    337
    338                  if decision != wx.ID_OK:
    339                          return
    340
    341                  if date is None:
    342                          return
    343
    344                  if not date.IsValid():
    345                          return
    346
    347                  date = gmDateTime.wxDate2py_dt(wxDate = date).replace (
    348                          hour = 11,
    349                          minute = 11,
    350                          second = 11,
    351                          microsecond = 111111
    352                  )
    353                  val = gmDateTime.pydt_strftime(date, format = '%Y-%m-%d', accuracy = gmDateTime.acc_days)
    354                  self.SetText(value = val, data = date, suppress_smarts = True)
    355          #--------------------------------------------------------
    356          # phrasewheel internal API
    357          #--------------------------------------------------------
    358 -        def _on_lose_focus(self, event):
    359                  # no valid date yet ?
    360                  if len(self._data) == 0:
    361                          self._set_data_to_first_match()
    362                          date = self.GetData()
    363                          if date is not None:
    364                                  self.SetValue(gmDateTime.pydt_strftime(date, format = '%Y-%m-%d', accuracy = gmDateTime.acc_days))
    365
    366                  # let the base class do its thing
    367                  super(cDateInputPhraseWheel, self)._on_lose_focus(event)
    368          #--------------------------------------------------------
    369 -        def _picklist_item2display_string(self, item=None):
    370                  data = item['data']
    371                  if data is not None:
    372                          return gmDateTime.pydt_strftime(data, format = '%Y-%m-%d', accuracy = gmDateTime.acc_days)
    373                  return item['field_label']
    374          #--------------------------------------------------------
    375 -        def _on_key_down(self, event):
    376
    377                  # <ALT-C> / <ALT-K> -> calendar
    378                  if event.AltDown() is True:
    379                          char = unichr(event.GetUnicodeKey())
    380                          if char in u'ckCK':
    381                                  self.__pick_from_calendar()
    382                                  return
    383
    384                  super(cDateInputPhraseWheel, self)._on_key_down(event)
    385          #--------------------------------------------------------
    386 -        def _get_data_tooltip(self):
    387                  if len(self._data) == 0:
    388                          return u''
    389
    390                  date = self.GetData()
    391                  # if match provider only provided completions
    392                  # but not a full date with it
    393                  if date is None:
    394                          return u''
    395
    396                  return gmDateTime.pydt_strftime (
    397                          date,
    398                          format = '%A, %d. %B %Y (%x)',
    399                          accuracy = gmDateTime.acc_days
    400                  )
    401          #--------------------------------------------------------
    402          # external API
    403          #--------------------------------------------------------
    404 -        def SetValue(self, value):
    405
    406                  if isinstance(value, pyDT.datetime):
    407                          date = value.replace (
    408                                  hour = 11,
    409                                  minute = 11,
    410                                  second = 11,
    411                                  microsecond = 111111
    412                          )
    413                          self.SetText(data = date, suppress_smarts = True)
    414                          return
    415
    416                  if value is None:
    417                          value = u''
    418
    419                  super(self.__class__, self).SetValue(value)
    420          #--------------------------------------------------------
    421 -        def SetText(self, value=u'', data=None, suppress_smarts=False):
    422
    423                  if data is not None:
    424                          if isinstance(data, gmDateTime.cFuzzyTimestamp):
    425                                  data = data.timestamp.replace (
    426                                          hour = 11,
    427                                          minute = 11,
    428                                          second = 11,
    429                                          microsecond = 111111
    430                                  )
    431                          if value.strip() == u'':
    432                                  value = gmDateTime.pydt_strftime(data, format = '%Y-%m-%d', accuracy = gmDateTime.acc_days)
    433
    434                  super(self.__class__, self).SetText(value = value, data = data, suppress_smarts = suppress_smarts)
    435          #--------------------------------------------------------
    436 -        def SetData(self, data=None):
    437                  if data is None:
    438                          gmPhraseWheel.cPhraseWheel.SetText(self, u'', None)
    439                          return
    440                  self.SetText(data = data)
    441          #--------------------------------------------------------
    442 -        def GetData(self):
    443                  if len(self._data) == 0:
    444                          self._set_data_to_first_match()
    445
    446                  return super(self.__class__, self).GetData()
    447          #--------------------------------------------------------
    448 -        def is_valid_timestamp(self, allow_empty=True):
    449                  if len(self._data) > 0:
    450                          self.display_as_valid(True)
    451                          return True
    452
    453                  if self.GetValue().strip() == u'':
    454                          if allow_empty:
    455                                  self.display_as_valid(True)
    456                                  return True
    457                          else:
    458                                  self.display_as_valid(False)
    459                                  return False
    460
    461                  # skip showing calendar on '*' from here
    462                  if self.GetValue().strip() == u'*':
    463                          self.display_as_valid(False)
    464                          return False
    465
    466                  # try to auto-snap to first match
    467                  self._set_data_to_first_match()
    468                  if len(self._data) == 0:
    469                          self.display_as_valid(False)
    470                          return False
    471
    472                  date = self.GetData()
    473                  self.SetValue(gmDateTime.pydt_strftime(date, format = '%Y-%m-%d', accuracy = gmDateTime.acc_days))
    474                  self.display_as_valid(True)
    475                  return True
    476          #--------------------------------------------------------
    477          # properties
    478          #--------------------------------------------------------
    479 -        def _get_date(self):
    480                  return self.GetData()
    481
    482 -        def _set_date(self, date):
    483                  raise AttributeError('._set_date not implemented')
    484  #               val = gmDateTime.pydt_strftime(date, format = '%Y-%m-%d', accuracy = gmDateTime.acc_days)
    485  #               self.data = date.replace (
    486  #                       hour = 11,
    487  #                       minute = 11,
    488  #                       second = 11,
    489  #                       microsecond = 111111
    490  #               )
    491
    492          date = property(_get_date, _set_date)
    493  #============================================================
    494 -class cMatchProvider_FuzzyTimestamp(gmMatchProvider.cMatchProvider):
    495 -        def __init__(self):
    496                  self.__allow_past = 1
    497                  self.__shifting_base = None
    498
    499                  gmMatchProvider.cMatchProvider.__init__(self)
    500
    501                  self.setThresholds(aPhrase = 1, aWord = 998, aSubstring = 999)
    502                  self.word_separators = None
    503  #               self.ignored_chars("""[?!."'\\(){}\[\]<>~#*$%^_]+""")
    504          #--------------------------------------------------------
    505          # external API
    506          #--------------------------------------------------------
    507          #--------------------------------------------------------
    508          # base class API
    509          #--------------------------------------------------------
    510          # internal matching algorithms
    511          #
    512          # if we end up here:
    513          #       - aFragment will not be "None"
    514          #   - aFragment will be lower case
    515          #       - we _do_ deliver matches (whether we find any is a different story)
    516          #--------------------------------------------------------
    517 -        def getMatchesByPhrase(self, aFragment):
    518                  """Return matches for aFragment at start of phrases."""
    519                  matches = gmDateTime.str2fuzzy_timestamp_matches(aFragment.strip())
    520
    521                  if len(matches) == 0:
    522                          return (False, [])
    523
    524                  items = []
    525                  for match in matches:
    526                          items.append ({
    527                                  'data': match['data'],
    528                                  'field_label': match['label'],
    529                                  'list_label': match['label']
    530                          })
    531
    532                  return (True, items)
    533          #--------------------------------------------------------
    534 -        def getMatchesByWord(self, aFragment):
    535                  """Return matches for aFragment at start of words inside phrases."""
    536                  return self.getMatchesByPhrase(aFragment)
    537          #--------------------------------------------------------
    538 -        def getMatchesBySubstr(self, aFragment):
    539                  """Return matches for aFragment as a true substring."""
    540                  return self.getMatchesByPhrase(aFragment)
    541          #--------------------------------------------------------
    542 -        def getAllMatches(self):
    543                  """Return all items."""
    544                  return (False, [])
    545  #==================================================
    546 -class cFuzzyTimestampInput(gmPhraseWheel.cPhraseWheel):
    547
    548 -        def __init__(self, *args, **kwargs):
    549
    550                  gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
    551
    552                  self.matcher = cMatchProvider_FuzzyTimestamp()
    553                  self.phrase_separators = None
    554                  self.selection_only = True
    555                  self.selection_only_error_msg = _('Cannot interpret input as timestamp.')
    556                  self.display_accuracy = None
    557          #--------------------------------------------------------
    558          # internal helpers
    559          #--------------------------------------------------------
    560 -        def __text2timestamp(self, val=None):
    561                  if val is None:
    562                          val = self.GetValue()
    563                  val = val.strip()
    564                  if val == u'':
    565                          return None
    566                  success, matches = self.matcher.getMatchesByPhrase(val)
    567                  if len(matches) == 1:
    568                          return matches[0]['data']
    569                  return None
    570          #--------------------------------------------------------
    571          # phrasewheel internal API
    572          #--------------------------------------------------------
    573 -        def _on_lose_focus(self, event):
    574                  # are we valid ?
    575                  if self.data is None:
    576                          # no, so try
    577                          date = self.__text2timestamp()
    578                          if date is not None:
    579                                  self.SetValue(value = date.format_accurately(accuracy = self.display_accuracy))
    580                                  self.data = date
    581
    582                  # let the base class do its thing
    583                  gmPhraseWheel.cPhraseWheel._on_lose_focus(self, event)
    584          #--------------------------------------------------------
    585 -        def _picklist_item2display_string(self, item=None):
    586                  data = item['data']
    587                  if data is not None:
    588                          return data.format_accurately(accuracy = self.display_accuracy)
    589                  return item['field_label']
    590          #--------------------------------------------------------
    591          # external API
    592          #--------------------------------------------------------
    593 -        def SetText(self, value=u'', data=None, suppress_smarts=False):
    594
    595                  if data is not None:
    596                          if isinstance(data, pyDT.datetime):
    597                                  data = gmDateTime.cFuzzyTimestamp(timestamp=data)
    598                          if value.strip() == u'':
    599                                  value = data.format_accurately(accuracy = self.display_accuracy)
    600
    601                  gmPhraseWheel.cPhraseWheel.SetText(self, value = value, data = data, suppress_smarts = suppress_smarts)
    602          #--------------------------------------------------------
    603 -        def SetData(self, data=None):
    604                  if data is None:
    605                          gmPhraseWheel.cPhraseWheel.SetText(self, u'', None)
    606                  else:
    607                          if isinstance(data, pyDT.datetime):
    608                                  data = gmDateTime.cFuzzyTimestamp(timestamp=data)
    609                          gmPhraseWheel.cPhraseWheel.SetText(self, value = data.format_accurately(accuracy = self.display_accuracy), data = data)
    610          #--------------------------------------------------------
    611 -        def is_valid_timestamp(self, empty_is_valid=True):
    612                  if self.GetData() is not None:
    613                          return True
    614
    615                  # skip empty value
    616                  if self.GetValue().strip() == u'':
    617                          if empty_is_valid:
    618                                  return True
    619                          return False
    620
    621                  date = self.__text2timestamp()
    622                  if date is None:
    623                          return False
    624
    625                  self.SetText (
    626                          value = date.format_accurately(accuracy = self.display_accuracy),
    627                          data = date,
    628                          suppress_smarts = True
    629                  )
    630
    631                  return True
    632  #==================================================
    633  # main
    634  #--------------------------------------------------
    635  if __name__ == '__main__':
    636
    637          if len(sys.argv) < 2:
    638                  sys.exit()
    639
    640          if sys.argv[1] != 'test':
    641                  sys.exit()
    642
    643          gmI18N.activate_locale()
    644          gmI18N.install_domain(domain='gnumed')
    645          gmDateTime.init()
    646
    647          #----------------------------------------------------
    648 -        def test_cli():
    649                  mp = cMatchProvider_FuzzyTimestamp()
    650                  mp.word_separators = None
    651                  mp.setThresholds(aWord = 998, aSubstring = 999)
    652                  val = None
    653                  while val != 'exit':
    654                          print "************************************"
    655                          val = raw_input('Enter date fragment ("exit" to quit): ')
    656                          found, matches = mp.getMatches(aFragment=val)
    657                          for match in matches:
    658                                  #print match
    659                                  print match['label']
    660                                  print match['data']
    661                                  print "---------------"
    662          #--------------------------------------------------------
    663 -        def test_fuzzy_picker():
    664                  app = wx.PyWidgetTester(size = (300, 40))
    665                  app.SetWidget(cFuzzyTimestampInput, id=-1, size=(180,20), pos=(10,20))
    666                  app.MainLoop()
    667          #--------------------------------------------------------
    668 -        def test_picker():
    669                  app = wx.PyWidgetTester(size = (300, 40))
    670                  app.SetWidget(cDateInputPhraseWheel, id=-1, size=(180,20), pos=(10,20))
    671                  app.MainLoop()
    672          #--------------------------------------------------------
    673          #test_cli()
    674          #test_fuzzy_picker()
    675          test_picker()
    676
    677  #==================================================
    678