0001 """Provides access to stored IDLE configuration information. 0002 0003 Refer to the comments at the beginning of config-main.def for a description of 0004 the available configuration files and the design implemented to update user 0005 configuration information. In particular, user configuration choices which 0006 duplicate the defaults will be removed from the user's configuration files, 0007 and if a file becomes empty, it will be deleted. 0008 0009 The contents of the user files may be altered using the Options/Configure IDLE 0010 menu to access the configuration GUI (configDialog.py), or manually. 0011 0012 Throughout this module there is an emphasis on returning useable defaults 0013 when a problem occurs in returning a requested configuration value back to 0014 idle. This is to allow IDLE to continue to function in spite of errors in 0015 the retrieval of config information. When a default is returned instead of 0016 a requested config value, a message is printed to stderr to aid in 0017 configuration problem notification and resolution. 0018 0019 """ 0020 import os 0021 import sys 0022 import string 0023 from ConfigParser import ConfigParser, NoOptionError, NoSectionError 0024 0025 class InvalidConfigType(Exception): pass 0026 class InvalidConfigSet(Exception): pass 0027 class InvalidFgBg(Exception): pass 0028 class InvalidTheme(Exception): pass 0029 0030 class IdleConfParser(ConfigParser): 0031 """ 0032 A ConfigParser specialised for idle configuration file handling 0033 """ 0034 def __init__(self, cfgFile, cfgDefaults=None): 0035 """ 0036 cfgFile - string, fully specified configuration file name 0037 """ 0038 self.file=cfgFile 0039 ConfigParser.__init__(self,defaults=cfgDefaults) 0040 0041 def Get(self, section, option, type=None, default=None): 0042 """ 0043 Get an option value for given section/option or return default. 0044 If type is specified, return as type. 0045 """ 0046 if type=='bool': 0047 getVal=self.getboolean 0048 elif type=='int': 0049 getVal=self.getint 0050 else: 0051 getVal=self.get 0052 if self.has_option(section,option): 0053 #return getVal(section, option, raw, vars, default) 0054 return getVal(section, option) 0055 else: 0056 return default 0057 0058 def GetOptionList(self,section): 0059 """ 0060 Get an option list for given section 0061 """ 0062 if self.has_section(section): 0063 return self.options(section) 0064 else: #return a default value 0065 return [] 0066 0067 def Load(self): 0068 """ 0069 Load the configuration file from disk 0070 """ 0071 self.read(self.file) 0072 0073 class IdleUserConfParser(IdleConfParser): 0074 """ 0075 IdleConfigParser specialised for user configuration handling. 0076 """ 0077 0078 def AddSection(self,section): 0079 """ 0080 if section doesn't exist, add it 0081 """ 0082 if not self.has_section(section): 0083 self.add_section(section) 0084 0085 def RemoveEmptySections(self): 0086 """ 0087 remove any sections that have no options 0088 """ 0089 for section in self.sections(): 0090 if not self.GetOptionList(section): 0091 self.remove_section(section) 0092 0093 def IsEmpty(self): 0094 """ 0095 Remove empty sections and then return 1 if parser has no sections 0096 left, else return 0. 0097 """ 0098 self.RemoveEmptySections() 0099 if self.sections(): 0100 return 0 0101 else: 0102 return 1 0103 0104 def RemoveOption(self,section,option): 0105 """ 0106 If section/option exists, remove it. 0107 Returns 1 if option was removed, 0 otherwise. 0108 """ 0109 if self.has_section(section): 0110 return self.remove_option(section,option) 0111 0112 def SetOption(self,section,option,value): 0113 """ 0114 Sets option to value, adding section if required. 0115 Returns 1 if option was added or changed, otherwise 0. 0116 """ 0117 if self.has_option(section,option): 0118 if self.get(section,option)==value: 0119 return 0 0120 else: 0121 self.set(section,option,value) 0122 return 1 0123 else: 0124 if not self.has_section(section): 0125 self.add_section(section) 0126 self.set(section,option,value) 0127 return 1 0128 0129 def RemoveFile(self): 0130 """ 0131 Removes the user config file from disk if it exists. 0132 """ 0133 if os.path.exists(self.file): 0134 os.remove(self.file) 0135 0136 def Save(self): 0137 """Update user configuration file. 0138 0139 Remove empty sections. If resulting config isn't empty, write the file 0140 to disk. If config is empty, remove the file from disk if it exists. 0141 0142 """ 0143 if not self.IsEmpty(): 0144 cfgFile=open(self.file,'w') 0145 self.write(cfgFile) 0146 else: 0147 self.RemoveFile() 0148 0149 class IdleConf: 0150 """ 0151 holds config parsers for all idle config files: 0152 default config files 0153 (idle install dir)/config-main.def 0154 (idle install dir)/config-extensions.def 0155 (idle install dir)/config-highlight.def 0156 (idle install dir)/config-keys.def 0157 user config files 0158 (user home dir)/.idlerc/config-main.cfg 0159 (user home dir)/.idlerc/config-extensions.cfg 0160 (user home dir)/.idlerc/config-highlight.cfg 0161 (user home dir)/.idlerc/config-keys.cfg 0162 """ 0163 def __init__(self): 0164 self.defaultCfg={} 0165 self.userCfg={} 0166 self.cfg={} 0167 self.CreateConfigHandlers() 0168 self.LoadCfgFiles() 0169 #self.LoadCfg() 0170 0171 def CreateConfigHandlers(self): 0172 """ 0173 set up a dictionary of config parsers for default and user 0174 configurations respectively 0175 """ 0176 #build idle install path 0177 if __name__ != '__main__': # we were imported 0178 idleDir=os.path.dirname(__file__) 0179 else: # we were exec'ed (for testing only) 0180 idleDir=os.path.abspath(sys.path[0]) 0181 userDir=self.GetUserCfgDir() 0182 configTypes=('main','extensions','highlight','keys') 0183 defCfgFiles={} 0184 usrCfgFiles={} 0185 for cfgType in configTypes: #build config file names 0186 defCfgFiles[cfgType]=os.path.join(idleDir,'config-'+cfgType+'.def') 0187 usrCfgFiles[cfgType]=os.path.join(userDir,'config-'+cfgType+'.cfg') 0188 for cfgType in configTypes: #create config parsers 0189 self.defaultCfg[cfgType]=IdleConfParser(defCfgFiles[cfgType]) 0190 self.userCfg[cfgType]=IdleUserConfParser(usrCfgFiles[cfgType]) 0191 0192 def GetUserCfgDir(self): 0193 """ 0194 Creates (if required) and returns a filesystem directory for storing 0195 user config files. 0196 """ 0197 cfgDir='.idlerc' 0198 userDir=os.path.expanduser('~') 0199 if userDir != '~': #'HOME' exists as a key in os.environ 0200 if not os.path.exists(userDir): 0201 warn=('\n Warning: HOME environment variable points to\n '+ 0202 userDir+'\n but the path does not exist.\n') 0203 sys.stderr.write(warn) 0204 userDir='~' 0205 if userDir=='~': #we still don't have a home directory 0206 #traditionally idle has defaulted to os.getcwd(), is this adeqate? 0207 userDir = os.getcwd() #hack for no real homedir 0208 userDir=os.path.join(userDir,cfgDir) 0209 if not os.path.exists(userDir): 0210 try: #make the config dir if it doesn't exist yet 0211 os.mkdir(userDir) 0212 except IOError: 0213 warn=('\n Warning: unable to create user config directory\n '+ 0214 userDir+'\n') 0215 sys.stderr.write(warn) 0216 return userDir 0217 0218 def GetOption(self, configType, section, option, default=None, type=None, 0219 warn_on_default=True): 0220 """ 0221 Get an option value for given config type and given general 0222 configuration section/option or return a default. If type is specified, 0223 return as type. Firstly the user configuration is checked, with a 0224 fallback to the default configuration, and a final 'catch all' 0225 fallback to a useable passed-in default if the option isn't present in 0226 either the user or the default configuration. 0227 configType must be one of ('main','extensions','highlight','keys') 0228 If a default is returned, and warn_on_default is True, a warning is 0229 printed to stderr. 0230 0231 """ 0232 if self.userCfg[configType].has_option(section,option): 0233 return self.userCfg[configType].Get(section, option, type=type) 0234 elif self.defaultCfg[configType].has_option(section,option): 0235 return self.defaultCfg[configType].Get(section, option, type=type) 0236 else: #returning default, print warning 0237 if warn_on_default: 0238 warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n' 0239 ' problem retrieving configration option %r\n' 0240 ' from section %r.\n' 0241 ' returning default value: %r\n' % 0242 (option, section, default)) 0243 sys.stderr.write(warning) 0244 return default 0245 0246 def SetOption(self, configType, section, option, value): 0247 """In user's config file, set section's option to value. 0248 0249 """ 0250 self.userCfg[configType].SetOption(section, option, value) 0251 0252 def GetSectionList(self, configSet, configType): 0253 """ 0254 Get a list of sections from either the user or default config for 0255 the given config type. 0256 configSet must be either 'user' or 'default' 0257 configType must be one of ('main','extensions','highlight','keys') 0258 """ 0259 if not (configType in ('main','extensions','highlight','keys')): 0260 raise InvalidConfigType, 'Invalid configType specified' 0261 if configSet == 'user': 0262 cfgParser=self.userCfg[configType] 0263 elif configSet == 'default': 0264 cfgParser=self.defaultCfg[configType] 0265 else: 0266 raise InvalidConfigSet, 'Invalid configSet specified' 0267 return cfgParser.sections() 0268 0269 def GetHighlight(self, theme, element, fgBg=None): 0270 """ 0271 return individual highlighting theme elements. 0272 fgBg - string ('fg'or'bg') or None, if None return a dictionary 0273 containing fg and bg colours (appropriate for passing to Tkinter in, 0274 e.g., a tag_config call), otherwise fg or bg colour only as specified. 0275 """ 0276 if self.defaultCfg['highlight'].has_section(theme): 0277 themeDict=self.GetThemeDict('default',theme) 0278 else: 0279 themeDict=self.GetThemeDict('user',theme) 0280 fore=themeDict[element+'-foreground'] 0281 if element=='cursor': #there is no config value for cursor bg 0282 back=themeDict['normal-background'] 0283 else: 0284 back=themeDict[element+'-background'] 0285 highlight={"foreground": fore,"background": back} 0286 if not fgBg: #return dict of both colours 0287 return highlight 0288 else: #return specified colour only 0289 if fgBg == 'fg': 0290 return highlight["foreground"] 0291 if fgBg == 'bg': 0292 return highlight["background"] 0293 else: 0294 raise InvalidFgBg, 'Invalid fgBg specified' 0295 0296 def GetThemeDict(self,type,themeName): 0297 """ 0298 type - string, 'default' or 'user' theme type 0299 themeName - string, theme name 0300 Returns a dictionary which holds {option:value} for each element 0301 in the specified theme. Values are loaded over a set of ultimate last 0302 fallback defaults to guarantee that all theme elements are present in 0303 a newly created theme. 0304 """ 0305 if type == 'user': 0306 cfgParser=self.userCfg['highlight'] 0307 elif type == 'default': 0308 cfgParser=self.defaultCfg['highlight'] 0309 else: 0310 raise InvalidTheme, 'Invalid theme type specified' 0311 #foreground and background values are provded for each theme element 0312 #(apart from cursor) even though all these values are not yet used 0313 #by idle, to allow for their use in the future. Default values are 0314 #generally black and white. 0315 theme={ 'normal-foreground':'#000000', 0316 'normal-background':'#ffffff', 0317 'keyword-foreground':'#000000', 0318 'keyword-background':'#ffffff', 0319 'builtin-foreground':'#000000', 0320 'builtin-background':'#ffffff', 0321 'comment-foreground':'#000000', 0322 'comment-background':'#ffffff', 0323 'string-foreground':'#000000', 0324 'string-background':'#ffffff', 0325 'definition-foreground':'#000000', 0326 'definition-background':'#ffffff', 0327 'hilite-foreground':'#000000', 0328 'hilite-background':'gray', 0329 'break-foreground':'#ffffff', 0330 'break-background':'#000000', 0331 'hit-foreground':'#ffffff', 0332 'hit-background':'#000000', 0333 'error-foreground':'#ffffff', 0334 'error-background':'#000000', 0335 #cursor (only foreground can be set) 0336 'cursor-foreground':'#000000', 0337 #shell window 0338 'stdout-foreground':'#000000', 0339 'stdout-background':'#ffffff', 0340 'stderr-foreground':'#000000', 0341 'stderr-background':'#ffffff', 0342 'console-foreground':'#000000', 0343 'console-background':'#ffffff' } 0344 for element in theme.keys(): 0345 if not cfgParser.has_option(themeName,element): 0346 #we are going to return a default, print warning 0347 warning=('\n Warning: configHandler.py - IdleConf.GetThemeDict' 0348 ' -\n problem retrieving theme element %r' 0349 '\n from theme %r.\n' 0350 ' returning default value: %r\n' % 0351 (element, themeName, theme[element])) 0352 sys.stderr.write(warning) 0353 colour=cfgParser.Get(themeName,element,default=theme[element]) 0354 theme[element]=colour 0355 return theme 0356 0357 def CurrentTheme(self): 0358 """ 0359 Returns the name of the currently active theme 0360 """ 0361 return self.GetOption('main','Theme','name',default='') 0362 0363 def CurrentKeys(self): 0364 """ 0365 Returns the name of the currently active key set 0366 """ 0367 return self.GetOption('main','Keys','name',default='') 0368 0369 def GetExtensions(self, active_only=True, editor_only=False, shell_only=False): 0370 """ 0371 Gets a list of all idle extensions declared in the config files. 0372 active_only - boolean, if true only return active (enabled) extensions 0373 """ 0374 extns=self.RemoveKeyBindNames( 0375 self.GetSectionList('default','extensions')) 0376 userExtns=self.RemoveKeyBindNames( 0377 self.GetSectionList('user','extensions')) 0378 for extn in userExtns: 0379 if extn not in extns: #user has added own extension 0380 extns.append(extn) 0381 if active_only: 0382 activeExtns=[] 0383 for extn in extns: 0384 if self.GetOption('extensions', extn, 'enable', default=True, 0385 type='bool'): 0386 #the extension is enabled 0387 if editor_only or shell_only: 0388 if editor_only: 0389 option = "enable_editor" 0390 else: 0391 option = "enable_shell" 0392 if self.GetOption('extensions', extn,option, 0393 default=True, type='bool', 0394 warn_on_default=False): 0395 activeExtns.append(extn) 0396 else: 0397 activeExtns.append(extn) 0398 return activeExtns 0399 else: 0400 return extns 0401 0402 def RemoveKeyBindNames(self,extnNameList): 0403 #get rid of keybinding section names 0404 names=extnNameList 0405 kbNameIndicies=[] 0406 for name in names: 0407 if name.endswith('_bindings') or name.endswith('_cfgBindings'): 0408 kbNameIndicies.append(names.index(name)) 0409 kbNameIndicies.sort() 0410 kbNameIndicies.reverse() 0411 for index in kbNameIndicies: #delete each keybinding section name 0412 del(names[index]) 0413 return names 0414 0415 def GetExtnNameForEvent(self,virtualEvent): 0416 """ 0417 Returns the name of the extension that virtualEvent is bound in, or 0418 None if not bound in any extension. 0419 virtualEvent - string, name of the virtual event to test for, without 0420 the enclosing '<< >>' 0421 """ 0422 extName=None 0423 vEvent='<<'+virtualEvent+'>>' 0424 for extn in self.GetExtensions(active_only=0): 0425 for event in self.GetExtensionKeys(extn).keys(): 0426 if event == vEvent: 0427 extName=extn 0428 return extName 0429 0430 def GetExtensionKeys(self,extensionName): 0431 """ 0432 returns a dictionary of the configurable keybindings for a particular 0433 extension,as they exist in the dictionary returned by GetCurrentKeySet; 0434 that is, where previously used bindings are disabled. 0435 """ 0436 keysName=extensionName+'_cfgBindings' 0437 activeKeys=self.GetCurrentKeySet() 0438 extKeys={} 0439 if self.defaultCfg['extensions'].has_section(keysName): 0440 eventNames=self.defaultCfg['extensions'].GetOptionList(keysName) 0441 for eventName in eventNames: 0442 event='<<'+eventName+'>>' 0443 binding=activeKeys[event] 0444 extKeys[event]=binding 0445 return extKeys 0446 0447 def __GetRawExtensionKeys(self,extensionName): 0448 """ 0449 returns a dictionary of the configurable keybindings for a particular 0450 extension, as defined in the configuration files, or an empty dictionary 0451 if no bindings are found 0452 """ 0453 keysName=extensionName+'_cfgBindings' 0454 extKeys={} 0455 if self.defaultCfg['extensions'].has_section(keysName): 0456 eventNames=self.defaultCfg['extensions'].GetOptionList(keysName) 0457 for eventName in eventNames: 0458 binding=self.GetOption('extensions',keysName, 0459 eventName,default='').split() 0460 event='<<'+eventName+'>>' 0461 extKeys[event]=binding 0462 return extKeys 0463 0464 def GetExtensionBindings(self,extensionName): 0465 """ 0466 Returns a dictionary of all the event bindings for a particular 0467 extension. The configurable keybindings are returned as they exist in 0468 the dictionary returned by GetCurrentKeySet; that is, where re-used 0469 keybindings are disabled. 0470 """ 0471 bindsName=extensionName+'_bindings' 0472 extBinds=self.GetExtensionKeys(extensionName) 0473 #add the non-configurable bindings 0474 if self.defaultCfg['extensions'].has_section(bindsName): 0475 eventNames=self.defaultCfg['extensions'].GetOptionList(bindsName) 0476 for eventName in eventNames: 0477 binding=self.GetOption('extensions',bindsName, 0478 eventName,default='').split() 0479 event='<<'+eventName+'>>' 0480 extBinds[event]=binding 0481 0482 return extBinds 0483 0484 def GetKeyBinding(self, keySetName, eventStr): 0485 """ 0486 returns the keybinding for a specific event. 0487 keySetName - string, name of key binding set 0488 eventStr - string, the virtual event we want the binding for, 0489 represented as a string, eg. '<<event>>' 0490 """ 0491 eventName=eventStr[2:-2] #trim off the angle brackets 0492 binding=self.GetOption('keys',keySetName,eventName,default='').split() 0493 return binding 0494 0495 def GetCurrentKeySet(self): 0496 return self.GetKeySet(self.CurrentKeys()) 0497 0498 def GetKeySet(self,keySetName): 0499 """ 0500 Returns a dictionary of: all requested core keybindings, plus the 0501 keybindings for all currently active extensions. If a binding defined 0502 in an extension is already in use, that binding is disabled. 0503 """ 0504 keySet=self.GetCoreKeys(keySetName) 0505 activeExtns=self.GetExtensions(active_only=1) 0506 for extn in activeExtns: 0507 extKeys=self.__GetRawExtensionKeys(extn) 0508 if extKeys: #the extension defines keybindings 0509 for event in extKeys.keys(): 0510 if extKeys[event] in keySet.values(): 0511 #the binding is already in use 0512 extKeys[event]='' #disable this binding 0513 keySet[event]=extKeys[event] #add binding 0514 return keySet 0515 0516 def IsCoreBinding(self,virtualEvent): 0517 """ 0518 returns true if the virtual event is bound in the core idle keybindings. 0519 virtualEvent - string, name of the virtual event to test for, without 0520 the enclosing '<< >>' 0521 """ 0522 return ('<<'+virtualEvent+'>>') in self.GetCoreKeys().keys() 0523 0524 def GetCoreKeys(self, keySetName=None): 0525 """ 0526 returns the requested set of core keybindings, with fallbacks if 0527 required. 0528 Keybindings loaded from the config file(s) are loaded _over_ these 0529 defaults, so if there is a problem getting any core binding there will 0530 be an 'ultimate last resort fallback' to the CUA-ish bindings 0531 defined here. 0532 """ 0533 keyBindings={ 0534 '<<copy>>': ['<Control-c>', '<Control-C>'], 0535 '<<cut>>': ['<Control-x>', '<Control-X>'], 0536 '<<paste>>': ['<Control-v>', '<Control-V>'], 0537 '<<beginning-of-line>>': ['<Control-a>', '<Home>'], 0538 '<<center-insert>>': ['<Control-l>'], 0539 '<<close-all-windows>>': ['<Control-q>'], 0540 '<<close-window>>': ['<Alt-F4>'], 0541 '<<do-nothing>>': ['<Control-x>'], 0542 '<<end-of-file>>': ['<Control-d>'], 0543 '<<python-docs>>': ['<F1>'], 0544 '<<python-context-help>>': ['<Shift-F1>'], 0545 '<<history-next>>': ['<Alt-n>'], 0546 '<<history-previous>>': ['<Alt-p>'], 0547 '<<interrupt-execution>>': ['<Control-c>'], 0548 '<<view-restart>>': ['<F6>'], 0549 '<<restart-shell>>': ['<Control-F6>'], 0550 '<<open-class-browser>>': ['<Alt-c>'], 0551 '<<open-module>>': ['<Alt-m>'], 0552 '<<open-new-window>>': ['<Control-n>'], 0553 '<<open-window-from-file>>': ['<Control-o>'], 0554 '<<plain-newline-and-indent>>': ['<Control-j>'], 0555 '<<print-window>>': ['<Control-p>'], 0556 '<<redo>>': ['<Control-y>'], 0557 '<<remove-selection>>': ['<Escape>'], 0558 '<<save-copy-of-window-as-file>>': ['<Alt-Shift-S>'], 0559 '<<save-window-as-file>>': ['<Alt-s>'], 0560 '<<save-window>>': ['<Control-s>'], 0561 '<<select-all>>': ['<Alt-a>'], 0562 '<<toggle-auto-coloring>>': ['<Control-slash>'], 0563 '<<undo>>': ['<Control-z>'], 0564 '<<find-again>>': ['<Control-g>', '<F3>'], 0565 '<<find-in-files>>': ['<Alt-F3>'], 0566 '<<find-selection>>': ['<Control-F3>'], 0567 '<<find>>': ['<Control-f>'], 0568 '<<replace>>': ['<Control-h>'], 0569 '<<goto-line>>': ['<Alt-g>'], 0570 '<<smart-backspace>>': ['<Key-BackSpace>'], 0571 '<<newline-and-indent>>': ['<Key-Return> <Key-KP_Enter>'], 0572 '<<smart-indent>>': ['<Key-Tab>'], 0573 '<<indent-region>>': ['<Control-Key-bracketright>'], 0574 '<<dedent-region>>': ['<Control-Key-bracketleft>'], 0575 '<<comment-region>>': ['<Alt-Key-3>'], 0576 '<<uncomment-region>>': ['<Alt-Key-4>'], 0577 '<<tabify-region>>': ['<Alt-Key-5>'], 0578 '<<untabify-region>>': ['<Alt-Key-6>'], 0579 '<<toggle-tabs>>': ['<Alt-Key-t>'], 0580 '<<change-indentwidth>>': ['<Alt-Key-u>'] 0581 } 0582 if keySetName: 0583 for event in keyBindings.keys(): 0584 binding=self.GetKeyBinding(keySetName,event) 0585 if binding: 0586 keyBindings[event]=binding 0587 else: #we are going to return a default, print warning 0588 warning=('\n Warning: configHandler.py - IdleConf.GetCoreKeys' 0589 ' -\n problem retrieving key binding for event %r' 0590 '\n from key set %r.\n' 0591 ' returning default value: %r\n' % 0592 (event, keySetName, keyBindings[event])) 0593 sys.stderr.write(warning) 0594 return keyBindings 0595 0596 def GetExtraHelpSourceList(self,configSet): 0597 """Fetch list of extra help sources from a given configSet. 0598 0599 Valid configSets are 'user' or 'default'. Return a list of tuples of 0600 the form (menu_item , path_to_help_file , option), or return the empty 0601 list. 'option' is the sequence number of the help resource. 'option' 0602 values determine the position of the menu items on the Help menu, 0603 therefore the returned list must be sorted by 'option'. 0604 0605 """ 0606 helpSources=[] 0607 if configSet=='user': 0608 cfgParser=self.userCfg['main'] 0609 elif configSet=='default': 0610 cfgParser=self.defaultCfg['main'] 0611 else: 0612 raise InvalidConfigSet, 'Invalid configSet specified' 0613 options=cfgParser.GetOptionList('HelpFiles') 0614 for option in options: 0615 value=cfgParser.Get('HelpFiles',option,default=';') 0616 if value.find(';')==-1: #malformed config entry with no ';' 0617 menuItem='' #make these empty 0618 helpPath='' #so value won't be added to list 0619 else: #config entry contains ';' as expected 0620 value=string.split(value,';') 0621 menuItem=value[0].strip() 0622 helpPath=value[1].strip() 0623 if menuItem and helpPath: #neither are empty strings 0624 helpSources.append( (menuItem,helpPath,option) ) 0625 helpSources.sort(self.__helpsort) 0626 return helpSources 0627 0628 def __helpsort(self, h1, h2): 0629 if int(h1[2]) < int(h2[2]): 0630 return -1 0631 elif int(h1[2]) > int(h2[2]): 0632 return 1 0633 else: 0634 return 0 0635 0636 def GetAllExtraHelpSourcesList(self): 0637 """ 0638 Returns a list of tuples containing the details of all additional help 0639 sources configured, or an empty list if there are none. Tuples are of 0640 the format returned by GetExtraHelpSourceList. 0641 """ 0642 allHelpSources=( self.GetExtraHelpSourceList('default')+ 0643 self.GetExtraHelpSourceList('user') ) 0644 return allHelpSources 0645 0646 def LoadCfgFiles(self): 0647 """ 0648 load all configuration files. 0649 """ 0650 for key in self.defaultCfg.keys(): 0651 self.defaultCfg[key].Load() 0652 self.userCfg[key].Load() #same keys 0653 0654 def SaveUserCfgFiles(self): 0655 """ 0656 write all loaded user configuration files back to disk 0657 """ 0658 for key in self.userCfg.keys(): 0659 self.userCfg[key].Save() 0660 0661 idleConf=IdleConf() 0662 0663 ### module test 0664 if __name__ == '__main__': 0665 def dumpCfg(cfg): 0666 print '\n',cfg,'\n' 0667 for key in cfg.keys(): 0668 sections=cfg[key].sections() 0669 print key 0670 print sections 0671 for section in sections: 0672 options=cfg[key].options(section) 0673 print section 0674 print options 0675 for option in options: 0676 print option, '=', cfg[key].Get(section,option) 0677 dumpCfg(idleConf.defaultCfg) 0678 dumpCfg(idleConf.userCfg) 0679 print idleConf.userCfg['main'].Get('Theme','name') 0680 #print idleConf.userCfg['highlight'].GetDefHighlight('Foo','normal') 0681
Generated by PyXR 0.9.4