commit 1dedd398649679b99e8983b937500e56d5ef4b73
Author: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date:   Wed Jul 27 11:52:50 2022 +0200

    Allow to unbind without specifying the lfun
    
    When unbinding a shortcut, it may happen that the exact definition of
    the request is not known. A typical example it Tab, which is bound to
    a complex command sequence.
    
    In this case it is convenient to use the syntax
    \unbind "Tab" "*"
    
    To make this word, the special "*" value is translated to the
    FuncRequest::unknown lfun and this value is considered specially in
    several places.
---
 src/KeyMap.cpp                |   52 ++++++++++++++++++++++-------------------
 src/frontends/qt/GuiPrefs.cpp |   10 ++++----
 2 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/src/KeyMap.cpp b/src/KeyMap.cpp
index f469da5..b4a87d2 100644
--- a/src/KeyMap.cpp
+++ b/src/KeyMap.cpp
@@ -160,29 +160,30 @@ void KeyMap::unbind(KeySequence * seq, FuncRequest const 
& func, unsigned int r)
        KeyModifier const mod2 = seq->modifiers[r].second;
 
        // check if key is already there
+       vector <Table::iterator> removes;
        Table::iterator end = table.end();
-       Table::iterator remove = end;
        for (Table::iterator it = table.begin(); it != end; ++it) {
                if (code == it->code
                    && mod1 == it->mod.first
                    && mod2 == it->mod.second) {
                        // remove
                        if (r + 1 == seq->length()) {
-                               if (it->func == func) {
-                                       remove = it;
+                               if (it->func == func || func == 
FuncRequest::unknown) {
+                                       removes.push_back(it);
                                        if (it->prefixes)
                                                it->prefixes.reset();
                                }
                        } else if (it->prefixes) {
                                it->prefixes->unbind(seq, func, r + 1);
                                if (it->prefixes->empty())
-                                       remove = it;
+                                       removes.push_back(it);
                                return;
                        }
                }
        }
-       if (remove != end)
-               table.erase(remove);
+
+       for (unsigned i = removes.size(); i > 0; --i)
+               table.erase(removes[i-1]);
 }
 
 
@@ -333,7 +334,7 @@ KeyMap::ReturnValues KeyMap::readWithoutConv(FileName const 
& bind_file, KeyMap
                        string cmd = lexrc.getString();
 
                        FuncRequest func = lyxaction.lookupFunc(cmd);
-                       if (func.action() == LFUN_UNKNOWN_ACTION) {
+                       if (func == FuncRequest::unknown) {
                                lexrc.printError("BN_BIND: Unknown LyX function 
`$$Token'");
                                error = true;
                                break;
@@ -357,13 +358,16 @@ KeyMap::ReturnValues KeyMap::readWithoutConv(FileName 
const & bind_file, KeyMap
                                break;
                        }
                        string cmd = lexrc.getString();
-
-                       FuncRequest func = lyxaction.lookupFunc(cmd);
-                       if (func.action() == LFUN_UNKNOWN_ACTION) {
-                               lexrc.printError("BN_UNBIND: Unknown LyX"
-                                                " function `$$Token'");
-                               error = true;
-                               break;
+                       FuncRequest func;
+                       if (cmd == "*")
+                               func = FuncRequest::unknown;
+                       else {
+                               func = lyxaction.lookupFunc(cmd);
+                               if (func == FuncRequest::unknown) {
+                                       lexrc.printError("BN_UNBIND: Unknown 
LyX function `$$Token'");
+                                       error = true;
+                                       break;
+                               }
                        }
 
                        if (unbind_map)
@@ -409,17 +413,17 @@ void KeyMap::write(string const & bind_file, bool append, 
bool unbind) const
                   << "Format " << LFUN_FORMAT << "\n\n";
 
        string tag = unbind ? "\\unbind" : "\\bind";
-       BindingList const list = listBindings(false);
-       BindingList::const_iterator it = list.begin();
-       BindingList::const_iterator it_end = list.end();
-       for (; it != it_end; ++it) {
-               FuncCode action = it->request.action();
-               string arg = to_utf8(it->request.argument());
-
-               string const cmd = lyxaction.getActionName(action)
-                       + (arg.empty() ? string() : " " + arg) ;
+       for (auto const & bnd : listBindings(false)) {
+               FuncCode const action = bnd.request.action();
+               string const arg = to_utf8(bnd.request.argument());
+
+               string cmd;
+               if (unbind && bnd.request == FuncRequest::unknown)
+                       cmd = "*";
+               else
+                       cmd = lyxaction.getActionName(action) + (arg.empty() ? 
string() : " " + arg);
                os << tag << " \""
-                  << to_utf8(it->sequence.print(KeySequence::BindFile))
+                  << to_utf8(bnd.sequence.print(KeySequence::BindFile))
                   << "\" " << Lexer::quoteString(cmd)
                   << "\n";
        }
diff --git a/src/frontends/qt/GuiPrefs.cpp b/src/frontends/qt/GuiPrefs.cpp
index 2b6b9cd..31da129 100644
--- a/src/frontends/qt/GuiPrefs.cpp
+++ b/src/frontends/qt/GuiPrefs.cpp
@@ -3087,10 +3087,10 @@ QTreeWidgetItem * 
PrefShortcuts::insertShortcutItem(FuncRequest const & lfun,
        QTreeWidgetItem * newItem = nullptr;
        // for unbind items, try to find an existing item in the system bind 
list
        if (tag == KeyMap::UserUnbind) {
-               QList<QTreeWidgetItem*> const items = 
shortcutsTW->findItems(lfun_name,
-                       Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 
0);
+               QList<QTreeWidgetItem*> const items = 
shortcutsTW->findItems(shortcut,
+                       Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive), 
1);
                for (auto const & item : items) {
-                       if (item->text(1) == shortcut) {
+                       if (item->text(0) == lfun_name || lfun == 
FuncRequest::unknown) {
                                newItem = item;
                                break;
                        }
@@ -3125,10 +3125,10 @@ QTreeWidgetItem * 
PrefShortcuts::insertShortcutItem(FuncRequest const & lfun,
                        // this should not happen
                        newItem = new QTreeWidgetItem(shortcutsTW);
                }
+               newItem->setText(0, lfun_name);
+               newItem->setText(1, shortcut);
        }
 
-       newItem->setText(0, lfun_name);
-       newItem->setText(1, shortcut);
        // record BindFile representation to recover KeySequence when needed.
        newItem->setData(1, Qt::UserRole, 
toqstr(seq.print(KeySequence::BindFile)));
        setItemType(newItem, tag);
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to