X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FLyXFunc.cpp;h=ee4702067d5cc75a9b817a00af64c086c2f48b0b;hb=027563eec2d2a1b81391b221f9ca40d823713235;hp=253dd67b86882d9925f5d2a96d319a157e7562a3;hpb=d4b02ad711246494499cdaa5418f5ebbc54530e2;p=lyx.git diff --git a/src/LyXFunc.cpp b/src/LyXFunc.cpp index 253dd67b86..ee4702067d 100644 --- a/src/LyXFunc.cpp +++ b/src/LyXFunc.cpp @@ -18,10 +18,10 @@ */ #include -#include #include "LyXFunc.h" +#include "LayoutFile.h" #include "BranchList.h" #include "buffer_funcs.h" #include "Buffer.h" @@ -33,14 +33,12 @@ #include "Converter.h" #include "Cursor.h" #include "CutAndPaste.h" -#include "debug.h" #include "DispatchResult.h" #include "Encoding.h" #include "ErrorList.h" #include "Format.h" #include "FuncRequest.h" #include "FuncStatus.h" -#include "gettext.h" #include "InsetIterator.h" #include "Intl.h" #include "KeyMap.h" @@ -57,8 +55,6 @@ #include "Row.h" #include "Server.h" #include "Session.h" -#include "TextClassList.h" -#include "ToolbarBackend.h" #include "insets/InsetBox.h" #include "insets/InsetBranch.h" @@ -70,22 +66,22 @@ #include "insets/InsetGraphics.h" #include "insets/InsetInclude.h" #include "insets/InsetNote.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/FileDialog.h" -#include "frontends/FontLoader.h" #include "frontends/KeySymbol.h" #include "frontends/LyXView.h" #include "frontends/Selection.h" +#include "support/debug.h" #include "support/environment.h" -#include "support/FileFilterList.h" #include "support/FileName.h" #include "support/filetools.h" +#include "support/gettext.h" #include "support/lstrings.h" #include "support/Path.h" #include "support/Package.h" @@ -93,137 +89,40 @@ #include "support/convert.h" #include "support/os.h" -#include - #include +#include -using std::endl; -using std::make_pair; -using std::pair; -using std::string; -using std::istringstream; -using std::ostringstream; -using std::find; -using std::vector; +using namespace std; +using namespace lyx::support; namespace lyx { using frontend::LyXView; -using support::absolutePath; -using support::addName; -using support::addPath; -using support::bformat; -using support::changeExtension; -using support::contains; -using support::FileFilterList; -using support::FileName; -using support::fileSearch; -using support::i18nLibFileSearch; -using support::makeDisplayPath; -using support::makeAbsPath; -using support::package; -using support::quoteName; -using support::rtrim; -using support::split; -using support::subst; -using support::Systemcall; -using support::token; -using support::trim; -using support::prefixIs; - - namespace Alert = frontend::Alert; -extern bool quitting; -extern bool use_gui; - namespace { -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) +void reconfigure(LyXView * lv, string const & option) { // emit message signal. - lv.message(_("Running configure...")); + if (lv) + lv->message(_("Running configure...")); // Run configure in user lyx directory - support::PathChanger p(package().user_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")); + if (lv) + lv->message(_("Reloading configuration...")); + lyxrc.read(libFileSearch(string(), "lyxrc.defaults")); // Re-read packages.lst LaTeXFeatures::getAvailable(); @@ -310,7 +209,7 @@ void LyXFunc::initKeySequences(KeyMap * kb) void LyXFunc::setLyXView(LyXView * lv) { - if (!quitting && lyx_view_ && lyx_view_->view() && lyx_view_ != lv) + if (lyx_view_ && lyx_view_->view() && lyx_view_ != lv) // save current selection to the selection buffer to allow // middle-button paste in another window cap::saveSelection(lyx_view_->view()->cursor()); @@ -318,7 +217,7 @@ void LyXFunc::setLyXView(LyXView * lv) } -void LyXFunc::handleKeyFunc(kb_action action) +void LyXFunc::handleKeyFunc(FuncCode action) { char_type c = encoded_last_key; @@ -336,7 +235,8 @@ void LyXFunc::handleKeyFunc(kb_action action) 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) { BOOST_ASSERT(lyx_view_); @@ -396,7 +296,8 @@ void LyXFunc::processKeySym(KeySymbol const & keysym, KeyModifier state) if (keysym.isModifier()) { LYXERR(Debug::KEY, "isModifier true"); - lyx_view_->restartCursor(); + if (lyx_view_) + lyx_view_->restartCursor(); return; } @@ -411,8 +312,7 @@ void LyXFunc::processKeySym(KeySymbol const & keysym, KeyModifier state) cancel_meta_seq.reset(); FuncRequest func = cancel_meta_seq.addkey(keysym, state); - LYXERR(Debug::KEY, BOOST_CURRENT_FUNCTION - << " action first set to [" << func.action << ']'); + 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. @@ -420,8 +320,7 @@ void LyXFunc::processKeySym(KeySymbol const & keysym, KeyModifier state) 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 << ']'); + LYXERR(Debug::KEY, "action now set to [" << func.action << ']'); } // Dont remove this unless you know what you are doing. @@ -431,9 +330,8 @@ void LyXFunc::processKeySym(KeySymbol const & keysym, KeyModifier state) if (func.action == LFUN_NOACTION) func = FuncRequest(LFUN_COMMAND_PREFIX); - LYXERR(Debug::KEY, BOOST_CURRENT_FUNCTION - << " Key [action=" << func.action << "][" - << to_utf8(keyseq.print(KeySequence::Portable)) << ']'); + 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 @@ -476,9 +374,12 @@ void LyXFunc::processKeySym(KeySymbol const & keysym, KeyModifier state) } } else { dispatch(func); + if (!lyx_view_) + return; } - lyx_view_->restartCursor(); + if (lyx_view_) + lyx_view_->restartCursor(); } @@ -487,7 +388,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const //lyxerr << "LyXFunc::getStatus: cmd: " << cmd << endl; FuncStatus flag; - Buffer * buf = lyx_view_? lyx_view_->buffer() : 0; + Buffer * buf = lyx_view_ ? lyx_view_->buffer() : 0; if (cmd.action == LFUN_NOACTION) { flag.message(from_utf8(N_("Nothing to do"))); @@ -535,11 +436,35 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const bool enable = true; switch (cmd.action) { + // FIXME: these cases should be hidden in GuiApplication::getStatus(). + case LFUN_WINDOW_CLOSE: + if (theApp()) + return theApp()->getStatus(cmd); + enable = false; + break; + + // FIXME: these cases should be hidden in GuiView::getStatus(). case LFUN_DIALOG_TOGGLE: case LFUN_DIALOG_SHOW: + case LFUN_UI_TOGGLE: case LFUN_DIALOG_UPDATE: + // FIXME: add special handling for about and prefs dialogs here + // which do not depend on GuiView. + if (lyx_view_) + return lyx_view_->getStatus(cmd); + else + enable = false; + break; + case LFUN_TOOLBAR_TOGGLE: case LFUN_INSET_APPLY: + case LFUN_BUFFER_WRITE: + case LFUN_BUFFER_WRITE_AS: + case LFUN_SPLIT_VIEW: + case LFUN_CLOSE_TAB_GROUP: + case LFUN_COMPLETION_POPUP: + case LFUN_COMPLETION_INLINE: + case LFUN_COMPLETION_COMPLETE: if (lyx_view_) return lyx_view_->getStatus(cmd); enable = false; @@ -592,33 +517,33 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const enable = getStatus(fr).enabled(); break; } - - case LFUN_BUFFER_WRITE: { - enable = lyx_view_->buffer()->isUnnamed() - || !lyx_view_->buffer()->isClean(); + + // This could be used for the no-GUI version. The GUI version is handled in + // LyXView::getStatus(). See above. + /* + case LFUN_BUFFER_WRITE: + case LFUN_BUFFER_WRITE_AS: { + Buffer * b = theBufferList().getBuffer(cmd.getArg(0)); + enable = b && (b->isUnnamed() || !b->isClean()); break; } - + */ case LFUN_BUFFER_WRITE_ALL: { - // We enable the command only if there are some modified buffers + // We enable the command only if there are some modified buffers Buffer * first = theBufferList().first(); - bool modified = false; - if (first) { - Buffer * b = 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()) { - modified = true; - break; - } - b = theBufferList().next(b); - } while (b != first); - } - - enable = modified; - + do { + if (!b->isClean()) { + enable = true; + break; + } + b = theBufferList().next(b); + } while (b != first); break; } @@ -632,10 +557,6 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const enable = LyX::ref().session().bookmarks().size() > 0; break; - 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 case LFUN_COMMAND_SEQUENCE: { @@ -649,7 +570,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const case LFUN_CALL: { FuncRequest func; - std::string name = to_utf8(cmd.argument()); + string name = to_utf8(cmd.argument()); if (LyX::ref().topLevelCmdDef().lock(name, func)) { func.origin = cmd.origin; flag = getStatus(func); @@ -672,7 +593,6 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const case LFUN_CANCEL: case LFUN_META_PREFIX: case LFUN_BUFFER_CLOSE: - case LFUN_BUFFER_WRITE_AS: case LFUN_BUFFER_UPDATE: case LFUN_BUFFER_VIEW: case LFUN_MASTER_BUFFER_UPDATE: @@ -681,7 +601,6 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const case LFUN_BUFFER_AUTO_SAVE: case LFUN_RECONFIGURE: case LFUN_HELP_OPEN: - case LFUN_FILE_NEW: case LFUN_FILE_OPEN: case LFUN_DROP_LAYOUTS_CHOICE: case LFUN_MENU_OPEN: @@ -691,7 +610,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const case LFUN_DIALOG_HIDE: case LFUN_DIALOG_DISCONNECT_INSET: case LFUN_BUFFER_CHILD_OPEN: - case LFUN_TOGGLE_CURSOR_FOLLOWS_SCROLLBAR: + case LFUN_CURSOR_FOLLOWS_SCROLLBAR_TOGGLE: case LFUN_KEYMAP_OFF: case LFUN_KEYMAP_PRIMARY: case LFUN_KEYMAP_SECONDARY: @@ -791,26 +710,23 @@ void showPrintError(string const & name) } -void loadTextClass(string const & name) +bool loadLayoutFile(string const & name, string const & buf_path) { - std::pair const tc_pair = - textclasslist.numberOfClass(name); - - if (!tc_pair.first) { + if (!LayoutFileList::get().haveClass(name)) { lyxerr << "Document class \"" << name << "\" does not exist." - << std::endl; - return; + << endl; + return false; } - textclass_type const tc = tc_pair.second; - - if (!textclasslist[tc].load()) { - docstring s = bformat(_("The document class %1$s." - "could not be loaded."), - from_utf8(textclasslist[tc].name())); + 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; } + return true; } @@ -822,7 +738,7 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new); void LyXFunc::dispatch(FuncRequest const & cmd) { string const argument = to_utf8(cmd.argument()); - kb_action const action = cmd.action; + FuncCode const action = cmd.action; LYXERR(Debug::ACTION, "\nLyXFunc::dispatch: cmd: " << cmd); //lyxerr << "LyXFunc::dispatch: cmd: " << cmd << endl; @@ -844,22 +760,6 @@ void LyXFunc::dispatch(FuncRequest const & cmd) 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: - case LFUN_INSET_APPLY: - BOOST_ASSERT(lyx_view_); - lyx_view_->dispatch(cmd); - if (lyx_view_->view()) - updateFlags = lyx_view_->view()->cursor().result().update(); - break; case LFUN_WORD_FIND_FORWARD: case LFUN_WORD_FIND_BACKWARD: { @@ -915,64 +815,10 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } // --- Menus ----------------------------------------------- - case LFUN_BUFFER_NEW: - menuNew(argument, false); - updateFlags = Update::None; - break; - - case LFUN_BUFFER_NEW_TEMPLATE: - menuNew(argument, true); - updateFlags = Update::None; - break; - case LFUN_BUFFER_CLOSE: - closeBuffer(); - updateFlags = Update::None; - 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()->absFileName())); - lyx_view_->message(str); - lyx_view_->buffer()->menuWrite(); - lyx_view_->message(str + _(" done.")); - } else { - lyx_view_->buffer()->writeAs(); - } - updateFlags = Update::None; - break; - - case LFUN_BUFFER_WRITE_AS: - BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); - lyx_view_->buffer()->writeAs(argument); - updateFlags = Update::None; - break; - - case LFUN_BUFFER_WRITE_ALL: { - Buffer * first = theBufferList().first(); - if (first) { - Buffer * b = first; - lyx_view_->message(_("Saving all documents...")); - - // We cannot use a for loop as the buffer list cycles. - do { - if (!b->isClean()) { - if (!b->isUnnamed()) { - b->menuWrite(); - lyxerr[Debug::ACTION] << "Saved " << b->absFileName() << endl; - } else - b->writeAs(); - } - b = theBufferList().next(b); - } while (b != first); - lyx_view_->message(_("All documents saved.")); - } - + lyx_view_->closeBuffer(); updateFlags = Update::None; break; - } case LFUN_BUFFER_RELOAD: { BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); @@ -1033,7 +879,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) if (!format) { lyxerr << "Format \"" << format_name << "\" not recognized!" - << std::endl; + << endl; break; } @@ -1099,7 +945,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) string const path = buffer->temppath(); // Prevent the compiler from optimizing away p FileName pp(path); - support::PathChanger p(pp); + PathChanger p(pp); // there are three cases here: // 1. we print to a file @@ -1174,26 +1020,20 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; } + // FIXME: There is need for a command-line import. + /* case LFUN_BUFFER_IMPORT: doImport(argument); break; - - case LFUN_LYX_QUIT: - // quitting is triggered by the gui code - // (leaving the event loop). - lyx_view_->message(from_utf8(N_("Exiting."))); - if (theBufferList().quitWriteAll()) - theApp()->closeAllViews(); - break; + */ case LFUN_BUFFER_AUTO_SAVE: lyx_view_->buffer()->autoSave(); break; case LFUN_RECONFIGURE: - BOOST_ASSERT(lyx_view_); // argument is any additional parameter to the configure.py command - reconfigure(*lyx_view_, argument); + reconfigure(lyx_view_, argument); break; case LFUN_HELP_OPEN: { @@ -1211,11 +1051,11 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } lyx_view_->message(bformat(_("Opening help file %1$s..."), makeDisplayPath(fname.absFilename()))); - Buffer * buf = loadAndViewFile(fname, false); + Buffer * buf = lyx_view_->loadDocument(fname, false); if (buf) { updateLabels(*buf); lyx_view_->setBuffer(buf); - lyx_view_->errors("Parse"); + buf->errors("Parse"); } updateFlags = Update::None; break; @@ -1267,42 +1107,6 @@ void LyXFunc::dispatch(FuncRequest const & cmd) reloadBuffer(); break; - // --- buffers ---------------------------------------- - case LFUN_BUFFER_SWITCH: - BOOST_ASSERT(lyx_view_); - lyx_view_->setBuffer(theBufferList().getBuffer(argument)); - updateFlags = Update::None; - break; - - case LFUN_BUFFER_NEXT: - BOOST_ASSERT(lyx_view_); - lyx_view_->setBuffer(theBufferList().next(lyx_view_->buffer())); - updateFlags = Update::None; - break; - - case LFUN_BUFFER_PREVIOUS: - BOOST_ASSERT(lyx_view_); - lyx_view_->setBuffer(theBufferList().previous(lyx_view_->buffer())); - updateFlags = Update::None; - break; - - case LFUN_FILE_NEW: { - BOOST_ASSERT(lyx_view_); - 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_); - open(argument); - updateFlags = Update::None; - break; - // --- lyxserver commands ---------------------------- case LFUN_SERVER_GET_NAME: BOOST_ASSERT(lyx_view_ && lyx_view_->buffer()); @@ -1336,7 +1140,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) if (theBufferList().exists(s.absFilename())) buf = theBufferList().getBuffer(s.absFilename()); else { - buf = loadAndViewFile(s); + buf = lyx_view_->loadDocument(s); loaded = true; } } @@ -1350,7 +1154,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) lyx_view_->setBuffer(buf); view()->setCursorFromRow(row); if (loaded) - lyx_view_->errors("Parse"); + buf->errors("Parse"); updateFlags = Update::FitCursor; break; } @@ -1432,6 +1236,11 @@ void LyXFunc::dispatch(FuncRequest const & cmd) data = InsetNoteMailer::params2string(p); break; } + case SPACE_CODE: { + InsetSpaceParams p; + data = InsetSpaceMailer::params2string(p); + break; + } case VSPACE_CODE: { VSpace space; data = InsetVSpaceMailer::params2string(space); @@ -1444,7 +1253,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } default: lyxerr << "Inset type '" << name << - "' not recognized in LFUN_DIALOG_SHOW_NEW_INSET" << std:: endl; + "' not recognized in LFUN_DIALOG_SHOW_NEW_INSET" << endl; insetCodeOK = false; break; } // end switch(code) @@ -1490,18 +1299,18 @@ void LyXFunc::dispatch(FuncRequest const & cmd) } else { setMessage(bformat(_("Opening child document %1$s..."), makeDisplayPath(filename.absFilename()))); - child = loadAndViewFile(filename, true); + 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->setParentName(parent->absFileName()); + child->setParent(parent); updateLabels(*child->masterBuffer()); lyx_view_->setBuffer(child); if (parsed) - lyx_view_->errors("Parse"); + child->errors("Parse"); } // If a screen update is required (in case where auto_open is false), @@ -1512,7 +1321,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; } - case LFUN_TOGGLE_CURSOR_FOLLOWS_SCROLLBAR: + case LFUN_CURSOR_FOLLOWS_SCROLLBAR_TOGGLE: BOOST_ASSERT(lyx_view_); lyxrc.cursor_follows_scrollbar = !lyxrc.cursor_follows_scrollbar; break; @@ -1592,15 +1401,6 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; } - case LFUN_SCREEN_FONT_UPDATE: - BOOST_ASSERT(lyx_view_); - // handle the screen font changes. - theFontLoader().update(); - /// 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_SET_COLOR: { string lyx_name; string const x11_name = split(argument, lyx_name, ' '); @@ -1720,13 +1520,9 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_BUFFER_PARAMS_APPLY: { BOOST_ASSERT(lyx_view_); - biblio::CiteEngine const oldEngine = - lyx_view_->buffer()->params().getEngine(); Buffer * buffer = lyx_view_->buffer(); - - TextClassPtr oldClass = buffer->params().getTextClassPtr(); - + DocumentClass * oldClass = buffer->params().documentClassPtr(); Cursor & cur = view()->cursor(); cur.recordUndoFullDocument(); @@ -1744,30 +1540,21 @@ void LyXFunc::dispatch(FuncRequest const & cmd) 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; + // 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: { BOOST_ASSERT(lyx_view_); Buffer * buffer = lyx_view_->buffer(); - TextClassPtr oldClass = buffer->params().getTextClassPtr(); + DocumentClass * oldClass = buffer->params().documentClassPtr(); view()->cursor().recordUndoFullDocument(); buffer->params().clearLayoutModules(); + buffer->params().makeDocumentClass(); updateLayout(oldClass, buffer); updateFlags = Update::Force | Update::FitCursor; break; @@ -1776,9 +1563,10 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_LAYOUT_MODULE_ADD: { BOOST_ASSERT(lyx_view_); Buffer * buffer = lyx_view_->buffer(); - TextClassPtr oldClass = buffer->params().getTextClassPtr(); + DocumentClass * oldClass = buffer->params().documentClassPtr(); view()->cursor().recordUndoFullDocument(); buffer->params().addLayoutModule(argument); + buffer->params().makeDocumentClass(); updateLayout(oldClass, buffer); updateFlags = Update::Force | Update::FitCursor; break; @@ -1788,26 +1576,23 @@ void LyXFunc::dispatch(FuncRequest const & cmd) BOOST_ASSERT(lyx_view_); Buffer * buffer = lyx_view_->buffer(); - loadTextClass(argument); - - std::pair const tc_pair = - textclasslist.numberOfClass(argument); - - if (!tc_pair.first) + if (!loadLayoutFile(argument, buffer->temppath()) && + !loadLayoutFile(argument, buffer->filePath())) break; - textclass_type const old_class = buffer->params().getBaseClass(); - textclass_type const new_class = tc_pair.second; + LayoutFile const * old_layout = buffer->params().baseClass(); + LayoutFile const * new_layout = &(LayoutFileList::get()[argument]); - if (old_class == new_class) + if (old_layout == new_layout) // nothing to do break; //Save the old, possibly modular, layout for use in conversion. - TextClassPtr oldClass = buffer->params().getTextClassPtr(); + DocumentClass * oldDocClass = buffer->params().documentClassPtr(); view()->cursor().recordUndoFullDocument(); - buffer->params().setBaseClass(new_class); - updateLayout(oldClass, buffer); + buffer->params().setBaseClass(argument); + buffer->params().makeDocumentClass(); + updateLayout(oldDocClass, buffer); updateFlags = Update::Force | Update::FitCursor; break; } @@ -1815,17 +1600,18 @@ void LyXFunc::dispatch(FuncRequest const & cmd) 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); + DocumentClass * oldClass = buffer->params().documentClassPtr(); + LayoutFileIndex bc = buffer->params().baseClassID(); + LayoutFileList::get().reset(bc); + buffer->params().makeDocumentClass(); updateLayout(oldClass, buffer); updateFlags = Update::Force | Update::FitCursor; break; } case LFUN_TEXTCLASS_LOAD: - loadTextClass(argument); + loadLayoutFile(argument, lyx_view_->buffer()->temppath()) || + loadLayoutFile(argument, lyx_view_->buffer()->filePath()); break; case LFUN_LYXRC_APPLY: { @@ -1853,39 +1639,69 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; } - case LFUN_WINDOW_NEW: - theApp()->createView(); - break; - - case LFUN_WINDOW_CLOSE: - BOOST_ASSERT(lyx_view_); - BOOST_ASSERT(theApp()); - // update bookmark pit of the current buffer before window close - for (size_t i = 0; i < LyX::ref().session().bookmarks().size(); ++i) - gotoBookmark(i+1, false, false); - // ask the user for saving changes or cancel quit - if (!theBufferList().quitWriteAll()) - break; - lyx_view_->close(); - return; - case LFUN_BOOKMARK_GOTO: // go to bookmark, open unopened file and switch to buffer if necessary gotoBookmark(convert(to_utf8(cmd.argument())), true, true); + updateFlags = Update::FitCursor; break; case LFUN_BOOKMARK_CLEAR: LyX::ref().session().bookmarks().clear(); break; - default: { - BOOST_ASSERT(lyx_view_); + default: + BOOST_ASSERT(theApp()); + // Let the frontend dispatch its own actions. + if (theApp()->dispatch(cmd)) + // Nothing more to do. + return; + + // Everything below is only for active lyx_view_ + if (lyx_view_ == 0) + break; + + // Let the current LyXView dispatch its own actions. + if (lyx_view_->dispatch(cmd)) { + if (lyx_view_->view()) + updateFlags = lyx_view_->view()->cursor().result().update(); + break; + } + + BOOST_ASSERT(lyx_view_->view()); + // Let the current BufferView dispatch its own actions. + if (view()->dispatch(cmd)) { + // The BufferView took care of its own updates if needed. + updateFlags = Update::None; + break; + } + + // Let the current Cursor dispatch its own actions. + Cursor old = view()->cursor(); + view()->cursor().getPos(cursorPosBeforeDispatchX_, + cursorPosBeforeDispatchY_); view()->cursor().dispatch(cmd); + + // notify insets we just left + if (view()->cursor() != old) { + old.fixIfBroken(); + bool badcursor = notifyCursorLeaves(old, view()->cursor()); + if (badcursor) + view()->cursor().fixIfBroken(); + } + + // 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) + lyx_view_->updateCompletion(view()->cursor(), true, true); + else if (cmd.action == LFUN_CHAR_DELETE_BACKWARD) + lyx_view_->updateCompletion(view()->cursor(), false, true); + else + lyx_view_->updateCompletion(view()->cursor(), false, false); + } + updateFlags = view()->cursor().result().update(); - if (!view()->cursor().result().dispatched()) - updateFlags = view()->dispatch(cmd); - break; - } } if (lyx_view_ && lyx_view_->buffer()) { @@ -1899,16 +1715,16 @@ void LyXFunc::dispatch(FuncRequest const & cmd) if (flag.enabled() && !lyxaction.funcHasFlag(action, LyXAction::NoBuffer) && !lyxaction.funcHasFlag(action, LyXAction::ReadOnly)) - lyx_view_->buffer()->markDirty(); + lyx_view_->buffer()->markDirty(); - //Do we have a selection? + // Do we have a selection? theSelection().haveSelection(view()->cursor().selection()); - - if (view()->cursor().inTexted()) { - } + + // update gui + lyx_view_->restartCursor(); } } - if (!quitting && lyx_view_) { + if (lyx_view_) { // Some messages may already be translated, so we cannot use _() sendDispatchMessage(translateIfPossible(getMessage()), cmd); } @@ -1961,263 +1777,19 @@ void LyXFunc::sendDispatchMessage(docstring const & msg, FuncRequest const & cmd } -void LyXFunc::menuNew(string const & name, bool fromTemplate) -{ - // FIXME: initpath is not used. What to do? - string initpath = lyxrc.document_path; - string filename(name); - - if (lyx_view_->buffer()) { - string const trypath = lyx_view_->buffer()->filePath(); - // If directory is writeable, use this as default. - if (FileName(trypath).isDirWritable()) - initpath = trypath; - } - - static int newfile_number; - - if (filename.empty()) { - filename = addName(lyxrc.document_path, - "newfile" + convert(++newfile_number) + ".lyx"); - while (theBufferList().exists(filename) || - FileName(filename).isReadable()) { - ++newfile_number; - filename = addName(lyxrc.document_path, - "newfile" + convert(newfile_number) + - ".lyx"); - } - } - - // The template stuff - string templname; - if (fromTemplate) { - 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 = - dlg.open(from_utf8(lyxrc.template_path), - FileFilterList(_("LyX Documents (*.lyx)")), - docstring()); - - if (result.first == FileDialog::Later) - return; - if (result.second.empty()) - return; - templname = to_utf8(result.second); - } - - Buffer * const b = newFile(filename, templname, !name.empty()); - if (b) - lyx_view_->setBuffer(b); -} - - -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; - - if (lyx_view_->buffer()) { - string const trypath = lyx_view_->buffer()->filePath(); - // If directory is writeable, use this as default. - if (FileName(trypath).isDirWritable()) - initpath = trypath; - } - - string filename; - - if (fname.empty()) { - 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 = - dlg.open(from_utf8(initpath), - FileFilterList(_("LyX Documents (*.lyx)")), - docstring()); - - if (result.first == FileDialog::Later) - return; - - filename = to_utf8(result.second); - - // check selected filename - if (filename.empty()) { - lyx_view_->message(_("Canceled.")); - return; - } - } else - filename = fname; - - // get absolute path of file and add ".lyx" to the filename if - // necessary - FileName const fullname = fileSearch(string(), filename, "lyx"); - if (!fullname.empty()) - filename = fullname.absFilename(); - - // if the file doesn't exist, let the user create one - if (!fullname.exists()) { - // the user specifically chose this name. Believe him. - Buffer * const b = newFile(filename, string(), true); - if (b) - lyx_view_->setBuffer(b); - return; - } - - docstring const disp_fn = makeDisplayPath(filename); - lyx_view_->message(bformat(_("Opening document %1$s..."), disp_fn)); - - docstring str2; - Buffer * buf = loadAndViewFile(fullname); - if (buf) { - updateLabels(*buf); - lyx_view_->setBuffer(buf); - lyx_view_->errors("Parse"); - str2 = bformat(_("Document %1$s opened."), disp_fn); - } else { - str2 = bformat(_("Could not open document %1$s"), disp_fn); - } - lyx_view_->message(str2); -} - - -void LyXFunc::doImport(string const & argument) -{ - string format; - string filename = split(argument, format, ' '); - - LYXERR(Debug::INFO, "LyXFunc::doImport: " << format - << " file: " << filename); - - // need user interaction - if (filename.empty()) { - string initpath = lyxrc.document_path; - - if (lyx_view_->buffer()) { - string const trypath = lyx_view_->buffer()->filePath(); - // If directory is writeable, use this as default. - if (FileName(trypath).isDirWritable()) - initpath = trypath; - } - - docstring const text = bformat(_("Select %1$s file to import"), - formats.prettyName(format)); - - 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 += " (*."; - // FIXME UNICODE - filter += from_utf8(formats.extension(format)); - filter += ')'; - - FileDialog::Result result = - dlg.open(from_utf8(initpath), - FileFilterList(filter), - docstring()); - - if (result.first == FileDialog::Later) - return; - - filename = to_utf8(result.second); - - // check selected filename - if (filename.empty()) - lyx_view_->message(_("Canceled.")); - } - - if (filename.empty()) - return; - - // get absolute path of file - FileName const fullname(makeAbsPath(filename)); - - FileName const lyxfile(changeExtension(fullname.absFilename(), ".lyx")); - - // Check if the document already is open - if (use_gui && theBufferList().exists(lyxfile.absFilename())) { - if (!theBufferList().close(theBufferList().getBuffer(lyxfile.absFilename()), true)) { - lyx_view_->message(_("Canceled.")); - return; - } - } - - // if the file exists already, and we didn't do - // -i lyx thefile.lyx, warn - if (lyxfile.exists() && fullname != lyxfile) { - docstring const file = makeDisplayPath(lyxfile.absFilename(), 30); - - docstring text = bformat(_("The document %1$s already exists.\n\n" - "Do you want to overwrite that document?"), file); - int const ret = Alert::prompt(_("Overwrite document?"), - text, 0, 1, _("&Overwrite"), _("&Cancel")); - - if (ret == 1) { - lyx_view_->message(_("Canceled.")); - return; - } - } - - ErrorList errorList; - import(lyx_view_, fullname, format, errorList); - // FIXME (Abdel 12/08/06): Is there a need to display the error list here? -} - - -void LyXFunc::closeBuffer() -{ - // goto bookmark to update bookmark pit. - for (size_t i = 0; i < LyX::ref().session().bookmarks().size(); ++i) - gotoBookmark(i+1, false, false); - - theBufferList().close(lyx_view_->buffer(), true); -} - - void LyXFunc::reloadBuffer() { - FileName filename(lyx_view_->buffer()->absFileName()); + FileName filename = lyx_view_->buffer()->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(lyx_view_->buffer()); + Buffer * buf = lyx_view_->loadDocument(filename); docstring const disp_fn = makeDisplayPath(filename.absFilename()); docstring str; - closeBuffer(); - Buffer * buf = loadAndViewFile(filename); if (buf) { updateLabels(*buf); lyx_view_->setBuffer(buf); - lyx_view_->errors("Parse"); + buf->errors("Parse"); str = bformat(_("Document %1$s reloaded."), disp_fn); } else { str = bformat(_("Could not reload document %1$s"), disp_fn); @@ -2244,7 +1816,7 @@ void LyXFunc::setMessage(docstring const & m) const } -docstring const LyXFunc::viewStatusMessage() +docstring LyXFunc::viewStatusMessage() { // When meta-fake key is pressed, show the key sequence so far + "M-". if (wasMetaKey()) @@ -2276,15 +1848,14 @@ bool LyXFunc::wasMetaKey() const } -void LyXFunc::updateLayout(TextClassPtr const & oldlayout, - Buffer * buffer) +void LyXFunc::updateLayout(DocumentClass * 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(), + oldlayout, buffer->params().documentClassPtr(), static_cast(buffer->inset()), el); view()->setCursor(backcur.asDocIterator(&(buffer->inset()))); @@ -2317,6 +1888,15 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new) 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: @@ -2336,11 +1916,13 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new) if (lyxrc_orig.document_path != lyxrc_new.document_path) { FileName path(lyxrc_new.document_path); if (path.exists() && path.isDirectory()) - support::package().document_dir() = FileName(lyxrc.document_path); + 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_INDEX_COMMAND: case LyXRC::RC_INPUT: case LyXRC::RC_KBMAP: @@ -2355,12 +1937,14 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new) case LyXRC::RC_LANGUAGE_GLOBAL_OPTIONS: case LyXRC::RC_LANGUAGE_PACKAGE: case LyXRC::RC_LANGUAGE_USE_BABEL: + 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_PATH_PREFIX: if (lyxrc_orig.path_prefix != lyxrc_new.path_prefix) { - support::prependEnvPath("PATH", lyxrc.path_prefix); + prependEnvPath("PATH", lyxrc.path_prefix); } case LyXRC::RC_PERS_DICT: case LyXRC::RC_PREVIEW: @@ -2399,13 +1983,14 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new) 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_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) { - support::os::windows_style_tex_paths(lyxrc_new.windows_style_tex_paths); + os::windows_style_tex_paths(lyxrc_new.windows_style_tex_paths); } case LyXRC::RC_UIFILE: case LyXRC::RC_USER_EMAIL: @@ -2416,10 +2001,17 @@ 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_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_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;