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