X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fundo.C;h=33b97827325f006009e10dbcc3ef59165aa0c583;hb=969ab85d985485f503790cb13f98a582d4e1cdb5;hp=4723b57b43d0e73d7ac00042069f84f4e047a0b1;hpb=68b0cca2e701e4959ffb4754184b9b28110b8e7f;p=lyx.git diff --git a/src/undo.C b/src/undo.C index 4723b57b43..33b9782732 100644 --- a/src/undo.C +++ b/src/undo.C @@ -17,17 +17,21 @@ #include "undo.h" #include "buffer.h" +#include "buffer_funcs.h" #include "cursor.h" #include "debug.h" #include "BufferView.h" #include "lyxtext.h" #include "paragraph.h" +#include "ParagraphList.h" -#include "mathed/math_support.h" +#include "mathed/MathSupport.h" +#include "insets/inset.h" #include -using lyx::pit_type; + +namespace lyx { using std::advance; using std::endl; @@ -47,22 +51,33 @@ std::ostream & operator<<(std::ostream & os, Undo const & undo) } -void recordUndo(Undo::undo_kind kind, - DocIterator & cell, +bool samePar(StableDocIterator const & i1, StableDocIterator const & i2) +{ + StableDocIterator tmpi2 = i2; + tmpi2.pos() = i1.pos(); + return i1 == tmpi2; +} + + +void doRecordUndo(Undo::undo_kind kind, + DocIterator const & cell, pit_type first_pit, pit_type last_pit, - DocIterator & cur, + DocIterator const & cur, + BufferParams const & bparams, + bool isFullBuffer, limited_stack & stack) { if (first_pit > last_pit) std::swap(first_pit, last_pit); - // create the position information of the Undo entry Undo undo; undo.kind = kind; undo.cell = cell; undo.cursor = cur; - lyxerr << "recordUndo: cur: " << cur << endl; - lyxerr << "recordUndo: pos: " << cur.pos() << endl; + undo.bparams = bparams ; + undo.isFullBuffer = isFullBuffer; + //lyxerr << "recordUndo: cur: " << cur << endl; + //lyxerr << "recordUndo: pos: " << cur.pos() << endl; //lyxerr << "recordUndo: cell: " << cell << endl; undo.from = first_pit; undo.end = cell.lastpit() - last_pit; @@ -73,10 +88,10 @@ void recordUndo(Undo::undo_kind kind, if (!undo_finished && kind != Undo::ATOMIC && !stack.empty() - && stack.top().cell.size() == undo.cell.size() - && stack.top().kind == undo.kind - && stack.top().from == undo.from - && stack.top().end == undo.end) + && samePar(stack.top().cell, undo.cell) + && stack.top().kind == undo.kind + && stack.top().from == undo.from + && stack.top().end == undo.end) return; // fill in the real data to be saved @@ -87,12 +102,12 @@ void recordUndo(Undo::undo_kind kind, // some more effort needed here as 'the whole cell' of the // main LyXText _is_ the whole document. // record the relevant paragraphs - LyXText * text = cell.text(); + LyXText const * text = cell.text(); BOOST_ASSERT(text); - ParagraphList & plist = text->paragraphs(); - ParagraphList::iterator first = plist.begin(); + ParagraphList const & plist = text->paragraphs(); + ParagraphList::const_iterator first = plist.begin(); advance(first, first_pit); - ParagraphList::iterator last = plist.begin(); + ParagraphList::const_iterator last = plist.begin(); advance(last, last_pit + 1); undo.pars = ParagraphList(first, last); } @@ -105,6 +120,7 @@ void recordUndo(Undo::undo_kind kind, undo_finished = false; } + void recordUndo(Undo::undo_kind kind, LCursor & cur, pit_type first_pit, pit_type last_pit, limited_stack & stack) @@ -112,18 +128,49 @@ void recordUndo(Undo::undo_kind kind, BOOST_ASSERT(first_pit <= cur.lastpit()); BOOST_ASSERT(last_pit <= cur.lastpit()); - recordUndo(kind, cur, first_pit, last_pit, cur, stack); + doRecordUndo(kind, cur, first_pit, last_pit, cur, + cur.bv().buffer()->params(), false, stack); } -void performUndoOrRedo(BufferView & bv, Undo const & undo) + +// Returns false if no undo possible. +bool textUndoOrRedo(BufferView & bv, + limited_stack & stack, limited_stack & otherstack) { + finishUndo(); + + if (stack.empty()) { + // Nothing to do. + return false; + } + + // Adjust undo stack and get hold of current undo data. + Undo undo = stack.top(); + stack.pop(); + + // We will store in otherstack the part of the document under 'undo' + Buffer * buf = bv.buffer(); + DocIterator cell_dit = undo.cell.asDocIterator(&buf->inset()); + + doRecordUndo(Undo::ATOMIC, cell_dit, + undo.from, cell_dit.lastpit() - undo.end, bv.cursor(), + undo.bparams, undo.isFullBuffer, + otherstack); + + // This does the actual undo/redo. //lyxerr << "undo, performing: " << undo << std::endl; - DocIterator dit = undo.cell.asDocIterator(&bv.buffer()->inset()); - if (dit.inMathed()) { + DocIterator dit = undo.cell.asDocIterator(&buf->inset()); + if (undo.isFullBuffer) { + // This is a full document + otherstack.top().bparams = buf->params(); + buf->params() = undo.bparams; + buf->paragraphs() = undo.pars; + } 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 // all math inset cells have just one paragraph!) + // lyxerr << "undo.array=" << to_ascii(undo.array) <setInsetOwner(dit.realInset()); plist.insert(first, undo.pars.begin(), undo.pars.end()); + updateLabels(*buf); } + // Set cursor LCursor & cur = bv.cursor(); - cur.setCursor(undo.cursor.asDocIterator(&bv.buffer()->inset())); + cur.setCursor(undo.cursor.asDocIterator(&buf->inset())); cur.selection() = false; cur.resetAnchor(); finishUndo(); -} - - -// Returns false if no undo possible. -bool textUndoOrRedo(BufferView & bv, - limited_stack & stack, limited_stack & otherstack) -{ - if (stack.empty()) { - // Nothing to do. - finishUndo(); - return false; - } - - // - // Adjust undo stack and get hold of current undo data. - // - Undo undo = stack.top(); - stack.pop(); - finishUndo(); - - - // - // This implements redo. - // - - // The cursor will be placed at cur_dit after - // the ongoing undo operation. - DocIterator cur_dit = - undo.cursor.asDocIterator(&bv.buffer()->inset()); - - // This is the place the cursor is currently located. - LCursor & cur = bv.cursor(); - DocIterator cell_dit = cur; - - // If both places have the same depth we stay in the same - // cell and store paragraphs from this cell. Otherwise we - // will drop slices from the more nested iterator and - // create an undo item from a single paragraph of the common - // ancestor. - DocIterator ancestor_dit = cur_dit; - while (ancestor_dit.size() > cur.size()) - ancestor_dit.pop_back(); - - if (cur_dit.size() == cell_dit.size()) { - recordUndo(Undo::ATOMIC, cell_dit, - cell_dit.pit(), cur_dit.pit(), - cur_dit, otherstack); - } - else { - recordUndo(Undo::ATOMIC, ancestor_dit, - ancestor_dit.pit(), - ancestor_dit.pit(), - cur_dit, otherstack); - } - - // - // This does the actual undo. - // - performUndoOrRedo(bv, undo); return true; } @@ -258,7 +255,9 @@ void recordUndoInset(LCursor & cur, Undo::undo_kind kind) { LCursor c = cur; c.pop(); - recordUndo(c, kind); + Buffer * buf = cur.bv().buffer(); + doRecordUndo(kind, c, c.pit(), c.pit(), cur, + buf->params(), false, buf->undostack()); } @@ -281,8 +280,20 @@ void recordUndo(LCursor & cur, Undo::undo_kind kind, } -void recordUndoFullDocument(LCursor &) +void recordUndoFullDocument(BufferView * bv) { - //recordUndo(Undo::ATOMIC, - // cur, 0, cur.bv().text()->paragraphs().size() - 1); + Buffer * buf = bv->buffer(); + doRecordUndo( + Undo::ATOMIC, + doc_iterator_begin(buf->inset()), + 0, buf->paragraphs().size() - 1, + bv->cursor(), + buf->params(), + true, + buf->undostack() + ); + undo_finished = false; } + + +} // namespace lyx