Package Gnumed :: Package wxpython :: Module gmTextExpansionWidgets
[frames] | no frames]

Source Code for Module Gnumed.wxpython.gmTextExpansionWidgets

  1  # -*- coding: utf8 -*- 
  2  """GNUmed text 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.wxpython import gmEditArea 
 21  from Gnumed.wxpython import gmListWidgets 
 22   
 23   
 24  _log = logging.getLogger('gm.ui') 
 25   
 26  _text_expansion_fillin_regex = r'\$<.*>\$' 
 27   
 28  #============================================================ 
 29  from Gnumed.wxGladeWidgets import wxgTextExpansionEditAreaPnl 
 30   
31 -class cTextExpansionEditAreaPnl(wxgTextExpansionEditAreaPnl.wxgTextExpansionEditAreaPnl, gmEditArea.cGenericEditAreaMixin):
32
33 - def __init__(self, *args, **kwds):
34 35 try: 36 data = kwds['keyword'] 37 del kwds['keyword'] 38 except KeyError: 39 data = None 40 41 wxgTextExpansionEditAreaPnl.wxgTextExpansionEditAreaPnl.__init__(self, *args, **kwds) 42 gmEditArea.cGenericEditAreaMixin.__init__(self) 43 44 self.mode = 'new' 45 self.data = data 46 if data is not None: 47 self.mode = 'edit' 48 49 #self.__init_ui() 50 self.__register_interests()
51 #--------------------------------------------------------
52 - def __init_ui(self, keyword=None):
53 54 if keyword is not None: 55 self.data = keyword
56 #---------------------------------------------------------------- 57 # generic Edit Area mixin API 58 #----------------------------------------------------------------
59 - def _valid_for_save(self):
60 validity = True 61 62 if self._TCTRL_keyword.GetValue().strip() == u'': 63 validity = False 64 self.display_tctrl_as_valid(tctrl = self._TCTRL_keyword, valid = False) 65 gmDispatcher.send(signal = 'statustext', msg = _('Cannot save text expansion without keyword.'), beep = True) 66 else: 67 self.display_tctrl_as_valid(tctrl = self._TCTRL_keyword, valid = True) 68 69 if self._TCTRL_expansion.GetValue().strip() == u'': 70 validity = False 71 self.display_tctrl_as_valid(tctrl = self._TCTRL_expansion, valid = False) 72 gmDispatcher.send(signal = 'statustext', msg = _('Cannot save text expansion without expansion text.'), beep = True) 73 else: 74 self.display_tctrl_as_valid(tctrl = self._TCTRL_expansion, valid = True) 75 76 return validity
77 #----------------------------------------------------------------
78 - def _save_as_new(self):
79 kwd = self._TCTRL_keyword.GetValue().strip() 80 saved = gmPG2.add_text_expansion ( 81 keyword = kwd, 82 expansion = self._TCTRL_expansion.GetValue(), 83 public = self._RBTN_public.GetValue() 84 ) 85 if not saved: 86 return False 87 88 self.data = kwd 89 return True
90 #----------------------------------------------------------------
91 - def _save_as_update(self):
92 kwd = self._TCTRL_keyword.GetValue().strip() 93 gmPG2.edit_text_expansion ( 94 keyword = kwd, 95 expansion = self._TCTRL_expansion.GetValue() 96 ) 97 self.data = kwd 98 return True
99 #----------------------------------------------------------------
100 - def _refresh_as_new(self):
101 self._TCTRL_keyword.SetValue(u'') 102 self._TCTRL_keyword.Enable(True) 103 self._TCTRL_expansion.SetValue(u'') 104 self._TCTRL_expansion.Enable(False) 105 self._RBTN_public.Enable(True) 106 self._RBTN_private.Enable(True) 107 self._RBTN_public.SetValue(1) 108 109 self._TCTRL_keyword.SetFocus()
110 #----------------------------------------------------------------
112 self._TCTRL_keyword.SetValue(u'%s%s' % (self.data, _(u'___copy'))) 113 self._TCTRL_keyword.Enable(True) 114 expansion = gmPG2.expand_keyword(keyword = self.data) 115 self._TCTRL_expansion.SetValue(gmTools.coalesce(expansion, u'')) 116 self._TCTRL_expansion.Enable(True) 117 self._RBTN_public.Enable(True) 118 self._RBTN_private.Enable(True) 119 self._RBTN_public.SetValue(1) 120 121 self._TCTRL_keyword.SetFocus()
122 #----------------------------------------------------------------
123 - def _refresh_from_existing(self):
124 self._TCTRL_keyword.SetValue(self.data) 125 self._TCTRL_keyword.Enable(False) 126 expansion = gmPG2.expand_keyword(keyword = self.data) 127 self._TCTRL_expansion.SetValue(gmTools.coalesce(expansion, u'')) 128 self._TCTRL_expansion.Enable(True) 129 self._RBTN_public.Enable(False) 130 self._RBTN_private.Enable(False) 131 132 self._TCTRL_expansion.SetFocus()
133 #---------------------------------------------------------------- 134 # event handling 135 #----------------------------------------------------------------
136 - def __register_interests(self):
137 self._TCTRL_keyword.Bind(wx.EVT_TEXT, self._on_keyword_modified)
138 #----------------------------------------------------------------
139 - def _on_keyword_modified(self, evt):
140 if self._TCTRL_keyword.GetValue().strip() == u'': 141 self._TCTRL_expansion.Enable(False) 142 else: 143 self._TCTRL_expansion.Enable(True)
144 #============================================================
145 -def configure_keyword_text_expansion(parent=None):
146 147 if parent is None: 148 parent = wx.GetApp().GetTopWindow() 149 150 #---------------------- 151 def delete(keyword=None): 152 gmPG2.delete_text_expansion(keyword = keyword) 153 return True
154 #---------------------- 155 def edit(keyword=None): 156 ea = cTextExpansionEditAreaPnl(parent, -1, keyword = keyword) 157 dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea) 158 dlg.SetTitle ( 159 gmTools.coalesce(keyword, _('Adding text expansion'), _('Editing text expansion "%s"')) 160 ) 161 if dlg.ShowModal() == wx.ID_OK: 162 return True 163 164 return False 165 #---------------------- 166 def refresh(lctrl=None): 167 kwds = [ [ 168 r[0], 169 gmTools.bool2subst(r[1], gmTools.u_checkmark_thick, u''), 170 gmTools.bool2subst(r[2], gmTools.u_checkmark_thick, u''), 171 r[3] 172 ] for r in gmPG2.get_text_expansion_keywords() 173 ] 174 data = [ r[0] for r in gmPG2.get_text_expansion_keywords() ] 175 lctrl.set_string_items(kwds) 176 lctrl.set_data(data) 177 #---------------------- 178 179 gmListWidgets.get_choices_from_list ( 180 parent = parent, 181 msg = _('\nSelect the keyword you want to edit !\n'), 182 caption = _('Editing keyword-based text expansions ...'), 183 columns = [_('Keyword'), _('Public'), _('Private'), _('Owner')], 184 single_selection = True, 185 edit_callback = edit, 186 new_callback = edit, 187 delete_callback = delete, 188 refresh_callback = refresh 189 ) 190 #============================================================ 191 from Gnumed.wxGladeWidgets import wxgTextExpansionFillInDlg 192
193 -class cTextExpansionFillInDlg(wxgTextExpansionFillInDlg.wxgTextExpansionFillInDlg):
194
195 - def __init__(self, *args, **kwds):
196 wxgTextExpansionFillInDlg.wxgTextExpansionFillInDlg.__init__(self, *args, **kwds) 197 198 self.__expansion = None 199 self.__init_ui()
200 #---------------------------------------------
201 - def __init_ui(self):
202 self._LBL_top_part.SetLabel(u'') 203 self._LBL_left_part.SetLabel(u'') 204 self._LBL_left_part.Hide() 205 self._TCTRL_fillin.SetValue(u'') 206 self._TCTRL_fillin.Disable() 207 self._TCTRL_fillin.Hide() 208 self._LBL_right_part.SetLabel(u'') 209 self._LBL_right_part.Hide() 210 self._LBL_bottom_part.SetLabel(u'') 211 self._BTN_OK.Disable() 212 self._BTN_forward.Disable() 213 self._BTN_cancel.SetFocus() 214 self._LBL_hint.SetLabel(u'')
215 #---------------------------------------------
216 - def __goto_next_fillin(self):
217 if self.__expansion is None: 218 return 219 220 if self.__new_expansion: 221 self.__filled_in = self.__expansion 222 self.__new_expansion = False 223 else: 224 self.__filled_in = ( 225 self._LBL_top_part.GetLabel() + 226 self.__left_splitter + 227 self._LBL_left_part.GetLabel() + 228 self._TCTRL_fillin.GetValue().strip() + 229 self._LBL_right_part.GetLabel() + 230 self.__right_splitter + 231 self._LBL_bottom_part.GetLabel() 232 ) 233 234 # anything to fill in ? 235 if regex.search(_text_expansion_fillin_regex, self.__filled_in) is None: 236 # no 237 self._LBL_top_part.SetLabel(self.__filled_in) 238 self._LBL_left_part.SetLabel(u'') 239 self._LBL_left_part.Hide() 240 self._TCTRL_fillin.SetValue(u'') 241 self._TCTRL_fillin.Disable() 242 self._TCTRL_fillin.Hide() 243 self._LBL_right_part.SetLabel(u'') 244 self._LBL_right_part.Hide() 245 self._LBL_bottom_part.SetLabel(u'') 246 self._BTN_OK.Enable() 247 self._BTN_forward.Disable() 248 self._BTN_OK.SetDefault() 249 return 250 251 # yes 252 top, fillin, bottom = regex.split(r'(' + _text_expansion_fillin_regex + r')', self.__filled_in, maxsplit = 1) 253 top_parts = top.rsplit(u'\n', 1) 254 top_part = top_parts[0] 255 if len(top_parts) == 1: 256 self.__left_splitter = u'' 257 left_part = u'' 258 else: 259 self.__left_splitter = u'\n' 260 left_part = top_parts[1] 261 bottom_parts = bottom.split(u'\n', 1) 262 if len(bottom_parts) == 1: 263 parts = bottom_parts[0].split(u' ', 1) 264 right_part = parts[0] 265 if len(parts) == 1: 266 self.__right_splitter = u'' 267 bottom_part = u'' 268 else: 269 self.__right_splitter = u' ' 270 bottom_part = parts[1] 271 else: 272 self.__right_splitter = u'\n' 273 right_part = bottom_parts[0] 274 bottom_part = bottom_parts[1] 275 hint = fillin.strip('$').strip('<').strip('>').strip() 276 self._LBL_top_part.SetLabel(top_part) 277 self._LBL_left_part.SetLabel(left_part) 278 self._LBL_left_part.Show() 279 self._TCTRL_fillin.Enable() 280 self._TCTRL_fillin.SetValue(u'') 281 self._TCTRL_fillin.Show() 282 self._LBL_right_part.SetLabel(right_part) 283 self._LBL_right_part.Show() 284 self._LBL_bottom_part.SetLabel(bottom_part) 285 self._BTN_OK.Disable() 286 self._BTN_forward.Enable() 287 self._BTN_forward.SetDefault() 288 self._LBL_hint.SetLabel(hint) 289 self._TCTRL_fillin.SetFocus() 290 291 self.Layout() 292 self.Fit()
293 #--------------------------------------------- 294 # properties 295 #---------------------------------------------
296 - def _get_expansion(self):
297 return self.__expansion
298
299 - def _set_expansion(self, expansion):
300 self.__expansion = expansion 301 self.__new_expansion = True 302 self.__goto_next_fillin() 303 return
304 305 expansion = property(_get_expansion, _set_expansion) 306 #---------------------------------------------
307 - def _get_filled_in(self):
308 return self.__filled_in
309 310 filled_in_expansion = property(_get_filled_in, lambda x:x) 311 #---------------------------------------------
312 - def _on_forward_button_pressed(self, event):
313 self.__goto_next_fillin()
314 #============================================================
315 -def expand_keyword(parent=None, keyword=None, show_list=False):
316 """Expand keyword and replace inside it. 317 318 Returns: 319 None: aborted or no expansion available 320 u'': empty expansion 321 u'<text>' the expansion 322 """ 323 if keyword is None: 324 return None 325 326 if parent is None: 327 parent = wx.GetApp().GetTopWindow() 328 329 if show_list: 330 candidates = gmPG2.get_keyword_expansion_candidates(keyword = keyword) 331 if len(candidates) == 0: 332 return None 333 if len(candidates) == 1: 334 keyword = candidates[0] 335 else: 336 keyword = gmListWidgets.get_choices_from_list ( 337 parent = parent, 338 msg = _( 339 'Several macros match the keyword [%s].\n' 340 '\n' 341 'Please select the expansion you want to happen.' 342 ) % keyword, 343 caption = _('Selecting text macro'), 344 choices = candidates, 345 columns = [_('Keyword')], 346 single_selection = True, 347 can_return_empty = False 348 ) 349 if keyword is None: 350 return None 351 352 expansion = gmPG2.expand_keyword(keyword = keyword) 353 354 # not found 355 if expansion is None: 356 return None 357 358 # no replacement necessary: 359 if expansion.strip() == u'': 360 return expansion 361 362 if regex.search(_text_expansion_fillin_regex, expansion) is not None: 363 dlg = cTextExpansionFillInDlg(None, -1) 364 dlg.expansion = expansion 365 button = dlg.ShowModal() 366 if button == wx.ID_OK: 367 expansion = dlg.filled_in_expansion 368 dlg.Destroy() 369 370 return expansion
371 372 #============================================================ 373 # main 374 #------------------------------------------------------------ 375 if __name__ == '__main__': 376 377 if len(sys.argv) < 2: 378 sys.exit() 379 380 if sys.argv[1] != 'test': 381 sys.exit() 382 383 from Gnumed.pycommon import gmI18N 384 gmI18N.activate_locale() 385 gmI18N.install_domain(domain = 'gnumed') 386 387 #----------------------------------------
388 - def test_fillin():
389 expansion = u"""HEMORR²HAGES: Blutungsrisiko unter OAK 390 -------------------------------------- 391 Am Heart J. 2006 Mar;151(3):713-9. 392 393 $<1 oder 0 eingeben>$ H epatische oder Nierenerkrankung 394 $<1 oder 0 eingeben>$ E thanolabusus 395 $<1 oder 0 eingeben>$ M alignom 396 $<1 oder 0 eingeben>$ O ld patient (> 75 Jahre) 397 $<1 oder 0 eingeben>$ R eduzierte Thrombozytenzahl/-funktion 398 $<2 oder 0 eingeben>$ R²ekurrente (frühere) große Blutung 399 $<1 oder 0 eingeben>$ H ypertonie (unkontrolliert) 400 $<1 oder 0 eingeben>$ A nämie 401 $<1 oder 0 eingeben>$ G enetische Faktoren 402 $<1 oder 0 eingeben>$ E xzessives Sturzrisiko 403 $<1 oder 0 eingeben>$ S Schlaganfall in der Anamnese 404 -------------------------------------- 405 Summe Rate großer Blutungen 406 pro 100 Patientenjahre 407 0 1.9 408 1 2.5 409 2 5.3 410 3 8.4 411 4 10.4 412 >4 12.3 413 414 Bewertung: Summe = $<Summe ausrechnen und bewerten>$""" 415 416 app = wx.PyWidgetTester(size = (600, 600)) 417 dlg = cTextExpansionFillInDlg(None, -1) 418 dlg.expansion = expansion 419 dlg.ShowModal()
420 #app.MainLoop() 421 #---------------------------------------- 422 test_fillin() 423