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