1ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot""" 2ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotDialog for building Tkinter accelerator key bindings 3ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot""" 4ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotfrom Tkinter import * 5ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotimport tkMessageBox 6ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotimport string 7ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 8ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass GetKeysDialog(Toplevel): 9ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def __init__(self,parent,title,action,currentKeySequences): 10ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot """ 11ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot action - string, the name of the virtual event these keys will be 12ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot mapped to 13ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot currentKeys - list, a list of all key sequence lists currently mapped 14ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot to virtual events, for overlap checking 15ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot """ 16ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot Toplevel.__init__(self, parent) 17ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.configure(borderwidth=5) 18ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.resizable(height=FALSE,width=FALSE) 19ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.title(title) 20ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.transient(parent) 21ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.grab_set() 22ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.protocol("WM_DELETE_WINDOW", self.Cancel) 23ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.parent = parent 24ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.action=action 25ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.currentKeySequences=currentKeySequences 26ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.result='' 27ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.keyString=StringVar(self) 28ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.keyString.set('') 29ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.SetModifiersForPlatform() # set self.modifiers, self.modifier_label 30ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.modifier_vars = [] 31ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot for modifier in self.modifiers: 32ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot variable = StringVar(self) 33ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot variable.set('') 34ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.modifier_vars.append(variable) 35ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.advanced = False 36ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.CreateWidgets() 37ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.LoadFinalKeyList() 38ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.withdraw() #hide while setting geometry 39ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.update_idletasks() 40ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.geometry("+%d+%d" % 41ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ((parent.winfo_rootx()+((parent.winfo_width()/2) 42ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot -(self.winfo_reqwidth()/2)), 43ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot parent.winfo_rooty()+((parent.winfo_height()/2) 44ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot -(self.winfo_reqheight()/2)) )) ) #centre dialog over parent 45ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.deiconify() #geometry set, unhide 46ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.wait_window() 47ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 48ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def CreateWidgets(self): 49ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot frameMain = Frame(self,borderwidth=2,relief=SUNKEN) 50ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot frameMain.pack(side=TOP,expand=TRUE,fill=BOTH) 51ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot frameButtons=Frame(self) 52ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot frameButtons.pack(side=BOTTOM,fill=X) 53ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.buttonOK = Button(frameButtons,text='OK', 54ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot width=8,command=self.OK) 55ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.buttonOK.grid(row=0,column=0,padx=5,pady=5) 56ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.buttonCancel = Button(frameButtons,text='Cancel', 57ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot width=8,command=self.Cancel) 58ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.buttonCancel.grid(row=0,column=1,padx=5,pady=5) 59ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.frameKeySeqBasic = Frame(frameMain) 60ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.frameKeySeqAdvanced = Frame(frameMain) 61ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.frameControlsBasic = Frame(frameMain) 62ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.frameHelpAdvanced = Frame(frameMain) 63ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.frameKeySeqAdvanced.grid(row=0,column=0,sticky=NSEW,padx=5,pady=5) 64ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.frameKeySeqBasic.grid(row=0,column=0,sticky=NSEW,padx=5,pady=5) 65ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.frameKeySeqBasic.lift() 66ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.frameHelpAdvanced.grid(row=1,column=0,sticky=NSEW,padx=5) 67ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.frameControlsBasic.grid(row=1,column=0,sticky=NSEW,padx=5) 68ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.frameControlsBasic.lift() 69ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.buttonLevel = Button(frameMain,command=self.ToggleLevel, 70ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text='Advanced Key Binding Entry >>') 71ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.buttonLevel.grid(row=2,column=0,stick=EW,padx=5,pady=5) 72ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot labelTitleBasic = Label(self.frameKeySeqBasic, 73ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text="New keys for '"+self.action+"' :") 74ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot labelTitleBasic.pack(anchor=W) 75ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot labelKeysBasic = Label(self.frameKeySeqBasic,justify=LEFT, 76ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot textvariable=self.keyString,relief=GROOVE,borderwidth=2) 77ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot labelKeysBasic.pack(ipadx=5,ipady=5,fill=X) 78ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.modifier_checkbuttons = {} 79ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot column = 0 80ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot for modifier, variable in zip(self.modifiers, self.modifier_vars): 81ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot label = self.modifier_label.get(modifier, modifier) 82ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot check=Checkbutton(self.frameControlsBasic, 83ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot command=self.BuildKeyString, 84ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text=label,variable=variable,onvalue=modifier,offvalue='') 85ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot check.grid(row=0,column=column,padx=2,sticky=W) 86ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.modifier_checkbuttons[modifier] = check 87ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot column += 1 88ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot labelFnAdvice=Label(self.frameControlsBasic,justify=LEFT, 89ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text=\ 90ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "Select the desired modifier keys\n"+ 91ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "above, and the final key from the\n"+ 92ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "list on the right.\n\n" + 93ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "Use upper case Symbols when using\n" + 94ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "the Shift modifier. (Letters will be\n" + 95ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "converted automatically.)") 96ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot labelFnAdvice.grid(row=1,column=0,columnspan=4,padx=2,sticky=W) 97ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.listKeysFinal=Listbox(self.frameControlsBasic,width=15,height=10, 98ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot selectmode=SINGLE) 99ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.listKeysFinal.bind('<ButtonRelease-1>',self.FinalKeySelected) 100ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.listKeysFinal.grid(row=0,column=4,rowspan=4,sticky=NS) 101ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot scrollKeysFinal=Scrollbar(self.frameControlsBasic,orient=VERTICAL, 102ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot command=self.listKeysFinal.yview) 103ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.listKeysFinal.config(yscrollcommand=scrollKeysFinal.set) 104ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot scrollKeysFinal.grid(row=0,column=5,rowspan=4,sticky=NS) 105ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.buttonClear=Button(self.frameControlsBasic, 106ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text='Clear Keys',command=self.ClearKeySeq) 107ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.buttonClear.grid(row=2,column=0,columnspan=4) 108ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot labelTitleAdvanced = Label(self.frameKeySeqAdvanced,justify=LEFT, 109ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text="Enter new binding(s) for '"+self.action+"' :\n"+ 110ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "(These bindings will not be checked for validity!)") 111ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot labelTitleAdvanced.pack(anchor=W) 112ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.entryKeysAdvanced=Entry(self.frameKeySeqAdvanced, 113ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot textvariable=self.keyString) 114ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.entryKeysAdvanced.pack(fill=X) 115ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot labelHelpAdvanced=Label(self.frameHelpAdvanced,justify=LEFT, 116ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot text="Key bindings are specified using Tkinter keysyms as\n"+ 117ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "in these samples: <Control-f>, <Shift-F2>, <F12>,\n" 118ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "<Control-space>, <Meta-less>, <Control-Alt-Shift-X>.\n" 119ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "Upper case is used when the Shift modifier is present!\n\n" + 120ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "'Emacs style' multi-keystroke bindings are specified as\n" + 121ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "follows: <Control-x><Control-y>, where the first key\n" + 122ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "is the 'do-nothing' keybinding.\n\n" + 123ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "Multiple separate bindings for one action should be\n"+ 124ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "separated by a space, eg., <Alt-v> <Meta-v>." ) 125ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot labelHelpAdvanced.grid(row=0,column=0,sticky=NSEW) 126ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 127ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def SetModifiersForPlatform(self): 128ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot """Determine list of names of key modifiers for this platform. 129ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 130ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot The names are used to build Tk bindings -- it doesn't matter if the 131ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot keyboard has these keys, it matters if Tk understands them. The 132ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot order is also important: key binding equality depends on it, so 133ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot config-keys.def must use the same ordering. 134ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot """ 135ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot from idlelib import macosxSupport 136ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if macosxSupport.runningAsOSXApp(): 137ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.modifiers = ['Shift', 'Control', 'Option', 'Command'] 138ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot else: 139ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.modifiers = ['Control', 'Alt', 'Shift'] 140ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.modifier_label = {'Control': 'Ctrl'} # short name 141ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 142ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def ToggleLevel(self): 143ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if self.buttonLevel.cget('text')[:8]=='Advanced': 144ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.ClearKeySeq() 145ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.buttonLevel.config(text='<< Basic Key Binding Entry') 146ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.frameKeySeqAdvanced.lift() 147ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.frameHelpAdvanced.lift() 148ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.entryKeysAdvanced.focus_set() 149ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.advanced = True 150ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot else: 151ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.ClearKeySeq() 152ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.buttonLevel.config(text='Advanced Key Binding Entry >>') 153ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.frameKeySeqBasic.lift() 154ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.frameControlsBasic.lift() 155ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.advanced = False 156ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 157ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def FinalKeySelected(self,event): 158ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.BuildKeyString() 159ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 160ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def BuildKeyString(self): 161ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot keyList = modifiers = self.GetModifiers() 162ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot finalKey = self.listKeysFinal.get(ANCHOR) 163ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if finalKey: 164ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot finalKey = self.TranslateKey(finalKey, modifiers) 165ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot keyList.append(finalKey) 166ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.keyString.set('<' + string.join(keyList,'-') + '>') 167ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 168ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def GetModifiers(self): 169ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot modList = [variable.get() for variable in self.modifier_vars] 170ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return [mod for mod in modList if mod] 171ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 172ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def ClearKeySeq(self): 173ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.listKeysFinal.select_clear(0,END) 174ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.listKeysFinal.yview(MOVETO, '0.0') 175ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot for variable in self.modifier_vars: 176ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot variable.set('') 177ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.keyString.set('') 178ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 179ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def LoadFinalKeyList(self): 180ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot #these tuples are also available for use in validity checks 181ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.functionKeys=('F1','F2','F2','F4','F5','F6','F7','F8','F9', 182ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 'F10','F11','F12') 183ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.alphanumKeys=tuple(string.ascii_lowercase+string.digits) 184ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.punctuationKeys=tuple('~!@#%^&*()_-+={}[]|;:,.<>/?') 185ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.whitespaceKeys=('Tab','Space','Return') 186ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.editKeys=('BackSpace','Delete','Insert') 187ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.moveKeys=('Home','End','Page Up','Page Down','Left Arrow', 188ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 'Right Arrow','Up Arrow','Down Arrow') 189ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot #make a tuple of most of the useful common 'final' keys 190ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot keys=(self.alphanumKeys+self.punctuationKeys+self.functionKeys+ 191ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.whitespaceKeys+self.editKeys+self.moveKeys) 192ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.listKeysFinal.insert(END, *keys) 193ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 194ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def TranslateKey(self, key, modifiers): 195ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot "Translate from keycap symbol to the Tkinter keysym" 196ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot translateDict = {'Space':'space', 197ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '~':'asciitilde','!':'exclam','@':'at','#':'numbersign', 198ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '%':'percent','^':'asciicircum','&':'ampersand','*':'asterisk', 199ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '(':'parenleft',')':'parenright','_':'underscore','-':'minus', 200ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '+':'plus','=':'equal','{':'braceleft','}':'braceright', 201ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '[':'bracketleft',']':'bracketright','|':'bar',';':'semicolon', 202ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ':':'colon',',':'comma','.':'period','<':'less','>':'greater', 203ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '/':'slash','?':'question','Page Up':'Prior','Page Down':'Next', 204ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 'Left Arrow':'Left','Right Arrow':'Right','Up Arrow':'Up', 205ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 'Down Arrow': 'Down', 'Tab':'Tab'} 206ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if key in translateDict.keys(): 207ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot key = translateDict[key] 208ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if 'Shift' in modifiers and key in string.ascii_lowercase: 209ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot key = key.upper() 210ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot key = 'Key-' + key 211ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return key 212ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 213ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def OK(self, event=None): 214ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if self.advanced or self.KeysOK(): # doesn't check advanced string yet 215ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.result=self.keyString.get() 216ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.destroy() 217ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 218ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def Cancel(self, event=None): 219ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.result='' 220ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.destroy() 221ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 222ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def KeysOK(self): 223ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot '''Validity check on user's 'basic' keybinding selection. 224ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 225ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot Doesn't check the string produced by the advanced dialog because 226ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 'modifiers' isn't set. 227ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 228ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ''' 229ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot keys = self.keyString.get() 230ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot keys.strip() 231ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot finalKey = self.listKeysFinal.get(ANCHOR) 232ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot modifiers = self.GetModifiers() 233ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot # create a key sequence list for overlap check: 234ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot keySequence = keys.split() 235ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot keysOK = False 236ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot title = 'Key Sequence Error' 237ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot if not keys: 238ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot tkMessageBox.showerror(title=title, parent=self, 239ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot message='No keys specified.') 240ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot elif not keys.endswith('>'): 241ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot tkMessageBox.showerror(title=title, parent=self, 242ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot message='Missing the final Key') 243ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot elif (not modifiers 244ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot and finalKey not in self.functionKeys + self.moveKeys): 245ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot tkMessageBox.showerror(title=title, parent=self, 246ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot message='No modifier key(s) specified.') 247ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot elif (modifiers == ['Shift']) \ 248ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot and (finalKey not in 249ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot self.functionKeys + self.moveKeys + ('Tab', 'Space')): 250ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot msg = 'The shift modifier by itself may not be used with'\ 251ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot ' this key symbol.' 252ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot tkMessageBox.showerror(title=title, parent=self, message=msg) 253ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot elif keySequence in self.currentKeySequences: 254ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot msg = 'This key combination is already in use.' 255ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot tkMessageBox.showerror(title=title, parent=self, message=msg) 256ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot else: 257ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot keysOK = True 258ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot return keysOK 259ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot 260ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotif __name__ == '__main__': 261ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot #test the dialog 262ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot root=Tk() 263ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot def run(): 264ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot keySeq='' 265ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot dlg=GetKeysDialog(root,'Get Keys','find-again',[]) 266ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot print dlg.result 267ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot Button(root,text='Dialog',command=run).pack() 268ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot root.mainloop() 269