1
2
3
4 __version__ = "$Revision: 1.106 $"
5 __author__ = "R.Terry <rterry@gnumed.net>, I.Haywood <i.haywood@ugrad.unimelb.edu.au>, K.Hilbert <Karsten.Hilbert@gmx.net>"
6 __license__ = "GPL"
7
8
9 import sys, os.path, datetime as pyDT, logging
10
11
12 import wx
13
14
15 from Gnumed.pycommon import gmGuiBroker, gmPG2, gmDispatcher, gmTools, gmCfg2, gmDateTime, gmI18N
16 from Gnumed.business import gmPerson, gmEMRStructItems, gmAllergy
17
18 from Gnumed.wxpython import gmGuiHelpers
19 from Gnumed.wxpython import gmDemographicsWidgets
20 from Gnumed.wxpython import gmAllergyWidgets
21 from Gnumed.wxpython import gmPatSearchWidgets
22 from Gnumed.wxpython import gmPatPicWidgets
23
24
25 _log = logging.getLogger('gm.ui')
26 _log.info(__version__)
27
28 [ ID_BTN_pat_demographics,
29
30 ID_BMITOOL,
31 ID_BMIMENU,
32 ID_PREGTOOL,
33 ID_PREGMENU,
34 ID_LOCKBUTTON,
35 ID_LOCKMENU,
36 ] = map(lambda _init_ctrls: wx.NewId(), range(7))
37
38
39 bg_col = wx.Colour(214,214,214)
40 fg_col = wx.Colour(0,0,131)
41 col_brightred = wx.Colour(255,0,0)
42
43 -class cMainTopPanel(wx.Panel):
44
45 - def __init__(self, parent, id):
46
47 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.RAISED_BORDER)
48
49 self.__gb = gmGuiBroker.GuiBroker()
50
51 self.__do_layout()
52 self.__register_interests()
53
54
55
56 self.curr_pat = gmPerson.gmCurrentPatient()
57
58
59 self.SetAutoLayout(True)
60 self.Show(True)
61
62 - def __do_layout(self):
63 """Create the layout.
64
65 .--------------------------------.
66 | patient | top row |
67 | picture |----------------------|
68 | | bottom row |
69 `--------------------------------'
70 """
71 self.SetBackgroundColour(bg_col)
72
73
74
75
76
77
78
79 self.szr_top_row = wx.BoxSizer(wx.HORIZONTAL)
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 self.patient_selector = gmPatSearchWidgets.cActivePatientSelector(self, -1)
109 cfg = gmCfg2.gmCfgData()
110 if cfg.get(option = 'slave'):
111 self.patient_selector.SetEditable(0)
112 self.patient_selector.SetToolTip(None)
113 self.patient_selector.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
114
115
116 self.lbl_age = wx.StaticText(self, -1, u'', style = wx.ALIGN_CENTER_VERTICAL)
117 self.lbl_age.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
118
119
120 self.lbl_allergies = wx.StaticText (self, -1, _('Caveat'), style = wx.ALIGN_CENTER_VERTICAL)
121 self.lbl_allergies.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
122 self.lbl_allergies.SetBackgroundColour(bg_col)
123 self.lbl_allergies.SetForegroundColour(col_brightred)
124 self.txt_allergies = wx.TextCtrl (self, -1, "", style = wx.TE_READONLY)
125 self.txt_allergies.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
126 self.txt_allergies.SetForegroundColour (col_brightred)
127
128 self.szr_top_row.Add(self.patient_selector, 6, wx.LEFT | wx.BOTTOM, 3)
129 self.szr_top_row.Add(self.lbl_age, 0, wx.ALL, 3)
130 self.szr_top_row.Add(self.lbl_allergies, 0, wx.ALL, 3)
131 self.szr_top_row.Add(self.txt_allergies, 8, wx.BOTTOM, 3)
132
133
134
135
136
137
138
139
140
141 self.szr_bottom_row = wx.BoxSizer(wx.HORIZONTAL)
142 self._PNL_tags = gmDemographicsWidgets.cImageTagPresenterPnl(self, -1)
143 self.szr_bottom_row.Add(self._PNL_tags, 0, wx.GROW, 0)
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183 self.szr_stacked_rows = wx.BoxSizer(wx.VERTICAL)
184
185
186 try:
187 self.szr_stacked_rows.Add(1, 1, 0)
188 except:
189 self.szr_stacked_rows.Add((1, 1), 0)
190
191
192 self.szr_stacked_rows.Add(self.szr_top_row, 0, wx.EXPAND)
193 self.szr_stacked_rows.Add(self.szr_bottom_row, 1, wx.EXPAND|wx.TOP, 5)
194
195
196 self.patient_picture = gmPatPicWidgets.cPatientPicture(self, -1)
197
198
199
200
201 self.szr_main = wx.BoxSizer(wx.HORIZONTAL)
202
203 self.szr_main.Add(self.patient_picture, 0, wx.LEFT | wx.TOP | wx.Right, 5)
204
205 self.szr_main.Add(self.szr_stacked_rows, 1)
206
207
208 self.SetSizer(self.szr_main)
209
210 self.szr_main.Fit(self)
211
212
213
214
215
216
218
219 wx.EVT_BUTTON(self, ID_BTN_pat_demographics, self.__on_display_demographics)
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238 wx.EVT_LEFT_DCLICK(self.txt_allergies, self._on_allergies_dclicked)
239
240
241 gmDispatcher.connect(signal = u'post_patient_selection', receiver = self._on_post_patient_selection)
242 gmDispatcher.connect(signal = u'allg_mod_db', receiver = self._update_allergies)
243 gmDispatcher.connect(signal = u'allg_state_mod_db', receiver = self._update_allergies)
244 gmDispatcher.connect(signal = u'name_mod_db', receiver = self._on_name_identity_change)
245 gmDispatcher.connect(signal = u'identity_mod_db', receiver = self._on_name_identity_change)
246 gmDispatcher.connect(signal = u'identity_tag_mod_db', receiver = self._on_tag_change)
247
248
249
250
251
252
254 pat = gmPerson.gmCurrentPatient()
255 if not pat.connected:
256 gmDispatcher.send('statustext', msg = _('Cannot activate Allergy Manager. No active patient.'))
257 return
258 dlg = gmAllergyWidgets.cAllergyManagerDlg(parent=self, id=-1)
259 dlg.ShowModal()
260 return
261
262
263
264
265
266
267
268
269
270
271
272
273
274 - def _on_tag_change(self):
275 wx.CallAfter(self.__update_tags)
276
278 wx.CallAfter(self.__on_name_identity_change)
279
281 self.__update_age_label()
282 self.Layout()
283
285
286
287 wx.CallAfter(self.__on_post_patient_selection, **kwargs)
288
290 self.__update_age_label()
291 self.__update_allergies()
292 self.__update_tags()
293 self.Layout()
294
296 print "display patient demographic window now"
297
298 - def _update_allergies(self, **kwargs):
299 wx.CallAfter(self.__update_allergies)
300
301
302
305
307
308 if self.curr_pat['deceased'] is None:
309
310 if self.curr_pat.get_formatted_dob(format = '%m-%d') == pyDT.datetime.now(tz = gmDateTime.gmCurrentLocalTimezone).strftime('%m-%d'):
311 template = _('%s %s (%s today !)')
312 else:
313 template = u'%s %s (%s)'
314
315
316
317 age = template % (
318 gmPerson.map_gender2symbol[self.curr_pat['gender']],
319 self.curr_pat.get_formatted_dob(format = '%d %b %Y', encoding = gmI18N.get_encoding()),
320 self.curr_pat['medical_age']
321 )
322
323
324 if self.curr_pat['lastnames'] == u'Leibner':
325 if self.curr_pat['firstnames'] == u'Steffi':
326 if self.curr_pat['preferred'] == u'Wildfang':
327 age = u'%s %s' % (gmTools.u_black_heart, age)
328
329 else:
330
331 template = u'%s %s - %s (%s)'
332 age = template % (
333 gmPerson.map_gender2symbol[self.curr_pat['gender']],
334 self.curr_pat.get_formatted_dob(format = '%d.%b %Y', encoding = gmI18N.get_encoding()),
335 self.curr_pat['deceased'].strftime('%d.%b %Y').decode(gmI18N.get_encoding()),
336 self.curr_pat['medical_age']
337 )
338
339 self.lbl_age.SetLabel(age)
340
341 - def __update_allergies(self, **kwargs):
342
343 emr = self.curr_pat.get_emr()
344 state = emr.allergy_state
345
346
347 if state['last_confirmed'] is None:
348 confirmed = _('never')
349 else:
350 confirmed = state['last_confirmed'].strftime('%Y %B %d').decode(gmI18N.get_encoding())
351 tt = (state.state_string + (90 * u' '))[:90] + u'\n'
352 tt += _('last confirmed %s\n') % confirmed
353 tt += gmTools.coalesce(state['comment'], u'', _('Comment (%s): %%s') % state['modified_by'])
354 tt += u'\n'
355
356
357 tmp = []
358 for allergy in emr.get_allergies():
359
360 if allergy['type'] == 'allergy':
361 tmp.append(allergy['descriptor'][:10].strip() + gmTools.u_ellipsis)
362
363 if allergy['definite']:
364 certainty = _('definite')
365 else:
366 certainty = _('suspected')
367 reaction = gmTools.coalesce(allergy['reaction'], _('reaction not recorded'))
368 if len(reaction) > 50:
369 reaction = reaction[:50] + gmTools.u_ellipsis
370 tt += u'%s (%s, %s): %s\n' % (
371 allergy['descriptor'],
372 allergy['l10n_type'],
373 certainty,
374 reaction
375 )
376
377 if len(tmp) == 0:
378 tmp = state.state_symbol
379 else:
380 tmp = ','.join(tmp)
381
382 if state['last_confirmed'] is not None:
383 tmp += state['last_confirmed'].strftime(' (%x)')
384
385 self.txt_allergies.SetValue(tmp)
386 self.txt_allergies.SetToolTipString(tt)
387
388
389
391 """Insert a widget on the right-hand side of the bottom toolbar.
392 """
393 self.szr_bottom_row.Add(widget, 0, wx.RIGHT, 0)
394
396 """Insert a widget on the left-hand side of the bottom toolbar.
397 """
398 self.szr_bottom_row.Prepend(widget, 0, wx.ALL, 0)
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471 if __name__ == "__main__":
472 wx.InitAllImageHandlers()
473 app = wxPyWidgetTester(size = (400, 200))
474 app.SetWidget(cMainTopPanel, -1)
475 app.MainLoop()
476
477