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