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

Source Code for Module Gnumed.wxpython.gmEditArea

   1  #==================================================================== 
   2  # GNUmed Richard style Edit Area 
   3  #==================================================================== 
   4  __license__ = 'GPL' 
   5  __version__ = "$Revision: 1.135 $" 
   6  __author__ = "R.Terry, K.Hilbert" 
   7   
   8  #====================================================================== 
   9  import sys 
  10  import logging 
  11  import datetime as pydt 
  12   
  13   
  14  import wx 
  15   
  16   
  17  if __name__ == '__main__': 
  18          sys.path.insert(0, '../../') 
  19  from Gnumed.pycommon import gmDispatcher 
  20   
  21   
  22  _log = logging.getLogger('gm.ui') 
  23  _log.info(__version__) 
  24  #==================================================================== 
  25  edit_area_modes = ['new', 'edit', 'new_from_existing'] 
  26   
27 -class cGenericEditAreaMixin(object):
28 """Mixin for edit area panels providing generic functionality. 29 30 **************** start of template **************** 31 32 #==================================================================== 33 # Class definition: 34 35 from Gnumed.wxGladeWidgets import wxgXxxEAPnl 36 37 class cXxxEAPnl(wxgXxxEAPnl.wxgXxxEAPnl, gmEditArea.cGenericEditAreaMixin): 38 39 def __init__(self, *args, **kwargs): 40 41 try: 42 data = kwargs['xxx'] 43 del kwargs['xxx'] 44 except KeyError: 45 data = None 46 47 wxgXxxEAPnl.wxgXxxEAPnl.__init__(self, *args, **kwargs) 48 gmEditArea.cGenericEditAreaMixin.__init__(self) 49 50 # Code using this mixin should set mode and data 51 # after instantiating the class: 52 self.mode = 'new' 53 self.data = data 54 if data is not None: 55 self.mode = 'edit' 56 57 #self.__init_ui() 58 #---------------------------------------------------------------- 59 # def __init_ui(self): 60 # # adjust phrasewheels etc 61 #---------------------------------------------------------------- 62 # generic Edit Area mixin API 63 #---------------------------------------------------------------- 64 def _valid_for_save(self): 65 66 # its best to validate bottom -> top such that the 67 # cursor ends up in the topmost failing field 68 69 # remove when implemented: 70 return False 71 72 validity = True 73 74 if self._TCTRL_xxx.GetValue().strip() == u'': 75 validity = False 76 self.display_tctrl_as_valid(tctrl = self._TCTRL_xxx, valid = False) 77 self._TCTRL_xxx.SetFocus() 78 else: 79 self.display_tctrl_as_valid(tctrl = self._TCTRL_xxx, valid = True) 80 81 if self._PRW_xxx.GetData() is None: 82 validity = False 83 self._PRW_xxx.display_as_valid(False) 84 self._PRW_xxx.SetFocus() 85 else: 86 self._PRW_xxx.display_as_valid(True) 87 88 return validity 89 #---------------------------------------------------------------- 90 def _save_as_new(self): 91 # save the data as a new instance 92 data = gmXXXX.create_xxxx() 93 94 data[''] = self._ 95 data[''] = self._ 96 97 data.save() 98 99 # must be done very late or else the property access 100 # will refresh the display such that later field 101 # access will return empty values 102 self.data = data 103 return False 104 return True 105 #---------------------------------------------------------------- 106 def _save_as_update(self): 107 # update self.data and save the changes 108 self.data[''] = self._TCTRL_xxx.GetValue().strip() 109 self.data[''] = self._PRW_xxx.GetData() 110 self.data[''] = self._CHBOX_xxx.GetValue() 111 self.data.save() 112 return True 113 #---------------------------------------------------------------- 114 def _refresh_as_new(self): 115 pass 116 #---------------------------------------------------------------- 117 def _refresh_as_new_from_existing(self): 118 self._refresh_as_new() 119 #---------------------------------------------------------------- 120 def _refresh_from_existing(self): 121 pass 122 #---------------------------------------------------------------- 123 124 **************** end of template **************** 125 """
126 - def __init__(self):
127 self.__mode = 'new' 128 self.__data = None 129 self.successful_save_msg = None 130 self.__tctrl_validity_colors = { 131 True: wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW), 132 False: 'pink' 133 } 134 self._refresh_as_new()
135 #----------------------------------------------------------------
136 - def _get_mode(self):
137 return self.__mode
138
139 - def _set_mode(self, mode=None):
140 if mode not in edit_area_modes: 141 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes)) 142 if mode == 'edit': 143 if self.__data is None: 144 raise ValueError('[%s] <mode> "edit" needs data value' % self.__class__.__name__) 145 146 prev_mode = self.__mode 147 self.__mode = mode 148 if mode != prev_mode: 149 self.refresh()
150 151 mode = property(_get_mode, _set_mode) 152 #----------------------------------------------------------------
153 - def _get_data(self):
154 return self.__data
155
156 - def _set_data(self, data=None):
157 if data is None: 158 if self.__mode == 'edit': 159 raise ValueError('[%s] <mode> "edit" needs data value' % self.__class__.__name__) 160 self.__data = data 161 self.refresh()
162 163 data = property(_get_data, _set_data) 164 #----------------------------------------------------------------
165 - def save(self):
166 """Invoked from the generic edit area dialog. 167 168 Invokes 169 _valid_for_save, 170 _save_as_new, 171 _save_as_update 172 on the implementing edit area as needed. 173 174 _save_as_* must set self.__data and return True/False 175 """ 176 if not self._valid_for_save(): 177 return False 178 179 # remove messages about previous invalid save attempts 180 gmDispatcher.send(signal = 'statustext', msg = u'') 181 182 if self.__mode in ['new', 'new_from_existing']: 183 if self._save_as_new(): 184 self.mode = 'edit' 185 return True 186 return False 187 188 elif self.__mode == 'edit': 189 return self._save_as_update() 190 191 else: 192 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
193 #----------------------------------------------------------------
194 - def refresh(self):
195 """Invoked from the generic edit area dialog. 196 197 Invokes 198 _refresh_as_new() 199 _refresh_from_existing() 200 _refresh_as_new_from_existing() 201 on the implementing edit area as needed. 202 203 Then calls _valid_for_save(). 204 """ 205 if self.__mode == 'new': 206 result = self._refresh_as_new() 207 self._valid_for_save() 208 return result 209 elif self.__mode == 'edit': 210 result = self._refresh_from_existing() 211 return result 212 elif self.__mode == 'new_from_existing': 213 result = self._refresh_as_new_from_existing() 214 self._valid_for_save() 215 return result 216 else: 217 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
218 #----------------------------------------------------------------
219 - def display_tctrl_as_valid(self, tctrl=None, valid=None):
220 tctrl.SetBackgroundColour(self.__tctrl_validity_colors[valid]) 221 tctrl.Refresh()
222 #----------------------------------------------------------------
223 - def display_ctrl_as_valid(self, ctrl=None, valid=None):
224 ctrl.SetBackgroundColour(self.__tctrl_validity_colors[valid]) 225 ctrl.Refresh()
226 #==================================================================== 227 from Gnumed.wxGladeWidgets import wxgGenericEditAreaDlg2 228
229 -class cGenericEditAreaDlg2(wxgGenericEditAreaDlg2.wxgGenericEditAreaDlg2):
230 """Dialog for parenting edit area panels with save/clear/next/cancel""" 231 232 _lucky_day = 1 233 _lucky_month = 4 234 _today = pydt.date.today() 235
236 - def __init__(self, *args, **kwargs):
237 238 new_ea = kwargs['edit_area'] 239 del kwargs['edit_area'] 240 241 if not isinstance(new_ea, cGenericEditAreaMixin): 242 raise TypeError('[%s]: edit area instance must be child of cGenericEditAreaMixin') 243 244 try: 245 single_entry = kwargs['single_entry'] 246 del kwargs['single_entry'] 247 except KeyError: 248 single_entry = False 249 250 wxgGenericEditAreaDlg2.wxgGenericEditAreaDlg2.__init__(self, *args, **kwargs) 251 252 self.left_extra_button = None 253 254 if cGenericEditAreaDlg2._today.day != cGenericEditAreaDlg2._lucky_day: 255 self._BTN_lucky.Enable(False) 256 self._BTN_lucky.Hide() 257 else: 258 if cGenericEditAreaDlg2._today.month != cGenericEditAreaDlg2._lucky_month: 259 self._BTN_lucky.Enable(False) 260 self._BTN_lucky.Hide() 261 262 # replace dummy panel 263 dummy_ea_pnl = self._PNL_ea 264 ea_pnl_szr = dummy_ea_pnl.GetContainingSizer() 265 ea_pnl_parent = dummy_ea_pnl.GetParent() 266 ea_pnl_szr.Remove(dummy_ea_pnl) 267 dummy_ea_pnl.Destroy() 268 del dummy_ea_pnl 269 new_ea_min_size = new_ea.GetMinSize() 270 new_ea.Reparent(ea_pnl_parent) 271 self._PNL_ea = new_ea 272 ea_pnl_szr.Add(self._PNL_ea, 1, wx.EXPAND, 0) 273 ea_pnl_szr.SetMinSize(new_ea_min_size) # set minimum size of EA pnl sizer from its new EA item 274 ea_pnl_szr.Fit(new_ea) # resize the new EA to the minimum size of the EA pnl sizer 275 276 # adjust buttons 277 if single_entry: 278 self._BTN_forward.Enable(False) 279 self._BTN_forward.Hide() 280 281 self._adjust_clear_revert_buttons() 282 283 # redraw layout 284 #self.Layout() 285 main_szr = self.GetSizer() 286 main_szr.Fit(self) 287 self.Layout() 288 #self.Refresh() # apparently not needed (27.3.2011) 289 290 self._PNL_ea.refresh()
291 #--------------------------------------------------------
293 if self._PNL_ea.data is None: 294 self._BTN_clear.Enable(True) 295 self._BTN_clear.Show() 296 self._BTN_revert.Enable(False) 297 self._BTN_revert.Hide() 298 else: 299 self._BTN_clear.Enable(False) 300 self._BTN_clear.Hide() 301 self._BTN_revert.Enable(True) 302 self._BTN_revert.Show()
303 #--------------------------------------------------------
304 - def _on_save_button_pressed(self, evt):
305 if self._PNL_ea.save(): 306 if self.IsModal(): 307 self.EndModal(wx.ID_OK) 308 else: 309 self.Close()
310 #--------------------------------------------------------
311 - def _on_revert_button_pressed(self, evt):
312 self._PNL_ea.refresh()
313 #--------------------------------------------------------
314 - def _on_clear_button_pressed(self, evt):
315 self._PNL_ea.refresh()
316 #--------------------------------------------------------
317 - def _on_forward_button_pressed(self, evt):
318 if self._PNL_ea.save(): 319 if self._PNL_ea.successful_save_msg is not None: 320 gmDispatcher.send(signal = 'statustext', msg = self._PNL_ea.successful_save_msg) 321 self._PNL_ea.mode = 'new_from_existing' 322 323 self._adjust_clear_revert_buttons() 324 325 self.Layout() 326 main_szr = self.GetSizer() 327 main_szr.Fit(self) 328 self.Refresh() 329 330 self._PNL_ea.refresh()
331 #--------------------------------------------------------
332 - def _on_lucky_button_pressed(self, evt):
333 gmGuiHelpers.gm_show_info ( 334 _( 'Today is your lucky day !\n' 335 '\n' 336 'You have won one year of GNUmed\n' 337 'updates for free !\n' 338 ), 339 _('GNUmed Lottery') 340 )
341 #--------------------------------------------------------
342 - def _on_left_extra_button_pressed(self, event):
343 if not self.__left_extra_button_callback(self._PNL_ea.data): 344 return 345 346 if self.IsModal(): 347 self.EndModal(wx.ID_OK) 348 else: 349 self.Close()
350 #------------------------------------------------------------ 351 # properties 352 #------------------------------------------------------------
353 - def _set_left_extra_button(self, definition):
354 if definition is None: 355 self._BTN_extra_left.Enable(False) 356 self._BTN_extra_left.Hide() 357 self.__left_extra_button_callback = None 358 return 359 360 (label, tooltip, callback) = definition 361 if not callable(callback): 362 raise ValueError('<left extra button> callback is not a callable: %s' % callback) 363 self.__left_extra_button_callback = callback 364 self._BTN_extra_left.SetLabel(label) 365 self._BTN_extra_left.SetToolTipString(tooltip) 366 self._BTN_extra_left.Enable(True) 367 self._BTN_extra_left.Show()
368 369 left_extra_button = property(lambda x:x, _set_left_extra_button)
370 #==================================================================== 371 # DEPRECATED: 372 from Gnumed.wxGladeWidgets import wxgGenericEditAreaDlg 373
374 -class cGenericEditAreaDlg(wxgGenericEditAreaDlg.wxgGenericEditAreaDlg):
375 """Dialog for parenting edit area with save/clear/cancel""" 376
377 - def __init__(self, *args, **kwargs):
378 379 ea = kwargs['edit_area'] 380 del kwargs['edit_area'] 381 382 wxgGenericEditAreaDlg.wxgGenericEditAreaDlg.__init__(self, *args, **kwargs) 383 384 szr = self._PNL_ea.GetContainingSizer() 385 szr.Remove(self._PNL_ea) 386 ea.Reparent(self) 387 szr.Add(ea, 1, wx.ALL|wx.EXPAND, 4) 388 self._PNL_ea = ea 389 390 self.Layout() 391 szr = self.GetSizer() 392 szr.Fit(self) 393 self.Refresh() 394 395 self._PNL_ea.refresh()
396 #--------------------------------------------------------
397 - def _on_save_button_pressed(self, evt):
398 """The edit area save() method must return True/False.""" 399 if self._PNL_ea.save(): 400 if self.IsModal(): 401 self.EndModal(wx.ID_OK) 402 else: 403 self.Close()
404 #--------------------------------------------------------
405 - def _on_clear_button_pressed(self, evt):
406 self._PNL_ea.refresh()
407 #==================================================================== 408 #==================================================================== 409 #==================================================================== 410 #import time 411 412 #from Gnumed.business import gmPerson, gmDemographicRecord 413 from Gnumed.pycommon import gmGuiBroker 414 #from Gnumed.wxpython import gmDateTimeInput, gmPhraseWheel, gmGuiHelpers 415 416 _gb = gmGuiBroker.GuiBroker() 417 418 gmSECTION_SUMMARY = 1 419 gmSECTION_DEMOGRAPHICS = 2 420 gmSECTION_CLINICALNOTES = 3 421 gmSECTION_FAMILYHISTORY = 4 422 gmSECTION_PASTHISTORY = 5 423 gmSECTION_SCRIPT = 8 424 gmSECTION_REQUESTS = 9 425 gmSECTION_REFERRALS = 11 426 gmSECTION_RECALLS = 12 427 428 richards_blue = wx.Colour(0,0,131) 429 richards_aqua = wx.Colour(0,194,197) 430 richards_dark_gray = wx.Color(131,129,131) 431 richards_light_gray = wx.Color(255,255,255) 432 richards_coloured_gray = wx.Color(131,129,131) 433 434 435 CONTROLS_WITHOUT_LABELS =['wxTextCtrl', 'cEditAreaField', 'wx.SpinCtrl', 'gmPhraseWheel', 'wx.ComboBox'] 436
437 -def _decorate_editarea_field(widget):
438 widget.SetForegroundColour(wx.Color(255, 0, 0)) 439 widget.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
440 #====================================================================
441 -class cEditAreaPopup(wx.Dialog):
442 - def __init__ ( 443 self, 444 parent, 445 id, 446 title = 'edit area popup', 447 pos=wx.DefaultPosition, 448 size=wx.DefaultSize, 449 style=wx.SIMPLE_BORDER, 450 name='', 451 edit_area = None 452 ):
453 if not isinstance(edit_area, cEditArea2): 454 raise TypeError('<edit_area> must be of type cEditArea2 but is <%s>' % type(edit_area)) 455 wx.Dialog.__init__(self, parent, id, title, pos, size, style, name) 456 self.__wxID_BTN_SAVE = wx.NewId() 457 self.__wxID_BTN_RESET = wx.NewId() 458 self.__editarea = edit_area 459 self.__do_layout() 460 self.__register_events()
461 #-------------------------------------------------------- 462 # public API 463 #--------------------------------------------------------
464 - def get_summary(self):
465 return self.__editarea.get_summary()
466 #--------------------------------------------------------
467 - def __do_layout(self):
468 self.__editarea.Reparent(self) 469 470 self.__btn_SAVE = wx.Button(self, self.__wxID_BTN_SAVE, _("Save")) 471 self.__btn_SAVE.SetToolTipString(_('save entry into medical record')) 472 self.__btn_RESET = wx.Button(self, self.__wxID_BTN_RESET, _("Reset")) 473 self.__btn_RESET.SetToolTipString(_('reset entry')) 474 self.__btn_CANCEL = wx.Button(self, wx.ID_CANCEL, _("Cancel")) 475 self.__btn_CANCEL.SetToolTipString(_('discard entry and cancel')) 476 477 szr_buttons = wx.BoxSizer(wx.HORIZONTAL) 478 szr_buttons.Add(self.__btn_SAVE, 1, wx.EXPAND | wx.ALL, 1) 479 szr_buttons.Add(self.__btn_RESET, 1, wx.EXPAND | wx.ALL, 1) 480 szr_buttons.Add(self.__btn_CANCEL, 1, wx.EXPAND | wx.ALL, 1) 481 482 szr_main = wx.BoxSizer(wx.VERTICAL) 483 szr_main.Add(self.__editarea, 1, wx.EXPAND) 484 szr_main.Add(szr_buttons, 0, wx.EXPAND) 485 486 self.SetSizerAndFit(szr_main)
487 #-------------------------------------------------------- 488 # event handling 489 #--------------------------------------------------------
490 - def __register_events(self):
491 # connect standard buttons 492 wx.EVT_BUTTON(self.__btn_SAVE, self.__wxID_BTN_SAVE, self._on_SAVE_btn_pressed) 493 wx.EVT_BUTTON(self.__btn_RESET, self.__wxID_BTN_RESET, self._on_RESET_btn_pressed) 494 wx.EVT_BUTTON(self.__btn_CANCEL, wx.ID_CANCEL, self._on_CANCEL_btn_pressed) 495 496 wx.EVT_CLOSE(self, self._on_CANCEL_btn_pressed) 497 498 # client internal signals 499 # gmDispatcher.connect(signal = gmSignals.pre_patient_selection(), receiver = self._on_pre_patient_selection) 500 # gmDispatcher.connect(signal = gmSignals.application_closing(), receiver = self._on_application_closing) 501 # gmDispatcher.connect(signal = gmSignals.post_patient_selection(), receiver = self.on_post_patient_selection) 502 503 return 1
504 #--------------------------------------------------------
505 - def _on_SAVE_btn_pressed(self, evt):
506 if self.__editarea.save_data(): 507 self.__editarea.Close() 508 self.EndModal(wx.ID_OK) 509 return 510 short_err = self.__editarea.get_short_error() 511 long_err = self.__editarea.get_long_error() 512 if (short_err is None) and (long_err is None): 513 long_err = _( 514 'Unspecified error saving data in edit area.\n\n' 515 'Programmer forgot to specify proper error\n' 516 'message in [%s].' 517 ) % self.__editarea.__class__.__name__ 518 if short_err is not None: 519 gmDispatcher.send(signal = 'statustext', msg = short_err) 520 if long_err is not None: 521 gmGuiHelpers.gm_show_error(long_err, _('saving clinical data'))
522 #--------------------------------------------------------
523 - def _on_CANCEL_btn_pressed(self, evt):
524 self.__editarea.Close() 525 self.EndModal(wx.ID_CANCEL)
526 #--------------------------------------------------------
527 - def _on_RESET_btn_pressed(self, evt):
528 self.__editarea.reset_ui()
529 #====================================================================
530 -class cEditArea2(wx.Panel):
531 - def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TAB_TRAVERSAL):
532 # init main background panel 533 wx.Panel.__init__ ( 534 self, 535 parent, 536 id, 537 pos = pos, 538 size = size, 539 style = style | wx.TAB_TRAVERSAL 540 ) 541 self.SetBackgroundColour(wx.Color(222,222,222)) 542 543 self.data = None # a placeholder for opaque data 544 self.fields = {} 545 self.prompts = {} 546 self._short_error = None 547 self._long_error = None 548 self._summary = None 549 self._patient = gmPerson.gmCurrentPatient() 550 self.__wxID_BTN_OK = wx.NewId() 551 self.__wxID_BTN_CLEAR = wx.NewId() 552 self.__do_layout() 553 self.__register_events() 554 self.Show()
555 #-------------------------------------------------------- 556 # external API 557 #--------------------------------------------------------
558 - def save_data(self):
559 """This needs to be overridden by child classes.""" 560 self._long_error = _( 561 'Cannot save data from edit area.\n\n' 562 'Programmer forgot to override method:\n' 563 ' <%s.save_data>' 564 ) % self.__class__.__name__ 565 return False
566 #--------------------------------------------------------
567 - def reset_ui(self):
568 msg = _( 569 'Cannot reset fields in edit area.\n\n' 570 'Programmer forgot to override method:\n' 571 ' <%s.reset_ui>' 572 ) % self.__class__.__name__ 573 gmGuiHelpers.gm_show_error(msg)
574 #--------------------------------------------------------
575 - def get_short_error(self):
576 tmp = self._short_error 577 self._short_error = None 578 return tmp
579 #--------------------------------------------------------
580 - def get_long_error(self):
581 tmp = self._long_error 582 self._long_error = None 583 return tmp
584 #--------------------------------------------------------
585 - def get_summary(self):
586 return _('<No embed string for [%s]>') % self.__class__.__name__
587 #-------------------------------------------------------- 588 # event handling 589 #--------------------------------------------------------
590 - def __register_events(self):
591 # client internal signals 592 if self._patient.connected: 593 gmDispatcher.connect(signal = 'pre_patient_selection', receiver = self._on_pre_patient_selection) 594 gmDispatcher.connect(signal = 'post_patient_selection', receiver = self.on_post_patient_selection) 595 gmDispatcher.connect(signal = 'application_closing', receiver = self._on_application_closing) 596 597 # wxPython events 598 wx.EVT_CLOSE(self, self._on_close) 599 600 return 1
601 #--------------------------------------------------------
602 - def __deregister_events(self):
603 gmDispatcher.disconnect(signal = u'pre_patient_selection', receiver = self._on_pre_patient_selection) 604 gmDispatcher.disconnect(signal = u'post_patient_selection', receiver = self.on_post_patient_selection) 605 gmDispatcher.disconnect(signal = u'application_closing', receiver = self._on_application_closing)
606 #-------------------------------------------------------- 607 # handlers 608 #--------------------------------------------------------
609 - def _on_close(self, event):
610 self.__deregister_events() 611 event.Skip()
612 #--------------------------------------------------------
613 - def _on_OK_btn_pressed(self, event):
614 """Only active if _make_standard_buttons was called in child class.""" 615 # FIXME: this try: except: block seems to large 616 try: 617 event.Skip() 618 if self.data is None: 619 self._save_new_entry() 620 self.reset_ui() 621 else: 622 self._save_modified_entry() 623 self.reset_ui() 624 except gmExceptions.InvalidInputError, err: 625 # nasty evil popup dialogue box 626 # but for invalid input we want to interrupt user 627 gmGuiHelpers.gm_show_error (err, _("Invalid Input")) 628 except: 629 _log.exception( "save data problem in [%s]" % self.__class__.__name__)
630 #--------------------------------------------------------
631 - def _on_clear_btn_pressed(self, event):
632 """Only active if _make_standard_buttons was called in child class.""" 633 # FIXME: check for unsaved data 634 self.reset_ui() 635 event.Skip()
636 #--------------------------------------------------------
637 - def _on_application_closing(self, **kwds):
638 self.__deregister_events() 639 # remember wxCallAfter 640 if not self._patient.connected: 641 return True 642 # FIXME: should do this: 643 # if self.user_wants_save(): 644 # if self.save_data(): 645 # return True 646 return True 647 _log.error('[%s] lossage' % self.__class__.__name__) 648 return False
649 #--------------------------------------------------------
650 - def _on_pre_patient_selection(self, **kwds):
651 """Just before new patient becomes active.""" 652 # remember wxCallAfter 653 if not self._patient.connected: 654 return True 655 # FIXME: should do this: 656 # if self.user_wants_save(): 657 # if self.save_data(): 658 # return True 659 return True 660 _log.error('[%s] lossage' % self.__class__.__name__) 661 return False
662 #--------------------------------------------------------
663 - def on_post_patient_selection( self, **kwds):
664 """Just after new patient became active.""" 665 # remember to use wxCallAfter() 666 self.reset_ui()
667 #---------------------------------------------------------------- 668 # internal helpers 669 #----------------------------------------------------------------
670 - def __do_layout(self):
671 672 # define prompts and fields 673 self._define_prompts() 674 self._define_fields(parent = self) 675 if len(self.fields) != len(self.prompts): 676 _log.error('[%s]: #fields != #prompts' % self.__class__.__name__) 677 return None 678 679 # and generate edit area from it 680 szr_main_fgrid = wx.FlexGridSizer(rows = len(self.prompts), cols=2) 681 color = richards_aqua 682 lines = self.prompts.keys() 683 lines.sort() 684 for line in lines: 685 # 1) prompt 686 label, color, weight = self.prompts[line] 687 # FIXME: style for centering in vertical direction ? 688 prompt = wx.StaticText ( 689 parent = self, 690 id = -1, 691 label = label, 692 style = wx.ALIGN_CENTRE 693 ) 694 # FIXME: resolution dependant 695 prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, '')) 696 prompt.SetForegroundColour(color) 697 prompt.SetBackgroundColour(richards_light_gray) 698 szr_main_fgrid.Add(prompt, flag=wx.EXPAND | wx.ALIGN_RIGHT) 699 700 # 2) widget(s) for line 701 szr_line = wx.BoxSizer(wx.HORIZONTAL) 702 positions = self.fields[line].keys() 703 positions.sort() 704 for pos in positions: 705 field, weight = self.fields[line][pos] 706 # field.SetBackgroundColour(wx.Color(222,222,222)) 707 szr_line.Add(field, weight, wx.EXPAND) 708 szr_main_fgrid.Add(szr_line, flag=wx.GROW | wx.ALIGN_LEFT) 709 710 # grid can grow column 1 only, not column 0 711 szr_main_fgrid.AddGrowableCol(1) 712 713 # # use sizer for border around everything plus a little gap 714 # # FIXME: fold into szr_main_panels ? 715 # self.szr_central_container = wx.BoxSizer(wxHORIZONTAL) 716 # self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wxALL, 5) 717 718 # and do the layouting 719 self.SetSizerAndFit(szr_main_fgrid)
720 # self.FitInside() 721 #---------------------------------------------------------------- 722 # intra-class API 723 #----------------------------------------------------------------
724 - def _define_prompts(self):
725 """Child classes override this to define their prompts using _add_prompt()""" 726 _log.error('missing override in [%s]' % self.__class__.__name__)
727 #----------------------------------------------------------------
728 - def _add_prompt(self, line, label='missing label', color=richards_blue, weight=0):
729 """Add a new prompt line. 730 731 To be used from _define_fields in child classes. 732 733 - label, the label text 734 - color 735 - weight, the weight given in sizing the various rows. 0 means the row 736 always has minimum size 737 """ 738 self.prompts[line] = (label, color, weight)
739 #----------------------------------------------------------------
740 - def _define_fields(self, parent):
741 """Defines the fields. 742 743 - override in child classes 744 - mostly uses _add_field() 745 """ 746 _log.error('missing override in [%s]' % self.__class__.__name__)
747 #----------------------------------------------------------------
748 - def _add_field(self, line=None, pos=None, widget=None, weight=0):
749 if None in (line, pos, widget): 750 _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget)) 751 if not self.fields.has_key(line): 752 self.fields[line] = {} 753 self.fields[line][pos] = (widget, weight)
754 #----------------------------------------------------------------
755 - def _make_standard_buttons(self, parent):
756 """Generates OK/CLEAR buttons for edit area.""" 757 self.btn_OK = wx.Button(parent, self.__wxID_BTN_OK, _("OK")) 758 self.btn_OK.SetToolTipString(_('save entry into medical record')) 759 self.btn_Clear = wx.Button(parent, self.__wxID_BTN_CLEAR, _("Clear")) 760 self.btn_Clear.SetToolTipString(_('initialize input fields for new entry')) 761 762 szr_buttons = wx.BoxSizer(wx.HORIZONTAL) 763 szr_buttons.Add(self.btn_OK, 1, wx.EXPAND | wx.ALL, 1) 764 szr_buttons.Add((5, 0), 0) 765 szr_buttons.Add(self.btn_Clear, 1, wx.EXPAND | wx.ALL, 1) 766 767 # connect standard buttons 768 wx.EVT_BUTTON(self.btn_OK, self.__wxID_BTN_OK, self._on_OK_btn_pressed) 769 wx.EVT_BUTTON(self.btn_Clear, self.__wxID_BTN_CLEAR, self._on_clear_btn_pressed) 770 771 return szr_buttons
772 #==================================================================== 773 #==================================================================== 774 #text control class to be later replaced by the gmPhraseWheel 775 #--------------------------------------------------------------------
776 -class cEditAreaField(wx.TextCtrl):
777 - def __init__ (self, parent, id = -1, pos = wx.DefaultPosition, size=wx.DefaultSize):
778 wx.TextCtrl.__init__(self,parent,id,"",pos, size ,wx.SIMPLE_BORDER) 779 _decorate_editarea_field(self)
780 #====================================================================
781 -class cEditArea(wx.Panel):
782 - def __init__(self, parent, id, pos, size, style):
783 784 print "class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__ 785 786 # init main background panel 787 wx.Panel.__init__(self, parent, id, pos=pos, size=size, style=wx.NO_BORDER | wx.TAB_TRAVERSAL) 788 self.SetBackgroundColour(wx.Color(222,222,222)) 789 790 self.data = None 791 self.fields = {} 792 self.prompts = {} 793 794 ID_BTN_OK = wx.NewId() 795 ID_BTN_CLEAR = wx.NewId() 796 797 self.__do_layout() 798 799 # self.input_fields = {} 800 801 # self._postInit() 802 # self.old_data = {} 803 804 self._patient = gmPerson.gmCurrentPatient() 805 self.__register_events() 806 self.Show(True)
807 #---------------------------------------------------------------- 808 # internal helpers 809 #----------------------------------------------------------------
810 - def __do_layout(self):
811 # define prompts and fields 812 self._define_prompts() 813 self.fields_pnl = wx.Panel(self, -1, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL) 814 self._define_fields(parent = self.fields_pnl) 815 # and generate edit area from it 816 szr_prompts = self.__generate_prompts() 817 szr_fields = self.__generate_fields() 818 819 # stack prompts and fields horizontally 820 self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL) 821 self.szr_main_panels.Add(szr_prompts, 11, wx.EXPAND) 822 self.szr_main_panels.Add(5, 0, 0, wx.EXPAND) 823 self.szr_main_panels.Add(szr_fields, 90, wx.EXPAND) 824 825 # use sizer for border around everything plus a little gap 826 # FIXME: fold into szr_main_panels ? 827 self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL) 828 self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5) 829 830 # and do the layouting 831 self.SetAutoLayout(True) 832 self.SetSizer(self.szr_central_container) 833 self.szr_central_container.Fit(self)
834 #----------------------------------------------------------------
835 - def __generate_prompts(self):
836 if len(self.fields) != len(self.prompts): 837 _log.error('[%s]: #fields != #prompts' % self.__class__.__name__) 838 return None 839 # prompts live on a panel 840 prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER) 841 prompt_pnl.SetBackgroundColour(richards_light_gray) 842 # make them 843 color = richards_aqua 844 lines = self.prompts.keys() 845 lines.sort() 846 self.prompt_widget = {} 847 for line in lines: 848 label, color, weight = self.prompts[line] 849 self.prompt_widget[line] = self.__make_prompt(prompt_pnl, "%s " % label, color) 850 # make shadow below prompts in gray 851 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0) 852 shadow_below_prompts.SetBackgroundColour(richards_dark_gray) 853 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL) 854 szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND) 855 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND) 856 857 # stack prompt panel and shadow vertically 858 vszr_prompts = wx.BoxSizer(wx.VERTICAL) 859 vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND) 860 vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND) 861 862 # make shadow to the right of the prompts 863 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0) 864 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray) 865 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL) 866 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND) 867 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts, 1, wx.EXPAND) 868 869 # stack vertical prompt sizer and shadow horizontally 870 hszr_prompts = wx.BoxSizer(wx.HORIZONTAL) 871 hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND) 872 hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND) 873 874 return hszr_prompts
875 #----------------------------------------------------------------
876 - def __generate_fields(self):
877 self.fields_pnl.SetBackgroundColour(wx.Color(222,222,222)) 878 # rows, cols, hgap, vgap 879 vszr = wx.BoxSizer(wx.VERTICAL) 880 lines = self.fields.keys() 881 lines.sort() 882 self.field_line_szr = {} 883 for line in lines: 884 self.field_line_szr[line] = wx.BoxSizer(wx.HORIZONTAL) 885 positions = self.fields[line].keys() 886 positions.sort() 887 for pos in positions: 888 field, weight = self.fields[line][pos] 889 self.field_line_szr[line].Add(field, weight, wx.EXPAND) 890 try: 891 vszr.Add(self.field_line_szr[line], self.prompts[line][2], flag = wx.EXPAND) # use same lineweight as prompts 892 except KeyError: 893 _log.error("Error with line=%s, self.field_line_szr has key:%s; self.prompts has key: %s" % (line, self.field_line_szr.has_key(line), self.prompts.has_key(line) ) ) 894 # put them on the panel 895 self.fields_pnl.SetSizer(vszr) 896 vszr.Fit(self.fields_pnl) 897 898 # make shadow below edit fields in gray 899 shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0) 900 shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray) 901 szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL) 902 szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND) 903 szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND) 904 905 # stack edit fields and shadow vertically 906 vszr_edit_fields = wx.BoxSizer(wx.VERTICAL) 907 vszr_edit_fields.Add(self.fields_pnl, 92, wx.EXPAND) 908 vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND) 909 910 # make shadow to the right of the edit area 911 shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0) 912 shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray) 913 szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL) 914 szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND) 915 szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND) 916 917 # stack vertical edit fields sizer and shadow horizontally 918 hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL) 919 hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND) 920 hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND) 921 922 return hszr_edit_fields
923 #---------------------------------------------------------------
924 - def __make_prompt(self, parent, aLabel, aColor):
925 # FIXME: style for centering in vertical direction ? 926 prompt = wx.StaticText( 927 parent, 928 -1, 929 aLabel, 930 style = wx.ALIGN_RIGHT 931 ) 932 prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, '')) 933 prompt.SetForegroundColour(aColor) 934 return prompt
935 #---------------------------------------------------------------- 936 # intra-class API 937 #----------------------------------------------------------------
938 - def _add_prompt(self, line, label='missing label', color=richards_blue, weight=0):
939 """Add a new prompt line. 940 941 To be used from _define_fields in child classes. 942 943 - label, the label text 944 - color 945 - weight, the weight given in sizing the various rows. 0 means the rwo 946 always has minimum size 947 """ 948 self.prompts[line] = (label, color, weight)
949 #----------------------------------------------------------------
950 - def _add_field(self, line=None, pos=None, widget=None, weight=0):
951 if None in (line, pos, widget): 952 _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget)) 953 if not self.fields.has_key(line): 954 self.fields[line] = {} 955 self.fields[line][pos] = (widget, weight)
956 #----------------------------------------------------------------
957 - def _define_fields(self, parent):
958 """Defines the fields. 959 960 - override in child classes 961 - mostly uses _add_field() 962 """ 963 _log.error('missing override in [%s]' % self.__class__.__name__)
964 #----------------------------------------------------------------
965 - def _define_prompts(self):
966 _log.error('missing override in [%s]' % self.__class__.__name__)
967 #----------------------------------------------------------------
968 - def _make_standard_buttons(self, parent):
969 """Generates OK/CLEAR buttons for edit area.""" 970 self.btn_OK = wx.Button(parent, ID_BTN_OK, _("OK")) 971 self.btn_OK.SetToolTipString(_('save entry into medical record')) 972 self.btn_Clear = wx.Button(parent, ID_BTN_CLEAR, _("Clear")) 973 self.btn_Clear.SetToolTipString(_('initialize input fields for new entry')) 974 975 szr_buttons = wx.BoxSizer(wx.HORIZONTAL) 976 szr_buttons.Add(self.btn_OK, 1, wx.EXPAND | wx.ALL, 1) 977 szr_buttons.Add(5, 0, 0) 978 szr_buttons.Add(self.btn_Clear, 1, wx.EXPAND | wx.ALL, 1) 979 980 return szr_buttons
981 #--------------------------------------------------------
982 - def _pre_save_data(self):
983 pass
984 #--------------------------------------------------------
985 - def _save_data(self):
986 _log.error('[%s] programmer forgot to define _save_data()' % self.__class__.__name__) 987 _log.info('child classes of cEditArea *must* override this function') 988 return False
989 #-------------------------------------------------------- 990 # event handling 991 #--------------------------------------------------------
992 - def __register_events(self):
993 # connect standard buttons 994 wx.EVT_BUTTON(self.btn_OK, ID_BTN_OK, self._on_OK_btn_pressed) 995 wx.EVT_BUTTON(self.btn_Clear, ID_BTN_CLEAR, self._on_clear_btn_pressed) 996 997 wx.EVT_SIZE (self.fields_pnl, self._on_resize_fields) 998 999 # client internal signals 1000 gmDispatcher.connect(signal = u'pre_patient_selection', receiver = self._on_pre_patient_selection) 1001 gmDispatcher.connect(signal = u'application_closing', receiver = self._on_application_closing) 1002 gmDispatcher.connect(signal = u'post_patient_selection', receiver = self.on_post_patient_selection) 1003 1004 return 1
1005 #-------------------------------------------------------- 1006 # handlers 1007 #--------------------------------------------------------
1008 - def _on_OK_btn_pressed(self, event):
1009 # FIXME: this try: except: block seems to large 1010 try: 1011 event.Skip() 1012 if self.data is None: 1013 self._save_new_entry() 1014 self.set_data() 1015 else: 1016 self._save_modified_entry() 1017 self.set_data() 1018 except gmExceptions.InvalidInputError, err: 1019 # nasty evil popup dialogue box 1020 # but for invalid input we want to interrupt user 1021 gmGuiHelpers.gm_show_error (err, _("Invalid Input")) 1022 except: 1023 _log.exception( "save data problem in [%s]" % self.__class__.__name__)
1024 #--------------------------------------------------------
1025 - def _on_clear_btn_pressed(self, event):
1026 # FIXME: check for unsaved data 1027 self.set_data() 1028 event.Skip()
1029 #--------------------------------------------------------
1030 - def on_post_patient_selection( self, **kwds):
1031 # remember to use wxCallAfter() 1032 self.set_data()
1033 #--------------------------------------------------------
1034 - def _on_application_closing(self, **kwds):
1035 # remember wxCallAfter 1036 if not self._patient.connected: 1037 return True 1038 if self._save_data(): 1039 return True 1040 _log.error('[%s] lossage' % self.__class__.__name__) 1041 return False
1042 #--------------------------------------------------------
1043 - def _on_pre_patient_selection(self, **kwds):
1044 # remember wxCallAfter 1045 if not self._patient.connected: 1046 return True 1047 if self._save_data(): 1048 return True 1049 _log.error('[%s] lossage' % self.__class__.__name__) 1050 return False
1051 #--------------------------------------------------------
1052 - def _on_resize_fields (self, event):
1053 self.fields_pnl.Layout() 1054 # resize the prompts accordingly 1055 for i in self.field_line_szr.keys(): 1056 # query the BoxSizer to find where the field line is 1057 pos = self.field_line_szr[i].GetPosition() 1058 # and set the prompt lable to the same Y position 1059 self.prompt_widget[i].SetPosition((0, pos.y))
1060 #====================================================================
1061 -class gmEditArea(cEditArea):
1062 - def __init__(self, parent, id, aType = None):
1063 1064 print "class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__ 1065 1066 # sanity checks 1067 if aType not in _known_edit_area_types: 1068 _log.error('unknown edit area type: [%s]' % aType) 1069 raise gmExceptions.ConstructorError, 'unknown edit area type: [%s]' % aType 1070 self._type = aType 1071 1072 # init main background panel 1073 cEditArea.__init__(self, parent, id) 1074 1075 self.input_fields = {} 1076 1077 self._postInit() 1078 self.old_data = {} 1079 1080 self._patient = gmPerson.gmCurrentPatient() 1081 self.Show(True)
1082 #---------------------------------------------------------------- 1083 # internal helpers 1084 #---------------------------------------------------------------- 1085 #---------------------------------------------------------------- 1086 # to be obsoleted 1087 #----------------------------------------------------------------
1088 - def __make_prompts(self, prompt_labels):
1089 # prompts live on a panel 1090 prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER) 1091 prompt_pnl.SetBackgroundColour(richards_light_gray) 1092 # make them 1093 gszr = wx.FlexGridSizer (len(prompt_labels)+1, 1, 2, 2) 1094 color = richards_aqua 1095 for prompt in prompt_labels: 1096 label = self.__make_prompt(prompt_pnl, "%s " % prompt, color) 1097 gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT) 1098 color = richards_blue 1099 gszr.RemoveGrowableRow (line-1) 1100 # put sizer on panel 1101 prompt_pnl.SetSizer(gszr) 1102 gszr.Fit(prompt_pnl) 1103 prompt_pnl.SetAutoLayout(True) 1104 1105 # make shadow below prompts in gray 1106 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0) 1107 shadow_below_prompts.SetBackgroundColour(richards_dark_gray) 1108 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL) 1109 szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND) 1110 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND) 1111 1112 # stack prompt panel and shadow vertically 1113 vszr_prompts = wx.BoxSizer(wx.VERTICAL) 1114 vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND) 1115 vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND) 1116 1117 # make shadow to the right of the prompts 1118 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0) 1119 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray) 1120 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL) 1121 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND) 1122 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND) 1123 1124 # stack vertical prompt sizer and shadow horizontally 1125 hszr_prompts = wx.BoxSizer(wx.HORIZONTAL) 1126 hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND) 1127 hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND) 1128 1129 return hszr_prompts
1130 #----------------------------------------------------------------
1131 - def _make_edit_lines(self, parent):
1132 _log.error('programmer forgot to define edit area lines for [%s]' % self._type) 1133 _log.info('child classes of gmEditArea *must* override this function') 1134 return []
1135 #----------------------------------------------------------------
1136 - def __make_editing_area(self):
1137 # make edit fields 1138 fields_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL) 1139 fields_pnl.SetBackgroundColour(wx.Color(222,222,222)) 1140 # rows, cols, hgap, vgap 1141 gszr = wx.GridSizer(len(_prompt_defs[self._type]), 1, 2, 2) 1142 1143 # get lines 1144 lines = self._make_edit_lines(parent = fields_pnl) 1145 1146 self.lines = lines 1147 if len(lines) != len(_prompt_defs[self._type]): 1148 _log.error('#(edit lines) not equal #(prompts) for [%s], something is fishy' % self._type) 1149 for line in lines: 1150 gszr.Add(line, 0, wx.EXPAND | wx.ALIGN_LEFT) 1151 # put them on the panel 1152 fields_pnl.SetSizer(gszr) 1153 gszr.Fit(fields_pnl) 1154 fields_pnl.SetAutoLayout(True) 1155 1156 # make shadow below edit fields in gray 1157 shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0) 1158 shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray) 1159 szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL) 1160 szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND) 1161 szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND) 1162 1163 # stack edit fields and shadow vertically 1164 vszr_edit_fields = wx.BoxSizer(wx.VERTICAL) 1165 vszr_edit_fields.Add(fields_pnl, 92, wx.EXPAND) 1166 vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND) 1167 1168 # make shadow to the right of the edit area 1169 shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0) 1170 shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray) 1171 szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL) 1172 szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND) 1173 szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND) 1174 1175 # stack vertical edit fields sizer and shadow horizontally 1176 hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL) 1177 hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND) 1178 hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND) 1179 1180 return hszr_edit_fields
1181
1182 - def set_old_data( self, map):
1183 self.old_data = map
1184
1185 - def _default_init_fields(self):
1186 #self.dirty = 0 #this flag is for patient_activating event to save any unsaved entries 1187 self.setInputFieldValues( self._get_init_values()) 1188 self.data = None
1189
1190 - def _get_init_values(self):
1191 map = {} 1192 for k in self.input_fields.keys(): 1193 map[k] = '' 1194 return map
1195 1196 #--------------------------------------------------------
1197 - def _init_fields(self):
1198 self._default_init_fields()
1199 1200 # _log.Log(gmLog.lErr, 'programmer forgot to define _init_fields() for [%s]' % self._type) 1201 # _log.Log(gmLog.lInfo, 'child classes of gmEditArea *must* override this function') 1202 # raise AttributeError 1203 #-------------------------------------------------------------------------------------------------------------
1204 - def _updateUI(self):
1205 _log.warning("you may want to override _updateUI for [%s]" % self.__class__.__name__)
1206 1207
1208 - def _postInit(self):
1209 """override for further control setup""" 1210 pass
1211 1212
1213 - def _makeLineSizer(self, widget, weight, spacerWeight):
1214 szr = wx.BoxSizer(wx.HORIZONTAL) 1215 szr.Add( widget, weight, wx.EXPAND) 1216 szr.Add( 0,0, spacerWeight, wx.EXPAND) 1217 return szr
1218
1219 - def _makeCheckBox(self, parent, title):
1220 1221 cb = wx.CheckBox( parent, -1, _(title)) 1222 cb.SetForegroundColour( richards_blue) 1223 return cb
1224 1225 1226
1227 - def _makeExtraColumns(self , parent, lines, weightMap = {} ):
1228 """this is a utlity method to add extra columns""" 1229 #add an extra column if the class has attribute "extraColumns" 1230 if self.__class__.__dict__.has_key("extraColumns"): 1231 for x in self.__class__.extraColumns: 1232 lines = self._addColumn(parent, lines, x, weightMap) 1233 return lines
1234 1235 1236
1237 - def _addColumn(self, parent, lines, extra, weightMap = {}, existingWeight = 5 , extraWeight = 2):
1238 """ 1239 # add ia extra column in the edit area. 1240 # preconditions: 1241 # parent is fields_pnl (weak); 1242 # self.input_fields exists (required); 1243 # ; extra is a list of tuples of format - 1244 # ( key for input_fields, widget label , widget class to instantiate ) 1245 """ 1246 1247 newlines = [] 1248 i = 0 1249 for x in lines: 1250 # adjust weight if line has specific weightings. 1251 if weightMap.has_key( x): 1252 (existingWeight, extraWeight) = weightMap[x] 1253 1254 szr = wx.BoxSizer(wx.HORIZONTAL) 1255 szr.Add( x, existingWeight, wx.EXPAND) 1256 if i < len(extra) and extra[i] <> None: 1257 1258 (inputKey, widgetLabel, aclass) = extra[i] 1259 if aclass.__name__ in CONTROLS_WITHOUT_LABELS: 1260 szr.Add( self._make_prompt(parent, widgetLabel, richards_blue) ) 1261 widgetLabel = "" 1262 1263 1264 w = aclass( parent, -1, widgetLabel) 1265 if not aclass.__name__ in CONTROLS_WITHOUT_LABELS: 1266 w.SetForegroundColour(richards_blue) 1267 1268 szr.Add(w, extraWeight , wx.EXPAND) 1269 1270 # make sure the widget is locatable via input_fields 1271 self.input_fields[inputKey] = w 1272 1273 newlines.append(szr) 1274 i += 1 1275 return newlines
1276
1277 - def setInputFieldValues(self, map, id = None ):
1278 #self.monitoring_dirty = 0 1279 for k,v in map.items(): 1280 field = self.input_fields.get(k, None) 1281 if field == None: 1282 continue 1283 try: 1284 field.SetValue( str(v) ) 1285 except: 1286 try: 1287 if type(v) == type(''): 1288 v = 0 1289 1290 field.SetValue( v) 1291 except: 1292 pass 1293 self.setDataId(id) 1294 #self.monitoring_dirty = 1 1295 self.set_old_data(self.getInputFieldValues())
1296
1297 - def getDataId(self):
1298 return self.data
1299
1300 - def setDataId(self, id):
1301 self.data = id
1302
1303 - def _getInputFieldValues(self):
1304 values = {} 1305 for k,v in self.input_fields.items(): 1306 values[k] = v.GetValue() 1307 return values
1308
1309 - def getInputFieldValues(self, fields = None):
1310 if fields == None: 1311 fields = self.input_fields.keys() 1312 values = {} 1313 for f in fields: 1314 try: 1315 values[f] = self.input_fields[f].GetValue() 1316 except: 1317 pass 1318 return values
1319 #====================================================================
1320 -class gmFamilyHxEditArea(gmEditArea):
1321 - def __init__(self, parent, id):
1322 try: 1323 gmEditArea.__init__(self, parent, id, aType = 'family history') 1324 except gmExceptions.ConstructorError: 1325 _log.exceptions('cannot instantiate family Hx edit area') 1326 raise
1327 #----------------------------------------------------------------
1328 - def _make_edit_lines(self, parent):
1329 _log.debug("making family Hx lines") 1330 lines = [] 1331 self.input_fields = {} 1332 # line 1 1333 # FIXME: put patient search widget here, too ... 1334 # add button "make active patient" 1335 self.input_fields['name'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize) 1336 self.input_fields['DOB'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize) 1337 lbl_dob = self._make_prompt(parent, _(" Date of Birth "), richards_blue) 1338 szr = wx.BoxSizer(wx.HORIZONTAL) 1339 szr.Add(self.input_fields['name'], 4, wx.EXPAND) 1340 szr.Add(lbl_dob, 2, wx.EXPAND) 1341 szr.Add(self.input_fields['DOB'], 4, wx.EXPAND) 1342 lines.append(szr) 1343 # line 2 1344 # FIXME: keep relationship attachments permamently ! (may need to make new patient ...) 1345 # FIXME: learning phrasewheel attached to list loaded from backend 1346 self.input_fields['relationship'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize) 1347 szr = wx.BoxSizer(wx.HORIZONTAL) 1348 szr.Add(self.input_fields['relationship'], 4, wx.EXPAND) 1349 lines.append(szr) 1350 # line 3 1351 self.input_fields['condition'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize) 1352 self.cb_condition_confidential = wx.CheckBox(parent, -1, _("confidental"), wx.DefaultPosition, wx.DefaultSize, wx.NO_BORDER) 1353 szr = wx.BoxSizer(wx.HORIZONTAL) 1354 szr.Add(self.input_fields['condition'], 6, wx.EXPAND) 1355 szr.Add(self.cb_condition_confidential, 0, wx.EXPAND) 1356 lines.append(szr) 1357 # line 4 1358 self.input_fields['comment'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize) 1359 lines.append(self.input_fields['comment']) 1360 # line 5 1361 lbl_onset = self._make_prompt(parent, _(" age onset "), richards_blue) 1362 self.input_fields['age onset'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize) 1363 # FIXME: combo box ... 1364 lbl_caused_death = self._make_prompt(parent, _(" caused death "), richards_blue) 1365 self.input_fields['caused death'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize) 1366 lbl_aod = self._make_prompt(parent, _(" age died "), richards_blue) 1367 self.input_fields['AOD'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize) 1368 szr = wx.BoxSizer(wx.HORIZONTAL) 1369 szr.Add(lbl_onset, 0, wx.EXPAND) 1370 szr.Add(self.input_fields['age onset'], 1,wx.EXPAND) 1371 szr.Add(lbl_caused_death, 0, wx.EXPAND) 1372 szr.Add(self.input_fields['caused death'], 2,wx.EXPAND) 1373 szr.Add(lbl_aod, 0, wx.EXPAND) 1374 szr.Add(self.input_fields['AOD'], 1, wx.EXPAND) 1375 szr.Add(2, 2, 8) 1376 lines.append(szr) 1377 # line 6 1378 self.input_fields['progress notes'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize) 1379 lines.append(self.input_fields['progress notes']) 1380 # line 8 1381 self.Btn_next_condition = wx.Button(parent, -1, _("Next Condition")) 1382 szr = wx.BoxSizer(wx.HORIZONTAL) 1383 szr.AddSpacer(10, 0, 0) 1384 szr.Add(self.Btn_next_condition, 0, wx.EXPAND | wx.ALL, 1) 1385 szr.Add(2, 1, 5) 1386 szr.Add(self._make_standard_buttons(parent), 0, wx.EXPAND) 1387 lines.append(szr) 1388 1389 return lines
1390
1391 - def _save_data(self):
1392 return 1
1393 1394 #====================================================================
1395 -class gmPastHistoryEditArea(gmEditArea):
1396
1397 - def __init__(self, parent, id):
1398 gmEditArea.__init__(self, parent, id, aType = 'past history')
1399
1400 - def _define_prompts(self):
1401 self._add_prompt(line = 1, label = _("When Noted")) 1402 self._add_prompt(line = 2, label = _("Laterality")) 1403 self._add_prompt(line = 3, label = _("Condition")) 1404 self._add_prompt(line = 4, label = _("Notes")) 1405 self._add_prompt(line = 6, label = _("Status")) 1406 self._add_prompt(line = 7, label = _("Progress Note")) 1407 self._add_prompt(line = 8, label = '')
1408 #--------------------------------------------------------
1409 - def _define_fields(self, parent):
1410 # line 1 1411 self.fld_date_noted = gmDateTimeInput.gmDateInput( 1412 parent = parent, 1413 id = -1, 1414 style = wx.SIMPLE_BORDER 1415 ) 1416 self._add_field( 1417 line = 1, 1418 pos = 1, 1419 widget = self.fld_date_noted, 1420 weight = 2 1421 ) 1422 self._add_field( 1423 line = 1, 1424 pos = 2, 1425 widget = cPrompt_edit_area(parent,-1, _("Age")), 1426 weight = 0) 1427 1428 self.fld_age_noted = cEditAreaField(parent) 1429 self._add_field( 1430 line = 1, 1431 pos = 3, 1432 widget = self.fld_age_noted, 1433 weight = 2 1434 ) 1435 1436 # line 2 1437 self.fld_laterality_none= wx.RadioButton(parent, -1, _("N/A")) 1438 self.fld_laterality_left= wx.RadioButton(parent, -1, _("L")) 1439 self.fld_laterality_right= wx.RadioButton(parent, -1, _("R")) 1440 self.fld_laterality_both= wx.RadioButton(parent, -1, _("both")) 1441 self._add_field( 1442 line = 2, 1443 pos = 1, 1444 widget = self.fld_laterality_none, 1445 weight = 0 1446 ) 1447 self._add_field( 1448 line = 2, 1449 pos = 2, 1450 widget = self.fld_laterality_left, 1451 weight = 0 1452 ) 1453 self._add_field( 1454 line = 2, 1455 pos = 3, 1456 widget = self.fld_laterality_right, 1457 weight = 1 1458 ) 1459 self._add_field( 1460 line = 2, 1461 pos = 4, 1462 widget = self.fld_laterality_both, 1463 weight = 1 1464 ) 1465 # line 3 1466 self.fld_condition= cEditAreaField(parent) 1467 self._add_field( 1468 line = 3, 1469 pos = 1, 1470 widget = self.fld_condition, 1471 weight = 6 1472 ) 1473 # line 4 1474 self.fld_notes= cEditAreaField(parent) 1475 self._add_field( 1476 line = 4, 1477 pos = 1, 1478 widget = self.fld_notes, 1479 weight = 6 1480 ) 1481 # line 5 1482 self.fld_significant= wx.CheckBox( 1483 parent, 1484 -1, 1485 _("significant"), 1486 style = wx.NO_BORDER 1487 ) 1488 self.fld_active= wx.CheckBox( 1489 parent, 1490 -1, 1491 _("active"), 1492 style = wx.NO_BORDER 1493 ) 1494 1495 self._add_field( 1496 line = 5, 1497 pos = 1, 1498 widget = self.fld_significant, 1499 weight = 0 1500 ) 1501 self._add_field( 1502 line = 5, 1503 pos = 2, 1504 widget = self.fld_active, 1505 weight = 0 1506 ) 1507 #line 6 1508 self.fld_progress= cEditAreaField(parent) 1509 self._add_field( 1510 line = 6, 1511 pos = 1, 1512 widget = self.fld_progress, 1513 weight = 6 1514 ) 1515 1516 #line 7 1517 self._add_field( 1518 line = 7, 1519 pos = 4, 1520 widget = self._make_standard_buttons(parent), 1521 weight = 2 1522 )
1523 #--------------------------------------------------------
1524 - def _postInit(self):
1525 return 1526 #handling of auto age or year filling. 1527 wx.EVT_KILL_FOCUS( self.fld_age_noted, self._ageKillFocus) 1528 wx.EVT_KILL_FOCUS( self.fld_date_noted, self._yearKillFocus)
1529 #--------------------------------------------------------
1530 - def _ageKillFocus( self, event):
1531 # skip first, else later failure later in block causes widget to be unfocusable 1532 event.Skip() 1533 try : 1534 year = self._getBirthYear() + int(self.fld_age_noted.GetValue().strip() ) 1535 self.fld_date_noted.SetValue( str (year) ) 1536 except: 1537 pass
1538
1539 - def _getBirthYear(self):
1540 try: 1541 birthyear = int(str(self._patient['dob']).split('-')[0]) 1542 except: 1543 # birthyear = time.localtime()[0] 1544 birthyear = 1 1545 1546 return birthyear
1547
1548 - def _yearKillFocus( self, event):
1549 event.Skip() 1550 try: 1551 age = int(self.fld_date_noted.GetValue().strip() ) - self._getBirthYear() 1552 self.fld_age_noted.SetValue( str (age) ) 1553 except: 1554 pass 1555 1556 __init_values = { 1557 "condition": "", 1558 "notes1": "", 1559 "notes2": "", 1560 "age": "", 1561 #"year": str(time.localtime()[0]), 1562 "progress": "", 1563 "active": 1, 1564 "operation": 0, 1565 "confidential": 0, 1566 "significant": 1, 1567 "both": 0, 1568 "left": 0, 1569 "right": 0, 1570 "none" : 1 1571 } 1572
1573 - def _getDefaultAge(self):
1574 try: 1575 #return time.localtime()[0] - self._patient.getBirthYear() 1576 return 1 1577 except: 1578 return 0
1579
1580 - def _get_init_values(self):
1581 values = gmPastHistoryEditArea.__init_values 1582 values["age"] = str( self._getDefaultAge()) 1583 return values
1584
1585 - def _save_data(self):
1586 clinical = self._patient.get_emr().get_past_history() 1587 if self.getDataId() is None: 1588 id = clinical.create_history( self.get_fields_formatting_values() ) 1589 self.setDataId(id) 1590 return 1591 1592 clinical.update_history( self.get_fields_formatting_values(), self.getDataId() )
1593 1594 #====================================================================
1595 -class gmReferralEditArea(gmEditArea):
1596
1597 - def __init__(self, parent, id):
1598 try: 1599 gmEditArea.__init__(self, parent, id, aType = 'referral') 1600 except gmExceptions.ConstructorError: 1601 _log.exception('cannot instantiate referral edit area') 1602 self.data = None # we don't use this in this widget 1603 self.recipient = None
1604
1605 - def _define_prompts(self):
1606 self._add_prompt (line = 1, label = _ ("Specialty")) 1607 self._add_prompt (line = 2, label = _ ("Name")) 1608 self._add_prompt (line = 3, label = _ ("Address")) 1609 self._add_prompt (line = 4, label = _ ("Options")) 1610 self._add_prompt (line = 5, label = _("Text"), weight =6) 1611 self._add_prompt (line = 6, label = "")
1612
1613 - def _define_fields (self, parent):
1614 self.fld_specialty = gmPhraseWheel.cPhraseWheel ( 1615 parent = parent, 1616 id = -1, 1617 style = wx.SIMPLE_BORDER 1618 ) 1619 #_decorate_editarea_field (self.fld_specialty) 1620 self._add_field ( 1621 line = 1, 1622 pos = 1, 1623 widget = self.fld_specialty, 1624 weight = 1 1625 ) 1626 self.fld_name = gmPhraseWheel.cPhraseWheel ( 1627 parent = parent, 1628 id = -1, 1629 style = wx.SIMPLE_BORDER 1630 ) 1631 #_decorate_editarea_field (self.fld_name) 1632 self._add_field ( 1633 line = 2, 1634 pos = 1, 1635 widget = self.fld_name, 1636 weight = 1 1637 ) 1638 self.fld_address = wx.ComboBox (parent, -1, style = wx.CB_READONLY) 1639 #_decorate_editarea_field (self.fld_address) 1640 self._add_field ( 1641 line = 3, 1642 pos = 1, 1643 widget = self.fld_address, 1644 weight = 1 1645 ) 1646 # FIXME: replace with set_callback_on_* 1647 # self.fld_specialty.setDependent (self.fld_name, "occupation") 1648 self.fld_name.add_callback_on_selection(self.setAddresses) 1649 # flags line 1650 self.fld_med = wx.CheckBox (parent, -1, _("Meds"), style=wx.NO_BORDER) 1651 self._add_field ( 1652 line = 4, 1653 pos = 1, 1654 widget = self.fld_med, 1655 weight = 1 1656 ) 1657 self.fld_past = wx.CheckBox (parent, -1, _("Past Hx"), style=wx.NO_BORDER) 1658 self._add_field ( 1659 line = 4, 1660 pos = 4, 1661 widget = self.fld_past, 1662 weight = 1 1663 ) 1664 self.fld_text = wx.TextCtrl (parent, -1, style= wx.TE_MULTILINE) 1665 self._add_field ( 1666 line = 5, 1667 pos = 1, 1668 widget = self.fld_text, 1669 weight = 1) 1670 # final line 1671 self._add_field( 1672 line = 6, 1673 pos = 1, 1674 widget = self._make_standard_buttons(parent), 1675 weight = 1 1676 ) 1677 return 1
1678
1679 - def set_data (self):
1680 """ 1681 Doesn't accept any value as this doesn't make sense for this edit area 1682 """ 1683 self.fld_specialty.SetValue ('') 1684 self.fld_name.SetValue ('') 1685 self.fld_address.Clear () 1686 self.fld_address.SetValue ('') 1687 self.fld_med.SetValue (0) 1688 self.fld_past.SetValue (0) 1689 self.fld_text.SetValue ('') 1690 self.recipient = None
1691
1692 - def setAddresses (self, id):
1693 """ 1694 Set the available addresses for the selected identity 1695 """ 1696 if id is None: 1697 self.recipient = None 1698 self.fld_address.Clear () 1699 self.fld_address.SetValue ('') 1700 else: 1701 self.recipient = gmDemographicRecord.cDemographicRecord_SQL (id) 1702 self.fld_address.Clear () 1703 self.addr = self.recipient.getAddresses ('work') 1704 for i in self.addr: 1705 self.fld_address.Append (_("%(number)s %(street)s, %(urb)s %(postcode)s") % i, ('post', i)) 1706 fax = self.recipient.getCommChannel (gmDemographicRecord.FAX) 1707 email = self.recipient.getCommChannel (gmDemographicRecord.EMAIL) 1708 if fax: 1709 self.fld_address.Append ("%s: %s" % (_("FAX"), fax), ('fax', fax)) 1710 if email: 1711 self.fld_address.Append ("%s: %s" % (_("E-MAIL"), email), ('email', email))
1712
1713 - def _save_new_entry(self):
1714 """ 1715 We are always saving a "new entry" here because data_ID is always None 1716 """ 1717 if not self.recipient: 1718 raise gmExceptions.InvalidInputError(_('must have a recipient')) 1719 if self.fld_address.GetSelection() == -1: 1720 raise gmExceptions.InvalidInputError(_('must select address')) 1721 channel, addr = self.fld_address.GetClientData (self.fld_address.GetSelection()) 1722 text = self.fld_text.GetValue() 1723 flags = {} 1724 flags['meds'] = self.fld_med.GetValue() 1725 flags['pasthx'] = self.fld_past.GetValue() 1726 if not gmReferral.create_referral (self._patient, self.recipient, channel, addr, text, flags): 1727 raise gmExceptions.InvalidInputError('error sending form')
1728 1729 #==================================================================== 1730 #==================================================================== 1731 # unconverted edit areas below 1732 #====================================================================
1733 -class gmPrescriptionEditArea(gmEditArea):
1734 - def __init__(self, parent, id):
1735 try: 1736 gmEditArea.__init__(self, parent, id, aType = 'prescription') 1737 except gmExceptions.ConstructorError: 1738 _log.exceptions('cannot instantiate prescription edit area') 1739 raise
1740 1741 1742 #----------------------------------------------------------------
1743 - def _make_edit_lines(self, parent):
1744 _log.debug("making prescription lines") 1745 lines = [] 1746 self.txt_problem = cEditAreaField(parent) 1747 self.txt_class = cEditAreaField(parent) 1748 self.txt_generic = cEditAreaField(parent) 1749 self.txt_brand = cEditAreaField(parent) 1750 self.txt_strength= cEditAreaField(parent) 1751 self.txt_directions= cEditAreaField(parent) 1752 self.txt_for = cEditAreaField(parent) 1753 self.txt_progress = cEditAreaField(parent) 1754 1755 lines.append(self.txt_problem) 1756 lines.append(self.txt_class) 1757 lines.append(self.txt_generic) 1758 lines.append(self.txt_brand) 1759 lines.append(self.txt_strength) 1760 lines.append(self.txt_directions) 1761 lines.append(self.txt_for) 1762 lines.append(self.txt_progress) 1763 lines.append(self._make_standard_buttons(parent)) 1764 self.input_fields = { 1765 "problem": self.txt_problem, 1766 "class" : self.txt_class, 1767 "generic" : self.txt_generic, 1768 "brand" : self.txt_brand, 1769 "strength": self.txt_strength, 1770 "directions": self.txt_directions, 1771 "for" : self.txt_for, 1772 "progress": self.txt_progress 1773 1774 } 1775 1776 return self._makeExtraColumns( parent, lines)
1777 1778 1779 # This makes gmPrescriptionEditArea more adaptable to different nationalities special requirements. 1780 # ( well, it could be.) 1781 # to change at runtime, do 1782 1783 # gmPrescriptionEditArea.extraColumns = [ one or more columnListInfo ] 1784 1785 # each columnListInfo element describes one column, 1786 # where columnListInfo is a list of 1787 # tuples of [ inputMap name, widget label, widget class to instantiate from] 1788 1789 #gmPrescriptionEditArea.extraColumns = [ basicPrescriptionExtra ] 1790 #gmPrescriptionEditArea.extraColumns = [ auPrescriptionExtra ] 1791 1792
1793 - def _save_data(self):
1794 return 1
1795 1796 #==================================================================== 1797 # old style stuff below 1798 #==================================================================== 1799 #Class which shows a blue bold label left justified 1800 #--------------------------------------------------------------------
1801 -class cPrompt_edit_area(wx.StaticText):
1802 - def __init__(self, parent, id, prompt, aColor = richards_blue):
1803 wx.StaticText.__init__(self, parent, id, prompt, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_LEFT) 1804 self.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, '')) 1805 self.SetForegroundColour(aColor)
1806 #==================================================================== 1807 # create the editorprompts class which expects a dictionary of labels 1808 # passed to it with prompts relevant to the editing area. 1809 # remove the if else from this once the edit area labelling is fixed 1810 #--------------------------------------------------------------------
1811 -class gmPnlEditAreaPrompts(wx.Panel):
1812 - def __init__(self, parent, id, prompt_labels):
1813 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER) 1814 self.SetBackgroundColour(richards_light_gray) 1815 gszr = wx.GridSizer (len(prompt_labels)+1, 1, 2, 2) 1816 color = richards_aqua 1817 for prompt_key in prompt_labels.keys(): 1818 label = cPrompt_edit_area(self, -1, " %s" % prompt_labels[prompt_key], aColor = color) 1819 gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT) 1820 color = richards_blue 1821 self.SetSizer(gszr) 1822 gszr.Fit(self) 1823 self.SetAutoLayout(True)
1824 #==================================================================== 1825 #Class central to gnumed data input 1826 #allows data entry of multiple different types.e.g scripts, 1827 #referrals, measurements, recalls etc 1828 #@TODO : just about everything 1829 #section = calling section eg allergies, script 1830 #----------------------------------------------------------
1831 -class EditTextBoxes(wx.Panel):
1832 - def __init__(self, parent, id, editareaprompts, section):
1833 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize,style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL) 1834 self.SetBackgroundColour(wx.Color(222,222,222)) 1835 self.parent = parent 1836 # rows, cols, hgap, vgap 1837 self.gszr = wx.GridSizer(len(editareaprompts), 1, 2, 2) 1838 1839 if section == gmSECTION_SUMMARY: 1840 pass 1841 elif section == gmSECTION_DEMOGRAPHICS: 1842 pass 1843 elif section == gmSECTION_CLINICALNOTES: 1844 pass 1845 elif section == gmSECTION_FAMILYHISTORY: 1846 pass 1847 elif section == gmSECTION_PASTHISTORY: 1848 pass 1849 # line 1 1850 1851 self.txt_condition = cEditAreaField(self,PHX_CONDITION,wx.DefaultPosition,wx.DefaultSize) 1852 self.rb_sideleft = wxRadioButton(self,PHX_LEFT, _(" (L) "), wx.DefaultPosition,wx.DefaultSize) 1853 self.rb_sideright = wxRadioButton(self, PHX_RIGHT, _("(R)"), wx.DefaultPosition,wx.DefaultSize,wx.SUNKEN_BORDER) 1854 self.rb_sideboth = wxRadioButton(self, PHX_BOTH, _("Both"), wx.DefaultPosition,wx.DefaultSize) 1855 rbsizer = wx.BoxSizer(wx.HORIZONTAL) 1856 rbsizer.Add(self.rb_sideleft,1,wx.EXPAND) 1857 rbsizer.Add(self.rb_sideright,1,wx.EXPAND) 1858 rbsizer.Add(self.rb_sideboth,1,wx.EXPAND) 1859 szr1 = wx.BoxSizer(wx.HORIZONTAL) 1860 szr1.Add(self.txt_condition, 4, wx.EXPAND) 1861 szr1.Add(rbsizer, 3, wx.EXPAND) 1862 # self.sizer_line1.Add(self.rb_sideleft,1,wx.EXPAND|wxALL,2) 1863 # self.sizer_line1.Add(self.rb_sideright,1,wx.EXPAND|wxALL,2) 1864 # self.sizer_line1.Add(self.rb_sideboth,1,wx.EXPAND|wxALL,2) 1865 # line 2 1866 self.txt_notes1 = cEditAreaField(self,PHX_NOTES,wx.DefaultPosition,wx.DefaultSize) 1867 # line 3 1868 self.txt_notes2= cEditAreaField(self,PHX_NOTES2,wx.DefaultPosition,wx.DefaultSize) 1869 # line 4 1870 self.txt_agenoted = cEditAreaField(self, PHX_AGE, wx.DefaultPosition, wx.DefaultSize) 1871 szr4 = wx.BoxSizer(wx.HORIZONTAL) 1872 szr4.Add(self.txt_agenoted, 1, wx.EXPAND) 1873 szr4.Add(5, 0, 5) 1874 # line 5 1875 self.txt_yearnoted = cEditAreaField(self,PHX_YEAR,wx.DefaultPosition,wx.DefaultSize) 1876 szr5 = wx.BoxSizer(wx.HORIZONTAL) 1877 szr5.Add(self.txt_yearnoted, 1, wx.EXPAND) 1878 szr5.Add(5, 0, 5) 1879 # line 6 1880 self.parent.cb_active = wx.CheckBox(self, PHX_ACTIVE, _("Active"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 1881 self.parent.cb_operation = wx.CheckBox(self, PHX_OPERATION, _("Operation"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 1882 self.parent.cb_confidential = wx.CheckBox(self, PHX_CONFIDENTIAL , _("Confidential"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 1883 self.parent.cb_significant = wx.CheckBox(self, PHX_SIGNIFICANT, _("Significant"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 1884 szr6 = wx.BoxSizer(wx.HORIZONTAL) 1885 szr6.Add(self.parent.cb_active, 1, wx.EXPAND) 1886 szr6.Add(self.parent.cb_operation, 1, wx.EXPAND) 1887 szr6.Add(self.parent.cb_confidential, 1, wx.EXPAND) 1888 szr6.Add(self.parent.cb_significant, 1, wx.EXPAND) 1889 # line 7 1890 self.txt_progressnotes = cEditAreaField(self,PHX_PROGRESSNOTES ,wx.DefaultPosition,wx.DefaultSize) 1891 # line 8 1892 szr8 = wx.BoxSizer(wx.HORIZONTAL) 1893 szr8.Add(5, 0, 6) 1894 szr8.Add(self._make_standard_buttons(), 0, wx.EXPAND) 1895 1896 self.gszr.Add(szr1,0,wx.EXPAND) 1897 self.gszr.Add(self.txt_notes1,0,wx.EXPAND) 1898 self.gszr.Add(self.txt_notes2,0,wx.EXPAND) 1899 self.gszr.Add(szr4,0,wx.EXPAND) 1900 self.gszr.Add(szr5,0,wx.EXPAND) 1901 self.gszr.Add(szr6,0,wx.EXPAND) 1902 self.gszr.Add(self.txt_progressnotes,0,wx.EXPAND) 1903 self.gszr.Add(szr8,0,wx.EXPAND) 1904 #self.anylist = wx.ListCtrl(self, -1, wx.DefaultPosition,wx.DefaultSize,wx.LC_REPORT|wx.LC_LIST|wx.SUNKEN_BORDER) 1905 1906 elif section == gmSECTION_SCRIPT: 1907 pass 1908 elif section == gmSECTION_REQUESTS: 1909 pass 1910 elif section == gmSECTION_RECALLS: 1911 pass 1912 else: 1913 pass 1914 1915 self.SetSizer(self.gszr) 1916 self.gszr.Fit(self) 1917 1918 self.SetAutoLayout(True) 1919 self.Show(True)
1920 #----------------------------------------------------------------
1921 - def _make_standard_buttons(self):
1922 self.btn_OK = wx.Button(self, -1, _("Ok")) 1923 self.btn_Clear = wx.Button(self, -1, _("Clear")) 1924 szr_buttons = wx.BoxSizer(wx.HORIZONTAL) 1925 szr_buttons.Add(self.btn_OK, 1, wx.EXPAND, wx.ALL, 1) 1926 szr_buttons.Add(5, 0, 0) 1927 szr_buttons.Add(self.btn_Clear, 1, wx.EXPAND, wx.ALL, 1) 1928 return szr_buttons
1929 #====================================================================
1930 -class EditArea(wx.Panel):
1931 - def __init__(self, parent, id, line_labels, section):
1932 _log.warning('***** old style EditArea instantiated, please convert *****') 1933 1934 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, style = wx.NO_BORDER) 1935 self.SetBackgroundColour(wx.Color(222,222,222)) 1936 1937 # make prompts 1938 prompts = gmPnlEditAreaPrompts(self, -1, line_labels) 1939 # and shadow below prompts in ... 1940 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0) 1941 # ... gray 1942 shadow_below_prompts.SetBackgroundColour(richards_dark_gray) 1943 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL) 1944 szr_shadow_below_prompts.Add(5,0,0,wx.EXPAND) 1945 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND) 1946 # stack prompts and shadow vertically 1947 szr_prompts = wx.BoxSizer(wx.VERTICAL) 1948 szr_prompts.Add(prompts, 97, wx.EXPAND) 1949 szr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND) 1950 1951 # make edit fields 1952 edit_fields = EditTextBoxes(self, -1, line_labels, section) 1953 # make shadow below edit area ... 1954 shadow_below_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0) 1955 # ... gray 1956 shadow_below_editarea.SetBackgroundColour(richards_coloured_gray) 1957 szr_shadow_below_editarea = wx.BoxSizer(wx.HORIZONTAL) 1958 szr_shadow_below_editarea.Add(5,0,0,wx.EXPAND) 1959 szr_shadow_below_editarea.Add(shadow_below_editarea, 12, wx.EXPAND) 1960 # stack edit fields and shadow vertically 1961 szr_editarea = wx.BoxSizer(wx.VERTICAL) 1962 szr_editarea.Add(edit_fields, 92, wx.EXPAND) 1963 szr_editarea.Add(szr_shadow_below_editarea, 5, wx.EXPAND) 1964 1965 # make shadows to the right of ... 1966 # ... the prompts ... 1967 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0) 1968 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray) 1969 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL) 1970 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND) 1971 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND) 1972 # ... and the edit area 1973 shadow_rightof_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0) 1974 shadow_rightof_editarea.SetBackgroundColour(richards_coloured_gray) 1975 szr_shadow_rightof_editarea = wx.BoxSizer(wx.VERTICAL) 1976 szr_shadow_rightof_editarea.Add(0, 5, 0, wx.EXPAND) 1977 szr_shadow_rightof_editarea.Add(shadow_rightof_editarea, 1, wx.EXPAND) 1978 1979 # stack prompts, shadows and fields horizontally 1980 self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL) 1981 self.szr_main_panels.Add(szr_prompts, 10, wx.EXPAND) 1982 self.szr_main_panels.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND) 1983 self.szr_main_panels.Add(5, 0, 0, wx.EXPAND) 1984 self.szr_main_panels.Add(szr_editarea, 89, wx.EXPAND) 1985 self.szr_main_panels.Add(szr_shadow_rightof_editarea, 1, wx.EXPAND) 1986 1987 # use sizer for border around everything plus a little gap 1988 # FIXME: fold into szr_main_panels ? 1989 self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL) 1990 self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5) 1991 self.SetSizer(self.szr_central_container) 1992 self.szr_central_container.Fit(self) 1993 self.SetAutoLayout(True) 1994 self.Show(True)
1995 1996 1997 #==================================================================== 1998 # old stuff still needed for conversion 1999 #-------------------------------------------------------------------- 2000 #==================================================================== 2001 2002 #==================================================================== 2003 2004 # elif section == gmSECTION_SCRIPT: 2005 # gmLog.gmDefLog.Log (gmLog.lData, "in script section now") 2006 # self.text1_prescription_reason = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize) 2007 # self.text2_drug_class = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize) 2008 # self.text3_generic_drug = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize) 2009 # self.text4_brand_drug = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize) 2010 # self.text5_strength = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize) 2011 # self.text6_directions = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize) 2012 # self.text7_for_duration = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize) 2013 # self.text8_prescription_progress_notes = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize) 2014 # self.text9_quantity = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize) 2015 # lbl_veterans = cPrompt_edit_area(self,-1," Veteran ") 2016 # lbl_reg24 = cPrompt_edit_area(self,-1," Reg 24 ") 2017 # lbl_quantity = cPrompt_edit_area(self,-1," Quantity ") 2018 # lbl_repeats = cPrompt_edit_area(self,-1," Repeats ") 2019 # lbl_usualmed = cPrompt_edit_area(self,-1," Usual ") 2020 # self.cb_veteran = wx.CheckBox(self, -1, " Yes ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 2021 # self.cb_reg24 = wx.CheckBox(self, -1, " Yes ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 2022 # self.cb_usualmed = wx.CheckBox(self, -1, " Yes ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 2023 # self.sizer_auth_PI = wx.BoxSizer(wxHORIZONTAL) 2024 # self.btn_authority = wx.Button(self,-1,">Authority") #create authority script 2025 # self.btn_briefPI = wx.Button(self,-1,"Brief PI") #show brief drug product information 2026 # self.sizer_auth_PI.Add(self.btn_authority,1,wx.EXPAND|wxALL,2) #put authority button and PI button 2027 # self.sizer_auth_PI.Add(self.btn_briefPI,1,wx.EXPAND|wxALL,2) #on same sizer 2028 # self.text10_repeats = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize) 2029 # self.sizer_line3.Add(self.text3_generic_drug,5,wx.EXPAND) 2030 # self.sizer_line3.Add(lbl_veterans,1,wx.EXPAND) 2031 # self.sizer_line3.Add(self.cb_veteran,1,wx.EXPAND) 2032 # self.sizer_line4.Add(self.text4_brand_drug,5,wx.EXPAND) 2033 # self.sizer_line4.Add(lbl_reg24,1,wx.EXPAND) 2034 # self.sizer_line4.Add(self.cb_reg24,1,wx.EXPAND) 2035 # self.sizer_line5.Add(self.text5_strength,5,wx.EXPAND) 2036 # self.sizer_line5.Add(lbl_quantity,1,wx.EXPAND) 2037 # self.sizer_line5.Add(self.text9_quantity,1,wx.EXPAND) 2038 # self.sizer_line6.Add(self.text6_directions,5,wx.EXPAND) 2039 # self.sizer_line6.Add(lbl_repeats,1,wx.EXPAND) 2040 # self.sizer_line6.Add(self.text10_repeats,1,wx.EXPAND) 2041 # self.sizer_line7.Add(self.text7_for_duration,5,wx.EXPAND) 2042 # self.sizer_line7.Add(lbl_usualmed,1,wx.EXPAND) 2043 # self.sizer_line7.Add(self.cb_usualmed,1,wx.EXPAND) 2044 # self.sizer_line8.Add(5,0,0) 2045 # self.sizer_line8.Add(self.sizer_auth_PI,2,wx.EXPAND) 2046 # self.sizer_line8.Add(5,0,2) 2047 # self.sizer_line8.Add(self.btn_OK,1,wx.EXPAND|wxALL,2) 2048 # self.sizer_line8.Add(self.btn_Clear,1,wx.EXPAND|wxALL,2) 2049 # self.gszr.Add(self.text1_prescription_reason,1,wx.EXPAND) #prescribe for 2050 # self.gszr.Add(self.text2_drug_class,1,wx.EXPAND) #prescribe by class 2051 # self.gszr.Add(self.sizer_line3,1,wx.EXPAND) #prescribe by generic, lbl_veterans, cb_veteran 2052 # self.gszr.Add(self.sizer_line4,1,wx.EXPAND) #prescribe by brand, lbl_reg24, cb_reg24 2053 # self.gszr.Add(self.sizer_line5,1,wx.EXPAND) #drug strength, lbl_quantity, text_quantity 2054 # self.gszr.Add(self.sizer_line6,1,wx.EXPAND) #txt_directions, lbl_repeats, text_repeats 2055 # self.gszr.Add(self.sizer_line7,1,wx.EXPAND) #text_for,lbl_usual,chk_usual 2056 # self.gszr.Add(self.text8_prescription_progress_notes,1,wx.EXPAND) #text_progressNotes 2057 # self.gszr.Add(self.sizer_line8,1,wx.EXPAND) 2058 2059 2060 # elif section == gmSECTION_REQUESTS: 2061 # #----------------------------------------------------------------------------- 2062 #editing area for general requests e.g pathology, radiology, physiotherapy etc 2063 #create textboxes, radiobuttons etc 2064 #----------------------------------------------------------------------------- 2065 # self.txt_request_type = cEditAreaField(self,ID_REQUEST_TYPE,wx.DefaultPosition,wx.DefaultSize) 2066 # self.txt_request_company = cEditAreaField(self,ID_REQUEST_COMPANY,wx.DefaultPosition,wx.DefaultSize) 2067 # self.txt_request_street = cEditAreaField(self,ID_REQUEST_STREET,wx.DefaultPosition,wx.DefaultSize) 2068 # self.txt_request_suburb = cEditAreaField(self,ID_REQUEST_SUBURB,wx.DefaultPosition,wx.DefaultSize) 2069 # self.txt_request_phone= cEditAreaField(self,ID_REQUEST_PHONE,wx.DefaultPosition,wx.DefaultSize) 2070 # self.txt_request_requests = cEditAreaField(self,ID_REQUEST_REQUESTS,wx.DefaultPosition,wx.DefaultSize) 2071 # self.txt_request_notes = cEditAreaField(self,ID_REQUEST_FORMNOTES,wx.DefaultPosition,wx.DefaultSize) 2072 # self.txt_request_medications = cEditAreaField(self,ID_REQUEST_MEDICATIONS,wx.DefaultPosition,wx.DefaultSize) 2073 # self.txt_request_copyto = cEditAreaField(self,ID_REQUEST_COPYTO,wx.DefaultPosition,wx.DefaultSize) 2074 # self.txt_request_progressnotes = cEditAreaField(self,ID_PROGRESSNOTES,wx.DefaultPosition,wx.DefaultSize) 2075 # self.lbl_companyphone = cPrompt_edit_area(self,-1," Phone ") 2076 # self.cb_includeallmedications = wx.CheckBox(self, -1, " Include all medications ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 2077 # self.rb_request_bill_bb = wxRadioButton(self, ID_REQUEST_BILL_BB, "Bulk Bill ", wx.DefaultPosition,wx.DefaultSize) 2078 # self.rb_request_bill_private = wxRadioButton(self, ID_REQUEST_BILL_PRIVATE, "Private", wx.DefaultPosition,wx.DefaultSize,wx.SUNKEN_BORDER) 2079 # self.rb_request_bill_rebate = wxRadioButton(self, ID_REQUEST_BILL_REBATE, "Rebate", wx.DefaultPosition,wx.DefaultSize) 2080 # self.rb_request_bill_wcover = wxRadioButton(self, ID_REQUEST_BILL_wcover, "w/cover", wx.DefaultPosition,wx.DefaultSize) 2081 #-------------------------------------------------------------- 2082 #add controls to sizers where multiple controls per editor line 2083 #-------------------------------------------------------------- 2084 # self.sizer_request_optionbuttons = wx.BoxSizer(wxHORIZONTAL) 2085 # self.sizer_request_optionbuttons.Add(self.rb_request_bill_bb,1,wx.EXPAND) 2086 # self.sizer_request_optionbuttons.Add(self.rb_request_bill_private ,1,wx.EXPAND) 2087 # self.sizer_request_optionbuttons.Add(self.rb_request_bill_rebate ,1,wx.EXPAND) 2088 # self.sizer_request_optionbuttons.Add(self.rb_request_bill_wcover ,1,wx.EXPAND) 2089 # self.sizer_line4.Add(self.txt_request_suburb,4,wx.EXPAND) 2090 # self.sizer_line4.Add(self.lbl_companyphone,1,wx.EXPAND) 2091 # self.sizer_line4.Add(self.txt_request_phone,2,wx.EXPAND) 2092 # self.sizer_line7.Add(self.txt_request_medications, 4,wx.EXPAND) 2093 # self.sizer_line7.Add(self.cb_includeallmedications,3,wx.EXPAND) 2094 # self.sizer_line10.AddSizer(self.sizer_request_optionbuttons,3,wx.EXPAND) 2095 # self.sizer_line10.AddSizer(self.szr_buttons,1,wx.EXPAND) 2096 #self.sizer_line10.Add(self.btn_OK,1,wx.EXPAND|wxALL,1) 2097 #self.sizer_line10.Add(self.btn_Clear,1,wx.EXPAND|wxALL,1) 2098 #------------------------------------------------------------------ 2099 #add either controls or sizers with controls to vertical grid sizer 2100 #------------------------------------------------------------------ 2101 # self.gszr.Add(self.txt_request_type,0,wx.EXPAND) #e.g Pathology 2102 # self.gszr.Add(self.txt_request_company,0,wx.EXPAND) #e.g Douglas Hanly Moir 2103 # self.gszr.Add(self.txt_request_street,0,wx.EXPAND) #e.g 120 Big Street 2104 # self.gszr.AddSizer(self.sizer_line4,0,wx.EXPAND) #e.g RYDE NSW Phone 02 1800 222 365 2105 # self.gszr.Add(self.txt_request_requests,0,wx.EXPAND) #e.g FBC;ESR;UEC;LFTS 2106 # self.gszr.Add(self.txt_request_notes,0,wx.EXPAND) #e.g generally tired;weight loss; 2107 # self.gszr.AddSizer(self.sizer_line7,0,wx.EXPAND) #e.g Lipitor;losec;zyprexa 2108 # self.gszr.Add(self.txt_request_copyto,0,wx.EXPAND) #e.g Dr I'm All Heart, 120 Big Street Smallville 2109 # self.gszr.Add(self.txt_request_progressnotes,0,wx.EXPAND) #emphasised to patient must return for results 2110 # self.sizer_line8.Add(5,0,6) 2111 # self.sizer_line8.Add(self.btn_OK,1,wx.EXPAND|wxALL,2) 2112 # self.sizer_line8.Add(self.btn_Clear,1,wx.EXPAND|wxALL,2) 2113 # self.gszr.Add(self.sizer_line10,0,wx.EXPAND) #options:b/bill private, rebate,w/cover btnok,btnclear 2114 2115 2116 # elif section == gmSECTION_MEASUREMENTS: 2117 # self.combo_measurement_type = wx.ComboBox(self, ID_MEASUREMENT_TYPE, "", wx.DefaultPosition,wx.DefaultSize, ['Blood pressure','INR','Height','Weight','Whatever other measurement you want to put in here'], wx.CB_DROPDOWN) 2118 # self.combo_measurement_type.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL, wx.BOLD,False,'')) 2119 # self.combo_measurement_type.SetForegroundColour(wx.Color(255,0,0)) 2120 # self.txt_measurement_value = cEditAreaField(self,ID_MEASUREMENT_VALUE,wx.DefaultPosition,wx.DefaultSize) 2121 # self.txt_txt_measurement_date = cEditAreaField(self,ID_MEASUREMENT_DATE,wx.DefaultPosition,wx.DefaultSize) 2122 # self.txt_txt_measurement_comment = cEditAreaField(self,ID_MEASUREMENT_COMMENT,wx.DefaultPosition,wx.DefaultSize) 2123 # self.txt_txt_measurement_progressnote = cEditAreaField(self,ID_PROGRESSNOTES,wx.DefaultPosition,wx.DefaultSize) 2124 # self.sizer_graphnextbtn = wx.BoxSizer(wxHORIZONTAL) 2125 # self.btn_nextvalue = wx.Button(self,ID_MEASUREMENT_NEXTVALUE," Next Value ") #clear fields except type 2126 # self.btn_graph = wx.Button(self,ID_MEASUREMENT_GRAPH," Graph ") #graph all values of this type 2127 # self.sizer_graphnextbtn.Add(self.btn_nextvalue,1,wx.EXPAND|wxALL,2) #put next and graph button 2128 # self.sizer_graphnextbtn.Add(self.btn_graph,1,wx.EXPAND|wxALL,2) #on same sizer 2129 # self.gszr.Add(self.combo_measurement_type,0,wx.EXPAND) #e.g Blood pressure 2130 # self.gszr.Add(self.txt_measurement_value,0,wx.EXPAND) #e.g 120.70 2131 # self.gszr.Add(self.txt_txt_measurement_date,0,wx.EXPAND) #e.g 10/12/2001 2132 # self.gszr.Add(self.txt_txt_measurement_comment,0,wx.EXPAND) #e.g sitting, right arm 2133 # self.gszr.Add(self.txt_txt_measurement_progressnote,0,wx.EXPAND) #e.g given home BP montitor, see 1 week 2134 # self.sizer_line8.Add(5,0,0) 2135 # self.sizer_line8.Add(self.sizer_graphnextbtn,2,wx.EXPAND) 2136 # self.sizer_line8.Add(5,0,2) 2137 # self.sizer_line8.Add(self.btn_OK,1,wx.EXPAND|wxALL,2) 2138 # self.sizer_line8.Add(self.btn_Clear,1,wx.EXPAND|wxALL,2) 2139 # self.gszr.AddSizer(self.sizer_line8,0,wx.EXPAND) 2140 2141 2142 # elif section == gmSECTION_REFERRALS: 2143 # self.btnpreview = wx.Button(self,-1,"Preview") 2144 # self.sizer_btnpreviewok = wx.BoxSizer(wxHORIZONTAL) 2145 #-------------------------------------------------------- 2146 #editing area for referral letters, insurance letters etc 2147 #create textboxes, checkboxes etc 2148 #-------------------------------------------------------- 2149 # self.txt_referralcategory = cEditAreaField(self,ID_REFERRAL_CATEGORY,wx.DefaultPosition,wx.DefaultSize) 2150 # self.txt_referralname = cEditAreaField(self,ID_REFERRAL_NAME,wx.DefaultPosition,wx.DefaultSize) 2151 # self.txt_referralorganisation = cEditAreaField(self,ID_REFERRAL_ORGANISATION,wx.DefaultPosition,wx.DefaultSize) 2152 # self.txt_referralstreet1 = cEditAreaField(self,ID_REFERRAL_STREET1,wx.DefaultPosition,wx.DefaultSize) 2153 # self.txt_referralstreet2 = cEditAreaField(self,ID_REFERRAL_STREET2,wx.DefaultPosition,wx.DefaultSize) 2154 # self.txt_referralstreet3 = cEditAreaField(self,ID_REFERRAL_STREET3,wx.DefaultPosition,wx.DefaultSize) 2155 # self.txt_referralsuburb = cEditAreaField(self,ID_REFERRAL_SUBURB,wx.DefaultPosition,wx.DefaultSize) 2156 # self.txt_referralpostcode = cEditAreaField(self,ID_REFERRAL_POSTCODE,wx.DefaultPosition,wx.DefaultSize) 2157 # self.txt_referralfor = cEditAreaField(self,ID_REFERRAL_FOR,wx.DefaultPosition,wx.DefaultSize) 2158 # self.txt_referralwphone= cEditAreaField(self,ID_REFERRAL_WPHONE,wx.DefaultPosition,wx.DefaultSize) 2159 # self.txt_referralwfax= cEditAreaField(self,ID_REFERRAL_WFAX,wx.DefaultPosition,wx.DefaultSize) 2160 # self.txt_referralwemail= cEditAreaField(self,ID_REFERRAL_WEMAIL,wx.DefaultPosition,wx.DefaultSize) 2161 #self.txt_referralrequests = cEditAreaField(self,ID_REFERRAL_REQUESTS,wx.DefaultPosition,wx.DefaultSize) 2162 #self.txt_referralnotes = cEditAreaField(self,ID_REFERRAL_FORMNOTES,wx.DefaultPosition,wx.DefaultSize) 2163 #self.txt_referralmedications = cEditAreaField(self,ID_REFERRAL_MEDICATIONS,wx.DefaultPosition,wx.DefaultSize) 2164 # self.txt_referralcopyto = cEditAreaField(self,ID_REFERRAL_COPYTO,wx.DefaultPosition,wx.DefaultSize) 2165 # self.txt_referralprogressnotes = cEditAreaField(self,ID_PROGRESSNOTES,wx.DefaultPosition,wx.DefaultSize) 2166 # self.lbl_referralwphone = cPrompt_edit_area(self,-1," W Phone ") 2167 # self.lbl_referralwfax = cPrompt_edit_area(self,-1," W Fax ") 2168 # self.lbl_referralwemail = cPrompt_edit_area(self,-1," W Email ") 2169 # self.lbl_referralpostcode = cPrompt_edit_area(self,-1," Postcode ") 2170 # self.chkbox_referral_usefirstname = wx.CheckBox(self, -1, " Use Firstname ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 2171 # self.chkbox_referral_headoffice = wx.CheckBox(self, -1, " Head Office ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 2172 # self.chkbox_referral_medications = wx.CheckBox(self, -1, " Medications ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 2173 # self.chkbox_referral_socialhistory = wx.CheckBox(self, -1, " Social History ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 2174 # self.chkbox_referral_familyhistory = wx.CheckBox(self, -1, " Family History ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 2175 # self.chkbox_referral_pastproblems = wx.CheckBox(self, -1, " Past Problems ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 2176 # self.chkbox_referral_activeproblems = wx.CheckBox(self, -1, " Active Problems ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 2177 # self.chkbox_referral_habits = wx.CheckBox(self, -1, " Habits ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 2178 #self.chkbox_referral_Includeall = wx.CheckBox(self, -1, " Include all of the above ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER) 2179 #-------------------------------------------------------------- 2180 #add controls to sizers where multiple controls per editor line 2181 #-------------------------------------------------------------- 2182 # self.sizer_line2.Add(self.txt_referralname,2,wx.EXPAND) 2183 # self.sizer_line2.Add(self.chkbox_referral_usefirstname,2,wx.EXPAND) 2184 # self.sizer_line3.Add(self.txt_referralorganisation,2,wx.EXPAND) 2185 # self.sizer_line3.Add(self.chkbox_referral_headoffice,2, wx.EXPAND) 2186 # self.sizer_line4.Add(self.txt_referralstreet1,2,wx.EXPAND) 2187 # self.sizer_line4.Add(self.lbl_referralwphone,1,wx.EXPAND) 2188 # self.sizer_line4.Add(self.txt_referralwphone,1,wx.EXPAND) 2189 # self.sizer_line5.Add(self.txt_referralstreet2,2,wx.EXPAND) 2190 # self.sizer_line5.Add(self.lbl_referralwfax,1,wx.EXPAND) 2191 # self.sizer_line5.Add(self.txt_referralwfax,1,wx.EXPAND) 2192 # self.sizer_line6.Add(self.txt_referralstreet3,2,wx.EXPAND) 2193 # self.sizer_line6.Add(self.lbl_referralwemail,1,wx.EXPAND) 2194 # self.sizer_line6.Add(self.txt_referralwemail,1,wx.EXPAND) 2195 # self.sizer_line7.Add(self.txt_referralsuburb,2,wx.EXPAND) 2196 # self.sizer_line7.Add(self.lbl_referralpostcode,1,wx.EXPAND) 2197 # self.sizer_line7.Add(self.txt_referralpostcode,1,wx.EXPAND) 2198 # self.sizer_line10.Add(self.chkbox_referral_medications,1,wx.EXPAND) 2199 # self.sizer_line10.Add(self.chkbox_referral_socialhistory,1,wx.EXPAND) 2200 # self.sizer_line10.Add(self.chkbox_referral_familyhistory,1,wx.EXPAND) 2201 # self.sizer_line11.Add(self.chkbox_referral_pastproblems ,1,wx.EXPAND) 2202 # self.sizer_line11.Add(self.chkbox_referral_activeproblems ,1,wx.EXPAND) 2203 # self.sizer_line11.Add(self.chkbox_referral_habits ,1,wx.EXPAND) 2204 # self.sizer_btnpreviewok.Add(self.btnpreview,0,wx.EXPAND) 2205 # self.szr_buttons.Add(self.btn_Clear,0, wx.EXPAND) 2206 #------------------------------------------------------------------ 2207 #add either controls or sizers with controls to vertical grid sizer 2208 #------------------------------------------------------------------ 2209 # self.gszr.Add(self.txt_referralcategory,0,wx.EXPAND) #e.g Othopaedic surgeon 2210 # self.gszr.Add(self.sizer_line2,0,wx.EXPAND) #e.g Dr B Breaker 2211 # self.gszr.Add(self.sizer_line3,0,wx.EXPAND) #e.g General Orthopaedic servies 2212 # self.gszr.Add(self.sizer_line4,0,wx.EXPAND) #e.g street1 2213 # self.gszr.Add(self.sizer_line5,0,wx.EXPAND) #e.g street2 2214 # self.gszr.Add(self.sizer_line6,0,wx.EXPAND) #e.g street3 2215 # self.gszr.Add(self.sizer_line7,0,wx.EXPAND) #e.g suburb and postcode 2216 # self.gszr.Add(self.txt_referralfor,0,wx.EXPAND) #e.g Referral for an opinion 2217 # self.gszr.Add(self.txt_referralcopyto,0,wx.EXPAND) #e.g Dr I'm All Heart, 120 Big Street Smallville 2218 # self.gszr.Add(self.txt_referralprogressnotes,0,wx.EXPAND) #emphasised to patient must return for results 2219 # self.gszr.AddSizer(self.sizer_line10,0,wx.EXPAND) #e.g check boxes to include medications etc 2220 # self.gszr.Add(self.sizer_line11,0,wx.EXPAND) #e.g check boxes to include active problems etc 2221 #self.spacer = wxWindow(self,-1,wx.DefaultPosition,wx.DefaultSize) 2222 #self.spacer.SetBackgroundColour(wx.Color(255,255,255)) 2223 # self.sizer_line12.Add(5,0,6) 2224 #self.sizer_line12.Add(self.spacer,6,wx.EXPAND) 2225 # self.sizer_line12.Add(self.btnpreview,1,wx.EXPAND|wxALL,2) 2226 # self.sizer_line12.Add(self.btn_Clear,1,wx.EXPAND|wxALL,2) 2227 # self.gszr.Add(self.sizer_line12,0,wx.EXPAND) #btnpreview and btn clear 2228 2229 2230 # elif section == gmSECTION_RECALLS: 2231 #FIXME remove present options in this combo box #FIXME defaults need to be loaded from database 2232 # self.combo_tosee = wx.ComboBox(self, ID_RECALLS_TOSEE, "", wx.DefaultPosition,wx.DefaultSize, ['Doctor1','Doctor2','Nurse1','Dietition'], wx.CB_READONLY ) #wx.CB_DROPDOWN) 2233 # self.combo_tosee.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL, wx.BOLD,False,'')) 2234 # self.combo_tosee.SetForegroundColour(wx.Color(255,0,0)) 2235 #FIXME defaults need to be loaded from database 2236 # self.combo_recall_method = wx.ComboBox(self, ID_RECALLS_CONTACTMETHOD, "", wx.DefaultPosition,wx.DefaultSize, ['Letter','Telephone','Email','Carrier pigeon'], wx.CB_READONLY ) 2237 # self.combo_recall_method.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL, wx.BOLD,False,'')) 2238 # self.combo_recall_method.SetForegroundColour(wx.Color(255,0,0)) 2239 #FIXME defaults need to be loaded from database 2240 # self.combo_apptlength = wx.ComboBox(self, ID_RECALLS_APPNTLENGTH, "", wx.DefaultPosition,wx.DefaultSize, ['brief','standard','long','prolonged'], wx.CB_READONLY ) 2241 # self.combo_apptlength.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL, wx.BOLD,False,'')) 2242 # self.combo_apptlength.SetForegroundColour(wx.Color(255,0,0)) 2243 # self.txt_recall_for = cEditAreaField(self,ID_RECALLS_TXT_FOR, wx.DefaultPosition,wx.DefaultSize) 2244 # self.txt_recall_due = cEditAreaField(self,ID_RECALLS_TXT_DATEDUE, wx.DefaultPosition,wx.DefaultSize) 2245 # self.txt_recall_addtext = cEditAreaField(self,ID_RECALLS_TXT_ADDTEXT,wx.DefaultPosition,wx.DefaultSize) 2246 # self.txt_recall_include = cEditAreaField(self,ID_RECALLS_TXT_INCLUDEFORMS,wx.DefaultPosition,wx.DefaultSize) 2247 # self.txt_recall_progressnotes = cEditAreaField(self,ID_PROGRESSNOTES,wx.DefaultPosition,wx.DefaultSize) 2248 # self.lbl_recall_consultlength = cPrompt_edit_area(self,-1," Appointment length ") 2249 #sizer_lkine1 has the method of recall and the appointment length 2250 # self.sizer_line1.Add(self.combo_recall_method,1,wx.EXPAND) 2251 # self.sizer_line1.Add(self.lbl_recall_consultlength,1,wx.EXPAND) 2252 # self.sizer_line1.Add(self.combo_apptlength,1,wx.EXPAND) 2253 #Now add the controls to the grid sizer 2254 # self.gszr.Add(self.combo_tosee,1,wx.EXPAND) #list of personel for patient to see 2255 # self.gszr.Add(self.txt_recall_for,1,wx.EXPAND) #the actual recall may be free text or word wheel 2256 # self.gszr.Add(self.txt_recall_due,1,wx.EXPAND) #date of future recall 2257 # self.gszr.Add(self.txt_recall_addtext,1,wx.EXPAND) #added explanation e.g 'come fasting' 2258 # self.gszr.Add(self.txt_recall_include,1,wx.EXPAND) #any forms to be sent out first eg FBC 2259 # self.gszr.AddSizer(self.sizer_line1,1,wx.EXPAND) #the contact method, appointment length 2260 # self.gszr.Add(self.txt_recall_progressnotes,1,wx.EXPAND) #add any progress notes for consultation 2261 # self.sizer_line8.Add(5,0,6) 2262 # self.sizer_line8.Add(self.btn_OK,1,wx.EXPAND|wxALL,2) 2263 # self.sizer_line8.Add(self.btn_Clear,1,wx.EXPAND|wxALL,2) 2264 # self.gszr.Add(self.sizer_line8,1,wx.EXPAND) 2265 # else: 2266 # pass 2267 2268 #==================================================================== 2269 # main 2270 #-------------------------------------------------------------------- 2271 if __name__ == "__main__": 2272 2273 #================================================================
2274 - class cTestEditArea(cEditArea):
2275 - def __init__(self, parent):
2276 cEditArea.__init__(self, parent, -1)
2277 - def _define_prompts(self):
2278 self._add_prompt(line=1, label='line 1') 2279 self._add_prompt(line=2, label='buttons')
2280 - def _define_fields(self, parent):
2281 # line 1 2282 self.fld_substance = cEditAreaField(parent) 2283 self._add_field( 2284 line = 1, 2285 pos = 1, 2286 widget = self.fld_substance, 2287 weight = 1 2288 ) 2289 # line 2 2290 self._add_field( 2291 line = 2, 2292 pos = 1, 2293 widget = self._make_standard_buttons(parent), 2294 weight = 1 2295 )
2296 #================================================================ 2297 app = wxPyWidgetTester(size = (400, 200)) 2298 app.SetWidget(cTestEditArea) 2299 app.MainLoop() 2300 # app = wxPyWidgetTester(size = (400, 200)) 2301 # app.SetWidget(gmFamilyHxEditArea, -1) 2302 # app.MainLoop() 2303 # app = wxPyWidgetTester(size = (400, 200)) 2304 # app.SetWidget(gmPastHistoryEditArea, -1) 2305 # app.MainLoop() 2306 #==================================================================== 2307