diff options
author | Friedemann Kleint <Friedemann.Kleint@nokia.com> | 2010-02-16 13:19:53 (GMT) |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@nokia.com> | 2010-02-16 13:19:53 (GMT) |
commit | f36b0cb1ecdfd0cda6537bdd3acf47eb216db49f (patch) | |
tree | 4ba9dde2eaabfa03bd2e27fa58d19d9f8267814a /tools/designer/src/components/formeditor | |
parent | 329148df0bdbf7e66c2ba0f6608eb49658f5f2c1 (diff) | |
download | Qt-f36b0cb1ecdfd0cda6537bdd3acf47eb216db49f.zip Qt-f36b0cb1ecdfd0cda6537bdd3acf47eb216db49f.tar.gz Qt-f36b0cb1ecdfd0cda6537bdd3acf47eb216db49f.tar.bz2 |
Designer: Implement isDirty()-handling using a QUndoStack.
Remove Designer-specific handling of isDirty() due to its
bug-proneness, use instead an extended QUndoStack.that allows
for setting to 'dirty' without commands for some special cases.
Task-number: QTBUG-8041
Diffstat (limited to 'tools/designer/src/components/formeditor')
5 files changed, 225 insertions, 40 deletions
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 8b8351d..ccb1984 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) @@ -1584,7 +1580,7 @@ void FormWindow::handleArrowKeyEvent(int key, Qt::KeyboardModifiers modifiers) ArrowKeyPropertyCommand *cmd = new ArrowKeyPropertyCommand(this); cmd->init(selection, operation); - m_commandHistory->push(cmd); + m_undoStack.push(cmd); } bool FormWindow::handleKeyReleaseEvent(QWidget *, QWidget *, QKeyEvent *e) @@ -1863,7 +1859,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); } } @@ -1873,7 +1869,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); @@ -2009,14 +2005,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() @@ -2031,7 +2025,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(); } @@ -2048,7 +2042,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(); } @@ -2429,20 +2423,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) @@ -2811,7 +2797,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(); @@ -2975,6 +2961,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 1b2916c..06f60b5 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 *); @@ -337,7 +335,7 @@ private: QPoint m_startPos; - QUndoStack *m_commandHistory; + QDesignerUndoStack m_undoStack; QString m_fileName; @@ -351,9 +349,6 @@ private: QTimer *m_checkSelectionTimer; QTimer *m_geometryChangedTimer; - int m_dirty; - int m_lastIndex; - FormWindowWidgetStack *m_widgetStack; WidgetEditorTool *m_widgetEditor; diff --git a/tools/designer/src/components/formeditor/qdesignerundostack.cpp b/tools/designer/src/components/formeditor/qdesignerundostack.cpp new file mode 100644 index 0000000..6996bcd --- /dev/null +++ b/tools/designer/src/components/formeditor/qdesignerundostack.cpp @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Designer of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdesignerundostack.h" + +#include <QtGui/QUndoStack> +#include <QtGui/QUndoCommand> + +namespace qdesigner_internal { + +QDesignerUndoStack::QDesignerUndoStack(QObject *parent) : + QObject(parent), + m_undoStack(new QUndoStack), + m_fakeDirty(false) +{ + connect(m_undoStack, SIGNAL(indexChanged(int)), this, SIGNAL(changed())); +} + +QDesignerUndoStack::~QDesignerUndoStack() +{ // QUndoStack is managed by the QUndoGroup +} + +void QDesignerUndoStack::push(QUndoCommand * cmd) +{ + m_undoStack->push(cmd); +} + +void QDesignerUndoStack::beginMacro(const QString &text) +{ + m_undoStack->beginMacro(text); +} + +void QDesignerUndoStack::endMacro() +{ + m_undoStack->endMacro(); +} + +int QDesignerUndoStack::index() const +{ + return m_undoStack->index(); +} + +const QUndoStack *QDesignerUndoStack::qundoStack() const +{ + return m_undoStack; +} +QUndoStack *QDesignerUndoStack::qundoStack() +{ + return m_undoStack; +} + +bool QDesignerUndoStack::isDirty() const +{ + return m_fakeDirty || !m_undoStack->isClean(); +} + +void QDesignerUndoStack::setDirty(bool v) +{ + if (isDirty() == v) + return; + if (v) { + m_fakeDirty = true; + emit changed(); + } else { + m_fakeDirty = false; + m_undoStack->setClean(); + } +} + +} // namespace qdesigner_internal diff --git a/tools/designer/src/components/formeditor/qdesignerundostack.h b/tools/designer/src/components/formeditor/qdesignerundostack.h new file mode 100644 index 0000000..b1b3389 --- /dev/null +++ b/tools/designer/src/components/formeditor/qdesignerundostack.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Designer of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDESIGNERUNDOSTACK_H +#define QDESIGNERUNDOSTACK_H + +#include <QtCore/QObject> + +QT_BEGIN_NAMESPACE +class QUndoStack; +class QUndoCommand; +QT_END_NAMESPACE + +namespace qdesigner_internal { + +/* QDesignerUndoStack: A QUndoStack extended by a way of setting it to + * "dirty" indepently of commands (by modifications without commands + * such as resizing). Accomplished via bool m_fakeDirty flag. The + * lifecycle of the QUndoStack is managed by the QUndoGroup. */ +class QDesignerUndoStack : public QObject +{ + Q_DISABLE_COPY(QDesignerUndoStack) + Q_OBJECT +public: + explicit QDesignerUndoStack(QObject *parent = 0); + virtual ~QDesignerUndoStack(); + + void push(QUndoCommand * cmd); + void beginMacro(const QString &text); + void endMacro(); + int index() const; + + const QUndoStack *qundoStack() const; + QUndoStack *qundoStack(); + + bool isDirty() const; + +signals: + void changed(); + +public slots: + void setDirty(bool); + +private: + QUndoStack *m_undoStack; + bool m_fakeDirty; +}; + +} // namespace qdesigner_internal + +#endif // QDESIGNERUNDOSTACK_H |