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
339
355
357 allergy = self._LCTRL_allergies.get_selected_item_data(only_one=True)
358 if allergy is None:
359 return
360 self._PNL_edit_area.refresh(allergy = allergy)
361 self._BTN_delete.Enable(True)
362 self._LBL_message.SetLabel(_('Edit the selected allergy item:'))
363
402
416
418 """Allergy details panel.
419
420 This panel will hold all the allergy details and
421 allow entry of those details via the editing area.
422 """
423
431
433
434 pnl_UpperCaption = gmTerryGuiParts.cHeadingCaption(self, -1, _("ALLERGIES"))
435 self.editarea = gmAllergyEditArea(self, -1)
436
437
438
439 pnl_MiddleCaption = gmTerryGuiParts.cDividerCaption(self, -1, _("Allergy and Sensitivity - Summary"))
440
441
442 self.LCTRL_allergies = wx.ListCtrl (
443 parent = self,
444 id = ID_ALLERGY_LIST,
445 pos = wx.DefaultPosition,
446 size = wx.DefaultSize,
447 style = wx.LC_SINGLE_SEL | wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_HRULES | wx.LC_VRULES | wx.VSCROLL
448 )
449 self.LCTRL_allergies.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, ''))
450 self.LCTRL_allergies.InsertColumn(0, _("Type"))
451 self.LCTRL_allergies.InsertColumn(1, _("Status"))
452 self.LCTRL_allergies.InsertColumn(2, _("ATC/Class"))
453 self.LCTRL_allergies.InsertColumn(3, _("Substance"))
454 self.LCTRL_allergies.InsertColumn(4, _("Generics"))
455 self.LCTRL_allergies.InsertColumn(5, _("Reaction"))
456
457
458 pnl_LowerCaption = gmTerryGuiParts.cDividerCaption(self, -1, _('Class notes'))
459
460
461 self.class_notes = wx.TextCtrl (
462 self,
463 -1,
464 "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.",
465 size = (200, 100),
466 style = wx.TE_MULTILINE | wx.TE_READONLY
467 )
468 self.class_notes.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, ''))
469
470
471 self.mainsizer = wx.BoxSizer(wx.VERTICAL)
472 self.mainsizer.Add(pnl_UpperCaption, 0, wx.EXPAND)
473 self.mainsizer.Add(self.editarea, 6, wx.EXPAND)
474
475 self.mainsizer.Add(pnl_MiddleCaption, 0, wx.EXPAND)
476 self.mainsizer.Add(self.LCTRL_allergies, 5, wx.EXPAND)
477 self.mainsizer.Add(pnl_LowerCaption, 0, wx.EXPAND)
478 self.mainsizer.Add(self.class_notes, 4, wx.EXPAND)
479
480 self.SetAutoLayout(True)
481 self.SetSizer(self.mainsizer)
482 self.mainsizer.Fit(self)
483
485 wx.EVT_LIST_ITEM_ACTIVATED(self, ID_ALLERGY_LIST, self._on_allergy_activated)
486
487
488 gmDispatcher.connect(signal = u'post_patient_selection', receiver=self._schedule_data_reget)
489
490
492 self.editarea.set_data()
493 self.LCTRL_allergies.DeleteAllItems()
494
496 if not self.__pat.connected:
497 return False
498
499 self.LCTRL_allergies.DeleteAllItems()
500
501 emr = self.__pat.get_emr()
502 allergies = emr.get_allergies()
503 if allergies is None:
504 return False
505 for list_line in range(len(allergies)):
506 allg = allergies[list_line]
507 list_line = self.LCTRL_allergies.InsertStringItem(list_line, allg['l10n_type'])
508
509 if allg['definite']:
510 self.LCTRL_allergies.SetStringItem(list_line, 1, _('definite'))
511 else:
512 self.LCTRL_allergies.SetStringItem(list_line, 1, _('likely'))
513 if allg['atc_code'] is not None:
514 self.LCTRL_allergies.SetStringItem(list_line, 2, allg['atc_code'])
515 self.LCTRL_allergies.SetStringItem(list_line, 3, allg['substance'])
516 if allg['generics'] is not None:
517 self.LCTRL_allergies.SetStringItem(list_line, 4, allg['generics'])
518 self.LCTRL_allergies.SetStringItem(list_line, 5, allg['reaction'])
519 self.LCTRL_allergies.SetItemData(list_line, allg['pk_allergy'])
520 for col in range(5):
521 self.LCTRL_allergies.SetColumnWidth(col, wx.LIST_AUTOSIZE)
522
523 return True
524
530
531
532
533 if __name__ == "__main__":
534
535 gmI18N.activate_locale()
536 gmI18N.install_domain(domain='gnumed')
537
538
540 app = wx.PyWidgetTester(size = (600, 600))
541 dlg = cAllergyEditAreaDlg(parent=app.frame, id=-1)
542 dlg.ShowModal()
543
544
545
546
547 return
548
550 app = wx.PyWidgetTester(size = (800, 600))
551 dlg = cAllergyManagerDlg(parent=app.frame, id=-1)
552 dlg.ShowModal()
553 return
554
555 if len(sys.argv) > 1 and sys.argv[1] == 'test':
556
557 pat = gmPersonSearch.ask_for_patient()
558 if pat is None:
559 sys.exit(0)
560 gmPatSearchWidgets.set_active_patient(pat)
561
562
563 test_allergy_manager_dlg()
564
565
566
567
568
569