| 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: /cvsroot/gnumed/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.DateTime()
184
185 wx.DatePickerCtrl.SetValue(self, value)
186 #----------------------------------------------
188 """Returns datetime.datetime values"""
189
190 value = wx.DatePickerCtrl.GetValue(self)
191
192 # manage null dates (useful when wx.DP_ALLOWNONE is set)
193 if not value.IsValid():
194 return None
195
196 if not as_pydt:
197 return value
198
199 return pyDT.datetime(value.GetYear(), value.GetMonth() + 1, value.GetDay())
200 #----------------------------------------------
201 # def convenience wrapper
202 #----------------------------------------------
204 valid = self.GetValue().IsValid()
205 if valid:
206 self.SetBackgroundColour(gmPhraseWheel.color_prw_valid)
207 else:
208 self.SetBackgroundColour(gmPhraseWheel.color_prw_invalid)
209 self.Refresh()
210 return valid
211 #----------------------------------------------
213 val = self.GetValue()
214 if val.IsValid():
215 self.SetBackgroundColour(gmPhraseWheel.color_prw_valid)
216 val = gmDateTime.wxDate2py_dt(val)
217 self.Refresh()
218 else:
219 val = None
220 return val
221 #==================================================
222 # main
223 #--------------------------------------------------
224 if __name__ == '__main__':
225
226 if (len(sys.argv) > 1) and (sys.argv[1] == 'test'):
227 from Gnumed.pycommon import gmI18N
228 gmI18N.activate_locale()
229 gmI18N.install_domain(domain='gnumed')
230 gmDateTime.init()
231
232 #----------------------------------------------------
234 mp = cMatchProvider_FuzzyTimestamp()
235 mp.word_separators = None
236 mp.setThresholds(aWord = 998, aSubstring = 999)
237 val = None
238 while val != 'exit':
239 print "************************************"
240 val = raw_input('Enter date fragment: ')
241 found, matches = mp.getMatches(aFragment=val)
242 for match in matches:
243 print match['label']
244 print match['data']
245 print "---------------"
246 #--------------------------------------------------------
248 app = wx.PyWidgetTester(size = (200, 300))
249 app.SetWidget(cFuzzyTimestampInput, id=-1, size=(180,20), pos=(10,20))
250 app.MainLoop()
251 #--------------------------------------------------------
253 app = wx.PyWidgetTester(size = (200, 300))
254 app.SetWidget(cDateInputCtrl, id=-1, size=(180,20), pos=(10,20))
255 app.MainLoop()
256 #--------------------------------------------------------
257 #test_cli()
258 #test_gui()
259 test_picker()
260
261 #==================================================
262 # - free text input: start string with "
263 #==================================================
264 # $Log: gmDateTimeInput.py,v $
265 # Revision 1.66 2009/12/21 15:04:57 ncq
266 # - cDatePickerCtrl
267 # - SetValue now takes datetime, too
268 # - GetValue can return datetime
269 #
270 # Revision 1.65 2009/06/04 14:52:54 ncq
271 # - re-import lost cDatePickerCtrl and test
272 #
273 # Revision 1.65 2009/05/28 10:49:55 ncq
274 # - cDatePickerCtrl
275 #
276 # Revision 1.64 2009/02/05 14:28:46 ncq
277 # - cleanup
278 #
279 # Revision 1.63 2008/06/22 17:31:50 ncq
280 # - some cleanup
281 #
282 # Revision 1.62 2008/06/18 15:46:49 ncq
283 # - cleanup: offset/trigger chars are handled in the str 2 timestamp function directly
284 #
285 # Revision 1.61 2008/06/15 20:33:55 ncq
286 # - adjust to match provider properties
287 #
288 # Revision 1.60 2008/05/07 15:20:36 ncq
289 # - support suppress smarts in SetText
290 #
291 # Revision 1.59 2008/04/02 10:22:03 ncq
292 # - optionalize test suite running
293 #
294 # Revision 1.58 2008/03/05 22:30:13 ncq
295 # - new style logging
296 #
297 # Revision 1.57 2007/07/10 20:28:36 ncq
298 # - consolidate install_domain() args
299 #
300 # Revision 1.56 2007/06/15 10:24:53 ncq
301 # - adjust to change function signature
302 #
303 # Revision 1.55 2007/04/02 18:39:52 ncq
304 # - gmFuzzyTimestamp -> gmDateTime
305 #
306 # Revision 1.54 2007/03/18 14:01:52 ncq
307 # - re-add lost 1.54
308 #
309 # Revision 1.54 2007/03/12 12:26:15 ncq
310 # - allow SetData/SetText to take datetime.datetime instances
311 #
312 # Revision 1.53 2007/02/16 12:51:07 ncq
313 # - fix is_valid_timestamp()
314 #
315 # Revision 1.52 2007/02/16 10:23:44 ncq
316 # - make it selection_only and set error message
317 # - u''ify more
318 # - delegate more work to standard phrasewheel code
319 # - add SetText()
320 # - fix _picklist_selection2display_string()
321 # - need to activate locale in test suite
322 #
323 # Revision 1.51 2007/02/05 12:15:23 ncq
324 # - no more aMatchProvider/selection_only in cPhraseWheel.__init__()
325 #
326 # Revision 1.50 2007/02/04 15:51:00 ncq
327 # - no more snap_to_first_match
328 # - use SetText()
329 # - explicetly unset phrase separators
330 #
331 # Revision 1.49 2006/12/21 10:54:18 ncq
332 # - add SetData
333 #
334 # Revision 1.48 2006/11/27 23:14:33 ncq
335 # - remove prints
336 #
337 # Revision 1.47 2006/11/27 23:04:49 ncq
338 # - factor out UI-independant code
339 #
340 # Revision 1.46 2006/11/27 12:39:00 ncq
341 # - remove useless check
342 #
343 # Revision 1.45 2006/11/26 22:38:14 ncq
344 # - recognize 1953 as meaning that year :-)
345 #
346 # Revision 1.44 2006/11/24 14:19:43 ncq
347 # - variable name fix in __text2timestamp
348 #
349 # Revision 1.43 2006/11/24 10:01:31 ncq
350 # - gm_beep_statustext() -> gm_statustext()
351 #
352 # Revision 1.42 2006/11/19 11:11:57 ncq
353 # - fix wrong return value
354 #
355 # Revision 1.41 2006/07/19 20:29:50 ncq
356 # - import cleanup
357 #
358 # Revision 1.40 2006/07/01 13:12:32 ncq
359 # - improve test harness
360 #
361 # Revision 1.39 2006/06/15 15:35:30 ncq
362 # - better error handling
363 #
364 # Revision 1.38 2006/06/05 21:30:08 ncq
365 # - add single-dot expander so German 23. expands to 23rd this month this year
366 # - add is_valid_timestamp() to external API so patient wizard can use it
367 #
368 # Revision 1.37 2006/06/04 21:50:32 ncq
369 # - cleanup
370 #
371 # Revision 1.36 2006/06/02 13:17:50 ncq
372 # - add configurable offset chars for i18n
373 # - various cleanups and optimizations
374 # - fix __explicit_offset to use proper fuzzy timestamp
375 # - __validate() -> __text2timestamp() and smarten up
376 #
377 # Revision 1.35 2006/06/02 10:12:09 ncq
378 # - cleanup
379 # - add more fragment expanders
380 #
381 # Revision 1.34 2006/05/24 10:35:38 ncq
382 # - better named match provider
383 #
384 # Revision 1.33 2006/05/24 10:12:37 ncq
385 # - cleanup
386 # - timestamp match provider:
387 # - use fuzzy timestamp
388 # - i18n()ize single character triggers
389 # - improve phrasewheel strings
390 # - fuzzy timestamp phrasewheel
391 # - a lot of cleanup
392 # - proper test code
393 #
394 # Revision 1.32 2006/05/20 18:37:10 ncq
395 # - cleanup
396 #
397 # Revision 1.31 2006/05/12 12:08:51 ncq
398 # - comment out proposed fix for unicode problems
399 #
400 # Revision 1.30 2005/09/28 21:27:30 ncq
401 # - a lot of wx2.6-ification
402 #
403 # Revision 1.29 2005/09/28 15:57:47 ncq
404 # - a whole bunch of wx.Foo -> wx.Foo
405 #
406 # Revision 1.28 2005/09/26 18:01:50 ncq
407 # - use proper way to import wx26 vs wx2.4
408 # - note: THIS WILL BREAK RUNNING THE CLIENT IN SOME PLACES
409 # - time for fixup
410 #
411 # Revision 1.27 2005/09/25 01:13:06 ihaywood
412 # use a nicer way of discovering non-Unicode wxPython builds
413 # I resisted the temptation to use "if os.environ['USER'] == 'ncq':"
414 #
415 # Revision 1.26 2005/09/25 01:00:47 ihaywood
416 # bugfixes
417 #
418 # remember 2.6 uses "import wx" not "from wxPython import wx"
419 # removed not null constraint on clin_encounter.rfe as has no value on instantiation
420 # client doesn't try to set clin_encounter.description as it doesn't exist anymore
421 #
422 # Revision 1.25 2005/08/22 13:03:46 ncq
423 # - set bounds on "day of month" calculations
424 #
425 # Revision 1.24 2005/07/31 16:22:25 ncq
426 # - need to import "time"
427 #
428 # Revision 1.23 2005/07/31 16:04:19 ncq
429 # - on some platforms, notably MS Windows mx.DateTime does not support
430 # strptime(), hence use time.strptime()
431 #
432 # Revision 1.22 2005/07/31 15:32:50 ncq
433 # - cleanup
434 #
435 # Revision 1.21 2005/07/31 15:23:40 ncq
436 # - fixed long-standing validation logic bug
437 # - logging is best done using proper syntax, too
438 #
439 # Revision 1.20 2005/07/27 15:17:06 ncq
440 # - properly catch date input error such that we
441 # may find the bug on Windows
442 #
443 # Revision 1.19 2005/06/08 22:01:42 cfmoro
444 # Avoid validating when empty date
445 #
446 # Revision 1.18 2005/06/08 21:19:50 cfmoro
447 # Crash fix
448 #
449 # Revision 1.17 2005/06/04 09:55:32 ncq
450 # - also call parent class _on_lose_focus so we don't loose
451 # callbacks set by other people
452 #
453 # Revision 1.16 2005/06/03 00:54:33 cfmoro
454 # Validte date in SetValue
455 #
456 # Revision 1.15 2005/06/03 00:36:54 cfmoro
457 # Validate date on setValue
458 #
459 # Revision 1.14 2005/06/02 23:28:54 cfmoro
460 # Date validation
461 #
462 # Revision 1.13 2005/04/25 17:11:33 ncq
463 # - set encoding for file
464 #
465 # Revision 1.12 2005/04/24 15:05:22 ncq
466 # - use gmI18N properly
467 #
468 # Revision 1.11 2004/12/23 16:20:15 ncq
469 # - add licence
470 #
471 # Revision 1.10 2004/07/18 20:30:53 ncq
472 # - wxPython.true/false -> Python.True/False as Python tells us to do
473 #
474 # Revision 1.9 2004/03/05 11:22:35 ncq
475 # - import from Gnumed.<pkg>
476 #
477 # Revision 1.8 2004/02/25 09:46:21 ncq
478 # - import from pycommon now, not python-common
479 #
480 # Revision 1.7 2003/11/05 22:21:06 sjtan
481 #
482 # let's gmDateInput specify id_callback in constructor list.
483 #
484 # Revision 1.6 2003/11/04 10:35:23 ihaywood
485 # match providers in gmDemographicRecord
486 #
487 # Revision 1.5 2003/10/06 17:49:40 ncq
488 # - remove dependancy on gmI18N on standalone test run
489 #
490 # Revision 1.4 2003/10/02 20:51:12 ncq
491 # - add alt-XX shortcuts, move __* to _*
492 #
493 # Revision 1.3 2003/09/30 18:47:47 ncq
494 # - converted date time input field into phrase wheel descendant
495 #
496 # Revision 1.2 2003/08/10 00:57:15 ncq
497 # - add TODO item
498 #
499 # Revision 1.1 2003/05/23 14:05:01 ncq
500 # - first implementation
501 #
502
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Tue Feb 9 04:02:21 2010 | http://epydoc.sourceforge.net |