1
2 """GNUmed keyword expansion widgets."""
3
4 __author__ = "Karsten Hilbert <Karsten.Hilbert@gmx.net>"
5 __license__ = "GPL v2 or later"
6
7 import logging
8 import sys
9 import re as regex
10
11
12 import wx
13
14
15 if __name__ == '__main__':
16 sys.path.insert(0, '../../')
17 from Gnumed.pycommon import gmDispatcher
18 from Gnumed.pycommon import gmPG2
19 from Gnumed.pycommon import gmTools
20 from Gnumed.business import gmKeywordExpansion
21 from Gnumed.wxpython import gmEditArea
22 from Gnumed.wxpython import gmListWidgets
23
24
25 _log = logging.getLogger('gm.ui')
26
27 _text_expansion_fillin_regex = r'\$<.*>\$'
28
29
30 from Gnumed.wxGladeWidgets import wxgTextExpansionEditAreaPnl
31
32 -class cTextExpansionEditAreaPnl(wxgTextExpansionEditAreaPnl.wxgTextExpansionEditAreaPnl, gmEditArea.cGenericEditAreaMixin):
33
34 - def __init__(self, *args, **kwds):
35
36 try:
37 data = kwds['keyword']
38 del kwds['keyword']
39 except KeyError:
40 data = None
41
42 wxgTextExpansionEditAreaPnl.wxgTextExpansionEditAreaPnl.__init__(self, *args, **kwds)
43 gmEditArea.cGenericEditAreaMixin.__init__(self)
44
45 self.mode = 'new'
46 self.data = data
47 if data is not None:
48 self.mode = 'edit'
49
50
51 self.__register_interests()
52
53 - def __init_ui(self, keyword=None):
54
55 if keyword is not None:
56 self.data = keyword
57
58
59
61 validity = True
62
63 if self._TCTRL_keyword.GetValue().strip() == u'':
64 validity = False
65 self.display_tctrl_as_valid(tctrl = self._TCTRL_keyword, valid = False)
66 gmDispatcher.send(signal = 'statustext', msg = _('Cannot save keyword expansion without keyword.'), beep = True)
67 else:
68 self.display_tctrl_as_valid(tctrl = self._TCTRL_keyword, valid = True)
69
70 if self._TCTRL_expansion.GetValue().strip() == u'':
71 validity = False
72 self.display_tctrl_as_valid(tctrl = self._TCTRL_expansion, valid = False)
73 gmDispatcher.send(signal = 'statustext', msg = _('Cannot save keyword expansion without expansion text.'), beep = True)
74 else:
75 self.display_tctrl_as_valid(tctrl = self._TCTRL_expansion, valid = True)
76
77 return validity
78
79 - def _save_as_new(self):
80 kwd = self._TCTRL_keyword.GetValue().strip()
81 saved = gmKeywordExpansion.add_text_expansion (
82 keyword = kwd,
83 expansion = self._TCTRL_expansion.GetValue(),
84 public = self._RBTN_public.GetValue()
85 )
86 if not saved:
87 return False
88
89 self.data = kwd
90 return True
91
93 kwd = self._TCTRL_keyword.GetValue().strip()
94 gmKeywordExpansion.edit_text_expansion (
95 keyword = kwd,
96 expansion = self._TCTRL_expansion.GetValue()
97 )
98 self.data = kwd
99 return True
100
101 - def _refresh_as_new(self):
102 self._TCTRL_keyword.SetValue(u'')
103 self._TCTRL_keyword.Enable(True)
104 self._TCTRL_expansion.SetValue(u'')
105 self._TCTRL_expansion.Enable(False)
106 self._RBTN_public.Enable(True)
107 self._RBTN_private.Enable(True)
108 self._RBTN_public.SetValue(1)
109
110 self._TCTRL_keyword.SetFocus()
111
113 self._TCTRL_keyword.SetValue(u'%s%s' % (self.data, _(u'___copy')))
114 self._TCTRL_keyword.Enable(True)
115 expansion = gmKeywordExpansion.expand_keyword(keyword = self.data)
116 self._TCTRL_expansion.SetValue(gmTools.coalesce(expansion, u''))
117 self._TCTRL_expansion.Enable(True)
118 self._RBTN_public.Enable(True)
119 self._RBTN_private.Enable(True)
120 self._RBTN_public.SetValue(1)
121
122 self._TCTRL_keyword.SetFocus()
123
125 self._TCTRL_keyword.SetValue(self.data)
126 self._TCTRL_keyword.Enable(False)
127 expansion = gmKeywordExpansion.expand_keyword(keyword = self.data)
128 self._TCTRL_expansion.SetValue(gmTools.coalesce(expansion, u''))
129 self._TCTRL_expansion.Enable(True)
130 self._RBTN_public.Enable(False)
131 self._RBTN_private.Enable(False)
132
133 self._TCTRL_expansion.SetFocus()
134
135
136
138 self._TCTRL_keyword.Bind(wx.EVT_TEXT, self._on_keyword_modified)
139
140 - def _on_keyword_modified(self, evt):
141 if self._TCTRL_keyword.GetValue().strip() == u'':
142 self._TCTRL_expansion.Enable(False)
143 else:
144 self._TCTRL_expansion.Enable(True)
145
155
156 def edit(keyword=None):
157 ea = cTextExpansionEditAreaPnl(parent, -1, keyword = keyword)
158 dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea)
159 dlg.SetTitle (
160 gmTools.coalesce(keyword, _('Adding keyword expansion'), _('Editing keyword expansion "%s"'))
161 )
162 if dlg.ShowModal() == wx.ID_OK:
163 return True
164
165 return False
166
167 def refresh(lctrl=None):
168 expansions = gmKeywordExpansion.get_keyword_expansions(order_by = u'is_textual DESC, keyword, public_expansion')
169 items = [[
170 e['keyword'],
171 gmTools.bool2subst(e['is_textual'], _('text'), _('data')),
172 gmTools.bool2subst(e['public_expansion'], _('public'), _('private'))
173 ] for e in expansions
174 ]
175 lctrl.set_string_items(items)
176 lctrl.set_data(expansions)
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191 gmListWidgets.get_choices_from_list (
192 parent = parent,
193 msg = _('\nSelect the keyword you want to edit !\n'),
194 caption = _('Editing keyword-based expansions ...'),
195 columns = [_('Keyword'), _('Type'), _('Scope')],
196 single_selection = True,
197 edit_callback = edit,
198 new_callback = edit,
199 delete_callback = delete,
200 refresh_callback = refresh
201 )
202
203 from Gnumed.wxGladeWidgets import wxgTextExpansionFillInDlg
204
205 -class cTextExpansionFillInDlg(wxgTextExpansionFillInDlg.wxgTextExpansionFillInDlg):
206
207 - def __init__(self, *args, **kwds):
208 wxgTextExpansionFillInDlg.wxgTextExpansionFillInDlg.__init__(self, *args, **kwds)
209
210 self.__expansion = None
211 self.__init_ui()
212
213 - def __init_ui(self):
214 self._LBL_top_part.SetLabel(u'')
215 self._LBL_left_part.SetLabel(u'')
216 self._LBL_left_part.Hide()
217 self._TCTRL_fillin.SetValue(u'')
218 self._TCTRL_fillin.SetBackgroundColour('yellow')
219 self._TCTRL_fillin.Disable()
220 self._TCTRL_fillin.Hide()
221 self._LBL_right_part.SetLabel(u'')
222 self._LBL_right_part.Hide()
223 self._LBL_bottom_part.SetLabel(u'')
224 self._BTN_OK.Disable()
225 self._BTN_forward.Disable()
226 self._BTN_cancel.SetFocus()
227 self._LBL_hint.SetLabel(u'')
228
230 if self.__expansion is None:
231 return
232
233 if self.__new_expansion:
234 self.__filled_in = self.__expansion
235 self.__new_expansion = False
236 else:
237 self.__filled_in = (
238 self._LBL_top_part.GetLabel() +
239 self.__left_splitter +
240 self._LBL_left_part.GetLabel() +
241 self._TCTRL_fillin.GetValue().strip() +
242 self._LBL_right_part.GetLabel() +
243 self.__right_splitter +
244 self._LBL_bottom_part.GetLabel()
245 )
246
247
248 if regex.search(_text_expansion_fillin_regex, self.__filled_in) is None:
249
250 self._LBL_top_part.SetLabel(self.__filled_in)
251 self._LBL_left_part.SetLabel(u'')
252 self._LBL_left_part.Hide()
253 self._TCTRL_fillin.SetValue(u'')
254 self._TCTRL_fillin.Disable()
255 self._TCTRL_fillin.Hide()
256 self._LBL_right_part.SetLabel(u'')
257 self._LBL_right_part.Hide()
258 self._LBL_bottom_part.SetLabel(u'')
259 self._BTN_OK.Enable()
260 self._BTN_forward.Disable()
261 self._BTN_OK.SetDefault()
262 return
263
264
265 top, fillin, bottom = regex.split(r'(' + _text_expansion_fillin_regex + r')', self.__filled_in, maxsplit = 1)
266 top_parts = top.rsplit(u'\n', 1)
267 top_part = top_parts[0]
268 if len(top_parts) == 1:
269 self.__left_splitter = u''
270 left_part = u''
271 else:
272 self.__left_splitter = u'\n'
273 left_part = top_parts[1]
274 bottom_parts = bottom.split(u'\n', 1)
275 if len(bottom_parts) == 1:
276 parts = bottom_parts[0].split(u' ', 1)
277 right_part = parts[0]
278 if len(parts) == 1:
279 self.__right_splitter = u''
280 bottom_part = u''
281 else:
282 self.__right_splitter = u' '
283 bottom_part = parts[1]
284 else:
285 self.__right_splitter = u'\n'
286 right_part = bottom_parts[0]
287 bottom_part = bottom_parts[1]
288 hint = fillin.strip('$').strip('<').strip('>').strip()
289 self._LBL_top_part.SetLabel(top_part)
290 self._LBL_left_part.SetLabel(left_part)
291 self._LBL_left_part.Show()
292 self._TCTRL_fillin.Enable()
293 self._TCTRL_fillin.SetValue(u'')
294 self._TCTRL_fillin.Show()
295 self._LBL_right_part.SetLabel(right_part)
296 self._LBL_right_part.Show()
297 self._LBL_bottom_part.SetLabel(bottom_part)
298 self._BTN_OK.Disable()
299 self._BTN_forward.Enable()
300 self._BTN_forward.SetDefault()
301 self._LBL_hint.SetLabel(hint)
302 self._TCTRL_fillin.SetFocus()
303
304 self.Layout()
305 self.Fit()
306
307
308
309 - def _get_expansion(self):
310 return self.__expansion
311
312 - def _set_expansion(self, expansion):
313 self.__expansion = expansion
314 self.__new_expansion = True
315 self.__goto_next_fillin()
316 return
317
318 expansion = property(_get_expansion, _set_expansion)
319
320 - def _get_filled_in(self):
321 return self.__filled_in
322
323 filled_in_expansion = property(_get_filled_in, lambda x:x)
324
325 - def _set_keyword(self, keyword):
326 self.SetTitle(_('Expanding <%s>') % keyword)
327
328 keyword = property(lambda x:x, _set_keyword)
329
330
331
333 self.__goto_next_fillin()
334
392
393
394
395
396 if __name__ == '__main__':
397
398 if len(sys.argv) < 2:
399 sys.exit()
400
401 if sys.argv[1] != 'test':
402 sys.exit()
403
404 from Gnumed.pycommon import gmI18N
405 gmI18N.activate_locale()
406 gmI18N.install_domain(domain = 'gnumed')
407
408
410 expansion = u"""HEMORR²HAGES: Blutungsrisiko unter OAK
411 --------------------------------------
412 Am Heart J. 2006 Mar;151(3):713-9.
413
414 $<1 oder 0 eingeben>$ H epatische oder Nierenerkrankung
415 $<1 oder 0 eingeben>$ E thanolabusus
416 $<1 oder 0 eingeben>$ M alignom
417 $<1 oder 0 eingeben>$ O ld patient (> 75 Jahre)
418 $<1 oder 0 eingeben>$ R eduzierte Thrombozytenzahl/-funktion
419 $<2 oder 0 eingeben>$ R²ekurrente (frühere) große Blutung
420 $<1 oder 0 eingeben>$ H ypertonie (unkontrolliert)
421 $<1 oder 0 eingeben>$ A nämie
422 $<1 oder 0 eingeben>$ G enetische Faktoren
423 $<1 oder 0 eingeben>$ E xzessives Sturzrisiko
424 $<1 oder 0 eingeben>$ S Schlaganfall in der Anamnese
425 --------------------------------------
426 Summe Rate großer Blutungen
427 pro 100 Patientenjahre
428 0 1.9
429 1 2.5
430 2 5.3
431 3 8.4
432 4 10.4
433 >4 12.3
434
435 Bewertung: Summe = $<Summe ausrechnen und bewerten>$"""
436
437 app = wx.PyWidgetTester(size = (600, 600))
438 dlg = cTextExpansionFillInDlg(None, -1)
439 dlg.expansion = expansion
440 dlg.ShowModal()
441
442
443 test_fillin()
444