X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FUndo.cpp;h=28a2e822395abefca4956d3970e079567922f1c1;hb=38c2cde0d8695ac5287bae218c4a33a2acf18ef8;hp=7b924c7b49a6e73b0bbca83287daa9f60a538860;hpb=b63421b7dc65e0c721f8928d1330b9bb2cff43d8;p=lyx.git diff --git a/src/Undo.cpp b/src/Undo.cpp index 7b924c7b49..28a2e82239 100644 --- a/src/Undo.cpp +++ b/src/Undo.cpp @@ -18,9 +18,12 @@ #include "Undo.h" #include "Buffer.h" +#include "BufferList.h" #include "BufferParams.h" #include "buffer_funcs.h" #include "Cursor.h" +#include "CutAndPaste.h" +#include "ErrorList.h" #include "Paragraph.h" #include "ParagraphList.h" #include "Text.h" @@ -29,6 +32,7 @@ #include "mathed/MathData.h" #include "insets/Inset.h" +#include "insets/InsetText.h" #include "support/debug.h" #include "support/gettext.h" @@ -37,6 +41,7 @@ #include #include +#include using namespace std; using namespace lyx::support; @@ -85,21 +90,15 @@ struct UndoElement { } /// - UndoElement(UndoElement const & ue) : time(current_time()) - { - kind = ue.kind; - cur_before = ue.cur_before; - cur_after = ue.cur_after; - cell = ue.cell; - from = ue.from; - end = ue.end; - pars = ue.pars; - array = ue.array; - bparams = ue.bparams - ? new BufferParams(*ue.bparams) : 0; - lyx_clean = ue.lyx_clean; - group_id = ue.group_id; - } + UndoElement(UndoElement const & ue) : + kind(ue.kind), + cur_before(ue.cur_before), cur_after(ue.cur_after), + cell(ue.cell), from(ue.from), end(ue.end), + pars(ue.pars), array(ue.array), + bparams(ue.bparams ? new BufferParams(*ue.bparams) : 0), + lyx_clean(ue.lyx_clean), group_id(ue.group_id), + time(current_time()) + {} /// ~UndoElement() { @@ -198,10 +197,10 @@ struct Undo::Private group_id_(0), group_level_(0) {} // Do one undo/redo step - void doTextUndoOrRedo(CursorData & cur, UndoElementStack & stack, + void doUndoRedoAction(CursorData & cur, UndoElementStack & stack, UndoElementStack & otherStack); // Apply one undo/redo group. Returns false if no undo possible. - bool textUndoOrRedo(CursorData & cur, bool isUndoOperation); + bool undoRedoAction(CursorData & cur, bool isUndoOperation); /// void doRecordUndo(UndoKind kind, @@ -425,7 +424,7 @@ void Undo::Private::recordUndoBufferParams(CursorData const & cur) } -void Undo::Private::doTextUndoOrRedo(CursorData & cur, UndoElementStack & stack, UndoElementStack & otherstack) +void Undo::Private::doUndoRedoAction(CursorData & cur, UndoElementStack & stack, UndoElementStack & otherstack) { // Adjust undo stack and get hold of current undo data. UndoElement & undo = stack.top(); @@ -453,7 +452,13 @@ void Undo::Private::doTextUndoOrRedo(CursorData & cur, UndoElementStack & stack, // This is a params undo element delete otherstack.top().bparams; otherstack.top().bparams = new BufferParams(buffer_.params()); + DocumentClassConstPtr olddc = buffer_.params().documentClassPtr(); buffer_.params() = *undo.bparams; + // The error list is not supposed to be helpful here. + ErrorList el; + cap::switchBetweenClasses(olddc, buffer_.params().documentClassPtr(), + static_cast(buffer_.inset()), el); + LATTEST(el.empty()); } else if (dit.inMathed()) { // We stored the full cell here as there is not much to be // gained by storing just 'a few' paragraphs (most if not @@ -461,6 +466,7 @@ void Undo::Private::doTextUndoOrRedo(CursorData & cur, UndoElementStack & stack, //LYXERR0("undo.array: " << *undo.array); LBUFERR(undo.array); dit.cell().swap(*undo.array); + dit.inset().setBuffer(buffer_); delete undo.array; undo.array = 0; } else { @@ -488,6 +494,15 @@ void Undo::Private::doTextUndoOrRedo(CursorData & cur, UndoElementStack & stack, for (; pit != end; ++pit) pit->setInsetOwner(dit.realInset()); plist.insert(first, undo.pars->begin(), undo.pars->end()); + + // set the buffers for insets we created + ParagraphList::iterator fpit = plist.begin(); + advance(fpit, undo.from); + ParagraphList::iterator fend = fpit; + advance(fend, undo.pars->size()); + for (; fpit != fend; ++fpit) + fpit->setInsetBuffers(buffer_); + delete undo.pars; undo.pars = 0; } @@ -507,7 +522,7 @@ void Undo::Private::doTextUndoOrRedo(CursorData & cur, UndoElementStack & stack, } -bool Undo::Private::textUndoOrRedo(CursorData & cur, bool isUndoOperation) +bool Undo::Private::undoRedoAction(CursorData & cur, bool isUndoOperation) { undo_finished_ = true; @@ -521,10 +536,7 @@ bool Undo::Private::textUndoOrRedo(CursorData & cur, bool isUndoOperation) const size_t gid = stack.top().group_id; while (!stack.empty() && stack.top().group_id == gid) - doTextUndoOrRedo(cur, stack, otherstack); - - // Adapt the new material to current buffer. - buffer_.setBuffersForInsets(); // FIXME This shouldn't be here. + doUndoRedoAction(cur, stack, otherstack); return true; } @@ -536,15 +548,15 @@ void Undo::finishUndo() } -bool Undo::textUndo(CursorData & cur) +bool Undo::undoAction(CursorData & cur) { - return d->textUndoOrRedo(cur, true); + return d->undoRedoAction(cur, true); } -bool Undo::textRedo(CursorData & cur) +bool Undo::redoAction(CursorData & cur) { - return d->textUndoOrRedo(cur, false); + return d->undoRedoAction(cur, false); } @@ -553,7 +565,8 @@ void Undo::beginUndoGroup() if (d->group_level_ == 0) { // create a new group ++d->group_id_; - LYXERR(Debug::UNDO, "+++++++Creating new group " << d->group_id_); + LYXERR(Debug::UNDO, "+++++++ Creating new group " << d->group_id_ + << " for buffer " << &d->buffer_); } ++d->group_level_; } @@ -577,7 +590,8 @@ void Undo::endUndoGroup() if (d->group_level_ == 0) { // real end of the group d->group_cur_before_ = CursorData(); - LYXERR(Debug::UNDO, "-------End of group " << d->group_id_); + LYXERR(Debug::UNDO, "------- End of group " << d->group_id_ + << " of buffer " << &d->buffer_); } } @@ -590,6 +604,24 @@ void Undo::endUndoGroup(CursorData const & cur_after) } +void Undo::splitUndoGroup(CursorData const & cur) +{ + size_t const level = d->group_level_; + d->group_level_ = 1; + endUndoGroup(cur); + beginUndoGroup(cur); + d->group_level_ = level; +} + + +bool Undo::activeUndoGroup() const +{ + return d->group_level_ > 0 + && !d->undostack_.empty() + && d->undostack_.top().group_id == d->group_id_; +} + + void Undo::recordUndo(CursorData const & cur, UndoKind kind) { d->recordUndo(kind, cur, cur.pit(), cur.pit(), cur); @@ -634,15 +666,32 @@ void Undo::recordUndoFullBuffer(CursorData const & cur) /// UndoGroupHelper class stuff +class UndoGroupHelper::Impl { + friend class UndoGroupHelper; + set buffers_; +}; + + +UndoGroupHelper::UndoGroupHelper(Buffer * buf) : d(new UndoGroupHelper::Impl) +{ + resetBuffer(buf); +} + + +UndoGroupHelper::~UndoGroupHelper() +{ + for (Buffer * buf : d->buffers_) + if (theBufferList().isLoaded(buf) || theBufferList().isInternal(buf)) + buf->undo().endUndoGroup(); + delete d; +} + void UndoGroupHelper::resetBuffer(Buffer * buf) { - if (buf == buffer_) - return; - if (buffer_) - buffer_->undo().endUndoGroup(); - buffer_ = buf; - if (buffer_) - buffer_->undo().beginUndoGroup(); + if (buf && d->buffers_.count(buf) == 0) { + d->buffers_.insert(buf); + buf->undo().beginUndoGroup(); + } }