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