diff --git a/tools/designer/src/components/formeditor/formeditor.pri b/tools/designer/src/components/formeditor/formeditor.pri
index bbe96d5..b1a9318 100644
--- a/tools/designer/src/components/formeditor/formeditor.pri
+++ b/tools/designer/src/components/formeditor/formeditor.pri
@@ -8,6 +8,7 @@ FORMS +=   $$PWD/deviceprofiledialog.ui \
            $$PWD/templateoptionspage.ui
 
 HEADERS += $$PWD/qdesigner_resource.h \
+           $$PWD/qdesignerundostack.h \
            $$PWD/formwindow.h \
            $$PWD/formwindow_widgetstack.h \
            $$PWD/formwindow_dnditem.h \
@@ -41,6 +42,7 @@ HEADERS += $$PWD/qdesigner_resource.h \
            $$PWD/templateoptionspage.h
 
 SOURCES += $$PWD/qdesigner_resource.cpp \
+           $$PWD/qdesignerundostack.cpp \
            $$PWD/formwindow.cpp \
            $$PWD/formwindow_widgetstack.cpp \
            $$PWD/formwindow_dnditem.cpp \
diff --git a/tools/designer/src/components/formeditor/formwindow.cpp b/tools/designer/src/components/formeditor/formwindow.cpp
index 3a7cd83..b1b02b8 100644
--- a/tools/designer/src/components/formeditor/formwindow.cpp
+++ b/tools/designer/src/components/formeditor/formwindow.cpp
@@ -399,8 +399,7 @@ void FormWindow::setCursorToAll(const QCursor &c, QWidget *start)
 void FormWindow::init()
 {
     if (FormWindowManager *manager = qobject_cast<FormWindowManager*> (core()->formWindowManager())) {
-        m_commandHistory = new QUndoStack(this);
-        manager->undoGroup()->addStack(m_commandHistory);
+        manager->undoGroup()->addStack(m_undoStack.qundoStack());
     }
 
     m_blockSelectionChanged = false;
@@ -429,9 +428,8 @@ void FormWindow::init()
     m_mainContainer = 0;
     m_currentWidget = 0;
 
-    connect(m_commandHistory, SIGNAL(indexChanged(int)), this, SLOT(updateDirty()));
-    connect(m_commandHistory, SIGNAL(indexChanged(int)), this, SIGNAL(changed()));
-    connect(m_commandHistory, SIGNAL(indexChanged(int)), this, SLOT(checkSelection()));
+    connect(&m_undoStack, SIGNAL(changed()), this, SIGNAL(changed()));
+    connect(&m_undoStack, SIGNAL(changed()), this, SLOT(checkSelection()));
 
     core()->metaDataBase()->add(this);
 
@@ -1227,14 +1225,14 @@ void FormWindow::insertWidget(QWidget *w, const QRect &rect, QWidget *container,
     if (w->parentWidget() != container) {
         ReparentWidgetCommand *cmd = new ReparentWidgetCommand(this);
         cmd->init(w, container);
-        m_commandHistory->push(cmd);
+        m_undoStack.push(cmd);
     }
 
-    m_commandHistory->push(geom_cmd);
+    m_undoStack.push(geom_cmd);
 
     InsertWidgetCommand *cmd = new InsertWidgetCommand(this);
     cmd->init(w, already_in_form);
-    m_commandHistory->push(cmd);
+    m_undoStack.push(cmd);
 
     endCommand();
 
@@ -1277,12 +1275,10 @@ void FormWindow::resizeWidget(QWidget *widget, const QRect &geometry)
     Q_ASSERT(isDescendant(this, widget));
 
     QRect r = geometry;
-    if (m_lastIndex > m_commandHistory->index())
-        m_lastIndex = -1;
     SetPropertyCommand *cmd = new SetPropertyCommand(this);
     cmd->init(widget, QLatin1String("geometry"), r);
     cmd->setText(tr("Resize"));
-    m_commandHistory->push(cmd);
+    m_undoStack.push(cmd);
 }
 
 void FormWindow::raiseChildSelections(QWidget *w)
@@ -1485,7 +1481,7 @@ void FormWindow::handleArrowKeyEvent(int key, Qt::KeyboardModifiers modifiers)
     const int selCount = selection.count();
     // check if selection is the same as last time
     if (selCount != m_moveSelection.count() ||
-        m_lastUndoIndex != m_commandHistory->index()) {
+        m_lastUndoIndex != m_undoStack.index()) {
         m_moveSelection.clear();
         startMacro = true;
     } else {
@@ -1515,7 +1511,7 @@ void FormWindow::handleArrowKeyEvent(int key, Qt::KeyboardModifiers modifiers)
             cmd = new SetPropertyCommand(this);
             cmd->init(w, QLatin1String("geometry"), geom);
             cmd->setText(tr("Key Move"));
-            m_commandHistory->push(cmd);
+            m_undoStack.push(cmd);
 
             if (m_moveSelection.count() > index)
                 m_moveSelection.replace(index, cmd);
@@ -1529,7 +1525,7 @@ void FormWindow::handleArrowKeyEvent(int key, Qt::KeyboardModifiers modifiers)
 
     if (startMacro) {
         endCommand();
-        m_lastUndoIndex = m_commandHistory->index();
+        m_lastUndoIndex = m_undoStack.index();
     }
 }
 
@@ -1809,7 +1805,7 @@ void FormWindow::paste(PasteMode pasteMode)
             foreach (QWidget *w, clipboard.m_widgets) {
                 InsertWidgetCommand *cmd = new InsertWidgetCommand(this);
                 cmd->init(w);
-                m_commandHistory->push(cmd);
+                m_undoStack.push(cmd);
                 selectWidget(w);
             }
         }
@@ -1819,7 +1815,7 @@ void FormWindow::paste(PasteMode pasteMode)
                 ensureUniqueObjectName(a);
                 AddActionCommand *cmd = new AddActionCommand(this);
                 cmd->init(a);
-                m_commandHistory->push(cmd);
+                m_undoStack.push(cmd);
             }
         endCommand();
     } while (false);
@@ -1955,14 +1951,12 @@ void FormWindow::breakLayout(QWidget *w)
 
 void FormWindow::beginCommand(const QString &description)
 {
-    if (m_lastIndex > m_commandHistory->index())
-        m_lastIndex = -1;
-    m_commandHistory->beginMacro(description);
+    m_undoStack.beginMacro(description);
 }
 
 void FormWindow::endCommand()
 {
-    m_commandHistory->endMacro();
+    m_undoStack.endMacro();
 }
 
 void FormWindow::raiseWidgets()
@@ -1977,7 +1971,7 @@ void FormWindow::raiseWidgets()
     foreach (QWidget *widget, widgets) {
         RaiseWidgetCommand *cmd = new RaiseWidgetCommand(this);
         cmd->init(widget);
-        m_commandHistory->push(cmd);
+        m_undoStack.push(cmd);
     }
     endCommand();
 }
@@ -1994,7 +1988,7 @@ void FormWindow::lowerWidgets()
     foreach (QWidget *widget, widgets) {
         LowerWidgetCommand *cmd = new LowerWidgetCommand(this);
         cmd->init(widget);
-        m_commandHistory->push(cmd);
+        m_undoStack.push(cmd);
     }
     endCommand();
 }
@@ -2375,20 +2369,12 @@ FormWindow *FormWindow::findFormWindow(QWidget *w)
 
 bool FormWindow::isDirty() const
 {
-    return m_dirty;
+    return m_undoStack.isDirty();
 }
 
 void FormWindow::setDirty(bool dirty)
 {
-    m_dirty = dirty;
-
-    if (!m_dirty)
-        m_lastIndex = m_commandHistory->index();
-}
-
-void FormWindow::updateDirty()
-{
-    m_dirty = m_commandHistory->index() != m_lastIndex;
+    m_undoStack.setDirty(dirty);
 }
 
 QWidget *FormWindow::containerAt(const QPoint &pos)
@@ -2757,7 +2743,7 @@ bool FormWindow::dropDockWidget(QDesignerDnDItemInterface *item, const QPoint &g
         qVariantSetValue(v, e);
         SetPropertyCommand *cmd = new SetPropertyCommand(this);
         cmd->init(widget, dockWidgetAreaName, v);
-        m_commandHistory->push(cmd);
+        m_undoStack.push(cmd);
     }
 
     endCommand();
@@ -2921,6 +2907,11 @@ QWidget *FormWindow::formContainer() const
     return m_widgetStack->formContainer();
 }
 
+QUndoStack *FormWindow::commandHistory() const
+{
+    return const_cast<QDesignerUndoStack &>(m_undoStack).qundoStack();
+}
+
 } // namespace
 
 QT_END_NAMESPACE
diff --git a/tools/designer/src/components/formeditor/formwindow.h b/tools/designer/src/components/formeditor/formwindow.h
index 3eee476..cf5d2de 100644
--- a/tools/designer/src/components/formeditor/formwindow.h
+++ b/tools/designer/src/components/formeditor/formwindow.h
@@ -43,6 +43,7 @@
 #define FORMWINDOW_H
 
 #include "formeditor_global.h"
+#include "qdesignerundostack.h"
 #include <formwindowbase_p.h>
 
 // Qt
@@ -64,7 +65,6 @@ class QLabel;
 class QTimer;
 class QAction;
 class QMenu;
-class QUndoStack;
 class QRubberBand;
 
 namespace qdesigner_internal {
@@ -76,6 +76,7 @@ class FormWindowWidgetStack;
 class FormWindowManager;
 class FormWindowDnDItem;
 class SetPropertyCommand;
+class QDesignerUndoStack;
 
 class QT_FORMEDITOR_EXPORT FormWindow: public FormWindowBase
 {
@@ -165,9 +166,7 @@ public:
     void manageWidget(QWidget *w);
     void unmanageWidget(QWidget *w);
 
-    inline QUndoStack *commandHistory() const
-    { return m_commandHistory; }
-
+    virtual QUndoStack *commandHistory() const;
     void beginCommand(const QString &description);
     void endCommand();
 
@@ -238,7 +237,6 @@ protected:
 
 private slots:
     void selectionChangedTimerDone();
-    void updateDirty();
     void checkSelection();
     void checkSelectionNow();
     void slotSelectWidget(QAction *);
@@ -338,7 +336,7 @@ private:
 
     QPoint m_startPos;
 
-    QUndoStack *m_commandHistory;
+    QDesignerUndoStack m_undoStack;
 
     QString m_fileName;
 
@@ -352,9 +350,6 @@ private:
     QTimer *m_checkSelectionTimer;
     QTimer *m_geometryChangedTimer;
 
-    int m_dirty;
-    int m_lastIndex;
-
     FormWindowWidgetStack *m_widgetStack;
     WidgetEditorTool *m_widgetEditor;
 
