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