(self, liststore, path, key, mods, _code)
Handle an edited keybinding
Handle an edited keybinding
Handle an edited keybinding
def on_cellrenderer_accel_edited(self, liststore, path, key, mods, _code):
        """Handle an edited keybinding"""
        # Ignore `Gdk.KEY_Tab` so that `Shift+Tab` is displayed as `Shift+Tab`
        # in `Preferences>Keybindings` and NOT `Left Tab` (see `Gdk.KEY_ISO_Left_Tab`).
        if mods & Gdk.ModifierType.SHIFT_MASK and key != Gdk.KEY_Tab:
            key_with_shift = Gdk.Keymap.translate_keyboard_state(
                self.keybindings.keymap,
                hardware_keycode=_code,
                state=Gdk.ModifierType.SHIFT_MASK,
                group=0,
            )
            keyval_lower, keyval_upper = Gdk.keyval_convert_case(key)

            # Remove the Shift modifier from `mods` if a new key binding doesn't
            # contain a letter and its key value (`key`) can't be modified by a
            # Shift key.
            if key_with_shift.level != 0 and keyval_lower == keyval_upper:
                mods = Gdk.ModifierType(mods & ~Gdk.ModifierType.SHIFT_MASK)
                key = key_with_shift.keyval

        accel = Gtk.accelerator_name(key, mods)
        current_binding = liststore.get_value(liststore.get_iter(path), 0)
        parsed_accel = Gtk.accelerator_parse(accel)

        duplicate_bindings = []
        for conf_binding, conf_accel in self.config["keybindings"].items():
            if conf_accel is None:
                continue

            parsed_conf_accel = Gtk.accelerator_parse(conf_accel)

            if (
                parsed_accel == parsed_conf_accel
                and current_binding != conf_binding
            ):
                duplicate_bindings.append((conf_binding, conf_accel))

        if duplicate_bindings:
            dialog = Gtk.MessageDialog(
                transient_for=self.window,
                flags=Gtk.DialogFlags.MODAL,
                message_type=Gtk.MessageType.ERROR,
                buttons=Gtk.ButtonsType.CLOSE,
                text="Duplicate Key Bindings Are Not Allowed",
            )

            accel_label = Gtk.accelerator_get_label(key, mods)
            # get the first found duplicate
            duplicate_keybinding_name = duplicate_bindings[0][0]

            message = (
                "Key binding `{0}` is already in use to trigger the `{1}` action."
            ).format(accel_label, self.keybindingnames[duplicate_keybinding_name])
            dialog.format_secondary_text(message)

            self.active_message_dialog = dialog
            dialog.run()
            dialog.destroy()
            self.active_message_dialog = None

            return

        celliter = liststore.get_iter_from_string(path)
        liststore.set(celliter, 2, key, 3, mods)

        binding = liststore.get_value(liststore.get_iter(path), 0)
        accel = Gtk.accelerator_name(key, mods)
        self.config['keybindings'][binding] = accel
        self.config.save()
def on_cellrenderer_accel_edited ( self , liststore , path , key , mods , _code ) : # Ignore `Gdk.KEY_Tab` so that `Shift+Tab` is displayed as `Shift+Tab` # in `Preferences>Keybindings` and NOT `Left Tab` (see `Gdk.KEY_ISO_Left_Tab`). if mods & Gdk . ModifierType . SHIFT_MASK and key != Gdk . KEY_Tab : key_with_shift = Gdk . Keymap . translate_keyboard_state ( self . keybindings . keymap , hardware_keycode = _code , state = Gdk . ModifierType . SHIFT_MASK , group = 0 , ) keyval_lower , keyval_upper = Gdk . keyval_convert_case ( key ) # Remove the Shift modifier from `mods` if a new key binding doesn't # contain a letter and its key value (`key`) can't be modified by a # Shift key. if key_with_shift . level != 0 and keyval_lower == keyval_upper : mods = Gdk . ModifierType ( mods & ~ Gdk . ModifierType . SHIFT_MASK ) key = key_with_shift . keyval accel = Gtk . accelerator_name ( key , mods ) current_binding = liststore . get_value ( liststore . get_iter ( path ) , 0 ) parsed_accel = Gtk . accelerator_parse ( accel ) duplicate_bindings = [ ] for conf_binding , conf_accel in self . config [ "keybindings" ] . items ( ) : if conf_accel is None : continue parsed_conf_accel = Gtk . accelerator_parse ( conf_accel ) if ( parsed_accel == parsed_conf_accel and current_binding != conf_binding ) : duplicate_bindings . append ( ( conf_binding , conf_accel ) ) if duplicate_bindings : dialog = Gtk . MessageDialog ( transient_for = self . window , flags = Gtk . DialogFlags . MODAL , message_type = Gtk . MessageType . ERROR , buttons = Gtk . ButtonsType . CLOSE , text = "Duplicate Key Bindings Are Not Allowed" , ) accel_label = Gtk . accelerator_get_label ( key , mods ) # get the first found duplicate duplicate_keybinding_name = duplicate_bindings [ 0 ] [ 0 ] message = ( "Key binding `{0}` is already in use to trigger the `{1}` action." ) . format ( accel_label , self . keybindingnames [ duplicate_keybinding_name ] ) dialog . format_secondary_text ( message ) self . active_message_dialog = dialog dialog . run ( ) dialog . destroy ( ) self . active_message_dialog = None return celliter = liststore . get_iter_from_string ( path ) liststore . set ( celliter , 2 , key , 3 , mods ) binding = liststore . get_value ( liststore . get_iter ( path ) , 0 ) accel = Gtk . accelerator_name ( key , mods ) self . config [ 'keybindings' ] [ binding ] = accel self . config . save ( )