This brings back undo (and redo...) to a somewhat working state.

The most prominent flaw is that the cursor is placed at the beginning
of the first paragraph touched by the undo in the main paragraph list.

This means undo currently leaves all minipages/tabulars/whatever
[Pretty much the same situation as we had with math all the time, so
I know this is annyoing...]

Internally I had to change the ParIterator container from stack to vector
as I needed access to the 'bottom' as well.

This can be reverted as soon as we have 'per inset undo' back.

Ok?

Andre'

-- 
Those who desire to give up Freedom in order to gain Security, will not have,
nor do they deserve, either one.     (T. Jefferson or B. Franklin or both...)
Index: Makefile.am
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/Makefile.am,v
retrieving revision 1.176
diff -u -p -r1.176 Makefile.am
--- Makefile.am 29 May 2003 11:19:50 -0000      1.176
+++ Makefile.am 4 Jun 2003 11:14:05 -0000
@@ -79,6 +79,7 @@ lyx_SOURCES = \
        MenuBackend.h \
        paragraph_funcs.C \
        paragraph_funcs.h \
+       ParagraphList.C \
        ParagraphList.h \
        ParagraphParameters.C \
        ParagraphParameters.h \
Index: ParagraphList.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/ParagraphList.h,v
retrieving revision 1.19
diff -u -p -r1.19 ParagraphList.h
--- ParagraphList.h     28 May 2003 06:47:14 -0000      1.19
+++ ParagraphList.h     4 Jun 2003 11:14:05 -0000
@@ -3,165 +3,24 @@
 #ifndef PARAGRAPH_LIST_H
 #define PARAGRAPH_LIST_H
 
-//#define NO_STD_LIST 1
-
-#ifndef NO_STD_LIST
-
 #include "paragraph.h"
 
 #include <list>
 
-struct ParagraphList : public std::list<Paragraph>
-{
-};
-
-typedef std::pair<ParagraphList::iterator, int> PitPosPair;
-
-#else
-
-class Paragraph;
-
-#include <iterator>
-#include <utility>
-
-///
-class ParagraphList {
-public:
-       ///
-       class iterator {
-       public:
-               friend class ParagraphList;
-               ///
-               typedef std::bidirectional_iterator_tag iterator_category;
-               ///
-               typedef Paragraph * value_type;
-               ///
-               typedef ptrdiff_t difference_type;
-               ///
-               typedef Paragraph * pointer;
-               ///
-               typedef Paragraph & reference;
-               ///
-               iterator();
-               ///
-               reference operator*();
-               ///
-               pointer operator->();
-               ///
-               iterator & operator++();
-               ///
-               iterator operator++(int);
-               ///
-               iterator & operator--();
-               ///
-               iterator operator--(int);
-       private:
-               ///
-               iterator(value_type);
-               ///
-               Paragraph * ptr;
-       };
-       ///
-       class const_iterator {
-       public:
-               friend class ParagraphList;
-               ///
-               typedef std::bidirectional_iterator_tag iterator_category;
-               ///
-               typedef Paragraph * value_type;
-               ///
-               typedef ptrdiff_t difference_type;
-               ///
-               typedef Paragraph const * const_pointer;
-               ///
-               typedef Paragraph const & const_reference;
-               ///
-               const_iterator();
-               ///
-               const_reference operator*();
-               ///
-               const_pointer operator->();
-               ///
-               const_iterator & operator++();
-               ///
-               const_iterator operator++(int);
-               ///
-               const_iterator & operator--();
-               ///
-               const_iterator operator--(int);
-       private:
-               ///
-               const_iterator(value_type);
-               ///
-               Paragraph * ptr;
-       };
-       ///
+struct ParagraphList : public std::list<Paragraph> {
+       /// clear id_
        ParagraphList();
-       ///
-       ParagraphList(ParagraphList const &);
-       ///
-       ParagraphList & operator=(ParagraphList const &);
-       ///
-       iterator insert(iterator it, Paragraph const & par);
-       ///
-       void insert(iterator pos, iterator beg, iterator end);
-       ///
-       void assign(iterator beg, iterator end);
-       ///
-       void splice(iterator pos, ParagraphList & pl);
-       ///
-       void clear();
-       ///
-       iterator erase(iterator it);
-       ///
-       iterator erase(iterator first, iterator last);
-       ///
-       iterator begin();
-       ///
-       const_iterator begin() const;
-       ///
-       iterator end();
-       ///
-       const_iterator end() const;
-       ///
-       void push_back(Paragraph const &);
-       ///
-       Paragraph const & front() const;
-       ///
-       Paragraph & front();
-       ///
-       Paragraph const & back() const;
-       ///
-       Paragraph & back();
-       ///
-       int size() const;
-       ///
-       bool empty() const;
+       /// return id for undo
+       int id() const;
+       /// create a unique id 
+       void createId();
 private:
-       ///
-       Paragraph * parlist;
+       /// our personal id
+       int id_;
+       /// incremented on each call to createId()
+       static int last_id_;    
 };
 
-
-
 typedef std::pair<ParagraphList::iterator, int> PitPosPair;
-
-
-
-///
-bool operator==(ParagraphList::iterator const & i1,
-               ParagraphList::iterator const & i2);
-///
-bool operator!=(ParagraphList::iterator const & i1,
-               ParagraphList::iterator const & i2);
-
-///
-bool operator==(ParagraphList::const_iterator const & i1,
-               ParagraphList::const_iterator const & i2);
-///
-bool operator!=(ParagraphList::const_iterator const & i1,
-               ParagraphList::const_iterator const & i2);
-
-#endif
 
 #endif
Index: iterators.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/iterators.C,v
retrieving revision 1.12
diff -u -p -r1.12 iterators.C
--- iterators.C 29 May 2003 01:13:16 -0000      1.12
+++ iterators.C 4 Jun 2003 11:14:05 -0000
@@ -17,11 +17,13 @@
 #include <boost/next_prior.hpp>
 #include <boost/optional.hpp>
 
-#include <stack>
+// it's conceptionally a stack, but undo needs random access...
+//#include <stack>
+#include <vector>
 
 using boost::next;
 using boost::optional;
-using std::stack;
+using std::vector;
 
 ///
 /// ParPosition
@@ -68,14 +70,14 @@ bool operator!=(ParPosition const & pos1
 ///
 
 struct ParIterator::Pimpl {
-       typedef stack<ParPosition> PosHolder;
+       typedef vector<ParPosition> PosHolder;
        PosHolder positions;
 };
 
 ParIterator::ParIterator(ParagraphList::iterator pit, ParagraphList const & pl)
        : pimpl_(new Pimpl)
 {
-       pimpl_->positions.push(ParPosition(pit, pl));
+       pimpl_->positions.push_back(ParPosition(pit, pl));
 }
 
 
@@ -98,14 +100,14 @@ void ParIterator::operator=(ParIterator 
 ParIterator & ParIterator::operator++()
 {
        while (!pimpl_->positions.empty()) {
-               ParPosition & p = pimpl_->positions.top();
+               ParPosition & p = pimpl_->positions.back();
 
                // Does the current inset contain more "cells" ?
                if (p.index) {
                        ++(*p.index);
                        ParagraphList * plist = 
(*p.it)->inset->getParagraphs(*p.index);
                        if (plist && !plist->empty()) {
-                               pimpl_->positions.push(ParPosition(plist->begin(), 
*plist));
+                               
pimpl_->positions.push_back(ParPosition(plist->begin(), *plist));
                                return *this;
                        }
                        ++(*p.it);
@@ -121,7 +123,7 @@ ParIterator & ParIterator::operator++()
                        ParagraphList * plist = (*p.it)->inset->getParagraphs(0);
                        if (plist && !plist->empty()) {
                                p.index.reset(0);
-                               pimpl_->positions.push(ParPosition(plist->begin(), 
*plist));
+                               
pimpl_->positions.push_back(ParPosition(plist->begin(), *plist));
                                return *this;
                        }
                }
@@ -137,7 +139,7 @@ ParIterator & ParIterator::operator++()
                }
 
                // Drop end and move up in the stack.
-               pimpl_->positions.pop();
+               pimpl_->positions.pop_back();
        }
        return *this;
 }
@@ -145,13 +147,19 @@ ParIterator & ParIterator::operator++()
 
 ParagraphList::iterator ParIterator::operator*() const
 {
-       return pimpl_->positions.top().pit;
+       return pimpl_->positions.back().pit;
 }
 
 
 ParagraphList::iterator ParIterator::operator->() const
 {
-       return pimpl_->positions.top().pit;
+       return pimpl_->positions.back().pit;
+}
+
+
+ParagraphList::iterator ParIterator::outerPar() const
+{
+       return pimpl_->positions[0].pit;
 }
 
 
@@ -163,7 +171,7 @@ size_t ParIterator::size() const
 
 ParagraphList & ParIterator::plist() const
 {
-       return *const_cast<ParagraphList*>(pimpl_->positions.top().plist);
+       return *const_cast<ParagraphList*>(pimpl_->positions.back().plist);
 }
 
 
@@ -185,7 +193,7 @@ bool operator!=(ParIterator const & iter
 
 
 struct ParConstIterator::Pimpl {
-       typedef stack<ParPosition> PosHolder;
+       typedef vector<ParPosition> PosHolder;
        PosHolder positions;
 };
 
@@ -194,7 +202,7 @@ ParConstIterator::ParConstIterator(Parag
                                   ParagraphList const & pl)
        : pimpl_(new Pimpl)
 {
-       pimpl_->positions.push(ParPosition(pit, pl));
+       pimpl_->positions.push_back(ParPosition(pit, pl));
 }
 
 
@@ -210,14 +218,14 @@ ParConstIterator::ParConstIterator(ParCo
 ParConstIterator & ParConstIterator::operator++()
 {
        while (!pimpl_->positions.empty()) {
-               ParPosition & p = pimpl_->positions.top();
+               ParPosition & p = pimpl_->positions.back();
 
                // Does the current inset contain more "cells" ?
                if (p.index) {
                        ++(*p.index);
                        ParagraphList * plist = 
(*p.it)->inset->getParagraphs(*p.index);
                        if (plist && !plist->empty()) {
-                               pimpl_->positions.push(ParPosition(plist->begin(), 
*plist));
+                               
pimpl_->positions.push_back(ParPosition(plist->begin(), *plist));
                                return *this;
                        }
                        ++(*p.it);
@@ -233,7 +241,7 @@ ParConstIterator & ParConstIterator::ope
                        ParagraphList * plist = (*p.it)->inset->getParagraphs(0);
                        if (plist && !plist->empty()) {
                                p.index.reset(0);
-                               pimpl_->positions.push(ParPosition(plist->begin(), 
*plist));
+                               
pimpl_->positions.push_back(ParPosition(plist->begin(), *plist));
                                return *this;
                        }
                }
@@ -249,7 +257,7 @@ ParConstIterator & ParConstIterator::ope
                }
 
                // Drop end and move up in the stack.
-               pimpl_->positions.pop();
+               pimpl_->positions.pop_back();
        }
 
        return *this;
@@ -258,13 +266,13 @@ ParConstIterator & ParConstIterator::ope
 
 ParagraphList::iterator ParConstIterator::operator*() const
 {
-       return pimpl_->positions.top().pit;
+       return pimpl_->positions.back().pit;
 }
 
 
 ParagraphList::iterator ParConstIterator::operator->() const
 {
-       return pimpl_->positions.top().pit;
+       return pimpl_->positions.back().pit;
 }
 
 
Index: iterators.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/iterators.h,v
retrieving revision 1.10
diff -u -p -r1.10 iterators.h
--- iterators.h 23 May 2003 10:33:38 -0000      1.10
+++ iterators.h 4 Jun 2003 11:14:05 -0000
@@ -33,6 +33,8 @@ public:
        ///
        ParagraphList::iterator operator->() const;
        ///
+       ParagraphList::iterator outerPar() const;
+       ///
        ParagraphList & plist() const;
        ///
        size_t size() const;
Index: text2.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text2.C,v
retrieving revision 1.366
diff -u -p -r1.366 text2.C
--- text2.C     4 Jun 2003 07:14:03 -0000       1.366
+++ text2.C     4 Jun 2003 11:14:05 -0000
@@ -658,7 +658,7 @@ void LyXText::redoDrawingOfParagraph(LyX
 }
 
 
-// deletes and inserts again all paragaphs between the cursor
+// deletes and inserts again all paragraphs between the cursor
 // and the specified par
 // This function is needed after SetLayout and SetFont etc.
 void LyXText::redoParagraphs(LyXCursor const & cur,
Index: undo.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/undo.C,v
retrieving revision 1.15
diff -u -p -r1.15 undo.C
--- undo.C      4 Jun 2003 07:14:03 -0000       1.15
+++ undo.C      4 Jun 2003 11:14:05 -0000
@@ -11,20 +11,19 @@
 #include <config.h>
 
 #include "undo.h"
-#include "paragraph.h"
 
-
-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,
-          ParagraphList const & par_arg)
-       : pars(par_arg)
-{
-       kind = kind_arg;
-       number_of_inset_id = id_inset_arg;
-       number_of_before_par = number_before_arg;
-       number_of_behind_par = number_behind_arg;
-       number_of_cursor_par = cursor_par_arg;
-       cursor_pos = cursor_pos_arg;
-}
+Undo::Undo(undo_kind kind_arg, int inset, int plist,
+          int first, int last,
+          int cursor, int cursor_pos_arg,
+          ParagraphList const & par)
+       :
+               kind(kind_arg),
+               inset_id(inset),
+               plist_id(plist),
+               first_par_offset(first),
+               last_par_offset(last),
+               cursor_par_offset(cursor),
+               cursor_pos(cursor_pos_arg),
+               pars(par)
+{}
 
Index: undo.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/undo.h,v
retrieving revision 1.17
diff -u -p -r1.17 undo.h
--- undo.h      4 Jun 2003 07:14:03 -0000       1.17
+++ undo.h      4 Jun 2003 11:14:05 -0000
@@ -31,22 +31,24 @@ public:
        ///
        undo_kind kind;
        ///
-       int number_of_before_par;
+       int inset_id; // valid if >= 0, if < 0 then not in inset
        ///
-       int number_of_behind_par;
+       int plist_id;
        ///
-       int number_of_cursor_par;
+       int first_par_offset;
        ///
-       int number_of_inset_id; // valid if >= 0, if < 0 then not in inset
+       int last_par_offset;
+       ///
+       int cursor_par_offset;
        ///
        int cursor_pos; // valid if >= 0
        ///
        ParagraphList pars;
 
        ///
-       Undo(undo_kind kind, int inset_id,
-            int before_par_id, int behind_par_id,
-            int cursor_par_id, int cursor_pos,
+       Undo(undo_kind kind, int inset_id, int plist_id,
+            int first, int last,
+            int cursor, int cursor_pos,
             ParagraphList const & par_arg);
 
 };
Index: undo_funcs.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/undo_funcs.C,v
retrieving revision 1.69
diff -u -p -r1.69 undo_funcs.C
--- undo_funcs.C        4 Jun 2003 07:14:03 -0000       1.69
+++ undo_funcs.C        4 Jun 2003 11:14:05 -0000
@@ -48,78 +48,51 @@ bool textHandleUndo(BufferView * bv, Und
 {
        Buffer * buf = bv->buffer();
 
-       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;
-
-       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();
-               text->setCursorIntern(plist->begin(), 0);
-       } else {
-               first = *before;
-               ++first;
-       }
-       int const first_id  = first->id();
+       ParagraphList * plist = 0;
+       ParIterator null = buf->par_iterator_end();
 
-       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";
+       for (ParIterator it = buf->par_iterator_begin(); it != null; ++it)
+               if (it.plist().id() == undo.plist_id) {
+                       plist = &it.plist();
+                       break;
+               }
 
        // Set the right(new) inset-owner of the paragraph if there is any.
-       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);
+       UpdatableInset * inset = 0;
+       if (undo.inset_id >= 0) {
+               Inset * in = bv->buffer()->getInsetFromID(undo.inset_id);
+               inset = static_cast<UpdatableInset *>(in);
        }
        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";
+               pit->setInsetOwner(inset);
+
+       lyxerr << "\nhandle: inset_id: " << undo.inset_id << "\n";
+       lyxerr << "handle: inset: " << inset << "\n";
+       lyxerr << "handle: plist_id: " << undo.plist_id << "\n";
+       lyxerr << "handle: 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";
-
-       // 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;
+       {
+               ParagraphList::iterator first = plist->begin();
+               advance(first, undo.first_par_offset);
+               ParagraphList::iterator last = plist->begin();
+               advance(last, plist->size() - undo.last_par_offset);
+               lyxerr << "handle: first_id:  " << first->id()  << "\n";
+               lyxerr << "handle: last_id: " << last->id() << "\n";
+               plist->erase(first, ++last);
+               lyxerr << "after remove\n";
+       }
+
+       // re-insert old stuff
+       {
+               ParagraphList::iterator first = plist->begin();
+               advance(first, undo.first_par_offset);
+               plist->insert(first, undo.pars.begin(), undo.pars.end());
+               lyxerr << "after insert\n";
        }
 
-
-       // inset saved paragraphs
-       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
@@ -131,53 +104,53 @@ bool textHandleUndo(BufferView * bv, Und
                }
        */
 
-       // Set the cursor for redoing
-       // if we have a par before the first.
-       if (before != null) {
-               Inset * it = before->inInset();
-               LyXText * text = it ? it->getLyXText(bv) : bv->text;
-               text->setCursorIntern(*before, 0);
-       }
-
-       UpdatableInset * it = 0;
-       if (first != plist->end())
-               it = first->inInset();
-       lyxerr << "it: " << it << "\n";
-
-
-       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) {
-                       FuncRequest cmd(bv, LFUN_INSET_EDIT, "left");
-                       it->localDispatch(cmd);
-                       t = it->getLyXText(bv);
-               } else {
-                       t = bv->text;
+       // redo Paragraphs  (should be handled outside undo...)
+       LyXText * text = inset ? inset->getLyXText(bv) : bv->text;
+       {
+               lyxerr << "text: " << text << "\n";
+               if (undo.first_par_offset) {
+                       ParagraphList::iterator redo = plist->begin();
+                       advance(redo, undo.first_par_offset);
+                       text->setCursorIntern(plist->begin(), 0);
                }
-               t->setCursorIntern(*tmppar, undo.cursor_pos);
-               // Clear any selection and set the selection
-               // cursor for an evt. new selection.
-               t->clearSelection();
-               t->selection.cursor = t->cursor;
-               t->updateCounters();
-       } else {
-               lyxerr << "tmppar == null \n";
+               text->redoParagraphs(text->cursor, plist->end());
+               lyxerr << "after redo\n";
        }
 
+/*
+       Inset * = bv->buffer()->getInsetFromID(inset_id);
+       lyxerr << "tmppar: " << tmppar->id() << "\n";
+       LyXText * t;
        if (it) {
+               FuncRequest cmd(bv, LFUN_INSET_EDIT, "left");
+               it->localDispatch(cmd);
+               t = it->getLyXText(bv);
+       } else {
+               t = bv->text;
+       }
+       t->setCursorIntern(*tmppar, undo.cursor_pos);
+       // Clear any selection and set the selection
+       // cursor for an evt. new selection.
+       t->clearSelection();
+       t->selection.cursor = t->cursor;
+       t->updateCounters();
+*/
+
+       if (inset) {
                lyxerr << "fit cursor...\n";
                bv->fitCursor();
-               bv->updateInset(it);
-               bv->text->setCursorIntern(bv->text->cursor.par(),
-                                         bv->text->cursor.pos());
+               bv->updateInset(inset);
+       }
+
+       // set cursor
+       {
+               ParagraphList::iterator cursor = plist->begin();
+               advance(cursor, undo.cursor_par_offset);
+               bv->text->setCursorIntern(cursor, undo.cursor_pos);
+               lyxerr << "after setCursor\n";
        }
 
+
        finishUndo();
        bv->text->postPaint(0);
 
@@ -187,55 +160,60 @@ bool textHandleUndo(BufferView * bv, Und
 
 
 void createUndo(BufferView * bv, Undo::undo_kind kind,
-       int first_id, int last_id,
+       ParagraphList::iterator first, ParagraphList::iterator last,
        limited_stack<Undo> & stack)
 {
        Buffer * buf = bv->buffer();
 
-       ParIterator null    = buf->par_iterator_end();
-       ParIterator prev    = null;
-       ParIterator before  = null;
-       ParIterator first   = null;
-       ParIterator last    = null;
-       ParIterator behind  = null;
+       ParagraphList * plist = 0;
+       ParIterator null = buf->par_iterator_end();
+
+       lyxerr << "\n";
 
+#if 0
+       // this is what we'd like to have in the end for small grained undo
        for (ParIterator it = buf->par_iterator_begin(); it != null; ++it) {
-               if (it->id() == first_id) {
-                       first = it;
-                       before = prev;
+               if (it->id() == first->id()) {
+                       plist = &it.plist();
+                       break;
                }
-               if (it->id() == last_id) {
-                       last = it;
-                       behind = last;
-                       ++behind;
+       }
+
+#else
+
+       // and that's the big stick we wield now
+       lyxerr << "create: first_id orig:   " << first->id()  << "\n";
+       lyxerr << "create: last_id orig:    " << last->id()   << "\n";
+       plist = &buf->paragraphs;
+       // this is what we'd like to have in the end for small grained undo
+       for (ParIterator it = buf->par_iterator_begin(); it != null; ++it) {
+               if (it->id() == first->id()) {
+                       first = it.outerPar(); 
+                       last = it.outerPar(); 
+                       break;
                }
-               prev = it;
        }
 
-       if (last == null)
-               last = first;
+#endif
 
-       int const before_id = (before == null) ? -1 : before->id();
-       int const behind_id = (behind == null) ? -1 : behind->id();
-       int inset_id        = (first->inInset()) ? first->inInset()->id() : -1;
-
-       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";
+       int const inset_id = first->inInset() ? first->inInset()->id() : -1;
 
-       ParagraphList * plist = 0;
-       if (first != null)
-               plist = &first.plist();
-       else if (behind != null)
-               plist = &behind.plist();
-       else if (!plist) {
-               lyxerr << "plist from buffer (should this happen?)\n";
-               plist = &buf->paragraphs;
+       int const first_offset  = std::distance(plist->begin(), first);
+       int const last_offset   = std::distance(last, plist->end());
+
+       if (last == plist->end()) {
+               lyxerr << "*** createUndo: last == end  schould not happen\n";
        }
 
+       lyxerr << "create: plist_id:     " << plist->id()  << "\n";
+       lyxerr << "create: first_id:     " << first->id()  << "\n";
+       lyxerr << "create: last_id:      " << last->id()   << "\n";
+       lyxerr << "create: first_offset: " << first_offset  << "\n";
+       lyxerr << "create: last_offset:  " << last_offset   << "\n";
+       lyxerr << "create: inset_id:     " << inset_id  << "\n";
+       lyxerr << "create: kind:         " << kind  << "\n";
+
+
        // Undo::EDIT and Undo::FINISH are
        // always finished. (no overlapping there)
        // overlapping only with insert and delete inside one paragraph:
@@ -247,27 +225,33 @@ void createUndo(BufferView * bv, Undo::u
                // Check whether storing is needed.
                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) {
+                   buf->undostack.top().first_par_offset == first_offset &&
+                   buf->undostack.top().last_par_offset == last_offset) {
                        // No undo needed.
                        return;
                }
        }
 
        // Create a new Undo.
+/*
+       // this should be re-activated once we are back at fine-grained undo
        LyXCursor const & cur = bv->theLockingInset() ?
                        bv->theLockingInset()->cursor(bv) : bv->text->cursor;
+       int const cursor_offset = std::distance(plist->begin(), cur.par());
 
-       stack.push(Undo(kind, inset_id,
-               before_id, behind_id, cur.par()->id(), cur.pos(), ParagraphList()));
+       stack.push(Undo(kind, inset_id, plist->id(),
+               first_offset, last_offset, cursor_offset, cur.pos(), ParagraphList()));
+*/
+       stack.push(Undo(kind, inset_id, plist->id(),
+               first_offset, last_offset, first_offset, 0, ParagraphList()));
 
        ParagraphList & undo_pars = stack.top().pars;
 
-       for (ParagraphList::iterator it = *first; it != *last; ++it) {
+       for (ParagraphList::iterator it = first; it != last; ++it) {
                undo_pars.push_back(*it);
                undo_pars.back().id(it->id());
        }
-       undo_pars.push_back(**last);
+       undo_pars.push_back(*last);
        undo_pars.back().id(last->id());
 
        // A memory optimization: Just store the layout
@@ -284,7 +268,7 @@ void createUndo(BufferView * bv, Undo::u
 // Returns false if no undo possible.
 bool textUndoOrRedo(BufferView * bv,
        limited_stack<Undo> & stack,
-       limited_stack<Undo> & /*otherstack*/)
+       limited_stack<Undo> & otherstack)
 {
        if (stack.empty()) {
                finishNoUndo(bv);
@@ -295,38 +279,24 @@ bool textUndoOrRedo(BufferView * bv,
        stack.pop();
        finishUndo();
 
-/*
        if (!undo_frozen) {
+               otherstack.push(undo);
+               otherstack.top().pars.clear();
                Buffer * buf = bv->buffer();
-               ParIterator p = buf->getParFromID(undo->number_of_before_par);
-               ParIterator const end = buf->par_iterator_end();
-               bool ok = false;
-               ParagraphList::iterator first;
-               // default constructed?
-               if (p != end) {
-                       first = p.par();
-                       if (first->next())
-                               first = first->next();
-               } 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) {
-                       ParIterator behind = 
buf->getParFromID(undo.number_of_behind_par);
-                       createUndo(bv, undo.kind, first, behind.par(), otherstack);
+               ParagraphList & plist = buf->paragraphs;
+               lyxerr << "\nredo: first: " << undo.first_par_offset << "\n";
+               lyxerr << "redo: last:  " << undo.last_par_offset << "\n";
+               lyxerr << "redo: size:  " << plist.size() << "\n";
+               if (undo.first_par_offset + undo.last_par_offset <= int(plist.size())) 
{
+                       ParagraphList::iterator first = plist.begin();
+                       advance(first, undo.first_par_offset);
+                       ParagraphList::iterator last = plist.begin();
+                       advance(last, plist.size() - undo.last_par_offset + 1);
+                       otherstack.top().pars.insert(otherstack.top().pars.begin(), 
first, last);
                }
        }
-*/
 
-       // Now we can unlock the inset for saftey because the inset
+       // Now we can unlock the inset for safety because the inset
        // pointer could be changed during the undo-function. Anyway
        // if needed we have to lock the right inset/position if this
        // is requested.
@@ -386,7 +356,7 @@ void setUndo(BufferView * bv, Undo::undo
             ParagraphList::iterator first, ParagraphList::iterator last)
 {
        if (!undo_frozen) {
-               createUndo(bv, kind, first->id(), last->id(), bv->buffer()->undostack);
+               createUndo(bv, kind, first, last, bv->buffer()->undostack);
                bv->buffer()->redostack.clear();
        }
 }

Reply via email to