From c8c589353ade8d8b82248e8adf79ea2feb43b454 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Fri, 9 Dec 2022 14:45:14 +0100 Subject: [PATCH] Detect when one tries to bind a lfun to a prefix of longer commands Change KeyMap::getBinding to return FuncRequest::prefix in this case. Add handling of this case in PrefShortcuts::validateNewShortcut. What does not seem to work is that if, for example, accent-acute is bound to M-s (which is a prefix for size-related bindings), and then the binding is removed, the functions are not visibly restored. Part of bug #10131. --- src/KeyMap.cpp | 2 +- src/KeyMap.h | 5 +++-- src/frontends/qt/GuiPrefs.cpp | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/KeyMap.cpp b/src/KeyMap.cpp index c530f5f1f2..c34fe7eefb 100644 --- a/src/KeyMap.cpp +++ b/src/KeyMap.cpp @@ -203,7 +203,7 @@ FuncRequest KeyMap::getBinding(KeySequence const & seq, unsigned int r) && mod1 == it->mod.first && mod2 == it->mod.second) { if (r + 1 == seq.length()) - return it->func; + return (it->prefixes) ? FuncRequest::prefix : it->func; else if (it->prefixes) return it->prefixes->getBinding(seq, r + 1); } diff --git a/src/KeyMap.h b/src/KeyMap.h index 9386c1fee4..ac9de6298b 100644 --- a/src/KeyMap.h +++ b/src/KeyMap.h @@ -65,8 +65,9 @@ public: unsigned int r = 0); - /// returns the function bound to this key sequence, or - /// FuncRequest::unknown if no binding exists for it. + /// returns the function bound to this key sequence, or: + /// * FuncRequest::unknown if no binding exists for it; + /// * FuncRequest::prefix if this is the start of longer keysequences /// @param r an internal recursion counter // FIXME Surely there's a better way to do that? FuncRequest getBinding(KeySequence const & seq, unsigned int r = 0); diff --git a/src/frontends/qt/GuiPrefs.cpp b/src/frontends/qt/GuiPrefs.cpp index a2ac0c83eb..a5f4014874 100644 --- a/src/frontends/qt/GuiPrefs.cpp +++ b/src/frontends/qt/GuiPrefs.cpp @@ -3408,6 +3408,23 @@ bool PrefShortcuts::validateNewShortcut(FuncRequest const & func, // nothing to change return false; + // Check whether the key sequence is a prefix for other shortcuts. + if (oldBinding == FuncRequest::prefix) { + docstring const new_action_string = makeCmdString(func); + docstring const text = bformat(_("Shortcut `%1$s' is already a prefix for other commands.\n" + "Are you sure you want to unbind these commands and bind it to %2$s?"), + k.print(KeySequence::ForGui), new_action_string); + int ret = Alert::prompt(_("Redefine shortcut?"), + text, 0, 1, _("&Redefine"), _("&Cancel")); + if (ret != 0) + return false; + QString const sequence_text = toqstr(k.print(KeySequence::ForGui)); + QList items = shortcutsTW->findItems(sequence_text, + Qt::MatchFlags(Qt::MatchStartsWith | Qt::MatchRecursive), 1); + deactivateShortcuts(items); + return true; + } + // make sure this key isn't already bound---and, if so, prompt user // (exclude the lfun the user already wants to modify) docstring const action_string = makeCmdString(oldBinding);