Kaydet (Commit) 085eb1b3 authored tarafından Steven M. Gava's avatar Steven M. Gava

further work on config system and config saving

üst c121745f
...@@ -28,23 +28,8 @@ ...@@ -28,23 +28,8 @@
[General] [General]
editor-on-startup= 1 editor-on-startup= 1
#run-in-separate-process= 1 user-help-browser= 0
#help-browser= "" user-help-browser-command=
[HelpFiles]
#idle="IDLE _Help",""
#python="_Python Documentation",""
#additional help sources
1=
2=
3=
4=
5=
6=
7=
8=
9=
10=
[EditorWindow] [EditorWindow]
width= 80 width= 80
...@@ -66,15 +51,23 @@ name= IDLE Classic ...@@ -66,15 +51,23 @@ name= IDLE Classic
default= 1 default= 1
name= IDLE Classic Windows name= IDLE Classic Windows
[RecentFiles] [HelpFiles]
1= #additional help sources, must be viewable by an html browser
2= #will be listed on the Help/Other Help menu
3= #option names are the sequence number of the option
4= #values take the form: menu item;/path/to/help/source
5= #obviously you can't use a semi-colon in a menu item or path and the path will
6= #be platform specific because of path separators, drive specs etc.
7= #eg.:
8= #1= My Extra Help Source;/usr/share/doc/foo/index.html
9= #2= Another Help Source;/path/to/another.html
10=
#[RecentFiles]
#this section will only be present in the user config file idle-main.cfg
#where it will record the most recently openned files in the form
#IndexNum= /full/path/of/file , for display on the File/Recent Files menu
#it is present here for reference only
#eg.:
#1=/most/recently/openned/file
#2=/next/most/recently/openned/file
#etc.
This diff is collapsed.
...@@ -8,8 +8,7 @@ Provides access to stored idle configuration information. ...@@ -8,8 +8,7 @@ Provides access to stored idle configuration information.
# a requested config value, a message is printed to stderr to aid in # a requested config value, a message is printed to stderr to aid in
# configuration problem notification and resolution. # configuration problem notification and resolution.
import os import os, sys, string
import sys
from ConfigParser import ConfigParser, NoOptionError, NoSectionError from ConfigParser import ConfigParser, NoOptionError, NoSectionError
class IdleConfParser(ConfigParser): class IdleConfParser(ConfigParser):
...@@ -44,7 +43,7 @@ class IdleConfParser(ConfigParser): ...@@ -44,7 +43,7 @@ class IdleConfParser(ConfigParser):
""" """
Get an option list for given section Get an option list for given section
""" """
if self.has_section: if self.has_section(section):
return self.options(section) return self.options(section)
else: #return a default value else: #return a default value
return [] return []
...@@ -516,16 +515,51 @@ class IdleConf: ...@@ -516,16 +515,51 @@ class IdleConf:
'<<find>>': ['<Control-f>'], '<<find>>': ['<Control-f>'],
'<<replace>>': ['<Control-h>'], '<<replace>>': ['<Control-h>'],
'<<goto-line>>': ['<Alt-g>'] } '<<goto-line>>': ['<Alt-g>'] }
if keySetName: if keySetName:
for event in keyBindings.keys(): for event in keyBindings.keys():
binding=self.GetKeyBinding(keySetName,event) binding=self.GetKeyBinding(keySetName,event)
if binding: #otherwise will keep default if binding: #otherwise will keep default
keyBindings[event]=binding keyBindings[event]=binding
return keyBindings 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':
cfgParser=self.defaultCfg['main']
else:
raise 'Invalid configSet specified'
options=cfgParser.GetOptionList('HelpFiles')
for option in options:
value=cfgParser.Get('HelpFiles',option,default=';')
if value.find(';')==-1: #malformed config entry with no ';'
menuItem='' #make these empty
helpPath='' #so value won't be added to list
else: #config entry contains ';' as expected
value=string.split(value,';')
menuItem=value[0].strip()
helpPath=value[1].strip()
if menuItem and helpPath: #neither are empty strings
helpSources.append( (menuItem,helpPath,option) )
return helpSources
def GetAllExtraHelpSourcesList(self):
"""
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')+
self.GetExtraHelpSourceList('user') )
return allHelpSources
def LoadCfgFiles(self): def LoadCfgFiles(self):
""" """
load all configuration files. load all configuration files.
......
"""
Dialog that allows user to specify or edit the parameters for a user configured
help source.
"""
from Tkinter import *
import tkMessageBox
import os
class GetHelpSourceDialog(Toplevel):
def __init__(self,parent,title,menuItem='',filePath=''):
"""
menuItem - string, the menu item to edit, if any
filePath - string, the help file path to edit, if any
"""
Toplevel.__init__(self, parent)
self.configure(borderwidth=5)
self.resizable(height=FALSE,width=FALSE)
self.title(title)
self.transient(parent)
self.grab_set()
self.protocol("WM_DELETE_WINDOW", self.Cancel)
self.parent = parent
self.result=None
self.CreateWidgets()
self.withdraw() #hide while setting geometry
self.update_idletasks()
#needs to be done here so that the winfo_reqwidth is valid
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):
self.menu=StringVar(self)
self.path=StringVar(self)
self.fontSize=StringVar(self)
self.frameMain = Frame(self,borderwidth=2,relief=SUNKEN)
self.frameMain.pack(side=TOP,expand=TRUE,fill=BOTH)
labelMenu=Label(self.frameMain,anchor=W,justify=LEFT,
text='Menu Item:')
self.entryMenu=Entry(self.frameMain,textvariable=self.menu,width=30)
self.entryMenu.focus_set()
labelPath=Label(self.frameMain,anchor=W,justify=LEFT,
text='Help File Path:')
self.entryPath=Entry(self.frameMain,textvariable=self.path,width=40)
self.entryMenu.focus_set()
labelMenu.pack(anchor=W,padx=5,pady=3)
self.entryMenu.pack(anchor=W,padx=5,pady=3)
labelPath.pack(anchor=W,padx=5,pady=3)
self.entryPath.pack(anchor=W,padx=5,pady=3)
frameButtons=Frame(self)
frameButtons.pack(side=BOTTOM,fill=X)
self.buttonOk = Button(frameButtons,text='Ok',
width=8,command=self.Ok)
self.buttonOk.grid(row=0,column=0,padx=5,pady=5)
self.buttonCancel = Button(frameButtons,text='Cancel',
width=8,command=self.Cancel)
self.buttonCancel.grid(row=0,column=1,padx=5,pady=5)
def MenuOk(self):
#simple validity check for a sensible
#menu item name
menuOk=1
menu=self.menu.get()
menu.strip()
if not menu: #no menu item specified
tkMessageBox.showerror(title='Menu Item Error',
message='No menu item specified.')
self.entryMenu.focus_set()
menuOk=0
elif len(menu)>30: #menu item name too long
tkMessageBox.showerror(title='Menu Item Error',
message='Menu item too long. It should be no more '+
'than 30 characters.')
self.entryMenu.focus_set()
menuOk=0
return menuOk
def PathOk(self):
#simple validity check for menu file path
pathOk=1
path=self.path.get()
path.strip()
if not path: #no path specified
tkMessageBox.showerror(title='File Path Error',
message='No help file path specified.')
self.entryPath.focus_set()
pathOk=0
elif not os.path.exists(path):
tkMessageBox.showerror(title='File Path Error',
message='Help file path does not exist.')
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.destroy()
def Cancel(self, event=None):
self.result=None
self.destroy()
if __name__ == '__main__':
#test the dialog
root=Tk()
def run():
keySeq=''
dlg=GetHelpSourceDialog(root,'Get Help Source')
print dlg.result
Button(root,text='Dialog',command=run).pack()
root.mainloop()
...@@ -65,10 +65,10 @@ class GetCfgSectionNameDialog(Toplevel): ...@@ -65,10 +65,10 @@ class GetCfgSectionNameDialog(Toplevel):
tkMessageBox.showerror(title='Name Error', tkMessageBox.showerror(title='Name Error',
message='No name specified.') message='No name specified.')
nameOk=0 nameOk=0
elif len(name)>60: #name too long elif len(name)>30: #name too long
tkMessageBox.showerror(title='Name Error', tkMessageBox.showerror(title='Name Error',
message='Name too long. Keep it to less than '+ message='Name too long. It should be no more than '+
'60 characters.') '30 characters.')
nameOk=0 nameOk=0
elif name in self.usedNames: elif name in self.usedNames:
tkMessageBox.showerror(title='Name Error', tkMessageBox.showerror(title='Name Error',
...@@ -78,7 +78,7 @@ class GetCfgSectionNameDialog(Toplevel): ...@@ -78,7 +78,7 @@ class GetCfgSectionNameDialog(Toplevel):
def Ok(self, event=None): def Ok(self, event=None):
if self.NameOk(): if self.NameOk():
self.result=self.name.get() self.result=self.name.get().strip()
self.destroy() self.destroy()
def Cancel(self, event=None): def Cancel(self, event=None):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment