Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | # |
2 | # Instant Python | |
3 | # $Id: tkFileDialog.py,v 1.13 2004/07/18 06:14:44 tim_one Exp $ | |
4 | # | |
5 | # tk common file dialogues | |
6 | # | |
7 | # this module provides interfaces to the native file dialogues | |
8 | # available in Tk 4.2 and newer, and the directory dialogue available | |
9 | # in Tk 8.3 and newer. | |
10 | # | |
11 | # written by Fredrik Lundh, May 1997. | |
12 | # | |
13 | ||
14 | # | |
15 | # options (all have default values): | |
16 | # | |
17 | # - defaultextension: added to filename if not explicitly given | |
18 | # | |
19 | # - filetypes: sequence of (label, pattern) tuples. the same pattern | |
20 | # may occur with several patterns. use "*" as pattern to indicate | |
21 | # all files. | |
22 | # | |
23 | # - initialdir: initial directory. preserved by dialog instance. | |
24 | # | |
25 | # - initialfile: initial file (ignored by the open dialog). preserved | |
26 | # by dialog instance. | |
27 | # | |
28 | # - parent: which window to place the dialog on top of | |
29 | # | |
30 | # - title: dialog title | |
31 | # | |
32 | # - multiple: if true user may select more than one file | |
33 | # | |
34 | # options for the directory chooser: | |
35 | # | |
36 | # - initialdir, parent, title: see above | |
37 | # | |
38 | # - mustexist: if true, user must pick an existing directory | |
39 | # | |
40 | # | |
41 | ||
42 | ||
43 | from tkCommonDialog import Dialog | |
44 | ||
45 | class _Dialog(Dialog): | |
46 | ||
47 | def _fixoptions(self): | |
48 | try: | |
49 | # make sure "filetypes" is a tuple | |
50 | self.options["filetypes"] = tuple(self.options["filetypes"]) | |
51 | except KeyError: | |
52 | pass | |
53 | ||
54 | def _fixresult(self, widget, result): | |
55 | if result: | |
56 | # keep directory and filename until next time | |
57 | import os | |
58 | # convert Tcl path objects to strings | |
59 | try: | |
60 | result = result.string | |
61 | except AttributeError: | |
62 | # it already is a string | |
63 | pass | |
64 | path, file = os.path.split(result) | |
65 | self.options["initialdir"] = path | |
66 | self.options["initialfile"] = file | |
67 | self.filename = result # compatibility | |
68 | return result | |
69 | ||
70 | ||
71 | # | |
72 | # file dialogs | |
73 | ||
74 | class Open(_Dialog): | |
75 | "Ask for a filename to open" | |
76 | ||
77 | command = "tk_getOpenFile" | |
78 | ||
79 | def _fixresult(self, widget, result): | |
80 | if isinstance(result, tuple): | |
81 | # multiple results: | |
82 | result = tuple([getattr(r, "string", r) for r in result]) | |
83 | if result: | |
84 | import os | |
85 | path, file = os.path.split(result[0]) | |
86 | self.options["initialdir"] = path | |
87 | # don't set initialfile or filename, as we have multiple of these | |
88 | return result | |
89 | if not widget.tk.wantobjects() and "multiple" in self.options: | |
90 | # Need to split result explicitly | |
91 | return self._fixresult(widget, widget.tk.splitlist(result)) | |
92 | return _Dialog._fixresult(self, widget, result) | |
93 | ||
94 | class SaveAs(_Dialog): | |
95 | "Ask for a filename to save as" | |
96 | ||
97 | command = "tk_getSaveFile" | |
98 | ||
99 | ||
100 | # the directory dialog has its own _fix routines. | |
101 | class Directory(Dialog): | |
102 | "Ask for a directory" | |
103 | ||
104 | command = "tk_chooseDirectory" | |
105 | ||
106 | def _fixresult(self, widget, result): | |
107 | if result: | |
108 | # convert Tcl path objects to strings | |
109 | try: | |
110 | result = result.string | |
111 | except AttributeError: | |
112 | # it already is a string | |
113 | pass | |
114 | # keep directory until next time | |
115 | self.options["initialdir"] = result | |
116 | self.directory = result # compatibility | |
117 | return result | |
118 | ||
119 | # | |
120 | # convenience stuff | |
121 | ||
122 | def askopenfilename(**options): | |
123 | "Ask for a filename to open" | |
124 | ||
125 | return Open(**options).show() | |
126 | ||
127 | def asksaveasfilename(**options): | |
128 | "Ask for a filename to save as" | |
129 | ||
130 | return SaveAs(**options).show() | |
131 | ||
132 | def askopenfilenames(**options): | |
133 | """Ask for multiple filenames to open | |
134 | ||
135 | Returns a list of filenames or empty list if | |
136 | cancel button selected | |
137 | """ | |
138 | options["multiple"]=1 | |
139 | return Open(**options).show() | |
140 | ||
141 | # FIXME: are the following perhaps a bit too convenient? | |
142 | ||
143 | def askopenfile(mode = "r", **options): | |
144 | "Ask for a filename to open, and returned the opened file" | |
145 | ||
146 | filename = Open(**options).show() | |
147 | if filename: | |
148 | return open(filename, mode) | |
149 | return None | |
150 | ||
151 | def askopenfiles(mode = "r", **options): | |
152 | """Ask for multiple filenames and return the open file | |
153 | objects | |
154 | ||
155 | returns a list of open file objects or an empty list if | |
156 | cancel selected | |
157 | """ | |
158 | ||
159 | files = askopenfilenames(**options) | |
160 | if files: | |
161 | ofiles=[] | |
162 | for filename in files: | |
163 | ofiles.append(open(filename, mode)) | |
164 | files=ofiles | |
165 | return files | |
166 | ||
167 | ||
168 | def asksaveasfile(mode = "w", **options): | |
169 | "Ask for a filename to save as, and returned the opened file" | |
170 | ||
171 | filename = SaveAs(**options).show() | |
172 | if filename: | |
173 | return open(filename, mode) | |
174 | return None | |
175 | ||
176 | def askdirectory (**options): | |
177 | "Ask for a directory, and return the file name" | |
178 | return Directory(**options).show() | |
179 | ||
180 | # -------------------------------------------------------------------- | |
181 | # test stuff | |
182 | ||
183 | if __name__ == "__main__": | |
184 | # Since the file name may contain non-ASCII characters, we need | |
185 | # to find an encoding that likely supports the file name, and | |
186 | # displays correctly on the terminal. | |
187 | ||
188 | # Start off with UTF-8 | |
189 | enc = "utf-8" | |
190 | import sys | |
191 | ||
192 | # See whether CODESET is defined | |
193 | try: | |
194 | import locale | |
195 | locale.setlocale(locale.LC_ALL,'') | |
196 | enc = locale.nl_langinfo(locale.CODESET) | |
197 | except (ImportError, AttributeError): | |
198 | pass | |
199 | ||
200 | # dialog for openening files | |
201 | ||
202 | openfilename=askopenfilename(filetypes=[("all files", "*")]) | |
203 | try: | |
204 | fp=open(openfilename,"r") | |
205 | fp.close() | |
206 | except: | |
207 | print "Could not open File: " | |
208 | print sys.exc_info()[1] | |
209 | ||
210 | print "open", openfilename.encode(enc) | |
211 | ||
212 | # dialog for saving files | |
213 | ||
214 | saveasfilename=asksaveasfilename() | |
215 | print "saveas", saveasfilename.encode(enc) |