Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2303b1c

Browse files
committed
Keybindings with the Shift modifier now work correctly. So do bindings
which use the Space key. Limit unmodified user keybindings to the function keys. Python Bug 775353, IDLEfork Bugs 755647, 761557 Improve error handling during startup if there's no Tkinter. M NEWS.txt M PyShell.py M config-keys.def M configHandler.py M keybindingDialog.py Backport candidate.
1 parent 5f4e45d commit 2303b1c

5 files changed

Lines changed: 83 additions & 74 deletions

File tree

Lib/idlelib/NEWS.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ What's New in IDLE 1.0+?
33

44
*Release date: XX-XXX-2003*
55

6+
- Keybindings with the Shift modifier now work correctly. So do bindings which
7+
use the Space key. Limit unmodified user keybindings to the function keys.
8+
Python Bug 775353, IDLEfork Bugs 755647, 761557
9+
610
- After an exception, run.py was not setting the exception vector. Noam
711
Raphael suggested correcting this so pdb's postmortem pm() would work.
812
IDLEfork Patch 844675

Lib/idlelib/PyShell.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@
1616
import linecache
1717
from code import InteractiveInterpreter
1818

19-
from Tkinter import *
19+
try:
20+
from Tkinter import *
21+
except ImportError:
22+
print>>sys.__stderr__, "** IDLE can't import Tkinter. " \
23+
"Your Python may not be configured for Tk. **"
24+
sys.exit(1)
2025
import tkMessageBox
2126

2227
from EditorWindow import EditorWindow, fixwordbreaks

Lib/idlelib/config-keys.def

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ open-new-window=<Control-Key-n>
3030
open-window-from-file=<Control-Key-o>
3131
plain-newline-and-indent=<Control-Key-j>
3232
print-window=<Control-Key-p>
33-
redo=<Control-Shift-Key-z>
33+
redo=<Control-Shift-Key-Z>
3434
remove-selection=<Key-Escape>
35-
save-copy-of-window-as-file=<Alt-Shift-Key-s>
36-
save-window-as-file=<Control-Shift-Key-s>
35+
save-copy-of-window-as-file=<Alt-Shift-Key-S>
36+
save-window-as-file=<Control-Shift-Key-S>
3737
save-window=<Control-Key-s>
3838
select-all=<Control-Key-a>
3939
toggle-auto-coloring=<Control-Key-slash>
@@ -78,7 +78,7 @@ open-window-from-file=<Control-Key-x><Control-Key-f>
7878
plain-newline-and-indent=<Control-Key-j>
7979
print-window=<Control-x><Control-Key-p>
8080
python-docs=<Control-Key-h>
81-
python-context-help=<Control-Shift-Key-h>
81+
python-context-help=<Control-Shift-Key-H>
8282
redo=<Alt-Key-z> <Meta-Key-z>
8383
remove-selection=<Key-Escape>
8484
save-copy-of-window-as-file=<Control-Key-x><Control-Key-y>
@@ -128,9 +128,9 @@ open-new-window=<Command-Key-n>
128128
open-window-from-file=<Command-Key-o>
129129
plain-newline-and-indent=<Control-Key-j>
130130
print-window=<Command-Key-p>
131-
redo=<Shift-Command-Key-z>
131+
redo=<Shift-Command-Key-Z>
132132
remove-selection=<Key-Escape>
133-
save-window-as-file=<Shift-Command-Key-s>
133+
save-window-as-file=<Shift-Command-Key-S>
134134
save-window=<Command-Key-s>
135135
save-copy-of-window-as-file=<Option-Command-Key-s>
136136
select-all=<Command-Key-a>

Lib/idlelib/configHandler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ def GetCoreKeys(self, keySetName=None):
531531
'<<print-window>>': ['<Control-p>'],
532532
'<<redo>>': ['<Control-y>'],
533533
'<<remove-selection>>': ['<Escape>'],
534-
'<<save-copy-of-window-as-file>>': ['<Alt-Shift-s>'],
534+
'<<save-copy-of-window-as-file>>': ['<Alt-Shift-S>'],
535535
'<<save-window-as-file>>': ['<Alt-s>'],
536536
'<<save-window>>': ['<Control-s>'],
537537
'<<select-all>>': ['<Alt-a>'],

Lib/idlelib/keybindingDialog.py

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
dialog for building tkinter accelerator key bindings
2+
Dialog for building Tkinter accelerator key bindings
33
"""
44
from Tkinter import *
55
import tkMessageBox
@@ -49,9 +49,9 @@ def CreateWidgets(self):
4949
frameMain.pack(side=TOP,expand=TRUE,fill=BOTH)
5050
frameButtons=Frame(self)
5151
frameButtons.pack(side=BOTTOM,fill=X)
52-
self.buttonOk = Button(frameButtons,text='Ok',
53-
width=8,command=self.Ok)
54-
self.buttonOk.grid(row=0,column=0,padx=5,pady=5)
52+
self.buttonOK = Button(frameButtons,text='OK',
53+
width=8,command=self.OK)
54+
self.buttonOK.grid(row=0,column=0,padx=5,pady=5)
5555
self.buttonCancel = Button(frameButtons,text='Cancel',
5656
width=8,command=self.Cancel)
5757
self.buttonCancel.grid(row=0,column=1,padx=5,pady=5)
@@ -85,9 +85,13 @@ def CreateWidgets(self):
8585
self.modifier_checkbuttons[modifier] = check
8686
column += 1
8787
labelFnAdvice=Label(self.frameControlsBasic,justify=LEFT,
88-
text="Select the desired modifier\n"+
89-
"keys above, and final key\n"+
90-
"from the list on the right.")
88+
text=\
89+
"Select the desired modifier keys\n"+
90+
"above, and the final key from the\n"+
91+
"list on the right.\n\n" +
92+
"Use upper case Symbols when using\n" +
93+
"the Shift modifier. (Letters will be\n" +
94+
"converted automatically.)")
9195
labelFnAdvice.grid(row=1,column=0,columnspan=4,padx=2,sticky=W)
9296
self.listKeysFinal=Listbox(self.frameControlsBasic,width=15,height=10,
9397
selectmode=SINGLE)
@@ -102,17 +106,19 @@ def CreateWidgets(self):
102106
self.buttonClear.grid(row=2,column=0,columnspan=4)
103107
labelTitleAdvanced = Label(self.frameKeySeqAdvanced,justify=LEFT,
104108
text="Enter new binding(s) for '"+self.action+"' :\n"+
105-
"(will not be checked for validity)")
109+
"(These bindings will not be checked for validity!)")
106110
labelTitleAdvanced.pack(anchor=W)
107111
self.entryKeysAdvanced=Entry(self.frameKeySeqAdvanced,
108112
textvariable=self.keyString)
109113
self.entryKeysAdvanced.pack(fill=X)
110114
labelHelpAdvanced=Label(self.frameHelpAdvanced,justify=LEFT,
111-
text="Key bindings are specified using tkinter key id's as\n"+
115+
text="Key bindings are specified using Tkinter keysyms as\n"+
112116
"in these samples: <Control-f>, <Shift-F2>, <F12>,\n"
113-
"<Control-space>, <Meta-less>, <Control-Alt-Shift-x>.\n\n"+
114-
"'Emacs style' multi-keystroke bindings are specified as\n"+
115-
"follows: <Control-x><Control-y> or <Meta-f><Meta-g>.\n\n"+
117+
"<Control-space>, <Meta-less>, <Control-Alt-Shift-X>.\n"
118+
"Upper case is used when the Shift modifier is present!\n\n" +
119+
"'Emacs style' multi-keystroke bindings are specified as\n" +
120+
"follows: <Control-x><Control-y>, where the first key\n" +
121+
"is the 'do-nothing' keybinding.\n\n" +
116122
"Multiple separate bindings for one action should be\n"+
117123
"separated by a space, eg., <Alt-v> <Meta-v>." )
118124
labelHelpAdvanced.grid(row=0,column=0,sticky=NSEW)
@@ -149,20 +155,12 @@ def FinalKeySelected(self,event):
149155
self.BuildKeyString()
150156

151157
def BuildKeyString(self):
152-
keyList=[]
153-
modifiers=self.GetModifiers()
154-
finalKey=self.listKeysFinal.get(ANCHOR)
155-
if modifiers: modifiers[0]='<'+modifiers[0]
156-
keyList=keyList+modifiers
158+
keyList = modifiers = self.GetModifiers()
159+
finalKey = self.listKeysFinal.get(ANCHOR)
157160
if finalKey:
158-
if (not modifiers) and (finalKey not
159-
in self.alphanumKeys+self.punctuationKeys):
160-
finalKey='<'+self.TranslateKey(finalKey)
161-
else:
162-
finalKey=self.TranslateKey(finalKey)
163-
keyList.append(finalKey+'>')
164-
keyStr=string.join(keyList,'-')
165-
self.keyString.set(keyStr)
161+
finalKey = self.TranslateKey(finalKey, modifiers)
162+
keyList.append(finalKey)
163+
self.keyString.set('<' + string.join(keyList,'-') + '>')
166164

167165
def GetModifiers(self):
168166
modList = [variable.get() for variable in self.modifier_vars]
@@ -190,65 +188,67 @@ def LoadFinalKeyList(self):
190188
self.whitespaceKeys+self.editKeys+self.moveKeys)
191189
self.listKeysFinal.insert(END, *keys)
192190

193-
def TranslateKey(self,key):
194-
#translate from key list value to tkinter key-id
195-
translateDict={'~':'asciitilde','!':'exclam','@':'at','#':'numbersign',
191+
def TranslateKey(self, key, modifiers):
192+
"Translate from keycap symbol to the Tkinter keysym"
193+
translateDict = {'Space':'space',
194+
'~':'asciitilde','!':'exclam','@':'at','#':'numbersign',
196195
'%':'percent','^':'asciicircum','&':'ampersand','*':'asterisk',
197196
'(':'parenleft',')':'parenright','_':'underscore','-':'minus',
198197
'+':'plus','=':'equal','{':'braceleft','}':'braceright',
199198
'[':'bracketleft',']':'bracketright','|':'bar',';':'semicolon',
200199
':':'colon',',':'comma','.':'period','<':'less','>':'greater',
201200
'/':'slash','?':'question','Page Up':'Prior','Page Down':'Next',
202201
'Left Arrow':'Left','Right Arrow':'Right','Up Arrow':'Up',
203-
'Down Arrow': 'Down'}
202+
'Down Arrow': 'Down', 'Tab':'tab'}
204203
if key in translateDict.keys():
205-
key=translateDict[key]
206-
key='Key-'+key
204+
key = translateDict[key]
205+
if 'Shift' in modifiers and key in string.ascii_lowercase:
206+
key = key.upper()
207+
key = 'Key-' + key
207208
return key
208209

209-
def Ok(self, event=None):
210-
if self.KeysOk():
210+
def OK(self, event=None):
211+
if self.KeysOK():
211212
self.result=self.keyString.get()
212213
self.destroy()
213214

214215
def Cancel(self, event=None):
215216
self.result=''
216217
self.destroy()
217218

218-
def KeysOk(self):
219-
#simple validity check
220-
keysOk=1
221-
keys=self.keyString.get()
219+
def KeysOK(self):
220+
"Validity check on user's keybinding selection"
221+
keys = self.keyString.get()
222222
keys.strip()
223-
finalKey=self.listKeysFinal.get(ANCHOR)
224-
modifiers=self.GetModifiers()
225-
keySequence=keys.split()#make into a key sequence list for overlap check
226-
if not keys: #no keys specified
227-
tkMessageBox.showerror(title='Key Sequence Error',
228-
message='No keys specified.')
229-
keysOk=0
230-
elif not keys.endswith('>'): #no final key specified
231-
tkMessageBox.showerror(title='Key Sequence Error',
232-
message='No final key specified.')
233-
keysOk=0
234-
elif (not modifiers) and (finalKey in
235-
self.alphanumKeys+self.punctuationKeys):
236-
#modifier required
237-
tkMessageBox.showerror(title='Key Sequence Error',
238-
message='No modifier key(s) specified.')
239-
keysOk=0
240-
elif (modifiers==['Shift']) and (finalKey not
241-
in self.functionKeys+('Tab',)):
242-
#shift alone is only a useful modifier with a function key
243-
tkMessageBox.showerror(title='Key Sequence Error',
244-
message='Shift alone is not a useful modifier '+
245-
'when used with this final key key.')
246-
keysOk=0
247-
elif keySequence in self.currentKeySequences: #keys combo already in use
248-
tkMessageBox.showerror(title='Key Sequence Error',
249-
message='This key combination is already in use.')
250-
keysOk=0
251-
return keysOk
223+
finalKey = self.listKeysFinal.get(ANCHOR)
224+
modifiers = self.GetModifiers()
225+
# create a key sequence list for overlap check:
226+
keySequence = keys.split()
227+
keysOK = False
228+
title = 'Key Sequence Error'
229+
if not keys:
230+
tkMessageBox.showerror(title=title, parent=self,
231+
message='No keys specified.')
232+
elif not keys.endswith('>'):
233+
tkMessageBox.showerror(title=title, parent=self,
234+
message='Missing the final Key')
235+
elif not modifiers and finalKey not in self.functionKeys:
236+
tkMessageBox.showerror(title=title, parent=self,
237+
message='No modifier key(s) specified.')
238+
elif (modifiers == ['Shift']) \
239+
and (finalKey not in
240+
self.functionKeys + ('Tab', 'Space')):
241+
msg = 'The shift modifier by itself may not be used with' \
242+
' this key symbol; only with F1-F12, Tab, or Space'
243+
tkMessageBox.showerror(title=title, parent=self,
244+
message=msg)
245+
elif keySequence in self.currentKeySequences:
246+
msg = 'This key combination is already in use.'
247+
tkMessageBox.showerror(title=title, parent=self,
248+
message=msg)
249+
else:
250+
keysOK = True
251+
return keysOK
252252

253253
if __name__ == '__main__':
254254
#test the dialog

0 commit comments

Comments
 (0)