further work on config system and config saving

This commit is contained in:
Steven M. Gava 2002-02-05 04:52:32 +00:00
parent c121745fda
commit 085eb1b372
5 changed files with 335 additions and 102 deletions

View File

@ -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
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.

View File

@ -10,6 +10,7 @@ from dynOptionMenuWidget import DynOptionMenu
from tabpage import TabPageSet from tabpage import TabPageSet
from keybindingDialog import GetKeysDialog from keybindingDialog import GetKeysDialog
from configSectionNameDialog import GetCfgSectionNameDialog from configSectionNameDialog import GetCfgSectionNameDialog
from configHelpSourceEdit import GetHelpSourceDialog
class ConfigDialog(Toplevel): class ConfigDialog(Toplevel):
""" """
configuration dialog for idle configuration dialog for idle
@ -213,7 +214,7 @@ class ConfigDialog(Toplevel):
value=0,text='Background',command=self.SetColourSampleBinding) value=0,text='Background',command=self.SetColourSampleBinding)
self.fgHilite.set(1) self.fgHilite.set(1)
buttonSaveCustomTheme=Button(frameCustom, buttonSaveCustomTheme=Button(frameCustom,
text='Save as New Custom Theme') text='Save as New Custom Theme',command=self.SaveAsNewTheme)
#frameTheme #frameTheme
labelThemeTitle=Label(frameTheme,text='Select a Highlighting Theme') labelThemeTitle=Label(frameTheme,text='Select a Highlighting Theme')
labelTypeTitle=Label(frameTheme,text='Select : ') labelTypeTitle=Label(frameTheme,text='Select : ')
@ -270,7 +271,8 @@ class ConfigDialog(Toplevel):
labelTargetTitle=Label(frameTarget,text='Action - Key(s)') labelTargetTitle=Label(frameTarget,text='Action - Key(s)')
scrollTargetY=Scrollbar(frameTarget) scrollTargetY=Scrollbar(frameTarget)
scrollTargetX=Scrollbar(frameTarget,orient=HORIZONTAL) scrollTargetX=Scrollbar(frameTarget,orient=HORIZONTAL)
self.listBindings=Listbox(frameTarget) self.listBindings=Listbox(frameTarget,takefocus=FALSE,
exportselection=FALSE)
self.listBindings.bind('<ButtonRelease-1>',self.KeyBindingSelected) self.listBindings.bind('<ButtonRelease-1>',self.KeyBindingSelected)
scrollTargetY.config(command=self.listBindings.yview) scrollTargetY.config(command=self.listBindings.yview)
scrollTargetX.config(command=self.listBindings.xview) scrollTargetX.config(command=self.listBindings.xview)
@ -278,7 +280,8 @@ class ConfigDialog(Toplevel):
self.listBindings.config(xscrollcommand=scrollTargetX.set) self.listBindings.config(xscrollcommand=scrollTargetX.set)
self.buttonNewKeys=Button(frameCustom,text='Get New Keys for Selection', self.buttonNewKeys=Button(frameCustom,text='Get New Keys for Selection',
command=self.GetNewKeys,state=DISABLED) command=self.GetNewKeys,state=DISABLED)
buttonSaveCustomKeys=Button(frameCustom,text='Save as New Custom Key Set') buttonSaveCustomKeys=Button(frameCustom,
text='Save as New Custom Key Set',command=self.SaveAsNewKeySet)
#frameKeySets #frameKeySets
labelKeysTitle=Label(frameKeySets,text='Select a Key Set') labelKeysTitle=Label(frameKeySets,text='Select a Key Set')
labelTypeTitle=Label(frameKeySets,text='Select : ') labelTypeTitle=Label(frameKeySets,text='Select : ')
@ -322,14 +325,15 @@ class ConfigDialog(Toplevel):
self.winWidth=StringVar(self) self.winWidth=StringVar(self)
self.winHeight=StringVar(self) self.winHeight=StringVar(self)
self.startupEdit=IntVar(self) self.startupEdit=IntVar(self)
self.extEnabled=IntVar(self) self.userHelpBrowser=BooleanVar(self)
self.helpBrowser=StringVar(self)
#widget creation #widget creation
#body #body
frame=self.tabPages.pages['General']['page'] frame=self.tabPages.pages['General']['page']
#body section frames #body section frames
frameRun=Frame(frame,borderwidth=2,relief=GROOVE) frameRun=Frame(frame,borderwidth=2,relief=GROOVE)
frameWinSize=Frame(frame,borderwidth=2,relief=GROOVE) frameWinSize=Frame(frame,borderwidth=2,relief=GROOVE)
frameExt=Frame(frame,borderwidth=2,relief=GROOVE) frameHelp=Frame(frame,borderwidth=2,relief=GROOVE)
#frameRun #frameRun
labelRunTitle=Label(frameRun,text='Startup Preferences') labelRunTitle=Label(frameRun,text='Startup Preferences')
labelRunChoiceTitle=Label(frameRun,text='On startup : ') labelRunChoiceTitle=Label(frameRun,text='On startup : ')
@ -346,29 +350,33 @@ class ConfigDialog(Toplevel):
labelWinHeightTitle=Label(frameWinSize,text='Height') labelWinHeightTitle=Label(frameWinSize,text='Height')
entryWinHeight=Entry(frameWinSize,textvariable=self.winHeight, entryWinHeight=Entry(frameWinSize,textvariable=self.winHeight,
width=3) width=3)
#frameExt #frameHelp
frameExtList=Frame(frameExt) labelHelpTitle=Label(frameHelp,text='Help Options')
frameExtSet=Frame(frameExt) frameHelpList=Frame(frameHelp)
labelExtTitle=Label(frameExt,text='Configure IDLE Extensions') frameHelpListButtons=Frame(frameHelpList)
labelExtListTitle=Label(frameExtList,text='Extension') labelHelpListTitle=Label(frameHelpList,text='Additional (html) Help Sources:')
scrollExtList=Scrollbar(frameExtList) scrollHelpList=Scrollbar(frameHelpList)
self.listExt=Listbox(frameExtList,height=5) self.listHelp=Listbox(frameHelpList,height=5,takefocus=FALSE,
scrollExtList.config(command=self.listExt.yview) exportselection=FALSE)
self.listExt.config(yscrollcommand=scrollExtList.set) scrollHelpList.config(command=self.listHelp.yview)
self.listExt.bind('<ButtonRelease-1>',self.ExtensionSelected) self.listHelp.config(yscrollcommand=scrollHelpList.set)
labelExtSetTitle=Label(frameExtSet,text='Settings') self.listHelp.bind('<ButtonRelease-1>',self.HelpSourceSelected)
self.radioEnableExt=Radiobutton(frameExtSet,variable=self.extEnabled, self.buttonHelpListEdit=Button(frameHelpListButtons,text='Edit',
value=1,text="enabled",state=DISABLED, state=DISABLED,width=8,command=self.HelpListItemEdit)
command=self.ExtensionStateToggled) self.buttonHelpListAdd=Button(frameHelpListButtons,text='Add',
self.radioDisableExt=Radiobutton(frameExtSet,variable=self.extEnabled, width=8,command=self.HelpListItemAdd)
value=0,text="disabled",state=DISABLED, self.buttonHelpListRemove=Button(frameHelpListButtons,text='Remove',
command=self.ExtensionStateToggled) state=DISABLED,width=8,command=self.HelpListItemRemove)
self.buttonExtConfig=Button(frameExtSet,text='Configure',state=DISABLED) checkHelpBrowser=Checkbutton(frameHelp,variable=self.userHelpBrowser,
onvalue=1,offvalue=0,text='user specified (html) help browser:',
command=self.OnCheckUserHelpBrowser)
self.entryHelpBrowser=Entry(frameHelp,textvariable=self.helpBrowser,
width=40)
#widget packing #widget packing
#body #body
frameRun.pack(side=TOP,padx=5,pady=5,fill=X) frameRun.pack(side=TOP,padx=5,pady=5,fill=X)
frameWinSize.pack(side=TOP,padx=5,pady=5,fill=X) frameWinSize.pack(side=TOP,padx=5,pady=5,fill=X)
frameExt.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) frameHelp.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH)
#frameRun #frameRun
labelRunTitle.pack(side=TOP,anchor=W,padx=5,pady=5) labelRunTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
labelRunChoiceTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) labelRunChoiceTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
@ -380,17 +388,18 @@ class ConfigDialog(Toplevel):
labelWinHeightTitle.pack(side=RIGHT,anchor=E,pady=5) labelWinHeightTitle.pack(side=RIGHT,anchor=E,pady=5)
entryWinWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5) entryWinWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5)
labelWinWidthTitle.pack(side=RIGHT,anchor=E,pady=5) labelWinWidthTitle.pack(side=RIGHT,anchor=E,pady=5)
#frameExt #frameHelp
labelExtTitle.pack(side=TOP,anchor=W,padx=5,pady=5) labelHelpTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
frameExtSet.pack(side=RIGHT,padx=5,pady=5,fill=Y) frameHelpListButtons.pack(side=RIGHT,padx=5,pady=5,fill=Y)
frameExtList.pack(side=RIGHT,padx=5,pady=5,expand=TRUE,fill=BOTH) frameHelpList.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH)
labelExtListTitle.pack(side=TOP,anchor=W) labelHelpListTitle.pack(side=TOP,anchor=W)
scrollExtList.pack(side=RIGHT,anchor=W,fill=Y) scrollHelpList.pack(side=RIGHT,anchor=W,fill=Y)
self.listExt.pack(side=LEFT,anchor=E,expand=TRUE,fill=BOTH) self.listHelp.pack(side=LEFT,anchor=E,expand=TRUE,fill=BOTH)
labelExtSetTitle.pack(side=TOP,anchor=W) self.buttonHelpListEdit.pack(side=TOP,anchor=W,pady=5)
self.radioEnableExt.pack(side=TOP,anchor=W) self.buttonHelpListAdd.pack(side=TOP,anchor=W)
self.radioDisableExt.pack(side=TOP,anchor=W) self.buttonHelpListRemove.pack(side=TOP,anchor=W,pady=5)
self.buttonExtConfig.pack(side=TOP,anchor=W,pady=5) checkHelpBrowser.pack(side=TOP,anchor=W,padx=5)
self.entryHelpBrowser.pack(side=TOP,anchor=W,padx=5,pady=5)
return frame return frame
def AttachVarCallbacks(self): def AttachVarCallbacks(self):
@ -475,6 +484,7 @@ class ConfigDialog(Toplevel):
self.changedItems={'main':{},'highlight':{},'keys':{},'extensions':{}} self.changedItems={'main':{},'highlight':{},'keys':{},'extensions':{}}
def AddChangedItem(self,type,section,item,value): def AddChangedItem(self,type,section,item,value):
print type,section,item,value
value=str(value) #make sure we use a string value=str(value) #make sure we use a string
if not self.changedItems[type].has_key(section): if not self.changedItems[type].has_key(section):
self.changedItems[type][section]={} self.changedItems[type][section]={}
@ -519,24 +529,21 @@ class ConfigDialog(Toplevel):
binding=self.listBindings.get(listIndex) binding=self.listBindings.get(listIndex)
bindName=binding.split()[0] #first part, up to first space bindName=binding.split()[0] #first part, up to first space
currentKeySequences=idleConf.GetCurrentKeySet().values() currentKeySequences=idleConf.GetCurrentKeySet().values()
newKeys=GetKeysDialog(self,'Get New Keys',bindName,currentKeySequences) newKeys=GetKeysDialog(self,'Get New Keys',bindName,
if newKeys.result: #new keys were specified currentKeySequences).result
if newKeys: #new keys were specified
if self.keysAreDefault.get(): #current key set is a built-in if self.keysAreDefault.get(): #current key set is a built-in
message=('Your changes will be saved as a new Custom Key Set. '+ message=('Your changes will be saved as a new Custom Key Set. '+
'Enter a name for your new Custom Key Set below.') 'Enter a name for your new Custom Key Set below.')
usedNames=idleConf.GetSectionList('user','keys') newKeySet=self.GetNewKeysName(message)
for newName in self.changedItems['keys'].keys(): if not newKeySet: #user cancelled custom key set creation
if newName not in usedNames: usedNames.append(newName)
newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set',
message,usedNames)
if not newKeySet.result: #user cancelled custom key set creation
self.listBindings.select_set(listIndex) self.listBindings.select_set(listIndex)
self.listBindings.select_anchor(listIndex) self.listBindings.select_anchor(listIndex)
return return
else: #create new custom key set based on previously active key set else: #create new custom key set based on previously active key set
self.CreateNewKeySet(newKeySet.result) self.CreateNewKeySet(newKeySet)
self.listBindings.delete(listIndex) self.listBindings.delete(listIndex)
self.listBindings.insert(listIndex,bindName+' - '+newKeys.result) self.listBindings.insert(listIndex,bindName+' - '+newKeys)
self.listBindings.select_set(listIndex) self.listBindings.select_set(listIndex)
self.listBindings.select_anchor(listIndex) self.listBindings.select_anchor(listIndex)
self.keyBinding.set(newKeys.result) self.keyBinding.set(newKeys.result)
@ -544,6 +551,19 @@ class ConfigDialog(Toplevel):
self.listBindings.select_set(listIndex) self.listBindings.select_set(listIndex)
self.listBindings.select_anchor(listIndex) self.listBindings.select_anchor(listIndex)
def GetNewKeysName(self,message):
usedNames=idleConf.GetSectionList('user','keys')
for newName in self.changedItems['keys'].keys():
if newName not in usedNames: usedNames.append(newName)
newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set',
message,usedNames).result
return newKeySet
def SaveAsNewKeySet(self):
newKeysName=self.GetNewKeysName('New Key Set Name:')
if newKeysName:
self.CreateNewKeySet(newKeysName)
def KeyBindingSelected(self,event): def KeyBindingSelected(self,event):
self.buttonNewKeys.config(state=NORMAL) self.buttonNewKeys.config(state=NORMAL)
@ -578,15 +598,11 @@ class ConfigDialog(Toplevel):
if self.themeIsBuiltin.get(): #current theme is a built-in if self.themeIsBuiltin.get(): #current theme is a built-in
message=('Your changes will be saved as a new Custom Theme. '+ message=('Your changes will be saved as a new Custom Theme. '+
'Enter a name for your new Custom Theme below.') 'Enter a name for your new Custom Theme below.')
usedNames=idleConf.GetSectionList('user','highlight') newTheme=self.GetNewThemeName(message)
for newName in self.changedItems['highlight'].keys(): if not newTheme: #user cancelled custom theme creation
if newName not in usedNames: usedNames.append(newName)
newTheme=GetCfgSectionNameDialog(self,'New Custom Theme',
message,usedNames)
if not newTheme.result: #user cancelled custom theme creation
return return
else: #create new custom theme based on previously active theme else: #create new custom theme based on previously active theme
self.CreateNewTheme(newTheme.result) self.CreateNewTheme(newTheme)
self.colour.set(colourString) self.colour.set(colourString)
self.frameColourSet.config(bg=colourString)#set sample self.frameColourSet.config(bg=colourString)#set sample
if self.fgHilite.get(): plane='foreground' if self.fgHilite.get(): plane='foreground'
@ -594,6 +610,19 @@ class ConfigDialog(Toplevel):
apply(self.textHighlightSample.tag_config, apply(self.textHighlightSample.tag_config,
(self.themeElements[target][0],),{plane:colourString}) (self.themeElements[target][0],),{plane:colourString})
def GetNewThemeName(self,message):
usedNames=idleConf.GetSectionList('user','highlight')
for newName in self.changedItems['highlight'].keys():
if newName not in usedNames: usedNames.append(newName)
newTheme=GetCfgSectionNameDialog(self,'New Custom Theme',
message,usedNames).result
return newTheme
def SaveAsNewTheme(self):
newThemeName=self.GetNewThemeName('New Theme Name:')
if newThemeName:
self.CreateNewTheme(newThemeName)
def CreateNewTheme(self,newThemeName): def CreateNewTheme(self,newThemeName):
#creates new custom theme based on the previously active theme, #creates new custom theme based on the previously active theme,
#and makes the new theme active #and makes the new theme active
@ -666,6 +695,63 @@ class ConfigDialog(Toplevel):
apply(self.textHighlightSample.tag_config, apply(self.textHighlightSample.tag_config,
(self.themeElements[element][0],),colours) (self.themeElements[element][0],),colours)
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.buttonHelpListRemove.config(state=DISABLED)
else: #there are some entries
if self.listHelp.curselection(): #there currently is a selection
self.buttonHelpListEdit.config(state=NORMAL)
self.buttonHelpListRemove.config(state=NORMAL)
else: #there currently is not a selection
self.buttonHelpListEdit.config(state=DISABLED)
self.buttonHelpListRemove.config(state=DISABLED)
def HelpListItemAdd(self):
helpSource=GetHelpSourceDialog(self,'New Help Source').result
if helpSource:
self.userHelpList.append( (helpSource[0],helpSource[1]) )
self.listHelp.insert(END,helpSource[0]+' '+helpSource[1])
self.UpdateUserHelpChangedItems()
self.SetHelpListButtonStates()
def HelpListItemEdit(self):
itemIndex=self.listHelp.index(ANCHOR)
helpSource=self.userHelpList[itemIndex]
newHelpSource=GetHelpSourceDialog(self,'New Help Source',
menuItem=helpSource[0],filePath=helpSource[1]).result
if (not newHelpSource) or (newHelpSource==helpSource):
return #no changes
self.userHelpList[itemIndex]=newHelpSource
self.listHelp.delete(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'):
del(self.changedItems['main']['HelpFiles'])
for num in range(1,len(self.userHelpList)+1):
self.AddChangedItem('main','HelpFiles',str(num),
string.join(self.userHelpList[num-1],';'))
def LoadFontCfg(self): def LoadFontCfg(self):
##base editor font selection list ##base editor font selection list
fonts=list(tkFont.families(self)) fonts=list(tkFont.families(self))
@ -784,17 +870,16 @@ class ConfigDialog(Toplevel):
#initial window size #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')) self.winHeight.set(idleConf.GetOption('main','EditorWindow','height'))
#extensions #help browsing
extns=idleConf.GetExtensions(activeOnly=0) self.userHelpList=idleConf.GetExtraHelpSourceList('user')
apply(self.listExt.insert,(END,)+tuple(extns)) for helpItem in self.userHelpList:
self.listHelp.insert(END,helpItem[0]+' '+helpItem[1])
def ExtensionSelected(self,event): self.SetHelpListButtonStates()
self.radioEnableExt.config(state=NORMAL) self.userHelpBrowser.set(idleConf.GetOption('main','General',
self.radioDisableExt.config(state=NORMAL) 'user-help-browser',default=0,type='bool'))
self.buttonExtConfig.config(state=NORMAL) self.helpBrowser.set(idleConf.GetOption('main','General',
extn=self.listExt.get(ANCHOR) 'user-help-browser-command',default=''))
self.extEnabled.set(idleConf.GetOption('extensions',extn,'enable', self.OnCheckUserHelpBrowser()
default=1,type='bool'))
def LoadConfigs(self): def LoadConfigs(self):
""" """
@ -808,7 +893,6 @@ class ConfigDialog(Toplevel):
self.LoadThemeCfg() self.LoadThemeCfg()
### keys page ### keys page
self.LoadKeyCfg() self.LoadKeyCfg()
### help page
### general page ### general page
self.LoadGeneralCfg() self.LoadGeneralCfg()
@ -824,6 +908,9 @@ class ConfigDialog(Toplevel):
""" """
save configuration changes to user config files. save configuration changes to user config files.
""" """
if self.changedItems['main'].has_key('HelpFiles'):
#this section gets completely replaced
idleConf.userCfg['main'].remove_section('HelpFiles')
for configType in self.changedItems.keys(): for configType in self.changedItems.keys():
cfgTypeHasChanges=0 cfgTypeHasChanges=0
for section in self.changedItems[configType].keys(): for section in self.changedItems[configType].keys():

View File

@ -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):
""" """
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:
'<<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.

View File

@ -0,0 +1,119 @@
"""
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()

View File

@ -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):
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):