1
2 """
3 Sample App to illustrate table functionality.
4 Created January 2008
5 Copyright (C) Damien Farrell
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 """
21
22 from Tkinter import *
23 import Pmw
24 import tkFileDialog, tkMessageBox, tkSimpleDialog
25 import re
26 import os
27 import time
28 import pickle
29 from Custom import MyTable
30 from TableModels import TableModel
31 from Tables_IO import TableImporter
32 from Prefs import Preferences
33
35 """
36 Tables app
37 """
38 - def __init__(self,parent=None,data=None,datafile=None):
39 "Initialize the application."
40 self.parent=parent
41
42
43 if not self.parent:
44 Frame.__init__(self)
45 self.tablesapp_win=self.master
46
47 else:
48 self.tablesapp_win=Toplevel()
49
50
51 import platform
52 self.currplatform=platform.system()
53 if not hasattr(self,'defaultsavedir'):
54 self.defaultsavedir = os.getcwd()
55
56 self.preferences=Preferences('TablesApp',{'check_for_update':1})
57 self.loadprefs()
58 self.tablesapp_win.title('Tables Application')
59 self.tablesapp_win.geometry('+200+200')
60 self.x_size=800
61 self.y_size=600
62 self.createMenuBar()
63 self.apptoolBar = ToolBar(self.tablesapp_win, self)
64 self.apptoolBar.pack(fill=BOTH, expand=NO)
65
66
67
68 if data != None:
69 self.data = data
70 self.new_project(data)
71 elif datafile != None:
72 self.open_project(datafile)
73 else:
74 self.new_project()
75
76 self.tablesapp_win.protocol('WM_DELETE_WINDOW',self.quit)
77 return
78
80 """Create the menu bar for the application. """
81 self.menu=Menu(self.tablesapp_win)
82 self.proj_menu={'01New':{'cmd':self.new_project},
83 '02Open':{'cmd':self.open_project},
84 '03Close':{'cmd':self.close_project},
85 '04Save':{'cmd':self.save_project},
86 '05Save As':{'cmd':self.save_as_project},
87 '06Preferences..':{'cmd':self.showPrefsDialog},
88 '08Quit':{'cmd':self.quit}}
89 if self.parent:
90 self.proj_menu['08Return to Database']={'cmd':self.return_data}
91 self.proj_menu=self.create_pulldown(self.menu,self.proj_menu)
92 self.menu.add_cascade(label='Project',menu=self.proj_menu['var'])
93
94 self.records_menu={'01Add Row':{'cmd':self.add_Row},
95 '02Delete Row':{'cmd':self.delete_Row},
96 '03Add Column':{'cmd':self.add_Column},
97 '04Delete Column':{'cmd':self.delete_Column},
98 '05Auto Add Rows':{'cmd':self.autoAdd_Rows},
99 '06Auto Add Columns':{'cmd':self.autoAdd_Columns},
100 '07Find':{'cmd':self.createSearchBar},
101 }
102 self.records_menu=self.create_pulldown(self.menu,self.records_menu)
103 self.menu.add_cascade(label='Records',menu=self.records_menu['var'])
104
105 self.sheet_menu={'01Add Sheet':{'cmd':self.add_Sheet},
106 '02Remove Sheet':{'cmd':self.delete_Sheet},
107 '03Copy Sheet':{'cmd':self.copy_Sheet},
108 '04Rename Sheet':{'cmd':self.rename_Sheet},
109 }
110 self.sheet_menu=self.create_pulldown(self.menu,self.sheet_menu)
111 self.menu.add_cascade(label='Sheet',menu=self.sheet_menu['var'])
112
113 self.IO_menu={'01Import from csv file':{'cmd':self.import_cvs},
114 '02Export to csv file':{'cmd':self.export_cvs},
115 }
116
117 self.IO_menu=self.create_pulldown(self.menu,self.IO_menu)
118 self.menu.add_cascade(label='Import/Export',menu=self.IO_menu['var'])
119
120
121 self.view_menu = Menu(self.menu, tearoff=0)
122 self.view_menu.add_radiobutton(label="Normal View", state=ACTIVE,command=self.normal_view)
123 self.view_menu.add_radiobutton(label="Page View", command=self.page_view)
124 self.menu.add_cascade(label='View',menu=self.view_menu)
125
126
127
128
129 self.help_menu={'01Online Help':{'cmd':self.online_documentation},
130 '02About':{'cmd':self.about_Tables}}
131 self.help_menu=self.create_pulldown(self.menu,self.help_menu)
132 self.menu.add_cascade(label='Help',menu=self.help_menu['var'])
133
134 self.tablesapp_win.config(menu=self.menu)
135
136 return
137
139
140
141
142 var=Menu(menu,tearoff=0)
143 items=dict.keys()
144 items.sort()
145 for item in items:
146 if item[-3:]=='sep':
147 var.add_separator()
148 else:
149
150
151
152 command=None
153 if dict[item].has_key('cmd'):
154 command=dict[item]['cmd']
155
156
157
158 if dict[item].has_key('sc'):
159 var.add_command(label='%-25s %9s' %(item[2:],dict[item]['sc']),command=command)
160 else:
161 var.add_command(label='%-25s' %(item[2:]),command=command)
162 dict['var']=var
163 return dict
164
166 """Add a find entry box"""
167 frame = Frame(self.tablesapp_win)
168 row=0
169 def close():
170 frame.destroy()
171 self.findtext=StringVar()
172 self.findbox=Entry(frame,textvariable=self.findtext,width=30,bg='white')
173 self.findbox.grid(row=row,column=1,sticky='news',columnspan=2,padx=2,pady=2)
174 self.findbox.bind('<Return>',self.do_find_text)
175 Label(frame,text='Find:').grid(row=row,column=0,sticky='ew')
176 self.findagainbutton=Button(frame,text='Find Again', command=self.do_find_again)
177 self.findagainbutton.grid(row=row,column=3,sticky='news',padx=2,pady=2)
178 self.cbutton=Button(frame,text='Close', command=close)
179 self.cbutton.grid(row=row,column=4,sticky='news',padx=2,pady=2)
180 frame.pack(fill=BOTH, expand=NO)
181 return
182
183
185 """Setup default prefs file if any of the keys are not present"""
186 defaultprefs = {'textsize':14,
187 'windowwidth': 800 ,'windowheight':600}
188 for prop in defaultprefs.keys():
189 try:
190 self.preferences.get(prop)
191 except:
192 self.preferences.set(prop, defaultprefs[prop])
193
194 return
195
197 self.prefswindow = self.currenttable.showtablePrefs()
198
199 return
200
201
203 """Create a new table, with model and add the frame"""
204 if hasattr(self,'currenttable'):
205 self.notebook.destroy()
206 self.currenttable.destroy()
207
208
209 self.sheets = {}
210 self.notebook = Pmw.NoteBook(self.tablesapp_win, raisecommand=self.setcurrenttable)
211 self.notebook.pack(fill='both', expand=1, padx=4, pady=4)
212 if data !=None:
213 for s in data.keys():
214 sdata = data[s]
215 try:
216 self.add_Sheet(s ,sdata)
217 except:
218 print 'skipping'
219 else:
220
221 self.add_Sheet('sheet1')
222 self.notebook.setnaturalsize()
223 return
224
226 if filename == None:
227 filename=tkFileDialog.askopenfilename(defaultextension='.tbleprj"',
228 initialdir=os.getcwd(),
229 filetypes=[("Pickle file","*.tbleprj"),
230 ("All files","*.*")],
231 parent=self.tablesapp_win)
232 if os.path.isfile(filename):
233 fd=open(filename)
234 data=pickle.load(fd)
235 fd.close()
236 self.new_project(data)
237 self.filename=filename
238 return
239
249
251 """Save as a new filename"""
252 filename=tkFileDialog.asksaveasfilename(parent=self.tablesapp_win,
253 defaultextension='.tblprj',
254 initialdir=self.defaultsavedir,
255 filetypes=[("TableApp project","*.tblprj"),
256 ("All files","*.*")])
257 if not filename:
258 print 'Returning'
259 return
260 self.filename=filename
261 self.do_save_project(self.filename)
262 return
263
265 """Get model dicts and write all to pickle file"""
266 data={}
267 for s in self.sheets.keys():
268 currtable = self.sheets[s]
269 model = currtable.getModel()
270 data[s] = model.getData()
271
272 fd=open(filename,'w')
273 pickle.dump(data,fd)
274 fd.close()
275 return
276
278 if hasattr(self,'currenttable'):
279
280 self.currenttable.destroy()
281 return
282
296
301
302
303 - def add_Sheet(self, sheetname=None, sheetdata=None):
304 """Add a new sheet - handles all the table creation stuff"""
305 def checksheet_name(name):
306 if name == '':
307 tkMessageBox.showwarning("Whoops", "Name should not be blank.")
308 return 0
309 if self.sheets.has_key(name):
310 tkMessageBox.showwarning("Name exists", "Sheet name already exists!")
311 return 0
312 noshts = len(self.notebook.pagenames())
313 if sheetname == None:
314 sheetname = tkSimpleDialog.askstring("New sheet name?", "Enter sheet name:",
315 initialvalue='sheet'+str(noshts+1))
316 checksheet_name(sheetname)
317 page = self.notebook.add(sheetname)
318
319 if sheetdata != None:
320 model = TableModel(sheetdata)
321 self.currenttable = MyTable(page, model)
322 else:
323 self.currenttable = MyTable(page)
324
325
326 self.currenttable.loadPrefs(self.preferences)
327
328 self.currenttable.createTableFrame()
329
330 self.sheets[sheetname] = self.currenttable
331 self.saved = 0
332 return sheetname
333
335 """Delete a sheet"""
336 s = self.notebook.getcurselection()
337 self.notebook.delete(s)
338 del self.sheets[s]
339 return
340
342 """Copy a sheet"""
343 newdata = self.currenttable.getModel().getData().copy()
344 if newname==None:
345 self.add_Sheet(None, newdata)
346 else:
347 self.add_Sheet(newname, newdata)
348 return
349
351 """Rename a sheet"""
352 s = self.notebook.getcurselection()
353 newname = tkSimpleDialog.askstring("New sheet name?", "Enter new sheet name:",
354 initialvalue=s)
355 if newname == None:
356 return
357 self.copy_Sheet(newname)
358 self.delete_Sheet()
359 return
360
362 """Set the currenttable so that menu items work with visible sheet"""
363 try:
364 s = self.notebook.getcurselection()
365 self.currenttable = self.sheets[s]
366 except:
367 pass
368 return
369
371 """Add a new row"""
372 self.currenttable.add_Row()
373 self.saved = 0
374 return
375
377 """Delete currently selected row"""
378 self.currenttable.delete_Row()
379 self.saved = 0
380 return
381
383 """Add a new column"""
384 self.currenttable.add_Column()
385 self.saved = 0
386 return
387
389 """Delete currently selected column in table"""
390 self.currenttable.delete_Column()
391 self.saved = 0
392 return
393
395 """Auto add x rows"""
396 self.currenttable.autoAdd_Rows()
397 self.saved = 0
398 return
399
401 """Auto add x rows"""
402 self.currenttable.autoAdd_Columns()
403 self.saved = 0
404 return
405
409
410 - def do_find_text(self, event=None):
411 """Find the text in the table"""
412 if not hasattr(self,'currenttable'):
413 return
414 import string
415 if string.strip(self.findtext.get())=='':
416 return
417 searchstring=self.findtext.get()
418 if self.currenttable!=None:
419 self.currenttable.findValue(searchstring)
420 return
421
423 """Find again"""
424 if not hasattr(self,'currenttable'):
425 return
426 searchstring=self.findtext.get()
427 if self.currenttable!=None:
428 self.currenttable.findValue(searchstring, findagain=1)
429 return
430
431 - def plot(self, event=None):
432 self.currenttable.plot_Selected()
433 return
434
438
440 self.currenttable.paging_Off()
441 return
442
443 - def page_view(self,event=None):
444 self.currenttable.paging = 1
445 self.currenttable.redrawTable()
446 return
447
449 self.ab_win=Toplevel()
450 self.ab_win.geometry('+100+350')
451 self.ab_win.title('About TablesApp')
452
453 import Table_images
454 logo = Table_images.tableapp_logo()
455 label = Label(self.ab_win,image=logo)
456 label.image = logo
457 label.grid(row=0,column=0,sticky='news',padx=4,pady=4)
458
459 text=['Tables Sample App ','Shows the use of Tablecanvas class for tkinter',
460 'Copyright (C) Damien Farrell 2008', 'This program is free software; you can redistribute it and/or',
461 'modify it under the terms of the GNU General Public License',
462 'as published by the Free Software Foundation; either version 2',
463 'of the License, or (at your option) any later version.']
464 row=1
465 for line in text:
466 tmp=Label(self.ab_win,text=line)
467 tmp.grid(row=row,column=0,sticky='news',padx=4)
468 row=row+1
469 return
470
472 """Open the online documentation"""
473 import webbrowser
474 link='http://sourceforge.net/projects/tkintertable/'
475 webbrowser.open(link,autoraise=1)
476 return
477
479 self.tablesapp_win.destroy()
480
481 return
482
524
525
526
528 "Run the application"
529 import sys, os
530 from optparse import OptionParser
531 parser = OptionParser()
532 parser.add_option("-f", "--file", dest="tablefile",
533 help="Open a table file", metavar="FILE")
534 opts, remainder = parser.parse_args()
535 if opts.tablefile != None:
536 app=TablesApp(datafile=opts.tablefile)
537 else:
538 app=TablesApp()
539 app.mainloop()
540 return
541
542 if __name__ == '__main__':
543 main()
544