summaryrefslogtreecommitdiffstats
path: root/src/declarative/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/util')
-rw-r--r--src/declarative/util/qbindablemap.cpp179
-rw-r--r--src/declarative/util/qbindablemap.h87
-rw-r--r--src/declarative/util/qfxglobal.h124
-rw-r--r--src/declarative/util/qfxperf.cpp75
-rw-r--r--src/declarative/util/qfxperf.h87
-rw-r--r--src/declarative/util/qfxview.cpp310
-rw-r--r--src/declarative/util/qfxview.h107
-rw-r--r--src/declarative/util/qmlanimation.cpp2292
-rw-r--r--src/declarative/util/qmlanimation.h453
-rw-r--r--src/declarative/util/qmlanimation_p.h374
-rw-r--r--src/declarative/util/qmlbehaviour.cpp248
-rw-r--r--src/declarative/util/qmlbehaviour.h99
-rw-r--r--src/declarative/util/qmlbind.cpp203
-rw-r--r--src/declarative/util/qmlbind.h89
-rw-r--r--src/declarative/util/qmlconnection.cpp290
-rw-r--r--src/declarative/util/qmlconnection.h91
-rw-r--r--src/declarative/util/qmldatetimeformatter.cpp368
-rw-r--r--src/declarative/util/qmldatetimeformatter.h116
-rw-r--r--src/declarative/util/qmlfollow.cpp309
-rw-r--r--src/declarative/util/qmlfollow.h94
-rw-r--r--src/declarative/util/qmlfont.cpp147
-rw-r--r--src/declarative/util/qmlfont.h92
-rw-r--r--src/declarative/util/qmllistaccessor.cpp243
-rw-r--r--src/declarative/util/qmllistaccessor.h82
-rw-r--r--src/declarative/util/qmllistmodel.cpp721
-rw-r--r--src/declarative/util/qmllistmodel.h96
-rw-r--r--src/declarative/util/qmlnullablevalue_p.h67
-rw-r--r--src/declarative/util/qmlopenmetaobject.cpp188
-rw-r--r--src/declarative/util/qmlopenmetaobject.h96
-rw-r--r--src/declarative/util/qmlpackage.cpp148
-rw-r--r--src/declarative/util/qmlpackage.h86
-rw-r--r--src/declarative/util/qmlscript.cpp219
-rw-r--r--src/declarative/util/qmlscript.h80
-rw-r--r--src/declarative/util/qmlsetproperties.cpp247
-rw-r--r--src/declarative/util/qmlsetproperties.h83
-rw-r--r--src/declarative/util/qmlstate.cpp469
-rw-r--r--src/declarative/util/qmlstate.h175
-rw-r--r--src/declarative/util/qmlstate_p.h77
-rw-r--r--src/declarative/util/qmlstategroup.cpp306
-rw-r--r--src/declarative/util/qmlstategroup.h95
-rw-r--r--src/declarative/util/qmlstateoperations.cpp416
-rw-r--r--src/declarative/util/qmlstateoperations.h132
-rw-r--r--src/declarative/util/qmltransition.cpp283
-rw-r--r--src/declarative/util/qmltransition.h98
-rw-r--r--src/declarative/util/qperformancelog.cpp177
-rw-r--r--src/declarative/util/qperformancelog.h176
-rw-r--r--src/declarative/util/util.pri49
47 files changed, 11043 insertions, 0 deletions
diff --git a/src/declarative/util/qbindablemap.cpp b/src/declarative/util/qbindablemap.cpp
new file mode 100644
index 0000000..aea2a2c
--- /dev/null
+++ b/src/declarative/util/qbindablemap.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbindablemap.h"
+#include <qmlopenmetaobject.h>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+//QBindableMapMetaObject lets us listen for changes coming from QML
+//so we can emit the changed signal.
+class QBindableMapMetaObject : public QmlOpenMetaObject
+{
+public:
+ QBindableMapMetaObject(QBindableMap *obj) : QmlOpenMetaObject(obj)
+ {
+ map = obj;
+ }
+
+protected:
+ virtual void propertyWrite(int index)
+ {
+ map->emitChanged(QLatin1String(name(index)));
+ }
+
+private:
+ QBindableMap *map;
+};
+
+/*!
+ \class QBindableMap
+ \brief The QBindableMap class allows you to set key-value pairs that can be used in bindings.
+
+ QBindableMap provides a convenient way to expose domain data to the UI layer.
+ The following example shows how you might declare data in C++ and then
+ access it in QML.
+
+ Setup in C++:
+ \code
+ //create our data
+ QBindableMap ownerData;
+ ownerData.setValue("name", QVariant(QString("John Smith")));
+ ownerData.setValue("phone", QVariant(QString("555-5555")));
+
+ //expose it to the UI layer
+ QmlContext *ctxt = view->bindContext();
+ ctxt->setProperty("owner", &data);
+ \endcode
+
+ Then, in QML:
+ \code
+ <Text text="{owner.name}"/>
+ <Text text="{owner.phone}"/>
+ \endcode
+
+ The binding is dynamic - whenever a key's value is updated, anything bound to that
+ key will be updated as well.
+
+ To detect value changes made in the UI layer you can connect to the changed() signal.
+ However, note that changed() is \b NOT emitted when changes are made by calling setValue()
+ or clearValue() - it is only emitted when a value is updated from QML.
+*/
+
+// is there a more efficient way to store/return keys?
+// (or should we just provide an iterator or something else instead?)
+// can we provide a way to clear keys?
+// do we want to make any claims regarding key ordering?
+// should we have signals for insertion and and deletion -- becoming more model like
+// should we emit change for our own changes as well?
+// Bug or Feature?: values can be created in QML (owner.somethingElse = "Hello") will create somethingElse property. (need to verify if this is actually the case)
+// Bug or Feature?: all values are read-write (there are no read-only values)
+
+/*!
+ Constructs a bindable map with parent object \a parent.
+*/
+QBindableMap::QBindableMap(QObject *parent)
+: QObject(parent)
+{
+ m_mo = new QBindableMapMetaObject(this);
+}
+
+QBindableMap::~QBindableMap()
+{
+}
+
+/*!
+ Clears the value (if any) associated with \a key.
+*/
+void QBindableMap::clearValue(const QString &key)
+{
+ //m_keys.remove(); //###
+ m_mo->setValue(key.toLatin1(), QVariant());
+ //emit changed(key);
+}
+
+/*!
+ Returns the value associated with \a key.
+
+ If no value has been set for this key (or if the value has been cleared),
+ an invalid QVariant is returned.
+*/
+QVariant QBindableMap::value(const QString &key) const
+{
+ return m_mo->value(key.toLatin1());
+}
+
+/*!
+ Sets the value associated with \a key to \a value.
+
+ If the key doesn't exist, it is automatically created.
+*/
+void QBindableMap::setValue(const QString &key, QVariant value)
+{
+ if (!m_keys.contains(key))
+ m_keys.append(key);
+ m_mo->setValue(key.toLatin1(), value);
+ //emit changed(key);
+}
+
+/*!
+ Returns the list of keys.
+
+ Keys that have been cleared will still appear in this list, even though their
+ associated values are invalid QVariants.
+*/
+QStringList QBindableMap::keys() const
+{
+ return m_keys;
+}
+
+/*!
+ \fn void QBindableMap::changed(const QString &key)
+ This signal is emitted whenever one of the values in the map is changed. \a key
+ is the key corresponding to the value that was changed.
+ */
+
+void QBindableMap::emitChanged(const QString &key)
+{
+ emit changed(key);
+}
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qbindablemap.h b/src/declarative/util/qbindablemap.h
new file mode 100644
index 0000000..d617867
--- /dev/null
+++ b/src/declarative/util/qbindablemap.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBINDABLEMAP_H
+#define QBINDABLEMAP_H
+
+#include <qfxglobal.h>
+#include <QObject>
+#include <QHash>
+#include <QStringList>
+#include <QVariant>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QBindableMapMetaObject;
+class Q_DECLARATIVE_EXPORT QBindableMap : public QObject
+{
+ Q_OBJECT
+public:
+ QBindableMap(QObject *parent = 0);
+ virtual ~QBindableMap();
+
+ QVariant value(const QString &key) const;
+ void setValue(const QString &key, QVariant value);
+ void clearValue(const QString &key);
+
+ Q_INVOKABLE QStringList keys() const;
+
+Q_SIGNALS:
+ void changed(const QString &key);
+
+private:
+ Q_DISABLE_COPY(QBindableMap)
+ void emitChanged(const QString &key);
+ QBindableMapMetaObject *m_mo;
+ QStringList m_keys;
+ friend class QBindableMapMetaObject;
+};
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+#endif
diff --git a/src/declarative/util/qfxglobal.h b/src/declarative/util/qfxglobal.h
new file mode 100644
index 0000000..52cf021
--- /dev/null
+++ b/src/declarative/util/qfxglobal.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFXGLOBAL_H
+#define QFXGLOBAL_H
+
+#include <qglobal.h>
+#include <QObject>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+#if defined(QT_OPENGL_ES_1)
+#define QFX_CONFIGURATION_OPENGL1
+#elif defined(QT_OPENGL_ES_2)
+#define QFX_CONFIGURATION_OPENGL2
+#else
+#define QFX_CONFIGURATION_SOFTWARE
+#endif
+
+/*
+ The choices of renderer are:
+ QFX_RENDER_QPAINTER
+ QFX_RENDER_OPENGL1
+ QFX_RENDER_OPENGL2
+ To simplify code, if either of the OpenGL renderers are used,
+ QFX_RENDER_OPENGL is also defined.
+*/
+
+#if defined(QFX_CONFIGURATION_OPENGL2)
+
+#define QFX_RENDER_OPENGL
+#define QFX_RENDER_OPENGL2
+
+#elif defined(QFX_CONFIGURATION_OPENGL1)
+
+#define QFX_RENDER_OPENGL
+#define QFX_RENDER_OPENGL1
+
+#elif defined(QFX_CONFIGURATION_SOFTWARE)
+
+#define QFX_RENDER_QPAINTER
+
+#endif
+
+#define DEFINE_BOOL_CONFIG_OPTION(name, var) \
+ static bool name() \
+ { \
+ static enum { Yes, No, Unknown } status = Unknown; \
+ if(status == Unknown) { \
+ QByteArray v = qgetenv(#var); \
+ bool value = !v.isEmpty() && v != "0" && v != "false"; \
+ if(value) status = Yes; \
+ else status = No; \
+ } \
+ return status == Yes; \
+ }
+
+struct QFx_DerivedObject : public QObject
+{
+ void setParent_noEvent(QObject *parent) {
+ bool sce = d_ptr->sendChildEvents;
+ d_ptr->sendChildEvents = false;
+ setParent(parent);
+ d_ptr->sendChildEvents = sce;
+ }
+};
+
+/*!
+ Makes the \a object a child of \a parent. Note that when using this method,
+ neither \a parent nor the object's previous parent (if it had one) will
+ receive ChildRemoved or ChildAdded events.
+*/
+inline void QFx_setParent_noEvent(QObject *object, QObject *parent)
+{
+ static_cast<QFx_DerivedObject *>(object)->setParent_noEvent(parent);
+}
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+#endif // QFXGLOBAL_H
diff --git a/src/declarative/util/qfxperf.cpp b/src/declarative/util/qfxperf.cpp
new file mode 100644
index 0000000..5ce8646
--- /dev/null
+++ b/src/declarative/util/qfxperf.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qfxperf.h"
+
+
+QT_BEGIN_NAMESPACE
+Q_DEFINE_PERFORMANCE_LOG(QFxPerf, "QFx") {
+ Q_DEFINE_PERFORMANCE_METRIC(XmlParsing, "XML Parsing");
+ Q_DEFINE_PERFORMANCE_METRIC(Compile, "XML Compilation");
+ Q_DEFINE_PERFORMANCE_METRIC(CompileRun, "XML Compilation Run");
+ Q_DEFINE_PERFORMANCE_METRIC(CssParsing, "CSS Parsing");
+ Q_DEFINE_PERFORMANCE_METRIC(CreateComponent, "Component creation");
+ Q_DEFINE_PERFORMANCE_METRIC(BindInit, "BindValue Initialization");
+ Q_DEFINE_PERFORMANCE_METRIC(BindCompile, "BindValue compile");
+ Q_DEFINE_PERFORMANCE_METRIC(BindValue, "BindValue execution");
+ Q_DEFINE_PERFORMANCE_METRIC(BindValueSSE, "BindValue execution SSE");
+ Q_DEFINE_PERFORMANCE_METRIC(BindValueQt, "BindValue execution QtScript");
+ Q_DEFINE_PERFORMANCE_METRIC(BindableValueUpdate, "QmlBindableValue::update");
+ Q_DEFINE_PERFORMANCE_METRIC(PixmapLoad, "Pixmap loading");
+ Q_DEFINE_PERFORMANCE_METRIC(MetaProperty, "Meta property resolution");
+ Q_DEFINE_PERFORMANCE_METRIC(PathCache, "Path cache");
+ Q_DEFINE_PERFORMANCE_METRIC(CreateParticle, "Particle creation");
+ Q_DEFINE_PERFORMANCE_METRIC(FontDatabase, "Font database creation");
+ Q_DEFINE_PERFORMANCE_METRIC(ItemComponentComplete, "QFxItem::componentComplete");
+ Q_DEFINE_PERFORMANCE_METRIC(ImageComponentComplete, "QFxImage::componentComplete");
+ Q_DEFINE_PERFORMANCE_METRIC(ComponentInstanceComponentComplete, "QFxComponentInstance::componentComplete");
+ Q_DEFINE_PERFORMANCE_METRIC(BaseLayoutComponentComplete, "QFxBaseLayout::componentComplete");
+ Q_DEFINE_PERFORMANCE_METRIC(TextComponentComplete, "QFxText::componentComplete");
+ Q_DEFINE_PERFORMANCE_METRIC(ContextQuery, "QtScript: Query Context");
+ Q_DEFINE_PERFORMANCE_METRIC(ContextProperty, "QtScript: Context Property");
+ Q_DEFINE_PERFORMANCE_METRIC(ObjectQuery, "QtScript: Query Object");
+ Q_DEFINE_PERFORMANCE_METRIC(ObjectProperty, "QtScript: Object Property");
+ Q_DEFINE_PERFORMANCE_METRIC(ObjectSetProperty, "QtScript: Set Object Property");
+ Q_DEFINE_PERFORMANCE_METRIC(QFxText_setText, "QFxText::setText");
+}
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qfxperf.h b/src/declarative/util/qfxperf.h
new file mode 100644
index 0000000..b1f9bd0
--- /dev/null
+++ b/src/declarative/util/qfxperf.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef _QFXPERF_H_
+#define _QFXPERF_H_
+
+#include "qperformancelog.h"
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+Q_DECLARE_PERFORMANCE_LOG(QFxPerf) {
+ Q_DECLARE_PERFORMANCE_METRIC(XmlParsing);
+ Q_DECLARE_PERFORMANCE_METRIC(Compile);
+ Q_DECLARE_PERFORMANCE_METRIC(CompileRun);
+ Q_DECLARE_PERFORMANCE_METRIC(CssParsing);
+ Q_DECLARE_PERFORMANCE_METRIC(CreateComponent);
+ Q_DECLARE_PERFORMANCE_METRIC(BindInit);
+ Q_DECLARE_PERFORMANCE_METRIC(BindCompile);
+ Q_DECLARE_PERFORMANCE_METRIC(BindValue);
+ Q_DECLARE_PERFORMANCE_METRIC(BindValueSSE);
+ Q_DECLARE_PERFORMANCE_METRIC(BindValueQt);
+ Q_DECLARE_PERFORMANCE_METRIC(BindableValueUpdate);
+ Q_DECLARE_PERFORMANCE_METRIC(PixmapLoad);
+ Q_DECLARE_PERFORMANCE_METRIC(MetaProperty);
+ Q_DECLARE_PERFORMANCE_METRIC(PathCache);
+ Q_DECLARE_PERFORMANCE_METRIC(CreateParticle);
+ Q_DECLARE_PERFORMANCE_METRIC(FontDatabase);
+ Q_DECLARE_PERFORMANCE_METRIC(ItemComponentComplete);
+ Q_DECLARE_PERFORMANCE_METRIC(ImageComponentComplete);
+ Q_DECLARE_PERFORMANCE_METRIC(ComponentInstanceComponentComplete);
+ Q_DECLARE_PERFORMANCE_METRIC(BaseLayoutComponentComplete);
+ Q_DECLARE_PERFORMANCE_METRIC(TextComponentComplete);
+ Q_DECLARE_PERFORMANCE_METRIC(ContextQuery);
+ Q_DECLARE_PERFORMANCE_METRIC(ContextProperty);
+ Q_DECLARE_PERFORMANCE_METRIC(ObjectQuery);
+ Q_DECLARE_PERFORMANCE_METRIC(ObjectProperty);
+ Q_DECLARE_PERFORMANCE_METRIC(ObjectSetProperty);
+ Q_DECLARE_PERFORMANCE_METRIC(QFxText_setText);
+}
+
+#endif // _QFXPERF_H_
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
diff --git a/src/declarative/util/qfxview.cpp b/src/declarative/util/qfxview.cpp
new file mode 100644
index 0000000..3fb30e9
--- /dev/null
+++ b/src/declarative/util/qfxview.cpp
@@ -0,0 +1,310 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qscriptvalueiterator.h"
+#include "qdebug.h"
+#include "qtimer.h"
+#include "qevent.h"
+#include "qdir.h"
+#include "qcoreapplication.h"
+#include "qfontdatabase.h"
+#include "qicon.h"
+#include "qurl.h"
+#include "qboxlayout.h"
+
+#include "qmlbindablevalue.h"
+#include "qml.h"
+#include "qfxitem.h"
+#include "qperformancelog.h"
+#include "qfxperf.h"
+
+#include "qfxview.h"
+#include <QtDeclarative/qmlengine.h>
+#include <QtDeclarative/qmlcontext.h>
+
+
+QT_BEGIN_NAMESPACE
+DEFINE_BOOL_CONFIG_OPTION(itemTreeDump, ITEMTREE_DUMP);
+
+static QVariant stringToPixmap(const QString &str)
+{
+ //XXX need to use correct paths
+ return QVariant(QPixmap(str));
+}
+
+static QVariant stringToIcon(const QString &str)
+{
+ //XXX need to use correct paths
+ return QVariant(QIcon(str));
+}
+
+static QVariant stringToKeySequence(const QString &str)
+{
+ return QVariant::fromValue(QKeySequence(str));
+}
+
+static QVariant stringToUrl(const QString &str)
+{
+ return QVariant(QUrl(str));
+}
+
+class QFxViewPrivate
+{
+public:
+ QFxViewPrivate(QFxView *w)
+ : q(w), root(0), component(0) {}
+
+ QFxView *q;
+ QFxItem *root;
+
+ QUrl source;
+ QString xml;
+
+ QmlEngine engine;
+ QmlComponent *component;
+ void init();
+};
+
+/*!
+ \class QFxView
+ \brief The QFxView class provides a widget for displaying a Qt Declarative user interface.
+
+ QFxView currently provides a minimal interface for displaying Qml files, and
+ connecting between QML and C++ Qt objects.
+
+ Typcial usage looks something like this:
+ \code
+ ...
+ QFxView *view = new QFxView(this);
+ vbox->addWidget(view);
+
+ QFile file(fileName);
+ file.open(QFile::ReadOnly);
+ QString xml = file.readAll();
+ view->setXml(xml, fileName);
+
+ QFileInfo fi(file);
+ view->setPath(fi.path());
+
+ view->execute();
+ ...
+ \endcode
+*/
+
+QFxView::QFxView(QWidget *parent)
+: QSimpleCanvas(parent), d(new QFxViewPrivate(this))
+{
+ d->init();
+}
+
+QFxView::QFxView(QSimpleCanvas::CanvasMode mode, QWidget *parent)
+: QSimpleCanvas(mode, parent), d(new QFxViewPrivate(this))
+{
+ d->init();
+}
+
+void QFxViewPrivate::init()
+{
+ // XXX: These need to be put in a central location for this kind of thing
+ qRegisterMetaType<QFxAnchorLine>("QFxAnchorLine");
+
+ QmlMetaType::registerCustomStringConverter(QVariant::Pixmap, &stringToPixmap);
+ QmlMetaType::registerCustomStringConverter(QVariant::Icon, &stringToIcon);
+ QmlMetaType::registerCustomStringConverter(QVariant::KeySequence, &stringToKeySequence);
+ QmlMetaType::registerCustomStringConverter(QVariant::Url, &stringToUrl);
+
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ QFxPerfTimer<QFxPerf::FontDatabase> perf;
+#endif
+ QFontDatabase database;
+}
+
+QFxView::~QFxView()
+{
+ clearItems();
+ delete d; d = 0;
+}
+
+void QFxView::setUrl(const QUrl& url)
+{
+ d->source = url;
+ d->xml = QString();
+}
+
+void QFxView::setXml(const QString &xml, const QString &filename)
+{
+ d->source = QUrl::fromLocalFile(filename);
+ d->xml = xml;
+}
+
+QString QFxView::xml() const
+{
+ return d->xml;
+}
+
+QmlEngine* QFxView::engine()
+{
+ return &d->engine;
+}
+
+QmlContext* QFxView::rootContext()
+{
+ return d->engine.rootContext();
+}
+
+void QFxView::execute()
+{
+ rootContext()->activate();
+
+ if (d->xml.isEmpty()) {
+ d->component = new QmlComponent(&d->engine, d->source, this);
+ } else {
+ d->component = new QmlComponent(&d->engine, d->xml.toUtf8(), d->source);
+ }
+
+ if(d->component->isReady()) {
+ continueExecute();
+ } else {
+ connect(d->component, SIGNAL(readyChanged()), this, SLOT(continueExecute()));
+ }
+}
+
+void QFxView::continueExecute()
+{
+ disconnect(d->component, SIGNAL(readyChanged()), this, SLOT(continueExecute()));
+
+ if(!d->component){
+ qWarning() << "Error in loading" << d->source;
+ return;
+ }
+
+ QObject *obj = d->component->create();
+ rootContext()->deactivate();
+ if(obj) {
+ if(QFxItem *item = qobject_cast<QFxItem *>(obj)) {
+ item->QSimpleCanvasItem::setParent(QSimpleCanvas::root());
+
+ if(itemTreeDump())
+ item->dump();
+
+ QPerformanceLog::displayData();
+ QPerformanceLog::clear();
+ d->root = item;
+ emit sceneResized(QSize(item->width(), item->height()));
+ } else if(QWidget *wid = qobject_cast<QWidget *>(obj)) {
+ window()->setAttribute(Qt::WA_OpaquePaintEvent, false);
+ window()->setAttribute(Qt::WA_NoSystemBackground, false);
+ if (!layout()) {
+ setLayout(new QVBoxLayout);
+ } else if (layout()->count()) {
+ // Hide the QGraphicsView in GV mode.
+ QLayoutItem *item = layout()->itemAt(0);
+ if (item->widget())
+ item->widget()->hide();
+ }
+ layout()->addWidget(wid);
+ emit sceneResized(wid->size());
+ }
+ }
+}
+
+QFxItem* QFxView::addItem(const QString &xml, QFxItem* parent)
+{
+ if(!d->root)
+ return 0;
+
+ QmlComponent component(&d->engine, xml.toUtf8(), QUrl());
+ QObject *obj = component.create();
+ if(obj){
+ QFxItem *item = static_cast<QFxItem *>(obj);
+ if(!parent)
+ parent = d->root;
+
+ item->setItemParent(parent);
+ return item;
+ }
+ return 0;
+}
+
+void QFxView::reset()
+{
+ clearItems();
+ d->engine.clearComponentCache();
+}
+
+void QFxView::clearItems()
+{
+ if(!d->root)
+ return;
+ delete d->root;
+ d->root = 0;
+}
+
+QFxItem *QFxView::root() const
+{
+ return d->root;
+}
+
+void QFxView::resizeEvent(QResizeEvent *e)
+{
+ if(d->root) {
+ d->root->setWidth(width());
+ d->root->setHeight(height());
+ }
+ QSimpleCanvas::resizeEvent(e);
+}
+
+void QFxView::focusInEvent(QFocusEvent *)
+{
+ // Do nothing (do not call QWidget::update())
+}
+
+void QFxView::focusOutEvent(QFocusEvent *)
+{
+ // Do nothing (do not call QWidget::update())
+}
+
+
+void QFxView::dumpRoot()
+{
+ root()->dump();
+}
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qfxview.h b/src/declarative/util/qfxview.h
new file mode 100644
index 0000000..b5592b8
--- /dev/null
+++ b/src/declarative/util/qfxview.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef _QFXVIEW_H_
+#define _QFXVIEW_H_
+
+#include <qfxglobal.h>
+#include <QtCore/qdatetime.h>
+#include <QtGui/qgraphicssceneevent.h>
+#include <QtGui/qwidget.h>
+#include <qsimplecanvas.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QFxItem;
+class QmlEngine;
+class QmlContext;
+class Canvas;
+
+class QFxViewPrivate;
+class Q_DECLARATIVE_EXPORT QFxView : public QSimpleCanvas
+{
+Q_OBJECT
+public:
+ explicit QFxView(QWidget *parent = 0);
+ QFxView(QSimpleCanvas::CanvasMode mode, QWidget* parent = 0);
+
+ virtual ~QFxView();
+
+ void setUrl(const QUrl&);
+ void setXml(const QString &xml, const QString &filename=QString());
+ QString xml() const;
+ QmlEngine* engine();
+ QmlContext* rootContext();
+ virtual void execute();
+ virtual void reset();
+
+ virtual QFxItem* addItem(const QString &xml, QFxItem* parent=0);
+ virtual void clearItems();
+
+ virtual QFxItem *root() const;
+
+ void dumpRoot();
+
+Q_SIGNALS:
+ void sceneResized(QSize size);
+
+private Q_SLOTS:
+ void continueExecute();
+
+protected:
+ virtual void resizeEvent(QResizeEvent *);
+ void focusInEvent(QFocusEvent *);
+ void focusOutEvent(QFocusEvent *);
+
+private:
+ friend class QFxViewPrivate;
+ QFxViewPrivate *d;
+};
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+#endif // _QFXVIEW_H_
diff --git a/src/declarative/util/qmlanimation.cpp b/src/declarative/util/qmlanimation.cpp
new file mode 100644
index 0000000..803f2b2
--- /dev/null
+++ b/src/declarative/util/qmlanimation.cpp
@@ -0,0 +1,2292 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlanimation.h"
+#include "gfxtimeline.h"
+#include "qvariant.h"
+#include "qcolor.h"
+#include "qfile.h"
+#include "gfxeasing.h"
+#include "qmlpropertyvaluesource.h"
+#include "qml.h"
+#include "qmlanimation_p.h"
+#include "gfxtimeline.h"
+#include "qmlbehaviour.h"
+#include <QParallelAnimationGroup>
+#include <QSequentialAnimationGroup>
+#include <QtCore/qset.h>
+#include <QtDeclarative/qmlexpression.h>
+#include <private/qmlstringconverters_p.h>
+
+/* TODO:
+ Check for any memory leaks
+ easing should be a QEasingCurve-type property
+ All other XXXs
+*/
+
+QT_BEGIN_NAMESPACE
+
+QEasingCurve stringToCurve(const QString &curve)
+{
+ QEasingCurve easingCurve;
+
+ QString normalizedCurve = curve;
+ bool hasParams = curve.contains(QLatin1Char('('));
+ QStringList props;
+
+ if(hasParams) {
+ QString easeName = curve.trimmed();
+ if(!easeName.endsWith(QLatin1Char(')'))) {
+ qWarning("QEasingCurve: Unmatched perenthesis in easing function '%s'",
+ curve.toLatin1().constData());
+ return easingCurve;
+ }
+
+ int idx = easeName.indexOf(QLatin1Char('('));
+ QString prop_str =
+ easeName.mid(idx + 1, easeName.length() - 1 - idx - 1);
+ normalizedCurve = easeName.left(idx);
+
+ props = prop_str.split(QLatin1Char(','));
+ }
+
+ normalizedCurve = normalizedCurve.mid(4);
+ //XXX optimize?
+ int index = QEasingCurve::staticMetaObject.indexOfEnumerator("Type");
+ QMetaEnum me = QEasingCurve::staticMetaObject.enumerator(index);
+
+ int value = me.keyToValue(normalizedCurve.toLatin1().constData());
+ if (value < 0) {
+ //XXX print line number
+ qWarning("QEasingCurve: Unknown easing curve '%s'",
+ curve.toLatin1().constData());
+ value = 0;
+ }
+ easingCurve.setType((QEasingCurve::Type)value);
+
+ if (hasParams) {
+ foreach(QString str, props) {
+ int sep = str.indexOf(QLatin1Char(':'));
+
+ if(sep == -1) {
+ qWarning("QEasingCurve: Improperly specified property in easing function '%s'",
+ curve.toLatin1().constData());
+ return easingCurve;
+ }
+
+ QString propName = str.left(sep).trimmed();
+ bool isOk;
+ qreal propValue = str.mid(sep + 1).trimmed().toDouble(&isOk);
+
+ if(propName.isEmpty() || !isOk) {
+ qWarning("QEasingCurve: Improperly specified property in easing function '%s'",
+ curve.toLatin1().constData());
+ return easingCurve;
+ }
+
+ //XXX optimize
+ if (propName == QLatin1String("amplitude")) {
+ easingCurve.setAmplitude(propValue);
+ } else if (propName == QLatin1String("period")) {
+ easingCurve.setPeriod(propValue);
+ } else if (propName == QLatin1String("overshoot")) {
+ easingCurve.setOvershoot(propValue);
+ }
+ }
+ }
+
+ return easingCurve;
+}
+
+QML_DEFINE_NOCREATE_TYPE(QmlAbstractAnimation);
+
+/*!
+ \qmlclass Animation
+ \brief The Animation element is the base of all QML animations.
+
+ The Animation element cannot be used directly in a QML file. It exists
+ to provide a set of common properties and methods, available across all the
+ other animation types that inherit from it. Attempting to use the Animation
+ element directly will result in an error.
+*/
+
+/*!
+ \class QmlAbstractAnimation
+ \internal
+*/
+
+QmlAbstractAnimation::QmlAbstractAnimation(QObject *parent)
+: QmlPropertyValueSource(*(new QmlAbstractAnimationPrivate), parent)
+{
+}
+
+QmlAbstractAnimation::~QmlAbstractAnimation()
+{
+}
+
+QmlAbstractAnimation::QmlAbstractAnimation(QmlAbstractAnimationPrivate &dd, QObject *parent)
+: QmlPropertyValueSource(dd, parent)
+{
+}
+
+/*!
+ \qmlproperty bool Animation::running
+ This property holds whether the animation is currently running.
+
+ The \c running property can be set to declaratively control whether or not
+ an animation is running. The following example will animate a rectangle
+ whenever the \l MouseRegion is pressed.
+
+ \code
+ <Rect width="100" height="100">
+ <x>
+ <NumericAnimation running="{MyMouse.pressed}" from="0" to="100" />
+ </x>
+ <MouseRegion id="MyMouse" />
+ </Rect>
+ \endcode
+
+ Likewise, the \c running property can be read to determine if the animation
+ is running. In the following example the text element will indicate whether
+ or not the animation is running.
+
+ \code
+ <NumericAnimation id="MyAnimation" />
+ <Text text="{MyAnimation.running?'Animation is running':'Animation is not running'}" />
+ \endcode
+
+ Animations can also be started and stopped imperatively from JavaScript
+ using the \c start() and \c stop() methods.
+
+ By default, animations are not running.
+*/
+bool QmlAbstractAnimation::isRunning() const
+{
+ Q_D(const QmlAbstractAnimation);
+ return d->running;
+}
+
+void QmlAbstractAnimationPrivate::commence()
+{
+ Q_Q(QmlAbstractAnimation);
+
+ q->prepare(userProperty.value);
+ q->qtAnimation()->start();
+ if(!q->qtAnimation()->state() == QAbstractAnimation::Running) {
+ running = false;
+ emit q->completed();
+ }
+}
+
+void QmlAbstractAnimation::setRunning(bool r)
+{
+ Q_D(QmlAbstractAnimation);
+ if(d->running == r)
+ return;
+
+ if(d->group) {
+ qWarning("QmlAbstractAnimation: setRunning() cannot be used on non-root animation nodes");
+ return;
+ }
+
+ d->running = r;
+ if(d->running) {
+ if(!d->connectedTimeLine) {
+ QObject::connect(qtAnimation(), SIGNAL(finished()),
+ this, SLOT(timelineComplete()));
+ d->connectedTimeLine = true;
+ }
+ if (d->componentComplete)
+ d->commence();
+ else
+ d->startOnCompletion = true;
+ emit started();
+ } else {
+ if(!d->finishPlaying)
+ qtAnimation()->stop();
+ emit completed();
+ }
+
+ emit runningChanged(d->running);
+}
+
+void QmlAbstractAnimation::classBegin()
+{
+ Q_D(QmlAbstractAnimation);
+ d->componentComplete = false;
+}
+
+void QmlAbstractAnimation::componentComplete()
+{
+ Q_D(QmlAbstractAnimation);
+ if (d->startOnCompletion)
+ d->commence();
+ d->componentComplete = true;
+}
+
+/*!
+ \qmlproperty bool Animation::finishPlaying
+ This property holds whether the animation should finish playing when it is stopped.
+
+ If this true the animation will complete its current iteration when it
+ is stopped - either by setting the \c running property to false, or by
+ calling the \c stop() method. The \c complete() method is not effected
+ by this value.
+
+ This behaviour is most useful when the \c repeat property is set, as the
+ animation will finish playing normally but not restart.
+
+ By default, the finishPlaying property is not set.
+*/
+bool QmlAbstractAnimation::finishPlaying() const
+{
+ Q_D(const QmlAbstractAnimation);
+ return d->finishPlaying;
+}
+
+void QmlAbstractAnimation::setFinishPlaying(bool f)
+{
+ Q_D(QmlAbstractAnimation);
+ if(d->finishPlaying == f)
+ return;
+
+ d->finishPlaying = f;
+ emit finishPlayingChanged(f);
+}
+
+/*!
+ \qmlproperty bool Animation::repeat
+ This property holds whether the animation should repeat.
+
+ If set, the animation will continuously repeat until it is explicitly
+ stopped - either by setting the \c running property to false, or by calling
+ the \c stop() method.
+
+ In the following example, the rectangle will spin indefinately.
+
+ \code
+ <Rect>
+ <rotation>
+ <NumericAnimation running="true" repeat="true" from="0" to="360" />
+ </rotation>
+ </Rect>
+ \endcode
+*/
+bool QmlAbstractAnimation::repeat() const
+{
+ Q_D(const QmlAbstractAnimation);
+ return d->repeat;
+}
+
+void QmlAbstractAnimation::setRepeat(bool r)
+{
+ Q_D(QmlAbstractAnimation);
+ if(r == d->repeat)
+ return;
+
+ d->repeat = r;
+ int ic = r ? -1 : 1;
+ qtAnimation()->setIterationCount(ic);
+ emit repeatChanged(r);
+}
+
+QmlAnimationGroup *QmlAbstractAnimation::group() const
+{
+ Q_D(const QmlAbstractAnimation);
+ return d->group;
+}
+
+void QmlAbstractAnimation::setGroup(QmlAnimationGroup *g)
+{
+ Q_D(QmlAbstractAnimation);
+ if(d->group == g)
+ return;
+ if(d->group)
+ static_cast<QmlAnimationGroupPrivate *>(d->group->d_ptr)->animations.removeAll(this);
+
+ d->group = g;
+
+ if(d->group && !static_cast<QmlAnimationGroupPrivate *>(d->group->d_ptr)->animations.contains(this))
+ static_cast<QmlAnimationGroupPrivate *>(d->group->d_ptr)->animations.append(this);
+
+ if (d->group)
+ ((QAnimationGroup*)d->group->qtAnimation())->addAnimation(qtAnimation());
+
+ //if(g) //if removed from a group, then the group should no longer be the parent
+ setParent(g);
+}
+
+/*!
+ \qmlproperty Object Animation::target
+ This property holds an explicit target object to animate.
+
+ The exact effect of the \c target property depends on how the animation
+ is being used. Refer to the \l animation documentation for details.
+*/
+QObject *QmlAbstractAnimation::target() const
+{
+ Q_D(const QmlAbstractAnimation);
+ return d->target;
+}
+
+void QmlAbstractAnimation::setTarget(QObject *o)
+{
+ Q_D(QmlAbstractAnimation);
+ if(d->target == o)
+ return;
+
+ d->target = o;
+ if(d->target && !d->propertyName.isEmpty()) {
+ d->userProperty = QmlMetaProperty(d->target, d->propertyName);
+ } else {
+ d->userProperty.invalidate();
+ }
+
+ emit targetChanged(d->target, d->propertyName);
+}
+
+/*!
+ \qmlproperty string Animation::property
+ This property holds an explicit property to animated.
+
+ The exact effect of the \c property property depends on how the animation
+ is being used. Refer to the \l animation documentation for details.
+*/
+QString QmlAbstractAnimation::property() const
+{
+ Q_D(const QmlAbstractAnimation);
+ return d->propertyName;
+}
+
+void QmlAbstractAnimation::setProperty(const QString &n)
+{
+ Q_D(QmlAbstractAnimation);
+ if(d->propertyName == n)
+ return;
+
+ d->propertyName = n;
+ if(d->target && !d->propertyName.isEmpty()) {
+ d->userProperty = QmlMetaProperty(d->target, d->propertyName);
+ } else {
+ d->userProperty.invalidate();
+ }
+
+ emit targetChanged(d->target, d->propertyName);
+}
+
+/*!
+ \qmlmethod Animation::start()
+ \brief Starts the animation.
+
+ If the animation is already running, calling this method has no effect. The
+ \c running property will be true following a call to \c start().
+*/
+void QmlAbstractAnimation::start()
+{
+ setRunning(true);
+}
+
+/*!
+ \qmlmethod Animation::stop()
+ \brief Stops the animation.
+
+ If the animation is not running, calling this method has no effect. The
+ \c running property will be false following a call to \c stop().
+
+ Normally \c stop() stops the animation immediately, and the animation has
+ no further influence on property values. In this example animation
+ \code
+ <Rect>
+ <x>
+ <NumericAnimation from="0" to="100" duration="500" />
+ </x>
+ </Rect>
+ \endcode
+ was stopped at time 250ms, the \c x property will have a value of 50.
+
+ However, if the \c finishPlaying property is set, the animation will
+ continue running until it completes and then stop. The \c running property
+ will still become false immediately.
+*/
+void QmlAbstractAnimation::stop()
+{
+ setRunning(false);
+}
+
+/*!
+ \qmlmethod Animation::restart()
+ \brief Restarts the animation.
+
+ This is a convenience method, and is equivalent to calling \c stop() and
+ then \c start().
+*/
+void QmlAbstractAnimation::restart()
+{
+ stop();
+ start();
+}
+
+/*!
+ \qmlmethod Animation::complete()
+ \brief Stops the animation, jumping to the final property values.
+
+ If the animation is not running, calling this method has no effect. The
+ \c running property will be false following a call to \c complete().
+
+ Unlike \c stop(), \c complete() immediately fast-forwards the animation to
+ its end. In the following example,
+ \code
+ <Rect>
+ <x>
+ <NumericAnimation from="0" to="100" duration="500" />
+ </x>
+ </Rect>
+ \endcode
+ calling \c stop() at time 250ms will result in the \c x property having
+ a value of 50, while calling \c complete() will set the \c x property to
+ 100, exactly as though the animation had played the whole way through.
+*/
+void QmlAbstractAnimation::complete()
+{
+ if(isRunning()) {
+ qtAnimation()->setCurrentTime(qtAnimation()->duration());
+ }
+}
+
+void QmlAbstractAnimation::setTarget(const QmlMetaProperty &p)
+{
+ Q_D(QmlAbstractAnimation);
+ if(d->userProperty.isNull)
+ d->userProperty = p;
+}
+
+//prepare is called before an animation begins
+//(when an animation is used as a simple animation, and not as part of a transition)
+void QmlAbstractAnimation::prepare(QmlMetaProperty &)
+{
+}
+
+void QmlAbstractAnimation::transition(QmlStateActions &actions,
+ QmlMetaProperties &modified,
+ TransitionDirection direction)
+{
+ Q_UNUSED(actions);
+ Q_UNUSED(modified);
+ Q_UNUSED(direction);
+}
+
+void QmlAbstractAnimation::timelineComplete()
+{
+ setRunning(false);
+}
+
+/*!
+ \qmlclass PauseAnimation QmlPauseAnimation
+ \inherits Animation
+ \brief The PauseAnimation provides a pause for an animation.
+
+ When used in a SequentialAnimation, PauseAnimation is a step when
+ nothing happens, for a specified duration.
+
+ A 500ms animation sequence, with a 100ms pause between two animations:
+ \code
+ <SequentialAnimation>
+ <NumericAnimation ... duration="200"/>
+ <PauseAnimation duration="100"/>
+ <NumericAnimation ... duration="200"/>
+ </SequentialAnimation>
+ \endcode
+*/
+/*!
+ \internal
+ \class QmlPauseAnimation
+ \ingroup animation states
+ \brief The QmlPauseAnimation class provides a pause for an animation.
+
+ When used in a QmlSequentialAnimation, QmlPauseAnimation is a step when
+ nothing happens, for a specified duration.
+
+ A QmlPauseAnimation object can be instantiated in Qml using the tag
+ \ref xmlPauseAnimation "&lt;PauseAnimation&gt;".
+*/
+
+QML_DEFINE_TYPE(QmlPauseAnimation,PauseAnimation);
+QmlPauseAnimation::QmlPauseAnimation(QObject *parent)
+: QmlAbstractAnimation(*(new QmlPauseAnimationPrivate), parent)
+{
+ Q_D(QmlPauseAnimation);
+ d->init();
+}
+
+QmlPauseAnimation::~QmlPauseAnimation()
+{
+}
+
+void QmlPauseAnimationPrivate::init()
+{
+ Q_Q(QmlPauseAnimation);
+ pa = new QPauseAnimation(q);
+}
+
+/*!
+ \qmlproperty int PauseAnimation::duration
+ This property holds the duration of the pause in milliseconds
+
+ The default value is 250.
+*/
+/*!
+ \property QmlPauseAnimation::duration
+ \brief the duration of the pause in milliseconds
+
+ The default value is 250.
+*/
+int QmlPauseAnimation::duration() const
+{
+ Q_D(const QmlPauseAnimation);
+ return d->pa->duration();
+}
+
+void QmlPauseAnimation::setDuration(int duration)
+{
+ if(duration < 0) {
+ qWarning("QmlPauseAnimation: Cannot set a duration of < 0");
+ return;
+ }
+
+ Q_D(QmlPauseAnimation);
+ if(d->pa->duration() == duration)
+ return;
+ d->pa->setDuration(duration);
+ emit durationChanged(duration);
+}
+
+void QmlPauseAnimation::prepare(QmlMetaProperty &p)
+{
+ Q_D(QmlPauseAnimation);
+ if(d->userProperty.isNull)
+ d->property = p;
+ else
+ d->property = d->userProperty;
+}
+
+QAbstractAnimation *QmlPauseAnimation::qtAnimation()
+{
+ Q_D(QmlPauseAnimation);
+ return d->pa;
+}
+
+/*!
+ \qmlclass ColorAnimation QmlColorAnimation
+ \inherits Animation
+ \brief The ColorAnimation allows you to animate color changes.
+
+ \code
+ <ColorAnimation from="white" to="#c0c0c0" duration="100"/>
+ \endcode
+
+ The default property animated is \c color, but like other animations,
+ this can be changed by setting \c property. The \c color property will
+ still animate. XXX is this a bug?
+*/
+/*!
+ \internal
+ \class QmlColorAnimation
+ \ingroup animation states
+ \brief The QmlColorAnimation class allows you to animate color changes.
+
+ A QmlColorAnimation object can be instantiated in Qml using the tag
+ \ref xmlColorAnimation "&lt;ColorAnimation&gt;".
+*/
+
+QmlColorAnimation::QmlColorAnimation(QObject *parent)
+: QmlAbstractAnimation(*(new QmlColorAnimationPrivate), parent)
+{
+ Q_D(QmlColorAnimation);
+ d->init();
+}
+
+QmlColorAnimation::~QmlColorAnimation()
+{
+}
+
+void QmlColorAnimationPrivate::init()
+{
+ Q_Q(QmlColorAnimation);
+ ca = new GfxValueAnimator(q);
+ ca->setStartValue(QVariant(0.0f));
+ ca->setEndValue(QVariant(1.0f));
+}
+
+/*!
+ \qmlproperty int ColorAnimation::duration
+ This property holds the duration of the color transition, in milliseconds.
+
+ The default value is 250.
+*/
+/*!
+ \property QmlColorAnimation::duration
+ \brief the duration of the transition, in milliseconds.
+
+ The default value is 250.
+*/
+int QmlColorAnimation::duration() const
+{
+ Q_D(const QmlColorAnimation);
+ return d->ca->duration();
+}
+
+void QmlColorAnimation::setDuration(int duration)
+{
+ if(duration < 0) {
+ qWarning("QmlColorAnimation: Cannot set a duration of < 0");
+ return;
+ }
+
+ Q_D(QmlColorAnimation);
+ if(d->ca->duration() == duration)
+ return;
+ d->ca->setDuration(duration);
+ emit durationChanged(duration);
+}
+
+/*!
+ \qmlproperty color ColorAnimation::from
+ This property holds the starting color.
+*/
+/*!
+ \property QmlColorAnimation::from
+ \brief the starting color.
+*/
+QColor QmlColorAnimation::from() const
+{
+ Q_D(const QmlColorAnimation);
+ return d->fromValue;
+}
+
+void QmlColorAnimation::setFrom(const QColor &f)
+{
+ Q_D(QmlColorAnimation);
+ if(d->fromValue.isValid() && f == d->fromValue)
+ return;
+ d->fromValue = f;
+ emit fromChanged(f);
+}
+
+/*!
+ \qmlproperty color ColorAnimation::from
+ This property holds the ending color.
+*/
+/*!
+ \property QmlColorAnimation::to
+ \brief the ending color.
+*/
+QColor QmlColorAnimation::to() const
+{
+ Q_D(const QmlColorAnimation);
+ return d->toValue;
+}
+
+void QmlColorAnimation::setTo(const QColor &t)
+{
+ Q_D(QmlColorAnimation);
+ if(d->toValue.isValid() && t == d->toValue)
+ return;
+ d->toValue = t;
+ emit toChanged(t);
+}
+
+/*!
+ \qmlproperty string ColorAnimation::easing
+ This property holds the easing curve used for the transition.
+
+ Each channel of the color is eased using the same easing curve.
+ See NumericAnimation::easing for a full discussion of easing,
+ and a list of available curves.
+*/
+QString QmlColorAnimation::easing() const
+{
+ Q_D(const QmlColorAnimation);
+ return d->easing;
+}
+
+void QmlColorAnimation::setEasing(const QString &e)
+{
+ Q_D(QmlColorAnimation);
+ if(d->easing == e)
+ return;
+
+ d->easing = e;
+ d->ca->setEasingCurve(stringToCurve(d->easing));
+ emit easingChanged(e);
+}
+
+/*!
+ \qmlproperty list<Item> ColorAnimation::filter
+ This property holds the items selected to be affected by this animation (all if not set).
+ \sa exclude
+*/
+QList<QObject *> *QmlColorAnimation::filter()
+{
+ Q_D(QmlColorAnimation);
+ return &d->filter;
+}
+
+/*!
+ \qmlproperty list<Item> ColorAnimation::exclude
+ This property holds the items not to be affected by this animation.
+ \sa filter
+*/
+QList<QObject *> *QmlColorAnimation::exclude()
+{
+ Q_D(QmlColorAnimation);
+ return &d->exclude;
+}
+
+void QmlColorAnimation::prepare(QmlMetaProperty &p)
+{
+ Q_D(QmlColorAnimation);
+ if(d->userProperty.isNull)
+ d->property = p;
+ else
+ d->property = d->userProperty;
+ d->fromSourced = false;
+ d->value.GfxValue::setValue(0.);
+ d->ca->setAnimValue(&d->value, QAbstractAnimation::KeepWhenStopped);
+}
+
+QAbstractAnimation *QmlColorAnimation::qtAnimation()
+{
+ Q_D(QmlColorAnimation);
+ return d->ca;
+}
+
+void QmlColorAnimation::transition(QmlStateActions &actions,
+ QmlMetaProperties &modified,
+ TransitionDirection direction)
+{
+ Q_D(QmlColorAnimation);
+ Q_UNUSED(direction);
+
+ struct NTransitionData : public GfxValue
+ {
+ QmlStateActions actions;
+ void write(QmlMetaProperty &property, const QColor &color)
+ {
+ if(property.propertyType() == qMetaTypeId<QColor>()) {
+ property.write(color);
+ }
+ }
+
+ void setValue(qreal v)
+ {
+ GfxValue::setValue(v);
+ for(int ii = 0; ii < actions.count(); ++ii) {
+ Action &action = actions[ii];
+
+ QColor to(action.toValue.value<QColor>());
+
+ if(v == 1.) {
+ write(action.property, to);
+ } else {
+ if(action.fromValue.isNull()) {
+ action.fromValue = action.property.read();
+ if(action.fromValue.isNull())
+ action.fromValue = QVariant(QColor());
+ }
+
+ QColor from(action.fromValue.value<QColor>());
+
+ //XXX consolidate somewhere
+ uint red = uint(qreal(from.red()) + v * (qreal(to.red()) - qreal(from.red())));
+ uint green = uint(qreal(from.green()) + v * (qreal(to.green()) - qreal(from.green())));
+ uint blue = uint(qreal(from.blue()) + v * (qreal(to.blue()) - qreal(from.blue())));
+ uint alpha = uint(qreal(from.alpha()) + v * (qreal(to.alpha()) - qreal(from.alpha())));
+
+ write(action.property, QColor(red, green, blue, alpha));
+ }
+ }
+ }
+ };
+
+ //XXX should we get rid of this?
+ QStringList props;
+ props << QLatin1String("color");
+ if(!d->propertyName.isEmpty() && !props.contains(d->propertyName))
+ props.append(d->propertyName);
+
+ NTransitionData *data = new NTransitionData;
+
+ QSet<QObject *> objs;
+ for(int ii = 0; ii < actions.count(); ++ii) {
+ Action &action = actions[ii];
+
+ QObject *obj = action.property.object();
+ QString propertyName = action.property.name();
+
+ if((d->filter.isEmpty() || d->filter.contains(obj)) &&
+ (!d->exclude.contains(obj)) && props.contains(propertyName) &&
+ (!target() || target() == obj)) {
+ objs.insert(obj);
+ Action myAction = action;
+ if(d->fromValue.isValid())
+ myAction.fromValue = QVariant(d->fromValue);
+ if(d->toValue.isValid())
+ myAction.toValue = QVariant(d->toValue);
+
+ modified << action.property;
+ data->actions << myAction;
+ action.fromValue = myAction.toValue;
+ }
+ }
+
+ if(d->toValue.isValid() && target() && !objs.contains(target())) {
+ QObject *obj = target();
+ for(int jj = 0; jj < props.count(); ++jj) {
+ Action myAction;
+ myAction.property = QmlMetaProperty(obj, props.at(jj));
+
+ if(d->fromValue.isValid())
+ myAction.fromValue = QVariant(d->fromValue);
+
+ myAction.toValue = QVariant(d->toValue);
+ myAction.bv = 0;
+ myAction.event = 0;
+ data->actions << myAction;
+ }
+ }
+
+ if(data->actions.count())
+ d->ca->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped);
+ else
+ delete data;
+}
+
+
+void QmlColorAnimationPrivate::valueChanged(qreal v)
+{
+ if(!fromSourced) {
+ if(!fromValue.isValid()) {
+ fromValue = QColor(qvariant_cast<QColor>(property.read()));
+ }
+ fromSourced = true;
+ }
+
+ //XXX consolidate somewhere
+ uint red = uint(qreal(fromValue.red()) + v * (qreal(toValue.red()) - qreal(fromValue.red())));
+ uint green = uint(qreal(fromValue.green()) + v * (qreal(toValue.green()) - qreal(fromValue.green())));
+ uint blue = uint(qreal(fromValue.blue()) + v * (qreal(toValue.blue()) - qreal(fromValue.blue())));
+ uint alpha = uint(qreal(fromValue.alpha()) + v * (qreal(toValue.alpha()) - qreal(fromValue.alpha())));
+
+ if(property.propertyType() == qMetaTypeId<QColor>()) {
+ property.write(QColor(red, green, blue, alpha));
+ }
+}
+QML_DEFINE_TYPE(QmlColorAnimation,ColorAnimation);
+
+/*!
+ \qmlclass RunScriptAction QmlRunScriptAction
+ \inherits Animation
+ \brief The RunScripAction allows scripts to be run during transitions.
+
+*/
+/*!
+ \internal
+ \class QmlRunScriptAction
+ \brief The QmlRunScriptAction class allows scropts to be run during transitions
+
+ \ref xmlRunScriptAction
+*/
+QmlRunScriptAction::QmlRunScriptAction(QObject *parent)
+ :QmlAbstractAnimation(*(new QmlRunScriptActionPrivate), parent)
+{
+ Q_D(QmlRunScriptAction);
+ d->init();
+}
+
+QmlRunScriptAction::~QmlRunScriptAction()
+{
+}
+
+void QmlRunScriptActionPrivate::init()
+{
+ Q_Q(QmlRunScriptAction);
+ rsa = new QActionAnimation(&proxy, q);
+}
+
+/*!
+ \qmlproperty QString RunScript::script
+ This property holds the script to run.
+*/
+QString QmlRunScriptAction::script() const
+{
+ Q_D(const QmlRunScriptAction);
+ return d->script;
+}
+
+void QmlRunScriptAction::setScript(const QString &script)
+{
+ Q_D(QmlRunScriptAction);
+ if(script == d->script)
+ return;
+ d->script = script;
+ emit scriptChanged(script);
+}
+
+/*!
+ \qmlproperty QString RunScript::script
+ This property holds the file containing the script to run.
+*/
+QString QmlRunScriptAction::file() const
+{
+ Q_D(const QmlRunScriptAction);
+ return d->file;
+}
+
+void QmlRunScriptAction::setFile(const QString &file)
+{
+ Q_D(QmlRunScriptAction);
+ if(file == d->file)
+ return;
+ d->file = file;
+ emit fileChanged(file);
+}
+
+void QmlRunScriptActionPrivate::execute()
+{
+ Q_Q(QmlRunScriptAction);
+ QString scriptStr = script;
+ if(!file.isEmpty()){
+ QFile scriptFile(file);
+ if(scriptFile.open(QIODevice::ReadOnly | QIODevice::Text)){
+ scriptStr = QString::fromUtf8(scriptFile.readAll());
+ }
+ }
+
+ if(!scriptStr.isEmpty()) {
+ QmlExpression expr(ctxt, scriptStr, q);
+ expr.setTrackChange(false);
+ expr.value();
+ }
+}
+
+QAbstractAnimation *QmlRunScriptAction::qtAnimation()
+{
+ Q_D(QmlRunScriptAction);
+ return d->rsa;
+}
+
+QML_DEFINE_TYPE(QmlRunScriptAction, RunScriptAction);
+
+/*!
+ \qmlclass SetPropertyAction QmlSetPropertyAction
+ \inherits Animation
+ \brief The SetPropertyAction allows property changes during transitions.
+
+ Explicitly set \c theimage.smooth=true during a transition:
+ \code
+ <SetPropertyAction target="{theimage}" property="smooth" value="true"/>
+ \endcode
+
+ Set \c thewebview.url to the value set for the destination state:
+ \code
+ <SetPropertyAction target="{thewebview}" property="url"/>
+ \endcode
+
+ The SetPropertyAction is immediate -
+ the target property is not animated to the selected value in any way.
+*/
+/*!
+ \internal
+ \class QmlSetPropertyAction
+ \brief The QmlSetPropertyAction class allows property changes during transitions.
+
+ A QmlSetPropertyAction object can be instantiated in Qml using the tag
+ \ref xmlSetPropertyAction "&lt;SetPropertyAction&gt;".
+*/
+QmlSetPropertyAction::QmlSetPropertyAction(QObject *parent)
+: QmlAbstractAnimation(*(new QmlSetPropertyActionPrivate), parent)
+{
+ Q_D(QmlSetPropertyAction);
+ d->init();
+}
+
+QmlSetPropertyAction::~QmlSetPropertyAction()
+{
+}
+
+void QmlSetPropertyActionPrivate::init()
+{
+ Q_Q(QmlSetPropertyAction);
+ spa = new QActionAnimation(q);
+}
+
+/*!
+ \qmlproperty string SetPropertyAction::properties
+ This property holds the properties to be immediately set, comma-separated.
+*/
+QString QmlSetPropertyAction::properties() const
+{
+ Q_D(const QmlSetPropertyAction);
+ return d->properties;
+}
+
+void QmlSetPropertyAction::setProperties(const QString &p)
+{
+ Q_D(QmlSetPropertyAction);
+ if(d->properties == p)
+ return;
+ d->properties = p;
+ emit propertiesChanged(p);
+}
+
+/*!
+ \qmlproperty list<Item> SetPropertyAction::filter
+ This property holds the items selected to be affected by this animation (all if not set).
+ \sa exclude
+*/
+QList<QObject *> *QmlSetPropertyAction::filter()
+{
+ Q_D(QmlSetPropertyAction);
+ return &d->filter;
+}
+
+/*!
+ \qmlproperty list<Item> SetPropertyAction::exclude
+ This property holds the items not to be affected by this animation.
+ \sa filter
+*/
+QList<QObject *> *QmlSetPropertyAction::exclude()
+{
+ Q_D(QmlSetPropertyAction);
+ return &d->exclude;
+}
+
+/*!
+ \qmlproperty any SetPropertyAction::value
+ This property holds the value to be set on the property.
+ If not set, then the value defined for the end state of the transition.
+*/
+QVariant QmlSetPropertyAction::value() const
+{
+ Q_D(const QmlSetPropertyAction);
+ return d->value;
+}
+
+void QmlSetPropertyAction::setValue(const QVariant &v)
+{
+ Q_D(QmlSetPropertyAction);
+ if(d->value.isNull || d->value != v) {
+ d->value = v;
+ emit valueChanged(v);
+ }
+}
+
+void QmlSetPropertyActionPrivate::doAction()
+{
+ property.write(value);
+}
+
+QAbstractAnimation *QmlSetPropertyAction::qtAnimation()
+{
+ Q_D(QmlSetPropertyAction);
+ return d->spa;
+}
+
+void QmlSetPropertyAction::prepare(QmlMetaProperty &p)
+{
+ Q_D(QmlSetPropertyAction);
+
+ if(d->userProperty.isNull)
+ d->property = p;
+ else
+ d->property = d->userProperty;
+
+ d->spa->setAnimAction(&d->proxy, QAbstractAnimation::KeepWhenStopped);
+}
+
+void QmlSetPropertyAction::transition(QmlStateActions &actions,
+ QmlMetaProperties &modified,
+ TransitionDirection direction)
+{
+ Q_D(QmlSetPropertyAction);
+ Q_UNUSED(direction);
+
+ struct QmlSetPropertyAnimationAction : public QAbstractAnimationAction
+ {
+ QmlStateActions actions;
+ virtual void doAction()
+ {
+ for(int ii = 0; ii < actions.count(); ++ii) {
+ const Action &action = actions.at(ii);
+ QmlBehaviour::_ignore = true;
+ action.property.write(action.toValue);
+ QmlBehaviour::_ignore = false;
+ }
+ }
+ };
+
+ QStringList props = d->properties.split(QLatin1Char(','));
+ for(int ii = 0; ii < props.count(); ++ii)
+ props[ii] = props.at(ii).trimmed();
+ if(!d->propertyName.isEmpty() && !props.contains(d->propertyName))
+ props.append(d->propertyName);
+
+ QmlSetPropertyAnimationAction *data = new QmlSetPropertyAnimationAction;
+
+ QSet<QObject *> objs;
+ for(int ii = 0; ii < actions.count(); ++ii) {
+ Action &action = actions[ii];
+
+ QObject *obj = action.property.object();
+ QString propertyName = action.property.name();
+
+ if((d->filter.isEmpty() || d->filter.contains(obj)) &&
+ (!d->exclude.contains(obj)) && props.contains(propertyName) &&
+ (!target() || target() == obj)) {
+ objs.insert(obj);
+ Action myAction = action;
+
+ if(d->value.isValid())
+ myAction.toValue = d->value;
+
+ modified << action.property;
+ data->actions << myAction;
+ action.fromValue = myAction.toValue;
+ }
+ }
+
+ if(d->value.isValid() && target() && !objs.contains(target())) {
+ QObject *obj = target();
+ for(int jj = 0; jj < props.count(); ++jj) {
+ Action myAction;
+ myAction.property = QmlMetaProperty(obj, props.at(jj));
+ myAction.toValue = d->value;
+ data->actions << myAction;
+ }
+ }
+
+ if(data->actions.count()) {
+ d->spa->setAnimAction(data, QAbstractAnimation::DeleteWhenStopped);
+ } else {
+ delete data;
+ }
+}
+
+QML_DEFINE_TYPE(QmlSetPropertyAction,SetPropertyAction);
+
+/*!
+ \qmlclass ParentChangeAction QmlParentChangeAction
+ \inherits Animation
+ \brief The ParentChangeAction allows parent changes during transitions.
+
+ The ParentChangeAction is immediate - it is not animated in any way.
+*/
+
+QmlParentChangeAction::QmlParentChangeAction(QObject *parent)
+: QmlAbstractAnimation(*(new QmlParentChangeActionPrivate), parent)
+{
+ Q_D(QmlParentChangeAction);
+ d->init();
+}
+
+QmlParentChangeAction::~QmlParentChangeAction()
+{
+}
+
+void QmlParentChangeActionPrivate::init()
+{
+ Q_Q(QmlParentChangeAction);
+ cpa = new QActionAnimation(q);
+}
+
+void QmlParentChangeActionPrivate::doAction()
+{
+ //XXX property.write(value);
+}
+
+void QmlParentChangeAction::prepare(QmlMetaProperty &p)
+{
+ Q_D(QmlParentChangeAction);
+
+ if(d->userProperty.isNull)
+ d->property = p;
+ else
+ d->property = d->userProperty;
+
+ //XXX
+}
+
+QAbstractAnimation *QmlParentChangeAction::qtAnimation()
+{
+ Q_D(QmlParentChangeAction);
+ return d->cpa;
+}
+
+void QmlParentChangeAction::transition(QmlStateActions &actions,
+ QmlMetaProperties &modified,
+ TransitionDirection direction)
+{
+ Q_D(QmlParentChangeAction);
+ Q_UNUSED(direction);
+
+ struct QmlParentChangeActionData : public QAbstractAnimationAction
+ {
+ QmlStateActions actions;
+ virtual void doAction()
+ {
+ for(int ii = 0; ii < actions.count(); ++ii) {
+ const Action &action = actions.at(ii);
+ QmlBehaviour::_ignore = true;
+ action.property.write(action.toValue);
+ QmlBehaviour::_ignore = false;
+ }
+ }
+ };
+
+ QmlParentChangeActionData *data = new QmlParentChangeActionData;
+
+ QSet<QObject *> objs;
+ for(int ii = 0; ii < actions.count(); ++ii) {
+ Action &action = actions[ii];
+
+ QObject *obj = action.property.object();
+ QString propertyName = action.property.name();
+
+ if((!target() || target() == obj) && propertyName == QString(QLatin1String("moveToParent"))) {
+ objs.insert(obj);
+ Action myAction = action;
+
+ /*if(d->value.isValid())
+ myAction.toValue = d->value;*/
+
+ modified << action.property;
+ data->actions << myAction;
+ action.fromValue = myAction.toValue;
+ }
+ }
+
+ /*if(d->value.isValid() && target() && !objs.contains(target())) {
+ QObject *obj = target();
+ for(int jj = 0; jj < props.count(); ++jj) {
+ Action myAction;
+ myAction.property = QmlMetaProperty(obj, props.at(jj));
+ myAction.toValue = d->value;
+ data->actions << myAction;
+ }
+ }*/
+
+ if(data->actions.count()) {
+ d->cpa->setAnimAction(data, QAbstractAnimation::DeleteWhenStopped);
+ } else {
+ delete data;
+ }
+}
+
+QML_DEFINE_TYPE(QmlParentChangeAction,ParentChangeAction);
+
+/*!
+ \qmlclass NumericAnimation QmlNumericAnimation
+ \inherits Animation
+ \brief The NumericAnimation allows you to animate changes in properties of type qreal.
+
+ Animate a set of properties over 200ms, from their values in the start state to
+ their values in the end state of the transition:
+ \code
+ <NumericAnimation properties="x,y,scale" duration="200"/>
+ \endcode
+*/
+
+/*!
+ \internal
+ \class QmlNumericAnimation
+ \ingroup animation states
+ \brief The QmlNumericAnimation class allows you to animate changes in properties of type qreal.
+
+ A QmlNumericAnimation object can be instantiated in Qml using the tag
+ \ref xmlNumericAnimation "&lt;NumericAnimation&gt;".
+*/
+
+QmlNumericAnimation::QmlNumericAnimation(QObject *parent)
+: QmlAbstractAnimation(*(new QmlNumericAnimationPrivate), parent)
+{
+ Q_D(QmlNumericAnimation);
+ d->init();
+}
+
+QmlNumericAnimation::~QmlNumericAnimation()
+{
+}
+
+void QmlNumericAnimationPrivate::init()
+{
+ Q_Q(QmlNumericAnimation);
+ na = new GfxValueAnimator(q);
+ na->setStartValue(QVariant(0.0f));
+ na->setEndValue(QVariant(1.0f));
+}
+
+/*!
+ \qmlproperty int NumericAnimation::duration
+ This property holds the duration of the transition, in milliseconds.
+
+ The default value is 250.
+*/
+/*!
+ \property QmlNumericAnimation::duration
+ \brief the duration of the transition, in milliseconds.
+
+ The default value is 250.
+*/
+int QmlNumericAnimation::duration() const
+{
+ Q_D(const QmlNumericAnimation);
+ return d->na->duration();
+}
+
+void QmlNumericAnimation::setDuration(int duration)
+{
+ if(duration < 0) {
+ qWarning("QmlNumericAnimation: Cannot set a duration of < 0");
+ return;
+ }
+
+ Q_D(QmlNumericAnimation);
+ if(d->na->duration() == duration)
+ return;
+ d->na->setDuration(duration);
+ emit durationChanged(duration);
+}
+
+/*!
+ \qmlproperty real NumericAnimation::from
+ This property holds the starting value.
+ If not set, then the value defined in the start state of the transition.
+*/
+/*!
+ \property QmlNumericAnimation::from
+ \brief the starting value.
+*/
+qreal QmlNumericAnimation::from() const
+{
+ Q_D(const QmlNumericAnimation);
+ return d->from;
+}
+
+void QmlNumericAnimation::setFrom(qreal f)
+{
+ Q_D(QmlNumericAnimation);
+ if(!d->from.isNull && f == d->from)
+ return;
+ d->from = f;
+ emit fromChanged(f);
+}
+
+/*!
+ \qmlproperty real NumericAnimation::to
+ This property holds the ending value.
+ If not set, then the value defined in the end state of the transition.
+*/
+/*!
+ \property QmlNumericAnimation::to
+ \brief the ending value.
+*/
+qreal QmlNumericAnimation::to() const
+{
+ Q_D(const QmlNumericAnimation);
+ return d->to;
+}
+
+void QmlNumericAnimation::setTo(qreal t)
+{
+ Q_D(QmlNumericAnimation);
+ if(!d->to.isNull && t == d->to)
+ return;
+ d->to = t;
+ emit toChanged(t);
+}
+
+/* XML docs in GfxEasing */
+/*!
+ \property QmlNumericAnimation::easing
+ This property holds the easing curve to use.
+
+ \sa QEasingCurve
+*/
+QString QmlNumericAnimation::easing() const
+{
+ Q_D(const QmlNumericAnimation);
+ return d->easing;
+}
+
+void QmlNumericAnimation::setEasing(const QString &e)
+{
+ Q_D(QmlNumericAnimation);
+ if(d->easing == e)
+ return;
+
+ d->easing = e;
+ d->na->setEasingCurve(stringToCurve(d->easing));
+ emit easingChanged(e);
+}
+
+/*!
+ \qmlproperty string NumericAnimation::properties
+ This property holds the properties this animation should be applied to.
+
+ This is a comma-separated list of properties that should use
+ this animation when they change.
+*/
+/*!
+ \property QmlNumericAnimation::properties
+ \brief the properties this animation should be applied to.
+
+ properties holds a comma-separated list of properties that should use
+ this animation when they change.
+*/
+QString QmlNumericAnimation::properties() const
+{
+ Q_D(const QmlNumericAnimation);
+ return d->properties;
+}
+
+void QmlNumericAnimation::setProperties(const QString &prop)
+{
+ Q_D(QmlNumericAnimation);
+ if(d->properties == prop)
+ return;
+
+ d->properties = prop;
+ emit propertiesChanged(prop);
+}
+
+/*!
+ \qmlproperty list<Item> NumericAnimation::filter
+ This property holds the items selected to be affected by this animation (all if not set).
+ \sa exclude
+*/
+QList<QObject *> *QmlNumericAnimation::filter()
+{
+ Q_D(QmlNumericAnimation);
+ return &d->filter;
+}
+
+/*!
+ \qmlproperty list<Item> NumericAnimation::exclude
+ This property holds the items not to be affected by this animation.
+ \sa filter
+*/
+QList<QObject *> *QmlNumericAnimation::exclude()
+{
+ Q_D(QmlNumericAnimation);
+ return &d->exclude;
+}
+
+void QmlNumericAnimationPrivate::valueChanged(qreal r)
+{
+ if(!fromSourced) {
+ if(from.isNull) {
+ fromValue = qvariant_cast<qreal>(property.read());
+ } else {
+ fromValue = from;
+ }
+ fromSourced = true;
+ }
+
+ if(r == 1.) {
+ property.write(to.value);
+ } else {
+ qreal val = fromValue + (to-fromValue) * r;
+ property.write(val);
+ }
+}
+
+void QmlNumericAnimation::prepare(QmlMetaProperty &p)
+{
+ Q_D(QmlNumericAnimation);
+ if(d->userProperty.isNull)
+ d->property = p;
+ else
+ d->property = d->userProperty;
+ d->fromSourced = false;
+ d->value.GfxValue::setValue(0.);
+ d->na->setAnimValue(&d->value, QAbstractAnimation::KeepWhenStopped);
+}
+
+QAbstractAnimation *QmlNumericAnimation::qtAnimation()
+{
+ Q_D(QmlNumericAnimation);
+ return d->na;
+}
+
+void QmlNumericAnimation::transition(QmlStateActions &actions,
+ QmlMetaProperties &modified,
+ TransitionDirection direction)
+{
+ Q_D(QmlNumericAnimation);
+ Q_UNUSED(direction);
+
+ struct NTransitionData : public GfxValue
+ {
+ QmlStateActions actions;
+ void setValue(qreal v)
+ {
+ GfxValue::setValue(v);
+ for(int ii = 0; ii < actions.count(); ++ii) {
+ Action &action = actions[ii];
+
+ QmlBehaviour::_ignore = true;
+ if(v == 1.)
+ action.property.write(action.toValue.toDouble());
+ else {
+ if(action.fromValue.isNull()) {
+ action.fromValue = action.property.read();
+ if(action.fromValue.isNull()) {
+ action.fromValue = QVariant(0.);
+ }
+ }
+ qreal start = action.fromValue.toDouble();
+ qreal end = action.toValue.toDouble();
+ qreal val = start + (end-start) * v;
+ action.property.write(val);
+ }
+ QmlBehaviour::_ignore = false;
+ }
+ }
+ };
+
+ QStringList props = d->properties.split(QLatin1Char(','));
+ for(int ii = 0; ii < props.count(); ++ii)
+ props[ii] = props.at(ii).trimmed();
+ if(!d->propertyName.isEmpty() && !props.contains(d->propertyName))
+ props.append(d->propertyName);
+
+ NTransitionData *data = new NTransitionData;
+
+ QSet<QObject *> objs;
+ for(int ii = 0; ii < actions.count(); ++ii) {
+ Action &action = actions[ii];
+
+ QObject *obj = action.property.object();
+ QString propertyName = action.property.name();
+
+ if((d->filter.isEmpty() || d->filter.contains(obj)) &&
+ (!d->exclude.contains(obj)) && props.contains(propertyName) &&
+ (!target() || target() == obj)) {
+ objs.insert(obj);
+ Action myAction = action;
+ if(d->from.isValid()) {
+ myAction.fromValue = QVariant(d->from);
+ } else {
+ myAction.fromValue = QVariant();
+ }
+ if(d->to.isValid())
+ myAction.toValue = QVariant(d->to);
+
+ modified << action.property;
+
+ data->actions << myAction;
+ action.fromValue = myAction.toValue;
+ }
+ }
+
+ if(d->to.isValid() && target() && !objs.contains(target())) {
+ QObject *obj = target();
+ for(int jj = 0; jj < props.count(); ++jj) {
+ Action myAction;
+ myAction.property = QmlMetaProperty(obj, props.at(jj));
+
+ if(d->from.isValid())
+ myAction.fromValue = QVariant(d->from);
+
+ myAction.toValue = QVariant(d->to);
+ myAction.bv = 0;
+ myAction.event = 0;
+ data->actions << myAction;
+ }
+ }
+
+ if(data->actions.count()) {
+ d->na->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped);
+ } else {
+ delete data;
+ }
+}
+
+QML_DEFINE_TYPE(QmlNumericAnimation,NumericAnimation);
+
+QmlAnimationGroup::QmlAnimationGroup(QObject *parent)
+: QmlAbstractAnimation(*(new QmlAnimationGroupPrivate), parent)
+{
+}
+
+QmlAnimationGroup::~QmlAnimationGroup()
+{
+}
+
+QmlList<QmlAbstractAnimation *> *QmlAnimationGroup::animations()
+{
+ Q_D(QmlAnimationGroup);
+ return &d->animations;
+}
+
+/*!
+ \qmlclass SequentialAnimation QmlSequentialAnimation
+ \inherits Animation
+ \brief The SequentialAnimation allows you to run animations sequentially.
+
+ Animations controlled in SequentialAnimation will be run one after the other.
+
+ The following example chains two numeric animations together. The \c MyItem
+ object will animate from its current x position to 100, and then back to 0.
+
+ \code
+ <SequentialAnimation>
+ <NumericAnimation target="{MyItem}" property="x" to="100" />
+ <NumericAnimation target="{MyItem}" property="x" to="0" />
+ <SequentialAnimation>
+ \endcode
+
+ \sa ParallelAnimation
+*/
+
+QmlSequentialAnimation::QmlSequentialAnimation(QObject *parent) :
+ QmlAnimationGroup(parent)
+{
+ Q_D(QmlAnimationGroup);
+ d->ag = new QSequentialAnimationGroup(this);
+}
+
+QmlSequentialAnimation::~QmlSequentialAnimation()
+{
+}
+
+void QmlSequentialAnimation::prepare(QmlMetaProperty &p)
+{
+ Q_D(QmlAnimationGroup);
+ if(d->userProperty.isNull)
+ d->property = p;
+ else
+ d->property = d->userProperty;
+
+ for (int i = 0; i < d->animations.size(); ++i)
+ d->animations.at(i)->prepare(d->property);
+}
+
+QAbstractAnimation *QmlSequentialAnimation::qtAnimation()
+{
+ Q_D(QmlAnimationGroup);
+ return d->ag;
+}
+
+void QmlSequentialAnimation::transition(QmlStateActions &actions,
+ QmlMetaProperties &modified,
+ TransitionDirection direction)
+{
+ Q_D(QmlAnimationGroup);
+
+ int inc = 1;
+ int from = 0;
+ if(direction == Backward) {
+ inc = -1;
+ from = d->animations.count() - 1;
+ }
+
+ //XXX removing and readding isn't ideal; we do it to get around the problem mentioned below.
+ for (int i = d->ag->animationCount()-1; i >= 0; --i)
+ d->ag->takeAnimationAt(i);
+
+ for(int ii = from; ii < d->animations.count() && ii >= 0; ii += inc) {
+ d->animations.at(ii)->transition(actions, modified, direction);
+ d->ag->addAnimation(d->animations.at(ii)->qtAnimation());
+ }
+
+ //XXX changing direction means all the animations play in reverse, while we only want the ordering reversed.
+ //d->ag->setDirection(direction == Backward ? QAbstractAnimation::Backward : QAbstractAnimation::Forward);
+}
+
+QML_DEFINE_TYPE(QmlSequentialAnimation,SequentialAnimation);
+
+/*!
+ \qmlclass ParallelAnimation QmlParallelAnimation
+ \inherits Animation
+ \brief The ParallelAnimation allows you to run animations in parallel.
+
+ Animations contained in ParallelAnimation will be run at the same time.
+
+ The following animation demonstrates animating the \c MyItem item
+ to (100,100) by animating the x and y properties in parallel.
+
+ \code
+ <ParallelAnimation>
+ <NumericAnimation target="{MyItem}" property="x" to="100" />
+ <NumericAnimation target="{MyItem}" property="y" to="100" />
+ </ParallelAnimation>
+ \endcode
+
+ \sa SequentialAnimation
+*/
+/*!
+ \internal
+ \class QmlParallelAnimation
+ \ingroup animation states
+ \brief The QmlParallelAnimation class allows you to run animations in parallel.
+
+ Animations controlled by QmlParallelAnimation will be run at the same time.
+
+ \sa QmlSequentialAnimation
+
+ A QmlParallelAnimation object can be instantiated in Qml using the tag
+ \ref xmlParallelAnimation "&lt;ParallelAnimation&gt;".
+*/
+
+QmlParallelAnimation::QmlParallelAnimation(QObject *parent) :
+ QmlAnimationGroup(parent)
+{
+ Q_D(QmlAnimationGroup);
+ d->ag = new QParallelAnimationGroup(this);
+}
+
+QmlParallelAnimation::~QmlParallelAnimation()
+{
+}
+
+void QmlParallelAnimation::prepare(QmlMetaProperty &p)
+{
+ Q_D(QmlAnimationGroup);
+ if(d->userProperty.isNull)
+ d->property = p;
+ else
+ d->property = d->userProperty;
+
+ for (int i = 0; i < d->animations.size(); ++i)
+ d->animations.at(i)->prepare(d->property);
+}
+
+QAbstractAnimation *QmlParallelAnimation::qtAnimation()
+{
+ Q_D(QmlAnimationGroup);
+ return d->ag;
+}
+
+void QmlParallelAnimation::transition(QmlStateActions &actions,
+ QmlMetaProperties &modified,
+ TransitionDirection direction)
+{
+ Q_D(QmlAnimationGroup);
+
+ for(int ii = 0; ii < d->animations.count(); ++ii) {
+ d->animations.at(ii)->transition(actions, modified, direction);
+ }
+}
+
+QML_DEFINE_TYPE(QmlParallelAnimation,ParallelAnimation);
+
+//XXX it would be good to use QVariantAnimation's interpolators if possible
+QVariant QmlVariantAnimationPrivate::interpolateVariant(const QVariant &from, const QVariant &to, qreal progress)
+{
+ if (from.userType() != to.userType())
+ return QVariant();
+
+ QVariant res;
+ switch (from.userType()) {
+ case QVariant::Int: {
+ int f = from.toInt();
+ int t = to.toInt();
+ res = f + (t - f) * progress;
+ break;
+ }
+ case QVariant::Double: {
+ double f = from.toDouble();
+ double t = to.toDouble();
+ res = f + (t - f) * progress;
+ break;
+ }
+ case QMetaType::Float: {
+ float f = from.toDouble();
+ float t = to.toDouble();
+ res = f + (t - f) * progress;
+ break;
+ }
+ case QVariant::Color: {
+ QColor f = from.value<QColor>();
+ QColor t = to.value<QColor>();
+ uint red = uint(qreal(f.red()) + progress * (qreal(t.red()) - qreal(f.red())));
+ uint green = uint(qreal(f.green()) + progress * (qreal(t.green()) - qreal(f.green())));
+ uint blue = uint(qreal(f.blue()) + progress * (qreal(t.blue()) - qreal(f.blue())));
+ res = QColor(red,green,blue);
+ break;
+ }
+ case QVariant::Rect: {
+ QRect f = from.value<QRect>();
+ QRect t = to.value<QRect>();
+ int x = f.x() + (t.x() - f.x()) * progress;
+ int y = f.y() + (t.y() - f.y()) * progress;
+ int w = f.width() + (t.width() - f.width()) * progress;
+ int h = f.height() + (t.height() - f.height()) * progress;
+ res = QRect(x, y, w, h);
+ break;
+ }
+ case QVariant::RectF: {
+ QRectF f = from.value<QRectF>();
+ QRectF t = to.value<QRectF>();
+ qreal x = f.x() + (t.x() - f.x()) * progress;
+ qreal y = f.y() + (t.y() - f.y()) * progress;
+ qreal w = f.width() + (t.width() - f.width()) * progress;
+ qreal h = f.height() + (t.height() - f.height()) * progress;
+ res = QRectF(x, y, w, h);
+ break;
+ }
+ case QVariant::Point: {
+ QPoint f = from.value<QPoint>();
+ QPoint t = to.value<QPoint>();
+ int x = f.x() + (t.x() - f.x()) * progress;
+ int y = f.y() + (t.y() - f.y()) * progress;
+ res = QPointF(x, y);
+ break;
+ }
+ case QVariant::PointF: {
+ QPointF f = from.value<QPointF>();
+ QPointF t = to.value<QPointF>();
+ qreal x = f.x() + (t.x() - f.x()) * progress;
+ qreal y = f.y() + (t.y() - f.y()) * progress;
+ res = QPointF(x, y);
+ break;
+ }
+ case QVariant::Size: {
+ QSize f = from.value<QSize>();
+ QSize t = to.value<QSize>();
+ int w = f.width() + (t.width() - f.width()) * progress;
+ int h = f.height() + (t.height() - f.height()) * progress;
+ res = QSize(w, h);
+ break;
+ }
+ case QVariant::SizeF: {
+ QSizeF f = from.value<QSizeF>();
+ QSizeF t = to.value<QSizeF>();
+ qreal w = f.width() + (t.width() - f.width()) * progress;
+ qreal h = f.height() + (t.height() - f.height()) * progress;
+ res = QSizeF(w, h);
+ break;
+ }
+ default:
+ res = to;
+ break;
+ }
+
+ return res;
+}
+
+//convert a variant from string type to another animatable type
+void QmlVariantAnimationPrivate::convertVariant(QVariant &variant, QVariant::Type type)
+{
+ if (variant.type() != QVariant::String) {
+ variant.convert(type);
+ return;
+ }
+
+ switch (type) {
+ case QVariant::Rect: {
+ variant.setValue(QmlStringConverters::rectFFromString(variant.toString()).toRect());
+ break;
+ }
+ case QVariant::RectF: {
+ variant.setValue(QmlStringConverters::rectFFromString(variant.toString()));
+ break;
+ }
+ case QVariant::Point: {
+ variant.setValue(QmlStringConverters::pointFFromString(variant.toString()).toPoint());
+ break;
+ }
+ case QVariant::PointF: {
+ variant.setValue(QmlStringConverters::pointFFromString(variant.toString()));
+ break;
+ }
+ case QVariant::Size: {
+ variant.setValue(QmlStringConverters::sizeFFromString(variant.toString()).toSize());
+ break;
+ }
+ case QVariant::SizeF: {
+ variant.setValue(QmlStringConverters::sizeFFromString(variant.toString()));
+ break;
+ }
+ case QVariant::Color: {
+ variant.setValue(QmlStringConverters::colorFromString(variant.toString()));
+ break;
+ }
+ default:
+ variant.convert(type);
+ break;
+ }
+}
+
+/*!
+ \qmlclass VariantAnimation QmlVariantAnimation
+ \inherits Animation
+ \brief The VariantAnimation allows you to animate changes in properties of type QVariant.
+
+ Animate a size property over 200ms, from its current size to 20-by-20:
+ \code
+ <VariantAnimation property="size" to="20x20" duration="200"/>
+ \endcode
+*/
+
+QmlVariantAnimation::QmlVariantAnimation(QObject *parent)
+: QmlAbstractAnimation(*(new QmlVariantAnimationPrivate), parent)
+{
+ Q_D(QmlVariantAnimation);
+ d->init();
+}
+
+QmlVariantAnimation::~QmlVariantAnimation()
+{
+}
+
+void QmlVariantAnimationPrivate::init()
+{
+ Q_Q(QmlVariantAnimation);
+ va = new GfxValueAnimator(q);
+ va->setStartValue(QVariant(0.0f));
+ va->setEndValue(QVariant(1.0f));
+}
+
+/*!
+ \qmlproperty int VariantAnimation::duration
+ This property holds the duration of the transition, in milliseconds.
+
+ The default value is 250.
+*/
+/*!
+ \property QmlVariantAnimation::duration
+ \brief the duration of the transition, in milliseconds.
+
+ The default value is 250.
+*/
+int QmlVariantAnimation::duration() const
+{
+ Q_D(const QmlVariantAnimation);
+ return d->va->duration();
+}
+
+void QmlVariantAnimation::setDuration(int duration)
+{
+ if(duration < 0) {
+ qWarning("QmlVariantAnimation: Cannot set a duration of < 0");
+ return;
+ }
+
+ Q_D(QmlVariantAnimation);
+ if(d->va->duration() == duration)
+ return;
+ d->va->setDuration(duration);
+ emit durationChanged(duration);
+}
+
+/*!
+ \qmlproperty real VariantAnimation::from
+ This property holds the starting value.
+ If not set, then the value defined in the start state of the transition.
+*/
+/*!
+ \property QmlVariantAnimation::from
+ \brief the starting value.
+*/
+QVariant QmlVariantAnimation::from() const
+{
+ Q_D(const QmlVariantAnimation);
+ return d->from;
+}
+
+void QmlVariantAnimation::setFrom(const QVariant &f)
+{
+ Q_D(QmlVariantAnimation);
+ if(!d->from.isNull && f == d->from)
+ return;
+ d->from = f;
+ emit fromChanged(f);
+}
+
+/*!
+ \qmlproperty real VariantAnimation::to
+ This property holds the ending value.
+ If not set, then the value defined in the end state of the transition.
+*/
+/*!
+ \property QmlVariantAnimation::to
+ \brief the ending value.
+*/
+QVariant QmlVariantAnimation::to() const
+{
+ Q_D(const QmlVariantAnimation);
+ return d->to;
+}
+
+void QmlVariantAnimation::setTo(const QVariant &t)
+{
+ Q_D(QmlVariantAnimation);
+ if(!d->to.isNull && t == d->to)
+ return;
+ d->to = t;
+ emit toChanged(t);
+}
+
+/*!
+ \qmlproperty string VariantAnimation::easing
+ This property holds the easing curve used for the transition.
+
+ See NumericAnimation::easing for a full discussion of easing,
+ and a list of available curves.
+*/
+
+/*!
+ \property QmlVariantAnimation::easing
+ \brief the easing curve to use.
+
+ \sa QEasingCurve
+*/
+QString QmlVariantAnimation::easing() const
+{
+ Q_D(const QmlVariantAnimation);
+ return d->easing;
+}
+
+void QmlVariantAnimation::setEasing(const QString &e)
+{
+ Q_D(QmlVariantAnimation);
+ if(d->easing == e)
+ return;
+
+ d->easing = e;
+ d->va->setEasingCurve(stringToCurve(d->easing));
+ emit easingChanged(e);
+}
+
+/*!
+ \qmlproperty string VariantAnimation::properties
+ This property holds the properties this animation should be applied to.
+
+ This is a comma-separated list of properties that should use
+ this animation when they change.
+*/
+/*!
+ \property QmlVariantAnimation::properties
+ \brief the properties this animation should be applied to
+
+ properties holds a copy separated list of properties that should use
+ this animation when they change.
+*/
+QString QmlVariantAnimation::properties() const
+{
+ Q_D(const QmlVariantAnimation);
+ return d->properties;
+}
+
+void QmlVariantAnimation::setProperties(const QString &prop)
+{
+ Q_D(QmlVariantAnimation);
+ if(d->properties == prop)
+ return;
+
+ d->properties = prop;
+ emit propertiesChanged(prop);
+}
+
+/*!
+ \qmlproperty list<Item> VariantAnimation::filter
+ This property holds the items selected to be affected by this animation (all if not set).
+ \sa exclude
+*/
+QList<QObject *> *QmlVariantAnimation::filter()
+{
+ Q_D(QmlVariantAnimation);
+ return &d->filter;
+}
+
+/*!
+ \qmlproperty list<Item> VariantAnimation::exclude
+ This property holds the items not to be affected by this animation.
+ \sa filter
+*/
+QList<QObject *> *QmlVariantAnimation::exclude()
+{
+ Q_D(QmlVariantAnimation);
+ return &d->exclude;
+}
+
+void QmlVariantAnimationPrivate::valueChanged(qreal r)
+{
+ if(!fromSourced) {
+ if(from.isNull) {
+ fromValue = property.read();
+ } else {
+ fromValue = from;
+ }
+ fromSourced = true;
+ }
+
+ if(r == 1.) {
+ property.write(to.value);
+ } else {
+ QVariant val = interpolateVariant(fromValue, to.value, r);
+ property.write(val);
+ }
+}
+
+QAbstractAnimation *QmlVariantAnimation::qtAnimation()
+{
+ Q_D(QmlVariantAnimation);
+ return d->va;
+}
+
+void QmlVariantAnimation::prepare(QmlMetaProperty &p)
+{
+ Q_D(QmlVariantAnimation);
+ if(d->userProperty.isNull)
+ d->property = p;
+ else
+ d->property = d->userProperty;
+
+ d->convertVariant(d->to.value, (QVariant::Type)d->property.propertyType());
+ if (!d->from.isNull)
+ d->convertVariant(d->from.value, (QVariant::Type)d->property.propertyType());
+
+ d->fromSourced = false;
+ d->value.GfxValue::setValue(0.);
+ d->va->setAnimValue(&d->value, QAbstractAnimation::KeepWhenStopped);
+}
+
+void QmlVariantAnimation::transition(QmlStateActions &actions,
+ QmlMetaProperties &modified,
+ TransitionDirection direction)
+{
+ Q_D(QmlVariantAnimation);
+ Q_UNUSED(direction);
+
+ struct NTransitionData : public GfxValue
+ {
+ QmlStateActions actions;
+ void setValue(qreal v)
+ {
+ GfxValue::setValue(v);
+ for(int ii = 0; ii < actions.count(); ++ii) {
+ Action &action = actions[ii];
+
+ if(v == 1.)
+ action.property.write(action.toValue);
+ else {
+ if(action.fromValue.isNull()) {
+ action.fromValue = action.property.read();
+ /*if(action.fromValue.isNull())
+ action.fromValue = QVariant(0.);*/ //XXX can we give a default value for any type?
+ }
+ QVariant val = QmlVariantAnimationPrivate::interpolateVariant(action.fromValue, action.toValue, v);
+ action.property.write(val);
+ }
+ }
+ }
+ };
+
+ QStringList props = d->properties.split(QLatin1Char(','));
+ for(int ii = 0; ii < props.count(); ++ii)
+ props[ii] = props.at(ii).trimmed();
+ if(!d->propertyName.isEmpty() && !props.contains(d->propertyName))
+ props.append(d->propertyName);
+
+ NTransitionData *data = new NTransitionData;
+
+ QSet<QObject *> objs;
+ for(int ii = 0; ii < actions.count(); ++ii) {
+ Action &action = actions[ii];
+
+ QObject *obj = action.property.object();
+ QString propertyName = action.property.name();
+
+ if((d->filter.isEmpty() || d->filter.contains(obj)) &&
+ (!d->exclude.contains(obj)) && props.contains(propertyName) &&
+ (!target() || target() == obj)) {
+ objs.insert(obj);
+ Action myAction = action;
+
+ if(d->from.isValid())
+ myAction.fromValue = QVariant(d->from);
+ if(d->to.isValid())
+ myAction.toValue = QVariant(d->to);
+
+ d->convertVariant(myAction.fromValue, (QVariant::Type)myAction.property.propertyType());
+ d->convertVariant(myAction.toValue, (QVariant::Type)myAction.property.propertyType());
+
+ modified << action.property;
+
+ data->actions << myAction;
+ action.fromValue = myAction.toValue;
+ }
+ }
+
+ if(d->to.isValid() && target() && !objs.contains(target())) {
+ QObject *obj = target();
+ for(int jj = 0; jj < props.count(); ++jj) {
+ Action myAction;
+ myAction.property = QmlMetaProperty(obj, props.at(jj));
+
+ if(d->from.isValid()) {
+ d->convertVariant(d->from.value, (QVariant::Type)myAction.property.propertyType());
+ myAction.fromValue = QVariant(d->from);
+ }
+
+ d->convertVariant(d->to.value, (QVariant::Type)myAction.property.propertyType());
+ myAction.toValue = QVariant(d->to);
+ myAction.bv = 0;
+ myAction.event = 0;
+ data->actions << myAction;
+ }
+ }
+
+ if(data->actions.count()) {
+ d->va->setAnimValue(data, QAbstractAnimation::DeleteWhenStopped);
+ } else {
+ delete data;
+ }
+}
+
+//XXX whats the best name for this? (just Animation?)
+QML_DEFINE_TYPE(QmlVariantAnimation,VariantAnimation);
+
+
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qmlanimation.h b/src/declarative/util/qmlanimation.h
new file mode 100644
index 0000000..578631c
--- /dev/null
+++ b/src/declarative/util/qmlanimation.h
@@ -0,0 +1,453 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLANIMATION_H
+#define QMLANIMATION_H
+
+#include <QtCore/qvariant.h>
+#include <QtGui/qcolor.h>
+#include <qmltransition.h>
+#include <qmlpropertyvaluesource.h>
+#include <qmlstate.h>
+#include <qml.h>
+#include <QAbstractAnimation>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QmlAbstractAnimationPrivate;
+class QmlAnimationGroup;
+class QmlAbstractAnimation : public QmlPropertyValueSource, public QmlParserStatus
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlAbstractAnimation)
+
+ Q_INTERFACES(QmlParserStatus);
+ Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged);
+ Q_PROPERTY(bool finishPlaying READ finishPlaying WRITE setFinishPlaying NOTIFY finishPlayingChanged());
+ Q_PROPERTY(bool repeat READ repeat WRITE setRepeat NOTIFY repeatChanged);
+ Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged);
+ Q_PROPERTY(QString property READ property WRITE setProperty NOTIFY targetChanged);
+ Q_CLASSINFO("DefaultMethod", "start()");
+ Q_INTERFACES(QmlParserStatus)
+
+public:
+ QmlAbstractAnimation(QObject *parent=0);
+ virtual ~QmlAbstractAnimation();
+
+ bool isRunning() const;
+ void setRunning(bool);
+ bool finishPlaying() const;
+ void setFinishPlaying(bool);
+ bool repeat() const;
+ void setRepeat(bool);
+
+ QmlAnimationGroup *group() const;
+ void setGroup(QmlAnimationGroup *);
+
+ QObject *target() const;
+ void setTarget(QObject *);
+ QString property() const;
+ void setProperty(const QString &);
+
+ void classBegin();
+ void componentComplete();
+
+Q_SIGNALS:
+ void started();
+ void completed();
+ void runningChanged(bool);
+ void repeatChanged(bool);
+ void targetChanged(QObject *, const QString &);
+ void finishPlayingChanged(bool);
+
+public Q_SLOTS:
+ void restart();
+ void start();
+ void stop();
+ void complete();
+
+protected:
+ virtual void setTarget(const QmlMetaProperty &);
+ QmlAbstractAnimation(QmlAbstractAnimationPrivate &dd, QObject *parent);
+
+public:
+ enum TransitionDirection { Forward, Backward };
+ virtual void transition(QmlStateActions &actions,
+ QmlMetaProperties &modified,
+ TransitionDirection direction);
+ virtual void prepare(QmlMetaProperty &);
+ virtual QAbstractAnimation *qtAnimation() = 0;
+
+private Q_SLOTS:
+ void timelineComplete();
+};
+
+QML_DECLARE_TYPE(QmlAbstractAnimation);
+
+class QmlPauseAnimationPrivate;
+class QmlPauseAnimation : public QmlAbstractAnimation
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlPauseAnimation);
+
+ Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged);
+
+public:
+ QmlPauseAnimation(QObject *parent=0);
+ virtual ~QmlPauseAnimation();
+
+ int duration() const;
+ void setDuration(int);
+
+Q_SIGNALS:
+ void durationChanged(int);
+
+protected:
+ virtual QAbstractAnimation *qtAnimation();
+ virtual void prepare(QmlMetaProperty &);
+};
+QML_DECLARE_TYPE(QmlPauseAnimation);
+
+class QmlColorAnimationPrivate;
+class QmlColorAnimation : public QmlAbstractAnimation
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlColorAnimation);
+ Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged);
+ Q_PROPERTY(QColor from READ from WRITE setFrom NOTIFY fromChanged);
+ Q_PROPERTY(QColor to READ to WRITE setTo NOTIFY toChanged);
+ Q_PROPERTY(QString easing READ easing WRITE setEasing NOTIFY easingChanged);
+ Q_PROPERTY(QList<QObject *>* filter READ filter);
+ Q_PROPERTY(QList<QObject *>* exclude READ exclude);
+
+public:
+ QmlColorAnimation(QObject *parent=0);
+ virtual ~QmlColorAnimation();
+
+ int duration() const;
+ void setDuration(int);
+
+ QColor from() const;
+ void setFrom(const QColor &);
+
+ QColor to() const;
+ void setTo(const QColor &);
+
+ QString easing() const;
+ void setEasing(const QString &);
+
+ QList<QObject *> *filter();
+
+ QList<QObject *> *exclude();
+
+protected:
+ virtual void transition(QmlStateActions &actions,
+ QmlMetaProperties &modified,
+ TransitionDirection direction);
+ virtual QAbstractAnimation *qtAnimation();
+ virtual void prepare(QmlMetaProperty &);
+
+Q_SIGNALS:
+ void durationChanged(int);
+ void fromChanged(const QColor &);
+ void toChanged(const QColor &);
+ void easingChanged(const QString &);
+};
+QML_DECLARE_TYPE(QmlColorAnimation);
+
+class QmlRunScriptActionPrivate;
+class QmlRunScriptAction : public QmlAbstractAnimation
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlRunScriptAction);
+
+ Q_PROPERTY(QString script READ script WRITE setScript NOTIFY scriptChanged);
+ Q_PROPERTY(QString file READ file WRITE setFile NOTIFY fileChanged);
+
+public:
+ QmlRunScriptAction(QObject *parent=0);
+ virtual ~QmlRunScriptAction();
+
+ QString script() const;
+ void setScript(const QString &);
+
+ QString file() const;
+ void setFile(const QString &);
+
+Q_SIGNALS:
+ void fileChanged(const QString &);
+ void scriptChanged(const QString &);
+
+protected:
+ virtual QAbstractAnimation *qtAnimation();
+};
+QML_DECLARE_TYPE(QmlRunScriptAction);
+
+class QmlSetPropertyActionPrivate;
+class QmlSetPropertyAction : public QmlAbstractAnimation
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlSetPropertyAction);
+
+ Q_PROPERTY(QString properties READ properties WRITE setProperties NOTIFY propertiesChanged);
+ Q_PROPERTY(QList<QObject *>* filter READ filter);
+ Q_PROPERTY(QList<QObject *>* exclude READ exclude);
+ Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged);
+
+public:
+ QmlSetPropertyAction(QObject *parent=0);
+ virtual ~QmlSetPropertyAction();
+
+ QString properties() const;
+ void setProperties(const QString &);
+
+ QList<QObject *> *filter();
+ QList<QObject *> *exclude();
+
+ QVariant value() const;
+ void setValue(const QVariant &);
+
+Q_SIGNALS:
+ void valueChanged(const QVariant &);
+ void propertiesChanged(const QString &);
+
+protected:
+ virtual void transition(QmlStateActions &actions,
+ QmlMetaProperties &modified,
+ TransitionDirection direction);
+ virtual QAbstractAnimation *qtAnimation();
+ virtual void prepare(QmlMetaProperty &);
+};
+QML_DECLARE_TYPE(QmlSetPropertyAction);
+
+class QmlParentChangeActionPrivate;
+class QmlParentChangeAction : public QmlAbstractAnimation
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlParentChangeAction);
+
+ //XXX should have parent property as well for when it isn't part of a transition
+
+public:
+ QmlParentChangeAction(QObject *parent=0);
+ virtual ~QmlParentChangeAction();
+
+protected:
+ virtual void transition(QmlStateActions &actions,
+ QmlMetaProperties &modified,
+ TransitionDirection direction);
+ virtual QAbstractAnimation *qtAnimation();
+ virtual void prepare(QmlMetaProperty &);
+};
+QML_DECLARE_TYPE(QmlParentChangeAction);
+
+class QmlNumericAnimationPrivate;
+class QmlNumericAnimation : public QmlAbstractAnimation
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlNumericAnimation);
+
+ Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged);
+ Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged);
+ Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged);
+ Q_PROPERTY(QString easing READ easing WRITE setEasing NOTIFY easingChanged);
+ Q_PROPERTY(QString properties READ properties WRITE setProperties NOTIFY propertiesChanged);
+ Q_PROPERTY(QList<QObject *>* filter READ filter);
+ Q_PROPERTY(QList<QObject *>* exclude READ exclude);
+
+public:
+ QmlNumericAnimation(QObject *parent=0);
+ virtual ~QmlNumericAnimation();
+
+ int duration() const;
+ void setDuration(int);
+
+ qreal from() const;
+ void setFrom(qreal);
+
+ qreal to() const;
+ void setTo(qreal);
+
+ QString easing() const;
+ void setEasing(const QString &);
+
+ QString properties() const;
+ void setProperties(const QString &);
+
+ QList<QObject *> *filter();
+ QList<QObject *> *exclude();
+
+protected:
+ virtual void transition(QmlStateActions &actions,
+ QmlMetaProperties &modified,
+ TransitionDirection direction);
+ virtual QAbstractAnimation *qtAnimation();
+ virtual void prepare(QmlMetaProperty &);
+
+Q_SIGNALS:
+ void durationChanged(int);
+ void fromChanged(qreal);
+ void toChanged(qreal);
+ void easingChanged(const QString &);
+ void propertiesChanged(const QString &);
+};
+QML_DECLARE_TYPE(QmlNumericAnimation);
+
+#if 0
+class QmlDiscreteAnimation : public QmlAbstractAnimation
+{
+Q_OBJECT
+};
+#endif
+
+class QmlAnimationGroupPrivate;
+class QmlAnimationGroup : public QmlAbstractAnimation
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlAnimationGroup);
+
+ Q_CLASSINFO("DefaultProperty", "animations");
+ Q_PROPERTY(QmlList<QmlAbstractAnimation *> *animations READ animations);
+
+public:
+ QmlAnimationGroup(QObject *parent);
+ virtual ~QmlAnimationGroup();
+
+ QmlList<QmlAbstractAnimation *>* animations();
+};
+
+class QmlSequentialAnimation : public QmlAnimationGroup
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlAnimationGroup);
+
+public:
+ QmlSequentialAnimation(QObject *parent=0);
+ virtual ~QmlSequentialAnimation();
+
+protected:
+ virtual void transition(QmlStateActions &actions,
+ QmlMetaProperties &modified,
+ TransitionDirection direction);
+ virtual QAbstractAnimation *qtAnimation();
+ virtual void prepare(QmlMetaProperty &);
+};
+QML_DECLARE_TYPE(QmlSequentialAnimation);
+
+class QmlParallelAnimation : public QmlAnimationGroup
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlAnimationGroup);
+
+public:
+ QmlParallelAnimation(QObject *parent=0);
+ virtual ~QmlParallelAnimation();
+
+protected:
+ virtual void transition(QmlStateActions &actions,
+ QmlMetaProperties &modified,
+ TransitionDirection direction);
+ virtual QAbstractAnimation *qtAnimation();
+ virtual void prepare(QmlMetaProperty &);
+};
+QML_DECLARE_TYPE(QmlParallelAnimation);
+
+class QmlVariantAnimationPrivate;
+class QmlVariantAnimation : public QmlAbstractAnimation
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlVariantAnimation);
+
+ Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged);
+ Q_PROPERTY(QVariant from READ from WRITE setFrom NOTIFY fromChanged);
+ Q_PROPERTY(QVariant to READ to WRITE setTo NOTIFY toChanged);
+ Q_PROPERTY(QString easing READ easing WRITE setEasing NOTIFY easingChanged);
+ Q_PROPERTY(QString properties READ properties WRITE setProperties NOTIFY propertiesChanged);
+ Q_PROPERTY(QList<QObject *>* filter READ filter);
+ Q_PROPERTY(QList<QObject *>* exclude READ exclude);
+
+public:
+ QmlVariantAnimation(QObject *parent=0);
+ virtual ~QmlVariantAnimation();
+
+ int duration() const;
+ void setDuration(int);
+
+ QVariant from() const;
+ void setFrom(const QVariant &);
+
+ QVariant to() const;
+ void setTo(const QVariant &);
+
+ QString easing() const;
+ void setEasing(const QString &);
+
+ QString properties() const;
+ void setProperties(const QString &);
+
+ QList<QObject *> *filter();
+ QList<QObject *> *exclude();
+
+protected:
+ virtual void transition(QmlStateActions &actions,
+ QmlMetaProperties &modified,
+ TransitionDirection direction);
+ virtual QAbstractAnimation *qtAnimation();
+ virtual void prepare(QmlMetaProperty &);
+
+Q_SIGNALS:
+ void durationChanged(int);
+ void fromChanged(QVariant);
+ void toChanged(QVariant);
+ void easingChanged(const QString &);
+ void propertiesChanged(const QString &);
+};
+QML_DECLARE_TYPE(QmlVariantAnimation);
+
+#endif // QMLANIMATION_H
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
diff --git a/src/declarative/util/qmlanimation_p.h b/src/declarative/util/qmlanimation_p.h
new file mode 100644
index 0000000..db7cb18
--- /dev/null
+++ b/src/declarative/util/qmlanimation_p.h
@@ -0,0 +1,374 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLANIMATION_P_H
+#define QMLANIMATION_P_H
+
+#include <private/qobject_p.h>
+#include <private/qmlnullablevalue_p.h>
+#include <qmlanimation.h>
+#include <qml.h>
+#include <qmlcontext.h>
+#include <private/qvariantanimation_p.h>
+#include <QPauseAnimation>
+#include <QVariantAnimation>
+#include <QAnimationGroup>
+#include <QColor>
+#include <gfxvalueproxy.h>
+
+QT_BEGIN_NAMESPACE
+
+//interface for classes that provide animation actions for QActionAnimation
+class QAbstractAnimationAction
+{
+public:
+ virtual ~QAbstractAnimationAction() {}
+ virtual void doAction() = 0;
+};
+
+//templated animation action
+//allows us to specify an action that calls a function of a class.
+//(so that class doesn't have to inherit QmlAbstractAnimationAction)
+template<class T, void (T::*method)()>
+class QAnimationActionProxy : public QAbstractAnimationAction
+{
+public:
+ QAnimationActionProxy(T *p) : m_p(p) {}
+ virtual void doAction() { (m_p->*method)(); }
+
+private:
+ T *m_p;
+};
+
+//performs an action of type QAbstractAnimationAction
+class QActionAnimation : public QAbstractAnimation
+{
+public:
+ QActionAnimation(QObject *parent = 0) : QAbstractAnimation(parent), animAction(0), policy(KeepWhenStopped) {}
+ QActionAnimation(QAbstractAnimationAction *action, QObject *parent = 0)
+ : QAbstractAnimation(parent), animAction(action), policy(KeepWhenStopped) {}
+ virtual int duration() const { return 0; }
+ void setAnimAction(QAbstractAnimationAction *action, DeletionPolicy p)
+ {
+ if (state() == Running)
+ stop();
+ animAction = action;
+ policy = p;
+ }
+protected:
+ virtual void updateCurrentTime(int) {}
+
+ virtual void updateState(State /*oldState*/, State newState)
+ {
+ if (newState == Running) {
+ if (animAction)
+ animAction->doAction();
+ } else if (newState == Stopped && policy == DeleteWhenStopped) {
+ delete animAction;
+ animAction = 0;
+ }
+ }
+
+private:
+ QAbstractAnimationAction *animAction;
+ DeletionPolicy policy;
+};
+
+//animates GfxValue (assumes start and end values will be reals or compatible)
+class GfxValueAnimator : public QVariantAnimation
+{
+public:
+ GfxValueAnimator(QObject *parent = 0) : QVariantAnimation(parent), animValue(0), policy(KeepWhenStopped) {}
+ GfxValueAnimator(GfxValue *value, QObject *parent = 0) : QVariantAnimation(parent), animValue(value), policy(KeepWhenStopped) {}
+ void setAnimValue(GfxValue *value, DeletionPolicy p)
+ {
+ if (state() == Running)
+ stop();
+ animValue = value;
+ policy = p;
+ }
+protected:
+ virtual void updateCurrentValue(const QVariant &value)
+ {
+ if (animValue)
+ animValue->setValue(value.toDouble());
+ }
+ virtual void updateState(State oldState, State newState)
+ {
+ QVariantAnimation::updateState(oldState, newState);
+ if (newState == Stopped && policy == DeleteWhenStopped) {
+ delete animValue;
+ animValue = 0;
+ }
+ }
+
+private:
+ GfxValue *animValue;
+ DeletionPolicy policy;
+};
+
+//an animation that just gives a tick
+template<class T, void (T::*method)(int)>
+class QTickAnimationProxy : public QAbstractAnimation
+{
+public:
+ QTickAnimationProxy(T *p, QObject *parent = 0) : QAbstractAnimation(parent), m_p(p) {}
+ virtual int duration() const { return -1; }
+protected:
+ virtual void updateCurrentTime(int msec) { (m_p->*method)(msec); }
+
+private:
+ T *m_p;
+};
+
+class QmlAbstractAnimationPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QmlAbstractAnimation);
+public:
+ QmlAbstractAnimationPrivate()
+ : running(false), finishPlaying(false), repeat(false),
+ connectedTimeLine(false), componentComplete(true), startOnCompletion(false),
+ target(0), group(0) {}
+
+ bool running;
+ bool finishPlaying;
+ bool repeat;
+ bool connectedTimeLine;
+
+ bool componentComplete;
+ bool startOnCompletion;
+
+ void commence();
+
+ QmlNullableValue<QmlMetaProperty> userProperty;
+ QObject *target;
+ QString propertyName;
+
+ QmlMetaProperty property;
+ QmlAnimationGroup *group;
+};
+
+class QmlPauseAnimationPrivate : public QmlAbstractAnimationPrivate
+{
+ Q_DECLARE_PUBLIC(QmlPauseAnimation);
+public:
+ QmlPauseAnimationPrivate()
+ : QmlAbstractAnimationPrivate(), pa(0) {}
+
+ void init();
+
+ QPauseAnimation *pa;
+};
+
+class QmlColorAnimationPrivate : public QmlAbstractAnimationPrivate
+{
+ Q_DECLARE_PUBLIC(QmlColorAnimation);
+public:
+ QmlColorAnimationPrivate()
+ : QmlAbstractAnimationPrivate(), fromSourced(false), ca(0), value(this, &QmlColorAnimationPrivate::valueChanged) {}
+
+ void init();
+
+ QString easing;
+
+ QList<QObject *> filter;
+ QList<QObject *> exclude;
+ bool fromSourced;
+ QColor fromValue;
+ QColor toValue;
+ GfxValueAnimator *ca;
+ virtual void valueChanged(qreal);
+
+ GfxValueProxy<QmlColorAnimationPrivate> value;
+};
+
+class QmlRunScriptActionPrivate : public QmlAbstractAnimationPrivate
+{
+ Q_DECLARE_PUBLIC(QmlRunScriptAction);
+public:
+ QmlRunScriptActionPrivate()
+ : QmlAbstractAnimationPrivate(), ctxt(QmlContext::activeContext()), proxy(this), rsa(0) {}
+
+ void init();
+
+ QString script;
+ QString file;
+ QmlContext* ctxt;
+
+ void execute();
+
+ QAnimationActionProxy<QmlRunScriptActionPrivate,
+ &QmlRunScriptActionPrivate::execute> proxy;
+ QActionAnimation *rsa;
+};
+
+class QmlSetPropertyActionPrivate : public QmlAbstractAnimationPrivate
+{
+ Q_DECLARE_PUBLIC(QmlSetPropertyAction);
+public:
+ QmlSetPropertyActionPrivate()
+ : QmlAbstractAnimationPrivate(), proxy(this), spa(0) {}
+
+ void init();
+
+ QString properties;
+ QList<QObject *> filter;
+ QList<QObject *> exclude;
+
+ QmlNullableValue<QVariant> value;
+
+ void doAction();
+
+ QAnimationActionProxy<QmlSetPropertyActionPrivate,
+ &QmlSetPropertyActionPrivate::doAction> proxy;
+ QActionAnimation *spa;
+};
+
+class QmlParentChangeActionPrivate : public QmlAbstractAnimationPrivate
+{
+ Q_DECLARE_PUBLIC(QmlParentChangeAction);
+public:
+ QmlParentChangeActionPrivate()
+ : QmlAbstractAnimationPrivate() {}
+
+ void init();
+
+ void doAction();
+ QActionAnimation *cpa;
+};
+
+class QmlNumericAnimationPrivate : public QmlAbstractAnimationPrivate
+{
+ Q_DECLARE_PUBLIC(QmlNumericAnimation);
+public:
+ QmlNumericAnimationPrivate()
+ : QmlAbstractAnimationPrivate(), fromSourced(false), na(0), value(this, &QmlNumericAnimationPrivate::valueChanged) {}
+
+ void init();
+
+ QmlNullableValue<qreal> from;
+ QmlNullableValue<qreal> to;
+
+ QString easing;
+
+ QString properties;
+ QList<QObject *> filter;
+ QList<QObject *> exclude;
+
+ bool fromSourced;
+ qreal fromValue;
+ GfxValueAnimator *na;
+ virtual void valueChanged(qreal);
+
+ GfxValueProxy<QmlNumericAnimationPrivate> value;
+};
+
+class QmlAnimationGroupPrivate : public QmlAbstractAnimationPrivate
+{
+ Q_DECLARE_PUBLIC(QmlAnimationGroup);
+public:
+ QmlAnimationGroupPrivate()
+ : QmlAbstractAnimationPrivate(), animations(this), ag(0) {}
+
+ struct AnimationList : public QmlConcreteList<QmlAbstractAnimation *>
+ {
+ AnimationList(QmlAnimationGroupPrivate *p)
+ : anim(p) {}
+ virtual void append(QmlAbstractAnimation *a) {
+ QmlConcreteList<QmlAbstractAnimation *>::append(a);
+ a->setGroup(anim->q_func());
+ }
+ virtual void clear()
+ {
+ for (int i = 0; i < count(); ++i)
+ at(i)->setGroup(0);
+ QmlConcreteList<QmlAbstractAnimation *>::clear();
+ }
+ virtual void removeAt(int i)
+ {
+ at(i)->setGroup(0);
+ QmlConcreteList<QmlAbstractAnimation *>::removeAt(i);
+ }
+ virtual void insert(int i, QmlAbstractAnimation *a)
+ {
+ QmlConcreteList<QmlAbstractAnimation *>::insert(i, a);
+ a->setGroup(anim->q_func());
+ }
+
+ QmlAnimationGroupPrivate *anim;
+ };
+
+ AnimationList animations;
+ QAnimationGroup *ag;
+};
+
+class QmlVariantAnimationPrivate : public QmlAbstractAnimationPrivate
+{
+ Q_DECLARE_PUBLIC(QmlVariantAnimation);
+public:
+ QmlVariantAnimationPrivate()
+ : QmlAbstractAnimationPrivate(), fromSourced(false), va(0), value(this, &QmlVariantAnimationPrivate::valueChanged) {}
+
+ void init();
+
+ QmlNullableValue<QVariant> from;
+ QmlNullableValue<QVariant> to;
+
+ QString easing;
+
+ QString properties;
+ QList<QObject *> filter;
+ QList<QObject *> exclude;
+
+ bool fromSourced;
+ QVariant fromValue;
+ GfxValueAnimator *va;
+ virtual void valueChanged(qreal);
+
+ GfxValueProxy<QmlVariantAnimationPrivate> value;
+
+ static QVariant interpolateVariant(const QVariant &from, const QVariant &to, qreal progress);
+ static void convertVariant(QVariant &variant, QVariant::Type type);
+};
+
+#endif // QMLANIMATION_P_H
+
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qmlbehaviour.cpp b/src/declarative/util/qmlbehaviour.cpp
new file mode 100644
index 0000000..3169f63
--- /dev/null
+++ b/src/declarative/util/qmlbehaviour.cpp
@@ -0,0 +1,248 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qobject_p.h>
+#include "qmlanimation.h"
+#include "qmltransition.h"
+#include "qmlbehaviour.h"
+#include <QtDeclarative/qmlcontext.h>
+
+
+QT_BEGIN_NAMESPACE
+QML_DEFINE_TYPE(QmlBehaviour,Behaviour);
+
+
+class QmlBehaviourData : public QObject
+{
+Q_OBJECT
+public:
+ QmlBehaviourData(QObject *parent)
+ : QObject(parent) {}
+
+ Q_PROPERTY(QVariant endValue READ endValue NOTIFY valuesChanged);
+ Q_PROPERTY(QVariant startValue READ startValue NOTIFY valuesChanged);
+ QVariant endValue() const { return e; }
+ QVariant startValue() const { return s; }
+
+ QVariant e;
+ QVariant s;
+
+Q_SIGNALS:
+ void valuesChanged();
+
+private:
+ friend class QmlBehaviour;
+};
+
+class QmlBehaviourPrivate : public QObjectPrivate
+{
+public:
+ QmlBehaviourPrivate()
+ : context(0), oldContext(0), valueData(0), operations(this) {}
+ QmlMetaProperty property;
+ QVariant currentValue;
+
+ QVariant fromValue;
+ QVariant toValue;
+ QmlContext *context;
+ QmlContext *oldContext;
+ QmlBehaviourData *valueData;
+ class AnimationList : public QmlConcreteList<QmlAbstractAnimation *>
+ {
+ public:
+ AnimationList(QmlBehaviourPrivate *parent) : _parent(parent) {}
+ virtual void append(QmlAbstractAnimation *a)
+ {
+ QmlConcreteList<QmlAbstractAnimation *>::append(a);
+ _parent->group->addAnimation(a->qtAnimation());
+ }
+ virtual void clear() { QmlConcreteList<QmlAbstractAnimation *>::clear(); } //###
+ private:
+ QmlBehaviourPrivate *_parent;
+ };
+ AnimationList operations;
+ QSequentialAnimationGroup *group;
+};
+
+/*!
+ \qmlclass Behaviour QmlBehaviour
+ \brief The Behaviour element allows you to specify a default animation for a property change.
+
+ In example below, Rect1 will use a bounce easing curve over 200 millisecond for any changes to its y property:
+ \code
+ <Rect id="Rect1" y="200" width="20" height="20" color="#00ff00">
+ <y>
+ <Behaviour>
+ <NumericAnimation easing="easeOutBounce(amplitude:100)" duration="200" />
+ </Behaviour>
+ </y>
+ </Rect>
+ \endcode
+*/
+
+QmlBehaviour::QmlBehaviour(QObject *parent)
+: QmlPropertyValueSource(*(new QmlBehaviourPrivate), parent)
+{
+ Q_D(QmlBehaviour);
+ d->valueData = new QmlBehaviourData(this);
+ d->context = new QmlContext(QmlContext::activeContext(), this);
+ d->context->addDefaultObject(d->valueData);
+ d->group = new QSequentialAnimationGroup(this);
+}
+
+/*!
+ \qmlproperty QVariant Behaviour::fromValue
+ This property holds a selector specifying a starting value for the behaviour
+
+ If you only want the behaviour to apply when the change starts at a
+ specific value you can specify fromValue. This selector is used in conjunction
+ with the toValue selector.
+*/
+
+QVariant QmlBehaviour::fromValue() const
+{
+ Q_D(const QmlBehaviour);
+ return d->fromValue;
+}
+
+void QmlBehaviour::setFromValue(const QVariant &v)
+{
+ Q_D(QmlBehaviour);
+ d->fromValue = v;
+}
+
+/*!
+ \qmlproperty QVariant Behaviour::toValue
+ This property holds a selector specifying a ending value for the behaviour
+
+ If you only want the behaviour to apply when the change ends at a
+ specific value you can specify toValue. This selector is used in conjunction
+ with the fromValue selector.
+*/
+
+QVariant QmlBehaviour::toValue() const
+{
+ Q_D(const QmlBehaviour);
+ return d->toValue;
+}
+
+void QmlBehaviour::setToValue(const QVariant &v)
+{
+ Q_D(QmlBehaviour);
+ d->toValue = v;
+}
+
+QmlList<QmlAbstractAnimation *>* QmlBehaviour::operations()
+{
+ Q_D(QmlBehaviour);
+ return &d->operations;
+}
+
+QmlBehaviour::~QmlBehaviour()
+{
+ //### do we need any other cleanup here?
+}
+
+bool QmlBehaviour::_ignore = false;
+void QmlBehaviour::propertyValueChanged()
+{
+ Q_D(QmlBehaviour);
+ if(_ignore)
+ return;
+
+ QVariant newValue = d->property.read();
+
+ if((!fromValue().isValid() || fromValue() == d->currentValue) &&
+ (!toValue().isValid() || toValue() == newValue)) {
+
+ //### does this clean up everything needed?
+ d->group->stop();
+
+ d->valueData->e = newValue;
+ d->valueData->s = d->currentValue;
+ emit d->valueData->valuesChanged();
+
+ QmlStateOperation::ActionList actions;
+ Action action;
+ action.property = d->property;
+ action.fromValue = d->currentValue;
+ action.toValue = newValue;
+ actions << action;
+
+ _ignore = true;
+ d->property.write(d->currentValue);
+
+ QList<QmlMetaProperty> after;
+ for(int ii = 0; ii < d->operations.count(); ++ii) {
+ d->operations.at(ii)->transition(actions, after, QmlAbstractAnimation::Forward);
+ }
+ d->group->start();
+ if(!after.contains(d->property))
+ d->property.write(newValue);
+ _ignore = false;
+ }
+
+ d->currentValue = newValue;
+}
+
+void QmlBehaviour::setTarget(const QmlMetaProperty &property)
+{
+ Q_D(QmlBehaviour);
+ d->property = property;
+ d->currentValue = property.read();
+ d->property.connectNotifier(this, SLOT(propertyValueChanged()));
+}
+
+void QmlBehaviour::classBegin()
+{
+ Q_D(QmlBehaviour);
+ d->context->activate();
+}
+
+void QmlBehaviour::classComplete()
+{
+ Q_D(QmlBehaviour);
+ d->context->deactivate();
+}
+
+#include "qmlbehaviour.moc"
+
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qmlbehaviour.h b/src/declarative/util/qmlbehaviour.h
new file mode 100644
index 0000000..080423a
--- /dev/null
+++ b/src/declarative/util/qmlbehaviour.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLBEHAVIOUR_H
+#define QMLBEHAVIOUR_H
+
+#include <qmlpropertyvaluesource.h>
+#include <qml.h>
+#include <qmlstate.h>
+#include <gfxtimeline.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QmlAbstractAnimation;
+class QmlBehaviourPrivate;
+class Q_DECLARATIVE_EXPORT QmlBehaviour : public QmlPropertyValueSource,
+ public QmlParserStatus
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlBehaviour)
+ Q_INTERFACES(QmlParserStatus)
+
+ Q_PROPERTY(QVariant from READ fromValue WRITE setFromValue);
+ Q_PROPERTY(QVariant to READ toValue WRITE setToValue);
+ Q_CLASSINFO("DefaultProperty", "operations");
+ Q_PROPERTY(QmlList<QmlAbstractAnimation *>* operations READ operations);
+
+public:
+ QmlBehaviour(QObject *parent=0);
+ ~QmlBehaviour();
+
+ QVariant fromValue() const;
+ void setFromValue(const QVariant &);
+ QVariant toValue() const;
+ void setToValue(const QVariant &);
+ virtual void setTarget(const QmlMetaProperty &);
+
+ QmlList<QmlAbstractAnimation *>* operations();
+
+ static bool _ignore;
+
+protected:
+ virtual void classBegin();
+ virtual void classComplete();
+
+private Q_SLOTS:
+ void propertyValueChanged();
+};
+QML_DECLARE_TYPE(QmlBehaviour);
+
+
+#endif // QMLBEHAVIOUR_H
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
diff --git a/src/declarative/util/qmlbind.cpp b/src/declarative/util/qmlbind.cpp
new file mode 100644
index 0000000..d71d711
--- /dev/null
+++ b/src/declarative/util/qmlbind.cpp
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qmlbindablevalue.h>
+#include <QtDeclarative/qmlengine.h>
+#include <QtDeclarative/qmlcontext.h>
+#include <private/qobject_p.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qdebug.h>
+#include <QtScript/qscriptvalue.h>
+#include <QtScript/qscriptcontext.h>
+#include <QtScript/qscriptengine.h>
+#include <private/qmlnullablevalue_p.h>
+#include "qmlbind.h"
+
+QT_BEGIN_NAMESPACE
+class QmlBindPrivate : public QObjectPrivate
+{
+public:
+ QmlBindPrivate() : when(true), obj(0) {}
+
+ bool when;
+ QObject *obj;
+ QString prop;
+ QmlNullableValue<QVariant> value;
+};
+
+QML_DEFINE_TYPE(QmlBind,Bind);
+/*!
+ \qmlclass Bind QmlBind
+ \brief The Bind element allows arbitrary property bindings to be created.
+
+ Sometimes it is necessary to bind to a property of an object that wasn't
+ directly instantiated by QML - generally a property of a class exported
+ to QML by C++. In these cases, regular property binding doesn't work. Bind
+ allows you to bind any value to any property.
+
+ For example, imagine a C++ application that maps an "app.enteredText"
+ property into QML. You could use Bind to update the enteredText property
+ like this.
+ \code
+ <LineEdit id="myTextField" text="Please type here..." />
+ <Bind target="{app}" property="enteredText" value="{myTextField.text}" />
+ \endcode
+ Whenever the text in the LineEdit is updated, the C++ property will be
+ updated also.
+
+ If the bind target or bind property is changed, the bound value is
+ immediately pushed onto the new target.
+
+ \sa {qmlforcpp}{Qt Declarative Markup Language For C++ Programmers}
+ */
+/*!
+ \internal
+ \class QmlBind
+ \ingroup utility
+ \brief The QmlBind class allows arbitrary property bindings to be created.
+
+ Simple bindings are usually earier to do in-place rather than creating a
+ QmlBind item. For that reason, QmlBind is usually used to transfer property information
+ from Qml to C++.
+
+ \sa cppqml
+ */
+QmlBind::QmlBind(QObject *parent)
+ : QObject(*(new QmlBindPrivate), parent)
+{
+}
+
+QmlBind::~QmlBind()
+{
+}
+
+bool QmlBind::when() const
+{
+ Q_D(const QmlBind);
+ return d->when;
+}
+
+void QmlBind::setWhen(bool v)
+{
+ Q_D(QmlBind);
+ d->when = v;
+ eval();
+}
+
+/*!
+ \qmlproperty Object Bind::target
+
+ The object to be updated.
+ */
+/*!
+ \property QmlBind::target
+ \brief the object to be updated.
+*/
+QObject *QmlBind::object()
+{
+ Q_D(const QmlBind);
+ return d->obj;
+}
+
+void QmlBind::setObject(QObject *obj)
+{
+ Q_D(QmlBind);
+ d->obj = obj;
+ eval();
+}
+
+/*!
+ \qmlproperty string Bind::property
+
+ The property to be updated.
+ */
+/*!
+ \property QmlBind::property
+ \brief the property of the target to be updated.
+*/
+QString QmlBind::property() const
+{
+ Q_D(const QmlBind);
+ return d->prop;
+}
+
+void QmlBind::setProperty(const QString &p)
+{
+ Q_D(QmlBind);
+ d->prop = p;
+ eval();
+}
+
+/*!
+ \qmlproperty any Bind::value
+
+ The value to be set on the target object and property. This can be a
+ constant (which isn't very useful), or a bound expression.
+ */
+/*!
+ \property QmlBind::value
+ \brief the value to bind to.
+*/
+QVariant QmlBind::value() const
+{
+ Q_D(const QmlBind);
+ return d->value.value;
+}
+
+void QmlBind::setValue(const QVariant &v)
+{
+ Q_D(QmlBind);
+ d->value.value = v;
+ d->value.isNull = false;
+ eval();
+}
+
+void QmlBind::eval()
+{
+ Q_D(QmlBind);
+ if(!d->obj || d->value.isNull || !d->when)
+ return;
+
+ QmlMetaProperty prop(d->obj, d->prop);
+ prop.write(d->value.value);
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qmlbind.h b/src/declarative/util/qmlbind.h
new file mode 100644
index 0000000..355edfd
--- /dev/null
+++ b/src/declarative/util/qmlbind.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLBIND_H
+#define QMLBIND_H
+
+#include <qfxglobal.h>
+#include <QtCore/qobject.h>
+#include "qml.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QmlBindPrivate;
+class Q_DECLARATIVE_EXPORT QmlBind : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlBind);
+
+ Q_PROPERTY(QObject *target READ object WRITE setObject);
+ Q_PROPERTY(QString property READ property WRITE setProperty);
+ Q_PROPERTY(QVariant value READ value WRITE setValue);
+
+public:
+ QmlBind(QObject *parent=0);
+ ~QmlBind();
+
+ Q_PROPERTY(bool when READ when WRITE setWhen);
+ bool when() const;
+ void setWhen(bool);
+
+ QObject *object();
+ void setObject(QObject *);
+
+ QString property() const;
+ void setProperty(const QString &);
+
+ QVariant value() const;
+ void setValue(const QVariant &);
+
+private:
+ void eval();
+};
+QML_DECLARE_TYPE(QmlBind);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+#endif
diff --git a/src/declarative/util/qmlconnection.cpp b/src/declarative/util/qmlconnection.cpp
new file mode 100644
index 0000000..df45a31
--- /dev/null
+++ b/src/declarative/util/qmlconnection.cpp
@@ -0,0 +1,290 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlconnection.h"
+#include <QtDeclarative/qmlexpression.h>
+#include "private/qmlboundsignal_p.h"
+#include "private/qobject_p.h"
+#include <QtDeclarative/qmlcontext.h>
+#include <QtCore/qdebug.h>
+
+
+QT_BEGIN_NAMESPACE
+class QmlConnectionPrivate : public QObjectPrivate
+{
+public:
+ QmlConnectionPrivate() : ctxt(0), boundsignal(0), signalSender(0), componentcomplete(false) {}
+
+ QmlContext *ctxt;
+ QmlBoundSignal *boundsignal;
+ QObject *signalSender;
+ QString script;
+ QString signal;
+ bool componentcomplete;
+};
+
+/*!
+ \qmlclass Connection QmlConnection
+ \brief The Connection element describes generalized connections to signals.
+
+ JavaScript-in-HTML style \l {qmlformatsignalscpp}{signal properties} do not allow:
+ \list
+ \i connecting to signals with the same name but different parameters
+ \i conformance checking that parameters are correctly named
+ \i multiple connections to the same signal
+ \i connections outside the scope of the signal sender
+ \i signals in classes with coincidentally-named on<Signal> properties
+ \endlist
+
+ When any of these is needed, the Connection element can be used instead.
+ Where a signal could be connected like this:
+
+ \code
+ <MouseRegion onClicked="foo(x+123,y+456)" />
+ \endcode
+
+ An equivalent binding can be made with a Connection element:
+
+ \code
+ <MouseRegion>
+ <Connection signal="clicked(x,y)" script="foo(x+123,y+456)" />
+ </MouseRegion>
+ \endcode
+
+ More generally, the Connection element can be a child of some other element than
+ the sender of the signal, and the script is the default attribute:
+
+ \code
+ <MouseRegion id="mr"/>
+ ...
+ <Connection sender="{mr}" signal="clicked(x,y)">
+ foo(x+123,y+456)
+ </Connection>
+ \endcode
+*/
+
+/*!
+ \internal
+ \class QmlConnection
+ \brief The QmlConnection class describes generalized connections to signals.
+
+ QmlSetProperties is a mechanism for connecting a script to be run when
+ some object sends a signal.
+*/
+QmlConnection::QmlConnection(QObject *parent) :
+ QObject(*(new QmlConnectionPrivate), parent)
+{
+ Q_D(QmlConnection);
+ d->ctxt = QmlContext::activeContext();
+}
+
+QmlConnection::~QmlConnection()
+{
+ Q_D(QmlConnection);
+ delete d->boundsignal;
+}
+
+/*!
+ \qmlproperty Object Connection::sender
+ This property holds the object that sends the signal.
+
+ By default, the sender is assumed to be the parent of the Connection.
+*/
+
+/*!
+ \property QmlConnection::sender
+ \brief the object that sends the signal.
+
+ By default, the sender is assumed to be the parent of the Connection.
+
+ Note that the set/get methods are setSignalSender() and signalSender(),
+ due to the pre-existence of QObject::sender().
+*/
+QObject *QmlConnection::signalSender() const
+{
+ Q_D(const QmlConnection);
+ return d->signalSender ? d->signalSender : parent();
+}
+
+void QmlConnection::setSignalSender(QObject *obj)
+{
+ Q_D(QmlConnection);
+ if (d->signalSender == obj)
+ return;
+ disconnectIfValid();
+ d->signalSender = obj;
+ connectIfValid();
+}
+
+void QmlConnection::connectIfValid()
+{
+ Q_D(QmlConnection);
+ if (!d->componentcomplete)
+ return;
+ // boundsignal must not exist
+ if ((d->signalSender || parent()) && !d->signal.isEmpty() && !d->script.isEmpty()) {
+ // create
+ // XXX scope?
+ int sigIdx = -1;
+ int lparen = d->signal.indexOf(QLatin1Char('('));
+ QList<QByteArray> sigparams;
+ if (lparen >= 0 && d->signal.length() > lparen+2) {
+ QStringList l = d->signal.mid(lparen+1,d->signal.length()-lparen-2).split(QLatin1Char(','));
+ foreach (QString s, l) {
+ sigparams.append(s.toLatin1());
+ }
+ }
+ QString signalname = d->signal.left(lparen);
+ QObject *sender = d->signalSender ? d->signalSender : parent();
+ const QMetaObject *mo = sender->metaObject();
+ int methods = mo->methodCount();
+ for(int ii = 0; ii < methods; ++ii) {
+ QMetaMethod method = mo->method(ii);
+ QString methodName = QLatin1String(method.signature());
+ int idx = methodName.indexOf(QLatin1Char('('));
+ methodName = methodName.left(idx);
+ if(methodName == signalname && (lparen<0 || method.parameterNames() == sigparams)) {
+ sigIdx = ii;
+ break;
+ }
+ }
+ if (sigIdx < 0) {
+ qWarning() << "signal" << d->signal << "not found";
+ return;
+ }
+
+ if (sigparams.isEmpty())
+ d->boundsignal = new QmlBoundSignal(d->ctxt, d->script, sender, sigIdx, this);
+ else
+ d->boundsignal = new QmlBoundSignalProxy(new QmlContext(d->ctxt,this), d->script, sender, sigIdx, this);
+ }
+}
+
+void QmlConnection::disconnectIfValid()
+{
+ Q_D(QmlConnection);
+ if (!d->componentcomplete)
+ return;
+ if ((d->signalSender || parent()) && !d->signal.isEmpty() && !d->script.isEmpty()) {
+ // boundsignal must exist
+ // destroy
+ delete d->boundsignal;
+ d->boundsignal = 0;
+ }
+}
+
+void QmlConnection::componentComplete()
+{
+ Q_D(QmlConnection);
+ d->componentcomplete=true;
+ connectIfValid();
+}
+
+
+/*!
+ \qmlproperty string Connection::script
+ This property holds the JavaScript executed whenever the signal is sent.
+
+ This is the default attribute of Connection.
+*/
+
+/*!
+ \property QmlConnection::script
+ \brief the JavaScript executed whenever the signal is sent.
+*/
+QString QmlConnection::script() const
+{
+ Q_D(const QmlConnection);
+ return d->script;
+}
+
+void QmlConnection::setScript(const QString& script)
+{
+ Q_D(QmlConnection);
+ if ((d->signalSender || parent()) && !d->signal.isEmpty()) {
+ if (d->script.isEmpty()) {
+ // mustn't exist - create
+ d->script = script;
+ connectIfValid();
+ } else {
+ // must exist - update
+ d->script = script;
+ d->boundsignal->setExpression(script);
+ }
+ } else {
+ d->script = script;
+ }
+}
+
+/*!
+ \qmlproperty string Connection::signal
+ This property holds the signal from the sender to which the script is attached.
+
+ The signal must have its formal parameter names given in parentheses:
+
+ \code
+ <Connection signal="clicked(x,y)" ... />
+ \endcode
+*/
+
+/*!
+ \property QmlConnection::signal
+ \brief the signal from the sender to which the script is attached.
+*/
+QString QmlConnection::signal() const
+{
+ Q_D(const QmlConnection);
+ return d->signal;
+}
+
+void QmlConnection::setSignal(const QString& sig)
+{
+ Q_D(QmlConnection);
+ if (d->signal == sig)
+ return;
+ disconnectIfValid();
+ d->signal = sig;
+ connectIfValid();
+}
+
+QML_DEFINE_TYPE(QmlConnection,Connection);
+
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qmlconnection.h b/src/declarative/util/qmlconnection.h
new file mode 100644
index 0000000..c943092
--- /dev/null
+++ b/src/declarative/util/qmlconnection.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLCONNECTION_H
+#define QMLCONNECTION_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstring.h>
+#include <QtDeclarative/qml.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QmlBoundSignal;
+class QmlContext;
+class QmlConnectionPrivate;
+class Q_DECLARATIVE_EXPORT QmlConnection : public QObject, public QmlParserStatus
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlConnection)
+
+ Q_INTERFACES(QmlParserStatus);
+ Q_CLASSINFO("DefaultProperty", "script");
+ Q_PROPERTY(QObject *sender READ signalSender WRITE setSignalSender);
+ Q_PROPERTY(QString script READ script WRITE setScript);
+ Q_PROPERTY(QString signal READ signal WRITE setSignal);
+
+public:
+ QmlConnection(QObject *parent=0);
+ ~QmlConnection();
+
+ QObject *signalSender() const;
+ void setSignalSender(QObject *);
+ QString script() const;
+ void setScript(const QString&);
+ QString signal() const;
+ void setSignal(const QString&);
+
+private:
+ void disconnectIfValid();
+ void connectIfValid();
+ void componentComplete();
+};
+QML_DECLARE_TYPE(QmlConnection);
+
+#endif
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
diff --git a/src/declarative/util/qmldatetimeformatter.cpp b/src/declarative/util/qmldatetimeformatter.cpp
new file mode 100644
index 0000000..138f68b
--- /dev/null
+++ b/src/declarative/util/qmldatetimeformatter.cpp
@@ -0,0 +1,368 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmldatetimeformatter.h"
+#include "private/qobject_p.h"
+#include <QtCore/qlocale.h>
+
+QT_BEGIN_NAMESPACE
+//TODO: may need optimisation as the QDateTime member may not be needed?
+// be able to set a locale?
+
+class QmlDateTimeFormatterPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QmlDateTimeFormatter)
+public:
+ QmlDateTimeFormatterPrivate() : locale(QLocale::system()), longStyle(false), classComplete(true) {}
+
+ void updateText();
+
+ QDateTime dateTime;
+ QDate date;
+ QTime time;
+ QLocale locale;
+ QString dateTimeText;
+ QString dateText;
+ QString timeText;
+ QString dateTimeFormat; //set for convienience?
+ QString dateFormat;
+ QString timeFormat;
+ bool longStyle;
+ bool classComplete;
+};
+
+/*!
+ \qmlclass DateTimeFormatter QmlDateTimeFormatter
+ \brief The DateTimeFormatter allows you to control the format of a date string.
+
+ \code
+ <DateTimeFormatter id="Formatter" date="{System.date}"/>
+ <Text text="{Formatter.dateText}"/>
+ \endcode
+
+ By default, the text properties (dateText, timeText, and dateTimeText) will return the
+ date and time using the current system locale's format.
+*/
+
+/*!
+ \internal
+ \class QmlDateTimeFormatter
+ \ingroup utility
+ \brief The QmlDateTimeFormatter class allows you to format a date string.
+*/
+
+QmlDateTimeFormatter::QmlDateTimeFormatter(QObject *parent)
+: QObject(*(new QmlDateTimeFormatterPrivate), parent)
+{
+}
+
+QmlDateTimeFormatter::~QmlDateTimeFormatter()
+{
+}
+
+/*!
+ \qmlproperty string DateTimeFormatter::dateText
+ \qmlproperty string DateTimeFormatter::timeText
+ \qmlproperty string DateTimeFormatter::dateTimeText
+
+ Formatted text representations of the \c date, \c time,
+ and \c {date and time}, respectively.
+
+ If there is no explictly specified format the DateTimeFormatter
+ will use the system locale's default 'short' setting.
+
+ \code
+ <!-- specify source date (assuming today is February 19, 2009) -->
+ <DateTimeFormatter id="formatter" dateTime="{Today.date}"/>
+
+ <!-- display the full date and time -->
+ <Text text="{formatter.dateText}"/>
+ \endcode
+
+ Would be equivalent to the following for a US English locale:
+
+ \code
+ <!-- display the date -->
+ <Text text="2/19/09"/>
+ \endcode
+*/
+QString QmlDateTimeFormatter::dateTimeText() const
+{
+ Q_D(const QmlDateTimeFormatter);
+ return d->dateTimeText;
+}
+
+QString QmlDateTimeFormatter::dateText() const
+{
+ Q_D(const QmlDateTimeFormatter);
+ return d->dateText;
+}
+
+QString QmlDateTimeFormatter::timeText() const
+{
+ Q_D(const QmlDateTimeFormatter);
+ return d->timeText;
+}
+
+/*!
+ \qmlproperty date DateTimeFormatter::date
+ \qmlproperty time DateTimeFormatter::time
+ \qmlproperty datetime DateTimeFormatter::dateTime
+
+ The source date and time to be used by the formatter.
+
+ \code
+ <!-- setting the date and time -->
+ <DateTimeFormatter date="{System.date}" time="{System.time}"/>
+ \endcode
+
+ For convienience it is possible to set the datetime property to set both the date and the time.
+ \code
+ <!-- setting the datetime -->
+ <DateTimeFormatter dateTime="{System.dateTime}"/>
+ \endcode
+
+ There can only be one instance of date and time per formatter; if date, time, and dateTime are all
+ set the actual date and time used is not guaranteed.
+
+ \note If no date is set, dateTimeText will be just the date;
+ If no time is set, the dateTimeText will be just the time.
+
+*/
+QDate QmlDateTimeFormatter::date() const
+{
+ Q_D(const QmlDateTimeFormatter);
+ return d->date;
+}
+
+QTime QmlDateTimeFormatter::time() const
+{
+ Q_D(const QmlDateTimeFormatter);
+ return d->time;
+}
+
+QDateTime QmlDateTimeFormatter::dateTime() const
+{
+ Q_D(const QmlDateTimeFormatter);
+ return d->dateTime;
+}
+
+/*!
+ \qmlproperty string DateTimeFormatter::dateFormat
+ \qmlproperty string DateTimeFormatter::timeFormat
+ \qmlproperty string DateTimeFormatter::dateTimeFormat
+
+ Specifies a custom format which the DateTime Formatter can use.
+
+ If there is no explictly specified format the DateTimeFormatter
+ will use the system locale's default 'short' setting.
+
+ The text's format may be modified by setting:
+ \list
+ \i \c dateFormat
+ \i \c timeFormat
+ \i \c dateTimeFormat
+ \endlist
+
+ If only the format for date is defined, the time and dateTime formats will be defined
+ as the system locale default and likewise for the others.
+
+ Syntax for the format is based on the QDateTime::toString() formatting options.
+
+ \code
+ <!-- Format the date such that the dateText is: '1997-12-12'>
+ <DateFormatter id="formatter" dateTime="{Today.dateTime}" formatDate="yyyy-MM-d"/>
+ \endcode
+
+ Assigning an empty string to a particular format will reset it.
+*/
+QString QmlDateTimeFormatter::dateTimeFormat() const
+{
+ Q_D(const QmlDateTimeFormatter);
+ return d->dateTimeFormat;
+}
+
+QString QmlDateTimeFormatter::dateFormat() const
+{
+ Q_D(const QmlDateTimeFormatter);
+ return d->dateFormat;
+}
+
+QString QmlDateTimeFormatter::timeFormat() const
+{
+ Q_D(const QmlDateTimeFormatter);
+ return d->timeFormat;
+}
+
+/*!
+ \qmlproperty bool DateTimeFormatter::longStyle
+
+ This property causes the formatter to use the system locale's long format rather than short format
+ by default.
+
+ This setting is off by default.
+*/
+bool QmlDateTimeFormatter::longStyle() const
+{
+ Q_D(const QmlDateTimeFormatter);
+ return d->longStyle;
+}
+
+void QmlDateTimeFormatter::setDateTime(const QDateTime &dateTime)
+{
+ Q_D(QmlDateTimeFormatter);
+ if (d->dateTime == dateTime)
+ return;
+ d->dateTime = dateTime;
+ d->date = d->dateTime.date();
+ d->time = d->dateTime.time();
+ d->updateText();
+}
+
+void QmlDateTimeFormatter::setTime(const QTime &time)
+{
+ Q_D(QmlDateTimeFormatter);
+ if (d->dateTime.time() == time)
+ return;
+ d->time = time;
+ d->dateTime.setTime(time);
+ d->updateText();
+}
+
+void QmlDateTimeFormatter::setDate(const QDate &date)
+{
+ Q_D(QmlDateTimeFormatter);
+ if (d->dateTime.date() == date)
+ return;
+ d->date = date;
+ bool clearTime = d->dateTime.time().isValid() ? false : true; //because setting date generates default time
+ d->dateTime.setDate(date);
+ if (clearTime)
+ d->dateTime.setTime(QTime());
+ d->updateText();
+}
+
+//DateTime formatting may be a combination of date and time?
+void QmlDateTimeFormatter::setDateTimeFormat(const QString &format)
+{
+ Q_D(QmlDateTimeFormatter);
+ //no format checking
+ d->dateTimeFormat = format;
+ d->updateText();
+}
+
+void QmlDateTimeFormatter::setDateFormat(const QString &format)
+{
+ Q_D(QmlDateTimeFormatter);
+ //no format checking
+ d->dateFormat = format;
+ d->updateText();
+}
+
+void QmlDateTimeFormatter::setTimeFormat(const QString &format)
+{
+ Q_D(QmlDateTimeFormatter);
+ //no format checking
+ d->timeFormat = format;
+ d->updateText();
+}
+
+void QmlDateTimeFormatter::setLongStyle(bool longStyle)
+{
+ Q_D(QmlDateTimeFormatter);
+ d->longStyle = longStyle;
+ d->updateText();
+}
+
+void QmlDateTimeFormatterPrivate::updateText()
+{
+ Q_Q(QmlDateTimeFormatter);
+ if (!classComplete)
+ return;
+
+ QString str;
+ QString str1;
+ QString str2;
+
+ Qt::DateFormat defaultFormat = longStyle ? Qt::SystemLocaleLongDate : Qt::SystemLocaleShortDate;
+
+ if (dateFormat.isEmpty())
+ str1 = date.toString(defaultFormat);
+ else
+ str1 = date.toString(dateFormat);
+
+ if (timeFormat.isEmpty())
+ str2 = time.toString(defaultFormat);
+ else
+ str2 = time.toString(timeFormat);
+
+ if (dateTimeFormat.isEmpty())
+ str = dateTime.toString(defaultFormat);
+ //else if (!formatTime.isEmpty() && !formatDate.isEmpty())
+ // str = str1 + QLatin1Char(' ') + str2;
+ else
+ str = dateTime.toString(dateTimeFormat);
+
+ if (dateTimeText == str && dateText == str1 && timeText == str2)
+ return;
+
+ dateTimeText = str;
+ dateText = str1;
+ timeText = str2;
+
+ emit q->textChanged();
+}
+
+void QmlDateTimeFormatter::classBegin()
+{
+ Q_D(QmlDateTimeFormatter);
+ d->classComplete = false;
+}
+
+void QmlDateTimeFormatter::classComplete()
+{
+ Q_D(QmlDateTimeFormatter);
+ d->classComplete = true;
+ d->updateText();
+}
+
+QML_DEFINE_TYPE(QmlDateTimeFormatter, DateTimeFormatter);
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qmldatetimeformatter.h b/src/declarative/util/qmldatetimeformatter.h
new file mode 100644
index 0000000..3421f8c
--- /dev/null
+++ b/src/declarative/util/qmldatetimeformatter.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLDATETIMEFORMATTER_H
+#define QMLDATETIMEFORMATTER_H
+
+#include <QtCore/qdatetime.h>
+#include <QtDeclarative/qml.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QmlDateTimeFormatterPrivate;
+class Q_DECLARATIVE_EXPORT QmlDateTimeFormatter : public QObject, public QmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QmlParserStatus)
+
+ Q_PROPERTY(QString dateText READ dateText NOTIFY textChanged)
+ Q_PROPERTY(QString timeText READ timeText NOTIFY textChanged)
+ Q_PROPERTY(QString dateTimeText READ dateTimeText NOTIFY textChanged)
+ Q_PROPERTY(QDate date READ date WRITE setDate)
+ Q_PROPERTY(QTime time READ time WRITE setTime)
+ Q_PROPERTY(QDateTime dateTime READ dateTime WRITE setDateTime)
+ Q_PROPERTY(QString dateFormat READ dateFormat WRITE setDateFormat)
+ Q_PROPERTY(QString timeFormat READ timeFormat WRITE setTimeFormat)
+ Q_PROPERTY(QString dateTimeFormat READ dateTimeFormat WRITE setDateTimeFormat)
+ Q_PROPERTY(bool longStyle READ longStyle WRITE setLongStyle)
+public:
+ QmlDateTimeFormatter(QObject *parent=0);
+ ~QmlDateTimeFormatter();
+
+ QString dateTimeText() const;
+ QString dateText() const;
+ QString timeText() const;
+
+ QDate date() const;
+ void setDate(const QDate &);
+
+ QTime time() const;
+ void setTime(const QTime &);
+
+ QDateTime dateTime() const;
+ void setDateTime(const QDateTime &);
+
+ QString dateTimeFormat() const;
+ void setDateTimeFormat(const QString &);
+
+ QString dateFormat() const;
+ void setDateFormat(const QString &);
+
+ QString timeFormat() const;
+ void setTimeFormat(const QString &);
+
+ bool longStyle() const;
+ void setLongStyle(bool);
+
+ virtual void classBegin();
+ virtual void classComplete();
+
+Q_SIGNALS:
+ void textChanged();
+
+private:
+ Q_DISABLE_COPY(QmlDateTimeFormatter)
+ Q_DECLARE_PRIVATE(QmlDateTimeFormatter)
+};
+
+QML_DECLARE_TYPE(QmlDateTimeFormatter);
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+#endif
diff --git a/src/declarative/util/qmlfollow.cpp b/src/declarative/util/qmlfollow.cpp
new file mode 100644
index 0000000..c841b85
--- /dev/null
+++ b/src/declarative/util/qmlfollow.cpp
@@ -0,0 +1,309 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <limits.h>
+#include <QtCore/qdebug.h>
+#include <gfxtimeline.h>
+#include "private/qobject_p.h"
+#include "qmlfollow.h"
+#include "private/qmlanimation_p.h"
+
+
+QT_BEGIN_NAMESPACE
+QML_DEFINE_TYPE(QmlFollow,Follow);
+
+class QmlFollowPrivate : public QObjectPrivate
+{
+public:
+ QmlFollowPrivate()
+ : sourceValue(0), maxVelocity(0), lastTime(0)
+ , mass(1.0), spring(0.), damping(0.), velocity(0), enabled(true), mode(Track), clock(this) {}
+
+ QmlMetaProperty property;
+ qreal currentValue;
+ qreal sourceValue;
+ qreal maxVelocity;
+ qreal velocityms;
+ int lastTime;
+ qreal mass;
+ qreal spring;
+ qreal damping;
+ qreal velocity;
+ bool enabled;
+
+ enum Mode {
+ Track,
+ Velocity,
+ Spring
+ };
+ Mode mode;
+
+ void tick(int);
+ void updateMode();
+ void start();
+ void stop();
+
+ QTickAnimationProxy<QmlFollowPrivate, &QmlFollowPrivate::tick> clock;
+};
+
+void QmlFollowPrivate::tick(int time)
+{
+ int elapsed = time - lastTime;
+ if (!elapsed)
+ return;
+ if (mode == Spring) {
+ if (elapsed < 10) // capped at 100fps.
+ return;
+ // Real men solve the spring DEs using RK4.
+ // We'll do something much simpler which gives a result that looks fine.
+ int count = (elapsed+5) / 10;
+ for (int i = 0; i < count; ++i) {
+ qreal diff = sourceValue - currentValue;
+ velocity = velocity + spring * diff - damping * velocity;
+ // The following line supports mass. Not sure its worth the extra divisions.
+ // velocity = velocity + spring / mass * diff - damping / mass * velocity;
+ if (maxVelocity > 0.) {
+ // limit velocity
+ if (velocity > maxVelocity)
+ velocity = maxVelocity;
+ else if (velocity < -maxVelocity)
+ velocity = -maxVelocity;
+ }
+ currentValue += velocity * 10.0 / 1000.0;
+ }
+ if (qAbs(velocity) < 0.5 && qAbs(sourceValue - currentValue) < 0.5) {
+ velocity = 0.0;
+ currentValue = sourceValue;
+ clock.stop();
+ }
+ lastTime = time - (elapsed - count * 10);
+ } else {
+ qreal moveBy = elapsed * velocityms;
+ qreal diff = sourceValue - currentValue;
+ if (diff > 0) {
+ currentValue += moveBy;
+ if (currentValue > sourceValue) {
+ currentValue = sourceValue;
+ clock.stop();
+ }
+ } else {
+ currentValue -= moveBy;
+ if (currentValue < sourceValue) {
+ currentValue = sourceValue;
+ clock.stop();
+ }
+ }
+ lastTime = time;
+ }
+ property.write(currentValue);
+}
+
+void QmlFollowPrivate::updateMode()
+{
+ if (spring == 0. && maxVelocity == 0.)
+ mode = Track;
+ else if (spring > 0.)
+ mode = Spring;
+ else
+ mode = Velocity;
+}
+
+void QmlFollowPrivate::start()
+{
+ if (!enabled)
+ return;
+
+ if (mode == QmlFollowPrivate::Track) {
+ currentValue = sourceValue;
+ property.write(currentValue);
+ } else if (sourceValue != currentValue && clock.state() != QAbstractAnimation::Running) {
+ lastTime = 0;
+ clock.start(); // infinity??
+ }
+}
+
+void QmlFollowPrivate::stop()
+{
+ clock.stop();
+}
+
+/*!
+ \qmlclass Follow QmlFollow
+ \brief The Follow element allows a property to track a value.
+
+ In example below, Rect2 will follow Rect1 moving with a velocity of up to 200:
+ \code
+ <Rect id="Rect1" y="{200}" width="20" height="20" color="#00ff00">
+ <y>
+ <SequentialAnimation running="true" repeat="true">
+ <NumericAnimation to="{200}" easing="easeOutBounce(amplitude:100)" duration="2000" />
+ <PauseAnimation duration="1000" />
+ </SequentialAnimation>
+ </y>
+ </Rect>
+ <Rect id="Rect2" x="{Rect1.width}" width="20" height="20" color="#ff0000">
+ <y>
+ <Follow source="{Rect1.y}" velocity="200"/>
+ </y>
+ </Rect>
+ \endcode
+*/
+
+QmlFollow::QmlFollow(QObject *parent)
+: QmlPropertyValueSource(*(new QmlFollowPrivate),parent)
+{
+}
+
+QmlFollow::~QmlFollow()
+{
+}
+
+void QmlFollow::setTarget(const QmlMetaProperty &property)
+{
+ Q_D(QmlFollow);
+ d->property = property;
+ d->currentValue = property.read().toDouble();
+}
+
+qreal QmlFollow::sourceValue() const
+{
+ Q_D(const QmlFollow);
+ return d->sourceValue;
+}
+
+/*!
+ \qmlproperty qreal Follow::source
+ This property holds the source value which will be tracked.
+
+ Bind to a property in order to track its changes.
+*/
+
+void QmlFollow::setSourceValue(qreal value)
+{
+ Q_D(QmlFollow);
+ d->sourceValue = value;
+ d->start();
+}
+
+/*!
+ \qmlproperty qreal Follow::velocity
+ This property holds the maximum velocity allowed when tracking the source.
+*/
+
+qreal QmlFollow::velocity() const
+{
+ Q_D(const QmlFollow);
+ return d->maxVelocity;
+}
+
+void QmlFollow::setVelocity(qreal velocity)
+{
+ Q_D(QmlFollow);
+ d->maxVelocity = velocity;
+ d->velocityms = velocity / 1000.0;
+ d->updateMode();
+}
+
+/*!
+ \qmlproperty qreal Follow::spring
+ This property holds the spring constant
+
+ The spring constant describes how strongly the target is pulled towards the
+ source. Setting spring to 0 turns off spring tracking. Useful values 0 - 5.0
+
+ When a spring constant is set and the velocity property is greater than 0,
+ velocity limits the maximum speed.
+*/
+qreal QmlFollow::spring() const
+{
+ Q_D(const QmlFollow);
+ return d->spring;
+}
+
+void QmlFollow::setSpring(qreal spring)
+{
+ Q_D(QmlFollow);
+ d->spring = spring;
+ d->updateMode();
+}
+
+/*!
+ \qmlproperty qreal Follow::damping
+ This property holds the spring damping constant
+
+ The damping constant describes how quickly a sprung follower comes to rest.
+ Useful range is 0 - 1.0
+*/
+qreal QmlFollow::damping() const
+{
+ Q_D(const QmlFollow);
+ return d->damping;
+}
+
+void QmlFollow::setDamping(qreal damping)
+{
+ Q_D(QmlFollow);
+ if (damping > 1.)
+ damping = 1.;
+
+ d->damping = damping;
+}
+
+/*!
+ \qmlproperty bool Follow::enabled
+ This property holds whether the target will track the source.
+*/
+bool QmlFollow::enabled() const
+{
+ Q_D(const QmlFollow);
+ return d->enabled;
+}
+
+void QmlFollow::setEnabled(bool enabled)
+{
+ Q_D(QmlFollow);
+ d->enabled = enabled;
+ if (enabled)
+ d->start();
+ else
+ d->stop();
+}
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qmlfollow.h b/src/declarative/util/qmlfollow.h
new file mode 100644
index 0000000..a609305
--- /dev/null
+++ b/src/declarative/util/qmlfollow.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLFOLLOW_H
+#define QMLFOLLOW_H
+
+#include <qmlpropertyvaluesource.h>
+#include <qml.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QmlFollowPrivate;
+class Q_DECLARATIVE_EXPORT QmlFollow : public QmlPropertyValueSource,
+ public QmlParserStatus
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlFollow)
+ Q_INTERFACES(QmlParserStatus)
+
+ Q_PROPERTY(qreal source READ sourceValue WRITE setSourceValue);
+ Q_PROPERTY(qreal velocity READ velocity WRITE setVelocity);
+ Q_PROPERTY(qreal spring READ spring WRITE setSpring);
+ Q_PROPERTY(qreal damping READ damping WRITE setDamping);
+ Q_PROPERTY(bool enabled READ enabled WRITE setEnabled);
+
+public:
+ QmlFollow(QObject *parent=0);
+ ~QmlFollow();
+
+ virtual void setTarget(const QmlMetaProperty &);
+
+ qreal sourceValue() const;
+ void setSourceValue(qreal value);
+ qreal velocity() const;
+ void setVelocity(qreal velocity);
+ qreal spring() const;
+ void setSpring(qreal spring);
+ qreal damping() const;
+ void setDamping(qreal damping);
+ bool enabled() const;
+ void setEnabled(bool enabled);
+};
+
+QML_DECLARE_TYPE(QmlFollow);
+
+
+#endif // QFXFOLLOW_H
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
diff --git a/src/declarative/util/qmlfont.cpp b/src/declarative/util/qmlfont.cpp
new file mode 100644
index 0000000..ad91edd
--- /dev/null
+++ b/src/declarative/util/qmlfont.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "private/qobject_p.h"
+#include "qfont.h"
+#include "qmlfont.h"
+
+
+QT_BEGIN_NAMESPACE
+class QmlFontPrivate : public QObjectPrivate
+{
+public:
+ QFont font;
+};
+
+QML_DEFINE_TYPE(QmlFont,Font);
+
+/*!
+ \internal
+ \class QmlFont
+ \ingroup utility
+ \brief The QmlFont class provides a font used for drawing text on a QFxView.
+*/
+QmlFont::QmlFont(QObject *parent)
+ : QObject(*(new QmlFontPrivate), parent)
+{
+}
+
+QmlFont::~QmlFont()
+{
+}
+
+/*!
+ \property QmlFont::family
+ \brief the family of the font.
+*/
+QString QmlFont::family() const
+{
+ Q_D(const QmlFont);
+ return d->font.family();
+}
+
+void QmlFont::setFamily(const QString &family)
+{
+ Q_D(QmlFont);
+ d->font.setFamily(family);
+ emit updated();
+}
+
+/*!
+ \property QmlFont::bold
+ \brief whether the font should be bold.
+*/
+bool QmlFont::bold() const
+{
+ Q_D(const QmlFont);
+ return d->font.bold();
+}
+
+void QmlFont::setBold(bool b)
+{
+ Q_D(QmlFont);
+ d->font.setBold(b);
+ emit updated();
+}
+
+/*!
+ \property QmlFont::italic
+ \brief whether the font should be italic.
+*/
+bool QmlFont::italic() const
+{
+ Q_D(const QmlFont);
+ return d->font.italic();
+}
+
+void QmlFont::setItalic(bool b)
+{
+ Q_D(QmlFont);
+ d->font.setItalic(b);
+ emit updated();
+}
+
+/*!
+ \property QmlFont::size
+ \brief the size of the font in points.
+*/
+qreal QmlFont::size() const
+{
+ Q_D(const QmlFont);
+ return d->font.pointSizeF();
+}
+
+void QmlFont::setSize(qreal size)
+{
+ Q_D(QmlFont);
+ d->font.setPointSizeF(size);
+ emit updated();
+}
+
+/*!
+ \brief Returns a QFont representation of the font.
+*/
+QFont QmlFont::font() const
+{
+ Q_D(const QmlFont);
+ return d->font;
+}
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qmlfont.h b/src/declarative/util/qmlfont.h
new file mode 100644
index 0000000..b6bce7c
--- /dev/null
+++ b/src/declarative/util/qmlfont.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLFONT_H
+#define QMLFONT_H
+
+#include <QtCore/qobject.h>
+#include <qml.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QmlFontPrivate;
+class Q_DECLARATIVE_EXPORT QmlFont : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlFont)
+
+ Q_PROPERTY(QString family READ family WRITE setFamily)
+ Q_PROPERTY(bool bold READ bold WRITE setBold)
+ Q_PROPERTY(bool italic READ italic WRITE setItalic)
+ Q_PROPERTY(qreal size READ size WRITE setSize)
+
+public:
+ QmlFont(QObject *parent=0);
+ ~QmlFont();
+
+ QString family() const;
+ void setFamily(const QString &);
+
+ bool bold() const;
+ void setBold(bool b);
+
+ bool italic() const;
+ void setItalic(bool b);
+
+ qreal size() const;
+ void setSize(qreal size);
+
+ QFont font() const;
+
+Q_SIGNALS:
+ void updated();
+};
+QML_DECLARE_TYPE(QmlFont);
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+#endif // QMLFONT_H
diff --git a/src/declarative/util/qmllistaccessor.cpp b/src/declarative/util/qmllistaccessor.cpp
new file mode 100644
index 0000000..9387bbc
--- /dev/null
+++ b/src/declarative/util/qmllistaccessor.cpp
@@ -0,0 +1,243 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmllistaccessor.h"
+#include <QStringList>
+#include <qmlmetatype.h>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+QmlListAccessor::QmlListAccessor()
+: type(Invalid)
+{
+}
+
+QmlListAccessor::~QmlListAccessor()
+{
+}
+
+QVariant QmlListAccessor::list() const
+{
+ return d;
+}
+
+void QmlListAccessor::setList(const QVariant &v)
+{
+ d = v;
+
+ if(!d.isValid()) {
+ type = Invalid;
+ } else if(d.type() == QVariant::StringList) {
+ type = StringList;
+ } else if(d.type() != QVariant::UserType) {
+ type = Instance;
+ } else if(QmlMetaType::isObject(d.userType())) {
+ QObject *data = 0;
+ data = *(QObject **)v.constData();
+ d = QVariant::fromValue(data);
+ type = Instance;
+ } else if(QmlMetaType::isQmlList(d.userType())) {
+ type = QmlList;
+ } else if(QmlMetaType::isList(d.userType())) {
+ type = QList;
+ } else {
+ type = Invalid;
+ d = QVariant();
+ }
+}
+
+int QmlListAccessor::count() const
+{
+ switch(type) {
+ case Invalid:
+ return 0;
+ case StringList:
+ return qvariant_cast<QStringList>(d).count();
+ case QmlList:
+ {
+ QmlPrivate::ListInterface *li = *(QmlPrivate::ListInterface **)d.constData();
+ return li->count();
+ }
+ case QList:
+ return QmlMetaType::listCount(d);
+ case Instance:
+ return 1;
+ }
+
+ return 0;
+}
+
+QVariant QmlListAccessor::at(int idx) const
+{
+ Q_ASSERT(idx >= 0 && idx < count());
+ switch(type) {
+ case Invalid:
+ return QVariant();
+ case StringList:
+ return QVariant::fromValue(qvariant_cast<QStringList>(d).at(idx));
+ case QmlList:
+ {
+ QmlPrivate::ListInterface *li = *(QmlPrivate::ListInterface **)d.constData();
+ void *ptr[1];
+ li->at(idx, ptr);
+ return QmlMetaType::fromObject((QObject*)ptr[0], li->type()); //XXX only handles QObject-derived types
+ }
+ case QList:
+ return QmlMetaType::listAt(d, idx);
+ case Instance:
+ return d;
+ }
+
+ return QVariant();
+}
+
+void QmlListAccessor::append(const QVariant &value)
+{
+ switch(type) {
+ case Invalid:
+ break;
+ case StringList:
+ {
+ const QString &str = value.toString();
+ qvariant_cast<QStringList>(d).append(str);
+ break;
+ }
+ case QmlList:
+ {
+ QmlPrivate::ListInterface *li = *(QmlPrivate::ListInterface **)d.constData();
+ li->append(const_cast<void *>(value.constData())); //XXX
+ break;
+ }
+ case QList:
+ QmlMetaType::append(d, value);
+ break;
+ case Instance:
+ //do nothing
+ break;
+ }
+}
+
+void QmlListAccessor::insert(int index, const QVariant &value)
+{
+ switch(type) {
+ case Invalid:
+ break;
+ case StringList:
+ {
+ const QString &str = value.toString();
+ qvariant_cast<QStringList>(d).insert(index, str);
+ break;
+ }
+ case QmlList:
+ {
+ QmlPrivate::ListInterface *li = *(QmlPrivate::ListInterface **)d.constData();
+ li->insert(index, const_cast<void *>(value.constData())); //XXX
+ break;
+ }
+ case QList:
+ //XXX needs implementation
+ qWarning() << "insert function not yet implemented for QLists";
+ break;
+ case Instance:
+ //XXX do nothing?
+ if (index == 0)
+ setList(value);
+ break;
+ }
+}
+
+void QmlListAccessor::removeAt(int index)
+{
+ switch(type) {
+ case Invalid:
+ break;
+ case StringList:
+ qvariant_cast<QStringList>(d).removeAt(index);
+ break;
+ case QmlList:
+ {
+ QmlPrivate::ListInterface *li = *(QmlPrivate::ListInterface **)d.constData();
+ li->removeAt(index);
+ break;
+ }
+ case QList:
+ //XXX needs implementation
+ qWarning() << "removeAt function not yet implemented for QLists";
+ break;
+ case Instance:
+ //XXX do nothing?
+ if (index == 0)
+ setList(QVariant());
+ break;
+ }
+}
+
+void QmlListAccessor::clear()
+{
+ switch(type) {
+ case Invalid:
+ break;
+ case StringList:
+ qvariant_cast<QStringList>(d).clear();
+ break;
+ case QmlList:
+ {
+ QmlPrivate::ListInterface *li = *(QmlPrivate::ListInterface **)d.constData();
+ li->clear();
+ break;
+ }
+ case QList:
+ QmlMetaType::clear(d);
+ break;
+ case Instance:
+ //XXX what should we do here?
+ setList(QVariant());
+ break;
+ }
+}
+
+bool QmlListAccessor::isValid() const
+{
+ return type != Invalid;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qmllistaccessor.h b/src/declarative/util/qmllistaccessor.h
new file mode 100644
index 0000000..29f910d
--- /dev/null
+++ b/src/declarative/util/qmllistaccessor.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLLISTACCESSOR_H
+#define QMLLISTACCESSOR_H
+
+#include <QVariant>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class Q_DECLARATIVE_EXPORT QmlListAccessor
+{
+public:
+ QmlListAccessor();
+ virtual ~QmlListAccessor();
+
+ QVariant list() const;
+ void setList(const QVariant &);
+
+ bool isValid() const;
+
+ int count() const;
+ QVariant at(int) const;
+
+ virtual void append(const QVariant &);
+ virtual void insert(int, const QVariant &);
+ virtual void removeAt(int);
+ virtual void clear();
+
+private:
+ enum Type { Invalid, StringList, QmlList, QList, Instance };
+ Type type;
+ QVariant d;
+};
+
+#endif // QMLLISTACCESSOR_H
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
diff --git a/src/declarative/util/qmllistmodel.cpp b/src/declarative/util/qmllistmodel.cpp
new file mode 100644
index 0000000..992185a
--- /dev/null
+++ b/src/declarative/util/qmllistmodel.cpp
@@ -0,0 +1,721 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qstack.h>
+#include <QXmlStreamReader>
+#include "qmlcustomparser.h"
+#include "qmlopenmetaobject.h"
+#include <qmlcontext.h>
+#include <qmlbindablevalue.h>
+#include "qmllistmodel.h"
+
+QT_BEGIN_NAMESPACE
+
+#define DATA_ROLE_ID 1
+#define DATA_ROLE_NAME "data"
+
+Q_DECLARE_METATYPE(QListModelInterface *);
+class QmlListModelPrivate
+{
+public:
+ QmlListModelPrivate(QmlListModel *m)
+ : q(m),
+ type(QmlListModel::Invalid),
+ listModelInterface(0),
+ singleObject(0),
+ roleCacheValid(false)
+ {
+ }
+
+ void clear()
+ {
+ type = QmlListModel::Invalid;
+ model = QVariant();
+ if(listModelInterface)
+ listModelInterface->disconnect(q);
+ listModelInterface = 0;
+ singleObject = 0;
+ roleCacheValid = false;
+ roleCache.clear();
+ }
+
+ void updateRoleCache()
+ {
+ if(roleCacheValid)
+ return;
+
+ roleCacheValid = true;
+ if(type == QmlListModel::SingleObject)
+ roleCache = QmlMetaProperty::properties(singleObject);
+ }
+
+ QmlListModel *q;
+
+ QmlListModel::ModelType type;
+
+ QVariant model;
+ QListModelInterface *listModelInterface;
+ QObject *singleObject;
+
+ bool roleCacheValid;
+ QStringList roleCache;
+};
+
+/*!
+ \qmlclass ListModel QmlListModel
+ \brief The ListModel element defines a free-form list data source.
+
+ The ListModel is a simple XML heirarchy of items containing data roles.
+ For example:
+
+ \code
+ <ListModel id="FruitModel">
+ <Fruit>
+ <name>Apple</name>
+ <cost>2.45</cost>
+ <Fruit>
+ <Fruit>
+ <name>Orange</name>
+ <cost>3.25</cost>
+ </Fruit>
+ <Fruit>
+ <name>Banana</name>
+ <cost>1.95</cost>
+ </Fruit>
+ </ListModel>
+ \endcode
+
+ Elements beginning with a capital are items. Elements beginning
+ with lower-case are the data roles. The above example defines a
+ ListModel containing three items, with the roles "name" and "cost".
+
+ The defined model can be used in views such as ListView:
+ \code
+ <Component id="FruitDelegate">
+ <Item width="200" height="50">
+ <Text text="{name}"/>
+ <Text text="{'$'+cost}" anchors.right="{parent.right}"/>
+ </Item>
+ </Component>
+
+ <ListView model="{FruitModel}" delegate="{FruitDelegate}" anchors.fill="{parent}"/>
+ \endcode
+*/
+/*!
+ \internal
+ \class QmlListModel
+*/
+QmlListModel::QmlListModel(QObject *parent)
+: QListModelInterface(parent), d(new QmlListModelPrivate(this))
+{
+}
+
+QmlListModel::~QmlListModel()
+{
+ delete d; d = 0;
+}
+
+QmlListModel::ModelType QmlListModel::modelType() const
+{
+ return d->type;
+}
+
+bool QmlListModel::setModel(const QVariant &model)
+{
+ d->clear();
+
+ QListModelInterface *iface = qvariant_cast<QListModelInterface *>(model);
+ if(iface) {
+ QObject::connect(iface, SIGNAL(itemsInserted(int,int)),
+ this, SIGNAL(itemsInserted(int,int)));
+ QObject::connect(iface, SIGNAL(itemsRemoved(int,int)),
+ this, SIGNAL(itemsRemoved(int,int)));
+ QObject::connect(iface, SIGNAL(itemsMoved(int,int,int)),
+ this, SIGNAL(itemsMoved(int,int,int)));
+ QObject::connect(iface, SIGNAL(itemsChanged(int,int,QList<int>)),
+ this, SIGNAL(itemsChanged(int,int,QList<int>)));
+ d->listModelInterface = iface;
+ d->type = ListInterface;
+ d->model = model;
+ return true;
+ }
+
+ QObject *object = qvariant_cast<QObject *>(model);
+ if(object) {
+ d->singleObject = object;
+ d->type = SingleObject;
+ d->model = model;
+ return true;
+ }
+
+ if(QmlMetaType::isList(model)) {
+ d->type = SimpleList;
+ d->model = model;
+ return true;
+ }
+
+ return false;
+}
+
+QVariant QmlListModel::model() const
+{
+ return d->model;
+}
+
+QList<int> QmlListModel::roles() const
+{
+ d->updateRoleCache();
+ switch(modelType()) {
+ case Invalid:
+ return QList<int>();
+ case SimpleList:
+ return QList<int>() << DATA_ROLE_ID;
+ case ListInterface:
+ return d->listModelInterface->roles();
+ case SingleObject:
+ {
+ QList<int> rv;
+ for(int ii = 0; ii < d->roleCache.count(); ++ii)
+ rv << ii;
+ return rv;
+ }
+ break;
+ };
+ return QList<int>();
+}
+
+QString QmlListModel::toString(int role) const
+{
+ d->updateRoleCache();
+ switch(modelType()) {
+ case Invalid:
+ return QString();
+ case SimpleList:
+ if(role == DATA_ROLE_ID)
+ return QLatin1String(DATA_ROLE_NAME);
+ else
+ return QString();
+ case ListInterface:
+ return d->listModelInterface->toString(role);
+ case SingleObject:
+ if(role >= d->roleCache.count())
+ return QString();
+ else
+ return d->roleCache.at(role);
+ };
+ return QString();
+}
+
+/*!
+ \qmlproperty int ListModel::count
+ This property holds the number of items in the list.
+*/
+int QmlListModel::count() const
+{
+ switch(modelType()) {
+ case Invalid:
+ return 0;
+ case SimpleList:
+ return QmlMetaType::listCount(model());
+ case ListInterface:
+ return d->listModelInterface->count();
+ case SingleObject:
+ return 1;
+ }
+ return 0;
+}
+
+QHash<int,QVariant> QmlListModel::data(int index, const QList<int> &roles) const
+{
+ d->updateRoleCache();
+ QHash<int, QVariant> rv;
+ switch(modelType()) {
+ case Invalid:
+ break;
+ case SimpleList:
+ if(roles.contains(DATA_ROLE_ID))
+ rv.insert(DATA_ROLE_ID, QmlMetaType::listAt(d->model, index));
+ break;
+ case ListInterface:
+ return d->listModelInterface->data(index, roles);
+ case SingleObject:
+ {
+ for(int ii = 0; ii < roles.count(); ++ii) {
+ QmlMetaProperty prop(d->singleObject, toString(roles.at(ii)));
+ rv.insert(roles.at(ii), prop.read());
+ }
+ }
+ break;
+ };
+
+ return rv;
+}
+
+
+
+struct ModelNode;
+class ListModel : public QListModelInterface
+{
+ Q_OBJECT
+public:
+ ListModel(QObject *parent=0);
+
+ virtual QList<int> roles() const;
+ virtual QString toString(int role) const;
+ Q_PROPERTY(int count READ count);
+ virtual int count() const;
+ virtual QHash<int,QVariant> data(int index, const QList<int> &roles = (QList<int>())) const;
+
+private:
+ QVariant valueForNode(ModelNode *) const;
+ mutable QStringList roleStrings;
+ friend class ListModelParser;
+ friend struct ModelNode;
+
+ void checkRoles() const;
+ void addRole(const QString &) const;
+ mutable bool _rolesOk;
+ ModelNode *_root;
+};
+
+class ModelObject : public QObject
+{
+ Q_OBJECT
+public:
+ ModelObject(ModelNode *);
+
+ void setValue(const QByteArray &name, const QVariant &val)
+ {
+ _mo->setValue(name, val);
+ }
+
+private:
+ ModelNode *_node;
+ bool _haveProperties;
+ QmlOpenMetaObject *_mo;
+};
+
+struct ModelNode
+{
+ ModelNode();
+ ~ModelNode();
+ QString className;
+
+ QList<QVariant> values;
+ QHash<QString, ModelNode *> properties;
+
+ ListModel *model() {
+ if(!modelCache) {
+ modelCache = new ListModel;
+ modelCache->_root = this;
+ }
+ return modelCache;
+ }
+
+ ModelObject *object() {
+ if(!objectCache) {
+ objectCache = new ModelObject(this);
+ QHash<QString, ModelNode *>::iterator it;
+ for (it = properties.begin(); it != properties.end(); ++it) {
+ if (!(*it)->values.isEmpty())
+ objectCache->setValue(it.key().toLatin1(), (*it)->values.first());
+ }
+ }
+ return objectCache;
+ }
+
+ ListModel *modelCache;
+ ModelObject *objectCache;
+};
+Q_DECLARE_METATYPE(ModelNode *);
+
+ModelObject::ModelObject(ModelNode *node)
+: _node(node), _haveProperties(false), _mo(new QmlOpenMetaObject(this))
+{
+}
+
+QML_DECLARE_TYPE(ListModel);
+QML_DEFINE_TYPE(ListModel,ListModel);
+ListModel::ListModel(QObject *parent)
+: QListModelInterface(parent), _rolesOk(false), _root(0)
+{
+}
+
+void ListModel::checkRoles() const
+{
+ if(_rolesOk)
+ return;
+
+ for(int ii = 0; ii < _root->values.count(); ++ii) {
+ ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(ii));
+ if(node) {
+ foreach(QString role, node->properties.keys())
+ addRole(role);
+ }
+ }
+
+ _rolesOk = true;
+}
+
+void ListModel::addRole(const QString &role) const
+{
+ if(!roleStrings.contains(role))
+ roleStrings << role;
+}
+
+QList<int> ListModel::roles() const
+{
+ checkRoles();
+ QList<int> rv;
+ for(int ii = 0; ii < roleStrings.count(); ++ii)
+ rv << ii;
+ return rv;
+}
+
+QString ListModel::toString(int role) const
+{
+ checkRoles();
+ if(role < roleStrings.count())
+ return roleStrings.at(role);
+ else
+ return QString();
+}
+
+QVariant ListModel::valueForNode(ModelNode *node) const
+{
+ QObject *rv = 0;
+
+ if(!node->properties.isEmpty()) {
+ // Object
+ rv = node->object();
+ } else if(node->values.count() == 0) {
+ // Invalid
+ return QVariant();
+ } else if(node->values.count() == 1) {
+ // Value
+ QVariant &var = node->values[0];
+ ModelNode *valueNode = qvariant_cast<ModelNode *>(var);
+ if(valueNode) {
+ if(!valueNode->properties.isEmpty())
+ rv = valueNode->object();
+ else
+ rv = valueNode->model();
+ } else {
+ return var;
+ }
+ } else if(node->values.count() > 1) {
+ // List
+ rv = node->model();
+ }
+
+ if(rv)
+ return QVariant::fromValue(rv);
+ else
+ return QVariant();
+}
+
+QHash<int,QVariant> ListModel::data(int index, const QList<int> &roles) const
+{
+ checkRoles();
+ QHash<int, QVariant> rv;
+ if(index >= count())
+ return rv;
+
+ ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
+ if(!node)
+ return rv;
+
+ for(int ii = 0; ii < roles.count(); ++ii) {
+ const QString &roleString = roleStrings.at(roles.at(ii));
+
+ QHash<QString, ModelNode *>::ConstIterator iter =
+ node->properties.find(roleString);
+ if(iter != node->properties.end()) {
+ ModelNode *row = *iter;
+ rv.insert(roles.at(ii), valueForNode(row));
+ }
+ }
+
+ return rv;
+}
+
+int ListModel::count() const
+{
+ if(!_root) return 0;
+ return _root->values.count();
+}
+
+struct ListInstruction
+{
+ enum { Push, Pop, Value, Set } type;
+ int dataIdx;
+};
+
+class ListModelParser : public QmlCustomParser
+{
+public:
+ virtual QByteArray compile(QXmlStreamReader& reader, bool *);
+ virtual QVariant create(const QByteArray &);
+};
+QML_DEFINE_CUSTOM_PARSER(ListModel, ListModelParser);
+
+static void dump(ModelNode *node, int ind)
+{
+ QByteArray indentBa(ind * 4, ' ');
+ const char *indent = indentBa.constData();
+
+ for(int ii = 0; ii < node->values.count(); ++ii) {
+ ModelNode *subNode = qvariant_cast<ModelNode *>(node->values.at(ii));
+ if(subNode) {
+ qWarning().nospace() << indent << "Sub-node " << ii << ": class " << subNode->className;
+ dump(subNode, ind + 1);
+ } else {
+ qWarning().nospace() << indent << "Sub-node " << ii << ": " << node->values.at(ii).toString();
+ }
+ }
+
+ for(QHash<QString, ModelNode *>::ConstIterator iter = node->properties.begin(); iter != node->properties.end(); ++iter) {
+ qWarning().nospace() << indent << "Property " << iter.key() << ":";
+ dump(iter.value(), ind + 1);
+ }
+}
+
+ModelNode::ModelNode()
+: modelCache(0), objectCache(0)
+{
+}
+
+ModelNode::~ModelNode()
+{
+ qDeleteAll(properties);
+ for(int ii = 0; ii < values.count(); ++ii) {
+ ModelNode *node = qvariant_cast<ModelNode *>(values.at(ii));
+ if(node) { delete node; node = 0; }
+ }
+ if(modelCache) { delete modelCache; modelCache = 0; }
+}
+
+struct ListModelData
+{
+ int dataOffset;
+ int id;
+ int instrCount;
+ ListInstruction *instructions() const { return (ListInstruction *)((char *)this + sizeof(ListModelData)); }
+};
+
+QByteArray ListModelParser::compile(QXmlStreamReader& reader, bool *ok)
+{
+ *ok = true;
+
+ QByteArray id;
+ QByteArray data;
+ QList<ListInstruction> instr;
+ int depth=0;
+
+ while(!reader.atEnd() && depth >= 0) {
+ switch(reader.readNext()) {
+ case QXmlStreamReader::StartElement:
+ {
+ QStringRef name = reader.name();
+ bool isType = name.at(0).isUpper();
+
+ if (isType) {
+ ListInstruction li;
+ li.type = ListInstruction::Push;
+ li.dataIdx = -1;
+ instr << li;
+
+ for (int i = 0; i < reader.attributes().count(); ++i) {
+ const QXmlStreamAttribute &attr = reader.attributes().at(i);
+ QStringRef attrName = attr.name();
+ QStringRef attrValue = attr.value();
+
+ ListInstruction li;
+ int ref = data.count();
+ data.append(attrName.toString().toLatin1());
+ data.append('\0');
+ li.type = ListInstruction::Set;
+ li.dataIdx = ref;
+ instr << li;
+
+ ref = data.count();
+ data.append(attrValue.toString().toLatin1());
+ data.append('\0');
+ li.type = ListInstruction::Value;
+ li.dataIdx = ref;
+ instr << li;
+
+ li.type = ListInstruction::Pop;
+ li.dataIdx = -1;
+ instr << li;
+ }
+ } else {
+ ListInstruction li;
+ int ref = data.count();
+ data.append(name.toString().toLatin1());
+ data.append('\0');
+ li.type = ListInstruction::Set;
+ li.dataIdx = ref;
+ instr << li;
+ }
+ }
+ ++depth;
+ break;
+ case QXmlStreamReader::EndElement:
+ {
+ ListInstruction li;
+ li.type = ListInstruction::Pop;
+ li.dataIdx = -1;
+ instr << li;
+ --depth;
+ }
+ break;
+ case QXmlStreamReader::Characters:
+ if (!reader.isWhitespace()) {
+ int ref = data.count();
+ QByteArray d = reader.text().toString().toLatin1();
+ d.append('\0');
+ data.append(d);
+
+ ListInstruction li;
+ li.type = ListInstruction::Value;
+ li.dataIdx = ref;
+ instr << li;
+ }
+ break;
+
+ case QXmlStreamReader::Invalid:
+ case QXmlStreamReader::NoToken:
+ case QXmlStreamReader::StartDocument:
+ case QXmlStreamReader::EndDocument:
+ case QXmlStreamReader::Comment:
+ case QXmlStreamReader::DTD:
+ case QXmlStreamReader::EntityReference:
+ case QXmlStreamReader::ProcessingInstruction:
+ break;
+ }
+ }
+
+ if (reader.hasError())
+ *ok = true;
+
+ if (!*ok)
+ return QByteArray();
+
+ int size = sizeof(ListModelData) +
+ instr.count() * sizeof(ListInstruction) +
+ data.count();
+
+ QByteArray rv;
+ rv.resize(size);
+
+ ListModelData *lmd = (ListModelData *)rv.data();
+ if(id.count())
+ lmd->id = 0;
+ else
+ lmd->id = -1;
+ lmd->dataOffset = sizeof(ListModelData) +
+ instr.count() * sizeof(ListInstruction);
+ lmd->instrCount = instr.count();
+ for(int ii = 0; ii < instr.count(); ++ii)
+ lmd->instructions()[ii] = instr.at(ii);
+ ::memcpy(rv.data() + lmd->dataOffset, data.constData(), data.count());
+
+ return rv;
+}
+
+QVariant ListModelParser::create(const QByteArray &d)
+{
+ ListModel *rv = new ListModel;
+ ModelNode *root = new ModelNode;
+ rv->_root = root;
+ QStack<ModelNode *> nodes;
+ nodes << root;
+
+ const ListModelData *lmd = (const ListModelData *)d.constData();
+ const char *data = ((const char *)lmd) + lmd->dataOffset;
+
+ for(int ii = 0; ii < lmd->instrCount; ++ii) {
+ const ListInstruction &instr = lmd->instructions()[ii];
+
+ switch(instr.type) {
+ case ListInstruction::Push:
+ {
+ ModelNode *n = nodes.top();
+ ModelNode *n2 = new ModelNode;
+ n->values << qVariantFromValue(n2);
+ nodes.push(n2);
+ }
+ break;
+
+ case ListInstruction::Pop:
+ nodes.pop();
+ break;
+
+ case ListInstruction::Value:
+ {
+ ModelNode *n = nodes.top();
+ n->values.append(QByteArray(data + instr.dataIdx));
+ }
+ break;
+
+ case ListInstruction::Set:
+ {
+ ModelNode *n = nodes.top();
+ ModelNode *n2 = new ModelNode;
+ n->properties.insert(QLatin1String(data + instr.dataIdx), n2);
+ nodes.push(n2);
+ }
+ break;
+ }
+ }
+
+ if(lmd->id != -1) {
+ QmlContext *ctxt = QmlContext::activeContext();
+ ctxt->setContextProperty(QLatin1String(data + lmd->id), rv);
+ }
+
+ return QVariant::fromValue(rv);
+}
+
+QT_END_NAMESPACE
+#include "qmllistmodel.moc"
diff --git a/src/declarative/util/qmllistmodel.h b/src/declarative/util/qmllistmodel.h
new file mode 100644
index 0000000..3dcac4f
--- /dev/null
+++ b/src/declarative/util/qmllistmodel.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLLISTMODEL_H
+#define QMLLISTMODEL_H
+
+#include <QObject>
+#include <qfxglobal.h>
+#include <QStringList>
+#include <QHash>
+#include <QList>
+#include <QVariant>
+#include <qml.h>
+#include <qlistmodelinterface.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QmlListModelPrivate;
+class Q_DECLARATIVE_EXPORT QmlListModel : public QListModelInterface
+{
+Q_OBJECT
+public:
+ QmlListModel(QObject *parent = 0);
+ virtual ~QmlListModel();
+
+ enum ModelType {
+ Invalid,
+ SimpleList,
+ ListInterface,
+ SingleObject
+ };
+
+ ModelType modelType() const;
+ bool setModel(const QVariant &);
+ QVariant model() const;
+
+ virtual QList<int> roles() const;
+ virtual QString toString(int role) const;
+
+ Q_PROPERTY(int count READ count);
+ virtual int count() const;
+ virtual QHash<int,QVariant>
+ data(int index, const QList<int> &roles = (QList<int>())) const;
+private:
+ QmlListModelPrivate *d;
+};
+QML_DECLARE_TYPE(QmlListModel);
+
+#endif // QMLLISTMODEL_H
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
diff --git a/src/declarative/util/qmlnullablevalue_p.h b/src/declarative/util/qmlnullablevalue_p.h
new file mode 100644
index 0000000..f16ddd6
--- /dev/null
+++ b/src/declarative/util/qmlnullablevalue_p.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLNULLABLEVALUE_P_H
+#define QMLNULLABLEVALUE_P_H
+
+template<typename T>
+struct QmlNullableValue
+{
+ QmlNullableValue()
+ : isNull(true), value(T()) {}
+ QmlNullableValue(const QmlNullableValue<T> &o)
+ : isNull(o.isNull), value(o.value) {}
+ QmlNullableValue(const T &t)
+ : isNull(false), value(t) {}
+ QmlNullableValue<T> &operator=(const T &t)
+ { isNull = false; value = t; return *this; }
+ QmlNullableValue<T> &operator=(const QmlNullableValue<T> &o)
+ { isNull = o.isNull; value = o.value; return *this; }
+ operator T() const { return value; }
+
+ void invalidate() { isNull = true; }
+ bool isValid() const { return !isNull; }
+ bool isNull;
+ T value;
+};
+
+#endif // QMLNULLABLEVALUE_P_H
+
diff --git a/src/declarative/util/qmlopenmetaobject.cpp b/src/declarative/util/qmlopenmetaobject.cpp
new file mode 100644
index 0000000..09d71bd
--- /dev/null
+++ b/src/declarative/util/qmlopenmetaobject.cpp
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlopenmetaobject.h"
+#include <QDebug>
+
+
+QT_BEGIN_NAMESPACE
+QmlOpenMetaObject::QmlOpenMetaObject(QObject *obj, bool automatic)
+: autoCreate(automatic), parent(0), mem(0), _object(obj)
+{
+ mob.setSuperClass(obj->metaObject());
+ mob.setFlags(QMetaObjectBuilder::DynamicMetaObject);
+
+ QObjectPrivate *op = QObjectPrivate::get(obj);
+ if(op->metaObject)
+ mob.setSuperClass(op->metaObject);
+
+ mem = mob.toMetaObject();
+ *static_cast<QMetaObject *>(this) = *mem;
+ op->metaObject = this;
+ _propertyOffset = propertyOffset();
+ _signalOffset = methodOffset();
+}
+
+QmlOpenMetaObject::~QmlOpenMetaObject()
+{
+ if(parent)
+ delete parent;
+ qFree(mem);
+}
+
+int QmlOpenMetaObject::metaCall(QMetaObject::Call c, int id, void **a)
+{
+ if(( c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty)
+ && id >= _propertyOffset) {
+ int propId = id - _propertyOffset;
+ if(c == QMetaObject::ReadProperty) {
+ propertyRead(propId);
+ *reinterpret_cast<QVariant *>(a[0]) = data[propId];
+ } else if(c == QMetaObject::WriteProperty) {
+ if(data[propId] != *reinterpret_cast<QVariant *>(a[0])) {
+ propertyWrite(propId);
+ data[propId] = *reinterpret_cast<QVariant *>(a[0]);
+ activate(_object, _signalOffset + propId, 0);
+ }
+ }
+ return -1;
+ } else {
+ if(parent)
+ return parent->metaCall(c, id, a);
+ else
+ return _object->qt_metacall(c, id, a);
+ }
+}
+
+QVariant QmlOpenMetaObject::value(int id) const
+{
+ Q_ASSERT(id >= 0 && id < data.count());
+ return data.at(id);
+}
+
+void QmlOpenMetaObject::setValue(int id, const QVariant &value)
+{
+ Q_ASSERT(id >= 0 && id < data.count());
+ data[id] = value;
+ activate(_object, id + _signalOffset, 0);
+}
+
+QVariant QmlOpenMetaObject::value(const QByteArray &name) const
+{
+ QHash<QByteArray, int>::ConstIterator iter = names.find(name);
+ if(iter == names.end())
+ return QVariant();
+
+ return data.at(*iter);
+}
+
+void QmlOpenMetaObject::setValue(const QByteArray &name, const QVariant &val)
+{
+ QHash<QByteArray, int>::ConstIterator iter = names.find(name);
+
+ int id = -1;
+ if(iter == names.end()) {
+ id = doCreateProperty(name.constData()) - _propertyOffset;
+ } else {
+ id = *iter;
+ }
+
+ if(data[id] == val)
+ return;
+
+ data[id] = val;
+ activate(_object, id + _signalOffset, 0);
+}
+
+int QmlOpenMetaObject::createProperty(const char *name, const char *)
+{
+ if(autoCreate)
+ return doCreateProperty(name);
+ else
+ return -1;
+}
+
+int QmlOpenMetaObject::doCreateProperty(const char *name)
+{
+ int id = mob.propertyCount();
+ mob.addSignal("__" + QByteArray::number(id) + "()");
+ QMetaPropertyBuilder build = mob.addProperty(name, "QVariant", id);
+ build.setDynamic(true);
+ data << propertyCreated(id, build);
+ qFree(mem);
+ mem = mob.toMetaObject();
+ *static_cast<QMetaObject *>(this) = *mem;
+ names.insert(name, id);
+
+ return _propertyOffset + id;
+}
+
+void QmlOpenMetaObject::propertyRead(int)
+{
+}
+
+void QmlOpenMetaObject::propertyWrite(int)
+{
+}
+
+QVariant QmlOpenMetaObject::propertyCreated(int, QMetaPropertyBuilder &)
+{
+ return QVariant();
+}
+
+int QmlOpenMetaObject::count() const
+{
+ return data.count();
+}
+
+QByteArray QmlOpenMetaObject::name(int idx) const
+{
+ Q_ASSERT(idx >= 0 && idx < data.count());
+
+ return mob.property(idx).name();
+}
+
+QObject *QmlOpenMetaObject::object() const
+{
+ return _object;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qmlopenmetaobject.h b/src/declarative/util/qmlopenmetaobject.h
new file mode 100644
index 0000000..17cecd87
--- /dev/null
+++ b/src/declarative/util/qmlopenmetaobject.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLOPENMETAOBJECT_H
+#define QMLOPENMETAOBJECT_H
+
+#include <QMetaObject>
+#include "private/qmetaobjectbuilder_p.h"
+#include <private/qobject_p.h>
+#include <QObject>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class Q_DECLARATIVE_EXPORT QmlOpenMetaObject : public QAbstractDynamicMetaObject
+{
+public:
+ QmlOpenMetaObject(QObject *, bool = true);
+ ~QmlOpenMetaObject();
+
+ QVariant value(const QByteArray &) const;
+ void setValue(const QByteArray &, const QVariant &);
+ QVariant value(int) const;
+ void setValue(int, const QVariant &);
+
+ int count() const;
+ QByteArray name(int) const;
+
+ QObject *object() const;
+protected:
+ virtual int metaCall(QMetaObject::Call _c, int _id, void **_a);
+ virtual int createProperty(const char *, const char *);
+
+ virtual void propertyRead(int);
+ virtual void propertyWrite(int);
+ virtual QVariant propertyCreated(int, QMetaPropertyBuilder &);
+
+private:
+ int doCreateProperty(const char *);
+ bool autoCreate;
+ QAbstractDynamicMetaObject *parent;
+ int _propertyOffset;
+ int _signalOffset;
+ QList<QVariant> data;
+ QHash<QByteArray, int> names;
+ QMetaObjectBuilder mob;
+ QMetaObject *mem;
+ QObject *_object;
+};
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+#endif // QMLOPENMETAOBJECT_H
diff --git a/src/declarative/util/qmlpackage.cpp b/src/declarative/util/qmlpackage.cpp
new file mode 100644
index 0000000..264d186
--- /dev/null
+++ b/src/declarative/util/qmlpackage.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "private/qobject_p.h"
+#include "qmlpackage.h"
+
+
+QT_BEGIN_NAMESPACE
+class QmlPackagePrivate : public QObjectPrivate
+{
+public:
+ QmlPackagePrivate() {}
+
+ QmlConcreteList<QObject *> dataList;
+};
+
+class QmlPackageAttached : public QObject
+{
+Q_OBJECT
+public:
+ QmlPackageAttached(QObject *parent);
+ virtual ~QmlPackageAttached();
+
+ Q_PROPERTY(QString name READ name WRITE setName);
+ QString name() const;
+ void setName(const QString &n);
+
+ static QHash<QObject *, QmlPackageAttached *> attached;
+private:
+ QString _name;
+};
+
+QHash<QObject *, QmlPackageAttached *> QmlPackageAttached::attached;
+
+QmlPackageAttached::QmlPackageAttached(QObject *parent)
+: QObject(parent)
+{
+ attached.insert(parent, this);
+}
+
+QmlPackageAttached::~QmlPackageAttached()
+{
+ attached.remove(parent());
+}
+
+QString QmlPackageAttached::name() const
+{
+ return _name;
+}
+
+void QmlPackageAttached::setName(const QString &n)
+{
+ _name = n;
+}
+
+QmlPackage::QmlPackage(QObject *parent)
+ : QObject(*(new QmlPackagePrivate), parent)
+{
+}
+
+QmlPackage::~QmlPackage()
+{
+}
+
+QmlList<QObject *> *QmlPackage::data()
+{
+ Q_D(QmlPackage);
+ return &d->dataList;
+}
+
+bool QmlPackage::hasPart(const QString &name)
+{
+ Q_D(QmlPackage);
+ for(int ii = 0; ii < d->dataList.count(); ++ii) {
+ QObject *obj = d->dataList.at(ii);
+ QmlPackageAttached *a = QmlPackageAttached::attached.value(obj);
+ if(a && a->name() == name)
+ return true;
+ }
+ return false;
+}
+
+QObject *QmlPackage::part(const QString &name)
+{
+ Q_D(QmlPackage);
+ if(name.isEmpty() && !d->dataList.isEmpty())
+ return d->dataList.at(0);
+
+ for(int ii = 0; ii < d->dataList.count(); ++ii) {
+ QObject *obj = d->dataList.at(ii);
+ QmlPackageAttached *a = QmlPackageAttached::attached.value(obj);
+ if(a && a->name() == name)
+ return obj;
+ }
+
+ if(name == QLatin1String("default") && !d->dataList.isEmpty())
+ return d->dataList.at(0);
+
+ return 0;
+}
+
+QObject *QmlPackage::qmlAttachedProperties(QObject *o)
+{
+ return new QmlPackageAttached(o);
+}
+
+QML_DEFINE_TYPE(QmlPackage, Package);
+
+QT_END_NAMESPACE
+#include "qmlpackage.moc"
diff --git a/src/declarative/util/qmlpackage.h b/src/declarative/util/qmlpackage.h
new file mode 100644
index 0000000..6652b98
--- /dev/null
+++ b/src/declarative/util/qmlpackage.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLPACKAGE_H
+#define QMLPACKAGE_H
+
+#include <qml.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+/*****************************************************************************
+ *****************************************************************************
+ XXX Experimental
+ *****************************************************************************
+*****************************************************************************/
+
+class QmlPackagePrivate;
+class QmlPackage : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlPackage)
+
+ Q_CLASSINFO("DefaultProperty", "data");
+ Q_PROPERTY(QmlList<QObject *> *data READ data SCRIPTABLE false);
+
+public:
+ QmlPackage(QObject *parent=0);
+ virtual ~QmlPackage();
+
+ QmlList<QObject *> *data();
+
+ QObject *part(const QString & = QString());
+ bool hasPart(const QString &);
+
+ static QObject *qmlAttachedProperties(QObject *);
+};
+QML_DECLARE_TYPE(QmlPackage);
+
+#endif // QMLPACKAGE_H
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
diff --git a/src/declarative/util/qmlscript.cpp b/src/declarative/util/qmlscript.cpp
new file mode 100644
index 0000000..a24c427
--- /dev/null
+++ b/src/declarative/util/qmlscript.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qmlbindablevalue.h>
+#include <QtDeclarative/qmlengine.h>
+#include <QtDeclarative/qmlcontext.h>
+#include <private/qobject_p.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qdebug.h>
+#include <QtScript/qscriptvalue.h>
+#include <QtScript/qscriptcontext.h>
+#include <QtScript/qscriptengine.h>
+#include <private/qmlnullablevalue_p.h>
+#include <private/qmlengine_p.h>
+#include <private/qmlcontext_p.h>
+#include "qmlscript.h"
+#include <QNetworkReply>
+#include <QNetworkRequest>
+#include <QtDeclarative/qmlinfo.h>
+
+QT_BEGIN_NAMESPACE
+
+
+
+class QmlScriptPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QmlScript);
+
+public:
+ QmlScriptPrivate() : reply(0), ctxt(0) {}
+
+ void addScriptToEngine(const QString &, const QString &fileName=QString());
+
+ QString script;
+ QString source;
+ QNetworkReply *reply;
+ QUrl url;
+ QmlContext *ctxt;
+};
+
+/*!
+ \qmlclass Script QmlScript
+ \brief The Script element adds JavaScript snippets.
+ \ingroup utility
+
+ QmlScript is used to add convenient JavaScript "glue" methods to
+ your Qt Declarative application or component. While you can have any JavaScript code
+ within a QmlScript, it is best to limit yourself to defining functions.
+
+ \qml
+ <Script>
+ function debugMyComponent() {
+ print(text.text);
+ print(otherinterestingitem.property);
+ }
+ </Script>
+ <MouseRegion onClicked="debugMyComponent()" />
+ \endqml
+
+ \note QmlScript executes JavaScript as soon as it is specified.
+ When defining a component, this may be before the execution context is
+ fully specified. As a result some properties or items may not be
+ accessible. By limiting your JavaScript to defining functions that are
+ only executed later once the context is fully defined, this problem is
+ avoided.
+*/
+
+QML_DEFINE_TYPE(QmlScript,Script);
+QmlScript::QmlScript(QObject *parent) : QObject(*(new QmlScriptPrivate), parent)
+{
+ Q_D(QmlScript);
+ d->ctxt = QmlContext::activeContext();
+}
+
+/*!
+ \qmlproperty string Script::script
+ \default
+ JavaScript code to execute.
+*/
+/*!
+ \property QmlScript::script
+ \brief a script snippet.
+*/
+QString QmlScript::script() const
+{
+ Q_D(const QmlScript);
+ return d->script;
+}
+
+void QmlScript::setScript(const QString &script)
+{
+ Q_D(QmlScript);
+ d->script = script;
+ d->addScriptToEngine(d->script);
+}
+
+/*!
+ \qmlproperty string Script::source
+
+ Setting this property causes the Script element to read JavaScript code from
+ the file specified.
+ */
+/*!
+ \property QmlScript::source
+ \brief the path to a script file.
+*/
+QString QmlScript::source() const
+{
+ Q_D(const QmlScript);
+ return d->source;
+}
+
+void QmlScript::setSource(const QString &source)
+{
+ Q_D(QmlScript);
+ if (d->source == source)
+ return;
+ d->source = source;
+ d->url = d->ctxt->resolvedUrl(source);
+ QNetworkRequest req(d->url);
+ req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
+ d->reply = d->ctxt->engine()->networkAccessManager()->get(req);
+ QObject::connect(d->reply, SIGNAL(finished()),
+ this, SLOT(replyFinished()));
+}
+
+void QmlScript::replyFinished()
+{
+ Q_D(QmlScript);
+ if (!d->reply->error()) {
+ QByteArray ba = d->reply->readAll();
+ d->addScriptToEngine(QString::fromUtf8(ba), d->source);
+ }
+ d->reply->deleteLater();
+ d->reply = 0;
+}
+
+void QmlScriptPrivate::addScriptToEngine(const QString &script, const QString &fileName)
+{
+ Q_Q(QmlScript);
+ QmlEngine *engine = ctxt->engine();
+ QScriptEngine *scriptEngine = engine->scriptEngine();
+
+ QScriptContext *currentContext = engine->scriptEngine()->currentContext();
+ QScriptValueList oldScopeChain = currentContext->scopeChain();
+ QScriptValue oldact = currentContext->activationObject();
+
+ for (int i = 0; i < oldScopeChain.size(); ++i) {
+ currentContext->popScope();
+ }
+ for (int i = ctxt->d_func()->scopeChain.size() - 1; i > -1; --i) {
+ currentContext->pushScope(ctxt->d_func()->scopeChain.at(i));
+ }
+
+ currentContext->setActivationObject(ctxt->d_func()->scopeChain.at(0));
+
+ QScriptValue val = scriptEngine->evaluate(script, fileName);
+ if (scriptEngine->hasUncaughtException()) {
+ if (scriptEngine->uncaughtException().isError()){
+ QScriptValue exception = scriptEngine->uncaughtException();
+ if(!exception.property(QLatin1String("fileName")).toString().isEmpty()){
+ qWarning() << exception.property(QLatin1String("fileName")).toString()
+ << scriptEngine->uncaughtExceptionLineNumber()
+ << exception.toString();
+
+ } else {
+ qmlInfo(q) << exception.toString();
+ }
+ }
+ }
+
+ currentContext->setActivationObject(oldact);
+
+ for (int i = 0; i < ctxt->d_func()->scopeChain.size(); ++i)
+ currentContext->popScope();
+
+ for (int i = oldScopeChain.size() - 1; i > -1; --i)
+ currentContext->pushScope(oldScopeChain.at(i));
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qmlscript.h b/src/declarative/util/qmlscript.h
new file mode 100644
index 0000000..fc038b4
--- /dev/null
+++ b/src/declarative/util/qmlscript.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLSCRIPT_H
+#define QMLSCRIPT_H
+
+#include <qfxglobal.h>
+#include <QtCore/qobject.h>
+#include "qml.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QmlScriptPrivate;
+class Q_DECLARATIVE_EXPORT QmlScript : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlScript);
+
+ Q_PROPERTY(QString script READ script WRITE setScript);
+ Q_PROPERTY(QString src READ source WRITE setSource);
+ Q_CLASSINFO("DefaultProperty", "script");
+
+public:
+ QmlScript(QObject *parent=0);
+
+ QString script() const;
+ void setScript(const QString &);
+
+ QString source() const;
+ void setSource(const QString &);
+
+private Q_SLOTS:
+ void replyFinished();
+};
+QML_DECLARE_TYPE(QmlScript);
+
+QT_END_NAMESPACE
+QT_END_HEADER
+#endif
diff --git a/src/declarative/util/qmlsetproperties.cpp b/src/declarative/util/qmlsetproperties.cpp
new file mode 100644
index 0000000..f385391
--- /dev/null
+++ b/src/declarative/util/qmlsetproperties.cpp
@@ -0,0 +1,247 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "private/qobject_p.h"
+#include "qmlopenmetaobject.h"
+#include "qmlsetproperties.h"
+#include <QtCore/qdebug.h>
+#include <QtDeclarative/qmlinfo.h>
+
+
+QT_BEGIN_NAMESPACE
+class QmlSetPropertiesMetaObject : public QmlOpenMetaObject
+{
+public:
+ QmlSetPropertiesMetaObject(QObject *);
+
+protected:
+ virtual void propertyRead(int);
+ virtual void propertyWrite(int);
+};
+
+class QmlSetPropertiesProxyObject : public QObject
+{
+Q_OBJECT
+public:
+ QmlSetPropertiesProxyObject(QObject *);
+
+ QmlSetPropertiesMetaObject *fxMetaObject() const { return _mo; }
+private:
+ QmlSetPropertiesMetaObject *_mo;
+};
+
+QmlSetPropertiesProxyObject::QmlSetPropertiesProxyObject(QObject *parent)
+: QObject(parent), _mo(new QmlSetPropertiesMetaObject(this))
+{
+}
+
+QmlSetPropertiesMetaObject::QmlSetPropertiesMetaObject(QObject *obj)
+: QmlOpenMetaObject(obj)
+{
+}
+
+void QmlSetPropertiesMetaObject::propertyRead(int id)
+{
+ if(!value(id).isValid())
+ setValue(id, QVariant::fromValue((QObject *)new QmlSetPropertiesProxyObject(object())));
+
+ QmlOpenMetaObject::propertyRead(id);
+}
+
+void QmlSetPropertiesMetaObject::propertyWrite(int id)
+{
+ if(value(id).userType() == qMetaTypeId<QObject *>()) {
+ QObject *val = qvariant_cast<QObject *>(value(id));
+ QmlSetPropertiesProxyObject *proxy = qobject_cast<QmlSetPropertiesProxyObject *>(val);
+ if(proxy) {
+ setValue(id, QVariant());
+ delete proxy;
+ }
+ }
+ QmlOpenMetaObject::propertyWrite(id);
+}
+
+/*!
+ \qmlclass SetProperties QmlSetProperties
+ \brief The SetProperties element describes new property values for a state.
+
+ SetProperties is a convenience element for changing many properties on a single
+ object. It allows you to specify the property names and values similar to how
+ you normally would specify them for the actual item:
+
+ \code
+ <SetProperties target="{myRect}" x="52" y="300" width="48"/>
+ \endcode
+
+ \c target is a property of \c SetProperties, so if the property you want to change
+ is named \e target you will have to use \l SetProperty instead. You should also
+ use \l SetProperty if you want to update the binding for a property,
+ as SetProperties does not support this.
+*/
+
+/*!
+ \internal
+ \class QmlSetProperties
+ \brief The QmlSetProperties class describes new property values for a state.
+
+ \ingroup states
+
+ QmlSetProperties is a convenience class for changing many properties on a single
+ object. It allows you to specify the property names and values similar to how
+ you normally would specify them for the actual item:
+
+ \code
+ <SetProperties target="{myRect}" x="52" y="300" width="48"/>
+ \endcode
+
+ \c target is a property of \c SetProperties, so if the property you want to change
+ is named \e target you will have to use QmlSetProperty instead. You should also use QmlSetProperty
+ if you want to update the binding for a property, as QmlSetProperties does not support this.
+
+ \sa QmlSetProperty
+*/
+
+class QmlSetPropertiesPrivate : public QObjectPrivate
+{
+public:
+ QmlSetPropertiesPrivate() : obj(0), mo(0) {}
+
+ QObject *obj;
+ QmlSetPropertiesMetaObject *mo;
+};
+
+QML_DEFINE_TYPE(QmlSetProperties,SetProperties);
+QmlSetProperties::QmlSetProperties()
+ : QmlStateOperation(*(new QmlSetPropertiesPrivate))
+{
+ Q_D(QmlSetProperties);
+ d->mo = new QmlSetPropertiesMetaObject(this);
+}
+
+QmlSetProperties::QmlSetProperties(QObject *parent)
+ : QmlStateOperation(*(new QmlSetPropertiesPrivate), parent)
+{
+ Q_D(QmlSetProperties);
+ d->mo = new QmlSetPropertiesMetaObject(this);
+}
+
+QmlSetProperties::~QmlSetProperties()
+{
+}
+
+/*!
+ \qmlproperty Object SetProperties::target
+ This property holds the object that the properties to change belong to
+*/
+
+/*!
+ \property QmlSetProperties::target
+ \brief the object that the properties to change belong to
+*/
+QObject *QmlSetProperties::object()
+{
+ Q_D(QmlSetProperties);
+ return d->obj;
+}
+
+void QmlSetProperties::setObject(QObject *o)
+{
+ Q_D(QmlSetProperties);
+ d->obj = o;
+}
+
+QmlSetProperties::ActionList
+QmlSetProperties::doAction(QmlSetPropertiesMetaObject *metaObject,
+ QObject *object)
+{
+ ActionList list;
+
+ for (int ii = 0; ii < metaObject->count(); ++ii) {
+
+ QByteArray name = metaObject->name(ii);
+ QVariant value = metaObject->value(ii);
+
+ QmlSetPropertiesProxyObject *po = qobject_cast<QmlSetPropertiesProxyObject *>(qvariant_cast<QObject *>(value));
+
+ QmlMetaProperty prop(object, QLatin1String(name));
+
+ if(po) {
+ QObject *objVal = QmlMetaType::toQObject(prop.read());
+ if(!objVal) {
+ qmlInfo(this) << object->metaObject()->className()
+ << "has no object property named" << name;
+ continue;
+ }
+
+ list << doAction(po->fxMetaObject(), objVal);
+ } else if (!prop.isValid()) {
+ qmlInfo(this) << object->metaObject()->className()
+ << "has no property named" << name;
+ continue;
+ } else if (!prop.isWritable()) {
+ qmlInfo(this) << object->metaObject()->className()
+ << name << "is not writable, and cannot be set.";
+ continue;
+ } else {
+ //append action
+ Action a;
+ a.property = prop;
+ a.fromValue = prop.read();
+ a.toValue = value;
+
+ list << a;
+ }
+ }
+
+ return list;
+}
+
+QmlSetProperties::ActionList QmlSetProperties::actions()
+{
+ Q_D(QmlSetProperties);
+ if (!d->obj)
+ return ActionList();
+
+ return doAction(d->mo, d->obj);
+}
+
+QT_END_NAMESPACE
+#include "qmlsetproperties.moc"
diff --git a/src/declarative/util/qmlsetproperties.h b/src/declarative/util/qmlsetproperties.h
new file mode 100644
index 0000000..456b672
--- /dev/null
+++ b/src/declarative/util/qmlsetproperties.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLSETPROPERTIES_H
+#define QMLSETPROPERTIES_H
+
+#include <qmlstateoperations.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QmlSetPropertiesMetaObject;
+class QmlSetPropertiesPrivate;
+class Q_DECLARATIVE_EXPORT QmlSetProperties : public QmlStateOperation
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlSetProperties);
+
+ Q_PROPERTY(QObject *target READ object WRITE setObject);
+
+public:
+ QmlSetProperties();
+ QmlSetProperties(QObject *parent);
+ ~QmlSetProperties();
+
+ QObject *object();
+ void setObject(QObject *);
+
+ virtual ActionList actions();
+
+private:
+ ActionList doAction(QmlSetPropertiesMetaObject *, QObject *);
+ //QmlSetProperties::ActionList appendDotActions(const QVariant &, const QVariant &);
+};
+QML_DECLARE_TYPE(QmlSetProperties);
+
+#endif // QMLSETPROPERTIES_H
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
diff --git a/src/declarative/util/qmlstate.cpp b/src/declarative/util/qmlstate.cpp
new file mode 100644
index 0000000..50ae6b5
--- /dev/null
+++ b/src/declarative/util/qmlstate.cpp
@@ -0,0 +1,469 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <gfxeasing.h>
+#include "qmltransition.h"
+#include "qmlstategroup.h"
+#include "qmlstate_p.h"
+#include "qmlbindablevalue.h"
+#include "qmlstateoperations.h"
+#include "qmlanimation.h"
+#include "qmlanimation_p.h"
+#include "qmlstate.h"
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+DEFINE_BOOL_CONFIG_OPTION(stateChangeDebug, STATECHANGE_DEBUG);
+
+Action::Action() : bv(0), event(0), actionDone(false)
+{
+}
+
+ActionEvent::~ActionEvent()
+{
+}
+
+QString ActionEvent::name() const
+{
+ return QString();
+}
+
+void ActionEvent::execute()
+{
+}
+
+/*!
+ \internal
+*/
+QmlStateOperation::QmlStateOperation(QObjectPrivate &dd, QObject *parent)
+ : QObject(dd, parent)
+{
+}
+
+/*!
+ \qmlclass State
+ \brief The State element defines configurations of objects and properties.
+
+ A state is specified as a set of batched changes from the default configuration.
+
+ Note that setting the state of an object from within another state of the same object is
+ inadvisible. Not only would this have the same effect as going directly to the second state
+ it may cause the program to crash.
+
+ \sa {states-transitions}{States and Transitions}
+*/
+
+/*!
+ \internal
+ \class QmlState
+ \brief The QmlState class allows you to define configurations of objects and properties.
+
+ \ingroup states
+
+ QmlState allows you to specify a state as a set of batched changes from the default
+ configuration.
+
+ \sa {states-transitions}{States and Transitions}
+*/
+
+QML_DEFINE_TYPE(QmlState,State);
+QmlState::QmlState(QObject *parent)
+: QObject(*(new QmlStatePrivate), parent)
+{
+}
+
+QmlState::~QmlState()
+{
+}
+
+/*!
+ \qmlproperty string State::name
+ This property holds the name of the state
+
+ Each state should have a unique name.
+*/
+
+/*!
+ \property QmlState::name
+ \brief the name of the state
+
+ Each state should have a unique name.
+*/
+QString QmlState::name() const
+{
+ Q_D(const QmlState);
+ return d->name;
+}
+
+void QmlState::setName(const QString &n)
+{
+ Q_D(QmlState);
+ d->name = n;
+}
+
+bool QmlState::isWhenKnown() const
+{
+ Q_D(const QmlState);
+ return d->when != 0;
+}
+
+/*!
+ \qmlproperty bool State::when
+ This property holds when the state should be applied
+
+ This should be set to an expression that evaluates to true when you want the state to
+ be applied.
+*/
+
+/*!
+ \property QmlState::when
+ \brief when the state should be applied
+
+ This should be set to an expression that evaluates to true when you want the state to
+ be applied.
+*/
+QmlBindableValue *QmlState::when() const
+{
+ Q_D(const QmlState);
+ return d->when;
+}
+
+void QmlState::setWhen(QmlBindableValue *when)
+{
+ Q_D(QmlState);
+ d->when = when;
+ if(d->group)
+ d->group->updateAutoState();
+}
+
+/*!
+ \advanced
+ \qmlproperty string State::extends
+ This property holds the state that this state extends
+
+ The state being extended is treated as the base state in regards to
+ the changes specified by the extending state.
+*/
+
+/*!
+ \property QmlState::extends
+ \brief the state that this state extends
+
+ The state being extended is treated as the base state in regards to
+ the changes specified by the extending state.
+
+ \sa operations
+*/
+QString QmlState::extends() const
+{
+ Q_D(const QmlState);
+ return d->extends;
+}
+
+void QmlState::setExtends(const QString &extends)
+{
+ Q_D(QmlState);
+ d->extends = extends;
+}
+
+/*!
+ \qmlproperty list<StateOperation> State::operations
+ This property holds the changes to apply for this state
+ \default
+
+ By default these changes are applied against the default state. If the state
+ extends another state, then the changes are applied against the state being
+ extended.
+*/
+
+/*!
+ \property QmlState::operations
+ \brief the changes to apply for this state
+
+ By default these changes are applied against the default state. If the state
+ extends another state, then the changes are applied against the state being
+ extended.
+*/
+QmlList<QmlStateOperation *> *QmlState::operations()
+{
+ Q_D(QmlState);
+ return &d->operations;
+}
+
+QmlState &QmlState::operator<<(QmlStateOperation *op)
+{
+ Q_D(QmlState);
+ d->operations.append(op);
+ return *this;
+}
+
+#if 0
+static void dump(const QmlStateOperation::ActionList &list)
+{
+ if(!QString(getenv("STATE_DEBUG")).isEmpty())
+ return;
+
+ for(int ii = 0; ii < list.count(); ++ii) {
+ const Action &action = list.at(ii);
+ qWarning() << action.property.object << action.property.name << action.toValue;
+ }
+}
+#endif
+
+void QmlStatePrivate::complete()
+{
+ Q_Q(QmlState);
+ //apply bindings (now that all transitions are complete)
+ //////////////////////////////////////////////////////////
+ foreach(const Action &action, bindingsList) {
+ if (action.bv && !action.toBinding.isEmpty()) {
+ action.bv->setExpression(action.toBinding);
+ }
+ }
+ //////////////////////////////////////////////////////////
+
+ for(int ii = 0; ii < reverting.count(); ++ii) {
+ for(int jj = 0; jj < revertList.count(); ++jj) {
+ if(revertList.at(jj).property == reverting.at(ii)) {
+ revertList.removeAt(jj);
+ break;
+ }
+ }
+ }
+ reverting.clear();
+
+ for(int ii = 0; ii < completeList.count(); ++ii) {
+ const QmlMetaProperty &prop = completeList.at(ii).property;
+ prop.write(completeList.at(ii).value);
+ }
+
+ completeList.clear();
+ transition = 0;
+ emit q->completed();
+}
+
+QmlStateOperation::ActionList QmlStatePrivate::generateActionList(QmlStateGroup *group) const
+{
+ QmlStateOperation::ActionList applyList;
+ if(inState)
+ return applyList;
+
+ inState = true;
+
+ if(!extends.isEmpty()) {
+ QList<QmlState *> states = group->states();
+ for(int ii = 0; ii < states.count(); ++ii)
+ if(states.at(ii)->name() == extends)
+ applyList = static_cast<QmlStatePrivate*>(states.at(ii)->d_ptr)->generateActionList(group);
+ }
+
+ foreach(QmlStateOperation *op, operations)
+ applyList << op->actions();
+
+ inState = false;
+ return applyList;
+}
+
+QmlStateGroup *QmlState::stateGroup() const
+{
+ Q_D(const QmlState);
+ return d->group;
+}
+
+void QmlState::setStateGroup(QmlStateGroup *group)
+{
+ Q_D(QmlState);
+ d->group = group;
+}
+
+void QmlState::cancel()
+{
+ Q_D(QmlState);
+ if (d->transition) {
+ d->transition->stop(); //XXX this could potentially trigger a complete in rare circumstances
+ d->transition = 0;
+ }
+}
+
+void QmlState::apply(QmlStateGroup *group, QmlTransition *trans, QmlState *revert)
+{
+ Q_D(QmlState);
+
+ cancel();
+ if(revert)
+ revert->cancel();
+ d->revertList.clear();
+ d->reverting.clear();
+ d->bindingsList.clear();
+
+ if(revert)
+ d->revertList = static_cast<QmlStatePrivate*>(revert->d_ptr)->revertList;
+ QmlStateOperation::RevertActionList additionalReverts;
+
+ QmlStateOperation::ActionList applyList = d->generateActionList(group);
+
+ for(int ii = 0; ii < applyList.count(); ++ii) {
+ const Action &action = applyList.at(ii);
+ if(action.event)
+ continue;
+
+ bool found = false;
+ for(int jj = 0; !found && jj < d->revertList.count(); ++jj) {
+ if(d->revertList.at(jj).property == action.property)
+ found = true;
+ }
+ if(!found) {
+ RevertAction r(action);
+ additionalReverts << r;
+ }
+ }
+ for(int ii = 0; ii < d->revertList.count(); ++ii) {
+ bool found = false;
+ for(int jj = 0; !found && jj < applyList.count(); ++jj) {
+ const Action &action = applyList.at(jj);
+ if(action.property == d->revertList.at(ii).property)
+ found = true;
+ }
+ if(!found) {
+ QVariant cur = d->revertList.at(ii).property.read();
+ Action a;
+ a.property = d->revertList.at(ii).property;
+ a.fromValue = cur;
+ a.toValue = d->revertList.at(ii).value;
+ a.toBinding = d->revertList.at(ii).binding;
+ if (!a.toBinding.isEmpty()) {
+ a.fromBinding = d->revertList.at(ii).bv->expression(); //### relies on clearExpression not clearing string
+ a.bv = d->revertList.at(ii).bv;
+ }
+ applyList << a;
+ d->reverting << d->revertList.at(ii).property;
+ }
+ }
+ d->revertList << additionalReverts;
+
+ //apply all changes, and work out any ending positions for bindings
+ //then rewind all changes and proceed as normal
+ //### 4 foreach loops!
+ ////////////////////////////////////////////////////////////////////
+ foreach(const Action &action, applyList) {
+ if(stateChangeDebug())
+ qWarning() << " Action:" << action.property.object() << action.property.name() << action.toValue;
+
+ if (action.bv && !action.toBinding.isEmpty()) {
+ d->bindingsList << action;
+ action.bv->clearExpression();
+ }
+ }
+
+ if (!d->bindingsList.isEmpty()) {
+ foreach(const Action &action, applyList) {
+ if (action.bv && !action.toBinding.isEmpty()) {
+ action.bv->setExpression(action.toBinding);
+ } else if(!action.event) {
+ action.property.write(action.toValue);
+ }
+ }
+
+ for (int ii = 0; ii < applyList.size(); ++ii) {
+ Action *action = &applyList[ii];
+ if(action->event)
+ continue;
+
+ const QmlMetaProperty &prop = action->property;
+ if (action->bv && !action->toBinding.isEmpty()) {
+ action->toValue = prop.read();
+ }
+ }
+
+ foreach(const Action &action, applyList) {
+ if(action.event)
+ continue;
+
+ if (action.bv && !action.toBinding.isEmpty())
+ action.bv->clearExpression();
+ action.property.write(action.fromValue);
+ }
+ }
+ ////////////////////////////////////////////////////////////////////
+
+ QmlStateOperation::ActionList modList = applyList;
+ QList<QmlMetaProperty> touched;
+ d->completeList.clear();
+ if(trans) {
+ d->transition = trans;
+ trans->prepare(modList, touched, this);
+ for(int ii = 0; ii < modList.count(); ++ii) {
+ const Action &action = modList.at(ii);
+
+ if(action.event) {
+ if(action.actionDone) {
+ modList.removeAt(ii);
+ --ii;
+ }
+ } else {
+ if(action.toValue != action.fromValue) {
+ d->completeList << RevertAction(action, false);
+ }
+
+ if(touched.contains(action.property)) {
+ modList.removeAt(ii);
+ --ii;
+ }
+ }
+ }
+ }
+
+ foreach(const Action &action, modList) {
+ if(action.event)
+ action.event->execute();
+ else
+ action.property.write(action.toValue);
+ }
+}
+
+QML_DEFINE_TYPE(QmlStateOperation,StateOperation);
+QmlStateOperation::ActionList QmlStateOperation::actions()
+{
+ return ActionList();
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qmlstate.h b/src/declarative/util/qmlstate.h
new file mode 100644
index 0000000..3e6727d
--- /dev/null
+++ b/src/declarative/util/qmlstate.h
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLSTATE_H
+#define QMLSTATE_H
+
+#include <QtCore/qobject.h>
+#include <qfxglobal.h>
+#include <gfxtimeline.h>
+#include <qml.h>
+#include <QSequentialAnimationGroup>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class ActionEvent;
+class QmlBindableValue;
+class Action
+{
+public:
+ Action();
+
+ QmlMetaProperty property;
+ QVariant fromValue;
+ QVariant toValue;
+ QString fromBinding;
+ QString toBinding;
+ QmlBindableValue *bv;
+ ActionEvent *event;
+ bool actionDone;
+};
+
+class ActionEvent
+{
+public:
+ virtual ~ActionEvent();
+ virtual QString name() const;
+ virtual void execute();
+};
+
+class RevertAction
+{
+public:
+ RevertAction(const Action &a, bool from = true) : bv(0)
+ {
+ property = a.property;
+ if (from) {
+ value = a.fromValue;
+ binding = a.fromBinding;
+ } else {
+ value = a.toValue;
+ binding = a.toBinding;
+ }
+ bv = a.bv;
+ }
+
+ QmlMetaProperty property;
+ QVariant value;
+ QString binding;
+ QmlBindableValue *bv;
+};
+
+class QmlStateGroup;
+class Q_DECLARATIVE_EXPORT QmlStateOperation : public QObject
+{
+ Q_OBJECT
+public:
+ QmlStateOperation(QObject *parent = 0)
+ : QObject(parent) {}
+ typedef QList<Action> ActionList;
+ typedef QList<RevertAction> RevertActionList;
+
+ virtual ActionList actions();
+
+protected:
+ QmlStateOperation(QObjectPrivate &dd, QObject *parent = 0);
+};
+QML_DECLARE_TYPE(QmlStateOperation);
+
+typedef QmlStateOperation::ActionList QmlStateActions;
+
+class QmlTransition;
+class QmlTransitionPrivate;
+class QmlStatePrivate;
+class Q_DECLARATIVE_EXPORT QmlState : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString name READ name WRITE setName);
+ Q_PROPERTY(QmlBindableValue *when READ when WRITE setWhen);
+ Q_PROPERTY(QString extends READ extends WRITE setExtends);
+ Q_PROPERTY(QmlList<QmlStateOperation *>* operations READ operations);
+ Q_CLASSINFO("DefaultProperty", "operations");
+
+public:
+ QmlState(QObject *parent=0);
+ virtual ~QmlState();
+
+ QString name() const;
+ void setName(const QString &);
+
+ /*'when' is a QmlBindableValue to limit state changes oscillation
+ due to the unpredictable order of evaluation of bound expressions*/
+ bool isWhenKnown() const;
+ QmlBindableValue *when() const;
+ void setWhen(QmlBindableValue *);
+
+ QString extends() const;
+ void setExtends(const QString &);
+
+ QmlList<QmlStateOperation *> *operations();
+ QmlState &operator<<(QmlStateOperation *);
+
+ void apply(QmlStateGroup *, QmlTransition *, QmlState *revert);
+ void cancel();
+
+ QmlStateGroup *stateGroup() const;
+ void setStateGroup(QmlStateGroup *);
+
+Q_SIGNALS:
+ void completed();
+
+private:
+ Q_DECLARE_PRIVATE(QmlState)
+ Q_DISABLE_COPY(QmlState)
+ friend class QmlTransitionPrivate;
+};
+QML_DECLARE_TYPE(QmlState);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMLSTATE_H
diff --git a/src/declarative/util/qmlstate_p.h b/src/declarative/util/qmlstate_p.h
new file mode 100644
index 0000000..20d1c1a
--- /dev/null
+++ b/src/declarative/util/qmlstate_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLSTATE_P_H
+#define QMLSTATE_P_H
+
+#include <qmlstate.h>
+#include "private/qobject_p.h"
+#include "private/qmlanimation_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QmlStatePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QmlState);
+
+public:
+ QmlStatePrivate()
+ : when(0), transition(0), inState(false), group(0) {}
+
+ QString name;
+ QmlBindableValue *when;
+ QmlConcreteList<QmlStateOperation *> operations;
+ QmlTransition *transition;
+ QmlStateOperation::RevertActionList revertList;
+ QList<QmlMetaProperty> reverting;
+ QmlStateOperation::RevertActionList completeList;
+ QmlStateOperation::ActionList bindingsList;
+ QString extends;
+ mutable bool inState;
+ QmlStateGroup *group;
+
+ QmlStateOperation::ActionList generateActionList(QmlStateGroup *) const;
+ void complete();
+};
+
+QT_END_NAMESPACE
+
+#endif // QMLSTATE_P_H
diff --git a/src/declarative/util/qmlstategroup.cpp b/src/declarative/util/qmlstategroup.cpp
new file mode 100644
index 0000000..36fea4e
--- /dev/null
+++ b/src/declarative/util/qmlstategroup.cpp
@@ -0,0 +1,306 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "private/qobject_p.h"
+#include "qmlbindablevalue.h"
+#include "qmlstategroup.h"
+#include "qmltransition.h"
+#include <QtCore/qdebug.h>
+
+
+QT_BEGIN_NAMESPACE
+DEFINE_BOOL_CONFIG_OPTION(stateChangeDebug, STATECHANGE_DEBUG);
+
+QML_DEFINE_TYPE(QmlStateGroup,StateGroup);
+
+class QmlStateGroupPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QmlStateGroup)
+public:
+ QmlStateGroupPrivate(QmlStateGroup *p)
+ : nullState(0), states(p), classComplete(true),
+ componentComplete(true), ignoreTrans(false) {}
+
+ QString currentState;
+ QmlState *nullState;
+
+ struct StateList : public QmlConcreteList<QmlState *>
+ {
+ StateList(QmlStateGroup *g)
+ :group(g) {}
+ void append(QmlState *s) {
+ QmlConcreteList<QmlState *>::append(s);
+ if(s) s->setStateGroup(group);
+ }
+ private:
+ QmlStateGroup *group;
+ };
+ StateList states;
+
+ QmlConcreteList<QmlTransition *> transitions;
+ bool classComplete;
+ bool componentComplete;
+ bool ignoreTrans;
+
+ QmlTransition *findTransition(const QString &from, const QString &to);
+ void setCurrentStateInternal(const QString &state, bool = false);
+ void updateAutoState();
+};
+
+QmlStateGroup::QmlStateGroup(QObject *parent)
+ : QObject(*(new QmlStateGroupPrivate(this)), parent)
+{
+}
+
+QmlStateGroup::~QmlStateGroup()
+{
+}
+
+QList<QmlState *> QmlStateGroup::states() const
+{
+ Q_D(const QmlStateGroup);
+ return d->states;
+}
+
+QmlList<QmlState *>* QmlStateGroup::statesProperty()
+{
+ Q_D(QmlStateGroup);
+ return &(d->states);
+}
+
+QmlList<QmlTransition *>* QmlStateGroup::transitionsProperty()
+{
+ Q_D(QmlStateGroup);
+ return &(d->transitions);
+}
+
+QString QmlStateGroup::state() const
+{
+ Q_D(const QmlStateGroup);
+ return d->currentState;
+}
+
+void QmlStateGroup::setState(const QString &state)
+{
+ Q_D(QmlStateGroup);
+ if(d->currentState == state)
+ return;
+
+ d->setCurrentStateInternal(state);
+
+ d->currentState = state;
+ emit stateChanged(d->currentState);
+}
+
+void QmlStateGroup::classBegin()
+{
+ Q_D(QmlStateGroup);
+ d->classComplete = false;
+ d->componentComplete = false;
+}
+
+void QmlStateGroup::classComplete()
+{
+ Q_D(QmlStateGroup);
+ d->classComplete = true;
+}
+
+void QmlStateGroup::updateAutoState()
+{
+ Q_D(QmlStateGroup);
+ d->updateAutoState();
+}
+
+void QmlStateGroupPrivate::updateAutoState()
+{
+ Q_Q(QmlStateGroup);
+ if(!classComplete)
+ return;
+
+ bool revert = false;
+ for(int ii = 0; ii < states.count(); ++ii) {
+ QmlState *state = states.at(ii);
+ if(state->isWhenKnown()) {
+ if(!state->name().isEmpty()) {
+ if(state->when() && state->when()->value().toBool()) {
+ if(stateChangeDebug())
+ qWarning() << "Setting auto state due to:"
+ << state->when()->expression();
+ q->setState(state->name());
+ return;
+ } else if(state->name() == currentState) {
+ revert = true;
+ }
+ }
+ }
+ }
+ if(revert)
+ q->setState(QString());
+}
+
+QmlTransition *QmlStateGroupPrivate::findTransition(const QString &from, const QString &to)
+{
+ QmlTransition *highest = 0;
+ int score = 0;
+ bool reversed = false;
+ bool done = false;
+
+ for(int ii = 0; !done && ii < transitions.count(); ++ii) {
+ QmlTransition *t = transitions.at(ii);
+ for(int ii = 0; ii < 2; ++ii)
+ {
+ if(ii && (!t->reversible() ||
+ (t->fromState() == QLatin1String("*") &&
+ t->toState() == QLatin1String("*"))))
+ break;
+ QStringList fromState;
+ QStringList toState;
+
+ fromState = t->fromState().split(QLatin1Char(','));
+ toState = t->toState().split(QLatin1Char(','));
+ if(ii == 1)
+ qSwap(fromState, toState);
+ int tScore = 0;
+ if(fromState.contains(from))
+ tScore += 2;
+ else if(fromState.contains(QLatin1String("*")))
+ tScore += 1;
+ else
+ continue;
+
+ if(toState.contains(to))
+ tScore += 2;
+ else if(toState.contains(QLatin1String("*")))
+ tScore += 1;
+ else
+ continue;
+
+ if(ii == 1)
+ reversed = true;
+ else
+ reversed = false;
+
+ if(tScore == 4) {
+ highest = t;
+ done = true;
+ break;
+ } else if(tScore > score) {
+ score = tScore;
+ highest = t;
+ }
+ }
+ }
+
+ if(highest)
+ highest->setReversed(reversed);
+
+ return highest;
+}
+
+void QmlStateGroupPrivate::setCurrentStateInternal(const QString &state,
+ bool ignoreTrans)
+{
+ Q_Q(QmlStateGroup);
+ if(!componentComplete)
+ return;
+
+ QmlTransition *transition = (ignoreTrans || ignoreTrans) ? 0 : findTransition(currentState, state);
+ if(stateChangeDebug()) {
+ qWarning() << this << "Changing state. From" << currentState << ". To" << state;
+ if(transition)
+ qWarning() << " using transition" << transition->fromState()
+ << transition->toState();
+ }
+
+ QmlState *oldState = 0;
+ if(!currentState.isEmpty()) {
+ for(int ii = 0; ii < states.count(); ++ii) {
+ if(states.at(ii)->name() == currentState) {
+ oldState = states.at(ii);
+ break;
+ }
+ }
+ }
+
+ currentState = state;
+
+ QmlState *newState = 0;
+ for(int ii = 0; ii < states.count(); ++ii) {
+ if(states.at(ii)->name() == currentState) {
+ newState = states.at(ii);
+ break;
+ }
+ }
+
+ if(oldState == 0 || newState == 0) {
+ if(!nullState) { nullState = new QmlState(q); }
+ if(!oldState) oldState = nullState;
+ if(!newState) newState = nullState;
+ }
+
+ newState->apply(q, transition, oldState);
+}
+
+void QmlStateGroup::componentComplete()
+{
+ Q_D(QmlStateGroup);
+ d->updateAutoState();
+ d->componentComplete = true;
+ if(!d->currentState.isEmpty()) {
+ QString cs = d->currentState;
+ d->currentState = QString();
+ d->setCurrentStateInternal(cs, true);
+ }
+}
+
+QmlState *QmlStateGroup::findState(const QString &name) const
+{
+ Q_D(const QmlStateGroup);
+ for (int i = 0; i < d->states.count(); ++i) {
+ QmlState *state = d->states.at(i);
+ if (state->name() == name)
+ return state;
+ }
+
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qmlstategroup.h b/src/declarative/util/qmlstategroup.h
new file mode 100644
index 0000000..55b84eb
--- /dev/null
+++ b/src/declarative/util/qmlstategroup.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLSTATEGROUP_H
+#define QMLSTATEGROUP_H
+
+#include <qmlstate.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+class QmlStateGroupPrivate;
+class QmlStateGroup : public QObject, public QmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QmlParserStatus)
+ Q_DECLARE_PRIVATE(QmlStateGroup);
+
+ Q_PROPERTY(QString state READ state WRITE setState NOTIFY stateChanged);
+ Q_PROPERTY(QmlList<QmlState *>* states READ statesProperty DESIGNABLE false);
+ Q_PROPERTY(QmlList<QmlTransition *>* transitions READ transitionsProperty DESIGNABLE false);
+
+public:
+ QmlStateGroup(QObject * = 0);
+ virtual ~QmlStateGroup();
+
+ QString state() const;
+ void setState(const QString &);
+
+ QmlList<QmlState *>* statesProperty();
+ QList<QmlState *> states() const;
+
+ QmlList<QmlTransition *>* transitionsProperty();
+
+ QmlState *findState(const QString &name) const;
+
+ virtual void classBegin();
+ virtual void classComplete();
+ virtual void componentComplete();
+Q_SIGNALS:
+ void stateChanged(const QString &);
+
+private:
+ friend class QmlState;
+ void updateAutoState();
+};
+QML_DECLARE_TYPE(QmlStateGroup);
+
+#endif // QMLSTATEGROUP_H
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
diff --git a/src/declarative/util/qmlstateoperations.cpp b/src/declarative/util/qmlstateoperations.cpp
new file mode 100644
index 0000000..c2ba4b8
--- /dev/null
+++ b/src/declarative/util/qmlstateoperations.cpp
@@ -0,0 +1,416 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qobject_p.h>
+#include <gfxeasing.h>
+#include <qml.h>
+#include <QtDeclarative/qmlcontext.h>
+#include "qmlbindablevalue.h"
+#include "qmlstateoperations.h"
+#include <QtCore/qdebug.h>
+#include <QtDeclarative/qmlinfo.h>
+
+QT_BEGIN_NAMESPACE
+
+class QmlParentChangePrivate : public QObjectPrivate
+{
+public:
+ QmlParentChangePrivate() : target(0), parent(0) {}
+
+ QObject *target;
+ QObject *parent;
+};
+
+/*!
+ \qmlclass ParentChange
+ \brief The ParentChange element allows you to reparent an object in a state.
+*/
+
+QML_DEFINE_TYPE(QmlParentChange,ParentChange);
+QmlParentChange::QmlParentChange(QObject *parent)
+ : QmlStateOperation(*(new QmlParentChangePrivate), parent)
+{
+}
+
+QmlParentChange::~QmlParentChange()
+{
+}
+
+/*!
+ \qmlproperty Object ParentChange::target
+ This property holds the object to be reparented
+*/
+
+QObject *QmlParentChange::object() const
+{
+ Q_D(const QmlParentChange);
+ return d->target;
+}
+void QmlParentChange::setObject(QObject *target)
+{
+ Q_D(QmlParentChange);
+ d->target = target;
+}
+
+/*!
+ \qmlproperty Object ParentChange::parent
+ This property holds the parent for the object in this state
+*/
+
+QObject *QmlParentChange::parent() const
+{
+ Q_D(const QmlParentChange);
+ return d->parent;
+}
+
+void QmlParentChange::setParent(QObject *parent)
+{
+ Q_D(QmlParentChange);
+ d->parent = parent;
+}
+
+QmlStateOperation::ActionList QmlParentChange::actions()
+{
+ Q_D(QmlParentChange);
+ if(!d->target || !d->parent)
+ return ActionList();
+
+ QString propName(QLatin1String("moveToParent"));
+ QmlMetaProperty prop(d->target, propName);
+ if (!prop.isValid()) {
+ qmlInfo(this) << d->target->metaObject()->className()
+ << "has no property named" << propName;
+ return ActionList();
+ }else if(!prop.isWritable()){
+ qmlInfo(this) << d->target->metaObject()->className() << propName
+ << "is not a writable property and cannot be set.";
+ return ActionList();
+ }
+ QVariant cur = prop.read();
+
+ Action a;
+ a.property = prop;
+ a.fromValue = cur;
+ a.toValue = qVariantFromValue(d->parent);
+
+ return ActionList() << a;
+}
+
+class QmlRunScriptPrivate : public QObjectPrivate
+{
+public:
+ QmlRunScriptPrivate() : ctxt(0) {}
+
+ QmlContext *ctxt;
+ QString script;
+ QString name;
+};
+
+/*!
+ \qmlclass RunScript QmlRunScript
+ \brief The RunScript element allows you to run a script in a state.
+*/
+QML_DEFINE_TYPE(QmlRunScript,RunScript);
+QmlRunScript::QmlRunScript(QObject *parent)
+: QmlStateOperation(*(new QmlRunScriptPrivate), parent)
+{
+ Q_D(QmlRunScript);
+ d->ctxt = QmlContext::activeContext();
+}
+
+QmlRunScript::~QmlRunScript()
+{
+}
+
+/*!
+ \qmlproperty string RunScript::script
+ This property holds the script to run when the state is current.
+*/
+QString QmlRunScript::script() const
+{
+ Q_D(const QmlRunScript);
+ return d->script;
+}
+
+void QmlRunScript::setScript(const QString &s)
+{
+ Q_D(QmlRunScript);
+ d->script = s;
+}
+
+QString QmlRunScript::name() const
+{
+ Q_D(const QmlRunScript);
+ return d->name;
+}
+
+void QmlRunScript::setName(const QString &n)
+{
+ Q_D(QmlRunScript);
+ d->name = n;
+}
+
+void QmlRunScript::execute()
+{
+ Q_D(QmlRunScript);
+ if(!d->script.isEmpty()) {
+ QmlExpression expr(d->ctxt, d->script, this);
+ expr.setTrackChange(false);
+ expr.value();
+ }
+}
+
+QmlRunScript::ActionList QmlRunScript::actions()
+{
+ ActionList rv;
+ Action a;
+ a.event = this;
+ rv << a;
+ return rv;
+}
+
+/*!
+ \qmlclass SetProperty QmlSetProperty
+ \brief The SetProperty element describes a new property value or binding for a state.
+
+ The code below changes the position of the Rect depending upon
+ the current state:
+
+ \code
+ <Rect id="myrect" width="50" height="50" color="red"/>
+
+ <states>
+ <State name="Position1">
+ <SetProperty target="{myrect}" property="x" value="150"/>
+ <SetProperty target="{myrect}" property="y" value="50"/>
+ </State>
+ <State name="Position2">
+ <SetProperty target="{myrect}" property="y" value="200"/>
+ </State>
+ </states>
+ \endcode
+
+ \sa SetProperties
+*/
+
+/*!
+ \internal
+ \class QmlSetProperty
+ \brief The QmlSetProperty class describes a new property value or binding for a state.
+
+ \ingroup states
+
+ \sa QmlSetProperties
+*/
+
+class QmlSetPropertyPrivate : public QObjectPrivate
+{
+public:
+ QmlSetPropertyPrivate() : obj(0) {}
+
+ QObject *obj;
+ QString prop;
+ QVariant value;
+ QString binding;
+};
+
+QML_DEFINE_TYPE(QmlSetProperty,SetProperty);
+
+QmlSetProperty::QmlSetProperty(QObject *parent)
+ : QmlStateOperation(*(new QmlSetPropertyPrivate), parent)
+{
+}
+
+QmlSetProperty::~QmlSetProperty()
+{
+}
+
+/*!
+ \qmlproperty Object SetProperty::target
+ This property holds the object the property to change belongs to
+*/
+
+/*!
+ \property QmlSetProperty::target
+ \brief the object the property to change belongs to
+*/
+QObject *QmlSetProperty::object()
+{
+ Q_D(QmlSetProperty);
+ return d->obj;
+}
+
+void QmlSetProperty::setObject(QObject *o)
+{
+ Q_D(QmlSetProperty);
+ d->obj = o;
+}
+
+/*!
+ \qmlproperty string SetProperty::property
+ This property holds the name of the property to change
+*/
+
+/*!
+ \property QmlSetProperty::property
+ \brief the name of the property to change
+*/
+QString QmlSetProperty::property() const
+{
+ Q_D(const QmlSetProperty);
+ return d->prop;
+}
+
+void QmlSetProperty::setProperty(const QString &p)
+{
+ Q_D(QmlSetProperty);
+ d->prop = p;
+}
+
+/*!
+ \qmlproperty variant SetProperty::value
+ This property holds the value to assign to the property
+
+ You should set either a \c value or a \c binding, but not both.
+*/
+
+/*!
+ \property QmlSetProperty::value
+ \brief the value to assign to the property
+
+ You should set either a value or a binding, not both.
+*/
+QVariant QmlSetProperty::value() const
+{
+ Q_D(const QmlSetProperty);
+ return d->value;
+}
+
+void QmlSetProperty::setValue(const QVariant &v)
+{
+ Q_D(QmlSetProperty);
+ d->value = v;
+}
+
+/*!
+ \qmlproperty string SetProperty::binding
+ This property holds the binding to assign to the property
+
+ You should set either a \c value or a \c binding, but not both.
+*/
+
+/*!
+ \property QmlSetProperty::binding
+ \brief the binding to assign to the property
+
+ You should set either a value or a binding, not both.
+*/
+QString QmlSetProperty::binding() const
+{
+ Q_D(const QmlSetProperty);
+ return d->binding;
+}
+
+void QmlSetProperty::setBinding(const QString &binding)
+{
+ Q_D(QmlSetProperty);
+ d->binding = binding;
+}
+
+QmlSetProperty::ActionList QmlSetProperty::actions()
+{
+ Q_D(QmlSetProperty);
+ if(!d->obj)
+ return ActionList();
+
+ QObject *obj = d->obj;
+ QString propName = d->prop;
+
+ if (d->prop.contains(QLatin1Char('.'))) { //handle dot properties
+ QStringList str = d->prop.split(QLatin1Char('.'));
+ for(int ii = 0; ii < str.count()-1; ++ii) {
+ const QString &s = str.at(ii);
+ QmlMetaProperty prop(obj, s);
+ if(!prop.isValid()) {
+ qmlInfo(this) << obj->metaObject()->className()
+ << "has no property named" << s;
+ return ActionList();
+ }
+ QVariant v = prop.read();
+ obj = QmlMetaType::toQObject(v);
+ if (!obj) {
+ qmlInfo(this) << "Unable to coerce value property"
+ << s << "into a QObject";
+ return ActionList();
+ }
+ }
+ propName = str.last();
+ }
+
+ QmlMetaProperty prop(obj, propName);
+ if (!prop.isValid()) {
+ qmlInfo(this) << obj->metaObject()->className()
+ << "has no property named" << propName;
+ return ActionList();
+ }else if(!prop.isWritable()){
+ qmlInfo(this) << obj->metaObject()->className() << propName
+ << "is not a writable property and cannot be set.";
+ return ActionList();
+ }
+ QVariant cur = prop.read();
+
+ Action a;
+ a.property = prop;
+ a.fromValue = cur;
+ a.toValue = d->value;
+ if (!d->binding.isEmpty()) {
+ QmlBindableValue *bv = prop.binding();
+ if(bv) {
+ a.fromBinding = bv->expression();
+ a.bv = bv;
+ }
+ }
+ a.toBinding = d->binding;
+
+ return ActionList() << a;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/util/qmlstateoperations.h b/src/declarative/util/qmlstateoperations.h
new file mode 100644
index 0000000..8ecdcd2
--- /dev/null
+++ b/src/declarative/util/qmlstateoperations.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLSTATEOPERATIONS_H
+#define QMLSTATEOPERATIONS_H
+
+#include <qmlstate.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QmlParentChangePrivate;
+class Q_DECLARATIVE_EXPORT QmlParentChange : public QmlStateOperation
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlParentChange);
+
+ Q_PROPERTY(QObject *target READ object WRITE setObject)
+ Q_PROPERTY(QObject *parent READ parent WRITE setParent)
+public:
+ QmlParentChange(QObject *parent=0);
+ ~QmlParentChange();
+
+ QObject *object() const;
+ void setObject(QObject *);
+
+ QObject *parent() const;
+ void setParent(QObject *);
+
+ virtual ActionList actions();
+};
+QML_DECLARE_TYPE(QmlParentChange);
+
+class QmlRunScriptPrivate;
+class Q_DECLARATIVE_EXPORT QmlRunScript : public QmlStateOperation, public ActionEvent
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlRunScript)
+
+ Q_PROPERTY(QString script READ script WRITE setScript);
+ Q_PROPERTY(QString name READ name WRITE setName);
+
+public:
+ QmlRunScript(QObject *parent=0);
+ ~QmlRunScript();
+
+ virtual ActionList actions();
+
+ QString script() const;
+ void setScript(const QString &);
+
+ virtual QString name() const;
+ void setName(const QString &);
+
+ virtual void execute();
+};
+QML_DECLARE_TYPE(QmlRunScript);
+
+class QmlSetPropertyPrivate;
+class Q_DECLARATIVE_EXPORT QmlSetProperty : public QmlStateOperation
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlSetProperty);
+
+ Q_PROPERTY(QObject *target READ object WRITE setObject);
+ Q_PROPERTY(QString property READ property WRITE setProperty);
+ Q_PROPERTY(QVariant value READ value WRITE setValue);
+ Q_PROPERTY(QString binding READ binding WRITE setBinding);
+
+public:
+ QmlSetProperty(QObject *parent=0);
+ ~QmlSetProperty();
+
+ QObject *object();
+ void setObject(QObject *);
+ QString property() const;
+ void setProperty(const QString &);
+ QVariant value() const;
+ void setValue(const QVariant &);
+ QString binding() const;
+ void setBinding(const QString&);
+
+ virtual ActionList actions();
+};
+QML_DECLARE_TYPE(QmlSetProperty);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMLSTATEOPERATIONS_H
diff --git a/src/declarative/util/qmltransition.cpp b/src/declarative/util/qmltransition.cpp
new file mode 100644
index 0000000..fb09e32
--- /dev/null
+++ b/src/declarative/util/qmltransition.cpp
@@ -0,0 +1,283 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlstate.h"
+#include "qmlstategroup.h"
+#include "qmlstate_p.h"
+#include "qmlbindablevalue.h"
+#include "qmlstateoperations.h"
+#include "qmlanimation.h"
+#include "qmlanimation_p.h"
+#include <QParallelAnimationGroup>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmlclass Transition QmlTransition
+ \brief The Transition element defines animated transitions that occur on state changes.
+
+ \sa {states-transitions}{States and Transitions}
+*/
+
+/*!
+ \internal
+ \class QmlTransition
+ \brief The QmlTransition class allows you to define animated transitions that occur on state changes.
+
+ \ingroup states
+*/
+
+//ParallelAnimationWrapperallows us to do a "callback" when the animation finishes, rather than connecting
+//and disconnecting signals and slots frequently
+class ParallelAnimationWrapper : public QParallelAnimationGroup
+{
+ Q_OBJECT
+public:
+ ParallelAnimationWrapper(QObject *parent) : QParallelAnimationGroup(parent) {}
+ QmlTransitionPrivate *trans;
+protected:
+ virtual void updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState);
+};
+
+class QmlTransitionPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QmlTransition)
+public:
+ QmlTransitionPrivate() : fromState(QLatin1String("*")), toState(QLatin1String("*"))
+ , reversed(false), reversible(false), group(0), endState(0)
+ {
+ operations.parent = this;
+ }
+
+ QString fromState;
+ QString toState;
+ bool reversed;
+ bool reversible;
+ ParallelAnimationWrapper *group;
+ QmlState *endState;
+
+ void init()
+ {
+ Q_Q(QmlTransition);
+ group = new ParallelAnimationWrapper(q);
+ group->trans = this;
+ }
+
+ void complete()
+ {
+ endState->d_func()->complete();
+ }
+
+ class AnimationList : public QmlConcreteList<QmlAbstractAnimation *>
+ {
+ public:
+ AnimationList() : parent(0) {}
+ virtual void append(QmlAbstractAnimation *a);
+ virtual void clear() { QmlConcreteList<QmlAbstractAnimation *>::clear(); } //XXX
+
+ QmlTransitionPrivate *parent;
+ };
+ AnimationList operations;
+};
+
+void QmlTransitionPrivate::AnimationList::append(QmlAbstractAnimation *a)
+{
+ QmlConcreteList<QmlAbstractAnimation *>::append(a);
+ parent->group->addAnimation(a->qtAnimation());
+}
+
+void ParallelAnimationWrapper::updateState(QAbstractAnimation::State oldState, QAbstractAnimation::State newState)
+{
+ QParallelAnimationGroup::updateState(oldState, newState);
+ //XXX not 100% guaranteed to be at end (if there are many zero duration animations at the end)?
+ if (newState == Stopped && currentTime() == duration())
+ {
+ trans->complete();
+ }
+}
+
+
+QML_DEFINE_TYPE(QmlTransition,Transition);
+QmlTransition::QmlTransition(QObject *parent)
+ : QObject(*(new QmlTransitionPrivate), parent)
+{
+ Q_D(QmlTransition);
+ d->init();
+}
+
+QmlTransition::~QmlTransition()
+{
+}
+
+void QmlTransition::stop()
+{
+ Q_D(QmlTransition);
+ d->group->stop();
+}
+
+void QmlTransition::setReversed(bool r)
+{
+ Q_D(QmlTransition);
+ d->reversed = r;
+}
+
+void QmlTransition::prepare(QmlStateOperation::ActionList &actions,
+ QList<QmlMetaProperty> &after,
+ QmlState *endState)
+{
+ Q_D(QmlTransition);
+
+ if(d->reversed) {
+ for(int ii = d->operations.count() - 1; ii >= 0; --ii) {
+ d->operations.at(ii)->transition(actions, after, QmlAbstractAnimation::Backward);
+ }
+ } else {
+ for(int ii = 0; ii < d->operations.count(); ++ii) {
+ d->operations.at(ii)->transition(actions, after, QmlAbstractAnimation::Forward);
+ }
+ }
+
+ d->endState = endState;
+ d->group->start();
+}
+
+/*!
+ \qmlproperty string Transition::fromState
+ \qmlproperty string Transition::toState
+ These properties are selectors indicating which state changes should trigger the transition.
+
+ fromState is used in conjunction with toState to determine when a transition should
+ be applied. By default fromState and toState are both "*" (any state). In the following example,
+ the transition is applied when changing from state1 to state2.
+ \code
+ <Transition fromState="state1" toState="state2">
+ ...
+ </Transition>
+ \endcode
+*/
+
+/*!
+ \property QmlTransition::fromState
+ \brief a selector indicating which states, when left, should trigger the transition.
+
+ fromState is used in conjunction with toState to determine when a transition should
+ be applied. The default value is "*" (any state).
+*/
+QString QmlTransition::fromState() const
+{
+ Q_D(const QmlTransition);
+ return d->fromState;
+}
+
+void QmlTransition::setFromState(const QString &f)
+{
+ Q_D(QmlTransition);
+ d->fromState = f;
+}
+
+/*!
+ \qmlproperty bool Transition::reversible
+ This property holds whether the transition should be automatically reversed when the conditions that triggered this transition are reversed.
+
+ The default value is false.
+*/
+
+
+/*!
+ \property QmlTransition::reversible
+ \brief whether the transition should be automatically reversed when the conditions that triggered this transition are reversed.
+
+ The default value is false.
+*/
+bool QmlTransition::reversible() const
+{
+ Q_D(const QmlTransition);
+ return d->reversible;
+}
+
+void QmlTransition::setReversible(bool r)
+{
+ Q_D(QmlTransition);
+ d->reversible = r;
+}
+
+/*!
+ \property QmlTransition::toState
+ \brief a selector indicating which states, when entered, should trigger the transition.
+
+ toState is used in conjunction with fromState to determine when a transition should
+ be applied. The default value is "*" (any state).
+*/
+QString QmlTransition::toState() const
+{
+ Q_D(const QmlTransition);
+ return d->toState;
+}
+
+void QmlTransition::setToState(const QString &t)
+{
+ Q_D(QmlTransition);
+ d->toState = t;
+}
+
+/*!
+ \qmlproperty list<Animation> Transition::operations
+ This property holds a list of the animations to be run for this transition.
+
+ The top-level animations in operations are run in parallel.
+ To run them sequentially, you can create a single <SequentialAnimation>
+ which contains all the animations, and assign that to operations.
+ \default
+*/
+
+/*!
+ \property QmlTransition::operations
+ \brief a list of the transition animations to be run.
+*/
+QmlList<QmlAbstractAnimation *>* QmlTransition::operations()
+{
+ Q_D(QmlTransition);
+ return &d->operations;
+}
+
+QT_END_NAMESPACE
+
+#include "qmltransition.moc"
diff --git a/src/declarative/util/qmltransition.h b/src/declarative/util/qmltransition.h
new file mode 100644
index 0000000..0d86b7d
--- /dev/null
+++ b/src/declarative/util/qmltransition.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLTRANSITION_H
+#define QMLTRANSITION_H
+
+#include <QtCore/qobject.h>
+#include <qfxglobal.h>
+#include <gfxtimeline.h>
+#include <qmlstate.h>
+#include <qml.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QmlAbstractAnimation;
+class QmlTransitionPrivate;
+class Q_DECLARATIVE_EXPORT QmlTransition : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QmlTransition)
+
+ Q_PROPERTY(QString fromState READ fromState WRITE setFromState)
+ Q_PROPERTY(QString toState READ toState WRITE setToState)
+ Q_PROPERTY(bool reversible READ reversible WRITE setReversible)
+ Q_PROPERTY(QmlList<QmlAbstractAnimation *>* operations READ operations)
+ Q_CLASSINFO("DefaultProperty", "operations")
+
+public:
+ QmlTransition(QObject *parent=0);
+ ~QmlTransition();
+
+ QString fromState() const;
+ void setFromState(const QString &);
+
+ QString toState() const;
+ void setToState(const QString &);
+
+ bool reversible() const;
+ void setReversible(bool);
+
+ QmlList<QmlAbstractAnimation *>* operations();
+
+ void prepare(QmlStateOperation::ActionList &actions,
+ QList<QmlMetaProperty> &after,
+ QmlState *endState);
+
+ void setReversed(bool r);
+ void stop();
+};
+QML_DECLARE_TYPE(QmlTransition);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMLTRANSITION_H
diff --git a/src/declarative/util/qperformancelog.cpp b/src/declarative/util/qperformancelog.cpp
new file mode 100644
index 0000000..52ccc0d
--- /dev/null
+++ b/src/declarative/util/qperformancelog.cpp
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qperformancelog.h"
+#include <QHash>
+#include <QDebug>
+
+
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+
+struct QPerformanceLogData
+{
+ struct Log
+ {
+ Log()
+ : logDescription(0), maxId(-1) {}
+
+ QHash<int, const char *> descriptions;
+ const char *logDescription;
+ int maxId;
+ };
+
+ typedef QHash<QPerformanceLog::LogData *, Log> Logs;
+ Logs logs;
+};
+Q_GLOBAL_STATIC(QPerformanceLogData, performanceLogData);
+
+QPerformanceLog::LogData::LogData(const char *desc)
+: sumTime(0), data(0)
+{
+ QPerformanceLogData *logData = performanceLogData();
+
+ QPerformanceLogData::Log log;
+ log.logDescription = desc;
+ logData->logs.insert(this, log);
+
+ timer.start();
+}
+
+QPerformanceLog::LogMetric::LogMetric(LogData *l, int id, const char *desc)
+{
+ if(id < 0)
+ qFatal("QPerformanceLog: Invalid log id %d ('%s')", id, desc);
+
+ QPerformanceLogData *logData = performanceLogData();
+
+ QPerformanceLogData::Logs::Iterator logIter = logData->logs.find(l);
+ if(logIter == logData->logs.end())
+ qFatal("QPerformanceLog: Unable to locate log for metric '%s'", desc);
+ QPerformanceLogData::Log &log = *logIter;
+ if(log.descriptions.contains(id))
+ qFatal("QPerformanceLog: Duplicate log metric %d ('%s')", id, desc);
+ log.descriptions.insert(id, desc);
+
+ if(log.maxId < id) {
+ log.maxId = id;
+ if(l->data) delete [] l->data;
+ l->data = new unsigned int[2 * (log.maxId + 1)];
+ ::memset(l->data, 0, 2 * (log.maxId + 1) * sizeof(unsigned int));
+ }
+}
+
+static void QPerformanceLog_clear(QPerformanceLog::LogData *l, const QPerformanceLogData::Log *pl)
+{
+ ::memset(l->data, 0, 2 * (pl->maxId + 1) * sizeof(unsigned int));
+}
+
+static void QPerformanceLog_displayData(const QPerformanceLog::LogData *l, const QPerformanceLogData::Log *pl)
+{
+ qWarning() << pl->logDescription << "performance data";
+ unsigned int total = 0;
+ for(QHash<int, const char *>::ConstIterator iter = pl->descriptions.begin();
+ iter != pl->descriptions.end();
+ ++iter) {
+
+ int id = iter.key();
+ unsigned int ms = l->data[id * 2];
+ total += ms;
+ unsigned int inst = l->data[id * 2 + 1];
+ float pi = float(ms) / float(inst);
+ qWarning().nospace() << " " << *iter << ": " << ms << " ms over "
+ << inst << " instances (" << pi << " ms/instance)";
+ }
+ qWarning().nospace() << " TOTAL: " << total;
+}
+
+void QPerformanceLog::displayData()
+{
+ QPerformanceLogData *logData = performanceLogData();
+
+ for(QPerformanceLogData::Logs::ConstIterator iter = logData->logs.begin();
+ iter != logData->logs.end();
+ ++iter) {
+ QPerformanceLog_displayData(iter.key(), &(*iter));
+ }
+}
+
+void QPerformanceLog::clear()
+{
+ QPerformanceLogData *logData = performanceLogData();
+
+ for(QPerformanceLogData::Logs::ConstIterator iter = logData->logs.begin();
+ iter != logData->logs.end();
+ ++iter) {
+ QPerformanceLog_clear(iter.key(), &(*iter));
+ }
+}
+
+void QPerformanceLog::displayData(LogData *l)
+{
+ QPerformanceLogData *logData = performanceLogData();
+ QPerformanceLogData::Logs::ConstIterator iter = logData->logs.find(l);
+ if(iter == logData->logs.end())
+ qFatal("QPerformanceLog: Internal corruption - unable to locate log");
+
+ QPerformanceLog_displayData(iter.key(), &(*iter));
+}
+
+void QPerformanceLog::clear(LogData *l)
+{
+ QPerformanceLogData *logData = performanceLogData();
+ QPerformanceLogData::Logs::ConstIterator iter = logData->logs.find(l);
+ if(iter == logData->logs.end())
+ qFatal("QPerformanceLog: Internal corruption - unable to locate log");
+
+ QPerformanceLog_clear(iter.key(), &(*iter));
+}
+
+#else // Q_ENABLE_PERFORMANCE_LOG
+
+void QPerformanceLog::displayData()
+{
+}
+
+void QPerformanceLog::clear()
+{
+}
+
+#endif // Q_ENABLE_PERFORMANCE_LOG
diff --git a/src/declarative/util/qperformancelog.h b/src/declarative/util/qperformancelog.h
new file mode 100644
index 0000000..9d19bbd
--- /dev/null
+++ b/src/declarative/util/qperformancelog.h
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPERFORMANCELOG_H
+#define QPERFORMANCELOG_H
+
+#include <QtCore/qdatetime.h>
+namespace QPerformanceLog
+{
+ Q_DECLARATIVE_EXPORT void displayData();
+ Q_DECLARATIVE_EXPORT void clear();
+
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+ struct LogData {
+ LogData(const char *);
+ QTime timer;
+ int sumTime;
+ unsigned int *data;
+ };
+
+ struct LogMetric {
+ LogMetric(LogData *, int, const char *);
+ };
+
+ // Internal
+ void displayData(LogData *);
+ void clear(LogData *);
+#endif
+};
+
+#ifdef Q_ENABLE_PERFORMANCE_LOG
+
+#define Q_DECLARE_PERFORMANCE_METRIC(name) \
+ enum { name = ValueChoice<0, ValueTracker<0, __LINE__>::value, __LINE__>::value }; \
+ template<int L> \
+ struct ValueTracker<name, L> \
+ { \
+ enum { value = name }; \
+ }; \
+ extern QPerformanceLog::LogMetric metric ## name;
+
+#define Q_DECLARE_PERFORMANCE_LOG(name) \
+ namespace name { \
+ extern QPerformanceLog::LogData log; \
+ inline void displayData() { QPerformanceLog::displayData(&log); } \
+ inline void clear() { QPerformanceLog::clear(&log); } \
+ } \
+ template<int N> \
+ class name ## Timer { \
+ public: \
+ name ## Timer() { \
+ lastSum = name::log.sumTime + name::log.timer.restart(); \
+ name::log.sumTime = 0; \
+ } \
+ ~ name ## Timer() { \
+ name::log.data[2 * N] += name::log.sumTime + name::log.timer.restart(); \
+ ++name::log.data[2 * N + 1]; \
+ name::log.sumTime = lastSum; \
+ } \
+ private: \
+ int lastSum; \
+ }; \
+ namespace name { \
+ template<int N, int L> \
+ struct ValueTracker \
+ { \
+ enum { value = -1 }; \
+ }; \
+ template<int DefNextValue, int NextValue, int L> \
+ struct ValueChoice \
+ { \
+ enum { value = ValueChoice<DefNextValue + 1, ValueTracker<DefNextValue + 1, L>::value, L>::value }; \
+ }; \
+ template<int DefNextValue, int L> \
+ struct ValueChoice<DefNextValue, -1, L> \
+ { \
+ enum { value = DefNextValue }; \
+ }; \
+ } \
+ namespace name
+
+#define Q_DEFINE_PERFORMANCE_LOG(name, desc) \
+ QPerformanceLog::LogData name::log(desc); \
+ namespace name
+
+#define Q_DEFINE_PERFORMANCE_METRIC(name, desc) \
+ QPerformanceLog::LogMetric metrix ## name(&log, name, desc);
+
+#else // Q_ENABLE_PERFORMANCE_LOG
+
+#define Q_DECLARE_PERFORMANCE_METRIC(name) \
+ enum { name = ValueChoice<0, ValueTracker<0, __LINE__>::value, __LINE__>::value }; \
+ template<int L> \
+ struct ValueTracker<name, L> \
+ { \
+ enum { value = name }; \
+ }; \
+
+#define Q_DECLARE_PERFORMANCE_LOG(name) \
+ namespace name { \
+ inline void displayData() { }; \
+ inline void clear() { }; \
+ } \
+ template<int N> \
+ class name ## Timer { \
+ public: \
+ name ## Timer() { \
+ } \
+ ~ name ## Timer() { \
+ } \
+ }; \
+ namespace name { \
+ template<int N, int L> \
+ struct ValueTracker \
+ { \
+ enum { value = -1 }; \
+ }; \
+ template<int DefNextValue, int NextValue, int L> \
+ struct ValueChoice \
+ { \
+ enum { value = ValueChoice<DefNextValue + 1, ValueTracker<DefNextValue + 1, L>::value, L>::value }; \
+ }; \
+ template<int DefNextValue, int L> \
+ struct ValueChoice<DefNextValue, -1, L> \
+ { \
+ enum { value = DefNextValue }; \
+ }; \
+ } \
+ namespace name
+
+#define Q_DEFINE_PERFORMANCE_LOG(name, desc) \
+ namespace name
+
+#define Q_DEFINE_PERFORMANCE_METRIC(name, desc)
+
+#endif // Q_ENABLE_PERFORMANCE_LOG
+
+#endif // QPERFORMANCELOG_H
diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri
new file mode 100644
index 0000000..030a44e
--- /dev/null
+++ b/src/declarative/util/util.pri
@@ -0,0 +1,49 @@
+SOURCES += \
+ util/qfxview.cpp \
+ util/qfxperf.cpp \
+ util/qperformancelog.cpp \
+ util/qmlconnection.cpp \
+ util/qmlpackage.cpp \
+ util/qmlscript.cpp \
+ util/qmlanimation.cpp \
+ util/qmlbehaviour.cpp \
+ util/qmlfont.cpp \
+ util/qmlfollow.cpp \
+ util/qmlstate.cpp\
+ util/qmlstateoperations.cpp \
+ util/qmlsetproperties.cpp \
+ util/qmlstategroup.cpp \
+ util/qmltransition.cpp \
+ util/qbindablemap.cpp \
+ util/qmldatetimeformatter.cpp \
+ util/qmllistmodel.cpp\
+ util/qmllistaccessor.cpp \
+ util/qmlopenmetaobject.cpp \
+ util/qmlbind.cpp
+
+HEADERS += \
+ util/qfxview.h \
+ util/qfxperf.h \
+ util/qfxglobal.h \
+ util/qperformancelog.h \
+ util/qmlconnection.h \
+ util/qmlpackage.h \
+ util/qmlscript.h \
+ util/qmlanimation.h \
+ util/qmlanimation_p.h \
+ util/qmlbehaviour.h \
+ util/qmlfont.h \
+ util/qmlfollow.h \
+ util/qmlstate.h\
+ util/qmlstateoperations.h \
+ util/qmlsetproperties.h \
+ util/qmlstate_p.h\
+ util/qmlstategroup.h \
+ util/qmltransition.h \
+ util/qbindablemap.h \
+ util/qmldatetimeformatter.h \
+ util/qmllistmodel.h\
+ util/qmllistaccessor.h \
+ util/qmlopenmetaobject.h \
+ util/qmlnullablevalue_p.h \
+ util/qmlbind.h