(self)
Return frame of widgets for Keys tab.

        Enable users to provisionally change both individual and sets of
        keybindings (shortcut keys). Except for features implemented as
        extensions, keybindings are stored in complete sets called
        keysets. Built-in keysets in idlelib/config-keys.def are fixed
        as far as the dialog is concerned. Any keyset can be used as the
        base for a new custom keyset, stored in .idlerc/config-keys.cfg.

        Function load_key_cfg() initializes tk variables and keyset
        lists and calls load_keys_list for the current keyset.
        Radiobuttons builtin_keyset_on and custom_keyset_on toggle var
        keyset_source, which controls if the current set of keybindings
        are from a builtin or custom keyset. DynOptionMenus builtinlist
        and customlist contain lists of the builtin and custom keysets,
        respectively, and the current item from each list is stored in
        vars builtin_name and custom_name.

        Button delete_custom_keys invokes delete_custom_keys() to delete
        a custom keyset from idleConf.userCfg['keys'] and changes.  Button
        save_custom_keys invokes save_as_new_key_set() which calls
        get_new_keys_name() and create_new_key_set() to save a custom keyset
        and its keybindings to idleConf.userCfg['keys'].

        Listbox bindingslist contains all of the keybindings for the
        selected keyset.  The keybindings are loaded in load_keys_list()
        and are pairs of (event, [keys]) where keys can be a list
        of one or more key combinations to bind to the same event.
        Mouse button 1 click invokes on_bindingslist_select(), which
        allows button_new_keys to be clicked.

        So, an item is selected in listbindings, which activates
        button_new_keys, and clicking button_new_keys calls function
        get_new_keys().  Function get_new_keys() gets the key mappings from the
        current keyset for the binding event item that was selected.  The
        function then displays another dialog, GetKeysDialog, with the
        selected binding event and current keys and allows new key sequences
        to be entered for that binding event.  If the keys aren't
        changed, nothing happens.  If the keys are changed and the keyset
        is a builtin, function get_new_keys_name() will be called
        for input of a custom keyset name.  If no name is given, then the
        change to the keybinding will abort and no updates will be made.  If
        a custom name is entered in the prompt or if the current keyset was
        already custom (and thus didn't require a prompt), then
        idleConf.userCfg['keys'] is updated in function create_new_key_set()
        with the change to the event binding.  The item listing in bindingslist
        is updated with the new keys.  Var keybinding is also set which invokes
        the callback function, var_changed_keybinding, to add the change to
        the 'keys' or 'extensions' changes tracker based on the binding type.

        Tk Variables:
            keybinding: Action/key bindings.

        Methods:
            load_keys_list: Reload active set.
            create_new_key_set: Combine active keyset and changes.
            set_keys_type: Command for keyset_source.
            save_new_key_set: Save to idleConf.userCfg['keys'] (is function).
            deactivate_current_config: Remove keys bindings in editors.

        Widgets for KeysPage(frame):  (*) widgets bound to self
            frame_key_sets: LabelFrame
                frames[0]: Frame
                    (*)builtin_keyset_on: Radiobutton - var keyset_source
                    (*)custom_keyset_on: Radiobutton - var keyset_source
                    (*)builtinlist: DynOptionMenu - var builtin_name,
                            func keybinding_selected
                    (*)customlist: DynOptionMenu - var custom_name,
                            func keybinding_selected
                    (*)keys_message: Label
                frames[1]: Frame
                    (*)button_delete_custom_keys: Button - delete_custom_keys
                    (*)button_save_custom_keys: Button -  save_as_new_key_set
            frame_custom: LabelFrame
                frame_target: Frame
                    target_title: Label
                    scroll_target_y: Scrollbar
                    scroll_target_x: Scrollbar
                    (*)bindingslist: ListBox - on_bindingslist_select
                    (*)button_new_keys: Button - get_new_keys & ..._name
Return frame of widgets for Keys tab.
Return frame of widgets for Keys tab .
def create_page_keys(self):
        """Return frame of widgets for Keys tab.

        Enable users to provisionally change both individual and sets of
        keybindings (shortcut keys). Except for features implemented as
        extensions, keybindings are stored in complete sets called
        keysets. Built-in keysets in idlelib/config-keys.def are fixed
        as far as the dialog is concerned. Any keyset can be used as the
        base for a new custom keyset, stored in .idlerc/config-keys.cfg.

        Function load_key_cfg() initializes tk variables and keyset
        lists and calls load_keys_list for the current keyset.
        Radiobuttons builtin_keyset_on and custom_keyset_on toggle var
        keyset_source, which controls if the current set of keybindings
        are from a builtin or custom keyset. DynOptionMenus builtinlist
        and customlist contain lists of the builtin and custom keysets,
        respectively, and the current item from each list is stored in
        vars builtin_name and custom_name.

        Button delete_custom_keys invokes delete_custom_keys() to delete
        a custom keyset from idleConf.userCfg['keys'] and changes.  Button
        save_custom_keys invokes save_as_new_key_set() which calls
        get_new_keys_name() and create_new_key_set() to save a custom keyset
        and its keybindings to idleConf.userCfg['keys'].

        Listbox bindingslist contains all of the keybindings for the
        selected keyset.  The keybindings are loaded in load_keys_list()
        and are pairs of (event, [keys]) where keys can be a list
        of one or more key combinations to bind to the same event.
        Mouse button 1 click invokes on_bindingslist_select(), which
        allows button_new_keys to be clicked.

        So, an item is selected in listbindings, which activates
        button_new_keys, and clicking button_new_keys calls function
        get_new_keys().  Function get_new_keys() gets the key mappings from the
        current keyset for the binding event item that was selected.  The
        function then displays another dialog, GetKeysDialog, with the
        selected binding event and current keys and allows new key sequences
        to be entered for that binding event.  If the keys aren't
        changed, nothing happens.  If the keys are changed and the keyset
        is a builtin, function get_new_keys_name() will be called
        for input of a custom keyset name.  If no name is given, then the
        change to the keybinding will abort and no updates will be made.  If
        a custom name is entered in the prompt or if the current keyset was
        already custom (and thus didn't require a prompt), then
        idleConf.userCfg['keys'] is updated in function create_new_key_set()
        with the change to the event binding.  The item listing in bindingslist
        is updated with the new keys.  Var keybinding is also set which invokes
        the callback function, var_changed_keybinding, to add the change to
        the 'keys' or 'extensions' changes tracker based on the binding type.

        Tk Variables:
            keybinding: Action/key bindings.

        Methods:
            load_keys_list: Reload active set.
            create_new_key_set: Combine active keyset and changes.
            set_keys_type: Command for keyset_source.
            save_new_key_set: Save to idleConf.userCfg['keys'] (is function).
            deactivate_current_config: Remove keys bindings in editors.

        Widgets for KeysPage(frame):  (*) widgets bound to self
            frame_key_sets: LabelFrame
                frames[0]: Frame
                    (*)builtin_keyset_on: Radiobutton - var keyset_source
                    (*)custom_keyset_on: Radiobutton - var keyset_source
                    (*)builtinlist: DynOptionMenu - var builtin_name,
                            func keybinding_selected
                    (*)customlist: DynOptionMenu - var custom_name,
                            func keybinding_selected
                    (*)keys_message: Label
                frames[1]: Frame
                    (*)button_delete_custom_keys: Button - delete_custom_keys
                    (*)button_save_custom_keys: Button -  save_as_new_key_set
            frame_custom: LabelFrame
                frame_target: Frame
                    target_title: Label
                    scroll_target_y: Scrollbar
                    scroll_target_x: Scrollbar
                    (*)bindingslist: ListBox - on_bindingslist_select
                    (*)button_new_keys: Button - get_new_keys & ..._name
        """
        self.builtin_name = tracers.add(
                StringVar(self), self.var_changed_builtin_name)
        self.custom_name = tracers.add(
                StringVar(self), self.var_changed_custom_name)
        self.keyset_source = tracers.add(
                BooleanVar(self), self.var_changed_keyset_source)
        self.keybinding = tracers.add(
                StringVar(self), self.var_changed_keybinding)

        # Create widgets:
        # body and section frames.
        frame_custom = LabelFrame(
                self, borderwidth=2, relief=GROOVE,
                text=' Custom Key Bindings ')
        frame_key_sets = LabelFrame(
                self, borderwidth=2, relief=GROOVE, text=' Key Set ')
        # frame_custom.
        frame_target = Frame(frame_custom)
        target_title = Label(frame_target, text='Action - Key(s)')
        scroll_target_y = Scrollbar(frame_target)
        scroll_target_x = Scrollbar(frame_target, orient=HORIZONTAL)
        self.bindingslist = Listbox(
                frame_target, takefocus=FALSE, exportselection=FALSE)
        self.bindingslist.bind('<ButtonRelease-1>',
                               self.on_bindingslist_select)
        scroll_target_y['command'] = self.bindingslist.yview
        scroll_target_x['command'] = self.bindingslist.xview
        self.bindingslist['yscrollcommand'] = scroll_target_y.set
        self.bindingslist['xscrollcommand'] = scroll_target_x.set
        self.button_new_keys = Button(
                frame_custom, text='Get New Keys for Selection',
                command=self.get_new_keys, state='disabled')
        # frame_key_sets.
        frames = [Frame(frame_key_sets, padding=2, borderwidth=0)
                  for i in range(2)]
        self.builtin_keyset_on = Radiobutton(
                frames[0], variable=self.keyset_source, value=1,
                command=self.set_keys_type, text='Use a Built-in Key Set')
        self.custom_keyset_on = Radiobutton(
                frames[0], variable=self.keyset_source, value=0,
                command=self.set_keys_type, text='Use a Custom Key Set')
        self.builtinlist = DynOptionMenu(
                frames[0], self.builtin_name, None, command=None)
        self.customlist = DynOptionMenu(
                frames[0], self.custom_name, None, command=None)
        self.button_delete_custom_keys = Button(
                frames[1], text='Delete Custom Key Set',
                command=self.delete_custom_keys)
        self.button_save_custom_keys = Button(
                frames[1], text='Save as New Custom Key Set',
                command=self.save_as_new_key_set)
        self.keys_message = Label(frames[0], borderwidth=2)

        # Pack widgets:
        # body.
        frame_custom.pack(side=BOTTOM, padx=5, pady=5, expand=TRUE, fill=BOTH)
        frame_key_sets.pack(side=BOTTOM, padx=5, pady=5, fill=BOTH)
        # frame_custom.
        self.button_new_keys.pack(side=BOTTOM, fill=X, padx=5, pady=5)
        frame_target.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH)
        # frame_target.
        frame_target.columnconfigure(0, weight=1)
        frame_target.rowconfigure(1, weight=1)
        target_title.grid(row=0, column=0, columnspan=2, sticky=W)
        self.bindingslist.grid(row=1, column=0, sticky=NSEW)
        scroll_target_y.grid(row=1, column=1, sticky=NS)
        scroll_target_x.grid(row=2, column=0, sticky=EW)
        # frame_key_sets.
        self.builtin_keyset_on.grid(row=0, column=0, sticky=W+NS)
        self.custom_keyset_on.grid(row=1, column=0, sticky=W+NS)
        self.builtinlist.grid(row=0, column=1, sticky=NSEW)
        self.customlist.grid(row=1, column=1, sticky=NSEW)
        self.keys_message.grid(row=0, column=2, sticky=NSEW, padx=5, pady=5)
        self.button_delete_custom_keys.pack(side=LEFT, fill=X, expand=True, padx=2)
        self.button_save_custom_keys.pack(side=LEFT, fill=X, expand=True, padx=2)
        frames[0].pack(side=TOP, fill=BOTH, expand=True)
        frames[1].pack(side=TOP, fill=X, expand=True, pady=2)
def create_page_keys ( self ) : self . builtin_name = tracers . add ( StringVar ( self ) , self . var_changed_builtin_name ) self . custom_name = tracers . add ( StringVar ( self ) , self . var_changed_custom_name ) self . keyset_source = tracers . add ( BooleanVar ( self ) , self . var_changed_keyset_source ) self . keybinding = tracers . add ( StringVar ( self ) , self . var_changed_keybinding ) # Create widgets: # body and section frames. frame_custom = LabelFrame ( self , borderwidth = 2 , relief = GROOVE , text = ' Custom Key Bindings ' ) frame_key_sets = LabelFrame ( self , borderwidth = 2 , relief = GROOVE , text = ' Key Set ' ) # frame_custom. frame_target = Frame ( frame_custom ) target_title = Label ( frame_target , text = 'Action - Key(s)' ) scroll_target_y = Scrollbar ( frame_target ) scroll_target_x = Scrollbar ( frame_target , orient = HORIZONTAL ) self . bindingslist = Listbox ( frame_target , takefocus = FALSE , exportselection = FALSE ) self . bindingslist . bind ( '<ButtonRelease-1>' , self . on_bindingslist_select ) scroll_target_y [ 'command' ] = self . bindingslist . yview scroll_target_x [ 'command' ] = self . bindingslist . xview self . bindingslist [ 'yscrollcommand' ] = scroll_target_y . set self . bindingslist [ 'xscrollcommand' ] = scroll_target_x . set self . button_new_keys = Button ( frame_custom , text = 'Get New Keys for Selection' , command = self . get_new_keys , state = 'disabled' ) # frame_key_sets. frames = [ Frame ( frame_key_sets , padding = 2 , borderwidth = 0 ) for i in range ( 2 ) ] self . builtin_keyset_on = Radiobutton ( frames [ 0 ] , variable = self . keyset_source , value = 1 , command = self . set_keys_type , text = 'Use a Built-in Key Set' ) self . custom_keyset_on = Radiobutton ( frames [ 0 ] , variable = self . keyset_source , value = 0 , command = self . set_keys_type , text = 'Use a Custom Key Set' ) self . builtinlist = DynOptionMenu ( frames [ 0 ] , self . builtin_name , None , command = None ) self . customlist = DynOptionMenu ( frames [ 0 ] , self . custom_name , None , command = None ) self . button_delete_custom_keys = Button ( frames [ 1 ] , text = 'Delete Custom Key Set' , command = self . delete_custom_keys ) self . button_save_custom_keys = Button ( frames [ 1 ] , text = 'Save as New Custom Key Set' , command = self . save_as_new_key_set ) self . keys_message = Label ( frames [ 0 ] , borderwidth = 2 ) # Pack widgets: # body. frame_custom . pack ( side = BOTTOM , padx = 5 , pady = 5 , expand = TRUE , fill = BOTH ) frame_key_sets . pack ( side = BOTTOM , padx = 5 , pady = 5 , fill = BOTH ) # frame_custom. self . button_new_keys . pack ( side = BOTTOM , fill = X , padx = 5 , pady = 5 ) frame_target . pack ( side = LEFT , padx = 5 , pady = 5 , expand = TRUE , fill = BOTH ) # frame_target. frame_target . columnconfigure ( 0 , weight = 1 ) frame_target . rowconfigure ( 1 , weight = 1 ) target_title . grid ( row = 0 , column = 0 , columnspan = 2 , sticky = W ) self . bindingslist . grid ( row = 1 , column = 0 , sticky = NSEW ) scroll_target_y . grid ( row = 1 , column = 1 , sticky = NS ) scroll_target_x . grid ( row = 2 , column = 0 , sticky = EW ) # frame_key_sets. self . builtin_keyset_on . grid ( row = 0 , column = 0 , sticky = W + NS ) self . custom_keyset_on . grid ( row = 1 , column = 0 , sticky = W + NS ) self . builtinlist . grid ( row = 0 , column = 1 , sticky = NSEW ) self . customlist . grid ( row = 1 , column = 1 , sticky = NSEW ) self . keys_message . grid ( row = 0 , column = 2 , sticky = NSEW , padx = 5 , pady = 5 ) self . button_delete_custom_keys . pack ( side = LEFT , fill = X , expand = True , padx = 2 ) self . button_save_custom_keys . pack ( side = LEFT , fill = X , expand = True , padx = 2 ) frames [ 0 ] . pack ( side = TOP , fill = BOTH , expand = True ) frames [ 1 ] . pack ( side = TOP , fill = X , expand = True , pady = 2 )