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

Source Code for Module Gnumed.wxpython.gmKeywordExpansionWidgets

  1  # -*- coding: utf-8 -*- 
  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  import os.path 
 11   
 12   
 13  import wx 
 14  import wx.stc 
 15   
 16   
 17  if __name__ == '__main__': 
 18          sys.path.insert(0, '../../') 
 19  from Gnumed.pycommon import gmDispatcher 
 20  from Gnumed.pycommon import gmPG2 
 21  from Gnumed.pycommon import gmTools 
 22  from Gnumed.business import gmKeywordExpansion 
 23  from Gnumed.wxpython import gmEditArea 
 24  from Gnumed.wxpython import gmListWidgets 
 25   
 26   
 27  _log = logging.getLogger('gm.ui') 
 28   
 29  _text_expansion_fillin_regex = r'\$\[[^]]*\]\$' 
 30   
 31  #============================================================ 
32 -class cKeywordExpansion_TextCtrlMixin():
33
34 - def __init__(self, *args, **kwargs):
35 if not isinstance(self, (wx.TextCtrl, wx.stc.StyledTextCtrl)): 36 raise TypeError('[%s]: can only be applied to wx.TextCtrl or wx.stc.StyledTextCtrl, not [%s]' % (cKeywordExpansion_TextCtrlMixin, self.__class__.__name__))
37 38 #--------------------------------------------------------
40 self.__keyword_separators = regex.compile("[!?'\".,:;)}\]\r\n\s\t]+") 41 self.Bind(wx.EVT_CHAR, self.__on_char_in_keyword_expansion_mixin)
42 43 #--------------------------------------------------------
45 self.Unbind(wx.EVT_CHAR)
46 47 #--------------------------------------------------------
48 - def attempt_expansion(self, show_list_if_needed=False):
49 50 visible, caret_pos_in_line, line_no = self.PositionToXY(self.InsertionPoint) 51 line = self.GetLineText(line_no) 52 keyword_candidate = self.__keyword_separators.split(line[:caret_pos_in_line])[-1] 53 54 if ( 55 (show_list_if_needed is False) 56 and 57 (keyword_candidate != '$$steffi') # Easter Egg ;-) 58 and 59 (keyword_candidate not in [ r[0] for r in gmKeywordExpansion.get_textual_expansion_keywords() ]) 60 ): 61 return 62 63 # why does this work despite the wx.TextCtrl docs saying that 64 # InsertionPoint values cannot be used as indices into strings ? 65 # because we never cross an EOL which is the only documented 66 # reason for insertion point to be off the string index 67 start = self.InsertionPoint - len(keyword_candidate) 68 wx.CallAfter(self.__replace_keyword_with_expansion, keyword = keyword_candidate, position = start, show_list_if_needed = show_list_if_needed) 69 return
70 71 #-------------------------------------------------------- 72 # event handling 73 #--------------------------------------------------------
75 evt.Skip() 76 77 # empty ? 78 if self.LastPosition == 1: 79 return 80 81 char = chr(evt.GetUnicodeKey()) 82 83 user_wants_expansion_attempt = False 84 if evt.GetModifiers() == (wx.MOD_CMD | wx.MOD_ALT): # portable CTRL-ALT-... 85 if evt.GetKeyCode() == wx.WXK_RETURN: # CTRL-ALT-ENTER 86 user_wants_expansion_attempt = True 87 elif evt.GetKeyCode() == 20: # CTRL-ALT-T 88 user_wants_expansion_attempt = True 89 else: 90 return 91 92 if user_wants_expansion_attempt is False: 93 # user did not press CTRL-ALT-ENTER, 94 # however, did they last enter a 95 # "keyword separator", active character ? 96 if self.__keyword_separators.match(char) is None: 97 return 98 99 self.attempt_expansion(show_list_if_needed = user_wants_expansion_attempt)
100 101 #-------------------------------------------------------- 102 # internal helpers 103 #--------------------------------------------------------
104 - def __replace_keyword_with_expansion(self, keyword=None, position=None, show_list_if_needed=False):
105 106 expansion = expand_keyword(parent = self, keyword = keyword, show_list_if_needed = show_list_if_needed) 107 if expansion is None: 108 return 109 if expansion == '': 110 return 111 112 if not self.IsMultiLine(): 113 expansion_lines = gmTools.strip_leading_empty_lines ( 114 lines = gmTools.strip_trailing_empty_lines ( 115 text = expansion, 116 return_list = True 117 ), 118 return_list = True 119 ) 120 if len(expansion_lines) == 0: 121 return 122 if len(expansion_lines) == 1: 123 expansion = expansion_lines[0] 124 else: 125 msg = _( 126 'The fragment <%s> expands to multiple lines !\n' 127 '\n' 128 'This text field can hold one line only, hwoever.\n' 129 '\n' 130 'Please select the line you want to insert:' 131 ) % keyword 132 expansion = gmListWidgets.get_choices_from_list ( 133 parent = self, 134 msg = msg, 135 caption = _('Adapting multi-line expansion to single-line text field'), 136 choices = expansion_lines, 137 selections = [0], 138 columns = [_('Keyword expansion lines')], 139 single_selection = True, 140 can_return_empty = False 141 ) 142 if expansion is None: 143 return 144 145 self.Replace ( 146 position, 147 position + len(keyword), 148 expansion 149 ) 150 151 self.SetInsertionPoint(position + len(expansion) + 1) 152 self.ShowPosition(position + len(expansion) + 1) 153 154 return
155 156 #============================================================ 157 from Gnumed.wxGladeWidgets import wxgTextExpansionEditAreaPnl 158
159 -class cTextExpansionEditAreaPnl(wxgTextExpansionEditAreaPnl.wxgTextExpansionEditAreaPnl, gmEditArea.cGenericEditAreaMixin):
160
161 - def __init__(self, *args, **kwds):
162 163 try: 164 data = kwds['expansion'] 165 del kwds['expansion'] 166 except KeyError: 167 data = None 168 169 wxgTextExpansionEditAreaPnl.wxgTextExpansionEditAreaPnl.__init__(self, *args, **kwds) 170 gmEditArea.cGenericEditAreaMixin.__init__(self) 171 172 self.mode = 'new' 173 self.data = data 174 if data is not None: 175 self.mode = 'edit' 176 177 # self.__init_ui() 178 self.__register_interests() 179 180 self.__data_filename = None
181 182 #-------------------------------------------------------- 183 # def __init_ui(self, expansion=None): 184 # self._BTN_select_data_file.Enable(False) 185 186 #---------------------------------------------------------------- 187 # generic Edit Area mixin API 188 #----------------------------------------------------------------
189 - def _valid_for_save(self):
190 validity = True 191 192 has_expansion = ( 193 (self._TCTRL_expansion.GetValue().strip() != '') 194 or 195 (self.__data_filename is not None) 196 or 197 ((self.data is not None) and (self.data['is_textual'] is False)) 198 ) 199 200 if has_expansion: 201 self.display_tctrl_as_valid(tctrl = self._TCTRL_expansion, valid = True) 202 self.display_tctrl_as_valid(tctrl = self._TCTRL_data_file, valid = True) 203 else: 204 validity = False 205 gmDispatcher.send(signal = 'statustext', msg = _('Cannot save keyword expansion without text or data expansion.'), beep = True) 206 self.display_tctrl_as_valid(tctrl = self._TCTRL_expansion, valid = False) 207 self.display_tctrl_as_valid(tctrl = self._TCTRL_data_file, valid = False) 208 if self.data is None: 209 self._TCTRL_expansion.SetFocus() 210 else: 211 if self.data['is_textual']: 212 self._TCTRL_expansion.SetFocus() 213 else: 214 self._BTN_select_data_file.SetFocus() 215 216 if self._TCTRL_keyword.GetValue().strip() == '': 217 validity = False 218 self.display_tctrl_as_valid(tctrl = self._TCTRL_keyword, valid = False) 219 gmDispatcher.send(signal = 'statustext', msg = _('Cannot save keyword expansion without keyword.'), beep = True) 220 self._TCTRL_keyword.SetFocus() 221 else: 222 self.display_tctrl_as_valid(tctrl = self._TCTRL_keyword, valid = True) 223 224 return validity
225 226 #----------------------------------------------------------------
227 - def _save_as_new(self):
228 expansion = gmKeywordExpansion.create_keyword_expansion ( 229 keyword = self._TCTRL_keyword.GetValue().strip(), 230 text = self._TCTRL_expansion.GetValue(), 231 data_file = self.__data_filename, 232 public = self._RBTN_public.GetValue() 233 ) 234 235 if expansion is False: 236 return False 237 238 expansion['is_encrypted'] = self._CHBOX_is_encrypted.IsChecked() 239 expansion.save() 240 241 self.data = expansion 242 return True
243 244 #----------------------------------------------------------------
245 - def _save_as_update(self):
246 247 self.data['expansion'] = self._TCTRL_expansion.GetValue().strip() 248 self.data['is_encrypted'] = self._CHBOX_is_encrypted.IsChecked() 249 self.data.save() 250 251 if self.__data_filename is not None: 252 self.data.update_data_from_file(filename = self.__data_filename) 253 254 return True
255 #---------------------------------------------------------------- 256 #----------------------------------------------------------------
257 - def _refresh_as_new(self):
258 self.__data_filename = None 259 260 self._TCTRL_keyword.SetValue('') 261 self._TCTRL_keyword.Enable(True) 262 263 self._LBL_data.Enable(False) 264 self._BTN_select_data_file.Enable(False) 265 self._TCTRL_data_file.SetValue('') 266 self._CHBOX_is_encrypted.SetValue(False) 267 self._CHBOX_is_encrypted.Enable(False) 268 269 self._LBL_text.Enable(False) 270 self._TCTRL_expansion.SetValue('') 271 self._TCTRL_expansion.Enable(False) 272 273 self._RBTN_public.Enable(False) 274 self._RBTN_private.Enable(False) 275 self._RBTN_public.SetValue(1) 276 277 self._TCTRL_keyword.SetFocus()
278 #----------------------------------------------------------------
280 self._refresh_from_existing() 281 282 self._TCTRL_keyword.SetValue('%s%s' % (self.data, _('___copy'))) 283 self._TCTRL_keyword.Enable(True) 284 285 self._RBTN_public.Enable(True) 286 self._RBTN_private.Enable(True) 287 288 self._TCTRL_keyword.SetFocus()
289 #----------------------------------------------------------------
290 - def _refresh_from_existing(self):
291 self.__data_filename = None 292 293 self._TCTRL_keyword.SetValue(self.data['keyword']) 294 self._TCTRL_keyword.Enable(False) 295 296 if self.data['is_textual']: 297 self._LBL_text.Enable(True) 298 self._TCTRL_expansion.SetValue(gmTools.coalesce(self.data['expansion'], '')) 299 300 self._LBL_data.Enable(False) 301 self._BTN_select_data_file.Enable(False) 302 self._TCTRL_data_file.SetValue('') 303 self._CHBOX_is_encrypted.SetValue(False) 304 self._CHBOX_is_encrypted.Enable(False) 305 else: 306 self._LBL_text.Enable(False) 307 self._TCTRL_expansion.SetValue('') 308 309 self._LBL_data.Enable(True) 310 self._BTN_select_data_file.Enable(True) 311 self._TCTRL_data_file.SetValue(_('Size: %s') % gmTools.size2str(self.data['data_size'])) 312 self._CHBOX_is_encrypted.SetValue(self.data['is_encrypted']) 313 self._CHBOX_is_encrypted.Enable(True) 314 315 self._RBTN_public.Enable(False) 316 self._RBTN_private.Enable(False) 317 if self.data['public_expansion']: 318 self._RBTN_public.SetValue(1) 319 else: 320 self._RBTN_private.SetValue(1) 321 322 if self.data['is_textual']: 323 self._TCTRL_expansion.SetFocus() 324 else: 325 self._BTN_select_data_file.SetFocus()
326 #---------------------------------------------------------------- 327 # event handling 328 #----------------------------------------------------------------
329 - def __register_interests(self):
330 self._TCTRL_keyword.Bind(wx.EVT_TEXT, self._on_keyword_modified) 331 self._TCTRL_expansion.Bind(wx.EVT_TEXT, self._on_expansion_modified)
332 #----------------------------------------------------------------
333 - def _on_keyword_modified(self, evt):
334 if self._TCTRL_keyword.GetValue().strip() == '': 335 self._LBL_text.Enable(False) 336 self._TCTRL_expansion.Enable(False) 337 self._LBL_data.Enable(False) 338 self._BTN_select_data_file.Enable(False) 339 self._CHBOX_is_encrypted.Enable(False) 340 self._RBTN_public.Enable(False) 341 self._RBTN_private.Enable(False) 342 return 343 344 # keyword is not empty 345 # mode must be new(_from_existing) or else 346 # we cannot modify the keyword in the first place 347 self._LBL_text.Enable(True) 348 self._TCTRL_expansion.Enable(True) 349 self._LBL_data.Enable(True) 350 self._BTN_select_data_file.Enable(True) 351 self._RBTN_public.Enable(True) 352 self._RBTN_private.Enable(True)
353 #----------------------------------------------------------------
354 - def _on_expansion_modified(self, evt):
355 if self._TCTRL_expansion.GetValue().strip() == '': 356 self._LBL_data.Enable(True) 357 self._BTN_select_data_file.Enable(True) 358 return 359 360 self.__data_filename = None 361 self._LBL_data.Enable(False) 362 self._BTN_select_data_file.Enable(False) 363 self._TCTRL_data_file.SetValue('') 364 self._CHBOX_is_encrypted.Enable(False)
365 #----------------------------------------------------------------
366 - def _on_select_data_file_button_pressed(self, event):
367 wildcards = [ 368 "%s (*)|*" % _('all files'), 369 "%s (*.*)|*.*" % _('all files (Windows)') 370 ] 371 372 dlg = wx.FileDialog ( 373 parent = self, 374 message = _('Choose the file containing the data snippet'), 375 wildcard = '|'.join(wildcards), 376 style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST 377 ) 378 result = dlg.ShowModal() 379 if result != wx.ID_CANCEL: 380 self.__data_filename = dlg.GetPath() 381 self._TCTRL_data_file.SetValue(self.__data_filename) 382 self._CHBOX_is_encrypted.SetValue(False) 383 self._CHBOX_is_encrypted.Enable(True) 384 385 dlg.Destroy()
386 387 #============================================================
388 -def configure_keyword_text_expansion(parent=None):
389 390 if parent is None: 391 parent = wx.GetApp().GetTopWindow() 392 393 #---------------------- 394 def delete(expansion=None): 395 gmKeywordExpansion.delete_keyword_expansion(pk = expansion['pk_expansion']) 396 return True
397 #---------------------- 398 def edit(expansion=None): 399 ea = cTextExpansionEditAreaPnl(parent, -1, expansion = expansion) 400 dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea) 401 if expansion is None: 402 title = _('Adding keyword expansion') 403 else: 404 title = _('Editing keyword expansion "%s"') % expansion['keyword'] 405 dlg.SetTitle(title) 406 if dlg.ShowModal() == wx.ID_OK: 407 return True 408 409 return False 410 #---------------------- 411 def tooltip(expansion): 412 return expansion.format() 413 #---------------------- 414 def refresh(lctrl=None): 415 expansions = gmKeywordExpansion.get_keyword_expansions(order_by = 'is_textual DESC, keyword, public_expansion', force_reload = True) 416 items = [[ 417 e['keyword'], 418 gmTools.bool2subst(e['is_textual'], _('text'), _('data')), 419 gmTools.bool2subst(e['public_expansion'], _('public'), _('private')) 420 ] for e in expansions 421 ] 422 lctrl.set_string_items(items) 423 lctrl.set_data(expansions) 424 #---------------------- 425 426 gmListWidgets.get_choices_from_list ( 427 parent = parent, 428 msg = _('\nSelect the keyword you want to edit !\n'), 429 caption = _('Editing keyword-based expansions ...'), 430 columns = [_('Keyword'), _('Type'), _('Scope')], 431 single_selection = True, 432 edit_callback = edit, 433 new_callback = edit, 434 delete_callback = delete, 435 refresh_callback = refresh, 436 list_tooltip_callback = tooltip 437 ) 438 439 #============================================================ 440 from Gnumed.wxGladeWidgets import wxgTextExpansionFillInDlg 441
442 -class cTextExpansionFillInDlg(wxgTextExpansionFillInDlg.wxgTextExpansionFillInDlg):
443
444 - def __init__(self, *args, **kwds):
445 wxgTextExpansionFillInDlg.wxgTextExpansionFillInDlg.__init__(self, *args, **kwds) 446 447 self.__expansion = None 448 self.__init_ui()
449 #---------------------------------------------
450 - def __init_ui(self):
451 self._LBL_top_part.SetLabel('') 452 font = self._LBL_left_part.GetFont() 453 font.SetPointSize(pointSize = font.GetPointSize() + 1) 454 self._LBL_left_part.SetFont(font) 455 self._LBL_left_part.SetLabel('') 456 self._LBL_left_part.Hide() 457 font = self._TCTRL_fillin.GetFont() 458 font.SetPointSize(pointSize = font.GetPointSize() + 1) 459 self._TCTRL_fillin.SetFont(font) 460 self._TCTRL_fillin.SetValue('') 461 self._TCTRL_fillin.SetBackgroundColour('yellow') 462 self._TCTRL_fillin.Disable() 463 self._TCTRL_fillin.Hide() 464 font = self._LBL_right_part.GetFont() 465 font.SetPointSize(pointSize = font.GetPointSize() + 1) 466 self._LBL_right_part.SetFont(font) 467 self._LBL_right_part.SetLabel('') 468 self._LBL_right_part.Hide() 469 self._LBL_bottom_part.SetLabel('') 470 self._BTN_OK.Disable() 471 self._BTN_forward.Disable() 472 self._BTN_cancel.SetFocus() 473 self._LBL_hint.SetLabel('')
474 #---------------------------------------------
475 - def __goto_next_fillin(self):
476 if self.__expansion is None: 477 return 478 479 if self.__new_expansion: 480 self.__filled_in = self.__expansion 481 self.__new_expansion = False 482 else: 483 self.__filled_in = ( 484 self._LBL_top_part.GetLabel() + 485 self.__left_splitter + 486 self._LBL_left_part.GetLabel() + 487 self._TCTRL_fillin.GetValue().strip() + 488 self._LBL_right_part.GetLabel() + 489 self.__right_splitter + 490 self._LBL_bottom_part.GetLabel() 491 ) 492 493 # anything to fill in ? 494 if regex.search(_text_expansion_fillin_regex, self.__filled_in) is None: 495 # no 496 self._LBL_top_part.SetLabel(self.__filled_in) 497 self._LBL_left_part.SetLabel('') 498 self._LBL_left_part.Hide() 499 self._TCTRL_fillin.SetValue('') 500 self._TCTRL_fillin.Disable() 501 self._TCTRL_fillin.Hide() 502 self._LBL_right_part.SetLabel('') 503 self._LBL_right_part.Hide() 504 self._LBL_bottom_part.SetLabel('') 505 self._BTN_OK.Enable() 506 self._BTN_forward.Disable() 507 self._BTN_OK.SetDefault() 508 return 509 510 # yes 511 top, fillin, bottom = regex.split(r'(' + _text_expansion_fillin_regex + r')', self.__filled_in, maxsplit = 1) 512 top_parts = top.rsplit('\n', 1) 513 top_part = top_parts[0] 514 if len(top_parts) == 1: 515 self.__left_splitter = '' 516 left_part = '' 517 else: 518 self.__left_splitter = '\n' 519 left_part = top_parts[1] 520 bottom_parts = bottom.split('\n', 1) 521 if len(bottom_parts) == 1: 522 parts = bottom_parts[0].split(' ', 1) 523 right_part = parts[0] 524 if len(parts) == 1: 525 self.__right_splitter = '' 526 bottom_part = '' 527 else: 528 self.__right_splitter = ' ' 529 bottom_part = parts[1] 530 else: 531 self.__right_splitter = '\n' 532 right_part = bottom_parts[0] 533 bottom_part = bottom_parts[1] 534 hint = fillin.strip('$').strip('[').strip(']').strip() 535 self._LBL_top_part.SetLabel(top_part) 536 self._LBL_left_part.SetLabel(left_part) 537 self._LBL_left_part.Show() 538 self._TCTRL_fillin.Enable() 539 self._TCTRL_fillin.SetValue('') 540 self._TCTRL_fillin.Show() 541 self._LBL_right_part.SetLabel(right_part) 542 self._LBL_right_part.Show() 543 self._LBL_bottom_part.SetLabel(bottom_part) 544 self._BTN_OK.Disable() 545 self._BTN_forward.Enable() 546 self._BTN_forward.SetDefault() 547 self._LBL_hint.SetLabel(hint) 548 self._TCTRL_fillin.SetFocus() 549 550 self.Layout() 551 self.Fit()
552 #--------------------------------------------- 553 # properties 554 #---------------------------------------------
555 - def _get_expansion(self):
556 return self.__expansion
557
558 - def _set_expansion(self, expansion):
559 self.__expansion = expansion 560 self.__new_expansion = True 561 self.__goto_next_fillin() 562 return
563 564 expansion = property(_get_expansion, _set_expansion) 565 #---------------------------------------------
566 - def _get_filled_in(self):
567 return self.__filled_in
568 569 filled_in_expansion = property(_get_filled_in, lambda x:x) 570 #---------------------------------------------
571 - def _set_keyword(self, keyword):
572 self.SetTitle(_('Expanding <%s>') % keyword)
573 574 keyword = property(lambda x:x, _set_keyword) 575 #--------------------------------------------- 576 # event handlers 577 #---------------------------------------------
578 - def _on_forward_button_pressed(self, event):
579 self.__goto_next_fillin()
580 581 #============================================================
582 -def expand_keyword(parent=None, keyword=None, show_list_if_needed=False):
583 """Expand keyword and replace inside it. 584 585 Returns: 586 None: aborted or no expansion available 587 u'': empty expansion 588 u'<text>' the expansion 589 """ 590 if keyword is None: 591 return None 592 if parent is None: 593 parent = wx.GetApp().GetTopWindow() 594 595 if show_list_if_needed: 596 candidates = gmKeywordExpansion.get_matching_textual_keywords(fragment = keyword) 597 if len(candidates) == 0: 598 return None 599 if len(candidates) == 1: 600 keyword = candidates[0] 601 else: 602 keyword = gmListWidgets.get_choices_from_list ( 603 parent = parent, 604 msg = _( 605 'Several macro keywords match the fragment [%s].\n' 606 '\n' 607 'Please select the expansion you want to happen.' 608 ) % keyword, 609 caption = _('Selecting text macro'), 610 choices = candidates, 611 columns = [_('Keyword')], 612 single_selection = True, 613 can_return_empty = False 614 ) 615 if keyword is None: 616 return None 617 618 expansion = gmKeywordExpansion.expand_keyword(keyword = keyword) 619 620 # not found 621 if expansion is None: 622 return None 623 624 # no replacement necessary: 625 if expansion.strip() == '': 626 return expansion 627 628 if regex.search(_text_expansion_fillin_regex, expansion) is not None: 629 dlg = cTextExpansionFillInDlg(None, -1) 630 dlg.keyword = keyword 631 dlg.expansion = expansion 632 button = dlg.ShowModal() 633 if button == wx.ID_OK: 634 expansion = dlg.filled_in_expansion 635 dlg.Destroy() 636 637 return expansion
638 639 #============================================================ 640 # main 641 #------------------------------------------------------------ 642 if __name__ == '__main__': 643 644 if len(sys.argv) < 2: 645 sys.exit() 646 647 if sys.argv[1] != 'test': 648 sys.exit() 649 650 from Gnumed.pycommon import gmI18N 651 gmI18N.activate_locale() 652 gmI18N.install_domain(domain = 'gnumed') 653 654 #----------------------------------------
655 - def test_fillin():
656 expansion = """HEMORR²HAGES: Blutungsrisiko unter OAK 657 -------------------------------------- 658 Am Heart J. 2006 Mar;151(3):713-9. 659 660 $[1 oder 0 eingeben]$ H epatische oder Nierenerkrankung 661 $[1 oder 0 eingeben]$ E thanolabusus 662 $[1 oder 0 eingeben]$ M alignom 663 $[1 oder 0 eingeben]$ O ld patient (> 75 Jahre) 664 $[1 oder 0 eingeben]$ R eduzierte Thrombozytenzahl/-funktion 665 $[2 oder 0 eingeben]$ R²ekurrente (frühere) große Blutung 666 $[1 oder 0 eingeben]$ H ypertonie (unkontrolliert) 667 $[1 oder 0 eingeben]$ A nämie 668 $[1 oder 0 eingeben]$ G enetische Faktoren 669 $[1 oder 0 eingeben]$ E xzessives Sturzrisiko 670 $[1 oder 0 eingeben]$ S Schlaganfall in der Anamnese 671 -------------------------------------- 672 Summe Rate großer Blutungen 673 pro 100 Patientenjahre 674 0 1.9 675 1 2.5 676 2 5.3 677 3 8.4 678 4 10.4 679 >4 12.3 680 681 Bewertung: Summe = $[Summe ausrechnen und bewerten]$""" 682 683 app = wx.PyWidgetTester(size = (600, 600)) 684 dlg = cTextExpansionFillInDlg(None, -1) 685 dlg.expansion = expansion 686 dlg.ShowModal()
687 #app.MainLoop() 688 #---------------------------------------- 689 test_fillin() 690