| Home | 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 # ========================================================================
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 import logging
14 import sys
15
16
17 import wx
18
19
20 if __name__ == '__main__':
21 sys.path.insert(0, '../../')
22 from Gnumed.pycommon import gmMatchProvider
23 from Gnumed.wxpython import gmPhraseWheel
24
25
26 _log = logging.getLogger('gm.main')
27 # ========================================================================
29
31
32 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
33
34 items = [
35 {'list_label': _('Yes: + / ! / 1'), 'field_label': _('yes'), 'data': True, 'weight': 0},
36 {'list_label': _('No: - / 0'), 'field_label': _('no'), 'data': False, 'weight': 1},
37 {'list_label': _('Unknown: ?'), 'field_label': _('unknown'), 'data': None, 'weight': 2},
38 ]
39 mp = gmMatchProvider.cMatchProvider_FixedList(items)
40 mp.setThresholds(1, 1, 2)
41 mp.word_separators = '[ :/]+'
42 mp.word_separators = None
43 mp.ignored_chars = r"[.'\\(){}\[\]<>~#*$%^_=&@\t23456]+" + r'"'
44
45 self.matcher = mp
46 # ========================================================================
47 from Gnumed.wxGladeWidgets import wxg2ButtonQuestionDlg
48
50
52
53 caption = kwargs['caption']
54 question = kwargs['question']
55 button_defs = kwargs['button_defs'][:2]
56 del kwargs['caption']
57 del kwargs['question']
58 del kwargs['button_defs']
59
60 try:
61 show_checkbox = kwargs['show_checkbox']
62 del kwargs['show_checkbox']
63 except KeyError:
64 show_checkbox = False
65
66 try:
67 checkbox_msg = kwargs['checkbox_msg']
68 del kwargs['checkbox_msg']
69 except KeyError:
70 checkbox_msg = None
71
72 try:
73 checkbox_tooltip = kwargs['checkbox_tooltip']
74 del kwargs['checkbox_tooltip']
75 except KeyError:
76 checkbox_tooltip = None
77
78 wxg2ButtonQuestionDlg.wxg2ButtonQuestionDlg.__init__(self, *args, **kwargs)
79
80 self.SetTitle(title = caption)
81 self._LBL_question.SetLabel(label = question)
82
83 if not show_checkbox:
84 self._CHBOX_dont_ask_again.Hide()
85 else:
86 if checkbox_msg is not None:
87 self._CHBOX_dont_ask_again.SetLabel(checkbox_msg)
88 if checkbox_tooltip is not None:
89 self._CHBOX_dont_ask_again.SetToolTipString(checkbox_tooltip)
90
91 buttons = [self._BTN_1, self._BTN_2]
92 for idx in range(len(button_defs)):
93 buttons[idx].SetLabel(label = button_defs[idx]['label'])
94 buttons[idx].SetToolTipString(button_defs[idx]['tooltip'])
95 try:
96 if button_defs[idx]['default'] is True:
97 buttons[idx].SetDefault()
98 buttons[idx].SetFocus()
99 except KeyError:
100 pass
101
102 self.Fit()
103 #--------------------------------------------------------
106 #--------------------------------------------------------
107 # event handlers
108 #--------------------------------------------------------
114 #--------------------------------------------------------
120 # ========================================================================
121 from Gnumed.wxGladeWidgets import wxg3ButtonQuestionDlg
122
124
126
127 caption = kwargs['caption']
128 question = kwargs['question']
129 button_defs = kwargs['button_defs'][:3]
130
131 del kwargs['caption']
132 del kwargs['question']
133 del kwargs['button_defs']
134
135 wxg3ButtonQuestionDlg.wxg3ButtonQuestionDlg.__init__(self, *args, **kwargs)
136
137 self.SetTitle(title = caption)
138 self._LBL_question.SetLabel(label = question)
139
140 buttons = [self._BTN_1, self._BTN_2, self._BTN_3]
141 for idx in range(len(button_defs)):
142 buttons[idx].SetLabel(label = button_defs[idx]['label'])
143 buttons[idx].SetToolTipString(button_defs[idx]['tooltip'])
144 try:
145 if button_defs[idx]['default'] is True:
146 buttons[idx].SetDefault()
147 buttons[idx].SetFocus()
148 except KeyError:
149 pass
150
151 self.Fit()
152 #--------------------------------------------------------
153 # event handlers
154 #--------------------------------------------------------
160 #--------------------------------------------------------
166 # ========================================================================
167 from Gnumed.wxGladeWidgets import wxgMultilineTextEntryDlg
168
170 """Editor for a bit of text."""
171
173
174 try:
175 title = kwargs['title']
176 del kwargs['title']
177 except KeyError:
178 title = None
179
180 try:
181 msg = kwargs['msg']
182 del kwargs['msg']
183 except KeyError:
184 msg = None
185
186 try:
187 data = kwargs['data']
188 del kwargs['data']
189 except KeyError:
190 data = None
191
192 try:
193 self.original_text = kwargs['text']
194 del kwargs['text']
195 except KeyError:
196 self.original_text = None
197
198 wxgMultilineTextEntryDlg.wxgMultilineTextEntryDlg.__init__(self, *args, **kwargs)
199
200 if title is not None:
201 self.SetTitle(title)
202
203 if self.original_text is not None:
204 self._TCTRL_text.SetValue(self.original_text)
205 self._BTN_restore.Enable(True)
206
207 if msg is None:
208 self._LBL_msg.Hide()
209 else:
210 self._LBL_msg.SetLabel(msg)
211 self.Layout()
212 self.Refresh()
213
214 if data is None:
215 self._TCTRL_data.Hide()
216 else:
217 self._TCTRL_data.SetValue(data)
218 self.Layout()
219 self.Refresh()
220 #--------------------------------------------------------
221 # properties
222 #--------------------------------------------------------
224 return self._TCTRL_text.GetValue()
225
226 value = property(_get_value, lambda x:x)
227 #--------------------------------------------------------
230
231 is_user_formatted = property(_get_is_user_formatted, lambda x:x)
232 #--------------------------------------------------------
234 self._CHBOX_is_already_formatted.Enable(value)
235
236 enable_user_formatting = property(lambda x:x, _set_enable_user_formatting)
237 #--------------------------------------------------------
238 # event handlers
239 #--------------------------------------------------------
246 #--------------------------------------------------------
249 #--------------------------------------------------------
253 # ========================================================================
254 from Gnumed.business import gmSurgery
255 from Gnumed.wxGladeWidgets import wxgGreetingEditorDlg
256
258
260 wxgGreetingEditorDlg.wxgGreetingEditorDlg.__init__(self, *args, **kwargs)
261
262 self.surgery = gmSurgery.gmCurrentPractice()
263 self._TCTRL_message.SetValue(self.surgery.db_logon_banner)
264 #--------------------------------------------------------
265 # event handlers
266 #--------------------------------------------------------
273 # ========================================================================
275 """TreeCtrl mixin class to record expansion history."""
277 if not isinstance(self, wx.TreeCtrl):
278 raise TypeError('[%s]: mixin can only be applied to wx.TreeCtrl, not [%s]' % (cTreeExpansionHistoryMixin, self.__class__.__name__))
279 self.expansion_state = {}
280 #--------------------------------------------------------
281 # public API
282 #--------------------------------------------------------
285 #--------------------------------------------------------
287 if len(self.expansion_state) == 0:
288 return True
289 self.__restore_subtree_expansion(start_node_id = self.GetRootItem())
290 #--------------------------------------------------------
292 if len(self.expansion_state) == 0:
293 print "currently no expansion snapshot available"
294 return True
295 print "last snapshot of state of expansion"
296 print "-----------------------------------"
297 print "listing expanded nodes:"
298 for node_id in self.expansion_state.keys():
299 print "node ID:", node_id
300 print " selected:", self.expansion_state[node_id]
301 #--------------------------------------------------------
302 # internal API
303 #--------------------------------------------------------
305 """This records node expansion states based on the item label.
306
307 A side effect of this is that identically named items can
308 become unduly synchronized in their expand state after a
309 snapshot/restore cycle.
310
311 Better choices might be
312
313 id(item.GetPyData()) or
314 item.GetPyData().get_tree_uid()
315
316 where get_tree_uid():
317
318 '[%s:%s]' % (self.__class__.__name__, id(self))
319
320 or some such. This would survive renaming of the item.
321
322 For database items it may be useful to include the
323 primary key which would - contrary to id() - survive
324 reloads from the database.
325 """
326 # protect against empty tree where not even
327 # a root node exists
328 if not start_node_id.IsOk():
329 return True
330
331 if not self.IsExpanded(start_node_id):
332 return True
333
334 self.expansion_state[self.GetItemText(start_node_id)] = self.IsSelected(start_node_id)
335
336 child_id, cookie = self.GetFirstChild(start_node_id)
337 while child_id.IsOk():
338 self.__record_subtree_expansion(start_node_id = child_id)
339 child_id, cookie = self.GetNextChild(start_node_id, cookie)
340
341 return
342 #--------------------------------------------------------
344 start_node_label = self.GetItemText(start_node_id)
345 try:
346 node_selected = self.expansion_state[start_node_label]
347 except KeyError:
348 return
349
350 self.Expand(start_node_id)
351 if node_selected:
352 self.SelectItem(start_node_id)
353
354 child_id, cookie = self.GetFirstChild(start_node_id)
355 while child_id.IsOk():
356 self.__restore_subtree_expansion(start_node_id = child_id)
357 child_id, cookie = self.GetNextChild(start_node_id, cookie)
358
359 return
360 # ========================================================================
362 """Generic file drop target class.
363
364 Protocol:
365 Widgets being declared file drop targets
366 must provide the method:
367
368 add_filenames(filenames)
369 """
370 #-----------------------------------------------
372 wx.FileDropTarget.__init__(self)
373 self.target = target
374 _log.debug('setting up [%s] as file drop target', target)
375 #-----------------------------------------------
377 self.target.add_filenames(filenames)
378 # ========================================================================
380 img_data = None
381 bitmap = None
382 rescaled_height = height
383 try:
384 img_data = wx.Image(filename, wx.BITMAP_TYPE_ANY)
385 current_width = img_data.GetWidth()
386 current_height = img_data.GetHeight()
387 # if current_width == 0:
388 # current_width = 1
389 # if current_height == 0:
390 # current_height = 1
391 rescaled_width = (float(current_width) / current_height) * rescaled_height
392 img_data.Rescale(rescaled_width, rescaled_height, quality = wx.IMAGE_QUALITY_HIGH) # w, h
393 bitmap = wx.BitmapFromImage(img_data)
394 del img_data
395 except StandardError:
396 _log.exception('cannot load image from [%s]', filename)
397 del img_data
398 del bitmap
399 return None
400
401 return bitmap
402 # ========================================================================
404 if aMessage is None:
405 aMessage = _('programmer forgot to specify error message')
406
407 aMessage += _("\n\nPlease consult the error log for all the gory details !")
408
409 if aTitle is None:
410 aTitle = _('generic error message')
411
412 dlg = wx.MessageDialog (
413 parent = None,
414 message = aMessage,
415 caption = aTitle,
416 style = wx.OK | wx.ICON_ERROR | wx.STAY_ON_TOP
417 )
418 dlg.ShowModal()
419 dlg.Destroy()
420 return True
421 #-------------------------------------------------------------------------
423 if aMessage is None:
424 aMessage = _('programmer forgot to specify info message')
425
426 if aTitle is None:
427 aTitle = _('generic info message')
428
429 dlg = wx.MessageDialog (
430 parent = None,
431 message = aMessage,
432 caption = aTitle,
433 style = wx.OK | wx.ICON_INFORMATION | wx.STAY_ON_TOP
434 )
435 dlg.ShowModal()
436 dlg.Destroy()
437 return True
438 #-------------------------------------------------------------------------
440 if aMessage is None:
441 aMessage = _('programmer forgot to specify warning')
442
443 if aTitle is None:
444 aTitle = _('generic warning message')
445
446 dlg = wx.MessageDialog (
447 parent = None,
448 message = aMessage,
449 caption = aTitle,
450 style = wx.OK | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP
451 )
452 dlg.ShowModal()
453 dlg.Destroy()
454 return True
455 #-------------------------------------------------------------------------
456 -def gm_show_question(aMessage='programmer forgot to specify question', aTitle='generic user question dialog', cancel_button=False, question=None, title=None):
457 if cancel_button:
458 style = wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION | wx.STAY_ON_TOP
459 else:
460 style = wx.YES_NO | wx.ICON_QUESTION | wx.STAY_ON_TOP
461
462 if question is None:
463 question = aMessage
464 if title is None:
465 title = aTitle
466
467 dlg = wx.MessageDialog(None, question, title, style)
468 btn_pressed = dlg.ShowModal()
469 dlg.Destroy()
470
471 if btn_pressed == wx.ID_YES:
472 return True
473 elif btn_pressed == wx.ID_NO:
474 return False
475 else:
476 return None
477 #======================================================================
478 if __name__ == '__main__':
479
480 if len(sys.argv) < 2:
481 sys.exit()
482
483 if sys.argv[1] != 'test':
484 sys.exit()
485
486 from Gnumed.pycommon import gmI18N
487 gmI18N.activate_locale()
488 gmI18N.install_domain(domain='gnumed')
489
490 #------------------------------------------------------------------
492 app = wx.App()
493 img = file2scaled_image(filename = sys.argv[2])
494 print img
495 print img.Height
496 print img.Width
497 #------------------------------------------------------------------
499 app = wx.PyWidgetTester(size = (200, 50))
500 prw = cThreeValuedLogicPhraseWheel(parent = app.frame, id = -1)
501 app.frame.Show(True)
502 app.MainLoop()
503
504 return True
505 #------------------------------------------------------------------
506 #test_scale_img()
507 test_sql_logic_prw()
508
509 #======================================================================
510
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Mon Dec 5 04:00:12 2011 | http://epydoc.sourceforge.net |