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

Source Code for Module Gnumed.wxpython.gmEditArea

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