| Home | Trees | Indices | Help |
|
|---|
|
|
1 # -*- coding: iso-8859-1 -*-
2 """GNUmed date input widget
3
4 All GNUmed date input should happen via classes in
5 this module. Initially this is just a plain text box
6 but using this throughout GNUmed will allow us to
7 transparently add features.
8
9 @copyright: author(s)
10 """
11 #==============================================================================
12 # $Source: /home/ncq/Projekte/cvs2git/vcs-mirror/gnumed/gnumed/client/wxpython/gmDateTimeInput.py,v $
13 # $Id: gmDateTimeInput.py,v 1.66 2009-12-21 15:04:57 ncq Exp $
14 __version__ = "$Revision: 1.66 $"
15 __author__ = "K. Hilbert <Karsten.Hilbert@gmx.net>"
16 __licence__ = "GPL (details at http://www.gnu.org)"
17
18 import re, string, sys, time, datetime as pyDT, logging
19
20
21 import mx.DateTime as mxDT, wx
22
23
24 # GNUmed specific
25 if __name__ == '__main__':
26 sys.path.insert(0, '../../')
27 from Gnumed.pycommon import gmMatchProvider, gmDateTime
28 from Gnumed.wxpython import gmPhraseWheel, gmGuiHelpers
29
30 _log = logging.getLogger('gm.ui')
31
32 #============================================================
35 self.__allow_past = 1
36 self.__shifting_base = None
37
38 gmMatchProvider.cMatchProvider.__init__(self)
39
40 self.setThresholds(aPhrase = 1, aWord = 998, aSubstring = 999)
41 self.word_separators = None
42 # self.ignored_chars("""[?!."'\\(){}\[\]<>~#*$%^_]+""")
43 #--------------------------------------------------------
44 # external API
45 #--------------------------------------------------------
46 #--------------------------------------------------------
47 # base class API
48 #--------------------------------------------------------
49 # internal matching algorithms
50 #
51 # if we end up here:
52 # - aFragment will not be "None"
53 # - aFragment will be lower case
54 # - we _do_ deliver matches (whether we find any is a different story)
55 #--------------------------------------------------------
57 """Return matches for aFragment at start of phrases."""
58 self.__now = mxDT.now()
59 matches = gmDateTime.str2fuzzy_timestamp_matches(aFragment.strip())
60 if len(matches) > 0:
61 return (True, matches)
62 else:
63 return (False, [])
64 #--------------------------------------------------------
66 """Return matches for aFragment at start of words inside phrases."""
67 return self.getMatchesByPhrase(aFragment)
68 #--------------------------------------------------------
70 """Return matches for aFragment as a true substring."""
71 return self.getMatchesByPhrase(aFragment)
72 #--------------------------------------------------------
77 #==================================================
79
81
82 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
83
84 self.matcher = cMatchProvider_FuzzyTimestamp()
85 self.phrase_separators = None
86 self.selection_only = True
87 self.selection_only_error_msg = _('Cannot interpret input as timestamp.')
88 #--------------------------------------------------------
89 # internal helpers
90 #--------------------------------------------------------
92
93 if val is None:
94 val = self.GetValue().strip()
95
96 success, matches = self.matcher.getMatchesByPhrase(val)
97 #matches = gmDateTime.str2fuzzy_timestamp_matches(str2parse=val)
98 if len(matches) == 1:
99 return matches[0]['data']
100
101 return None
102 #--------------------------------------------------------
103 # phrasewheel internal API
104 #--------------------------------------------------------
106 # are we valid ?
107 if self.data is None:
108 # no, so try
109 self.data = self.__text2timestamp()
110
111 # let the base class do its thing
112 gmPhraseWheel.cPhraseWheel._on_lose_focus(self, event)
113 #--------------------------------------------------------
115 data = self._picklist.GetSelectedItemData()
116 if data is not None:
117 return data.format_accurately()
118 return self._picklist.get_selected_item_label()
119 #--------------------------------------------------------
120 # external API
121 #--------------------------------------------------------
123
124 if data is not None:
125 if isinstance(data, pyDT.datetime):
126 data = gmDateTime.cFuzzyTimestamp(timestamp=data)
127 if value.strip() == u'':
128 value = data.format_accurately()
129
130 gmPhraseWheel.cPhraseWheel.SetText(self, value = value, data = data, suppress_smarts = suppress_smarts)
131 #--------------------------------------------------------
133 if data is None:
134 gmPhraseWheel.cPhraseWheel.SetText(self, u'', None)
135 else:
136 if isinstance(data, pyDT.datetime):
137 data = gmDateTime.cFuzzyTimestamp(timestamp=data)
138 gmPhraseWheel.cPhraseWheel.SetText(self, value = data.format_accurately(), data = data)
139 #--------------------------------------------------------
153 #==================================================
165 #==================================================
167
171 #super(cDateInputCtrl, self).__init__(*args, **kwargs)
172 #self.Bind(wx.EVT_DATE_CHANGED, self.__on_date_changed, self)
173 #----------------------------------------------
175 """Set either datetime.datetime or wx.DateTime"""
176
177 if isinstance(value, (pyDT.date, pyDT.datetime)):
178 wxvalue = wx.DateTime()
179 wxvalue.Set(year = value.year, month = value.month-1, day = value.day)
180 value = wxvalue
181
182 elif value is None:
183 value = wx.DefaultDateTime
184
185 wx.DatePickerCtrl.SetValue(self, value)
186 #----------------------------------------------
188 """Returns datetime.datetime values"""
189
190 value = wx.DatePickerCtrl.GetValue(self)
191
192 if value is None:
193 return None
194
195 # manage null dates (useful when wx.DP_ALLOWNONE is set)
196 if not value.IsValid():
197 return None
198
199 self.SetBackgroundColour(gmPhraseWheel.color_prw_valid)
200 self.Refresh()
201
202 if not as_pydt:
203 return value
204
205 return gmDateTime.wxDate2py_dt(value)
206
207 #return pyDT.datetime(value.GetYear(), value.GetMonth() + 1, value.GetDay())
208 #----------------------------------------------
209 # def convenience wrapper
210 #----------------------------------------------
212 val = self.GetValue()
213
214 if val is None:
215 if allow_none:
216 valid = True
217 else:
218 valid = False
219 else:
220 valid = val.IsValid()
221
222 if valid:
223 self.SetBackgroundColour(gmPhraseWheel.color_prw_valid)
224 else:
225 self.SetBackgroundColour(gmPhraseWheel.color_prw_invalid)
226
227 self.Refresh()
228 return valid
229 #----------------------------------------------
231 return self.GetValue(as_pydt = True)
232 #----------------------------------------------
234 if valid is True:
235 self.SetBackgroundColour(gmPhraseWheel.color_prw_valid)
236 else:
237 self.SetBackgroundColour(gmPhraseWheel.color_prw_invalid)
238 self.Refresh()
239 #==================================================
240 # main
241 #--------------------------------------------------
242 if __name__ == '__main__':
243
244 if (len(sys.argv) > 1) and (sys.argv[1] == 'test'):
245 from Gnumed.pycommon import gmI18N
246 gmI18N.activate_locale()
247 gmI18N.install_domain(domain='gnumed')
248 gmDateTime.init()
249
250 #----------------------------------------------------
252 mp = cMatchProvider_FuzzyTimestamp()
253 mp.word_separators = None
254 mp.setThresholds(aWord = 998, aSubstring = 999)
255 val = None
256 while val != 'exit':
257 print "************************************"
258 val = raw_input('Enter date fragment: ')
259 found, matches = mp.getMatches(aFragment=val)
260 for match in matches:
261 print match['label']
262 print match['data']
263 print "---------------"
264 #--------------------------------------------------------
266 app = wx.PyWidgetTester(size = (200, 300))
267 app.SetWidget(cFuzzyTimestampInput, id=-1, size=(180,20), pos=(10,20))
268 app.MainLoop()
269 #--------------------------------------------------------
271 app = wx.PyWidgetTester(size = (200, 300))
272 app.SetWidget(cDateInputCtrl, id=-1, size=(180,20), pos=(10,20))
273 app.MainLoop()
274 #--------------------------------------------------------
275 #test_cli()
276 #test_gui()
277 test_picker()
278
279 #==================================================
280 # - free text input: start string with "
281 #==================================================
282 # $Log: gmDateTimeInput.py,v $
283 # Revision 1.66 2009-12-21 15:04:57 ncq
284 # - cDatePickerCtrl
285 # - SetValue now takes datetime, too
286 # - GetValue can return datetime
287 #
288 # Revision 1.65 2009/06/04 14:52:54 ncq
289 # - re-import lost cDatePickerCtrl and test
290 #
291 # Revision 1.65 2009/05/28 10:49:55 ncq
292 # - cDatePickerCtrl
293 #
294 # Revision 1.64 2009/02/05 14:28:46 ncq
295 # - cleanup
296 #
297 # Revision 1.63 2008/06/22 17:31:50 ncq
298 # - some cleanup
299 #
300 # Revision 1.62 2008/06/18 15:46:49 ncq
301 # - cleanup: offset/trigger chars are handled in the str 2 timestamp function directly
302 #
303 # Revision 1.61 2008/06/15 20:33:55 ncq
304 # - adjust to match provider properties
305 #
306 # Revision 1.60 2008/05/07 15:20:36 ncq
307 # - support suppress smarts in SetText
308 #
309 # Revision 1.59 2008/04/02 10:22:03 ncq
310 # - optionalize test suite running
311 #
312 # Revision 1.58 2008/03/05 22:30:13 ncq
313 # - new style logging
314 #
315 # Revision 1.57 2007/07/10 20:28:36 ncq
316 # - consolidate install_domain() args
317 #
318 # Revision 1.56 2007/06/15 10:24:53 ncq
319 # - adjust to change function signature
320 #
321 # Revision 1.55 2007/04/02 18:39:52 ncq
322 # - gmFuzzyTimestamp -> gmDateTime
323 #
324 # Revision 1.54 2007/03/18 14:01:52 ncq
325 # - re-add lost 1.54
326 #
327 # Revision 1.54 2007/03/12 12:26:15 ncq
328 # - allow SetData/SetText to take datetime.datetime instances
329 #
330 # Revision 1.53 2007/02/16 12:51:07 ncq
331 # - fix is_valid_timestamp()
332 #
333 # Revision 1.52 2007/02/16 10:23:44 ncq
334 # - make it selection_only and set error message
335 # - u''ify more
336 # - delegate more work to standard phrasewheel code
337 # - add SetText()
338 # - fix _picklist_selection2display_string()
339 # - need to activate locale in test suite
340 #
341 # Revision 1.51 2007/02/05 12:15:23 ncq
342 # - no more aMatchProvider/selection_only in cPhraseWheel.__init__()
343 #
344 # Revision 1.50 2007/02/04 15:51:00 ncq
345 # - no more snap_to_first_match
346 # - use SetText()
347 # - explicetly unset phrase separators
348 #
349 # Revision 1.49 2006/12/21 10:54:18 ncq
350 # - add SetData
351 #
352 # Revision 1.48 2006/11/27 23:14:33 ncq
353 # - remove prints
354 #
355 # Revision 1.47 2006/11/27 23:04:49 ncq
356 # - factor out UI-independant code
357 #
358 # Revision 1.46 2006/11/27 12:39:00 ncq
359 # - remove useless check
360 #
361 # Revision 1.45 2006/11/26 22:38:14 ncq
362 # - recognize 1953 as meaning that year :-)
363 #
364 # Revision 1.44 2006/11/24 14:19:43 ncq
365 # - variable name fix in __text2timestamp
366 #
367 # Revision 1.43 2006/11/24 10:01:31 ncq
368 # - gm_beep_statustext() -> gm_statustext()
369 #
370 # Revision 1.42 2006/11/19 11:11:57 ncq
371 # - fix wrong return value
372 #
373 # Revision 1.41 2006/07/19 20:29:50 ncq
374 # - import cleanup
375 #
376 # Revision 1.40 2006/07/01 13:12:32 ncq
377 # - improve test harness
378 #
379 # Revision 1.39 2006/06/15 15:35:30 ncq
380 # - better error handling
381 #
382 # Revision 1.38 2006/06/05 21:30:08 ncq
383 # - add single-dot expander so German 23. expands to 23rd this month this year
384 # - add is_valid_timestamp() to external API so patient wizard can use it
385 #
386 # Revision 1.37 2006/06/04 21:50:32 ncq
387 # - cleanup
388 #
389 # Revision 1.36 2006/06/02 13:17:50 ncq
390 # - add configurable offset chars for i18n
391 # - various cleanups and optimizations
392 # - fix __explicit_offset to use proper fuzzy timestamp
393 # - __validate() -> __text2timestamp() and smarten up
394 #
395 # Revision 1.35 2006/06/02 10:12:09 ncq
396 # - cleanup
397 # - add more fragment expanders
398 #
399 # Revision 1.34 2006/05/24 10:35:38 ncq
400 # - better named match provider
401 #
402 # Revision 1.33 2006/05/24 10:12:37 ncq
403 # - cleanup
404 # - timestamp match provider:
405 # - use fuzzy timestamp
406 # - i18n()ize single character triggers
407 # - improve phrasewheel strings
408 # - fuzzy timestamp phrasewheel
409 # - a lot of cleanup
410 # - proper test code
411 #
412 # Revision 1.32 2006/05/20 18:37:10 ncq
413 # - cleanup
414 #
415 # Revision 1.31 2006/05/12 12:08:51 ncq
416 # - comment out proposed fix for unicode problems
417 #
418 # Revision 1.30 2005/09/28 21:27:30 ncq
419 # - a lot of wx2.6-ification
420 #
421 # Revision 1.29 2005/09/28 15:57:47 ncq
422 # - a whole bunch of wx.Foo -> wx.Foo
423 #
424 # Revision 1.28 2005/09/26 18:01:50 ncq
425 # - use proper way to import wx26 vs wx2.4
426 # - note: THIS WILL BREAK RUNNING THE CLIENT IN SOME PLACES
427 # - time for fixup
428 #
429 # Revision 1.27 2005/09/25 01:13:06 ihaywood
430 # use a nicer way of discovering non-Unicode wxPython builds
431 # I resisted the temptation to use "if os.environ['USER'] == 'ncq':"
432 #
433 # Revision 1.26 2005/09/25 01:00:47 ihaywood
434 # bugfixes
435 #
436 # remember 2.6 uses "import wx" not "from wxPython import wx"
437 # removed not null constraint on clin_encounter.rfe as has no value on instantiation
438 # client doesn't try to set clin_encounter.description as it doesn't exist anymore
439 #
440 # Revision 1.25 2005/08/22 13:03:46 ncq
441 # - set bounds on "day of month" calculations
442 #
443 # Revision 1.24 2005/07/31 16:22:25 ncq
444 # - need to import "time"
445 #
446 # Revision 1.23 2005/07/31 16:04:19 ncq
447 # - on some platforms, notably MS Windows mx.DateTime does not support
448 # strptime(), hence use time.strptime()
449 #
450 # Revision 1.22 2005/07/31 15:32:50 ncq
451 # - cleanup
452 #
453 # Revision 1.21 2005/07/31 15:23:40 ncq
454 # - fixed long-standing validation logic bug
455 # - logging is best done using proper syntax, too
456 #
457 # Revision 1.20 2005/07/27 15:17:06 ncq
458 # - properly catch date input error such that we
459 # may find the bug on Windows
460 #
461 # Revision 1.19 2005/06/08 22:01:42 cfmoro
462 # Avoid validating when empty date
463 #
464 # Revision 1.18 2005/06/08 21:19:50 cfmoro
465 # Crash fix
466 #
467 # Revision 1.17 2005/06/04 09:55:32 ncq
468 # - also call parent class _on_lose_focus so we don't loose
469 # callbacks set by other people
470 #
471 # Revision 1.16 2005/06/03 00:54:33 cfmoro
472 # Validte date in SetValue
473 #
474 # Revision 1.15 2005/06/03 00:36:54 cfmoro
475 # Validate date on setValue
476 #
477 # Revision 1.14 2005/06/02 23:28:54 cfmoro
478 # Date validation
479 #
480 # Revision 1.13 2005/04/25 17:11:33 ncq
481 # - set encoding for file
482 #
483 # Revision 1.12 2005/04/24 15:05:22 ncq
484 # - use gmI18N properly
485 #
486 # Revision 1.11 2004/12/23 16:20:15 ncq
487 # - add licence
488 #
489 # Revision 1.10 2004/07/18 20:30:53 ncq
490 # - wxPython.true/false -> Python.True/False as Python tells us to do
491 #
492 # Revision 1.9 2004/03/05 11:22:35 ncq
493 # - import from Gnumed.<pkg>
494 #
495 # Revision 1.8 2004/02/25 09:46:21 ncq
496 # - import from pycommon now, not python-common
497 #
498 # Revision 1.7 2003/11/05 22:21:06 sjtan
499 #
500 # let's gmDateInput specify id_callback in constructor list.
501 #
502 # Revision 1.6 2003/11/04 10:35:23 ihaywood
503 # match providers in gmDemographicRecord
504 #
505 # Revision 1.5 2003/10/06 17:49:40 ncq
506 # - remove dependancy on gmI18N on standalone test run
507 #
508 # Revision 1.4 2003/10/02 20:51:12 ncq
509 # - add alt-XX shortcuts, move __* to _*
510 #
511 # Revision 1.3 2003/09/30 18:47:47 ncq
512 # - converted date time input field into phrase wheel descendant
513 #
514 # Revision 1.2 2003/08/10 00:57:15 ncq
515 # - add TODO item
516 #
517 # Revision 1.1 2003/05/23 14:05:01 ncq
518 # - first implementation
519 #
520
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Mon Jun 28 04:13:25 2010 | http://epydoc.sourceforge.net |