diff options
author | Matthew Vogt <matthew.vogt@nokia.com> | 2012-03-12 08:18:01 +1000 |
---|---|---|
committer | Matthew Vogt <matthew.vogt@nokia.com> | 2012-03-12 08:35:40 +1000 |
commit | 1f52c5430144eb7ba6baa7e3954675ca0707b947 (patch) | |
tree | 22106095d5cc61c7b5625c8ff2639e1530d2c3b0 /src | |
parent | 616bbd1988f3b92f7d980b6c9a1278f11b712573 (diff) | |
parent | ed74ec4c40f1476c545bcaacb12fe3a607172035 (diff) |
Merge branch 'master' of git://gitorious.org/qt/qtdeclarative into api_changes
Change-Id: I578b1e2f1bb374da6194e6ba04a0fd459b2632fe
Diffstat (limited to 'src')
32 files changed, 558 insertions, 2246 deletions
diff --git a/src/qml/debugger/debugger.pri b/src/qml/debugger/debugger.pri index f85663c01f..f5abd2c196 100644 --- a/src/qml/debugger/debugger.pri +++ b/src/qml/debugger/debugger.pri @@ -1,8 +1,6 @@ SOURCES += \ $$PWD/qpacketprotocol.cpp \ $$PWD/qqmldebugservice.cpp \ - $$PWD/qqmldebugclient.cpp \ - $$PWD/qqmlenginedebug.cpp \ $$PWD/qqmlprofilerservice.cpp \ $$PWD/qqmldebugserver.cpp \ $$PWD/qqmlinspectorservice.cpp \ @@ -15,8 +13,6 @@ HEADERS += \ $$PWD/qpacketprotocol_p.h \ $$PWD/qqmldebugservice_p.h \ $$PWD/qqmldebugservice_p_p.h \ - $$PWD/qqmldebugclient_p.h \ - $$PWD/qqmlenginedebug_p.h \ $$PWD/qqmlprofilerservice_p.h \ $$PWD/qqmldebugserver_p.h \ $$PWD/qqmldebugserverconnection_p.h \ diff --git a/src/qml/debugger/qqmldebugclient.cpp b/src/qml/debugger/qqmldebugclient.cpp deleted file mode 100644 index fcb0861c21..0000000000 --- a/src/qml/debugger/qqmldebugclient.cpp +++ /dev/null @@ -1,421 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qqmldebugclient_p.h" - -#include "qpacketprotocol_p.h" - -#include <QtCore/qdebug.h> -#include <QtCore/qstringlist.h> -#include <QtNetwork/qnetworkproxy.h> - -#include <private/qobject_p.h> - -QT_BEGIN_NAMESPACE - -const int protocolVersion = 1; -const QString serverId = QLatin1String("QDeclarativeDebugServer"); -const QString clientId = QLatin1String("QDeclarativeDebugClient"); - -class QQmlDebugClientPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QQmlDebugClient) -public: - QQmlDebugClientPrivate(); - - QString name; - QQmlDebugConnection *connection; -}; - -class QQmlDebugConnectionPrivate : public QObject -{ - Q_OBJECT -public: - QQmlDebugConnectionPrivate(QQmlDebugConnection *c); - QQmlDebugConnection *q; - QPacketProtocol *protocol; - QIODevice *device; - - bool gotHello; - QHash <QString, float> serverPlugins; - QHash<QString, QQmlDebugClient *> plugins; - - void advertisePlugins(); - void connectDeviceSignals(); - -public Q_SLOTS: - void connected(); - void readyRead(); - void deviceAboutToClose(); -}; - -QQmlDebugConnectionPrivate::QQmlDebugConnectionPrivate(QQmlDebugConnection *c) - : QObject(c), q(c), protocol(0), device(0), gotHello(false) -{ - protocol = new QPacketProtocol(q, this); - QObject::connect(c, SIGNAL(connected()), this, SLOT(connected())); - QObject::connect(protocol, SIGNAL(readyRead()), this, SLOT(readyRead())); -} - -void QQmlDebugConnectionPrivate::advertisePlugins() -{ - if (!q->isConnected()) - return; - - QPacket pack; - pack << serverId << 1 << plugins.keys(); - protocol->send(pack); - q->flush(); -} - -void QQmlDebugConnectionPrivate::connected() -{ - QPacket pack; - pack << serverId << 0 << protocolVersion << plugins.keys(); - protocol->send(pack); - q->flush(); -} - -void QQmlDebugConnectionPrivate::readyRead() -{ - if (!gotHello) { - QPacket pack = protocol->read(); - QString name; - - pack >> name; - - bool validHello = false; - if (name == clientId) { - int op = -1; - pack >> op; - if (op == 0) { - int version = -1; - pack >> version; - if (version == protocolVersion) { - QStringList pluginNames; - QList<float> pluginVersions; - pack >> pluginNames; - if (!pack.isEmpty()) - pack >> pluginVersions; - - const int pluginNamesSize = pluginNames.size(); - const int pluginVersionsSize = pluginVersions.size(); - for (int i = 0; i < pluginNamesSize; ++i) { - float pluginVersion = 1.0; - if (i < pluginVersionsSize) - pluginVersion = pluginVersions.at(i); - serverPlugins.insert(pluginNames.at(i), pluginVersion); - } - - validHello = true; - } - } - } - - if (!validHello) { - qWarning("QQmlDebugConnection: Invalid hello message"); - QObject::disconnect(protocol, SIGNAL(readyRead()), this, SLOT(readyRead())); - return; - } - gotHello = true; - - QHash<QString, QQmlDebugClient *>::Iterator iter = plugins.begin(); - for (; iter != plugins.end(); ++iter) { - QQmlDebugClient::State newState = QQmlDebugClient::Unavailable; - if (serverPlugins.contains(iter.key())) - newState = QQmlDebugClient::Enabled; - iter.value()->stateChanged(newState); - } - } - - while (protocol->packetsAvailable()) { - QPacket pack = protocol->read(); - QString name; - pack >> name; - - if (name == clientId) { - int op = -1; - pack >> op; - - if (op == 1) { - // Service Discovery - QHash<QString, float> oldServerPlugins = serverPlugins; - serverPlugins.clear(); - - QStringList pluginNames; - QList<float> pluginVersions; - pack >> pluginNames; - if (!pack.isEmpty()) - pack >> pluginVersions; - - const int pluginNamesSize = pluginNames.size(); - const int pluginVersionsSize = pluginVersions.size(); - for (int i = 0; i < pluginNamesSize; ++i) { - float pluginVersion = 1.0; - if (i < pluginVersionsSize) - pluginVersion = pluginVersions.at(i); - serverPlugins.insert(pluginNames.at(i), pluginVersion); - } - - QHash<QString, QQmlDebugClient *>::Iterator iter = plugins.begin(); - for (; iter != plugins.end(); ++iter) { - const QString pluginName = iter.key(); - QQmlDebugClient::State newSate = QQmlDebugClient::Unavailable; - if (serverPlugins.contains(pluginName)) - newSate = QQmlDebugClient::Enabled; - - if (oldServerPlugins.contains(pluginName) - != serverPlugins.contains(pluginName)) { - iter.value()->stateChanged(newSate); - } - } - } else { - qWarning() << "QQmlDebugConnection: Unknown control message id" << op; - } - } else { - QByteArray message; - pack >> message; - - QHash<QString, QQmlDebugClient *>::Iterator iter = - plugins.find(name); - if (iter == plugins.end()) { - qWarning() << "QQmlDebugConnection: Message received for missing plugin" << name; - } else { - (*iter)->messageReceived(message); - } - } - } -} - -void QQmlDebugConnectionPrivate::deviceAboutToClose() -{ - // This is nasty syntax but we want to emit our own aboutToClose signal (by calling QIODevice::close()) - // without calling the underlying device close fn as that would cause an infinite loop - q->QIODevice::close(); -} - -QQmlDebugConnection::QQmlDebugConnection(QObject *parent) - : QIODevice(parent), d(new QQmlDebugConnectionPrivate(this)) -{ -} - -QQmlDebugConnection::~QQmlDebugConnection() -{ - QHash<QString, QQmlDebugClient*>::iterator iter = d->plugins.begin(); - for (; iter != d->plugins.end(); ++iter) { - iter.value()->d_func()->connection = 0; - iter.value()->stateChanged(QQmlDebugClient::NotConnected); - } -} - -bool QQmlDebugConnection::isConnected() const -{ - return state() == QAbstractSocket::ConnectedState; -} - -qint64 QQmlDebugConnection::readData(char *data, qint64 maxSize) -{ - return d->device->read(data, maxSize); -} - -qint64 QQmlDebugConnection::writeData(const char *data, qint64 maxSize) -{ - return d->device->write(data, maxSize); -} - -qint64 QQmlDebugConnection::bytesAvailable() const -{ - return d->device->bytesAvailable(); -} - -bool QQmlDebugConnection::isSequential() const -{ - return true; -} - -void QQmlDebugConnection::close() -{ - if (isOpen()) { - QIODevice::close(); - d->device->close(); - emit stateChanged(QAbstractSocket::UnconnectedState); - - QHash<QString, QQmlDebugClient*>::iterator iter = d->plugins.begin(); - for (; iter != d->plugins.end(); ++iter) { - iter.value()->stateChanged(QQmlDebugClient::NotConnected); - } - } -} - -bool QQmlDebugConnection::waitForConnected(int msecs) -{ - QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device); - if (socket) - return socket->waitForConnected(msecs); - return false; -} - -QAbstractSocket::SocketState QQmlDebugConnection::state() const -{ - QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device); - if (socket) - return socket->state(); - - return QAbstractSocket::UnconnectedState; -} - -void QQmlDebugConnection::flush() -{ - QAbstractSocket *socket = qobject_cast<QAbstractSocket*>(d->device); - if (socket) { - socket->flush(); - return; - } -} - -void QQmlDebugConnection::connectToHost(const QString &hostName, quint16 port) -{ - QTcpSocket *socket = new QTcpSocket(d); - socket->setProxy(QNetworkProxy::NoProxy); - d->device = socket; - d->connectDeviceSignals(); - d->gotHello = false; - connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SIGNAL(stateChanged(QAbstractSocket::SocketState))); - connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(error(QAbstractSocket::SocketError))); - connect(socket, SIGNAL(connected()), this, SIGNAL(connected())); - socket->connectToHost(hostName, port); - QIODevice::open(ReadWrite | Unbuffered); -} - -void QQmlDebugConnectionPrivate::connectDeviceSignals() -{ - connect(device, SIGNAL(bytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64))); - connect(device, SIGNAL(readyRead()), q, SIGNAL(readyRead())); - connect(device, SIGNAL(aboutToClose()), this, SLOT(deviceAboutToClose())); -} - -// - -QQmlDebugClientPrivate::QQmlDebugClientPrivate() - : connection(0) -{ -} - -QQmlDebugClient::QQmlDebugClient(const QString &name, - QQmlDebugConnection *parent) - : QObject(*(new QQmlDebugClientPrivate), parent) -{ - Q_D(QQmlDebugClient); - d->name = name; - d->connection = parent; - - if (!d->connection) - return; - - if (d->connection->d->plugins.contains(name)) { - qWarning() << "QQmlDebugClient: Conflicting plugin name" << name; - d->connection = 0; - } else { - d->connection->d->plugins.insert(name, this); - d->connection->d->advertisePlugins(); - } -} - -QQmlDebugClient::~QQmlDebugClient() -{ - Q_D(QQmlDebugClient); - if (d->connection && d->connection->d) { - d->connection->d->plugins.remove(d->name); - d->connection->d->advertisePlugins(); - } -} - -QString QQmlDebugClient::name() const -{ - Q_D(const QQmlDebugClient); - return d->name; -} - -float QQmlDebugClient::serviceVersion() const -{ - Q_D(const QQmlDebugClient); - if (d->connection->d->serverPlugins.contains(d->name)) - return d->connection->d->serverPlugins.value(d->name); - return -1; -} - -QQmlDebugClient::State QQmlDebugClient::state() const -{ - Q_D(const QQmlDebugClient); - if (!d->connection - || !d->connection->isConnected() - || !d->connection->d->gotHello) - return NotConnected; - - if (d->connection->d->serverPlugins.contains(d->name)) - return Enabled; - - return Unavailable; -} - -void QQmlDebugClient::sendMessage(const QByteArray &message) -{ - Q_D(QQmlDebugClient); - if (state() != Enabled) - return; - - QPacket pack; - pack << d->name << message; - d->connection->d->protocol->send(pack); - d->connection->flush(); -} - -void QQmlDebugClient::stateChanged(State) -{ -} - -void QQmlDebugClient::messageReceived(const QByteArray &) -{ -} - -QT_END_NAMESPACE - -#include <qqmldebugclient.moc> diff --git a/src/qml/debugger/qqmldebugclient_p.h b/src/qml/debugger/qqmldebugclient_p.h deleted file mode 100644 index 064e15cf49..0000000000 --- a/src/qml/debugger/qqmldebugclient_p.h +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQMLDEBUGCLIENT_H -#define QQMLDEBUGCLIENT_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 <QtNetwork/qtcpsocket.h> - -#include <private/qtqmlglobal_p.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - - -class QQmlDebugConnectionPrivate; -class Q_QML_PRIVATE_EXPORT QQmlDebugConnection : public QIODevice -{ - Q_OBJECT - Q_DISABLE_COPY(QQmlDebugConnection) -public: - QQmlDebugConnection(QObject * = 0); - ~QQmlDebugConnection(); - - void connectToHost(const QString &hostName, quint16 port); - - qint64 bytesAvailable() const; - bool isConnected() const; - QAbstractSocket::SocketState state() const; - void flush(); - bool isSequential() const; - void close(); - bool waitForConnected(int msecs = 30000); - -signals: - void connected(); - void stateChanged(QAbstractSocket::SocketState socketState); - void error(QAbstractSocket::SocketError socketError); - -protected: - qint64 readData(char *data, qint64 maxSize); - qint64 writeData(const char *data, qint64 maxSize); - -private: - QQmlDebugConnectionPrivate *d; - friend class QQmlDebugClient; - friend class QQmlDebugClientPrivate; -}; - -class QQmlDebugClientPrivate; -class Q_QML_PRIVATE_EXPORT QQmlDebugClient : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QQmlDebugClient) - Q_DISABLE_COPY(QQmlDebugClient) - -public: - enum State { NotConnected, Unavailable, Enabled }; - - QQmlDebugClient(const QString &, QQmlDebugConnection *parent); - ~QQmlDebugClient(); - - QString name() const; - float serviceVersion() const; - State state() const; - - virtual void sendMessage(const QByteArray &); - -protected: - virtual void stateChanged(State); - virtual void messageReceived(const QByteArray &); - -private: - friend class QQmlDebugConnection; - friend class QQmlDebugConnectionPrivate; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QQMLDEBUGCLIENT_H diff --git a/src/qml/debugger/qqmlenginedebug.cpp b/src/qml/debugger/qqmlenginedebug.cpp deleted file mode 100644 index 65af181f1b..0000000000 --- a/src/qml/debugger/qqmlenginedebug.cpp +++ /dev/null @@ -1,1072 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qqmlenginedebug_p.h" - -#include "qqmldebugclient_p.h" - -#include "qqmlenginedebugservice_p.h" - -#include <private/qobject_p.h> - -QT_BEGIN_NAMESPACE - -class QQmlEngineDebugClient : public QQmlDebugClient -{ -public: - QQmlEngineDebugClient(QQmlDebugConnection *client, QQmlEngineDebugPrivate *p); - -protected: - virtual void stateChanged(State state); - virtual void messageReceived(const QByteArray &); - -private: - QQmlEngineDebugPrivate *priv; - friend class QQmlEngineDebugPrivate; -}; - -class QQmlEngineDebugPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QQmlEngineDebug) -public: - QQmlEngineDebugPrivate(QQmlDebugConnection *); - ~QQmlEngineDebugPrivate(); - - void stateChanged(QQmlEngineDebug::State status); - void message(const QByteArray &); - - QQmlEngineDebugClient *client; - int nextId; - int getId(); - - void decode(QDataStream &, QQmlDebugContextReference &); - void decode(QDataStream &, QQmlDebugObjectReference &, bool simple); - - static void remove(QQmlEngineDebug *, QQmlDebugEnginesQuery *); - static void remove(QQmlEngineDebug *, QQmlDebugRootContextQuery *); - static void remove(QQmlEngineDebug *, QQmlDebugObjectQuery *); - static void remove(QQmlEngineDebug *, QQmlDebugExpressionQuery *); - static void remove(QQmlEngineDebug *, QQmlDebugWatch *); - - QHash<int, QQmlDebugEnginesQuery *> enginesQuery; - QHash<int, QQmlDebugRootContextQuery *> rootContextQuery; - QHash<int, QQmlDebugObjectQuery *> objectQuery; - QHash<int, QQmlDebugExpressionQuery *> expressionQuery; - - QHash<int, QQmlDebugWatch *> watched; -}; - -QQmlEngineDebugClient::QQmlEngineDebugClient(QQmlDebugConnection *client, - QQmlEngineDebugPrivate *p) - : QQmlDebugClient(QLatin1String("QDeclarativeEngine"), client), priv(p) -{ -} - -void QQmlEngineDebugClient::stateChanged(State status) -{ - if (priv) - priv->stateChanged(static_cast<QQmlEngineDebug::State>(status)); -} - -void QQmlEngineDebugClient::messageReceived(const QByteArray &data) -{ - if (priv) - priv->message(data); -} - -QQmlEngineDebugPrivate::QQmlEngineDebugPrivate(QQmlDebugConnection *c) - : client(new QQmlEngineDebugClient(c, this)), nextId(0) -{ -} - -QQmlEngineDebugPrivate::~QQmlEngineDebugPrivate() -{ - if (client) - client->priv = 0; - delete client; - - QHash<int, QQmlDebugEnginesQuery*>::iterator enginesIter = enginesQuery.begin(); - for (; enginesIter != enginesQuery.end(); ++enginesIter) { - enginesIter.value()->m_client = 0; - if (enginesIter.value()->state() == QQmlDebugQuery::Waiting) - enginesIter.value()->setState(QQmlDebugQuery::Error); - } - - QHash<int, QQmlDebugRootContextQuery*>::iterator rootContextIter = rootContextQuery.begin(); - for (; rootContextIter != rootContextQuery.end(); ++rootContextIter) { - rootContextIter.value()->m_client = 0; - if (rootContextIter.value()->state() == QQmlDebugQuery::Waiting) - rootContextIter.value()->setState(QQmlDebugQuery::Error); - } - - QHash<int, QQmlDebugObjectQuery*>::iterator objectIter = objectQuery.begin(); - for (; objectIter != objectQuery.end(); ++objectIter) { - objectIter.value()->m_client = 0; - if (objectIter.value()->state() == QQmlDebugQuery::Waiting) - objectIter.value()->setState(QQmlDebugQuery::Error); - } - - QHash<int, QQmlDebugExpressionQuery*>::iterator exprIter = expressionQuery.begin(); - for (; exprIter != expressionQuery.end(); ++exprIter) { - exprIter.value()->m_client = 0; - if (exprIter.value()->state() == QQmlDebugQuery::Waiting) - exprIter.value()->setState(QQmlDebugQuery::Error); - } - - QHash<int, QQmlDebugWatch*>::iterator watchIter = watched.begin(); - for (; watchIter != watched.end(); ++watchIter) { - watchIter.value()->m_client = 0; - watchIter.value()->setState(QQmlDebugWatch::Dead); - } -} - -int QQmlEngineDebugPrivate::getId() -{ - return nextId++; -} - -void QQmlEngineDebugPrivate::remove(QQmlEngineDebug *c, QQmlDebugEnginesQuery *q) -{ - if (c && q) { - QQmlEngineDebugPrivate *p = (QQmlEngineDebugPrivate *)QObjectPrivate::get(c); - p->enginesQuery.remove(q->m_queryId); - } -} - -void QQmlEngineDebugPrivate::remove(QQmlEngineDebug *c, - QQmlDebugRootContextQuery *q) -{ - if (c && q) { - QQmlEngineDebugPrivate *p = (QQmlEngineDebugPrivate *)QObjectPrivate::get(c); - p->rootContextQuery.remove(q->m_queryId); - } -} - -void QQmlEngineDebugPrivate::remove(QQmlEngineDebug *c, QQmlDebugObjectQuery *q) -{ - if (c && q) { - QQmlEngineDebugPrivate *p = (QQmlEngineDebugPrivate *)QObjectPrivate::get(c); - p->objectQuery.remove(q->m_queryId); - } -} - -void QQmlEngineDebugPrivate::remove(QQmlEngineDebug *c, QQmlDebugExpressionQuery *q) -{ - if (c && q) { - QQmlEngineDebugPrivate *p = (QQmlEngineDebugPrivate *)QObjectPrivate::get(c); - p->expressionQuery.remove(q->m_queryId); - } -} - -void QQmlEngineDebugPrivate::remove(QQmlEngineDebug *c, QQmlDebugWatch *w) -{ - if (c && w) { - QQmlEngineDebugPrivate *p = (QQmlEngineDebugPrivate *)QObjectPrivate::get(c); - p->watched.remove(w->m_queryId); - } -} - -void QQmlEngineDebugPrivate::decode(QDataStream &ds, QQmlDebugObjectReference &o, - bool simple) -{ - QQmlEngineDebugService::QQmlObjectData data; - ds >> data; - o.m_debugId = data.objectId; - o.m_class = data.objectType; - o.m_idString = data.idString; - o.m_name = data.objectName; - o.m_source.m_url = data.url; - o.m_source.m_lineNumber = data.lineNumber; - o.m_source.m_columnNumber = data.columnNumber; - o.m_contextDebugId = data.contextId; - - if (simple) - return; - - int childCount; - bool recur; - ds >> childCount >> recur; - - for (int ii = 0; ii < childCount; ++ii) { - o.m_children.append(QQmlDebugObjectReference()); - decode(ds, o.m_children.last(), !recur); - } - - int propCount; - ds >> propCount; - - for (int ii = 0; ii < propCount; ++ii) { - QQmlEngineDebugService::QQmlObjectProperty data; - ds >> data; - QQmlDebugPropertyReference prop; - prop.m_objectDebugId = o.m_debugId; - prop.m_name = data.name; - prop.m_binding = data.binding; - prop.m_hasNotifySignal = data.hasNotifySignal; - prop.m_valueTypeName = data.valueTypeName; - switch (data.type) { - case QQmlEngineDebugService::QQmlObjectProperty::Basic: - case QQmlEngineDebugService::QQmlObjectProperty::List: - case QQmlEngineDebugService::QQmlObjectProperty::SignalProperty: - { - prop.m_value = data.value; - break; - } - case QQmlEngineDebugService::QQmlObjectProperty::Object: - { - QQmlDebugObjectReference obj; - obj.m_debugId = prop.m_value.toInt(); - prop.m_value = QVariant::fromValue(obj); - break; - } - case QQmlEngineDebugService::QQmlObjectProperty::Unknown: - break; - } - o.m_properties << prop; - } -} - -void QQmlEngineDebugPrivate::decode(QDataStream &ds, QQmlDebugContextReference &c) -{ - ds >> c.m_name >> c.m_debugId; - - int contextCount; - ds >> contextCount; - - for (int ii = 0; ii < contextCount; ++ii) { - c.m_contexts.append(QQmlDebugContextReference()); - decode(ds, c.m_contexts.last()); - } - - int objectCount; - ds >> objectCount; - - for (int ii = 0; ii < objectCount; ++ii) { - QQmlDebugObjectReference obj; - decode(ds, obj, true); - - obj.m_contextDebugId = c.m_debugId; - c.m_objects << obj; - } -} - -void QQmlEngineDebugPrivate::stateChanged(QQmlEngineDebug::State status) -{ - emit q_func()->stateChanged(status); -} - -void QQmlEngineDebugPrivate::message(const QByteArray &data) -{ - QDataStream ds(data); - - QByteArray type; - ds >> type; - - //qDebug() << "QQmlEngineDebugPrivate::message()" << type; - - if (type == "LIST_ENGINES_R") { - int queryId; - ds >> queryId; - - QQmlDebugEnginesQuery *query = enginesQuery.value(queryId); - if (!query) - return; - enginesQuery.remove(queryId); - - int count; - ds >> count; - - for (int ii = 0; ii < count; ++ii) { - QQmlDebugEngineReference ref; - ds >> ref.m_name; - ds >> ref.m_debugId; - query->m_engines << ref; - } - - query->m_client = 0; - query->setState(QQmlDebugQuery::Completed); - } else if (type == "LIST_OBJECTS_R") { - int queryId; - ds >> queryId; - - QQmlDebugRootContextQuery *query = rootContextQuery.value(queryId); - if (!query) - return; - rootContextQuery.remove(queryId); - - if (!ds.atEnd()) - decode(ds, query->m_context); - - query->m_client = 0; - query->setState(QQmlDebugQuery::Completed); - } else if (type == "FETCH_OBJECT_R") { - int queryId; - ds >> queryId; - - QQmlDebugObjectQuery *query = objectQuery.value(queryId); - if (!query) - return; - objectQuery.remove(queryId); - - if (!ds.atEnd()) - decode(ds, query->m_object, false); - - query->m_client = 0; - query->setState(QQmlDebugQuery::Completed); - } else if (type == "EVAL_EXPRESSION_R") { - int queryId; - QVariant result; - ds >> queryId >> result; - - QQmlDebugExpressionQuery *query = expressionQuery.value(queryId); - if (!query) - return; - expressionQuery.remove(queryId); - - query->m_result = result; - query->m_client = 0; - query->setState(QQmlDebugQuery::Completed); - } else if (type == "WATCH_PROPERTY_R") { - int queryId; - bool ok; - ds >> queryId >> ok; - - QQmlDebugWatch *watch = watched.value(queryId); - if (!watch) - return; - - watch->setState(ok ? QQmlDebugWatch::Active : QQmlDebugWatch::Inactive); - } else if (type == "WATCH_OBJECT_R") { - int queryId; - bool ok; - ds >> queryId >> ok; - - QQmlDebugWatch *watch = watched.value(queryId); - if (!watch) - return; - - watch->setState(ok ? QQmlDebugWatch::Active : QQmlDebugWatch::Inactive); - } else if (type == "WATCH_EXPR_OBJECT_R") { - int queryId; - bool ok; - ds >> queryId >> ok; - - QQmlDebugWatch *watch = watched.value(queryId); - if (!watch) - return; - - watch->setState(ok ? QQmlDebugWatch::Active : QQmlDebugWatch::Inactive); - } else if (type == "UPDATE_WATCH") { - int queryId; - int debugId; - QByteArray name; - QVariant value; - ds >> queryId >> debugId >> name >> value; - - QQmlDebugWatch *watch = watched.value(queryId, 0); - if (!watch) - return; - emit watch->valueChanged(name, value); - } else if (type == "OBJECT_CREATED") { - emit q_func()->newObjects(); - } -} - -QQmlEngineDebug::QQmlEngineDebug(QQmlDebugConnection *client, QObject *parent) - : QObject(*(new QQmlEngineDebugPrivate(client)), parent) -{ -} - -QQmlEngineDebug::~QQmlEngineDebug() -{ -} - -QQmlEngineDebug::State QQmlEngineDebug::state() const -{ - Q_D(const QQmlEngineDebug); - - return static_cast<QQmlEngineDebug::State>(d->client->state()); -} - -QQmlDebugPropertyWatch *QQmlEngineDebug::addWatch(const QQmlDebugPropertyReference &property, QObject *parent) -{ - Q_D(QQmlEngineDebug); - - QQmlDebugPropertyWatch *watch = new QQmlDebugPropertyWatch(parent); - if (d->client->state() == QQmlDebugClient::Enabled) { - int queryId = d->getId(); - watch->m_queryId = queryId; - watch->m_client = this; - watch->m_objectDebugId = property.objectDebugId(); - watch->m_name = property.name(); - d->watched.insert(queryId, watch); - - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); - ds << QByteArray("WATCH_PROPERTY") << queryId << property.objectDebugId() << property.name().toUtf8(); - d->client->sendMessage(message); - } else { - watch->m_state = QQmlDebugWatch::Dead; - } - - return watch; -} - -QQmlDebugWatch *QQmlEngineDebug::addWatch(const QQmlDebugContextReference &, const QString &, QObject *) -{ - qWarning("QQmlEngineDebug::addWatch(): Not implemented"); - return 0; -} - -QQmlDebugObjectExpressionWatch *QQmlEngineDebug::addWatch(const QQmlDebugObjectReference &object, const QString &expr, QObject *parent) -{ - Q_D(QQmlEngineDebug); - QQmlDebugObjectExpressionWatch *watch = new QQmlDebugObjectExpressionWatch(parent); - if (d->client->state() == QQmlDebugClient::Enabled) { - int queryId = d->getId(); - watch->m_queryId = queryId; - watch->m_client = this; - watch->m_objectDebugId = object.debugId(); - watch->m_expr = expr; - d->watched.insert(queryId, watch); - - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); - ds << QByteArray("WATCH_EXPR_OBJECT") << queryId << object.debugId() << expr; - d->client->sendMessage(message); - } else { - watch->m_state = QQmlDebugWatch::Dead; - } - return watch; -} - -QQmlDebugWatch *QQmlEngineDebug::addWatch(const QQmlDebugObjectReference &object, QObject *parent) -{ - Q_D(QQmlEngineDebug); - - QQmlDebugWatch *watch = new QQmlDebugWatch(parent); - if (d->client->state() == QQmlDebugClient::Enabled) { - int queryId = d->getId(); - watch->m_queryId = queryId; - watch->m_client = this; - watch->m_objectDebugId = object.debugId(); - d->watched.insert(queryId, watch); - - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); - ds << QByteArray("WATCH_OBJECT") << queryId << object.debugId(); - d->client->sendMessage(message); - } else { - watch->m_state = QQmlDebugWatch::Dead; - } - - return watch; -} - -QQmlDebugWatch *QQmlEngineDebug::addWatch(const QQmlDebugFileReference &, QObject *) -{ - qWarning("QQmlEngineDebug::addWatch(): Not implemented"); - return 0; -} - -void QQmlEngineDebug::removeWatch(QQmlDebugWatch *watch) -{ - Q_D(QQmlEngineDebug); - - if (!watch || !watch->m_client) - return; - - watch->m_client = 0; - watch->setState(QQmlDebugWatch::Inactive); - - d->watched.remove(watch->queryId()); - - if (d->client && d->client->state() == QQmlDebugClient::Enabled) { - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); - ds << QByteArray("NO_WATCH") << watch->queryId(); - d->client->sendMessage(message); - } -} - -QQmlDebugEnginesQuery *QQmlEngineDebug::queryAvailableEngines(QObject *parent) -{ - Q_D(QQmlEngineDebug); - - QQmlDebugEnginesQuery *query = new QQmlDebugEnginesQuery(parent); - if (d->client->state() == QQmlDebugClient::Enabled) { - query->m_client = this; - int queryId = d->getId(); - query->m_queryId = queryId; - d->enginesQuery.insert(queryId, query); - - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); - ds << QByteArray("LIST_ENGINES") << queryId; - d->client->sendMessage(message); - } else { - query->m_state = QQmlDebugQuery::Error; - } - - return query; -} - -QQmlDebugRootContextQuery *QQmlEngineDebug::queryRootContexts(const QQmlDebugEngineReference &engine, QObject *parent) -{ - Q_D(QQmlEngineDebug); - - QQmlDebugRootContextQuery *query = new QQmlDebugRootContextQuery(parent); - if (d->client->state() == QQmlDebugClient::Enabled && engine.debugId() != -1) { - query->m_client = this; - int queryId = d->getId(); - query->m_queryId = queryId; - d->rootContextQuery.insert(queryId, query); - - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); - ds << QByteArray("LIST_OBJECTS") << queryId << engine.debugId(); - d->client->sendMessage(message); - } else { - query->m_state = QQmlDebugQuery::Error; - } - - return query; -} - -QQmlDebugObjectQuery *QQmlEngineDebug::queryObject(const QQmlDebugObjectReference &object, QObject *parent) -{ - Q_D(QQmlEngineDebug); - - QQmlDebugObjectQuery *query = new QQmlDebugObjectQuery(parent); - if (d->client->state() == QQmlDebugClient::Enabled && object.debugId() != -1) { - query->m_client = this; - int queryId = d->getId(); - query->m_queryId = queryId; - d->objectQuery.insert(queryId, query); - - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); - ds << QByteArray("FETCH_OBJECT") << queryId << object.debugId() - << false << true; - d->client->sendMessage(message); - } else { - query->m_state = QQmlDebugQuery::Error; - } - - return query; -} - -QQmlDebugObjectQuery *QQmlEngineDebug::queryObjectRecursive(const QQmlDebugObjectReference &object, QObject *parent) -{ - Q_D(QQmlEngineDebug); - - QQmlDebugObjectQuery *query = new QQmlDebugObjectQuery(parent); - if (d->client->state() == QQmlDebugClient::Enabled && object.debugId() != -1) { - query->m_client = this; - int queryId = d->getId(); - query->m_queryId = queryId; - d->objectQuery.insert(queryId, query); - - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); - ds << QByteArray("FETCH_OBJECT") << queryId << object.debugId() - << true << true; - d->client->sendMessage(message); - } else { - query->m_state = QQmlDebugQuery::Error; - } - - return query; -} - -QQmlDebugExpressionQuery *QQmlEngineDebug::queryExpressionResult(int objectDebugId, const QString &expr, QObject *parent) -{ - Q_D(QQmlEngineDebug); - - QQmlDebugExpressionQuery *query = new QQmlDebugExpressionQuery(parent); - if (d->client->state() == QQmlDebugClient::Enabled && objectDebugId != -1) { - query->m_client = this; - query->m_expr = expr; - int queryId = d->getId(); - query->m_queryId = queryId; - d->expressionQuery.insert(queryId, query); - - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); - ds << QByteArray("EVAL_EXPRESSION") << queryId << objectDebugId << expr; - d->client->sendMessage(message); - } else { - query->m_state = QQmlDebugQuery::Error; - } - - return query; -} - -bool QQmlEngineDebug::setBindingForObject(int objectDebugId, const QString &propertyName, - const QVariant &bindingExpression, - bool isLiteralValue, - QString source, int line) -{ - Q_D(QQmlEngineDebug); - - if (d->client->state() == QQmlDebugClient::Enabled && objectDebugId != -1) { - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); - ds << QByteArray("SET_BINDING") << objectDebugId << propertyName << bindingExpression << isLiteralValue << source << line; - d->client->sendMessage(message); - return true; - } else { - return false; - } -} - -bool QQmlEngineDebug::resetBindingForObject(int objectDebugId, const QString &propertyName) -{ - Q_D(QQmlEngineDebug); - - if (d->client->state() == QQmlDebugClient::Enabled && objectDebugId != -1) { - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); - ds << QByteArray("RESET_BINDING") << objectDebugId << propertyName; - d->client->sendMessage(message); - return true; - } else { - return false; - } -} - -bool QQmlEngineDebug::setMethodBody(int objectDebugId, const QString &methodName, - const QString &methodBody) -{ - Q_D(QQmlEngineDebug); - - if (d->client->state() == QQmlDebugClient::Enabled && objectDebugId != -1) { - QByteArray message; - QDataStream ds(&message, QIODevice::WriteOnly); - ds << QByteArray("SET_METHOD_BODY") << objectDebugId << methodName << methodBody; - d->client->sendMessage(message); - return true; - } else { - return false; - } -} - -QQmlDebugWatch::QQmlDebugWatch(QObject *parent) - : QObject(parent), m_state(Waiting), m_queryId(-1), m_client(0), m_objectDebugId(-1) -{ -} - -QQmlDebugWatch::~QQmlDebugWatch() -{ - if (m_client && m_queryId != -1) - QQmlEngineDebugPrivate::remove(m_client, this); -} - -int QQmlDebugWatch::queryId() const -{ - return m_queryId; -} - -int QQmlDebugWatch::objectDebugId() const -{ - return m_objectDebugId; -} - -QQmlDebugWatch::State QQmlDebugWatch::state() const -{ - return m_state; -} - -void QQmlDebugWatch::setState(State s) -{ - if (m_state == s) - return; - m_state = s; - emit stateChanged(m_state); -} - -QQmlDebugPropertyWatch::QQmlDebugPropertyWatch(QObject *parent) - : QQmlDebugWatch(parent) -{ -} - -QString QQmlDebugPropertyWatch::name() const -{ - return m_name; -} - - -QQmlDebugObjectExpressionWatch::QQmlDebugObjectExpressionWatch(QObject *parent) - : QQmlDebugWatch(parent) -{ -} - -QString QQmlDebugObjectExpressionWatch::expression() const -{ - return m_expr; -} - - -QQmlDebugQuery::QQmlDebugQuery(QObject *parent) - : QObject(parent), m_state(Waiting) -{ -} - -QQmlDebugQuery::State QQmlDebugQuery::state() const -{ - return m_state; -} - -bool QQmlDebugQuery::isWaiting() const -{ - return m_state == Waiting; -} - -void QQmlDebugQuery::setState(State s) -{ - if (m_state == s) - return; - m_state = s; - emit stateChanged(m_state); -} - -QQmlDebugEnginesQuery::QQmlDebugEnginesQuery(QObject *parent) - : QQmlDebugQuery(parent), m_client(0), m_queryId(-1) -{ -} - -QQmlDebugEnginesQuery::~QQmlDebugEnginesQuery() -{ - if (m_client && m_queryId != -1) - QQmlEngineDebugPrivate::remove(m_client, this); -} - -QList<QQmlDebugEngineReference> QQmlDebugEnginesQuery::engines() const -{ - return m_engines; -} - -QQmlDebugRootContextQuery::QQmlDebugRootContextQuery(QObject *parent) - : QQmlDebugQuery(parent), m_client(0), m_queryId(-1) -{ -} - -QQmlDebugRootContextQuery::~QQmlDebugRootContextQuery() -{ - if (m_client && m_queryId != -1) - QQmlEngineDebugPrivate::remove(m_client, this); -} - -QQmlDebugContextReference QQmlDebugRootContextQuery::rootContext() const -{ - return m_context; -} - -QQmlDebugObjectQuery::QQmlDebugObjectQuery(QObject *parent) - : QQmlDebugQuery(parent), m_client(0), m_queryId(-1) -{ -} - -QQmlDebugObjectQuery::~QQmlDebugObjectQuery() -{ - if (m_client && m_queryId != -1) - QQmlEngineDebugPrivate::remove(m_client, this); -} - -QQmlDebugObjectReference QQmlDebugObjectQuery::object() const -{ - return m_object; -} - -QQmlDebugExpressionQuery::QQmlDebugExpressionQuery(QObject *parent) - : QQmlDebugQuery(parent), m_client(0), m_queryId(-1) -{ -} - -QQmlDebugExpressionQuery::~QQmlDebugExpressionQuery() -{ - if (m_client && m_queryId != -1) - QQmlEngineDebugPrivate::remove(m_client, this); -} - -QVariant QQmlDebugExpressionQuery::expression() const -{ - return m_expr; -} - -QVariant QQmlDebugExpressionQuery::result() const -{ - return m_result; -} - -QQmlDebugEngineReference::QQmlDebugEngineReference() - : m_debugId(-1) -{ -} - -QQmlDebugEngineReference::QQmlDebugEngineReference(int debugId) - : m_debugId(debugId) -{ -} - -QQmlDebugEngineReference::QQmlDebugEngineReference(const QQmlDebugEngineReference &o) - : m_debugId(o.m_debugId), m_name(o.m_name) -{ -} - -QQmlDebugEngineReference & -QQmlDebugEngineReference::operator=(const QQmlDebugEngineReference &o) -{ - m_debugId = o.m_debugId; m_name = o.m_name; - return *this; -} - -int QQmlDebugEngineReference::debugId() const -{ - return m_debugId; -} - -QString QQmlDebugEngineReference::name() const -{ - return m_name; -} - -QQmlDebugObjectReference::QQmlDebugObjectReference() - : m_debugId(-1), m_contextDebugId(-1) -{ -} - -QQmlDebugObjectReference::QQmlDebugObjectReference(int debugId) - : m_debugId(debugId), m_contextDebugId(-1) -{ -} - -QQmlDebugObjectReference::QQmlDebugObjectReference(const QQmlDebugObjectReference &o) - : m_debugId(o.m_debugId), m_class(o.m_class), m_idString(o.m_idString), - m_name(o.m_name), m_source(o.m_source), m_contextDebugId(o.m_contextDebugId), - m_properties(o.m_properties), m_children(o.m_children) -{ -} - -QQmlDebugObjectReference & -QQmlDebugObjectReference::operator=(const QQmlDebugObjectReference &o) -{ - m_debugId = o.m_debugId; m_class = o.m_class; m_idString = o.m_idString; - m_name = o.m_name; m_source = o.m_source; m_contextDebugId = o.m_contextDebugId; - m_properties = o.m_properties; m_children = o.m_children; - return *this; -} - -int QQmlDebugObjectReference::debugId() const -{ - return m_debugId; -} - -QString QQmlDebugObjectReference::className() const -{ - return m_class; -} - -QString QQmlDebugObjectReference::idString() const -{ - return m_idString; -} - -QString QQmlDebugObjectReference::name() const -{ - return m_name; -} - -QQmlDebugFileReference QQmlDebugObjectReference::source() const -{ - return m_source; -} - -int QQmlDebugObjectReference::contextDebugId() const -{ - return m_contextDebugId; -} - -QList<QQmlDebugPropertyReference> QQmlDebugObjectReference::properties() const -{ - return m_properties; -} - -QList<QQmlDebugObjectReference> QQmlDebugObjectReference::children() const -{ - return m_children; -} - -QQmlDebugContextReference::QQmlDebugContextReference() - : m_debugId(-1) -{ -} - -QQmlDebugContextReference::QQmlDebugContextReference(const QQmlDebugContextReference &o) - : m_debugId(o.m_debugId), m_name(o.m_name), m_objects(o.m_objects), m_contexts(o.m_contexts) -{ -} - -QQmlDebugContextReference &QQmlDebugContextReference::operator=(const QQmlDebugContextReference &o) -{ - m_debugId = o.m_debugId; m_name = o.m_name; m_objects = o.m_objects; - m_contexts = o.m_contexts; - return *this; -} - -int QQmlDebugContextReference::debugId() const -{ - return m_debugId; -} - -QString QQmlDebugContextReference::name() const -{ - return m_name; -} - -QList<QQmlDebugObjectReference> QQmlDebugContextReference::objects() const -{ - return m_objects; -} - -QList<QQmlDebugContextReference> QQmlDebugContextReference::contexts() const -{ - return m_contexts; -} - -QQmlDebugFileReference::QQmlDebugFileReference() - : m_lineNumber(-1), m_columnNumber(-1) -{ -} - -QQmlDebugFileReference::QQmlDebugFileReference(const QQmlDebugFileReference &o) - : m_url(o.m_url), m_lineNumber(o.m_lineNumber), m_columnNumber(o.m_columnNumber) -{ -} - -QQmlDebugFileReference &QQmlDebugFileReference::operator=(const QQmlDebugFileReference &o) -{ - m_url = o.m_url; m_lineNumber = o.m_lineNumber; m_columnNumber = o.m_columnNumber; - return *this; -} - -QUrl QQmlDebugFileReference::url() const -{ - return m_url; -} - -void QQmlDebugFileReference::setUrl(const QUrl &u) -{ - m_url = u; -} - -int QQmlDebugFileReference::lineNumber() const -{ - return m_lineNumber; -} - -void QQmlDebugFileReference::setLineNumber(int l) -{ - m_lineNumber = l; -} - -int QQmlDebugFileReference::columnNumber() const -{ - return m_columnNumber; -} - -void QQmlDebugFileReference::setColumnNumber(int c) -{ - m_columnNumber = c; -} - -QQmlDebugPropertyReference::QQmlDebugPropertyReference() - : m_objectDebugId(-1), m_hasNotifySignal(false) -{ -} - -QQmlDebugPropertyReference::QQmlDebugPropertyReference(const QQmlDebugPropertyReference &o) - : m_objectDebugId(o.m_objectDebugId), m_name(o.m_name), m_value(o.m_value), - m_valueTypeName(o.m_valueTypeName), m_binding(o.m_binding), - m_hasNotifySignal(o.m_hasNotifySignal) -{ -} - -QQmlDebugPropertyReference &QQmlDebugPropertyReference::operator=(const QQmlDebugPropertyReference &o) -{ - m_objectDebugId = o.m_objectDebugId; m_name = o.m_name; m_value = o.m_value; - m_valueTypeName = o.m_valueTypeName; m_binding = o.m_binding; - m_hasNotifySignal = o.m_hasNotifySignal; - return *this; -} - -int QQmlDebugPropertyReference::objectDebugId() const -{ - return m_objectDebugId; -} - -QString QQmlDebugPropertyReference::name() const -{ - return m_name; -} - -QString QQmlDebugPropertyReference::valueTypeName() const -{ - return m_valueTypeName; -} - -QVariant QQmlDebugPropertyReference::value() const -{ - return m_value; -} - -QString QQmlDebugPropertyReference::binding() const -{ - return m_binding; -} - -bool QQmlDebugPropertyReference::hasNotifySignal() const -{ - return m_hasNotifySignal; -} - -QT_END_NAMESPACE - diff --git a/src/qml/debugger/qqmlenginedebug_p.h b/src/qml/debugger/qqmlenginedebug_p.h deleted file mode 100644 index 0562d8755b..0000000000 --- a/src/qml/debugger/qqmlenginedebug_p.h +++ /dev/null @@ -1,397 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQMLENGINEDEBUG_H -#define QQMLENGINEDEBUG_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 <QtCore/qobject.h> -#include <QtCore/qurl.h> -#include <QtCore/qvariant.h> - -#include <private/qtqmlglobal_p.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - - -class QQmlDebugConnection; -class QQmlDebugWatch; -class QQmlDebugPropertyWatch; -class QQmlDebugObjectExpressionWatch; -class QQmlDebugEnginesQuery; -class QQmlDebugRootContextQuery; -class QQmlDebugObjectQuery; -class QQmlDebugExpressionQuery; -class QQmlDebugPropertyReference; -class QQmlDebugContextReference; -class QQmlDebugObjectReference; -class QQmlDebugFileReference; -class QQmlDebugEngineReference; -class QQmlEngineDebugPrivate; -class Q_QML_PRIVATE_EXPORT QQmlEngineDebug : public QObject -{ - Q_OBJECT -public: - enum State { NotConnected, Unavailable, Enabled }; - - explicit QQmlEngineDebug(QQmlDebugConnection *, QObject * = 0); - ~QQmlEngineDebug(); - - State state() const; - - QQmlDebugPropertyWatch *addWatch(const QQmlDebugPropertyReference &, - QObject *parent = 0); - QQmlDebugWatch *addWatch(const QQmlDebugContextReference &, const QString &, - QObject *parent = 0); - QQmlDebugObjectExpressionWatch *addWatch(const QQmlDebugObjectReference &, const QString &, - QObject *parent = 0); - QQmlDebugWatch *addWatch(const QQmlDebugObjectReference &, - QObject *parent = 0); - QQmlDebugWatch *addWatch(const QQmlDebugFileReference &, - QObject *parent = 0); - - void removeWatch(QQmlDebugWatch *watch); - - QQmlDebugEnginesQuery *queryAvailableEngines(QObject *parent = 0); - QQmlDebugRootContextQuery *queryRootContexts(const QQmlDebugEngineReference &, - QObject *parent = 0); - QQmlDebugObjectQuery *queryObject(const QQmlDebugObjectReference &, - QObject *parent = 0); - QQmlDebugObjectQuery *queryObjectRecursive(const QQmlDebugObjectReference &, - QObject *parent = 0); - QQmlDebugExpressionQuery *queryExpressionResult(int objectDebugId, - const QString &expr, - QObject *parent = 0); - bool setBindingForObject(int objectDebugId, const QString &propertyName, - const QVariant &bindingExpression, bool isLiteralValue, - QString source = QString(), int line = -1); - bool resetBindingForObject(int objectDebugId, const QString &propertyName); - bool setMethodBody(int objectDebugId, const QString &methodName, const QString &methodBody); - -Q_SIGNALS: - void newObjects(); - void stateChanged(State state); - -private: - Q_DECLARE_PRIVATE(QQmlEngineDebug) -}; - -class Q_QML_PRIVATE_EXPORT QQmlDebugWatch : public QObject -{ - Q_OBJECT -public: - enum State { Waiting, Active, Inactive, Dead }; - - QQmlDebugWatch(QObject *); - ~QQmlDebugWatch(); - - int queryId() const; - int objectDebugId() const; - State state() const; - -Q_SIGNALS: - void stateChanged(QQmlDebugWatch::State); - //void objectChanged(int, const QQmlDebugObjectReference &); - //void valueChanged(int, const QVariant &); - - // Server sends value as string if it is a user-type variant - void valueChanged(const QByteArray &name, const QVariant &value); - -private: - friend class QQmlEngineDebug; - friend class QQmlEngineDebugPrivate; - void setState(State); - State m_state; - int m_queryId; - QQmlEngineDebug *m_client; - int m_objectDebugId; -}; - -class Q_QML_PRIVATE_EXPORT QQmlDebugPropertyWatch : public QQmlDebugWatch -{ - Q_OBJECT -public: - QQmlDebugPropertyWatch(QObject *parent); - - QString name() const; - -private: - friend class QQmlEngineDebug; - QString m_name; -}; - -class Q_QML_PRIVATE_EXPORT QQmlDebugObjectExpressionWatch : public QQmlDebugWatch -{ - Q_OBJECT -public: - QQmlDebugObjectExpressionWatch(QObject *parent); - - QString expression() const; - -private: - friend class QQmlEngineDebug; - QString m_expr; - int m_debugId; -}; - - -class Q_QML_PRIVATE_EXPORT QQmlDebugQuery : public QObject -{ - Q_OBJECT -public: - enum State { Waiting, Error, Completed }; - - State state() const; - bool isWaiting() const; - -Q_SIGNALS: - void stateChanged(QQmlDebugQuery::State); - -protected: - QQmlDebugQuery(QObject *); - -private: - friend class QQmlEngineDebug; - friend class QQmlEngineDebugPrivate; - void setState(State); - State m_state; -}; - -class Q_QML_PRIVATE_EXPORT QQmlDebugFileReference -{ -public: - QQmlDebugFileReference(); - QQmlDebugFileReference(const QQmlDebugFileReference &); - QQmlDebugFileReference &operator=(const QQmlDebugFileReference &); - - QUrl url() const; - void setUrl(const QUrl &); - int lineNumber() const; - void setLineNumber(int); - int columnNumber() const; - void setColumnNumber(int); - -private: - friend class QQmlEngineDebugPrivate; - QUrl m_url; - int m_lineNumber; - int m_columnNumber; -}; - -class Q_QML_PRIVATE_EXPORT QQmlDebugEngineReference -{ -public: - QQmlDebugEngineReference(); - QQmlDebugEngineReference(int); - QQmlDebugEngineReference(const QQmlDebugEngineReference &); - QQmlDebugEngineReference &operator=(const QQmlDebugEngineReference &); - - int debugId() const; - QString name() const; - -private: - friend class QQmlEngineDebugPrivate; - int m_debugId; - QString m_name; -}; - -class Q_QML_PRIVATE_EXPORT QQmlDebugObjectReference -{ -public: - QQmlDebugObjectReference(); - QQmlDebugObjectReference(int); - QQmlDebugObjectReference(const QQmlDebugObjectReference &); - QQmlDebugObjectReference &operator=(const QQmlDebugObjectReference &); - - int debugId() const; - QString className() const; - QString idString() const; - QString name() const; - - QQmlDebugFileReference source() const; - int contextDebugId() const; - - QList<QQmlDebugPropertyReference> properties() const; - QList<QQmlDebugObjectReference> children() const; - -private: - friend class QQmlEngineDebugPrivate; - int m_debugId; - QString m_class; - QString m_idString; - QString m_name; - QQmlDebugFileReference m_source; - int m_contextDebugId; - QList<QQmlDebugPropertyReference> m_properties; - QList<QQmlDebugObjectReference> m_children; -}; - -class Q_QML_PRIVATE_EXPORT QQmlDebugContextReference -{ -public: - QQmlDebugContextReference(); - QQmlDebugContextReference(const QQmlDebugContextReference &); - QQmlDebugContextReference &operator=(const QQmlDebugContextReference &); - - int debugId() const; - QString name() const; - - QList<QQmlDebugObjectReference> objects() const; - QList<QQmlDebugContextReference> contexts() const; - -private: - friend class QQmlEngineDebugPrivate; - int m_debugId; - QString m_name; - QList<QQmlDebugObjectReference> m_objects; - QList<QQmlDebugContextReference> m_contexts; -}; - -class Q_QML_PRIVATE_EXPORT QQmlDebugPropertyReference -{ -public: - QQmlDebugPropertyReference(); - QQmlDebugPropertyReference(const QQmlDebugPropertyReference &); - QQmlDebugPropertyReference &operator=(const QQmlDebugPropertyReference &); - - int objectDebugId() const; - QString name() const; - QVariant value() const; - QString valueTypeName() const; - QString binding() const; - bool hasNotifySignal() const; - -private: - friend class QQmlEngineDebugPrivate; - int m_objectDebugId; - QString m_name; - QVariant m_value; - QString m_valueTypeName; - QString m_binding; - bool m_hasNotifySignal; -}; - - -class Q_QML_PRIVATE_EXPORT QQmlDebugEnginesQuery : public QQmlDebugQuery -{ - Q_OBJECT -public: - virtual ~QQmlDebugEnginesQuery(); - QList<QQmlDebugEngineReference> engines() const; -private: - friend class QQmlEngineDebug; - friend class QQmlEngineDebugPrivate; - QQmlDebugEnginesQuery(QObject *); - QQmlEngineDebug *m_client; - int m_queryId; - QList<QQmlDebugEngineReference> m_engines; -}; - -class Q_QML_PRIVATE_EXPORT QQmlDebugRootContextQuery : public QQmlDebugQuery -{ - Q_OBJECT -public: - virtual ~QQmlDebugRootContextQuery(); - QQmlDebugContextReference rootContext() const; -private: - friend class QQmlEngineDebug; - friend class QQmlEngineDebugPrivate; - QQmlDebugRootContextQuery(QObject *); - QQmlEngineDebug *m_client; - int m_queryId; - QQmlDebugContextReference m_context; -}; - -class Q_QML_PRIVATE_EXPORT QQmlDebugObjectQuery : public QQmlDebugQuery -{ - Q_OBJECT -public: - virtual ~QQmlDebugObjectQuery(); - QQmlDebugObjectReference object() const; -private: - friend class QQmlEngineDebug; - friend class QQmlEngineDebugPrivate; - QQmlDebugObjectQuery(QObject *); - QQmlEngineDebug *m_client; - int m_queryId; - QQmlDebugObjectReference m_object; - -}; - -class Q_QML_PRIVATE_EXPORT QQmlDebugExpressionQuery : public QQmlDebugQuery -{ - Q_OBJECT -public: - virtual ~QQmlDebugExpressionQuery(); - QVariant expression() const; - QVariant result() const; -private: - friend class QQmlEngineDebug; - friend class QQmlEngineDebugPrivate; - QQmlDebugExpressionQuery(QObject *); - QQmlEngineDebug *m_client; - int m_queryId; - QVariant m_expr; - QVariant m_result; -}; - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(QQmlDebugEngineReference) -Q_DECLARE_METATYPE(QQmlDebugObjectReference) -Q_DECLARE_METATYPE(QQmlDebugContextReference) -Q_DECLARE_METATYPE(QQmlDebugPropertyReference) - -QT_END_HEADER - -#endif // QQMLENGINEDEBUG_H diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index a19644fb3e..bb6eb3b723 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -339,7 +339,8 @@ void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags) if (!d->updating) { QQmlBindingProfiler prof(d->url, d->line, d->column); - prof.addDetail(expression()); + if (prof.enabled) + prof.addDetail(expression()); d->updating = true; QQmlAbstractExpression::DeleteWatcher watcher(d); diff --git a/src/qml/qml/qqmlscript.cpp b/src/qml/qml/qqmlscript.cpp index db59a7266f..8e22e488ed 100644 --- a/src/qml/qml/qqmlscript.cpp +++ b/src/qml/qml/qqmlscript.cpp @@ -50,6 +50,7 @@ #include <private/qqmlrewrite_p.h> #include <QStack> +#include <QStringList> #include <QCoreApplication> #include <QtDebug> diff --git a/src/qml/qml/qquicklistmodel.cpp b/src/qml/qml/qquicklistmodel.cpp index 30c4f5d1d1..48187ca067 100644 --- a/src/qml/qml/qquicklistmodel.cpp +++ b/src/qml/qml/qquicklistmodel.cpp @@ -1110,14 +1110,18 @@ int ListElement::setJsProperty(const ListLayout::Role &role, v8::Handle<v8::Valu } else if (d->IsNumber()) { roleIndex = setDoubleProperty(role, d->NumberValue()); } else if (d->IsArray()) { - ListModel *subModel = new ListModel(role.subLayout, 0, -1); - v8::Handle<v8::Array> subArray = v8::Handle<v8::Array>::Cast(d); - int arrayLength = subArray->Length(); - for (int j=0 ; j < arrayLength ; ++j) { - v8::Handle<v8::Object> subObject = subArray->Get(j)->ToObject(); - subModel->append(subObject, eng); + if (role.type == ListLayout::Role::List) { + ListModel *subModel = new ListModel(role.subLayout, 0, -1); + v8::Handle<v8::Array> subArray = v8::Handle<v8::Array>::Cast(d); + int arrayLength = subArray->Length(); + for (int j=0 ; j < arrayLength ; ++j) { + v8::Handle<v8::Object> subObject = subArray->Get(j)->ToObject(); + subModel->append(subObject, eng); + } + roleIndex = setListProperty(role, subModel); + } else { + qmlInfo(0) << QString::fromLatin1("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(role.name).arg(roleTypeName(role.type)).arg(roleTypeName(ListLayout::Role::List)); } - roleIndex = setListProperty(role, subModel); } else if (d->IsBoolean()) { roleIndex = setBoolProperty(role, d->BooleanValue()); } else if (d->IsObject()) { diff --git a/src/qml/qml/rewriter/textwriter.cpp b/src/qml/qml/rewriter/textwriter.cpp index f14c4af521..458fee68a1 100644 --- a/src/qml/qml/rewriter/textwriter.cpp +++ b/src/qml/qml/rewriter/textwriter.cpp @@ -46,7 +46,7 @@ QT_QML_BEGIN_NAMESPACE using namespace QQmlJS; TextWriter::TextWriter() - :string(0), cursor(0) + :string(0) { } @@ -72,8 +72,8 @@ bool TextWriter::hasOverlap(int pos, int length) if (overlaps(pos, length, cmd.pos, cmd.length)) return true; } - return false; } + return false; } bool TextWriter::hasMoveInto(int pos, int length) @@ -137,25 +137,12 @@ void TextWriter::doReplace(const Replace &replace) } } - if (string) { - string->replace(replace.pos, replace.length, replace.replacement); - } else if (cursor) { - cursor->setPosition(replace.pos); - cursor->setPosition(replace.pos + replace.length, QTextCursor::KeepAnchor); - cursor->insertText(replace.replacement); - } + string->replace(replace.pos, replace.length, replace.replacement); } void TextWriter::doMove(const Move &move) { - QString text; - if (string) { - text = string->mid(move.pos, move.length); - } else if (cursor) { - cursor->setPosition(move.pos); - cursor->setPosition(move.pos + move.length, QTextCursor::KeepAnchor); - text = cursor->selectedText(); - } + QString text(string->mid(move.pos, move.length)); Replace cut; cut.pos = move.pos; @@ -183,17 +170,10 @@ void TextWriter::write(QString *s) string = 0; } -void TextWriter::write(QTextCursor *textCursor) -{ - cursor = textCursor; - write_helper(); - cursor = 0; -} - void TextWriter::write_helper() { - if (cursor) - cursor->beginEditBlock(); + Q_ASSERT(string); + { Replace cmd; while (!replaceList.isEmpty()) { @@ -210,8 +190,6 @@ void TextWriter::write_helper() doMove(cmd); } } - if (cursor) - cursor->endEditBlock(); } QT_QML_END_NAMESPACE diff --git a/src/qml/qml/rewriter/textwriter_p.h b/src/qml/qml/rewriter/textwriter_p.h index 94e2d08730..6c36a2f00d 100644 --- a/src/qml/qml/rewriter/textwriter_p.h +++ b/src/qml/qml/rewriter/textwriter_p.h @@ -46,7 +46,6 @@ #include <QtCore/QString> #include <QtCore/QList> -#include <QtGui/QTextCursor> QT_BEGIN_HEADER QT_QML_BEGIN_NAMESPACE @@ -56,7 +55,6 @@ namespace QQmlJS { class TextWriter { QString *string; - QTextCursor *cursor; struct Replace { int pos; @@ -89,8 +87,6 @@ public: void move(int pos, int length, int to); void write(QString *s); - void write(QTextCursor *textCursor); - }; } // end of namespace QQmlJS diff --git a/src/qml/qml/v4/qv4compiler.cpp b/src/qml/qml/v4/qv4compiler.cpp index f8fe3b4b57..608368afc2 100644 --- a/src/qml/qml/v4/qv4compiler.cpp +++ b/src/qml/qml/v4/qv4compiler.cpp @@ -696,29 +696,20 @@ quint8 QV4CompilerPrivate::instructionOpcode(IR::Binop *e) void QV4CompilerPrivate::visitBinop(IR::Binop *e) { + if (e->type == IR::InvalidType) { + discard(); + return; + } + int left = currentReg; int right = currentReg + 1; - if (e->left->asTemp() && e->type != IR::StringType) // Not sure if the e->type != String test is needed - left = e->left->asTemp()->index; - else - traceExpression(e->left, left); + traceExpression(e->left, left); + traceExpression(e->right, right); - if (IR::Temp *t = e->right->asTemp()) - right = t->index; - else - traceExpression(e->right, right); - - if (e->left->type != e->right->type) { - if (qmlVerboseCompiler()) - qWarning().nospace() << "invalid operands to binary operator " << IR::binaryOperator(e->op) - << "(`" << IR::binaryOperator(e->left->type) - << "' and `" - << IR::binaryOperator(e->right->type) - << "'"; - discard(); - return; - } + // At this point it is possible that the type of the + // subexpressions is different. This can happen because + // we keep BINOP expressions in HIR. switch (e->op) { case IR::OpInvalid: diff --git a/src/qml/qml/v4/qv4ir.cpp b/src/qml/qml/v4/qv4ir.cpp index 3b33898cd1..68175d3bf4 100644 --- a/src/qml/qml/v4/qv4ir.cpp +++ b/src/qml/qml/v4/qv4ir.cpp @@ -221,7 +221,7 @@ void Name::init(Name *base, Type type, const QString *id, Symbol symbol, quint32 builtin = MathCosBultinFunction; } else if (id->length() == 10 && *id == QLatin1String("Math.round")) { builtin = MathRoundBultinFunction; - } else if (id->length() == 10 && *id == QLatin1String("Math.floor)")) { + } else if (id->length() == 10 && *id == QLatin1String("Math.floor")) { builtin = MathFloorBultinFunction; } else if (id->length() == 7 && *id == QLatin1String("Math.PI")) { builtin = MathPIBuiltinConstant; @@ -448,11 +448,6 @@ Temp *BasicBlock::TEMP(Type type) return TEMP(type, function->tempCount++); } -Expr *BasicBlock::CONST(double value) -{ - return CONST(IR::RealType, value); -} - Expr *BasicBlock::CONST(Type type, double value) { Const *e = function->pool->New<Const>(); @@ -549,28 +544,30 @@ Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right) if (left && right) { if (Const *c1 = left->asConst()) { if (Const *c2 = right->asConst()) { + const IR::Type ty = Binop::typeForOp(op, left, right); + switch (op) { - case OpAdd: return CONST(c1->value + c2->value); - case OpAnd: return CONST(c1->value ? c2->value : 0); - case OpBitAnd: return CONST(int(c1->value) & int(c2->value)); - case OpBitOr: return CONST(int(c1->value) | int(c2->value)); - case OpBitXor: return CONST(int(c1->value) ^ int(c2->value)); - case OpDiv: return CONST(c1->value / c2->value); - case OpEqual: return CONST(c1->value == c2->value); - case OpGe: return CONST(c1->value >= c2->value); - case OpGt: return CONST(c1->value > c2->value); - case OpLe: return CONST(c1->value <= c2->value); - case OpLShift: return CONST(int(c1->value) << int(c2->value)); - case OpLt: return CONST(c1->value < c2->value); - case OpMod: return CONST(::fmod(c1->value, c2->value)); - case OpMul: return CONST(c1->value * c2->value); - case OpNotEqual: return CONST(c1->value != c2->value); - case OpOr: return CONST(c1->value ? c1->value : c2->value); - case OpRShift: return CONST(int(c1->value) >> int(c2->value)); - case OpStrictEqual: return CONST(c1->value == c2->value); - case OpStrictNotEqual: return CONST(c1->value != c2->value); - case OpSub: return CONST(c1->value - c2->value); - case OpURShift: return CONST(unsigned(c1->value) >> int(c2->value)); + case OpAdd: return CONST(ty, c1->value + c2->value); + case OpAnd: return CONST(ty, c1->value ? c2->value : 0); + case OpBitAnd: return CONST(ty, int(c1->value) & int(c2->value)); + case OpBitOr: return CONST(ty, int(c1->value) | int(c2->value)); + case OpBitXor: return CONST(ty, int(c1->value) ^ int(c2->value)); + case OpDiv: return CONST(ty, c1->value / c2->value); + case OpEqual: return CONST(ty, c1->value == c2->value); + case OpGe: return CONST(ty, c1->value >= c2->value); + case OpGt: return CONST(ty, c1->value > c2->value); + case OpLe: return CONST(ty, c1->value <= c2->value); + case OpLShift: return CONST(ty, int(c1->value) << int(c2->value)); + case OpLt: return CONST(ty, c1->value < c2->value); + case OpMod: return CONST(ty, ::fmod(c1->value, c2->value)); + case OpMul: return CONST(ty, c1->value * c2->value); + case OpNotEqual: return CONST(ty, c1->value != c2->value); + case OpOr: return CONST(ty, c1->value ? c1->value : c2->value); + case OpRShift: return CONST(ty, int(c1->value) >> int(c2->value)); + case OpStrictEqual: return CONST(ty, c1->value == c2->value); + case OpStrictNotEqual: return CONST(ty, c1->value != c2->value); + case OpSub: return CONST(ty, c1->value - c2->value); + case OpURShift: return CONST(ty, unsigned(c1->value) >> int(c2->value)); case OpIfTrue: // unary ops case OpNot: diff --git a/src/qml/qml/v4/qv4ir_p.h b/src/qml/qml/v4/qv4ir_p.h index e80c7e2869..3d3288b65f 100644 --- a/src/qml/qml/v4/qv4ir_p.h +++ b/src/qml/qml/v4/qv4ir_p.h @@ -339,7 +339,6 @@ struct Binop: Expr { virtual void dump(QTextStream &out); -private: static Type typeForOp(AluOp op, Expr *left, Expr *right); }; @@ -525,7 +524,6 @@ struct BasicBlock { Temp *TEMP(Type type, int index); Temp *TEMP(Type type); - Expr *CONST(double value); Expr *CONST(Type type, double value); Expr *STRING(const QStringRef &value); diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp index 32581a072c..36e88e5276 100644 --- a/src/qml/qml/v4/qv4irbuilder.cpp +++ b/src/qml/qml/v4/qv4irbuilder.cpp @@ -531,7 +531,7 @@ bool QV4IRBuilder::visit(AST::NumericLiteral *ast) _expr.format = ExprResult::cx; _block->JUMP(ast->value ? _expr.iftrue : _expr.iffalse); } else { - _expr.code = _block->CONST(ast->value); + _expr.code = _block->CONST(IR::RealType, ast->value); } return false; } @@ -767,7 +767,7 @@ bool QV4IRBuilder::visit(AST::UnaryMinusExpression *ast) if (expr.isNot(IR::InvalidType)) { if (IR::Const *c = expr.code->asConst()) { _expr = expr; - _expr.code = _block->CONST(-c->value); + _expr.code = _block->CONST(expr->type, -c->value); return false; } @@ -785,7 +785,7 @@ bool QV4IRBuilder::visit(AST::TildeExpression *ast) if (expr.isNot(IR::InvalidType)) { if (IR::Const *c = expr.code->asConst()) { _expr = expr; - _expr.code = _block->CONST(~int(c->value)); + _expr.code = _block->CONST(expr->type, ~int(c->value)); return false; } IR::Expr *code = _block->UNOP(IR::OpCompl, expr); @@ -803,7 +803,7 @@ bool QV4IRBuilder::visit(AST::NotExpression *ast) if (expr.isNot(IR::InvalidType)) { if (IR::Const *c = expr.code->asConst()) { _expr = expr; - _expr.code = _block->CONST(!c->value); + _expr.code = _block->CONST(IR::BoolType, !c->value); return false; } @@ -823,16 +823,18 @@ bool QV4IRBuilder::visit(AST::NotExpression *ast) void QV4IRBuilder::binop(AST::BinaryExpression *ast, ExprResult left, ExprResult right) { if (IR::Type t = maxType(left.type(), right.type())) { - implicitCvt(left, t); - implicitCvt(right, t); + if (!left->asConst() && !right->asConst()) { + // the implicit conversions are needed only + // when compiling non-constant expressions. + implicitCvt(left, t); + implicitCvt(right, t); + } if (_expr.hint == ExprResult::cx) { _expr.format = ExprResult::cx; _block->CJUMP(_block->BINOP(IR::binaryOperator(ast->op), left, right), _expr.iftrue, _expr.iffalse); } else { - IR::Expr *code = _block->BINOP(IR::binaryOperator(ast->op), left, right); - _expr.code = _block->TEMP(code->type); - _block->MOVE(_expr.code, code); + _expr.code = _block->BINOP(IR::binaryOperator(ast->op), left, right); } } } @@ -862,7 +864,7 @@ bool QV4IRBuilder::visit(AST::BinaryExpression *ast) IR::Temp *r = _block->TEMP(IR::InvalidType); _block = iffalse; - _block->MOVE(r, _block->CONST(0)); // ### use the right null value + _block->MOVE(r, _block->CONST(IR::BoolType, 0)); // ### use the right null value _block->JUMP(endif); _block = iftrue; diff --git a/src/qml/qml/v8/qv8sequencewrapper_p_p.h b/src/qml/qml/v8/qv8sequencewrapper_p_p.h index 9d519809fa..eebc40eeed 100644 --- a/src/qml/qml/v8/qv8sequencewrapper_p_p.h +++ b/src/qml/qml/v8/qv8sequencewrapper_p_p.h @@ -265,6 +265,7 @@ static QString convertUrlToString(QV8Engine *, const QUrl &v) static QVariant toVariant(QV8Engine *e, v8::Handle<v8::Array> array, uint32_t length, bool *succeeded) \ { \ SequenceType list; \ + list.reserve(length); \ for (uint32_t ii = 0; ii < length; ++ii) { \ list.append(ConversionFromV8fn(e, array->Get(ii))); \ } \ @@ -334,14 +335,15 @@ static QString convertUrlToString(QV8Engine *, const QUrl &v) /* according to ECMA262r3 we need to insert */ \ /* undefined values increasing length to newLength. */ \ /* We cannot, so we insert default-values instead. */ \ + QT_TRY { \ + c.reserve(newCount); \ + } QT_CATCH (std::bad_alloc &exception) { \ + generateWarning(engine, QString(QLatin1String(exception.what()) \ + + QLatin1String(" during length set"))); \ + return; /* failed; don't write back any result. */ \ + } \ while (newCount > count++) { \ - QT_TRY { \ - c.append(DefaultValue); \ - } QT_CATCH (std::bad_alloc &exception) { \ - generateWarning(engine, QString(QLatin1String(exception.what()) \ - + QLatin1String(" during length set"))); \ - return; /* failed; don't write back any result. */ \ - } \ + c.append(DefaultValue); \ } \ } else { \ /* according to ECMA262r3 we need to remove */ \ @@ -382,15 +384,16 @@ static QString convertUrlToString(QV8Engine *, const QUrl &v) /* according to ECMA262r3 we need to insert */ \ /* the value at the given index, increasing length to index+1. */ \ QT_TRY { \ - while (signedIdx > count++) { \ - c.append(DefaultValue); \ - } \ - c.append(elementValue); \ + c.reserve(signedIdx + 1); \ } QT_CATCH (std::bad_alloc &exception) { \ generateWarning(engine, QString(QLatin1String(exception.what()) \ + QLatin1String(" during indexed set"))); \ return v8::Undefined(); /* failed; don't write back any result. */ \ } \ + while (signedIdx > count++) { \ + c.append(DefaultValue); \ + } \ + c.append(elementValue); \ } \ /* write back. already checked that object is non-null, so skip that check here. */ \ if (objectType == QV8SequenceResource::Reference) \ diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp index 170a37c979..60f1992b57 100644 --- a/src/quick/items/qquickcanvas.cpp +++ b/src/quick/items/qquickcanvas.cpp @@ -374,6 +374,14 @@ static QQuickMouseEventEx touchToMouseEvent(QEvent::Type type, const QTouchEvent void QQuickCanvasPrivate::translateTouchToMouse(QTouchEvent *event) { + if (event->type() == QEvent::TouchCancel) { + touchMouseId = -1; + if (!mouseGrabberItem) + return; + mouseGrabberItem->ungrabMouse(); + mouseGrabberItem = 0; + return; + } for (int i = 0; i < event->touchPoints().count(); ++i) { QTouchEvent::TouchPoint p = event->touchPoints().at(i); if (touchMouseId == -1 && p.state() & Qt::TouchPointPressed) { @@ -1177,7 +1185,8 @@ bool QQuickCanvasPrivate::deliverWheelEvent(QQuickItem *item, QWheelEvent *event QPointF p = item->mapFromScene(event->posF()); if (QRectF(0, 0, item->width(), item->height()).contains(p)) { - QWheelEvent wheel(p, event->delta(), event->buttons(), event->modifiers(), event->orientation()); + QWheelEvent wheel(p, p, event->pixelDelta(), event->angleDelta(), event->delta(), + event->orientation(), event->buttons(), event->modifiers()); wheel.accept(); q->sendEvent(item, &wheel); if (wheel.isAccepted()) { diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index 597e64eb18..9222a7766d 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -236,4 +236,108 @@ Item { */ +/*! + \qmlclass WheelEvent QQuickWheelEvent + \inqmlmodule QtQuick 2 + \ingroup qml-event-elements + + \brief The WheelEvent object provides information about a mouse wheel event. + + The position of the mouse can be found via the \l x and \l y properties. + + \sa MouseArea +*/ + +/*! + \internal + \class QQuickWheelEvent +*/ + +/*! + \qmlproperty int QtQuick2::WheelEvent::x + \qmlproperty int QtQuick2::WheelEvent::y + + These properties hold the coordinates of the position supplied by the wheel event. +*/ + +/*! + \qmlproperty bool QtQuick2::WheelEvent::accepted + + Setting \a accepted to true prevents the wheel event from being + propagated to items below this item. + + Generally, if the item acts on the wheel event then it should be accepted + so that items lower in the stacking order do not also respond to the same event. +*/ + +/*! + \qmlproperty int QtQuick2::WheelEvent::buttons + + This property holds the mouse buttons pressed when the wheel event was generated. + + It contains a bitwise combination of: + \list + \o Qt.LeftButton + \o Qt.RightButton + \o Qt.MiddleButton + \endlist +*/ + +/*! + \qmlproperty point QtQuick2::WheelEvent::angleDelta + + This property holds the distance that the wheel is rotated in wheel degrees. + The x and y cordinate of this property holds the delta in horizontal and + vertical orientation. + + A positive value indicates that the wheel was rotated up/right; + a negative value indicates that the wheel was rotated down/left. + + Most mouse types work in steps of 15 degrees, in which case the delta value is a + multiple of 120; i.e., 120 units * 1/8 = 15 degrees. +*/ + +/*! + \qmlproperty point QtQuick2::WheelEvent::pixelDelta + + This property holds the delta in screen pixels and is available in plataforms that + have high-resolution trackpads, such as Mac OS X. + The x and y cordinate of this property holds the delta in horizontal and + vertical orientation. The value should be used directly to scroll content on screen. + + For platforms without high-resolution trackpad support, pixelDelta will always be (0,0), + and angleDelta should be used instead. +*/ + +/*! + \qmlproperty int QtQuick2::WheelEvent::modifiers + + This property holds the keyboard modifier flags that existed immediately + before the event occurred. + + It contains a bitwise combination of: + \list + \o Qt.NoModifier - No modifier key is pressed. + \o Qt.ShiftModifier - A Shift key on the keyboard is pressed. + \o Qt.ControlModifier - A Ctrl key on the keyboard is pressed. + \o Qt.AltModifier - An Alt key on the keyboard is pressed. + \o Qt.MetaModifier - A Meta key on the keyboard is pressed. + \o Qt.KeypadModifier - A keypad button is pressed. + \endlist + + For example, to react to a Control key pressed during the wheel event: + \qml + MouseArea { + onWheel: { + if (wheel.modifiers & Qt.ControlModifier) { + if (wheel.angleDelta.y > 0) + zoomIn(); + else + zoomOut(); + } + } + } + \endqml +*/ + QT_END_NAMESPACE diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h index 6300b0f2a7..004daafb04 100644 --- a/src/quick/items/qquickevents_p_p.h +++ b/src/quick/items/qquickevents_p_p.h @@ -201,9 +201,47 @@ private: }; +class QQuickWheelEvent : public QObject +{ + Q_OBJECT + Q_PROPERTY(qreal x READ x) + Q_PROPERTY(qreal y READ y) + Q_PROPERTY(QPoint angleDelta READ angleDelta) + Q_PROPERTY(QPoint pixelDelta READ pixelDelta) + Q_PROPERTY(int buttons READ buttons) + Q_PROPERTY(int modifiers READ modifiers) + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted) + +public: + QQuickWheelEvent(qreal x, qreal y, const QPoint& angleDelta, const QPoint& pixelDelta, + Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) + : _x(x), _y(y), _angleDelta(angleDelta), _pixelDelta(pixelDelta), _buttons(buttons), + _modifiers(modifiers), _accepted(true) {} + + qreal x() const { return _x; } + qreal y() const { return _y; } + QPoint angleDelta() const { return _angleDelta; } + QPoint pixelDelta() const { return _pixelDelta; } + int buttons() const { return _buttons; } + int modifiers() const { return _modifiers; } + + bool isAccepted() { return _accepted; } + void setAccepted(bool accepted) { _accepted = accepted; } + +private: + qreal _x; + qreal _y; + QPoint _angleDelta; + QPoint _pixelDelta; + Qt::MouseButtons _buttons; + Qt::KeyboardModifiers _modifiers; + bool _accepted; +}; + QT_END_NAMESPACE QML_DECLARE_TYPE(QQuickKeyEvent) QML_DECLARE_TYPE(QQuickMouseEvent) +QML_DECLARE_TYPE(QQuickWheelEvent) #endif // QQUICKEVENTS_P_P_H diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index a78ab4c4e5..78899b27e5 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -120,8 +120,8 @@ public: return itemX() + view->cellWidth(); } } - void setPosition(qreal col, qreal row) { - moveTo(pointForPosition(col, row)); + void setPosition(qreal col, qreal row, bool immediate = false) { + moveTo(pointForPosition(col, row), immediate); } bool contains(qreal x, qreal y) const { return (x >= itemX() && x < itemX() + view->cellWidth() && @@ -483,7 +483,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d if (!(item = static_cast<FxGridItemSG*>(createItem(modelIndex, doBuffer)))) break; if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems() - item->setPosition(colPos, rowPos); + item->setPosition(colPos, rowPos, true); item->item->setVisible(!doBuffer); visibleItems.append(item); if (++colNum >= columns) { @@ -521,7 +521,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d break; --visibleIndex; if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems() - item->setPosition(colPos, rowPos); + item->setPosition(colPos, rowPos, true); item->item->setVisible(!doBuffer); visibleItems.prepend(item); if (--colNum < 0) { @@ -2165,12 +2165,10 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert & FxViewItem *item = visibleItems.at(i); if (item->index != -1 && item->index >= modelIndex) { item->index += count; - if (transitioner) { - if (change.isMove()) - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::MoveTransition, false); - else - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, false); - } + if (change.isMove()) + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, false); + else + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, false); } } @@ -2201,8 +2199,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert & insertResult->changedFirstItem = true; if (!change.isMove()) { addedItems->append(item); - if (transitioner) - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, true); + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); } insertResult->sizeChangesBeforeVisiblePos += rowSize(); } @@ -2239,8 +2236,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert & movingIntoView->append(MovedItem(item, change.moveKey(item->index))); } else { addedItems->append(item); - if (transitioner) - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, true); + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); } insertResult->sizeChangesAfterVisiblePos += rowSize(); @@ -2291,7 +2287,7 @@ void QQuickGridViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex qreal origColPos = gridItem->rowPos(); int indexDiff = gridItem->index - countItemsRemoved; gridItem->setPosition((indexDiff % columns) * colSize(), (indexDiff / columns) * rowSize()); - transitioner->transitionNextReposition(gridItem, QQuickItemViewTransitioner::RemoveTransition, false); + gridItem->transitionNextReposition(transitioner, QQuickItemViewTransitioner::RemoveTransition, false); gridItem->setPosition(origRowPos, origColPos); } } diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index 3d23f7b03a..421a4cd0b1 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -169,6 +169,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType<QQuickAnchors>(); qmlRegisterType<QQuickKeyEvent>(); qmlRegisterType<QQuickMouseEvent>(); + qmlRegisterType<QQuickWheelEvent>(); qmlRegisterType<QQuickTransform>(); qmlRegisterType<QQuickPathElement>(); qmlRegisterType<QQuickCurve>(); diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index e368d1aaec..c6f45aaf0b 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -46,12 +46,16 @@ QT_BEGIN_NAMESPACE FxViewItem::FxViewItem(QQuickItem *i, bool own) - : QQuickViewItem(i), ownItem(own), releaseAfterTransition(false) + : item(i) + , transitionableItem(0) + , ownItem(own) + , releaseAfterTransition(false) { } FxViewItem::~FxViewItem() { + delete transitionableItem; if (ownItem && item) { item->setParentItem(0); item->deleteLater(); @@ -59,6 +63,71 @@ FxViewItem::~FxViewItem() } } +qreal FxViewItem::itemX() const +{ + return transitionableItem ? transitionableItem->itemX() : item->x(); +} + +qreal FxViewItem::itemY() const +{ + return transitionableItem ? transitionableItem->itemY() : item->y(); +} + +void FxViewItem::moveTo(const QPointF &pos, bool immediate) +{ + if (transitionableItem) + transitionableItem->moveTo(pos, immediate); + else + item->setPos(pos); +} + +void FxViewItem::setVisible(bool visible) +{ + if (!visible && transitionableItem && transitionableItem->transitionScheduledOrRunning()) + return; + item->setVisible(visible); +} + +QQuickItemViewTransitioner::TransitionType FxViewItem::scheduledTransitionType() const +{ + return transitionableItem ? transitionableItem->nextTransitionType : QQuickItemViewTransitioner::NoTransition; +} + +bool FxViewItem::transitionScheduledOrRunning() const +{ + return transitionableItem ? transitionableItem->transitionScheduledOrRunning() : false; +} + +bool FxViewItem::transitionRunning() const +{ + return transitionableItem ? transitionableItem->transitionRunning() : false; +} + +bool FxViewItem::isPendingRemoval() const +{ + return transitionableItem ? transitionableItem->isPendingRemoval() : false; +} + +void FxViewItem::transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget) +{ + if (!transitioner) + return; + if (!transitionableItem) + transitionableItem = new QQuickItemViewTransitionableItem(item); + transitioner->transitionNextReposition(transitionableItem, type, asTarget); +} + +bool FxViewItem::prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds) +{ + return transitionableItem ? transitionableItem->prepareTransition(transitioner, index, viewBounds) : false; +} + +void FxViewItem::startTransition(QQuickItemViewTransitioner *transitioner) +{ + if (transitionableItem) + transitionableItem->startTransition(transitioner, index); +} + QQuickItemViewChangeSet::QQuickItemViewChangeSet() : active(false) @@ -1615,7 +1684,7 @@ void QQuickItemViewPrivate::layout() // assume that any items moving now are moving due to the remove - if they schedule // a different transition, that will override this one anyway for (int i=0; i<visibleItems.count(); i++) - transitioner->transitionNextReposition(visibleItems[i], QQuickItemViewTransitioner::RemoveTransition, false); + visibleItems[i]->transitionNextReposition(transitioner, QQuickItemViewTransitioner::RemoveTransition, false); } ChangeResult insertionPosChanges; @@ -1631,7 +1700,7 @@ void QQuickItemViewPrivate::layout() if (transitioner && transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) { for (int i=0; i<visibleItems.count(); i++) - transitioner->transitionNextReposition(visibleItems.at(i), QQuickItemViewTransitioner::PopulateTransition, true); + visibleItems.at(i)->transitionNextReposition(transitioner, QQuickItemViewTransitioner::PopulateTransition, true); } layoutVisibleItems(); @@ -1791,7 +1860,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult repositionItemAt(movingIntoView[i].item, fromIndex, -totalInsertionResult->sizeChangesAfterVisiblePos); else repositionItemAt(movingIntoView[i].item, fromIndex, totalInsertionResult->sizeChangesAfterVisiblePos); - transitioner->transitionNextReposition(movingIntoView[i].item, QQuickItemViewTransitioner::MoveTransition, true); + movingIntoView[i].item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, true); } } } @@ -1855,12 +1924,10 @@ bool QQuickItemViewPrivate::applyRemovalChange(const QQuickChangeSet::Remove &re } else if (item->index >= removal.index + removal.count) { // after removed items item->index -= removal.count; - if (transitioner) { - if (removal.isMove()) - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::MoveTransition, false); - else - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::RemoveTransition, false); - } + if (removal.isMove()) + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, false); + else + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::RemoveTransition, false); ++it; } else { // removed item @@ -1894,8 +1961,7 @@ void QQuickItemViewPrivate::removeItem(FxViewItem *item, const QQuickChangeSet:: } if (removal.isMove()) { currentChanges.removedItems.insert(removal.moveKey(item->index), item); - if (transitioner) - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::MoveTransition, true); + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, true); } else { // track item so it is released later currentChanges.removedItems.insertMulti(QQuickChangeSet::MoveKey(), item); @@ -1977,7 +2043,7 @@ void QQuickItemViewPrivate::prepareRemoveTransitions(QHash<QQuickChangeSet::Move FxViewItem *item = *it; item->releaseAfterTransition = true; releasePendingTransition.append(item); - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::RemoveTransition, true); + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::RemoveTransition, true); it = removedItems->erase(it); } else { ++it; @@ -1996,7 +2062,7 @@ bool QQuickItemViewPrivate::prepareNonVisibleItemTransition(FxViewItem *item, co if (!transitioner) return false; - if (item->nextTransitionType == QQuickItemViewTransitioner::MoveTransition) + if (item->scheduledTransitionType() == QQuickItemViewTransitioner::MoveTransition) repositionItemAt(item, item->index, 0); if (item->prepareTransition(transitioner, viewBounds)) { @@ -2006,12 +2072,13 @@ bool QQuickItemViewPrivate::prepareNonVisibleItemTransition(FxViewItem *item, co return false; } -void QQuickItemViewPrivate::viewItemTransitionFinished(QQuickViewItem *i) +void QQuickItemViewPrivate::viewItemTransitionFinished(QQuickItemViewTransitionableItem *item) { - FxViewItem *item = static_cast<FxViewItem *>(i); - if (item->releaseAfterTransition) { - releasePendingTransition.removeOne(item); - releaseItem(item); + for (int i=0; i<releasePendingTransition.count(); i++) { + if (releasePendingTransition[i]->transitionableItem == item) { + releaseItem(releasePendingTransition.takeAt(i)); + return; + } } } diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h index 80dacc0cb4..dfc0a8bc7e 100644 --- a/src/quick/items/qquickitemview_p_p.h +++ b/src/quick/items/qquickitemview_p_p.h @@ -57,12 +57,27 @@ QT_BEGIN_NAMESPACE QT_MODULE(Quick) -class FxViewItem : public QQuickViewItem +class FxViewItem { public: FxViewItem(QQuickItem *, bool own); virtual ~FxViewItem(); + qreal itemX() const; + qreal itemY() const; + + void moveTo(const QPointF &pos, bool immediate); + void setVisible(bool visible); + + QQuickItemViewTransitioner::TransitionType scheduledTransitionType() const; + bool transitionScheduledOrRunning() const; + bool transitionRunning() const; + bool isPendingRemoval() const; + + void transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget); + bool prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds); + void startTransition(QQuickItemViewTransitioner *transitioner); + // these are positions and sizes along the current direction of scrolling/flicking virtual qreal position() const = 0; virtual qreal endPosition() const = 0; @@ -71,7 +86,10 @@ public: virtual bool contains(qreal x, qreal y) const = 0; + QQuickItem *item; + QQuickItemViewTransitionableItem *transitionableItem; QQuickItemViewAttached *attached; + int index; bool ownItem; bool releaseAfterTransition; }; @@ -192,7 +210,7 @@ public: void prepareVisibleItemTransitions(); void prepareRemoveTransitions(QHash<QQuickChangeSet::MoveKey, FxViewItem *> *removedItems); bool prepareNonVisibleItemTransition(FxViewItem *item, const QRectF &viewBounds); - virtual void viewItemTransitionFinished(QQuickViewItem *item); + virtual void viewItemTransitionFinished(QQuickItemViewTransitionableItem *item); int findMoveKeyIndex(QQuickChangeSet::MoveKey key, const QVector<QQuickChangeSet::Remove> &changes) const; diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp index 5669ef927e..d9dce49349 100644 --- a/src/quick/items/qquickitemviewtransition.cpp +++ b/src/quick/items/qquickitemviewtransition.cpp @@ -55,13 +55,14 @@ public: QQuickItemViewTransitionJob(); ~QQuickItemViewTransitionJob(); - void startTransition(QQuickViewItem *item, QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, const QPointF &to, bool isTargetItem); + void startTransition(QQuickItemViewTransitionableItem *item, int index, QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, const QPointF &to, bool isTargetItem); QQuickItemViewTransitioner *m_transitioner; - QQuickViewItem *m_item; + QQuickItemViewTransitionableItem *m_item; QPointF m_toPos; QQuickItemViewTransitioner::TransitionType m_type; bool m_isTarget; + bool *m_wasDeleted; protected: virtual void finished(); @@ -73,16 +74,19 @@ QQuickItemViewTransitionJob::QQuickItemViewTransitionJob() , m_item(0) , m_type(QQuickItemViewTransitioner::NoTransition) , m_isTarget(false) + , m_wasDeleted(0) { } QQuickItemViewTransitionJob::~QQuickItemViewTransitionJob() { + if (m_wasDeleted) + *m_wasDeleted = true; if (m_transitioner) m_transitioner->runningJobs.remove(this); } -void QQuickItemViewTransitionJob::startTransition(QQuickViewItem *item, QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, const QPointF &to, bool isTargetItem) +void QQuickItemViewTransitionJob::startTransition(QQuickItemViewTransitionableItem *item, int index, QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, const QPointF &to, bool isTargetItem) { if (type == QQuickItemViewTransitioner::NoTransition) return; @@ -110,7 +114,7 @@ void QQuickItemViewTransitionJob::startTransition(QQuickViewItem *item, QQuickIt QQuickViewTransitionAttached *attached = static_cast<QQuickViewTransitionAttached*>(qmlAttachedPropertiesObject<QQuickViewTransitionAttached>(trans)); if (attached) { - attached->m_index = item->index; + attached->m_index = index; attached->m_item = item->item; attached->m_destination = to; attached->m_targetIndexes = m_transitioner->targetIndexes(type); @@ -134,8 +138,16 @@ void QQuickItemViewTransitionJob::finished() { QQuickTransitionManager::finished(); - if (m_transitioner) + if (m_transitioner) { + bool deleted = false; + m_wasDeleted = &deleted; m_transitioner->finishedTransition(this, m_item); + if (deleted) + return; + m_wasDeleted = 0; + + m_transitioner = 0; + } m_item = 0; m_toPos.setX(0); @@ -197,12 +209,12 @@ bool QQuickItemViewTransitioner::canTransition(QQuickItemViewTransitioner::Trans return false; } -void QQuickItemViewTransitioner::transitionNextReposition(QQuickViewItem *item, QQuickItemViewTransitioner::TransitionType type, bool isTarget) +void QQuickItemViewTransitioner::transitionNextReposition(QQuickItemViewTransitionableItem *item, QQuickItemViewTransitioner::TransitionType type, bool isTarget) { item->setNextTransition(type, isTarget); } -void QQuickItemViewTransitioner::addToTargetLists(QQuickItemViewTransitioner::TransitionType type, QQuickViewItem *item, int index) +void QQuickItemViewTransitioner::addToTargetLists(QQuickItemViewTransitioner::TransitionType type, QQuickItemViewTransitionableItem *item, int index) { switch (type) { case NoTransition: @@ -302,7 +314,7 @@ const QList<QObject *> &QQuickItemViewTransitioner::targetItems(QQuickItemViewTr return qquickitemviewtransition_emptyTargets; } -void QQuickItemViewTransitioner::finishedTransition(QQuickItemViewTransitionJob *job, QQuickViewItem *item) +void QQuickItemViewTransitioner::finishedTransition(QQuickItemViewTransitionJob *job, QQuickItemViewTransitionableItem *item) { if (!runningJobs.contains(job)) return; @@ -315,23 +327,22 @@ void QQuickItemViewTransitioner::finishedTransition(QQuickItemViewTransitionJob } -QQuickViewItem::QQuickViewItem(QQuickItem *i) +QQuickItemViewTransitionableItem::QQuickItemViewTransitionableItem(QQuickItem *i) : item(i) , transition(0) , nextTransitionType(QQuickItemViewTransitioner::NoTransition) - , index(-1) , isTransitionTarget(false) , nextTransitionToSet(false) , prepared(false) { } -QQuickViewItem::~QQuickViewItem() +QQuickItemViewTransitionableItem::~QQuickItemViewTransitionableItem() { delete transition; } -qreal QQuickViewItem::itemX() const +qreal QQuickItemViewTransitionableItem::itemX() const { if (nextTransitionType != QQuickItemViewTransitioner::NoTransition) return nextTransitionToSet ? nextTransitionTo.x() : item->x(); @@ -341,7 +352,7 @@ qreal QQuickViewItem::itemX() const return item->x(); } -qreal QQuickViewItem::itemY() const +qreal QQuickItemViewTransitionableItem::itemY() const { // If item is transitioning to some pos, return that dest pos. // If item was redirected to some new pos before the current transition finished, @@ -354,35 +365,33 @@ qreal QQuickViewItem::itemY() const return item->y(); } -void QQuickViewItem::moveTo(const QPointF &pos) +void QQuickItemViewTransitionableItem::moveTo(const QPointF &pos, bool immediate) { - if (transitionScheduledOrRunning()) { + if (immediate || !transitionScheduledOrRunning()) { + if (immediate) { + if (transition) + transition->cancel(); + resetTransitionData(); + } + item->setPos(pos); + } else { nextTransitionTo = pos; nextTransitionToSet = true; - } else { - item->setPos(pos); } } -void QQuickViewItem::setVisible(bool visible) -{ - if (!visible && transitionScheduledOrRunning()) - return; - item->setVisible(visible); -} - -bool QQuickViewItem::transitionScheduledOrRunning() const +bool QQuickItemViewTransitionableItem::transitionScheduledOrRunning() const { return (transition && transition->isRunning()) || nextTransitionType != QQuickItemViewTransitioner::NoTransition; } -bool QQuickViewItem::transitionRunning() const +bool QQuickItemViewTransitionableItem::transitionRunning() const { return (transition && transition->isRunning()); } -bool QQuickViewItem::isPendingRemoval() const +bool QQuickItemViewTransitionableItem::isPendingRemoval() const { if (nextTransitionType == QQuickItemViewTransitioner::RemoveTransition) return isTransitionTarget; @@ -391,7 +400,7 @@ bool QQuickViewItem::isPendingRemoval() const return false; } -bool QQuickViewItem::prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds) +bool QQuickItemViewTransitionableItem::prepareTransition(QQuickItemViewTransitioner *transitioner, int index, const QRectF &viewBounds) { bool doTransition = false; @@ -466,7 +475,7 @@ bool QQuickViewItem::prepareTransition(QQuickItemViewTransitioner *transitioner, return doTransition; } -void QQuickViewItem::startTransition(QQuickItemViewTransitioner *transitioner) +void QQuickItemViewTransitionableItem::startTransition(QQuickItemViewTransitioner *transitioner, int index) { if (nextTransitionType == QQuickItemViewTransitioner::NoTransition) return; @@ -486,12 +495,12 @@ void QQuickViewItem::startTransition(QQuickItemViewTransitioner *transitioner) if (!nextTransitionToSet) moveTo(item->pos()); - transition->startTransition(this, transitioner, nextTransitionType, nextTransitionTo, isTransitionTarget); + transition->startTransition(this, index, transitioner, nextTransitionType, nextTransitionTo, isTransitionTarget); nextTransitionType = QQuickItemViewTransitioner::NoTransition; prepared = false; } -void QQuickViewItem::setNextTransition(QQuickItemViewTransitioner::TransitionType type, bool isTargetItem) +void QQuickItemViewTransitionableItem::setNextTransition(QQuickItemViewTransitioner::TransitionType type, bool isTargetItem) { // Don't reset nextTransitionToSet - once it is set, it cannot be changed // until the animation finishes since the itemX() and itemY() may be used @@ -500,20 +509,20 @@ void QQuickViewItem::setNextTransition(QQuickItemViewTransitioner::TransitionTyp isTransitionTarget = isTargetItem; } -bool QQuickViewItem::transitionWillChangePosition() const +bool QQuickItemViewTransitionableItem::transitionWillChangePosition() const { if (transitionRunning() && transition->m_toPos != nextTransitionTo) return true; return nextTransitionTo != item->pos(); } -void QQuickViewItem::finishedTransition() +void QQuickItemViewTransitionableItem::finishedTransition() { nextTransitionToSet = false; nextTransitionTo = QPointF(); } -void QQuickViewItem::resetTransitionData() +void QQuickItemViewTransitionableItem::resetTransitionData() { nextTransitionType = QQuickItemViewTransitioner::NoTransition; isTransitionTarget = false; diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h index 73c238e929..a4babdca05 100644 --- a/src/quick/items/qquickitemviewtransition_p.h +++ b/src/quick/items/qquickitemviewtransition_p.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Quick) class QQuickItem; -class QQuickViewItem; +class QQuickItemViewTransitionableItem; class QQuickItemViewTransitionJob; @@ -61,7 +61,7 @@ public: QQuickItemViewTransitionChangeListener() {} virtual ~QQuickItemViewTransitionChangeListener() {} - virtual void viewItemTransitionFinished(QQuickViewItem *item) = 0; + virtual void viewItemTransitionFinished(QQuickItemViewTransitionableItem *item) = 0; }; @@ -80,9 +80,9 @@ public: virtual ~QQuickItemViewTransitioner(); bool canTransition(QQuickItemViewTransitioner::TransitionType type, bool asTarget) const; - void transitionNextReposition(QQuickViewItem *item, QQuickItemViewTransitioner::TransitionType type, bool isTarget); + void transitionNextReposition(QQuickItemViewTransitionableItem *item, QQuickItemViewTransitioner::TransitionType type, bool isTarget); - void addToTargetLists(QQuickItemViewTransitioner::TransitionType type, QQuickViewItem *item, int index); + void addToTargetLists(QQuickItemViewTransitioner::TransitionType type, QQuickItemViewTransitionableItem *item, int index); void resetTargetLists(); QQuickTransition *transitionObject(QQuickItemViewTransitioner::TransitionType type, bool asTarget); @@ -116,37 +116,35 @@ private: QQuickItemViewTransitionChangeListener *changeListener; bool usePopulateTransition; - void finishedTransition(QQuickItemViewTransitionJob *job, QQuickViewItem *item); + void finishedTransition(QQuickItemViewTransitionJob *job, QQuickItemViewTransitionableItem *item); }; /* - An item in a view, that can be transitioned using QQuickViewTransitionJob. + An item that can be transitioned using QQuickViewTransitionJob. */ -class QQuickViewItem +class QQuickItemViewTransitionableItem { public: - QQuickViewItem(QQuickItem *i); - virtual ~QQuickViewItem(); + QQuickItemViewTransitionableItem(QQuickItem *i); + virtual ~QQuickItemViewTransitionableItem(); qreal itemX() const; qreal itemY() const; - void moveTo(const QPointF &pos); - void setVisible(bool visible); + void moveTo(const QPointF &pos, bool immediate = false); bool transitionScheduledOrRunning() const; bool transitionRunning() const; bool isPendingRemoval() const; - bool prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds); - void startTransition(QQuickItemViewTransitioner *transitioner); + bool prepareTransition(QQuickItemViewTransitioner *transitioner, int index, const QRectF &viewBounds); + void startTransition(QQuickItemViewTransitioner *transitioner, int index); QPointF nextTransitionTo; QQuickItem *item; QQuickItemViewTransitionJob *transition; QQuickItemViewTransitioner::TransitionType nextTransitionType; - int index; bool isTransitionTarget; bool nextTransitionToSet; bool prepared; diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index a2f687c86b..9db2060d89 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -292,7 +292,7 @@ public: : itemX() + item->width()); } } - void setPosition(qreal pos) { + void setPosition(qreal pos, bool immediate = false) { // position the section immediately even if there is a transition if (section()) { if (view->orientation() == QQuickListView::Vertical) { @@ -304,7 +304,7 @@ public: section()->setX(pos); } } - moveTo(pointForPosition(pos)); + moveTo(pointForPosition(pos), immediate); } void setSize(qreal size) { if (view->orientation() == QQuickListView::Vertical) @@ -638,7 +638,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d if (!(item = static_cast<FxListItemSG*>(createItem(modelIndex, doBuffer)))) break; if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems() - item->setPosition(pos); + item->setPosition(pos, true); item->item->setVisible(!doBuffer); pos += item->size() + spacing; visibleItems.append(item); @@ -658,7 +658,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, bool d --visibleIndex; visiblePos -= item->size() + spacing; if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems() - item->setPosition(visiblePos); + item->setPosition(visiblePos, true); item->item->setVisible(!doBuffer); visibleItems.prepend(item); changed = true; @@ -2786,8 +2786,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert & insertResult->changedFirstItem = true; if (!change.isMove()) { addedItems->append(item); - if (transitioner) - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, true); + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); } insertResult->sizeChangesBeforeVisiblePos += item->size() + spacing; pos -= item->size() + spacing; @@ -2817,8 +2816,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert & movingIntoView->append(MovedItem(item, change.moveKey(item->index))); } else { addedItems->append(item); - if (transitioner) - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, true); + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); } insertResult->sizeChangesAfterVisiblePos += item->size() + spacing; pos += item->size() + spacing; @@ -2828,13 +2826,12 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert & for (; index < visibleItems.count(); ++index) { FxViewItem *item = visibleItems.at(index); - if (item->index != -1) + if (item->index != -1) { item->index += count; - if (transitioner) { if (change.isMove()) - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::MoveTransition, false); + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, false); else - transitioner->transitionNextReposition(item, QQuickItemViewTransitioner::AddTransition, false); + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, false); } } @@ -2869,7 +2866,7 @@ void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex if (!listItem->transitionScheduledOrRunning()) { qreal pos = listItem->position(); listItem->setPosition(pos - sizeRemoved); - transitioner->transitionNextReposition(listItem, QQuickItemViewTransitioner::RemoveTransition, false); + listItem->transitionNextReposition(transitioner, QQuickItemViewTransitioner::RemoveTransition, false); listItem->setPosition(pos); } } diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index ef57242319..efb804bd18 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -236,6 +236,13 @@ bool QQuickMouseAreaPrivate::isClickConnected() return QObjectPrivate::get(q)->isSignalConnected(idx); } +bool QQuickMouseAreaPrivate::isWheelConnected() +{ + Q_Q(QQuickMouseArea); + static int idx = QObjectPrivate::get(q)->signalIndex("wheel(QQuickWheelEvent*)"); + return QObjectPrivate::get(q)->isSignalConnected(idx); +} + void QQuickMouseAreaPrivate::propagate(QQuickMouseEvent* event, PropagateType t) { Q_Q(QQuickMouseArea); @@ -331,7 +338,8 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i Information about the mouse position and button clicks are provided via signals for which event handler properties are defined. The most commonly used involved handling mouse presses and clicks: onClicked, onDoubleClicked, - onPressed, onReleased and onPressAndHold. + onPressed, onReleased and onPressAndHold. It's also possible to handle mouse + wheel events via the onWheel signal. By default, MouseArea items only report mouse clicks and not changes to the position of the mouse cursor. Setting the hoverEnabled property ensures that @@ -513,6 +521,17 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i the logic when the MouseArea has lost the mouse handling to the \l Flickable, \c onCanceled should be used in addition to onReleased. */ + +/*! + \qmlsignal QtQuick2::MouseArea::onWheel(WheelEvent mouse) + + This handler is called in response to both mouse wheel and trackpad scroll gestures. + + The \l {WheelEvent}{wheel} parameter provides information about the event, including the x and y + position, any buttons currently pressed, and information about the wheel movement, including + angleDelta and pixelDelta. +*/ + QQuickMouseArea::QQuickMouseArea(QQuickItem *parent) : QQuickItem(*(new QQuickMouseAreaPrivate), parent) { @@ -860,6 +879,22 @@ void QQuickMouseArea::hoverLeaveEvent(QHoverEvent *event) setHovered(false); } +void QQuickMouseArea::wheelEvent(QWheelEvent *event) +{ + Q_D(QQuickMouseArea); + if (!d->absorb) { + QQuickItem::wheelEvent(event); + return; + } + + QQuickWheelEvent we(event->posF().x(), event->posF().y(), event->angleDelta(), + event->pixelDelta(), event->buttons(), event->modifiers()); + we.setAccepted(d->isWheelConnected()); + emit wheel(&we); + if (!we.isAccepted()) + QQuickItem::wheelEvent(event); +} + void QQuickMouseArea::ungrabMouse() { Q_D(QQuickMouseArea); diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h index 93a0635eb5..7eb9e5da05 100644 --- a/src/quick/items/qquickmousearea_p.h +++ b/src/quick/items/qquickmousearea_p.h @@ -119,6 +119,7 @@ private: }; class QQuickMouseAreaPrivate; +class QQuickWheelEvent; // used in QtLocation class Q_QUICK_EXPORT QQuickMouseArea : public QQuickItem { @@ -182,6 +183,7 @@ Q_SIGNALS: void released(QQuickMouseEvent *mouse); void clicked(QQuickMouseEvent *mouse); void doubleClicked(QQuickMouseEvent *mouse); + void wheel(QQuickWheelEvent *wheel); void entered(); void exited(); void canceled(); @@ -199,6 +201,7 @@ protected: virtual void hoverEnterEvent(QHoverEvent *event); virtual void hoverMoveEvent(QHoverEvent *event); virtual void hoverLeaveEvent(QHoverEvent *event); + virtual void wheelEvent(QWheelEvent *event); virtual bool childMouseEventFilter(QQuickItem *i, QEvent *e); virtual void timerEvent(QTimerEvent *event); virtual void windowDeactivateEvent(); diff --git a/src/quick/items/qquickmousearea_p_p.h b/src/quick/items/qquickmousearea_p_p.h index bcdf033cba..f5521d9228 100644 --- a/src/quick/items/qquickmousearea_p_p.h +++ b/src/quick/items/qquickmousearea_p_p.h @@ -83,6 +83,7 @@ public: bool isPressAndHoldConnected(); bool isDoubleClickConnected(); bool isClickConnected(); + bool isWheelConnected(); bool absorb : 1; bool hovered : 1; diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp index e9a0c179e0..7c4cd18346 100644 --- a/src/quick/items/qquickpositioners.cpp +++ b/src/quick/items/qquickpositioners.cpp @@ -72,6 +72,60 @@ void QQuickBasePositionerPrivate::unwatchChanges(QQuickItem* other) otherPrivate->removeItemChangeListener(this, watchedChanges); } + +QQuickBasePositioner::PositionedItem::PositionedItem(QQuickItem *i) + : item(i) + , transitionableItem(0) + , index(-1) + , isNew(false) + , isVisible(true) +{ +} + +QQuickBasePositioner::PositionedItem::~PositionedItem() +{ + delete transitionableItem; +} + +qreal QQuickBasePositioner::PositionedItem::itemX() const +{ + return transitionableItem ? transitionableItem->itemX() : item->x(); +} + +qreal QQuickBasePositioner::PositionedItem::itemY() const +{ + return transitionableItem ? transitionableItem->itemY() : item->y(); +} + +void QQuickBasePositioner::PositionedItem::moveTo(const QPointF &pos) +{ + if (transitionableItem) + transitionableItem->moveTo(pos); + else + item->setPos(pos); +} + +void QQuickBasePositioner::PositionedItem::transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget) +{ + if (!transitioner) + return; + if (!transitionableItem) + transitionableItem = new QQuickItemViewTransitionableItem(item); + transitioner->transitionNextReposition(transitionableItem, type, asTarget); +} + +bool QQuickBasePositioner::PositionedItem::prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds) +{ + return transitionableItem ? transitionableItem->prepareTransition(transitioner, index, viewBounds) : false; +} + +void QQuickBasePositioner::PositionedItem::startTransition(QQuickItemViewTransitioner *transitioner) +{ + if (transitionableItem) + transitionableItem->startTransition(transitioner, index); +} + + QQuickBasePositioner::QQuickBasePositioner(PositionerType at, QQuickItem *parent) : QQuickImplicitSizeItem(*(new QQuickBasePositionerPrivate), parent) { @@ -114,7 +168,8 @@ QQuickBasePositioner::~QQuickBasePositioner() d->unwatchChanges(positionedItems.at(i).item); for (int i = 0; i < unpositionedItems.count(); ++i) d->unwatchChanges(unpositionedItems.at(i).item); - positionedItems.clear(); + clearPositionedItems(&positionedItems); + clearPositionedItems(&unpositionedItems); } void QQuickBasePositioner::updatePolish() @@ -194,10 +249,10 @@ void QQuickBasePositioner::itemChange(ItemChange change, const ItemChangeData &v int idx = positionedItems.find(posItem); if (idx >= 0) { d->unwatchChanges(child); - positionedItems.remove(idx); + removePositionedItem(&positionedItems, idx); } else if ((idx = unpositionedItems.find(posItem)) >= 0) { d->unwatchChanges(child); - unpositionedItems.remove(idx); + removePositionedItem(&unpositionedItems, idx); } d->setPositioningDirty(); } @@ -246,8 +301,7 @@ void QQuickBasePositioner::prePositioning() if (addedIndex < 0) addedIndex = posItem.index; PositionedItem *theItem = &positionedItems[positionedItems.count()-1]; - d->transitioner->transitionNextReposition(theItem, - QQuickItemViewTransitioner::AddTransition, true); + theItem->transitionNextReposition(d->transitioner, QQuickItemViewTransitioner::AddTransition, true); } } } else { @@ -268,8 +322,7 @@ void QQuickBasePositioner::prePositioning() if (d->transitioner) { if (addedIndex < 0) addedIndex = item->index; - d->transitioner->transitionNextReposition(&positionedItems[positionedItems.count()-1], - QQuickItemViewTransitioner::AddTransition, true); + positionedItems[positionedItems.count()-1].transitionNextReposition(d->transitioner, QQuickItemViewTransitioner::AddTransition, true); } } else { item->isNew = false; @@ -283,11 +336,11 @@ void QQuickBasePositioner::prePositioning() for (int i=0; i<positionedItems.count(); i++) { if (!positionedItems[i].isNew) { if (addedIndex >= 0) { - d->transitioner->transitionNextReposition(&positionedItems[i], QQuickItemViewTransitioner::AddTransition, false); + positionedItems[i].transitionNextReposition(d->transitioner, QQuickItemViewTransitioner::AddTransition, false); } else { // just queue the item for a move-type displace - if the item hasn't // moved anywhere, it won't be transitioned anyway - d->transitioner->transitionNextReposition(&positionedItems[i], QQuickItemViewTransitioner::MoveTransition, false); + positionedItems[i].transitionNextReposition(d->transitioner, QQuickItemViewTransitioner::MoveTransition, false); } } } @@ -342,6 +395,24 @@ void QQuickBasePositioner::positionItemY(qreal y, PositionedItem *target) } } +/* + Since PositionedItem values are stored by value, their internal transitionableItem pointers + must be cleaned up when a PositionedItem is removed from a QPODVector, otherwise the pointer + is never deleted since QPODVector doesn't invoke the destructor. + */ +void QQuickBasePositioner::removePositionedItem(QPODVector<PositionedItem,8> *items, int index) +{ + Q_ASSERT(index >= 0 && index < items->count()); + delete items->at(index).transitionableItem; + items->remove(index); +} +void QQuickBasePositioner::clearPositionedItems(QPODVector<PositionedItem,8> *items) +{ + for (int i=0; i<items->count(); i++) + delete items->at(i).transitionableItem; + items->clear(); +} + QQuickPositionerAttached *QQuickBasePositioner::qmlAttachedProperties(QObject *obj) { return new QQuickPositionerAttached(obj); diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h index 8921bfa39b..c13d9975af 100644 --- a/src/quick/items/qquickpositioners_p.h +++ b/src/quick/items/qquickpositioners_p.h @@ -133,22 +133,39 @@ protected: virtual void doPositioning(QSizeF *contentSize)=0; virtual void reportConflictingAnchors()=0; - class PositionedItem : public QQuickViewItem + class PositionedItem { public : - PositionedItem(QQuickItem *i) : QQuickViewItem(i), isNew(false), isVisible(true) {} + PositionedItem(QQuickItem *i); + ~PositionedItem(); bool operator==(const PositionedItem &other) const { return other.item == item; } + qreal itemX() const; + qreal itemY() const; + + void moveTo(const QPointF &pos); + + void transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget); + bool prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds); + void startTransition(QQuickItemViewTransitioner *transitioner); + + QQuickItem *item; + QQuickItemViewTransitionableItem *transitionableItem; + int index; bool isNew; bool isVisible; }; QPODVector<PositionedItem,8> positionedItems; QPODVector<PositionedItem,8> unpositionedItems;//Still 'in' the positioner, just not positioned + void positionItem(qreal x, qreal y, PositionedItem *target); void positionItemX(qreal, PositionedItem *target); void positionItemY(qreal, PositionedItem *target); + void removePositionedItem(QPODVector<PositionedItem,8> *items, int index); + void clearPositionedItems(QPODVector<PositionedItem,8> *items); + private: Q_DISABLE_COPY(QQuickBasePositioner) Q_DECLARE_PRIVATE(QQuickBasePositioner) diff --git a/src/quick/items/qquickpositioners_p_p.h b/src/quick/items/qquickpositioners_p_p.h index 21fa67574b..8c6bf7f101 100644 --- a/src/quick/items/qquickpositioners_p_p.h +++ b/src/quick/items/qquickpositioners_p_p.h @@ -139,7 +139,9 @@ public: void itemDestroyed(QQuickItem *item) { Q_Q(QQuickBasePositioner); - q->positionedItems.removeOne(QQuickBasePositioner::PositionedItem(item)); + int index = q->positionedItems.find(QQuickBasePositioner::PositionedItem(item)); + if (index >= 0) + q->removePositionedItem(&q->positionedItems, index); } static Qt::LayoutDirection getLayoutDirection(const QQuickBasePositioner *positioner) diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index a9bff73bd9..3db5f5a7a3 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -1626,7 +1626,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * QRectF bounds = boundingRect(); node->addTextDocument(bounds.topLeft(), d->document, d->color, QQuickText::Normal, QColor(), - d->selectionColor, d->selectedTextColor, selectionStart(), + QColor(), d->selectionColor, d->selectedTextColor, selectionStart(), selectionEnd() - 1); // selectionEnd() returns first char after // selection |