| Home | Trees | Indices | Help |
|
|---|
|
|
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 #--------------------------------------------------
78
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 #------------------------------------------------------------
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,''))
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
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
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
456
459
460
462 wx.wx.EVT_LIST_BEGIN_DRAG(self.list_organisations, self.list_organisations.GetId(), self._doDrag)
463
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
477
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
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
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
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
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
534 self.input_field['postcode'].SetValue (gmOrganization.getPostcodeForUrbId(id))
535 self.input_field['postcode'].input_was_selected= 1
536
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
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
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
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
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:
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
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
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
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
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
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
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:
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
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
795 self._current = org
796
797
800
803
805 self._currentPerson = None
806 self.setCurrent(self._helper.create())
807 self.getCurrent().setParent(parent)
808 self.newForm()
809
813
817
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
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
849
850
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
891
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
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
914 tab_name = _("Contacts")
915
918
922
925
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
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
987
992
993
997
998
999
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
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
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Fri Jan 25 02:55:27 2019 | http://epydoc.sourceforge.net |