| 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 del kwargs['caption']
131 del kwargs['question']
132 del kwargs['button_defs']
133
134 try:
135 show_checkbox = kwargs['show_checkbox']
136 del kwargs['show_checkbox']
137 except KeyError:
138 show_checkbox = False
139
140 try:
141 checkbox_msg = kwargs['checkbox_msg']
142 del kwargs['checkbox_msg']
143 except KeyError:
144 checkbox_msg = None
145
146 try:
147 checkbox_tooltip = kwargs['checkbox_tooltip']
148 del kwargs['checkbox_tooltip']
149 except KeyError:
150 checkbox_tooltip = None
151
152 wxg3ButtonQuestionDlg.wxg3ButtonQuestionDlg.__init__(self, *args, **kwargs)
153
154 self.SetTitle(title = caption)
155 self._LBL_question.SetLabel(label = question)
156
157 if not show_checkbox:
158 self._CHBOX_dont_ask_again.Hide()
159 else:
160 if checkbox_msg is not None:
161 self._CHBOX_dont_ask_again.SetLabel(checkbox_msg)
162 if checkbox_tooltip is not None:
163 self._CHBOX_dont_ask_again.SetToolTipString(checkbox_tooltip)
164
165 buttons = [self._BTN_1, self._BTN_2, self._BTN_3]
166 for idx in range(len(button_defs)):
167 buttons[idx].SetLabel(label = button_defs[idx]['label'])
168 buttons[idx].SetToolTipString(button_defs[idx]['tooltip'])
169 try:
170 if button_defs[idx]['default'] is True:
171 buttons[idx].SetDefault()
172 buttons[idx].SetFocus()
173 except KeyError:
174 pass
175
176 self.Fit()
177 #--------------------------------------------------------
180 #--------------------------------------------------------
181 # event handlers
182 #--------------------------------------------------------
188 #--------------------------------------------------------
194 # ========================================================================
195 from Gnumed.wxGladeWidgets import wxgMultilineTextEntryDlg
196
198 """Editor for a bit of text."""
199
201
202 try:
203 title = kwargs['title']
204 del kwargs['title']
205 except KeyError:
206 title = None
207
208 try:
209 msg = kwargs['msg']
210 del kwargs['msg']
211 except KeyError:
212 msg = None
213
214 try:
215 data = kwargs['data']
216 del kwargs['data']
217 except KeyError:
218 data = None
219
220 try:
221 self.original_text = kwargs['text']
222 del kwargs['text']
223 except KeyError:
224 self.original_text = None
225
226 wxgMultilineTextEntryDlg.wxgMultilineTextEntryDlg.__init__(self, *args, **kwargs)
227
228 if title is not None:
229 self.SetTitle(title)
230
231 if self.original_text is not None:
232 self._TCTRL_text.SetValue(self.original_text)
233 self._BTN_restore.Enable(True)
234
235 if msg is None:
236 self._LBL_msg.Hide()
237 else:
238 self._LBL_msg.SetLabel(msg)
239 self.Layout()
240 self.Refresh()
241
242 if data is None:
243 self._TCTRL_data.Hide()
244 else:
245 self._TCTRL_data.SetValue(data)
246 self.Layout()
247 self.Refresh()
248
249 self._TCTRL_text.SetFocus()
250 #--------------------------------------------------------
251 # properties
252 #--------------------------------------------------------
254 return self._TCTRL_text.GetValue()
255
256 value = property(_get_value, lambda x:x)
257 #--------------------------------------------------------
260
261 is_user_formatted = property(_get_is_user_formatted, lambda x:x)
262 #--------------------------------------------------------
264 self._CHBOX_is_already_formatted.Enable(value)
265
266 enable_user_formatting = property(lambda x:x, _set_enable_user_formatting)
267 #--------------------------------------------------------
268 # event handlers
269 #--------------------------------------------------------
276 #--------------------------------------------------------
279 #--------------------------------------------------------
283 # ========================================================================
284 from Gnumed.business import gmSurgery
285 from Gnumed.wxGladeWidgets import wxgGreetingEditorDlg
286
288
290 wxgGreetingEditorDlg.wxgGreetingEditorDlg.__init__(self, *args, **kwargs)
291
292 self.surgery = gmSurgery.gmCurrentPractice()
293 self._TCTRL_message.SetValue(self.surgery.db_logon_banner)
294 #--------------------------------------------------------
295 # event handlers
296 #--------------------------------------------------------
303 # ========================================================================
305 """TreeCtrl mixin class to record expansion history."""
307 if not isinstance(self, wx.TreeCtrl):
308 raise TypeError('[%s]: mixin can only be applied to wx.TreeCtrl, not [%s]' % (cTreeExpansionHistoryMixin, self.__class__.__name__))
309 self.expansion_state = {}
310 #--------------------------------------------------------
311 # public API
312 #--------------------------------------------------------
315 #--------------------------------------------------------
317 if len(self.expansion_state) == 0:
318 return True
319 self.__restore_subtree_expansion(start_node_id = self.GetRootItem())
320 #--------------------------------------------------------
322 if len(self.expansion_state) == 0:
323 print "currently no expansion snapshot available"
324 return True
325 print "last snapshot of state of expansion"
326 print "-----------------------------------"
327 print "listing expanded nodes:"
328 for node_id in self.expansion_state.keys():
329 print "node ID:", node_id
330 print " selected:", self.expansion_state[node_id]
331 #--------------------------------------------------------
332 # internal API
333 #--------------------------------------------------------
335 """This records node expansion states based on the item label.
336
337 A side effect of this is that identically named items can
338 become unduly synchronized in their expand state after a
339 snapshot/restore cycle.
340
341 Better choices might be
342
343 id(item.GetPyData()) or
344 item.GetPyData().get_tree_uid()
345
346 where get_tree_uid():
347
348 '[%s:%s]' % (self.__class__.__name__, id(self))
349
350 or some such. This would survive renaming of the item.
351
352 For database items it may be useful to include the
353 primary key which would - contrary to id() - survive
354 reloads from the database.
355 """
356 # protect against empty tree where not even
357 # a root node exists
358 if not start_node_id.IsOk():
359 return True
360
361 if not self.IsExpanded(start_node_id):
362 return True
363
364 self.expansion_state[self.GetItemText(start_node_id)] = self.IsSelected(start_node_id)
365
366 child_id, cookie = self.GetFirstChild(start_node_id)
367 while child_id.IsOk():
368 self.__record_subtree_expansion(start_node_id = child_id)
369 child_id, cookie = self.GetNextChild(start_node_id, cookie)
370
371 return
372 #--------------------------------------------------------
374 start_node_label = self.GetItemText(start_node_id)
375 try:
376 node_selected = self.expansion_state[start_node_label]
377 except KeyError:
378 return
379
380 self.Expand(start_node_id)
381 if node_selected:
382 self.SelectItem(start_node_id)
383
384 child_id, cookie = self.GetFirstChild(start_node_id)
385 while child_id.IsOk():
386 self.__restore_subtree_expansion(start_node_id = child_id)
387 child_id, cookie = self.GetNextChild(start_node_id, cookie)
388
389 return
390 # ========================================================================
392 """Generic file drop target class.
393
394 Protocol:
395 Widgets being declared file drop targets
396 must provide the method:
397
398 add_filenames(filenames)
399 """
400 #-----------------------------------------------
402 wx.FileDropTarget.__init__(self)
403 self.target = target
404 _log.debug('setting up [%s] as file drop target', target)
405 #-----------------------------------------------
407 self.target.add_filenames(filenames)
408 # ========================================================================
410 img_data = None
411 bitmap = None
412 rescaled_height = height
413 try:
414 img_data = wx.Image(filename, wx.BITMAP_TYPE_ANY)
415 current_width = img_data.GetWidth()
416 current_height = img_data.GetHeight()
417 # if current_width == 0:
418 # current_width = 1
419 # if current_height == 0:
420 # current_height = 1
421 rescaled_width = (float(current_width) / current_height) * rescaled_height
422 img_data.Rescale(rescaled_width, rescaled_height, quality = wx.IMAGE_QUALITY_HIGH) # w, h
423 bitmap = wx.BitmapFromImage(img_data)
424 del img_data
425 except StandardError:
426 _log.exception('cannot load image from [%s]', filename)
427 del img_data
428 del bitmap
429 return None
430
431 return bitmap
432 # ========================================================================
434 if aMessage is None:
435 aMessage = _('programmer forgot to specify error message')
436
437 aMessage += _("\n\nPlease consult the error log for all the gory details !")
438
439 if aTitle is None:
440 aTitle = _('generic error message')
441
442 dlg = wx.MessageDialog (
443 parent = None,
444 message = aMessage,
445 caption = aTitle,
446 style = wx.OK | wx.ICON_ERROR | wx.STAY_ON_TOP
447 )
448 dlg.ShowModal()
449 dlg.Destroy()
450 return True
451 #-------------------------------------------------------------------------
453 if aMessage is None:
454 aMessage = _('programmer forgot to specify info message')
455
456 if aTitle is None:
457 aTitle = _('generic info message')
458
459 dlg = wx.MessageDialog (
460 parent = None,
461 message = aMessage,
462 caption = aTitle,
463 style = wx.OK | wx.ICON_INFORMATION | wx.STAY_ON_TOP
464 )
465 dlg.ShowModal()
466 dlg.Destroy()
467 return True
468 #-------------------------------------------------------------------------
470 if aMessage is None:
471 aMessage = _('programmer forgot to specify warning')
472
473 if aTitle is None:
474 aTitle = _('generic warning message')
475
476 dlg = wx.MessageDialog (
477 parent = None,
478 message = aMessage,
479 caption = aTitle,
480 style = wx.OK | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP
481 )
482 dlg.ShowModal()
483 dlg.Destroy()
484 return True
485 #-------------------------------------------------------------------------
486 -def gm_show_question(aMessage='programmer forgot to specify question', aTitle='generic user question dialog', cancel_button=False, question=None, title=None):
487 if cancel_button:
488 style = wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION | wx.STAY_ON_TOP
489 else:
490 style = wx.YES_NO | wx.ICON_QUESTION | wx.STAY_ON_TOP
491
492 if question is None:
493 question = aMessage
494 if title is None:
495 title = aTitle
496
497 dlg = wx.MessageDialog(None, question, title, style)
498 btn_pressed = dlg.ShowModal()
499 dlg.Destroy()
500
501 if btn_pressed == wx.ID_YES:
502 return True
503 elif btn_pressed == wx.ID_NO:
504 return False
505 else:
506 return None
507 #======================================================================
508 if __name__ == '__main__':
509
510 if len(sys.argv) < 2:
511 sys.exit()
512
513 if sys.argv[1] != 'test':
514 sys.exit()
515
516 from Gnumed.pycommon import gmI18N
517 gmI18N.activate_locale()
518 gmI18N.install_domain(domain='gnumed')
519
520 #------------------------------------------------------------------
522 app = wx.App()
523 img = file2scaled_image(filename = sys.argv[2])
524 print img
525 print img.Height
526 print img.Width
527 #------------------------------------------------------------------
529 app = wx.PyWidgetTester(size = (200, 50))
530 prw = cThreeValuedLogicPhraseWheel(parent = app.frame, id = -1)
531 app.frame.Show(True)
532 app.MainLoop()
533
534 return True
535 #------------------------------------------------------------------
536 #test_scale_img()
537 test_sql_logic_prw()
538
539 #======================================================================
540
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Mon Jun 25 03:59:07 2012 | http://epydoc.sourceforge.net |