Trees | Indices | Help |
|
---|
|
1 """GNUmed GUI helper classes and functions. 2 3 This module provides some convenient wxPython GUI 4 helper thingies that are widely used throughout 5 GnuMed. 6 7 This source code is protected by the GPL licensing scheme. 8 Details regarding the GPL are available at http://www.gnu.org 9 You may use and share it as long as you don't deny this right 10 to anybody else. 11 """ 12 # ======================================================================== 13 # $Source: /cvsroot/gnumed/gnumed/gnumed/client/wxpython/gmGuiHelpers.py,v $ 14 # $Id: gmGuiHelpers.py,v 1.106 2010/02/06 21:05:48 ncq Exp $ 15 __version__ = "$Revision: 1.106 $" 16 __author__ = "K. Hilbert <Karsten.Hilbert@gmx.net>" 17 __license__ = "GPL (details at http://www.gnu.org)" 18 19 import os 20 21 22 import wx 23 24 25 from Gnumed.business import gmSurgery 26 from Gnumed.wxGladeWidgets import wxg3ButtonQuestionDlg, wxg2ButtonQuestionDlg, wxgGreetingEditorDlg 27 28 # ========================================================================30100 # ========================================================================32 33 caption = kwargs['caption'] 34 question = kwargs['question'] 35 button_defs = kwargs['button_defs'][:2] 36 del kwargs['caption'] 37 del kwargs['question'] 38 del kwargs['button_defs'] 39 40 try: 41 show_checkbox = kwargs['show_checkbox'] 42 del kwargs['show_checkbox'] 43 except KeyError: 44 show_checkbox = False 45 46 try: 47 checkbox_msg = kwargs['checkbox_msg'] 48 del kwargs['checkbox_msg'] 49 except KeyError: 50 checkbox_msg = None 51 52 try: 53 checkbox_tooltip = kwargs['checkbox_tooltip'] 54 del kwargs['checkbox_tooltip'] 55 except KeyError: 56 checkbox_tooltip = None 57 58 wxg2ButtonQuestionDlg.wxg2ButtonQuestionDlg.__init__(self, *args, **kwargs) 59 60 self.SetTitle(title = caption) 61 self._LBL_question.SetLabel(label = question) 62 63 if not show_checkbox: 64 self._CHBOX_dont_ask_again.Hide() 65 else: 66 if checkbox_msg is not None: 67 self._CHBOX_dont_ask_again.SetLabel(checkbox_msg) 68 if checkbox_tooltip is not None: 69 self._CHBOX_dont_ask_again.SetToolTipString(checkbox_tooltip) 70 71 buttons = [self._BTN_1, self._BTN_2] 72 for idx in range(len(button_defs)): 73 buttons[idx].SetLabel(label = button_defs[idx]['label']) 74 buttons[idx].SetToolTipString(button_defs[idx]['tooltip']) 75 try: 76 if button_defs[idx]['default'] is True: 77 buttons[idx].SetDefault() 78 buttons[idx].SetFocus() 79 except KeyError: 80 pass 81 82 self.Fit()83 #-------------------------------------------------------- 86 #-------------------------------------------------------- 87 # event handlers 88 #-------------------------------------------------------- 94 #--------------------------------------------------------102144 # ======================================================================== 145 from Gnumed.wxGladeWidgets import wxgMultilineTextEntryDlg 146104 105 caption = kwargs['caption'] 106 question = kwargs['question'] 107 button_defs = kwargs['button_defs'][:3] 108 109 del kwargs['caption'] 110 del kwargs['question'] 111 del kwargs['button_defs'] 112 113 wxg3ButtonQuestionDlg.wxg3ButtonQuestionDlg.__init__(self, *args, **kwargs) 114 115 self.SetTitle(title = caption) 116 self._LBL_question.SetLabel(label = question) 117 118 buttons = [self._BTN_1, self._BTN_2, self._BTN_3] 119 for idx in range(len(button_defs)): 120 buttons[idx].SetLabel(label = button_defs[idx]['label']) 121 buttons[idx].SetToolTipString(button_defs[idx]['tooltip']) 122 try: 123 if button_defs[idx]['default'] is True: 124 buttons[idx].SetDefault() 125 buttons[idx].SetFocus() 126 except KeyError: 127 pass 128 129 self.Fit()130 #-------------------------------------------------------- 131 # event handlers 132 #-------------------------------------------------------- 138 #--------------------------------------------------------148 """Editor for a bit of text.""" 149219 # ========================================================================151 152 try: 153 title = kwargs['title'] 154 del kwargs['title'] 155 except KeyError: 156 title = None 157 158 try: 159 msg = kwargs['msg'] 160 del kwargs['msg'] 161 except KeyError: 162 msg = None 163 164 try: 165 data = kwargs['data'] 166 del kwargs['data'] 167 except KeyError: 168 data = None 169 170 try: 171 self.original_text = kwargs['text'] 172 del kwargs['text'] 173 except KeyError: 174 self.original_text = None 175 176 wxgMultilineTextEntryDlg.wxgMultilineTextEntryDlg.__init__(self, *args, **kwargs) 177 178 if title is not None: 179 self.SetTitle(title) 180 181 if self.original_text is not None: 182 self._TCTRL_text.SetValue(self.original_text) 183 self._BTN_restore.Enable(True) 184 185 if msg is None: 186 self._LBL_msg.Hide() 187 else: 188 self._LBL_msg.SetLabel(msg) 189 self.Layout() 190 self.Refresh() 191 192 if data is None: 193 self._TCTRL_data.Hide() 194 else: 195 self._TCTRL_data.SetValue(data) 196 self.Layout() 197 self.Refresh()198 #--------------------------------------------------------200 return self._TCTRL_text.GetValue()201 202 value = property(_get_value, lambda x:x) 203 #-------------------------------------------------------- 204 # event handlers 205 #-------------------------------------------------------- 212 #-------------------------------------------------------- 215 #--------------------------------------------------------221236 # ========================================================================223 wxgGreetingEditorDlg.wxgGreetingEditorDlg.__init__(self, *args, **kwargs) 224 225 self.surgery = gmSurgery.gmCurrentPractice() 226 self._TCTRL_message.SetValue(self.surgery.db_logon_banner)227 #-------------------------------------------------------- 228 # event handlers 229 #--------------------------------------------------------238 """TreeCtrl mixin class to record expansion history."""323 # ========================================================================240 if not isinstance(self, wx.TreeCtrl): 241 raise TypeError('[%s]: mixin can only be applied to wx.TreeCtrl, not [%s]' % (cTreeExpansionHistoryMixin, self.__class__.__name__)) 242 self.expansion_state = {}243 #-------------------------------------------------------- 244 # public API 245 #-------------------------------------------------------- 248 #--------------------------------------------------------250 if len(self.expansion_state) == 0: 251 return True 252 self.__restore_subtree_expansion(start_node_id = self.GetRootItem())253 #--------------------------------------------------------255 if len(self.expansion_state) == 0: 256 print "currently no expansion snapshot available" 257 return True 258 print "last snapshot of state of expansion" 259 print "-----------------------------------" 260 print "listing expanded nodes:" 261 for node_id in self.expansion_state.keys(): 262 print "node ID:", node_id 263 print " selected:", self.expansion_state[node_id]264 #-------------------------------------------------------- 265 # internal API 266 #--------------------------------------------------------268 """This records node expansion states based on the item label. 269 270 A side effect of this is that identically named items can 271 become unduly synchronized in their expand state after a 272 snapshot/restore cycle. 273 274 Better choices might be 275 276 id(item.GetPyData()) or 277 item.GetPyData().get_tree_uid() 278 279 where get_tree_uid(): 280 281 '[%s:%s]' % (self.__class__.__name__, id(self)) 282 283 or some such. This would survive renaming of the item. 284 285 For database items it may be useful to include the 286 primary key which would - contrary to id() - survive 287 reloads from the database. 288 """ 289 # protect against empty tree where not even 290 # a root node exists 291 if not start_node_id.IsOk(): 292 return True 293 294 if not self.IsExpanded(start_node_id): 295 return True 296 297 self.expansion_state[self.GetItemText(start_node_id)] = self.IsSelected(start_node_id) 298 299 child_id, cookie = self.GetFirstChild(start_node_id) 300 while child_id.IsOk(): 301 self.__record_subtree_expansion(start_node_id = child_id) 302 child_id, cookie = self.GetNextChild(start_node_id, cookie) 303 304 return305 #--------------------------------------------------------307 start_node_label = self.GetItemText(start_node_id) 308 try: 309 node_selected = self.expansion_state[start_node_label] 310 except KeyError: 311 return 312 313 self.Expand(start_node_id) 314 if node_selected: 315 self.SelectItem(start_node_id) 316 317 child_id, cookie = self.GetFirstChild(start_node_id) 318 while child_id.IsOk(): 319 self.__restore_subtree_expansion(start_node_id = child_id) 320 child_id, cookie = self.GetNextChild(start_node_id, cookie) 321 322 return325 """Generic file drop target class. 326 327 Protocol: 328 Widgets being declared file drop targets 329 must provide the method: 330 331 add_filenames(filenames) 332 """ 333 #----------------------------------------------- 337 #-----------------------------------------------340 # ========================================================================339 self.target.add_filenames(filenames)342 if aMessage is None: 343 aMessage = _('programmer forgot to specify error message') 344 345 aMessage += _("\n\nPlease consult the error log for all the gory details !") 346 347 if aTitle is None: 348 aTitle = _('generic error message') 349 350 dlg = wx.MessageDialog ( 351 parent = None, 352 message = aMessage, 353 caption = aTitle, 354 style = wx.OK | wx.ICON_ERROR | wx.STAY_ON_TOP 355 ) 356 dlg.ShowModal() 357 dlg.Destroy() 358 return True359 #-------------------------------------------------------------------------361 if aMessage is None: 362 aMessage = _('programmer forgot to specify info message') 363 364 if aTitle is None: 365 aTitle = _('generic info message') 366 367 dlg = wx.MessageDialog ( 368 parent = None, 369 message = aMessage, 370 caption = aTitle, 371 style = wx.OK | wx.ICON_INFORMATION | wx.STAY_ON_TOP 372 ) 373 dlg.ShowModal() 374 dlg.Destroy() 375 return True376 #-------------------------------------------------------------------------378 if aMessage is None: 379 aMessage = _('programmer forgot to specify warning') 380 381 if aTitle is None: 382 aTitle = _('generic warning message') 383 384 dlg = wx.MessageDialog ( 385 parent = None, 386 message = aMessage, 387 caption = aTitle, 388 style = wx.OK | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP 389 ) 390 dlg.ShowModal() 391 dlg.Destroy() 392 return True393 #-------------------------------------------------------------------------394 -def gm_show_question(aMessage='programmer forgot to specify question', aTitle='generic user question dialog', cancel_button=False):395 if cancel_button: 396 style = wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION | wx.STAY_ON_TOP 397 else: 398 style = wx.YES_NO | wx.ICON_QUESTION | wx.STAY_ON_TOP 399 400 dlg = wx.MessageDialog ( 401 None, 402 aMessage, 403 aTitle, 404 style 405 ) 406 btn_pressed = dlg.ShowModal() 407 dlg.Destroy() 408 409 if btn_pressed == wx.ID_YES: 410 return True 411 elif btn_pressed == wx.ID_NO: 412 return False 413 else: 414 return None415 #----------------------------------------------------------------------417 """ 418 Utility function to create the main sizer of a wizard's page. 419 420 @param wizPg The wizard page widget 421 @type wizPg A wx.WizardPageSimple instance 422 @param title The wizard page's descriptive title 423 @type title A StringType instance 424 """ 425 sizer = wx.BoxSizer(wx.VERTICAL) 426 wizPg.SetSizer(sizer) 427 title = wx.StaticText(wizPg, -1, title) 428 title.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD)) 429 sizer.Add(title, 0, wx.ALIGN_CENTRE|wx.ALL, 2) 430 sizer.Add(wx.StaticLine(wizPg, -1), 0, wx.EXPAND|wx.ALL, 2) 431 return sizer432 #============================================================ 433 434 # ======================================================================== 435 # $Log: gmGuiHelpers.py,v $ 436 # Revision 1.106 2010/02/06 21:05:48 ncq 437 # - support data in multiline text ctrl 438 # 439 # Revision 1.105 2009/09/23 14:42:28 ncq 440 # - remove dead code 441 # 442 # Revision 1.104 2009/07/23 16:39:23 ncq 443 # - try to improve multiline text dialog 444 # 445 # Revision 1.103 2009/07/06 17:12:34 ncq 446 # - cleanup 447 # 448 # Revision 1.102 2009/05/18 15:31:29 ncq 449 # - checkbox_is_checked convenience wrapper 450 # 451 # Revision 1.101 2009/02/24 11:19:54 ncq 452 # - cleanup 453 # 454 # Revision 1.100 2009/01/15 11:37:06 ncq 455 # - no more save callback in multiline text editor 456 # 457 # Revision 1.99 2009/01/11 19:17:17 ncq 458 # - support new action buttons in text editor 459 # 460 # Revision 1.98 2008/12/18 21:28:26 ncq 461 # - cMultilineTextEntryDlg 462 # 463 # Revision 1.97 2008/11/21 13:06:09 ncq 464 # - cleanup 465 # 466 # Revision 1.96 2008/08/08 13:30:12 ncq 467 # - needs gmSurgery 468 # 469 # Revision 1.95 2008/08/06 13:21:42 ncq 470 # - add checkbox tooltip support to 2 button question dialog 471 # 472 # Revision 1.94 2008/07/07 11:36:44 ncq 473 # - just cleanup 474 # 475 # Revision 1.93 2008/06/24 13:59:18 ncq 476 # - properly handle default buttons, SetFocus, too, in 2/3ButtonDlg 477 # 478 # Revision 1.92 2008/05/13 14:12:33 ncq 479 # - factor out exception handling 480 # 481 # Revision 1.91 2008/04/12 19:18:48 ncq 482 # - listen to application_closing and ignore 483 # PyDeadObjectError when closing down 484 # 485 # Revision 1.90 2008/03/06 18:33:12 ncq 486 # - properly log exception information for unhandled exceptions 487 # 488 # Revision 1.89 2008/03/02 15:11:55 ncq 489 # - support sender email in bug reporting 490 # 491 # Revision 1.88 2008/02/26 16:27:20 ncq 492 # - cleanup exception handler 493 # - actually log exception :-( 494 # 495 # Revision 1.87 2008/02/25 17:34:39 ncq 496 # - use new logging 497 # - auto-enable debug mode on first unhandled exception 498 # 499 # Revision 1.86 2008/01/22 12:22:18 ncq 500 # - better layout of bug report email 501 # 502 # Revision 1.85 2008/01/16 19:38:43 ncq 503 # - configure_*() factored out 504 # 505 # Revision 1.84 2008/01/13 01:17:50 ncq 506 # - use log_stack_trace() 507 # - annouce completed bug report emailing 508 # 509 # Revision 1.83 2008/01/11 16:14:05 ncq 510 # - cleanup 511 # - use staff name/system account in log mailing 512 # 513 # Revision 1.82 2008/01/07 19:52:40 ncq 514 # - proper use of flush() 515 # 516 # Revision 1.81 2008/01/06 08:12:29 ncq 517 # - auto-switch to --debug on detecting an unhandled exception 518 # - always save user comment if there is any 519 # - always backup the log file with comment for later perusal 520 # 521 # Revision 1.80 2008/01/05 16:41:27 ncq 522 # - remove logging from gm_show_*() 523 # 524 # Revision 1.79 2007/12/24 23:31:24 shilbert 525 # - remove some dlg.SetFocus statements 526 # 527 # Revision 1.78 2007/12/23 12:10:49 ncq 528 # - cleanup 529 # 530 # Revision 1.77 2007/12/11 12:49:26 ncq 531 # - explicit signal handling 532 # 533 # Revision 1.76 2007/12/04 17:32:33 ncq 534 # - improved wording 535 # 536 # Revision 1.75 2007/12/04 17:08:14 ncq 537 # - allow editing bug report targets before sending 538 # 539 # Revision 1.74 2007/12/04 16:15:28 ncq 540 # - remove get_dbowner_connection() 541 # 542 # Revision 1.73 2007/12/04 15:17:39 ncq 543 # - start general purpose progress bar 544 # 545 # Revision 1.72 2007/11/21 13:31:53 ncq 546 # - use send_mail() in exception handling dialog 547 # 548 # Revision 1.71 2007/10/21 20:18:32 ncq 549 # - configure_string_option() 550 # 551 # Revision 1.70 2007/10/19 12:50:31 ncq 552 # - add configure_boolean_option() 553 # 554 # Revision 1.69 2007/10/11 12:01:51 ncq 555 # - make c3ButtonQuestionDlg() more robust in the face of no-default button def 556 # 557 # Revision 1.68 2007/09/25 20:44:23 ncq 558 # - support saving user comment in log file rescued on error 559 # 560 # Revision 1.67 2007/09/20 21:30:06 ncq 561 # - cGreetingEditorDlg 562 # 563 # Revision 1.66 2007/09/03 11:03:20 ncq 564 # - teach top level wx exception handler about ImportError 565 # 566 # Revision 1.65 2007/08/20 14:25:16 ncq 567 # - factor out bits of code out of the actual top level 568 # exception handler in a bid to make it more resilient 569 # 570 # Revision 1.64 2007/07/18 14:43:01 ncq 571 # - do away with accessing console as it often breaks 572 # 573 # Revision 1.63 2007/06/18 20:31:58 ncq 574 # - gm_Multi/SingleChoiceDlg moved to gmListWidgets 575 # 576 # Revision 1.62 2007/06/11 20:35:06 ncq 577 # - MSW does ref counting in Begin/EndBusyCursor 578 # - add gmMultiChoiceDialog 579 # 580 # Revision 1.61 2007/05/14 10:34:07 ncq 581 # - no more gm_statustext() 582 # 583 # Revision 1.60 2007/05/14 10:05:33 ncq 584 # - make "default" button definition optional 585 # 586 # Revision 1.59 2007/05/14 08:36:13 ncq 587 # - in c2ButtonQuestionDlg make keyword show_checkbox option defaulting to False 588 # 589 # Revision 1.58 2007/05/11 14:15:59 ncq 590 # - display help desk in exception handler 591 # - properly handle keep running/close client buttons 592 # 593 # Revision 1.57 2007/05/08 16:04:40 ncq 594 # - add wxPython based exception display handler 595 # 596 # Revision 1.56 2007/04/27 13:28:48 ncq 597 # - implement c2ButtonQuestionDlg 598 # 599 # Revision 1.55 2007/04/23 01:06:42 ncq 600 # - add password argument to get_dbowner_connection() 601 # 602 # Revision 1.54 2007/04/11 20:41:58 ncq 603 # - remove gm_icon() 604 # 605 # Revision 1.53 2007/04/09 22:02:40 ncq 606 # - fix docstring 607 # 608 # Revision 1.52 2007/03/18 14:07:14 ncq 609 # - factor out hook script running 610 # 611 # Revision 1.51 2007/03/02 15:32:56 ncq 612 # - turn gm_statustext() into signal sender with depreciation 613 # warning (should used gmDispatcher.send() now) 614 # 615 # Revision 1.50 2007/02/19 16:13:36 ncq 616 # - add run_hook_script() 617 # 618 # Revision 1.49 2007/02/18 16:57:38 ncq 619 # - make sure gm-dbo connections aren't returned from the pool 620 # 621 # Revision 1.48 2007/01/20 22:52:27 ncq 622 # - .KeyCode -> GetKeyCode() 623 # 624 # Revision 1.47 2007/01/16 13:59:51 ncq 625 # - protect against empty trees in expansion history mixin 626 # 627 # Revision 1.46 2007/01/15 13:04:25 ncq 628 # - c3ButtonQuestionDlg 629 # - remove cReturnTraversalTextCtrl 630 # 631 # Revision 1.45 2007/01/13 22:43:41 ncq 632 # - remove str() raising Unicode exceptions 633 # 634 # Revision 1.44 2007/01/13 22:19:37 ncq 635 # - cTreeExpansionHistoryMixin 636 # 637 # Revision 1.43 2007/01/12 13:09:46 ncq 638 # - cFileDropTarget 639 # 640 # Revision 1.42 2006/12/15 15:24:06 ncq 641 # - cleanup 642 # 643 # Revision 1.41 2006/11/24 09:53:24 ncq 644 # - gm_beep_statustext() -> gm_statustext(beep=True) 645 # 646 # Revision 1.40 2006/11/05 14:18:57 ncq 647 # - missing "style =" 648 # 649 # Revision 1.39 2006/10/24 13:23:31 ncq 650 # - use gmPG2.get_default_login() in get_dbowner_connection() 651 # 652 # Revision 1.38 2006/10/08 11:03:09 ncq 653 # - convert to gmPG2 654 # 655 # Revision 1.37 2006/09/03 11:29:30 ncq 656 # - add cancel_button argument to show_question 657 # 658 # Revision 1.36 2006/08/01 22:03:49 ncq 659 # - cleanup 660 # 661 # Revision 1.35 2006/06/20 09:42:42 ncq 662 # - cTextObjectValidator -> cTextWidgetValidator 663 # - add custom invalid message to text widget validator 664 # - variable renaming, cleanup 665 # - fix demographics validation 666 # 667 # Revision 1.34 2006/06/17 16:42:48 ncq 668 # - add get_dbowner_connection() 669 # 670 # Revision 1.33 2006/05/01 18:47:32 ncq 671 # - cleanup 672 # 673 # Revision 1.32 2006/01/15 13:19:16 shilbert 674 # - gm_SingleChoiceDialog was added 675 # - wxpython 2.6 does not support client data associated with item 676 # 677 # Revision 1.31 2005/10/27 21:37:29 shilbert 678 # fixed wxYES|NO into wx.YES|NO 679 # 680 # Revision 1.30 2005/10/11 21:14:10 ncq 681 # - remove out-of-place LogException() call 682 # 683 # Revision 1.29 2005/10/09 08:07:56 ihaywood 684 # a textctrl that uses return for navigation wx 2.6 only 685 # 686 # Revision 1.28 2005/10/04 13:09:49 sjtan 687 # correct syntax errors; get soap entry working again. 688 # 689 # Revision 1.27 2005/10/04 00:04:45 sjtan 690 # convert to wx.; catch some transitional errors temporarily 691 # 692 # Revision 1.26 2005/09/28 21:27:30 ncq 693 # - a lot of wx2.6-ification 694 # 695 # Revision 1.25 2005/09/28 15:57:48 ncq 696 # - a whole bunch of wx.Foo -> wx.Foo 697 # 698 # Revision 1.24 2005/09/26 18:01:50 ncq 699 # - use proper way to import wx26 vs wx2.4 700 # - note: THIS WILL BREAK RUNNING THE CLIENT IN SOME PLACES 701 # - time for fixup 702 # 703 # Revision 1.23 2005/09/12 15:09:42 ncq 704 # - cleanup 705 # 706 # Revision 1.22 2005/06/10 16:11:14 shilbert 707 # szr.AddWindow() -> Add() such that wx2.5 works 708 # 709 # Revision 1.21 2005/06/08 01:27:50 cfmoro 710 # Validator fix 711 # 712 # Revision 1.20 2005/05/05 06:27:52 ncq 713 # - add wx.STAY_ON_TOP in an effort to keep popups up front 714 # 715 # Revision 1.19 2005/04/24 14:48:57 ncq 716 # - improved wording 717 # 718 # Revision 1.18 2005/04/10 12:09:16 cfmoro 719 # GUI implementation of the first-basic (wizard) page for patient details input 720 # 721 # Revision 1.17 2005/03/06 09:21:08 ihaywood 722 # stole a couple of icons from Richard's demo code 723 # 724 # Revision 1.16 2004/12/21 21:00:35 ncq 725 # - if no status text handler available, dump to stdout 726 # 727 # Revision 1.15 2004/12/21 19:40:56 ncq 728 # - fix faulty LogException() usage 729 # 730 # Revision 1.14 2004/09/25 13:10:40 ncq 731 # - in gm_beep_statustext() make aMessage a defaulted keyword argument 732 # 733 # Revision 1.13 2004/08/19 13:56:51 ncq 734 # - added gm_show_warning() 735 # 736 # Revision 1.12 2004/08/18 10:18:42 ncq 737 # - added gm_show_info() 738 # 739 # Revision 1.11 2004/05/28 13:30:27 ncq 740 # - set_status_text -> _set_status_text so nobody 741 # gets the idea to use it directly 742 # 743 # Revision 1.10 2004/05/26 23:23:35 shilbert 744 # - import statement fixed 745 # 746 # Revision 1.9 2004/04/11 10:10:56 ncq 747 # - cleanup 748 # 749 # Revision 1.8 2004/04/10 01:48:31 ihaywood 750 # can generate referral letters, output to xdvi at present 751 # 752 # Revision 1.7 2004/03/04 19:46:54 ncq 753 # - switch to package based import: from Gnumed.foo import bar 754 # 755 # Revision 1.6 2003/12/29 16:49:18 uid66147 756 # - cleanup, gm_beep_statustext() 757 # 758 # Revision 1.5 2003/11/17 10:56:38 sjtan 759 # 760 # synced and commiting. 761 # 762 # Revision 1.1 2003/10/23 06:02:39 sjtan 763 # 764 # manual edit areas modelled after r.terry's specs. 765 # 766 # Revision 1.4 2003/08/26 12:35:52 ncq 767 # - properly replace \n\r 768 # 769 # Revision 1.3 2003/08/24 09:15:20 ncq 770 # - remove spurious self's 771 # 772 # Revision 1.2 2003/08/24 08:58:07 ncq 773 # - use gm_show_* 774 # 775 # Revision 1.1 2003/08/21 00:11:48 ncq 776 # - adds some widely used wxPython GUI helper functions 777 # 778
Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Tue Feb 9 04:02:28 2010 | http://epydoc.sourceforge.net |