summaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/debugger/debugger.pri8
-rw-r--r--src/declarative/debugger/qdeclarativedebugclient.cpp36
-rw-r--r--src/declarative/debugger/qdeclarativedebugserver.cpp361
-rw-r--r--src/declarative/debugger/qdeclarativedebugserver_p.h88
-rw-r--r--src/declarative/debugger/qdeclarativedebugserverconnection_p.h73
-rw-r--r--src/declarative/debugger/qdeclarativedebugservice.cpp319
-rw-r--r--src/declarative/debugger/qdeclarativedebugservice_p_p.h71
-rw-r--r--src/declarative/debugger/qdeclarativedebugtrace.cpp106
-rw-r--r--src/declarative/debugger/qdeclarativedebugtrace_p.h43
-rw-r--r--src/declarative/debugger/qpacketprotocol.cpp8
-rw-r--r--src/declarative/debugger/qpacketprotocol_p.h5
-rw-r--r--src/declarative/graphicsitems/graphicsitems.pri7
-rw-r--r--src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp12
-rw-r--r--src/declarative/graphicsitems/qdeclarativeborderimage.cpp47
-rw-r--r--src/declarative/graphicsitems/qdeclarativeborderimage_p.h4
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp54
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable_p.h4
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp2
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimage.cpp112
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimagebase.cpp45
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimagebase_p.h10
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h6
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem.cpp46
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp8
-rw-r--r--src/declarative/graphicsitems/qdeclarativepincharea.cpp579
-rw-r--r--src/declarative/graphicsitems/qdeclarativepincharea_p.h308
-rw-r--r--src/declarative/graphicsitems/qdeclarativepincharea_p_p.h109
-rw-r--r--src/declarative/graphicsitems/qdeclarativerepeater.cpp123
-rw-r--r--src/declarative/graphicsitems/qdeclarativerepeater_p.h6
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext.cpp11
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext_p.h3
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit.cpp14
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit_p.h4
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput.cpp19
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp5
-rw-r--r--src/declarative/qml/qdeclarative.h77
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp35
-rw-r--r--src/declarative/qml/qdeclarativebinding_p.h4
-rw-r--r--src/declarative/qml/qdeclarativeboundsignal.cpp4
-rw-r--r--src/declarative/qml/qdeclarativecompiledbindings.cpp7
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp87
-rw-r--r--src/declarative/qml/qdeclarativecompiler_p.h1
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp4
-rw-r--r--src/declarative/qml/qdeclarativecontext_p.h1
-rw-r--r--src/declarative/qml/qdeclarativecustomparser.cpp9
-rw-r--r--src/declarative/qml/qdeclarativecustomparser_p.h3
-rw-r--r--src/declarative/qml/qdeclarativedata_p.h5
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp5
-rw-r--r--src/declarative/qml/qdeclarativeenginedebug.cpp152
-rw-r--r--src/declarative/qml/qdeclarativeenginedebug_p.h6
-rw-r--r--src/declarative/qml/qdeclarativeinstruction_p.h1
-rw-r--r--src/declarative/qml/qdeclarativemetatype.cpp84
-rw-r--r--src/declarative/qml/qdeclarativemetatype_p.h5
-rw-r--r--src/declarative/qml/qdeclarativeobjectscriptclass.cpp14
-rw-r--r--src/declarative/qml/qdeclarativeprivate.h2
-rw-r--r--src/declarative/qml/qdeclarativeproperty.cpp100
-rw-r--r--src/declarative/qml/qdeclarativeproperty_p.h13
-rw-r--r--src/declarative/qml/qdeclarativepropertycache.cpp3
-rw-r--r--src/declarative/qml/qdeclarativepropertycache_p.h4
-rw-r--r--src/declarative/qml/qdeclarativerewrite.cpp62
-rw-r--r--src/declarative/qml/qdeclarativerewrite_p.h4
-rw-r--r--src/declarative/qml/qdeclarativescriptparser.cpp1
-rw-r--r--src/declarative/qml/qdeclarativesqldatabase.cpp2
-rw-r--r--src/declarative/qml/qdeclarativestringconverters.cpp6
-rw-r--r--src/declarative/qml/qdeclarativetypeloader.cpp4
-rw-r--r--src/declarative/qml/qdeclarativetypenamescriptclass.cpp5
-rw-r--r--src/declarative/qml/qdeclarativevaluetype.cpp1
-rw-r--r--src/declarative/qml/qdeclarativevme.cpp4
-rw-r--r--src/declarative/qml/qmetaobjectbuilder.cpp33
-rw-r--r--src/declarative/qml/qmetaobjectbuilder_p.h2
-rw-r--r--src/declarative/qml/qml.pri9
-rw-r--r--src/declarative/qml/qperformancetimer.cpp226
-rw-r--r--src/declarative/qml/qperformancetimer_p.h79
-rw-r--r--src/declarative/util/qdeclarativeconnections.cpp7
-rw-r--r--src/declarative/util/qdeclarativelistmodel.cpp2
-rw-r--r--src/declarative/util/qdeclarativeopenmetaobject.cpp1
-rw-r--r--src/declarative/util/qdeclarativepixmapcache.cpp22
-rw-r--r--src/declarative/util/qdeclarativepixmapcache_p.h12
-rw-r--r--src/declarative/util/qdeclarativepropertychanges.cpp135
-rw-r--r--src/declarative/util/qdeclarativepropertychanges_p.h18
-rw-r--r--src/declarative/util/qdeclarativestate.cpp26
-rw-r--r--src/declarative/util/qdeclarativestate_p.h12
-rw-r--r--src/declarative/util/qdeclarativestateoperations.cpp116
-rw-r--r--src/declarative/util/qdeclarativeview.cpp24
-rw-r--r--src/declarative/util/qdeclarativexmllistmodel.cpp2
87 files changed, 3318 insertions, 781 deletions
diff --git a/src/declarative/debugger/debugger.pri b/src/declarative/debugger/debugger.pri
index 25f7687..75287b4 100644
--- a/src/declarative/debugger/debugger.pri
+++ b/src/declarative/debugger/debugger.pri
@@ -7,13 +7,17 @@ SOURCES += \
$$PWD/qdeclarativedebugclient.cpp \
$$PWD/qdeclarativedebug.cpp \
$$PWD/qdeclarativedebugtrace.cpp \
- $$PWD/qdeclarativedebughelper.cpp
+ $$PWD/qdeclarativedebughelper.cpp \
+ $$PWD/qdeclarativedebugserver.cpp
HEADERS += \
$$PWD/qdeclarativedebuggerstatus_p.h \
$$PWD/qpacketprotocol_p.h \
$$PWD/qdeclarativedebugservice_p.h \
+ $$PWD/qdeclarativedebugservice_p_p.h \
$$PWD/qdeclarativedebugclient_p.h \
$$PWD/qdeclarativedebug_p.h \
$$PWD/qdeclarativedebugtrace_p.h \
- $$PWD/qdeclarativedebughelper_p.h
+ $$PWD/qdeclarativedebughelper_p.h \
+ $$PWD/qdeclarativedebugserver_p.h \
+ debugger/qdeclarativedebugserverconnection_p.h
diff --git a/src/declarative/debugger/qdeclarativedebugclient.cpp b/src/declarative/debugger/qdeclarativedebugclient.cpp
index f5c5751..204ca4f 100644
--- a/src/declarative/debugger/qdeclarativedebugclient.cpp
+++ b/src/declarative/debugger/qdeclarativedebugclient.cpp
@@ -61,7 +61,7 @@ public:
QDeclarativeDebugClientPrivate();
QString name;
- QDeclarativeDebugConnection *client;
+ QDeclarativeDebugConnection *connection;
};
class QDeclarativeDebugConnectionPrivate : public QObject
@@ -202,7 +202,7 @@ QDeclarativeDebugConnection::~QDeclarativeDebugConnection()
{
QHash<QString, QDeclarativeDebugClient*>::iterator iter = d->plugins.begin();
for (; iter != d->plugins.end(); ++iter) {
- iter.value()->d_func()->client = 0;
+ iter.value()->d_func()->connection = 0;
iter.value()->statusChanged(QDeclarativeDebugClient::NotConnected);
}
}
@@ -213,7 +213,7 @@ bool QDeclarativeDebugConnection::isConnected() const
}
QDeclarativeDebugClientPrivate::QDeclarativeDebugClientPrivate()
-: client(0)
+: connection(0)
{
}
@@ -223,26 +223,26 @@ QDeclarativeDebugClient::QDeclarativeDebugClient(const QString &name,
{
Q_D(QDeclarativeDebugClient);
d->name = name;
- d->client = parent;
+ d->connection = parent;
- if (!d->client)
+ if (!d->connection)
return;
- if (d->client->d->plugins.contains(name)) {
+ if (d->connection->d->plugins.contains(name)) {
qWarning() << "QDeclarativeDebugClient: Conflicting plugin name" << name;
- d->client = 0;
+ d->connection = 0;
} else {
- d->client->d->plugins.insert(name, this);
- d->client->d->advertisePlugins();
+ d->connection->d->plugins.insert(name, this);
+ d->connection->d->advertisePlugins();
}
}
QDeclarativeDebugClient::~QDeclarativeDebugClient()
{
Q_D(const QDeclarativeDebugClient);
- if (d->client && d->client->d) {
- d->client->d->plugins.remove(d->name);
- d->client->d->advertisePlugins();
+ if (d->connection && d->connection->d) {
+ d->connection->d->plugins.remove(d->name);
+ d->connection->d->advertisePlugins();
}
}
@@ -255,12 +255,12 @@ QString QDeclarativeDebugClient::name() const
QDeclarativeDebugClient::Status QDeclarativeDebugClient::status() const
{
Q_D(const QDeclarativeDebugClient);
- if (!d->client
- || !d->client->isConnected()
- || !d->client->d->gotHello)
+ if (!d->connection
+ || !d->connection->isConnected()
+ || !d->connection->d->gotHello)
return NotConnected;
- if (d->client->d->serverPlugins.contains(d->name))
+ if (d->connection->d->serverPlugins.contains(d->name))
return Enabled;
return Unavailable;
@@ -275,8 +275,8 @@ void QDeclarativeDebugClient::sendMessage(const QByteArray &message)
QPacket pack;
pack << d->name << message;
- d->client->d->protocol->send(pack);
- d->client->d->q->flush();
+ d->connection->d->protocol->send(pack);
+ d->connection->d->q->flush();
}
void QDeclarativeDebugClient::statusChanged(Status)
diff --git a/src/declarative/debugger/qdeclarativedebugserver.cpp b/src/declarative/debugger/qdeclarativedebugserver.cpp
new file mode 100644
index 0000000..a269984
--- /dev/null
+++ b/src/declarative/debugger/qdeclarativedebugserver.cpp
@@ -0,0 +1,361 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "private/qdeclarativedebugserver_p.h"
+#include "private/qdeclarativedebugservice_p.h"
+#include "private/qdeclarativedebugservice_p_p.h"
+#include "private/qdeclarativeengine_p.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QPluginLoader>
+#include <QtCore/QStringList>
+
+#include <private/qobject_p.h>
+#include <private/qapplication_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*
+ QDeclarativeDebug Protocol (Version 1):
+
+ handshake:
+ 1. Client sends
+ "QDeclarativeDebugServer" 0 version pluginNames
+ version: an int representing the highest protocol version the client knows
+ pluginNames: plugins available on client side
+ 2. Server sends
+ "QDeclarativeDebugClient" 0 version pluginNames
+ version: an int representing the highest protocol version the client & server know
+ pluginNames: plugins available on server side. plugins both in the client and server message are enabled.
+ client plugin advertisement
+ 1. Client sends
+ "QDeclarativeDebugServer" 1 pluginNames
+ server plugin advertisement
+ 1. Server sends
+ "QDeclarativeDebugClient" 1 pluginNames
+ plugin communication:
+ Everything send with a header different to "QDeclarativeDebugServer" is sent to the appropriate plugin.
+ */
+
+const int protocolVersion = 1;
+
+
+class QDeclarativeDebugServerPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QDeclarativeDebugServer)
+public:
+ QDeclarativeDebugServerPrivate();
+
+ void advertisePlugins();
+
+ QDeclarativeDebugServerConnection *connection;
+ QHash<QString, QDeclarativeDebugService *> plugins;
+ QStringList clientPlugins;
+ bool gotHello;
+
+ static QDeclarativeDebugServerConnection *loadConnectionPlugin();
+};
+
+QDeclarativeDebugServerPrivate::QDeclarativeDebugServerPrivate() :
+ connection(0),
+ gotHello(false)
+{
+}
+
+void QDeclarativeDebugServerPrivate::advertisePlugins()
+{
+ if (!gotHello)
+ return;
+
+ QByteArray message;
+ {
+ QDataStream out(&message, QIODevice::WriteOnly);
+ out << QString(QLatin1String("QDeclarativeDebugClient")) << 1 << plugins.keys();
+ }
+ connection->send(message);
+}
+
+QDeclarativeDebugServerConnection *QDeclarativeDebugServerPrivate::loadConnectionPlugin()
+{
+ QStringList pluginCandidates;
+ const QStringList paths = QCoreApplication::libraryPaths();
+ foreach (const QString &libPath, paths) {
+ const QDir dir(libPath + QLatin1String("/qmldebugging"));
+ if (dir.exists()) {
+ QStringList plugins(dir.entryList(QDir::Files));
+ foreach (const QString &pluginPath, plugins) {
+ pluginCandidates << dir.absoluteFilePath(pluginPath);
+ }
+ }
+ }
+
+ foreach (const QString &pluginPath, pluginCandidates) {
+ QPluginLoader loader(pluginPath);
+ if (!loader.load()) {
+ continue;
+ }
+ QDeclarativeDebugServerConnection *connection = 0;
+ if (QObject *instance = loader.instance())
+ connection = qobject_cast<QDeclarativeDebugServerConnection*>(instance);
+
+ if (connection)
+ return connection;
+ loader.unload();
+ }
+ return 0;
+}
+
+bool QDeclarativeDebugServer::hasDebuggingClient() const
+{
+ Q_D(const QDeclarativeDebugServer);
+ return d->connection
+ && d->connection->isConnected()
+ && d->gotHello;
+}
+
+QDeclarativeDebugServer *QDeclarativeDebugServer::instance()
+{
+ static bool commandLineTested = false;
+ static QDeclarativeDebugServer *server = 0;
+
+ if (!commandLineTested) {
+ commandLineTested = true;
+
+#ifndef QDECLARATIVE_NO_DEBUG_PROTOCOL
+ QApplicationPrivate *appD = static_cast<QApplicationPrivate*>(QObjectPrivate::get(qApp));
+ // ### remove port definition when protocol is changed
+ int port = 0;
+ bool block = false;
+ bool ok = false;
+
+ // format: qmljsdebugger=port:3768[,block]
+ if (!appD->qmljsDebugArgumentsString().isEmpty()) {
+ if (!QDeclarativeEnginePrivate::qml_debugging_enabled) {
+ const QString message =
+ QString::fromAscii("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". "
+ "Debugging has not been enabled.").arg(
+ appD->qmljsDebugArgumentsString());
+ qWarning("%s", qPrintable(message));
+ return 0;
+ }
+
+ if (appD->qmljsDebugArgumentsString().indexOf(QLatin1String("port:")) == 0) {
+ int separatorIndex = appD->qmljsDebugArgumentsString().indexOf(QLatin1Char(','));
+ port = appD->qmljsDebugArgumentsString().mid(5, separatorIndex - 5).toInt(&ok);
+ }
+ block = appD->qmljsDebugArgumentsString().contains(QLatin1String("block"));
+
+ if (ok) {
+ server = new QDeclarativeDebugServer();
+
+ QDeclarativeDebugServerConnection *connection
+ = QDeclarativeDebugServerPrivate::loadConnectionPlugin();
+ if (connection) {
+ server->d_func()->connection = connection;
+
+ connection->setServer(server);
+ connection->setPort(port, block);
+ } else {
+ qWarning() << QString::fromAscii("QDeclarativeDebugServer: Ignoring\"-qmljsdebugger=%1\". "
+ "Remote debugger plugin has not been found.").arg(appD->qmljsDebugArgumentsString());
+ }
+
+ } else {
+ qWarning(QString::fromAscii("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". "
+ "Format is -qmljsdebugger=port:<port>[,block]").arg(
+ appD->qmljsDebugArgumentsString()).toAscii().constData());
+ }
+ }
+#endif
+ }
+
+ return server;
+}
+
+QDeclarativeDebugServer::QDeclarativeDebugServer()
+: QObject(*(new QDeclarativeDebugServerPrivate))
+{
+}
+
+void QDeclarativeDebugServer::receiveMessage(const QByteArray &message)
+{
+ Q_D(QDeclarativeDebugServer);
+
+ QDataStream in(message);
+ if (!d->gotHello) {
+
+ QString name;
+ int op;
+ in >> name >> op;
+
+ if (name != QLatin1String("QDeclarativeDebugServer")
+ || op != 0) {
+ qWarning("QDeclarativeDebugServer: Invalid hello message");
+ d->connection->disconnect();
+ return;
+ }
+
+ int version;
+ in >> version >> d->clientPlugins;
+
+ QHash<QString, QDeclarativeDebugService*>::Iterator iter = d->plugins.begin();
+ for (; iter != d->plugins.end(); ++iter) {
+ QDeclarativeDebugService::Status newStatus = QDeclarativeDebugService::Unavailable;
+ if (d->clientPlugins.contains(iter.key()))
+ newStatus = QDeclarativeDebugService::Enabled;
+ iter.value()->d_func()->status = newStatus;
+ iter.value()->statusChanged(newStatus);
+ }
+
+ QByteArray helloAnswer;
+ {
+ QDataStream out(&helloAnswer, QIODevice::WriteOnly);
+ out << QString(QLatin1String("QDeclarativeDebugClient")) << 0 << protocolVersion << d->plugins.keys();
+ }
+ d->connection->send(helloAnswer);
+
+ d->gotHello = true;
+ qWarning("QDeclarativeDebugServer: Connection established");
+ } else {
+
+ QString debugServer(QLatin1String("QDeclarativeDebugServer"));
+
+ QString name;
+ in >> name;
+
+ if (name == debugServer) {
+ int op = -1;
+ in >> op;
+
+ if (op == 1) {
+ // Service Discovery
+ QStringList oldClientPlugins = d->clientPlugins;
+ in >> d->clientPlugins;
+
+ QHash<QString, QDeclarativeDebugService*>::Iterator iter = d->plugins.begin();
+ for (; iter != d->plugins.end(); ++iter) {
+ const QString pluginName = iter.key();
+ QDeclarativeDebugService::Status newStatus = QDeclarativeDebugService::Unavailable;
+ if (d->clientPlugins.contains(pluginName))
+ newStatus = QDeclarativeDebugService::Enabled;
+
+ if (oldClientPlugins.contains(pluginName)
+ != d->clientPlugins.contains(pluginName)) {
+ iter.value()->d_func()->status = newStatus;
+ iter.value()->statusChanged(newStatus);
+ }
+ }
+ } else {
+ qWarning("QDeclarativeDebugServer: Invalid control message %d", op);
+ }
+ } else {
+ QByteArray message;
+ in >> message;
+
+ QHash<QString, QDeclarativeDebugService *>::Iterator iter =
+ d->plugins.find(name);
+ if (iter == d->plugins.end()) {
+ qWarning() << "QDeclarativeDebugServer: Message received for missing plugin" << name;
+ } else {
+ (*iter)->messageReceived(message);
+ }
+ }
+ }
+}
+
+QList<QDeclarativeDebugService*> QDeclarativeDebugServer::services() const
+{
+ const Q_D(QDeclarativeDebugServer);
+ return d->plugins.values();
+}
+
+QStringList QDeclarativeDebugServer::serviceNames() const
+{
+ const Q_D(QDeclarativeDebugServer);
+ return d->plugins.keys();
+}
+
+bool QDeclarativeDebugServer::addService(QDeclarativeDebugService *service)
+{
+ Q_D(QDeclarativeDebugServer);
+ if (!service || d->plugins.contains(service->name()))
+ return false;
+
+ d->plugins.insert(service->name(), service);
+ d->advertisePlugins();
+
+ QDeclarativeDebugService::Status newStatus = QDeclarativeDebugService::Unavailable;
+ if (d->clientPlugins.contains(service->name()))
+ newStatus = QDeclarativeDebugService::Enabled;
+ service->d_func()->status = newStatus;
+ service->statusChanged(newStatus);
+ return true;
+}
+
+bool QDeclarativeDebugServer::removeService(QDeclarativeDebugService *service)
+{
+ Q_D(QDeclarativeDebugServer);
+ if (!service || !d->plugins.contains(service->name()))
+ return false;
+
+ d->plugins.remove(service->name());
+ d->advertisePlugins();
+
+ QDeclarativeDebugService::Status newStatus = QDeclarativeDebugService::NotConnected;
+ service->d_func()->server = 0;
+ service->d_func()->status = newStatus;
+ service->statusChanged(newStatus);
+ return true;
+}
+
+void QDeclarativeDebugServer::sendMessage(QDeclarativeDebugService *service,
+ const QByteArray &message)
+{
+ Q_D(QDeclarativeDebugServer);
+ QByteArray msg;
+ {
+ QDataStream out(&msg, QIODevice::WriteOnly);
+ out << service->name() << message;
+ }
+ d->connection->send(msg);
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/debugger/qdeclarativedebugserver_p.h b/src/declarative/debugger/qdeclarativedebugserver_p.h
new file mode 100644
index 0000000..ec3e60f
--- /dev/null
+++ b/src/declarative/debugger/qdeclarativedebugserver_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEDEBUGSERVER_H
+#define QDECLARATIVEDEBUGSERVER_H
+
+#include <private/qdeclarativeglobal_p.h>
+#include <private/qdeclarativedebugserverconnection_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeDebugService;
+
+class QDeclarativeDebugServerPrivate;
+class Q_DECLARATIVE_EXPORT QDeclarativeDebugServer : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QDeclarativeDebugServer)
+ Q_DISABLE_COPY(QDeclarativeDebugServer)
+public:
+ static QDeclarativeDebugServer *instance();
+
+ void setConnection(QDeclarativeDebugServerConnection *connection);
+
+ bool hasDebuggingClient() const;
+
+ QList<QDeclarativeDebugService*> services() const;
+ QStringList serviceNames() const;
+
+ bool addService(QDeclarativeDebugService *service);
+ bool removeService(QDeclarativeDebugService *service);
+
+ void sendMessage(QDeclarativeDebugService *service, const QByteArray &message);
+ void receiveMessage(const QByteArray &message);
+
+private:
+ friend class QDeclarativeDebugService;
+ friend class QDeclarativeDebugServicePrivate;
+ QDeclarativeDebugServer();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEDEBUGSERVICE_H
diff --git a/src/declarative/debugger/qdeclarativedebugserverconnection_p.h b/src/declarative/debugger/qdeclarativedebugserverconnection_p.h
new file mode 100644
index 0000000..631da74
--- /dev/null
+++ b/src/declarative/debugger/qdeclarativedebugserverconnection_p.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEDEBUGSERVERCONNECTION_H
+#define QDECLARATIVEDEBUGSERVERCONNECTION_H
+
+#include <QtDeclarative/private/qdeclarativeglobal_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeDebugServer;
+class Q_DECLARATIVE_EXPORT QDeclarativeDebugServerConnection
+{
+public:
+ QDeclarativeDebugServerConnection() {}
+ virtual ~QDeclarativeDebugServerConnection() {}
+
+ virtual void setServer(QDeclarativeDebugServer *server) = 0;
+ virtual void setPort(int port, bool bock) = 0;
+ virtual bool isConnected() const = 0;
+ virtual void send(const QByteArray &message) = 0;
+ virtual void disconnect() = 0;
+};
+
+Q_DECLARE_INTERFACE(QDeclarativeDebugServerConnection, "com.trolltech.Qt.QDeclarativeDebugServerConnection/1.0")
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEDEBUGSERVERCONNECTION_H
diff --git a/src/declarative/debugger/qdeclarativedebugservice.cpp b/src/declarative/debugger/qdeclarativedebugservice.cpp
index 849df73..9d321da 100644
--- a/src/declarative/debugger/qdeclarativedebugservice.cpp
+++ b/src/declarative/debugger/qdeclarativedebugservice.cpp
@@ -40,301 +40,14 @@
****************************************************************************/
#include "private/qdeclarativedebugservice_p.h"
+#include "private/qdeclarativedebugservice_p_p.h"
+#include "private/qdeclarativedebugserver_p.h"
-#include "private/qpacketprotocol_p.h"
-#include "private/qdeclarativeengine_p.h"
-
-#include <QtCore/qdebug.h>
-#include <QtNetwork/qtcpserver.h>
-#include <QtNetwork/qtcpsocket.h>
-#include <QtCore/qstringlist.h>
-
-#include <private/qobject_p.h>
-#include <private/qapplication_p.h>
-#include <QtGui/qapplication.h>
+#include <QtCore/QDebug>
+#include <QtCore/QStringList>
QT_BEGIN_NAMESPACE
-/*
- QDeclarativeDebug Protocol (Version 1):
-
- handshake:
- 1. Client sends
- "QDeclarativeDebugServer" 0 version pluginNames
- version: an int representing the highest protocol version the client knows
- pluginNames: plugins available on client side
- 2. Server sends
- "QDeclarativeDebugClient" 0 version pluginNames
- version: an int representing the highest protocol version the client & server know
- pluginNames: plugins available on server side. plugins both in the client and server message are enabled.
- client plugin advertisement
- 1. Client sends
- "QDeclarativeDebugServer" 1 pluginNames
- server plugin advertisement
- 1. Server sends
- "QDeclarativeDebugClient" 1 pluginNames
- plugin communication:
- Everything send with a header different to "QDeclarativeDebugServer" is sent to the appropriate plugin.
- */
-
-const int protocolVersion = 1;
-
-class QDeclarativeDebugServerPrivate;
-class QDeclarativeDebugServer : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QDeclarativeDebugServer)
- Q_DISABLE_COPY(QDeclarativeDebugServer)
-public:
- static QDeclarativeDebugServer *instance();
- void listen();
- void waitForConnection();
- bool hasDebuggingClient() const;
-
-private Q_SLOTS:
- void readyRead();
- void newConnection();
-
-private:
- friend class QDeclarativeDebugService;
- friend class QDeclarativeDebugServicePrivate;
- QDeclarativeDebugServer(int);
-};
-
-class QDeclarativeDebugServerPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QDeclarativeDebugServer)
-public:
- QDeclarativeDebugServerPrivate();
-
- void advertisePlugins();
-
- int port;
- QTcpSocket *connection;
- QPacketProtocol *protocol;
- QHash<QString, QDeclarativeDebugService *> plugins;
- QStringList clientPlugins;
- QTcpServer *tcpServer;
- bool gotHello;
-};
-
-class QDeclarativeDebugServicePrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QDeclarativeDebugService)
-public:
- QDeclarativeDebugServicePrivate();
-
- QString name;
- QDeclarativeDebugServer *server;
-};
-
-QDeclarativeDebugServerPrivate::QDeclarativeDebugServerPrivate()
-: connection(0), protocol(0), gotHello(false)
-{
-}
-
-void QDeclarativeDebugServerPrivate::advertisePlugins()
-{
- if (!connection
- || connection->state() != QTcpSocket::ConnectedState
- || !gotHello)
- return;
-
- QPacket pack;
- pack << QString(QLatin1String("QDeclarativeDebugClient")) << 1 << plugins.keys();
- protocol->send(pack);
- connection->flush();
-}
-
-void QDeclarativeDebugServer::listen()
-{
- Q_D(QDeclarativeDebugServer);
-
- d->tcpServer = new QTcpServer(this);
- QObject::connect(d->tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection()));
- if (d->tcpServer->listen(QHostAddress::Any, d->port))
- qWarning("QDeclarativeDebugServer: Waiting for connection on port %d...", d->port);
- else
- qWarning("QDeclarativeDebugServer: Unable to listen on port %d", d->port);
-}
-
-void QDeclarativeDebugServer::waitForConnection()
-{
- Q_D(QDeclarativeDebugServer);
- d->tcpServer->waitForNewConnection(-1);
-}
-
-void QDeclarativeDebugServer::newConnection()
-{
- Q_D(QDeclarativeDebugServer);
-
- if (d->connection) {
- qWarning("QDeclarativeDebugServer error: another client is already connected");
- QTcpSocket *faultyConnection = d->tcpServer->nextPendingConnection();
- delete faultyConnection;
- return;
- }
-
- d->connection = d->tcpServer->nextPendingConnection();
- d->connection->setParent(this);
- d->protocol = new QPacketProtocol(d->connection, this);
- QObject::connect(d->protocol, SIGNAL(readyRead()), this, SLOT(readyRead()));
-}
-
-bool QDeclarativeDebugServer::hasDebuggingClient() const
-{
- Q_D(const QDeclarativeDebugServer);
- return d->connection
- && (d->connection->state() == QTcpSocket::ConnectedState)
- && d->gotHello;
-}
-
-QDeclarativeDebugServer *QDeclarativeDebugServer::instance()
-{
- static bool commandLineTested = false;
- static QDeclarativeDebugServer *server = 0;
-
- if (!commandLineTested) {
- commandLineTested = true;
-
-#ifndef QDECLARATIVE_NO_DEBUG_PROTOCOL
- QApplicationPrivate *appD = static_cast<QApplicationPrivate*>(QObjectPrivate::get(qApp));
- // ### remove port definition when protocol is changed
- int port = 0;
- bool block = false;
- bool ok = false;
-
- // format: qmljsdebugger=port:3768[,block]
- if (!appD->qmljsDebugArgumentsString().isEmpty()) {
- if (!QDeclarativeEnginePrivate::qml_debugging_enabled) {
- qWarning() << QString::fromLatin1("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". "
- "Debugging has not been enabled.").arg(
- appD->qmljsDebugArgumentsString()).toAscii().constData();
- return 0;
- }
-
- if (appD->qmljsDebugArgumentsString().indexOf(QLatin1String("port:")) == 0) {
- int separatorIndex = appD->qmljsDebugArgumentsString().indexOf(QLatin1Char(','));
- port = appD->qmljsDebugArgumentsString().mid(5, separatorIndex - 5).toInt(&ok);
- }
- block = appD->qmljsDebugArgumentsString().contains(QLatin1String("block"));
-
- if (ok) {
- server = new QDeclarativeDebugServer(port);
- server->listen();
- if (block) {
- server->waitForConnection();
- }
- } else {
- const QString message =
- QString::fromAscii("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". "
- "Format is -qmljsdebugger=port:<port>[,block]").
- arg(appD->qmljsDebugArgumentsString());
- qWarning("%s", qPrintable(message));
- }
- }
-#endif
- }
-
- return server;
-}
-
-QDeclarativeDebugServer::QDeclarativeDebugServer(int port)
-: QObject(*(new QDeclarativeDebugServerPrivate))
-{
- Q_D(QDeclarativeDebugServer);
- d->port = port;
-}
-
-void QDeclarativeDebugServer::readyRead()
-{
- Q_D(QDeclarativeDebugServer);
-
- if (!d->gotHello) {
- QPacket hello = d->protocol->read();
-
- QString name;
- int op;
- hello >> name >> op;
-
- if (name != QLatin1String("QDeclarativeDebugServer")
- || op != 0) {
- qWarning("QDeclarativeDebugServer: Invalid hello message");
- QObject::disconnect(d->protocol, SIGNAL(readyRead()), this, SLOT(readyRead()));
- d->protocol->deleteLater();
- d->protocol = 0;
- d->connection->deleteLater();
- d->connection = 0;
- return;
- }
-
- int version;
- hello >> version >> d->clientPlugins;
-
- QHash<QString, QDeclarativeDebugService*>::Iterator iter = d->plugins.begin();
- for (; iter != d->plugins.end(); ++iter) {
- QDeclarativeDebugService::Status newStatus = QDeclarativeDebugService::Unavailable;
- if (d->clientPlugins.contains(iter.key()))
- newStatus = QDeclarativeDebugService::Enabled;
- iter.value()->statusChanged(newStatus);
- }
-
- QPacket helloAnswer;
- helloAnswer << QString(QLatin1String("QDeclarativeDebugClient")) << 0 << protocolVersion << d->plugins.keys();
- d->protocol->send(helloAnswer);
- d->connection->flush();
-
- d->gotHello = true;
- qWarning("QDeclarativeDebugServer: Connection established");
- }
-
- QString debugServer(QLatin1String("QDeclarativeDebugServer"));
-
- while (d->protocol->packetsAvailable()) {
- QPacket pack = d->protocol->read();
-
- QString name;
- pack >> name;
-
- if (name == debugServer) {
- int op = -1;
- pack >> op;
-
- if (op == 1) {
- // Service Discovery
- QStringList oldClientPlugins = d->clientPlugins;
- pack >> d->clientPlugins;
-
- QHash<QString, QDeclarativeDebugService*>::Iterator iter = d->plugins.begin();
- for (; iter != d->plugins.end(); ++iter) {
- const QString pluginName = iter.key();
- QDeclarativeDebugService::Status newStatus = QDeclarativeDebugService::Unavailable;
- if (d->clientPlugins.contains(pluginName))
- newStatus = QDeclarativeDebugService::Enabled;
-
- if (oldClientPlugins.contains(pluginName)
- != d->clientPlugins.contains(pluginName)) {
- iter.value()->statusChanged(newStatus);
- }
- }
- } else {
- qWarning("QDeclarativeDebugServer: Invalid control message %d", op);
- }
- } else {
- QByteArray message;
- pack >> message;
-
- QHash<QString, QDeclarativeDebugService *>::Iterator iter =
- d->plugins.find(name);
- if (iter == d->plugins.end()) {
- qWarning() << "QDeclarativeDebugServer: Message received for missing plugin" << name;
- } else {
- (*iter)->messageReceived(message);
- }
- }
- }
-}
-
QDeclarativeDebugServicePrivate::QDeclarativeDebugServicePrivate()
: server(0)
{
@@ -346,16 +59,16 @@ QDeclarativeDebugService::QDeclarativeDebugService(const QString &name, QObject
Q_D(QDeclarativeDebugService);
d->name = name;
d->server = QDeclarativeDebugServer::instance();
+ d->status = QDeclarativeDebugService::NotConnected;
if (!d->server)
return;
- if (d->server->d_func()->plugins.contains(name)) {
+ if (d->server->serviceNames().contains(name)) {
qWarning() << "QDeclarativeDebugService: Conflicting plugin name" << name;
d->server = 0;
} else {
- d->server->d_func()->plugins.insert(name, this);
- d->server->d_func()->advertisePlugins();
+ d->server->addService(this);
}
}
@@ -363,8 +76,7 @@ QDeclarativeDebugService::~QDeclarativeDebugService()
{
Q_D(const QDeclarativeDebugService);
if (d->server) {
- d->server->d_func()->plugins.remove(d->name);
- d->server->d_func()->advertisePlugins();
+ d->server->removeService(this);
}
}
@@ -377,13 +89,7 @@ QString QDeclarativeDebugService::name() const
QDeclarativeDebugService::Status QDeclarativeDebugService::status() const
{
Q_D(const QDeclarativeDebugService);
- if (!d->server
- || !d->server->hasDebuggingClient())
- return NotConnected;
- if (d->server->d_func()->clientPlugins.contains(d->name))
- return Enabled;
-
- return Unavailable;
+ return d->status;
}
namespace {
@@ -500,10 +206,7 @@ void QDeclarativeDebugService::sendMessage(const QByteArray &message)
if (status() != Enabled)
return;
- QPacket pack;
- pack << d->name << message;
- d->server->d_func()->protocol->send(pack);
- d->server->d_func()->connection->flush();
+ d->server->sendMessage(this, message);
}
void QDeclarativeDebugService::statusChanged(Status)
@@ -515,5 +218,3 @@ void QDeclarativeDebugService::messageReceived(const QByteArray &)
}
QT_END_NAMESPACE
-
-#include <qdeclarativedebugservice.moc>
diff --git a/src/declarative/debugger/qdeclarativedebugservice_p_p.h b/src/declarative/debugger/qdeclarativedebugservice_p_p.h
new file mode 100644
index 0000000..d2c8dda
--- /dev/null
+++ b/src/declarative/debugger/qdeclarativedebugservice_p_p.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEDEBUGSERVICE_P_H
+#define QDECLARATIVEDEBUGSERVICE_P_H
+
+#include <QtCore/qglobal.h>
+#include <private/qobject_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeDebugServer;
+
+class QDeclarativeDebugServicePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QDeclarativeDebugService)
+public:
+ QDeclarativeDebugServicePrivate();
+
+ QString name;
+ QDeclarativeDebugServer *server;
+ QDeclarativeDebugService::Status status;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEDEBUGSERVICE_P_H
diff --git a/src/declarative/debugger/qdeclarativedebugtrace.cpp b/src/declarative/debugger/qdeclarativedebugtrace.cpp
index 03e2d56..314db70 100644
--- a/src/declarative/debugger/qdeclarativedebugtrace.cpp
+++ b/src/declarative/debugger/qdeclarativedebugtrace.cpp
@@ -43,11 +43,27 @@
#include <QtCore/qdatastream.h>
#include <QtCore/qurl.h>
+#include <QtCore/qtimer.h>
Q_GLOBAL_STATIC(QDeclarativeDebugTrace, traceInstance);
+// convert to a QByteArray that can be sent to the debug client
+// use of QDataStream can skew results if m_deferredSend == false
+// (see tst_qperformancetimer::trace() benchmark)
+QByteArray QDeclarativeDebugData::toByteArray() const
+{
+ QByteArray data;
+ //### using QDataStream is relatively expensive
+ QDataStream ds(&data, QIODevice::WriteOnly);
+ ds << time << messageType << detailType;
+ if (messageType == (int)QDeclarativeDebugTrace::RangeData)
+ ds << detailData;
+ return data;
+}
+
QDeclarativeDebugTrace::QDeclarativeDebugTrace()
-: QDeclarativeDebugService(QLatin1String("CanvasFrameRate"))
+: QDeclarativeDebugService(QLatin1String("CanvasFrameRate")),
+ m_enabled(false), m_deferredSend(true)
{
m_timer.start();
}
@@ -64,10 +80,16 @@ void QDeclarativeDebugTrace::startRange(RangeType t)
traceInstance()->startRangeImpl(t);
}
-void QDeclarativeDebugTrace::rangeData(RangeType t, const QUrl &url)
+void QDeclarativeDebugTrace::rangeData(RangeType t, const QString &data)
{
if (QDeclarativeDebugService::isDebuggingEnabled())
- traceInstance()->rangeDataImpl(t, url);
+ traceInstance()->rangeDataImpl(t, data);
+}
+
+void QDeclarativeDebugTrace::rangeData(RangeType t, const QUrl &data)
+{
+ if (QDeclarativeDebugService::isDebuggingEnabled())
+ traceInstance()->rangeDataImpl(t, data);
}
void QDeclarativeDebugTrace::endRange(RangeType t)
@@ -78,45 +100,81 @@ void QDeclarativeDebugTrace::endRange(RangeType t)
void QDeclarativeDebugTrace::addEventImpl(EventType event)
{
- if (status() != Enabled)
+ if (status() != Enabled || !m_enabled)
return;
- QByteArray data;
- QDataStream ds(&data, QIODevice::WriteOnly);
- ds << m_timer.elapsed() << (int)Event << (int)event;
- sendMessage(data);
+ QDeclarativeDebugData ed = {m_timer.elapsed(), (int)Event, (int)event, QString()};
+ processMessage(ed);
}
void QDeclarativeDebugTrace::startRangeImpl(RangeType range)
{
- if (status() != Enabled)
+ if (status() != Enabled || !m_enabled)
return;
- QByteArray data;
- QDataStream ds(&data, QIODevice::WriteOnly);
- ds << m_timer.elapsed() << (int)RangeStart << (int)range;
- sendMessage(data);
+ QDeclarativeDebugData rd = {m_timer.elapsed(), (int)RangeStart, (int)range, QString()};
+ processMessage(rd);
}
-void QDeclarativeDebugTrace::rangeDataImpl(RangeType range, const QUrl &u)
+void QDeclarativeDebugTrace::rangeDataImpl(RangeType range, const QString &rData)
{
- if (status() != Enabled)
+ if (status() != Enabled || !m_enabled)
return;
- QByteArray data;
- QDataStream ds(&data, QIODevice::WriteOnly);
- ds << m_timer.elapsed() << (int)RangeData << (int)range << (QString)u.toString();
- sendMessage(data);
+ QDeclarativeDebugData rd = {m_timer.elapsed(), (int)RangeData, (int)range, rData};
+ processMessage(rd);
+}
+
+void QDeclarativeDebugTrace::rangeDataImpl(RangeType range, const QUrl &rData)
+{
+ if (status() != Enabled || !m_enabled)
+ return;
+
+ QDeclarativeDebugData rd = {m_timer.elapsed(), (int)RangeData, (int)range, rData.toEncoded(QUrl::FormattingOption(0x100))};
+ processMessage(rd);
}
void QDeclarativeDebugTrace::endRangeImpl(RangeType range)
{
- if (status() != Enabled)
+ if (status() != Enabled || !m_enabled)
return;
- QByteArray data;
- QDataStream ds(&data, QIODevice::WriteOnly);
- ds << m_timer.elapsed() << (int)RangeEnd << (int)range;
- sendMessage(data);
+ QDeclarativeDebugData rd = {m_timer.elapsed(), (int)RangeEnd, (int)range, QString()};
+ processMessage(rd);
+}
+
+/*
+ Either send the message directly, or queue up
+ a list of messages to send later (via sendMessages)
+*/
+void QDeclarativeDebugTrace::processMessage(const QDeclarativeDebugData &message)
+{
+ if (m_deferredSend)
+ m_data.append(message);
+ else
+ sendMessage(message.toByteArray());
}
+/*
+ Send the messages queued up by processMessage
+*/
+void QDeclarativeDebugTrace::sendMessages()
+{
+ if (m_deferredSend) {
+ //### this is a suboptimal way to send batched messages
+ for (int i = 0; i < m_data.count(); ++i)
+ sendMessage(m_data.at(i).toByteArray());
+ m_data.clear();
+ }
+}
+
+void QDeclarativeDebugTrace::messageReceived(const QByteArray &message)
+{
+ QByteArray rwData = message;
+ QDataStream stream(&rwData, QIODevice::ReadOnly);
+
+ stream >> m_enabled;
+
+ if (!m_enabled)
+ sendMessages();
+}
diff --git a/src/declarative/debugger/qdeclarativedebugtrace_p.h b/src/declarative/debugger/qdeclarativedebugtrace_p.h
index 704c49a..3f9b904 100644
--- a/src/declarative/debugger/qdeclarativedebugtrace_p.h
+++ b/src/declarative/debugger/qdeclarativedebugtrace_p.h
@@ -43,24 +43,28 @@
#define QDECLARATIVEDEBUGTRACE_P_H
#include <private/qdeclarativedebugservice_p.h>
-#include <QtCore/qelapsedtimer.h>
+#include <private/qperformancetimer_p.h>
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
+struct QDeclarativeDebugData
+{
+ qint64 time;
+ int messageType;
+ int detailType;
+ QString detailData;
+
+ QByteArray toByteArray() const;
+};
+
+Q_DECLARE_TYPEINFO(QDeclarativeDebugData,Q_PRIMITIVE_TYPE);
+
class QUrl;
class Q_AUTOTEST_EXPORT QDeclarativeDebugTrace : public QDeclarativeDebugService
{
public:
- enum EventType {
- FramePaint,
- Mouse,
- Key,
-
- MaximumEventType
- };
-
enum Message {
Event,
RangeStart,
@@ -70,10 +74,20 @@ public:
MaximumMessage
};
+ enum EventType {
+ FramePaint,
+ Mouse,
+ Key,
+
+ MaximumEventType
+ };
+
enum RangeType {
Painting,
Compiling,
Creating,
+ Binding, //running a binding
+ HandlingSignal, //running a signal handler
MaximumRangeType
};
@@ -81,16 +95,25 @@ public:
static void addEvent(EventType);
static void startRange(RangeType);
+ static void rangeData(RangeType, const QString &);
static void rangeData(RangeType, const QUrl &);
static void endRange(RangeType);
QDeclarativeDebugTrace();
+protected:
+ virtual void messageReceived(const QByteArray &);
private:
void addEventImpl(EventType);
void startRangeImpl(RangeType);
+ void rangeDataImpl(RangeType, const QString &);
void rangeDataImpl(RangeType, const QUrl &);
void endRangeImpl(RangeType);
- QElapsedTimer m_timer;
+ void processMessage(const QDeclarativeDebugData &);
+ void sendMessages();
+ QPerformanceTimer m_timer;
+ bool m_enabled;
+ bool m_deferredSend;
+ QList<QDeclarativeDebugData> m_data;
};
QT_END_NAMESPACE
diff --git a/src/declarative/debugger/qpacketprotocol.cpp b/src/declarative/debugger/qpacketprotocol.cpp
index c2f7709..ad1e767 100644
--- a/src/declarative/debugger/qpacketprotocol.cpp
+++ b/src/declarative/debugger/qpacketprotocol.cpp
@@ -452,6 +452,14 @@ bool QPacket::isEmpty() const
}
/*!
+ Returns raw packet data.
+ */
+QByteArray QPacket::data() const
+{
+ return b;
+}
+
+/*!
Clears data in the packet. This is useful for reusing one writable packet.
For example
\code
diff --git a/src/declarative/debugger/qpacketprotocol_p.h b/src/declarative/debugger/qpacketprotocol_p.h
index d153833..1c69cdd 100644
--- a/src/declarative/debugger/qpacketprotocol_p.h
+++ b/src/declarative/debugger/qpacketprotocol_p.h
@@ -59,7 +59,7 @@ class QPacket;
class QPacketAutoSend;
class QPacketProtocolPrivate;
-class Q_DECLARATIVE_PRIVATE_EXPORT QPacketProtocol : public QObject
+class Q_DECLARATIVE_EXPORT QPacketProtocol : public QObject
{
Q_OBJECT
public:
@@ -89,7 +89,7 @@ private:
};
-class Q_DECLARATIVE_PRIVATE_EXPORT QPacket : public QDataStream
+class Q_DECLARATIVE_EXPORT QPacket : public QDataStream
{
public:
QPacket();
@@ -98,6 +98,7 @@ public:
void clear();
bool isEmpty() const;
+ QByteArray data() const;
protected:
friend class QPacketProtocol;
diff --git a/src/declarative/graphicsitems/graphicsitems.pri b/src/declarative/graphicsitems/graphicsitems.pri
index ffdeb29..2cd3323 100644
--- a/src/declarative/graphicsitems/graphicsitems.pri
+++ b/src/declarative/graphicsitems/graphicsitems.pri
@@ -50,7 +50,9 @@ HEADERS += \
$$PWD/qdeclarativelayoutitem_p.h \
$$PWD/qdeclarativeitemchangelistener_p.h \
$$PWD/qdeclarativegraphicswidget_p.h \
- $$PWD/qdeclarativetextlayout_p.h
+ $$PWD/qdeclarativetextlayout_p.h \
+ $$PWD/qdeclarativepincharea_p.h \
+ $$PWD/qdeclarativepincharea_p_p.h
SOURCES += \
$$PWD/qdeclarativeitemsmodule.cpp \
@@ -83,5 +85,6 @@ SOURCES += \
$$PWD/qdeclarativelistview.cpp \
$$PWD/qdeclarativelayoutitem.cpp \
$$PWD/qdeclarativegraphicswidget.cpp \
- $$PWD/qdeclarativetextlayout.cpp
+ $$PWD/qdeclarativetextlayout.cpp \
+ $$PWD/qdeclarativepincharea.cpp
diff --git a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp
index 12a820f..abdfdfa 100644
--- a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp
@@ -86,6 +86,16 @@ QT_BEGIN_NAMESPACE
\sa BorderImage, Image
*/
+/*!
+ \qmlproperty bool AnimatedImage::mirror
+ \since Quick 1.1
+
+ This property holds whether the image should be horizontally inverted
+ (effectively displaying a mirrored image).
+
+ The default value is false.
+*/
+
QDeclarativeAnimatedImage::QDeclarativeAnimatedImage(QDeclarativeItem *parent)
: QDeclarativeImage(*(new QDeclarativeAnimatedImagePrivate), parent)
{
@@ -126,7 +136,7 @@ void QDeclarativeAnimatedImage::setPaused(bool pause)
\qmlproperty bool AnimatedImage::playing
This property holds whether the animated image is playing.
- By defaults, this property is true, meaning that the animation
+ By default, this property is true, meaning that the animation
will start playing immediately.
*/
bool QDeclarativeAnimatedImage::isPlaying() const
diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
index c0a7d72..63b2b9a 100644
--- a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
@@ -200,6 +200,16 @@ QDeclarativeBorderImage::~QDeclarativeBorderImage()
*/
/*!
+ \qmlproperty bool BorderImage::mirror
+ \since Quick 1.1
+
+ This property holds whether the image should be horizontally inverted
+ (effectively displaying a mirrored image).
+
+ The default value is false.
+*/
+
+/*!
\qmlproperty url BorderImage::source
This property holds the URL that refers to the source image.
@@ -226,6 +236,16 @@ QDeclarativeBorderImage::~QDeclarativeBorderImage()
\sa QDeclarativeImageProvider
*/
+
+/*!
+ \qmlproperty QSize BorderImage::sourceSize
+
+ This property holds the actual width and height of the loaded image.
+
+ In BorderImage, this property is read-only.
+
+ \sa Image::sourceSize
+*/
void QDeclarativeBorderImage::setSource(const QUrl &url)
{
Q_D(QDeclarativeBorderImage);
@@ -290,7 +310,12 @@ void QDeclarativeBorderImage::load()
}
} else {
- d->pix.load(qmlEngine(this), d->url, d->async);
+ QDeclarativePixmap::Options options;
+ if (d->async)
+ options |= QDeclarativePixmap::Asynchronous;
+ if (d->cached)
+ options |= QDeclarativePixmap::Cached;
+ d->pix.load(qmlEngine(this), d->url, options);
if (d->pix.isLoading()) {
d->pix.connectFinished(this, SLOT(requestFinished()));
@@ -310,6 +335,7 @@ void QDeclarativeBorderImage::load()
d->progress = 1.0;
emit statusChanged(d->status);
emit progressChanged(d->progress);
+ requestFinished();
update();
}
}
@@ -413,7 +439,12 @@ void QDeclarativeBorderImage::setGridScaledImage(const QDeclarativeGridScaledIma
d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl()));
- d->pix.load(qmlEngine(this), d->sciurl, d->async);
+ QDeclarativePixmap::Options options;
+ if (d->async)
+ options |= QDeclarativePixmap::Asynchronous;
+ if (d->cached)
+ options |= QDeclarativePixmap::Cached;
+ d->pix.load(qmlEngine(this), d->sciurl, options);
if (d->pix.isLoading()) {
static int thisRequestProgress = -1;
@@ -465,6 +496,9 @@ void QDeclarativeBorderImage::requestFinished()
setImplicitWidth(impsize.width());
setImplicitHeight(impsize.height());
+ if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height())
+ emit sourceSizeChanged();
+
d->progress = 1.0;
emit statusChanged(d->status);
emit progressChanged(1.0);
@@ -514,8 +548,15 @@ void QDeclarativeBorderImage::paint(QPainter *p, const QStyleOptionGraphicsItem
bool oldAA = p->testRenderHint(QPainter::Antialiasing);
bool oldSmooth = p->testRenderHint(QPainter::SmoothPixmapTransform);
+ QTransform oldTransform;
if (d->smooth)
p->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth);
+ if (d->mirror) {
+ oldTransform = p->transform();
+ QTransform mirror;
+ mirror.translate(d->width(), 0).scale(-1, 1.0);
+ p->setWorldTransform(mirror * oldTransform);
+ }
const QDeclarativeScaleGrid *border = d->getScaleGrid();
int left = border->left();
@@ -541,6 +582,8 @@ void QDeclarativeBorderImage::paint(QPainter *p, const QStyleOptionGraphicsItem
p->setRenderHint(QPainter::Antialiasing, oldAA);
p->setRenderHint(QPainter::SmoothPixmapTransform, oldSmooth);
}
+ if (d->mirror)
+ p->setWorldTransform(oldTransform);
}
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage_p.h b/src/declarative/graphicsitems/qdeclarativeborderimage_p.h
index 9944cbe..d9db0ac 100644
--- a/src/declarative/graphicsitems/qdeclarativeborderimage_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeborderimage_p.h
@@ -63,6 +63,9 @@ class Q_AUTOTEST_EXPORT QDeclarativeBorderImage : public QDeclarativeImageBase
Q_PROPERTY(TileMode horizontalTileMode READ horizontalTileMode WRITE setHorizontalTileMode NOTIFY horizontalTileModeChanged)
Q_PROPERTY(TileMode verticalTileMode READ verticalTileMode WRITE setVerticalTileMode NOTIFY verticalTileModeChanged)
+ // read-only for BorderImage
+ Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged)
+
public:
QDeclarativeBorderImage(QDeclarativeItem *parent=0);
~QDeclarativeBorderImage();
@@ -83,6 +86,7 @@ public:
Q_SIGNALS:
void horizontalTileModeChanged();
void verticalTileModeChanged();
+ void sourceSizeChanged();
protected:
virtual void load();
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index f5da491..52ad1e1 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -1271,6 +1271,60 @@ void QDeclarativeFlickable::setContentHeight(qreal h)
d->updateBeginningEnd();
}
+/*!
+ \qmlmethod Flickable::resizeContent(real width, real height, QPointF center)
+ \preliminary
+
+ Resizes the content to \a width x \a height about \a center.
+
+ \bold {This method was added in QtQuick 1.1.}
+
+ This does not scale the contents of the Flickable - it only resizes the \l contentWidth
+ and \l contentHeight.
+
+ Resizing the content may result in the content being positioned outside
+ the bounds of the Flickable. Calling \l returnToBounds() will
+ move the content back within legal bounds.
+*/
+void QDeclarativeFlickable::resizeContent(qreal w, qreal h, QPointF center)
+{
+ Q_D(QDeclarativeFlickable);
+ if (w != d->hData.viewSize) {
+ qreal oldSize = d->hData.viewSize;
+ setContentWidth(w);
+ if (center.x() != 0) {
+ qreal pos = center.x() * w / oldSize;
+ setContentX(contentX() + pos - center.x());
+ }
+ }
+ if (h != d->vData.viewSize) {
+ qreal oldSize = d->vData.viewSize;
+ setContentHeight(h);
+ if (center.y() != 0) {
+ qreal pos = center.y() * h / oldSize;
+ setContentY(contentY() + pos - center.y());
+ }
+ }
+}
+
+/*!
+ \qmlmethod Flickable::returnToBounds()
+ \preliminary
+
+ Ensures the content is within legal bounds.
+
+ \bold {This method was added in QtQuick 1.1.}
+
+ This may be called to ensure that the content is within legal bounds
+ after manually positioning the content.
+*/
+void QDeclarativeFlickable::returnToBounds()
+{
+ Q_D(QDeclarativeFlickable);
+ d->fixupX();
+ d->fixupY();
+}
+
qreal QDeclarativeFlickable::vWidth() const
{
Q_D(const QDeclarativeFlickable);
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p.h
index 6e4d8ed..ece2db7 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeflickable_p.h
@@ -149,6 +149,10 @@ public:
FlickableDirection flickableDirection() const;
void setFlickableDirection(FlickableDirection);
+ //XXX Added in QtQuick 1.1
+ Q_INVOKABLE void resizeContent(qreal w, qreal h, QPointF center);
+ Q_INVOKABLE void returnToBounds();
+
Q_SIGNALS:
void contentWidthChanged();
void contentHeightChanged();
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index 7ddf6a2..c2c28c2 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -1615,6 +1615,8 @@ void QDeclarativeGridView::setFlow(Flow flow)
setContentHeight(-1);
setFlickableDirection(QDeclarativeFlickable::HorizontalFlick);
}
+ setContentX(0);
+ setContentY(0);
d->clear();
d->updateGrid();
refill();
diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp
index aa74716..68a1ecb 100644
--- a/src/declarative/graphicsitems/qdeclarativeimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp
@@ -458,84 +458,102 @@ QRectF QDeclarativeImage::boundingRect() const
are always loaded asynchonously.
*/
+/*!
+ \qmlproperty bool Image::cached
+ \since Quick 1.1
+
+ Specifies that the image should be cached. The default value is
+ true. Setting \a cached to false is useful when dealing with large images,
+ to make sure that they aren't cached at the expense of small 'ui element' images.
+*/
+
+/*!
+ \qmlproperty bool Image::mirror
+ \since Quick 1.1
+
+ This property holds whether the image should be horizontally inverted
+ (effectively displaying a mirrored image).
+
+ The default value is false.
+*/
+
+
void QDeclarativeImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
{
Q_D(QDeclarativeImage);
if (d->pix.pixmap().isNull() )
return;
- bool oldAA = p->testRenderHint(QPainter::Antialiasing);
- bool oldSmooth = p->testRenderHint(QPainter::SmoothPixmapTransform);
- if (d->smooth)
- p->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth);
+ int drawWidth = width();
+ int drawHeight = height();
+ bool doClip = false;
+ QTransform transform;
+ qreal widthScale = width() / qreal(d->pix.width());
+ qreal heightScale = height() / qreal(d->pix.height());
if (width() != d->pix.width() || height() != d->pix.height()) {
if (d->fillMode >= Tile) {
- if (d->fillMode == Tile) {
- p->drawTiledPixmap(QRectF(0,0,width(),height()), d->pix);
- } else {
- qreal widthScale = width() / qreal(d->pix.width());
- qreal heightScale = height() / qreal(d->pix.height());
-
- QTransform scale;
- if (d->fillMode == TileVertically) {
- scale.scale(widthScale, 1.0);
- QTransform old = p->transform();
- p->setWorldTransform(scale * old);
- p->drawTiledPixmap(QRectF(0,0,d->pix.width(),height()), d->pix);
- p->setWorldTransform(old);
- } else {
- scale.scale(1.0, heightScale);
- QTransform old = p->transform();
- p->setWorldTransform(scale * old);
- p->drawTiledPixmap(QRectF(0,0,width(),d->pix.height()), d->pix);
- p->setWorldTransform(old);
- }
+ if (d->fillMode == TileVertically) {
+ transform.scale(widthScale, 1.0);
+ drawWidth = d->pix.width();
+ } else if (d->fillMode == TileHorizontally) {
+ transform.scale(1.0, heightScale);
+ drawHeight = d->pix.height();
}
} else {
- qreal widthScale = width() / qreal(d->pix.width());
- qreal heightScale = height() / qreal(d->pix.height());
-
- QTransform scale;
-
if (d->fillMode == PreserveAspectFit) {
if (widthScale <= heightScale) {
heightScale = widthScale;
- scale.translate(0, (height() - heightScale * d->pix.height()) / 2);
+ transform.translate(0, (height() - heightScale * d->pix.height()) / 2);
} else if(heightScale < widthScale) {
widthScale = heightScale;
- scale.translate((width() - widthScale * d->pix.width()) / 2, 0);
+ transform.translate((width() - widthScale * d->pix.width()) / 2, 0);
}
} else if (d->fillMode == PreserveAspectCrop) {
if (widthScale < heightScale) {
widthScale = heightScale;
- scale.translate((width() - widthScale * d->pix.width()) / 2, 0);
+ transform.translate((width() - widthScale * d->pix.width()) / 2, 0);
} else if(heightScale < widthScale) {
heightScale = widthScale;
- scale.translate(0, (height() - heightScale * d->pix.height()) / 2);
+ transform.translate(0, (height() - heightScale * d->pix.height()) / 2);
}
}
- if (clip()) {
- p->save();
- p->setClipRect(QRectF(0, 0, d->mWidth, d->mHeight), Qt::IntersectClip);
- }
- scale.scale(widthScale, heightScale);
- QTransform old = p->transform();
- p->setWorldTransform(scale * old);
- p->drawPixmap(0, 0, d->pix);
- p->setWorldTransform(old);
- if (clip()) {
- p->restore();
- }
+ transform.scale(widthScale, heightScale);
+ drawWidth = d->pix.width();
+ drawHeight = d->pix.height();
+ doClip = clip();
}
- } else {
- p->drawPixmap(0, 0, d->pix);
}
+ QTransform oldTransform;
+ bool oldAA = p->testRenderHint(QPainter::Antialiasing);
+ bool oldSmooth = p->testRenderHint(QPainter::SmoothPixmapTransform);
+ if (d->smooth)
+ p->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth);
+ if (doClip) {
+ p->save();
+ p->setClipRect(QRectF(0, 0, d->mWidth, d->mHeight), Qt::IntersectClip);
+ }
+ if (d->mirror)
+ transform.translate(drawWidth, 0).scale(-1.0, 1.0);
+ if (!transform.isIdentity()) {
+ oldTransform = p->transform();
+ p->setWorldTransform(transform * oldTransform);
+ }
+
+ if (d->fillMode >= Tile)
+ p->drawTiledPixmap(QRectF(0, 0, drawWidth, drawHeight), d->pix);
+ else
+ p->drawPixmap(QRectF(0, 0, drawWidth, drawHeight), d->pix, QRectF(0, 0, drawWidth, drawHeight));
+
if (d->smooth) {
p->setRenderHint(QPainter::Antialiasing, oldAA);
p->setRenderHint(QPainter::SmoothPixmapTransform, oldSmooth);
}
+ if (doClip)
+ p->restore();
+ if (!transform.isIdentity())
+ p->setWorldTransform(oldTransform);
}
void QDeclarativeImage::pixmapChange()
diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
index c3bac2d..c745635 100644
--- a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
@@ -128,6 +128,44 @@ QSize QDeclarativeImageBase::sourceSize() const
return QSize(width != -1 ? width : implicitWidth(), height != -1 ? height : implicitHeight());
}
+bool QDeclarativeImageBase::cached() const
+{
+ Q_D(const QDeclarativeImageBase);
+ return d->cached;
+}
+
+void QDeclarativeImageBase::setCached(bool cached)
+{
+ Q_D(QDeclarativeImageBase);
+ if (d->cached == cached)
+ return;
+
+ d->cached = cached;
+ emit cachedChanged();
+ if (isComponentComplete())
+ load();
+}
+
+void QDeclarativeImageBase::setMirror(bool mirror)
+{
+ Q_D(QDeclarativeImageBase);
+ if (mirror == d->mirror)
+ return;
+
+ d->mirror = mirror;
+
+ if (isComponentComplete())
+ update();
+
+ emit mirrorChanged();
+}
+
+bool QDeclarativeImageBase::mirror() const
+{
+ Q_D(const QDeclarativeImageBase);
+ return d->mirror;
+}
+
void QDeclarativeImageBase::load()
{
Q_D(QDeclarativeImageBase);
@@ -143,7 +181,12 @@ void QDeclarativeImageBase::load()
pixmapChange();
update();
} else {
- d->pix.load(qmlEngine(this), d->url, d->explicitSourceSize ? sourceSize() : QSize(), d->async);
+ QDeclarativePixmap::Options options;
+ if (d->async)
+ options |= QDeclarativePixmap::Asynchronous;
+ if (d->cached)
+ options |= QDeclarativePixmap::Cached;
+ d->pix.load(qmlEngine(this), d->url, d->explicitSourceSize ? sourceSize() : QSize(), options);
if (d->pix.isLoading()) {
d->progress = 0.0;
diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase_p.h b/src/declarative/graphicsitems/qdeclarativeimagebase_p.h
index 68eb8d0..b6e55ec 100644
--- a/src/declarative/graphicsitems/qdeclarativeimagebase_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeimagebase_p.h
@@ -58,7 +58,9 @@ class Q_AUTOTEST_EXPORT QDeclarativeImageBase : public QDeclarativeItem
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
+ Q_PROPERTY(bool cached READ cached WRITE setCached NOTIFY cachedChanged) // ### VERSIONING: Only in QtQuick 1.1
Q_PROPERTY(QSize sourceSize READ sourceSize WRITE setSourceSize NOTIFY sourceSizeChanged)
+ Q_PROPERTY(bool mirror READ mirror WRITE setMirror NOTIFY mirrorChanged) // ### VERSIONING: Only in QtQuick 1.1
public:
~QDeclarativeImageBase();
@@ -72,15 +74,23 @@ public:
bool asynchronous() const;
void setAsynchronous(bool);
+ bool cached() const;
+ void setCached(bool);
+
virtual void setSourceSize(const QSize&);
QSize sourceSize() const;
+ virtual void setMirror(bool mirror);
+ bool mirror() const;
+
Q_SIGNALS:
void sourceChanged(const QUrl &);
void sourceSizeChanged();
void statusChanged(QDeclarativeImageBase::Status);
void progressChanged(qreal progress);
void asynchronousChanged();
+ void cachedChanged();
+ void mirrorChanged();
protected:
virtual void load();
diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h b/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h
index 3d23ba9..950914f 100644
--- a/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h
@@ -70,7 +70,9 @@ public:
: status(QDeclarativeImageBase::Null),
progress(0.0),
explicitSourceSize(false),
- async(false)
+ async(false),
+ cached(true),
+ mirror(false)
{
QGraphicsItemPrivate::flags = QGraphicsItemPrivate::flags & ~QGraphicsItem::ItemHasNoContents;
}
@@ -82,6 +84,8 @@ public:
QSize sourcesize;
bool explicitSourceSize : 1;
bool async : 1;
+ bool cached : 1;
+ bool mirror: 1;
};
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp
index 922fa8f..295a889 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp
@@ -444,6 +444,11 @@ void QDeclarativeItemKeyFilter::componentComplete()
\c KeyNavigation.BeforeItem allows the event to be used for key navigation
before the item, rather than after.
+ If item to which the focus is switching is not enabled or visible, an attempt will
+ be made to skip this item and focus on the next. This is possible if there are
+ a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
+ or visible, they will also be skipped.
+
\sa {Keys}{Keys attached property}
*/
@@ -452,10 +457,12 @@ void QDeclarativeItemKeyFilter::componentComplete()
\qmlproperty Item KeyNavigation::right
\qmlproperty Item KeyNavigation::up
\qmlproperty Item KeyNavigation::down
+ \qmlproperty Item KeyNavigation::tab
+ \qmlproperty Item KeyNavigation::backtab
These properties hold the item to assign focus to
- when the left, right, up or down cursor keys are
- pressed.
+ when the left, right, up or down cursor keys, or the
+ tab key are pressed.
*/
/*!
@@ -611,37 +618,37 @@ void QDeclarativeKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
switch(event->key()) {
case Qt::Key_Left:
if (d->left) {
- d->left->setFocus(true);
+ setFocusNavigation(d->left, "left");
event->accept();
}
break;
case Qt::Key_Right:
if (d->right) {
- d->right->setFocus(true);
+ setFocusNavigation(d->right, "right");
event->accept();
}
break;
case Qt::Key_Up:
if (d->up) {
- d->up->setFocus(true);
+ setFocusNavigation(d->up, "up");
event->accept();
}
break;
case Qt::Key_Down:
if (d->down) {
- d->down->setFocus(true);
+ setFocusNavigation(d->down, "down");
event->accept();
}
break;
case Qt::Key_Tab:
if (d->tab) {
- d->tab->setFocus(true);
+ setFocusNavigation(d->tab, "tab");
event->accept();
}
break;
case Qt::Key_Backtab:
if (d->backtab) {
- d->backtab->setFocus(true);
+ setFocusNavigation(d->backtab, "backtab");
event->accept();
}
break;
@@ -700,6 +707,29 @@ void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyReleased(event, post);
}
+void QDeclarativeKeyNavigationAttached::setFocusNavigation(QDeclarativeItem *currentItem, const char *dir)
+{
+ QDeclarativeItem *initialItem = currentItem;
+ bool isNextItem = false;
+ do {
+ isNextItem = false;
+ if (currentItem->isVisible() && currentItem->isEnabled()) {
+ currentItem->setFocus(true);
+ } else {
+ QObject *attached =
+ qmlAttachedPropertiesObject<QDeclarativeKeyNavigationAttached>(currentItem, false);
+ if (attached) {
+ QDeclarativeItem *tempItem = qvariant_cast<QDeclarativeItem*>(attached->property(dir));
+ if (tempItem) {
+ currentItem = tempItem;
+ isNextItem = true;
+ }
+ }
+ }
+ }
+ while (currentItem != initialItem && isNextItem);
+}
+
/*!
\qmlclass Keys QDeclarativeKeysAttached
\ingroup qml-basic-interaction-elements
diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h
index a36ee34..7e4d157 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h
@@ -415,6 +415,7 @@ Q_SIGNALS:
private:
virtual void keyPressed(QKeyEvent *event, bool post);
virtual void keyReleased(QKeyEvent *event, bool post);
+ void setFocusNavigation(QDeclarativeItem *currentItem, const char *dir);
};
class QDeclarativeKeysAttachedPrivate : public QObjectPrivate
diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
index 52703c2..f06b256 100644
--- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
@@ -78,6 +78,7 @@
#include "private/qdeclarativewebview_p_p.h"
#endif
#include "private/qdeclarativeanchors_p.h"
+#include "private/qdeclarativepincharea_p.h"
static QDeclarativePrivate::AutoParentResult qgraphicsobject_autoParent(QObject *obj, QObject *parent)
{
@@ -147,10 +148,13 @@ void QDeclarativeItemModule::defineModule()
qmlRegisterType<QDeclarativeViewSection>("QtQuick",1,0,"ViewSection");
qmlRegisterType<QDeclarativeVisualDataModel>("QtQuick",1,0,"VisualDataModel");
qmlRegisterType<QDeclarativeVisualItemModel>("QtQuick",1,0,"VisualItemModel");
+ qmlRegisterType<QDeclarativePinchArea>("QtQuick",1,1,"PinchArea");
+ qmlRegisterType<QDeclarativePinch>();
qmlRegisterType<QDeclarativeAnchors>();
qmlRegisterType<QDeclarativeKeyEvent>();
qmlRegisterType<QDeclarativeMouseEvent>();
+ qmlRegisterType<QDeclarativePinchEvent>();
qmlRegisterType<QGraphicsObject>();
qmlRegisterType<QGraphicsWidget>("QtQuick",1,0,"QGraphicsWidget");
qmlRegisterExtendedType<QGraphicsWidget,QDeclarativeGraphicsWidget>("QtQuick",1,0,"QGraphicsWidget");
@@ -171,6 +175,10 @@ void QDeclarativeItemModule::defineModule()
qmlRegisterType<QGraphicsEffect>();
#endif
+ // QtQuick 1.1 items
+ qmlRegisterType<QDeclarativeRepeater, 1>("QtQuick",1,1,"Repeater");
+
+
qmlRegisterUncreatableType<QDeclarativeKeyNavigationAttached>("QtQuick",1,0,"KeyNavigation",QDeclarativeKeyNavigationAttached::tr("KeyNavigation is only available via attached properties"));
qmlRegisterUncreatableType<QDeclarativeKeysAttached>("QtQuick",1,0,"Keys",QDeclarativeKeysAttached::tr("Keys is only available via attached properties"));
diff --git a/src/declarative/graphicsitems/qdeclarativepincharea.cpp b/src/declarative/graphicsitems/qdeclarativepincharea.cpp
new file mode 100644
index 0000000..998c30d
--- /dev/null
+++ b/src/declarative/graphicsitems/qdeclarativepincharea.cpp
@@ -0,0 +1,579 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativepincharea_p.h"
+#include "qdeclarativepincharea_p_p.h"
+
+#include <QApplication>
+#include <QGraphicsScene>
+
+#include <float.h>
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ \qmlclass PinchEvent QDeclarativePinchEvent
+ \ingroup qml-event-elements
+ \brief The PinchEvent object provides information about a pinch event.
+
+ \bold {The PinchEvent element was added in QtQuick 1.1}
+
+ The \c center, \c startCenter, \c lastCenter properties provide the center position between the two touch points.
+
+ The \c scale and \c lastScale properties provide the scale factor.
+
+ The \c angle, \c lastAngle and \c rotation properties provide the angle between the two points and the amount of rotation.
+
+ The \c point1, \c point2, \c startPoint1, \c startPoint2 properties provide the positions of the touch points.
+
+ The \c accepted property may be set to false in the \c onPinchStarted handler if the gesture should not
+ be handled.
+
+ \sa PinchArea
+*/
+
+/*!
+ \qmlproperty QPointF PinchEvent::center
+ \qmlproperty QPointF PinchEvent::startCenter
+ \qmlproperty QPointF PinchEvent::lastCenter
+
+ These properties hold the position of the center point between the two touch points.
+
+ \list
+ \o \c center is the current center point
+ \o \c lastCenter is the center point of the previous event.
+ \o \c startCenter is the center point when the gesture began
+ \endlist
+*/
+
+/*!
+ \qmlproperty real PinchEvent::scale
+ \qmlproperty real PinchEvent::lastScale
+
+ These properties hold the scale factor determined by the change in distance between the two touch points.
+
+ \list
+ \o \c scale is the current scale factor.
+ \o \c lastScale is the scale factor of the previous event.
+ \endlist
+
+ When a pinch gesture is started, the scale is 1.0.
+*/
+
+/*!
+ \qmlproperty real PinchEvent::angle
+ \qmlproperty real PinchEvent::lastAngle
+ \qmlproperty real PinchEvent::rotation
+
+ These properties hold the angle between the two touch points.
+
+ \list
+ \o \c angle is the current angle between the two points in the range -180 to 180.
+ \o \c lastAngle is the angle of the previous event.
+ \o \c rotation is the total rotation since the pinch gesture started.
+ \endlist
+
+ When a pinch gesture is started, the rotation is 0.0.
+*/
+
+/*!
+ \qmlproperty QPointF PinchEvent::point1
+ \qmlproperty QPointF PinchEvent::startPoint1
+ \qmlproperty QPointF PinchEvent::point2
+ \qmlproperty QPointF PinchEvent::startPoint2
+
+ These properties provide the actual touch points generating the pinch.
+
+ \list
+ \o \c point1 and \c point2 hold the current positions of the points.
+ \o \c startPoint1 and \c startPoint2 hold the positions of the points when the second point was touched.
+ \endlist
+*/
+
+/*!
+ \qmlproperty bool PinchEvent::accepted
+
+ Setting this property to false in the \c PinchArea::onPinchStarted handler
+ will result in no further pinch events being generated, and the gesture
+ ignored.
+*/
+
+QDeclarativePinch::QDeclarativePinch()
+ : m_target(0), m_minScale(1.0), m_maxScale(1.0)
+ , m_minRotation(0.0), m_maxRotation(0.0)
+ , m_axis(NoDrag), m_xmin(-FLT_MAX), m_xmax(FLT_MAX)
+ , m_ymin(-FLT_MAX), m_ymax(FLT_MAX), m_active(false)
+{
+}
+
+QDeclarativePinchAreaPrivate::~QDeclarativePinchAreaPrivate()
+{
+ delete pinch;
+}
+
+/*!
+ \qmlclass PinchArea QDeclarativePinchArea
+ \brief The PinchArea item enables simple pinch gesture handling.
+ \inherits Item
+
+ \bold {The PinchArea element was added in QtQuick 1.1}
+
+ A PinchArea is an invisible item that is typically used in conjunction with
+ a visible item in order to provide pinch gesture handling for that item.
+
+ The \l enabled property is used to enable and disable pinch handling for
+ the proxied item. When disabled, the pinch area becomes transparent to
+ mouse/touch events.
+
+ PinchArea can be used in two ways:
+
+ \list
+ \o setting a \c pinch.target to provide automatic interaction with an element
+ \o using the onPinchStarted, onPinchChanged and onPinchFinished handlers
+ \endlist
+
+ \sa PinchEvent
+*/
+
+/*!
+ \qmlsignal PinchArea::onPinchStarted()
+
+ This handler is called when the pinch area detects that a pinch gesture has started.
+
+ The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
+ including the scale, center and angle of the pinch.
+
+ To ignore this gesture set the \c pinch.accepted property to false. The gesture
+ will be cancelled and no further events will be sent.
+*/
+
+/*!
+ \qmlsignal PinchArea::onPinchChanged()
+
+ This handler is called when the pinch area detects that a pinch gesture has changed.
+
+ The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
+ including the scale, center and angle of the pinch.
+*/
+
+/*!
+ \qmlsignal PinchArea::onPinchFinished()
+
+ This handler is called when the pinch area detects that a pinch gesture has finished.
+
+ The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
+ including the scale, center and angle of the pinch.
+*/
+
+
+/*!
+ \qmlproperty Item PinchArea::pinch.target
+ \qmlproperty bool PinchArea::pinch.active
+ \qmlproperty real PinchArea::pinch.minimumScale
+ \qmlproperty real PinchArea::pinch.maximumScale
+ \qmlproperty real PinchArea::pinch.minimumRotation
+ \qmlproperty real PinchArea::pinch.maximumRotation
+ \qmlproperty enumeration PinchArea::pinch.dragAxis
+ \qmlproperty real PinchArea::pinch.minimumX
+ \qmlproperty real PinchArea::pinch.maximumX
+ \qmlproperty real PinchArea::pinch.minimumY
+ \qmlproperty real PinchArea::pinch.maximumY
+
+ \c pinch provides a convenient way to make an item react to pinch gestures.
+
+ \list
+ \i \c pinch.target specifies the id of the item to drag.
+ \i \c pinch.active specifies if the target item is currently being dragged.
+ \i \c pinch.minimumScale and \c pinch.maximumScale limit the range of the Item::scale property.
+ \i \c pinch.minimumRotation and \c pinch.maximumRotation limit the range of the Item::rotation property.
+ \i \c pinch.dragAxis specifies whether dragging in not allowed (\c Pinch.NoDrag), can be done horizontally (\c Pinch.XAxis), vertically (\c Pinch.YAxis), or both (\c Pinch.XandYAxis)
+ \i \c pinch.minimum and \c pinch.maximum limit how far the target can be dragged along the corresponding axes.
+ \endlist
+*/
+
+QDeclarativePinchArea::QDeclarativePinchArea(QDeclarativeItem *parent)
+ : QDeclarativeItem(*(new QDeclarativePinchAreaPrivate), parent)
+{
+ Q_D(QDeclarativePinchArea);
+ d->init();
+}
+
+QDeclarativePinchArea::~QDeclarativePinchArea()
+{
+}
+
+/*!
+ \qmlproperty bool PinchArea::enabled
+ This property holds whether the item accepts pinch gestures.
+
+ This property defaults to true.
+*/
+bool QDeclarativePinchArea::isEnabled() const
+{
+ Q_D(const QDeclarativePinchArea);
+ return d->absorb;
+}
+
+void QDeclarativePinchArea::setEnabled(bool a)
+{
+ Q_D(QDeclarativePinchArea);
+ if (a != d->absorb) {
+ d->absorb = a;
+ emit enabledChanged();
+ }
+}
+
+bool QDeclarativePinchArea::event(QEvent *event)
+{
+ Q_D(QDeclarativePinchArea);
+ if (!d->absorb || !isVisible())
+ return QDeclarativeItem::event(event);
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate: {
+ QTouchEvent *touch = static_cast<QTouchEvent*>(event);
+ d->touchPoints.clear();
+ for (int i = 0; i < touch->touchPoints().count(); ++i) {
+ if (!(touch->touchPoints().at(i).state() & Qt::TouchPointReleased)) {
+ d->touchPoints << touch->touchPoints().at(i);
+ }
+ }
+ updatePinch();
+ }
+ return true;
+ case QEvent::TouchEnd:
+ d->touchPoints.clear();
+ updatePinch();
+ break;
+ default:
+ return QDeclarativeItem::event(event);
+ }
+
+ return QDeclarativeItem::event(event);
+}
+
+void QDeclarativePinchArea::updatePinch()
+{
+ Q_D(QDeclarativePinchArea);
+ if (d->touchPoints.count() != 2) {
+ if (d->inPinch) {
+ d->stealMouse = false;
+ setKeepMouseGrab(false);
+ d->inPinch = false;
+ const qreal rotationAngle = d->pinchStartAngle - d->pinchLastAngle;
+ QPointF pinchCenter = mapFromScene(d->sceneLastCenter);
+ QDeclarativePinchEvent pe(pinchCenter, d->pinchLastScale, d->pinchLastAngle, rotationAngle);
+ pe.setStartCenter(d->pinchStartCenter);
+ pe.setLastCenter(pinchCenter);
+ pe.setLastAngle(d->pinchLastAngle);
+ pe.setLastScale(d->pinchLastScale);
+ pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
+ pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
+ pe.setPoint1(d->lastPoint1);
+ pe.setPoint2(d->lastPoint2);
+ emit pinchFinished(&pe);
+ if (d->pinch && d->pinch->target())
+ d->pinch->setActive(false);
+ }
+ return;
+ }
+ if (d->touchPoints.at(0).state() & Qt::TouchPointPressed
+ || d->touchPoints.at(1).state() & Qt::TouchPointPressed) {
+ d->sceneStartPoint1 = d->touchPoints.at(0).scenePos();
+ d->sceneStartPoint2 = d->touchPoints.at(1).scenePos();
+ d->inPinch = false;
+ d->pinchRejected = false;
+ } else if (!d->pinchRejected){
+ QDeclarativeItem *grabber = scene() ? qobject_cast<QDeclarativeItem*>(scene()->mouseGrabberItem()) : 0;
+ if (grabber == this || !grabber || !grabber->keepMouseGrab()) {
+ const int dragThreshold = QApplication::startDragDistance();
+ QPointF p1 = d->touchPoints.at(0).scenePos();
+ QPointF p2 = d->touchPoints.at(1).scenePos();
+ qreal dx = p1.x() - p2.x();
+ qreal dy = p1.y() - p2.y();
+ qreal dist = sqrt(dx*dx + dy*dy);
+ QPointF sceneCenter = (p1 + p2)/2;
+ qreal angle = QLineF(p1, p2).angle();
+ if (angle > 180)
+ angle -= 360;
+ if (!d->inPinch) {
+ if (qAbs(p1.x()-d->sceneStartPoint1.x()) > dragThreshold
+ || qAbs(p1.y()-d->sceneStartPoint1.y()) > dragThreshold
+ || qAbs(p2.x()-d->sceneStartPoint2.x()) > dragThreshold
+ || qAbs(p2.y()-d->sceneStartPoint2.y()) > dragThreshold) {
+ d->sceneStartCenter = sceneCenter;
+ d->sceneLastCenter = sceneCenter;
+ d->pinchStartCenter = mapFromScene(sceneCenter);
+ d->pinchStartDist = dist;
+ d->pinchStartAngle = angle;
+ d->pinchLastScale = 1.0;
+ d->pinchLastAngle = angle;
+ d->lastPoint1 = d->touchPoints.at(0).pos();
+ d->lastPoint2 = d->touchPoints.at(1).pos();
+ QDeclarativePinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0);
+ pe.setStartCenter(d->pinchStartCenter);
+ pe.setLastCenter(d->pinchStartCenter);
+ pe.setLastAngle(d->pinchLastAngle);
+ pe.setLastScale(d->pinchLastScale);
+ pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
+ pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
+ pe.setPoint1(d->lastPoint1);
+ pe.setPoint2(d->lastPoint2);
+ emit pinchStarted(&pe);
+ if (pe.accepted()) {
+ d->inPinch = true;
+ d->stealMouse = true;
+ grabMouse();
+ setKeepMouseGrab(true);
+ if (d->pinch && d->pinch->target()) {
+ d->pinchStartPos = pinch()->target()->pos();
+ d->pinchStartScale = d->pinch->target()->scale();
+ d->pinchStartRotation = d->pinch->target()->rotation();
+ d->pinch->setActive(true);
+ }
+ } else {
+ d->pinchRejected = true;
+ }
+ }
+ } else if (d->pinchStartDist > 0) {
+ qreal scale = dist / d->pinchStartDist;
+ qreal rotationAngle = d->pinchStartAngle - angle;
+ if (rotationAngle > 180)
+ rotationAngle -= 360;
+ QPointF pinchCenter = mapFromScene(sceneCenter);
+ QDeclarativePinchEvent pe(pinchCenter, scale, angle, rotationAngle);
+ pe.setStartCenter(d->pinchStartCenter);
+ pe.setLastCenter(mapFromScene(d->sceneLastCenter));
+ pe.setLastAngle(d->pinchLastAngle);
+ pe.setLastScale(d->pinchLastScale);
+ pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
+ pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
+ pe.setPoint1(d->touchPoints.at(0).pos());
+ pe.setPoint2(d->touchPoints.at(1).pos());
+ d->pinchLastScale = scale;
+ d->sceneLastCenter = sceneCenter;
+ d->pinchLastAngle = angle;
+ d->lastPoint1 = d->touchPoints.at(0).pos();
+ d->lastPoint2 = d->touchPoints.at(1).pos();
+ emit pinchChanged(&pe);
+ if (d->pinch && d->pinch->target()) {
+ qreal s = d->pinchStartScale * scale;
+ s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale());
+ pinch()->target()->setScale(s);
+ QPointF pos = sceneCenter - d->sceneStartCenter + d->pinchStartPos;
+ if (pinch()->axis() & QDeclarativePinch::XAxis) {
+ qreal x = pos.x();
+ if (x < pinch()->xmin())
+ x = pinch()->xmin();
+ else if (x > pinch()->xmax())
+ x = pinch()->xmax();
+ pinch()->target()->setX(x);
+ }
+ if (pinch()->axis() & QDeclarativePinch::YAxis) {
+ qreal y = pos.y();
+ if (y < pinch()->ymin())
+ y = pinch()->ymin();
+ else if (y > pinch()->ymax())
+ y = pinch()->ymax();
+ pinch()->target()->setY(y);
+ }
+ if (d->pinchStartRotation >= pinch()->minimumRotation()
+ && d->pinchStartRotation <= pinch()->maximumRotation()) {
+ qreal r = rotationAngle + d->pinchStartRotation;
+ r = qMin(qMax(pinch()->minimumRotation(),r), pinch()->maximumRotation());
+ pinch()->target()->setRotation(r);
+ }
+ }
+ }
+ }
+ }
+}
+
+void QDeclarativePinchArea::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QDeclarativePinchArea);
+ d->stealMouse = false;
+ if (!d->absorb)
+ QDeclarativeItem::mousePressEvent(event);
+ else {
+ setKeepMouseGrab(false);
+ event->setAccepted(true);
+ }
+}
+
+void QDeclarativePinchArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QDeclarativePinchArea);
+ if (!d->absorb) {
+ QDeclarativeItem::mouseMoveEvent(event);
+ return;
+ }
+}
+
+void QDeclarativePinchArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QDeclarativePinchArea);
+ d->stealMouse = false;
+ if (!d->absorb) {
+ QDeclarativeItem::mouseReleaseEvent(event);
+ } else {
+ QGraphicsScene *s = scene();
+ if (s && s->mouseGrabberItem() == this)
+ ungrabMouse();
+ setKeepMouseGrab(false);
+ }
+}
+
+bool QDeclarativePinchArea::sceneEvent(QEvent *event)
+{
+ bool rv = QDeclarativeItem::sceneEvent(event);
+ if (event->type() == QEvent::UngrabMouse) {
+ setKeepMouseGrab(false);
+ }
+ return rv;
+}
+
+bool QDeclarativePinchArea::sendMouseEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QDeclarativePinchArea);
+ QGraphicsSceneMouseEvent mouseEvent(event->type());
+ QRectF myRect = mapToScene(QRectF(0, 0, width(), height())).boundingRect();
+
+ QGraphicsScene *s = scene();
+ QDeclarativeItem *grabber = s ? qobject_cast<QDeclarativeItem*>(s->mouseGrabberItem()) : 0;
+ bool stealThisEvent = d->stealMouse;
+ if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) {
+ mouseEvent.setAccepted(false);
+ for (int i = 0x1; i <= 0x10; i <<= 1) {
+ if (event->buttons() & i) {
+ Qt::MouseButton button = Qt::MouseButton(i);
+ mouseEvent.setButtonDownPos(button, mapFromScene(event->buttonDownPos(button)));
+ }
+ }
+ mouseEvent.setScenePos(event->scenePos());
+ mouseEvent.setLastScenePos(event->lastScenePos());
+ mouseEvent.setPos(mapFromScene(event->scenePos()));
+ mouseEvent.setLastPos(mapFromScene(event->lastScenePos()));
+
+ switch(mouseEvent.type()) {
+ case QEvent::GraphicsSceneMouseMove:
+ mouseMoveEvent(&mouseEvent);
+ break;
+ case QEvent::GraphicsSceneMousePress:
+ mousePressEvent(&mouseEvent);
+ break;
+ case QEvent::GraphicsSceneMouseRelease:
+ mouseReleaseEvent(&mouseEvent);
+ break;
+ default:
+ break;
+ }
+ grabber = qobject_cast<QDeclarativeItem*>(s->mouseGrabberItem());
+ if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this)
+ grabMouse();
+
+ return stealThisEvent;
+ }
+ if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) {
+ d->stealMouse = false;
+ if (s && s->mouseGrabberItem() == this)
+ ungrabMouse();
+ setKeepMouseGrab(false);
+ }
+ return false;
+}
+
+bool QDeclarativePinchArea::sceneEventFilter(QGraphicsItem *i, QEvent *e)
+{
+ Q_D(QDeclarativePinchArea);
+ if (!d->absorb || !isVisible())
+ return QDeclarativeItem::sceneEventFilter(i, e);
+ switch (e->type()) {
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseMove:
+ case QEvent::GraphicsSceneMouseRelease:
+ return sendMouseEvent(static_cast<QGraphicsSceneMouseEvent *>(e));
+ break;
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate: {
+ QTouchEvent *touch = static_cast<QTouchEvent*>(e);
+ d->touchPoints.clear();
+ for (int i = 0; i < touch->touchPoints().count(); ++i)
+ if (!(touch->touchPoints().at(i).state() & Qt::TouchPointReleased))
+ d->touchPoints << touch->touchPoints().at(i);
+ updatePinch();
+ }
+ return d->inPinch;
+ case QEvent::TouchEnd:
+ d->touchPoints.clear();
+ updatePinch();
+ break;
+ default:
+ break;
+ }
+
+ return QDeclarativeItem::sceneEventFilter(i, e);
+}
+
+void QDeclarativePinchArea::geometryChanged(const QRectF &newGeometry,
+ const QRectF &oldGeometry)
+{
+ QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
+}
+
+QVariant QDeclarativePinchArea::itemChange(GraphicsItemChange change,
+ const QVariant &value)
+{
+ return QDeclarativeItem::itemChange(change, value);
+}
+
+QDeclarativePinch *QDeclarativePinchArea::pinch()
+{
+ Q_D(QDeclarativePinchArea);
+ if (!d->pinch)
+ d->pinch = new QDeclarativePinch;
+ return d->pinch;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativepincharea_p.h b/src/declarative/graphicsitems/qdeclarativepincharea_p.h
new file mode 100644
index 0000000..9a73a17
--- /dev/null
+++ b/src/declarative/graphicsitems/qdeclarativepincharea_p.h
@@ -0,0 +1,308 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEPINCHAREA_H
+#define QDECLARATIVEPINCHAREA_H
+
+#include <qdeclarativeitem.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class Q_AUTOTEST_EXPORT QDeclarativePinch : public QObject
+{
+ Q_OBJECT
+
+ Q_ENUMS(Axis)
+ Q_PROPERTY(QGraphicsObject *target READ target WRITE setTarget RESET resetTarget)
+ Q_PROPERTY(qreal minimumScale READ minimumScale WRITE setMinimumScale NOTIFY minimumScaleChanged)
+ Q_PROPERTY(qreal maximumScale READ maximumScale WRITE setMaximumScale NOTIFY maximumScaleChanged)
+ Q_PROPERTY(qreal minimumRotation READ minimumRotation WRITE setMinimumRotation NOTIFY minimumRotationChanged)
+ Q_PROPERTY(qreal maximumRotation READ maximumRotation WRITE setMaximumRotation NOTIFY maximumRotationChanged)
+ Q_PROPERTY(Axis dragAxis READ axis WRITE setAxis NOTIFY dragAxisChanged)
+ Q_PROPERTY(qreal minimumX READ xmin WRITE setXmin NOTIFY minimumXChanged)
+ Q_PROPERTY(qreal maximumX READ xmax WRITE setXmax NOTIFY maximumXChanged)
+ Q_PROPERTY(qreal minimumY READ ymin WRITE setYmin NOTIFY minimumYChanged)
+ Q_PROPERTY(qreal maximumY READ ymax WRITE setYmax NOTIFY maximumYChanged)
+ Q_PROPERTY(bool active READ active NOTIFY activeChanged)
+
+public:
+ QDeclarativePinch();
+
+ QGraphicsObject *target() const { return m_target; }
+ void setTarget(QGraphicsObject *target) {
+ if (target == m_target)
+ return;
+ m_target = target;
+ emit targetChanged();
+ }
+ void resetTarget() {
+ if (!m_target)
+ return;
+ m_target = 0;
+ emit targetChanged();
+ }
+
+ qreal minimumScale() const { return m_minScale; }
+ void setMinimumScale(qreal s) {
+ if (s == m_minScale)
+ return;
+ m_minScale = s;
+ emit minimumScaleChanged();
+ }
+ qreal maximumScale() const { return m_maxScale; }
+ void setMaximumScale(qreal s) {
+ if (s == m_maxScale)
+ return;
+ m_maxScale = s;
+ emit maximumScaleChanged();
+ }
+
+ qreal minimumRotation() const { return m_minRotation; }
+ void setMinimumRotation(qreal r) {
+ if (r == m_minRotation)
+ return;
+ m_minRotation = r;
+ emit minimumRotationChanged();
+ }
+ qreal maximumRotation() const { return m_maxRotation; }
+ void setMaximumRotation(qreal r) {
+ if (r == m_maxRotation)
+ return;
+ m_maxRotation = r;
+ emit maximumRotationChanged();
+ }
+
+ enum Axis { NoDrag=0x00, XAxis=0x01, YAxis=0x02, XandYAxis=0x03 };
+ Axis axis() const { return m_axis; }
+ void setAxis(Axis a) {
+ if (a == m_axis)
+ return;
+ m_axis = a;
+ emit dragAxisChanged();
+ }
+
+ qreal xmin() const { return m_xmin; }
+ void setXmin(qreal x) {
+ if (x == m_xmin)
+ return;
+ m_xmin = x;
+ emit minimumXChanged();
+ }
+ qreal xmax() const { return m_xmax; }
+ void setXmax(qreal x) {
+ if (x == m_xmax)
+ return;
+ m_xmax = x;
+ emit maximumXChanged();
+ }
+ qreal ymin() const { return m_ymin; }
+ void setYmin(qreal y) {
+ if (y == m_ymin)
+ return;
+ m_ymin = y;
+ emit minimumYChanged();
+ }
+ qreal ymax() const { return m_ymax; }
+ void setYmax(qreal y) {
+ if (y == m_ymax)
+ return;
+ m_ymax = y;
+ emit maximumYChanged();
+ }
+
+ bool active() const { return m_active; }
+ void setActive(bool a) {
+ if (a == m_active)
+ return;
+ m_active = a;
+ emit activeChanged();
+ }
+
+signals:
+ void targetChanged();
+ void minimumScaleChanged();
+ void maximumScaleChanged();
+ void minimumRotationChanged();
+ void maximumRotationChanged();
+ void dragAxisChanged();
+ void minimumXChanged();
+ void maximumXChanged();
+ void minimumYChanged();
+ void maximumYChanged();
+ void activeChanged();
+
+private:
+ QGraphicsObject *m_target;
+ qreal m_minScale;
+ qreal m_maxScale;
+ qreal m_minRotation;
+ qreal m_maxRotation;
+ Axis m_axis;
+ qreal m_xmin;
+ qreal m_xmax;
+ qreal m_ymin;
+ qreal m_ymax;
+ bool m_active;
+};
+
+class Q_AUTOTEST_EXPORT QDeclarativePinchEvent : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QPointF center READ center)
+ Q_PROPERTY(QPointF startCenter READ startCenter)
+ Q_PROPERTY(QPointF lastCenter READ lastCenter)
+ Q_PROPERTY(qreal scale READ scale)
+ Q_PROPERTY(qreal lastScale READ lastScale)
+ Q_PROPERTY(qreal angle READ angle)
+ Q_PROPERTY(qreal lastAngle READ lastAngle)
+ Q_PROPERTY(qreal rotation READ rotation)
+ Q_PROPERTY(QPointF point1 READ point1)
+ Q_PROPERTY(QPointF startPoint1 READ startPoint1)
+ Q_PROPERTY(QPointF point2 READ point2)
+ Q_PROPERTY(QPointF startPoint2 READ startPoint2)
+ Q_PROPERTY(bool accepted READ accepted WRITE setAccepted)
+
+public:
+ QDeclarativePinchEvent(QPointF c, qreal s, qreal a, qreal r)
+ : QObject(), m_center(c), m_scale(s), m_angle(a), m_rotation(r) {}
+
+ QPointF center() const { return m_center; }
+ QPointF startCenter() const { return m_startCenter; }
+ void setStartCenter(QPointF c) { m_startCenter = c; }
+ QPointF lastCenter() const { return m_lastCenter; }
+ void setLastCenter(QPointF c) { m_lastCenter = c; }
+ qreal scale() const { return m_scale; }
+ qreal lastScale() const { return m_lastScale; }
+ void setLastScale(qreal s) { m_lastScale = s; }
+ qreal angle() const { return m_angle; }
+ qreal lastAngle() const { return m_lastAngle; }
+ void setLastAngle(qreal a) { m_lastAngle = a; }
+ qreal rotation() const { return m_rotation; }
+ QPointF point1() const { return m_point1; }
+ void setPoint1(QPointF p) { m_point1 = p; }
+ QPointF startPoint1() const { return m_startPoint1; }
+ void setStartPoint1(QPointF p) { m_startPoint1 = p; }
+ QPointF point2() const { return m_point2; }
+ void setPoint2(QPointF p) { m_point2 = p; }
+ QPointF startPoint2() const { return m_startPoint2; }
+ void setStartPoint2(QPointF p) { m_startPoint2 = p; }
+
+ bool accepted() const { return m_accepted; }
+ void setAccepted(bool a) { m_accepted = a; }
+
+private:
+ QPointF m_center;
+ QPointF m_startCenter;
+ QPointF m_lastCenter;
+ qreal m_scale;
+ qreal m_lastScale;
+ qreal m_angle;
+ qreal m_lastAngle;
+ qreal m_rotation;
+ QPointF m_point1;
+ QPointF m_point2;
+ QPointF m_startPoint1;
+ QPointF m_startPoint2;
+ bool m_accepted;
+};
+
+
+class QDeclarativeMouseEvent;
+class QDeclarativePinchAreaPrivate;
+class Q_AUTOTEST_EXPORT QDeclarativePinchArea : public QDeclarativeItem
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
+ Q_PROPERTY(QDeclarativePinch *pinch READ pinch CONSTANT)
+
+public:
+ QDeclarativePinchArea(QDeclarativeItem *parent=0);
+ ~QDeclarativePinchArea();
+
+ bool isEnabled() const;
+ void setEnabled(bool);
+
+ QDeclarativePinch *pinch();
+
+Q_SIGNALS:
+ void enabledChanged();
+ void pinchStarted(QDeclarativePinchEvent *pinch);
+ void pinchChanged(QDeclarativePinchEvent *pinch);
+ void pinchFinished(QDeclarativePinchEvent *pinch);
+
+protected:
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ bool sceneEvent(QEvent *);
+ bool sendMouseEvent(QGraphicsSceneMouseEvent *event);
+ bool sceneEventFilter(QGraphicsItem *i, QEvent *e);
+ bool event(QEvent *);
+
+ virtual void geometryChanged(const QRectF &newGeometry,
+ const QRectF &oldGeometry);
+ virtual QVariant itemChange(GraphicsItemChange change, const QVariant& value);
+
+private:
+ void updatePinch();
+ void handlePress();
+ void handleRelease();
+
+private:
+ Q_DISABLE_COPY(QDeclarativePinchArea)
+ Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativePinchArea)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QDeclarativePinch)
+QML_DECLARE_TYPE(QDeclarativePinchEvent)
+QML_DECLARE_TYPE(QDeclarativePinchArea)
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEPINCHAREA_H
diff --git a/src/declarative/graphicsitems/qdeclarativepincharea_p_p.h b/src/declarative/graphicsitems/qdeclarativepincharea_p_p.h
new file mode 100644
index 0000000..b1cdf68
--- /dev/null
+++ b/src/declarative/graphicsitems/qdeclarativepincharea_p_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEPINCHAREA_P_H
+#define QDECLARATIVEPINCHAREA_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qdatetime.h>
+#include <qbasictimer.h>
+#include <qevent.h>
+#include <qgraphicssceneevent.h>
+#include "qdeclarativeitem_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativePinch;
+class QDeclarativePinchAreaPrivate : public QDeclarativeItemPrivate
+{
+ Q_DECLARE_PUBLIC(QDeclarativePinchArea)
+public:
+ QDeclarativePinchAreaPrivate()
+ : absorb(true), stealMouse(false), inPinch(false)
+ , pinchRejected(false), pinch(0)
+ {
+ }
+
+ ~QDeclarativePinchAreaPrivate();
+
+ void init()
+ {
+ Q_Q(QDeclarativePinchArea);
+ q->setAcceptedMouseButtons(Qt::LeftButton);
+ q->setAcceptTouchEvents(true);
+ q->setFiltersChildEvents(true);
+ }
+
+ bool absorb : 1;
+ bool stealMouse : 1;
+ bool inPinch : 1;
+ bool pinchRejected : 1;
+ QDeclarativePinch *pinch;
+ QPointF sceneStartPoint1;
+ QPointF sceneStartPoint2;
+ QPointF lastPoint1;
+ QPointF lastPoint2;
+ qreal pinchStartDist;
+ qreal pinchStartScale;
+ qreal pinchLastScale;
+ qreal pinchStartRotation;
+ qreal pinchStartAngle;
+ qreal pinchLastAngle;
+ QPointF sceneStartCenter;
+ QPointF pinchStartCenter;
+ QPointF sceneLastCenter;
+ QPointF pinchStartPos;
+ QList<QTouchEvent::TouchPoint> touchPoints;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVEPINCHAREA_P_H
diff --git a/src/declarative/graphicsitems/qdeclarativerepeater.cpp b/src/declarative/graphicsitems/qdeclarativerepeater.cpp
index 6f46c7b..fa684c1 100644
--- a/src/declarative/graphicsitems/qdeclarativerepeater.cpp
+++ b/src/declarative/graphicsitems/qdeclarativerepeater.cpp
@@ -84,43 +84,23 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate()
\image repeater-simple.png
- The \l model of a Repeater can be any of the supported \l {qmlmodels}{Data Models}.
+ A Repeater's \l model can be any of the supported \l {qmlmodels}{data models}.
+ Additionally, like delegates for other views, a Repeater delegate can access
+ its index within the repeater, as well as the model data relevant to the
+ delegate. See the \l delegate property documentation for details.
Items instantiated by the Repeater are inserted, in order, as
children of the Repeater's parent. The insertion starts immediately after
the repeater's position in its parent stacking list. This allows
a Repeater to be used inside a layout. For example, the following Repeater's
items are stacked between a red rectangle and a blue rectangle:
-
+
\snippet doc/src/snippets/declarative/repeaters/repeater.qml layout
\image repeater.png
- \section2 The \c index and \c modelData properties
-
- The index of a delegate is exposed as an accessible \c index property in the delegate.
- Properties of the model are also available depending upon the type of \l {qmlmodels}{Data Model}.
-
- Here is a Repeater that uses the \c index property inside the instantiated items:
-
- \table
- \row
- \o \snippet doc/src/snippets/declarative/repeaters/repeater.qml index
- \o \image repeater-index.png
- \endtable
-
- Here is another Repeater that uses the \c modelData property to reference the data for a
- particular index:
-
- \table
- \row
- \o \snippet doc/src/snippets/declarative/repeaters/repeater.qml modeldata
- \o \image repeater-modeldata.png
- \endtable
-
-
- A Repeater item owns all items it instantiates. Removing or dynamically destroying
+ \note A Repeater item owns all items it instantiates. Removing or dynamically destroying
an item created by a Repeater results in unpredictable behavior.
@@ -146,6 +126,27 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate()
\endcode
*/
+/*!
+ \qmlsignal Repeater::onItemAdded(int index, Item item)
+ \since Quick 1.1
+
+ This handler is called when an item is added to the repeater. The \a index
+ parameter holds the index at which the item has been inserted within the
+ repeater, and the \a item parameter holds the \l Item that has been added.
+*/
+
+/*!
+ \qmlsignal Repeater::onItemRemoved(int index, Item item)
+ \since Quick 1.1
+
+ This handler is called when an item is removed from the repeater. The \a index
+ parameter holds the index at which the item was removed from the repeater,
+ and the \a item parameter holds the \l Item that was removed.
+
+ Do not keep a reference to \a item if it was created by this repeater, as
+ in these cases it will be deleted shortly after the handler is called.
+*/
+
QDeclarativeRepeater::QDeclarativeRepeater(QDeclarativeItem *parent)
: QDeclarativeItem(*(new QDeclarativeRepeaterPrivate), parent)
{
@@ -160,26 +161,16 @@ QDeclarativeRepeater::~QDeclarativeRepeater()
The model providing data for the repeater.
- This property can be set to any of the following:
+ This property can be set to any of the supported \l {qmlmodels}{data models}:
\list
- \o A number that indicates the number of delegates to be created
+ \o A number that indicates the number of delegates to be created by the repeater
\o A model (e.g. a ListModel item, or a QAbstractItemModel subclass)
\o A string list
\o An object list
\endlist
- In each case, the data element and the index is exposed to each instantiated
- component. The index is always exposed as an accessible \c index property.
- In the case of an object or string list, the data element (of type string
- or object) is available as the \c modelData property. In the case of a Qt model,
- all roles are available as named properties just like in the view classes.
-
- As a special case the model can also be merely a number. In this case it will
- create that many instances of the component. They will also be assigned an index
- based on the order they are created.
-
- Models can also be created directly in QML, using a \l{ListModel} or \l{XmlListModel}.
+ The type of model affects the properties that are exposed to the \l delegate.
\sa {qmlmodels}{Data Models}
*/
@@ -243,8 +234,33 @@ void QDeclarativeRepeater::setModel(const QVariant &model)
\default
The delegate provides a template defining each item instantiated by the repeater.
- The index is exposed as an accessible \c index property. Properties of the
- model are also available depending upon the type of \l {qmlmodels}{Data Model}.
+
+ Delegates are exposed to a read-only \c index property that indicates the index
+ of the delegate within the repeater. For example, the following \l Text delegate
+ displays the index of each repeated item:
+
+ \table
+ \row
+ \o \snippet doc/src/snippets/declarative/repeaters/repeater.qml index
+ \o \image repeater-index.png
+ \endtable
+
+ If the \l model is a \l{QStringList-based model}{string list} or
+ \l{QObjectList-based model}{object list}, the delegate is also exposed to
+ a read-only \c modelData property that holds the string or object data. For
+ example:
+
+ \table
+ \row
+ \o \snippet doc/src/snippets/declarative/repeaters/repeater.qml modeldata
+ \o \image repeater-modeldata.png
+ \endtable
+
+ If the \l model is a model object (such as a \l ListModel) the delegate
+ can access all model roles as named properties, in the same way that delegates
+ do for view classes like ListView.
+
+ \sa {QML Data Models}
*/
QDeclarativeComponent *QDeclarativeRepeater::delegate() const
{
@@ -288,6 +304,21 @@ int QDeclarativeRepeater::count() const
return 0;
}
+/*!
+ \qmlmethod Item Repeater::itemAt(index)
+ \since Quick 1.1
+
+ Returns the \l Item that has been created at the given \a index, or \c null
+ if no item exists at \a index.
+*/
+QDeclarativeItem *QDeclarativeRepeater::itemAt(int index) const
+{
+ Q_D(const QDeclarativeRepeater);
+ if (index >= 0 && index < d->deletables.count())
+ return d->deletables[index];
+ return 0;
+
+}
void QDeclarativeRepeater::componentComplete()
{
@@ -309,8 +340,13 @@ QVariant QDeclarativeRepeater::itemChange(GraphicsItemChange change,
void QDeclarativeRepeater::clear()
{
Q_D(QDeclarativeRepeater);
+ bool complete = isComponentComplete();
+
if (d->model) {
- foreach (QDeclarativeItem *item, d->deletables) {
+ while (d->deletables.count() > 0) {
+ QDeclarativeItem *item = d->deletables.takeLast();
+ if (complete)
+ emit itemRemoved(d->deletables.count()-1, item);
d->model->release(item);
}
}
@@ -335,6 +371,7 @@ void QDeclarativeRepeater::regenerate()
item->setParentItem(parentItem());
item->stackBefore(this);
d->deletables << item;
+ emit itemAdded(ii, item);
}
}
}
@@ -355,6 +392,7 @@ void QDeclarativeRepeater::itemsInserted(int index, int count)
else
item->stackBefore(this);
d->deletables.insert(modelIndex, item);
+ emit itemAdded(modelIndex, item);
}
}
emit countChanged();
@@ -367,6 +405,7 @@ void QDeclarativeRepeater::itemsRemoved(int index, int count)
return;
while (count--) {
QDeclarativeItem *item = d->deletables.takeAt(index);
+ emit itemRemoved(index, item);
if (item)
d->model->release(item);
else
diff --git a/src/declarative/graphicsitems/qdeclarativerepeater_p.h b/src/declarative/graphicsitems/qdeclarativerepeater_p.h
index ff58fa0..62552a6 100644
--- a/src/declarative/graphicsitems/qdeclarativerepeater_p.h
+++ b/src/declarative/graphicsitems/qdeclarativerepeater_p.h
@@ -72,10 +72,16 @@ public:
int count() const;
+ Q_INVOKABLE Q_REVISION(1) QDeclarativeItem *itemAt(int index) const;
+
Q_SIGNALS:
void modelChanged();
void delegateChanged();
void countChanged();
+
+ Q_REVISION(1) void itemAdded(int index, QDeclarativeItem *item);
+ Q_REVISION(1) void itemRemoved(int index, QDeclarativeItem *item);
+
private:
void clear();
void regenerate();
diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp
index 303b21c..cf11be6 100644
--- a/src/declarative/graphicsitems/qdeclarativetext.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetext.cpp
@@ -297,6 +297,8 @@ QSize QDeclarativeTextPrivate::setupTextLayout()
lineWidth = q->width();
QTextOption textOption = layout.textOption();
+ if (hAlign == QDeclarativeText::AlignJustify)
+ textOption.setAlignment(Qt::Alignment(hAlign));
textOption.setWrapMode(QTextOption::WrapMode(wrapMode));
layout.setTextOption(textOption);
@@ -325,7 +327,7 @@ QSize QDeclarativeTextPrivate::setupTextLayout()
height += line.height();
if (!cacheAllTextAsImage) {
- if (hAlign == QDeclarativeText::AlignLeft) {
+ if ((hAlign == QDeclarativeText::AlignLeft) || (hAlign == QDeclarativeText::AlignJustify)) {
x = 0;
} else if (hAlign == QDeclarativeText::AlignRight) {
x = layoutWidth - line.naturalTextWidth();
@@ -351,7 +353,7 @@ QPixmap QDeclarativeTextPrivate::textLayoutImage(bool drawStyle)
qreal x = 0;
for (int i = 0; i < layout.lineCount(); ++i) {
QTextLine line = layout.lineAt(i);
- if (hAlign == QDeclarativeText::AlignLeft) {
+ if ((hAlign == QDeclarativeText::AlignLeft) || (hAlign == QDeclarativeText::AlignJustify)) {
x = 0;
} else if (hAlign == QDeclarativeText::AlignRight) {
x = size.width() - line.naturalTextWidth();
@@ -898,8 +900,8 @@ void QDeclarativeText::setStyleColor(const QColor &color)
Sets the horizontal and vertical alignment of the text within the Text items
width and height. By default, the text is top-left aligned.
- The valid values for \c horizontalAlignment are \c Text.AlignLeft, \c Text.AlignRight and
- \c Text.AlignHCenter. The valid values for \c verticalAlignment are \c Text.AlignTop, \c Text.AlignBottom
+ The valid values for \c horizontalAlignment are \c Text.AlignLeft, \c Text.AlignRight, \c Text.AlignHCenter and
+ \c Text.AlignJustify. The valid values for \c verticalAlignment are \c Text.AlignTop, \c Text.AlignBottom
and \c Text.AlignVCenter.
Note that for a single line of text, the size of the text is the area of the text. In this common case,
@@ -1117,6 +1119,7 @@ QRectF QDeclarativeText::boundingRect() const
switch (d->hAlign) {
case AlignLeft:
+ case AlignJustify:
x = 0;
break;
case AlignRight:
diff --git a/src/declarative/graphicsitems/qdeclarativetext_p.h b/src/declarative/graphicsitems/qdeclarativetext_p.h
index 51434d5..49bff14 100644
--- a/src/declarative/graphicsitems/qdeclarativetext_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetext_p.h
@@ -82,7 +82,8 @@ public:
enum HAlignment { AlignLeft = Qt::AlignLeft,
AlignRight = Qt::AlignRight,
- AlignHCenter = Qt::AlignHCenter };
+ AlignHCenter = Qt::AlignHCenter,
+ AlignJustify = Qt::AlignJustify }; // ### VERSIONING: Only in QtQuick 1.1
enum VAlignment { AlignTop = Qt::AlignTop,
AlignBottom = Qt::AlignBottom,
AlignVCenter = Qt::AlignVCenter };
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
index 4e16d24..b76a70c 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
@@ -442,6 +442,7 @@ void QDeclarativeTextEdit::setSelectedTextColor(const QColor &color)
\o TextEdit.AlignLeft (default)
\o TextEdit.AlignRight
\o TextEdit.AlignHCenter
+ \o TextEdit.AlignJustify
\endlist
Valid values for \c verticalAlignment are:
@@ -997,6 +998,19 @@ void QDeclarativeTextEditPrivate::focusChanged(bool hasFocus)
}
/*!
+ \qmlmethod void TextEdit::deselect()
+
+ Removes active text selection.
+*/
+void QDeclarativeTextEdit::deselect()
+{
+ Q_D(QDeclarativeTextEdit);
+ QTextCursor c = d->control->textCursor();
+ c.clearSelection();
+ d->control->setTextCursor(c);
+}
+
+/*!
\qmlmethod void TextEdit::selectAll()
Causes all text to be selected.
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p.h
index 68fde3d..691d995 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextedit_p.h
@@ -97,7 +97,8 @@ public:
enum HAlignment {
AlignLeft = Qt::AlignLeft,
AlignRight = Qt::AlignRight,
- AlignHCenter = Qt::AlignHCenter
+ AlignHCenter = Qt::AlignHCenter,
+ AlignJustify = Qt::AlignJustify // ### VERSIONING: Only in QtQuick 1.1
};
enum VAlignment {
@@ -222,6 +223,7 @@ Q_SIGNALS:
void selectByMouseChanged(bool selectByMouse);
public Q_SLOTS:
+ void deselect();
void selectAll();
void selectWord();
void select(int start, int end);
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index 521e4ab..ac07d4b 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
@@ -361,6 +361,14 @@ void QDeclarativeTextInput::setReadOnly(bool ro)
emit readOnlyChanged(ro);
}
+/*!
+ \qmlproperty int TextInput::maximumLength
+ The maximum permitted length of the text in the TextInput.
+
+ If the text is too long, it is truncated at the limit.
+
+ By default, this property contains a value of 32767.
+*/
int QDeclarativeTextInput::maxLength() const
{
Q_D(const QDeclarativeTextInput);
@@ -1160,6 +1168,17 @@ QVariant QDeclarativeTextInput::inputMethodQuery(Qt::InputMethodQuery property)
}
/*!
+ \qmlmethod void TextInput::deselect()
+
+ Removes active text selection.
+*/
+void QDeclarativeTextInput::deselect()
+{
+ Q_D(QDeclarativeTextInput);
+ d->control->deselect();
+}
+
+/*!
\qmlmethod void TextInput::selectAll()
Causes all text to be selected.
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h
index 06f77e5..878f040 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h
@@ -231,6 +231,7 @@ protected:
void focusInEvent(QFocusEvent *event);
public Q_SLOTS:
+ void deselect();
void selectAll();
void selectWord();
void select(int start, int end);
diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
index bf9263b..a5fae36 100644
--- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
+++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
@@ -557,8 +557,9 @@ QDeclarativeVisualDataModelData::~QDeclarativeVisualDataModelData()
void QDeclarativeVisualDataModelData::ensureProperties()
{
QDeclarativeVisualDataModelPrivate *modelPriv = QDeclarativeVisualDataModelPrivate::get(m_model);
- if (modelPriv->m_metaDataCacheable && !modelPriv->m_metaDataCreated) {
- modelPriv->createMetaData();
+ if (modelPriv->m_metaDataCacheable) {
+ if (!modelPriv->m_metaDataCreated)
+ modelPriv->createMetaData();
if (modelPriv->m_metaDataCreated)
m_meta->setCached(true);
}
diff --git a/src/declarative/qml/qdeclarative.h b/src/declarative/qml/qdeclarative.h
index f0c62f4..8a6d068 100644
--- a/src/declarative/qml/qdeclarative.h
+++ b/src/declarative/qml/qdeclarative.h
@@ -113,6 +113,7 @@ int qmlRegisterType()
0, 0,
+ 0,
0
};
@@ -148,6 +149,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
0, 0,
+ 0,
0
};
@@ -181,12 +183,82 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c
0, 0,
+ 0,
0
};
return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type);
}
+template<typename T, int metaObjectRevision>
+int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
+{
+ QByteArray name(T::staticMetaObject.className());
+
+ QByteArray pointerName(name + '*');
+ QByteArray listName("QDeclarativeListProperty<" + name + ">");
+
+ QDeclarativePrivate::RegisterType type = {
+ 1,
+
+ qRegisterMetaType<T *>(pointerName.constData()),
+ qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
+ sizeof(T), QDeclarativePrivate::createInto<T>,
+ QString(),
+
+ uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
+
+ QDeclarativePrivate::attachedPropertiesFunc<T>(),
+ QDeclarativePrivate::attachedPropertiesMetaObject<T>(),
+
+ QDeclarativePrivate::StaticCastSelector<T,QDeclarativeParserStatus>::cast(),
+ QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueSource>::cast(),
+ QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueInterceptor>::cast(),
+
+ 0, 0,
+
+ 0,
+ metaObjectRevision
+ };
+
+ return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type);
+}
+
+template<typename T, int metaObjectRevision>
+int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
+{
+ QByteArray name(T::staticMetaObject.className());
+
+ QByteArray pointerName(name + '*');
+ QByteArray listName("QDeclarativeListProperty<" + name + ">");
+
+ QDeclarativePrivate::RegisterType type = {
+ 1,
+
+ qRegisterMetaType<T *>(pointerName.constData()),
+ qRegisterMetaType<QDeclarativeListProperty<T> >(listName.constData()),
+ sizeof(T), QDeclarativePrivate::createInto<T>,
+ QString(),
+
+ uri, versionMajor, versionMinor, 0, &T::staticMetaObject,
+
+ QDeclarativePrivate::attachedPropertiesFunc<T>(),
+ QDeclarativePrivate::attachedPropertiesMetaObject<T>(),
+
+ QDeclarativePrivate::StaticCastSelector<T,QDeclarativeParserStatus>::cast(),
+ QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueSource>::cast(),
+ QDeclarativePrivate::StaticCastSelector<T,QDeclarativePropertyValueInterceptor>::cast(),
+
+ 0, 0,
+
+ 0,
+ metaObjectRevision
+ };
+
+ return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type);
+}
+
+
template<typename T, typename E>
int qmlRegisterExtendedType()
{
@@ -214,6 +286,7 @@ int qmlRegisterExtendedType()
QDeclarativePrivate::createParent<E>, &E::staticMetaObject,
+ 0,
0
};
@@ -255,6 +328,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
QDeclarativePrivate::createParent<E>, &E::staticMetaObject,
+ 0,
0
};
@@ -309,7 +383,8 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
0, 0,
- parser
+ parser,
+ 0
};
return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type);
diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp
index a7fbf44..223d057 100644
--- a/src/declarative/qml/qdeclarativebinding.cpp
+++ b/src/declarative/qml/qdeclarativebinding.cpp
@@ -46,9 +46,11 @@
#include "qdeclarativecontext.h"
#include "qdeclarativeinfo.h"
#include "private/qdeclarativecontext_p.h"
+#include "private/qdeclarativecompiler_p.h"
#include "private/qdeclarativedata_p.h"
#include "private/qdeclarativestringconverters_p.h"
#include "private/qdeclarativestate_p_p.h"
+#include "private/qdeclarativedebugtrace_p.h"
#include <QVariant>
#include <QtCore/qdebug.h>
@@ -207,6 +209,8 @@ void QDeclarativeAbstractBinding::setEnabled(bool enabled, QDeclarativePropertyP
if (enabled) update(flags);
}
+QDeclarativeBinding::Identifier QDeclarativeBinding::Invalid = -1;
+
void QDeclarativeBindingPrivate::refresh()
{
Q_Q(QDeclarativeBinding);
@@ -232,6 +236,22 @@ QDeclarativeBinding::QDeclarativeBinding(void *data, QDeclarativeRefCount *rc, Q
setNotifyOnValueChanged(true);
}
+QDeclarativeBinding *
+QDeclarativeBinding::createBinding(Identifier id, QObject *obj, QDeclarativeContext *ctxt,
+ const QString &url, int lineNumber, QObject *parent)
+{
+ if (id < 0)
+ return 0;
+
+ QDeclarativeContextData *ctxtdata = QDeclarativeContextData::get(ctxt);
+
+ QDeclarativeEnginePrivate *engine = QDeclarativeEnginePrivate::get(qmlEngine(obj));
+ QDeclarativeCompiledData *cdata = 0;
+ if (engine && ctxtdata && !ctxtdata->url.isEmpty())
+ cdata = engine->typeLoader.get(ctxtdata->url)->compiledData();
+ return cdata ? new QDeclarativeBinding((void*)cdata->datas.at(id).constData(), cdata, obj, ctxtdata, url, lineNumber, parent) : 0;
+}
+
QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDeclarativeContext *ctxt,
QObject *parent)
: QDeclarativeExpression(QDeclarativeContextData::get(ctxt), obj, str, *new QDeclarativeBindingPrivate)
@@ -266,6 +286,20 @@ QDeclarativeProperty QDeclarativeBinding::property() const
return d->property;
}
+class QDeclarativeBindingProfiler {
+public:
+ QDeclarativeBindingProfiler(QDeclarativeBinding *bind)
+ {
+ QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Binding);
+ QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Binding, bind->expression());
+ }
+
+ ~QDeclarativeBindingProfiler()
+ {
+ QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Binding);
+ }
+};
+
void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
{
Q_D(QDeclarativeBinding);
@@ -274,6 +308,7 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
return;
if (!d->updating) {
+ QDeclarativeBindingProfiler prof(this);
d->updating = true;
bool wasDeleted = false;
d->deleted = &wasDeleted;
diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h
index 7823a3d..69931d9 100644
--- a/src/declarative/qml/qdeclarativebinding_p.h
+++ b/src/declarative/qml/qdeclarativebinding_p.h
@@ -162,6 +162,10 @@ public:
virtual void update(QDeclarativePropertyPrivate::WriteFlags flags);
virtual QString expression() const;
+ typedef int Identifier;
+ static Identifier Invalid;
+ static QDeclarativeBinding *createBinding(Identifier, QObject *, QDeclarativeContext *, const QString &, int, QObject *parent=0);
+
public Q_SLOTS:
void update() { update(QDeclarativePropertyPrivate::DontRemoveBinding); }
diff --git a/src/declarative/qml/qdeclarativeboundsignal.cpp b/src/declarative/qml/qdeclarativeboundsignal.cpp
index 6af3e05..030fb2c 100644
--- a/src/declarative/qml/qdeclarativeboundsignal.cpp
+++ b/src/declarative/qml/qdeclarativeboundsignal.cpp
@@ -49,6 +49,7 @@
#include "qdeclarative.h"
#include "qdeclarativecontext.h"
#include "private/qdeclarativeglobal_p.h"
+#include "private/qdeclarativedebugtrace_p.h"
#include <QtCore/qdebug.h>
@@ -165,6 +166,8 @@ QDeclarativeBoundSignal *QDeclarativeBoundSignal::cast(QObject *o)
int QDeclarativeBoundSignal::qt_metacall(QMetaObject::Call c, int id, void **a)
{
if (c == QMetaObject::InvokeMetaMethod && id == evaluateIdx) {
+ QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::HandlingSignal);
+ QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::HandlingSignal, QLatin1String(m_signal.signature()) + QLatin1String(": ") + (m_expression ? m_expression->expression() : ""));
m_isEvaluating = true;
if (!m_paramsValid) {
if (!m_signal.parameterTypes().isEmpty())
@@ -180,6 +183,7 @@ int QDeclarativeBoundSignal::qt_metacall(QMetaObject::Call c, int id, void **a)
}
if (m_params) m_params->clearValues();
m_isEvaluating = false;
+ QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::HandlingSignal);
return -1;
} else {
return QObject::qt_metacall(c, id, a);
diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp
index 5c295b9..619016b 100644
--- a/src/declarative/qml/qdeclarativecompiledbindings.cpp
+++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp
@@ -54,6 +54,7 @@
#include <private/qdeclarativeanchors_p_p.h>
#include <private/qdeclarativeglobal_p.h>
#include <private/qdeclarativefastproperties_p.h>
+#include <private/qdeclarativedebugtrace_p.h>
QT_BEGIN_NAMESPACE
@@ -302,7 +303,9 @@ void QDeclarativeCompiledBindingsPrivate::Binding::setEnabled(bool e, QDeclarati
void QDeclarativeCompiledBindingsPrivate::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags)
{
+ QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Binding);
parent->run(this, flags);
+ QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Binding);
}
void QDeclarativeCompiledBindingsPrivate::Binding::destroy()
@@ -2524,6 +2527,10 @@ bool QDeclarativeBindingCompilerPrivate::fetch(Result &rv, const QMetaObject *mo
rv.metaObject = 0;
rv.type = 0;
+ //XXX binding optimizer doesn't handle properties with a revision
+ if (prop.revision() > 0)
+ return false;
+
int fastFetchIndex = fastProperties()->accessorIndexForProperty(mo, idx);
Instr fetch;
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index df428b1..0c56165 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -902,6 +902,7 @@ void QDeclarativeCompiler::genObject(QDeclarativeParser::Object *obj)
create.line = obj->location.start.line;
create.createSimple.create = output->types.at(obj->type).type->createFunction();
create.createSimple.typeSize = output->types.at(obj->type).type->createSize();
+ create.createSimple.type = obj->type;
create.createSimple.column = obj->location.start.column;
output->bytecode << create;
@@ -1351,7 +1352,8 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl
if(name[0] >= 'A' && name[0] <= 'Z')
name[0] = name[0] - 'A' + 'a';
- int sigIdx = QDeclarativePropertyPrivate::findSignalByName(obj->metaObject(), name).methodIndex();
+ QMetaMethod method = QDeclarativePropertyPrivate::findSignalByName(obj->metaObject(), name);
+ int sigIdx = method.methodIndex();
if (sigIdx == -1) {
@@ -1364,6 +1366,13 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl
if (prop->value || prop->values.count() != 1)
COMPILE_EXCEPTION(prop, tr("Incorrectly specified signal assignment"));
+ if (method.revision() > 0) {
+ QDeclarativeType *type = output->types.at(obj->type).type;
+ if (!type->isMethodAvailable(sigIdx, method.revision())) {
+ COMPILE_EXCEPTION(prop, tr("Signal \"%1\" not available in %2 %3.%4").arg(QString::fromUtf8(prop->name)).arg(QString::fromUtf8(type->qmlTypeName())).arg(obj->majorVersion).arg(obj->minorVersion));
+ }
+ }
+
prop->index = sigIdx;
obj->addSignalProperty(prop);
@@ -1481,6 +1490,12 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
// successful index resolution
if (p.name()) {
prop->type = p.userType();
+ if (p.revision() > 0) {
+ QDeclarativeType *type = output->types.at(obj->type).type;
+ if (!type->isPropertyAvailable(prop->index, p.revision())) {
+ COMPILE_EXCEPTION(prop, tr("Property \"%1\" not available in %2 %3.%4").arg(QString::fromUtf8(prop->name)).arg(QString::fromUtf8(type->qmlTypeName())).arg(obj->majorVersion).arg(obj->minorVersion));
+ }
+ }
}
// Check if this is an alias
@@ -1894,14 +1909,22 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
COMPILE_EXCEPTION(prop, tr("Unexpected object assignment"));
} else if (value->value.isScript()) {
// ### Check for writability
- BindingReference reference;
- reference.expression = value->value;
- reference.property = prop;
- reference.value = value;
- reference.bindingContext = ctxt;
- reference.bindingContext.owner++;
- addBindingReference(reference);
- value->type = Value::PropertyBinding;
+
+ //optimization for <Type>.<EnumValue> enum assignments
+ bool isEnumAssignment = false;
+ COMPILE_CHECK(testQualifiedEnumAssignment(p, obj, value, &isEnumAssignment));
+ if (isEnumAssignment) {
+ value->type = Value::Literal;
+ } else {
+ BindingReference reference;
+ reference.expression = value->value;
+ reference.property = prop;
+ reference.value = value;
+ reference.bindingContext = ctxt;
+ reference.bindingContext.owner++;
+ addBindingReference(reference);
+ value->type = Value::PropertyBinding;
+ }
} else {
COMPILE_CHECK(testLiteralAssignment(p, value));
value->type = Value::Literal;
@@ -2196,7 +2219,15 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop
QDeclarativeType *type = 0;
unit->imports().resolveType(typeName.toUtf8(), &type, 0, 0, 0, 0);
- if (!type || obj->typeName != type->qmlTypeName())
+ //handle enums on value types (where obj->typeName is empty)
+ QByteArray objTypeName = obj->typeName;
+ if (objTypeName.isEmpty()) {
+ QDeclarativeType *objType = toQmlType(obj);
+ if (objType)
+ objTypeName = objType->qmlTypeName();
+ }
+
+ if (!type || objTypeName != type->qmlTypeName())
return true;
QString enumValue = parts.at(1);
@@ -2246,6 +2277,35 @@ const QMetaObject *QDeclarativeCompiler::resolveType(const QByteArray& name) con
return qmltype->metaObject();
}
+// similar to logic of completeComponentBuild, but also sticks data
+// into datas at the end
+int QDeclarativeCompiler::rewriteBinding(const QString& expression, const QByteArray& name)
+{
+ QDeclarativeRewrite::RewriteBinding rewriteBinding;
+ rewriteBinding.setName('$' + name.mid(name.lastIndexOf('.') + 1));
+ bool isSharable = false;
+ QString rewrite = rewriteBinding(expression, 0, &isSharable);
+
+ quint32 length = rewrite.length();
+ quint32 pc;
+
+ if (isSharable) {
+ pc = output->cachedClosures.count();
+ pc |= 0x80000000;
+ output->cachedClosures.append(0);
+ } else {
+ pc = output->cachedPrograms.length();
+ output->cachedPrograms.append(0);
+ }
+
+ QByteArray compiledData =
+ QByteArray((const char *)&pc, sizeof(quint32)) +
+ QByteArray((const char *)&length, sizeof(quint32)) +
+ QByteArray((const char *)rewrite.constData(),
+ rewrite.length() * sizeof(QChar));
+
+ return output->indexForByteArray(compiledData);
+}
// Ensures that the dynamic meta specification on obj is valid
bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj)
@@ -2849,13 +2909,10 @@ bool QDeclarativeCompiler::completeComponentBuild()
// Pre-rewrite the expression
QString expression = binding.expression.asScript();
- // ### Optimize
- QDeclarativeRewrite::SharedBindingTester sharableTest;
- bool isSharable = sharableTest.isSharable(expression);
-
QDeclarativeRewrite::RewriteBinding rewriteBinding;
rewriteBinding.setName('$'+binding.property->name);
- expression = rewriteBinding(expression);
+ bool isSharable = false;
+ expression = rewriteBinding(binding.expression.asAST(), expression, &isSharable);
quint32 length = expression.length();
quint32 pc;
diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h
index 7d76ad9..bface8f 100644
--- a/src/declarative/qml/qdeclarativecompiler_p.h
+++ b/src/declarative/qml/qdeclarativecompiler_p.h
@@ -161,6 +161,7 @@ public:
int evaluateEnum(const QByteArray& script) const; // for QDeclarativeCustomParser::evaluateEnum
const QMetaObject *resolveType(const QByteArray& name) const; // for QDeclarativeCustomParser::resolveType
+ int rewriteBinding(const QString& expression, const QByteArray& name); // for QDeclarativeCustomParser::rewriteBinding
private:
static void reset(QDeclarativeCompiledData *);
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index ecb3bc5..38bd74b 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -778,8 +778,10 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *parentCon
Q_ASSERT(!isRoot || state); // Either this isn't a root component, or a state data must be provided
Q_ASSERT((state != 0) ^ (errors != 0)); // One of state or errors (but not both) must be provided
- if (isRoot)
+ if (isRoot) {
QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
+ QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, component->url);
+ }
QDeclarativeContextData *ctxt = new QDeclarativeContextData;
ctxt->isInternal = true;
diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h
index 6c14feb..6b71381 100644
--- a/src/declarative/qml/qdeclarativecontext_p.h
+++ b/src/declarative/qml/qdeclarativecontext_p.h
@@ -77,7 +77,6 @@ class QDeclarativeEngine;
class QDeclarativeExpression;
class QDeclarativeExpressionPrivate;
class QDeclarativeAbstractExpression;
-class QDeclarativeBinding_Id;
class QDeclarativeCompiledBindings;
class QDeclarativeContextData;
diff --git a/src/declarative/qml/qdeclarativecustomparser.cpp b/src/declarative/qml/qdeclarativecustomparser.cpp
index 97a6a00..58ffc56 100644
--- a/src/declarative/qml/qdeclarativecustomparser.cpp
+++ b/src/declarative/qml/qdeclarativecustomparser.cpp
@@ -304,5 +304,14 @@ const QMetaObject *QDeclarativeCustomParser::resolveType(const QByteArray& name)
return compiler->resolveType(name);
}
+/*!
+ Rewrites \a expression and returns an identifier that can be
+ used to construct the binding later. \a name
+ is used as the name of the rewritten function.
+*/
+QDeclarativeBinding::Identifier QDeclarativeCustomParser::rewriteBinding(const QString& expression, const QByteArray& name)
+{
+ return compiler->rewriteBinding(expression, name);
+}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecustomparser_p.h b/src/declarative/qml/qdeclarativecustomparser_p.h
index c3f9dd2..9b419c2 100644
--- a/src/declarative/qml/qdeclarativecustomparser_p.h
+++ b/src/declarative/qml/qdeclarativecustomparser_p.h
@@ -56,6 +56,7 @@
#include "private/qdeclarativemetatype_p.h"
#include "qdeclarativeerror.h"
#include "private/qdeclarativeparser_p.h"
+#include "private/qdeclarativebinding_p.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qxmlstream.h>
@@ -140,6 +141,8 @@ protected:
const QMetaObject *resolveType(const QByteArray&) const;
+ QDeclarativeBinding::Identifier rewriteBinding(const QString&, const QByteArray&);
+
private:
QList<QDeclarativeError> exceptions;
QDeclarativeCompiler *compiler;
diff --git a/src/declarative/qml/qdeclarativedata_p.h b/src/declarative/qml/qdeclarativedata_p.h
index 4767169..81f279c 100644
--- a/src/declarative/qml/qdeclarativedata_p.h
+++ b/src/declarative/qml/qdeclarativedata_p.h
@@ -66,6 +66,7 @@ class QDeclarativePropertyCache;
class QDeclarativeContextData;
class QDeclarativeNotifier;
class QDeclarativeDataExtended;
+class QDeclarativeType;
// This class is structured in such a way, that simply zero'ing it is the
// default state for elemental object allocations. This is crucial in the
// workings of the QDeclarativeInstruction::CreateSimpleObject instruction.
@@ -77,7 +78,7 @@ public:
: ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false),
context(0), outerContext(0), bindings(0), nextContextObject(0), prevContextObject(0), bindingBitsSize(0),
bindingBits(0), lineNumber(0), columnNumber(0), deferredComponent(0), deferredIdx(0),
- scriptValue(0), objectDataRefCount(0), propertyCache(0), guards(0), extendedData(0) {
+ scriptValue(0), objectDataRefCount(0), propertyCache(0), guards(0), type(0), extendedData(0) {
init();
}
@@ -136,6 +137,8 @@ public:
QDeclarativeGuard<QObject> *guards;
+ const QDeclarativeType *type;
+
static QDeclarativeData *get(const QObject *object, bool create = false) {
QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object));
if (priv->wasDeleted) {
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index cf3ea42..0a008ff 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -69,6 +69,7 @@
#include "private/qdeclarativetypenamecache_p.h"
#include "private/qdeclarativeinclude_p.h"
#include "private/qdeclarativenotifier_p.h"
+#include "private/qdeclarativedebugtrace_p.h"
#include <QtCore/qmetaobject.h>
#include <QScriptClass>
@@ -959,7 +960,8 @@ Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
QDeclarativeData *data = QDeclarativeData::get(object);
if (data && data->deferredComponent) {
-
+ QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
+ QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, QLatin1String("Deferred Creation:") + object->metaObject()->className());
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
QDeclarativeComponentPrivate::ConstructionState state;
@@ -969,6 +971,7 @@ Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
data->deferredComponent = 0;
QDeclarativeComponentPrivate::complete(ep, &state);
+ QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Creating);
}
}
diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp
index e54f7d6..b6b4b49 100644
--- a/src/declarative/qml/qdeclarativeenginedebug.cpp
+++ b/src/declarative/qml/qdeclarativeenginedebug.cpp
@@ -52,6 +52,7 @@
#include "private/qdeclarativevaluetype_p.h"
#include "private/qdeclarativevmemetaobject_p.h"
#include "private/qdeclarativeexpression_p.h"
+#include "private/qdeclarativepropertychanges_p.h"
#include <QtCore/qdebug.h>
#include <QtCore/qmetaobject.h>
@@ -195,11 +196,6 @@ void QDeclarativeEngineDebugServer::buildObjectDump(QDataStream &message,
{
message << objectData(object);
- // Some children aren't added to an object until particular properties are read
- // - e.g. child state objects aren't added until the 'states' property is read -
- // but this should only affect internal objects that aren't shown by the
- // debugger anyway.
-
QObjectList children = object->children();
int childrenCount = children.count();
@@ -260,6 +256,18 @@ void QDeclarativeEngineDebugServer::buildObjectDump(QDataStream &message,
message << fakeProperties[ii];
}
+void QDeclarativeEngineDebugServer::prepareDeferredObjects(QObject *obj)
+{
+ qmlExecuteDeferred(obj);
+
+ QObjectList children = obj->children();
+ for (int ii = 0; ii < children.count(); ++ii) {
+ QObject *child = children.at(ii);
+ prepareDeferredObjects(child);
+ }
+
+}
+
void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, QDeclarativeContext *ctxt)
{
QDeclarativeContextData *p = QDeclarativeContextData::get(ctxt);
@@ -300,6 +308,35 @@ void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, QDecla
}
}
+void QDeclarativeEngineDebugServer::buildStatesList(QDeclarativeContext *ctxt, bool cleanList=false)
+{
+ if (cleanList)
+ m_allStates.clear();
+
+ QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(ctxt);
+ for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
+ buildStatesList(ctxtPriv->instances.at(ii));
+ }
+
+ QDeclarativeContextData *child = QDeclarativeContextData::get(ctxt)->childContexts;
+ while (child) {
+ buildStatesList(child->asQDeclarativeContext());
+ child = child->nextChild;
+ }
+}
+
+void QDeclarativeEngineDebugServer::buildStatesList(QObject *obj)
+{
+ if (QDeclarativeState *state = dynamic_cast<QDeclarativeState *>(obj)) {
+ m_allStates.append(state);
+ }
+
+ QObjectList children = obj->children();
+ for (int ii = 0; ii < children.count(); ++ii) {
+ buildStatesList(children.at(ii));
+ }
+}
+
QDeclarativeEngineDebugServer::QDeclarativeObjectData
QDeclarativeEngineDebugServer::objectData(QObject *object)
{
@@ -378,8 +415,10 @@ void QDeclarativeEngineDebugServer::messageReceived(const QByteArray &message)
QDataStream rs(&reply, QIODevice::WriteOnly);
rs << QByteArray("LIST_OBJECTS_R") << queryId;
- if (engine)
+ if (engine) {
buildObjectList(rs, engine->rootContext());
+ buildStatesList(engine->rootContext(), true);
+ }
sendMessage(reply);
} else if (type == "FETCH_OBJECT") {
@@ -396,8 +435,11 @@ void QDeclarativeEngineDebugServer::messageReceived(const QByteArray &message)
QDataStream rs(&reply, QIODevice::WriteOnly);
rs << QByteArray("FETCH_OBJECT_R") << queryId;
- if (object)
+ if (object) {
+ if (recurse)
+ prepareDeferredObjects(object);
buildObjectDump(rs, object, recurse, dumpProperties);
+ }
sendMessage(reply);
} else if (type == "WATCH_OBJECT") {
@@ -497,26 +539,66 @@ void QDeclarativeEngineDebugServer::setBinding(int objectId,
{
QObject *object = objectForId(objectId);
QDeclarativeContext *context = qmlContext(object);
+ QByteArray propertyNameArray = propertyName.toUtf8();
if (object && context) {
-
QDeclarativeProperty property(object, propertyName, context);
- if (isLiteralValue) {
- property.write(expression);
- } else if (hasValidSignal(object, propertyName)) {
- QDeclarativeExpression *declarativeExpression = new QDeclarativeExpression(context, object, expression.toString());
- QDeclarativeExpression *oldExpression = QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression);
- declarativeExpression->setSourceLocation(oldExpression->sourceFile(), oldExpression->lineNumber());
- } else if (property.isProperty()) {
- QDeclarativeBinding *binding = new QDeclarativeBinding(expression.toString(), object, context);
- binding->setTarget(property);
- binding->setNotifyOnValueChanged(true);
- QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, binding);
- if (oldBinding)
- oldBinding->destroy();
- binding->update();
+ if (property.isValid()) {
+
+ bool inBaseState = true;
+
+ foreach(QWeakPointer<QDeclarativeState> statePointer, m_allStates) {
+ if (QDeclarativeState *state = statePointer.data()) {
+ // here we assume that the revert list on itself defines the base state
+ if ( state->isStateActive() && state->containsPropertyInRevertList(object, propertyNameArray) ) {
+ inBaseState = false;
+
+ QDeclarativeBinding *newBinding = 0;
+ if (!isLiteralValue) {
+ newBinding = new QDeclarativeBinding(expression.toString(), object, context);
+ newBinding->setTarget(property);
+ newBinding->setNotifyOnValueChanged(true);
+ }
+
+ state->changeBindingInRevertList(object,propertyNameArray, newBinding);
+
+ if (isLiteralValue)
+ state->changeValueInRevertList(object, propertyNameArray, expression);
+ }
+ }
+ }
+
+ if (inBaseState) {
+ if (isLiteralValue) {
+ property.write(expression);
+ } else if (hasValidSignal(object, propertyName)) {
+ QDeclarativeExpression *declarativeExpression = new QDeclarativeExpression(context, object, expression.toString());
+ QDeclarativeExpression *oldExpression = QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression);
+ declarativeExpression->setSourceLocation(oldExpression->sourceFile(), oldExpression->lineNumber());
+ } else if (property.isProperty()) {
+ QDeclarativeBinding *binding = new QDeclarativeBinding(expression.toString(), object, context);
+ binding->setTarget(property);
+ binding->setNotifyOnValueChanged(true);
+ QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, binding);
+ if (oldBinding)
+ oldBinding->destroy();
+ binding->update();
+ } else {
+ qWarning() << "QDeclarativeEngineDebugServer::setBinding: unable to set property" << propertyName << "on object" << object;
+ }
+ }
+
} else {
- qWarning() << "QDeclarativeEngineDebugServer::setBinding: unable to set property" << propertyName << "on object" << object;
+ // not a valid property
+ if (QDeclarativePropertyChanges *propertyChanges = dynamic_cast<QDeclarativePropertyChanges *>(object)) {
+ if (isLiteralValue) {
+ propertyChanges->changeValue(propertyName.toUtf8(),expression);
+ } else {
+ propertyChanges->changeExpression(propertyName.toUtf8(),expression.toString());
+ }
+ } else {
+ qWarning() << "QDeclarativeEngineDebugServer::setBinding: unable to set property" << propertyName << "on object" << object;
+ }
}
}
}
@@ -534,11 +616,31 @@ void QDeclarativeEngineDebugServer::resetBinding(int objectId, const QString &pr
QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, 0);
if (oldBinding)
oldBinding->destroy();
+ }
+ if (property.isResettable()) {
+ // Note: this will reset the property in any case, without regard to states
+ // Right now almost no QDeclarativeItem has reset methods for its properties (with the
+ // notable exception of QDeclarativeAnchors), so this is not a big issue
+ // later on, setBinding does take states into account
+ property.reset();
} else {
- if (property.isResettable()) {
- property.reset();
+ // overwrite with default value
+ if (QDeclarativeType *objType = QDeclarativeMetaType::qmlType(object->metaObject())) {
+ if (QObject *emptyObject = objType->create()) {
+ if (emptyObject->property(propertyName.toLatin1()).isValid()) {
+ QVariant defaultValue = QDeclarativeProperty(emptyObject, propertyName).read();
+ if (defaultValue.isValid()) {
+ setBinding(objectId, propertyName, defaultValue, true);
+ }
+ }
+ delete emptyObject;
+ }
}
}
+ } else {
+ if (QDeclarativePropertyChanges *propertyChanges = dynamic_cast<QDeclarativePropertyChanges *>(object)) {
+ propertyChanges->removeProperty(propertyName.toUtf8());
+ }
}
}
}
diff --git a/src/declarative/qml/qdeclarativeenginedebug_p.h b/src/declarative/qml/qdeclarativeenginedebug_p.h
index 97b8121..65eb1ff 100644
--- a/src/declarative/qml/qdeclarativeenginedebug_p.h
+++ b/src/declarative/qml/qdeclarativeenginedebug_p.h
@@ -57,6 +57,7 @@
#include <QtCore/qurl.h>
#include <QtCore/qvariant.h>
+#include <QWeakPointer>
QT_BEGIN_NAMESPACE
@@ -64,6 +65,7 @@ class QDeclarativeEngine;
class QDeclarativeContext;
class QDeclarativeWatcher;
class QDataStream;
+class QDeclarativeState;
class QDeclarativeEngineDebugServer : public QDeclarativeDebugService
{
@@ -105,8 +107,11 @@ private Q_SLOTS:
void propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value);
private:
+ void prepareDeferredObjects(QObject *);
void buildObjectList(QDataStream &, QDeclarativeContext *);
void buildObjectDump(QDataStream &, QObject *, bool, bool);
+ void buildStatesList(QDeclarativeContext *, bool);
+ void buildStatesList(QObject *obj);
QDeclarativeObjectData objectData(QObject *);
QDeclarativeObjectProperty propertyData(QObject *, int);
QVariant valueContents(const QVariant &defaultValue) const;
@@ -116,6 +121,7 @@ private:
QList<QDeclarativeEngine *> m_engines;
QDeclarativeWatcher *m_watch;
+ QList<QWeakPointer<QDeclarativeState> > m_allStates;
};
Q_DECLARATIVE_PRIVATE_EXPORT QDataStream &operator<<(QDataStream &, const QDeclarativeEngineDebugServer::QDeclarativeObjectData &);
Q_DECLARATIVE_PRIVATE_EXPORT QDataStream &operator>>(QDataStream &, QDeclarativeEngineDebugServer::QDeclarativeObjectData &);
diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h
index 94676fc..4030bab 100644
--- a/src/declarative/qml/qdeclarativeinstruction_p.h
+++ b/src/declarative/qml/qdeclarativeinstruction_p.h
@@ -182,6 +182,7 @@ public:
struct CreateSimpleInstruction {
void (*create)(void *);
int typeSize;
+ int type;
ushort column;
};
struct StoreMetaInstruction {
diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp
index 7a78a1f..48a63bb 100644
--- a/src/declarative/qml/qdeclarativemetatype.cpp
+++ b/src/declarative/qml/qdeclarativemetatype.cpp
@@ -134,10 +134,13 @@ public:
bool m_isInterface : 1;
const char *m_iid;
+ QByteArray m_module;
QByteArray m_name;
int m_version_maj;
int m_version_min;
int m_typeId; int m_listId;
+ int m_revision;
+ mutable QDeclarativeType *m_superType;
int m_allocationSize;
void (*m_newFunc)(void *);
@@ -155,6 +158,7 @@ public:
int m_index;
QDeclarativeCustomParser *m_customParser;
mutable volatile bool m_isSetup:1;
+ mutable bool m_haveSuperType : 1;
mutable QList<QDeclarativeProxyMetaObject::ProxyData> m_metaObjects;
static QHash<const QMetaObject *, int> m_attachedPropertyIds;
@@ -163,10 +167,10 @@ public:
QHash<const QMetaObject *, int> QDeclarativeTypePrivate::m_attachedPropertyIds;
QDeclarativeTypePrivate::QDeclarativeTypePrivate()
-: m_isInterface(false), m_iid(0), m_typeId(0), m_listId(0),
+: m_isInterface(false), m_iid(0), m_typeId(0), m_listId(0), m_revision(0), m_superType(0),
m_allocationSize(0), m_newFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0), m_attachedPropertiesType(0),
m_parserStatusCast(-1), m_propertyValueSourceCast(-1), m_propertyValueInterceptorCast(-1),
- m_extFunc(0), m_extMetaObject(0), m_index(-1), m_customParser(0), m_isSetup(false)
+ m_extFunc(0), m_extMetaObject(0), m_index(-1), m_customParser(0), m_isSetup(false), m_haveSuperType(false)
{
}
@@ -192,9 +196,12 @@ QDeclarativeType::QDeclarativeType(int index, const QDeclarativePrivate::Registe
if (type.uri) name += '/';
name += type.elementName;
+ d->m_module = type.uri;
d->m_name = name;
d->m_version_maj = type.versionMajor;
d->m_version_min = type.versionMinor;
+ if (type.version >= 1) // revisions added in version 1
+ d->m_revision = type.revision;
d->m_typeId = type.typeId;
d->m_listId = type.listId;
d->m_allocationSize = type.objectSize;
@@ -243,6 +250,56 @@ bool QDeclarativeType::availableInVersion(int vmajor, int vminor) const
return vmajor > d->m_version_maj || (vmajor == d->m_version_maj && vminor >= d->m_version_min);
}
+bool QDeclarativeType::availableInVersion(const QByteArray &module, int vmajor, int vminor) const
+{
+ return module == d->m_module && (vmajor > d->m_version_maj || (vmajor == d->m_version_maj && vminor >= d->m_version_min));
+}
+
+// returns the nearest _registered_ super class
+QDeclarativeType *QDeclarativeType::superType() const
+{
+ if (!d->m_haveSuperType) {
+ const QMetaObject *mo = d->m_baseMetaObject->superClass();
+ while (mo && !d->m_superType) {
+ d->m_superType = QDeclarativeMetaType::qmlType(mo, d->m_module, d->m_version_maj, d->m_version_min);
+ mo = mo->superClass();
+ }
+ d->m_haveSuperType = true;
+ }
+
+ return d->m_superType;
+}
+
+bool QDeclarativeType::isPropertyAvailable(int index, int revision) const
+{
+ if (revision == 0)
+ return true;
+
+ if (index < d->m_baseMetaObject->propertyOffset()) {
+ if (QDeclarativeType *super = superType())
+ return super->isPropertyAvailable(index, revision);
+ } else if (index < d->m_baseMetaObject->propertyOffset() + d->m_baseMetaObject->propertyCount()) {
+ return d->m_revision >= revision;
+ }
+
+ return false;
+}
+
+bool QDeclarativeType::isMethodAvailable(int index, int revision) const
+{
+ if (revision == 0)
+ return true;
+
+ if (index < d->m_baseMetaObject->methodOffset()) {
+ if (QDeclarativeType *super = superType())
+ return super->isMethodAvailable(index, revision);
+ } else if (index < d->m_baseMetaObject->methodOffset() + d->m_baseMetaObject->methodCount()) {
+ return d->m_revision >= revision;
+ }
+
+ return false;
+}
+
static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd)
{
@@ -572,7 +629,7 @@ int registerType(const QDeclarativePrivate::RegisterType &type)
if (!dtype->qmlTypeName().isEmpty())
data->nameToType.insertMulti(dtype->qmlTypeName(), dtype);
- data->metaObjectToType.insert(dtype->baseMetaObject(), dtype);
+ data->metaObjectToType.insertMulti(dtype->baseMetaObject(), dtype);
if (data->objects.size() <= type.typeId)
data->objects.resize(type.typeId + 16);
@@ -862,6 +919,27 @@ QDeclarativeType *QDeclarativeMetaType::qmlType(const QMetaObject *metaObject)
}
/*!
+ Returns the type (if any) that corresponds to the \a metaObject in version specified
+ by \a version_major and \a version_minor in module specified by \a uri. Returns null if no
+ type is registered.
+*/
+QDeclarativeType *QDeclarativeMetaType::qmlType(const QMetaObject *metaObject, const QByteArray &module, int version_major, int version_minor)
+{
+ QReadLocker lock(metaTypeDataLock());
+ QDeclarativeMetaTypeData *data = metaTypeData();
+
+ QDeclarativeMetaTypeData::MetaObjects::const_iterator it = data->metaObjectToType.find(metaObject);
+ while (it != data->metaObjectToType.end() && it.key() == metaObject) {
+ QDeclarativeType *t = *it;
+ if (version_major < 0 || t->availableInVersion(module, version_major,version_minor))
+ return t;
+ ++it;
+ }
+
+ return 0;
+}
+
+/*!
Returns the type (if any) that corresponds to the QVariant::Type \a userType.
Returns null if no type is registered.
*/
diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h
index 9c486d3..d9a3795 100644
--- a/src/declarative/qml/qdeclarativemetatype_p.h
+++ b/src/declarative/qml/qdeclarativemetatype_p.h
@@ -76,6 +76,7 @@ public:
static QDeclarativeType *qmlType(const QByteArray &, int, int);
static QDeclarativeType *qmlType(const QMetaObject *);
+ static QDeclarativeType *qmlType(const QMetaObject *metaObject, const QByteArray &module, int version_major, int version_minor);
static QDeclarativeType *qmlType(int);
static QMetaProperty defaultProperty(const QMetaObject *);
@@ -115,6 +116,9 @@ public:
int majorVersion() const;
int minorVersion() const;
bool availableInVersion(int vmajor, int vminor) const;
+ bool availableInVersion(const QByteArray &module, int vmajor, int vminor) const;
+ bool isPropertyAvailable(int index, int revision) const;
+ bool isMethodAvailable(int index, int revision) const;
QObject *create() const;
void create(QObject **, void **, size_t) const;
@@ -149,6 +153,7 @@ public:
int index() const;
private:
+ QDeclarativeType *superType() const;
friend class QDeclarativeTypePrivate;
friend struct QDeclarativeMetaTypeData;
friend int registerType(const QDeclarativePrivate::RegisterType &);
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
index b0bc5bb..090eeda 100644
--- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
+++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp
@@ -166,6 +166,20 @@ QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &nam
QDeclarativeEnginePrivate *enginePrivate = QDeclarativeEnginePrivate::get(engine);
lastData = QDeclarativePropertyCache::property(engine, obj, name, local);
+ if (lastData && lastData->revision > 0 && (hints & ImplicitObject)) {
+ QDeclarativeData *data = QDeclarativeData::get(obj);
+ if (data) {
+ if (!data->type) {
+ lastData = 0;
+ } else if (lastData->flags & QDeclarativePropertyCache::Data::IsFunction) {
+ if (!data->type->isMethodAvailable(lastData->coreIndex, lastData->revision))
+ lastData = 0;
+ } else if (!data->type->isPropertyAvailable(lastData->coreIndex, lastData->revision)) {
+ lastData = 0;
+ }
+ }
+ }
+
if (lastData)
return QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess;
diff --git a/src/declarative/qml/qdeclarativeprivate.h b/src/declarative/qml/qdeclarativeprivate.h
index 388c92e..981df78 100644
--- a/src/declarative/qml/qdeclarativeprivate.h
+++ b/src/declarative/qml/qdeclarativeprivate.h
@@ -214,6 +214,8 @@ namespace QDeclarativePrivate
const QMetaObject *extensionMetaObject;
QDeclarativeCustomParser *customParser;
+ int revision;
+ // If this is extended ensure "version" is bumped!!!
};
struct RegisterInterface {
diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp
index 60edd64..d7cf6cc 100644
--- a/src/declarative/qml/qdeclarativeproperty.cpp
+++ b/src/declarative/qml/qdeclarativeproperty.cpp
@@ -106,15 +106,16 @@ qWarning() << "Pixel size should now be 24:" << property.read().toInt();
Create an invalid QDeclarativeProperty.
*/
QDeclarativeProperty::QDeclarativeProperty()
-: d(new QDeclarativePropertyPrivate)
+: d(0)
{
- d->q = this;
}
/*! \internal */
QDeclarativeProperty::~QDeclarativeProperty()
{
- delete d; d = 0;
+ if (d)
+ d->release();
+ d = 0;
}
/*!
@@ -124,7 +125,6 @@ QDeclarativeProperty::~QDeclarativeProperty()
QDeclarativeProperty::QDeclarativeProperty(QObject *obj)
: d(new QDeclarativePropertyPrivate)
{
- d->q = this;
d->initDefault(obj);
}
@@ -137,7 +137,6 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj)
QDeclarativeProperty::QDeclarativeProperty(QObject *obj, QDeclarativeContext *ctxt)
: d(new QDeclarativePropertyPrivate)
{
- d->q = this;
d->context = ctxt?QDeclarativeContextData::get(ctxt):0;
d->engine = ctxt?ctxt->engine():0;
d->initDefault(obj);
@@ -152,7 +151,6 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, QDeclarativeContext *ct
QDeclarativeProperty::QDeclarativeProperty(QObject *obj, QDeclarativeEngine *engine)
: d(new QDeclarativePropertyPrivate)
{
- d->q = this;
d->context = 0;
d->engine = engine;
d->initDefault(obj);
@@ -178,7 +176,6 @@ void QDeclarativePropertyPrivate::initDefault(QObject *obj)
QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name)
: d(new QDeclarativePropertyPrivate)
{
- d->q = this;
d->initProperty(obj, name);
if (!isValid()) d->object = 0;
}
@@ -190,7 +187,6 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name)
QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name, QDeclarativeContext *ctxt)
: d(new QDeclarativePropertyPrivate)
{
- d->q = this;
d->context = ctxt?QDeclarativeContextData::get(ctxt):0;
d->engine = ctxt?ctxt->engine():0;
d->initProperty(obj, name);
@@ -205,7 +201,6 @@ QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name, QD
QDeclarativeProperty::QDeclarativeProperty(QObject *obj, const QString &name, QDeclarativeEngine *engine)
: d(new QDeclarativePropertyPrivate)
{
- d->q = this;
d->context = 0;
d->engine = engine;
d->initProperty(obj, name);
@@ -315,6 +310,8 @@ void QDeclarativePropertyPrivate::initProperty(QObject *obj, const QString &name
if (property && !(property->flags & QDeclarativePropertyCache::Data::IsFunction)) {
object = currentObject;
core = *property;
+ nameCache = terminal;
+ isNameCached = true;
}
}
@@ -322,9 +319,10 @@ void QDeclarativePropertyPrivate::initProperty(QObject *obj, const QString &name
Create a copy of \a other.
*/
QDeclarativeProperty::QDeclarativeProperty(const QDeclarativeProperty &other)
-: d(new QDeclarativePropertyPrivate(*other.d))
{
- d->q = this;
+ d = other.d;
+ if (d)
+ d->addref();
}
/*!
@@ -353,13 +351,13 @@ QDeclarativeProperty::QDeclarativeProperty(const QDeclarativeProperty &other)
*/
QDeclarativeProperty::PropertyTypeCategory QDeclarativeProperty::propertyTypeCategory() const
{
- return d->propertyTypeCategory();
+ return d ? d->propertyTypeCategory() : InvalidCategory;
}
QDeclarativeProperty::PropertyTypeCategory
QDeclarativePropertyPrivate::propertyTypeCategory() const
{
- uint type = q->type();
+ uint type = this->type();
if (isValueType()) {
return QDeclarativeProperty::Normal;
@@ -386,6 +384,8 @@ QDeclarativePropertyPrivate::propertyTypeCategory() const
*/
const char *QDeclarativeProperty::propertyTypeName() const
{
+ if (!d)
+ return 0;
if (d->isValueType()) {
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(d->context);
@@ -412,6 +412,8 @@ const char *QDeclarativeProperty::propertyTypeName() const
*/
bool QDeclarativeProperty::operator==(const QDeclarativeProperty &other) const
{
+ if (!d || !other.d)
+ return false;
// category is intentially omitted here as it is generated
// from the other members
return d->object == other.d->object &&
@@ -425,7 +427,7 @@ bool QDeclarativeProperty::operator==(const QDeclarativeProperty &other) const
*/
int QDeclarativeProperty::propertyType() const
{
- return d->propertyType();
+ return d ? d->propertyType() : QVariant::Invalid;
}
bool QDeclarativePropertyPrivate::isValueType() const
@@ -435,7 +437,7 @@ bool QDeclarativePropertyPrivate::isValueType() const
int QDeclarativePropertyPrivate::propertyType() const
{
- uint type = q->type();
+ uint type = this->type();
if (isValueType()) {
return valueType.valueTypePropType;
} else if (type & QDeclarativeProperty::Property) {
@@ -448,17 +450,22 @@ int QDeclarativePropertyPrivate::propertyType() const
}
}
+QDeclarativeProperty::Type QDeclarativePropertyPrivate::type() const
+{
+ if (core.flags & QDeclarativePropertyCache::Data::IsFunction)
+ return QDeclarativeProperty::SignalProperty;
+ else if (core.isValid())
+ return QDeclarativeProperty::Property;
+ else
+ return QDeclarativeProperty::Invalid;
+}
+
/*!
Returns the type of the property.
*/
QDeclarativeProperty::Type QDeclarativeProperty::type() const
{
- if (d->core.flags & QDeclarativePropertyCache::Data::IsFunction)
- return SignalProperty;
- else if (d->core.isValid())
- return Property;
- else
- return Invalid;
+ return d ? d->type() : Invalid;
}
/*!
@@ -482,7 +489,7 @@ bool QDeclarativeProperty::isSignalProperty() const
*/
QObject *QDeclarativeProperty::object() const
{
- return d->object;
+ return d ? d->object : 0;
}
/*!
@@ -490,15 +497,11 @@ QObject *QDeclarativeProperty::object() const
*/
QDeclarativeProperty &QDeclarativeProperty::operator=(const QDeclarativeProperty &other)
{
- d->context = other.d->context;
- d->engine = other.d->engine;
- d->object = other.d->object;
-
- d->isNameCached = other.d->isNameCached;
- d->core = other.d->core;
- d->nameCache = other.d->nameCache;
-
- d->valueType = other.d->valueType;
+ if (d)
+ d->release();
+ d = other.d;
+ if (d)
+ d->addref();
return *this;
}
@@ -508,6 +511,8 @@ QDeclarativeProperty &QDeclarativeProperty::operator=(const QDeclarativeProperty
*/
bool QDeclarativeProperty::isWritable() const
{
+ if (!d)
+ return false;
if (!d->object)
return false;
if (d->core.flags & QDeclarativePropertyCache::Data::IsQList) //list
@@ -525,6 +530,8 @@ bool QDeclarativeProperty::isWritable() const
*/
bool QDeclarativeProperty::isDesignable() const
{
+ if (!d)
+ return false;
if (type() & Property && d->core.isValid() && d->object)
return d->object->metaObject()->property(d->core.coreIndex).isDesignable();
else
@@ -536,6 +543,8 @@ bool QDeclarativeProperty::isDesignable() const
*/
bool QDeclarativeProperty::isResettable() const
{
+ if (!d)
+ return false;
if (type() & Property && d->core.isValid() && d->object)
return d->core.flags & QDeclarativePropertyCache::Data::IsResettable;
else
@@ -548,6 +557,8 @@ bool QDeclarativeProperty::isResettable() const
*/
bool QDeclarativeProperty::isValid() const
{
+ if (!d)
+ return false;
return type() != Invalid;
}
@@ -556,6 +567,8 @@ bool QDeclarativeProperty::isValid() const
*/
QString QDeclarativeProperty::name() const
{
+ if (!d)
+ return QString();
if (!d->isNameCached) {
// ###
if (!d->object) {
@@ -592,6 +605,8 @@ QString QDeclarativeProperty::name() const
*/
QMetaProperty QDeclarativeProperty::property() const
{
+ if (!d)
+ return QMetaProperty();
if (type() & Property && d->core.isValid() && d->object)
return d->object->metaObject()->property(d->core.coreIndex);
else
@@ -604,6 +619,8 @@ QMetaProperty QDeclarativeProperty::property() const
*/
QMetaMethod QDeclarativeProperty::method() const
{
+ if (!d)
+ return QMetaMethod();
if (type() & SignalProperty && d->object)
return d->object->metaObject()->method(d->core.coreIndex);
else
@@ -617,7 +634,7 @@ QMetaMethod QDeclarativeProperty::method() const
QDeclarativeAbstractBinding *
QDeclarativePropertyPrivate::binding(const QDeclarativeProperty &that)
{
- if (!that.isProperty() || !that.d->object)
+ if (!that.d || !that.isProperty() || !that.d->object)
return 0;
return binding(that.d->object, that.d->core.coreIndex, that.d->valueType.valueTypeCoreIdx);
@@ -641,7 +658,7 @@ QDeclarativePropertyPrivate::setBinding(const QDeclarativeProperty &that,
QDeclarativeAbstractBinding *newBinding,
WriteFlags flags)
{
- if (!that.isProperty() || !that.d->object) {
+ if (!that.d || !that.isProperty() || !that.d->object) {
if (newBinding)
newBinding->destroy();
return 0;
@@ -891,6 +908,8 @@ QDeclarativePropertyPrivate::setSignalExpression(const QDeclarativeProperty &tha
*/
QVariant QDeclarativeProperty::read() const
{
+ if (!d)
+ return QVariant();
if (!d->object)
return QVariant();
@@ -1032,8 +1051,10 @@ bool QDeclarativePropertyPrivate::writeEnumProperty(const QMetaProperty &prop, i
bool QDeclarativePropertyPrivate::writeValueProperty(const QVariant &value, WriteFlags flags)
{
// Remove any existing bindings on this property
- if (!(flags & DontRemoveBinding)) {
- QDeclarativeAbstractBinding *binding = setBinding(*q, 0);
+ if (!(flags & DontRemoveBinding) &&
+ (type() & QDeclarativeProperty::Property) && object) {
+ QDeclarativeAbstractBinding *binding = setBinding(object, core.coreIndex,
+ valueType.valueTypeCoreIdx, 0, flags);
if (binding) binding->destroy();
}
@@ -1312,6 +1333,8 @@ bool QDeclarativeProperty::reset() const
bool QDeclarativePropertyPrivate::write(const QDeclarativeProperty &that,
const QVariant &value, WriteFlags flags)
{
+ if (!that.d)
+ return false;
if (that.d->object && that.type() & QDeclarativeProperty::Property &&
that.d->core.isValid() && that.isWritable())
return that.d->writeValueProperty(value, flags);
@@ -1390,12 +1413,12 @@ bool QDeclarativeProperty::connectNotifySignal(QObject *dest, const char *slot)
*/
int QDeclarativeProperty::index() const
{
- return d->core.coreIndex;
+ return d ? d->core.coreIndex : -1;
}
int QDeclarativePropertyPrivate::valueTypeCoreIndex(const QDeclarativeProperty &that)
{
- return that.d->valueType.valueTypeCoreIdx;
+ return that.d ? that.d->valueType.valueTypeCoreIdx : -1;
}
/*!
@@ -1404,6 +1427,8 @@ int QDeclarativePropertyPrivate::valueTypeCoreIndex(const QDeclarativeProperty &
*/
int QDeclarativePropertyPrivate::bindingIndex(const QDeclarativeProperty &that)
{
+ if (!that.d)
+ return -1;
int rv = that.d->core.coreIndex;
if (rv != -1 && that.d->valueType.valueTypeCoreIdx != -1)
rv = rv | (that.d->valueType.valueTypeCoreIdx << 24);
@@ -1455,6 +1480,7 @@ QDeclarativePropertyPrivate::restore(const QByteArray &data, QObject *object, QD
if (data.isEmpty())
return prop;
+ prop.d = new QDeclarativePropertyPrivate;
prop.d->object = object;
prop.d->context = ctxt;
prop.d->engine = ctxt->engine;
diff --git a/src/declarative/qml/qdeclarativeproperty_p.h b/src/declarative/qml/qdeclarativeproperty_p.h
index 6392f88..f7d24f1 100644
--- a/src/declarative/qml/qdeclarativeproperty_p.h
+++ b/src/declarative/qml/qdeclarativeproperty_p.h
@@ -65,23 +65,15 @@ QT_BEGIN_NAMESPACE
class QDeclarativeContext;
class QDeclarativeEnginePrivate;
class QDeclarativeExpression;
-class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativePropertyPrivate
+class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativePropertyPrivate : public QDeclarativeRefCount
{
public:
enum WriteFlag { BypassInterceptor = 0x01, DontRemoveBinding = 0x02, RemoveBindingOnAliasWrite = 0x04 };
Q_DECLARE_FLAGS(WriteFlags, WriteFlag)
QDeclarativePropertyPrivate()
- : q(0), context(0), engine(0), object(0), isNameCached(false) {}
-
+ : context(0), engine(0), object(0), isNameCached(false) {}
- QDeclarativePropertyPrivate(const QDeclarativePropertyPrivate &other)
- : q(0), context(other.context), engine(other.engine), object(other.object),
- isNameCached(other.isNameCached),
- core(other.core), nameCache(other.nameCache),
- valueType(other.valueType) {}
-
- QDeclarativeProperty *q;
QDeclarativeContextData *context;
QDeclarativeEngine *engine;
QDeclarativeGuard<QObject> object;
@@ -98,6 +90,7 @@ public:
bool isValueType() const;
int propertyType() const;
+ QDeclarativeProperty::Type type() const;
QDeclarativeProperty::PropertyTypeCategory propertyTypeCategory() const;
QVariant readValueProperty();
diff --git a/src/declarative/qml/qdeclarativepropertycache.cpp b/src/declarative/qml/qdeclarativepropertycache.cpp
index dd9a224..76c9eb9 100644
--- a/src/declarative/qml/qdeclarativepropertycache.cpp
+++ b/src/declarative/qml/qdeclarativepropertycache.cpp
@@ -88,6 +88,7 @@ void QDeclarativePropertyCache::Data::load(const QMetaProperty &p, QDeclarativeE
coreIndex = p.propertyIndex();
notifyIndex = p.notifySignalIndex();
flags = flagsForProperty(p, engine);
+ revision = p.revision();
}
void QDeclarativePropertyCache::Data::load(const QMetaMethod &m)
@@ -106,6 +107,7 @@ void QDeclarativePropertyCache::Data::load(const QMetaMethod &m)
QList<QByteArray> params = m.parameterTypes();
if (!params.isEmpty())
flags |= Data::HasArguments;
+ revision = m.revision();
}
@@ -235,7 +237,6 @@ void QDeclarativePropertyCache::append(QDeclarativeEngine *engine, const QMetaOb
Data::Flag propertyFlags, Data::Flag methodFlags, Data::Flag signalFlags)
{
QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
-
int methodCount = metaObject->methodCount();
// 3 to block the destroyed signal and the deleteLater() slot
int methodOffset = qMax(3, metaObject->methodOffset());
diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h
index f7c5daa..3f7f9ef 100644
--- a/src/declarative/qml/qdeclarativepropertycache_p.h
+++ b/src/declarative/qml/qdeclarativepropertycache_p.h
@@ -110,6 +110,7 @@ public:
int notifyIndex; // When !IsFunction
int relatedIndex; // When IsFunction
};
+ int revision;
static Flags flagsForProperty(const QMetaProperty &, QDeclarativeEngine *engine = 0);
void load(const QMetaProperty &, QDeclarativeEngine *engine = 0);
@@ -176,7 +177,8 @@ bool QDeclarativePropertyCache::Data::operator==(const QDeclarativePropertyCache
return flags == other.flags &&
propType == other.propType &&
coreIndex == other.coreIndex &&
- notifyIndex == other.notifyIndex;
+ notifyIndex == other.notifyIndex &&
+ revision == other.revision;
}
QDeclarativePropertyCache::Data *
diff --git a/src/declarative/qml/qdeclarativerewrite.cpp b/src/declarative/qml/qdeclarativerewrite.cpp
index bc9a114..219674f 100644
--- a/src/declarative/qml/qdeclarativerewrite.cpp
+++ b/src/declarative/qml/qdeclarativerewrite.cpp
@@ -62,12 +62,17 @@ bool SharedBindingTester::isSharable(const QString &code)
if (!parser.statement())
return false;
+ return isSharable(parser.statement());
+}
+
+bool SharedBindingTester::isSharable(AST::Node *node)
+{
_sharable = true;
- AST::Node::acceptChild(parser.statement(), this);
+ AST::Node::acceptChild(node, this);
return _sharable;
}
-QString RewriteBinding::operator()(const QString &code, bool *ok)
+QString RewriteBinding::operator()(const QString &code, bool *ok, bool *sharable)
{
Engine engine;
NodePool pool(QString(), &engine);
@@ -80,10 +85,63 @@ QString RewriteBinding::operator()(const QString &code, bool *ok)
return QString();
} else {
if (ok) *ok = true;
+ if (sharable) {
+ SharedBindingTester tester;
+ *sharable = tester.isSharable(parser.statement());
+ }
}
return rewrite(code, 0, parser.statement());
}
+QString RewriteBinding::operator()(QDeclarativeJS::AST::Node *node, const QString &code, bool *sharable)
+{
+ if (!node)
+ return code;
+
+ if (sharable) {
+ SharedBindingTester tester;
+ *sharable = tester.isSharable(node);
+ }
+
+ QDeclarativeJS::AST::ExpressionNode *expression = node->expressionCast();
+ QDeclarativeJS::AST::Statement *statement = node->statementCast();
+ if(!expression && !statement)
+ return code;
+
+ TextWriter w;
+ _writer = &w;
+ _position = expression ? expression->firstSourceLocation().begin() : statement->firstSourceLocation().begin();
+ _inLoop = 0;
+
+ accept(node);
+
+ unsigned startOfStatement = 0;
+ unsigned endOfStatement = (expression ? expression->lastSourceLocation().end() : statement->lastSourceLocation().end()) - _position;
+
+ QString startString = QLatin1String("(function ") + QString::fromUtf8(_name) + QLatin1String("() { ");
+ if (expression)
+ startString += QLatin1String("return ");
+ _writer->replace(startOfStatement, 0, startString);
+ _writer->replace(endOfStatement, 0, QLatin1String(" })"));
+
+ if (rewriteDump()) {
+ qWarning() << "=============================================================";
+ qWarning() << "Rewrote:";
+ qWarning() << qPrintable(code);
+ }
+
+ QString codeCopy = code;
+ w.write(&codeCopy);
+
+ if (rewriteDump()) {
+ qWarning() << "To:";
+ qWarning() << qPrintable(code);
+ qWarning() << "=============================================================";
+ }
+
+ return codeCopy;
+}
+
void RewriteBinding::accept(AST::Node *node)
{
AST::Node::acceptChild(node, this);
diff --git a/src/declarative/qml/qdeclarativerewrite_p.h b/src/declarative/qml/qdeclarativerewrite_p.h
index 6f3c46e..310ef3c 100644
--- a/src/declarative/qml/qdeclarativerewrite_p.h
+++ b/src/declarative/qml/qdeclarativerewrite_p.h
@@ -68,6 +68,7 @@ class SharedBindingTester : protected AST::Visitor
bool _sharable;
public:
bool isSharable(const QString &code);
+ bool isSharable(AST::Node *Node);
virtual bool visit(AST::FunctionDeclaration *) { _sharable = false; return false; }
virtual bool visit(AST::FunctionExpression *) { _sharable = false; return false; }
@@ -81,7 +82,8 @@ class RewriteBinding: protected AST::Visitor
QByteArray _name;
public:
- QString operator()(const QString &code, bool *ok = 0);
+ QString operator()(const QString &code, bool *ok = 0, bool *sharable = 0);
+ QString operator()(QDeclarativeJS::AST::Node *node, const QString &code, bool *sharable = 0);
//name of the function: used for the debugger
void setName(const QByteArray &name) { _name = name; }
diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp
index 57cc9ab..e32a3d2 100644
--- a/src/declarative/qml/qdeclarativescriptparser.cpp
+++ b/src/declarative/qml/qdeclarativescriptparser.cpp
@@ -307,7 +307,6 @@ ProcessAST::defineObjectBinding(AST::UiQualifiedId *propertyName,
obj->location = location;
if (propertyCount) {
-
Property *prop = currentProperty();
Value *v = new Value;
v->object = obj;
diff --git a/src/declarative/qml/qdeclarativesqldatabase.cpp b/src/declarative/qml/qdeclarativesqldatabase.cpp
index bda02a5..a774c02 100644
--- a/src/declarative/qml/qdeclarativesqldatabase.cpp
+++ b/src/declarative/qml/qdeclarativesqldatabase.cpp
@@ -351,7 +351,7 @@ static QScriptValue qmlsqldatabase_read_transaction(QScriptContext *context, QSc
}
/*
- Currently documented in doc/src/declarastive/globalobject.qdoc
+ Currently documented in doc/src/declarative/globalobject.qdoc
*/
static QScriptValue qmlsqldatabase_open_sync(QScriptContext *context, QScriptEngine *engine)
{
diff --git a/src/declarative/qml/qdeclarativestringconverters.cpp b/src/declarative/qml/qdeclarativestringconverters.cpp
index 7534a2c..55fae87 100644
--- a/src/declarative/qml/qdeclarativestringconverters.cpp
+++ b/src/declarative/qml/qdeclarativestringconverters.cpp
@@ -136,7 +136,7 @@ QVariant QDeclarativeStringConverters::variantFromString(const QString &s, int p
QColor QDeclarativeStringConverters::colorFromString(const QString &s, bool *ok)
{
- if (s.startsWith(QLatin1Char('#')) && s.length() == 9) {
+ if (s.length() == 9 && s.startsWith(QLatin1Char('#'))) {
uchar a = fromHex(s, 1);
uchar r = fromHex(s, 3);
uchar g = fromHex(s, 5);
@@ -144,9 +144,7 @@ QColor QDeclarativeStringConverters::colorFromString(const QString &s, bool *ok)
if (ok) *ok = true;
return QColor(r, g, b, a);
} else {
- QColor rv;
- if (s.startsWith(QLatin1Char('#')) || QColor::colorNames().contains(s.toLower()))
- rv = QColor(s);
+ QColor rv(s);
if (ok) *ok = rv.isValid();
return rv;
}
diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp
index c015519..f42e8a7 100644
--- a/src/declarative/qml/qdeclarativetypeloader.cpp
+++ b/src/declarative/qml/qdeclarativetypeloader.cpp
@@ -45,6 +45,7 @@
#include <private/qdeclarativecompiler_p.h>
#include <private/qdeclarativecomponent_p.h>
#include <private/qdeclarativeglobal_p.h>
+#include <private/qdeclarativedebugtrace_p.h>
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtCore/qdebug.h>
@@ -895,10 +896,12 @@ void QDeclarativeTypeData::downloadProgressChanged(qreal p)
void QDeclarativeTypeData::compile()
{
Q_ASSERT(m_compiledData == 0);
+ QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Compiling);
m_compiledData = new QDeclarativeCompiledData(typeLoader()->engine());
m_compiledData->url = m_imports.baseUrl();
m_compiledData->name = m_compiledData->url.toString();
+ QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Compiling, m_compiledData->name);
QDeclarativeCompiler compiler;
if (!compiler.compile(typeLoader()->engine(), this, m_compiledData)) {
@@ -906,6 +909,7 @@ void QDeclarativeTypeData::compile()
m_compiledData->release();
m_compiledData = 0;
}
+ QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Compiling);
}
void QDeclarativeTypeData::resolveTypes()
diff --git a/src/declarative/qml/qdeclarativetypenamescriptclass.cpp b/src/declarative/qml/qdeclarativetypenamescriptclass.cpp
index cba7b4a..e93aae2 100644
--- a/src/declarative/qml/qdeclarativetypenamescriptclass.cpp
+++ b/src/declarative/qml/qdeclarativetypenamescriptclass.cpp
@@ -109,9 +109,8 @@ QDeclarativeTypeNameScriptClass::queryProperty(Object *obj, const Identifier &na
} else if (data->type) {
- QString strName = toString(name);
-
- if (strName.at(0).isUpper()) {
+ if (startsWithUpper(name)) {
+ QString strName = toString(name);
// Must be an enum
if (data->mode == IncludeEnums) {
// ### Optimize
diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp
index 5dc6ffd..bf02de8 100644
--- a/src/declarative/qml/qdeclarativevaluetype.cpp
+++ b/src/declarative/qml/qdeclarativevaluetype.cpp
@@ -71,6 +71,7 @@ int qmlRegisterValueTypeEnums(const char *uri, int versionMajor, int versionMino
0, 0,
+ 0,
0
};
diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp
index c742dec..6ee653b 100644
--- a/src/declarative/qml/qdeclarativevme.cpp
+++ b/src/declarative/qml/qdeclarativevme.cpp
@@ -194,6 +194,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
QDeclarativeData *ddata = QDeclarativeData::get(o);
Q_ASSERT(ddata);
+ if (types.at(instr.create.type).type)
+ ddata->type = types.at(instr.create.type).type;
if (stack.isEmpty()) {
if (ddata->context) {
@@ -249,6 +251,8 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack,
QDeclarativeData *ddata =
(QDeclarativeData *)(((const char *)o) + instr.createSimple.typeSize);
+ if (types.at(instr.createSimple.type).type)
+ ddata->type = types.at(instr.createSimple.type).type;
ddata->lineNumber = instr.line;
ddata->columnNumber = instr.createSimple.column;
diff --git a/src/declarative/qml/qmetaobjectbuilder.cpp b/src/declarative/qml/qmetaobjectbuilder.cpp
index dfe89f8..60cd6a9 100644
--- a/src/declarative/qml/qmetaobjectbuilder.cpp
+++ b/src/declarative/qml/qmetaobjectbuilder.cpp
@@ -122,7 +122,7 @@ enum PropertyFlags {
User = 0x00100000,
ResolveUser = 0x00200000,
Notify = 0x00400000,
- Dynamic = 0x00800000
+ Revisioned = 0x00800000
};
enum MethodFlags {
@@ -139,7 +139,8 @@ enum MethodFlags {
MethodCompatibility = 0x10,
MethodCloned = 0x20,
- MethodScriptable = 0x40
+ MethodScriptable = 0x40,
+ MethodRevisioned = 0x80
};
struct QMetaObjectPrivate
@@ -2277,21 +2278,6 @@ bool QMetaPropertyBuilder::isEnumOrFlag() const
}
/*!
- Returns true if the property has the dynamic flag set;
- otherwise returns false. The default value is false.
-
- \sa setDynamic()
-*/
-bool QMetaPropertyBuilder::isDynamic() const
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- return d->flag(Dynamic);
- else
- return false;
-}
-
-/*!
Sets this property to readable if \a value is true.
\sa isReadable(), setWritable()
@@ -2415,19 +2401,6 @@ void QMetaPropertyBuilder::setEnumOrFlag(bool value)
}
/*!
- Sets this property to have the dynamic flag if \a value is
- true.
-
- \sa isDynamic()
-*/
-void QMetaPropertyBuilder::setDynamic(bool value)
-{
- QMetaPropertyBuilderPrivate *d = d_func();
- if (d)
- d->setFlag(Dynamic, value);
-}
-
-/*!
\class QMetaEnumBuilder
\internal
\brief The QMetaEnumBuilder class enables modifications to an enumerator definition on a meta object builder.
diff --git a/src/declarative/qml/qmetaobjectbuilder_p.h b/src/declarative/qml/qmetaobjectbuilder_p.h
index a90ba63..c270f60 100644
--- a/src/declarative/qml/qmetaobjectbuilder_p.h
+++ b/src/declarative/qml/qmetaobjectbuilder_p.h
@@ -258,7 +258,6 @@ public:
bool isUser() const;
bool hasStdCppSet() const;
bool isEnumOrFlag() const;
- bool isDynamic() const;
void setReadable(bool value);
void setWritable(bool value);
@@ -270,7 +269,6 @@ public:
void setUser(bool value);
void setStdCppSet(bool value);
void setEnumOrFlag(bool value);
- void setDynamic(bool value);
private:
const QMetaObjectBuilder *_mobj;
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 66b69f9..bf9e54a 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -55,7 +55,8 @@ SOURCES += \
$$PWD/qdeclarativedirparser.cpp \
$$PWD/qdeclarativeextensionplugin.cpp \
$$PWD/qdeclarativeimport.cpp \
- $$PWD/qdeclarativelist.cpp
+ $$PWD/qdeclarativelist.cpp \
+ $$PWD/qperformancetimer.cpp
HEADERS += \
$$PWD/qdeclarativeparser_p.h \
@@ -129,8 +130,12 @@ HEADERS += \
$$PWD/qdeclarativedirparser_p.h \
$$PWD/qdeclarativeextensioninterface.h \
$$PWD/qdeclarativeimport_p.h \
- $$PWD/qdeclarativeextensionplugin.h
+ $$PWD/qdeclarativeextensionplugin.h \
+ $$PWD/qperformancetimer_p.h
QT += sql
include(parser/parser.pri)
include(rewriter/rewriter.pri)
+
+# mirrors logic in corelib/kernel/kernel.pri
+unix:!symbian: contains(QT_CONFIG, clock-gettime):include($$QT_SOURCE_TREE/config.tests/unix/clock-gettime/clock-gettime.pri)
diff --git a/src/declarative/qml/qperformancetimer.cpp b/src/declarative/qml/qperformancetimer.cpp
new file mode 100644
index 0000000..1d7ca80
--- /dev/null
+++ b/src/declarative/qml/qperformancetimer.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qperformancetimer_p.h"
+
+#if defined(Q_OS_MAC)
+#include <sys/time.h>
+#include <unistd.h>
+#include <mach/mach_time.h>
+#elif defined(Q_OS_UNIX)
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+#elif defined(Q_OS_SYMBIAN)
+#include <e32std.h>
+#include <sys/time.h>
+#include <hal.h>
+#elif defined(Q_OS_WIN)
+#include <windows.h>
+#endif
+
+// mac/unix code heavily copied from QElapsedTimer
+
+QT_BEGIN_NAMESPACE
+
+////////////////////////////// Mac //////////////////////////////
+#if defined(Q_OS_MAC)
+
+static mach_timebase_info_data_t info = {0,0};
+static qint64 absoluteToNSecs(qint64 cpuTime)
+{
+ if (info.denom == 0)
+ mach_timebase_info(&info);
+ qint64 nsecs = cpuTime * info.numer / info.denom;
+ return nsecs;
+}
+
+void QPerformanceTimer::start()
+{
+ t1 = mach_absolute_time();
+}
+
+qint64 QPerformanceTimer::elapsed() const
+{
+ uint64_t cpu_time = mach_absolute_time();
+ return absoluteToNSecs(cpu_time - t1);
+}
+
+////////////////////////////// Unix //////////////////////////////
+#elif defined(Q_OS_UNIX)
+
+#if defined(QT_NO_CLOCK_MONOTONIC) || defined(QT_BOOTSTRAPPED)
+// turn off the monotonic clock
+# ifdef _POSIX_MONOTONIC_CLOCK
+# undef _POSIX_MONOTONIC_CLOCK
+# endif
+# define _POSIX_MONOTONIC_CLOCK -1
+#endif
+
+#if (_POSIX_MONOTONIC_CLOCK-0 != 0)
+static const bool monotonicClockChecked = true;
+static const bool monotonicClockAvailable = _POSIX_MONOTONIC_CLOCK > 0;
+#else
+static int monotonicClockChecked = false;
+static int monotonicClockAvailable = false;
+#endif
+
+#ifdef Q_CC_GNU
+# define is_likely(x) __builtin_expect((x), 1)
+#else
+# define is_likely(x) (x)
+#endif
+#define load_acquire(x) ((volatile const int&)(x))
+#define store_release(x,v) ((volatile int&)(x) = (v))
+
+static void unixCheckClockType()
+{
+#if (_POSIX_MONOTONIC_CLOCK-0 == 0)
+ if (is_likely(load_acquire(monotonicClockChecked)))
+ return;
+
+# if defined(_SC_MONOTONIC_CLOCK)
+ // detect if the system support monotonic timers
+ long x = sysconf(_SC_MONOTONIC_CLOCK);
+ store_release(monotonicClockAvailable, x >= 200112L);
+# endif
+
+ store_release(monotonicClockChecked, true);
+#endif
+}
+
+static inline void do_gettime(qint64 *sec, qint64 *frac)
+{
+#if (_POSIX_MONOTONIC_CLOCK-0 >= 0)
+ unixCheckClockType();
+ if (is_likely(monotonicClockAvailable)) {
+ timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ *sec = ts.tv_sec;
+ *frac = ts.tv_nsec;
+ return;
+ }
+#endif
+ *sec = 0;
+ *frac = 0;
+}
+
+void QPerformanceTimer::start()
+{
+ do_gettime(&t1, &t2);
+}
+
+qint64 QPerformanceTimer::elapsed() const
+{
+ qint64 sec, frac;
+ do_gettime(&sec, &frac);
+ sec = sec - t1;
+ frac = frac - t2;
+
+ return sec * Q_INT64_C(1000000000) + frac;
+}
+
+////////////////////////////// Symbian //////////////////////////////
+#elif defined(Q_OS_SYMBIAN)
+
+static qint64 getTimeFromTick(quint64 elapsed)
+{
+ static TInt freq;
+ if (!freq)
+ HAL::Get(HALData::EFastCounterFrequency, freq);
+
+ // ### not sure on units
+ return elapsed / freq;
+}
+
+void QPerformanceTimer::start()
+{
+ t1 = User::FastCounter();
+}
+
+qint64 QPerformanceTimer::elapsed() const
+{
+ return getTimeFromTick(User::FastCounter() - t1);
+}
+
+////////////////////////////// Windows //////////////////////////////
+#elif defined(Q_OS_WIN)
+
+static qint64 getTimeFromTick(quint64 elapsed)
+{
+ static LARGE_INTEGER freq;
+ if (!freq.QuadPart)
+ QueryPerformanceFrequency(&freq);
+ return 1000000000 * elapsed / freq.QuadPart;
+}
+
+void QPerformanceTimer::start()
+{
+ LARGE_INTEGER li;
+ QueryPerformanceCounter(&li);
+ t1 = li.QuadPart;
+}
+
+qint64 QPerformanceTimer::elapsed() const
+{
+ LARGE_INTEGER li;
+ QueryPerformanceCounter(&li);
+ return getTimeFromTick(li.QuadPart - t1);
+}
+
+////////////////////////////// Default //////////////////////////////
+#else
+
+// default implementation (no hi-perf timer) does nothing
+void QPerformanceTimer::start()
+{
+}
+
+qint64 QPerformanceTimer::elapsed() const
+{
+ return 0;
+}
+
+#endif
+
+QT_END_NAMESPACE
+
+
diff --git a/src/declarative/qml/qperformancetimer_p.h b/src/declarative/qml/qperformancetimer_p.h
new file mode 100644
index 0000000..14310bf
--- /dev/null
+++ b/src/declarative/qml/qperformancetimer_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPERFORMANCETIMER_P_H
+#define QPERFORMANCETIMER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of moc. This header file may change from version to version without notice,
+// or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class Q_AUTOTEST_EXPORT QPerformanceTimer
+{
+public:
+ void start();
+ qint64 elapsed() const;
+
+private:
+ qint64 t1;
+ qint64 t2;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPERFORMANCETIMER_P_H
diff --git a/src/declarative/util/qdeclarativeconnections.cpp b/src/declarative/util/qdeclarativeconnections.cpp
index 15e5ac5..e102f2c 100644
--- a/src/declarative/util/qdeclarativeconnections.cpp
+++ b/src/declarative/util/qdeclarativeconnections.cpp
@@ -45,6 +45,7 @@
#include <qdeclarativeproperty_p.h>
#include <qdeclarativeboundsignal_p.h>
#include <qdeclarativecontext.h>
+#include <qdeclarativecontext_p.h>
#include <qdeclarativeinfo.h>
#include <QtCore/qdebug.h>
@@ -257,7 +258,11 @@ void QDeclarativeConnections::connectSignals()
if (prop.isValid() && (prop.type() & QDeclarativeProperty::SignalProperty)) {
QDeclarativeBoundSignal *signal =
new QDeclarativeBoundSignal(target(), prop.method(), this);
- signal->setExpression(new QDeclarativeExpression(qmlContext(this), 0, script));
+ QDeclarativeExpression *expression = new QDeclarativeExpression(qmlContext(this), 0, script);
+ QDeclarativeData *ddata = QDeclarativeData::get(this);
+ if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty())
+ expression->setSourceLocation(ddata->outerContext->url.toString(), ddata->lineNumber);
+ signal->setExpression(expression);
d->boundsignals += signal;
} else {
if (!d->ignoreUnknownSignals)
diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp
index 398480e..538e8af 100644
--- a/src/declarative/util/qdeclarativelistmodel.cpp
+++ b/src/declarative/util/qdeclarativelistmodel.cpp
@@ -1450,6 +1450,8 @@ void ModelNode::setObjectValue(const QScriptValue& valuemap, bool writeToCache)
if (v.isArray()) {
value->isArray = true;
value->setListValue(v);
+ if (writeToCache && objectCache)
+ objectCache->setValue(it.name().toUtf8(), QVariant::fromValue(value->model(m_model)));
} else {
value->values << v.toVariant();
if (writeToCache && objectCache)
diff --git a/src/declarative/util/qdeclarativeopenmetaobject.cpp b/src/declarative/util/qdeclarativeopenmetaobject.cpp
index c611435..1426cea 100644
--- a/src/declarative/util/qdeclarativeopenmetaobject.cpp
+++ b/src/declarative/util/qdeclarativeopenmetaobject.cpp
@@ -97,7 +97,6 @@ int QDeclarativeOpenMetaObjectType::createProperty(const QByteArray &name)
int id = d->mob.propertyCount();
d->mob.addSignal("__" + QByteArray::number(id) + "()");
QMetaPropertyBuilder build = d->mob.addProperty(name, "QVariant", id);
- build.setDynamic(true);
propertyCreated(id, build);
qFree(d->mem);
d->mem = d->mob.toMetaObject();
diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp
index 380d9bc..7c0a7f0 100644
--- a/src/declarative/util/qdeclarativepixmapcache.cpp
+++ b/src/declarative/util/qdeclarativepixmapcache.cpp
@@ -959,20 +959,20 @@ QRect QDeclarativePixmap::rect() const
void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url)
{
- load(engine, url, QSize(), false);
+ load(engine, url, QSize(), QDeclarativePixmap::Cached);
}
-void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, bool async)
+void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, QDeclarativePixmap::Options options)
{
- load(engine, url, QSize(), async);
+ load(engine, url, QSize(), options);
}
void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, const QSize &size)
{
- load(engine, url, size, false);
+ load(engine, url, size, QDeclarativePixmap::Cached);
}
-void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, const QSize &requestSize, bool async)
+void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, const QSize &requestSize, QDeclarativePixmap::Options options)
{
if (d) { d->release(); d = 0; }
@@ -982,19 +982,20 @@ void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, const
QHash<QDeclarativePixmapKey, QDeclarativePixmapData *>::Iterator iter = store->m_cache.find(key);
if (iter == store->m_cache.end()) {
- if (async) {
+ if (options & QDeclarativePixmap::Asynchronous) {
// pixmaps can only be loaded synchronously
if (url.scheme() == QLatin1String("image")
&& QDeclarativeEnginePrivate::get(engine)->getImageProviderType(url) == QDeclarativeImageProvider::Pixmap) {
- async = false;
+ options &= ~QDeclarativePixmap::Asynchronous;
}
}
- if (!async) {
+ if (!(options & QDeclarativePixmap::Asynchronous)) {
bool ok = false;
d = createPixmapDataSync(engine, url, requestSize, &ok);
if (ok) {
- d->addToCache();
+ if (options & QDeclarativePixmap::Cached)
+ d->addToCache();
return;
}
if (d) // loadable, but encountered error while loading
@@ -1007,7 +1008,8 @@ void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, const
QDeclarativePixmapReader *reader = QDeclarativePixmapReader::instance(engine);
d = new QDeclarativePixmapData(url, requestSize);
- d->addToCache();
+ if (options & QDeclarativePixmap::Cached)
+ d->addToCache();
d->reply = reader->getImage(d);
} else {
diff --git a/src/declarative/util/qdeclarativepixmapcache_p.h b/src/declarative/util/qdeclarativepixmapcache_p.h
index 2e83cc4..9e1016f 100644
--- a/src/declarative/util/qdeclarativepixmapcache_p.h
+++ b/src/declarative/util/qdeclarativepixmapcache_p.h
@@ -66,6 +66,12 @@ public:
enum Status { Null, Ready, Error, Loading };
+ enum Option {
+ Asynchronous = 0x00000001,
+ Cached = 0x00000002
+ };
+ Q_DECLARE_FLAGS(Options, Option)
+
bool isNull() const;
bool isReady() const;
bool isError() const;
@@ -85,9 +91,9 @@ public:
inline operator const QPixmap &() const;
void load(QDeclarativeEngine *, const QUrl &);
- void load(QDeclarativeEngine *, const QUrl &, bool);
+ void load(QDeclarativeEngine *, const QUrl &, QDeclarativePixmap::Options options);
void load(QDeclarativeEngine *, const QUrl &, const QSize &);
- void load(QDeclarativeEngine *, const QUrl &, const QSize &, bool);
+ void load(QDeclarativeEngine *, const QUrl &, const QSize &, QDeclarativePixmap::Options options);
void clear();
void clear(QObject *);
@@ -107,6 +113,8 @@ inline QDeclarativePixmap::operator const QPixmap &() const
return pixmap();
}
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativePixmap::Options)
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp
index 8d01b80..47f03a1 100644
--- a/src/declarative/util/qdeclarativepropertychanges.cpp
+++ b/src/declarative/util/qdeclarativepropertychanges.cpp
@@ -42,6 +42,9 @@
#include "private/qdeclarativepropertychanges_p.h"
#include "private/qdeclarativeopenmetaobject_p.h"
+#include "private/qdeclarativerewrite_p.h"
+#include "private/qdeclarativeengine_p.h"
+#include "private/qdeclarativecompiler_p.h"
#include <qdeclarativeinfo.h>
#include <qdeclarativecustomparser_p.h>
@@ -217,11 +220,22 @@ public:
void decode();
- QList<QPair<QByteArray, QVariant> > properties;
- QList<QPair<QByteArray, QDeclarativeExpression *> > expressions;
+ class ExpressionChange {
+ public:
+ ExpressionChange(const QString &_name,
+ QDeclarativeBinding::Identifier _id,
+ QDeclarativeExpression *_expr)
+ : name(_name), id(_id), expression(_expr) {}
+ QString name;
+ QDeclarativeBinding::Identifier id;
+ QDeclarativeExpression *expression;
+ };
+
+ QList<QPair<QString, QVariant> > properties;
+ QList<ExpressionChange> expressions;
QList<QDeclarativeReplaceSignalHandler*> signalReplacements;
- QDeclarativeProperty property(const QByteArray &);
+ QDeclarativeProperty property(const QString &);
};
void
@@ -267,6 +281,7 @@ QDeclarativePropertyChangesParser::compile(const QList<QDeclarativeCustomParserP
QDeclarativeParser::Variant v = qvariant_cast<QDeclarativeParser::Variant>(data.at(ii).second);
QVariant var;
bool isScript = v.isScript();
+ QDeclarativeBinding::Identifier id;
switch(v.type()) {
case QDeclarativeParser::Variant::Boolean:
var = QVariant(v.asBoolean());
@@ -280,10 +295,17 @@ QDeclarativePropertyChangesParser::compile(const QList<QDeclarativeCustomParserP
case QDeclarativeParser::Variant::Invalid:
case QDeclarativeParser::Variant::Script:
var = QVariant(v.asScript());
+ {
+ // Pre-rewrite the expression
+ QString expression = v.asScript();
+ id = rewriteBinding(expression, data.at(ii).first); //### recreates the AST, which is slow
+ }
break;
}
- ds << data.at(ii).first << isScript << var;
+ ds << QString::fromUtf8(data.at(ii).first) << isScript << var;
+ if (isScript)
+ ds << id;
}
return rv;
@@ -300,12 +322,15 @@ void QDeclarativePropertyChangesPrivate::decode()
int count;
ds >> count;
for (int ii = 0; ii < count; ++ii) {
- QByteArray name;
+ QString name;
bool isScript;
QVariant data;
+ QDeclarativeBinding::Identifier id = QDeclarativeBinding::Invalid;
ds >> name;
ds >> isScript;
ds >> data;
+ if (isScript)
+ ds >> id;
QDeclarativeProperty prop = property(name); //### better way to check for signal property?
if (prop.type() & QDeclarativeProperty::SignalProperty) {
@@ -322,7 +347,7 @@ void QDeclarativePropertyChangesPrivate::decode()
QDeclarativeData *ddata = QDeclarativeData::get(q);
if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty())
expression->setSourceLocation(ddata->outerContext->url.toString(), ddata->lineNumber);
- expressions << qMakePair(name, expression);
+ expressions << ExpressionChange(name, id, expression);
} else {
properties << qMakePair(name, data);
}
@@ -350,7 +375,7 @@ QDeclarativePropertyChanges::~QDeclarativePropertyChanges()
{
Q_D(QDeclarativePropertyChanges);
for(int ii = 0; ii < d->expressions.count(); ++ii)
- delete d->expressions.at(ii).second;
+ delete d->expressions.at(ii).expression;
for(int ii = 0; ii < d->signalReplacements.count(); ++ii)
delete d->signalReplacements.at(ii);
}
@@ -389,15 +414,15 @@ void QDeclarativePropertyChanges::setRestoreEntryValues(bool v)
}
QDeclarativeProperty
-QDeclarativePropertyChangesPrivate::property(const QByteArray &property)
+QDeclarativePropertyChangesPrivate::property(const QString &property)
{
Q_Q(QDeclarativePropertyChanges);
- QDeclarativeProperty prop(object, QString::fromUtf8(property), qmlContext(q));
+ QDeclarativeProperty prop(object, property, qmlContext(q));
if (!prop.isValid()) {
- qmlInfo(q) << QDeclarativePropertyChanges::tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(property));
+ qmlInfo(q) << QDeclarativePropertyChanges::tr("Cannot assign to non-existent property \"%1\"").arg(property);
return QDeclarativeProperty();
} else if (!(prop.type() & QDeclarativeProperty::SignalProperty) && !prop.isWritable()) {
- qmlInfo(q) << QDeclarativePropertyChanges::tr("Cannot assign to read-only property \"%1\"").arg(QString::fromUtf8(property));
+ qmlInfo(q) << QDeclarativePropertyChanges::tr("Cannot assign to read-only property \"%1\"").arg(property);
return QDeclarativeProperty();
}
return prop;
@@ -413,9 +438,7 @@ QDeclarativePropertyChanges::ActionList QDeclarativePropertyChanges::actions()
for (int ii = 0; ii < d->properties.count(); ++ii) {
- QByteArray property = d->properties.at(ii).first;
-
- QDeclarativeAction a(d->object, QString::fromUtf8(property),
+ QDeclarativeAction a(d->object, d->properties.at(ii).first,
qmlContext(this), d->properties.at(ii).second);
if (a.property.isValid()) {
@@ -437,7 +460,7 @@ QDeclarativePropertyChanges::ActionList QDeclarativePropertyChanges::actions()
for (int ii = 0; ii < d->expressions.count(); ++ii) {
- QByteArray property = d->expressions.at(ii).first;
+ const QString &property = d->expressions.at(ii).name;
QDeclarativeProperty prop = d->property(property);
if (prop.isValid()) {
@@ -446,16 +469,20 @@ QDeclarativePropertyChanges::ActionList QDeclarativePropertyChanges::actions()
a.property = prop;
a.fromValue = a.property.read();
a.specifiedObject = d->object;
- a.specifiedProperty = QString::fromUtf8(property);
+ a.specifiedProperty = property;
if (d->isExplicit) {
- a.toValue = d->expressions.at(ii).second->evaluate();
+ a.toValue = d->expressions.at(ii).expression->evaluate();
} else {
- QDeclarativeExpression *e = d->expressions.at(ii).second;
- QDeclarativeBinding *newBinding =
- new QDeclarativeBinding(e->expression(), object(), qmlContext(this));
+ QDeclarativeExpression *e = d->expressions.at(ii).expression;
+
+ QDeclarativeBinding::Identifier id = d->expressions.at(ii).id;
+ QDeclarativeBinding *newBinding = id != QDeclarativeBinding::Invalid ? QDeclarativeBinding::createBinding(id, object(), qmlContext(this), e->sourceFile(), e->lineNumber()) : 0;
+ if (!newBinding) {
+ newBinding = new QDeclarativeBinding(e->expression(), object(), qmlContext(this));
+ newBinding->setSourceLocation(e->sourceFile(), e->lineNumber());
+ }
newBinding->setTarget(prop);
- newBinding->setSourceLocation(e->sourceFile(), e->lineNumber());
a.toBinding = newBinding;
a.deletableToBinding = true;
}
@@ -498,10 +525,10 @@ void QDeclarativePropertyChanges::setIsExplicit(bool e)
d->isExplicit = e;
}
-bool QDeclarativePropertyChanges::containsValue(const QByteArray &name) const
+bool QDeclarativePropertyChanges::containsValue(const QString &name) const
{
Q_D(const QDeclarativePropertyChanges);
- typedef QPair<QByteArray, QVariant> PropertyEntry;
+ typedef QPair<QString, QVariant> PropertyEntry;
QListIterator<PropertyEntry> propertyIterator(d->properties);
while (propertyIterator.hasNext()) {
@@ -514,15 +541,15 @@ bool QDeclarativePropertyChanges::containsValue(const QByteArray &name) const
return false;
}
-bool QDeclarativePropertyChanges::containsExpression(const QByteArray &name) const
+bool QDeclarativePropertyChanges::containsExpression(const QString &name) const
{
Q_D(const QDeclarativePropertyChanges);
- typedef QPair<QByteArray, QDeclarativeExpression *> ExpressionEntry;
+ typedef QDeclarativePropertyChangesPrivate::ExpressionChange ExpressionEntry;
QListIterator<ExpressionEntry> expressionIterator(d->expressions);
while (expressionIterator.hasNext()) {
const ExpressionEntry &entry = expressionIterator.next();
- if (entry.first == name) {
+ if (entry.name == name) {
return true;
}
}
@@ -530,21 +557,21 @@ bool QDeclarativePropertyChanges::containsExpression(const QByteArray &name) con
return false;
}
-bool QDeclarativePropertyChanges::containsProperty(const QByteArray &name) const
+bool QDeclarativePropertyChanges::containsProperty(const QString &name) const
{
return containsValue(name) || containsExpression(name);
}
-void QDeclarativePropertyChanges::changeValue(const QByteArray &name, const QVariant &value)
+void QDeclarativePropertyChanges::changeValue(const QString &name, const QVariant &value)
{
Q_D(QDeclarativePropertyChanges);
- typedef QPair<QByteArray, QVariant> PropertyEntry;
- typedef QPair<QByteArray, QDeclarativeExpression *> ExpressionEntry;
+ typedef QPair<QString, QVariant> PropertyEntry;
+ typedef QDeclarativePropertyChangesPrivate::ExpressionChange ExpressionEntry;
QMutableListIterator<ExpressionEntry> expressionIterator(d->expressions);
while (expressionIterator.hasNext()) {
const ExpressionEntry &entry = expressionIterator.next();
- if (entry.first == name) {
+ if (entry.name == name) {
expressionIterator.remove();
if (state() && state()->isStateActive()) {
QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::binding(d->property(name));
@@ -576,7 +603,7 @@ void QDeclarativePropertyChanges::changeValue(const QByteArray &name, const QVar
action.property = d->property(name);
action.fromValue = action.property.read();
action.specifiedObject = object();
- action.specifiedProperty = QString::fromUtf8(name);
+ action.specifiedProperty = name;
action.toValue = value;
propertyIterator.insert(PropertyEntry(name, value));
@@ -589,11 +616,11 @@ void QDeclarativePropertyChanges::changeValue(const QByteArray &name, const QVar
}
}
-void QDeclarativePropertyChanges::changeExpression(const QByteArray &name, const QString &expression)
+void QDeclarativePropertyChanges::changeExpression(const QString &name, const QString &expression)
{
Q_D(QDeclarativePropertyChanges);
- typedef QPair<QByteArray, QVariant> PropertyEntry;
- typedef QPair<QByteArray, QDeclarativeExpression *> ExpressionEntry;
+ typedef QPair<QString, QVariant> PropertyEntry;
+ typedef QDeclarativePropertyChangesPrivate::ExpressionChange ExpressionEntry;
bool hadValue = false;
@@ -610,8 +637,8 @@ void QDeclarativePropertyChanges::changeExpression(const QByteArray &name, const
QMutableListIterator<ExpressionEntry> expressionIterator(d->expressions);
while (expressionIterator.hasNext()) {
const ExpressionEntry &entry = expressionIterator.next();
- if (entry.first == name) {
- entry.second->setExpression(expression);
+ if (entry.name == name) {
+ entry.expression->setExpression(expression);
if (state() && state()->isStateActive()) {
QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::binding(d->property(name));
if (oldBinding) {
@@ -628,7 +655,7 @@ void QDeclarativePropertyChanges::changeExpression(const QByteArray &name, const
}
QDeclarativeExpression *newExpression = new QDeclarativeExpression(qmlContext(this), d->object, expression);
- expressionIterator.insert(ExpressionEntry(name, newExpression));
+ expressionIterator.insert(ExpressionEntry(name, QDeclarativeBinding::Invalid, newExpression));
if (state() && state()->isStateActive()) {
if (hadValue) {
@@ -647,7 +674,7 @@ void QDeclarativePropertyChanges::changeExpression(const QByteArray &name, const
action.property = d->property(name);
action.fromValue = action.property.read();
action.specifiedObject = object();
- action.specifiedProperty = QString::fromUtf8(name);
+ action.specifiedProperty = name;
if (d->isExplicit) {
@@ -670,11 +697,11 @@ void QDeclarativePropertyChanges::changeExpression(const QByteArray &name, const
// what about the signal handler?
}
-QVariant QDeclarativePropertyChanges::property(const QByteArray &name) const
+QVariant QDeclarativePropertyChanges::property(const QString &name) const
{
Q_D(const QDeclarativePropertyChanges);
- typedef QPair<QByteArray, QVariant> PropertyEntry;
- typedef QPair<QByteArray, QDeclarativeExpression *> ExpressionEntry;
+ typedef QPair<QString, QVariant> PropertyEntry;
+ typedef QDeclarativePropertyChangesPrivate::ExpressionChange ExpressionEntry;
QListIterator<PropertyEntry> propertyIterator(d->properties);
while (propertyIterator.hasNext()) {
@@ -687,24 +714,24 @@ QVariant QDeclarativePropertyChanges::property(const QByteArray &name) const
QListIterator<ExpressionEntry> expressionIterator(d->expressions);
while (expressionIterator.hasNext()) {
const ExpressionEntry &entry = expressionIterator.next();
- if (entry.first == name) {
- return QVariant(entry.second->expression());
+ if (entry.name == name) {
+ return QVariant(entry.expression->expression());
}
}
return QVariant();
}
-void QDeclarativePropertyChanges::removeProperty(const QByteArray &name)
+void QDeclarativePropertyChanges::removeProperty(const QString &name)
{
Q_D(QDeclarativePropertyChanges);
- typedef QPair<QByteArray, QVariant> PropertyEntry;
- typedef QPair<QByteArray, QDeclarativeExpression *> ExpressionEntry;
+ typedef QPair<QString, QVariant> PropertyEntry;
+ typedef QDeclarativePropertyChangesPrivate::ExpressionChange ExpressionEntry;
QMutableListIterator<ExpressionEntry> expressionIterator(d->expressions);
while (expressionIterator.hasNext()) {
const ExpressionEntry &entry = expressionIterator.next();
- if (entry.first == name) {
+ if (entry.name == name) {
expressionIterator.remove();
state()->removeEntryFromRevertList(object(), name);
return;
@@ -722,10 +749,10 @@ void QDeclarativePropertyChanges::removeProperty(const QByteArray &name)
}
}
-QVariant QDeclarativePropertyChanges::value(const QByteArray &name) const
+QVariant QDeclarativePropertyChanges::value(const QString &name) const
{
Q_D(const QDeclarativePropertyChanges);
- typedef QPair<QByteArray, QVariant> PropertyEntry;
+ typedef QPair<QString, QVariant> PropertyEntry;
QListIterator<PropertyEntry> propertyIterator(d->properties);
while (propertyIterator.hasNext()) {
@@ -738,16 +765,16 @@ QVariant QDeclarativePropertyChanges::value(const QByteArray &name) const
return QVariant();
}
-QString QDeclarativePropertyChanges::expression(const QByteArray &name) const
+QString QDeclarativePropertyChanges::expression(const QString &name) const
{
Q_D(const QDeclarativePropertyChanges);
- typedef QPair<QByteArray, QDeclarativeExpression *> ExpressionEntry;
+ typedef QDeclarativePropertyChangesPrivate::ExpressionChange ExpressionEntry;
QListIterator<ExpressionEntry> expressionIterator(d->expressions);
while (expressionIterator.hasNext()) {
const ExpressionEntry &entry = expressionIterator.next();
- if (entry.first == name) {
- return entry.second->expression();
+ if (entry.name == name) {
+ return entry.expression->expression();
}
}
diff --git a/src/declarative/util/qdeclarativepropertychanges_p.h b/src/declarative/util/qdeclarativepropertychanges_p.h
index 449574c..1a98cec 100644
--- a/src/declarative/util/qdeclarativepropertychanges_p.h
+++ b/src/declarative/util/qdeclarativepropertychanges_p.h
@@ -75,19 +75,19 @@ public:
virtual ActionList actions();
- bool containsProperty(const QByteArray &name) const;
- bool containsValue(const QByteArray &name) const;
- bool containsExpression(const QByteArray &name) const;
- void changeValue(const QByteArray &name, const QVariant &value);
- void changeExpression(const QByteArray &name, const QString &expression);
- void removeProperty(const QByteArray &name);
- QVariant value(const QByteArray &name) const;
- QString expression(const QByteArray &name) const;
+ bool containsProperty(const QString &name) const;
+ bool containsValue(const QString &name) const;
+ bool containsExpression(const QString &name) const;
+ void changeValue(const QString &name, const QVariant &value);
+ void changeExpression(const QString &name, const QString &expression);
+ void removeProperty(const QString &name);
+ QVariant value(const QString &name) const;
+ QString expression(const QString &name) const;
void detachFromState();
void attachToState();
- QVariant property(const QByteArray &name) const;
+ QVariant property(const QString &name) const;
};
class QDeclarativePropertyChangesParser : public QDeclarativeCustomParser
diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp
index 3915485..cde6f00 100644
--- a/src/declarative/util/qdeclarativestate.cpp
+++ b/src/declarative/util/qdeclarativestate.cpp
@@ -66,7 +66,7 @@ QDeclarativeAction::QDeclarativeAction()
QDeclarativeAction::QDeclarativeAction(QObject *target, const QString &propertyName,
const QVariant &value)
: restore(true), actionDone(false), reverseEvent(false), deletableToBinding(false),
- property(target, propertyName), toValue(value),
+ property(target, propertyName, qmlEngine(target)), toValue(value),
fromBinding(0), event(0),
specifiedObject(target), specifiedProperty(propertyName)
{
@@ -370,7 +370,7 @@ void QDeclarativeAction::deleteFromBinding()
}
}
-bool QDeclarativeState::containsPropertyInRevertList(QObject *target, const QByteArray &name) const
+bool QDeclarativeState::containsPropertyInRevertList(QObject *target, const QString &name) const
{
Q_D(const QDeclarativeState);
@@ -379,7 +379,7 @@ bool QDeclarativeState::containsPropertyInRevertList(QObject *target, const QByt
while (revertListIterator.hasNext()) {
const QDeclarativeSimpleAction &simpleAction = revertListIterator.next();
- if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty().toUtf8() == name)
+ if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name)
return true;
}
}
@@ -387,7 +387,7 @@ bool QDeclarativeState::containsPropertyInRevertList(QObject *target, const QByt
return false;
}
-bool QDeclarativeState::changeValueInRevertList(QObject *target, const QByteArray &name, const QVariant &revertValue)
+bool QDeclarativeState::changeValueInRevertList(QObject *target, const QString &name, const QVariant &revertValue)
{
Q_D(QDeclarativeState);
@@ -396,7 +396,7 @@ bool QDeclarativeState::changeValueInRevertList(QObject *target, const QByteArra
while (revertListIterator.hasNext()) {
QDeclarativeSimpleAction &simpleAction = revertListIterator.next();
- if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty().toUtf8() == name) {
+ if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name) {
simpleAction.setValue(revertValue);
return true;
}
@@ -406,7 +406,7 @@ bool QDeclarativeState::changeValueInRevertList(QObject *target, const QByteArra
return false;
}
-bool QDeclarativeState::changeBindingInRevertList(QObject *target, const QByteArray &name, QDeclarativeAbstractBinding *binding)
+bool QDeclarativeState::changeBindingInRevertList(QObject *target, const QString &name, QDeclarativeAbstractBinding *binding)
{
Q_D(QDeclarativeState);
@@ -415,7 +415,7 @@ bool QDeclarativeState::changeBindingInRevertList(QObject *target, const QByteAr
while (revertListIterator.hasNext()) {
QDeclarativeSimpleAction &simpleAction = revertListIterator.next();
- if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty().toUtf8() == name) {
+ if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name) {
if (simpleAction.binding())
simpleAction.binding()->destroy();
@@ -428,7 +428,7 @@ bool QDeclarativeState::changeBindingInRevertList(QObject *target, const QByteAr
return false;
}
-bool QDeclarativeState::removeEntryFromRevertList(QObject *target, const QByteArray &name)
+bool QDeclarativeState::removeEntryFromRevertList(QObject *target, const QString &name)
{
Q_D(QDeclarativeState);
@@ -437,7 +437,7 @@ bool QDeclarativeState::removeEntryFromRevertList(QObject *target, const QByteAr
while (revertListIterator.hasNext()) {
QDeclarativeSimpleAction &simpleAction = revertListIterator.next();
- if (simpleAction.property().object() == target && simpleAction.property().name().toUtf8() == name) {
+ if (simpleAction.property().object() == target && simpleAction.property().name() == name) {
QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::binding(simpleAction.property());
if (oldBinding) {
QDeclarativePropertyPrivate::setBinding(simpleAction.property(), 0);
@@ -517,7 +517,7 @@ void QDeclarativeState::addEntriesToRevertList(const QList<QDeclarativeAction> &
}
}
-QVariant QDeclarativeState::valueInRevertList(QObject *target, const QByteArray &name) const
+QVariant QDeclarativeState::valueInRevertList(QObject *target, const QString &name) const
{
Q_D(const QDeclarativeState);
@@ -526,7 +526,7 @@ QVariant QDeclarativeState::valueInRevertList(QObject *target, const QByteArray
while (revertListIterator.hasNext()) {
const QDeclarativeSimpleAction &simpleAction = revertListIterator.next();
- if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty().toUtf8() == name)
+ if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name)
return simpleAction.value();
}
}
@@ -534,7 +534,7 @@ QVariant QDeclarativeState::valueInRevertList(QObject *target, const QByteArray
return QVariant();
}
-QDeclarativeAbstractBinding *QDeclarativeState::bindingInRevertList(QObject *target, const QByteArray &name) const
+QDeclarativeAbstractBinding *QDeclarativeState::bindingInRevertList(QObject *target, const QString &name) const
{
Q_D(const QDeclarativeState);
@@ -543,7 +543,7 @@ QDeclarativeAbstractBinding *QDeclarativeState::bindingInRevertList(QObject *tar
while (revertListIterator.hasNext()) {
const QDeclarativeSimpleAction &simpleAction = revertListIterator.next();
- if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty().toUtf8() == name)
+ if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name)
return simpleAction.binding();
}
}
diff --git a/src/declarative/util/qdeclarativestate_p.h b/src/declarative/util/qdeclarativestate_p.h
index 7b9c18a..dd43a50 100644
--- a/src/declarative/util/qdeclarativestate_p.h
+++ b/src/declarative/util/qdeclarativestate_p.h
@@ -180,15 +180,15 @@ public:
QDeclarativeStateGroup *stateGroup() const;
void setStateGroup(QDeclarativeStateGroup *);
- bool containsPropertyInRevertList(QObject *target, const QByteArray &name) const;
- bool changeValueInRevertList(QObject *target, const QByteArray &name, const QVariant &revertValue);
- bool changeBindingInRevertList(QObject *target, const QByteArray &name, QDeclarativeAbstractBinding *binding);
- bool removeEntryFromRevertList(QObject *target, const QByteArray &name);
+ bool containsPropertyInRevertList(QObject *target, const QString &name) const;
+ bool changeValueInRevertList(QObject *target, const QString &name, const QVariant &revertValue);
+ bool changeBindingInRevertList(QObject *target, const QString &name, QDeclarativeAbstractBinding *binding);
+ bool removeEntryFromRevertList(QObject *target, const QString &name);
void addEntryToRevertList(const QDeclarativeAction &action);
void removeAllEntriesFromRevertList(QObject *target);
void addEntriesToRevertList(const QList<QDeclarativeAction> &actions);
- QVariant valueInRevertList(QObject *target, const QByteArray &name) const;
- QDeclarativeAbstractBinding *bindingInRevertList(QObject *target, const QByteArray &name) const;
+ QVariant valueInRevertList(QObject *target, const QString &name) const;
+ QDeclarativeAbstractBinding *bindingInRevertList(QObject *target, const QString &name) const;
bool isStateActive() const;
diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp
index d1d7822..b606ff3 100644
--- a/src/declarative/util/qdeclarativestateoperations.cpp
+++ b/src/declarative/util/qdeclarativestateoperations.cpp
@@ -83,6 +83,13 @@ public:
QDeclarativeNullableValue<QDeclarativeScriptString> scaleString;
QDeclarativeNullableValue<QDeclarativeScriptString> rotationString;
+ QDeclarativeNullableValue<qreal> x;
+ QDeclarativeNullableValue<qreal> y;
+ QDeclarativeNullableValue<qreal> width;
+ QDeclarativeNullableValue<qreal> height;
+ QDeclarativeNullableValue<qreal> scale;
+ QDeclarativeNullableValue<qreal> rotation;
+
void doChange(QDeclarativeItem *targetParent, QDeclarativeItem *stackBefore = 0);
};
@@ -213,10 +220,21 @@ QDeclarativeScriptString QDeclarativeParentChange::x() const
return d->xString.value;
}
+void tryReal(QDeclarativeNullableValue<qreal> &value, const QString &string)
+{
+ bool ok = false;
+ qreal realValue = string.toFloat(&ok);
+ if (ok)
+ value = realValue;
+ else
+ value.invalidate();
+}
+
void QDeclarativeParentChange::setX(QDeclarativeScriptString x)
{
Q_D(QDeclarativeParentChange);
d->xString = x;
+ tryReal(d->x, x.script());
}
bool QDeclarativeParentChange::xIsSet() const
@@ -235,6 +253,7 @@ void QDeclarativeParentChange::setY(QDeclarativeScriptString y)
{
Q_D(QDeclarativeParentChange);
d->yString = y;
+ tryReal(d->y, y.script());
}
bool QDeclarativeParentChange::yIsSet() const
@@ -253,6 +272,7 @@ void QDeclarativeParentChange::setWidth(QDeclarativeScriptString width)
{
Q_D(QDeclarativeParentChange);
d->widthString = width;
+ tryReal(d->width, width.script());
}
bool QDeclarativeParentChange::widthIsSet() const
@@ -271,6 +291,7 @@ void QDeclarativeParentChange::setHeight(QDeclarativeScriptString height)
{
Q_D(QDeclarativeParentChange);
d->heightString = height;
+ tryReal(d->height, height.script());
}
bool QDeclarativeParentChange::heightIsSet() const
@@ -289,6 +310,7 @@ void QDeclarativeParentChange::setScale(QDeclarativeScriptString scale)
{
Q_D(QDeclarativeParentChange);
d->scaleString = scale;
+ tryReal(d->scale, scale.script());
}
bool QDeclarativeParentChange::scaleIsSet() const
@@ -307,6 +329,7 @@ void QDeclarativeParentChange::setRotation(QDeclarativeScriptString rotation)
{
Q_D(QDeclarativeParentChange);
d->rotationString = rotation;
+ tryReal(d->rotation, rotation.script());
}
bool QDeclarativeParentChange::rotationIsSet() const
@@ -367,16 +390,15 @@ QDeclarativeStateOperation::ActionList QDeclarativeParentChange::actions()
a.event = this;
actions << a;
+ QDeclarativeContext *ctxt = qmlContext(this);
+
if (d->xString.isValid()) {
- bool ok = false;
- QString script = d->xString.value.script();
- qreal x = script.toFloat(&ok);
- if (ok) {
- QDeclarativeAction xa(d->target, QLatin1String("x"), x);
+ if (d->x.isValid()) {
+ QDeclarativeAction xa(d->target, QLatin1String("x"), ctxt, d->x.value);
actions << xa;
} else {
- QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
- newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("x")));
+ QDeclarativeBinding *newBinding = new QDeclarativeBinding(d->xString.value.script(), d->target, ctxt);
+ newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("x"), ctxt));
QDeclarativeAction xa;
xa.property = newBinding->property();
xa.toBinding = newBinding;
@@ -387,15 +409,12 @@ QDeclarativeStateOperation::ActionList QDeclarativeParentChange::actions()
}
if (d->yString.isValid()) {
- bool ok = false;
- QString script = d->yString.value.script();
- qreal y = script.toFloat(&ok);
- if (ok) {
- QDeclarativeAction ya(d->target, QLatin1String("y"), y);
+ if (d->y.isValid()) {
+ QDeclarativeAction ya(d->target, QLatin1String("y"), ctxt, d->y.value);
actions << ya;
} else {
- QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
- newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("y")));
+ QDeclarativeBinding *newBinding = new QDeclarativeBinding(d->yString.value.script(), d->target, ctxt);
+ newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("y"), ctxt));
QDeclarativeAction ya;
ya.property = newBinding->property();
ya.toBinding = newBinding;
@@ -406,15 +425,12 @@ QDeclarativeStateOperation::ActionList QDeclarativeParentChange::actions()
}
if (d->scaleString.isValid()) {
- bool ok = false;
- QString script = d->scaleString.value.script();
- qreal scale = script.toFloat(&ok);
- if (ok) {
- QDeclarativeAction sa(d->target, QLatin1String("scale"), scale);
+ if (d->scale.isValid()) {
+ QDeclarativeAction sa(d->target, QLatin1String("scale"), ctxt, d->scale.value);
actions << sa;
} else {
- QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
- newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("scale")));
+ QDeclarativeBinding *newBinding = new QDeclarativeBinding(d->scaleString.value.script(), d->target, ctxt);
+ newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("scale"), ctxt));
QDeclarativeAction sa;
sa.property = newBinding->property();
sa.toBinding = newBinding;
@@ -425,15 +441,12 @@ QDeclarativeStateOperation::ActionList QDeclarativeParentChange::actions()
}
if (d->rotationString.isValid()) {
- bool ok = false;
- QString script = d->rotationString.value.script();
- qreal rotation = script.toFloat(&ok);
- if (ok) {
- QDeclarativeAction ra(d->target, QLatin1String("rotation"), rotation);
+ if (d->rotation.isValid()) {
+ QDeclarativeAction ra(d->target, QLatin1String("rotation"), ctxt, d->rotation.value);
actions << ra;
} else {
- QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
- newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("rotation")));
+ QDeclarativeBinding *newBinding = new QDeclarativeBinding(d->rotationString.value.script(), d->target, ctxt);
+ newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("rotation"), ctxt));
QDeclarativeAction ra;
ra.property = newBinding->property();
ra.toBinding = newBinding;
@@ -444,15 +457,12 @@ QDeclarativeStateOperation::ActionList QDeclarativeParentChange::actions()
}
if (d->widthString.isValid()) {
- bool ok = false;
- QString script = d->widthString.value.script();
- qreal width = script.toFloat(&ok);
- if (ok) {
- QDeclarativeAction wa(d->target, QLatin1String("width"), width);
+ if (d->width.isValid()) {
+ QDeclarativeAction wa(d->target, QLatin1String("width"), ctxt, d->width.value);
actions << wa;
} else {
- QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
- newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("width")));
+ QDeclarativeBinding *newBinding = new QDeclarativeBinding(d->widthString.value.script(), d->target, ctxt);
+ newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("width"), ctxt));
QDeclarativeAction wa;
wa.property = newBinding->property();
wa.toBinding = newBinding;
@@ -463,15 +473,12 @@ QDeclarativeStateOperation::ActionList QDeclarativeParentChange::actions()
}
if (d->heightString.isValid()) {
- bool ok = false;
- QString script = d->heightString.value.script();
- qreal height = script.toFloat(&ok);
- if (ok) {
- QDeclarativeAction ha(d->target, QLatin1String("height"), height);
+ if (d->height.isValid()) {
+ QDeclarativeAction ha(d->target, QLatin1String("height"), ctxt, d->height.value);
actions << ha;
} else {
- QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
- newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("height")));
+ QDeclarativeBinding *newBinding = new QDeclarativeBinding(d->heightString.value.script(), d->target, ctxt);
+ newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("height"), ctxt));
QDeclarativeAction ha;
ha.property = newBinding->property();
ha.toBinding = newBinding;
@@ -1075,32 +1082,34 @@ QDeclarativeAnchorChanges::ActionList QDeclarativeAnchorChanges::actions()
d->vCenterProp = QDeclarativeProperty(d->target, QLatin1String("anchors.verticalCenter"));
d->baselineProp = QDeclarativeProperty(d->target, QLatin1String("anchors.baseline"));
+ QDeclarativeContext *ctxt = qmlContext(this);
+
if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::LeftAnchor) {
- d->leftBinding = new QDeclarativeBinding(d->anchorSet->d_func()->leftScript.script(), d->target, qmlContext(this));
+ d->leftBinding = new QDeclarativeBinding(d->anchorSet->d_func()->leftScript.script(), d->target, ctxt);
d->leftBinding->setTarget(d->leftProp);
}
if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::RightAnchor) {
- d->rightBinding = new QDeclarativeBinding(d->anchorSet->d_func()->rightScript.script(), d->target, qmlContext(this));
+ d->rightBinding = new QDeclarativeBinding(d->anchorSet->d_func()->rightScript.script(), d->target, ctxt);
d->rightBinding->setTarget(d->rightProp);
}
if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::HCenterAnchor) {
- d->hCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->hCenterScript.script(), d->target, qmlContext(this));
+ d->hCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->hCenterScript.script(), d->target, ctxt);
d->hCenterBinding->setTarget(d->hCenterProp);
}
if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::TopAnchor) {
- d->topBinding = new QDeclarativeBinding(d->anchorSet->d_func()->topScript.script(), d->target, qmlContext(this));
+ d->topBinding = new QDeclarativeBinding(d->anchorSet->d_func()->topScript.script(), d->target, ctxt);
d->topBinding->setTarget(d->topProp);
}
if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::BottomAnchor) {
- d->bottomBinding = new QDeclarativeBinding(d->anchorSet->d_func()->bottomScript.script(), d->target, qmlContext(this));
+ d->bottomBinding = new QDeclarativeBinding(d->anchorSet->d_func()->bottomScript.script(), d->target, ctxt);
d->bottomBinding->setTarget(d->bottomProp);
}
if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::VCenterAnchor) {
- d->vCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->vCenterScript.script(), d->target, qmlContext(this));
+ d->vCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->vCenterScript.script(), d->target, ctxt);
d->vCenterBinding->setTarget(d->vCenterProp);
}
if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::BaselineAnchor) {
- d->baselineBinding = new QDeclarativeBinding(d->anchorSet->d_func()->baselineScript.script(), d->target, qmlContext(this));
+ d->baselineBinding = new QDeclarativeBinding(d->anchorSet->d_func()->baselineScript.script(), d->target, ctxt);
d->baselineBinding->setTarget(d->baselineProp);
}
@@ -1380,24 +1389,25 @@ QList<QDeclarativeAction> QDeclarativeAnchorChanges::additionalActions()
bool vChange = combined & QDeclarativeAnchors::Vertical_Mask;
if (d->target) {
+ QDeclarativeContext *ctxt = qmlContext(this);
QDeclarativeAction a;
if (hChange && d->fromX != d->toX) {
- a.property = QDeclarativeProperty(d->target, QLatin1String("x"));
+ a.property = QDeclarativeProperty(d->target, QLatin1String("x"), ctxt);
a.toValue = d->toX;
extra << a;
}
if (vChange && d->fromY != d->toY) {
- a.property = QDeclarativeProperty(d->target, QLatin1String("y"));
+ a.property = QDeclarativeProperty(d->target, QLatin1String("y"), ctxt);
a.toValue = d->toY;
extra << a;
}
if (hChange && d->fromWidth != d->toWidth) {
- a.property = QDeclarativeProperty(d->target, QLatin1String("width"));
+ a.property = QDeclarativeProperty(d->target, QLatin1String("width"), ctxt);
a.toValue = d->toWidth;
extra << a;
}
if (vChange && d->fromHeight != d->toHeight) {
- a.property = QDeclarativeProperty(d->target, QLatin1String("height"));
+ a.property = QDeclarativeProperty(d->target, QLatin1String("height"), ctxt);
a.toValue = d->toHeight;
extra << a;
}
diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp
index c22f200..9d4d4b0 100644
--- a/src/declarative/util/qdeclarativeview.cpp
+++ b/src/declarative/util/qdeclarativeview.cpp
@@ -77,7 +77,7 @@ extern Q_GUI_EXPORT bool qt_applefontsmoothing_enabled;
class QDeclarativeScene : public QGraphicsScene
{
public:
- QDeclarativeScene();
+ QDeclarativeScene(QObject *parent = 0);
protected:
virtual void keyPressEvent(QKeyEvent *);
@@ -88,7 +88,7 @@ protected:
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
};
-QDeclarativeScene::QDeclarativeScene()
+QDeclarativeScene::QDeclarativeScene(QObject *parent) : QGraphicsScene(parent)
{
}
@@ -132,7 +132,8 @@ class QDeclarativeViewPrivate : public QGraphicsViewPrivate, public QDeclarative
Q_DECLARE_PUBLIC(QDeclarativeView)
public:
QDeclarativeViewPrivate()
- : root(0), declarativeItemRoot(0), graphicsWidgetRoot(0), component(0), resizeMode(QDeclarativeView::SizeViewToRootObject), initialSize(0,0) {}
+ : root(0), declarativeItemRoot(0), graphicsWidgetRoot(0), component(0),
+ resizeMode(QDeclarativeView::SizeViewToRootObject), initialSize(0,0) {}
~QDeclarativeViewPrivate() { delete root; delete engine; }
void execute();
void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
@@ -155,8 +156,6 @@ public:
QElapsedTimer frameTimer;
void init();
-
- QDeclarativeScene scene;
};
void QDeclarativeViewPrivate::execute()
@@ -234,6 +233,9 @@ void QDeclarativeViewPrivate::itemGeometryChanged(QDeclarativeItem *resizeItem,
you can connect to the statusChanged() signal and monitor for QDeclarativeView::Error.
The errors are available via QDeclarativeView::errors().
+ If you're using your own QGraphicsScene-based scene with QDeclarativeView, remember to
+ enable scene's sticky focus mode and to set itemIndexMethod to QGraphicsScene::NoIndex.
+
\sa {Integrating QML with existing Qt UI code}, {Using QML in C++ Applications}
*/
@@ -277,7 +279,7 @@ void QDeclarativeViewPrivate::init()
{
Q_Q(QDeclarativeView);
engine = new QDeclarativeEngine();
- q->setScene(&scene);
+ q->setScene(new QDeclarativeScene(q));
q->setOptimizationFlags(QGraphicsView::DontSavePainterState);
q->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
@@ -286,11 +288,11 @@ void QDeclarativeViewPrivate::init()
// These seem to give the best performance
q->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
- scene.setItemIndexMethod(QGraphicsScene::NoIndex);
+ q->scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
q->viewport()->setFocusPolicy(Qt::NoFocus);
q->setFocusPolicy(Qt::StrongFocus);
- scene.setStickyFocus(true); //### needed for correct focus handling
+ q->scene()->setStickyFocus(true); //### needed for correct focus handling
}
/*!
@@ -557,14 +559,14 @@ void QDeclarativeView::continueExecute()
void QDeclarativeView::setRootObject(QObject *obj)
{
Q_D(QDeclarativeView);
- if (d->root == obj)
+ if (d->root == obj || !scene())
return;
if (QDeclarativeItem *declarativeItem = qobject_cast<QDeclarativeItem *>(obj)) {
- d->scene.addItem(declarativeItem);
+ scene()->addItem(declarativeItem);
d->root = declarativeItem;
d->declarativeItemRoot = declarativeItem;
} else if (QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(obj)) {
- d->scene.addItem(graphicsObject);
+ scene()->addItem(graphicsObject);
d->root = graphicsObject;
if (graphicsObject->isWidget()) {
d->graphicsWidgetRoot = static_cast<QGraphicsWidget*>(graphicsObject);
diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp
index e97cd67..9e616de 100644
--- a/src/declarative/util/qdeclarativexmllistmodel.cpp
+++ b/src/declarative/util/qdeclarativexmllistmodel.cpp
@@ -382,7 +382,7 @@ void QDeclarativeXmlQuery::doSubQueryJob()
for (int i = 0; i < queries.size(); ++i) {
QList<QVariant> resultList;
if (!queries[i].isEmpty()) {
- subquery.setQuery(m_prefix + QLatin1String("(let $v := ") + queries[i] + QLatin1String(" return if ($v) then ") + queries[i] + QLatin1String(" else \"\")"));
+ subquery.setQuery(m_prefix + QLatin1String("(let $v := string(") + queries[i] + QLatin1String(") return if ($v) then ") + queries[i] + QLatin1String(" else \"\")"));
if (subquery.isValid()) {
QXmlResultItems resultItems;
subquery.evaluateTo(&resultItems);