| 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
418 if parent is None:
419 parent = wx.GetApp().GetTopWindow()
420 #------------------------------------------------------------
421 def refresh(lctrl):
422 adrs = gmDemographicRecord.get_addresses(order_by = u'l10n_country, urb, street, number, subunit')
423 items = [ [
424 a['street'],
425 gmTools.coalesce(a['notes_street'], u''),
426 a['number'],
427 gmTools.coalesce(a['subunit'], u''),
428 a['postcode'],
429 a['urb'],
430 gmTools.coalesce(a['suburb'], u''),
431 a['l10n_state'],
432 a['l10n_country'],
433 gmTools.coalesce(a['notes_subunit'], u'')
434 ] for a in adrs
435 ]
436 lctrl.set_string_items(items)
437 lctrl.set_data(adrs)
438
439 #------------------------------------------------------------
440 cols = [
441 _('Street'),
442 _('Street info'),
443 _('Number'),
444 _('Subunit'),
445 _('Postal code'),
446 _('Place'),
447 _('Suburb'),
448 _('Region'),
449 _('Country'),
450 _('Comment')
451 ]
452 gmListWidgets.get_choices_from_list (
453 parent = parent,
454 caption = _('Showing addresses registered in GNUmed.'),
455 columns = cols,
456 single_selection = True,
457 refresh_callback = refresh
458 )
459 #============================================================
461 """A list for managing a person's addresses.
462
463 Does NOT act on/listen to the current patient.
464 """
466
467 try:
468 self.__identity = kwargs['identity']
469 del kwargs['identity']
470 except KeyError:
471 self.__identity = None
472
473 gmListWidgets.cGenericListManagerPnl.__init__(self, *args, **kwargs)
474
475 self.new_callback = self._add_address
476 self.edit_callback = self._edit_address
477 self.delete_callback = self._del_address
478 self.refresh_callback = self.refresh
479
480 self.__init_ui()
481 self.refresh()
482 #--------------------------------------------------------
483 # external API
484 #--------------------------------------------------------
486 if self.__identity is None:
487 self._LCTRL_items.set_string_items()
488 return
489
490 adrs = self.__identity.get_addresses()
491 self._LCTRL_items.set_string_items (
492 items = [ [
493 a['l10n_address_type'],
494 a['street'],
495 gmTools.coalesce(a['notes_street'], u''),
496 a['number'],
497 gmTools.coalesce(a['subunit'], u''),
498 a['postcode'],
499 a['urb'],
500 gmTools.coalesce(a['suburb'], u''),
501 a['l10n_state'],
502 a['l10n_country'],
503 gmTools.coalesce(a['notes_subunit'], u'')
504 ] for a in adrs
505 ]
506 )
507 self._LCTRL_items.set_column_widths()
508 self._LCTRL_items.set_data(data = adrs)
509 #--------------------------------------------------------
510 # internal helpers
511 #--------------------------------------------------------
513 self._LCTRL_items.SetToolTipString(_('List of known addresses.'))
514 self._LCTRL_items.set_columns(columns = [
515 _('Type'),
516 _('Street'),
517 _('Street info'),
518 _('Number'),
519 _('Subunit'),
520 _('Postal code'),
521 _('Place'),
522 _('Suburb'),
523 _('Region'),
524 _('Country'),
525 _('Comment')
526 ])
527 #--------------------------------------------------------
529 ea = cAddressEditAreaPnl(self, -1)
530 ea.identity = self.__identity
531 dlg = gmEditArea.cGenericEditAreaDlg(self, -1, edit_area = ea)
532 dlg.SetTitle(_('Adding new address'))
533 if dlg.ShowModal() == wx.ID_OK:
534 return True
535 return False
536 #--------------------------------------------------------
538 ea = cAddressEditAreaPnl(self, -1, address = address)
539 ea.identity = self.__identity
540 dlg = gmEditArea.cGenericEditAreaDlg(self, -1, edit_area = ea)
541 dlg.SetTitle(_('Editing address'))
542 if dlg.ShowModal() == wx.ID_OK:
543 # did we add an entirely new address ?
544 # if so then unlink the old one as implied by "edit"
545 if ea.address['pk_address'] != address['pk_address']:
546 self.__identity.unlink_address(address = address)
547 return True
548 return False
549 #--------------------------------------------------------
551 go_ahead = gmGuiHelpers.gm_show_question (
552 _( 'Are you sure you want to remove this\n'
553 "address from the patient's addresses ?\n"
554 '\n'
555 'The address itself will not be deleted\n'
556 'but it will no longer be associated with\n'
557 'this patient.'
558 ),
559 _('Removing address')
560 )
561 if not go_ahead:
562 return False
563 self.__identity.unlink_address(address = address)
564 return True
565 #--------------------------------------------------------
566 # properties
567 #--------------------------------------------------------
570
574
575 identity = property(_get_identity, _set_identity)
576 #============================================================
577 from Gnumed.wxGladeWidgets import wxgGenericAddressEditAreaPnl
578
580 """An edit area for editing/creating an address.
581
582 Does NOT act on/listen to the current patient.
583 """
585 try:
586 self.address = kwargs['address']
587 del kwargs['address']
588 except KeyError:
589 self.address = None
590
591 wxgGenericAddressEditAreaPnl.wxgGenericAddressEditAreaPnl.__init__(self, *args, **kwargs)
592
593 self.identity = None
594
595 self.__register_interests()
596 self.refresh()
597 #--------------------------------------------------------
598 # external API
599 #--------------------------------------------------------
601 if address is not None:
602 self.address = address
603
604 if self.address is not None:
605 self._PRW_type.SetText(self.address['l10n_address_type'])
606 self._PRW_zip.SetText(self.address['postcode'])
607 self._PRW_street.SetText(self.address['street'], data = self.address['street'])
608 self._TCTRL_notes_street.SetValue(gmTools.coalesce(self.address['notes_street'], ''))
609 self._TCTRL_number.SetValue(self.address['number'])
610 self._TCTRL_subunit.SetValue(gmTools.coalesce(self.address['subunit'], ''))
611 self._PRW_suburb.SetText(gmTools.coalesce(self.address['suburb'], ''))
612 self._PRW_urb.SetText(self.address['urb'], data = self.address['urb'])
613 self._PRW_state.SetText(self.address['l10n_state'], data = self.address['code_state'])
614 self._PRW_country.SetText(self.address['l10n_country'], data = self.address['code_country'])
615 self._TCTRL_notes_subunit.SetValue(gmTools.coalesce(self.address['notes_subunit'], ''))
616 # FIXME: clear fields
617 # else:
618 # pass
619 #--------------------------------------------------------
621 """Links address to patient, creating new address if necessary"""
622
623 if not self.__valid_for_save():
624 return False
625
626 # link address to patient
627 try:
628 adr = self.identity.link_address (
629 number = self._TCTRL_number.GetValue().strip(),
630 street = self._PRW_street.GetValue().strip(),
631 postcode = self._PRW_zip.GetValue().strip(),
632 urb = self._PRW_urb.GetValue().strip(),
633 state = self._PRW_state.GetData(),
634 country = self._PRW_country.GetData(),
635 subunit = gmTools.none_if(self._TCTRL_subunit.GetValue().strip(), u''),
636 suburb = gmTools.none_if(self._PRW_suburb.GetValue().strip(), u''),
637 id_type = self._PRW_type.GetData()
638 )
639 except:
640 _log.exception('cannot save address')
641 gmGuiHelpers.gm_show_error (
642 _('Cannot save address.\n\n'
643 'Does the state [%s]\n'
644 'exist in country [%s] ?'
645 ) % (
646 self._PRW_state.GetValue().strip(),
647 self._PRW_country.GetValue().strip()
648 ),
649 _('Saving address')
650 )
651 return False
652
653 notes = self._TCTRL_notes_street.GetValue().strip()
654 if notes != u'':
655 adr['notes_street'] = notes
656 notes = self._TCTRL_notes_subunit.GetValue().strip()
657 if notes != u'':
658 adr['notes_subunit'] = notes
659 adr.save_payload()
660
661 self.address = adr
662
663 return True
664 #--------------------------------------------------------
665 # event handling
666 #--------------------------------------------------------
668 self._PRW_zip.add_callback_on_lose_focus(self._on_zip_set)
669 self._PRW_country.add_callback_on_lose_focus(self._on_country_set)
670 #--------------------------------------------------------
672 """Set the street, town, state and country according to entered zip code."""
673 zip_code = self._PRW_zip.GetValue()
674 if zip_code.strip() == u'':
675 self._PRW_street.unset_context(context = u'zip')
676 self._PRW_urb.unset_context(context = u'zip')
677 self._PRW_state.unset_context(context = u'zip')
678 self._PRW_country.unset_context(context = u'zip')
679 else:
680 self._PRW_street.set_context(context = u'zip', val = zip_code)
681 self._PRW_urb.set_context(context = u'zip', val = zip_code)
682 self._PRW_state.set_context(context = u'zip', val = zip_code)
683 self._PRW_country.set_context(context = u'zip', val = zip_code)
684 #--------------------------------------------------------
686 """Set the states according to entered country."""
687 country = self._PRW_country.GetData()
688 if country is None:
689 self._PRW_state.unset_context(context = 'country')
690 else:
691 self._PRW_state.set_context(context = 'country', val = country)
692 #--------------------------------------------------------
693 # internal helpers
694 #--------------------------------------------------------
696
697 # validate required fields
698 is_any_field_filled = False
699
700 required_fields = (
701 self._PRW_type,
702 self._PRW_zip,
703 self._PRW_street,
704 self._TCTRL_number,
705 self._PRW_urb
706 )
707 for field in required_fields:
708 if len(field.GetValue().strip()) == 0:
709 if is_any_field_filled:
710 field.SetBackgroundColour('pink')
711 field.SetFocus()
712 field.Refresh()
713 gmGuiHelpers.gm_show_error (
714 _('Address details must be filled in completely or not at all.'),
715 _('Saving contact data')
716 )
717 return False
718 else:
719 is_any_field_filled = True
720 field.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
721 field.Refresh()
722
723 required_fields = (
724 self._PRW_state,
725 self._PRW_country
726 )
727 for field in required_fields:
728 if field.GetData() is None:
729 if is_any_field_filled:
730 field.SetBackgroundColour('pink')
731 field.SetFocus()
732 field.Refresh()
733 gmGuiHelpers.gm_show_error (
734 _('Address details must be filled in completely or not at all.'),
735 _('Saving contact data')
736 )
737 return False
738 else:
739 is_any_field_filled = True
740 field.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
741 field.Refresh()
742
743 return True
744 #============================================================
746
748
749 query = u"""
750 select * from (
751 (select
752 pk_address,
753 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
754 || urb || coalesce(' (' || suburb || ')', '') || ', '
755 || postcode
756 || coalesce(', ' || notes_street, '')
757 || coalesce(', ' || notes_subunit, '')
758 ) as address
759 from
760 dem.v_address
761 where
762 street %(fragment_condition)s
763
764 ) union (
765
766 select
767 pk_address,
768 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
769 || urb || coalesce(' (' || suburb || ')', '') || ', '
770 || postcode
771 || coalesce(', ' || notes_street, '')
772 || coalesce(', ' || notes_subunit, '')
773 ) as address
774 from
775 dem.v_address
776 where
777 postcode_street %(fragment_condition)s
778
779 ) union (
780
781 select
782 pk_address,
783 (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
784 || urb || coalesce(' (' || suburb || ')', '') || ', '
785 || postcode
786 || coalesce(', ' || notes_street, '')
787 || coalesce(', ' || notes_subunit, '')
788 ) as address
789 from
790 dem.v_address
791 where
792 postcode_urb %(fragment_condition)s
793 )
794 ) as union_result
795 order by union_result.address limit 50"""
796
797 gmMatchProvider.cMatchProvider_SQL2.__init__(self, queries = query)
798
799 self.setThresholds(2, 4, 6)
800 # self.word_separators = u'[ \t]+'
801
802 #============================================================
804
806
807 mp = cAddressMatchProvider()
808 gmPhraseWheel.cPhraseWheel.__init__ (
809 self,
810 *args,
811 **kwargs
812 )
813 self.matcher = cAddressMatchProvider()
814 self.SetToolTipString(_('Select an address by postcode or street name.'))
815 self.selection_only = True
816 self.__address = None
817 self.__old_pk = None
818 #--------------------------------------------------------
820
821 pk = self.GetData()
822
823 if pk is None:
824 self.__address = None
825 return None
826
827 if self.__address is None:
828 self.__old_pk = pk
829 self.__address = gmDemographicRecord.cAddress(aPK_obj = pk)
830 else:
831 if pk != self.__old_pk:
832 self.__old_pk = pk
833 self.__address = gmDemographicRecord.cAddress(aPK_obj = pk)
834
835 return self.__address
836 #============================================================
838
840
841 query = u"""
842 select id, type from ((
843 select id, _(name) as type, 1 as rank
844 from dem.address_type
845 where _(name) %(fragment_condition)s
846 ) union (
847 select id, name as type, 2 as rank
848 from dem.address_type
849 where name %(fragment_condition)s
850 )) as ur
851 order by
852 ur.rank, ur.type
853 """
854 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
855 mp.setThresholds(1, 2, 4)
856 mp.word_separators = u'[ \t]+'
857 gmPhraseWheel.cPhraseWheel.__init__ (
858 self,
859 *args,
860 **kwargs
861 )
862 self.matcher = mp
863 self.SetToolTipString(_('Select the type of address.'))
864 # self.capitalisation_mode = gmTools.CAPS_FIRST
865 self.selection_only = True
866 #--------------------------------------------------------
867 # def GetData(self, can_create=False):
868 # if self.data is None:
869 # if can_create:
870 # self.data = gmDocuments.create_document_type(self.GetValue().strip())['pk_doc_type'] # FIXME: error handling
871 # return self.data
872 #============================================================
874
876 # FIXME: add possible context
877 query = u"""
878 (select distinct postcode, postcode from dem.street where postcode %(fragment_condition)s limit 20)
879 union
880 (select distinct postcode, postcode from dem.urb where postcode %(fragment_condition)s limit 20)"""
881 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
882 mp.setThresholds(2, 3, 15)
883 gmPhraseWheel.cPhraseWheel.__init__ (
884 self,
885 *args,
886 **kwargs
887 )
888 self.SetToolTipString(_("Type or select a zip code (postcode)."))
889 self.matcher = mp
890 #============================================================
892
894 context = {
895 u'ctxt_zip': {
896 u'where_part': u'and zip ilike %(zip)s',
897 u'placeholder': u'zip'
898 }
899 }
900 query = u"""
901 select s1, s2 from (
902 select s1, s2, rank from (
903 select distinct on (street)
904 street as s1, street as s2, 1 as rank
905 from dem.v_zip2data
906 where
907 street %(fragment_condition)s
908 %(ctxt_zip)s
909
910 union all
911
912 select distinct on (name)
913 name as s1, name as s2, 2 as rank
914 from dem.street
915 where
916 name %(fragment_condition)s
917
918 ) as q2
919 ) as q1 order by rank, s2 limit 50"""
920 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
921 mp.setThresholds(3, 5, 8)
922 gmPhraseWheel.cPhraseWheel.__init__ (
923 self,
924 *args,
925 **kwargs
926 )
927 self.unset_context(context = u'zip')
928
929 self.SetToolTipString(_('Type or select a street.'))
930 self.capitalisation_mode = gmTools.CAPS_FIRST
931 self.matcher = mp
932 #============================================================
934
936
937 query = """
938 select distinct on (suburb) suburb, suburb
939 from dem.street
940 where suburb %(fragment_condition)s
941 order by suburb
942 limit 50
943 """
944 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
945 mp.setThresholds(2, 3, 6)
946 gmPhraseWheel.cPhraseWheel.__init__ (
947 self,
948 *args,
949 **kwargs
950 )
951
952 self.SetToolTipString(_('Type or select the suburb.'))
953 self.capitalisation_mode = gmTools.CAPS_FIRST
954 self.matcher = mp
955 #============================================================
957
959 context = {
960 u'ctxt_zip': {
961 u'where_part': u'and zip ilike %(zip)s',
962 u'placeholder': u'zip'
963 }
964 }
965 query = u"""
966 select u1, u2 from (
967 select distinct on (rank, u1)
968 u1, u2, rank
969 from (
970 select
971 urb as u1, urb as u2, 1 as rank
972 from dem.v_zip2data
973 where
974 urb %(fragment_condition)s
975 %(ctxt_zip)s
976
977 union all
978
979 select
980 name as u1, name as u2, 2 as rank
981 from dem.urb
982 where
983 name %(fragment_condition)s
984 ) as union_result
985 order by rank, u1
986 ) as distincted_union
987 limit 50
988 """
989 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
990 mp.setThresholds(3, 5, 7)
991 gmPhraseWheel.cPhraseWheel.__init__ (
992 self,
993 *args,
994 **kwargs
995 )
996 self.unset_context(context = u'zip')
997
998 self.SetToolTipString(_('Type or select a city/town/village/dwelling.'))
999 self.capitalisation_mode = gmTools.CAPS_FIRST
1000 self.matcher = mp
1001
1002 #============================================================
1003 # communication channels related widgets
1004 #============================================================
1006
1008
1009 query = u"""
1010 select pk, type from ((
1011 select pk, _(description) as type, 1 as rank
1012 from dem.enum_comm_types
1013 where _(description) %(fragment_condition)s
1014 ) union (
1015 select pk, description as type, 2 as rank
1016 from dem.enum_comm_types
1017 where description %(fragment_condition)s
1018 )) as ur
1019 order by
1020 ur.rank, ur.type
1021 """
1022 mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
1023 mp.setThresholds(1, 2, 4)
1024 mp.word_separators = u'[ \t]+'
1025 gmPhraseWheel.cPhraseWheel.__init__ (
1026 self,
1027 *args,
1028 **kwargs
1029 )
1030 self.matcher = mp
1031 self.SetToolTipString(_('Select the type of communications channel.'))
1032 self.selection_only = True
1033
1034 #------------------------------------------------------------
1035 from Gnumed.wxGladeWidgets import wxgCommChannelEditAreaPnl
1036
1038 """An edit area for editing/creating a comms channel.
1039
1040 Does NOT act on/listen to the current patient.
1041 """
1043 try:
1044 self.channel = kwargs['comm_channel']
1045 del kwargs['comm_channel']
1046 except KeyError:
1047 self.channel = None
1048
1049 wxgCommChannelEditAreaPnl.wxgCommChannelEditAreaPnl.__init__(self, *args, **kwargs)
1050
1051 self.identity = None
1052
1053 self.refresh()
1054 #--------------------------------------------------------
1055 # external API
1056 #--------------------------------------------------------
1058 if comm_channel is not None:
1059 self.channel = comm_channel
1060
1061 if self.channel is None:
1062 self._PRW_type.SetText(u'')
1063 self._TCTRL_url.SetValue(u'')
1064 self._PRW_address.SetText(value = u'', data = None)
1065 self._CHBOX_confidential.SetValue(False)
1066 else:
1067 self._PRW_type.SetText(self.channel['l10n_comm_type'])
1068 self._TCTRL_url.SetValue(self.channel['url'])
1069 self._PRW_address.SetData(data = self.channel['pk_address'])
1070 self._CHBOX_confidential.SetValue(self.channel['is_confidential'])
1071 #--------------------------------------------------------
1073 """Links comm channel to patient."""
1074 if self.channel is None:
1075 if not self.__valid_for_save():
1076 return False
1077 try:
1078 self.channel = self.identity.link_comm_channel (
1079 pk_channel_type = self._PRW_type.GetData(),
1080 url = self._TCTRL_url.GetValue().strip(),
1081 is_confidential = self._CHBOX_confidential.GetValue(),
1082 )
1083 except gmPG2.dbapi.IntegrityError:
1084 _log.exception('error saving comm channel')
1085 gmDispatcher.send(signal = u'statustext', msg = _('Cannot save communications channel.'), beep = True)
1086 return False
1087 else:
1088 comm_type = self._PRW_type.GetValue().strip()
1089 if comm_type != u'':
1090 self.channel['comm_type'] = comm_type
1091 url = self._TCTRL_url.GetValue().strip()
1092 if url != u'':
1093 self.channel['url'] = url
1094 self.channel['is_confidential'] = self._CHBOX_confidential.GetValue()
1095
1096 self.channel['pk_address'] = self._PRW_address.GetData()
1097 self.channel.save_payload()
1098
1099 return True
1100 #--------------------------------------------------------
1101 # internal helpers
1102 #--------------------------------------------------------
1104
1105 no_errors = True
1106
1107 if self._PRW_type.GetData() is None:
1108 self._PRW_type.SetBackgroundColour('pink')
1109 self._PRW_type.SetFocus()
1110 self._PRW_type.Refresh()
1111 no_errors = False
1112 else:
1113 self._PRW_type.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
1114 self._PRW_type.Refresh()
1115
1116 if self._TCTRL_url.GetValue().strip() == u'':
1117 self._TCTRL_url.SetBackgroundColour('pink')
1118 self._TCTRL_url.SetFocus()
1119 self._TCTRL_url.Refresh()
1120 no_errors = False
1121 else:
1122 self._TCTRL_url.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW))
1123 self._TCTRL_url.Refresh()
1124
1125 return no_errors
1126
1127 #------------------------------------------------------------
1129 """A list for managing a person's comm channels.
1130
1131 Does NOT act on/listen to the current patient.
1132 """
1134
1135 try:
1136 self.__identity = kwargs['identity']
1137 del kwargs['identity']
1138 except KeyError:
1139 self.__identity = None
1140
1141 gmListWidgets.cGenericListManagerPnl.__init__(self, *args, **kwargs)
1142
1143 self.new_callback = self._add_comm
1144 self.edit_callback = self._edit_comm
1145 self.delete_callback = self._del_comm
1146 self.refresh_callback = self.refresh
1147
1148 self.__init_ui()
1149 self.refresh()
1150 #--------------------------------------------------------
1151 # external API
1152 #--------------------------------------------------------
1154 if self.__identity is None:
1155 self._LCTRL_items.set_string_items()
1156 return
1157
1158 comms = self.__identity.get_comm_channels()
1159 self._LCTRL_items.set_string_items (
1160 items = [ [ gmTools.bool2str(c['is_confidential'], u'X', u''), c['l10n_comm_type'], c['url'] ] for c in comms ]
1161 )
1162 self._LCTRL_items.set_column_widths()
1163 self._LCTRL_items.set_data(data = comms)
1164 #--------------------------------------------------------
1165 # internal helpers
1166 #--------------------------------------------------------
1168 self._LCTRL_items.SetToolTipString(_('List of known communication channels.'))
1169 self._LCTRL_items.set_columns(columns = [
1170 _('confidential'),
1171 _('Type'),
1172 _('Value')
1173 ])
1174 #--------------------------------------------------------
1176 ea = cCommChannelEditAreaPnl(self, -1)
1177 ea.identity = self.__identity
1178 dlg = gmEditArea.cGenericEditAreaDlg(self, -1, edit_area = ea)
1179 dlg.SetTitle(_('Adding new communications channel'))
1180 if dlg.ShowModal() == wx.ID_OK:
1181 return True
1182 return False
1183 #--------------------------------------------------------
1185 ea = cCommChannelEditAreaPnl(self, -1, comm_channel = comm_channel)
1186 ea.identity = self.__identity
1187 dlg = gmEditArea.cGenericEditAreaDlg(self, -1, edit_area = ea)
1188 dlg.SetTitle(_('Editing communications channel'))
1189 if dlg.ShowModal() == wx.ID_OK:
1190 return True
1191 return False
1192 #--------------------------------------------------------
1194 go_ahead = gmGuiHelpers.gm_show_question (
1195 _( 'Are you sure this patient can no longer\n'
1196 "be contacted via this channel ?"
1197 ),
1198 _('Removing communication channel')
1199 )
1200 if not go_ahead:
1201 return False
1202 self.__identity.unlink_comm_channel(comm_channel = comm)
1203 return True
1204 #--------------------------------------------------------
1205 # properties
1206 #--------------------------------------------------------
1209
1213
1214 identity = property(_get_identity, _set_identity)
1215
1216 #------------------------------------------------------------
1217 from Gnumed.wxGladeWidgets import wxgPersonContactsManagerPnl
1218
1220 """A panel for editing contact data for a person.
1221
1222 - provides access to:
1223 - addresses
1224 - communication paths
1225
1226 Does NOT act on/listen to the current patient.
1227 """
1229
1230 wxgPersonContactsManagerPnl.wxgPersonContactsManagerPnl.__init__(self, *args, **kwargs)
1231
1232 self.__identity = None
1233 self.refresh()
1234 #--------------------------------------------------------
1235 # external API
1236 #--------------------------------------------------------
1240 #--------------------------------------------------------
1241 # properties
1242 #--------------------------------------------------------
1245
1249
1250 identity = property(_get_identity, _set_identity)
1251
1252 #============================================================
1253 if __name__ == "__main__":
1254
1255 #--------------------------------------------------------
1257 app = wx.PyWidgetTester(size = (200, 50))
1258 pw = cStateSelectionPhraseWheel(app.frame, -1)
1259 # pw.set_context(context = u'zip', val = u'04318')
1260 # pw.set_context(context = u'country', val = u'Deutschland')
1261 app.frame.Show(True)
1262 app.MainLoop()
1263 #--------------------------------------------------------
1265 app = wx.PyWidgetTester(size = (600, 400))
1266 widget = cPersonAddressesManagerPnl(app.frame, -1)
1267 widget.identity = activate_patient()
1268 app.frame.Show(True)
1269 app.MainLoop()
1270 #--------------------------------------------------------
1272 app = wx.PyWidgetTester(size = (600, 400))
1273 app.SetWidget(cAddressEditAreaPnl, address = gmDemographicRecord.cAddress(aPK_obj = 1))
1274 app.MainLoop()
1275 #--------------------------------------------------------
1277 app = wx.PyWidgetTester(size = (200, 50))
1278 pw = cAddressPhraseWheel(app.frame, -1)
1279 app.frame.Show(True)
1280 app.MainLoop()
1281 #--------------------------------------------------------
1283 app = wx.PyWidgetTester(size = (200, 50))
1284 pw = cAddressTypePhraseWheel(app.frame, -1)
1285 app.frame.Show(True)
1286 app.MainLoop()
1287 #--------------------------------------------------------
1289 app = wx.PyWidgetTester(size = (200, 50))
1290 pw = cZipcodePhraseWheel(app.frame, -1)
1291 app.frame.Show(True)
1292 app.MainLoop()
1293 #--------------------------------------------------------
1295 app = wx.PyWidgetTester(size = (200, 50))
1296 pw = cStreetPhraseWheel(app.frame, -1)
1297 # pw.set_context(context = u'zip', val = u'04318')
1298 app.frame.Show(True)
1299 app.MainLoop()
1300 #--------------------------------------------------------
1302 app = wx.PyWidgetTester(size = (200, 50))
1303 pw = cSuburbPhraseWheel(app.frame, -1)
1304 app.frame.Show(True)
1305 app.MainLoop()
1306 #--------------------------------------------------------
1308 app = wx.PyWidgetTester(size = (200, 50))
1309 pw = cUrbPhraseWheel(app.frame, -1)
1310 app.frame.Show(True)
1311 pw.set_context(context = u'zip', val = u'04317')
1312 app.MainLoop()
1313 #--------------------------------------------------------
1315 app = wx.PyWidgetTester(size = (600, 400))
1316 widget = cPersonCommsManagerPnl(app.frame, -1)
1317 widget.identity = activate_patient()
1318 app.frame.Show(True)
1319 app.MainLoop()
1320
1321 #============================================================
1322
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Mon Nov 29 04:05:55 2010 | http://epydoc.sourceforge.net |