X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FUndo.cpp;h=31eaec3dbd84977ee7d52e3dca4c86b3726df7f9;hb=e52a38549328a58b6fe8efeecef21a71fb9c8d65;hp=122b1aada65011d341d3104c34628527aa0901da;hpb=1b1f8dd235ba8e168348cd23c824063f2595a0c5;p=lyx.git diff --git a/src/Undo.cpp b/src/Undo.cpp index 122b1aada6..31eaec3dbd 100644 --- a/src/Undo.cpp +++ b/src/Undo.cpp @@ -61,15 +61,15 @@ structure ('Undo') _before_ it is changed in some edit operation. Obviously, the stored range should be as small as possible. However, there is a lower limit: The StableDocIterator stored in the undo class must be valid after the changes, too, as it will used as a pointer -where to insert the stored bits when performining undo. +where to insert the stored bits when performining undo. */ struct UndoElement { /// - UndoElement(UndoKind kin, CursorData const & cb, + UndoElement(UndoKind kin, CursorData const & cb, StableDocIterator const & cel, - pit_type fro, pit_type en, ParagraphList * pl, - MathData * ar, BufferParams const & bp, + pit_type fro, pit_type en, ParagraphList * pl, + MathData * ar, BufferParams const & bp, bool ifb, bool lc, size_t gid) : kind(kin), cur_before(cb), cell(cel), from(fro), end(en), pars(pl), array(ar), bparams(0), isFullBuffer(ifb), @@ -127,11 +127,11 @@ struct UndoElement size_t group_id; private: /// Protect construction - UndoElement(); + UndoElement(); }; -class UndoElementStack +class UndoElementStack { public: /// limit is the maximum size of the stack @@ -160,20 +160,24 @@ public: /// Push an item on to the stack, deleting the bottom group on /// overflow. void push(UndoElement const & v) { - c_.push_front(v); - if (c_.size() > limit_) { + // Remove some entries if the limit has been reached. + // However, if the only group on the stack is the one + // we are currently populating, do nothing. + if (c_.size() >= limit_ + && c_.front().group_id != v.group_id) { // remove a whole group at once. const size_t gid = c_.back().group_id; while (!c_.empty() && c_.back().group_id == gid) c_.pop_back(); } + c_.push_front(v); } /// Mark all the elements of the stack as dirty void markDirty() { for (size_t i = 0; i != c_.size(); ++i) c_[i].lyx_clean = false; - } + } private: /// Internal contents. @@ -185,11 +189,11 @@ private: struct Undo::Private { - Private(Buffer & buffer) : buffer_(buffer), undo_finished_(true), + Private(Buffer & buffer) : buffer_(buffer), undo_finished_(true), group_id(0), group_level(0) {} - + // Do one undo/redo step - void doTextUndoOrRedo(CursorData & cur, UndoElementStack & stack, + void doTextUndoOrRedo(CursorData & cur, UndoElementStack & stack, UndoElementStack & otherStack); // Apply one undo/redo group. Returns false if no undo possible. bool textUndoOrRedo(CursorData & cur, bool isUndoOperation); @@ -273,7 +277,7 @@ void Undo::markDirty() { d->undo_finished_ = true; d->undostack_.markDirty(); - d->redostack_.markDirty(); + d->redostack_.markDirty(); } @@ -328,7 +332,7 @@ void Undo::Private::doRecordUndo(UndoKind kind, else LYXERR(Debug::UNDO, "Create undo element of group " << group_id); // create the position information of the Undo entry - UndoElement undo(kind, cur_before, cell, from, end, 0, 0, + UndoElement undo(kind, cur_before, cell, from, end, 0, 0, buffer_.params(), isFullBuffer, buffer_.isClean(), group_id); // fill in the real data to be saved @@ -341,7 +345,7 @@ void Undo::Private::doRecordUndo(UndoKind kind, // main Text _is_ the whole document. // record the relevant paragraphs Text const * text = cell.text(); - LBUFERR(text, _("Uninitialized cell.")); + LBUFERR(text); ParagraphList const & plist = text->paragraphs(); ParagraphList::const_iterator first = plist.begin(); advance(first, first_pit); @@ -401,7 +405,7 @@ void Undo::Private::doTextUndoOrRedo(CursorData & cur, UndoElementStack & stack, //LYXERR0("undo, performing: " << undo); DocIterator dit = undo.cell.asDocIterator(&buffer_); if (undo.isFullBuffer) { - LBUFERR(undo.pars, _("Undo stack is corrupt!")); + LBUFERR(undo.pars); // This is a full document delete otherstack.top().bparams; otherstack.top().bparams = new BufferParams(buffer_.params()); @@ -414,15 +418,15 @@ void Undo::Private::doTextUndoOrRedo(CursorData & cur, UndoElementStack & stack, // gained by storing just 'a few' paragraphs (most if not // all math inset cells have just one paragraph!) //LYXERR0("undo.array: " << *undo.array); - LBUFERR(undo.array, _("Undo stack is corrupt!")); + LBUFERR(undo.array); dit.cell().swap(*undo.array); delete undo.array; undo.array = 0; } else { // Some finer machinery is needed here. Text * text = dit.text(); - LBUFERR(text, _("Invalid cursor.")); - LBUFERR(undo.pars, _("Undo stack is corrupt!")); + LBUFERR(text); + LBUFERR(undo.pars); ParagraphList & plist = text->paragraphs(); // remove new stuff between first and last @@ -578,7 +582,7 @@ void Undo::recordUndoFullDocument(CursorData const & cur) // This one may happen outside of the main undo group, so we // put it in its own subgroup to avoid complaints. beginUndoGroup(); - d->recordUndo(ATOMIC_UNDO, doc_iterator_begin(&d->buffer_), + d->recordUndo(ATOMIC_UNDO, doc_iterator_begin(&d->buffer_), 0, d->buffer_.paragraphs().size() - 1, cur, true); endUndoGroup(); }