1
2
3
4 __license__ = 'GPL'
5 __version__ = "$Revision: 1.135 $"
6 __author__ = "R.Terry, K.Hilbert"
7
8
9 import logging, datetime as pydt
10
11
12 import wx
13
14
15 from Gnumed.pycommon import gmDispatcher, gmExceptions
16 from Gnumed.wxGladeWidgets import wxgGenericEditAreaDlg, wxgGenericEditAreaDlg2
17
18
19 _log = logging.getLogger('gm.ui')
20 _log.info(__version__)
21
22 edit_area_modes = ['new', 'edit', 'new_from_existing']
23
25 """Mixin for edit area panels providing generic functionality.
26
27 **************** start of template ****************
28
29 #====================================================================
30 # Class definition:
31
32 from Gnumed.wxGladeWidgets import wxgXxxEAPnl
33
34 class cXxxEAPnl(wxgXxxEAPnl.wxgXxxEAPnl, gmEditArea.cGenericEditAreaMixin):
35
36 def __init__(self, *args, **kwargs):
37
38 try:
39 data = kwargs['xxx']
40 del kwargs['xxx']
41 except KeyError:
42 data = None
43
44 wxgXxxEAPnl.wxgXxxEAPnl.__init__(self, *args, **kwargs)
45 gmEditArea.cGenericEditAreaMixin.__init__(self)
46
47 # Code using this mixin should set mode and data
48 # after instantiating the class:
49 self.mode = 'new'
50 self.data = data
51 if data is not None:
52 self.mode = 'edit'
53
54 #self.__init_ui()
55 #----------------------------------------------------------------
56 # def __init_ui(self):
57 # # adjust phrasewheels etc
58 #----------------------------------------------------------------
59 # generic Edit Area mixin API
60 #----------------------------------------------------------------
61 def _valid_for_save(self):
62 # remove when implemented:
63 return False
64
65 validity = True
66
67 if self._TCTRL_xxx.GetValue().strip() == u'':
68 validity = False
69 self.display_tctrl_as_valid(tctrl = self._TCTRL_xxx, valid = False)
70 else:
71 self.display_tctrl_as_valid(tctrl = self._TCTRL_xxx, valid = True)
72
73 if self._PRW_xxx.GetData() is None:
74 validity = False
75 self._PRW_xxx.display_as_valid(False)
76 else:
77 self._PRW_xxx.display_as_valid(True)
78
79 return validity
80 #----------------------------------------------------------------
81 def _save_as_new(self):
82 # save the data as a new instance
83 data = gmXXXX.create_xxxx()
84
85 data[''] = self._
86 data[''] = self._
87
88 data.save()
89
90 # must be done very late or else the property access
91 # will refresh the display such that later field
92 # access will return empty values
93 self.data = data
94 return False
95 return True
96 #----------------------------------------------------------------
97 def _save_as_update(self):
98 # update self.data and save the changes
99 self.data[''] = self._TCTRL_xxx.GetValue().strip()
100 self.data[''] = self._PRW_xxx.GetData()
101 self.data[''] = self._CHBOX_xxx.GetValue()
102 self.data.save()
103 return True
104 #----------------------------------------------------------------
105 def _refresh_as_new(self):
106 pass
107 #----------------------------------------------------------------
108 def _refresh_as_new_from_existing(self):
109 self._refresh_as_new()
110 #----------------------------------------------------------------
111 def _refresh_from_existing(self):
112 pass
113 #----------------------------------------------------------------
114
115 **************** end of template ****************
116 """
118 self.__mode = 'new'
119 self.__data = None
120 self.successful_save_msg = None
121 self._refresh_as_new()
122 self.__tctrl_validity_colors = {
123 True: wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW),
124 False: 'pink'
125 }
126
129
131 if mode not in edit_area_modes:
132 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
133 if mode == 'edit':
134 if self.__data is None:
135 raise ValueError('[%s] <mode> "edit" needs data value' % self.__class__.__name__)
136
137 prev_mode = self.__mode
138 self.__mode = mode
139 if mode != prev_mode:
140 self.refresh()
141
142 mode = property(_get_mode, _set_mode)
143
146
148 if data is None:
149 if self.__mode == 'edit':
150 raise ValueError('[%s] <mode> "edit" needs data value' % self.__class__.__name__)
151 self.__data = data
152 self.refresh()
153
154 data = property(_get_data, _set_data)
155
157 """Invoked from the generic edit area dialog.
158
159 Invokes
160 _valid_for_save,
161 _save_as_new,
162 _save_as_update
163 on the implementing edit area as needed.
164
165 _save_as_* must set self.__data and return True/False
166 """
167 if not self._valid_for_save():
168 return False
169
170 if self.__mode in ['new', 'new_from_existing']:
171 if self._save_as_new():
172 self.mode = 'edit'
173 return True
174 return False
175
176 elif self.__mode == 'edit':
177 return self._save_as_update()
178
179 else:
180 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
181
183 """Invoked from the generic edit area dialog.
184
185 Invokes
186 _refresh_as_new()
187 _refresh_from_existing()
188 _refresh_as_new_from_existing()
189 on the implementing edit area as needed.
190
191 Then calls _valid_for_save().
192 """
193 if self.__mode == 'new':
194 result = self._refresh_as_new()
195 self._valid_for_save()
196 return result
197 elif self.__mode == 'edit':
198 result = self._refresh_from_existing()
199 return result
200 elif self.__mode == 'new_from_existing':
201 result = self._refresh_as_new_from_existing()
202 self._valid_for_save()
203 return result
204 else:
205 raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
206
208 tctrl.SetBackgroundColour(self.__tctrl_validity_colors[valid])
209 tctrl.Refresh()
210
212 ctrl.SetBackgroundColour(self.__tctrl_validity_colors[valid])
213 ctrl.Refresh()
214
216 """Dialog for parenting edit area panels with save/clear/next/cancel"""
217
218 _lucky_day = 1
219 _lucky_month = 4
220 _today = pydt.date.today()
221
223
224 new_ea = kwargs['edit_area']
225 del kwargs['edit_area']
226
227 if not isinstance(new_ea, cGenericEditAreaMixin):
228 raise TypeError('[%s]: edit area instance must be child of cGenericEditAreaMixin')
229
230 try:
231 single_entry = kwargs['single_entry']
232 del kwargs['single_entry']
233 except KeyError:
234 single_entry = False
235
236 wxgGenericEditAreaDlg2.wxgGenericEditAreaDlg2.__init__(self, *args, **kwargs)
237
238 self.left_extra_button = None
239
240 if cGenericEditAreaDlg2._today.day != cGenericEditAreaDlg2._lucky_day:
241 self._BTN_lucky.Enable(False)
242 self._BTN_lucky.Hide()
243 else:
244 if cGenericEditAreaDlg2._today.month != cGenericEditAreaDlg2._lucky_month:
245 self._BTN_lucky.Enable(False)
246 self._BTN_lucky.Hide()
247
248
249 dummy_ea_pnl = self._PNL_ea
250 ea_pnl_szr = dummy_ea_pnl.GetContainingSizer()
251 ea_pnl_parent = dummy_ea_pnl.GetParent()
252 ea_pnl_szr.Remove(dummy_ea_pnl)
253 dummy_ea_pnl.Destroy()
254 del dummy_ea_pnl
255 new_ea_min_size = new_ea.GetMinSize()
256 new_ea.Reparent(ea_pnl_parent)
257 self._PNL_ea = new_ea
258 ea_pnl_szr.Add(self._PNL_ea, 1, wx.EXPAND, 0)
259 ea_pnl_szr.SetMinSize(new_ea_min_size)
260 ea_pnl_szr.Fit(new_ea)
261
262
263 if single_entry:
264 self._BTN_forward.Enable(False)
265 self._BTN_forward.Hide()
266
267 self._adjust_clear_revert_buttons()
268
269
270
271 main_szr = self.GetSizer()
272 main_szr.Fit(self)
273 self.Layout()
274
275
276 self._PNL_ea.refresh()
277
289
296
299
302
317
327
336
337
338
354
355 left_extra_button = property(lambda x:x, _set_left_extra_button)
356
357
359 """Dialog for parenting edit area with save/clear/cancel"""
360
362
363 ea = kwargs['edit_area']
364 del kwargs['edit_area']
365
366 wxgGenericEditAreaDlg.wxgGenericEditAreaDlg.__init__(self, *args, **kwargs)
367
368 szr = self._PNL_ea.GetContainingSizer()
369 szr.Remove(self._PNL_ea)
370 ea.Reparent(self)
371 szr.Add(ea, 1, wx.ALL|wx.EXPAND, 4)
372 self._PNL_ea = ea
373
374 self.Layout()
375 szr = self.GetSizer()
376 szr.Fit(self)
377 self.Refresh()
378
379 self._PNL_ea.refresh()
380
388
391
392
393
394
395
396
397 from Gnumed.pycommon import gmGuiBroker
398
399
400 _gb = gmGuiBroker.GuiBroker()
401
402 gmSECTION_SUMMARY = 1
403 gmSECTION_DEMOGRAPHICS = 2
404 gmSECTION_CLINICALNOTES = 3
405 gmSECTION_FAMILYHISTORY = 4
406 gmSECTION_PASTHISTORY = 5
407 gmSECTION_SCRIPT = 8
408 gmSECTION_REQUESTS = 9
409 gmSECTION_REFERRALS = 11
410 gmSECTION_RECALLS = 12
411
412 richards_blue = wx.Colour(0,0,131)
413 richards_aqua = wx.Colour(0,194,197)
414 richards_dark_gray = wx.Color(131,129,131)
415 richards_light_gray = wx.Color(255,255,255)
416 richards_coloured_gray = wx.Color(131,129,131)
417
418
419 CONTROLS_WITHOUT_LABELS =['wxTextCtrl', 'cEditAreaField', 'wx.SpinCtrl', 'gmPhraseWheel', 'wx.ComboBox']
420
422 widget.SetForegroundColour(wx.Color(255, 0, 0))
423 widget.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
424
437 if not isinstance(edit_area, cEditArea2):
438 raise gmExceptions.ConstructorError, '<edit_area> must be of type cEditArea2 but is <%s>' % type(edit_area)
439 wx.Dialog.__init__(self, parent, id, title, pos, size, style, name)
440 self.__wxID_BTN_SAVE = wx.NewId()
441 self.__wxID_BTN_RESET = wx.NewId()
442 self.__editarea = edit_area
443 self.__do_layout()
444 self.__register_events()
445
446
447
450
452 self.__editarea.Reparent(self)
453
454 self.__btn_SAVE = wx.Button(self, self.__wxID_BTN_SAVE, _("Save"))
455 self.__btn_SAVE.SetToolTipString(_('save entry into medical record'))
456 self.__btn_RESET = wx.Button(self, self.__wxID_BTN_RESET, _("Reset"))
457 self.__btn_RESET.SetToolTipString(_('reset entry'))
458 self.__btn_CANCEL = wx.Button(self, wx.ID_CANCEL, _("Cancel"))
459 self.__btn_CANCEL.SetToolTipString(_('discard entry and cancel'))
460
461 szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
462 szr_buttons.Add(self.__btn_SAVE, 1, wx.EXPAND | wx.ALL, 1)
463 szr_buttons.Add(self.__btn_RESET, 1, wx.EXPAND | wx.ALL, 1)
464 szr_buttons.Add(self.__btn_CANCEL, 1, wx.EXPAND | wx.ALL, 1)
465
466 szr_main = wx.BoxSizer(wx.VERTICAL)
467 szr_main.Add(self.__editarea, 1, wx.EXPAND)
468 szr_main.Add(szr_buttons, 0, wx.EXPAND)
469
470 self.SetSizerAndFit(szr_main)
471
472
473
475
476 wx.EVT_BUTTON(self.__btn_SAVE, self.__wxID_BTN_SAVE, self._on_SAVE_btn_pressed)
477 wx.EVT_BUTTON(self.__btn_RESET, self.__wxID_BTN_RESET, self._on_RESET_btn_pressed)
478 wx.EVT_BUTTON(self.__btn_CANCEL, wx.ID_CANCEL, self._on_CANCEL_btn_pressed)
479
480 wx.EVT_CLOSE(self, self._on_CANCEL_btn_pressed)
481
482
483
484
485
486
487 return 1
488
490 if self.__editarea.save_data():
491 self.__editarea.Close()
492 self.EndModal(wx.ID_OK)
493 return
494 short_err = self.__editarea.get_short_error()
495 long_err = self.__editarea.get_long_error()
496 if (short_err is None) and (long_err is None):
497 long_err = _(
498 'Unspecified error saving data in edit area.\n\n'
499 'Programmer forgot to specify proper error\n'
500 'message in [%s].'
501 ) % self.__editarea.__class__.__name__
502 if short_err is not None:
503 gmDispatcher.send(signal = 'statustext', msg = short_err)
504 if long_err is not None:
505 gmGuiHelpers.gm_show_error(long_err, _('saving clinical data'))
506
508 self.__editarea.Close()
509 self.EndModal(wx.ID_CANCEL)
510
513
515 - def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TAB_TRAVERSAL):
516
517 wx.Panel.__init__ (
518 self,
519 parent,
520 id,
521 pos = pos,
522 size = size,
523 style = style | wx.TAB_TRAVERSAL
524 )
525 self.SetBackgroundColour(wx.Color(222,222,222))
526
527 self.data = None
528 self.fields = {}
529 self.prompts = {}
530 self._short_error = None
531 self._long_error = None
532 self._summary = None
533 self._patient = gmPerson.gmCurrentPatient()
534 self.__wxID_BTN_OK = wx.NewId()
535 self.__wxID_BTN_CLEAR = wx.NewId()
536 self.__do_layout()
537 self.__register_events()
538 self.Show()
539
540
541
543 """This needs to be overridden by child classes."""
544 self._long_error = _(
545 'Cannot save data from edit area.\n\n'
546 'Programmer forgot to override method:\n'
547 ' <%s.save_data>'
548 ) % self.__class__.__name__
549 return False
550
552 msg = _(
553 'Cannot reset fields in edit area.\n\n'
554 'Programmer forgot to override method:\n'
555 ' <%s.reset_ui>'
556 ) % self.__class__.__name__
557 gmGuiHelpers.gm_show_error(msg)
558
560 tmp = self._short_error
561 self._short_error = None
562 return tmp
563
565 tmp = self._long_error
566 self._long_error = None
567 return tmp
568
570 return _('<No embed string for [%s]>') % self.__class__.__name__
571
572
573
585
590
591
592
594 self.__deregister_events()
595 event.Skip()
596
598 """Only active if _make_standard_buttons was called in child class."""
599
600 try:
601 event.Skip()
602 if self.data is None:
603 self._save_new_entry()
604 self.reset_ui()
605 else:
606 self._save_modified_entry()
607 self.reset_ui()
608 except gmExceptions.InvalidInputError, err:
609
610
611 gmGuiHelpers.gm_show_error (err, _("Invalid Input"))
612 except:
613 _log.exception( "save data problem in [%s]" % self.__class__.__name__)
614
616 """Only active if _make_standard_buttons was called in child class."""
617
618 self.reset_ui()
619 event.Skip()
620
622 self.__deregister_events()
623
624 if not self._patient.connected:
625 return True
626
627
628
629
630 return True
631 _log.error('[%s] lossage' % self.__class__.__name__)
632 return False
633
635 """Just before new patient becomes active."""
636
637 if not self._patient.connected:
638 return True
639
640
641
642
643 return True
644 _log.error('[%s] lossage' % self.__class__.__name__)
645 return False
646
648 """Just after new patient became active."""
649
650 self.reset_ui()
651
652
653
655
656
657 self._define_prompts()
658 self._define_fields(parent = self)
659 if len(self.fields) != len(self.prompts):
660 _log.error('[%s]: #fields != #prompts' % self.__class__.__name__)
661 return None
662
663
664 szr_main_fgrid = wx.FlexGridSizer(rows = len(self.prompts), cols=2)
665 color = richards_aqua
666 lines = self.prompts.keys()
667 lines.sort()
668 for line in lines:
669
670 label, color, weight = self.prompts[line]
671
672 prompt = wx.StaticText (
673 parent = self,
674 id = -1,
675 label = label,
676 style = wx.ALIGN_CENTRE
677 )
678
679 prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
680 prompt.SetForegroundColour(color)
681 prompt.SetBackgroundColour(richards_light_gray)
682 szr_main_fgrid.Add(prompt, flag=wx.EXPAND | wx.ALIGN_RIGHT)
683
684
685 szr_line = wx.BoxSizer(wx.HORIZONTAL)
686 positions = self.fields[line].keys()
687 positions.sort()
688 for pos in positions:
689 field, weight = self.fields[line][pos]
690
691 szr_line.Add(field, weight, wx.EXPAND)
692 szr_main_fgrid.Add(szr_line, flag=wx.GROW | wx.ALIGN_LEFT)
693
694
695 szr_main_fgrid.AddGrowableCol(1)
696
697
698
699
700
701
702
703 self.SetSizerAndFit(szr_main_fgrid)
704
705
706
707
709 """Child classes override this to define their prompts using _add_prompt()"""
710 _log.error('missing override in [%s]' % self.__class__.__name__)
711
713 """Add a new prompt line.
714
715 To be used from _define_fields in child classes.
716
717 - label, the label text
718 - color
719 - weight, the weight given in sizing the various rows. 0 means the row
720 always has minimum size
721 """
722 self.prompts[line] = (label, color, weight)
723
725 """Defines the fields.
726
727 - override in child classes
728 - mostly uses _add_field()
729 """
730 _log.error('missing override in [%s]' % self.__class__.__name__)
731
732 - def _add_field(self, line=None, pos=None, widget=None, weight=0):
733 if None in (line, pos, widget):
734 _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget))
735 if not self.fields.has_key(line):
736 self.fields[line] = {}
737 self.fields[line][pos] = (widget, weight)
738
756
757
758
759
761 - def __init__ (self, parent, id = -1, pos = wx.DefaultPosition, size=wx.DefaultSize):
762 wx.TextCtrl.__init__(self,parent,id,"",pos, size ,wx.SIMPLE_BORDER)
763 _decorate_editarea_field(self)
764
766 - def __init__(self, parent, id, pos, size, style):
767
768 print "class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__
769
770
771 wx.Panel.__init__(self, parent, id, pos=pos, size=size, style=wx.NO_BORDER | wx.TAB_TRAVERSAL)
772 self.SetBackgroundColour(wx.Color(222,222,222))
773
774 self.data = None
775 self.fields = {}
776 self.prompts = {}
777
778 ID_BTN_OK = wx.NewId()
779 ID_BTN_CLEAR = wx.NewId()
780
781 self.__do_layout()
782
783
784
785
786
787
788 self._patient = gmPerson.gmCurrentPatient()
789 self.__register_events()
790 self.Show(True)
791
792
793
795
796 self._define_prompts()
797 self.fields_pnl = wx.Panel(self, -1, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
798 self._define_fields(parent = self.fields_pnl)
799
800 szr_prompts = self.__generate_prompts()
801 szr_fields = self.__generate_fields()
802
803
804 self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL)
805 self.szr_main_panels.Add(szr_prompts, 11, wx.EXPAND)
806 self.szr_main_panels.Add(5, 0, 0, wx.EXPAND)
807 self.szr_main_panels.Add(szr_fields, 90, wx.EXPAND)
808
809
810
811 self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL)
812 self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5)
813
814
815 self.SetAutoLayout(True)
816 self.SetSizer(self.szr_central_container)
817 self.szr_central_container.Fit(self)
818
820 if len(self.fields) != len(self.prompts):
821 _log.error('[%s]: #fields != #prompts' % self.__class__.__name__)
822 return None
823
824 prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
825 prompt_pnl.SetBackgroundColour(richards_light_gray)
826
827 color = richards_aqua
828 lines = self.prompts.keys()
829 lines.sort()
830 self.prompt_widget = {}
831 for line in lines:
832 label, color, weight = self.prompts[line]
833 self.prompt_widget[line] = self.__make_prompt(prompt_pnl, "%s " % label, color)
834
835 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
836 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
837 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
838 szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND)
839 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
840
841
842 vszr_prompts = wx.BoxSizer(wx.VERTICAL)
843 vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND)
844 vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
845
846
847 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
848 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
849 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
850 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
851 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts, 1, wx.EXPAND)
852
853
854 hszr_prompts = wx.BoxSizer(wx.HORIZONTAL)
855 hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND)
856 hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
857
858 return hszr_prompts
859
861 self.fields_pnl.SetBackgroundColour(wx.Color(222,222,222))
862
863 vszr = wx.BoxSizer(wx.VERTICAL)
864 lines = self.fields.keys()
865 lines.sort()
866 self.field_line_szr = {}
867 for line in lines:
868 self.field_line_szr[line] = wx.BoxSizer(wx.HORIZONTAL)
869 positions = self.fields[line].keys()
870 positions.sort()
871 for pos in positions:
872 field, weight = self.fields[line][pos]
873 self.field_line_szr[line].Add(field, weight, wx.EXPAND)
874 try:
875 vszr.Add(self.field_line_szr[line], self.prompts[line][2], flag = wx.EXPAND)
876 except KeyError:
877 _log.error("Error with line=%s, self.field_line_szr has key:%s; self.prompts has key: %s" % (line, self.field_line_szr.has_key(line), self.prompts.has_key(line) ) )
878
879 self.fields_pnl.SetSizer(vszr)
880 vszr.Fit(self.fields_pnl)
881
882
883 shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
884 shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray)
885 szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
886 szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND)
887 szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND)
888
889
890 vszr_edit_fields = wx.BoxSizer(wx.VERTICAL)
891 vszr_edit_fields.Add(self.fields_pnl, 92, wx.EXPAND)
892 vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND)
893
894
895 shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
896 shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray)
897 szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL)
898 szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND)
899 szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND)
900
901
902 hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
903 hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND)
904 hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND)
905
906 return hszr_edit_fields
907
909
910 prompt = wx.StaticText(
911 parent,
912 -1,
913 aLabel,
914 style = wx.ALIGN_RIGHT
915 )
916 prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
917 prompt.SetForegroundColour(aColor)
918 return prompt
919
920
921
923 """Add a new prompt line.
924
925 To be used from _define_fields in child classes.
926
927 - label, the label text
928 - color
929 - weight, the weight given in sizing the various rows. 0 means the rwo
930 always has minimum size
931 """
932 self.prompts[line] = (label, color, weight)
933
934 - def _add_field(self, line=None, pos=None, widget=None, weight=0):
935 if None in (line, pos, widget):
936 _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget))
937 if not self.fields.has_key(line):
938 self.fields[line] = {}
939 self.fields[line][pos] = (widget, weight)
940
942 """Defines the fields.
943
944 - override in child classes
945 - mostly uses _add_field()
946 """
947 _log.error('missing override in [%s]' % self.__class__.__name__)
948
950 _log.error('missing override in [%s]' % self.__class__.__name__)
951
965
968
970 _log.error('[%s] programmer forgot to define _save_data()' % self.__class__.__name__)
971 _log.info('child classes of cEditArea *must* override this function')
972 return False
973
974
975
977
978 wx.EVT_BUTTON(self.btn_OK, ID_BTN_OK, self._on_OK_btn_pressed)
979 wx.EVT_BUTTON(self.btn_Clear, ID_BTN_CLEAR, self._on_clear_btn_pressed)
980
981 wx.EVT_SIZE (self.fields_pnl, self._on_resize_fields)
982
983
984 gmDispatcher.connect(signal = u'pre_patient_selection', receiver = self._on_pre_patient_selection)
985 gmDispatcher.connect(signal = u'application_closing', receiver = self._on_application_closing)
986 gmDispatcher.connect(signal = u'post_patient_selection', receiver = self.on_post_patient_selection)
987
988 return 1
989
990
991
1008
1010
1011 self.set_data()
1012 event.Skip()
1013
1014 - def on_post_patient_selection( self, **kwds):
1015
1016 self.set_data()
1017
1019
1020 if not self._patient.connected:
1021 return True
1022 if self._save_data():
1023 return True
1024 _log.error('[%s] lossage' % self.__class__.__name__)
1025 return False
1026
1028
1029 if not self._patient.connected:
1030 return True
1031 if self._save_data():
1032 return True
1033 _log.error('[%s] lossage' % self.__class__.__name__)
1034 return False
1035
1037 self.fields_pnl.Layout()
1038
1039 for i in self.field_line_szr.keys():
1040
1041 pos = self.field_line_szr[i].GetPosition()
1042
1043 self.prompt_widget[i].SetPosition((0, pos.y))
1044
1046 - def __init__(self, parent, id, aType = None):
1047
1048 print "class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__
1049
1050
1051 if aType not in _known_edit_area_types:
1052 _log.error('unknown edit area type: [%s]' % aType)
1053 raise gmExceptions.ConstructorError, 'unknown edit area type: [%s]' % aType
1054 self._type = aType
1055
1056
1057 cEditArea.__init__(self, parent, id)
1058
1059 self.input_fields = {}
1060
1061 self._postInit()
1062 self.old_data = {}
1063
1064 self._patient = gmPerson.gmCurrentPatient()
1065 self.Show(True)
1066
1067
1068
1069
1070
1071
1073
1074 prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
1075 prompt_pnl.SetBackgroundColour(richards_light_gray)
1076
1077 gszr = wx.FlexGridSizer (len(prompt_labels)+1, 1, 2, 2)
1078 color = richards_aqua
1079 for prompt in prompt_labels:
1080 label = self.__make_prompt(prompt_pnl, "%s " % prompt, color)
1081 gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT)
1082 color = richards_blue
1083 gszr.RemoveGrowableRow (line-1)
1084
1085 prompt_pnl.SetSizer(gszr)
1086 gszr.Fit(prompt_pnl)
1087 prompt_pnl.SetAutoLayout(True)
1088
1089
1090 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1091 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
1092 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
1093 szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND)
1094 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
1095
1096
1097 vszr_prompts = wx.BoxSizer(wx.VERTICAL)
1098 vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND)
1099 vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
1100
1101
1102 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1103 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
1104 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
1105 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
1106 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND)
1107
1108
1109 hszr_prompts = wx.BoxSizer(wx.HORIZONTAL)
1110 hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND)
1111 hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
1112
1113 return hszr_prompts
1114
1116 _log.error('programmer forgot to define edit area lines for [%s]' % self._type)
1117 _log.info('child classes of gmEditArea *must* override this function')
1118 return []
1119
1121
1122 fields_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
1123 fields_pnl.SetBackgroundColour(wx.Color(222,222,222))
1124
1125 gszr = wx.GridSizer(len(_prompt_defs[self._type]), 1, 2, 2)
1126
1127
1128 lines = self._make_edit_lines(parent = fields_pnl)
1129
1130 self.lines = lines
1131 if len(lines) != len(_prompt_defs[self._type]):
1132 _log.error('#(edit lines) not equal #(prompts) for [%s], something is fishy' % self._type)
1133 for line in lines:
1134 gszr.Add(line, 0, wx.EXPAND | wx.ALIGN_LEFT)
1135
1136 fields_pnl.SetSizer(gszr)
1137 gszr.Fit(fields_pnl)
1138 fields_pnl.SetAutoLayout(True)
1139
1140
1141 shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1142 shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray)
1143 szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
1144 szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND)
1145 szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND)
1146
1147
1148 vszr_edit_fields = wx.BoxSizer(wx.VERTICAL)
1149 vszr_edit_fields.Add(fields_pnl, 92, wx.EXPAND)
1150 vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND)
1151
1152
1153 shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1154 shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray)
1155 szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL)
1156 szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND)
1157 szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND)
1158
1159
1160 hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
1161 hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND)
1162 hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND)
1163
1164 return hszr_edit_fields
1165
1168
1173
1175 map = {}
1176 for k in self.input_fields.keys():
1177 map[k] = ''
1178 return map
1179
1180
1182 self._default_init_fields()
1183
1184
1185
1186
1187
1189 _log.warning("you may want to override _updateUI for [%s]" % self.__class__.__name__)
1190
1191
1192 - def _postInit(self):
1193 """override for further control setup"""
1194 pass
1195
1196
1198 szr = wx.BoxSizer(wx.HORIZONTAL)
1199 szr.Add( widget, weight, wx.EXPAND)
1200 szr.Add( 0,0, spacerWeight, wx.EXPAND)
1201 return szr
1202
1204
1205 cb = wx.CheckBox( parent, -1, _(title))
1206 cb.SetForegroundColour( richards_blue)
1207 return cb
1208
1209
1210
1212 """this is a utlity method to add extra columns"""
1213
1214 if self.__class__.__dict__.has_key("extraColumns"):
1215 for x in self.__class__.extraColumns:
1216 lines = self._addColumn(parent, lines, x, weightMap)
1217 return lines
1218
1219
1220
1221 - def _addColumn(self, parent, lines, extra, weightMap = {}, existingWeight = 5 , extraWeight = 2):
1222 """
1223 # add ia extra column in the edit area.
1224 # preconditions:
1225 # parent is fields_pnl (weak);
1226 # self.input_fields exists (required);
1227 # ; extra is a list of tuples of format -
1228 # ( key for input_fields, widget label , widget class to instantiate )
1229 """
1230
1231 newlines = []
1232 i = 0
1233 for x in lines:
1234
1235 if weightMap.has_key( x):
1236 (existingWeight, extraWeight) = weightMap[x]
1237
1238 szr = wx.BoxSizer(wx.HORIZONTAL)
1239 szr.Add( x, existingWeight, wx.EXPAND)
1240 if i < len(extra) and extra[i] <> None:
1241
1242 (inputKey, widgetLabel, aclass) = extra[i]
1243 if aclass.__name__ in CONTROLS_WITHOUT_LABELS:
1244 szr.Add( self._make_prompt(parent, widgetLabel, richards_blue) )
1245 widgetLabel = ""
1246
1247
1248 w = aclass( parent, -1, widgetLabel)
1249 if not aclass.__name__ in CONTROLS_WITHOUT_LABELS:
1250 w.SetForegroundColour(richards_blue)
1251
1252 szr.Add(w, extraWeight , wx.EXPAND)
1253
1254
1255 self.input_fields[inputKey] = w
1256
1257 newlines.append(szr)
1258 i += 1
1259 return newlines
1260
1280
1283
1286
1292
1303
1311
1313 _log.debug("making family Hx lines")
1314 lines = []
1315 self.input_fields = {}
1316
1317
1318
1319 self.input_fields['name'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1320 self.input_fields['DOB'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1321 lbl_dob = self._make_prompt(parent, _(" Date of Birth "), richards_blue)
1322 szr = wx.BoxSizer(wx.HORIZONTAL)
1323 szr.Add(self.input_fields['name'], 4, wx.EXPAND)
1324 szr.Add(lbl_dob, 2, wx.EXPAND)
1325 szr.Add(self.input_fields['DOB'], 4, wx.EXPAND)
1326 lines.append(szr)
1327
1328
1329
1330 self.input_fields['relationship'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1331 szr = wx.BoxSizer(wx.HORIZONTAL)
1332 szr.Add(self.input_fields['relationship'], 4, wx.EXPAND)
1333 lines.append(szr)
1334
1335 self.input_fields['condition'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1336 self.cb_condition_confidential = wx.CheckBox(parent, -1, _("confidental"), wx.DefaultPosition, wx.DefaultSize, wx.NO_BORDER)
1337 szr = wx.BoxSizer(wx.HORIZONTAL)
1338 szr.Add(self.input_fields['condition'], 6, wx.EXPAND)
1339 szr.Add(self.cb_condition_confidential, 0, wx.EXPAND)
1340 lines.append(szr)
1341
1342 self.input_fields['comment'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1343 lines.append(self.input_fields['comment'])
1344
1345 lbl_onset = self._make_prompt(parent, _(" age onset "), richards_blue)
1346 self.input_fields['age onset'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1347
1348 lbl_caused_death = self._make_prompt(parent, _(" caused death "), richards_blue)
1349 self.input_fields['caused death'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1350 lbl_aod = self._make_prompt(parent, _(" age died "), richards_blue)
1351 self.input_fields['AOD'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1352 szr = wx.BoxSizer(wx.HORIZONTAL)
1353 szr.Add(lbl_onset, 0, wx.EXPAND)
1354 szr.Add(self.input_fields['age onset'], 1,wx.EXPAND)
1355 szr.Add(lbl_caused_death, 0, wx.EXPAND)
1356 szr.Add(self.input_fields['caused death'], 2,wx.EXPAND)
1357 szr.Add(lbl_aod, 0, wx.EXPAND)
1358 szr.Add(self.input_fields['AOD'], 1, wx.EXPAND)
1359 szr.Add(2, 2, 8)
1360 lines.append(szr)
1361
1362 self.input_fields['progress notes'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
1363 lines.append(self.input_fields['progress notes'])
1364
1365 self.Btn_next_condition = wx.Button(parent, -1, _("Next Condition"))
1366 szr = wx.BoxSizer(wx.HORIZONTAL)
1367 szr.AddSpacer(10, 0, 0)
1368 szr.Add(self.Btn_next_condition, 0, wx.EXPAND | wx.ALL, 1)
1369 szr.Add(2, 1, 5)
1370 szr.Add(self._make_standard_buttons(parent), 0, wx.EXPAND)
1371 lines.append(szr)
1372
1373 return lines
1374
1377
1378
1379 -class gmPastHistoryEditArea(gmEditArea):
1380
1381 - def __init__(self, parent, id):
1382 gmEditArea.__init__(self, parent, id, aType = 'past history')
1383
1384 - def _define_prompts(self):
1385 self._add_prompt(line = 1, label = _("When Noted"))
1386 self._add_prompt(line = 2, label = _("Laterality"))
1387 self._add_prompt(line = 3, label = _("Condition"))
1388 self._add_prompt(line = 4, label = _("Notes"))
1389 self._add_prompt(line = 6, label = _("Status"))
1390 self._add_prompt(line = 7, label = _("Progress Note"))
1391 self._add_prompt(line = 8, label = '')
1392
1393 - def _define_fields(self, parent):
1394
1395 self.fld_date_noted = gmDateTimeInput.gmDateInput(
1396 parent = parent,
1397 id = -1,
1398 style = wx.SIMPLE_BORDER
1399 )
1400 self._add_field(
1401 line = 1,
1402 pos = 1,
1403 widget = self.fld_date_noted,
1404 weight = 2
1405 )
1406 self._add_field(
1407 line = 1,
1408 pos = 2,
1409 widget = cPrompt_edit_area(parent,-1, _("Age")),
1410 weight = 0)
1411
1412 self.fld_age_noted = cEditAreaField(parent)
1413 self._add_field(
1414 line = 1,
1415 pos = 3,
1416 widget = self.fld_age_noted,
1417 weight = 2
1418 )
1419
1420
1421 self.fld_laterality_none= wx.RadioButton(parent, -1, _("N/A"))
1422 self.fld_laterality_left= wx.RadioButton(parent, -1, _("L"))
1423 self.fld_laterality_right= wx.RadioButton(parent, -1, _("R"))
1424 self.fld_laterality_both= wx.RadioButton(parent, -1, _("both"))
1425 self._add_field(
1426 line = 2,
1427 pos = 1,
1428 widget = self.fld_laterality_none,
1429 weight = 0
1430 )
1431 self._add_field(
1432 line = 2,
1433 pos = 2,
1434 widget = self.fld_laterality_left,
1435 weight = 0
1436 )
1437 self._add_field(
1438 line = 2,
1439 pos = 3,
1440 widget = self.fld_laterality_right,
1441 weight = 1
1442 )
1443 self._add_field(
1444 line = 2,
1445 pos = 4,
1446 widget = self.fld_laterality_both,
1447 weight = 1
1448 )
1449
1450 self.fld_condition= cEditAreaField(parent)
1451 self._add_field(
1452 line = 3,
1453 pos = 1,
1454 widget = self.fld_condition,
1455 weight = 6
1456 )
1457
1458 self.fld_notes= cEditAreaField(parent)
1459 self._add_field(
1460 line = 4,
1461 pos = 1,
1462 widget = self.fld_notes,
1463 weight = 6
1464 )
1465
1466 self.fld_significant= wx.CheckBox(
1467 parent,
1468 -1,
1469 _("significant"),
1470 style = wx.NO_BORDER
1471 )
1472 self.fld_active= wx.CheckBox(
1473 parent,
1474 -1,
1475 _("active"),
1476 style = wx.NO_BORDER
1477 )
1478
1479 self._add_field(
1480 line = 5,
1481 pos = 1,
1482 widget = self.fld_significant,
1483 weight = 0
1484 )
1485 self._add_field(
1486 line = 5,
1487 pos = 2,
1488 widget = self.fld_active,
1489 weight = 0
1490 )
1491
1492 self.fld_progress= cEditAreaField(parent)
1493 self._add_field(
1494 line = 6,
1495 pos = 1,
1496 widget = self.fld_progress,
1497 weight = 6
1498 )
1499
1500
1501 self._add_field(
1502 line = 7,
1503 pos = 4,
1504 widget = self._make_standard_buttons(parent),
1505 weight = 2
1506 )
1507
1508 - def _postInit(self):
1509 return
1510
1511 wx.EVT_KILL_FOCUS( self.fld_age_noted, self._ageKillFocus)
1512 wx.EVT_KILL_FOCUS( self.fld_date_noted, self._yearKillFocus)
1513
1514 - def _ageKillFocus( self, event):
1515
1516 event.Skip()
1517 try :
1518 year = self._getBirthYear() + int(self.fld_age_noted.GetValue().strip() )
1519 self.fld_date_noted.SetValue( str (year) )
1520 except:
1521 pass
1522
1523 - def _getBirthYear(self):
1524 try:
1525 birthyear = int(str(self._patient['dob']).split('-')[0])
1526 except:
1527
1528 birthyear = 1
1529
1530 return birthyear
1531
1532 - def _yearKillFocus( self, event):
1533 event.Skip()
1534 try:
1535 age = int(self.fld_date_noted.GetValue().strip() ) - self._getBirthYear()
1536 self.fld_age_noted.SetValue( str (age) )
1537 except:
1538 pass
1539
1540 __init_values = {
1541 "condition": "",
1542 "notes1": "",
1543 "notes2": "",
1544 "age": "",
1545
1546 "progress": "",
1547 "active": 1,
1548 "operation": 0,
1549 "confidential": 0,
1550 "significant": 1,
1551 "both": 0,
1552 "left": 0,
1553 "right": 0,
1554 "none" : 1
1555 }
1556
1557 - def _getDefaultAge(self):
1558 try:
1559
1560 return 1
1561 except:
1562 return 0
1563
1564 - def _get_init_values(self):
1565 values = gmPastHistoryEditArea.__init_values
1566 values["age"] = str( self._getDefaultAge())
1567 return values
1568
1569 - def _save_data(self):
1570 clinical = self._patient.get_emr().get_past_history()
1571 if self.getDataId() is None:
1572 id = clinical.create_history( self.get_fields_formatting_values() )
1573 self.setDataId(id)
1574 return
1575
1576 clinical.update_history( self.get_fields_formatting_values(), self.getDataId() )
1577
1578
1588
1590 self._add_prompt (line = 1, label = _ ("Specialty"))
1591 self._add_prompt (line = 2, label = _ ("Name"))
1592 self._add_prompt (line = 3, label = _ ("Address"))
1593 self._add_prompt (line = 4, label = _ ("Options"))
1594 self._add_prompt (line = 5, label = _("Text"), weight =6)
1595 self._add_prompt (line = 6, label = "")
1596
1598 self.fld_specialty = gmPhraseWheel.cPhraseWheel (
1599 parent = parent,
1600 id = -1,
1601 style = wx.SIMPLE_BORDER
1602 )
1603
1604 self._add_field (
1605 line = 1,
1606 pos = 1,
1607 widget = self.fld_specialty,
1608 weight = 1
1609 )
1610 self.fld_name = gmPhraseWheel.cPhraseWheel (
1611 parent = parent,
1612 id = -1,
1613 style = wx.SIMPLE_BORDER
1614 )
1615
1616 self._add_field (
1617 line = 2,
1618 pos = 1,
1619 widget = self.fld_name,
1620 weight = 1
1621 )
1622 self.fld_address = wx.ComboBox (parent, -1, style = wx.CB_READONLY)
1623
1624 self._add_field (
1625 line = 3,
1626 pos = 1,
1627 widget = self.fld_address,
1628 weight = 1
1629 )
1630
1631
1632 self.fld_name.add_callback_on_selection(self.setAddresses)
1633
1634 self.fld_med = wx.CheckBox (parent, -1, _("Meds"), style=wx.NO_BORDER)
1635 self._add_field (
1636 line = 4,
1637 pos = 1,
1638 widget = self.fld_med,
1639 weight = 1
1640 )
1641 self.fld_past = wx.CheckBox (parent, -1, _("Past Hx"), style=wx.NO_BORDER)
1642 self._add_field (
1643 line = 4,
1644 pos = 4,
1645 widget = self.fld_past,
1646 weight = 1
1647 )
1648 self.fld_text = wx.TextCtrl (parent, -1, style= wx.TE_MULTILINE)
1649 self._add_field (
1650 line = 5,
1651 pos = 1,
1652 widget = self.fld_text,
1653 weight = 1)
1654
1655 self._add_field(
1656 line = 6,
1657 pos = 1,
1658 widget = self._make_standard_buttons(parent),
1659 weight = 1
1660 )
1661 return 1
1662
1664 """
1665 Doesn't accept any value as this doesn't make sense for this edit area
1666 """
1667 self.fld_specialty.SetValue ('')
1668 self.fld_name.SetValue ('')
1669 self.fld_address.Clear ()
1670 self.fld_address.SetValue ('')
1671 self.fld_med.SetValue (0)
1672 self.fld_past.SetValue (0)
1673 self.fld_text.SetValue ('')
1674 self.recipient = None
1675
1677 """
1678 Set the available addresses for the selected identity
1679 """
1680 if id is None:
1681 self.recipient = None
1682 self.fld_address.Clear ()
1683 self.fld_address.SetValue ('')
1684 else:
1685 self.recipient = gmDemographicRecord.cDemographicRecord_SQL (id)
1686 self.fld_address.Clear ()
1687 self.addr = self.recipient.getAddresses ('work')
1688 for i in self.addr:
1689 self.fld_address.Append (_("%(number)s %(street)s, %(urb)s %(postcode)s") % i, ('post', i))
1690 fax = self.recipient.getCommChannel (gmDemographicRecord.FAX)
1691 email = self.recipient.getCommChannel (gmDemographicRecord.EMAIL)
1692 if fax:
1693 self.fld_address.Append ("%s: %s" % (_("FAX"), fax), ('fax', fax))
1694 if email:
1695 self.fld_address.Append ("%s: %s" % (_("E-MAIL"), email), ('email', email))
1696
1697 - def _save_new_entry(self):
1698 """
1699 We are always saving a "new entry" here because data_ID is always None
1700 """
1701 if not self.recipient:
1702 raise gmExceptions.InvalidInputError(_('must have a recipient'))
1703 if self.fld_address.GetSelection() == -1:
1704 raise gmExceptions.InvalidInputError(_('must select address'))
1705 channel, addr = self.fld_address.GetClientData (self.fld_address.GetSelection())
1706 text = self.fld_text.GetValue()
1707 flags = {}
1708 flags['meds'] = self.fld_med.GetValue()
1709 flags['pasthx'] = self.fld_past.GetValue()
1710 if not gmReferral.create_referral (self._patient, self.recipient, channel, addr, text, flags):
1711 raise gmExceptions.InvalidInputError('error sending form')
1712
1713
1714
1715
1716
1724
1725
1726
1728 _log.debug("making prescription lines")
1729 lines = []
1730 self.txt_problem = cEditAreaField(parent)
1731 self.txt_class = cEditAreaField(parent)
1732 self.txt_generic = cEditAreaField(parent)
1733 self.txt_brand = cEditAreaField(parent)
1734 self.txt_strength= cEditAreaField(parent)
1735 self.txt_directions= cEditAreaField(parent)
1736 self.txt_for = cEditAreaField(parent)
1737 self.txt_progress = cEditAreaField(parent)
1738
1739 lines.append(self.txt_problem)
1740 lines.append(self.txt_class)
1741 lines.append(self.txt_generic)
1742 lines.append(self.txt_brand)
1743 lines.append(self.txt_strength)
1744 lines.append(self.txt_directions)
1745 lines.append(self.txt_for)
1746 lines.append(self.txt_progress)
1747 lines.append(self._make_standard_buttons(parent))
1748 self.input_fields = {
1749 "problem": self.txt_problem,
1750 "class" : self.txt_class,
1751 "generic" : self.txt_generic,
1752 "brand" : self.txt_brand,
1753 "strength": self.txt_strength,
1754 "directions": self.txt_directions,
1755 "for" : self.txt_for,
1756 "progress": self.txt_progress
1757
1758 }
1759
1760 return self._makeExtraColumns( parent, lines)
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1779
1780
1781
1782
1783
1784
1787 wx.StaticText.__init__(self, parent, id, prompt, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_LEFT)
1788 self.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
1789 self.SetForegroundColour(aColor)
1790
1791
1792
1793
1794
1796 - def __init__(self, parent, id, prompt_labels):
1797 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
1798 self.SetBackgroundColour(richards_light_gray)
1799 gszr = wx.GridSizer (len(prompt_labels)+1, 1, 2, 2)
1800 color = richards_aqua
1801 for prompt_key in prompt_labels.keys():
1802 label = cPrompt_edit_area(self, -1, " %s" % prompt_labels[prompt_key], aColor = color)
1803 gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT)
1804 color = richards_blue
1805 self.SetSizer(gszr)
1806 gszr.Fit(self)
1807 self.SetAutoLayout(True)
1808
1809
1810
1811
1812
1813
1814
1815 -class EditTextBoxes(wx.Panel):
1816 - def __init__(self, parent, id, editareaprompts, section):
1817 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize,style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
1818 self.SetBackgroundColour(wx.Color(222,222,222))
1819 self.parent = parent
1820
1821 self.gszr = wx.GridSizer(len(editareaprompts), 1, 2, 2)
1822
1823 if section == gmSECTION_SUMMARY:
1824 pass
1825 elif section == gmSECTION_DEMOGRAPHICS:
1826 pass
1827 elif section == gmSECTION_CLINICALNOTES:
1828 pass
1829 elif section == gmSECTION_FAMILYHISTORY:
1830 pass
1831 elif section == gmSECTION_PASTHISTORY:
1832 pass
1833
1834
1835 self.txt_condition = cEditAreaField(self,PHX_CONDITION,wx.DefaultPosition,wx.DefaultSize)
1836 self.rb_sideleft = wxRadioButton(self,PHX_LEFT, _(" (L) "), wx.DefaultPosition,wx.DefaultSize)
1837 self.rb_sideright = wxRadioButton(self, PHX_RIGHT, _("(R)"), wx.DefaultPosition,wx.DefaultSize,wx.SUNKEN_BORDER)
1838 self.rb_sideboth = wxRadioButton(self, PHX_BOTH, _("Both"), wx.DefaultPosition,wx.DefaultSize)
1839 rbsizer = wx.BoxSizer(wx.HORIZONTAL)
1840 rbsizer.Add(self.rb_sideleft,1,wx.EXPAND)
1841 rbsizer.Add(self.rb_sideright,1,wx.EXPAND)
1842 rbsizer.Add(self.rb_sideboth,1,wx.EXPAND)
1843 szr1 = wx.BoxSizer(wx.HORIZONTAL)
1844 szr1.Add(self.txt_condition, 4, wx.EXPAND)
1845 szr1.Add(rbsizer, 3, wx.EXPAND)
1846
1847
1848
1849
1850 self.txt_notes1 = cEditAreaField(self,PHX_NOTES,wx.DefaultPosition,wx.DefaultSize)
1851
1852 self.txt_notes2= cEditAreaField(self,PHX_NOTES2,wx.DefaultPosition,wx.DefaultSize)
1853
1854 self.txt_agenoted = cEditAreaField(self, PHX_AGE, wx.DefaultPosition, wx.DefaultSize)
1855 szr4 = wx.BoxSizer(wx.HORIZONTAL)
1856 szr4.Add(self.txt_agenoted, 1, wx.EXPAND)
1857 szr4.Add(5, 0, 5)
1858
1859 self.txt_yearnoted = cEditAreaField(self,PHX_YEAR,wx.DefaultPosition,wx.DefaultSize)
1860 szr5 = wx.BoxSizer(wx.HORIZONTAL)
1861 szr5.Add(self.txt_yearnoted, 1, wx.EXPAND)
1862 szr5.Add(5, 0, 5)
1863
1864 self.parent.cb_active = wx.CheckBox(self, PHX_ACTIVE, _("Active"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1865 self.parent.cb_operation = wx.CheckBox(self, PHX_OPERATION, _("Operation"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1866 self.parent.cb_confidential = wx.CheckBox(self, PHX_CONFIDENTIAL , _("Confidential"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1867 self.parent.cb_significant = wx.CheckBox(self, PHX_SIGNIFICANT, _("Significant"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
1868 szr6 = wx.BoxSizer(wx.HORIZONTAL)
1869 szr6.Add(self.parent.cb_active, 1, wx.EXPAND)
1870 szr6.Add(self.parent.cb_operation, 1, wx.EXPAND)
1871 szr6.Add(self.parent.cb_confidential, 1, wx.EXPAND)
1872 szr6.Add(self.parent.cb_significant, 1, wx.EXPAND)
1873
1874 self.txt_progressnotes = cEditAreaField(self,PHX_PROGRESSNOTES ,wx.DefaultPosition,wx.DefaultSize)
1875
1876 szr8 = wx.BoxSizer(wx.HORIZONTAL)
1877 szr8.Add(5, 0, 6)
1878 szr8.Add(self._make_standard_buttons(), 0, wx.EXPAND)
1879
1880 self.gszr.Add(szr1,0,wx.EXPAND)
1881 self.gszr.Add(self.txt_notes1,0,wx.EXPAND)
1882 self.gszr.Add(self.txt_notes2,0,wx.EXPAND)
1883 self.gszr.Add(szr4,0,wx.EXPAND)
1884 self.gszr.Add(szr5,0,wx.EXPAND)
1885 self.gszr.Add(szr6,0,wx.EXPAND)
1886 self.gszr.Add(self.txt_progressnotes,0,wx.EXPAND)
1887 self.gszr.Add(szr8,0,wx.EXPAND)
1888
1889
1890 elif section == gmSECTION_SCRIPT:
1891 pass
1892 elif section == gmSECTION_REQUESTS:
1893 pass
1894 elif section == gmSECTION_RECALLS:
1895 pass
1896 else:
1897 pass
1898
1899 self.SetSizer(self.gszr)
1900 self.gszr.Fit(self)
1901
1902 self.SetAutoLayout(True)
1903 self.Show(True)
1904
1906 self.btn_OK = wx.Button(self, -1, _("Ok"))
1907 self.btn_Clear = wx.Button(self, -1, _("Clear"))
1908 szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
1909 szr_buttons.Add(self.btn_OK, 1, wx.EXPAND, wx.ALL, 1)
1910 szr_buttons.Add(5, 0, 0)
1911 szr_buttons.Add(self.btn_Clear, 1, wx.EXPAND, wx.ALL, 1)
1912 return szr_buttons
1913
1915 - def __init__(self, parent, id, line_labels, section):
1916 _log.warning('***** old style EditArea instantiated, please convert *****')
1917
1918 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, style = wx.NO_BORDER)
1919 self.SetBackgroundColour(wx.Color(222,222,222))
1920
1921
1922 prompts = gmPnlEditAreaPrompts(self, -1, line_labels)
1923
1924 shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1925
1926 shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
1927 szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
1928 szr_shadow_below_prompts.Add(5,0,0,wx.EXPAND)
1929 szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
1930
1931 szr_prompts = wx.BoxSizer(wx.VERTICAL)
1932 szr_prompts.Add(prompts, 97, wx.EXPAND)
1933 szr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
1934
1935
1936 edit_fields = EditTextBoxes(self, -1, line_labels, section)
1937
1938 shadow_below_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1939
1940 shadow_below_editarea.SetBackgroundColour(richards_coloured_gray)
1941 szr_shadow_below_editarea = wx.BoxSizer(wx.HORIZONTAL)
1942 szr_shadow_below_editarea.Add(5,0,0,wx.EXPAND)
1943 szr_shadow_below_editarea.Add(shadow_below_editarea, 12, wx.EXPAND)
1944
1945 szr_editarea = wx.BoxSizer(wx.VERTICAL)
1946 szr_editarea.Add(edit_fields, 92, wx.EXPAND)
1947 szr_editarea.Add(szr_shadow_below_editarea, 5, wx.EXPAND)
1948
1949
1950
1951 shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1952 shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
1953 szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
1954 szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
1955 szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND)
1956
1957 shadow_rightof_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
1958 shadow_rightof_editarea.SetBackgroundColour(richards_coloured_gray)
1959 szr_shadow_rightof_editarea = wx.BoxSizer(wx.VERTICAL)
1960 szr_shadow_rightof_editarea.Add(0, 5, 0, wx.EXPAND)
1961 szr_shadow_rightof_editarea.Add(shadow_rightof_editarea, 1, wx.EXPAND)
1962
1963
1964 self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL)
1965 self.szr_main_panels.Add(szr_prompts, 10, wx.EXPAND)
1966 self.szr_main_panels.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
1967 self.szr_main_panels.Add(5, 0, 0, wx.EXPAND)
1968 self.szr_main_panels.Add(szr_editarea, 89, wx.EXPAND)
1969 self.szr_main_panels.Add(szr_shadow_rightof_editarea, 1, wx.EXPAND)
1970
1971
1972
1973 self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL)
1974 self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5)
1975 self.SetSizer(self.szr_central_container)
1976 self.szr_central_container.Fit(self)
1977 self.SetAutoLayout(True)
1978 self.Show(True)
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
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255 if __name__ == "__main__":
2256
2257
2262 self._add_prompt(line=1, label='line 1')
2263 self._add_prompt(line=2, label='buttons')
2265
2266 self.fld_substance = cEditAreaField(parent)
2267 self._add_field(
2268 line = 1,
2269 pos = 1,
2270 widget = self.fld_substance,
2271 weight = 1
2272 )
2273
2274 self._add_field(
2275 line = 2,
2276 pos = 1,
2277 widget = self._make_standard_buttons(parent),
2278 weight = 1
2279 )
2280
2281 app = wxPyWidgetTester(size = (400, 200))
2282 app.SetWidget(cTestEditArea)
2283 app.MainLoop()
2284
2285
2286
2287
2288
2289
2290
2291