Package Gnumed :: Package CherryPy :: Module gmGuiHelpersWeb
[frames] | no frames]

Source Code for Module Gnumed.CherryPy.gmGuiHelpersWeb

  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: /home/ncq/Projekte/cvs2git/vcs-mirror/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  # ======================================================================== 
29 -class c2ButtonQuestionDlg(wxg2ButtonQuestionDlg.wxg2ButtonQuestionDlg):
30
31 - def __init__(self, *args, **kwargs):
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 #--------------------------------------------------------
84 - def checkbox_is_checked(self):
85 return self._CHBOX_dont_ask_again.IsChecked()
86 #-------------------------------------------------------- 87 # event handlers 88 #--------------------------------------------------------
89 - def _on_BTN_1_pressed(self, evt):
90 if self.IsModal(): 91 self.EndModal(wx.ID_YES) 92 else: 93 self.Close()
94 #--------------------------------------------------------
95 - def _on_BTN_2_pressed(self, evt):
96 if self.IsModal(): 97 self.EndModal(wx.ID_NO) 98 else: 99 self.Close()
100 # ========================================================================
101 -class c3ButtonQuestionDlg(wxg3ButtonQuestionDlg.wxg3ButtonQuestionDlg):
102
103 - def __init__(self, *args, **kwargs):
104 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 #--------------------------------------------------------
133 - def _on_BTN_1_pressed(self, evt):
134 if self.IsModal(): 135 self.EndModal(wx.ID_YES) 136 else: 137 self.Close()
138 #--------------------------------------------------------
139 - def _on_BTN_2_pressed(self, evt):
140 if self.IsModal(): 141 self.EndModal(wx.ID_NO) 142 else: 143 self.Close()
144 # ======================================================================== 145 from Gnumed.wxGladeWidgets import wxgMultilineTextEntryDlg 146
147 -class cMultilineTextEntryDlg(wxgMultilineTextEntryDlg.wxgMultilineTextEntryDlg):
148 """Editor for a bit of text.""" 149
150 - def __init__(self, *args, **kwargs):
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 #--------------------------------------------------------
199 - def _get_value(self):
200 return self._TCTRL_text.GetValue()
201 202 value = property(_get_value, lambda x:x) 203 #-------------------------------------------------------- 204 # event handlers 205 #--------------------------------------------------------
206 - def _on_save_button_pressed(self, evt):
207 208 if self.IsModal(): 209 self.EndModal(wx.ID_SAVE) 210 else: 211 self.Close()
212 #--------------------------------------------------------
213 - def _on_clear_button_pressed(self, evt):
214 self._TCTRL_text.SetValue(u'')
215 #--------------------------------------------------------
216 - def _on_restore_button_pressed(self, evt):
217 if self.original_text is not None: 218 self._TCTRL_text.SetValue(self.original_text)
219 # ========================================================================
220 -class cGreetingEditorDlg(wxgGreetingEditorDlg.wxgGreetingEditorDlg):
221
222 - def __init__(self, *args, **kwargs):
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 #--------------------------------------------------------
230 - def _on_save_button_pressed(self, evt):
231 self.surgery.db_logon_banner = self._TCTRL_message.GetValue().strip() 232 if self.IsModal(): 233 self.EndModal(wx.ID_SAVE) 234 else: 235 self.Close()
236 # ========================================================================
237 -class cTreeExpansionHistoryMixin:
238 """TreeCtrl mixin class to record expansion history."""
239 - def __init__(self):
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 #--------------------------------------------------------
246 - def snapshot_expansion(self):
247 self.__record_subtree_expansion(start_node_id = self.GetRootItem())
248 #--------------------------------------------------------
249 - def restore_expansion(self):
250 if len(self.expansion_state) == 0: 251 return True 252 self.__restore_subtree_expansion(start_node_id = self.GetRootItem())
253 #--------------------------------------------------------
254 - def print_expansion(self):
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 #--------------------------------------------------------
267 - def __record_subtree_expansion(self, start_node_id=None):
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 return
305 #--------------------------------------------------------
306 - def __restore_subtree_expansion(self, start_node_id=None):
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 return
323 # ========================================================================
324 -class cFileDropTarget(wx.FileDropTarget):
325 """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 #-----------------------------------------------
334 - def __init__(self, target):
335 wx.FileDropTarget.__init__(self) 336 self.target = target
337 #-----------------------------------------------
338 - def OnDropFiles(self, x, y, filenames):
339 self.target.add_filenames(filenames)
340 # ========================================================================
341 -def gm_show_error(aMessage = None, aTitle = None):
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 message = aMessage 351 print message
352 353 #dlg = wx.MessageDialog ( 354 # parent = None, 355 # message = aMessage, 356 # caption = aTitle, 357 # style = wx.OK | wx.ICON_ERROR | wx.STAY_ON_TOP 358 #) 359 #dlg.ShowModal() 360 #dlg.Destroy() 361 #return True 362 #-------------------------------------------------------------------------
363 -def gm_show_info(aMessage = None, aTitle = None):
364 if aMessage is None: 365 aMessage = _('programmer forgot to specify info message') 366 367 if aTitle is None: 368 aTitle = _('generic info message') 369 370 dlg = wx.MessageDialog ( 371 parent = None, 372 message = aMessage, 373 caption = aTitle, 374 style = wx.OK | wx.ICON_INFORMATION | wx.STAY_ON_TOP 375 ) 376 dlg.ShowModal() 377 dlg.Destroy() 378 return True
379 #-------------------------------------------------------------------------
380 -def gm_show_warning(aMessage=None, aTitle=None):
381 if aMessage is None: 382 aMessage = _('programmer forgot to specify warning') 383 384 if aTitle is None: 385 aTitle = _('generic warning message') 386 387 dlg = wx.MessageDialog ( 388 parent = None, 389 message = aMessage, 390 caption = aTitle, 391 style = wx.OK | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP 392 ) 393 dlg.ShowModal() 394 dlg.Destroy() 395 return True
396 #-------------------------------------------------------------------------
397 -def gm_show_question(aMessage='programmer forgot to specify question', aTitle='generic user question dialog', cancel_button=False):
398 if cancel_button: 399 style = wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION | wx.STAY_ON_TOP 400 else: 401 style = wx.YES_NO | wx.ICON_QUESTION | wx.STAY_ON_TOP 402 403 dlg = wx.MessageDialog ( 404 None, 405 aMessage, 406 aTitle, 407 style 408 ) 409 btn_pressed = dlg.ShowModal() 410 dlg.Destroy() 411 412 if btn_pressed == wx.ID_YES: 413 return True 414 elif btn_pressed == wx.ID_NO: 415 return False 416 else: 417 return None
418 #----------------------------------------------------------------------
419 -def makePageTitle(wizPg, title):
420 """ 421 Utility function to create the main sizer of a wizard's page. 422 423 @param wizPg The wizard page widget 424 @type wizPg A wx.WizardPageSimple instance 425 @param title The wizard page's descriptive title 426 @type title A StringType instance 427 """ 428 sizer = wx.BoxSizer(wx.VERTICAL) 429 wizPg.SetSizer(sizer) 430 title = wx.StaticText(wizPg, -1, title) 431 title.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD)) 432 sizer.Add(title, 0, wx.ALIGN_CENTRE|wx.ALL, 2) 433 sizer.Add(wx.StaticLine(wizPg, -1), 0, wx.EXPAND|wx.ALL, 2) 434 return sizer
435 #============================================================ 436 437 # ======================================================================== 438 # $Log: gmGuiHelpers.py,v $ 439 # Revision 1.106 2010-02-06 21:05:48 ncq 440 # - support data in multiline text ctrl 441 # 442 # Revision 1.105 2009/09/23 14:42:28 ncq 443 # - remove dead code 444 # 445 # Revision 1.104 2009/07/23 16:39:23 ncq 446 # - try to improve multiline text dialog 447 # 448 # Revision 1.103 2009/07/06 17:12:34 ncq 449 # - cleanup 450 # 451 # Revision 1.102 2009/05/18 15:31:29 ncq 452 # - checkbox_is_checked convenience wrapper 453 # 454 # Revision 1.101 2009/02/24 11:19:54 ncq 455 # - cleanup 456 # 457 # Revision 1.100 2009/01/15 11:37:06 ncq 458 # - no more save callback in multiline text editor 459 # 460 # Revision 1.99 2009/01/11 19:17:17 ncq 461 # - support new action buttons in text editor 462 # 463 # Revision 1.98 2008/12/18 21:28:26 ncq 464 # - cMultilineTextEntryDlg 465 # 466 # Revision 1.97 2008/11/21 13:06:09 ncq 467 # - cleanup 468 # 469 # Revision 1.96 2008/08/08 13:30:12 ncq 470 # - needs gmSurgery 471 # 472 # Revision 1.95 2008/08/06 13:21:42 ncq 473 # - add checkbox tooltip support to 2 button question dialog 474 # 475 # Revision 1.94 2008/07/07 11:36:44 ncq 476 # - just cleanup 477 # 478 # Revision 1.93 2008/06/24 13:59:18 ncq 479 # - properly handle default buttons, SetFocus, too, in 2/3ButtonDlg 480 # 481 # Revision 1.92 2008/05/13 14:12:33 ncq 482 # - factor out exception handling 483 # 484 # Revision 1.91 2008/04/12 19:18:48 ncq 485 # - listen to application_closing and ignore 486 # PyDeadObjectError when closing down 487 # 488 # Revision 1.90 2008/03/06 18:33:12 ncq 489 # - properly log exception information for unhandled exceptions 490 # 491 # Revision 1.89 2008/03/02 15:11:55 ncq 492 # - support sender email in bug reporting 493 # 494 # Revision 1.88 2008/02/26 16:27:20 ncq 495 # - cleanup exception handler 496 # - actually log exception :-( 497 # 498 # Revision 1.87 2008/02/25 17:34:39 ncq 499 # - use new logging 500 # - auto-enable debug mode on first unhandled exception 501 # 502 # Revision 1.86 2008/01/22 12:22:18 ncq 503 # - better layout of bug report email 504 # 505 # Revision 1.85 2008/01/16 19:38:43 ncq 506 # - configure_*() factored out 507 # 508 # Revision 1.84 2008/01/13 01:17:50 ncq 509 # - use log_stack_trace() 510 # - annouce completed bug report emailing 511 # 512 # Revision 1.83 2008/01/11 16:14:05 ncq 513 # - cleanup 514 # - use staff name/system account in log mailing 515 # 516 # Revision 1.82 2008/01/07 19:52:40 ncq 517 # - proper use of flush() 518 # 519 # Revision 1.81 2008/01/06 08:12:29 ncq 520 # - auto-switch to --debug on detecting an unhandled exception 521 # - always save user comment if there is any 522 # - always backup the log file with comment for later perusal 523 # 524 # Revision 1.80 2008/01/05 16:41:27 ncq 525 # - remove logging from gm_show_*() 526 # 527 # Revision 1.79 2007/12/24 23:31:24 shilbert 528 # - remove some dlg.SetFocus statements 529 # 530 # Revision 1.78 2007/12/23 12:10:49 ncq 531 # - cleanup 532 # 533 # Revision 1.77 2007/12/11 12:49:26 ncq 534 # - explicit signal handling 535 # 536 # Revision 1.76 2007/12/04 17:32:33 ncq 537 # - improved wording 538 # 539 # Revision 1.75 2007/12/04 17:08:14 ncq 540 # - allow editing bug report targets before sending 541 # 542 # Revision 1.74 2007/12/04 16:15:28 ncq 543 # - remove get_dbowner_connection() 544 # 545 # Revision 1.73 2007/12/04 15:17:39 ncq 546 # - start general purpose progress bar 547 # 548 # Revision 1.72 2007/11/21 13:31:53 ncq 549 # - use send_mail() in exception handling dialog 550 # 551 # Revision 1.71 2007/10/21 20:18:32 ncq 552 # - configure_string_option() 553 # 554 # Revision 1.70 2007/10/19 12:50:31 ncq 555 # - add configure_boolean_option() 556 # 557 # Revision 1.69 2007/10/11 12:01:51 ncq 558 # - make c3ButtonQuestionDlg() more robust in the face of no-default button def 559 # 560 # Revision 1.68 2007/09/25 20:44:23 ncq 561 # - support saving user comment in log file rescued on error 562 # 563 # Revision 1.67 2007/09/20 21:30:06 ncq 564 # - cGreetingEditorDlg 565 # 566 # Revision 1.66 2007/09/03 11:03:20 ncq 567 # - teach top level wx exception handler about ImportError 568 # 569 # Revision 1.65 2007/08/20 14:25:16 ncq 570 # - factor out bits of code out of the actual top level 571 # exception handler in a bid to make it more resilient 572 # 573 # Revision 1.64 2007/07/18 14:43:01 ncq 574 # - do away with accessing console as it often breaks 575 # 576 # Revision 1.63 2007/06/18 20:31:58 ncq 577 # - gm_Multi/SingleChoiceDlg moved to gmListWidgets 578 # 579 # Revision 1.62 2007/06/11 20:35:06 ncq 580 # - MSW does ref counting in Begin/EndBusyCursor 581 # - add gmMultiChoiceDialog 582 # 583 # Revision 1.61 2007/05/14 10:34:07 ncq 584 # - no more gm_statustext() 585 # 586 # Revision 1.60 2007/05/14 10:05:33 ncq 587 # - make "default" button definition optional 588 # 589 # Revision 1.59 2007/05/14 08:36:13 ncq 590 # - in c2ButtonQuestionDlg make keyword show_checkbox option defaulting to False 591 # 592 # Revision 1.58 2007/05/11 14:15:59 ncq 593 # - display help desk in exception handler 594 # - properly handle keep running/close client buttons 595 # 596 # Revision 1.57 2007/05/08 16:04:40 ncq 597 # - add wxPython based exception display handler 598 # 599 # Revision 1.56 2007/04/27 13:28:48 ncq 600 # - implement c2ButtonQuestionDlg 601 # 602 # Revision 1.55 2007/04/23 01:06:42 ncq 603 # - add password argument to get_dbowner_connection() 604 # 605 # Revision 1.54 2007/04/11 20:41:58 ncq 606 # - remove gm_icon() 607 # 608 # Revision 1.53 2007/04/09 22:02:40 ncq 609 # - fix docstring 610 # 611 # Revision 1.52 2007/03/18 14:07:14 ncq 612 # - factor out hook script running 613 # 614 # Revision 1.51 2007/03/02 15:32:56 ncq 615 # - turn gm_statustext() into signal sender with depreciation 616 # warning (should used gmDispatcher.send() now) 617 # 618 # Revision 1.50 2007/02/19 16:13:36 ncq 619 # - add run_hook_script() 620 # 621 # Revision 1.49 2007/02/18 16:57:38 ncq 622 # - make sure gm-dbo connections aren't returned from the pool 623 # 624 # Revision 1.48 2007/01/20 22:52:27 ncq 625 # - .KeyCode -> GetKeyCode() 626 # 627 # Revision 1.47 2007/01/16 13:59:51 ncq 628 # - protect against empty trees in expansion history mixin 629 # 630 # Revision 1.46 2007/01/15 13:04:25 ncq 631 # - c3ButtonQuestionDlg 632 # - remove cReturnTraversalTextCtrl 633 # 634 # Revision 1.45 2007/01/13 22:43:41 ncq 635 # - remove str() raising Unicode exceptions 636 # 637 # Revision 1.44 2007/01/13 22:19:37 ncq 638 # - cTreeExpansionHistoryMixin 639 # 640 # Revision 1.43 2007/01/12 13:09:46 ncq 641 # - cFileDropTarget 642 # 643 # Revision 1.42 2006/12/15 15:24:06 ncq 644 # - cleanup 645 # 646 # Revision 1.41 2006/11/24 09:53:24 ncq 647 # - gm_beep_statustext() -> gm_statustext(beep=True) 648 # 649 # Revision 1.40 2006/11/05 14:18:57 ncq 650 # - missing "style =" 651 # 652 # Revision 1.39 2006/10/24 13:23:31 ncq 653 # - use gmPG2.get_default_login() in get_dbowner_connection() 654 # 655 # Revision 1.38 2006/10/08 11:03:09 ncq 656 # - convert to gmPG2 657 # 658 # Revision 1.37 2006/09/03 11:29:30 ncq 659 # - add cancel_button argument to show_question 660 # 661 # Revision 1.36 2006/08/01 22:03:49 ncq 662 # - cleanup 663 # 664 # Revision 1.35 2006/06/20 09:42:42 ncq 665 # - cTextObjectValidator -> cTextWidgetValidator 666 # - add custom invalid message to text widget validator 667 # - variable renaming, cleanup 668 # - fix demographics validation 669 # 670 # Revision 1.34 2006/06/17 16:42:48 ncq 671 # - add get_dbowner_connection() 672 # 673 # Revision 1.33 2006/05/01 18:47:32 ncq 674 # - cleanup 675 # 676 # Revision 1.32 2006/01/15 13:19:16 shilbert 677 # - gm_SingleChoiceDialog was added 678 # - wxpython 2.6 does not support client data associated with item 679 # 680 # Revision 1.31 2005/10/27 21:37:29 shilbert 681 # fixed wxYES|NO into wx.YES|NO 682 # 683 # Revision 1.30 2005/10/11 21:14:10 ncq 684 # - remove out-of-place LogException() call 685 # 686 # Revision 1.29 2005/10/09 08:07:56 ihaywood 687 # a textctrl that uses return for navigation wx 2.6 only 688 # 689 # Revision 1.28 2005/10/04 13:09:49 sjtan 690 # correct syntax errors; get soap entry working again. 691 # 692 # Revision 1.27 2005/10/04 00:04:45 sjtan 693 # convert to wx.; catch some transitional errors temporarily 694 # 695 # Revision 1.26 2005/09/28 21:27:30 ncq 696 # - a lot of wx2.6-ification 697 # 698 # Revision 1.25 2005/09/28 15:57:48 ncq 699 # - a whole bunch of wx.Foo -> wx.Foo 700 # 701 # Revision 1.24 2005/09/26 18:01:50 ncq 702 # - use proper way to import wx26 vs wx2.4 703 # - note: THIS WILL BREAK RUNNING THE CLIENT IN SOME PLACES 704 # - time for fixup 705 # 706 # Revision 1.23 2005/09/12 15:09:42 ncq 707 # - cleanup 708 # 709 # Revision 1.22 2005/06/10 16:11:14 shilbert 710 # szr.AddWindow() -> Add() such that wx2.5 works 711 # 712 # Revision 1.21 2005/06/08 01:27:50 cfmoro 713 # Validator fix 714 # 715 # Revision 1.20 2005/05/05 06:27:52 ncq 716 # - add wx.STAY_ON_TOP in an effort to keep popups up front 717 # 718 # Revision 1.19 2005/04/24 14:48:57 ncq 719 # - improved wording 720 # 721 # Revision 1.18 2005/04/10 12:09:16 cfmoro 722 # GUI implementation of the first-basic (wizard) page for patient details input 723 # 724 # Revision 1.17 2005/03/06 09:21:08 ihaywood 725 # stole a couple of icons from Richard's demo code 726 # 727 # Revision 1.16 2004/12/21 21:00:35 ncq 728 # - if no status text handler available, dump to stdout 729 # 730 # Revision 1.15 2004/12/21 19:40:56 ncq 731 # - fix faulty LogException() usage 732 # 733 # Revision 1.14 2004/09/25 13:10:40 ncq 734 # - in gm_beep_statustext() make aMessage a defaulted keyword argument 735 # 736 # Revision 1.13 2004/08/19 13:56:51 ncq 737 # - added gm_show_warning() 738 # 739 # Revision 1.12 2004/08/18 10:18:42 ncq 740 # - added gm_show_info() 741 # 742 # Revision 1.11 2004/05/28 13:30:27 ncq 743 # - set_status_text -> _set_status_text so nobody 744 # gets the idea to use it directly 745 # 746 # Revision 1.10 2004/05/26 23:23:35 shilbert 747 # - import statement fixed 748 # 749 # Revision 1.9 2004/04/11 10:10:56 ncq 750 # - cleanup 751 # 752 # Revision 1.8 2004/04/10 01:48:31 ihaywood 753 # can generate referral letters, output to xdvi at present 754 # 755 # Revision 1.7 2004/03/04 19:46:54 ncq 756 # - switch to package based import: from Gnumed.foo import bar 757 # 758 # Revision 1.6 2003/12/29 16:49:18 uid66147 759 # - cleanup, gm_beep_statustext() 760 # 761 # Revision 1.5 2003/11/17 10:56:38 sjtan 762 # 763 # synced and commiting. 764 # 765 # Revision 1.1 2003/10/23 06:02:39 sjtan 766 # 767 # manual edit areas modelled after r.terry's specs. 768 # 769 # Revision 1.4 2003/08/26 12:35:52 ncq 770 # - properly replace \n\r 771 # 772 # Revision 1.3 2003/08/24 09:15:20 ncq 773 # - remove spurious self's 774 # 775 # Revision 1.2 2003/08/24 08:58:07 ncq 776 # - use gm_show_* 777 # 778 # Revision 1.1 2003/08/21 00:11:48 ncq 779 # - adds some widely used wxPython GUI helper functions 780 # 781