ยปCore Development>Code coverage>Lib/lib-tk/FileDialog.py

Python code coverage for Lib/lib-tk/FileDialog.py

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