| Home | Trees | Indices | Help |
|
|---|
|
|
1 """GNUmed allergy related widgets."""
2 ############################################################################
3 __version__ = "$Revision: 1.36 $"
4 __author__ = "R.Terry <rterry@gnumed.net>, H.Herb <hherb@gnumed.net>, K.Hilbert <Karsten.Hilbert@gmx.net>"
5 __license__ = 'GPL (details at http://www.gnu.org)'
6
7 import sys, time, datetime as pyDT, logging
8
9
10 import wx
11
12
13 if __name__ == '__main__':
14 sys.path.insert(0, '../../')
15 from Gnumed.pycommon import gmDispatcher, gmI18N, gmDateTime, gmTools, gmMatchProvider
16 from Gnumed.wxpython import gmDateTimeInput, gmTerryGuiParts, gmRegetMixin, gmPatSearchWidgets
17 from Gnumed.business import gmPerson, gmAllergy, gmPersonSearch
18 from Gnumed.wxGladeWidgets import wxgAllergyEditAreaPnl, wxgAllergyEditAreaDlg, wxgAllergyManagerDlg
19
20 _log = logging.getLogger('gm.ui')
21 _log.info(__version__)
22
23 #======================================================================
25
27 wxgAllergyEditAreaPnl.wxgAllergyEditAreaPnl.__init__(self, *args, **kwargs)
28
29 try:
30 self.__allergy = kwargs['allergy']
31 except KeyError:
32 self.__allergy = None
33
34 mp = gmMatchProvider.cMatchProvider_SQL2 (
35 queries = [u"""
36 select substance, substance
37 from clin.allergy
38 where substance %(fragment_condition)s
39
40 union
41
42 select generics, generics
43 from clin.allergy
44 where generics %(fragment_condition)s
45
46 union
47
48 select allergene, allergene
49 from clin.allergy
50 where allergene %(fragment_condition)s
51
52 union
53
54 select atc_code, atc_code
55 from clin.allergy
56 where atc_code %(fragment_condition)s
57 """
58 ]
59 )
60 mp.setThresholds(2, 3, 5)
61 self._PRW_trigger.matcher = mp
62
63 mp = gmMatchProvider.cMatchProvider_SQL2 (
64 queries = [u"""
65 select narrative, narrative
66 from clin.allergy
67 where narrative %(fragment_condition)s
68 """]
69 )
70 mp.setThresholds(2, 3, 5)
71 self._PRW_reaction.matcher = mp
72 self._PRW_reaction.enable_default_spellchecker()
73
74 # self._RBTN_type_sensitivity.MoveAfterInTabOrder(self._RBTN_type_allergy)
75 # self._ChBOX_definite.MoveAfterInTabOrder(self._RBTN_type_sensitivity)
76
77 self.refresh()
78 #--------------------------------------------------------
79 # external API
80 #--------------------------------------------------------
84 #--------------------------------------------------------
86
87 if allergy is not None:
88 self.__allergy = allergy
89
90 if self.__allergy is None:
91 ts = gmDateTime.cFuzzyTimestamp (
92 timestamp = pyDT.datetime.now(tz=gmDateTime.gmCurrentLocalTimezone),
93 accuracy = gmDateTime.acc_days
94 )
95 self._DPRW_date_noted.SetData(data = ts)
96 self._PRW_trigger.SetText()
97 self._TCTRL_brand_name.SetValue('')
98 self._TCTRL_generic.SetValue('')
99 self._ChBOX_generic_specific.SetValue(0)
100 self._TCTRL_atc_classes.SetValue('')
101 self._PRW_reaction.SetText()
102 self._RBTN_type_allergy.SetValue(1)
103 self._RBTN_type_sensitivity.SetValue(0)
104 self._ChBOX_definite.SetValue(1)
105 return True
106
107 if not isinstance(self.__allergy, gmAllergy.cAllergy):
108 raise ValueError('[%s].refresh(): expected gmAllergy.cAllergy instance, got [%s] instead' % (self.__class__.__name__, self.__allergy))
109
110 ts = gmDateTime.cFuzzyTimestamp (
111 timestamp = self.__allergy['date'],
112 accuracy = gmDateTime.acc_days
113 )
114 self._DPRW_date_noted.SetData(data=ts)
115 self._PRW_trigger.SetText(value = self.__allergy['allergene'])
116 self._TCTRL_brand_name.SetValue(self.__allergy['substance'])
117 self._TCTRL_generic.SetValue(gmTools.coalesce(self.__allergy['generics'], ''))
118 self._ChBOX_generic_specific.SetValue(self.__allergy['generic_specific'])
119 self._TCTRL_atc_classes.SetValue(gmTools.coalesce(self.__allergy['atc_code'], ''))
120 self._PRW_reaction.SetText(value = gmTools.coalesce(self.__allergy['reaction'], ''))
121 if self.__allergy['type'] == 'allergy':
122 self._RBTN_type_allergy.SetValue(1)
123 else:
124 self._RBTN_type_sensitivity.SetValue(1)
125 self._ChBOX_definite.SetValue(self.__allergy['definite'])
126 #--------------------------------------------------------
128
129 if self._PRW_trigger.GetValue().strip() == '':
130 self._PRW_trigger.SetBackgroundColour('pink')
131 self._PRW_trigger.Refresh()
132 self._PRW_trigger.SetFocus()
133 return False
134 self._PRW_trigger.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
135 self._PRW_trigger.Refresh()
136
137 return True
138 #--------------------------------------------------------
140 if not self.__is_valid_for_save():
141 return False
142
143 if self.__allergy is None:
144 if not can_create:
145 gmDispatcher.send(signal='statustext', msg=_('Creating new allergy not allowed.'))
146 return False
147
148 pat = gmPerson.gmCurrentPatient()
149 emr = pat.get_emr()
150
151 if self._RBTN_type_allergy.GetValue():
152 allg_type = 'allergy'
153 else:
154 allg_type = 'sensitivity'
155 self.__allergy = emr.add_allergy (
156 substance = self._PRW_trigger.GetValue().strip(),
157 allg_type = allg_type
158 )
159
160 # and update it with known data
161 self.__allergy['date'] = self._DPRW_date_noted.GetData().get_pydt()
162 self.__allergy['allergene'] = self._PRW_trigger.GetValue().strip()
163 # FIXME: determine brandname/generic/etc from substance (trigger field)
164 self.__allergy['generic_specific'] = (True and self._ChBOX_generic_specific.GetValue())
165 self.__allergy['reaction'] = self._PRW_reaction.GetValue().strip()
166 self.__allergy['definite'] = (True and self._ChBOX_definite.GetValue())
167 if self._RBTN_type_allergy.GetValue():
168 self.__allergy['pk_type'] = 'allergy'
169 else:
170 self.__allergy['pk_type'] = 'sensitivity'
171
172 self.__allergy.save_payload()
173
174 return True
175 #======================================================================
177
179
180 try:
181 allergy = kwargs['allergy']
182 del kwargs['allergy']
183 except KeyError:
184 allergy = None
185
186 wxgAllergyEditAreaDlg.wxgAllergyEditAreaDlg.__init__(self, *args, **kwargs)
187
188 if allergy is None:
189 # self._BTN_save.SetLabel(_('&Save'))
190 self._BTN_clear.SetLabel(_('&Clear'))
191 else:
192 # self._BTN_save.SetLabel(_('Update'))
193 self._BTN_clear.SetLabel(_('&Restore'))
194
195 self._PNL_edit_area.refresh(allergy = allergy)
196 #--------------------------------------------------------
203 #--------------------------------------------------------
206 #======================================================================
208
210
211 wxgAllergyManagerDlg.wxgAllergyManagerDlg.__init__(self, *args, **kwargs)
212
213 self.Centre(direction = wx.BOTH)
214
215 self.__set_columns()
216 # MacOSX crashes on this with:
217 # exception type : wx._core.PyAssertionError
218 # exception value: C++ assertion "i" failed at /BUILD/wxPython-src-2.8.3.0/src/common/wincmn.cpp(2634) in DoMoveInTabOrder(): MoveBefore/AfterInTabOrder(): win is not a sibling
219 # while Win/Linux work just fine
220 #self._PNL_edit_area._ChBOX_definite.MoveAfterInTabOrder(self._BTN_save)
221 self.__refresh_state_ui()
222 self.__refresh_details_ui()
223 #--------------------------------------------------------
224 # internal helpers
225 #--------------------------------------------------------
227 self._LCTRL_allergies.set_columns (columns = [
228 _('Type'),
229 _('Certainty'),
230 _('Trigger'),
231 _('Reaction')
232 ])
233 #--------------------------------------------------------
235
236 pat = gmPerson.gmCurrentPatient()
237 emr = pat.get_emr()
238 state = emr.allergy_state
239
240 self._TXT_current_state.SetLabel(state.state_string)
241
242 if state['last_confirmed'] is None:
243 self._TXT_last_confirmed.SetLabel(_('<allergy state unasked>'))
244 else:
245 self._TXT_last_confirmed.SetLabel(state['last_confirmed'].strftime('%x %H:%M'))
246
247 if state['has_allergy'] is None:
248 self._RBTN_unknown.SetValue(True)
249 self._RBTN_none.SetValue(False)
250 self._RBTN_some.SetValue(False)
251
252 self._RBTN_unknown.Enable(True)
253 self._RBTN_none.Enable(True)
254
255 elif state['has_allergy'] == 0:
256 self._RBTN_unknown.SetValue(False)
257 self._RBTN_none.SetValue(True)
258 self._RBTN_some.SetValue(False)
259
260 self._RBTN_unknown.Enable(True)
261 self._RBTN_none.Enable(True)
262
263 elif state['has_allergy'] == 1:
264 self._RBTN_unknown.SetValue(False)
265 self._RBTN_none.SetValue(False)
266 self._RBTN_some.SetValue(True)
267
268 self._RBTN_unknown.Enable(True)
269 self._RBTN_none.Enable(False)
270
271 else:
272 self._RBTN_unknown.SetValue(True)
273 self._RBTN_none.SetValue(False)
274 self._RBTN_some.SetValue(False)
275
276 self._RBTN_unknown.Enable(True)
277 self._RBTN_none.Enable(True)
278
279 gmDispatcher.send(signal=u'statustext', msg=_('invalid allergy state [%s]') % state, beep=True)
280
281 if state['comment'] is not None:
282 self._TCTRL_state_comment.SetValue(state['comment'])
283 #--------------------------------------------------------
285
286 pat = gmPerson.gmCurrentPatient()
287 emr = pat.get_emr()
288 allergies = emr.get_allergies()
289 no_of_allergies = len(allergies)
290
291 # display allergies
292 self._LCTRL_allergies.DeleteAllItems()
293 if no_of_allergies > 0:
294 emr.allergy_state = 1
295
296 for allergy in allergies:
297 row_idx = self._LCTRL_allergies.InsertStringItem(no_of_allergies, label = allergy['l10n_type'])
298 if allergy['definite']:
299 label = _('definite')
300 else:
301 label = u''
302 self._LCTRL_allergies.SetStringItem(index = row_idx, col = 1, label = label)
303 self._LCTRL_allergies.SetStringItem(index = row_idx, col = 2, label = allergy['descriptor'])
304 self._LCTRL_allergies.SetStringItem(index = row_idx, col = 3, label = gmTools.coalesce(allergy['reaction'], u''))
305 self._LCTRL_allergies.set_data(data=allergies)
306
307 self._LCTRL_allergies.Enable(True)
308 self._RBTN_some.SetValue(True)
309 self._RBTN_unknown.Enable(False)
310 self._RBTN_none.Enable(False)
311 else:
312 self._LCTRL_allergies.Enable(False)
313 self._RBTN_unknown.Enable(True)
314 self._RBTN_none.Enable(True)
315
316 self._LCTRL_allergies.set_column_widths (widths = [
317 wx.LIST_AUTOSIZE,
318 wx.LIST_AUTOSIZE,
319 wx.LIST_AUTOSIZE,
320 wx.LIST_AUTOSIZE
321 ])
322
323 self._PNL_edit_area.clear()
324 self._BTN_delete.Enable(False)
325 #--------------------------------------------------------
326 # event handlers
327 #--------------------------------------------------------
333 #--------------------------------------------------------
338 #--------------------------------------------------------
354 #--------------------------------------------------------
356 allergy = self._LCTRL_allergies.get_selected_item_data(only_one=True)
357 if allergy is None:
358 return
359 self._PNL_edit_area.refresh(allergy=allergy)
360 self._BTN_delete.Enable(True)
361 #--------------------------------------------------------
400 #--------------------------------------------------------
414 #======================================================================
416 """Allergy details panel.
417
418 This panel will hold all the allergy details and
419 allow entry of those details via the editing area.
420 """
421 #----------------------------------------------------
423 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.RAISED_BORDER)
424 gmRegetMixin.cRegetOnPaintMixin.__init__(self)
425 self.__do_layout()
426 self.__pat = gmPerson.gmCurrentPatient()
427 self.__register_interests()
428 self.__reset_ui_content()
429 #----------------------------------------------------
431 # -- top part --
432 pnl_UpperCaption = gmTerryGuiParts.cHeadingCaption(self, -1, _("ALLERGIES"))
433 self.editarea = gmAllergyEditArea(self, -1)
434
435 # -- middle part --
436 # divider headings below edit area
437 pnl_MiddleCaption = gmTerryGuiParts.cDividerCaption(self, -1, _("Allergy and Sensitivity - Summary"))
438 # self.sizer_divider_drug_generic = wx.BoxSizer(wxHORIZONTAL)
439 # self.sizer_divider_drug_generic.Add(pnl_MiddleCaption, 1, wxEXPAND)
440 self.LCTRL_allergies = wx.ListCtrl (
441 parent = self,
442 id = ID_ALLERGY_LIST,
443 pos = wx.DefaultPosition,
444 size = wx.DefaultSize,
445 style = wx.LC_SINGLE_SEL | wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_HRULES | wx.LC_VRULES | wx.VSCROLL
446 )
447 self.LCTRL_allergies.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, ''))
448 self.LCTRL_allergies.InsertColumn(0, _("Type"))
449 self.LCTRL_allergies.InsertColumn(1, _("Status"))
450 self.LCTRL_allergies.InsertColumn(2, _("ATC/Class"))
451 self.LCTRL_allergies.InsertColumn(3, _("Substance"))
452 self.LCTRL_allergies.InsertColumn(4, _("Generics"))
453 self.LCTRL_allergies.InsertColumn(5, _("Reaction"))
454
455 # -- bottom part --
456 pnl_LowerCaption = gmTerryGuiParts.cDividerCaption(self, -1, _('Class notes'))
457 #add a richtext control or a wxTextCtrl multiline to display the class text information
458 #e.g. would contain say information re the penicillins
459 self.class_notes = wx.TextCtrl (
460 self,
461 -1,
462 "A member of a new class of nonsteroidal anti-inflammatory agents (COX-2 selective NSAIDs) which have a mechanism of action that inhibits prostaglandin synthesis primarily by inhibition of cyclooxygenase 2 (COX-2). At therapeutic doses these have no effect on prostanoids synthesised by activation of COX-1 thereby not interfering with normal COX-1 related physiological processes in tissues, particularly the stomach, intestine and platelets.",
463 size = (200, 100),
464 style = wx.TE_MULTILINE | wx.TE_READONLY
465 )
466 self.class_notes.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, ''))
467
468 # -- add elements to main background sizer --
469 self.mainsizer = wx.BoxSizer(wx.VERTICAL)
470 self.mainsizer.Add(pnl_UpperCaption, 0, wx.EXPAND)
471 self.mainsizer.Add(self.editarea, 6, wx.EXPAND)
472 # self.mainsizer.Add(self.sizer_divider_drug_generic,0,wxEXPAND)
473 self.mainsizer.Add(pnl_MiddleCaption, 0, wx.EXPAND)
474 self.mainsizer.Add(self.LCTRL_allergies, 5, wx.EXPAND)
475 self.mainsizer.Add(pnl_LowerCaption, 0, wx.EXPAND)
476 self.mainsizer.Add(self.class_notes, 4, wx.EXPAND)
477
478 self.SetAutoLayout(True)
479 self.SetSizer(self.mainsizer)
480 self.mainsizer.Fit(self)
481 #-----------------------------------------------
483 wx.EVT_LIST_ITEM_ACTIVATED(self, ID_ALLERGY_LIST, self._on_allergy_activated)
484
485 # client internal signals
486 gmDispatcher.connect(signal = u'post_patient_selection', receiver=self._schedule_data_reget)
487 # gmDispatcher.connect(signal = u'vaccinations_updated', receiver=self._schedule_data_reget)
488 #-----------------------------------------------
492 #-----------------------------------------------
494 if not self.__pat.connected:
495 return False
496
497 self.LCTRL_allergies.DeleteAllItems()
498
499 emr = self.__pat.get_emr()
500 allergies = emr.get_allergies()
501 if allergies is None:
502 return False
503 for list_line in range(len(allergies)):
504 allg = allergies[list_line]
505 list_line = self.LCTRL_allergies.InsertStringItem(list_line, allg['l10n_type'])
506 # FIXME: check with Richard design specs
507 if allg['definite']:
508 self.LCTRL_allergies.SetStringItem(list_line, 1, _('definite'))
509 else:
510 self.LCTRL_allergies.SetStringItem(list_line, 1, _('likely'))
511 if allg['atc_code'] is not None:
512 self.LCTRL_allergies.SetStringItem(list_line, 2, allg['atc_code'])
513 self.LCTRL_allergies.SetStringItem(list_line, 3, allg['substance'])
514 if allg['generics'] is not None:
515 self.LCTRL_allergies.SetStringItem(list_line, 4, allg['generics'])
516 self.LCTRL_allergies.SetStringItem(list_line, 5, allg['reaction'])
517 self.LCTRL_allergies.SetItemData(list_line, allg['pk_allergy'])
518 for col in range(5):
519 self.LCTRL_allergies.SetColumnWidth(col, wx.LIST_AUTOSIZE)
520 # FIXME: resize event needed ?
521 return True
522 #-----------------------------------------------
524 pk_allg = evt.GetData()
525 emr = self.__pat.get_emr()
526 allgs = emr.get_allergies(ID_list=[pk_allg])
527 self.editarea.set_data(allergy = allgs[0])
528 #======================================================================
529 # main
530 #----------------------------------------------------------------------
531 if __name__ == "__main__":
532
533 gmI18N.activate_locale()
534 gmI18N.install_domain(domain='gnumed')
535
536 #-----------------------------------------------
538 app = wx.PyWidgetTester(size = (600, 600))
539 dlg = cAllergyEditAreaDlg(parent=app.frame, id=-1)
540 dlg.ShowModal()
541 # emr = pat.get_emr()
542 # allergy = emr.get_allergies()[0]
543 # dlg = cAllergyEditAreaDlg(parent=app.frame, id=-1, allergy=allergy)
544 # dlg.ShowModal()
545 return
546 #-----------------------------------------------
548 app = wx.PyWidgetTester(size = (800, 600))
549 dlg = cAllergyManagerDlg(parent=app.frame, id=-1)
550 dlg.ShowModal()
551 return
552 #-----------------------------------------------
553 if len(sys.argv) > 1 and sys.argv[1] == 'test':
554
555 pat = gmPersonSearch.ask_for_patient()
556 if pat is None:
557 sys.exit(0)
558 gmPatSearchWidgets.set_active_patient(pat)
559
560 #test_allergy_edit_area_dlg()
561 test_allergy_manager_dlg()
562
563 # app = wxPyWidgetTester(size = (600, 600))
564 # app.SetWidget(cAllergyPanel, -1)
565 # app.MainLoop()
566 #======================================================================
567
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Mon Nov 29 04:04:49 2010 | http://epydoc.sourceforge.net |