]> git.lyx.org Git - features.git/commitdiff
bit of undo
authorAndré Pönitz <poenitz@gmx.net>
Wed, 4 Jun 2003 07:14:05 +0000 (07:14 +0000)
committerAndré Pönitz <poenitz@gmx.net>
Wed, 4 Jun 2003 07:14:05 +0000 (07:14 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@7100 a592a061-630c-0410-9148-cb99ea01b6c8

16 files changed:
src/ChangeLog
src/buffer.h
src/insets/ChangeLog
src/insets/inset.C
src/insets/inset.h
src/insets/insetinclude.C
src/lyxfunc.C
src/paragraph.C
src/paragraph.h
src/paragraph_pimpl.h
src/support/ChangeLog
src/support/limited_stack.h
src/text2.C
src/undo.C
src/undo.h
src/undo_funcs.C

index 88e46a2478c9bf1bf6f806796913dba242eec188..041015101d3c7a075c53828714e1927161cc8f1d 100644 (file)
@@ -1,3 +1,15 @@
+
+2003-06-04  André Pönitz  <poenitz@gmx.net>
+
+       * buffer.h: use Undo directly instead of shared_ptr<Undo>
+
+       * paragraph_pimpl.h:    
+       * paragraph.[Ch]: some Inset -> UpdatableInset changes
+
+       * undo.[Ch]: use ParagraphList instead of vector<Paragraph>
+
+       * undo_funcs.C: make some simple cases of undo work again
+
 2003-06-03  John Levon  <levon@movementarian.org>
 
        * ispell.C: HPUX doesn't have sys/select.h
index 09c2b5670c6b230faf327ef4e3d4eb31d409e244..d5e1f08b365c382a6ed8d2e7547af0c14b8a59f3 100644 (file)
@@ -23,7 +23,6 @@
 #include "author.h"
 #include "iterators.h"
 
-#include <boost/shared_ptr.hpp>
 #include <boost/scoped_ptr.hpp>
 
 class BufferView;
@@ -273,10 +272,10 @@ public:
        bool isMultiLingual();
 
        /// Does this mean that this is buffer local?
-       limited_stack<boost::shared_ptr<Undo> > undostack;
+       limited_stack<Undo> undostack;
 
        /// Does this mean that this is buffer local?
-       limited_stack<boost::shared_ptr<Undo> > redostack;
+       limited_stack<Undo> redostack;
 
        ///
        BufferParams params;
index 29528a5f2b71b403e8708b487c92111d7ac5a0b3..14e6696ef156a03c182dc66ab9f298ea6610972e 100644 (file)
@@ -1,3 +1,8 @@
+
+2003-06-04  André Pönitz  <poenitz@gmx.net>
+
+       * inset.[Ch]: change owner_ from Inset * to UpdatableInset *
+
 2003-06-04  John Levon  <levon@movementarian.org>
 
        * insettabular.C: back out tall table speed up. It was broken
index a69f1f8884baa8d348423ed2d986c68b395a71a0..b8d7281569863ad553fcd097a5a1286f3caaf16f 100644 (file)
@@ -22,6 +22,8 @@
 #include "dimension.h"
 #include "metricsinfo.h"
 
+#include "insets/updatableinset.h"
+
 #include "frontends/Painter.h"
 #include "frontends/mouse_state.h"
 
index edd4d01fffa275972c821d57ccb392573001bd22..29b18c534b0a147aad3009da489eebc0300ec045 100644 (file)
@@ -33,6 +33,7 @@ class LyXCursor;
 class FuncRequest;
 class WordLangTuple;
 class ParagraphList;
+class UpdatableInset;
 
 namespace grfx {
        class PreviewLoader;
@@ -216,9 +217,9 @@ public:
        ///
        string const & getInsetName() const { return name_; }
        ///
-       void setOwner(Inset * inset) { owner_ = inset; }
+       void setOwner(UpdatableInset * inset) { owner_ = inset; }
        ///
-       Inset * owner() const { return owner_; }
+       UpdatableInset * owner() const { return owner_; }
        ///
        void parOwner(Paragraph * par) { par_owner_ = par; }
        ///
@@ -342,7 +343,7 @@ protected:
 
 private:
        ///
-       Inset * owner_;
+       UpdatableInset * owner_;
        /// the paragraph in which this inset has been inserted
        Paragraph * par_owner_;
        ///
index 4b93fde201d6cc6b394b70af80246c784259f625..6b25e65864ae634917b44f4720f1e97f1a453e60 100644 (file)
@@ -528,14 +528,7 @@ void InsetInclude::draw(PainterInfo & pi, int x, int y) const
        if (!preview_->monitoring())
                preview_->startMonitoring();
 
-       Dimension dim;
-       MetricsInfo mi;
-       mi.base.bv = pi.base.bv;
-       mi.base.font = pi.base.font;
-       metrics(mi, dim);
-       dim_ = dim;
-
-       pi.pain.image(x, y - dim.asc, dim.wid, dim.height(),
+       pi.pain.image(x, y - dim_.asc, dim_.wid, dim_.height(),
                            *(preview_->pimage()->image()));
 }
 
index b1a737955eaa2cac3aad98bb2f8b0d3902fbee7e..7fb2c50776711f42433de0c416f8d3abadd22864 100644 (file)
@@ -501,7 +501,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & ev) const
                // jump back to owner if an InsetText, so
                // we get back to the InsetTabular or whatever
                if (inset->lyxCode() == Inset::TEXT_CODE)
-                       inset = static_cast<UpdatableInset*>(inset->owner());
+                       inset = inset->owner();
 
                Inset::Code code = inset->lyxCode();
                switch (code) {
index 844b2b50d34f6398839b4099315792f93c82a2a6..028db2d8280b623fa0835562ceeec588e794c57d 100644 (file)
@@ -97,6 +97,32 @@ Paragraph::Paragraph(Paragraph const & lp)
 }
 
 
+void Paragraph::operator=(Paragraph const & lp)
+{
+       // needed as we will destroy the pimpl_ before copying it
+       if (&lp != this)
+               return;
+       lyxerr << "Paragraph::operator=()\n";
+       delete pimpl_;
+       pimpl_ = new Pimpl(*lp.pimpl_, this);
+
+       enumdepth = lp.enumdepth;
+       itemdepth = lp.itemdepth;
+       // this is because of the dummy layout of the paragraphs that
+       // follow footnotes
+       layout_ = lp.layout();
+
+       // copy everything behind the break-position to the new paragraph
+       insetlist = lp.insetlist;
+       InsetList::iterator it = insetlist.begin();
+       InsetList::iterator end = insetlist.end();
+       for (; it != end; ++it) {
+               it->inset = it->inset->clone();
+               // tell the new inset who is the boss now
+               it->inset->parOwner(this);
+       }
+}
+
 // the destructor removes the new paragraph from the list
 Paragraph::~Paragraph()
 {
@@ -1205,14 +1231,14 @@ string const Paragraph::asString(Buffer const * buffer,
 }
 
 
-void Paragraph::setInsetOwner(Inset * i)
+void Paragraph::setInsetOwner(UpdatableInset * inset)
 {
-       pimpl_->inset_owner = i;
+       pimpl_->inset_owner = inset;
        InsetList::iterator it = insetlist.begin();
        InsetList::iterator end = insetlist.end();
        for (; it != end; ++it)
                if (it->inset)
-                       it->inset->setOwner(i);
+                       it->inset->setOwner(inset);
 }
 
 
@@ -1350,7 +1376,7 @@ void Paragraph::layout(LyXLayout_ptr const & new_layout)
 }
 
 
-Inset * Paragraph::inInset() const
+UpdatableInset * Paragraph::inInset() const
 {
        return pimpl_->inset_owner;
 }
index 1524217ac371efad2befa72ed45719b04401632c..c89c15b787e06439330285ede006b3f86d7906fb 100644 (file)
@@ -31,6 +31,7 @@ class LatexRunParams;
 class ParagraphParameters;
 class TexRow;
 class ParagraphList;
+class UpdatableInset;
 
 /// A Paragraph holds all text, attributes and insets in a text paragraph
 class Paragraph  {
@@ -55,7 +56,7 @@ public:
        ///
        Paragraph(Paragraph const &);
        ///
-       //void operator=(Paragraph const &);
+       void operator=(Paragraph const &);
        /// the destructor removes the new paragraph from the list
        ~Paragraph();
 
@@ -105,9 +106,9 @@ public:
        void makeSameLayout(Paragraph const & par);
 
        ///
-       Inset * inInset() const;
+       UpdatableInset * inInset() const;
        ///
-       void setInsetOwner(Inset * i);
+       void setInsetOwner(UpdatableInset * inset);
        ///
        void deleteInsetsLyXText(BufferView *);
        ///
index 9a1ea617d6a0ddaff00f0bd8e8030a5d9e79a6b2..8d1977d8a347f7feb58add3cd29183509afea3af 100644 (file)
@@ -84,7 +84,7 @@ struct Paragraph::Pimpl {
        /// erase the given range
        int erase(lyx::pos_type start, lyx::pos_type end);
        ///
-       Inset * inset_owner;
+       UpdatableInset * inset_owner;
 
        /** A font entry covers a range of positions. Notice that the
            entries in the list are inserted in random order.
index 7ab024522dce3f22d494949b4ae0e5fff160b43f..e9faf877e9ff5b7f6243b55cce8a954b36144272 100644 (file)
@@ -1,3 +1,8 @@
+
+2003-06-04  André Pönitz  <poenitz@gmx.net>
+
+       * limited_stack.h (top): return reference instead of value
+
 2003-06-02  Angus Leeming  <leeming@lyx.org>
 
        * filetools.[Ch] (copyFileToDir): new helper function.
index f56d0c3ca621f430f9f1f80691c00254c0ce2259..319a05c2d5df8316772c0fd0e94c6fa2c98ebb94 100644 (file)
@@ -33,7 +33,7 @@ public:
        }
 
        /// Return the top element.
-       value_type top() {
+       value_type top() {
                return c_.front();
        }
 
index c380608e371bc2babebc7177c2da68c449274954..17c410da5af45e37c13ebe27f3898548ecf3b877 100644 (file)
@@ -330,7 +330,7 @@ void LyXText::toggleInset()
                // No, try to see if we are inside a collapsable inset
                if (inset_owner && inset_owner->owner()
                    && inset_owner->owner()->isOpen()) {
-                       bv()->unlockInset(static_cast<UpdatableInset *>(inset_owner->owner()));
+                       bv()->unlockInset(inset_owner->owner());
                        inset_owner->owner()->close(bv());
                        bv()->getLyXText()->cursorRight(bv());
                }
@@ -1772,7 +1772,7 @@ float LyXText::getCursorX(RowList::iterator rit,
 void LyXText::setCursorIntern(ParagraphList::iterator pit,
                              pos_type pos, bool setfont, bool boundary)
 {
-       InsetText * it = static_cast<InsetText *>(pit->inInset());
+       UpdatableInset * it = pit->inInset();
        if (it) {
                if (it != inset_owner) {
                        lyxerr[Debug::INSETS] << "InsetText   is " << it
index 9b093e41ed4b88b6cd5e4012926904b63198bf1b..ca532b4b1cbbe9689de9fadab93061bf2dfe5236 100644 (file)
@@ -17,7 +17,7 @@
 Undo::Undo(undo_kind kind_arg, int id_inset_arg,
           int number_before_arg, int number_behind_arg,
           int cursor_par_arg, int cursor_pos_arg,
-          std::vector<Paragraph *> const & par_arg)
+          ParagraphList const & par_arg)
        : pars(par_arg)
 {
        kind = kind_arg;
@@ -28,11 +28,3 @@ Undo::Undo(undo_kind kind_arg, int id_inset_arg,
        cursor_pos = cursor_pos_arg;
 }
 
-
-Undo::~Undo()
-{
-       std::vector<Paragraph *>::iterator it = pars.begin();
-       std::vector<Paragraph *>::iterator end = pars.end();
-       for ( ; it != end; ++it)
-               delete *it;
-}
index 19fb2d13631f4b35c5fa028fb72117b89fce478f..8b85b7f50c83c58dafee5fc6601e9a23ff849ebd 100644 (file)
@@ -12,9 +12,7 @@
 #ifndef UNDO_H
 #define UNDO_H
 
-#include <vector>
-
-class Paragraph;
+#include "ParagraphList.h"
 
 ///
 class Undo {
@@ -43,14 +41,14 @@ public:
        ///
        int cursor_pos; // valid if >= 0
        ///
-       std::vector<Paragraph *> pars;
-       ///
-       Undo(undo_kind kind_arg, int id_inset_arg,
-            int number_before_arg, int number_behind_arg,
-            int cursor_par_arg, int cursor_pos_arg,
-            std::vector<Paragraph *> const & par_arg);
+       ParagraphList pars;
+
        ///
-       ~Undo();
+       Undo(undo_kind kind, int inset_id,
+            int before_par_id, int behind_par_id,
+            int cursor_par_id, int cursor_pos,
+            ParagraphList const & par_arg);
+
 };
 
 
index 3630619a4e3a31080dd5dc4ae459d2c14cbb2253..b0e2eddbc0f518f49efa657a31987b5ba7779d92 100644 (file)
 #include "support/LAssert.h"
 #include "iterators.h"
 
-#include <vector>
-
-using std::vector;
-using boost::shared_ptr;
-
 
 /// The flag used by FinishUndo().
 bool undo_finished;
@@ -33,31 +28,6 @@ bool undo_frozen;
 
 namespace {
 
-/// Utility to return the cursor.
-LyXCursor const & undoCursor(BufferView * bv)
-{
-       if (bv->theLockingInset())
-               return bv->theLockingInset()->cursor(bv);
-       return bv->text->cursor;
-}
-
-
-/**
- * Returns a pointer to the very first Paragraph depending of where
- * we are so it will return the first paragraph of the buffer or the
- * first paragraph of the textinset we're in.
- */
-ParagraphList * undoParagraphs(BufferView * bv, int inset_id)
-{
-       Inset * inset = bv->buffer()->getInsetFromID(inset_id);
-       if (inset) {
-               ParagraphList * result = inset->getParagraphs(0);
-               if (result && !result->empty())
-                       return result;
-       }
-       return &bv->text->ownerParagraphs();
-}
-
 
 /**
  * Finish the undo operation in the case there was no entry
@@ -76,120 +46,111 @@ void finishNoUndo(BufferView * bv)
 // Returns false if no undo possible.
 bool textHandleUndo(BufferView * bv, Undo & undo)
 {
-       Buffer * b = bv->buffer();
+       Buffer * buf = bv->buffer();
 
-       ParIterator const before = b->getParFromID(undo.number_of_before_par);
-       ParIterator const behind = b->getParFromID(undo.number_of_behind_par);
-       ParIterator const null   = b->par_iterator_end();
+       ParIterator const before = buf->getParFromID(undo.number_of_before_par);
+       ParIterator const behind = buf->getParFromID(undo.number_of_behind_par);
+       ParIterator const null   = buf->par_iterator_end();
 
        int const before_id = (before == null) ? -1 : before->id();
        int const behind_id = (behind == null) ? -1 : behind->id();
        int const inset_id  = undo.number_of_inset_id;
 
-       ParagraphList * plist = undoParagraphs(bv, inset_id);
+       Inset * inset = bv->buffer()->getInsetFromID(inset_id);
+       LyXText * text = inset ? inset->getLyXText(bv) : bv->text;
+
+       ParagraphList * plist = &bv->text->ownerParagraphs();
+       if (inset) {
+               ParagraphList * tmp = inset->getParagraphs(0);
+               if (tmp && !tmp->empty())
+                       plist = tmp;
+       }
 
        ParagraphList::iterator first;
        if (before == null) {
                // if there's no before take the beginning of parlist.
                first = plist->begin();
-               LyXText * t = bv->text;
-               if (inset_id >= 0)
-                       if (Inset * in = bv->buffer()->getInsetFromID(inset_id))
-                               t = in->getLyXText(bv);
-               t->setCursorIntern(plist->begin(), 0);
+               text->setCursorIntern(plist->begin(), 0);
        } else {
                first = *before;
                ++first;
        }
        int const first_id  = first->id();
 
-       int after_id;
-       ParagraphList::iterator after;
-       if (behind == null) {
-               // if there's no behind take the end of parlist.
-               after = plist->end();
-               after_id = -1;
-       } else {
-               after = *behind;
-               after_id = after->id();
-       }
-
-       lyxerr << "\nbefore_id: " << before_id << "\n";
-       lyxerr << "first_id:  " << first_id  << "\n";
-       lyxerr << "after_id: " << after_id << "\n";
-       lyxerr << "behind_id: " << behind_id << "\n";
-       lyxerr << "inset_id: " << inset_id << "\n";
+       lyxerr << "\nhandle: before_id: " << before_id << "\n";
+       lyxerr << "handle: first_id:  " << first_id  << "\n";
+       lyxerr << "handle: behind_id: " << behind_id << "\n";
+       lyxerr << "handle: inset_id: " << inset_id << "\n";
 
        // Set the right(new) inset-owner of the paragraph if there is any.
-       if (!undo.pars.empty()) {
-               Inset * in = 0;
-               if (before != null)
-                       in = before->inInset();
-               else if (inset_id >= 0)
-                       in = bv->buffer()->getInsetFromID(inset_id);
-               for (size_t i = 0, n = undo.pars.size(); i < n; ++i)
-                       undo.pars[i]->setInsetOwner(in);
-       }
-
-
-       // quick hack to make the common case work
-       if (undo.pars.size() == 1 && boost::next(first) == after) {
-       //      first = *undo.pars[0];
-               lyxerr << "could use special case...\n";
+       UpdatableInset * in = 0;
+       if (before != null)
+               in = before->inInset();
+       else if (inset_id >= 0) {
+               Inset * inset = bv->buffer()->getInsetFromID(inset_id);
+               in = static_cast<UpdatableInset *>(inset);
        }
+       ParagraphList::iterator pit = undo.pars.begin();
+       ParagraphList::iterator end = undo.pars.end();
+       for ( ; pit != end; ++pit)
+               pit->setInsetOwner(in);
+       lyxerr << "in: " << in << "\n";
+       lyxerr << "undo.pars.size(): " << undo.pars.size() << "\n";
+
+       // remove stuff between first and behind
+       if (behind == null) 
+               plist->erase(first, plist->end());
+       else
+               plist->erase(first, *behind);
+       lyxerr << "after erase\n";
 
-#if 0
-       // remove stuff between first and after
-       plist->erase(first, after);
        // re-create first
        if (before == null) {
                // if there's no before take the beginning of parlist.
+               lyxerr << "no 'before'\n";
                first = plist->begin();
        } else {
+               lyxerr << "have 'before'\n";
                first = *before;
                ++first;
        }
 
-#endif
 
        // inset saved paragraphs
-       for (size_t i = 0, n = undo.pars.size(); i < n; ++i) {
-               lyxerr << " inserting par " << undo.pars[i]->id() << "\n";
-               lyxerr << " inserting plist: " << plist << "\n";
-               //plist->insert(first, new Paragraph(*undo.pars[i], true));
-               /*
-                       // A memory optimization for edit:
-                       // Only layout information
-                       // is stored in the undo. So restore
-                       // the text informations.
-                       if (undo.kind == Undo::EDIT) {
-                               undo.pars[par]->setContentsFromPar(*deletelist.back());
-                               ++par;
-                       }
-               */
-       }
+       lyxerr << "undo.pars.size(): " << undo.pars.size() << "\n";
+       plist->insert(first, undo.pars.begin(), undo.pars.end());
+       lyxerr << "after insert\n";
+       /*
+               // A memory optimization for edit:
+               // Only layout information
+               // is stored in the undo. So restore
+               // the text informations.
+               if (undo.kind == Undo::EDIT) {
+                       undo.pars[par]->setContentsFromPar(*deletelist.back());
+                       ++par;
+               }
+       */
 
        // Set the cursor for redoing
        // if we have a par before the first.
        if (before != null) {
                Inset * it = before->inInset();
-               if (it)
-                       it->getLyXText(bv)->setCursorIntern(*before, 0);
-               else
-                       bv->text->setCursorIntern(*before, 0);
+               LyXText * text = it ? it->getLyXText(bv) : bv->text;
+               text->setCursorIntern(*before, 0);
        }
 
        UpdatableInset * it = 0;
-       if (first != plist->begin())
-               it = static_cast<UpdatableInset*>(first->inInset());
+       if (first != plist->end())
+               it = first->inInset();
+       lyxerr << "it: " << it << "\n";
 
-       LyXText * text = it ? it->getLyXText(bv) : bv->text;
 
        text->redoParagraphs(text->cursor, plist->end());
 
        ParIterator tmppar = bv->buffer()->getParFromID(inset_id);
 
        if (tmppar != null) {
+               lyxerr << "tmppar: " << tmppar->id() << "\n";
                LyXText * t;
                Inset * it = tmppar->inInset();
                if (it) {
@@ -205,9 +166,12 @@ bool textHandleUndo(BufferView * bv, Undo & undo)
                t->clearSelection();
                t->selection.cursor = t->cursor;
                t->updateCounters();
+       } else {
+               lyxerr << "tmppar == null \n";
        }
 
        if (it) {
+               lyxerr << "fit cursor...\n";
                bv->fitCursor();
                bv->updateInset(it);
                bv->text->setCursorIntern(bv->text->cursor.par(),
@@ -217,28 +181,30 @@ bool textHandleUndo(BufferView * bv, Undo & undo)
        finishUndo();
        bv->text->postPaint(0);
 
+       lyxerr << "finished  textHandleUndo...\n";
        return true;
 }
 
 
-bool createUndo(BufferView * bv, Undo::undo_kind kind,
-       int first_id, int last_id, shared_ptr<Undo> & u)
+void createUndo(BufferView * bv, Undo::undo_kind kind,
+       int first_id, int last_id,
+       limited_stack<Undo> & stack)
 {
-       Buffer * b = bv->buffer();
+       Buffer * buf = bv->buffer();
 
-       ParIterator null    = b->par_iterator_end();
+       ParIterator null    = buf->par_iterator_end();
        ParIterator prev    = null;
        ParIterator before  = null;
        ParIterator first   = null;
        ParIterator last    = null;
        ParIterator behind  = null;
 
-       for (ParIterator it = b->par_iterator_begin(); it != null; ++it) {
-               if ((*it)->id() == first_id) {
+       for (ParIterator it = buf->par_iterator_begin(); it != null; ++it) {
+               if (it->id() == first_id) {
                        first = it;
                        before = prev;
                }
-               if ((*it)->id() == last_id) {
+               if (it->id() == last_id) {
                        last = it;
                        behind = last;
                        ++behind;
@@ -253,11 +219,12 @@ bool createUndo(BufferView * bv, Undo::undo_kind kind,
        int const behind_id = (behind == null) ? -1 : behind->id();
        int inset_id        = (first->inInset()) ? first->inInset()->id() : -1;
 
-       lyxerr << "\nbefore_id: " << before_id << "\n";
-       lyxerr << "first_id:  " << first_id  << "\n";
-       lyxerr << "last_id:   " << last_id   << "\n";
-       lyxerr << "behind_id: " << behind_id << "\n";
-       lyxerr << "inset_id:  " << inset_id  << "\n";
+       lyxerr << "\ncreate: before_id: " << before_id << "\n";
+       lyxerr << "create: first_id:  " << first_id  << "\n";
+       lyxerr << "create: last_id:   " << last_id   << "\n";
+       lyxerr << "create: behind_id: " << behind_id << "\n";
+       lyxerr << "create: inset_id:  " << inset_id  << "\n";
+       lyxerr << "create: kind:  " << kind  << "\n";
 
        ParagraphList * plist = 0;
        if (first != null)
@@ -266,7 +233,7 @@ bool createUndo(BufferView * bv, Undo::undo_kind kind,
                plist = &behind.plist();
        else if (!plist) {
                lyxerr << "plist from buffer (should this happen?)\n";
-               plist = &b->paragraphs;
+               plist = &buf->paragraphs;
        }
 
        // Undo::EDIT and Undo::FINISH are
@@ -276,32 +243,32 @@ bool createUndo(BufferView * bv, Undo::undo_kind kind,
        // appear one by one when undoing.
        // EDIT is special since only layout information, not the
        // contents of a paragaph are stored.
-       if (!undo_finished && (kind != Undo::EDIT) && (kind != Undo::FINISH)) {
+       if (!undo_finished && kind != Undo::EDIT && kind != Undo::FINISH) {
                // Check whether storing is needed.
-               if (!b->undostack.empty() &&
-                   b->undostack.top()->kind == kind &&
-                   b->undostack.top()->number_of_before_par == before_id &&
-                   b->undostack.top()->number_of_behind_par == behind_id) {
+               if (!buf->undostack.empty() &&
+                   buf->undostack.top().kind == kind &&
+                   buf->undostack.top().number_of_before_par == before_id &&
+                   buf->undostack.top().number_of_behind_par == behind_id) {
                        // No undo needed.
-                       return false;
+                       return;
                }
        }
 
        // Create a new Undo.
-#warning FIXME Why is this a vector and not a ParagraphList?
-       std::vector<Paragraph *> undo_pars;
+       LyXCursor const & cur = bv->theLockingInset() ?
+                       bv->theLockingInset()->cursor(bv) : bv->text->cursor;
+
+       stack.push(Undo(kind, inset_id,
+               before_id, behind_id, cur.par()->id(), cur.pos(), ParagraphList()));
+
+       ParagraphList & undo_pars = stack.top().pars;
 
        for (ParagraphList::iterator it = *first; it != *last; ++it) {
-               int id = it->id();
-               Paragraph * tmp = new Paragraph(*it);
-               tmp->id(id);
-               undo_pars.push_back(tmp);
+               undo_pars.push_back(*it);
+               undo_pars.back().id(it->id());
        }
-
-       int const id = last->id();
-       Paragraph * tmp = new Paragraph(**last);
-       tmp->id(id);
-       undo_pars.push_back(tmp);
+       undo_pars.push_back(**last);
+       undo_pars.back().id(last->id());
 
        // A memory optimization: Just store the layout
        // information when only edit.
@@ -310,36 +277,29 @@ bool createUndo(BufferView * bv, Undo::undo_kind kind,
        //      for (size_t i = 0, n = undo_pars.size(); i < n; ++i)
        //              undo_pars[i]->clearContents();
 
-       int cursor_par = undoCursor(bv).par()->id();
-       int cursor_pos = undoCursor(bv).pos();
-
-       u.reset(new Undo(kind, inset_id,
-               before_id, behind_id, cursor_par, cursor_pos, undo_pars));
-
        undo_finished = false;
-       return true;
 }
 
 
 // Returns false if no undo possible.
 bool textUndoOrRedo(BufferView * bv,
-       limited_stack<boost::shared_ptr<Undo> > & stack,
-                   limited_stack<boost::shared_ptr<Undo> > & /*otherstack*/)
+       limited_stack<Undo> & stack,
+       limited_stack<Undo> & /*otherstack*/)
 {
        if (stack.empty()) {
                finishNoUndo(bv);
                return false;
        }
 
-       shared_ptr<Undo> undo = stack.top();
+       Undo undo = stack.top();
        stack.pop();
        finishUndo();
 
 /*
        if (!undo_frozen) {
                Buffer * buf = bv->buffer();
-               ParIterator p = b->getParFromID(undo->number_of_before_par);
-               ParIterator const end = b->par_iterator_end();
+               ParIterator p = buf->getParFromID(undo->number_of_before_par);
+               ParIterator const end = buf->par_iterator_end();
                bool ok = false;
                ParagraphList::iterator first;
                // default constructed?
@@ -347,13 +307,21 @@ bool textUndoOrRedo(BufferView * bv,
                        first = p.par();
                        if (first->next())
                                first = first->next();
-               } else
-                       first = undoParagraphs(bv, undo->number_of_inset_id)->begin();
+               } else {
+                       // Set first to the very first Paragraph depending of where
+                       // we are so it will return the first paragraph of the buffer or the
+                       // first paragraph of the textinset we're in.
+                       first = bv->text->ownerParagraphs()->begin();
+                       Inset * inset = bv->buffer()->getInsetFromID(inset_id);
+                       if (inset) {
+                               ParagraphList * result = inset->getParagraphs(0);
+                               if (result && !result->empty())
+                                       first = result->begin();
+                       }
+               }
                if (ok) {
-                       shared_ptr<Undo> u;
-                       ParIterator behind = b->getParFromID(undo->number_of_behind_par);
-                       if (createUndo(bv, undo->kind, first, behind.par(), u))
-                               otherstack.push(u);
+                       ParIterator behind = buf->getParFromID(undo.number_of_behind_par);
+                       createUndo(bv, undo.kind, first, behind.par(), otherstack);
                }
        }
 */
@@ -364,7 +332,7 @@ bool textUndoOrRedo(BufferView * bv,
        // is requested.
        freezeUndo();
        bv->unlockInset(bv->theLockingInset());
-       bool const ret = textHandleUndo(bv, *undo.get());
+       bool const ret = textHandleUndo(bv, undo);
        unFreezeUndo();
        return ret;
 }
@@ -417,12 +385,8 @@ void setUndo(BufferView * bv, Undo::undo_kind kind,
 void setUndo(BufferView * bv, Undo::undo_kind kind,
             ParagraphList::iterator first, ParagraphList::iterator last)
 {
-#warning DISABLED
-       //return;
        if (!undo_frozen) {
-               shared_ptr<Undo> u;
-               if (createUndo(bv, kind, first->id(), last->id(), u))
-                       bv->buffer()->undostack.push(u);
+               createUndo(bv, kind, first->id(), last->id(), bv->buffer()->undostack);
                bv->buffer()->redostack.clear();
        }
 }