1
2
3
4 __license__ = 'GPL'
5 __version__ = "$Revision: 1.135 $"
6 __author__ = "R.Terry, K.Hilbert"
7
8
9 import sys
10 import logging
11 import datetime as pydt
12
13
14 import wx
15
16
17 if __name__ == '__main__':
18 sys.path.insert(0, '../../')
19 from Gnumed.pycommon import gmDispatcher
20
21
22 _log = logging.getLogger('gm.ui')
23 _log.info(__version__)
24
25 edit_area_modes = ['new', 'edit', 'new_from_existing']
26
28 """Mixin for edit area panels providing generic functionality.
29
30 **************** start of template ****************
31
32 #====================================================================
33 # Class definition:
34
35 from Gnumed.wxGladeWidgets import wxgXxxEAPnl
36
37 class cXxxEAPnl(wxgXxxEAPnl.wxgXxxEAPnl, gmEditArea.cGenericEditAreaMixin):
38
39 def __init__(self, *args, **kwargs):
40
41 try:
42 data = kwargs['xxx']
43 del kwargs['xxx']
44 except KeyError:
45 data = None
46
47 wxgXxxEAPnl.wxgXxxEAPnl.__init__(self, *args, **kwargs)
48 gmEditArea.cGenericEditAreaMixin.__init__(self)
49
50 # Code using this mixin should set mode and data
51 # after instantiating the class:
52 self.mode = 'new'
53 self.data = data
54 if data is not None:
55 self.mode = 'edit'
56
57 #self.__init_ui()
58 #----------------------------------------------------------------
59 # def __init_ui(self):
60 # # adjust phrasewheels etc
61 #----------------------------------------------------------------
62 # generic Edit Area mixin API
63 #----------------------------------------------------------------
64 def _valid_for_save(self):
65
66 # its best to validate bottom -> top such that the
67 # cursor ends up in the topmost failing field
68
69 # remove when implemented:
70 return False
71
72 validity = True
73
74 if self._TCTRL_xxx.GetValue().strip() == u'':
75 validity = False
76 self.display_tctrl_as_valid(tctrl = self._TCTRL_xxx, valid = False)
77 self._TCTRL_xxx.SetFocus()
78 else:
79 self.display_tctrl_as_valid(tctrl = self._TCTRL_xxx, valid = True)
80
81 if self._PRW_xxx.GetData() is None:
82 validity = False
83 self._PRW_xxx.display_as_valid(False)
84 self._PRW_xxx.SetFocus()
85 else:
86 self._PRW_xxx.display_as_valid(True)
87
88 return validity
89 #----------------------------------------------------------------
90 def _save_as_new(self):
91 # save the data as a new instance
92 data = gmXXXX.create_xxxx()
93
94 data[''] = self._
95 data[''] = self._
96
97 data.save()
98
99 # must be done very late or else the property access
100 # will refresh the display such that later field
101 # access will return empty values
102 self.data = data
103 return False
104 return True
105 #----------------------------------------------------------------
106 def _save_as_update(self):
107 # update self.data and save the changes
108 self.data[''] = self._TCTRL_xxx.GetValue().strip()
109 self.data[''] = self._PRW_xxx.GetData()
110 self.data[''] = self._CHBOX_xxx.GetValue()
111 self.data.save()
112 return True
113 #----------------------------------------------------------------
114 def _refresh_as_new(self):
115 pass
116 #----------------------------------------------------------------
117 def _refresh_as_new_from_existing(self):
118 self._refresh_as_new()
119 #----------------------------------------------------------------
120 def _refresh_from_existing(self):
121 pass
122 #----------------------------------------------------------------
123
124 **************** end of template ****************
125 """
127 self.__mode = 'new'
128 self.__data = None
129 self.successful_save_msg = None
130 self.__tctrl_validity_colors = {
131 True: wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW),
132 False: 'pink'
133 }
134 self._refresh_as_new()
135
138
140 if mode not in edit_area_modes:
141 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
142 if mode == 'edit':
143 if self.__data is None:
144 raise ValueError('[%s] <mode> "edit" needs data value' % self.__class__.__name__)
145
146 prev_mode = self.__mode
147 self.__mode = mode
148 if mode != prev_mode:
149 self.refresh()
150
151 mode = property(_get_mode, _set_mode)
152
155
157 if data is None:
158 if self.__mode == 'edit':
159 raise ValueError('[%s] <mode> "edit" needs data value' % self.__class__.__name__)
160 self.__data = data
161 self.refresh()
162
163 data = property(_get_data, _set_data)
164
166 """Invoked from the generic edit area dialog.
167
168 Invokes
169 _valid_for_save,
170 _save_as_new,
171 _save_as_update
172 on the implementing edit area as needed.
173
174 _save_as_* must set self.__data and return True/False
175 """
176 if not self._valid_for_save():
177 return False
178
179
180 gmDispatcher.send(signal = 'statustext', msg = u'')
181
182 if self.__mode in ['new', 'new_from_existing']:
183 if self._save_as_new():
184 self.mode = 'edit'
185 return True
186 return False
187
188 elif self.__mode == 'edit':
189 return self._save_as_update()
190
191 else:
192 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
193
195 """Invoked from the generic edit area dialog.
196
197 Invokes
198 _refresh_as_new()
199 _refresh_from_existing()
200 _refresh_as_new_from_existing()
201 on the implementing edit area as needed.
202
203 Then calls _valid_for_save().
204 """
205 if self.__mode == 'new':
206 result = self._refresh_as_new()
207 self._valid_for_save()
208 return result
209 elif self.__mode == 'edit':
210 result = self._refresh_from_existing()
211 return result
212 elif self.__mode == 'new_from_existing':
213 result = self._refresh_as_new_from_existing()
214 self._valid_for_save()
215 return result
216 else:
217 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
218
220 tctrl.SetBackgroundColour(self.__tctrl_validity_colors[valid])
221 tctrl.Refresh()
222
224 ctrl.SetBackgroundColour(self.__tctrl_validity_colors[valid])
225 ctrl.Refresh()
226
227 from Gnumed.wxGladeWidgets import wxgGenericEditAreaDlg2
228
230 """Dialog for parenting edit area panels with save/clear/next/cancel"""
231
232 _lucky_day = 1
233 _lucky_month = 4
234 _today = pydt.date.today()
235
237
238 new_ea = kwargs['edit_area']
239 del kwargs['edit_area']
240
241 if not isinstance(new_ea, cGenericEditAreaMixin):
242 raise TypeError('[%s]: edit area instance must be child of cGenericEditAreaMixin')
243
244 try:
245 single_entry = kwargs['single_entry']
246 del kwargs['single_entry']
247 except KeyError:
248 single_entry = False
249
250 wxgGenericEditAreaDlg2.wxgGenericEditAreaDlg2.__init__(self, *args, **kwargs)
251
252 self.left_extra_button = None
253
254 if cGenericEditAreaDlg2._today.day != cGenericEditAreaDlg2._lucky_day:
255 self._BTN_lucky.Enable(False)
256 self._BTN_lucky.Hide()
257 else:
258 if cGenericEditAreaDlg2._today.month != cGenericEditAreaDlg2._lucky_month:
259 self._BTN_lucky.Enable(False)
260 self._BTN_lucky.Hide()
261
262
263 dummy_ea_pnl = self._PNL_ea
264 ea_pnl_szr = dummy_ea_pnl.GetContainingSizer()
265 ea_pnl_parent = dummy_ea_pnl.GetParent()
266 ea_pnl_szr.Remove(dummy_ea_pnl)
267 dummy_ea_pnl.Destroy()
268 del dummy_ea_pnl
269 new_ea_min_size = new_ea.GetMinSize()
270 new_ea.Reparent(ea_pnl_parent)
271 self._PNL_ea = new_ea
272 ea_pnl_szr.Add(self._PNL_ea, 1, wx.EXPAND, 0)
273 ea_pnl_szr.SetMinSize(new_ea_min_size)
274 ea_pnl_szr.Fit(new_ea)
275
276
277 if single_entry:
278 self._BTN_forward.Enable(False)
279 self._BTN_forward.Hide()
280
281 self._adjust_clear_revert_buttons()
282
283
284
285 main_szr = self.GetSizer()
286 main_szr.Fit(self)
287 self.Layout()
288
289
290 self._PNL_ea.refresh()
291
303
310
313
316
331
341
350
351
352
368
369 left_extra_button = property(lambda x:x, _set_left_extra_button)
370
371
372 from Gnumed.wxGladeWidgets import wxgGenericEditAreaDlg
373
375 """Dialog for parenting edit area with save/clear/cancel"""
376
378
379 ea = kwargs['edit_area']
380 del kwargs['edit_area']
381
382 wxgGenericEditAreaDlg.wxgGenericEditAreaDlg.__init__(self, *args, **kwargs)
383
384 szr = self._PNL_ea.GetContainingSizer()
385 szr.Remove(self._PNL_ea)
386 ea.Reparent(self)
387 szr.Add(ea, 1, wx.ALL|wx.EXPAND, 4)
388 self._PNL_ea = ea
389
390 self.Layout()
391 szr = self.GetSizer()
392 szr.Fit(self)
393 self.Refresh()
394
395 self._PNL_ea.refresh()
396
404
407
408
409
410
411
412
413 from Gnumed.pycommon import gmGuiBroker
414
415
416 _gb = gmGuiBroker.GuiBroker()
417
418 gmSECTION_SUMMARY = 1
419 gmSECTION_DEMOGRAPHICS = 2
420 gmSECTION_CLINICALNOTES = 3
421 gmSECTION_FAMILYHISTORY = 4
422 gmSECTION_PASTHISTORY = 5
423 gmSECTION_SCRIPT = 8
424 gmSECTION_REQUESTS = 9
425 gmSECTION_REFERRALS = 11
426 gmSECTION_RECALLS = 12
427
428 richards_blue = wx.Colour(0,0,131)
429 richards_aqua = wx.Colour(0,194,197)
430 richards_dark_gray = wx.Color(131,129,131)
431 richards_light_gray = wx.Color(255,255,255)
432 richards_coloured_gray = wx.Color(131,129,131)
433
434
435 CONTROLS_WITHOUT_LABELS =['wxTextCtrl', 'cEditAreaField', 'wx.SpinCtrl', 'gmPhraseWheel', 'wx.ComboBox']
436
438 widget.SetForegroundColour(wx.Color(255, 0, 0))
439 widget.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
440
453 if not isinstance(edit_area, cEditArea2):
454 raise TypeError('<edit_area> must be of type cEditArea2 but is <%s>' % type(edit_area))
455 wx.Dialog.__init__(self, parent, id, title, pos, size, style, name)
456 self.__wxID_BTN_SAVE = wx.NewId()
457 self.__wxID_BTN_RESET = wx.NewId()
458 self.__editarea = edit_area
459 self.__do_layout()
460 self.__register_events()
461
462
463
466
468 self.__editarea.Reparent(self)
469
470 self.__btn_SAVE = wx.Button(self, self.__wxID_BTN_SAVE, _("Save"))
471 self.__btn_SAVE.SetToolTipString(_('save entry into medical record'))
472 self.__btn_RESET = wx.Button(self, self.__wxID_BTN_RESET, _("Reset"))
473 self.__btn_RESET.SetToolTipString(_('reset entry'))
474 self.__btn_CANCEL = wx.Button(self, wx.ID_CANCEL, _("Cancel"))
475 self.__btn_CANCEL.SetToolTipString(_('discard entry and cancel'))
476
477 szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
478 szr_buttons.Add(self.__btn_SAVE, 1, wx.EXPAND | wx.ALL, 1)
479 szr_buttons.Add(self.__btn_RESET, 1, wx.EXPAND | wx.ALL, 1)
480 szr_buttons.Add(self.__btn_CANCEL, 1, wx.EXPAND | wx.ALL, 1)
481
482 szr_main = wx.BoxSizer(wx.VERTICAL)
483 szr_main.Add(self.__editarea, 1, wx.EXPAND)
484 szr_main.Add(szr_buttons, 0, wx.EXPAND)
485
486 self.SetSizerAndFit(szr_main)
487
488
489
491
492 wx.EVT_BUTTON(self.__btn_SAVE, self.__wxID_BTN_SAVE, self._on_SAVE_btn_pressed)
493 wx.EVT_BUTTON(self.__btn_RESET, self.__wxID_BTN_RESET, self._on_RESET_btn_pressed)
494 wx.EVT_BUTTON(self.__btn_CANCEL, wx.ID_CANCEL, self._on_CANCEL_btn_pressed)
495
496 wx.EVT_CLOSE(self, self._on_CANCEL_btn_pressed)
497
498
499
500
501
502
503 return 1
504
506 if self.__editarea.save_data():
507 self.__editarea.Close()
508 self.EndModal(wx.ID_OK)
509 return
510 short_err = self.__editarea.get_short_error()
511 long_err = self.__editarea.get_long_error()
512 if (short_err is None) and (long_err is None):
513 long_err = _(
514 'Unspecified error saving data in edit area.\n\n'
515 'Programmer forgot to specify proper error\n'
516 'message in [%s].'
517 ) % self.__editarea.__class__.__name__
518 if short_err is not None:
519 gmDispatcher.send(signal = 'statustext', msg = short_err)
520 if long_err is not None:
521 gmGuiHelpers.gm_show_error(long_err, _('saving clinical data'))
522
524 self.__editarea.Close()
525 self.EndModal(wx.ID_CANCEL)
526
529
531 - def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TAB_TRAVERSAL):
532
533 wx.Panel.__init__ (
534 self,
535 parent,
536 id,
537 pos = pos,
538 size = size,
539 style = style | wx.TAB_TRAVERSAL
540 )
541 self.SetBackgroundColour(wx.Color(222,222,222))
542
543 self.data = None
544 self.fields = {}
545 self.prompts = {}
546 self._short_error = None
547 self._long_error = None
548 self._summary = None
549 self._patient = gmPerson.gmCurrentPatient()
550 self.__wxID_BTN_OK = wx.NewId()
551 self.__wxID_BTN_CLEAR = wx.NewId()
552 self.__do_layout()
553 self.__register_events()
554 self.Show()
555
556
557
559 """This needs to be overridden by child classes."""
560 self._long_error = _(
561 'Cannot save data from edit area.\n\n'
562 'Programmer forgot to override method:\n'
563 ' <%s.save_data>'
564 ) % self.__class__.__name__
565 return False
566
568 msg = _(
569 'Cannot reset fields in edit area.\n\n'
570 'Programmer forgot to override method:\n'
571 ' <%s.reset_ui>'
572 ) % self.__class__.__name__
573 gmGuiHelpers.gm_show_error(msg)
574
576 tmp = self._short_error
577 self._short_error = None
578 return tmp
579
581 tmp = self._long_error
582 self._long_error = None
583 return tmp
584
586 return _('<No embed string for [%s]>') % self.__class__.__name__
587
588
589
601
606
607
608
610 self.__deregister_events()
611 event.Skip()
612
614 """Only active if _make_standard_buttons was called in child class."""
615
616 try:
617 event.Skip()
618 if self.data is None:
619 self._save_new_entry()
620 self.reset_ui()
621 else:
622 self._save_modified_entry()
623 self.reset_ui()
624 except gmExceptions.InvalidInputError, err:
625
626
627 gmGuiHelpers.gm_show_error (err, _("Invalid Input"))
628 except:
629 _log.exception( "save data problem in [%s]" % self.__class__.__name__)
630
632 """Only active if _make_standard_buttons was called in child class."""
633
634 self.reset_ui()
635 event.Skip()
636
638 self.__deregister_events()
639
640 if not self._patient.connected:
641 return True
642
643
644
645
646 return True
647 _log.error('[%s] lossage' % self.__class__.__name__)
648 return False
649
651 """Just before new patient becomes active."""
652
653 if not self._patient.connected:
654 return True
655
656
657
658
659 return True
660 _log.error('[%s] lossage' % self.__class__.__name__)
661 return False
662
664 """Just after new patient became active."""
665
666 self.reset_ui()
667
668
669
671
672
673 self._define_prompts()
674 self._define_fields(parent = self)
675 if len(self.fields) != len(self.prompts):
676 _log.error('[%s]: #fields != #prompts' % self.__class__.__name__)
677 return None
678
679
680 szr_main_fgrid = wx.FlexGridSizer(rows = len(self.prompts), cols=2)
681 color = richards_aqua
682 lines = self.prompts.keys()
683 lines.sort()
684 for line in lines:
685
686 label, color, weight = self.prompts[line]
687
688 prompt = wx.StaticText (
689 parent = self,
690 id = -1,
691 label = label,
692 style = wx.ALIGN_CENTRE
693 )
694
695 prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
696 prompt.SetForegroundColour(color)
697 prompt.SetBackgroundColour(richards_light_gray)
698 szr_main_fgrid.Add(prompt, flag=wx.EXPAND | wx.ALIGN_RIGHT)
699
700
701 szr_line = wx.BoxSizer(wx.HORIZONTAL)
702 positions = self.fields[line].keys()
703 positions.sort()
704 for pos in positions:
705 field, weight = self.fields[line][pos]
706
707 szr_line.Add(field, weight, wx.EXPAND)
708 szr_main_fgrid.Add(szr_line, flag=wx.GROW | wx.ALIGN_LEFT)
709
710
711 szr_main_fgrid.AddGrowableCol(1)
712
713
714
715
716
717
718
719 self.SetSizerAndFit(szr_main_fgrid)
720
721
722
723
725 """Child classes override this to define their prompts using _add_prompt()"""
726 _log.error('missing override in [%s]' % self.__class__.__name__)
727
729 """Add a new prompt line.
730
731 To be used from _define_fields in child classes.
732
733 - label, the label text
734 - color
735 - weight, the weight given in sizing the various rows. 0 means the row
736 always has minimum size
737 """
738 self.prompts[line] = (label, color, weight)
739
741 """Defines the fields.
742
743 - override in child classes
744 - mostly uses _add_field()
745 """
746 _log.error('missing override in [%s]' % self.__class__.__name__)
747
748 - def _add_field(self, line=None, pos=None, widget=None, weight=0):
749 if None in (line, pos, widget):
750 _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget))
751 if not self.fields.has_key(line):
752 self.fields[line] = {}
753 self.fields[line][pos] = (widget, weight)
754
772
773
774
775
777 - def __init__ (self, parent, id = -1, pos = wx.DefaultPosition, size=wx.DefaultSize):
778 wx.TextCtrl.__init__(self,parent,id,"",pos, size ,wx.SIMPLE_BORDER)
779 _decorate_editarea_field(self)
780
782 - def __init__(self, parent, id, pos, size, style):
783
784 print "class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__
785
786
787 wx.Panel.__init__(self, parent, id, pos=pos, size=size, style=wx.NO_BORDER | wx.TAB_TRAVERSAL)
788 self.SetBackgroundColour(wx.Color(222,222,222))
789
790 self.data = None
791 self.fields = {}
792 self.prompts = {}
793
794 ID_BTN_OK = wx.NewId()
795 ID_BTN_CLEAR = wx.NewId()
796
797 self.__do_layout()
798
799
800
801
802
803
804 self._patient = gmPerson.gmCurrentPatient()
805 self.__register_events()
806 self.Show(True)
807
808
809
811
812 self._define_prompts()
813 self.fields_pnl = wx.Panel(self, -1, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
814 self._define_fields(parent = self.fields_pnl)
815
816 szr_prompts = self.__generate_prompts()
817 szr_fields = self.__generate_fields()
818
819
820 self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL)
821 self.szr_main_panels.Add(szr_prompts, 11, wx.EXPAND)
822 self.szr_main_panels.Add(5, 0, 0, wx.EXPAND)
823 self.szr_main_panels.Add(szr_fields, 90, wx.EXPAND)
824
825
826
827 self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL)
828 self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5)
829
830
831 self.SetAutoLayout(True)
832 self.SetSizer(self.szr_central_container)
833 self.szr_central_container.Fit(self)
834
836 if len(self.fields) != len(self.prompts):
837 _log.error('[%s]: #fields != #prompts' % self.__class__.__name__)
838 return None
839
840 prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
841 prompt_pnl.SetBackgroundColour(richards_light_gray)
842
843 color = richards_aqua
844 lines = self.prompts.keys()
845 lines.sort()
846 self.prompt_widget = {}
847 for line in lines:
848 label, color, weight = self.prompts[line]
849 self.prompt_widget[line] = self.__make_prompt(prompt_pnl, "%s " % label, color)
850
851 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
852 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
853 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
854 szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND)
855 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
856
857
858 vszr_prompts = wx.BoxSizer(wx.VERTICAL)
859 vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND)
860 vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
861
862
863 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
864 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
865 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
866 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
867 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts, 1, wx.EXPAND)
868
869
870 hszr_prompts = wx.BoxSizer(wx.HORIZONTAL)
871 hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND)
872 hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
873
874 return hszr_prompts
875
877 self.fields_pnl.SetBackgroundColour(wx.Color(222,222,222))
878
879 vszr = wx.BoxSizer(wx.VERTICAL)
880 lines = self.fields.keys()
881 lines.sort()
882 self.field_line_szr = {}
883 for line in lines:
884 self.field_line_szr[line] = wx.BoxSizer(wx.HORIZONTAL)
885 positions = self.fields[line].keys()
886 positions.sort()
887 for pos in positions:
888 field, weight = self.fields[line][pos]
889 self.field_line_szr[line].Add(field, weight, wx.EXPAND)
890 try:
891 vszr.Add(self.field_line_szr[line], self.prompts[line][2], flag = wx.EXPAND)
892 except KeyError:
893 _log.error("Error with line=%s, self.field_line_szr has key:%s; self.prompts has key: %s" % (line, self.field_line_szr.has_key(line), self.prompts.has_key(line) ) )
894
895 self.fields_pnl.SetSizer(vszr)
896 vszr.Fit(self.fields_pnl)
897
898
899 shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
900 shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray)
901 szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
902 szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND)
903 szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND)
904
905
906 vszr_edit_fields = wx.BoxSizer(wx.VERTICAL)
907 vszr_edit_fields.Add(self.fields_pnl, 92, wx.EXPAND)
908 vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND)
909
910
911 shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
912 shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray)
913 szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL)
914 szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND)
915 szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND)
916
917
918 hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
919 hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND)
920 hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND)
921
922 return hszr_edit_fields
923
925
926 prompt = wx.StaticText(
927 parent,
928 -1,
929 aLabel,
930 style = wx.ALIGN_RIGHT
931 )
932 prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
933 prompt.SetForegroundColour(aColor)
934 return prompt
935
936
937
939 """Add a new prompt line.
940
941 To be used from _define_fields in child classes.
942
943 - label, the label text
944 - color
945 - weight, the weight given in sizing the various rows. 0 means the rwo
946 always has minimum size
947 """
948 self.prompts[line] = (label, color, weight)
949
950 - def _add_field(self, line=None, pos=None, widget=None, weight=0):
951 if None in (line, pos, widget):
952 _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget))
953 if not self.fields.has_key(line):
954 self.fields[line] = {}
955 self.fields[line][pos] = (widget, weight)
956
958 """Defines the fields.
959
960 - override in child classes
961 - mostly uses _add_field()
962 """
963 _log.error('missing override in [%s]' % self.__class__.__name__)
964
966 _log.error('missing override in [%s]' % self.__class__.__name__)
967
981
984
986 _log.error('[%s] programmer forgot to define _save_data()' % self.__class__.__name__)
987 _log.info('child classes of cEditArea *must* override this function')
988 return False
989
990
991
993
994 wx.EVT_BUTTON(self.btn_OK, ID_BTN_OK, self._on_OK_btn_pressed)
995 wx.EVT_BUTTON(self.btn_Clear, ID_BTN_CLEAR, self._on_clear_btn_pressed)
996
997 wx.EVT_SIZE (self.fields_pnl, self._on_resize_fields)
998
999
1000 gmDispatcher.connect(signal = u'pre_patient_selection', receiver = self._on_pre_patient_selection)
1001 gmDispatcher.connect(signal = u'application_closing', receiver = self._on_application_closing)
1002 gmDispatcher.connect(signal = u'post_patient_selection', receiver = self.on_post_patient_selection)
1003
1004 return 1
1005
1006
1007
1024
1026
1027 self.set_data()
1028 event.Skip()
1029
1030 - def on_post_patient_selection( self, **kwds):
1031
1032 self.set_data()
1033
1035
1036 if not self._patient.connected:
1037 return True
1038 if self._save_data():
1039 return True
1040 _log.error('[%s] lossage' % self.__class__.__name__)
1041 return False
1042
1044
1045 if not self._patient.connected:
1046 return True
1047 if self._save_data():
1048 return True
1049 _log.error('[%s] lossage' % self.__class__.__name__)
1050 return False
1051
1053 self.fields_pnl.Layout()
1054
1055 for i in self.field_line_szr.keys():
1056
1057 pos = self.field_line_szr[i].GetPosition()
1058
1059 self.prompt_widget[i].SetPosition((0, pos.y))
1060
1062 - def __init__(self, parent, id, aType = None):
1063
1064 print "class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__
1065
1066
1067 if aType not in _known_edit_area_types:
1068 _log.error('unknown edit area type: [%s]' % aType)
1069 raise gmExceptions.ConstructorError, 'unknown edit area type: [%s]' % aType
1070 self._type = aType
1071
1072
1073 cEditArea.__init__(self, parent, id)
1074
1075 self.input_fields = {}
1076
1077 self._postInit()
1078 self.old_data = {}
1079
1080 self._patient = gmPerson.gmCurrentPatient()
1081 self.Show(True)
1082
1083
1084
1085
1086
1087
1089
1090 prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
1091 prompt_pnl.SetBackgroundColour(richards_light_gray)
1092
1093 gszr = wx.FlexGridSizer (len(prompt_labels)+1, 1, 2, 2)
1094 color = richards_aqua
1095 for prompt in prompt_labels:
1096 label = self.__make_prompt(prompt_pnl, "%s " % prompt, color)
1097 gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT)
1098 color = richards_blue
1099 gszr.RemoveGrowableRow (line-1)
1100
1101 prompt_pnl.SetSizer(gszr)
1102 gszr.Fit(prompt_pnl)
1103 prompt_pnl.SetAutoLayout(True)
1104
1105
1106 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1107 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
1108 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
1109 szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND)
1110 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
1111
1112
1113 vszr_prompts = wx.BoxSizer(wx.VERTICAL)
1114 vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND)
1115 vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
1116
1117
1118 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1119 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
1120 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
1121 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
1122 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND)
1123
1124
1125 hszr_prompts = wx.BoxSizer(wx.HORIZONTAL)
1126 hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND)
1127 hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
1128
1129 return hszr_prompts
1130
1132 _log.error('programmer forgot to define edit area lines for [%s]' % self._type)
1133 _log.info('child classes of gmEditArea *must* override this function')
1134 return []
1135
1137
1138 fields_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
1139 fields_pnl.SetBackgroundColour(wx.Color(222,222,222))
1140
1141 gszr = wx.GridSizer(len(_prompt_defs[self._type]), 1, 2, 2)
1142
1143
1144 lines = self._make_edit_lines(parent = fields_pnl)
1145
1146 self.lines = lines
1147 if len(lines) != len(_prompt_defs[self._type]):
1148 _log.error('#(edit lines) not equal #(prompts) for [%s], something is fishy' % self._type)
1149 for line in lines:
1150 gszr.Add(line, 0, wx.EXPAND | wx.ALIGN_LEFT)
1151
1152 fields_pnl.SetSizer(gszr)
1153 gszr.Fit(fields_pnl)
1154 fields_pnl.SetAutoLayout(True)
1155
1156
1157 shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1158 shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray)
1159 szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
1160 szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND)
1161 szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND)
1162
1163
1164 vszr_edit_fields = wx.BoxSizer(wx.VERTICAL)
1165 vszr_edit_fields.Add(fields_pnl, 92, wx.EXPAND)
1166 vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND)
1167
1168
1169 shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1170 shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray)
1171 szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL)
1172 szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND)
1173 szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND)
1174
1175
1176 hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
1177 hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND)
1178 hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND)
1179
1180 return hszr_edit_fields
1181
1184
1189
1191 map = {}
1192 for k in self.input_fields.keys():
1193 map[k] = ''
1194 return map
1195
1196
1198 self._default_init_fields()
1199
1200
1201
1202
1203
1205 _log.warning("you may want to override _updateUI for [%s]" % self.__class__.__name__)
1206
1207
1208 - def _postInit(self):
1209 """override for further control setup"""
1210 pass
1211
1212
1214 szr = wx.BoxSizer(wx.HORIZONTAL)
1215 szr.Add( widget, weight, wx.EXPAND)
1216 szr.Add( 0,0, spacerWeight, wx.EXPAND)
1217 return szr
1218
1220
1221 cb = wx.CheckBox( parent, -1, _(title))
1222 cb.SetForegroundColour( richards_blue)
1223 return cb
1224
1225
1226
1228 """this is a utlity method to add extra columns"""
1229
1230 if self.__class__.__dict__.has_key("extraColumns"):
1231 for x in self.__class__.extraColumns:
1232 lines = self._addColumn(parent, lines, x, weightMap)
1233 return lines
1234
1235
1236
1237 - def _addColumn(self, parent, lines, extra, weightMap = {}, existingWeight = 5 , extraWeight = 2):
1238 """
1239 # add ia extra column in the edit area.
1240 # preconditions:
1241 # parent is fields_pnl (weak);
1242 # self.input_fields exists (required);
1243 # ; extra is a list of tuples of format -
1244 # ( key for input_fields, widget label , widget class to instantiate )
1245 """
1246
1247 newlines = []
1248 i = 0
1249 for x in lines:
1250
1251 if weightMap.has_key( x):
1252 (existingWeight, extraWeight) = weightMap[x]
1253
1254 szr = wx.BoxSizer(wx.HORIZONTAL)
1255 szr.Add( x, existingWeight, wx.EXPAND)
1256 if i < len(extra) and extra[i] <> None:
1257
1258 (inputKey, widgetLabel, aclass) = extra[i]
1259 if aclass.__name__ in CONTROLS_WITHOUT_LABELS:
1260 szr.Add( self._make_prompt(parent, widgetLabel, richards_blue) )
1261 widgetLabel = ""
1262
1263
1264 w = aclass( parent, -1, widgetLabel)
1265 if not aclass.__name__ in CONTROLS_WITHOUT_LABELS:
1266 w.SetForegroundColour(richards_blue)
1267
1268 szr.Add(w, extraWeight , wx.EXPAND)
1269
1270
1271 self.input_fields[inputKey] = w
1272
1273 newlines.append(szr)
1274 i += 1
1275 return newlines
1276
1296
1299
1302
1308
1319
1327
1329 _log.debug("making family Hx lines")
1330 lines = []
1331 self.input_fields = {}
1332
1333
1334
1335 self.input_fields['name'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1336 self.input_fields['DOB'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1337 lbl_dob = self._make_prompt(parent, _(" Date of Birth "), richards_blue)
1338 szr = wx.BoxSizer(wx.HORIZONTAL)
1339 szr.Add(self.input_fields['name'], 4, wx.EXPAND)
1340 szr.Add(lbl_dob, 2, wx.EXPAND)
1341 szr.Add(self.input_fields['DOB'], 4, wx.EXPAND)
1342 lines.append(szr)
1343
1344
1345
1346 self.input_fields['relationship'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1347 szr = wx.BoxSizer(wx.HORIZONTAL)
1348 szr.Add(self.input_fields['relationship'], 4, wx.EXPAND)
1349 lines.append(szr)
1350
1351 self.input_fields['condition'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1352 self.cb_condition_confidential = wx.CheckBox(parent, -1, _("confidental"), wx.DefaultPosition, wx.DefaultSize, wx.NO_BORDER)
1353 szr = wx.BoxSizer(wx.HORIZONTAL)
1354 szr.Add(self.input_fields['condition'], 6, wx.EXPAND)
1355 szr.Add(self.cb_condition_confidential, 0, wx.EXPAND)
1356 lines.append(szr)
1357
1358 self.input_fields['comment'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1359 lines.append(self.input_fields['comment'])
1360
1361 lbl_onset = self._make_prompt(parent, _(" age onset "), richards_blue)
1362 self.input_fields['age onset'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1363
1364 lbl_caused_death = self._make_prompt(parent, _(" caused death "), richards_blue)
1365 self.input_fields['caused death'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1366 lbl_aod = self._make_prompt(parent, _(" age died "), richards_blue)
1367 self.input_fields['AOD'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1368 szr = wx.BoxSizer(wx.HORIZONTAL)
1369 szr.Add(lbl_onset, 0, wx.EXPAND)
1370 szr.Add(self.input_fields['age onset'], 1,wx.EXPAND)
1371 szr.Add(lbl_caused_death, 0, wx.EXPAND)
1372 szr.Add(self.input_fields['caused death'], 2,wx.EXPAND)
1373 szr.Add(lbl_aod, 0, wx.EXPAND)
1374 szr.Add(self.input_fields['AOD'], 1, wx.EXPAND)
1375 szr.Add(2, 2, 8)
1376 lines.append(szr)
1377
1378 self.input_fields['progress notes'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1379 lines.append(self.input_fields['progress notes'])
1380
1381 self.Btn_next_condition = wx.Button(parent, -1, _("Next Condition"))
1382 szr = wx.BoxSizer(wx.HORIZONTAL)
1383 szr.AddSpacer(10, 0, 0)
1384 szr.Add(self.Btn_next_condition, 0, wx.EXPAND | wx.ALL, 1)
1385 szr.Add(2, 1, 5)
1386 szr.Add(self._make_standard_buttons(parent), 0, wx.EXPAND)
1387 lines.append(szr)
1388
1389 return lines
1390
1393
1394
1395 -class gmPastHistoryEditArea(gmEditArea):
1396
1397 - def __init__(self, parent, id):
1398 gmEditArea.__init__(self, parent, id, aType = 'past history')
1399
1400 - def _define_prompts(self):
1401 self._add_prompt(line = 1, label = _("When Noted"))
1402 self._add_prompt(line = 2, label = _("Laterality"))
1403 self._add_prompt(line = 3, label = _("Condition"))
1404 self._add_prompt(line = 4, label = _("Notes"))
1405 self._add_prompt(line = 6, label = _("Status"))
1406 self._add_prompt(line = 7, label = _("Progress Note"))
1407 self._add_prompt(line = 8, label = '')
1408
1409 - def _define_fields(self, parent):
1410
1411 self.fld_date_noted = gmDateTimeInput.gmDateInput(
1412 parent = parent,
1413 id = -1,
1414 style = wx.SIMPLE_BORDER
1415 )
1416 self._add_field(
1417 line = 1,
1418 pos = 1,
1419 widget = self.fld_date_noted,
1420 weight = 2
1421 )
1422 self._add_field(
1423 line = 1,
1424 pos = 2,
1425 widget = cPrompt_edit_area(parent,-1, _("Age")),
1426 weight = 0)
1427
1428 self.fld_age_noted = cEditAreaField(parent)
1429 self._add_field(
1430 line = 1,
1431 pos = 3,
1432 widget = self.fld_age_noted,
1433 weight = 2
1434 )
1435
1436
1437 self.fld_laterality_none= wx.RadioButton(parent, -1, _("N/A"))
1438 self.fld_laterality_left= wx.RadioButton(parent, -1, _("L"))
1439 self.fld_laterality_right= wx.RadioButton(parent, -1, _("R"))
1440 self.fld_laterality_both= wx.RadioButton(parent, -1, _("both"))
1441 self._add_field(
1442 line = 2,
1443 pos = 1,
1444 widget = self.fld_laterality_none,
1445 weight = 0
1446 )
1447 self._add_field(
1448 line = 2,
1449 pos = 2,
1450 widget = self.fld_laterality_left,
1451 weight = 0
1452 )
1453 self._add_field(
1454 line = 2,
1455 pos = 3,
1456 widget = self.fld_laterality_right,
1457 weight = 1
1458 )
1459 self._add_field(
1460 line = 2,
1461 pos = 4,
1462 widget = self.fld_laterality_both,
1463 weight = 1
1464 )
1465
1466 self.fld_condition= cEditAreaField(parent)
1467 self._add_field(
1468 line = 3,
1469 pos = 1,
1470 widget = self.fld_condition,
1471 weight = 6
1472 )
1473
1474 self.fld_notes= cEditAreaField(parent)
1475 self._add_field(
1476 line = 4,
1477 pos = 1,
1478 widget = self.fld_notes,
1479 weight = 6
1480 )
1481
1482 self.fld_significant= wx.CheckBox(
1483 parent,
1484 -1,
1485 _("significant"),
1486 style = wx.NO_BORDER
1487 )
1488 self.fld_active= wx.CheckBox(
1489 parent,
1490 -1,
1491 _("active"),
1492 style = wx.NO_BORDER
1493 )
1494
1495 self._add_field(
1496 line = 5,
1497 pos = 1,
1498 widget = self.fld_significant,
1499 weight = 0
1500 )
1501 self._add_field(
1502 line = 5,
1503 pos = 2,
1504 widget = self.fld_active,
1505 weight = 0
1506 )
1507
1508 self.fld_progress= cEditAreaField(parent)
1509 self._add_field(
1510 line = 6,
1511 pos = 1,
1512 widget = self.fld_progress,
1513 weight = 6
1514 )
1515
1516
1517 self._add_field(
1518 line = 7,
1519 pos = 4,
1520 widget = self._make_standard_buttons(parent),
1521 weight = 2
1522 )
1523
1524 - def _postInit(self):
1525 return
1526
1527 wx.EVT_KILL_FOCUS( self.fld_age_noted, self._ageKillFocus)
1528 wx.EVT_KILL_FOCUS( self.fld_date_noted, self._yearKillFocus)
1529
1530 - def _ageKillFocus( self, event):
1531
1532 event.Skip()
1533 try :
1534 year = self._getBirthYear() + int(self.fld_age_noted.GetValue().strip() )
1535 self.fld_date_noted.SetValue( str (year) )
1536 except:
1537 pass
1538
1539 - def _getBirthYear(self):
1540 try:
1541 birthyear = int(str(self._patient['dob']).split('-')[0])
1542 except:
1543
1544 birthyear = 1
1545
1546 return birthyear
1547
1548 - def _yearKillFocus( self, event):
1549 event.Skip()
1550 try:
1551 age = int(self.fld_date_noted.GetValue().strip() ) - self._getBirthYear()
1552 self.fld_age_noted.SetValue( str (age) )
1553 except:
1554 pass
1555
1556 __init_values = {
1557 "condition": "",
1558 "notes1": "",
1559 "notes2": "",
1560 "age": "",
1561
1562 "progress": "",
1563 "active": 1,
1564 "operation": 0,
1565 "confidential": 0,
1566 "significant": 1,
1567 "both": 0,
1568 "left": 0,
1569 "right": 0,
1570 "none" : 1
1571 }
1572
1573 - def _getDefaultAge(self):
1574 try:
1575
1576 return 1
1577 except:
1578 return 0
1579
1580 - def _get_init_values(self):
1581 values = gmPastHistoryEditArea.__init_values
1582 values["age"] = str( self._getDefaultAge())
1583 return values
1584
1585 - def _save_data(self):
1586 clinical = self._patient.get_emr().get_past_history()
1587 if self.getDataId() is None:
1588 id = clinical.create_history( self.get_fields_formatting_values() )
1589 self.setDataId(id)
1590 return
1591
1592 clinical.update_history( self.get_fields_formatting_values(), self.getDataId() )
1593
1594
1604
1606 self._add_prompt (line = 1, label = _ ("Specialty"))
1607 self._add_prompt (line = 2, label = _ ("Name"))
1608 self._add_prompt (line = 3, label = _ ("Address"))
1609 self._add_prompt (line = 4, label = _ ("Options"))
1610 self._add_prompt (line = 5, label = _("Text"), weight =6)
1611 self._add_prompt (line = 6, label = "")
1612
1614 self.fld_specialty = gmPhraseWheel.cPhraseWheel (
1615 parent = parent,
1616 id = -1,
1617 style = wx.SIMPLE_BORDER
1618 )
1619
1620 self._add_field (
1621 line = 1,
1622 pos = 1,
1623 widget = self.fld_specialty,
1624 weight = 1
1625 )
1626 self.fld_name = gmPhraseWheel.cPhraseWheel (
1627 parent = parent,
1628 id = -1,
1629 style = wx.SIMPLE_BORDER
1630 )
1631
1632 self._add_field (
1633 line = 2,
1634 pos = 1,
1635 widget = self.fld_name,
1636 weight = 1
1637 )
1638 self.fld_address = wx.ComboBox (parent, -1, style = wx.CB_READONLY)
1639
1640 self._add_field (
1641 line = 3,
1642 pos = 1,
1643 widget = self.fld_address,
1644 weight = 1
1645 )
1646
1647
1648 self.fld_name.add_callback_on_selection(self.setAddresses)
1649
1650 self.fld_med = wx.CheckBox (parent, -1, _("Meds"), style=wx.NO_BORDER)
1651 self._add_field (
1652 line = 4,
1653 pos = 1,
1654 widget = self.fld_med,
1655 weight = 1
1656 )
1657 self.fld_past = wx.CheckBox (parent, -1, _("Past Hx"), style=wx.NO_BORDER)
1658 self._add_field (
1659 line = 4,
1660 pos = 4,
1661 widget = self.fld_past,
1662 weight = 1
1663 )
1664 self.fld_text = wx.TextCtrl (parent, -1, style= wx.TE_MULTILINE)
1665 self._add_field (
1666 line = 5,
1667 pos = 1,
1668 widget = self.fld_text,
1669 weight = 1)
1670
1671 self._add_field(
1672 line = 6,
1673 pos = 1,
1674 widget = self._make_standard_buttons(parent),
1675 weight = 1
1676 )
1677 return 1
1678
1680 """
1681 Doesn't accept any value as this doesn't make sense for this edit area
1682 """
1683 self.fld_specialty.SetValue ('')
1684 self.fld_name.SetValue ('')
1685 self.fld_address.Clear ()
1686 self.fld_address.SetValue ('')
1687 self.fld_med.SetValue (0)
1688 self.fld_past.SetValue (0)
1689 self.fld_text.SetValue ('')
1690 self.recipient = None
1691
1693 """
1694 Set the available addresses for the selected identity
1695 """
1696 if id is None:
1697 self.recipient = None
1698 self.fld_address.Clear ()
1699 self.fld_address.SetValue ('')
1700 else:
1701 self.recipient = gmDemographicRecord.cDemographicRecord_SQL (id)
1702 self.fld_address.Clear ()
1703 self.addr = self.recipient.getAddresses ('work')
1704 for i in self.addr:
1705 self.fld_address.Append (_("%(number)s %(street)s, %(urb)s %(postcode)s") % i, ('post', i))
1706 fax = self.recipient.getCommChannel (gmDemographicRecord.FAX)
1707 email = self.recipient.getCommChannel (gmDemographicRecord.EMAIL)
1708 if fax:
1709 self.fld_address.Append ("%s: %s" % (_("FAX"), fax), ('fax', fax))
1710 if email:
1711 self.fld_address.Append ("%s: %s" % (_("E-MAIL"), email), ('email', email))
1712
1713 - def _save_new_entry(self):
1714 """
1715 We are always saving a "new entry" here because data_ID is always None
1716 """
1717 if not self.recipient:
1718 raise gmExceptions.InvalidInputError(_('must have a recipient'))
1719 if self.fld_address.GetSelection() == -1:
1720 raise gmExceptions.InvalidInputError(_('must select address'))
1721 channel, addr = self.fld_address.GetClientData (self.fld_address.GetSelection())
1722 text = self.fld_text.GetValue()
1723 flags = {}
1724 flags['meds'] = self.fld_med.GetValue()
1725 flags['pasthx'] = self.fld_past.GetValue()
1726 if not gmReferral.create_referral (self._patient, self.recipient, channel, addr, text, flags):
1727 raise gmExceptions.InvalidInputError('error sending form')
1728
1729
1730
1731
1732
1740
1741
1742
1744 _log.debug("making prescription lines")
1745 lines = []
1746 self.txt_problem = cEditAreaField(parent)
1747 self.txt_class = cEditAreaField(parent)
1748 self.txt_generic = cEditAreaField(parent)
1749 self.txt_brand = cEditAreaField(parent)
1750 self.txt_strength= cEditAreaField(parent)
1751 self.txt_directions= cEditAreaField(parent)
1752 self.txt_for = cEditAreaField(parent)
1753 self.txt_progress = cEditAreaField(parent)
1754
1755 lines.append(self.txt_problem)
1756 lines.append(self.txt_class)
1757 lines.append(self.txt_generic)
1758 lines.append(self.txt_brand)
1759 lines.append(self.txt_strength)
1760 lines.append(self.txt_directions)
1761 lines.append(self.txt_for)
1762 lines.append(self.txt_progress)
1763 lines.append(self._make_standard_buttons(parent))
1764 self.input_fields = {
1765 "problem": self.txt_problem,
1766 "class" : self.txt_class,
1767 "generic" : self.txt_generic,
1768 "brand" : self.txt_brand,
1769 "strength": self.txt_strength,
1770 "directions": self.txt_directions,
1771 "for" : self.txt_for,
1772 "progress": self.txt_progress
1773
1774 }
1775
1776 return self._makeExtraColumns( parent, lines)
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1795
1796
1797
1798
1799
1800
1803 wx.StaticText.__init__(self, parent, id, prompt, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_LEFT)
1804 self.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
1805 self.SetForegroundColour(aColor)
1806
1807
1808
1809
1810
1812 - def __init__(self, parent, id, prompt_labels):
1813 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
1814 self.SetBackgroundColour(richards_light_gray)
1815 gszr = wx.GridSizer (len(prompt_labels)+1, 1, 2, 2)
1816 color = richards_aqua
1817 for prompt_key in prompt_labels.keys():
1818 label = cPrompt_edit_area(self, -1, " %s" % prompt_labels[prompt_key], aColor = color)
1819 gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT)
1820 color = richards_blue
1821 self.SetSizer(gszr)
1822 gszr.Fit(self)
1823 self.SetAutoLayout(True)
1824
1825
1826
1827
1828
1829
1830
1831 -class EditTextBoxes(wx.Panel):
1832 - def __init__(self, parent, id, editareaprompts, section):
1833 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize,style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
1834 self.SetBackgroundColour(wx.Color(222,222,222))
1835 self.parent = parent
1836
1837 self.gszr = wx.GridSizer(len(editareaprompts), 1, 2, 2)
1838
1839 if section == gmSECTION_SUMMARY:
1840 pass
1841 elif section == gmSECTION_DEMOGRAPHICS:
1842 pass
1843 elif section == gmSECTION_CLINICALNOTES:
1844 pass
1845 elif section == gmSECTION_FAMILYHISTORY:
1846 pass
1847 elif section == gmSECTION_PASTHISTORY:
1848 pass
1849
1850
1851 self.txt_condition = cEditAreaField(self,PHX_CONDITION,wx.DefaultPosition,wx.DefaultSize)
1852 self.rb_sideleft = wxRadioButton(self,PHX_LEFT, _(" (L) "), wx.DefaultPosition,wx.DefaultSize)
1853 self.rb_sideright = wxRadioButton(self, PHX_RIGHT, _("(R)"), wx.DefaultPosition,wx.DefaultSize,wx.SUNKEN_BORDER)
1854 self.rb_sideboth = wxRadioButton(self, PHX_BOTH, _("Both"), wx.DefaultPosition,wx.DefaultSize)
1855 rbsizer = wx.BoxSizer(wx.HORIZONTAL)
1856 rbsizer.Add(self.rb_sideleft,1,wx.EXPAND)
1857 rbsizer.Add(self.rb_sideright,1,wx.EXPAND)
1858 rbsizer.Add(self.rb_sideboth,1,wx.EXPAND)
1859 szr1 = wx.BoxSizer(wx.HORIZONTAL)
1860 szr1.Add(self.txt_condition, 4, wx.EXPAND)
1861 szr1.Add(rbsizer, 3, wx.EXPAND)
1862
1863
1864
1865
1866 self.txt_notes1 = cEditAreaField(self,PHX_NOTES,wx.DefaultPosition,wx.DefaultSize)
1867
1868 self.txt_notes2= cEditAreaField(self,PHX_NOTES2,wx.DefaultPosition,wx.DefaultSize)
1869
1870 self.txt_agenoted = cEditAreaField(self, PHX_AGE, wx.DefaultPosition, wx.DefaultSize)
1871 szr4 = wx.BoxSizer(wx.HORIZONTAL)
1872 szr4.Add(self.txt_agenoted, 1, wx.EXPAND)
1873 szr4.Add(5, 0, 5)
1874
1875 self.txt_yearnoted = cEditAreaField(self,PHX_YEAR,wx.DefaultPosition,wx.DefaultSize)
1876 szr5 = wx.BoxSizer(wx.HORIZONTAL)
1877 szr5.Add(self.txt_yearnoted, 1, wx.EXPAND)
1878 szr5.Add(5, 0, 5)
1879
1880 self.parent.cb_active = wx.CheckBox(self, PHX_ACTIVE, _("Active"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1881 self.parent.cb_operation = wx.CheckBox(self, PHX_OPERATION, _("Operation"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1882 self.parent.cb_confidential = wx.CheckBox(self, PHX_CONFIDENTIAL , _("Confidential"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1883 self.parent.cb_significant = wx.CheckBox(self, PHX_SIGNIFICANT, _("Significant"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1884 szr6 = wx.BoxSizer(wx.HORIZONTAL)
1885 szr6.Add(self.parent.cb_active, 1, wx.EXPAND)
1886 szr6.Add(self.parent.cb_operation, 1, wx.EXPAND)
1887 szr6.Add(self.parent.cb_confidential, 1, wx.EXPAND)
1888 szr6.Add(self.parent.cb_significant, 1, wx.EXPAND)
1889
1890 self.txt_progressnotes = cEditAreaField(self,PHX_PROGRESSNOTES ,wx.DefaultPosition,wx.DefaultSize)
1891
1892 szr8 = wx.BoxSizer(wx.HORIZONTAL)
1893 szr8.Add(5, 0, 6)
1894 szr8.Add(self._make_standard_buttons(), 0, wx.EXPAND)
1895
1896 self.gszr.Add(szr1,0,wx.EXPAND)
1897 self.gszr.Add(self.txt_notes1,0,wx.EXPAND)
1898 self.gszr.Add(self.txt_notes2,0,wx.EXPAND)
1899 self.gszr.Add(szr4,0,wx.EXPAND)
1900 self.gszr.Add(szr5,0,wx.EXPAND)
1901 self.gszr.Add(szr6,0,wx.EXPAND)
1902 self.gszr.Add(self.txt_progressnotes,0,wx.EXPAND)
1903 self.gszr.Add(szr8,0,wx.EXPAND)
1904
1905
1906 elif section == gmSECTION_SCRIPT:
1907 pass
1908 elif section == gmSECTION_REQUESTS:
1909 pass
1910 elif section == gmSECTION_RECALLS:
1911 pass
1912 else:
1913 pass
1914
1915 self.SetSizer(self.gszr)
1916 self.gszr.Fit(self)
1917
1918 self.SetAutoLayout(True)
1919 self.Show(True)
1920
1922 self.btn_OK = wx.Button(self, -1, _("Ok"))
1923 self.btn_Clear = wx.Button(self, -1, _("Clear"))
1924 szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
1925 szr_buttons.Add(self.btn_OK, 1, wx.EXPAND, wx.ALL, 1)
1926 szr_buttons.Add(5, 0, 0)
1927 szr_buttons.Add(self.btn_Clear, 1, wx.EXPAND, wx.ALL, 1)
1928 return szr_buttons
1929
1931 - def __init__(self, parent, id, line_labels, section):
1932 _log.warning('***** old style EditArea instantiated, please convert *****')
1933
1934 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, style = wx.NO_BORDER)
1935 self.SetBackgroundColour(wx.Color(222,222,222))
1936
1937
1938 prompts = gmPnlEditAreaPrompts(self, -1, line_labels)
1939
1940 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1941
1942 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
1943 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
1944 szr_shadow_below_prompts.Add(5,0,0,wx.EXPAND)
1945 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
1946
1947 szr_prompts = wx.BoxSizer(wx.VERTICAL)
1948 szr_prompts.Add(prompts, 97, wx.EXPAND)
1949 szr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
1950
1951
1952 edit_fields = EditTextBoxes(self, -1, line_labels, section)
1953
1954 shadow_below_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1955
1956 shadow_below_editarea.SetBackgroundColour(richards_coloured_gray)
1957 szr_shadow_below_editarea = wx.BoxSizer(wx.HORIZONTAL)
1958 szr_shadow_below_editarea.Add(5,0,0,wx.EXPAND)
1959 szr_shadow_below_editarea.Add(shadow_below_editarea, 12, wx.EXPAND)
1960
1961 szr_editarea = wx.BoxSizer(wx.VERTICAL)
1962 szr_editarea.Add(edit_fields, 92, wx.EXPAND)
1963 szr_editarea.Add(szr_shadow_below_editarea, 5, wx.EXPAND)
1964
1965
1966
1967 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1968 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
1969 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
1970 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
1971 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND)
1972
1973 shadow_rightof_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1974 shadow_rightof_editarea.SetBackgroundColour(richards_coloured_gray)
1975 szr_shadow_rightof_editarea = wx.BoxSizer(wx.VERTICAL)
1976 szr_shadow_rightof_editarea.Add(0, 5, 0, wx.EXPAND)
1977 szr_shadow_rightof_editarea.Add(shadow_rightof_editarea, 1, wx.EXPAND)
1978
1979
1980 self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL)
1981 self.szr_main_panels.Add(szr_prompts, 10, wx.EXPAND)
1982 self.szr_main_panels.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
1983 self.szr_main_panels.Add(5, 0, 0, wx.EXPAND)
1984 self.szr_main_panels.Add(szr_editarea, 89, wx.EXPAND)
1985 self.szr_main_panels.Add(szr_shadow_rightof_editarea, 1, wx.EXPAND)
1986
1987
1988
1989 self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL)
1990 self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5)
1991 self.SetSizer(self.szr_central_container)
1992 self.szr_central_container.Fit(self)
1993 self.SetAutoLayout(True)
1994 self.Show(True)
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271 if __name__ == "__main__":
2272
2273
2278 self._add_prompt(line=1, label='line 1')
2279 self._add_prompt(line=2, label='buttons')
2281
2282 self.fld_substance = cEditAreaField(parent)
2283 self._add_field(
2284 line = 1,
2285 pos = 1,
2286 widget = self.fld_substance,
2287 weight = 1
2288 )
2289
2290 self._add_field(
2291 line = 2,
2292 pos = 1,
2293 widget = self._make_standard_buttons(parent),
2294 weight = 1
2295 )
2296
2297 app = wxPyWidgetTester(size = (400, 200))
2298 app.SetWidget(cTestEditArea)
2299 app.MainLoop()
2300
2301
2302
2303
2304
2305
2306
2307