# This command is only needed and available on Tk >= 8.4.0 for OSX
# Without it, call tips intrude on the typing process by grabbing
# the focus.
- tw.tk.call("::tk::unsupported::MacWindowStyle", "style", tw._w,
+ tw.tk.call("::tk::unsupported::MacWindowStyle", "style", tw._w,
"help", "noActivates")
except TclError:
pass
while i and str[i-1] in idchars:
i -= 1
return str[i:]
-
+
def fetch_tip(self, name):
- """Return the argument list and docstring of a function or class
-
+ """Return the argument list and docstring of a function or class
+
If there is a Python subprocess, get the calltip there. Otherwise,
either fetch_tip() is running in the subprocess itself or it was called
in an IDLE EditorWindow before any script had been run.
two unrelated modules are being edited some calltips in the current
module may be inoperative if the module was not the last to run.
- """
+ """
try:
rpcclt = self.editwin.flist.pyshell.interp.rpcclt
except:
print "%d of %d tests failed" % (len(failed), len(tests))
tc = TC()
- tests = (t1, t2, t3, t4, t5, t6,
+ tests = (t1, t2, t3, t4, t5, t6,
TC, tc.t1, tc.t2, tc.t3, tc.t4, tc.t5, tc.t6)
test(tests)
if cnf:
apply(self.tag_configure, (tag,), cnf)
self.tag_raise('sel')
-
+
def LoadTagDefs(self):
theme = idleConf.GetOption('main','Theme','name')
self.tagdefs = {
# The following is used by ReplaceDialog:
"hit": idleConf.GetHighlight(theme, "hit"),
}
-
+
if DEBUG: print 'tagdefs',tagdefs
def insert(self, index, chars, tags=None):
def user_line(self, frame):
co_filename = frame.f_code.co_filename
- co_name = frame.f_code.co_name
+ co_name = frame.f_code.co_name
## print>>sys.__stderr__, "*function: ", frame.f_code.co_name
- ## print>>sys.__stderr__, "*file: ", frame.f_code.co_filename
+ ## print>>sys.__stderr__, "*file: ", frame.f_code.co_filename
## print>>sys.__stderr__, "*line number: ", frame.f_code.co_firstlineno
## print>>sys.__stderr__, "*name: ", co_name
## print>>sys.__stderr__, "*function: ", frame.f_locals.get(co_name,None)
try:
# XXX 12 Dec 2002 CGT TO DO: Find way to get a reference to the
- # XXX currently running function. If the function has an
+ # XXX currently running function. If the function has an
# attribute called "DebuggerStepThrough", prevent the debugger
# from stepping through Idle code. The following doesn't work
# in instance methods. Hard coded some workarounds.
self.frame = None
self.make_gui()
self.interacting = 0
-
+
def run(self, *args):
try:
self.interacting = 1
text.bind("<<untabify-region>>",self.untabify_region_event)
text.bind("<<toggle-tabs>>",self.toggle_tabs_event)
text.bind("<<change-indentwidth>>",self.change_indentwidth_event)
-
+
if flist:
flist.inversedict[self] = key
if key:
if self.extensions.has_key('AutoIndent'):
self.extensions['AutoIndent'].set_indentation_params(
self.ispythonsource(filename))
-
+
def set_status_bar(self):
self.status_bar = self.MultiStatusBar(self.top)
self.status_bar.set_label('column', 'Col: ?', side=RIGHT)
def about_dialog(self, event=None):
aboutDialog.AboutDialog(self.top,'About IDLEfork')
-
+
def config_dialog(self, event=None):
configDialog.ConfigDialog(self.top,'Settings')
-
+
def good_advice(self, event=None):
tkMessageBox.showinfo('Advice', "Don't Panic!", master=self.text)
def view_readme(self, event=None):
fn=os.path.join(os.path.abspath(os.path.dirname(__file__)),'README.txt')
- textView.TextViewer(self.top,'IDLEfork - README',fn)
+ textView.TextViewer(self.top,'IDLEfork - README',fn)
def help_dialog(self, event=None):
fn=os.path.join(os.path.abspath(os.path.dirname(__file__)),'help.txt')
- textView.TextViewer(self.top,'Help',fn)
-
+ textView.TextViewer(self.top,'Help',fn)
+
help_url = "http://www.python.org/doc/current/"
if sys.platform[:3] == "win":
fn = os.path.dirname(__file__)
self.per.removefilter(self.color)
self.color = None
self.per.insertfilter(self.undo)
-
+
def ResetColorizer(self):
"Update the colour theme if it is changed"
# Called from configDialog.py
self.per.insertfilter(self.color)
def ResetFont(self):
- "Update the text widgets' font if it is changed"
+ "Update the text widgets' font if it is changed"
# Called from configDialog.py
fontWeight='normal'
if idleConf.GetOption('main','EditorWindow','font-bold',type='bool'):
self.menuExtraHelp.add_command(label=menuItem[0],
command=self.__DisplayExtraHelpCallback(menuItem[1]))
else: #no extra help items
- if hasattr(self,'menuExtraHelp'):
- helpMenu.delete(cascadeIndex-1)
+ if hasattr(self,'menuExtraHelp'):
+ helpMenu.delete(cascadeIndex-1)
del(self.menuExtraHelp)
-
+
def __DisplayExtraHelpCallback(self,helpFile):
def DisplayExtraHelp(helpFile=helpFile):
self.display_docs(helpFile)
return DisplayExtraHelp
-
+
def UpdateRecentFilesList(self,newFile=None):
"Load or update the recent files list, and menu if required"
rfList=[]
rfList=RFfile.readlines()
finally:
RFfile.close()
- if newFile:
+ if newFile:
newFile=os.path.abspath(newFile)+'\n'
if newFile in rfList:
rfList.remove(newFile)
for instance in self.top.instanceDict.keys():
menu = instance.menuRecentFiles
menu.delete(1,END)
- i = 0 ; ul = 0; ullen = len(ullist)
+ i = 0 ; ul = 0; ullen = len(ullist)
for file in rfList:
fileName=file[0:-1]
callback = instance.__RecentFileCallback(fileName)
command=callback,
underline=ul)
i += 1
-
+
def __CleanRecentFiles(self,rfList):
origRfList=rfList[:]
count=0
nonFiles=[]
for path in rfList:
- if not os.path.exists(path[0:-1]):
+ if not os.path.exists(path[0:-1]):
nonFiles.append(count)
count=count+1
if nonFiles:
finally:
RFfile.close()
return rfList
-
+
def __RecentFileCallback(self,fileName):
def OpenRecentFile(fileName=fileName):
self.io.open(editFile=fileName)
return OpenRecentFile
-
+
def saved_change_hook(self):
short = self.short_title()
long = self.long_title()
def maybesave(self):
if self.io:
if not self.get_saved():
- if self.top.state()!='normal':
+ if self.top.state()!='normal':
self.top.deiconify()
self.top.lower()
self.top.lift()
self.save_a_copy)
self.fileencoding = None
self.__id_print = self.text.bind("<<print-window>>", self.print_window)
-
+
def close(self):
# Undo command bindings
self.text.unbind("<<open-window-from-file>>", self.__id_open)
"# -*- coding: %s -*- \nto your file" % enc,
master = self.text)
return chars
-
+
def fixlastline(self):
c = self.text.get("end-2c")
if c != '\n':
output = "Printing command: %s\n" % repr(command) + output
tkMessageBox.showerror("Print status", output, master=self.text)
else: #no printing for this platform
- message="Printing is not enabled for this platform: %s" % platform
+ message="Printing is not enabled for this platform: %s" % platform
tkMessageBox.showinfo("Print status", message, master=self.text)
return "break"
-
+
opendialog = None
savedialog = None
# def flush(self):
# pass
-
-
-
-
-
-
-
save[filename] = cache[filename]
orig_checkcache()
cache.update(save)
-
+
# Patch linecache.checkcache():
linecache.checkcache = extended_linecache_checkcache
lines = open(self.breakpointPath,"r").readlines()
for line in lines:
if line.startswith(filename + '='):
- breakpoint_linenumbers = eval(line[len(filename)+1:])
+ breakpoint_linenumbers = eval(line[len(filename)+1:])
for breakpoint_linenumber in breakpoint_linenumbers:
self.set_breakpoint(breakpoint_linenumber)
"Extend base method - clear breaks when module is closed"
self.clear_file_breaks()
EditorWindow._close(self)
-
+
class PyShellFileList(FileList):
"Extend base class: file list when a shell is present"
class ModifiedColorDelegator(ColorDelegator):
"Extend base class: colorizer for the shell window itself"
-
+
def __init__(self):
ColorDelegator.__init__(self)
self.LoadTagDefs()
self.tag_remove("TODO", "1.0", "iomark")
self.tag_add("SYNC", "1.0", "iomark")
ColorDelegator.recolorize_main(self)
-
+
def LoadTagDefs(self):
ColorDelegator.LoadTagDefs(self)
theme = idleConf.GetOption('main','Theme','name')
rpcclt = None
rpcpid = None
- def spawn_subprocess(self):
+ def spawn_subprocess(self):
args = self.build_subprocess_arglist()
self.rpcpid = os.spawnv(os.P_NOWAIT, args[0], args)
# here are the applet architectures tried:
#
# framework applet: sys.executable + -p is correct
- # python 2.2 + pure python main applet:
+ # python 2.2 + pure python main applet:
# sys.executable + -p is correct
# pythonw idle.py: sys.executable + -c is correct
#
# close only the subprocess debugger
debug = self.getdebugger()
if debug:
- RemoteDebugger.close_subprocess_debugger(self.rpcclt)
+ RemoteDebugger.close_subprocess_debugger(self.rpcclt)
# kill subprocess, spawn a new one, accept connection
self.rpcclt.close()
self.spawn_subprocess()
while tb:
for rpcfile in exclude:
if tb[-1][0].count(rpcfile):
- break
+ break
else:
break
del tb[-1]
lines = source.split("\n")
linecache.cache[filename] = len(source)+1, 0, lines, filename
return filename
-
+
def showsyntaxerror(self, filename=None):
"""Extend base class method: Add Colorizing
"The Python Shell window is already executing a command; "
"please wait until it is finished.",
master=self.tkconsole.text)
-
+
def runcommand(self, code):
"Run the code without invoking the debugger"
# The code better not raise an exception!
usage_msg = """\
-USAGE: idle [-deis] [-t title] [file]*
+USAGE: idle [-deis] [-t title] [file]*
idle [-ds] [-t title] (-c cmd | -r file) [arg]*
idle [-ds] [-t title] - [arg]*
-
+
-h print this help message and exit
The following options will override the IDLE 'settings' configuration:
if args and args[0] == '-':
cmd = sys.stdin.read()
enable_shell = True
-
+
use_subprocess = True
# process sys.argv and sys.path:
sys.path.insert(0, dir)
# check the IDLE settings configuration (but command line overrides)
edit_start = idleConf.GetOption('main', 'General',
- 'editor-on-startup', type='bool')
+ 'editor-on-startup', type='bool')
enable_edit = enable_edit or edit_start
- enable_shell = enable_shell or not edit_start
+ enable_shell = enable_shell or not edit_start
# start editor and/or shell windows:
root = Tk(className="Idle")
fixwordbreaks(root)
3. Personal firewall software is preventing IDLE from using this port
IDLE makes and accepts connections only with this computer, and does not
-communicate over the internet in any way. Its use of port 8833 should not
+communicate over the internet in any way. Its use of port 8833 should not
be a security risk on a single-user machine.
"""
def clear_all_file_breaks(self, filename):
msg = self.idb.clear_all_file_breaks(filename)
return msg
-
+
#----------called by a FrameProxy----------
def frame_attr(self, fid, name):
debugger and RPC link objects. (The second reference to the debugger GUI
is deleted in PyShell.close_remote_debugger().)
- """
+ """
close_subprocess_debugger(rpcclt)
rpcclt.unregister(gui_adap_oid)
idb_adap_oid_ret = rpcclt.remotecall("exec", "start_the_debugger",\
(gui_adap_oid,), {})
assert idb_adap_oid_ret == idb_adap_oid, 'Idb restarted with different oid'
-
self.errorbox("Syntax error",
"There's an error in your program:\n" + msg)
return False
-
+
def colorize_syntax_error(self, msg, lineno, offset):
text = self.editwin.text
pos = "0.0 + %d lines + %d chars" % (lineno-1, offset-1)
else:
text.mark_set("insert", pos + "+1c")
text.see(pos)
-
+
def run_script_event(self, event):
"Check syntax, if ok run the script in the shell top level"
filename = self.getfilename()
('_Zoom Height', '<<zoom-height>>'),
])
]
-
+
def __init__(self, editwin):
self.editwin = editwin
#newy = 24
newy = 0
#newheight = newheight - 96
- newheight = newheight - 88
+ newheight = newheight - 88
if height >= newheight:
newgeom = ""
else:
class AboutDialog(Toplevel):
"""
modal about dialog for idle
- """
+ """
def __init__(self,parent,title):
Toplevel.__init__(self, parent)
self.configure(borderwidth=5)
parent.winfo_rooty()+30))
self.bg="#707070"
self.fg="#ffffff"
-
+
self.CreateWidgets()
self.resizable(height=FALSE,width=FALSE)
self.title(title)
self.bind('<Return>',self.Ok) #dismiss dialog
self.bind('<Escape>',self.Ok) #dismiss dialog
self.wait_window()
-
+
def CreateWidgets(self):
frameMain = Frame(self,borderwidth=2,relief=SUNKEN)
frameButtons = Frame(self)
#handle weird tk version num in windoze python >= 1.6 (?!?)
tkVer = `TkVersion`.split('.')
tkVer[len(tkVer)-1] = str('%.3g' % (float('.'+tkVer[len(tkVer)-1])))[2:]
- if tkVer[len(tkVer)-1] == '':
+ if tkVer[len(tkVer)-1] == '':
tkVer[len(tkVer)-1] = '0'
tkVer = string.join(tkVer,'.')
labelTkVer = Label(frameBg,text='Tk version: '+
def ShowLicense(self):
self.ViewFile('About - License','LICENSE.txt')
-
+
def ShowCredits(self):
self.ViewFile('About - Credits','CREDITS.txt')
def Ok(self, event=None):
self.destroy()
-
+
if __name__ == '__main__':
#test the dialog
root=Tk()
"boolcheck - import this module to ensure True, False, bool() builtins exist."
-try:
+try:
True
except NameError:
import __builtin__
__builtin__.False = 0
from operator import truth
__builtin__.bool = truth
-
class ConfigDialog(Toplevel):
"""
configuration dialog for idle
- """
+ """
def __init__(self,parent,title):
Toplevel.__init__(self, parent)
self.configure(borderwidth=5)
parent.winfo_rooty()+30))
#Theme Elements. Each theme element key is it's display name.
#The first value of the tuple is the sample area tag name.
- #The second value is the display name list sort index.
+ #The second value is the display name list sort index.
self.themeElements={'Normal Text':('normal','00'),
'Python Keywords':('keyword','01'),
'Python Definitions':('definition','02'),
#self.bind('<Alt-a>',self.Apply) #apply changes, save
#self.bind('<F1>',self.Help) #context help
self.LoadConfigs()
- self.AttachVarCallbacks() #avoid callbacks during LoadConfigs
+ self.AttachVarCallbacks() #avoid callbacks during LoadConfigs
self.wait_window()
-
+
def CreateWidgets(self):
self.tabPages = TabPageSet(self,
pageNames=['Fonts/Tabs','Highlighting','Keys','General'])
self.buttonCancel.pack(side=LEFT,padx=5,pady=5)
frameActionButtons.pack(side=BOTTOM)
self.tabPages.pack(side=TOP,expand=TRUE,fill=BOTH)
-
+
def CreatePageFontTab(self):
#tkVars
self.fontSize=StringVar(self)
self.fontName=StringVar(self)
self.spaceNum=IntVar(self)
#self.tabCols=IntVar(self)
- self.indentBySpaces=BooleanVar(self)
+ self.indentBySpaces=BooleanVar(self)
self.editFont=tkFont.Font(self,('courier',12,'normal'))
##widget creation
#body frame
self.fgHilite=BooleanVar(self)
self.colour=StringVar(self)
self.fontName=StringVar(self)
- self.themeIsBuiltin=BooleanVar(self)
+ self.themeIsBuiltin=BooleanVar(self)
self.highlightTarget=StringVar(self)
##widget creation
#body frame
(' ','normal'),('stderr','stderr'),('\n','normal'))
for txTa in textAndTags:
text.insert(END,txTa[0],txTa[1])
- for element in self.themeElements.keys():
+ 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))
self.radioBg=Radiobutton(frameFgBg,variable=self.fgHilite,
value=0,text='Background',command=self.SetColourSampleBinding)
self.fgHilite.set(1)
- buttonSaveCustomTheme=Button(frameCustom,
+ buttonSaveCustomTheme=Button(frameCustom,
text='Save as New Custom Theme',command=self.SaveAsNewTheme)
#frameTheme
labelThemeTitle=Label(frameTheme,text='Select a Highlighting Theme')
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)
+ buttonSaveCustomTheme.pack(side=BOTTOM,fill=X,padx=5,pady=5)
#frameTheme
labelThemeTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
labelTypeTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
self.bindingTarget=StringVar(self)
self.builtinKeys=StringVar(self)
self.customKeys=StringVar(self)
- self.keysAreBuiltin=BooleanVar(self)
+ self.keysAreBuiltin=BooleanVar(self)
self.keyBinding=StringVar(self)
##widget creation
#body frame
frameKeySets.pack(side=LEFT,padx=5,pady=5,fill=Y)
#frameCustom
labelCustomTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
- buttonSaveCustomKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5)
- self.buttonNewKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5)
+ buttonSaveCustomKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5)
+ self.buttonNewKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5)
frameTarget.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH)
#frame target
frameTarget.columnconfigure(0,weight=1)
return frame
def CreatePageGeneral(self):
- #tkVars
- self.winWidth=StringVar(self)
+ #tkVars
+ self.winWidth=StringVar(self)
self.winHeight=StringVar(self)
- self.startupEdit=IntVar(self)
+ self.startupEdit=IntVar(self)
self.userHelpBrowser=BooleanVar(self)
self.helpBrowser=StringVar(self)
#widget creation
#body
frame=self.tabPages.pages['General']['page']
- #body section frames
+ #body section frames
frameRun=Frame(frame,borderwidth=2,relief=GROOVE)
frameWinSize=Frame(frame,borderwidth=2,relief=GROOVE)
frameHelp=Frame(frame,borderwidth=2,relief=GROOVE)
labelRunTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
labelRunChoiceTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
radioStartupEdit.pack(side=LEFT,anchor=W,padx=5,pady=5)
- radioStartupShell.pack(side=LEFT,anchor=W,padx=5,pady=5)
+ radioStartupShell.pack(side=LEFT,anchor=W,padx=5,pady=5)
#frameWinSize
labelWinSizeTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
entryWinHeight.pack(side=RIGHT,anchor=E,padx=10,pady=5)
self.colour.trace_variable('w',self.VarChanged_colour)
self.builtinTheme.trace_variable('w',self.VarChanged_builtinTheme)
self.customTheme.trace_variable('w',self.VarChanged_customTheme)
- self.themeIsBuiltin.trace_variable('w',self.VarChanged_themeIsBuiltin)
+ self.themeIsBuiltin.trace_variable('w',self.VarChanged_themeIsBuiltin)
self.highlightTarget.trace_variable('w',self.VarChanged_highlightTarget)
self.keyBinding.trace_variable('w',self.VarChanged_keyBinding)
self.builtinKeys.trace_variable('w',self.VarChanged_builtinKeys)
self.customKeys.trace_variable('w',self.VarChanged_customKeys)
- self.keysAreBuiltin.trace_variable('w',self.VarChanged_keysAreBuiltin)
+ self.keysAreBuiltin.trace_variable('w',self.VarChanged_keysAreBuiltin)
self.winWidth.trace_variable('w',self.VarChanged_winWidth)
self.winHeight.trace_variable('w',self.VarChanged_winHeight)
self.startupEdit.trace_variable('w',self.VarChanged_startupEdit)
def VarChanged_fontSize(self,*params):
value=self.fontSize.get()
self.AddChangedItem('main','EditorWindow','font-size',value)
-
+
def VarChanged_fontName(self,*params):
value=self.fontName.get()
self.AddChangedItem('main','EditorWindow','font',value)
def VarChanged_highlightTarget(self,*params):
self.SetHighlightTarget()
-
+
def VarChanged_keyBinding(self,*params):
value=self.keyBinding.get()
keySet=self.customKeys.get()
extName=idleConf.GetExtnNameForEvent(event)
extKeybindSection=extName+'_cfgBindings'
self.AddChangedItem('extensions',extKeybindSection,event,value)
-
+
def VarChanged_builtinKeys(self,*params):
value=self.builtinKeys.get()
self.AddChangedItem('main','Keys','name',value)
self.LoadKeysList(value)
def VarChanged_keysAreBuiltin(self,*params):
- value=self.keysAreBuiltin.get()
+ value=self.keysAreBuiltin.get()
self.AddChangedItem('main','Keys','default',value)
- if value:
+ if value:
self.VarChanged_builtinKeys()
else:
self.VarChanged_customKeys()
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
- #dictionary. The key should be the config file section name and the
+ #should be made in the relevant section (config type) of this
+ #dictionary. The key should be the config file section name and the
#value a dictionary, whose key:value pairs are item=value pairs for
#that config file section.
self.changedItems={'main':{},'highlight':{},'keys':{},'extensions':{}}
def AddChangedItem(self,type,section,item,value):
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]={}
self.changedItems[type][section][item]=value
-
+
def GetDefaultItems(self):
dItems={'main':{},'highlight':{},'keys':{},'extensions':{}}
for configType in dItems.keys():
for section in sections:
dItems[configType][section]={}
options=idleConf.defaultCfg[configType].GetOptionList(section)
- for option in options:
+ for option in options:
dItems[configType][section][option]=(
idleConf.defaultCfg[configType].Get(section,option))
return dItems
-
+
def SetThemeType(self):
if self.themeIsBuiltin.get():
self.optMenuThemeBuiltin.config(state=NORMAL)
self.radioKeysCustom.config(state=NORMAL)
self.optMenuKeysCustom.config(state=NORMAL)
self.buttonDeleteCustomKeys.config(state=NORMAL)
-
+
def GetNewKeys(self):
listIndex=self.listBindings.index(ANCHOR)
binding=self.listBindings.get(listIndex)
bindName=binding.split()[0] #first part, up to first space
- if self.keysAreBuiltin.get():
+ if self.keysAreBuiltin.get():
currentKeySetName=self.builtinKeys.get()
- else:
+ else:
currentKeySetName=self.customKeys.get()
currentBindings=idleConf.GetCurrentKeySet()
if currentKeySetName in self.changedItems['keys'].keys(): #unsaved changes
self.listBindings.select_set(listIndex)
self.listBindings.select_anchor(listIndex)
return
- else: #create new custom key set based on previously active key set
- self.CreateNewKeySet(newKeySet)
+ else: #create new custom key set based on previously active key set
+ self.CreateNewKeySet(newKeySet)
self.listBindings.delete(listIndex)
self.listBindings.insert(listIndex,bindName+' - '+newKeys)
self.listBindings.select_set(listIndex)
newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set',
message,usedNames).result
return newKeySet
-
+
def SaveAsNewKeySet(self):
newKeysName=self.GetNewKeysName('New Key Set Name:')
if newKeysName:
def CreateNewKeySet(self,newKeySetName):
#creates new custom key set based on the previously active key set,
#and makes the new key set active
- if self.keysAreBuiltin.get():
+ if self.keysAreBuiltin.get():
prevKeySetName=self.builtinKeys.get()
- else:
+ else:
prevKeySetName=self.customKeys.get()
prevKeys=idleConf.GetCoreKeys(prevKeySetName)
newKeys={}
self.optMenuKeysCustom.SetMenu(customKeyList,newKeySetName)
self.keysAreBuiltin.set(0)
self.SetKeysType()
-
+
def LoadKeysList(self,keySetName):
reselect=0
newKeySet=0
bindNames=keySet.keys()
bindNames.sort()
self.listBindings.delete(0,END)
- for bindName in bindNames:
+ for bindName in bindNames:
key=string.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():
#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 '+
prevColour=self.frameColourSet.cget('bg')
rgbTuplet, colourString = tkColorChooser.askcolor(parent=self,
title='Pick new colour for : '+target,initialcolor=prevColour)
- if colourString and (colourString!=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. '+
newTheme=self.GetNewThemeName(message)
if not newTheme: #user cancelled custom theme creation
return
- else: #create new custom theme based on previously active theme
- self.CreateNewTheme(newTheme)
+ else: #create new custom theme based on previously active theme
+ self.CreateNewTheme(newTheme)
self.colour.set(colourString)
else: #current theme is user defined
self.colour.set(colourString)
-
+
def OnNewColourSet(self):
newColour=self.colour.get()
self.frameColourSet.config(bg=newColour)#set sample
newTheme=GetCfgSectionNameDialog(self,'New Custom Theme',
message,usedNames).result
return newTheme
-
+
def SaveAsNewTheme(self):
newThemeName=self.GetNewThemeName('New Theme Name:')
if newThemeName:
def CreateNewTheme(self,newThemeName):
#creates new custom theme based on the previously active theme,
#and makes the new theme active
- if self.themeIsBuiltin.get():
+ if self.themeIsBuiltin.get():
themeType='default'
themeName=self.builtinTheme.get()
- else:
+ else:
themeType='user'
themeName=self.customTheme.get()
newTheme=idleConf.GetThemeDict(themeType,themeName)
self.optMenuThemeCustom.SetMenu(customThemeList,newThemeName)
self.themeIsBuiltin.set(0)
self.SetThemeType()
-
+
def OnListFontButtonRelease(self,event):
self.fontName.set(self.listFontName.get(ANCHOR))
self.SetFontSample()
-
+
def SetFontSample(self,event=None):
fontName=self.fontName.get()
- if self.fontBold.get():
+ if self.fontBold.get():
fontWeight=tkFont.BOLD
- else:
+ else:
fontWeight=tkFont.NORMAL
self.editFont.config(size=self.fontSize.get(),
weight=fontWeight,family=fontName)
self.radioBg.config(state=NORMAL)
self.fgHilite.set(1)
self.SetColourSample()
-
+
def SetColourSampleBinding(self,*args):
self.SetColourSample()
-
+
def SetColourSample(self):
#set the colour smaple area
tag=self.themeElements[self.highlightTarget.get()][0]
else: plane='background'
colour=self.textHighlightSample.tag_cget(tag,plane)
self.frameColourSet.config(bg=colour)
-
+
def PaintThemeSample(self):
if self.themeIsBuiltin.get(): #a default theme
theme=self.builtinTheme.get()
element=self.themeElements[elementTitle][0]
colours=idleConf.GetHighlight(theme,element)
if element=='cursor': #cursor sample needs special painting
- colours['background']=idleConf.GetHighlight(theme,
+ colours['background']=idleConf.GetHighlight(theme,
'normal', fgBg='bg')
#handle any unsaved changes to this theme
if theme in self.changedItems['highlight'].keys():
colours['background']=themeDict[element+'-background']
apply(self.textHighlightSample.tag_config,(element,),colours)
self.SetColourSample()
-
+
def OnCheckUserHelpBrowser(self):
if self.userHelpBrowser.get():
self.entryHelpBrowser.config(state=NORMAL)
else:
self.entryHelpBrowser.config(state=DISABLED)
-
+
def HelpSourceSelected(self,event):
self.SetHelpListButtonStates()
-
+
def SetHelpListButtonStates(self):
if self.listHelp.size()<1: #no entries in list
self.buttonHelpListEdit.config(state=DISABLED)
self.listHelp.insert(END,helpSource[0]+' '+helpSource[1])
self.UpdateUserHelpChangedItems()
self.SetHelpListButtonStates()
-
+
def HelpListItemEdit(self):
itemIndex=self.listHelp.index(ANCHOR)
helpSource=self.userHelpList[itemIndex]
self.listHelp.insert(itemIndex,newHelpSource[0]+' '+newHelpSource[1])
self.UpdateUserHelpChangedItems()
self.SetHelpListButtonStates()
-
+
def HelpListItemRemove(self):
itemIndex=self.listHelp.index(ANCHOR)
del(self.userHelpList[itemIndex])
self.listHelp.delete(itemIndex)
self.UpdateUserHelpChangedItems()
self.SetHelpListButtonStates()
-
+
def UpdateUserHelpChangedItems(self):
#clear and rebuild the HelpFiles secion in self.changedItems
if self.changedItems['main'].has_key('HelpFiles'):
for num in range(1,len(self.userHelpList)+1):
self.AddChangedItem('main','HelpFiles',str(num),
string.join(self.userHelpList[num-1],';'))
-
+
def LoadFontCfg(self):
##base editor font selection list
fonts=list(tkFont.families(self))
##fontWeight
self.fontBold.set(idleConf.GetOption('main','EditorWindow',
'font-bold',default=0,type='bool'))
- ##font sample
+ ##font sample
self.SetFontSample()
-
+
def LoadTabCfg(self):
##indent type radiobuttons
spaceIndent=idleConf.GetOption('main','Indent','use-spaces',
# default=4,type='int')
self.spaceNum.set(spaceNum)
#self.tabCols.set(tabCols)
-
+
def LoadThemeCfg(self):
##current theme type radiobutton
self.themeIsBuiltin.set(idleConf.GetOption('main','Theme','default',
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
##load theme element option menu
themeNames=self.themeElements.keys()
themeNames.sort(self.__ThemeNameIndexCompare)
- self.optMenuHighlightTarget.SetMenu(themeNames,themeNames[0])
+ self.optMenuHighlightTarget.SetMenu(themeNames,themeNames[0])
self.PaintThemeSample()
self.SetHighlightTarget()
-
+
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
else: return 1
-
+
def LoadKeyCfg(self):
##current keys type radiobutton
self.keysAreBuiltin.set(idleConf.GetOption('main','Keys','default',
itemList=idleConf.GetSectionList('user','keys')
itemList.sort()
if not itemList:
- self.radioKeysCustom.config(state=DISABLED)
- self.customKeys.set('- no custom keys -')
+ self.radioKeysCustom.config(state=DISABLED)
+ self.customKeys.set('- no custom keys -')
else:
self.optMenuKeysCustom.SetMenu(itemList,itemList[0])
else: #user key set selected
itemList=idleConf.GetSectionList('default','keys')
itemList.sort()
self.optMenuKeysBuiltin.SetMenu(itemList,itemList[0])
- self.SetKeysType()
+ self.SetKeysType()
##load keyset element list
keySetName=idleConf.CurrentKeys()
self.LoadKeysList(keySetName)
-
+
def LoadGeneralCfg(self):
#startup state
self.startupEdit.set(idleConf.GetOption('main','General',
'editor-on-startup',default=1,type='bool'))
#initial window size
- self.winWidth.set(idleConf.GetOption('main','EditorWindow','width'))
+ self.winWidth.set(idleConf.GetOption('main','EditorWindow','width'))
self.winHeight.set(idleConf.GetOption('main','EditorWindow','height'))
#help browsing
self.userHelpList=idleConf.GetExtraHelpSourceList('user')
#self.helpBrowser.set(idleConf.GetOption('main','General',
# 'user-help-browser-command',default=''))
#self.OnCheckUserHelpBrowser()
-
+
def LoadConfigs(self):
"""
load configuration from default and user config files and populate
the widgets on the config dialog pages.
"""
### fonts / tabs page
- self.LoadFontCfg()
- self.LoadTabCfg()
+ self.LoadFontCfg()
+ self.LoadTabCfg()
### highlighting page
self.LoadThemeCfg()
### keys page
self.LoadKeyCfg()
### general page
self.LoadGeneralCfg()
-
+
def SaveNewKeySet(self,keySetName,keySet):
"""
save a newly created core key set.
for event in keySet.keys():
value=keySet[event]
idleConf.userCfg['keys'].SetOption(keySetName,event,value)
-
+
def SaveNewTheme(self,themeName,theme):
"""
save a newly created theme.
for element in theme.keys():
value=theme[element]
idleConf.userCfg['highlight'].SetOption(themeName,element,value)
-
+
def SetUserValue(self,configType,section,item,value):
if idleConf.defaultCfg[configType].has_option(section,item):
if idleConf.defaultCfg[configType].Get(section,item)==value:
return idleConf.userCfg[configType].RemoveOption(section,item)
#if we got here set the option
return idleConf.userCfg[configType].SetOption(section,item,value)
-
+
def SaveAllChangedConfigs(self):
"""
save all configuration changes to user config files.
value=self.changedItems[configType][section][item]
if self.SetUserValue(configType,section,item,value):
cfgTypeHasChanges=1
- if cfgTypeHasChanges:
- idleConf.userCfg[configType].Save()
+ if cfgTypeHasChanges:
+ idleConf.userCfg[configType].Save()
self.ResetChangedItems() #clear the changed items dict
-
+
def ActivateConfigChanges(self):
- #things that need to be done to make
+ #things that need to be done to make
#applied config changes dynamic:
#update editor/shell font and repaint
#dynamically update indentation setttings
instance.ResetFont()
instance.ResetKeybindings()
instance.ResetExtraHelpMenu()
-
+
def Cancel(self):
self.destroy()
# when a problem occurs in returning a requested configuration value back to
# idle. This is to allow idle to continue to function in spite of errors in
# the retrieval of config information. When a default is returned instead of
-# a requested config value, a message is printed to stderr to aid in
-# configuration problem notification and resolution.
+# a requested config value, a message is printed to stderr to aid in
+# configuration problem notification and resolution.
import os, sys, string
from ConfigParser import ConfigParser, NoOptionError, NoSectionError
"""
self.file=cfgFile
ConfigParser.__init__(self,defaults=cfgDefaults)
-
+
def Get(self, section, option, type=None, default=None):
"""
Get an option value for given section/option or return default.
If type is specified, return as type.
"""
- if type=='bool':
+ if type=='bool':
getVal=self.getboolean
- elif type=='int':
+ elif type=='int':
getVal=self.getint
- else:
+ else:
getVal=self.get
if self.has_option(section,option):
#return getVal(section, option, raw, vars, default)
return []
def Load(self):
- """
- Load the configuration file from disk
+ """
+ Load the configuration file from disk
"""
self.read(self.file)
-
+
class IdleUserConfParser(IdleConfParser):
"""
IdleConfigParser specialised for user configuration handling.
"""
if not self.has_section(section):
self.add_section(section)
-
+
def RemoveEmptySections(self):
"""
remove any sections that have no options
"""
for section in self.sections():
if not self.GetOptionList(section):
- self.remove_section(section)
-
+ self.remove_section(section)
+
def IsEmpty(self):
"""
Remove empty sections and then return 1 if parser has no sections
return 0
else:
return 1
-
+
def RemoveOption(self,section,option):
"""
If section/option exists, remove it.
"""
if self.has_section(section):
return self.remove_option(section,option)
-
+
def SetOption(self,section,option,value):
"""
Sets option to value, adding section if required.
self.add_section(section)
self.set(section,option,value)
return 1
-
+
def RemoveFile(self):
"""
Removes the user config file from disk if it exists.
"""
if os.path.exists(self.file):
- os.remove(self.file)
-
+ os.remove(self.file)
+
def Save(self):
"""
If config isn't empty, write file to disk. If config is empty,
self.CreateConfigHandlers()
self.LoadCfgFiles()
#self.LoadCfg()
-
+
def CreateConfigHandlers(self):
"""
- set up a dictionary of config parsers for default and user
+ set up a dictionary of config parsers for default and user
configurations respectively
"""
#build idle install path
defCfgFiles={}
usrCfgFiles={}
for cfgType in configTypes: #build config file names
- defCfgFiles[cfgType]=os.path.join(idleDir,'config-'+cfgType+'.def')
- usrCfgFiles[cfgType]=os.path.join(userDir,'config-'+cfgType+'.cfg')
+ defCfgFiles[cfgType]=os.path.join(idleDir,'config-'+cfgType+'.def')
+ usrCfgFiles[cfgType]=os.path.join(userDir,'config-'+cfgType+'.cfg')
for cfgType in configTypes: #create config parsers
self.defaultCfg[cfgType]=IdleConfParser(defCfgFiles[cfgType])
self.userCfg[cfgType]=IdleUserConfParser(usrCfgFiles[cfgType])
-
+
def GetUserCfgDir(self):
"""
- Creates (if required) and returns a filesystem directory for storing
+ Creates (if required) and returns a filesystem directory for storing
user config files.
"""
cfgDir='.idlerc'
if userDir=='~': #we still don't have a home directory
#traditionally idle has defaulted to os.getcwd(), is this adeqate?
userDir = os.getcwd() #hack for no real homedir
- userDir=os.path.join(userDir,cfgDir)
+ userDir=os.path.join(userDir,cfgDir)
if not os.path.exists(userDir):
- try: #make the config dir if it doesn't exist yet
+ try: #make the config dir if it doesn't exist yet
os.mkdir(userDir)
except IOError:
warn=('\n Warning: unable to create user config directory\n '+
userDir+'\n')
sys.stderr.write(warn)
return userDir
-
+
def GetOption(self, configType, section, option, default=None, type=None):
"""
- Get an option value for given config type and given general
+ Get an option value for given config type and given general
configuration section/option or return a default. If type is specified,
- return as type. Firstly the user configuration is checked, with a
- fallback to the default configuration, and a final 'catch all'
- fallback to a useable passed-in default if the option isn't present in
+ return as type. Firstly the user configuration is checked, with a
+ fallback to the default configuration, and a final 'catch all'
+ fallback to a useable passed-in default if the option isn't present in
either the user or the default configuration.
configType must be one of ('main','extensions','highlight','keys')
If a default is returned a warning is printed to stderr.
' returning default value: '+`default`+'\n')
sys.stderr.write(warning)
return default
-
+
def GetSectionList(self, configSet, configType):
"""
- Get a list of sections from either the user or default config for
+ Get a list of sections from either the user or default config for
the given config type.
- configSet must be either 'user' or 'default'
+ configSet must be either 'user' or 'default'
configType must be one of ('main','extensions','highlight','keys')
"""
if not (configType in ('main','extensions','highlight','keys')):
else:
raise InvalidConfigSet, 'Invalid configSet specified'
return cfgParser.sections()
-
+
def GetHighlight(self, theme, element, fgBg=None):
"""
return individual highlighting theme elements.
fgBg - string ('fg'or'bg') or None, if None return a dictionary
- containing fg and bg colours (appropriate for passing to Tkinter in,
- e.g., a tag_config call), otherwise fg or bg colour only as specified.
+ containing fg and bg colours (appropriate for passing to Tkinter in,
+ e.g., a tag_config call), otherwise fg or bg colour only as specified.
"""
if self.defaultCfg['highlight'].has_section(theme):
themeDict=self.GetThemeDict('default',theme)
fore=themeDict[element+'-foreground']
if element=='cursor': #there is no config value for cursor bg
back=themeDict['normal-background']
- else:
+ else:
back=themeDict[element+'-background']
highlight={"foreground": fore,"background": back}
if not fgBg: #return dict of both colours
return highlight["foreground"]
if fgBg == 'bg':
return highlight["background"]
- else:
+ else:
raise InvalidFgBg, 'Invalid fgBg specified'
def GetThemeDict(self,type,themeName):
themeName - string, theme name
Returns a dictionary which holds {option:value} for each element
in the specified theme. Values are loaded over a set of ultimate last
- fallback defaults to guarantee that all theme elements are present in
+ fallback defaults to guarantee that all theme elements are present in
a newly created theme.
"""
if type == 'user':
#(apart from cursor) even though all these values are not yet used
#by idle, to allow for their use in the future. Default values are
#generally black and white.
- theme={ 'normal-foreground':'#000000',
- 'normal-background':'#ffffff',
- 'keyword-foreground':'#000000',
- 'keyword-background':'#ffffff',
- 'comment-foreground':'#000000',
- 'comment-background':'#ffffff',
+ theme={ 'normal-foreground':'#000000',
+ 'normal-background':'#ffffff',
+ 'keyword-foreground':'#000000',
+ 'keyword-background':'#ffffff',
+ 'comment-foreground':'#000000',
+ 'comment-background':'#ffffff',
'string-foreground':'#000000',
'string-background':'#ffffff',
- 'definition-foreground':'#000000',
+ 'definition-foreground':'#000000',
'definition-background':'#ffffff',
'hilite-foreground':'#000000',
'hilite-background':'gray',
'hit-foreground':'#ffffff',
'hit-background':'#000000',
'error-foreground':'#ffffff',
- 'error-background':'#000000',
- #cursor (only foreground can be set)
- 'cursor-foreground':'#000000',
+ 'error-background':'#000000',
+ #cursor (only foreground can be set)
+ 'cursor-foreground':'#000000',
#shell window
'stdout-foreground':'#000000',
'stdout-background':'#ffffff',
'\n from theme '+`themeName`+'.\n'+
' returning default value: '+`theme[element]`+'\n')
sys.stderr.write(warning)
- colour=cfgParser.Get(themeName,element,default=theme[element])
+ colour=cfgParser.Get(themeName,element,default=theme[element])
theme[element]=colour
return theme
-
+
def CurrentTheme(self):
"""
- Returns the name of the currently active theme
+ Returns the name of the currently active theme
"""
return self.GetOption('main','Theme','name',default='')
-
+
def CurrentKeys(self):
"""
- Returns the name of the currently active key set
+ Returns the name of the currently active key set
"""
return self.GetOption('main','Keys','name',default='')
-
+
def GetExtensions(self, activeOnly=1):
"""
Gets a list of all idle extensions declared in the config files.
self.GetSectionList('user','extensions'))
for extn in userExtns:
if extn not in extns: #user has added own extension
- extns.append(extn)
+ extns.append(extn)
if activeOnly:
activeExtns=[]
for extn in extns:
activeExtns.append(extn)
return activeExtns
else:
- return extns
+ return extns
def RemoveKeyBindNames(self,extnNameList):
#get rid of keybinding section names
names=extnNameList
kbNameIndicies=[]
for name in names:
- if name.endswith('_bindings') or name.endswith('_cfgBindings'):
- kbNameIndicies.append(names.index(name))
+ if name.endswith('_bindings') or name.endswith('_cfgBindings'):
+ kbNameIndicies.append(names.index(name))
kbNameIndicies.sort()
kbNameIndicies.reverse()
- for index in kbNameIndicies: #delete each keybinding section name
+ for index in kbNameIndicies: #delete each keybinding section name
del(names[index])
return names
-
+
def GetExtnNameForEvent(self,virtualEvent):
"""
Returns the name of the extension that virtualEvent is bound in, or
if event == vEvent:
extName=extn
return extName
-
+
def GetExtensionKeys(self,extensionName):
"""
returns a dictionary of the configurable keybindings for a particular
event='<<'+eventName+'>>'
binding=activeKeys[event]
extKeys[event]=binding
- return extKeys
-
+ return extKeys
+
def __GetRawExtensionKeys(self,extensionName):
"""
returns a dictionary of the configurable keybindings for a particular
eventName,default='').split()
event='<<'+eventName+'>>'
extKeys[event]=binding
- return extKeys
-
+ return extKeys
+
def GetExtensionBindings(self,extensionName):
"""
Returns a dictionary of all the event bindings for a particular
extension. The configurable keybindings are returned as they exist in
- the dictionary returned by GetCurrentKeySet; that is, where re-used
+ the dictionary returned by GetCurrentKeySet; that is, where re-used
keybindings are disabled.
"""
bindsName=extensionName+'_bindings'
eventName,default='').split()
event='<<'+eventName+'>>'
extBinds[event]=binding
-
- return extBinds
-
+
+ return extBinds
+
def GetKeyBinding(self, keySetName, eventStr):
"""
returns the keybinding for a specific event.
keySetName - string, name of key binding set
- eventStr - string, the virtual event we want the binding for,
+ eventStr - string, the virtual event we want the binding for,
represented as a string, eg. '<<event>>'
"""
eventName=eventStr[2:-2] #trim off the angle brackets
def GetCurrentKeySet(self):
return self.GetKeySet(self.CurrentKeys())
-
+
def GetKeySet(self,keySetName):
"""
- Returns a dictionary of: all requested core keybindings, plus the
+ Returns a dictionary of: all requested core keybindings, plus the
keybindings for all currently active extensions. If a binding defined
in an extension is already in use, that binding is disabled.
"""
the enclosing '<< >>'
"""
return ('<<'+virtualEvent+'>>') in self.GetCoreKeys().keys()
-
+
def GetCoreKeys(self, keySetName=None):
"""
returns the requested set of core keybindings, with fallbacks if
'<<do-nothing>>': ['<Control-x>'],
'<<end-of-file>>': ['<Control-d>'],
'<<python-docs>>': ['<F1>'],
- '<<python-context-help>>': ['<Shift-F1>'],
+ '<<python-context-help>>': ['<Shift-F1>'],
'<<history-next>>': ['<Alt-n>'],
'<<history-previous>>': ['<Alt-p>'],
'<<interrupt-execution>>': ['<Control-c>'],
'<<find-selection>>': ['<Control-F3>'],
'<<find>>': ['<Control-f>'],
'<<replace>>': ['<Control-h>'],
- '<<goto-line>>': ['<Alt-g>'],
+ '<<goto-line>>': ['<Alt-g>'],
'<<smart-backspace>>': ['<Key-BackSpace>'],
'<<newline-and-indent>>': ['<Key-Return> <Key-KP_Enter>'],
'<<smart-indent>>': ['<Key-Tab>'],
' returning default value: '+`keyBindings[event]`+'\n')
sys.stderr.write(warning)
return keyBindings
-
+
def GetExtraHelpSourceList(self,configSet):
"""
Returns a list of tuples containing the details of any additional
help sources configured in the requested configSet ('user' or 'default')
, or an empty list if there are none. Returned tuples are of the form
form (menu_item , path_to_help_file , option).
- """
+ """
helpSources=[]
if configSet=='user':
cfgParser=self.userCfg['main']
- elif configSet=='default':
+ elif configSet=='default':
cfgParser=self.defaultCfg['main']
else:
raise InvalidConfigSet, 'Invalid configSet specified'
def GetAllExtraHelpSourcesList(self):
"""
- Returns a list of tuples containing the details of all additional help
+ Returns a list of tuples containing the details of all additional help
sources configured, or an empty list if there are none. Tuples are of
the format returned by GetExtraHelpSourceList.
- """
- allHelpSources=( self.GetExtraHelpSourceList('default')+
+ """
+ allHelpSources=( self.GetExtraHelpSourceList('default')+
self.GetExtraHelpSourceList('user') )
- return allHelpSources
-
+ return allHelpSources
+
def LoadCfgFiles(self):
- """
+ """
load all configuration files.
"""
for key in self.defaultCfg.keys():
- self.defaultCfg[key].Load()
- self.userCfg[key].Load() #same keys
+ self.defaultCfg[key].Load()
+ self.userCfg[key].Load() #same keys
def SaveUserCfgFiles(self):
"""
write all loaded user configuration files back to disk
"""
for key in self.userCfg.keys():
- self.userCfg[key].Save()
+ self.userCfg[key].Save()
idleConf=IdleConf()
print sections
for section in sections:
options=cfg[key].options(section)
- print section
+ print section
print options
for option in options:
print option, '=', cfg[key].Get(section,option)
self.withdraw() #hide while setting geometry
self.update_idletasks()
#needs to be done here so that the winfo_reqwidth is valid
- self.geometry("+%d+%d" %
+ self.geometry("+%d+%d" %
((parent.winfo_rootx()+((parent.winfo_width()/2)
-(self.winfo_reqwidth()/2)),
parent.winfo_rooty()+((parent.winfo_height()/2)
self.buttonCancel.grid(row=0,column=1,padx=5,pady=5)
def MenuOk(self):
- #simple validity check for a sensible
+ #simple validity check for a sensible
#menu item name
menuOk=1
menu=self.menu.get()
self.entryMenu.focus_set()
menuOk=0
return menuOk
-
+
def PathOk(self):
- #simple validity check for menu file path
+ #simple validity check for menu file path
pathOk=1
path=self.path.get()
path.strip()
self.entryPath.focus_set()
pathOk=0
return pathOk
-
+
def Ok(self, event=None):
if self.MenuOk():
if self.PathOk():
- self.result=( self.menu.get().strip(),self.path.get().strip() )
+ self.result=( self.menu.get().strip(),self.path.get().strip() )
self.destroy()
-
+
def Cancel(self, event=None):
self.result=None
self.destroy()
print dlg.result
Button(root,text='Dialog',command=run).pack()
root.mainloop()
-
-
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" %
+ self.geometry("+%d+%d" %
((parent.winfo_rootx()+((parent.winfo_width()/2)
-(self.winfo_reqwidth()/2)),
parent.winfo_rooty()+((parent.winfo_height()/2)
self.buttonCancel.grid(row=0,column=1,padx=5,pady=5)
def NameOk(self):
- #simple validity check for a sensible
+ #simple validity check for a sensible
#ConfigParser file section name
nameOk=1
name=self.name.get()
message='This name is already in use.')
nameOk=0
return nameOk
-
+
def Ok(self, event=None):
if self.NameOk():
self.result=self.name.get().strip()
self.destroy()
-
+
def Cancel(self, event=None):
self.result=''
self.destroy()
print dlg.result
Button(root,text='Dialog',command=run).pack()
root.mainloop()
-
-
#self.menu=self['menu']
self.variable=variable
self.command=kwargs.get('command')
-
+
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
+ value - initial value to set the optionmenu's menubutton to
"""
self['menu'].delete(0,'end')
for item in valueList:
"""
-dialog for building tkinter accelerator key bindings
+dialog for building tkinter accelerator key bindings
"""
from Tkinter import *
import tkMessageBox
action - string, the name of the virtual event these keys will be
mapped to
currentKeys - list, a list of all key sequence lists currently mapped
- to virtual events, for overlap checking
+ to virtual events, for overlap checking
"""
Toplevel.__init__(self, parent)
self.configure(borderwidth=5)
self.LoadFinalKeyList()
self.withdraw() #hide while setting geometry
self.update_idletasks()
- self.geometry("+%d+%d" %
+ 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
self.deiconify() #geometry set, unhide
self.wait_window()
-
+
def CreateWidgets(self):
frameMain = Frame(self,borderwidth=2,relief=SUNKEN)
frameMain.pack(side=TOP,expand=TRUE,fill=BOTH)
self.ClearKeySeq()
self.buttonLevel.config(text='Advanced Key Binding Entry >>')
self.frameKeySeqBasic.lift()
- self.frameControlsBasic.lift()
-
+ self.frameControlsBasic.lift()
+
def FinalKeySelected(self,event):
self.BuildKeyString()
-
+
def BuildKeyString(self):
keyList=[]
modifiers=self.GetModifiers()
finalKey=self.listKeysFinal.get(ANCHOR)
if modifiers: modifiers[0]='<'+modifiers[0]
keyList=keyList+modifiers
- if finalKey:
- if (not modifiers) and (finalKey not
+ if finalKey:
+ if (not modifiers) and (finalKey not
in self.alphanumKeys+self.punctuationKeys):
finalKey='<'+self.TranslateKey(finalKey)
else:
keyList.append(finalKey+'>')
keyStr=string.join(keyList,'-')
self.keyString.set(keyStr)
-
+
def GetModifiers(self):
modList = [variable.get() for variable in self.modifier_vars]
return filter(None, modList)
for variable in self.modifier_vars:
variable.set('')
self.keyString.set('')
-
+
def LoadFinalKeyList(self):
#these tuples are also available for use in validity checks
self.functionKeys=('F1','F2','F2','F4','F5','F6','F7','F8','F9',
self.whitespaceKeys+self.editKeys+self.moveKeys)
apply(self.listKeysFinal.insert,
(END,)+keys)
-
+
def TranslateKey(self,key):
#translate from key list value to tkinter key-id
translateDict={'~':'asciitilde','!':'exclam','@':'at','#':'numbersign',
key=translateDict[key]
key='Key-'+key
return key
-
+
def Ok(self, event=None):
if self.KeysOk():
self.result=self.keyString.get()
self.destroy()
-
+
def Cancel(self, event=None):
self.result=''
self.destroy()
-
+
def KeysOk(self):
#simple validity check
keysOk=1
tkMessageBox.showerror(title='Key Sequence Error',
message='No final key specified.')
keysOk=0
- elif (not modifiers) and (finalKey in
+ elif (not modifiers) and (finalKey in
self.alphanumKeys+self.punctuationKeys):
#modifier required
tkMessageBox.showerror(title='Key Sequence Error',
message='No modifier key(s) specified.')
keysOk=0
- elif (modifiers==['Shift']) and (finalKey not
+ elif (modifiers==['Shift']) and (finalKey not
in self.functionKeys+('Tab',)):
#shift alone is only a useful modifier with a function key
tkMessageBox.showerror(title='Key Sequence Error',
message='This key combination is already in use.')
keysOk=0
return keysOk
-
+
if __name__ == '__main__':
#test the dialog
root=Tk()
Installation:
see the install_IDLE target in python/dist/src/Mac/OSX/Makefile
-
-Usage:
+
+Usage:
1. Double clicking IDLE icon will open IDLE.
2. Dropping file on IDLE icon will open that file in IDLE.
__file__ = sys.argv[0]
idlelib = join(split(__file__)[0], 'idlelib')
if isdir(idlelib):
- sys.path.append(idlelib)
+ sys.path.append(idlelib)
# see if we are being asked to execute the subprocess code
if '-p' in sys.argv:
# def pickle_function(fn):
# assert isinstance(fn, type.FunctionType)
# return `fn`
-
+
copy_reg.pickle(types.CodeType, pickle_code, unpickle_code)
# copy_reg.pickle(types.FunctionType, pickle_function, unpickle_function)
def server_activate(self):
"""Override TCPServer method, connect() instead of listen()
-
+
Due to the reversed connection, self.server_address is actually the
address of the Idle Client to which we are connecting.
"""
self.socket.connect(self.server_address)
-
+
def get_request(self):
"Override TCPServer method, return already connected socket"
return self.socket, self.server_address
pass
def localcall(self, request):
- self.debug("localcall:", request)
+ self.debug("localcall:", request)
try:
how, (oid, methodname, args, kwargs) = request
except TypeError:
return ("EXCEPTION", (mod, name, args, tb))
def remotecall(self, oid, methodname, args, kwargs):
- self.debug("remotecall:")
+ self.debug("remotecall:")
seq = self.asynccall(oid, methodname, args, kwargs)
return self.asyncreturn(seq)
# do the best we can:
raise name, args
if how == "ERROR":
- self.debug("decoderesponse: Internal ERROR:", what)
+ self.debug("decoderesponse: Internal ERROR:", what)
raise RuntimeError, what
raise SystemError, (how, what)
cv.notify()
self.statelock.release()
continue
-
+
#----------------- end class SocketIO --------------------
class RemoteObject:
for name in dir(obj):
attr = getattr(obj, name)
if not callable(attr):
- attributes[name] = 1
+ attributes[name] = 1
class MethodProxy:
# XXX 25 Jul 02 KBK needs update to use rpc.py register/unregister methods
class RemotePerson:
def __init__(self,name):
- self.name = name
+ self.name = name
def greet(self, name):
print "(someone called greet)"
print "Hello %s, I am %s." % (name, self.name)
print
def getName(self):
print "(someone called getName)"
- print
+ print
return self.name
def greet_this_guy(self, name):
print "(someone called greet_this_guy)"
remote_guy.greet("Thomas Edison")
print "Done."
print
-
+
person = RemotePerson("Thomas Edison")
svr = RPCServer(addr)
svr.register('thomas', person)
thomas.greet("Alexander Bell")
#clt.remotecall("thomas","greet",("Alexander Bell",), {})
print "Done."
- print
+ print
time.sleep(2)
# demonstrates remote server calling local instance
class LocalPerson:
def __init__(self,name):
- self.name = name
+ self.name = name
def greet(self, name):
print "You've greeted me!"
def getName(self):
if __name__ == '__main__':
test()
-
-
class PageTab(Frame):
"""
a 'page tab' like framed button
- """
+ """
def __init__(self,parent):
Frame.__init__(self, parent,borderwidth=2,relief=RIDGE)
self.button=Radiobutton(self,padx=5,pady=5,takefocus=FALSE,
indicatoron=FALSE,highlightthickness=0,
borderwidth=0,selectcolor=self.cget('bg'))
self.button.pack()
-
+
class TabPageSet(Frame):
"""
a set of 'pages' with TabButtons for controlling their display
- """
+ """
def __init__(self,parent,pageNames=[],**kw):
"""
pageNames - a list of strings, each string will be the dictionary key
- to a page's data, and the name displayed on the page's tab. Should be
- specified in desired page order. The first page will be the default
+ to a page's data, and the name displayed on the page's tab. Should be
+ specified in desired page order. The first page will be the default
and first active page.
"""
Frame.__init__(self, parent, kw)
else:
raise InvalidTabPage, 'Invalid TabPage Name'
## pop up the active 'tab' only
- for page in self.pages.keys():
+ for page in self.pages.keys():
self.pages[page]['tab'].config(relief=RIDGE)
self.pages[self.GetActivePage()]['tab'].config(relief=RAISED)
## switch page
self.pages[self.GetActivePage()]['page'].lift()
-
+
def GetActivePage(self):
return self.activePage.get()
value=pageName)
self.pages[pageName]['tab'].pack(side=LEFT)
self.pages[pageName]['page'].grid(row=1,column=0,sticky=NSEW)
- if len(self.pages)==1: # adding first page
+ if len(self.pages)==1: # adding first page
self.defaultPage=pageName
self.activePage.set(self.defaultPage)
self.ChangePage()
# handle removing last remaining, or default, or active page
if not self.pages: # removed last remaining page
self.defaultPage=''
- return
+ return
if pageName==self.defaultPage: # set a new default page
self.defaultPage=\
self.tabBar.winfo_children()[0].button.cget('text')
- if pageName==self.GetActivePage(): # set a new active page
+ if pageName==self.GetActivePage(): # set a new active page
self.activePage.set(self.defaultPage)
self.ChangePage()
entryPgName.pack(padx=5)
tabPage.ChangePage()
root.mainloop()
-
##---------------------------------------------------------------------------##
##
-## idle - simple text view dialog
+## idle - simple text view dialog
## elguavas
-##
+##
##---------------------------------------------------------------------------##
"""
simple text browser for idle
class TextViewer(Toplevel):
"""
simple text viewer dialog for idle
- """
+ """
def __init__(self,parent,title,fileName):
"""
fileName - string,should be an absoulute filename
self.LoadTextFile(fileName)
self.textView.config(state=DISABLED)
self.wait_window()
-
+
def LoadTextFile(self, fileName):
textFile = None
try:
message='Unable to load file '+`fileName`+' .')
else:
self.textView.insert(0.0,textFile.read())
-
+
def CreateWidgets(self):
frameText = Frame(self)
frameButtons = Frame(self)
self.textView.pack(side=LEFT,expand=TRUE,fill=BOTH)
frameButtons.pack(side=BOTTOM,fill=X)
frameText.pack(side=TOP,expand=TRUE,fill=BOTH)
-
+
def Ok(self, event=None):
self.destroy()