| Home | Trees | Indices | Help |
|
|---|
|
|
1 """GNUmed provider inbox handling widgets.
2 """
3 #================================================================
4 __version__ = "$Revision: 1.48 $"
5 __author__ = "Karsten Hilbert <Karsten.Hilbert@gmx.net>"
6
7 import sys, logging
8
9
10 import wx
11
12
13 if __name__ == '__main__':
14 sys.path.insert(0, '../../')
15 from Gnumed.pycommon import gmI18N, gmDispatcher, gmTools, gmCfg, gmPG2, gmExceptions
16 from Gnumed.business import gmPerson, gmSurgery
17 from Gnumed.wxpython import gmGuiHelpers, gmListWidgets, gmPlugin, gmRegetMixin, gmPhraseWheel, gmEditArea, gmAuthWidgets, gmPatSearchWidgets
18 from Gnumed.wxGladeWidgets import wxgProviderInboxPnl, wxgTextExpansionEditAreaPnl
19
20
21 _log = logging.getLogger('gm.ui')
22 _log.info(__version__)
23
24 _indicator = {
25 -1: '',
26 0: '',
27 1: '*!!*'
28 }
29 #============================================================
31
33
34 try:
35 self.__keyword = kwds['keyword']
36 del kwds['keyword']
37 except KeyError:
38 self.__keyword = None
39
40 wxgTextExpansionEditAreaPnl.wxgTextExpansionEditAreaPnl.__init__(self, *args, **kwds)
41
42 self.__init_ui()
43 self.__register_interests()
44 #--------------------------------------------------------
46 if not self.__valid_for_save():
47 return False
48
49 if self.__keyword is None:
50 result = gmPG2.add_text_expansion (
51 keyword = self._TCTRL_keyword.GetValue().strip(),
52 expansion = self._TCTRL_expansion.GetValue(),
53 public = self._RBTN_public.GetValue()
54 )
55 else:
56 gmPG2.edit_text_expansion (
57 keyword = self._TCTRL_keyword.GetValue().strip(),
58 expansion = self._TCTRL_expansion.GetValue()
59 )
60 result = True
61
62 return result
63 #--------------------------------------------------------
66 # if self.__keyword is not None:
67 # self._TCTRL_expansion.SetValue(u'')
68 #--------------------------------------------------------
69 # event handling
70 #--------------------------------------------------------
73 #--------------------------------------------------------
75 if self._TCTRL_keyword.GetValue().strip() == u'':
76 self._TCTRL_expansion.Enable(False)
77 else:
78 self._TCTRL_expansion.Enable(True)
79 #--------------------------------------------------------
80 # internal API
81 #--------------------------------------------------------
83
84 kwd = self._TCTRL_keyword.GetValue().strip()
85 if kwd == u'':
86 self._TCTRL_keyword.SetBackgroundColour('pink')
87 gmDispatcher.send(signal = 'statustext', msg = _('Cannot save text expansion without keyword.'), beep = True)
88 return False
89 self._TCTRL_keyword.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
90
91 if self._TCTRL_expansion.GetValue().strip() == u'':
92 self._TCTRL_expansion.SetBackgroundColour('pink')
93 gmDispatcher.send(signal = 'statustext', msg = _('Cannot save text expansion without expansion text.'), beep = True)
94 return False
95 self._TCTRL_expansion.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
96
97 return True
98 #--------------------------------------------------------
100
101 if keyword is not None:
102 self.__keyword = keyword
103
104 if self.__keyword is None:
105 self._TCTRL_keyword.SetValue(u'')
106 self._TCTRL_keyword.Enable(True)
107 self._TCTRL_expansion.SetValue(u'')
108 self._TCTRL_expansion.Enable(False)
109 self._RBTN_public.Enable(True)
110 self._RBTN_private.Enable(True)
111 self._RBTN_public.SetValue(1)
112 else:
113 expansion = gmPG2.expand_keyword(keyword = self.__keyword)
114 self._TCTRL_keyword.SetValue(self.__keyword)
115 self._TCTRL_keyword.Enable(False)
116 self._TCTRL_expansion.SetValue(gmTools.coalesce(expansion, u''))
117 self._TCTRL_expansion.Enable(True)
118 self._RBTN_public.Enable(False)
119 self._RBTN_private.Enable(False)
120 #============================================================
122
123 if parent is None:
124 parent = wx.GetApp().GetTopWindow()
125
126 #----------------------
127 def delete(keyword=None):
128 gmPG2.delete_text_expansion(keyword = keyword)
129 return True
130 #----------------------
131 def edit(keyword=None):
132 # add new keyword
133 ea = cTextExpansionEditAreaPnl(parent, -1, keyword=keyword)
134 dlg = gmEditArea.cGenericEditAreaDlg(parent, -1, edit_area = ea)
135 dlg.SetTitle (
136 gmTools.coalesce(keyword, _('Adding text expansion'), _('Editing text expansion "%s"'))
137 )
138 if dlg.ShowModal() == wx.ID_OK:
139 return True
140
141 return False
142 #----------------------
143 def refresh(lctrl=None):
144 kwds = [ [
145 r[0],
146 gmTools.bool2subst(r[1], gmTools.u_checkmark_thick, u''),
147 gmTools.bool2subst(r[2], gmTools.u_checkmark_thick, u''),
148 r[3]
149 ] for r in gmPG2.get_text_expansion_keywords()
150 ]
151 data = [ r[0] for r in gmPG2.get_text_expansion_keywords() ]
152 lctrl.set_string_items(kwds)
153 lctrl.set_data(data)
154 #----------------------
155
156 gmListWidgets.get_choices_from_list (
157 parent = parent,
158 msg = _('\nSelect the keyword you want to edit !\n'),
159 caption = _('Editing keyword-based text expansions ...'),
160 columns = [_('Keyword'), _('Public'), _('Private'), _('Owner')],
161 single_selection = True,
162 edit_callback = edit,
163 new_callback = edit,
164 delete_callback = delete,
165 refresh_callback = refresh
166 )
167 #============================================================
169
171
172 gmPhraseWheel.cPhraseWheel.__init__ (
173 self,
174 *args,
175 **kwargs
176 )
177 self.matcher = gmPerson.cMatchProvider_Provider()
178 self.SetToolTipString(_('Select a healthcare provider.'))
179 self.selection_only = True
180 #============================================================
181 # practice related widgets
182 #============================================================
184
185 if parent is None:
186 parent = wx.GetApp().GetTopWindow()
187
188 #-----------------------------------
189 def refresh(lctrl):
190
191 cmd = u'SELECT * FROM audit.v_audit_trail ORDER BY audit_when_ts'
192 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = False)
193
194
195
196 lctrl.set_string_items (
197 [ [
198 r['event_when'],
199 r['event_by'],
200 u'%s %s %s' % (
201 gmTools.coalesce(r['row_version_before'], gmTools.u_diameter),
202 gmTools.u_right_arrow,
203 gmTools.coalesce(r['row_version_after'], gmTools.u_diameter)
204 ),
205 r['event_table'],
206 r['event'],
207 r['pk_audit']
208 ] for r in rows ]
209 )
210 #lctrl.set_selections(selections = sels)
211 #-----------------------------------
212 gmListWidgets.get_choices_from_list (
213 parent = parent,
214 msg = u'',
215 caption = _('GNUmed database audit log ...'),
216 columns = [ _('When'), _('Who'), _('Revisions'), _('Table'), _('Event'), '#' ],
217 single_selection = True,
218 refresh_callback = refresh
219 )
220
221 #============================================================
222 # FIXME: this should be moved elsewhere !
224
225 if parent is None:
226 parent = wx.GetApp().GetTopWindow()
227
228 #-----------------------------------
229 def delete(workplace):
230
231 curr_workplace = gmSurgery.gmCurrentPractice().active_workplace
232 if workplace == curr_workplace:
233 gmDispatcher.send(signal = 'statustext', msg = _('Cannot delete the active workplace.'), beep = True)
234 return False
235
236 dlg = gmGuiHelpers.c2ButtonQuestionDlg (
237 parent,
238 -1,
239 caption = _('Deleting workplace ...'),
240 question = _('Are you sure you want to delete this workplace ?\n\n "%s"\n') % workplace,
241 show_checkbox = True,
242 checkbox_msg = _('delete configuration, too'),
243 checkbox_tooltip = _(
244 'Check this if you want to delete all configuration items\n'
245 'for this workplace along with the workplace itself.'
246 ),
247 button_defs = [
248 {'label': _('Delete'), 'tooltip': _('Yes, delete this workplace.'), 'default': True},
249 {'label': _('Do NOT delete'), 'tooltip': _('No, do NOT delete this workplace'), 'default': False}
250 ]
251 )
252
253 decision = dlg.ShowModal()
254 if decision != wx.ID_YES:
255 dlg.Destroy()
256 return False
257
258 include_cfg = dlg.checkbox_is_checked()
259 dlg.Destroy()
260
261 dbo_conn = gmAuthWidgets.get_dbowner_connection(procedure = _('delete workplace'))
262 if not dbo_conn:
263 return False
264
265 gmSurgery.delete_workplace(workplace = workplace, conn = dbo_conn, delete_config = include_cfg)
266 return True
267 #-----------------------------------
268 def edit(workplace=None):
269
270 available_plugins = gmPlugin.get_installed_plugins(plugin_dir='gui')
271
272 dbcfg = gmCfg.cCfgSQL()
273
274 if workplace is None:
275 dlg = wx.TextEntryDialog (
276 parent = parent,
277 message = _('Enter a descriptive name for the new workplace:'),
278 caption = _('Configuring GNUmed workplaces ...'),
279 defaultValue = u'',
280 style = wx.OK | wx.CENTRE
281 )
282 dlg.ShowModal()
283 workplace = dlg.GetValue().strip()
284 if workplace == u'':
285 gmGuiHelpers.gm_show_error(_('Cannot save a new workplace without a name.'), _('Configuring GNUmed workplaces ...'))
286 return False
287 curr_plugins = []
288 choices = available_plugins
289 else:
290 curr_plugins = gmTools.coalesce(dbcfg.get2 (
291 option = u'horstspace.notebook.plugin_load_order',
292 workplace = workplace,
293 bias = 'workplace'
294 ), []
295 )
296 choices = curr_plugins[:]
297 for p in available_plugins:
298 if p not in choices:
299 choices.append(p)
300
301 sels = range(len(curr_plugins))
302 new_plugins = gmListWidgets.get_choices_from_list (
303 parent = parent,
304 msg = _(
305 '\n'
306 'Select the plugin(s) to be loaded the next time\n'
307 'the client is restarted under the workplace:\n'
308 '\n'
309 ' [%s]'
310 '\n'
311 ) % workplace,
312 caption = _('Configuring GNUmed workplaces ...'),
313 choices = choices,
314 selections = sels,
315 columns = [_('Plugins')],
316 single_selection = False
317 )
318
319 if new_plugins == curr_plugins:
320 return True
321
322 if new_plugins is None:
323 return True
324
325 dbcfg.set (
326 option = u'horstspace.notebook.plugin_load_order',
327 value = new_plugins,
328 workplace = workplace
329 )
330
331 return True
332 #-----------------------------------
333 def refresh(lctrl):
334 workplaces = gmSurgery.gmCurrentPractice().workplaces
335 curr_workplace = gmSurgery.gmCurrentPractice().active_workplace
336 try:
337 sels = [workplaces.index(curr_workplace)]
338 except ValueError:
339 sels = []
340
341 lctrl.set_string_items(workplaces)
342 lctrl.set_selections(selections = sels)
343 #-----------------------------------
344 gmListWidgets.get_choices_from_list (
345 parent = parent,
346 msg = _(
347 '\nSelect the workplace to configure below.\n'
348 '\n'
349 'The currently active workplace is preselected.\n'
350 ),
351 caption = _('Configuring GNUmed workplaces ...'),
352 columns = [_('Workplace')],
353 single_selection = True,
354 refresh_callback = refresh,
355 edit_callback = edit,
356 new_callback = edit,
357 delete_callback = delete
358 )
359 #============================================================
360 -class cProviderInboxPnl(wxgProviderInboxPnl.wxgProviderInboxPnl, gmRegetMixin.cRegetOnPaintMixin):
361
362 _item_handlers = {}
363 _patient_msg_types = ['clinical.review docs', 'clinical.review results']
364 #--------------------------------------------------------
366
367 wxgProviderInboxPnl.wxgProviderInboxPnl.__init__(self, *args, **kwds)
368 gmRegetMixin.cRegetOnPaintMixin.__init__(self)
369
370 self.provider = gmPerson.gmCurrentProvider()
371 self.filter_mode = 'all'
372 self.__init_ui()
373
374 cProviderInboxPnl._item_handlers['clinical.review docs'] = self._goto_doc_review
375 cProviderInboxPnl._item_handlers['clinical.review results'] = self._goto_measurements_review
376
377 self.__register_interests()
378 #--------------------------------------------------------
379 # reget-on-paint API
380 #--------------------------------------------------------
384 #--------------------------------------------------------
385 # internal helpers
386 #--------------------------------------------------------
388 gmDispatcher.connect(signal = u'message_inbox_generic_mod_db', receiver = self._on_message_inbox_mod_db)
389 gmDispatcher.connect(signal = u'message_inbox_mod_db', receiver = self._on_message_inbox_mod_db)
390 # FIXME: listen for results insertion/deletion
391 gmDispatcher.connect(signal = u'reviewed_test_results_mod_db', receiver = self._on_message_inbox_mod_db)
392 # FIXME: listen for doc insertion/deletion
393 # FIXME: listen for doc reviews
394 gmDispatcher.connect(signal = u'post_patient_selection', receiver = self._on_post_patient_selection)
395 #--------------------------------------------------------
397 self._LCTRL_provider_inbox.set_columns([u'', _('date'), _('category'), _('type'), _('message')])
398
399 msg = _('\n Inbox of %(title)s %(lname)s.\n') % {
400 'title': gmTools.coalesce (
401 self.provider['title'],
402 gmPerson.map_gender2salutation(self.provider['gender'])
403 ),
404 'lname': self.provider['lastnames']
405 }
406
407 self._msg_welcome.SetLabel(msg)
408
409 if gmPerson.gmCurrentPatient().connected:
410 self._RBTN_active_patient.Enable()
411 #--------------------------------------------------------
413
414 """Fill UI with data."""
415 self.__msgs = self.provider.inbox.messages
416
417 if self.filter_mode == 'active':
418 if gmPerson.gmCurrentPatient().connected:
419 curr_pat_id = gmPerson.gmCurrentPatient().ID
420 self.__msgs = [ m for m in self.__msgs if m['pk_patient'] == curr_pat_id ]
421 else:
422 self.__msgs = []
423
424 items = [
425 [
426 _indicator[m['importance']],
427 m['received_when'].strftime('%Y-%m-%d'),
428 m['l10n_category'],
429 m['l10n_type'],
430 m['comment']
431 ] for m in self.__msgs
432 ]
433 self._LCTRL_provider_inbox.set_string_items(items = items)
434 self._LCTRL_provider_inbox.set_data(data = self.__msgs)
435 self._LCTRL_provider_inbox.set_column_widths()
436 #--------------------------------------------------------
437 # event handlers
438 #--------------------------------------------------------
442 #--------------------------------------------------------
444 wx.CallAfter(self._schedule_data_reget)
445 gmDispatcher.send(signal = u'request_user_attention', msg = _('Please check your GNUmed Inbox !'))
446 #--------------------------------------------------------
448 msg = self._LCTRL_provider_inbox.get_selected_item_data(only_one = True)
449 if msg is None:
450 return
451
452 handler_key = '%s.%s' % (msg['category'], msg['type'])
453 try:
454 handle_item = cProviderInboxPnl._item_handlers[handler_key]
455 except KeyError:
456 gmGuiHelpers.gm_show_warning (
457 _(
458 """No double-click action pre-programmed into
459 GNUmed for message category and type:
460
461 [%s]
462 """
463 ) % handler_key,
464 _('handling provider inbox item')
465 )
466 return False
467
468 if not handle_item(pk_context = msg['pk_context'], pk_patient = msg['pk_patient']):
469 _log.error('item handler returned "false"')
470 _log.error('handler key: [%s]', handler_key)
471 _log.error('message: %s', str(msg))
472 return False
473
474 return True
475 #--------------------------------------------------------
478 #--------------------------------------------------------
480 msg = self._LCTRL_provider_inbox.get_selected_item_data(only_one = True)
481 if msg is None:
482 return
483
484 if msg['data'] is None:
485 tmp = _('Message: %s') % msg['comment']
486 else:
487 tmp = _('Message: %s\nData: %s') % (msg['comment'], msg['data'])
488
489 self._TXT_inbox_item_comment.SetValue(tmp)
490 #--------------------------------------------------------
492 tmp = self._LCTRL_provider_inbox.get_selected_item_data(only_one = True)
493 if tmp is None:
494 return
495 self.__focussed_msg = tmp
496
497 # build menu
498 menu = wx.Menu(title = _('Inbox Message menu'))
499 # - delete message
500 if not self.__focussed_msg['is_virtual']:
501 ID = wx.NewId()
502 menu.AppendItem(wx.MenuItem(menu, ID, _('delete message')))
503 wx.EVT_MENU(menu, ID, self._on_delete_focussed_msg)
504
505 # show menu
506 self.PopupMenu(menu, wx.DefaultPosition)
507 menu.Destroy()
508 #--------------------------------------------------------
513 #--------------------------------------------------------
518 #--------------------------------------------------------
519 # item handlers
520 #--------------------------------------------------------
522 if self.__focussed_msg['is_virtual']:
523 gmDispatcher.send(signal = 'statustext', msg = _('You must deal with the reason for this message to remove it from your inbox.'), beep = True)
524 return False
525
526 if not self.provider.inbox.delete_message(self.__focussed_msg['pk_message_inbox']):
527 gmDispatcher.send(signal='statustext', msg=_('Problem removing message from Inbox.'))
528 return False
529 return True
530 #--------------------------------------------------------
532 wx.BeginBusyCursor()
533
534 try:
535 pat = gmPerson.cIdentity(aPK_obj = pk_patient)
536 except gmExceptions.ConstructorError:
537 wx.EndBusyCursor()
538 _log.exception('patient [%s] not found', pk_patient)
539 gmGuiHelpers.gm_show_error (
540 _('Supposedly there are unreviewed documents\n'
541 'for patient [%s]. However, I cannot find\n'
542 'that patient in the GNUmed database.'
543 ) % pk_patient,
544 _('handling provider inbox item')
545 )
546 return False
547
548 success = gmPatSearchWidgets.set_active_patient(patient = pat)
549
550 wx.EndBusyCursor()
551
552 if not success:
553 gmGuiHelpers.gm_show_error (
554 _('Supposedly there are unreviewed documents\n'
555 'for patient [%s]. However, I cannot find\n'
556 'that patient in the GNUmed database.'
557 ) % pk_patient,
558 _('handling provider inbox item')
559 )
560 return False
561
562 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmShowMedDocs', sort_mode = 'review')
563 return True
564 #--------------------------------------------------------
566 wx.BeginBusyCursor()
567 success = gmPatSearchWidgets.set_active_patient(patient=gmPerson.cIdentity(aPK_obj=pk_patient))
568 wx.EndBusyCursor()
569 if not success:
570 gmGuiHelpers.gm_show_error (
571 _('Supposedly there are unreviewed results\n'
572 'for patient [%s]. However, I cannot find\n'
573 'that patient in the GNUmed database.'
574 ) % pk_patient,
575 _('handling provider inbox item')
576 )
577 return False
578
579 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmMeasurementsGridPlugin')
580 return True
581 #============================================================
582 if __name__ == '__main__':
583
584 gmI18N.activate_locale()
585 gmI18N.install_domain(domain = 'gnumed')
586
590
592 app = wx.PyWidgetTester(size = (800, 600))
593 app.SetWidget(cProviderInboxPnl, -1)
594 app.MainLoop()
595
596 if len(sys.argv) > 1 and sys.argv[1] == 'test':
597 #test_configure_wp_plugins()
598 test_message_inbox()
599
600 #============================================================
601
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Mon Jun 28 04:12:56 2010 | http://epydoc.sourceforge.net |