| Home | Trees | Indices | Help |
|
|---|
|
|
1 """Widgets dealing with address/contact information."""
2 #============================================================
3 __version__ = "$Revision: 1.175 $"
4 __author__ = "R.Terry, SJ Tan, I Haywood, Carlos Moro <cfmoro1976@yahoo.es>"
5 __license__ = 'GPL (details at http://www.gnu.org)'
6
7 # standard library
8 import sys, logging
9
10
11 import wx
12
13
14 # GNUmed specific
15 if __name__ == '__main__':
16 sys.path.insert(0, '../../')
17 from Gnumed.pycommon import gmDispatcher, gmMatchProvider, gmPG2, gmTools
18 from Gnumed.business import gmDemographicRecord
19 from Gnumed.wxpython import gmPhraseWheel, gmGuiHelpers, gmCfgWidgets
20 from Gnumed.wxpython import gmListWidgets, gmEditArea
21
22
23 # constant defs
24 _log = logging.getLogger('gm.ui')
25
26
27 try:
28 _('dummy-no-need-to-translate-but-make-epydoc-happy')
29 except NameError:
30 _ = lambda x:x
31
32 #============================================================
33 # country related widgets / functions
34 #============================================================
36
37 if parent is None:
38 parent = wx.GetApp().GetTopWindow()
39
40 countries = gmDemographicRecord.get_countries()
41
42 gmCfgWidgets.configure_string_from_list_option (
43 parent = parent,
44 message = _('Select the default country for new persons.\n'),
45 option = 'person.create.default_country',
46 bias = 'user',
47 choices = [ (c['l10n_country'], c['code']) for c in countries ],
48 columns = [_('Country'), _('Code')],
49 data = [ c['name'] for c in countries ]
50 )
51 #============================================================
53
55
56 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
57
58 context = {
59 u'ctxt_zip': {
60 u'where_part': u'and zip ilike %(zip)s',
61 u'placeholder': u'zip'
62 }
63 }
64 query = u"""
65 select code, name from (
66 select distinct on (code, name) code, (name || ' (' || code || ')') as name, rank from (
67
68 -- localized to user
69
70 select
71 code_country as code, l10n_country as name, 1 as rank
72 from dem.v_zip2data
73 where
74 l10n_country %(fragment_condition)s
75 %(ctxt_zip)s
76
77 union all
78
79 select
80 code as code, _(name) as name, 2 as rank
81 from dem.country
82 where
83 _(name) %(fragment_condition)s
84
85 union all
86
87 -- non-localized
88
89 select
90 code_country as code, country as name, 3 as rank
91 from dem.v_zip2data
92 where
93 country %(fragment_condition)s
94 %(ctxt_zip)s
95
96 union all
97
98 select
99 code as code, name as name, 4 as rank
100 from dem.country
101 where
102 name %(fragment_condition)s
103
104 union all
105
106 -- abbreviation
107
108 select
109 code as code, name as name, 5 as rank
110 from dem.country
111 where
112 code %(fragment_condition)s
113
114 ) as q2
115 ) as q1 order by rank, name limit 25"""
116 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
117 mp.setThresholds(2, 5, 9)
118 self.matcher = mp
119
120 self.unset_context(context = u'zip')
121 self.SetToolTipString(_('Type or select a country.'))
122 self.capitalisation_mode = gmTools.CAPS_FIRST
123 self.selection_only = True
124
125 #============================================================
126 # province/state related widgets / functions
127 #============================================================
129
130 if parent is None:
131 parent = wx.GetApp().GetTopWindow()
132
133 provs = gmDemographicRecord.get_provinces()
134
135 gmCfgWidgets.configure_string_from_list_option (
136 parent = parent,
137 message = _('Select the default region/province/state/territory for new persons.\n'),
138 option = 'person.create.default_region',
139 bias = 'user',
140 choices = [ (p['l10n_country'], p['l10n_state'], p['code_state']) for p in provs ],
141 columns = [_('Country'), _('Region'), _('Code')],
142 data = [ p['state'] for p in provs ]
143 )
144 #============================================================
146 ea = cProvinceEAPnl(parent = parent, id = -1, province = province)
147 dlg = gmEditArea.cGenericEditAreaDlg2(parent = parent, id = -1, edit_area = ea, single_entry = (province is not None))
148 dlg.SetTitle(gmTools.coalesce(province, _('Adding province'), _('Editing province')))
149 result = dlg.ShowModal()
150 dlg.Destroy()
151 return (result == wx.ID_OK)
152 #============================================================
154
155 msg = _(
156 'Are you sure you want to delete this province ?\n'
157 '\n'
158 'Deletion will only work if this province is not\n'
159 'yet in use in any patient addresses.'
160 )
161
162 tt = _(
163 'Also delete any towns/cities/villages known\n'
164 'to be situated in this state as long as\n'
165 'no patients are recorded to live there.'
166 )
167
168 dlg = gmGuiHelpers.c2ButtonQuestionDlg (
169 parent,
170 -1,
171 caption = _('Deleting province'),
172 question = msg,
173 show_checkbox = True,
174 checkbox_msg = _('delete related townships'),
175 checkbox_tooltip = tt,
176 button_defs = [
177 {'label': _('Yes, delete'), 'tooltip': _('Delete province and possibly related townships.'), 'default': False},
178 {'label': _('No'), 'tooltip': _('No, do NOT delete anything.'), 'default': True}
179 ]
180 )
181
182 decision = dlg.ShowModal()
183 if decision != wx.ID_YES:
184 dlg.Destroy()
185 return False
186
187 include_urbs = dlg.checkbox_is_checked()
188 dlg.Destroy()
189
190 return gmDemographicRecord.delete_province(province = province, delete_urbs = include_urbs)
191 #============================================================
193
194 if parent is None:
195 parent = wx.GetApp().GetTopWindow()
196
197 #------------------------------------------------------------
198 def delete(province=None):
199 return delete_province(parent = parent, province = province['pk_state'])
200 #------------------------------------------------------------
201 def edit(province=None):
202 return edit_province(parent = parent, province = province)
203 #------------------------------------------------------------
204 def refresh(lctrl):
205 wx.BeginBusyCursor()
206 provinces = gmDemographicRecord.get_provinces()
207 lctrl.set_string_items([ (p['l10n_country'], p['l10n_state']) for p in provinces ])
208 lctrl.set_data(provinces)
209 wx.EndBusyCursor()
210 #------------------------------------------------------------
211 msg = _(
212 '\n'
213 'This list shows the provinces known to GNUmed.\n'
214 '\n'
215 'In your jurisdiction "province" may correspond to either of "state",\n'
216 '"county", "region", "territory", or some such term.\n'
217 '\n'
218 'Select the province you want to edit !\n'
219 )
220
221 gmListWidgets.get_choices_from_list (
222 parent = parent,
223 msg = msg,
224 caption = _('Editing provinces ...'),
225 columns = [_('Country'), _('Province')],
226 single_selection = True,
227 new_callback = edit,
228 #edit_callback = edit,
229 delete_callback = delete,
230 refresh_callback = refresh
231 )
232 #============================================================
234
236
237 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
238
239 context = {
240 u'ctxt_country_name': {
241 u'where_part': u'and l10n_country ilike %(country_name)s or country ilike %(country_name)s',
242 u'placeholder': u'country_name'
243 },
244 u'ctxt_zip': {
245 u'where_part': u'and zip ilike %(zip)s',
246 u'placeholder': u'zip'
247 },
248 u'ctxt_country_code': {
249 u'where_part': u'and country in (select code from dem.country where _(name) ilike %(country_name)s or name ilike %(country_name)s)',
250 u'placeholder': u'country_name'
251 }
252 }
253
254 query = u"""
255 select code, name from (
256 select distinct on (name) code, name, rank from (
257 -- 1: find states based on name, context: zip and country name
258 select
259 code_state as code, state as name, 1 as rank
260 from dem.v_zip2data
261 where
262 state %(fragment_condition)s
263 %(ctxt_country_name)s
264 %(ctxt_zip)s
265
266 union all
267
268 -- 2: find states based on code, context: zip and country name
269 select
270 code_state as code, state as name, 2 as rank
271 from dem.v_zip2data
272 where
273 code_state %(fragment_condition)s
274 %(ctxt_country_name)s
275 %(ctxt_zip)s
276
277 union all
278
279 -- 3: find states based on name, context: country
280 select
281 code as code, name as name, 3 as rank
282 from dem.state
283 where
284 name %(fragment_condition)s
285 %(ctxt_country_code)s
286
287 union all
288
289 -- 4: find states based on code, context: country
290 select
291 code as code, name as name, 3 as rank
292 from dem.state
293 where
294 code %(fragment_condition)s
295 %(ctxt_country_code)s
296
297 ) as q2
298 ) as q1 order by rank, name limit 50"""
299
300 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
301 mp.setThresholds(2, 5, 6)
302 mp.word_separators = u'[ \t]+'
303 self.matcher = mp
304
305 self.unset_context(context = u'zip')
306 self.unset_context(context = u'country_name')
307 self.SetToolTipString(_('Type or select a state/region/province/territory.'))
308 self.capitalisation_mode = gmTools.CAPS_FIRST
309 self.selection_only = True
310 #====================================================================
311 from Gnumed.wxGladeWidgets import wxgProvinceEAPnl
312
314
316
317 try:
318 data = kwargs['province']
319 del kwargs['province']
320 except KeyError:
321 data = None
322
323 wxgProvinceEAPnl.wxgProvinceEAPnl.__init__(self, *args, **kwargs)
324 gmEditArea.cGenericEditAreaMixin.__init__(self)
325
326 self.mode = 'new'
327 self.data = data
328 if data is not None:
329 self.mode = 'edit'
330
331 self.__init_ui()
332 #----------------------------------------------------------------
335 #----------------------------------------------------------------
336 # generic Edit Area mixin API
337 #----------------------------------------------------------------
339
340 validity = True
341
342 if self._PRW_province.GetData() is None:
343 if self._PRW_province.GetValue().strip() == u'':
344 validity = False
345 self._PRW_province.display_as_valid(False)
346 else:
347 self._PRW_province.display_as_valid(True)
348 else:
349 self._PRW_province.display_as_valid(True)
350
351 if self._PRW_province.GetData() is None:
352 if self._TCTRL_code.GetValue().strip() == u'':
353 validity = False
354 self._TCTRL_code.SetBackgroundColour(gmPhraseWheel.color_prw_invalid)
355 else:
356 self._TCTRL_code.SetBackgroundColour(gmPhraseWheel.color_prw_valid)
357
358 if self._PRW_country.GetData() is None:
359 validity = False
360 self._PRW_country.display_as_valid(False)
361 else:
362 self._PRW_country.display_as_valid(True)
363
364 return validity
365 #----------------------------------------------------------------
367 gmDemographicRecord.create_province (
368 name = self._PRW_province.GetValue().strip(),
369 code = self._TCTRL_code.GetValue().strip(),
370 country = self._PRW_country.GetData()
371 )
372
373 # EA is refreshed automatically after save, so need this ...
374 self.data = {
375 'l10n_state' : self._PRW_province.GetValue().strip(),
376 'code_state' : self._TCTRL_code.GetValue().strip(),
377 'l10n_country' : self._PRW_country.GetValue().strip()
378 }
379
380 return True
381 #----------------------------------------------------------------
383 # update self.data and save the changes
384 #self.data[''] =
385 #self.data[''] =
386 #self.data[''] =
387 #self.data.save()
388
389 # do nothing for now (IOW, don't support updates)
390 return True
391 #----------------------------------------------------------------
393 self._PRW_province.SetText()
394 self._TCTRL_code.SetValue(u'')
395 self._PRW_country.SetText()
396
397 self._PRW_province.SetFocus()
398 #----------------------------------------------------------------
400 self._PRW_province.SetText(self.data['l10n_state'], self.data['code_state'])
401 self._TCTRL_code.SetValue(self.data['code_state'])
402 self._PRW_country.SetText(self.data['l10n_country'], self.data['code_country'])
403
404 self._PRW_province.SetFocus()
405 #----------------------------------------------------------------
412
413 #============================================================
414 # address phrasewheels and widgets
415 #============================================================
417 """A list for managing a person's addresses.
418
419 Does NOT act on/listen to the current patient.
420 """
422
423 try:
424 self.__identity = kwargs['identity']
425 del kwargs['identity']
426 except KeyError:
427 self.__identity = None
428
429 gmListWidgets.cGenericListManagerPnl.__init__(self, *args, **kwargs)
430
431 self.new_callback = self._add_address
432 self.edit_callback = self._edit_address
433 self.delete_callback = self._del_address
434 self.refresh_callback = self.refresh
435
436 self.__init_ui()
437 self.refresh()
438 #--------------------------------------------------------
439 # external API
440 #--------------------------------------------------------
442 if self.__identity is None:
443 self._LCTRL_items.set_string_items()
444 return
445
446 adrs = self.__identity.get_addresses()
447 self._LCTRL_items.set_string_items (
448 items = [ [
449 a['l10n_address_type'],
450 a['street'],
451 gmTools.coalesce(a['notes_street'], u''),
452 a['number'],
453 gmTools.coalesce(a['subunit'], u''),
454 a['postcode'],
455 a['urb'],
456 gmTools.coalesce(a['suburb'], u''),
457 a['l10n_state'],
458 a['l10n_country'],
459 gmTools.coalesce(a['notes_subunit'], u'')
460 ] for a in adrs
461 ]
462 )
463 self._LCTRL_items.set_column_widths()
464 self._LCTRL_items.set_data(data = adrs)
465 #--------------------------------------------------------
466 # internal helpers
467 #--------------------------------------------------------
469 self._LCTRL_items.SetToolTipString(_('List of known addresses.'))
470 self._LCTRL_items.set_columns(columns = [
471 _('Type'),
472 _('Street'),
473 _('Street info'),
474 _('Number'),
475 _('Subunit'),
476 _('Postal code'),
477 _('Place'),
478 _('Suburb'),
479 _('Region'),
480 _('Country'),
481 _('Comment')
482 ])
483 #--------------------------------------------------------
485 ea = cAddressEditAreaPnl(self, -1)
486 ea.identity = self.__identity
487 dlg = gmEditArea.cGenericEditAreaDlg(self, -1, edit_area = ea)
488 dlg.SetTitle(_('Adding new address'))
489 if dlg.ShowModal() == wx.ID_OK:
490 return True
491 return False
492 #--------------------------------------------------------
494 ea = cAddressEditAreaPnl(self, -1, address = address)
495 ea.identity = self.__identity
496 dlg = gmEditArea.cGenericEditAreaDlg(self, -1, edit_area = ea)
497 dlg.SetTitle(_('Editing address'))
498 if dlg.ShowModal() == wx.ID_OK:
499 # did we add an entirely new address ?
500 # if so then unlink the old one as implied by "edit"
501 if ea.address['pk_address'] != address['pk_address']:
502 self.__identity.unlink_address(address = address)
503 return True
504 return False
505 #--------------------------------------------------------
507 go_ahead = gmGuiHelpers.gm_show_question (
508 _( 'Are you sure you want to remove this\n'
509 "address from the patient's addresses ?\n"
510 '\n'
511 'The address itself will not be deleted\n'
512 'but it will no longer be associated with\n'
513 'this patient.'
514 ),
515 _('Removing address')
516 )
517 if not go_ahead:
518 return False
519 self.__identity.unlink_address(address = address)
520 return True
521 #--------------------------------------------------------
522 # properties
523 #--------------------------------------------------------
526
530
531 identity = property(_get_identity, _set_identity)
532 #============================================================
533 from Gnumed.wxGladeWidgets import wxgGenericAddressEditAreaPnl
534
536 """An edit area for editing/creating an address.
537
538 Does NOT act on/listen to the current patient.
539 """
541 try:
542 self.address = kwargs['address']
543 del kwargs['address']
544 except KeyError:
545 self.address = None
546
547 wxgGenericAddressEditAreaPnl.wxgGenericAddressEditAreaPnl.__init__(self, *args, **kwargs)
548
549 self.identity = None
550
551 self.__register_interests()
552 self.refresh()
553 #--------------------------------------------------------
554 # external API
555 #--------------------------------------------------------
557 if address is not None:
558 self.address = address
559
560 if self.address is not None:
561 self._PRW_type.SetText(self.address['l10n_address_type'])
562 self._PRW_zip.SetText(self.address['postcode'])
563 self._PRW_street.SetText(self.address['street'], data = self.address['street'])
564 self._TCTRL_notes_street.SetValue(gmTools.coalesce(self.address['notes_street'], ''))
565 self._TCTRL_number.SetValue(self.address['number'])
566 self._TCTRL_subunit.SetValue(gmTools.coalesce(self.address['subunit'], ''))
567 self._PRW_suburb.SetText(gmTools.coalesce(self.address['suburb'], ''))
568 self._PRW_urb.SetText(self.address['urb'], data = self.address['urb'])
569 self._PRW_state.SetText(self.address['l10n_state'], data = self.address['code_state'])
570 self._PRW_country.SetText(self.address['l10n_country'], data = self.address['code_country'])
571 self._TCTRL_notes_subunit.SetValue(gmTools.coalesce(self.address['notes_subunit'], ''))
572 # FIXME: clear fields
573 # else:
574 # pass
575 #--------------------------------------------------------
577 """Links address to patient, creating new address if necessary"""
578
579 if not self.__valid_for_save():
580 return False
581
582 # link address to patient
583 try:
584 adr = self.identity.link_address (
585 number = self._TCTRL_number.GetValue().strip(),
586 street = self._PRW_street.GetValue().strip(),
587 postcode = self._PRW_zip.GetValue().strip(),
588 urb = self._PRW_urb.GetValue().strip(),
589 state = self._PRW_state.GetData(),
590 country = self._PRW_country.GetData(),
591 subunit = gmTools.none_if(self._TCTRL_subunit.GetValue().strip(), u''),
592 suburb = gmTools.none_if(self._PRW_suburb.GetValue().strip(), u''),
593 id_type = self._PRW_type.GetData()
594 )
595 except:
596 _log.exception('cannot save address')
597 gmGuiHelpers.gm_show_error (
598 _('Cannot save address.\n\n'
599 'Does the state [%s]\n'
600 'exist in country [%s] ?'
601 ) % (
602 self._PRW_state.GetValue().strip(),
603 self._PRW_country.GetValue().strip()
604 ),
605 _('Saving address')
606 )
607 return False
608
609 notes = self._TCTRL_notes_street.GetValue().strip()
610 if notes != u'':
611 adr['notes_street'] = notes
612 notes = self._TCTRL_notes_subunit.GetValue().strip()
613 if notes != u'':
614 adr['notes_subunit'] = notes
615 adr.save_payload()
616
617 self.address = adr
618
619 return True
620 #--------------------------------------------------------
621 # event handling
622 #--------------------------------------------------------
624 self._PRW_zip.add_callback_on_lose_focus(self._on_zip_set)
625 self._PRW_country.add_callback_on_lose_focus(self._on_country_set)
626 #--------------------------------------------------------
628 """Set the street, town, state and country according to entered zip code."""
629 zip_code = self._PRW_zip.GetValue()
630 if zip_code.strip() == u'':
631 self._PRW_street.unset_context(context = u'zip')
632 self._PRW_urb.unset_context(context = u'zip')
633 self._PRW_state.unset_context(context = u'zip')
634 self._PRW_country.unset_context(context = u'zip')
635 else:
636 self._PRW_street.set_context(context = u'zip', val = zip_code)
637 self._PRW_urb.set_context(context = u'zip', val = zip_code)
638 self._PRW_state.set_context(context = u'zip', val = zip_code)
639 self._PRW_country.set_context(context = u'zip', val = zip_code)
640 #--------------------------------------------------------
642 """Set the states according to entered country."""
643 country = self._PRW_country.GetData()
644 if country is None:
645 self._PRW_state.unset_context(context = 'country')
646 else:
647 self._PRW_state.set_context(context = 'country', val = country)
648 #--------------------------------------------------------
649 # internal helpers
650 #--------------------------------------------------------
652
653 # validate required fields
654 is_any_field_filled = False
655
656 required_fields = (
657 self._PRW_type,
658 self._PRW_zip,
659 self._PRW_street,
660 self._TCTRL_number,
661 self._PRW_urb
662 )
663 for field in required_fields:
664 if len(field.GetValue().strip()) == 0:
665 if is_any_field_filled:
666 field.SetBackgroundColour('pink')
667 field.SetFocus()
668 field.Refresh()
669 gmGuiHelpers.gm_show_error (
670 _('Address details must be filled in completely or not at all.'),
671 _('Saving contact data')
672 )
673 return False
674 else:
675 is_any_field_filled = True
676 field.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
677 field.Refresh()
678
679 required_fields = (
680 self._PRW_state,
681 self._PRW_country
682 )
683 for field in required_fields:
684 if field.GetData() is None:
685 if is_any_field_filled:
686 field.SetBackgroundColour('pink')
687 field.SetFocus()
688 field.Refresh()
689 gmGuiHelpers.gm_show_error (
690 _('Address details must be filled in completely or not at all.'),
691 _('Saving contact data')
692 )
693 return False
694 else:
695 is_any_field_filled = True
696 field.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
697 field.Refresh()
698
699 return True
700 #============================================================
702
704
705 query = u"""
706 select * from (
707 (select
708 pk_address,
709 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
710 || urb || coalesce(' (' || suburb || ')', '') || ', '
711 || postcode
712 || coalesce(', ' || notes_street, '')
713 || coalesce(', ' || notes_subunit, '')
714 ) as address
715 from
716 dem.v_address
717 where
718 street %(fragment_condition)s
719
720 ) union (
721
722 select
723 pk_address,
724 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
725 || urb || coalesce(' (' || suburb || ')', '') || ', '
726 || postcode
727 || coalesce(', ' || notes_street, '')
728 || coalesce(', ' || notes_subunit, '')
729 ) as address
730 from
731 dem.v_address
732 where
733 postcode_street %(fragment_condition)s
734
735 ) union (
736
737 select
738 pk_address,
739 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
740 || urb || coalesce(' (' || suburb || ')', '') || ', '
741 || postcode
742 || coalesce(', ' || notes_street, '')
743 || coalesce(', ' || notes_subunit, '')
744 ) as address
745 from
746 dem.v_address
747 where
748 postcode_urb %(fragment_condition)s
749 )
750 ) as union_result
751 order by union_result.address limit 50"""
752
753 gmMatchProvider.cMatchProvider_SQL2.__init__(self, queries = query)
754
755 self.setThresholds(2, 4, 6)
756 # self.word_separators = u'[ \t]+'
757
758 #============================================================
760
762
763 mp = cAddressMatchProvider()
764 gmPhraseWheel.cPhraseWheel.__init__ (
765 self,
766 *args,
767 **kwargs
768 )
769 self.matcher = cAddressMatchProvider()
770 self.SetToolTipString(_('Select an address by postcode or street name.'))
771 self.selection_only = True
772 self.__address = None
773 self.__old_pk = None
774 #--------------------------------------------------------
776
777 pk = self.GetData()
778
779 if pk is None:
780 self.__address = None
781 return None
782
783 if self.__address is None:
784 self.__old_pk = pk
785 self.__address = gmDemographicRecord.cAddress(aPK_obj = pk)
786 else:
787 if pk != self.__old_pk:
788 self.__old_pk = pk
789 self.__address = gmDemographicRecord.cAddress(aPK_obj = pk)
790
791 return self.__address
792 #============================================================
794
796
797 query = u"""
798 select id, type from ((
799 select id, _(name) as type, 1 as rank
800 from dem.address_type
801 where _(name) %(fragment_condition)s
802 ) union (
803 select id, name as type, 2 as rank
804 from dem.address_type
805 where name %(fragment_condition)s
806 )) as ur
807 order by
808 ur.rank, ur.type
809 """
810 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
811 mp.setThresholds(1, 2, 4)
812 mp.word_separators = u'[ \t]+'
813 gmPhraseWheel.cPhraseWheel.__init__ (
814 self,
815 *args,
816 **kwargs
817 )
818 self.matcher = mp
819 self.SetToolTipString(_('Select the type of address.'))
820 # self.capitalisation_mode = gmTools.CAPS_FIRST
821 self.selection_only = True
822 #--------------------------------------------------------
823 # def GetData(self, can_create=False):
824 # if self.data is None:
825 # if can_create:
826 # self.data = gmDocuments.create_document_type(self.GetValue().strip())['pk_doc_type'] # FIXME: error handling
827 # return self.data
828 #============================================================
830
832 # FIXME: add possible context
833 query = u"""
834 (select distinct postcode, postcode from dem.street where postcode %(fragment_condition)s limit 20)
835 union
836 (select distinct postcode, postcode from dem.urb where postcode %(fragment_condition)s limit 20)"""
837 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
838 mp.setThresholds(2, 3, 15)
839 gmPhraseWheel.cPhraseWheel.__init__ (
840 self,
841 *args,
842 **kwargs
843 )
844 self.SetToolTipString(_("Type or select a zip code (postcode)."))
845 self.matcher = mp
846 #============================================================
848
850 context = {
851 u'ctxt_zip': {
852 u'where_part': u'and zip ilike %(zip)s',
853 u'placeholder': u'zip'
854 }
855 }
856 query = u"""
857 select s1, s2 from (
858 select s1, s2, rank from (
859 select distinct on (street)
860 street as s1, street as s2, 1 as rank
861 from dem.v_zip2data
862 where
863 street %(fragment_condition)s
864 %(ctxt_zip)s
865
866 union all
867
868 select distinct on (name)
869 name as s1, name as s2, 2 as rank
870 from dem.street
871 where
872 name %(fragment_condition)s
873
874 ) as q2
875 ) as q1 order by rank, s2 limit 50"""
876 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
877 mp.setThresholds(3, 5, 8)
878 gmPhraseWheel.cPhraseWheel.__init__ (
879 self,
880 *args,
881 **kwargs
882 )
883 self.unset_context(context = u'zip')
884
885 self.SetToolTipString(_('Type or select a street.'))
886 self.capitalisation_mode = gmTools.CAPS_FIRST
887 self.matcher = mp
888 #============================================================
890
892
893 query = """
894 select distinct on (suburb) suburb, suburb
895 from dem.street
896 where suburb %(fragment_condition)s
897 order by suburb
898 limit 50
899 """
900 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
901 mp.setThresholds(2, 3, 6)
902 gmPhraseWheel.cPhraseWheel.__init__ (
903 self,
904 *args,
905 **kwargs
906 )
907
908 self.SetToolTipString(_('Type or select the suburb.'))
909 self.capitalisation_mode = gmTools.CAPS_FIRST
910 self.matcher = mp
911 #============================================================
913
915 context = {
916 u'ctxt_zip': {
917 u'where_part': u'and zip ilike %(zip)s',
918 u'placeholder': u'zip'
919 }
920 }
921 query = u"""
922 select u1, u2 from (
923 select distinct on (rank, u1)
924 u1, u2, rank
925 from (
926 select
927 urb as u1, urb as u2, 1 as rank
928 from dem.v_zip2data
929 where
930 urb %(fragment_condition)s
931 %(ctxt_zip)s
932
933 union all
934
935 select
936 name as u1, name as u2, 2 as rank
937 from dem.urb
938 where
939 name %(fragment_condition)s
940 ) as union_result
941 order by rank, u1
942 ) as distincted_union
943 limit 50
944 """
945 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
946 mp.setThresholds(3, 5, 7)
947 gmPhraseWheel.cPhraseWheel.__init__ (
948 self,
949 *args,
950 **kwargs
951 )
952 self.unset_context(context = u'zip')
953
954 self.SetToolTipString(_('Type or select a city/town/village/dwelling.'))
955 self.capitalisation_mode = gmTools.CAPS_FIRST
956 self.matcher = mp
957
958 #============================================================
959 # communication channels related widgets
960 #============================================================
962
964
965 query = u"""
966 select pk, type from ((
967 select pk, _(description) as type, 1 as rank
968 from dem.enum_comm_types
969 where _(description) %(fragment_condition)s
970 ) union (
971 select pk, description as type, 2 as rank
972 from dem.enum_comm_types
973 where description %(fragment_condition)s
974 )) as ur
975 order by
976 ur.rank, ur.type
977 """
978 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
979 mp.setThresholds(1, 2, 4)
980 mp.word_separators = u'[ \t]+'
981 gmPhraseWheel.cPhraseWheel.__init__ (
982 self,
983 *args,
984 **kwargs
985 )
986 self.matcher = mp
987 self.SetToolTipString(_('Select the type of communications channel.'))
988 self.selection_only = True
989
990 #------------------------------------------------------------
991 from Gnumed.wxGladeWidgets import wxgCommChannelEditAreaPnl
992
994 """An edit area for editing/creating a comms channel.
995
996 Does NOT act on/listen to the current patient.
997 """
999 try:
1000 self.channel = kwargs['comm_channel']
1001 del kwargs['comm_channel']
1002 except KeyError:
1003 self.channel = None
1004
1005 wxgCommChannelEditAreaPnl.wxgCommChannelEditAreaPnl.__init__(self, *args, **kwargs)
1006
1007 self.identity = None
1008
1009 self.refresh()
1010 #--------------------------------------------------------
1011 # external API
1012 #--------------------------------------------------------
1014 if comm_channel is not None:
1015 self.channel = comm_channel
1016
1017 if self.channel is None:
1018 self._PRW_type.SetText(u'')
1019 self._TCTRL_url.SetValue(u'')
1020 self._PRW_address.SetText(value = u'', data = None)
1021 self._CHBOX_confidential.SetValue(False)
1022 else:
1023 self._PRW_type.SetText(self.channel['l10n_comm_type'])
1024 self._TCTRL_url.SetValue(self.channel['url'])
1025 self._PRW_address.SetData(data = self.channel['pk_address'])
1026 self._CHBOX_confidential.SetValue(self.channel['is_confidential'])
1027 #--------------------------------------------------------
1029 """Links comm channel to patient."""
1030 if self.channel is None:
1031 if not self.__valid_for_save():
1032 return False
1033 try:
1034 self.channel = self.identity.link_comm_channel (
1035 pk_channel_type = self._PRW_type.GetData(),
1036 url = self._TCTRL_url.GetValue().strip(),
1037 is_confidential = self._CHBOX_confidential.GetValue(),
1038 )
1039 except gmPG2.dbapi.IntegrityError:
1040 _log.exception('error saving comm channel')
1041 gmDispatcher.send(signal = u'statustext', msg = _('Cannot save communications channel.'), beep = True)
1042 return False
1043 else:
1044 comm_type = self._PRW_type.GetValue().strip()
1045 if comm_type != u'':
1046 self.channel['comm_type'] = comm_type
1047 url = self._TCTRL_url.GetValue().strip()
1048 if url != u'':
1049 self.channel['url'] = url
1050 self.channel['is_confidential'] = self._CHBOX_confidential.GetValue()
1051
1052 self.channel['pk_address'] = self._PRW_address.GetData()
1053 self.channel.save_payload()
1054
1055 return True
1056 #--------------------------------------------------------
1057 # internal helpers
1058 #--------------------------------------------------------
1060
1061 no_errors = True
1062
1063 if self._PRW_type.GetData() is None:
1064 self._PRW_type.SetBackgroundColour('pink')
1065 self._PRW_type.SetFocus()
1066 self._PRW_type.Refresh()
1067 no_errors = False
1068 else:
1069 self._PRW_type.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
1070 self._PRW_type.Refresh()
1071
1072 if self._TCTRL_url.GetValue().strip() == u'':
1073 self._TCTRL_url.SetBackgroundColour('pink')
1074 self._TCTRL_url.SetFocus()
1075 self._TCTRL_url.Refresh()
1076 no_errors = False
1077 else:
1078 self._TCTRL_url.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
1079 self._TCTRL_url.Refresh()
1080
1081 return no_errors
1082
1083 #------------------------------------------------------------
1085 """A list for managing a person's comm channels.
1086
1087 Does NOT act on/listen to the current patient.
1088 """
1090
1091 try:
1092 self.__identity = kwargs['identity']
1093 del kwargs['identity']
1094 except KeyError:
1095 self.__identity = None
1096
1097 gmListWidgets.cGenericListManagerPnl.__init__(self, *args, **kwargs)
1098
1099 self.new_callback = self._add_comm
1100 self.edit_callback = self._edit_comm
1101 self.delete_callback = self._del_comm
1102 self.refresh_callback = self.refresh
1103
1104 self.__init_ui()
1105 self.refresh()
1106 #--------------------------------------------------------
1107 # external API
1108 #--------------------------------------------------------
1110 if self.__identity is None:
1111 self._LCTRL_items.set_string_items()
1112 return
1113
1114 comms = self.__identity.get_comm_channels()
1115 self._LCTRL_items.set_string_items (
1116 items = [ [ gmTools.bool2str(c['is_confidential'], u'X', u''), c['l10n_comm_type'], c['url'] ] for c in comms ]
1117 )
1118 self._LCTRL_items.set_column_widths()
1119 self._LCTRL_items.set_data(data = comms)
1120 #--------------------------------------------------------
1121 # internal helpers
1122 #--------------------------------------------------------
1124 self._LCTRL_items.SetToolTipString(_('List of known communication channels.'))
1125 self._LCTRL_items.set_columns(columns = [
1126 _('confidential'),
1127 _('Type'),
1128 _('Value')
1129 ])
1130 #--------------------------------------------------------
1132 ea = cCommChannelEditAreaPnl(self, -1)
1133 ea.identity = self.__identity
1134 dlg = gmEditArea.cGenericEditAreaDlg(self, -1, edit_area = ea)
1135 dlg.SetTitle(_('Adding new communications channel'))
1136 if dlg.ShowModal() == wx.ID_OK:
1137 return True
1138 return False
1139 #--------------------------------------------------------
1141 ea = cCommChannelEditAreaPnl(self, -1, comm_channel = comm_channel)
1142 ea.identity = self.__identity
1143 dlg = gmEditArea.cGenericEditAreaDlg(self, -1, edit_area = ea)
1144 dlg.SetTitle(_('Editing communications channel'))
1145 if dlg.ShowModal() == wx.ID_OK:
1146 return True
1147 return False
1148 #--------------------------------------------------------
1150 go_ahead = gmGuiHelpers.gm_show_question (
1151 _( 'Are you sure this patient can no longer\n'
1152 "be contacted via this channel ?"
1153 ),
1154 _('Removing communication channel')
1155 )
1156 if not go_ahead:
1157 return False
1158 self.__identity.unlink_comm_channel(comm_channel = comm)
1159 return True
1160 #--------------------------------------------------------
1161 # properties
1162 #--------------------------------------------------------
1165
1169
1170 identity = property(_get_identity, _set_identity)
1171
1172 #------------------------------------------------------------
1173 from Gnumed.wxGladeWidgets import wxgPersonContactsManagerPnl
1174
1176 """A panel for editing contact data for a person.
1177
1178 - provides access to:
1179 - addresses
1180 - communication paths
1181
1182 Does NOT act on/listen to the current patient.
1183 """
1185
1186 wxgPersonContactsManagerPnl.wxgPersonContactsManagerPnl.__init__(self, *args, **kwargs)
1187
1188 self.__identity = None
1189 self.refresh()
1190 #--------------------------------------------------------
1191 # external API
1192 #--------------------------------------------------------
1196 #--------------------------------------------------------
1197 # properties
1198 #--------------------------------------------------------
1201
1205
1206 identity = property(_get_identity, _set_identity)
1207
1208 #============================================================
1209 if __name__ == "__main__":
1210
1211 #--------------------------------------------------------
1213 app = wx.PyWidgetTester(size = (200, 50))
1214 pw = cStateSelectionPhraseWheel(app.frame, -1)
1215 # pw.set_context(context = u'zip', val = u'04318')
1216 # pw.set_context(context = u'country', val = u'Deutschland')
1217 app.frame.Show(True)
1218 app.MainLoop()
1219 #--------------------------------------------------------
1221 app = wx.PyWidgetTester(size = (600, 400))
1222 widget = cPersonAddressesManagerPnl(app.frame, -1)
1223 widget.identity = activate_patient()
1224 app.frame.Show(True)
1225 app.MainLoop()
1226 #--------------------------------------------------------
1228 app = wx.PyWidgetTester(size = (600, 400))
1229 app.SetWidget(cAddressEditAreaPnl, address = gmDemographicRecord.cAddress(aPK_obj = 1))
1230 app.MainLoop()
1231 #--------------------------------------------------------
1233 app = wx.PyWidgetTester(size = (200, 50))
1234 pw = cAddressPhraseWheel(app.frame, -1)
1235 app.frame.Show(True)
1236 app.MainLoop()
1237 #--------------------------------------------------------
1239 app = wx.PyWidgetTester(size = (200, 50))
1240 pw = cAddressTypePhraseWheel(app.frame, -1)
1241 app.frame.Show(True)
1242 app.MainLoop()
1243 #--------------------------------------------------------
1245 app = wx.PyWidgetTester(size = (200, 50))
1246 pw = cZipcodePhraseWheel(app.frame, -1)
1247 app.frame.Show(True)
1248 app.MainLoop()
1249 #--------------------------------------------------------
1251 app = wx.PyWidgetTester(size = (200, 50))
1252 pw = cStreetPhraseWheel(app.frame, -1)
1253 # pw.set_context(context = u'zip', val = u'04318')
1254 app.frame.Show(True)
1255 app.MainLoop()
1256 #--------------------------------------------------------
1258 app = wx.PyWidgetTester(size = (200, 50))
1259 pw = cSuburbPhraseWheel(app.frame, -1)
1260 app.frame.Show(True)
1261 app.MainLoop()
1262 #--------------------------------------------------------
1264 app = wx.PyWidgetTester(size = (200, 50))
1265 pw = cUrbPhraseWheel(app.frame, -1)
1266 app.frame.Show(True)
1267 pw.set_context(context = u'zip', val = u'04317')
1268 app.MainLoop()
1269 #--------------------------------------------------------
1271 app = wx.PyWidgetTester(size = (600, 400))
1272 widget = cPersonCommsManagerPnl(app.frame, -1)
1273 widget.identity = activate_patient()
1274 app.frame.Show(True)
1275 app.MainLoop()
1276
1277 #============================================================
1278
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Fri Oct 1 04:05:23 2010 | http://epydoc.sourceforge.net |