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 gmEMRStructWidgets
23 from Gnumed.wxpython import gmPatPicWidgets
24
25
26 _log = logging.getLogger('gm.ui')
27 _log.info(__version__)
28
29 [ ID_BTN_pat_demographics,
30
31 ID_BMITOOL,
32 ID_BMIMENU,
33 ID_PREGTOOL,
34 ID_PREGMENU,
35 ID_LOCKBUTTON,
36 ID_LOCKMENU,
37 ] = map(lambda _init_ctrls: wx.NewId(), range(7))
38
39
40 bg_col = wx.Colour(214,214,214)
41 fg_col = wx.Colour(0,0,131)
42 col_brightred = wx.Colour(255,0,0)
43
44 -class cMainTopPanel(wx.Panel):
45
46 - def __init__(self, parent, id):
47
48 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.RAISED_BORDER)
49
50 self.__gb = gmGuiBroker.GuiBroker()
51
52 self.__do_layout()
53 self.__register_interests()
54
55
56
57 self.curr_pat = gmPerson.gmCurrentPatient()
58
59
60 self.SetAutoLayout(True)
61 self.Show(True)
62
63 - def __do_layout(self):
64 """Create the layout.
65
66 .--------------------------------.
67 | patient | top row |
68 | picture |----------------------|
69 | | bottom row |
70 `--------------------------------'
71 """
72 self.SetBackgroundColour(bg_col)
73
74
75
76
77
78
79
80 self.szr_top_row = wx.BoxSizer(wx.HORIZONTAL)
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
109 self.patient_selector = gmPatSearchWidgets.cActivePatientSelector(self, -1)
110 cfg = gmCfg2.gmCfgData()
111 if cfg.get(option = 'slave'):
112 self.patient_selector.SetEditable(0)
113 self.patient_selector.SetToolTip(None)
114 self.patient_selector.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
115
116
117 self.lbl_age = wx.StaticText(self, -1, u'', style = wx.ALIGN_CENTER_VERTICAL)
118 self.lbl_age.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
119
120
121 self.lbl_allergies = wx.StaticText (self, -1, _('Caveat'), style = wx.ALIGN_CENTER_VERTICAL)
122 self.lbl_allergies.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
123 self.lbl_allergies.SetBackgroundColour(bg_col)
124 self.lbl_allergies.SetForegroundColour(col_brightred)
125 self.txt_allergies = wx.TextCtrl (self, -1, "", style = wx.TE_READONLY)
126 self.txt_allergies.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
127 self.txt_allergies.SetForegroundColour (col_brightred)
128
129 self.szr_top_row.Add(self.patient_selector, 6, wx.LEFT | wx.BOTTOM, 3)
130 self.szr_top_row.Add(self.lbl_age, 0, wx.ALL, 3)
131 self.szr_top_row.Add(self.lbl_allergies, 0, wx.ALL, 3)
132 self.szr_top_row.Add(self.txt_allergies, 8, wx.BOTTOM, 3)
133
134
135
136
137
138
139
140
141
142 self.szr_bottom_row = wx.BoxSizer(wx.HORIZONTAL)
143 self._PNL_tags = gmDemographicsWidgets.cImageTagPresenterPnl(self, -1)
144 self.szr_bottom_row.Add(self._PNL_tags, 2, wx.ALIGN_CENTER_VERTICAL, 0)
145
146
147 self.szr_bottom_row.Add((20, 20), 1, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 0)
148
149 pnl_enc = gmEMRStructWidgets.cActiveEncounterPnl(self, -1)
150 self.szr_bottom_row.Add(pnl_enc, 1, wx.ALIGN_CENTER_VERTICAL, 0)
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
184
185
186
187
188
189
190 self.szr_stacked_rows = wx.BoxSizer(wx.VERTICAL)
191
192
193 try:
194 self.szr_stacked_rows.Add(1, 1, 0)
195 except:
196 self.szr_stacked_rows.Add((1, 1), 0)
197
198
199 self.szr_stacked_rows.Add(self.szr_top_row, 0, wx.EXPAND)
200 self.szr_stacked_rows.Add(self.szr_bottom_row, 1, wx.EXPAND|wx.TOP, 5)
201
202
203 self.patient_picture = gmPatPicWidgets.cPatientPicture(self, -1)
204
205
206
207
208 self.szr_main = wx.BoxSizer(wx.HORIZONTAL)
209
210 self.szr_main.Add(self.patient_picture, 0, wx.LEFT | wx.TOP | wx.Right, 5)
211
212 self.szr_main.Add(self.szr_stacked_rows, 1)
213
214
215 self.SetSizer(self.szr_main)
216
217 self.szr_main.Fit(self)
218
219
220
221
222
223
225
226 wx.EVT_BUTTON(self, ID_BTN_pat_demographics, self.__on_display_demographics)
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245 wx.EVT_LEFT_DCLICK(self.txt_allergies, self._on_allergies_dclicked)
246
247
248 gmDispatcher.connect(signal = u'post_patient_selection', receiver = self._on_post_patient_selection)
249 gmDispatcher.connect(signal = u'allg_mod_db', receiver = self._update_allergies)
250 gmDispatcher.connect(signal = u'allg_state_mod_db', receiver = self._update_allergies)
251 gmDispatcher.connect(signal = u'name_mod_db', receiver = self._on_name_identity_change)
252 gmDispatcher.connect(signal = u'identity_mod_db', receiver = self._on_name_identity_change)
253 gmDispatcher.connect(signal = u'identity_tag_mod_db', receiver = self._on_tag_change)
254
255
256
257
258
259
261 pat = gmPerson.gmCurrentPatient()
262 if not pat.connected:
263 gmDispatcher.send('statustext', msg = _('Cannot activate Allergy Manager. No active patient.'))
264 return
265 dlg = gmAllergyWidgets.cAllergyManagerDlg(parent=self, id=-1)
266 dlg.ShowModal()
267 return
268
269
270
271
272
273
274
275
276
277
278
279
280
281 - def _on_tag_change(self):
282 wx.CallAfter(self.__update_tags)
283
285 wx.CallAfter(self.__on_name_identity_change)
286
288 self.__update_age_label()
289 self.Layout()
290
292
293
294 wx.CallAfter(self.__on_post_patient_selection, **kwargs)
295
297 self.__update_age_label()
298 self.__update_allergies()
299 self.__update_tags()
300 self.Layout()
301
303 print "display patient demographic window now"
304
305 - def _update_allergies(self, **kwargs):
306 wx.CallAfter(self.__update_allergies)
307
308
309
312
314
315 if self.curr_pat['deceased'] is None:
316
317 if self.curr_pat.get_formatted_dob(format = '%m-%d') == pyDT.datetime.now(tz = gmDateTime.gmCurrentLocalTimezone).strftime('%m-%d'):
318 template = _('%s %s (%s today !)')
319 else:
320 template = u'%s %s (%s)'
321
322
323
324 age = template % (
325 gmPerson.map_gender2symbol[self.curr_pat['gender']],
326 self.curr_pat.get_formatted_dob(format = '%d %b %Y', encoding = gmI18N.get_encoding()),
327 self.curr_pat['medical_age']
328 )
329
330
331 if self.curr_pat['lastnames'] == u'Leibner':
332 if self.curr_pat['firstnames'] == u'Steffi':
333 if self.curr_pat['preferred'] == u'Wildfang':
334 age = u'%s %s' % (gmTools.u_black_heart, age)
335
336 else:
337
338 template = u'%s %s - %s (%s)'
339 age = template % (
340 gmPerson.map_gender2symbol[self.curr_pat['gender']],
341 self.curr_pat.get_formatted_dob(format = '%d.%b %Y', encoding = gmI18N.get_encoding()),
342 self.curr_pat['deceased'].strftime('%d.%b %Y').decode(gmI18N.get_encoding()),
343 self.curr_pat['medical_age']
344 )
345
346 self.lbl_age.SetLabel(age)
347
348 - def __update_allergies(self, **kwargs):
349
350 emr = self.curr_pat.get_emr()
351 state = emr.allergy_state
352
353
354 if state['last_confirmed'] is None:
355 confirmed = _('never')
356 else:
357 confirmed = state['last_confirmed'].strftime('%Y %B %d').decode(gmI18N.get_encoding())
358 tt = (state.state_string + (90 * u' '))[:90] + u'\n'
359 tt += _('last confirmed %s\n') % confirmed
360 tt += gmTools.coalesce(state['comment'], u'', _('Comment (%s): %%s') % state['modified_by'])
361 tt += u'\n'
362
363
364 tmp = []
365 for allergy in emr.get_allergies():
366
367 if allergy['type'] == 'allergy':
368 tmp.append(allergy['descriptor'][:10].strip() + gmTools.u_ellipsis)
369
370 if allergy['definite']:
371 certainty = _('definite')
372 else:
373 certainty = _('suspected')
374 reaction = gmTools.coalesce(allergy['reaction'], _('reaction not recorded'))
375 if len(reaction) > 50:
376 reaction = reaction[:50] + gmTools.u_ellipsis
377 tt += u'%s (%s, %s): %s\n' % (
378 allergy['descriptor'],
379 allergy['l10n_type'],
380 certainty,
381 reaction
382 )
383
384 if len(tmp) == 0:
385 tmp = state.state_symbol
386 else:
387 tmp = ','.join(tmp)
388
389 if state['last_confirmed'] is not None:
390 tmp += state['last_confirmed'].strftime(' (%x)')
391
392 self.txt_allergies.SetValue(tmp)
393 self.txt_allergies.SetToolTipString(tt)
394
395
396
398 """Insert a widget on the right-hand side of the bottom toolbar.
399 """
400 self.szr_bottom_row.Add(widget, 0, wx.RIGHT, 0)
401
403 """Insert a widget on the left-hand side of the bottom toolbar.
404 """
405 self.szr_bottom_row.Prepend(widget, 0, wx.ALL, 0)
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
472
473
474
475
476
477
478 if __name__ == "__main__":
479 wx.InitAllImageHandlers()
480 app = wxPyWidgetTester(size = (400, 200))
481 app.SetWidget(cMainTopPanel, -1)
482 app.MainLoop()
483
484