Gnumed.wxpython.gui.gmContacts

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

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

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