Permalink
Browse files

Add Undo Framework QML API

This commit introduces an initial implementation of a QML API for the
Undo Framework.

The QML plugin for this API exports three new QML elements: UndoStack,
UndoCommand and UndoPropertyCommand. The API for both the first and
the second are very similar to the QUndoStack and QUndoCommand C++
APIs. The thrid use the declarative nature of the QML elements to
undo/redo based on the values of a group of properties specified by
the user.

This commit also adds an example in 'examples/undo/quickundo' to show
how this API could be used.

Other patchs are expected soon to improve this API and also add more
examples/docs.

Change-Id: I9d290f514b360c721116c3937bd0e03d5f0eacbb
Reviewed-by: Anselmo L. S. Melo <anselmo.melo@openbossa.org>
  • Loading branch information...
1 parent bc6356e commit 31c80c4e522c438809f6081248f090eee7199a64 @luisgabriel luisgabriel committed with Anselmo L. S. Melo Mar 23, 2012
@@ -0,0 +1,20 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ property alias text: label.text
+ signal clicked()
+
+
+ width: 50
+ height: 50
+ Text {
+ id: label
+ anchors.centerIn: parent
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: root.clicked()
+ }
+}
@@ -0,0 +1,74 @@
+import QtQuick 2.0
+import Playground.UiHelpers.UndoFramework 1.0
+
+Rectangle {
+ id: root
+
+ width: 800
+ height: 600
+
+ UndoStack {
+ id: stack
+ }
+
+ UndoPropertyCommand {
+ id: moveCommand
+ properties: ["x", "y"]
+ }
+
+ UndoCommand {
+ id: colorCommand
+ onUndo: target.color = Qt.rgba(0, 0, 0, 1);
+ onRedo: target.color = Qt.rgba(0.5, 0.2, 0.1, 1);
+ onCommandDestroyed: console.log("Command destroyed!");
+ }
+
+ Row {
+ anchors {
+ right: parent.right
+ top: parent.top
+ margins: 20
+ }
+ spacing: 20
+
+ Button {
+ color: "red"
+ width: 100
+ text: "Change color"
+ onClicked: stack.push(colorCommand, rec);
+ }
+ Button {
+ color: "blue"
+ text: "Undo"
+ onClicked: stack.undo();
+ }
+ Button {
+ color: "green"
+ text: "Redo"
+ onClicked: stack.redo();
+ }
+ }
+
+ Rectangle {
+ id: rec
+
+ x: 20
+ y: 50
+ width: 50
+ height: 50
+ color: "black"
+
+ Drag.active: dragArea.drag.active
+ Drag.hotSpot.x: 10
+ Drag.hotSpot.y: 10
+
+ MouseArea {
+ id: dragArea
+
+ anchors.fill: parent
+ drag.target: parent
+
+ onPressed: stack.push(moveCommand, parent);
+ }
+ }
+}
@@ -0,0 +1,16 @@
+import QmlProject 1.0
+
+Project {
+ /* Include .qml, .js, and image files from current directory and subdirectories */
+ QmlFiles {
+ directory: ""
+ }
+ JavaScriptFiles {
+ directory: ""
+ }
+ ImageFiles {
+ directory: ""
+ }
+ /* List of plugin directories passed to QML runtime */
+ //importPaths: [ "../../../src/imports/undo/" ]
+}
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+
+SUBDIRS += undo
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the UiHelpers playground module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtQml/qqmlextensionplugin.h>
+
+#include "uiquickundostack_p.h"
+#include "uiquickundocommands_p.h"
+
+
+class QmlUndoFrameworkPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+
+public:
+ virtual void registerTypes(const char* uri);
+};
+
+void QmlUndoFrameworkPlugin::registerTypes(const char* uri)
+{
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("Playground.UiHelpers.UndoFramework"));
+
+ qmlRegisterType<UiQuickUndoStack>(uri, 1, 0, "UndoStack");
+ qmlRegisterUncreatableType<UiQuickBaseUndoCommand>(uri, 1, 0, "", "");
+ qmlRegisterType<UiQuickUndoCommand>(uri, 1, 0, "UndoCommand");
+ qmlRegisterType<UiQuickUndoPropertyCommand>(uri, 1, 0, "UndoPropertyCommand");
+}
+
+#include "plugin.moc"
+
+Q_EXPORT_PLUGIN2(qmlundoframeworkplugin, QT_PREPEND_NAMESPACE(QmlUndoFrameworkPlugin))
@@ -0,0 +1 @@
+plugin qmlundoframeworkplugin
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the UiHelpers playground module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "uiquickundocommands_p.h"
+
+
+UiQuickBaseUndoCommand::UiQuickBaseUndoCommand(QObject *parent)
+ : QObject(parent)
+{
+}
+
+UiQuickBaseUndoCommand::~UiQuickBaseUndoCommand()
+{
+}
+
+UiQuickUndoCommand::UiQuickUndoCommand(QObject *parent)
+ : UiQuickBaseUndoCommand(parent)
+{
+}
+
+UiQuickUndoCommand::~UiQuickUndoCommand()
+{
+}
+
+UndoCommand::UndoCommand(QObject* target, UiQuickUndoCommand *qmlObject)
+ : UiUndoCommand()
+ , m_target(target)
+ , m_qmlObject(qmlObject)
+{
+}
+
+UndoCommand::~UndoCommand()
+{
+ emit m_qmlObject->commandDestroyed(m_target);
+}
+
+void UndoCommand::undo()
+{
+ emit m_qmlObject->undo(m_target);
+}
+
+void UndoCommand::redo()
+{
+ emit m_qmlObject->redo(m_target);
+}
+
+// --------------------------------- //
+
+UiQuickUndoPropertyCommand::UiQuickUndoPropertyCommand(QObject *parent)
+ : UiQuickBaseUndoCommand(parent)
+ , m_properties(QVariantList())
+{
+}
+
+UiQuickUndoPropertyCommand::~UiQuickUndoPropertyCommand()
+{
+}
+
+QVariantList UiQuickUndoPropertyCommand::properties() const
+{
+ return m_properties;
+}
+
+void UiQuickUndoPropertyCommand::setProperties(const QVariantList& prop)
+{
+ m_properties = prop;
+ emit propertiesChanged();
+}
+
+UndoPropertyCommand::UndoPropertyCommand(QObject* t, UiQuickUndoPropertyCommand *q)
+ : UiUndoCommand()
+ , m_undoState(TargetState())
+ , m_redoState(TargetState())
+ , m_target(t)
+ , m_qmlObject(q)
+{
+ saveState(m_undoState);
+}
+
+UndoPropertyCommand::~UndoPropertyCommand()
+{
+}
+
+void UndoPropertyCommand::saveState(TargetState& state)
+{
+ foreach (const QVariant& var, m_qmlObject->properties()) {
+ QByteArray propertyName = var.toByteArray();
+ state.append(qMakePair(propertyName, m_target->property(propertyName.data())));
+ }
+}
+
+void UndoPropertyCommand::applyState(TargetState& state)
+{
+ foreach (PropertyState pair, state)
+ m_target->setProperty(pair.first, pair.second);
+}
+
+void UndoPropertyCommand::undo()
+{
+ applyState(m_undoState);
+}
+
+void UndoPropertyCommand::redo()
+{
+ if (m_redoState.empty())
+ saveState(m_redoState);
+ else
+ applyState(m_redoState);
+}
Oops, something went wrong.

0 comments on commit 31c80c4

Please sign in to comment.