symbian-qemu-0.9.1-12/python-2.6.1/Tools/pynche/PyncheWidget.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """Main Pynche (Pythonically Natural Color and Hue Editor) widget.
       
     2 
       
     3 This window provides the basic decorations, primarily including the menubar.
       
     4 It is used to bring up other windows.
       
     5 """
       
     6 
       
     7 import sys
       
     8 import os
       
     9 from Tkinter import *
       
    10 import tkMessageBox
       
    11 import tkFileDialog
       
    12 import ColorDB
       
    13 
       
    14 # Milliseconds between interrupt checks
       
    15 KEEPALIVE_TIMER = 500
       
    16 
       
    17 
       
    18 
       
    19 class PyncheWidget:
       
    20     def __init__(self, version, switchboard, master=None, extrapath=[]):
       
    21         self.__sb = switchboard
       
    22         self.__version = version
       
    23         self.__textwin = None
       
    24         self.__listwin = None
       
    25         self.__detailswin = None
       
    26         self.__helpwin = None
       
    27         self.__dialogstate = {}
       
    28         modal = self.__modal = not not master
       
    29         # If a master was given, we are running as a modal dialog servant to
       
    30         # some other application.  We rearrange our UI in this case (there's
       
    31         # no File menu and we get `Okay' and `Cancel' buttons), and we do a
       
    32         # grab_set() to make ourselves modal
       
    33         if modal:
       
    34             self.__tkroot = tkroot = Toplevel(master, class_='Pynche')
       
    35             tkroot.grab_set()
       
    36             tkroot.withdraw()
       
    37         else:
       
    38             # Is there already a default root for Tk, say because we're
       
    39             # running under Guido's IDE? :-) Two conditions say no, either the
       
    40             # import fails or _default_root is None.
       
    41             tkroot = None
       
    42             try:
       
    43                 from Tkinter import _default_root
       
    44                 tkroot = self.__tkroot = _default_root
       
    45             except ImportError:
       
    46                 pass
       
    47             if not tkroot:
       
    48                 tkroot = self.__tkroot = Tk(className='Pynche')
       
    49             # but this isn't our top level widget, so make it invisible
       
    50             tkroot.withdraw()
       
    51         # create the menubar
       
    52         menubar = self.__menubar = Menu(tkroot)
       
    53         #
       
    54         # File menu
       
    55         #
       
    56         filemenu = self.__filemenu = Menu(menubar, tearoff=0)
       
    57         filemenu.add_command(label='Load palette...',
       
    58                              command=self.__load,
       
    59                              underline=0)
       
    60         if not modal:
       
    61             filemenu.add_command(label='Quit',
       
    62                                  command=self.__quit,
       
    63                                  accelerator='Alt-Q',
       
    64                                  underline=0)
       
    65         #
       
    66         # View menu
       
    67         #
       
    68         views = make_view_popups(self.__sb, self.__tkroot, extrapath)
       
    69         viewmenu = Menu(menubar, tearoff=0)
       
    70         for v in views:
       
    71             viewmenu.add_command(label=v.menutext(),
       
    72                                  command=v.popup,
       
    73                                  underline=v.underline())
       
    74         #
       
    75         # Help menu
       
    76         #
       
    77         helpmenu = Menu(menubar, name='help', tearoff=0)
       
    78         helpmenu.add_command(label='About Pynche...',
       
    79                              command=self.__popup_about,
       
    80                              underline=0)
       
    81         helpmenu.add_command(label='Help...',
       
    82                              command=self.__popup_usage,
       
    83                              underline=0)
       
    84         #
       
    85         # Tie them all together
       
    86         #
       
    87         menubar.add_cascade(label='File',
       
    88                             menu=filemenu,
       
    89                             underline=0)
       
    90         menubar.add_cascade(label='View',
       
    91                             menu=viewmenu,
       
    92                             underline=0)
       
    93         menubar.add_cascade(label='Help',
       
    94                             menu=helpmenu,
       
    95                             underline=0)
       
    96 
       
    97         # now create the top level window
       
    98         root = self.__root = Toplevel(tkroot, class_='Pynche', menu=menubar)
       
    99         root.protocol('WM_DELETE_WINDOW',
       
   100                       modal and self.__bell or self.__quit)
       
   101         root.title('Pynche %s' % version)
       
   102         root.iconname('Pynche')
       
   103         # Only bind accelerators for the File->Quit menu item if running as a
       
   104         # standalone app
       
   105         if not modal:
       
   106             root.bind('<Alt-q>', self.__quit)
       
   107             root.bind('<Alt-Q>', self.__quit)
       
   108         else:
       
   109             # We're a modal dialog so we have a new row of buttons
       
   110             bframe = Frame(root, borderwidth=1, relief=RAISED)
       
   111             bframe.grid(row=4, column=0, columnspan=2,
       
   112                         sticky='EW',
       
   113                         ipady=5)
       
   114             okay = Button(bframe,
       
   115                           text='Okay',
       
   116                           command=self.__okay)
       
   117             okay.pack(side=LEFT, expand=1)
       
   118             cancel = Button(bframe,
       
   119                             text='Cancel',
       
   120                             command=self.__cancel)
       
   121             cancel.pack(side=LEFT, expand=1)
       
   122 
       
   123     def __quit(self, event=None):
       
   124         self.__tkroot.quit()
       
   125 
       
   126     def __bell(self, event=None):
       
   127         self.__tkroot.bell()
       
   128 
       
   129     def __okay(self, event=None):
       
   130         self.__sb.withdraw_views()
       
   131         self.__tkroot.grab_release()
       
   132         self.__quit()
       
   133 
       
   134     def __cancel(self, event=None):
       
   135         self.__sb.canceled()
       
   136         self.__okay()
       
   137 
       
   138     def __keepalive(self):
       
   139         # Exercise the Python interpreter regularly so keyboard interrupts get
       
   140         # through.
       
   141         self.__tkroot.tk.createtimerhandler(KEEPALIVE_TIMER, self.__keepalive)
       
   142 
       
   143     def start(self):
       
   144         if not self.__modal:
       
   145             self.__keepalive()
       
   146         self.__tkroot.mainloop()
       
   147 
       
   148     def window(self):
       
   149         return self.__root
       
   150 
       
   151     def __popup_about(self, event=None):
       
   152         from Main import __version__
       
   153         tkMessageBox.showinfo('About Pynche ' + __version__,
       
   154                               '''\
       
   155 Pynche %s
       
   156 The PYthonically Natural
       
   157 Color and Hue Editor
       
   158 
       
   159 For information
       
   160 contact: Barry A. Warsaw
       
   161 email:   bwarsaw@python.org''' % __version__)
       
   162 
       
   163     def __popup_usage(self, event=None):
       
   164         if not self.__helpwin:
       
   165             self.__helpwin = Helpwin(self.__root, self.__quit)
       
   166         self.__helpwin.deiconify()
       
   167 
       
   168     def __load(self, event=None):
       
   169         while 1:
       
   170             idir, ifile = os.path.split(self.__sb.colordb().filename())
       
   171             file = tkFileDialog.askopenfilename(
       
   172                 filetypes=[('Text files', '*.txt'),
       
   173                            ('All files', '*'),
       
   174                            ],
       
   175                 initialdir=idir,
       
   176                 initialfile=ifile)
       
   177             if not file:
       
   178                 # cancel button
       
   179                 return
       
   180             try:
       
   181                 colordb = ColorDB.get_colordb(file)
       
   182             except IOError:
       
   183                 tkMessageBox.showerror('Read error', '''\
       
   184 Could not open file for reading:
       
   185 %s''' % file)
       
   186                 continue
       
   187             if colordb is None:
       
   188                 tkMessageBox.showerror('Unrecognized color file type', '''\
       
   189 Unrecognized color file type in file:
       
   190 %s''' % file)
       
   191                 continue
       
   192             break
       
   193         self.__sb.set_colordb(colordb)
       
   194 
       
   195     def withdraw(self):
       
   196         self.__root.withdraw()
       
   197 
       
   198     def deiconify(self):
       
   199         self.__root.deiconify()
       
   200 
       
   201 
       
   202 
       
   203 class Helpwin:
       
   204     def __init__(self, master, quitfunc):
       
   205         from Main import docstring
       
   206         self.__root = root = Toplevel(master, class_='Pynche')
       
   207         root.protocol('WM_DELETE_WINDOW', self.__withdraw)
       
   208         root.title('Pynche Help Window')
       
   209         root.iconname('Pynche Help Window')
       
   210         root.bind('<Alt-q>', quitfunc)
       
   211         root.bind('<Alt-Q>', quitfunc)
       
   212         root.bind('<Alt-w>', self.__withdraw)
       
   213         root.bind('<Alt-W>', self.__withdraw)
       
   214 
       
   215         # more elaborate help is available in the README file
       
   216         readmefile = os.path.join(sys.path[0], 'README')
       
   217         try:
       
   218             fp = None
       
   219             try:
       
   220                 fp = open(readmefile)
       
   221                 contents = fp.read()
       
   222                 # wax the last page, it contains Emacs cruft
       
   223                 i = contents.rfind('\f')
       
   224                 if i > 0:
       
   225                     contents = contents[:i].rstrip()
       
   226             finally:
       
   227                 if fp:
       
   228                     fp.close()
       
   229         except IOError:
       
   230             sys.stderr.write("Couldn't open Pynche's README, "
       
   231                              'using docstring instead.\n')
       
   232             contents = docstring()
       
   233 
       
   234         self.__text = text = Text(root, relief=SUNKEN,
       
   235                                   width=80, height=24)
       
   236         self.__text.focus_set()
       
   237         text.insert(0.0, contents)
       
   238         scrollbar = Scrollbar(root)
       
   239         scrollbar.pack(fill=Y, side=RIGHT)
       
   240         text.pack(fill=BOTH, expand=YES)
       
   241         text.configure(yscrollcommand=(scrollbar, 'set'))
       
   242         scrollbar.configure(command=(text, 'yview'))
       
   243 
       
   244     def __withdraw(self, event=None):
       
   245         self.__root.withdraw()
       
   246 
       
   247     def deiconify(self):
       
   248         self.__root.deiconify()
       
   249 
       
   250 
       
   251 
       
   252 class PopupViewer:
       
   253     def __init__(self, module, name, switchboard, root):
       
   254         self.__m = module
       
   255         self.__name = name
       
   256         self.__sb = switchboard
       
   257         self.__root = root
       
   258         self.__menutext = module.ADDTOVIEW
       
   259         # find the underline character
       
   260         underline = module.ADDTOVIEW.find('%')
       
   261         if underline == -1:
       
   262             underline = 0
       
   263         else:
       
   264             self.__menutext = module.ADDTOVIEW.replace('%', '', 1)
       
   265         self.__underline = underline
       
   266         self.__window = None
       
   267 
       
   268     def menutext(self):
       
   269         return self.__menutext
       
   270 
       
   271     def underline(self):
       
   272         return self.__underline
       
   273 
       
   274     def popup(self, event=None):
       
   275         if not self.__window:
       
   276             # class and module must have the same name
       
   277             class_ = getattr(self.__m, self.__name)
       
   278             self.__window = class_(self.__sb, self.__root)
       
   279             self.__sb.add_view(self.__window)
       
   280         self.__window.deiconify()
       
   281 
       
   282     def __cmp__(self, other):
       
   283         return cmp(self.__menutext, other.__menutext)
       
   284 
       
   285 
       
   286 def make_view_popups(switchboard, root, extrapath):
       
   287     viewers = []
       
   288     # where we are in the file system
       
   289     dirs = [os.path.dirname(__file__)] + extrapath
       
   290     for dir in dirs:
       
   291         if dir == '':
       
   292             dir = '.'
       
   293         for file in os.listdir(dir):
       
   294             if file[-9:] == 'Viewer.py':
       
   295                 name = file[:-3]
       
   296                 try:
       
   297                     module = __import__(name)
       
   298                 except ImportError:
       
   299                     # Pynche is running from inside a package, so get the
       
   300                     # module using the explicit path.
       
   301                     pkg = __import__('pynche.'+name)
       
   302                     module = getattr(pkg, name)
       
   303                 if hasattr(module, 'ADDTOVIEW') and module.ADDTOVIEW:
       
   304                     # this is an external viewer
       
   305                     v = PopupViewer(module, name, switchboard, root)
       
   306                     viewers.append(v)
       
   307     # sort alphabetically
       
   308     viewers.sort()
       
   309     return viewers