From c628a06c709dcf0d96ad55a475a5a1318d06dba4 Mon Sep 17 00:00:00 2001 From: "Steven M. Gava" Date: Sat, 19 Jan 2002 10:33:21 +0000 Subject: [PATCH] further work on keybinding configuration --- Lib/idlelib/configDialog.py | 5 +- Lib/idlelib/configHandler.py | 101 ++++++++++++++++++++++++++++++-- Lib/idlelib/keybindingDialog.py | 32 ++++++++-- 3 files changed, 123 insertions(+), 15 deletions(-) diff --git a/Lib/idlelib/configDialog.py b/Lib/idlelib/configDialog.py index 2b133915572..42df59478b3 100644 --- a/Lib/idlelib/configDialog.py +++ b/Lib/idlelib/configDialog.py @@ -583,7 +583,7 @@ class ConfigDialog(Toplevel): self.optMenuKeysBuiltin.SetMenu(itemList,itemList[0]) self.SetKeysType() ##load keyset element list - keySet=idleConf.GetKeys(currentOption) + keySet=idleConf.GetCurrentKeySet() bindNames=keySet.keys() bindNames.sort() for bindName in bindNames: @@ -595,8 +595,7 @@ class ConfigDialog(Toplevel): listIndex=self.listBindings.index(ANCHOR) binding=self.listBindings.get(listIndex) bindName=binding.split()[0] #first part, up to first space - currentKeySet=idleConf.CurrentKeys() - currentKeySequences=idleConf.GetKeys(currentKeySet).values() + currentKeySequences=idleConf.GetCurrentKeySet().values() newKeys=GetKeysDialog(self,'Get New Keys',bindName,currentKeySequences) if newKeys.result: #new keys were specified self.listBindings.delete(listIndex) diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py index b78ae752d7a..34be897d1e5 100644 --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -153,7 +153,6 @@ class IdleConf: cfgParser=self.defaultCfg[configType] else: raise 'Invalid configSet specified' - return cfgParser.sections() def GetHighlight(self, theme, element, fgBg=None): @@ -215,8 +214,10 @@ class IdleConf: Gets a list of all idle extensions declared in the config files. activeOnly - boolean, if true only return active (enabled) extensions """ - extns=self.GetSectionList('default','extensions') - userExtns=self.GetSectionList('user','extensions') + extns=self.RemoveKeyBindNames( + self.GetSectionList('default','extensions')) + userExtns=self.RemoveKeyBindNames( + self.GetSectionList('user','extensions')) for extn in userExtns: if extn not in extns: #user has added own extension extns.append(extn) @@ -230,6 +231,75 @@ class IdleConf: else: 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)) + kbNameIndicies.sort() + kbNameIndicies.reverse() + for index in kbNameIndicies: #delete each keybinding section name + del(names[index]) + return names + + def GetExtensionKeys(self,extensionName): + """ + returns a dictionary of the configurable keybindings for a particular + extension,as they exist in the dictionary returned by GetCurrentKeySet; + that is, where previously re-used bindings are disabled. + """ + keysName=extensionName+'_cfgBindings' + activeKeys=self.GetCurrentKeySet() + extKeys={} + if self.defaultCfg['extensions'].has_section(keysName): + eventNames=self.defaultCfg['extensions'].GetOptionList(keysName) + for eventName in eventNames: + event='<<'+eventName+'>>' + binding=activeKeys[event] + extKeys[event]=binding + return extKeys + + def __GetRawExtensionKeys(self,extensionName): + """ + returns a dictionary of the configurable keybindings for a particular + extension, as defined in the configuration files, or an empty dictionary + if no bindings are found + """ + keysName=extensionName+'_cfgBindings' + extKeys={} + if self.defaultCfg['extensions'].has_section(keysName): + eventNames=self.defaultCfg['extensions'].GetOptionList(keysName) + for eventName in eventNames: + binding=self.GetOption('extensions',keysName, + eventName,default='').split() + event='<<'+eventName+'>>' + extKeys[event]=binding + 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 + keybindings are disabled. + """ + bindsName=extensionName+'_bindings' + extBinds=self.GetExtensionKeys(extensionName) + #add the non-configurable bindings + if self.defaultCfg['extensions'].has_section(bindsName): + eventNames=self.defaultCfg['extensions'].GetOptionList(bindsName) + for eventName in eventNames: + binding=self.GetOption('extensions',bindsName, + eventName,default='').split() + event='<<'+eventName+'>>' + extBinds[event]=binding + + return extBinds + + + def GetKeyBinding(self, keySetName, eventStr): """ returns the keybinding for a specific event. @@ -241,12 +311,31 @@ class IdleConf: binding=self.GetOption('keys',keySetName,eventName,default='').split() return binding - def GetKeys(self, keySetName=None): + def GetCurrentKeySet(self): """ - returns the requested set of keybindings, with fallbacks if required. + Returns a dictionary of: all current 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. + """ + currentKeySet=self.GetCoreKeys(keySetName=self.CurrentKeys()) + activeExtns=self.GetExtensions(activeOnly=1) + for extn in activeExtns: + extKeys=self.__GetRawExtensionKeys(extn) + if extKeys: #the extension defines keybindings + for event in extKeys.keys(): + if extKeys[event] in currentKeySet.values(): + #the binding is already in use + extKeys[event]='' #disable this binding + currentKeySet[event]=extKeys[event] #add binding + return currentKeySet + + def GetCoreKeys(self, keySetName=None): + """ + returns the requested set of core keybindings, with fallbacks if + required. """ #keybindings loaded from the config file(s) are loaded _over_ these - #defaults, so if there is a problem getting any binding there will + #defaults, so if there is a problem getting any core binding there will #be an 'ultimate last resort fallback' to the CUA-ish bindings #defined here. keyBindings={ diff --git a/Lib/idlelib/keybindingDialog.py b/Lib/idlelib/keybindingDialog.py index 0958578c035..c510257f56d 100644 --- a/Lib/idlelib/keybindingDialog.py +++ b/Lib/idlelib/keybindingDialog.py @@ -161,9 +161,10 @@ class GetKeysDialog(Toplevel): keyList=keyList+modifiers if finalKey: if (not modifiers) and (finalKey in self.functionKeys): - finalKey='<'+finalKey + finalKey='<'+self.TranslateKey(finalKey) + else: + finalKey=self.TranslateKey(finalKey) keyList.append(finalKey+'>') - keyStr=string.join(keyList,'-') self.keyString.set(keyStr) @@ -189,15 +190,34 @@ class GetKeysDialog(Toplevel): #these tuples are also available for use in validity checks self.functionKeys=('F1','F2','F2','F4','F5','F6','F7','F8','F9', 'F10','F11','F12') - self.punctuationKeys=tuple('~!@#%^&*()_-+={}[]|;:,./?') - self.specialKeys=('tab','space') self.alphanumKeys=tuple(string.ascii_lowercase+string.digits) + self.punctuationKeys=tuple('~!@#%^&*()_-+={}[]|;:,.<>/?') + self.whitespaceKeys=('Tab','Space','Return') + self.editKeys=('BackSpace','Delete','Insert') + self.moveKeys=('Home','End','Page Up','Page Down','Left Arrow', + 'Right Arrow','Up Arrow','Down Arrow') #make a tuple of most of the useful common 'final' keys - keys=(self.alphanumKeys+self.punctuationKeys+self.specialKeys+ - self.functionKeys) + keys=(self.alphanumKeys+self.punctuationKeys+self.functionKeys+ + 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', + '%':'percent','^':'asciicircum','&':'ampersand','*':'asterisk', + '(':'parenleft',')':'parenright','_':'underscore','-':'minus', + '+':'plus','=':'equal','{':'braceleft','}':'braceright', + '[':'bracketleft',']':'bracketright','|':'bar',';':'semicolon', + ':':'colon',',':'comma','.':'period','<':'less','>':'greater', + '/':'slash','?':'question','Page Up':'Prior','Page Down':'Next', + 'Left Arrow':'Left','Right Arrow':'Right','Up Arrow':'Up', + 'Down Arrow': 'Down'} + if key in translateDict.keys(): + key=translateDict[key] + key='Key-'+key + return key + def Ok(self, event=None): if self.KeysOk(): self.result=self.keyString.get()