+struct UndoElement
+{
+ ///
+ UndoElement(UndoKind kin, StableDocIterator const & cur,
+ StableDocIterator const & cel,
+ pit_type fro, pit_type en, ParagraphList * pl,
+ MathData * ar, BufferParams const & bp,
+ bool ifb, size_t gid) :
+ kind(kin), cursor(cur), cell(cel), from(fro), end(en),
+ pars(pl), array(ar), bparams(0), isFullBuffer(ifb), group_id(gid)
+ {
+ if (isFullBuffer)
+ bparams = new BufferParams(bp);
+ }
+ ///
+ UndoElement(UndoElement const & ue)
+ {
+ kind = ue.kind;
+ cursor = ue.cursor;
+ cell = ue.cell;
+ from = ue.from;
+ end = ue.end;
+ pars = ue.pars;
+ array = ue.array;
+ bparams = ue.isFullBuffer
+ ? new BufferParams(*ue.bparams) : ue.bparams;
+ isFullBuffer = ue.isFullBuffer;
+ group_id = ue.group_id;
+ }
+ ///
+ ~UndoElement()
+ {
+ if (isFullBuffer)
+ delete bparams;
+ }
+ /// 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 const * bparams;
+ /// Only used in case of full backups
+ bool isFullBuffer;
+ /// the element's group id
+ size_t group_id;
+private:
+ /// Protect construction
+ UndoElement();
+};
+
+
+class UndoElementStack
+{
+public:
+ /// limit is the maximum size of the stack
+ UndoElementStack(size_t limit = 100) { limit_ = limit; }
+ /// limit is the maximum size of the stack
+ ~UndoElementStack() { clear(); }
+
+ /// Return the top element.
+ UndoElement & top() { return c_.front(); }
+
+ /// Pop and throw away the top element.
+ void pop() { c_.pop_front(); }
+
+ /// Return true if the stack is empty.
+ bool empty() const { return c_.empty(); }
+
+ /// Clear all elements, deleting them.
+ void clear() {
+ for (size_t i = 0; i != c_.size(); ++i) {
+ delete c_[i].array;
+ delete c_[i].pars;
+ }
+ c_.clear();
+ }