Gnumed.wxpython.gmAddressWidgets

Package Gnumed :: Package wxpython :: Module gmAddressWidgets |
[frames] | no frames]

# Source Code for Module Gnumed.wxpython.gmAddressWidgets

       1  """GNUmed generic address related widgets."""
       2  #================================================================
       3  __author__ = 'karsten.hilbert@gmx.net'
       4  __license__ = 'GPL v2 or later (details at http://www.gnu.org)'
       5
       6  # stdlib
       7  import logging, sys
       8
       9
      10  # 3rd party
      11  import wx
      12
      13
      14  # GNUmed
      15  if __name__ == '__main__':
      16          sys.path.insert(0, '../../')
      17
      18  from Gnumed.pycommon import gmTools
      19  from Gnumed.pycommon import gmMatchProvider
      20  from Gnumed.business import gmDemographicRecord
      21
      22  from Gnumed.wxpython import gmCfgWidgets
      23  from Gnumed.wxpython import gmPhraseWheel
      24  from Gnumed.wxpython import gmListWidgets
      25  from Gnumed.wxpython import gmEditArea
      26  from Gnumed.wxpython import gmGuiHelpers
      27
      28
      29  _log = logging.getLogger('gm.ui')
      30  #============================================================
      31  # country related widgets / functions
      32  #============================================================
      33 -def configure_default_country(parent=None):
      34
      35          if parent is None:
      36                  parent = wx.GetApp().GetTopWindow()
      37
      38          countries = gmDemographicRecord.get_countries()
      39
      40          gmCfgWidgets.configure_string_from_list_option (
      41                  parent = parent,
      42                  message = _('Select the default country for new persons.\n'),
      43                  option = 'person.create.default_country',
      44                  bias = 'user',
      45                  choices = [ (c['l10n_country'], c['code']) for c in countries ],
      46                  columns = [_('Country'), _('Code')],
      47                  data = [ c['code'] for c in countries ]
      48          )
      49  #============================================================
      50 -class cCountryPhraseWheel(gmPhraseWheel.cPhraseWheel):
      51
      52 -        def __init__(self, *args, **kwargs):
      53
      54                  gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
      55
      56                  context = {
      57                          'ctxt_zip': {
      58                                  'where_part': 'and zip ilike %(zip)s',
      59                                  'placeholder': 'zip'
      60                          }
      61                  }
      62                  query = """
      63  SELECT
      64          data,
      65          field_label,
      66          list_label
      67  FROM (
      68          SELECT DISTINCT ON (data)
      69                  data,
      70                  field_label,
      71                  list_label,
      72                  rank
      73          FROM (
      74
      75          -- localized to user
      76                          SELECT
      77                                  code_country AS data,
      78                                  l10n_country AS field_label,
      79                                  l10n_country || ' (' || code_country || '): ' || country AS list_label,
      80                                  1 AS rank
      81                          FROM dem.v_zip2data
      82                          WHERE
      83                                  l10n_country %(fragment_condition)s
      84                                  %(ctxt_zip)s
      85                  UNION ALL
      86                          SELECT
      87                                  code AS data,
      88                                  _(name) AS field_label,
      89                                  _(name) || ' (' || code || '): ' || name AS list_label,
      90                                  2 AS rank
      91                          FROM dem.country
      92                          WHERE
      93                                  _(name) %(fragment_condition)s
      94
      95                  UNION ALL
      96
      97          -- non-localized
      98                          SELECT
      99                                  code_country AS data,
     100                                  l10n_country AS field_label,
     101                                  country || ' (' || code_country || '): ' || l10n_country AS list_label,
     102                                  3 AS rank
     103                          FROM dem.v_zip2data
     104                          WHERE
     105                                  country %(fragment_condition)s
     106                                  %(ctxt_zip)s
     107                  UNION ALL
     108                          SELECT
     109                                  code AS data,
     110                                  _(name) AS field_label,
     111                                  name || ' (' || code || '): ' || _(name) AS list_label,
     112                                  4 AS rank
     113                          FROM dem.country
     114                          WHERE
     115                                  name %(fragment_condition)s
     116
     117                  UNION ALL
     118
     119          -- abbreviation
     120                          SELECT
     121                                  code AS data,
     122                                  _(name) AS field_label,
     123                                  code || ': ' || _(name) || ' (' || name || ')' AS list_label,
     124                                  5 AS rank
     125                          FROM dem.country
     126                          WHERE
     127                                  code %(fragment_condition)s
     128
     129          ) AS candidates
     130  ) AS distint_candidates
     131  ORDER BY rank, list_label
     132  LIMIT 25"""
     133                  mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
     134                  mp._SQL_data2match = """
     135                          SELECT
     136                                  code AS data,
     137                                  _(name) AS field_label,
     138                                  code || ': ' || _(name) || ' (' || name || ')' AS list_label,
     139                                  5 AS rank
     140                          FROM dem.country
     141                          WHERE
     142                                  code = %(pk)s
     143                  """
     144                  mp.setThresholds(2, 5, 9)
     145                  self.matcher = mp
     146
     147                  self.unset_context(context = 'zip')
     148                  self.SetToolTip(_('Type or select a country.'))
     149                  self.capitalisation_mode = gmTools.CAPS_FIRST
     150                  self.selection_only = True
     151
     152  #============================================================
     153  # region related widgets / functions
     154  #============================================================
     155 -def configure_default_region(parent=None):
     156
     157          if parent is None:
     158                  parent = wx.GetApp().GetTopWindow()
     159
     160          regs = gmDemographicRecord.get_regions()
     161
     162          gmCfgWidgets.configure_string_from_list_option (
     163                  parent = parent,
     164                  message = _('Select the default region (state/province/county/territory/arrondissement/prefecture/department/kanton/...) for new persons.\n'),
     165                  option = 'person.create.default_region',
     166                  bias = 'user',
     167                  choices = [ (r['l10n_country'], r['l10n_region'], r['code_region']) for r in regs ],
     168                  columns = [_('Country'), _('Region'), _('Code')],
     169                  data = [ r['region'] for r in regs ]
     170          )
     171  #============================================================
     172 -def edit_region(parent=None, region=None):
     173          ea = cProvinceEAPnl(parent, -1, region = region)
     174          dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea, single_entry = (region is not None))
     175          dlg.SetTitle(gmTools.coalesce(region, _('Adding region'), _('Editing region')))
     176          result = dlg.ShowModal()
     177          dlg.Destroy()
     178          return (result == wx.ID_OK)
     179  #============================================================
     180 -def delete_region(parent=None, region=None):
     181
     182          msg = _(
     183                  'Are you sure you want to delete this region ?\n'
     184                  '\n'
     185                  'Deletion will only work if this region is not\n'
     186                  'yet in use in any patient addresses.'
     187          )
     188
     189          tt = _(
     190                  'Also delete any towns/cities/villages known\n'
     191                  'to be situated in this state as long as\n'
     192                  'no patients are recorded to live there.'
     193          )
     194
     195          dlg = gmGuiHelpers.c2ButtonQuestionDlg (
     196                  parent,
     197                  -1,
     198                  caption = _('Deleting region'),
     199                  question = msg,
     200                  show_checkbox = True,
     201                  checkbox_msg = _('delete related townships'),
     202                  checkbox_tooltip = tt,
     203                  button_defs = [
     204                          {'label': _('Yes, delete'), 'tooltip': _('Delete region and possibly related townships.'), 'default': False},
     205                          {'label': _('No'), 'tooltip': _('No, do NOT delete anything.'), 'default': True}
     206                  ]
     207          )
     208
     209          decision = dlg.ShowModal()
     210          if decision != wx.ID_YES:
     211                  dlg.Destroy()
     212                  return False
     213
     214          include_urbs = dlg.checkbox_is_checked()
     215          dlg.Destroy()
     216
     217          return gmDemographicRecord.delete_region(region = region, delete_urbs = include_urbs)
     218  #============================================================
     219 -def manage_regions(parent=None):
     220
     221          if parent is None:
     222                  parent = wx.GetApp().GetTopWindow()
     223
     224          #------------------------------------------------------------
     225          def delete(region=None):
     226                  return delete_region(parent = parent, region = region['pk_region'])
     227          #------------------------------------------------------------
     228          def edit(region=None):
     229                  return edit_region(parent = parent, region = region)
     230          #------------------------------------------------------------
     231          def refresh(lctrl):
     232                  wx.BeginBusyCursor()
     233                  provinces = gmDemographicRecord.get_regions()
     234                  lctrl.set_string_items([ (p['l10n_country'], p['l10n_region']) for p in provinces ])
     235                  lctrl.set_data(provinces)
     236                  wx.EndBusyCursor()
     237          #------------------------------------------------------------
     238          msg = _(
     239                  'This list shows the regions known to GNUmed.\n'
     240                  '\n'
     241                  'In your jurisdiction "region" may correspond to either of "state",\n'
     242                  '"county", "province", "territory", "arrondissement", "department,"\n'
     243                  '"prefecture", "kanton", or some such term.\n'
     244          )
     245
     246          gmListWidgets.get_choices_from_list (
     247                  parent = parent,
     248                  msg = msg,
     249                  caption = _('Editing regions ...'),
     250                  columns = [_('Country'), _('Region')],
     251                  single_selection = True,
     252                  new_callback = edit,
     253                  #edit_callback = edit,
     254                  delete_callback = delete,
     255                  refresh_callback = refresh
     256          )
     257  #============================================================
     258 -class cStateSelectionPhraseWheel(gmPhraseWheel.cPhraseWheel):
     259
     260 -        def __init__(self, *args, **kwargs):
     261
     262                  gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
     263
     264                  context = {
     265                          'ctxt_country_name': {
     266                                  'where_part': 'AND l10n_country ILIKE %(country_name)s OR country ILIKE %(country_name)s',
     267                                  'placeholder': 'country_name'
     268                          },
     269                          'ctxt_zip': {
     270                                  'where_part': 'AND zip ilike %(zip)s',
     271                                  'placeholder': 'zip'
     272                          },
     273                          'ctxt_country_code': {
     274                                  'where_part': 'AND country IN (SELECT code FROM dem.country WHERE _(name) ILIKE %(country_name)s OR name ILIKE %(country_name)s)',
     275                                  'placeholder': 'country_name'
     276                          }
     277                  }
     278
     279                  query = """
     280  SELECT
     281          data,
     282          field_label,
     283          list_label
     284  FROM (
     285          SELECT DISTINCT ON (field_label)
     286                  data,
     287                  field_label,
     288                  list_label,
     289                  rank
     290          FROM (
     291                          -- 1: find regions based on name, context: zip and country name
     292                          SELECT
     293                                  code_region AS data,
     294                                  region AS field_label,
     295                                  region || ' (' || code_region || '), ' || l10n_country || ' (' || code_country || ')' AS list_label,
     296                                  1 AS rank
     297                          FROM dem.v_zip2data
     298                          WHERE
     299                                  region %(fragment_condition)s
     300                                  %(ctxt_country_name)s
     301                                  %(ctxt_zip)s
     302
     303                  UNION ALL
     304
     305                          -- 2: find regions based on code, context: zip and country name
     306                          SELECT
     307                                  code_region AS data,
     308                                  region AS field_label,
     309                                  code_region || ': ' || region || ' (' || l10n_country || ', ' || code_country || ')' AS list_label,
     310                                  2 AS rank
     311                          FROM dem.v_zip2data
     312                          WHERE
     313                                  code_region %(fragment_condition)s
     314                                  %(ctxt_country_name)s
     315                                  %(ctxt_zip)s
     316
     317                  UNION ALL
     318
     319                          -- 3: find regions based on name, context: country
     320                          SELECT
     321                                  code AS data,
     322                                  name AS field_label,
     323                                  name || ' (' || code || '), ' || country AS list_label,
     324                                  3 AS rank
     325                          FROM dem.region
     326                          WHERE
     327                                  name %(fragment_condition)s
     328                                  %(ctxt_country_code)s
     329
     330                  UNION ALL
     331
     332                          -- 4: find regions based on code, context: country
     333                          SELECT
     334                                  code AS data,
     335                                  name AS field_label,
     336                                  code || ': ' || name || ', ' || country AS list_label,
     337                                  3 AS rank
     338                          FROM dem.region
     339                          WHERE
     340                                  code %(fragment_condition)s
     341                                  %(ctxt_country_code)s
     342
     343          ) AS candidate_regions
     344  ) AS distinct_matches
     345  ORDER BY rank, list_label
     346  LIMIT 50"""
     347
     348                  mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
     349                  mp.setThresholds(2, 5, 6)
     350                  mp.word_separators = '[ \t]+'
     351                  self.matcher = mp
     352
     353                  self.unset_context(context = 'zip')
     354                  self.unset_context(context = 'country_name')
     355                  self.SetToolTip(_('Type or select a region (state/province/county/territory/arrondissement/prefecture/department/kanton/...).'))
     356                  self.capitalisation_mode = gmTools.CAPS_FIRST
     357                  self.selection_only = True
     358  #====================================================================
     359  from Gnumed.wxGladeWidgets import wxgProvinceEAPnl
     360
     361 -class cProvinceEAPnl(wxgProvinceEAPnl.wxgProvinceEAPnl, gmEditArea.cGenericEditAreaMixin):
     362
     363 -        def __init__(self, *args, **kwargs):
     364
     365                  try:
     366                          data = kwargs['region']
     367                          del kwargs['region']
     368                  except KeyError:
     369                          data = None
     370
     371                  wxgProvinceEAPnl.wxgProvinceEAPnl.__init__(self, *args, **kwargs)
     372                  gmEditArea.cGenericEditAreaMixin.__init__(self)
     373
     374                  self.mode = 'new'
     375                  self.data = data
     376                  if data is not None:
     377                          self.mode = 'edit'
     378
     379                  self.__init_ui()
     380          #----------------------------------------------------------------
     381 -        def __init_ui(self):
     382                  self._PRW_region.selection_only = False
     383          #----------------------------------------------------------------
     384          # generic Edit Area mixin API
     385          #----------------------------------------------------------------
     386 -        def _valid_for_save(self):
     387
     388                  validity = True
     389
     390                  if self._PRW_region.GetData() is None:
     391                          if self._PRW_region.GetValue().strip() == '':
     392                                  validity = False
     393                                  self._PRW_region.display_as_valid(False)
     394                          else:
     395                                  self._PRW_region.display_as_valid(True)
     396                  else:
     397                          self._PRW_region.display_as_valid(True)
     398
     399                  if self._PRW_region.GetData() is None:
     400                          if self._TCTRL_code.GetValue().strip() == '':
     401                                  validity = False
     402                                  self._TCTRL_code.SetBackgroundColour(gmPhraseWheel.color_prw_invalid)
     403                          else:
     404                                  self._TCTRL_code.SetBackgroundColour(gmPhraseWheel.color_prw_valid)
     405
     406                  if self._PRW_country.GetData() is None:
     407                          validity = False
     408                          self._PRW_country.display_as_valid(False)
     409                  else:
     410                          self._PRW_country.display_as_valid(True)
     411
     412                  return validity
     413          #----------------------------------------------------------------
     414 -        def _save_as_new(self):
     415                  gmDemographicRecord.create_region (
     416                          name = self._PRW_region.GetValue().strip(),
     417                          code = self._TCTRL_code.GetValue().strip(),
     418                          country = self._PRW_country.GetData()
     419                  )
     420
     421                  # EA is refreshed automatically after save, so need this ...
     422                  self.data = {
     423                          'l10n_region' : self._PRW_region.GetValue().strip(),
     424                          'code_region' : self._TCTRL_code.GetValue().strip(),
     425                          'l10n_country' : self._PRW_country.GetValue().strip(),
     426                          'code_country' : self._PRW_country.GetData().strip()
     427                  }
     428
     429                  return True
     430          #----------------------------------------------------------------
     431 -        def _save_as_update(self):
     432                  # update self.data and save the changes
     433                  #self.data[''] =
     434                  #self.data[''] =
     435                  #self.data[''] =
     436                  #self.data.save()
     437
     438                  # do nothing for now (IOW, don't support updates)
     439                  return True
     440          #----------------------------------------------------------------
     441 -        def _refresh_as_new(self):
     442                  self._PRW_region.SetText()
     443                  self._TCTRL_code.SetValue('')
     444                  self._PRW_country.SetText()
     445
     446                  self._PRW_region.SetFocus()
     447          #----------------------------------------------------------------
     448 -        def _refresh_from_existing(self):
     449                  self._PRW_region.SetText(self.data['l10n_region'], self.data['code_region'])
     450                  self._TCTRL_code.SetValue(self.data['code_region'])
     451                  self._PRW_country.SetText(self.data['l10n_country'], self.data['code_country'])
     452
     453                  self._PRW_region.SetFocus()
     454          #----------------------------------------------------------------
     455 -        def _refresh_as_new_from_existing(self):
     456                  self._PRW_region.SetText()
     457                  self._TCTRL_code.SetValue('')
     458                  self._PRW_country.SetText(self.data['l10n_country'], self.data['code_country'])
     459
     460                  self._PRW_region.SetFocus()
     461
     462  #============================================================
     463  # other address parts phrasewheels and widgets
     464  #============================================================
     465 -class cZipcodePhraseWheel(gmPhraseWheel.cPhraseWheel):
     466
     467 -        def __init__(self, *args, **kwargs):
     468                  # FIXME: add possible context
     469                  query = """(
     470                          SELECT DISTINCT ON (list_label)
     471                                  postcode AS data,
     472                                  postcode || ' (' || name || ')' AS list_label,
     473                                  postcode AS field_label
     474                          FROM dem.street
     475                          WHERE
     476                                  postcode %(fragment_condition)s
     477                          ORDER BY list_label
     478                          LIMIT 20
     479
     480                  ) UNION (
     481
     482                          SELECT DISTINCT ON (list_label)
     483                                  postcode AS data,
     484                                  postcode || ' (' || name || ')' AS list_label,
     485                                  postcode AS field_label
     486                          FROM dem.urb
     487                          WHERE
     488                                  postcode %(fragment_condition)s
     489                          ORDER BY list_label
     490                          LIMIT 20
     491                  )"""
     492                  mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
     493                  mp.setThresholds(2, 3, 15)
     494                  gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
     495                  self.SetToolTip(_("Type or select a zip code (postcode).\n\nUse e.g. '?' if unknown."))
     496                  self.matcher = mp
     497  #============================================================
     498 -class cStreetPhraseWheel(gmPhraseWheel.cPhraseWheel):
     499
     500 -        def __init__(self, *args, **kwargs):
     501                  context = {
     502                          'ctxt_zip': {
     503                                  'where_part': 'AND zip ILIKE %(zip)s',
     504                                  'placeholder': 'zip'
     505                          }
     506                  }
     507                  query = """
     508          SELECT
     509                  data,
     510                  field_label,
     511                  list_label
     512          FROM (
     513
     514                          SELECT DISTINCT ON (data)
     515                                  street AS data,
     516                                  street AS field_label,
     517                                  street || ' (' || zip || ', ' || urb || coalesce(', ' || suburb, '') || ', ' || l10n_country || ')' AS list_label,
     518                                  1 AS rank
     519                          FROM dem.v_zip2data
     520                          WHERE
     521                                  street %(fragment_condition)s
     522                                  %(ctxt_zip)s
     523
     524                  UNION ALL
     525
     526                          SELECT DISTINCT ON (data)
     527                                  name AS data,
     528                                  name AS field_label,
     529                                  name || ' (' || coalesce(postcode, '') || coalesce(', ' || suburb, '') || ')' AS list_label,
     530                                  2 AS rank
     531                          FROM dem.street
     532                          WHERE
     533                                  name %(fragment_condition)s
     534
     535          ) AS matching_streets
     536          ORDER BY rank, field_label
     537          LIMIT 50"""
     538                  mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
     539                  mp.setThresholds(3, 5, 8)
     540                  gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
     541                  self.unset_context(context = 'zip')
     542
     543                  self.SetToolTip(_('Type or select a street.'))
     544                  self.capitalisation_mode = gmTools.CAPS_FIRST
     545                  self.matcher = mp
     546  #============================================================
     547 -class cSuburbPhraseWheel(gmPhraseWheel.cPhraseWheel):
     548
     549 -        def __init__(self, *args, **kwargs):
     550
     551                  query = """
     552  SELECT DISTINCT ON (suburb) suburb, suburb
     553  FROM dem.street
     554  WHERE suburb %(fragment_condition)s
     555  ORDER BY suburb
     556  LIMIT 50
     557  """
     558                  mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
     559                  mp.setThresholds(2, 3, 6)
     560                  gmPhraseWheel.cPhraseWheel.__init__ (
     561                          self,
     562                          *args,
     563                          **kwargs
     564                  )
     565
     566                  self.SetToolTip(_('Type or select the suburb.'))
     567                  self.capitalisation_mode = gmTools.CAPS_FIRST
     568                  self.matcher = mp
     569  #============================================================
     570 -class cUrbPhraseWheel(gmPhraseWheel.cPhraseWheel):
     571
     572 -        def __init__(self, *args, **kwargs):
     573                  context = {
     574                          'ctxt_zip': {
     575                                  'where_part': 'and zip ilike %(zip)s',
     576                                  'placeholder': 'zip'
     577                          }
     578                  }
     579                  query = """
     580          SELECT DISTINCT ON (rank, data)
     581                  data,
     582                  field_label,
     583                  list_label
     584          FROM (
     585
     586                          SELECT
     587                                  urb AS data,
     588                                  urb AS field_label,
     589                                  urb || ' (' || zip || ', ' || region || ', ' || l10n_country || ')' AS list_label,
     590                                  1 AS rank
     591                          FROM dem.v_zip2data
     592                          WHERE
     593                                  urb %(fragment_condition)s
     594                                  %(ctxt_zip)s
     595
     596                  UNION ALL
     597
     598                          SELECT
     599                                  name AS data,
     600                                  name AS field_label,
     601                                  name || ' (' || postcode ||')' AS list_label,
     602                                  2 AS rank
     603                          FROM dem.urb
     604                          WHERE
     605                                  name %(fragment_condition)s
     606
     607          ) AS matching_urbs
     608          ORDER BY rank, data
     609          LIMIT 50"""
     610                  mp = gmMatchProvider.cMatchProvider_SQL2(queries=query, context=context)
     611                  mp.setThresholds(3, 5, 7)
     612                  gmPhraseWheel.cPhraseWheel.__init__ (
     613                          self,
     614                          *args,
     615                          **kwargs
     616                  )
     617                  self.unset_context(context = 'zip')
     618
     619                  self.SetToolTip(_('Type or select a city/town/village/dwelling.'))
     620                  self.capitalisation_mode = gmTools.CAPS_FIRST
     621                  self.matcher = mp
     622  #============================================================
     623  # address type related widgets
     624  #============================================================
     625 -class cAddressTypePhraseWheel(gmPhraseWheel.cPhraseWheel):
     626
     627 -        def __init__(self, *args, **kwargs):
     628
     629                  query = """
     630  SELECT id, type FROM ((
     631          SELECT id, _(name) AS type, 1 AS rank
     632          FROM dem.address_type
     633          WHERE _(name) %(fragment_condition)s
     634  ) UNION (
     635          SELECT id, name AS type, 2 AS rank
     636          FROM dem.address_type
     637          WHERE name %(fragment_condition)s
     638  )) AS ur
     639  order by
     640          ur.rank, ur.type
     641  """
     642                  mp = gmMatchProvider.cMatchProvider_SQL2(queries=query)
     643                  mp.setThresholds(1, 2, 4)
     644                  mp.word_separators = '[ \t]+'
     645                  gmPhraseWheel.cPhraseWheel.__init__ (
     646                          self,
     647                          *args,
     648                          **kwargs
     649                  )
     650                  self.matcher = mp
     651                  self.SetToolTip(_('Select the type of address.'))
     652  #               self.capitalisation_mode = gmTools.CAPS_FIRST
     653                  self.selection_only = True
     654          #--------------------------------------------------------
     655  #       def GetData(self, can_create=False):
     656  #               if self.data is None:
     657  #                       if can_create:
     658  #                               self.data = gmDocuments.create_document_type(self.GetValue().strip())['pk_doc_type']    # FIXME: error handling
     659  #               return self.data
     660
     661  #============================================================
     662  # address phrasewheels and widgets
     663  #============================================================
     664 -def manage_addresses(parent=None):
     665
     666          if parent is None:
     667                  parent = wx.GetApp().GetTopWindow()
     668
     669          #------------------------------------------------------------
     670          def calculate_tooltip(address):
     671                  return '\n'.join(address.format())
     672          #------------------------------------------------------------
     673          def delete(address):
     674                  return gmDemographicRecord.delete_address(pk_address = address['pk_address'])
     675          #------------------------------------------------------------
     676          def refresh(lctrl):
     677                  adrs = gmDemographicRecord.get_addresses(order_by = 'l10n_country, urb, street, number, subunit')
     678                  items = [ [
     679                                  a['street'],
     680                                  gmTools.coalesce(a['notes_street'], ''),
     681                                  a['number'],
     682                                  gmTools.coalesce(a['subunit'], ''),
     683                                  a['postcode'],
     684                                  a['urb'],
     685                                  gmTools.coalesce(a['suburb'], ''),
     686                                  a['l10n_region'],
     687                                  a['l10n_country'],
     688                                  gmTools.coalesce(a['notes_subunit'], '')
     689                          ] for a in adrs
     690                  ]
     691                  lctrl.set_string_items(items)
     692                  lctrl.set_data(adrs)
     693
     694          #------------------------------------------------------------
     695          cols = [
     696                  _('Street'),
     697                  _('Street info'),
     698                  _('Number'),
     699                  _('Subunit'),
     700                  _('Postal code'),
     701                  _('Community'),
     702                  _('Suburb'),
     703                  _('Region'),
     704                  _('Country'),
     705                  _('Comment')
     706          ]
     707          return gmListWidgets.get_choices_from_list (
     708                  parent = parent,
     709                  caption = _('Showing addresses registered in GNUmed.'),
     710                  columns = cols,
     711                  single_selection = True,
     712                  refresh_callback = refresh,
     713                  delete_callback = delete,
     714                  list_tooltip_callback = calculate_tooltip
     715          )
     716
     717  #============================================================
     718  from Gnumed.wxGladeWidgets import wxgGenericAddressEditAreaPnl
     719
     720 -class cAddressEAPnl(wxgGenericAddressEditAreaPnl.wxgGenericAddressEditAreaPnl, gmEditArea.cGenericEditAreaMixin):
     721
     722 -        def __init__(self, *args, **kwargs):
     723
     724                  try:
     725                          data = kwargs['address']
     726                          del kwargs['address']
     727                  except KeyError:
     728                          data = None
     729
     730                  self.address_holder = None
     731                  self.__type_is_editable = True
     732                  self.__address_is_searchable = False
     733
     734                  wxgGenericAddressEditAreaPnl.wxgGenericAddressEditAreaPnl.__init__(self, *args, **kwargs)
     735                  gmEditArea.cGenericEditAreaMixin.__init__(self)
     736
     737                  self.type_is_editable = True
     738                  self.address_is_searchable = False
     739
     740                  # Code using this mixin should set mode and data
     741                  # after instantiating the class:
     742                  self.mode = 'new'
     743                  self.data = data
     744                  if data is not None:
     745                          self.mode = 'edit'
     746
     747                  self.__init_ui()
     748          #----------------------------------------------------------------
     749 -        def __init_ui(self):
     750                  self._PRW_zip.add_callback_on_lose_focus(self._on_zip_set)
     751                  self._PRW_country.add_callback_on_lose_focus(self._on_country_set)
     752          #----------------------------------------------------------------
     753          # generic Edit Area mixin API
     754          #----------------------------------------------------------------
     755 -        def _valid_for_save(self):
     756
     757                  validity = True
     758
     759                  # if any field is filled, all must be filled, so track that
     760                  is_any_field_filled = False
     761
     762                  # check by string
     763                  required_fields = [
     764                          self._PRW_urb,
     765                          self._TCTRL_number,
     766                          self._PRW_street,
     767                          self._PRW_zip
     768                  ]
     769                  if self.__type_is_editable:
     770                          required_fields.insert(0, self._PRW_type)
     771                  for field in required_fields:
     772                          if len(field.GetValue().strip()) == 0:
     773                                  if is_any_field_filled:
     774                                          self.display_ctrl_as_valid(field, False)
     775                                          field.SetFocus()
     776                                          gmGuiHelpers.gm_show_error (
     777                                                  _('Address details must be filled in completely or not at all.'),
     778                                                  _('Saving contact data')
     779                                          )
     780                                          validity = False
     781                          else:
     782                                  is_any_field_filled = True
     783                                  self.display_ctrl_as_valid(field, True)
     784
     785                  # check by data
     786                  required_fields = (
     787                          self._PRW_country,
     788                          self._PRW_state
     789                  )
     790                  for field in required_fields:
     791                          if field.GetData() is None:
     792                                  if is_any_field_filled:
     793                                          self.display_ctrl_as_valid(field, False)
     794                                          field.SetFocus()
     795                                          gmGuiHelpers.gm_show_error (
     796                                                  _('Address details must be filled in completely or not at all.'),
     797                                                  _('Saving contact data')
     798                                          )
     799                                          validity = False
     800                          else:
     801                                  is_any_field_filled = True
     802                                  self.display_ctrl_as_valid(field, True)
     803
     804                  return validity
     805          #----------------------------------------------------------------
     806 -        def _save_as_new(self):
     807                  try:
     808                          # will create or return address
     809                          address = gmDemographicRecord.create_address (
     810                                  country_code = self._PRW_country.GetData(),
     811                                  region_code = self._PRW_state.GetData(),
     812                                  urb = self._PRW_urb.GetValue().strip(),
     813                                  suburb = gmTools.none_if(self._PRW_suburb.GetValue().strip(), ''),
     814                                  postcode = self._PRW_zip.GetValue().strip(),
     815                                  street = self._PRW_street.GetValue().strip(),
     816                                  number = self._TCTRL_number.GetValue().strip(),
     817                                  subunit = gmTools.none_if(self._TCTRL_subunit.GetValue().strip(), '')
     818                          )
     819                  except:
     820                          _log.exception('cannot save address')
     821                          gmGuiHelpers.gm_show_error (
     822                                  _('Cannot save address.\n\n'
     823                                    'Does the region [%s]\n'
     824                                    'exist in country [%s] ?'
     825                                  ) % (
     826                                          self._PRW_state.GetValue().strip(),
     827                                          self._PRW_country.GetValue().strip()
     828                                  ),
     829                                  _('Saving address')
     830                          )
     831                          return False
     832
     833                  # link address to holder (there better be one)
     834                  linked_address = self.address_holder.link_address(id_type = self._PRW_type.GetData(), address = address)
     835                  if linked_address['pk_address'] != address['pk_address']:
     836                          raise ValueError('problem linking address to person or org')
     837
     838                  address['notes_street'] = gmTools.none_if(self._TCTRL_notes_street.GetValue().strip(), '')
     839                  address['notes_subunit'] = gmTools.none_if(self._TCTRL_notes_subunit.GetValue().strip(), '')
     840                  address.save()
     841
     842                  linked_address.refetch_payload()
     843                  self.data = linked_address
     844
     845                  return True
     846          #----------------------------------------------------------------
     847 -        def _save_as_update(self):
     848                  # do not update existing address, rather
     849                  # create new one or get corresponding
     850                  # address should it exist
     851                  try:
     852                          created_or_loaded_address = gmDemographicRecord.create_address (
     853                                  country_code = self._PRW_country.GetData(),
     854                                  region_code = self._PRW_state.GetData(),
     855                                  urb = self._PRW_urb.GetValue().strip(),
     856                                  suburb = gmTools.none_if(self._PRW_suburb.GetValue().strip(), ''),
     857                                  postcode = self._PRW_zip.GetValue().strip(),
     858                                  street = self._PRW_street.GetValue().strip(),
     859                                  number = self._TCTRL_number.GetValue().strip(),
     860                                  subunit = gmTools.none_if(self._TCTRL_subunit.GetValue().strip(), '')
     861                          )
     862                  except:
     863                          _log.exception('cannot save address')
     864                          gmGuiHelpers.gm_show_error (
     865                                  _('Cannot save address.\n\n'
     866                                    'Does the region [%s]\n'
     867                                    'exist in country [%s] ?'
     868                                  ) % (
     869                                          self._PRW_state.GetValue().strip(),
     870                                          self._PRW_country.GetValue().strip()
     871                                  ),
     872                                  _('Saving address')
     873                          )
     874                          return False
     875
     876                  # link address to holder (there better be one)
     877                  linked_address = self.address_holder.link_address(id_type = self._PRW_type.GetData(), address = created_or_loaded_address)
     878                  if linked_address['pk_address'] != created_or_loaded_address['pk_address']:
     879                          raise ValueError('problem linking address to person or org')
     880
     881                  created_or_loaded_address['notes_street'] = gmTools.none_if(self._TCTRL_notes_street.GetValue().strip(), '')
     882                  created_or_loaded_address['notes_subunit'] = gmTools.none_if(self._TCTRL_notes_subunit.GetValue().strip(), '')
     883                  created_or_loaded_address.save_payload()
     884                  linked_address.refetch_payload()
     885                  self.data = linked_address
     886
     887                  return True
     888          #----------------------------------------------------------------
     889 -        def _refresh_as_new(self):
     890                  self._PRW_type.SetText('', None)
     891                  self._PRW_zip.SetText('', None)
     892                  self._PRW_street.SetText('', None)
     893                  self._TCTRL_notes_street.SetValue('')
     894                  self._TCTRL_number.SetValue('')
     895                  self._TCTRL_subunit.SetValue('')
     896                  self._PRW_suburb.SetText('', None)
     897                  self._PRW_urb.SetText('', None)
     898                  self._PRW_state.SetText('', None)
     899                  self._PRW_country.SetText('', None)
     900                  self._TCTRL_notes_subunit.SetValue('')
     901
     902                  if self.__type_is_editable:
     903                          self._PRW_type.SetFocus()
     904                  else:
     905                          self._PRW_zip.SetFocus()
     906          #----------------------------------------------------------------
     907 -        def _refresh_as_new_from_existing(self):
     908                  self._refresh_as_new()
     909
     910                  self._PRW_zip.SetText(self.data['postcode'])
     911                  self._PRW_street.SetText(self.data['street'], data = self.data['street'])
     912                  self._PRW_suburb.SetText(gmTools.coalesce(self.data['suburb'], ''))
     913                  self._PRW_urb.SetText(self.data['urb'], data = self.data['urb'])
     914                  self._PRW_state.SetText(self.data['l10n_region'], data = self.data['code_region'])
     915                  self._PRW_country.SetText(self.data['l10n_country'], data = self.data['code_country'])
     916
     917                  if self.__type_is_editable:
     918                          self._PRW_type.SetFocus()
     919                  else:
     920                          self._TCTRL_number.SetFocus()
     921          #----------------------------------------------------------------
     922 -        def _refresh_from_existing(self):
     923                  if self.__type_is_editable:
     924                          self._PRW_type.SetText(self.data['l10n_address_type'])
     925                  else:
     926                          self._PRW_type.SetText('', None)
     927                  self._PRW_zip.SetText(self.data['postcode'])
     928                  self._PRW_street.SetText(self.data['street'], data = self.data['street'])
     929                  self._TCTRL_notes_street.SetValue(gmTools.coalesce(self.data['notes_street'], ''))
     930                  self._TCTRL_number.SetValue(self.data['number'])
     931                  self._TCTRL_subunit.SetValue(gmTools.coalesce(self.data['subunit'], ''))
     932                  self._PRW_suburb.SetText(gmTools.coalesce(self.data['suburb'], ''))
     933                  self._PRW_urb.SetText(self.data['urb'], data = self.data['urb'])
     934                  self._PRW_state.SetText(self.data['l10n_region'], data = self.data['code_region'])
     935                  self._PRW_country.SetText(self.data['l10n_country'], data = self.data['code_country'])
     936                  self._TCTRL_notes_subunit.SetValue(gmTools.coalesce(self.data['notes_subunit'], ''))
     937
     938                  if self.__type_is_editable:
     939                          self._PRW_type.SetFocus()
     940                  else:
     941                          self._PRW_zip.SetFocus()
     942          #----------------------------------------------------------------
     943          # event handling
     944          #----------------------------------------------------------------
     945 -        def _on_zip_set(self):
     946                  """Set the street, town, region and country according to entered zip code."""
     947                  zip_code = self._PRW_zip.GetValue()
     948                  if zip_code.strip() == '':
     949                          self._PRW_street.unset_context(context = 'zip')
     950                          self._PRW_urb.unset_context(context = 'zip')
     951                          self._PRW_state.unset_context(context = 'zip')
     952                          self._PRW_country.unset_context(context = 'zip')
     953                  else:
     954                          self._PRW_street.set_context(context = 'zip', val = zip_code)
     955                          self._PRW_urb.set_context(context = 'zip', val = zip_code)
     956                          self._PRW_state.set_context(context = 'zip', val = zip_code)
     957                          self._PRW_country.set_context(context = 'zip', val = zip_code)
     958          #----------------------------------------------------------------
     959 -        def _on_country_set(self):
     960                  """Set the regions according to entered country."""
     961                  country = self._PRW_country.GetData()
     962                  if country is None:
     963                          self._PRW_state.unset_context(context = 'country')
     964                  else:
     965                          self._PRW_state.set_context(context = 'country', val = country)
     966          #----------------------------------------------------------------
     967          # properties
     968          #----------------------------------------------------------------
     969 -        def _get_type_is_editable(self):
     970                  return self.__type_is_editable
     971
     972 -        def _set_type_is_editable(self, type_is_editable):
     973                  self.__type_is_editable = type_is_editable
     974                  self._PRW_type.Enable(type_is_editable)
     975                  self._PRW_type.Show(type_is_editable)
     976                  self._LBL_type.Show(type_is_editable)
     977
     978          type_is_editable = property(_get_type_is_editable, _set_type_is_editable)
     979          #----------------------------------------------------------------
     980 -        def _get_address_is_searchable(self):
     981                  return self.__address_is_searchable
     982
     983 -        def _set_address_is_searchable(self, address_is_searchable):
     984                  # FIXME: always set to FALSE when self.mode == 'new' ?
     985                  self.__address_is_searchable = address_is_searchable
     986                  self._PRW_address_searcher.Enable(address_is_searchable)
     987                  self._PRW_address_searcher.Show(address_is_searchable)
     988                  self._LBL_search.Show(address_is_searchable)
     989
     990          address_is_searchable = property(_get_address_is_searchable, _set_address_is_searchable)
     991          #----------------------------------------------------------------
     992 -        def _get_address(self):
     993                  return self.data
     994
     995 -        def _set_address(self, address):
     996                  self.data = address
     997
     998          address = property(_get_address, _set_address)
     999
    1000  #============================================================
    1001 -class cAddressMatchProvider(gmMatchProvider.cMatchProvider_SQL2):
    1002
    1003 -        def __init__(self):
    1004
    1005                  query = """
    1006  SELECT * FROM (
    1007          (SELECT
    1008                  pk_address AS data,
    1009                  (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
    1010                                  || urb || coalesce(' (' || suburb || ')', '') || ', '
    1011                                  || postcode || ', '
    1012                                  || code_country
    1013                  ) AS field_label,
    1014                  (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
    1015                                  || urb || coalesce(' (' || suburb || ')', '') || ', '
    1016                                  || postcode || ', '
    1017                                  || l10n_region || ', '
    1018                                  || l10n_country
    1019                                  || coalesce(', ' || notes_street, '')
    1020                                  || coalesce(', ' || notes_subunit, '')
    1021                  ) AS list_label
    1022          FROM
    1023                  dem.v_address
    1024          WHERE
    1025                  street %(fragment_condition)s
    1026
    1027          ) UNION (
    1028
    1029          SELECT
    1030                  pk_address AS data,
    1031                  (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
    1032                                  || urb || coalesce(' (' || suburb || ')', '') || ', '
    1033                                  || postcode || ', '
    1034                                  || code_country
    1035                  ) AS field_label,
    1036                  (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
    1037                                  || urb || coalesce(' (' || suburb || ')', '') || ', '
    1038                                  || postcode || ', '
    1039                                  || l10n_region || ', '
    1040                                  || l10n_country
    1041                                  || coalesce(', ' || notes_street, '')
    1042                                  || coalesce(', ' || notes_subunit, '')
    1043                  ) AS list_label
    1044          FROM
    1045                  dem.v_address
    1046          WHERE
    1047                  postcode_street %(fragment_condition)s
    1048
    1049          ) UNION (
    1050
    1051          SELECT
    1052                  pk_address AS data,
    1053                  (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
    1054                                  || urb || coalesce(' (' || suburb || ')', '') || ', '
    1055                                  || postcode || ', '
    1056                                  || code_country
    1057                  ) AS field_label,
    1058                  (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
    1059                                  || urb || coalesce(' (' || suburb || ')', '') || ', '
    1060                                  || postcode || ', '
    1061                                  || l10n_region || ', '
    1062                                  || l10n_country
    1063                                  || coalesce(', ' || notes_street, '')
    1064                                  || coalesce(', ' || notes_subunit, '')
    1065                  ) AS list_label
    1066          FROM
    1067                  dem.v_address
    1068          WHERE
    1069                  postcode_urb %(fragment_condition)s
    1070          )
    1071  ) AS matching_addresses
    1072  ORDER BY list_label
    1073  LIMIT 50"""
    1074
    1075                  gmMatchProvider.cMatchProvider_SQL2.__init__(self, queries = query)
    1076
    1077                  self.setThresholds(2, 4, 6)
    1078  #               self.word_separators = u'[ \t]+'
    1079
    1080                  self._SQL_data2match = """
    1081          SELECT
    1082                  pk_address AS data,
    1083                  (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
    1084                                  || urb || coalesce(' (' || suburb || ')', '') || ', '
    1085                                  || postcode || ', '
    1086                                  || code_country
    1087                  ) AS field_label,
    1088                  (street || ' ' || number || coalesce(' (' || subunit || ')', '') || ', '
    1089                                  || urb || coalesce(' (' || suburb || ')', '') || ', '
    1090                                  || postcode || ', '
    1091                                  || l10n_region || ', '
    1092                                  || l10n_country
    1093                                  || coalesce(', ' || notes_street, '')
    1094                                  || coalesce(', ' || notes_subunit, '')
    1095                  ) AS list_label
    1096          FROM
    1097                  dem.v_address
    1098          WHERE
    1099                  pk_address = %(pk)s
    1100          """
    1101
    1102  #============================================================
    1103 -class cAddressPhraseWheel(gmPhraseWheel.cPhraseWheel):
    1104
    1105 -        def __init__(self, *args, **kwargs):
    1106
    1107                  gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs)
    1108                  self.matcher = cAddressMatchProvider()
    1109                  self.SetToolTip(_('Select an address by postcode or street name.'))
    1110                  self.selection_only = True
    1111                  self.__address = None
    1112                  self.__old_pk = None
    1113          #--------------------------------------------------------
    1114 -        def _get_data_tooltip(self):
    1115                  adr = self.address
    1116                  if adr is None:
    1117                          return None
    1118                  return '\n'.join(adr.format())
    1119          #--------------------------------------------------------
    1120 -        def _data2instance(self):
    1121                  return gmDemographicRecord.cAddress(aPK_obj = self.GetData())
    1122          #--------------------------------------------------------
    1123          # properties
    1124          #--------------------------------------------------------
    1125 -        def __get_address(self):
    1126                  pk = self.GetData()
    1127                  if pk is None:
    1128                          self.__address = None
    1129                          return None
    1130                  if self.__address is None:
    1131                          self.__old_pk = pk
    1132                          self.__address = gmDemographicRecord.cAddress(aPK_obj = pk)
    1133                  else:
    1134                          if pk != self.__old_pk:
    1135                                  self.__old_pk = pk
    1136                                  self.__address = gmDemographicRecord.cAddress(aPK_obj = pk)
    1137                  return self.__address
    1138
    1139 -        def __set_address(self, address):
    1140                  if address is None:
    1141                          self.__old_pk = None
    1142                          self.__address = None
    1143                          self.SetText('', None)
    1144                          return
    1145                  if isinstance(address, gmDemographicRecord.cAddress):
    1146                          self.__old_pk = address['pk_address']
    1147                          self.__address = address
    1148                          pk = self.__old_pk
    1149                  else:
    1150                          self.__old_pk = None
    1151                          self.__address = None
    1152                          pk = address
    1153                  match = self.matcher.get_match_by_data(data = pk)
    1154                  if match is None:
    1155                          raise ValueError('[%s]: cannot match address [#%s]' % (self.__class__.__name__, pk))
    1156                  self.SetText(match['field_label'], pk)
    1157
    1158          address = property(__get_address, __set_address)
    1159          #--------------------------------------------------------
    1160 -        def __get_person_address(self):
    1161                  pk = self.GetData()
    1162                  if pk is None:
    1163                          self.__address = None
    1164                          return None
    1165                  if self.__address is None:
    1166                          self.__old_pk = pk
    1167                          self.__address = gmDemographicRecord.cPatientAddress(aPK_obj = pk)
    1168                  else:
    1169                          if pk != self.__old_pk:
    1170                                  self.__old_pk = pk
    1171                                  self.__address = gmDemographicRecord.cPatientAddress(aPK_obj = pk)
    1172                  return self.__address
    1173
    1174          person_address = property(__get_person_address, lambda x:x)
    1175
    1176  #============================================================
    1177  from Gnumed.wxGladeWidgets import wxgAddressSelectionDlg
    1178
    1179 -class cAddressSelectionDlg(wxgAddressSelectionDlg.wxgAddressSelectionDlg):
    1180
    1181 -        def __init__(self, *args, **kwargs):
    1182                  wxgAddressSelectionDlg.wxgAddressSelectionDlg.__init__(self, *args, **kwargs)
    1183                  self._PRW_address_searcher.SetFocus()
    1184          #--------------------------------------------------------
    1185 -        def _get_address(self):
    1186                  return self._PRW_address_searcher.address
    1187
    1188          address = property(_get_address, lambda x:x)
    1189          #--------------------------------------------------------
    1190 -        def _set_message(self, msg):
    1191                  self._LBL_msg.SetLabel(msg)
    1192
    1193          message = property(lambda x:x, _set_message)
    1194          #--------------------------------------------------------
    1195 -        def _on_manage_addresses_button_pressed(self, event):
    1196                  event.Skip()
    1197                  manage_addresses(parent = self)
    1198
    1199  #================================================================
    1200  # main
    1201  #----------------------------------------------------------------
    1202  if __name__ == '__main__':
    1203
    1204          if len(sys.argv) < 2:
    1205                  sys.exit()
    1206
    1207          if sys.argv[1] != 'test':
    1208                  sys.exit()
    1209
    1210          from Gnumed.pycommon import gmI18N
    1211          gmI18N.activate_locale()
    1212          gmI18N.install_domain()
    1213          from Gnumed.business import gmPersonSearch
    1214
    1215          #--------------------------------------------------------
    1216 -        def test_country_prw():
    1217                  app = wx.PyWidgetTester(size = (200, 50))
    1218                  pw = cCountryPhraseWheel(app.frame, -1)
    1219                  app.frame.Show(True)
    1220                  app.MainLoop()
    1221          #--------------------------------------------------------
    1222 -        def test_region_prw():
    1223                  app = wx.PyWidgetTester(size = (200, 50))
    1224                  pw = cStateSelectionPhraseWheel(app.frame, -1)
    1225                  pw.set_context(context = 'zip', val = '04318')
    1226                  pw.set_context(context = 'country', val = 'Deutschland')
    1227                  app.frame.Show(True)
    1228                  app.MainLoop()
    1229          #--------------------------------------------------------
    1230 -        def test_zipcode_prw():
    1231                  app = wx.PyWidgetTester(size = (200, 50))
    1232                  pw = cZipcodePhraseWheel(app.frame, -1)
    1233                  app.frame.Show(True)
    1234                  app.MainLoop()
    1235          #--------------------------------------------------------
    1236 -        def test_street_prw():
    1237                  app = wx.PyWidgetTester(size = (200, 50))
    1238                  pw = cStreetPhraseWheel(app.frame, -1)
    1239  #               pw.set_context(context = u'zip', val = u'04318')
    1240                  app.frame.Show(True)
    1241                  app.MainLoop()
    1242          #--------------------------------------------------------
    1243 -        def test_suburb_prw():
    1244                  app = wx.PyWidgetTester(size = (200, 50))
    1245                  pw = cSuburbPhraseWheel(app.frame, -1)
    1246                  app.frame.Show(True)
    1247                  app.MainLoop()
    1248          #--------------------------------------------------------
    1249 -        def test_urb_prw():
    1250                  app = wx.PyWidgetTester(size = (200, 50))
    1251                  pw = cUrbPhraseWheel(app.frame, -1)
    1252                  app.frame.Show(True)
    1253                  pw.set_context(context = 'zip', val = '04317')
    1254                  app.MainLoop()
    1255          #--------------------------------------------------------
    1256 -        def test_address_type_prw():
    1257                  app = wx.PyWidgetTester(size = (200, 50))
    1258                  pw = cAddressTypePhraseWheel(app.frame, -1)
    1259                  app.frame.Show(True)
    1260                  app.MainLoop()
    1261          #--------------------------------------------------------
    1262 -        def test_address_prw():
    1263                  app = wx.PyWidgetTester(size = (200, 50))
    1264                  pw = cAddressPhraseWheel(app.frame, -1)
    1265                  app.frame.Show(True)
    1266                  app.MainLoop()
    1267          #--------------------------------------------------------
    1268 -        def test_address_ea_pnl():
    1269                  app = wx.PyWidgetTester(size = (600, 400))
    1270                  app.SetWidget(cAddressEditAreaPnl, address = gmDemographicRecord.cAddress(aPK_obj = 1))
    1271                  app.MainLoop()
    1272          #--------------------------------------------------------
    1273          #test_address_type_prw()
    1274          #test_zipcode_prw()
    1275          #test_region_prw()
    1276          #test_street_prw()
    1277          #test_suburb_prw()
    1278          #test_country_prw()
    1279          #test_urb_prw()
    1280          #test_address_ea_pnl()
    1281          test_address_prw()
    1282
    1283  #================================================================
    1284