1 """GNUmed provider inbox handling widgets.
2 """
3
4 __author__ = "Karsten Hilbert <Karsten.Hilbert@gmx.net>"
5
6 import sys
7 import logging
8
9
10 import wx
11
12
13 if __name__ == '__main__':
14 sys.path.insert(0, '../../')
15 from Gnumed.pycommon import gmI18N
16 from Gnumed.pycommon import gmExceptions
17 from Gnumed.pycommon import gmPG2
18 from Gnumed.pycommon import gmCfg
19 from Gnumed.pycommon import gmTools
20 from Gnumed.pycommon import gmDispatcher
21 from Gnumed.pycommon import gmMatchProvider
22 from Gnumed.pycommon import gmDateTime
23 from Gnumed.pycommon import gmNetworkTools
24
25 from Gnumed.business import gmPerson
26 from Gnumed.business import gmStaff
27 from Gnumed.business import gmSurgery
28 from Gnumed.business import gmProviderInbox
29
30 from Gnumed.wxpython import gmGuiHelpers
31 from Gnumed.wxpython import gmListWidgets
32 from Gnumed.wxpython import gmPlugin
33 from Gnumed.wxpython import gmRegetMixin
34 from Gnumed.wxpython import gmPhraseWheel
35 from Gnumed.wxpython import gmEditArea
36 from Gnumed.wxpython import gmAuthWidgets
37 from Gnumed.wxpython import gmPatSearchWidgets
38 from Gnumed.wxpython import gmVaccWidgets
39 from Gnumed.wxpython import gmCfgWidgets
40 from Gnumed.wxpython import gmDataPackWidgets
41
42
43 _log = logging.getLogger('gm.ui')
44
45 _indicator = {
46 -1: '',
47 0: '',
48 1: '*!!*'
49 }
50
87
100
101
102
104
105 if parent is None:
106 parent = wx.GetApp().GetTopWindow()
107
108 conn = gmAuthWidgets.get_dbowner_connection(procedure = _('showing audit trail'))
109 if conn is None:
110 return False
111
112
113 def refresh(lctrl):
114 cmd = u'SELECT * FROM audit.v_audit_trail ORDER BY audit_when_ts'
115 rows, idx = gmPG2.run_ro_queries(link_obj = conn, queries = [{'cmd': cmd}], get_col_idx = False)
116 lctrl.set_string_items (
117 [ [
118 r['event_when'],
119 r['event_by'],
120 u'%s %s %s' % (
121 gmTools.coalesce(r['row_version_before'], gmTools.u_diameter),
122 gmTools.u_right_arrow,
123 gmTools.coalesce(r['row_version_after'], gmTools.u_diameter)
124 ),
125 r['event_table'],
126 r['event'],
127 r['pk_audit']
128 ] for r in rows ]
129 )
130
131 gmListWidgets.get_choices_from_list (
132 parent = parent,
133 msg = u'',
134 caption = _('GNUmed database audit log ...'),
135 columns = [ _('When'), _('Who'), _('Revisions'), _('Table'), _('Event'), '#' ],
136 single_selection = True,
137 refresh_callback = refresh
138 )
139
140
141
142
187
188 def edit(workplace=None):
189
190 dbcfg = gmCfg.cCfgSQL()
191
192 if workplace is None:
193 dlg = wx.TextEntryDialog (
194 parent = parent,
195 message = _('Enter a descriptive name for the new workplace:'),
196 caption = _('Configuring GNUmed workplaces ...'),
197 defaultValue = u'',
198 style = wx.OK | wx.CENTRE
199 )
200 dlg.ShowModal()
201 workplace = dlg.GetValue().strip()
202 if workplace == u'':
203 gmGuiHelpers.gm_show_error(_('Cannot save a new workplace without a name.'), _('Configuring GNUmed workplaces ...'))
204 return False
205 curr_plugins = []
206 else:
207 curr_plugins = gmTools.coalesce(dbcfg.get2 (
208 option = u'horstspace.notebook.plugin_load_order',
209 workplace = workplace,
210 bias = 'workplace'
211 ), []
212 )
213
214 msg = _(
215 'Pick the plugin(s) to be loaded the next time the client is restarted under the workplace:\n'
216 '\n'
217 ' [%s]\n'
218 ) % workplace
219
220 picker = gmListWidgets.cItemPickerDlg (
221 parent,
222 -1,
223 title = _('Configuring workplace plugins ...'),
224 msg = msg
225 )
226 picker.set_columns(['Available plugins'], ['Active plugins'])
227 available_plugins = gmPlugin.get_installed_plugins(plugin_dir = 'gui')
228 picker.set_choices(available_plugins)
229 picker.set_picks(picks = curr_plugins[:])
230 btn_pressed = picker.ShowModal()
231 if btn_pressed != wx.ID_OK:
232 picker.Destroy()
233 return False
234
235 new_plugins = picker.get_picks()
236 picker.Destroy()
237 if new_plugins == curr_plugins:
238 return True
239
240 if new_plugins is None:
241 return True
242
243 dbcfg.set (
244 option = u'horstspace.notebook.plugin_load_order',
245 value = new_plugins,
246 workplace = workplace
247 )
248
249 return True
250
251 def edit_old(workplace=None):
252
253 available_plugins = gmPlugin.get_installed_plugins(plugin_dir='gui')
254
255 dbcfg = gmCfg.cCfgSQL()
256
257 if workplace is None:
258 dlg = wx.TextEntryDialog (
259 parent = parent,
260 message = _('Enter a descriptive name for the new workplace:'),
261 caption = _('Configuring GNUmed workplaces ...'),
262 defaultValue = u'',
263 style = wx.OK | wx.CENTRE
264 )
265 dlg.ShowModal()
266 workplace = dlg.GetValue().strip()
267 if workplace == u'':
268 gmGuiHelpers.gm_show_error(_('Cannot save a new workplace without a name.'), _('Configuring GNUmed workplaces ...'))
269 return False
270 curr_plugins = []
271 choices = available_plugins
272 else:
273 curr_plugins = gmTools.coalesce(dbcfg.get2 (
274 option = u'horstspace.notebook.plugin_load_order',
275 workplace = workplace,
276 bias = 'workplace'
277 ), []
278 )
279 choices = curr_plugins[:]
280 for p in available_plugins:
281 if p not in choices:
282 choices.append(p)
283
284 sels = range(len(curr_plugins))
285 new_plugins = gmListWidgets.get_choices_from_list (
286 parent = parent,
287 msg = _(
288 '\n'
289 'Select the plugin(s) to be loaded the next time\n'
290 'the client is restarted under the workplace:\n'
291 '\n'
292 ' [%s]'
293 '\n'
294 ) % workplace,
295 caption = _('Configuring GNUmed workplaces ...'),
296 choices = choices,
297 selections = sels,
298 columns = [_('Plugins')],
299 single_selection = False
300 )
301
302 if new_plugins == curr_plugins:
303 return True
304
305 if new_plugins is None:
306 return True
307
308 dbcfg.set (
309 option = u'horstspace.notebook.plugin_load_order',
310 value = new_plugins,
311 workplace = workplace
312 )
313
314 return True
315
316 def clone(workplace=None):
317 if workplace is None:
318 return False
319
320 new_name = wx.GetTextFromUser (
321 message = _('Enter a name for the new workplace !'),
322 caption = _('Cloning workplace'),
323 default_value = u'%s-2' % workplace,
324 parent = parent
325 ).strip()
326
327 if new_name == u'':
328 return False
329
330 dbcfg = gmCfg.cCfgSQL()
331 opt = u'horstspace.notebook.plugin_load_order'
332
333 plugins = dbcfg.get2 (
334 option = opt,
335 workplace = workplace,
336 bias = 'workplace'
337 )
338
339 dbcfg.set (
340 option = opt,
341 value = plugins,
342 workplace = new_name
343 )
344
345
346
347 return True
348
349 def refresh(lctrl):
350 workplaces = gmSurgery.gmCurrentPractice().workplaces
351 curr_workplace = gmSurgery.gmCurrentPractice().active_workplace
352 try:
353 sels = [workplaces.index(curr_workplace)]
354 except ValueError:
355 sels = []
356
357 lctrl.set_string_items(workplaces)
358 lctrl.set_selections(selections = sels)
359
360 gmListWidgets.get_choices_from_list (
361 parent = parent,
362 msg = _(
363 '\nSelect the workplace to configure below.\n'
364 '\n'
365 'The currently active workplace is preselected.\n'
366 ),
367 caption = _('Configuring GNUmed workplaces ...'),
368 columns = [_('Workplace')],
369 single_selection = True,
370 refresh_callback = refresh,
371 edit_callback = edit,
372 new_callback = edit,
373 delete_callback = delete,
374 left_extra_button = (_('Clone'), _('Clone the selected workplace'), clone)
375 )
376
378
380
381 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
382
383 query = u"""
384 SELECT DISTINCT ON (label)
385 pk_type,
386 (l10n_type || ' (' || l10n_category || ')')
387 AS label
388 FROM
389 dem.v_inbox_item_type
390 WHERE
391 l10n_type %(fragment_condition)s
392 OR
393 type %(fragment_condition)s
394 OR
395 l10n_category %(fragment_condition)s
396 OR
397 category %(fragment_condition)s
398 ORDER BY label
399 LIMIT 50"""
400
401 mp = gmMatchProvider.cMatchProvider_SQL2(queries = query)
402 mp.setThresholds(1, 2, 4)
403 self.matcher = mp
404 self.SetToolTipString(_('Select a message type.'))
405
418
420 wx.CallAfter(__display_clinical_reminders)
421
422 gmDispatcher.connect(signal = u'post_patient_selection', receiver = _display_clinical_reminders)
423
425 pat = gmPerson.gmCurrentPatient()
426 if not pat.connected:
427 return
428 for msg in pat.due_messages:
429 if msg['expiry_date'] is None:
430 exp = u''
431 else:
432 exp = _(' - expires %s') % gmDateTime.pydt_strftime (
433 msg['expiry_date'],
434 '%Y %b %d',
435 accuracy = gmDateTime.acc_days
436 )
437 txt = _(
438 'Due for %s (since %s%s):\n'
439 '%s'
440 '%s'
441 '\n'
442 'Patient: %s\n'
443 'Reminder by: %s'
444 ) % (
445 gmDateTime.format_interval_medically(msg['interval_due']),
446 gmDateTime.pydt_strftime(msg['due_date'], '%Y %b %d', accuracy = gmDateTime.acc_days),
447 exp,
448 gmTools.coalesce(msg['comment'], u'', u'\n%s\n'),
449 gmTools.coalesce(msg['data'], u'', u'\n%s\n'),
450 pat['description_gender'],
451 msg['modified_by']
452 )
453 gmGuiHelpers.gm_show_warning (
454 aTitle = _('Clinical reminder'),
455 aMessage = txt
456 )
457 for hint in pat.dynamic_hints:
458 txt = u'%s\n\n%s\n\n %s' % (
459 hint['title'],
460 gmTools.wrap(hint['hint'], width = 50, initial_indent = u' ', subsequent_indent = u' '),
461 hint['source']
462 )
463 dlg = gmGuiHelpers.c2ButtonQuestionDlg (
464 None,
465 -1,
466 caption = _('Clinical hint'),
467 question = txt,
468 button_defs = [
469 {'label': _('OK'), 'tooltip': _('OK'), 'default': True},
470 {'label': _('More info'), 'tooltip': _('Go to [%s]') % hint['url']}
471 ]
472 )
473 button = dlg.ShowModal()
474 dlg.Destroy()
475 if button == wx.ID_NO:
476 gmNetworkTools.open_url_in_browser(hint['url'], autoraise = False)
477
478 return
479
480 from Gnumed.wxGladeWidgets import wxgInboxMessageEAPnl
481
482 -class cInboxMessageEAPnl(wxgInboxMessageEAPnl.wxgInboxMessageEAPnl, gmEditArea.cGenericEditAreaMixin):
483
503
509
510
511
576
578
579 pat_id = None
580 if self._CHBOX_active_patient.GetValue() is True:
581 pat_id = gmPerson.gmCurrentPatient().ID
582 else:
583 if self._PRW_patient.person is not None:
584 pat_id = self._PRW_patient.person.ID
585
586 receiver = None
587 if self._CHBOX_send_to_me.IsChecked():
588 receiver = gmStaff.gmCurrentProvider()['pk_staff']
589 else:
590 if self._PRW_receiver.GetData() is not None:
591 receiver = self._PRW_receiver.GetData()
592
593 msg = gmProviderInbox.create_inbox_message (
594 patient = pat_id,
595 staff = receiver,
596 message_type = self._PRW_type.GetData(can_create = True),
597 subject = self._TCTRL_subject.GetValue().strip()
598 )
599
600 msg['data'] = self._TCTRL_message.GetValue().strip()
601
602 if self._PRW_due.is_valid_timestamp():
603 msg['due_date'] = self._PRW_due.date
604
605 if self._PRW_expiry.is_valid_timestamp():
606 msg['expiry_date'] = self._PRW_expiry.date
607
608 if self._RBTN_normal.GetValue() is True:
609 msg['importance'] = 0
610 elif self._RBTN_high.GetValue() is True:
611 msg['importance'] = 1
612 else:
613 msg['importance'] = -1
614
615 msg.save()
616 self.data = msg
617 return True
618
654
680
682 self._refresh_as_new()
683
737
738
739
741 if self._CHBOX_active_patient.IsChecked():
742 self._PRW_patient.Enable(False)
743 self._PRW_patient.person = None
744 else:
745 self._PRW_patient.Enable(True)
746
748 if self._CHBOX_send_to_me.IsChecked():
749 self._PRW_receiver.Enable(False)
750 self._PRW_receiver.SetData(data = gmStaff.gmCurrentProvider()['pk_staff'])
751 else:
752 self._PRW_receiver.Enable(True)
753 self._PRW_receiver.SetText(value = u'', data = None)
754
770
771
790
791 return gmListWidgets.get_choices_from_list (
792 parent = parent,
793 msg = None,
794 caption = _('Reminders for the current patient'),
795 columns = [ _('Status'), _('Subject'), '#' ],
796 single_selection = False,
797 can_return_empty = True,
798 ignore_OK_button = False,
799 refresh_callback = refresh
800
801
802
803
804
805
806 )
807
808
809 from Gnumed.wxGladeWidgets import wxgProviderInboxPnl
810
811 -class cProviderInboxPnl(wxgProviderInboxPnl.wxgProviderInboxPnl, gmRegetMixin.cRegetOnPaintMixin):
812
813 _item_handlers = {}
814
815
831
832
833
837
839 _log.debug('_populate_with_data() (after _schedule_data_reget ?)')
840 self.__populate_inbox()
841 return True
842
843
844
846 _log.debug('called by notebook plugin API, skipping inbox loading')
847
848 return True
849
850
851
853 gmDispatcher.connect(signal = u'message_inbox_generic_mod_db', receiver = self._on_message_inbox_generic_mod_db)
854 gmDispatcher.connect(signal = u'message_inbox_mod_db', receiver = self._on_message_inbox_mod_db)
855
856 gmDispatcher.connect(signal = u'reviewed_test_results_mod_db', receiver = self._on_results_mod_db)
857 gmDispatcher.connect(signal = u'identity_mod_db', receiver = self._on_identity_mod_db)
858 gmDispatcher.connect(signal = u'doc_mod_db', receiver = self._on_doc_mod_db)
859 gmDispatcher.connect(signal = u'doc_obj_review_mod_db', receiver = self._on_doc_obj_review_mod_db)
860 gmDispatcher.connect(signal = u'post_patient_selection', receiver = self._on_post_patient_selection)
861
863 self._LCTRL_provider_inbox.set_columns([u'', _('Sent'), _('Category'), _('Type'), _('Message')])
864
865 msg = _('\n Inbox of %(title)s %(lname)s.\n') % {
866 'title': gmTools.coalesce (
867 self.provider['title'],
868 gmPerson.map_gender2salutation(self.provider['gender'])
869 ),
870 'lname': self.provider['lastnames']
871 }
872
873 self._LCTRL_provider_inbox.item_tooltip_callback = self._get_msg_tooltip
874 self._LCTRL_provider_inbox.debug = 'provider inbox list'
875
876 self._msg_welcome.SetLabel(msg)
877
878 if gmPerson.gmCurrentPatient().connected:
879 self._RBTN_active_patient.Enable()
880
882 _log.debug('populating provider inbox')
883
884 self.__msgs = self.provider.inbox.messages
885 _log.debug('total # of inbox msgs for current provider: %s', len(self.__msgs))
886
887 if self.filter_mode == 'active':
888 _log.debug('inbox set to show msgs for active patient only')
889 if gmPerson.gmCurrentPatient().connected:
890 curr_pat_id = gmPerson.gmCurrentPatient().ID
891 _log.debug('filtering msgs against active patient: %s', curr_pat_id)
892 self.__msgs = [ m for m in self.__msgs if m['pk_patient'] == curr_pat_id ]
893 else:
894 _log.debug('no active patient, so not showing any inbox msgs')
895 self.__msgs = []
896 else:
897 _log.debug('inbox set to show all messages')
898
899 _log.debug('# of inbox msgs to actually show: %s', len(self.__msgs))
900
901 items = [
902 [
903 _indicator[m['importance']],
904 m['received_when'].strftime('%Y-%m-%d'),
905 m['l10n_category'],
906 m['l10n_type'],
907 m['comment']
908 ] for m in self.__msgs
909 ]
910 _log.debug('# of list items created from msgs: %s', len(items))
911 self._LCTRL_provider_inbox.set_string_items(items = items)
912 self._LCTRL_provider_inbox.set_data(data = self.__msgs)
913 self._LCTRL_provider_inbox.set_column_widths()
914 self._TXT_inbox_item_comment.SetValue(u'')
915
916
917
919 _log.debug('reviewed_test_results_mod_db')
920 wx.CallAfter(self.__on_message_inbox_mod_db)
921
923 _log.debug('identity_mod_db')
924 wx.CallAfter(self.__on_message_inbox_mod_db)
925
927 _log.debug('doc_obj_review_mod_db')
928 wx.CallAfter(self.__on_message_inbox_mod_db)
929
931 _log.debug('doc_mod_db')
932 wx.CallAfter(self.__on_message_inbox_mod_db)
933
935 _log.debug('message_inbox_generic_mod_db')
936 wx.CallAfter(self.__on_message_inbox_mod_db)
937
939 _log.debug('message_inbox_mod_db')
940 wx.CallAfter(self.__on_message_inbox_mod_db)
941
943 self._schedule_data_reget()
944 gmDispatcher.send(signal = u'request_user_attention', msg = _('Please check your GNUmed Inbox !'))
945
947 _log.debug('post_patient_selection')
948 wx.CallAfter(self.__on_post_patient_selection)
949
951 self._RBTN_active_patient.Enable()
952 self._schedule_data_reget()
953
955
956 try:
957 msg = self._LCTRL_provider_inbox.get_selected_item_data(only_one = True)
958 except IndexError:
959 _log.exception('problem with provider inbox item data access')
960 gmGuiHelpers.gm_show_error (
961 aTitle = _('handling provider inbox item'),
962 aMessage = _('There was a problem accessing the message data.')
963 )
964 _log.debug('effecting inbox reload')
965 wx.CallAfter(self.__populate_inbox)
966 return False
967
968 if msg is None:
969 return
970
971 handler_key = '%s.%s' % (msg['category'], msg['type'])
972 try:
973 handle_item = cProviderInboxPnl._item_handlers[handler_key]
974 except KeyError:
975 if msg['pk_patient'] is None:
976 gmGuiHelpers.gm_show_warning (
977 _('No double-click action pre-programmed into\n'
978 'GNUmed for message category and type:\n'
979 '\n'
980 ' [%s]\n'
981 ) % handler_key,
982 _('handling provider inbox item')
983 )
984 return False
985 handle_item = self._goto_patient
986
987 if not handle_item(pk_context = msg['pk_context'], pk_patient = msg['pk_patient']):
988 _log.error('item handler returned <False>')
989 _log.error('handler key: [%s]', handler_key)
990 _log.error('message: %s', str(msg))
991 return False
992
993 return True
994
997
999 msg = self._LCTRL_provider_inbox.get_selected_item_data(only_one = True)
1000 if msg is None:
1001 return
1002
1003 if msg['data'] is None:
1004 tmp = _('Message: %s') % msg['comment']
1005 else:
1006 tmp = _('Message: %s\nData: %s') % (msg['comment'], msg['data'])
1007
1008 self._TXT_inbox_item_comment.SetValue(tmp)
1009
1011 tmp = self._LCTRL_provider_inbox.get_selected_item_data(only_one = True)
1012 if tmp is None:
1013 return
1014 self.__focussed_msg = tmp
1015
1016
1017 menu = wx.Menu(title = _('Inbox Message Actions:'))
1018
1019 if self.__focussed_msg['pk_patient'] is not None:
1020 ID = wx.NewId()
1021 menu.AppendItem(wx.MenuItem(menu, ID, _('Activate patient')))
1022 wx.EVT_MENU(menu, ID, self._on_goto_patient)
1023
1024 if not self.__focussed_msg['is_virtual']:
1025
1026 ID = wx.NewId()
1027 menu.AppendItem(wx.MenuItem(menu, ID, _('Delete')))
1028 wx.EVT_MENU(menu, ID, self._on_delete_focussed_msg)
1029
1030 ID = wx.NewId()
1031 menu.AppendItem(wx.MenuItem(menu, ID, _('Edit')))
1032 wx.EVT_MENU(menu, ID, self._on_edit_focussed_msg)
1033
1034
1035
1036
1037
1038
1039
1040
1041 self.PopupMenu(menu, wx.DefaultPosition)
1042 menu.Destroy()
1043
1049
1055
1058
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1100 return self._goto_patient(pk_patient = self.__focussed_msg['pk_patient'])
1101
1103 if self.__focussed_msg['is_virtual']:
1104 gmDispatcher.send(signal = 'statustext', msg = _('You must deal with the reason for this message to remove it from your inbox.'), beep = True)
1105 return False
1106
1107 if not self.provider.inbox.delete_message(self.__focussed_msg['pk_inbox_message']):
1108 gmDispatcher.send(signal='statustext', msg=_('Problem removing message from Inbox.'))
1109 return False
1110 return True
1111
1113 if self.__focussed_msg['is_virtual']:
1114 gmDispatcher.send(signal = 'statustext', msg = _('This message cannot be edited because it is virtual.'))
1115 return False
1116 edit_inbox_message(parent = self, message = self.__focussed_msg, single_entry = True)
1117 return True
1118
1120 if self.__focussed_msg['pk_staff'] is None:
1121 gmDispatcher.send(signal = 'statustext', msg = _('This message is already visible to all providers.'))
1122 return False
1123 print "now distributing"
1124 return True
1125
1127
1128 wx.BeginBusyCursor()
1129
1130 msg = _('There is a message about patient [%s].\n\n'
1131 'However, I cannot find that\n'
1132 'patient in the GNUmed database.'
1133 ) % pk_patient
1134
1135 try:
1136 pat = gmPerson.cIdentity(aPK_obj = pk_patient)
1137 except gmExceptions.ConstructorError:
1138 wx.EndBusyCursor()
1139 _log.exception('patient [%s] not found', pk_patient)
1140 gmGuiHelpers.gm_show_error(msg, _('handling provider inbox item'))
1141 return False
1142 except:
1143 wx.EndBusyCursor()
1144 raise
1145
1146 success = gmPatSearchWidgets.set_active_patient(patient = pat)
1147
1148 wx.EndBusyCursor()
1149
1150 if not success:
1151 gmGuiHelpers.gm_show_error(msg, _('handling provider inbox item'))
1152 return False
1153
1154 return True
1155
1183
1185
1186 msg = _('Supposedly there are unreviewed results\n'
1187 'for patient [%s]. However, I cannot find\n'
1188 'that patient in the GNUmed database.'
1189 ) % pk_patient
1190
1191 wx.BeginBusyCursor()
1192
1193 try:
1194 pat = gmPerson.cIdentity(aPK_obj = pk_patient)
1195 except gmExceptions.ConstructorError:
1196 wx.EndBusyCursor()
1197 _log.exception('patient [%s] not found', pk_patient)
1198 gmGuiHelpers.gm_show_error(msg, _('handling provider inbox item'))
1199 return False
1200
1201 success = gmPatSearchWidgets.set_active_patient(patient = pat)
1202
1203 wx.EndBusyCursor()
1204
1205 if not success:
1206 gmGuiHelpers.gm_show_error(msg, _('handling provider inbox item'))
1207 return False
1208
1209 wx.CallAfter(gmDispatcher.send, signal = 'display_widget', name = 'gmMeasurementsGridPlugin')
1210 return True
1211
1240
1242
1243 if parent is None:
1244 parent = wx.GetApp().GetTopWindow()
1245
1246 def get_tooltip(item):
1247 if item is None:
1248 return None
1249 return item.format()
1250
1251 def switch_activation(item):
1252 conn = gmAuthWidgets.get_dbowner_connection(procedure = _('Switching clinical hint activation'))
1253 if conn is None:
1254 return False
1255 item['is_active'] = not item['is_active']
1256 return item.save(conn = conn)
1257
1258 def manage_data_packs(item):
1259 gmDataPackWidgets.manage_data_packs(parent = parent)
1260 return True
1261
1262 def refresh(lctrl):
1263 hints = gmProviderInbox.get_dynamic_hints(order_by = u'is_active DESC, source, hint')
1264 items = [ [
1265 gmTools.bool2subst(h['is_active'], gmTools.u_checkmark_thin, u''),
1266 h['title'],
1267 h['source'][:30],
1268 h['hint'][:60],
1269 gmTools.coalesce(h['url'], u'')[:60],
1270 h['lang'],
1271 h['pk']
1272 ] for h in hints ]
1273 lctrl.set_string_items(items)
1274 lctrl.set_data(hints)
1275
1276 gmListWidgets.get_choices_from_list (
1277 parent = parent,
1278 msg = _('\nDynamic hints registered with GNUmed.\n'),
1279 caption = _('Showing dynamic hints.'),
1280 columns = [ _('Active'), _('Title'), _('Source'), _('Hint'), u'URL', _('Language'), u'#' ],
1281 single_selection = True,
1282 refresh_callback = refresh,
1283 left_extra_button = (
1284 _('(De)-Activate'),
1285 _('Switch activation of the selected hint'),
1286 switch_activation
1287 ),
1288 right_extra_button = (
1289 _('Data packs'),
1290 _('Browse and install clinical hints data packs'),
1291 manage_data_packs
1292 ),
1293 list_tooltip_callback = get_tooltip
1294 )
1295
1296
1297 if __name__ == '__main__':
1298
1299 if len(sys.argv) < 2:
1300 sys.exit()
1301
1302 if sys.argv[1] != 'test':
1303 sys.exit()
1304
1305 gmI18N.activate_locale()
1306 gmI18N.install_domain(domain = 'gnumed')
1307
1311
1313 app = wx.PyWidgetTester(size = (800, 600))
1314 app.SetWidget(cProviderInboxPnl, -1)
1315 app.MainLoop()
1316
1318 app = wx.PyWidgetTester(size = (800, 600))
1319 app.SetWidget(cInboxMessageEAPnl, -1)
1320 app.MainLoop()
1321
1322
1323
1324
1325 test_msg_ea()
1326
1327
1328