blob: ae012bfa8a7724eec8c49884f1682afc753a2f75 [file] [log] [blame]
Guido van Rossum06981c31997-01-31 18:58:12 +00001#! /usr/bin/env python
2
3"""GUI interface to webchecker.
4
5This works as a Grail applet too! E.g.
6
Guido van Rossum4f6ecda1997-02-01 05:17:29 +00007 <APPLET CODE=wcgui.py NAME=CheckerWindow></APPLET>
Guido van Rossum06981c31997-01-31 18:58:12 +00008
Guido van Rossumaf310c11997-02-02 23:30:32 +00009Checkpoints are not (yet??? ever???) supported.
Guido van Rossum06981c31997-01-31 18:58:12 +000010
11User interface:
12
Guido van Rossum4f6ecda1997-02-01 05:17:29 +000013Enter a root to check in the text entry box. To enter more than one root,
Guido van Rossumaf310c11997-02-02 23:30:32 +000014enter them one at a time and press <Return> for each one.
Guido van Rossum4f6ecda1997-02-01 05:17:29 +000015
16Command buttons Start, Stop and "Check one" govern the checking process in
17the obvious way. Start and "Check one" also enter the root from the text
Guido van Rossumaf310c11997-02-02 23:30:32 +000018entry box if one is present. There's also a check box (enabled by default)
19to decide whether actually to follow external links (since this can slow
20the checking down considerably). Finally there's a Quit button.
Guido van Rossum4f6ecda1997-02-01 05:17:29 +000021
22A series of checkbuttons determines whether the corresponding output panel
23is shown. List panels are also automatically shown or hidden when their
24status changes between empty to non-empty. There are six panels:
Guido van Rossum06981c31997-01-31 18:58:12 +000025
26Log -- raw output from the checker (-v, -q affect this)
Guido van Rossumaf310c11997-02-02 23:30:32 +000027To check -- links discovered but not yet checked
28Checked -- links that have been checked
Guido van Rossum06981c31997-01-31 18:58:12 +000029Bad links -- links that failed upon checking
Guido van Rossumaf310c11997-02-02 23:30:32 +000030Errors -- pages containing at least one bad link
Guido van Rossum06981c31997-01-31 18:58:12 +000031Details -- details about one URL; double click on a URL in any of
Guido van Rossumaf310c11997-02-02 23:30:32 +000032 the above list panels (not in Log) will show details
33 for that URL
Guido van Rossum4f6ecda1997-02-01 05:17:29 +000034
Guido van Rossum06981c31997-01-31 18:58:12 +000035Use your window manager's Close command to quit.
36
37Command line options:
38
39-m bytes -- skip HTML pages larger than this size (default %(MAXPAGE)d)
Guido van Rossum06981c31997-01-31 18:58:12 +000040-q -- quiet operation (also suppresses external links report)
41-v -- verbose operation; repeating -v will increase verbosity
Guido van Rossuma8946401999-11-17 15:03:52 +000042-t root -- specify root dir which should be treated as internal (can repeat)
43-a -- don't check name anchors
Guido van Rossum06981c31997-01-31 18:58:12 +000044
45Command line arguments:
46
47rooturl -- URL to start checking
48 (default %(DEFROOT)s)
49
Guido van Rossumaf310c11997-02-02 23:30:32 +000050XXX The command line options (-m, -q, -v) should be GUI accessible.
Guido van Rossum06981c31997-01-31 18:58:12 +000051
Guido van Rossum4f6ecda1997-02-01 05:17:29 +000052XXX The roots should be visible as a list (?).
Guido van Rossum06981c31997-01-31 18:58:12 +000053
Guido van Rossumaf310c11997-02-02 23:30:32 +000054XXX The multipanel user interface is clumsy.
Guido van Rossum06981c31997-01-31 18:58:12 +000055
56"""
57
58# ' Emacs bait
59
60
61import sys
62import getopt
63import string
64from Tkinter import *
65import tktools
Guido van Rossum497a1981999-11-17 15:40:48 +000066import webchecker
Guido van Rossum06981c31997-01-31 18:58:12 +000067import random
68
Guido van Rossum4f6ecda1997-02-01 05:17:29 +000069# Override some for a weaker platform
70if sys.platform == 'mac':
71 webchecker.DEFROOT = "http://grail.cnri.reston.va.us/"
72 webchecker.MAXPAGE = 50000
73 webchecker.verbose = 4
Guido van Rossum06981c31997-01-31 18:58:12 +000074
75def main():
Guido van Rossum06981c31997-01-31 18:58:12 +000076 try:
Guido van Rossuma8946401999-11-17 15:03:52 +000077 opts, args = getopt.getopt(sys.argv[1:], 't:m:qva')
Guido van Rossum06981c31997-01-31 18:58:12 +000078 except getopt.error, msg:
Guido van Rossum986abac1998-04-06 14:29:28 +000079 sys.stdout = sys.stderr
80 print msg
81 print __doc__%vars(webchecker)
82 sys.exit(2)
Guido van Rossuma8946401999-11-17 15:03:52 +000083 webchecker.verbose = webchecker.VERBOSE
84 webchecker.nonames = webchecker.NONAMES
85 webchecker.maxpage = webchecker.MAXPAGE
86 extra_roots = []
Guido van Rossum06981c31997-01-31 18:58:12 +000087 for o, a in opts:
Guido van Rossum986abac1998-04-06 14:29:28 +000088 if o == '-m':
89 webchecker.maxpage = string.atoi(a)
90 if o == '-q':
91 webchecker.verbose = 0
92 if o == '-v':
93 webchecker.verbose = webchecker.verbose + 1
Guido van Rossuma8946401999-11-17 15:03:52 +000094 if o == '-t':
95 extra_roots.append(a)
96 if o == '-a':
97 webchecker.nonames = not webchecker.nonames
Guido van Rossum06981c31997-01-31 18:58:12 +000098 root = Tk(className='Webchecker')
99 root.protocol("WM_DELETE_WINDOW", root.quit)
Guido van Rossum4f6ecda1997-02-01 05:17:29 +0000100 c = CheckerWindow(root)
Guido van Rossuma8946401999-11-17 15:03:52 +0000101 c.setflags(verbose=webchecker.verbose, maxpage=webchecker.maxpage,
102 nonames=webchecker.nonames)
Guido van Rossum4f6ecda1997-02-01 05:17:29 +0000103 if args:
Guido van Rossum986abac1998-04-06 14:29:28 +0000104 for arg in args[:-1]:
105 c.addroot(arg)
106 c.suggestroot(args[-1])
Guido van Rossuma8946401999-11-17 15:03:52 +0000107 # Usually conditioned on whether external links
108 # will be checked, but since that's not a command
109 # line option, just toss them in.
110 for url_root in extra_roots:
111 # Make sure it's terminated by a slash,
112 # so that addroot doesn't discard the last
113 # directory component.
114 if url_root[-1] != "/":
115 url_root = url_root + "/"
116 c.addroot(url_root, add_to_do = 0)
Guido van Rossum06981c31997-01-31 18:58:12 +0000117 root.mainloop()
118
119
120class CheckerWindow(webchecker.Checker):
121
Guido van Rossum4f6ecda1997-02-01 05:17:29 +0000122 def __init__(self, parent, root=webchecker.DEFROOT):
Guido van Rossum986abac1998-04-06 14:29:28 +0000123 self.__parent = parent
Guido van Rossumaf310c11997-02-02 23:30:32 +0000124
Guido van Rossum986abac1998-04-06 14:29:28 +0000125 self.__topcontrols = Frame(parent)
126 self.__topcontrols.pack(side=TOP, fill=X)
127 self.__label = Label(self.__topcontrols, text="Root URL:")
128 self.__label.pack(side=LEFT)
129 self.__rootentry = Entry(self.__topcontrols, width=60)
130 self.__rootentry.pack(side=LEFT)
131 self.__rootentry.bind('<Return>', self.enterroot)
132 self.__rootentry.focus_set()
Guido van Rossumaf310c11997-02-02 23:30:32 +0000133
Guido van Rossum986abac1998-04-06 14:29:28 +0000134 self.__controls = Frame(parent)
135 self.__controls.pack(side=TOP, fill=X)
136 self.__running = 0
137 self.__start = Button(self.__controls, text="Run", command=self.start)
138 self.__start.pack(side=LEFT)
139 self.__stop = Button(self.__controls, text="Stop", command=self.stop,
140 state=DISABLED)
141 self.__stop.pack(side=LEFT)
142 self.__step = Button(self.__controls, text="Check one",
143 command=self.step)
144 self.__step.pack(side=LEFT)
145 self.__cv = BooleanVar(parent)
146 self.__cv.set(self.checkext)
147 self.__checkext = Checkbutton(self.__controls, variable=self.__cv,
148 command=self.update_checkext,
149 text="Check nonlocal links",)
150 self.__checkext.pack(side=LEFT)
151 self.__reset = Button(self.__controls, text="Start over", command=self.reset)
152 self.__reset.pack(side=LEFT)
153 if __name__ == '__main__': # No Quit button under Grail!
154 self.__quit = Button(self.__controls, text="Quit",
155 command=self.__parent.quit)
156 self.__quit.pack(side=RIGHT)
Guido van Rossumaf310c11997-02-02 23:30:32 +0000157
Guido van Rossum986abac1998-04-06 14:29:28 +0000158 self.__status = Label(parent, text="Status: initial", anchor=W)
159 self.__status.pack(side=TOP, fill=X)
160 self.__checking = Label(parent, text="Idle", anchor=W)
161 self.__checking.pack(side=TOP, fill=X)
162 self.__mp = mp = MultiPanel(parent)
163 sys.stdout = self.__log = LogPanel(mp, "Log")
Guido van Rossuma8946401999-11-17 15:03:52 +0000164 self.__todo = ListPanel(mp, "To check", self, self.showinfo)
165 self.__done = ListPanel(mp, "Checked", self, self.showinfo)
166 self.__bad = ListPanel(mp, "Bad links", self, self.showinfo)
167 self.__errors = ListPanel(mp, "Pages w/ bad links", self, self.showinfo)
Guido van Rossum986abac1998-04-06 14:29:28 +0000168 self.__details = LogPanel(mp, "Details")
Guido van Rossuma8946401999-11-17 15:03:52 +0000169 self.root_seed = None
Guido van Rossum986abac1998-04-06 14:29:28 +0000170 webchecker.Checker.__init__(self)
171 if root:
172 root = string.strip(str(root))
173 if root:
174 self.suggestroot(root)
175 self.newstatus()
Guido van Rossumaf310c11997-02-02 23:30:32 +0000176
Guido van Rossumaf310c11997-02-02 23:30:32 +0000177 def reset(self):
Guido van Rossum986abac1998-04-06 14:29:28 +0000178 webchecker.Checker.reset(self)
179 for p in self.__todo, self.__done, self.__bad, self.__errors:
180 p.clear()
Guido van Rossuma8946401999-11-17 15:03:52 +0000181 if self.root_seed:
182 self.suggestroot(self.root_seed)
Guido van Rossum4f6ecda1997-02-01 05:17:29 +0000183
184 def suggestroot(self, root):
Guido van Rossum986abac1998-04-06 14:29:28 +0000185 self.__rootentry.delete(0, END)
186 self.__rootentry.insert(END, root)
187 self.__rootentry.select_range(0, END)
Guido van Rossuma8946401999-11-17 15:03:52 +0000188 self.root_seed = root
Guido van Rossum4f6ecda1997-02-01 05:17:29 +0000189
190 def enterroot(self, event=None):
Guido van Rossum986abac1998-04-06 14:29:28 +0000191 root = self.__rootentry.get()
192 root = string.strip(root)
193 if root:
194 self.__checking.config(text="Adding root "+root)
195 self.__checking.update_idletasks()
196 self.addroot(root)
197 self.__checking.config(text="Idle")
198 try:
199 i = self.__todo.items.index(root)
200 except (ValueError, IndexError):
201 pass
202 else:
203 self.__todo.list.select_clear(0, END)
204 self.__todo.list.select_set(i)
205 self.__todo.list.yview(i)
206 self.__rootentry.delete(0, END)
Guido van Rossum4f6ecda1997-02-01 05:17:29 +0000207
208 def start(self):
Guido van Rossum986abac1998-04-06 14:29:28 +0000209 self.__start.config(state=DISABLED, relief=SUNKEN)
210 self.__stop.config(state=NORMAL)
211 self.__step.config(state=DISABLED)
212 self.enterroot()
213 self.__running = 1
214 self.go()
Guido van Rossum4f6ecda1997-02-01 05:17:29 +0000215
216 def stop(self):
Guido van Rossum986abac1998-04-06 14:29:28 +0000217 self.__stop.config(state=DISABLED, relief=SUNKEN)
218 self.__running = 0
Guido van Rossum4f6ecda1997-02-01 05:17:29 +0000219
220 def step(self):
Guido van Rossum986abac1998-04-06 14:29:28 +0000221 self.__start.config(state=DISABLED)
222 self.__step.config(state=DISABLED, relief=SUNKEN)
223 self.enterroot()
224 self.__running = 0
225 self.dosomething()
Guido van Rossum06981c31997-01-31 18:58:12 +0000226
227 def go(self):
Guido van Rossum986abac1998-04-06 14:29:28 +0000228 if self.__running:
229 self.__parent.after_idle(self.dosomething)
230 else:
231 self.__checking.config(text="Idle")
232 self.__start.config(state=NORMAL, relief=RAISED)
233 self.__stop.config(state=DISABLED, relief=RAISED)
234 self.__step.config(state=NORMAL, relief=RAISED)
Guido van Rossum4f6ecda1997-02-01 05:17:29 +0000235
236 __busy = 0
Guido van Rossum06981c31997-01-31 18:58:12 +0000237
238 def dosomething(self):
Guido van Rossum986abac1998-04-06 14:29:28 +0000239 if self.__busy: return
240 self.__busy = 1
241 if self.todo:
242 l = self.__todo.selectedindices()
243 if l:
244 i = l[0]
245 else:
246 i = 0
247 self.__todo.list.select_set(i)
248 self.__todo.list.yview(i)
249 url = self.__todo.items[i]
Guido van Rossuma8946401999-11-17 15:03:52 +0000250 self.__checking.config(text="Checking "+self.format_url(url))
Guido van Rossum986abac1998-04-06 14:29:28 +0000251 self.__parent.update()
252 self.dopage(url)
253 else:
254 self.stop()
255 self.__busy = 0
256 self.go()
Guido van Rossum06981c31997-01-31 18:58:12 +0000257
258 def showinfo(self, url):
Guido van Rossum986abac1998-04-06 14:29:28 +0000259 d = self.__details
260 d.clear()
Guido van Rossuma8946401999-11-17 15:03:52 +0000261 d.put("URL: %s\n" % self.format_url(url))
Guido van Rossum986abac1998-04-06 14:29:28 +0000262 if self.bad.has_key(url):
263 d.put("Error: %s\n" % str(self.bad[url]))
264 if url in self.roots:
265 d.put("Note: This is a root URL\n")
266 if self.done.has_key(url):
267 d.put("Status: checked\n")
268 o = self.done[url]
269 elif self.todo.has_key(url):
270 d.put("Status: to check\n")
271 o = self.todo[url]
272 else:
273 d.put("Status: unknown (!)\n")
274 o = []
Guido van Rossuma8946401999-11-17 15:03:52 +0000275 if (not url[1]) and self.errors.has_key(url[0]):
Guido van Rossum986abac1998-04-06 14:29:28 +0000276 d.put("Bad links from this page:\n")
Guido van Rossuma8946401999-11-17 15:03:52 +0000277 for triple in self.errors[url[0]]:
Guido van Rossum986abac1998-04-06 14:29:28 +0000278 link, rawlink, msg = triple
Guido van Rossuma8946401999-11-17 15:03:52 +0000279 d.put(" HREF %s" % self.format_url(link))
280 if self.format_url(link) != rawlink: d.put(" (%s)" %rawlink)
Guido van Rossum986abac1998-04-06 14:29:28 +0000281 d.put("\n")
282 d.put(" error %s\n" % str(msg))
283 self.__mp.showpanel("Details")
284 for source, rawlink in o:
285 d.put("Origin: %s" % source)
Guido van Rossuma8946401999-11-17 15:03:52 +0000286 if rawlink != self.format_url(url):
Guido van Rossum986abac1998-04-06 14:29:28 +0000287 d.put(" (%s)" % rawlink)
288 d.put("\n")
289 d.text.yview("1.0")
Guido van Rossum06981c31997-01-31 18:58:12 +0000290
291 def setbad(self, url, msg):
Guido van Rossum986abac1998-04-06 14:29:28 +0000292 webchecker.Checker.setbad(self, url, msg)
293 self.__bad.insert(url)
294 self.newstatus()
Guido van Rossum06981c31997-01-31 18:58:12 +0000295
296 def setgood(self, url):
Guido van Rossum986abac1998-04-06 14:29:28 +0000297 webchecker.Checker.setgood(self, url)
298 self.__bad.remove(url)
299 self.newstatus()
Guido van Rossum06981c31997-01-31 18:58:12 +0000300
Guido van Rossumaf310c11997-02-02 23:30:32 +0000301 def newlink(self, url, origin):
Guido van Rossum986abac1998-04-06 14:29:28 +0000302 webchecker.Checker.newlink(self, url, origin)
303 if self.done.has_key(url):
304 self.__done.insert(url)
305 elif self.todo.has_key(url):
306 self.__todo.insert(url)
307 self.newstatus()
Guido van Rossum06981c31997-01-31 18:58:12 +0000308
309 def markdone(self, url):
Guido van Rossum986abac1998-04-06 14:29:28 +0000310 webchecker.Checker.markdone(self, url)
311 self.__done.insert(url)
312 self.__todo.remove(url)
313 self.newstatus()
Guido van Rossum06981c31997-01-31 18:58:12 +0000314
Guido van Rossumaf310c11997-02-02 23:30:32 +0000315 def seterror(self, url, triple):
Guido van Rossum986abac1998-04-06 14:29:28 +0000316 webchecker.Checker.seterror(self, url, triple)
Guido van Rossuma8946401999-11-17 15:03:52 +0000317 self.__errors.insert((url, ''))
Guido van Rossum986abac1998-04-06 14:29:28 +0000318 self.newstatus()
Guido van Rossumaf310c11997-02-02 23:30:32 +0000319
320 def newstatus(self):
Guido van Rossum986abac1998-04-06 14:29:28 +0000321 self.__status.config(text="Status: "+self.status())
322 self.__parent.update()
Guido van Rossumaf310c11997-02-02 23:30:32 +0000323
Guido van Rossum88b02cf1998-03-05 20:12:18 +0000324 def update_checkext(self):
Guido van Rossum986abac1998-04-06 14:29:28 +0000325 self.checkext = self.__cv.get()
Guido van Rossum88b02cf1998-03-05 20:12:18 +0000326
Guido van Rossum06981c31997-01-31 18:58:12 +0000327
328class ListPanel:
329
Guido van Rossuma8946401999-11-17 15:03:52 +0000330 def __init__(self, mp, name, checker, showinfo=None):
Guido van Rossum986abac1998-04-06 14:29:28 +0000331 self.mp = mp
332 self.name = name
333 self.showinfo = showinfo
Guido van Rossuma8946401999-11-17 15:03:52 +0000334 self.checker = checker
Guido van Rossum986abac1998-04-06 14:29:28 +0000335 self.panel = mp.addpanel(name)
336 self.list, self.frame = tktools.make_list_box(
337 self.panel, width=60, height=5)
338 self.list.config(exportselection=0)
339 if showinfo:
340 self.list.bind('<Double-Button-1>', self.doubleclick)
341 self.items = []
Guido van Rossum06981c31997-01-31 18:58:12 +0000342
Guido van Rossumaf310c11997-02-02 23:30:32 +0000343 def clear(self):
Guido van Rossum986abac1998-04-06 14:29:28 +0000344 self.items = []
345 self.list.delete(0, END)
346 self.mp.hidepanel(self.name)
Guido van Rossumaf310c11997-02-02 23:30:32 +0000347
Guido van Rossum4f6ecda1997-02-01 05:17:29 +0000348 def doubleclick(self, event):
Guido van Rossum986abac1998-04-06 14:29:28 +0000349 l = self.selectedindices()
350 if l:
Guido van Rossuma8946401999-11-17 15:03:52 +0000351 self.showinfo(self.items[l[0]])
Guido van Rossum4f6ecda1997-02-01 05:17:29 +0000352
353 def selectedindices(self):
Guido van Rossum986abac1998-04-06 14:29:28 +0000354 l = self.list.curselection()
355 if not l: return []
356 return map(string.atoi, l)
Guido van Rossum06981c31997-01-31 18:58:12 +0000357
358 def insert(self, url):
Guido van Rossum986abac1998-04-06 14:29:28 +0000359 if url not in self.items:
360 if not self.items:
361 self.mp.showpanel(self.name)
362 # (I tried sorting alphabetically, but the display is too jumpy)
363 i = len(self.items)
Guido van Rossuma8946401999-11-17 15:03:52 +0000364 self.list.insert(i, self.checker.format_url(url))
Guido van Rossum986abac1998-04-06 14:29:28 +0000365 self.list.yview(i)
366 self.items.insert(i, url)
Guido van Rossum06981c31997-01-31 18:58:12 +0000367
368 def remove(self, url):
Guido van Rossum986abac1998-04-06 14:29:28 +0000369 try:
370 i = self.items.index(url)
371 except (ValueError, IndexError):
372 pass
373 else:
374 was_selected = i in self.selectedindices()
375 self.list.delete(i)
376 del self.items[i]
377 if not self.items:
378 self.mp.hidepanel(self.name)
379 elif was_selected:
380 if i >= len(self.items):
381 i = len(self.items) - 1
382 self.list.select_set(i)
Guido van Rossum06981c31997-01-31 18:58:12 +0000383
384
385class LogPanel:
386
387 def __init__(self, mp, name):
Guido van Rossum986abac1998-04-06 14:29:28 +0000388 self.mp = mp
389 self.name = name
390 self.panel = mp.addpanel(name)
391 self.text, self.frame = tktools.make_text_box(self.panel, height=10)
392 self.text.config(wrap=NONE)
Guido van Rossum06981c31997-01-31 18:58:12 +0000393
394 def clear(self):
Guido van Rossum986abac1998-04-06 14:29:28 +0000395 self.text.delete("1.0", END)
396 self.text.yview("1.0")
Guido van Rossum06981c31997-01-31 18:58:12 +0000397
Guido van Rossumaf310c11997-02-02 23:30:32 +0000398 def put(self, s):
Guido van Rossum986abac1998-04-06 14:29:28 +0000399 self.text.insert(END, s)
400 if '\n' in s:
401 self.text.yview(END)
Guido van Rossumaf310c11997-02-02 23:30:32 +0000402
Guido van Rossum06981c31997-01-31 18:58:12 +0000403 def write(self, s):
Guido van Rossum986abac1998-04-06 14:29:28 +0000404 self.text.insert(END, s)
405 if '\n' in s:
406 self.text.yview(END)
407 self.panel.update()
Guido van Rossum06981c31997-01-31 18:58:12 +0000408
409
410class MultiPanel:
411
412 def __init__(self, parent):
Guido van Rossum986abac1998-04-06 14:29:28 +0000413 self.parent = parent
414 self.frame = Frame(self.parent)
415 self.frame.pack(expand=1, fill=BOTH)
416 self.topframe = Frame(self.frame, borderwidth=2, relief=RAISED)
417 self.topframe.pack(fill=X)
418 self.botframe = Frame(self.frame)
419 self.botframe.pack(expand=1, fill=BOTH)
420 self.panelnames = []
421 self.panels = {}
Guido van Rossum06981c31997-01-31 18:58:12 +0000422
423 def addpanel(self, name, on=0):
Guido van Rossum986abac1998-04-06 14:29:28 +0000424 v = StringVar(self.parent)
425 if on:
426 v.set(name)
427 else:
428 v.set("")
429 check = Checkbutton(self.topframe, text=name,
430 offvalue="", onvalue=name, variable=v,
431 command=self.checkpanel)
432 check.pack(side=LEFT)
433 panel = Frame(self.botframe)
434 label = Label(panel, text=name, borderwidth=2, relief=RAISED, anchor=W)
435 label.pack(side=TOP, fill=X)
436 t = v, check, panel
437 self.panelnames.append(name)
438 self.panels[name] = t
439 if on:
440 panel.pack(expand=1, fill=BOTH)
441 return panel
Guido van Rossum06981c31997-01-31 18:58:12 +0000442
443 def showpanel(self, name):
Guido van Rossum986abac1998-04-06 14:29:28 +0000444 v, check, panel = self.panels[name]
445 v.set(name)
446 panel.pack(expand=1, fill=BOTH)
Guido van Rossum06981c31997-01-31 18:58:12 +0000447
448 def hidepanel(self, name):
Guido van Rossum986abac1998-04-06 14:29:28 +0000449 v, check, panel = self.panels[name]
450 v.set("")
451 panel.pack_forget()
Guido van Rossum06981c31997-01-31 18:58:12 +0000452
453 def checkpanel(self):
Guido van Rossum986abac1998-04-06 14:29:28 +0000454 for name in self.panelnames:
455 v, check, panel = self.panels[name]
456 panel.pack_forget()
457 for name in self.panelnames:
458 v, check, panel = self.panels[name]
459 if v.get():
460 panel.pack(expand=1, fill=BOTH)
Guido van Rossum06981c31997-01-31 18:58:12 +0000461
462
463if __name__ == '__main__':
464 main()