X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Flyxfunc.C;h=7de71684d5d8267f2de39d929e5b4b88325e2ce3;hb=35204f8f33d7400a5fefeffea533fb4cb4097211;hp=771d8019172a643bb9b0bd0607c5a8efd59aa35f;hpb=37e164c6f9e792e51ceac0ad58885ee5b3758330;p=lyx.git diff --git a/src/lyxfunc.C b/src/lyxfunc.C index 771d801917..7de71684d5 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -78,6 +78,7 @@ #include "frontends/Dialogs.h" #include "frontends/FileDialog.h" #include "frontends/FontLoader.h" +#include "frontends/Gui.h" #include "frontends/LyXKeySym.h" #include "frontends/LyXView.h" #include "frontends/Menubar.h" @@ -228,8 +229,8 @@ void LyXFunc::handleKeyFunc(kb_action action) if (keyseq->length()) c = 0; - lyx_view_->view()->getIntl().getTransManager() - .deadkey(c, get_accent(action).accent, view()->getLyXText()); + lyx_view_->view()->getIntl().getTransManager().deadkey( + c, get_accent(action).accent, view()->getLyXText(), view()->cursor()); // Need to clear, in case the minibuffer calls these // actions keyseq->clear(); @@ -346,6 +347,25 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const { //lyxerr << "LyXFunc::getStatus: cmd: " << cmd << endl; FuncStatus flag; + + if (cmd.action == LFUN_LYX_QUIT) { + flag.message(from_utf8(N_("Exiting"))); + flag.enabled(true); + return flag; + } else if (cmd.action == LFUN_BOOKMARK_GOTO) { + // bookmarks can be valid even if there is no opened buffer + flag.enabled(LyX::ref().session().bookmarks().isValid(convert(to_utf8(cmd.argument())))); + return flag; + } else if (cmd.action == LFUN_BOOKMARK_CLEAR) { + flag.enabled(LyX::ref().session().bookmarks().size() > 0); + return flag; + } else if (cmd.action == LFUN_TOOLBAR_TOGGLE_STATE) { + ToolbarBackend::Flags flags = lyx_view_->getToolbarState(to_utf8(cmd.argument())); + if (!(flags & ToolbarBackend::AUTO)) + flag.setOnOff(flags & ToolbarBackend::ON); + return flag; + } + LCursor & cur = view()->cursor(); /* In LyX/Mac, when a dialog is open, the menus of the @@ -357,7 +377,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const http://bugzilla.lyx.org/show_bug.cgi?id=1941#c4 */ Buffer * buf; - if (cmd.origin == FuncRequest::UI && !lyx_view_->hasFocus()) + if (cmd.origin == FuncRequest::MENU && !lyx_view_->hasFocus()) buf = 0; else buf = lyx_view_->buffer(); @@ -557,6 +577,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const break; } + // this one is difficult to get right. As a half-baked // solution, we consider only the first action of the sequence case LFUN_COMMAND_SEQUENCE: { @@ -580,7 +601,6 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const case LFUN_BUFFER_UPDATE: case LFUN_BUFFER_VIEW: case LFUN_BUFFER_IMPORT: - case LFUN_LYX_QUIT: case LFUN_TOC_VIEW: case LFUN_BUFFER_AUTO_SAVE: case LFUN_RECONFIGURE: @@ -619,6 +639,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const case LFUN_BUFFER_NEXT: case LFUN_BUFFER_PREVIOUS: case LFUN_WINDOW_NEW: + case LFUN_WINDOW_CLOSE: // these are handled in our dispatch() break; @@ -716,7 +737,6 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new); void LyXFunc::dispatch(FuncRequest const & cmd) { - BOOST_ASSERT(view()); string const argument = to_utf8(cmd.argument()); kb_action const action = cmd.action; @@ -744,6 +764,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_WORD_FIND_FORWARD: case LFUN_WORD_FIND_BACKWARD: { + BOOST_ASSERT(lyx_view_ && lyx_view_->view()); static string last_search; string searched_string; @@ -765,15 +786,18 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_COMMAND_PREFIX: + BOOST_ASSERT(lyx_view_); lyx_view_->message(from_utf8(keyseq->printOptions())); break; case LFUN_COMMAND_EXECUTE: + BOOST_ASSERT(lyx_view_); lyx_view_->getToolbars().display("minibuffer", true); lyx_view_->focus_command_buffer(); break; case LFUN_CANCEL: + BOOST_ASSERT(lyx_view_ && lyx_view_->view()); keyseq->reset(); meta_fake_bit = key_modifier::none; if (view()->buffer()) @@ -788,6 +812,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; case LFUN_BUFFER_TOGGLE_READ_ONLY: + BOOST_ASSERT(lyx_view_ && lyx_view_->view() && lyx_view_->buffer()); if (lyx_view_->buffer()->lyxvc().inUse()) lyx_view_->buffer()->lyxvc().toggleReadOnly(); else @@ -806,9 +831,11 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_BUFFER_CLOSE: closeBuffer(); + view()->update(); break; case LFUN_BUFFER_WRITE: + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); if (!lyx_view_->buffer()->isUnnamed()) { docstring const str = bformat(_("Saving document %1$s..."), makeDisplayPath(lyx_view_->buffer()->fileName())); @@ -821,11 +848,13 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; case LFUN_BUFFER_WRITE_AS: + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); writeAs(lyx_view_->buffer(), argument); updateFlags = Update::None; break; case LFUN_BUFFER_RELOAD: { + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); docstring const file = makeDisplayPath(view()->buffer()->fileName(), 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); @@ -838,22 +867,27 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_BUFFER_UPDATE: + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); Exporter::Export(lyx_view_->buffer(), argument, true); break; case LFUN_BUFFER_VIEW: + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); Exporter::preview(lyx_view_->buffer(), argument); break; case LFUN_BUILD_PROGRAM: + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); Exporter::Export(lyx_view_->buffer(), "program", true); break; case LFUN_BUFFER_CHKTEX: + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); lyx_view_->buffer()->runChktex(); break; case LFUN_BUFFER_EXPORT: + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); if (argument == "custom") lyx_view_->getDialogs().show("sendto"); else { @@ -862,6 +896,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; case LFUN_BUFFER_EXPORT_CUSTOM: { + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); string format_name; string command = split(argument, format_name, ' '); Format const * format = formats.getFormat(format_name); @@ -904,6 +939,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_BUFFER_PRINT: { + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); string target; string target_name; string command = split(split(argument, target, ' '), @@ -999,17 +1035,26 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; case LFUN_LYX_QUIT: - if (view()->buffer()) { + if (argument != "force") { + if (!theApp->gui().closeAll()) + break; + lyx_view_ = 0; + } + + // FIXME: this code needs to be transfered somewhere else + // as lyx_view_ will most certainly be null and a same buffer + // might be visible in more than one LyXView. + if (lyx_view_ && lyx_view_->view()->buffer()) { // save cursor Position for opened files to .lyx/session - LyX::ref().session().saveFilePosition(lyx_view_->buffer()->fileName(), + LyX::ref().session().lastFilePos().save(lyx_view_->buffer()->fileName(), boost::tie(view()->cursor().pit(), view()->cursor().pos()) ); - // save bookmarks to .lyx/session - view()->saveSavedPositions(); - } - LyX::ref().quit(argument == "force"); + } + + LyX::ref().quit(); break; case LFUN_TOC_VIEW: { + BOOST_ASSERT(lyx_view_); InsetCommandParams p("tableofcontents"); string const data = InsetCommandMailer::params2string("toc", p); lyx_view_->getDialogs().show("toc", data, 0); @@ -1021,10 +1066,12 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; case LFUN_RECONFIGURE: - reconfigure(view()); + BOOST_ASSERT(lyx_view_); + reconfigure(*lyx_view_); break; case LFUN_HELP_OPEN: { + BOOST_ASSERT(lyx_view_); string const arg = argument; if (arg.empty()) { setErrorMessage(_("Missing argument")); @@ -1044,6 +1091,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) // --- version control ------------------------------- case LFUN_VC_REGISTER: + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); if (!ensureBufferClean(view())) break; if (!lyx_view_->buffer()->lyxvc().inUse()) { @@ -1053,6 +1101,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; case LFUN_VC_CHECK_IN: + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); if (!ensureBufferClean(view())) break; if (lyx_view_->buffer()->lyxvc().inUse() @@ -1063,6 +1112,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; case LFUN_VC_CHECK_OUT: + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); if (!ensureBufferClean(view())) break; if (lyx_view_->buffer()->lyxvc().inUse() @@ -1073,46 +1123,56 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; case LFUN_VC_REVERT: + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); lyx_view_->buffer()->lyxvc().revert(); view()->reload(); break; case LFUN_VC_UNDO_LAST: + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); lyx_view_->buffer()->lyxvc().undoLast(); view()->reload(); break; // --- buffers ---------------------------------------- case LFUN_BUFFER_SWITCH: + BOOST_ASSERT(lyx_view_); lyx_view_->setBuffer(theBufferList().getBuffer(argument)); break; case LFUN_BUFFER_NEXT: + BOOST_ASSERT(lyx_view_); lyx_view_->setBuffer(theBufferList().next(view()->buffer())); break; case LFUN_BUFFER_PREVIOUS: + BOOST_ASSERT(lyx_view_); lyx_view_->setBuffer(theBufferList().previous(view()->buffer())); break; case LFUN_FILE_NEW: + BOOST_ASSERT(lyx_view_); newFile(view(), argument); break; case LFUN_FILE_OPEN: + BOOST_ASSERT(lyx_view_); open(argument); break; case LFUN_DROP_LAYOUTS_CHOICE: + BOOST_ASSERT(lyx_view_); lyx_view_->getToolbars().openLayoutList(); break; case LFUN_MENU_OPEN: + BOOST_ASSERT(lyx_view_); lyx_view_->getMenubar().openByName(from_utf8(argument)); break; // --- lyxserver commands ---------------------------- case LFUN_SERVER_GET_NAME: + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); setMessage(from_utf8(lyx_view_->buffer()->fileName())); lyxerr[Debug::INFO] << "FNAME[" << lyx_view_->buffer()->fileName() @@ -1125,6 +1185,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; case LFUN_SERVER_GOTO_FILE_ROW: { + BOOST_ASSERT(lyx_view_); string file_name; int row; istringstream is(argument); @@ -1153,6 +1214,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_DIALOG_SHOW: { + BOOST_ASSERT(lyx_view_); string const name = cmd.getArg(0); string data = trim(to_utf8(cmd.argument()).substr(name.size())); @@ -1183,12 +1245,14 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_DIALOG_SHOW_NEW_INSET: { + BOOST_ASSERT(lyx_view_); string const name = cmd.getArg(0); string data = trim(to_utf8(cmd.argument()).substr(name.size())); if (name == "bibitem" || name == "bibtex" || name == "index" || name == "label" || + name == "nomenclature" || name == "ref" || name == "toc" || name == "url") { @@ -1235,6 +1299,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_DIALOG_UPDATE: { + BOOST_ASSERT(lyx_view_); string const & name = argument; // Can only update a dialog connected to an existing inset InsetBase * inset = lyx_view_->getDialogs().getOpenInset(name); @@ -1254,11 +1319,13 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; case LFUN_DIALOG_DISCONNECT_INSET: + BOOST_ASSERT(lyx_view_); lyx_view_->getDialogs().disconnect(argument); break; case LFUN_CITATION_INSERT: { + BOOST_ASSERT(lyx_view_); if (!argument.empty()) { // we can have one optional argument, delimited by '|' // citation-insert | @@ -1282,12 +1349,13 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_BUFFER_CHILD_OPEN: { + BOOST_ASSERT(lyx_view_); string const filename = makeAbsPath(argument, lyx_view_->buffer()->filePath()); // FIXME Should use bformat setMessage(_("Opening child document ") + makeDisplayPath(filename) + "..."); - view()->savePosition(0); + view()->saveBookmark(false); string const parentfilename = lyx_view_->buffer()->fileName(); if (theBufferList().exists(filename)) lyx_view_->setBuffer(theBufferList().getBuffer(filename)); @@ -1301,22 +1369,27 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_TOGGLE_CURSOR_FOLLOWS_SCROLLBAR: + BOOST_ASSERT(lyx_view_); lyxrc.cursor_follows_scrollbar = !lyxrc.cursor_follows_scrollbar; break; case LFUN_KEYMAP_OFF: + BOOST_ASSERT(lyx_view_); lyx_view_->view()->getIntl().keyMapOn(false); break; case LFUN_KEYMAP_PRIMARY: + BOOST_ASSERT(lyx_view_); lyx_view_->view()->getIntl().keyMapPrim(); break; case LFUN_KEYMAP_SECONDARY: + BOOST_ASSERT(lyx_view_); lyx_view_->view()->getIntl().keyMapSec(); break; case LFUN_KEYMAP_TOGGLE: + BOOST_ASSERT(lyx_view_); lyx_view_->view()->getIntl().toggleKeyMap(); break; @@ -1353,6 +1426,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_SCREEN_FONT_UPDATE: + BOOST_ASSERT(lyx_view_); // handle the screen font changes. lyxrc.set_font_norm_type(); theFontLoader().update(); @@ -1396,10 +1470,12 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_MESSAGE: + BOOST_ASSERT(lyx_view_); lyx_view_->message(from_utf8(argument)); break; case LFUN_EXTERNAL_EDIT: { + BOOST_ASSERT(lyx_view_); FuncRequest fr(action, argument); InsetExternal().dispatch(view()->cursor(), fr); break; @@ -1412,6 +1488,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_INSET_APPLY: { + BOOST_ASSERT(lyx_view_); string const name = cmd.getArg(0); InsetBase * inset = lyx_view_->getDialogs().getOpenInset(name); if (inset) { @@ -1428,6 +1505,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_ALL_INSETS_TOGGLE: { + BOOST_ASSERT(lyx_view_); string action; string const name = split(argument, action, ' '); InsetBase::Code const inset_code = @@ -1452,6 +1530,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_BUFFER_LANGUAGE: { + BOOST_ASSERT(lyx_view_); Buffer & buffer = *lyx_view_->buffer(); Language const * oldL = buffer.params().language; Language const * newL = languages.getLanguage(argument); @@ -1494,6 +1573,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_BUFFER_PARAMS_APPLY: { + BOOST_ASSERT(lyx_view_); biblio::CiteEngine const engine = lyx_view_->buffer()->params().cite_engine; @@ -1525,6 +1605,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_TEXTCLASS_APPLY: { + BOOST_ASSERT(lyx_view_); Buffer * buffer = lyx_view_->buffer(); textclass_type const old_class = @@ -1582,10 +1663,45 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } case LFUN_WINDOW_NEW: - BOOST_ASSERT(theApp); LyX::ref().newLyXView(); + break; + + case LFUN_WINDOW_CLOSE: + BOOST_ASSERT(lyx_view_); + BOOST_ASSERT(theApp); + lyx_view_->close(); + // We return here because lyx_view does not exists anymore. + return; + + case LFUN_BOOKMARK_GOTO: { + BOOST_ASSERT(lyx_view_); + unsigned int idx = convert(to_utf8(cmd.argument())); + BookmarksSection::Bookmark const bm = LyX::ref().session().bookmarks().bookmark(idx); + BOOST_ASSERT(!bm.filename.empty()); + // if the file is not opened, open it. + if (!theBufferList().exists(bm.filename)) + dispatch(FuncRequest(LFUN_FILE_OPEN, bm.filename)); + // open may fail, so we need to test it again + if (theBufferList().exists(bm.filename)) { + // if the current buffer is not that one, switch to it. + if (lyx_view_->buffer()->fileName() != bm.filename) + dispatch(FuncRequest(LFUN_BUFFER_SWITCH, bm.filename)); + // BOOST_ASSERT(lyx_view_->buffer()->fileName() != bm.filename); + view()->moveToPosition(bm.par_id, bm.par_pos); + } + break; + } + + case LFUN_BOOKMARK_CLEAR: + LyX::ref().session().bookmarks().clear(); + break; + + case LFUN_TOOLBAR_TOGGLE_STATE: + lyx_view_->toggleToolbarState(argument); + break; default: { + BOOST_ASSERT(lyx_view_); view()->cursor().dispatch(cmd); updateFlags = view()->cursor().result().update(); if (!view()->cursor().result().dispatched()) @@ -1595,20 +1711,16 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } } - if (view()->buffer()) { + if (lyx_view_ && view()->buffer()) { // Redraw screen unless explicitly told otherwise. // This also initializes the position cache for all insets // in (at least partially) visible top-level paragraphs. - bool needSecondUpdate = false; - if (updateFlags != Update::None) - view()->update(updateFlags); - else - needSecondUpdate = view()->fitCursor(); + std::pair needSecondUpdate = view()->update(updateFlags); - if (needSecondUpdate || updateFlags != Update::None) { - view()->buffer()->changed(); - lyx_view_->updateStatusBar(); - } + if (needSecondUpdate.first) + view()->buffer()->changed(needSecondUpdate.second); + + lyx_view_->updateStatusBar(); // if we executed a mutating lfun, mark the buffer as dirty if (flag.enabled() @@ -1621,26 +1733,18 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } } } - if (!quitting) - // FIXME UNICODE: _() does not support anything but ascii. - // Do we need a to_ascii() method? + if (!quitting) { + lyx_view_->updateMenubar(); + lyx_view_->updateToolbars(); sendDispatchMessage(getMessage(), cmd); + } } void LyXFunc::sendDispatchMessage(docstring const & msg, FuncRequest const & cmd) { - /* When an action did not originate from the UI/kbd, it makes - * sense to avoid updating the GUI. It turns out that this - * fixes bug 1941, for reasons that are described here: - * http://bugzilla.lyx.org/show_bug.cgi?id=1941#c4 - */ - if (cmd.origin != FuncRequest::INTERNAL) { - lyx_view_->updateMenubar(); - lyx_view_->updateToolbars(); - } - - const bool verbose = (cmd.origin == FuncRequest::UI + const bool verbose = (cmd.origin == FuncRequest::MENU + || cmd.origin == FuncRequest::TOOLBAR || cmd.origin == FuncRequest::COMMANDBUFFER); if (cmd.action == LFUN_SELF_INSERT || !verbose) { @@ -1892,7 +1996,7 @@ void LyXFunc::doImport(string const & argument) void LyXFunc::closeBuffer() { // save current cursor position - LyX::ref().session().saveFilePosition(lyx_view_->buffer()->fileName(), + LyX::ref().session().lastFilePos().save(lyx_view_->buffer()->fileName(), boost::tie(view()->cursor().pit(), view()->cursor().pos()) ); if (theBufferList().close(lyx_view_->buffer(), true) && !quitting) { if (theBufferList().empty()) { @@ -1984,6 +2088,7 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new) 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_CUSTOM_EXPORT_COMMAND: @@ -2080,6 +2185,7 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new) 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: