[Python-checkins] r63740 - sandbox/trunk/ttk-gsoc/src/idlelib_ttk.diff
guilherme.polo
python-checkins at python.org
Tue May 27 03:53:51 CEST 2008
Author: guilherme.polo
Date: Tue May 27 03:53:51 2008
New Revision: 63740
Log:
Much better fallback now, in case ttk is not present
Modified:
sandbox/trunk/ttk-gsoc/src/idlelib_ttk.diff
Modified: sandbox/trunk/ttk-gsoc/src/idlelib_ttk.diff
==============================================================================
--- sandbox/trunk/ttk-gsoc/src/idlelib_ttk.diff (original)
+++ sandbox/trunk/ttk-gsoc/src/idlelib_ttk.diff Tue May 27 03:53:51 2008
@@ -1,6 +1,6 @@
Index: Lib/idlelib/AutoCompleteWindow.py
===================================================================
---- Lib/idlelib/AutoCompleteWindow.py (revision 63650)
+--- Lib/idlelib/AutoCompleteWindow.py (revision 63734)
+++ Lib/idlelib/AutoCompleteWindow.py (working copy)
@@ -4,7 +4,11 @@
from Tkinter import *
@@ -16,7 +16,7 @@
KEYPRESS_VIRTUAL_EVENT_NAME = "<<autocompletewindow-keypress>>"
Index: Lib/idlelib/ToolTip.py
===================================================================
---- Lib/idlelib/ToolTip.py (revision 63650)
+--- Lib/idlelib/ToolTip.py (revision 63734)
+++ Lib/idlelib/ToolTip.py (working copy)
@@ -3,7 +3,8 @@
# may be useful for some purposes in (or almost in ;) the current project scope
@@ -28,34 +28,70 @@
class ToolTipBase:
+Index: Lib/idlelib/stylist.py
+===================================================================
+--- Lib/idlelib/stylist.py (revision 0)
++++ Lib/idlelib/stylist.py (revision 0)
+@@ -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: Lib/idlelib/configSectionNameDialog.py
===================================================================
---- Lib/idlelib/configSectionNameDialog.py (revision 63650)
+--- Lib/idlelib/configSectionNameDialog.py (revision 63734)
+++ Lib/idlelib/configSectionNameDialog.py (working copy)
-@@ -4,7 +4,11 @@
+@@ -4,7 +4,12 @@
"""
from Tkinter import *
import tkMessageBox
+from idlelib.configHandler import idleConf
-+if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
++if TTK:
+ from ttk import *
+
class GetCfgSectionNameDialog(Toplevel):
def __init__(self,parent,title,message,usedNames):
"""
-@@ -46,7 +50,7 @@
- entryName.focus_set()
- self.messageInfo.pack(padx=5,pady=5)#,expand=TRUE,fill=BOTH)
- entryName.pack(padx=5,pady=5)
-- frameButtons=Frame(self)
-+ frameButtons=Frame(self, style='RootColor.TFrame')
- frameButtons.pack(side=BOTTOM,fill=X)
- self.buttonOk = Button(frameButtons,text='Ok',
- width=8,command=self.Ok)
+@@ -55,6 +60,9 @@
+ width=8,command=self.Cancel)
+ self.buttonCancel.grid(row=0,column=1,padx=5,pady=5)
+
++ if TTK:
++ frameButton['style'] = 'RootColor.TFrame'
++
+ def NameOk(self):
+ #simple validity check for a sensible
+ #ConfigParser file section name
Index: Lib/idlelib/PyShell.py
===================================================================
---- Lib/idlelib/PyShell.py (revision 63650)
+--- Lib/idlelib/PyShell.py (revision 63734)
+++ Lib/idlelib/PyShell.py (working copy)
@@ -22,14 +22,25 @@
print>>sys.__stderr__, "** IDLE can't import Tkinter. " \
@@ -106,7 +142,7 @@
flist = PyShellFileList(root)
Index: Lib/idlelib/Debugger.py
===================================================================
---- Lib/idlelib/Debugger.py (revision 63650)
+--- Lib/idlelib/Debugger.py (revision 63734)
+++ Lib/idlelib/Debugger.py (working copy)
@@ -5,7 +5,10 @@
from WindowList import ListedToplevel
@@ -121,7 +157,7 @@
Index: Lib/idlelib/configDialog.py
===================================================================
---- Lib/idlelib/configDialog.py (revision 63650)
+--- Lib/idlelib/configDialog.py (revision 63734)
+++ Lib/idlelib/configDialog.py (working copy)
@@ -7,7 +7,6 @@
@@ -131,17 +167,20 @@
"""
from Tkinter import *
import tkMessageBox, tkColorChooser, tkFont
-@@ -20,6 +19,9 @@
+@@ -19,7 +18,12 @@
+ from keybindingDialog import GetKeysDialog
from configSectionNameDialog import GetCfgSectionNameDialog
from configHelpSourceEdit import GetHelpSourceDialog
++from stylist import PoorManStyle
-+if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
++if TTK:
+ from ttk import *
+
class ConfigDialog(Toplevel):
def __init__(self,parent,title):
-@@ -47,6 +49,7 @@
+@@ -47,6 +51,7 @@
'Shell Stderr Text':('stderr','12'),
}
self.ResetChangedItems() #load initial values in changed items dict
@@ -149,22 +188,30 @@
self.CreateWidgets()
self.resizable(height=FALSE,width=FALSE)
self.transient(parent)
-@@ -64,32 +67,35 @@
+@@ -64,32 +69,52 @@
self.wm_deiconify()
self.wait_window()
+ def SetupStyles(self):
-+ 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
++ 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)
-+ frameActionButtons = Frame(self, style='RootColor.TFrame')
++ frameActionButtons = Frame(self)
#action buttons
self.buttonHelp = Button(frameActionButtons,text='Help',
- command=self.Help,takefocus=FALSE,
@@ -178,13 +225,22 @@
- self.buttonCancel = Button(frameActionButtons,text='Cancel',
- command=self.Cancel,takefocus=FALSE,
- padx=6,pady=3)
-+ command=self.Help, takefocus=FALSE, style='S.TButton')
++ command=self.Help, takefocus=FALSE)
+ self.buttonOk = Button(frameActionButtons, text='Ok',
-+ command=self.Ok, takefocus=FALSE, style='S.TButton')
++ command=self.Ok, takefocus=FALSE)
+ self.buttonApply = Button(frameActionButtons, text='Apply',
-+ command=self.Apply, takefocus=FALSE, style='S.TButton')
++ command=self.Apply, takefocus=FALSE)
+ self.buttonCancel = Button(frameActionButtons, text='Cancel',
-+ command=self.Cancel, takefocus=FALSE, style='S.TButton')
++ 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()
@@ -202,7 +258,7 @@
Frame(self, height=2, borderwidth=0).pack(side=BOTTOM)
self.tabPages.pack(side=TOP,expand=TRUE,fill=BOTH)
-@@ -127,7 +133,7 @@
+@@ -127,7 +152,7 @@
frameFontSample=Frame(frameFont,relief=SOLID,borderwidth=1)
self.labelFontSample=Label(frameFontSample,
text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]',
@@ -211,7 +267,7 @@
#frameIndent
frameIndentSize=Frame(frameIndent)
labelSpaceNumTitle=Label(frameIndentSize, justify=LEFT,
-@@ -149,7 +155,7 @@
+@@ -149,7 +174,7 @@
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)
@@ -220,7 +276,7 @@
#frameIndent
frameIndentSize.pack(side=TOP,fill=X)
labelSpaceNumTitle.pack(side=TOP,anchor=W,padx=5)
-@@ -174,7 +180,7 @@
+@@ -174,7 +199,7 @@
text=' Highlighting Theme ')
#frameCustom
self.textHighlightSample=Text(frameCustom,relief=SOLID,borderwidth=1,
@@ -229,14 +285,15 @@
takefocus=FALSE,highlightthickness=0,wrap=NONE)
text=self.textHighlightSample
text.bind('<Double-Button-1>',lambda e: 'break')
-@@ -197,12 +203,14 @@
+@@ -197,12 +222,15 @@
lambda event,elem=element: event.widget.winfo_toplevel()
.highlightTarget.set(elem))
text.config(state=DISABLED)
- self.frameColourSet=Frame(frameCustom,relief=SOLID,borderwidth=1)
+
-+ self.frameColourSet=Frame(frameCustom, relief=SOLID, borderwidth=1,
-+ style="Color.TFrame")
++ 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,highlightthickness=0)
@@ -247,16 +304,21 @@
self.radioFg=Radiobutton(frameFgBg,variable=self.fgHilite,
value=1,text='Foreground',command=self.SetColourSampleBinding)
self.radioBg=Radiobutton(frameFgBg,variable=self.fgHilite,
-@@ -275,7 +283,7 @@
+@@ -275,8 +303,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)
-+ frames = [Frame(frameKeySets, borderwidth=0, style='S2.TFrame')
- for i in range(2)]
+- 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')
-@@ -748,14 +756,14 @@
+ self.radioKeysCustom=Radiobutton(frames[0],variable=self.keysAreBuiltin,
+@@ -748,14 +779,14 @@
def GetColour(self):
target=self.highlightTarget.get()
@@ -274,7 +336,7 @@
newTheme=self.GetNewThemeName(message)
if not newTheme: #user cancelled custom theme creation
return
-@@ -767,7 +775,7 @@
+@@ -767,7 +798,7 @@
def OnNewColourSet(self):
newColour=self.colour.get()
@@ -283,7 +345,7 @@
if self.fgHilite.get(): plane='foreground'
else: plane='background'
sampleElement=self.themeElements[self.highlightTarget.get()][0]
-@@ -777,6 +785,7 @@
+@@ -777,6 +808,7 @@
self.AddChangedItem('highlight',theme,themeElement,newColour)
def GetNewThemeName(self,message):
@@ -291,7 +353,7 @@
usedNames=(idleConf.GetSectionList('user','highlight')+
idleConf.GetSectionList('default','highlight'))
newTheme=GetCfgSectionNameDialog(self,'New Custom Theme',
-@@ -846,7 +855,7 @@
+@@ -846,7 +878,7 @@
if self.fgHilite.get(): plane='foreground'
else: plane='background'
colour=self.textHighlightSample.tag_cget(tag,plane)
@@ -302,7 +364,7 @@
if self.themeIsBuiltin.get(): #a default theme
Index: Lib/idlelib/ReplaceDialog.py
===================================================================
---- Lib/idlelib/ReplaceDialog.py (revision 63650)
+--- Lib/idlelib/ReplaceDialog.py (revision 63734)
+++ Lib/idlelib/ReplaceDialog.py (working copy)
@@ -11,9 +11,12 @@
dialog.open(text)
@@ -336,43 +398,30 @@
self.do_find(0)
Index: Lib/idlelib/tabbedpages.py
===================================================================
---- Lib/idlelib/tabbedpages.py (revision 63650)
+--- Lib/idlelib/tabbedpages.py (revision 63734)
+++ Lib/idlelib/tabbedpages.py (working copy)
-@@ -1,360 +1,34 @@
+@@ -1,490 +1,4 @@
-"""An implementation of tabbed pages using only standard Tkinter.
-+"""Classes exported:
-
+-
-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.
-
-+TabbedPageSet -- A custom ttk.Notebook used by IDLE.
- """
- from Tkinter import *
-+from idlelib.configHandler import idleConf
-
-+if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
-+ from ttk import *
-+else:
-+ print "This will fail for now."
-+ class Notebook(object): pass
-+
- class InvalidNameError(Exception): pass
- class AlreadyExistsError(Exception): pass
-
-+class FramePage(object):
-+ def __init__(self, notebook):
-+ self.frame = Frame(notebook)
-
+-"""
+-from Tkinter import *
+-
+-class InvalidNameError(Exception): pass
+-class AlreadyExistsError(Exception): pass
+-
+-
-class TabSet(Frame):
- """A widget containing tabs (buttons) in one or more rows.
-
- Only one tab may be selected at a time.
-
-+class TabbedPageSet(Notebook):
- """
+- """
- def __init__(self, page_set, select_command,
- tabs=None, n_rows=1, max_tabs_per_row=5,
- expand_tabs=False, **kw):
@@ -645,21 +694,20 @@
- 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
+- 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.
-+ subclass of ttk'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.
+- 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.
-
- """
@@ -710,14 +758,13 @@
- def __init__(self, parent, page_names=None, page_class=PageLift,
- n_rows=1, max_tabs_per_row=5, expand_tabs=False,
- **kw):
-+ def __init__(self, master, page_names=None, **kw):
- """Constructor arguments:
-
- page_names -- A list of strings, each will be the dictionary key to a
-@@ -362,56 +36,13 @@
- 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.
+- """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.
@@ -739,18 +786,15 @@
- unpacked (i.e. pack_forget). This mechanism may also cause the
- TabbedPageSet to resize when the page is changed.
-
- """
+- """
- Frame.__init__(self, parent, **kw)
-+ Notebook.__init__(self, master, **kw)
-
+-
- self.page_class = page_class
- self.pages = {}
+- self.pages = {}
- self._pages_order = []
- self._current_page = None
- self._default_page = None
-+ for name in page_names:
-+ self.add_page(name)
-
+-
- self.columnconfigure(0, weight=1)
- self.rowconfigure(1, weight=1)
-
@@ -771,35 +815,29 @@
-
- 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:
-@@ -420,62 +51,32 @@
- raise AlreadyExistsError(
- "TabPage named '%s' already exists" % page_name)
-
+- 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)
-+ fpage = FramePage(self)
-+ self.pages[page_name] = fpage
-+ self.add(fpage.frame, text=page_name, padding=6)
-
+-
- if len(self.pages) == 1: # adding first page
- self._default_page = page_name
- self.change_page(page_name)
-+ # workaround for bug #1878298 at tktoolkit sf bug tracker
-+ self.event_generate('<Expose>')
-
- def remove_page(self, 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)
-
+- if not page_name in self.pages:
+- raise KeyError("No such TabPage: '%s" % page_name)
+-
- self._pages_order.remove(page_name)
-+ self.forget(self.index(self.pages[page_name].frame))
-+ del self.pages[page_name]
-
+-
- # handle removing last remaining, default, or currently shown page
- if len(self._pages_order) > 0:
- if page_name == self._default_page:
@@ -807,9 +845,7 @@
- self._default_page = self._pages_order[0]
- else:
- self._default_page = None
-+ # workaround for bug #1878298 at tktoolkit sf bug tracker
-+ self.event_generate('<Expose>')
-
+-
- if page_name == self._current_page:
- self.change_page(self._default_page)
-
@@ -834,65 +870,76 @@
-
- self._tab_set.set_selected_tab(page_name)
-
- if __name__ == '__main__':
- # test dialog
- root=Tk()
+-if __name__ == '__main__':
+- # test dialog
+- root=Tk()
- tabPage=TabbedPageSet(root, page_names=['Foobar','Baz'], n_rows=0,
- expand_tabs=False,
- )
-+ style = Style()
-+ style.configure('C.TLabel', padding=20)
-+ tabPage=TabbedPageSet(root, page_names=['Foobar','Baz'])
- tabPage.pack(side=TOP, expand=TRUE, fill=BOTH)
+- 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['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',
+- 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()
++try:
++ from idlelib.tabbedpages_new import TabbedPageSet
++except ImportError:
++ from idlelib.tabbedpages_old import TabbedPageSet
Index: Lib/idlelib/keybindingDialog.py
===================================================================
---- Lib/idlelib/keybindingDialog.py (revision 63650)
+--- Lib/idlelib/keybindingDialog.py (revision 63734)
+++ Lib/idlelib/keybindingDialog.py (working copy)
-@@ -5,6 +5,11 @@
+@@ -5,6 +5,12 @@
import tkMessageBox
import string
+from idlelib.configHandler import idleConf
+
-+if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
++if TTK:
+ from ttk import *
+
class GetKeysDialog(Toplevel):
def __init__(self,parent,title,action,currentKeySequences):
"""
-@@ -48,7 +53,7 @@
- def CreateWidgets(self):
- frameMain = Frame(self,borderwidth=2,relief=SUNKEN)
- frameMain.pack(side=TOP,expand=TRUE,fill=BOTH)
-- frameButtons=Frame(self)
-+ frameButtons=Frame(self, style='RootColor.TFrame')
- frameButtons.pack(side=BOTTOM,fill=X)
- self.buttonOK = Button(frameButtons,text='OK',
- width=8,command=self.OK)
+@@ -124,6 +130,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.
+
Index: Lib/idlelib/configHelpSourceEdit.py
===================================================================
---- Lib/idlelib/configHelpSourceEdit.py (revision 63650)
+--- Lib/idlelib/configHelpSourceEdit.py (revision 63734)
+++ Lib/idlelib/configHelpSourceEdit.py (working copy)
-@@ -6,7 +6,11 @@
+@@ -6,7 +6,12 @@
from Tkinter import *
import tkMessageBox
import tkFileDialog
+from idlelib.configHandler import idleConf
-+if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
++if TTK:
+ from ttk import *
+
class GetHelpSourceDialog(Toplevel):
def __init__(self, parent, title, menuItem='', filePath=''):
"""Get menu entry and url/ local file location for Additional Help
-@@ -25,6 +29,7 @@
+@@ -25,6 +30,7 @@
self.protocol("WM_DELETE_WINDOW", self.Cancel)
self.parent = parent
self.result = None
@@ -900,12 +947,7 @@
self.CreateWidgets()
self.menu.set(menuItem)
self.path.set(filePath)
-@@ -64,11 +69,11 @@
- browseButton = Button(self.frameMain, text='Browse', width=8,
- command=self.browseFile)
- browseButton.pack(pady=3)
-- frameButtons = Frame(self)
-+ frameButtons = Frame(self, style='RootColor.TFrame')
+@@ -68,11 +74,14 @@
frameButtons.pack(side=BOTTOM, fill=X)
self.buttonOk = Button(frameButtons, text='OK',
width=8, default=ACTIVE, command=self.Ok)
@@ -914,9 +956,16 @@
self.buttonCancel = Button(frameButtons, text='Cancel',
width=8, command=self.Cancel)
self.buttonCancel.grid(row=0, column=1, padx=5, pady=5)
+
++ if TTK:
++ frameButtons['style'] = 'RootColor.TFrame'
++
+ def browseFile(self):
+ filetypes = [
+ ("HTML Files", "*.htm *.html", "TEXT"),
Index: Lib/idlelib/GrepDialog.py
===================================================================
---- Lib/idlelib/GrepDialog.py (revision 63650)
+--- Lib/idlelib/GrepDialog.py (revision 63734)
+++ Lib/idlelib/GrepDialog.py (working copy)
@@ -4,7 +4,11 @@
from Tkinter import *
@@ -977,7 +1026,7 @@
- self.top.withdraw()
Index: Lib/idlelib/EditorWindow.py
===================================================================
---- Lib/idlelib/EditorWindow.py (revision 63650)
+--- Lib/idlelib/EditorWindow.py (revision 63734)
+++ Lib/idlelib/EditorWindow.py (working copy)
@@ -365,7 +365,7 @@
self.menudict = menudict = {}
@@ -990,9 +1039,9 @@
if sys.platform == 'darwin' and '.framework' in sys.executable:
Index: Lib/idlelib/aboutDialog.py
===================================================================
---- Lib/idlelib/aboutDialog.py (revision 63650)
+--- Lib/idlelib/aboutDialog.py (revision 63734)
+++ Lib/idlelib/aboutDialog.py (working copy)
-@@ -1,13 +1,15 @@
+@@ -1,13 +1,17 @@
-"""About Dialog for IDLE
-
-"""
@@ -1004,15 +1053,17 @@
import textView
import idlever
++from idlelib.stylist import PoorManStyle
+from idlelib.configHandler import idleConf
+
-+if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
++if TTK:
+ from ttk import *
+
class AboutDialog(Toplevel):
"""Modal about dialog for idle
-@@ -15,10 +17,16 @@
+@@ -15,10 +19,13 @@
def __init__(self,parent,title):
Toplevel.__init__(self, parent)
self.configure(borderwidth=5)
@@ -1021,75 +1072,86 @@
parent.winfo_rooty()+30))
self.bg = "#707070"
self.fg = "#ffffff"
-+
-+ style = Style()
-+ style.configure('Color.TLabel', foreground=self.fg, background=self.bg)
-+ style.configure('Color.TFrame', background=self.bg)
-+
++
++ self.SetupStyles()
self.CreateWidgets()
self.resizable(height=FALSE, width=FALSE)
self.title(title)
-@@ -31,40 +39,36 @@
+@@ -31,40 +38,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 = Frame(self)
- frameButtons.pack(side=BOTTOM, fill=X)
-+ frameButtons = Frame(self, style='RootColor.TFrame')
+ 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 = 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)
++ self.buttonOk = Button(frameButtons, text='Close', command=self.Ok)
+ self.buttonOk.pack()
-+ frameBg = Frame(frameMain, style='Color.TFrame')
++ frameBg = Frame(frameMain)
frameBg.pack(expand=TRUE, fill=BOTH)
- labelTitle = Label(frameBg, text='IDLE', fg=self.fg, bg=self.bg,
-+ labelTitle = Label(frameBg, text='IDLE', style='Color.TLabel',
- font=('courier', 24, 'bold'))
+- font=('courier', 24, 'bold'))
++ 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,
+- labelDesc = Label(frameBg, text=byline, justify=LEFT,
- fg=self.fg, bg=self.bg)
-+ style='Color.TLabel')
++ 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, style='Color.TLabel')
++ 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, style='Color.TLabel')
++ justify=LEFT)
labelWWW.grid(row=7, column=0, columnspan=2, sticky=W, padx=10, pady=0)
- Frame(frameBg, borderwidth=1, relief=SUNKEN,
+- Frame(frameBg, borderwidth=1, relief=SUNKEN,
- height=2, bg=self.bg).grid(row=8, column=0, sticky=EW,
-+ height=2, style='Color.TFrame').grid(row=8, column=0, sticky=EW,
- columnspan=3, padx=5, pady=5)
+- 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], style='Color.TLabel')
++ 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('.')
-@@ -73,40 +77,34 @@
+@@ -72,44 +83,50 @@
+ if tkVer[len(tkVer)-1] == '':
tkVer[len(tkVer)-1] = '0'
tkVer = '.'.join(tkVer)
- labelTkVer = Label(frameBg, text='Tk version: '+
+- labelTkVer = Label(frameBg, text='Tk version: '+
- tkVer, fg=self.fg, bg=self.bg)
-+ tkVer, style='Color.TLabel')
++ 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, style='Color.TFrame')
++ 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,
@@ -1103,17 +1165,17 @@
- highlightbackground=self.bg,
command=self.ShowPythonCredits)
buttonCredits.pack(side=LEFT, padx=10, pady=10)
- Frame(frameBg, borderwidth=1, relief=SUNKEN,
+- Frame(frameBg, borderwidth=1, relief=SUNKEN,
- height=2, bg=self.bg).grid(row=11, column=0, sticky=EW,
- columnspan=3, padx=5, pady=5)
-+ height=2, style='Color.TFrame').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 = Label(frameBg, text='IDLE version: ' + idlever.IDLE_VERSION,
- fg=self.fg, bg=self.bg)
-+ style='Color.TLabel')
++ 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, style='Color.TFrame')
++ 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,
@@ -1128,9 +1190,27 @@
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)
+
Index: Lib/idlelib/config-main.def
===================================================================
---- Lib/idlelib/config-main.def (revision 63650)
+--- Lib/idlelib/config-main.def (revision 63734)
+++ Lib/idlelib/config-main.def (working copy)
@@ -49,6 +49,7 @@
print-command-posix=lpr %s
@@ -1142,7 +1222,7 @@
width= 80
Index: Lib/idlelib/IOBinding.py
===================================================================
---- Lib/idlelib/IOBinding.py (revision 63650)
+--- Lib/idlelib/IOBinding.py (revision 63734)
+++ Lib/idlelib/IOBinding.py (working copy)
@@ -18,6 +18,9 @@
@@ -1156,7 +1236,7 @@
except ImportError:
Index: Lib/idlelib/ScrolledList.py
===================================================================
---- Lib/idlelib/ScrolledList.py (revision 63650)
+--- Lib/idlelib/ScrolledList.py (revision 63734)
+++ Lib/idlelib/ScrolledList.py (working copy)
@@ -1,5 +1,9 @@
from Tkinter import *
@@ -1170,9 +1250,9 @@
default = "(None)"
Index: Lib/idlelib/textView.py
===================================================================
---- Lib/idlelib/textView.py (revision 63650)
+--- Lib/idlelib/textView.py (revision 63734)
+++ Lib/idlelib/textView.py (working copy)
-@@ -1,10 +1,12 @@
+@@ -1,10 +1,13 @@
-"""Simple text browser for IDLE
+"""Simple text browser for IDLE"""
@@ -1183,18 +1263,14 @@
-import tkMessageBox
+from idlelib.configHandler import idleConf
-+if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
++if TTK:
+ from ttk import *
+
class TextViewer(Toplevel):
"""A simple text viewer dialog for IDLE
-@@ -38,19 +40,19 @@
-
- def CreateWidgets(self):
- frameText = Frame(self, relief=SUNKEN, height=700)
-- frameButtons = Frame(self)
-+ frameButtons = Frame(self, style='RootColor.TFrame')
+@@ -42,17 +45,20 @@
self.buttonOk = Button(frameButtons, text='Close',
command=self.Ok, takefocus=FALSE)
self.scrollbarView = Scrollbar(frameText, orient=VERTICAL,
@@ -1213,10 +1289,15 @@
+ 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()
+
Index: Lib/idlelib/SearchDialogBase.py
===================================================================
---- Lib/idlelib/SearchDialogBase.py (revision 63650)
+--- Lib/idlelib/SearchDialogBase.py (revision 63734)
+++ Lib/idlelib/SearchDialogBase.py (working copy)
@@ -1,35 +1,40 @@
from Tkinter import *
@@ -1421,7 +1502,7 @@
+ column += 1
Index: Lib/idlelib/CallTipWindow.py
===================================================================
---- Lib/idlelib/CallTipWindow.py (revision 63650)
+--- Lib/idlelib/CallTipWindow.py (revision 63734)
+++ Lib/idlelib/CallTipWindow.py (working copy)
@@ -5,7 +5,11 @@
@@ -1446,7 +1527,7 @@
c=container()
Index: Lib/idlelib/SearchDialog.py
===================================================================
---- Lib/idlelib/SearchDialog.py (revision 63650)
+--- Lib/idlelib/SearchDialog.py (revision 63734)
+++ Lib/idlelib/SearchDialog.py (working copy)
@@ -21,10 +21,10 @@
return _setup(text).find_selection(text)
@@ -1461,43 +1542,530 @@
def default_command(self, event=None):
if not self.engine.getprog():
+Index: Lib/idlelib/tabbedpages_old.py
+===================================================================
+--- Lib/idlelib/tabbedpages_old.py (revision 0)
++++ Lib/idlelib/tabbedpages_old.py (revision 0)
+@@ -0,0 +1,490 @@
++"""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 *
++
++class InvalidNameError(Exception): pass
++class AlreadyExistsError(Exception): pass
++
++
++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
++ 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 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()
Index: Lib/idlelib/TreeWidget.py
===================================================================
---- Lib/idlelib/TreeWidget.py (revision 63650)
+--- Lib/idlelib/TreeWidget.py (revision 63734)
+++ Lib/idlelib/TreeWidget.py (working copy)
-@@ -21,6 +21,11 @@
+@@ -21,6 +21,12 @@
import ZoomHeight
from configHandler import idleConf
+from idlelib.configHandler import idleConf
+
-+if idleConf.GetOption('main', 'General', 'use-ttk', type='int'):
++TTK = idleConf.GetOption('main', 'General', 'use-ttk', type='int')
++if TTK:
+ from ttk import *
+
ICONDIR = "Icons"
# Look for Icons subdirectory in the same directory as this module
-@@ -68,6 +73,10 @@
- self.x = self.y = None
- self.iconimages = {} # cache of PhotoImage instances for icons
-
-+ # XXX
-+ #style = Style()
-+ #style.configure("P.TLabel", padding=2, borderwidth=0)
-+
- def destroy(self):
- for c in self.children[:]:
- self.children.remove(c)
-@@ -248,7 +257,7 @@
+@@ -248,7 +254,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, style='P.TLabel')
++ 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,6 +460,8 @@
+@@ -451,6 +459,8 @@
# Testing functions
@@ -1506,9 +2074,99 @@
def test():
import PyShell
root = Toplevel(PyShell.root)
+Index: Lib/idlelib/tabbedpages_new.py
+===================================================================
+--- Lib/idlelib/tabbedpages_new.py (revision 0)
++++ Lib/idlelib/tabbedpages_new.py (revision 0)
+@@ -0,0 +1,85 @@
++"""Classes exported:
++
++TabbedPageSet -- A custom ttk.Notebook used by IDLE.
++"""
++from Tkinter import *
++from ttk import *
++
++class InvalidNameError(Exception): pass
++class AlreadyExistsError(Exception): pass
++
++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 = {}
++ for name in page_names:
++ self.add_page(name)
++
++ 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>')
++
++ def remove_page(self, page_name):
++ 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>')
++
++if __name__ == '__main__':
++ # 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: Lib/idlelib/MultiStatusBar.py
===================================================================
---- Lib/idlelib/MultiStatusBar.py (revision 63650)
+--- Lib/idlelib/MultiStatusBar.py (revision 63734)
+++ Lib/idlelib/MultiStatusBar.py (working copy)
@@ -1,5 +1,9 @@
from Tkinter import *
More information about the Python-checkins
mailing list