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