summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2009-10-22 01:59:33 (GMT)
committerMartin Jones <martin.jones@nokia.com>2009-10-22 01:59:33 (GMT)
commit6c9ac788a60fcd2f946787a5297d7c2f71ad1968 (patch)
treeaf53424d7d2adfcbb324624ab93d31845d3db80d /src
parent2391cf5d127882ce8811e058115d5c2605328079 (diff)
parentfa85d539decf7bdcb16fa8f52858b13479cea659 (diff)
downloadQt-6c9ac788a60fcd2f946787a5297d7c2f71ad1968.zip
Qt-6c9ac788a60fcd2f946787a5297d7c2f71ad1968.tar.gz
Qt-6c9ac788a60fcd2f946787a5297d7c2f71ad1968.tar.bz2
Merge branch 'kinetic-declarativeui' of scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
Diffstat (limited to 'src')
-rw-r--r--src/corelib/animation/qabstractanimation.cpp27
-rw-r--r--src/declarative/debugger/qmldebug.cpp81
-rw-r--r--src/declarative/debugger/qmldebug.h24
-rw-r--r--src/declarative/extra/extra.pri4
-rw-r--r--src/declarative/extra/qbindablemap.cpp182
-rw-r--r--src/declarative/extra/qmlfolderlistmodel.cpp413
-rw-r--r--src/declarative/extra/qmlfolderlistmodel.h128
-rw-r--r--src/declarative/fx/qfxlistview.cpp46
-rw-r--r--src/declarative/qml/qml.pri2
-rw-r--r--src/declarative/qml/qmlcompiler.cpp32
-rw-r--r--src/declarative/qml/qmlcompiler_p.h3
-rw-r--r--src/declarative/qml/qmlengine.cpp70
-rw-r--r--src/declarative/qml/qmlengine_p.h3
-rw-r--r--src/declarative/qml/qmlenginedebug.cpp81
-rw-r--r--src/declarative/qml/qmlenginedebug_p.h2
-rw-r--r--src/declarative/qml/qmlexpression.cpp16
-rw-r--r--src/declarative/qml/qmlexpression.h2
-rw-r--r--src/declarative/qml/qmlexpression_p.h4
-rw-r--r--src/declarative/qml/qmlinstruction_p.h6
-rw-r--r--src/declarative/qml/qmlparser.cpp10
-rw-r--r--src/declarative/qml/qmlparser_p.h2
-rw-r--r--src/declarative/qml/qmlscriptstring.cpp154
-rw-r--r--src/declarative/qml/qmlscriptstring.h87
-rw-r--r--src/declarative/qml/qmlsqldatabase.cpp2
-rw-r--r--src/declarative/qml/qmlvme.cpp16
-rw-r--r--src/declarative/qml/qmlvmemetaobject.cpp3
-rw-r--r--src/declarative/qml/qmlvmemetaobject_p.h1
-rw-r--r--src/declarative/util/qmlanimation_p.h2
-rw-r--r--src/declarative/util/qmlopenmetaobject.cpp8
-rw-r--r--src/declarative/util/qmlopenmetaobject.h1
-rw-r--r--src/declarative/util/qmlpropertymap.cpp273
-rw-r--r--src/declarative/util/qmlpropertymap.h (renamed from src/declarative/extra/qbindablemap.h)33
-rw-r--r--src/declarative/util/util.pri6
33 files changed, 927 insertions, 797 deletions
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index 8d34a98..0d5f278 100644
--- a/src/corelib/animation/qabstractanimation.cpp
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -228,7 +228,11 @@ void QUnifiedTimer::updateAnimationsTime()
void QUnifiedTimer::restartAnimationTimer()
{
- if (!animationTimer.isActive()) {
+ if (runningLeafAnimations == 0 && !runningPauseAnimations.isEmpty()) {
+ int closestTimeToFinish = closestPauseAnimationTimeToFinish();
+ animationTimer.start(closestTimeToFinish, this);
+ isPauseTimerActive = true;
+ } else if (!animationTimer.isActive() || isPauseTimerActive) {
animationTimer.start(timingInterval, this);
isPauseTimerActive = false;
}
@@ -274,11 +278,11 @@ void QUnifiedTimer::registerAnimation(QAbstractAnimation *animation, bool isTopL
void QUnifiedTimer::unregisterAnimation(QAbstractAnimation *animation)
{
- unregisterRunningAnimation(animation);
-
if (!QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer)
return;
+ unregisterRunningAnimation(animation);
+
int idx = animations.indexOf(animation);
if (idx != -1) {
animations.removeAt(idx);
@@ -314,6 +318,7 @@ void QUnifiedTimer::unregisterRunningAnimation(QAbstractAnimation *animation)
runningPauseAnimations.removeOne(animation);
else
runningLeafAnimations--;
+ Q_ASSERT(runningLeafAnimations >= 0);
}
int QUnifiedTimer::closestPauseAnimationTimeToFinish()
@@ -324,9 +329,9 @@ int QUnifiedTimer::closestPauseAnimationTimeToFinish()
int timeToFinish;
if (animation->direction() == QAbstractAnimation::Forward)
- timeToFinish = animation->duration() - QAbstractAnimationPrivate::get(animation)->currentTime;
+ timeToFinish = animation->duration() - animation->currentTime();
else
- timeToFinish = QAbstractAnimationPrivate::get(animation)->totalCurrentTime;
+ timeToFinish = animation->currentTime();
if (timeToFinish < closestTimeToFinish)
closestTimeToFinish = timeToFinish;
@@ -644,13 +649,13 @@ int QAbstractAnimation::currentLoop() const
*/
int QAbstractAnimation::totalDuration() const
{
- Q_D(const QAbstractAnimation);
- if (d->loopCount < 0)
- return -1;
int dura = duration();
- if (dura == -1)
+ if (dura <= 0)
+ return dura;
+ int loopcount = loopCount();
+ if (loopcount < 0)
return -1;
- return dura * d->loopCount;
+ return dura * loopcount;
}
/*!
@@ -681,7 +686,7 @@ void QAbstractAnimation::setCurrentTime(int msecs)
// Calculate new time and loop.
int dura = duration();
- int totalDura = (d->loopCount < 0 || dura == -1) ? -1 : dura * d->loopCount;
+ int totalDura = dura <= 0 ? dura : ((d->loopCount < 0) ? -1 : dura * d->loopCount);
if (totalDura != -1)
msecs = qMin(totalDura, msecs);
d->totalCurrentTime = msecs;
diff --git a/src/declarative/debugger/qmldebug.cpp b/src/declarative/debugger/qmldebug.cpp
index 1ef7503..2537ec0 100644
--- a/src/declarative/debugger/qmldebug.cpp
+++ b/src/declarative/debugger/qmldebug.cpp
@@ -32,10 +32,12 @@ public:
static void remove(QmlEngineDebug *, QmlDebugEnginesQuery *);
static void remove(QmlEngineDebug *, QmlDebugRootContextQuery *);
static void remove(QmlEngineDebug *, QmlDebugObjectQuery *);
+ static void remove(QmlEngineDebug *, QmlDebugExpressionQuery *);
QHash<int, QmlDebugEnginesQuery *> enginesQuery;
QHash<int, QmlDebugRootContextQuery *> rootContextQuery;
QHash<int, QmlDebugObjectQuery *> objectQuery;
+ QHash<int, QmlDebugExpressionQuery *> expressionQuery;
QHash<int, QmlDebugWatch *> watched;
};
@@ -81,6 +83,12 @@ void QmlEngineDebugPrivate::remove(QmlEngineDebug *c, QmlDebugObjectQuery *q)
p->objectQuery.remove(q->m_queryId);
}
+void QmlEngineDebugPrivate::remove(QmlEngineDebug *c, QmlDebugExpressionQuery *q)
+{
+ QmlEngineDebugPrivate *p = (QmlEngineDebugPrivate *)QObjectPrivate::get(c);
+ p->expressionQuery.remove(q->m_queryId);
+}
+
Q_DECLARE_METATYPE(QmlDebugObjectReference);
void QmlEngineDebugPrivate::decode(QDataStream &ds, QmlDebugObjectReference &o,
bool simple)
@@ -109,6 +117,7 @@ void QmlEngineDebugPrivate::decode(QDataStream &ds, QmlDebugObjectReference &o,
prop.m_name = data.name;
prop.m_binding = data.binding;
prop.m_hasNotifySignal = data.hasNotifySignal;
+ prop.m_valueTypeName = data.valueTypeName;
if (data.type == QmlEngineDebugServer::QmlObjectProperty::Basic)
prop.m_value = data.value;
else if (data.type == QmlEngineDebugServer::QmlObjectProperty::Object) {
@@ -116,7 +125,6 @@ void QmlEngineDebugPrivate::decode(QDataStream &ds, QmlDebugObjectReference &o,
obj.m_debugId = prop.m_value.toInt();
prop.m_value = qVariantFromValue(obj);
}
-
o.m_properties << prop;
}
@@ -212,6 +220,19 @@ void QmlEngineDebugPrivate::message(const QByteArray &data)
query->m_client = 0;
query->setState(QmlDebugQuery::Completed);
+ } else if (type == "EVAL_EXPRESSION_R") {
+ int queryId;
+ QVariant result;
+ ds >> queryId >> result;
+
+ QmlDebugExpressionQuery *query = expressionQuery.value(queryId);
+ if (!query)
+ return;
+ expressionQuery.remove(queryId);
+
+ query->m_result = result;
+ query->m_client = 0;
+ query->setState(QmlDebugQuery::Completed);
} else if (type == "WATCH_PROPERTY_R") {
int queryId;
bool ok;
@@ -267,7 +288,6 @@ QmlDebugPropertyWatch *QmlEngineDebug::addWatch(const QmlDebugPropertyReference
QmlDebugPropertyWatch *watch = new QmlDebugPropertyWatch(parent);
if (d->client->isConnected()) {
- //query->m_client = this;
int queryId = d->getId();
watch->m_queryId = queryId;
watch->m_objectDebugId = property.objectDebugId();
@@ -445,6 +465,29 @@ QmlDebugObjectQuery *QmlEngineDebug::queryObjectRecursive(const QmlDebugObjectRe
return query;
}
+QmlDebugExpressionQuery *QmlEngineDebug::queryExpressionResult(int objectDebugId, const QString &expr, QObject *parent)
+{
+ Q_D(QmlEngineDebug);
+
+ QmlDebugExpressionQuery *query = new QmlDebugExpressionQuery(parent);
+ if (d->client->isConnected() && objectDebugId != -1) {
+ query->m_client = this;
+ query->m_expr = expr;
+ int queryId = d->getId();
+ query->m_queryId = queryId;
+ d->expressionQuery.insert(queryId, query);
+
+ QByteArray message;
+ QDataStream ds(&message, QIODevice::WriteOnly);
+ ds << QByteArray("EVAL_EXPRESSION") << queryId << objectDebugId << expr;
+ d->client->sendMessage(message);
+ } else {
+ query->m_state = QmlDebugQuery::Error;
+ }
+
+ return query;
+}
+
QmlDebugWatch::QmlDebugWatch(QObject *parent)
: QObject(parent), m_state(Waiting), m_queryId(-1), m_objectDebugId(-1)
{
@@ -566,6 +609,27 @@ QmlDebugObjectReference QmlDebugObjectQuery::object() const
return m_object;
}
+QmlDebugExpressionQuery::QmlDebugExpressionQuery(QObject *parent)
+: QmlDebugQuery(parent), m_client(0), m_queryId(-1)
+{
+}
+
+QmlDebugExpressionQuery::~QmlDebugExpressionQuery()
+{
+ if (m_client && m_queryId != -1)
+ QmlEngineDebugPrivate::remove(m_client, this);
+}
+
+QString QmlDebugExpressionQuery::expression() const
+{
+ return m_expr;
+}
+
+QVariant QmlDebugExpressionQuery::result() const
+{
+ return m_result;
+}
+
QmlDebugEngineReference::QmlDebugEngineReference()
: m_debugId(-1)
{
@@ -748,13 +812,17 @@ QmlDebugPropertyReference::QmlDebugPropertyReference()
}
QmlDebugPropertyReference::QmlDebugPropertyReference(const QmlDebugPropertyReference &o)
-: m_objectDebugId(o.m_objectDebugId), m_name(o.m_name), m_value(o.m_value), m_binding(o.m_binding), m_hasNotifySignal(o.m_hasNotifySignal)
+: m_objectDebugId(o.m_objectDebugId), m_name(o.m_name), m_value(o.m_value),
+ m_valueTypeName(o.m_valueTypeName), m_binding(o.m_binding),
+ m_hasNotifySignal(o.m_hasNotifySignal)
{
}
QmlDebugPropertyReference &QmlDebugPropertyReference::operator=(const QmlDebugPropertyReference &o)
{
- m_objectDebugId = o.m_objectDebugId; m_name = o.m_name; m_value = o.m_value; m_binding = o.m_binding; m_hasNotifySignal = o.m_hasNotifySignal;
+ m_objectDebugId = o.m_objectDebugId; m_name = o.m_name; m_value = o.m_value;
+ m_valueTypeName = o.m_valueTypeName; m_binding = o.m_binding;
+ m_hasNotifySignal = o.m_hasNotifySignal;
return *this;
}
@@ -768,6 +836,11 @@ QString QmlDebugPropertyReference::name() const
return m_name;
}
+QString QmlDebugPropertyReference::valueTypeName() const
+{
+ return m_valueTypeName;
+}
+
QVariant QmlDebugPropertyReference::value() const
{
return m_value;
diff --git a/src/declarative/debugger/qmldebug.h b/src/declarative/debugger/qmldebug.h
index 681ee08..bd076ff 100644
--- a/src/declarative/debugger/qmldebug.h
+++ b/src/declarative/debugger/qmldebug.h
@@ -12,6 +12,7 @@ class QmlDebugObjectExpressionWatch;
class QmlDebugEnginesQuery;
class QmlDebugRootContextQuery;
class QmlDebugObjectQuery;
+class QmlDebugExpressionQuery;
class QmlDebugPropertyReference;
class QmlDebugContextReference;
class QmlDebugObjectReference;
@@ -44,6 +45,9 @@ public:
QObject *parent = 0);
QmlDebugObjectQuery *queryObjectRecursive(const QmlDebugObjectReference &,
QObject *parent = 0);
+ QmlDebugExpressionQuery *queryExpressionResult(int objectDebugId,
+ const QString &expr,
+ QObject *parent = 0);
private:
Q_DECLARE_PRIVATE(QmlEngineDebug)
@@ -228,6 +232,7 @@ public:
int objectDebugId() const;
QString name() const;
QVariant value() const;
+ QString valueTypeName() const;
QString binding() const;
bool hasNotifySignal() const;
@@ -236,6 +241,7 @@ private:
int m_objectDebugId;
QString m_name;
QVariant m_value;
+ QString m_valueTypeName;
QString m_binding;
bool m_hasNotifySignal;
};
@@ -287,4 +293,22 @@ private:
};
+class Q_DECLARATIVE_EXPORT QmlDebugExpressionQuery : public QmlDebugQuery
+{
+Q_OBJECT
+public:
+ virtual ~QmlDebugExpressionQuery();
+ QString expression() const;
+ QVariant result() const;
+private:
+ friend class QmlEngineDebug;
+ friend class QmlEngineDebugPrivate;
+ QmlDebugExpressionQuery(QObject *);
+ QmlEngineDebug *m_client;
+ int m_queryId;
+ QString m_expr;
+ QVariant m_result;
+
+};
+
#endif // QMLDEBUG_H
diff --git a/src/declarative/extra/extra.pri b/src/declarative/extra/extra.pri
index 6730550..502504a 100644
--- a/src/declarative/extra/extra.pri
+++ b/src/declarative/extra/extra.pri
@@ -3,11 +3,9 @@ SOURCES += \
extra/qmlnumberformatter.cpp \
extra/qmldatetimeformatter.cpp \
extra/qfxintegermodel.cpp \
- extra/qmlfolderlistmodel.cpp \
extra/qfxanimatedimageitem.cpp \
extra/qfxparticles.cpp \
extra/qmlbehavior.cpp \
- extra/qbindablemap.cpp \
extra/qmlfontloader.cpp
HEADERS += \
@@ -15,12 +13,10 @@ HEADERS += \
extra/qmlnumberformatter.h \
extra/qmldatetimeformatter.h \
extra/qfxintegermodel.h \
- extra/qmlfolderlistmodel.h \
extra/qfxanimatedimageitem.h \
extra/qfxanimatedimageitem_p.h \
extra/qfxparticles.h \
extra/qmlbehavior.h \
- extra/qbindablemap.h \
extra/qmlfontloader.h
contains(QT_CONFIG, xmlpatterns) {
diff --git a/src/declarative/extra/qbindablemap.cpp b/src/declarative/extra/qbindablemap.cpp
deleted file mode 100644
index 5254e2a..0000000
--- a/src/declarative/extra/qbindablemap.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/****************************************************************************
-**
-** 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(QString::fromUtf8(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);
-}
-
-/*!
- Destroys the bindable map.
-*/
-QBindableMap::~QBindableMap()
-{
-}
-
-/*!
- Clears the value (if any) associated with \a key.
-*/
-void QBindableMap::clearValue(const QString &key)
-{
- //m_keys.remove(); //###
- m_mo->setValue(key.toUtf8(), 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.toUtf8());
-}
-
-/*!
- 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.toUtf8(), 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/extra/qmlfolderlistmodel.cpp b/src/declarative/extra/qmlfolderlistmodel.cpp
deleted file mode 100644
index 0e5c275..0000000
--- a/src/declarative/extra/qmlfolderlistmodel.cpp
+++ /dev/null
@@ -1,413 +0,0 @@
-/****************************************************************************
-**
-** 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 <QDirModel>
-#include <qdebug.h>
-#include "qmlfolderlistmodel.h"
-#include <QtDeclarative/qmlcontext.h>
-
-QT_BEGIN_NAMESPACE
-
-class QmlFolderListModelPrivate : public QObjectPrivate
-{
-public:
- QmlFolderListModelPrivate()
- : sortField(QmlFolderListModel::Name), sortReversed(false), count(0) {
- nameFilters << QLatin1String("*");
- }
-
- void updateSorting() {
- QDir::SortFlags flags = 0;
- switch(sortField) {
- case QmlFolderListModel::Unsorted:
- flags |= QDir::Unsorted;
- break;
- case QmlFolderListModel::Name:
- flags |= QDir::Name;
- break;
- case QmlFolderListModel::Time:
- flags |= QDir::Time;
- break;
- case QmlFolderListModel::Size:
- flags |= QDir::Size;
- break;
- case QmlFolderListModel::Type:
- flags |= QDir::Type;
- break;
- }
-
- if (sortReversed)
- flags |= QDir::Reversed;
-
- model.setSorting(flags);
- }
-
- QDirModel model;
- QUrl folder;
- QStringList nameFilters;
- QModelIndex folderIndex;
- QmlFolderListModel::SortField sortField;
- bool sortReversed;
- int count;
-};
-
-/*!
- \qmlclass FolderListModel
- \brief The FolderListModel provides a model of the contents of a folder in a filesystem.
-
- FolderListModel provides access to the local filesystem. The \e folder property
- specifies the folder to list.
-
- Qt uses "/" as a universal directory separator in the same way that "/" is
- used as a path separator in URLs. If you always use "/" as a directory
- separator, Qt will translate your paths to conform to the underlying
- operating system.
-
- The roles available are:
- \list
- \o fileName
- \o filePath
- \endlist
-
- Additionally a file entry can be differentiated from a folder entry
- via the \l isFolder() method.
-*/
-
-QmlFolderListModel::QmlFolderListModel(QObject *parent)
- : QListModelInterface(*(new QmlFolderListModelPrivate), parent)
-{
- Q_D(QmlFolderListModel);
- d->model.setFilter(QDir::AllDirs | QDir::Files | QDir::Drives | QDir::NoDotAndDotDot);
- connect(&d->model, SIGNAL(rowsInserted(const QModelIndex&,int,int))
- , this, SLOT(inserted(const QModelIndex&,int,int)));
- connect(&d->model, SIGNAL(rowsRemoved(const QModelIndex&,int,int))
- , this, SLOT(removed(const QModelIndex&,int,int)));
- connect(&d->model, SIGNAL(dataChanged(const QModelIndex&,const QModelIndex&))
- , this, SLOT(dataChanged(const QModelIndex&,const QModelIndex&)));
- connect(&d->model, SIGNAL(modelReset()), this, SLOT(refresh()));
- connect(&d->model, SIGNAL(layoutChanged()), this, SLOT(refresh()));
-}
-
-QmlFolderListModel::~QmlFolderListModel()
-{
-}
-
-QHash<int,QVariant> QmlFolderListModel::data(int index, const QList<int> &roles) const
-{
- Q_UNUSED(roles);
- Q_D(const QmlFolderListModel);
- QHash<int,QVariant> folderData;
- QModelIndex modelIndex = d->model.index(index, 0, d->folderIndex);
- if (modelIndex.isValid()) {
- folderData[QDirModel::FileNameRole] = d->model.data(modelIndex, QDirModel::FileNameRole);
- folderData[QDirModel::FilePathRole] = QUrl::fromLocalFile(d->model.data(modelIndex, QDirModel::FilePathRole).toString());
- }
-
- return folderData;
-}
-
-int QmlFolderListModel::count() const
-{
- Q_D(const QmlFolderListModel);
- return d->count;
-}
-
-QList<int> QmlFolderListModel::roles() const
-{
- QList<int> r;
- r << QDirModel::FileNameRole;
- r << QDirModel::FilePathRole;
- return r;
-}
-
-QString QmlFolderListModel::toString(int role) const
-{
- switch (role) {
- case QDirModel::FileNameRole:
- return QLatin1String("fileName");
- case QDirModel::FilePathRole:
- return QLatin1String("filePath");
- }
-
- return QString();
-}
-
-/*!
- \qmlproperty string FolderListModel::folder
-
- The \a folder property holds the folder the model is currently providing.
-
- It is a URL, but must be a file: or qrc: URL (or relative to such a URL).
-*/
-QUrl QmlFolderListModel::folder() const
-{
- Q_D(const QmlFolderListModel);
- return d->folder;
-}
-
-void QmlFolderListModel::setFolder(const QUrl &folder)
-{
- Q_D(QmlFolderListModel);
- if (folder == d->folder)
- return;
- QModelIndex index = d->model.index(folder.toLocalFile());
- if (index.isValid() && d->model.isDir(index)) {
- d->folder = folder;
- QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection);
- emit folderChanged();
- }
-}
-
-QUrl QmlFolderListModel::parentFolder() const
-{
- Q_D(const QmlFolderListModel);
- int pos = d->folder.path().lastIndexOf(QLatin1Char('/'));
- if (pos == -1)
- return QUrl();
- QUrl r = d->folder;
- r.setPath(d->folder.path().left(pos));
- return r;
-}
-
-/*!
- \qmlproperty list<string> FolderListModel::nameFilters
-
- The \a nameFilters property contains a list of filename filters.
- The filters may include the ? and * wildcards.
-
- The example below filters on PNG and JPEG files:
-
- \code
- FolderListModel {
- nameFilters: [ "*.png", "*.jpg" ]
- }
- \endcode
-*/
-QStringList QmlFolderListModel::nameFilters() const
-{
- Q_D(const QmlFolderListModel);
- return d->nameFilters;
-}
-
-void QmlFolderListModel::setNameFilters(const QStringList &filters)
-{
- Q_D(QmlFolderListModel);
- d->nameFilters = filters;
- d->model.setNameFilters(d->nameFilters);
-}
-
-void QmlFolderListModel::componentComplete()
-{
- Q_D(QmlFolderListModel);
- if (!d->folder.isValid() || !QDir().exists(d->folder.toLocalFile()))
- setFolder(QUrl(QLatin1String("file://")+QDir::currentPath()));
-
- if (!d->folderIndex.isValid())
- QMetaObject::invokeMethod(this, "refresh", Qt::QueuedConnection);
-}
-
-QmlFolderListModel::SortField QmlFolderListModel::sortField() const
-{
- Q_D(const QmlFolderListModel);
- return d->sortField;
-}
-
-void QmlFolderListModel::setSortField(SortField field)
-{
- Q_D(QmlFolderListModel);
- if (field != d->sortField) {
- d->sortField = field;
- d->updateSorting();
- }
-}
-
-bool QmlFolderListModel::sortReversed() const
-{
- Q_D(const QmlFolderListModel);
- return d->sortReversed;
-}
-
-void QmlFolderListModel::setSortReversed(bool rev)
-{
- Q_D(QmlFolderListModel);
- if (rev != d->sortReversed) {
- d->sortReversed = rev;
- d->updateSorting();
- }
-}
-
-/*!
- \qmlmethod bool FolderListModel::isFolder(int index)
-
- Returns true if the entry \a index is a folder; otherwise
- returns false.
-*/
-bool QmlFolderListModel::isFolder(int index) const
-{
- Q_D(const QmlFolderListModel);
- if (index != -1) {
- QModelIndex idx = d->model.index(index, 0, d->folderIndex);
- if (idx.isValid())
- return d->model.isDir(idx);
- }
- return false;
-}
-
-void QmlFolderListModel::refresh()
-{
- Q_D(QmlFolderListModel);
- d->folderIndex = QModelIndex();
- if (d->count) {
- int tmpCount = d->count;
- d->count = 0;
- emit itemsRemoved(0, tmpCount);
- }
- d->folderIndex = d->model.index(d->folder.toLocalFile());
- d->count = d->model.rowCount(d->folderIndex);
- if (d->count) {
- emit itemsInserted(0, d->count);
- }
-}
-
-void QmlFolderListModel::inserted(const QModelIndex &index, int start, int end)
-{
- Q_D(QmlFolderListModel);
- if (index == d->folderIndex) {
- d->count = d->model.rowCount(d->folderIndex);
- emit itemsInserted(start, end - start + 1);
- }
-}
-
-void QmlFolderListModel::removed(const QModelIndex &index, int start, int end)
-{
- Q_D(QmlFolderListModel);
- if (index == d->folderIndex) {
- d->count = d->model.rowCount(d->folderIndex);
- emit itemsRemoved(start, end - start + 1);
- }
-}
-
-void QmlFolderListModel::dataChanged(const QModelIndex &start, const QModelIndex &end)
-{
- Q_D(QmlFolderListModel);
- qDebug() << "data changed";
- if (start.parent() == d->folderIndex)
- emit itemsChanged(start.row(), end.row() - start.row() + 1, roles());
-}
-
-/*!
- \qmlproperty bool FolderListModel::showDirs
-
- If true (the default), directories are included in the model.
-
- Note that the nameFilters are ignored for directories.
-*/
-bool QmlFolderListModel::showDirs() const
-{
- Q_D(const QmlFolderListModel);
- return d->model.filter() & QDir::AllDirs;
-}
-
-void QmlFolderListModel::setShowDirs(bool on)
-{
- Q_D(QmlFolderListModel);
- if (!(d->model.filter() & QDir::AllDirs) == !on)
- return;
- if (on)
- d->model.setFilter(d->model.filter() | QDir::AllDirs | QDir::Drives);
- else
- d->model.setFilter(d->model.filter() & ~(QDir::AllDirs | QDir::Drives));
-}
-
-/*!
- \qmlproperty bool FolderListModel::showDotAndDotDot
-
- If true, the "." and ".." directories are included in the model.
-
- The default is false.
-*/
-bool QmlFolderListModel::showDotAndDotDot() const
-{
- Q_D(const QmlFolderListModel);
- return !(d->model.filter() & QDir::NoDotAndDotDot);
-}
-
-void QmlFolderListModel::setShowDotAndDotDot(bool on)
-{
- Q_D(QmlFolderListModel);
- if (!(d->model.filter() & QDir::NoDotAndDotDot) == on)
- return;
- if (on)
- d->model.setFilter(d->model.filter() & ~QDir::NoDotAndDotDot);
- else
- d->model.setFilter(d->model.filter() | QDir::NoDotAndDotDot);
-}
-
-/*!
- \qmlproperty bool FolderListModel::showOnlyReadable
-
- If true, only readable files and directories are shown.
-
- The default is false.
-*/
-bool QmlFolderListModel::showOnlyReadable() const
-{
- Q_D(const QmlFolderListModel);
- return d->model.filter() & QDir::Readable;
-}
-
-void QmlFolderListModel::setShowOnlyReadable(bool on)
-{
- Q_D(QmlFolderListModel);
- if (!(d->model.filter() & QDir::Readable) == !on)
- return;
- if (on)
- d->model.setFilter(d->model.filter() | QDir::Readable);
- else
- d->model.setFilter(d->model.filter() & ~QDir::Readable);
-}
-
-
-QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,FolderListModel,QmlFolderListModel)
-
-QT_END_NAMESPACE
-
diff --git a/src/declarative/extra/qmlfolderlistmodel.h b/src/declarative/extra/qmlfolderlistmodel.h
deleted file mode 100644
index 66e600b..0000000
--- a/src/declarative/extra/qmlfolderlistmodel.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/****************************************************************************
-**
-** 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 QMLFOLDERLISTMODEL_H
-#define QMLFOLDERLISTMODEL_H
-
-#include <QtDeclarative/qml.h>
-#include <QtDeclarative/QListModelInterface>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-class QmlContext;
-class QModelIndex;
-
-class QmlFolderListModelPrivate;
-class Q_DECLARATIVE_EXPORT QmlFolderListModel : public QListModelInterface, public QmlParserStatus
-{
- Q_OBJECT
- Q_INTERFACES(QmlParserStatus)
-
- Q_PROPERTY(QUrl folder READ folder WRITE setFolder NOTIFY folderChanged)
- Q_PROPERTY(QUrl parentFolder READ parentFolder NOTIFY folderChanged)
- Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters)
- Q_PROPERTY(SortField sortField READ sortField WRITE setSortField)
- Q_PROPERTY(bool sortReversed READ sortReversed WRITE setSortReversed)
- Q_PROPERTY(bool showDirs READ showDirs WRITE setShowDirs)
- Q_PROPERTY(bool showDotAndDotDot READ showDotAndDotDot WRITE setShowDotAndDotDot)
- Q_PROPERTY(bool showOnlyReadable READ showOnlyReadable WRITE setShowOnlyReadable)
-
-public:
- QmlFolderListModel(QObject *parent = 0);
- ~QmlFolderListModel();
-
- virtual QHash<int,QVariant> data(int index, const QList<int> &roles = (QList<int>())) const;
- virtual int count() const;
- virtual QList<int> roles() const;
- virtual QString toString(int role) const;
-
- QUrl folder() const;
- void setFolder(const QUrl &folder);
-
- QUrl parentFolder() const;
-
- QStringList nameFilters() const;
- void setNameFilters(const QStringList &filters);
-
- virtual void componentComplete();
-
- Q_INVOKABLE bool isFolder(int index) const;
-
- enum SortField { Unsorted, Name, Time, Size, Type };
- SortField sortField() const;
- void setSortField(SortField field);
- Q_ENUMS(SortField)
-
- bool sortReversed() const;
- void setSortReversed(bool rev);
-
- bool showDirs() const;
- void setShowDirs(bool);
- bool showDotAndDotDot() const;
- void setShowDotAndDotDot(bool);
- bool showOnlyReadable() const;
- void setShowOnlyReadable(bool);
-
-Q_SIGNALS:
- void folderChanged();
-
-private Q_SLOTS:
- void refresh();
- void inserted(const QModelIndex &index, int start, int end);
- void removed(const QModelIndex &index, int start, int end);
- void dataChanged(const QModelIndex &start, const QModelIndex &end);
-
-private:
- Q_DECLARE_PRIVATE(QmlFolderListModel)
- Q_DISABLE_COPY(QmlFolderListModel)
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QmlFolderListModel)
-
-QT_END_HEADER
-
-#endif // QMLFOLDERLISTMODEL_H
diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp
index 4fb0ec1..2ea1cb7 100644
--- a/src/declarative/fx/qfxlistview.cpp
+++ b/src/declarative/fx/qfxlistview.cpp
@@ -864,6 +864,52 @@ QFxListView::~QFxListView()
}
/*!
+ \qmlattachedproperty bool ListView::isCurrentItem
+ This attched property is true if this delegate is the current item; otherwise false.
+
+ It is attached to each instance of the delegate.
+
+ This property may be used to adjust the appearance of the current item, for example:
+
+ \snippet doc/src/snippets/declarative/listview/highlight.qml 0
+*/
+
+/*!
+ \qmlattachedproperty ListView ListView::view
+ This attached property holds the view that manages this delegate instance.
+
+ It is attached to each instance of the delegate.
+*/
+
+/*!
+ \qmlattachedproperty string ListView::prevSection
+ This attached property holds the section of the previous element.
+
+ It is attached to each instance of the delegate.
+
+ The section is evaluated using the \l {ListView::sectionExpression}{sectionExpression} property.
+*/
+
+/*!
+ \qmlattachedproperty string ListView::section
+ This attached property holds the section of this element.
+
+ It is attached to each instance of the delegate.
+
+ The section is evaluated using the \l {ListView::sectionExpression}{sectionExpression} property.
+*/
+
+/*!
+ \qmlattachedproperty bool ListView::delayRemove
+ This attached property holds whether the delegate may be destroyed.
+
+ It is attached to each instance of the delegate.
+
+ It is sometimes necessary to delay the destruction of an item
+ until an animation completes.
+*/
+
+/*!
\qmlproperty model ListView::model
This property holds the model providing data for the list.
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 58a18a2..b6e86a8 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -40,6 +40,7 @@ SOURCES += qml/qmlparser.cpp \
qml/qmlpropertycache.cpp \
qml/qmlintegercache.cpp \
qml/qmltypenamecache.cpp \
+ qml/qmlscriptstring.cpp \
qml/qmlobjectscriptclass.cpp \
qml/qmlcontextscriptclass.cpp \
qml/qmlglobalscriptclass.cpp \
@@ -102,6 +103,7 @@ HEADERS += qml/qmlparser_p.h \
qml/qmlpropertycache_p.h \
qml/qmlintegercache_p.h \
qml/qmltypenamecache_p.h \
+ qml/qmlscriptstring.h \
qml/qmlobjectscriptclass_p.h \
qml/qmlcontextscriptclass_p.h \
qml/qmlglobalscriptclass_p.h \
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index e2fd7cb..726051e 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -69,6 +69,7 @@
#include <private/qmlexpression_p.h>
#include "qmlmetaproperty_p.h"
#include "qmlrewrite_p.h"
+#include <QtDeclarative/qmlscriptstring.h>
#include "qmlscriptparser_p.h"
@@ -860,6 +861,17 @@ void QmlCompiler::genObject(QmlParser::Object *obj)
void QmlCompiler::genObjectBody(QmlParser::Object *obj)
{
+ typedef QPair<Property *, int> PropPair;
+ foreach(const PropPair &prop, obj->scriptStringProperties) {
+ QmlInstruction ss;
+ ss.type = QmlInstruction::StoreScriptString;
+ ss.storeScriptString.propertyIndex = prop.first->index;
+ ss.storeScriptString.value =
+ output->indexForString(prop.first->values.at(0)->value.asScript());
+ ss.storeScriptString.scope = prop.second;
+ output->bytecode << ss;
+ }
+
bool seenDefer = false;
foreach(Property *prop, obj->valueProperties) {
if (prop->isDeferred) {
@@ -1371,6 +1383,10 @@ bool QmlCompiler::buildProperty(QmlParser::Property *prop,
COMPILE_CHECK(buildListProperty(prop, obj, ctxt));
+ } else if (prop->type == qMetaTypeId<QmlScriptString>()) {
+
+ COMPILE_CHECK(buildScriptStringProperty(prop, obj, ctxt));
+
} else {
COMPILE_CHECK(buildPropertyAssignment(prop, obj, ctxt));
@@ -1823,6 +1839,22 @@ bool QmlCompiler::buildListProperty(QmlParser::Property *prop,
return true;
}
+// Compiles an assignment to a QmlScriptString property
+bool QmlCompiler::buildScriptStringProperty(QmlParser::Property *prop,
+ QmlParser::Object *obj,
+ const BindingContext &ctxt)
+{
+ if (prop->values.count() > 1)
+ COMPILE_EXCEPTION(prop->values.at(1), qApp->translate("QmlCompiler", "Cannot assign multiple values to a script property"));
+
+ if (prop->values.at(0)->object || !prop->values.at(0)->value.isScript())
+ COMPILE_EXCEPTION(prop->values.at(0), qApp->translate("QmlCompiler", "Invalid property assignment: script expected"));
+
+ obj->addScriptStringProperty(prop, ctxt.stack);
+
+ return true;
+}
+
// Compile regular property assignments of the form "property: <value>"
//
// ### The following problems exist
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index cff4937..8a9ca9c 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -197,6 +197,9 @@ private:
bool buildListProperty(QmlParser::Property *prop,
QmlParser::Object *obj,
const BindingContext &ctxt);
+ bool buildScriptStringProperty(QmlParser::Property *prop,
+ QmlParser::Object *obj,
+ const BindingContext &ctxt);
bool buildPropertyAssignment(QmlParser::Property *prop,
QmlParser::Object *obj,
const BindingContext &ctxt);
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 528e8c9..9fad80b 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -76,9 +76,10 @@
#include <QtCore/qdir.h>
#include <QtGui/qcolor.h>
#include <QtGui/qvector3d.h>
+#include <QtGui/qsound.h>
#include <qmlcomponent.h>
-#include "private/qmlcomponentjs_p.h"
-#include "private/qmlmetaproperty_p.h"
+#include <private/qmlcomponentjs_p.h>
+#include <private/qmlmetaproperty_p.h>
#include <private/qmlbinding_p.h>
#include <private/qmlvme_p.h>
#include <private/qmlenginedebug_p.h>
@@ -87,6 +88,7 @@
#include <private/qmlsqldatabase_p.h>
#include <private/qmltypenamescriptclass_p.h>
#include <private/qmllistscriptclass_p.h>
+#include <QtDeclarative/qmlscriptstring.h>
#ifdef Q_OS_WIN // for %APPDATA%
#include "qt_windows.h"
@@ -153,12 +155,14 @@ QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e)
qtObject.setProperty(QLatin1String("darker"), scriptEngine.newFunction(QmlEnginePrivate::darker, 1));
qtObject.setProperty(QLatin1String("tint"), scriptEngine.newFunction(QmlEnginePrivate::tint, 2));
+ //misc methods
+ qtObject.setProperty(QLatin1String("playSound"), scriptEngine.newFunction(QmlEnginePrivate::playSound, 1));
+
scriptEngine.globalObject().setProperty(QLatin1String("createQmlObject"),
scriptEngine.newFunction(QmlEnginePrivate::createQmlObject, 1));
scriptEngine.globalObject().setProperty(QLatin1String("createComponent"),
scriptEngine.newFunction(QmlEnginePrivate::createComponent, 1));
- //scriptEngine.globalObject().setScriptClass(new QmlGlobalScriptClass(&scriptEngine));
globalClass = new QmlGlobalScriptClass(&scriptEngine);
}
@@ -216,6 +220,9 @@ Q_GLOBAL_STATIC(QmlEngineDebugServer, qmlEngineDebugServer);
void QmlEnginePrivate::init()
{
Q_Q(QmlEngine);
+ qRegisterMetaType<QVariant>("QVariant");
+ qRegisterMetaType<QmlScriptString>("QmlScriptString");
+
scriptEngine.installTranslatorFunctions();
contextClass = new QmlContextScriptClass(q);
objectClass = new QmlObjectScriptClass(q);
@@ -281,8 +288,6 @@ QmlEngine::QmlEngine(QObject *parent)
{
Q_D(QmlEngine);
d->init();
-
- qRegisterMetaType<QVariant>("QVariant");
}
/*!
@@ -401,7 +406,12 @@ QmlContext *QmlEngine::contextForObject(const QObject *object)
QmlDeclarativeData *data =
static_cast<QmlDeclarativeData *>(priv->declarativeData);
- return data?data->context:0;
+ if (!data)
+ return 0;
+ else if (data->outerContext)
+ return data->outerContext;
+ else
+ return data->context;
}
/*!
@@ -565,6 +575,17 @@ QScriptValue QmlEnginePrivate::qmlScriptObject(QObject* object,
}
/*!
+ Returns the QmlContext for the executing QScript \a ctxt.
+*/
+QmlContext *QmlEnginePrivate::getContext(QScriptContext *ctxt)
+{
+ QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
+ Q_ASSERT(scopeNode.isValid());
+ Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
+ return contextClass->contextFromValue(scopeNode);
+}
+
+/*!
This function is intended for use inside QML only. In C++ just create a
component object as usual.
@@ -626,7 +647,7 @@ QScriptValue QmlEnginePrivate::createComponent(QScriptContext *ctxt,
static_cast<QmlScriptEngine*>(engine)->p;
QmlEngine* activeEngine = activeEnginePriv->q_func();
- QmlContext* context = activeEnginePriv->currentExpression->context();
+ QmlContext* context = activeEnginePriv->getContext(ctxt);
if(ctxt->argumentCount() != 1) {
c = new QmlComponentJS(activeEngine);
}else{
@@ -647,7 +668,7 @@ QScriptValue QmlEnginePrivate::createComponent(QScriptContext *ctxt,
Example (where targetItem is the id of an existing QML item):
\code
- newObject = createQmlObject('Rectangle {color: "red"; width: 20; height: 20}',
+ newObject = createQmlObject('import Qt 4.6; Rectangle {color: "red"; width: 20; height: 20}',
targetItem, "dynamicSnippet1");
\endcode
@@ -677,9 +698,16 @@ QScriptValue QmlEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngi
QUrl url;
if(ctxt->argumentCount() > 2)
url = QUrl(ctxt->argument(2).toString());
+ else
+ url = QUrl(QLatin1String("DynamicQML"));
QObject *parentArg = activeEnginePriv->objectClass->toQObject(ctxt->argument(1));
QmlContext *qmlCtxt = qmlContext(parentArg);
- url = qmlCtxt->resolvedUrl(url);
+ if (url.isEmpty()) {
+ url = qmlCtxt->resolvedUrl(QUrl(QLatin1String("<Unknown File>")));
+ } else {
+ url = qmlCtxt->resolvedUrl(url);
+ }
+
QmlComponent component(activeEngine, qml.toUtf8(), url);
if(component.isError()) {
QList<QmlError> errors = component.errors();
@@ -836,6 +864,30 @@ QScriptValue QmlEnginePrivate::darker(QScriptContext *ctxt, QScriptEngine *engin
return qScriptValueFromValue(engine, qVariantFromValue(color));
}
+QScriptValue QmlEnginePrivate::playSound(QScriptContext *ctxt, QScriptEngine *engine)
+{
+ if (ctxt->argumentCount() < 1)
+ return engine->undefinedValue();
+
+ QUrl url(ctxt->argument(0).toString());
+
+ QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(engine);
+ if (url.isRelative()) {
+ QmlContext *context = enginePriv->getContext(ctxt);
+ if (!context)
+ return engine->undefinedValue();
+
+ url = context->resolvedUrl(url);
+ }
+
+ if (url.scheme() == QLatin1String("file")) {
+
+ QSound::play(url.toLocalFile());
+
+ }
+ return engine->undefinedValue();
+}
+
/*!
This function allows tinting one color with another.
diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h
index a85ac55..a74854d 100644
--- a/src/declarative/qml/qmlengine_p.h
+++ b/src/declarative/qml/qmlengine_p.h
@@ -259,10 +259,13 @@ public:
static QScriptValue darker(QScriptContext*, QScriptEngine*);
static QScriptValue tint(QScriptContext*, QScriptEngine*);
+ static QScriptValue playSound(QScriptContext*, QScriptEngine*);
+
static QScriptEngine *getScriptEngine(QmlEngine *e) { return &e->d_func()->scriptEngine; }
static QmlEngine *getEngine(QScriptEngine *e) { return static_cast<QmlScriptEngine*>(e)->p->q_func(); }
static QmlEnginePrivate *get(QmlEngine *e) { return e->d_func(); }
static QmlEnginePrivate *get(QScriptEngine *e) { return static_cast<QmlScriptEngine*>(e)->p; }
+ QmlContext *getContext(QScriptContext *);
};
diff --git a/src/declarative/qml/qmlenginedebug.cpp b/src/declarative/qml/qmlenginedebug.cpp
index e20616a..7178e6c 100644
--- a/src/declarative/qml/qmlenginedebug.cpp
+++ b/src/declarative/qml/qmlenginedebug.cpp
@@ -80,7 +80,8 @@ QDataStream &operator>>(QDataStream &ds,
QDataStream &operator<<(QDataStream &ds,
const QmlEngineDebugServer::QmlObjectProperty &data)
{
- ds << (int)data.type << data.name << data.value << data.binding << data.hasNotifySignal;
+ ds << (int)data.type << data.name << data.value << data.valueTypeName
+ << data.binding << data.hasNotifySignal;
return ds;
}
@@ -88,7 +89,8 @@ QDataStream &operator>>(QDataStream &ds,
QmlEngineDebugServer::QmlObjectProperty &data)
{
int type;
- ds >> type >> data.name >> data.value >> data.binding >> data.hasNotifySignal;
+ ds >> type >> data.name >> data.value >> data.valueTypeName
+ >> data.binding >> data.hasNotifySignal;
data.type = (QmlEngineDebugServer::QmlObjectProperty::Type)type;
return ds;
}
@@ -101,6 +103,7 @@ QmlEngineDebugServer::propertyData(QObject *obj, int propIdx)
QMetaProperty prop = obj->metaObject()->property(propIdx);
rv.type = QmlObjectProperty::Unknown;
+ rv.valueTypeName = QString::fromUtf8(prop.typeName());
rv.name = prop.name();
rv.hasNotifySignal = prop.hasNotifySignal();
QmlAbstractBinding *binding = QmlMetaProperty(obj, rv.name).binding();
@@ -116,6 +119,7 @@ QmlEngineDebugServer::propertyData(QObject *obj, int propIdx)
QmlMetaType::isQmlList(prop.userType())) {
rv.type = QmlObjectProperty::List;
}
+
return rv;
}
@@ -149,7 +153,7 @@ void QmlEngineDebugServer::buildObjectList(QDataStream &message,
int ctxtId = QmlDebugService::idForObject(ctxt);
message << ctxtName << ctxtId;
-
+
int count = 0;
for (QSet<QmlContext *>::ConstIterator iter = p->childContexts.begin();
@@ -184,6 +188,32 @@ void QmlEngineDebugServer::buildObjectList(QDataStream &message,
}
}
+QVariant QmlEngineDebugServer::serializableVariant(const QVariant &value)
+{
+ if (value.type() < QVariant::UserType)
+ return value;
+
+ if (!value.toString().isEmpty())
+ return value.toString();
+
+ QVariant v;
+ if (value.type() == QVariant::UserType || QmlMetaType::isObject(value.userType())) {
+ QObject *o = QmlMetaType::toQObject(value);
+ if (o) {
+ QString objectName = o->objectName();
+ if (objectName.isEmpty())
+ objectName = QLatin1String("<unnamed>");
+ v = QString::fromUtf8(o->metaObject()->className()) +
+ QLatin1String(": ") + objectName;
+ }
+ }
+
+ if (v.isNull())
+ v = QString::fromUtf8(value.typeName());
+
+ return v;
+}
+
QmlEngineDebugServer::QmlObjectData
QmlEngineDebugServer::objectData(QObject *object)
{
@@ -310,29 +340,42 @@ void QmlEngineDebugServer::messageReceived(const QByteArray &message)
ds >> queryId;
m_watch->removeWatch(queryId);
+ } else if (type == "EVAL_EXPRESSION") {
+ int queryId;
+ int objectId;
+ QString expr;
+
+ ds >> queryId >> objectId >> expr;
+
+ QObject *object = QmlDebugService::objectForId(objectId);
+ QmlContext *context = qmlContext(object);
+ QVariant result;
+ if (object && context) {
+ QmlExpression *exprObj = new QmlExpression(context, expr, object);
+ bool undefined = false;
+ QVariant value = exprObj->value(&undefined);
+ if (undefined)
+ result = QLatin1String("<undefined>");
+ else
+ result = serializableVariant(value);
+ delete exprObj;
+ } else {
+ result = QLatin1String("<unknown context>");
+ }
+
+ QByteArray reply;
+ QDataStream rs(&reply, QIODevice::WriteOnly);
+ rs << QByteArray("EVAL_EXPRESSION_R") << queryId << result;
+
+ sendMessage(reply);
}
}
void QmlEngineDebugServer::propertyChanged(int id, int objectId, const QByteArray &property, const QVariant &value)
{
QByteArray reply;
- QVariant v;
+ QVariant v = serializableVariant(value);
QDataStream rs(&reply, QIODevice::WriteOnly);
-
- if (value.type() == QVariant::UserType || QmlMetaType::isObject(value.userType())) {
- QObject *o = QmlMetaType::toQObject(value);
- if (o) {
- QString objectName = o->objectName();
- if (objectName.isEmpty())
- objectName = QLatin1String("<unnamed>");
- v = QString::fromUtf8(o->metaObject()->className()) +
- QLatin1String(": ") + objectName;
- }
- if (v.isNull())
- v = value.toString();
- } else {
- v = value;
- }
rs << QByteArray("UPDATE_WATCH") << id << objectId << property << v;
diff --git a/src/declarative/qml/qmlenginedebug_p.h b/src/declarative/qml/qmlenginedebug_p.h
index e2f903c..075a711 100644
--- a/src/declarative/qml/qmlenginedebug_p.h
+++ b/src/declarative/qml/qmlenginedebug_p.h
@@ -85,6 +85,7 @@ public:
Type type;
QString name;
QVariant value;
+ QString valueTypeName;
QString binding;
bool hasNotifySignal;
};
@@ -103,6 +104,7 @@ private:
void buildObjectDump(QDataStream &, QObject *, bool);
QmlObjectData objectData(QObject *);
QmlObjectProperty propertyData(QObject *, int);
+ QVariant serializableVariant(const QVariant &value);
static QList<QmlEngine *> m_engines;
QmlWatcher *m_watch;
diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp
index cfa9469..d2bf4a8 100644
--- a/src/declarative/qml/qmlexpression.cpp
+++ b/src/declarative/qml/qmlexpression.cpp
@@ -281,7 +281,7 @@ void QmlExpressionPrivate::printException(QScriptEngine *scriptEngine)
}
}
-QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope)
+QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUndefined)
{
#ifdef Q_ENABLE_PERFORMANCE_LOG
QFxPerfTimer<QFxPerf::BindValueQt> perfqt;
@@ -318,6 +318,9 @@ QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope)
QScriptValue svalue = data->expressionFunction.call();
+ if (isUndefined)
+ *isUndefined = svalue.isUndefined();
+
if (scriptEngine->hasUncaughtException())
printException(scriptEngine);
@@ -355,7 +358,7 @@ QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope)
return rv;
}
-QVariant QmlExpressionPrivate::value(QObject *secondaryScope)
+QVariant QmlExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined)
{
Q_Q(QmlExpression);
@@ -382,7 +385,7 @@ QVariant QmlExpressionPrivate::value(QObject *secondaryScope)
if (data->sse.isValid()) {
rv = evalSSE();
} else {
- rv = evalQtScript(secondaryScope);
+ rv = evalQtScript(secondaryScope, isUndefined);
}
ep->currentExpression = lastCurrentExpression;
@@ -406,11 +409,14 @@ QVariant QmlExpressionPrivate::value(QObject *secondaryScope)
/*!
Returns the value of the expression, or an invalid QVariant if the
expression is invalid or has an error.
+
+ \a isUndefined is set to true if the expression resulted in an
+ undefined value.
*/
-QVariant QmlExpression::value()
+QVariant QmlExpression::value(bool *isUndefined)
{
Q_D(QmlExpression);
- return d->value();
+ return d->value(0, isUndefined);
}
/*!
diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h
index 73682f1..96694d6 100644
--- a/src/declarative/qml/qmlexpression.h
+++ b/src/declarative/qml/qmlexpression.h
@@ -83,7 +83,7 @@ public:
QObject *scopeObject() const;
public Q_SLOTS:
- QVariant value();
+ QVariant value(bool *isUndefined = 0);
Q_SIGNALS:
virtual void valueChanged();
diff --git a/src/declarative/qml/qmlexpression_p.h b/src/declarative/qml/qmlexpression_p.h
index d9bb27b..3ec8d1c 100644
--- a/src/declarative/qml/qmlexpression_p.h
+++ b/src/declarative/qml/qmlexpression_p.h
@@ -140,9 +140,9 @@ public:
QmlExpressionData *data;
- QVariant value(QObject *secondaryScope = 0);
+ QVariant value(QObject *secondaryScope = 0, bool *isUndefined = 0);
QVariant evalSSE();
- QVariant evalQtScript(QObject *secondaryScope);
+ QVariant evalQtScript(QObject *secondaryScope, bool *isUndefined = 0);
void updateGuards(const QPODVector<QmlEnginePrivate::CapturedProperty> &properties);
void clearGuards();
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index 5265d42..dc18b05 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -119,6 +119,7 @@ public:
StoreSignal, /* storeSignal */
StoreScript, /* storeScript */
+ StoreScriptString, /* storeScriptString */
//
// Unresolved single assignment
@@ -245,6 +246,11 @@ public:
int value;
} storeString;
struct {
+ int propertyIndex;
+ int value;
+ int scope;
+ } storeScriptString;
+ struct {
int value;
int fileName;
int lineNumber;
diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp
index bae263a..f9e3c50 100644
--- a/src/declarative/qml/qmlparser.cpp
+++ b/src/declarative/qml/qmlparser.cpp
@@ -80,6 +80,9 @@ QmlParser::Object::~Object()
prop->release();
foreach(Property *prop, valueTypeProperties)
prop->release();
+ typedef QPair<Property *, int> PropPair;
+ foreach(const PropPair &prop, scriptStringProperties)
+ prop.first->release();
foreach(const DynamicProperty &prop, dynamicProperties)
if (prop.defaultValue) prop.defaultValue->release();
foreach(Object *obj, scriptBlockObjects)
@@ -142,6 +145,13 @@ void QmlParser::Object::addValueTypeProperty(Property *p)
valueTypeProperties << p;
}
+void QmlParser::Object::addScriptStringProperty(Property *p, int stack)
+{
+ p->addref();
+ scriptStringProperties << qMakePair(p, stack);
+}
+
+
Property *QmlParser::Object::getProperty(const QByteArray &name, bool create)
{
if (!properties.contains(name)) {
diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h
index 88d7d77..f0867ea 100644
--- a/src/declarative/qml/qmlparser_p.h
+++ b/src/declarative/qml/qmlparser_p.h
@@ -160,11 +160,13 @@ namespace QmlParser
void addAttachedProperty(Property *);
void addGroupedProperty(Property *);
void addValueTypeProperty(Property *);
+ void addScriptStringProperty(Property *, int = 0);
QList<Property *> valueProperties;
QList<Property *> signalProperties;
QList<Property *> attachedProperties;
QList<Property *> groupedProperties;
QList<Property *> valueTypeProperties;
+ QList<QPair<Property *, int> > scriptStringProperties;
// Script blocks that were nested under this object
QStringList scriptBlocks;
diff --git a/src/declarative/qml/qmlscriptstring.cpp b/src/declarative/qml/qmlscriptstring.cpp
new file mode 100644
index 0000000..8a6afcc
--- /dev/null
+++ b/src/declarative/qml/qmlscriptstring.cpp
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** 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 "qmlscriptstring.h"
+
+QT_BEGIN_NAMESPACE
+
+class QmlScriptStringPrivate : public QSharedData
+{
+public:
+ QmlScriptStringPrivate() : context(0), scope(0) {}
+
+ QmlContext *context;
+ QObject *scope;
+ QString script;
+};
+
+/*!
+\class QmlScriptString
+\brief The QmlScriptString class encapsulates a script and its context.
+
+The QmlScriptString is used by properties that want to accept a script "assignment" from QML.
+
+Normally, the following code would result in a binding being established for the \c script
+property. If the property had a type of QmlScriptString, the script - \e {print(1921)} - itself
+would be passed to the property and it could choose how to handle it.
+
+\code
+MyType {
+ script: print(1921)
+}
+\endcode
+*/
+
+/*!
+Construct an empty instance.
+*/
+QmlScriptString::QmlScriptString()
+: d(new QmlScriptStringPrivate)
+{
+}
+
+/*!
+Copy \a other.
+*/
+QmlScriptString::QmlScriptString(const QmlScriptString &other)
+: d(other.d)
+{
+}
+
+/*!
+\internal
+*/
+QmlScriptString::~QmlScriptString()
+{
+}
+
+/*!
+Assign \a other to this.
+*/
+QmlScriptString &QmlScriptString::operator=(const QmlScriptString &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+Return the context for the script.
+*/
+QmlContext *QmlScriptString::context() const
+{
+ return d->context;
+}
+
+/*!
+Sets the \a context for the script.
+*/
+void QmlScriptString::setContext(QmlContext *context)
+{
+ d->context = context;
+}
+
+/*!
+Returns the scope object for the script.
+*/
+QObject *QmlScriptString::scopeObject() const
+{
+ return d->scope;
+}
+
+/*!
+Sets the scope \a object for the script.
+*/
+void QmlScriptString::setScopeObject(QObject *object)
+{
+ d->scope = object;
+}
+
+/*!
+Returns the script text.
+*/
+QString QmlScriptString::script() const
+{
+ return d->script;
+}
+
+/*!
+Sets the \a script text.
+*/
+void QmlScriptString::setScript(const QString &script)
+{
+ d->script = script;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/declarative/qml/qmlscriptstring.h b/src/declarative/qml/qmlscriptstring.h
new file mode 100644
index 0000000..c6067ce
--- /dev/null
+++ b/src/declarative/qml/qmlscriptstring.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 QMLSCRIPTSTRING_H
+#define QMLSCRIPTSTRING_H
+
+#include <QtCore/qstring.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qmetatype.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QObject;
+class QmlContext;
+class QmlScriptStringPrivate;
+class Q_DECLARATIVE_EXPORT QmlScriptString
+{
+public:
+ QmlScriptString();
+ QmlScriptString(const QmlScriptString &);
+ ~QmlScriptString();
+
+ QmlScriptString &operator=(const QmlScriptString &);
+
+ QmlContext *context() const;
+ void setContext(QmlContext *);
+
+ QObject *scopeObject() const;
+ void setScopeObject(QObject *);
+
+ QString script() const;
+ void setScript(const QString &);
+
+private:
+ QSharedDataPointer<QmlScriptStringPrivate> d;
+};
+
+Q_DECLARE_METATYPE(QmlScriptString);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMLSCRIPTSTRING_H
+
diff --git a/src/declarative/qml/qmlsqldatabase.cpp b/src/declarative/qml/qmlsqldatabase.cpp
index 4a5983d..9e39ffc 100644
--- a/src/declarative/qml/qmlsqldatabase.cpp
+++ b/src/declarative/qml/qmlsqldatabase.cpp
@@ -340,7 +340,7 @@ static QScriptValue qmlsqldatabase_open(QScriptContext *context, QScriptEngine *
QString basename = QmlEnginePrivate::get(engine)->offlineStoragePath + QLatin1String("/Databases/");
QDir().mkpath(basename);
basename += dbid;
- database.setDatabaseName(basename+QLatin1String(".sqllite"));
+ database.setDatabaseName(basename+QLatin1String(".sqlite"));
QSettings ini(basename+QLatin1String(".ini"),QSettings::IniFormat);
ini.setValue(QLatin1String("Name"), dbname);
ini.setValue(QLatin1String("Version"), dbversion);
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index 1f3903d..7f673a2 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -67,6 +67,7 @@
#include <private/qmlbinding_p.h>
#include <private/qmlcontext_p.h>
#include <private/qmlbindingoptimizations_p.h>
+#include <QtDeclarative/qmlscriptstring.h>
QT_BEGIN_NAMESPACE
@@ -552,6 +553,21 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt,
}
break;
+ case QmlInstruction::StoreScriptString:
+ {
+ QObject *target = stack.top();
+ QObject *scope = stack.at(stack.count() - 1 - instr.storeScriptString.scope);
+ QmlScriptString ss;
+ ss.setContext(ctxt);
+ ss.setScopeObject(scope);
+ ss.setScript(primitives.at(instr.storeScriptString.value));
+
+ void *a[] = { &ss, 0, &status, &flags };
+ QMetaObject::metacall(target, QMetaObject::WriteProperty,
+ instr.storeScriptString.propertyIndex, a);
+ }
+ break;
+
case QmlInstruction::BeginObject:
{
QObject *target = stack.top();
diff --git a/src/declarative/qml/qmlvmemetaobject.cpp b/src/declarative/qml/qmlvmemetaobject.cpp
index e5acc51..62a2a6b 100644
--- a/src/declarative/qml/qmlvmemetaobject.cpp
+++ b/src/declarative/qml/qmlvmemetaobject.cpp
@@ -55,7 +55,7 @@ QmlVMEMetaObject::QmlVMEMetaObject(QObject *obj,
const QMetaObject *other,
const QmlVMEMetaData *meta,
QmlRefCount *rc)
-: object(obj), ref(rc), metaData(meta), parent(0)
+: object(obj), ref(rc), ctxt(qmlContext(obj)), metaData(meta), parent(0)
{
if (ref)
ref->addref();
@@ -251,7 +251,6 @@ int QmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
(const QChar *)(((const char*)metaData) + data->bodyOffset);
QString code = QString::fromRawData(body, data->bodyLength);
- QmlContext *ctxt = qmlContext(object);
if (0 == (metaData->methodData() + id)->parameterCount) {
QmlExpression expr(ctxt, code, object);
diff --git a/src/declarative/qml/qmlvmemetaobject_p.h b/src/declarative/qml/qmlvmemetaobject_p.h
index d376f4c..de46853 100644
--- a/src/declarative/qml/qmlvmemetaobject_p.h
+++ b/src/declarative/qml/qmlvmemetaobject_p.h
@@ -112,6 +112,7 @@ protected:
private:
QObject *object;
QmlRefCount *ref;
+ QGuard<QmlContext> ctxt;
const QmlVMEMetaData *metaData;
int propOffset;
diff --git a/src/declarative/util/qmlanimation_p.h b/src/declarative/util/qmlanimation_p.h
index 4f6edb7..22c4e2d 100644
--- a/src/declarative/util/qmlanimation_p.h
+++ b/src/declarative/util/qmlanimation_p.h
@@ -92,6 +92,7 @@ private:
//performs an action of type QAbstractAnimationAction
class QActionAnimation : public QAbstractAnimation
{
+ Q_OBJECT
public:
QActionAnimation(QObject *parent = 0) : QAbstractAnimation(parent), animAction(0), policy(KeepWhenStopped) {}
QActionAnimation(QAbstractAnimationAction *action, QObject *parent = 0)
@@ -126,6 +127,7 @@ private:
//animates QmlTimeLineValue (assumes start and end values will be reals or compatible)
class QmlTimeLineValueAnimator : public QVariantAnimation
{
+ Q_OBJECT
public:
QmlTimeLineValueAnimator(QObject *parent = 0) : QVariantAnimation(parent), animValue(0), fromSourced(0), policy(KeepWhenStopped) {}
void setAnimValue(QmlTimeLineValue *value, DeletionPolicy p)
diff --git a/src/declarative/util/qmlopenmetaobject.cpp b/src/declarative/util/qmlopenmetaobject.cpp
index 7305362..11648f6 100644
--- a/src/declarative/util/qmlopenmetaobject.cpp
+++ b/src/declarative/util/qmlopenmetaobject.cpp
@@ -136,6 +136,14 @@ QVariant QmlOpenMetaObject::value(const QByteArray &name) const
return d->data.at(*iter);
}
+QVariant &QmlOpenMetaObject::operator[](const QByteArray &name)
+{
+ QHash<QByteArray, int>::ConstIterator iter = d->names.find(name);
+ Q_ASSERT(iter != d->names.end());
+
+ return d->data[*iter];
+}
+
void QmlOpenMetaObject::setValue(const QByteArray &name, const QVariant &val)
{
QHash<QByteArray, int>::ConstIterator iter = d->names.find(name);
diff --git a/src/declarative/util/qmlopenmetaobject.h b/src/declarative/util/qmlopenmetaobject.h
index f65660d..be0490d 100644
--- a/src/declarative/util/qmlopenmetaobject.h
+++ b/src/declarative/util/qmlopenmetaobject.h
@@ -64,6 +64,7 @@ public:
void setValue(const QByteArray &, const QVariant &);
QVariant value(int) const;
void setValue(int, const QVariant &);
+ QVariant &operator[](const QByteArray &);
int count() const;
QByteArray name(int) const;
diff --git a/src/declarative/util/qmlpropertymap.cpp b/src/declarative/util/qmlpropertymap.cpp
new file mode 100644
index 0000000..a587af3
--- /dev/null
+++ b/src/declarative/util/qmlpropertymap.cpp
@@ -0,0 +1,273 @@
+/****************************************************************************
+**
+** 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 "qmlpropertymap.h"
+#include <qmlopenmetaobject.h>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+//QmlPropertyMapMetaObject lets us listen for changes coming from QML
+//so we can emit the changed signal.
+class QmlPropertyMapMetaObject : public QmlOpenMetaObject
+{
+public:
+ QmlPropertyMapMetaObject(QmlPropertyMap *obj, QmlPropertyMapPrivate *objPriv);
+
+protected:
+ virtual void propertyWrite(int index);
+
+private:
+ QmlPropertyMap *map;
+ QmlPropertyMapPrivate *priv;
+};
+
+class QmlPropertyMapPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QmlPropertyMap)
+public:
+ QmlPropertyMapMetaObject *mo;
+ QStringList keys;
+ void emitChanged(const QString &key);
+};
+
+void QmlPropertyMapPrivate::emitChanged(const QString &key)
+{
+ Q_Q(QmlPropertyMap);
+ emit q->valueChanged(key);
+}
+
+QmlPropertyMapMetaObject::QmlPropertyMapMetaObject(QmlPropertyMap *obj, QmlPropertyMapPrivate *objPriv) : QmlOpenMetaObject(obj)
+{
+ map = obj;
+ priv = objPriv;
+}
+
+void QmlPropertyMapMetaObject::propertyWrite(int index)
+{
+ priv->emitChanged(QString::fromUtf8(name(index)));
+}
+
+/*!
+ \class QmlPropertyMap
+ \brief The QmlPropertyMap class allows you to set key-value pairs that can be used in bindings.
+
+ QmlPropertyMap 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
+ QmlPropertyMap ownerData;
+ ownerData.insert("name", QVariant(QString("John Smith")));
+ ownerData.insert("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 valueChanged() signal.
+ However, note that valueChanged() is \b NOT emitted when changes are made by calling insert()
+ or clear() - it is only emitted when a value is updated from QML.
+
+ \note It is not possible to remove keys from the map; once a key has been added, you can only
+ modify or clear its associated value.
+*/
+
+/*!
+ Constructs a bindable map with parent object \a parent.
+*/
+QmlPropertyMap::QmlPropertyMap(QObject *parent)
+: QObject(*(new QmlPropertyMapPrivate), parent)
+{
+ Q_D(QmlPropertyMap);
+ d->mo = new QmlPropertyMapMetaObject(this, d);
+}
+
+/*!
+ Destroys the bindable map.
+*/
+QmlPropertyMap::~QmlPropertyMap()
+{
+}
+
+/*!
+ Clears the value (if any) associated with \a key.
+*/
+void QmlPropertyMap::clear(const QString &key)
+{
+ Q_D(QmlPropertyMap);
+ d->mo->setValue(key.toUtf8(), QVariant());
+}
+
+/*!
+ 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 QmlPropertyMap::value(const QString &key) const
+{
+ Q_D(const QmlPropertyMap);
+ return d->mo->value(key.toUtf8());
+}
+
+/*!
+ Sets the value associated with \a key to \a value.
+
+ If the key doesn't exist, it is automatically created.
+*/
+void QmlPropertyMap::insert(const QString &key, const QVariant &value)
+{
+ Q_D(QmlPropertyMap);
+ if (!d->keys.contains(key))
+ d->keys.append(key);
+ d->mo->setValue(key.toUtf8(), value);
+}
+
+/*!
+ 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 QmlPropertyMap::keys() const
+{
+ Q_D(const QmlPropertyMap);
+ return d->keys;
+}
+
+/*!
+ \overload
+
+ Same as size().
+*/
+int QmlPropertyMap::count() const
+{
+ Q_D(const QmlPropertyMap);
+ return d->keys.count();
+}
+
+/*!
+ Returns the number of keys in the map.
+
+ \sa isEmpty(), count()
+*/
+int QmlPropertyMap::size() const
+{
+ Q_D(const QmlPropertyMap);
+ return d->keys.size();
+}
+
+/*!
+ Returns true if the map contains no keys; otherwise returns
+ false.
+
+ \sa size()
+*/
+bool QmlPropertyMap::isEmpty() const
+{
+ Q_D(const QmlPropertyMap);
+ return d->keys.isEmpty();
+}
+
+/*!
+ Returns true if the map contains \a key.
+
+ \sa size()
+*/
+bool QmlPropertyMap::contains(const QString &key) const
+{
+ Q_D(const QmlPropertyMap);
+ return d->keys.contains(key);
+}
+
+/*!
+ Returns the value associated with the key \a key as a modifiable
+ reference.
+
+ If the map contains no item with key \a key, the function inserts
+ an invalid QVariant into the map with key \a key, and
+ returns a reference to it.
+
+ \sa insert(), value()
+*/
+QVariant &QmlPropertyMap::operator[](const QString &key)
+{
+ //### optimize
+ Q_D(QmlPropertyMap);
+ QByteArray utf8key = key.toUtf8();
+ if (!d->keys.contains(key)) {
+ d->keys.append(key);
+ d->mo->setValue(utf8key, QVariant()); //force creation -- needed below
+ }
+
+ return (*(d->mo))[utf8key];
+}
+
+/*!
+ \overload
+
+ Same as value().
+*/
+const QVariant QmlPropertyMap::operator[](const QString &key) const
+{
+ return value(key);
+}
+
+/*!
+ \fn void QmlPropertyMap::valueChanged(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.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/declarative/extra/qbindablemap.h b/src/declarative/util/qmlpropertymap.h
index aa1908e..24b4395 100644
--- a/src/declarative/extra/qbindablemap.h
+++ b/src/declarative/util/qmlpropertymap.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QBINDABLEMAP_H
-#define QBINDABLEMAP_H
+#ifndef QMLPROPERTYMAP_H
+#define QMLPROPERTYMAP_H
#include <QtDeclarative/qfxglobal.h>
#include <QtCore/QObject>
@@ -54,29 +54,34 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-class QBindableMapMetaObject;
-class Q_DECLARATIVE_EXPORT QBindableMap : public QObject
+class QmlPropertyMapPrivate;
+class Q_DECLARATIVE_EXPORT QmlPropertyMap : public QObject
{
Q_OBJECT
public:
- QBindableMap(QObject *parent = 0);
- virtual ~QBindableMap();
+ QmlPropertyMap(QObject *parent = 0);
+ virtual ~QmlPropertyMap();
QVariant value(const QString &key) const;
- void setValue(const QString &key, QVariant value);
- void clearValue(const QString &key);
+ void insert(const QString &key, const QVariant &value);
+ void clear(const QString &key);
Q_INVOKABLE QStringList keys() const;
+ int count() const;
+ int size() const;
+ bool isEmpty() const;
+ bool contains(const QString &key) const;
+
+ QVariant &operator[](const QString &key);
+ const QVariant operator[](const QString &key) const;
+
Q_SIGNALS:
- void changed(const QString &key);
+ void valueChanged(const QString &key);
private:
- Q_DISABLE_COPY(QBindableMap)
- void emitChanged(const QString &key);
- QBindableMapMetaObject *m_mo;
- QStringList m_keys;
- friend class QBindableMapMetaObject;
+ Q_DECLARE_PRIVATE(QmlPropertyMap)
+ Q_DISABLE_COPY(QmlPropertyMap)
};
QT_END_NAMESPACE
diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri
index ec9967c..01ad898 100644
--- a/src/declarative/util/util.pri
+++ b/src/declarative/util/util.pri
@@ -19,7 +19,8 @@ SOURCES += \
util/qmlopenmetaobject.cpp \
util/qmltimeline.cpp \
util/qmltimer.cpp \
- util/qmlbind.cpp
+ util/qmlbind.cpp \
+ util/qmlpropertymap.cpp
HEADERS += \
util/qmlview.h \
@@ -46,4 +47,5 @@ HEADERS += \
util/qmlnullablevalue_p.h \
util/qmltimeline_p.h \
util/qmltimer.h \
- util/qmlbind.h
+ util/qmlbind.h \
+ util/qmlpropertymap.h