X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FLyXFunc.cpp;h=ee89ed58a651fb9c8bb8b831d72849e60e77a660;hb=a3315920a2816111293b0112b689148bd6635e1e;hp=b9384260d105ea63270e907870deeb4d34be78f9;hpb=77d4d1256daa6253a69cf222292ad8156cb57c72;p=lyx.git diff --git a/src/LyXFunc.cpp b/src/LyXFunc.cpp index b9384260d1..ee89ed58a6 100644 --- a/src/LyXFunc.cpp +++ b/src/LyXFunc.cpp @@ -23,44 +23,42 @@ #include "LyXFunc.h" #include "BranchList.h" -#include "Buffer.h" #include "buffer_funcs.h" +#include "Buffer.h" #include "BufferList.h" #include "BufferParams.h" #include "BufferView.h" -#include "bufferview_funcs.h" +#include "CmdDef.h" +#include "Color.h" +#include "Converter.h" #include "Cursor.h" #include "CutAndPaste.h" #include "debug.h" #include "DispatchResult.h" #include "Encoding.h" #include "ErrorList.h" -#include "Exporter.h" #include "Format.h" #include "FuncRequest.h" #include "FuncStatus.h" #include "gettext.h" -#include "Importer.h" #include "InsetIterator.h" #include "Intl.h" #include "KeyMap.h" #include "Language.h" -#include "Color.h" -#include "Session.h" -#include "LyX.h" -#include "callback.h" +#include "Lexer.h" #include "LyXAction.h" #include "lyxfind.h" -#include "Lexer.h" +#include "LyX.h" #include "LyXRC.h" -#include "Row.h" -#include "Server.h" -#include "TextClassList.h" #include "LyXVC.h" #include "Paragraph.h" -#include "ParIterator.h" #include "ParagraphParameters.h" -#include "Undo.h" +#include "ParIterator.h" +#include "Row.h" +#include "Server.h" +#include "Session.h" +#include "TextClassList.h" +#include "ToolbarBackend.h" #include "insets/InsetBox.h" #include "insets/InsetBranch.h" @@ -76,24 +74,18 @@ #include "insets/InsetVSpace.h" #include "insets/InsetWrap.h" -#include "frontends/Application.h" #include "frontends/alert.h" -#include "frontends/Dialogs.h" +#include "frontends/Application.h" #include "frontends/FileDialog.h" #include "frontends/FontLoader.h" -#include "frontends/Gui.h" #include "frontends/KeySymbol.h" #include "frontends/LyXView.h" -#include "frontends/Menubar.h" #include "frontends/Selection.h" -#include "frontends/Toolbars.h" -#include "frontends/WorkArea.h" #include "support/environment.h" #include "support/FileFilterList.h" +#include "support/FileName.h" #include "support/filetools.h" -#include "support/ForkedcallsController.h" -#include "support/fs_extras.h" #include "support/lstrings.h" #include "support/Path.h" #include "support/Package.h" @@ -102,7 +94,6 @@ #include "support/os.h" #include -#include #include @@ -112,13 +103,11 @@ using std::pair; using std::string; using std::istringstream; using std::ostringstream; - -namespace fs = boost::filesystem; +using std::find; +using std::vector; namespace lyx { -using bv_funcs::freefont2string; - using frontend::LyXView; using support::absolutePath; @@ -130,13 +119,9 @@ using support::contains; using support::FileFilterList; using support::FileName; using support::fileSearch; -using support::ForkedcallsController; using support::i18nLibFileSearch; -using support::isDirWriteable; -using support::isFileReadable; -using support::isStrInt; -using support::makeAbsPath; using support::makeDisplayPath; +using support::makeAbsPath; using support::package; using support::quoteName; using support::rtrim; @@ -147,13 +132,117 @@ using support::token; using support::trim; using support::prefixIs; + namespace Alert = frontend::Alert; +extern bool quitting; +extern bool use_gui; namespace { -bool getLocalStatus(Cursor cursor, - FuncRequest const & cmd, FuncStatus & status) + +bool import(LyXView * lv, FileName const & filename, + string const & format, ErrorList & errorList) +{ + docstring const displaypath = makeDisplayPath(filename.absFilename()); + lv->message(bformat(_("Importing %1$s..."), displaypath)); + + FileName const lyxfile(changeExtension(filename.absFilename(), ".lyx")); + + string loader_format; + vector loaders = theConverters().loaders(); + if (find(loaders.begin(), loaders.end(), format) == loaders.end()) { + for (vector::const_iterator it = loaders.begin(); + it != loaders.end(); ++it) { + if (theConverters().isReachable(format, *it)) { + string const tofile = + changeExtension(filename.absFilename(), + formats.extension(*it)); + if (!theConverters().convert(0, filename, FileName(tofile), + filename, format, *it, errorList)) + return false; + loader_format = *it; + break; + } + } + if (loader_format.empty()) { + frontend::Alert::error(_("Couldn't import file"), + bformat(_("No information for importing the format %1$s."), + formats.prettyName(format))); + return false; + } + } else { + loader_format = format; + } + + + if (loader_format == "lyx") { + Buffer * buf = theLyXFunc().loadAndViewFile(lyxfile); + if (!buf) { + // we are done + lv->message(_("file not imported!")); + return false; + } + updateLabels(*buf); + lv->setBuffer(buf); + lv->errors("Parse"); + } else { + Buffer * const b = newFile(lyxfile.absFilename(), string(), true); + if (b) + lv->setBuffer(b); + else + return false; + bool as_paragraphs = loader_format == "textparagraph"; + string filename2 = (loader_format == format) ? filename.absFilename() + : changeExtension(filename.absFilename(), + formats.extension(loader_format)); + lv->view()->insertPlaintextFile(filename2, as_paragraphs); + lv->dispatch(FuncRequest(LFUN_MARK_OFF)); + } + + // we are done + lv->message(_("imported.")); + return true; +} + + + +// This function runs "configure" and then rereads lyx.defaults to +// reconfigure the automatic settings. +void reconfigure(LyXView & lv, string const & option) +{ + // emit message signal. + lv.message(_("Running configure...")); + + // Run configure in user lyx directory + support::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. + lv.message(_("Reloading configuration...")); + lyxrc.read(support::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(); @@ -205,18 +294,17 @@ Change::Type lookupChangeType(DocIterator const & dit, bool outer = false) } + LyXFunc::LyXFunc() - : lyx_view_(0), - encoded_last_key(0), - meta_fake_bit(key_modifier::none) + : lyx_view_(0), encoded_last_key(0), meta_fake_bit(NoModifier) { } void LyXFunc::initKeySequences(KeyMap * kb) { - keyseq.reset(new KeySequence(kb, kb)); - cancel_meta_seq.reset(new KeySequence(kb, kb)); + keyseq = KeySequence(kb, kb); + cancel_meta_seq = KeySequence(kb, kb); } @@ -234,7 +322,7 @@ void LyXFunc::handleKeyFunc(kb_action action) { char_type c = encoded_last_key; - if (keyseq->length()) + if (keyseq.length()) c = 0; BOOST_ASSERT(lyx_view_ && lyx_view_->view()); @@ -242,10 +330,10 @@ void LyXFunc::handleKeyFunc(kb_action action) c, get_accent(action).accent, view()->cursor().innerText(), view()->cursor()); // Need to clear, in case the minibuffer calls these // actions - keyseq->clear(); + keyseq.clear(); // copied verbatim from do_accent_char view()->cursor().resetAnchor(); - view()->update(); + view()->processUpdateFlags(Update::FitCursor); } @@ -269,7 +357,7 @@ void LyXFunc::gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer) return; // if the current buffer is not that one, switch to it. - if (lyx_view_->buffer()->fileName() != file) { + if (lyx_view_->buffer()->absFileName() != file) { if (!switchToBuffer) return; dispatch(FuncRequest(LFUN_BUFFER_SWITCH, file)); @@ -295,91 +383,86 @@ void LyXFunc::gotoBookmark(unsigned int idx, bool openFile, bool switchToBuffer) } -void LyXFunc::processKeySym(KeySymbolPtr keysym, key_modifier::state state) +void LyXFunc::processKeySym(KeySymbol const & keysym, KeyModifier state) { - LYXERR(Debug::KEY) << "KeySym is " << keysym->getSymbolName() << endl; + 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)" - << endl; + if (!keysym.isOK()) { + LYXERR(Debug::KEY, "Empty kbd action (probably composing)"); + lyx_view_->restartCursor(); return; } - if (keysym->isModifier()) { - LYXERR(Debug::KEY) << "isModifier true" << endl; + if (keysym.isModifier()) { + LYXERR(Debug::KEY, "isModifier true"); + lyx_view_->restartCursor(); return; } //Encoding const * encoding = view()->cursor().getEncoding(); - //encoded_last_key = keysym->getISOEncoded(encoding ? encoding->name() : ""); + //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(); + 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(); + cancel_meta_seq.reset(); - FuncRequest func = cancel_meta_seq->addkey(keysym, state); - LYXERR(Debug::KEY) << BOOST_CURRENT_FUNCTION - << " action first set to [" << func.action << ']' - << endl; + FuncRequest func = cancel_meta_seq.addkey(keysym, state); + LYXERR(Debug::KEY, BOOST_CURRENT_FUNCTION + << " 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 = key_modifier::none. RVDK_PATCH_5. + // 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) << BOOST_CURRENT_FUNCTION - << "action now set to [" - << func.action << ']' << endl; + func = keyseq.addkey(keysym, (state | meta_fake_bit)); + LYXERR(Debug::KEY, BOOST_CURRENT_FUNCTION + << "action now set to [" << func.action << ']'); } // Dont remove this unless you know what you are doing. - meta_fake_bit = key_modifier::none; + meta_fake_bit = NoModifier; // Can this happen now ? - if (func.action == LFUN_NOACTION) { + if (func.action == LFUN_NOACTION) func = FuncRequest(LFUN_COMMAND_PREFIX); - } - LYXERR(Debug::KEY) << BOOST_CURRENT_FUNCTION - << " Key [action=" - << func.action << "][" - << to_utf8(keyseq->print(false)) << ']' - << endl; + LYXERR(Debug::KEY, BOOST_CURRENT_FUNCTION + << " Key [action=" << func.action << "][" + << to_utf8(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(true)); - } + 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 == key_modifier::shift) { - LYXERR(Debug::KEY) << "Trying without shift" << endl; - func = keyseq->addkey(keysym, key_modifier::none); - LYXERR(Debug::KEY) << "Action now " << func.action << endl; + 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." << endl; + 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" << endl; + LYXERR(Debug::KEY, "Unknown, !isText() - giving up"); lyx_view_->message(_("Unknown function.")); + lyx_view_->restartCursor(); return; } } @@ -389,18 +472,13 @@ void LyXFunc::processKeySym(KeySymbolPtr keysym, key_modifier::state state) docstring const arg(1, encoded_last_key); dispatch(FuncRequest(LFUN_SELF_INSERT, arg, FuncRequest::KEYBOARD)); - LYXERR(Debug::KEY) - << "SelfInsert arg[`" << to_utf8(arg) << "']" << endl; + LYXERR(Debug::KEY, "SelfInsert arg[`" << to_utf8(arg) << "']"); } } else { dispatch(func); } - /* When we move around, or type, it's nice to be able to see - * the cursor immediately after the keypress. - */ - if (lyx_view_ && lyx_view_->currentWorkArea()) - lyx_view_->currentWorkArea()->startBlinkingCursor(); + lyx_view_->restartCursor(); } @@ -409,19 +487,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const //lyxerr << "LyXFunc::getStatus: cmd: " << cmd << endl; FuncStatus flag; - Cursor & cur = view()->cursor(); - - /* 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-related. - - Note that this code is not perfect, as bug 1941 attests: - http://bugzilla.lyx.org/show_bug.cgi?id=1941#c4 - */ Buffer * buf = lyx_view_? lyx_view_->buffer() : 0; - if (lyx_view_ && cmd.origin == FuncRequest::MENU && !lyx_view_->hasFocus()) - buf = 0; if (cmd.action == LFUN_NOACTION) { flag.message(from_utf8(N_("Nothing to do"))); @@ -468,6 +534,16 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const // to handle (Andre') bool enable = true; switch (cmd.action) { + + case LFUN_DIALOG_TOGGLE: + case LFUN_DIALOG_SHOW: + case LFUN_DIALOG_UPDATE: + case LFUN_TOOLBAR_TOGGLE: + if (lyx_view_) + return lyx_view_->getStatus(cmd); + enable = false; + break; + case LFUN_BUFFER_TOGGLE_READ_ONLY: flag.setOnOff(buf->isReadonly()); break; @@ -475,13 +551,13 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const 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->fileName()) + if (buf && to_utf8(cmd.argument()) == buf->absFileName()) flag.setOnOff(true); break; case LFUN_BUFFER_EXPORT: enable = cmd.argument() == "custom" - || Exporter::isExportable(*buf, to_utf8(cmd.argument())); + || buf->isExportable(to_utf8(cmd.argument())); break; case LFUN_BUFFER_CHKTEX: @@ -489,16 +565,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const break; case LFUN_BUILD_PROGRAM: - enable = Exporter::isExportable(*buf, "program"); - break; - - case LFUN_LAYOUT_TABULAR: - enable = cur.innerInsetOfType(Inset::TABULAR_CODE); - break; - - case LFUN_LAYOUT: - case LFUN_LAYOUT_PARAGRAPH: - enable = !cur.inset().forceDefaultParagraphs(cur.idx()); + enable = buf->isExportable("program"); break; case LFUN_VC_REGISTER: @@ -515,53 +582,21 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const enable = buf->lyxvc().inUse(); break; case LFUN_BUFFER_RELOAD: - enable = !buf->isUnnamed() && fs::exists(buf->fileName()) + enable = !buf->isUnnamed() && buf->fileName().exists() && (!buf->isClean() || buf->isExternallyModified(Buffer::timestamp_method)); break; - case LFUN_INSET_SETTINGS: { - enable = false; - if (!cur) + case LFUN_INSET_APPLY: { + if (!view()) { + enable = false; break; - Inset::Code code = cur.inset().lyxCode(); - switch (code) { - case Inset::TABULAR_CODE: - enable = cmd.argument() == "tabular"; - break; - case Inset::ERT_CODE: - enable = cmd.argument() == "ert"; - break; - case Inset::FLOAT_CODE: - enable = cmd.argument() == "float"; - break; - case Inset::WRAP_CODE: - enable = cmd.argument() == "wrap"; - break; - case Inset::NOTE_CODE: - enable = cmd.argument() == "note"; - break; - case Inset::BRANCH_CODE: - enable = cmd.argument() == "branch"; - break; - case Inset::BOX_CODE: - enable = cmd.argument() == "box"; - break; - case Inset::LISTINGS_CODE: - enable = cmd.argument() == "listings"; - break; - default: - break; } - break; - } - - case LFUN_INSET_APPLY: { string const name = cmd.getArg(0); - Inset * inset = lyx_view_->getDialogs().getOpenInset(name); + Inset * inset = lyx_view_->getOpenInset(name); if (inset) { FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument()); FuncStatus fs; - if (!inset->getStatus(cur, fr, fs)) { + if (!inset->getStatus(view()->cursor(), fr, fs)) { // Every inset is supposed to handle this BOOST_ASSERT(false); } @@ -574,52 +609,6 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const break; } - case LFUN_DIALOG_TOGGLE: - flag.setOnOff(lyx_view_->getDialogs().visible(cmd.getArg(0))); - // fall through to set "enable" - case LFUN_DIALOG_SHOW: { - string const name = cmd.getArg(0); - if (!buf) - enable = name == "aboutlyx" - || name == "file" //FIXME: should be removed. - || name == "prefs" - || name == "texinfo"; - else if (name == "print") - enable = Exporter::isExportable(*buf, "dvi") - && lyxrc.print_command != "none"; - else if (name == "character") - enable = cur.inset().lyxCode() != Inset::ERT_CODE && - cur.inset().lyxCode() != Inset::LISTINGS_CODE; - else if (name == "latexlog") - enable = isFileReadable(FileName(buf->getLogName().second)); - else if (name == "spellchecker") -#if defined (USE_ASPELL) || defined (USE_ISPELL) || defined (USE_PSPELL) - enable = !buf->isReadonly(); -#else - enable = false; -#endif - else if (name == "vclog") - enable = buf->lyxvc().inUse(); - break; - } - - case LFUN_DIALOG_SHOW_NEW_INSET: - enable = cur.inset().lyxCode() != Inset::ERT_CODE && - cur.inset().lyxCode() != Inset::LISTINGS_CODE; - if (cur.inset().lyxCode() == Inset::CAPTION_CODE) { - FuncStatus flag; - if (cur.inset().getStatus(cur, cmd, flag)) - return flag; - } - break; - - case LFUN_DIALOG_UPDATE: { - string const name = cmd.getArg(0); - if (!buf) - enable = name == "prefs"; - break; - } - case LFUN_CITATION_INSERT: { FuncRequest fr(LFUN_INSET_INSERT, "citation"); enable = getStatus(fr).enabled(); @@ -665,15 +654,9 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const enable = LyX::ref().session().bookmarks().size() > 0; break; - case LFUN_TOOLBAR_TOGGLE: { - bool const current = lyx_view_->isToolbarVisible(cmd.getArg(0)); - flag.setOnOff(current); - break; - } - case LFUN_WINDOW_CLOSE: { - enable = (theApp()->gui().viewIds().size() > 1); + case LFUN_WINDOW_CLOSE: + enable = theApp()->viewCount() > 0; break; - } // this one is difficult to get right. As a half-baked // solution, we consider only the first action of the sequence @@ -683,6 +666,23 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const FuncRequest func(lyxaction.lookupFunc(firstcmd)); func.origin = cmd.origin; flag = getStatus(func); + break; + } + + case LFUN_CALL: { + FuncRequest func; + std::string name = to_utf8(cmd.argument()); + if (LyX::ref().topLevelCmdDef().lock(name, func)) { + func.origin = cmd.origin; + flag = getStatus(func); + LyX::ref().topLevelCmdDef().release(name); + } else { + // catch recursion or unknown command definiton + // all operations until the recursion or unknown command + // definiton occures are performed, so set the state to enabled + enable = true; + } + break; } case LFUN_BUFFER_NEW: @@ -697,6 +697,8 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const case LFUN_BUFFER_WRITE_AS: case LFUN_BUFFER_UPDATE: case LFUN_BUFFER_VIEW: + case LFUN_MASTER_BUFFER_UPDATE: + case LFUN_MASTER_BUFFER_VIEW: case LFUN_BUFFER_IMPORT: case LFUN_BUFFER_AUTO_SAVE: case LFUN_RECONFIGURE: @@ -731,6 +733,9 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const 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: @@ -740,7 +745,11 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const break; default: - if (!getLocalStatus(cur, cmd, flag)) + if (!view()) { + enable = false; + break; + } + if (!getLocalStatus(view()->cursor(), cmd, flag)) flag = view()->getStatus(cmd); } @@ -756,7 +765,8 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const } // Are we in a DELETED change-tracking region? - if (buf && lookupChangeType(cur, true) == Change::DELETED + 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."))); @@ -777,7 +787,7 @@ bool LyXFunc::ensureBufferClean(BufferView * bv) if (buf.isClean()) return true; - docstring const file = makeDisplayPath(buf.fileName(), 30); + docstring const file = buf.fileName().displayName(30); docstring text = bformat(_("The document %1$s has unsaved " "changes.\n\nDo you want to save " "the document?"), file); @@ -803,7 +813,7 @@ void showPrintError(string const & name) } -void loadTextclass(string const & name) +void loadTextClass(string const & name) { std::pair const tc_pair = textclasslist.numberOfClass(name); @@ -818,10 +828,10 @@ void loadTextclass(string const & name) textclass_type const tc = tc_pair.second; if (!textclasslist[tc].load()) { - docstring s = bformat(_("The document could not be converted\n" - "into the document class %1$s."), + docstring s = bformat(_("The document class %1$s." + "could not be loaded."), from_utf8(textclasslist[tc].name())); - Alert::error(_("Could not change class"), s); + Alert::error(_("Could not load class"), s); } } @@ -836,7 +846,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) string const argument = to_utf8(cmd.argument()); kb_action const action = cmd.action; - LYXERR(Debug::ACTION) << endl << "LyXFunc::dispatch: cmd: " << cmd << endl; + LYXERR(Debug::ACTION, "\nLyXFunc::dispatch: cmd: " << cmd); //lyxerr << "LyXFunc::dispatch: cmd: " << cmd << endl; // we have not done anything wrong yet. @@ -850,13 +860,25 @@ void LyXFunc::dispatch(FuncRequest const & cmd) FuncStatus const flag = getStatus(cmd); if (!flag.enabled()) { // We cannot use this function here - LYXERR(Debug::ACTION) << "LyXFunc::dispatch: " + LYXERR(Debug::ACTION, "LyXFunc::dispatch: " << lyxaction.getActionName(action) - << " [" << action << "] is disabled at this location" - << endl; + << " [" << action << "] is disabled at this location"); setErrorMessage(flag.message()); } else { switch (action) { + // Let lyx_view_ dispatch its own actions. + case LFUN_COMMAND_EXECUTE: + case LFUN_DROP_LAYOUTS_CHOICE: + case LFUN_MENU_OPEN: + case LFUN_TOOLBAR_TOGGLE: + case LFUN_DIALOG_UPDATE: + case LFUN_DIALOG_TOGGLE: + case LFUN_DIALOG_DISCONNECT_INSET: + case LFUN_DIALOG_HIDE: + case LFUN_DIALOG_SHOW: + BOOST_ASSERT(lyx_view_); + lyx_view_->dispatch(cmd); + break; case LFUN_WORD_FIND_FORWARD: case LFUN_WORD_FIND_BACKWARD: { @@ -883,18 +905,13 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_COMMAND_PREFIX: BOOST_ASSERT(lyx_view_); - lyx_view_->message(keyseq->printOptions(true)); - break; - - case LFUN_COMMAND_EXECUTE: - BOOST_ASSERT(lyx_view_); - lyx_view_->showMiniBuffer(true); + lyx_view_->message(keyseq.printOptions(true)); break; case LFUN_CANCEL: BOOST_ASSERT(lyx_view_ && lyx_view_->view()); - keyseq->reset(); - meta_fake_bit = key_modifier::none; + keyseq.reset(); + meta_fake_bit = NoModifier; if (lyx_view_->buffer()) // cancel any selection dispatch(FuncRequest(LFUN_MARK_OFF)); @@ -902,18 +919,19 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; case LFUN_META_PREFIX: - meta_fake_bit = key_modifier::alt; - setMessage(keyseq->print(true)); + meta_fake_bit = AltModifier; + setMessage(keyseq.print(KeySequence::ForGui)); break; - case LFUN_BUFFER_TOGGLE_READ_ONLY: + 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(); + Buffer * buf = lyx_view_->buffer(); + if (buf->lyxvc().inUse()) + buf->lyxvc().toggleReadOnly(); else - lyx_view_->buffer()->setReadonly( - !lyx_view_->buffer()->isReadonly()); + buf->setReadonly(!lyx_view_->buffer()->isReadonly()); break; + } // --- Menus ----------------------------------------------- case LFUN_BUFFER_NEW: @@ -935,19 +953,19 @@ void LyXFunc::dispatch(FuncRequest const & cmd) 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())); + makeDisplayPath(lyx_view_->buffer()->absFileName())); lyx_view_->message(str); - menuWrite(lyx_view_->buffer()); + lyx_view_->buffer()->menuWrite(); lyx_view_->message(str + _(" done.")); } else { - writeAs(lyx_view_->buffer()); + lyx_view_->buffer()->writeAs(); } updateFlags = Update::None; break; case LFUN_BUFFER_WRITE_AS: BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); - writeAs(lyx_view_->buffer(), argument); + lyx_view_->buffer()->writeAs(argument); updateFlags = Update::None; break; @@ -961,10 +979,10 @@ void LyXFunc::dispatch(FuncRequest const & cmd) do { if (!b->isClean()) { if (!b->isUnnamed()) { - menuWrite(b); - lyxerr[Debug::ACTION] << "Saved " << b->fileName() << endl; + b->menuWrite(); + lyxerr[Debug::ACTION] << "Saved " << b->absFileName() << endl; } else - writeAs(b); + b->writeAs(); } b = theBufferList().next(b); } while (b != first); @@ -977,7 +995,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_BUFFER_RELOAD: { BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); - docstring const file = makeDisplayPath(lyx_view_->buffer()->fileName(), 20); + docstring const file = makeDisplayPath(lyx_view_->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?"), @@ -990,17 +1008,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); + lyx_view_->buffer()->doExport(argument, true); break; case LFUN_BUFFER_VIEW: BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); - Exporter::preview(lyx_view_->buffer(), argument); + lyx_view_->buffer()->preview(argument); + break; + + case LFUN_MASTER_BUFFER_UPDATE: + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer() && lyx_view_->buffer()->masterBuffer()); + lyx_view_->buffer()->masterBuffer()->doExport(argument, true); + break; + + case LFUN_MASTER_BUFFER_VIEW: + BOOST_ASSERT(lyx_view_ && lyx_view_->buffer() && lyx_view_->buffer()->masterBuffer()); + lyx_view_->buffer()->masterBuffer()->preview(argument); break; case LFUN_BUILD_PROGRAM: BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); - Exporter::Export(lyx_view_->buffer(), "program", true); + lyx_view_->buffer()->doExport("program", true); break; case LFUN_BUFFER_CHKTEX: @@ -1011,10 +1039,9 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_BUFFER_EXPORT: BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); if (argument == "custom") - lyx_view_->getDialogs().show("sendto"); - else { - Exporter::Export(lyx_view_->buffer(), argument, false); - } + dispatch(FuncRequest(LFUN_DIALOG_SHOW, "sendto")); + else + lyx_view_->buffer()->doExport(argument, false); break; case LFUN_BUFFER_EXPORT_CUSTOM: { @@ -1036,8 +1063,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) // Output to filename if (format->name() == "lyx") { - string const latexname = - buffer->getLatexName(false); + string const latexname = buffer->latexName(false); filename = changeExtension(latexname, format->extension()); filename = addName(buffer->temppath(), filename); @@ -1046,7 +1072,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; } else { - Exporter::Export(buffer, format_name, true, filename); + buffer->doExport(format_name, true, filename); } // Substitute $$FName for filename @@ -1083,16 +1109,16 @@ void LyXFunc::dispatch(FuncRequest const & cmd) Buffer * buffer = lyx_view_->buffer(); - if (!Exporter::Export(buffer, "dvi", true)) { - showPrintError(buffer->fileName()); + if (!buffer->doExport("dvi", true)) { + showPrintError(buffer->absFileName()); break; } // Push directory path. - string const path(buffer->temppath()); + string const path = buffer->temppath(); // Prevent the compiler from optimizing away p FileName pp(path); - support::Path p(pp); + support::PathChanger p(pp); // there are three cases here: // 1. we print to a file @@ -1101,8 +1127,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) Systemcall one; int res = 0; string const dviname = - changeExtension(buffer->getLatexName(true), - "dvi"); + changeExtension(buffer->latexName(true), "dvi"); if (target == "printer") { if (!lyxrc.print_spool_command.empty()) { @@ -1146,7 +1171,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) FileName const filename(makeAbsPath(target_name, lyx_view_->buffer()->filePath())); FileName const dvifile(makeAbsPath(dviname, path)); - if (fs::exists(filename.toFilesystemEncoding())) { + if (filename.exists()) { docstring text = bformat( _("The file %1$s already exists.\n\n" "Do you want to overwrite that file?"), @@ -1164,7 +1189,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } if (res != 0) - showPrintError(buffer->fileName()); + showPrintError(buffer->absFileName()); break; } @@ -1177,16 +1202,17 @@ void LyXFunc::dispatch(FuncRequest const & cmd) // (leaving the event loop). lyx_view_->message(from_utf8(N_("Exiting."))); if (theBufferList().quitWriteAll()) - theApp()->gui().closeAllViews(); + theApp()->closeAllViews(); break; case LFUN_BUFFER_AUTO_SAVE: - autoSave(view()); + lyx_view_->buffer()->autoSave(); break; case LFUN_RECONFIGURE: BOOST_ASSERT(lyx_view_); - reconfigure(*lyx_view_); + // argument is any additional parameter to the configure.py command + reconfigure(*lyx_view_, argument); break; case LFUN_HELP_OPEN: { @@ -1204,11 +1230,11 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } lyx_view_->message(bformat(_("Opening help file %1$s..."), makeDisplayPath(fname.absFilename()))); - Buffer * buf = lyx_view_->loadLyXFile(fname, false); + Buffer * buf = loadAndViewFile(fname, false); if (buf) { updateLabels(*buf); lyx_view_->setBuffer(buf); - lyx_view_->showErrorList("Parse"); + lyx_view_->errors("Parse"); } updateFlags = Update::None; break; @@ -1279,11 +1305,16 @@ void LyXFunc::dispatch(FuncRequest const & cmd) updateFlags = Update::None; break; - case LFUN_FILE_NEW: + case LFUN_FILE_NEW: { BOOST_ASSERT(lyx_view_); - newFile(*lyx_view_, argument); + string name; + string tmpname = split(argument, name, ':'); // Split filename + Buffer * const b = newFile(name, tmpname); + if (b) + lyx_view_->setBuffer(b); updateFlags = Update::None; break; + } case LFUN_FILE_OPEN: BOOST_ASSERT(lyx_view_); @@ -1291,27 +1322,16 @@ void LyXFunc::dispatch(FuncRequest const & cmd) updateFlags = Update::None; break; - case LFUN_DROP_LAYOUTS_CHOICE: - BOOST_ASSERT(lyx_view_); - lyx_view_->openLayoutList(); - break; - - case LFUN_MENU_OPEN: - BOOST_ASSERT(lyx_view_); - lyx_view_->openMenu(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() - << "] " << endl; + setMessage(from_utf8(lyx_view_->buffer()->absFileName())); + LYXERR(Debug::INFO, "FNAME[" + << lyx_view_->buffer()->absFileName() << ']'); break; case LFUN_SERVER_NOTIFY: - dispatch_buffer = keyseq->print(false); + dispatch_buffer = keyseq.print(KeySequence::Portable); theServer().notifyClient(to_utf8(dispatch_buffer)); break; @@ -1335,7 +1355,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) if (theBufferList().exists(s.absFilename())) buf = theBufferList().getBuffer(s.absFilename()); else { - buf = lyx_view_->loadLyXFile(s); + buf = loadAndViewFile(s); loaded = true; } } @@ -1349,139 +1369,109 @@ void LyXFunc::dispatch(FuncRequest const & cmd) lyx_view_->setBuffer(buf); view()->setCursorFromRow(row); if (loaded) - lyx_view_->showErrorList("Parse"); + lyx_view_->errors("Parse"); updateFlags = Update::FitCursor; break; } - case LFUN_DIALOG_SHOW: { - BOOST_ASSERT(lyx_view_); - string const name = cmd.getArg(0); - string data = trim(to_utf8(cmd.argument()).substr(name.size())); - - if (name == "character") { - data = freefont2string(); - if (!data.empty()) - lyx_view_->getDialogs().show("character", data); - } else if (name == "latexlog") { - pair const logfile = - lyx_view_->buffer()->getLogName(); - switch (logfile.first) { - case Buffer::latexlog: - data = "latex "; - break; - case Buffer::buildlog: - data = "literate "; - break; - } - data += Lexer::quoteString(logfile.second); - lyx_view_->getDialogs().show("log", data); - } else if (name == "vclog") { - string const data = "vc " + - Lexer::quoteString(lyx_view_->buffer()->lyxvc().getLogFile()); - lyx_view_->getDialogs().show("log", data); - } else - lyx_view_->getDialogs().show(name, data); - break; - } case LFUN_DIALOG_SHOW_NEW_INSET: { BOOST_ASSERT(lyx_view_); string const name = cmd.getArg(0); + InsetCode code = insetCode(name); 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") { - InsetCommandParams p(name); + bool insetCodeOK = true; + switch (code) { + case BIBITEM_CODE: + case BIBTEX_CODE: + case INDEX_CODE: + case LABEL_CODE: + case NOMENCL_CODE: + case REF_CODE: + case TOC_CODE: + case HYPERLINK_CODE: { + InsetCommandParams p(code); data = InsetCommandMailer::params2string(name, p); - } else if (name == "include") { + 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(data); - data = InsetIncludeMailer::params2string(p); - } else if (name == "box") { + InsetCommandParams p(INCLUDE_CODE, data); + data = InsetCommandMailer::params2string("include", p); + break; + } + case BOX_CODE: { // \c data == "Boxed" || "Frameless" etc InsetBoxParams p(data); data = InsetBoxMailer::params2string(p); - } else if (name == "branch") { + break; + } + case BRANCH_CODE: { InsetBranchParams p; data = InsetBranchMailer::params2string(p); - } else if (name == "citation") { - InsetCommandParams p("cite"); + break; + } + case CITE_CODE: { + InsetCommandParams p(CITE_CODE); data = InsetCommandMailer::params2string(name, p); - } else if (name == "ert") { + break; + } + case ERT_CODE: { data = InsetERTMailer::params2string(InsetCollapsable::Open); - } else if (name == "external") { + break; + } + case EXTERNAL_CODE: { InsetExternalParams p; Buffer const & buffer = *lyx_view_->buffer(); data = InsetExternalMailer::params2string(p, buffer); - } else if (name == "float") { + break; + } + case FLOAT_CODE: { InsetFloatParams p; data = InsetFloatMailer::params2string(p); - } else if (name == "listings") { + break; + } + case LISTINGS_CODE: { InsetListingsParams p; data = InsetListingsMailer::params2string(p); - } else if (name == "graphics") { + break; + } + case GRAPHICS_CODE: { InsetGraphicsParams p; Buffer const & buffer = *lyx_view_->buffer(); data = InsetGraphicsMailer::params2string(p, buffer); - } else if (name == "note") { + break; + } + case NOTE_CODE: { InsetNoteParams p; data = InsetNoteMailer::params2string(p); - } else if (name == "vspace") { + break; + } + case VSPACE_CODE: { VSpace space; data = InsetVSpaceMailer::params2string(space); - } else if (name == "wrap") { + break; + } + case WRAP_CODE: { InsetWrapParams p; data = InsetWrapMailer::params2string(p); + break; } - lyx_view_->getDialogs().show(name, data, 0); - break; - } - - case LFUN_DIALOG_UPDATE: { - BOOST_ASSERT(lyx_view_); - string const & name = argument; - // Can only update a dialog connected to an existing inset - Inset * inset = lyx_view_->getDialogs().getOpenInset(name); - if (inset) { - FuncRequest fr(LFUN_INSET_DIALOG_UPDATE, cmd.argument()); - inset->dispatch(view()->cursor(), fr); - } else if (name == "paragraph") { - dispatch(FuncRequest(LFUN_PARAGRAPH_UPDATE)); - } else if (name == "prefs") { - lyx_view_->getDialogs().update(name, string()); - } - break; - } - - case LFUN_DIALOG_HIDE: - LyX::cref().hideDialogs(argument, 0); - break; - - case LFUN_DIALOG_TOGGLE: { - BOOST_ASSERT(lyx_view_); - if (lyx_view_->getDialogs().visible(cmd.getArg(0))) - dispatch(FuncRequest(LFUN_DIALOG_HIDE, argument)); - else - dispatch(FuncRequest(LFUN_DIALOG_SHOW, argument)); + default: + lyxerr << "Inset type '" << name << + "' not recognized in LFUN_DIALOG_SHOW_NEW_INSET" << std:: endl; + insetCodeOK = false; + break; + } // end switch(code) + if (insetCodeOK) + dispatch(FuncRequest(LFUN_DIALOG_SHOW, name + " " + data)); 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()) { @@ -1495,7 +1485,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) arg = token(argument, '|', 0); opt1 = token(argument, '|', 1); } - InsetCommandParams icp("cite"); + InsetCommandParams icp(CITE_CODE); icp["key"] = from_utf8(arg); if (!opt1.empty()) icp["before"] = from_utf8(opt1); @@ -1519,18 +1509,18 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } else { setMessage(bformat(_("Opening child document %1$s..."), makeDisplayPath(filename.absFilename()))); - child = lyx_view_->loadLyXFile(filename, true); + child = loadAndViewFile(filename, true); 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->setParentName(parent->fileName()); - updateLabels(*child->getMasterBuffer()); + child->setParentName(parent->absFileName()); + updateLabels(*child->masterBuffer()); lyx_view_->setBuffer(child); if (parsed) - lyx_view_->showErrorList("Parse"); + lyx_view_->errors("Parse"); } // If a screen update is required (in case where auto_open is false), @@ -1592,6 +1582,28 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; } + case LFUN_CALL: { + FuncRequest func; + if (LyX::ref().topLevelCmdDef().lock(argument, func)) { + func.origin = cmd.origin; + dispatch(func); + LyX::ref().topLevelCmdDef().release(argument); + } else { + if (func.action == LFUN_UNKNOWN_ACTION) { + // unknown command definition + lyxerr << "Warning: unknown command definition `" + << argument << "'" + << endl; + } else { + // recursion detected + lyxerr << "Warning: Recursion in the command definition `" + << argument << "' detected" + << endl; + } + } + break; + } + case LFUN_PREFERENCES_SAVE: { lyxrc.write(makeAbsPath("preferences", package().user_support().absFilename()), @@ -1619,8 +1631,8 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } bool const graphicsbg_changed = - (lyx_name == lcolor.getLyXName(Color::graphicsbg) && - x11_name != lcolor.getX11Name(Color::graphicsbg)); + (lyx_name == lcolor.getLyXName(Color_graphicsbg) && + x11_name != lcolor.getX11Name(Color_graphicsbg)); if (!lcolor.setColor(lyx_name, x11_name)) { setErrorMessage( @@ -1663,7 +1675,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_INSET_APPLY: { BOOST_ASSERT(lyx_view_); string const name = cmd.getArg(0); - Inset * inset = lyx_view_->getDialogs().getOpenInset(name); + Inset * inset = lyx_view_->getOpenInset(name); if (inset) { FuncRequest fr(LFUN_INSET_MODIFY, argument); inset->dispatch(view()->cursor(), fr); @@ -1681,8 +1693,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) BOOST_ASSERT(lyx_view_); string action; string const name = split(argument, action, ' '); - Inset::Code const inset_code = - Inset::translate(name); + InsetCode const inset_code = insetCode(name); Cursor & cur = view()->cursor(); FuncRequest fr(LFUN_INSET_TOGGLE, action); @@ -1692,10 +1703,10 @@ void LyXFunc::dispatch(FuncRequest const & cmd) InsetIterator const end = inset_iterator_end(inset); for (; it != end; ++it) { if (!it->asInsetMath() - && (inset_code == Inset::NO_CODE + && (inset_code == NO_CODE || inset_code == it->lyxCode())) { Cursor tmpcur = cur; - tmpcur.pushLeft(*it); + tmpcur.pushBackward(*it); it->dispatch(tmpcur, fr); } } @@ -1735,7 +1746,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) << endl; } - if (defaults.writeFile(FileName(defaults.fileName()))) + if (defaults.writeFile(FileName(defaults.absFileName()))) setMessage(bformat(_("Document defaults saved in %1$s"), makeDisplayPath(fname))); else @@ -1745,33 +1756,67 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_BUFFER_PARAMS_APPLY: { BOOST_ASSERT(lyx_view_); - biblio::CiteEngine const engine = - lyx_view_->buffer()->params().getEngine(); + biblio::CiteEngine const oldEngine = + lyx_view_->buffer()->params().getEngine(); + + Buffer * buffer = lyx_view_->buffer(); + TextClassPtr oldClass = buffer->params().getTextClassPtr(); + + Cursor & cur = view()->cursor(); + cur.recordUndoFullDocument(); + istringstream ss(argument); Lexer lex(0,0); lex.setStream(ss); - int const unknown_tokens = - lyx_view_->buffer()->readHeader(lex); + 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; + << unknown_tokens << " unknown token" + << (unknown_tokens == 1 ? "" : "s") + << endl; } - if (engine == lyx_view_->buffer()->params().getEngine()) - break; - - Cursor & cur = view()->cursor(); - FuncRequest fr(LFUN_INSET_REFRESH); - - Inset & inset = lyx_view_->buffer()->inset(); - InsetIterator it = inset_iterator_begin(inset); - InsetIterator const end = inset_iterator_end(inset); - for (; it != end; ++it) - if (it->lyxCode() == Inset::CITE_CODE) - it->dispatch(cur, fr); + + updateLayout(oldClass, buffer); + + biblio::CiteEngine const newEngine = + lyx_view_->buffer()->params().getEngine(); + + if (oldEngine != newEngine) { + FuncRequest fr(LFUN_INSET_REFRESH); + + Inset & inset = lyx_view_->buffer()->inset(); + InsetIterator it = inset_iterator_begin(inset); + InsetIterator const end = inset_iterator_end(inset); + for (; it != end; ++it) + if (it->lyxCode() == CITE_CODE) + it->dispatch(cur, fr); + } + + updateFlags = Update::Force | Update::FitCursor; + break; + } + + case LFUN_LAYOUT_MODULES_CLEAR: { + BOOST_ASSERT(lyx_view_); + Buffer * buffer = lyx_view_->buffer(); + TextClassPtr oldClass = buffer->params().getTextClassPtr(); + view()->cursor().recordUndoFullDocument(); + buffer->params().clearLayoutModules(); + updateLayout(oldClass, buffer); + updateFlags = Update::Force | Update::FitCursor; + break; + } + + case LFUN_LAYOUT_MODULE_ADD: { + BOOST_ASSERT(lyx_view_); + Buffer * buffer = lyx_view_->buffer(); + TextClassPtr oldClass = buffer->params().getTextClassPtr(); + view()->cursor().recordUndoFullDocument(); + buffer->params().addLayoutModule(argument); + updateLayout(oldClass, buffer); + updateFlags = Update::Force | Update::FitCursor; break; } @@ -1779,10 +1824,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) BOOST_ASSERT(lyx_view_); Buffer * buffer = lyx_view_->buffer(); - textclass_type const old_class = - buffer->params().textclass; - - loadTextclass(argument); + loadTextClass(argument); std::pair const tc_pair = textclasslist.numberOfClass(argument); @@ -1790,30 +1832,36 @@ void LyXFunc::dispatch(FuncRequest const & cmd) if (!tc_pair.first) break; + textclass_type const old_class = buffer->params().getBaseClass(); textclass_type const new_class = tc_pair.second; + if (old_class == new_class) // nothing to do break; - lyx_view_->message(_("Converting document to new document class...")); - recordUndoFullDocument(view()); - buffer->params().textclass = new_class; - StableDocIterator backcur(view()->cursor()); - ErrorList & el = buffer->errorList("Class Switch"); - cap::switchBetweenClasses( - old_class, new_class, - static_cast(buffer->inset()), el); - - view()->setCursor(backcur.asDocIterator(&(buffer->inset()))); - - buffer->errors("Class Switch"); - updateLabels(*buffer); + //Save the old, possibly modular, layout for use in conversion. + TextClassPtr oldClass = buffer->params().getTextClassPtr(); + view()->cursor().recordUndoFullDocument(); + buffer->params().setBaseClass(new_class); + updateLayout(oldClass, buffer); + updateFlags = Update::Force | Update::FitCursor; + break; + } + + case LFUN_LAYOUT_RELOAD: { + BOOST_ASSERT(lyx_view_); + Buffer * buffer = lyx_view_->buffer(); + TextClassPtr oldClass = buffer->params().getTextClassPtr(); + textclass_type const tc = buffer->params().getBaseClass(); + textclasslist.reset(tc); + buffer->params().setBaseClass(tc); + updateLayout(oldClass, buffer); updateFlags = Update::Force | Update::FitCursor; break; } case LFUN_TEXTCLASS_LOAD: - loadTextclass(argument); + loadTextClass(argument); break; case LFUN_LYXRC_APPLY: { @@ -1831,6 +1879,8 @@ void LyXFunc::dispatch(FuncRequest const & cmd) actOnUpdatedPrefs(lyxrc_orig, lyxrc); + 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 @@ -1864,30 +1914,6 @@ void LyXFunc::dispatch(FuncRequest const & cmd) LyX::ref().session().bookmarks().clear(); break; - case LFUN_TOOLBAR_TOGGLE: { - BOOST_ASSERT(lyx_view_); - string const name = cmd.getArg(0); - bool const allowauto = cmd.getArg(1) == "allowauto"; - lyx_view_->toggleToolbarState(name, allowauto); - ToolbarInfo * tbi = lyx_view_->getToolbarInfo(name); - if (!tbi) { - setMessage(bformat(_("Unknown toolbar \"%1$s\""), - from_utf8(name))); - break; - } - docstring state; - if (tbi->flags & ToolbarInfo::ON) - state = _("on"); - else if (tbi->flags & ToolbarInfo::OFF) - state = _("off"); - else if (tbi->flags & ToolbarInfo::AUTO) - state = _("auto"); - - setMessage(bformat(_("Toolbar \"%1$s\" state set to %2$s"), - _(tbi->gui_name), state)); - break; - } - default: { BOOST_ASSERT(lyx_view_); view()->cursor().dispatch(cmd); @@ -1903,14 +1929,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) // also initializes the position cache for all insets in // (at least partially) visible top-level paragraphs. // We will redraw the screen only if needed. - if (view()->update(updateFlags)) { - // Buffer::changed() signals that a repaint is needed. - // The frontend (WorkArea) knows which area to repaint - // thanks to the ViewMetricsInfo updated above. - lyx_view_->buffer()->changed(); - } - - lyx_view_->updateStatusBar(); + view()->processUpdateFlags(updateFlags); // if we executed a mutating lfun, mark the buffer as dirty if (flag.enabled() @@ -1922,12 +1941,10 @@ void LyXFunc::dispatch(FuncRequest const & cmd) theSelection().haveSelection(view()->cursor().selection()); if (view()->cursor().inTexted()) { - lyx_view_->updateLayoutChoice(); } } } if (!quitting && lyx_view_) { - lyx_view_->updateToolbars(); // Some messages may already be translated, so we cannot use _() sendDispatchMessage(translateIfPossible(getMessage()), cmd); } @@ -1941,7 +1958,7 @@ void LyXFunc::sendDispatchMessage(docstring const & msg, FuncRequest const & cmd || cmd.origin == FuncRequest::COMMANDBUFFER); if (cmd.action == LFUN_SELF_INSERT || !verbose) { - LYXERR(Debug::ACTION) << "dispatch msg is " << to_utf8(msg) << endl; + LYXERR(Debug::ACTION, "dispatch msg is " << to_utf8(msg)); if (!msg.empty()) lyx_view_->message(msg); return; @@ -1962,7 +1979,7 @@ void LyXFunc::sendDispatchMessage(docstring const & msg, FuncRequest const & cmd } } - docstring const shortcuts = theTopLevelKeymap().printbindings(cmd); + docstring const shortcuts = theTopLevelKeymap().printBindings(cmd); if (!shortcuts.empty()) comname += ": " + shortcuts; @@ -1974,8 +1991,7 @@ void LyXFunc::sendDispatchMessage(docstring const & msg, FuncRequest const & cmd dispatch_msg += '(' + rtrim(comname) + ')'; } - LYXERR(Debug::ACTION) << "verbose dispatch msg " - << to_utf8(dispatch_msg) << endl; + LYXERR(Debug::ACTION, "verbose dispatch msg " << to_utf8(dispatch_msg)); if (!dispatch_msg.empty()) lyx_view_->message(dispatch_msg); } @@ -1990,7 +2006,7 @@ void LyXFunc::menuNew(string const & name, bool fromTemplate) if (lyx_view_->buffer()) { string const trypath = lyx_view_->buffer()->filePath(); // If directory is writeable, use this as default. - if (isDirWriteable(FileName(trypath))) + if (FileName(trypath).isDirWritable()) initpath = trypath; } @@ -2000,7 +2016,7 @@ void LyXFunc::menuNew(string const & name, bool fromTemplate) filename = addName(lyxrc.document_path, "newfile" + convert(++newfile_number) + ".lyx"); while (theBufferList().exists(filename) || - fs::is_readable(FileName(filename).toFilesystemEncoding())) { + FileName(filename).isReadable()) { ++newfile_number; filename = addName(lyxrc.document_path, "newfile" + convert(newfile_number) + @@ -2011,13 +2027,12 @@ void LyXFunc::menuNew(string const & name, bool fromTemplate) // The template stuff string templname; if (fromTemplate) { - FileDialog fileDlg(_("Select template file"), - LFUN_SELECT_FILE_SYNC, - make_pair(_("Documents|#o#O"), from_utf8(lyxrc.document_path)), - make_pair(_("Templates|#T#t"), from_utf8(lyxrc.template_path))); + FileDialog dlg(_("Select template file")); + dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path)); + dlg.setButton1(_("Templates|#T#t"), from_utf8(lyxrc.template_path)); FileDialog::Result result = - fileDlg.open(from_utf8(lyxrc.template_path), + dlg.open(from_utf8(lyxrc.template_path), FileFilterList(_("LyX Documents (*.lyx)")), docstring()); @@ -2034,6 +2049,35 @@ void LyXFunc::menuNew(string const & name, bool fromTemplate) } +Buffer * LyXFunc::loadAndViewFile(FileName const & filename, bool tolastfiles) +{ + lyx_view_->setBusy(true); + + Buffer * newBuffer = checkAndLoadLyXFile(filename); + + if (!newBuffer) { + lyx_view_->message(_("Document not loaded.")); + lyx_view_->setBusy(false); + return 0; + } + + lyx_view_->setBuffer(newBuffer); + + // scroll to the position when the file was last closed + if (lyxrc.use_lastfilepos) { + LastFilePosSection::FilePos filepos = + LyX::ref().session().lastFilePos().load(filename); + lyx_view_->view()->moveToPosition(filepos.pit, filepos.pos, 0, 0); + } + + if (tolastfiles) + LyX::ref().session().lastFiles().add(filename); + + lyx_view_->setBusy(false); + return newBuffer; +} + + void LyXFunc::open(string const & fname) { string initpath = lyxrc.document_path; @@ -2041,20 +2085,20 @@ void LyXFunc::open(string const & fname) if (lyx_view_->buffer()) { string const trypath = lyx_view_->buffer()->filePath(); // If directory is writeable, use this as default. - if (isDirWriteable(FileName(trypath))) + if (FileName(trypath).isDirWritable()) initpath = trypath; } string filename; if (fname.empty()) { - FileDialog fileDlg(_("Select document to open"), - LFUN_FILE_OPEN, - make_pair(_("Documents|#o#O"), from_utf8(lyxrc.document_path)), - make_pair(_("Examples|#E#e"), from_utf8(addPath(package().system_support().absFilename(), "examples")))); + FileDialog dlg(_("Select document to open"), LFUN_FILE_OPEN); + dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path)); + dlg.setButton2(_("Examples|#E#e"), + from_utf8(addPath(package().system_support().absFilename(), "examples"))); FileDialog::Result result = - fileDlg.open(from_utf8(initpath), + dlg.open(from_utf8(initpath), FileFilterList(_("LyX Documents (*.lyx)")), docstring()); @@ -2078,7 +2122,7 @@ void LyXFunc::open(string const & fname) filename = fullname.absFilename(); // if the file doesn't exist, let the user create one - if (!fs::exists(fullname.toFilesystemEncoding())) { + if (!fullname.exists()) { // the user specifically chose this name. Believe him. Buffer * const b = newFile(filename, string(), true); if (b) @@ -2090,11 +2134,11 @@ void LyXFunc::open(string const & fname) lyx_view_->message(bformat(_("Opening document %1$s..."), disp_fn)); docstring str2; - Buffer * buf = lyx_view_->loadLyXFile(fullname); + Buffer * buf = loadAndViewFile(fullname); if (buf) { updateLabels(*buf); lyx_view_->setBuffer(buf); - lyx_view_->showErrorList("Parse"); + lyx_view_->errors("Parse"); str2 = bformat(_("Document %1$s opened."), disp_fn); } else { str2 = bformat(_("Could not open document %1$s"), disp_fn); @@ -2108,8 +2152,8 @@ void LyXFunc::doImport(string const & argument) string format; string filename = split(argument, format, ' '); - LYXERR(Debug::INFO) << "LyXFunc::doImport: " << format - << " file: " << filename << endl; + LYXERR(Debug::INFO, "LyXFunc::doImport: " << format + << " file: " << filename); // need user interaction if (filename.empty()) { @@ -2118,18 +2162,17 @@ void LyXFunc::doImport(string const & argument) if (lyx_view_->buffer()) { string const trypath = lyx_view_->buffer()->filePath(); // If directory is writeable, use this as default. - if (isDirWriteable(FileName(trypath))) + if (FileName(trypath).isDirWritable()) initpath = trypath; } docstring const text = bformat(_("Select %1$s file to import"), formats.prettyName(format)); - FileDialog fileDlg(text, - LFUN_BUFFER_IMPORT, - make_pair(_("Documents|#o#O"), from_utf8(lyxrc.document_path)), - make_pair(_("Examples|#E#e"), - from_utf8(addPath(package().system_support().absFilename(), "examples")))); + FileDialog dlg(text, LFUN_BUFFER_IMPORT); + dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path)); + dlg.setButton2(_("Examples|#E#e"), + from_utf8(addPath(package().system_support().absFilename(), "examples"))); docstring filter = formats.prettyName(format); filter += " (*."; @@ -2138,7 +2181,7 @@ void LyXFunc::doImport(string const & argument) filter += ')'; FileDialog::Result result = - fileDlg.open(from_utf8(initpath), + dlg.open(from_utf8(initpath), FileFilterList(filter), docstring()); @@ -2170,7 +2213,7 @@ void LyXFunc::doImport(string const & argument) // if the file exists already, and we didn't do // -i lyx thefile.lyx, warn - if (fs::exists(lyxfile.toFilesystemEncoding()) && fullname != lyxfile) { + if (lyxfile.exists() && fullname != lyxfile) { docstring const file = makeDisplayPath(lyxfile.absFilename(), 30); docstring text = bformat(_("The document %1$s already exists.\n\n" @@ -2185,7 +2228,7 @@ void LyXFunc::doImport(string const & argument) } ErrorList errorList; - Importer::Import(lyx_view_, fullname, format, errorList); + import(lyx_view_, fullname, format, errorList); // FIXME (Abdel 12/08/06): Is there a need to display the error list here? } @@ -2202,15 +2245,15 @@ void LyXFunc::closeBuffer() void LyXFunc::reloadBuffer() { - FileName filename(lyx_view_->buffer()->fileName()); + FileName filename(lyx_view_->buffer()->absFileName()); docstring const disp_fn = makeDisplayPath(filename.absFilename()); docstring str; closeBuffer(); - Buffer * buf = lyx_view_->loadLyXFile(filename); + Buffer * buf = loadAndViewFile(filename); if (buf) { updateLabels(*buf); lyx_view_->setBuffer(buf); - lyx_view_->showErrorList("Parse"); + lyx_view_->errors("Parse"); str = bformat(_("Document %1$s reloaded."), disp_fn); } else { str = bformat(_("Could not reload document %1$s"), disp_fn); @@ -2241,12 +2284,12 @@ docstring const LyXFunc::viewStatusMessage() { // When meta-fake key is pressed, show the key sequence so far + "M-". if (wasMetaKey()) - return keyseq->print(true) + "M-"; + 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); + if (keyseq.length() > 0 && !keyseq.deleted()) + return keyseq.printOptions(true); BOOST_ASSERT(lyx_view_); if (!lyx_view_->buffer()) @@ -2265,7 +2308,25 @@ BufferView * LyXFunc::view() const bool LyXFunc::wasMetaKey() const { - return (meta_fake_bit != key_modifier::none); + return (meta_fake_bit != NoModifier); +} + + +void LyXFunc::updateLayout(TextClassPtr const & oldlayout, + Buffer * buffer) +{ + lyx_view_->message(_("Converting document to new document class...")); + + StableDocIterator backcur(view()->cursor()); + ErrorList & el = buffer->errorList("Class Switch"); + cap::switchBetweenClasses( + oldlayout, buffer->params().getTextClassPtr(), + static_cast(buffer->inset()), el); + + view()->setCursor(backcur.asDocIterator(&(buffer->inset()))); + + buffer->errors("Class Switch"); + updateLabels(*buffer); } @@ -2304,13 +2365,13 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new) case LyXRC::RC_DATE_INSERT_FORMAT: case LyXRC::RC_DEFAULT_LANGUAGE: case LyXRC::RC_DEFAULT_PAPERSIZE: + 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) { - string const encoded = FileName( - lyxrc_new.document_path).toFilesystemEncoding(); - if (fs::exists(encoded) && fs::is_directory(encoded)) + FileName path(lyxrc_new.document_path); + if (path.exists() && path.isDirectory()) support::package().document_dir() = FileName(lyxrc.document_path); } case LyXRC::RC_ESC_CHARS: @@ -2369,9 +2430,7 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new) case LyXRC::RC_SCREEN_FONT_SIZES: case LyXRC::RC_SCREEN_FONT_TYPEWRITER: case LyXRC::RC_SCREEN_FONT_TYPEWRITER_FOUNDRY: - case LyXRC::RC_SCREEN_GEOMETRY_HEIGHT: - case LyXRC::RC_SCREEN_GEOMETRY_WIDTH: - case LyXRC::RC_SCREEN_GEOMETRY_XYSAVED: + case LyXRC::RC_GEOMETRY_SESSION: case LyXRC::RC_SCREEN_ZOOM: case LyXRC::RC_SERVERPIPE: case LyXRC::RC_SET_COLOR: @@ -2393,8 +2452,10 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new) case LyXRC::RC_USE_ESC_CHARS: case LyXRC::RC_USE_INP_ENC: case LyXRC::RC_USE_PERS_DICT: + 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_VIEWER: case LyXRC::RC_LAST: break;