"""File selection dialog classes.

Classes:

- FileDialog
- LoadFileDialog
- SaveFileDialog

"""

from Tkinter import *
from Dialog import Dialog

ANCHOR = 'anchor'

import os
import fnmatch


dialogstates = {}


class FileDialog:

    """Standard file selection dialog -- no checks on selected file.

    Usage:

        d = FileDialog(master)
        file = d.go(dir_or_file, pattern, default, key)
        if file is None: ...canceled...
	else: ...open file...

    All arguments to go() are optional.

    The 'key' argument specifies a key in the global dictionary
    'dialogstates', which keeps track of the values for the directory
    and pattern arguments, overriding the values passed in (it does
    not keep track of the default argument!).  If no key is specified,
    the dialog keeps no memory of previous state.  Note that memory is
    kept even when the dialog is cancelled.  (All this emulates the
    behavior of the Macintosh file selection dialogs.)

    """

    title = "File Selection Dialog"

    def __init__(self, master, title=None):
	if title is None: title = self.title
	self.master = master
	self.directory = None

	self.top = Toplevel(master)
	self.top.title(title)
	self.top.iconname(title)

	self.botframe = Frame(self.top)
	self.botframe.pack(side=BOTTOM, fill=X)

	self.selection = Entry(self.top)
	self.selection.pack(side=BOTTOM, fill=X)
	self.selection.bind('<Return>', self.ok_event)

	self.filter = Entry(self.top)
	self.filter.pack(side=TOP, fill=X)
	self.filter.bind('<Return>', self.filter_command)

	self.midframe = Frame(self.top)
	self.midframe.pack(expand=YES, fill=BOTH)

	self.filesbar = Scrollbar(self.midframe)
	self.filesbar.pack(side=RIGHT, fill=Y)
	self.files = Listbox(self.midframe, exportselection=0,
			     yscrollcommand=(self.filesbar, 'set'))
	self.files.pack(side=RIGHT, expand=YES, fill=BOTH)
	self.files.bind('<ButtonRelease-1>', self.files_select_event)
	self.files.bind('<Double-ButtonRelease-1>', self.files_double_event)
	self.filesbar.config(command=(self.files, 'yview'))

	self.dirsbar = Scrollbar(self.midframe)
	self.dirsbar.pack(side=LEFT, fill=Y)
	self.dirs = Listbox(self.midframe, exportselection=0,
			    yscrollcommand=(self.dirsbar, 'set'))
	self.dirs.pack(side=LEFT, expand=YES, fill=BOTH)
	self.dirsbar.config(command=(self.dirs, 'yview'))
	self.dirs.bind('<ButtonRelease-1>', self.dirs_select_event)
	self.dirs.bind('<Double-ButtonRelease-1>', self.dirs_double_event)

	self.ok_button = Button(self.botframe,
				 text="OK",
				 command=self.ok_command)
	self.ok_button.pack(side=LEFT)
	self.filter_button = Button(self.botframe,
				    text="Filter",
				    command=self.filter_command)
	self.filter_button.pack(side=LEFT, expand=YES)
	self.cancel_button = Button(self.botframe,
				    text="Cancel",
				    command=self.cancel_command)
	self.cancel_button.pack(side=RIGHT)

	self.top.protocol('WM_DELETE_WINDOW', self.cancel_command)
	# XXX Are the following okay for a general audience?
	self.top.bind('<Alt-w>', self.cancel_command)
	self.top.bind('<Alt-W>', self.cancel_command)

    def go(self, dir_or_file=os.curdir, pattern="*", default="", key=None):
	if key and dialogstates.has_key(key):
	    self.directory, pattern = dialogstates[key]
	else:
	    dir_or_file = os.path.expanduser(dir_or_file)
	    if os.path.isdir(dir_or_file):
		self.directory = dir_or_file
	    else:
		self.directory, default = os.path.split(dir_or_file)
	self.set_filter(self.directory, pattern)
	self.set_selection(default)
	self.filter_command()
	self.selection.focus_set()
	self.top.grab_set()
	self.how = None
	self.master.mainloop()		# Exited by self.quit(how)
	if key: dialogstates[key] = self.get_filter()
	self.top.destroy()
	return self.how

    def quit(self, how=None):
	self.how = how
	self.master.quit()		# Exit mainloop()

    def dirs_double_event(self, event):
	self.filter_command()

    def dirs_select_event(self, event):
	dir, pat = self.get_filter()
	subdir = self.dirs.get(ANCHOR)
	dir = os.path.normpath(os.path.join(self.directory, subdir))
	self.set_filter(dir, pat)

    def files_double_event(self, event):
	self.ok_command()

    def files_select_event(self, event):
	file = self.files.get(ANCHOR)
	self.set_selection(file)

    def ok_event(self, event):
	self.ok_command()

    def ok_command(self):
	self.quit(self.get_selection())

    def filter_command(self, event=None):
	dir, pat = self.get_filter()
	try:
	    names = os.listdir(dir)
	except os.error:
	    self.master.bell()
	    return
	self.directory = dir
	self.set_filter(dir, pat)
	names.sort()
	subdirs = [os.pardir]
	matchingfiles = []
	for name in names:
	    fullname = os.path.join(dir, name)
	    if os.path.isdir(fullname):
		subdirs.append(name)
	    elif fnmatch.fnmatch(name, pat):
		matchingfiles.append(name)
	self.dirs.delete(0, END)
	for name in subdirs:
	    self.dirs.insert(END, name)
	self.files.delete(0, END)
	for name in matchingfiles:
	    self.files.insert(END, name)
	head, tail = os.path.split(self.get_selection())
	if tail == os.curdir: tail = ''
	self.set_selection(tail)

    def get_filter(self):
	filter = self.filter.get()
	filter = os.path.expanduser(filter)
	if filter[-1:] == os.sep or os.path.isdir(filter):
	    filter = os.path.join(filter, "*")
	return os.path.split(filter)

    def get_selection(self):
	file = self.selection.get()
	file = os.path.expanduser(file)
	return file

    def cancel_command(self, event=None):
	self.quit()

    def set_filter(self, dir, pat):
	if not os.path.isabs(dir):
	    try:
		pwd = os.getcwd()
	    except os.error:
		pwd = None
	    if pwd:
		dir = os.path.join(pwd, dir)
		dir = os.path.normpath(dir)
	self.filter.delete(0, END)
	self.filter.insert(END, os.path.join(dir or os.curdir, pat or "*"))

    def set_selection(self, file):
	self.selection.delete(0, END)
	self.selection.insert(END, os.path.join(self.directory, file))


class LoadFileDialog(FileDialog):

    """File selection dialog which checks that the file exists."""

    title = "Load File Selection Dialog"

    def ok_command(self):
	file = self.get_selection()
	if not os.path.isfile(file):
	    self.master.bell()
	else:
	    self.quit(file)


class SaveFileDialog(FileDialog):

    """File selection dialog which checks that the file may be created."""

    title = "Save File Selection Dialog"

    def ok_command(self):
	file = self.get_selection()
	if os.path.exists(file):
	    if os.path.isdir(file):
		self.master.bell()
		return
	    d = Dialog(self.top,
		       title="Overwrite Existing File Question",
		       text="Overwrite existing file %s?" % `file`,
		       bitmap='questhead',
		       default=1,
		       strings=("Yes", "Cancel"))
	    if d.num != 0:
		return
	else:
	    head, tail = os.path.split(file)
	    if not os.path.isdir(head):
		self.master.bell()
		return
	self.quit(file)


def test():
    """Simple test program."""
    root = Tk()
    root.withdraw()
    fd = LoadFileDialog(root)
    loadfile = fd.go(key="test")
    fd = SaveFileDialog(root)
    savefile = fd.go(key="test")
    print loadfile, savefile


if __name__ == '__main__':
    test()
