X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FLyXFunc.cpp;h=6a619200e28f9ad6a9f5acd461eae7a59eac991e;hb=2098f1d8c20d51e63e670bcdc9da8996068975bf;hp=9a2969d2dbd871f9d938878e1ce47f143e1b2a27;hpb=b4b19b59a329f789c9ca72febfad1e76bc74d756;p=lyx.git diff --git a/src/LyXFunc.cpp b/src/LyXFunc.cpp index 9a2969d2db..6a619200e2 100644 --- a/src/LyXFunc.cpp +++ b/src/LyXFunc.cpp @@ -40,7 +40,6 @@ #include "FuncRequest.h" #include "FuncStatus.h" #include "InsetIterator.h" -#include "Intl.h" #include "KeyMap.h" #include "Language.h" #include "Lexer.h" @@ -53,26 +52,9 @@ #include "ParagraphParameters.h" #include "ParIterator.h" #include "Row.h" -#include "Server.h" #include "Session.h" #include "SpellChecker.h" -#include "insets/InsetBox.h" -#include "insets/InsetBranch.h" -#include "insets/InsetCommand.h" -#include "insets/InsetERT.h" -#include "insets/InsetExternal.h" -#include "insets/InsetFloat.h" -#include "insets/InsetGraphics.h" -#include "insets/InsetInclude.h" -#include "insets/InsetListings.h" -#include "insets/InsetNote.h" -#include "insets/InsetPhantom.h" -#include "insets/InsetSpace.h" -#include "insets/InsetTabular.h" -#include "insets/InsetVSpace.h" -#include "insets/InsetWrap.h" - #include "frontends/alert.h" #include "frontends/Application.h" #include "frontends/KeySymbol.h" @@ -84,10 +66,9 @@ #include "support/FileName.h" #include "support/filetools.h" #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" @@ -103,146 +84,17 @@ 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.")); -} - - -bool getLocalStatus(Cursor cursor, FuncRequest const & cmd, FuncStatus & status) -{ - // Try to fix cursor in case it is broken. - cursor.fixIfBroken(); - - // This is, of course, a mess. Better create a new doc iterator and use - // this in Inset::getStatus. This might require an additional - // BufferView * arg, though (which should be avoided) - //Cursor safe = *this; - bool res = false; - for ( ; cursor.depth(); cursor.pop()) { - //lyxerr << "\nCursor::getStatus: cmd: " << cmd << endl << *this << endl; - LASSERT(cursor.idx() <= cursor.lastidx(), /**/); - LASSERT(cursor.pit() <= cursor.lastpit(), /**/); - LASSERT(cursor.pos() <= cursor.lastpos(), /**/); - - // The inset's getStatus() will return 'true' if it made - // a definitive decision on whether it want to handle the - // request or not. The result of this decision is put into - // the 'status' parameter. - if (cursor.inset().getStatus(cursor, cmd, status)) { - res = true; - break; - } - } - return res; -} - - -/** Return the change status at cursor position, taking in account the - * status at each level of the document iterator (a table in a deleted - * footnote is deleted). - * When \param outer is true, the top slice is not looked at. - */ -Change::Type lookupChangeType(DocIterator const & dit, bool outer = false) -{ - size_t const depth = dit.depth() - (outer ? 1 : 0); - - for (size_t i = 0 ; i < depth ; ++i) { - CursorSlice const & slice = dit[i]; - if (!slice.inset().inMathed() - && slice.pos() < slice.paragraph().size()) { - Change::Type const ch = slice.paragraph().lookupChange(slice.pos()).type; - if (ch != Change::UNCHANGED) - return ch; - } - } - return Change::UNCHANGED; -} - -} - - LyXFunc::LyXFunc() - : lyx_view_(0), 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::setLyXView(LyXView * lv) { - if (lyx_view_ && lyx_view_->currentBufferView() && lyx_view_ != lv) - // save current selection to the selection buffer to allow - // middle-button paste in another window - cap::saveSelection(lyx_view_->currentBufferView()->cursor()); - lyx_view_ = lv; } -void LyXFunc::handleKeyFunc(FuncCode action) -{ - char_type c = encoded_last_key; - - if (keyseq.length()) - c = 0; - - LASSERT(lyx_view_ && lyx_view_->currentBufferView(), /**/); - lyx_view_->currentBufferView()->getIntl().getTransManager().deadkey( - c, get_accent(action).accent, view()->cursor().innerText(), - view()->cursor()); - // Need to clear, in case the minibuffer calls these - // actions - keyseq.clear(); - // copied verbatim from do_accent_char - view()->cursor().resetAnchor(); - view()->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) { - LASSERT(lyx_view_, /**/); + LyXView * lv = theApp()->currentWindow(); + LASSERT(lv, /**/); if (!theSession().bookmarks().isValid(idx)) return; BookmarksSection::Bookmark const & bm = theSession().bookmarks().bookmark(idx); @@ -267,16 +119,16 @@ void LyXFunc::gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer) dispatch(FuncRequest(LFUN_BOOKMARK_SAVE, "0")); // if the current buffer is not that one, switch to it. - if (!lyx_view_->documentBufferView() - || lyx_view_->documentBufferView()->buffer().fileName() != tmp.filename) { + if (!lv->documentBufferView() + || lv->documentBufferView()->buffer().fileName() != tmp.filename) { if (!switchToBuffer) return; dispatch(FuncRequest(LFUN_BUFFER_SWITCH, file)); } // moveToPosition try paragraph id first and then paragraph (pit, pos). - if (!view()->moveToPosition(tmp.bottom_pit, tmp.bottom_pos, - tmp.top_id, tmp.top_pos)) + if (!lv->documentBufferView()->moveToPosition( + tmp.bottom_pit, tmp.bottom_pos, tmp.top_id, tmp.top_pos)) return; // bm changed @@ -284,13 +136,13 @@ void LyXFunc::gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer) return; // Cursor jump succeeded! - Cursor const & cur = view()->cursor(); + Cursor const & cur = lv->documentBufferView()->cursor(); pit_type new_pit = cur.pit(); pos_type new_pos = cur.pos(); int new_id = cur.paragraph().id(); // if bottom_pit, bottom_pos or top_id has been changed, update bookmark - // see http://bugzilla.lyx.org/show_bug.cgi?id=3092 + // see http://www.lyx.org/trac/ticket/3092 if (bm.bottom_pit != new_pit || bm.bottom_pos != new_pos || bm.top_id != new_id) { const_cast(bm).updatePos( @@ -299,162 +151,24 @@ 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()); - - // Do nothing if we have nothing (JMarc) - if (!keysym.isOK()) { - LYXERR(Debug::KEY, "Empty kbd action (probably composing)"); - lyx_view_->restartCursor(); - return; - } - - if (keysym.isModifier()) { - LYXERR(Debug::KEY, "isModifier true"); - if (lyx_view_) - lyx_view_->restartCursor(); - return; - } - - //Encoding const * encoding = view()->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) - lyx_view_->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"); - lyx_view_->message(_("Unknown function.")); - lyx_view_->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 (!lyx_view_) - return; - } -} - - FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const { //lyxerr << "LyXFunc::getStatus: cmd: " << cmd << endl; FuncStatus flag; - /* In LyX/Mac, when a dialog is open, the menus of the - application can still be accessed without giving focus to - the main window. In this case, we want to disable the menu - entries that are buffer or view-related. - - If this code is moved somewhere else (like in - GuiView::getStatus), then several functions will not be - handled correctly. - */ - frontend::LyXView * lv = 0; - Buffer * buf = 0; - if (lyx_view_ - && (cmd.origin != FuncRequest::MENU || lyx_view_->hasFocus())) { - lv = lyx_view_; - if (lyx_view_->documentBufferView()) - buf = &lyx_view_->documentBufferView()->buffer(); - } - if (cmd.action == LFUN_NOACTION) { flag.message(from_utf8(N_("Nothing to do"))); flag.setEnabled(false); return flag; } - switch (cmd.action) { - case LFUN_UNKNOWN_ACTION: + if (cmd.action == LFUN_UNKNOWN_ACTION) { flag.unknown(true); flag.setEnabled(false); - break; - - default: - break; - } - - if (flag.unknown()) { flag.message(from_utf8(N_("Unknown action"))); return flag; } - if (!flag.enabled()) { - if (flag.message().empty()) - flag.message(from_utf8(N_("Command disabled"))); - return flag; - } - - // Check whether we need a buffer - if (!lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer) && !buf) { - // no, exit directly - flag.message(from_utf8(N_("Command not allowed with" - "out any document open"))); - flag.setEnabled(false); - return flag; - } - // I would really like to avoid having this switch and rather try to // encode this in the function itself. // -- And I'd rather let an inset decide which LFUNs it is willing @@ -462,55 +176,6 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const bool enable = true; switch (cmd.action) { - case LFUN_BUFFER_TOGGLE_READ_ONLY: - flag.setOnOff(buf->isReadonly()); - break; - - case LFUN_BUFFER_SWITCH: - // toggle on the current buffer, but do not toggle off - // the other ones (is that a good idea?) - if (buf && to_utf8(cmd.argument()) == buf->absFileName()) - flag.setOnOff(true); - break; - - case LFUN_BUFFER_CHKTEX: - enable = buf->isLatex() && !lyxrc.chktex_command.empty(); - break; - - case LFUN_BUILD_PROGRAM: - enable = buf->isExportable("program"); - break; - - case LFUN_VC_REGISTER: - enable = !buf->lyxvc().inUse(); - break; - case LFUN_VC_CHECK_IN: - enable = buf->lyxvc().checkInEnabled(); - break; - case LFUN_VC_CHECK_OUT: - enable = buf->lyxvc().checkOutEnabled(); - break; - case LFUN_VC_LOCKING_TOGGLE: - enable = !buf->isReadonly() && buf->lyxvc().lockingToggleEnabled(); - flag.setOnOff(enable && !buf->lyxvc().locker().empty()); - break; - case LFUN_VC_REVERT: - enable = buf->lyxvc().inUse(); - break; - case LFUN_VC_UNDO_LAST: - enable = buf->lyxvc().undoLastEnabled(); - break; - case LFUN_BUFFER_RELOAD: - enable = !buf->isUnnamed() && buf->fileName().exists() - && (!buf->isClean() || buf->isExternallyModified(Buffer::timestamp_method)); - break; - - case LFUN_CITATION_INSERT: { - FuncRequest fr(LFUN_INSET_INSERT, "citation"); - enable = getStatus(fr).enabled(); - break; - } - // This could be used for the no-GUI version. The GUI version is handled in // LyXView::getStatus(). See above. /* @@ -522,24 +187,6 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const } */ - case LFUN_BUFFER_WRITE_ALL: { - // We enable the command only if there are some modified buffers - Buffer * first = theBufferList().first(); - enable = false; - if (!first) - break; - Buffer * b = first; - // We cannot use a for loop as the buffer list is a cycle. - do { - if (!b->isClean()) { - enable = true; - break; - } - b = theBufferList().next(b); - } while (b != first); - break; - } - case LFUN_BOOKMARK_GOTO: { const unsigned int num = convert(to_utf8(cmd.argument())); enable = theSession().bookmarks().isValid(num); @@ -596,80 +243,11 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const break; } - case LFUN_VC_COMMAND: { - if (cmd.argument().empty()) - enable = false; - - if (!buf && contains(cmd.getArg(0), 'D')) - enable = false; - break; - } - - case LFUN_MASTER_BUFFER_UPDATE: - case LFUN_MASTER_BUFFER_VIEW: - if (!buf->parent()) { - enable = false; - break; - } - case LFUN_BUFFER_UPDATE: - case LFUN_BUFFER_VIEW: { - string format = to_utf8(cmd.argument()); - if (cmd.argument().empty()) - format = buf->getDefaultOutputFormat(); - typedef vector Formats; - Formats formats; - formats = buf->exportableFormats(true); - Formats::const_iterator fit = formats.begin(); - Formats::const_iterator end = formats.end(); - enable = false; - for (; fit != end ; ++fit) { - if ((*fit)->name() == format) - enable = true; - } - break; - } - - case LFUN_WORD_FIND_FORWARD: - case LFUN_WORD_FIND_BACKWARD: - case LFUN_WORD_FINDADV: - case LFUN_COMMAND_PREFIX: - case LFUN_COMMAND_EXECUTE: - case LFUN_CANCEL: - case LFUN_META_PREFIX: - case LFUN_BUFFER_CLOSE: - case LFUN_BUFFER_IMPORT: - case LFUN_BUFFER_AUTO_SAVE: - case LFUN_RECONFIGURE: - case LFUN_HELP_OPEN: - case LFUN_DROP_LAYOUTS_CHOICE: - case LFUN_MENU_OPEN: - case LFUN_SERVER_GET_FILENAME: - case LFUN_SERVER_NOTIFY: - case LFUN_SERVER_GOTO_FILE_ROW: - case LFUN_DIALOG_HIDE: - case LFUN_DIALOG_DISCONNECT_INSET: - case LFUN_BUFFER_CHILD_OPEN: case LFUN_CURSOR_FOLLOWS_SCROLLBAR_TOGGLE: - case LFUN_KEYMAP_OFF: - case LFUN_KEYMAP_PRIMARY: - case LFUN_KEYMAP_SECONDARY: - case LFUN_KEYMAP_TOGGLE: case LFUN_REPEAT: - case LFUN_BUFFER_EXPORT_CUSTOM: case LFUN_PREFERENCES_SAVE: - case LFUN_MESSAGE: - case LFUN_INSET_EDIT: - case LFUN_BUFFER_LANGUAGE: - case LFUN_TEXTCLASS_APPLY: - case LFUN_TEXTCLASS_LOAD: case LFUN_BUFFER_SAVE_AS_DEFAULT: - case LFUN_BUFFER_PARAMS_APPLY: - case LFUN_LAYOUT_MODULES_CLEAR: - case LFUN_LAYOUT_MODULE_ADD: - case LFUN_LAYOUT_RELOAD: - case LFUN_LYXRC_APPLY: - case LFUN_BUFFER_NEXT: - case LFUN_BUFFER_PREVIOUS: + case LFUN_DEBUG_LEVEL_SET: // these are handled in our dispatch() break; @@ -682,6 +260,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const break; // Does the view know something? + LyXView * lv = theApp()->currentWindow(); if (!lv) { enable = false; break; @@ -689,47 +268,26 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const if (lv->getStatus(cmd, flag)) break; + BufferView * bv = lv->currentBufferView(); + BufferView * doc_bv = lv->documentBufferView(); // If we do not have a BufferView, then other functions are disabled - if (!view()) { + if (!bv) { enable = false; break; } - - // Is this a function that acts on inset at point? - Inset * inset = view()->cursor().nextInset(); - if (lyxaction.funcHasFlag(cmd.action, LyXAction::AtPoint) - && inset && inset->getStatus(view()->cursor(), cmd, flag)) - break; - - bool decided = getLocalStatus(view()->cursor(), cmd, flag); - if (!decided) - // try the BufferView - decided = view()->getStatus(cmd, flag); + // try the BufferView + bool decided = bv->getStatus(cmd, flag); if (!decided) // try the Buffer - view()->buffer().getStatus(cmd, flag); + decided = bv->buffer().getStatus(cmd, flag); + if (!decided && doc_bv) + // try the Document Buffer + decided = doc_bv->buffer().getStatus(cmd, flag); } if (!enable) flag.setEnabled(false); - // Can we use a readonly buffer? - if (buf && buf->isReadonly() - && !lyxaction.funcHasFlag(cmd.action, LyXAction::ReadOnly) - && !lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer)) { - flag.message(from_utf8(N_("Document is read-only"))); - flag.setEnabled(false); - } - - // Are we in a DELETED change-tracking region? - if (buf && view() - && lookupChangeType(view()->cursor(), true) == Change::DELETED - && !lyxaction.funcHasFlag(cmd.action, LyXAction::ReadOnly) - && !lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer)) { - flag.message(from_utf8(N_("This portion of the document is deleted."))); - flag.setEnabled(false); - } - // the default error message if we disable the command if (!flag.enabled() && flag.message().empty()) flag.message(from_utf8(N_("Command disabled"))); @@ -737,64 +295,49 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const return flag; } - -bool LyXFunc::ensureBufferClean(BufferView * bv) +/// send a post-dispatch status message +static docstring sendDispatchMessage(docstring const & msg, FuncRequest const & cmd) { - Buffer & buf = bv->buffer(); - if (buf.isClean() && !buf.isUnnamed()) - return true; - - docstring const file = buf.fileName().displayName(30); - docstring title; - docstring text; - if (!buf.isUnnamed()) { - text = bformat(_("The document %1$s has unsaved " - "changes.\n\nDo you want to save " - "the document?"), file); - title = _("Save changed document?"); - - } else { - text = bformat(_("The document %1$s has not been " - "saved yet.\n\nDo you want to save " - "the document?"), file); - title = _("Save new document?"); - } - int const ret = Alert::prompt(title, text, 0, 1, _("&Save"), _("&Cancel")); + const bool verbose = (cmd.origin == FuncRequest::MENU + || cmd.origin == FuncRequest::TOOLBAR + || cmd.origin == FuncRequest::COMMANDBUFFER); - if (ret == 0) - lyx_view_->dispatch(FuncRequest(LFUN_BUFFER_WRITE)); + if (cmd.action == LFUN_SELF_INSERT || !verbose) { + LYXERR(Debug::ACTION, "dispatch msg is " << msg); + return msg; + } - return buf.isClean() && !buf.isUnnamed(); -} + docstring dispatch_msg = msg; + if (!dispatch_msg.empty()) + dispatch_msg += ' '; + docstring comname = from_utf8(lyxaction.getActionName(cmd.action)); -namespace { + bool argsadded = false; -bool loadLayoutFile(string const & name, string const & buf_path) -{ - if (!LayoutFileList::get().haveClass(name)) { - lyxerr << "Document class \"" << name - << "\" does not exist." - << endl; - return false; + if (!cmd.argument().empty()) { + if (cmd.action != LFUN_UNKNOWN_ACTION) { + comname += ' ' + cmd.argument(); + argsadded = true; + } } + docstring const shortcuts = theTopLevelKeymap(). + printBindings(cmd, KeySequence::ForGui); - LayoutFile & tc = LayoutFileList::get()[name]; - if (!tc.load(buf_path)) { - docstring s = bformat(_("The document class %1$s " - "could not be loaded."), from_utf8(name)); - Alert::error(_("Could not load class"), s); - return false; + if (!shortcuts.empty()) + comname += ": " + shortcuts; + else if (!argsadded && !cmd.argument().empty()) + comname += ' ' + cmd.argument(); + + if (!comname.empty()) { + comname = rtrim(comname); + dispatch_msg += '(' + rtrim(comname) + ')'; } - return true; + LYXERR(Debug::ACTION, "verbose dispatch msg " << to_utf8(dispatch_msg)); + return dispatch_msg; } -void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new); - -} //namespace anon - - void LyXFunc::dispatch(FuncRequest const & cmd) { string const argument = to_utf8(cmd.argument()); @@ -811,6 +354,8 @@ void LyXFunc::dispatch(FuncRequest const & cmd) //This is done unless explicitely requested otherwise Update::flags updateFlags = Update::FitCursor; + LyXView * lv = theApp()->currentWindow(); + FuncStatus const flag = getStatus(cmd); if (!flag.enabled()) { // We cannot use this function here @@ -818,552 +363,15 @@ void LyXFunc::dispatch(FuncRequest const & cmd) << lyxaction.getActionName(action) << " [" << action << "] is disabled at this location"); setErrorMessage(flag.message()); - if (lyx_view_) - lyx_view_->restartCursor(); + if (lv) + lv->restartCursor(); } else { - Buffer * buffer = 0; - if (lyx_view_ && lyx_view_->currentBufferView()) - buffer = &lyx_view_->currentBufferView()->buffer(); switch (action) { - case LFUN_WORD_FIND_FORWARD: - case LFUN_WORD_FIND_BACKWARD: { - LASSERT(lyx_view_ && lyx_view_->currentBufferView(), /**/); - static docstring last_search; - docstring searched_string; - - if (!cmd.argument().empty()) { - last_search = cmd.argument(); - searched_string = cmd.argument(); - } else { - searched_string = last_search; - } - - if (searched_string.empty()) - break; - - bool const fw = action == LFUN_WORD_FIND_FORWARD; - docstring const data = - find2string(searched_string, true, false, fw); - find(view(), FuncRequest(LFUN_WORD_FIND, data)); - break; - } - - case LFUN_COMMAND_PREFIX: - LASSERT(lyx_view_, /**/); - lyx_view_->message(keyseq.printOptions(true)); - break; - - case LFUN_CANCEL: - LASSERT(lyx_view_ && lyx_view_->currentBufferView(), /**/); - keyseq.reset(); - meta_fake_bit = NoModifier; - if (buffer) - // 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; - - case LFUN_BUFFER_TOGGLE_READ_ONLY: { - LASSERT(lyx_view_ && lyx_view_->currentBufferView() && buffer, /**/); - if (buffer->lyxvc().inUse()) - buffer->lyxvc().toggleReadOnly(); - else - buffer->setReadonly(!buffer->isReadonly()); - break; - } - - // --- Menus ----------------------------------------------- - case LFUN_BUFFER_CLOSE: - lyx_view_->closeBuffer(); - buffer = 0; - updateFlags = Update::None; - break; - - case LFUN_BUFFER_CLOSE_ALL: - lyx_view_->closeBufferAll(); - buffer = 0; - updateFlags = Update::None; - break; - - case LFUN_BUFFER_RELOAD: { - LASSERT(lyx_view_ && buffer, /**/); - docstring const file = makeDisplayPath(buffer->absFileName(), 20); - docstring text = bformat(_("Any changes will be lost. Are you sure " - "you want to revert to the saved version of the document %1$s?"), file); - int const ret = Alert::prompt(_("Revert to saved document?"), - text, 1, 1, _("&Revert"), _("&Cancel")); - - if (ret == 0) - reloadBuffer(); - break; - } - - case LFUN_BUFFER_UPDATE: { - LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/); - Buffer & doc_buffer = lyx_view_->documentBufferView()->buffer(); - string format = argument; - if (argument.empty()) - format = doc_buffer.getDefaultOutputFormat(); - doc_buffer.doExport(format, true); - break; - } - - case LFUN_BUFFER_VIEW: { - LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/); - Buffer & doc_buffer = lyx_view_->documentBufferView()->buffer(); - string format = argument; - if (argument.empty()) - format = doc_buffer.getDefaultOutputFormat(); - doc_buffer.preview(format); - break; - } - - case LFUN_MASTER_BUFFER_UPDATE: { - LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/); - Buffer & doc_buffer = lyx_view_->documentBufferView()->buffer(); - string format = argument; - if (argument.empty()) - format = doc_buffer.masterBuffer()->getDefaultOutputFormat(); - doc_buffer.masterBuffer()->doExport(format, true); - break; - } - - case LFUN_MASTER_BUFFER_VIEW: { - LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/); - Buffer & doc_buffer = lyx_view_->documentBufferView()->buffer(); - string format = argument; - if (argument.empty()) - format = doc_buffer.masterBuffer()->getDefaultOutputFormat(); - doc_buffer.masterBuffer()->preview(format); - break; - } - - case LFUN_BUILD_PROGRAM: - LASSERT(lyx_view_ && buffer, /**/); - buffer->doExport("program", true); - break; - - case LFUN_BUFFER_CHKTEX: - LASSERT(lyx_view_ && buffer, /**/); - buffer->runChktex(); - break; - - case LFUN_BUFFER_EXPORT: - LASSERT(lyx_view_ && buffer, /**/); - if (argument == "custom") - dispatch(FuncRequest(LFUN_DIALOG_SHOW, "sendto")); - else - buffer->doExport(argument, false); - break; - - case LFUN_BUFFER_EXPORT_CUSTOM: { - LASSERT(lyx_view_ && buffer, /**/); - string format_name; - string command = split(argument, format_name, ' '); - Format const * format = formats.getFormat(format_name); - if (!format) { - lyxerr << "Format \"" << format_name - << "\" not recognized!" - << endl; - break; - } - - // The name of the file created by the conversion process - string filename; - - // Output to filename - if (format->name() == "lyx") { - string const latexname = buffer->latexName(false); - filename = changeExtension(latexname, - format->extension()); - filename = addName(buffer->temppath(), filename); - - if (!buffer->writeFile(FileName(filename))) - break; - - } else { - buffer->doExport(format_name, true, filename); - } - - // Substitute $$FName for filename - if (!contains(command, "$$FName")) - command = "( " + command + " ) < $$FName"; - command = subst(command, "$$FName", filename); - - // Execute the command in the background - Systemcall call; - call.startscript(Systemcall::DontWait, command); - break; - } - - // FIXME: There is need for a command-line import. - /* - case LFUN_BUFFER_IMPORT: - doImport(argument); - break; - */ - - case LFUN_BUFFER_AUTO_SAVE: - buffer->autoSave(); - break; - - case LFUN_RECONFIGURE: - // argument is any additional parameter to the configure.py command - reconfigure(lyx_view_, argument); - break; - - case LFUN_HELP_OPEN: { - if (lyx_view_ == 0) - theApp()->dispatch(FuncRequest(LFUN_WINDOW_NEW)); - string const arg = argument; - if (arg.empty()) { - setErrorMessage(from_utf8(N_("Missing argument"))); - break; - } - FileName fname = i18nLibFileSearch("doc", arg, "lyx"); - if (fname.empty()) - fname = i18nLibFileSearch("examples", arg, "lyx"); - - if (fname.empty()) { - lyxerr << "LyX: unable to find documentation file `" - << arg << "'. Bad installation?" << endl; - break; - } - lyx_view_->message(bformat(_("Opening help file %1$s..."), - makeDisplayPath(fname.absFilename()))); - Buffer * buf = lyx_view_->loadDocument(fname, false); - if (buf) { - buf->updateLabels(); - lyx_view_->setBuffer(buf); - buf->errors("Parse"); - } - updateFlags = Update::None; - break; - } - - // --- version control ------------------------------- - case LFUN_VC_REGISTER: - LASSERT(lyx_view_ && buffer, /**/); - if (!ensureBufferClean(view())) - break; - if (!buffer->lyxvc().inUse()) { - if (buffer->lyxvc().registrer()) - reloadBuffer(); - } - updateFlags = Update::Force; - break; - - case LFUN_VC_CHECK_IN: - LASSERT(lyx_view_ && buffer, /**/); - if (!ensureBufferClean(view())) - break; - if (buffer->lyxvc().inUse() - && !buffer->isReadonly()) { - setMessage(from_utf8(buffer->lyxvc().checkIn())); - reloadBuffer(); - } - break; - - case LFUN_VC_CHECK_OUT: - LASSERT(lyx_view_ && buffer, /**/); - if (!ensureBufferClean(view())) - break; - if (buffer->lyxvc().inUse()) { - setMessage(from_utf8(buffer->lyxvc().checkOut())); - reloadBuffer(); - } - break; - - case LFUN_VC_LOCKING_TOGGLE: - LASSERT(lyx_view_ && buffer, /**/); - if (!ensureBufferClean(view()) || buffer->isReadonly()) - break; - if (buffer->lyxvc().inUse()) { - string res = buffer->lyxvc().lockingToggle(); - if (res.empty()) - frontend::Alert::error(_("Revision control error."), - _("Error when setting the locking property.")); - else { - setMessage(from_utf8(res)); - reloadBuffer(); - } - } - break; - - case LFUN_VC_REVERT: - LASSERT(lyx_view_ && buffer, /**/); - buffer->lyxvc().revert(); - reloadBuffer(); - break; - - case LFUN_VC_UNDO_LAST: - LASSERT(lyx_view_ && buffer, /**/); - buffer->lyxvc().undoLast(); - reloadBuffer(); - break; - - // --- lyxserver commands ---------------------------- - case LFUN_SERVER_GET_FILENAME: - LASSERT(lyx_view_ && buffer, /**/); - setMessage(from_utf8(buffer->absFileName())); - LYXERR(Debug::INFO, "FNAME[" - << buffer->absFileName() << ']'); - break; - - case LFUN_SERVER_NOTIFY: - dispatch_buffer = keyseq.print(KeySequence::Portable); - theServer().notifyClient(to_utf8(dispatch_buffer)); - break; - - case LFUN_SERVER_GOTO_FILE_ROW: { - LASSERT(lyx_view_, /**/); - string file_name; - int row; - istringstream is(argument); - is >> file_name >> row; - file_name = os::internal_path(file_name); - Buffer * buf = 0; - bool loaded = false; - string const abstmp = package().temp_dir().absFilename(); - string const realtmp = package().temp_dir().realPath(); - // We have to use os::path_prefix_is() here, instead of - // simply prefixIs(), because the file name comes from - // an external application and may need case adjustment. - if (os::path_prefix_is(file_name, abstmp, os::CASE_ADJUSTED) - || os::path_prefix_is(file_name, realtmp, os::CASE_ADJUSTED)) { - // Needed by inverse dvi search. If it is a file - // in tmpdir, call the apropriated function. - // If tmpdir is a symlink, we may have the real - // path passed back, so we correct for that. - if (!prefixIs(file_name, abstmp)) - file_name = subst(file_name, realtmp, abstmp); - buf = theBufferList().getBufferFromTmp(file_name); - } else { - // Must replace extension of the file to be .lyx - // and get full path - FileName const s = fileSearch(string(), changeExtension(file_name, ".lyx"), "lyx"); - // Either change buffer or load the file - if (theBufferList().exists(s)) - buf = theBufferList().getBuffer(s); - else if (s.exists()) { - buf = lyx_view_->loadDocument(s); - loaded = true; - } else - lyx_view_->message(bformat( - _("File does not exist: %1$s"), - makeDisplayPath(file_name))); - } - - if (!buf) { - updateFlags = Update::None; - break; - } - - buf->updateLabels(); - lyx_view_->setBuffer(buf); - view()->setCursorFromRow(row); - if (loaded) - buf->errors("Parse"); - updateFlags = Update::FitCursor; - break; - } - - - case LFUN_DIALOG_SHOW_NEW_INSET: { - LASSERT(lyx_view_, /**/); - string const name = cmd.getArg(0); - InsetCode code = insetCode(name); - string data = trim(to_utf8(cmd.argument()).substr(name.size())); - bool insetCodeOK = true; - switch (code) { - case BIBITEM_CODE: - case BIBTEX_CODE: - case INDEX_CODE: - case LABEL_CODE: - case NOMENCL_CODE: - case NOMENCL_PRINT_CODE: - case REF_CODE: - case TOC_CODE: - case HYPERLINK_CODE: { - InsetCommandParams p(code); - data = InsetCommand::params2string(name, p); - break; - } - case INCLUDE_CODE: { - // data is the include type: one of "include", - // "input", "verbatiminput" or "verbatiminput*" - if (data.empty()) - // default type is requested - data = "include"; - InsetCommandParams p(INCLUDE_CODE, data); - data = InsetCommand::params2string("include", p); - break; - } - case BOX_CODE: { - // \c data == "Boxed" || "Frameless" etc - InsetBoxParams p(data); - data = InsetBox::params2string(p); - break; - } - case BRANCH_CODE: { - InsetBranchParams p; - data = InsetBranch::params2string(p); - break; - } - case CITE_CODE: { - InsetCommandParams p(CITE_CODE); - data = InsetCommand::params2string(name, p); - break; - } - case ERT_CODE: { - data = InsetERT::params2string(InsetCollapsable::Open); - break; - } - case EXTERNAL_CODE: { - InsetExternalParams p; - data = InsetExternal::params2string(p, *buffer); - break; - } - case FLOAT_CODE: { - InsetFloatParams p; - data = InsetFloat::params2string(p); - break; - } - case LISTINGS_CODE: { - InsetListingsParams p; - data = InsetListings::params2string(p); - break; - } - case GRAPHICS_CODE: { - InsetGraphicsParams p; - data = InsetGraphics::params2string(p, *buffer); - break; - } - case NOTE_CODE: { - InsetNoteParams p; - data = InsetNote::params2string(p); - break; - } - case PHANTOM_CODE: { - InsetPhantomParams p; - data = InsetPhantom::params2string(p); - break; - } - case SPACE_CODE: { - InsetSpaceParams p; - data = InsetSpace::params2string(p); - break; - } - case VSPACE_CODE: { - VSpace space; - data = InsetVSpace::params2string(space); - break; - } - case WRAP_CODE: { - InsetWrapParams p; - data = InsetWrap::params2string(p); - break; - } - default: - lyxerr << "Inset type '" << name << - "' not recognized in LFUN_DIALOG_SHOW_NEW_INSET" << endl; - insetCodeOK = false; - break; - } // end switch(code) - if (insetCodeOK) - dispatch(FuncRequest(LFUN_DIALOG_SHOW, name + " " + data)); - break; - } - - case LFUN_CITATION_INSERT: { - LASSERT(lyx_view_, /**/); - if (!argument.empty()) { - // we can have one optional argument, delimited by '|' - // citation-insert | - // this should be enhanced to also support text_after - // and citation style - string arg = argument; - string opt1; - if (contains(argument, "|")) { - arg = token(argument, '|', 0); - opt1 = token(argument, '|', 1); - } - InsetCommandParams icp(CITE_CODE); - icp["key"] = from_utf8(arg); - if (!opt1.empty()) - icp["before"] = from_utf8(opt1); - string icstr = InsetCommand::params2string("citation", icp); - FuncRequest fr(LFUN_INSET_INSERT, icstr); - dispatch(fr); - } else - dispatch(FuncRequest(LFUN_DIALOG_SHOW_NEW_INSET, "citation")); - break; - } - - case LFUN_BUFFER_CHILD_OPEN: { - LASSERT(lyx_view_ && buffer, /**/); - FileName filename = makeAbsPath(argument, buffer->filePath()); - view()->saveBookmark(false); - Buffer * child = 0; - bool parsed = false; - if (theBufferList().exists(filename)) { - child = theBufferList().getBuffer(filename); - } else { - setMessage(bformat(_("Opening child document %1$s..."), - makeDisplayPath(filename.absFilename()))); - child = lyx_view_->loadDocument(filename, false); - parsed = true; - } - if (child) { - // Set the parent name of the child document. - // This makes insertion of citations and references in the child work, - // when the target is in the parent or another child document. - child->setParent(buffer); - child->masterBuffer()->updateLabels(); - lyx_view_->setBuffer(child); - if (parsed) - child->errors("Parse"); - } - - // If a screen update is required (in case where auto_open is false), - // setBuffer() would have taken care of it already. Otherwise we shall - // reset the update flag because it can cause a circular problem. - // See bug 3970. - updateFlags = Update::None; - break; - } - case LFUN_CURSOR_FOLLOWS_SCROLLBAR_TOGGLE: - LASSERT(lyx_view_, /**/); lyxrc.cursor_follows_scrollbar = !lyxrc.cursor_follows_scrollbar; break; - case LFUN_KEYMAP_OFF: - LASSERT(lyx_view_ && lyx_view_->currentBufferView(), /**/); - lyx_view_->currentBufferView()->getIntl().keyMapOn(false); - break; - - case LFUN_KEYMAP_PRIMARY: - LASSERT(lyx_view_ && lyx_view_->currentBufferView(), /**/); - lyx_view_->currentBufferView()->getIntl().keyMapPrim(); - break; - - case LFUN_KEYMAP_SECONDARY: - LASSERT(lyx_view_ && lyx_view_->currentBufferView(), /**/); - lyx_view_->currentBufferView()->getIntl().keyMapSec(); - break; - - case LFUN_KEYMAP_TOGGLE: - LASSERT(lyx_view_ && lyx_view_->currentBufferView(), /**/); - lyx_view_->currentBufferView()->getIntl().toggleKeyMap(); - break; - case LFUN_REPEAT: { // repeat command string countstr; @@ -1380,7 +388,10 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_COMMAND_SEQUENCE: { // argument contains ';'-terminated commands string arg = argument; - if (theBufferList().isLoaded(buffer)) + // FIXME: this LFUN should also work without any view. + Buffer * buffer = (lv && lv->documentBufferView()) + ? &(lv->documentBufferView()->buffer()) : 0; + if (buffer) buffer->undo().beginUndoGroup(); while (!arg.empty()) { string first; @@ -1389,6 +400,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) func.origin = cmd.origin; dispatch(func); } + // the buffer may have been closed by one action if (theBufferList().isLoaded(buffer)) buffer->undo().endUndoGroup(); break; @@ -1440,24 +452,6 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; } - case LFUN_MESSAGE: - LASSERT(lyx_view_, /**/); - lyx_view_->message(from_utf8(argument)); - break; - - case LFUN_BUFFER_LANGUAGE: { - LASSERT(lyx_view_, /**/); - Language const * oldL = buffer->params().language; - Language const * newL = languages.getLanguage(argument); - if (!newL || oldL == newL) - break; - - if (oldL->rightToLeft() == newL->rightToLeft() - && !buffer->isMultiLingual()) - buffer->changeLanguage(oldL, newL); - break; - } - case LFUN_BUFFER_SAVE_AS_DEFAULT: { string const fname = addName(addPath(package().user_support().absFilename(), "templates/"), @@ -1484,135 +478,6 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; } - case LFUN_BUFFER_PARAMS_APPLY: { - LASSERT(lyx_view_, /**/); - - DocumentClass const * const oldClass = buffer->params().documentClassPtr(); - Cursor & cur = view()->cursor(); - cur.recordUndoFullDocument(); - - istringstream ss(argument); - Lexer lex; - lex.setStream(ss); - int const unknown_tokens = buffer->readHeader(lex); - - if (unknown_tokens != 0) { - lyxerr << "Warning in LFUN_BUFFER_PARAMS_APPLY!\n" - << unknown_tokens << " unknown token" - << (unknown_tokens == 1 ? "" : "s") - << endl; - } - - updateLayout(oldClass, buffer); - - updateFlags = Update::Force | Update::FitCursor; - // We are most certainly here because of a change in the document - // It is then better to make sure that all dialogs are in sync with - // current document settings. LyXView::restartCursor() achieve this. - lyx_view_->restartCursor(); - break; - } - - case LFUN_LAYOUT_MODULES_CLEAR: { - LASSERT(lyx_view_, /**/); - DocumentClass const * const oldClass = buffer->params().documentClassPtr(); - view()->cursor().recordUndoFullDocument(); - buffer->params().clearLayoutModules(); - buffer->params().makeDocumentClass(); - updateLayout(oldClass, buffer); - updateFlags = Update::Force | Update::FitCursor; - break; - } - - case LFUN_LAYOUT_MODULE_ADD: { - LASSERT(lyx_view_, /**/); - BufferParams const & params = buffer->params(); - if (!params.moduleCanBeAdded(argument)) { - LYXERR0("Module `" << argument << - "' cannot be added due to failed requirements or " - "conflicts with installed modules."); - break; - } - DocumentClass const * const oldClass = params.documentClassPtr(); - view()->cursor().recordUndoFullDocument(); - buffer->params().addLayoutModule(argument); - buffer->params().makeDocumentClass(); - updateLayout(oldClass, buffer); - updateFlags = Update::Force | Update::FitCursor; - break; - } - - case LFUN_TEXTCLASS_APPLY: { - LASSERT(lyx_view_, /**/); - - if (!loadLayoutFile(argument, buffer->temppath()) && - !loadLayoutFile(argument, buffer->filePath())) - break; - - LayoutFile const * old_layout = buffer->params().baseClass(); - LayoutFile const * new_layout = &(LayoutFileList::get()[argument]); - - if (old_layout == new_layout) - // nothing to do - break; - - //Save the old, possibly modular, layout for use in conversion. - DocumentClass const * const oldDocClass = buffer->params().documentClassPtr(); - view()->cursor().recordUndoFullDocument(); - buffer->params().setBaseClass(argument); - buffer->params().makeDocumentClass(); - updateLayout(oldDocClass, buffer); - updateFlags = Update::Force | Update::FitCursor; - break; - } - - case LFUN_LAYOUT_RELOAD: { - LASSERT(lyx_view_, /**/); - DocumentClass const * const oldClass = buffer->params().documentClassPtr(); - LayoutFileIndex bc = buffer->params().baseClassID(); - LayoutFileList::get().reset(bc); - buffer->params().setBaseClass(bc); - buffer->params().makeDocumentClass(); - updateLayout(oldClass, buffer); - updateFlags = Update::Force | Update::FitCursor; - break; - } - - case LFUN_TEXTCLASS_LOAD: - loadLayoutFile(argument, buffer->temppath()) || - loadLayoutFile(argument, buffer->filePath()); - 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); @@ -1623,238 +488,127 @@ void LyXFunc::dispatch(FuncRequest const & cmd) theSession().bookmarks().clear(); break; - case LFUN_VC_COMMAND: { - string flag = cmd.getArg(0); - if (buffer && contains(flag, 'R') && !ensureBufferClean(view())) - break; - docstring message; - if (contains(flag, 'M')) - if (!Alert::askForText(message, _("LyX VC: Log Message"))) - break; - - string path = cmd.getArg(1); - if (contains(path, "$$p") && buffer) - path = subst(path, "$$p", buffer->filePath()); - LYXERR(Debug::LYXVC, "Directory: " << path); - FileName pp(path); - if (!pp.isReadableDirectory()) { - lyxerr << _("Directory is not accessible.") << endl; - break; - } - support::PathChanger p(pp); - - string command = cmd.getArg(2); - if (command.empty()) - break; - if (buffer) { - command = subst(command, "$$i", buffer->absFileName()); - command = subst(command, "$$p", buffer->filePath()); - } - command = subst(command, "$$m", to_utf8(message)); - LYXERR(Debug::LYXVC, "Command: " << command); - Systemcall one; - one.startscript(Systemcall::Wait, command); - - if (!buffer) - break; - if (contains(flag, 'I')) - buffer->markDirty(); - if (contains(flag, 'R')) - reloadBuffer(); - + case LFUN_DEBUG_LEVEL_SET: + lyxerr.setLevel(Debug::value(to_utf8(cmd.argument()))); 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 lyx_view_ - if (lyx_view_ == 0) + // Everything below is only for active window + if (lv == 0) break; - // Start an undo group. This may be needed for - // some stuff like inset-apply on labels. - if (theBufferList().isLoaded(buffer)) - buffer->undo().beginUndoGroup(); - // Let the current LyXView dispatch its own actions. - if (lyx_view_->dispatch(cmd)) { - if (lyx_view_->currentBufferView()) { - updateFlags = lyx_view_->currentBufferView()->cursor().result().update(); - if (theBufferList().isLoaded(buffer)) - buffer->undo().endUndoGroup(); - } + if (lv->dispatch(cmd)) { + BufferView * bv = lv->currentBufferView(); + if (bv) + updateFlags = bv->cursor().result().update(); break; } - LASSERT(lyx_view_->currentBufferView(), /**/); + BufferView * bv = lv->currentBufferView(); + LASSERT(bv, /**/); // Let the current BufferView dispatch its own actions. - if (view()->dispatch(cmd)) { + if (bv->dispatch(cmd)) { // The BufferView took care of its own updates if needed. updateFlags = Update::None; - if (theBufferList().isLoaded(buffer)) - buffer->undo().endUndoGroup(); break; } - // OK, so try the Buffer itself - DispatchResult dr; - view()->buffer().dispatch(cmd, dr); + BufferView * doc_bv = lv->documentBufferView(); + // Try with the document BufferView dispatch if any. + if (doc_bv && doc_bv->dispatch(cmd)) { + updateFlags = Update::None; + break; + } + + // OK, so try the current Buffer itself... + bv->buffer().dispatch(cmd, dr); if (dr.dispatched()) { updateFlags = dr.update(); break; } - - // Is this a function that acts on inset at point? - Inset * inset = view()->cursor().nextInset(); - if (lyxaction.funcHasFlag(action, LyXAction::AtPoint) - && inset) { - view()->cursor().result().dispatched(true); - view()->cursor().result().update(Update::FitCursor | Update::Force); - FuncRequest tmpcmd = cmd; - inset->dispatch(view()->cursor(), tmpcmd); - if (view()->cursor().result().dispatched()) { - updateFlags = view()->cursor().result().update(); + // and with the document Buffer. + if (doc_bv) { + doc_bv->buffer().dispatch(cmd, dr); + if (dr.dispatched()) { + updateFlags = dr.update(); break; } } // Let the current Cursor dispatch its own actions. - Cursor old = view()->cursor(); - view()->cursor().getPos(cursorPosBeforeDispatchX_, + Cursor old = bv->cursor(); + bv->cursor().getPos(cursorPosBeforeDispatchX_, cursorPosBeforeDispatchY_); - view()->cursor().dispatch(cmd); + bv->cursor().dispatch(cmd); // notify insets we just left - if (view()->cursor() != old) { + if (bv->cursor() != old) { old.fixIfBroken(); - bool badcursor = notifyCursorLeavesOrEnters(old, view()->cursor()); + bool badcursor = notifyCursorLeavesOrEnters(old, bv->cursor()); if (badcursor) - view()->cursor().fixIfBroken(); + bv->cursor().fixIfBroken(); } - if (theBufferList().isLoaded(buffer)) - buffer->undo().endUndoGroup(); - // update completion. We do it here and not in // processKeySym to avoid another redraw just for a // changed inline completion if (cmd.origin == FuncRequest::KEYBOARD) { if (cmd.action == LFUN_SELF_INSERT - || (cmd.action == LFUN_ERT_INSERT && view()->cursor().inMathed())) - lyx_view_->updateCompletion(view()->cursor(), true, true); + || (cmd.action == LFUN_ERT_INSERT && bv->cursor().inMathed())) + lv->updateCompletion(bv->cursor(), true, true); else if (cmd.action == LFUN_CHAR_DELETE_BACKWARD) - lyx_view_->updateCompletion(view()->cursor(), false, true); + lv->updateCompletion(bv->cursor(), false, true); else - lyx_view_->updateCompletion(view()->cursor(), false, false); + lv->updateCompletion(bv->cursor(), false, false); } - updateFlags = view()->cursor().result().update(); + updateFlags = bv->cursor().result().update(); } // if we executed a mutating lfun, mark the buffer as dirty - if (theBufferList().isLoaded(buffer) && flag.enabled() + Buffer * doc_buffer = (lv && lv->documentBufferView()) + ? &(lv->documentBufferView()->buffer()) : 0; + if (doc_buffer && theBufferList().isLoaded(doc_buffer) + && flag.enabled() && !lyxaction.funcHasFlag(action, LyXAction::NoBuffer) && !lyxaction.funcHasFlag(action, LyXAction::ReadOnly)) - buffer->markDirty(); + lv->currentBufferView()->buffer().markDirty(); - if (lyx_view_ && lyx_view_->currentBufferView()) { + if (lv && lv->currentBufferView()) { // BufferView::update() updates the ViewMetricsInfo and // also initializes the position cache for all insets in // (at least partially) visible top-level paragraphs. // We will redraw the screen only if needed. - view()->processUpdateFlags(updateFlags); + lv->currentBufferView()->processUpdateFlags(updateFlags); // Do we have a selection? - theSelection().haveSelection(view()->cursor().selection()); + theSelection().haveSelection( + lv->currentBufferView()->cursor().selection()); // update gui - lyx_view_->restartCursor(); + lv->restartCursor(); } } - if (lyx_view_) { + if (lv) { // Some messages may already be translated, so we cannot use _() - sendDispatchMessage(translateIfPossible(getMessage()), cmd); + lv->message(sendDispatchMessage( + translateIfPossible(getMessage()), cmd)); } } -void LyXFunc::sendDispatchMessage(docstring const & msg, FuncRequest const & cmd) -{ - const bool verbose = (cmd.origin == FuncRequest::MENU - || cmd.origin == FuncRequest::TOOLBAR - || cmd.origin == FuncRequest::COMMANDBUFFER); - - if (cmd.action == LFUN_SELF_INSERT || !verbose) { - LYXERR(Debug::ACTION, "dispatch msg is " << to_utf8(msg)); - if (!msg.empty()) - lyx_view_->message(msg); - return; - } - - docstring dispatch_msg = msg; - if (!dispatch_msg.empty()) - dispatch_msg += ' '; - - docstring comname = from_utf8(lyxaction.getActionName(cmd.action)); - - bool argsadded = false; - - if (!cmd.argument().empty()) { - if (cmd.action != LFUN_UNKNOWN_ACTION) { - comname += ' ' + cmd.argument(); - argsadded = true; - } - } - - docstring const shortcuts = theTopLevelKeymap().printBindings(cmd, KeySequence::ForGui); - - if (!shortcuts.empty()) - comname += ": " + shortcuts; - else if (!argsadded && !cmd.argument().empty()) - comname += ' ' + cmd.argument(); - - if (!comname.empty()) { - comname = rtrim(comname); - dispatch_msg += '(' + rtrim(comname) + ')'; - } - - LYXERR(Debug::ACTION, "verbose dispatch msg " << to_utf8(dispatch_msg)); - if (!dispatch_msg.empty()) - lyx_view_->message(dispatch_msg); -} - - -void LyXFunc::reloadBuffer() -{ - Buffer * buf = &lyx_view_->documentBufferView()->buffer(); - FileName filename = buf->fileName(); - // The user has already confirmed that the changes, if any, should - // be discarded. So we just release the Buffer and don't call closeBuffer(); - theBufferList().release(buf); - // if the lyx_view_ has been destroyed, create a new one - if (!lyx_view_) - theApp()->dispatch(FuncRequest(LFUN_WINDOW_NEW)); - buf = lyx_view_->loadDocument(filename); - docstring const disp_fn = makeDisplayPath(filename.absFilename()); - docstring str; - if (buf) { - buf->updateLabels(); - lyx_view_->setBuffer(buf); - buf->errors("Parse"); - str = bformat(_("Document %1$s reloaded."), disp_fn); - } else { - str = bformat(_("Could not reload document %1$s"), disp_fn); - } - lyx_view_->message(str); -} - -// Each "lyx_view_" should have it's own message method. lyxview and +// Each LyXView should have it's own message method. lyxview and // the minibuffer would use the minibuffer, but lyxserver would // send an ERROR signal to its client. Alejandro 970603 // This function is bit problematic when it comes to NLS, to make the @@ -1873,222 +627,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); - - LASSERT(lyx_view_, /**/); - if (!lyx_view_->currentBufferView()) - return _("Welcome to LyX!"); - - return view()->cursor().currentState(); -} - - -BufferView * LyXFunc::view() const -{ - LASSERT(lyx_view_, /**/); - return lyx_view_->currentBufferView(); -} - - -bool LyXFunc::wasMetaKey() const -{ - return (meta_fake_bit != NoModifier); -} - - -void LyXFunc::updateLayout(DocumentClass const * const oldlayout, Buffer * buf) -{ - lyx_view_->message(_("Converting document to new document class...")); - - StableDocIterator backcur(view()->cursor()); - ErrorList & el = buf->errorList("Class Switch"); - cap::switchBetweenClasses( - oldlayout, buf->params().documentClassPtr(), - static_cast(buf->inset()), el); - - view()->setCursor(backcur.asDocIterator(buf)); - - buf->errors("Class Switch"); - buf->updateLabels(); -} - - -namespace { - -void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new) -{ - // Why the switch you might ask. It is a trick to ensure that all - // the elements in the LyXRCTags enum is handled. As you can see - // there are no breaks at all. So it is just a huge fall-through. - // The nice thing is that we will get a warning from the compiler - // if we forget an element. - LyXRC::LyXRCTags tag = LyXRC::RC_LAST; - switch (tag) { - case LyXRC::RC_ACCEPT_COMPOUND: - case LyXRC::RC_ALT_LANG: - case LyXRC::RC_PLAINTEXT_LINELEN: - case LyXRC::RC_PLAINTEXT_ROFF_COMMAND: - case LyXRC::RC_AUTOCORRECTION_MATH: - case LyXRC::RC_AUTOREGIONDELETE: - case LyXRC::RC_AUTORESET_OPTIONS: - case LyXRC::RC_AUTOSAVE: - case LyXRC::RC_AUTO_NUMBER: - case LyXRC::RC_BACKUPDIR_PATH: - case LyXRC::RC_BIBTEX_ALTERNATIVES: - case LyXRC::RC_BIBTEX_COMMAND: - case LyXRC::RC_BINDFILE: - case LyXRC::RC_CHECKLASTFILES: - case LyXRC::RC_COMPLETION_CURSOR_TEXT: - case LyXRC::RC_COMPLETION_INLINE_DELAY: - case LyXRC::RC_COMPLETION_INLINE_DOTS: - case LyXRC::RC_COMPLETION_INLINE_MATH: - case LyXRC::RC_COMPLETION_INLINE_TEXT: - case LyXRC::RC_COMPLETION_POPUP_AFTER_COMPLETE: - case LyXRC::RC_COMPLETION_POPUP_DELAY: - case LyXRC::RC_COMPLETION_POPUP_MATH: - case LyXRC::RC_COMPLETION_POPUP_TEXT: - case LyXRC::RC_USELASTFILEPOS: - case LyXRC::RC_LOADSESSION: - case LyXRC::RC_CHKTEX_COMMAND: - case LyXRC::RC_CONVERTER: - case LyXRC::RC_CONVERTER_CACHE_MAXAGE: - case LyXRC::RC_COPIER: - case LyXRC::RC_CURSOR_FOLLOWS_SCROLLBAR: - case LyXRC::RC_SCROLL_BELOW_DOCUMENT: - case LyXRC::RC_DATE_INSERT_FORMAT: - case LyXRC::RC_DEFAULT_LANGUAGE: - case LyXRC::RC_GUI_LANGUAGE: - case LyXRC::RC_DEFAULT_PAPERSIZE: - case LyXRC::RC_DEFAULT_VIEW_FORMAT: - case LyXRC::RC_DEFFILE: - case LyXRC::RC_DIALOGS_ICONIFY_WITH_MAIN: - case LyXRC::RC_DISPLAY_GRAPHICS: - case LyXRC::RC_DOCUMENTPATH: - if (lyxrc_orig.document_path != lyxrc_new.document_path) { - FileName path(lyxrc_new.document_path); - if (path.exists() && path.isDirectory()) - package().document_dir() = FileName(lyxrc.document_path); - } - case LyXRC::RC_ESC_CHARS: - case LyXRC::RC_EXAMPLEPATH: - case LyXRC::RC_FONT_ENCODING: - case LyXRC::RC_FORMAT: - case LyXRC::RC_GROUP_LAYOUTS: - case LyXRC::RC_HUNSPELLDIR_PATH: - case LyXRC::RC_INDEX_ALTERNATIVES: - case LyXRC::RC_INDEX_COMMAND: - case LyXRC::RC_JBIBTEX_COMMAND: - case LyXRC::RC_JINDEX_COMMAND: - case LyXRC::RC_NOMENCL_COMMAND: - case LyXRC::RC_INPUT: - case LyXRC::RC_KBMAP: - case LyXRC::RC_KBMAP_PRIMARY: - case LyXRC::RC_KBMAP_SECONDARY: - case LyXRC::RC_LABEL_INIT_LENGTH: - case LyXRC::RC_LANGUAGE_AUTO_BEGIN: - case LyXRC::RC_LANGUAGE_AUTO_END: - case LyXRC::RC_LANGUAGE_COMMAND_BEGIN: - case LyXRC::RC_LANGUAGE_COMMAND_END: - case LyXRC::RC_LANGUAGE_COMMAND_LOCAL: - case LyXRC::RC_LANGUAGE_GLOBAL_OPTIONS: - case LyXRC::RC_LANGUAGE_PACKAGE: - case LyXRC::RC_LANGUAGE_USE_BABEL: - case LyXRC::RC_MAC_LIKE_WORD_MOVEMENT: - case LyXRC::RC_MACRO_EDIT_STYLE: - case LyXRC::RC_MAKE_BACKUP: - case LyXRC::RC_MARK_FOREIGN_LANGUAGE: - case LyXRC::RC_MOUSE_WHEEL_SPEED: - case LyXRC::RC_NUMLASTFILES: - case LyXRC::RC_PARAGRAPH_MARKERS: - case LyXRC::RC_PATH_PREFIX: - if (lyxrc_orig.path_prefix != lyxrc_new.path_prefix) { - prependEnvPath("PATH", lyxrc.path_prefix); - } - case LyXRC::RC_PERS_DICT: - case LyXRC::RC_PREVIEW: - case LyXRC::RC_PREVIEW_HASHED_LABELS: - case LyXRC::RC_PREVIEW_SCALE_FACTOR: - case LyXRC::RC_PRINTCOLLCOPIESFLAG: - case LyXRC::RC_PRINTCOPIESFLAG: - case LyXRC::RC_PRINTER: - case LyXRC::RC_PRINTEVENPAGEFLAG: - case LyXRC::RC_PRINTEXSTRAOPTIONS: - case LyXRC::RC_PRINTFILEEXTENSION: - case LyXRC::RC_PRINTLANDSCAPEFLAG: - case LyXRC::RC_PRINTODDPAGEFLAG: - case LyXRC::RC_PRINTPAGERANGEFLAG: - case LyXRC::RC_PRINTPAPERDIMENSIONFLAG: - case LyXRC::RC_PRINTPAPERFLAG: - case LyXRC::RC_PRINTREVERSEFLAG: - case LyXRC::RC_PRINTSPOOL_COMMAND: - case LyXRC::RC_PRINTSPOOL_PRINTERPREFIX: - case LyXRC::RC_PRINTTOFILE: - case LyXRC::RC_PRINTTOPRINTER: - case LyXRC::RC_PRINT_ADAPTOUTPUT: - case LyXRC::RC_PRINT_COMMAND: - case LyXRC::RC_RTL_SUPPORT: - case LyXRC::RC_SCREEN_DPI: - case LyXRC::RC_SCREEN_FONT_ROMAN: - case LyXRC::RC_SCREEN_FONT_ROMAN_FOUNDRY: - case LyXRC::RC_SCREEN_FONT_SANS: - case LyXRC::RC_SCREEN_FONT_SANS_FOUNDRY: - case LyXRC::RC_SCREEN_FONT_SCALABLE: - case LyXRC::RC_SCREEN_FONT_SIZES: - case LyXRC::RC_SCREEN_FONT_TYPEWRITER: - case LyXRC::RC_SCREEN_FONT_TYPEWRITER_FOUNDRY: - case LyXRC::RC_GEOMETRY_SESSION: - case LyXRC::RC_SCREEN_ZOOM: - case LyXRC::RC_SERVERPIPE: - case LyXRC::RC_SET_COLOR: - case LyXRC::RC_SHOW_BANNER: - case LyXRC::RC_OPEN_BUFFERS_IN_TABS: - case LyXRC::RC_SPELL_COMMAND: - case LyXRC::RC_SPELLCHECKER: - case LyXRC::RC_SPELLCHECK_CONTINUOUSLY: - case LyXRC::RC_SPLITINDEX_COMMAND: - case LyXRC::RC_TEMPDIRPATH: - case LyXRC::RC_TEMPLATEPATH: - case LyXRC::RC_TEX_ALLOWS_SPACES: - case LyXRC::RC_TEX_EXPECTS_WINDOWS_PATHS: - if (lyxrc_orig.windows_style_tex_paths != lyxrc_new.windows_style_tex_paths) { - os::windows_style_tex_paths(lyxrc_new.windows_style_tex_paths); - } - case LyXRC::RC_THESAURUSDIRPATH: - case LyXRC::RC_UIFILE: - case LyXRC::RC_USER_EMAIL: - case LyXRC::RC_USER_NAME: - case LyXRC::RC_USETEMPDIR: - case LyXRC::RC_USE_ALT_LANG: - case LyXRC::RC_USE_CONVERTER_CACHE: - case LyXRC::RC_USE_ESC_CHARS: - case LyXRC::RC_USE_INP_ENC: - case LyXRC::RC_USE_PERS_DICT: - case LyXRC::RC_USE_TOOLTIP: - case LyXRC::RC_USE_PIXMAP_CACHE: - case LyXRC::RC_USE_SPELL_LIB: - case LyXRC::RC_VIEWDVI_PAPEROPTION: - case LyXRC::RC_SORT_LAYOUTS: - case LyXRC::RC_FULL_SCREEN_LIMIT: - case LyXRC::RC_FULL_SCREEN_SCROLLBAR: - case LyXRC::RC_FULL_SCREEN_MENUBAR: - case LyXRC::RC_FULL_SCREEN_TABBAR: - case LyXRC::RC_FULL_SCREEN_TOOLBARS: - case LyXRC::RC_FULL_SCREEN_WIDTH: - case LyXRC::RC_VISUAL_CURSOR: - case LyXRC::RC_VIEWER: - case LyXRC::RC_LAST: - break; - } -} - -} // namespace anon } // namespace lyx