diff -r 000000000000 -r ae805ac0140d python-2.5.2/win32/Tools/pynche/PyncheWidget.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python-2.5.2/win32/Tools/pynche/PyncheWidget.py Fri Apr 03 17:19:34 2009 +0100 @@ -0,0 +1,309 @@ +"""Main Pynche (Pythonically Natural Color and Hue Editor) widget. + +This window provides the basic decorations, primarily including the menubar. +It is used to bring up other windows. +""" + +import sys +import os +from Tkinter import * +import tkMessageBox +import tkFileDialog +import ColorDB + +# Milliseconds between interrupt checks +KEEPALIVE_TIMER = 500 + + + +class PyncheWidget: + def __init__(self, version, switchboard, master=None, extrapath=[]): + self.__sb = switchboard + self.__version = version + self.__textwin = None + self.__listwin = None + self.__detailswin = None + self.__helpwin = None + self.__dialogstate = {} + modal = self.__modal = not not master + # If a master was given, we are running as a modal dialog servant to + # some other application. We rearrange our UI in this case (there's + # no File menu and we get `Okay' and `Cancel' buttons), and we do a + # grab_set() to make ourselves modal + if modal: + self.__tkroot = tkroot = Toplevel(master, class_='Pynche') + tkroot.grab_set() + tkroot.withdraw() + else: + # Is there already a default root for Tk, say because we're + # running under Guido's IDE? :-) Two conditions say no, either the + # import fails or _default_root is None. + tkroot = None + try: + from Tkinter import _default_root + tkroot = self.__tkroot = _default_root + except ImportError: + pass + if not tkroot: + tkroot = self.__tkroot = Tk(className='Pynche') + # but this isn't our top level widget, so make it invisible + tkroot.withdraw() + # create the menubar + menubar = self.__menubar = Menu(tkroot) + # + # File menu + # + filemenu = self.__filemenu = Menu(menubar, tearoff=0) + filemenu.add_command(label='Load palette...', + command=self.__load, + underline=0) + if not modal: + filemenu.add_command(label='Quit', + command=self.__quit, + accelerator='Alt-Q', + underline=0) + # + # View menu + # + views = make_view_popups(self.__sb, self.__tkroot, extrapath) + viewmenu = Menu(menubar, tearoff=0) + for v in views: + viewmenu.add_command(label=v.menutext(), + command=v.popup, + underline=v.underline()) + # + # Help menu + # + helpmenu = Menu(menubar, name='help', tearoff=0) + helpmenu.add_command(label='About Pynche...', + command=self.__popup_about, + underline=0) + helpmenu.add_command(label='Help...', + command=self.__popup_usage, + underline=0) + # + # Tie them all together + # + menubar.add_cascade(label='File', + menu=filemenu, + underline=0) + menubar.add_cascade(label='View', + menu=viewmenu, + underline=0) + menubar.add_cascade(label='Help', + menu=helpmenu, + underline=0) + + # now create the top level window + root = self.__root = Toplevel(tkroot, class_='Pynche', menu=menubar) + root.protocol('WM_DELETE_WINDOW', + modal and self.__bell or self.__quit) + root.title('Pynche %s' % version) + root.iconname('Pynche') + # Only bind accelerators for the File->Quit menu item if running as a + # standalone app + if not modal: + root.bind('', self.__quit) + root.bind('', self.__quit) + else: + # We're a modal dialog so we have a new row of buttons + bframe = Frame(root, borderwidth=1, relief=RAISED) + bframe.grid(row=4, column=0, columnspan=2, + sticky='EW', + ipady=5) + okay = Button(bframe, + text='Okay', + command=self.__okay) + okay.pack(side=LEFT, expand=1) + cancel = Button(bframe, + text='Cancel', + command=self.__cancel) + cancel.pack(side=LEFT, expand=1) + + def __quit(self, event=None): + self.__tkroot.quit() + + def __bell(self, event=None): + self.__tkroot.bell() + + def __okay(self, event=None): + self.__sb.withdraw_views() + self.__tkroot.grab_release() + self.__quit() + + def __cancel(self, event=None): + self.__sb.canceled() + self.__okay() + + def __keepalive(self): + # Exercise the Python interpreter regularly so keyboard interrupts get + # through. + self.__tkroot.tk.createtimerhandler(KEEPALIVE_TIMER, self.__keepalive) + + def start(self): + if not self.__modal: + self.__keepalive() + self.__tkroot.mainloop() + + def window(self): + return self.__root + + def __popup_about(self, event=None): + from Main import __version__ + tkMessageBox.showinfo('About Pynche ' + __version__, + '''\ +Pynche %s +The PYthonically Natural +Color and Hue Editor + +For information +contact: Barry A. Warsaw +email: bwarsaw@python.org''' % __version__) + + def __popup_usage(self, event=None): + if not self.__helpwin: + self.__helpwin = Helpwin(self.__root, self.__quit) + self.__helpwin.deiconify() + + def __load(self, event=None): + while 1: + idir, ifile = os.path.split(self.__sb.colordb().filename()) + file = tkFileDialog.askopenfilename( + filetypes=[('Text files', '*.txt'), + ('All files', '*'), + ], + initialdir=idir, + initialfile=ifile) + if not file: + # cancel button + return + try: + colordb = ColorDB.get_colordb(file) + except IOError: + tkMessageBox.showerror('Read error', '''\ +Could not open file for reading: +%s''' % file) + continue + if colordb is None: + tkMessageBox.showerror('Unrecognized color file type', '''\ +Unrecognized color file type in file: +%s''' % file) + continue + break + self.__sb.set_colordb(colordb) + + def withdraw(self): + self.__root.withdraw() + + def deiconify(self): + self.__root.deiconify() + + + +class Helpwin: + def __init__(self, master, quitfunc): + from Main import docstring + self.__root = root = Toplevel(master, class_='Pynche') + root.protocol('WM_DELETE_WINDOW', self.__withdraw) + root.title('Pynche Help Window') + root.iconname('Pynche Help Window') + root.bind('', quitfunc) + root.bind('', quitfunc) + root.bind('', self.__withdraw) + root.bind('', self.__withdraw) + + # more elaborate help is available in the README file + readmefile = os.path.join(sys.path[0], 'README') + try: + fp = None + try: + fp = open(readmefile) + contents = fp.read() + # wax the last page, it contains Emacs cruft + i = contents.rfind('\f') + if i > 0: + contents = contents[:i].rstrip() + finally: + if fp: + fp.close() + except IOError: + sys.stderr.write("Couldn't open Pynche's README, " + 'using docstring instead.\n') + contents = docstring() + + self.__text = text = Text(root, relief=SUNKEN, + width=80, height=24) + self.__text.focus_set() + text.insert(0.0, contents) + scrollbar = Scrollbar(root) + scrollbar.pack(fill=Y, side=RIGHT) + text.pack(fill=BOTH, expand=YES) + text.configure(yscrollcommand=(scrollbar, 'set')) + scrollbar.configure(command=(text, 'yview')) + + def __withdraw(self, event=None): + self.__root.withdraw() + + def deiconify(self): + self.__root.deiconify() + + + +class PopupViewer: + def __init__(self, module, name, switchboard, root): + self.__m = module + self.__name = name + self.__sb = switchboard + self.__root = root + self.__menutext = module.ADDTOVIEW + # find the underline character + underline = module.ADDTOVIEW.find('%') + if underline == -1: + underline = 0 + else: + self.__menutext = module.ADDTOVIEW.replace('%', '', 1) + self.__underline = underline + self.__window = None + + def menutext(self): + return self.__menutext + + def underline(self): + return self.__underline + + def popup(self, event=None): + if not self.__window: + # class and module must have the same name + class_ = getattr(self.__m, self.__name) + self.__window = class_(self.__sb, self.__root) + self.__sb.add_view(self.__window) + self.__window.deiconify() + + def __cmp__(self, other): + return cmp(self.__menutext, other.__menutext) + + +def make_view_popups(switchboard, root, extrapath): + viewers = [] + # where we are in the file system + dirs = [os.path.dirname(__file__)] + extrapath + for dir in dirs: + if dir == '': + dir = '.' + for file in os.listdir(dir): + if file[-9:] == 'Viewer.py': + name = file[:-3] + try: + module = __import__(name) + except ImportError: + # Pynche is running from inside a package, so get the + # module using the explicit path. + pkg = __import__('pynche.'+name) + module = getattr(pkg, name) + if hasattr(module, 'ADDTOVIEW') and module.ADDTOVIEW: + # this is an external viewer + v = PopupViewer(module, name, switchboard, root) + viewers.append(v) + # sort alphabetically + viewers.sort() + return viewers