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  # ======================================================================== 
  8  __version__ = "$Revision: 1.106 $" 
  9  __author__  = "K. Hilbert <Karsten.Hilbert@gmx.net>" 
 10  __license__ = "GPL v2 or later (details at http://www.gnu.org)" 
 11   
 12  import os 
 13   
 14   
 15  import wx 
 16   
 17   
 18  from Gnumed.business import gmPraxis 
 19  from Gnumed.wxGladeWidgets import wxg3ButtonQuestionDlg, wxg2ButtonQuestionDlg, wxgGreetingEditorDlg 
 20   
 21  # ======================================================================== 
22 -class c2ButtonQuestionDlg(wxg2ButtonQuestionDlg.wxg2ButtonQuestionDlg):
23
24 - def __init__(self, *args, **kwargs):
25 26 caption = kwargs['caption'] 27 question = kwargs['question'] 28 button_defs = kwargs['button_defs'][:2] 29 del kwargs['caption'] 30 del kwargs['question'] 31 del kwargs['button_defs'] 32 33 try: 34 show_checkbox = kwargs['show_checkbox'] 35 del kwargs['show_checkbox'] 36 except KeyError: 37 show_checkbox = False 38 39 try: 40 checkbox_msg = kwargs['checkbox_msg'] 41 del kwargs['checkbox_msg'] 42 except KeyError: 43 checkbox_msg = None 44 45 try: 46 checkbox_tooltip = kwargs['checkbox_tooltip'] 47 del kwargs['checkbox_tooltip'] 48 except KeyError: 49 checkbox_tooltip = None 50 51 wxg2ButtonQuestionDlg.wxg2ButtonQuestionDlg.__init__(self, *args, **kwargs) 52 53 self.SetTitle(title = caption) 54 self._LBL_question.SetLabel(label = question) 55 56 if not show_checkbox: 57 self._CHBOX_dont_ask_again.Hide() 58 else: 59 if checkbox_msg is not None: 60 self._CHBOX_dont_ask_again.SetLabel(checkbox_msg) 61 if checkbox_tooltip is not None: 62 self._CHBOX_dont_ask_again.SetToolTipString(checkbox_tooltip) 63 64 buttons = [self._BTN_1, self._BTN_2] 65 for idx in range(len(button_defs)): 66 buttons[idx].SetLabel(label = button_defs[idx]['label']) 67 buttons[idx].SetToolTipString(button_defs[idx]['tooltip']) 68 try: 69 if button_defs[idx]['default'] is True: 70 buttons[idx].SetDefault() 71 buttons[idx].SetFocus() 72 except KeyError: 73 pass 74 75 self.Fit()
76 #--------------------------------------------------------
77 - def checkbox_is_checked(self):
78 return self._CHBOX_dont_ask_again.IsChecked()
79 #-------------------------------------------------------- 80 # event handlers 81 #--------------------------------------------------------
82 - def _on_BTN_1_pressed(self, evt):
83 if self.IsModal(): 84 self.EndModal(wx.ID_YES) 85 else: 86 self.Close()
87 #--------------------------------------------------------
88 - def _on_BTN_2_pressed(self, evt):
89 if self.IsModal(): 90 self.EndModal(wx.ID_NO) 91 else: 92 self.Close()
93 # ========================================================================
94 -class c3ButtonQuestionDlg(wxg3ButtonQuestionDlg.wxg3ButtonQuestionDlg):
95
96 - def __init__(self, *args, **kwargs):
97 98 caption = kwargs['caption'] 99 question = kwargs['question'] 100 button_defs = kwargs['button_defs'][:3] 101 102 del kwargs['caption'] 103 del kwargs['question'] 104 del kwargs['button_defs'] 105 106 wxg3ButtonQuestionDlg.wxg3ButtonQuestionDlg.__init__(self, *args, **kwargs) 107 108 self.SetTitle(title = caption) 109 self._LBL_question.SetLabel(label = question) 110 111 buttons = [self._BTN_1, self._BTN_2, self._BTN_3] 112 for idx in range(len(button_defs)): 113 buttons[idx].SetLabel(label = button_defs[idx]['label']) 114 buttons[idx].SetToolTipString(button_defs[idx]['tooltip']) 115 try: 116 if button_defs[idx]['default'] is True: 117 buttons[idx].SetDefault() 118 buttons[idx].SetFocus() 119 except KeyError: 120 pass 121 122 self.Fit()
123 #-------------------------------------------------------- 124 # event handlers 125 #--------------------------------------------------------
126 - def _on_BTN_1_pressed(self, evt):
127 if self.IsModal(): 128 self.EndModal(wx.ID_YES) 129 else: 130 self.Close()
131 #--------------------------------------------------------
132 - def _on_BTN_2_pressed(self, evt):
133 if self.IsModal(): 134 self.EndModal(wx.ID_NO) 135 else: 136 self.Close()
137 # ======================================================================== 138 from Gnumed.wxGladeWidgets import wxgMultilineTextEntryDlg 139
140 -class cMultilineTextEntryDlg(wxgMultilineTextEntryDlg.wxgMultilineTextEntryDlg):
141 """Editor for a bit of text.""" 142
143 - def __init__(self, *args, **kwargs):
144 145 try: 146 title = kwargs['title'] 147 del kwargs['title'] 148 except KeyError: 149 title = None 150 151 try: 152 msg = kwargs['msg'] 153 del kwargs['msg'] 154 except KeyError: 155 msg = None 156 157 try: 158 data = kwargs['data'] 159 del kwargs['data'] 160 except KeyError: 161 data = None 162 163 try: 164 self.original_text = kwargs['text'] 165 del kwargs['text'] 166 except KeyError: 167 self.original_text = None 168 169 wxgMultilineTextEntryDlg.wxgMultilineTextEntryDlg.__init__(self, *args, **kwargs) 170 171 if title is not None: 172 self.SetTitle(title) 173 174 if self.original_text is not None: 175 self._TCTRL_text.SetValue(self.original_text) 176 self._BTN_restore.Enable(True) 177 178 if msg is None: 179 self._LBL_msg.Hide() 180 else: 181 self._LBL_msg.SetLabel(msg) 182 self.Layout() 183 self.Refresh() 184 185 if data is None: 186 self._TCTRL_data.Hide() 187 else: 188 self._TCTRL_data.SetValue(data) 189 self.Layout() 190 self.Refresh()
191 #--------------------------------------------------------
192 - def _get_value(self):
193 return self._TCTRL_text.GetValue()
194 195 value = property(_get_value, lambda x:x) 196 #-------------------------------------------------------- 197 # event handlers 198 #--------------------------------------------------------
199 - def _on_save_button_pressed(self, evt):
200 201 if self.IsModal(): 202 self.EndModal(wx.ID_SAVE) 203 else: 204 self.Close()
205 #--------------------------------------------------------
206 - def _on_clear_button_pressed(self, evt):
207 self._TCTRL_text.SetValue(u'')
208 #--------------------------------------------------------
209 - def _on_restore_button_pressed(self, evt):
210 if self.original_text is not None: 211 self._TCTRL_text.SetValue(self.original_text)
212 # ========================================================================
213 -class cGreetingEditorDlg(wxgGreetingEditorDlg.wxgGreetingEditorDlg):
214
215 - def __init__(self, *args, **kwargs):
216 wxgGreetingEditorDlg.wxgGreetingEditorDlg.__init__(self, *args, **kwargs) 217 218 self.praxis = gmPraxis.gmCurrentPraxisBranch() 219 self._TCTRL_message.SetValue(self.praxis.db_logon_banner)
220 #-------------------------------------------------------- 221 # event handlers 222 #--------------------------------------------------------
223 - def _on_save_button_pressed(self, evt):
224 self.praxis.db_logon_banner = self._TCTRL_message.GetValue().strip() 225 if self.IsModal(): 226 self.EndModal(wx.ID_SAVE) 227 else: 228 self.Close()
229 # ========================================================================
230 -class cTreeExpansionHistoryMixin:
231 """TreeCtrl mixin class to record expansion history."""
232 - def __init__(self):
233 if not isinstance(self, wx.TreeCtrl): 234 raise TypeError('[%s]: mixin can only be applied to wx.TreeCtrl, not [%s]' % (cTreeExpansionHistoryMixin, self.__class__.__name__)) 235 self.expansion_state = {}
236 #-------------------------------------------------------- 237 # public API 238 #--------------------------------------------------------
239 - def snapshot_expansion(self):
240 self.__record_subtree_expansion(start_node_id = self.GetRootItem())
241 #--------------------------------------------------------
242 - def restore_expansion(self):
243 if len(self.expansion_state) == 0: 244 return True 245 self.__restore_subtree_expansion(start_node_id = self.GetRootItem())
246 #--------------------------------------------------------
247 - def print_expansion(self):
248 if len(self.expansion_state) == 0: 249 print "currently no expansion snapshot available" 250 return True 251 print "last snapshot of state of expansion" 252 print "-----------------------------------" 253 print "listing expanded nodes:" 254 for node_id in self.expansion_state.keys(): 255 print "node ID:", node_id 256 print " selected:", self.expansion_state[node_id]
257 #-------------------------------------------------------- 258 # internal API 259 #--------------------------------------------------------
260 - def __record_subtree_expansion(self, start_node_id=None):
261 """This records node expansion states based on the item label. 262 263 A side effect of this is that identically named items can 264 become unduly synchronized in their expand state after a 265 snapshot/restore cycle. 266 267 Better choices might be 268 269 id(item.GetPyData()) or 270 item.GetPyData().get_tree_uid() 271 272 where get_tree_uid(): 273 274 '[%s:%s]' % (self.__class__.__name__, id(self)) 275 276 or some such. This would survive renaming of the item. 277 278 For database items it may be useful to include the 279 primary key which would - contrary to id() - survive 280 reloads from the database. 281 """ 282 # protect against empty tree where not even 283 # a root node exists 284 if not start_node_id.IsOk(): 285 return True 286 287 if not self.IsExpanded(start_node_id): 288 return True 289 290 self.expansion_state[self.GetItemText(start_node_id)] = self.IsSelected(start_node_id) 291 292 child_id, cookie = self.GetFirstChild(start_node_id) 293 while child_id.IsOk(): 294 self.__record_subtree_expansion(start_node_id = child_id) 295 child_id, cookie = self.GetNextChild(start_node_id, cookie) 296 297 return
298 #--------------------------------------------------------
299 - def __restore_subtree_expansion(self, start_node_id=None):
300 start_node_label = self.GetItemText(start_node_id) 301 try: 302 node_selected = self.expansion_state[start_node_label] 303 except KeyError: 304 return 305 306 self.Expand(start_node_id) 307 if node_selected: 308 self.SelectItem(start_node_id) 309 310 child_id, cookie = self.GetFirstChild(start_node_id) 311 while child_id.IsOk(): 312 self.__restore_subtree_expansion(start_node_id = child_id) 313 child_id, cookie = self.GetNextChild(start_node_id, cookie) 314 315 return
316 # ========================================================================
317 -class cFileDropTarget(wx.FileDropTarget):
318 """Generic file drop target class. 319 320 Protocol: 321 Widgets being declared file drop targets 322 must provide the method: 323 324 add_filenames(filenames) 325 """ 326 #-----------------------------------------------
327 - def __init__(self, target):
328 wx.FileDropTarget.__init__(self) 329 self.target = target
330 #-----------------------------------------------
331 - def OnDropFiles(self, x, y, filenames):
332 self.target.add_filenames(filenames)
333 # ========================================================================
334 -def gm_show_error(aMessage = None, aTitle = None):
335 if aMessage is None: 336 aMessage = _('programmer forgot to specify error message') 337 338 aMessage += _("\n\nPlease consult the error log for all the gory details !") 339 340 if aTitle is None: 341 aTitle = _('generic error message') 342 343 message = aMessage 344 print message
345 346 #dlg = wx.MessageDialog ( 347 # parent = None, 348 # message = aMessage, 349 # caption = aTitle, 350 # style = wx.OK | wx.ICON_ERROR | wx.STAY_ON_TOP 351 #) 352 #dlg.ShowModal() 353 #dlg.Destroy() 354 #return True 355 #-------------------------------------------------------------------------
356 -def gm_show_info(aMessage = None, aTitle = None):
357 if aMessage is None: 358 aMessage = _('programmer forgot to specify info message') 359 360 if aTitle is None: 361 aTitle = _('generic info message') 362 363 dlg = wx.MessageDialog ( 364 parent = None, 365 message = aMessage, 366 caption = aTitle, 367 style = wx.OK | wx.ICON_INFORMATION | wx.STAY_ON_TOP 368 ) 369 dlg.ShowModal() 370 dlg.Destroy() 371 return True
372 #-------------------------------------------------------------------------
373 -def gm_show_warning(aMessage=None, aTitle=None):
374 if aMessage is None: 375 aMessage = _('programmer forgot to specify warning') 376 377 if aTitle is None: 378 aTitle = _('generic warning message') 379 380 dlg = wx.MessageDialog ( 381 parent = None, 382 message = aMessage, 383 caption = aTitle, 384 style = wx.OK | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP 385 ) 386 dlg.ShowModal() 387 dlg.Destroy() 388 return True
389 #-------------------------------------------------------------------------
390 -def gm_show_question(aMessage='programmer forgot to specify question', aTitle='generic user question dialog', cancel_button=False):
391 if cancel_button: 392 style = wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION | wx.STAY_ON_TOP 393 else: 394 style = wx.YES_NO | wx.ICON_QUESTION | wx.STAY_ON_TOP 395 396 dlg = wx.MessageDialog ( 397 None, 398 aMessage, 399 aTitle, 400 style 401 ) 402 btn_pressed = dlg.ShowModal() 403 dlg.Destroy() 404 405 if btn_pressed == wx.ID_YES: 406 return True 407 elif btn_pressed == wx.ID_NO: 408 return False 409 else: 410 return None
411 #----------------------------------------------------------------------
412 -def makePageTitle(wizPg, title):
413 """ 414 Utility function to create the main sizer of a wizard's page. 415 416 @param wizPg The wizard page widget 417 @type wizPg A wx.WizardPageSimple instance 418 @param title The wizard page's descriptive title 419 @type title A StringType instance 420 """ 421 sizer = wx.BoxSizer(wx.VERTICAL) 422 wizPg.SetSizer(sizer) 423 title = wx.StaticText(wizPg, -1, title) 424 title.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD)) 425 sizer.Add(title, 0, wx.ALIGN_CENTRE|wx.ALL, 2) 426 sizer.Add(wx.StaticLine(wizPg, -1), 0, wx.EXPAND|wx.ALL, 2) 427 return sizer
428 #============================================================ 429