From 54290ef776a311f0c303e2a8df4de5e39e9a032a Mon Sep 17 00:00:00 2001
From: Erik Verbruggen <erik.verbruggen@nokia.com>
Date: Tue, 9 Feb 2010 14:30:08 +0100
Subject: Added method to clear the undo/redo stacks.

Reviewed-by: mae
---
 src/gui/text/qtextdocument.cpp   | 17 +++++++++++
 src/gui/text/qtextdocument.h     |  7 +++++
 src/gui/text/qtextdocument_p.cpp | 62 ++++++++++++++++++++++++++--------------
 src/gui/text/qtextdocument_p.h   |  3 +-
 4 files changed, 67 insertions(+), 22 deletions(-)

diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index b8c9b94..80931c9 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -436,6 +436,23 @@ void QTextDocument::redo(QTextCursor *cursor)
 }
 
 /*!
+    \since 4.7
+    Clears the specified stacks.
+
+    This method clears any commands on the undo stack, the redo stack, or both (the
+    default). If any commands got cleared, the appropriate signals
+    (\a QTextDocument::undoAvailable or \a QTextDocument::redoAvailable) get
+    emitted.
+
+    \sa QTextDocument::undoAvailable QTextDocument::redoAvailable
+*/
+void QTextDocument::clearUndoRedoStacks(Stacks stacksToClear)
+{
+    Q_D(QTextDocument);
+    d->clearUndoRedoStacks(stacksToClear, true);
+}
+
+/*!
     \overload
 
 */
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index b5bcb41..0140772 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -256,6 +256,13 @@ public:
     void undo(QTextCursor *cursor);
     void redo(QTextCursor *cursor);
 
+    enum Stacks {
+        UndoStack = 0x01,
+        RedoStack = 0x02,
+        UndoAndRedoStacks = UndoStack | RedoStack
+    };
+    void clearUndoRedoStacks(Stacks historyToClear = UndoAndRedoStacks);
+
     int maximumBlockCount() const;
     void setMaximumBlockCount(int maximum);
 
diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp
index 372b9dc..b36642b 100644
--- a/src/gui/text/qtextdocument_p.cpp
+++ b/src/gui/text/qtextdocument_p.cpp
@@ -260,7 +260,7 @@ void QTextDocumentPrivate::clear()
 
         title.clear();
         undoState = 0;
-        truncateUndoStack();
+        clearUndoRedoStacks(QTextDocument::UndoStack);
         text = QString();
         unreachableCharacterCount = 0;
         modifiedState = 0;
@@ -292,7 +292,7 @@ QTextDocumentPrivate::~QTextDocumentPrivate()
     cursors.clear();
     undoState = 0;
     undoEnabled = true;
-    truncateUndoStack();
+    clearUndoRedoStacks(QTextDocument::UndoStack);
 }
 
 void QTextDocumentPrivate::setLayout(QAbstractTextDocumentLayout *layout)
@@ -1027,7 +1027,7 @@ void QTextDocumentPrivate::appendUndoItem(const QTextUndoCommand &c)
     if (!undoEnabled)
         return;
     if (undoState < undoStack.size())
-        truncateUndoStack();
+        clearUndoRedoStacks(QTextDocument::UndoStack);
 
     if (!undoStack.isEmpty() && modified) {
         QTextUndoCommand &last = undoStack[undoState - 1];
@@ -1050,26 +1050,46 @@ void QTextDocumentPrivate::appendUndoItem(const QTextUndoCommand &c)
         emit document()->undoCommandAdded();
 }
 
-void QTextDocumentPrivate::truncateUndoStack()
+void QTextDocumentPrivate::clearUndoRedoStacks(QTextDocument::Stacks stacksToClear,
+                                               bool emitSignals)
 {
-    if (undoState == undoStack.size())
-        return;
-
-    for (int i = undoState; i < undoStack.size(); ++i) {
-        QTextUndoCommand c = undoStack[i];
-        if (c.command & QTextUndoCommand::Removed) {
-            // ########
-//             QTextFragment *f = c.fragment_list;
-//             while (f) {
-//                 QTextFragment *n = f->right;
-//                 delete f;
-//                 f = n;
-//             }
-        } else if (c.command & QTextUndoCommand::Custom) {
-            delete c.custom;
+    bool undoCommandsAvailable = undoState != 0;
+    bool redoCommandsAvailable = undoState != undoStack.size();
+    if (stacksToClear == QTextDocument::UndoStack && undoCommandsAvailable) {
+        for (int i = 0; i < undoState; ++i) {
+            QTextUndoCommand c = undoStack[undoState];
+            if (c.command & QTextUndoCommand::Custom)
+                delete c.custom;
+        }
+        undoStack.remove(0, undoState);
+        undoStack.resize(undoStack.size() - undoState);
+        undoState = 0;
+        if (emitSignals)
+            emitUndoAvailable(false);
+    } else if (stacksToClear == QTextDocument::RedoStack
+               && redoCommandsAvailable) {
+        for (int i = undoState; i < undoStack.size(); ++i) {
+            QTextUndoCommand c = undoStack[i];
+            if (c.command & QTextUndoCommand::Custom)
+                delete c.custom;
+        }
+        undoStack.resize(undoState);
+        if (emitSignals)
+            emitRedoAvailable(false);
+    } else if (stacksToClear == QTextDocument::UndoAndRedoStacks
+               && (undoCommandsAvailable || redoCommandsAvailable)) {
+        for (int i = 0; i < undoStack.size(); ++i) {
+            QTextUndoCommand c = undoStack[i];
+            if (c.command & QTextUndoCommand::Custom)
+                delete c.custom;
         }
+        undoState = 0;
+        undoStack.resize(0);
+        if (emitSignals && undoCommandsAvailable)
+            emitUndoAvailable(false);
+        if (emitSignals && redoCommandsAvailable)
+            emitRedoAvailable(false);
     }
-    undoStack.resize(undoState);
 }
 
 void QTextDocumentPrivate::emitUndoAvailable(bool available)
@@ -1097,7 +1117,7 @@ void QTextDocumentPrivate::enableUndoRedo(bool enable)
 
     if (!enable) {
         undoState = 0;
-        truncateUndoStack();
+        clearUndoRedoStacks(QTextDocument::UndoStack);
         emitUndoAvailable(false);
         emitRedoAvailable(false);
     }
diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h
index 4ecc2fa..ac5ed3c 100644
--- a/src/gui/text/qtextdocument_p.h
+++ b/src/gui/text/qtextdocument_p.h
@@ -252,10 +252,11 @@ public:
     inline QFont defaultFont() const { return formats.defaultFont(); }
     inline void setDefaultFont(const QFont &f) { formats.setDefaultFont(f); }
 
+    void clearUndoRedoStacks(QTextDocument::Stacks stacksToClear, bool emitSignals = false);
+
 private:
     bool split(int pos);
     bool unite(uint f);
-    void truncateUndoStack();
 
     void insert_string(int pos, uint strPos, uint length, int format, QTextUndoCommand::Operation op);
     int insert_block(int pos, uint strPos, int format, int blockformat, QTextUndoCommand::Operation op, int command);
-- 
cgit v0.12