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
144
145
148
150 if mode not in edit_area_modes:
151 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
152 if mode == 'edit':
153 if self.__data is None:
154 raise ValueError('[%s] <mode> "edit" needs data value' % self.__class__.__name__)
155
156 prev_mode = self.__mode
157 self.__mode = mode
158 if mode != prev_mode:
159 self.refresh()
160
161 mode = property(_get_mode, _set_mode)
162
165
167 if data is None:
168 if self.__mode == 'edit':
169 raise ValueError('[%s] <mode> "edit" needs data value' % self.__class__.__name__)
170 self.__data = data
171 self.refresh()
172
173 data = property(_get_data, _set_data)
174
177
178 status_message = property(lambda x:x, show_msg)
179
180
181
183 """Invoked from the generic edit area dialog.
184
185 Invokes
186 _valid_for_save,
187 _save_as_new,
188 _save_as_update
189 on the implementing edit area as needed.
190
191 _save_as_* must set self.__data and return True/False
192 """
193 if not self._valid_for_save():
194 return False
195
196
197 gmDispatcher.send(signal = 'statustext', msg = u'')
198
199 if self.__mode in ['new', 'new_from_existing']:
200 if self._save_as_new():
201 self.mode = 'edit'
202 return True
203 return False
204
205 elif self.__mode == 'edit':
206 return self._save_as_update()
207
208 else:
209 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
210
212 """Invoked from the generic edit area dialog.
213
214 Invokes
215 _refresh_as_new()
216 _refresh_from_existing()
217 _refresh_as_new_from_existing()
218 on the implementing edit area as needed.
219
220 Then calls _valid_for_save().
221 """
222 if self.__mode == 'new':
223 result = self._refresh_as_new()
224 self._valid_for_save()
225 return result
226 elif self.__mode == 'edit':
227 result = self._refresh_from_existing()
228 return result
229 elif self.__mode == 'new_from_existing':
230 result = self._refresh_as_new_from_existing()
231 self._valid_for_save()
232 return result
233 else:
234 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
235
238
240 ctrl.SetBackgroundColour(self.__tctrl_validity_colors[valid])
241 ctrl.Refresh()
242
243
244 from Gnumed.wxGladeWidgets import wxgGenericEditAreaDlg2
245
247 """Dialog for parenting edit area panels with save/clear/next/cancel"""
248
249 _lucky_day = 1
250 _lucky_month = 4
251 _today = pydt.date.today()
252
254
255 new_ea = kwargs['edit_area']
256 del kwargs['edit_area']
257
258 if not isinstance(new_ea, cGenericEditAreaMixin):
259 raise TypeError('[%s]: edit area instance must be child of cGenericEditAreaMixin')
260
261 try:
262 single_entry = kwargs['single_entry']
263 del kwargs['single_entry']
264 except KeyError:
265 single_entry = False
266
267 wxgGenericEditAreaDlg2.wxgGenericEditAreaDlg2.__init__(self, *args, **kwargs)
268
269 self.left_extra_button = None
270
271 if cGenericEditAreaDlg2._today.day != cGenericEditAreaDlg2._lucky_day:
272 self._BTN_lucky.Enable(False)
273 self._BTN_lucky.Hide()
274 else:
275 if cGenericEditAreaDlg2._today.month != cGenericEditAreaDlg2._lucky_month:
276 self._BTN_lucky.Enable(False)
277 self._BTN_lucky.Hide()
278
279
280 dummy_ea_pnl = self._PNL_ea
281 ea_pnl_szr = dummy_ea_pnl.GetContainingSizer()
282 ea_pnl_parent = dummy_ea_pnl.GetParent()
283 ea_pnl_szr.Remove(dummy_ea_pnl)
284 dummy_ea_pnl.Destroy()
285 del dummy_ea_pnl
286 new_ea_min_size = new_ea.GetMinSize()
287 new_ea.Reparent(ea_pnl_parent)
288 self._PNL_ea = new_ea
289 ea_pnl_szr.Add(self._PNL_ea, 1, wx.EXPAND, 0)
290 ea_pnl_szr.SetMinSize(new_ea_min_size)
291 ea_pnl_szr.Fit(new_ea)
292
293
294 if single_entry:
295 self._BTN_forward.Enable(False)
296 self._BTN_forward.Hide()
297
298 self._adjust_clear_revert_buttons()
299
300
301 self._TCTRL_status.SetValue('')
302 gmDispatcher.connect(signal = u'statustext', receiver = self._on_set_statustext)
303
304
305
306 main_szr = self.GetSizer()
307 main_szr.Fit(self)
308 self.Layout()
309
310
311 self._PNL_ea.refresh()
312
313 - def _on_set_statustext(self, msg=None, loglevel=None, beep=True):
314 if msg is None:
315 self._TCTRL_status.SetValue('')
316 return
317 if msg.strip() == u'':
318 self._TCTRL_status.SetValue('')
319 return
320 self._TCTRL_status.SetValue(msg)
321 return
322
334
342
345
348
363
374
383
384
385
401
402 left_extra_button = property(lambda x:x, _set_left_extra_button)
403
404
405
406
407
408
409
410 from Gnumed.pycommon import gmGuiBroker
411
412
413 _gb = gmGuiBroker.GuiBroker()
414
415 gmSECTION_SUMMARY = 1
416 gmSECTION_DEMOGRAPHICS = 2
417 gmSECTION_CLINICALNOTES = 3
418 gmSECTION_FAMILYHISTORY = 4
419 gmSECTION_PASTHISTORY = 5
420 gmSECTION_SCRIPT = 8
421 gmSECTION_REQUESTS = 9
422 gmSECTION_REFERRALS = 11
423 gmSECTION_RECALLS = 12
424
425 richards_blue = wx.Colour(0,0,131)
426 richards_aqua = wx.Colour(0,194,197)
427 richards_dark_gray = wx.Colour(131,129,131)
428 richards_light_gray = wx.Colour(255,255,255)
429 richards_coloured_gray = wx.Colour(131,129,131)
430
431
432 CONTROLS_WITHOUT_LABELS =['wxTextCtrl', 'cEditAreaField', 'wx.SpinCtrl', 'gmPhraseWheel', 'wx.ComboBox']
433
435 widget.SetForegroundColour(wx.Colour(255, 0, 0))
436 widget.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
437
450 if not isinstance(edit_area, cEditArea2):
451 raise TypeError('<edit_area> must be of type cEditArea2 but is <%s>' % type(edit_area))
452 wx.Dialog.__init__(self, parent, id, title, pos, size, style, name)
453 self.__wxID_BTN_SAVE = wx.NewId()
454 self.__wxID_BTN_RESET = wx.NewId()
455 self.__editarea = edit_area
456 self.__do_layout()
457 self.__register_events()
458
459
460
463
465 self.__editarea.Reparent(self)
466
467 self.__btn_SAVE = wx.Button(self, self.__wxID_BTN_SAVE, _("Save"))
468 self.__btn_SAVE.SetToolTipString(_('save entry into medical record'))
469 self.__btn_RESET = wx.Button(self, self.__wxID_BTN_RESET, _("Reset"))
470 self.__btn_RESET.SetToolTipString(_('reset entry'))
471 self.__btn_CANCEL = wx.Button(self, wx.ID_CANCEL, _("Cancel"))
472 self.__btn_CANCEL.SetToolTipString(_('discard entry and cancel'))
473
474 szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
475 szr_buttons.Add(self.__btn_SAVE, 1, wx.EXPAND | wx.ALL, 1)
476 szr_buttons.Add(self.__btn_RESET, 1, wx.EXPAND | wx.ALL, 1)
477 szr_buttons.Add(self.__btn_CANCEL, 1, wx.EXPAND | wx.ALL, 1)
478
479 szr_main = wx.BoxSizer(wx.VERTICAL)
480 szr_main.Add(self.__editarea, 1, wx.EXPAND)
481 szr_main.Add(szr_buttons, 0, wx.EXPAND)
482
483 self.SetSizerAndFit(szr_main)
484
485
486
488
489 wx.EVT_BUTTON(self.__btn_SAVE, self.__wxID_BTN_SAVE, self._on_SAVE_btn_pressed)
490 wx.EVT_BUTTON(self.__btn_RESET, self.__wxID_BTN_RESET, self._on_RESET_btn_pressed)
491 wx.EVT_BUTTON(self.__btn_CANCEL, wx.ID_CANCEL, self._on_CANCEL_btn_pressed)
492
493 wx.EVT_CLOSE(self, self._on_CANCEL_btn_pressed)
494
495
496
497
498
499
500 return 1
501
503 if self.__editarea.save_data():
504 self.__editarea.Close()
505 self.EndModal(wx.ID_OK)
506 return
507 short_err = self.__editarea.get_short_error()
508 long_err = self.__editarea.get_long_error()
509 if (short_err is None) and (long_err is None):
510 long_err = _(
511 'Unspecified error saving data in edit area.\n\n'
512 'Programmer forgot to specify proper error\n'
513 'message in [%s].'
514 ) % self.__editarea.__class__.__name__
515 if short_err is not None:
516 gmDispatcher.send(signal = 'statustext', msg = short_err)
517 if long_err is not None:
518 gmGuiHelpers.gm_show_error(long_err, _('saving clinical data'))
519
521 self.__editarea.Close()
522 self.EndModal(wx.ID_CANCEL)
523
526
528 - def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TAB_TRAVERSAL):
529
530 wx.Panel.__init__ (
531 self,
532 parent,
533 id,
534 pos = pos,
535 size = size,
536 style = style | wx.TAB_TRAVERSAL
537 )
538 self.SetBackgroundColour(wx.Colour(222,222,222))
539
540 self.data = None
541 self.fields = {}
542 self.prompts = {}
543 self._short_error = None
544 self._long_error = None
545 self._summary = None
546 self._patient = gmPerson.gmCurrentPatient()
547 self.__wxID_BTN_OK = wx.NewId()
548 self.__wxID_BTN_CLEAR = wx.NewId()
549 self.__do_layout()
550 self.__register_events()
551 self.Show()
552
553
554
556 """This needs to be overridden by child classes."""
557 self._long_error = _(
558 'Cannot save data from edit area.\n\n'
559 'Programmer forgot to override method:\n'
560 ' <%s.save_data>'
561 ) % self.__class__.__name__
562 return False
563
565 msg = _(
566 'Cannot reset fields in edit area.\n\n'
567 'Programmer forgot to override method:\n'
568 ' <%s.reset_ui>'
569 ) % self.__class__.__name__
570 gmGuiHelpers.gm_show_error(msg)
571
573 tmp = self._short_error
574 self._short_error = None
575 return tmp
576
578 tmp = self._long_error
579 self._long_error = None
580 return tmp
581
583 return _('<No embed string for [%s]>') % self.__class__.__name__
584
585
586
598
603
604
605
607 self.__deregister_events()
608 event.Skip()
609
611 """Only active if _make_standard_buttons was called in child class."""
612
613 try:
614 event.Skip()
615 if self.data is None:
616 self._save_new_entry()
617 self.reset_ui()
618 else:
619 self._save_modified_entry()
620 self.reset_ui()
621 except gmExceptions.InvalidInputError, err:
622
623
624 gmGuiHelpers.gm_show_error (err, _("Invalid Input"))
625 except:
626 _log.exception( "save data problem in [%s]" % self.__class__.__name__)
627
629 """Only active if _make_standard_buttons was called in child class."""
630
631 self.reset_ui()
632 event.Skip()
633
635 self.__deregister_events()
636
637 if not self._patient.connected:
638 return True
639
640
641
642
643 return True
644 _log.error('[%s] lossage' % self.__class__.__name__)
645 return False
646
648 """Just before new patient becomes active."""
649
650 if not self._patient.connected:
651 return True
652
653
654
655
656 return True
657 _log.error('[%s] lossage' % self.__class__.__name__)
658 return False
659
661 """Just after new patient became active."""
662
663 self.reset_ui()
664
665
666
668
669
670 self._define_prompts()
671 self._define_fields(parent = self)
672 if len(self.fields) != len(self.prompts):
673 _log.error('[%s]: #fields != #prompts' % self.__class__.__name__)
674 return None
675
676
677 szr_main_fgrid = wx.FlexGridSizer(rows = len(self.prompts), cols=2)
678 color = richards_aqua
679 lines = self.prompts.keys()
680 lines.sort()
681 for line in lines:
682
683 label, color, weight = self.prompts[line]
684
685 prompt = wx.StaticText (
686 parent = self,
687 id = -1,
688 label = label,
689 style = wx.ALIGN_CENTRE
690 )
691
692 prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
693 prompt.SetForegroundColour(color)
694 prompt.SetBackgroundColour(richards_light_gray)
695 szr_main_fgrid.Add(prompt, flag=wx.EXPAND | wx.ALIGN_RIGHT)
696
697
698 szr_line = wx.BoxSizer(wx.HORIZONTAL)
699 positions = self.fields[line].keys()
700 positions.sort()
701 for pos in positions:
702 field, weight = self.fields[line][pos]
703
704 szr_line.Add(field, weight, wx.EXPAND)
705 szr_main_fgrid.Add(szr_line, flag=wx.GROW | wx.ALIGN_LEFT)
706
707
708 szr_main_fgrid.AddGrowableCol(1)
709
710
711
712
713
714
715
716 self.SetSizerAndFit(szr_main_fgrid)
717
718
719
720
722 """Child classes override this to define their prompts using _add_prompt()"""
723 _log.error('missing override in [%s]' % self.__class__.__name__)
724
726 """Add a new prompt line.
727
728 To be used from _define_fields in child classes.
729
730 - label, the label text
731 - color
732 - weight, the weight given in sizing the various rows. 0 means the row
733 always has minimum size
734 """
735 self.prompts[line] = (label, color, weight)
736
738 """Defines the fields.
739
740 - override in child classes
741 - mostly uses _add_field()
742 """
743 _log.error('missing override in [%s]' % self.__class__.__name__)
744
745 - def _add_field(self, line=None, pos=None, widget=None, weight=0):
746 if None in (line, pos, widget):
747 _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget))
748 if not self.fields.has_key(line):
749 self.fields[line] = {}
750 self.fields[line][pos] = (widget, weight)
751
769
770
771
772
774 - def __init__ (self, parent, id = -1, pos = wx.DefaultPosition, size=wx.DefaultSize):
775 wx.TextCtrl.__init__(self,parent,id,"",pos, size ,wx.SIMPLE_BORDER)
776 _decorate_editarea_field(self)
777
779 - def __init__(self, parent, id, pos, size, style):
780
781 print "class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__
782
783
784 wx.Panel.__init__(self, parent, id, pos=pos, size=size, style=wx.NO_BORDER | wx.TAB_TRAVERSAL)
785 self.SetBackgroundColour(wx.Colour(222,222,222))
786
787 self.data = None
788 self.fields = {}
789 self.prompts = {}
790
791 ID_BTN_OK = wx.NewId()
792 ID_BTN_CLEAR = wx.NewId()
793
794 self.__do_layout()
795
796
797
798
799
800
801 self._patient = gmPerson.gmCurrentPatient()
802 self.__register_events()
803 self.Show(True)
804
805
806
808
809 self._define_prompts()
810 self.fields_pnl = wx.Panel(self, -1, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
811 self._define_fields(parent = self.fields_pnl)
812
813 szr_prompts = self.__generate_prompts()
814 szr_fields = self.__generate_fields()
815
816
817 self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL)
818 self.szr_main_panels.Add(szr_prompts, 11, wx.EXPAND)
819 self.szr_main_panels.Add(5, 0, 0, wx.EXPAND)
820 self.szr_main_panels.Add(szr_fields, 90, wx.EXPAND)
821
822
823
824 self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL)
825 self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5)
826
827
828 self.SetAutoLayout(True)
829 self.SetSizer(self.szr_central_container)
830 self.szr_central_container.Fit(self)
831
833 if len(self.fields) != len(self.prompts):
834 _log.error('[%s]: #fields != #prompts' % self.__class__.__name__)
835 return None
836
837 prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
838 prompt_pnl.SetBackgroundColour(richards_light_gray)
839
840 color = richards_aqua
841 lines = self.prompts.keys()
842 lines.sort()
843 self.prompt_widget = {}
844 for line in lines:
845 label, color, weight = self.prompts[line]
846 self.prompt_widget[line] = self.__make_prompt(prompt_pnl, "%s " % label, color)
847
848 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
849 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
850 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
851 szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND)
852 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
853
854
855 vszr_prompts = wx.BoxSizer(wx.VERTICAL)
856 vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND)
857 vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
858
859
860 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
861 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
862 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
863 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
864 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts, 1, wx.EXPAND)
865
866
867 hszr_prompts = wx.BoxSizer(wx.HORIZONTAL)
868 hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND)
869 hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
870
871 return hszr_prompts
872
874 self.fields_pnl.SetBackgroundColour(wx.Colour(222,222,222))
875
876 vszr = wx.BoxSizer(wx.VERTICAL)
877 lines = self.fields.keys()
878 lines.sort()
879 self.field_line_szr = {}
880 for line in lines:
881 self.field_line_szr[line] = wx.BoxSizer(wx.HORIZONTAL)
882 positions = self.fields[line].keys()
883 positions.sort()
884 for pos in positions:
885 field, weight = self.fields[line][pos]
886 self.field_line_szr[line].Add(field, weight, wx.EXPAND)
887 try:
888 vszr.Add(self.field_line_szr[line], self.prompts[line][2], flag = wx.EXPAND)
889 except KeyError:
890 _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) ) )
891
892 self.fields_pnl.SetSizer(vszr)
893 vszr.Fit(self.fields_pnl)
894
895
896 shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
897 shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray)
898 szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
899 szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND)
900 szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND)
901
902
903 vszr_edit_fields = wx.BoxSizer(wx.VERTICAL)
904 vszr_edit_fields.Add(self.fields_pnl, 92, wx.EXPAND)
905 vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND)
906
907
908 shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
909 shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray)
910 szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL)
911 szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND)
912 szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND)
913
914
915 hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
916 hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND)
917 hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND)
918
919 return hszr_edit_fields
920
922
923 prompt = wx.StaticText(
924 parent,
925 -1,
926 aLabel,
927 style = wx.ALIGN_RIGHT
928 )
929 prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
930 prompt.SetForegroundColour(aColor)
931 return prompt
932
933
934
936 """Add a new prompt line.
937
938 To be used from _define_fields in child classes.
939
940 - label, the label text
941 - color
942 - weight, the weight given in sizing the various rows. 0 means the rwo
943 always has minimum size
944 """
945 self.prompts[line] = (label, color, weight)
946
947 - def _add_field(self, line=None, pos=None, widget=None, weight=0):
948 if None in (line, pos, widget):
949 _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget))
950 if not self.fields.has_key(line):
951 self.fields[line] = {}
952 self.fields[line][pos] = (widget, weight)
953
955 """Defines the fields.
956
957 - override in child classes
958 - mostly uses _add_field()
959 """
960 _log.error('missing override in [%s]' % self.__class__.__name__)
961
963 _log.error('missing override in [%s]' % self.__class__.__name__)
964
978
981
983 _log.error('[%s] programmer forgot to define _save_data()' % self.__class__.__name__)
984 _log.info('child classes of cEditArea *must* override this function')
985 return False
986
987
988
990
991 wx.EVT_BUTTON(self.btn_OK, ID_BTN_OK, self._on_OK_btn_pressed)
992 wx.EVT_BUTTON(self.btn_Clear, ID_BTN_CLEAR, self._on_clear_btn_pressed)
993
994 wx.EVT_SIZE (self.fields_pnl, self._on_resize_fields)
995
996
997 gmDispatcher.connect(signal = u'pre_patient_selection', receiver = self._on_pre_patient_selection)
998 gmDispatcher.connect(signal = u'application_closing', receiver = self._on_application_closing)
999 gmDispatcher.connect(signal = u'post_patient_selection', receiver = self.on_post_patient_selection)
1000
1001 return 1
1002
1003
1004
1021
1026
1027 - def on_post_patient_selection( self, **kwds):
1028
1029 self.set_data()
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
1042 if not self._patient.connected:
1043 return True
1044 if self._save_data():
1045 return True
1046 _log.error('[%s] lossage' % self.__class__.__name__)
1047 return False
1048
1050 self.fields_pnl.Layout()
1051
1052 for i in self.field_line_szr.keys():
1053
1054 pos = self.field_line_szr[i].GetPosition()
1055
1056 self.prompt_widget[i].SetPosition((0, pos.y))
1057
1059 - def __init__(self, parent, id, aType = None):
1060
1061 print "class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__
1062
1063
1064 if aType not in _known_edit_area_types:
1065 _log.error('unknown edit area type: [%s]' % aType)
1066 raise gmExceptions.ConstructorError, 'unknown edit area type: [%s]' % aType
1067 self._type = aType
1068
1069
1070 cEditArea.__init__(self, parent, id)
1071
1072 self.input_fields = {}
1073
1074 self._postInit()
1075 self.old_data = {}
1076
1077 self._patient = gmPerson.gmCurrentPatient()
1078 self.Show(True)
1079
1080
1081
1082
1083
1084
1086
1087 prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
1088 prompt_pnl.SetBackgroundColour(richards_light_gray)
1089
1090 gszr = wx.FlexGridSizer (len(prompt_labels)+1, 1, 2, 2)
1091 color = richards_aqua
1092 for prompt in prompt_labels:
1093 label = self.__make_prompt(prompt_pnl, "%s " % prompt, color)
1094 gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT)
1095 color = richards_blue
1096 gszr.RemoveGrowableRow (line-1)
1097
1098 prompt_pnl.SetSizer(gszr)
1099 gszr.Fit(prompt_pnl)
1100 prompt_pnl.SetAutoLayout(True)
1101
1102
1103 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1104 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
1105 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
1106 szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND)
1107 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
1108
1109
1110 vszr_prompts = wx.BoxSizer(wx.VERTICAL)
1111 vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND)
1112 vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
1113
1114
1115 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1116 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
1117 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
1118 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
1119 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND)
1120
1121
1122 hszr_prompts = wx.BoxSizer(wx.HORIZONTAL)
1123 hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND)
1124 hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
1125
1126 return hszr_prompts
1127
1129 _log.error('programmer forgot to define edit area lines for [%s]' % self._type)
1130 _log.info('child classes of gmEditArea *must* override this function')
1131 return []
1132
1134
1135 fields_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
1136 fields_pnl.SetBackgroundColour(wx.Colour(222,222,222))
1137
1138 gszr = wx.GridSizer(len(_prompt_defs[self._type]), 1, 2, 2)
1139
1140
1141 lines = self._make_edit_lines(parent = fields_pnl)
1142
1143 self.lines = lines
1144 if len(lines) != len(_prompt_defs[self._type]):
1145 _log.error('#(edit lines) not equal #(prompts) for [%s], something is fishy' % self._type)
1146 for line in lines:
1147 gszr.Add(line, 0, wx.EXPAND | wx.ALIGN_LEFT)
1148
1149 fields_pnl.SetSizer(gszr)
1150 gszr.Fit(fields_pnl)
1151 fields_pnl.SetAutoLayout(True)
1152
1153
1154 shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1155 shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray)
1156 szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
1157 szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND)
1158 szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND)
1159
1160
1161 vszr_edit_fields = wx.BoxSizer(wx.VERTICAL)
1162 vszr_edit_fields.Add(fields_pnl, 92, wx.EXPAND)
1163 vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND)
1164
1165
1166 shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1167 shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray)
1168 szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL)
1169 szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND)
1170 szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND)
1171
1172
1173 hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
1174 hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND)
1175 hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND)
1176
1177 return hszr_edit_fields
1178
1181
1186
1188 map = {}
1189 for k in self.input_fields.keys():
1190 map[k] = ''
1191 return map
1192
1193
1195 self._default_init_fields()
1196
1197
1198
1199
1200
1202 _log.warning("you may want to override _updateUI for [%s]" % self.__class__.__name__)
1203
1204
1205 - def _postInit(self):
1206 """override for further control setup"""
1207 pass
1208
1209
1211 szr = wx.BoxSizer(wx.HORIZONTAL)
1212 szr.Add( widget, weight, wx.EXPAND)
1213 szr.Add( 0,0, spacerWeight, wx.EXPAND)
1214 return szr
1215
1217
1218 cb = wx.CheckBox( parent, -1, _(title))
1219 cb.SetForegroundColour( richards_blue)
1220 return cb
1221
1222
1223
1225 """this is a utlity method to add extra columns"""
1226
1227 if self.__class__.__dict__.has_key("extraColumns"):
1228 for x in self.__class__.extraColumns:
1229 lines = self._addColumn(parent, lines, x, weightMap)
1230 return lines
1231
1232
1233
1234 - def _addColumn(self, parent, lines, extra, weightMap = {}, existingWeight = 5 , extraWeight = 2):
1235 """
1236 # add ia extra column in the edit area.
1237 # preconditions:
1238 # parent is fields_pnl (weak);
1239 # self.input_fields exists (required);
1240 # ; extra is a list of tuples of format -
1241 # ( key for input_fields, widget label , widget class to instantiate )
1242 """
1243
1244 newlines = []
1245 i = 0
1246 for x in lines:
1247
1248 if weightMap.has_key( x):
1249 (existingWeight, extraWeight) = weightMap[x]
1250
1251 szr = wx.BoxSizer(wx.HORIZONTAL)
1252 szr.Add( x, existingWeight, wx.EXPAND)
1253 if i < len(extra) and extra[i] <> None:
1254
1255 (inputKey, widgetLabel, aclass) = extra[i]
1256 if aclass.__name__ in CONTROLS_WITHOUT_LABELS:
1257 szr.Add( self._make_prompt(parent, widgetLabel, richards_blue) )
1258 widgetLabel = ""
1259
1260
1261 w = aclass( parent, -1, widgetLabel)
1262 if not aclass.__name__ in CONTROLS_WITHOUT_LABELS:
1263 w.SetForegroundColour(richards_blue)
1264
1265 szr.Add(w, extraWeight , wx.EXPAND)
1266
1267
1268 self.input_fields[inputKey] = w
1269
1270 newlines.append(szr)
1271 i += 1
1272 return newlines
1273
1293
1296
1299
1305
1316
1317 -class gmPastHistoryEditArea(gmEditArea):
1318
1319 - def __init__(self, parent, id):
1320 gmEditArea.__init__(self, parent, id, aType = 'past history')
1321
1322 - def _define_prompts(self):
1323 self._add_prompt(line = 1, label = _("When Noted"))
1324 self._add_prompt(line = 2, label = _("Laterality"))
1325 self._add_prompt(line = 3, label = _("Condition"))
1326 self._add_prompt(line = 4, label = _("Notes"))
1327 self._add_prompt(line = 6, label = _("Status"))
1328 self._add_prompt(line = 7, label = _("Progress Note"))
1329 self._add_prompt(line = 8, label = '')
1330
1331 - def _define_fields(self, parent):
1332
1333 self.fld_date_noted = gmDateTimeInput.gmDateInput(
1334 parent = parent,
1335 id = -1,
1336 style = wx.SIMPLE_BORDER
1337 )
1338 self._add_field(
1339 line = 1,
1340 pos = 1,
1341 widget = self.fld_date_noted,
1342 weight = 2
1343 )
1344 self._add_field(
1345 line = 1,
1346 pos = 2,
1347 widget = cPrompt_edit_area(parent,-1, _("Age")),
1348 weight = 0)
1349
1350 self.fld_age_noted = cEditAreaField(parent)
1351 self._add_field(
1352 line = 1,
1353 pos = 3,
1354 widget = self.fld_age_noted,
1355 weight = 2
1356 )
1357
1358
1359 self.fld_laterality_none= wx.RadioButton(parent, -1, _("N/A"))
1360 self.fld_laterality_left= wx.RadioButton(parent, -1, _("L"))
1361 self.fld_laterality_right= wx.RadioButton(parent, -1, _("R"))
1362 self.fld_laterality_both= wx.RadioButton(parent, -1, _("both"))
1363 self._add_field(
1364 line = 2,
1365 pos = 1,
1366 widget = self.fld_laterality_none,
1367 weight = 0
1368 )
1369 self._add_field(
1370 line = 2,
1371 pos = 2,
1372 widget = self.fld_laterality_left,
1373 weight = 0
1374 )
1375 self._add_field(
1376 line = 2,
1377 pos = 3,
1378 widget = self.fld_laterality_right,
1379 weight = 1
1380 )
1381 self._add_field(
1382 line = 2,
1383 pos = 4,
1384 widget = self.fld_laterality_both,
1385 weight = 1
1386 )
1387
1388 self.fld_condition= cEditAreaField(parent)
1389 self._add_field(
1390 line = 3,
1391 pos = 1,
1392 widget = self.fld_condition,
1393 weight = 6
1394 )
1395
1396 self.fld_notes= cEditAreaField(parent)
1397 self._add_field(
1398 line = 4,
1399 pos = 1,
1400 widget = self.fld_notes,
1401 weight = 6
1402 )
1403
1404 self.fld_significant= wx.CheckBox(
1405 parent,
1406 -1,
1407 _("significant"),
1408 style = wx.NO_BORDER
1409 )
1410 self.fld_active= wx.CheckBox(
1411 parent,
1412 -1,
1413 _("active"),
1414 style = wx.NO_BORDER
1415 )
1416
1417 self._add_field(
1418 line = 5,
1419 pos = 1,
1420 widget = self.fld_significant,
1421 weight = 0
1422 )
1423 self._add_field(
1424 line = 5,
1425 pos = 2,
1426 widget = self.fld_active,
1427 weight = 0
1428 )
1429
1430 self.fld_progress= cEditAreaField(parent)
1431 self._add_field(
1432 line = 6,
1433 pos = 1,
1434 widget = self.fld_progress,
1435 weight = 6
1436 )
1437
1438
1439 self._add_field(
1440 line = 7,
1441 pos = 4,
1442 widget = self._make_standard_buttons(parent),
1443 weight = 2
1444 )
1445
1446 - def _postInit(self):
1447 return
1448
1449 wx.EVT_KILL_FOCUS( self.fld_age_noted, self._ageKillFocus)
1450 wx.EVT_KILL_FOCUS( self.fld_date_noted, self._yearKillFocus)
1451
1452 - def _ageKillFocus( self, event):
1453
1454 event.Skip()
1455 try :
1456 year = self._getBirthYear() + int(self.fld_age_noted.GetValue().strip() )
1457 self.fld_date_noted.SetValue( str (year) )
1458 except:
1459 pass
1460
1461 - def _getBirthYear(self):
1462 try:
1463 birthyear = int(str(self._patient['dob']).split('-')[0])
1464 except:
1465
1466 birthyear = 1
1467
1468 return birthyear
1469
1470 - def _yearKillFocus( self, event):
1471 event.Skip()
1472 try:
1473 age = int(self.fld_date_noted.GetValue().strip() ) - self._getBirthYear()
1474 self.fld_age_noted.SetValue( str (age) )
1475 except:
1476 pass
1477
1478 __init_values = {
1479 "condition": "",
1480 "notes1": "",
1481 "notes2": "",
1482 "age": "",
1483
1484 "progress": "",
1485 "active": 1,
1486 "operation": 0,
1487 "confidential": 0,
1488 "significant": 1,
1489 "both": 0,
1490 "left": 0,
1491 "right": 0,
1492 "none" : 1
1493 }
1494
1495 - def _getDefaultAge(self):
1496 try:
1497
1498 return 1
1499 except:
1500 return 0
1501
1502 - def _get_init_values(self):
1503 values = gmPastHistoryEditArea.__init_values
1504 values["age"] = str( self._getDefaultAge())
1505 return values
1506
1507 - def _save_data(self):
1508 clinical = self._patient.get_emr().get_past_history()
1509 if self.getDataId() is None:
1510 id = clinical.create_history( self.get_fields_formatting_values() )
1511 self.setDataId(id)
1512 return
1513
1514 clinical.update_history( self.get_fields_formatting_values(), self.getDataId() )
1515
1516
1526
1528 self._add_prompt (line = 1, label = _ ("Specialty"))
1529 self._add_prompt (line = 2, label = _ ("Name"))
1530 self._add_prompt (line = 3, label = _ ("Address"))
1531 self._add_prompt (line = 4, label = _ ("Options"))
1532 self._add_prompt (line = 5, label = _("Text"), weight =6)
1533 self._add_prompt (line = 6, label = "")
1534
1536 self.fld_specialty = gmPhraseWheel.cPhraseWheel (
1537 parent = parent,
1538 id = -1,
1539 style = wx.SIMPLE_BORDER
1540 )
1541
1542 self._add_field (
1543 line = 1,
1544 pos = 1,
1545 widget = self.fld_specialty,
1546 weight = 1
1547 )
1548 self.fld_name = gmPhraseWheel.cPhraseWheel (
1549 parent = parent,
1550 id = -1,
1551 style = wx.SIMPLE_BORDER
1552 )
1553
1554 self._add_field (
1555 line = 2,
1556 pos = 1,
1557 widget = self.fld_name,
1558 weight = 1
1559 )
1560 self.fld_address = wx.ComboBox (parent, -1, style = wx.CB_READONLY)
1561
1562 self._add_field (
1563 line = 3,
1564 pos = 1,
1565 widget = self.fld_address,
1566 weight = 1
1567 )
1568
1569
1570 self.fld_name.add_callback_on_selection(self.setAddresses)
1571
1572 self.fld_med = wx.CheckBox (parent, -1, _("Meds"), style=wx.NO_BORDER)
1573 self._add_field (
1574 line = 4,
1575 pos = 1,
1576 widget = self.fld_med,
1577 weight = 1
1578 )
1579 self.fld_past = wx.CheckBox (parent, -1, _("Past Hx"), style=wx.NO_BORDER)
1580 self._add_field (
1581 line = 4,
1582 pos = 4,
1583 widget = self.fld_past,
1584 weight = 1
1585 )
1586 self.fld_text = wx.TextCtrl (parent, -1, style= wx.TE_MULTILINE)
1587 self._add_field (
1588 line = 5,
1589 pos = 1,
1590 widget = self.fld_text,
1591 weight = 1)
1592
1593 self._add_field(
1594 line = 6,
1595 pos = 1,
1596 widget = self._make_standard_buttons(parent),
1597 weight = 1
1598 )
1599 return 1
1600
1602 """
1603 Doesn't accept any value as this doesn't make sense for this edit area
1604 """
1605 self.fld_specialty.SetValue ('')
1606 self.fld_name.SetValue ('')
1607 self.fld_address.Clear ()
1608 self.fld_address.SetValue ('')
1609 self.fld_med.SetValue (0)
1610 self.fld_past.SetValue (0)
1611 self.fld_text.SetValue ('')
1612 self.recipient = None
1613
1615 """
1616 Set the available addresses for the selected identity
1617 """
1618 if id is None:
1619 self.recipient = None
1620 self.fld_address.Clear ()
1621 self.fld_address.SetValue ('')
1622 else:
1623 self.recipient = gmDemographicRecord.cDemographicRecord_SQL (id)
1624 self.fld_address.Clear ()
1625 self.addr = self.recipient.getAddresses ('work')
1626 for i in self.addr:
1627 self.fld_address.Append (_("%(number)s %(street)s, %(urb)s %(postcode)s") % i, ('post', i))
1628 fax = self.recipient.getCommChannel (gmDemographicRecord.FAX)
1629 email = self.recipient.getCommChannel (gmDemographicRecord.EMAIL)
1630 if fax:
1631 self.fld_address.Append ("%s: %s" % (_("FAX"), fax), ('fax', fax))
1632 if email:
1633 self.fld_address.Append ("%s: %s" % (_("E-MAIL"), email), ('email', email))
1634
1635 - def _save_new_entry(self):
1636 """
1637 We are always saving a "new entry" here because data_ID is always None
1638 """
1639 if not self.recipient:
1640 raise gmExceptions.InvalidInputError(_('must have a recipient'))
1641 if self.fld_address.GetSelection() == -1:
1642 raise gmExceptions.InvalidInputError(_('must select address'))
1643 channel, addr = self.fld_address.GetClientData (self.fld_address.GetSelection())
1644 text = self.fld_text.GetValue()
1645 flags = {}
1646 flags['meds'] = self.fld_med.GetValue()
1647 flags['pasthx'] = self.fld_past.GetValue()
1648 if not gmReferral.create_referral (self._patient, self.recipient, channel, addr, text, flags):
1649 raise gmExceptions.InvalidInputError('error sending form')
1650
1651
1652
1653
1654
1662
1663
1664
1666 _log.debug("making prescription lines")
1667 lines = []
1668 self.txt_problem = cEditAreaField(parent)
1669 self.txt_class = cEditAreaField(parent)
1670 self.txt_generic = cEditAreaField(parent)
1671 self.txt_brand = cEditAreaField(parent)
1672 self.txt_strength= cEditAreaField(parent)
1673 self.txt_directions= cEditAreaField(parent)
1674 self.txt_for = cEditAreaField(parent)
1675 self.txt_progress = cEditAreaField(parent)
1676
1677 lines.append(self.txt_problem)
1678 lines.append(self.txt_class)
1679 lines.append(self.txt_generic)
1680 lines.append(self.txt_brand)
1681 lines.append(self.txt_strength)
1682 lines.append(self.txt_directions)
1683 lines.append(self.txt_for)
1684 lines.append(self.txt_progress)
1685 lines.append(self._make_standard_buttons(parent))
1686 self.input_fields = {
1687 "problem": self.txt_problem,
1688 "class" : self.txt_class,
1689 "generic" : self.txt_generic,
1690 "brand" : self.txt_brand,
1691 "strength": self.txt_strength,
1692 "directions": self.txt_directions,
1693 "for" : self.txt_for,
1694 "progress": self.txt_progress
1695
1696 }
1697
1698 return self._makeExtraColumns( parent, lines)
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1717
1718
1719
1720
1721
1722
1725 wx.StaticText.__init__(self, parent, id, prompt, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_LEFT)
1726 self.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
1727 self.SetForegroundColour(aColor)
1728
1729
1730
1731
1732
1734 - def __init__(self, parent, id, prompt_labels):
1735 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
1736 self.SetBackgroundColour(richards_light_gray)
1737 gszr = wx.GridSizer (len(prompt_labels)+1, 1, 2, 2)
1738 color = richards_aqua
1739 for prompt_key in prompt_labels.keys():
1740 label = cPrompt_edit_area(self, -1, " %s" % prompt_labels[prompt_key], aColor = color)
1741 gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT)
1742 color = richards_blue
1743 self.SetSizer(gszr)
1744 gszr.Fit(self)
1745 self.SetAutoLayout(True)
1746
1747
1748
1749
1750
1751
1752
1753 -class EditTextBoxes(wx.Panel):
1754 - def __init__(self, parent, id, editareaprompts, section):
1755 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize,style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
1756 self.SetBackgroundColour(wx.Colour(222,222,222))
1757 self.parent = parent
1758
1759 self.gszr = wx.GridSizer(len(editareaprompts), 1, 2, 2)
1760
1761 if section == gmSECTION_SUMMARY:
1762 pass
1763 elif section == gmSECTION_DEMOGRAPHICS:
1764 pass
1765 elif section == gmSECTION_CLINICALNOTES:
1766 pass
1767 elif section == gmSECTION_FAMILYHISTORY:
1768 pass
1769 elif section == gmSECTION_PASTHISTORY:
1770 pass
1771
1772
1773 self.txt_condition = cEditAreaField(self,PHX_CONDITION,wx.DefaultPosition,wx.DefaultSize)
1774 self.rb_sideleft = wxRadioButton(self,PHX_LEFT, _(" (L) "), wx.DefaultPosition,wx.DefaultSize)
1775 self.rb_sideright = wxRadioButton(self, PHX_RIGHT, _("(R)"), wx.DefaultPosition,wx.DefaultSize,wx.SUNKEN_BORDER)
1776 self.rb_sideboth = wxRadioButton(self, PHX_BOTH, _("Both"), wx.DefaultPosition,wx.DefaultSize)
1777 rbsizer = wx.BoxSizer(wx.HORIZONTAL)
1778 rbsizer.Add(self.rb_sideleft,1,wx.EXPAND)
1779 rbsizer.Add(self.rb_sideright,1,wx.EXPAND)
1780 rbsizer.Add(self.rb_sideboth,1,wx.EXPAND)
1781 szr1 = wx.BoxSizer(wx.HORIZONTAL)
1782 szr1.Add(self.txt_condition, 4, wx.EXPAND)
1783 szr1.Add(rbsizer, 3, wx.EXPAND)
1784
1785
1786
1787
1788 self.txt_notes1 = cEditAreaField(self,PHX_NOTES,wx.DefaultPosition,wx.DefaultSize)
1789
1790 self.txt_notes2= cEditAreaField(self,PHX_NOTES2,wx.DefaultPosition,wx.DefaultSize)
1791
1792 self.txt_agenoted = cEditAreaField(self, PHX_AGE, wx.DefaultPosition, wx.DefaultSize)
1793 szr4 = wx.BoxSizer(wx.HORIZONTAL)
1794 szr4.Add(self.txt_agenoted, 1, wx.EXPAND)
1795 szr4.Add(5, 0, 5)
1796
1797 self.txt_yearnoted = cEditAreaField(self,PHX_YEAR,wx.DefaultPosition,wx.DefaultSize)
1798 szr5 = wx.BoxSizer(wx.HORIZONTAL)
1799 szr5.Add(self.txt_yearnoted, 1, wx.EXPAND)
1800 szr5.Add(5, 0, 5)
1801
1802 self.parent.cb_active = wx.CheckBox(self, PHX_ACTIVE, _("Active"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1803 self.parent.cb_operation = wx.CheckBox(self, PHX_OPERATION, _("Operation"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1804 self.parent.cb_confidential = wx.CheckBox(self, PHX_CONFIDENTIAL , _("Confidential"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1805 self.parent.cb_significant = wx.CheckBox(self, PHX_SIGNIFICANT, _("Significant"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1806 szr6 = wx.BoxSizer(wx.HORIZONTAL)
1807 szr6.Add(self.parent.cb_active, 1, wx.EXPAND)
1808 szr6.Add(self.parent.cb_operation, 1, wx.EXPAND)
1809 szr6.Add(self.parent.cb_confidential, 1, wx.EXPAND)
1810 szr6.Add(self.parent.cb_significant, 1, wx.EXPAND)
1811
1812 self.txt_progressnotes = cEditAreaField(self,PHX_PROGRESSNOTES ,wx.DefaultPosition,wx.DefaultSize)
1813
1814 szr8 = wx.BoxSizer(wx.HORIZONTAL)
1815 szr8.Add(5, 0, 6)
1816 szr8.Add(self._make_standard_buttons(), 0, wx.EXPAND)
1817
1818 self.gszr.Add(szr1,0,wx.EXPAND)
1819 self.gszr.Add(self.txt_notes1,0,wx.EXPAND)
1820 self.gszr.Add(self.txt_notes2,0,wx.EXPAND)
1821 self.gszr.Add(szr4,0,wx.EXPAND)
1822 self.gszr.Add(szr5,0,wx.EXPAND)
1823 self.gszr.Add(szr6,0,wx.EXPAND)
1824 self.gszr.Add(self.txt_progressnotes,0,wx.EXPAND)
1825 self.gszr.Add(szr8,0,wx.EXPAND)
1826
1827
1828 elif section == gmSECTION_SCRIPT:
1829 pass
1830 elif section == gmSECTION_REQUESTS:
1831 pass
1832 elif section == gmSECTION_RECALLS:
1833 pass
1834 else:
1835 pass
1836
1837 self.SetSizer(self.gszr)
1838 self.gszr.Fit(self)
1839
1840 self.SetAutoLayout(True)
1841 self.Show(True)
1842
1844 self.btn_OK = wx.Button(self, -1, _("Ok"))
1845 self.btn_Clear = wx.Button(self, -1, _("Clear"))
1846 szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
1847 szr_buttons.Add(self.btn_OK, 1, wx.EXPAND, wx.ALL, 1)
1848 szr_buttons.Add(5, 0, 0)
1849 szr_buttons.Add(self.btn_Clear, 1, wx.EXPAND, wx.ALL, 1)
1850 return szr_buttons
1851
1853 - def __init__(self, parent, id, line_labels, section):
1854 _log.warning('***** old style EditArea instantiated, please convert *****')
1855
1856 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, style = wx.NO_BORDER)
1857 self.SetBackgroundColour(wx.Colour(222,222,222))
1858
1859
1860 prompts = gmPnlEditAreaPrompts(self, -1, line_labels)
1861
1862 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1863
1864 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
1865 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
1866 szr_shadow_below_prompts.Add(5,0,0,wx.EXPAND)
1867 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
1868
1869 szr_prompts = wx.BoxSizer(wx.VERTICAL)
1870 szr_prompts.Add(prompts, 97, wx.EXPAND)
1871 szr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
1872
1873
1874 edit_fields = EditTextBoxes(self, -1, line_labels, section)
1875
1876 shadow_below_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1877
1878 shadow_below_editarea.SetBackgroundColour(richards_coloured_gray)
1879 szr_shadow_below_editarea = wx.BoxSizer(wx.HORIZONTAL)
1880 szr_shadow_below_editarea.Add(5,0,0,wx.EXPAND)
1881 szr_shadow_below_editarea.Add(shadow_below_editarea, 12, wx.EXPAND)
1882
1883 szr_editarea = wx.BoxSizer(wx.VERTICAL)
1884 szr_editarea.Add(edit_fields, 92, wx.EXPAND)
1885 szr_editarea.Add(szr_shadow_below_editarea, 5, wx.EXPAND)
1886
1887
1888
1889 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1890 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
1891 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
1892 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
1893 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND)
1894
1895 shadow_rightof_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1896 shadow_rightof_editarea.SetBackgroundColour(richards_coloured_gray)
1897 szr_shadow_rightof_editarea = wx.BoxSizer(wx.VERTICAL)
1898 szr_shadow_rightof_editarea.Add(0, 5, 0, wx.EXPAND)
1899 szr_shadow_rightof_editarea.Add(shadow_rightof_editarea, 1, wx.EXPAND)
1900
1901
1902 self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL)
1903 self.szr_main_panels.Add(szr_prompts, 10, wx.EXPAND)
1904 self.szr_main_panels.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
1905 self.szr_main_panels.Add(5, 0, 0, wx.EXPAND)
1906 self.szr_main_panels.Add(szr_editarea, 89, wx.EXPAND)
1907 self.szr_main_panels.Add(szr_shadow_rightof_editarea, 1, wx.EXPAND)
1908
1909
1910
1911 self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL)
1912 self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5)
1913 self.SetSizer(self.szr_central_container)
1914 self.szr_central_container.Fit(self)
1915 self.SetAutoLayout(True)
1916 self.Show(True)
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
2185
2186
2187
2188
2189
2190
2191
2192
2193 if __name__ == "__main__":
2194
2195
2200 self._add_prompt(line=1, label='line 1')
2201 self._add_prompt(line=2, label='buttons')
2203
2204 self.fld_substance = cEditAreaField(parent)
2205 self._add_field(
2206 line = 1,
2207 pos = 1,
2208 widget = self.fld_substance,
2209 weight = 1
2210 )
2211
2212 self._add_field(
2213 line = 2,
2214 pos = 1,
2215 widget = self._make_standard_buttons(parent),
2216 weight = 1
2217 )
2218
2219 app = wxPyWidgetTester(size = (400, 200))
2220 app.SetWidget(cTestEditArea)
2221 app.MainLoop()
2222
2223
2224
2225
2226
2227
2228
2229