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 #============================================================77 #==================================================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 = None42 # 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 #--------------------------------------------------------79153 #================================================== 165 #==================================================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 None102 #-------------------------------------------------------- 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 #--------------------------------------------------------167 171 #super(cDateInputCtrl, self).__init__(*args, **kwargs) 172 #self.Bind(wx.EVT_DATE_CHANGED, self.__on_date_changed, self) 173 #----------------------------------------------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 #----------------------------------------------------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 valid229 #----------------------------------------------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()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 Sat May 22 04:14:00 2010 | http://epydoc.sourceforge.net |