+
+/**
+These are the elements put on the undo stack. Each object contains complete
+paragraphs from some cell and sufficient information to restore the cursor
+state.
+
+The cell is given by a DocIterator pointing to this cell, the 'interesting'
+range of paragraphs by counting them from begin and end of cell,
+respectively.
+
+The cursor is also given as DocIterator and should point to some place in
+the stored paragraph range. In case of math, we simply store the whole
+cell, as there usually is just a simple paragraph in a cell.
+
+The idea is to store the contents of 'interesting' paragraphs in some
+structure ('Undo') _before_ it is changed in some edit operation.
+Obviously, the stored ranged should be as small as possible. However, it
+there is a lower limit: The StableDocIterator pointing 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.
+
+*/
+struct UndoElement
+{
+ /// Which kind of operation are we recording for?
+ UndoKind kind;
+ /// the position of the cursor
+ StableDocIterator cursor;
+ /// the position of the cell described
+ StableDocIterator cell;
+ /// counted from begin of cell
+ pit_type from;
+ /// complement to end of this cell
+ pit_type end;
+ /// the contents of the saved Paragraphs (for texted)
+ ParagraphList * pars;
+ /// the contents of the saved MathData (for mathed)
+ MathData * array;
+ /// Only used in case of full backups
+ BufferParams bparams;
+ /// Only used in case of full backups
+ bool isFullBuffer;
+};
+
+
+struct Undo::Private
+{
+ Private(Buffer & buffer): buffer_(buffer) {}
+
+ // Returns false if no undo possible.
+ bool textUndoOrRedo(DocIterator & cur, bool isUndoOperation);
+ ///
+ void doRecordUndo(UndoKind kind,
+ DocIterator const & cell,
+ pit_type first_pit,
+ pit_type last_pit,
+ DocIterator const & cur,
+ bool isFullBuffer,
+ bool isUndoOperation);
+
+ ///
+ void recordUndo(UndoKind kind,
+ DocIterator & cur,
+ pit_type first_pit,
+ pit_type last_pit);
+
+ ///
+ Buffer & buffer_;
+ /// Undo stack.
+ limited_stack<UndoElement> undostack;
+ /// Redo stack.
+ limited_stack<UndoElement> redostack;
+
+ /// The flag used by Undo::finishUndo().
+ bool undo_finished;
+};
+
+
+Undo::Undo(Buffer & buffer): d(new Undo::Private(buffer))
+{
+}
+
+
+Undo::~Undo()
+{
+ delete d;
+}