1 """Main Pynche (Pythonically Natural Color and Hue Editor) widget.
3 This window provides the basic decorations, primarily including the menubar.
4 It is used to bring up other windows.
15 # Milliseconds between interrupt checks
21 def __init__(self
, version
, switchboard
, master
=None, extrapath
=[]):
22 self
.__sb
= switchboard
23 self
.__version
= version
26 self
.__detailswin
= None
28 self
.__dialogstate
= {}
29 modal
= self
.__modal
= not not master
30 # If a master was given, we are running as a modal dialog servant to
31 # some other application. We rearrange our UI in this case (there's
32 # no File menu and we get `Okay' and `Cancel' buttons), and we do a
33 # grab_set() to make ourselves modal
35 self
.__tkroot
= tkroot
= Toplevel(master
, class_
='Pynche')
39 # Is there already a default root for Tk, say because we're
40 # running under Guido's IDE? :-) Two conditions say no, either the
41 # import fails or _default_root is None.
44 from Tkinter
import _default_root
45 tkroot
= self
.__tkroot
= _default_root
49 tkroot
= self
.__tkroot
= Tk(className
='Pynche')
50 # but this isn't our top level widget, so make it invisible
53 menubar
= self
.__menubar
= Menu(tkroot
)
57 filemenu
= self
.__filemenu
= Menu(menubar
, tearoff
=0)
58 filemenu
.add_command(label
='Load palette...',
62 filemenu
.add_command(label
='Quit',
69 views
= make_view_popups(self
.__sb
, self
.__tkroot
, extrapath
)
70 viewmenu
= Menu(menubar
, tearoff
=0)
72 viewmenu
.add_command(label
=v
.menutext(),
74 underline
=v
.underline())
78 helpmenu
= Menu(menubar
, name
='help', tearoff
=0)
79 helpmenu
.add_command(label
='About Pynche...',
80 command
=self
.__popup
_about
,
82 helpmenu
.add_command(label
='Help...',
83 command
=self
.__popup
_usage
,
86 # Tie them all together
88 menubar
.add_cascade(label
='File',
91 menubar
.add_cascade(label
='View',
94 menubar
.add_cascade(label
='Help',
98 # now create the top level window
99 root
= self
.__root
= Toplevel(tkroot
, class_
='Pynche', menu
=menubar
)
100 root
.protocol('WM_DELETE_WINDOW',
101 modal
and self
.__bell
or self
.__quit
)
102 root
.title('Pynche %s' % version
)
103 root
.iconname('Pynche')
104 # Only bind accelerators for the File->Quit menu item if running as a
107 root
.bind('<Alt-q>', self
.__quit
)
108 root
.bind('<Alt-Q>', self
.__quit
)
110 # We're a modal dialog so we have a new row of buttons
111 bframe
= Frame(root
, borderwidth
=1, relief
=RAISED
)
112 bframe
.grid(row
=4, column
=0, columnspan
=2,
115 okay
= Button(bframe
,
118 okay
.pack(side
=LEFT
, expand
=1)
119 cancel
= Button(bframe
,
121 command
=self
.__cancel
)
122 cancel
.pack(side
=LEFT
, expand
=1)
124 def __quit(self
, event
=None):
127 def __bell(self
, event
=None):
130 def __okay(self
, event
=None):
131 self
.__sb
.withdraw_views()
132 self
.__tkroot
.grab_release()
135 def __cancel(self
, event
=None):
139 def __keepalive(self
):
140 # Exercise the Python interpreter regularly so keyboard interrupts get
142 self
.__tkroot
.tk
.createtimerhandler(KEEPALIVE_TIMER
, self
.__keepalive
)
147 self
.__tkroot
.mainloop()
152 def __popup_about(self
, event
=None):
153 from Main
import __version__
154 tkMessageBox
.showinfo('About Pynche ' + __version__
,
157 The PYthonically Natural
161 contact: Barry A. Warsaw
162 email: bwarsaw@python.org''' % __version__
)
164 def __popup_usage(self
, event
=None):
165 if not self
.__helpwin
:
166 self
.__helpwin
= Helpwin(self
.__root
, self
.__quit
)
167 self
.__helpwin
.deiconify()
169 def __load(self
, event
=None):
171 idir
, ifile
= os
.path
.split(self
.__sb
.colordb().filename())
172 file = tkFileDialog
.askopenfilename(
173 filetypes
=[('Text files', '*.txt'),
182 colordb
= ColorDB
.get_colordb(file)
184 tkMessageBox
.showerror('Read error', '''\
185 Could not open file for reading:
189 tkMessageBox
.showerror('Unrecognized color file type', '''\
190 Unrecognized color file type in file:
194 self
.__sb
.set_colordb(colordb
)
197 self
.__root
.withdraw()
200 self
.__root
.deiconify()
205 def __init__(self
, master
, quitfunc
):
206 from Main
import __version__
, docstring
207 self
.__root
= root
= Toplevel(master
, class_
='Pynche')
208 root
.protocol('WM_DELETE_WINDOW', self
.__withdraw
)
209 root
.title('Pynche Help Window')
210 root
.iconname('Pynche Help Window')
211 root
.bind('<Alt-q>', quitfunc
)
212 root
.bind('<Alt-Q>', quitfunc
)
213 root
.bind('<Alt-w>', self
.__withdraw
)
214 root
.bind('<Alt-W>', self
.__withdraw
)
216 # more elaborate help is available in the README file
217 readmefile
= os
.path
.join(sys
.path
[0], 'README')
221 fp
= open(readmefile
)
223 # wax the last page, it contains Emacs cruft
224 i
= string
.rfind(contents
, '\f')
226 contents
= string
.rstrip(contents
[:i
])
231 sys
.stderr
.write("Couldn't open Pynche's README, "
232 'using docstring instead.\n')
233 contents
= docstring()
235 self
.__text
= text
= Text(root
, relief
=SUNKEN
,
237 self
.__text
.focus_set()
238 text
.insert(0.0, contents
)
239 scrollbar
= Scrollbar(root
)
240 scrollbar
.pack(fill
=Y
, side
=RIGHT
)
241 text
.pack(fill
=BOTH
, expand
=YES
)
242 text
.configure(yscrollcommand
=(scrollbar
, 'set'))
243 scrollbar
.configure(command
=(text
, 'yview'))
245 def __withdraw(self
, event
=None):
246 self
.__root
.withdraw()
249 self
.__root
.deiconify()
254 def __init__(self
, module
, name
, switchboard
, root
):
257 self
.__sb
= switchboard
259 self
.__menutext
= module
.ADDTOVIEW
260 # find the underline character
261 underline
= string
.find(module
.ADDTOVIEW
, '%')
265 self
.__menutext
= string
.replace(module
.ADDTOVIEW
, '%', '', 1)
266 self
.__underline
= underline
270 return self
.__menutext
273 return self
.__underline
275 def popup(self
, event
=None):
276 if not self
.__window
:
277 # class and module must have the same name
278 class_
= getattr(self
.__m
, self
.__name
)
279 self
.__window
= class_(self
.__sb
, self
.__root
)
280 self
.__sb
.add_view(self
.__window
)
281 self
.__window
.deiconify()
283 def __cmp__(self
, other
):
284 return cmp(self
.__menutext
, other
.__menutext
)
287 def make_view_popups(switchboard
, root
, extrapath
):
289 # where we are in the file system
290 dirs
= [os
.path
.dirname(__file__
)] + extrapath
294 for file in os
.listdir(dir):
295 if file[-9:] == 'Viewer.py':
298 module
= __import__(name
)
300 # Pynche is running from inside a package, so get the
301 # module using the explicit path.
302 pkg
= __import__('pynche.'+name
)
303 module
= getattr(pkg
, name
)
304 if hasattr(module
, 'ADDTOVIEW') and module
.ADDTOVIEW
:
305 # this is an external viewer
306 v
= PopupViewer(module
, name
, switchboard
, root
)
308 # sort alphabetically