| Trees | Indices | Help |
|
|---|
|
|
1 """GNUmed allergy related widgets."""
2 ############################################################################
3 # $Source: /cvsroot/gnumed/gnumed/gnumed/client/wxpython/gmAllergyWidgets.py,v $
4 # $Id: gmAllergyWidgets.py,v 1.36 2010/02/06 21:00:07 ncq Exp $
5 __version__ = "$Revision: 1.36 $"
6 __author__ = "R.Terry <rterry@gnumed.net>, H.Herb <hherb@gnumed.net>, K.Hilbert <Karsten.Hilbert@gmx.net>"
7 __license__ = 'GPL (details at http://www.gnu.org)'
8
9 import sys, time, datetime as pyDT, logging
10
11
12 import wx
13
14
15 if __name__ == '__main__':
16 sys.path.insert(0, '../../')
17 from Gnumed.pycommon import gmDispatcher, gmI18N, gmDateTime, gmTools, gmMatchProvider
18 from Gnumed.wxpython import gmDateTimeInput, gmTerryGuiParts, gmRegetMixin, gmPatSearchWidgets
19 from Gnumed.business import gmPerson, gmAllergy
20 from Gnumed.wxGladeWidgets import wxgAllergyEditAreaPnl, wxgAllergyEditAreaDlg, wxgAllergyManagerDlg
21
22 _log = logging.getLogger('gm.ui')
23 _log.info(__version__)
24
25 #======================================================================
27
29 wxgAllergyEditAreaPnl.wxgAllergyEditAreaPnl.__init__(self, *args, **kwargs)
30
31 try:
32 self.__allergy = kwargs['allergy']
33 except KeyError:
34 self.__allergy = None
35
36 mp = gmMatchProvider.cMatchProvider_SQL2 (
37 queries = [u"""
38 select substance, substance
39 from clin.allergy
40 where substance %(fragment_condition)s
41
42 union
43
44 select generics, generics
45 from clin.allergy
46 where generics %(fragment_condition)s
47
48 union
49
50 select allergene, allergene
51 from clin.allergy
52 where allergene %(fragment_condition)s
53
54 union
55
56 select atc_code, atc_code
57 from clin.allergy
58 where atc_code %(fragment_condition)s
59 """
60 ]
61 )
62 mp.setThresholds(2, 3, 5)
63 self._PRW_trigger.matcher = mp
64
65 mp = gmMatchProvider.cMatchProvider_SQL2 (
66 queries = [u"""
67 select narrative, narrative
68 from clin.allergy
69 where narrative %(fragment_condition)s
70 """]
71 )
72 mp.setThresholds(2, 3, 5)
73 self._PRW_reaction.matcher = mp
74 self._PRW_reaction.enable_default_spellchecker()
75
76 # self._RBTN_type_sensitivity.MoveAfterInTabOrder(self._RBTN_type_allergy)
77 # self._ChBOX_definite.MoveAfterInTabOrder(self._RBTN_type_sensitivity)
78
79 self.refresh()
80 #--------------------------------------------------------
81 # external API
82 #--------------------------------------------------------
86 #--------------------------------------------------------
88
89 if allergy is not None:
90 self.__allergy = allergy
91
92 if self.__allergy is None:
93 ts = gmDateTime.cFuzzyTimestamp (
94 timestamp = pyDT.datetime.now(tz=gmDateTime.gmCurrentLocalTimezone),
95 accuracy = gmDateTime.acc_days
96 )
97 self._DPRW_date_noted.SetData(data = ts)
98 self._PRW_trigger.SetText()
99 self._TCTRL_brand_name.SetValue('')
100 self._TCTRL_generic.SetValue('')
101 self._ChBOX_generic_specific.SetValue(0)
102 self._TCTRL_atc_classes.SetValue('')
103 self._PRW_reaction.SetText()
104 self._RBTN_type_allergy.SetValue(1)
105 self._RBTN_type_sensitivity.SetValue(0)
106 self._ChBOX_definite.SetValue(1)
107 return True
108
109 if not isinstance(self.__allergy, gmAllergy.cAllergy):
110 raise ValueError('[%s].refresh(): expected gmAllergy.cAllergy instance, got [%s] instead' % (self.__class__.__name__, self.__allergy))
111
112 ts = gmDateTime.cFuzzyTimestamp (
113 timestamp = self.__allergy['date'],
114 accuracy = gmDateTime.acc_days
115 )
116 self._DPRW_date_noted.SetData(data=ts)
117 self._PRW_trigger.SetText(value = self.__allergy['substance'])
118 self._TCTRL_brand_name.SetValue(self.__allergy['substance'])
119 self._TCTRL_generic.SetValue(gmTools.coalesce(self.__allergy['generics'], ''))
120 self._ChBOX_generic_specific.SetValue(self.__allergy['generic_specific'])
121 self._TCTRL_atc_classes.SetValue(gmTools.coalesce(self.__allergy['atc_code'], ''))
122 self._PRW_reaction.SetText(value = gmTools.coalesce(self.__allergy['reaction'], ''))
123 if self.__allergy['type'] == 'allergy':
124 self._RBTN_type_allergy.SetValue(1)
125 else:
126 self._RBTN_type_sensitivity.SetValue(1)
127 self._ChBOX_definite.SetValue(self.__allergy['definite'])
128 #--------------------------------------------------------
130
131 if self._PRW_trigger.GetValue().strip() == '':
132 self._PRW_trigger.SetBackgroundColour('pink')
133 self._PRW_trigger.Refresh()
134 self._PRW_trigger.SetFocus()
135 return False
136 self._PRW_trigger.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
137 self._PRW_trigger.Refresh()
138
139 return True
140 #--------------------------------------------------------
142 if not self.__is_valid_for_save():
143 return False
144
145 if self.__allergy is None:
146 if not can_create:
147 gmDispatcher.send(signal='statustext', msg=_('Creating new allergy not allowed.'))
148 return False
149
150 pat = gmPerson.gmCurrentPatient()
151 emr = pat.get_emr()
152
153 if self._RBTN_type_allergy.GetValue():
154 allg_type = 'allergy'
155 else:
156 allg_type = 'sensitivity'
157 self.__allergy = emr.add_allergy (
158 substance = self._PRW_trigger.GetValue().strip(),
159 allg_type = allg_type
160 )
161
162 # and update it with known data
163 self.__allergy['date'] = self._DPRW_date_noted.GetData().get_pydt()
164 self.__allergy['substance'] = self._PRW_trigger.GetValue().strip()
165 # FIXME: determine brandname/generic/etc from substance (trigger field)
166 self.__allergy['generic_specific'] = (True and self._ChBOX_generic_specific.GetValue())
167 self.__allergy['reaction'] = self._PRW_reaction.GetValue().strip()
168 self.__allergy['definite'] = (True and self._ChBOX_definite.GetValue())
169 if self._RBTN_type_allergy.GetValue():
170 self.__allergy['pk_type'] = 'allergy'
171 else:
172 self.__allergy['pk_type'] = 'sensitivity'
173
174 self.__allergy.save_payload()
175
176 return True
177 #======================================================================
179
181
182 try:
183 allergy = kwargs['allergy']
184 del kwargs['allergy']
185 except KeyError:
186 allergy = None
187
188 wxgAllergyEditAreaDlg.wxgAllergyEditAreaDlg.__init__(self, *args, **kwargs)
189
190 if allergy is None:
191 # self._BTN_save.SetLabel(_('&Save'))
192 self._BTN_clear.SetLabel(_('&Clear'))
193 else:
194 # self._BTN_save.SetLabel(_('Update'))
195 self._BTN_clear.SetLabel(_('&Restore'))
196
197 self._PNL_edit_area.refresh(allergy = allergy)
198 #--------------------------------------------------------
205 #--------------------------------------------------------
208 #======================================================================
210
212
213 wxgAllergyManagerDlg.wxgAllergyManagerDlg.__init__(self, *args, **kwargs)
214
215 self.Centre(direction = wx.BOTH)
216
217 self.__set_columns()
218 # MacOSX crashes on this with:
219 # exception type : wx._core.PyAssertionError
220 # exception value: C++ assertion "i" failed at /BUILD/wxPython-src-2.8.3.0/src/common/wincmn.cpp(2634) in DoMoveInTabOrder(): MoveBefore/AfterInTabOrder(): win is not a sibling
221 # while Win/Linux work just fine
222 #self._PNL_edit_area._ChBOX_definite.MoveAfterInTabOrder(self._BTN_save)
223 self.__refresh_state_ui()
224 self.__refresh_details_ui()
225 #--------------------------------------------------------
226 # internal helpers
227 #--------------------------------------------------------
229 self._LCTRL_allergies.set_columns (columns = [
230 _('Type'),
231 _('Certainty'),
232 _('Trigger'),
233 _('Reaction')
234 ])
235 #--------------------------------------------------------
237
238 pat = gmPerson.gmCurrentPatient()
239 emr = pat.get_emr()
240 state = emr.allergy_state
241
242 self._TXT_current_state.SetLabel(state.state_string)
243
244 if state['last_confirmed'] is None:
245 self._TXT_last_confirmed.SetLabel(_('<allergy state unasked>'))
246 else:
247 self._TXT_last_confirmed.SetLabel(state['last_confirmed'].strftime('%x %H:%M'))
248
249 if state['has_allergy'] is None:
250 self._RBTN_unknown.SetValue(True)
251 self._RBTN_none.SetValue(False)
252 self._RBTN_some.SetValue(False)
253
254 self._RBTN_unknown.Enable(True)
255 self._RBTN_none.Enable(True)
256
257 elif state['has_allergy'] == 0:
258 self._RBTN_unknown.SetValue(False)
259 self._RBTN_none.SetValue(True)
260 self._RBTN_some.SetValue(False)
261
262 self._RBTN_unknown.Enable(True)
263 self._RBTN_none.Enable(True)
264
265 elif state['has_allergy'] == 1:
266 self._RBTN_unknown.SetValue(False)
267 self._RBTN_none.SetValue(False)
268 self._RBTN_some.SetValue(True)
269
270 self._RBTN_unknown.Enable(True)
271 self._RBTN_none.Enable(False)
272
273 else:
274 self._RBTN_unknown.SetValue(True)
275 self._RBTN_none.SetValue(False)
276 self._RBTN_some.SetValue(False)
277
278 self._RBTN_unknown.Enable(True)
279 self._RBTN_none.Enable(True)
280
281 gmDispatcher.send(signal=u'statustext', msg=_('invalid allergy state [%s]') % state, beep=True)
282
283 if state['comment'] is not None:
284 self._TCTRL_state_comment.SetValue(state['comment'])
285 #--------------------------------------------------------
287
288 pat = gmPerson.gmCurrentPatient()
289 emr = pat.get_emr()
290 allergies = emr.get_allergies()
291 no_of_allergies = len(allergies)
292
293 # display allergies
294 self._LCTRL_allergies.DeleteAllItems()
295 if no_of_allergies > 0:
296 emr.allergy_state = 1
297
298 for allergy in allergies:
299 row_idx = self._LCTRL_allergies.InsertStringItem(no_of_allergies, label = allergy['l10n_type'])
300 if allergy['definite']:
301 label = _('definite')
302 else:
303 label = u''
304 self._LCTRL_allergies.SetStringItem(index = row_idx, col = 1, label = label)
305 self._LCTRL_allergies.SetStringItem(index = row_idx, col = 2, label = allergy['descriptor'])
306 self._LCTRL_allergies.SetStringItem(index = row_idx, col = 3, label = gmTools.coalesce(allergy['reaction'], u''))
307 self._LCTRL_allergies.set_data(data=allergies)
308
309 self._LCTRL_allergies.Enable(True)
310 self._RBTN_some.SetValue(True)
311 self._RBTN_unknown.Enable(False)
312 self._RBTN_none.Enable(False)
313 else:
314 self._LCTRL_allergies.Enable(False)
315 self._RBTN_unknown.Enable(True)
316 self._RBTN_none.Enable(True)
317
318 self._LCTRL_allergies.set_column_widths (widths = [
319 wx.LIST_AUTOSIZE,
320 wx.LIST_AUTOSIZE,
321 wx.LIST_AUTOSIZE,
322 wx.LIST_AUTOSIZE
323 ])
324
325 self._PNL_edit_area.clear()
326 self._BTN_delete.Enable(False)
327 #--------------------------------------------------------
328 # event handlers
329 #--------------------------------------------------------
335 #--------------------------------------------------------
340 #--------------------------------------------------------
356 #--------------------------------------------------------
358 allergy = self._LCTRL_allergies.get_selected_item_data(only_one=True)
359 if allergy is None:
360 return
361 self._PNL_edit_area.refresh(allergy=allergy)
362 self._BTN_delete.Enable(True)
363 #--------------------------------------------------------
402 #--------------------------------------------------------
416 #======================================================================
418 """Allergy details panel.
419
420 This panel will hold all the allergy details and
421 allow entry of those details via the editing area.
422 """
423 #----------------------------------------------------
425 wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.RAISED_BORDER)
426 gmRegetMixin.cRegetOnPaintMixin.__init__(self)
427 self.__do_layout()
428 self.__pat = gmPerson.gmCurrentPatient()
429 self.__register_interests()
430 self.__reset_ui_content()
431 #----------------------------------------------------
433 # -- top part --
434 pnl_UpperCaption = gmTerryGuiParts.cHeadingCaption(self, -1, _("ALLERGIES"))
435 self.editarea = gmAllergyEditArea(self, -1)
436
437 # -- middle part --
438 # divider headings below edit area
439 pnl_MiddleCaption = gmTerryGuiParts.cDividerCaption(self, -1, _("Allergy and Sensitivity - Summary"))
440 # self.sizer_divider_drug_generic = wx.BoxSizer(wxHORIZONTAL)
441 # self.sizer_divider_drug_generic.Add(pnl_MiddleCaption, 1, wxEXPAND)
442 self.LCTRL_allergies = wx.ListCtrl (
443 parent = self,
444 id = ID_ALLERGY_LIST,
445 pos = wx.DefaultPosition,
446 size = wx.DefaultSize,
447 style = wx.LC_SINGLE_SEL | wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_HRULES | wx.LC_VRULES | wx.VSCROLL
448 )
449 self.LCTRL_allergies.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, ''))
450 self.LCTRL_allergies.InsertColumn(0, _("Type"))
451 self.LCTRL_allergies.InsertColumn(1, _("Status"))
452 self.LCTRL_allergies.InsertColumn(2, _("ATC/Class"))
453 self.LCTRL_allergies.InsertColumn(3, _("Substance"))
454 self.LCTRL_allergies.InsertColumn(4, _("Generics"))
455 self.LCTRL_allergies.InsertColumn(5, _("Reaction"))
456
457 # -- bottom part --
458 pnl_LowerCaption = gmTerryGuiParts.cDividerCaption(self, -1, _('Class notes'))
459 #add a richtext control or a wxTextCtrl multiline to display the class text information
460 #e.g. would contain say information re the penicillins
461 self.class_notes = wx.TextCtrl (
462 self,
463 -1,
464 "A member of a new class of nonsteroidal anti-inflammatory agents (COX-2 selective NSAIDs) which have a mechanism of action that inhibits prostaglandin synthesis primarily by inhibition of cyclooxygenase 2 (COX-2). At therapeutic doses these have no effect on prostanoids synthesised by activation of COX-1 thereby not interfering with normal COX-1 related physiological processes in tissues, particularly the stomach, intestine and platelets.",
465 size = (200, 100),
466 style = wx.TE_MULTILINE | wx.TE_READONLY
467 )
468 self.class_notes.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False, ''))
469
470 # -- add elements to main background sizer --
471 self.mainsizer = wx.BoxSizer(wx.VERTICAL)
472 self.mainsizer.Add(pnl_UpperCaption, 0, wx.EXPAND)
473 self.mainsizer.Add(self.editarea, 6, wx.EXPAND)
474 # self.mainsizer.Add(self.sizer_divider_drug_generic,0,wxEXPAND)
475 self.mainsizer.Add(pnl_MiddleCaption, 0, wx.EXPAND)
476 self.mainsizer.Add(self.LCTRL_allergies, 5, wx.EXPAND)
477 self.mainsizer.Add(pnl_LowerCaption, 0, wx.EXPAND)
478 self.mainsizer.Add(self.class_notes, 4, wx.EXPAND)
479
480 self.SetAutoLayout(True)
481 self.SetSizer(self.mainsizer)
482 self.mainsizer.Fit(self)
483 #-----------------------------------------------
485 wx.EVT_LIST_ITEM_ACTIVATED(self, ID_ALLERGY_LIST, self._on_allergy_activated)
486
487 # client internal signals
488 gmDispatcher.connect(signal = u'post_patient_selection', receiver=self._schedule_data_reget)
489 # gmDispatcher.connect(signal = u'vaccinations_updated', receiver=self._schedule_data_reget)
490 #-----------------------------------------------
494 #-----------------------------------------------
496 if not self.__pat.connected:
497 return False
498
499 self.LCTRL_allergies.DeleteAllItems()
500
501 emr = self.__pat.get_emr()
502 allergies = emr.get_allergies()
503 if allergies is None:
504 return False
505 for list_line in range(len(allergies)):
506 allg = allergies[list_line]
507 list_line = self.LCTRL_allergies.InsertStringItem(list_line, allg['l10n_type'])
508 # FIXME: check with Richard design specs
509 if allg['definite']:
510 self.LCTRL_allergies.SetStringItem(list_line, 1, _('definite'))
511 else:
512 self.LCTRL_allergies.SetStringItem(list_line, 1, _('likely'))
513 if allg['atc_code'] is not None:
514 self.LCTRL_allergies.SetStringItem(list_line, 2, allg['atc_code'])
515 self.LCTRL_allergies.SetStringItem(list_line, 3, allg['substance'])
516 if allg['generics'] is not None:
517 self.LCTRL_allergies.SetStringItem(list_line, 4, allg['generics'])
518 self.LCTRL_allergies.SetStringItem(list_line, 5, allg['reaction'])
519 self.LCTRL_allergies.SetItemData(list_line, allg['pk_allergy'])
520 for col in range(5):
521 self.LCTRL_allergies.SetColumnWidth(col, wx.LIST_AUTOSIZE)
522 # FIXME: resize event needed ?
523 return True
524 #-----------------------------------------------
526 pk_allg = evt.GetData()
527 emr = self.__pat.get_emr()
528 allgs = emr.get_allergies(ID_list=[pk_allg])
529 self.editarea.set_data(allergy = allgs[0])
530 #======================================================================
531 # main
532 #----------------------------------------------------------------------
533 if __name__ == "__main__":
534
535 gmI18N.activate_locale()
536 gmI18N.install_domain(domain='gnumed')
537
538 #-----------------------------------------------
540 app = wx.PyWidgetTester(size = (600, 600))
541 dlg = cAllergyEditAreaDlg(parent=app.frame, id=-1)
542 dlg.ShowModal()
543 # emr = pat.get_emr()
544 # allergy = emr.get_allergies()[0]
545 # dlg = cAllergyEditAreaDlg(parent=app.frame, id=-1, allergy=allergy)
546 # dlg.ShowModal()
547 return
548 #-----------------------------------------------
550 app = wx.PyWidgetTester(size = (800, 600))
551 dlg = cAllergyManagerDlg(parent=app.frame, id=-1)
552 dlg.ShowModal()
553 return
554 #-----------------------------------------------
555 if len(sys.argv) > 1 and sys.argv[1] == 'test':
556
557 pat = gmPerson.ask_for_patient()
558 if pat is None:
559 sys.exit(0)
560 gmPatSearchWidgets.set_active_patient(pat)
561
562 #test_allergy_edit_area_dlg()
563 test_allergy_manager_dlg()
564
565 # app = wxPyWidgetTester(size = (600, 600))
566 # app.SetWidget(cAllergyPanel, -1)
567 # app.MainLoop()
568 #======================================================================
569 # $Log: gmAllergyWidgets.py,v $
570 # Revision 1.36 2010/02/06 21:00:07 ncq
571 # - do not fail deleting allergy if none selected
572 #
573 # Revision 1.35 2009/06/04 16:30:30 ncq
574 # - use set active patient from pat search widgets
575 #
576 # Revision 1.34 2008/10/22 12:12:31 ncq
577 # - rework allergy manager as per list
578 #
579 # Revision 1.33 2008/10/12 16:04:28 ncq
580 # - rework according to list discussion
581 #
582 # Revision 1.32 2008/07/07 13:43:16 ncq
583 # - current patient .connected
584 #
585 # Revision 1.31 2008/03/06 18:29:29 ncq
586 # - standard lib logging only
587 #
588 # Revision 1.30 2008/01/30 14:03:41 ncq
589 # - use signal names directly
590 # - switch to std lib logging
591 #
592 # Revision 1.29 2008/01/16 19:38:15 ncq
593 # - wxMAC doesn't like some Move*InTabOrder()
594 #
595 # Revision 1.28 2007/10/25 12:19:53 ncq
596 # - no more useless allergy update
597 #
598 # Revision 1.27 2007/09/10 18:35:27 ncq
599 # - help wxPython a bit with tab order
600 # - fix a faulty variable access
601 # - improve test suite
602 #
603 # Revision 1.26 2007/08/12 00:06:59 ncq
604 # - no more gmSignals.py
605 #
606 # Revision 1.25 2007/07/10 20:28:36 ncq
607 # - consolidate install_domain() args
608 #
609 # Revision 1.24 2007/04/02 18:39:52 ncq
610 # - gmFuzzyTimestamp -> gmDateTime
611 #
612 # Revision 1.23 2007/03/27 09:59:47 ncq
613 # - enable spell checker on allergy.reaction
614 #
615 # Revision 1.22 2007/03/26 16:49:50 ncq
616 # - "reaction" can be empty
617 #
618 # Revision 1.21 2007/03/22 11:04:15 ncq
619 # - activate prw match providers
620 #
621 # Revision 1.20 2007/03/21 08:14:01 ncq
622 # - improved allergy manager
623 # - cleanup
624 #
625 # Revision 1.19 2007/03/18 13:57:43 ncq
626 # - re-add lost 1.19
627 #
628 # Revision 1.19 2007/03/12 12:25:15 ncq
629 # - add allergy edit area panel/dialog
630 # - improved test suite
631 #
632 # Revision 1.18 2007/02/04 15:49:31 ncq
633 # - use SetText() on phrasewheel
634 #
635 # Revision 1.17 2006/10/25 07:46:44 ncq
636 # - Format() -> strftime() since datetime.datetime does not have .Format()
637 #
638 # Revision 1.16 2006/10/24 13:20:57 ncq
639 # - do not import gmPG
640 #
641 # Revision 1.15 2006/05/15 13:35:59 ncq
642 # - signal cleanup:
643 # - activating_patient -> pre_patient_selection
644 # - patient_selected -> post_patient_selection
645 #
646 # Revision 1.14 2006/05/04 09:49:20 ncq
647 # - get_clinical_record() -> get_emr()
648 # - adjust to changes in set_active_patient()
649 # - need explicit set_active_patient() after ask_for_patient() if wanted
650 #
651 # Revision 1.13 2006/01/03 12:12:03 ncq
652 # - make epydoc happy re _()
653 #
654 # Revision 1.12 2005/12/27 18:46:39 ncq
655 # - use gmI18N
656 #
657 # Revision 1.11 2005/09/28 21:27:30 ncq
658 # - a lot of wx2.6-ification
659 #
660 # Revision 1.10 2005/09/28 15:57:47 ncq
661 # - a whole bunch of wx.Foo -> wx.Foo
662 #
663 # Revision 1.9 2005/09/26 18:01:50 ncq
664 # - use proper way to import wx26 vs wx2.4
665 # - note: THIS WILL BREAK RUNNING THE CLIENT IN SOME PLACES
666 # - time for fixup
667 #
668 # Revision 1.8 2005/09/24 09:17:27 ncq
669 # - some wx2.6 compatibility fixes
670 #
671 # Revision 1.7 2005/03/20 17:49:11 ncq
672 # - default for id
673 #
674 # Revision 1.6 2005/01/31 10:37:26 ncq
675 # - gmPatient.py -> gmPerson.py
676 #
677 # Revision 1.5 2004/12/15 21:55:00 ncq
678 # - adapt to cleanly separated old/new style edit area
679 #
680 # Revision 1.4 2004/10/27 12:17:22 ncq
681 # - robustify should there not be an active patient
682 #
683 # Revision 1.3 2004/10/11 20:14:16 ncq
684 # - use RegetOnPaintMixin
685 # - attach to backend
686 # - cleanup, remove cruft
687 #
688 # Revision 1.2 2004/07/18 20:30:53 ncq
689 # - wxPython.true/false -> Python.True/False as Python tells us to do
690 #
691 # Revision 1.1 2004/07/17 21:16:38 ncq
692 # - cleanup/refactor allergy widgets:
693 # - Horst space plugin added
694 # - Richard space plugin separated out
695 # - plugin independant GUI code aggregated
696 # - allergies edit area factor out from generic edit area file
697 #
698 #
699
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Tue Feb 9 04:01:27 2010 | http://epydoc.sourceforge.net |