keybinding configuration

This commit is contained in:
Steven M. Gava 2002-01-19 00:29:54 +00:00
parent d45a543418
commit facfc09352
5 changed files with 110 additions and 72 deletions

View file

@ -13,7 +13,6 @@ beginning-of-line=<Control-a> <Home>
center-insert=<Control-l> center-insert=<Control-l>
close-all-windows=<Control-q> close-all-windows=<Control-q>
close-window=<Alt-F4> close-window=<Alt-F4>
dump-undo-state=<Control-backslash>
end-of-file=<Control-d> end-of-file=<Control-d>
python-docs=<F1> python-docs=<F1>
python-context-help=<Shift-F1> python-context-help=<Shift-F1>
@ -49,7 +48,6 @@ center-insert=<Control-l>
close-all-windows=<Control-x><Control-c> close-all-windows=<Control-x><Control-c>
close-window=<Control-x><Control-0> <Control-x><Key-0> close-window=<Control-x><Control-0> <Control-x><Key-0>
do-nothing=<Control-x> do-nothing=<Control-x>
dump-undo-state=<Control-backslash>
end-of-file=<Control-d> end-of-file=<Control-d>
history-next=<Alt-n> <Meta-n> history-next=<Alt-n> <Meta-n>
history-previous=<Alt-p> <Meta-p> history-previous=<Alt-p> <Meta-p>

View file

@ -3,10 +3,12 @@ configuration dialog
""" """
from Tkinter import * from Tkinter import *
import tkMessageBox, tkColorChooser, tkFont import tkMessageBox, tkColorChooser, tkFont
import string
from configHandler import idleConf from configHandler import idleConf
from dynOptionMenuWidget import DynOptionMenu from dynOptionMenuWidget import DynOptionMenu
from tabpage import TabPageSet from tabpage import TabPageSet
from keybindingDialog import GetKeysDialog
class ConfigDialog(Toplevel): class ConfigDialog(Toplevel):
""" """
@ -354,20 +356,17 @@ class ConfigDialog(Toplevel):
frameKeySets=Frame(frame,borderwidth=2,relief=GROOVE) frameKeySets=Frame(frame,borderwidth=2,relief=GROOVE)
#frameCustom #frameCustom
frameTarget=Frame(frameCustom) frameTarget=Frame(frameCustom)
frameSet=Frame(frameCustom)
labelCustomTitle=Label(frameCustom,text='Set Custom Key Bindings') labelCustomTitle=Label(frameCustom,text='Set Custom Key Bindings')
labelTargetTitle=Label(frameTarget,text='Action') labelTargetTitle=Label(frameTarget,text='Action - Key(s)')
scrollTarget=Scrollbar(frameTarget) scrollTargetY=Scrollbar(frameTarget)
listTarget=Listbox(frameTarget) scrollTargetX=Scrollbar(frameTarget,orient=HORIZONTAL)
scrollTarget.config(command=listTarget.yview) self.listBindings=Listbox(frameTarget)
listTarget.config(yscrollcommand=scrollTarget.set) scrollTargetY.config(command=self.listBindings.yview)
labelKeyBindTitle=Label(frameSet,text='Binding') scrollTargetX.config(command=self.listBindings.xview)
labelModifierTitle=Label(frameSet,text='Modifier:') self.listBindings.config(yscrollcommand=scrollTargetY.set)
checkCtrl=Checkbutton(frameSet,text='Ctrl') self.listBindings.config(xscrollcommand=scrollTargetX.set)
checkAlt=Checkbutton(frameSet,text='Alt') buttonNewKeys=Button(frameCustom,text='Get New Keys for Selection',
checkShift=Checkbutton(frameSet,text='Shift') command=self.GetNewKeys)
labelKeyEntryTitle=Label(frameSet,text='Key:')
entryKey=Entry(frameSet,width=4)
buttonSaveCustomKeys=Button(frameCustom,text='Save as a Custom Key Set') buttonSaveCustomKeys=Button(frameCustom,text='Save as a Custom Key Set')
#frameKeySets #frameKeySets
labelKeysTitle=Label(frameKeySets,text='Select a Key Set') labelKeysTitle=Label(frameKeySets,text='Select a Key Set')
@ -388,18 +387,15 @@ class ConfigDialog(Toplevel):
#frameCustom #frameCustom
labelCustomTitle.pack(side=TOP,anchor=W,padx=5,pady=5) labelCustomTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
buttonSaveCustomKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5) buttonSaveCustomKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5)
frameTarget.pack(side=LEFT,padx=5,pady=5,fill=Y) buttonNewKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5)
frameSet.pack(side=LEFT,padx=5,pady=5,fill=Y) frameTarget.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH)
labelTargetTitle.pack(side=TOP,anchor=W) #frame target
scrollTarget.pack(side=RIGHT,anchor=W,fill=Y) frameTarget.columnconfigure(0,weight=1)
listTarget.pack(side=TOP,anchor=W,expand=TRUE,fill=BOTH) frameTarget.rowconfigure(1,weight=1)
labelKeyBindTitle.pack(side=TOP,anchor=W) labelTargetTitle.grid(row=0,column=0,columnspan=2,sticky=W)
labelModifierTitle.pack(side=TOP,anchor=W,pady=5) self.listBindings.grid(row=1,column=0,sticky=NSEW)
checkCtrl.pack(side=TOP,anchor=W) scrollTargetY.grid(row=1,column=1,sticky=NS)
checkAlt.pack(side=TOP,anchor=W,pady=2) scrollTargetX.grid(row=2,column=0,sticky=EW)
checkShift.pack(side=TOP,anchor=W)
labelKeyEntryTitle.pack(side=TOP,anchor=W,pady=5)
entryKey.pack(side=TOP,anchor=W)
#frameKeySets #frameKeySets
labelKeysTitle.pack(side=TOP,anchor=W,padx=5,pady=5) labelKeysTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
labelTypeTitle.pack(side=TOP,anchor=W,padx=5,pady=5) labelTypeTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
@ -432,7 +428,6 @@ class ConfigDialog(Toplevel):
value=1,command=self.SetKeysType,text='in a Separate Process') value=1,command=self.SetKeysType,text='in a Separate Process')
#frameWinSize #frameWinSize
labelWinSizeTitle=Label(frameWinSize,text='Initial Window Size') labelWinSizeTitle=Label(frameWinSize,text='Initial Window Size')
buttonWinSizeSet=Button(frameWinSize,text='Set to current window size')
labelWinWidthTitle=Label(frameWinSize,text='Width') labelWinWidthTitle=Label(frameWinSize,text='Width')
entryWinWidth=Entry(frameWinSize,textvariable=self.winWidth, entryWinWidth=Entry(frameWinSize,textvariable=self.winWidth,
width=3) width=3)
@ -467,12 +462,11 @@ class ConfigDialog(Toplevel):
radioRunInternal.pack(side=LEFT,anchor=W,padx=5,pady=5) radioRunInternal.pack(side=LEFT,anchor=W,padx=5,pady=5)
radioRunSeparate.pack(side=LEFT,anchor=W,padx=5,pady=5) radioRunSeparate.pack(side=LEFT,anchor=W,padx=5,pady=5)
#frameWinSize #frameWinSize
labelWinSizeTitle.pack(side=TOP,anchor=W,padx=5,pady=5) labelWinSizeTitle.pack(side=LEFT,anchor=W,padx=5,pady=5)
buttonWinSizeSet.pack(side=LEFT,anchor=W,padx=5,pady=5) entryWinHeight.pack(side=RIGHT,anchor=E,padx=10,pady=5)
labelWinWidthTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) labelWinHeightTitle.pack(side=RIGHT,anchor=E,pady=5)
entryWinWidth.pack(side=LEFT,anchor=W,padx=5,pady=5) entryWinWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5)
labelWinHeightTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) labelWinWidthTitle.pack(side=RIGHT,anchor=E,pady=5)
entryWinHeight.pack(side=LEFT,anchor=W,padx=5,pady=5)
#frameExt #frameExt
labelExtTitle.pack(side=TOP,anchor=W,padx=5,pady=5) labelExtTitle.pack(side=TOP,anchor=W,padx=5,pady=5)
frameExtSet.pack(side=RIGHT,padx=5,pady=5,fill=Y) frameExtSet.pack(side=RIGHT,padx=5,pady=5,fill=Y)
@ -588,7 +582,31 @@ class ConfigDialog(Toplevel):
itemList=idleConf.GetSectionList('default','keys') itemList=idleConf.GetSectionList('default','keys')
self.optMenuKeysBuiltin.SetMenu(itemList,itemList[0]) self.optMenuKeysBuiltin.SetMenu(itemList,itemList[0])
self.SetKeysType() self.SetKeysType()
##load keyset element option menu ##load keyset element list
keySet=idleConf.GetKeys(currentOption)
bindNames=keySet.keys()
bindNames.sort()
for bindName in bindNames:
key=string.join(keySet[bindName]) #make key(s) into a string
bindName=bindName[2:-2] #trim off the angle brackets
self.listBindings.insert(END, bindName+' - '+key)
def GetNewKeys(self):
listIndex=self.listBindings.index(ANCHOR)
binding=self.listBindings.get(listIndex)
bindName=binding.split()[0] #first part, up to first space
newKeys=GetKeysDialog(self,'Get New Keys',bindName)
print newKeys.result
if newKeys.result: #new keys were specified
self.listBindings.delete(listIndex)
self.listBindings.insert(listIndex,bindName+' - '+newKeys.result)
self.listBindings.select_set(listIndex)
def LoadGeneralCfg(self):
#initial window size
self.winWidth.set(idleConf.GetOption('main','EditorWindow','width'))
self.winHeight.set(idleConf.GetOption('main','EditorWindow','height'))
def LoadConfigs(self): def LoadConfigs(self):
""" """
@ -604,6 +622,7 @@ class ConfigDialog(Toplevel):
self.LoadKeyCfg() self.LoadKeyCfg()
### help page ### help page
### general page ### general page
self.LoadGeneralCfg()
def SaveConfigs(self): def SaveConfigs(self):
""" """

View file

@ -257,7 +257,6 @@ class IdleConf:
'<<center-insert>>': ['<Control-l>'], '<<center-insert>>': ['<Control-l>'],
'<<close-all-windows>>': ['<Control-q>'], '<<close-all-windows>>': ['<Control-q>'],
'<<close-window>>': ['<Alt-F4>'], '<<close-window>>': ['<Alt-F4>'],
'<<dump-undo-state>>': ['<Control-backslash>'],
'<<end-of-file>>': ['<Control-d>'], '<<end-of-file>>': ['<Control-d>'],
'<<python-docs>>': ['<F1>'], '<<python-docs>>': ['<F1>'],
'<<python-context-help>>': ['<Shift-F1>'], '<<python-context-help>>': ['<Shift-F1>'],

View file

@ -1,9 +1,3 @@
##---------------------------------------------------------------------------##
##
## idle - modified OptionMenu widget
## elguavas
##
##---------------------------------------------------------------------------##
""" """
OptionMenu widget modified to allow dynamic menu reconfiguration OptionMenu widget modified to allow dynamic menu reconfiguration
and setting of highlightthickness and setting of highlightthickness

View file

@ -5,8 +5,8 @@ from Tkinter import *
import tkMessageBox import tkMessageBox
import string, os import string, os
class GetAccelDialog(Toplevel): class GetKeysDialog(Toplevel):
def __init__(self,parent,title,action,keySequenceStr): def __init__(self,parent,title,action):
Toplevel.__init__(self, parent) Toplevel.__init__(self, parent)
self.configure(borderwidth=5) self.configure(borderwidth=5)
self.resizable(height=FALSE,width=FALSE) self.resizable(height=FALSE,width=FALSE)
@ -16,7 +16,7 @@ class GetAccelDialog(Toplevel):
self.protocol("WM_DELETE_WINDOW", self.Cancel) self.protocol("WM_DELETE_WINDOW", self.Cancel)
self.parent = parent self.parent = parent
self.action=action self.action=action
self.keySequenceStr=keySequenceStr self.result=''
self.keyString=StringVar(self) self.keyString=StringVar(self)
self.keyString.set('') self.keyString.set('')
self.keyCtrl=StringVar(self) self.keyCtrl=StringVar(self)
@ -107,13 +107,12 @@ class GetAccelDialog(Toplevel):
command=self.listKeysFinal.yview) command=self.listKeysFinal.yview)
self.listKeysFinal.config(yscrollcommand=scrollKeysFinal.set) self.listKeysFinal.config(yscrollcommand=scrollKeysFinal.set)
scrollKeysFinal.grid(row=0,column=5,rowspan=4,sticky=NS) scrollKeysFinal.grid(row=0,column=5,rowspan=4,sticky=NS)
self.buttonAddNew=Button(self.frameControlsBasic, # self.buttonAddNew=Button(self.frameControlsBasic,
text='Accept Key Sequence',width=25,command=None) # text='Accept Key Sequence',width=25,command=None)
self.buttonAddNew.grid(row=2,column=0,columnspan=4) # self.buttonAddNew.grid(row=2,column=0,columnspan=4)
self.buttonClearLast=Button(self.frameControlsBasic, self.buttonClear=Button(self.frameControlsBasic,
text='Clear Last Key Sequence',width=25, text='Clear Keys',command=self.ClearKeySeq)
command=self.ClearLastKeySeq) self.buttonClear.grid(row=2,column=0,columnspan=4)
self.buttonClearLast.grid(row=3,column=0,columnspan=4)
labelTitleAdvanced = Label(self.frameKeySeqAdvanced,justify=LEFT, labelTitleAdvanced = Label(self.frameKeySeqAdvanced,justify=LEFT,
text="Enter new binding(s) for '"+self.action+"' :\n"+ text="Enter new binding(s) for '"+self.action+"' :\n"+
"(will not be checked for validity)") "(will not be checked for validity)")
@ -133,11 +132,13 @@ class GetAccelDialog(Toplevel):
def ToggleLevel(self): def ToggleLevel(self):
if self.buttonLevel.cget('text')[:8]=='Advanced': if self.buttonLevel.cget('text')[:8]=='Advanced':
self.ClearKeySeq()
self.buttonLevel.config(text='<< Basic Key Binding Entry') self.buttonLevel.config(text='<< Basic Key Binding Entry')
self.frameKeySeqAdvanced.lift() self.frameKeySeqAdvanced.lift()
self.frameHelpAdvanced.lift() self.frameHelpAdvanced.lift()
self.entryKeysAdvanced.focus_set() self.entryKeysAdvanced.focus_set()
else: else:
self.ClearKeySeq()
self.buttonLevel.config(text='Advanced Key Binding Entry >>') self.buttonLevel.config(text='Advanced Key Binding Entry >>')
self.frameKeySeqBasic.lift() self.frameKeySeqBasic.lift()
self.frameControlsBasic.lift() self.frameControlsBasic.lift()
@ -147,8 +148,7 @@ class GetAccelDialog(Toplevel):
def BuildKeyString(self): def BuildKeyString(self):
keyList=[] keyList=[]
modifiers=self.GetModifiers(self.keyCtrl.get(),self.keyAlt.get(), modifiers=self.GetModifiers()
self.keyShift.get())
finalKey=self.listKeysFinal.get(ANCHOR) finalKey=self.listKeysFinal.get(ANCHOR)
if modifiers: modifiers[0]='<'+modifiers[0] if modifiers: modifiers[0]='<'+modifiers[0]
keyList=keyList+modifiers keyList=keyList+modifiers
@ -160,39 +160,67 @@ class GetAccelDialog(Toplevel):
keyStr=string.join(keyList,'-') keyStr=string.join(keyList,'-')
self.keyString.set(keyStr) self.keyString.set(keyStr)
def GetModifiers(self):
# if (finalKey not in self.functionKeys) and (not modifiers):
# tkMessageBox.showerror(title='Key Binding Error',
# message='At least one modifier key should be specified.')
# return
def GetModifiers(self,ctrl,alt,shift):
modList=[] modList=[]
ctrl=self.keyCtrl.get()
alt=self.keyAlt.get()
shift=self.keyShift.get()
if ctrl: modList.append(ctrl) if ctrl: modList.append(ctrl)
if alt: modList.append(alt) if alt: modList.append(alt)
if shift: modList.append(shift) if shift: modList.append(shift)
return modList return modList
def ClearLastKeySeq(self): def ClearKeySeq(self):
pass self.listKeysFinal.select_clear(0,END)
self.listKeysFinal.yview(MOVETO, '0.0')
self.keyCtrl.set('')
self.keyAlt.set(''),
self.keyShift.set('')
self.keyString.set('')
def LoadFinalKeyList(self): def LoadFinalKeyList(self):
#make a tuple of most of the useful common 'final' keys #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')
keys=(tuple(string.ascii_lowercase+string.digits+ self.punctuationKeys=tuple('~!@#%^&*()_-+={}[]|;:,./?')
'~!@#%^&*()_-+={}[]|;:,./?')+('tab','space')+self.functionKeys) self.specialKeys=('tab','space')
self.alphanumKeys=tuple(string.ascii_lowercase+string.digits)
#make a tuple of most of the useful common 'final' keys
keys=(self.alphanumKeys+self.punctuationKeys+self.specialKeys+
self.functionKeys)
apply(self.listKeysFinal.insert, apply(self.listKeysFinal.insert,
(END,)+keys) (END,)+keys)
def KeysOk(self):
#simple validity check
keysOk=1
keys=self.keyString.get()
keys.strip()
finalKey=self.listKeysFinal.get(ANCHOR)
modifiers=self.GetModifiers()
if not keys: #no keys specified
tkMessageBox.showerror(title='Key Sequence Error',
message='No keys specified.')
keysOk=0
elif not keys.endswith('>'): #no final key specified
tkMessageBox.showerror(title='Key Sequence Error',
message='No final key specified.')
keysOk=0
elif (modifiers==['Shift']) and (finalKey not in self.functionKeys):
#shift alone is only a useful modifier with a function key
tkMessageBox.showerror(title='Key Sequence Error',
message='Shift alone is only a useful modifier '+
'when used with a function key.')
keysOk=0
return keysOk
def Ok(self, event=None): def Ok(self, event=None):
if self.KeysOk(): if self.KeysOk():
self.keySequenceStr=self.keyDisplay.get() self.result=self.keyString.get()
self.destroy() self.destroy()
def Cancel(self, event=None): def Cancel(self, event=None):
self.keySequenceStr='' self.result=''
self.destroy() self.destroy()
if __name__ == '__main__': if __name__ == '__main__':
@ -202,7 +230,7 @@ if __name__ == '__main__':
#import aboutDialog #import aboutDialog
#aboutDialog.AboutDialog(root,'About') #aboutDialog.AboutDialog(root,'About')
keySeq='' keySeq=''
GetAccelDialog(root,'Get Keys','find-again',keySeq) dlg=GetKeysDialog(root,'Get Keys','find-again')
print keySeq print dlg.result
Button(root,text='Dialog',command=run).pack() Button(root,text='Dialog',command=run).pack()
root.mainloop() root.mainloop()