From 1cd45c2ae17fa6cda303f41a49fecba1ed5f0b45 Mon Sep 17 00:00:00 2001 From: Abdelrazak Younes Date: Sun, 4 Oct 2009 20:58:20 +0000 Subject: [PATCH] Transfer all keyboard related code and actions from LyXFunc to GuiApplication. Part of it should be transfered later to GuiView and BufferView. This code can probably be simplified a lot... git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@31518 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/LyX.cpp | 2 - src/LyXFunc.cpp | 281 +-------------------------- src/LyXFunc.h | 24 --- src/Text3.cpp | 3 +- src/frontends/Application.h | 11 +- src/frontends/qt4/GuiApplication.cpp | 281 ++++++++++++++++++++++++++- src/frontends/qt4/GuiApplication.h | 8 +- src/frontends/qt4/GuiView.cpp | 4 +- src/frontends/qt4/GuiWorkArea.cpp | 2 +- 9 files changed, 299 insertions(+), 317 deletions(-) diff --git a/src/LyX.cpp b/src/LyX.cpp index 7f2c6f3c91..0c8234d961 100644 --- a/src/LyX.cpp +++ b/src/LyX.cpp @@ -765,8 +765,6 @@ bool LyX::init() // load user bind file user.bind pimpl_->toplevel_keymap_.read("user", 0, KeyMap::MissingOK); - pimpl_->lyxfunc_.initKeySequences(&pimpl_->toplevel_keymap_); - if (lyxerr.debugging(Debug::LYXRC)) lyxrc.print(); diff --git a/src/LyXFunc.cpp b/src/LyXFunc.cpp index 5248fd6365..2017df3ef6 100644 --- a/src/LyXFunc.cpp +++ b/src/LyXFunc.cpp @@ -40,10 +40,8 @@ #include "FuncRequest.h" #include "FuncStatus.h" #include "InsetIterator.h" -#include "Intl.h" #include "KeyMap.h" #include "Language.h" -#include "LaTeXFeatures.h" #include "Lexer.h" #include "LyXAction.h" #include "lyxfind.h" @@ -54,7 +52,6 @@ #include "ParagraphParameters.h" #include "ParIterator.h" #include "Row.h" -#include "Server.h" #include "Session.h" #include "SpellChecker.h" @@ -71,9 +68,7 @@ #include "support/gettext.h" #include "support/lassert.h" #include "support/lstrings.h" -#include "support/Path.h" #include "support/Package.h" -#include "support/Systemcall.h" #include "support/convert.h" #include "support/os.h" @@ -89,81 +84,11 @@ using frontend::LyXView; namespace Alert = frontend::Alert; -namespace { - - -// This function runs "configure" and then rereads lyx.defaults to -// reconfigure the automatic settings. -void reconfigure(LyXView * lv, string const & option) -{ - // emit message signal. - if (lv) - lv->message(_("Running configure...")); - - // Run configure in user lyx directory - PathChanger p(package().user_support()); - string configure_command = package().configure_command(); - configure_command += option; - Systemcall one; - int ret = one.startscript(Systemcall::Wait, configure_command); - p.pop(); - // emit message signal. - if (lv) - lv->message(_("Reloading configuration...")); - lyxrc.read(libFileSearch(string(), "lyxrc.defaults")); - // Re-read packages.lst - LaTeXFeatures::getAvailable(); - - if (ret) - Alert::information(_("System reconfiguration failed"), - _("The system reconfiguration has failed.\n" - "Default textclass is used but LyX may " - "not be able to work properly.\n" - "Please reconfigure again if needed.")); - else - - Alert::information(_("System reconfigured"), - _("The system has been reconfigured.\n" - "You need to restart LyX to make use of any\n" - "updated document class specifications.")); -} - -} - - LyXFunc::LyXFunc() - : encoded_last_key(0), meta_fake_bit(NoModifier) { } -void LyXFunc::initKeySequences(KeyMap * kb) -{ - keyseq = KeySequence(kb, kb); - cancel_meta_seq = KeySequence(kb, kb); -} - - -void LyXFunc::handleKeyFunc(FuncCode action) -{ - char_type c = encoded_last_key; - - if (keyseq.length()) - c = 0; - LyXView * lv = theApp()->currentWindow(); - LASSERT(lv && lv->currentBufferView(), /**/); - BufferView * bv = lv->currentBufferView(); - bv->getIntl().getTransManager().deadkey( - c, get_accent(action).accent, bv->cursor().innerText(), - bv->cursor()); - // Need to clear, in case the minibuffer calls these - // actions - keyseq.clear(); - // copied verbatim from do_accent_char - bv->cursor().resetAnchor(); - bv->processUpdateFlags(Update::FitCursor); -} - //FIXME: bookmark handling is a frontend issue. This code should be transferred // to GuiView and be GuiView and be window dependent. void LyXFunc::gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer) @@ -226,105 +151,6 @@ void LyXFunc::gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer) } -void LyXFunc::processKeySym(KeySymbol const & keysym, KeyModifier state) -{ - LYXERR(Debug::KEY, "KeySym is " << keysym.getSymbolName()); - - LyXView * lv = theApp()->currentWindow(); - - // Do nothing if we have nothing (JMarc) - if (!keysym.isOK()) { - LYXERR(Debug::KEY, "Empty kbd action (probably composing)"); - lv->restartCursor(); - return; - } - - if (keysym.isModifier()) { - LYXERR(Debug::KEY, "isModifier true"); - if (lv) - lv->restartCursor(); - return; - } - - //Encoding const * encoding = lv->documentBufferView()->cursor().getEncoding(); - //encoded_last_key = keysym.getISOEncoded(encoding ? encoding->name() : ""); - // FIXME: encoded_last_key shadows the member variable of the same - // name. Is that intended? - char_type encoded_last_key = keysym.getUCSEncoded(); - - // Do a one-deep top-level lookup for - // cancel and meta-fake keys. RVDK_PATCH_5 - cancel_meta_seq.reset(); - - FuncRequest func = cancel_meta_seq.addkey(keysym, state); - LYXERR(Debug::KEY, "action first set to [" << func.action << ']'); - - // When not cancel or meta-fake, do the normal lookup. - // Note how the meta_fake Mod1 bit is OR-ed in and reset afterwards. - // Mostly, meta_fake_bit = NoModifier. RVDK_PATCH_5. - if ((func.action != LFUN_CANCEL) && (func.action != LFUN_META_PREFIX)) { - // remove Caps Lock and Mod2 as a modifiers - func = keyseq.addkey(keysym, (state | meta_fake_bit)); - LYXERR(Debug::KEY, "action now set to [" << func.action << ']'); - } - - // Dont remove this unless you know what you are doing. - meta_fake_bit = NoModifier; - - // Can this happen now ? - if (func.action == LFUN_NOACTION) - func = FuncRequest(LFUN_COMMAND_PREFIX); - - LYXERR(Debug::KEY, " Key [action=" << func.action << "][" - << keyseq.print(KeySequence::Portable) << ']'); - - // already here we know if it any point in going further - // why not return already here if action == -1 and - // num_bytes == 0? (Lgb) - - if (keyseq.length() > 1) - lv->message(keyseq.print(KeySequence::ForGui)); - - - // Maybe user can only reach the key via holding down shift. - // Let's see. But only if shift is the only modifier - if (func.action == LFUN_UNKNOWN_ACTION && state == ShiftModifier) { - LYXERR(Debug::KEY, "Trying without shift"); - func = keyseq.addkey(keysym, NoModifier); - LYXERR(Debug::KEY, "Action now " << func.action); - } - - if (func.action == LFUN_UNKNOWN_ACTION) { - // Hmm, we didn't match any of the keysequences. See - // if it's normal insertable text not already covered - // by a binding - if (keysym.isText() && keyseq.length() == 1) { - LYXERR(Debug::KEY, "isText() is true, inserting."); - func = FuncRequest(LFUN_SELF_INSERT, - FuncRequest::KEYBOARD); - } else { - LYXERR(Debug::KEY, "Unknown, !isText() - giving up"); - lv->message(_("Unknown function.")); - lv->restartCursor(); - return; - } - } - - if (func.action == LFUN_SELF_INSERT) { - if (encoded_last_key != 0) { - docstring const arg(1, encoded_last_key); - dispatch(FuncRequest(LFUN_SELF_INSERT, arg, - FuncRequest::KEYBOARD)); - LYXERR(Debug::KEY, "SelfInsert arg[`" << to_utf8(arg) << "']"); - } - } else { - dispatch(func); - if (!lv) - return; - } -} - - FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const { //lyxerr << "LyXFunc::getStatus: cmd: " << cmd << endl; @@ -431,19 +257,12 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const break; } - case LFUN_COMMAND_PREFIX: - case LFUN_CANCEL: - case LFUN_META_PREFIX: - case LFUN_RECONFIGURE: case LFUN_DROP_LAYOUTS_CHOICE: - case LFUN_SERVER_GET_FILENAME: - case LFUN_SERVER_NOTIFY: case LFUN_CURSOR_FOLLOWS_SCROLLBAR_TOGGLE: case LFUN_REPEAT: case LFUN_PREFERENCES_SAVE: case LFUN_INSET_EDIT: case LFUN_BUFFER_SAVE_AS_DEFAULT: - case LFUN_LYXRC_APPLY: // these are handled in our dispatch() break; @@ -564,44 +383,6 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } else { switch (action) { - case LFUN_COMMAND_PREFIX: - dispatch(FuncRequest(LFUN_MESSAGE, keyseq.printOptions(true))); - break; - - case LFUN_CANCEL: - keyseq.reset(); - meta_fake_bit = NoModifier; - if (lv && lv->currentBufferView()) - // cancel any selection - dispatch(FuncRequest(LFUN_MARK_OFF)); - setMessage(from_ascii(N_("Cancel"))); - break; - - case LFUN_META_PREFIX: - meta_fake_bit = AltModifier; - setMessage(keyseq.print(KeySequence::ForGui)); - break; - - // --- Menus ----------------------------------------------- - case LFUN_RECONFIGURE: - // argument is any additional parameter to the configure.py command - reconfigure(lv, argument); - break; - - // --- lyxserver commands ---------------------------- - case LFUN_SERVER_GET_FILENAME: { - LASSERT(lv && lv->documentBufferView(), return); - docstring const fname = from_utf8( - lv->documentBufferView()->buffer().absFileName()); - setMessage(fname); - LYXERR(Debug::INFO, "FNAME[" << fname << ']'); - break; - } - case LFUN_SERVER_NOTIFY: - dispatch_buffer = keyseq.print(KeySequence::Portable); - theServer().notifyClient(to_utf8(dispatch_buffer)); - break; - case LFUN_CURSOR_FOLLOWS_SCROLLBAR_TOGGLE: lyxrc.cursor_follows_scrollbar = !lyxrc.cursor_follows_scrollbar; break; @@ -714,36 +495,6 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; } - case LFUN_LYXRC_APPLY: { - // reset active key sequences, since the bindings - // are updated (bug 6064) - keyseq.reset(); - LyXRC const lyxrc_orig = lyxrc; - - istringstream ss(argument); - bool const success = lyxrc.read(ss) == 0; - - if (!success) { - lyxerr << "Warning in LFUN_LYXRC_APPLY!\n" - << "Unable to read lyxrc data" - << endl; - break; - } - - actOnUpdatedPrefs(lyxrc_orig, lyxrc); - - setSpellChecker(); - - theApp()->resetGui(); - - /// We force the redraw in any case because there might be - /// some screen font changes. - /// FIXME: only the current view will be updated. the Gui - /// class is able to furnish the list of views. - updateFlags = Update::Force; - break; - } - case LFUN_BOOKMARK_GOTO: // go to bookmark, open unopened file and switch to buffer if necessary gotoBookmark(convert(to_utf8(cmd.argument())), true, true); @@ -755,11 +506,14 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; default: + DispatchResult dr; + LASSERT(theApp(), /**/); // Let the frontend dispatch its own actions. - if (theApp()->dispatch(cmd)) + theApp()->dispatch(cmd, dr); + if (dr.dispatched()) // Nothing more to do. - return; + break; // Everything below is only for active window if (lv == 0) @@ -791,7 +545,6 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } // OK, so try the current Buffer itself... - DispatchResult dr; bv->buffer().dispatch(cmd, dr); if (dr.dispatched()) { updateFlags = dr.update(); @@ -901,28 +654,4 @@ void LyXFunc::setMessage(docstring const & m) const } -docstring LyXFunc::viewStatusMessage() -{ - // When meta-fake key is pressed, show the key sequence so far + "M-". - if (wasMetaKey()) - return keyseq.print(KeySequence::ForGui) + "M-"; - - // Else, when a non-complete key sequence is pressed, - // show the available options. - if (keyseq.length() > 0 && !keyseq.deleted()) - return keyseq.printOptions(true); - - return docstring(); -} - - -bool LyXFunc::wasMetaKey() const -{ - return (meta_fake_bit != NoModifier); -} - - -namespace { - -} // namespace anon } // namespace lyx diff --git a/src/LyXFunc.h b/src/LyXFunc.h index d560b15f47..9b8fe7ffbd 100644 --- a/src/LyXFunc.h +++ b/src/LyXFunc.h @@ -49,21 +49,9 @@ public: /// LyX dispatcher, executes lyx actions. void dispatch(FuncRequest const &); - /// - void initKeySequences(KeyMap * kb); - - /// return the status bar state string - docstring viewStatusMessage(); - - /// - void processKeySym(KeySymbol const & key, KeyModifier state); - /// FuncStatus getStatus(FuncRequest const & action) const; - /// The last key was meta - bool wasMetaKey() const; - /// True if lyxfunc reports an error bool errorStat() const { return errorstat; } /// Buffer to store result messages @@ -72,8 +60,6 @@ public: void setErrorMessage(docstring const &) const; /// Buffer to store result messages docstring const getMessage() const { return dispatch_buffer; } - /// Handle a accented char key sequence - void handleKeyFunc(FuncCode action); /// goto a bookmark /// openFile: whether or not open a file if the file is not opened /// switchToBuffer: whether or not switch to buffer if the buffer is @@ -86,16 +72,6 @@ public: int cursorBeforeDispatchY() const { return cursorPosBeforeDispatchY_; } private: - /// the last character added to the key sequence, in UCS4 encoded form - char_type encoded_last_key; - - /// - KeySequence keyseq; - /// - KeySequence cancel_meta_seq; - /// - KeyModifier meta_fake_bit; - /// cursor position before dispatch started int cursorPosBeforeDispatchX_; int cursorPosBeforeDispatchY_; diff --git a/src/Text3.cpp b/src/Text3.cpp index 7963262a15..b7605efc1a 100644 --- a/src/Text3.cpp +++ b/src/Text3.cpp @@ -1996,7 +1996,7 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) case LFUN_ACCENT_HUNGARIAN_UMLAUT: case LFUN_ACCENT_CIRCLE: case LFUN_ACCENT_OGONEK: - theLyXFunc().handleKeyFunc(cmd.action); + theApp()->handleKeyFunc(cmd.action); if (!cmd.argument().empty()) // FIXME: Are all these characters encoded in one byte in utf8? bv->translateAndInsert(cmd.argument()[0], this, cur); @@ -2741,7 +2741,6 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, case LFUN_NOACTION: case LFUN_NOTE_NEXT: case LFUN_REFERENCE_NEXT: - case LFUN_SERVER_NOTIFY: case LFUN_SERVER_SET_XY: case LFUN_TEXTSTYLE_APPLY: case LFUN_TEXTSTYLE_UPDATE: diff --git a/src/frontends/Application.h b/src/frontends/Application.h index fa470f2f5d..b73256db88 100644 --- a/src/frontends/Application.h +++ b/src/frontends/Application.h @@ -12,6 +12,9 @@ #define APPLICATION_H #include "ColorCode.h" +#include "FuncCode.h" + +#include "KeyModifier.h" #include "support/strfwd.h" @@ -24,6 +27,7 @@ namespace lyx { class BufferView; class Buffer; +class DispatchResult; class docstring_list; class FuncRequest; class FuncStatus; @@ -172,8 +176,7 @@ public: /// virtual bool getStatus(FuncRequest const & cmd, FuncStatus & flag) const = 0; /// dispatch command. - /// \return true if the \c FuncRequest has been dispatched. - virtual bool dispatch(FuncRequest const & cmd) = 0; + virtual void dispatch(FuncRequest const & cmd, DispatchResult & dr) = 0; /// virtual void resetGui() = 0; @@ -228,6 +231,10 @@ public: /// \return the icon file name for the given action. virtual docstring iconName(FuncRequest const & f, bool unknown) = 0; + + /// Handle a accented char key sequence + /// FIXME: this is only needed for LFUN_ACCENT_* in Text::dispatch() + virtual void handleKeyFunc(FuncCode action) = 0; }; /// Return the list of loadable formats. diff --git a/src/frontends/qt4/GuiApplication.cpp b/src/frontends/qt4/GuiApplication.cpp index 6b0a78adaa..8eaa682c7d 100644 --- a/src/frontends/qt4/GuiApplication.cpp +++ b/src/frontends/qt4/GuiApplication.cpp @@ -37,12 +37,15 @@ #include "Font.h" #include "FuncRequest.h" #include "FuncStatus.h" +#include "Intl.h" #include "Language.h" +#include "LaTeXFeatures.h" #include "Lexer.h" #include "LyX.h" #include "LyXAction.h" #include "LyXFunc.h" #include "LyXRC.h" +#include "Server.h" #include "Session.h" #include "version.h" @@ -59,6 +62,8 @@ #include "support/Messages.h" #include "support/os.h" #include "support/Package.h" +#include "support/Path.h" +#include "support/Systemcall.h" #ifdef Q_WS_MACX #include "support/linkback/LinkBackProxy.h" @@ -471,7 +476,7 @@ public: QKeyEvent * ke = static_cast(e); KeySymbol sym; setKeySymbol(&sym, ke); - theLyXFunc().processKeySym(sym, q_key_state(ke->modifiers())); + guiApp->processKeySym(sym, q_key_state(ke->modifiers())); e->accept(); return true; } @@ -644,12 +649,20 @@ public: struct GuiApplication::Private { - Private(): language_model_(0), global_menubar_(0) + Private(): language_model_(0), global_menubar_(0), + encoded_last_key(0), meta_fake_bit(NoModifier) { #ifdef Q_WS_WIN /// WMF Mime handler for Windows clipboard. wmf_mime_ = new QWindowsMimeMetafile(); #endif + initKeySequences(&theTopLevelKeymap()); + } + + void initKeySequences(KeyMap * kb) + { + keyseq = KeySequence(kb, kb); + cancel_meta_seq = KeySequence(kb, kb); } /// @@ -680,6 +693,16 @@ struct GuiApplication::Private /// delayed FuncRequests std::queue func_request_queue_; + /// the last character added to the key sequence, in UCS4 encoded form + char_type encoded_last_key; + + /// + KeySequence keyseq; + /// + KeySequence cancel_meta_seq; + /// + KeyModifier meta_fake_bit; + /// Multiple views container. /** * Warning: This must not be a smart pointer as the destruction of the @@ -833,6 +856,13 @@ bool GuiApplication::getStatus(FuncRequest const & cmd, FuncStatus & flag) const case LFUN_SET_COLOR: case LFUN_WINDOW_NEW: case LFUN_LYX_QUIT: + case LFUN_LYXRC_APPLY: + case LFUN_COMMAND_PREFIX: + case LFUN_CANCEL: + case LFUN_META_PREFIX: + case LFUN_RECONFIGURE: + case LFUN_SERVER_GET_FILENAME: + case LFUN_SERVER_NOTIFY: enable = true; break; @@ -846,8 +876,45 @@ bool GuiApplication::getStatus(FuncRequest const & cmd, FuncStatus & flag) const return true; } - -bool GuiApplication::dispatch(FuncRequest const & cmd) + +// This function runs "configure" and then rereads lyx.defaults to +// reconfigure the automatic settings. +static void reconfigure(LyXView * lv, string const & option) +{ + // emit message signal. + if (lv) + lv->message(_("Running configure...")); + + // Run configure in user lyx directory + PathChanger p(package().user_support()); + string configure_command = package().configure_command(); + configure_command += option; + Systemcall one; + int ret = one.startscript(Systemcall::Wait, configure_command); + p.pop(); + // emit message signal. + if (lv) + lv->message(_("Reloading configuration...")); + lyxrc.read(libFileSearch(QString(), "lyxrc.defaults")); + // Re-read packages.lst + LaTeXFeatures::getAvailable(); + + if (ret) + Alert::information(_("System reconfiguration failed"), + _("The system reconfiguration has failed.\n" + "Default textclass is used but LyX may " + "not be able to work properly.\n" + "Please reconfigure again if needed.")); + else + + Alert::information(_("System reconfigured"), + _("The system has been reconfigured.\n" + "You need to restart LyX to make use of any\n" + "updated document class specifications.")); +} + + +void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr) { switch (cmd.action) { @@ -993,13 +1060,213 @@ bool GuiApplication::dispatch(FuncRequest const & cmd) break; } + case LFUN_LYXRC_APPLY: { + // reset active key sequences, since the bindings + // are updated (bug 6064) + d->keyseq.reset(); + LyXRC const lyxrc_orig = lyxrc; + + istringstream ss(to_utf8(cmd.argument())); + bool const success = lyxrc.read(ss) == 0; + + if (!success) { + lyxerr << "Warning in LFUN_LYXRC_APPLY!\n" + << "Unable to read lyxrc data" + << endl; + break; + } + + actOnUpdatedPrefs(lyxrc_orig, lyxrc); + setSpellChecker(); + resetGui(); + + break; + } + + case LFUN_COMMAND_PREFIX: + lyx::dispatch(FuncRequest(LFUN_MESSAGE, d->keyseq.printOptions(true))); + break; + + case LFUN_CANCEL: { + d->keyseq.reset(); + d->meta_fake_bit = NoModifier; + GuiView * gv = currentView(); + if (gv && gv->currentBufferView()) + // cancel any selection + lyx::dispatch(FuncRequest(LFUN_MARK_OFF)); + dr.setMessage(from_ascii(N_("Cancel"))); + break; + } + case LFUN_META_PREFIX: + d->meta_fake_bit = AltModifier; + dr.setMessage(d->keyseq.print(KeySequence::ForGui)); + break; + + // --- Menus ----------------------------------------------- + case LFUN_RECONFIGURE: + // argument is any additional parameter to the configure.py command + reconfigure(currentView(), to_utf8(cmd.argument())); + break; + + // --- lyxserver commands ---------------------------- + case LFUN_SERVER_GET_FILENAME: { + GuiView * lv = currentView(); + LASSERT(lv && lv->documentBufferView(), return); + docstring const fname = from_utf8( + lv->documentBufferView()->buffer().absFileName()); + dr.setMessage(fname); + LYXERR(Debug::INFO, "FNAME[" << fname << ']'); + break; + } + case LFUN_SERVER_NOTIFY: { + docstring const dispatch_buffer = d->keyseq.print(KeySequence::Portable); + dr.setMessage(dispatch_buffer); + theServer().notifyClient(to_utf8(dispatch_buffer)); + break; + } default: // Notify the caller that the action has not been dispatched. - return false; + dr.dispatched(false); + return; } // The action has been dispatched. - return true; + dr.dispatched(true); +} + + +docstring GuiApplication::viewStatusMessage() +{ + // When meta-fake key is pressed, show the key sequence so far + "M-". + if (d->meta_fake_bit != NoModifier) + return d->keyseq.print(KeySequence::ForGui) + "M-"; + + // Else, when a non-complete key sequence is pressed, + // show the available options. + if (d->keyseq.length() > 0 && !d->keyseq.deleted()) + return d->keyseq.printOptions(true); + + return docstring(); +} + + +void GuiApplication::handleKeyFunc(FuncCode action) +{ + char_type c = d->encoded_last_key; + + if (d->keyseq.length()) + c = 0; + GuiView * gv = currentView(); + LASSERT(gv && gv->currentBufferView(), return); + BufferView * bv = gv->currentBufferView(); + bv->getIntl().getTransManager().deadkey( + c, get_accent(action).accent, bv->cursor().innerText(), + bv->cursor()); + // Need to clear, in case the minibuffer calls these + // actions + d->keyseq.clear(); + // copied verbatim from do_accent_char + bv->cursor().resetAnchor(); + bv->processUpdateFlags(Update::FitCursor); +} + + +void GuiApplication::processKeySym(KeySymbol const & keysym, KeyModifier state) +{ + LYXERR(Debug::KEY, "KeySym is " << keysym.getSymbolName()); + + LyXView * lv = theApp()->currentWindow(); + + // Do nothing if we have nothing (JMarc) + if (!keysym.isOK()) { + LYXERR(Debug::KEY, "Empty kbd action (probably composing)"); + lv->restartCursor(); + return; + } + + if (keysym.isModifier()) { + LYXERR(Debug::KEY, "isModifier true"); + if (lv) + lv->restartCursor(); + return; + } + + //Encoding const * encoding = lv->documentBufferView()->cursor().getEncoding(); + //encoded_last_key = keysym.getISOEncoded(encoding ? encoding->name() : ""); + // FIXME: encoded_last_key shadows the member variable of the same + // name. Is that intended? + char_type encoded_last_key = keysym.getUCSEncoded(); + + // Do a one-deep top-level lookup for + // cancel and meta-fake keys. RVDK_PATCH_5 + d->cancel_meta_seq.reset(); + + FuncRequest func = d->cancel_meta_seq.addkey(keysym, state); + LYXERR(Debug::KEY, "action first set to [" << func.action << ']'); + + // When not cancel or meta-fake, do the normal lookup. + // Note how the meta_fake Mod1 bit is OR-ed in and reset afterwards. + // Mostly, meta_fake_bit = NoModifier. RVDK_PATCH_5. + if ((func.action != LFUN_CANCEL) && (func.action != LFUN_META_PREFIX)) { + // remove Caps Lock and Mod2 as a modifiers + func = d->keyseq.addkey(keysym, (state | d->meta_fake_bit)); + LYXERR(Debug::KEY, "action now set to [" << func.action << ']'); + } + + // Dont remove this unless you know what you are doing. + d->meta_fake_bit = NoModifier; + + // Can this happen now ? + if (func.action == LFUN_NOACTION) + func = FuncRequest(LFUN_COMMAND_PREFIX); + + LYXERR(Debug::KEY, " Key [action=" << func.action << "][" + << d->keyseq.print(KeySequence::Portable) << ']'); + + // already here we know if it any point in going further + // why not return already here if action == -1 and + // num_bytes == 0? (Lgb) + + if (d->keyseq.length() > 1) + lv->message(d->keyseq.print(KeySequence::ForGui)); + + + // Maybe user can only reach the key via holding down shift. + // Let's see. But only if shift is the only modifier + if (func.action == LFUN_UNKNOWN_ACTION && state == ShiftModifier) { + LYXERR(Debug::KEY, "Trying without shift"); + func = d->keyseq.addkey(keysym, NoModifier); + LYXERR(Debug::KEY, "Action now " << func.action); + } + + if (func.action == LFUN_UNKNOWN_ACTION) { + // Hmm, we didn't match any of the keysequences. See + // if it's normal insertable text not already covered + // by a binding + if (keysym.isText() && d->keyseq.length() == 1) { + LYXERR(Debug::KEY, "isText() is true, inserting."); + func = FuncRequest(LFUN_SELF_INSERT, + FuncRequest::KEYBOARD); + } else { + LYXERR(Debug::KEY, "Unknown, !isText() - giving up"); + lv->message(_("Unknown function.")); + lv->restartCursor(); + return; + } + } + + if (func.action == LFUN_SELF_INSERT) { + if (encoded_last_key != 0) { + docstring const arg(1, encoded_last_key); + lyx::dispatch(FuncRequest(LFUN_SELF_INSERT, arg, + FuncRequest::KEYBOARD)); + LYXERR(Debug::KEY, "SelfInsert arg[`" << to_utf8(arg) << "']"); + } + } else { + lyx::dispatch(func); + if (!lv) + return; + } } @@ -1031,7 +1298,7 @@ void GuiApplication::resetGui() gv->resetDialogs(); } - dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE)); + lyx::dispatch(FuncRequest(LFUN_SCREEN_FONT_UPDATE)); } diff --git a/src/frontends/qt4/GuiApplication.h b/src/frontends/qt4/GuiApplication.h index 4b01f257fe..9621167377 100644 --- a/src/frontends/qt4/GuiApplication.h +++ b/src/frontends/qt4/GuiApplication.h @@ -28,6 +28,7 @@ namespace lyx { class BufferView; class ColorCache; +class KeySymbol; namespace frontend { @@ -59,7 +60,7 @@ public: //@{ LyXView * currentWindow(); bool getStatus(FuncRequest const & cmd, FuncStatus & flag) const; - bool dispatch(FuncRequest const &); + void dispatch(FuncRequest const &, DispatchResult & dr); void dispatchDelayed(FuncRequest const &); void resetGui(); void restoreGuiSession(); @@ -77,6 +78,7 @@ public: docstring iconName(FuncRequest const & f, bool unknown); void hideDialogs(std::string const & name, Inset * inset) const; Buffer const * updateInset(Inset const * inset) const; + void handleKeyFunc(FuncCode action); //@} Toolbars const & toolbars() const; @@ -125,6 +127,10 @@ public: void unregisterView(GuiView * gv); /// GuiView & view(int id) const; + /// + void processKeySym(KeySymbol const & key, KeyModifier state); + /// return the status bar state string + docstring viewStatusMessage(); private Q_SLOTS: /// diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index 5d94999f11..736b9d81ba 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -735,7 +735,7 @@ void GuiView::updateStatusBar() void GuiView::showMessage() { - QString msg = toqstr(theLyXFunc().viewStatusMessage()); + QString msg = toqstr(theGuiApp()->viewStatusMessage()); if (msg.isEmpty()) { BufferView const * bv = currentBufferView(); if (bv) @@ -827,7 +827,7 @@ bool GuiView::event(QEvent * e) // is viewed. KeySymbol sym; setKeySymbol(&sym, ke); - theLyXFunc().processKeySym(sym, q_key_state(ke->modifiers())); + guiApp->processKeySym(sym, q_key_state(ke->modifiers())); e->accept(); return true; } diff --git a/src/frontends/qt4/GuiWorkArea.cpp b/src/frontends/qt4/GuiWorkArea.cpp index 4780ebbd71..2efc36bcd7 100644 --- a/src/frontends/qt4/GuiWorkArea.cpp +++ b/src/frontends/qt4/GuiWorkArea.cpp @@ -455,7 +455,7 @@ void GuiWorkArea::processKeySym(KeySymbol const & key, KeyModifier mod) // we better stop the blinking cursor... // the cursor gets restarted in GuiView::restartCursor() stopBlinkingCursor(); - theLyXFunc().processKeySym(key, mod); + guiApp->processKeySym(key, mod); }