14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao"""File selection dialog classes.
24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
34adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoClasses:
44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao- FileDialog
64adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao- LoadFileDialog
74adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao- SaveFileDialog
84adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
94adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao"""
104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom Tkinter import *
124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom Dialog import Dialog
134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport os
154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport fnmatch
164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodialogstates = {}
194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass FileDialog:
224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    """Standard file selection dialog -- no checks on selected file.
244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    Usage:
264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        d = FileDialog(master)
284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        fname = d.go(dir_or_file, pattern, default, key)
294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if fname is None: ...canceled...
304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        else: ...open file...
314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    All arguments to go() are optional.
334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    The 'key' argument specifies a key in the global dictionary
354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    'dialogstates', which keeps track of the values for the directory
364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    and pattern arguments, overriding the values passed in (it does
374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    not keep track of the default argument!).  If no key is specified,
384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    the dialog keeps no memory of previous state.  Note that memory is
394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    kept even when the dialog is canceled.  (All this emulates the
404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    behavior of the Macintosh file selection dialogs.)
414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    """
434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    title = "File Selection Dialog"
454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def __init__(self, master, title=None):
474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if title is None: title = self.title
484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.master = master
494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.directory = None
504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.top = Toplevel(master)
524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.top.title(title)
534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.top.iconname(title)
544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.botframe = Frame(self.top)
564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.botframe.pack(side=BOTTOM, fill=X)
574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.selection = Entry(self.top)
594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.selection.pack(side=BOTTOM, fill=X)
604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.selection.bind('<Return>', self.ok_event)
614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.filter = Entry(self.top)
634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.filter.pack(side=TOP, fill=X)
644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.filter.bind('<Return>', self.filter_command)
654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.midframe = Frame(self.top)
674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.midframe.pack(expand=YES, fill=BOTH)
684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.filesbar = Scrollbar(self.midframe)
704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.filesbar.pack(side=RIGHT, fill=Y)
714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.files = Listbox(self.midframe, exportselection=0,
724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                             yscrollcommand=(self.filesbar, 'set'))
734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.files.pack(side=RIGHT, expand=YES, fill=BOTH)
744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        btags = self.files.bindtags()
754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.files.bindtags(btags[1:] + btags[:1])
764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.files.bind('<ButtonRelease-1>', self.files_select_event)
774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.files.bind('<Double-ButtonRelease-1>', self.files_double_event)
784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.filesbar.config(command=(self.files, 'yview'))
794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.dirsbar = Scrollbar(self.midframe)
814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.dirsbar.pack(side=LEFT, fill=Y)
824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.dirs = Listbox(self.midframe, exportselection=0,
834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                            yscrollcommand=(self.dirsbar, 'set'))
844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.dirs.pack(side=LEFT, expand=YES, fill=BOTH)
854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.dirsbar.config(command=(self.dirs, 'yview'))
864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        btags = self.dirs.bindtags()
874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.dirs.bindtags(btags[1:] + btags[:1])
884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.dirs.bind('<ButtonRelease-1>', self.dirs_select_event)
894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.dirs.bind('<Double-ButtonRelease-1>', self.dirs_double_event)
904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.ok_button = Button(self.botframe,
924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                 text="OK",
934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                 command=self.ok_command)
944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.ok_button.pack(side=LEFT)
954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.filter_button = Button(self.botframe,
964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                    text="Filter",
974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                    command=self.filter_command)
984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.filter_button.pack(side=LEFT, expand=YES)
994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.cancel_button = Button(self.botframe,
1004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                    text="Cancel",
1014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                    command=self.cancel_command)
1024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.cancel_button.pack(side=RIGHT)
1034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.top.protocol('WM_DELETE_WINDOW', self.cancel_command)
1054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # XXX Are the following okay for a general audience?
1064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.top.bind('<Alt-w>', self.cancel_command)
1074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.top.bind('<Alt-W>', self.cancel_command)
1084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def go(self, dir_or_file=os.curdir, pattern="*", default="", key=None):
1104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if key and key in dialogstates:
1114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.directory, pattern = dialogstates[key]
1124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        else:
1134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            dir_or_file = os.path.expanduser(dir_or_file)
1144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if os.path.isdir(dir_or_file):
1154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.directory = dir_or_file
1164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            else:
1174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.directory, default = os.path.split(dir_or_file)
1184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.set_filter(self.directory, pattern)
1194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.set_selection(default)
1204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.filter_command()
1214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.selection.focus_set()
1224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.top.wait_visibility() # window needs to be visible for the grab
1234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.top.grab_set()
1244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.how = None
1254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.master.mainloop()          # Exited by self.quit(how)
1264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if key:
1274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            directory, pattern = self.get_filter()
1284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if self.how:
1294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                directory = os.path.dirname(self.how)
1304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            dialogstates[key] = directory, pattern
1314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.top.destroy()
1324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return self.how
1334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def quit(self, how=None):
1354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.how = how
1364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.master.quit()              # Exit mainloop()
1374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def dirs_double_event(self, event):
1394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.filter_command()
1404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def dirs_select_event(self, event):
1424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        dir, pat = self.get_filter()
1434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        subdir = self.dirs.get('active')
1444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        dir = os.path.normpath(os.path.join(self.directory, subdir))
1454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.set_filter(dir, pat)
1464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def files_double_event(self, event):
1484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.ok_command()
1494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def files_select_event(self, event):
1514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        file = self.files.get('active')
1524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.set_selection(file)
1534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def ok_event(self, event):
1554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.ok_command()
1564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def ok_command(self):
1584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.quit(self.get_selection())
1594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def filter_command(self, event=None):
1614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        dir, pat = self.get_filter()
1624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        try:
1634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            names = os.listdir(dir)
1644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        except os.error:
1654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.master.bell()
1664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return
1674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.directory = dir
1684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.set_filter(dir, pat)
1694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        names.sort()
1704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        subdirs = [os.pardir]
1714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        matchingfiles = []
1724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for name in names:
1734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            fullname = os.path.join(dir, name)
1744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if os.path.isdir(fullname):
1754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                subdirs.append(name)
1764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            elif fnmatch.fnmatch(name, pat):
1774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                matchingfiles.append(name)
1784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.dirs.delete(0, END)
1794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for name in subdirs:
1804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.dirs.insert(END, name)
1814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.files.delete(0, END)
1824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for name in matchingfiles:
1834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.files.insert(END, name)
1844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        head, tail = os.path.split(self.get_selection())
1854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if tail == os.curdir: tail = ''
1864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.set_selection(tail)
1874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def get_filter(self):
1894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        filter = self.filter.get()
1904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        filter = os.path.expanduser(filter)
1914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if filter[-1:] == os.sep or os.path.isdir(filter):
1924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            filter = os.path.join(filter, "*")
1934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return os.path.split(filter)
1944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def get_selection(self):
1964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        file = self.selection.get()
1974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        file = os.path.expanduser(file)
1984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return file
1994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def cancel_command(self, event=None):
2014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.quit()
2024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def set_filter(self, dir, pat):
2044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if not os.path.isabs(dir):
2054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            try:
2064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                pwd = os.getcwd()
2074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            except os.error:
2084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                pwd = None
2094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if pwd:
2104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                dir = os.path.join(pwd, dir)
2114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                dir = os.path.normpath(dir)
2124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.filter.delete(0, END)
2134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.filter.insert(END, os.path.join(dir or os.curdir, pat or "*"))
2144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def set_selection(self, file):
2164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.selection.delete(0, END)
2174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.selection.insert(END, os.path.join(self.directory, file))
2184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass LoadFileDialog(FileDialog):
2214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    """File selection dialog which checks that the file exists."""
2234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    title = "Load File Selection Dialog"
2254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def ok_command(self):
2274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        file = self.get_selection()
2284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if not os.path.isfile(file):
2294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.master.bell()
2304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        else:
2314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.quit(file)
2324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass SaveFileDialog(FileDialog):
2354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    """File selection dialog which checks that the file may be created."""
2374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    title = "Save File Selection Dialog"
2394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def ok_command(self):
2414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        file = self.get_selection()
2424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if os.path.exists(file):
2434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if os.path.isdir(file):
2444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.master.bell()
2454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                return
2464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            d = Dialog(self.top,
2474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                       title="Overwrite Existing File Question",
2484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                       text="Overwrite existing file %r?" % (file,),
2494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                       bitmap='questhead',
2504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                       default=1,
2514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                       strings=("Yes", "Cancel"))
2524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if d.num != 0:
2534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                return
2544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        else:
2554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            head, tail = os.path.split(file)
2564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if not os.path.isdir(head):
2574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.master.bell()
2584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                return
2594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.quit(file)
2604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef test():
2634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    """Simple test program."""
2644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    root = Tk()
2654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    root.withdraw()
2664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    fd = LoadFileDialog(root)
2674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    loadfile = fd.go(key="test")
2684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    fd = SaveFileDialog(root)
2694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    savefile = fd.go(key="test")
2704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print loadfile, savefile
2714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif __name__ == '__main__':
2744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    test()
275