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

# Source Code for Module Gnumed.wxpython.gmWaitingListWidgets

      1  """GNUmed data pack related widgets."""
      2  #================================================================
      3  __author__ = 'karsten.hilbert@gmx.net'
      4  __license__ = 'GPL v2 or later (details at http://www.gnu.org)'
      5
      6  # stdlib
      7  import logging
      8  import sys
      9
     10
     11  # 3rd party
     12  import wx
     13
     14
     15  # GNUmed
     16  if __name__ == '__main__':
     17          sys.path.insert(0, '../../')
     18
     19  from Gnumed.pycommon import gmDispatcher
     20  from Gnumed.pycommon import gmTools
     21  from Gnumed.pycommon import gmMatchProvider
     22  from Gnumed.pycommon import gmI18N
     23
     24  from Gnumed.business import gmSurgery
     25  from Gnumed.business import gmPerson
     26
     27  from Gnumed.wxpython import gmEditArea
     28  from Gnumed.wxpython import gmPhraseWheel
     29  from Gnumed.wxpython import gmRegetMixin
     30  from Gnumed.wxpython import gmPatSearchWidgets
     31  from Gnumed.wxpython import gmGuiHelpers
     32
     33
     34  _log = logging.getLogger('gm.ui')
     35  #============================================================
     36  # waiting list widgets
     37  #============================================================
     38 -class cWaitingZonePhraseWheel(gmPhraseWheel.cPhraseWheel):
     39
     40 -        def __init__(self, *args, **kwargs):
     41
     42                  gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
     43
     44                  mp = gmMatchProvider.cMatchProvider_FixedList(aSeq = [])
     45                  mp.setThresholds(1, 2, 2)
     46                  self.matcher = mp
     47                  self.selection_only = False
     48
     49          #--------------------------------------------------------
     50 -        def update_matcher(self, items):
     51                  self.matcher.set_items([ {'data': i, 'list_label': i, 'field_label': i, 'weight': 1} for i in items ])
     52
     53  #============================================================
     54  from Gnumed.wxGladeWidgets import wxgWaitingListEntryEditAreaPnl
     55
     56 -class cWaitingListEntryEditAreaPnl(wxgWaitingListEntryEditAreaPnl.wxgWaitingListEntryEditAreaPnl, gmEditArea.cGenericEditAreaMixin):
     57
     58 -        def __init__ (self, *args, **kwargs):
     59
     60                  try:
     61                          self.patient = kwargs['patient']
     62                          del kwargs['patient']
     63                  except KeyError:
     64                          self.patient = None
     65
     66                  try:
     67                          data = kwargs['entry']
     68                          del kwargs['entry']
     69                  except KeyError:
     70                          data = None
     71
     72                  wxgWaitingListEntryEditAreaPnl.wxgWaitingListEntryEditAreaPnl.__init__(self, *args, **kwargs)
     73                  gmEditArea.cGenericEditAreaMixin.__init__(self)
     74
     75                  if data is None:
     76                          self.mode = 'new'
     77                  else:
     78                          self.data = data
     79                          self.mode = 'edit'
     80
     81                  praxis = gmSurgery.gmCurrentPractice()
     82                  pats = praxis.waiting_list_patients
     83                  zones = {}
     84                  zones.update([ [p['waiting_zone'], None] for p in pats if p['waiting_zone'] is not None ])
     85                  self._PRW_zone.update_matcher(items = zones.keys())
     86          #--------------------------------------------------------
     87          # edit area mixin API
     88          #--------------------------------------------------------
     89 -        def _refresh_as_new(self):
     90                  if self.patient is None:
     91                          self._PRW_patient.person = None
     92                          self._PRW_patient.Enable(True)
     93                          self._PRW_patient.SetFocus()
     94                  else:
     95                          self._PRW_patient.person = self.patient
     96                          self._PRW_patient.Enable(False)
     97                          self._TCTRL_comment.SetFocus()
     98                  self._PRW_patient._display_name()
     99
    100                  self._TCTRL_comment.SetValue(u'')
    101                  self._PRW_zone.SetValue(u'')
    102                  self._SPCTRL_urgency.SetValue(0)
    103          #--------------------------------------------------------
    104 -        def _refresh_from_existing(self):
    105                  self._PRW_patient.person = gmPerson.cIdentity(aPK_obj = self.data['pk_identity'])
    106                  self._PRW_patient.Enable(False)
    107                  self._PRW_patient._display_name()
    108
    109                  self._TCTRL_comment.SetValue(gmTools.coalesce(self.data['comment'], u''))
    110                  self._PRW_zone.SetValue(gmTools.coalesce(self.data['waiting_zone'], u''))
    111                  self._SPCTRL_urgency.SetValue(self.data['urgency'])
    112
    113                  self._TCTRL_comment.SetFocus()
    114          #--------------------------------------------------------
    115 -        def _valid_for_save(self):
    116                  validity = True
    117
    118                  self.display_tctrl_as_valid(tctrl = self._PRW_patient, valid = (self._PRW_patient.person is not None))
    119                  validity = (self._PRW_patient.person is not None)
    120
    121                  if validity is False:
    122                          gmDispatcher.send(signal = 'statustext', msg = _('Cannot add to waiting list. Missing essential input.'))
    123
    124                  return validity
    125          #----------------------------------------------------------------
    126 -        def _save_as_new(self):
    127                  # FIXME: filter out dupes
    128                  self._PRW_patient.person.put_on_waiting_list (
    129                          urgency = self._SPCTRL_urgency.GetValue(),
    130                          comment = gmTools.none_if(self._TCTRL_comment.GetValue().strip(), u''),
    131                          zone = gmTools.none_if(self._PRW_zone.GetValue().strip(), u'')
    132                  )
    133                  # dummy:
    134                  self.data = {'pk_identity': self._PRW_patient.person.ID, 'comment': None, 'waiting_zone': None, 'urgency': 0}
    135                  return True
    136          #----------------------------------------------------------------
    137 -        def _save_as_update(self):
    138                  gmSurgery.gmCurrentPractice().update_in_waiting_list (
    139                          pk = self.data['pk_waiting_list'],
    140                          urgency = self._SPCTRL_urgency.GetValue(),
    141                          comment = self._TCTRL_comment.GetValue().strip(),
    142                          zone = self._PRW_zone.GetValue().strip()
    143                  )
    144                  return True
    145  #============================================================
    146  from Gnumed.wxGladeWidgets import wxgWaitingListPnl
    147
    148 -class cWaitingListPnl(wxgWaitingListPnl.wxgWaitingListPnl, gmRegetMixin.cRegetOnPaintMixin):
    149
    150 -        def __init__ (self, *args, **kwargs):
    151
    152                  wxgWaitingListPnl.wxgWaitingListPnl.__init__(self, *args, **kwargs)
    153                  gmRegetMixin.cRegetOnPaintMixin.__init__(self)
    154
    155                  self.__current_zone = None
    156
    157                  self.__init_ui()
    158                  self.__register_events()
    159          #--------------------------------------------------------
    160          # interal helpers
    161          #--------------------------------------------------------
    162 -        def __init_ui(self):
    163                  self._LCTRL_patients.set_columns ([
    164                          _('Zone'),
    165                          _('Urgency'),
    166                          #' ! ',
    167                          _('Waiting time'),
    168                          _('Patient'),
    169                          _('Born'),
    170                          _('Comment')
    171                  ])
    172                  self._LCTRL_patients.set_column_widths(widths = [wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE_USEHEADER, wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE, wx.LIST_AUTOSIZE])
    173                  self._LCTRL_patients.item_tooltip_callback = self._on_get_list_tooltip
    174                  self._PRW_zone.add_callback_on_selection(callback = self._on_zone_selected)
    175                  self._PRW_zone.add_callback_on_lose_focus(callback = self._on_zone_selected)
    176          #--------------------------------------------------------
    177 -        def _on_get_list_tooltip(self, entry):
    178
    179                  dob = gmTools.coalesce (
    180                                  gmTools.coalesce (
    181                                          entry['dob'],
    182                                          u'',
    183                                          function_initial = ('strftime', '%d %b %Y')
    184                                  ),
    185                                  u'',
    186                                  u' (%s)',
    187                                  function_initial = ('decode', gmI18N.get_encoding())
    188                  )
    189
    190                  tt = _(
    191                          '%s patients are waiting.\n'
    192                          '\n'
    193                          'Doubleclick to activate (entry will stay in list).'
    194                  ) % self._LCTRL_patients.GetItemCount()
    195
    196                  tt += _(
    197                          '\n'
    198                          '%s\n'
    199                          'Patient: %s%s\n'
    200                          '%s'
    201                          'Urgency: %s\n'
    202                          'Time: %s\n'
    203                          '%s'
    204                  ) % (
    205                          gmTools.u_box_horiz_single * 50,
    206                          u'%s, %s (%s)' % (entry['lastnames'], entry['firstnames'], entry['l10n_gender']),
    207                          dob,
    208                          gmTools.coalesce(entry['waiting_zone'], u'', _('Zone: %s\n')),
    209                          entry['urgency'],
    210                          entry['waiting_time_formatted'].replace(u'00 ', u'', 1).replace('00:', u'').lstrip('0'),
    211                          gmTools.coalesce(entry['comment'], u'', u'\n%s')
    212                  )
    213
    214                  return tt
    215          #--------------------------------------------------------
    216 -        def __register_events(self):
    217                  gmDispatcher.connect(signal = u'waiting_list_generic_mod_db', receiver = self._on_waiting_list_modified)
    218          #--------------------------------------------------------
    219 -        def __refresh_waiting_list(self):
    220
    221                  praxis = gmSurgery.gmCurrentPractice()
    222                  pats = praxis.waiting_list_patients
    223
    224                  # set matcher to all zones currently in use
    225                  zones = {}
    226                  zones.update([ [p['waiting_zone'], None] for p in pats if p['waiting_zone'] is not None ])
    227                  self._PRW_zone.update_matcher(items = zones.keys())
    228
    229                  # filter patient list by zone and set waiting list
    230                  self.__current_zone = self._PRW_zone.GetValue().strip()
    231                  if self.__current_zone == u'':
    232                          pats = [ p for p in pats ]
    233                  else:
    234                          pats = [ p for p in pats if p['waiting_zone'] == self.__current_zone ]
    235
    236                  old_pks = [ d['pk_waiting_list'] for d in self._LCTRL_patients.get_selected_item_data() ]
    237                  self._LCTRL_patients.set_string_items (
    238                          [ [
    239                                  gmTools.coalesce(p['waiting_zone'], u''),
    240                                  p['urgency'],
    241                                  p['waiting_time_formatted'].replace(u'00 ', u'', 1).replace('00:', u'').lstrip('0'),
    242                                  u'%s, %s (%s)' % (p['lastnames'], p['firstnames'], p['l10n_gender']),
    243                                  gmTools.coalesce (
    244                                          gmTools.coalesce (
    245                                                  p['dob'],
    246                                                  u'',
    247                                                  function_initial = ('strftime', '%d %b %Y')
    248                                          ),
    249                                          u'',
    250                                          function_initial = ('decode', gmI18N.get_encoding())
    251                                  ),
    252                                  gmTools.coalesce(p['comment'], u'').split('\n')[0]
    253                          ] for p in pats ]
    254                  )
    255                  self._LCTRL_patients.set_column_widths()
    256                  self._LCTRL_patients.set_data(pats)
    257                  new_selections = []
    258                  new_pks = [ p['pk_waiting_list'] for p in pats ]
    259                  for old_pk in old_pks:
    260                          if old_pk in new_pks:
    261                                  new_selections.append(new_pks.index(old_pk))
    262                  self._LCTRL_patients.selections = new_selections
    263                  self._LCTRL_patients.Refresh()
    264
    265                  self._LBL_no_of_patients.SetLabel(_('(%s patients)') % len(pats))
    266
    267                  if len(pats) == 0:
    268                          self._BTN_activate.Enable(False)
    269                          self._BTN_activateplus.Enable(False)
    270                          self._BTN_remove.Enable(False)
    271                          self._BTN_edit.Enable(False)
    272                          self._BTN_up.Enable(False)
    273                          self._BTN_down.Enable(False)
    274                  else:
    275                          self._BTN_activate.Enable(True)
    276                          self._BTN_activateplus.Enable(True)
    277                          self._BTN_remove.Enable(True)
    278                          self._BTN_edit.Enable(True)
    279                  if len(pats) > 1:
    280                          self._BTN_up.Enable(True)
    281                          self._BTN_down.Enable(True)
    282          #--------------------------------------------------------
    283          # event handlers
    284          #--------------------------------------------------------
    285 -        def _on_zone_selected(self, zone=None):
    286                  if self.__current_zone == self._PRW_zone.GetValue().strip():
    287                          return True
    288                  wx.CallAfter(self.__refresh_waiting_list)
    289                  return True
    290          #--------------------------------------------------------
    291 -        def _on_waiting_list_modified(self, *args, **kwargs):
    292                  wx.CallAfter(self._schedule_data_reget)
    293          #--------------------------------------------------------
    294 -        def _on_list_item_activated(self, evt):
    295                  item = self._LCTRL_patients.get_selected_item_data(only_one=True)
    296                  if item is None:
    297                          return
    298                  pat = gmPerson.cIdentity(aPK_obj = item['pk_identity'])
    299                  wx.CallAfter(gmPatSearchWidgets.set_active_patient, patient = pat)
    300          #--------------------------------------------------------
    301 -        def _on_activate_button_pressed(self, evt):
    302                  item = self._LCTRL_patients.get_selected_item_data(only_one=True)
    303                  if item is None:
    304                          return
    305                  pat = gmPerson.cIdentity(aPK_obj = item['pk_identity'])
    306                  wx.CallAfter(gmPatSearchWidgets.set_active_patient, patient = pat)
    307          #--------------------------------------------------------
    308 -        def _on_activateplus_button_pressed(self, evt):
    309                  item = self._LCTRL_patients.get_selected_item_data(only_one=True)
    310                  if item is None:
    311                          return
    312                  pat = gmPerson.cIdentity(aPK_obj = item['pk_identity'])
    313                  gmSurgery.gmCurrentPractice().remove_from_waiting_list(pk = item['pk_waiting_list'])
    314                  wx.CallAfter(gmPatSearchWidgets.set_active_patient, patient = pat)
    315          #--------------------------------------------------------
    316 -        def _on_add_patient_button_pressed(self, evt):
    317
    318                  curr_pat = gmPerson.gmCurrentPatient()
    319                  if not curr_pat.connected:
    320                          gmDispatcher.send(signal = 'statustext', msg = _('Cannot add waiting list entry: No patient selected.'), beep = True)
    321                          return
    322
    323                  ea = cWaitingListEntryEditAreaPnl(self, -1, patient = curr_pat)
    324                  dlg = gmEditArea.cGenericEditAreaDlg2(self, -1, edit_area = ea, single_entry = True)
    325                  dlg.ShowModal()
    326                  dlg.Destroy()
    327          #--------------------------------------------------------
    328 -        def _on_edit_button_pressed(self, event):
    329                  item = self._LCTRL_patients.get_selected_item_data(only_one=True)
    330                  if item is None:
    331                          return
    332                  ea = cWaitingListEntryEditAreaPnl(self, -1, entry = item)
    333                  dlg = gmEditArea.cGenericEditAreaDlg2(self, -1, edit_area = ea, single_entry = True)
    334                  dlg.ShowModal()
    335                  dlg.Destroy()
    336          #--------------------------------------------------------
    337 -        def _on_remove_button_pressed(self, evt):
    338                  item = self._LCTRL_patients.get_selected_item_data(only_one = True)
    339                  if item is None:
    340                          return
    341                  cmt = gmTools.coalesce(item['comment'], u'').split('\n')[0].strip()[:40]
    342                  if cmt != u'':
    343                          cmt += u'\n'
    344                  question = _(
    345                          'Are you sure you want to remove\n'
    346                          '\n'
    347                          ' %s, %s (%s)\n'
    348                          ' born: %s\n'
    349                          ' %s'
    350                          '\n'
    351                          'from the waiting list ?'
    352                  ) % (
    353                          item['lastnames'],
    354                          item['firstnames'],
    355                          item['l10n_gender'],
    356                          gmTools.coalesce (
    357                                  gmTools.coalesce (
    358                                          item['dob'],
    359                                          u'',
    360                                          function_initial = ('strftime', '%d %b %Y')
    361                                  ),
    362                                  u'',
    363                                  function_initial = ('decode', gmI18N.get_encoding())
    364                          ),
    365                          cmt
    366                  )
    367                  do_delete = gmGuiHelpers.gm_show_question (
    368                          title = _('Delete waiting list entry'),
    369                          question = question
    370                  )
    371                  if not do_delete:
    372                          return
    373                  gmSurgery.gmCurrentPractice().remove_from_waiting_list(pk = item['pk_waiting_list'])
    374          #--------------------------------------------------------
    375 -        def _on_up_button_pressed(self, evt):
    376                  item = self._LCTRL_patients.get_selected_item_data(only_one=True)
    377                  if item is None:
    378                          return
    379                  gmSurgery.gmCurrentPractice().raise_in_waiting_list(current_position = item['list_position'])
    380          #--------------------------------------------------------
    381 -        def _on_down_button_pressed(self, evt):
    382                  item = self._LCTRL_patients.get_selected_item_data(only_one=True)
    383                  if item is None:
    384                          return
    385                  gmSurgery.gmCurrentPractice().lower_in_waiting_list(current_position = item['list_position'])
    386          #--------------------------------------------------------
    387          # edit
    388          #--------------------------------------------------------
    389          # reget-on-paint API
    390          #--------------------------------------------------------
    391 -        def _populate_with_data(self):
    392                  self.__refresh_waiting_list()
    393                  return True
    394  #================================================================
    395  # main
    396  #----------------------------------------------------------------
    397  if __name__ == '__main__':
    398
    399          if len(sys.argv) < 2:
    400                  sys.exit()
    401
    402          if sys.argv[1] != 'test':
    403                  sys.exit()
    404
    405          gmI18N.activate_locale()
    406          gmI18N.install_domain()
    407
    408          #--------------------------------------------------------
    409  #       def test_generic_codes_prw():
    410  #               gmPG2.get_connection()
    411  #               app = wx.PyWidgetTester(size = (500, 40))
    412  #               pw = cGenericCodesPhraseWheel(app.frame, -1)
    413  #               #pw.set_context(context = u'zip', val = u'04318')
    414  #               app.frame.Show(True)
    415  #               app.MainLoop()
    416  #       #--------------------------------------------------------
    417  #       test_generic_codes_prw()
    418
    419          app = wx.PyWidgetTester(size = (200, 40))
    420          app.SetWidget(cWaitingListPnl, -1)
    421          app.MainLoop()
    422
    423  #================================================================
    424