diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 4fae0d8131..05f14ef876 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -34,6 +34,7 @@ #include "InsetIterator.h" #include "Language.h" #include "LaTeXFeatures.h" +#include "LayoutFile.h" #include "Lexer.h" #include "LyX.h" #include "lyxfind.h" @@ -895,12 +896,43 @@ bool BufferView::scrollToCursor(DocIterator const & dit, bool recenter) } +void BufferView::updateLayout(DocumentClass const * const oldlayout) +{ + message(_("Converting document to new document class...")); + + StableDocIterator backcur(d->cursor_); + ErrorList & el = buffer_.errorList("Class Switch"); + cap::switchBetweenClasses( + oldlayout, buffer_.params().documentClassPtr(), + static_cast(buffer_.inset()), el); + + setCursor(backcur.asDocIterator(&buffer_)); + + buffer_.errors("Class Switch"); + buffer_.updateLabels(); +} + + bool BufferView::getStatus(FuncRequest const & cmd, FuncStatus & flag) { Cursor & cur = d->cursor_; switch (cmd.action) { + + // FIXME: This is a bit problematic because we don't check is this is a + // document BufferView or not for these LFUNs. We probably have to + // dispatch both to currentBufferView() and, if that fails, + // to documentBufferView(); same as we do know for current Buffer and + // document Buffer. Ideally those LFUN should go to Buffer as they* + // operate on the full Buffer and the cursor is only needed either for + // an Undo record or to restore a cursor position. But we don't know + // how to do that inside Buffer of course. case LFUN_BUFFER_PARAMS_APPLY: + case LFUN_LAYOUT_MODULES_CLEAR: + case LFUN_LAYOUT_MODULE_ADD: + case LFUN_LAYOUT_RELOAD: + case LFUN_TEXTCLASS_APPLY: + case LFUN_TEXTCLASS_LOAD: flag.setEnabled(!buffer_.isReadonly()); break; @@ -1056,6 +1088,7 @@ bool BufferView::dispatch(FuncRequest const & cmd) << " y[" << cmd.y << ']' << " button[" << cmd.button() << ']'); + string const argument = to_utf8(cmd.argument()); Cursor & cur = d->cursor_; switch (cmd.action) { @@ -1072,7 +1105,7 @@ bool BufferView::dispatch(FuncRequest const & cmd) << unknown_tokens << " unknown token" << (unknown_tokens == 1 ? "" : "s")); } - theLyXFunc().updateLayout(oldClass, &buffer_); + updateLayout(oldClass); // 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 @@ -1081,6 +1114,73 @@ bool BufferView::dispatch(FuncRequest const & cmd) break; } + case LFUN_LAYOUT_MODULES_CLEAR: { + DocumentClass const * const oldClass = + buffer_.params().documentClassPtr(); + cur.recordUndoFullDocument(); + buffer_.params().clearLayoutModules(); + buffer_.params().makeDocumentClass(); + updateLayout(oldClass); + processUpdateFlags(Update::Force | Update::FitCursor); + break; + } + + case LFUN_LAYOUT_MODULE_ADD: { + BufferParams const & params = buffer_.params(); + if (!params.moduleCanBeAdded(argument)) { + LYXERR0("Module `" << argument << + "' cannot be added due to failed requirements or " + "conflicts with installed modules."); + break; + } + DocumentClass const * const oldClass = params.documentClassPtr(); + cur.recordUndoFullDocument(); + buffer_.params().addLayoutModule(argument); + buffer_.params().makeDocumentClass(); + updateLayout(oldClass); + processUpdateFlags(Update::Force | Update::FitCursor); + break; + } + + case LFUN_TEXTCLASS_APPLY: { + if (!LayoutFileList::get().load(argument, buffer_.temppath()) && + !LayoutFileList::get().load(argument, buffer_.filePath())) + break; + + LayoutFile const * old_layout = buffer_.params().baseClass(); + LayoutFile const * new_layout = &(LayoutFileList::get()[argument]); + + if (old_layout == new_layout) + // nothing to do + break; + + //Save the old, possibly modular, layout for use in conversion. + DocumentClass const * const oldDocClass = + buffer_.params().documentClassPtr(); + cur.recordUndoFullDocument(); + buffer_.params().setBaseClass(argument); + buffer_.params().makeDocumentClass(); + updateLayout(oldDocClass); + processUpdateFlags(Update::Force | Update::FitCursor); + break; + } + + case LFUN_TEXTCLASS_LOAD: + LayoutFileList::get().load(argument, buffer_.temppath()) || + LayoutFileList::get().load(argument, buffer_.filePath()); + break; + + case LFUN_LAYOUT_RELOAD: { + DocumentClass const * const oldClass = buffer_.params().documentClassPtr(); + LayoutFileIndex bc = buffer_.params().baseClassID(); + LayoutFileList::get().reset(bc); + buffer_.params().setBaseClass(bc); + buffer_.params().makeDocumentClass(); + updateLayout(oldClass); + processUpdateFlags(Update::Force | Update::FitCursor); + break; + } + case LFUN_UNDO: cur.message(_("Undo")); cur.clearSelection(); diff --git a/src/BufferView.h b/src/BufferView.h index 6c2b53fcb6..9cbb3cf60a 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -32,6 +32,7 @@ class Change; class CoordCache; class Cursor; class DocIterator; +class DocumentClass; class FuncRequest; class FuncStatus; class Intl; @@ -327,6 +328,8 @@ private: int y //< y-coordinate on screen ) const; + /// + void updateLayout(DocumentClass const * const oldlayout); /// int width_; /// diff --git a/src/LayoutFile.cpp b/src/LayoutFile.cpp index 05fc109941..88a4cf63f5 100644 --- a/src/LayoutFile.cpp +++ b/src/LayoutFile.cpp @@ -18,11 +18,14 @@ #include "Lexer.h" #include "TextClass.h" -#include "support/lassert.h" +#include "frontends/alert.h" + #include "support/debug.h" #include "support/FileName.h" #include "support/filetools.h" #include "support/gettext.h" +#include "support/lassert.h" +#include "support/lstrings.h" #include #include @@ -288,6 +291,24 @@ LayoutFileIndex } +bool LayoutFileList::load(string const & name, string const & buf_path) +{ + if (!haveClass(name)) { + LYXERR0("Document class \"" << name << "\" does not exist."); + return false; + } + + LayoutFile * tc = classmap_[name]; + if (!tc->load(buf_path)) { + docstring s = bformat(_("The document class %1$s " + "could not be loaded."), from_utf8(name)); + frontend::Alert::error(_("Could not load class"), s); + return false; + } + return true; +} + + LayoutFileIndex defaultBaseclass() { if (LayoutFileList::get().haveClass("article")) diff --git a/src/LayoutFile.h b/src/LayoutFile.h index 847b469435..b56da88319 100644 --- a/src/LayoutFile.h +++ b/src/LayoutFile.h @@ -124,6 +124,10 @@ public: addLocalLayout(std::string const & textclass, std::string const & path); /// a list of the available classes std::vector classList() const; + + /// + bool load(std::string const & name, std::string const & buf_path); + private: /// typedef std::map ClassMap; diff --git a/src/LyXFunc.cpp b/src/LyXFunc.cpp index f681b90dda..b53f2d2c2d 100644 --- a/src/LyXFunc.cpp +++ b/src/LyXFunc.cpp @@ -567,12 +567,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const case LFUN_REPEAT: case LFUN_PREFERENCES_SAVE: case LFUN_INSET_EDIT: - case LFUN_TEXTCLASS_APPLY: - case LFUN_TEXTCLASS_LOAD: case LFUN_BUFFER_SAVE_AS_DEFAULT: - case LFUN_LAYOUT_MODULES_CLEAR: - case LFUN_LAYOUT_MODULE_ADD: - case LFUN_LAYOUT_RELOAD: case LFUN_LYXRC_APPLY: // these are handled in our dispatch() break; @@ -649,26 +644,6 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const namespace { -bool loadLayoutFile(string const & name, string const & buf_path) -{ - if (!LayoutFileList::get().haveClass(name)) { - lyxerr << "Document class \"" << name - << "\" does not exist." - << endl; - return false; - } - - 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; -} - - void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new); } //namespace anon @@ -1065,77 +1040,6 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; } - case LFUN_LAYOUT_MODULES_CLEAR: { - LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/); - DocumentClass const * const oldClass = buffer->params().documentClassPtr(); - lyx_view_->documentBufferView()->cursor().recordUndoFullDocument(); - buffer->params().clearLayoutModules(); - buffer->params().makeDocumentClass(); - updateLayout(oldClass, buffer); - updateFlags = Update::Force | Update::FitCursor; - break; - } - - case LFUN_LAYOUT_MODULE_ADD: { - LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/); - BufferParams const & params = buffer->params(); - if (!params.moduleCanBeAdded(argument)) { - LYXERR0("Module `" << argument << - "' cannot be added due to failed requirements or " - "conflicts with installed modules."); - break; - } - DocumentClass const * const oldClass = params.documentClassPtr(); - lyx_view_->documentBufferView()->cursor().recordUndoFullDocument(); - buffer->params().addLayoutModule(argument); - buffer->params().makeDocumentClass(); - updateLayout(oldClass, buffer); - updateFlags = Update::Force | Update::FitCursor; - break; - } - - case LFUN_TEXTCLASS_APPLY: { - LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/); - - if (!loadLayoutFile(argument, buffer->temppath()) && - !loadLayoutFile(argument, buffer->filePath())) - break; - - LayoutFile const * old_layout = buffer->params().baseClass(); - LayoutFile const * new_layout = &(LayoutFileList::get()[argument]); - - if (old_layout == new_layout) - // nothing to do - break; - - //Save the old, possibly modular, layout for use in conversion. - DocumentClass const * const oldDocClass = - buffer->params().documentClassPtr(); - lyx_view_->documentBufferView()->cursor().recordUndoFullDocument(); - buffer->params().setBaseClass(argument); - buffer->params().makeDocumentClass(); - updateLayout(oldDocClass, buffer); - updateFlags = Update::Force | Update::FitCursor; - break; - } - - case LFUN_LAYOUT_RELOAD: { - LASSERT(lyx_view_, /**/); - DocumentClass const * const oldClass = buffer->params().documentClassPtr(); - LayoutFileIndex bc = buffer->params().baseClassID(); - LayoutFileList::get().reset(bc); - buffer->params().setBaseClass(bc); - buffer->params().makeDocumentClass(); - updateLayout(oldClass, buffer); - updateFlags = Update::Force | Update::FitCursor; - break; - } - - case LFUN_TEXTCLASS_LOAD: - loadLayoutFile(argument, buffer->temppath()) || - loadLayoutFile(argument, buffer->filePath()); - break; - case LFUN_LYXRC_APPLY: { // reset active key sequences, since the bindings // are updated (bug 6064) @@ -1397,23 +1301,6 @@ bool LyXFunc::wasMetaKey() const } -void LyXFunc::updateLayout(DocumentClass const * const oldlayout, Buffer * buf) -{ - lyx_view_->message(_("Converting document to new document class...")); - - StableDocIterator backcur(lyx_view_->currentBufferView()->cursor()); - ErrorList & el = buf->errorList("Class Switch"); - cap::switchBetweenClasses( - oldlayout, buf->params().documentClassPtr(), - static_cast(buf->inset()), el); - - lyx_view_->currentBufferView()->setCursor(backcur.asDocIterator(buf)); - - buf->errors("Class Switch"); - buf->updateLabels(); -} - - namespace { void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new) diff --git a/src/LyXFunc.h b/src/LyXFunc.h index d186a13ed7..b4060831a7 100644 --- a/src/LyXFunc.h +++ b/src/LyXFunc.h @@ -92,9 +92,6 @@ public: /// cursor y position before dispatch started int cursorBeforeDispatchY() const { return cursorPosBeforeDispatchY_; } - /// - void updateLayout(DocumentClass const * const oldlayout, Buffer * buffer); - private: /// frontend::LyXView * lyx_view_;