Commits

Georg Brandl  committed 9bead90

Merged revisions 85820,85823,85825,85840,85843-85845,85849-85851,85855,85867,85875,85907-85908,85911,85914 via svnmerge from
svn+ssh://svn.python.org/python/branches/py3k

........
r85820 | georg.brandl | 2010-10-24 16:20:22 +0200 (So, 24 Okt 2010) | 1 line

Remove usage of exception indexing.
........
r85823 | georg.brandl | 2010-10-24 16:32:45 +0200 (So, 24 Okt 2010) | 1 line

Fix style.
........
r85825 | georg.brandl | 2010-10-24 17:16:02 +0200 (So, 24 Okt 2010) | 1 line

Add documentation about the default warnings filters.
........
r85840 | georg.brandl | 2010-10-25 19:50:20 +0200 (Mo, 25 Okt 2010) | 1 line

#3018: tkinter demo fixes for py3k.
........
r85843 | georg.brandl | 2010-10-26 08:59:23 +0200 (Di, 26 Okt 2010) | 1 line

Markup fix.
........
r85844 | georg.brandl | 2010-10-26 12:39:14 +0200 (Di, 26 Okt 2010) | 1 line

Work a bit more on tkinter demos.
........
r85845 | georg.brandl | 2010-10-26 12:42:16 +0200 (Di, 26 Okt 2010) | 1 line

faqwiz is removed.
........
r85849 | georg.brandl | 2010-10-26 21:31:06 +0200 (Di, 26 Okt 2010) | 1 line

#10200: typo.
........
r85850 | georg.brandl | 2010-10-26 21:58:11 +0200 (Di, 26 Okt 2010) | 1 line

#10200: typo.
........
r85851 | georg.brandl | 2010-10-26 22:12:37 +0200 (Di, 26 Okt 2010) | 1 line

Fix import.
........
r85855 | georg.brandl | 2010-10-27 09:21:54 +0200 (Mi, 27 Okt 2010) | 1 line

Encoding fix.
........
r85867 | georg.brandl | 2010-10-27 22:01:51 +0200 (Mi, 27 Okt 2010) | 1 line

Add David.
........
r85875 | georg.brandl | 2010-10-28 10:38:30 +0200 (Do, 28 Okt 2010) | 1 line

Fix bytes/str issues in get-remote-certificate.py.
........
r85907 | georg.brandl | 2010-10-29 06:54:13 +0200 (Fr, 29 Okt 2010) | 1 line

#10222: fix for overzealous AIX compiler.
........
r85908 | georg.brandl | 2010-10-29 07:22:17 +0200 (Fr, 29 Okt 2010) | 1 line

send_bytes obviously needs bytes...
........
r85911 | georg.brandl | 2010-10-29 07:36:28 +0200 (Fr, 29 Okt 2010) | 1 line

Fix markup error and update false positive entries from "make suspicious".
........
r85914 | georg.brandl | 2010-10-29 08:17:38 +0200 (Fr, 29 Okt 2010) | 1 line

(?:...) is a non-capturing, but still grouping construct.
........

  • Participants
  • Parent commits 05ee6f8
  • Branches 3.1

Comments (0)

Files changed (38)

File Demo/cgi/README

 CGI Examples
 ------------
 
-Here are some example CGI programs.  For a larger example, see
-../../Tools/faqwiz/.
+Here are some example CGI programs.
 
 cgi0.sh -- A shell script to test your server is configured for CGI
 cgi1.py -- A Python script to test your server is configured for CGI

File Demo/md5test/md5driver.py

     mdContext = md5()
 
     while 1:
-        data = sys.stdin.read(16)
+        data = sys.stdin.read(16).encode()
         if not data:
             break
         mdContext.update(data)

File Demo/tkinter/guido/AttrDialog.py

-
-# The options of a widget are described by the following attributes
-# of the Pack and Widget dialogs:
-#
-# Dialog.current: {name: value}
-# -- changes during Widget's lifetime
-#
-# Dialog.options: {name: (default, klass)}
-# -- depends on widget class only
-#
-# Dialog.classes: {klass: (v0, v1, v2, ...) | 'boolean' | 'other'}
-# -- totally static, though different between PackDialog and WidgetDialog
-#    (but even that could be unified)
-
-from tkinter import *
-
-class Option:
-
-    varclass = StringVar            # May be overridden
-
-    def __init__(self, dialog, option):
-        self.dialog = dialog
-        self.option = option
-        self.master = dialog.top
-        self.default, self.klass = dialog.options[option]
-        self.var = self.varclass(self.master)
-        self.frame = Frame(self.master)
-        self.frame.pack(fill=X)
-        self.label = Label(self.frame, text=(option + ":"))
-        self.label.pack(side=LEFT)
-        self.update()
-        self.addoption()
-
-    def refresh(self):
-        self.dialog.refresh()
-        self.update()
-
-    def update(self):
-        try:
-            self.current = self.dialog.current[self.option]
-        except KeyError:
-            self.current = self.default
-        self.var.set(self.current)
-
-    def set(self, e=None):          # Should be overridden
-        pass
-
-class BooleanOption(Option):
-
-    varclass = BooleanVar
-
-    def addoption(self):
-        self.button = Checkbutton(self.frame,
-                                 text='on/off',
-                                 onvalue=1,
-                                 offvalue=0,
-                                 variable=self.var,
-                                 relief=RAISED,
-                                 borderwidth=2,
-                                 command=self.set)
-        self.button.pack(side=RIGHT)
-
-class EnumOption(Option):
-
-    def addoption(self):
-        self.button = Menubutton(self.frame,
-                                 textvariable=self.var,
-                                 relief=RAISED, borderwidth=2)
-        self.button.pack(side=RIGHT)
-        self.menu = Menu(self.button)
-        self.button['menu'] = self.menu
-        for v in self.dialog.classes[self.klass]:
-            self.menu.add_radiobutton(
-                label=v,
-                variable=self.var,
-                value=v,
-                command=self.set)
-
-class StringOption(Option):
-
-    def addoption(self):
-        self.entry = Entry(self.frame,
-                           textvariable=self.var,
-                           width=10,
-                           relief=SUNKEN,
-                           borderwidth=2)
-        self.entry.pack(side=RIGHT, fill=X, expand=1)
-        self.entry.bind('<Return>', self.set)
-
-class ReadonlyOption(Option):
-
-    def addoption(self):
-        self.label = Label(self.frame, textvariable=self.var,
-                           anchor=E)
-        self.label.pack(side=RIGHT)
-
-class Dialog:
-
-    def __init__(self, master):
-        self.master = master
-        self.fixclasses()
-        self.refresh()
-        self.top = Toplevel(self.master)
-        self.top.title(self.__class__.__name__)
-        self.top.minsize(1, 1)
-        self.addchoices()
-
-    def refresh(self): pass         # Must override
-
-    def fixclasses(self): pass      # May override
-
-    def addchoices(self):
-        self.choices = {}
-        list = []
-        for k, dc in self.options.items():
-            list.append((k, dc))
-        list.sort()
-        for k, (d, c) in list:
-            try:
-                cl = self.classes[c]
-            except KeyError:
-                cl = 'unknown'
-            if type(cl) == TupleType:
-                cl = self.enumoption
-            elif cl == 'boolean':
-                cl = self.booleanoption
-            elif cl == 'readonly':
-                cl = self.readonlyoption
-            else:
-                cl = self.stringoption
-            self.choices[k] = cl(self, k)
-
-    # Must override:
-    options = {}
-    classes = {}
-
-    # May override:
-    booleanoption = BooleanOption
-    stringoption = StringOption
-    enumoption = EnumOption
-    readonlyoption = ReadonlyOption
-
-class PackDialog(Dialog):
-
-    def __init__(self, widget):
-        self.widget = widget
-        Dialog.__init__(self, widget)
-
-    def refresh(self):
-        self.current = self.widget.info()
-        self.current['.class'] = self.widget.winfo_class()
-        self.current['.name'] = self.widget._w
-
-    class packoption: # Mix-in class
-        def set(self, e=None):
-            self.current = self.var.get()
-            try:
-                self.dialog.widget.pack(**{self.option: self.current})
-            except TclError as msg:
-                print(msg)
-                self.refresh()
-
-    class booleanoption(packoption, BooleanOption): pass
-    class enumoption(packoption, EnumOption): pass
-    class stringoption(packoption, StringOption): pass
-    class readonlyoption(packoption, ReadonlyOption): pass
-
-    options = {
-            '.class': (None, 'Class'),
-            '.name': (None, 'Name'),
-            'after': (None, 'Widget'),
-            'anchor': ('center', 'Anchor'),
-            'before': (None, 'Widget'),
-            'expand': ('no', 'Boolean'),
-            'fill': ('none', 'Fill'),
-            'in': (None, 'Widget'),
-            'ipadx': (0, 'Pad'),
-            'ipady': (0, 'Pad'),
-            'padx': (0, 'Pad'),
-            'pady': (0, 'Pad'),
-            'side': ('top', 'Side'),
-            }
-
-    classes = {
-            'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER),
-            'Boolean': 'boolean',
-            'Class': 'readonly',
-            'Expand': 'boolean',
-            'Fill': (NONE, X, Y, BOTH),
-            'Name': 'readonly',
-            'Pad': 'pixel',
-            'Side': (TOP, RIGHT, BOTTOM, LEFT),
-            'Widget': 'readonly',
-            }
-
-class RemotePackDialog(PackDialog):
-
-    def __init__(self, master, app, widget):
-        self.master = master
-        self.app = app
-        self.widget = widget
-        self.refresh()
-        self.top = Toplevel(self.master)
-        self.top.title(self.app + ' PackDialog')
-        self.top.minsize(1, 1)
-        self.addchoices()
-
-    def refresh(self):
-        try:
-            words = self.master.tk.splitlist(
-                    self.master.send(self.app,
-                                     'pack',
-                                     'info',
-                                     self.widget))
-        except TclError as msg:
-            print(msg)
-            return
-        dict = {}
-        for i in range(0, len(words), 2):
-            key = words[i][1:]
-            value = words[i+1]
-            dict[key] = value
-        dict['.class'] = self.master.send(self.app,
-                                          'winfo',
-                                          'class',
-                                          self.widget)
-        dict['.name'] = self.widget
-        self.current = dict
-
-    class remotepackoption: # Mix-in class
-        def set(self, e=None):
-            self.current = self.var.get()
-            try:
-                self.dialog.master.send(
-                        self.dialog.app,
-                        'pack',
-                        'config',
-                        self.dialog.widget,
-                        '-'+self.option,
-                        self.dialog.master.tk.merge(
-                                self.current))
-            except TclError as msg:
-                print(msg)
-                self.refresh()
-
-    class booleanoption(remotepackoption, BooleanOption): pass
-    class enumoption(remotepackoption, EnumOption): pass
-    class stringoption(remotepackoption, StringOption): pass
-    class readonlyoption(remotepackoption, ReadonlyOption): pass
-
-class WidgetDialog(Dialog):
-
-    def __init__(self, widget):
-        self.widget = widget
-        self.klass = widget.winfo_class()
-        Dialog.__init__(self, widget)
-
-    def fixclasses(self):
-        if self.klass in self.addclasses:
-            classes = {}
-            for c in (self.classes,
-                      self.addclasses[self.klass]):
-                for k in c.keys():
-                    classes[k] = c[k]
-            self.classes = classes
-
-    def refresh(self):
-        self.configuration = self.widget.config()
-        self.update()
-        self.current['.class'] = self.widget.winfo_class()
-        self.current['.name'] = self.widget._w
-
-    def update(self):
-        self.current = {}
-        self.options = {}
-        for k, v in self.configuration.items():
-            if len(v) > 4:
-                self.current[k] = v[4]
-                self.options[k] = v[3], v[2] # default, klass
-        self.options['.class'] = (None, 'Class')
-        self.options['.name'] = (None, 'Name')
-
-    class widgetoption: # Mix-in class
-        def set(self, e=None):
-            self.current = self.var.get()
-            try:
-                self.dialog.widget[self.option] = self.current
-            except TclError as msg:
-                print(msg)
-                self.refresh()
-
-    class booleanoption(widgetoption, BooleanOption): pass
-    class enumoption(widgetoption, EnumOption): pass
-    class stringoption(widgetoption, StringOption): pass
-    class readonlyoption(widgetoption, ReadonlyOption): pass
-
-    # Universal classes
-    classes = {
-            'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER),
-            'Aspect': 'integer',
-            'Background': 'color',
-            'Bitmap': 'bitmap',
-            'BorderWidth': 'pixel',
-            'Class': 'readonly',
-            'CloseEnough': 'double',
-            'Command': 'command',
-            'Confine': 'boolean',
-            'Cursor': 'cursor',
-            'CursorWidth': 'pixel',
-            'DisabledForeground': 'color',
-            'ExportSelection': 'boolean',
-            'Font': 'font',
-            'Foreground': 'color',
-            'From': 'integer',
-            'Geometry': 'geometry',
-            'Height': 'pixel',
-            'InsertWidth': 'time',
-            'Justify': (LEFT, CENTER, RIGHT),
-            'Label': 'string',
-            'Length': 'pixel',
-            'MenuName': 'widget',
-            'Name': 'readonly',
-            'OffTime': 'time',
-            'OnTime': 'time',
-            'Orient': (HORIZONTAL, VERTICAL),
-            'Pad': 'pixel',
-            'Relief': (RAISED, SUNKEN, FLAT, RIDGE, GROOVE),
-            'RepeatDelay': 'time',
-            'RepeatInterval': 'time',
-            'ScrollCommand': 'command',
-            'ScrollIncrement': 'pixel',
-            'ScrollRegion': 'rectangle',
-            'ShowValue': 'boolean',
-            'SetGrid': 'boolean',
-            'Sliderforeground': 'color',
-            'SliderLength': 'pixel',
-            'Text': 'string',
-            'TickInterval': 'integer',
-            'To': 'integer',
-            'Underline': 'index',
-            'Variable': 'variable',
-            'Value': 'string',
-            'Width': 'pixel',
-            'Wrap': (NONE, CHAR, WORD),
-            }
-
-    # Classes that (may) differ per widget type
-    _tristate = {'State': (NORMAL, ACTIVE, DISABLED)}
-    _bistate = {'State': (NORMAL, DISABLED)}
-    addclasses = {
-            'Button': _tristate,
-            'Radiobutton': _tristate,
-            'Checkbutton': _tristate,
-            'Entry': _bistate,
-            'Text': _bistate,
-            'Menubutton': _tristate,
-            'Slider': _bistate,
-            }
-
-class RemoteWidgetDialog(WidgetDialog):
-
-    def __init__(self, master, app, widget):
-        self.app = app
-        self.widget = widget
-        self.klass = master.send(self.app,
-                                 'winfo',
-                                 'class',
-                                 self.widget)
-        Dialog.__init__(self, master)
-
-    def refresh(self):
-        try:
-            items = self.master.tk.splitlist(
-                    self.master.send(self.app,
-                                     self.widget,
-                                     'config'))
-        except TclError as msg:
-            print(msg)
-            return
-        dict = {}
-        for item in items:
-            words = self.master.tk.splitlist(item)
-            key = words[0][1:]
-            value = (key,) + words[1:]
-            dict[key] = value
-        self.configuration = dict
-        self.update()
-        self.current['.class'] = self.klass
-        self.current['.name'] = self.widget
-
-    class remotewidgetoption: # Mix-in class
-        def set(self, e=None):
-            self.current = self.var.get()
-            try:
-                self.dialog.master.send(
-                        self.dialog.app,
-                        self.dialog.widget,
-                        'config',
-                        '-'+self.option,
-                        self.current)
-            except TclError as msg:
-                print(msg)
-                self.refresh()
-
-    class booleanoption(remotewidgetoption, BooleanOption): pass
-    class enumoption(remotewidgetoption, EnumOption): pass
-    class stringoption(remotewidgetoption, StringOption): pass
-    class readonlyoption(remotewidgetoption, ReadonlyOption): pass
-
-def test():
-    import sys
-    root = Tk()
-    root.minsize(1, 1)
-    if sys.argv[1:]:
-        remotetest(root, sys.argv[1])
-    else:
-        frame = Frame(root, name='frame')
-        frame.pack(expand=1, fill=BOTH)
-        button = Button(frame, name='button', text='button')
-        button.pack(expand=1)
-        canvas = Canvas(frame, name='canvas')
-        canvas.pack()
-        fpd = PackDialog(frame)
-        fwd = WidgetDialog(frame)
-        bpd = PackDialog(button)
-        bwd = WidgetDialog(button)
-        cpd = PackDialog(canvas)
-        cwd = WidgetDialog(canvas)
-    root.mainloop()
-
-def remotetest(root, app):
-    from listtree import listtree
-    list = listtree(root, app)
-    list.bind('<Any-Double-1>', opendialogs)
-    list.app = app                  # Pass it on to handler
-
-def opendialogs(e):
-    import string
-    list = e.widget
-    sel = list.curselection()
-    for i in sel:
-        item = list.get(i)
-        widget = string.split(item)[0]
-        RemoteWidgetDialog(list, list.app, widget)
-        if widget == '.': continue
-        try:
-            RemotePackDialog(list, list.app, widget)
-        except TclError as msg:
-            print(msg)
-
-test()

File Demo/tkinter/guido/ManPage.py

-# Widget to display a man page
-
-import re
-from tkinter import *
-from tkinter import _tkinter
-from tkinter.scrolledtext import ScrolledText
-
-# XXX These fonts may have to be changed to match your system
-BOLDFONT = '*-Courier-Bold-R-Normal-*-120-*'
-ITALICFONT = '*-Courier-Medium-O-Normal-*-120-*'
-
-# XXX Recognizing footers is system dependent
-# (This one works for IRIX 5.2 and Solaris 2.2)
-footerprog = re.compile(
-        '^     Page [1-9][0-9]*[ \t]+\|^.*Last change:.*[1-9][0-9]*\n')
-emptyprog = re.compile('^[ \t]*\n')
-ulprog = re.compile('^[ \t]*[Xv!_][Xv!_ \t]*\n')
-
-# Basic Man Page class -- does not disable editing
-class EditableManPage(ScrolledText):
-
-    # Initialize instance
-    def __init__(self, master=None, **cnf):
-        # Initialize base class
-        ScrolledText.__init__(self, master, **cnf)
-
-        # Define tags for formatting styles
-        self.tag_config('X', underline=1)
-        self.tag_config('!', font=BOLDFONT)
-        self.tag_config('_', font=ITALICFONT)
-
-        # Set state to idle
-        self.fp = None
-        self.lineno = 0
-
-    # Test whether we are busy parsing a file
-    def busy(self):
-        return self.fp != None
-
-    # Ensure we're not busy
-    def kill(self):
-        if self.busy():
-            self._endparser()
-
-    # Parse a file, in the background
-    def asyncparsefile(self, fp):
-        self._startparser(fp)
-        self.tk.createfilehandler(fp, _tkinter.READABLE,
-                                  self._filehandler)
-
-    parsefile = asyncparsefile      # Alias
-
-    # I/O handler used by background parsing
-    def _filehandler(self, fp, mask):
-        nextline = self.fp.readline()
-        if not nextline:
-            self._endparser()
-            return
-        self._parseline(nextline)
-
-    # Parse a file, now (cannot be aborted)
-    def syncparsefile(self, fp):
-        from select import select
-        def avail(fp=fp, tout=0.0, select=select):
-            return select([fp], [], [], tout)[0]
-        height = self.getint(self['height'])
-        self._startparser(fp)
-        while 1:
-            nextline = fp.readline()
-            if not nextline:
-                break
-            self._parseline(nextline)
-        self._endparser()
-
-    # Initialize parsing from a particular file -- must not be busy
-    def _startparser(self, fp):
-        if self.busy():
-            raise RuntimeError('startparser: still busy')
-        fp.fileno()             # Test for file-ness
-        self.fp = fp
-        self.lineno = 0
-        self.ok = 0
-        self.empty = 0
-        self.buffer = None
-        savestate = self['state']
-        self['state'] = NORMAL
-        self.delete('1.0', END)
-        self['state'] = savestate
-
-    # End parsing -- must be busy, need not be at EOF
-    def _endparser(self):
-        if not self.busy():
-            raise RuntimeError('endparser: not busy')
-        if self.buffer:
-            self._parseline('')
-        try:
-            self.tk.deletefilehandler(self.fp)
-        except TclError as msg:
-            pass
-        self.fp.close()
-        self.fp = None
-        del self.ok, self.empty, self.buffer
-
-    # Parse a single line
-    def _parseline(self, nextline):
-        if not self.buffer:
-            # Save this line -- we need one line read-ahead
-            self.buffer = nextline
-            return
-        if emptyprog.match(self.buffer) >= 0:
-            # Buffered line was empty -- set a flag
-            self.empty = 1
-            self.buffer = nextline
-            return
-        textline = self.buffer
-        if ulprog.match(nextline) >= 0:
-            # Next line is properties for buffered line
-            propline = nextline
-            self.buffer = None
-        else:
-            # Next line is read-ahead
-            propline = None
-            self.buffer = nextline
-        if not self.ok:
-            # First non blank line after footer must be header
-            # -- skip that too
-            self.ok = 1
-            self.empty = 0
-            return
-        if footerprog.match(textline) >= 0:
-            # Footer -- start skipping until next non-blank line
-            self.ok = 0
-            self.empty = 0
-            return
-        savestate = self['state']
-        self['state'] = NORMAL
-        if TkVersion >= 4.0:
-            self.mark_set('insert', 'end-1c')
-        else:
-            self.mark_set('insert', END)
-        if self.empty:
-            # One or more previous lines were empty
-            # -- insert one blank line in the text
-            self._insert_prop('\n')
-            self.lineno = self.lineno + 1
-            self.empty = 0
-        if not propline:
-            # No properties
-            self._insert_prop(textline)
-        else:
-            # Search for properties
-            p = ''
-            j = 0
-            for i in range(min(len(propline), len(textline))):
-                if propline[i] != p:
-                    if j < i:
-                        self._insert_prop(textline[j:i], p)
-                        j = i
-                    p = propline[i]
-            self._insert_prop(textline[j:])
-        self.lineno = self.lineno + 1
-        self['state'] = savestate
-
-    # Insert a string at the end, with at most one property (tag)
-    def _insert_prop(self, str, prop = ' '):
-        here = self.index(AtInsert())
-        self.insert(AtInsert(), str)
-        if TkVersion <= 4.0:
-            tags = self.tag_names(here)
-            for tag in tags:
-                self.tag_remove(tag, here, AtInsert())
-        if prop != ' ':
-            self.tag_add(prop, here, AtInsert())
-
-# Readonly Man Page class -- disables editing, otherwise the same
-class ReadonlyManPage(EditableManPage):
-
-    # Initialize instance
-    def __init__(self, master=None, **cnf):
-        cnf['state'] = DISABLED
-        EditableManPage.__init__(self, master, **cnf)
-
-# Alias
-ManPage = ReadonlyManPage
-
-# Test program.
-# usage: ManPage [manpage]; or ManPage [-f] file
-# -f means that the file is nroff -man output run through ul -i
-def test():
-    import os
-    import sys
-    # XXX This directory may be different on your system
-    MANDIR = '/usr/local/man/mann'
-    DEFAULTPAGE = 'Tcl'
-    formatted = 0
-    if sys.argv[1:] and sys.argv[1] == '-f':
-        formatted = 1
-        del sys.argv[1]
-    if sys.argv[1:]:
-        name = sys.argv[1]
-    else:
-        name = DEFAULTPAGE
-    if not formatted:
-        if name[-2:-1] != '.':
-            name = name + '.n'
-        name = os.path.join(MANDIR, name)
-    root = Tk()
-    root.minsize(1, 1)
-    manpage = ManPage(root, relief=SUNKEN, borderwidth=2)
-    manpage.pack(expand=1, fill=BOTH)
-    if formatted:
-        fp = open(name, 'r')
-    else:
-        fp = os.popen('nroff -man %s | ul -i' % name, 'r')
-    manpage.parsefile(fp)
-    root.mainloop()
-
-# Run the test program when called as a script
-if __name__ == '__main__':
-    test()

File Demo/tkinter/guido/MimeViewer.py

-#! /usr/bin/env python
-
-# View a single MIME multipart message.
-# Display each part as a box.
-
-import string
-from types import *
-from tkinter import *
-from tkinter.scrolledtext import ScrolledText
-
-class MimeViewer:
-    def __init__(self, parent, title, msg):
-        self.title = title
-        self.msg = msg
-        self.frame = Frame(parent, {'relief': 'raised', 'bd': 2})
-        self.frame.packing = {'expand': 0, 'fill': 'both'}
-        self.button = Checkbutton(self.frame,
-                             {'text': title,
-                              'command': self.toggle})
-        self.button.pack({'anchor': 'w'})
-        headertext = msg.getheadertext(
-                lambda x: x != 'received' and x[:5] != 'x400-')
-        height = countlines(headertext, 4)
-        if height:
-            self.htext = ScrolledText(self.frame,
-                              {'height': height,
-                               'width': 80,
-                               'wrap': 'none',
-                               'relief': 'raised',
-                               'bd': 2})
-            self.htext.packing = {'expand': 1, 'fill': 'both',
-                                  'after': self.button}
-            self.htext.insert('end', headertext)
-        else:
-            self.htext = Frame(self.frame,
-                               {'relief': 'raised', 'bd': 2})
-            self.htext.packing = {'side': 'top',
-                                  'ipady': 2,
-                                  'fill': 'x',
-                                  'after': self.button}
-        body = msg.getbody()
-        if type(body) == StringType:
-            self.pad = None
-            height = countlines(body, 10)
-            if height:
-                self.btext = ScrolledText(self.frame,
-                                  {'height': height,
-                                   'width': 80,
-                                   'wrap': 'none',
-                                   'relief': 'raised',
-                                   'bd': 2})
-                self.btext.packing = {'expand': 1,
-                                      'fill': 'both'}
-                self.btext.insert('end', body)
-            else:
-                self.btext = None
-            self.parts = None
-        else:
-            self.pad = Frame(self.frame,
-                             {'relief': 'flat', 'bd': 2})
-            self.pad.packing = {'side': 'left', 'ipadx': 10,
-                                'fill': 'y', 'after': self.htext}
-            self.parts = []
-            for i in range(len(body)):
-                p = MimeViewer(self.frame,
-                               '%s.%d' % (title, i+1),
-                               body[i])
-                self.parts.append(p)
-            self.btext = None
-        self.collapsed = 1
-    def pack(self):
-        self.frame.pack(self.frame.packing)
-    def destroy(self):
-        self.frame.destroy()
-    def show(self):
-        if self.collapsed:
-            self.button.invoke()
-    def toggle(self):
-        if self.collapsed:
-            self.explode()
-        else:
-            self.collapse()
-    def collapse(self):
-        self.collapsed = 1
-        for comp in self.htext, self.btext, self.pad:
-            if comp:
-                comp.forget()
-        if self.parts:
-            for part in self.parts:
-                part.frame.forget()
-        self.frame.pack({'expand': 0})
-    def explode(self):
-        self.collapsed = 0
-        for comp in self.htext, self.btext, self.pad:
-            if comp: comp.pack(comp.packing)
-        if self.parts:
-            for part in self.parts:
-                part.pack()
-        self.frame.pack({'expand': 1})
-
-def countlines(str, limit):
-    i = 0
-    n = 0
-    while  n < limit:
-        i = string.find(str, '\n', i)
-        if i < 0: break
-        n = n+1
-        i = i+1
-    return n
-
-def main():
-    import sys
-    import getopt
-    import mhlib
-    opts, args = getopt.getopt(sys.argv[1:], '')
-    for o, a in opts:
-        pass
-    message = None
-    folder = 'inbox'
-    for arg in args:
-        if arg[:1] == '+':
-            folder = arg[1:]
-        else:
-            message = string.atoi(arg)
-
-    mh = mhlib.MH()
-    f = mh.openfolder(folder)
-    if not message:
-        message = f.getcurrent()
-    m = f.openmessage(message)
-
-    root = Tk()
-    tk = root.tk
-
-    top = MimeViewer(root, '+%s/%d' % (folder, message), m)
-    top.pack()
-    top.show()
-
-    root.minsize(1, 1)
-
-    tk.mainloop()
-
-if __name__ == '__main__': main()

File Demo/tkinter/guido/ShellWindow.py

-import os
-import sys
-import string
-from tkinter import *
-from tkinter.scrolledtext import ScrolledText
-from tkinter.dialog import Dialog
-import signal
-
-BUFSIZE = 512
-
-class ShellWindow(ScrolledText):
-
-    def __init__(self, master=None, shell=None, **cnf):
-        if not shell:
-            try:
-                shell = os.environ['SHELL']
-            except KeyError:
-                shell = '/bin/sh'
-            shell = shell + ' -i'
-        args = string.split(shell)
-        shell = args[0]
-
-        ScrolledText.__init__(self, master, **cnf)
-        self.pos = '1.0'
-        self.bind('<Return>', self.inputhandler)
-        self.bind('<Control-c>', self.sigint)
-        self.bind('<Control-t>', self.sigterm)
-        self.bind('<Control-k>', self.sigkill)
-        self.bind('<Control-d>', self.sendeof)
-
-        self.pid, self.fromchild, self.tochild = spawn(shell, args)
-        self.tk.createfilehandler(self.fromchild, READABLE,
-                                  self.outputhandler)
-
-    def outputhandler(self, file, mask):
-        data = os.read(file, BUFSIZE)
-        if not data:
-            self.tk.deletefilehandler(file)
-            pid, sts = os.waitpid(self.pid, 0)
-            print('pid', pid, 'status', sts)
-            self.pid = None
-            detail = sts>>8
-            cause = sts & 0xff
-            if cause == 0:
-                msg = "exit status %d" % detail
-            else:
-                msg = "killed by signal %d" % (cause & 0x7f)
-                if cause & 0x80:
-                    msg = msg + " -- core dumped"
-            Dialog(self.master,
-                   text=msg,
-                   title="Exit status",
-                   bitmap='warning',
-                   default=0,
-                   strings=('OK',))
-            return
-        self.insert(END, data)
-        self.pos = self.index("end - 1 char")
-        self.yview_pickplace(END)
-
-    def inputhandler(self, *args):
-        if not self.pid:
-            self.no_process()
-            return "break"
-        self.insert(END, "\n")
-        line = self.get(self.pos, "end - 1 char")
-        self.pos = self.index(END)
-        os.write(self.tochild, line)
-        return "break"
-
-    def sendeof(self, *args):
-        if not self.pid:
-            self.no_process()
-            return "break"
-        os.close(self.tochild)
-        return "break"
-
-    def sendsig(self, sig):
-        if not self.pid:
-            self.no_process()
-            return "break"
-        os.kill(self.pid, sig)
-        return "break"
-
-    def sigint(self, *args):
-        return self.sendsig(signal.SIGINT)
-
-    def sigquit(self, *args):
-        return self.sendsig(signal.SIGQUIT)
-
-    def sigterm(self, *args):
-        return self.sendsig(signal.SIGTERM)
-
-    def sigkill(self, *args):
-        return self.sendsig(signal.SIGKILL)
-
-    def no_process(self):
-        Dialog(self.master,
-               text="No active process",
-               title="No process",
-               bitmap='error',
-               default=0,
-               strings=('OK',))
-
-MAXFD = 100     # Max number of file descriptors (os.getdtablesize()???)
-
-def spawn(prog, args):
-    p2cread, p2cwrite = os.pipe()
-    c2pread, c2pwrite = os.pipe()
-    pid = os.fork()
-    if pid == 0:
-        # Child
-        for i in 0, 1, 2:
-            try:
-                os.close(i)
-            except os.error:
-                pass
-        if os.dup(p2cread) != 0:
-            sys.stderr.write('popen2: bad read dup\n')
-        if os.dup(c2pwrite) != 1:
-            sys.stderr.write('popen2: bad write dup\n')
-        if os.dup(c2pwrite) != 2:
-            sys.stderr.write('popen2: bad write dup\n')
-        os.closerange(3, MAXFD)
-        try:
-            os.execvp(prog, args)
-        finally:
-            sys.stderr.write('execvp failed\n')
-            os._exit(1)
-    os.close(p2cread)
-    os.close(c2pwrite)
-    return pid, c2pread, p2cwrite
-
-def test():
-    shell = string.join(sys.argv[1:])
-    root = Tk()
-    root.minsize(1, 1)
-    if shell:
-        w = ShellWindow(root, shell=shell)
-    else:
-        w = ShellWindow(root)
-    w.pack(expand=1, fill=BOTH)
-    w.focus_set()
-    w.tk.mainloop()
-
-if __name__ == '__main__':
-    test()

File Demo/tkinter/guido/attr_dialog.py

+
+# The options of a widget are described by the following attributes
+# of the Pack and Widget dialogs:
+#
+# Dialog.current: {name: value}
+# -- changes during Widget's lifetime
+#
+# Dialog.options: {name: (default, klass)}
+# -- depends on widget class only
+#
+# Dialog.classes: {klass: (v0, v1, v2, ...) | 'boolean' | 'other'}
+# -- totally static, though different between PackDialog and WidgetDialog
+#    (but even that could be unified)
+
+from tkinter import *
+
+
+class Option:
+
+    varclass = StringVar            # May be overridden
+
+    def __init__(self, dialog, option):
+        self.dialog = dialog
+        self.option = option
+        self.master = dialog.top
+        self.default, self.klass = dialog.options[option]
+        self.var = self.varclass(self.master)
+        self.frame = Frame(self.master)
+        self.frame.pack(fill=X)
+        self.label = Label(self.frame, text=(option + ":"))
+        self.label.pack(side=LEFT)
+        self.update()
+        self.addoption()
+
+    def refresh(self):
+        self.dialog.refresh()
+        self.update()
+
+    def update(self):
+        try:
+            self.current = self.dialog.current[self.option]
+        except KeyError:
+            self.current = self.default
+        self.var.set(self.current)
+
+    def set(self, e=None):          # Should be overridden
+        pass
+
+
+class BooleanOption(Option):
+
+    varclass = BooleanVar
+
+    def addoption(self):
+        self.button = Checkbutton(self.frame,
+                                 text='on/off',
+                                 onvalue=1,
+                                 offvalue=0,
+                                 variable=self.var,
+                                 relief=RAISED,
+                                 borderwidth=2,
+                                 command=self.set)
+        self.button.pack(side=RIGHT)
+
+
+class EnumOption(Option):
+
+    def addoption(self):
+        self.button = Menubutton(self.frame,
+                                 textvariable=self.var,
+                                 relief=RAISED, borderwidth=2)
+        self.button.pack(side=RIGHT)
+        self.menu = Menu(self.button)
+        self.button['menu'] = self.menu
+        for v in self.dialog.classes[self.klass]:
+            self.menu.add_radiobutton(
+                label=v,
+                variable=self.var,
+                value=v,
+                command=self.set)
+
+
+class StringOption(Option):
+
+    def addoption(self):
+        self.entry = Entry(self.frame,
+                           textvariable=self.var,
+                           width=10,
+                           relief=SUNKEN,
+                           borderwidth=2)
+        self.entry.pack(side=RIGHT, fill=X, expand=1)
+        self.entry.bind('<Return>', self.set)
+
+
+class ReadonlyOption(Option):
+
+    def addoption(self):
+        self.label = Label(self.frame, textvariable=self.var,
+                           anchor=E)
+        self.label.pack(side=RIGHT)
+
+
+class Dialog:
+
+    def __init__(self, master):
+        self.master = master
+        self.fixclasses()
+        self.refresh()
+        self.top = Toplevel(self.master)
+        self.top.title(self.__class__.__name__)
+        self.top.minsize(1, 1)
+        self.addchoices()
+
+    def refresh(self): pass         # Must override
+
+    def fixclasses(self): pass      # May override
+
+    def addchoices(self):
+        self.choices = {}
+        list = []
+        for k, dc in self.options.items():
+            list.append((k, dc))
+        list.sort()
+        for k, (d, c) in list:
+            try:
+                cl = self.classes[c]
+            except KeyError:
+                cl = 'unknown'
+            if type(cl) is tuple:
+                cl = self.enumoption
+            elif cl == 'boolean':
+                cl = self.booleanoption
+            elif cl == 'readonly':
+                cl = self.readonlyoption
+            else:
+                cl = self.stringoption
+            self.choices[k] = cl(self, k)
+
+    # Must override:
+    options = {}
+    classes = {}
+
+    # May override:
+    booleanoption = BooleanOption
+    stringoption = StringOption
+    enumoption = EnumOption
+    readonlyoption = ReadonlyOption
+
+
+class PackDialog(Dialog):
+
+    def __init__(self, widget):
+        self.widget = widget
+        Dialog.__init__(self, widget)
+
+    def refresh(self):
+        self.current = self.widget.info()
+        self.current['.class'] = self.widget.winfo_class()
+        self.current['.name'] = self.widget._w
+
+    class packoption: # Mix-in class
+        def set(self, e=None):
+            self.current = self.var.get()
+            try:
+                self.dialog.widget.pack(**{self.option: self.current})
+            except TclError as msg:
+                print(msg)
+                self.refresh()
+
+    class booleanoption(packoption, BooleanOption): pass
+    class enumoption(packoption, EnumOption): pass
+    class stringoption(packoption, StringOption): pass
+    class readonlyoption(packoption, ReadonlyOption): pass
+
+    options = {
+            '.class': (None, 'Class'),
+            '.name': (None, 'Name'),
+            'after': (None, 'Widget'),
+            'anchor': ('center', 'Anchor'),
+            'before': (None, 'Widget'),
+            'expand': ('no', 'Boolean'),
+            'fill': ('none', 'Fill'),
+            'in': (None, 'Widget'),
+            'ipadx': (0, 'Pad'),
+            'ipady': (0, 'Pad'),
+            'padx': (0, 'Pad'),
+            'pady': (0, 'Pad'),
+            'side': ('top', 'Side'),
+            }
+
+    classes = {
+            'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER),
+            'Boolean': 'boolean',
+            'Class': 'readonly',
+            'Expand': 'boolean',
+            'Fill': (NONE, X, Y, BOTH),
+            'Name': 'readonly',
+            'Pad': 'pixel',
+            'Side': (TOP, RIGHT, BOTTOM, LEFT),
+            'Widget': 'readonly',
+            }
+
+class RemotePackDialog(PackDialog):
+
+    def __init__(self, master, app, widget):
+        self.master = master
+        self.app = app
+        self.widget = widget
+        self.refresh()
+        self.top = Toplevel(self.master)
+        self.top.title(self.app + ' PackDialog')
+        self.top.minsize(1, 1)
+        self.addchoices()
+
+    def refresh(self):
+        try:
+            words = self.master.tk.splitlist(
+                    self.master.send(self.app,
+                                     'pack',
+                                     'info',
+                                     self.widget))
+        except TclError as msg:
+            print(msg)
+            return
+        dict = {}
+        for i in range(0, len(words), 2):
+            key = words[i][1:]
+            value = words[i+1]
+            dict[key] = value
+        dict['.class'] = self.master.send(self.app,
+                                          'winfo',
+                                          'class',
+                                          self.widget)
+        dict['.name'] = self.widget
+        self.current = dict
+
+    class remotepackoption: # Mix-in class
+        def set(self, e=None):
+            self.current = self.var.get()
+            try:
+                self.dialog.master.send(
+                        self.dialog.app,
+                        'pack',
+                        'config',
+                        self.dialog.widget,
+                        '-'+self.option,
+                        self.dialog.master.tk.merge(
+                                self.current))
+            except TclError as msg:
+                print(msg)
+                self.refresh()
+
+    class booleanoption(remotepackoption, BooleanOption): pass
+    class enumoption(remotepackoption, EnumOption): pass
+    class stringoption(remotepackoption, StringOption): pass
+    class readonlyoption(remotepackoption, ReadonlyOption): pass
+
+
+class WidgetDialog(Dialog):
+
+    def __init__(self, widget):
+        self.widget = widget
+        self.klass = widget.winfo_class()
+        Dialog.__init__(self, widget)
+
+    def fixclasses(self):
+        if self.klass in self.addclasses:
+            classes = {}
+            for c in (self.classes,
+                      self.addclasses[self.klass]):
+                for k in c.keys():
+                    classes[k] = c[k]
+            self.classes = classes
+
+    def refresh(self):
+        self.configuration = self.widget.config()
+        self.update()
+        self.current['.class'] = self.widget.winfo_class()
+        self.current['.name'] = self.widget._w
+
+    def update(self):
+        self.current = {}
+        self.options = {}
+        for k, v in self.configuration.items():
+            if len(v) > 4:
+                self.current[k] = v[4]
+                self.options[k] = v[3], v[2] # default, klass
+        self.options['.class'] = (None, 'Class')
+        self.options['.name'] = (None, 'Name')
+
+    class widgetoption: # Mix-in class
+        def set(self, e=None):
+            self.current = self.var.get()
+            try:
+                self.dialog.widget[self.option] = self.current
+            except TclError as msg:
+                print(msg)
+                self.refresh()
+
+    class booleanoption(widgetoption, BooleanOption): pass
+    class enumoption(widgetoption, EnumOption): pass
+    class stringoption(widgetoption, StringOption): pass
+    class readonlyoption(widgetoption, ReadonlyOption): pass
+
+    # Universal classes
+    classes = {
+            'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER),
+            'Aspect': 'integer',
+            'Background': 'color',
+            'Bitmap': 'bitmap',
+            'BorderWidth': 'pixel',
+            'Class': 'readonly',
+            'CloseEnough': 'double',
+            'Command': 'command',
+            'Confine': 'boolean',
+            'Cursor': 'cursor',
+            'CursorWidth': 'pixel',
+            'DisabledForeground': 'color',
+            'ExportSelection': 'boolean',
+            'Font': 'font',
+            'Foreground': 'color',
+            'From': 'integer',
+            'Geometry': 'geometry',
+            'Height': 'pixel',
+            'InsertWidth': 'time',
+            'Justify': (LEFT, CENTER, RIGHT),
+            'Label': 'string',
+            'Length': 'pixel',
+            'MenuName': 'widget',
+            'Name': 'readonly',
+            'OffTime': 'time',
+            'OnTime': 'time',
+            'Orient': (HORIZONTAL, VERTICAL),
+            'Pad': 'pixel',
+            'Relief': (RAISED, SUNKEN, FLAT, RIDGE, GROOVE),
+            'RepeatDelay': 'time',
+            'RepeatInterval': 'time',
+            'ScrollCommand': 'command',
+            'ScrollIncrement': 'pixel',
+            'ScrollRegion': 'rectangle',
+            'ShowValue': 'boolean',
+            'SetGrid': 'boolean',
+            'Sliderforeground': 'color',
+            'SliderLength': 'pixel',
+            'Text': 'string',
+            'TickInterval': 'integer',
+            'To': 'integer',
+            'Underline': 'index',
+            'Variable': 'variable',
+            'Value': 'string',
+            'Width': 'pixel',
+            'Wrap': (NONE, CHAR, WORD),
+            }
+
+    # Classes that (may) differ per widget type
+    _tristate = {'State': (NORMAL, ACTIVE, DISABLED)}
+    _bistate = {'State': (NORMAL, DISABLED)}
+    addclasses = {
+            'Button': _tristate,
+            'Radiobutton': _tristate,
+            'Checkbutton': _tristate,
+            'Entry': _bistate,
+            'Text': _bistate,
+            'Menubutton': _tristate,
+            'Slider': _bistate,
+            }
+
+
+class RemoteWidgetDialog(WidgetDialog):
+
+    def __init__(self, master, app, widget):
+        self.app = app
+        self.widget = widget
+        self.klass = master.send(self.app,
+                                 'winfo',
+                                 'class',
+                                 self.widget)
+        Dialog.__init__(self, master)
+
+    def refresh(self):
+        try:
+            items = self.master.tk.splitlist(
+                    self.master.send(self.app,
+                                     self.widget,
+                                     'config'))
+        except TclError as msg:
+            print(msg)
+            return
+        dict = {}
+        for item in items:
+            words = self.master.tk.splitlist(item)
+            key = words[0][1:]
+            value = (key,) + words[1:]
+            dict[key] = value
+        self.configuration = dict
+        self.update()
+        self.current['.class'] = self.klass
+        self.current['.name'] = self.widget
+
+    class remotewidgetoption: # Mix-in class
+        def set(self, e=None):
+            self.current = self.var.get()
+            try:
+                self.dialog.master.send(
+                        self.dialog.app,
+                        self.dialog.widget,
+                        'config',
+                        '-'+self.option,
+                        self.current)
+            except TclError as msg:
+                print(msg)
+                self.refresh()
+
+    class booleanoption(remotewidgetoption, BooleanOption): pass
+    class enumoption(remotewidgetoption, EnumOption): pass
+    class stringoption(remotewidgetoption, StringOption): pass
+    class readonlyoption(remotewidgetoption, ReadonlyOption): pass
+
+
+def test():
+    import sys
+    root = Tk()
+    root.minsize(1, 1)
+    if sys.argv[1:]:
+        remotetest(root, sys.argv[1])
+    else:
+        frame = Frame(root, name='frame')
+        frame.pack(expand=1, fill=BOTH)
+        button = Button(frame, name='button', text='button')
+        button.pack(expand=1)
+        canvas = Canvas(frame, name='canvas')
+        canvas.pack()
+        fpd = PackDialog(frame)
+        fwd = WidgetDialog(frame)
+        bpd = PackDialog(button)
+        bwd = WidgetDialog(button)
+        cpd = PackDialog(canvas)
+        cwd = WidgetDialog(canvas)
+    root.mainloop()
+
+def remotetest(root, app):
+    from listtree import listtree
+    list = listtree(root, app)
+    list.bind('<Any-Double-1>', opendialogs)
+    list.app = app                  # Pass it on to handler
+
+def opendialogs(e):
+    list = e.widget
+    sel = list.curselection()
+    for i in sel:
+        item = list.get(i)
+        widget = item.split()[0]
+        RemoteWidgetDialog(list, list.app, widget)
+        if widget == '.': continue
+        try:
+            RemotePackDialog(list, list.app, widget)
+        except TclError as msg:
+            print(msg)
+
+test()

File Demo/tkinter/guido/canvasevents.py

 #! /usr/bin/env python
 
 from tkinter import *
-from Canvas import Oval, Group, CanvasText
 
 
-# Fix a bug in Canvas.Group as distributed in Python 1.4.  The
-# distributed bind() method is broken.  This is what should be used:
+# Since Canvas.Group is no longer present, the following class reproduces
+# a subset of the old Group class that is used by this app.
 
-class Group(Group):
-    def bind(self, sequence=None, command=None):
-        return self.canvas.tag_bind(self.id, sequence, command)
+class Group:
+    def __init__(self, canvas, tag=None):
+        if tag is None:
+            tag = 'Group%d' % id(self)
+
+        self.tag = self.id = tag
+        self.canvas = canvas
+        self.canvas.dtag(self.tag)
+
+    def __str__(self):
+        return self.tag
+
+    def _do(self, cmd, *args):
+        return self.canvas.tk.call(self.canvas._w, cmd, self.tag, *args)
+
+    def addtag_withtag(self, tagOrId):
+        self._do('addtag', 'withtag', tagOrId)
+
+    def bind(self, sequence=None, command=None, add=None):
+        return self.canvas.tag_bind(self.id, sequence, command, add)
+
+    def move(self, x_amount, y_amount):
+        self._do('move', x_amount, y_amount)
+
+    def dtag(self, tagToDelete=None):
+        self._do('dtag', tagToDelete)
+
+    def tkraise(self, aboveThis=None):
+        self._do('raise', aboveThis)
+
 
 class Object:
 
 
     All instance attributes are public since the derived class may
     need them.
-
     """
 
     def __init__(self, canvas, x=0, y=0, fill='red', text='object'):
         return str(self.group)
 
     def createitems(self, fill, text):
-        self.__oval = Oval(self.canvas,
-                           self.x-20, self.y-10, self.x+20, self.y+10,
-                           fill=fill, width=3)
+        self.__oval = self.canvas.create_oval(self.x - 20, self.y - 10,
+            self.x + 20, self.y + 20, fill=fill, width=3)
         self.group.addtag_withtag(self.__oval)
-        self.__text = CanvasText(self.canvas,
-                           self.x, self.y, text=text)
+        self.__text = self.canvas.create_text(self.x, self.y, text=text)
         self.group.addtag_withtag(self.__text)
 
     def moveby(self, dx, dy):
 
 
 class Bottom(Object):
-
     """An object to serve as the bottom of a pile."""
 
     def createitems(self, *args):
-        self.__oval = Oval(self.canvas,
-                           self.x-20, self.y-10, self.x+20, self.y+10,
-                           fill='gray', outline='')
+        self.__oval = self.canvas.create_oval(self.x - 20, self.y - 10,
+            self.x + 20, self.y + 10, fill='gray', outline='')
         self.group.addtag_withtag(self.__oval)
 
 
 class Pile:
-
     """A group of graphical objects."""
 
     def __init__(self, canvas, x, y, tag=None):

File Demo/tkinter/guido/dialog.py

 
     # 2. Fill the top part with the bitmap and message.
 
-    msg = Message(top, width='3i', text=text,
-                  font='-Adobe-Times-Medium-R-Normal-*-180-*')
+    msg = Message(top, width='3i', text=text)
     msg.pack(side=RIGHT, expand=1, fill=BOTH, padx='3m', pady='3m')
     if bitmap:
         bm = Label(top, bitmap=bitmap)

File Demo/tkinter/guido/electrons.py

 
 # Main program
 def main():
-    import sys, string
+    import sys
 
     # First argument is number of electrons, default 30
     if sys.argv[1:]:
-        n = string.atoi(sys.argv[1])
+        n = int(sys.argv[1])
     else:
         n = 30
 

File Demo/tkinter/guido/hanoi.py

 
 # Main program
 def main():
-    import sys, string
+    import sys
 
     # First argument is number of pegs, default 4
     if sys.argv[1:]:
-        n = string.atoi(sys.argv[1])
+        n = int(sys.argv[1])
     else:
         n = 4
 

File Demo/tkinter/guido/listtree.py

 # List a remote app's widget tree (names and classes only)
 
 import sys
-import string
 
 from tkinter import *
 
 
 def listnodes(list, app, widget, level):
     klass = list.send(app, 'winfo', 'class', widget)
-##      i = string.rindex(widget, '.')
-##      list.insert(END, '%s%s (%s)' % ((level-1)*'.   ', widget[i:], klass))
     list.insert(END, '%s (%s)' % (widget, klass))
     children = list.tk.splitlist(
             list.send(app, 'winfo', 'children', widget))

File Demo/tkinter/guido/manpage.py

+# Widget to display a man page
+
+import os
+import re
+import sys
+
+from tkinter import *
+from tkinter.font import Font
+from tkinter.scrolledtext import ScrolledText
+
+# XXX Recognizing footers is system dependent
+# (This one works for IRIX 5.2 and Solaris 2.2)
+footerprog = re.compile(
+        '^     Page [1-9][0-9]*[ \t]+\|^.*Last change:.*[1-9][0-9]*\n')
+emptyprog = re.compile('^[ \t]*\n')
+ulprog = re.compile('^[ \t]*[Xv!_][Xv!_ \t]*\n')
+
+
+class EditableManPage(ScrolledText):
+    """Basic Man Page class -- does not disable editing."""
+
+    def __init__(self, master=None, **cnf):
+        ScrolledText.__init__(self, master, **cnf)
+
+        bold = Font(font=self['font']).copy()
+        bold.config(weight='bold')
+        italic = Font(font=self['font']).copy()
+        italic.config(slant='italic')
+
+        # Define tags for formatting styles
+        self.tag_config('X', underline=1)
+        self.tag_config('!', font=bold)
+        self.tag_config('_', font=italic)
+
+        # Set state to idle
+        self.fp = None
+        self.lineno = 0
+
+    def busy(self):
+        """Test whether we are busy parsing a file."""
+        return self.fp != None
+
+    def kill(self):
+        """Ensure we're not busy."""
+        if self.busy():
+            self._endparser()
+
+    def asyncparsefile(self, fp):
+        """Parse a file, in the background."""
+        self._startparser(fp)
+        self.tk.createfilehandler(fp, READABLE,
+                                  self._filehandler)
+
+    parsefile = asyncparsefile   # Alias
+
+    def _filehandler(self, fp, mask):
+        """I/O handler used by background parsing."""
+        nextline = self.fp.readline()
+        if not nextline:
+            self._endparser()
+            return
+        self._parseline(nextline)
+
+    def syncparsefile(self, fp):
+        """Parse a file, now (cannot be aborted)."""
+        self._startparser(fp)
+        while True:
+            nextline = fp.readline()
+            if not nextline:
+                break
+            self._parseline(nextline)
+        self._endparser()
+
+    def _startparser(self, fp):
+        """Initialize parsing from a particular file -- must not be busy."""
+        if self.busy():
+            raise RuntimeError('startparser: still busy')
+        fp.fileno()             # Test for file-ness
+        self.fp = fp
+        self.lineno = 0
+        self.ok = 0
+        self.empty = 0
+        self.buffer = None
+        savestate = self['state']
+        self['state'] = NORMAL
+        self.delete('1.0', END)
+        self['state'] = savestate
+
+    def _endparser(self):
+        """End parsing -- must be busy, need not be at EOF."""
+        if not self.busy():
+            raise RuntimeError('endparser: not busy')
+        if self.buffer:
+            self._parseline('')
+        try:
+            self.tk.deletefilehandler(self.fp)
+        except TclError:
+            pass
+        self.fp.close()
+        self.fp = None
+        del self.ok, self.empty, self.buffer
+
+    def _parseline(self, nextline):
+        """Parse a single line."""
+        if not self.buffer:
+            # Save this line -- we need one line read-ahead
+            self.buffer = nextline
+            return
+        if emptyprog.match(self.buffer):
+            # Buffered line was empty -- set a flag
+            self.empty = 1
+            self.buffer = nextline
+            return
+        textline = self.buffer
+        if ulprog.match(nextline):
+            # Next line is properties for buffered line
+            propline = nextline
+            self.buffer = None
+        else:
+            # Next line is read-ahead
+            propline = None
+            self.buffer = nextline
+        if not self.ok:
+            # First non blank line after footer must be header
+            # -- skip that too
+            self.ok = 1
+            self.empty = 0
+            return
+        if footerprog.match(textline):
+            # Footer -- start skipping until next non-blank line
+            self.ok = 0
+            self.empty = 0
+            return
+        savestate = self['state']
+        self['state'] = NORMAL
+        if TkVersion >= 4.0:
+            self.mark_set('insert', 'end-1c')
+        else:
+            self.mark_set('insert', END)
+        if self.empty:
+            # One or more previous lines were empty
+            # -- insert one blank line in the text
+            self._insert_prop('\n')
+            self.lineno = self.lineno + 1
+            self.empty = 0
+        if not propline:
+            # No properties
+            self._insert_prop(textline)
+        else:
+            # Search for properties
+            p = ''
+            j = 0
+            for i in range(min(len(propline), len(textline))):
+                if propline[i] != p:
+                    if j < i:
+                        self._insert_prop(textline[j:i], p)
+                        j = i
+                    p = propline[i]
+            self._insert_prop(textline[j:])
+        self.lineno = self.lineno + 1
+        self['state'] = savestate
+
+    def _insert_prop(self, str, prop = ' '):
+        """Insert a string at the end, with at most one property (tag)."""
+        here = self.index(AtInsert())
+        self.insert(AtInsert(), str)
+        if TkVersion <= 4.0:
+            tags = self.tag_names(here)
+            for tag in tags:
+                self.tag_remove(tag, here, AtInsert())
+        if prop != ' ':
+            self.tag_add(prop, here, AtInsert())
+
+
+class ReadonlyManPage(EditableManPage):
+    """Readonly Man Page class -- disables editing, otherwise the same."""
+
+    def __init__(self, master=None, **cnf):
+        cnf['state'] = DISABLED
+        EditableManPage.__init__(self, master, **cnf)
+
+# Alias
+ManPage = ReadonlyManPage
+
+# usage: ManPage [manpage]; or ManPage [-f] file
+# -f means that the file is nroff -man output run through ul -i
+def main():
+    # XXX This directory may be different on your system
+    MANDIR = ''
+    DEFAULTPAGE = 'Tcl'
+    formatted = 0
+    if sys.argv[1:] and sys.argv[1] == '-f':
+        formatted = 1
+        del sys.argv[1]
+    if sys.argv[1:]:
+        name = sys.argv[1]
+    else:
+        name = DEFAULTPAGE
+    if not formatted:
+        if name[-2:-1] != '.':
+            name = name + '.n'
+        name = os.path.join(MANDIR, name)
+    root = Tk()
+    root.minsize(1, 1)
+    manpage = ManPage(root, relief=SUNKEN, borderwidth=2)
+    manpage.pack(expand=1, fill=BOTH)
+    if formatted:
+        fp = open(name, 'r')
+    else:
+        fp = os.popen('nroff -man -c %s | ul -i' % name, 'r')
+    manpage.parsefile(fp)
+    root.mainloop()
+
+if __name__ == '__main__':
+    main()

File Demo/tkinter/guido/mbox.py

 # Scan MH folder, display results in window
 
 import os
+import re
 import sys
-import re
 import getopt
-import string
-import mhlib
-
+import mailbox
 from tkinter import *
 
 from dialog import dialog
 
-mailbox = os.environ['HOME'] + '/Mail'
+MBOXPATH = os.environ['HOME'] + '/Mail'
 
 def main():
     global root, tk, top, mid, bot
 
     # Initialize MH
 
-    mh = mhlib.MH()
-    mhf = mh.openfolder(folder)
+    mh = mailbox.MH(MBOXPATH)
+    mhf = mh.get_folder(folder)
 
     # Build widget hierarchy
 
         return
     i = sel[0]
     folder = folderbox.get(i)
-    mhf = mh.openfolder(folder)
+    mhf = mh.get_folder(folder)
     rescan()
 
 def open_message(e=None):
     tk.call('update', 'idletasks')
     i = sel[0]
     line = scanbox.get(i)
-    if scanparser.match(line) >= 0:
-        num = string.atoi(scanparser.group(1))
-        m = mhf.openmessage(num)
+    m = scanparser.match(line)
+    if m:
+        num = int(m.group(1))
+        m = mhf.get_message(num)
         if viewer: viewer.destroy()
-        from MimeViewer import MimeViewer
+        from mimeviewer import MimeViewer
         viewer = MimeViewer(bot, '+%s/%d' % (folder, num), m)
         viewer.pack()
         viewer.show()
     todo = []
     for i in sel:
         line = scanbox.get(i)
-        if scanparser.match(line) >= 0:
-            todo.append(string.atoi(scanparser.group(1)))
-    mhf.removemessages(todo)
+        m = scanparser.match(line)
+        if m:
+            toremove = int(m.group(1))
+            todo.append(toremove)
+            mhf.remove(toremove)
     rescan()
     fixfocus(min(todo), itop)
 
     todo = []
     for i in sel:
         line = scanbox.get(i)
-        if scanparser.match(line) >= 0:
-            todo.append(string.atoi(scanparser.group(1)))
+        m = scanparser.match(line)
+        if m:
+            todo.append(int(m.group(1)))
     if lastrefile != refileto or not tofolder:
         lastrefile = refileto
         tofolder = None
-        tofolder = mh.openfolder(lastrefile)
+        tofolder = mh.get_folder(lastrefile)
     mhf.refilemessages(todo, tofolder)
     rescan()
     fixfocus(min(todo), itop)
     n = scanbox.size()
     for i in range(n):
         line = scanbox.get(repr(i))
-        if scanparser.match(line) >= 0:
-            num = string.atoi(scanparser.group(1))
+        m = scanparser.match(line)
+        if m:
+            num = int(m.group(1))
             if num >= near:
                 break
     else:
         i = 'end'
-    scanbox.select_from(i)
     scanbox.yview(itop)
 
 def setfolders():
     folderbox.delete(0, 'end')
-    for fn in mh.listallfolders():
+    for fn in mh.list_folders():
         folderbox.insert('end', fn)
 
 def rescan():
         scanbox.insert('end', line)
 
 def scanfolder(folder = 'inbox', sequence = 'all'):
-    return [line[:-1] for line in os.popen('scan +%s %s' % (folder, sequence), 'r').readlines()]
+    return [line[:-1] for line in
+            os.popen('scan +%s %s' % (folder, sequence), 'r').readlines()]
 
 main()

File Demo/tkinter/guido/mimeviewer.py

+#! /usr/bin/env python3
+
+# View a single MIME multipart message.
+# Display each part as a box.
+
+import os
+import sys
+import getopt
+import mailbox
+from tkinter import *
+from tkinter.scrolledtext import ScrolledText
+
+MBOXPATH = os.environ['HOME'] + '/Mail'
+
+class Error(Exception):
+    pass
+
+def getcurrent(self):
+    """Return the current message.  Raise Error when there is none."""
+    seqs = self.get_sequences()
+    try:
+        return max(seqs['cur'])
+    except (ValueError, KeyError):
+        raise Error("no cur message")
+
+
+class MimeViewer:
+    def __init__(self, parent, title, msg):
+        self.title = title
+        self.msg = msg
+        self.frame = Frame(parent, {'relief': 'raised', 'bd': 2})
+        self.frame.packing = {'expand': 0, 'fill': 'both'}
+        self.button = Checkbutton(self.frame,
+                             {'text': title,
+                              'command': self.toggle})
+        self.button.pack({'anchor': 'w'})
+        headertext = []
+        for item in msg.items():
+            headertext.append("%s: %s" % item)
+        headertext = '\n'.join(headertext)