From ab5415844758da415df4048c923a95a1f1be4a26 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Mon, 16 May 2022 22:16:53 +0200 Subject: [PATCH] Honor key bindings for commit string When the commit string from the inputMethodEvent can be interpreted as characters bound to some action, dispatch this action instead of inserting the string. This is useful on an international keyboard, when diaresis+space gives a plain double quote. It is better in this case to enter a smart quote. Adapted from a patch from Daniel Ramoeller . Fixes bug #10377. --- src/frontends/KeySymbol.h | 3 +++ src/frontends/qt/GuiKeySymbol.cpp | 8 ++++++++ src/frontends/qt/GuiWorkArea.cpp | 24 +++++++++++++++++++----- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/frontends/KeySymbol.h b/src/frontends/KeySymbol.h index cdb5f8f3a1..7e67536aa5 100644 --- a/src/frontends/KeySymbol.h +++ b/src/frontends/KeySymbol.h @@ -33,6 +33,9 @@ public: /// Initialize with the name of a key. F. ex. "space" or "a" void init(std::string const & symbolname); + /// Initialize with some platform specific sym value + void init(int key); + /// Is this a valid key? bool isOK() const; diff --git a/src/frontends/qt/GuiKeySymbol.cpp b/src/frontends/qt/GuiKeySymbol.cpp index 77e3dc35d0..551ea8dc6d 100644 --- a/src/frontends/qt/GuiKeySymbol.cpp +++ b/src/frontends/qt/GuiKeySymbol.cpp @@ -752,6 +752,14 @@ void KeySymbol::init(string const & symbolname) } +void KeySymbol::init(int key) +{ + key_ = key; + text_ = from_utf8(qkey_to_string(key)); + LYXERR(Debug::KEY, "Init key to " << key_ << ", " << to_utf8(text_)); +} + + bool KeySymbol::isOK() const { bool const ok = !(text_.empty() && qkey_to_string(key_).empty()); diff --git a/src/frontends/qt/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp index e70563bc5a..900273f038 100644 --- a/src/frontends/qt/GuiWorkArea.cpp +++ b/src/frontends/qt/GuiWorkArea.cpp @@ -31,7 +31,9 @@ #include "Cursor.h" #include "Font.h" #include "FuncRequest.h" +#include "KeyMap.h" #include "KeySymbol.h" +#include "KeySequence.h" #include "LyX.h" #include "LyXRC.h" #include "LyXVC.h" @@ -47,7 +49,6 @@ #include "frontends/Application.h" #include "frontends/CaretGeometry.h" - #include "frontends/FontMetrics.h" #include "frontends/WorkAreaManager.h" @@ -1313,11 +1314,24 @@ void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e) LYXERR(Debug::KEY, "preeditString: " << e->preeditString() << " commitString: " << e->commitString()); - // insert the processed text in the document (handles undo) if (!e->commitString().isEmpty()) { - FuncRequest cmd(LFUN_SELF_INSERT, - qstring_to_ucs4(e->commitString()), - FuncRequest::KEYBOARD); + FuncRequest cmd; + // take care of commit string assigned to a shortcut + // e.g. quotation mark on international keyboard + KeySequence keyseq; + for (QChar const & ch : e->commitString()) { + KeySymbol keysym; + keysym.init(ch.unicode()); + keyseq.addkey(keysym, NoModifier); + } + cmd = theTopLevelKeymap().getBinding(keyseq); + + if (cmd == FuncRequest::noaction || cmd == FuncRequest::unknown + || cmd.action() == LFUN_SELF_INSERT) + // insert the processed text in the document (handles undo) + cmd = FuncRequest(LFUN_SELF_INSERT, qstring_to_ucs4(e->commitString())); + + cmd.setOrigin(FuncRequest::KEYBOARD); dispatch(cmd); // FIXME: this is supposed to remove traces from preedit // string. Can we avoid calling it explicitly? -- 2.39.5