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 #----------------------------------------------------------------
58 # def __init_ui(self):
59 # # adjust phrasewheels etc
60
61 #----------------------------------------------------------------
62 # generic Edit Area mixin API
63 #----------------------------------------------------------------
64 def _valid_for_save(self):
65
66 # its best to validate bottom -> top such that the
67 # cursor ends up in the topmost failing field
68
69 # remove when implemented:
70 return False
71
72 validity = True
73
74 if self._TCTRL_xxx.GetValue().strip() == u'':
75 validity = False
76 self.display_tctrl_as_valid(tctrl = self._TCTRL_xxx, valid = False)
77 self.status_message = _('No entry in field xxx.')
78 self._TCTRL_xxx.SetFocus()
79 else:
80 self.display_tctrl_as_valid(tctrl = self._TCTRL_xxx, valid = True)
81
82 if self._PRW_xxx.GetData() is None:
83 validity = False
84 self._PRW_xxx.display_as_valid(False)
85 self.status_message = _('No entry in field xxx.')
86 self._PRW_xxx.SetFocus()
87 else:
88 self._PRW_xxx.display_as_valid(True)
89
90 return validity
91
92 #----------------------------------------------------------------
93 def _save_as_new(self):
94
95 # remove when implemented:
96 return False
97
98 # save the data as a new instance
99 data = gmXXXX.create_xxxx()
100
101 data[''] = self._
102 data[''] = self._
103
104 data.save()
105
106 # must be done very late or else the property access
107 # will refresh the display such that later field
108 # access will return empty values
109 self.data = data
110 return False
111 return True
112
113 #----------------------------------------------------------------
114 def _save_as_update(self):
115
116 # remove when implemented:
117 return False
118
119 # update self.data and save the changes
120 self.data[''] = self._TCTRL_xxx.GetValue().strip()
121 self.data[''] = self._PRW_xxx.GetData()
122 self.data[''] = self._CHBOX_xxx.GetValue()
123 self.data.save()
124 return True
125
126 #----------------------------------------------------------------
127 def _refresh_as_new(self):
128 pass
129
130 #----------------------------------------------------------------
131 def _refresh_as_new_from_existing(self):
132 self._refresh_as_new()
133
134 #----------------------------------------------------------------
135 def _refresh_from_existing(self):
136 pass
137
138 #----------------------------------------------------------------
139 def set_fields(self, fields):
140 # <fields> must be a dict compatible with the
141 # structure of the business object this edit
142 # area is for,
143 # thusly, the edit area knows how to set its
144 # controls from it,
145 # <fields> doesn't have to contain all keys, rather:
146 # - missing ones are skipped
147 # - unknown ones are ignored
148 # each key must hold a dict with at least a key 'value'
149 # and _can_ contain another key 'data',
150 # 'value' and 'data' must be compatible with the
151 # control they go into,
152 # controls which don't require 'data' (say, RadioButton)
153 # will ignore an existing 'data' key
154 pass
155
156 #----------------------------------------------------------------
157
158 **************** end of template ****************
159 """
161 self.__mode = 'new'
162 self.__data = None
163 self.successful_save_msg = None
164 self.__tctrl_validity_colors = {
165 True: wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW),
166 False: 'pink'
167 }
168 self._refresh_as_new()
169
170
171
172
175
177 if mode not in edit_area_modes:
178 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
179 if mode == 'edit':
180 if self.__data is None:
181 raise ValueError('[%s] <mode> "edit" needs data value' % self.__class__.__name__)
182
183 prev_mode = self.__mode
184 self.__mode = mode
185 if mode != prev_mode:
186 self.refresh()
187
188 mode = property(_get_mode, _set_mode)
189
190
193
195 if data is None:
196 if self.__mode == 'edit':
197 raise ValueError('[%s] <mode> "edit" needs data value' % self.__class__.__name__)
198 self.__data = data
199 self.refresh()
200
201 data = property(_get_data, _set_data)
202
203
206
207 status_message = property(lambda x:x, show_msg)
208
209
210
211
213 """Invoked from the generic edit area dialog.
214
215 Invokes
216 _valid_for_save,
217 _save_as_new,
218 _save_as_update
219 on the implementing edit area as needed.
220
221 _save_as_* must set self.__data and return True/False
222 """
223 if not self._valid_for_save():
224 return False
225
226
227 gmDispatcher.send(signal = 'statustext', msg = '')
228
229 if self.__mode in ['new', 'new_from_existing']:
230 if self._save_as_new():
231 self.mode = 'edit'
232 return True
233 return False
234
235 elif self.__mode == 'edit':
236 return self._save_as_update()
237
238 else:
239 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
240
241
243 """Invoked from the generic edit area dialog.
244
245 Invokes
246 _refresh_as_new()
247 _refresh_from_existing()
248 _refresh_as_new_from_existing()
249 on the implementing edit area as needed.
250
251 Then calls _valid_for_save().
252 """
253 if self.__mode == 'new':
254 result = self._refresh_as_new()
255 self._valid_for_save()
256 return result
257 elif self.__mode == 'edit':
258 result = self._refresh_from_existing()
259 self._valid_for_save()
260 return result
261 elif self.__mode == 'new_from_existing':
262 result = self._refresh_as_new_from_existing()
263 self._valid_for_save()
264 return result
265 else:
266 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
267
268
271
272
276
277
278 from Gnumed.wxGladeWidgets import wxgGenericEditAreaDlg2
279
281 """Dialog for parenting edit area panels with save/clear/next/cancel"""
282
283 _lucky_day = 1
284 _lucky_month = 4
285 _today = pydt.date.today()
286
288
289 new_ea = kwargs['edit_area']
290 del kwargs['edit_area']
291
292 if not isinstance(new_ea, cGenericEditAreaMixin):
293 raise TypeError('[%s]: edit area instance must be child of cGenericEditAreaMixin')
294
295 try:
296 single_entry = kwargs['single_entry']
297 del kwargs['single_entry']
298 except KeyError:
299 single_entry = False
300
301 try:
302 title = kwargs['title']
303 if not title.startswith('GMd: '):
304 kwargs['title'] = 'GMd: %s' % title
305 except KeyError:
306 kwargs['title'] = 'GMd: %s' % self.__class__.__name__
307
308 wxgGenericEditAreaDlg2.wxgGenericEditAreaDlg2.__init__(self, *args, **kwargs)
309
310 self.left_extra_button = None
311
312 if cGenericEditAreaDlg2._today.day != cGenericEditAreaDlg2._lucky_day:
313 self._BTN_lucky.Enable(False)
314 self._BTN_lucky.Hide()
315 else:
316 if cGenericEditAreaDlg2._today.month != cGenericEditAreaDlg2._lucky_month:
317 self._BTN_lucky.Enable(False)
318 self._BTN_lucky.Hide()
319
320
321 dummy_ea_pnl = self._PNL_ea
322 ea_pnl_szr = dummy_ea_pnl.GetContainingSizer()
323 ea_pnl_parent = dummy_ea_pnl.GetParent()
324
325 dummy_ea_pnl.Destroy()
326 del dummy_ea_pnl
327 new_ea_min_size = new_ea.GetMinSize()
328 new_ea.Reparent(ea_pnl_parent)
329 self._PNL_ea = new_ea
330 ea_pnl_szr.Add(self._PNL_ea, 1, wx.EXPAND, 0)
331 ea_pnl_szr.SetMinSize(new_ea_min_size)
332 ea_pnl_szr.Fit(new_ea)
333
334
335 if single_entry:
336 self._BTN_forward.Enable(False)
337 self._BTN_forward.Hide()
338
339 self._adjust_clear_revert_buttons()
340
341
342 self._TCTRL_status.SetValue('')
343 gmDispatcher.connect(signal = 'statustext', receiver = self._on_set_statustext)
344
345
346
347 main_szr = self.GetSizer()
348 main_szr.Fit(self)
349 self.Layout()
350
351
352 self._PNL_ea.refresh()
353
354
355 - def _on_set_statustext(self, msg=None, loglevel=None, beep=True):
356 if msg is None:
357 self._TCTRL_status.SetValue('')
358 return
359 if msg.strip() == '':
360 self._TCTRL_status.SetValue('')
361 return
362 self._TCTRL_status.SetValue(msg)
363 return
364
365
377
385
388
391
406
417
426
427
428
444
445 left_extra_button = property(lambda x:x, _set_left_extra_button)
446
447
448
449
450
451
452
453
454
455 from Gnumed.pycommon import gmGuiBroker
456
457
458 _gb = gmGuiBroker.GuiBroker()
459
460 gmSECTION_SUMMARY = 1
461 gmSECTION_DEMOGRAPHICS = 2
462 gmSECTION_CLINICALNOTES = 3
463 gmSECTION_FAMILYHISTORY = 4
464 gmSECTION_PASTHISTORY = 5
465 gmSECTION_SCRIPT = 8
466 gmSECTION_REQUESTS = 9
467 gmSECTION_REFERRALS = 11
468 gmSECTION_RECALLS = 12
469
470 richards_blue = wx.Colour(0,0,131)
471 richards_aqua = wx.Colour(0,194,197)
472 richards_dark_gray = wx.Colour(131,129,131)
473 richards_light_gray = wx.Colour(255,255,255)
474 richards_coloured_gray = wx.Colour(131,129,131)
475
476
477 CONTROLS_WITHOUT_LABELS =['wxTextCtrl', 'cEditAreaField', 'wx.SpinCtrl', 'gmPhraseWheel', 'wx.ComboBox']
478
480 widget.SetForegroundColour(wx.Colour(255, 0, 0))
481 widget.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
482
495 if not isinstance(edit_area, cEditArea2):
496 raise TypeError('<edit_area> must be of type cEditArea2 but is <%s>' % type(edit_area))
497 wx.Dialog.__init__(self, parent, id, title, pos, size, style, name)
498 self.__wxID_BTN_SAVE = wx.NewId()
499 self.__wxID_BTN_RESET = wx.NewId()
500 self.__editarea = edit_area
501 self.__do_layout()
502 self.__register_events()
503
504
505
508
510 self.__editarea.Reparent(self)
511
512 self.__btn_SAVE = wx.Button(self, self.__wxID_BTN_SAVE, _("Save"))
513 self.__btn_SAVE.SetToolTip(_('save entry into medical record'))
514 self.__btn_RESET = wx.Button(self, self.__wxID_BTN_RESET, _("Reset"))
515 self.__btn_RESET.SetToolTip(_('reset entry'))
516 self.__btn_CANCEL = wx.Button(self, wx.ID_CANCEL, _("Cancel"))
517 self.__btn_CANCEL.SetToolTip(_('discard entry and cancel'))
518
519 szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
520 szr_buttons.Add(self.__btn_SAVE, 1, wx.EXPAND | wx.ALL, 1)
521 szr_buttons.Add(self.__btn_RESET, 1, wx.EXPAND | wx.ALL, 1)
522 szr_buttons.Add(self.__btn_CANCEL, 1, wx.EXPAND | wx.ALL, 1)
523
524 szr_main = wx.BoxSizer(wx.VERTICAL)
525 szr_main.Add(self.__editarea, 1, wx.EXPAND)
526 szr_main.Add(szr_buttons, 0, wx.EXPAND)
527
528 self.SetSizerAndFit(szr_main)
529
530
531
533
534 wx.EVT_BUTTON(self.__btn_SAVE, self.__wxID_BTN_SAVE, self._on_SAVE_btn_pressed)
535 wx.EVT_BUTTON(self.__btn_RESET, self.__wxID_BTN_RESET, self._on_RESET_btn_pressed)
536 wx.EVT_BUTTON(self.__btn_CANCEL, wx.ID_CANCEL, self._on_CANCEL_btn_pressed)
537
538 wx.EVT_CLOSE(self, self._on_CANCEL_btn_pressed)
539
540
541
542
543
544
545 return 1
546
548 if self.__editarea.save_data():
549 self.__editarea.Close()
550 self.EndModal(wx.ID_OK)
551 return
552 short_err = self.__editarea.get_short_error()
553 long_err = self.__editarea.get_long_error()
554 if (short_err is None) and (long_err is None):
555 long_err = _(
556 'Unspecified error saving data in edit area.\n\n'
557 'Programmer forgot to specify proper error\n'
558 'message in [%s].'
559 ) % self.__editarea.__class__.__name__
560 if short_err is not None:
561 gmDispatcher.send(signal = 'statustext', msg = short_err)
562 if long_err is not None:
563 gmGuiHelpers.gm_show_error(long_err, _('saving clinical data'))
564
566 self.__editarea.Close()
567 self.EndModal(wx.ID_CANCEL)
568
571
573 - def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TAB_TRAVERSAL):
574
575 wx.Panel.__init__ (
576 self,
577 parent,
578 id,
579 pos = pos,
580 size = size,
581 style = style | wx.TAB_TRAVERSAL
582 )
583 self.SetBackgroundColour(wx.Colour(222,222,222))
584
585 self.data = None
586 self.fields = {}
587 self.prompts = {}
588 self._short_error = None
589 self._long_error = None
590 self._summary = None
591 self._patient = gmPerson.gmCurrentPatient()
592 self.__wxID_BTN_OK = wx.NewId()
593 self.__wxID_BTN_CLEAR = wx.NewId()
594 self.__do_layout()
595 self.__register_events()
596 self.Show()
597
598
599
601 """This needs to be overridden by child classes."""
602 self._long_error = _(
603 'Cannot save data from edit area.\n\n'
604 'Programmer forgot to override method:\n'
605 ' <%s.save_data>'
606 ) % self.__class__.__name__
607 return False
608
610 msg = _(
611 'Cannot reset fields in edit area.\n\n'
612 'Programmer forgot to override method:\n'
613 ' <%s.reset_ui>'
614 ) % self.__class__.__name__
615 gmGuiHelpers.gm_show_error(msg)
616
618 tmp = self._short_error
619 self._short_error = None
620 return tmp
621
623 tmp = self._long_error
624 self._long_error = None
625 return tmp
626
628 return _('<No embed string for [%s]>') % self.__class__.__name__
629
630
631
643
648
649
650
652 self.__deregister_events()
653 event.Skip()
654
656 """Only active if _make_standard_buttons was called in child class."""
657
658 try:
659 event.Skip()
660 if self.data is None:
661 self._save_new_entry()
662 self.reset_ui()
663 else:
664 self._save_modified_entry()
665 self.reset_ui()
666 except Exception as err:
667
668
669 gmGuiHelpers.gm_show_error (err, _("Invalid Input"))
670 except:
671 _log.exception( "save data problem in [%s]" % self.__class__.__name__)
672
674 """Only active if _make_standard_buttons was called in child class."""
675
676 self.reset_ui()
677 event.Skip()
678
680 self.__deregister_events()
681
682 if not self._patient.connected:
683 return True
684
685
686
687
688 return True
689 _log.error('[%s] lossage' % self.__class__.__name__)
690 return False
691
693 """Just before new patient becomes active."""
694
695 if not self._patient.connected:
696 return True
697
698
699
700
701 return True
702 _log.error('[%s] lossage' % self.__class__.__name__)
703 return False
704
706 """Just after new patient became active."""
707
708 self.reset_ui()
709
710
711
713
714
715 self._define_prompts()
716 self._define_fields(parent = self)
717 if len(self.fields) != len(self.prompts):
718 _log.error('[%s]: #fields != #prompts' % self.__class__.__name__)
719 return None
720
721
722 szr_main_fgrid = wx.FlexGridSizer(rows = len(self.prompts), cols=2)
723 color = richards_aqua
724 lines = self.prompts.keys()
725 lines.sort()
726 for line in lines:
727
728 label, color, weight = self.prompts[line]
729
730 prompt = wx.StaticText (
731 parent = self,
732 id = -1,
733 label = label,
734 style = wx.ALIGN_CENTRE
735 )
736
737 prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
738 prompt.SetForegroundColour(color)
739 prompt.SetBackgroundColour(richards_light_gray)
740 szr_main_fgrid.Add(prompt, flag=wx.EXPAND | wx.ALIGN_RIGHT)
741
742
743 szr_line = wx.BoxSizer(wx.HORIZONTAL)
744 positions = self.fields[line].keys()
745 positions.sort()
746 for pos in positions:
747 field, weight = self.fields[line][pos]
748
749 szr_line.Add(field, weight, wx.EXPAND)
750 szr_main_fgrid.Add(szr_line, flag=wx.GROW | wx.ALIGN_LEFT)
751
752
753 szr_main_fgrid.AddGrowableCol(1)
754
755
756
757
758
759
760
761 self.SetSizerAndFit(szr_main_fgrid)
762
763
764
765
767 """Child classes override this to define their prompts using _add_prompt()"""
768 _log.error('missing override in [%s]' % self.__class__.__name__)
769
771 """Add a new prompt line.
772
773 To be used from _define_fields in child classes.
774
775 - label, the label text
776 - color
777 - weight, the weight given in sizing the various rows. 0 means the row
778 always has minimum size
779 """
780 self.prompts[line] = (label, color, weight)
781
783 """Defines the fields.
784
785 - override in child classes
786 - mostly uses _add_field()
787 """
788 _log.error('missing override in [%s]' % self.__class__.__name__)
789
790 - def _add_field(self, line=None, pos=None, widget=None, weight=0):
791 if None in (line, pos, widget):
792 _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget))
793 if line not in self.fields:
794 self.fields[line] = {}
795 self.fields[line][pos] = (widget, weight)
796
814
815
816
817
819 - def __init__ (self, parent, id = -1, pos = wx.DefaultPosition, size=wx.DefaultSize):
822
824 - def __init__(self, parent, id, pos, size, style):
825
826 print("class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__)
827
828
829 wx.Panel.__init__(self, parent, id, pos=pos, size=size, style=wx.NO_BORDER | wx.TAB_TRAVERSAL)
830 self.SetBackgroundColour(wx.Colour(222,222,222))
831
832 self.data = None
833 self.fields = {}
834 self.prompts = {}
835
836 ID_BTN_OK = wx.NewId()
837 ID_BTN_CLEAR = wx.NewId()
838
839 self.__do_layout()
840
841
842
843
844
845
846 self._patient = gmPerson.gmCurrentPatient()
847 self.__register_events()
848 self.Show(True)
849
850
851
853
854 self._define_prompts()
855 self.fields_pnl = wx.Panel(self, -1, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
856 self._define_fields(parent = self.fields_pnl)
857
858 szr_prompts = self.__generate_prompts()
859 szr_fields = self.__generate_fields()
860
861
862 self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL)
863 self.szr_main_panels.Add(szr_prompts, 11, wx.EXPAND)
864 self.szr_main_panels.Add(5, 0, 0, wx.EXPAND)
865 self.szr_main_panels.Add(szr_fields, 90, wx.EXPAND)
866
867
868
869 self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL)
870 self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5)
871
872
873 self.SetAutoLayout(True)
874 self.SetSizer(self.szr_central_container)
875 self.szr_central_container.Fit(self)
876
878 if len(self.fields) != len(self.prompts):
879 _log.error('[%s]: #fields != #prompts' % self.__class__.__name__)
880 return None
881
882 prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
883 prompt_pnl.SetBackgroundColour(richards_light_gray)
884
885 color = richards_aqua
886 lines = self.prompts.keys()
887 lines.sort()
888 self.prompt_widget = {}
889 for line in lines:
890 label, color, weight = self.prompts[line]
891 self.prompt_widget[line] = self.__make_prompt(prompt_pnl, "%s " % label, color)
892
893 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
894 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
895 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
896 szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND)
897 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
898
899
900 vszr_prompts = wx.BoxSizer(wx.VERTICAL)
901 vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND)
902 vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
903
904
905 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
906 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
907 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
908 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
909 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts, 1, wx.EXPAND)
910
911
912 hszr_prompts = wx.BoxSizer(wx.HORIZONTAL)
913 hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND)
914 hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
915
916 return hszr_prompts
917
919 self.fields_pnl.SetBackgroundColour(wx.Colour(222,222,222))
920
921 vszr = wx.BoxSizer(wx.VERTICAL)
922 lines = self.fields.keys()
923 lines.sort()
924 self.field_line_szr = {}
925 for line in lines:
926 self.field_line_szr[line] = wx.BoxSizer(wx.HORIZONTAL)
927 positions = self.fields[line].keys()
928 positions.sort()
929 for pos in positions:
930 field, weight = self.fields[line][pos]
931 self.field_line_szr[line].Add(field, weight, wx.EXPAND)
932 try:
933 vszr.Add(self.field_line_szr[line], self.prompts[line][2], flag = wx.EXPAND)
934 except KeyError:
935 _log.error("Error with line=%s, self.field_line_szr has key:%s; self.prompts has key: %s" % (
936 line,
937 (line in self.field_line_szr),
938 (line in self.prompts)
939 ))
940
941 self.fields_pnl.SetSizer(vszr)
942 vszr.Fit(self.fields_pnl)
943
944
945 shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
946 shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray)
947 szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
948 szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND)
949 szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND)
950
951
952 vszr_edit_fields = wx.BoxSizer(wx.VERTICAL)
953 vszr_edit_fields.Add(self.fields_pnl, 92, wx.EXPAND)
954 vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND)
955
956
957 shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
958 shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray)
959 szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL)
960 szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND)
961 szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND)
962
963
964 hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
965 hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND)
966 hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND)
967
968 return hszr_edit_fields
969
971
972 prompt = wx.StaticText(
973 parent,
974 -1,
975 aLabel,
976 style = wx.ALIGN_RIGHT
977 )
978 prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
979 prompt.SetForegroundColour(aColor)
980 return prompt
981
982
983
985 """Add a new prompt line.
986
987 To be used from _define_fields in child classes.
988
989 - label, the label text
990 - color
991 - weight, the weight given in sizing the various rows. 0 means the rwo
992 always has minimum size
993 """
994 self.prompts[line] = (label, color, weight)
995
996 - def _add_field(self, line=None, pos=None, widget=None, weight=0):
997 if None in (line, pos, widget):
998 _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget))
999 if line not in self.fields:
1000 self.fields[line] = {}
1001 self.fields[line][pos] = (widget, weight)
1002
1004 """Defines the fields.
1005
1006 - override in child classes
1007 - mostly uses _add_field()
1008 """
1009 _log.error('missing override in [%s]' % self.__class__.__name__)
1010
1012 _log.error('missing override in [%s]' % self.__class__.__name__)
1013
1027
1030
1032 _log.error('[%s] programmer forgot to define _save_data()' % self.__class__.__name__)
1033 _log.info('child classes of cEditArea *must* override this function')
1034 return False
1035
1036
1037
1039
1040 wx.EVT_BUTTON(self.btn_OK, ID_BTN_OK, self._on_OK_btn_pressed)
1041 wx.EVT_BUTTON(self.btn_Clear, ID_BTN_CLEAR, self._on_clear_btn_pressed)
1042
1043 wx.EVT_SIZE (self.fields_pnl, self._on_resize_fields)
1044
1045
1046 gmDispatcher.connect(signal = 'pre_patient_unselection', receiver = self._on_pre_patient_unselection)
1047 gmDispatcher.connect(signal = 'application_closing', receiver = self._on_application_closing)
1048 gmDispatcher.connect(signal = 'post_patient_selection', receiver = self.on_post_patient_selection)
1049
1050 return 1
1051
1052
1053
1055
1056 try:
1057 event.Skip()
1058 if self.data is None:
1059 self._save_new_entry()
1060 self.set_data()
1061 else:
1062 self._save_modified_entry()
1063 self.set_data()
1064 except Exception as err:
1065
1066
1067 gmGuiHelpers.gm_show_error (err, _("Invalid Input"))
1068 except:
1069 _log.exception( "save data problem in [%s]" % self.__class__.__name__)
1070
1075
1076 - def on_post_patient_selection( self, **kwds):
1077
1078 self.set_data()
1079
1081
1082 if not self._patient.connected:
1083 return True
1084 if self._save_data():
1085 return True
1086 _log.error('[%s] lossage' % self.__class__.__name__)
1087 return False
1088
1090
1091 if not self._patient.connected:
1092 return True
1093 if self._save_data():
1094 return True
1095 _log.error('[%s] lossage' % self.__class__.__name__)
1096 return False
1097
1099 self.fields_pnl.Layout()
1100
1101 for i in self.field_line_szr.keys():
1102
1103 pos = self.field_line_szr[i].GetPosition()
1104
1105 self.prompt_widget[i].SetPosition((0, pos.y))
1106
1108 - def __init__(self, parent, id, aType = None):
1109
1110 print("class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__)
1111
1112
1113 if aType not in _known_edit_area_types:
1114 _log.error('unknown edit area type: [%s]' % aType)
1115 raise gmExceptions.ConstructorError('unknown edit area type: [%s]' % aType)
1116 self._type = aType
1117
1118
1119 cEditArea.__init__(self, parent, id)
1120
1121 self.input_fields = {}
1122
1123 self._postInit()
1124 self.old_data = {}
1125
1126 self._patient = gmPerson.gmCurrentPatient()
1127 self.Show(True)
1128
1129
1130
1131
1132
1133
1135
1136 prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
1137 prompt_pnl.SetBackgroundColour(richards_light_gray)
1138
1139 gszr = wx.FlexGridSizer (len(prompt_labels)+1, 1, 2, 2)
1140 color = richards_aqua
1141 for prompt in prompt_labels:
1142 label = self.__make_prompt(prompt_pnl, "%s " % prompt, color)
1143 gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT)
1144 color = richards_blue
1145 gszr.RemoveGrowableRow (line-1)
1146
1147 prompt_pnl.SetSizer(gszr)
1148 gszr.Fit(prompt_pnl)
1149 prompt_pnl.SetAutoLayout(True)
1150
1151
1152 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1153 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
1154 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
1155 szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND)
1156 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
1157
1158
1159 vszr_prompts = wx.BoxSizer(wx.VERTICAL)
1160 vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND)
1161 vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
1162
1163
1164 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1165 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
1166 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
1167 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
1168 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND)
1169
1170
1171 hszr_prompts = wx.BoxSizer(wx.HORIZONTAL)
1172 hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND)
1173 hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
1174
1175 return hszr_prompts
1176
1178 _log.error('programmer forgot to define edit area lines for [%s]' % self._type)
1179 _log.info('child classes of gmEditArea *must* override this function')
1180 return []
1181
1183
1184 fields_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
1185 fields_pnl.SetBackgroundColour(wx.Colour(222,222,222))
1186
1187 gszr = wx.GridSizer(len(_prompt_defs[self._type]), 1, 2, 2)
1188
1189
1190 lines = self._make_edit_lines(parent = fields_pnl)
1191
1192 self.lines = lines
1193 if len(lines) != len(_prompt_defs[self._type]):
1194 _log.error('#(edit lines) not equal #(prompts) for [%s], something is fishy' % self._type)
1195 for line in lines:
1196 gszr.Add(line, 0, wx.EXPAND | wx.ALIGN_LEFT)
1197
1198 fields_pnl.SetSizer(gszr)
1199 gszr.Fit(fields_pnl)
1200 fields_pnl.SetAutoLayout(True)
1201
1202
1203 shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1204 shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray)
1205 szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
1206 szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND)
1207 szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND)
1208
1209
1210 vszr_edit_fields = wx.BoxSizer(wx.VERTICAL)
1211 vszr_edit_fields.Add(fields_pnl, 92, wx.EXPAND)
1212 vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND)
1213
1214
1215 shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1216 shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray)
1217 szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL)
1218 szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND)
1219 szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND)
1220
1221
1222 hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
1223 hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND)
1224 hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND)
1225
1226 return hszr_edit_fields
1227
1230
1235
1237 map = {}
1238 for k in self.input_fields.keys():
1239 map[k] = ''
1240 return map
1241
1242
1244 self._default_init_fields()
1245
1246
1247
1248
1249
1251 _log.warning("you may want to override _updateUI for [%s]" % self.__class__.__name__)
1252
1253
1254 - def _postInit(self):
1255 """override for further control setup"""
1256 pass
1257
1258
1260 szr = wx.BoxSizer(wx.HORIZONTAL)
1261 szr.Add( widget, weight, wx.EXPAND)
1262 szr.Add( 0,0, spacerWeight, wx.EXPAND)
1263 return szr
1264
1266
1267 cb = wx.CheckBox( parent, -1, _(title))
1268 cb.SetForegroundColour( richards_blue)
1269 return cb
1270
1271
1272
1274 """this is a utlity method to add extra columns"""
1275
1276 if "extraColumns" in self.__class__.__dict__:
1277 for x in self.__class__.extraColumns:
1278 lines = self._addColumn(parent, lines, x, weightMap)
1279 return lines
1280
1281
1282 - def _addColumn(self, parent, lines, extra, weightMap = {}, existingWeight = 5 , extraWeight = 2):
1283 """
1284 # add ia extra column in the edit area.
1285 # preconditions:
1286 # parent is fields_pnl (weak);
1287 # self.input_fields exists (required);
1288 # ; extra is a list of tuples of format -
1289 # ( key for input_fields, widget label , widget class to instantiate )
1290 """
1291 newlines = []
1292 i = 0
1293 for x in lines:
1294
1295 if x in weightMap:
1296 (existingWeight, extraWeight) = weightMap[x]
1297
1298 szr = wx.BoxSizer(wx.HORIZONTAL)
1299 szr.Add( x, existingWeight, wx.EXPAND)
1300 if i < len(extra) and extra[i] is not None:
1301 (inputKey, widgetLabel, aclass) = extra[i]
1302 if aclass.__name__ in CONTROLS_WITHOUT_LABELS:
1303 szr.Add( self._make_prompt(parent, widgetLabel, richards_blue) )
1304 widgetLabel = ""
1305
1306 w = aclass( parent, -1, widgetLabel)
1307 if not aclass.__name__ in CONTROLS_WITHOUT_LABELS:
1308 w.SetForegroundColour(richards_blue)
1309
1310 szr.Add(w, extraWeight , wx.EXPAND)
1311
1312
1313 self.input_fields[inputKey] = w
1314
1315 newlines.append(szr)
1316 i += 1
1317 return newlines
1318
1338
1341
1344
1350
1361
1362 -class gmPastHistoryEditArea(gmEditArea):
1363
1364 - def __init__(self, parent, id):
1365 gmEditArea.__init__(self, parent, id, aType = 'past history')
1366
1367 - def _define_prompts(self):
1368 self._add_prompt(line = 1, label = _("When Noted"))
1369 self._add_prompt(line = 2, label = _("Laterality"))
1370 self._add_prompt(line = 3, label = _("Condition"))
1371 self._add_prompt(line = 4, label = _("Notes"))
1372 self._add_prompt(line = 6, label = _("Status"))
1373 self._add_prompt(line = 7, label = _("Progress Note"))
1374 self._add_prompt(line = 8, label = '')
1375
1376 - def _define_fields(self, parent):
1377
1378 self.fld_date_noted = gmDateTimeInput.gmDateInput(
1379 parent = parent,
1380 id = -1,
1381 style = wx.SIMPLE_BORDER
1382 )
1383 self._add_field(
1384 line = 1,
1385 pos = 1,
1386 widget = self.fld_date_noted,
1387 weight = 2
1388 )
1389 self._add_field(
1390 line = 1,
1391 pos = 2,
1392 widget = cPrompt_edit_area(parent,-1, _("Age")),
1393 weight = 0)
1394
1395 self.fld_age_noted = cEditAreaField(parent)
1396 self._add_field(
1397 line = 1,
1398 pos = 3,
1399 widget = self.fld_age_noted,
1400 weight = 2
1401 )
1402
1403
1404 self.fld_laterality_none= wx.RadioButton(parent, -1, _("N/A"))
1405 self.fld_laterality_left= wx.RadioButton(parent, -1, _("L"))
1406 self.fld_laterality_right= wx.RadioButton(parent, -1, _("R"))
1407 self.fld_laterality_both= wx.RadioButton(parent, -1, _("both"))
1408 self._add_field(
1409 line = 2,
1410 pos = 1,
1411 widget = self.fld_laterality_none,
1412 weight = 0
1413 )
1414 self._add_field(
1415 line = 2,
1416 pos = 2,
1417 widget = self.fld_laterality_left,
1418 weight = 0
1419 )
1420 self._add_field(
1421 line = 2,
1422 pos = 3,
1423 widget = self.fld_laterality_right,
1424 weight = 1
1425 )
1426 self._add_field(
1427 line = 2,
1428 pos = 4,
1429 widget = self.fld_laterality_both,
1430 weight = 1
1431 )
1432
1433 self.fld_condition= cEditAreaField(parent)
1434 self._add_field(
1435 line = 3,
1436 pos = 1,
1437 widget = self.fld_condition,
1438 weight = 6
1439 )
1440
1441 self.fld_notes= cEditAreaField(parent)
1442 self._add_field(
1443 line = 4,
1444 pos = 1,
1445 widget = self.fld_notes,
1446 weight = 6
1447 )
1448
1449 self.fld_significant= wx.CheckBox(
1450 parent,
1451 -1,
1452 _("significant"),
1453 style = wx.NO_BORDER
1454 )
1455 self.fld_active= wx.CheckBox(
1456 parent,
1457 -1,
1458 _("active"),
1459 style = wx.NO_BORDER
1460 )
1461
1462 self._add_field(
1463 line = 5,
1464 pos = 1,
1465 widget = self.fld_significant,
1466 weight = 0
1467 )
1468 self._add_field(
1469 line = 5,
1470 pos = 2,
1471 widget = self.fld_active,
1472 weight = 0
1473 )
1474
1475 self.fld_progress= cEditAreaField(parent)
1476 self._add_field(
1477 line = 6,
1478 pos = 1,
1479 widget = self.fld_progress,
1480 weight = 6
1481 )
1482
1483
1484 self._add_field(
1485 line = 7,
1486 pos = 4,
1487 widget = self._make_standard_buttons(parent),
1488 weight = 2
1489 )
1490
1491 - def _postInit(self):
1492 return
1493
1494 wx.EVT_KILL_FOCUS( self.fld_age_noted, self._ageKillFocus)
1495 wx.EVT_KILL_FOCUS( self.fld_date_noted, self._yearKillFocus)
1496
1497 - def _ageKillFocus( self, event):
1498
1499 event.Skip()
1500 try :
1501 year = self._getBirthYear() + int(self.fld_age_noted.GetValue().strip() )
1502 self.fld_date_noted.SetValue( str (year) )
1503 except:
1504 pass
1505
1506 - def _getBirthYear(self):
1507 try:
1508 birthyear = int(str(self._patient['dob']).split('-')[0])
1509 except:
1510
1511 birthyear = 1
1512
1513 return birthyear
1514
1515 - def _yearKillFocus( self, event):
1516 event.Skip()
1517 try:
1518 age = int(self.fld_date_noted.GetValue().strip() ) - self._getBirthYear()
1519 self.fld_age_noted.SetValue( str (age) )
1520 except:
1521 pass
1522
1523 __init_values = {
1524 "condition": "",
1525 "notes1": "",
1526 "notes2": "",
1527 "age": "",
1528
1529 "progress": "",
1530 "active": 1,
1531 "operation": 0,
1532 "confidential": 0,
1533 "significant": 1,
1534 "both": 0,
1535 "left": 0,
1536 "right": 0,
1537 "none" : 1
1538 }
1539
1540 - def _getDefaultAge(self):
1541 try:
1542
1543 return 1
1544 except:
1545 return 0
1546
1547 - def _get_init_values(self):
1548 values = gmPastHistoryEditArea.__init_values
1549 values["age"] = str( self._getDefaultAge())
1550 return values
1551
1552 - def _save_data(self):
1553 clinical = self._patient.emr.get_past_history()
1554 if self.getDataId() is None:
1555 id = clinical.create_history( self.get_fields_formatting_values() )
1556 self.setDataId(id)
1557 return
1558
1559 clinical.update_history( self.get_fields_formatting_values(), self.getDataId() )
1560
1561
1571
1573 self._add_prompt (line = 1, label = _ ("Specialty"))
1574 self._add_prompt (line = 2, label = _ ("Name"))
1575 self._add_prompt (line = 3, label = _ ("Address"))
1576 self._add_prompt (line = 4, label = _ ("Options"))
1577 self._add_prompt (line = 5, label = _("Text"), weight =6)
1578 self._add_prompt (line = 6, label = "")
1579
1581 self.fld_specialty = gmPhraseWheel.cPhraseWheel (
1582 parent = parent,
1583 id = -1,
1584 style = wx.SIMPLE_BORDER
1585 )
1586
1587 self._add_field (
1588 line = 1,
1589 pos = 1,
1590 widget = self.fld_specialty,
1591 weight = 1
1592 )
1593 self.fld_name = gmPhraseWheel.cPhraseWheel (
1594 parent = parent,
1595 id = -1,
1596 style = wx.SIMPLE_BORDER
1597 )
1598
1599 self._add_field (
1600 line = 2,
1601 pos = 1,
1602 widget = self.fld_name,
1603 weight = 1
1604 )
1605 self.fld_address = wx.ComboBox (parent, -1, style = wx.CB_READONLY)
1606
1607 self._add_field (
1608 line = 3,
1609 pos = 1,
1610 widget = self.fld_address,
1611 weight = 1
1612 )
1613
1614
1615 self.fld_name.add_callback_on_selection(self.setAddresses)
1616
1617 self.fld_med = wx.CheckBox (parent, -1, _("Meds"), style=wx.NO_BORDER)
1618 self._add_field (
1619 line = 4,
1620 pos = 1,
1621 widget = self.fld_med,
1622 weight = 1
1623 )
1624 self.fld_past = wx.CheckBox (parent, -1, _("Past Hx"), style=wx.NO_BORDER)
1625 self._add_field (
1626 line = 4,
1627 pos = 4,
1628 widget = self.fld_past,
1629 weight = 1
1630 )
1631 self.fld_text = wx.TextCtrl (parent, -1, style= wx.TE_MULTILINE)
1632 self._add_field (
1633 line = 5,
1634 pos = 1,
1635 widget = self.fld_text,
1636 weight = 1)
1637
1638 self._add_field(
1639 line = 6,
1640 pos = 1,
1641 widget = self._make_standard_buttons(parent),
1642 weight = 1
1643 )
1644 return 1
1645
1647 """
1648 Doesn't accept any value as this doesn't make sense for this edit area
1649 """
1650 self.fld_specialty.SetValue ('')
1651 self.fld_name.SetValue ('')
1652 self.fld_address.Clear ()
1653 self.fld_address.SetValue ('')
1654 self.fld_med.SetValue (0)
1655 self.fld_past.SetValue (0)
1656 self.fld_text.SetValue ('')
1657 self.recipient = None
1658
1660 """
1661 Set the available addresses for the selected identity
1662 """
1663 if id is None:
1664 self.recipient = None
1665 self.fld_address.Clear ()
1666 self.fld_address.SetValue ('')
1667 else:
1668 self.recipient = gmDemographicRecord.cDemographicRecord_SQL (id)
1669 self.fld_address.Clear ()
1670 self.addr = self.recipient.getAddresses ('work')
1671 for i in self.addr:
1672 self.fld_address.Append (_("%(number)s %(street)s, %(urb)s %(postcode)s") % i, ('post', i))
1673 fax = self.recipient.getCommChannel (gmDemographicRecord.FAX)
1674 email = self.recipient.getCommChannel (gmDemographicRecord.EMAIL)
1675 if fax:
1676 self.fld_address.Append ("%s: %s" % (_("FAX"), fax), ('fax', fax))
1677 if email:
1678 self.fld_address.Append ("%s: %s" % (_("E-MAIL"), email), ('email', email))
1679
1680 - def _save_new_entry(self):
1681 """
1682 We are always saving a "new entry" here because data_ID is always None
1683 """
1684 if not self.recipient:
1685 raise UserWarning(_('must have a recipient'))
1686 if self.fld_address.GetSelection() == -1:
1687 raise UserWarning(_('must select address'))
1688 channel, addr = self.fld_address.GetClientData (self.fld_address.GetSelection())
1689 text = self.fld_text.GetValue()
1690 flags = {}
1691 flags['meds'] = self.fld_med.GetValue()
1692 flags['pasthx'] = self.fld_past.GetValue()
1693 if not gmReferral.create_referral (self._patient, self.recipient, channel, addr, text, flags):
1694 raise UserWarning('error sending form')
1695
1696
1697
1698
1699
1707
1708
1709
1711 _log.debug("making prescription lines")
1712 lines = []
1713 self.txt_problem = cEditAreaField(parent)
1714 self.txt_class = cEditAreaField(parent)
1715 self.txt_generic = cEditAreaField(parent)
1716 self.txt_drug_product = cEditAreaField(parent)
1717 self.txt_strength= cEditAreaField(parent)
1718 self.txt_directions= cEditAreaField(parent)
1719 self.txt_for = cEditAreaField(parent)
1720 self.txt_progress = cEditAreaField(parent)
1721
1722 lines.append(self.txt_problem)
1723 lines.append(self.txt_class)
1724 lines.append(self.txt_generic)
1725 lines.append(self.txt_drug_product)
1726 lines.append(self.txt_strength)
1727 lines.append(self.txt_directions)
1728 lines.append(self.txt_for)
1729 lines.append(self.txt_progress)
1730 lines.append(self._make_standard_buttons(parent))
1731 self.input_fields = {
1732 "problem": self.txt_problem,
1733 "class" : self.txt_class,
1734 "generic" : self.txt_generic,
1735 "prod" : self.txt_drug_product,
1736 "strength": self.txt_strength,
1737 "directions": self.txt_directions,
1738 "for" : self.txt_for,
1739 "progress": self.txt_progress
1740
1741 }
1742
1743 return self._makeExtraColumns( parent, lines)
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1762
1763
1764
1765
1766
1767
1770 wx.StaticText.__init__(self, parent, id, prompt, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_LEFT)
1771 self.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
1772 self.SetForegroundColour(aColor)
1773
1774
1775
1776
1777
1779 - def __init__(self, parent, id, prompt_labels):
1780 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
1781 self.SetBackgroundColour(richards_light_gray)
1782 gszr = wx.GridSizer (len(prompt_labels)+1, 1, 2, 2)
1783 color = richards_aqua
1784 for prompt_key in prompt_labels.keys():
1785 label = cPrompt_edit_area(self, -1, " %s" % prompt_labels[prompt_key], aColor = color)
1786 gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT)
1787 color = richards_blue
1788 self.SetSizer(gszr)
1789 gszr.Fit(self)
1790 self.SetAutoLayout(True)
1791
1792
1793
1794
1795
1796
1797
1798 -class EditTextBoxes(wx.Panel):
1799 - def __init__(self, parent, id, editareaprompts, section):
1800 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize,style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
1801 self.SetBackgroundColour(wx.Colour(222,222,222))
1802 self.parent = parent
1803
1804 self.gszr = wx.GridSizer(len(editareaprompts), 1, 2, 2)
1805
1806 if section == gmSECTION_SUMMARY:
1807 pass
1808 elif section == gmSECTION_DEMOGRAPHICS:
1809 pass
1810 elif section == gmSECTION_CLINICALNOTES:
1811 pass
1812 elif section == gmSECTION_FAMILYHISTORY:
1813 pass
1814 elif section == gmSECTION_PASTHISTORY:
1815 pass
1816
1817
1818 self.txt_condition = cEditAreaField(self,PHX_CONDITION,wx.DefaultPosition,wx.DefaultSize)
1819 self.rb_sideleft = wxRadioButton(self,PHX_LEFT, _(" (L) "), wx.DefaultPosition,wx.DefaultSize)
1820 self.rb_sideright = wxRadioButton(self, PHX_RIGHT, _("(R)"), wx.DefaultPosition,wx.DefaultSize,wx.SUNKEN_BORDER)
1821 self.rb_sideboth = wxRadioButton(self, PHX_BOTH, _("Both"), wx.DefaultPosition,wx.DefaultSize)
1822 rbsizer = wx.BoxSizer(wx.HORIZONTAL)
1823 rbsizer.Add(self.rb_sideleft,1,wx.EXPAND)
1824 rbsizer.Add(self.rb_sideright,1,wx.EXPAND)
1825 rbsizer.Add(self.rb_sideboth,1,wx.EXPAND)
1826 szr1 = wx.BoxSizer(wx.HORIZONTAL)
1827 szr1.Add(self.txt_condition, 4, wx.EXPAND)
1828 szr1.Add(rbsizer, 3, wx.EXPAND)
1829
1830
1831
1832
1833 self.txt_notes1 = cEditAreaField(self,PHX_NOTES,wx.DefaultPosition,wx.DefaultSize)
1834
1835 self.txt_notes2= cEditAreaField(self,PHX_NOTES2,wx.DefaultPosition,wx.DefaultSize)
1836
1837 self.txt_agenoted = cEditAreaField(self, PHX_AGE, wx.DefaultPosition, wx.DefaultSize)
1838 szr4 = wx.BoxSizer(wx.HORIZONTAL)
1839 szr4.Add(self.txt_agenoted, 1, wx.EXPAND)
1840 szr4.Add(5, 0, 5)
1841
1842 self.txt_yearnoted = cEditAreaField(self,PHX_YEAR,wx.DefaultPosition,wx.DefaultSize)
1843 szr5 = wx.BoxSizer(wx.HORIZONTAL)
1844 szr5.Add(self.txt_yearnoted, 1, wx.EXPAND)
1845 szr5.Add(5, 0, 5)
1846
1847 self.parent.cb_active = wx.CheckBox(self, PHX_ACTIVE, _("Active"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1848 self.parent.cb_operation = wx.CheckBox(self, PHX_OPERATION, _("Operation"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1849 self.parent.cb_confidential = wx.CheckBox(self, PHX_CONFIDENTIAL , _("Confidential"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1850 self.parent.cb_significant = wx.CheckBox(self, PHX_SIGNIFICANT, _("Significant"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1851 szr6 = wx.BoxSizer(wx.HORIZONTAL)
1852 szr6.Add(self.parent.cb_active, 1, wx.EXPAND)
1853 szr6.Add(self.parent.cb_operation, 1, wx.EXPAND)
1854 szr6.Add(self.parent.cb_confidential, 1, wx.EXPAND)
1855 szr6.Add(self.parent.cb_significant, 1, wx.EXPAND)
1856
1857 self.txt_progressnotes = cEditAreaField(self,PHX_PROGRESSNOTES ,wx.DefaultPosition,wx.DefaultSize)
1858
1859 szr8 = wx.BoxSizer(wx.HORIZONTAL)
1860 szr8.Add(5, 0, 6)
1861 szr8.Add(self._make_standard_buttons(), 0, wx.EXPAND)
1862
1863 self.gszr.Add(szr1,0,wx.EXPAND)
1864 self.gszr.Add(self.txt_notes1,0,wx.EXPAND)
1865 self.gszr.Add(self.txt_notes2,0,wx.EXPAND)
1866 self.gszr.Add(szr4,0,wx.EXPAND)
1867 self.gszr.Add(szr5,0,wx.EXPAND)
1868 self.gszr.Add(szr6,0,wx.EXPAND)
1869 self.gszr.Add(self.txt_progressnotes,0,wx.EXPAND)
1870 self.gszr.Add(szr8,0,wx.EXPAND)
1871
1872
1873 elif section == gmSECTION_SCRIPT:
1874 pass
1875 elif section == gmSECTION_REQUESTS:
1876 pass
1877 elif section == gmSECTION_RECALLS:
1878 pass
1879 else:
1880 pass
1881
1882 self.SetSizer(self.gszr)
1883 self.gszr.Fit(self)
1884
1885 self.SetAutoLayout(True)
1886 self.Show(True)
1887
1889 self.btn_OK = wx.Button(self, -1, _("Ok"))
1890 self.btn_Clear = wx.Button(self, -1, _("Clear"))
1891 szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
1892 szr_buttons.Add(self.btn_OK, 1, wx.EXPAND, wx.ALL, 1)
1893 szr_buttons.Add(5, 0, 0)
1894 szr_buttons.Add(self.btn_Clear, 1, wx.EXPAND, wx.ALL, 1)
1895 return szr_buttons
1896
1898 - def __init__(self, parent, id, line_labels, section):
1899 _log.warning('***** old style EditArea instantiated, please convert *****')
1900
1901 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, style = wx.NO_BORDER)
1902 self.SetBackgroundColour(wx.Colour(222,222,222))
1903
1904
1905 prompts = gmPnlEditAreaPrompts(self, -1, line_labels)
1906
1907 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1908
1909 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
1910 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
1911 szr_shadow_below_prompts.Add(5,0,0,wx.EXPAND)
1912 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
1913
1914 szr_prompts = wx.BoxSizer(wx.VERTICAL)
1915 szr_prompts.Add(prompts, 97, wx.EXPAND)
1916 szr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
1917
1918
1919 edit_fields = EditTextBoxes(self, -1, line_labels, section)
1920
1921 shadow_below_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1922
1923 shadow_below_editarea.SetBackgroundColour(richards_coloured_gray)
1924 szr_shadow_below_editarea = wx.BoxSizer(wx.HORIZONTAL)
1925 szr_shadow_below_editarea.Add(5,0,0,wx.EXPAND)
1926 szr_shadow_below_editarea.Add(shadow_below_editarea, 12, wx.EXPAND)
1927
1928 szr_editarea = wx.BoxSizer(wx.VERTICAL)
1929 szr_editarea.Add(edit_fields, 92, wx.EXPAND)
1930 szr_editarea.Add(szr_shadow_below_editarea, 5, wx.EXPAND)
1931
1932
1933
1934 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1935 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
1936 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
1937 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
1938 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND)
1939
1940 shadow_rightof_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1941 shadow_rightof_editarea.SetBackgroundColour(richards_coloured_gray)
1942 szr_shadow_rightof_editarea = wx.BoxSizer(wx.VERTICAL)
1943 szr_shadow_rightof_editarea.Add(0, 5, 0, wx.EXPAND)
1944 szr_shadow_rightof_editarea.Add(shadow_rightof_editarea, 1, wx.EXPAND)
1945
1946
1947 self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL)
1948 self.szr_main_panels.Add(szr_prompts, 10, wx.EXPAND)
1949 self.szr_main_panels.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
1950 self.szr_main_panels.Add(5, 0, 0, wx.EXPAND)
1951 self.szr_main_panels.Add(szr_editarea, 89, wx.EXPAND)
1952 self.szr_main_panels.Add(szr_shadow_rightof_editarea, 1, wx.EXPAND)
1953
1954
1955
1956 self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL)
1957 self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5)
1958 self.SetSizer(self.szr_central_container)
1959 self.szr_central_container.Fit(self)
1960 self.SetAutoLayout(True)
1961 self.Show(True)
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238 if __name__ == "__main__":
2239
2240
2245 self._add_prompt(line=1, label='line 1')
2246 self._add_prompt(line=2, label='buttons')
2248
2249 self.fld_substance = cEditAreaField(parent)
2250 self._add_field(
2251 line = 1,
2252 pos = 1,
2253 widget = self.fld_substance,
2254 weight = 1
2255 )
2256
2257 self._add_field(
2258 line = 2,
2259 pos = 1,
2260 widget = self._make_standard_buttons(parent),
2261 weight = 1
2262 )
2263
2264 app = wxPyWidgetTester(size = (400, 200))
2265 app.SetWidget(cTestEditArea)
2266 app.MainLoop()
2267
2268
2269
2270
2271
2272
2273
2274