Gnumed.wxpython.gui.gmContacts

Package Gnumed :: Package wxpython :: Package gui :: Module gmContacts |
[frames] | no frames]

# Source Code for Module Gnumed.wxpython.gui.gmContacts

       1  # -*- coding: utf-8 -*-
       2  #############################################################################
       3  # This panel is a contact manager to display and allow the
       4  # use to add/delete/edit organisations,branches, persons
       5  #
       6  # If you don't like it - change this code
       7  #
       8  #       contains dummy data only
       9  #       implemented for gui presentation only
      10  ##############################################################################
      11  # $Source: /home/ncq/Projekte/cvs2git/vcs-mirror/gnumed/gnumed/client/wxpython/gui/gmContacts.py,v $
      12  __version__ = "$Revision: 1.50 $"
      13  __author__ = "Dr. Richard Terry, \
      14                          Sebastian Hilbert <Sebastian.Hilbert@gmx.net>"
      15  __license__ = "GPL v2 or later (details at http://www.gnu.org)"
      16
      17  from Gnumed.pycommon import gmI18N
      18
      19  import wx
      20
      21  from Gnumed.wxpython import gmPlugin, images_contacts_toolbar16_16
      22  from Gnumed.wxpython.gmPhraseWheel import cPhraseWheel
      23  from Gnumed.business import gmDemographicRecord
      24  from Gnumed.business.gmDemographicRecord import OrgCategoryMP
      25  from Gnumed.business.gmOrganization import cOrgHelperImpl1,  cOrgHelperImpl2, cOrgHelperImpl3, cCatFinder, setPostcodeWidgetFromUrbId
      26
      27  DISPLAYPERSON = 0
      28  organisationsdata = {
      29  1 : ("John Hunter Hospital","", "Lookout Rd NEW LAMBTON HEIGHTS","Public Hospital","02 49213000"),
      30  2 : (" ","Cardiovascular Department", "","", "49214200"),
      31  3 : ( " ","- Dr L Smith","Cardiologist","lsmith@cardiology.jhh.com.au", "0148 222 222"),
      32  4 : (" ","Department of Surgery", "","", "49214200"),
      33  5 : ( " ","- Dr No Brains","Colorectal surgeon","nobrainer@surgery.jhh.com.au", "0148 111 111"),
      34  6 : ("Belmont District Hospital","", "Lake Rd BELMONT","Public Hospital","02 49421111"),
      35  7 : (" ","Physiotherapy", "","", "49423567"),
      36  8 : ( " ","- P Lang","Sports Physiotherapist","plang@jphysio.bdh.com.au", "494223568"),
      37  9 : ( " ","- L Short","Physiotherapist","lshort@jphysio.bdh.com.au", "494223568"),
      38  }
      39
      40  [
      41  ID_ORGANISATIONSLIST,
      42  ID_ALL_MENU,
      43  ID_COMBOTYPE,
      44  ID_SAVESQL,
      45  ID_SEARCHGLOBAL,
      46  ID_ORGANISATIONDISPLAY,
      47  ID_GENERALPRACTICESDISPLAY,
      48  ID_DOCTORSDISPLAY,
      49  ID_PERSONSDISPLAY,
      50  ID_ORGANISATIONADD,
      51  ID_BRANCHDEPTADD,
      52  ID_EMPLOYEEADD,
      53  ID_PERSONADD,
      54  ID_RELOAD,
      55  ID_SEARCHSPECIFIC,
      56  ID_SORTA_Z,
      57  ID_SORTZ_A,
      58  ID_SENDEMAIL,
      59  ID_LINKINTERNET,
      60  ID_INSTANTREPORT,
      61  ID_REPORTS,
      62  ID_SAVE,
      63  ID_ORGPERSON_SELECTED
      64
      65  ] = map(lambda _init_ctrls: wx.wx.NewId(), range(23))
      66
      67  divisionTypes = [_('Head Office'),_('Branch'),_('Department')]
      68
      69
      70  #--------------------------------------------------
      71  #Class which shows a blue bold label left justified
      72  #--------------------------------------------------
      73 -class BlueLabel(wx.wxStaticText):
      74 -        def __init__(self, parent, id, prompt):
      75                  wx.wxStaticText.__init__(self,parent, id,prompt, wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxALIGN_LEFT)
      76                  self.SetFont(wx.wxFont(12, wx.wxSWISS, wx.wx.NORMAL, wx.wx.BOLD,False,''))
      77                  self.SetForegroundColour(wx.wxColour(0,0,131))
      78
      79 -class DarkBlueHeading(wx.wxStaticText):
      80 -        def __init__(self, parent, id, prompt):
      81                  wx.wxStaticText.__init__(self,parent, id,prompt, wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxALIGN_CENTER)
      82                  self.SetFont(wx.wxFont(
      83                          pointSize = 12,
      84                          family = wx.wxSWISS,
      85                          style = wx.wx.NORMAL,
      86                          weight = wx.wx.BOLD,
      87                          underline = False
      88                          )
      89                  )
      90                  self.SetForegroundColour(wx.wxColour(0,0,255))
      91  #------------------------------------------------------------
      92  #text control class to be later replaced by the gmPhraseWheel
      93  #------------------------------------------------------------
      94 -class TextBox_RedBold(wx.wx.TextCtrl):
      95 -        def __init__ (self, parent, id): #, wx.wxDefaultPostion, wx.wxDefaultSize):
      96                  wx.wx.TextCtrl.__init__(self,parent,id,"", wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxSIMPLE_BORDER)
      97                  self.SetForegroundColour(wx.wxColor(255,0,0))
      98                  self.SetFont(wx.wxFont(12, wx.wxSWISS, wx.wx.NORMAL, wx.wx.BOLD,False,''))
      99 -class TextBox_BlackNormal(wx.wx.TextCtrl):
     100 -        def __init__ (self, parent, id): #, wx.wxDefaultPostion, wx.wxDefaultSize):
     101                  wx.wx.TextCtrl.__init__(self,parent,id,"", wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxSIMPLE_BORDER)
     102                  self.SetForegroundColour(wx.wxColor(0,0,0))
     103                  self.SetFont(wx.wxFont(12, wx.wxSWISS, wx.wx.NORMAL, wx.wx.BOLD,False,''))
     104
     105 -class cContactsPanel(wx.wx.Panel):
     106 -        def __init__(self, parent,id):
     107                  wx.wx.Panel.__init__(self, parent, id, wx.wxDefaultPosition, wx.wxDefaultSize, wx.wx.NO_BORDER| wx.wx.TAB_TRAVERSAL)
     108                  #-----------------------------------------------------------------
     109                  #create top list box which will show organisations, employees, etc
     110                  #-----------------------------------------------------------------
     111                  self.list_organisations = wx.wx.ListCtrl(self, ID_ORGANISATIONSLIST,  wx.wxDefaultPosition, wx.wxDefaultSize, wx.wx.LC_REPORT| wx.wx.LC_NO_HEADER| wx.wxSUNKEN_BORDER)
     112                  self.list_organisations.SetForegroundColour(wx.wxColor(74,76,74))
     113                  self.list_organisations.SetFont(wx.wxFont(10, wx.wxSWISS, wx.wx.NORMAL, wx.wx.NORMAL, False, ''))
     114                  #----------------------------------------
     115                  # add some dummy data to the allergy list
     116                  self.list_organisations.InsertColumn(0, "Organisation")
     117                  self.list_organisations.InsertColumn(1, "Employees")
     118                  self.list_organisations.InsertColumn(2, "Address")
     119                  self.list_organisations.InsertColumn(3, "Category/Email")
     120                  self.list_organisations.InsertColumn(4, "Phone")
     121
     122                  #-------------------------------------------------------------
     123                  #loop through the scriptdata array and add to the list control
     124                  #note the different syntax for the first coloum of each row
     125                  #i.e. here > self.list_organisations.InsertItem(x, data[0])!!
     126                  #-------------------------------------------------------------
     127                  items = organisationsdata.items()
     128                  for x in range(len(items)):
     129                          key, data = items[x]
     130                          #print items[x]
     131                          #print x, data[0],data[1],data[2]
     132                          self.list_organisations.InsertItem(x, data[0])
     133                          self.list_organisations.SetItem(x, 1, data[1])
     134                          self.list_organisations.SetItem(x, 2, data[2])
     135                          self.list_organisations.SetItem(x, 3, data[3])
     136                          self.list_organisations.SetItem(x, 4, data[4])
     137                  self.list_organisations.SetItemData(x, key)
     138                  self.list_organisations.SetColumnWidth(0, wx.wx.LIST_AUTOSIZE)
     139                  self.list_organisations.SetColumnWidth(1, wx.wx.LIST_AUTOSIZE)
     140                  self.list_organisations.SetColumnWidth(2, wx.wx.LIST_AUTOSIZE)
     141                  self.list_organisations.SetColumnWidth(3, wx.wx.LIST_AUTOSIZE)
     142                  self.list_organisations.SetColumnWidth(4, wx.wx.LIST_AUTOSIZE)
     143
     144                  #--------------------
     145                  #create static labels
     146                  #--------------------
     147                  self.lbl_heading = DarkBlueHeading(self,-1,_("Organisation"))
     148                  self.lbl_org_name = BlueLabel(self,-1,_("Name"))
     149                  self.lbl_Type = BlueLabel(self,-1,_("Office"))
     150                  self.lbl_org_street = BlueLabel(self,-1,("Street"))
     151                  self.lbl_org_suburb = BlueLabel(self,-1,_("Suburb"))
     152                  self.lbl_org_state = BlueLabel(self,-1,_("Region"))                   #eg NSW
     153                  self.lbl_org_zip = wx.wxStaticText(self,id,_("Zip"), wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxALIGN_CENTRE)
     154                  self.lbl_org_zip.SetFont(wx.wxFont(12, wx.wxSWISS, wx.wx.NORMAL, wx.wx.BOLD,False,''))
     155                  self.lbl_org_zip.SetForegroundColour(wx.wxColour(0,0,131))
     156                  #self.lbl_org_zip = BlueLabel(self,-1,"Zip")
     157                  self.lbl_org_category = BlueLabel(self,-1,_("Category"))
     158                  #self.lbl_pers_occupation =  BlueLabel(self,-1,"Occupation")
     159                  self.lbl_org_user1 = BlueLabel(self,-1,_("User1"))
     160                  self.lbl_org_user2 = BlueLabel(self,-1,_("User2"))
     161                  self.lbl_org_user3 = BlueLabel(self,-1,_("User3"))
     162                  self.lbl_org_phone = BlueLabel(self,-1,_("Phone"))
     163                  self.lbl_org_fax = BlueLabel(self,-1,_("Fax"))
     164                  self.lbl_org_email = BlueLabel(self,-1,_("Email"))
     165                  self.lbl_org_internet = BlueLabel(self,-1,_("Internet"))
     166                  self.lbl_org_mobile = BlueLabel(self,-1,_("Mobile"))
     167                  self.lbl_org_memo = BlueLabel(self,-1,_("Memo"))
     168
     169                  #--------------------
     170                  #create the textboxes
     171                  #--------------------
     172                  self.txt_org_name = TextBox_RedBold(self,-1)
     173                  self.txt_org_type = TextBox_RedBold(self,-1)       #head office, branch or department
     174                  #self.txt_org_number = TextBox_RedBold(self, -1)
     175  #               self.txt_org_street = cPhraseWheel( parent = self,id = -1 , aMatchProvider= StreetMP(),  pos = wx.wxDefaultPosition, size= wx.wxDefaultSize )
     176  #               self.txt_org_street.SetFont(wx.wxFont(12, wx.wxSWISS, wx.wx.NORMAL, wx.wx.NORMAL, False, ''))
     177  #               self.txt_org_suburb = cPhraseWheel( parent = self,id = -1 , aMatchProvider= MP_urb_by_zip(), selection_only = 1)
     178  #               self.txt_org_suburb.add_callback_on_selection(self.__urb_selected)
     179  #               self.txt_org_zip  = cPhraseWheel( parent = self,id = -1 , aMatchProvider= PostcodeMP(), selection_only = 1,  pos = wx.wxDefaultPosition, size= wx.wxDefaultSize)
     180                  # FIXME: replace with set_callback_on_*
     181  #               self.txt_org_zip.setDependent (self.txt_org_suburb, 'postcode')
     182
     183                  #self.txt_org_street = wx.wx.TextCtrl(self, 30,"", wx.wxDefaultPosition, wx.wxDefaultSize, style= wx.wx.TE_MULTILINE| wx.wx.NO_3D| wx.wxSIMPLE_BORDER)
     184
     185                  #self.txt_org_street.SetForegroundColour(wx.wxColor(255,0,0))
     186                  #self.txt_org_street.SetFont(wx.wxFont(12, wx.wxSWISS, wx.wx.NORMAL, wx.wx.BOLD,False,''))
     187                  #self.txt_org_suburb = TextBox_RedBold(self,-1)
     188                  #self.txt_org_zip = TextBox_RedBold(self,-1)
     189                  self.txt_org_state = TextBox_RedBold(self,-1) #for user defined fields later
     190                  self.txt_org_user1 = TextBox_BlackNormal(self,-1)
     191                  self.txt_org_user2 = TextBox_BlackNormal(self,-1)
     192                  self.txt_org_user3 = TextBox_BlackNormal(self,-1)
     193  #               self.txt_org_category = cPhraseWheel(self, -1, aMatchProvider = OrgCategoryMP(), selection_only = 1, pos = wx.wxDefaultPosition, size= wx.wxDefaultSize)
     194                  #self.txt_pers_occupation = TextBox_BlackNormal(self,-1)
     195                  self.txt_org_phone = TextBox_BlackNormal(self,-1)
     196                  self.txt_org_fax = TextBox_BlackNormal(self,-1)
     197                  self.txt_org_mobile = TextBox_BlackNormal(self,-1)
     198                  self.txt_org_email = TextBox_BlackNormal(self,-1)
     199                  self.txt_org_internet = TextBox_BlackNormal(self,-1)
     200                  self.txt_org_memo = wx.wx.TextCtrl(self, 30,
     201                                  "This company never pays its bills \n"
     202                                  "Insist on pre-payment before sending report",
     203                                  wx.wxDefaultPosition, wx.wxDefaultSize, style= wx.wx.TE_MULTILINE| wx.wx.NO_3D| wx.wxSIMPLE_BORDER)
     204                  self.txt_org_memo.SetInsertionPoint(0)
     205                  self.txt_org_memo.SetFont(wx.wxFont(12, wx.wxSWISS, wx.wx.NORMAL, wx.wx.NORMAL, False, ''))
     206                  self.combo_type = wx.wxComboBox(self, ID_COMBOTYPE, "", wx.wxDefaultPosition, wx.wxDefaultSize,  divisionTypes , wx.wxCB_READONLY ) # wx.wxCB_DROPDOWN)
     207                  self.combo_type.SetForegroundColour(wx.wxColor(255,0,0))
     208                  self.combo_type.SetFont(wx.wxFont(12, wx.wxSWISS, wx.wx.NORMAL, wx.wx.BOLD,False,''))
     209                  #----------------------
     210                  #create the check boxes
     211                  #----------------------
     212                  self.chbx_postaladdress = wx.wxCheckBox(self, -1,_( " Postal Address "), wx.wxDefaultPosition, wx.wxDefaultSize, wx.wx.NO_BORDER)
     213
     214                  self.input_fields = {
     215                          'name': self.txt_org_name,
     216                          'office': self.txt_org_type,
     217                          'category': self.txt_org_category,
     218                          'subtype': self.combo_type,
     219                          'street': self.txt_org_street,
     220                          'urb': self.txt_org_suburb,
     221                          'postcode' : self.txt_org_zip,
     222                          'memo': self.txt_org_memo,
     223                          'phone' : self.txt_org_phone,
     224                          'fax' : self.txt_org_fax,
     225                          'mobile': self.txt_org_mobile,
     226                          'email': self.txt_org_email,
     227                          'jabber': self.txt_org_internet }
     228
     229
     230                  self._set_controller()
     231
     232                  #-------------------------------------------
     233                  #create the sizers for each line of controls
     234                  #-------------------------------------------
     235                  self.sizer_line0 = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     236                  self.sizer_line1 = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     237                  self.sizer_line1a = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     238                  self.sizer_line2 = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     239                  self.sizer_line3 = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     240                  self.sizer_line4 = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     241                  self.sizer_line5 = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     242                  self.sizer_line6 = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     243                  self.sizer_line7 = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     244                  self.sizer_line8 = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     245                  self.sizer_line9 = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     246                  self.sizer_line10 = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     247                  self.sizer_line11 = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     248                  self.sizer_line0.Add((0,10),1)
     249                  #--------------------------------------
     250                  #Heading at top of the left hand column
     251                  #--------------------------------------
     252                  if wx.wxPlatform == '__WXMAC__':
     253                          self.sizer_line0.Add((0,0),4)
     254                  else:
     255                          self.sizer_line0.Add(0,0,4)
     256
     257                  self.sizer_line0.Add(self.lbl_heading,40, wx.wxEXPAND| wx.wxALIGN_CENTER)
     258
     259                  if wx.wxPlatform == '__WXMAC__':
     260                          self.sizer_line0.Add((0,0),48)
     261                  else:
     262                          self.sizer_line0.Add(0,0,48)
     263                  #---------------------------------------------
     264                  #line one:surname, organisation name, category
     265                  #---------------------------------------------
     266                  self.sizer_line1.Add(self.lbl_org_name,4, wx.wxALIGN_CENTER_VERTICAL,5)
     267                  self.sizer_line1.Add(self.txt_org_name,40, wx.wxEXPAND)
     268                  self.sizer_line1.Add(0,0,4)
     269                  self.sizer_line1.Add(self.lbl_org_category,8, wx.wxALIGN_CENTER_VERTICAL, 5)
     270                  self.sizer_line1.Add(self.txt_org_category,36, wx.wxEXPAND)
     271                  #--------------------------------------------------------------
     272                  #line onea:type of organisation:headoffice,branch of department
     273                  #--------------------------------------------------------------
     274
     275                  #self.sizer_line1a.Add(0,0,4)
     276                  self.sizer_line1a.Add(self.lbl_Type,4, wx.wxALIGN_LEFT,5)
     277                  self.sizer_line1a.Add(self.combo_type,20, wx.wxEXPAND)
     278                  self.sizer_line1a.Add(self.txt_org_type,20, wx.wxEXPAND)
     279                  if wx.wxPlatform == '__WXMAC__':
     280                          self.sizer_line1a.Add((0,0),4)
     281                  else:
     282                          self.sizer_line1a.Add(0,0,4)
     283                  if DISPLAYPERSON == 1:
     284                          self.sizer_line1a.Add(self.lbl_pers_occupation,8, wx.wxALIGN_CENTER_VERTICAL, 5)
     285                          self.sizer_line1a.Add(self.txt_pers_occupation,36, wx.wxEXPAND)
     286                  else:
     287                          self.sizer_line1a.Add(0,0,44)
     288                          #self.lbl_pers_occupation.Hide
     289                          #self.txt_pers_occupation.Hide
     290
     291                  #--------------------------------------------
     292                  #line two:street, + blank line under category
     293                  #design of sizer_line2_forphone: (Horizontal box sizer)
     294                  #                           |lbl_org_phone + txt_org_phone   |
     295                  #
     296                  #this is then added to:
     297                  #design of sizer_line2_rightside (verticalbox sizer)
     298                  #                           |blank line                      |
     299                  #                           |sizer_line2_forphone            |
     300                  #
     301                  #sizer_line2_rightside is then added to sizerline2:
     302                  # -----------------------------------------------------------
     303                  # street stuff on sizerline2 | spacer | sizer_line2_rightside|
     304                  #------------------------------------------------------------
     305                  self.sizer_line2_rightside = wx.wx.BoxSizer(wx.wx.VERTICAL)
     306                  self.sizer_line2_forphone = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     307                  self.sizer_line2_forphone.Add(self.lbl_org_phone,8, wx.wxGROW, wx.wxALIGN_CENTER_VERTICAL,5)
     308                  self.sizer_line2_forphone.Add(self.txt_org_phone,36, wx.wxEXPAND)
     309                  self.sizer_line2_forfax = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     310                  self.sizer_line2_forfax.Add(self.lbl_org_fax,8, wx.wxGROW, wx.wxALIGN_CENTER_VERTICAL,5)
     311                  self.sizer_line2_forfax.Add(self.txt_org_fax,36, wx.wxEXPAND)
     312                  self.sizer_line2_rightside.AddSizer(self.sizer_line2_forphone,2, wx.wxEXPAND)
     313                  self.sizer_line2_rightside.AddSizer(self.sizer_line2_forfax,2, wx.wxEXPAND)
     314                  self.sizer_line2.Add(self.lbl_org_street,4, wx.wxGROW| wx.wxALIGN_CENTER_VERTICAL,5)
     315                  self.sizer_line2.Add(self.txt_org_street,40, wx.wxEXPAND)
     316                  if wx.wxPlatform == '__WXMAC__':
     317                          self.sizer_line2.Add((0,0),4)
     318                  else:
     319                          self.sizer_line2.Add(0,0,4)
     320                  self.sizer_line2.AddSizer(self.sizer_line2_rightside,44, wx.wxEXPAND)
     321                  #----------------------------------------------------
     322                  #line three:suburb, region, zip code, organisation fax
     323                  #----------------------------------------------------
     324                  self.sizer_line3.Add(self.lbl_org_suburb,4, wx.wxEXPAND| wx.wxALIGN_CENTER_VERTICAL)
     325                  self.sizer_line3.Add(self.txt_org_suburb,40, wx.wxEXPAND)
     326                  if wx.wxPlatform == '__WXMAC__':
     327                          self.sizer_line3.Add((0,0),4)
     328                  else:
     329                          self.sizer_line3.Add(0,0,4)
     330                  self.sizer_line3.Add(self.lbl_org_email,8, wx.wxGROW| wx.wxALIGN_CENTER_VERTICAL)
     331                  self.sizer_line3.Add(self.txt_org_email,36, wx.wxEXPAND)
     332                  #-----------------------------------------------
     333                  #line four: head office checkbox, email text box
     334                  #-----------------------------------------------
     335                  self.sizer_line4.Add(self.lbl_org_state,4, wx.wxEXPAND| wx.wxALIGN_CENTER)
     336                  self.sizer_line4.Add(self.txt_org_state,20, wx.wxEXPAND)
     337                  self.sizer_line4.Add(self.lbl_org_zip,10, wx.wxGROW| wx.wx.TOP,5)
     338                  self.sizer_line4.Add(self.txt_org_zip,10, wx.wxEXPAND)
     339                  if wx.wxPlatform == '__WXMAC__':
     340                          self.sizer_line4.Add((0,0),4)
     341                  else:
     342                          self.sizer_line4.Add(0,0,4)
     343                  self.sizer_line4.Add(self.lbl_org_internet,8, wx.wxGROW| wx.wxALIGN_CENTER_VERTICAL,5)
     344                  self.sizer_line4.Add(self.txt_org_internet,36, wx.wxEXPAND)
     345                  #-----------------------------------------------
     346                  #line five: postal address checkbox, internet
     347                  #-----------------------------------------------
     348                  if wx.wxPlatform == '__WXMAC__':
     349                          self.sizer_line5.Add((0,0),4)
     350                  else:
     351                          self.sizer_line5.Add(0,0,4)
     352                  self.sizer_line5.Add(self.chbx_postaladdress,40, wx.wxEXPAND)
     353                  if wx.wxPlatform == '__WXMAC__':
     354                          self.sizer_line5.Add((0,0),4)
     355                  else:
     356                          self.sizer_line5.Add(0,0,4)
     357                  self.sizer_line5.Add(self.lbl_org_mobile,8, wx.wxGROW| wx.wxALIGN_CENTER_VERTICAL,5)
     358                  self.sizer_line5.Add(self.txt_org_mobile,36, wx.wxEXPAND)
     359                  #-----------------------------------------------
     360                  #line six: checkbox branch mobile phone number
     361                  #-----------------------------------------------
     362                  if wx.wxPlatform == '__WXMAC__':
     363                          self.sizer_line6.Add((0,20),96)
     364                  else:
     365                          self.sizer_line6.Add(0,20,96)
     366                  #-----------------------------------------------
     367                  #line seven: user1
     368                  #-----------------------------------------------
     369                  self.sizer_line7_user1 = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     370                  self.sizer_line7_user1.Add(self.lbl_org_user1,4, wx.wxGROW| wx.wxALIGN_CENTER_VERTICAL,5)
     371                  self.sizer_line7_user1.Add(self.txt_org_user1,18, wx.wxEXPAND)
     372                  self.sizer_line7_user2 = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     373                  self.sizer_line7_user2.Add(self.lbl_org_user2,4, wx.wxGROW| wx.wxALIGN_CENTER_VERTICAL,5)
     374                  self.sizer_line7_user2.Add(self.txt_org_user2,18, wx.wxEXPAND)
     375                  self.sizer_line7_user3 = wx.wx.BoxSizer(wx.wx.HORIZONTAL)
     376                  self.sizer_line7_user3.Add(self.lbl_org_user3,4, wx.wxGROW| wx.wxALIGN_CENTER_VERTICAL,5)
     377                  self.sizer_line7_user3.Add(self.txt_org_user3,18, wx.wxEXPAND)
     378                  self.sizer_line7_right = wx.wx.BoxSizer(wx.wx.VERTICAL)
     379                  self.sizer_line7_right.AddSizer(self.sizer_line7_user1,0, wx.wxEXPAND)
     380                  self.sizer_line7_right.AddSizer(self.sizer_line7_user2,0, wx.wxEXPAND)
     381                  self.sizer_line7_right.AddSizer(self.sizer_line7_user3,0, wx.wxEXPAND)
     382
     383
     384                  self.sizer_line7.Add(self.lbl_org_memo,4, wx.wxEXPAND| wx.wxALIGN_CENTER_VERTICAL,5)
     385                  self.sizer_line7.Add(self.txt_org_memo,40, wx.wxEXPAND)
     386                  if wx.wxPlatform == '__WXMAC__':
     387                          self.sizer_line7.Add((0,0),4)
     388                  else:
     389                          self.sizer_line7.Add(0,0,4)
     390                  self.sizer_line7.AddSizer(self.sizer_line7_right,44, wx.wxEXPAND)
     391                  self.nextsizer=  wx.wx.BoxSizer(wx.wx.VERTICAL)
     392                  self.nextsizer.Add(self.list_organisations,3, wx.wxEXPAND)
     393                  if wx.wxPlatform == '__WXMAC__':
     394                          self.nextsizer.Add((0,10),0)
     395                  else:
     396                          self.nextsizer.Add(0,10,0)
     397                  self.nextsizer.Add(self.sizer_line0,0, wx.wxEXPAND)
     398                  self.nextsizer.Add(self.sizer_line1,0, wx.wxEXPAND)
     399                  self.nextsizer.Add(self.sizer_line1a,0, wx.wxEXPAND)
     400                  self.nextsizer.Add(self.sizer_line2,0, wx.wxEXPAND)
     401                  self.nextsizer.Add(self.sizer_line3,0, wx.wxEXPAND)
     402                  self.nextsizer.Add(self.sizer_line4,0, wx.wxEXPAND)
     403                  self.nextsizer.Add(self.sizer_line5,0, wx.wxEXPAND)
     404                  self.nextsizer.Add(self.sizer_line6,0, wx.wxEXPAND)
     405                  self.nextsizer.Add(self.sizer_line7,0, wx.wxEXPAND)
     406                  self.mainsizer = wx.wx.BoxSizer(wx.wx.VERTICAL)
     407                  self.mainsizer.AddSizer(self.nextsizer,1, wx.wxEXPAND| wx.wxALL,10)
     408                  self.SetSizer(self.mainsizer)
     409                  self.mainsizer.Fit
     410                  self.SetAutoLayout(True)
     411                  self.Show(True)
     412
     413 -        def _set_controller(self, helper = cOrgHelperImpl3() ):
     414                  """Initialises the controller for this widget.
     415                  _helper is the orgHelper() that creates org instances, and finds many orgs.
     416                  _current is the current org being edited, or the parent of the current person.
     417                  _currentPerson is the current person being edited, or None.
     418                  _isPersonIndex is used by the list control selection handler to determine
     419                  if a row selected returns the id of a org, or an id of a person. Since
     420                  org and person are stored on different tables, the id itself cannot distinguish the item, and list data only stores an integer . Therefore the row position in the
     421                  list control maps to a person if it is a key in _isPersonIndex, and
     422                  the mapped object  is a OrgDemographicAdapter instance , which is
     423                  a cDemographicRecord wrapped in cOrg clothing, the intention being
     424                  to minimize re-write of gmContact's controller code.
     425                  self._tmpPerson maps the persons found in _isPersonIndex, so that
     426                  the person objects can be re-used when list_all_orgs is called, and
     427                  substituted for persons followed from org.getPersonMap() ,
     428                  for each org retrieved by _helper.findAllOrganizations().
     429                  ( orgHelperImpl2 will return orgs in parent/child order).
     430                  ( orgHelperImpl3 extends orgHelperImpl2 to provides creation of
     431                  person OrgDemographicAdapter,
     432                  and type testing a cOrg to see if it is a cPerson ).
     433
     434                  """
     435
     436                  self._connect_list()
     437                  self._helper = helper
     438                  self._current = None
     439
     440                  self._isPersonIndex = {}
     441                  self._tmpPerson = {}
     442                  self._currentPerson = None
     443                  self._cutPerson = None
     444
     445                  self._connectCutPaste()
     446
     447                  self._lastSelected = None # for internal cut and paste
     448
     449                  self._lastItemIndex = 0
     450
     451                  self._connectDrag()
     452
     453
     454 -        def getLastSelected(self):
     455                  return self._lastSelected
     456
     457 -        def setLastSelected(self, obj):
     458                  self._lastSelected = obj
     459
     460
     461 -        def _connectDrag(self):
     462                  wx.wx.EVT_LIST_BEGIN_DRAG(self.list_organisations, self.list_organisations.GetId(), self._doDrag)
     463
     464 -        def _doDrag(self, event):
     465                  dragSource = wx.wxDropSource(self)
     466                  text = self._getClipDragTextDataObject()
     467                  if text:
     468                          dragSource.SetData(text)
     469
     470                          result = dragSource.DoDragDrop(True)
     471                          if result == wx.wxDragCopy: print "drag copy action"
     472                          elif result == wx.wxDragMove: print "drag move action"
     473
     474
     475 -        def _connectCutPaste(self):
     476                  wx.wx.EVT_KEY_DOWN(self.list_organisations, self._checkForCutPaste)
     477
     478 -        def _checkForCutPaste(self, keyEvent):
     479                  #print "control down is ", keyEvent.ControlDown()
     480                  #print "keyCode is ", keyEvent.GetKeyCode()
     481                  c = keyEvent.GetKeyCode()
     482                  if keyEvent.ControlDown():
     483                          print c
     484                          if c == 88 : # ascii('x')
     485                                  print "cut"
     486                                  self._cutPerson = self.getLastSelected()
     487                                  self._doCopyToClipboard() # experiment with wx.wxClipboard
     488                          elif c == 86: # ascii('v')
     489                                  print "paste"
     490                                  self.doPaste()
     491                  keyEvent.Skip()
     492
     493 -        def doPaste(self):
     494                  if self.getCurrent() != None and self._cutPerson != None:
     495                          p = self._cutPerson
     496                          o = p.getParent()
     497                          o.unlinkPerson(p.getDemographicRecord() )
     498                          self.getCurrent().linkPerson(p.getDemographicRecord())
     499                          p.setParent(self.getCurrent())
     500
     501                          self.load_all_orgs()
     502
     503                          self._cutPerson = None
     504                          self.setLastSelected(None)
     505
     506
     507 -        def _doCopyToClipboard(self):
     508
     509                  board = wx.wx.TheClipboard
     510                  if not board.Open():
     511                          print "unable to get ownership of clipboard yet."
     512                          return False
     513                  text = self._getClipDragTextDataObject()
     514                  if text:
     515                          board.SetData(text )
     516                  board.Close()
     517
     518 -        def _getClipDragTextDataObject(self):
     519                  p = self.getLastSelected()
     520                  if p is None:
     521                          p = self.getCurrent()
     522                          if p is None:
     523                                  #<DEBUG>
     524                                  print "No current org or person to copy to clipboard"
     525                                  #</DEBUG>
     526                                  return None
     527                  return wx.wx.TextDataObject( p.getHelper().getClipboardText(p) )
     528
     529 -        def _connect_list(self):
     530                  """allow list selection to update the org edit area"""
     531                  wx.wx.EVT_LIST_ITEM_SELECTED(self.list_organisations, self.list_organisations.GetId(), self._orgperson_selected)
     532
     533 -        def __urb_selected(self, id):
     534                  self.input_field['postcode'].SetValue (gmOrganization.getPostcodeForUrbId(id))
     535                  self.input_field['postcode'].input_was_selected= 1
     536
     537 -        def get_address_values(self):
     538                  """from the street urb, postcode field, return number, street, urb, postcode list"""
     539                  f = self.input_fields
     540                  vals = [ f[n].GetValue() for n in ['street', 'urb', 'postcode'] ]
     541                  # split the street value into 2 parts, number and street. ? Have a separate number field instead.
     542                  addr = [ vals[0].split(' ')[0] , ' '.join( vals[0].split(' ')[1:] ) ] + vals[1:] + [None,None]
     543                  # [None, None] is region and country at the moment
     544                  return addr
     545
     546 -        def get_org_values(self):
     547                  """returns a dictionary of the widget controls contents"""
     548                  f = self.input_fields
     549
     550                  m =dict(  [ (n,f[n].GetValue()) for n in ['name','office', 'subtype', 'memo', 'category', 'phone', 'fax', 'email', 'mobile'] ] )
     551                  return m
     552
     553
     554 -        def add_org(self, org, showPersons = True):
     555                  """display an org in the list control, and show any dependent persons if
     556                  necessary."""
     557                  key, data = self.getOrgKeyData(org)
     558                  if key is None:
     559                          return
     560                  x = self.list_organisations.GetItemCount()
     561                  self._insert_org_data( x, key, data)
     562
     563                  if showPersons:
     564                          m = org.getPersonMap(reload=False)
     565                          # create _isPersonIndex, which maps a row index to
     566                          # a tuple of a person and a person's parent org.
     567                          #
     568                          for id, demRecord in m.items():
     569                                  if demRecord.getID() in self._tmpPerson:
     570                                          person = self._tmpPerson[demRecord.getID()]
     571                                  else:
     572                                          person = self._helper.createOrgPerson()
     573                                          person.setDemographicRecord(demRecord)
     574
     575                                  key, data = self.getOrgKeyData(person)
     576                                  ix = self.list_organisations.GetItemCount()
     577                                  self._insert_org_data(ix, key, data)
     578                                  person.setParent(org)
     579                                  self._isPersonIndex[ix] = person
     580
     581
     582
     583 -        def update_org(self, org):
     584                  """displays an org without reloading it. It is added to the end of a display list, currently, without attention to it's position in a contact tree. Use load_all_orgs()
     585                  is preferable, as it uses org's cached in the orgHelper, and person's cached
     586                  in self._tmpPerson.
     587                  """
     588                  key, data = self.getOrgKeyData(org)
     589                  if key is None:
     590                          return
     591
     592                  l = self.list_organisations
     593                  max = l.GetItemCount()
     594
     595                  for n in range( 0, max):
     596                          isPerson = self._helper.isPerson(org)
     597                          if l.GetItemData(n) == key and (
     598                          (not isPerson and n not in self._isPersonIndex )
     599                                  or (isPerson and n in self._isPersonIndex )  ):
     600                                  break
     601
     602                  if n == max:
     603                          self._insert_org_data(n, key, data)
     604                  else:
     605                          self._update_org_data(n, key, data)
     606
     607
     608 -        def getOrgKeyData(self, org):
     609                  """Converts org to data items for displaying in list control.
     610                  Rules are specific , and defined in original example gmContacts data
     611                  """
     612                  try:
     613                          key = int(org.getId())
     614                  except Exception:
     615                          print "org has no key. ? Failure in saving org ? non-existent org category"
     616                          print "if testing, try insert org_category(description) values('hospital')"
     617                          print "in a admin psql session, substitute 'hospital' for whatever category"
     618
     619                          gmLog.gmDefLog.LogException("failed to save org %s with id %s" %(org['name'], str(org.getId()) ) , sys.exc_info() )
     620                          return None, None
     621
     622
     623                  o = org.get()
     624
     625
     626                  phone_fax = '/fax '.join([ o.get('phone', '') , o.get('fax', '')]  )
     627                  address_str = org.getHelper().getAddressStr(org)
     628
     629                  # display for person
     630                  if org.getHelper().isPerson(org):
     631                          return key, ["", "- " + o['name'], o['subtype'], o.get('email',''), phone_fax]
     632
     633                  # display for top level org
     634                  elif org.getParent() is None:
     635                          return key, [o['name'], '', address_str,  o['category'], phone_fax]
     636
     637                  # display  branch, department , division
     638                  return key, ["", ' '.join([o.get('name',''), o.get('subtype','')]),address_str, o.get('email',''), phone_fax]
     639
     640
     641
     642 -        def _insert_org_data(self, n, key, data):
     643                  self.list_organisations.InsertItem(n, data[0])
     644                  self.list_organisations.SetItem(n, 1, data[1])
     645                  self.list_organisations.SetItem(n, 2, data[2])
     646                  self.list_organisations.SetItem(n, 3, data[3])
     647                  self.list_organisations.SetItem(n, 4, data[4])
     648                  self.list_organisations.SetItemData(n, key)
     649
     650
     651 -        def _update_org_data( self, n, key, data):
     652                  l = self.list_organisations
     653                  for i in range(0, 4):
     654                          l.SetItem(i, data[i])
     655                  l.SetItemData(n, key)
     656
     657
     658 -        def load_all_orgs(self):
     659                  """clears the list control, displays the example data, and then
     660                  the real data, from _helper.findAllOrganizations() """
     661                  #pos = self.list_organisations.GetScrollPos(wx.wx.VERTICAL)
     662                  self.list_organisations.DeleteAllItems()
     663                  #self._insert_example_data()   , removing this as it is confusing
     664                  if self._isPersonIndex != {}:
     665                          self._tmpPerson = {}
     666                          for person  in self._isPersonIndex.values():
     667                                  self._tmpPerson[person.getId()] = person
     668                          self._isPersonIndex = {}
     669
     670                  orgs = self.getOrgHelper().findAllOrganizations()
     671                  for org in orgs:
     672                          self.add_org(org)
     673
     674                  #self.list_organisations.SetScrollPos(wx.wx.VERTICAL, pos)
     675                  #self.list_organisations.Refresh()
     676                  self._ensureCurrentVisible()
     677
     678 -        def _ensureCurrentVisible(self):
     679                  l = self.list_organisations
     680                  person = self._currentPerson or self._cutPerson
     681                  print "person ", person, "self._cutPerson", self._cutPerson
     682
     683                  if person:
     684                          key = person.getId()
     685                          for i, p in self._isPersonIndex.items():
     686                                  if p.getId() == person.getId():
     687                                          break
     688                  elif self.getCurrent() is None:
     689                                  return
     690                  else:
     691
     692                          c = l.GetItemCount()
     693                          key = self.getCurrent().getId()
     694                          i , nexti = 0, -1
     695                          while  nexti != i and (i < l.GetItemCount() or i in self._isPersonIndex):
     696                                  i = nexti
     697                                  nexti = l.FindItemData(i, key)
     698                                  #print i
     699
     700                  for j in range(0, 2):
     701                          if i + 1 < l.GetItemCount():
     702                                  i += 1
     703
     704                  l.EnsureVisible(i)
     705
     706 -        def _insert_example_data(self):
     707                  items = organisationsdata.items()
     708                  for i in range(0,len(items)):
     709                          key, data = items[i]
     710                          self._insert_org_data(i, key, data)
     711
     712 -        def _orgperson_selected(self, event):
     713                  """handle list control selection event, passing to _person_selected(row index)
     714                  if it is a person displayed at the row index, or using self._helper.getFromCache
     715                  to retrieve the previously cached org by the key stored in the list item data."""
     716
     717                  ix = event.GetIndex()
     718                  key = self.list_organisations.GetItemData(ix)
     719
     720                  self.setLastSelected(None)  # clear the last selected person.
     721
     722                  if ix in self._isPersonIndex:
     723                          self._person_selected( self._isPersonIndex[ix])
     724                          return
     725                  else:
     726                          self._currentPerson = None
     727
     728                  org = self._helper.getFromCache(key)
     729                  self.clearForm()
     730                  if org == None:
     731                          """this block is mainly used to parse the example data.
     732                          It is probably not needed, in usage , as all data from the
     733                          database will be in the helper cache.
     734                          """
     735                          org = self._helper.create()
     736                          data = [ self.list_organisations.GetItem(ix,n).GetText() for n in range(0,5) ]
     737
     738                          org['name'] = data[0].strip()
     739                          org['subtype'] = data[1].strip()
     740                          j = 1
     741                          while org['name'] == '' and j <= ix:
     742                                  org['name'] = self.list_organisations.GetItem(ix-j, 0).GetText().strip()
     743                                  j += 1
     744
     745                          if org['subtype'] != '':
     746                                  org.setParent( org.getHelper().findOrgsByName(org['name'])[0] )
     747
     748                          #TODO remove this test filter
     749                          if  data[3].lower().find('hospital') >= 0:  data[3] = 'hospital'
     750
     751                          org['category'] = data[3]
     752                          org['phone'] = data[4]
     753
     754                          try:
     755                                  l = data[2].split(' ')
     756                                  # if no numerals in first token assume no address number
     757                                  if l[0].isalpha():
     758                                          l = [''] + l
     759                                  # if no numerals in last token asssume no postcode
     760                                  if l[-1].isalpha():
     761                                          l.append('')
     762                                  urb_start_idx = -2
     763
     764                                  # scan back , UPPERCASE words assumed to be part of suburb name
     765                                  while urb_start_idx > -len(l) and l[urb_start_idx-1].isupper():
     766                                          urb_start_idx -= 1
     767                                  if len (l) >= 4:
     768                                          number , street, urb, postcode = l[0], ' '.join(l[1:urb_start_idx]), ' '.join(l[urb_start_idx:-1]), l[-1]
     769                                          org.setAddress( number, street, urb, postcode, None, None )
     770                          except Exception:
     771                                  gmLog.gmDefLog.LogException("Unable to parse address", sys.exc_info() )
     772                                  print "unable to parse address"
     773
     774                  self.setCurrent(org)
     775                  self.checkEnabledFields()
     776                  self.loadCurrentValues(org)
     777
     778 -        def loadCurrentValues(self, org):
     779                  """parse an org into the edit widgets of gmContact"""
     780                  f = self.input_fields
     781                  for n in ['name','subtype', 'category', 'phone', 'email', 'fax', 'mobile']:
     782                          v = org[n]
     783                          if v == None: v = ''
     784                          f[n].SetValue(v.strip())
     785
     786                  a = org.getAddress()
     787                  s = a.get('number','').strip() + ' ' + a.get('street','').strip()
     788                  f['street'] .SetValue(s.strip())
     789                  f['urb'] .SetValue(a.get('urb','').strip() )
     790                  f['postcode'] .SetValue( str(a.get('postcode','')).strip())
     791
     792
     793
     794 -        def setCurrent(self, org):
     795                  self._current = org
     796
     797
     798 -        def getCurrent(self):
     799                  return self._current
     800
     801 -        def getOrgHelper(self):
     802                  return  self._helper
     803
     804 -        def newOrg(self, parent = None):
     805                  self._currentPerson = None
     806                  self.setCurrent(self._helper.create())
     807                  self.getCurrent().setParent(parent)
     808                  self.newForm()
     809
     810 -        def newForm(self):
     811                  self.clearForm()
     812                  self.checkEnabledFields()
     813
     814 -        def clearForm(self):
     815                  for k,f in self.input_fields.items():
     816                          f.SetValue('')
     817
     818 -        def checkEnabledFields(self):
     819                  """configure the edit widgets according to the type of org/person object"""
     820                  if not self._currentPerson is None:
     821                          self.lbl_Type.SetLabel(_('occupation'))
     822                          self._loadOccupations()
     823                          parent = self.getCurrent()
     824                          self.input_fields['name'].SetToolTip(wx.wx.ToolTip("'Title. first LAST-IN-CAPITAL',   or \n'Title. Last, first' \n- the dot is required to separate title; comma indicates the order of the names is last names, first names.") )
     825                  else:
     826                          self.lbl_Type.SetLabel(_('subdivision'))
     827                          self._loadDivisionTypes()
     828                          parent = self.getCurrent().getParent()
     829                          self.input_fields['name'].SetToolTip(wx.wx.ToolTip("The organization's name." ) )
     830
     831
     832                  dependent = not parent is None
     833                  if dependent:
     834                          self.input_fields['category'].SetValue(parent['category'])
     835                  self.input_fields['category'].Enable(not dependent)
     836
     837 -        def _loadOccupations(self):
     838                  f = self.input_fields['subtype']
     839                  f.Clear()
     840                  cats = cCatFinder('occupation', 'id','name').getCategories('occupation')
     841                  for x in cats:
     842                          f.Append(x)
     843
     844 -        def _loadDivisionTypes(self):
     845                  f = self.input_fields['subtype']
     846                  f.Clear()
     847                  for n in divisionTypes:
     848                          f.Append(n)
     849
     850
     851 -        def saveOrg(self):
     852                  """transfer the widget's edit controls to a org/person object, and
     853                  call its save() function, then reload all the orgs, and their persons, from the cache.
     854                  The save() function will update the cache if this is  a newly created
     855                  org/person."""
     856
     857                  if  not self._currentPerson is None:
     858                          org = self._currentPerson
     859                          org.setParent(self.getCurrent()) # work out how to reference parents
     860                                                          # within org cache
     861                  else:
     862                          org= self.getCurrent()
     863
     864                  if org is None:
     865                          """this block is unlikely, but there must be an org to work on."""
     866                          org = self.getOrgHelper().create()
     867                          self.setCurrent(org)
     868
     869
     870                  o = self.get_org_values()
     871                  a = self.get_address_values()
     872                  org.set(*[],**o)
     873                  #<DEBUG>
     874                  print "setting address with ", a
     875                  #</DEBUG>
     876                  org.setAddress(*a)
     877
     878                  isNew = org.getId() is None
     879                  org.save()
     880                  self.load_all_orgs()
     881
     882                  #if isNew:
     883                  #       self.add_org(org)
     884                  #else:
     885                  #               self.update_org(org) # refresh after saving
     886
     887
     888
     889 -        def isPersonCurrent(self):
     890                  return not self._currentPerson is None
     891
     892 -        def newPerson(self):
     893                  if self.getCurrent() is None or self.getCurrent().getId() is None:
     894                          print "Org must exist to add a person"
     895                          return False
     896                  self._currentPerson =  self.getOrgHelper().createOrgPerson()
     897                  self._currentPerson.setParent(self.getCurrent() )
     898                  self.newForm()
     899                  return True
     900
     901 -        def _person_selected(self, person):
     902                  """set the widget's state for person editing"""
     903                  self.clearForm()
     904                  self.setCurrent(person.getParent() )
     905                  self._currentPerson = person
     906                  self.checkEnabledFields()
     907                  self.loadCurrentValues(person)
     908
     909                  self.setLastSelected(person)
     910
     911
     912
     913 -class gmContacts (gmPlugin.cNotebookPluginOld):
     914          tab_name = _("Contacts")
     915
     916 -        def name (self):
     917                  return gmContacts.tab_name
     918
     919 -        def GetWidget (self, parent):
     920                  self._last_widget = cContactsPanel (parent, -1)
     921                  return self._last_widget
     922
     923 -        def MenuInfo (self):
     924                  return ('view', _('&Contacts'))
     925
     926 -        def populate_toolbar (self, tb, widget):
     927                  tool1 = tb.AddTool(ID_SEARCHGLOBAL, images_contacts_toolbar16_16.getfind_globalBitmap(),
     928                                          shortHelpString=_("Global Search Of Contacts Database"), isToggle=False)
     929                  tb.AddControl(wx.wx.TextCtrl(tb, ID_SEARCHGLOBAL, name ="txtGlobalSearch",size =(100,-1),style = 0, value = ''))
     930                  tool1 = tb.AddTool(ID_ORGANISATIONDISPLAY, images_contacts_toolbar16_16.getorganisationBitmap(),
     931                                          shortHelpString="Display Organisations",)
     932                  tool1 = tb.AddTool(ID_GENERALPRACTICESDISPLAY, images_contacts_toolbar16_16.getgeneralpracticesBitmap(),
     933                                          shortHelpString="Display General Practices",)
     934                  tool1 = tb.AddTool(ID_DOCTORSDISPLAY, images_contacts_toolbar16_16.getdoctorBitmap(),
     935                                          shortHelpString="Display Doctors",)
     936                  tool1 = tb.AddTool(ID_PERSONSDISPLAY, images_contacts_toolbar16_16.getpersonBitmap(),
     937                                          shortHelpString="Display Persons", isToggle=False)
     938                  tool1 = tb.AddTool(ID_ORGANISATIONADD, images_contacts_toolbar16_16.getorganisation_addBitmap(),
     939                                          shortHelpString="Add an Organisation",)
     940
     941                  tool1 = tb.AddTool(ID_SAVE, images_contacts_toolbar16_16.getsaveBitmap(),
     942                                          shortHelpString="Save Record",)
     943                  tool1 = tb.AddTool(ID_BRANCHDEPTADD, images_contacts_toolbar16_16.getbranch_addBitmap(),
     944                                          shortHelpString="Add Branch or Department",)
     945                  tool1 = tb.AddTool(ID_EMPLOYEEADD, images_contacts_toolbar16_16.getemployeesBitmap(),
     946                                          shortHelpString="Add an Employee",)
     947                  tool1 = tb.AddTool(ID_PERSONADD, images_contacts_toolbar16_16.getperson_addBitmap(),
     948                                          shortHelpString="Add Person",)
     949                  #tb.AddControl(wx.wxStaticBitmap(tb, -1, images_contacts_toolbar16_16.getvertical_separator_thinBitmap(), wx.wxDefaultPosition, wx.wxDefaultSize))
     950
     951
     952                  tb.AddControl(wx.wxStaticBitmap(tb, -1, images_contacts_toolbar16_16.getvertical_separator_thinBitmap(), wx.wxDefaultPosition, wx.wxDefaultSize))
     953
     954                  tool1 = tb.AddTool(ID_RELOAD, images_contacts_toolbar16_16.getreloadBitmap(),
     955                                          shortHelpString="Refresh Display",)
     956
     957                  tb.AddControl(wx.wxStaticBitmap(tb, -1, images_contacts_toolbar16_16.getvertical_separator_thinBitmap(), wx.wxDefaultPosition, wx.wxDefaultSize))
     958
     959                  tool1 = tb.AddTool(ID_SEARCHSPECIFIC, images_contacts_toolbar16_16.getfind_specificBitmap(),
     960                                          shortHelpString="Find Specific Records in Contacts Database",)
     961                  tool1 = tb.AddTool(ID_SORTA_Z, images_contacts_toolbar16_16.getsort_A_ZBitmap(),
     962                                          shortHelpString="Sort A to Z",)
     963                  tool1 = tb.AddTool(ID_SORTZ_A, images_contacts_toolbar16_16.getsort_Z_ABitmap(),
     964                                          shortHelpString="Sort Z to A",)
     965                  tool1 = tb.AddTool(ID_SENDEMAIL, images_contacts_toolbar16_16.getsendemailBitmap(),
     966                                          shortHelpString="Send Email",)
     967                  tool1 = tb.AddTool(ID_LINKINTERNET, images_contacts_toolbar16_16.getearthBitmap(),
     968                                          shortHelpString="Load Web Address",)
     969                  tool1 = tb.AddTool(ID_INSTANTREPORT, images_contacts_toolbar16_16.getlighteningBitmap(),
     970                                          shortHelpString="Instant Report from Grid",)
     971                  tool1 = tb.AddTool(ID_REPORTS, images_contacts_toolbar16_16.getreportsBitmap(),
     972                                          shortHelpString="Pre-formatted reports",)
     973
     974                  self.__connect_commands(tb)
     975
     976 -        def __connect_commands(self, toolbar):
     977                  wx.wx.EVT_TOOL(toolbar, ID_ORGANISATIONADD , self.addOrg)
     978                  wx.wx.EVT_TOOL(toolbar, ID_EMPLOYEEADD, self.addEmployee)
     979                  wx.wx.EVT_TOOL(toolbar ,ID_BRANCHDEPTADD , self.addBranchDept)
     980                  wx.wx.EVT_TOOL(toolbar, ID_ORGANISATIONDISPLAY, self.displayOrg)
     981                  wx.wx.EVT_TOOL(toolbar, ID_SAVE, self.saveOrg)
     982
     983 -        def addEmployee(self, event):
     984                  print "doEmployeeAdd"
     985                  w = self._last_widget
     986                  w.newPerson()
     987
     988 -        def addOrg(self, event):
     989                  print "doOrgAdd"
     990                  w = self._last_widget
     991                  w.newOrg()
     992
     993
     994 -        def saveOrg(self, event):
     995                  w = self._last_widget
     996                  w.saveOrg()
     997
     998
     999
    1000 -        def addBranchDept(self, event):
    1001                  print "doBranchDeptAdd"
    1002                  w = self._last_widget
    1003                  parent = w.getCurrent()
    1004                  if parent is None:
    1005                          print "No parent org for sub org"
    1006                          return
    1007
    1008                  if parent.getId() is None:
    1009                          print "Please save parent org first"
    1010                          return
    1011
    1012                  if not parent.getParent() is None:
    1013                          print "Only one level of sub-org implemented"
    1014                          return
    1015
    1016                  w.newOrg(parent)
    1017
    1018
    1019
    1020
    1021
    1022 -        def displayOrg(self, event):
    1023                  w = self._last_widget
    1024                  w.load_all_orgs()
    1025
    1026
    1027
    1028  if __name__ == "__main__":
    1029          app = wx.wxPyWidgetTester(size = (800, 600))
    1030          app.SetWidget(cContactsPanel, -1)
    1031          app.MainLoop()
    1032
    1033  #======================================================
    1034