]> git.lyx.org Git - lyx.git/blobdiff - src/undo.C
add GuiView parent to QToc for proper memory management.
[lyx.git] / src / undo.C
index 1a854a192c23af5f132b204203b62139aeebb4b6..ed523a45ceb57cb36c70dfcc8d2b6b54f5c39431 100644 (file)
 #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/MathSupport.h"
+#include "mathed/MathData.h"
 
-#include "mathed/math_support.h"
 #include "insets/inset.h"
 
 #include <algorithm>
 
-using lyx::pit_type;
+
+namespace lyx {
 
 using std::advance;
 using std::endl;
@@ -48,6 +53,14 @@ std::ostream & operator<<(std::ostream & os, Undo const & undo)
 }
 
 
+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,
@@ -60,6 +73,8 @@ void doRecordUndo(Undo::undo_kind kind,
                std::swap(first_pit, last_pit);
        // create the position information of the Undo entry
        Undo undo;
+       undo.array = 0;
+       undo.pars = 0;
        undo.kind = kind;
        undo.cell = cell;
        undo.cursor = cur;
@@ -77,33 +92,33 @@ void doRecordUndo(Undo::undo_kind kind,
        if (!undo_finished
            && kind != Undo::ATOMIC
            && !stack.empty()
-           && stack.top().cell == undo.cell
-                 && 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
        if (cell.inMathed()) {
                // simply use the whole cell
-               undo.array = asString(cell.cell());
+               undo.array = new MathArray(cell.cell());
        } else {
                // some more effort needed here as 'the whole cell' of the
                // main LyXText _is_ the whole document.
                // record the relevant paragraphs
                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);
+               undo.pars = new ParagraphList(first, last);
        }
 
        // push the undo entry to undo stack
-       //lyxerr << "undo record: " << stack.top() << std::endl;
        stack.push(undo);
+       //lyxerr << "undo record: " << stack.top() << std::endl;
 
        // next time we'll try again to combine entries if possible
        undo_finished = false;
@@ -151,19 +166,27 @@ bool textUndoOrRedo(BufferView & bv,
        //lyxerr << "undo, performing: " << undo << std::endl;
        DocIterator dit = undo.cell.asDocIterator(&buf->inset());
        if (undo.isFullBuffer) {
+               BOOST_ASSERT(undo.pars);
                // This is a full document
                otherstack.top().bparams = buf->params();
                buf->params() = undo.bparams;
-               buf->paragraphs() = undo.pars;
+               std::swap(buf->paragraphs(), *undo.pars);
+               delete undo.pars;
+               undo.pars = 0;
        } 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!)
-               asArray(undo.array, dit.cell());
+               //lyxerr << "undo.array: " << *undo.array <<endl;
+               BOOST_ASSERT(undo.array);
+               dit.cell().swap(*undo.array);
+               delete undo.array;
+               undo.array = 0;
        } else {
                // Some finer machinery is needed here.
                LyXText * text = dit.text();
                BOOST_ASSERT(text);
+               BOOST_ASSERT(undo.pars);
                ParagraphList & plist = text->paragraphs();
 
                // remove new stuff between first and last
@@ -179,18 +202,24 @@ bool textUndoOrRedo(BufferView & bv,
 
                // this ugly stuff is needed until we get rid of the
                // inset_owner backpointer
-               ParagraphList::const_iterator pit = undo.pars.begin();
-               ParagraphList::const_iterator end = undo.pars.end();
+               ParagraphList::iterator pit = undo.pars->begin();
+               ParagraphList::iterator const end = undo.pars->end();
                for (; pit != end; ++pit)
-                       const_cast<Paragraph &>(*pit).setInsetOwner(&dit.inset());
-               plist.insert(first, undo.pars.begin(), undo.pars.end());
+                       pit->setInsetOwner(dit.realInset());
+               plist.insert(first, undo.pars->begin(), undo.pars->end());
+               delete undo.pars;
+               undo.pars = 0;
+               updateLabels(*buf);
        }
+       BOOST_ASSERT(undo.pars == 0);
+       BOOST_ASSERT(undo.array == 0);
 
        // Set cursor
        LCursor & cur = bv.cursor();
        cur.setCursor(undo.cursor.asDocIterator(&buf->inset()));
        cur.selection() = false;
        cur.resetAnchor();
+       cur.fixIfBroken();
        finishUndo();
 
        return true;
@@ -242,7 +271,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());
 }
 
 
@@ -279,3 +310,6 @@ void recordUndoFullDocument(BufferView * bv)
        );
        undo_finished = false;
 }
+
+
+} // namespace lyx