[LyX/master] Detect when one tries to bind a lfun to a prefix of longer commands

Jean-Marc Lasgouttes lasgouttes at lyx.org
Fri Jul 21 20:51:03 UTC 2023


commit c8c589353ade8d8b82248e8adf79ea2feb43b454
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date:   Fri Dec 9 14:45:14 2022 +0100

    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 c530f5f..c34fe7e 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 9386c1f..ac9de62 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 a2ac0c8..a5f4014 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<QTreeWidgetItem*> 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);


More information about the lyx-cvs mailing list