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 v2 or later (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
75
76
77 self.refresh()
78
79
80
82 self.__allergy = None
83 return self.refresh()
84
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
139 - def save(self, can_create=True):
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 allergene = self._PRW_trigger.GetValue().strip(),
157 allg_type = allg_type
158 )
159
160
161 self.__allergy['date'] = self._DPRW_date_noted.GetData().get_pydt()
162 self.__allergy['allergene'] = self._PRW_trigger.GetValue().strip()
163
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
190 self._BTN_clear.SetLabel(_('&Clear'))
191 else:
192
193 self._BTN_clear.SetLabel(_('&Restore'))
194
195 self._PNL_edit_area.refresh(allergy = allergy)
196
203
206
208
223
224
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
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
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
429
431
432 pnl_UpperCaption = gmTerryGuiParts.cHeadingCaption(self, -1, _("ALLERGIES"))
433 self.editarea = gmAllergyEditArea(self, -1)
434
435
436
437 pnl_MiddleCaption = gmTerryGuiParts.cDividerCaption(self, -1, _("Allergy and Sensitivity - Summary"))
438
439
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
456 pnl_LowerCaption = gmTerryGuiParts.cDividerCaption(self, -1, _('Class notes'))
457
458
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
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
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
486 gmDispatcher.connect(signal = u'post_patient_selection', receiver=self._schedule_data_reget)
487
488
490 self.editarea.set_data()
491 self.LCTRL_allergies.DeleteAllItems()
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
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
521 return True
522
528
529
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
542
543
544
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
561 test_allergy_manager_dlg()
562
563
564
565
566
567