[Python-checkins] r65574 - sandbox/trunk/ttk-gsoc/src/tabs_ttk_and_co.diff

guilherme.polo python-checkins at python.org
Thu Aug 7 16:15:02 CEST 2008


Author: guilherme.polo
Date: Thu Aug  7 16:15:00 2008
New Revision: 65574

Log:
Removed idle patch .diff file, I will be adding it elsewhere

Removed:
   sandbox/trunk/ttk-gsoc/src/tabs_ttk_and_co.diff

Deleted: sandbox/trunk/ttk-gsoc/src/tabs_ttk_and_co.diff
==============================================================================
--- sandbox/trunk/ttk-gsoc/src/tabs_ttk_and_co.diff	Thu Aug  7 16:15:00 2008
+++ (empty file)
@@ -1,8367 +0,0 @@
-Index: ToolTip.py
-===================================================================
---- ToolTip.py	(revision 63995)
-+++ ToolTip.py	(revision 65541)
-@@ -1,89 +0,0 @@
--# general purpose 'tooltip' routines - currently unused in idlefork
--# (although the 'calltips' extension is partly based on this code)
--# may be useful for some purposes in (or almost in ;) the current project scope
--# Ideas gleaned from PySol
--
--from Tkinter import *
--
--class ToolTipBase:
--
--    def __init__(self, button):
--        self.button = button
--        self.tipwindow = None
--        self.id = None
--        self.x = self.y = 0
--        self._id1 = self.button.bind("<Enter>", self.enter)
--        self._id2 = self.button.bind("<Leave>", self.leave)
--        self._id3 = self.button.bind("<ButtonPress>", self.leave)
--
--    def enter(self, event=None):
--        self.schedule()
--
--    def leave(self, event=None):
--        self.unschedule()
--        self.hidetip()
--
--    def schedule(self):
--        self.unschedule()
--        self.id = self.button.after(1500, self.showtip)
--
--    def unschedule(self):
--        id = self.id
--        self.id = None
--        if id:
--            self.button.after_cancel(id)
--
--    def showtip(self):
--        if self.tipwindow:
--            return
--        # The tip window must be completely outside the button;
--        # otherwise when the mouse enters the tip window we get
--        # a leave event and it disappears, and then we get an enter
--        # event and it reappears, and so on forever :-(
--        x = self.button.winfo_rootx() + 20
--        y = self.button.winfo_rooty() + self.button.winfo_height() + 1
--        self.tipwindow = tw = Toplevel(self.button)
--        tw.wm_overrideredirect(1)
--        tw.wm_geometry("+%d+%d" % (x, y))
--        self.showcontents()
--
--    def showcontents(self, text="Your text here"):
--        # Override this in derived class
--        label = Label(self.tipwindow, text=text, justify=LEFT,
--                      background="#ffffe0", relief=SOLID, borderwidth=1)
--        label.pack()
--
--    def hidetip(self):
--        tw = self.tipwindow
--        self.tipwindow = None
--        if tw:
--            tw.destroy()
--
--class ToolTip(ToolTipBase):
--    def __init__(self, button, text):
--        ToolTipBase.__init__(self, button)
--        self.text = text
--    def showcontents(self):
--        ToolTipBase.showcontents(self, self.text)
--
--class ListboxToolTip(ToolTipBase):
--    def __init__(self, button, items):
--        ToolTipBase.__init__(self, button)
--        self.items = items
--    def showcontents(self):
--        listbox = Listbox(self.tipwindow, background="#ffffe0")
--        listbox.pack()
--        for item in self.items:
--            listbox.insert(END, item)
--
--def main():
--    # Test code
--    root = Tk()
--    b = Button(root, text="Hello", command=root.destroy)
--    b.pack()
--    root.update()
--    tip = ListboxToolTip(b, ["Hello", "world"])
--    root.mainloop()
--
--if __name__ == '__main__':
--    main()
-Index: AutoCompleteWindow.py
-===================================================================
---- AutoCompleteWindow.py	(revision 63995)
-+++ AutoCompleteWindow.py	(revision 65541)
-@@ -1,10 +1,16 @@
- """
- An auto-completion window for IDLE, used by the AutoComplete extension
- """
--from Tkinter import *
-+from Tkinter import Toplevel, Listbox, Scrollbar, TclError
-+from Tkconstants import END, LEFT, RIGHT, BOTH, VERTICAL, Y
-+
-+import AutoComplete
- from MultiCall import MC_SHIFT
--import AutoComplete
-+from configHandler import idleConf
- 
-+if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
-+    from ttk import Scrollbar
-+
- HIDE_VIRTUAL_EVENT_NAME = "<<autocompletewindow-hide>>"
- HIDE_SEQUENCES = ("<FocusOut>", "<ButtonPress>")
- KEYPRESS_VIRTUAL_EVENT_NAME = "<<autocompletewindow-keypress>>"
-Index: UndoDelegator.py
-===================================================================
---- UndoDelegator.py	(revision 63995)
-+++ UndoDelegator.py	(revision 65541)
-@@ -1,5 +1,5 @@
- import string
--from Tkinter import *
-+
- from Delegator import Delegator
- 
- #$ event <<redo>>
-@@ -74,7 +74,7 @@
-         if is_saved != self.was_saved:
-             self.was_saved = is_saved
-             if self.saved_change_hook:
--                self.saved_change_hook()
-+                self.saved_change_hook(None)
- 
-     def insert(self, index, chars, tags=None):
-         self.addcmd(InsertCommand(index, chars, tags))
-@@ -336,6 +336,7 @@
-         return self.depth
- 
- def main():
-+    from Tkinter import Tk, Text
-     from Percolator import Percolator
-     root = Tk()
-     root.wm_protocol("WM_DELETE_WINDOW", root.quit)
-Index: Bindings.py
-===================================================================
---- Bindings.py	(revision 63995)
-+++ Bindings.py	(revision 65541)
-@@ -6,15 +6,16 @@
- makes it possible, for example, to define a Debug menu which is only present in
- the PythonShell window, and a Format menu which is only present in the Editor
- windows.
--
- """
- import sys
-+
- from configHandler import idleConf
- 
- menudefs = [
-  # underscore prefixes character to underscore
-  ('file', [
-    ('_New Window', '<<open-new-window>>'),
-+   ('New _Tab', '<<new-tab>>'),
-    ('_Open...', '<<open-window-from-file>>'),
-    ('Open _Module...', '<<open-module>>'),
-    ('Class _Browser', '<<open-class-browser>>'),
-@@ -26,6 +27,7 @@
-    None,
-    ('Prin_t Window', '<<print-window>>'),
-    None,
-+   ('Close Tab', '<<close-tab>>'),
-    ('_Close', '<<close-window>>'),
-    ('E_xit', '<<close-all-windows>>'),
-   ]),
-@@ -80,7 +82,6 @@
-    ]),
- ]
- 
--import sys
- if sys.platform == 'darwin' and '.app' in sys.executable:
-     # Running as a proper MacOS application bundle. This block restructures
-     # the menus a little to make them conform better to the HIG.
-Index: AutoComplete.py
-===================================================================
---- AutoComplete.py	(revision 63995)
-+++ AutoComplete.py	(revision 65541)
-@@ -38,11 +38,11 @@
-     popupwait = idleConf.GetOption("extensions", "AutoComplete",
-                                    "popupwait", type="int", default=0)
- 
--    def __init__(self, editwin=None):
--        self.editwin = editwin
--        if editwin is None:  # subprocess and test
-+    def __init__(self, editpage=None):
-+        self.editpage = editpage
-+        if editpage is None:  # subprocess and test
-             return
--        self.text = editwin.text
-+        self.text = editpage.text
-         self.autocompletewindow = None
- 
-         # id of delayed call, and the index of the text insert when the delayed
-@@ -120,7 +120,7 @@
-             self.text.after_cancel(self._delayed_completion_id)
-             self._delayed_completion_id = None
- 
--        hp = HyperParser(self.editwin, "insert")
-+        hp = HyperParser(self.editpage, "insert")
-         curline = self.text.get("insert linestart", "insert")
-         i = j = len(curline)
-         if hp.is_in_string() and (not mode or mode==COMPLETE_FILES):
-@@ -176,7 +176,7 @@
-         module may be inoperative if the module was not the last to run.
-         """
-         try:
--            rpcclt = self.editwin.flist.pyshell.interp.rpcclt
-+            rpcclt = self.editpage.editwin.flist.pyshell.interp.rpcclt
-         except:
-             rpcclt = None
-         if rpcclt:
-Index: configHandler.py
-===================================================================
---- configHandler.py	(revision 63995)
-+++ configHandler.py	(revision 65541)
-@@ -19,10 +19,10 @@
- """
- import os
- import sys
--import string
--import macosxSupport
- from ConfigParser import ConfigParser, NoOptionError, NoSectionError
- 
-+import macosxSupport
-+
- class InvalidConfigType(Exception): pass
- class InvalidConfigSet(Exception): pass
- class InvalidFgBg(Exception): pass
-@@ -295,7 +295,10 @@
-             back=themeDict['normal-background']
-         else:
-             back=themeDict[element+'-background']
--        highlight={"foreground": fore,"background": back}
-+        #bold = 0
-+        #if  element + '-bold' in themeDict:
-+        #    bold = themeDict[element + '-bold']
-+        highlight={"foreground": fore, "background": back}#, "font": bold}
-         if not fgBg: #return dict of both colours
-             return highlight
-         else: #return specified colour only
-@@ -558,6 +561,10 @@
-         defined here.
-         """
-         keyBindings={
-+            '<<close-tab>>': ['<Control-w>'],
-+            '<<new-tab>>': ['<Control-t>'],
-+            '<<next-tab>>': ['<Control-Next'],
-+            '<<prev-tab>>': ['<Control-Prior'],
-             '<<copy>>': ['<Control-c>', '<Control-C>'],
-             '<<cut>>': ['<Control-x>', '<Control-X>'],
-             '<<paste>>': ['<Control-v>', '<Control-V>'],
-@@ -649,7 +656,7 @@
-                 menuItem='' #make these empty
-                 helpPath='' #so value won't be added to list
-             else: #config entry contains ';' as expected
--                value=string.split(value,';')
-+                value = value.split(';')
-                 menuItem=value[0].strip()
-                 helpPath=value[1].strip()
-             if menuItem and helpPath: #neither are empty strings
-Index: HyperParser.py
-===================================================================
---- HyperParser.py	(revision 63995)
-+++ HyperParser.py	(revision 65541)
-@@ -10,22 +10,22 @@
- 
- import string
- import keyword
-+
- import PyParse
-+from editorpage import index2line
- 
- class HyperParser:
- 
--    def __init__(self, editwin, index):
-+    def __init__(self, editpage, index):
-         """Initialize the HyperParser to analyze the surroundings of the given
-         index.
-         """
- 
--        self.editwin = editwin
--        self.text = text = editwin.text
-+        self.editwin = editwin = editpage.editwin
-+        self.text = text = editpage.text
- 
-         parser = PyParse.Parser(editwin.indentwidth, editwin.tabwidth)
- 
--        def index2line(index):
--            return int(float(index))
-         lno = index2line(text.index(index))
- 
-         if not editwin.context_use_ps1:
-@@ -38,7 +38,7 @@
-                 # its status will be the same as the char before it, if should.
-                 parser.set_str(text.get(startatindex, stopatindex)+' \n')
-                 bod = parser.find_good_parse_start(
--                          editwin._build_char_in_string_func(startatindex))
-+                          editwin.build_char_in_string_func(startatindex))
-                 if bod is not None or startat == 1:
-                     break
-             parser.set_lo(bod or 0)
-Index: ColorDelegator.py
-===================================================================
---- ColorDelegator.py	(revision 63995)
-+++ ColorDelegator.py	(revision 65541)
-@@ -1,8 +1,8 @@
-+import re
- import time
--import re
- import keyword
- import __builtin__
--from Tkinter import *
-+
- from Delegator import Delegator
- from configHandler import idleConf
- 
-@@ -182,8 +182,11 @@
-             ok = False
-             while not ok:
-                 mark = next
--                next = self.index(mark + "+%d lines linestart" %
--                                         lines_to_get)
-+                # XXX self could be None here in some cases.
-+                #     I can reproduce it by clicking "Apply" then "Ok"
-+                #     quickly in the config dialog (while editing a not so
-+                #     small file).
-+                next = self.index(mark + "+%d lines linestart" % lines_to_get)
-                 lines_to_get = min(lines_to_get * 2, 100)
-                 ok = "SYNC" in self.tag_names(next + "-1c")
-                 line = self.get(mark, next)
-@@ -248,6 +251,7 @@
-             self.tag_remove(tag, "1.0", "end")
- 
- def main():
-+    from Tkinter import Tk, Text
-     from Percolator import Percolator
-     root = Tk()
-     root.wm_protocol("WM_DELETE_WINDOW", root.quit)
-Index: configSectionNameDialog.py
-===================================================================
---- configSectionNameDialog.py	(revision 63995)
-+++ configSectionNameDialog.py	(revision 65541)
-@@ -2,96 +2,111 @@
- Dialog that allows user to specify a new config file section name.
- Used to get new highlight theme and keybinding set names.
- """
--from Tkinter import *
-+from Tkinter import Toplevel, Entry, Frame, Label, Button, StringVar
-+from Tkconstants import TOP, BOTTOM, RIGHT, BOTH, SUNKEN, X
- import tkMessageBox
- 
-+from configHandler import idleConf
-+
-+TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
-+if TTK:
-+    from ttk import Entry, Frame, Label, Button
-+
- class GetCfgSectionNameDialog(Toplevel):
--    def __init__(self,parent,title,message,usedNames):
-+    def __init__(self, parent, title, message, usedNames):
-         """
-         message - string, informational message to display
-         usedNames - list, list of names already in use for validity check
-         """
-         Toplevel.__init__(self, parent)
-         self.configure(borderwidth=5)
--        self.resizable(height=FALSE,width=FALSE)
-+        self.resizable(height=False, width=False)
-         self.title(title)
-         self.transient(parent)
-         self.grab_set()
-         self.protocol("WM_DELETE_WINDOW", self.Cancel)
-         self.parent = parent
--        self.message=message
--        self.usedNames=usedNames
--        self.result=''
-+        self.message = message
-+        self.usedNames = usedNames
-+        self.result = ''
-         self.CreateWidgets()
-         self.withdraw() #hide while setting geometry
-         self.update_idletasks()
--        #needs to be done here so that the winfo_reqwidth is valid
--        self.messageInfo.config(width=self.frameMain.winfo_reqwidth())
-         self.geometry("+%d+%d" %
--            ((parent.winfo_rootx()+((parent.winfo_width()/2)
--                -(self.winfo_reqwidth()/2)),
--              parent.winfo_rooty()+((parent.winfo_height()/2)
--                -(self.winfo_reqheight()/2)) )) ) #centre dialog over parent
-+            ((parent.winfo_rootx() + ((parent.winfo_width() / 2)
-+                - (self.winfo_reqwidth() / 2)),
-+              parent.winfo_rooty() + ((parent.winfo_height() / 2)
-+                - (self.winfo_reqheight() / 2)) )) ) #centre dialog over parent
-         self.deiconify() #geometry set, unhide
-         self.wait_window()
- 
-     def CreateWidgets(self):
--        self.name=StringVar(self)
--        self.fontSize=StringVar(self)
--        self.frameMain = Frame(self,borderwidth=2,relief=SUNKEN)
--        self.frameMain.pack(side=TOP,expand=TRUE,fill=BOTH)
--        self.messageInfo=Message(self.frameMain,anchor=W,justify=LEFT,padx=5,pady=5,
--                text=self.message)#,aspect=200)
--        entryName=Entry(self.frameMain,textvariable=self.name,width=30)
-+        self.name = StringVar(self)
-+        self.fontSize = StringVar(self)
-+        self.frameMain = Frame(self, borderwidth=2, relief=SUNKEN)
-+        self.messageInfo = Label(self.frameMain, text=self.message)
-+        entryName = Entry(self.frameMain, textvariable=self.name, width=30)
-+        frameButtons = Frame(self)
-+        self.buttonOk = Button(frameButtons, text='Ok', command=self.Ok)
-+        self.buttonCancel = Button(frameButtons, text='Cancel',
-+                command=self.Cancel)
-+
-         entryName.focus_set()
--        self.messageInfo.pack(padx=5,pady=5)#,expand=TRUE,fill=BOTH)
--        entryName.pack(padx=5,pady=5)
--        frameButtons=Frame(self)
--        frameButtons.pack(side=BOTTOM,fill=X)
--        self.buttonOk = Button(frameButtons,text='Ok',
--                width=8,command=self.Ok)
--        self.buttonOk.grid(row=0,column=0,padx=5,pady=5)
--        self.buttonCancel = Button(frameButtons,text='Cancel',
--                width=8,command=self.Cancel)
--        self.buttonCancel.grid(row=0,column=1,padx=5,pady=5)
- 
-+        self.frameMain.pack(side=TOP, expand=True, fill=BOTH)
-+        self.messageInfo.pack(padx=5, pady=5)
-+        entryName.pack(padx=5, pady=5)
-+        frameButtons.pack(side=BOTTOM, fill=X)
-+        self.buttonOk.pack(padx=1, pady=5, side=RIGHT)
-+        self.buttonCancel.pack(pady=5, padx=5, side=RIGHT)
-+
-+        if TTK:
-+            self.messageInfo['padding'] = 5
-+            frameButtons['style'] = 'RootColor.TFrame'
-+        else:
-+            self.messageInfo.configure(padx=5, pady=5)
-+
-     def NameOk(self):
-         #simple validity check for a sensible
-         #ConfigParser file section name
--        nameOk=1
--        name=self.name.get()
-+        nameOk = 1
-+        name = self.name.get()
-         name.strip()
-+
-         if not name: #no name specified
-             tkMessageBox.showerror(title='Name Error',
--                    message='No name specified.', parent=self)
--            nameOk=0
--        elif len(name)>30: #name too long
-+                message='No name specified.', parent=self)
-+            nameOk = 0
-+        elif len(name) > 30: #name too long
-             tkMessageBox.showerror(title='Name Error',
--                    message='Name too long. It should be no more than '+
--                    '30 characters.', parent=self)
-+                message=('Name too long. It should be no more than '
-+                         '30 characters.'), parent=self)
-             nameOk=0
-         elif name in self.usedNames:
-             tkMessageBox.showerror(title='Name Error',
-                     message='This name is already in use.', parent=self)
-             nameOk=0
-+
-         return nameOk
- 
-     def Ok(self, event=None):
-         if self.NameOk():
--            self.result=self.name.get().strip()
-+            self.result = self.name.get().strip()
-             self.destroy()
- 
-     def Cancel(self, event=None):
--        self.result=''
-+        self.result = ''
-         self.destroy()
- 
- if __name__ == '__main__':
-+    from Tkinter import Tk
-     #test the dialog
--    root=Tk()
-     def run():
--        keySeq=''
--        dlg=GetCfgSectionNameDialog(root,'Get Name',
--                'The information here should need to be word wrapped. Test.')
-+        keySeq = ''
-+        dlg = GetCfgSectionNameDialog(root, 'Get Name',
-+            'The information here should need to be word wrapped. Test.', [])
-         print dlg.result
--    Button(root,text='Dialog',command=run).pack()
-+
-+    root=Tk()
-+    Button(root, text='Dialog', command=run).pack()
-     root.mainloop()
-Index: stylist.py
-===================================================================
---- stylist.py	(revision 0)
-+++ stylist.py	(revision 65541)
-@@ -0,0 +1,29 @@
-+from configHandler import idleConf
-+
-+TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
-+
-+class PoorManStyle(object):
-+    def __init__(self, parent, styles=None, cfgstyles=None):
-+        self.parent = parent
-+        self.cfgstyles = cfgstyles
-+        self.styles = styles
-+
-+    def configure(self, style, lookup=None, background=None):
-+        if style not in self.cfgstyles: # passed wrong style probably
-+            return
-+
-+        widget = getattr(self.parent, self.cfgstyles[style])
-+        if lookup:
-+            return widget.cget('bg')
-+
-+        widget.configure(bg=background)
-+
-+    def style_it(self, w, style):
-+        if TTK:
-+            w['style'] = style
-+            return
-+
-+        if not style in self.styles: # may not need to be styled
-+            return
-+
-+        w.configure(**self.styles[style])
-Index: ZoomHeight.py
-===================================================================
---- ZoomHeight.py	(revision 63995)
-+++ ZoomHeight.py	(revision 65541)
-@@ -12,11 +12,11 @@
-          ])
-     ]
- 
--    def __init__(self, editwin):
--        self.editwin = editwin
-+    def __init__(self, editpage):
-+        self.editpage = editpage
- 
-     def zoom_height_event(self, event):
--        top = self.editwin.top
-+        top = self.editpage.editwin.top
-         zoom_height(top)
- 
- def zoom_height(top):
-Index: PyShell.py
-===================================================================
---- PyShell.py	(revision 63995)
-+++ PyShell.py	(revision 65541)
-@@ -1,40 +1,50 @@
- #! /usr/bin/env python
--
- import os
--import os.path
-+import re
- import sys
-+import time
-+import types
- import string
- import getopt
--import re
- import socket
--import time
-+import linecache
- import threading
--import traceback
--import types
--import macosxSupport
--
--import linecache
- from code import InteractiveInterpreter
- 
- try:
--    from Tkinter import *
-+    from Tkinter import Tk, Toplevel, TclError
-+    from Tkconstants import END
- except ImportError:
-     print>>sys.__stderr__, "** IDLE can't import Tkinter.  " \
-                            "Your Python may not be configured for Tk. **"
-     sys.exit(1)
-+try:
-+    from ttk import Style
-+    TTK = 1
-+except ImportError:
-+    print >> sys.stderr, "** IDLE can't import ttk."
-+    TTK = 0
-+
- import tkMessageBox
- 
--from EditorWindow import EditorWindow, fixwordbreaks
--from FileList import FileList
--from ColorDelegator import ColorDelegator
--from UndoDelegator import UndoDelegator
--from OutputWindow import OutputWindow
-+import macosxSupport
- from configHandler import idleConf
--import idlever
- 
-+# store ttk availability
-+idleConf.SetOption('main', 'General', 'use-ttk', str(TTK))
-+idleConf.SaveUserCfgFiles()
-+
- import rpc
-+import utils
-+import idlever
- import Debugger
-+import IOBinding
- import RemoteDebugger
-+from FileList import FileList
-+from OutputWindow import OutputWindow
-+from EditorWindow import EditorWindow, fixwordbreaks
-+from UndoDelegator import UndoDelegator
-+from ColorDelegator import ColorDelegator
- 
- IDENTCHARS = string.ascii_letters + string.digits + "_"
- LOCALHOST = '127.0.0.1'
-@@ -55,18 +65,20 @@
- except ImportError:
-     pass
- else:
--    def idle_showwarning(message, category, filename, lineno):
-+    def idle_showwarning(message, category, filename, lineno, line=None):
-         file = warning_stream
-         try:
--            file.write(warnings.formatwarning(message, category, filename, lineno))
-+            file.write(warnings.formatwarning(message, category, filename,
-+                lineno, line))
-         except IOError:
-             pass  ## file (probably __stderr__) is invalid, warning dropped.
-     warnings.showwarning = idle_showwarning
--    def idle_formatwarning(message, category, filename, lineno):
-+    def idle_formatwarning(message, category, filename, lineno, line=None):
-         """Format warnings the IDLE way"""
-         s = "\nWarning (from warnings module):\n"
-         s += '  File \"%s\", line %s\n' % (filename, lineno)
--        line = linecache.getline(filename, lineno).strip()
-+        if line is None:
-+            line = linecache.getline(filename, lineno).strip()
-         if line:
-             s += "    %s\n" % line
-         s += "%s: %s\n>>> " % (category.__name__, message)
-@@ -100,58 +112,67 @@
- class PyShellEditorWindow(EditorWindow):
-     "Regular text edit window in IDLE, supports breakpoints"
- 
-+    rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"),
-+                   ("Clear Breakpoint", "<<clear-breakpoint-here>>")]
-+
-     def __init__(self, *args):
--        self.breakpoints = []
-         EditorWindow.__init__(self, *args)
--        self.text.bind("<<set-breakpoint-here>>", self.set_breakpoint_here)
--        self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here)
--        self.text.bind("<<open-python-shell>>", self.flist.open_shell)
- 
-         self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(),
--                                           'breakpoints.lst')
-+            'breakpoints.lst')
-+        self.top.bind('<<tab-created>>', self.__configure_new_tab)
-+        self.__configure_new_tab()
-+
-+    def __configure_new_tab(self, event=None):
-+        page = self.text_notebook.last_page().editpage
-+        page.breakpoints = []
-+        text = page.text
-+
-+        text.bind("<<set-breakpoint-here>>",
-+            utils.callback(self._set_breakpoint_here, text, page))
-+        text.bind("<<clear-breakpoint-here>>",
-+            utils.callback(self._clear_breakpoint_here, text, page))
-+        text.bind("<<open-python-shell>>", self.flist.open_shell)
-+
-         # whenever a file is changed, restore breakpoints
--        if self.io.filename: self.restore_file_breaks()
--        def filename_changed_hook(old_hook=self.io.filename_change_hook,
-+        if page.io.filename:
-+            self.restore_file_breaks(text, page)
-+
-+        def filename_changed_hook(old_hook=page.io.filename_change_hook,
-                                   self=self):
--            self.restore_file_breaks()
-+            self.restore_file_breaks(text, page)
-             old_hook()
--        self.io.set_filename_change_hook(filename_changed_hook)
-+        page.io.set_filename_change_hook(filename_changed_hook)
- 
--    rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"),
--                   ("Clear Breakpoint", "<<clear-breakpoint-here>>")]
--
--    def set_breakpoint(self, lineno):
--        text = self.text
--        filename = self.io.filename
-+    def set_breakpoint(self, lineno, text, page):
-+        filename = page.io.filename
-         text.tag_add("BREAK", "%d.0" % lineno, "%d.0" % (lineno+1))
-         try:
--            i = self.breakpoints.index(lineno)
-+            i = page.breakpoints.index(lineno)
-         except ValueError:  # only add if missing, i.e. do once
--            self.breakpoints.append(lineno)
-+            page.breakpoints.append(lineno)
-         try:    # update the subprocess debugger
-             debug = self.flist.pyshell.interp.debugger
-             debug.set_breakpoint_here(filename, lineno)
-         except: # but debugger may not be active right now....
-             pass
- 
--    def set_breakpoint_here(self, event=None):
--        text = self.text
--        filename = self.io.filename
-+    def _set_breakpoint_here(self, event=None, text=None, page=None):
-+        filename = page.io.filename
-         if not filename:
-             text.bell()
-             return
-         lineno = int(float(text.index("insert")))
--        self.set_breakpoint(lineno)
-+        self.set_breakpoint(lineno, text, page)
- 
--    def clear_breakpoint_here(self, event=None):
--        text = self.text
--        filename = self.io.filename
-+    def _clear_breakpoint_here(self, event=None, text=None, page=None):
-+        filename = page.io.filename
-         if not filename:
-             text.bell()
-             return
-         lineno = int(float(text.index("insert")))
-         try:
--            self.breakpoints.remove(lineno)
-+            page.breakpoints.remove(lineno)
-         except:
-             pass
-         text.tag_remove("BREAK", "insert linestart",\
-@@ -163,13 +184,17 @@
-             pass
- 
-     def clear_file_breaks(self):
--        if self.breakpoints:
--            text = self.text
--            filename = self.io.filename
-+        for page in self.text_notebook.pages.itervalues():
-+            page = page.editpage
-+            text = page.text
-+            filename = page.io.filename
-+
-+            if not page.breakpoints:
-+                continue
-             if not filename:
-                 text.bell()
--                return
--            self.breakpoints = []
-+                continue
-+            page.breakpoints = []
-             text.tag_remove("BREAK", "1.0", END)
-             try:
-                 debug = self.flist.pyshell.interp.debugger
-@@ -177,7 +202,7 @@
-             except:
-                 pass
- 
--    def store_file_breaks(self):
-+    def store_file_breaks(self, page):
-         "Save breakpoints when file is saved"
-         # XXX 13 Dec 2002 KBK Currently the file must be saved before it can
-         #     be run.  The breaks are saved at that time.  If we introduce
-@@ -200,8 +225,8 @@
-         #     debugger is loaded) is updated during the save, the visible
-         #     breaks stay synched with the subprocess even if one of these
-         #     unexpected breakpoint deletions occurs.
--        breaks = self.breakpoints
--        filename = self.io.filename
-+        breaks = page.breakpoints
-+        filename = page.io.filename
-         try:
-             lines = open(self.breakpointPath,"r").readlines()
-         except IOError:
-@@ -210,49 +235,42 @@
-         for line in lines:
-             if not line.startswith(filename + '='):
-                 new_file.write(line)
--        self.update_breakpoints()
--        breaks = self.breakpoints
-+        self.update_breakpoints(page)
-+        breaks = page.breakpoints
-         if breaks:
-             new_file.write(filename + '=' + str(breaks) + '\n')
-         new_file.close()
- 
--    def restore_file_breaks(self):
--        self.text.update()   # this enables setting "BREAK" tags to be visible
--        filename = self.io.filename
-+    def restore_file_breaks(self, text, page):
-+        text.update()   # this enables setting "BREAK" tags to be visible
-+        filename = page.io.filename
-         if filename is None:
-             return
-         if os.path.isfile(self.breakpointPath):
--            lines = open(self.breakpointPath,"r").readlines()
-+            lines = open(self.breakpointPath, "r").readlines()
-             for line in lines:
-                 if line.startswith(filename + '='):
-                     breakpoint_linenumbers = eval(line[len(filename)+1:])
-                     for breakpoint_linenumber in breakpoint_linenumbers:
--                        self.set_breakpoint(breakpoint_linenumber)
-+                        self.set_breakpoint(breakpoint_linenumber, text, page)
- 
--    def update_breakpoints(self):
--        "Retrieves all the breakpoints in the current window"
--        text = self.text
-+    def update_breakpoints(self, page):
-+        "Retrieves all the breakpoints in the current page"
-+        text = page.text
-         ranges = text.tag_ranges("BREAK")
-         linenumber_list = self.ranges_to_linenumbers(ranges)
--        self.breakpoints = linenumber_list
-+        page.breakpoints = linenumber_list
- 
-     def ranges_to_linenumbers(self, ranges):
-         lines = []
-         for index in range(0, len(ranges), 2):
--            lineno = int(float(ranges[index]))
--            end = int(float(ranges[index+1]))
-+            lineno = int(float(str(ranges[index])))
-+            end = int(float(str(ranges[index+1])))
-             while lineno < end:
-                 lines.append(lineno)
-                 lineno += 1
-         return lines
- 
--# XXX 13 Dec 2002 KBK Not used currently
--#    def saved_change_hook(self):
--#        "Extend base method - clear breaks if module is modified"
--#        if not self.get_saved():
--#            self.clear_file_breaks()
--#        EditorWindow.saved_change_hook(self)
--
-     def _close(self):
-         "Extend base method - clear breaks when module is closed"
-         self.clear_file_breaks()
-@@ -589,7 +607,6 @@
-         self.save_warnings_filters = warnings.filters[:]
-         warnings.filterwarnings(action="error", category=SyntaxWarning)
-         if isinstance(source, types.UnicodeType):
--            import IOBinding
-             try:
-                 source = source.encode(IOBinding.encoding)
-             except UnicodeError:
-@@ -814,30 +831,47 @@
-             flist = PyShellFileList(root)
-         #
-         OutputWindow.__init__(self, flist, None, None)
-+        # remove things related to tabs. The window running the shell is
-+        # considered special enough to have a single window for it.
-+
-+        # remove tabs area
-+        if TTK:
-+            self.text_notebook['style'] = 'PyShell.TNotebook'
-+            style = Style(self.top)
-+            style.layout('PyShell.TNotebook.Tab', [('null', '')])
-+        else:
-+            self.text_notebook._tab_set.grid_forget()
-+
-+        # remove commands related to tab
-+        if 'file' in self.menudict:
-+            menu = self.menudict['file']
-+            curr_entry = None
-+            i = 0
-+            while True:
-+                last_entry, curr_entry = curr_entry, menu.entryconfigure(i)
-+                if last_entry == curr_entry:
-+                    break
-+
-+                if 'label' in curr_entry and 'Tab' in curr_entry['label'][-1]:
-+                    if 'New' in ' '.join(curr_entry['label'][-1]):
-+                        menu.delete(i)
-+                i += 1
-+        self.text.unbind('<<new-tab>>')
-+        #self.text.unbind('<<close-tab>>')
-+
-         #
--##        self.config(usetabs=1, indentwidth=8, context_use_ps1=1)
-         self.usetabs = True
-         # indentwidth must be 8 when using tabs.  See note in EditorWindow:
-         self.indentwidth = 8
-         self.context_use_ps1 = True
-         #
--        text = self.text
--        text.configure(wrap="char")
--        text.bind("<<newline-and-indent>>", self.enter_callback)
--        text.bind("<<plain-newline-and-indent>>", self.linefeed_callback)
--        text.bind("<<interrupt-execution>>", self.cancel_callback)
--        text.bind("<<end-of-file>>", self.eof_callback)
--        text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
--        text.bind("<<toggle-debugger>>", self.toggle_debugger)
--        text.bind("<<toggle-jit-stack-viewer>>", self.toggle_jit_stack_viewer)
--        if use_subprocess:
--            text.bind("<<view-restart>>", self.view_restart_mark)
--            text.bind("<<restart-shell>>", self.restart_shell)
--        #
-+        self.wtext = None
-+        self.textpage = None
-+        self.__configure_new_tab()
-+
-         self.save_stdout = sys.stdout
-         self.save_stderr = sys.stderr
-         self.save_stdin = sys.stdin
--        import IOBinding
-         self.stdout = PseudoFile(self, "stdout", IOBinding.encoding)
-         self.stderr = PseudoFile(self, "stderr", IOBinding.encoding)
-         self.console = PseudoFile(self, "console", IOBinding.encoding)
-@@ -845,11 +879,37 @@
-             sys.stdout = self.stdout
-             sys.stderr = self.stderr
-             sys.stdin = self
--        #
--        self.history = self.History(self.text)
--        #
-+
-         self.pollinterval = 50  # millisec
- 
-+        if TTK:
-+            self.set_theme(Style(self.root))
-+
-+    def __configure_new_tab(self):
-+        # select the last page (the one added)
-+        page = self.text_notebook.last_page().editpage
-+        self.wtext = text = page.text
-+        self.textpage = page
-+
-+        text.configure(wrap="char")
-+        text.bind("<<newline-and-indent>>",
-+            utils.callback(self._enter_callback, text))
-+        text.bind("<<plain-newline-and-indent>>",
-+            utils.callback(self._linefeed_callback, text))
-+        text.bind("<<interrupt-execution>>",
-+            utils.callback(self._cancel_callback, text))
-+        text.bind("<<end-of-file>>",
-+            utils.callback(self._eof_callback, text))
-+        text.bind("<<toggle-debugger>>", self._toggle_debugger)
-+        text.bind("<<toggle-jit-stack-viewer>>", self._toggle_jit_stack_viewer)
-+        text.bind("<<open-stack-viewer>>", self.open_stack_viewer)
-+        if use_subprocess:
-+            text.bind("<<view-restart>>",
-+                utils.callback(self._view_restart_mark, text))
-+            text.bind("<<restart-shell>>", self.restart_shell)
-+
-+        page.history = self.History(text)
-+
-     def get_standard_extension_names(self):
-         return idleConf.GetExtensions(shell_only=True)
- 
-@@ -866,11 +926,11 @@
-     def get_warning_stream(self):
-         return warning_stream
- 
--    def toggle_debugger(self, event=None):
-+    def _toggle_debugger(self, event=None):
-         if self.executing:
-             tkMessageBox.showerror("Don't debug now",
-                 "You can only toggle the debugger when idle",
--                master=self.text)
-+                master=self.text_notebook)
-             self.set_debugger_indicator()
-             return "break"
-         else:
-@@ -884,7 +944,7 @@
-         db = self.interp.getdebugger()
-         self.setvar("<<toggle-debugger>>", not not db)
- 
--    def toggle_jit_stack_viewer(self, event=None):
-+    def _toggle_jit_stack_viewer(self, event=None):
-         pass # All we need is the variable
- 
-     def close_debugger(self):
-@@ -930,7 +990,7 @@
-                 "Kill?",
-                 "The program is still running!\n Do you want to kill it?",
-                 default="ok",
--                parent=self.text)
-+                parent=self.text_notebook)
-             if response is False:
-                 return "cancel"
-         if self.reading:
-@@ -938,7 +998,7 @@
-         self.canceled = True
-         self.closing = True
-         # Wait for poll_subprocess() rescheduling to stop
--        self.text.after(2 * self.pollinterval, self.close2)
-+        self.text_notebook.after(2 * self.pollinterval, self.close2)
- 
-     def close2(self):
-         return EditorWindow.close(self)
-@@ -956,7 +1016,9 @@
-         self.interp = None
-         self.console = None
-         self.flist.pyshell = None
--        self.history = None
-+        for page in self.text_notebook.pages.itervalues():
-+            page.editpage.history = None
-+
-         EditorWindow._close(self)
- 
-     def ispythonsource(self, filename):
-@@ -996,38 +1058,12 @@
-         Tkinter._default_root = None # 03Jan04 KBK What's this?
-         return True
- 
--    def readline(self):
--        save = self.reading
--        try:
--            self.reading = 1
--            self.top.mainloop()  # nested mainloop()
--        finally:
--            self.reading = save
--        line = self.text.get("iomark", "end-1c")
--        if len(line) == 0:  # may be EOF if we quit our mainloop with Ctrl-C
--            line = "\n"
--        if isinstance(line, unicode):
--            import IOBinding
--            try:
--                line = line.encode(IOBinding.encoding)
--            except UnicodeError:
--                pass
--        self.resetoutput()
--        if self.canceled:
--            self.canceled = 0
--            if not use_subprocess:
--                raise KeyboardInterrupt
--        if self.endoffile:
--            self.endoffile = 0
--            line = ""
--        return line
--
-     def isatty(self):
-         return True
- 
--    def cancel_callback(self, event=None):
-+    def _cancel_callback(self, event=None, text=None):
-         try:
--            if self.text.compare("sel.first", "!=", "sel.last"):
-+            if text.compare("sel.first", "!=", "sel.last"):
-                 return # Active selection -- always use default binding
-         except:
-             pass
-@@ -1047,11 +1083,11 @@
-             self.top.quit()  # exit the nested mainloop() in readline()
-         return "break"
- 
--    def eof_callback(self, event):
-+    def _eof_callback(self, event, text):
-         if self.executing and not self.reading:
-             return # Let the default binding (delete next char) take over
--        if not (self.text.compare("iomark", "==", "insert") and
--                self.text.compare("insert", "==", "end-1c")):
-+        if not (text.compare("iomark", "==", "insert") and
-+                text.compare("insert", "==", "end-1c")):
-             return # Let the default binding (delete next char) take over
-         if not self.executing:
-             self.resetoutput()
-@@ -1062,24 +1098,24 @@
-             self.top.quit()
-         return "break"
- 
--    def linefeed_callback(self, event):
-+    def _linefeed_callback(self, event, text):
-         # Insert a linefeed without entering anything (still autoindented)
-         if self.reading:
--            self.text.insert("insert", "\n")
--            self.text.see("insert")
-+            text.insert("insert", "\n")
-+            text.see("insert")
-         else:
-             self.newline_and_indent_event(event)
-         return "break"
- 
--    def enter_callback(self, event):
-+    def _enter_callback(self, event, text):
-         if self.executing and not self.reading:
-             return # Let the default binding (insert '\n') take over
-         # If some text is selected, recall the selection
-         # (but only if this before the I/O mark)
-         try:
--            sel = self.text.get("sel.first", "sel.last")
-+            sel = text.get("sel.first", "sel.last")
-             if sel:
--                if self.text.compare("sel.last", "<=", "iomark"):
-+                if text.compare("sel.last", "<=", "iomark"):
-                     self.recall(sel, event)
-                     return "break"
-         except:
-@@ -1087,51 +1123,52 @@
-         # If we're strictly before the line containing iomark, recall
-         # the current line, less a leading prompt, less leading or
-         # trailing whitespace
--        if self.text.compare("insert", "<", "iomark linestart"):
-+        if text.compare("insert", "<", "iomark linestart"):
-             # Check if there's a relevant stdin range -- if so, use it
--            prev = self.text.tag_prevrange("stdin", "insert")
--            if prev and self.text.compare("insert", "<", prev[1]):
--                self.recall(self.text.get(prev[0], prev[1]), event)
-+            prev = text.tag_prevrange("stdin", "insert")
-+            if prev and text.compare("insert", "<", prev[1]):
-+                self.recall(text.get(prev[0], prev[1]), event)
-                 return "break"
--            next = self.text.tag_nextrange("stdin", "insert")
--            if next and self.text.compare("insert lineend", ">=", next[0]):
--                self.recall(self.text.get(next[0], next[1]), event)
-+            next = text.tag_nextrange("stdin", "insert")
-+            if next and text.compare("insert lineend", ">=", next[0]):
-+                self.recall(text.get(next[0], next[1]), event)
-                 return "break"
-             # No stdin mark -- just get the current line, less any prompt
--            indices = self.text.tag_nextrange("console", "insert linestart")
-+            indices = text.tag_nextrange("console", "insert linestart")
-             if indices and \
--               self.text.compare(indices[0], "<=", "insert linestart"):
--                self.recall(self.text.get(indices[1], "insert lineend"), event)
-+               text.compare(indices[0], "<=", "insert linestart"):
-+                self.recall(text.get(indices[1], "insert lineend"), event)
-             else:
--                self.recall(self.text.get("insert linestart", "insert lineend"), event)
-+                self.recall(text.get("insert linestart", "insert lineend"),
-+                    event)
-             return "break"
-         # If we're between the beginning of the line and the iomark, i.e.
-         # in the prompt area, move to the end of the prompt
--        if self.text.compare("insert", "<", "iomark"):
--            self.text.mark_set("insert", "iomark")
-+        if text.compare("insert", "<", "iomark"):
-+            text.mark_set("insert", "iomark")
-         # If we're in the current input and there's only whitespace
-         # beyond the cursor, erase that whitespace first
--        s = self.text.get("insert", "end-1c")
-+        s = text.get("insert", "end-1c")
-         if s and not s.strip():
--            self.text.delete("insert", "end-1c")
-+            text.delete("insert", "end-1c")
-         # If we're in the current input before its last line,
-         # insert a newline right at the insert point
--        if self.text.compare("insert", "<", "end-1c linestart"):
-+        if text.compare("insert", "<", "end-1c linestart"):
-             self.newline_and_indent_event(event)
-             return "break"
-         # We're in the last line; append a newline and submit it
--        self.text.mark_set("insert", "end-1c")
-+        text.mark_set("insert", "end-1c")
-         if self.reading:
--            self.text.insert("insert", "\n")
--            self.text.see("insert")
-+            text.insert("insert", "\n")
-+            text.see("insert")
-         else:
-             self.newline_and_indent_event(event)
--        self.text.tag_add("stdin", "iomark", "end-1c")
--        self.text.update_idletasks()
-+        text.tag_add("stdin", "iomark", "end-1c")
-+        text.update_idletasks()
-         if self.reading:
-             self.top.quit() # Break out of recursive mainloop() in raw_input()
-         else:
--            self.runit()
-+            self._runit(text)
-         return "break"
- 
-     def recall(self, s, event):
-@@ -1139,15 +1176,15 @@
-         s = re.sub(r'^\s*\n', '' , s)
-         s = re.sub(r'\n\s*$', '', s)
-         lines = s.split('\n')
--        self.text.undo_block_start()
-+        self.wtext.undo_block_start()
-         try:
--            self.text.tag_remove("sel", "1.0", "end")
--            self.text.mark_set("insert", "end-1c")
--            prefix = self.text.get("insert linestart", "insert")
-+            self.wtext.tag_remove("sel", "1.0", "end")
-+            self.wtext.mark_set("insert", "end-1c")
-+            prefix = self.wtext.get("insert linestart", "insert")
-             if prefix.rstrip().endswith(':'):
-                 self.newline_and_indent_event(event)
--                prefix = self.text.get("insert linestart", "insert")
--            self.text.insert("insert", lines[0].strip())
-+                prefix = self.wtext.get("insert linestart", "insert")
-+            self.wtext.insert("insert", lines[0].strip())
-             if len(lines) > 1:
-                 orig_base_indent = re.search(r'^([ \t]*)', lines[0]).group(0)
-                 new_base_indent  = re.search(r'^([ \t]*)', prefix).group(0)
-@@ -1155,13 +1192,13 @@
-                     if line.startswith(orig_base_indent):
-                         # replace orig base indentation with new indentation
-                         line = new_base_indent + line[len(orig_base_indent):]
--                    self.text.insert('insert', '\n'+line.rstrip())
-+                    self.wtext.insert('insert', '\n'+line.rstrip())
-         finally:
--            self.text.see("insert")
--            self.text.undo_block_stop()
-+            self.wtext.see("insert")
-+            self.wtext.undo_block_stop()
- 
--    def runit(self):
--        line = self.text.get("iomark", "end-1c")
-+    def _runit(self, text):
-+        line = text.get("iomark", "end-1c")
-         # Strip off last newline and surrounding whitespace.
-         # (To allow you to hit return twice to end a statement.)
-         i = len(line)
-@@ -1179,18 +1216,18 @@
-             return self.interp.remote_stack_viewer()
-         try:
-             sys.last_traceback
--        except:
-+        except AttributeError:
-             tkMessageBox.showerror("No stack trace",
-                 "There is no stack trace yet.\n"
-                 "(sys.last_traceback is not defined)",
--                master=self.text)
-+                master=self.text_notebook)
-             return
-         from StackViewer import StackBrowser
-         sv = StackBrowser(self.root, self.flist)
- 
--    def view_restart_mark(self, event=None):
--        self.text.see("iomark")
--        self.text.see("restart")
-+    def _view_restart_mark(self, event=None, text=None):
-+        text.see("iomark")
-+        text.see("restart")
- 
-     def restart_shell(self, event=None):
-         self.interp.restart_subprocess()
-@@ -1202,25 +1239,30 @@
-         except:
-             s = ""
-         self.console.write(s)
--        self.text.mark_set("insert", "end-1c")
-+
-+        curr_page = self.current_page
-+        if not curr_page:
-+            return
-+
-+        curr_page.text.mark_set("insert", "end-1c")
-         self.set_line_and_column()
--        self.io.reset_undo()
-+        curr_page.io.reset_undo()
- 
-     def resetoutput(self):
--        source = self.text.get("iomark", "end-1c")
--        if self.history:
--            self.history.history_store(source)
--        if self.text.get("end-2c") != "\n":
--            self.text.insert("end-1c", "\n")
--        self.text.mark_set("iomark", "end-1c")
-+        source = self.wtext.get("iomark", "end-1c")
-+        if self.textpage.history:
-+            self.textpage.history.history_store(source)
-+        if self.wtext.get("end-2c") != "\n":
-+            self.wtext.insert("end-1c", "\n")
-+        self.wtext.mark_set("iomark", "end-1c")
-         self.set_line_and_column()
-         sys.stdout.softspace = 0
- 
-     def write(self, s, tags=()):
-         try:
--            self.text.mark_gravity("iomark", "right")
--            OutputWindow.write(self, s, tags, "iomark")
--            self.text.mark_gravity("iomark", "left")
-+            self.wtext.mark_gravity("iomark", "right")
-+            OutputWindow.write(self, s, tags, "iomark", self.wtext)
-+            self.wtext.mark_gravity("iomark", "left")
-         except:
-             pass
-         if self.canceled:
-@@ -1381,6 +1423,19 @@
-     # start editor and/or shell windows:
-     root = Tk(className="Idle")
- 
-+    if TTK:
-+        # create base styles used along idle files
-+        style = Style()
-+
-+        rootbg = style.map('.', 'background')
-+        fstyle = {'background': []}
-+        for sspec in rootbg:
-+            if 'active' in sspec[:-1]:
-+                fstyle['background'].append(('!disabled', sspec[-1]))
-+                break
-+        style.map('RootColor.TFrame', **fstyle)
-+        # end styles
-+
-     fixwordbreaks(root)
-     root.withdraw()
-     flist = PyShellFileList(root)
-Index: ParenMatch.py
-===================================================================
---- ParenMatch.py	(revision 63995)
-+++ ParenMatch.py	(revision 65541)
-@@ -56,14 +56,13 @@
-     RESTORE_SEQUENCES = ("<KeyPress>", "<ButtonPress>",
-                          "<Key-Return>", "<Key-BackSpace>")
- 
--    def __init__(self, editwin):
--        self.editwin = editwin
--        self.text = editwin.text
-+    def __init__(self, editpage):
-+        self.editpage = editpage
-+        self.text = editpage.text
-         # Bind the check-restore event to the function restore_event,
-         # so that we can then use activate_restore (which calls event_add)
-         # and deactivate_restore (which calls event_delete).
--        editwin.text.bind(self.RESTORE_VIRTUAL_EVENT_NAME,
--                          self.restore_event)
-+        editpage.text.bind(self.RESTORE_VIRTUAL_EVENT_NAME, self.restore_event)
-         self.counter = 0
-         self.is_restore_active = 0
-         self.set_style(self.STYLE)
-@@ -90,7 +89,7 @@
-             self.set_timeout = self.set_timeout_none
- 
-     def flash_paren_event(self, event):
--        indices = HyperParser(self.editwin, "insert").get_surrounding_brackets()
-+        indices = HyperParser(self.editpage, "insert").get_surrounding_brackets()
-         if indices is None:
-             self.warn_mismatched()
-             return
-@@ -103,7 +102,7 @@
-         closer = self.text.get("insert-1c")
-         if closer not in _openers:
-             return
--        hp = HyperParser(self.editwin, "insert-1c")
-+        hp = HyperParser(self.editpage, "insert-1c")
-         if not hp.is_in_code():
-             return
-         indices = hp.get_surrounding_brackets(_openers[closer], True)
-@@ -159,14 +158,13 @@
-             if index != self.text.index("insert"):
-                 self.handle_restore_timer(c)
-             else:
--                self.editwin.text_frame.after(CHECK_DELAY, callme, callme)
--        self.editwin.text_frame.after(CHECK_DELAY, callme, callme)
-+                self.text.master.after(CHECK_DELAY, callme, callme)
-+        self.text.master.after(CHECK_DELAY, callme, callme)
- 
-     def set_timeout_last(self):
-         """The last highlight created will be removed after .5 sec"""
-         # associate a counter with an event; only disable the "paren"
-         # tag if the event is for the most recent timer.
-         self.counter += 1
--        self.editwin.text_frame.after(self.FLASH_DELAY,
--                                      lambda self=self, c=self.counter: \
--                                      self.handle_restore_timer(c))
-+        self.text.master.after(self.FLASH_DELAY,
-+            lambda self=self, c=self.counter: self.handle_restore_timer(c))
-Index: config-keys.def
-===================================================================
---- config-keys.def	(revision 63995)
-+++ config-keys.def	(revision 65541)
-@@ -8,6 +8,10 @@
- # configuration gui.
- 
- [IDLE Classic Windows]
-+close-tab=<Control-Key-w> <Control-Key-W>
-+new-tab=<Control-Key-t> <Control-Key-T>
-+next-tab=<Control-Key-Next>
-+prev-tab=<Control-Key-Prior>
- copy=<Control-Key-c> <Control-Key-C>
- cut=<Control-Key-x> <Control-Key-X>
- paste=<Control-Key-v> <Control-Key-V>
-@@ -59,6 +63,10 @@
- del-word-right=<Control-Key-Delete>
- 
- [IDLE Classic Unix]
-+close-tab=<Alt-Key-w><Control-Key-w>
-+new-tab=<Alt-Key-t><Control-Key-t>
-+next-tab=<Control-Key-Next>
-+prev-tab=<Control-Key-Prior>
- copy=<Alt-Key-w> <Meta-Key-w>
- cut=<Control-Key-w>
- paste=<Control-Key-y>
-@@ -110,6 +118,10 @@
- del-word-right=<Alt-Key-d>
- 
- [IDLE Classic Mac]
-+close-tab=<Control-key-w>
-+new-tab=<Control-Key-t>
-+next-tab=<Control-Key-Next>
-+prev-tab=<Control-Key-Prior>
- copy=<Command-Key-c>
- cut=<Command-Key-x>
- paste=<Command-Key-v>
-@@ -161,6 +173,10 @@
- del-word-right=<Control-Key-Delete>
- 
- [IDLE Classic OSX]
-+close-tab=<Control-Key-w>
-+new-tab = <Control-Key-t>
-+next-tab=<Control-Key-Next>
-+prev-tab=<Control-Key-Prior>
- toggle-tabs = <Control-Key-t>
- interrupt-execution = <Control-Key-c>
- untabify-region = <Control-Key-6>
-Index: Debugger.py
-===================================================================
---- Debugger.py	(revision 63995)
-+++ Debugger.py	(revision 65541)
-@@ -1,11 +1,17 @@
- import os
- import bdb
- import types
--from Tkinter import *
-+from Tkinter import Frame, Button, Entry, Checkbutton, Label, Scrollbar, \
-+                    Canvas, BooleanVar
-+from Tkconstants import W, LEFT, DISABLED, X, Y, BOTH, NW, GROOVE, RIGHT
-+
-+import macosxSupport
- from WindowList import ListedToplevel
- from ScrolledList import ScrolledList
--import macosxSupport
-+from configHandler import idleConf
- 
-+if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
-+    from ttk import Frame, Button, Checkbutton, Scrollbar
- 
- class Idb(bdb.Bdb):
- 
-@@ -92,7 +98,7 @@
-         self.top.bind("<Escape>", self.close)
-         #
-         self.bframe = bframe = Frame(top)
--        self.bframe.pack(anchor="w")
-+        self.bframe.pack(anchor=W)
-         self.buttons = bl = []
-         #
-         self.bcont = b = Button(bframe, text="Go", command=self.cont)
-@@ -107,11 +113,11 @@
-         bl.append(b)
-         #
-         for b in bl:
--            b.configure(state="disabled")
--            b.pack(side="left")
-+            b.configure(state=DISABLED)
-+            b.pack(side=LEFT)
-         #
-         self.cframe = cframe = Frame(bframe)
--        self.cframe.pack(side="left")
-+        self.cframe.pack(side=LEFT)
-         #
-         if not self.vstack:
-             self.__class__.vstack = BooleanVar(top)
-@@ -136,18 +142,18 @@
-             text="Globals", command=self.show_globals, variable=self.vglobals)
-         self.bglobals.grid(row=1, column=1)
-         #
--        self.status = Label(top, anchor="w")
--        self.status.pack(anchor="w")
--        self.error = Label(top, anchor="w")
--        self.error.pack(anchor="w", fill="x")
-+        self.status = Label(top, anchor=W)
-+        self.status.pack(anchor=W)
-+        self.error = Label(top, anchor=W)
-+        self.error.pack(anchor=W, fill=X)
-         self.errorbg = self.error.cget("background")
-         #
-         self.fstack = Frame(top, height=1)
--        self.fstack.pack(expand=1, fill="both")
-+        self.fstack.pack(expand=1, fill=BOTH)
-         self.flocals = Frame(top)
--        self.flocals.pack(expand=1, fill="both")
-+        self.flocals.pack(expand=1, fill=BOTH)
-         self.fglobals = Frame(top, height=1)
--        self.fglobals.pack(expand=1, fill="both")
-+        self.fglobals.pack(expand=1, fill=BOTH)
-         #
-         if self.vstack.get():
-             self.show_stack()
-@@ -155,6 +161,7 @@
-             self.show_locals()
-         if self.vglobals.get():
-             self.show_globals()
-+        #
- 
-     def interaction(self, message, frame, info=None):
-         self.frame = frame
-@@ -313,12 +320,14 @@
-         "Load PyShellEditorWindow breakpoints into subprocess debugger"
-         pyshell_edit_windows = self.pyshell.flist.inversedict.keys()
-         for editwin in pyshell_edit_windows:
--            filename = editwin.io.filename
--            try:
--                for lineno in editwin.breakpoints:
--                    self.set_breakpoint_here(filename, lineno)
--            except AttributeError:
--                continue
-+            for page in editwin.text_notebook.pages.itervalues():
-+                editpage = page.editpage
-+                filename = editpage.io.filename
-+                try:
-+                    for lineno in editpage.breakpoints:
-+                        self.set_breakpoint_here(filename, lineno)
-+                except AttributeError:
-+                    continue
- 
- class StackViewer(ScrolledList):
- 
-@@ -348,8 +357,7 @@
-             funcname = code.co_name
-             import linecache
-             sourceline = linecache.getline(filename, lineno)
--            import string
--            sourceline = string.strip(sourceline)
-+            sourceline = sourceline.strip()
-             if funcname in ("?", "", None):
-                 item = "%s, line %d: %s" % (modname, lineno, sourceline)
-             else:
-@@ -413,24 +421,25 @@
-             height = 20*len(dict) # XXX 20 == observed height of Entry widget
-         self.master = master
-         self.title = title
-+
-         import repr
-         self.repr = repr.Repr()
-         self.repr.maxstring = 60
-         self.repr.maxother = 60
-         self.frame = frame = Frame(master)
--        self.frame.pack(expand=1, fill="both")
--        self.label = Label(frame, text=title, borderwidth=2, relief="groove")
--        self.label.pack(fill="x")
--        self.vbar = vbar = Scrollbar(frame, name="vbar")
--        vbar.pack(side="right", fill="y")
-+        self.frame.pack(expand=1, fill=BOTH)
-+        self.label = Label(frame, text=title, borderwidth=2, relief=GROOVE)
-+        self.label.pack(fill=X)
-+        vbar = Scrollbar(frame, name="vbar")
-+        vbar.pack(side=RIGHT, fill=Y)
-         self.canvas = canvas = Canvas(frame,
-                                       height=min(300, max(40, height)),
-                                       scrollregion=(0, 0, width, height))
--        canvas.pack(side="left", fill="both", expand=1)
-+        canvas.pack(side=LEFT, fill=BOTH, expand=1)
-         vbar["command"] = canvas.yview
-         canvas["yscrollcommand"] = vbar.set
-         self.subframe = subframe = Frame(canvas)
--        self.sfid = canvas.create_window(0, 0, window=subframe, anchor="nw")
-+        self.sfid = canvas.create_window(0, 0, window=subframe, anchor=NW)
-         self.load_dict(dict)
- 
-     dict = -1
-@@ -458,10 +467,10 @@
-                 if rpc_client:
-                     svalue = svalue[1:-1]
-                 l = Label(subframe, text=name)
--                l.grid(row=row, column=0, sticky="nw")
-+                l.grid(row=row, column=0, sticky=NW)
-                 l = Entry(subframe, width=0, borderwidth=0)
-                 l.insert(0, svalue)
--                l.grid(row=row, column=1, sticky="nw")
-+                l.grid(row=row, column=1, sticky=NW)
-                 row = row+1
-         self.dict = dict
-         # XXX Could we use a <Configure> callback for the following?
-Index: configDialog.py
-===================================================================
---- configDialog.py	(revision 63995)
-+++ configDialog.py	(revision 65541)
-@@ -7,19 +7,30 @@
- 
- Note that tab width in IDLE is currently fixed at eight due to Tk issues.
- Refer to comments in EditorWindow autoindent code for details.
--
- """
--from Tkinter import *
-+from Tkinter import Toplevel, Frame, Button, Scale, Label, LabelFrame, Text, \
-+                    Listbox, Scrollbar, Checkbutton, Radiobutton, Entry, \
-+                    Checkbutton, StringVar, BooleanVar, IntVar
-+from Tkconstants import LEFT, RIGHT, BOTTOM, TOP, BOTH, GROOVE, SOLID, NONE, \
-+                        END, DISABLED, NSEW, Y, X, W, E, HORIZONTAL, NS, EW, \
-+                        N, ANCHOR, NORMAL
- import tkMessageBox, tkColorChooser, tkFont
--import string
- 
-+from stylist import PoorManStyle
-+from tabbedpages import get_tabbedpage
- from configHandler import idleConf
-+from keybindingDialog import GetKeysDialog
- from dynOptionMenuWidget import DynOptionMenu
--from tabbedpages import TabbedPageSet
--from keybindingDialog import GetKeysDialog
-+from configHelpSourceEdit import GetHelpSourceDialog
- from configSectionNameDialog import GetCfgSectionNameDialog
--from configHelpSourceEdit import GetHelpSourceDialog
- 
-+TabbedPageSet = get_tabbedpage()
-+TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
-+if TTK:
-+    from ttk import Frame, Button, Checkbutton, LabelFrame, LabeledScale, \
-+                    Combobox, Checkbutton, Entry, Radiobutton, Scrollbar, \
-+                    Label, Style
-+
- class ConfigDialog(Toplevel):
- 
-     def __init__(self,parent,title):
-@@ -27,8 +38,8 @@
-         self.wm_withdraw()
- 
-         self.configure(borderwidth=5)
--        self.geometry("+%d+%d" % (parent.winfo_rootx()+20,
--                parent.winfo_rooty()+30))
-+        self.geometry("+%d+%d" % (parent.winfo_rootx() + 20,
-+            parent.winfo_rooty() + 30))
-         #Theme Elements. Each theme element key is its display name.
-         #The first value of the tuple is the sample area tag name.
-         #The second value is the display name list sort index.
-@@ -47,8 +58,9 @@
-             'Shell Stderr Text':('stderr','12'),
-             }
-         self.ResetChangedItems() #load initial values in changed items dict
-+        self.SetupStyles()
-         self.CreateWidgets()
--        self.resizable(height=FALSE,width=FALSE)
-+        self.resizable(height=False, width=False)
-         self.transient(parent)
-         self.grab_set()
-         self.protocol("WM_DELETE_WINDOW", self.Cancel)
-@@ -64,34 +76,54 @@
-         self.wm_deiconify()
-         self.wait_window()
- 
-+    def SetupStyles(self):
-+        if TTK:
-+            style = Style(self.master)
-+            style.configure('S.TButton', padding=[6, 3])
-+            style.configure('S2.TFrame', padding=2)
-+            style.configure('Color.TFrame', background='blue')
-+            self.ttkstyle = style
-+            self.style = lambda w, style: w.configure(style=style)
-+        else:
-+            self.ttkstyle = PoorManStyle(self, styles={
-+                'S.TButton': {'pady': 6, 'padx': 3},
-+                'S2.TFrame': {'padx': 2, 'pady': 2}
-+                }, cfgstyles={'Color.TFrame': 'frameColourSet'})
-+            self.style = self.ttkstyle.style_it
-+
-     def CreateWidgets(self):
-         self.tabPages = TabbedPageSet(self,
--                page_names=['Fonts/Tabs','Highlighting','Keys','General'])
--        frameActionButtons = Frame(self,pady=2)
-+            page_names=['Fonts/Tabs','Highlighting','Keys','General'])
-+        frameActionButtons = Frame(self)
-         #action buttons
-         self.buttonHelp = Button(frameActionButtons,text='Help',
--                command=self.Help,takefocus=FALSE,
--                padx=6,pady=3)
--        self.buttonOk = Button(frameActionButtons,text='Ok',
--                command=self.Ok,takefocus=FALSE,
--                padx=6,pady=3)
--        self.buttonApply = Button(frameActionButtons,text='Apply',
--                command=self.Apply,takefocus=FALSE,
--                padx=6,pady=3)
--        self.buttonCancel = Button(frameActionButtons,text='Cancel',
--                command=self.Cancel,takefocus=FALSE,
--                padx=6,pady=3)
-+                command=self.Help, takefocus=False)
-+        self.buttonOk = Button(frameActionButtons, text='Ok',
-+                command=self.Ok, takefocus=False)
-+        self.buttonApply = Button(frameActionButtons, text='Apply',
-+                command=self.Apply, takefocus=False)
-+        self.buttonCancel = Button(frameActionButtons, text='Cancel',
-+                command=self.Cancel, takefocus=False)
-+
-+        # Apply styles
-+        s = self.style
-+        s(frameActionButtons, 'RootColor.TFrame')
-+        s(self.buttonHelp, 'S.TButton')
-+        s(self.buttonOk, 'S.TButton')
-+        s(self.buttonApply, 'S.TButton')
-+        s(self.buttonCancel, 'S.TButton')
-+
-         self.CreatePageFontTab()
-         self.CreatePageHighlight()
-         self.CreatePageKeys()
-         self.CreatePageGeneral()
--        self.buttonHelp.pack(side=RIGHT,padx=5)
--        self.buttonOk.pack(side=LEFT,padx=5)
--        self.buttonApply.pack(side=LEFT,padx=5)
--        self.buttonCancel.pack(side=LEFT,padx=5)
--        frameActionButtons.pack(side=BOTTOM)
-+        self.buttonHelp.pack(side=LEFT, pady=6)
-+        self.buttonApply.pack(side=RIGHT, pady=6)
-+        self.buttonOk.pack(side=RIGHT, padx=6, pady=6)
-+        self.buttonCancel.pack(side=RIGHT, pady=6)
-+        frameActionButtons.pack(side=BOTTOM, fill=X, expand=True)
-         Frame(self, height=2, borderwidth=0).pack(side=BOTTOM)
--        self.tabPages.pack(side=TOP,expand=TRUE,fill=BOTH)
-+        self.tabPages.pack(side=TOP,expand=True,fill=BOTH)
- 
-     def CreatePageFontTab(self):
-         #tkVars
-@@ -113,8 +145,8 @@
-         frameFontParam=Frame(frameFont)
-         labelFontNameTitle=Label(frameFontName,justify=LEFT,
-                 text='Font Face :')
--        self.listFontName=Listbox(frameFontName,height=5,takefocus=FALSE,
--                exportselection=FALSE)
-+        self.listFontName=Listbox(frameFontName,height=5,takefocus=False,
-+                exportselection=False)
-         self.listFontName.bind('<ButtonRelease-1>',self.OnListFontButtonRelease)
-         scrollFont=Scrollbar(frameFontName)
-         scrollFont.config(command=self.listFontName.yview)
-@@ -127,122 +159,143 @@
-         frameFontSample=Frame(frameFont,relief=SOLID,borderwidth=1)
-         self.labelFontSample=Label(frameFontSample,
-                 text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]',
--                justify=LEFT,font=self.editFont)
-+                justify=LEFT, font=self.editFont)
-         #frameIndent
-         frameIndentSize=Frame(frameIndent)
-         labelSpaceNumTitle=Label(frameIndentSize, justify=LEFT,
-                                  text='Python Standard: 4 Spaces!')
--        self.scaleSpaceNum=Scale(frameIndentSize, variable=self.spaceNum,
--                                 orient='horizontal',
--                                 tickinterval=2, from_=2, to=16)
-         #widget packing
-         #body
--        frameFont.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH)
-+        frameFont.pack(side=LEFT,padx=5,pady=5,expand=True,fill=BOTH)
-         frameIndent.pack(side=LEFT,padx=5,pady=5,fill=Y)
-         #frameFont
-         frameFontName.pack(side=TOP,padx=5,pady=5,fill=X)
-         frameFontParam.pack(side=TOP,padx=5,pady=5,fill=X)
-         labelFontNameTitle.pack(side=TOP,anchor=W)
--        self.listFontName.pack(side=LEFT,expand=TRUE,fill=X)
-+        self.listFontName.pack(side=LEFT,expand=True,fill=X)
-         scrollFont.pack(side=LEFT,fill=Y)
-         labelFontSizeTitle.pack(side=LEFT,anchor=W)
-         self.optMenuFontSize.pack(side=LEFT,anchor=W)
-         checkFontBold.pack(side=LEFT,anchor=W,padx=20)
--        frameFontSample.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH)
--        self.labelFontSample.pack(expand=TRUE,fill=BOTH)
-+        frameFontSample.pack(side=TOP,padx=5,pady=5,expand=True,fill=BOTH)
-+        self.labelFontSample.pack(expand=1, fill=Y)
-         #frameIndent
-         frameIndentSize.pack(side=TOP,fill=X)
--        labelSpaceNumTitle.pack(side=TOP,anchor=W,padx=5)
--        self.scaleSpaceNum.pack(side=TOP,padx=5,fill=X)
-+        labelSpaceNumTitle.pack(side=TOP, anchor=W, padx=5, pady=6)
-+
-+        if TTK:
-+            self.scaleSpaceNum = LabeledScale(frameIndentSize, self.spaceNum,
-+                from_=2, to=16, padding=2)
-+        else:
-+            self.scaleSpaceNum=Scale(frameIndentSize, variable=self.spaceNum,
-+                orient='horizontal', from_=2, to=16, tickinterval=2)
-+
-+        self.scaleSpaceNum.pack(side=TOP, padx=5, fill=X)
-+
-         return frame
- 
-     def CreatePageHighlight(self):
--        self.builtinTheme=StringVar(self)
--        self.customTheme=StringVar(self)
--        self.fgHilite=BooleanVar(self)
--        self.colour=StringVar(self)
--        self.fontName=StringVar(self)
--        self.themeIsBuiltin=BooleanVar(self)
--        self.highlightTarget=StringVar(self)
-+        self.builtinTheme = StringVar(self)
-+        self.customTheme = StringVar(self)
-+        self.fgHilite = BooleanVar(self)
-+        self.colour = StringVar(self)
-+        self.fontName = StringVar(self)
-+        self.themeIsBuiltin = BooleanVar(self)
-+        self.highlightTarget = StringVar(self)
-+        #self.themeFontBold = BooleanVar(self)
-         ##widget creation
-         #body frame
--        frame=self.tabPages.pages['Highlighting'].frame
-+        frame = self.tabPages.pages['Highlighting'].frame
-         #body section frames
--        frameCustom=LabelFrame(frame,borderwidth=2,relief=GROOVE,
--                               text=' Custom Highlighting ')
--        frameTheme=LabelFrame(frame,borderwidth=2,relief=GROOVE,
--                              text=' Highlighting Theme ')
-+        frameCustom = LabelFrame(frame, borderwidth=2, relief=GROOVE,
-+            text=' Custom Highlighting ')
-+        frameTheme = LabelFrame(frame, borderwidth=2, relief=GROOVE,
-+            text=' Highlighting Theme ')
-         #frameCustom
--        self.textHighlightSample=Text(frameCustom,relief=SOLID,borderwidth=1,
--            font=('courier',12,''),cursor='hand2',width=21,height=10,
--            takefocus=FALSE,highlightthickness=0,wrap=NONE)
--        text=self.textHighlightSample
--        text.bind('<Double-Button-1>',lambda e: 'break')
--        text.bind('<B1-Motion>',lambda e: 'break')
--        textAndTags=(('#you can click here','comment'),('\n','normal'),
--            ('#to choose items','comment'),('\n','normal'),('def','keyword'),
--            (' ','normal'),('func','definition'),('(param):','normal'),
--            ('\n  ','normal'),('"""string"""','string'),('\n  var0 = ','normal'),
--            ("'string'",'string'),('\n  var1 = ','normal'),("'selected'",'hilite'),
--            ('\n  var2 = ','normal'),("'found'",'hit'),
--            ('\n  var3 = ','normal'),('list', 'builtin'), ('(','normal'),
--            ('None', 'builtin'),(')\n\n','normal'),
--            (' error ','error'),(' ','normal'),('cursor |','cursor'),
--            ('\n ','normal'),('shell','console'),(' ','normal'),('stdout','stdout'),
--            (' ','normal'),('stderr','stderr'),('\n','normal'))
-+        self.textHighlightSample = Text(frameCustom, relief=SOLID,
-+            borderwidth=1, font=('courier', 12, ''), cursor='hand2', width=21,
-+            height=11, takefocus=False, highlightthickness=0, wrap=NONE)
-+        text = self.textHighlightSample
-+        text.bind('<Double-Button-1>', lambda e: 'break')
-+        text.bind('<B1-Motion>', lambda e: 'break')
-+        textAndTags = (
-+            ('#you can click here','comment'), ('\n','normal'),
-+            ('#to choose items', 'comment'), ('\n', 'normal'),
-+            ('def', 'keyword'), (' ', 'normal'), ('func', 'definition'),
-+            ('(param):', 'normal'), ('\n  ', 'normal'),
-+            ('"""string"""', 'string'),
-+            ('\n  var0 = ','normal'),  ("'string'", 'string'),
-+            ('\n  var1 = ', 'normal'), ("'selected'", 'hilite'),
-+            ('\n  var2 = ', 'normal'), ("'found'", 'hit'),
-+            ('\n  var3 = ', 'normal'), ('list', 'builtin'), ('(', 'normal'),
-+            ('None', 'builtin'), (')\n\n', 'normal'),
-+            (' error ', 'error'), (' ', 'normal'), ('cursor |', 'cursor'),
-+            ('\n ', 'normal'), ('shell', 'console'), (' ', 'normal'),
-+            ('stdout', 'stdout'), (' ', 'normal'), ('stderr', 'stderr'),
-+            ('\n', 'normal')
-+        )
-         for txTa in textAndTags:
--            text.insert(END,txTa[0],txTa[1])
-+            text.insert(END, txTa[0], txTa[1])
-         for element in self.themeElements.keys():
--            text.tag_bind(self.themeElements[element][0],'<ButtonPress-1>',
--                lambda event,elem=element: event.widget.winfo_toplevel()
--                .highlightTarget.set(elem))
-+            text.tag_bind(self.themeElements[element][0], '<ButtonPress-1>',
-+                lambda event, elem=element:
-+                    event.widget.winfo_toplevel().highlightTarget.set(elem))
-         text.config(state=DISABLED)
--        self.frameColourSet=Frame(frameCustom,relief=SOLID,borderwidth=1)
--        frameFgBg=Frame(frameCustom)
--        buttonSetColour=Button(self.frameColourSet,text='Choose Colour for :',
--            command=self.GetColour,highlightthickness=0)
--        self.optMenuHighlightTarget=DynOptionMenu(self.frameColourSet,
--            self.highlightTarget,None,highlightthickness=0)#,command=self.SetHighlightTargetBinding
--        self.radioFg=Radiobutton(frameFgBg,variable=self.fgHilite,
--            value=1,text='Foreground',command=self.SetColourSampleBinding)
--        self.radioBg=Radiobutton(frameFgBg,variable=self.fgHilite,
--            value=0,text='Background',command=self.SetColourSampleBinding)
-+
-+        self.frameColourSet = Frame(frameCustom, relief=SOLID, borderwidth=1)
-+        self.style(self.frameColourSet, 'Color.TFrame')
-+
-+        frameFgBg = Frame(frameCustom)
-+        buttonSetColour = Button(self.frameColourSet,
-+            text='Choose Colour for :', command=self.GetColour)
-+        self.optMenuHighlightTarget = DynOptionMenu(self.frameColourSet,
-+            self.highlightTarget, None)
-+        #self.optBoldText = Checkbutton(self.frameColourSet, text="Bold",
-+        #    variable=self.themeFontBold)
-+        self.radioFg = Radiobutton(frameFgBg, variable=self.fgHilite,
-+            value=1, text='Foreground', command=self.SetColourSampleBinding)
-+        self.radioBg = Radiobutton(frameFgBg, variable=self.fgHilite,
-+            value=0, text='Background', command=self.SetColourSampleBinding)
-         self.fgHilite.set(1)
--        buttonSaveCustomTheme=Button(frameCustom,
--            text='Save as New Custom Theme',command=self.SaveAsNewTheme)
-+        buttonSaveCustomTheme = Button(frameCustom,
-+            text='Save as New Custom Theme', command=self.SaveAsNewTheme)
-         #frameTheme
--        labelTypeTitle=Label(frameTheme,text='Select : ')
--        self.radioThemeBuiltin=Radiobutton(frameTheme,variable=self.themeIsBuiltin,
--            value=1,command=self.SetThemeType,text='a Built-in Theme')
--        self.radioThemeCustom=Radiobutton(frameTheme,variable=self.themeIsBuiltin,
--            value=0,command=self.SetThemeType,text='a Custom Theme')
--        self.optMenuThemeBuiltin=DynOptionMenu(frameTheme,
--            self.builtinTheme,None,command=None)
--        self.optMenuThemeCustom=DynOptionMenu(frameTheme,
--            self.customTheme,None,command=None)
--        self.buttonDeleteCustomTheme=Button(frameTheme,text='Delete Custom Theme',
--                command=self.DeleteCustomTheme)
-+        labelTypeTitle = Label(frameTheme, text='Select : ')
-+        self.radioThemeBuiltin = Radiobutton(frameTheme,
-+            variable=self.themeIsBuiltin, value=1,
-+            command=self.SetThemeType, text='a Built-in Theme')
-+        self.radioThemeCustom = Radiobutton(frameTheme,
-+            variable=self.themeIsBuiltin, value=0,
-+            command=self.SetThemeType, text='a Custom Theme')
-+        self.optMenuThemeBuiltin = DynOptionMenu(frameTheme,
-+            self.builtinTheme, None, command=None)
-+        self.optMenuThemeCustom = DynOptionMenu(frameTheme,
-+            self.customTheme, None, command=None)
-+        self.buttonDeleteCustomTheme = Button(frameTheme,
-+            text='Delete Custom Theme', command=self.DeleteCustomTheme)
-         ##widget packing
-         #body
--        frameCustom.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH)
--        frameTheme.pack(side=LEFT,padx=5,pady=5,fill=Y)
-+        frameCustom.pack(side=LEFT, padx=5, pady=5, expand=True, fill=BOTH)
-+        frameTheme.pack(side=LEFT, padx=5, pady=5, fill=Y)
-         #frameCustom
--        self.frameColourSet.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=X)
--        frameFgBg.pack(side=TOP,padx=5,pady=0)
--        self.textHighlightSample.pack(side=TOP,padx=5,pady=5,expand=TRUE,
-+        self.frameColourSet.pack(side=TOP, padx=5, pady=5, expand=True, fill=X)
-+        frameFgBg.pack(side=TOP, padx=5, pady=0)
-+        self.textHighlightSample.pack(side=TOP, padx=5, pady=5, expand=True,
-             fill=BOTH)
--        buttonSetColour.pack(side=TOP,expand=TRUE,fill=X,padx=8,pady=4)
--        self.optMenuHighlightTarget.pack(side=TOP,expand=TRUE,fill=X,padx=8,pady=3)
--        self.radioFg.pack(side=LEFT,anchor=E)
--        self.radioBg.pack(side=RIGHT,anchor=W)
--        buttonSaveCustomTheme.pack(side=BOTTOM,fill=X,padx=5,pady=5)
-+        buttonSetColour.pack(side=TOP, expand=True, fill=X, padx=8, pady=4)
-+        self.optMenuHighlightTarget.pack(side=LEFT, anchor=N, expand=True,
-+            fill=X, padx=8, pady=3)
-+        #self.optBoldText.pack(side=RIGHT, anchor=N, padx=8, pady=3)
-+        self.radioFg.pack(side=LEFT, anchor=E)
-+        self.radioBg.pack(side=RIGHT, anchor=W)
-+        buttonSaveCustomTheme.pack(side=BOTTOM, fill=X, padx=5, pady=5)
-         #frameTheme
--        labelTypeTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
--        self.radioThemeBuiltin.pack(side=TOP,anchor=W,padx=5)
--        self.radioThemeCustom.pack(side=TOP,anchor=W,padx=5,pady=2)
--        self.optMenuThemeBuiltin.pack(side=TOP,fill=X,padx=5,pady=5)
--        self.optMenuThemeCustom.pack(side=TOP,fill=X,anchor=W,padx=5,pady=5)
--        self.buttonDeleteCustomTheme.pack(side=TOP,fill=X,padx=5,pady=5)
-+        labelTypeTitle.pack(side=TOP, anchor=W, padx=5, pady=5)
-+        self.radioThemeBuiltin.pack(side=TOP, anchor=W, padx=5)
-+        self.radioThemeCustom.pack(side=TOP, anchor=W, padx=5, pady=2)
-+        self.optMenuThemeBuiltin.pack(side=TOP, fill=X, padx=5, pady=5)
-+        self.optMenuThemeCustom.pack(side=TOP, fill=X, anchor=W, padx=5, pady=5)
-+        self.buttonDeleteCustomTheme.pack(side=TOP, fill=X, padx=5, pady=5)
-         return frame
- 
-     def CreatePageKeys(self):
-@@ -265,8 +318,8 @@
-         labelTargetTitle=Label(frameTarget,text='Action - Key(s)')
-         scrollTargetY=Scrollbar(frameTarget)
-         scrollTargetX=Scrollbar(frameTarget,orient=HORIZONTAL)
--        self.listBindings=Listbox(frameTarget,takefocus=FALSE,
--                exportselection=FALSE)
-+        self.listBindings=Listbox(frameTarget,takefocus=False,
-+                exportselection=False)
-         self.listBindings.bind('<ButtonRelease-1>',self.KeyBindingSelected)
-         scrollTargetY.config(command=self.listBindings.yview)
-         scrollTargetX.config(command=self.listBindings.xview)
-@@ -275,8 +328,11 @@
-         self.buttonNewKeys=Button(frameCustom,text='Get New Keys for Selection',
-             command=self.GetNewKeys,state=DISABLED)
-         #frameKeySets
--        frames = [Frame(frameKeySets, padx=2, pady=2, borderwidth=0)
--                  for i in range(2)]
-+        frames = []
-+        for i in range(2):
-+            f = Frame(frameKeySets, borderwidth=0)
-+            self.style(f, 'S2.TFrame')
-+            frames.append(f)
-         self.radioKeysBuiltin=Radiobutton(frames[0],variable=self.keysAreBuiltin,
-             value=1,command=self.SetKeysType,text='Use a Built-in Key Set')
-         self.radioKeysCustom=Radiobutton(frames[0],variable=self.keysAreBuiltin,
-@@ -291,11 +347,11 @@
-                 text='Save as New Custom Key Set',command=self.SaveAsNewKeySet)
-         ##widget packing
-         #body
--        frameCustom.pack(side=BOTTOM,padx=5,pady=5,expand=TRUE,fill=BOTH)
-+        frameCustom.pack(side=BOTTOM,padx=5,pady=5,expand=True,fill=BOTH)
-         frameKeySets.pack(side=BOTTOM,padx=5,pady=5,fill=BOTH)
-         #frameCustom
-         self.buttonNewKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5)
--        frameTarget.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH)
-+        frameTarget.pack(side=LEFT,padx=5,pady=5,expand=True,fill=BOTH)
-         #frame target
-         frameTarget.columnconfigure(0,weight=1)
-         frameTarget.rowconfigure(1,weight=1)
-@@ -316,14 +372,16 @@
- 
-     def CreatePageGeneral(self):
-         #tkVars
--        self.winWidth=StringVar(self)
--        self.winHeight=StringVar(self)
--        self.paraWidth=StringVar(self)
--        self.startupEdit=IntVar(self)
--        self.autoSave=IntVar(self)
--        self.encoding=StringVar(self)
--        self.userHelpBrowser=BooleanVar(self)
--        self.helpBrowser=StringVar(self)
-+        self.winWidth = StringVar(self)
-+        self.winHeight = StringVar(self)
-+        self.paraWidth = StringVar(self)
-+        self.startupEdit = IntVar(self)
-+        self.autoSave = IntVar(self)
-+        self.encoding = StringVar(self)
-+        self.themename = StringVar(self)
-+        self.fileintab = BooleanVar(self)
-+        self.userHelpBrowser = BooleanVar(self)
-+        self.helpBrowser = StringVar(self)
-         #widget creation
-         #body
-         frame=self.tabPages.pages['General'].frame
-@@ -335,6 +393,9 @@
-         frameWinSize=Frame(frame,borderwidth=2,relief=GROOVE)
-         frameParaSize=Frame(frame,borderwidth=2,relief=GROOVE)
-         frameEncoding=Frame(frame,borderwidth=2,relief=GROOVE)
-+        frameModTab = Frame(frame, borderwidth=2, relief=GROOVE)
-+        if TTK:
-+            frameTheme = Frame(frame, borderwidth=2, relief=GROOVE)
-         frameHelp=LabelFrame(frame,borderwidth=2,relief=GROOVE,
-                              text=' Additional Help Sources ')
-         #frameRun
-@@ -371,12 +432,21 @@
-             value="utf-8",text="UTF-8")
-         radioEncNone=Radiobutton(frameEncoding,variable=self.encoding,
-             value="none",text="None")
-+        # frameModTab
-+        labelMTab = Label(frameModTab, text="Open files and modules in tabs")
-+        checkMTab = Checkbutton(frameModTab, variable=self.fileintab,
-+            text="Yes")
-+        #frameTheme
-+        if TTK:
-+            labelTheme = Label(frameTheme, text="Display Theme")
-+            comboTheme = Combobox(frameTheme, textvariable=self.themename,
-+                values=self.ttkstyle.theme_names(), state='readonly')
-         #frameHelp
-         frameHelpList=Frame(frameHelp)
-         frameHelpListButtons=Frame(frameHelpList)
-         scrollHelpList=Scrollbar(frameHelpList)
--        self.listHelp=Listbox(frameHelpList,height=5,takefocus=FALSE,
--                exportselection=FALSE)
-+        self.listHelp=Listbox(frameHelpList, height=4, takefocus=False,
-+                exportselection=False)
-         scrollHelpList.config(command=self.listHelp.yview)
-         self.listHelp.config(yscrollcommand=scrollHelpList.set)
-         self.listHelp.bind('<ButtonRelease-1>',self.HelpSourceSelected)
-@@ -393,7 +463,10 @@
-         frameWinSize.pack(side=TOP,padx=5,pady=5,fill=X)
-         frameParaSize.pack(side=TOP,padx=5,pady=5,fill=X)
-         frameEncoding.pack(side=TOP,padx=5,pady=5,fill=X)
--        frameHelp.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH)
-+        frameModTab.pack(side=TOP, padx=5, pady=5, fill=X)
-+        if TTK:
-+            frameTheme.pack(side=TOP, padx=5, pady=5, fill=X)
-+        frameHelp.pack(side=TOP,padx=5,pady=5,expand=True,fill=BOTH)
-         #frameRun
-         labelRunChoiceTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
-         radioStartupShell.pack(side=RIGHT,anchor=W,padx=5,pady=5)
-@@ -416,14 +489,22 @@
-         radioEncNone.pack(side=RIGHT,anchor=E,pady=5)
-         radioEncUTF8.pack(side=RIGHT,anchor=E,pady=5)
-         radioEncLocale.pack(side=RIGHT,anchor=E,pady=5)
-+        #frameModTab
-+        labelMTab.pack(side=LEFT, anchor=W, padx=5, pady=5)
-+        checkMTab.pack(side=RIGHT, anchor=E, padx=5, pady=5)
-+        #frameTheme
-+        if TTK:
-+            labelTheme.pack(side=LEFT, anchor=W, padx=5, pady=5)
-+            comboTheme.pack(side=RIGHT, anchor=E, padx=5, pady=5)
-         #frameHelp
-         frameHelpListButtons.pack(side=RIGHT,padx=5,pady=5,fill=Y)
--        frameHelpList.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH)
-+        frameHelpList.pack(side=TOP,padx=5,pady=5,expand=True,fill=BOTH)
-         scrollHelpList.pack(side=RIGHT,anchor=W,fill=Y)
--        self.listHelp.pack(side=LEFT,anchor=E,expand=TRUE,fill=BOTH)
-+        self.listHelp.pack(side=LEFT,anchor=E,expand=True,fill=BOTH)
-         self.buttonHelpListEdit.pack(side=TOP,anchor=W,pady=5)
-         self.buttonHelpListAdd.pack(side=TOP,anchor=W)
-         self.buttonHelpListRemove.pack(side=TOP,anchor=W,pady=5)
-+
-         return frame
- 
-     def AttachVarCallbacks(self):
-@@ -432,6 +513,7 @@
-         self.fontBold.trace_variable('w',self.VarChanged_fontBold)
-         self.spaceNum.trace_variable('w',self.VarChanged_spaceNum)
-         self.colour.trace_variable('w',self.VarChanged_colour)
-+        #self.themeFontBold.trace_variable('w', self.VarChanged_themeFontBold)
-         self.builtinTheme.trace_variable('w',self.VarChanged_builtinTheme)
-         self.customTheme.trace_variable('w',self.VarChanged_customTheme)
-         self.themeIsBuiltin.trace_variable('w',self.VarChanged_themeIsBuiltin)
-@@ -446,18 +528,20 @@
-         self.startupEdit.trace_variable('w',self.VarChanged_startupEdit)
-         self.autoSave.trace_variable('w',self.VarChanged_autoSave)
-         self.encoding.trace_variable('w',self.VarChanged_encoding)
-+        self.themename.trace_variable('w', self.VarChanged_themename)
-+        self.fileintab.trace_variable('w', self.VarChanged_fileintab)
- 
-     def VarChanged_fontSize(self,*params):
-         value=self.fontSize.get()
--        self.AddChangedItem('main','EditorWindow','font-size',value)
-+        self.AddChangedItem('main','EditorPage','font-size',value)
- 
-     def VarChanged_fontName(self,*params):
-         value=self.fontName.get()
--        self.AddChangedItem('main','EditorWindow','font',value)
-+        self.AddChangedItem('main','EditorPage','font',value)
- 
-     def VarChanged_fontBold(self,*params):
-         value=self.fontBold.get()
--        self.AddChangedItem('main','EditorWindow','font-bold',value)
-+        self.AddChangedItem('main','EditorPage','font-bold',value)
- 
-     def VarChanged_spaceNum(self,*params):
-         value=self.spaceNum.get()
-@@ -466,6 +550,9 @@
-     def VarChanged_colour(self,*params):
-         self.OnNewColourSet()
- 
-+    #def VarChanged_themeFontBold(self, *params):
-+    #    self.OnBoldChanged()
-+
-     def VarChanged_builtinTheme(self,*params):
-         value=self.builtinTheme.get()
-         self.AddChangedItem('main','Theme','name',value)
-@@ -521,11 +608,11 @@
- 
-     def VarChanged_winWidth(self,*params):
-         value=self.winWidth.get()
--        self.AddChangedItem('main','EditorWindow','width',value)
-+        self.AddChangedItem('main', 'EditorWindow', 'width', value)
- 
-     def VarChanged_winHeight(self,*params):
-         value=self.winHeight.get()
--        self.AddChangedItem('main','EditorWindow','height',value)
-+        self.AddChangedItem('main', 'EditorWindow', 'height', value)
- 
-     def VarChanged_paraWidth(self,*params):
-         value=self.paraWidth.get()
-@@ -541,8 +628,16 @@
- 
-     def VarChanged_encoding(self,*params):
-         value=self.encoding.get()
--        self.AddChangedItem('main','EditorWindow','encoding',value)
-+        self.AddChangedItem('main','EditorPage','encoding',value)
- 
-+    def VarChanged_themename(self, *params):
-+        value = self.themename.get()
-+        self.AddChangedItem('main', 'Theme', 'displaytheme', value)
-+
-+    def VarChanged_fileintab(self, *params):
-+        value = self.fileintab.get()
-+        self.AddChangedItem('main', 'EditorWindow', 'file-in-tab', value)
-+
-     def ResetChangedItems(self):
-         #When any config item is changed in this dialog, an entry
-         #should be made in the relevant section (config type) of this
-@@ -552,10 +647,10 @@
-         self.changedItems={'main':{},'highlight':{},'keys':{},'extensions':{}}
- 
-     def AddChangedItem(self,type,section,item,value):
--        value=str(value) #make sure we use a string
-+        value = str(value) #make sure we use a string
-         if not self.changedItems[type].has_key(section):
--            self.changedItems[type][section]={}
--        self.changedItems[type][section][item]=value
-+            self.changedItems[type][section] = {}
-+        self.changedItems[type][section][item] = value
- 
-     def GetDefaultItems(self):
-         dItems={'main':{},'highlight':{},'keys':{},'extensions':{}}
-@@ -653,7 +748,7 @@
-         newKeys={}
-         for event in prevKeys.keys(): #add key set to changed items
-             eventName=event[2:-2] #trim off the angle brackets
--            binding=string.join(prevKeys[event])
-+            binding=' '.join(prevKeys[event])
-             newKeys[eventName]=binding
-         #handle any unsaved changes to prev key set
-         if prevKeySetName in self.changedItems['keys'].keys():
-@@ -680,7 +775,7 @@
-         bindNames.sort()
-         self.listBindings.delete(0,END)
-         for bindName in bindNames:
--            key=string.join(keySet[bindName]) #make key(s) into a string
-+            key=' '.join(keySet[bindName]) #make key(s) into a string
-             bindName=bindName[2:-2] #trim off the angle brackets
-             if keySetName in self.changedItems['keys'].keys():
-                 #handle any unsaved changes to this key set
-@@ -694,9 +789,9 @@
- 
-     def DeleteCustomKeys(self):
-         keySetName=self.customKeys.get()
--        if not tkMessageBox.askyesno('Delete Key Set','Are you sure you wish '+
--                                     'to delete the key set %r ?' % (keySetName),
--                                     parent=self):
-+        if not tkMessageBox.askyesno("Delete Key Set",
-+            "Are you sure you wish to delete the key set %r ?" % keySetName,
-+            parent=self):
-             return
-         #remove key set from config
-         idleConf.userCfg['keys'].remove_section(keySetName)
-@@ -705,25 +800,26 @@
-         #write changes
-         idleConf.userCfg['keys'].Save()
-         #reload user key set list
--        itemList=idleConf.GetSectionList('user','keys')
-+        itemList = idleConf.GetSectionList('user', 'keys')
-         itemList.sort()
-         if not itemList:
-             self.radioKeysCustom.config(state=DISABLED)
--            self.optMenuKeysCustom.SetMenu(itemList,'- no custom keys -')
-+            self.optMenuKeysCustom.SetMenu(itemList, "- no custom keys -")
-         else:
-             self.optMenuKeysCustom.SetMenu(itemList,itemList[0])
-         #revert to default key set
--        self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys','default'))
--        self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys','name'))
-+        self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys',
-+            'default'))
-+        self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys', 'name'))
-         #user can't back out of these changes, they must be applied now
-         self.Apply()
-         self.SetKeysType()
- 
-     def DeleteCustomTheme(self):
--        themeName=self.customTheme.get()
--        if not tkMessageBox.askyesno('Delete Theme','Are you sure you wish '+
--                                     'to delete the theme %r ?' % (themeName,),
--                                     parent=self):
-+        themeName = self.customTheme.get()
-+        if not tkMessageBox.askyesno("Delete Theme",
-+            "Are you sure you wish to delete the theme %r ?" % themeName,
-+            parent=self):
-             return
-         #remove theme from config
-         idleConf.userCfg['highlight'].remove_section(themeName)
-@@ -732,30 +828,31 @@
-         #write changes
-         idleConf.userCfg['highlight'].Save()
-         #reload user theme list
--        itemList=idleConf.GetSectionList('user','highlight')
-+        itemList = idleConf.GetSectionList('user', 'highlight')
-         itemList.sort()
-         if not itemList:
-             self.radioThemeCustom.config(state=DISABLED)
--            self.optMenuThemeCustom.SetMenu(itemList,'- no custom themes -')
-+            self.optMenuThemeCustom.SetMenu(itemList, "- no custom themes -")
-         else:
--            self.optMenuThemeCustom.SetMenu(itemList,itemList[0])
-+            self.optMenuThemeCustom.SetMenu(itemList, itemList[0])
-         #revert to default theme
--        self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme','default'))
--        self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme','name'))
-+        self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme',
-+            'default'))
-+        self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme', 'name'))
-         #user can't back out of these changes, they must be applied now
-         self.Apply()
-         self.SetThemeType()
- 
-     def GetColour(self):
-         target=self.highlightTarget.get()
--        prevColour=self.frameColourSet.cget('bg')
-+        prevColour = self.ttkstyle.configure('Color.TFrame', 'background')
-         rgbTuplet, colourString = tkColorChooser.askcolor(parent=self,
-             title='Pick new colour for : '+target,initialcolor=prevColour)
-         if colourString and (colourString!=prevColour):
-             #user didn't cancel, and they chose a new colour
-             if self.themeIsBuiltin.get(): #current theme is a built-in
--                message=('Your changes will be saved as a new Custom Theme. '+
--                        'Enter a name for your new Custom Theme below.')
-+                message=("Your changes will be saved as a new Custom Theme. "
-+                         "Enter a name for your new Custom Theme below.")
-                 newTheme=self.GetNewThemeName(message)
-                 if not newTheme: #user cancelled custom theme creation
-                     return
-@@ -767,16 +864,33 @@
- 
-     def OnNewColourSet(self):
-         newColour=self.colour.get()
--        self.frameColourSet.config(bg=newColour)#set sample
-+        self.ttkstyle.configure('Color.TFrame', background=newColour)
-         if self.fgHilite.get(): plane='foreground'
-         else: plane='background'
-         sampleElement=self.themeElements[self.highlightTarget.get()][0]
--        self.textHighlightSample.tag_config(sampleElement, **{plane:newColour})
-+        self.textHighlightSample.tag_config(sampleElement, **{plane: newColour})
-         theme=self.customTheme.get()
-         themeElement=sampleElement+'-'+plane
-         self.AddChangedItem('highlight',theme,themeElement,newColour)
- 
-+    #def OnBoldChanged(self):
-+    #    bold = self.themeFontBold.get() and tkFont.BOLD or tkFont.NORMAL
-+    #    sampleElement = self.themeElements[self.highlightTarget.get()][0]
-+
-+    #    #fontName = self.fontName.get()
-+    #    #self.textHighlightSample.tag_config(sampleElement,
-+    #    #    font=(fontName, self.fontSize.get(), bold))
-+
-+    #    self.textHighlightSample.tag_config(sampleElement,
-+    #        font=('courier', 12, bold))
-+
-+    #    theme = self.customTheme.get()
-+    #    themeElement = "%s-%s" % (sampleElement, 'bold')
-+    #    self.AddChangedItem('highlight', theme, themeElement,
-+    #        (bold == tkFont.BOLD) and 1 or 0)
-+
-     def GetNewThemeName(self,message):
-+        # XXX idle bug here
-         usedNames=(idleConf.GetSectionList('user','highlight')+
-                 idleConf.GetSectionList('default','highlight'))
-         newTheme=GetCfgSectionNameDialog(self,'New Custom Theme',
-@@ -835,37 +949,45 @@
-             self.radioFg.config(state=NORMAL)
-             self.radioBg.config(state=NORMAL)
-             self.fgHilite.set(1)
-+        #tag = self.themeElements[self.highlightTarget.get()][0]
-+        #font = self.textHighlightSample.tag_cget(tag, 'font')
-+        #if font:
-+        #    self.themeFontBold.set(font.split()[2] == tkFont.BOLD)
-+        #else:
-+        #    self.themeFontBold.set(0)
-         self.SetColourSample()
- 
-     def SetColourSampleBinding(self,*args):
-         self.SetColourSample()
- 
-     def SetColourSample(self):
--        #set the colour smaple area
--        tag=self.themeElements[self.highlightTarget.get()][0]
--        if self.fgHilite.get(): plane='foreground'
--        else: plane='background'
--        colour=self.textHighlightSample.tag_cget(tag,plane)
--        self.frameColourSet.config(bg=colour)
-+        # set the colour sample area
-+        tag = self.themeElements[self.highlightTarget.get()][0]
-+        if self.fgHilite.get():
-+            plane = 'foreground'
-+        else:
-+            plane = 'background'
-+        colour = self.textHighlightSample.tag_cget(tag, plane)
-+        self.ttkstyle.configure('Color.TFrame', background=colour)
- 
-     def PaintThemeSample(self):
-         if self.themeIsBuiltin.get(): #a default theme
--            theme=self.builtinTheme.get()
-+            theme = self.builtinTheme.get()
-         else: #a user theme
--            theme=self.customTheme.get()
-+            theme = self.customTheme.get()
-         for elementTitle in self.themeElements.keys():
--            element=self.themeElements[elementTitle][0]
--            colours=idleConf.GetHighlight(theme,element)
--            if element=='cursor': #cursor sample needs special painting
--                colours['background']=idleConf.GetHighlight(theme,
--                        'normal', fgBg='bg')
-+            element = self.themeElements[elementTitle][0]
-+            colours = idleConf.GetHighlight(theme, element)
-+            if element == 'cursor': #cursor sample needs special painting
-+                colours['background'] = idleConf.GetHighlight(theme,
-+                    'normal', fgBg='bg')
-             #handle any unsaved changes to this theme
-             if theme in self.changedItems['highlight'].keys():
--                themeDict=self.changedItems['highlight'][theme]
--                if themeDict.has_key(element+'-foreground'):
--                    colours['foreground']=themeDict[element+'-foreground']
--                if themeDict.has_key(element+'-background'):
--                    colours['background']=themeDict[element+'-background']
-+                themeDict = self.changedItems['highlight'][theme]
-+                if themeDict.has_key(element + '-foreground'):
-+                    colours['foreground'] = themeDict[element + '-foreground']
-+                if themeDict.has_key(element + '-background'):
-+                    colours['background'] = themeDict[element + '-background']
-             self.textHighlightSample.tag_config(element, **colours)
-         self.SetColourSample()
- 
-@@ -917,7 +1039,7 @@
-         self.changedItems['main']['HelpFiles'] = {}
-         for num in range(1,len(self.userHelpList)+1):
-             self.AddChangedItem('main','HelpFiles',str(num),
--                    string.join(self.userHelpList[num-1][:2],';'))
-+                ';'.join(self.userHelpList[num - 1][:2]))
- 
-     def LoadFontCfg(self):
-         ##base editor font selection list
-@@ -925,7 +1047,7 @@
-         fonts.sort()
-         for font in fonts:
-             self.listFontName.insert(END,font)
--        configuredFont=idleConf.GetOption('main','EditorWindow','font',
-+        configuredFont=idleConf.GetOption('main','EditorPage','font',
-                 default='courier')
-         lc_configuredFont = configuredFont.lower()
-         self.fontName.set(lc_configuredFont)
-@@ -936,13 +1058,13 @@
-             self.listFontName.select_set(currentFontIndex)
-             self.listFontName.select_anchor(currentFontIndex)
-         ##font size dropdown
--        fontSize=idleConf.GetOption('main','EditorWindow','font-size',
-+        fontSize=idleConf.GetOption('main', 'EditorPage', 'font-size',
-                 default='10')
-         self.optMenuFontSize.SetMenu(('7','8','9','10','11','12','13','14',
-                 '16','18','20','22'),fontSize )
-         ##fontWeight
--        self.fontBold.set(idleConf.GetOption('main','EditorWindow',
--                'font-bold',default=0,type='bool'))
-+        self.fontBold.set(idleConf.GetOption('main', 'EditorPage',
-+                'font-bold', default=0, type='bool'))
-         ##font sample
-         self.SetFontSample()
- 
-@@ -954,37 +1076,41 @@
- 
-     def LoadThemeCfg(self):
-         ##current theme type radiobutton
--        self.themeIsBuiltin.set(idleConf.GetOption('main','Theme','default',
--            type='bool',default=1))
-+        self.themeIsBuiltin.set(idleConf.GetOption('main', 'Theme', 'default',
-+            type='bool', default=1))
-         ##currently set theme
--        currentOption=idleConf.CurrentTheme()
-+        currentOption = idleConf.CurrentTheme()
-         ##load available theme option menus
-         if self.themeIsBuiltin.get(): #default theme selected
--            itemList=idleConf.GetSectionList('default','highlight')
-+            itemList = idleConf.GetSectionList('default', 'highlight')
-             itemList.sort()
--            self.optMenuThemeBuiltin.SetMenu(itemList,currentOption)
--            itemList=idleConf.GetSectionList('user','highlight')
-+            self.optMenuThemeBuiltin.SetMenu(itemList, currentOption)
-+            itemList = idleConf.GetSectionList('user', 'highlight')
-             itemList.sort()
-             if not itemList:
-                 self.radioThemeCustom.config(state=DISABLED)
--                self.customTheme.set('- no custom themes -')
-+                self.customTheme.set("- no custom themes -")
-             else:
-                 self.optMenuThemeCustom.SetMenu(itemList,itemList[0])
-         else: #user theme selected
--            itemList=idleConf.GetSectionList('user','highlight')
-+            itemList = idleConf.GetSectionList('user', 'highlight')
-             itemList.sort()
--            self.optMenuThemeCustom.SetMenu(itemList,currentOption)
--            itemList=idleConf.GetSectionList('default','highlight')
-+            self.optMenuThemeCustom.SetMenu(itemList, currentOption)
-+            itemList = idleConf.GetSectionList('default', 'highlight')
-             itemList.sort()
--            self.optMenuThemeBuiltin.SetMenu(itemList,itemList[0])
-+            self.optMenuThemeBuiltin.SetMenu(itemList, itemList[0])
-         self.SetThemeType()
-         ##load theme element option menu
--        themeNames=self.themeElements.keys()
-+        themeNames = self.themeElements.keys()
-         themeNames.sort(self.__ThemeNameIndexCompare)
--        self.optMenuHighlightTarget.SetMenu(themeNames,themeNames[0])
-+        self.optMenuHighlightTarget.SetMenu(themeNames, themeNames[0])
-         self.PaintThemeSample()
-         self.SetHighlightTarget()
- 
-+        if TTK:
-+            displaytheme = idleConf.GetOption('main', 'Theme', 'displaytheme')
-+            self.themename.set(displaytheme)
-+
-     def __ThemeNameIndexCompare(self,a,b):
-         if self.themeElements[a][1]<self.themeElements[b][1]: return -1
-         elif self.themeElements[a][1]==self.themeElements[b][1]: return 0
-@@ -1028,13 +1154,17 @@
-         self.autoSave.set(idleConf.GetOption('main', 'General', 'autosave',
-                                              default=0, type='bool'))
-         #initial window size
--        self.winWidth.set(idleConf.GetOption('main','EditorWindow','width'))
--        self.winHeight.set(idleConf.GetOption('main','EditorWindow','height'))
-+        self.winWidth.set(idleConf.GetOption('main', 'EditorWindow', 'width'))
-+        self.winHeight.set(idleConf.GetOption('main', 'EditorWindow', 'height'))
-         #initial paragraph reformat size
--        self.paraWidth.set(idleConf.GetOption('main','FormatParagraph','paragraph'))
-+        self.paraWidth.set(idleConf.GetOption('main','FormatParagraph',
-+            'paragraph'))
-         # default source encoding
--        self.encoding.set(idleConf.GetOption('main', 'EditorWindow',
--                                             'encoding', default='none'))
-+        self.encoding.set(idleConf.GetOption('main', 'EditorPage',
-+            'encoding', default='none'))
-+        # open files/modules in tabs
-+        self.fileintab.set(idleConf.GetOption('main', 'EditorWindow',
-+            'file-in-tab', default=1, type='bool'))
-         # additional help sources
-         self.userHelpList = idleConf.GetAllExtraHelpSourcesList()
-         for helpItem in self.userHelpList:
-@@ -1125,6 +1255,8 @@
-             instance.set_notabs_indentwidth()
-             instance.ApplyKeybindings()
-             instance.reset_help_menu_entries()
-+            if TTK:
-+                instance.set_theme(self.ttkstyle)
- 
-     def Cancel(self):
-         self.destroy()
-@@ -1142,6 +1274,7 @@
-         pass
- 
- if __name__ == '__main__':
-+    from Tkinter import Tk
-     #test the dialog
-     root=Tk()
-     Button(root,text='Dialog',
-Index: SearchEngine.py
-===================================================================
---- SearchEngine.py	(revision 63995)
-+++ SearchEngine.py	(revision 65541)
-@@ -1,5 +1,5 @@
- import re
--from Tkinter import *
-+from Tkinter import StringVar, BooleanVar, TclError
- import tkMessageBox
- 
- def get(root):
-Index: ReplaceDialog.py
-===================================================================
---- ReplaceDialog.py	(revision 63995)
-+++ ReplaceDialog.py	(revision 65541)
-@@ -1,4 +1,5 @@
--from Tkinter import *
-+from Tkinter import StringVar, TclError
-+
- import SearchEngine
- from SearchDialogBase import SearchDialogBase
- 
-@@ -11,9 +12,12 @@
-     dialog.open(text)
- 
- class ReplaceDialog(SearchDialogBase):
--
-     title = "Replace Dialog"
-     icon = "Replace"
-+    bottom_btns = [("Find", 'find_it'),
-+                   ("Replace", 'replace_it'),
-+                   ("Replace+Find", 'default_command', 1),
-+                   ("Replace All", 'replace_all')]
- 
-     def __init__(self, root, engine):
-         SearchDialogBase.__init__(self, root, engine)
-@@ -36,14 +40,10 @@
- 
-     def create_entries(self):
-         SearchDialogBase.create_entries(self)
--        self.replent = self.make_entry("Replace with:", self.replvar)
-+        self.replent = self.make_entry("Replace with", self.replvar)
- 
-     def create_command_buttons(self):
-         SearchDialogBase.create_command_buttons(self)
--        self.make_button("Find", self.find_it)
--        self.make_button("Replace", self.replace_it)
--        self.make_button("Replace+Find", self.default_command, 1)
--        self.make_button("Replace All", self.replace_all)
- 
-     def find_it(self, event=None):
-         self.do_find(0)
-Index: ScriptBinding.py
-===================================================================
---- ScriptBinding.py	(revision 63995)
-+++ ScriptBinding.py	(revision 65541)
-@@ -46,8 +46,9 @@
-                  ('Check Module', '<<check-module>>'),
-                  ('Run Module', '<<run-module>>'), ]), ]
- 
--    def __init__(self, editwin):
--        self.editwin = editwin
-+    def __init__(self, editpage):
-+        self.editpage = editpage
-+        self.editwin = editpage.editwin
-         # Provide instance variables referenced by Debugger
-         # XXX This should be done differently
-         self.flist = self.editwin.flist
-@@ -70,7 +71,7 @@
-             msgtxt, (lineno, start) = msg
-             self.editwin.gotoline(lineno)
-             self.errorbox("Tabnanny Tokenizing Error",
--                          "Token Error: %s" % msgtxt)
-+                "Token Error: %s" % msgtxt)
-             return False
-         except tabnanny.NannyNag, nag:
-             # The error messages from tabnanny are too confusing...
-@@ -91,7 +92,7 @@
-             source = re.sub(r"\r", "\n", source)
-         if source and source[-1] != '\n':
-             source = source + '\n'
--        text = self.editwin.text
-+        text = self.editpage.text
-         text.tag_remove("ERROR", "1.0", "end")
-         try:
-             try:
-@@ -113,7 +114,7 @@
-             shell.set_warning_stream(saved_stream)
- 
-     def colorize_syntax_error(self, msg, lineno, offset):
--        text = self.editwin.text
-+        text = self.editpage.text
-         pos = "0.0 + %d lines + %d chars" % (lineno-1, offset-1)
-         text.tag_add("ERROR", pos)
-         char = text.get(pos)
-@@ -175,20 +176,20 @@
- 
-         If the user has configured IDLE for Autosave, the file will be
-         silently saved if it already exists and is dirty.
--
-         """
--        filename = self.editwin.io.filename
--        if not self.editwin.get_saved():
-+        page = self.editpage
-+        filename = page.io.filename
-+        if not page.get_saved():
-             autosave = idleConf.GetOption('main', 'General',
-                                           'autosave', type='bool')
-             if autosave and filename:
--                self.editwin.io.save(None)
-+                page.io.save(None)
-             else:
-                 reply = self.ask_save_dialog()
--                self.editwin.text.focus_set()
-+                page.text.focus_set()
-                 if reply == "ok":
--                    self.editwin.io.save(None)
--                    filename = self.editwin.io.filename
-+                    page.io.save(None)
-+                    filename = page.io.filename
-                 else:
-                     filename = None
-         return filename
-@@ -196,14 +197,12 @@
-     def ask_save_dialog(self):
-         msg = "Source Must Be Saved\n" + 5*' ' + "OK to Save?"
-         mb = tkMessageBox.Message(title="Save Before Run or Check",
--                                  message=msg,
--                                  icon=tkMessageBox.QUESTION,
--                                  type=tkMessageBox.OKCANCEL,
--                                  default=tkMessageBox.OK,
--                                  master=self.editwin.text)
-+            message=msg, icon=tkMessageBox.QUESTION,
-+            type=tkMessageBox.OKCANCEL, default=tkMessageBox.OK,
-+            master=self.editpage.text)
-         return mb.show()
- 
-     def errorbox(self, title, message):
-         # XXX This should really be a function of EditorWindow...
--        tkMessageBox.showerror(title, message, master=self.editwin.text)
--        self.editwin.text.focus_set()
-+        tkMessageBox.showerror(title, message, master=self.editpage.text)
-+        self.editpage.text.focus_set()
-Index: tabbedpages.py
-===================================================================
---- tabbedpages.py	(revision 63995)
-+++ tabbedpages.py	(revision 65541)
-@@ -1,490 +1,12 @@
--"""An implementation of tabbed pages using only standard Tkinter.
--
--Originally developed for use in IDLE. Based on tabpage.py.
--
--Classes exported:
--TabbedPageSet -- A Tkinter implementation of a tabbed-page widget.
--TabSet -- A widget containing tabs (buttons) in one or more rows.
--
--"""
--from Tkinter import *
--
-+# Exceptions used on both versions of tabbedpages
- class InvalidNameError(Exception): pass
- class AlreadyExistsError(Exception): pass
- 
-+def get_tabbedpage():
-+    """Returns the TabbedPageSet available for use."""
-+    try:
-+        from tabbedpages_new import TabbedPageSet
-+    except ImportError:
-+        from tabbedpages_old import TabbedPageSet
- 
--class TabSet(Frame):
--    """A widget containing tabs (buttons) in one or more rows.
--
--    Only one tab may be selected at a time.
--
--    """
--    def __init__(self, page_set, select_command,
--                 tabs=None, n_rows=1, max_tabs_per_row=5,
--                 expand_tabs=False, **kw):
--        """Constructor arguments:
--
--        select_command -- A callable which will be called when a tab is
--        selected. It is called with the name of the selected tab as an
--        argument.
--
--        tabs -- A list of strings, the names of the tabs. Should be specified in
--        the desired tab order. The first tab will be the default and first
--        active tab. If tabs is None or empty, the TabSet will be initialized
--        empty.
--
--        n_rows -- Number of rows of tabs to be shown. If n_rows <= 0 or is
--        None, then the number of rows will be decided by TabSet. See
--        _arrange_tabs() for details.
--
--        max_tabs_per_row -- Used for deciding how many rows of tabs are needed,
--        when the number of rows is not constant. See _arrange_tabs() for
--        details.
--
--        """
--        Frame.__init__(self, page_set, **kw)
--        self.select_command = select_command
--        self.n_rows = n_rows
--        self.max_tabs_per_row = max_tabs_per_row
--        self.expand_tabs = expand_tabs
--        self.page_set = page_set
--
--        self._tabs = {}
--        self._tab2row = {}
--        if tabs:
--            self._tab_names = list(tabs)
--        else:
--            self._tab_names = []
--        self._selected_tab = None
--        self._tab_rows = []
--
--        self.padding_frame = Frame(self, height=2,
--                                   borderwidth=0, relief=FLAT,
--                                   background=self.cget('background'))
--        self.padding_frame.pack(side=TOP, fill=X, expand=False)
--
--        self._arrange_tabs()
--
--    def add_tab(self, tab_name):
--        """Add a new tab with the name given in tab_name."""
--        if not tab_name:
--            raise InvalidNameError("Invalid Tab name: '%s'" % tab_name)
--        if tab_name in self._tab_names:
--            raise AlreadyExistsError("Tab named '%s' already exists" %tab_name)
--
--        self._tab_names.append(tab_name)
--        self._arrange_tabs()
--
--    def remove_tab(self, tab_name):
--        """Remove the tab named <tab_name>"""
--        if not tab_name in self._tab_names:
--            raise KeyError("No such Tab: '%s" % page_name)
--
--        self._tab_names.remove(tab_name)
--        self._arrange_tabs()
--
--    def set_selected_tab(self, tab_name):
--        """Show the tab named <tab_name> as the selected one"""
--        if tab_name == self._selected_tab:
--            return
--        if tab_name is not None and tab_name not in self._tabs:
--            raise KeyError("No such Tab: '%s" % page_name)
--
--        # deselect the current selected tab
--        if self._selected_tab is not None:
--            self._tabs[self._selected_tab].set_normal()
--        self._selected_tab = None
--
--        if tab_name is not None:
--            # activate the tab named tab_name
--            self._selected_tab = tab_name
--            tab = self._tabs[tab_name]
--            tab.set_selected()
--            # move the tab row with the selected tab to the bottom
--            tab_row = self._tab2row[tab]
--            tab_row.pack_forget()
--            tab_row.pack(side=TOP, fill=X, expand=0)
--
--    def _add_tab_row(self, tab_names, expand_tabs):
--        if not tab_names:
--            return
--
--        tab_row = Frame(self)
--        tab_row.pack(side=TOP, fill=X, expand=0)
--        self._tab_rows.append(tab_row)
--
--        for tab_name in tab_names:
--            tab = TabSet.TabButton(tab_name, self.select_command,
--                                   tab_row, self)
--            if expand_tabs:
--                tab.pack(side=LEFT, fill=X, expand=True)
--            else:
--                tab.pack(side=LEFT)
--            self._tabs[tab_name] = tab
--            self._tab2row[tab] = tab_row
--
--        # tab is the last one created in the above loop
--        tab.is_last_in_row = True
--
--    def _reset_tab_rows(self):
--        while self._tab_rows:
--            tab_row = self._tab_rows.pop()
--            tab_row.destroy()
--        self._tab2row = {}
--
--    def _arrange_tabs(self):
--        """
--        Arrange the tabs in rows, in the order in which they were added.
--
--        If n_rows >= 1, this will be the number of rows used. Otherwise the
--        number of rows will be calculated according to the number of tabs and
--        max_tabs_per_row. In this case, the number of rows may change when
--        adding/removing tabs.
--
--        """
--        # remove all tabs and rows
--        for tab_name in self._tabs.keys():
--            self._tabs.pop(tab_name).destroy()
--        self._reset_tab_rows()
--
--        if not self._tab_names:
--            return
--
--        if self.n_rows is not None and self.n_rows > 0:
--            n_rows = self.n_rows
--        else:
--            # calculate the required number of rows
--            n_rows = (len(self._tab_names) - 1) // self.max_tabs_per_row + 1
--
--        # not expanding the tabs with more than one row is very ugly
--        expand_tabs = self.expand_tabs or n_rows > 1
--        i = 0 # index in self._tab_names
--        for row_index in xrange(n_rows):
--            # calculate required number of tabs in this row
--            n_tabs = (len(self._tab_names) - i - 1) // (n_rows - row_index) + 1
--            tab_names = self._tab_names[i:i + n_tabs]
--            i += n_tabs
--            self._add_tab_row(tab_names, expand_tabs)
--
--        # re-select selected tab so it is properly displayed
--        selected = self._selected_tab
--        self.set_selected_tab(None)
--        if selected in self._tab_names:
--            self.set_selected_tab(selected)
--
--    class TabButton(Frame):
--        """A simple tab-like widget."""
--
--        bw = 2 # borderwidth
--
--        def __init__(self, name, select_command, tab_row, tab_set):
--            """Constructor arguments:
--
--            name -- The tab's name, which will appear in its button.
--
--            select_command -- The command to be called upon selection of the
--            tab. It is called with the tab's name as an argument.
--
--            """
--            Frame.__init__(self, tab_row, borderwidth=self.bw, relief=RAISED)
--
--            self.name = name
--            self.select_command = select_command
--            self.tab_set = tab_set
--            self.is_last_in_row = False
--
--            self.button = Radiobutton(
--                self, text=name, command=self._select_event,
--                padx=5, pady=1, takefocus=FALSE, indicatoron=FALSE,
--                highlightthickness=0, selectcolor='', borderwidth=0)
--            self.button.pack(side=LEFT, fill=X, expand=True)
--
--            self._init_masks()
--            self.set_normal()
--
--        def _select_event(self, *args):
--            """Event handler for tab selection.
--
--            With TabbedPageSet, this calls TabbedPageSet.change_page, so that
--            selecting a tab changes the page.
--
--            Note that this does -not- call set_selected -- it will be called by
--            TabSet.set_selected_tab, which should be called when whatever the
--            tabs are related to changes.
--
--            """
--            self.select_command(self.name)
--            return
--
--        def set_selected(self):
--            """Assume selected look"""
--            self._place_masks(selected=True)
--
--        def set_normal(self):
--            """Assume normal look"""
--            self._place_masks(selected=False)
--
--        def _init_masks(self):
--            page_set = self.tab_set.page_set
--            background = page_set.pages_frame.cget('background')
--            # mask replaces the middle of the border with the background color
--            self.mask = Frame(page_set, borderwidth=0, relief=FLAT,
--                              background=background)
--            # mskl replaces the bottom-left corner of the border with a normal
--            # left border
--            self.mskl = Frame(page_set, borderwidth=0, relief=FLAT,
--                              background=background)
--            self.mskl.ml = Frame(self.mskl, borderwidth=self.bw,
--                                 relief=RAISED)
--            self.mskl.ml.place(x=0, y=-self.bw,
--                               width=2*self.bw, height=self.bw*4)
--            # mskr replaces the bottom-right corner of the border with a normal
--            # right border
--            self.mskr = Frame(page_set, borderwidth=0, relief=FLAT,
--                              background=background)
--            self.mskr.mr = Frame(self.mskr, borderwidth=self.bw,
--                                 relief=RAISED)
--
--        def _place_masks(self, selected=False):
--            height = self.bw
--            if selected:
--                height += self.bw
--
--            self.mask.place(in_=self,
--                            relx=0.0, x=0,
--                            rely=1.0, y=0,
--                            relwidth=1.0, width=0,
--                            relheight=0.0, height=height)
--
--            self.mskl.place(in_=self,
--                            relx=0.0, x=-self.bw,
--                            rely=1.0, y=0,
--                            relwidth=0.0, width=self.bw,
--                            relheight=0.0, height=height)
--
--            page_set = self.tab_set.page_set
--            if selected and ((not self.is_last_in_row) or
--                             (self.winfo_rootx() + self.winfo_width() <
--                              page_set.winfo_rootx() + page_set.winfo_width())
--                             ):
--                # for a selected tab, if its rightmost edge isn't on the
--                # rightmost edge of the page set, the right mask should be one
--                # borderwidth shorter (vertically)
--                height -= self.bw
--
--            self.mskr.place(in_=self,
--                            relx=1.0, x=0,
--                            rely=1.0, y=0,
--                            relwidth=0.0, width=self.bw,
--                            relheight=0.0, height=height)
--
--            self.mskr.mr.place(x=-self.bw, y=-self.bw,
--                               width=2*self.bw, height=height + self.bw*2)
--
--            # finally, lower the tab set so that all of the frames we just
--            # placed hide it
--            self.tab_set.lower()
--
--class TabbedPageSet(Frame):
--    """A Tkinter tabbed-pane widget.
--
--    Constains set of 'pages' (or 'panes') with tabs above for selecting which
--    page is displayed. Only one page will be displayed at a time.
--
--    Pages may be accessed through the 'pages' attribute, which is a dictionary
--    of pages, using the name given as the key. A page is an instance of a
--    subclass of Tk's Frame widget.
--
--    The page widgets will be created (and destroyed when required) by the
--    TabbedPageSet. Do not call the page's pack/place/grid/destroy methods.
--
--    Pages may be added or removed at any time using the add_page() and
--    remove_page() methods.
--
--    """
--    class Page(object):
--        """Abstract base class for TabbedPageSet's pages.
--
--        Subclasses must override the _show() and _hide() methods.
--
--        """
--        uses_grid = False
--
--        def __init__(self, page_set):
--            self.frame = Frame(page_set, borderwidth=2, relief=RAISED)
--
--        def _show(self):
--            raise NotImplementedError
--
--        def _hide(self):
--            raise NotImplementedError
--
--    class PageRemove(Page):
--        """Page class using the grid placement manager's "remove" mechanism."""
--        uses_grid = True
--
--        def _show(self):
--            self.frame.grid(row=0, column=0, sticky=NSEW)
--
--        def _hide(self):
--            self.frame.grid_remove()
--
--    class PageLift(Page):
--        """Page class using the grid placement manager's "lift" mechanism."""
--        uses_grid = True
--
--        def __init__(self, page_set):
--            super(TabbedPageSet.PageLift, self).__init__(page_set)
--            self.frame.grid(row=0, column=0, sticky=NSEW)
--            self.frame.lower()
--
--        def _show(self):
--            self.frame.lift()
--
--        def _hide(self):
--            self.frame.lower()
--
--    class PagePackForget(Page):
--        """Page class using the pack placement manager's "forget" mechanism."""
--        def _show(self):
--            self.frame.pack(fill=BOTH, expand=True)
--
--        def _hide(self):
--            self.frame.pack_forget()
--
--    def __init__(self, parent, page_names=None, page_class=PageLift,
--                 n_rows=1, max_tabs_per_row=5, expand_tabs=False,
--                 **kw):
--        """Constructor arguments:
--
--        page_names -- A list of strings, each will be the dictionary key to a
--        page's widget, and the name displayed on the page's tab. Should be
--        specified in the desired page order. The first page will be the default
--        and first active page. If page_names is None or empty, the
--        TabbedPageSet will be initialized empty.
--
--        n_rows, max_tabs_per_row -- Parameters for the TabSet which will
--        manage the tabs. See TabSet's docs for details.
--
--        page_class -- Pages can be shown/hidden using three mechanisms:
--
--        * PageLift - All pages will be rendered one on top of the other. When
--          a page is selected, it will be brought to the top, thus hiding all
--          other pages. Using this method, the TabbedPageSet will not be resized
--          when pages are switched. (It may still be resized when pages are
--          added/removed.)
--
--        * PageRemove - When a page is selected, the currently showing page is
--          hidden, and the new page shown in its place. Using this method, the
--          TabbedPageSet may resize when pages are changed.
--
--        * PagePackForget - This mechanism uses the pack placement manager.
--          When a page is shown it is packed, and when it is hidden it is
--          unpacked (i.e. pack_forget). This mechanism may also cause the
--          TabbedPageSet to resize when the page is changed.
--
--        """
--        Frame.__init__(self, parent, **kw)
--
--        self.page_class = page_class
--        self.pages = {}
--        self._pages_order = []
--        self._current_page = None
--        self._default_page = None
--
--        self.columnconfigure(0, weight=1)
--        self.rowconfigure(1, weight=1)
--
--        self.pages_frame = Frame(self)
--        self.pages_frame.grid(row=1, column=0, sticky=NSEW)
--        if self.page_class.uses_grid:
--            self.pages_frame.columnconfigure(0, weight=1)
--            self.pages_frame.rowconfigure(0, weight=1)
--
--        # the order of the following commands is important
--        self._tab_set = TabSet(self, self.change_page, n_rows=n_rows,
--                               max_tabs_per_row=max_tabs_per_row,
--                               expand_tabs=expand_tabs)
--        if page_names:
--            for name in page_names:
--                self.add_page(name)
--        self._tab_set.grid(row=0, column=0, sticky=NSEW)
--
--        self.change_page(self._default_page)
--
--    def add_page(self, page_name):
--        """Add a new page with the name given in page_name."""
--        if not page_name:
--            raise InvalidNameError("Invalid TabPage name: '%s'" % page_name)
--        if page_name in self.pages:
--            raise AlreadyExistsError(
--                "TabPage named '%s' already exists" % page_name)
--
--        self.pages[page_name] = self.page_class(self.pages_frame)
--        self._pages_order.append(page_name)
--        self._tab_set.add_tab(page_name)
--
--        if len(self.pages) == 1: # adding first page
--            self._default_page = page_name
--            self.change_page(page_name)
--
--    def remove_page(self, page_name):
--        """Destroy the page whose name is given in page_name."""
--        if not page_name in self.pages:
--            raise KeyError("No such TabPage: '%s" % page_name)
--
--        self._pages_order.remove(page_name)
--
--        # handle removing last remaining, default, or currently shown page
--        if len(self._pages_order) > 0:
--            if page_name == self._default_page:
--                # set a new default page
--                self._default_page = self._pages_order[0]
--        else:
--            self._default_page = None
--
--        if page_name == self._current_page:
--            self.change_page(self._default_page)
--
--        self._tab_set.remove_tab(page_name)
--        page = self.pages.pop(page_name)
--        page.frame.destroy()
--
--    def change_page(self, page_name):
--        """Show the page whose name is given in page_name."""
--        if self._current_page == page_name:
--            return
--        if page_name is not None and page_name not in self.pages:
--            raise KeyError("No such TabPage: '%s'" % page_name)
--
--        if self._current_page is not None:
--            self.pages[self._current_page]._hide()
--        self._current_page = None
--
--        if page_name is not None:
--            self._current_page = page_name
--            self.pages[page_name]._show()
--
--        self._tab_set.set_selected_tab(page_name)
--
--if __name__ == '__main__':
--    # test dialog
--    root=Tk()
--    tabPage=TabbedPageSet(root, page_names=['Foobar','Baz'], n_rows=0,
--                          expand_tabs=False,
--                          )
--    tabPage.pack(side=TOP, expand=TRUE, fill=BOTH)
--    Label(tabPage.pages['Foobar'].frame, text='Foo', pady=20).pack()
--    Label(tabPage.pages['Foobar'].frame, text='Bar', pady=20).pack()
--    Label(tabPage.pages['Baz'].frame, text='Baz').pack()
--    entryPgName=Entry(root)
--    buttonAdd=Button(root, text='Add Page',
--            command=lambda:tabPage.add_page(entryPgName.get()))
--    buttonRemove=Button(root, text='Remove Page',
--            command=lambda:tabPage.remove_page(entryPgName.get()))
--    labelPgName=Label(root, text='name of page to add/remove:')
--    buttonAdd.pack(padx=5, pady=5)
--    buttonRemove.pack(padx=5, pady=5)
--    labelPgName.pack(padx=5)
--    entryPgName.pack(padx=5)
--    root.mainloop()
-+    return TabbedPageSet
-Index: keybindingDialog.py
-===================================================================
---- keybindingDialog.py	(revision 63995)
-+++ keybindingDialog.py	(revision 65541)
-@@ -1,10 +1,18 @@
- """
- Dialog for building Tkinter accelerator key bindings
- """
--from Tkinter import *
-+from Tkinter import Toplevel, Frame, Entry, Button, Checkbutton, Label, \
-+                    Listbox, Scrollbar, StringVar
-+from Tkconstants import TOP, BOTH, BOTTOM, X, NSEW, SUNKEN, LEFT, GROOVE, W, \
-+                        END, EW, NS, SINGLE, VERTICAL, ANCHOR, MOVETO
- import tkMessageBox
- import string
- 
-+from idlelib.configHandler import idleConf
-+TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
-+if TTK:
-+    from ttk import Frame, Entry, Button, Checkbutton, Label, Scrollbar
-+
- class GetKeysDialog(Toplevel):
-     def __init__(self,parent,title,action,currentKeySequences):
-         """
-@@ -15,7 +23,7 @@
-         """
-         Toplevel.__init__(self, parent)
-         self.configure(borderwidth=5)
--        self.resizable(height=FALSE,width=FALSE)
-+        self.resizable(height=False, width=False)
-         self.title(title)
-         self.transient(parent)
-         self.grab_set()
-@@ -46,10 +54,10 @@
-         self.wait_window()
- 
-     def CreateWidgets(self):
--        frameMain = Frame(self,borderwidth=2,relief=SUNKEN)
--        frameMain.pack(side=TOP,expand=TRUE,fill=BOTH)
-+        frameMain = Frame(self, borderwidth=2, relief=SUNKEN)
-+        frameMain.pack(side=TOP, expand=True, fill=BOTH)
-         frameButtons=Frame(self)
--        frameButtons.pack(side=BOTTOM,fill=X)
-+        frameButtons.pack(side=BOTTOM, fill=X)
-         self.buttonOK = Button(frameButtons,text='OK',
-                 width=8,command=self.OK)
-         self.buttonOK.grid(row=0,column=0,padx=5,pady=5)
-@@ -124,6 +132,9 @@
-                  "separated by a space, eg., <Alt-v> <Meta-v>." )
-         labelHelpAdvanced.grid(row=0,column=0,sticky=NSEW)
- 
-+        if TTK:
-+            frameButtons['style'] = 'RootColor.TFrame'
-+
-     def SetModifiersForPlatform(self):
-         """Determine list of names of key modifiers for this platform.
- 
-@@ -163,7 +174,7 @@
-         if finalKey:
-             finalKey = self.TranslateKey(finalKey, modifiers)
-             keyList.append(finalKey)
--        self.keyString.set('<' + string.join(keyList,'-') + '>')
-+        self.keyString.set('<%s>' % '-'.join(keyList))
- 
-     def GetModifiers(self):
-         modList = [variable.get() for variable in self.modifier_vars]
-@@ -258,6 +269,7 @@
-         return keysOK
- 
- if __name__ == '__main__':
-+    from Tkinter import Tk
-     #test the dialog
-     root=Tk()
-     def run():
-Index: configHelpSourceEdit.py
-===================================================================
---- configHelpSourceEdit.py	(revision 63995)
-+++ configHelpSourceEdit.py	(revision 65541)
-@@ -1,12 +1,17 @@
- "Dialog to specify or edit the parameters for a user configured help source."
--
- import os
- import sys
--
--from Tkinter import *
-+from Tkinter import Toplevel, Frame, Entry, Button, Label, StringVar
-+from Tkconstants import GROOVE, LEFT, RIGHT, W, ACTIVE, X, BOTH, TOP, BOTTOM
- import tkMessageBox
- import tkFileDialog
- 
-+from configHandler import idleConf
-+
-+TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
-+if TTK:
-+    from ttk import Frame, Entry, Button, Label
-+
- class GetHelpSourceDialog(Toplevel):
-     def __init__(self, parent, title, menuItem='', filePath=''):
-         """Get menu entry and url/ local file location for Additional Help
-@@ -18,13 +23,14 @@
-         """
-         Toplevel.__init__(self, parent)
-         self.configure(borderwidth=5)
--        self.resizable(height=FALSE, width=FALSE)
-+        self.resizable(height=False, width=False)
-         self.title(title)
-         self.transient(parent)
-         self.grab_set()
-         self.protocol("WM_DELETE_WINDOW", self.Cancel)
-         self.parent = parent
-         self.result = None
-+
-         self.CreateWidgets()
-         self.menu.set(menuItem)
-         self.path.set(filePath)
-@@ -46,33 +52,36 @@
-         self.path = StringVar(self)
-         self.fontSize = StringVar(self)
-         self.frameMain = Frame(self, borderwidth=2, relief=GROOVE)
--        self.frameMain.pack(side=TOP, expand=TRUE, fill=BOTH)
-         labelMenu = Label(self.frameMain, anchor=W, justify=LEFT,
--                          text='Menu Item:')
--        self.entryMenu = Entry(self.frameMain, textvariable=self.menu,
--                               width=30)
--        self.entryMenu.focus_set()
-+            text='Menu Item:')
-+        self.entryMenu = Entry(self.frameMain, textvariable=self.menu)
-         labelPath = Label(self.frameMain, anchor=W, justify=LEFT,
--                          text='Help File Path: Enter URL or browse for file')
-+            text='Help File Path: Enter URL or browse for file')
-         self.entryPath = Entry(self.frameMain, textvariable=self.path,
--                               width=40)
-+            width=30)
-+        browseButton = Button(self.frameMain, text='Browse', width=8,
-+            command=self.browseFile)
-+        frameButtons = Frame(self)
-+        self.buttonOk = Button(frameButtons, text='OK', width=8,
-+            default=ACTIVE,  command=self.Ok)
-+        self.buttonCancel = Button(frameButtons, text='Cancel', width=8,
-+            command=self.Cancel)
-+
-         self.entryMenu.focus_set()
-+
-+        self.frameMain.pack(side=TOP, expand=True, fill=BOTH)
-         labelMenu.pack(anchor=W, padx=5, pady=3)
--        self.entryMenu.pack(anchor=W, padx=5, pady=3)
-+        self.entryMenu.pack(anchor=W, padx=5, pady=3, fill=X)
-         labelPath.pack(anchor=W, padx=5, pady=3)
--        self.entryPath.pack(anchor=W, padx=5, pady=3)
--        browseButton = Button(self.frameMain, text='Browse', width=8,
--                              command=self.browseFile)
--        browseButton.pack(pady=3)
--        frameButtons = Frame(self)
-+        self.entryPath.pack(anchor=W, padx=5, pady=3, side=LEFT, fill=X)
-+        browseButton.pack(pady=3, padx=5, side=RIGHT)
-         frameButtons.pack(side=BOTTOM, fill=X)
--        self.buttonOk = Button(frameButtons, text='OK',
--                               width=8, default=ACTIVE,  command=self.Ok)
--        self.buttonOk.grid(row=0, column=0, padx=5,pady=5)
--        self.buttonCancel = Button(frameButtons, text='Cancel',
--                                   width=8, command=self.Cancel)
--        self.buttonCancel.grid(row=0, column=1, padx=5, pady=5)
-+        self.buttonOk.pack(pady=5, side=RIGHT)
-+        self.buttonCancel.pack(padx=5, pady=5, side=RIGHT)
- 
-+        if TTK:
-+            frameButtons['style'] = 'RootColor.TFrame'
-+
-     def browseFile(self):
-         filetypes = [
-             ("HTML Files", "*.htm *.html", "TEXT"),
-@@ -159,6 +168,7 @@
-         self.destroy()
- 
- if __name__ == '__main__':
-+    from Tkinter import Tk
-     #test the dialog
-     root = Tk()
-     def run():
-Index: WidgetRedirector.py
-===================================================================
---- WidgetRedirector.py	(revision 63995)
-+++ WidgetRedirector.py	(revision 65541)
-@@ -1,4 +1,4 @@
--from Tkinter import *
-+from Tkinter import TclError
- 
- class WidgetRedirector:
- 
-@@ -105,6 +105,7 @@
- 
- 
- def main():
-+    from Tkinter import Tk, Text
-     root = Tk()
-     root.wm_protocol("WM_DELETE_WINDOW", root.quit)
-     text = Text()
-Index: GrepDialog.py
-===================================================================
---- GrepDialog.py	(revision 63995)
-+++ GrepDialog.py	(revision 65541)
-@@ -1,10 +1,15 @@
- import os
--import fnmatch
- import sys
--from Tkinter import *
-+import fnmatch
-+from Tkinter import StringVar, BooleanVar, Checkbutton
-+
- import SearchEngine
- from SearchDialogBase import SearchDialogBase
-+from configHandler import idleConf
- 
-+if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
-+    from ttk import Checkbutton
-+
- def grep(text, io=None, flist=None):
-     root = text._root()
-     engine = SearchEngine.get(root)
-@@ -15,10 +20,10 @@
-     dialog.open(text, searchphrase, io)
- 
- class GrepDialog(SearchDialogBase):
--
-     title = "Find in Files Dialog"
-     icon = "Grep"
-     needwrapbutton = 0
-+    bottom_btns = [("Search Files", 'default_command', 1)]
- 
-     def __init__(self, root, engine, flist):
-         SearchDialogBase.__init__(self, root, engine)
-@@ -40,20 +45,18 @@
- 
-     def create_entries(self):
-         SearchDialogBase.create_entries(self)
--        self.globent = self.make_entry("In files:", self.globvar)
-+        self.globent = self.make_entry("In files", self.globvar)
- 
-     def create_other_buttons(self):
-         f = self.make_frame()
- 
--        btn = Checkbutton(f, anchor="w",
--                variable=self.recvar,
-+        btn = Checkbutton(f, variable=self.recvar,
-                 text="Recurse down subdirectories")
-         btn.pack(side="top", fill="both")
--        btn.select()
-+        btn.invoke()
- 
-     def create_command_buttons(self):
-         SearchDialogBase.create_command_buttons(self)
--        self.make_button("Search Files", self.default_command, 1)
- 
-     def default_command(self, event=None):
-         prog = self.engine.getprog()
-@@ -126,8 +129,3 @@
-             for subdir in subdirs:
-                 list.extend(self.findfiles(subdir, base, rec))
-         return list
--
--    def close(self, event=None):
--        if self.top:
--            self.top.grab_release()
--            self.top.withdraw()
-Index: FormatParagraph.py
-===================================================================
---- FormatParagraph.py	(revision 63995)
-+++ FormatParagraph.py	(revision 65541)
-@@ -25,28 +25,30 @@
-          ])
-     ]
- 
--    def __init__(self, editwin):
--        self.editwin = editwin
-+    def __init__(self, editpage):
-+        self.editpage = editpage
- 
-     def close(self):
--        self.editwin = None
-+        self.editpage = None
- 
-     def format_paragraph_event(self, event):
--        maxformatwidth = int(idleConf.GetOption('main','FormatParagraph','paragraph'))
--        text = self.editwin.text
--        first, last = self.editwin.get_selection_indices()
-+        maxformatwidth = int(idleConf.GetOption('main', 'FormatParagraph',
-+            'paragraph'))
-+        text = self.editpage.text
-+        first, last = self.editpage.get_selection_indices()
-         if first and last:
-             data = text.get(first, last)
-             comment_header = ''
-         else:
--            first, last, comment_header, data = \
--                    find_paragraph(text, text.index("insert"))
-+            first, last, comment_header, data = find_paragraph(text,
-+                text.index("insert"))
-         if comment_header:
-             # Reformat the comment lines - convert to text sans header.
-             lines = data.split("\n")
-             lines = map(lambda st, l=len(comment_header): st[l:], lines)
-             data = "\n".join(lines)
--            # Reformat to maxformatwidth chars or a 20 char width, whichever is greater.
-+            # Reformat to maxformatwidth chars or a 20 char width, whichever is
-+            # greater.
-             format_width = max(maxformatwidth - len(comment_header), 20)
-             newdata = reformat_paragraph(data, format_width)
-             # re-split and re-insert the comment header.
-Index: EditorWindow.py
-===================================================================
---- EditorWindow.py	(revision 63995)
-+++ EditorWindow.py	(revision 65541)
-@@ -1,55 +1,54 @@
--import sys
- import os
- import re
--import imp
--from itertools import count
--from Tkinter import *
--import tkSimpleDialog
-+import sys
-+import traceback
-+import webbrowser
- import tkMessageBox
--from MultiCall import MultiCallCreator
-+import tkSimpleDialog
-+from Tkinter import Menu, Scrollbar, TclError, BooleanVar
-+from Tkconstants import INSERT, END, RIGHT, BOTTOM, TOP, X, Y, BOTH
- 
--import webbrowser
--import idlever
-+import macosxSupport
-+import Bindings
- import WindowList
--import SearchDialog
--import GrepDialog
--import ReplaceDialog
--import PyParse
-+from editorpage import EditorPage, classifyws, filename_to_unicode
-+from tabbedpages import get_tabbedpage
- from configHandler import idleConf
--import aboutDialog, textView, configDialog
--import macosxSupport
-+from MultiStatusBar import MultiStatusBar
- 
-+TabbedPageSet = get_tabbedpage()
-+
-+TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
-+if TTK:
-+    from ttk import Scrollbar
-+
- # The default tab setting for a Text widget, in average-width characters.
- TK_TABWIDTH_DEFAULT = 8
- 
--def _find_module(fullname, path=None):
--    """Version of imp.find_module() that handles hierarchical module names"""
--
--    file = None
--    for tgt in fullname.split('.'):
--        if file is not None:
--            file.close()            # close intermediate files
--        (file, filename, descr) = imp.find_module(tgt, path)
--        if descr[2] == imp.PY_SOURCE:
--            break                   # find but not load the source file
--        module = imp.load_module(tgt, file, filename, descr)
--        try:
--            path = module.__path__
--        except AttributeError:
--            raise ImportError, 'No source for module ' + module.__name__
--    return file, filename, descr
--
- class EditorWindow(object):
--    from Percolator import Percolator
--    from ColorDelegator import ColorDelegator
--    from UndoDelegator import UndoDelegator
--    from IOBinding import IOBinding, filesystemencoding, encoding
--    import Bindings
--    from Tkinter import Toplevel
--    from MultiStatusBar import MultiStatusBar
-+    from ColorDelegator import ColorDelegator # overridden by PyShell
-+    from UndoDelegator import UndoDelegator   # overridden by PyShell
- 
-     help_url = None
-+    rmenu = None
-+    rmenu_specs = [
-+        # ("Label", "<<virtual-event>>"), ...
-+        ("Close", "<<close-window>>"), # Example
-+    ]
-+    menu_specs = [
-+        ("file", "_File"),
-+        ("edit", "_Edit"),
-+        ("format", "F_ormat"),
-+        ("run", "_Run"),
-+        ("options", "_Options"),
-+        ("windows", "_Windows"),
-+        ("help", "_Help"),
-+    ]
- 
-+    if macosxSupport.runningAsOSXApp():
-+        del menu_specs[-3]
-+        menu_specs[-2] = ("windows", "_Window")
-+
-     def __init__(self, flist=None, filename=None, key=None, root=None):
-         if EditorWindow.help_url is None:
-             dochome =  os.path.join(sys.prefix, 'Doc', 'index.html')
-@@ -81,7 +80,7 @@
-                     EditorWindow.help_url = 'file://' + EditorWindow.help_url
-             else:
-                 EditorWindow.help_url = "http://www.python.org/doc/current"
--        currentTheme=idleConf.CurrentTheme()
-+
-         self.flist = flist
-         root = root or flist.root
-         self.root = root
-@@ -90,94 +89,45 @@
-         except AttributeError:
-             sys.ps1 = '>>> '
-         self.menubar = Menu(root)
--        self.top = top = WindowList.ListedToplevel(root, menu=self.menubar)
-+        self.top = WindowList.ListedToplevel(root, menu=self.menubar)
-         if flist:
-             self.tkinter_vars = flist.vars
--            #self.top.instance_dict makes flist.inversedict avalable to
--            #configDialog.py so it can access all EditorWindow instaces
-+            # self.top.instance_dict makes flist.inversedict avalable to
-+            # configDialog.py so it can access all EditorWindow instaces
-             self.top.instance_dict = flist.inversedict
-         else:
-             self.tkinter_vars = {}  # keys: Tkinter event names
-                                     # values: Tkinter variable instances
-             self.top.instance_dict = {}
-         self.recent_files_path = os.path.join(idleConf.GetUserCfgDir(),
--                'recent-files.lst')
--        self.text_frame = text_frame = Frame(top)
--        self.vbar = vbar = Scrollbar(text_frame, name='vbar')
--        self.width = idleConf.GetOption('main','EditorWindow','width')
--        self.text = text = MultiCallCreator(Text)(
--                text_frame, name='text', padx=5, wrap='none',
--                width=self.width,
--                height=idleConf.GetOption('main','EditorWindow','height') )
--        self.top.focused_widget = self.text
-+            'recent-files.lst')
- 
--        self.createmenubar()
--        self.apply_bindings()
--
--        self.top.protocol("WM_DELETE_WINDOW", self.close)
--        self.top.bind("<<close-window>>", self.close_event)
--        if macosxSupport.runningAsOSXApp():
--            # Command-W on editorwindows doesn't work without this.
--            text.bind('<<close-window>>', self.close_event)
--        text.bind("<<cut>>", self.cut)
--        text.bind("<<copy>>", self.copy)
--        text.bind("<<paste>>", self.paste)
--        text.bind("<<center-insert>>", self.center_insert_event)
--        text.bind("<<help>>", self.help_dialog)
--        text.bind("<<python-docs>>", self.python_docs)
--        text.bind("<<about-idle>>", self.about_dialog)
--        text.bind("<<open-config-dialog>>", self.config_dialog)
--        text.bind("<<open-module>>", self.open_module)
--        text.bind("<<do-nothing>>", lambda event: "break")
--        text.bind("<<select-all>>", self.select_all)
--        text.bind("<<remove-selection>>", self.remove_selection)
--        text.bind("<<find>>", self.find_event)
--        text.bind("<<find-again>>", self.find_again_event)
--        text.bind("<<find-in-files>>", self.find_in_files_event)
--        text.bind("<<find-selection>>", self.find_selection_event)
--        text.bind("<<replace>>", self.replace_event)
--        text.bind("<<goto-line>>", self.goto_line_event)
--        text.bind("<3>", self.right_menu_event)
--        text.bind("<<smart-backspace>>",self.smart_backspace_event)
--        text.bind("<<newline-and-indent>>",self.newline_and_indent_event)
--        text.bind("<<smart-indent>>",self.smart_indent_event)
--        text.bind("<<indent-region>>",self.indent_region_event)
--        text.bind("<<dedent-region>>",self.dedent_region_event)
--        text.bind("<<comment-region>>",self.comment_region_event)
--        text.bind("<<uncomment-region>>",self.uncomment_region_event)
--        text.bind("<<tabify-region>>",self.tabify_region_event)
--        text.bind("<<untabify-region>>",self.untabify_region_event)
--        text.bind("<<toggle-tabs>>",self.toggle_tabs_event)
--        text.bind("<<change-indentwidth>>",self.change_indentwidth_event)
--        text.bind("<Left>", self.move_at_edge_if_selection(0))
--        text.bind("<Right>", self.move_at_edge_if_selection(1))
--        text.bind("<<del-word-left>>", self.del_word_left)
--        text.bind("<<del-word-right>>", self.del_word_right)
--        text.bind("<<beginning-of-line>>", self.home_callback)
--
-         if flist:
-             flist.inversedict[self] = key
-             if key:
-                 flist.dict[key] = self
--            text.bind("<<open-new-window>>", self.new_callback)
--            text.bind("<<close-all-windows>>", self.flist.close_all_callback)
--            text.bind("<<open-class-browser>>", self.open_class_browser)
--            text.bind("<<open-path-browser>>", self.open_path_browser)
- 
--        self.set_status_bar()
--        vbar['command'] = text.yview
--        vbar.pack(side=RIGHT, fill=Y)
--        text['yscrollcommand'] = vbar.set
--        fontWeight = 'normal'
--        if idleConf.GetOption('main', 'EditorWindow', 'font-bold', type='bool'):
--            fontWeight='bold'
--        text.config(font=(idleConf.GetOption('main', 'EditorWindow', 'font'),
--                          idleConf.GetOption('main', 'EditorWindow', 'font-size'),
--                          fontWeight))
--        text_frame.pack(side=LEFT, fill=BOTH, expand=1)
--        text.pack(side=TOP, fill=BOTH, expand=1)
--        text.focus_set()
-+        self.menudict = None
- 
-+        # create a Notebook where the text pages for this EditorWindow will
-+        # reside
-+        self.text_notebook = TabbedPageSet(self.top)
-+        self.text_notebook.pack(fill=BOTH, expand=True)
-+        self.text_notebook.bind('<<NotebookTabChanged>>', self._update_controls)
-+        self.new_tab(filename=filename, load_ext=False)
-+        self.text = self.current_page.text # XXX
-+        self.top.focused_widget = self.text
-+        self.top.bind('<<tab-closed>>', self._post_tab_close)
-+
-+        # The following "width" attribute is used by PyShell, so keep it here
-+        self.width = idleConf.GetOption('main', 'EditorPage', 'width')
-+
-+        self.top.protocol("WM_DELETE_WINDOW", self.close)
-+        self.top.bind("<<close-window>>", self.close_event)
-+
-+        self._create_statusbar()
-+        self.top.after_idle(self.set_line_and_column)
-+
-         # usetabs true  -> literal tab characters are used by indent and
-         #                  dedent cmds, possibly mixed with spaces if
-         #                  indentwidth is not a multiple of tabwidth,
-@@ -187,7 +137,8 @@
-         # Although use-spaces=0 can be configured manually in config-main.def,
-         # configuration of tabs v. spaces is not supported in the configuration
-         # dialog.  IDLE promotes the preferred Python indentation: use spaces!
--        usespaces = idleConf.GetOption('main', 'Indent', 'use-spaces', type='bool')
-+        usespaces = idleConf.GetOption('main', 'Indent', 'use-spaces',
-+            type='bool')
-         self.usetabs = not usespaces
- 
-         # tabwidth is the display width of a literal tab character.
-@@ -214,37 +165,10 @@
-         # Making the initial values larger slows things down more often.
-         self.num_context_lines = 50, 500, 5000000
- 
--        self.per = per = self.Percolator(text)
--
--        self.undo = undo = self.UndoDelegator()
--        per.insertfilter(undo)
--        text.undo_block_start = undo.undo_block_start
--        text.undo_block_stop = undo.undo_block_stop
--        undo.set_saved_change_hook(self.saved_change_hook)
--
--        # IOBinding implements file I/O and printing functionality
--        self.io = io = self.IOBinding(self)
--        io.set_filename_change_hook(self.filename_change_hook)
--
--        # Create the recent files submenu
--        self.recent_files_menu = Menu(self.menubar)
--        self.menudict['file'].insert_cascade(3, label='Recent Files',
--                                             underline=0,
--                                             menu=self.recent_files_menu)
--        self.update_recent_files_list()
--
--        self.color = None # initialized below in self.ResetColorizer
--        if filename:
--            if os.path.exists(filename) and not os.path.isdir(filename):
--                io.loadfile(filename)
--            else:
--                io.set_filename(filename)
--        self.ResetColorizer()
--        self.saved_change_hook()
--
-         self.set_indentation_params(self.ispythonsource(filename))
- 
--        self.load_extensions()
-+        self.extensions = {}
-+        self._load_extensions()
- 
-         menu = self.menudict.get('windows')
-         if menu:
-@@ -262,121 +186,96 @@
-         self.askinteger = tkSimpleDialog.askinteger
-         self.showerror = tkMessageBox.showerror
- 
--    def _filename_to_unicode(self, filename):
--        """convert filename to unicode in order to display it in Tk"""
--        if isinstance(filename, unicode) or not filename:
--            return filename
-+    @property
-+    def current_page(self):
-+        """Return the active EditorPage in EditorWindow."""
-+        curr_tab = self.text_notebook.select()
-+        if not curr_tab:
-+            return None
-+
-+        if TTK:
-+            page = self.text_notebook.pages[self.text_notebook.tab(
-+                curr_tab)['text']].editpage
-         else:
--            try:
--                return filename.decode(self.filesystemencoding)
--            except UnicodeDecodeError:
--                # XXX
--                try:
--                    return filename.decode(self.encoding)
--                except UnicodeDecodeError:
--                    # byte-to-byte conversion
--                    return filename.decode('iso8859-1')
-+            page = self.text_notebook.pages[curr_tab].editpage
-+        return page
- 
--    def new_callback(self, event):
--        dirname, basename = self.io.defaultfilename()
--        self.flist.new(dirname)
--        return "break"
-+    def short_title(self):
-+        # overriden by PyShell
-+        self.current_page.short_title()
- 
--    def home_callback(self, event):
--        if (event.state & 12) != 0 and event.keysym == "Home":
--            # state&1==shift, state&4==control, state&8==alt
--            return # <Modifier-Home>; fall back to class binding
-+    def next_tab(self, event):
-+        """Show next tab if not in the last tab already."""
-+        index = self.text_notebook.index(self.text_notebook.select())
-+        if index == len(self.text_notebook.tabs()) - 1:
-+            return
-+        self.text_notebook.select(index + 1)
- 
--        if self.text.index("iomark") and \
--           self.text.compare("iomark", "<=", "insert lineend") and \
--           self.text.compare("insert linestart", "<=", "iomark"):
--            insertpt = int(self.text.index("iomark").split(".")[1])
--        else:
--            line = self.text.get("insert linestart", "insert lineend")
--            for insertpt in xrange(len(line)):
--                if line[insertpt] not in (' ','\t'):
--                    break
--            else:
--                insertpt=len(line)
-+    def prev_tab(self, event):
-+        """Show the previous tab if not in the first tab already."""
-+        index = self.text_notebook.index(self.text_notebook.select())
-+        if index == 0:
-+            return
-+        self.text_notebook.select(index - 1)
- 
--        lineat = int(self.text.index("insert").split('.')[1])
-+    def new_tab(self, event=None, filename=None, load_ext=True):
-+        """Create a new EditorPage and insert it into the notebook."""
-+        page_title = "#%d" % (len(self.text_notebook.pages) + 1)
-+        page = self.text_notebook.add_page(page_title)
- 
--        if insertpt == lineat:
--            insertpt = 0
-+        vbar = Scrollbar(page.frame, name='vbar')
-+        page.editpage = EditorPage(page.frame, self, title=page_title,
-+            name='text', padx=5, wrap='none')
- 
--        dest = "insert linestart+"+str(insertpt)+"c"
-+        firstpage = False # don't update window's title
-+        if self.menudict is None:
-+            # This EditorWindow is being created now, perform the following
-+            # tasks before.
-+            firstpage = True # will cause window's title to be updated
-+            self.menudict = {}
-+            self._createmenubar(page.editpage.text)
-+            # Create the recent files submenu
-+            self.recent_files_menu = Menu(self.menubar)
-+            self.menudict['file'].insert_cascade(3, label='Recent Files',
-+                underline=0, menu=self.recent_files_menu)
-+            self.update_recent_files_list()
- 
--        if (event.state&1) == 0:
--            # shift not pressed
--            self.text.tag_remove("sel", "1.0", "end")
--        else:
--            if not self.text.index("sel.first"):
--                self.text.mark_set("anchor","insert")
-+        page.editpage.post_init(filename=filename, update_window_title=firstpage)
- 
--            first = self.text.index(dest)
--            last = self.text.index("anchor")
-+        text = page.editpage.text
-+        vbar['command'] = text.yview
-+        vbar.pack(side=RIGHT, fill=Y)
-+        text['yscrollcommand'] = vbar.set
-+        fontWeight = 'normal'
-+        if idleConf.GetOption('main', 'EditorPage', 'font-bold', type='bool'):
-+            fontWeight = 'bold'
-+        text.config(font=(idleConf.GetOption('main', 'EditorPage', 'font'),
-+            idleConf.GetOption('main', 'EditorPage', 'font-size'),
-+            fontWeight))
-+        text.pack(side=TOP, fill=BOTH, expand=1)
-+        text.focus_set()
- 
--            if self.text.compare(first,">",last):
--                first,last = last,first
-+        self.apply_bindings(tab=page)
-+        if load_ext:
-+            self._load_extensions()
-+        self.top.event_generate('<<tab-created>>')
-+        return "break"
- 
--            self.text.tag_remove("sel", "1.0", "end")
--            self.text.tag_add("sel", first, last)
--
--        self.text.mark_set("insert", dest)
--        self.text.see("insert")
-+    def new_callback(self, event, page):
-+        dirname, basename = page.io.defaultfilename()
-+        self.flist.new(dirname)
-         return "break"
- 
--    def set_status_bar(self):
--        self.status_bar = self.MultiStatusBar(self.top)
--        if macosxSupport.runningAsOSXApp():
--            # Insert some padding to avoid obscuring some of the statusbar
--            # by the resize widget.
--            self.status_bar.set_label('_padding1', '    ', side=RIGHT)
--        self.status_bar.set_label('column', 'Col: ?', side=RIGHT)
--        self.status_bar.set_label('line', 'Ln: ?', side=RIGHT)
--        self.status_bar.pack(side=BOTTOM, fill=X)
--        self.text.bind("<<set-line-and-column>>", self.set_line_and_column)
--        self.text.event_add("<<set-line-and-column>>",
--                            "<KeyRelease>", "<ButtonRelease>")
--        self.text.after_idle(self.set_line_and_column)
--
-     def set_line_and_column(self, event=None):
--        line, column = self.text.index(INSERT).split('.')
-+        # Used by PyShell too
-+        curr_page = self.current_page
-+        if not curr_page:
-+            return
-+
-+        line, column = curr_page.text.index(INSERT).split('.')
-         self.status_bar.set_label('column', 'Col: %s' % column)
-         self.status_bar.set_label('line', 'Ln: %s' % line)
- 
--    menu_specs = [
--        ("file", "_File"),
--        ("edit", "_Edit"),
--        ("format", "F_ormat"),
--        ("run", "_Run"),
--        ("options", "_Options"),
--        ("windows", "_Windows"),
--        ("help", "_Help"),
--    ]
--
--    if macosxSupport.runningAsOSXApp():
--        del menu_specs[-3]
--        menu_specs[-2] = ("windows", "_Window")
--
--
--    def createmenubar(self):
--        mbar = self.menubar
--        self.menudict = menudict = {}
--        for name, label in self.menu_specs:
--            underline, label = prepstr(label)
--            menudict[name] = menu = Menu(mbar, name=name)
--            mbar.add_cascade(label=label, menu=menu, underline=underline)
--
--        if sys.platform == 'darwin' and '.framework' in sys.executable:
--            # Insert the application menu
--            menudict['application'] = menu = Menu(mbar, name='apple')
--            mbar.add_cascade(label='IDLE', menu=menu)
--
--        self.fill_menus()
--        self.base_helpmenu_length = self.menudict['help'].index(END)
--        self.reset_help_menu_entries()
--
-     def postwindowsmenu(self):
-         # Only called when Windows menu exists
-         menu = self.menudict['windows']
-@@ -387,195 +286,27 @@
-             menu.delete(self.wmenu_end+1, end)
-         WindowList.add_windows_to_menu(menu)
- 
--    rmenu = None
-+    def newline_and_indent_event(self, event):
-+        """Call newline_and_indent_event on current EditorPage."""
-+        self.current_page.newline_and_indent_event(event)
- 
--    def right_menu_event(self, event):
--        self.text.tag_remove("sel", "1.0", "end")
--        self.text.mark_set("insert", "@%d,%d" % (event.x, event.y))
--        if not self.rmenu:
--            self.make_rmenu()
--        rmenu = self.rmenu
--        self.event = event
--        iswin = sys.platform[:3] == 'win'
--        if iswin:
--            self.text.config(cursor="arrow")
--        rmenu.tk_popup(event.x_root, event.y_root)
--        if iswin:
--            self.text.config(cursor="ibeam")
-+    def get_selection_indices(self):
-+        """Call get_selection_indices on current EditorPage."""
-+        return self.current_page.get_selection_indices()
- 
--    rmenu_specs = [
--        # ("Label", "<<virtual-event>>"), ...
--        ("Close", "<<close-window>>"), # Example
--    ]
-+    def build_char_in_string_func(self, startindex):
-+        """Call build_char_in_string_func on current EditorPage."""
-+        return self.current_page.build_char_in_string_func(startindex)
- 
--    def make_rmenu(self):
--        rmenu = Menu(self.text, tearoff=0)
--        for label, eventname in self.rmenu_specs:
--            def command(text=self.text, eventname=eventname):
--                text.event_generate(eventname)
--            rmenu.add_command(label=label, command=command)
--        self.rmenu = rmenu
--
--    def about_dialog(self, event=None):
--        aboutDialog.AboutDialog(self.top,'About IDLE')
--
--    def config_dialog(self, event=None):
--        configDialog.ConfigDialog(self.top,'Settings')
--
--    def help_dialog(self, event=None):
--        fn=os.path.join(os.path.abspath(os.path.dirname(__file__)),'help.txt')
--        textView.view_file(self.top,'Help',fn)
--
--    def python_docs(self, event=None):
--        if sys.platform[:3] == 'win':
--            os.startfile(self.help_url)
--        else:
--            webbrowser.open(self.help_url)
--        return "break"
--
--    def cut(self,event):
--        self.text.event_generate("<<Cut>>")
--        return "break"
--
--    def copy(self,event):
--        if not self.text.tag_ranges("sel"):
--            # There is no selection, so do nothing and maybe interrupt.
--            return
--        self.text.event_generate("<<Copy>>")
--        return "break"
--
--    def paste(self,event):
--        self.text.event_generate("<<Paste>>")
--        self.text.see("insert")
--        return "break"
--
--    def select_all(self, event=None):
--        self.text.tag_add("sel", "1.0", "end-1c")
--        self.text.mark_set("insert", "1.0")
--        self.text.see("insert")
--        return "break"
--
--    def remove_selection(self, event=None):
--        self.text.tag_remove("sel", "1.0", "end")
--        self.text.see("insert")
--
--    def move_at_edge_if_selection(self, edge_index):
--        """Cursor move begins at start or end of selection
--
--        When a left/right cursor key is pressed create and return to Tkinter a
--        function which causes a cursor move from the associated edge of the
--        selection.
--
--        """
--        self_text_index = self.text.index
--        self_text_mark_set = self.text.mark_set
--        edges_table = ("sel.first+1c", "sel.last-1c")
--        def move_at_edge(event):
--            if (event.state & 5) == 0: # no shift(==1) or control(==4) pressed
--                try:
--                    self_text_index("sel.first")
--                    self_text_mark_set("insert", edges_table[edge_index])
--                except TclError:
--                    pass
--        return move_at_edge
--
--    def del_word_left(self, event):
--        self.text.event_generate('<Meta-Delete>')
--        return "break"
--
--    def del_word_right(self, event):
--        self.text.event_generate('<Meta-d>')
--        return "break"
--
--    def find_event(self, event):
--        SearchDialog.find(self.text)
--        return "break"
--
--    def find_again_event(self, event):
--        SearchDialog.find_again(self.text)
--        return "break"
--
--    def find_selection_event(self, event):
--        SearchDialog.find_selection(self.text)
--        return "break"
--
--    def find_in_files_event(self, event):
--        GrepDialog.grep(self.text, self.io, self.flist)
--        return "break"
--
--    def replace_event(self, event):
--        ReplaceDialog.replace(self.text)
--        return "break"
--
--    def goto_line_event(self, event):
--        text = self.text
--        lineno = tkSimpleDialog.askinteger("Goto",
--                "Go to line number:",parent=text)
--        if lineno is None:
--            return "break"
--        if lineno <= 0:
--            text.bell()
--            return "break"
--        text.mark_set("insert", "%d.0" % lineno)
--        text.see("insert")
--
--    def open_module(self, event=None):
--        # XXX Shouldn't this be in IOBinding or in FileList?
--        try:
--            name = self.text.get("sel.first", "sel.last")
--        except TclError:
--            name = ""
--        else:
--            name = name.strip()
--        name = tkSimpleDialog.askstring("Module",
--                 "Enter the name of a Python module\n"
--                 "to search on sys.path and open:",
--                 parent=self.text, initialvalue=name)
--        if name:
--            name = name.strip()
--        if not name:
--            return
--        # XXX Ought to insert current file's directory in front of path
--        try:
--            (f, file, (suffix, mode, type)) = _find_module(name)
--        except (NameError, ImportError), msg:
--            tkMessageBox.showerror("Import error", str(msg), parent=self.text)
--            return
--        if type != imp.PY_SOURCE:
--            tkMessageBox.showerror("Unsupported type",
--                "%s is not a source module" % name, parent=self.text)
--            return
--        if f:
--            f.close()
--        if self.flist:
--            self.flist.open(file)
--        else:
--            self.io.loadfile(file)
--
--    def open_class_browser(self, event=None):
--        filename = self.io.filename
--        if not filename:
--            tkMessageBox.showerror(
--                "No filename",
--                "This buffer has no associated filename",
--                master=self.text)
--            self.text.focus_set()
--            return None
--        head, tail = os.path.split(filename)
--        base, ext = os.path.splitext(tail)
--        import ClassBrowser
--        ClassBrowser.ClassBrowser(self.flist, base, [head])
--
--    def open_path_browser(self, event=None):
--        import PathBrowser
--        PathBrowser.PathBrowser(self.flist)
--
-     def gotoline(self, lineno):
-+        page = self.current_page
-+        text = page.text
-+
-         if lineno is not None and lineno > 0:
--            self.text.mark_set("insert", "%d.0" % lineno)
--            self.text.tag_remove("sel", "1.0", "end")
--            self.text.tag_add("sel", "insert", "insert +1l")
--            self.center()
-+            text.mark_set("insert", "%d.0" % lineno)
-+            text.tag_remove("sel", "1.0", "end")
-+            text.tag_add("sel", "insert", "insert +1l")
-+            page.center()
- 
-     def ispythonsource(self, filename):
-         if not filename or os.path.isdir(filename):
-@@ -599,82 +330,59 @@
-     def set_close_hook(self, close_hook):
-         self.close_hook = close_hook
- 
--    def filename_change_hook(self):
--        if self.flist:
--            self.flist.filename_changed_edit(self)
--        self.saved_change_hook()
--        self.top.update_windowlist_registry(self)
--        self.ResetColorizer()
-+    def set_theme(self, ttkstyle):
-+        # called from configDialog.py
-+        ttkstyle.theme_use(idleConf.GetOption('main', 'Theme', 'displaytheme'))
- 
--    def _addcolorizer(self):
--        if self.color:
--            return
--        if self.ispythonsource(self.io.filename):
--            self.color = self.ColorDelegator()
--        # can add more colorizers here...
--        if self.color:
--            self.per.removefilter(self.undo)
--            self.per.insertfilter(self.color)
--            self.per.insertfilter(self.undo)
--
--    def _rmcolorizer(self):
--        if not self.color:
--            return
--        self.color.removecolors()
--        self.per.removefilter(self.color)
--        self.color = None
--
-     def ResetColorizer(self):
-         "Update the colour theme"
-         # Called from self.filename_change_hook and from configDialog.py
--        self._rmcolorizer()
--        self._addcolorizer()
--        theme = idleConf.GetOption('main','Theme','name')
--        normal_colors = idleConf.GetHighlight(theme, 'normal')
--        cursor_color = idleConf.GetHighlight(theme, 'cursor', fgBg='fg')
--        select_colors = idleConf.GetHighlight(theme, 'hilite')
--        self.text.config(
--            foreground=normal_colors['foreground'],
--            background=normal_colors['background'],
--            insertbackground=cursor_color,
--            selectforeground=select_colors['foreground'],
--            selectbackground=select_colors['background'],
--            )
-+        for page in self.text_notebook.pages.itervalues():
-+            page.editpage.reset_colorizer()
- 
-     def ResetFont(self):
-         "Update the text widgets' font if it is changed"
-         # Called from configDialog.py
--        fontWeight='normal'
--        if idleConf.GetOption('main','EditorWindow','font-bold',type='bool'):
--            fontWeight='bold'
--        self.text.config(font=(idleConf.GetOption('main','EditorWindow','font'),
--                idleConf.GetOption('main','EditorWindow','font-size'),
-+        fontWeight = 'normal'
-+        if idleConf.GetOption('main', 'EditorPage', 'font-bold', type='bool'):
-+            fontWeight = 'bold'
-+
-+        for page in self.text_notebook.pages.itervalues():
-+            text = page.editpage.text
-+            text.config(font=(idleConf.GetOption('main', 'EditorPage', 'font'),
-+                idleConf.GetOption('main', 'EditorPage', 'font-size'),
-                 fontWeight))
- 
-     def RemoveKeybindings(self):
-         "Remove the keybindings before they are changed."
-         # Called from configDialog.py
--        self.Bindings.default_keydefs = keydefs = idleConf.GetCurrentKeySet()
--        for event, keylist in keydefs.items():
--            self.text.event_delete(event, *keylist)
--        for extensionName in self.get_standard_extension_names():
-+        Bindings.default_keydefs = keydefs = idleConf.GetCurrentKeySet()
-+
-+        for page in self.text_notebook.pages.itervalues():
-+            text = page.editpage.text
-+            for event, keylist in keydefs.items():
-+                text.event_delete(event, *keylist)
-+
-+        for extensionName in self._get_standard_extension_names():
-             xkeydefs = idleConf.GetExtensionBindings(extensionName)
-             if xkeydefs:
--                for event, keylist in xkeydefs.items():
--                    self.text.event_delete(event, *keylist)
-+                for page in self.text_notebook.pages.itervalues():
-+                    text = page.editpage.text
-+                    for event, keylist in xkeydefs.items():
-+                        text.event_delete(event, *keylist)
- 
-     def ApplyKeybindings(self):
-         "Update the keybindings after they are changed"
-         # Called from configDialog.py
--        self.Bindings.default_keydefs = keydefs = idleConf.GetCurrentKeySet()
-+        Bindings.default_keydefs = keydefs = idleConf.GetCurrentKeySet()
-         self.apply_bindings()
--        for extensionName in self.get_standard_extension_names():
-+        for extensionName in self._get_standard_extension_names():
-             xkeydefs = idleConf.GetExtensionBindings(extensionName)
-             if xkeydefs:
-                 self.apply_bindings(xkeydefs)
-         #update menu accelerators
-         menuEventDict = {}
--        for menu in self.Bindings.menudefs:
-+        for menu in Bindings.menudefs:
-             menuEventDict[menu[0]] = {}
-             for item in menu[1]:
-                 if item:
-@@ -695,13 +403,6 @@
-                             accel = get_accelerator(keydefs, event)
-                             menu.entryconfig(index, accelerator=accel)
- 
--    def set_notabs_indentwidth(self):
--        "Update the indentwidth if changed and not using tabs in this window"
--        # Called from configDialog.py
--        if not self.usetabs:
--            self.indentwidth = idleConf.GetOption('main', 'Indent','num-spaces',
--                                                  type='int')
--
-     def reset_help_menu_entries(self):
-         "Update the additional help entries on the Help menu"
-         help_list = idleConf.GetAllExtraHelpSourcesList()
-@@ -719,19 +420,16 @@
-         # and update the menu dictionary
-         self.menudict['help'] = helpmenu
- 
--    def __extra_help_callback(self, helpfile):
--        "Create a callback with the helpfile value frozen at definition time"
--        def display_extra_help(helpfile=helpfile):
--            if not helpfile.startswith(('www', 'http')):
--                url = os.path.normpath(helpfile)
--            if sys.platform[:3] == 'win':
--                os.startfile(helpfile)
--            else:
--                webbrowser.open(helpfile)
--        return display_extra_help
-+    def set_notabs_indentwidth(self):
-+        "Update the indentwidth if changed and not using tabs in this window"
-+        # Called from configDialog.py
-+        if not self.usetabs:
-+            self.indentwidth = idleConf.GetOption('main', 'Indent','num-spaces',
-+                                                  type='int')
- 
-     def update_recent_files_list(self, new_file=None):
-         "Load and update the recent files list and menus"
-+        # IOBinding calls this
-         rf_list = []
-         if os.path.exists(self.recent_files_path):
-             rf_list_file = open(self.recent_files_path,'r')
-@@ -761,83 +459,18 @@
-         for instance in self.top.instance_dict.keys():
-             menu = instance.recent_files_menu
-             menu.delete(1, END)  # clear, and rebuild:
--            for i, file in zip(count(), rf_list):
-+            for i, file in enumerate(rf_list):
-                 file_name = file[0:-1]  # zap \n
-                 # make unicode string to display non-ASCII chars correctly
--                ufile_name = self._filename_to_unicode(file_name)
-+                ufile_name = filename_to_unicode(file_name)
-                 callback = instance.__recent_file_callback(file_name)
-                 menu.add_command(label=ulchars[i] + " " + ufile_name,
-                                  command=callback,
-                                  underline=0)
- 
--    def __recent_file_callback(self, file_name):
--        def open_recent_file(fn_closure=file_name):
--            self.io.open(editFile=fn_closure)
--        return open_recent_file
--
--    def saved_change_hook(self):
--        short = self.short_title()
--        long = self.long_title()
--        if short and long:
--            title = short + " - " + long
--        elif short:
--            title = short
--        elif long:
--            title = long
--        else:
--            title = "Untitled"
--        icon = short or long or title
--        if not self.get_saved():
--            title = "*%s*" % title
--            icon = "*%s" % icon
--        self.top.wm_title(title)
--        self.top.wm_iconname(icon)
--
-     def get_saved(self):
--        return self.undo.get_saved()
-+        return self.current_page.undo.get_saved() # XXX check this!
- 
--    def set_saved(self, flag):
--        self.undo.set_saved(flag)
--
--    def reset_undo(self):
--        self.undo.reset_undo()
--
--    def short_title(self):
--        filename = self.io.filename
--        if filename:
--            filename = os.path.basename(filename)
--        # return unicode string to display non-ASCII chars correctly
--        return self._filename_to_unicode(filename)
--
--    def long_title(self):
--        # return unicode string to display non-ASCII chars correctly
--        return self._filename_to_unicode(self.io.filename or "")
--
--    def center_insert_event(self, event):
--        self.center()
--
--    def center(self, mark="insert"):
--        text = self.text
--        top, bot = self.getwindowlines()
--        lineno = self.getlineno(mark)
--        height = bot - top
--        newtop = max(1, lineno - height//2)
--        text.yview(float(newtop))
--
--    def getwindowlines(self):
--        text = self.text
--        top = self.getlineno("@0,0")
--        bot = self.getlineno("@0,65535")
--        if top == bot and text.winfo_height() == 1:
--            # Geometry manager hasn't run yet
--            height = int(text['height'])
--            bot = top + height - 1
--        return top, bot
--
--    def getlineno(self, mark="insert"):
--        text = self.text
--        return int(float(text.index(mark)))
--
-     def get_geometry(self):
-         "Return (width, height, x, y)"
-         geom = self.top.wm_geometry()
-@@ -848,132 +481,49 @@
-     def close_event(self, event):
-         self.close()
- 
--    def maybesave(self):
--        if self.io:
--            if not self.get_saved():
--                if self.top.state()!='normal':
--                    self.top.deiconify()
--                self.top.lower()
--                self.top.lift()
--            return self.io.maybesave()
--
-     def close(self):
--        reply = self.maybesave()
--        if str(reply) != "cancel":
--            self._close()
--        return reply
-+        to_check = self.text_notebook.pages.copy()
- 
-+        while to_check:
-+            curr_tab = self.text_notebook.select()
-+            if TTK:
-+                page_name = self.text_notebook.tab(curr_tab)['text']
-+            else:
-+                page_name = curr_tab
-+            page = to_check.pop(page_name)
-+            editpage = page.editpage
-+            reply = editpage.close_tab()
-+            if reply == "cancel":
-+                break
-+
-     def _close(self):
--        if self.io.filename:
--            self.update_recent_files_list(new_file=self.io.filename)
-         WindowList.unregister_callback(self.postwindowsmenu)
--        self.unload_extensions()
--        self.io.close()
--        self.io = None
--        self.undo = None
--        if self.color:
--            self.color.close(False)
--            self.color = None
--        self.text = None
-+        self._unload_extensions()
-         self.tkinter_vars = None
--        self.per.close()
--        self.per = None
-+
-+        for page in self.text_notebook.pages.itervalues():
-+            page.editpage.close()
-+
-         self.top.destroy()
-         if self.close_hook:
-             # unless override: unregister from flist, terminate if last window
-             self.close_hook()
- 
--    def load_extensions(self):
--        self.extensions = {}
--        self.load_standard_extensions()
--
--    def unload_extensions(self):
--        for ins in self.extensions.values():
--            if hasattr(ins, "close"):
--                ins.close()
--        self.extensions = {}
--
--    def load_standard_extensions(self):
--        for name in self.get_standard_extension_names():
--            try:
--                self.load_extension(name)
--            except:
--                print "Failed to load extension", repr(name)
--                import traceback
--                traceback.print_exc()
--
--    def get_standard_extension_names(self):
--        return idleConf.GetExtensions(editor_only=True)
--
--    def load_extension(self, name):
--        try:
--            mod = __import__(name, globals(), locals(), [])
--        except ImportError:
--            print "\nFailed to import extension: ", name
--            return
--        cls = getattr(mod, name)
--        keydefs = idleConf.GetExtensionBindings(name)
--        if hasattr(cls, "menudefs"):
--            self.fill_menus(cls.menudefs, keydefs)
--        ins = cls(self)
--        self.extensions[name] = ins
--        if keydefs:
--            self.apply_bindings(keydefs)
--            for vevent in keydefs.keys():
--                methodname = vevent.replace("-", "_")
--                while methodname[:1] == '<':
--                    methodname = methodname[1:]
--                while methodname[-1:] == '>':
--                    methodname = methodname[:-1]
--                methodname = methodname + "_event"
--                if hasattr(ins, methodname):
--                    self.text.bind(vevent, getattr(ins, methodname))
--
--    def apply_bindings(self, keydefs=None):
-+    def apply_bindings(self, keydefs=None, tab=None):
-         if keydefs is None:
--            keydefs = self.Bindings.default_keydefs
--        text = self.text
--        text.keydefs = keydefs
--        for event, keylist in keydefs.items():
--            if keylist:
--                text.event_add(event, *keylist)
-+            keydefs = Bindings.default_keydefs
- 
--    def fill_menus(self, menudefs=None, keydefs=None):
--        """Add appropriate entries to the menus and submenus
-+        if tab:
-+            iter_over = [tab]
-+        else:
-+            iter_over = self.text_notebook.pages.itervalues()
- 
--        Menus that are absent or None in self.menudict are ignored.
--        """
--        if menudefs is None:
--            menudefs = self.Bindings.menudefs
--        if keydefs is None:
--            keydefs = self.Bindings.default_keydefs
--        menudict = self.menudict
--        text = self.text
--        for mname, entrylist in menudefs:
--            menu = menudict.get(mname)
--            if not menu:
--                continue
--            for entry in entrylist:
--                if not entry:
--                    menu.add_separator()
--                else:
--                    label, eventname = entry
--                    checkbutton = (label[:1] == '!')
--                    if checkbutton:
--                        label = label[1:]
--                    underline, label = prepstr(label)
--                    accelerator = get_accelerator(keydefs, eventname)
--                    def command(text=text, eventname=eventname):
--                        text.event_generate(eventname)
--                    if checkbutton:
--                        var = self.get_var_obj(eventname, BooleanVar)
--                        menu.add_checkbutton(label=label, underline=underline,
--                            command=command, accelerator=accelerator,
--                            variable=var)
--                    else:
--                        menu.add_command(label=label, underline=underline,
--                                         command=command,
--                                         accelerator=accelerator)
-+        for page in iter_over:
-+            text = page.editpage.text
-+            text.keydefs = keydefs
-+            for event, keylist in keydefs.items():
-+                if keylist:
-+                    text.event_add(event, *keylist)
- 
-     def getvar(self, name):
-         var = self.get_var_obj(name)
-@@ -990,52 +540,25 @@
-         else:
-             raise NameError, name
- 
--    def get_var_obj(self, name, vartype=None):
-+    def get_var_obj(self, name, vartype=None, text=None):
-         var = self.tkinter_vars.get(name)
-         if not var and vartype:
-             # create a Tkinter variable object with self.text as master:
--            self.tkinter_vars[name] = var = vartype(self.text)
-+            self.tkinter_vars[name] = var = vartype(text or self.text)
-         return var
- 
-     # Tk implementations of "virtual text methods" -- each platform
-     # reusing IDLE's support code needs to define these for its GUI's
-     # flavor of widget.
- 
--    # Is character at text_index in a Python string?  Return 0 for
--    # "guaranteed no", true for anything else.  This info is expensive
--    # to compute ab initio, but is probably already known by the
--    # platform's colorizer.
--
--    def is_char_in_string(self, text_index):
--        if self.color:
--            # Return true iff colorizer hasn't (re)gotten this far
--            # yet, or the character is tagged as being in a string
--            return self.text.tag_prevrange("TODO", text_index) or \
--                   "STRING" in self.text.tag_names(text_index)
--        else:
--            # The colorizer is missing: assume the worst
--            return 1
--
--    # If a selection is defined in the text widget, return (start,
--    # end) as Tkinter text indices, otherwise return (None, None)
--    def get_selection_indices(self):
--        try:
--            first = self.text.index("sel.first")
--            last = self.text.index("sel.last")
--            return first, last
--        except TclError:
--            return None, None
--
-     # Return the text widget's current view of what a tab stop means
-     # (equivalent width in spaces).
--
--    def get_tabwidth(self):
-+    def get_tabwidth(self): # XXX depends on self.text
-         current = self.text['tabs'] or TK_TABWIDTH_DEFAULT
-         return int(current)
- 
-     # Set the text widget's current view of what a tab stop means.
--
--    def set_tabwidth(self, newtabwidth):
-+    def set_tabwidth(self, newtabwidth): # XXX depends on self.text
-         text = self.text
-         if self.get_tabwidth() != newtabwidth:
-             pixels = text.tk.call("font", "measure", text["font"],
-@@ -1048,7 +571,6 @@
-     # indentwidth != tabwidth set usetabs false.
-     # In any case, adjust the Text widget's view of what a tab
-     # character means.
--
-     def set_indentation_params(self, ispythonsource, guess=True):
-         if guess and ispythonsource:
-             i = self.guess_indent()
-@@ -1058,386 +580,187 @@
-                 self.usetabs = False
-         self.set_tabwidth(self.tabwidth)
- 
--    def smart_backspace_event(self, event):
--        text = self.text
--        first, last = self.get_selection_indices()
--        if first and last:
--            text.delete(first, last)
--            text.mark_set("insert", first)
--            return "break"
--        # Delete whitespace left, until hitting a real char or closest
--        # preceding virtual tab stop.
--        chars = text.get("insert linestart", "insert")
--        if chars == '':
--            if text.compare("insert", ">", "1.0"):
--                # easy: delete preceding newline
--                text.delete("insert-1c")
--            else:
--                text.bell()     # at start of buffer
--            return "break"
--        if  chars[-1] not in " \t":
--            # easy: delete preceding real char
--            text.delete("insert-1c")
--            return "break"
--        # Ick.  It may require *inserting* spaces if we back up over a
--        # tab character!  This is written to be clear, not fast.
--        tabwidth = self.tabwidth
--        have = len(chars.expandtabs(tabwidth))
--        assert have > 0
--        want = ((have - 1) // self.indentwidth) * self.indentwidth
--        # Debug prompt is multilined....
--        last_line_of_prompt = sys.ps1.split('\n')[-1]
--        ncharsdeleted = 0
--        while 1:
--            if chars == last_line_of_prompt:
--                break
--            chars = chars[:-1]
--            ncharsdeleted = ncharsdeleted + 1
--            have = len(chars.expandtabs(tabwidth))
--            if have <= want or chars[-1] not in " \t":
--                break
--        text.undo_block_start()
--        text.delete("insert-%dc" % ncharsdeleted, "insert")
--        if have < want:
--            text.insert("insert", ' ' * (want - have))
--        text.undo_block_stop()
--        return "break"
-+    # Guess indentwidth from text content.
-+    # Return guessed indentwidth.  This should not be believed unless
-+    # it's in a reasonable range (e.g., it will be 0 if no indented
-+    # blocks are found).
-+    def guess_indent(self): # XXX depends on self.text
-+        opener, indented = IndentSearcher(self.text, self.tabwidth).run()
-+        if opener and indented:
-+            raw, indentsmall = classifyws(opener, self.tabwidth)
-+            raw, indentlarge = classifyws(indented, self.tabwidth)
-+        else:
-+            indentsmall = indentlarge = 0
-+        return indentlarge - indentsmall
- 
--    def smart_indent_event(self, event):
--        # if intraline selection:
--        #     delete it
--        # elif multiline selection:
--        #     do indent-region
--        # else:
--        #     indent one level
--        text = self.text
--        first, last = self.get_selection_indices()
--        text.undo_block_start()
--        try:
--            if first and last:
--                if index2line(first) != index2line(last):
--                    return self.indent_region_event(event)
--                text.delete(first, last)
--                text.mark_set("insert", first)
--            prefix = text.get("insert linestart", "insert")
--            raw, effective = classifyws(prefix, self.tabwidth)
--            if raw == len(prefix):
--                # only whitespace to the left
--                self.reindent_to(effective + self.indentwidth)
--            else:
--                # tab to the next 'stop' within or to right of line's text:
--                if self.usetabs:
--                    pad = '\t'
--                else:
--                    effective = len(prefix.expandtabs(self.tabwidth))
--                    n = self.indentwidth
--                    pad = ' ' * (n - effective % n)
--                text.insert("insert", pad)
--            text.see("insert")
--            return "break"
--        finally:
--            text.undo_block_stop()
-+    # Private methods/attributes
- 
--    def newline_and_indent_event(self, event):
--        text = self.text
--        first, last = self.get_selection_indices()
--        text.undo_block_start()
--        try:
--            if first and last:
--                text.delete(first, last)
--                text.mark_set("insert", first)
--            line = text.get("insert linestart", "insert")
--            i, n = 0, len(line)
--            while i < n and line[i] in " \t":
--                i = i+1
--            if i == n:
--                # the cursor is in or at leading indentation in a continuation
--                # line; just inject an empty line at the start
--                text.insert("insert linestart", '\n')
--                return "break"
--            indent = line[:i]
--            # strip whitespace before insert point unless it's in the prompt
--            i = 0
--            last_line_of_prompt = sys.ps1.split('\n')[-1]
--            while line and line[-1] in " \t" and line != last_line_of_prompt:
--                line = line[:-1]
--                i = i+1
--            if i:
--                text.delete("insert - %d chars" % i, "insert")
--            # strip whitespace after insert point
--            while text.get("insert") in " \t":
--                text.delete("insert")
--            # start new line
--            text.insert("insert", '\n')
-+    # extensions won't have more than one instance per window
-+    _unique_extensions = ['CodeContext', 'ScriptBinding', 'FormatParagraph']
- 
--            # adjust indentation for continuations and block
--            # open/close first need to find the last stmt
--            lno = index2line(text.index('insert'))
--            y = PyParse.Parser(self.indentwidth, self.tabwidth)
--            if not self.context_use_ps1:
--                for context in self.num_context_lines:
--                    startat = max(lno - context, 1)
--                    startatindex = `startat` + ".0"
--                    rawtext = text.get(startatindex, "insert")
--                    y.set_str(rawtext)
--                    bod = y.find_good_parse_start(
--                              self.context_use_ps1,
--                              self._build_char_in_string_func(startatindex))
--                    if bod is not None or startat == 1:
--                        break
--                y.set_lo(bod or 0)
--            else:
--                r = text.tag_prevrange("console", "insert")
--                if r:
--                    startatindex = r[1]
--                else:
--                    startatindex = "1.0"
--                rawtext = text.get(startatindex, "insert")
--                y.set_str(rawtext)
--                y.set_lo(0)
-+    def _unload_extensions(self):
-+        for ins in self.extensions.values():
-+            if hasattr(ins, "close"):
-+                ins.close()
-+        self.extensions = {}
- 
--            c = y.get_continuation_type()
--            if c != PyParse.C_NONE:
--                # The current stmt hasn't ended yet.
--                if c == PyParse.C_STRING_FIRST_LINE:
--                    # after the first line of a string; do not indent at all
--                    pass
--                elif c == PyParse.C_STRING_NEXT_LINES:
--                    # inside a string which started before this line;
--                    # just mimic the current indent
--                    text.insert("insert", indent)
--                elif c == PyParse.C_BRACKET:
--                    # line up with the first (if any) element of the
--                    # last open bracket structure; else indent one
--                    # level beyond the indent of the line with the
--                    # last open bracket
--                    self.reindent_to(y.compute_bracket_indent())
--                elif c == PyParse.C_BACKSLASH:
--                    # if more than one line in this stmt already, just
--                    # mimic the current indent; else if initial line
--                    # has a start on an assignment stmt, indent to
--                    # beyond leftmost =; else to beyond first chunk of
--                    # non-whitespace on initial line
--                    if y.get_num_lines_in_stmt() > 1:
--                        text.insert("insert", indent)
--                    else:
--                        self.reindent_to(y.compute_backslash_indent())
--                else:
--                    assert 0, "bogus continuation type %r" % (c,)
--                return "break"
-+    def _load_extension(self, name, tab):
-+        ext_loaded = self.extensions.get(name, None)
- 
--            # This line starts a brand new stmt; indent relative to
--            # indentation of initial line of closest preceding
--            # interesting stmt.
--            indent = y.get_base_indent_string()
--            text.insert("insert", indent)
--            if y.is_block_opener():
--                self.smart_indent_event(event)
--            elif indent and y.is_block_closer():
--                self.smart_backspace_event(event)
--            return "break"
--        finally:
--            text.see("insert")
--            text.undo_block_stop()
-+        try:
-+            mod = __import__(name, globals(), locals(), [])
-+        except ImportError:
-+            print "\nFailed to import extension: ", name
-+            return
- 
--    # Our editwin provides a is_char_in_string function that works
--    # with a Tk text index, but PyParse only knows about offsets into
--    # a string. This builds a function for PyParse that accepts an
--    # offset.
-+        keydefs = idleConf.GetExtensionBindings(name)
- 
--    def _build_char_in_string_func(self, startindex):
--        def inner(offset, _startindex=startindex,
--                  _icis=self.is_char_in_string):
--            return _icis(_startindex + "+%dc" % offset)
--        return inner
-+        if name not in self._unique_extensions or not ext_loaded:
-+            # create a new instance
-+            cls = getattr(mod, name)
-+            ins = cls(tab.editpage)
-+            self.extensions.setdefault(name, []).append(ins)
-+            if not ext_loaded:
-+                # create new items in menu only if this is the first time this
-+                # extension is being loaded in this window
-+                if hasattr(cls, "menudefs"):
-+                    self._fill_menus(cls.menudefs, keydefs)
-+        elif name in self._unique_extensions and ext_loaded:
-+            # get an existing instance
-+            ins = self.extensions[name][0]
- 
--    def indent_region_event(self, event):
--        head, tail, chars, lines = self.get_region()
--        for pos in range(len(lines)):
--            line = lines[pos]
--            if line:
--                raw, effective = classifyws(line, self.tabwidth)
--                effective = effective + self.indentwidth
--                lines[pos] = self._make_blanks(effective) + line[raw:]
--        self.set_region(head, tail, chars, lines)
--        return "break"
-+        if keydefs:
-+            self.apply_bindings(keydefs, tab)
-+            for vevent in keydefs.keys():
-+                methodname = vevent.replace("-", "_")
-+                while methodname[:1] == '<':
-+                    methodname = methodname[1:]
-+                while methodname[-1:] == '>':
-+                    methodname = methodname[:-1]
-+                methodname = methodname + "_event"
-+                if hasattr(ins, methodname):
-+                    tab.editpage.text.bind(vevent, getattr(ins, methodname))
- 
--    def dedent_region_event(self, event):
--        head, tail, chars, lines = self.get_region()
--        for pos in range(len(lines)):
--            line = lines[pos]
--            if line:
--                raw, effective = classifyws(line, self.tabwidth)
--                effective = max(effective - self.indentwidth, 0)
--                lines[pos] = self._make_blanks(effective) + line[raw:]
--        self.set_region(head, tail, chars, lines)
--        return "break"
-+    def _load_extensions(self):
-+        self._load_standard_extensions(self.text_notebook.last_page())
- 
--    def comment_region_event(self, event):
--        head, tail, chars, lines = self.get_region()
--        for pos in range(len(lines) - 1):
--            line = lines[pos]
--            lines[pos] = '##' + line
--        self.set_region(head, tail, chars, lines)
-+    def _load_standard_extensions(self, tab):
-+        for name in self._get_standard_extension_names():
-+            try:
-+                self._load_extension(name, tab)
-+            except:
-+                print "Failed to load extension", repr(name)
-+                traceback.print_exc()
- 
--    def uncomment_region_event(self, event):
--        head, tail, chars, lines = self.get_region()
--        for pos in range(len(lines)):
--            line = lines[pos]
--            if not line:
--                continue
--            if line[:2] == '##':
--                line = line[2:]
--            elif line[:1] == '#':
--                line = line[1:]
--            lines[pos] = line
--        self.set_region(head, tail, chars, lines)
-+    def _get_standard_extension_names(self):
-+        return idleConf.GetExtensions(editor_only=True)
- 
--    def tabify_region_event(self, event):
--        head, tail, chars, lines = self.get_region()
--        tabwidth = self._asktabwidth()
--        for pos in range(len(lines)):
--            line = lines[pos]
--            if line:
--                raw, effective = classifyws(line, tabwidth)
--                ntabs, nspaces = divmod(effective, tabwidth)
--                lines[pos] = '\t' * ntabs + ' ' * nspaces + line[raw:]
--        self.set_region(head, tail, chars, lines)
-+    def _post_tab_close(self, event):
-+        if not self.current_page:
-+            # no tabs now, close window
-+            self._close()
-+            return
- 
--    def untabify_region_event(self, event):
--        head, tail, chars, lines = self.get_region()
--        tabwidth = self._asktabwidth()
--        for pos in range(len(lines)):
--            lines[pos] = lines[pos].expandtabs(tabwidth)
--        self.set_region(head, tail, chars, lines)
-+    def _update_controls(self, event):
-+        curr_page = self.current_page
-+        if not curr_page:
-+            return
- 
--    def toggle_tabs_event(self, event):
--        if self.askyesno(
--              "Toggle tabs",
--              "Turn tabs " + ("on", "off")[self.usetabs] +
--              "?\nIndent width " +
--              ("will be", "remains at")[self.usetabs] + " 8." +
--              "\n Note: a tab is always 8 columns",
--              parent=self.text):
--            self.usetabs = not self.usetabs
--            # Try to prevent inconsistent indentation.
--            # User must change indent width manually after using tabs.
--            self.indentwidth = 8
--        return "break"
-+        self.text = curr_page.text
-+        curr_page.saved_change_hook(True, False) # update window title
-+        curr_page.text.focus_set()
-+        self.set_line_and_column()
- 
--    # XXX this isn't bound to anything -- see tabwidth comments
--##     def change_tabwidth_event(self, event):
--##         new = self._asktabwidth()
--##         if new != self.tabwidth:
--##             self.tabwidth = new
--##             self.set_indentation_params(0, guess=0)
--##         return "break"
-+        # update references in extensions that are loaded only once
-+        for ext in self._unique_extensions:
-+            if ext not in self.extensions:
-+                continue
-+            ext = self.extensions[ext][0]
-+            ext.editpage = curr_page
- 
--    def change_indentwidth_event(self, event):
--        new = self.askinteger(
--                  "Indent width",
--                  "New indent width (2-16)\n(Always use 8 when using tabs)",
--                  parent=self.text,
--                  initialvalue=self.indentwidth,
--                  minvalue=2,
--                  maxvalue=16)
--        if new and new != self.indentwidth and not self.usetabs:
--            self.indentwidth = new
--        return "break"
-+    def _create_statusbar(self):
-+        self.status_bar = MultiStatusBar(self.top)
-+        if macosxSupport.runningAsOSXApp():
-+            # Insert some padding to avoid obscuring some of the statusbar
-+            # by the resize widget.
-+            self.status_bar.set_label('_padding1', '    ', side=RIGHT)
-+        self.status_bar.set_label('column', 'Col: ?', side=RIGHT)
-+        self.status_bar.set_label('line', 'Ln: ?', side=RIGHT)
-+        self.status_bar.pack(side=BOTTOM, fill=X)
- 
--    def get_region(self):
--        text = self.text
--        first, last = self.get_selection_indices()
--        if first and last:
--            head = text.index(first + " linestart")
--            tail = text.index(last + "-1c lineend +1c")
--        else:
--            head = text.index("insert linestart")
--            tail = text.index("insert lineend +1c")
--        chars = text.get(head, tail)
--        lines = chars.split("\n")
--        return head, tail, chars, lines
-+    def _createmenubar(self, text):
-+        mbar = self.menubar
-+        menudict = self.menudict
-+        for name, label in self.menu_specs:
-+            underline, label = prepstr(label)
-+            menudict[name] = menu = Menu(mbar, name=name, tearoff=0)
-+            mbar.add_cascade(label=label, menu=menu, underline=underline)
- 
--    def set_region(self, head, tail, chars, lines):
--        text = self.text
--        newchars = "\n".join(lines)
--        if newchars == chars:
--            text.bell()
--            return
--        text.tag_remove("sel", "1.0", "end")
--        text.mark_set("insert", head)
--        text.undo_block_start()
--        text.delete(head, tail)
--        text.insert(head, newchars)
--        text.undo_block_stop()
--        text.tag_add("sel", head, "insert")
-+        if sys.platform == 'darwin' and '.framework' in sys.executable:
-+            # Insert the application menu
-+            menudict['application'] = menu = Menu(mbar, name='apple')
-+            mbar.add_cascade(label='IDLE', menu=menu)
- 
--    # Make string that displays as n leading blanks.
-+        self._fill_menus(text=text)
-+        self.base_helpmenu_length = self.menudict['help'].index(END)
-+        self.reset_help_menu_entries()
- 
--    def _make_blanks(self, n):
--        if self.usetabs:
--            ntabs, nspaces = divmod(n, self.tabwidth)
--            return '\t' * ntabs + ' ' * nspaces
--        else:
--            return ' ' * n
-+    def _fill_menus(self, menudefs=None, keydefs=None, text=None):
-+        """Add appropriate entries to the menus and submenus
- 
--    # Delete from beginning of line to insert point, then reinsert
--    # column logical (meaning use tabs if appropriate) spaces.
-+        Menus that are absent or None in self.menudict are ignored.
-+        """
-+        if menudefs is None:
-+            menudefs = Bindings.menudefs
-+        if keydefs is None:
-+            keydefs = Bindings.default_keydefs
-+        menudict = self.menudict
-+        for mname, entrylist in menudefs:
-+            menu = menudict.get(mname)
-+            if not menu:
-+                continue
-+            for entry in entrylist:
-+                if not entry:
-+                    menu.add_separator()
-+                else:
-+                    label, eventname = entry
-+                    checkbutton = (label[:1] == '!')
-+                    if checkbutton:
-+                        label = label[1:]
-+                    underline, label = prepstr(label)
-+                    accelerator = get_accelerator(keydefs, eventname)
-+                    def command(eventname=eventname):
-+                        self.text.event_generate(eventname)
-+                    if checkbutton:
-+                        var = self.get_var_obj(eventname, BooleanVar, text)
-+                        menu.add_checkbutton(label=label, underline=underline,
-+                            command=command, accelerator=accelerator,
-+                            variable=var)
-+                    else:
-+                        menu.add_command(label=label, underline=underline,
-+                            command=command, accelerator=accelerator)
- 
--    def reindent_to(self, column):
--        text = self.text
--        text.undo_block_start()
--        if text.compare("insert linestart", "!=", "insert"):
--            text.delete("insert linestart", "insert")
--        if column:
--            text.insert("insert", self._make_blanks(column))
--        text.undo_block_stop()
-+    def __recent_file_callback(self, file_name):
-+        def open_recent_file(fn_closure=file_name):
-+            self.current_page.io.open(editFile=fn_closure)
-+        return open_recent_file
- 
--    def _asktabwidth(self):
--        return self.askinteger(
--            "Tab width",
--            "Columns per tab? (2-16)",
--            parent=self.text,
--            initialvalue=self.indentwidth,
--            minvalue=2,
--            maxvalue=16) or self.tabwidth
-+    def __extra_help_callback(self, helpfile):
-+        "Create a callback with the helpfile value frozen at definition time"
-+        def display_extra_help(helpfile=helpfile):
-+            if not helpfile.startswith(('www', 'http')):
-+                url = os.path.normpath(helpfile)
-+            if sys.platform[:3] == 'win':
-+                os.startfile(helpfile)
-+            else:
-+                webbrowser.open(helpfile)
-+        return display_extra_help
- 
--    # Guess indentwidth from text content.
--    # Return guessed indentwidth.  This should not be believed unless
--    # it's in a reasonable range (e.g., it will be 0 if no indented
--    # blocks are found).
--
--    def guess_indent(self):
--        opener, indented = IndentSearcher(self.text, self.tabwidth).run()
--        if opener and indented:
--            raw, indentsmall = classifyws(opener, self.tabwidth)
--            raw, indentlarge = classifyws(indented, self.tabwidth)
--        else:
--            indentsmall = indentlarge = 0
--        return indentlarge - indentsmall
--
--# "line.col" -> line, as an int
--def index2line(index):
--    return int(float(index))
--
- # Look at the leading whitespace in s.
- # Return pair (# of leading ws characters,
- #              effective # of leading blanks after expanding
- #              tabs to width tabwidth)
- 
--def classifyws(s, tabwidth):
--    raw = effective = 0
--    for ch in s:
--        if ch == ' ':
--            raw = raw + 1
--            effective = effective + 1
--        elif ch == '\t':
--            raw = raw + 1
--            effective = (effective // tabwidth + 1) * tabwidth
--        else:
--            break
--    return raw, effective
--
- import tokenize
- _tokenize = tokenize
- del tokenize
-@@ -1534,6 +857,7 @@
- 
- 
- def test():
-+    from Tkinter import Tk
-     root = Tk()
-     fixwordbreaks(root)
-     root.withdraw()
-Index: help.txt
-===================================================================
---- help.txt	(revision 63995)
-+++ help.txt	(revision 65541)
-@@ -6,6 +6,7 @@
- File Menu:
- 
- 	New Window       -- Create a new editing window
-+    New Tab          -- Create a new editing tab
- 	Open...          -- Open an existing file
- 	Recent Files...  -- Open a list of recent files
- 	Open Module...   -- Open an existing module (searches sys.path)
-@@ -23,6 +24,7 @@
- 	---
- 	Print Window     -- Print the current window
- 	---
-+    Close Tab        -- Close current tab (asks to save if unsaved)
- 	Close            -- Close current window (asks to save if unsaved)
- 	Exit             -- Close all windows, quit (asks to save if unsaved)
- 
-Index: editorpage.py
-===================================================================
---- editorpage.py	(revision 0)
-+++ editorpage.py	(revision 65541)
-@@ -0,0 +1,925 @@
-+import os
-+import sys
-+import imp
-+import webbrowser
-+import tkMessageBox
-+import tkSimpleDialog
-+from Tkinter import Text, Menu, TclError
-+
-+import utils
-+import textView
-+import aboutDialog
-+import configDialog
-+import macosxSupport
-+import PyParse
-+import IOBinding
-+import GrepDialog
-+import PathBrowser
-+import ClassBrowser
-+import SearchDialog
-+import ReplaceDialog
-+from configHandler import idleConf
-+from MultiCall import MultiCallCreator
-+from Percolator import Percolator
-+
-+def classifyws(s, tabwidth):
-+    raw = effective = 0
-+    for ch in s:
-+        if ch == ' ':
-+            raw = raw + 1
-+            effective = effective + 1
-+        elif ch == '\t':
-+            raw = raw + 1
-+            effective = (effective // tabwidth + 1) * tabwidth
-+        else:
-+            break
-+    return raw, effective
-+
-+def index2line(index):
-+    """"line.col" -> line, as an int"""
-+    return int(float(index))
-+
-+def filename_to_unicode(filename):
-+    """Convert filename to unicode in order to display it in Tk"""
-+    if isinstance(filename, unicode) or not filename:
-+        return filename
-+    else:
-+        try:
-+            return filename.decode(IOBinding.filesystemencoding)
-+        except UnicodeDecodeError:
-+            # XXX
-+            try:
-+                return filename.decode(IOBinding.encoding)
-+            except UnicodeDecodeError:
-+                # byte-to-byte conversion
-+                return filename.decode('iso8859-1')
-+
-+def _find_module(fullname, path=None):
-+    """Version of imp.find_module() that handles hierarchical module names"""
-+    file = None
-+
-+    for tgt in fullname.split('.'):
-+        if file is not None:
-+            file.close()            # close intermediate files
-+        (file, filename, descr) = imp.find_module(tgt, path)
-+        if descr[2] == imp.PY_SOURCE:
-+            break                   # find but not load the source file
-+        module = imp.load_module(tgt, file, filename, descr)
-+        try:
-+            path = module.__path__
-+        except AttributeError:
-+            raise ImportError('No source for module %s' % module.__name__)
-+
-+    return file, filename, descr
-+
-+class EditorPage(object):
-+    def __init__(self, parent_frame, editwin, title=None, **kwargs):
-+        self.editwin = editwin
-+        self.title = title
-+        self.tab_initialized = False
-+        kwargs.setdefault('width', idleConf.GetOption('main', 'EditorPage',
-+            'width'))
-+        kwargs.setdefault('height', idleConf.GetOption('main', 'EditorPage',
-+            'height'))
-+
-+        self.text = MultiCallCreator(Text)(parent_frame, **kwargs)
-+        self.color = None # initialized in reset_colorizer
-+        self.per = Percolator(self.text)
-+        self.undo = self.editwin.UndoDelegator()
-+        self.per.insertfilter(self.undo)
-+        self.text.undo_block_start = self.undo.undo_block_start
-+        self.text.undo_block_stop = self.undo.undo_block_stop
-+        self.io = IOBinding.IOBinding(self)
-+
-+        self.undo.set_saved_change_hook(self.saved_change_hook)
-+        self.io.set_filename_change_hook(self.filename_change_hook)
-+        self.reset_colorizer()
-+        self._setup_bindings()
-+
-+    def post_init(self, filename=None, update_window_title=False):
-+        if filename:
-+            if os.path.exists(filename) and not os.path.isdir(filename):
-+                self.io.loadfile(filename)
-+            else:
-+                self.io.set_filename(filename)
-+        self.saved_change_hook(update_window_title=update_window_title)
-+        self.tab_initialized = True
-+
-+    def close_tab(self, event=None):
-+        """Close current tab, if no more tabs present, close the window."""
-+        if hasattr(self.editwin, 'interp'):
-+            # this is a PyShell, don't ask to save
-+            reply = 'yes'
-+        else:
-+            reply = str(self.maybesave())
-+        if reply != "cancel":
-+            if self.io.filename:
-+                self.editwin.update_recent_files_list(new_file=self.io.filename)
-+            self.close()
-+            self.editwin.text_notebook.remove_page(self.title)
-+            self.editwin.top.event_generate('<<tab-closed>>')
-+
-+        return reply
-+
-+    def close(self):
-+        """Perform necessary cleanup for this page before closing it."""
-+        self.io.close()
-+        self.io = None
-+
-+        self.undo = None
-+
-+        if self.color:
-+            self.color.close(False)
-+            self.color = None
-+
-+        self.per.close()
-+        self.per = None
-+        self.text = None
-+
-+    # XXX (1) mark where these functions are used
-+    def saved_change_hook(self,update_window_title=False,update_tab_title=True):
-+        short = self.editwin.short_title()
-+        long = self.long_title()
-+
-+        if short and long:
-+            title = short + " - " + long
-+            tabtitle = os.path.split(long)[-1]
-+        elif short:
-+            title = short
-+            tabtitle = short
-+        elif long:
-+            title = long
-+            tabtitle = os.path.split(long)[-1]
-+        else:
-+            title = tabtitle = "Untitled"
-+        icon = short or long or title
-+        if not self.get_saved():
-+            title = "*%s*" % title
-+            tabtitle = "*%s*" % tabtitle
-+            icon = "*%s" % icon
-+
-+        if update_tab_title:
-+            self.editwin.text_notebook.update_tabtitle(self, tabtitle)
-+        if update_window_title or (
-+           update_window_title is None and self.tab_initialized):
-+            self.editwin.top.wm_title(title)
-+            self.editwin.top.wm_iconname(icon)
-+
-+    def get_saved(self):
-+        return self.undo.get_saved()
-+
-+    def set_saved(self, flag):
-+        self.undo.set_saved(flag)
-+
-+    def filename_change_hook(self):
-+        if self.editwin.flist:
-+            self.editwin.flist.filename_changed_edit(self, self.editwin)
-+        self.saved_change_hook(self.tab_initialized)
-+        self.editwin.top.update_windowlist_registry(self.editwin)
-+        self.reset_colorizer()
-+
-+    def reset_undo(self):
-+        self.undo.reset_undo()
-+
-+    def reset_colorizer(self):
-+        "Update the colour theme"
-+        # Called from self.filename_change_hook and from configDialog.py
-+        self.__rmcolorizer()
-+        self.__addcolorizer()
-+        theme = idleConf.GetOption('main','Theme','name')
-+        normal_colors = idleConf.GetHighlight(theme, 'normal')
-+        cursor_color = idleConf.GetHighlight(theme, 'cursor', fgBg='fg')
-+        select_colors = idleConf.GetHighlight(theme, 'hilite')
-+
-+        self.text.config(
-+            foreground=normal_colors['foreground'],
-+            background=normal_colors['background'],
-+            insertbackground=cursor_color,
-+            selectforeground=select_colors['foreground'],
-+            selectbackground=select_colors['background'])
-+
-+    def short_title(self):
-+        filename = self.io.filename
-+        if filename:
-+            filename = os.path.basename(filename)
-+        # return unicode string to display non-ASCII chars correctly
-+        return filename_to_unicode(filename)
-+
-+    def long_title(self):
-+        # return unicode string to display non-ASCII chars correctly
-+        return filename_to_unicode(self.io.filename or "")
-+
-+    def maybesave(self):
-+        if self.io:
-+            if not self.get_saved():
-+                if self.editwin.top.state()!= 'normal':
-+                    self.editiwn.top.deiconify()
-+                self.editwin.top.lower()
-+                self.editwin.top.lift()
-+            return self.io.maybesave()
-+    # XXX (1) end
-+
-+    def center(self, mark="insert"):
-+        # Used by EditorWindow.gotoline
-+        text = self.text
-+        top, bot = self._getwindowlines()
-+        lineno = self._getlineno(mark)
-+        height = bot - top
-+        newtop = max(1, lineno - height//2)
-+        text.yview(float(newtop))
-+
-+    def newline_and_indent_event(self, event):
-+        # Used by EditorWindow.newline_and_indent_event which is used by PyShell
-+        text = self.text
-+        first, last = self.get_selection_indices()
-+        text.undo_block_start()
-+        try:
-+            if first and last:
-+                text.delete(first, last)
-+                text.mark_set("insert", first)
-+            line = text.get("insert linestart", "insert")
-+            i, n = 0, len(line)
-+            while i < n and line[i] in " \t":
-+                i = i+1
-+            if i == n:
-+                # the cursor is in or at leading indentation in a continuation
-+                # line; just inject an empty line at the start
-+                text.insert("insert linestart", '\n')
-+                return "break"
-+            indent = line[:i]
-+            # strip whitespace before insert point unless it's in the prompt
-+            i = 0
-+            last_line_of_prompt = sys.ps1.split('\n')[-1]
-+            while line and line[-1] in " \t" and line != last_line_of_prompt:
-+                line = line[:-1]
-+                i = i+1
-+            if i:
-+                text.delete("insert - %d chars" % i, "insert")
-+            # strip whitespace after insert point
-+            while text.get("insert") in " \t":
-+                text.delete("insert")
-+            # start new line
-+            text.insert("insert", '\n')
-+
-+            # adjust indentation for continuations and block
-+            # open/close first need to find the last stmt
-+            lno = index2line(text.index('insert'))
-+            #print self.editwin.indentwidth, self.editwin.tabwidth
-+            y = PyParse.Parser(self.editwin.indentwidth, self.editwin.tabwidth)
-+            if not self.editwin.context_use_ps1:
-+                for context in self.editwin.num_context_lines:
-+                    startat = max(lno - context, 1)
-+                    startatindex = `startat` + ".0"
-+                    rawtext = text.get(startatindex, "insert")
-+                    y.set_str(rawtext)
-+                    bod = y.find_good_parse_start(
-+                              self.editwin.context_use_ps1,
-+                              self.build_char_in_string_func(startatindex))
-+                    if bod is not None or startat == 1:
-+                        break
-+                y.set_lo(bod or 0)
-+            else:
-+                r = text.tag_prevrange("console", "insert")
-+                if r:
-+                    startatindex = r[1]
-+                else:
-+                    startatindex = "1.0"
-+                rawtext = text.get(startatindex, "insert")
-+                y.set_str(rawtext)
-+                y.set_lo(0)
-+
-+            c = y.get_continuation_type()
-+            if c != PyParse.C_NONE:
-+                # The current stmt hasn't ended yet.
-+                if c == PyParse.C_STRING_FIRST_LINE:
-+                    # after the first line of a string; do not indent at all
-+                    pass
-+                elif c == PyParse.C_STRING_NEXT_LINES:
-+                    # inside a string which started before this line;
-+                    # just mimic the current indent
-+                    text.insert("insert", indent)
-+                elif c == PyParse.C_BRACKET:
-+                    # line up with the first (if any) element of the
-+                    # last open bracket structure; else indent one
-+                    # level beyond the indent of the line with the
-+                    # last open bracket
-+                    self.__reindent_to(y.compute_bracket_indent())
-+                elif c == PyParse.C_BACKSLASH:
-+                    # if more than one line in this stmt already, just
-+                    # mimic the current indent; else if initial line
-+                    # has a start on an assignment stmt, indent to
-+                    # beyond leftmost =; else to beyond first chunk of
-+                    # non-whitespace on initial line
-+                    if y.get_num_lines_in_stmt() > 1:
-+                        text.insert("insert", indent)
-+                    else:
-+                        self.__reindent_to(y.compute_backslash_indent())
-+                else:
-+                    assert 0, "bogus continuation type %r" % (c,)
-+                return "break"
-+
-+            # This line starts a brand new stmt; indent relative to
-+            # indentation of initial line of closest preceding
-+            # interesting stmt.
-+            indent = y.get_base_indent_string()
-+            text.insert("insert", indent)
-+            if y.is_block_opener():
-+                self._smart_indent_event(event)
-+            elif indent and y.is_block_closer():
-+                self._smart_backspace_event(event)
-+            return "break"
-+        finally:
-+            text.see("insert")
-+            text.undo_block_stop()
-+
-+    # If a selection is defined in the text widget, return (start,
-+    # end) as Tkinter text indices, otherwise return (None, None)
-+    def get_selection_indices(self):
-+        # Used by EditorWindow.get_selection_indices which is used by
-+        # FormatParagraph
-+        try:
-+            first = self.text.index("sel.first")
-+            last = self.text.index("sel.last")
-+            return first, last
-+        except TclError:
-+            return None, None
-+
-+    # Our editpage provides a __is_char_in_string function that works
-+    # with a Tk text index, but PyParse only knows about offsets into
-+    # a string. This builds a function for PyParse that accepts an
-+    # offset.
-+    def build_char_in_string_func(self, startindex):
-+        # Used by EditorWindow.build_char_in_string_func which is used by
-+        # HyperParser
-+        def inner(offset, _startindex=startindex,
-+                  _icis=self.__is_char_in_string):
-+            return _icis(_startindex + "+%dc" % offset)
-+        return inner
-+
-+    def _setup_bindings(self):
-+        text = self.text
-+        def bind_them(to_bind, prefix='_%s'):
-+            for tb in to_bind:
-+                prefix_size = tb.count('<')
-+                method_name = tb[prefix_size:-prefix_size].replace('-', '_')
-+                text.bind(tb, getattr(self, prefix % method_name.lower()))
-+            
-+        actions = ('<<help>>', '<<python-docs>>',
-+            '<<about-idle>>', '<<open-config-dialog>>', '<<open-module>>',
-+            '<<cut>>', '<<copy>>', '<<paste>>', '<<select-all>>',
-+            '<<remove-selection>>', '<<del-word-left>>', '<<del-word-right>>',
-+            '<<beginning-of-line>>')
-+        events = ('<<find>>', '<<center-insert>>', '<<find-again>>',
-+            '<<find-in-files>>', '<<find-selection>>', '<<replace>>',
-+            '<<goto-line>>', '<<smart-backspace>>', '<<smart-indent>>',
-+            '<<indent-region>>', '<<dedent-region>>', '<<comment-region>>',
-+            '<<tabify-region>>', '<<untabify-region>>', '<<toggle-tabs>>',
-+            '<<change-indentwidth>>')
-+        parent_actions = ('<<new-tab>>', '<<next-tab>>', '<<prev-tab>>')
-+
-+        bind_them(actions)
-+        bind_them(events, prefix="_%s_event")
-+        for action in parent_actions:
-+            prefix_size = action.count('<')
-+            method_name = action[prefix_size:-prefix_size].replace('-', '_')
-+            text.bind(action, getattr(self.editwin, method_name))
-+
-+        text.bind('<<close-tab>>', self.close_tab)
-+        text.bind('<<newline-and-indent>>', self.newline_and_indent_event)
-+        text.bind("<<do-nothing>>", lambda event: "break")
-+        text.bind("<Left>", self._move_at_edge_if_selection(0))
-+        text.bind("<Right>", self._move_at_edge_if_selection(1))
-+        text.bind("<3>", self._right_menu)
-+        text.bind('<<set-line-and-column>>', self.editwin.set_line_and_column)
-+        text.event_add("<<set-line-and-column>>",
-+                                    "<KeyRelease>", "<ButtonRelease>")
-+
-+        if self.editwin.flist:
-+            text.bind("<<open-new-window>>",
-+                utils.callback(self.editwin.new_callback, self))
-+            text.bind("<<close-all-windows>>",
-+                self.editwin.flist.close_all_callback)
-+            text.bind("<<open-class-browser>>", self._open_class_browser)
-+            text.bind("<<open-path-browser>>", self._open_path_browser)
-+
-+        if macosxSupport.runningAsOSXApp():
-+            # Command-W on editorwindows doesn't work without this.
-+            text.bind('<<close-window>>', self.editwin.close_event)
-+
-+    def _help(self, event=None):
-+        fn = os.path.join(os.path.abspath(os.path.dirname(__file__)),
-+            'help.txt')
-+        textView.view_file(self.text, 'Help', fn)
-+
-+    def _python_docs(self, event=None):
-+        if sys.platform[:3] == 'win':
-+            os.startfile(self.editwin.help_url)
-+        else:
-+            webbrowser.open(self.editwin.help_url)
-+        return "break"
-+
-+    def _about_idle(self, event=None):
-+        aboutDialog.AboutDialog(self.text, 'About IDLE')
-+
-+    def _open_class_browser(self, event=None):
-+        filename = self.io.filename
-+        if not filename:
-+            tkMessageBox.showerror("No filename",
-+                "This buffer has no associated filename",
-+                master=self.text)
-+            self.text.focus_set()
-+            return None
-+        head, tail = os.path.split(filename)
-+        base, ext = os.path.splitext(tail)
-+        ClassBrowser.ClassBrowser(self.editwin.flist, base, [head])
-+
-+    def _open_path_browser(self, event=None):
-+        PathBrowser.PathBrowser(self.editwin.flist)
-+
-+    def _open_config_dialog(self, event=None):
-+        # When changing colors and saving it, it requires the attribute
-+        # instance_dict making necessary to pass self.editwin.top as the
-+        # parent
-+        configDialog.ConfigDialog(self.editwin.top, 'Settings')
-+
-+    def _open_module(self, event=None):
-+        try:
-+            name = self.text.get("sel.first", "sel.last")
-+        except TclError:
-+            name = ""
-+        else:
-+            name = name.strip()
-+
-+        name = tkSimpleDialog.askstring("Module",
-+            "Enter the name of a Python module\n"
-+            "to search on sys.path and open:",
-+            parent=self.text, initialvalue=name)
-+
-+        if name:
-+            name = name.strip()
-+        if not name:
-+            return
-+        # XXX Ought to insert current file's directory in front of path
-+        try:
-+            (f, file, (suffix, mode, type)) = _find_module(name)
-+        except (NameError, ImportError), msg:
-+            tkMessageBox.showerror("Import error", str(msg), parent=self.text)
-+            return
-+
-+        if type != imp.PY_SOURCE:
-+            tkMessageBox.showerror("Unsupported type",
-+                "%s is not a source module" % name, parent=self.text)
-+            return
-+        if f:
-+            f.close()
-+        if self.editwin.flist:
-+            if idleConf.GetOption('main', 'EditorWindow', 'file-in-tab',
-+                default=1, type='bool'):
-+                if hasattr(self.editwin, 'interp'):
-+                    # PyShell window must open a module in a new window
-+                    action = None
-+                else:
-+                    action = self.editwin.new_tab
-+            else:
-+                action = None
-+            self.editwin.flist.open(file, action)
-+        else:
-+            self.io.loadfile(file)
-+
-+    def _find_event(self, event):
-+        SearchDialog.find(self.text)
-+        return "break"
-+
-+    def _find_again_event(self, event):
-+        SearchDialog.find_again(self.text)
-+        return "break"
-+
-+    def _find_selection_event(self, event):
-+        SearchDialog.find_selection(self.text)
-+        return "break"
-+
-+    def _find_in_files_event(self, event):
-+        # XXX not expected to work correctly for now
-+        GrepDialog.grep(self.text, self.editwin.io, self.editwin.flist)
-+        return "break"
-+
-+    def _replace_event(self, event):
-+        ReplaceDialog.replace(self.text)
-+        return "break"
-+
-+    def _center_insert_event(self, event):
-+        self.center()
-+
-+    def _getwindowlines(self):
-+        text = self.text
-+        top = self._getlineno("@0,0")
-+        bot = self._getlineno("@0,65535")
-+        if top == bot and text.winfo_height() == 1:
-+            # Geometry manager hasn't run yet
-+            height = int(text['height'])
-+            bot = top + height - 1
-+        return top, bot
-+
-+    def _getlineno(self, mark="insert"):
-+        return int(float(self.text.index(mark)))
-+
-+    def _goto_line_event(self, event):
-+        text = self.text
-+        lineno = tkSimpleDialog.askinteger("Goto", "Go to line number:",
-+            parent=text)
-+
-+        if lineno is None:
-+            return "break"
-+
-+        if lineno <= 0:
-+            text.bell()
-+            return "break"
-+
-+        text.mark_set("insert", "%d.0" % lineno)
-+        text.see("insert")
-+
-+    def _cut(self, event):
-+        self.text.event_generate("<<Cut>>")
-+        return "break"
-+
-+    def _copy(self, event):
-+        if not self.text.tag_ranges("sel"):
-+            # There is no selection, so do nothing and maybe interrupt.
-+            return
-+
-+        self.text.event_generate("<<Copy>>")
-+        return "break"
-+
-+    def _paste(self, event):
-+        self.text.event_generate("<<Paste>>")
-+        self.text.see("insert")
-+        return "break"
-+
-+    def _select_all(self, event=None):
-+        self.text.tag_add("sel", "1.0", "end-1c")
-+        self.text.mark_set("insert", "1.0")
-+        self.text.see("insert")
-+        return "break"
-+
-+    def _remove_selection(self, event=None):
-+        self.text.tag_remove("sel", "1.0", "end")
-+        self.text.see("insert")
-+
-+    def _del_word_left(self, event):
-+        self.text.event_generate('<Meta-Delete>')
-+        return "break"
-+
-+    def _del_word_right(self, event):
-+        self.text.event_generate('<Meta-d>')
-+        return "break"
-+
-+    def _move_at_edge_if_selection(self, edge_index):
-+        """Cursor move begins at start or end of selection
-+        When a left/right cursor key is pressed create and return to Tkinter a
-+        function which causes a cursor move from the associated edge of the
-+        selection.
-+        """
-+        text_index = self.text.index
-+        text_mark_set = self.text.mark_set
-+        edges_table = ("sel.first+1c", "sel.last-1c")
-+
-+        def move_at_edge(event):
-+            if (event.state & 5) == 0: # no shift(==1) or control(==4) pressed
-+                try:
-+                    text_index("sel.first")
-+                    text_mark_set("insert", edges_table[edge_index])
-+                except TclError:
-+                    pass
-+
-+        return move_at_edge
-+
-+    def _beginning_of_line(self, event):
-+        if (event.state & 12) != 0 and event.keysym == "Home":
-+            # state&1==shift, state&4==control, state&8==alt
-+            return # <Modifier-Home>; fall back to class binding
-+
-+        text = self.text
-+
-+        if text.index("iomark") and \
-+           text.compare("iomark", "<=", "insert lineend") and \
-+           text.compare("insert linestart", "<=", "iomark"):
-+            insertpt = int(text.index("iomark").split(".")[1])
-+        else:
-+            line = text.get("insert linestart", "insert lineend")
-+            for insertpt in xrange(len(line)):
-+                if line[insertpt] not in (' ','\t'):
-+                    break
-+            else:
-+                insertpt=len(line)
-+
-+        lineat = int(text.index("insert").split('.')[1])
-+
-+        if insertpt == lineat:
-+            insertpt = 0
-+
-+        dest = "insert linestart+%sc" % str(insertpt)
-+
-+        if (event.state & 1) == 0:
-+            # shift not pressed
-+            text.tag_remove("sel", "1.0", "end")
-+        else:
-+            if not text.index("sel.first"):
-+                text.mark_set("anchor", "insert")
-+
-+            first = text.index(dest)
-+            last = text.index("anchor")
-+
-+            if text.compare(first, ">", last):
-+                first, last = last, first
-+
-+            text.tag_remove("sel", "1.0", "end")
-+            text.tag_add("sel", first, last)
-+
-+        text.mark_set("insert", dest)
-+        text.see("insert")
-+        return "break"
-+
-+    def _smart_backspace_event(self, event):
-+        text = self.text
-+        first, last = self.get_selection_indices()
-+        if first and last:
-+            text.delete(first, last)
-+            text.mark_set("insert", first)
-+            return "break"
-+        # Delete whitespace left, until hitting a real char or closest
-+        # preceding virtual tab stop.
-+        chars = text.get("insert linestart", "insert")
-+        if chars == '':
-+            if text.compare("insert", ">", "1.0"):
-+                # easy: delete preceding newline
-+                text.delete("insert-1c")
-+            else:
-+                text.bell()     # at start of buffer
-+            return "break"
-+        if  chars[-1] not in " \t":
-+            # easy: delete preceding real char
-+            text.delete("insert-1c")
-+            return "break"
-+        # Ick.  It may require *inserting* spaces if we back up over a
-+        # tab character!  This is written to be clear, not fast.
-+        tabwidth = self.editwin.tabwidth
-+        have = len(chars.expandtabs(tabwidth))
-+        assert have > 0
-+        want = ((have - 1) // 
-+            self.editwin.indentwidth) * self.editwin.indentwidth
-+        # Debug prompt is multilined....
-+        last_line_of_prompt = sys.ps1.split('\n')[-1]
-+        ncharsdeleted = 0
-+        while 1:
-+            if chars == last_line_of_prompt:
-+                break
-+            chars = chars[:-1]
-+            ncharsdeleted = ncharsdeleted + 1
-+            have = len(chars.expandtabs(tabwidth))
-+            if have <= want or chars[-1] not in " \t":
-+                break
-+        text.undo_block_start()
-+        text.delete("insert-%dc" % ncharsdeleted, "insert")
-+        if have < want:
-+            text.insert("insert", ' ' * (want - have))
-+        text.undo_block_stop()
-+        return "break"
-+
-+    def _smart_indent_event(self, event):
-+        # if intraline selection:
-+        #     delete it
-+        # elif multiline selection:
-+        #     do indent-region
-+        # else:
-+        #     indent one level
-+        text = self.text
-+        first, last = self.get_selection_indices()
-+        text.undo_block_start()
-+        try:
-+            if first and last:
-+                if index2line(first) != index2line(last):
-+                    return self._indent_region_event(event)
-+                text.delete(first, last)
-+                text.mark_set("insert", first)
-+            prefix = text.get("insert linestart", "insert")
-+            raw, effective = classifyws(prefix, self.editwin.tabwidth)
-+            if raw == len(prefix):
-+                # only whitespace to the left
-+                self.__reindent_to(effective + self.editwin.indentwidth)
-+            else:
-+                # tab to the next 'stop' within or to right of line's text:
-+                if self.editwin.usetabs:
-+                    pad = '\t'
-+                else:
-+                    effective = len(prefix.expandtabs(self.editwin.tabwidth))
-+                    n = self.editwin.indentwidth
-+                    pad = ' ' * (n - effective % n)
-+                text.insert("insert", pad)
-+            text.see("insert")
-+            return "break"
-+        finally:
-+            text.undo_block_stop()
-+
-+    def _indent_region_event(self, event):
-+        head, tail, chars, lines = self.__get_region()
-+        for pos in range(len(lines)):
-+            line = lines[pos]
-+            if line:
-+                raw, effective = classifyws(line, self.editwin.tabwidth)
-+                effective = effective + self.editwin.indentwidth
-+                lines[pos] = self.__make_blanks(effective) + line[raw:]
-+        self.__set_region(head, tail, chars, lines)
-+        return "break"
-+
-+    def _dedent_region_event(self, event):
-+        head, tail, chars, lines = self.__get_region()
-+        for pos in range(len(lines)):
-+            line = lines[pos]
-+            if line:
-+                raw, effective = classifyws(line, self.editwin.tabwidth)
-+                effective = max(effective - self.editwin.indentwidth, 0)
-+                lines[pos] = self.__make_blanks(effective) + line[raw:]
-+        self.__set_region(head, tail, chars, lines)
-+        return "break"
-+
-+    def _comment_region_event(self, event):
-+        head, tail, chars, lines = self.__get_region()
-+        for pos in range(len(lines) - 1):
-+            line = lines[pos]
-+            lines[pos] = '##' + line
-+        self.__set_region(head, tail, chars, lines)
-+
-+    def _uncomment_region_event(self, event):
-+        head, tail, chars, lines = self.__get_region()
-+        for pos in range(len(lines)):
-+            line = lines[pos]
-+            if not line:
-+                continue
-+            if line[:2] == '##':
-+                line = line[2:]
-+            elif line[:1] == '#':
-+                line = line[1:]
-+            lines[pos] = line
-+        self.__set_region(head, tail, chars, lines)
-+
-+    def _tabify_region_event(self, event):
-+        head, tail, chars, lines = self.__get_region()
-+        tabwidth = self.__asktabwidth()
-+        for pos in range(len(lines)):
-+            line = lines[pos]
-+            if line:
-+                raw, effective = classifyws(line, tabwidth)
-+                ntabs, nspaces = divmod(effective, tabwidth)
-+                lines[pos] = '\t' * ntabs + ' ' * nspaces + line[raw:]
-+        self.__set_region(head, tail, chars, lines)
-+
-+    def _untabify_region_event(self, event):
-+        head, tail, chars, lines = self.__get_region()
-+        tabwidth = self.__asktabwidth()
-+        for pos in range(len(lines)):
-+            lines[pos] = lines[pos].expandtabs(tabwidth)
-+        self.__set_region(head, tail, chars, lines)
-+
-+    def _toggle_tabs_event(self, event):
-+        if self.editwin.askyesno(
-+              "Toggle tabs",
-+              "Turn tabs " + ("on", "off")[self.editwin.usetabs] +
-+              "?\nIndent width " +
-+              ("will be", "remains at")[self.editwin.usetabs] + " 8." +
-+              "\n Note: a tab is always 8 columns",
-+              parent=self.text):
-+            self.editwin.usetabs = not self.editwin.usetabs
-+            # Try to prevent inconsistent indentation.
-+            # User must change indent width manually after using tabs.
-+            self.editwin.indentwidth = 8
-+        return "break"
-+
-+    def _change_indentwidth_event(self, event):
-+        new = self.editwin.askinteger(
-+                  "Indent width",
-+                  "New indent width (2-16)\n(Always use 8 when using tabs)",
-+                  parent=self.text,
-+                  initialvalue=self.editwin.indentwidth,
-+                  minvalue=2,
-+                  maxvalue=16)
-+        if new and new != self.editwin.indentwidth and not self.editwin.usetabs:
-+            self.editwin.indentwidth = new
-+        return "break"
-+
-+    def _right_menu(self, event):
-+        self.text.tag_remove("sel", "1.0", "end")
-+        self.text.mark_set("insert", "@%d,%d" % (event.x, event.y))
-+
-+        if not self.editwin.rmenu:
-+            self.__make_rmenu()
-+
-+        rmenu = self.editwin.rmenu
-+        self.event = event
-+        iswin = sys.platform[:3] == 'win'
-+        if iswin:
-+            self.text.config(cursor="arrow")
-+        rmenu.tk_popup(event.x_root, event.y_root)
-+        if iswin:
-+            self.text.config(cursor="ibeam")
-+
-+    def __make_rmenu(self):
-+        rmenu = Menu(self.text, tearoff=False)
-+
-+        for label, eventname in self.editwin.rmenu_specs:
-+            def command(text=self.text, eventname=eventname):
-+                text.event_generate(eventname)
-+            rmenu.add_command(label=label, command=command)
-+
-+        self.editwin.rmenu = rmenu
-+
-+    def __rmcolorizer(self):
-+        if not self.color:
-+            return
-+        self.color.removecolors()
-+        self.per.removefilter(self.color)
-+        self.color = None
-+
-+    def __addcolorizer(self):
-+        if self.color:
-+            return
-+        if self.editwin.ispythonsource(self.io.filename):
-+            self.color = self.editwin.ColorDelegator()
-+
-+        # can add more colorizers here...
-+        if self.color:
-+            self.per.removefilter(self.undo)
-+            self.per.insertfilter(self.color)
-+            self.per.insertfilter(self.undo)
-+
-+    def __asktabwidth(self):
-+        return self.editwin.askinteger(
-+            "Tab width",
-+            "Columns per tab? (2-16)",
-+            parent=self.text,
-+            initialvalue=self.editwin.indentwidth,
-+            minvalue=2,
-+            maxvalue=16) or self.editwin.tabwidth
-+
-+    # Make string that displays as n leading blanks.
-+    def __make_blanks(self, n):
-+        if self.editwin.usetabs:
-+            ntabs, nspaces = divmod(n, self.editwin.tabwidth)
-+            return '\t' * ntabs + ' ' * nspaces
-+        else:
-+            return ' ' * n
-+
-+    def __get_region(self):
-+        text = self.text
-+        first, last = self.get_selection_indices()
-+        if first and last:
-+            head = text.index(first + " linestart")
-+            tail = text.index(last + "-1c lineend +1c")
-+        else:
-+            head = text.index("insert linestart")
-+            tail = text.index("insert lineend +1c")
-+        chars = text.get(head, tail)
-+        lines = chars.split("\n")
-+        return head, tail, chars, lines
-+
-+    def __set_region(self, head, tail, chars, lines):
-+        text = self.text
-+        newchars = "\n".join(lines)
-+        if newchars == chars:
-+            text.bell()
-+            return
-+        text.tag_remove("sel", "1.0", "end")
-+        text.mark_set("insert", head)
-+        text.undo_block_start()
-+        text.delete(head, tail)
-+        text.insert(head, newchars)
-+        text.undo_block_stop()
-+        text.tag_add("sel", head, "insert")
-+
-+    # Delete from beginning of line to insert point, then reinsert
-+    # column logical (meaning use tabs if appropriate) spaces.
-+    def __reindent_to(self, column):
-+        text = self.text
-+        text.undo_block_start()
-+        if text.compare("insert linestart", "!=", "insert"):
-+            text.delete("insert linestart", "insert")
-+        if column:
-+            text.insert("insert", self.__make_blanks(column))
-+        text.undo_block_stop()
-+
-+    # Tk implementations of "virtual text methods" -- each platform
-+    # reusing IDLE's support code needs to define these for its GUI's
-+    # flavor of widget.
-+
-+    # Is character at text_index in a Python string?  Return 0 for
-+    # "guaranteed no", true for anything else.  This info is expensive
-+    # to compute ab initio, but is probably already known by the
-+    # platform's colorizer.
-+    def __is_char_in_string(self, text_index):
-+        if self.color:
-+            # Return true iff colorizer hasn't (re)gotten this far
-+            # yet, or the character is tagged as being in a string
-+            return self.text.tag_prevrange("TODO", text_index) or \
-+                   "STRING" in self.text.tag_names(text_index)
-+        else:
-+            # The colorizer is missing: assume the worst
-+            return 1
-Index: OutputWindow.py
-===================================================================
---- OutputWindow.py	(revision 63995)
-+++ OutputWindow.py	(revision 65541)
-@@ -1,8 +1,9 @@
--from Tkinter import *
--from EditorWindow import EditorWindow
- import re
- import tkMessageBox
-+
-+import utils
- import IOBinding
-+from EditorWindow import EditorWindow
- 
- class OutputWindow(EditorWindow):
- 
-@@ -14,8 +15,15 @@
- 
-     def __init__(self, *args):
-         EditorWindow.__init__(self, *args)
--        self.text.bind("<<goto-file-line>>", self.goto_file_line)
-+        self.top.bind("<<tab-created>>", self.__configure_new_tab)
-+        # configure the tab created in EditorWindow.__init__
-+        self.__configure_new_tab() 
- 
-+    def __configure_new_tab(self, event=None):
-+        page = self.text_notebook.last_page().editpage
-+        page.text.bind("<<goto-file-line>>", utils.callback(self.goto_file_line,
-+            page.text))
-+
-     # Customize EditorWindow
- 
-     def ispythonsource(self, filename):
-@@ -34,7 +42,8 @@
- 
-     # Act as output file
- 
--    def write(self, s, tags=(), mark="insert"):
-+    def write(self, s, tags=(), mark="insert", text=None):
-+        assert text is not None
-         # Tk assumes that byte strings are Latin-1;
-         # we assume that they are in the locale's encoding
-         if isinstance(s, str):
-@@ -43,12 +52,12 @@
-             except UnicodeError:
-                 # some other encoding; let Tcl deal with it
-                 pass
--        self.text.insert(mark, s, tags)
--        self.text.see(mark)
--        self.text.update()
-+        text.insert(mark, s, tags)
-+        text.see(mark)
-+        text.update()
- 
-     def writelines(self, l):
--        map(self.write, l)
-+        map(self.write, l, text=self.current_page.text)
- 
-     def flush(self):
-         pass
-@@ -67,28 +76,26 @@
- 
-     file_line_progs = None
- 
--    def goto_file_line(self, event=None):
-+    def goto_file_line(self, event, text):
-         if self.file_line_progs is None:
-             l = []
-             for pat in self.file_line_pats:
-                 l.append(re.compile(pat, re.IGNORECASE))
-             self.file_line_progs = l
--        # x, y = self.event.x, self.event.y
--        # self.text.mark_set("insert", "@%d,%d" % (x, y))
--        line = self.text.get("insert linestart", "insert lineend")
-+        
-+        line = text.get("insert linestart", "insert lineend")
-         result = self._file_line_helper(line)
-         if not result:
-             # Try the previous line.  This is handy e.g. in tracebacks,
-             # where you tend to right-click on the displayed source line
--            line = self.text.get("insert -1line linestart",
--                                 "insert -1line lineend")
-+            line = text.get("insert -1line linestart", "insert -1line ineend")
-             result = self._file_line_helper(line)
-             if not result:
-                 tkMessageBox.showerror(
-                     "No special line",
-                     "The line you point at doesn't look like "
-                     "a valid file name followed by a line number.",
--                    master=self.text)
-+                    master=text)
-                 return
-         filename, lineno = result
-         edit = self.flist.open(filename)
-@@ -111,47 +118,3 @@
-             return filename, int(lineno)
-         except TypeError:
-             return None
--
--# These classes are currently not used but might come in handy
--
--class OnDemandOutputWindow:
--
--    tagdefs = {
--        # XXX Should use IdlePrefs.ColorPrefs
--        "stdout":  {"foreground": "blue"},
--        "stderr":  {"foreground": "#007700"},
--    }
--
--    def __init__(self, flist):
--        self.flist = flist
--        self.owin = None
--
--    def write(self, s, tags, mark):
--        if not self.owin:
--            self.setup()
--        self.owin.write(s, tags, mark)
--
--    def setup(self):
--        self.owin = owin = OutputWindow(self.flist)
--        text = owin.text
--        for tag, cnf in self.tagdefs.items():
--            if cnf:
--                text.tag_configure(tag, **cnf)
--        text.tag_raise('sel')
--        self.write = self.owin.write
--
--#class PseudoFile:
--#
--#      def __init__(self, owin, tags, mark="end"):
--#          self.owin = owin
--#          self.tags = tags
--#          self.mark = mark
--
--#      def write(self, s):
--#          self.owin.write(s, self.tags, self.mark)
--
--#      def writelines(self, l):
--#          map(self.write, l)
--
--#      def flush(self):
--#          pass
-Index: aboutDialog.py
-===================================================================
---- aboutDialog.py	(revision 63995)
-+++ aboutDialog.py	(revision 65541)
-@@ -1,13 +1,18 @@
--"""About Dialog for IDLE
-+"""About Dialog for IDLE"""
-+import os
-+import sys
-+from Tkinter import Toplevel, Frame, Button, Label, TkVersion
-+from Tkconstants import LEFT, NSEW, SUNKEN, EW, W, BOTH, TOP, BOTTOM
- 
--"""
--
--from Tkinter import *
--import os
--import os.path
-+import idlever
- import textView
--import idlever
-+from stylist import PoorManStyle
-+from configHandler import idleConf
- 
-+TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
-+if TTK:
-+    from ttk import Frame, Button, Label, Style
-+
- class AboutDialog(Toplevel):
-     """Modal about dialog for idle
- 
-@@ -15,12 +20,15 @@
-     def __init__(self,parent,title):
-         Toplevel.__init__(self, parent)
-         self.configure(borderwidth=5)
-+
-         self.geometry("+%d+%d" % (parent.winfo_rootx()+30,
-                                   parent.winfo_rooty()+30))
-         self.bg = "#707070"
-         self.fg = "#ffffff"
-+ 
-+        self.SetupStyles()
-         self.CreateWidgets()
--        self.resizable(height=FALSE, width=FALSE)
-+        self.resizable(height=False, width=False)
-         self.title(title)
-         self.transient(parent)
-         self.grab_set()
-@@ -31,40 +39,44 @@
-         self.bind('<Escape>',self.Ok) #dismiss dialog
-         self.wait_window()
- 
-+    def SetupStyles(self):
-+        if TTK:
-+            style = Style(self.master)
-+            style.configure('Color.TLabel', foreground=self.fg,
-+                            background=self.bg)
-+            style.configure('Color.TFrame', background=self.bg)
-+            self.ttkstyle = style
-+            self.style = lambda w, style: w.configure(style=style)
-+        else:
-+            self.style = PoorManStyle(self,
-+                styles={'Color.TLabel': {'fg': self.fg, 'bg': self.bg},
-+                        'Color.TFrame': {'bg': self.bg}}).style_it
-+
-     def CreateWidgets(self):
-         frameMain = Frame(self, borderwidth=2, relief=SUNKEN)
-         frameButtons = Frame(self)
--        frameButtons.pack(side=BOTTOM, fill=X)
--        frameMain.pack(side=TOP, expand=TRUE, fill=BOTH)
--        self.buttonOk = Button(frameButtons, text='Close',
--                               command=self.Ok)
--        self.buttonOk.pack(padx=5, pady=5)
--        #self.picture = Image('photo', data=self.pictureData)
--        frameBg = Frame(frameMain, bg=self.bg)
--        frameBg.pack(expand=TRUE, fill=BOTH)
--        labelTitle = Label(frameBg, text='IDLE', fg=self.fg, bg=self.bg,
--                           font=('courier', 24, 'bold'))
-+        frameButtons.pack(side=BOTTOM, pady=3)
-+        frameMain.pack(side=TOP, expand=True, fill=BOTH)
-+        self.buttonOk = Button(frameButtons, text='Close', command=self.Ok)
-+        self.buttonOk.pack()
-+        frameBg = Frame(frameMain)
-+        frameBg.pack(expand=True, fill=BOTH)
-+        labelTitle = Label(frameBg, text='IDLE', font=('courier', 24, 'bold'))
-         labelTitle.grid(row=0, column=0, sticky=W, padx=10, pady=10)
--        #labelPicture = Label(frameBg, text='[picture]')
--        #image=self.picture, bg=self.bg)
--        #labelPicture.grid(row=1, column=1, sticky=W, rowspan=2,
--        #                  padx=0, pady=3)
-         byline = "Python's Integrated DeveLopment Environment" + 5*'\n'
--        labelDesc = Label(frameBg, text=byline, justify=LEFT,
--                          fg=self.fg, bg=self.bg)
-+        labelDesc = Label(frameBg, text=byline, justify=LEFT)
-         labelDesc.grid(row=2, column=0, sticky=W, columnspan=3, padx=10, pady=5)
-         labelEmail = Label(frameBg, text='email:  idle-dev at python.org',
--                           justify=LEFT, fg=self.fg, bg=self.bg)
-+                           justify=LEFT)
-         labelEmail.grid(row=6, column=0, columnspan=2,
-                         sticky=W, padx=10, pady=0)
-         labelWWW = Label(frameBg, text='www:  http://www.python.org/idle/',
--                         justify=LEFT, fg=self.fg, bg=self.bg)
-+                         justify=LEFT)
-         labelWWW.grid(row=7, column=0, columnspan=2, sticky=W, padx=10, pady=0)
--        Frame(frameBg, borderwidth=1, relief=SUNKEN,
--              height=2, bg=self.bg).grid(row=8, column=0, sticky=EW,
--                                         columnspan=3, padx=5, pady=5)
-+        fbg = Frame(frameBg, borderwidth=1, relief=SUNKEN,  height=2)
-+        fbg.grid(row=8, column=0, sticky=EW, columnspan=3, padx=5, pady=5)
-         labelPythonVer = Label(frameBg, text='Python version:  ' + \
--                               sys.version.split()[0], fg=self.fg, bg=self.bg)
-+                               sys.version.split()[0])
-         labelPythonVer.grid(row=9, column=0, sticky=W, padx=10, pady=0)
-         # handle weird tk version num in windoze python >= 1.6 (?!?)
-         tkVer = repr(TkVersion).split('.')
-@@ -72,44 +84,50 @@
-         if tkVer[len(tkVer)-1] == '':
-             tkVer[len(tkVer)-1] = '0'
-         tkVer = '.'.join(tkVer)
--        labelTkVer = Label(frameBg, text='Tk version:  '+
--                           tkVer, fg=self.fg, bg=self.bg)
-+        labelTkVer = Label(frameBg, text='Tk version:  '+ tkVer)
-         labelTkVer.grid(row=9, column=1, sticky=W, padx=2, pady=0)
--        py_button_f = Frame(frameBg, bg=self.bg)
-+        py_button_f = Frame(frameBg)
-         py_button_f.grid(row=10, column=0, columnspan=2, sticky=NSEW)
-         buttonLicense = Button(py_button_f, text='License', width=8,
--                               highlightbackground=self.bg,
-                                command=self.ShowLicense)
-         buttonLicense.pack(side=LEFT, padx=10, pady=10)
-         buttonCopyright = Button(py_button_f, text='Copyright', width=8,
--                                 highlightbackground=self.bg,
-                                  command=self.ShowCopyright)
-         buttonCopyright.pack(side=LEFT, padx=10, pady=10)
-         buttonCredits = Button(py_button_f, text='Credits', width=8,
--                               highlightbackground=self.bg,
-                                command=self.ShowPythonCredits)
-         buttonCredits.pack(side=LEFT, padx=10, pady=10)
--        Frame(frameBg, borderwidth=1, relief=SUNKEN,
--              height=2, bg=self.bg).grid(row=11, column=0, sticky=EW,
--                                         columnspan=3, padx=5, pady=5)
--        idle_v = Label(frameBg, text='IDLE version:   ' + idlever.IDLE_VERSION,
--                       fg=self.fg, bg=self.bg)
-+        fbg2 = Frame(frameBg, borderwidth=1, relief=SUNKEN, height=2)
-+        fbg2.grid(row=11, column=0, sticky=EW, columnspan=3, padx=5, pady=5)
-+        idle_v = Label(frameBg, text='IDLE version:   ' + idlever.IDLE_VERSION)
-         idle_v.grid(row=12, column=0, sticky=W, padx=10, pady=0)
--        idle_button_f = Frame(frameBg, bg=self.bg)
-+        idle_button_f = Frame(frameBg)
-         idle_button_f.grid(row=13, column=0, columnspan=3, sticky=NSEW)
-         idle_about_b = Button(idle_button_f, text='README', width=8,
--                                highlightbackground=self.bg,
-                                 command=self.ShowIDLEAbout)
-         idle_about_b.pack(side=LEFT, padx=10, pady=10)
-         idle_news_b = Button(idle_button_f, text='NEWS', width=8,
--                                highlightbackground=self.bg,
-                                 command=self.ShowIDLENEWS)
-         idle_news_b.pack(side=LEFT, padx=10, pady=10)
-         idle_credits_b = Button(idle_button_f, text='Credits', width=8,
--                                highlightbackground=self.bg,
-                                 command=self.ShowIDLECredits)
-         idle_credits_b.pack(side=LEFT, padx=10, pady=10)
- 
-+        s = self.style
-+        s(frameButtons, 'RootColor.TFrame')
-+        s(frameBg, 'Color.TFrame')
-+        s(labelTitle, 'Color.TLabel')
-+        s(labelDesc, 'Color.TLabel')
-+        s(labelEmail, 'Color.TLabel')
-+        s(labelWWW, 'Color.TLabel')
-+        s(fbg, 'Color.TFrame')
-+        s(labelPythonVer, 'Color.TLabel')
-+        s(labelTkVer, 'Color.TLabel')
-+        s(py_button_f, 'Color.TFrame')
-+        s(fbg2, 'Color.TFrame')
-+        s(idle_v, 'Color.TLabel')
-+        s(idle_button_f, 'Color.TFrame')
-+
-     def ShowLicense(self):
-         self.display_printer_text('About - License', license)
- 
-@@ -142,9 +160,9 @@
- 
- if __name__ == '__main__':
-     # test the dialog
-+    from Tkinter import Tk
-     root = Tk()
-     def run():
--        import aboutDialog
--        aboutDialog.AboutDialog(root, 'About')
-+        AboutDialog(root, 'About')
-     Button(root, text='Dialog', command=run).pack()
-     root.mainloop()
-Index: config-main.def
-===================================================================
---- config-main.def	(revision 63995)
-+++ config-main.def	(revision 65541)
-@@ -49,8 +49,14 @@
- print-command-posix=lpr %s
- print-command-win=start /min notepad /p %s
- delete-exitfunc= 1
-+use-ttk = 0
- 
- [EditorWindow]
-+width = 80
-+height = 40
-+file-in-tab = 1
-+
-+[EditorPage]
- width= 80
- height= 40
- font= courier
-@@ -68,6 +74,7 @@
- [Theme]
- default= 1
- name= IDLE Classic
-+displaytheme = default
- 
- [Keys]
- default= 1
-Index: PathBrowser.py
-===================================================================
---- PathBrowser.py	(revision 63995)
-+++ PathBrowser.py	(revision 65541)
-@@ -15,25 +15,29 @@
-         self.top.wm_iconname("Path Browser")
- 
-     def rootnode(self):
--        return PathBrowserTreeItem()
-+        return PathBrowserTreeItem(self.flist)
- 
- class PathBrowserTreeItem(TreeItem):
- 
-+    def __init__(self, flist):
-+        self.flist = flist
-+
-     def GetText(self):
-         return "sys.path"
- 
-     def GetSubList(self):
-         sublist = []
-         for dir in sys.path:
--            item = DirBrowserTreeItem(dir)
-+            item = DirBrowserTreeItem(dir, flist=self.flist)
-             sublist.append(item)
-         return sublist
- 
- class DirBrowserTreeItem(TreeItem):
- 
--    def __init__(self, dir, packages=[]):
-+    def __init__(self, dir, packages=[], flist=None):
-         self.dir = dir
-         self.packages = packages
-+        self.flist = flist
- 
-     def GetText(self):
-         if not self.packages:
-@@ -55,10 +59,11 @@
-         packages.sort()
-         sublist = []
-         for nn, name, file in packages:
--            item = DirBrowserTreeItem(file, self.packages + [name])
-+            item = DirBrowserTreeItem(file, self.packages + [name], self.flist)
-             sublist.append(item)
-         for nn, name in self.listmodules(names):
--            item = ModuleBrowserTreeItem(os.path.join(self.dir, name))
-+            item = ModuleBrowserTreeItem(os.path.join(self.dir, name), 
-+                self.flist)
-             sublist.append(item)
-         return sublist
- 
-Index: IOBinding.py
-===================================================================
---- IOBinding.py	(revision 63995)
-+++ IOBinding.py	(revision 65541)
-@@ -6,17 +6,20 @@
- #     which will only understand the local convention.
- 
- import os
-+import re
-+import sys
- import types
--import sys
- import codecs
- import tempfile
- import tkFileDialog
- import tkMessageBox
--import re
--from Tkinter import *
-+from Tkinter import Toplevel, Entry, Frame, Button, Label
-+from Tkconstants import W, X, TOP, LEFT, BOTH
- from SimpleDialog import SimpleDialog
- 
- from configHandler import idleConf
-+if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
-+    from ttk import Entry, Frame, Button, Label
- 
- try:
-     from codecs import BOM_UTF8
-@@ -93,11 +96,11 @@
-         # For some reason, the text is not selectable anymore if the
-         # widget is disabled.
-         # l2['state'] = DISABLED
--        l2.pack(side=TOP, anchor = W, fill=X)
-+        l2.pack(side=TOP, anchor=W, fill=X)
-         l3 = Label(top, text="to your file\n"
-                    "Choose OK to save this file as %s\n"
-                    "Edit your general options to silence this warning" % enc)
--        l3.pack(side=TOP, anchor = W)
-+        l3.pack(side=TOP, anchor=W)
- 
-         buttons = Frame(top)
-         buttons.pack(side=TOP, fill=X)
-@@ -142,10 +145,14 @@
- 
- 
- class IOBinding:
-+    filename_change_hook = None
-+    filename = None
-+    dirname = None
- 
--    def __init__(self, editwin):
--        self.editwin = editwin
--        self.text = editwin.text
-+    def __init__(self, editpage):
-+        self.editpage = editpage
-+        self.editwin = editpage.editwin
-+        self.text = editpage.text
-         self.__id_open = self.text.bind("<<open-window-from-file>>", self.open)
-         self.__id_save = self.text.bind("<<save-window>>", self.save)
-         self.__id_saveas = self.text.bind("<<save-window-as-file>>",
-@@ -163,27 +170,23 @@
-         self.text.unbind("<<save-copy-of-window-as-file>>", self.__id_savecopy)
-         self.text.unbind("<<print-window>>", self.__id_print)
-         # Break cycles
-+        self.text = None
-+        self.editpage = None
-         self.editwin = None
--        self.text = None
-         self.filename_change_hook = None
- 
-     def get_saved(self):
--        return self.editwin.get_saved()
-+        return self.editpage.get_saved()
- 
-     def set_saved(self, flag):
--        self.editwin.set_saved(flag)
-+        self.editpage.set_saved(flag)
- 
-     def reset_undo(self):
--        self.editwin.reset_undo()
-+        self.editpage.reset_undo()
- 
--    filename_change_hook = None
--
-     def set_filename_change_hook(self, hook):
-         self.filename_change_hook = hook
- 
--    filename = None
--    dirname = None
--
-     def set_filename(self, filename):
-         if filename and os.path.isdir(filename):
-             self.filename = None
-@@ -200,21 +203,33 @@
-             if not editFile:
-                 filename = self.askopenfile()
-             else:
--                filename=editFile
-+                filename = editFile
-             if filename:
-                 # If the current window has no filename and hasn't been
--                # modified, we replace its contents (no loss).  Otherwise
--                # we open a new window.  But we won't replace the
--                # shell window (which has an interp(reter) attribute), which
--                # gets set to "not modified" at every new prompt.
-+                # modified, we replace its contents (no loss). Otherwise
-+                # we open a new window, or maybe open in a tab.
-+                # But we won't replace the shell window (which has an
-+                # interp(reter) attribute), which gets set to "not modified"
-+                # at every new prompt.
-                 try:
-                     interp = self.editwin.interp
-                 except AttributeError:
-                     interp = None
-+
-                 if not self.filename and self.get_saved() and not interp:
-                     self.editwin.flist.open(filename, self.loadfile)
-                 else:
--                    self.editwin.flist.open(filename)
-+                    if idleConf.GetOption('main', 'EditorWindow',
-+                        'file-in-tab', default=1, type='bool'):
-+                        if interp:
-+                            # this is a PyShell, force file to be opened in a
-+                            # new window
-+                            action = None
-+                        else:
-+                            action = self.editwin.new_tab
-+                    else:
-+                        action = None
-+                    self.editwin.flist.open(filename, action)
-             else:
-                 self.text.focus_set()
-             return "break"
-@@ -341,8 +356,8 @@
-             if self.writefile(self.filename):
-                 self.set_saved(1)
-                 try:
--                    self.editwin.store_file_breaks()
--                except AttributeError:  # may be a PyShell
-+                    self.editwin.store_file_breaks(self.editpage)
-+                except AttributeError:  # may not be a PyShell
-                     pass
-         self.text.focus_set()
-         return "break"
-@@ -354,7 +369,7 @@
-                 self.set_filename(filename)
-                 self.set_saved(1)
-                 try:
--                    self.editwin.store_file_breaks()
-+                    self.editwin.store_file_breaks(self.editpage)
-                 except AttributeError:
-                     pass
-         self.text.focus_set()
-@@ -381,8 +396,7 @@
-             f.close()
-             return True
-         except IOError, msg:
--            tkMessageBox.showerror("I/O Error", str(msg),
--                                   master=self.text)
-+            tkMessageBox.showerror("I/O Error", str(msg), master=self.text)
-             return False
- 
-     def encode(self, chars):
-@@ -429,8 +443,7 @@
-                 return BOM_UTF8 + chars.encode("utf-8")
-         # Nothing was declared, and we had not determined an encoding
-         # on loading. Recommend an encoding line.
--        config_encoding = idleConf.GetOption("main","EditorWindow",
--                                             "encoding")
-+        config_encoding = idleConf.GetOption("main", "EditorPage", "encoding")
-         if config_encoding == 'utf-8':
-             # User has requested that we save files as UTF-8
-             return BOM_UTF8 + chars.encode("utf-8")
-@@ -563,6 +576,7 @@
-         self.editwin.update_recent_files_list(filename)
- 
- def test():
-+    from Tkinter import Tk, Text
-     root = Tk()
-     class MyEditWin:
-         def __init__(self, text):
-Index: WindowList.py
-===================================================================
---- WindowList.py	(revision 63995)
-+++ WindowList.py	(revision 65541)
-@@ -1,4 +1,4 @@
--from Tkinter import *
-+from Tkinter import Toplevel, TclError
- 
- class WindowList:
- 
-@@ -45,8 +45,8 @@
-             try:
-                 callback()
-             except:
--                print "warning: callback failed in WindowList", \
--                      sys.exc_type, ":", sys.exc_value
-+                print ("warning: callback failed in WindowList",
-+                    sys.exc_type, ":", sys.exc_value)
- 
- registry = WindowList()
- 
-Index: ScrolledList.py
-===================================================================
---- ScrolledList.py	(revision 63995)
-+++ ScrolledList.py	(revision 65541)
-@@ -1,5 +1,9 @@
--from Tkinter import *
-+from Tkinter import Frame, Menu, Listbox, Scrollbar
-+from idlelib.configHandler import idleConf
- 
-+if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
-+    from ttk import Frame, Scrollbar
-+
- class ScrolledList:
- 
-     default = "(None)"
-@@ -120,6 +124,7 @@
- 
- 
- def test():
-+    from Tkinter import Tk
-     root = Tk()
-     root.protocol("WM_DELETE_WINDOW", root.destroy)
-     class MyScrolledList(ScrolledList):
-Index: ClassBrowser.py
-===================================================================
---- ClassBrowser.py	(revision 63995)
-+++ ClassBrowser.py	(revision 65541)
-@@ -14,7 +14,6 @@
- import sys
- import pyclbr
- 
--import PyShell
- from WindowList import ListedToplevel
- from TreeWidget import TreeNode, TreeItem, ScrolledCanvas
- from configHandler import idleConf
-@@ -26,6 +25,7 @@
-         # XXX the code here is bogus!
-         self.name = name
-         self.file = os.path.join(path[0], self.name + ".py")
-+        self.flist = None
-         self.init(flist)
- 
-     def close(self, event=None):
-@@ -57,12 +57,13 @@
-         self.top.wm_iconname("Class Browser")
- 
-     def rootnode(self):
--        return ModuleBrowserTreeItem(self.file)
-+        return ModuleBrowserTreeItem(self.file, self.flist)
- 
- class ModuleBrowserTreeItem(TreeItem):
- 
--    def __init__(self, file):
-+    def __init__(self, file, flist):
-         self.file = file
-+        self.flist = flist
- 
-     def GetText(self):
-         return os.path.basename(self.file)
-@@ -73,7 +74,8 @@
-     def GetSubList(self):
-         sublist = []
-         for name in self.listclasses():
--            item = ClassBrowserTreeItem(name, self.classes, self.file)
-+            item = ClassBrowserTreeItem(name, self.classes, self.file, 
-+                self.flist)
-             sublist.append(item)
-         return sublist
- 
-@@ -82,7 +84,7 @@
-             return
-         if not os.path.exists(self.file):
-             return
--        PyShell.flist.open(self.file)
-+        self.flist.open(self.file)
- 
-     def IsExpandable(self):
-         return os.path.normcase(self.file[-3:]) == ".py"
-@@ -122,10 +124,11 @@
- 
- class ClassBrowserTreeItem(TreeItem):
- 
--    def __init__(self, name, classes, file):
-+    def __init__(self, name, classes, file, flist):
-         self.name = name
-         self.classes = classes
-         self.file = file
-+        self.flist = flist
-         try:
-             self.cl = self.classes[self.name]
-         except (IndexError, KeyError):
-@@ -163,7 +166,7 @@
-     def OnDoubleClick(self):
-         if not os.path.exists(self.file):
-             return
--        edit = PyShell.flist.open(self.file)
-+        edit = self.flist.open(self.file)
-         if hasattr(self.cl, 'lineno'):
-             lineno = self.cl.lineno
-             edit.gotoline(lineno)
-@@ -199,10 +202,11 @@
-     def OnDoubleClick(self):
-         if not os.path.exists(self.file):
-             return
--        edit = PyShell.flist.open(self.file)
-+        edit = self.flist.open(self.file)
-         edit.gotoline(self.cl.methods[self.name])
- 
- def main():
-+    import PyShell
-     try:
-         file = __file__
-     except NameError:
-Index: FileList.py
-===================================================================
---- FileList.py	(revision 63995)
-+++ FileList.py	(revision 65541)
-@@ -1,7 +1,15 @@
- import os
--from Tkinter import *
- import tkMessageBox
- 
-+def _canonize(filename):
-+    if not os.path.isabs(filename):
-+        try:
-+            pwd = os.getcwd()
-+        except os.error:
-+            pass
-+        else:
-+            filename = os.path.join(pwd, filename)
-+    return os.path.normpath(filename)
- 
- class FileList:
- 
-@@ -16,7 +24,7 @@
- 
-     def open(self, filename, action=None):
-         assert filename
--        filename = self.canonize(filename)
-+        filename = _canonize(filename)
-         if os.path.isdir(filename):
-             # This can happen when bad filename is passed on command line:
-             tkMessageBox.showerror(
-@@ -29,9 +37,10 @@
-             edit = self.dict[key]
-             edit.top.wakeup()
-             return edit
-+
-         if action:
-             # Don't create window, perform 'action', e.g. open in same window
--            return action(filename)
-+            return action(filename=filename)
-         else:
-             return self.EditorWindow(self, filename, key)
- 
-@@ -62,20 +71,20 @@
-         if not self.inversedict:
-             self.root.quit()
- 
--    def filename_changed_edit(self, edit):
--        edit.saved_change_hook()
-+    def filename_changed_edit(self, page, editwin):
-+        page.saved_change_hook(page.tab_initialized)
-         try:
--            key = self.inversedict[edit]
-+            key = self.inversedict[editwin]
-         except KeyError:
-             print "Don't know this EditorWindow object.  (rename)"
-             return
--        filename = edit.io.filename
-+        filename = page.io.filename
-         if not filename:
-             if key:
-                 del self.dict[key]
--            self.inversedict[edit] = None
-+            self.inversedict[editwin] = None
-             return
--        filename = self.canonize(filename)
-+        filename = _canonize(filename)
-         newkey = os.path.normcase(filename)
-         if newkey == key:
-             return
-@@ -86,28 +95,19 @@
-                 "Name Conflict",
-                 "You now have multiple edit windows open for %r" % (filename,),
-                 master=self.root)
--        self.dict[newkey] = edit
--        self.inversedict[edit] = newkey
-+        self.dict[newkey] = editwin
-+        self.inversedict[editwin] = newkey
-         if key:
-             try:
-                 del self.dict[key]
-             except KeyError:
-                 pass
- 
--    def canonize(self, filename):
--        if not os.path.isabs(filename):
--            try:
--                pwd = os.getcwd()
--            except os.error:
--                pass
--            else:
--                filename = os.path.join(pwd, filename)
--        return os.path.normpath(filename)
- 
--
- def _test():
-+    import sys
-+    from Tkinter import Tk
-     from EditorWindow import fixwordbreaks
--    import sys
-     root = Tk()
-     fixwordbreaks(root)
-     root.withdraw()
-Index: CallTips.py
-===================================================================
---- CallTips.py	(revision 63995)
-+++ CallTips.py	(revision 65541)
-@@ -22,12 +22,12 @@
-         ])
-     ]
- 
--    def __init__(self, editwin=None):
--        if editwin is None:  # subprocess and test
--            self.editwin = None
-+    def __init__(self, editpage=None):
-+        if editpage is None:  # subprocess and test
-+            self.editpage = None
-             return
--        self.editwin = editwin
--        self.text = editwin.text
-+        self.editpage = editpage
-+        self.text = editpage.text
-         self.calltip = None
-         self._make_calltip_window = self._make_tk_calltip_window
- 
-@@ -66,7 +66,7 @@
-     def open_calltip(self, evalfuncs):
-         self._remove_calltip_window()
- 
--        hp = HyperParser(self.editwin, "insert")
-+        hp = HyperParser(self.editpage, "insert")
-         sur_paren = hp.get_surrounding_brackets('(')
-         if not sur_paren:
-             return
-@@ -95,7 +95,7 @@
- 
-         """
-         try:
--            rpcclt = self.editwin.flist.pyshell.interp.rpcclt
-+            rpcclt = self.editpage.editwin.flist.pyshell.interp.rpcclt
-         except:
-             rpcclt = None
-         if rpcclt:
-Index: CodeContext.py
-===================================================================
---- CodeContext.py	(revision 63995)
-+++ CodeContext.py	(revision 65541)
-@@ -23,7 +23,7 @@
- getspacesfirstword =\
-                    lambda s, c=re.compile(r"^(\s*)(\w*)"): c.match(s).groups()
- 
--class CodeContext:
-+class CodeContext(object):
-     menudefs = [('options', [('!Code Conte_xt', '<<toggle-code-context>>')])]
-     context_depth = idleConf.GetOption("extensions", "CodeContext",
-                                        "numlines", type="int", default=3)
-@@ -31,10 +31,10 @@
-                                  "bgcolor", type="str", default="LightGray")
-     fgcolor = idleConf.GetOption("extensions", "CodeContext",
-                                  "fgcolor", type="str", default="Black")
--    def __init__(self, editwin):
--        self.editwin = editwin
--        self.text = editwin.text
--        self.textfont = self.text["font"]
-+
-+    def __init__(self, editpage):
-+        self.editpage = editpage
-+        self.editwin = editpage.editwin
-         self.label = None
-         # self.info is a list of (line number, indent level, line text, block
-         # keyword) tuples providing the block structure associated with
-@@ -43,14 +43,11 @@
-         # starts the toplevel 'block' of the module.
-         self.info = [(0, -1, "", False)]
-         self.topvisible = 1
--        visible = idleConf.GetOption("extensions", "CodeContext",
--                                     "visible", type="bool", default=False)
-+        visible = idleConf.GetOption("extensions", "CodeContext", "visible",
-+            type="bool", default=False)
-         if visible:
-             self.toggle_code_context_event()
-             self.editwin.setvar('<<toggle-code-context>>', True)
--        # Start two update cycles, one for context lines, one for font changes.
--        self.text.after(UPDATEINTERVAL, self.timer_event)
--        self.text.after(FONTUPDATEINTERVAL, self.font_timer_event)
- 
-     def toggle_code_context_event(self, event=None):
-         if not self.label:
-@@ -59,33 +56,27 @@
-             #
-             # All values are passed through int(str(<value>)), since some
-             # values may be pixel objects, which can't simply be added to ints.
--            widgets = self.editwin.text, self.editwin.text_frame
--            # Calculate the required vertical padding
--            padx = 0
--            for widget in widgets:
--                padx += int(str( widget.pack_info()['padx'] ))
--                padx += int(str( widget.cget('padx') ))
--            # Calculate the required border width
--            border = 0
--            for widget in widgets:
--                border += int(str( widget.cget('border') ))
-+
-+            # Calculate the required horizontal padding
-+            padx = int(str(self.editwin.text_notebook.pack_info()['padx']))
-+
-             self.label = Tkinter.Label(self.editwin.top,
-                                        text="\n" * (self.context_depth - 1),
-                                        anchor=W, justify=LEFT,
-                                        font=self.textfont,
-                                        bg=self.bgcolor, fg=self.fgcolor,
-                                        width=1, #don't request more than we get
--                                       padx=padx, border=border,
-+                                       padx=padx,
-                                        relief=SUNKEN)
--            # Pack the label widget before and above the text_frame widget,
--            # thus ensuring that it will appear directly above text_frame
-+            # Pack the label widget before and above the text_notebook widget,
-+            # thus ensuring that it will appear directly above text_notebook
-             self.label.pack(side=TOP, fill=X, expand=False,
--                            before=self.editwin.text_frame)
-+                before=self.editwin.text_notebook)
-         else:
-             self.label.destroy()
-             self.label = None
-         idleConf.SetOption("extensions", "CodeContext", "visible",
--                           str(self.label is not None))
-+            str(self.label is not None))
-         idleConf.SaveUserCfgFiles()
- 
-     def get_line_info(self, linenum):
-@@ -132,15 +123,12 @@
-         return lines, lastindent
- 
-     def update_code_context(self):
--        """Update context information and lines visible in the context pane.
--
--        """
-+        """Update context information and lines visible in the context pane."""
-         new_topvisible = int(self.text.index("@0,0").split('.')[0])
-         if self.topvisible == new_topvisible:      # haven't scrolled
-             return
-         if self.topvisible < new_topvisible:       # scroll down
--            lines, lastindent = self.get_context(new_topvisible,
--                                                 self.topvisible)
-+            lines, lastindent = self.get_context(new_topvisible, self.topvisible)
-             # retain only context info applicable to the region
-             # between topvisible and new_topvisible:
-             while self.info[-1][1] >= lastindent:
-@@ -153,8 +141,7 @@
-                 stopindent = self.info[-1][1]
-                 del self.info[-1]
-             lines, lastindent = self.get_context(new_topvisible,
--                                                 self.info[-1][0]+1,
--                                                 stopindent)
-+                self.info[-1][0] + 1, stopindent)
-         self.info.extend(lines)
-         self.topvisible = new_topvisible
-         # empty lines in context pane:
-@@ -174,3 +161,18 @@
-             self.textfont = newtextfont
-             self.label["font"] = self.textfont
-         self.text.after(FONTUPDATEINTERVAL, self.font_timer_event)
-+
-+    # Private methods
-+
-+    def _get_editpage(self):
-+        return self._editpage
-+
-+    def _set_editpage(self, page):
-+        self._editpage = page
-+        self.text = page.text
-+        self.textfont = self.text["font"]
-+        # Start two update cycles, one for context lines, one for font changes.
-+        self.text.after(UPDATEINTERVAL, self.timer_event)
-+        self.text.after(FONTUPDATEINTERVAL, self.font_timer_event)
-+
-+    editpage = property(_get_editpage, _set_editpage)
-Index: textView.py
-===================================================================
---- textView.py	(revision 63995)
-+++ textView.py	(revision 65541)
-@@ -1,10 +1,16 @@
--"""Simple text browser for IDLE
-+"""Simple text browser for IDLE"""
- 
--"""
--
--from Tkinter import *
- import tkMessageBox
-+from Tkinter import Toplevel, Frame, Button, Scrollbar, Text
-+from Tkconstants import DISABLED, SUNKEN, VERTICAL, WORD, RIGHT, Y, TOP, \
-+                        LEFT, BOTH, BOTTOM
- 
-+from configHandler import idleConf
-+
-+TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
-+if TTK:
-+    from ttk import Frame, Button, Scrollbar
-+
- class TextViewer(Toplevel):
-     """A simple text viewer dialog for IDLE
- 
-@@ -40,19 +46,22 @@
-         frameText = Frame(self, relief=SUNKEN, height=700)
-         frameButtons = Frame(self)
-         self.buttonOk = Button(frameButtons, text='Close',
--                               command=self.Ok, takefocus=FALSE)
-+                               command=self.Ok, takefocus=False)
-         self.scrollbarView = Scrollbar(frameText, orient=VERTICAL,
--                                       takefocus=FALSE, highlightthickness=0)
--        self.textView = Text(frameText, wrap=WORD, highlightthickness=0,
--                             fg=self.fg, bg=self.bg)
-+                                       takefocus=False)
-+        self.textView = Text(frameText, wrap=WORD, fg=self.fg, bg=self.bg,
-+                             highlightthickness=0)
-         self.scrollbarView.config(command=self.textView.yview)
-         self.textView.config(yscrollcommand=self.scrollbarView.set)
-         self.buttonOk.pack()
-         self.scrollbarView.pack(side=RIGHT,fill=Y)
--        self.textView.pack(side=LEFT,expand=TRUE,fill=BOTH)
--        frameButtons.pack(side=BOTTOM,fill=X)
--        frameText.pack(side=TOP,expand=TRUE,fill=BOTH)
-+        self.textView.pack(side=LEFT,expand=True,fill=BOTH)
-+        frameButtons.pack(side=BOTTOM)
-+        frameText.pack(side=TOP,expand=True,fill=BOTH)
- 
-+        if TTK:
-+            frameButtons['style'] = 'RootColor.TFrame'
-+
-     def Ok(self, event=None):
-         self.destroy()
- 
-@@ -68,7 +77,6 @@
-         else:
-             textFile = open(filename, 'r')
-     except IOError:
--        import tkMessageBox
-         tkMessageBox.showerror(title='File Load Error',
-                                message='Unable to load file %r .' % filename,
-                                parent=parent)
-@@ -77,6 +85,7 @@
- 
- 
- if __name__ == '__main__':
-+    from Tkinter import Tk
-     #test the dialog
-     root=Tk()
-     root.title('textView test')
-Index: SearchDialogBase.py
-===================================================================
---- SearchDialogBase.py	(revision 63995)
-+++ SearchDialogBase.py	(revision 65541)
-@@ -1,35 +1,42 @@
--from Tkinter import *
-+from Tkinter import Toplevel, Frame, Label, Entry, Button, Checkbutton, \
-+                    Radiobutton
- 
-+from configHandler import idleConf
-+
-+if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
-+    from ttk import Frame, Label, Entry, Button, Checkbutton, Radiobutton
-+
- class SearchDialogBase:
- 
-     title = "Search Dialog"
-     icon = "Search"
-     needwrapbutton = 1
-+    bottom_btns = None
- 
-     def __init__(self, root, engine):
-         self.root = root
-         self.engine = engine
--        self.top = None
-+        self.ttop = None
- 
-     def open(self, text, searchphrase=None):
-         self.text = text
--        if not self.top:
-+        if not self.ttop:
-             self.create_widgets()
-         else:
--            self.top.deiconify()
--            self.top.tkraise()
-+            self.ttop.deiconify()
-+            self.ttop.tkraise()
-         if searchphrase:
--            self.ent.delete(0,"end")
--            self.ent.insert("end",searchphrase)
-+            self.ent.delete(0, "end")
-+            self.ent.insert("end", searchphrase)
-         self.ent.focus_set()
-         self.ent.selection_range(0, "end")
-         self.ent.icursor(0)
--        self.top.grab_set()
-+        self.ttop.grab_set()
- 
-     def close(self, event=None):
--        if self.top:
--            self.top.grab_release()
--            self.top.withdraw()
-+        if self.ttop:
-+            self.ttop.grab_release()
-+            self.ttop.withdraw()
- 
-     def create_widgets(self):
-         top = Toplevel(self.root)
-@@ -38,103 +45,96 @@
-         top.protocol("WM_DELETE_WINDOW", self.close)
-         top.wm_title(self.title)
-         top.wm_iconname(self.icon)
--        self.top = top
-+        top.resizable(height=False, width=False)
-+        self.ttop = top
-+        self.top = Frame(top)
- 
-         self.row = 0
--        self.top.grid_columnconfigure(0, pad=2, weight=0)
--        self.top.grid_columnconfigure(1, pad=2, minsize=100, weight=100)
-+        self.top.grid(sticky='news')
- 
-         self.create_entries()
-         self.create_option_buttons()
-         self.create_other_buttons()
--        return self.create_command_buttons()
-+        self.create_command_buttons()
- 
-+
-     def make_entry(self, label, var):
-         l = Label(self.top, text=label)
--        l.grid(row=self.row, column=0, sticky="nw")
-+        l.grid(row=self.row, column=0, sticky="ne", padx=6, pady=6)
-         e = Entry(self.top, textvariable=var, exportselection=0)
--        e.grid(row=self.row, column=1, sticky="nwe")
-+        e.grid(row=self.row, column=1, sticky="nwe", padx=6, pady=6)
-         self.row = self.row + 1
-         return e
- 
-     def make_frame(self,labeltext=None):
-         if labeltext:
-             l = Label(self.top, text=labeltext)
--            l.grid(row=self.row, column=0, sticky="nw")
-+            l.grid(row=self.row, column=0, sticky="ne", padx=6, pady=6)
-         f = Frame(self.top)
--        f.grid(row=self.row, column=1, columnspan=1, sticky="nwe")
-+        f.grid(row=self.row, column=1, columnspan=1, sticky="nwe",
-+               padx=6, pady=6 if labeltext else 0)
-         self.row = self.row + 1
-         return f
- 
--    def make_button(self, label, command, isdef=0):
--        b = Button(self.buttonframe,
--                   text=label, command=command,
--                   default=isdef and "active" or "normal")
--        cols,rows=self.buttonframe.grid_size()
--        b.grid(pady=1,row=rows,column=0,sticky="ew")
--        self.buttonframe.grid(rowspan=rows+1)
--        return b
--
-     def create_entries(self):
--        self.ent = self.make_entry("Find:", self.engine.patvar)
-+        self.ent = self.make_entry("Find", self.engine.patvar)
- 
-     def create_option_buttons(self):
-         f = self.make_frame("Options")
- 
--        btn = Checkbutton(f, anchor="w",
--                variable=self.engine.revar,
--                text="Regular expression")
-+        btn = Checkbutton(f, variable=self.engine.revar,
-+                          text="Regular expression")
-         btn.pack(side="left", fill="both")
-         if self.engine.isre():
--            btn.select()
-+            btn.invoke()
- 
--        btn = Checkbutton(f, anchor="w",
--                variable=self.engine.casevar,
--                text="Match case")
-+        btn = Checkbutton(f, variable=self.engine.casevar, text="Match case")
-         btn.pack(side="left", fill="both")
-         if self.engine.iscase():
--            btn.select()
-+            btn.invoke()
- 
--        btn = Checkbutton(f, anchor="w",
--                variable=self.engine.wordvar,
--                text="Whole word")
-+        btn = Checkbutton(f, variable=self.engine.wordvar, text="Whole word")
-         btn.pack(side="left", fill="both")
-         if self.engine.isword():
--            btn.select()
-+            btn.invoke()
- 
-         if self.needwrapbutton:
--            btn = Checkbutton(f, anchor="w",
--                    variable=self.engine.wrapvar,
--                    text="Wrap around")
-+            btn = Checkbutton(f, variable=self.engine.wrapvar,
-+                              text="Wrap around")
-             btn.pack(side="left", fill="both")
-             if self.engine.iswrap():
--                btn.select()
-+                btn.invoke()
- 
-     def create_other_buttons(self):
-         f = self.make_frame("Direction")
- 
--        #lbl = Label(f, text="Direction: ")
--        #lbl.pack(side="left")
--
--        btn = Radiobutton(f, anchor="w",
--                variable=self.engine.backvar, value=1,
--                text="Up")
--        btn.pack(side="left", fill="both")
-+        btn = Radiobutton(f, variable=self.engine.backvar, value=1, text="Up")
-+        btn.pack(side="left")
-         if self.engine.isback():
--            btn.select()
-+            btn.invoke()
- 
--        btn = Radiobutton(f, anchor="w",
--                variable=self.engine.backvar, value=0,
--                text="Down")
--        btn.pack(side="left", fill="both")
-+        btn = Radiobutton(f, variable=self.engine.backvar, value=0, text="Down")
-+        btn.pack(side="left")
-         if not self.engine.isback():
--            btn.select()
-+            btn.invoke()
- 
-     def create_command_buttons(self):
--        #
--        # place button frame on the right
--        f = self.buttonframe = Frame(self.top)
--        f.grid(row=0,column=2,padx=2,pady=2,ipadx=2,ipady=2)
-+        self.bottom_btns = self.bottom_btns or []
-+        f = Frame(self.top)
-+        f.grid(row=self.row, column=0, columnspan=len(self.bottom_btns) + 1,
-+               pady=6)
- 
--        b = self.make_button("close", self.close)
--        b.lower()
-+        column = 0
-+        b = Button(f, text="Close", command=self.close)
-+        b.grid(row=self.row, column=column, padx=6, pady=6)
-+        column += 1
-+
-+        btns = {}
-+        for tbtn in self.bottom_btns:
-+            opts = {'text': tbtn[0], 'command': getattr(self, tbtn[1])}
-+            if len(tbtn) == 3:
-+                opts['default'] = tbtn[2] and 'active' or 'normal'
-+
-+            btns[opts['text']] = Button(f, **opts).grid(row=self.row, padx=6,
-+                                                        pady=6, column=column)
-+            column += 1
-Index: CallTipWindow.py
-===================================================================
---- CallTipWindow.py	(revision 63995)
-+++ CallTipWindow.py	(revision 65541)
-@@ -4,8 +4,14 @@
- Used by the CallTips IDLE extension.
- 
- """
--from Tkinter import *
-+from Tkinter import Toplevel, Label, TclError
-+from Tkconstants import SOLID, LEFT
- 
-+from configHandler import idleConf
-+
-+if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
-+    from ttk import Label
-+
- HIDE_VIRTUAL_EVENT_NAME = "<<calltipwindow-hide>>"
- HIDE_SEQUENCES = ("<Key-Escape>", "<FocusOut>")
- CHECKHIDE_VIRTUAL_EVENT_NAME = "<<calltipwindow-checkhide>>"
-@@ -142,6 +148,8 @@
- #
- class container: # Conceptually an editor_window
-     def __init__(self):
-+        from Tkinter import Tk, Text
-+        from Tkconstants import BOTH
-         root = Tk()
-         text = self.text = Text(root)
-         text.pack(side=LEFT, fill=BOTH, expand=1)
-@@ -163,6 +171,8 @@
-     def calltip_hide(self, event):
-         self.calltip.hidetip()
- 
-+# XXX Bugged test
-+
- def main():
-     # Test code
-     c=container()
-Index: SearchDialog.py
-===================================================================
---- SearchDialog.py	(revision 63995)
-+++ SearchDialog.py	(revision 65541)
-@@ -1,8 +1,8 @@
--from Tkinter import *
-+from Tkinter import TclError
-+
- import SearchEngine
- from SearchDialogBase import SearchDialogBase
- 
--
- def _setup(text):
-     root = text._root()
-     engine = SearchEngine.get(root)
-@@ -12,7 +12,7 @@
- 
- def find(text):
-     pat = text.get("sel.first", "sel.last")
--    return _setup(text).open(text,pat)
-+    return _setup(text).open(text, pat)
- 
- def find_again(text):
-     return _setup(text).find_again(text)
-@@ -21,10 +21,10 @@
-     return _setup(text).find_selection(text)
- 
- class SearchDialog(SearchDialogBase):
-+    bottom_btns = [("Find", 'default_command', 1)]
- 
-     def create_widgets(self):
--        f = SearchDialogBase.create_widgets(self)
--        self.make_button("Find", self.default_command, 1)
-+        SearchDialogBase.create_widgets(self)
- 
-     def default_command(self, event=None):
-         if not self.engine.getprog():
-Index: idlever.py
-===================================================================
---- idlever.py	(revision 63995)
-+++ idlever.py	(revision 65541)
-@@ -1 +1 @@
--IDLE_VERSION = "2.6a3"
-+IDLE_VERSION = "2.6a3-gpolo"
-Index: tabbedpages_old.py
-===================================================================
---- tabbedpages_old.py	(revision 0)
-+++ tabbedpages_old.py	(revision 65541)
-@@ -0,0 +1,546 @@
-+"""An implementation of tabbed pages using only standard Tkinter.
-+
-+Originally developed for use in IDLE. Based on tabpage.py.
-+
-+Classes exported:
-+TabbedPageSet -- A Tkinter implementation of a tabbed-page widget.
-+TabSet -- A widget containing tabs (buttons) in one or more rows.
-+
-+"""
-+from Tkinter import Frame, Radiobutton
-+from Tkconstants import BOTH, TOP, X, RAISED, NSEW, FLAT, LEFT
-+
-+from tabbedpages import InvalidNameError, AlreadyExistsError
-+
-+
-+class TabSet(Frame):
-+    """A widget containing tabs (buttons) in one or more rows.
-+
-+    Only one tab may be selected at a time.
-+
-+    """
-+    def __init__(self, page_set, select_command,
-+                 tabs=None, n_rows=1, max_tabs_per_row=5,
-+                 expand_tabs=False, **kw):
-+        """Constructor arguments:
-+
-+        select_command -- A callable which will be called when a tab is
-+        selected. It is called with the name of the selected tab as an
-+        argument.
-+
-+        tabs -- A list of strings, the names of the tabs. Should be specified in
-+        the desired tab order. The first tab will be the default and first
-+        active tab. If tabs is None or empty, the TabSet will be initialized
-+        empty.
-+
-+        n_rows -- Number of rows of tabs to be shown. If n_rows <= 0 or is
-+        None, then the number of rows will be decided by TabSet. See
-+        _arrange_tabs() for details.
-+
-+        max_tabs_per_row -- Used for deciding how many rows of tabs are needed,
-+        when the number of rows is not constant. See _arrange_tabs() for
-+        details.
-+
-+        """
-+        Frame.__init__(self, page_set, **kw)
-+        self.select_command = select_command
-+        self.n_rows = n_rows
-+        self.max_tabs_per_row = max_tabs_per_row
-+        self.expand_tabs = expand_tabs
-+        self.page_set = page_set
-+
-+        self._tabs = {}
-+        self._tab2row = {}
-+        if tabs:
-+            self._tab_names = list(tabs)
-+        else:
-+            self._tab_names = []
-+        self._selected_tab = None
-+        self._tab_rows = []
-+
-+        self.padding_frame = Frame(self, height=2,
-+                                   borderwidth=0, relief=FLAT,
-+                                   background=self.cget('background'))
-+        self.padding_frame.pack(side=TOP, fill=X, expand=False)
-+
-+        self._arrange_tabs()
-+
-+    def add_tab(self, tab_name):
-+        """Add a new tab with the name given in tab_name."""
-+        if not tab_name:
-+            raise InvalidNameError("Invalid Tab name: '%s'" % tab_name)
-+        if tab_name in self._tab_names:
-+            raise AlreadyExistsError("Tab named '%s' already exists" %tab_name)
-+
-+        self._tab_names.append(tab_name)
-+        self._arrange_tabs()
-+
-+    def remove_tab(self, tab_name):
-+        """Remove the tab named <tab_name>"""
-+        if not tab_name in self._tab_names:
-+            raise KeyError("No such Tab: '%s" % tab_name)
-+
-+        self._tab_names.remove(tab_name)
-+        self._arrange_tabs()
-+
-+    def set_selected_tab(self, tab_name):
-+        """Show the tab named <tab_name> as the selected one"""
-+        if tab_name == self._selected_tab:
-+            return
-+        if tab_name is not None and tab_name not in self._tabs:
-+            raise KeyError("No such Tab: '%s" % tab_name)
-+
-+        # deselect the current selected tab
-+        if self._selected_tab is not None:
-+            self._tabs[self._selected_tab].set_normal()
-+        self._selected_tab = None
-+
-+        if tab_name is not None:
-+            # activate the tab named tab_name
-+            self._selected_tab = tab_name
-+            tab = self._tabs[tab_name]
-+            tab.set_selected()
-+            # move the tab row with the selected tab to the bottom
-+            tab_row = self._tab2row[tab]
-+            tab_row.pack_forget()
-+            tab_row.pack(side=TOP, fill=X, expand=0)
-+
-+    def _add_tab_row(self, tab_names, expand_tabs):
-+        if not tab_names:
-+            return
-+
-+        tab_row = Frame(self)
-+        tab_row.pack(side=TOP, fill=X, expand=0)
-+        self._tab_rows.append(tab_row)
-+
-+        for tab_name in tab_names:
-+            tab = TabSet.TabButton(tab_name, self.select_command,
-+                                   tab_row, self)
-+            if expand_tabs:
-+                tab.pack(side=LEFT, fill=X, expand=True)
-+            else:
-+                tab.pack(side=LEFT)
-+            self._tabs[tab_name] = tab
-+            self._tab2row[tab] = tab_row
-+
-+        # tab is the last one created in the above loop
-+        tab.is_last_in_row = True
-+
-+    def _reset_tab_rows(self):
-+        while self._tab_rows:
-+            tab_row = self._tab_rows.pop()
-+            tab_row.destroy()
-+        self._tab2row = {}
-+
-+    def _arrange_tabs(self):
-+        """
-+        Arrange the tabs in rows, in the order in which they were added.
-+
-+        If n_rows >= 1, this will be the number of rows used. Otherwise the
-+        number of rows will be calculated according to the number of tabs and
-+        max_tabs_per_row. In this case, the number of rows may change when
-+        adding/removing tabs.
-+
-+        """
-+        # remove all tabs and rows
-+        while self._tabs:
-+            self._tabs.popitem()[1].destroy()
-+        self._reset_tab_rows()
-+
-+        if not self._tab_names:
-+            return
-+
-+        if self.n_rows is not None and self.n_rows > 0:
-+            n_rows = self.n_rows
-+        else:
-+            # calculate the required number of rows
-+            n_rows = (len(self._tab_names) - 1) // self.max_tabs_per_row + 1
-+
-+        # not expanding the tabs with more than one row is very ugly
-+        expand_tabs = self.expand_tabs or n_rows > 1
-+        i = 0 # index in self._tab_names
-+        for row_index in range(n_rows):
-+            # calculate required number of tabs in this row
-+            n_tabs = (len(self._tab_names) - i - 1) // (n_rows - row_index) + 1
-+            tab_names = self._tab_names[i:i + n_tabs]
-+            i += n_tabs
-+            self._add_tab_row(tab_names, expand_tabs)
-+
-+        # re-select selected tab so it is properly displayed
-+        selected = self._selected_tab
-+        self.set_selected_tab(None)
-+        if selected in self._tab_names:
-+            self.set_selected_tab(selected)
-+
-+    class TabButton(Frame):
-+        """A simple tab-like widget."""
-+
-+        bw = 2 # borderwidth
-+
-+        def __init__(self, name, select_command, tab_row, tab_set):
-+            """Constructor arguments:
-+
-+            name -- The tab's name, which will appear in its button.
-+
-+            select_command -- The command to be called upon selection of the
-+            tab. It is called with the tab's name as an argument.
-+
-+            """
-+            Frame.__init__(self, tab_row, borderwidth=self.bw, relief=RAISED)
-+
-+            self.name = name
-+            self.select_command = select_command
-+            self.tab_set = tab_set
-+            self.is_last_in_row = False
-+
-+            self.button = Radiobutton(
-+                self, text=name, command=self._select_event,
-+                padx=5, pady=1, takefocus=False, indicatoron=False,
-+                highlightthickness=0, selectcolor='', borderwidth=0)
-+            self.button.pack(side=LEFT, fill=X, expand=True)
-+
-+            self._init_masks()
-+            self.set_normal()
-+
-+        def _select_event(self, *args):
-+            """Event handler for tab selection.
-+
-+            With TabbedPageSet, this calls TabbedPageSet.change_page, so that
-+            selecting a tab changes the page.
-+
-+            Note that this does -not- call set_selected -- it will be called by
-+            TabSet.set_selected_tab, which should be called when whatever the
-+            tabs are related to changes.
-+
-+            """
-+            self.select_command(self.name)
-+            return
-+
-+        def set_selected(self):
-+            """Assume selected look"""
-+            self._place_masks(selected=True)
-+
-+        def set_normal(self):
-+            """Assume normal look"""
-+            self._place_masks(selected=False)
-+
-+        def _init_masks(self):
-+            page_set = self.tab_set.page_set
-+            background = page_set.pages_frame.cget('background')
-+            # mask replaces the middle of the border with the background color
-+            self.mask = Frame(page_set, borderwidth=0, relief=FLAT,
-+                              background=background)
-+            # mskl replaces the bottom-left corner of the border with a normal
-+            # left border
-+            self.mskl = Frame(page_set, borderwidth=0, relief=FLAT,
-+                              background=background)
-+            self.mskl.ml = Frame(self.mskl, borderwidth=self.bw,
-+                                 relief=RAISED)
-+            self.mskl.ml.place(x=0, y=-self.bw,
-+                               width=2*self.bw, height=self.bw*4)
-+            # mskr replaces the bottom-right corner of the border with a normal
-+            # right border
-+            self.mskr = Frame(page_set, borderwidth=0, relief=FLAT,
-+                              background=background)
-+            self.mskr.mr = Frame(self.mskr, borderwidth=self.bw,
-+                                 relief=RAISED)
-+
-+        def _place_masks(self, selected=False):
-+            height = self.bw
-+            if selected:
-+                height += self.bw
-+
-+            self.mask.place(in_=self,
-+                            relx=0.0, x=0,
-+                            rely=1.0, y=0,
-+                            relwidth=1.0, width=0,
-+                            relheight=0.0, height=height)
-+
-+            self.mskl.place(in_=self,
-+                            relx=0.0, x=-self.bw,
-+                            rely=1.0, y=0,
-+                            relwidth=0.0, width=self.bw,
-+                            relheight=0.0, height=height)
-+
-+            page_set = self.tab_set.page_set
-+            if selected and ((not self.is_last_in_row) or
-+                             (self.winfo_rootx() + self.winfo_width() <
-+                              page_set.winfo_rootx() + page_set.winfo_width())
-+                             ):
-+                # for a selected tab, if its rightmost edge isn't on the
-+                # rightmost edge of the page set, the right mask should be one
-+                # borderwidth shorter (vertically)
-+                height -= self.bw
-+
-+            self.mskr.place(in_=self,
-+                            relx=1.0, x=0,
-+                            rely=1.0, y=0,
-+                            relwidth=0.0, width=self.bw,
-+                            relheight=0.0, height=height)
-+
-+            self.mskr.mr.place(x=-self.bw, y=-self.bw,
-+                               width=2*self.bw, height=height + self.bw*2)
-+
-+            # finally, lower the tab set so that all of the frames we just
-+            # placed hide it
-+            self.tab_set.lower()
-+
-+class TabbedPageSet(Frame):
-+    """A Tkinter tabbed-pane widget.
-+
-+    Constains set of 'pages' (or 'panes') with tabs above for selecting which
-+    page is displayed. Only one page will be displayed at a time.
-+
-+    Pages may be accessed through the 'pages' attribute, which is a dictionary
-+    of pages, using the name given as the key. A page is an instance of a
-+    subclass of Tk's Frame widget.
-+
-+    The page widgets will be created (and destroyed when required) by the
-+    TabbedPageSet. Do not call the page's pack/place/grid/destroy methods.
-+
-+    Pages may be added or removed at any time using the add_page() and
-+    remove_page() methods.
-+
-+    """
-+    class Page(object):
-+        """Abstract base class for TabbedPageSet's pages.
-+
-+        Subclasses must override the _show() and _hide() methods.
-+
-+        """
-+        uses_grid = False
-+
-+        def __init__(self, page_set):
-+            self.frame = Frame(page_set, borderwidth=2, relief=RAISED)
-+
-+        def _show(self):
-+            raise NotImplementedError
-+
-+        def _hide(self):
-+            raise NotImplementedError
-+
-+    class PageRemove(Page):
-+        """Page class using the grid placement manager's "remove" mechanism."""
-+        uses_grid = True
-+
-+        def _show(self):
-+            self.frame.grid(row=0, column=0, sticky=NSEW)
-+
-+        def _hide(self):
-+            self.frame.grid_remove()
-+
-+    class PageLift(Page):
-+        """Page class using the grid placement manager's "lift" mechanism."""
-+        uses_grid = True
-+
-+        def __init__(self, page_set):
-+            super(TabbedPageSet.PageLift, self).__init__(page_set)
-+            self.frame.grid(row=0, column=0, sticky=NSEW)
-+            self.frame.lower()
-+
-+        def _show(self):
-+            self.frame.lift()
-+
-+        def _hide(self):
-+            self.frame.lower()
-+
-+    class PagePackForget(Page):
-+        """Page class using the pack placement manager's "forget" mechanism."""
-+        def _show(self):
-+            self.frame.pack(fill=BOTH, expand=True)
-+
-+        def _hide(self):
-+            self.frame.pack_forget()
-+
-+    def __init__(self, parent, page_names=None, page_class=PageLift,
-+                 n_rows=1, max_tabs_per_row=5, expand_tabs=False,
-+                 **kw):
-+        """Constructor arguments:
-+
-+        page_names -- A list of strings, each will be the dictionary key to a
-+        page's widget, and the name displayed on the page's tab. Should be
-+        specified in the desired page order. The first page will be the default
-+        and first active page. If page_names is None or empty, the
-+        TabbedPageSet will be initialized empty.
-+
-+        n_rows, max_tabs_per_row -- Parameters for the TabSet which will
-+        manage the tabs. See TabSet's docs for details.
-+
-+        page_class -- Pages can be shown/hidden using three mechanisms:
-+
-+        * PageLift - All pages will be rendered one on top of the other. When
-+          a page is selected, it will be brought to the top, thus hiding all
-+          other pages. Using this method, the TabbedPageSet will not be resized
-+          when pages are switched. (It may still be resized when pages are
-+          added/removed.)
-+
-+        * PageRemove - When a page is selected, the currently showing page is
-+          hidden, and the new page shown in its place. Using this method, the
-+          TabbedPageSet may resize when pages are changed.
-+
-+        * PagePackForget - This mechanism uses the pack placement manager.
-+          When a page is shown it is packed, and when it is hidden it is
-+          unpacked (i.e. pack_forget). This mechanism may also cause the
-+          TabbedPageSet to resize when the page is changed.
-+
-+        """
-+        Frame.__init__(self, parent, **kw)
-+
-+        self.page_class = page_class
-+        self.pages = {}
-+        self._pages_order = []
-+        self._current_page = None
-+        self._default_page = None
-+
-+        self.columnconfigure(0, weight=1)
-+        self.rowconfigure(1, weight=1)
-+
-+        self.pages_frame = Frame(self)
-+        self.pages_frame.grid(row=1, column=0, sticky=NSEW)
-+        if self.page_class.uses_grid:
-+            self.pages_frame.columnconfigure(0, weight=1)
-+            self.pages_frame.rowconfigure(0, weight=1)
-+
-+        # the order of the following commands is important
-+        self._tab_set = TabSet(self, self.change_page, n_rows=n_rows,
-+                               max_tabs_per_row=max_tabs_per_row,
-+                               expand_tabs=expand_tabs)
-+        if page_names:
-+            for name in page_names:
-+                self.add_page(name)
-+        self._tab_set.grid(row=0, column=0, sticky=NSEW)
-+
-+        self.change_page(self._default_page)
-+
-+    def update_tabtitle(self, tab, newtitle):
-+        """Update tab title to newtitle."""
-+        currpage = self.pages[tab.title]
-+        old = tab.title
-+
-+        # resolve title duplicate
-+        if newtitle in self.pages:
-+            count = 1
-+            temptitle = newtitle
-+            while temptitle in self.pages:
-+                temptitle = "%s #%d" % (newtitle, count)
-+                count += 1
-+            newtitle = temptitle
-+
-+        tab.title = newtitle
-+        # now update 1 million places.. yeh..
-+        self.pages[newtitle] = self.pages.pop(old)
-+        self._pages_order[self._pages_order.index(old)] = newtitle
-+        self._tab_set._tab_names[self._tab_set._tab_names.index(old)] = newtitle
-+        self._tab_set._tabs[newtitle] = self._tab_set._tabs.pop(old)
-+        self._tab_set._tabs[newtitle].button['text'] = newtitle
-+        if self._tab_set._selected_tab == old:
-+            self._tab_set._selected_tab = newtitle
-+        if self._current_page == old:
-+            self._current_page = newtitle
-+        if self._default_page == old:
-+            self._default_page = newtitle
-+
-+    def add_page(self, page_name):
-+        """Add a new page with the name given in page_name."""
-+        if not page_name:
-+            raise InvalidNameError("Invalid TabPage name: '%s'" % page_name)
-+        if page_name in self.pages:
-+            raise AlreadyExistsError(
-+                "TabPage named '%s' already exists" % page_name)
-+
-+        self.pages[page_name] = self.page_class(self.pages_frame)
-+        self._pages_order.append(page_name)
-+        self._tab_set.add_tab(page_name)
-+
-+        if len(self.pages) == 1: # adding first page
-+            self._default_page = page_name
-+            self.change_page(page_name)
-+
-+        return self.pages[page_name]
-+
-+    def remove_page(self, page_name):
-+        """Destroy the page whose name is given in page_name."""
-+        if not page_name in self.pages:
-+            raise KeyError("No such TabPage: '%s" % page_name)
-+
-+        self._pages_order.remove(page_name)
-+        # handle removing last remaining, default, or currently shown page
-+        if len(self._pages_order) > 0:
-+            if page_name == self._default_page:
-+                # set a new default page
-+                self._default_page = self._pages_order[0]
-+        else:
-+            self._default_page = None
-+
-+        if page_name == self._current_page:
-+            self.change_page(self._default_page)
-+
-+        self._tab_set.remove_tab(page_name)
-+        page = self.pages.pop(page_name)
-+        page.frame.destroy()
-+
-+    def change_page(self, page_name):
-+        """Show the page whose name is given in page_name."""
-+        if self._current_page == page_name:
-+            return
-+        if page_name is not None and page_name not in self.pages:
-+            raise KeyError("No such TabPage: '%s'" % page_name)
-+
-+        if self._current_page is not None:
-+            self.pages[self._current_page]._hide()
-+        self._current_page = None
-+
-+        if page_name is not None:
-+            self._current_page = page_name
-+            self.pages[page_name]._show()
-+
-+        self._tab_set.set_selected_tab(page_name)
-+        self.event_generate('<<NotebookTabChanged>>') # conform to ttk.Notebook
-+
-+    def last_page(self):
-+        return self.pages[self._pages_order[-1]]
-+
-+    # Some methods to make this Notebook compatible with the ttk Notebook
-+
-+    def select(self, page_id=None):
-+        """Return the name of the currently selected page, otherwise
-+        selects page_id.
-+        
-+        page_id may be an integer or a page name."""
-+        if page_id is None:
-+            return self._current_page
-+        elif isinstance(page_id, int):
-+            self.change_page(self._pages_order[page_id])
-+        elif isinstance(page_id, str):
-+            self.change_page(page_id)
-+
-+    def index(self, page_name):
-+        """Return the index of page_name."""
-+        return self._pages_order.index(page_name)
-+
-+    def tabs(self):
-+        """Return a list of page names."""
-+        return self._pages_order
-+
-+if __name__ == '__main__':
-+    from Tkinter import Tk, Label, Entry, Button
-+    # test dialog
-+    root=Tk()
-+    tabPage=TabbedPageSet(root, page_names=['Foobar','Baz'], n_rows=0,
-+                          expand_tabs=False,
-+                          )
-+    tabPage.pack(side=TOP, expand=True, fill=BOTH)
-+    Label(tabPage.pages['Foobar'].frame, text='Foo', pady=20).pack()
-+    Label(tabPage.pages['Foobar'].frame, text='Bar', pady=20).pack()
-+    Label(tabPage.pages['Baz'].frame, text='Baz').pack()
-+    entryPgName=Entry(root)
-+    buttonAdd=Button(root, text='Add Page',
-+            command=lambda:tabPage.add_page(entryPgName.get()))
-+    buttonRemove=Button(root, text='Remove Page',
-+            command=lambda:tabPage.remove_page(entryPgName.get()))
-+    labelPgName=Label(root, text='name of page to add/remove:')
-+    buttonAdd.pack(padx=5, pady=5)
-+    buttonRemove.pack(padx=5, pady=5)
-+    labelPgName.pack(padx=5)
-+    entryPgName.pack(padx=5)
-+    root.mainloop()
-Index: utils.py
-===================================================================
---- utils.py	(revision 0)
-+++ utils.py	(revision 65541)
-@@ -0,0 +1,4 @@
-+def callback(func, *myargs):
-+    def w(*args):
-+        return func(*(args + myargs))
-+    return w
-Index: TreeWidget.py
-===================================================================
---- TreeWidget.py	(revision 63995)
-+++ TreeWidget.py	(revision 65541)
-@@ -15,12 +15,16 @@
- # - optimize tree redraw after expand of subnode
- 
- import os
--from Tkinter import *
--import imp
-+from Tkinter import Tk, Label, Entry, Frame, Canvas, Scrollbar, PhotoImage
-+from Tkconstants import ALL, END
- 
- import ZoomHeight
- from configHandler import idleConf
- 
-+TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
-+if TTK:
-+    from ttk import Label, Entry, Frame, Scrollbar
-+
- ICONDIR = "Icons"
- 
- # Look for Icons subdirectory in the same directory as this module
-@@ -248,7 +252,9 @@
-             label = self.label
-         except AttributeError:
-             # padding carefully selected (on Windows) to match Entry widget:
--            self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2)
-+            self.label = Label(self.canvas, text=text)
-+            if not TTK:
-+                self.label.configure(bd=0, padx=2, pady=2)
-         theme = idleConf.GetOption('main','Theme','name')
-         if self.selected:
-             self.label.configure(idleConf.GetHighlight(theme, 'hilite'))
-@@ -451,7 +457,10 @@
- 
- # Testing functions
- 
-+# XXX Can't run these tests
-+
- def test():
-+    from Tkinter import Toplevel
-     import PyShell
-     root = Toplevel(PyShell.root)
-     root.configure(bd=0, bg="yellow")
-Index: run.py
-===================================================================
---- run.py	(revision 63995)
-+++ run.py	(revision 65541)
-@@ -24,11 +24,13 @@
- except ImportError:
-     pass
- else:
--    def idle_formatwarning_subproc(message, category, filename, lineno):
-+    def idle_formatwarning_subproc(message, category, filename, lineno,
-+        line=None):
-         """Format warnings the IDLE way"""
-         s = "\nWarning (from warnings module):\n"
-         s += '  File \"%s\", line %s\n' % (filename, lineno)
--        line = linecache.getline(filename, lineno).strip()
-+        if line is None:
-+            line = linecache.getline(filename, lineno).strip()
-         if line:
-             s += "    %s\n" % line
-         s += "%s: %s\n" % (category.__name__, message)
-Index: AutoExpand.py
-===================================================================
---- AutoExpand.py	(revision 63995)
-+++ AutoExpand.py	(revision 65541)
-@@ -15,8 +15,8 @@
- 
-     wordchars = string.ascii_letters + string.digits + "_"
- 
--    def __init__(self, editwin):
--        self.text = editwin.text
-+    def __init__(self, editpage):
-+        self.text = editpage.text
-         self.state = None
- 
-     def expand_word_event(self, event):
-Index: Percolator.py
-===================================================================
---- Percolator.py	(revision 63995)
-+++ Percolator.py	(revision 65541)
-@@ -1,5 +1,5 @@
-+from Delegator import Delegator
- from WidgetRedirector import WidgetRedirector
--from Delegator import Delegator
- 
- class Percolator:
- 
-@@ -81,5 +81,5 @@
-     root.mainloop()
- 
- if __name__ == "__main__":
--    from Tkinter import *
-+    from Tkinter import Tk, Text
-     main()
-Index: tabbedpages_new.py
-===================================================================
---- tabbedpages_new.py	(revision 0)
-+++ tabbedpages_new.py	(revision 65541)
-@@ -0,0 +1,116 @@
-+"""Classes exported:
-+
-+TabbedPageSet -- A custom ttk.Notebook used by IDLE.
-+"""
-+from ttk import Frame, Notebook
-+
-+from tabbedpages import InvalidNameError, AlreadyExistsError
-+
-+class FramePage(object):
-+    def __init__(self, notebook):
-+        self.frame = Frame(notebook)
-+
-+class TabbedPageSet(Notebook):
-+    """
-+    Pages may be accessed through the 'pages' attribute, which is a dictionary
-+    of pages, using the name given as the key. A page is an instance of a
-+    subclass of ttk's Frame widget.
-+
-+    Pages may be added or removed at any time using the add_page() and
-+    remove_page() methods.
-+    """
-+
-+    def __init__(self, master, page_names=None, **kw):
-+        """Constructor arguments:
-+
-+        page_names -- A list of strings, each will be the dictionary key to a
-+        page's widget, and the name displayed on the page's tab. Should be
-+        specified in the desired page order. The first page will be the default
-+        and first active page. If page_names is None or empty, the
-+        TabbedPageSet will be initialized empty.
-+        """
-+        Notebook.__init__(self, master, **kw)
-+
-+        self.pages = {}
-+        page_names = page_names or ()
-+        for name in page_names:
-+            self.add_page(name)
-+
-+    def update_tabtitle(self, tab, newtitle):
-+        """Update tab title to newtitle."""
-+        currpage = self.pages[tab.title].frame
-+        old = tab.title
-+
-+        # resolve title duplicate
-+        if newtitle in self.pages and currpage != self.pages[newtitle].frame:
-+            # newtitle is already present, and the current tab is not the
-+            # one who owns it
-+            count = 1
-+            temptitle = newtitle
-+            while temptitle in self.pages:
-+                if currpage == self.pages[temptitle].frame:
-+                    break
-+                temptitle = "%s #%d" % (newtitle, count)
-+                count += 1
-+            newtitle = temptitle
-+
-+        tab.title = newtitle
-+        self.pages[newtitle] = self.pages.pop(old)
-+        self.tab(currpage, text=newtitle)
-+
-+    def add_page(self, page_name):
-+        """Add a new page with the name given in page_name."""
-+        if not page_name:
-+            raise InvalidNameError("Invalid TabPage name: '%s'" % page_name)
-+        if page_name in self.pages:
-+            raise AlreadyExistsError(
-+                "TabPage named '%s' already exists" % page_name)
-+
-+        fpage = FramePage(self)
-+        self.pages[page_name] = fpage
-+        self.add(fpage.frame, text=page_name, padding=6)
-+
-+        # workaround for bug #1878298 at tktoolkit sf bug tracker
-+        self.event_generate('<Expose>')
-+
-+        return fpage
-+
-+    def remove_page(self, page_name):
-+        """Remove page_name from the notebook."""
-+        if not page_name in self.pages:
-+            raise KeyError("No such TabPage: '%s" % page_name)
-+
-+        self.forget(self.index(self.pages[page_name].frame))
-+        del self.pages[page_name]
-+
-+        # workaround for bug #1878298 at tktoolkit sf bug tracker
-+        self.event_generate('<Expose>')
-+
-+    def last_page(self):
-+        """Return the last page in the notebook."""
-+        return self.pages[self.tab(self.index('end') - 1)['text']]
-+
-+if __name__ == '__main__':
-+    from Tkinter import Tk
-+    from Tkconstants import TOP, BOTH
-+    from ttk import Label, Entry, Button, Style
-+    # test dialog
-+    root=Tk()
-+    style = Style()
-+    style.configure('C.TLabel', padding=20)
-+    tabPage=TabbedPageSet(root, page_names=['Foobar','Baz'])
-+    tabPage.pack(side=TOP, expand=True, fill=BOTH)
-+    Label(tabPage.pages['Foobar'].frame, text='Foo', style='C.TLabel').pack()
-+    Label(tabPage.pages['Foobar'].frame, text='Bar', style='C.TLabel').pack()
-+    Label(tabPage.pages['Baz'].frame, text='Baz').pack()
-+    entryPgName=Entry(root)
-+    buttonAdd=Button(root, text='Add Page',
-+            command=lambda:tabPage.add_page(entryPgName.get()))
-+    buttonRemove=Button(root, text='Remove Page',
-+            command=lambda:tabPage.remove_page(entryPgName.get()))
-+    labelPgName=Label(root, text='name of page to add/remove:')
-+    buttonAdd.pack(padx=5, pady=5)
-+    buttonRemove.pack(padx=5, pady=5)
-+    labelPgName.pack(padx=5)
-+    entryPgName.pack(padx=5)
-+    root.mainloop()
-Index: dynOptionMenuWidget.py
-===================================================================
---- dynOptionMenuWidget.py	(revision 63995)
-+++ dynOptionMenuWidget.py	(revision 65541)
-@@ -2,34 +2,41 @@
- OptionMenu widget modified to allow dynamic menu reconfiguration
- and setting of highlightthickness
- """
--from Tkinter import OptionMenu
-+from Tkinter import OptionMenu, Menu
- from Tkinter import _setit
- import copy
- 
-+from configHandler import idleConf
-+TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
-+if TTK:
-+    from ttk import *
-+
- class DynOptionMenu(OptionMenu):
--    """
--    unlike OptionMenu, our kwargs can include highlightthickness
--    """
-+    """Unlike OptionMenu, our kwargs can include highlightthickness"""
-     def __init__(self, master, variable, value, *values, **kwargs):
-         #get a copy of kwargs before OptionMenu.__init__ munges them
-         kwargsCopy=copy.copy(kwargs)
-         if 'highlightthickness' in kwargs.keys():
-             del(kwargs['highlightthickness'])
-+        self.command=kwargs.get('command')
-+        self.variable=variable
-+
-         OptionMenu.__init__(self, master, variable, value, *values, **kwargs)
-         self.config(highlightthickness=kwargsCopy.get('highlightthickness'))
--        #self.menu=self['menu']
--        self.variable=variable
--        self.command=kwargs.get('command')
- 
--    def SetMenu(self,valueList,value=None):
-+    def SetMenu(self, valueList, value=None):
-         """
-         clear and reload the menu with a new set of options.
-         valueList - list of new options
-         value - initial value to set the optionmenu's menubutton to
-         """
--        self['menu'].delete(0,'end')
--        for item in valueList:
--            self['menu'].add_command(label=item,
-+        if TTK:
-+            self.set_menu(value, *valueList)
-+        else:
-+            menu = self['menu']
-+            menu.delete(0,'end')
-+            for item in valueList:
-+                menu.add_command(label=item,
-                     command=_setit(self.variable,item,self.command))
--        if value:
--            self.variable.set(value)
-+            if value:
-+                self.variable.set(value)
-Index: extend.txt
-===================================================================
---- extend.txt	(revision 63995)
-+++ extend.txt	(revision 65541)
-@@ -81,3 +81,10 @@
- 
- For further information on binding refer to the Tkinter Resources web page at
- python.org and to the Tk Command "bind" man page.
-+
-+
-+Note
-+----
-+
-+Given that this branch is using tabbed pages, don't expect the previous
-+description to be correct related to the code present here.
-Index: MultiStatusBar.py
-===================================================================
---- MultiStatusBar.py	(revision 63995)
-+++ MultiStatusBar.py	(revision 65541)
-@@ -1,5 +1,11 @@
--from Tkinter import *
-+from Tkinter import Tk, Frame, Label
-+from Tkconstants import LEFT, SUNKEN, W
- 
-+from configHandler import idleConf
-+
-+if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
-+    from ttk import Frame, Label
-+
- class MultiStatusBar(Frame):
- 
-     def __init__(self, master=None, **kw):
-@@ -10,7 +16,7 @@
- 
-     def set_label(self, name, text='', side=LEFT):
-         if not self.labels.has_key(name):
--            label = Label(self, bd=1, relief=SUNKEN, anchor=W)
-+            label = Label(self, relief=SUNKEN, anchor=W)
-             label.pack(side=side)
-             self.labels[name] = label
-         else:
-@@ -18,6 +24,8 @@
-         label.config(text=text)
- 
- def _test():
-+    from Tkinter import Text
-+    from Tkconstants import TOP, BOTTOM, X
-     b = Frame()
-     c = Text(b)
-     c.pack(side=TOP)
-
-Property changes on: .
-___________________________________________________________________
-Name: svnmerge-integrated
-   + /python/trunk/Lib/idlelib:1-63994
-


More information about the Python-checkins mailing list