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

Source Code for Module Gnumed.wxpython.gmVaccWidgets

   1  """GNUmed immunisation/vaccination widgets. 
   2   
   3  Modelled after Richard Terry's design document. 
   4   
   5  copyright: authors 
   6  """ 
   7  #====================================================================== 
   8  __version__ = "$Revision: 1.36 $" 
   9  __author__ = "R.Terry, S.J.Tan, K.Hilbert" 
  10  __license__ = "GPL v2 or later (details at http://www.gnu.org)" 
  11   
  12  import sys, time, logging, webbrowser 
  13   
  14   
  15  import wx 
  16   
  17   
  18  if __name__ == '__main__': 
  19          sys.path.insert(0, '../../') 
  20  from Gnumed.pycommon import gmDispatcher, gmMatchProvider, gmTools, gmI18N 
  21  from Gnumed.pycommon import gmCfg, gmDateTime 
  22  from Gnumed.business import gmPerson, gmVaccination, gmSurgery 
  23  from Gnumed.wxpython import gmPhraseWheel, gmTerryGuiParts, gmRegetMixin, gmGuiHelpers 
  24  from Gnumed.wxpython import gmEditArea, gmListWidgets 
  25   
  26   
  27  _log = logging.getLogger('gm.vaccination') 
  28  _log.info(__version__) 
  29   
  30  #====================================================================== 
  31  # vaccination indication related widgets 
  32  #---------------------------------------------------------------------- 
33 -def manage_vaccination_indications(parent=None):
34 35 if parent is None: 36 parent = wx.GetApp().GetTopWindow() 37 #------------------------------------------------------------ 38 def refresh(lctrl): 39 inds = gmVaccination.get_indications(order_by = 'description') 40 41 items = [ [ 42 i['description'], 43 gmTools.coalesce ( 44 i['atcs_single_indication'], 45 u'', 46 u'%s' 47 ), 48 gmTools.coalesce ( 49 i['atcs_combi_indication'], 50 u'', 51 u'%s' 52 ), 53 u'%s' % i['id'] 54 ] for i in inds ] 55 56 lctrl.set_string_items(items) 57 lctrl.set_data(inds)
58 #------------------------------------------------------------ 59 gmListWidgets.get_choices_from_list ( 60 parent = parent, 61 msg = _('\nConditions preventable by vaccination as currently known to GNUmed.\n'), 62 caption = _('Showing vaccination preventable conditions.'), 63 columns = [ _('Condition'), _('ATCs: single-condition vaccines'), _('ATCs: multi-condition vaccines'), u'#' ], 64 single_selection = True, 65 refresh_callback = refresh 66 ) 67 #---------------------------------------------------------------------- 68 from Gnumed.wxGladeWidgets import wxgVaccinationIndicationsPnl 69
70 -class cVaccinationIndicationsPnl(wxgVaccinationIndicationsPnl.wxgVaccinationIndicationsPnl):
71
72 - def __init__(self, *args, **kwargs):
73 74 wxgVaccinationIndicationsPnl.wxgVaccinationIndicationsPnl.__init__(self, *args, **kwargs) 75 76 self.__indication2field = { 77 u'coxiella burnetii (Q fever)': self._CHBOX_coxq, 78 u'salmonella typhi (typhoid)': self._CHBOX_typhoid, 79 u'varicella (chickenpox, shingles)': self._CHBOX_varicella, 80 u'influenza (seasonal)': self._CHBOX_influenza, 81 u'bacillus anthracis (Anthrax)': self._CHBOX_anthrax, 82 u'human papillomavirus': self._CHBOX_hpv, 83 u'rotavirus': self._CHBOX_rota, 84 u'tuberculosis': self._CHBOX_tuberculosis, 85 u'variola virus (smallpox)': self._CHBOX_smallpox, 86 u'influenza (H1N1)': self._CHBOX_h1n1, 87 u'cholera': self._CHBOX_cholera, 88 u'diphtheria': self._CHBOX_diphtheria, 89 u'haemophilus influenzae b': self._CHBOX_hib, 90 u'hepatitis A': self._CHBOX_hepA, 91 u'hepatitis B': self._CHBOX_hepB, 92 u'japanese B encephalitis': self._CHBOX_japanese, 93 u'measles': self._CHBOX_measles, 94 u'meningococcus A': self._CHBOX_menA, 95 u'meningococcus C': self._CHBOX_menC, 96 u'meningococcus W': self._CHBOX_menW, 97 u'meningococcus Y': self._CHBOX_menY, 98 u'mumps': self._CHBOX_mumps, 99 u'pertussis': self._CHBOX_pertussis, 100 u'pneumococcus': self._CHBOX_pneumococcus, 101 u'poliomyelitis': self._CHBOX_polio, 102 u'rabies': self._CHBOX_rabies, 103 u'rubella': self._CHBOX_rubella, 104 u'tetanus': self._CHBOX_tetanus, 105 u'tick-borne meningoencephalitis': self._CHBOX_fsme, 106 u'yellow fever': self._CHBOX_yellow_fever, 107 u'yersinia pestis': self._CHBOX_yersinia_pestis 108 }
109 #------------------------------------------------------------------
110 - def enable_all(self):
111 for field in self.__dict__.keys(): 112 if field.startswith('_CHBOX_'): 113 self.__dict__[field].Enable() 114 self.Enable()
115 #------------------------------------------------------------------
116 - def disable_all(self):
117 for field in self.__dict__.keys(): 118 if field.startswith('_CHBOX_'): 119 self.__dict__[field].Disable() 120 self.Disable()
121 #------------------------------------------------------------------
122 - def clear_all(self):
123 for field in self.__dict__.keys(): 124 if field.startswith('_CHBOX_'): 125 self.__dict__[field].SetValue(False)
126 #------------------------------------------------------------------
127 - def select(self, indications=None):
128 for indication in indications: 129 self.__indication2field[indication].SetValue(True)
130 #------------------------------------------------------------------
131 - def _get_selected_indications(self):
132 indications = [] 133 for indication in self.__indication2field.keys(): 134 if self.__indication2field[indication].IsChecked(): 135 indications.append(indication) 136 return indications
137 138 selected_indications = property(_get_selected_indications, lambda x:x) 139 #------------------------------------------------------------------
140 - def _get_has_selection(self):
141 for indication in self.__indication2field.keys(): 142 if self.__indication2field[indication].IsChecked(): 143 return True 144 return False
145 146 has_selection = property(_get_has_selection, lambda x:x)
147 148 #====================================================================== 149 # vaccines related widgets 150 #----------------------------------------------------------------------
151 -def edit_vaccine(parent=None, vaccine=None, single_entry=True):
152 ea = cVaccineEAPnl(parent = parent, id = -1) 153 ea.data = vaccine 154 ea.mode = gmTools.coalesce(vaccine, 'new', 'edit') 155 dlg = gmEditArea.cGenericEditAreaDlg2(parent = parent, id = -1, edit_area = ea, single_entry = single_entry) 156 dlg.SetTitle(gmTools.coalesce(vaccine, _('Adding new vaccine'), _('Editing vaccine'))) 157 if dlg.ShowModal() == wx.ID_OK: 158 dlg.Destroy() 159 return True 160 dlg.Destroy() 161 return False
162 #----------------------------------------------------------------------
163 -def manage_vaccines(parent=None):
164 165 if parent is None: 166 parent = wx.GetApp().GetTopWindow() 167 #------------------------------------------------------------ 168 def delete(vaccine=None): 169 deleted = gmVaccination.delete_vaccine(vaccine = vaccine['pk_vaccine']) 170 if deleted: 171 return True 172 173 gmGuiHelpers.gm_show_info ( 174 _( 175 'Cannot delete vaccine\n' 176 '\n' 177 ' %s - %s (#%s)\n' 178 '\n' 179 'It is probably documented in a vaccination.' 180 ) % ( 181 vaccine['vaccine'], 182 vaccine['preparation'], 183 vaccine['pk_vaccine'] 184 ), 185 _('Deleting vaccine') 186 ) 187 188 return False
189 #------------------------------------------------------------ 190 def edit(vaccine=None): 191 return edit_vaccine(parent = parent, vaccine = vaccine, single_entry = True) 192 #------------------------------------------------------------ 193 def refresh(lctrl): 194 vaccines = gmVaccination.get_vaccines(order_by = 'vaccine') 195 196 items = [ [ 197 u'%s' % v['pk_brand'], 198 u'%s%s' % ( 199 v['vaccine'], 200 gmTools.bool2subst ( 201 v['is_fake_vaccine'], 202 u' (%s)' % _('fake'), 203 u'' 204 ) 205 ), 206 v['preparation'], 207 u'%s (%s)' % (v['route_abbreviation'], v['route_description']), 208 gmTools.bool2subst(v['is_live'], gmTools.u_checkmark_thin, u''), 209 gmTools.coalesce(v['atc_code'], u''), 210 u'%s%s' % ( 211 gmTools.coalesce(v['min_age'], u'?'), 212 gmTools.coalesce(v['max_age'], u'?', u' - %s'), 213 ), 214 gmTools.coalesce(v['comment'], u'') 215 ] for v in vaccines ] 216 lctrl.set_string_items(items) 217 lctrl.set_data(vaccines) 218 #------------------------------------------------------------ 219 gmListWidgets.get_choices_from_list ( 220 parent = parent, 221 msg = _('\nThe vaccines currently known to GNUmed.\n'), 222 caption = _('Showing vaccines.'), 223 columns = [ u'#', _('Brand'), _('Preparation'), _(u'Route'), _('Live'), _('ATC'), _('Age range'), _('Comment') ], 224 single_selection = True, 225 refresh_callback = refresh, 226 edit_callback = edit, 227 new_callback = edit, 228 delete_callback = delete 229 ) 230 #----------------------------------------------------------------------
231 -class cBatchNoPhraseWheel(gmPhraseWheel.cPhraseWheel):
232
233 - def __init__(self, *args, **kwargs):
234 235 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs) 236 237 context = { 238 u'ctxt_vaccine': { 239 u'where_part': u'AND pk_vaccine = %(pk_vaccine)s', 240 u'placeholder': u'pk_vaccine' 241 } 242 } 243 244 query = u""" 245 SELECT data, field_label, list_label FROM ( 246 247 SELECT distinct on (field_label) 248 data, 249 field_label, 250 list_label, 251 rank 252 FROM (( 253 -- batch_no by vaccine 254 SELECT 255 batch_no AS data, 256 batch_no AS field_label, 257 batch_no || ' (' || vaccine || ')' AS list_label, 258 1 as rank 259 FROM 260 clin.v_pat_vaccinations 261 WHERE 262 batch_no %(fragment_condition)s 263 %(ctxt_vaccine)s 264 ) UNION ALL ( 265 -- batch_no for any vaccine 266 SELECT 267 batch_no AS data, 268 batch_no AS field_label, 269 batch_no || ' (' || vaccine || ')' AS list_label, 270 2 AS rank 271 FROM 272 clin.v_pat_vaccinations 273 WHERE 274 batch_no %(fragment_condition)s 275 ) 276 277 ) AS matching_batch_nos 278 279 ) as unique_matches 280 281 ORDER BY rank, list_label 282 LIMIT 25 283 """ 284 mp = gmMatchProvider.cMatchProvider_SQL2(queries = query, context = context) 285 mp.setThresholds(1, 2, 3) 286 self.matcher = mp 287 288 self.unset_context(context = u'pk_vaccine') 289 self.SetToolTipString(_('Enter or select the batch/lot number of the vaccine used.')) 290 self.selection_only = False
291 #----------------------------------------------------------------------
292 -class cVaccinePhraseWheel(gmPhraseWheel.cPhraseWheel):
293
294 - def __init__(self, *args, **kwargs):
295 296 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs) 297 298 # consider ATCs in ref.branded_drug and vacc_indication 299 query = u""" 300 SELECT data, list_label, field_label FROM ( 301 302 SELECT DISTINCT ON (data) 303 data, 304 list_label, 305 field_label 306 FROM (( 307 -- fragment -> vaccine 308 SELECT 309 pk_vaccine AS data, 310 vaccine || ' (' || array_to_string(l10n_indications, ', ') || ')' AS list_label, 311 vaccine AS field_label 312 FROM 313 clin.v_vaccines 314 WHERE 315 vaccine %(fragment_condition)s 316 317 ) union all ( 318 319 -- fragment -> localized indication -> vaccines 320 SELECT 321 pk_vaccine AS data, 322 vaccine || ' (' || array_to_string(l10n_indications, ', ') || ')' AS list_label, 323 vaccine AS field_label 324 FROM 325 clin.v_indications4vaccine 326 WHERE 327 l10n_indication %(fragment_condition)s 328 329 ) union all ( 330 331 -- fragment -> indication -> vaccines 332 SELECT 333 pk_vaccine AS data, 334 vaccine || ' (' || array_to_string(indications, ', ') || ')' AS list_label, 335 vaccine AS field_label 336 FROM 337 clin.v_indications4vaccine 338 WHERE 339 indication %(fragment_condition)s 340 ) 341 ) AS distinct_total 342 343 ) AS total 344 345 ORDER by list_label 346 LIMIT 25 347 """ 348 mp = gmMatchProvider.cMatchProvider_SQL2(queries = query) 349 mp.setThresholds(1, 2, 3) 350 self.matcher = mp 351 352 self.selection_only = True
353 #------------------------------------------------------------------
354 - def _data2instance(self):
355 return gmVaccination.cVaccine(aPK_obj = self.GetData())
356 #---------------------------------------------------------------------- 357 from Gnumed.wxGladeWidgets import wxgVaccineEAPnl 358
359 -class cVaccineEAPnl(wxgVaccineEAPnl.wxgVaccineEAPnl, gmEditArea.cGenericEditAreaMixin):
360
361 - def __init__(self, *args, **kwargs):
362 363 try: 364 data = kwargs['vaccine'] 365 del kwargs['vaccine'] 366 except KeyError: 367 data = None 368 369 wxgVaccineEAPnl.wxgVaccineEAPnl.__init__(self, *args, **kwargs) 370 gmEditArea.cGenericEditAreaMixin.__init__(self) 371 372 self.mode = 'new' 373 self.data = data 374 if data is not None: 375 self.mode = 'edit' 376 377 self.__init_ui()
378 #----------------------------------------------------------------
379 - def __init_ui(self):
380 381 # route 382 query = u""" 383 SELECT DISTINCT ON (abbreviation) 384 id, 385 abbreviation || ' (' || _(description) || ')' 386 FROM 387 clin.vacc_route 388 WHERE 389 abbreviation %(fragment_condition)s 390 OR 391 description %(fragment_condition)s 392 ORDER BY 393 abbreviation 394 """ 395 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query) 396 mp.setThresholds(1, 2, 3) 397 self._PRW_route.matcher = mp 398 self._PRW_route.selection_only = True 399 400 #self._PRW_age_min = gmPhraseWheel.cPhraseWheel(self, -1, "", style=wx.NO_BORDER) 401 #self._PRW_age_max = gmPhraseWheel.cPhraseWheel(self, -1, "", style=wx.NO_BORDER) 402 403 self.Layout() 404 self.Fit()
405 #---------------------------------------------------------------- 406 # generic Edit Area mixin API 407 #----------------------------------------------------------------
408 - def _valid_for_save(self):
409 410 has_errors = False 411 412 if self._PRW_brand.GetValue().strip() == u'': 413 has_errors = True 414 self._PRW_brand.display_as_valid(False) 415 else: 416 self._PRW_brand.display_as_valid(True) 417 418 if self._PRW_route.GetData() is None: 419 has_errors = True 420 self._PRW_route.display_as_valid(False) 421 else: 422 self._PRW_route.display_as_valid(True) 423 424 if not self._PNL_indications.has_selection: 425 has_errors = True 426 427 if self._PRW_atc.GetValue().strip() in [u'', u'J07']: 428 self._PRW_atc.display_as_valid(True) 429 else: 430 if self._PRW_atc.GetData() is None: 431 self._PRW_atc.display_as_valid(True) 432 else: 433 has_errors = True 434 self._PRW_atc.display_as_valid(False) 435 436 val = self._PRW_age_min.GetValue().strip() 437 if val == u'': 438 self._PRW_age_min.display_as_valid(True) 439 else: 440 if gmDateTime.str2interval(val) is None: 441 has_errors = True 442 self._PRW_age_min.display_as_valid(False) 443 else: 444 self._PRW_age_min.display_as_valid(True) 445 446 val = self._PRW_age_max.GetValue().strip() 447 if val == u'': 448 self._PRW_age_max.display_as_valid(True) 449 else: 450 if gmDateTime.str2interval(val) is None: 451 has_errors = True 452 self._PRW_age_max.display_as_valid(False) 453 else: 454 self._PRW_age_max.display_as_valid(True) 455 456 # are we editing ? 457 ask_user = (self.mode == 'edit') 458 # is this vaccine in use ? 459 ask_user = (ask_user and self.data.is_in_use) 460 # a change ... 461 ask_user = ask_user and ( 462 # ... of brand ... 463 (self.data['pk_brand'] != self._PRW_route.GetData()) 464 or 465 # ... or indications ? 466 (self.data['indications'] != self._PNL_indications.selected_indications) 467 ) 468 469 if ask_user: 470 do_it = gmGuiHelpers.gm_show_question ( 471 aTitle = _('Saving vaccine'), 472 aMessage = _( 473 u'This vaccine is already in use:\n' 474 u'\n' 475 u' "%s"\n' 476 u' (%s)\n' 477 u'\n' 478 u'Are you absolutely positively sure that\n' 479 u'you really want to edit this vaccine ?\n' 480 '\n' 481 u'This will change the vaccine name and/or target\n' 482 u'conditions in each patient this vaccine was\n' 483 u'used in to document a vaccination with.\n' 484 ) % ( 485 self._PRW_brand.GetValue().strip(), 486 u', '.join(self.data['l10n_indications']) 487 ) 488 ) 489 if not do_it: 490 has_errors = True 491 492 return (has_errors is False)
493 #----------------------------------------------------------------
494 - def _save_as_new(self):
495 # save the data as a new instance 496 data = gmVaccination.create_vaccine ( 497 pk_brand = self._PRW_brand.GetData(), 498 brand_name = self._PRW_brand.GetValue(), 499 indications = self._PNL_indications.selected_indications 500 ) 501 502 data['pk_route'] = self._PRW_route.GetData() 503 data['is_live'] = self._CHBOX_live.GetValue() 504 val = self._PRW_age_min.GetValue().strip() 505 if val != u'': 506 data['min_age'] = gmDateTime.str2interval(val) 507 val = self._PRW_age_max.GetValue().strip() 508 if val != u'': 509 data['max_age'] = gmDateTime.str2interval(val) 510 val = self._TCTRL_comment.GetValue().strip() 511 if val != u'': 512 data['comment'] = val 513 514 data.save() 515 516 drug = data.brand 517 drug['is_fake'] = self._CHBOX_fake.GetValue() 518 val = self._PRW_atc.GetData() 519 if val is not None: 520 if val != u'J07': 521 drug['atc_code'] = val.strip() 522 drug.save() 523 524 # must be done very late or else the property access 525 # will refresh the display such that later field 526 # access will return empty values 527 self.data = data 528 529 return True
530 #----------------------------------------------------------------
531 - def _save_as_update(self):
532 533 drug = self.data.brand 534 drug['description'] = self._PRW_brand.GetValue().strip() 535 drug['is_fake'] = self._CHBOX_fake.GetValue() 536 val = self._PRW_atc.GetData() 537 if val is not None: 538 if val != u'J07': 539 drug['atc_code'] = val.strip() 540 drug.save() 541 542 # the validator already asked for changes so just do it 543 self.data.set_indications(indications = self._PNL_indications.selected_indications) 544 545 self.data['pk_route'] = self._PRW_route.GetData() 546 self.data['is_live'] = self._CHBOX_live.GetValue() 547 val = self._PRW_age_min.GetValue().strip() 548 if val != u'': 549 self.data['min_age'] = gmDateTime.str2interval(val) 550 if val != u'': 551 self.data['max_age'] = gmDateTime.str2interval(val) 552 val = self._TCTRL_comment.GetValue().strip() 553 if val != u'': 554 self.data['comment'] = val 555 556 self.data.save() 557 return True
558 #----------------------------------------------------------------
559 - def _refresh_as_new(self):
560 self._PRW_brand.SetText(value = u'', data = None, suppress_smarts = True) 561 self._PRW_route.SetText(value = u'intramuscular') 562 self._CHBOX_live.SetValue(False) 563 self._CHBOX_fake.SetValue(False) 564 self._PNL_indications.clear_all() 565 self._PRW_atc.SetText(value = u'', data = None, suppress_smarts = True) 566 self._PRW_age_min.SetText(value = u'', data = None, suppress_smarts = True) 567 self._PRW_age_max.SetText(value = u'', data = None, suppress_smarts = True) 568 self._TCTRL_comment.SetValue(u'') 569 570 self._PRW_brand.SetFocus()
571 #----------------------------------------------------------------
572 - def _refresh_from_existing(self):
573 self._PRW_brand.SetText(value = self.data['vaccine'], data = self.data['pk_brand']) 574 self._PRW_route.SetText(value = self.data['route_description'], data = self.data['pk_route']) 575 self._CHBOX_live.SetValue(self.data['is_live']) 576 self._CHBOX_fake.SetValue(self.data['is_fake_vaccine']) 577 self._PNL_indications.select(self.data['indications']) 578 self._PRW_atc.SetText(value = self.data['atc_code'], data = self.data['atc_code']) 579 if self.data['min_age'] is None: 580 self._PRW_age_min.SetText(value = u'', data = None, suppress_smarts = True) 581 else: 582 self._PRW_age_min.SetText ( 583 value = gmDateTime.format_interval(self.data['min_age'], gmDateTime.acc_years), 584 data = self.data['min_age'] 585 ) 586 if self.data['max_age'] is None: 587 self._PRW_age_max.SetText(value = u'', data = None, suppress_smarts = True) 588 else: 589 self._PRW_age_max.SetText ( 590 value = gmDateTime.format_interval(self.data['max_age'], gmDateTime.acc_years), 591 data = self.data['max_age'] 592 ) 593 self._TCTRL_comment.SetValue(gmTools.coalesce(self.data['comment'], u'')) 594 595 self._PRW_brand.SetFocus()
596 #----------------------------------------------------------------
598 self._refresh_as_new()
599 #====================================================================== 600 # vaccination related widgets 601 #----------------------------------------------------------------------
602 -def edit_vaccination(parent=None, vaccination=None, single_entry=True):
603 ea = cVaccinationEAPnl(parent = parent, id = -1) 604 ea.data = vaccination 605 ea.mode = gmTools.coalesce(vaccination, 'new', 'edit') 606 dlg = gmEditArea.cGenericEditAreaDlg2(parent = parent, id = -1, edit_area = ea, single_entry = single_entry) 607 dlg.SetTitle(gmTools.coalesce(vaccination, _('Adding new vaccinations'), _('Editing vaccination'))) 608 if dlg.ShowModal() == wx.ID_OK: 609 dlg.Destroy() 610 return True 611 dlg.Destroy() 612 if not single_entry: 613 return True 614 return False
615 #----------------------------------------------------------------------
616 -def manage_vaccinations(parent=None):
617 618 pat = gmPerson.gmCurrentPatient() 619 emr = pat.get_emr() 620 621 if parent is None: 622 parent = wx.GetApp().GetTopWindow() 623 #------------------------------------------------------------ 624 def browse2schedules(vaccination=None): 625 dbcfg = gmCfg.cCfgSQL() 626 url = dbcfg.get2 ( 627 option = 'external.urls.vaccination_plans', 628 workplace = gmSurgery.gmCurrentPractice().active_workplace, 629 bias = 'user', 630 default = u'http://www.bundesaerztekammer.de/downloads/ImpfempfehlungenRKI2009.pdf' 631 ) 632 633 webbrowser.open ( 634 url = url, 635 new = False, 636 autoraise = True 637 ) 638 return False
639 #------------------------------------------------------------ 640 def edit(vaccination=None): 641 return edit_vaccination(parent = parent, vaccination = vaccination, single_entry = (vaccination is not None)) 642 #------------------------------------------------------------ 643 def delete(vaccination=None): 644 gmVaccination.delete_vaccination(vaccination = vaccination['pk_vaccination']) 645 return True 646 #------------------------------------------------------------ 647 def refresh(lctrl): 648 649 vaccs = emr.get_vaccinations(order_by = 'date_given DESC, pk_vaccination') 650 651 items = [ [ 652 v['date_given'].strftime('%Y %B %d').decode(gmI18N.get_encoding()), 653 v['vaccine'], 654 u', '.join(v['l10n_indications']), 655 v['batch_no'], 656 gmTools.coalesce(v['site'], u''), 657 gmTools.coalesce(v['reaction'], u''), 658 gmTools.coalesce(v['comment'], u'') 659 ] for v in vaccs ] 660 661 lctrl.set_string_items(items) 662 lctrl.set_data(vaccs) 663 #------------------------------------------------------------ 664 gmListWidgets.get_choices_from_list ( 665 parent = parent, 666 msg = _('\nComplete vaccination history for this patient.\n'), 667 caption = _('Showing vaccinations.'), 668 columns = [ _('Date'), _('Vaccine'), _(u'Intended to protect from'), _('Batch'), _('Site'), _('Reaction'), _('Comment') ], 669 single_selection = True, 670 refresh_callback = refresh, 671 new_callback = edit, 672 edit_callback = edit, 673 delete_callback = delete, 674 left_extra_button = (_('Vaccination Plans'), _('Open a browser showing vaccination schedules.'), browse2schedules) 675 ) 676 #---------------------------------------------------------------------- 677 from Gnumed.wxGladeWidgets import wxgVaccinationEAPnl 678
679 -class cVaccinationEAPnl(wxgVaccinationEAPnl.wxgVaccinationEAPnl, gmEditArea.cGenericEditAreaMixin):
680 """ 681 - warn on apparent duplicates 682 - ask if "missing" (= previous, non-recorded) vaccinations 683 should be estimated and saved (add note "auto-generated") 684 685 Batch No (http://www.fao.org/docrep/003/v9952E12.htm) 686 """
687 - def __init__(self, *args, **kwargs):
688 689 try: 690 data = kwargs['vaccination'] 691 del kwargs['vaccination'] 692 except KeyError: 693 data = None 694 695 wxgVaccinationEAPnl.wxgVaccinationEAPnl.__init__(self, *args, **kwargs) 696 gmEditArea.cGenericEditAreaMixin.__init__(self) 697 698 self.mode = 'new' 699 self.data = data 700 if data is not None: 701 self.mode = 'edit' 702 703 self.__init_ui()
704 #----------------------------------------------------------------
705 - def __init_ui(self):
706 # adjust phrasewheels etc 707 self._PRW_vaccine.add_callback_on_lose_focus(self._on_PRW_vaccine_lost_focus) 708 self._PRW_provider.selection_only = False 709 # self._PRW_batch.unset_context(context = 'pk_vaccine') # done in PRW init() 710 self._PRW_reaction.add_callback_on_lose_focus(self._on_PRW_reaction_lost_focus)
711 #----------------------------------------------------------------
712 - def _on_PRW_vaccine_lost_focus(self):
713 714 vaccine = self._PRW_vaccine.GetData(as_instance=True) 715 716 # if we are editing we do not allow using indications rather than a vaccine 717 if self.mode == u'edit': 718 self._PNL_indications.clear_all() 719 if vaccine is None: 720 self._PRW_batch.unset_context(context = 'pk_vaccine') 721 else: 722 self._PRW_batch.set_context(context = 'pk_vaccine', val = vaccine['pk_vaccine']) 723 self._PNL_indications.select(indications = vaccine['indications']) 724 self._PNL_indications.disable_all() 725 726 # we are entering a new vaccination 727 else: 728 if vaccine is None: 729 self._PRW_batch.unset_context(context = 'pk_vaccine') 730 self._PNL_indications.enable_all() 731 else: 732 self._PRW_batch.set_context(context = 'pk_vaccine', val = vaccine['pk_vaccine']) 733 self._PNL_indications.clear_all() 734 self._PNL_indications.select(indications = vaccine['indications']) 735 self._PNL_indications.disable_all()
736 #----------------------------------------------------------------
738 if self._PRW_reaction.GetValue().strip() == u'': 739 self._BTN_report.Enable(False) 740 else: 741 self._BTN_report.Enable(True)
742 #---------------------------------------------------------------- 743 # generic Edit Area mixin API 744 #----------------------------------------------------------------
745 - def _valid_for_save(self):
746 747 has_errors = False 748 749 if not self._PRW_date_given.is_valid_timestamp(allow_empty = False): 750 has_errors = True 751 752 vaccine = self._PRW_vaccine.GetData(as_instance = True) 753 754 # we are editing, require vaccine rather than indications 755 if self.mode == u'edit': 756 if vaccine is None: 757 has_errors = True 758 self._PRW_vaccine.display_as_valid(False) 759 else: 760 self._PRW_vaccine.display_as_valid(True) 761 self._PNL_indications.clear_all() 762 self._PNL_indications.select(indications = vaccine['indications']) 763 self._PNL_indications.disable_all() 764 # we are creating, allow either vaccine or indications 765 else: 766 if vaccine is None: 767 if self._PNL_indications.has_selection: 768 self._PRW_vaccine.display_as_valid(True) 769 else: 770 has_errors = True 771 self._PRW_vaccine.display_as_valid(False) 772 else: 773 self._PRW_vaccine.display_as_valid(True) 774 775 if self._PRW_batch.GetValue().strip() == u'': 776 has_errors = True 777 self._PRW_batch.display_as_valid(False) 778 else: 779 self._PRW_batch.display_as_valid(True) 780 781 if self._PRW_episode.GetValue().strip() == u'': 782 self._PRW_episode.SetText(value = _('prevention')) 783 784 return (has_errors is False)
785 #----------------------------------------------------------------
786 - def _save_as_new(self):
787 788 vaccine = self._PRW_vaccine.GetData() 789 if vaccine is None: 790 data = self.__save_new_from_indications() 791 else: 792 data = self.__save_new_from_vaccine(vaccine = vaccine) 793 794 # must be done very late or else the property access 795 # will refresh the display such that later field 796 # access will return empty values 797 self.data = data 798 799 return True
800 #----------------------------------------------------------------
802 803 inds = self._PNL_indications.selected_indications 804 vaccine = gmVaccination.map_indications2generic_vaccine(indications = inds) 805 806 if vaccine is None: 807 for ind in inds: 808 vaccine = gmVaccination.map_indications2generic_vaccine(indications = [ind]) 809 data = self.__save_new_from_vaccine(vaccine = vaccine['pk_vaccine']) 810 else: 811 data = self.__save_new_from_vaccine(vaccine = vaccine['pk_vaccine']) 812 813 return data
814 #----------------------------------------------------------------
815 - def __save_new_from_vaccine(self, vaccine=None):
816 817 emr = gmPerson.gmCurrentPatient().get_emr() 818 819 data = emr.add_vaccination ( 820 episode = self._PRW_episode.GetData(can_create = True, is_open = False), 821 vaccine = vaccine, 822 batch_no = self._PRW_batch.GetValue().strip() 823 ) 824 825 if self._CHBOX_anamnestic.GetValue() is True: 826 data['soap_cat'] = u's' 827 else: 828 data['soap_cat'] = u'p' 829 830 data['date_given'] = self._PRW_date_given.GetData() 831 data['site'] = self._PRW_site.GetValue().strip() 832 data['pk_provider'] = self._PRW_provider.GetData() 833 data['reaction'] = self._PRW_reaction.GetValue().strip() 834 data['comment'] = self._TCTRL_comment.GetValue().strip() 835 836 data.save() 837 838 return data
839 #----------------------------------------------------------------
840 - def _save_as_update(self):
841 842 if self._CHBOX_anamnestic.GetValue() is True: 843 self.data['soap_cat'] = u's' 844 else: 845 self.data['soap_cat'] = u'p' 846 847 self.data['date_given'] = self._PRW_date_given.GetData() 848 self.data['pk_vaccine'] = self._PRW_vaccine.GetData() 849 self.data['batch_no'] = self._PRW_batch.GetValue().strip() 850 self.data['pk_episode'] = self._PRW_episode.GetData(can_create = True, is_open = False) 851 self.data['site'] = self._PRW_site.GetValue().strip() 852 self.data['pk_provider'] = self._PRW_provider.GetData() 853 self.data['reaction'] = self._PRW_reaction.GetValue().strip() 854 self.data['comment'] = self._TCTRL_comment.GetValue().strip() 855 856 self.data.save() 857 858 return True
859 #----------------------------------------------------------------
860 - def _refresh_as_new(self):
861 self._PRW_date_given.SetText(data = gmDateTime.pydt_now_here()) 862 self._CHBOX_anamnestic.SetValue(False) 863 self._PRW_vaccine.SetText(value = u'', data = None, suppress_smarts = True) 864 865 self._PNL_indications.clear_all() 866 self._PRW_batch.unset_context(context = 'pk_vaccine') 867 self._PRW_batch.SetValue(u'') 868 869 self._PRW_episode.SetText(value = u'', data = None, suppress_smarts = True) 870 self._PRW_site.SetValue(u'') 871 self._PRW_provider.SetData(data = None) 872 self._PRW_reaction.SetText(value = u'', data = None, suppress_smarts = True) 873 self._BTN_report.Enable(False) 874 self._TCTRL_comment.SetValue(u'') 875 876 self._PRW_date_given.SetFocus()
877 #----------------------------------------------------------------
878 - def _refresh_from_existing(self):
879 self._PRW_date_given.SetText(data = self.data['date_given']) 880 if self.data['soap_cat'] == u's': 881 self._CHBOX_anamnestic.SetValue(True) 882 else: 883 self._CHBOX_anamnestic.SetValue(False) 884 self._PRW_vaccine.SetText(value = self.data['vaccine'], data = self.data['pk_vaccine']) 885 886 self._PNL_indications.clear_all() 887 self._PNL_indications.select(indications = self.data['indications']) 888 self._PNL_indications.disable_all() 889 890 self._PRW_batch.SetValue(self.data['batch_no']) 891 self._PRW_episode.SetData(data = self.data['pk_episode']) 892 self._PRW_site.SetValue(gmTools.coalesce(self.data['site'], u'')) 893 self._PRW_provider.SetData(self.data['pk_provider']) 894 self._PRW_reaction.SetValue(gmTools.coalesce(self.data['reaction'], u'')) 895 if self.data['reaction'] is None: 896 self._BTN_report.Enable(False) 897 else: 898 self._BTN_report.Enable(True) 899 self._TCTRL_comment.SetValue(gmTools.coalesce(self.data['comment'], u'')) 900 901 self._PRW_date_given.SetFocus()
902 #----------------------------------------------------------------
904 self._PRW_date_given.SetText(data = self.data['date_given']) 905 #self._CHBOX_anamnestic.SetValue(False) 906 self._PRW_vaccine.SetText(value = self.data['vaccine'], data = self.data['pk_vaccine']) 907 908 self._PNL_indications.clear_all() 909 self._PNL_indications.select(indications = self.data['indications']) 910 self._PNL_indications.disable_all() 911 912 self._PRW_batch.set_context(context = 'pk_vaccine', val = self.data['pk_vaccine']) 913 self._PRW_batch.SetValue(u'') 914 915 self._PRW_episode.SetData(data = self.data['pk_episode']) 916 self._PRW_site.SetValue(gmTools.coalesce(self.data['site'], u'')) 917 self._PRW_provider.SetData(self.data['pk_provider']) 918 self._PRW_reaction.SetValue(u'') 919 self._BTN_report.Enable(False) 920 self._TCTRL_comment.SetValue(u'') 921 922 self._PRW_date_given.SetFocus()
923 #---------------------------------------------------------------- 924 # event handlers 925 #----------------------------------------------------------------
926 - def _on_report_button_pressed(self, event):
927 928 event.Skip() 929 930 dbcfg = gmCfg.cCfgSQL() 931 932 url = dbcfg.get2 ( 933 option = u'external.urls.report_vaccine_ADR', 934 workplace = gmSurgery.gmCurrentPractice().active_workplace, 935 bias = u'user', 936 default = u'http://www.pei.de/cln_042/SharedDocs/Downloads/fachkreise/uaw/meldeboegen/b-ifsg-meldebogen,templateId=raw,property=publicationFile.pdf/b-ifsg-meldebogen.pdf' 937 ) 938 939 if url.strip() == u'': 940 url = dbcfg.get2 ( 941 option = u'external.urls.report_ADR', 942 workplace = gmSurgery.gmCurrentPractice().active_workplace, 943 bias = u'user' 944 ) 945 946 webbrowser.open(url = url, new = False, autoraise = True)
947 #----------------------------------------------------------------
948 - def _on_add_vaccine_button_pressed(self, event):
949 edit_vaccine(parent = self, vaccine = None, single_entry = False)
950 # FIXME: could set newly generated vaccine here 951 #====================================================================== 952 #======================================================================
953 -class cImmunisationsPanel(wx.Panel, gmRegetMixin.cRegetOnPaintMixin):
954
955 - def __init__(self, parent, id):
956 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.RAISED_BORDER) 957 gmRegetMixin.cRegetOnPaintMixin.__init__(self) 958 self.__pat = gmPerson.gmCurrentPatient() 959 # do this here so "import cImmunisationsPanel from gmVaccWidgets" works 960 self.ID_VaccinatedIndicationsList = wx.NewId() 961 self.ID_VaccinationsPerRegimeList = wx.NewId() 962 self.ID_MissingShots = wx.NewId() 963 self.ID_ActiveSchedules = wx.NewId() 964 self.__do_layout() 965 self.__register_interests() 966 self.__reset_ui_content()
967 #----------------------------------------------------
968 - def __do_layout(self):
969 #----------------------------------------------- 970 # top part 971 #----------------------------------------------- 972 pnl_UpperCaption = gmTerryGuiParts.cHeadingCaption(self, -1, _(" IMMUNISATIONS ")) 973 self.editarea = cVaccinationEditArea(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.NO_BORDER) 974 975 #----------------------------------------------- 976 # middle part 977 #----------------------------------------------- 978 # divider headings below editing area 979 indications_heading = gmTerryGuiParts.cDividerCaption(self, -1, _("Indications")) 980 vaccinations_heading = gmTerryGuiParts.cDividerCaption(self, -1, _("Vaccinations")) 981 schedules_heading = gmTerryGuiParts.cDividerCaption(self, -1, _("Active Schedules")) 982 szr_MiddleCap = wx.BoxSizer(wx.HORIZONTAL) 983 szr_MiddleCap.Add(indications_heading, 4, wx.EXPAND) 984 szr_MiddleCap.Add(vaccinations_heading, 6, wx.EXPAND) 985 szr_MiddleCap.Add(schedules_heading, 10, wx.EXPAND) 986 987 # left list: indications for which vaccinations have been given 988 self.LBOX_vaccinated_indications = wx.ListBox( 989 parent = self, 990 id = self.ID_VaccinatedIndicationsList, 991 choices = [], 992 style = wx.LB_HSCROLL | wx.LB_NEEDED_SB | wx.SUNKEN_BORDER 993 ) 994 self.LBOX_vaccinated_indications.SetFont(wx.Font(12,wx.SWISS, wx.NORMAL, wx.NORMAL, False, '')) 995 996 # right list: when an indication has been selected on the left 997 # display the corresponding vaccinations on the right 998 self.LBOX_given_shots = wx.ListBox( 999 parent = self, 1000 id = self.ID_VaccinationsPerRegimeList, 1001 choices = [], 1002 style = wx.LB_HSCROLL | wx.LB_NEEDED_SB | wx.SUNKEN_BORDER 1003 ) 1004 self.LBOX_given_shots.SetFont(wx.Font(12,wx.SWISS, wx.NORMAL, wx.NORMAL, False, '')) 1005 1006 self.LBOX_active_schedules = wx.ListBox ( 1007 parent = self, 1008 id = self.ID_ActiveSchedules, 1009 choices = [], 1010 style = wx.LB_HSCROLL | wx.LB_NEEDED_SB | wx.SUNKEN_BORDER 1011 ) 1012 self.LBOX_active_schedules.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, '')) 1013 1014 szr_MiddleLists = wx.BoxSizer(wx.HORIZONTAL) 1015 szr_MiddleLists.Add(self.LBOX_vaccinated_indications, 4, wx.EXPAND) 1016 szr_MiddleLists.Add(self.LBOX_given_shots, 6, wx.EXPAND) 1017 szr_MiddleLists.Add(self.LBOX_active_schedules, 10, wx.EXPAND) 1018 1019 #--------------------------------------------- 1020 # bottom part 1021 #--------------------------------------------- 1022 missing_heading = gmTerryGuiParts.cDividerCaption(self, -1, _("Missing Immunisations")) 1023 szr_BottomCap = wx.BoxSizer(wx.HORIZONTAL) 1024 szr_BottomCap.Add(missing_heading, 1, wx.EXPAND) 1025 1026 self.LBOX_missing_shots = wx.ListBox ( 1027 parent = self, 1028 id = self.ID_MissingShots, 1029 choices = [], 1030 style = wx.LB_HSCROLL | wx.LB_NEEDED_SB | wx.SUNKEN_BORDER 1031 ) 1032 self.LBOX_missing_shots.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, '')) 1033 1034 szr_BottomLists = wx.BoxSizer(wx.HORIZONTAL) 1035 szr_BottomLists.Add(self.LBOX_missing_shots, 1, wx.EXPAND) 1036 1037 # alert caption 1038 pnl_AlertCaption = gmTerryGuiParts.cAlertCaption(self, -1, _(' Alerts ')) 1039 1040 #--------------------------------------------- 1041 # add all elements to the main background sizer 1042 #--------------------------------------------- 1043 self.mainsizer = wx.BoxSizer(wx.VERTICAL) 1044 self.mainsizer.Add(pnl_UpperCaption, 0, wx.EXPAND) 1045 self.mainsizer.Add(self.editarea, 6, wx.EXPAND) 1046 self.mainsizer.Add(szr_MiddleCap, 0, wx.EXPAND) 1047 self.mainsizer.Add(szr_MiddleLists, 4, wx.EXPAND) 1048 self.mainsizer.Add(szr_BottomCap, 0, wx.EXPAND) 1049 self.mainsizer.Add(szr_BottomLists, 4, wx.EXPAND) 1050 self.mainsizer.Add(pnl_AlertCaption, 0, wx.EXPAND) 1051 1052 self.SetAutoLayout(True) 1053 self.SetSizer(self.mainsizer) 1054 self.mainsizer.Fit(self)
1055 #----------------------------------------------------
1056 - def __register_interests(self):
1057 # wxPython events 1058 wx.EVT_SIZE(self, self.OnSize) 1059 wx.EVT_LISTBOX(self, self.ID_VaccinatedIndicationsList, self._on_vaccinated_indication_selected) 1060 wx.EVT_LISTBOX_DCLICK(self, self.ID_VaccinationsPerRegimeList, self._on_given_shot_selected) 1061 wx.EVT_LISTBOX_DCLICK(self, self.ID_MissingShots, self._on_missing_shot_selected) 1062 # wx.EVT_RIGHT_UP(self.lb1, self.EvtRightButton) 1063 1064 # client internal signals 1065 gmDispatcher.connect(signal= u'post_patient_selection', receiver=self._schedule_data_reget) 1066 gmDispatcher.connect(signal= u'vaccinations_updated', receiver=self._schedule_data_reget)
1067 #---------------------------------------------------- 1068 # event handlers 1069 #----------------------------------------------------
1070 - def OnSize (self, event):
1071 w, h = event.GetSize() 1072 self.mainsizer.SetDimension (0, 0, w, h)
1073 #----------------------------------------------------
1074 - def _on_given_shot_selected(self, event):
1075 """Paste previously given shot into edit area. 1076 """ 1077 self.editarea.set_data(aVacc=event.GetClientData())
1078 #----------------------------------------------------
1079 - def _on_missing_shot_selected(self, event):
1080 self.editarea.set_data(aVacc = event.GetClientData())
1081 #----------------------------------------------------
1082 - def _on_vaccinated_indication_selected(self, event):
1083 """Update right hand middle list to show vaccinations given for selected indication.""" 1084 ind_list = event.GetEventObject() 1085 selected_item = ind_list.GetSelection() 1086 ind = ind_list.GetClientData(selected_item) 1087 # clear list 1088 self.LBOX_given_shots.Set([]) 1089 emr = self.__pat.get_emr() 1090 shots = emr.get_vaccinations(indications = [ind]) 1091 # FIXME: use Set() for entire array (but problem with client_data) 1092 for shot in shots: 1093 if shot['is_booster']: 1094 marker = 'B' 1095 else: 1096 marker = '#%s' % shot['seq_no'] 1097 label = '%s - %s: %s' % (marker, shot['date'].strftime('%m/%Y'), shot['vaccine']) 1098 self.LBOX_given_shots.Append(label, shot)
1099 #----------------------------------------------------
1100 - def __reset_ui_content(self):
1101 # clear edit area 1102 self.editarea.set_data() 1103 # clear lists 1104 self.LBOX_vaccinated_indications.Clear() 1105 self.LBOX_given_shots.Clear() 1106 self.LBOX_active_schedules.Clear() 1107 self.LBOX_missing_shots.Clear()
1108 #----------------------------------------------------
1109 - def _populate_with_data(self):
1110 # clear lists 1111 self.LBOX_vaccinated_indications.Clear() 1112 self.LBOX_given_shots.Clear() 1113 self.LBOX_active_schedules.Clear() 1114 self.LBOX_missing_shots.Clear() 1115 1116 emr = self.__pat.get_emr() 1117 1118 t1 = time.time() 1119 # populate vaccinated-indications list 1120 # FIXME: consider adding virtual indication "most recent" to 1121 # FIXME: display most recent of all indications as suggested by Syan 1122 status, indications = emr.get_vaccinated_indications() 1123 # FIXME: would be faster to use Set() but can't 1124 # use Set(labels, client_data), and have to know 1125 # line position in SetClientData :-( 1126 for indication in indications: 1127 self.LBOX_vaccinated_indications.Append(indication[1], indication[0]) 1128 # self.LBOX_vaccinated_indications.Set(lines) 1129 # self.LBOX_vaccinated_indications.SetClientData(data) 1130 print "vaccinated indications took", time.time()-t1, "seconds" 1131 1132 t1 = time.time() 1133 # populate active schedules list 1134 scheds = emr.get_scheduled_vaccination_regimes() 1135 if scheds is None: 1136 label = _('ERROR: cannot retrieve active vaccination schedules') 1137 self.LBOX_active_schedules.Append(label) 1138 elif len(scheds) == 0: 1139 label = _('no active vaccination schedules') 1140 self.LBOX_active_schedules.Append(label) 1141 else: 1142 for sched in scheds: 1143 label = _('%s for %s (%s shots): %s') % (sched['regime'], sched['l10n_indication'], sched['shots'], sched['comment']) 1144 self.LBOX_active_schedules.Append(label) 1145 print "active schedules took", time.time()-t1, "seconds" 1146 1147 t1 = time.time() 1148 # populate missing-shots list 1149 missing_shots = emr.get_missing_vaccinations() 1150 print "getting missing shots took", time.time()-t1, "seconds" 1151 if missing_shots is None: 1152 label = _('ERROR: cannot retrieve due/overdue vaccinations') 1153 self.LBOX_missing_shots.Append(label, None) 1154 return True 1155 # due 1156 due_template = _('%.0d weeks left: shot %s for %s in %s, due %s (%s)') 1157 overdue_template = _('overdue %.0dyrs %.0dwks: shot %s for %s in schedule "%s" (%s)') 1158 for shot in missing_shots['due']: 1159 if shot['overdue']: 1160 years, days_left = divmod(shot['amount_overdue'].days, 364.25) 1161 weeks = days_left / 7 1162 # amount_overdue, seq_no, indication, regime, vacc_comment 1163 label = overdue_template % ( 1164 years, 1165 weeks, 1166 shot['seq_no'], 1167 shot['l10n_indication'], 1168 shot['regime'], 1169 shot['vacc_comment'] 1170 ) 1171 self.LBOX_missing_shots.Append(label, shot) 1172 else: 1173 # time_left, seq_no, regime, latest_due, vacc_comment 1174 label = due_template % ( 1175 shot['time_left'].days / 7, 1176 shot['seq_no'], 1177 shot['indication'], 1178 shot['regime'], 1179 shot['latest_due'].strftime('%m/%Y'), 1180 shot['vacc_comment'] 1181 ) 1182 self.LBOX_missing_shots.Append(label, shot) 1183 # booster 1184 lbl_template = _('due now: booster for %s in schedule "%s" (%s)') 1185 for shot in missing_shots['boosters']: 1186 # indication, regime, vacc_comment 1187 label = lbl_template % ( 1188 shot['l10n_indication'], 1189 shot['regime'], 1190 shot['vacc_comment'] 1191 ) 1192 self.LBOX_missing_shots.Append(label, shot) 1193 print "displaying missing shots took", time.time()-t1, "seconds" 1194 1195 return True
1196 #----------------------------------------------------
1197 - def _on_post_patient_selection(self, **kwargs):
1198 return 1
1199 # FIXME: 1200 # if has_focus: 1201 # wxCallAfter(self.__reset_ui_content) 1202 # else: 1203 # return 1 1204 #----------------------------------------------------
1205 - def _on_vaccinations_updated(self, **kwargs):
1206 return 1
1207 # FIXME: 1208 # if has_focus: 1209 # wxCallAfter(self.__reset_ui_content) 1210 # else: 1211 # is_stale == True 1212 # return 1 1213 #====================================================================== 1214 # main 1215 #---------------------------------------------------------------------- 1216 if __name__ == "__main__": 1217 1218 if len(sys.argv) < 2: 1219 sys.exit() 1220 1221 if sys.argv[1] != u'test': 1222 sys.exit() 1223 1224 app = wx.PyWidgetTester(size = (600, 600)) 1225 app.SetWidget(cATCPhraseWheel, -1) 1226 app.MainLoop() 1227 #====================================================================== 1228