mirror of
https://github.com/python/cpython.git
synced 2025-07-19 17:25:54 +00:00
further work on keybinding configuration
This commit is contained in:
parent
68d7336cb0
commit
c628a06c70
3 changed files with 123 additions and 15 deletions
|
@ -583,7 +583,7 @@ class ConfigDialog(Toplevel):
|
||||||
self.optMenuKeysBuiltin.SetMenu(itemList,itemList[0])
|
self.optMenuKeysBuiltin.SetMenu(itemList,itemList[0])
|
||||||
self.SetKeysType()
|
self.SetKeysType()
|
||||||
##load keyset element list
|
##load keyset element list
|
||||||
keySet=idleConf.GetKeys(currentOption)
|
keySet=idleConf.GetCurrentKeySet()
|
||||||
bindNames=keySet.keys()
|
bindNames=keySet.keys()
|
||||||
bindNames.sort()
|
bindNames.sort()
|
||||||
for bindName in bindNames:
|
for bindName in bindNames:
|
||||||
|
@ -595,8 +595,7 @@ class ConfigDialog(Toplevel):
|
||||||
listIndex=self.listBindings.index(ANCHOR)
|
listIndex=self.listBindings.index(ANCHOR)
|
||||||
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
|
||||||
currentKeySet=idleConf.CurrentKeys()
|
currentKeySequences=idleConf.GetCurrentKeySet().values()
|
||||||
currentKeySequences=idleConf.GetKeys(currentKeySet).values()
|
|
||||||
newKeys=GetKeysDialog(self,'Get New Keys',bindName,currentKeySequences)
|
newKeys=GetKeysDialog(self,'Get New Keys',bindName,currentKeySequences)
|
||||||
if newKeys.result: #new keys were specified
|
if newKeys.result: #new keys were specified
|
||||||
self.listBindings.delete(listIndex)
|
self.listBindings.delete(listIndex)
|
||||||
|
|
|
@ -153,7 +153,6 @@ class IdleConf:
|
||||||
cfgParser=self.defaultCfg[configType]
|
cfgParser=self.defaultCfg[configType]
|
||||||
else:
|
else:
|
||||||
raise 'Invalid configSet specified'
|
raise 'Invalid configSet specified'
|
||||||
|
|
||||||
return cfgParser.sections()
|
return cfgParser.sections()
|
||||||
|
|
||||||
def GetHighlight(self, theme, element, fgBg=None):
|
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.
|
Gets a list of all idle extensions declared in the config files.
|
||||||
activeOnly - boolean, if true only return active (enabled) extensions
|
activeOnly - boolean, if true only return active (enabled) extensions
|
||||||
"""
|
"""
|
||||||
extns=self.GetSectionList('default','extensions')
|
extns=self.RemoveKeyBindNames(
|
||||||
userExtns=self.GetSectionList('user','extensions')
|
self.GetSectionList('default','extensions'))
|
||||||
|
userExtns=self.RemoveKeyBindNames(
|
||||||
|
self.GetSectionList('user','extensions'))
|
||||||
for extn in userExtns:
|
for extn in userExtns:
|
||||||
if extn not in extns: #user has added own extension
|
if extn not in extns: #user has added own extension
|
||||||
extns.append(extn)
|
extns.append(extn)
|
||||||
|
@ -230,6 +231,75 @@ class IdleConf:
|
||||||
else:
|
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))
|
||||||
|
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):
|
def GetKeyBinding(self, keySetName, eventStr):
|
||||||
"""
|
"""
|
||||||
returns the keybinding for a specific event.
|
returns the keybinding for a specific event.
|
||||||
|
@ -241,12 +311,31 @@ class IdleConf:
|
||||||
binding=self.GetOption('keys',keySetName,eventName,default='').split()
|
binding=self.GetOption('keys',keySetName,eventName,default='').split()
|
||||||
return binding
|
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
|
#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
|
#be an 'ultimate last resort fallback' to the CUA-ish bindings
|
||||||
#defined here.
|
#defined here.
|
||||||
keyBindings={
|
keyBindings={
|
||||||
|
|
|
@ -161,9 +161,10 @@ class GetKeysDialog(Toplevel):
|
||||||
keyList=keyList+modifiers
|
keyList=keyList+modifiers
|
||||||
if finalKey:
|
if finalKey:
|
||||||
if (not modifiers) and (finalKey in self.functionKeys):
|
if (not modifiers) and (finalKey in self.functionKeys):
|
||||||
finalKey='<'+finalKey
|
finalKey='<'+self.TranslateKey(finalKey)
|
||||||
|
else:
|
||||||
|
finalKey=self.TranslateKey(finalKey)
|
||||||
keyList.append(finalKey+'>')
|
keyList.append(finalKey+'>')
|
||||||
|
|
||||||
keyStr=string.join(keyList,'-')
|
keyStr=string.join(keyList,'-')
|
||||||
self.keyString.set(keyStr)
|
self.keyString.set(keyStr)
|
||||||
|
|
||||||
|
@ -189,15 +190,34 @@ class GetKeysDialog(Toplevel):
|
||||||
#these tuples are also available for use in validity checks
|
#these tuples are also available for use in validity checks
|
||||||
self.functionKeys=('F1','F2','F2','F4','F5','F6','F7','F8','F9',
|
self.functionKeys=('F1','F2','F2','F4','F5','F6','F7','F8','F9',
|
||||||
'F10','F11','F12')
|
'F10','F11','F12')
|
||||||
self.punctuationKeys=tuple('~!@#%^&*()_-+={}[]|;:,./?')
|
|
||||||
self.specialKeys=('tab','space')
|
|
||||||
self.alphanumKeys=tuple(string.ascii_lowercase+string.digits)
|
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
|
#make a tuple of most of the useful common 'final' keys
|
||||||
keys=(self.alphanumKeys+self.punctuationKeys+self.specialKeys+
|
keys=(self.alphanumKeys+self.punctuationKeys+self.functionKeys+
|
||||||
self.functionKeys)
|
self.whitespaceKeys+self.editKeys+self.moveKeys)
|
||||||
apply(self.listKeysFinal.insert,
|
apply(self.listKeysFinal.insert,
|
||||||
(END,)+keys)
|
(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):
|
def Ok(self, event=None):
|
||||||
if self.KeysOk():
|
if self.KeysOk():
|
||||||
self.result=self.keyString.get()
|
self.result=self.keyString.get()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue