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
92 # remove when implemented:
93 return False
94
95 # save the data as a new instance
96 data = gmXXXX.create_xxxx()
97
98 data[''] = self._
99 data[''] = self._
100
101 data.save()
102
103 # must be done very late or else the property access
104 # will refresh the display such that later field
105 # access will return empty values
106 self.data = data
107 return False
108 return True
109 #----------------------------------------------------------------
110 def _save_as_update(self):
111
112 # remove when implemented:
113 return False
114
115 # update self.data and save the changes
116 self.data[''] = self._TCTRL_xxx.GetValue().strip()
117 self.data[''] = self._PRW_xxx.GetData()
118 self.data[''] = self._CHBOX_xxx.GetValue()
119 self.data.save()
120 return True
121 #----------------------------------------------------------------
122 def _refresh_as_new(self):
123 pass
124 #----------------------------------------------------------------
125 def _refresh_as_new_from_existing(self):
126 self._refresh_as_new()
127 #----------------------------------------------------------------
128 def _refresh_from_existing(self):
129 pass
130 #----------------------------------------------------------------
131
132 **************** end of template ****************
133 """
135 self.__mode = 'new'
136 self.__data = None
137 self.successful_save_msg = None
138 self.__tctrl_validity_colors = {
139 True: wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW),
140 False: 'pink'
141 }
142 self._refresh_as_new()
143
146
148 if mode not in edit_area_modes:
149 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
150 if mode == 'edit':
151 if self.__data is None:
152 raise ValueError('[%s] <mode> "edit" needs data value' % self.__class__.__name__)
153
154 prev_mode = self.__mode
155 self.__mode = mode
156 if mode != prev_mode:
157 self.refresh()
158
159 mode = property(_get_mode, _set_mode)
160
163
165 if data is None:
166 if self.__mode == 'edit':
167 raise ValueError('[%s] <mode> "edit" needs data value' % self.__class__.__name__)
168 self.__data = data
169 self.refresh()
170
171 data = property(_get_data, _set_data)
172
174 """Invoked from the generic edit area dialog.
175
176 Invokes
177 _valid_for_save,
178 _save_as_new,
179 _save_as_update
180 on the implementing edit area as needed.
181
182 _save_as_* must set self.__data and return True/False
183 """
184 if not self._valid_for_save():
185 return False
186
187
188 gmDispatcher.send(signal = 'statustext', msg = u'')
189
190 if self.__mode in ['new', 'new_from_existing']:
191 if self._save_as_new():
192 self.mode = 'edit'
193 return True
194 return False
195
196 elif self.__mode == 'edit':
197 return self._save_as_update()
198
199 else:
200 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
201
203 """Invoked from the generic edit area dialog.
204
205 Invokes
206 _refresh_as_new()
207 _refresh_from_existing()
208 _refresh_as_new_from_existing()
209 on the implementing edit area as needed.
210
211 Then calls _valid_for_save().
212 """
213 if self.__mode == 'new':
214 result = self._refresh_as_new()
215 self._valid_for_save()
216 return result
217 elif self.__mode == 'edit':
218 result = self._refresh_from_existing()
219 return result
220 elif self.__mode == 'new_from_existing':
221 result = self._refresh_as_new_from_existing()
222 self._valid_for_save()
223 return result
224 else:
225 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
226
229
231 ctrl.SetBackgroundColour(self.__tctrl_validity_colors[valid])
232 ctrl.Refresh()
233
234 from Gnumed.wxGladeWidgets import wxgGenericEditAreaDlg2
235
237 """Dialog for parenting edit area panels with save/clear/next/cancel"""
238
239 _lucky_day = 1
240 _lucky_month = 4
241 _today = pydt.date.today()
242
244
245 new_ea = kwargs['edit_area']
246 del kwargs['edit_area']
247
248 if not isinstance(new_ea, cGenericEditAreaMixin):
249 raise TypeError('[%s]: edit area instance must be child of cGenericEditAreaMixin')
250
251 try:
252 single_entry = kwargs['single_entry']
253 del kwargs['single_entry']
254 except KeyError:
255 single_entry = False
256
257 wxgGenericEditAreaDlg2.wxgGenericEditAreaDlg2.__init__(self, *args, **kwargs)
258
259 self.left_extra_button = None
260
261 if cGenericEditAreaDlg2._today.day != cGenericEditAreaDlg2._lucky_day:
262 self._BTN_lucky.Enable(False)
263 self._BTN_lucky.Hide()
264 else:
265 if cGenericEditAreaDlg2._today.month != cGenericEditAreaDlg2._lucky_month:
266 self._BTN_lucky.Enable(False)
267 self._BTN_lucky.Hide()
268
269
270 dummy_ea_pnl = self._PNL_ea
271 ea_pnl_szr = dummy_ea_pnl.GetContainingSizer()
272 ea_pnl_parent = dummy_ea_pnl.GetParent()
273 ea_pnl_szr.Remove(dummy_ea_pnl)
274 dummy_ea_pnl.Destroy()
275 del dummy_ea_pnl
276 new_ea_min_size = new_ea.GetMinSize()
277 new_ea.Reparent(ea_pnl_parent)
278 self._PNL_ea = new_ea
279 ea_pnl_szr.Add(self._PNL_ea, 1, wx.EXPAND, 0)
280 ea_pnl_szr.SetMinSize(new_ea_min_size)
281 ea_pnl_szr.Fit(new_ea)
282
283
284 if single_entry:
285 self._BTN_forward.Enable(False)
286 self._BTN_forward.Hide()
287
288 self._adjust_clear_revert_buttons()
289
290
291
292 main_szr = self.GetSizer()
293 main_szr.Fit(self)
294 self.Layout()
295
296
297 self._PNL_ea.refresh()
298
310
317
320
323
338
349
358
359
360
376
377 left_extra_button = property(lambda x:x, _set_left_extra_button)
378
379
380 from Gnumed.wxGladeWidgets import wxgGenericEditAreaDlg
381
383 """Dialog for parenting edit area with save/clear/cancel"""
384
386
387 ea = kwargs['edit_area']
388 del kwargs['edit_area']
389
390 wxgGenericEditAreaDlg.wxgGenericEditAreaDlg.__init__(self, *args, **kwargs)
391
392 szr = self._PNL_ea.GetContainingSizer()
393 szr.Remove(self._PNL_ea)
394 ea.Reparent(self)
395 szr.Add(ea, 1, wx.ALL|wx.EXPAND, 4)
396 self._PNL_ea = ea
397
398 self.Layout()
399 szr = self.GetSizer()
400 szr.Fit(self)
401 self.Refresh()
402
403 self._PNL_ea.refresh()
404
412
415
416
417
418
419
420
421 from Gnumed.pycommon import gmGuiBroker
422
423
424 _gb = gmGuiBroker.GuiBroker()
425
426 gmSECTION_SUMMARY = 1
427 gmSECTION_DEMOGRAPHICS = 2
428 gmSECTION_CLINICALNOTES = 3
429 gmSECTION_FAMILYHISTORY = 4
430 gmSECTION_PASTHISTORY = 5
431 gmSECTION_SCRIPT = 8
432 gmSECTION_REQUESTS = 9
433 gmSECTION_REFERRALS = 11
434 gmSECTION_RECALLS = 12
435
436 richards_blue = wx.Colour(0,0,131)
437 richards_aqua = wx.Colour(0,194,197)
438 richards_dark_gray = wx.Colour(131,129,131)
439 richards_light_gray = wx.Colour(255,255,255)
440 richards_coloured_gray = wx.Colour(131,129,131)
441
442
443 CONTROLS_WITHOUT_LABELS =['wxTextCtrl', 'cEditAreaField', 'wx.SpinCtrl', 'gmPhraseWheel', 'wx.ComboBox']
444
446 widget.SetForegroundColour(wx.Colour(255, 0, 0))
447 widget.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
448
461 if not isinstance(edit_area, cEditArea2):
462 raise TypeError('<edit_area> must be of type cEditArea2 but is <%s>' % type(edit_area))
463 wx.Dialog.__init__(self, parent, id, title, pos, size, style, name)
464 self.__wxID_BTN_SAVE = wx.NewId()
465 self.__wxID_BTN_RESET = wx.NewId()
466 self.__editarea = edit_area
467 self.__do_layout()
468 self.__register_events()
469
470
471
474
476 self.__editarea.Reparent(self)
477
478 self.__btn_SAVE = wx.Button(self, self.__wxID_BTN_SAVE, _("Save"))
479 self.__btn_SAVE.SetToolTipString(_('save entry into medical record'))
480 self.__btn_RESET = wx.Button(self, self.__wxID_BTN_RESET, _("Reset"))
481 self.__btn_RESET.SetToolTipString(_('reset entry'))
482 self.__btn_CANCEL = wx.Button(self, wx.ID_CANCEL, _("Cancel"))
483 self.__btn_CANCEL.SetToolTipString(_('discard entry and cancel'))
484
485 szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
486 szr_buttons.Add(self.__btn_SAVE, 1, wx.EXPAND | wx.ALL, 1)
487 szr_buttons.Add(self.__btn_RESET, 1, wx.EXPAND | wx.ALL, 1)
488 szr_buttons.Add(self.__btn_CANCEL, 1, wx.EXPAND | wx.ALL, 1)
489
490 szr_main = wx.BoxSizer(wx.VERTICAL)
491 szr_main.Add(self.__editarea, 1, wx.EXPAND)
492 szr_main.Add(szr_buttons, 0, wx.EXPAND)
493
494 self.SetSizerAndFit(szr_main)
495
496
497
499
500 wx.EVT_BUTTON(self.__btn_SAVE, self.__wxID_BTN_SAVE, self._on_SAVE_btn_pressed)
501 wx.EVT_BUTTON(self.__btn_RESET, self.__wxID_BTN_RESET, self._on_RESET_btn_pressed)
502 wx.EVT_BUTTON(self.__btn_CANCEL, wx.ID_CANCEL, self._on_CANCEL_btn_pressed)
503
504 wx.EVT_CLOSE(self, self._on_CANCEL_btn_pressed)
505
506
507
508
509
510
511 return 1
512
514 if self.__editarea.save_data():
515 self.__editarea.Close()
516 self.EndModal(wx.ID_OK)
517 return
518 short_err = self.__editarea.get_short_error()
519 long_err = self.__editarea.get_long_error()
520 if (short_err is None) and (long_err is None):
521 long_err = _(
522 'Unspecified error saving data in edit area.\n\n'
523 'Programmer forgot to specify proper error\n'
524 'message in [%s].'
525 ) % self.__editarea.__class__.__name__
526 if short_err is not None:
527 gmDispatcher.send(signal = 'statustext', msg = short_err)
528 if long_err is not None:
529 gmGuiHelpers.gm_show_error(long_err, _('saving clinical data'))
530
532 self.__editarea.Close()
533 self.EndModal(wx.ID_CANCEL)
534
537
539 - def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TAB_TRAVERSAL):
540
541 wx.Panel.__init__ (
542 self,
543 parent,
544 id,
545 pos = pos,
546 size = size,
547 style = style | wx.TAB_TRAVERSAL
548 )
549 self.SetBackgroundColour(wx.Colour(222,222,222))
550
551 self.data = None
552 self.fields = {}
553 self.prompts = {}
554 self._short_error = None
555 self._long_error = None
556 self._summary = None
557 self._patient = gmPerson.gmCurrentPatient()
558 self.__wxID_BTN_OK = wx.NewId()
559 self.__wxID_BTN_CLEAR = wx.NewId()
560 self.__do_layout()
561 self.__register_events()
562 self.Show()
563
564
565
567 """This needs to be overridden by child classes."""
568 self._long_error = _(
569 'Cannot save data from edit area.\n\n'
570 'Programmer forgot to override method:\n'
571 ' <%s.save_data>'
572 ) % self.__class__.__name__
573 return False
574
576 msg = _(
577 'Cannot reset fields in edit area.\n\n'
578 'Programmer forgot to override method:\n'
579 ' <%s.reset_ui>'
580 ) % self.__class__.__name__
581 gmGuiHelpers.gm_show_error(msg)
582
584 tmp = self._short_error
585 self._short_error = None
586 return tmp
587
589 tmp = self._long_error
590 self._long_error = None
591 return tmp
592
594 return _('<No embed string for [%s]>') % self.__class__.__name__
595
596
597
609
614
615
616
618 self.__deregister_events()
619 event.Skip()
620
622 """Only active if _make_standard_buttons was called in child class."""
623
624 try:
625 event.Skip()
626 if self.data is None:
627 self._save_new_entry()
628 self.reset_ui()
629 else:
630 self._save_modified_entry()
631 self.reset_ui()
632 except gmExceptions.InvalidInputError, err:
633
634
635 gmGuiHelpers.gm_show_error (err, _("Invalid Input"))
636 except:
637 _log.exception( "save data problem in [%s]" % self.__class__.__name__)
638
640 """Only active if _make_standard_buttons was called in child class."""
641
642 self.reset_ui()
643 event.Skip()
644
646 self.__deregister_events()
647
648 if not self._patient.connected:
649 return True
650
651
652
653
654 return True
655 _log.error('[%s] lossage' % self.__class__.__name__)
656 return False
657
659 """Just before new patient becomes active."""
660
661 if not self._patient.connected:
662 return True
663
664
665
666
667 return True
668 _log.error('[%s] lossage' % self.__class__.__name__)
669 return False
670
672 """Just after new patient became active."""
673
674 self.reset_ui()
675
676
677
679
680
681 self._define_prompts()
682 self._define_fields(parent = self)
683 if len(self.fields) != len(self.prompts):
684 _log.error('[%s]: #fields != #prompts' % self.__class__.__name__)
685 return None
686
687
688 szr_main_fgrid = wx.FlexGridSizer(rows = len(self.prompts), cols=2)
689 color = richards_aqua
690 lines = self.prompts.keys()
691 lines.sort()
692 for line in lines:
693
694 label, color, weight = self.prompts[line]
695
696 prompt = wx.StaticText (
697 parent = self,
698 id = -1,
699 label = label,
700 style = wx.ALIGN_CENTRE
701 )
702
703 prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
704 prompt.SetForegroundColour(color)
705 prompt.SetBackgroundColour(richards_light_gray)
706 szr_main_fgrid.Add(prompt, flag=wx.EXPAND | wx.ALIGN_RIGHT)
707
708
709 szr_line = wx.BoxSizer(wx.HORIZONTAL)
710 positions = self.fields[line].keys()
711 positions.sort()
712 for pos in positions:
713 field, weight = self.fields[line][pos]
714
715 szr_line.Add(field, weight, wx.EXPAND)
716 szr_main_fgrid.Add(szr_line, flag=wx.GROW | wx.ALIGN_LEFT)
717
718
719 szr_main_fgrid.AddGrowableCol(1)
720
721
722
723
724
725
726
727 self.SetSizerAndFit(szr_main_fgrid)
728
729
730
731
733 """Child classes override this to define their prompts using _add_prompt()"""
734 _log.error('missing override in [%s]' % self.__class__.__name__)
735
737 """Add a new prompt line.
738
739 To be used from _define_fields in child classes.
740
741 - label, the label text
742 - color
743 - weight, the weight given in sizing the various rows. 0 means the row
744 always has minimum size
745 """
746 self.prompts[line] = (label, color, weight)
747
749 """Defines the fields.
750
751 - override in child classes
752 - mostly uses _add_field()
753 """
754 _log.error('missing override in [%s]' % self.__class__.__name__)
755
756 - def _add_field(self, line=None, pos=None, widget=None, weight=0):
757 if None in (line, pos, widget):
758 _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget))
759 if not self.fields.has_key(line):
760 self.fields[line] = {}
761 self.fields[line][pos] = (widget, weight)
762
780
781
782
783
785 - def __init__ (self, parent, id = -1, pos = wx.DefaultPosition, size=wx.DefaultSize):
786 wx.TextCtrl.__init__(self,parent,id,"",pos, size ,wx.SIMPLE_BORDER)
787 _decorate_editarea_field(self)
788
790 - def __init__(self, parent, id, pos, size, style):
791
792 print "class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__
793
794
795 wx.Panel.__init__(self, parent, id, pos=pos, size=size, style=wx.NO_BORDER | wx.TAB_TRAVERSAL)
796 self.SetBackgroundColour(wx.Colour(222,222,222))
797
798 self.data = None
799 self.fields = {}
800 self.prompts = {}
801
802 ID_BTN_OK = wx.NewId()
803 ID_BTN_CLEAR = wx.NewId()
804
805 self.__do_layout()
806
807
808
809
810
811
812 self._patient = gmPerson.gmCurrentPatient()
813 self.__register_events()
814 self.Show(True)
815
816
817
819
820 self._define_prompts()
821 self.fields_pnl = wx.Panel(self, -1, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
822 self._define_fields(parent = self.fields_pnl)
823
824 szr_prompts = self.__generate_prompts()
825 szr_fields = self.__generate_fields()
826
827
828 self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL)
829 self.szr_main_panels.Add(szr_prompts, 11, wx.EXPAND)
830 self.szr_main_panels.Add(5, 0, 0, wx.EXPAND)
831 self.szr_main_panels.Add(szr_fields, 90, wx.EXPAND)
832
833
834
835 self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL)
836 self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5)
837
838
839 self.SetAutoLayout(True)
840 self.SetSizer(self.szr_central_container)
841 self.szr_central_container.Fit(self)
842
844 if len(self.fields) != len(self.prompts):
845 _log.error('[%s]: #fields != #prompts' % self.__class__.__name__)
846 return None
847
848 prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
849 prompt_pnl.SetBackgroundColour(richards_light_gray)
850
851 color = richards_aqua
852 lines = self.prompts.keys()
853 lines.sort()
854 self.prompt_widget = {}
855 for line in lines:
856 label, color, weight = self.prompts[line]
857 self.prompt_widget[line] = self.__make_prompt(prompt_pnl, "%s " % label, color)
858
859 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
860 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
861 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
862 szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND)
863 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
864
865
866 vszr_prompts = wx.BoxSizer(wx.VERTICAL)
867 vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND)
868 vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
869
870
871 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
872 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
873 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
874 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
875 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts, 1, wx.EXPAND)
876
877
878 hszr_prompts = wx.BoxSizer(wx.HORIZONTAL)
879 hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND)
880 hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
881
882 return hszr_prompts
883
885 self.fields_pnl.SetBackgroundColour(wx.Colour(222,222,222))
886
887 vszr = wx.BoxSizer(wx.VERTICAL)
888 lines = self.fields.keys()
889 lines.sort()
890 self.field_line_szr = {}
891 for line in lines:
892 self.field_line_szr[line] = wx.BoxSizer(wx.HORIZONTAL)
893 positions = self.fields[line].keys()
894 positions.sort()
895 for pos in positions:
896 field, weight = self.fields[line][pos]
897 self.field_line_szr[line].Add(field, weight, wx.EXPAND)
898 try:
899 vszr.Add(self.field_line_szr[line], self.prompts[line][2], flag = wx.EXPAND)
900 except KeyError:
901 _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) ) )
902
903 self.fields_pnl.SetSizer(vszr)
904 vszr.Fit(self.fields_pnl)
905
906
907 shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
908 shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray)
909 szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
910 szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND)
911 szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND)
912
913
914 vszr_edit_fields = wx.BoxSizer(wx.VERTICAL)
915 vszr_edit_fields.Add(self.fields_pnl, 92, wx.EXPAND)
916 vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND)
917
918
919 shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
920 shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray)
921 szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL)
922 szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND)
923 szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND)
924
925
926 hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
927 hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND)
928 hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND)
929
930 return hszr_edit_fields
931
933
934 prompt = wx.StaticText(
935 parent,
936 -1,
937 aLabel,
938 style = wx.ALIGN_RIGHT
939 )
940 prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
941 prompt.SetForegroundColour(aColor)
942 return prompt
943
944
945
947 """Add a new prompt line.
948
949 To be used from _define_fields in child classes.
950
951 - label, the label text
952 - color
953 - weight, the weight given in sizing the various rows. 0 means the rwo
954 always has minimum size
955 """
956 self.prompts[line] = (label, color, weight)
957
958 - def _add_field(self, line=None, pos=None, widget=None, weight=0):
959 if None in (line, pos, widget):
960 _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget))
961 if not self.fields.has_key(line):
962 self.fields[line] = {}
963 self.fields[line][pos] = (widget, weight)
964
966 """Defines the fields.
967
968 - override in child classes
969 - mostly uses _add_field()
970 """
971 _log.error('missing override in [%s]' % self.__class__.__name__)
972
974 _log.error('missing override in [%s]' % self.__class__.__name__)
975
989
992
994 _log.error('[%s] programmer forgot to define _save_data()' % self.__class__.__name__)
995 _log.info('child classes of cEditArea *must* override this function')
996 return False
997
998
999
1001
1002 wx.EVT_BUTTON(self.btn_OK, ID_BTN_OK, self._on_OK_btn_pressed)
1003 wx.EVT_BUTTON(self.btn_Clear, ID_BTN_CLEAR, self._on_clear_btn_pressed)
1004
1005 wx.EVT_SIZE (self.fields_pnl, self._on_resize_fields)
1006
1007
1008 gmDispatcher.connect(signal = u'pre_patient_selection', receiver = self._on_pre_patient_selection)
1009 gmDispatcher.connect(signal = u'application_closing', receiver = self._on_application_closing)
1010 gmDispatcher.connect(signal = u'post_patient_selection', receiver = self.on_post_patient_selection)
1011
1012 return 1
1013
1014
1015
1032
1034
1035 self.set_data()
1036 event.Skip()
1037
1038 - def on_post_patient_selection( self, **kwds):
1039
1040 self.set_data()
1041
1043
1044 if not self._patient.connected:
1045 return True
1046 if self._save_data():
1047 return True
1048 _log.error('[%s] lossage' % self.__class__.__name__)
1049 return False
1050
1052
1053 if not self._patient.connected:
1054 return True
1055 if self._save_data():
1056 return True
1057 _log.error('[%s] lossage' % self.__class__.__name__)
1058 return False
1059
1061 self.fields_pnl.Layout()
1062
1063 for i in self.field_line_szr.keys():
1064
1065 pos = self.field_line_szr[i].GetPosition()
1066
1067 self.prompt_widget[i].SetPosition((0, pos.y))
1068
1070 - def __init__(self, parent, id, aType = None):
1071
1072 print "class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__
1073
1074
1075 if aType not in _known_edit_area_types:
1076 _log.error('unknown edit area type: [%s]' % aType)
1077 raise gmExceptions.ConstructorError, 'unknown edit area type: [%s]' % aType
1078 self._type = aType
1079
1080
1081 cEditArea.__init__(self, parent, id)
1082
1083 self.input_fields = {}
1084
1085 self._postInit()
1086 self.old_data = {}
1087
1088 self._patient = gmPerson.gmCurrentPatient()
1089 self.Show(True)
1090
1091
1092
1093
1094
1095
1097
1098 prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
1099 prompt_pnl.SetBackgroundColour(richards_light_gray)
1100
1101 gszr = wx.FlexGridSizer (len(prompt_labels)+1, 1, 2, 2)
1102 color = richards_aqua
1103 for prompt in prompt_labels:
1104 label = self.__make_prompt(prompt_pnl, "%s " % prompt, color)
1105 gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT)
1106 color = richards_blue
1107 gszr.RemoveGrowableRow (line-1)
1108
1109 prompt_pnl.SetSizer(gszr)
1110 gszr.Fit(prompt_pnl)
1111 prompt_pnl.SetAutoLayout(True)
1112
1113
1114 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1115 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
1116 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
1117 szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND)
1118 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
1119
1120
1121 vszr_prompts = wx.BoxSizer(wx.VERTICAL)
1122 vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND)
1123 vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
1124
1125
1126 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1127 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
1128 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
1129 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
1130 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND)
1131
1132
1133 hszr_prompts = wx.BoxSizer(wx.HORIZONTAL)
1134 hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND)
1135 hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
1136
1137 return hszr_prompts
1138
1140 _log.error('programmer forgot to define edit area lines for [%s]' % self._type)
1141 _log.info('child classes of gmEditArea *must* override this function')
1142 return []
1143
1145
1146 fields_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
1147 fields_pnl.SetBackgroundColour(wx.Colour(222,222,222))
1148
1149 gszr = wx.GridSizer(len(_prompt_defs[self._type]), 1, 2, 2)
1150
1151
1152 lines = self._make_edit_lines(parent = fields_pnl)
1153
1154 self.lines = lines
1155 if len(lines) != len(_prompt_defs[self._type]):
1156 _log.error('#(edit lines) not equal #(prompts) for [%s], something is fishy' % self._type)
1157 for line in lines:
1158 gszr.Add(line, 0, wx.EXPAND | wx.ALIGN_LEFT)
1159
1160 fields_pnl.SetSizer(gszr)
1161 gszr.Fit(fields_pnl)
1162 fields_pnl.SetAutoLayout(True)
1163
1164
1165 shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1166 shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray)
1167 szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
1168 szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND)
1169 szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND)
1170
1171
1172 vszr_edit_fields = wx.BoxSizer(wx.VERTICAL)
1173 vszr_edit_fields.Add(fields_pnl, 92, wx.EXPAND)
1174 vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND)
1175
1176
1177 shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1178 shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray)
1179 szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL)
1180 szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND)
1181 szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND)
1182
1183
1184 hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
1185 hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND)
1186 hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND)
1187
1188 return hszr_edit_fields
1189
1192
1197
1199 map = {}
1200 for k in self.input_fields.keys():
1201 map[k] = ''
1202 return map
1203
1204
1206 self._default_init_fields()
1207
1208
1209
1210
1211
1213 _log.warning("you may want to override _updateUI for [%s]" % self.__class__.__name__)
1214
1215
1216 - def _postInit(self):
1217 """override for further control setup"""
1218 pass
1219
1220
1222 szr = wx.BoxSizer(wx.HORIZONTAL)
1223 szr.Add( widget, weight, wx.EXPAND)
1224 szr.Add( 0,0, spacerWeight, wx.EXPAND)
1225 return szr
1226
1228
1229 cb = wx.CheckBox( parent, -1, _(title))
1230 cb.SetForegroundColour( richards_blue)
1231 return cb
1232
1233
1234
1236 """this is a utlity method to add extra columns"""
1237
1238 if self.__class__.__dict__.has_key("extraColumns"):
1239 for x in self.__class__.extraColumns:
1240 lines = self._addColumn(parent, lines, x, weightMap)
1241 return lines
1242
1243
1244
1245 - def _addColumn(self, parent, lines, extra, weightMap = {}, existingWeight = 5 , extraWeight = 2):
1246 """
1247 # add ia extra column in the edit area.
1248 # preconditions:
1249 # parent is fields_pnl (weak);
1250 # self.input_fields exists (required);
1251 # ; extra is a list of tuples of format -
1252 # ( key for input_fields, widget label , widget class to instantiate )
1253 """
1254
1255 newlines = []
1256 i = 0
1257 for x in lines:
1258
1259 if weightMap.has_key( x):
1260 (existingWeight, extraWeight) = weightMap[x]
1261
1262 szr = wx.BoxSizer(wx.HORIZONTAL)
1263 szr.Add( x, existingWeight, wx.EXPAND)
1264 if i < len(extra) and extra[i] <> None:
1265
1266 (inputKey, widgetLabel, aclass) = extra[i]
1267 if aclass.__name__ in CONTROLS_WITHOUT_LABELS:
1268 szr.Add( self._make_prompt(parent, widgetLabel, richards_blue) )
1269 widgetLabel = ""
1270
1271
1272 w = aclass( parent, -1, widgetLabel)
1273 if not aclass.__name__ in CONTROLS_WITHOUT_LABELS:
1274 w.SetForegroundColour(richards_blue)
1275
1276 szr.Add(w, extraWeight , wx.EXPAND)
1277
1278
1279 self.input_fields[inputKey] = w
1280
1281 newlines.append(szr)
1282 i += 1
1283 return newlines
1284
1304
1307
1310
1316
1327
1328 -class gmPastHistoryEditArea(gmEditArea):
1329
1330 - def __init__(self, parent, id):
1331 gmEditArea.__init__(self, parent, id, aType = 'past history')
1332
1333 - def _define_prompts(self):
1334 self._add_prompt(line = 1, label = _("When Noted"))
1335 self._add_prompt(line = 2, label = _("Laterality"))
1336 self._add_prompt(line = 3, label = _("Condition"))
1337 self._add_prompt(line = 4, label = _("Notes"))
1338 self._add_prompt(line = 6, label = _("Status"))
1339 self._add_prompt(line = 7, label = _("Progress Note"))
1340 self._add_prompt(line = 8, label = '')
1341
1342 - def _define_fields(self, parent):
1343
1344 self.fld_date_noted = gmDateTimeInput.gmDateInput(
1345 parent = parent,
1346 id = -1,
1347 style = wx.SIMPLE_BORDER
1348 )
1349 self._add_field(
1350 line = 1,
1351 pos = 1,
1352 widget = self.fld_date_noted,
1353 weight = 2
1354 )
1355 self._add_field(
1356 line = 1,
1357 pos = 2,
1358 widget = cPrompt_edit_area(parent,-1, _("Age")),
1359 weight = 0)
1360
1361 self.fld_age_noted = cEditAreaField(parent)
1362 self._add_field(
1363 line = 1,
1364 pos = 3,
1365 widget = self.fld_age_noted,
1366 weight = 2
1367 )
1368
1369
1370 self.fld_laterality_none= wx.RadioButton(parent, -1, _("N/A"))
1371 self.fld_laterality_left= wx.RadioButton(parent, -1, _("L"))
1372 self.fld_laterality_right= wx.RadioButton(parent, -1, _("R"))
1373 self.fld_laterality_both= wx.RadioButton(parent, -1, _("both"))
1374 self._add_field(
1375 line = 2,
1376 pos = 1,
1377 widget = self.fld_laterality_none,
1378 weight = 0
1379 )
1380 self._add_field(
1381 line = 2,
1382 pos = 2,
1383 widget = self.fld_laterality_left,
1384 weight = 0
1385 )
1386 self._add_field(
1387 line = 2,
1388 pos = 3,
1389 widget = self.fld_laterality_right,
1390 weight = 1
1391 )
1392 self._add_field(
1393 line = 2,
1394 pos = 4,
1395 widget = self.fld_laterality_both,
1396 weight = 1
1397 )
1398
1399 self.fld_condition= cEditAreaField(parent)
1400 self._add_field(
1401 line = 3,
1402 pos = 1,
1403 widget = self.fld_condition,
1404 weight = 6
1405 )
1406
1407 self.fld_notes= cEditAreaField(parent)
1408 self._add_field(
1409 line = 4,
1410 pos = 1,
1411 widget = self.fld_notes,
1412 weight = 6
1413 )
1414
1415 self.fld_significant= wx.CheckBox(
1416 parent,
1417 -1,
1418 _("significant"),
1419 style = wx.NO_BORDER
1420 )
1421 self.fld_active= wx.CheckBox(
1422 parent,
1423 -1,
1424 _("active"),
1425 style = wx.NO_BORDER
1426 )
1427
1428 self._add_field(
1429 line = 5,
1430 pos = 1,
1431 widget = self.fld_significant,
1432 weight = 0
1433 )
1434 self._add_field(
1435 line = 5,
1436 pos = 2,
1437 widget = self.fld_active,
1438 weight = 0
1439 )
1440
1441 self.fld_progress= cEditAreaField(parent)
1442 self._add_field(
1443 line = 6,
1444 pos = 1,
1445 widget = self.fld_progress,
1446 weight = 6
1447 )
1448
1449
1450 self._add_field(
1451 line = 7,
1452 pos = 4,
1453 widget = self._make_standard_buttons(parent),
1454 weight = 2
1455 )
1456
1457 - def _postInit(self):
1458 return
1459
1460 wx.EVT_KILL_FOCUS( self.fld_age_noted, self._ageKillFocus)
1461 wx.EVT_KILL_FOCUS( self.fld_date_noted, self._yearKillFocus)
1462
1463 - def _ageKillFocus( self, event):
1464
1465 event.Skip()
1466 try :
1467 year = self._getBirthYear() + int(self.fld_age_noted.GetValue().strip() )
1468 self.fld_date_noted.SetValue( str (year) )
1469 except:
1470 pass
1471
1472 - def _getBirthYear(self):
1473 try:
1474 birthyear = int(str(self._patient['dob']).split('-')[0])
1475 except:
1476
1477 birthyear = 1
1478
1479 return birthyear
1480
1481 - def _yearKillFocus( self, event):
1482 event.Skip()
1483 try:
1484 age = int(self.fld_date_noted.GetValue().strip() ) - self._getBirthYear()
1485 self.fld_age_noted.SetValue( str (age) )
1486 except:
1487 pass
1488
1489 __init_values = {
1490 "condition": "",
1491 "notes1": "",
1492 "notes2": "",
1493 "age": "",
1494
1495 "progress": "",
1496 "active": 1,
1497 "operation": 0,
1498 "confidential": 0,
1499 "significant": 1,
1500 "both": 0,
1501 "left": 0,
1502 "right": 0,
1503 "none" : 1
1504 }
1505
1506 - def _getDefaultAge(self):
1507 try:
1508
1509 return 1
1510 except:
1511 return 0
1512
1513 - def _get_init_values(self):
1514 values = gmPastHistoryEditArea.__init_values
1515 values["age"] = str( self._getDefaultAge())
1516 return values
1517
1518 - def _save_data(self):
1519 clinical = self._patient.get_emr().get_past_history()
1520 if self.getDataId() is None:
1521 id = clinical.create_history( self.get_fields_formatting_values() )
1522 self.setDataId(id)
1523 return
1524
1525 clinical.update_history( self.get_fields_formatting_values(), self.getDataId() )
1526
1527
1537
1539 self._add_prompt (line = 1, label = _ ("Specialty"))
1540 self._add_prompt (line = 2, label = _ ("Name"))
1541 self._add_prompt (line = 3, label = _ ("Address"))
1542 self._add_prompt (line = 4, label = _ ("Options"))
1543 self._add_prompt (line = 5, label = _("Text"), weight =6)
1544 self._add_prompt (line = 6, label = "")
1545
1547 self.fld_specialty = gmPhraseWheel.cPhraseWheel (
1548 parent = parent,
1549 id = -1,
1550 style = wx.SIMPLE_BORDER
1551 )
1552
1553 self._add_field (
1554 line = 1,
1555 pos = 1,
1556 widget = self.fld_specialty,
1557 weight = 1
1558 )
1559 self.fld_name = gmPhraseWheel.cPhraseWheel (
1560 parent = parent,
1561 id = -1,
1562 style = wx.SIMPLE_BORDER
1563 )
1564
1565 self._add_field (
1566 line = 2,
1567 pos = 1,
1568 widget = self.fld_name,
1569 weight = 1
1570 )
1571 self.fld_address = wx.ComboBox (parent, -1, style = wx.CB_READONLY)
1572
1573 self._add_field (
1574 line = 3,
1575 pos = 1,
1576 widget = self.fld_address,
1577 weight = 1
1578 )
1579
1580
1581 self.fld_name.add_callback_on_selection(self.setAddresses)
1582
1583 self.fld_med = wx.CheckBox (parent, -1, _("Meds"), style=wx.NO_BORDER)
1584 self._add_field (
1585 line = 4,
1586 pos = 1,
1587 widget = self.fld_med,
1588 weight = 1
1589 )
1590 self.fld_past = wx.CheckBox (parent, -1, _("Past Hx"), style=wx.NO_BORDER)
1591 self._add_field (
1592 line = 4,
1593 pos = 4,
1594 widget = self.fld_past,
1595 weight = 1
1596 )
1597 self.fld_text = wx.TextCtrl (parent, -1, style= wx.TE_MULTILINE)
1598 self._add_field (
1599 line = 5,
1600 pos = 1,
1601 widget = self.fld_text,
1602 weight = 1)
1603
1604 self._add_field(
1605 line = 6,
1606 pos = 1,
1607 widget = self._make_standard_buttons(parent),
1608 weight = 1
1609 )
1610 return 1
1611
1613 """
1614 Doesn't accept any value as this doesn't make sense for this edit area
1615 """
1616 self.fld_specialty.SetValue ('')
1617 self.fld_name.SetValue ('')
1618 self.fld_address.Clear ()
1619 self.fld_address.SetValue ('')
1620 self.fld_med.SetValue (0)
1621 self.fld_past.SetValue (0)
1622 self.fld_text.SetValue ('')
1623 self.recipient = None
1624
1626 """
1627 Set the available addresses for the selected identity
1628 """
1629 if id is None:
1630 self.recipient = None
1631 self.fld_address.Clear ()
1632 self.fld_address.SetValue ('')
1633 else:
1634 self.recipient = gmDemographicRecord.cDemographicRecord_SQL (id)
1635 self.fld_address.Clear ()
1636 self.addr = self.recipient.getAddresses ('work')
1637 for i in self.addr:
1638 self.fld_address.Append (_("%(number)s %(street)s, %(urb)s %(postcode)s") % i, ('post', i))
1639 fax = self.recipient.getCommChannel (gmDemographicRecord.FAX)
1640 email = self.recipient.getCommChannel (gmDemographicRecord.EMAIL)
1641 if fax:
1642 self.fld_address.Append ("%s: %s" % (_("FAX"), fax), ('fax', fax))
1643 if email:
1644 self.fld_address.Append ("%s: %s" % (_("E-MAIL"), email), ('email', email))
1645
1646 - def _save_new_entry(self):
1647 """
1648 We are always saving a "new entry" here because data_ID is always None
1649 """
1650 if not self.recipient:
1651 raise gmExceptions.InvalidInputError(_('must have a recipient'))
1652 if self.fld_address.GetSelection() == -1:
1653 raise gmExceptions.InvalidInputError(_('must select address'))
1654 channel, addr = self.fld_address.GetClientData (self.fld_address.GetSelection())
1655 text = self.fld_text.GetValue()
1656 flags = {}
1657 flags['meds'] = self.fld_med.GetValue()
1658 flags['pasthx'] = self.fld_past.GetValue()
1659 if not gmReferral.create_referral (self._patient, self.recipient, channel, addr, text, flags):
1660 raise gmExceptions.InvalidInputError('error sending form')
1661
1662
1663
1664
1665
1673
1674
1675
1677 _log.debug("making prescription lines")
1678 lines = []
1679 self.txt_problem = cEditAreaField(parent)
1680 self.txt_class = cEditAreaField(parent)
1681 self.txt_generic = cEditAreaField(parent)
1682 self.txt_brand = cEditAreaField(parent)
1683 self.txt_strength= cEditAreaField(parent)
1684 self.txt_directions= cEditAreaField(parent)
1685 self.txt_for = cEditAreaField(parent)
1686 self.txt_progress = cEditAreaField(parent)
1687
1688 lines.append(self.txt_problem)
1689 lines.append(self.txt_class)
1690 lines.append(self.txt_generic)
1691 lines.append(self.txt_brand)
1692 lines.append(self.txt_strength)
1693 lines.append(self.txt_directions)
1694 lines.append(self.txt_for)
1695 lines.append(self.txt_progress)
1696 lines.append(self._make_standard_buttons(parent))
1697 self.input_fields = {
1698 "problem": self.txt_problem,
1699 "class" : self.txt_class,
1700 "generic" : self.txt_generic,
1701 "brand" : self.txt_brand,
1702 "strength": self.txt_strength,
1703 "directions": self.txt_directions,
1704 "for" : self.txt_for,
1705 "progress": self.txt_progress
1706
1707 }
1708
1709 return self._makeExtraColumns( parent, lines)
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1728
1729
1730
1731
1732
1733
1736 wx.StaticText.__init__(self, parent, id, prompt, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_LEFT)
1737 self.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
1738 self.SetForegroundColour(aColor)
1739
1740
1741
1742
1743
1745 - def __init__(self, parent, id, prompt_labels):
1746 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
1747 self.SetBackgroundColour(richards_light_gray)
1748 gszr = wx.GridSizer (len(prompt_labels)+1, 1, 2, 2)
1749 color = richards_aqua
1750 for prompt_key in prompt_labels.keys():
1751 label = cPrompt_edit_area(self, -1, " %s" % prompt_labels[prompt_key], aColor = color)
1752 gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT)
1753 color = richards_blue
1754 self.SetSizer(gszr)
1755 gszr.Fit(self)
1756 self.SetAutoLayout(True)
1757
1758
1759
1760
1761
1762
1763
1764 -class EditTextBoxes(wx.Panel):
1765 - def __init__(self, parent, id, editareaprompts, section):
1766 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize,style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
1767 self.SetBackgroundColour(wx.Colour(222,222,222))
1768 self.parent = parent
1769
1770 self.gszr = wx.GridSizer(len(editareaprompts), 1, 2, 2)
1771
1772 if section == gmSECTION_SUMMARY:
1773 pass
1774 elif section == gmSECTION_DEMOGRAPHICS:
1775 pass
1776 elif section == gmSECTION_CLINICALNOTES:
1777 pass
1778 elif section == gmSECTION_FAMILYHISTORY:
1779 pass
1780 elif section == gmSECTION_PASTHISTORY:
1781 pass
1782
1783
1784 self.txt_condition = cEditAreaField(self,PHX_CONDITION,wx.DefaultPosition,wx.DefaultSize)
1785 self.rb_sideleft = wxRadioButton(self,PHX_LEFT, _(" (L) "), wx.DefaultPosition,wx.DefaultSize)
1786 self.rb_sideright = wxRadioButton(self, PHX_RIGHT, _("(R)"), wx.DefaultPosition,wx.DefaultSize,wx.SUNKEN_BORDER)
1787 self.rb_sideboth = wxRadioButton(self, PHX_BOTH, _("Both"), wx.DefaultPosition,wx.DefaultSize)
1788 rbsizer = wx.BoxSizer(wx.HORIZONTAL)
1789 rbsizer.Add(self.rb_sideleft,1,wx.EXPAND)
1790 rbsizer.Add(self.rb_sideright,1,wx.EXPAND)
1791 rbsizer.Add(self.rb_sideboth,1,wx.EXPAND)
1792 szr1 = wx.BoxSizer(wx.HORIZONTAL)
1793 szr1.Add(self.txt_condition, 4, wx.EXPAND)
1794 szr1.Add(rbsizer, 3, wx.EXPAND)
1795
1796
1797
1798
1799 self.txt_notes1 = cEditAreaField(self,PHX_NOTES,wx.DefaultPosition,wx.DefaultSize)
1800
1801 self.txt_notes2= cEditAreaField(self,PHX_NOTES2,wx.DefaultPosition,wx.DefaultSize)
1802
1803 self.txt_agenoted = cEditAreaField(self, PHX_AGE, wx.DefaultPosition, wx.DefaultSize)
1804 szr4 = wx.BoxSizer(wx.HORIZONTAL)
1805 szr4.Add(self.txt_agenoted, 1, wx.EXPAND)
1806 szr4.Add(5, 0, 5)
1807
1808 self.txt_yearnoted = cEditAreaField(self,PHX_YEAR,wx.DefaultPosition,wx.DefaultSize)
1809 szr5 = wx.BoxSizer(wx.HORIZONTAL)
1810 szr5.Add(self.txt_yearnoted, 1, wx.EXPAND)
1811 szr5.Add(5, 0, 5)
1812
1813 self.parent.cb_active = wx.CheckBox(self, PHX_ACTIVE, _("Active"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1814 self.parent.cb_operation = wx.CheckBox(self, PHX_OPERATION, _("Operation"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1815 self.parent.cb_confidential = wx.CheckBox(self, PHX_CONFIDENTIAL , _("Confidential"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1816 self.parent.cb_significant = wx.CheckBox(self, PHX_SIGNIFICANT, _("Significant"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1817 szr6 = wx.BoxSizer(wx.HORIZONTAL)
1818 szr6.Add(self.parent.cb_active, 1, wx.EXPAND)
1819 szr6.Add(self.parent.cb_operation, 1, wx.EXPAND)
1820 szr6.Add(self.parent.cb_confidential, 1, wx.EXPAND)
1821 szr6.Add(self.parent.cb_significant, 1, wx.EXPAND)
1822
1823 self.txt_progressnotes = cEditAreaField(self,PHX_PROGRESSNOTES ,wx.DefaultPosition,wx.DefaultSize)
1824
1825 szr8 = wx.BoxSizer(wx.HORIZONTAL)
1826 szr8.Add(5, 0, 6)
1827 szr8.Add(self._make_standard_buttons(), 0, wx.EXPAND)
1828
1829 self.gszr.Add(szr1,0,wx.EXPAND)
1830 self.gszr.Add(self.txt_notes1,0,wx.EXPAND)
1831 self.gszr.Add(self.txt_notes2,0,wx.EXPAND)
1832 self.gszr.Add(szr4,0,wx.EXPAND)
1833 self.gszr.Add(szr5,0,wx.EXPAND)
1834 self.gszr.Add(szr6,0,wx.EXPAND)
1835 self.gszr.Add(self.txt_progressnotes,0,wx.EXPAND)
1836 self.gszr.Add(szr8,0,wx.EXPAND)
1837
1838
1839 elif section == gmSECTION_SCRIPT:
1840 pass
1841 elif section == gmSECTION_REQUESTS:
1842 pass
1843 elif section == gmSECTION_RECALLS:
1844 pass
1845 else:
1846 pass
1847
1848 self.SetSizer(self.gszr)
1849 self.gszr.Fit(self)
1850
1851 self.SetAutoLayout(True)
1852 self.Show(True)
1853
1855 self.btn_OK = wx.Button(self, -1, _("Ok"))
1856 self.btn_Clear = wx.Button(self, -1, _("Clear"))
1857 szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
1858 szr_buttons.Add(self.btn_OK, 1, wx.EXPAND, wx.ALL, 1)
1859 szr_buttons.Add(5, 0, 0)
1860 szr_buttons.Add(self.btn_Clear, 1, wx.EXPAND, wx.ALL, 1)
1861 return szr_buttons
1862
1864 - def __init__(self, parent, id, line_labels, section):
1865 _log.warning('***** old style EditArea instantiated, please convert *****')
1866
1867 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, style = wx.NO_BORDER)
1868 self.SetBackgroundColour(wx.Colour(222,222,222))
1869
1870
1871 prompts = gmPnlEditAreaPrompts(self, -1, line_labels)
1872
1873 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1874
1875 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
1876 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
1877 szr_shadow_below_prompts.Add(5,0,0,wx.EXPAND)
1878 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
1879
1880 szr_prompts = wx.BoxSizer(wx.VERTICAL)
1881 szr_prompts.Add(prompts, 97, wx.EXPAND)
1882 szr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
1883
1884
1885 edit_fields = EditTextBoxes(self, -1, line_labels, section)
1886
1887 shadow_below_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1888
1889 shadow_below_editarea.SetBackgroundColour(richards_coloured_gray)
1890 szr_shadow_below_editarea = wx.BoxSizer(wx.HORIZONTAL)
1891 szr_shadow_below_editarea.Add(5,0,0,wx.EXPAND)
1892 szr_shadow_below_editarea.Add(shadow_below_editarea, 12, wx.EXPAND)
1893
1894 szr_editarea = wx.BoxSizer(wx.VERTICAL)
1895 szr_editarea.Add(edit_fields, 92, wx.EXPAND)
1896 szr_editarea.Add(szr_shadow_below_editarea, 5, wx.EXPAND)
1897
1898
1899
1900 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1901 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
1902 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
1903 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
1904 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND)
1905
1906 shadow_rightof_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1907 shadow_rightof_editarea.SetBackgroundColour(richards_coloured_gray)
1908 szr_shadow_rightof_editarea = wx.BoxSizer(wx.VERTICAL)
1909 szr_shadow_rightof_editarea.Add(0, 5, 0, wx.EXPAND)
1910 szr_shadow_rightof_editarea.Add(shadow_rightof_editarea, 1, wx.EXPAND)
1911
1912
1913 self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL)
1914 self.szr_main_panels.Add(szr_prompts, 10, wx.EXPAND)
1915 self.szr_main_panels.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
1916 self.szr_main_panels.Add(5, 0, 0, wx.EXPAND)
1917 self.szr_main_panels.Add(szr_editarea, 89, wx.EXPAND)
1918 self.szr_main_panels.Add(szr_shadow_rightof_editarea, 1, wx.EXPAND)
1919
1920
1921
1922 self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL)
1923 self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5)
1924 self.SetSizer(self.szr_central_container)
1925 self.szr_central_container.Fit(self)
1926 self.SetAutoLayout(True)
1927 self.Show(True)
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
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 if __name__ == "__main__":
2205
2206
2211 self._add_prompt(line=1, label='line 1')
2212 self._add_prompt(line=2, label='buttons')
2214
2215 self.fld_substance = cEditAreaField(parent)
2216 self._add_field(
2217 line = 1,
2218 pos = 1,
2219 widget = self.fld_substance,
2220 weight = 1
2221 )
2222
2223 self._add_field(
2224 line = 2,
2225 pos = 1,
2226 widget = self._make_standard_buttons(parent),
2227 weight = 1
2228 )
2229
2230 app = wxPyWidgetTester(size = (400, 200))
2231 app.SetWidget(cTestEditArea)
2232 app.MainLoop()
2233
2234
2235
2236
2237
2238
2239
2240