1
2
3
4 __license__ = 'GPL'
5 __author__ = "R.Terry, K.Hilbert"
6
7
8 import sys
9 import logging
10 import datetime as pydt
11
12
13 import wx
14
15
16 if __name__ == '__main__':
17 sys.path.insert(0, '../../')
18 from Gnumed.pycommon import gmDispatcher
19
20
21 _log = logging.getLogger('gm.ui')
22
23 edit_area_modes = ['new', 'edit', 'new_from_existing']
24
26 """Mixin for edit area panels providing generic functionality.
27
28 **************** start of template ****************
29
30 #====================================================================
31 # Class definition:
32
33 from Gnumed.wxGladeWidgets import wxgXxxEAPnl
34
35 class cXxxEAPnl(wxgXxxEAPnl.wxgXxxEAPnl, gmEditArea.cGenericEditAreaMixin):
36
37 def __init__(self, *args, **kwargs):
38
39 try:
40 data = kwargs['xxx']
41 del kwargs['xxx']
42 except KeyError:
43 data = None
44
45 wxgXxxEAPnl.wxgXxxEAPnl.__init__(self, *args, **kwargs)
46 gmEditArea.cGenericEditAreaMixin.__init__(self)
47
48 # Code using this mixin should set mode and data
49 # after instantiating the class:
50 self.mode = 'new'
51 self.data = data
52 if data is not None:
53 self.mode = 'edit'
54
55 #self.__init_ui()
56 #----------------------------------------------------------------
57 # def __init_ui(self):
58 # # adjust phrasewheels etc
59 #----------------------------------------------------------------
60 # generic Edit Area mixin API
61 #----------------------------------------------------------------
62 def _valid_for_save(self):
63
64 # its best to validate bottom -> top such that the
65 # cursor ends up in the topmost failing field
66
67 # remove when implemented:
68 return False
69
70 validity = True
71
72 if self._TCTRL_xxx.GetValue().strip() == u'':
73 validity = False
74 self.display_tctrl_as_valid(tctrl = self._TCTRL_xxx, valid = False)
75 gmDispatcher.send(signal = 'statustext', msg = _('No entry in field xxx.'))
76 self._TCTRL_xxx.SetFocus()
77 else:
78 self.display_tctrl_as_valid(tctrl = self._TCTRL_xxx, valid = True)
79
80 if self._PRW_xxx.GetData() is None:
81 validity = False
82 self._PRW_xxx.display_as_valid(False)
83 gmDispatcher.send(signal = 'statustext', msg = _('No entry in field xxx.'))
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
235 from Gnumed.wxGladeWidgets import wxgGenericEditAreaDlg2
236
238 """Dialog for parenting edit area panels with save/clear/next/cancel"""
239
240 _lucky_day = 1
241 _lucky_month = 4
242 _today = pydt.date.today()
243
245
246 new_ea = kwargs['edit_area']
247 del kwargs['edit_area']
248
249 if not isinstance(new_ea, cGenericEditAreaMixin):
250 raise TypeError('[%s]: edit area instance must be child of cGenericEditAreaMixin')
251
252 try:
253 single_entry = kwargs['single_entry']
254 del kwargs['single_entry']
255 except KeyError:
256 single_entry = False
257
258 wxgGenericEditAreaDlg2.wxgGenericEditAreaDlg2.__init__(self, *args, **kwargs)
259
260 self.left_extra_button = None
261
262 if cGenericEditAreaDlg2._today.day != cGenericEditAreaDlg2._lucky_day:
263 self._BTN_lucky.Enable(False)
264 self._BTN_lucky.Hide()
265 else:
266 if cGenericEditAreaDlg2._today.month != cGenericEditAreaDlg2._lucky_month:
267 self._BTN_lucky.Enable(False)
268 self._BTN_lucky.Hide()
269
270
271 dummy_ea_pnl = self._PNL_ea
272 ea_pnl_szr = dummy_ea_pnl.GetContainingSizer()
273 ea_pnl_parent = dummy_ea_pnl.GetParent()
274 ea_pnl_szr.Remove(dummy_ea_pnl)
275 dummy_ea_pnl.Destroy()
276 del dummy_ea_pnl
277 new_ea_min_size = new_ea.GetMinSize()
278 new_ea.Reparent(ea_pnl_parent)
279 self._PNL_ea = new_ea
280 ea_pnl_szr.Add(self._PNL_ea, 1, wx.EXPAND, 0)
281 ea_pnl_szr.SetMinSize(new_ea_min_size)
282 ea_pnl_szr.Fit(new_ea)
283
284
285 if single_entry:
286 self._BTN_forward.Enable(False)
287 self._BTN_forward.Hide()
288
289 self._adjust_clear_revert_buttons()
290
291
292 self._TCTRL_status.SetValue('')
293 gmDispatcher.connect(signal = u'statustext', receiver = self._on_set_statustext)
294
295
296
297 main_szr = self.GetSizer()
298 main_szr.Fit(self)
299 self.Layout()
300
301
302 self._PNL_ea.refresh()
303
304 - def _on_set_statustext(self, msg=None, loglevel=None, beep=True):
305 if msg is None:
306 self._TCTRL_status.SetValue('')
307 return
308 if msg.strip() == u'':
309 self._TCTRL_status.SetValue('')
310 return
311 self._TCTRL_status.SetValue(msg)
312 return
313
325
333
336
339
354
365
374
375
376
392
393 left_extra_button = property(lambda x:x, _set_left_extra_button)
394
395
396
397
398
399
400
401 from Gnumed.pycommon import gmGuiBroker
402
403
404 _gb = gmGuiBroker.GuiBroker()
405
406 gmSECTION_SUMMARY = 1
407 gmSECTION_DEMOGRAPHICS = 2
408 gmSECTION_CLINICALNOTES = 3
409 gmSECTION_FAMILYHISTORY = 4
410 gmSECTION_PASTHISTORY = 5
411 gmSECTION_SCRIPT = 8
412 gmSECTION_REQUESTS = 9
413 gmSECTION_REFERRALS = 11
414 gmSECTION_RECALLS = 12
415
416 richards_blue = wx.Colour(0,0,131)
417 richards_aqua = wx.Colour(0,194,197)
418 richards_dark_gray = wx.Colour(131,129,131)
419 richards_light_gray = wx.Colour(255,255,255)
420 richards_coloured_gray = wx.Colour(131,129,131)
421
422
423 CONTROLS_WITHOUT_LABELS =['wxTextCtrl', 'cEditAreaField', 'wx.SpinCtrl', 'gmPhraseWheel', 'wx.ComboBox']
424
426 widget.SetForegroundColour(wx.Colour(255, 0, 0))
427 widget.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
428
441 if not isinstance(edit_area, cEditArea2):
442 raise TypeError('<edit_area> must be of type cEditArea2 but is <%s>' % type(edit_area))
443 wx.Dialog.__init__(self, parent, id, title, pos, size, style, name)
444 self.__wxID_BTN_SAVE = wx.NewId()
445 self.__wxID_BTN_RESET = wx.NewId()
446 self.__editarea = edit_area
447 self.__do_layout()
448 self.__register_events()
449
450
451
454
456 self.__editarea.Reparent(self)
457
458 self.__btn_SAVE = wx.Button(self, self.__wxID_BTN_SAVE, _("Save"))
459 self.__btn_SAVE.SetToolTipString(_('save entry into medical record'))
460 self.__btn_RESET = wx.Button(self, self.__wxID_BTN_RESET, _("Reset"))
461 self.__btn_RESET.SetToolTipString(_('reset entry'))
462 self.__btn_CANCEL = wx.Button(self, wx.ID_CANCEL, _("Cancel"))
463 self.__btn_CANCEL.SetToolTipString(_('discard entry and cancel'))
464
465 szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
466 szr_buttons.Add(self.__btn_SAVE, 1, wx.EXPAND | wx.ALL, 1)
467 szr_buttons.Add(self.__btn_RESET, 1, wx.EXPAND | wx.ALL, 1)
468 szr_buttons.Add(self.__btn_CANCEL, 1, wx.EXPAND | wx.ALL, 1)
469
470 szr_main = wx.BoxSizer(wx.VERTICAL)
471 szr_main.Add(self.__editarea, 1, wx.EXPAND)
472 szr_main.Add(szr_buttons, 0, wx.EXPAND)
473
474 self.SetSizerAndFit(szr_main)
475
476
477
479
480 wx.EVT_BUTTON(self.__btn_SAVE, self.__wxID_BTN_SAVE, self._on_SAVE_btn_pressed)
481 wx.EVT_BUTTON(self.__btn_RESET, self.__wxID_BTN_RESET, self._on_RESET_btn_pressed)
482 wx.EVT_BUTTON(self.__btn_CANCEL, wx.ID_CANCEL, self._on_CANCEL_btn_pressed)
483
484 wx.EVT_CLOSE(self, self._on_CANCEL_btn_pressed)
485
486
487
488
489
490
491 return 1
492
494 if self.__editarea.save_data():
495 self.__editarea.Close()
496 self.EndModal(wx.ID_OK)
497 return
498 short_err = self.__editarea.get_short_error()
499 long_err = self.__editarea.get_long_error()
500 if (short_err is None) and (long_err is None):
501 long_err = _(
502 'Unspecified error saving data in edit area.\n\n'
503 'Programmer forgot to specify proper error\n'
504 'message in [%s].'
505 ) % self.__editarea.__class__.__name__
506 if short_err is not None:
507 gmDispatcher.send(signal = 'statustext', msg = short_err)
508 if long_err is not None:
509 gmGuiHelpers.gm_show_error(long_err, _('saving clinical data'))
510
512 self.__editarea.Close()
513 self.EndModal(wx.ID_CANCEL)
514
517
519 - def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TAB_TRAVERSAL):
520
521 wx.Panel.__init__ (
522 self,
523 parent,
524 id,
525 pos = pos,
526 size = size,
527 style = style | wx.TAB_TRAVERSAL
528 )
529 self.SetBackgroundColour(wx.Colour(222,222,222))
530
531 self.data = None
532 self.fields = {}
533 self.prompts = {}
534 self._short_error = None
535 self._long_error = None
536 self._summary = None
537 self._patient = gmPerson.gmCurrentPatient()
538 self.__wxID_BTN_OK = wx.NewId()
539 self.__wxID_BTN_CLEAR = wx.NewId()
540 self.__do_layout()
541 self.__register_events()
542 self.Show()
543
544
545
547 """This needs to be overridden by child classes."""
548 self._long_error = _(
549 'Cannot save data from edit area.\n\n'
550 'Programmer forgot to override method:\n'
551 ' <%s.save_data>'
552 ) % self.__class__.__name__
553 return False
554
556 msg = _(
557 'Cannot reset fields in edit area.\n\n'
558 'Programmer forgot to override method:\n'
559 ' <%s.reset_ui>'
560 ) % self.__class__.__name__
561 gmGuiHelpers.gm_show_error(msg)
562
564 tmp = self._short_error
565 self._short_error = None
566 return tmp
567
569 tmp = self._long_error
570 self._long_error = None
571 return tmp
572
574 return _('<No embed string for [%s]>') % self.__class__.__name__
575
576
577
589
594
595
596
598 self.__deregister_events()
599 event.Skip()
600
602 """Only active if _make_standard_buttons was called in child class."""
603
604 try:
605 event.Skip()
606 if self.data is None:
607 self._save_new_entry()
608 self.reset_ui()
609 else:
610 self._save_modified_entry()
611 self.reset_ui()
612 except gmExceptions.InvalidInputError, err:
613
614
615 gmGuiHelpers.gm_show_error (err, _("Invalid Input"))
616 except:
617 _log.exception( "save data problem in [%s]" % self.__class__.__name__)
618
620 """Only active if _make_standard_buttons was called in child class."""
621
622 self.reset_ui()
623 event.Skip()
624
626 self.__deregister_events()
627
628 if not self._patient.connected:
629 return True
630
631
632
633
634 return True
635 _log.error('[%s] lossage' % self.__class__.__name__)
636 return False
637
639 """Just before new patient becomes active."""
640
641 if not self._patient.connected:
642 return True
643
644
645
646
647 return True
648 _log.error('[%s] lossage' % self.__class__.__name__)
649 return False
650
652 """Just after new patient became active."""
653
654 self.reset_ui()
655
656
657
659
660
661 self._define_prompts()
662 self._define_fields(parent = self)
663 if len(self.fields) != len(self.prompts):
664 _log.error('[%s]: #fields != #prompts' % self.__class__.__name__)
665 return None
666
667
668 szr_main_fgrid = wx.FlexGridSizer(rows = len(self.prompts), cols=2)
669 color = richards_aqua
670 lines = self.prompts.keys()
671 lines.sort()
672 for line in lines:
673
674 label, color, weight = self.prompts[line]
675
676 prompt = wx.StaticText (
677 parent = self,
678 id = -1,
679 label = label,
680 style = wx.ALIGN_CENTRE
681 )
682
683 prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
684 prompt.SetForegroundColour(color)
685 prompt.SetBackgroundColour(richards_light_gray)
686 szr_main_fgrid.Add(prompt, flag=wx.EXPAND | wx.ALIGN_RIGHT)
687
688
689 szr_line = wx.BoxSizer(wx.HORIZONTAL)
690 positions = self.fields[line].keys()
691 positions.sort()
692 for pos in positions:
693 field, weight = self.fields[line][pos]
694
695 szr_line.Add(field, weight, wx.EXPAND)
696 szr_main_fgrid.Add(szr_line, flag=wx.GROW | wx.ALIGN_LEFT)
697
698
699 szr_main_fgrid.AddGrowableCol(1)
700
701
702
703
704
705
706
707 self.SetSizerAndFit(szr_main_fgrid)
708
709
710
711
713 """Child classes override this to define their prompts using _add_prompt()"""
714 _log.error('missing override in [%s]' % self.__class__.__name__)
715
717 """Add a new prompt line.
718
719 To be used from _define_fields in child classes.
720
721 - label, the label text
722 - color
723 - weight, the weight given in sizing the various rows. 0 means the row
724 always has minimum size
725 """
726 self.prompts[line] = (label, color, weight)
727
729 """Defines the fields.
730
731 - override in child classes
732 - mostly uses _add_field()
733 """
734 _log.error('missing override in [%s]' % self.__class__.__name__)
735
736 - def _add_field(self, line=None, pos=None, widget=None, weight=0):
737 if None in (line, pos, widget):
738 _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget))
739 if not self.fields.has_key(line):
740 self.fields[line] = {}
741 self.fields[line][pos] = (widget, weight)
742
760
761
762
763
765 - def __init__ (self, parent, id = -1, pos = wx.DefaultPosition, size=wx.DefaultSize):
766 wx.TextCtrl.__init__(self,parent,id,"",pos, size ,wx.SIMPLE_BORDER)
767 _decorate_editarea_field(self)
768
770 - def __init__(self, parent, id, pos, size, style):
771
772 print "class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__
773
774
775 wx.Panel.__init__(self, parent, id, pos=pos, size=size, style=wx.NO_BORDER | wx.TAB_TRAVERSAL)
776 self.SetBackgroundColour(wx.Colour(222,222,222))
777
778 self.data = None
779 self.fields = {}
780 self.prompts = {}
781
782 ID_BTN_OK = wx.NewId()
783 ID_BTN_CLEAR = wx.NewId()
784
785 self.__do_layout()
786
787
788
789
790
791
792 self._patient = gmPerson.gmCurrentPatient()
793 self.__register_events()
794 self.Show(True)
795
796
797
799
800 self._define_prompts()
801 self.fields_pnl = wx.Panel(self, -1, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
802 self._define_fields(parent = self.fields_pnl)
803
804 szr_prompts = self.__generate_prompts()
805 szr_fields = self.__generate_fields()
806
807
808 self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL)
809 self.szr_main_panels.Add(szr_prompts, 11, wx.EXPAND)
810 self.szr_main_panels.Add(5, 0, 0, wx.EXPAND)
811 self.szr_main_panels.Add(szr_fields, 90, wx.EXPAND)
812
813
814
815 self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL)
816 self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5)
817
818
819 self.SetAutoLayout(True)
820 self.SetSizer(self.szr_central_container)
821 self.szr_central_container.Fit(self)
822
824 if len(self.fields) != len(self.prompts):
825 _log.error('[%s]: #fields != #prompts' % self.__class__.__name__)
826 return None
827
828 prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
829 prompt_pnl.SetBackgroundColour(richards_light_gray)
830
831 color = richards_aqua
832 lines = self.prompts.keys()
833 lines.sort()
834 self.prompt_widget = {}
835 for line in lines:
836 label, color, weight = self.prompts[line]
837 self.prompt_widget[line] = self.__make_prompt(prompt_pnl, "%s " % label, color)
838
839 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
840 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
841 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
842 szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND)
843 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
844
845
846 vszr_prompts = wx.BoxSizer(wx.VERTICAL)
847 vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND)
848 vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
849
850
851 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
852 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
853 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
854 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
855 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts, 1, wx.EXPAND)
856
857
858 hszr_prompts = wx.BoxSizer(wx.HORIZONTAL)
859 hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND)
860 hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
861
862 return hszr_prompts
863
865 self.fields_pnl.SetBackgroundColour(wx.Colour(222,222,222))
866
867 vszr = wx.BoxSizer(wx.VERTICAL)
868 lines = self.fields.keys()
869 lines.sort()
870 self.field_line_szr = {}
871 for line in lines:
872 self.field_line_szr[line] = wx.BoxSizer(wx.HORIZONTAL)
873 positions = self.fields[line].keys()
874 positions.sort()
875 for pos in positions:
876 field, weight = self.fields[line][pos]
877 self.field_line_szr[line].Add(field, weight, wx.EXPAND)
878 try:
879 vszr.Add(self.field_line_szr[line], self.prompts[line][2], flag = wx.EXPAND)
880 except KeyError:
881 _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) ) )
882
883 self.fields_pnl.SetSizer(vszr)
884 vszr.Fit(self.fields_pnl)
885
886
887 shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
888 shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray)
889 szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
890 szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND)
891 szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND)
892
893
894 vszr_edit_fields = wx.BoxSizer(wx.VERTICAL)
895 vszr_edit_fields.Add(self.fields_pnl, 92, wx.EXPAND)
896 vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND)
897
898
899 shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
900 shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray)
901 szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL)
902 szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND)
903 szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND)
904
905
906 hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
907 hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND)
908 hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND)
909
910 return hszr_edit_fields
911
913
914 prompt = wx.StaticText(
915 parent,
916 -1,
917 aLabel,
918 style = wx.ALIGN_RIGHT
919 )
920 prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
921 prompt.SetForegroundColour(aColor)
922 return prompt
923
924
925
927 """Add a new prompt line.
928
929 To be used from _define_fields in child classes.
930
931 - label, the label text
932 - color
933 - weight, the weight given in sizing the various rows. 0 means the rwo
934 always has minimum size
935 """
936 self.prompts[line] = (label, color, weight)
937
938 - def _add_field(self, line=None, pos=None, widget=None, weight=0):
939 if None in (line, pos, widget):
940 _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget))
941 if not self.fields.has_key(line):
942 self.fields[line] = {}
943 self.fields[line][pos] = (widget, weight)
944
946 """Defines the fields.
947
948 - override in child classes
949 - mostly uses _add_field()
950 """
951 _log.error('missing override in [%s]' % self.__class__.__name__)
952
954 _log.error('missing override in [%s]' % self.__class__.__name__)
955
969
972
974 _log.error('[%s] programmer forgot to define _save_data()' % self.__class__.__name__)
975 _log.info('child classes of cEditArea *must* override this function')
976 return False
977
978
979
981
982 wx.EVT_BUTTON(self.btn_OK, ID_BTN_OK, self._on_OK_btn_pressed)
983 wx.EVT_BUTTON(self.btn_Clear, ID_BTN_CLEAR, self._on_clear_btn_pressed)
984
985 wx.EVT_SIZE (self.fields_pnl, self._on_resize_fields)
986
987
988 gmDispatcher.connect(signal = u'pre_patient_selection', receiver = self._on_pre_patient_selection)
989 gmDispatcher.connect(signal = u'application_closing', receiver = self._on_application_closing)
990 gmDispatcher.connect(signal = u'post_patient_selection', receiver = self.on_post_patient_selection)
991
992 return 1
993
994
995
1012
1017
1018 - def on_post_patient_selection( self, **kwds):
1019
1020 self.set_data()
1021
1023
1024 if not self._patient.connected:
1025 return True
1026 if self._save_data():
1027 return True
1028 _log.error('[%s] lossage' % self.__class__.__name__)
1029 return False
1030
1032
1033 if not self._patient.connected:
1034 return True
1035 if self._save_data():
1036 return True
1037 _log.error('[%s] lossage' % self.__class__.__name__)
1038 return False
1039
1041 self.fields_pnl.Layout()
1042
1043 for i in self.field_line_szr.keys():
1044
1045 pos = self.field_line_szr[i].GetPosition()
1046
1047 self.prompt_widget[i].SetPosition((0, pos.y))
1048
1050 - def __init__(self, parent, id, aType = None):
1051
1052 print "class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__
1053
1054
1055 if aType not in _known_edit_area_types:
1056 _log.error('unknown edit area type: [%s]' % aType)
1057 raise gmExceptions.ConstructorError, 'unknown edit area type: [%s]' % aType
1058 self._type = aType
1059
1060
1061 cEditArea.__init__(self, parent, id)
1062
1063 self.input_fields = {}
1064
1065 self._postInit()
1066 self.old_data = {}
1067
1068 self._patient = gmPerson.gmCurrentPatient()
1069 self.Show(True)
1070
1071
1072
1073
1074
1075
1077
1078 prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
1079 prompt_pnl.SetBackgroundColour(richards_light_gray)
1080
1081 gszr = wx.FlexGridSizer (len(prompt_labels)+1, 1, 2, 2)
1082 color = richards_aqua
1083 for prompt in prompt_labels:
1084 label = self.__make_prompt(prompt_pnl, "%s " % prompt, color)
1085 gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT)
1086 color = richards_blue
1087 gszr.RemoveGrowableRow (line-1)
1088
1089 prompt_pnl.SetSizer(gszr)
1090 gszr.Fit(prompt_pnl)
1091 prompt_pnl.SetAutoLayout(True)
1092
1093
1094 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1095 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
1096 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
1097 szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND)
1098 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
1099
1100
1101 vszr_prompts = wx.BoxSizer(wx.VERTICAL)
1102 vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND)
1103 vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
1104
1105
1106 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1107 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
1108 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
1109 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
1110 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND)
1111
1112
1113 hszr_prompts = wx.BoxSizer(wx.HORIZONTAL)
1114 hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND)
1115 hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
1116
1117 return hszr_prompts
1118
1120 _log.error('programmer forgot to define edit area lines for [%s]' % self._type)
1121 _log.info('child classes of gmEditArea *must* override this function')
1122 return []
1123
1125
1126 fields_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
1127 fields_pnl.SetBackgroundColour(wx.Colour(222,222,222))
1128
1129 gszr = wx.GridSizer(len(_prompt_defs[self._type]), 1, 2, 2)
1130
1131
1132 lines = self._make_edit_lines(parent = fields_pnl)
1133
1134 self.lines = lines
1135 if len(lines) != len(_prompt_defs[self._type]):
1136 _log.error('#(edit lines) not equal #(prompts) for [%s], something is fishy' % self._type)
1137 for line in lines:
1138 gszr.Add(line, 0, wx.EXPAND | wx.ALIGN_LEFT)
1139
1140 fields_pnl.SetSizer(gszr)
1141 gszr.Fit(fields_pnl)
1142 fields_pnl.SetAutoLayout(True)
1143
1144
1145 shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1146 shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray)
1147 szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
1148 szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND)
1149 szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND)
1150
1151
1152 vszr_edit_fields = wx.BoxSizer(wx.VERTICAL)
1153 vszr_edit_fields.Add(fields_pnl, 92, wx.EXPAND)
1154 vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND)
1155
1156
1157 shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1158 shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray)
1159 szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL)
1160 szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND)
1161 szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND)
1162
1163
1164 hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
1165 hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND)
1166 hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND)
1167
1168 return hszr_edit_fields
1169
1172
1177
1179 map = {}
1180 for k in self.input_fields.keys():
1181 map[k] = ''
1182 return map
1183
1184
1186 self._default_init_fields()
1187
1188
1189
1190
1191
1193 _log.warning("you may want to override _updateUI for [%s]" % self.__class__.__name__)
1194
1195
1196 - def _postInit(self):
1197 """override for further control setup"""
1198 pass
1199
1200
1202 szr = wx.BoxSizer(wx.HORIZONTAL)
1203 szr.Add( widget, weight, wx.EXPAND)
1204 szr.Add( 0,0, spacerWeight, wx.EXPAND)
1205 return szr
1206
1208
1209 cb = wx.CheckBox( parent, -1, _(title))
1210 cb.SetForegroundColour( richards_blue)
1211 return cb
1212
1213
1214
1216 """this is a utlity method to add extra columns"""
1217
1218 if self.__class__.__dict__.has_key("extraColumns"):
1219 for x in self.__class__.extraColumns:
1220 lines = self._addColumn(parent, lines, x, weightMap)
1221 return lines
1222
1223
1224
1225 - def _addColumn(self, parent, lines, extra, weightMap = {}, existingWeight = 5 , extraWeight = 2):
1226 """
1227 # add ia extra column in the edit area.
1228 # preconditions:
1229 # parent is fields_pnl (weak);
1230 # self.input_fields exists (required);
1231 # ; extra is a list of tuples of format -
1232 # ( key for input_fields, widget label , widget class to instantiate )
1233 """
1234
1235 newlines = []
1236 i = 0
1237 for x in lines:
1238
1239 if weightMap.has_key( x):
1240 (existingWeight, extraWeight) = weightMap[x]
1241
1242 szr = wx.BoxSizer(wx.HORIZONTAL)
1243 szr.Add( x, existingWeight, wx.EXPAND)
1244 if i < len(extra) and extra[i] <> None:
1245
1246 (inputKey, widgetLabel, aclass) = extra[i]
1247 if aclass.__name__ in CONTROLS_WITHOUT_LABELS:
1248 szr.Add( self._make_prompt(parent, widgetLabel, richards_blue) )
1249 widgetLabel = ""
1250
1251
1252 w = aclass( parent, -1, widgetLabel)
1253 if not aclass.__name__ in CONTROLS_WITHOUT_LABELS:
1254 w.SetForegroundColour(richards_blue)
1255
1256 szr.Add(w, extraWeight , wx.EXPAND)
1257
1258
1259 self.input_fields[inputKey] = w
1260
1261 newlines.append(szr)
1262 i += 1
1263 return newlines
1264
1284
1287
1290
1296
1307
1308 -class gmPastHistoryEditArea(gmEditArea):
1309
1310 - def __init__(self, parent, id):
1311 gmEditArea.__init__(self, parent, id, aType = 'past history')
1312
1313 - def _define_prompts(self):
1314 self._add_prompt(line = 1, label = _("When Noted"))
1315 self._add_prompt(line = 2, label = _("Laterality"))
1316 self._add_prompt(line = 3, label = _("Condition"))
1317 self._add_prompt(line = 4, label = _("Notes"))
1318 self._add_prompt(line = 6, label = _("Status"))
1319 self._add_prompt(line = 7, label = _("Progress Note"))
1320 self._add_prompt(line = 8, label = '')
1321
1322 - def _define_fields(self, parent):
1323
1324 self.fld_date_noted = gmDateTimeInput.gmDateInput(
1325 parent = parent,
1326 id = -1,
1327 style = wx.SIMPLE_BORDER
1328 )
1329 self._add_field(
1330 line = 1,
1331 pos = 1,
1332 widget = self.fld_date_noted,
1333 weight = 2
1334 )
1335 self._add_field(
1336 line = 1,
1337 pos = 2,
1338 widget = cPrompt_edit_area(parent,-1, _("Age")),
1339 weight = 0)
1340
1341 self.fld_age_noted = cEditAreaField(parent)
1342 self._add_field(
1343 line = 1,
1344 pos = 3,
1345 widget = self.fld_age_noted,
1346 weight = 2
1347 )
1348
1349
1350 self.fld_laterality_none= wx.RadioButton(parent, -1, _("N/A"))
1351 self.fld_laterality_left= wx.RadioButton(parent, -1, _("L"))
1352 self.fld_laterality_right= wx.RadioButton(parent, -1, _("R"))
1353 self.fld_laterality_both= wx.RadioButton(parent, -1, _("both"))
1354 self._add_field(
1355 line = 2,
1356 pos = 1,
1357 widget = self.fld_laterality_none,
1358 weight = 0
1359 )
1360 self._add_field(
1361 line = 2,
1362 pos = 2,
1363 widget = self.fld_laterality_left,
1364 weight = 0
1365 )
1366 self._add_field(
1367 line = 2,
1368 pos = 3,
1369 widget = self.fld_laterality_right,
1370 weight = 1
1371 )
1372 self._add_field(
1373 line = 2,
1374 pos = 4,
1375 widget = self.fld_laterality_both,
1376 weight = 1
1377 )
1378
1379 self.fld_condition= cEditAreaField(parent)
1380 self._add_field(
1381 line = 3,
1382 pos = 1,
1383 widget = self.fld_condition,
1384 weight = 6
1385 )
1386
1387 self.fld_notes= cEditAreaField(parent)
1388 self._add_field(
1389 line = 4,
1390 pos = 1,
1391 widget = self.fld_notes,
1392 weight = 6
1393 )
1394
1395 self.fld_significant= wx.CheckBox(
1396 parent,
1397 -1,
1398 _("significant"),
1399 style = wx.NO_BORDER
1400 )
1401 self.fld_active= wx.CheckBox(
1402 parent,
1403 -1,
1404 _("active"),
1405 style = wx.NO_BORDER
1406 )
1407
1408 self._add_field(
1409 line = 5,
1410 pos = 1,
1411 widget = self.fld_significant,
1412 weight = 0
1413 )
1414 self._add_field(
1415 line = 5,
1416 pos = 2,
1417 widget = self.fld_active,
1418 weight = 0
1419 )
1420
1421 self.fld_progress= cEditAreaField(parent)
1422 self._add_field(
1423 line = 6,
1424 pos = 1,
1425 widget = self.fld_progress,
1426 weight = 6
1427 )
1428
1429
1430 self._add_field(
1431 line = 7,
1432 pos = 4,
1433 widget = self._make_standard_buttons(parent),
1434 weight = 2
1435 )
1436
1437 - def _postInit(self):
1438 return
1439
1440 wx.EVT_KILL_FOCUS( self.fld_age_noted, self._ageKillFocus)
1441 wx.EVT_KILL_FOCUS( self.fld_date_noted, self._yearKillFocus)
1442
1443 - def _ageKillFocus( self, event):
1444
1445 event.Skip()
1446 try :
1447 year = self._getBirthYear() + int(self.fld_age_noted.GetValue().strip() )
1448 self.fld_date_noted.SetValue( str (year) )
1449 except:
1450 pass
1451
1452 - def _getBirthYear(self):
1453 try:
1454 birthyear = int(str(self._patient['dob']).split('-')[0])
1455 except:
1456
1457 birthyear = 1
1458
1459 return birthyear
1460
1461 - def _yearKillFocus( self, event):
1462 event.Skip()
1463 try:
1464 age = int(self.fld_date_noted.GetValue().strip() ) - self._getBirthYear()
1465 self.fld_age_noted.SetValue( str (age) )
1466 except:
1467 pass
1468
1469 __init_values = {
1470 "condition": "",
1471 "notes1": "",
1472 "notes2": "",
1473 "age": "",
1474
1475 "progress": "",
1476 "active": 1,
1477 "operation": 0,
1478 "confidential": 0,
1479 "significant": 1,
1480 "both": 0,
1481 "left": 0,
1482 "right": 0,
1483 "none" : 1
1484 }
1485
1486 - def _getDefaultAge(self):
1487 try:
1488
1489 return 1
1490 except:
1491 return 0
1492
1493 - def _get_init_values(self):
1494 values = gmPastHistoryEditArea.__init_values
1495 values["age"] = str( self._getDefaultAge())
1496 return values
1497
1498 - def _save_data(self):
1499 clinical = self._patient.get_emr().get_past_history()
1500 if self.getDataId() is None:
1501 id = clinical.create_history( self.get_fields_formatting_values() )
1502 self.setDataId(id)
1503 return
1504
1505 clinical.update_history( self.get_fields_formatting_values(), self.getDataId() )
1506
1507
1517
1519 self._add_prompt (line = 1, label = _ ("Specialty"))
1520 self._add_prompt (line = 2, label = _ ("Name"))
1521 self._add_prompt (line = 3, label = _ ("Address"))
1522 self._add_prompt (line = 4, label = _ ("Options"))
1523 self._add_prompt (line = 5, label = _("Text"), weight =6)
1524 self._add_prompt (line = 6, label = "")
1525
1527 self.fld_specialty = gmPhraseWheel.cPhraseWheel (
1528 parent = parent,
1529 id = -1,
1530 style = wx.SIMPLE_BORDER
1531 )
1532
1533 self._add_field (
1534 line = 1,
1535 pos = 1,
1536 widget = self.fld_specialty,
1537 weight = 1
1538 )
1539 self.fld_name = gmPhraseWheel.cPhraseWheel (
1540 parent = parent,
1541 id = -1,
1542 style = wx.SIMPLE_BORDER
1543 )
1544
1545 self._add_field (
1546 line = 2,
1547 pos = 1,
1548 widget = self.fld_name,
1549 weight = 1
1550 )
1551 self.fld_address = wx.ComboBox (parent, -1, style = wx.CB_READONLY)
1552
1553 self._add_field (
1554 line = 3,
1555 pos = 1,
1556 widget = self.fld_address,
1557 weight = 1
1558 )
1559
1560
1561 self.fld_name.add_callback_on_selection(self.setAddresses)
1562
1563 self.fld_med = wx.CheckBox (parent, -1, _("Meds"), style=wx.NO_BORDER)
1564 self._add_field (
1565 line = 4,
1566 pos = 1,
1567 widget = self.fld_med,
1568 weight = 1
1569 )
1570 self.fld_past = wx.CheckBox (parent, -1, _("Past Hx"), style=wx.NO_BORDER)
1571 self._add_field (
1572 line = 4,
1573 pos = 4,
1574 widget = self.fld_past,
1575 weight = 1
1576 )
1577 self.fld_text = wx.TextCtrl (parent, -1, style= wx.TE_MULTILINE)
1578 self._add_field (
1579 line = 5,
1580 pos = 1,
1581 widget = self.fld_text,
1582 weight = 1)
1583
1584 self._add_field(
1585 line = 6,
1586 pos = 1,
1587 widget = self._make_standard_buttons(parent),
1588 weight = 1
1589 )
1590 return 1
1591
1593 """
1594 Doesn't accept any value as this doesn't make sense for this edit area
1595 """
1596 self.fld_specialty.SetValue ('')
1597 self.fld_name.SetValue ('')
1598 self.fld_address.Clear ()
1599 self.fld_address.SetValue ('')
1600 self.fld_med.SetValue (0)
1601 self.fld_past.SetValue (0)
1602 self.fld_text.SetValue ('')
1603 self.recipient = None
1604
1606 """
1607 Set the available addresses for the selected identity
1608 """
1609 if id is None:
1610 self.recipient = None
1611 self.fld_address.Clear ()
1612 self.fld_address.SetValue ('')
1613 else:
1614 self.recipient = gmDemographicRecord.cDemographicRecord_SQL (id)
1615 self.fld_address.Clear ()
1616 self.addr = self.recipient.getAddresses ('work')
1617 for i in self.addr:
1618 self.fld_address.Append (_("%(number)s %(street)s, %(urb)s %(postcode)s") % i, ('post', i))
1619 fax = self.recipient.getCommChannel (gmDemographicRecord.FAX)
1620 email = self.recipient.getCommChannel (gmDemographicRecord.EMAIL)
1621 if fax:
1622 self.fld_address.Append ("%s: %s" % (_("FAX"), fax), ('fax', fax))
1623 if email:
1624 self.fld_address.Append ("%s: %s" % (_("E-MAIL"), email), ('email', email))
1625
1626 - def _save_new_entry(self):
1627 """
1628 We are always saving a "new entry" here because data_ID is always None
1629 """
1630 if not self.recipient:
1631 raise gmExceptions.InvalidInputError(_('must have a recipient'))
1632 if self.fld_address.GetSelection() == -1:
1633 raise gmExceptions.InvalidInputError(_('must select address'))
1634 channel, addr = self.fld_address.GetClientData (self.fld_address.GetSelection())
1635 text = self.fld_text.GetValue()
1636 flags = {}
1637 flags['meds'] = self.fld_med.GetValue()
1638 flags['pasthx'] = self.fld_past.GetValue()
1639 if not gmReferral.create_referral (self._patient, self.recipient, channel, addr, text, flags):
1640 raise gmExceptions.InvalidInputError('error sending form')
1641
1642
1643
1644
1645
1653
1654
1655
1657 _log.debug("making prescription lines")
1658 lines = []
1659 self.txt_problem = cEditAreaField(parent)
1660 self.txt_class = cEditAreaField(parent)
1661 self.txt_generic = cEditAreaField(parent)
1662 self.txt_brand = cEditAreaField(parent)
1663 self.txt_strength= cEditAreaField(parent)
1664 self.txt_directions= cEditAreaField(parent)
1665 self.txt_for = cEditAreaField(parent)
1666 self.txt_progress = cEditAreaField(parent)
1667
1668 lines.append(self.txt_problem)
1669 lines.append(self.txt_class)
1670 lines.append(self.txt_generic)
1671 lines.append(self.txt_brand)
1672 lines.append(self.txt_strength)
1673 lines.append(self.txt_directions)
1674 lines.append(self.txt_for)
1675 lines.append(self.txt_progress)
1676 lines.append(self._make_standard_buttons(parent))
1677 self.input_fields = {
1678 "problem": self.txt_problem,
1679 "class" : self.txt_class,
1680 "generic" : self.txt_generic,
1681 "brand" : self.txt_brand,
1682 "strength": self.txt_strength,
1683 "directions": self.txt_directions,
1684 "for" : self.txt_for,
1685 "progress": self.txt_progress
1686
1687 }
1688
1689 return self._makeExtraColumns( parent, lines)
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1708
1709
1710
1711
1712
1713
1716 wx.StaticText.__init__(self, parent, id, prompt, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_LEFT)
1717 self.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
1718 self.SetForegroundColour(aColor)
1719
1720
1721
1722
1723
1725 - def __init__(self, parent, id, prompt_labels):
1726 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
1727 self.SetBackgroundColour(richards_light_gray)
1728 gszr = wx.GridSizer (len(prompt_labels)+1, 1, 2, 2)
1729 color = richards_aqua
1730 for prompt_key in prompt_labels.keys():
1731 label = cPrompt_edit_area(self, -1, " %s" % prompt_labels[prompt_key], aColor = color)
1732 gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT)
1733 color = richards_blue
1734 self.SetSizer(gszr)
1735 gszr.Fit(self)
1736 self.SetAutoLayout(True)
1737
1738
1739
1740
1741
1742
1743
1744 -class EditTextBoxes(wx.Panel):
1745 - def __init__(self, parent, id, editareaprompts, section):
1746 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize,style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
1747 self.SetBackgroundColour(wx.Colour(222,222,222))
1748 self.parent = parent
1749
1750 self.gszr = wx.GridSizer(len(editareaprompts), 1, 2, 2)
1751
1752 if section == gmSECTION_SUMMARY:
1753 pass
1754 elif section == gmSECTION_DEMOGRAPHICS:
1755 pass
1756 elif section == gmSECTION_CLINICALNOTES:
1757 pass
1758 elif section == gmSECTION_FAMILYHISTORY:
1759 pass
1760 elif section == gmSECTION_PASTHISTORY:
1761 pass
1762
1763
1764 self.txt_condition = cEditAreaField(self,PHX_CONDITION,wx.DefaultPosition,wx.DefaultSize)
1765 self.rb_sideleft = wxRadioButton(self,PHX_LEFT, _(" (L) "), wx.DefaultPosition,wx.DefaultSize)
1766 self.rb_sideright = wxRadioButton(self, PHX_RIGHT, _("(R)"), wx.DefaultPosition,wx.DefaultSize,wx.SUNKEN_BORDER)
1767 self.rb_sideboth = wxRadioButton(self, PHX_BOTH, _("Both"), wx.DefaultPosition,wx.DefaultSize)
1768 rbsizer = wx.BoxSizer(wx.HORIZONTAL)
1769 rbsizer.Add(self.rb_sideleft,1,wx.EXPAND)
1770 rbsizer.Add(self.rb_sideright,1,wx.EXPAND)
1771 rbsizer.Add(self.rb_sideboth,1,wx.EXPAND)
1772 szr1 = wx.BoxSizer(wx.HORIZONTAL)
1773 szr1.Add(self.txt_condition, 4, wx.EXPAND)
1774 szr1.Add(rbsizer, 3, wx.EXPAND)
1775
1776
1777
1778
1779 self.txt_notes1 = cEditAreaField(self,PHX_NOTES,wx.DefaultPosition,wx.DefaultSize)
1780
1781 self.txt_notes2= cEditAreaField(self,PHX_NOTES2,wx.DefaultPosition,wx.DefaultSize)
1782
1783 self.txt_agenoted = cEditAreaField(self, PHX_AGE, wx.DefaultPosition, wx.DefaultSize)
1784 szr4 = wx.BoxSizer(wx.HORIZONTAL)
1785 szr4.Add(self.txt_agenoted, 1, wx.EXPAND)
1786 szr4.Add(5, 0, 5)
1787
1788 self.txt_yearnoted = cEditAreaField(self,PHX_YEAR,wx.DefaultPosition,wx.DefaultSize)
1789 szr5 = wx.BoxSizer(wx.HORIZONTAL)
1790 szr5.Add(self.txt_yearnoted, 1, wx.EXPAND)
1791 szr5.Add(5, 0, 5)
1792
1793 self.parent.cb_active = wx.CheckBox(self, PHX_ACTIVE, _("Active"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1794 self.parent.cb_operation = wx.CheckBox(self, PHX_OPERATION, _("Operation"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1795 self.parent.cb_confidential = wx.CheckBox(self, PHX_CONFIDENTIAL , _("Confidential"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1796 self.parent.cb_significant = wx.CheckBox(self, PHX_SIGNIFICANT, _("Significant"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1797 szr6 = wx.BoxSizer(wx.HORIZONTAL)
1798 szr6.Add(self.parent.cb_active, 1, wx.EXPAND)
1799 szr6.Add(self.parent.cb_operation, 1, wx.EXPAND)
1800 szr6.Add(self.parent.cb_confidential, 1, wx.EXPAND)
1801 szr6.Add(self.parent.cb_significant, 1, wx.EXPAND)
1802
1803 self.txt_progressnotes = cEditAreaField(self,PHX_PROGRESSNOTES ,wx.DefaultPosition,wx.DefaultSize)
1804
1805 szr8 = wx.BoxSizer(wx.HORIZONTAL)
1806 szr8.Add(5, 0, 6)
1807 szr8.Add(self._make_standard_buttons(), 0, wx.EXPAND)
1808
1809 self.gszr.Add(szr1,0,wx.EXPAND)
1810 self.gszr.Add(self.txt_notes1,0,wx.EXPAND)
1811 self.gszr.Add(self.txt_notes2,0,wx.EXPAND)
1812 self.gszr.Add(szr4,0,wx.EXPAND)
1813 self.gszr.Add(szr5,0,wx.EXPAND)
1814 self.gszr.Add(szr6,0,wx.EXPAND)
1815 self.gszr.Add(self.txt_progressnotes,0,wx.EXPAND)
1816 self.gszr.Add(szr8,0,wx.EXPAND)
1817
1818
1819 elif section == gmSECTION_SCRIPT:
1820 pass
1821 elif section == gmSECTION_REQUESTS:
1822 pass
1823 elif section == gmSECTION_RECALLS:
1824 pass
1825 else:
1826 pass
1827
1828 self.SetSizer(self.gszr)
1829 self.gszr.Fit(self)
1830
1831 self.SetAutoLayout(True)
1832 self.Show(True)
1833
1835 self.btn_OK = wx.Button(self, -1, _("Ok"))
1836 self.btn_Clear = wx.Button(self, -1, _("Clear"))
1837 szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
1838 szr_buttons.Add(self.btn_OK, 1, wx.EXPAND, wx.ALL, 1)
1839 szr_buttons.Add(5, 0, 0)
1840 szr_buttons.Add(self.btn_Clear, 1, wx.EXPAND, wx.ALL, 1)
1841 return szr_buttons
1842
1844 - def __init__(self, parent, id, line_labels, section):
1845 _log.warning('***** old style EditArea instantiated, please convert *****')
1846
1847 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, style = wx.NO_BORDER)
1848 self.SetBackgroundColour(wx.Colour(222,222,222))
1849
1850
1851 prompts = gmPnlEditAreaPrompts(self, -1, line_labels)
1852
1853 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1854
1855 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
1856 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
1857 szr_shadow_below_prompts.Add(5,0,0,wx.EXPAND)
1858 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
1859
1860 szr_prompts = wx.BoxSizer(wx.VERTICAL)
1861 szr_prompts.Add(prompts, 97, wx.EXPAND)
1862 szr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
1863
1864
1865 edit_fields = EditTextBoxes(self, -1, line_labels, section)
1866
1867 shadow_below_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1868
1869 shadow_below_editarea.SetBackgroundColour(richards_coloured_gray)
1870 szr_shadow_below_editarea = wx.BoxSizer(wx.HORIZONTAL)
1871 szr_shadow_below_editarea.Add(5,0,0,wx.EXPAND)
1872 szr_shadow_below_editarea.Add(shadow_below_editarea, 12, wx.EXPAND)
1873
1874 szr_editarea = wx.BoxSizer(wx.VERTICAL)
1875 szr_editarea.Add(edit_fields, 92, wx.EXPAND)
1876 szr_editarea.Add(szr_shadow_below_editarea, 5, wx.EXPAND)
1877
1878
1879
1880 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1881 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
1882 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
1883 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
1884 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND)
1885
1886 shadow_rightof_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1887 shadow_rightof_editarea.SetBackgroundColour(richards_coloured_gray)
1888 szr_shadow_rightof_editarea = wx.BoxSizer(wx.VERTICAL)
1889 szr_shadow_rightof_editarea.Add(0, 5, 0, wx.EXPAND)
1890 szr_shadow_rightof_editarea.Add(shadow_rightof_editarea, 1, wx.EXPAND)
1891
1892
1893 self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL)
1894 self.szr_main_panels.Add(szr_prompts, 10, wx.EXPAND)
1895 self.szr_main_panels.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
1896 self.szr_main_panels.Add(5, 0, 0, wx.EXPAND)
1897 self.szr_main_panels.Add(szr_editarea, 89, wx.EXPAND)
1898 self.szr_main_panels.Add(szr_shadow_rightof_editarea, 1, wx.EXPAND)
1899
1900
1901
1902 self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL)
1903 self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5)
1904 self.SetSizer(self.szr_central_container)
1905 self.szr_central_container.Fit(self)
1906 self.SetAutoLayout(True)
1907 self.Show(True)
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
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 if __name__ == "__main__":
2185
2186
2191 self._add_prompt(line=1, label='line 1')
2192 self._add_prompt(line=2, label='buttons')
2194
2195 self.fld_substance = cEditAreaField(parent)
2196 self._add_field(
2197 line = 1,
2198 pos = 1,
2199 widget = self.fld_substance,
2200 weight = 1
2201 )
2202
2203 self._add_field(
2204 line = 2,
2205 pos = 1,
2206 widget = self._make_standard_buttons(parent),
2207 weight = 1
2208 )
2209
2210 app = wxPyWidgetTester(size = (400, 200))
2211 app.SetWidget(cTestEditArea)
2212 app.MainLoop()
2213
2214
2215
2216
2217
2218
2219
2220