Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / devtools / amd64 / lib / python2.4 / site-packages / Pmw / Pmw_1_2 / contrib / PmwFileDialog.py
CommitLineData
920dae64
AT
1#
2__version__ = '$Id: PmwFileDialog.py,v 1.2 2002/08/23 15:03:35 gregm Exp $'
3#
4# Filename dialogs using Pmw
5#
6# (C) Rob W.W. Hooft, Nonius BV, 1998
7#
8# Modifications:
9#
10# J. Willem M. Nissink, Cambridge Crystallographic Data Centre, 8/2002
11# Added optional information pane at top of dialog; if option
12# 'info' is specified, the text given will be shown (in blue).
13# Modified example to show both file and directory-type dialog
14#
15# No Guarantees. Distribute Freely.
16# Please send bug-fixes/patches/features to <r.hooft@euromail.com>
17#
18################################################################################
19import os,fnmatch,time
20import Tkinter,Pmw
21#Pmw.setversion("0.8.5")
22
23def _errorpop(master,text):
24 d=Pmw.MessageDialog(master,
25 title="Error",
26 message_text=text,
27 buttons=("OK",))
28 d.component('message').pack(ipadx=15,ipady=15)
29 d.activate()
30 d.destroy()
31
32class PmwFileDialog(Pmw.Dialog):
33 """File Dialog using Pmw"""
34 def __init__(self, parent = None, **kw):
35 # Define the megawidget options.
36 optiondefs = (
37 ('filter', '*', self.newfilter),
38 ('directory', os.getcwd(), self.newdir),
39 ('filename', '', self.newfilename),
40 ('historylen',10, None),
41 ('command', None, None),
42 ('info', None, None),
43 )
44 self.defineoptions(kw, optiondefs)
45 # Initialise base class (after defining options).
46 Pmw.Dialog.__init__(self, parent)
47
48 self.withdraw()
49
50 # Create the components.
51 interior = self.interior()
52
53 if self['info'] is not None:
54 rowoffset=1
55 dn = self.infotxt()
56 dn.grid(row=0,column=0,columnspan=2,padx=3,pady=3)
57 else:
58 rowoffset=0
59
60 dn = self.mkdn()
61 dn.grid(row=0+rowoffset,column=0,columnspan=2,padx=3,pady=3)
62 del dn
63
64 # Create the directory list component.
65 dnb = self.mkdnb()
66 dnb.grid(row=1+rowoffset,column=0,sticky='news',padx=3,pady=3)
67 del dnb
68
69 # Create the filename list component.
70 fnb = self.mkfnb()
71 fnb.grid(row=1+rowoffset,column=1,sticky='news',padx=3,pady=3)
72 del fnb
73
74 # Create the filter entry
75 ft = self.mkft()
76 ft.grid(row=2+rowoffset,column=0,columnspan=2,padx=3,pady=3)
77 del ft
78
79 # Create the filename entry
80 fn = self.mkfn()
81 fn.grid(row=3+rowoffset,column=0,columnspan=2,padx=3,pady=3)
82 fn.bind('<Return>',self.okbutton)
83 del fn
84
85 # Buttonbox already exists
86 bb=self.component('buttonbox')
87 bb.add('OK',command=self.okbutton)
88 bb.add('Cancel',command=self.cancelbutton)
89 del bb
90
91 Pmw.alignlabels([self.component('filename'),
92 self.component('filter'),
93 self.component('dirname')])
94
95 def infotxt(self):
96 """ Make information block component at the top """
97 return self.createcomponent(
98 'infobox',
99 (), None,
100 Tkinter.Label, (self.interior(),),
101 width=51,
102 relief='groove',
103 foreground='darkblue',
104 justify='left',
105 text=self['info']
106 )
107
108 def mkdn(self):
109 """Make directory name component"""
110 return self.createcomponent(
111 'dirname',
112 (), None,
113 Pmw.ComboBox, (self.interior(),),
114 entryfield_value=self['directory'],
115 entryfield_entry_width=40,
116 entryfield_validate=self.dirvalidate,
117 selectioncommand=self.setdir,
118 labelpos='w',
119 label_text='Directory:')
120
121 def mkdnb(self):
122 """Make directory name box"""
123 return self.createcomponent(
124 'dirnamebox',
125 (), None,
126 Pmw.ScrolledListBox, (self.interior(),),
127 label_text='directories',
128 labelpos='n',
129 hscrollmode='none',
130 dblclickcommand=self.selectdir)
131
132 def mkft(self):
133 """Make filter"""
134 return self.createcomponent(
135 'filter',
136 (), None,
137 Pmw.ComboBox, (self.interior(),),
138 entryfield_value=self['filter'],
139 entryfield_entry_width=40,
140 selectioncommand=self.setfilter,
141 labelpos='w',
142 label_text='Filter:')
143
144 def mkfnb(self):
145 """Make filename list box"""
146 return self.createcomponent(
147 'filenamebox',
148 (), None,
149 Pmw.ScrolledListBox, (self.interior(),),
150 label_text='files',
151 labelpos='n',
152 hscrollmode='none',
153 selectioncommand=self.singleselectfile,
154 dblclickcommand=self.selectfile)
155
156 def mkfn(self):
157 """Make file name entry"""
158 return self.createcomponent(
159 'filename',
160 (), None,
161 Pmw.ComboBox, (self.interior(),),
162 entryfield_value=self['filename'],
163 entryfield_entry_width=40,
164 entryfield_validate=self.filevalidate,
165 selectioncommand=self.setfilename,
166 labelpos='w',
167 label_text='Filename:')
168
169 def dirvalidate(self,string):
170 if os.path.isdir(string):
171 return Pmw.OK
172 else:
173 return Pmw.PARTIAL
174
175 def filevalidate(self,string):
176 if string=='':
177 return Pmw.PARTIAL
178 elif os.path.isfile(string):
179 return Pmw.OK
180 elif os.path.exists(string):
181 return Pmw.PARTIAL
182 else:
183 return Pmw.OK
184
185 def okbutton(self):
186 """OK action: user thinks he has input valid data and wants to
187 proceed. This is also called by <Return> in the filename entry"""
188 fn=self.component('filename').get()
189 self.setfilename(fn)
190 if self.validate(fn):
191 self.canceled=0
192 self.deactivate()
193
194 def cancelbutton(self):
195 """Cancel the operation"""
196 self.canceled=1
197 self.deactivate()
198
199 def tidy(self,w,v):
200 """Insert text v into the entry and at the top of the list of
201 the combobox w, remove duplicates"""
202 if not v:
203 return
204 entry=w.component('entry')
205 entry.delete(0,'end')
206 entry.insert(0,v)
207 list=w.component('scrolledlist')
208 list.insert(0,v)
209 index=1
210 while index<list.index('end'):
211 k=list.get(index)
212 if k==v or index>self['historylen']:
213 list.delete(index)
214 else:
215 index=index+1
216 w.checkentry()
217
218 def setfilename(self,value):
219 if not value:
220 return
221 value=os.path.join(self['directory'],value)
222 dir,fil=os.path.split(value)
223 self.configure(directory=dir,filename=value)
224
225 c=self['command']
226 if callable(c):
227 c()
228
229 def newfilename(self):
230 """Make sure a newly set filename makes it into the combobox list"""
231 self.tidy(self.component('filename'),self['filename'])
232
233 def setfilter(self,value):
234 self.configure(filter=value)
235
236 def newfilter(self):
237 """Make sure a newly set filter makes it into the combobox list"""
238 self.tidy(self.component('filter'),self['filter'])
239 self.fillit()
240
241 def setdir(self,value):
242 self.configure(directory=value)
243
244 def newdir(self):
245 """Make sure a newly set dirname makes it into the combobox list"""
246 self.tidy(self.component('dirname'),self['directory'])
247 self.fillit()
248
249 def singleselectfile(self):
250 """Single click in file listbox. Move file to "filename" combobox"""
251 cs=self.component('filenamebox').curselection()
252 if cs!=():
253 value=self.component('filenamebox').get(cs)
254 self.setfilename(value)
255
256 def selectfile(self):
257 """Take the selected file from the filename, normalize it, and OK"""
258 self.singleselectfile()
259 value=self.component('filename').get()
260 self.setfilename(value)
261 if value:
262 self.okbutton()
263
264 def selectdir(self):
265 """Take selected directory from the dirnamebox into the dirname"""
266 cs=self.component('dirnamebox').curselection()
267 if cs!=():
268 value=self.component('dirnamebox').get(cs)
269 dir=self['directory']
270 if not dir:
271 dir=os.getcwd()
272 if value:
273 if value=='..':
274 dir=os.path.split(dir)[0]
275 else:
276 dir=os.path.join(dir,value)
277 self.configure(directory=dir)
278 self.fillit()
279
280 def askfilename(self,directory=None,filter=None):
281 """The actual client function. Activates the dialog, and
282 returns only after a valid filename has been entered
283 (return value is that filename) or when canceled (return
284 value is None)"""
285 if directory!=None:
286 self.configure(directory=directory)
287 if filter!=None:
288 self.configure(filter=filter)
289 self.fillit()
290 self.canceled=1 # Needed for when user kills dialog window
291 self.activate()
292 if self.canceled:
293 return None
294 else:
295 return self.component('filename').get()
296
297 lastdir=""
298 lastfilter=None
299 lasttime=0
300 def fillit(self):
301 """Get the directory list and show it in the two listboxes"""
302 # Do not run unnecesarily
303 if self.lastdir==self['directory'] and self.lastfilter==self['filter'] and self.lasttime>os.stat(self.lastdir)[8]:
304 return
305 self.lastdir=self['directory']
306 self.lastfilter=self['filter']
307 self.lasttime=time.time()
308 dir=self['directory']
309 if not dir:
310 dir=os.getcwd()
311 dirs=['..']
312 files=[]
313 try:
314 fl=os.listdir(dir)
315 fl.sort()
316 except os.error,arg:
317 if arg[0] in (2,20):
318 return
319 raise
320 for f in fl:
321 if os.path.isdir(os.path.join(dir,f)):
322 dirs.append(f)
323 else:
324 filter=self['filter']
325 if not filter:
326 filter='*'
327 if fnmatch.fnmatch(f,filter):
328 files.append(f)
329 self.component('filenamebox').setlist(files)
330 self.component('dirnamebox').setlist(dirs)
331
332 def validate(self,filename):
333 """Validation function. Should return 1 if the filename is valid,
334 0 if invalid. May pop up dialogs to tell user why. Especially
335 suited to subclasses: i.e. only return 1 if the file does/doesn't
336 exist"""
337 return 1
338
339class PmwDirDialog(PmwFileDialog):
340 """Directory Dialog using Pmw"""
341 def __init__(self, parent = None, **kw):
342 # Define the megawidget options.
343 optiondefs = (
344 ('directory', os.getcwd(), self.newdir),
345 ('historylen',10, None),
346 ('command', None, None),
347 ('info', None, None),
348 )
349 self.defineoptions(kw, optiondefs)
350 # Initialise base class (after defining options).
351 Pmw.Dialog.__init__(self, parent)
352
353 self.withdraw()
354
355 # Create the components.
356 interior = self.interior()
357
358 if self['info'] is not None:
359 rowoffset=1
360 dn = self.infotxt()
361 dn.grid(row=0,column=0,columnspan=2,padx=3,pady=3)
362 else:
363 rowoffset=0
364
365 dn = self.mkdn()
366 dn.grid(row=1+rowoffset,column=0,columnspan=2,padx=3,pady=3)
367 dn.bind('<Return>',self.okbutton)
368 del dn
369
370 # Create the directory list component.
371 dnb = self.mkdnb()
372 dnb.grid(row=0+rowoffset,column=0,columnspan=2,sticky='news',padx=3,pady=3)
373 del dnb
374
375 # Buttonbox already exists
376 bb=self.component('buttonbox')
377 bb.add('OK',command=self.okbutton)
378 bb.add('Cancel',command=self.cancelbutton)
379 del bb
380
381 lastdir=""
382 def fillit(self):
383 """Get the directory list and show it in the two listboxes"""
384 # Do not run unnecesarily
385 if self.lastdir==self['directory']:
386 return
387 self.lastdir=self['directory']
388 dir=self['directory']
389 if not dir:
390 dir=os.getcwd()
391 dirs=['..']
392 try:
393 fl=os.listdir(dir)
394 fl.sort()
395 except os.error,arg:
396 if arg[0] in (2,20):
397 return
398 raise
399 for f in fl:
400 if os.path.isdir(os.path.join(dir,f)):
401 dirs.append(f)
402 self.component('dirnamebox').setlist(dirs)
403
404 def okbutton(self):
405 """OK action: user thinks he has input valid data and wants to
406 proceed. This is also called by <Return> in the dirname entry"""
407 fn=self.component('dirname').get()
408 self.configure(directory=fn)
409 if self.validate(fn):
410 self.canceled=0
411 self.deactivate()
412
413 def askfilename(self,directory=None):
414 """The actual client function. Activates the dialog, and
415 returns only after a valid filename has been entered
416 (return value is that filename) or when canceled (return
417 value is None)"""
418 if directory!=None:
419 self.configure(directory=directory)
420 self.fillit()
421 self.activate()
422 if self.canceled:
423 return None
424 else:
425 return self.component('dirname').get()
426
427 def dirvalidate(self,string):
428 if os.path.isdir(string):
429 return Pmw.OK
430 elif os.path.exists(string):
431 return Pmw.PARTIAL
432 else:
433 return Pmw.OK
434
435 def validate(self,filename):
436 """Validation function. Should return 1 if the filename is valid,
437 0 if invalid. May pop up dialogs to tell user why. Especially
438 suited to subclasses: i.e. only return 1 if the file does/doesn't
439 exist"""
440 if filename=='':
441 _errorpop(self.interior(),"Empty filename")
442 return 0
443 if os.path.isdir(filename) or not os.path.exists(filename):
444 return 1
445 else:
446 _errorpop(self.interior(),"This is not a directory")
447 return 0
448
449class PmwExistingFileDialog(PmwFileDialog):
450 def filevalidate(self,string):
451 if os.path.isfile(string):
452 return Pmw.OK
453 else:
454 return Pmw.PARTIAL
455
456 def validate(self,filename):
457 if os.path.isfile(filename):
458 return 1
459 elif os.path.exists(filename):
460 _errorpop(self.interior(),"This is not a plain file")
461 return 0
462 else:
463 _errorpop(self.interior(),"Please select an existing file")
464 return 0
465
466class PmwExistingDirDialog(PmwDirDialog):
467 def dirvalidate(self,string):
468 if os.path.isdir(string):
469 return Pmw.OK
470 else:
471 return Pmw.PARTIAL
472
473 def validate(self,filename):
474 if os.path.isdir(filename):
475 return 1
476 elif os.path.exists(filename):
477 _errorpop(self.interior(),"This is not a directory")
478 return 0
479 else:
480 _errorpop(self.interior(),"Please select an existing directory")
481
482if __name__=="__main__":
483 root=Tkinter.Tk()
484 root.withdraw()
485 Pmw.initialise()
486
487 f0=PmwFileDialog(root)
488 f0.title('File name dialog')
489 n=f0.askfilename()
490 print '\nFilename : ',repr(n),'\n'
491
492 f1=PmwDirDialog(root,info='This is a directory dialog')
493 f1.title('Directory name dialog')
494 while 1:
495 n=f1.askfilename()
496 if n is None:
497 break
498 print "Dirname : ",repr(n)