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 wxgGenericEditAreaDlg2.wxgGenericEditAreaDlg2.__init__(self, *args, **kwargs)
302
303 self.left_extra_button = None
304
305 if cGenericEditAreaDlg2._today.day != cGenericEditAreaDlg2._lucky_day:
306 self._BTN_lucky.Enable(False)
307 self._BTN_lucky.Hide()
308 else:
309 if cGenericEditAreaDlg2._today.month != cGenericEditAreaDlg2._lucky_month:
310 self._BTN_lucky.Enable(False)
311 self._BTN_lucky.Hide()
312
313
314 dummy_ea_pnl = self._PNL_ea
315 ea_pnl_szr = dummy_ea_pnl.GetContainingSizer()
316 ea_pnl_parent = dummy_ea_pnl.GetParent()
317
318 dummy_ea_pnl.Destroy()
319 del dummy_ea_pnl
320 new_ea_min_size = new_ea.GetMinSize()
321 new_ea.Reparent(ea_pnl_parent)
322 self._PNL_ea = new_ea
323 ea_pnl_szr.Add(self._PNL_ea, 1, wx.EXPAND, 0)
324 ea_pnl_szr.SetMinSize(new_ea_min_size)
325 ea_pnl_szr.Fit(new_ea)
326
327
328 if single_entry:
329 self._BTN_forward.Enable(False)
330 self._BTN_forward.Hide()
331
332 self._adjust_clear_revert_buttons()
333
334
335 self._TCTRL_status.SetValue('')
336 gmDispatcher.connect(signal = 'statustext', receiver = self._on_set_statustext)
337
338
339
340 main_szr = self.GetSizer()
341 main_szr.Fit(self)
342 self.Layout()
343
344
345 self._PNL_ea.refresh()
346
347 - def _on_set_statustext(self, msg=None, loglevel=None, beep=True):
348 if msg is None:
349 self._TCTRL_status.SetValue('')
350 return
351 if msg.strip() == '':
352 self._TCTRL_status.SetValue('')
353 return
354 self._TCTRL_status.SetValue(msg)
355 return
356
368
376
379
382
397
408
417
418
419
435
436 left_extra_button = property(lambda x:x, _set_left_extra_button)
437
438
439
440
441
442
443
444
445
446 from Gnumed.pycommon import gmGuiBroker
447
448
449 _gb = gmGuiBroker.GuiBroker()
450
451 gmSECTION_SUMMARY = 1
452 gmSECTION_DEMOGRAPHICS = 2
453 gmSECTION_CLINICALNOTES = 3
454 gmSECTION_FAMILYHISTORY = 4
455 gmSECTION_PASTHISTORY = 5
456 gmSECTION_SCRIPT = 8
457 gmSECTION_REQUESTS = 9
458 gmSECTION_REFERRALS = 11
459 gmSECTION_RECALLS = 12
460
461 richards_blue = wx.Colour(0,0,131)
462 richards_aqua = wx.Colour(0,194,197)
463 richards_dark_gray = wx.Colour(131,129,131)
464 richards_light_gray = wx.Colour(255,255,255)
465 richards_coloured_gray = wx.Colour(131,129,131)
466
467
468 CONTROLS_WITHOUT_LABELS =['wxTextCtrl', 'cEditAreaField', 'wx.SpinCtrl', 'gmPhraseWheel', 'wx.ComboBox']
469
471 widget.SetForegroundColour(wx.Colour(255, 0, 0))
472 widget.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
473
486 if not isinstance(edit_area, cEditArea2):
487 raise TypeError('<edit_area> must be of type cEditArea2 but is <%s>' % type(edit_area))
488 wx.Dialog.__init__(self, parent, id, title, pos, size, style, name)
489 self.__wxID_BTN_SAVE = wx.NewId()
490 self.__wxID_BTN_RESET = wx.NewId()
491 self.__editarea = edit_area
492 self.__do_layout()
493 self.__register_events()
494
495
496
499
501 self.__editarea.Reparent(self)
502
503 self.__btn_SAVE = wx.Button(self, self.__wxID_BTN_SAVE, _("Save"))
504 self.__btn_SAVE.SetToolTip(_('save entry into medical record'))
505 self.__btn_RESET = wx.Button(self, self.__wxID_BTN_RESET, _("Reset"))
506 self.__btn_RESET.SetToolTip(_('reset entry'))
507 self.__btn_CANCEL = wx.Button(self, wx.ID_CANCEL, _("Cancel"))
508 self.__btn_CANCEL.SetToolTip(_('discard entry and cancel'))
509
510 szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
511 szr_buttons.Add(self.__btn_SAVE, 1, wx.EXPAND | wx.ALL, 1)
512 szr_buttons.Add(self.__btn_RESET, 1, wx.EXPAND | wx.ALL, 1)
513 szr_buttons.Add(self.__btn_CANCEL, 1, wx.EXPAND | wx.ALL, 1)
514
515 szr_main = wx.BoxSizer(wx.VERTICAL)
516 szr_main.Add(self.__editarea, 1, wx.EXPAND)
517 szr_main.Add(szr_buttons, 0, wx.EXPAND)
518
519 self.SetSizerAndFit(szr_main)
520
521
522
524
525 wx.EVT_BUTTON(self.__btn_SAVE, self.__wxID_BTN_SAVE, self._on_SAVE_btn_pressed)
526 wx.EVT_BUTTON(self.__btn_RESET, self.__wxID_BTN_RESET, self._on_RESET_btn_pressed)
527 wx.EVT_BUTTON(self.__btn_CANCEL, wx.ID_CANCEL, self._on_CANCEL_btn_pressed)
528
529 wx.EVT_CLOSE(self, self._on_CANCEL_btn_pressed)
530
531
532
533
534
535
536 return 1
537
539 if self.__editarea.save_data():
540 self.__editarea.Close()
541 self.EndModal(wx.ID_OK)
542 return
543 short_err = self.__editarea.get_short_error()
544 long_err = self.__editarea.get_long_error()
545 if (short_err is None) and (long_err is None):
546 long_err = _(
547 'Unspecified error saving data in edit area.\n\n'
548 'Programmer forgot to specify proper error\n'
549 'message in [%s].'
550 ) % self.__editarea.__class__.__name__
551 if short_err is not None:
552 gmDispatcher.send(signal = 'statustext', msg = short_err)
553 if long_err is not None:
554 gmGuiHelpers.gm_show_error(long_err, _('saving clinical data'))
555
557 self.__editarea.Close()
558 self.EndModal(wx.ID_CANCEL)
559
562
564 - def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TAB_TRAVERSAL):
565
566 wx.Panel.__init__ (
567 self,
568 parent,
569 id,
570 pos = pos,
571 size = size,
572 style = style | wx.TAB_TRAVERSAL
573 )
574 self.SetBackgroundColour(wx.Colour(222,222,222))
575
576 self.data = None
577 self.fields = {}
578 self.prompts = {}
579 self._short_error = None
580 self._long_error = None
581 self._summary = None
582 self._patient = gmPerson.gmCurrentPatient()
583 self.__wxID_BTN_OK = wx.NewId()
584 self.__wxID_BTN_CLEAR = wx.NewId()
585 self.__do_layout()
586 self.__register_events()
587 self.Show()
588
589
590
592 """This needs to be overridden by child classes."""
593 self._long_error = _(
594 'Cannot save data from edit area.\n\n'
595 'Programmer forgot to override method:\n'
596 ' <%s.save_data>'
597 ) % self.__class__.__name__
598 return False
599
601 msg = _(
602 'Cannot reset fields in edit area.\n\n'
603 'Programmer forgot to override method:\n'
604 ' <%s.reset_ui>'
605 ) % self.__class__.__name__
606 gmGuiHelpers.gm_show_error(msg)
607
609 tmp = self._short_error
610 self._short_error = None
611 return tmp
612
614 tmp = self._long_error
615 self._long_error = None
616 return tmp
617
619 return _('<No embed string for [%s]>') % self.__class__.__name__
620
621
622
634
639
640
641
643 self.__deregister_events()
644 event.Skip()
645
647 """Only active if _make_standard_buttons was called in child class."""
648
649 try:
650 event.Skip()
651 if self.data is None:
652 self._save_new_entry()
653 self.reset_ui()
654 else:
655 self._save_modified_entry()
656 self.reset_ui()
657 except Exception as err:
658
659
660 gmGuiHelpers.gm_show_error (err, _("Invalid Input"))
661 except:
662 _log.exception( "save data problem in [%s]" % self.__class__.__name__)
663
665 """Only active if _make_standard_buttons was called in child class."""
666
667 self.reset_ui()
668 event.Skip()
669
671 self.__deregister_events()
672
673 if not self._patient.connected:
674 return True
675
676
677
678
679 return True
680 _log.error('[%s] lossage' % self.__class__.__name__)
681 return False
682
684 """Just before new patient becomes active."""
685
686 if not self._patient.connected:
687 return True
688
689
690
691
692 return True
693 _log.error('[%s] lossage' % self.__class__.__name__)
694 return False
695
697 """Just after new patient became active."""
698
699 self.reset_ui()
700
701
702
704
705
706 self._define_prompts()
707 self._define_fields(parent = self)
708 if len(self.fields) != len(self.prompts):
709 _log.error('[%s]: #fields != #prompts' % self.__class__.__name__)
710 return None
711
712
713 szr_main_fgrid = wx.FlexGridSizer(rows = len(self.prompts), cols=2)
714 color = richards_aqua
715 lines = self.prompts.keys()
716 lines.sort()
717 for line in lines:
718
719 label, color, weight = self.prompts[line]
720
721 prompt = wx.StaticText (
722 parent = self,
723 id = -1,
724 label = label,
725 style = wx.ALIGN_CENTRE
726 )
727
728 prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
729 prompt.SetForegroundColour(color)
730 prompt.SetBackgroundColour(richards_light_gray)
731 szr_main_fgrid.Add(prompt, flag=wx.EXPAND | wx.ALIGN_RIGHT)
732
733
734 szr_line = wx.BoxSizer(wx.HORIZONTAL)
735 positions = self.fields[line].keys()
736 positions.sort()
737 for pos in positions:
738 field, weight = self.fields[line][pos]
739
740 szr_line.Add(field, weight, wx.EXPAND)
741 szr_main_fgrid.Add(szr_line, flag=wx.GROW | wx.ALIGN_LEFT)
742
743
744 szr_main_fgrid.AddGrowableCol(1)
745
746
747
748
749
750
751
752 self.SetSizerAndFit(szr_main_fgrid)
753
754
755
756
758 """Child classes override this to define their prompts using _add_prompt()"""
759 _log.error('missing override in [%s]' % self.__class__.__name__)
760
762 """Add a new prompt line.
763
764 To be used from _define_fields in child classes.
765
766 - label, the label text
767 - color
768 - weight, the weight given in sizing the various rows. 0 means the row
769 always has minimum size
770 """
771 self.prompts[line] = (label, color, weight)
772
774 """Defines the fields.
775
776 - override in child classes
777 - mostly uses _add_field()
778 """
779 _log.error('missing override in [%s]' % self.__class__.__name__)
780
781 - def _add_field(self, line=None, pos=None, widget=None, weight=0):
782 if None in (line, pos, widget):
783 _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget))
784 if line not in self.fields:
785 self.fields[line] = {}
786 self.fields[line][pos] = (widget, weight)
787
805
806
807
808
810 - def __init__ (self, parent, id = -1, pos = wx.DefaultPosition, size=wx.DefaultSize):
813
815 - def __init__(self, parent, id, pos, size, style):
816
817 print("class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__)
818
819
820 wx.Panel.__init__(self, parent, id, pos=pos, size=size, style=wx.NO_BORDER | wx.TAB_TRAVERSAL)
821 self.SetBackgroundColour(wx.Colour(222,222,222))
822
823 self.data = None
824 self.fields = {}
825 self.prompts = {}
826
827 ID_BTN_OK = wx.NewId()
828 ID_BTN_CLEAR = wx.NewId()
829
830 self.__do_layout()
831
832
833
834
835
836
837 self._patient = gmPerson.gmCurrentPatient()
838 self.__register_events()
839 self.Show(True)
840
841
842
844
845 self._define_prompts()
846 self.fields_pnl = wx.Panel(self, -1, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
847 self._define_fields(parent = self.fields_pnl)
848
849 szr_prompts = self.__generate_prompts()
850 szr_fields = self.__generate_fields()
851
852
853 self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL)
854 self.szr_main_panels.Add(szr_prompts, 11, wx.EXPAND)
855 self.szr_main_panels.Add(5, 0, 0, wx.EXPAND)
856 self.szr_main_panels.Add(szr_fields, 90, wx.EXPAND)
857
858
859
860 self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL)
861 self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5)
862
863
864 self.SetAutoLayout(True)
865 self.SetSizer(self.szr_central_container)
866 self.szr_central_container.Fit(self)
867
869 if len(self.fields) != len(self.prompts):
870 _log.error('[%s]: #fields != #prompts' % self.__class__.__name__)
871 return None
872
873 prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
874 prompt_pnl.SetBackgroundColour(richards_light_gray)
875
876 color = richards_aqua
877 lines = self.prompts.keys()
878 lines.sort()
879 self.prompt_widget = {}
880 for line in lines:
881 label, color, weight = self.prompts[line]
882 self.prompt_widget[line] = self.__make_prompt(prompt_pnl, "%s " % label, color)
883
884 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
885 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
886 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
887 szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND)
888 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
889
890
891 vszr_prompts = wx.BoxSizer(wx.VERTICAL)
892 vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND)
893 vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
894
895
896 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
897 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
898 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
899 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
900 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts, 1, wx.EXPAND)
901
902
903 hszr_prompts = wx.BoxSizer(wx.HORIZONTAL)
904 hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND)
905 hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
906
907 return hszr_prompts
908
910 self.fields_pnl.SetBackgroundColour(wx.Colour(222,222,222))
911
912 vszr = wx.BoxSizer(wx.VERTICAL)
913 lines = self.fields.keys()
914 lines.sort()
915 self.field_line_szr = {}
916 for line in lines:
917 self.field_line_szr[line] = wx.BoxSizer(wx.HORIZONTAL)
918 positions = self.fields[line].keys()
919 positions.sort()
920 for pos in positions:
921 field, weight = self.fields[line][pos]
922 self.field_line_szr[line].Add(field, weight, wx.EXPAND)
923 try:
924 vszr.Add(self.field_line_szr[line], self.prompts[line][2], flag = wx.EXPAND)
925 except KeyError:
926 _log.error("Error with line=%s, self.field_line_szr has key:%s; self.prompts has key: %s" % (
927 line,
928 (line in self.field_line_szr),
929 (line in self.prompts)
930 ))
931
932 self.fields_pnl.SetSizer(vszr)
933 vszr.Fit(self.fields_pnl)
934
935
936 shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
937 shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray)
938 szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
939 szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND)
940 szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND)
941
942
943 vszr_edit_fields = wx.BoxSizer(wx.VERTICAL)
944 vszr_edit_fields.Add(self.fields_pnl, 92, wx.EXPAND)
945 vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND)
946
947
948 shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
949 shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray)
950 szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL)
951 szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND)
952 szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND)
953
954
955 hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
956 hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND)
957 hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND)
958
959 return hszr_edit_fields
960
962
963 prompt = wx.StaticText(
964 parent,
965 -1,
966 aLabel,
967 style = wx.ALIGN_RIGHT
968 )
969 prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
970 prompt.SetForegroundColour(aColor)
971 return prompt
972
973
974
976 """Add a new prompt line.
977
978 To be used from _define_fields in child classes.
979
980 - label, the label text
981 - color
982 - weight, the weight given in sizing the various rows. 0 means the rwo
983 always has minimum size
984 """
985 self.prompts[line] = (label, color, weight)
986
987 - def _add_field(self, line=None, pos=None, widget=None, weight=0):
988 if None in (line, pos, widget):
989 _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget))
990 if line not in self.fields:
991 self.fields[line] = {}
992 self.fields[line][pos] = (widget, weight)
993
995 """Defines the fields.
996
997 - override in child classes
998 - mostly uses _add_field()
999 """
1000 _log.error('missing override in [%s]' % self.__class__.__name__)
1001
1003 _log.error('missing override in [%s]' % self.__class__.__name__)
1004
1018
1021
1023 _log.error('[%s] programmer forgot to define _save_data()' % self.__class__.__name__)
1024 _log.info('child classes of cEditArea *must* override this function')
1025 return False
1026
1027
1028
1030
1031 wx.EVT_BUTTON(self.btn_OK, ID_BTN_OK, self._on_OK_btn_pressed)
1032 wx.EVT_BUTTON(self.btn_Clear, ID_BTN_CLEAR, self._on_clear_btn_pressed)
1033
1034 wx.EVT_SIZE (self.fields_pnl, self._on_resize_fields)
1035
1036
1037 gmDispatcher.connect(signal = 'pre_patient_unselection', receiver = self._on_pre_patient_unselection)
1038 gmDispatcher.connect(signal = 'application_closing', receiver = self._on_application_closing)
1039 gmDispatcher.connect(signal = 'post_patient_selection', receiver = self.on_post_patient_selection)
1040
1041 return 1
1042
1043
1044
1046
1047 try:
1048 event.Skip()
1049 if self.data is None:
1050 self._save_new_entry()
1051 self.set_data()
1052 else:
1053 self._save_modified_entry()
1054 self.set_data()
1055 except Exception as err:
1056
1057
1058 gmGuiHelpers.gm_show_error (err, _("Invalid Input"))
1059 except:
1060 _log.exception( "save data problem in [%s]" % self.__class__.__name__)
1061
1066
1067 - def on_post_patient_selection( self, **kwds):
1068
1069 self.set_data()
1070
1072
1073 if not self._patient.connected:
1074 return True
1075 if self._save_data():
1076 return True
1077 _log.error('[%s] lossage' % self.__class__.__name__)
1078 return False
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 self.fields_pnl.Layout()
1091
1092 for i in self.field_line_szr.keys():
1093
1094 pos = self.field_line_szr[i].GetPosition()
1095
1096 self.prompt_widget[i].SetPosition((0, pos.y))
1097
1099 - def __init__(self, parent, id, aType = None):
1100
1101 print("class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__)
1102
1103
1104 if aType not in _known_edit_area_types:
1105 _log.error('unknown edit area type: [%s]' % aType)
1106 raise gmExceptions.ConstructorError('unknown edit area type: [%s]' % aType)
1107 self._type = aType
1108
1109
1110 cEditArea.__init__(self, parent, id)
1111
1112 self.input_fields = {}
1113
1114 self._postInit()
1115 self.old_data = {}
1116
1117 self._patient = gmPerson.gmCurrentPatient()
1118 self.Show(True)
1119
1120
1121
1122
1123
1124
1126
1127 prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
1128 prompt_pnl.SetBackgroundColour(richards_light_gray)
1129
1130 gszr = wx.FlexGridSizer (len(prompt_labels)+1, 1, 2, 2)
1131 color = richards_aqua
1132 for prompt in prompt_labels:
1133 label = self.__make_prompt(prompt_pnl, "%s " % prompt, color)
1134 gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT)
1135 color = richards_blue
1136 gszr.RemoveGrowableRow (line-1)
1137
1138 prompt_pnl.SetSizer(gszr)
1139 gszr.Fit(prompt_pnl)
1140 prompt_pnl.SetAutoLayout(True)
1141
1142
1143 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1144 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
1145 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
1146 szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND)
1147 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
1148
1149
1150 vszr_prompts = wx.BoxSizer(wx.VERTICAL)
1151 vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND)
1152 vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
1153
1154
1155 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1156 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
1157 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
1158 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
1159 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND)
1160
1161
1162 hszr_prompts = wx.BoxSizer(wx.HORIZONTAL)
1163 hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND)
1164 hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
1165
1166 return hszr_prompts
1167
1169 _log.error('programmer forgot to define edit area lines for [%s]' % self._type)
1170 _log.info('child classes of gmEditArea *must* override this function')
1171 return []
1172
1174
1175 fields_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
1176 fields_pnl.SetBackgroundColour(wx.Colour(222,222,222))
1177
1178 gszr = wx.GridSizer(len(_prompt_defs[self._type]), 1, 2, 2)
1179
1180
1181 lines = self._make_edit_lines(parent = fields_pnl)
1182
1183 self.lines = lines
1184 if len(lines) != len(_prompt_defs[self._type]):
1185 _log.error('#(edit lines) not equal #(prompts) for [%s], something is fishy' % self._type)
1186 for line in lines:
1187 gszr.Add(line, 0, wx.EXPAND | wx.ALIGN_LEFT)
1188
1189 fields_pnl.SetSizer(gszr)
1190 gszr.Fit(fields_pnl)
1191 fields_pnl.SetAutoLayout(True)
1192
1193
1194 shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1195 shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray)
1196 szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
1197 szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND)
1198 szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND)
1199
1200
1201 vszr_edit_fields = wx.BoxSizer(wx.VERTICAL)
1202 vszr_edit_fields.Add(fields_pnl, 92, wx.EXPAND)
1203 vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND)
1204
1205
1206 shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1207 shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray)
1208 szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL)
1209 szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND)
1210 szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND)
1211
1212
1213 hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
1214 hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND)
1215 hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND)
1216
1217 return hszr_edit_fields
1218
1221
1226
1228 map = {}
1229 for k in self.input_fields.keys():
1230 map[k] = ''
1231 return map
1232
1233
1235 self._default_init_fields()
1236
1237
1238
1239
1240
1242 _log.warning("you may want to override _updateUI for [%s]" % self.__class__.__name__)
1243
1244
1245 - def _postInit(self):
1246 """override for further control setup"""
1247 pass
1248
1249
1251 szr = wx.BoxSizer(wx.HORIZONTAL)
1252 szr.Add( widget, weight, wx.EXPAND)
1253 szr.Add( 0,0, spacerWeight, wx.EXPAND)
1254 return szr
1255
1257
1258 cb = wx.CheckBox( parent, -1, _(title))
1259 cb.SetForegroundColour( richards_blue)
1260 return cb
1261
1262
1263
1265 """this is a utlity method to add extra columns"""
1266
1267 if "extraColumns" in self.__class__.__dict__:
1268 for x in self.__class__.extraColumns:
1269 lines = self._addColumn(parent, lines, x, weightMap)
1270 return lines
1271
1272
1273 - def _addColumn(self, parent, lines, extra, weightMap = {}, existingWeight = 5 , extraWeight = 2):
1274 """
1275 # add ia extra column in the edit area.
1276 # preconditions:
1277 # parent is fields_pnl (weak);
1278 # self.input_fields exists (required);
1279 # ; extra is a list of tuples of format -
1280 # ( key for input_fields, widget label , widget class to instantiate )
1281 """
1282 newlines = []
1283 i = 0
1284 for x in lines:
1285
1286 if x in weightMap:
1287 (existingWeight, extraWeight) = weightMap[x]
1288
1289 szr = wx.BoxSizer(wx.HORIZONTAL)
1290 szr.Add( x, existingWeight, wx.EXPAND)
1291 if i < len(extra) and extra[i] is not None:
1292 (inputKey, widgetLabel, aclass) = extra[i]
1293 if aclass.__name__ in CONTROLS_WITHOUT_LABELS:
1294 szr.Add( self._make_prompt(parent, widgetLabel, richards_blue) )
1295 widgetLabel = ""
1296
1297 w = aclass( parent, -1, widgetLabel)
1298 if not aclass.__name__ in CONTROLS_WITHOUT_LABELS:
1299 w.SetForegroundColour(richards_blue)
1300
1301 szr.Add(w, extraWeight , wx.EXPAND)
1302
1303
1304 self.input_fields[inputKey] = w
1305
1306 newlines.append(szr)
1307 i += 1
1308 return newlines
1309
1329
1332
1335
1341
1352
1353 -class gmPastHistoryEditArea(gmEditArea):
1354
1355 - def __init__(self, parent, id):
1356 gmEditArea.__init__(self, parent, id, aType = 'past history')
1357
1358 - def _define_prompts(self):
1359 self._add_prompt(line = 1, label = _("When Noted"))
1360 self._add_prompt(line = 2, label = _("Laterality"))
1361 self._add_prompt(line = 3, label = _("Condition"))
1362 self._add_prompt(line = 4, label = _("Notes"))
1363 self._add_prompt(line = 6, label = _("Status"))
1364 self._add_prompt(line = 7, label = _("Progress Note"))
1365 self._add_prompt(line = 8, label = '')
1366
1367 - def _define_fields(self, parent):
1368
1369 self.fld_date_noted = gmDateTimeInput.gmDateInput(
1370 parent = parent,
1371 id = -1,
1372 style = wx.SIMPLE_BORDER
1373 )
1374 self._add_field(
1375 line = 1,
1376 pos = 1,
1377 widget = self.fld_date_noted,
1378 weight = 2
1379 )
1380 self._add_field(
1381 line = 1,
1382 pos = 2,
1383 widget = cPrompt_edit_area(parent,-1, _("Age")),
1384 weight = 0)
1385
1386 self.fld_age_noted = cEditAreaField(parent)
1387 self._add_field(
1388 line = 1,
1389 pos = 3,
1390 widget = self.fld_age_noted,
1391 weight = 2
1392 )
1393
1394
1395 self.fld_laterality_none= wx.RadioButton(parent, -1, _("N/A"))
1396 self.fld_laterality_left= wx.RadioButton(parent, -1, _("L"))
1397 self.fld_laterality_right= wx.RadioButton(parent, -1, _("R"))
1398 self.fld_laterality_both= wx.RadioButton(parent, -1, _("both"))
1399 self._add_field(
1400 line = 2,
1401 pos = 1,
1402 widget = self.fld_laterality_none,
1403 weight = 0
1404 )
1405 self._add_field(
1406 line = 2,
1407 pos = 2,
1408 widget = self.fld_laterality_left,
1409 weight = 0
1410 )
1411 self._add_field(
1412 line = 2,
1413 pos = 3,
1414 widget = self.fld_laterality_right,
1415 weight = 1
1416 )
1417 self._add_field(
1418 line = 2,
1419 pos = 4,
1420 widget = self.fld_laterality_both,
1421 weight = 1
1422 )
1423
1424 self.fld_condition= cEditAreaField(parent)
1425 self._add_field(
1426 line = 3,
1427 pos = 1,
1428 widget = self.fld_condition,
1429 weight = 6
1430 )
1431
1432 self.fld_notes= cEditAreaField(parent)
1433 self._add_field(
1434 line = 4,
1435 pos = 1,
1436 widget = self.fld_notes,
1437 weight = 6
1438 )
1439
1440 self.fld_significant= wx.CheckBox(
1441 parent,
1442 -1,
1443 _("significant"),
1444 style = wx.NO_BORDER
1445 )
1446 self.fld_active= wx.CheckBox(
1447 parent,
1448 -1,
1449 _("active"),
1450 style = wx.NO_BORDER
1451 )
1452
1453 self._add_field(
1454 line = 5,
1455 pos = 1,
1456 widget = self.fld_significant,
1457 weight = 0
1458 )
1459 self._add_field(
1460 line = 5,
1461 pos = 2,
1462 widget = self.fld_active,
1463 weight = 0
1464 )
1465
1466 self.fld_progress= cEditAreaField(parent)
1467 self._add_field(
1468 line = 6,
1469 pos = 1,
1470 widget = self.fld_progress,
1471 weight = 6
1472 )
1473
1474
1475 self._add_field(
1476 line = 7,
1477 pos = 4,
1478 widget = self._make_standard_buttons(parent),
1479 weight = 2
1480 )
1481
1482 - def _postInit(self):
1483 return
1484
1485 wx.EVT_KILL_FOCUS( self.fld_age_noted, self._ageKillFocus)
1486 wx.EVT_KILL_FOCUS( self.fld_date_noted, self._yearKillFocus)
1487
1488 - def _ageKillFocus( self, event):
1489
1490 event.Skip()
1491 try :
1492 year = self._getBirthYear() + int(self.fld_age_noted.GetValue().strip() )
1493 self.fld_date_noted.SetValue( str (year) )
1494 except:
1495 pass
1496
1497 - def _getBirthYear(self):
1498 try:
1499 birthyear = int(str(self._patient['dob']).split('-')[0])
1500 except:
1501
1502 birthyear = 1
1503
1504 return birthyear
1505
1506 - def _yearKillFocus( self, event):
1507 event.Skip()
1508 try:
1509 age = int(self.fld_date_noted.GetValue().strip() ) - self._getBirthYear()
1510 self.fld_age_noted.SetValue( str (age) )
1511 except:
1512 pass
1513
1514 __init_values = {
1515 "condition": "",
1516 "notes1": "",
1517 "notes2": "",
1518 "age": "",
1519
1520 "progress": "",
1521 "active": 1,
1522 "operation": 0,
1523 "confidential": 0,
1524 "significant": 1,
1525 "both": 0,
1526 "left": 0,
1527 "right": 0,
1528 "none" : 1
1529 }
1530
1531 - def _getDefaultAge(self):
1532 try:
1533
1534 return 1
1535 except:
1536 return 0
1537
1538 - def _get_init_values(self):
1539 values = gmPastHistoryEditArea.__init_values
1540 values["age"] = str( self._getDefaultAge())
1541 return values
1542
1543 - def _save_data(self):
1544 clinical = self._patient.emr.get_past_history()
1545 if self.getDataId() is None:
1546 id = clinical.create_history( self.get_fields_formatting_values() )
1547 self.setDataId(id)
1548 return
1549
1550 clinical.update_history( self.get_fields_formatting_values(), self.getDataId() )
1551
1552
1562
1564 self._add_prompt (line = 1, label = _ ("Specialty"))
1565 self._add_prompt (line = 2, label = _ ("Name"))
1566 self._add_prompt (line = 3, label = _ ("Address"))
1567 self._add_prompt (line = 4, label = _ ("Options"))
1568 self._add_prompt (line = 5, label = _("Text"), weight =6)
1569 self._add_prompt (line = 6, label = "")
1570
1572 self.fld_specialty = gmPhraseWheel.cPhraseWheel (
1573 parent = parent,
1574 id = -1,
1575 style = wx.SIMPLE_BORDER
1576 )
1577
1578 self._add_field (
1579 line = 1,
1580 pos = 1,
1581 widget = self.fld_specialty,
1582 weight = 1
1583 )
1584 self.fld_name = gmPhraseWheel.cPhraseWheel (
1585 parent = parent,
1586 id = -1,
1587 style = wx.SIMPLE_BORDER
1588 )
1589
1590 self._add_field (
1591 line = 2,
1592 pos = 1,
1593 widget = self.fld_name,
1594 weight = 1
1595 )
1596 self.fld_address = wx.ComboBox (parent, -1, style = wx.CB_READONLY)
1597
1598 self._add_field (
1599 line = 3,
1600 pos = 1,
1601 widget = self.fld_address,
1602 weight = 1
1603 )
1604
1605
1606 self.fld_name.add_callback_on_selection(self.setAddresses)
1607
1608 self.fld_med = wx.CheckBox (parent, -1, _("Meds"), style=wx.NO_BORDER)
1609 self._add_field (
1610 line = 4,
1611 pos = 1,
1612 widget = self.fld_med,
1613 weight = 1
1614 )
1615 self.fld_past = wx.CheckBox (parent, -1, _("Past Hx"), style=wx.NO_BORDER)
1616 self._add_field (
1617 line = 4,
1618 pos = 4,
1619 widget = self.fld_past,
1620 weight = 1
1621 )
1622 self.fld_text = wx.TextCtrl (parent, -1, style= wx.TE_MULTILINE)
1623 self._add_field (
1624 line = 5,
1625 pos = 1,
1626 widget = self.fld_text,
1627 weight = 1)
1628
1629 self._add_field(
1630 line = 6,
1631 pos = 1,
1632 widget = self._make_standard_buttons(parent),
1633 weight = 1
1634 )
1635 return 1
1636
1638 """
1639 Doesn't accept any value as this doesn't make sense for this edit area
1640 """
1641 self.fld_specialty.SetValue ('')
1642 self.fld_name.SetValue ('')
1643 self.fld_address.Clear ()
1644 self.fld_address.SetValue ('')
1645 self.fld_med.SetValue (0)
1646 self.fld_past.SetValue (0)
1647 self.fld_text.SetValue ('')
1648 self.recipient = None
1649
1651 """
1652 Set the available addresses for the selected identity
1653 """
1654 if id is None:
1655 self.recipient = None
1656 self.fld_address.Clear ()
1657 self.fld_address.SetValue ('')
1658 else:
1659 self.recipient = gmDemographicRecord.cDemographicRecord_SQL (id)
1660 self.fld_address.Clear ()
1661 self.addr = self.recipient.getAddresses ('work')
1662 for i in self.addr:
1663 self.fld_address.Append (_("%(number)s %(street)s, %(urb)s %(postcode)s") % i, ('post', i))
1664 fax = self.recipient.getCommChannel (gmDemographicRecord.FAX)
1665 email = self.recipient.getCommChannel (gmDemographicRecord.EMAIL)
1666 if fax:
1667 self.fld_address.Append ("%s: %s" % (_("FAX"), fax), ('fax', fax))
1668 if email:
1669 self.fld_address.Append ("%s: %s" % (_("E-MAIL"), email), ('email', email))
1670
1671 - def _save_new_entry(self):
1672 """
1673 We are always saving a "new entry" here because data_ID is always None
1674 """
1675 if not self.recipient:
1676 raise UserWarning(_('must have a recipient'))
1677 if self.fld_address.GetSelection() == -1:
1678 raise UserWarning(_('must select address'))
1679 channel, addr = self.fld_address.GetClientData (self.fld_address.GetSelection())
1680 text = self.fld_text.GetValue()
1681 flags = {}
1682 flags['meds'] = self.fld_med.GetValue()
1683 flags['pasthx'] = self.fld_past.GetValue()
1684 if not gmReferral.create_referral (self._patient, self.recipient, channel, addr, text, flags):
1685 raise UserWarning('error sending form')
1686
1687
1688
1689
1690
1698
1699
1700
1702 _log.debug("making prescription lines")
1703 lines = []
1704 self.txt_problem = cEditAreaField(parent)
1705 self.txt_class = cEditAreaField(parent)
1706 self.txt_generic = cEditAreaField(parent)
1707 self.txt_drug_product = cEditAreaField(parent)
1708 self.txt_strength= cEditAreaField(parent)
1709 self.txt_directions= cEditAreaField(parent)
1710 self.txt_for = cEditAreaField(parent)
1711 self.txt_progress = cEditAreaField(parent)
1712
1713 lines.append(self.txt_problem)
1714 lines.append(self.txt_class)
1715 lines.append(self.txt_generic)
1716 lines.append(self.txt_drug_product)
1717 lines.append(self.txt_strength)
1718 lines.append(self.txt_directions)
1719 lines.append(self.txt_for)
1720 lines.append(self.txt_progress)
1721 lines.append(self._make_standard_buttons(parent))
1722 self.input_fields = {
1723 "problem": self.txt_problem,
1724 "class" : self.txt_class,
1725 "generic" : self.txt_generic,
1726 "prod" : self.txt_drug_product,
1727 "strength": self.txt_strength,
1728 "directions": self.txt_directions,
1729 "for" : self.txt_for,
1730 "progress": self.txt_progress
1731
1732 }
1733
1734 return self._makeExtraColumns( parent, lines)
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1753
1754
1755
1756
1757
1758
1761 wx.StaticText.__init__(self, parent, id, prompt, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_LEFT)
1762 self.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
1763 self.SetForegroundColour(aColor)
1764
1765
1766
1767
1768
1770 - def __init__(self, parent, id, prompt_labels):
1771 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
1772 self.SetBackgroundColour(richards_light_gray)
1773 gszr = wx.GridSizer (len(prompt_labels)+1, 1, 2, 2)
1774 color = richards_aqua
1775 for prompt_key in prompt_labels.keys():
1776 label = cPrompt_edit_area(self, -1, " %s" % prompt_labels[prompt_key], aColor = color)
1777 gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT)
1778 color = richards_blue
1779 self.SetSizer(gszr)
1780 gszr.Fit(self)
1781 self.SetAutoLayout(True)
1782
1783
1784
1785
1786
1787
1788
1789 -class EditTextBoxes(wx.Panel):
1790 - def __init__(self, parent, id, editareaprompts, section):
1791 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize,style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
1792 self.SetBackgroundColour(wx.Colour(222,222,222))
1793 self.parent = parent
1794
1795 self.gszr = wx.GridSizer(len(editareaprompts), 1, 2, 2)
1796
1797 if section == gmSECTION_SUMMARY:
1798 pass
1799 elif section == gmSECTION_DEMOGRAPHICS:
1800 pass
1801 elif section == gmSECTION_CLINICALNOTES:
1802 pass
1803 elif section == gmSECTION_FAMILYHISTORY:
1804 pass
1805 elif section == gmSECTION_PASTHISTORY:
1806 pass
1807
1808
1809 self.txt_condition = cEditAreaField(self,PHX_CONDITION,wx.DefaultPosition,wx.DefaultSize)
1810 self.rb_sideleft = wxRadioButton(self,PHX_LEFT, _(" (L) "), wx.DefaultPosition,wx.DefaultSize)
1811 self.rb_sideright = wxRadioButton(self, PHX_RIGHT, _("(R)"), wx.DefaultPosition,wx.DefaultSize,wx.SUNKEN_BORDER)
1812 self.rb_sideboth = wxRadioButton(self, PHX_BOTH, _("Both"), wx.DefaultPosition,wx.DefaultSize)
1813 rbsizer = wx.BoxSizer(wx.HORIZONTAL)
1814 rbsizer.Add(self.rb_sideleft,1,wx.EXPAND)
1815 rbsizer.Add(self.rb_sideright,1,wx.EXPAND)
1816 rbsizer.Add(self.rb_sideboth,1,wx.EXPAND)
1817 szr1 = wx.BoxSizer(wx.HORIZONTAL)
1818 szr1.Add(self.txt_condition, 4, wx.EXPAND)
1819 szr1.Add(rbsizer, 3, wx.EXPAND)
1820
1821
1822
1823
1824 self.txt_notes1 = cEditAreaField(self,PHX_NOTES,wx.DefaultPosition,wx.DefaultSize)
1825
1826 self.txt_notes2= cEditAreaField(self,PHX_NOTES2,wx.DefaultPosition,wx.DefaultSize)
1827
1828 self.txt_agenoted = cEditAreaField(self, PHX_AGE, wx.DefaultPosition, wx.DefaultSize)
1829 szr4 = wx.BoxSizer(wx.HORIZONTAL)
1830 szr4.Add(self.txt_agenoted, 1, wx.EXPAND)
1831 szr4.Add(5, 0, 5)
1832
1833 self.txt_yearnoted = cEditAreaField(self,PHX_YEAR,wx.DefaultPosition,wx.DefaultSize)
1834 szr5 = wx.BoxSizer(wx.HORIZONTAL)
1835 szr5.Add(self.txt_yearnoted, 1, wx.EXPAND)
1836 szr5.Add(5, 0, 5)
1837
1838 self.parent.cb_active = wx.CheckBox(self, PHX_ACTIVE, _("Active"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1839 self.parent.cb_operation = wx.CheckBox(self, PHX_OPERATION, _("Operation"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1840 self.parent.cb_confidential = wx.CheckBox(self, PHX_CONFIDENTIAL , _("Confidential"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1841 self.parent.cb_significant = wx.CheckBox(self, PHX_SIGNIFICANT, _("Significant"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1842 szr6 = wx.BoxSizer(wx.HORIZONTAL)
1843 szr6.Add(self.parent.cb_active, 1, wx.EXPAND)
1844 szr6.Add(self.parent.cb_operation, 1, wx.EXPAND)
1845 szr6.Add(self.parent.cb_confidential, 1, wx.EXPAND)
1846 szr6.Add(self.parent.cb_significant, 1, wx.EXPAND)
1847
1848 self.txt_progressnotes = cEditAreaField(self,PHX_PROGRESSNOTES ,wx.DefaultPosition,wx.DefaultSize)
1849
1850 szr8 = wx.BoxSizer(wx.HORIZONTAL)
1851 szr8.Add(5, 0, 6)
1852 szr8.Add(self._make_standard_buttons(), 0, wx.EXPAND)
1853
1854 self.gszr.Add(szr1,0,wx.EXPAND)
1855 self.gszr.Add(self.txt_notes1,0,wx.EXPAND)
1856 self.gszr.Add(self.txt_notes2,0,wx.EXPAND)
1857 self.gszr.Add(szr4,0,wx.EXPAND)
1858 self.gszr.Add(szr5,0,wx.EXPAND)
1859 self.gszr.Add(szr6,0,wx.EXPAND)
1860 self.gszr.Add(self.txt_progressnotes,0,wx.EXPAND)
1861 self.gszr.Add(szr8,0,wx.EXPAND)
1862
1863
1864 elif section == gmSECTION_SCRIPT:
1865 pass
1866 elif section == gmSECTION_REQUESTS:
1867 pass
1868 elif section == gmSECTION_RECALLS:
1869 pass
1870 else:
1871 pass
1872
1873 self.SetSizer(self.gszr)
1874 self.gszr.Fit(self)
1875
1876 self.SetAutoLayout(True)
1877 self.Show(True)
1878
1880 self.btn_OK = wx.Button(self, -1, _("Ok"))
1881 self.btn_Clear = wx.Button(self, -1, _("Clear"))
1882 szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
1883 szr_buttons.Add(self.btn_OK, 1, wx.EXPAND, wx.ALL, 1)
1884 szr_buttons.Add(5, 0, 0)
1885 szr_buttons.Add(self.btn_Clear, 1, wx.EXPAND, wx.ALL, 1)
1886 return szr_buttons
1887
1889 - def __init__(self, parent, id, line_labels, section):
1890 _log.warning('***** old style EditArea instantiated, please convert *****')
1891
1892 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, style = wx.NO_BORDER)
1893 self.SetBackgroundColour(wx.Colour(222,222,222))
1894
1895
1896 prompts = gmPnlEditAreaPrompts(self, -1, line_labels)
1897
1898 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1899
1900 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
1901 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
1902 szr_shadow_below_prompts.Add(5,0,0,wx.EXPAND)
1903 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
1904
1905 szr_prompts = wx.BoxSizer(wx.VERTICAL)
1906 szr_prompts.Add(prompts, 97, wx.EXPAND)
1907 szr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
1908
1909
1910 edit_fields = EditTextBoxes(self, -1, line_labels, section)
1911
1912 shadow_below_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1913
1914 shadow_below_editarea.SetBackgroundColour(richards_coloured_gray)
1915 szr_shadow_below_editarea = wx.BoxSizer(wx.HORIZONTAL)
1916 szr_shadow_below_editarea.Add(5,0,0,wx.EXPAND)
1917 szr_shadow_below_editarea.Add(shadow_below_editarea, 12, wx.EXPAND)
1918
1919 szr_editarea = wx.BoxSizer(wx.VERTICAL)
1920 szr_editarea.Add(edit_fields, 92, wx.EXPAND)
1921 szr_editarea.Add(szr_shadow_below_editarea, 5, wx.EXPAND)
1922
1923
1924
1925 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1926 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
1927 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
1928 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
1929 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND)
1930
1931 shadow_rightof_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1932 shadow_rightof_editarea.SetBackgroundColour(richards_coloured_gray)
1933 szr_shadow_rightof_editarea = wx.BoxSizer(wx.VERTICAL)
1934 szr_shadow_rightof_editarea.Add(0, 5, 0, wx.EXPAND)
1935 szr_shadow_rightof_editarea.Add(shadow_rightof_editarea, 1, wx.EXPAND)
1936
1937
1938 self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL)
1939 self.szr_main_panels.Add(szr_prompts, 10, wx.EXPAND)
1940 self.szr_main_panels.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
1941 self.szr_main_panels.Add(5, 0, 0, wx.EXPAND)
1942 self.szr_main_panels.Add(szr_editarea, 89, wx.EXPAND)
1943 self.szr_main_panels.Add(szr_shadow_rightof_editarea, 1, wx.EXPAND)
1944
1945
1946
1947 self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL)
1948 self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5)
1949 self.SetSizer(self.szr_central_container)
1950 self.szr_central_container.Fit(self)
1951 self.SetAutoLayout(True)
1952 self.Show(True)
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
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 if __name__ == "__main__":
2230
2231
2236 self._add_prompt(line=1, label='line 1')
2237 self._add_prompt(line=2, label='buttons')
2239
2240 self.fld_substance = cEditAreaField(parent)
2241 self._add_field(
2242 line = 1,
2243 pos = 1,
2244 widget = self.fld_substance,
2245 weight = 1
2246 )
2247
2248 self._add_field(
2249 line = 2,
2250 pos = 1,
2251 widget = self._make_standard_buttons(parent),
2252 weight = 1
2253 )
2254
2255 app = wxPyWidgetTester(size = (400, 200))
2256 app.SetWidget(cTestEditArea)
2257 app.MainLoop()
2258
2259
2260
2261
2262
2263
2264
2265