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

# Source Code for Module Gnumed.wxpython.gmEditArea

       1  #====================================================================
       2  # GNUmed Richard style Edit Area
       3  #====================================================================
       4  __license__ = 'GPL'
       5  __version__ = "$Revision: 1.135 $"
       6  __author__ = "R.Terry, K.Hilbert"
       7
       8  #======================================================================
       9  import sys
      10  import logging
      11  import datetime as pydt
      12
      13
      14  import wx
      15
      16
      17  if __name__ == '__main__':
      18          sys.path.insert(0, '../../')
      19  from Gnumed.pycommon import gmDispatcher
      20
      21
      22  _log = logging.getLogger('gm.ui')
      23  _log.info(__version__)
      24  #====================================================================
      25  edit_area_modes = ['new', 'edit', 'new_from_existing']
      26
      27 -class cGenericEditAreaMixin(object):
      28          """Mixin for edit area panels providing generic functionality.
      29
      30          **************** start of template ****************
      31
      32  #====================================================================
      33  # Class definition:
      34
      35  from Gnumed.wxGladeWidgets import wxgXxxEAPnl
      36
      37  class cXxxEAPnl(wxgXxxEAPnl.wxgXxxEAPnl, gmEditArea.cGenericEditAreaMixin):
      38
      39          def __init__(self, *args, **kwargs):
      40
      41                  try:
      42                          data = kwargs['xxx']
      43                          del kwargs['xxx']
      44                  except KeyError:
      45                          data = None
      46
      47                  wxgXxxEAPnl.wxgXxxEAPnl.__init__(self, *args, **kwargs)
      48                  gmEditArea.cGenericEditAreaMixin.__init__(self)
      49
      50                  # Code using this mixin should set mode and data
      51                  # after instantiating the class:
      52                  self.mode = 'new'
      53                  self.data = data
      54                  if data is not None:
      55                          self.mode = 'edit'
      56
      57                  #self.__init_ui()
      58          #----------------------------------------------------------------
      59  #       def __init_ui(self):
      60  #               # adjust phrasewheels etc
      61          #----------------------------------------------------------------
      62          # generic Edit Area mixin API
      63          #----------------------------------------------------------------
      64          def _valid_for_save(self):
      65
      66                  # its best to validate bottom -> top such that the
      67                  # cursor ends up in the topmost failing field
      68
      69                  # remove when implemented:
      70                  return False
      71
      72                  validity = True
      73
      74                  if self._TCTRL_xxx.GetValue().strip() == u'':
      75                          validity = False
      76                          self.display_tctrl_as_valid(tctrl = self._TCTRL_xxx, valid = False)
      77                          self._TCTRL_xxx.SetFocus()
      78                  else:
      79                          self.display_tctrl_as_valid(tctrl = self._TCTRL_xxx, valid = True)
      80
      81                  if self._PRW_xxx.GetData() is None:
      82                          validity = False
      83                          self._PRW_xxx.display_as_valid(False)
      84                          self._PRW_xxx.SetFocus()
      85                  else:
      86                          self._PRW_xxx.display_as_valid(True)
      87
      88                  return validity
      89          #----------------------------------------------------------------
      90          def _save_as_new(self):
      91                  # save the data as a new instance
      92                  data = gmXXXX.create_xxxx()
      93
      94                  data[''] = self._
      95                  data[''] = self._
      96
      97                  data.save()
      98
      99                  # must be done very late or else the property access
     100                  # will refresh the display such that later field
     101                  # access will return empty values
     102                  self.data = data
     103                  return False
     104                  return True
     105          #----------------------------------------------------------------
     106          def _save_as_update(self):
     107                  # update self.data and save the changes
     108                  self.data[''] = self._TCTRL_xxx.GetValue().strip()
     109                  self.data[''] = self._PRW_xxx.GetData()
     110                  self.data[''] = self._CHBOX_xxx.GetValue()
     111                  self.data.save()
     112                  return True
     113          #----------------------------------------------------------------
     114          def _refresh_as_new(self):
     115                  pass
     116          #----------------------------------------------------------------
     117          def _refresh_as_new_from_existing(self):
     118                  self._refresh_as_new()
     119          #----------------------------------------------------------------
     120          def _refresh_from_existing(self):
     121                  pass
     122          #----------------------------------------------------------------
     123
     124          **************** end of template ****************
     125          """
     126 -        def __init__(self):
     127                  self.__mode = 'new'
     128                  self.__data = None
     129                  self.successful_save_msg = None
     130                  self.__tctrl_validity_colors = {
     131                          True: wx.SystemSettings_GetColour(wx.SYS_COLOUR_WINDOW),
     132                          False: 'pink'
     133                  }
     134                  self._refresh_as_new()
     135          #----------------------------------------------------------------
     136 -        def _get_mode(self):
     137                  return self.__mode
     138
     139 -        def _set_mode(self, mode=None):
     140                  if mode not in edit_area_modes:
     141                          raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
     142                  if mode == 'edit':
     143                          if self.__data is None:
     144                                  raise ValueError('[%s] <mode> "edit" needs data value' % self.__class__.__name__)
     145
     146                  prev_mode = self.__mode
     147                  self.__mode = mode
     148                  if mode != prev_mode:
     149                          self.refresh()
     150
     151          mode = property(_get_mode, _set_mode)
     152          #----------------------------------------------------------------
     153 -        def _get_data(self):
     154                  return self.__data
     155
     156 -        def _set_data(self, data=None):
     157                  if data is None:
     158                          if self.__mode == 'edit':
     159                                  raise ValueError('[%s] <mode> "edit" needs data value' % self.__class__.__name__)
     160                  self.__data = data
     161                  self.refresh()
     162
     163          data = property(_get_data, _set_data)
     164          #----------------------------------------------------------------
     165 -        def save(self):
     166                  """Invoked from the generic edit area dialog.
     167
     168                  Invokes
     169                          _valid_for_save,
     170                          _save_as_new,
     171                          _save_as_update
     172                  on the implementing edit area as needed.
     173
     174                  _save_as_* must set self.__data and return True/False
     175                  """
     176                  if not self._valid_for_save():
     177                          return False
     178
     179                  # remove messages about previous invalid save attempts
     180                  gmDispatcher.send(signal = 'statustext', msg = u'')
     181
     182                  if self.__mode in ['new', 'new_from_existing']:
     183                          if self._save_as_new():
     184                                  self.mode = 'edit'
     185                                  return True
     186                          return False
     187
     188                  elif self.__mode == 'edit':
     189                          return self._save_as_update()
     190
     191                  else:
     192                          raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
     193          #----------------------------------------------------------------
     194 -        def refresh(self):
     195                  """Invoked from the generic edit area dialog.
     196
     197                  Invokes
     198                          _refresh_as_new()
     199                          _refresh_from_existing()
     200                          _refresh_as_new_from_existing()
     201                  on the implementing edit area as needed.
     202
     203                  Then calls _valid_for_save().
     204                  """
     205                  if self.__mode == 'new':
     206                          result = self._refresh_as_new()
     207                          self._valid_for_save()
     208                          return result
     209                  elif self.__mode == 'edit':
     210                          result = self._refresh_from_existing()
     211                          return result
     212                  elif self.__mode == 'new_from_existing':
     213                          result = self._refresh_as_new_from_existing()
     214                          self._valid_for_save()
     215                          return result
     216                  else:
     217                          raise ValueError('[%s] <mode> must be in %s' % (self.__class__.__name__, edit_area_modes))
     218          #----------------------------------------------------------------
     219 -        def display_tctrl_as_valid(self, tctrl=None, valid=None):
     220                  tctrl.SetBackgroundColour(self.__tctrl_validity_colors[valid])
     221                  tctrl.Refresh()
     222          #----------------------------------------------------------------
     223 -        def display_ctrl_as_valid(self, ctrl=None, valid=None):
     224                  ctrl.SetBackgroundColour(self.__tctrl_validity_colors[valid])
     225                  ctrl.Refresh()
     226  #====================================================================
     227  from Gnumed.wxGladeWidgets import wxgGenericEditAreaDlg2
     228
     229 -class cGenericEditAreaDlg2(wxgGenericEditAreaDlg2.wxgGenericEditAreaDlg2):
     230          """Dialog for parenting edit area panels with save/clear/next/cancel"""
     231
     232          _lucky_day = 1
     233          _lucky_month = 4
     234          _today = pydt.date.today()
     235
     236 -        def __init__(self, *args, **kwargs):
     237
     238                  new_ea = kwargs['edit_area']
     239                  del kwargs['edit_area']
     240
     241                  if not isinstance(new_ea, cGenericEditAreaMixin):
     242                          raise TypeError('[%s]: edit area instance must be child of cGenericEditAreaMixin')
     243
     244                  try:
     245                          single_entry = kwargs['single_entry']
     246                          del kwargs['single_entry']
     247                  except KeyError:
     248                          single_entry = False
     249
     250                  wxgGenericEditAreaDlg2.wxgGenericEditAreaDlg2.__init__(self, *args, **kwargs)
     251
     252                  self.left_extra_button = None
     253
     254                  if cGenericEditAreaDlg2._today.day != cGenericEditAreaDlg2._lucky_day:
     255                          self._BTN_lucky.Enable(False)
     256                          self._BTN_lucky.Hide()
     257                  else:
     258                          if cGenericEditAreaDlg2._today.month != cGenericEditAreaDlg2._lucky_month:
     259                                  self._BTN_lucky.Enable(False)
     260                                  self._BTN_lucky.Hide()
     261
     262                  # replace dummy panel
     263                  dummy_ea_pnl = self._PNL_ea
     264                  ea_pnl_szr = dummy_ea_pnl.GetContainingSizer()
     265                  ea_pnl_parent = dummy_ea_pnl.GetParent()
     266                  ea_pnl_szr.Remove(dummy_ea_pnl)
     267                  dummy_ea_pnl.Destroy()
     268                  del dummy_ea_pnl
     269                  new_ea_min_size = new_ea.GetMinSize()
     270                  new_ea.Reparent(ea_pnl_parent)
     271                  self._PNL_ea = new_ea
     272                  ea_pnl_szr.Add(self._PNL_ea, 1, wx.EXPAND, 0)
     273                  ea_pnl_szr.SetMinSize(new_ea_min_size)                                  # set minimum size of EA pnl sizer from its new EA item
     274                  ea_pnl_szr.Fit(new_ea)                                                                  # resize the new EA to the minimum size of the EA pnl sizer
     275
     276                  # adjust buttons
     277                  if single_entry:
     278                          self._BTN_forward.Enable(False)
     279                          self._BTN_forward.Hide()
     280
     281                  self._adjust_clear_revert_buttons()
     282
     283                  # redraw layout
     284                  #self.Layout()
     285                  main_szr = self.GetSizer()
     286                  main_szr.Fit(self)
     287                  self.Layout()
     288                  #self.Refresh()                         # apparently not needed (27.3.2011)
     289
     290                  self._PNL_ea.refresh()
     291          #--------------------------------------------------------
     292 -        def _adjust_clear_revert_buttons(self):
     293                  if self._PNL_ea.data is None:
     294                          self._BTN_clear.Enable(True)
     295                          self._BTN_clear.Show()
     296                          self._BTN_revert.Enable(False)
     297                          self._BTN_revert.Hide()
     298                  else:
     299                          self._BTN_clear.Enable(False)
     300                          self._BTN_clear.Hide()
     301                          self._BTN_revert.Enable(True)
     302                          self._BTN_revert.Show()
     303          #--------------------------------------------------------
     304 -        def _on_save_button_pressed(self, evt):
     305                  if self._PNL_ea.save():
     306                          if self.IsModal():
     307                                  self.EndModal(wx.ID_OK)
     308                          else:
     309                                  self.Close()
     310          #--------------------------------------------------------
     311 -        def _on_revert_button_pressed(self, evt):
     312                  self._PNL_ea.refresh()
     313          #--------------------------------------------------------
     314 -        def _on_clear_button_pressed(self, evt):
     315                  self._PNL_ea.refresh()
     316          #--------------------------------------------------------
     317 -        def _on_forward_button_pressed(self, evt):
     318                  if self._PNL_ea.save():
     319                          if self._PNL_ea.successful_save_msg is not None:
     320                                  gmDispatcher.send(signal = 'statustext', msg = self._PNL_ea.successful_save_msg)
     321                          self._PNL_ea.mode = 'new_from_existing'
     322
     323                          self._adjust_clear_revert_buttons()
     324
     325                          self.Layout()
     326                          main_szr = self.GetSizer()
     327                          main_szr.Fit(self)
     328                          self.Refresh()
     329
     330                          self._PNL_ea.refresh()
     331          #--------------------------------------------------------
     332 -        def _on_lucky_button_pressed(self, evt):
     333                  gmGuiHelpers.gm_show_info (
     334                          _(      'Today is your lucky day !\n'
     335                                  '\n'
     336                                  'You have won one year of GNUmed\n'
     337                                  'updates for free !\n'
     338                          ),
     339                          _('GNUmed Lottery')
     340                  )
     341          #--------------------------------------------------------
     342 -        def _on_left_extra_button_pressed(self, event):
     343                  if not self.__left_extra_button_callback(self._PNL_ea.data):
     344                          return
     345
     346                  if self.IsModal():
     347                          self.EndModal(wx.ID_OK)
     348                  else:
     349                          self.Close()
     350          #------------------------------------------------------------
     351          # properties
     352          #------------------------------------------------------------
     353 -        def _set_left_extra_button(self, definition):
     354                  if definition is None:
     355                          self._BTN_extra_left.Enable(False)
     356                          self._BTN_extra_left.Hide()
     357                          self.__left_extra_button_callback = None
     358                          return
     359
     360                  (label, tooltip, callback) = definition
     361                  if not callable(callback):
     362                          raise ValueError('<left extra button> callback is not a callable: %s' % callback)
     363                  self.__left_extra_button_callback = callback
     364                  self._BTN_extra_left.SetLabel(label)
     365                  self._BTN_extra_left.SetToolTipString(tooltip)
     366                  self._BTN_extra_left.Enable(True)
     367                  self._BTN_extra_left.Show()
     368
     369          left_extra_button = property(lambda x:x, _set_left_extra_button)
     370  #====================================================================
     371  # DEPRECATED:
     372  from Gnumed.wxGladeWidgets import wxgGenericEditAreaDlg
     373
     374 -class cGenericEditAreaDlg(wxgGenericEditAreaDlg.wxgGenericEditAreaDlg):
     375          """Dialog for parenting edit area with save/clear/cancel"""
     376
     377 -        def __init__(self, *args, **kwargs):
     378
     379                  ea = kwargs['edit_area']
     380                  del kwargs['edit_area']
     381
     382                  wxgGenericEditAreaDlg.wxgGenericEditAreaDlg.__init__(self, *args, **kwargs)
     383
     384                  szr = self._PNL_ea.GetContainingSizer()
     385                  szr.Remove(self._PNL_ea)
     386                  ea.Reparent(self)
     387                  szr.Add(ea, 1, wx.ALL|wx.EXPAND, 4)
     388                  self._PNL_ea = ea
     389
     390                  self.Layout()
     391                  szr = self.GetSizer()
     392                  szr.Fit(self)
     393                  self.Refresh()
     394
     395                  self._PNL_ea.refresh()
     396          #--------------------------------------------------------
     397 -        def _on_save_button_pressed(self, evt):
     398                  """The edit area save() method must return True/False."""
     399                  if self._PNL_ea.save():
     400                          if self.IsModal():
     401                                  self.EndModal(wx.ID_OK)
     402                          else:
     403                                  self.Close()
     404          #--------------------------------------------------------
     405 -        def _on_clear_button_pressed(self, evt):
     406                  self._PNL_ea.refresh()
     407  #====================================================================
     408  #====================================================================
     409  #====================================================================
     410  #import time
     411
     412  #from Gnumed.business import gmPerson, gmDemographicRecord
     413  from Gnumed.pycommon import gmGuiBroker
     414  #from Gnumed.wxpython import gmDateTimeInput, gmPhraseWheel, gmGuiHelpers
     415
     416  _gb = gmGuiBroker.GuiBroker()
     417
     418  gmSECTION_SUMMARY = 1
     419  gmSECTION_DEMOGRAPHICS = 2
     420  gmSECTION_CLINICALNOTES = 3
     421  gmSECTION_FAMILYHISTORY = 4
     422  gmSECTION_PASTHISTORY = 5
     423  gmSECTION_SCRIPT = 8
     424  gmSECTION_REQUESTS = 9
     425  gmSECTION_REFERRALS = 11
     426  gmSECTION_RECALLS = 12
     427
     428  richards_blue = wx.Colour(0,0,131)
     429  richards_aqua = wx.Colour(0,194,197)
     430  richards_dark_gray = wx.Colour(131,129,131)
     431  richards_light_gray = wx.Colour(255,255,255)
     432  richards_coloured_gray = wx.Colour(131,129,131)
     433
     434
     435  CONTROLS_WITHOUT_LABELS =['wxTextCtrl', 'cEditAreaField', 'wx.SpinCtrl', 'gmPhraseWheel', 'wx.ComboBox']
     436
     437 -def _decorate_editarea_field(widget):
     438          widget.SetForegroundColour(wx.Colour(255, 0, 0))
     439          widget.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
     440  #====================================================================
     441 -class cEditAreaPopup(wx.Dialog):
     442 -        def __init__ (
     443                  self,
     444                  parent,
     445                  id,
     446                  title = 'edit area popup',
     447                  pos=wx.DefaultPosition,
     448                  size=wx.DefaultSize,
     449                  style=wx.SIMPLE_BORDER,
     450                  name='',
     451                  edit_area = None
     452          ):
     453                  if not isinstance(edit_area, cEditArea2):
     454                          raise TypeError('<edit_area> must be of type cEditArea2 but is <%s>' % type(edit_area))
     455                  wx.Dialog.__init__(self, parent, id, title, pos, size, style, name)
     456                  self.__wxID_BTN_SAVE = wx.NewId()
     457                  self.__wxID_BTN_RESET = wx.NewId()
     458                  self.__editarea = edit_area
     459                  self.__do_layout()
     460                  self.__register_events()
     461          #--------------------------------------------------------
     462          # public API
     463          #--------------------------------------------------------
     464 -        def get_summary(self):
     465                  return self.__editarea.get_summary()
     466          #--------------------------------------------------------
     467 -        def __do_layout(self):
     468                  self.__editarea.Reparent(self)
     469
     470                  self.__btn_SAVE = wx.Button(self, self.__wxID_BTN_SAVE, _("Save"))
     471                  self.__btn_SAVE.SetToolTipString(_('save entry into medical record'))
     472                  self.__btn_RESET = wx.Button(self, self.__wxID_BTN_RESET, _("Reset"))
     473                  self.__btn_RESET.SetToolTipString(_('reset entry'))
     474                  self.__btn_CANCEL = wx.Button(self, wx.ID_CANCEL, _("Cancel"))
     475                  self.__btn_CANCEL.SetToolTipString(_('discard entry and cancel'))
     476
     477                  szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
     478                  szr_buttons.Add(self.__btn_SAVE, 1, wx.EXPAND | wx.ALL, 1)
     479                  szr_buttons.Add(self.__btn_RESET, 1, wx.EXPAND | wx.ALL, 1)
     480                  szr_buttons.Add(self.__btn_CANCEL, 1, wx.EXPAND | wx.ALL, 1)
     481
     482                  szr_main = wx.BoxSizer(wx.VERTICAL)
     483                  szr_main.Add(self.__editarea, 1, wx.EXPAND)
     484                  szr_main.Add(szr_buttons, 0, wx.EXPAND)
     485
     486                  self.SetSizerAndFit(szr_main)
     487          #--------------------------------------------------------
     488          # event handling
     489          #--------------------------------------------------------
     490 -        def __register_events(self):
     491                  # connect standard buttons
     492                  wx.EVT_BUTTON(self.__btn_SAVE, self.__wxID_BTN_SAVE, self._on_SAVE_btn_pressed)
     493                  wx.EVT_BUTTON(self.__btn_RESET, self.__wxID_BTN_RESET, self._on_RESET_btn_pressed)
     494                  wx.EVT_BUTTON(self.__btn_CANCEL, wx.ID_CANCEL, self._on_CANCEL_btn_pressed)
     495
     496                  wx.EVT_CLOSE(self, self._on_CANCEL_btn_pressed)
     497
     498                  # client internal signals
     499  #               gmDispatcher.connect(signal = gmSignals.pre_patient_selection(), receiver = self._on_pre_patient_selection)
     500  #               gmDispatcher.connect(signal = gmSignals.application_closing(), receiver = self._on_application_closing)
     501  #               gmDispatcher.connect(signal = gmSignals.post_patient_selection(), receiver = self.on_post_patient_selection)
     502
     503                  return 1
     504          #--------------------------------------------------------
     505 -        def _on_SAVE_btn_pressed(self, evt):
     506                  if self.__editarea.save_data():
     507                          self.__editarea.Close()
     508                          self.EndModal(wx.ID_OK)
     509                          return
     510                  short_err = self.__editarea.get_short_error()
     511                  long_err = self.__editarea.get_long_error()
     512                  if (short_err is None) and (long_err is None):
     513                          long_err = _(
     514                                  'Unspecified error saving data in edit area.\n\n'
     515                                  'Programmer forgot to specify proper error\n'
     516                                  'message in [%s].'
     517                          ) % self.__editarea.__class__.__name__
     518                  if short_err is not None:
     519                          gmDispatcher.send(signal = 'statustext', msg = short_err)
     520                  if long_err is not None:
     521                          gmGuiHelpers.gm_show_error(long_err, _('saving clinical data'))
     522          #--------------------------------------------------------
     523 -        def _on_CANCEL_btn_pressed(self, evt):
     524                  self.__editarea.Close()
     525                  self.EndModal(wx.ID_CANCEL)
     526          #--------------------------------------------------------
     527 -        def _on_RESET_btn_pressed(self, evt):
     528                  self.__editarea.reset_ui()
     529  #====================================================================
     530 -class cEditArea2(wx.Panel):
     531 -        def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TAB_TRAVERSAL):
     532                  # init main background panel
     533                  wx.Panel.__init__ (
     534                          self,
     535                          parent,
     536                          id,
     537                          pos = pos,
     538                          size = size,
     539                          style = style | wx.TAB_TRAVERSAL
     540                  )
     541                  self.SetBackgroundColour(wx.Colour(222,222,222))
     542
     543                  self.data = None                # a placeholder for opaque data
     544                  self.fields = {}
     545                  self.prompts = {}
     546                  self._short_error = None
     547                  self._long_error = None
     548                  self._summary = None
     549                  self._patient = gmPerson.gmCurrentPatient()
     550                  self.__wxID_BTN_OK = wx.NewId()
     551                  self.__wxID_BTN_CLEAR = wx.NewId()
     552                  self.__do_layout()
     553                  self.__register_events()
     554                  self.Show()
     555          #--------------------------------------------------------
     556          # external API
     557          #--------------------------------------------------------
     558 -        def save_data(self):
     559                  """This needs to be overridden by child classes."""
     560                  self._long_error = _(
     561                          'Cannot save data from edit area.\n\n'
     562                          'Programmer forgot to override method:\n'
     563                          '  <%s.save_data>'
     564                  ) % self.__class__.__name__
     565                  return False
     566          #--------------------------------------------------------
     567 -        def reset_ui(self):
     568                  msg = _(
     569                          'Cannot reset fields in edit area.\n\n'
     570                          'Programmer forgot to override method:\n'
     571                          '  <%s.reset_ui>'
     572                  ) % self.__class__.__name__
     573                  gmGuiHelpers.gm_show_error(msg)
     574          #--------------------------------------------------------
     575 -        def get_short_error(self):
     576                  tmp = self._short_error
     577                  self._short_error = None
     578                  return tmp
     579          #--------------------------------------------------------
     580 -        def get_long_error(self):
     581                  tmp = self._long_error
     582                  self._long_error = None
     583                  return tmp
     584          #--------------------------------------------------------
     585 -        def get_summary(self):
     586                  return _('<No embed string for [%s]>') % self.__class__.__name__
     587          #--------------------------------------------------------
     588          # event handling
     589          #--------------------------------------------------------
     590 -        def __register_events(self):
     591                  # client internal signals
     592                  if self._patient.connected:
     593                          gmDispatcher.connect(signal = 'pre_patient_selection', receiver = self._on_pre_patient_selection)
     594                          gmDispatcher.connect(signal = 'post_patient_selection', receiver = self.on_post_patient_selection)
     595                  gmDispatcher.connect(signal = 'application_closing', receiver = self._on_application_closing)
     596
     597                  # wxPython events
     598                  wx.EVT_CLOSE(self, self._on_close)
     599
     600                  return 1
     601          #--------------------------------------------------------
     602 -        def __deregister_events(self):
     603                  gmDispatcher.disconnect(signal = u'pre_patient_selection', receiver = self._on_pre_patient_selection)
     604                  gmDispatcher.disconnect(signal = u'post_patient_selection', receiver = self.on_post_patient_selection)
     605                  gmDispatcher.disconnect(signal = u'application_closing', receiver = self._on_application_closing)
     606          #--------------------------------------------------------
     607          # handlers
     608          #--------------------------------------------------------
     609 -        def _on_close(self, event):
     610                  self.__deregister_events()
     611                  event.Skip()
     612          #--------------------------------------------------------
     613 -        def _on_OK_btn_pressed(self, event):
     614                  """Only active if _make_standard_buttons was called in child class."""
     615                  # FIXME: this try: except: block seems to large
     616                  try:
     617                          event.Skip()
     618                          if self.data is None:
     619                                  self._save_new_entry()
     620                                  self.reset_ui()
     621                          else:
     622                                  self._save_modified_entry()
     623                                  self.reset_ui()
     624                  except gmExceptions.InvalidInputError, err:
     625                          # nasty evil popup dialogue box
     626                          # but for invalid input we want to interrupt user
     627                          gmGuiHelpers.gm_show_error (err, _("Invalid Input"))
     628                  except:
     629                          _log.exception( "save data problem in [%s]" % self.__class__.__name__)
     630          #--------------------------------------------------------
     631 -        def _on_clear_btn_pressed(self, event):
     632                  """Only active if _make_standard_buttons was called in child class."""
     633                  # FIXME: check for unsaved data
     634                  self.reset_ui()
     635                  event.Skip()
     636          #--------------------------------------------------------
     637 -        def _on_application_closing(self, **kwds):
     638                  self.__deregister_events()
     639                  # remember wxCallAfter
     640                  if not self._patient.connected:
     641                          return True
     642                  # FIXME: should do this:
     643  #               if self.user_wants_save():
     644  #                       if self.save_data():
     645  #                               return True
     646                  return True
     647                  _log.error('[%s] lossage' % self.__class__.__name__)
     648                  return False
     649          #--------------------------------------------------------
     650 -        def _on_pre_patient_selection(self, **kwds):
     651                  """Just before new patient becomes active."""
     652                  # remember wxCallAfter
     653                  if not self._patient.connected:
     654                          return True
     655                  # FIXME: should do this:
     656  #               if self.user_wants_save():
     657  #                       if self.save_data():
     658  #                               return True
     659                  return True
     660                  _log.error('[%s] lossage' % self.__class__.__name__)
     661                  return False
     662          #--------------------------------------------------------
     663 -        def on_post_patient_selection( self, **kwds):
     664                  """Just after new patient became active."""
     665                  # remember to use wxCallAfter()
     666                  self.reset_ui()
     667          #----------------------------------------------------------------
     668          # internal helpers
     669          #----------------------------------------------------------------
     670 -        def __do_layout(self):
     671
     672                  # define prompts and fields
     673                  self._define_prompts()
     674                  self._define_fields(parent = self)
     675                  if len(self.fields) != len(self.prompts):
     676                          _log.error('[%s]: #fields != #prompts' % self.__class__.__name__)
     677                          return None
     678
     679                  # and generate edit area from it
     680                  szr_main_fgrid = wx.FlexGridSizer(rows = len(self.prompts), cols=2)
     681                  color = richards_aqua
     682                  lines = self.prompts.keys()
     683                  lines.sort()
     684                  for line in lines:
     685                          # 1) prompt
     686                          label, color, weight = self.prompts[line]
     687                          # FIXME: style for centering in vertical direction ?
     688                          prompt = wx.StaticText (
     689                                  parent = self,
     690                                  id = -1,
     691                                  label = label,
     692                                  style = wx.ALIGN_CENTRE
     693                          )
     694                          # FIXME: resolution dependant
     695                          prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
     696                          prompt.SetForegroundColour(color)
     697                          prompt.SetBackgroundColour(richards_light_gray)
     698                          szr_main_fgrid.Add(prompt, flag=wx.EXPAND | wx.ALIGN_RIGHT)
     699
     700                          # 2) widget(s) for line
     701                          szr_line = wx.BoxSizer(wx.HORIZONTAL)
     702                          positions = self.fields[line].keys()
     703                          positions.sort()
     704                          for pos in positions:
     705                                  field, weight = self.fields[line][pos]
     706  #                               field.SetBackgroundColour(wx.Colour(222,222,222))
     707                                  szr_line.Add(field, weight, wx.EXPAND)
     708                          szr_main_fgrid.Add(szr_line, flag=wx.GROW | wx.ALIGN_LEFT)
     709
     710                  # grid can grow column 1 only, not column 0
     711                  szr_main_fgrid.AddGrowableCol(1)
     712
     713  #               # use sizer for border around everything plus a little gap
     714  #               # FIXME: fold into szr_main_panels ?
     715  #               self.szr_central_container = wx.BoxSizer(wxHORIZONTAL)
     716  #               self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wxALL, 5)
     717
     718                  # and do the layouting
     719                  self.SetSizerAndFit(szr_main_fgrid)
     720  #               self.FitInside()
     721          #----------------------------------------------------------------
     722          # intra-class API
     723          #----------------------------------------------------------------
     724 -        def _define_prompts(self):
     725                  """Child classes override this to define their prompts using _add_prompt()"""
     726                  _log.error('missing override in [%s]' % self.__class__.__name__)
     727          #----------------------------------------------------------------
     728 -        def _add_prompt(self, line, label='missing label', color=richards_blue, weight=0):
     729                  """Add a new prompt line.
     730
     731                  To be used from _define_fields in child classes.
     732
     733                  - label, the label text
     734                  - color
     735                  - weight, the weight given in sizing the various rows. 0 means the row
     736                    always has minimum size
     737                  """
     738                  self.prompts[line] = (label, color, weight)
     739          #----------------------------------------------------------------
     740 -        def _define_fields(self, parent):
     741                  """Defines the fields.
     742
     743                  - override in child classes
     744                  - mostly uses _add_field()
     745                  """
     746                  _log.error('missing override in [%s]' % self.__class__.__name__)
     747          #----------------------------------------------------------------
     748 -        def _add_field(self, line=None, pos=None, widget=None, weight=0):
     749                  if None in (line, pos, widget):
     750                          _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget))
     751                  if not self.fields.has_key(line):
     752                          self.fields[line] = {}
     753                  self.fields[line][pos] = (widget, weight)
     754          #----------------------------------------------------------------
     755 -        def _make_standard_buttons(self, parent):
     756                  """Generates OK/CLEAR buttons for edit area."""
     757                  self.btn_OK = wx.Button(parent, self.__wxID_BTN_OK, _("OK"))
     758                  self.btn_OK.SetToolTipString(_('save entry into medical record'))
     759                  self.btn_Clear = wx.Button(parent, self.__wxID_BTN_CLEAR, _("Clear"))
     760                  self.btn_Clear.SetToolTipString(_('initialize input fields for new entry'))
     761
     762                  szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
     763                  szr_buttons.Add(self.btn_OK, 1, wx.EXPAND | wx.ALL, 1)
     764                  szr_buttons.Add((5, 0), 0)
     765                  szr_buttons.Add(self.btn_Clear, 1, wx.EXPAND | wx.ALL, 1)
     766
     767                  # connect standard buttons
     768                  wx.EVT_BUTTON(self.btn_OK, self.__wxID_BTN_OK, self._on_OK_btn_pressed)
     769                  wx.EVT_BUTTON(self.btn_Clear, self.__wxID_BTN_CLEAR, self._on_clear_btn_pressed)
     770
     771                  return szr_buttons
     772  #====================================================================
     773  #====================================================================
     774  #text control class to be later replaced by the gmPhraseWheel
     775  #--------------------------------------------------------------------
     776 -class cEditAreaField(wx.TextCtrl):
     777 -        def __init__ (self, parent, id = -1, pos = wx.DefaultPosition, size=wx.DefaultSize):
     778                  wx.TextCtrl.__init__(self,parent,id,"",pos, size ,wx.SIMPLE_BORDER)
     779                  _decorate_editarea_field(self)
     780  #====================================================================
     781 -class cEditArea(wx.Panel):
     782 -        def __init__(self, parent, id, pos, size, style):
     783
     784                  print "class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__
     785
     786                  # init main background panel
     787                  wx.Panel.__init__(self, parent, id, pos=pos, size=size, style=wx.NO_BORDER | wx.TAB_TRAVERSAL)
     788                  self.SetBackgroundColour(wx.Colour(222,222,222))
     789
     790                  self.data = None
     791                  self.fields = {}
     792                  self.prompts = {}
     793
     794                  ID_BTN_OK = wx.NewId()
     795                  ID_BTN_CLEAR = wx.NewId()
     796
     797                  self.__do_layout()
     798
     799  #               self.input_fields = {}
     800
     801  #               self._postInit()
     802  #               self.old_data = {}
     803
     804                  self._patient = gmPerson.gmCurrentPatient()
     805                  self.__register_events()
     806                  self.Show(True)
     807          #----------------------------------------------------------------
     808          # internal helpers
     809          #----------------------------------------------------------------
     810 -        def __do_layout(self):
     811                  # define prompts and fields
     812                  self._define_prompts()
     813                  self.fields_pnl = wx.Panel(self, -1, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
     814                  self._define_fields(parent = self.fields_pnl)
     815                  # and generate edit area from it
     816                  szr_prompts = self.__generate_prompts()
     817                  szr_fields = self.__generate_fields()
     818
     819                  # stack prompts and fields horizontally
     820                  self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL)
     821                  self.szr_main_panels.Add(szr_prompts, 11, wx.EXPAND)
     822                  self.szr_main_panels.Add(5, 0, 0, wx.EXPAND)
     823                  self.szr_main_panels.Add(szr_fields, 90, wx.EXPAND)
     824
     825                  # use sizer for border around everything plus a little gap
     826                  # FIXME: fold into szr_main_panels ?
     827                  self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL)
     828                  self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5)
     829
     830                  # and do the layouting
     831                  self.SetAutoLayout(True)
     832                  self.SetSizer(self.szr_central_container)
     833                  self.szr_central_container.Fit(self)
     834          #----------------------------------------------------------------
     835 -        def __generate_prompts(self):
     836                  if len(self.fields) != len(self.prompts):
     837                          _log.error('[%s]: #fields != #prompts' % self.__class__.__name__)
     838                          return None
     839                  # prompts live on a panel
     840                  prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
     841                  prompt_pnl.SetBackgroundColour(richards_light_gray)
     842                  # make them
     843                  color = richards_aqua
     844                  lines = self.prompts.keys()
     845                  lines.sort()
     846                  self.prompt_widget = {}
     847                  for line in lines:
     848                          label, color, weight = self.prompts[line]
     849                          self.prompt_widget[line] = self.__make_prompt(prompt_pnl, "%s " % label, color)
     850                  # make shadow below prompts in gray
     851                  shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
     852                  shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
     853                  szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
     854                  szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND)
     855                  szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
     856
     857                  # stack prompt panel and shadow vertically
     858                  vszr_prompts = wx.BoxSizer(wx.VERTICAL)
     859                  vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND)
     860                  vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
     861
     862                  # make shadow to the right of the prompts
     863                  shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
     864                  shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
     865                  szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
     866                  szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
     867                  szr_shadow_rightof_prompts.Add(shadow_rightof_prompts, 1, wx.EXPAND)
     868
     869                  # stack vertical prompt sizer and shadow horizontally
     870                  hszr_prompts = wx.BoxSizer(wx.HORIZONTAL)
     871                  hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND)
     872                  hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
     873
     874                  return hszr_prompts
     875          #----------------------------------------------------------------
     876 -        def __generate_fields(self):
     877                  self.fields_pnl.SetBackgroundColour(wx.Colour(222,222,222))
     878                  # rows, cols, hgap, vgap
     879                  vszr = wx.BoxSizer(wx.VERTICAL)
     880                  lines = self.fields.keys()
     881                  lines.sort()
     882                  self.field_line_szr = {}
     883                  for line in lines:
     884                          self.field_line_szr[line] = wx.BoxSizer(wx.HORIZONTAL)
     885                          positions = self.fields[line].keys()
     886                          positions.sort()
     887                          for pos in positions:
     888                                  field, weight = self.fields[line][pos]
     889                                  self.field_line_szr[line].Add(field, weight, wx.EXPAND)
     890                          try:
     891                                  vszr.Add(self.field_line_szr[line], self.prompts[line][2], flag = wx.EXPAND) # use same lineweight as prompts
     892                          except KeyError:
     893                                  _log.error("Error with line=%s, self.field_line_szr has key:%s; self.prompts has key: %s" % (line, self.field_line_szr.has_key(line), self.prompts.has_key(line) ) )
     894                  # put them on the panel
     895                  self.fields_pnl.SetSizer(vszr)
     896                  vszr.Fit(self.fields_pnl)
     897
     898                  # make shadow below edit fields in gray
     899                  shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
     900                  shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray)
     901                  szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
     902                  szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND)
     903                  szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND)
     904
     905                  # stack edit fields and shadow vertically
     906                  vszr_edit_fields = wx.BoxSizer(wx.VERTICAL)
     907                  vszr_edit_fields.Add(self.fields_pnl, 92, wx.EXPAND)
     908                  vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND)
     909
     910                  # make shadow to the right of the edit area
     911                  shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
     912                  shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray)
     913                  szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL)
     914                  szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND)
     915                  szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND)
     916
     917                  # stack vertical edit fields sizer and shadow horizontally
     918                  hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
     919                  hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND)
     920                  hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND)
     921
     922                  return hszr_edit_fields
     923          #---------------------------------------------------------------
     924 -        def __make_prompt(self, parent, aLabel, aColor):
     925                  # FIXME: style for centering in vertical direction ?
     926                  prompt = wx.StaticText(
     927                          parent,
     928                          -1,
     929                          aLabel,
     930                          style = wx.ALIGN_RIGHT
     931                  )
     932                  prompt.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
     933                  prompt.SetForegroundColour(aColor)
     934                  return prompt
     935          #----------------------------------------------------------------
     936          # intra-class API
     937          #----------------------------------------------------------------
     938 -        def _add_prompt(self, line, label='missing label', color=richards_blue, weight=0):
     939                  """Add a new prompt line.
     940
     941                  To be used from _define_fields in child classes.
     942
     943                  - label, the label text
     944                  - color
     945                  - weight, the weight given in sizing the various rows. 0 means the rwo
     946                    always has minimum size
     947                  """
     948                  self.prompts[line] = (label, color, weight)
     949          #----------------------------------------------------------------
     950 -        def _add_field(self, line=None, pos=None, widget=None, weight=0):
     951                  if None in (line, pos, widget):
     952                          _log.error('argument error in [%s]: line=%s, pos=%s, widget=%s' % (self.__class__.__name__, line, pos, widget))
     953                  if not self.fields.has_key(line):
     954                          self.fields[line] = {}
     955                  self.fields[line][pos] = (widget, weight)
     956          #----------------------------------------------------------------
     957 -        def _define_fields(self, parent):
     958                  """Defines the fields.
     959
     960                  - override in child classes
     961                  - mostly uses _add_field()
     962                  """
     963                  _log.error('missing override in [%s]' % self.__class__.__name__)
     964          #----------------------------------------------------------------
     965 -        def _define_prompts(self):
     966                  _log.error('missing override in [%s]' % self.__class__.__name__)
     967          #----------------------------------------------------------------
     968 -        def _make_standard_buttons(self, parent):
     969                  """Generates OK/CLEAR buttons for edit area."""
     970                  self.btn_OK = wx.Button(parent, ID_BTN_OK, _("OK"))
     971                  self.btn_OK.SetToolTipString(_('save entry into medical record'))
     972                  self.btn_Clear = wx.Button(parent, ID_BTN_CLEAR, _("Clear"))
     973                  self.btn_Clear.SetToolTipString(_('initialize input fields for new entry'))
     974
     975                  szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
     976                  szr_buttons.Add(self.btn_OK, 1, wx.EXPAND | wx.ALL, 1)
     977                  szr_buttons.Add(5, 0, 0)
     978                  szr_buttons.Add(self.btn_Clear, 1, wx.EXPAND | wx.ALL, 1)
     979
     980                  return szr_buttons
     981          #--------------------------------------------------------
     982 -        def _pre_save_data(self):
     983                  pass
     984          #--------------------------------------------------------
     985 -        def _save_data(self):
     986                  _log.error('[%s] programmer forgot to define _save_data()' % self.__class__.__name__)
     987                  _log.info('child classes of cEditArea *must* override this function')
     988                  return False
     989          #--------------------------------------------------------
     990          # event handling
     991          #--------------------------------------------------------
     992 -        def __register_events(self):
     993                  # connect standard buttons
     994                  wx.EVT_BUTTON(self.btn_OK, ID_BTN_OK, self._on_OK_btn_pressed)
     995                  wx.EVT_BUTTON(self.btn_Clear, ID_BTN_CLEAR, self._on_clear_btn_pressed)
     996
     997                  wx.EVT_SIZE (self.fields_pnl, self._on_resize_fields)
     998
     999                  # client internal signals
    1000                  gmDispatcher.connect(signal = u'pre_patient_selection', receiver = self._on_pre_patient_selection)
    1001                  gmDispatcher.connect(signal = u'application_closing', receiver = self._on_application_closing)
    1002                  gmDispatcher.connect(signal = u'post_patient_selection', receiver = self.on_post_patient_selection)
    1003
    1004                  return 1
    1005          #--------------------------------------------------------
    1006          # handlers
    1007          #--------------------------------------------------------
    1008 -        def _on_OK_btn_pressed(self, event):
    1009                  # FIXME: this try: except: block seems to large
    1010                  try:
    1011                          event.Skip()
    1012                          if self.data is None:
    1013                                  self._save_new_entry()
    1014                                  self.set_data()
    1015                          else:
    1016                                  self._save_modified_entry()
    1017                                  self.set_data()
    1018                  except gmExceptions.InvalidInputError, err:
    1019                          # nasty evil popup dialogue box
    1020                          # but for invalid input we want to interrupt user
    1021                          gmGuiHelpers.gm_show_error (err, _("Invalid Input"))
    1022                  except:
    1023                          _log.exception( "save data  problem in [%s]" % self.__class__.__name__)
    1024          #--------------------------------------------------------
    1025 -        def _on_clear_btn_pressed(self, event):
    1026                  # FIXME: check for unsaved data
    1027                  self.set_data()
    1028                  event.Skip()
    1029          #--------------------------------------------------------
    1030 -        def on_post_patient_selection( self, **kwds):
    1031                  # remember to use wxCallAfter()
    1032                  self.set_data()
    1033          #--------------------------------------------------------
    1034 -        def _on_application_closing(self, **kwds):
    1035                  # remember wxCallAfter
    1036                  if not self._patient.connected:
    1037                          return True
    1038                  if self._save_data():
    1039                          return True
    1040                  _log.error('[%s] lossage' % self.__class__.__name__)
    1041                  return False
    1042          #--------------------------------------------------------
    1043 -        def _on_pre_patient_selection(self, **kwds):
    1044                  # remember wxCallAfter
    1045                  if not self._patient.connected:
    1046                          return True
    1047                  if self._save_data():
    1048                          return True
    1049                  _log.error('[%s] lossage' % self.__class__.__name__)
    1050                  return False
    1051          #--------------------------------------------------------
    1052 -        def _on_resize_fields (self, event):
    1053                  self.fields_pnl.Layout()
    1054                  # resize the prompts accordingly
    1055                  for i in self.field_line_szr.keys():
    1056                          # query the BoxSizer to find where the field line is
    1057                          pos = self.field_line_szr[i].GetPosition()
    1058                          # and set the prompt lable to the same Y position
    1059                          self.prompt_widget[i].SetPosition((0, pos.y))
    1060  #====================================================================
    1061 -class gmEditArea(cEditArea):
    1062 -        def __init__(self, parent, id, aType = None):
    1063
    1064                  print "class [%s] is deprecated, use cEditArea2 instead" % self.__class__.__name__
    1065
    1066                  # sanity checks
    1067                  if aType not in _known_edit_area_types:
    1068                          _log.error('unknown edit area type: [%s]' % aType)
    1069                          raise gmExceptions.ConstructorError, 'unknown edit area type: [%s]' % aType
    1070                  self._type = aType
    1071
    1072                  # init main background panel
    1073                  cEditArea.__init__(self, parent, id)
    1074
    1075                  self.input_fields = {}
    1076
    1077                  self._postInit()
    1078                  self.old_data = {}
    1079
    1080                  self._patient = gmPerson.gmCurrentPatient()
    1081                  self.Show(True)
    1082          #----------------------------------------------------------------
    1083          # internal helpers
    1084          #----------------------------------------------------------------
    1085          #----------------------------------------------------------------
    1086          # to be obsoleted
    1087          #----------------------------------------------------------------
    1088 -        def __make_prompts(self, prompt_labels):
    1089                  # prompts live on a panel
    1090                  prompt_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
    1091                  prompt_pnl.SetBackgroundColour(richards_light_gray)
    1092                  # make them
    1093                  gszr = wx.FlexGridSizer (len(prompt_labels)+1, 1, 2, 2)
    1094                  color = richards_aqua
    1095                  for prompt in prompt_labels:
    1096                          label = self.__make_prompt(prompt_pnl, "%s " % prompt, color)
    1097                          gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT)
    1098                          color = richards_blue
    1099                          gszr.RemoveGrowableRow (line-1)
    1100                  # put sizer on panel
    1101                  prompt_pnl.SetSizer(gszr)
    1102                  gszr.Fit(prompt_pnl)
    1103                  prompt_pnl.SetAutoLayout(True)
    1104
    1105                  # make shadow below prompts in gray
    1106                  shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
    1107                  shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
    1108                  szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
    1109                  szr_shadow_below_prompts.Add(5, 0, 0, wx.EXPAND)
    1110                  szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
    1111
    1112                  # stack prompt panel and shadow vertically
    1113                  vszr_prompts = wx.BoxSizer(wx.VERTICAL)
    1114                  vszr_prompts.Add(prompt_pnl, 97, wx.EXPAND)
    1115                  vszr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
    1116
    1117                  # make shadow to the right of the prompts
    1118                  shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
    1119                  shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
    1120                  szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
    1121                  szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
    1122                  szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND)
    1123
    1124                  # stack vertical prompt sizer and shadow horizontally
    1125                  hszr_prompts = wx.BoxSizer(wx.HORIZONTAL)
    1126                  hszr_prompts.Add(vszr_prompts, 10, wx.EXPAND)
    1127                  hszr_prompts.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
    1128
    1129                  return hszr_prompts
    1130          #----------------------------------------------------------------
    1131 -        def _make_edit_lines(self, parent):
    1132                  _log.error('programmer forgot to define edit area lines for [%s]' % self._type)
    1133                  _log.info('child classes of gmEditArea *must* override this function')
    1134                  return []
    1135          #----------------------------------------------------------------
    1136 -        def __make_editing_area(self):
    1137                  # make edit fields
    1138                  fields_pnl = wx.Panel(self, -1, wx.DefaultPosition, wx.DefaultSize, style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
    1139                  fields_pnl.SetBackgroundColour(wx.Colour(222,222,222))
    1140                  # rows, cols, hgap, vgap
    1141                  gszr = wx.GridSizer(len(_prompt_defs[self._type]), 1, 2, 2)
    1142
    1143                  # get lines
    1144                  lines = self._make_edit_lines(parent = fields_pnl)
    1145
    1146                  self.lines = lines
    1147                  if len(lines) != len(_prompt_defs[self._type]):
    1148                          _log.error('#(edit lines) not equal #(prompts) for [%s], something is fishy' % self._type)
    1149                  for line in lines:
    1150                          gszr.Add(line, 0, wx.EXPAND | wx.ALIGN_LEFT)
    1151                  # put them on the panel
    1152                  fields_pnl.SetSizer(gszr)
    1153                  gszr.Fit(fields_pnl)
    1154                  fields_pnl.SetAutoLayout(True)
    1155
    1156                  # make shadow below edit fields in gray
    1157                  shadow_below_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
    1158                  shadow_below_edit_fields.SetBackgroundColour(richards_coloured_gray)
    1159                  szr_shadow_below_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
    1160                  szr_shadow_below_edit_fields.Add(5, 0, 0, wx.EXPAND)
    1161                  szr_shadow_below_edit_fields.Add(shadow_below_edit_fields, 12, wx.EXPAND)
    1162
    1163                  # stack edit fields and shadow vertically
    1164                  vszr_edit_fields = wx.BoxSizer(wx.VERTICAL)
    1165                  vszr_edit_fields.Add(fields_pnl, 92, wx.EXPAND)
    1166                  vszr_edit_fields.Add(szr_shadow_below_edit_fields, 5, wx.EXPAND)
    1167
    1168                  # make shadow to the right of the edit area
    1169                  shadow_rightof_edit_fields = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
    1170                  shadow_rightof_edit_fields.SetBackgroundColour(richards_coloured_gray)
    1171                  szr_shadow_rightof_edit_fields = wx.BoxSizer(wx.VERTICAL)
    1172                  szr_shadow_rightof_edit_fields.Add(0, 5, 0, wx.EXPAND)
    1173                  szr_shadow_rightof_edit_fields.Add(shadow_rightof_edit_fields, 1, wx.EXPAND)
    1174
    1175                  # stack vertical edit fields sizer and shadow horizontally
    1176                  hszr_edit_fields = wx.BoxSizer(wx.HORIZONTAL)
    1177                  hszr_edit_fields.Add(vszr_edit_fields, 89, wx.EXPAND)
    1178                  hszr_edit_fields.Add(szr_shadow_rightof_edit_fields, 1, wx.EXPAND)
    1179
    1180                  return hszr_edit_fields
    1181
    1182 -        def set_old_data( self, map):
    1183                  self.old_data = map
    1184
    1185 -        def _default_init_fields(self):
    1186                  #self.dirty = 0  #this flag is for patient_activating event to save any unsaved entries
    1187                  self.setInputFieldValues( self._get_init_values())
    1188                  self.data = None
    1189
    1190 -        def _get_init_values(self):
    1191                  map = {}
    1192                  for k in self.input_fields.keys():
    1193                          map[k] = ''
    1194                  return map
    1195
    1196          #--------------------------------------------------------
    1197 -        def _init_fields(self):
    1198                  self._default_init_fields()
    1199
    1200          #       _log.Log(gmLog.lErr, 'programmer forgot to define _init_fields() for [%s]' % self._type)
    1201          #       _log.Log(gmLog.lInfo, 'child classes of gmEditArea *must* override this function')
    1202          #       raise AttributeError
    1203  #-------------------------------------------------------------------------------------------------------------
    1204 -        def _updateUI(self):
    1205                  _log.warning("you may want to override _updateUI for [%s]" % self.__class__.__name__)
    1206
    1207
    1208 -        def _postInit(self):
    1209                  """override for further control setup"""
    1210                  pass
    1211
    1212
    1213 -        def _makeLineSizer(self,  widget, weight, spacerWeight):
    1214                  szr = wx.BoxSizer(wx.HORIZONTAL)
    1215                  szr.Add( widget, weight, wx.EXPAND)
    1216                  szr.Add( 0,0, spacerWeight, wx.EXPAND)
    1217                  return szr
    1218
    1219 -        def _makeCheckBox(self, parent, title):
    1220
    1221                  cb =  wx.CheckBox( parent, -1, _(title))
    1222                  cb.SetForegroundColour( richards_blue)
    1223                  return cb
    1224
    1225
    1226
    1227 -        def _makeExtraColumns(self , parent, lines, weightMap = {} ):
    1228                  """this is a utlity method to add extra columns"""
    1229                  #add an extra column if the class has attribute "extraColumns"
    1230                  if self.__class__.__dict__.has_key("extraColumns"):
    1231                          for x in self.__class__.extraColumns:
    1232                                  lines = self._addColumn(parent, lines, x, weightMap)
    1233                  return lines
    1234
    1235
    1236
    1237 -        def _addColumn(self, parent, lines, extra, weightMap = {}, existingWeight = 5 , extraWeight = 2):
    1238                  """
    1239                  # add ia extra column in the edit area.
    1240                  # preconditions:
    1241                  #       parent is fields_pnl (weak);
    1242                  #       self.input_fields exists (required);
    1243                  #       ; extra is a list  of tuples of  format -
    1244                          # (     key for input_fields, widget label , widget class to instantiate )
    1245                  """
    1246
    1247                  newlines = []
    1248                  i = 0
    1249                  for x in lines:
    1250                          # adjust weight if line has specific weightings.
    1251                          if weightMap.has_key( x):
    1252                                  (existingWeight, extraWeight) = weightMap[x]
    1253
    1254                          szr = wx.BoxSizer(wx.HORIZONTAL)
    1255                          szr.Add( x, existingWeight, wx.EXPAND)
    1256                          if i < len(extra) and  extra[i] <> None:
    1257
    1258                                  (inputKey, widgetLabel, aclass) = extra[i]
    1259                                  if aclass.__name__ in CONTROLS_WITHOUT_LABELS:
    1260                                          szr.Add( self._make_prompt(parent,  widgetLabel, richards_blue)  )
    1261                                          widgetLabel = ""
    1262
    1263
    1264                                  w = aclass( parent, -1, widgetLabel)
    1265                                  if not aclass.__name__ in CONTROLS_WITHOUT_LABELS:
    1266                                          w.SetForegroundColour(richards_blue)
    1267
    1268                                  szr.Add(w, extraWeight , wx.EXPAND)
    1269
    1270                                  # make sure the widget is locatable via input_fields
    1271                                  self.input_fields[inputKey] = w
    1272
    1273                          newlines.append(szr)
    1274                          i += 1
    1275                  return newlines
    1276
    1277 -        def setInputFieldValues(self, map, id = None ):
    1278                  #self.monitoring_dirty = 0
    1279                  for k,v in map.items():
    1280                          field = self.input_fields.get(k, None)
    1281                          if field == None:
    1282                                  continue
    1283                          try:
    1284                                  field.SetValue( str(v) )
    1285                          except:
    1286                                  try:
    1287                                          if type(v) == type(''):
    1288                                                  v = 0
    1289
    1290                                          field.SetValue( v)
    1291                                  except:
    1292                                          pass
    1293                  self.setDataId(id)
    1294                  #self.monitoring_dirty = 1
    1295                  self.set_old_data(self.getInputFieldValues())
    1296
    1297 -        def getDataId(self):
    1298                  return self.data
    1299
    1300 -        def setDataId(self, id):
    1301                  self.data = id
    1302
    1303 -        def _getInputFieldValues(self):
    1304                  values = {}
    1305                  for k,v  in self.input_fields.items():
    1306                          values[k] = v.GetValue()
    1307                  return values
    1308
    1309 -        def getInputFieldValues(self, fields = None):
    1310                  if fields == None:
    1311                          fields = self.input_fields.keys()
    1312                  values = {}
    1313                  for f in fields:
    1314                          try:
    1315                                  values[f] = self.input_fields[f].GetValue()
    1316                          except:
    1317                                  pass
    1318                  return values
    1319  #====================================================================
    1320 -class gmFamilyHxEditArea(gmEditArea):
    1321 -        def __init__(self, parent, id):
    1322                  try:
    1323                          gmEditArea.__init__(self, parent, id, aType = 'family history')
    1324                  except gmExceptions.ConstructorError:
    1325                          _log.exceptions('cannot instantiate family Hx edit area')
    1326                          raise
    1327          #----------------------------------------------------------------
    1328 -        def _make_edit_lines(self, parent):
    1329                  _log.debug("making family Hx lines")
    1330                  lines = []
    1331                  self.input_fields = {}
    1332                  # line 1
    1333                  # FIXME: put patient search widget here, too ...
    1334                  # add button "make active patient"
    1335                  self.input_fields['name'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
    1336                  self.input_fields['DOB'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
    1337                  lbl_dob = self._make_prompt(parent, _(" Date of Birth "), richards_blue)
    1338                  szr = wx.BoxSizer(wx.HORIZONTAL)
    1339                  szr.Add(self.input_fields['name'], 4, wx.EXPAND)
    1340                  szr.Add(lbl_dob, 2, wx.EXPAND)
    1341                  szr.Add(self.input_fields['DOB'], 4, wx.EXPAND)
    1342                  lines.append(szr)
    1343                  # line 2
    1344                  # FIXME: keep relationship attachments permamently ! (may need to make new patient ...)
    1345                  # FIXME: learning phrasewheel attached to list loaded from backend
    1346                  self.input_fields['relationship'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
    1347                  szr = wx.BoxSizer(wx.HORIZONTAL)
    1348                  szr.Add(self.input_fields['relationship'], 4, wx.EXPAND)
    1349                  lines.append(szr)
    1350                  # line 3
    1351                  self.input_fields['condition'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
    1352                  self.cb_condition_confidential = wx.CheckBox(parent, -1, _("confidental"), wx.DefaultPosition, wx.DefaultSize, wx.NO_BORDER)
    1353                  szr = wx.BoxSizer(wx.HORIZONTAL)
    1354                  szr.Add(self.input_fields['condition'], 6, wx.EXPAND)
    1355                  szr.Add(self.cb_condition_confidential, 0, wx.EXPAND)
    1356                  lines.append(szr)
    1357                  # line 4
    1358                  self.input_fields['comment'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
    1359                  lines.append(self.input_fields['comment'])
    1360                  # line 5
    1361                  lbl_onset = self._make_prompt(parent, _(" age onset "), richards_blue)
    1362                  self.input_fields['age onset'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
    1363                  #    FIXME: combo box ...
    1364                  lbl_caused_death = self._make_prompt(parent, _(" caused death "), richards_blue)
    1365                  self.input_fields['caused death'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
    1366                  lbl_aod = self._make_prompt(parent, _(" age died "), richards_blue)
    1367                  self.input_fields['AOD'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
    1368                  szr = wx.BoxSizer(wx.HORIZONTAL)
    1369                  szr.Add(lbl_onset, 0, wx.EXPAND)
    1370                  szr.Add(self.input_fields['age onset'], 1,wx.EXPAND)
    1371                  szr.Add(lbl_caused_death, 0, wx.EXPAND)
    1372                  szr.Add(self.input_fields['caused death'], 2,wx.EXPAND)
    1373                  szr.Add(lbl_aod, 0, wx.EXPAND)
    1374                  szr.Add(self.input_fields['AOD'], 1, wx.EXPAND)
    1375                  szr.Add(2, 2, 8)
    1376                  lines.append(szr)
    1377                  # line 6
    1378                  self.input_fields['progress notes'] = cEditAreaField(parent, -1, wx.DefaultPosition, wx.DefaultSize)
    1379                  lines.append(self.input_fields['progress notes'])
    1380                  # line 8
    1381                  self.Btn_next_condition = wx.Button(parent, -1, _("Next Condition"))
    1382                  szr = wx.BoxSizer(wx.HORIZONTAL)
    1383                  szr.AddSpacer(10, 0, 0)
    1384                  szr.Add(self.Btn_next_condition, 0, wx.EXPAND | wx.ALL, 1)
    1385                  szr.Add(2, 1, 5)
    1386                  szr.Add(self._make_standard_buttons(parent), 0, wx.EXPAND)
    1387                  lines.append(szr)
    1388
    1389                  return lines
    1390
    1391 -        def _save_data(self):
    1392                  return 1
    1393
    1394  #====================================================================
    1395 -class gmPastHistoryEditArea(gmEditArea):
    1396
    1397 -        def __init__(self, parent, id):
    1398                  gmEditArea.__init__(self, parent, id, aType = 'past history')
    1399
    1400 -        def _define_prompts(self):
    1401                  self._add_prompt(line = 1, label = _("When Noted"))
    1402                  self._add_prompt(line = 2, label = _("Laterality"))
    1403                  self._add_prompt(line = 3, label = _("Condition"))
    1404                  self._add_prompt(line = 4, label = _("Notes"))
    1405                  self._add_prompt(line = 6, label = _("Status"))
    1406                  self._add_prompt(line = 7, label = _("Progress Note"))
    1407                  self._add_prompt(line = 8, label = '')
    1408          #--------------------------------------------------------
    1409 -        def _define_fields(self, parent):
    1410                  # line 1
    1411                  self.fld_date_noted = gmDateTimeInput.gmDateInput(
    1412                          parent = parent,
    1413                          id = -1,
    1414                          style = wx.SIMPLE_BORDER
    1415                  )
    1416                  self._add_field(
    1417                          line = 1,
    1418                          pos = 1,
    1419                          widget = self.fld_date_noted,
    1420                          weight = 2
    1421                  )
    1422                  self._add_field(
    1423                          line = 1,
    1424                          pos = 2,
    1425                          widget = cPrompt_edit_area(parent,-1, _("Age")),
    1426                          weight = 0)
    1427
    1428                  self.fld_age_noted = cEditAreaField(parent)
    1429                  self._add_field(
    1430                          line = 1,
    1431                          pos = 3,
    1432                          widget = self.fld_age_noted,
    1433                          weight = 2
    1434                  )
    1435
    1436                  # line 2
    1437                  self.fld_laterality_none= wx.RadioButton(parent, -1, _("N/A"))
    1438                  self.fld_laterality_left= wx.RadioButton(parent, -1, _("L"))
    1439                  self.fld_laterality_right= wx.RadioButton(parent, -1, _("R"))
    1440                  self.fld_laterality_both= wx.RadioButton(parent, -1, _("both"))
    1441                  self._add_field(
    1442                          line = 2,
    1443                          pos = 1,
    1444                          widget = self.fld_laterality_none,
    1445                          weight = 0
    1446                  )
    1447                  self._add_field(
    1448                          line = 2,
    1449                          pos = 2,
    1450                          widget = self.fld_laterality_left,
    1451                          weight = 0
    1452                  )
    1453                  self._add_field(
    1454                          line = 2,
    1455                          pos = 3,
    1456                          widget = self.fld_laterality_right,
    1457                          weight = 1
    1458                  )
    1459                  self._add_field(
    1460                          line = 2,
    1461                          pos = 4,
    1462                          widget = self.fld_laterality_both,
    1463                          weight = 1
    1464                  )
    1465                  # line 3
    1466                  self.fld_condition= cEditAreaField(parent)
    1467                  self._add_field(
    1468                          line = 3,
    1469                          pos = 1,
    1470                          widget = self.fld_condition,
    1471                          weight = 6
    1472                  )
    1473                  # line 4
    1474                  self.fld_notes= cEditAreaField(parent)
    1475                  self._add_field(
    1476                          line = 4,
    1477                          pos = 1,
    1478                          widget = self.fld_notes,
    1479                          weight = 6
    1480                  )
    1481                  # line 5
    1482                  self.fld_significant= wx.CheckBox(
    1483                          parent,
    1484                          -1,
    1485                          _("significant"),
    1486                          style = wx.NO_BORDER
    1487                  )
    1488                  self.fld_active= wx.CheckBox(
    1489                          parent,
    1490                          -1,
    1491                          _("active"),
    1492                          style = wx.NO_BORDER
    1493                  )
    1494
    1495                  self._add_field(
    1496                          line = 5,
    1497                          pos = 1,
    1498                          widget = self.fld_significant,
    1499                          weight = 0
    1500                  )
    1501                  self._add_field(
    1502                          line = 5,
    1503                          pos = 2,
    1504                          widget = self.fld_active,
    1505                          weight = 0
    1506                  )
    1507                  #line 6
    1508                  self.fld_progress= cEditAreaField(parent)
    1509                  self._add_field(
    1510                          line = 6,
    1511                          pos = 1,
    1512                          widget = self.fld_progress,
    1513                          weight = 6
    1514                  )
    1515
    1516                  #line 7
    1517                  self._add_field(
    1518                          line = 7,
    1519                          pos = 4,
    1520                          widget = self._make_standard_buttons(parent),
    1521                          weight = 2
    1522                  )
    1523          #--------------------------------------------------------
    1524 -        def  _postInit(self):
    1525                  return
    1526                  #handling of auto age or year filling.
    1527                  wx.EVT_KILL_FOCUS( self.fld_age_noted, self._ageKillFocus)
    1528                  wx.EVT_KILL_FOCUS( self.fld_date_noted, self._yearKillFocus)
    1529          #--------------------------------------------------------
    1530 -        def _ageKillFocus( self, event):
    1531                  # skip first, else later failure later in block causes widget to be unfocusable
    1532                  event.Skip()
    1533                  try :
    1534                          year = self._getBirthYear() + int(self.fld_age_noted.GetValue().strip() )
    1535                          self.fld_date_noted.SetValue( str (year) )
    1536                  except:
    1537                          pass
    1538
    1539 -        def _getBirthYear(self):
    1540                  try:
    1541                          birthyear = int(str(self._patient['dob']).split('-')[0])
    1542                  except:
    1543  #                       birthyear = time.localtime()[0]
    1544                          birthyear = 1
    1545
    1546                  return birthyear
    1547
    1548 -        def _yearKillFocus( self, event):
    1549                  event.Skip()
    1550                  try:
    1551                          age = int(self.fld_date_noted.GetValue().strip() ) - self._getBirthYear()
    1552                          self.fld_age_noted.SetValue( str (age) )
    1553                  except:
    1554                          pass
    1555
    1556          __init_values = {
    1557                          "condition": "",
    1558                          "notes1": "",
    1559                          "notes2": "",
    1560                          "age": "",
    1561                          #"year": str(time.localtime()[0]),
    1562                          "progress": "",
    1563                          "active": 1,
    1564                          "operation": 0,
    1565                          "confidential": 0,
    1566                          "significant": 1,
    1567                          "both": 0,
    1568                          "left": 0,
    1569                          "right": 0,
    1570                          "none" : 1
    1571                          }
    1572
    1573 -        def _getDefaultAge(self):
    1574                  try:
    1575                          #return time.localtime()[0] - self._patient.getBirthYear()
    1576                          return 1
    1577                  except:
    1578                          return 0
    1579
    1580 -        def _get_init_values(self):
    1581                  values = gmPastHistoryEditArea.__init_values
    1582                  values["age"] = str( self._getDefaultAge())
    1583                  return values
    1584
    1585 -        def _save_data(self):
    1586                  clinical = self._patient.get_emr().get_past_history()
    1587                  if self.getDataId() is None:
    1588                          id = clinical.create_history( self.get_fields_formatting_values() )
    1589                          self.setDataId(id)
    1590                          return
    1591
    1592                  clinical.update_history( self.get_fields_formatting_values(), self.getDataId() )
    1593
    1594  #====================================================================
    1595 -class gmReferralEditArea(gmEditArea):
    1596
    1597 -        def __init__(self, parent, id):
    1598                  try:
    1599                          gmEditArea.__init__(self, parent, id, aType = 'referral')
    1600                  except gmExceptions.ConstructorError:
    1601                          _log.exception('cannot instantiate referral edit area')
    1602                  self.data = None # we don't use this in this widget
    1603                  self.recipient = None
    1604
    1605 -        def _define_prompts(self):
    1606                  self._add_prompt (line = 1, label = _ ("Specialty"))
    1607                  self._add_prompt (line = 2, label = _ ("Name"))
    1608                  self._add_prompt (line = 3, label = _ ("Address"))
    1609                  self._add_prompt (line = 4, label = _ ("Options"))
    1610                  self._add_prompt (line = 5, label = _("Text"), weight =6)
    1611                  self._add_prompt (line = 6, label = "")
    1612
    1613 -        def _define_fields (self, parent):
    1614                  self.fld_specialty = gmPhraseWheel.cPhraseWheel (
    1615                          parent = parent,
    1616                          id = -1,
    1617                          style = wx.SIMPLE_BORDER
    1618                          )
    1619                  #_decorate_editarea_field (self.fld_specialty)
    1620                  self._add_field (
    1621                          line = 1,
    1622                          pos = 1,
    1623                          widget = self.fld_specialty,
    1624                          weight = 1
    1625                          )
    1626                  self.fld_name = gmPhraseWheel.cPhraseWheel (
    1627                          parent = parent,
    1628                          id = -1,
    1629                          style = wx.SIMPLE_BORDER
    1630                          )
    1631                  #_decorate_editarea_field (self.fld_name)
    1632                  self._add_field (
    1633                          line = 2,
    1634                          pos = 1,
    1635                          widget = self.fld_name,
    1636                          weight = 1
    1637                          )
    1638                  self.fld_address = wx.ComboBox (parent, -1, style = wx.CB_READONLY)
    1639                  #_decorate_editarea_field (self.fld_address)
    1640                  self._add_field (
    1641                          line = 3,
    1642                          pos = 1,
    1643                          widget = self.fld_address,
    1644                          weight = 1
    1645                          )
    1646                  # FIXME: replace with set_callback_on_*
    1647  #               self.fld_specialty.setDependent (self.fld_name, "occupation")
    1648                  self.fld_name.add_callback_on_selection(self.setAddresses)
    1649                  # flags line
    1650                  self.fld_med = wx.CheckBox (parent, -1, _("Meds"), style=wx.NO_BORDER)
    1651                  self._add_field (
    1652                          line = 4,
    1653                          pos = 1,
    1654                          widget = self.fld_med,
    1655                          weight = 1
    1656                          )
    1657                  self.fld_past = wx.CheckBox (parent, -1, _("Past Hx"), style=wx.NO_BORDER)
    1658                  self._add_field (
    1659                          line = 4,
    1660                          pos = 4,
    1661                          widget = self.fld_past,
    1662                          weight = 1
    1663                          )
    1664                  self.fld_text = wx.TextCtrl (parent, -1, style= wx.TE_MULTILINE)
    1665                  self._add_field (
    1666                          line = 5,
    1667                          pos = 1,
    1668                          widget = self.fld_text,
    1669                          weight = 1)
    1670                  # final line
    1671                  self._add_field(
    1672                          line = 6,
    1673                          pos = 1,
    1674                          widget = self._make_standard_buttons(parent),
    1675                          weight = 1
    1676                  )
    1677                  return 1
    1678
    1679 -        def set_data (self):
    1680                  """
    1681                  Doesn't accept any value as this doesn't make sense for this edit area
    1682                  """
    1683                  self.fld_specialty.SetValue ('')
    1684                  self.fld_name.SetValue ('')
    1685                  self.fld_address.Clear ()
    1686                  self.fld_address.SetValue ('')
    1687                  self.fld_med.SetValue (0)
    1688                  self.fld_past.SetValue (0)
    1689                  self.fld_text.SetValue ('')
    1690                  self.recipient = None
    1691
    1692 -        def setAddresses (self, id):
    1693                  """
    1694                  Set the available addresses for the selected identity
    1695                  """
    1696                  if id is None:
    1697                          self.recipient = None
    1698                          self.fld_address.Clear ()
    1699                          self.fld_address.SetValue ('')
    1700                  else:
    1701                          self.recipient = gmDemographicRecord.cDemographicRecord_SQL (id)
    1702                          self.fld_address.Clear ()
    1703                          self.addr = self.recipient.getAddresses ('work')
    1704                          for i in self.addr:
    1705                                  self.fld_address.Append (_("%(number)s %(street)s, %(urb)s %(postcode)s") % i, ('post', i))
    1706                          fax = self.recipient.getCommChannel (gmDemographicRecord.FAX)
    1707                          email  = self.recipient.getCommChannel (gmDemographicRecord.EMAIL)
    1708                          if fax:
    1709                                  self.fld_address.Append ("%s: %s" % (_("FAX"), fax), ('fax', fax))
    1710                          if email:
    1711                                  self.fld_address.Append ("%s: %s" % (_("E-MAIL"), email), ('email', email))
    1712
    1713 -        def _save_new_entry(self):
    1714                  """
    1715                  We are always saving a "new entry" here because data_ID is always None
    1716                  """
    1717                  if not self.recipient:
    1718                          raise gmExceptions.InvalidInputError(_('must have a recipient'))
    1719                  if self.fld_address.GetSelection() == -1:
    1720                          raise gmExceptions.InvalidInputError(_('must select address'))
    1721                  channel, addr = self.fld_address.GetClientData (self.fld_address.GetSelection())
    1722                  text = self.fld_text.GetValue()
    1723                  flags = {}
    1724                  flags['meds'] = self.fld_med.GetValue()
    1725                  flags['pasthx'] = self.fld_past.GetValue()
    1726                  if not gmReferral.create_referral (self._patient, self.recipient, channel, addr, text, flags):
    1727                          raise gmExceptions.InvalidInputError('error sending form')
    1728
    1729  #====================================================================
    1730  #====================================================================
    1731  # unconverted edit areas below
    1732  #====================================================================
    1733 -class gmPrescriptionEditArea(gmEditArea):
    1734 -        def __init__(self, parent, id):
    1735                  try:
    1736                          gmEditArea.__init__(self, parent, id, aType = 'prescription')
    1737                  except gmExceptions.ConstructorError:
    1738                          _log.exceptions('cannot instantiate prescription edit area')
    1739                          raise
    1740
    1741
    1742          #----------------------------------------------------------------
    1743 -        def _make_edit_lines(self, parent):
    1744                  _log.debug("making prescription lines")
    1745                  lines = []
    1746                  self.txt_problem = cEditAreaField(parent)
    1747                  self.txt_class = cEditAreaField(parent)
    1748                  self.txt_generic = cEditAreaField(parent)
    1749                  self.txt_brand = cEditAreaField(parent)
    1750                  self.txt_strength= cEditAreaField(parent)
    1751                  self.txt_directions= cEditAreaField(parent)
    1752                  self.txt_for = cEditAreaField(parent)
    1753                  self.txt_progress = cEditAreaField(parent)
    1754
    1755                  lines.append(self.txt_problem)
    1756                  lines.append(self.txt_class)
    1757                  lines.append(self.txt_generic)
    1758                  lines.append(self.txt_brand)
    1759                  lines.append(self.txt_strength)
    1760                  lines.append(self.txt_directions)
    1761                  lines.append(self.txt_for)
    1762                  lines.append(self.txt_progress)
    1763                  lines.append(self._make_standard_buttons(parent))
    1764                  self.input_fields = {
    1765                          "problem": self.txt_problem,
    1766                          "class" : self.txt_class,
    1767                          "generic" : self.txt_generic,
    1768                          "brand" : self.txt_brand,
    1769                          "strength": self.txt_strength,
    1770                          "directions": self.txt_directions,
    1771                          "for" : self.txt_for,
    1772                          "progress": self.txt_progress
    1773
    1774                  }
    1775
    1776                  return self._makeExtraColumns( parent, lines)
    1777
    1778
    1779  # This makes gmPrescriptionEditArea more adaptable to different nationalities special requirements.
    1780  # ( well, it could be.)
    1781  # to change at runtime, do
    1782
    1783  #             gmPrescriptionEditArea.extraColumns  = [ one or more columnListInfo ]
    1784
    1785  #    each columnListInfo  element describes one column,
    1786  #    where columnListInfo is    a  list of
    1787  #               tuples of       [ inputMap name,  widget label, widget class to instantiate from]
    1788
    1789  #gmPrescriptionEditArea.extraColumns = [  basicPrescriptionExtra ]
    1790  #gmPrescriptionEditArea.extraColumns = [  auPrescriptionExtra ]
    1791
    1792
    1793 -        def _save_data(self):
    1794                  return 1
    1795
    1796  #====================================================================
    1797  # old style stuff below
    1798  #====================================================================
    1799  #Class which shows a blue bold label left justified
    1800  #--------------------------------------------------------------------
    1801 -class cPrompt_edit_area(wx.StaticText):
    1802 -        def __init__(self, parent, id, prompt, aColor = richards_blue):
    1803                  wx.StaticText.__init__(self, parent, id, prompt, wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_LEFT)
    1804                  self.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD, False, ''))
    1805                  self.SetForegroundColour(aColor)
    1806  #====================================================================
    1807  # create the editorprompts class which expects a dictionary of labels
    1808  # passed to it with prompts relevant to the editing area.
    1809  # remove the if else from this once the edit area labelling is fixed
    1810  #--------------------------------------------------------------------
    1811 -class gmPnlEditAreaPrompts(wx.Panel):
    1812 -        def __init__(self, parent, id, prompt_labels):
    1813                  wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, wx.SIMPLE_BORDER)
    1814                  self.SetBackgroundColour(richards_light_gray)
    1815                  gszr = wx.GridSizer (len(prompt_labels)+1, 1, 2, 2)
    1816                  color = richards_aqua
    1817                  for prompt_key in prompt_labels.keys():
    1818                          label = cPrompt_edit_area(self, -1, " %s" % prompt_labels[prompt_key], aColor = color)
    1819                          gszr.Add(label, 0, wx.EXPAND | wx.ALIGN_RIGHT)
    1820                          color = richards_blue
    1821                  self.SetSizer(gszr)
    1822                  gszr.Fit(self)
    1823                  self.SetAutoLayout(True)
    1824  #====================================================================
    1825  #Class central to gnumed data input
    1826  #allows data entry of multiple different types.e.g scripts,
    1827  #referrals, measurements, recalls etc
    1828  #@TODO : just about everything
    1829  #section = calling section eg allergies, script
    1830  #----------------------------------------------------------
    1831 -class EditTextBoxes(wx.Panel):
    1832 -        def __init__(self, parent, id, editareaprompts, section):
    1833                  wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize,style = wx.RAISED_BORDER | wx.TAB_TRAVERSAL)
    1834                  self.SetBackgroundColour(wx.Colour(222,222,222))
    1835                  self.parent = parent
    1836                  # rows, cols, hgap, vgap
    1837                  self.gszr = wx.GridSizer(len(editareaprompts), 1, 2, 2)
    1838
    1839                  if section == gmSECTION_SUMMARY:
    1840                          pass
    1841                  elif section == gmSECTION_DEMOGRAPHICS:
    1842                          pass
    1843                  elif section == gmSECTION_CLINICALNOTES:
    1844                          pass
    1845                  elif section == gmSECTION_FAMILYHISTORY:
    1846                          pass
    1847                  elif section == gmSECTION_PASTHISTORY:
    1848                          pass
    1849                          # line 1
    1850
    1851                          self.txt_condition = cEditAreaField(self,PHX_CONDITION,wx.DefaultPosition,wx.DefaultSize)
    1852                          self.rb_sideleft = wxRadioButton(self,PHX_LEFT, _(" (L) "), wx.DefaultPosition,wx.DefaultSize)
    1853                          self.rb_sideright = wxRadioButton(self, PHX_RIGHT, _("(R)"), wx.DefaultPosition,wx.DefaultSize,wx.SUNKEN_BORDER)
    1854                          self.rb_sideboth = wxRadioButton(self, PHX_BOTH, _("Both"), wx.DefaultPosition,wx.DefaultSize)
    1855                          rbsizer = wx.BoxSizer(wx.HORIZONTAL)
    1856                          rbsizer.Add(self.rb_sideleft,1,wx.EXPAND)
    1857                          rbsizer.Add(self.rb_sideright,1,wx.EXPAND)
    1858                          rbsizer.Add(self.rb_sideboth,1,wx.EXPAND)
    1859                          szr1 = wx.BoxSizer(wx.HORIZONTAL)
    1860                          szr1.Add(self.txt_condition, 4, wx.EXPAND)
    1861                          szr1.Add(rbsizer, 3, wx.EXPAND)
    1862  #                       self.sizer_line1.Add(self.rb_sideleft,1,wx.EXPAND|wxALL,2)
    1863  #                       self.sizer_line1.Add(self.rb_sideright,1,wx.EXPAND|wxALL,2)
    1864  #                       self.sizer_line1.Add(self.rb_sideboth,1,wx.EXPAND|wxALL,2)
    1865                          # line 2
    1866                          self.txt_notes1 = cEditAreaField(self,PHX_NOTES,wx.DefaultPosition,wx.DefaultSize)
    1867                          # line 3
    1868                          self.txt_notes2= cEditAreaField(self,PHX_NOTES2,wx.DefaultPosition,wx.DefaultSize)
    1869                          # line 4
    1870                          self.txt_agenoted = cEditAreaField(self, PHX_AGE, wx.DefaultPosition, wx.DefaultSize)
    1871                          szr4 = wx.BoxSizer(wx.HORIZONTAL)
    1872                          szr4.Add(self.txt_agenoted, 1, wx.EXPAND)
    1873                          szr4.Add(5, 0, 5)
    1874                          # line 5
    1875                          self.txt_yearnoted  = cEditAreaField(self,PHX_YEAR,wx.DefaultPosition,wx.DefaultSize)
    1876                          szr5 = wx.BoxSizer(wx.HORIZONTAL)
    1877                          szr5.Add(self.txt_yearnoted, 1, wx.EXPAND)
    1878                          szr5.Add(5, 0, 5)
    1879                          # line 6
    1880                          self.parent.cb_active = wx.CheckBox(self, PHX_ACTIVE, _("Active"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    1881                          self.parent.cb_operation = wx.CheckBox(self, PHX_OPERATION, _("Operation"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    1882                          self.parent.cb_confidential = wx.CheckBox(self, PHX_CONFIDENTIAL , _("Confidential"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    1883                          self.parent.cb_significant = wx.CheckBox(self, PHX_SIGNIFICANT, _("Significant"), wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    1884                          szr6 = wx.BoxSizer(wx.HORIZONTAL)
    1885                          szr6.Add(self.parent.cb_active, 1, wx.EXPAND)
    1886                          szr6.Add(self.parent.cb_operation, 1, wx.EXPAND)
    1887                          szr6.Add(self.parent.cb_confidential, 1, wx.EXPAND)
    1888                          szr6.Add(self.parent.cb_significant, 1, wx.EXPAND)
    1889                          # line 7
    1890                          self.txt_progressnotes  = cEditAreaField(self,PHX_PROGRESSNOTES ,wx.DefaultPosition,wx.DefaultSize)
    1891                          # line 8
    1892                          szr8 = wx.BoxSizer(wx.HORIZONTAL)
    1893                          szr8.Add(5, 0, 6)
    1894                          szr8.Add(self._make_standard_buttons(), 0, wx.EXPAND)
    1895
    1896                          self.gszr.Add(szr1,0,wx.EXPAND)
    1897                          self.gszr.Add(self.txt_notes1,0,wx.EXPAND)
    1898                          self.gszr.Add(self.txt_notes2,0,wx.EXPAND)
    1899                          self.gszr.Add(szr4,0,wx.EXPAND)
    1900                          self.gszr.Add(szr5,0,wx.EXPAND)
    1901                          self.gszr.Add(szr6,0,wx.EXPAND)
    1902                          self.gszr.Add(self.txt_progressnotes,0,wx.EXPAND)
    1903                          self.gszr.Add(szr8,0,wx.EXPAND)
    1904                          #self.anylist = wx.ListCtrl(self, -1,  wx.DefaultPosition,wx.DefaultSize,wx.LC_REPORT|wx.LC_LIST|wx.SUNKEN_BORDER)
    1905
    1906                  elif section == gmSECTION_SCRIPT:
    1907                          pass
    1908                  elif section == gmSECTION_REQUESTS:
    1909                          pass
    1910                  elif section == gmSECTION_RECALLS:
    1911                          pass
    1912                  else:
    1913                          pass
    1914
    1915                  self.SetSizer(self.gszr)
    1916                  self.gszr.Fit(self)
    1917
    1918                  self.SetAutoLayout(True)
    1919                  self.Show(True)
    1920          #----------------------------------------------------------------
    1921 -        def _make_standard_buttons(self):
    1922                  self.btn_OK = wx.Button(self, -1, _("Ok"))
    1923                  self.btn_Clear = wx.Button(self, -1, _("Clear"))
    1924                  szr_buttons = wx.BoxSizer(wx.HORIZONTAL)
    1925                  szr_buttons.Add(self.btn_OK, 1, wx.EXPAND, wx.ALL, 1)
    1926                  szr_buttons.Add(5, 0, 0)
    1927                  szr_buttons.Add(self.btn_Clear, 1, wx.EXPAND, wx.ALL, 1)
    1928                  return szr_buttons
    1929  #====================================================================
    1930 -class EditArea(wx.Panel):
    1931 -        def __init__(self, parent, id, line_labels, section):
    1932                  _log.warning('***** old style EditArea instantiated, please convert *****')
    1933
    1934                  wx.Panel.__init__(self, parent, id, wx.DefaultPosition, wx.DefaultSize, style = wx.NO_BORDER)
    1935                  self.SetBackgroundColour(wx.Colour(222,222,222))
    1936
    1937                  # make prompts
    1938                  prompts = gmPnlEditAreaPrompts(self, -1, line_labels)
    1939                  # and shadow below prompts in ...
    1940                  shadow_below_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
    1941                  # ... gray
    1942                  shadow_below_prompts.SetBackgroundColour(richards_dark_gray)
    1943                  szr_shadow_below_prompts = wx.BoxSizer (wx.HORIZONTAL)
    1944                  szr_shadow_below_prompts.Add(5,0,0,wx.EXPAND)
    1945                  szr_shadow_below_prompts.Add(shadow_below_prompts, 10, wx.EXPAND)
    1946                  # stack prompts and shadow vertically
    1947                  szr_prompts = wx.BoxSizer(wx.VERTICAL)
    1948                  szr_prompts.Add(prompts, 97, wx.EXPAND)
    1949                  szr_prompts.Add(szr_shadow_below_prompts, 5, wx.EXPAND)
    1950
    1951                  # make edit fields
    1952                  edit_fields = EditTextBoxes(self, -1, line_labels, section)
    1953                  # make shadow below edit area ...
    1954                  shadow_below_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
    1955                  # ... gray
    1956                  shadow_below_editarea.SetBackgroundColour(richards_coloured_gray)
    1957                  szr_shadow_below_editarea = wx.BoxSizer(wx.HORIZONTAL)
    1958                  szr_shadow_below_editarea.Add(5,0,0,wx.EXPAND)
    1959                  szr_shadow_below_editarea.Add(shadow_below_editarea, 12, wx.EXPAND)
    1960                  # stack edit fields and shadow vertically
    1961                  szr_editarea = wx.BoxSizer(wx.VERTICAL)
    1962                  szr_editarea.Add(edit_fields, 92, wx.EXPAND)
    1963                  szr_editarea.Add(szr_shadow_below_editarea, 5, wx.EXPAND)
    1964
    1965                  # make shadows to the right of ...
    1966                  # ... the prompts ...
    1967                  shadow_rightof_prompts = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
    1968                  shadow_rightof_prompts.SetBackgroundColour(richards_dark_gray)
    1969                  szr_shadow_rightof_prompts = wx.BoxSizer(wx.VERTICAL)
    1970                  szr_shadow_rightof_prompts.Add(0,5,0,wx.EXPAND)
    1971                  szr_shadow_rightof_prompts.Add(shadow_rightof_prompts,1,wx.EXPAND)
    1972                  # ... and the edit area
    1973                  shadow_rightof_editarea = wxWindow(self, -1, wx.DefaultPosition, wx.DefaultSize, 0)
    1974                  shadow_rightof_editarea.SetBackgroundColour(richards_coloured_gray)
    1975                  szr_shadow_rightof_editarea = wx.BoxSizer(wx.VERTICAL)
    1976                  szr_shadow_rightof_editarea.Add(0, 5, 0, wx.EXPAND)
    1977                  szr_shadow_rightof_editarea.Add(shadow_rightof_editarea, 1, wx.EXPAND)
    1978
    1979                  # stack prompts, shadows and fields horizontally
    1980                  self.szr_main_panels = wx.BoxSizer(wx.HORIZONTAL)
    1981                  self.szr_main_panels.Add(szr_prompts, 10, wx.EXPAND)
    1982                  self.szr_main_panels.Add(szr_shadow_rightof_prompts, 1, wx.EXPAND)
    1983                  self.szr_main_panels.Add(5, 0, 0, wx.EXPAND)
    1984                  self.szr_main_panels.Add(szr_editarea, 89, wx.EXPAND)
    1985                  self.szr_main_panels.Add(szr_shadow_rightof_editarea, 1, wx.EXPAND)
    1986
    1987                  # use sizer for border around everything plus a little gap
    1988                  # FIXME: fold into szr_main_panels ?
    1989                  self.szr_central_container = wx.BoxSizer(wx.HORIZONTAL)
    1990                  self.szr_central_container.Add(self.szr_main_panels, 1, wx.EXPAND | wx.ALL, 5)
    1991                  self.SetSizer(self.szr_central_container)
    1992                  self.szr_central_container.Fit(self)
    1993                  self.SetAutoLayout(True)
    1994                  self.Show(True)
    1995
    1996
    1997  #====================================================================
    1998  # old stuff still needed for conversion
    1999  #--------------------------------------------------------------------
    2000  #====================================================================
    2001
    2002  #====================================================================
    2003
    2004  #               elif section == gmSECTION_SCRIPT:
    2005  #                     gmLog.gmDefLog.Log (gmLog.lData, "in script section now")
    2006  #                     self.text1_prescription_reason = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize)
    2007  #                     self.text2_drug_class = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize)
    2008  #                     self.text3_generic_drug = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize)
    2009  #                     self.text4_brand_drug = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize)
    2010  #                     self.text5_strength = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize)
    2011  #                     self.text6_directions = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize)
    2012  #                     self.text7_for_duration = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize)
    2013  #                     self.text8_prescription_progress_notes = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize)
    2014  #                     self.text9_quantity = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize)
    2015  #                     lbl_veterans = cPrompt_edit_area(self,-1,"  Veteran  ")
    2016  #                     lbl_reg24 = cPrompt_edit_area(self,-1,"  Reg 24  ")
    2017  #                     lbl_quantity = cPrompt_edit_area(self,-1,"  Quantity  ")
    2018  #                     lbl_repeats = cPrompt_edit_area(self,-1,"  Repeats  ")
    2019  #                     lbl_usualmed = cPrompt_edit_area(self,-1,"  Usual  ")
    2020  #                     self.cb_veteran  = wx.CheckBox(self, -1, " Yes ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    2021  #                     self.cb_reg24 = wx.CheckBox(self, -1, " Yes ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    2022  #                     self.cb_usualmed = wx.CheckBox(self, -1, " Yes ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    2023  #                     self.sizer_auth_PI = wx.BoxSizer(wxHORIZONTAL)
    2024  #                     self.btn_authority = wx.Button(self,-1,">Authority")     #create authority script
    2025  #                     self.btn_briefPI   = wx.Button(self,-1,"Brief PI")       #show brief drug product information
    2026  #                     self.sizer_auth_PI.Add(self.btn_authority,1,wx.EXPAND|wxALL,2)  #put authority button and PI button
    2027  #                     self.sizer_auth_PI.Add(self.btn_briefPI,1,wx.EXPAND|wxALL,2)    #on same sizer
    2028  #                     self.text10_repeats  = cEditAreaField(self,-1,wx.DefaultPosition,wx.DefaultSize)
    2029  #                     self.sizer_line3.Add(self.text3_generic_drug,5,wx.EXPAND)
    2030  #                     self.sizer_line3.Add(lbl_veterans,1,wx.EXPAND)
    2031   #                    self.sizer_line3.Add(self.cb_veteran,1,wx.EXPAND)
    2032  #                     self.sizer_line4.Add(self.text4_brand_drug,5,wx.EXPAND)
    2033  #                     self.sizer_line4.Add(lbl_reg24,1,wx.EXPAND)
    2034   #                    self.sizer_line4.Add(self.cb_reg24,1,wx.EXPAND)
    2035  #                     self.sizer_line5.Add(self.text5_strength,5,wx.EXPAND)
    2036  #                     self.sizer_line5.Add(lbl_quantity,1,wx.EXPAND)
    2037   #                    self.sizer_line5.Add(self.text9_quantity,1,wx.EXPAND)
    2038  #                     self.sizer_line6.Add(self.text6_directions,5,wx.EXPAND)
    2039  #                     self.sizer_line6.Add(lbl_repeats,1,wx.EXPAND)
    2040   #                    self.sizer_line6.Add(self.text10_repeats,1,wx.EXPAND)
    2041  #                     self.sizer_line7.Add(self.text7_for_duration,5,wx.EXPAND)
    2042  #                     self.sizer_line7.Add(lbl_usualmed,1,wx.EXPAND)
    2043   #                    self.sizer_line7.Add(self.cb_usualmed,1,wx.EXPAND)
    2044  #                     self.sizer_line8.Add(5,0,0)
    2045  #                     self.sizer_line8.Add(self.sizer_auth_PI,2,wx.EXPAND)
    2046  #                     self.sizer_line8.Add(5,0,2)
    2047  #                     self.sizer_line8.Add(self.btn_OK,1,wx.EXPAND|wxALL,2)
    2048  #                     self.sizer_line8.Add(self.btn_Clear,1,wx.EXPAND|wxALL,2)
    2049  #                     self.gszr.Add(self.text1_prescription_reason,1,wx.EXPAND) #prescribe for
    2050  #                     self.gszr.Add(self.text2_drug_class,1,wx.EXPAND) #prescribe by class
    2051  #                     self.gszr.Add(self.sizer_line3,1,wx.EXPAND) #prescribe by generic, lbl_veterans, cb_veteran
    2052  #                     self.gszr.Add(self.sizer_line4,1,wx.EXPAND) #prescribe by brand, lbl_reg24, cb_reg24
    2053  #                     self.gszr.Add(self.sizer_line5,1,wx.EXPAND) #drug strength, lbl_quantity, text_quantity
    2054  #                     self.gszr.Add(self.sizer_line6,1,wx.EXPAND) #txt_directions, lbl_repeats, text_repeats
    2055  #                     self.gszr.Add(self.sizer_line7,1,wx.EXPAND) #text_for,lbl_usual,chk_usual
    2056  #                     self.gszr.Add(self.text8_prescription_progress_notes,1,wx.EXPAND)            #text_progressNotes
    2057  #                     self.gszr.Add(self.sizer_line8,1,wx.EXPAND)
    2058
    2059
    2060  #               elif section == gmSECTION_REQUESTS:
    2061  #                     #-----------------------------------------------------------------------------
    2062                        #editing area for general requests e.g pathology, radiology, physiotherapy etc
    2063                        #create textboxes, radiobuttons etc
    2064                        #-----------------------------------------------------------------------------
    2065  #                     self.txt_request_type = cEditAreaField(self,ID_REQUEST_TYPE,wx.DefaultPosition,wx.DefaultSize)
    2066  #                     self.txt_request_company = cEditAreaField(self,ID_REQUEST_COMPANY,wx.DefaultPosition,wx.DefaultSize)
    2067  #                     self.txt_request_street = cEditAreaField(self,ID_REQUEST_STREET,wx.DefaultPosition,wx.DefaultSize)
    2068  #                     self.txt_request_suburb = cEditAreaField(self,ID_REQUEST_SUBURB,wx.DefaultPosition,wx.DefaultSize)
    2069  #                     self.txt_request_phone= cEditAreaField(self,ID_REQUEST_PHONE,wx.DefaultPosition,wx.DefaultSize)
    2070  #                     self.txt_request_requests = cEditAreaField(self,ID_REQUEST_REQUESTS,wx.DefaultPosition,wx.DefaultSize)
    2071  #                     self.txt_request_notes = cEditAreaField(self,ID_REQUEST_FORMNOTES,wx.DefaultPosition,wx.DefaultSize)
    2072  #                     self.txt_request_medications = cEditAreaField(self,ID_REQUEST_MEDICATIONS,wx.DefaultPosition,wx.DefaultSize)
    2073  #                     self.txt_request_copyto = cEditAreaField(self,ID_REQUEST_COPYTO,wx.DefaultPosition,wx.DefaultSize)
    2074  #                     self.txt_request_progressnotes = cEditAreaField(self,ID_PROGRESSNOTES,wx.DefaultPosition,wx.DefaultSize)
    2075  #                     self.lbl_companyphone = cPrompt_edit_area(self,-1,"  Phone  ")
    2076  #                     self.cb_includeallmedications = wx.CheckBox(self, -1, " Include all medications ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    2077  #                     self.rb_request_bill_bb = wxRadioButton(self, ID_REQUEST_BILL_BB, "Bulk Bill ", wx.DefaultPosition,wx.DefaultSize)
    2078  #                     self.rb_request_bill_private = wxRadioButton(self, ID_REQUEST_BILL_PRIVATE, "Private", wx.DefaultPosition,wx.DefaultSize,wx.SUNKEN_BORDER)
    2079  #                     self.rb_request_bill_rebate = wxRadioButton(self, ID_REQUEST_BILL_REBATE, "Rebate", wx.DefaultPosition,wx.DefaultSize)
    2080  #                     self.rb_request_bill_wcover = wxRadioButton(self, ID_REQUEST_BILL_wcover, "w/cover", wx.DefaultPosition,wx.DefaultSize)
    2081                        #--------------------------------------------------------------
    2082                       #add controls to sizers where multiple controls per editor line
    2083                        #--------------------------------------------------------------
    2084  #                      self.sizer_request_optionbuttons = wx.BoxSizer(wxHORIZONTAL)
    2085  #                     self.sizer_request_optionbuttons.Add(self.rb_request_bill_bb,1,wx.EXPAND)
    2086  #                     self.sizer_request_optionbuttons.Add(self.rb_request_bill_private ,1,wx.EXPAND)
    2087  #                      self.sizer_request_optionbuttons.Add(self.rb_request_bill_rebate  ,1,wx.EXPAND)
    2088  #                      self.sizer_request_optionbuttons.Add(self.rb_request_bill_wcover  ,1,wx.EXPAND)
    2089  #                     self.sizer_line4.Add(self.txt_request_suburb,4,wx.EXPAND)
    2090  #                     self.sizer_line4.Add(self.lbl_companyphone,1,wx.EXPAND)
    2091  #                     self.sizer_line4.Add(self.txt_request_phone,2,wx.EXPAND)
    2092  #                     self.sizer_line7.Add(self.txt_request_medications, 4,wx.EXPAND)
    2093  #                     self.sizer_line7.Add(self.cb_includeallmedications,3,wx.EXPAND)
    2094  #                     self.sizer_line10.AddSizer(self.sizer_request_optionbuttons,3,wx.EXPAND)
    2095  #                     self.sizer_line10.AddSizer(self.szr_buttons,1,wx.EXPAND)
    2096                        #self.sizer_line10.Add(self.btn_OK,1,wx.EXPAND|wxALL,1)
    2097                        #self.sizer_line10.Add(self.btn_Clear,1,wx.EXPAND|wxALL,1)
    2098                        #------------------------------------------------------------------
    2099                        #add either controls or sizers with controls to vertical grid sizer
    2100                        #------------------------------------------------------------------
    2101  #                      self.gszr.Add(self.txt_request_type,0,wx.EXPAND)                   #e.g Pathology
    2102  #                     self.gszr.Add(self.txt_request_company,0,wx.EXPAND)                #e.g Douglas Hanly Moir
    2103  #                     self.gszr.Add(self.txt_request_street,0,wx.EXPAND)                 #e.g 120 Big Street
    2104  #                     self.gszr.AddSizer(self.sizer_line4,0,wx.EXPAND)                   #e.g RYDE NSW Phone 02 1800 222 365
    2105  #                     self.gszr.Add(self.txt_request_requests,0,wx.EXPAND)               #e.g FBC;ESR;UEC;LFTS
    2106  #                     self.gszr.Add(self.txt_request_notes,0,wx.EXPAND)                  #e.g generally tired;weight loss;
    2107  #                     self.gszr.AddSizer(self.sizer_line7,0,wx.EXPAND)                   #e.g Lipitor;losec;zyprexa
    2108  #                     self.gszr.Add(self.txt_request_copyto,0,wx.EXPAND)                 #e.g Dr I'm All Heart, 120 Big Street Smallville
    2109  #                     self.gszr.Add(self.txt_request_progressnotes,0,wx.EXPAND)          #emphasised to patient must return for results
    2110   #                     self.sizer_line8.Add(5,0,6)
    2111  #                     self.sizer_line8.Add(self.btn_OK,1,wx.EXPAND|wxALL,2)
    2112  #                     self.sizer_line8.Add(self.btn_Clear,1,wx.EXPAND|wxALL,2)
    2113  #                     self.gszr.Add(self.sizer_line10,0,wx.EXPAND)                       #options:b/bill private, rebate,w/cover btnok,btnclear
    2114
    2115
    2116  #               elif section == gmSECTION_MEASUREMENTS:
    2117  #                     self.combo_measurement_type = wx.ComboBox(self, ID_MEASUREMENT_TYPE, "", wx.DefaultPosition,wx.DefaultSize, ['Blood pressure','INR','Height','Weight','Whatever other measurement you want to put in here'], wx.CB_DROPDOWN)
    2118  #                     self.combo_measurement_type.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL, wx.BOLD,False,''))
    2119  #                     self.combo_measurement_type.SetForegroundColour(wx.Colour(255,0,0))
    2120  #                     self.txt_measurement_value = cEditAreaField(self,ID_MEASUREMENT_VALUE,wx.DefaultPosition,wx.DefaultSize)
    2121  #                     self.txt_txt_measurement_date = cEditAreaField(self,ID_MEASUREMENT_DATE,wx.DefaultPosition,wx.DefaultSize)
    2122  #                     self.txt_txt_measurement_comment = cEditAreaField(self,ID_MEASUREMENT_COMMENT,wx.DefaultPosition,wx.DefaultSize)
    2123  #                     self.txt_txt_measurement_progressnote = cEditAreaField(self,ID_PROGRESSNOTES,wx.DefaultPosition,wx.DefaultSize)
    2124  #                     self.sizer_graphnextbtn = wx.BoxSizer(wxHORIZONTAL)
    2125  #                     self.btn_nextvalue = wx.Button(self,ID_MEASUREMENT_NEXTVALUE,"   Next Value   ")                 #clear fields except type
    2126  #                     self.btn_graph   = wx.Button(self,ID_MEASUREMENT_GRAPH," Graph ")                        #graph all values of this type
    2127  #                     self.sizer_graphnextbtn.Add(self.btn_nextvalue,1,wx.EXPAND|wxALL,2)  #put next and graph button
    2128  #                     self.sizer_graphnextbtn.Add(self.btn_graph,1,wx.EXPAND|wxALL,2)      #on same sizer
    2129  #                     self.gszr.Add(self.combo_measurement_type,0,wx.EXPAND)              #e.g Blood pressure
    2130  #                     self.gszr.Add(self.txt_measurement_value,0,wx.EXPAND)               #e.g 120.70
    2131  #                     self.gszr.Add(self.txt_txt_measurement_date,0,wx.EXPAND)            #e.g 10/12/2001
    2132  #                     self.gszr.Add(self.txt_txt_measurement_comment,0,wx.EXPAND)         #e.g sitting, right arm
    2133  #                     self.gszr.Add(self.txt_txt_measurement_progressnote,0,wx.EXPAND)    #e.g given home BP montitor, see 1 week
    2134  #                     self.sizer_line8.Add(5,0,0)
    2135  #                     self.sizer_line8.Add(self.sizer_graphnextbtn,2,wx.EXPAND)
    2136  #                     self.sizer_line8.Add(5,0,2)
    2137  #                     self.sizer_line8.Add(self.btn_OK,1,wx.EXPAND|wxALL,2)
    2138  #                     self.sizer_line8.Add(self.btn_Clear,1,wx.EXPAND|wxALL,2)
    2139  #                     self.gszr.AddSizer(self.sizer_line8,0,wx.EXPAND)
    2140
    2141
    2142  #               elif section == gmSECTION_REFERRALS:
    2143  #                     self.btnpreview = wx.Button(self,-1,"Preview")
    2144  #                     self.sizer_btnpreviewok = wx.BoxSizer(wxHORIZONTAL)
    2145                        #--------------------------------------------------------
    2146                        #editing area for referral letters, insurance letters etc
    2147                        #create textboxes, checkboxes etc
    2148                        #--------------------------------------------------------
    2149  #                     self.txt_referralcategory = cEditAreaField(self,ID_REFERRAL_CATEGORY,wx.DefaultPosition,wx.DefaultSize)
    2150  #                     self.txt_referralname = cEditAreaField(self,ID_REFERRAL_NAME,wx.DefaultPosition,wx.DefaultSize)
    2151  #                     self.txt_referralorganisation = cEditAreaField(self,ID_REFERRAL_ORGANISATION,wx.DefaultPosition,wx.DefaultSize)
    2152  #                     self.txt_referralstreet1 = cEditAreaField(self,ID_REFERRAL_STREET1,wx.DefaultPosition,wx.DefaultSize)
    2153  #                     self.txt_referralstreet2 = cEditAreaField(self,ID_REFERRAL_STREET2,wx.DefaultPosition,wx.DefaultSize)
    2154  #                     self.txt_referralstreet3 = cEditAreaField(self,ID_REFERRAL_STREET3,wx.DefaultPosition,wx.DefaultSize)
    2155  #                     self.txt_referralsuburb = cEditAreaField(self,ID_REFERRAL_SUBURB,wx.DefaultPosition,wx.DefaultSize)
    2156  #                     self.txt_referralpostcode = cEditAreaField(self,ID_REFERRAL_POSTCODE,wx.DefaultPosition,wx.DefaultSize)
    2157  #                     self.txt_referralfor = cEditAreaField(self,ID_REFERRAL_FOR,wx.DefaultPosition,wx.DefaultSize)
    2158  #                     self.txt_referralwphone= cEditAreaField(self,ID_REFERRAL_WPHONE,wx.DefaultPosition,wx.DefaultSize)
    2159  #                     self.txt_referralwfax= cEditAreaField(self,ID_REFERRAL_WFAX,wx.DefaultPosition,wx.DefaultSize)
    2160  #                     self.txt_referralwemail= cEditAreaField(self,ID_REFERRAL_WEMAIL,wx.DefaultPosition,wx.DefaultSize)
    2161                        #self.txt_referralrequests = cEditAreaField(self,ID_REFERRAL_REQUESTS,wx.DefaultPosition,wx.DefaultSize)
    2162                        #self.txt_referralnotes = cEditAreaField(self,ID_REFERRAL_FORMNOTES,wx.DefaultPosition,wx.DefaultSize)
    2163                        #self.txt_referralmedications = cEditAreaField(self,ID_REFERRAL_MEDICATIONS,wx.DefaultPosition,wx.DefaultSize)
    2164  #                     self.txt_referralcopyto = cEditAreaField(self,ID_REFERRAL_COPYTO,wx.DefaultPosition,wx.DefaultSize)
    2165  #                     self.txt_referralprogressnotes = cEditAreaField(self,ID_PROGRESSNOTES,wx.DefaultPosition,wx.DefaultSize)
    2166  #                     self.lbl_referralwphone = cPrompt_edit_area(self,-1,"  W Phone  ")
    2167  #                     self.lbl_referralwfax = cPrompt_edit_area(self,-1,"  W Fax  ")
    2168  #                     self.lbl_referralwemail = cPrompt_edit_area(self,-1,"  W Email  ")
    2169  #                     self.lbl_referralpostcode = cPrompt_edit_area(self,-1,"  Postcode  ")
    2170  #                     self.chkbox_referral_usefirstname = wx.CheckBox(self, -1, " Use Firstname ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    2171  #                     self.chkbox_referral_headoffice = wx.CheckBox(self, -1, " Head Office ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    2172  #                     self.chkbox_referral_medications = wx.CheckBox(self, -1, " Medications ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    2173  #                     self.chkbox_referral_socialhistory = wx.CheckBox(self, -1, " Social History ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    2174  #                     self.chkbox_referral_familyhistory = wx.CheckBox(self, -1, " Family History ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    2175  #                     self.chkbox_referral_pastproblems = wx.CheckBox(self, -1, " Past Problems ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    2176  #                     self.chkbox_referral_activeproblems = wx.CheckBox(self, -1, " Active Problems ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    2177  #                     self.chkbox_referral_habits = wx.CheckBox(self, -1, " Habits ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    2178                        #self.chkbox_referral_Includeall = wx.CheckBox(self, -1, " Include all of the above ", wx.DefaultPosition,wx.DefaultSize, wx.NO_BORDER)
    2179                        #--------------------------------------------------------------
    2180                        #add controls to sizers where multiple controls per editor line
    2181                        #--------------------------------------------------------------
    2182  #                     self.sizer_line2.Add(self.txt_referralname,2,wx.EXPAND)
    2183  #                     self.sizer_line2.Add(self.chkbox_referral_usefirstname,2,wx.EXPAND)
    2184  #                     self.sizer_line3.Add(self.txt_referralorganisation,2,wx.EXPAND)
    2185  #                     self.sizer_line3.Add(self.chkbox_referral_headoffice,2, wx.EXPAND)
    2186  #                     self.sizer_line4.Add(self.txt_referralstreet1,2,wx.EXPAND)
    2187  #                     self.sizer_line4.Add(self.lbl_referralwphone,1,wx.EXPAND)
    2188  #                     self.sizer_line4.Add(self.txt_referralwphone,1,wx.EXPAND)
    2189  #                     self.sizer_line5.Add(self.txt_referralstreet2,2,wx.EXPAND)
    2190  #                     self.sizer_line5.Add(self.lbl_referralwfax,1,wx.EXPAND)
    2191  #                     self.sizer_line5.Add(self.txt_referralwfax,1,wx.EXPAND)
    2192  #                     self.sizer_line6.Add(self.txt_referralstreet3,2,wx.EXPAND)
    2193  #                     self.sizer_line6.Add(self.lbl_referralwemail,1,wx.EXPAND)
    2194  #                     self.sizer_line6.Add(self.txt_referralwemail,1,wx.EXPAND)
    2195  #                     self.sizer_line7.Add(self.txt_referralsuburb,2,wx.EXPAND)
    2196  #                     self.sizer_line7.Add(self.lbl_referralpostcode,1,wx.EXPAND)
    2197  #                     self.sizer_line7.Add(self.txt_referralpostcode,1,wx.EXPAND)
    2198  #                     self.sizer_line10.Add(self.chkbox_referral_medications,1,wx.EXPAND)
    2199  #                     self.sizer_line10.Add(self.chkbox_referral_socialhistory,1,wx.EXPAND)
    2200  #                     self.sizer_line10.Add(self.chkbox_referral_familyhistory,1,wx.EXPAND)
    2201  #                     self.sizer_line11.Add(self.chkbox_referral_pastproblems  ,1,wx.EXPAND)
    2202  #                     self.sizer_line11.Add(self.chkbox_referral_activeproblems  ,1,wx.EXPAND)
    2203  #                     self.sizer_line11.Add(self.chkbox_referral_habits  ,1,wx.EXPAND)
    2204  #                     self.sizer_btnpreviewok.Add(self.btnpreview,0,wx.EXPAND)
    2205  #                     self.szr_buttons.Add(self.btn_Clear,0, wx.EXPAND)
    2206                        #------------------------------------------------------------------
    2207                        #add either controls or sizers with controls to vertical grid sizer
    2208                        #------------------------------------------------------------------
    2209   #                     self.gszr.Add(self.txt_referralcategory,0,wx.EXPAND)               #e.g Othopaedic surgeon
    2210  #                     self.gszr.Add(self.sizer_line2,0,wx.EXPAND)                        #e.g Dr B Breaker
    2211  #                     self.gszr.Add(self.sizer_line3,0,wx.EXPAND)                        #e.g General Orthopaedic servies
    2212  #                     self.gszr.Add(self.sizer_line4,0,wx.EXPAND)                        #e.g street1
    2213  #                     self.gszr.Add(self.sizer_line5,0,wx.EXPAND)                        #e.g street2
    2214  #                     self.gszr.Add(self.sizer_line6,0,wx.EXPAND)                        #e.g street3
    2215  #                     self.gszr.Add(self.sizer_line7,0,wx.EXPAND)                        #e.g suburb and postcode
    2216  #                     self.gszr.Add(self.txt_referralfor,0,wx.EXPAND)                    #e.g Referral for an opinion
    2217  #                     self.gszr.Add(self.txt_referralcopyto,0,wx.EXPAND)                 #e.g Dr I'm All Heart, 120 Big Street Smallville
    2218  #                     self.gszr.Add(self.txt_referralprogressnotes,0,wx.EXPAND)          #emphasised to patient must return for results
    2219  #                     self.gszr.AddSizer(self.sizer_line10,0,wx.EXPAND)                   #e.g check boxes to include medications etc
    2220  #                     self.gszr.Add(self.sizer_line11,0,wx.EXPAND)                       #e.g check boxes to include active problems etc
    2221                        #self.spacer = wxWindow(self,-1,wx.DefaultPosition,wx.DefaultSize)
    2222                        #self.spacer.SetBackgroundColour(wx.Colour(255,255,255))
    2223  #                     self.sizer_line12.Add(5,0,6)
    2224                        #self.sizer_line12.Add(self.spacer,6,wx.EXPAND)
    2225  #                     self.sizer_line12.Add(self.btnpreview,1,wx.EXPAND|wxALL,2)
    2226  #                     self.sizer_line12.Add(self.btn_Clear,1,wx.EXPAND|wxALL,2)
    2227  #                     self.gszr.Add(self.sizer_line12,0,wx.EXPAND)                       #btnpreview and btn clear
    2228
    2229
    2230  #               elif section == gmSECTION_RECALLS:
    2231                        #FIXME remove present options in this combo box     #FIXME defaults need to be loaded from database
    2232  #                     self.combo_tosee = wx.ComboBox(self, ID_RECALLS_TOSEE, "", wx.DefaultPosition,wx.DefaultSize, ['Doctor1','Doctor2','Nurse1','Dietition'], wx.CB_READONLY ) #wx.CB_DROPDOWN)
    2233  #                     self.combo_tosee.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL, wx.BOLD,False,''))
    2234  #                     self.combo_tosee.SetForegroundColour(wx.Colour(255,0,0))
    2235                        #FIXME defaults need to be loaded from database
    2236  #                     self.combo_recall_method = wx.ComboBox(self, ID_RECALLS_CONTACTMETHOD, "", wx.DefaultPosition,wx.DefaultSize, ['Letter','Telephone','Email','Carrier pigeon'], wx.CB_READONLY )
    2237  #                     self.combo_recall_method.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL, wx.BOLD,False,''))
    2238  #                     self.combo_recall_method.SetForegroundColour(wx.Colour(255,0,0))
    2239                        #FIXME defaults need to be loaded from database
    2240   #                     self.combo_apptlength = wx.ComboBox(self, ID_RECALLS_APPNTLENGTH, "", wx.DefaultPosition,wx.DefaultSize, ['brief','standard','long','prolonged'], wx.CB_READONLY )
    2241  #                     self.combo_apptlength.SetFont(wx.Font(12,wx.SWISS,wx.NORMAL, wx.BOLD,False,''))
    2242  #                     self.combo_apptlength.SetForegroundColour(wx.Colour(255,0,0))
    2243  #                     self.txt_recall_for = cEditAreaField(self,ID_RECALLS_TXT_FOR, wx.DefaultPosition,wx.DefaultSize)
    2244  #                     self.txt_recall_due = cEditAreaField(self,ID_RECALLS_TXT_DATEDUE, wx.DefaultPosition,wx.DefaultSize)
    2245  #                     self.txt_recall_addtext = cEditAreaField(self,ID_RECALLS_TXT_ADDTEXT,wx.DefaultPosition,wx.DefaultSize)
    2246  #                     self.txt_recall_include = cEditAreaField(self,ID_RECALLS_TXT_INCLUDEFORMS,wx.DefaultPosition,wx.DefaultSize)
    2247  #                     self.txt_recall_progressnotes = cEditAreaField(self,ID_PROGRESSNOTES,wx.DefaultPosition,wx.DefaultSize)
    2248  #                     self.lbl_recall_consultlength = cPrompt_edit_area(self,-1,"  Appointment length  ")
    2249                        #sizer_lkine1 has the method of recall and the appointment length
    2250  #                     self.sizer_line1.Add(self.combo_recall_method,1,wx.EXPAND)
    2251  #                     self.sizer_line1.Add(self.lbl_recall_consultlength,1,wx.EXPAND)
    2252  #                     self.sizer_line1.Add(self.combo_apptlength,1,wx.EXPAND)
    2253                        #Now add the controls to the grid sizer
    2254   #                     self.gszr.Add(self.combo_tosee,1,wx.EXPAND)                       #list of personel for patient to see
    2255  #                     self.gszr.Add(self.txt_recall_for,1,wx.EXPAND)                    #the actual recall may be free text or word wheel
    2256  #                     self.gszr.Add(self.txt_recall_due,1,wx.EXPAND)                    #date of future recall
    2257  #                     self.gszr.Add(self.txt_recall_addtext,1,wx.EXPAND)                #added explanation e.g 'come fasting'
    2258  #                     self.gszr.Add(self.txt_recall_include,1,wx.EXPAND)                #any forms to be sent out first eg FBC
    2259  #                     self.gszr.AddSizer(self.sizer_line1,1,wx.EXPAND)                        #the contact method, appointment length
    2260  #                     self.gszr.Add(self.txt_recall_progressnotes,1,wx.EXPAND)          #add any progress notes for consultation
    2261  #                     self.sizer_line8.Add(5,0,6)
    2262  #                     self.sizer_line8.Add(self.btn_OK,1,wx.EXPAND|wxALL,2)
    2263  #                     self.sizer_line8.Add(self.btn_Clear,1,wx.EXPAND|wxALL,2)
    2264  #                     self.gszr.Add(self.sizer_line8,1,wx.EXPAND)
    2265  #               else:
    2266  #                     pass
    2267
    2268  #====================================================================
    2269  # main
    2270  #--------------------------------------------------------------------
    2271  if __name__ == "__main__":
    2272
    2273          #================================================================
    2274 -        class cTestEditArea(cEditArea):
    2275 -                def __init__(self, parent):
    2276                          cEditArea.__init__(self, parent, -1)
    2277 -                def _define_prompts(self):
    2278                          self._add_prompt(line=1, label='line 1')
    2279                          self._add_prompt(line=2, label='buttons')
    2280 -                def _define_fields(self, parent):
    2281                          # line 1
    2282                          self.fld_substance = cEditAreaField(parent)
    2283                          self._add_field(
    2284                                  line = 1,
    2285                                  pos = 1,
    2286                                  widget = self.fld_substance,
    2287                                  weight = 1
    2288                          )
    2289                          # line 2
    2290                          self._add_field(
    2291                                  line = 2,
    2292                                  pos = 1,
    2293                                  widget = self._make_standard_buttons(parent),
    2294                                  weight = 1
    2295                          )
    2296          #================================================================
    2297          app = wxPyWidgetTester(size = (400, 200))
    2298          app.SetWidget(cTestEditArea)
    2299          app.MainLoop()
    2300  #       app = wxPyWidgetTester(size = (400, 200))
    2301  #       app.SetWidget(gmFamilyHxEditArea, -1)
    2302  #       app.MainLoop()
    2303  #       app = wxPyWidgetTester(size = (400, 200))
    2304  #       app.SetWidget(gmPastHistoryEditArea, -1)
    2305  #       app.MainLoop()
    2306  #====================================================================
    2307