Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / devtools / v8plus / lib / python2.4 / lib-tk / FileDialog.py
CommitLineData
920dae64
AT
1"""File selection dialog classes.
2
3Classes:
4
5- FileDialog
6- LoadFileDialog
7- SaveFileDialog
8
9"""
10
11from Tkinter import *
12from Dialog import Dialog
13
14import os
15import fnmatch
16
17
18dialogstates = {}
19
20
21class FileDialog:
22
23 """Standard file selection dialog -- no checks on selected file.
24
25 Usage:
26
27 d = FileDialog(master)
28 fname = d.go(dir_or_file, pattern, default, key)
29 if fname is None: ...canceled...
30 else: ...open file...
31
32 All arguments to go() are optional.
33
34 The 'key' argument specifies a key in the global dictionary
35 'dialogstates', which keeps track of the values for the directory
36 and pattern arguments, overriding the values passed in (it does
37 not keep track of the default argument!). If no key is specified,
38 the dialog keeps no memory of previous state. Note that memory is
39 kept even when the dialog is canceled. (All this emulates the
40 behavior of the Macintosh file selection dialogs.)
41
42 """
43
44 title = "File Selection Dialog"
45
46 def __init__(self, master, title=None):
47 if title is None: title = self.title
48 self.master = master
49 self.directory = None
50
51 self.top = Toplevel(master)
52 self.top.title(title)
53 self.top.iconname(title)
54
55 self.botframe = Frame(self.top)
56 self.botframe.pack(side=BOTTOM, fill=X)
57
58 self.selection = Entry(self.top)
59 self.selection.pack(side=BOTTOM, fill=X)
60 self.selection.bind('<Return>', self.ok_event)
61
62 self.filter = Entry(self.top)
63 self.filter.pack(side=TOP, fill=X)
64 self.filter.bind('<Return>', self.filter_command)
65
66 self.midframe = Frame(self.top)
67 self.midframe.pack(expand=YES, fill=BOTH)
68
69 self.filesbar = Scrollbar(self.midframe)
70 self.filesbar.pack(side=RIGHT, fill=Y)
71 self.files = Listbox(self.midframe, exportselection=0,
72 yscrollcommand=(self.filesbar, 'set'))
73 self.files.pack(side=RIGHT, expand=YES, fill=BOTH)
74 btags = self.files.bindtags()
75 self.files.bindtags(btags[1:] + btags[:1])
76 self.files.bind('<ButtonRelease-1>', self.files_select_event)
77 self.files.bind('<Double-ButtonRelease-1>', self.files_double_event)
78 self.filesbar.config(command=(self.files, 'yview'))
79
80 self.dirsbar = Scrollbar(self.midframe)
81 self.dirsbar.pack(side=LEFT, fill=Y)
82 self.dirs = Listbox(self.midframe, exportselection=0,
83 yscrollcommand=(self.dirsbar, 'set'))
84 self.dirs.pack(side=LEFT, expand=YES, fill=BOTH)
85 self.dirsbar.config(command=(self.dirs, 'yview'))
86 btags = self.dirs.bindtags()
87 self.dirs.bindtags(btags[1:] + btags[:1])
88 self.dirs.bind('<ButtonRelease-1>', self.dirs_select_event)
89 self.dirs.bind('<Double-ButtonRelease-1>', self.dirs_double_event)
90
91 self.ok_button = Button(self.botframe,
92 text="OK",
93 command=self.ok_command)
94 self.ok_button.pack(side=LEFT)
95 self.filter_button = Button(self.botframe,
96 text="Filter",
97 command=self.filter_command)
98 self.filter_button.pack(side=LEFT, expand=YES)
99 self.cancel_button = Button(self.botframe,
100 text="Cancel",
101 command=self.cancel_command)
102 self.cancel_button.pack(side=RIGHT)
103
104 self.top.protocol('WM_DELETE_WINDOW', self.cancel_command)
105 # XXX Are the following okay for a general audience?
106 self.top.bind('<Alt-w>', self.cancel_command)
107 self.top.bind('<Alt-W>', self.cancel_command)
108
109 def go(self, dir_or_file=os.curdir, pattern="*", default="", key=None):
110 if key and dialogstates.has_key(key):
111 self.directory, pattern = dialogstates[key]
112 else:
113 dir_or_file = os.path.expanduser(dir_or_file)
114 if os.path.isdir(dir_or_file):
115 self.directory = dir_or_file
116 else:
117 self.directory, default = os.path.split(dir_or_file)
118 self.set_filter(self.directory, pattern)
119 self.set_selection(default)
120 self.filter_command()
121 self.selection.focus_set()
122 self.top.wait_visibility() # window needs to be visible for the grab
123 self.top.grab_set()
124 self.how = None
125 self.master.mainloop() # Exited by self.quit(how)
126 if key:
127 directory, pattern = self.get_filter()
128 if self.how:
129 directory = os.path.dirname(self.how)
130 dialogstates[key] = directory, pattern
131 self.top.destroy()
132 return self.how
133
134 def quit(self, how=None):
135 self.how = how
136 self.master.quit() # Exit mainloop()
137
138 def dirs_double_event(self, event):
139 self.filter_command()
140
141 def dirs_select_event(self, event):
142 dir, pat = self.get_filter()
143 subdir = self.dirs.get('active')
144 dir = os.path.normpath(os.path.join(self.directory, subdir))
145 self.set_filter(dir, pat)
146
147 def files_double_event(self, event):
148 self.ok_command()
149
150 def files_select_event(self, event):
151 file = self.files.get('active')
152 self.set_selection(file)
153
154 def ok_event(self, event):
155 self.ok_command()
156
157 def ok_command(self):
158 self.quit(self.get_selection())
159
160 def filter_command(self, event=None):
161 dir, pat = self.get_filter()
162 try:
163 names = os.listdir(dir)
164 except os.error:
165 self.master.bell()
166 return
167 self.directory = dir
168 self.set_filter(dir, pat)
169 names.sort()
170 subdirs = [os.pardir]
171 matchingfiles = []
172 for name in names:
173 fullname = os.path.join(dir, name)
174 if os.path.isdir(fullname):
175 subdirs.append(name)
176 elif fnmatch.fnmatch(name, pat):
177 matchingfiles.append(name)
178 self.dirs.delete(0, END)
179 for name in subdirs:
180 self.dirs.insert(END, name)
181 self.files.delete(0, END)
182 for name in matchingfiles:
183 self.files.insert(END, name)
184 head, tail = os.path.split(self.get_selection())
185 if tail == os.curdir: tail = ''
186 self.set_selection(tail)
187
188 def get_filter(self):
189 filter = self.filter.get()
190 filter = os.path.expanduser(filter)
191 if filter[-1:] == os.sep or os.path.isdir(filter):
192 filter = os.path.join(filter, "*")
193 return os.path.split(filter)
194
195 def get_selection(self):
196 file = self.selection.get()
197 file = os.path.expanduser(file)
198 return file
199
200 def cancel_command(self, event=None):
201 self.quit()
202
203 def set_filter(self, dir, pat):
204 if not os.path.isabs(dir):
205 try:
206 pwd = os.getcwd()
207 except os.error:
208 pwd = None
209 if pwd:
210 dir = os.path.join(pwd, dir)
211 dir = os.path.normpath(dir)
212 self.filter.delete(0, END)
213 self.filter.insert(END, os.path.join(dir or os.curdir, pat or "*"))
214
215 def set_selection(self, file):
216 self.selection.delete(0, END)
217 self.selection.insert(END, os.path.join(self.directory, file))
218
219
220class LoadFileDialog(FileDialog):
221
222 """File selection dialog which checks that the file exists."""
223
224 title = "Load File Selection Dialog"
225
226 def ok_command(self):
227 file = self.get_selection()
228 if not os.path.isfile(file):
229 self.master.bell()
230 else:
231 self.quit(file)
232
233
234class SaveFileDialog(FileDialog):
235
236 """File selection dialog which checks that the file may be created."""
237
238 title = "Save File Selection Dialog"
239
240 def ok_command(self):
241 file = self.get_selection()
242 if os.path.exists(file):
243 if os.path.isdir(file):
244 self.master.bell()
245 return
246 d = Dialog(self.top,
247 title="Overwrite Existing File Question",
248 text="Overwrite existing file %r?" % (file,),
249 bitmap='questhead',
250 default=1,
251 strings=("Yes", "Cancel"))
252 if d.num != 0:
253 return
254 else:
255 head, tail = os.path.split(file)
256 if not os.path.isdir(head):
257 self.master.bell()
258 return
259 self.quit(file)
260
261
262def test():
263 """Simple test program."""
264 root = Tk()
265 root.withdraw()
266 fd = LoadFileDialog(root)
267 loadfile = fd.go(key="test")
268 fd = SaveFileDialog(root)
269 savefile = fd.go(key="test")
270 print loadfile, savefile
271
272
273if __name__ == '__main__':
274 test()