diff options
author | Olivier Goffart <olivier.goffart@nokia.com> | 2010-07-29 14:15:12 +0200 |
---|---|---|
committer | Olivier Goffart <olivier.goffart@nokia.com> | 2010-07-29 14:36:11 +0200 |
commit | f3cdbeff63e53e78e86d7196500ca46ac7273844 (patch) | |
tree | 2693855fa6c83ad0afa46f48f99e1a1d30a2262d /src/libs/qmljsdebugclient | |
parent | 333334c64cf1e42929a1729ea8f23fb0d2c02e5a (diff) | |
download | qt-creator-f3cdbeff63e53e78e86d7196500ca46ac7273844.tar.gz |
QmlJsInspector: remove private header dependencies
A copy of the client debugging code is made in src/libs/qmljsdebugclient/
(this comes from the qt code from commit 65642dd343bf61)
So the qmljsinspector plugin does not require anymore Qt private headers.
Diffstat (limited to 'src/libs/qmljsdebugclient')
-rw-r--r-- | src/libs/qmljsdebugclient/qdeclarativedebug.cpp | 1023 | ||||
-rw-r--r-- | src/libs/qmljsdebugclient/qdeclarativedebug_p.h | 377 | ||||
-rw-r--r-- | src/libs/qmljsdebugclient/qdeclarativedebugclient.cpp | 198 | ||||
-rw-r--r-- | src/libs/qmljsdebugclient/qdeclarativedebugclient_p.h | 99 | ||||
-rw-r--r-- | src/libs/qmljsdebugclient/qmljsdebugclient-lib.pri | 15 | ||||
-rw-r--r-- | src/libs/qmljsdebugclient/qpacketprotocol.cpp | 498 | ||||
-rw-r--r-- | src/libs/qmljsdebugclient/qpacketprotocol_p.h | 122 |
7 files changed, 2332 insertions, 0 deletions
diff --git a/src/libs/qmljsdebugclient/qdeclarativedebug.cpp b/src/libs/qmljsdebugclient/qdeclarativedebug.cpp new file mode 100644 index 0000000000..1b9af0d0b4 --- /dev/null +++ b/src/libs/qmljsdebugclient/qdeclarativedebug.cpp @@ -0,0 +1,1023 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdeclarativedebug_p.h" + +#include "qdeclarativedebugclient_p.h" + +#include <private/qobject_p.h> + +namespace QmlJsDebugClient { + +class QDeclarativeEngineDebugClient : public QDeclarativeDebugClient +{ +public: + QDeclarativeEngineDebugClient(QDeclarativeDebugConnection *client, QDeclarativeEngineDebugPrivate *p); + +protected: + virtual void messageReceived(const QByteArray &); + +private: + QDeclarativeEngineDebugPrivate *priv; +}; + +class QDeclarativeEngineDebugPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QDeclarativeEngineDebug) +public: + QDeclarativeEngineDebugPrivate(QDeclarativeDebugConnection *); + + void message(const QByteArray &); + + QDeclarativeEngineDebugClient *client; + int nextId; + int getId(); + + void decode(QDataStream &, QDeclarativeDebugContextReference &); + void decode(QDataStream &, QDeclarativeDebugObjectReference &, bool simple); + + static void remove(QDeclarativeEngineDebug *, QDeclarativeDebugEnginesQuery *); + static void remove(QDeclarativeEngineDebug *, QDeclarativeDebugRootContextQuery *); + static void remove(QDeclarativeEngineDebug *, QDeclarativeDebugObjectQuery *); + static void remove(QDeclarativeEngineDebug *, QDeclarativeDebugExpressionQuery *); + + QHash<int, QDeclarativeDebugEnginesQuery *> enginesQuery; + QHash<int, QDeclarativeDebugRootContextQuery *> rootContextQuery; + QHash<int, QDeclarativeDebugObjectQuery *> objectQuery; + QHash<int, QDeclarativeDebugExpressionQuery *> expressionQuery; + + QHash<int, QDeclarativeDebugWatch *> watched; +}; + +QDeclarativeEngineDebugClient::QDeclarativeEngineDebugClient(QDeclarativeDebugConnection *client, + QDeclarativeEngineDebugPrivate *p) +: QDeclarativeDebugClient(QLatin1String("QDeclarativeEngine"), client), priv(p) +{ + setEnabled(true); +} + +void QDeclarativeEngineDebugClient::messageReceived(const QByteArray &data) +{ + priv->message(data); +} + +QDeclarativeEngineDebugPrivate::QDeclarativeEngineDebugPrivate(QDeclarativeDebugConnection *c) +: client(new QDeclarativeEngineDebugClient(c, this)), nextId(0) +{ +} + +int QDeclarativeEngineDebugPrivate::getId() +{ + return nextId++; +} + +void QDeclarativeEngineDebugPrivate::remove(QDeclarativeEngineDebug *c, QDeclarativeDebugEnginesQuery *q) +{ + if (c && q) { + QDeclarativeEngineDebugPrivate *p = (QDeclarativeEngineDebugPrivate *)QObjectPrivate::get(c); + p->enginesQuery.remove(q->m_queryId); + } +} + +void QDeclarativeEngineDebugPrivate::remove(QDeclarativeEngineDebug *c, + QDeclarativeDebugRootContextQuery *q) +{ + if (c && q) { + QDeclarativeEngineDebugPrivate *p = (QDeclarativeEngineDebugPrivate *)QObjectPrivate::get(c); + p->rootContextQuery.remove(q->m_queryId); + } +} + +void QDeclarativeEngineDebugPrivate::remove(QDeclarativeEngineDebug *c, QDeclarativeDebugObjectQuery *q) +{ + if (c && q) { + QDeclarativeEngineDebugPrivate *p = (QDeclarativeEngineDebugPrivate *)QObjectPrivate::get(c); + p->objectQuery.remove(q->m_queryId); + } +} + +void QDeclarativeEngineDebugPrivate::remove(QDeclarativeEngineDebug *c, QDeclarativeDebugExpressionQuery *q) +{ + if (c && q) { + QDeclarativeEngineDebugPrivate *p = (QDeclarativeEngineDebugPrivate *)QObjectPrivate::get(c); + p->expressionQuery.remove(q->m_queryId); + } +} + +//from qdeclarativeenginedebug.cpp +struct QDeclarativeObjectData { + QUrl url; + int lineNumber; + int columnNumber; + QString idString; + QString objectName; + QString objectType; + int objectId; + int contextId; +}; +QDataStream &operator>>(QDataStream &ds, QDeclarativeObjectData &data) +{ + ds >> data.url >> data.lineNumber >> data.columnNumber >> data.idString + >> data.objectName >> data.objectType >> data.objectId >> data.contextId; + return ds; +} +struct QDeclarativeObjectProperty { + enum Type { Unknown, Basic, Object, List, SignalProperty }; + Type type; + QString name; + QVariant value; + QString valueTypeName; + QString binding; + bool hasNotifySignal; +}; +QDataStream &operator>>(QDataStream &ds, QDeclarativeObjectProperty &data) +{ + int type; + ds >> type >> data.name >> data.value >> data.valueTypeName + >> data.binding >> data.hasNotifySignal; + data.type = (QDeclarativeObjectProperty::Type)type; + return ds; +} + +void QDeclarativeEngineDebugPrivate::decode(QDataStream &ds, QDeclarativeDebugObjectReference &o, + bool simple) +{ + QDeclarativeObjectData 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(QDeclarativeDebugObjectReference()); + decode(ds, o.m_children.last(), !recur); + } + + int propCount; + ds >> propCount; + + for (int ii = 0; ii < propCount; ++ii) { + QDeclarativeObjectProperty data; + ds >> data; + QDeclarativeDebugPropertyReference 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 QDeclarativeObjectProperty::Basic: + case QDeclarativeObjectProperty::List: + case QDeclarativeObjectProperty::SignalProperty: + { + prop.m_value = data.value; + break; + } + case QDeclarativeObjectProperty::Object: + { + QDeclarativeDebugObjectReference obj; + obj.m_debugId = prop.m_value.toInt(); + prop.m_value = qVariantFromValue(obj); + break; + } + case QDeclarativeObjectProperty::Unknown: + break; + } + o.m_properties << prop; + } +} + +void QDeclarativeEngineDebugPrivate::decode(QDataStream &ds, QDeclarativeDebugContextReference &c) +{ + ds >> c.m_name >> c.m_debugId; + + int contextCount; + ds >> contextCount; + + for (int ii = 0; ii < contextCount; ++ii) { + c.m_contexts.append(QDeclarativeDebugContextReference()); + decode(ds, c.m_contexts.last()); + } + + int objectCount; + ds >> objectCount; + + for (int ii = 0; ii < objectCount; ++ii) { + QDeclarativeDebugObjectReference obj; + decode(ds, obj, true); + + obj.m_contextDebugId = c.m_debugId; + c.m_objects << obj; + } +} + +void QDeclarativeEngineDebugPrivate::message(const QByteArray &data) +{ + QDataStream ds(data); + + QByteArray type; + ds >> type; + + //qDebug() << "QDeclarativeEngineDebugPrivate::message()" << type; + + if (type == "LIST_ENGINES_R") { + int queryId; + ds >> queryId; + + QDeclarativeDebugEnginesQuery *query = enginesQuery.value(queryId); + if (!query) + return; + enginesQuery.remove(queryId); + + int count; + ds >> count; + + for (int ii = 0; ii < count; ++ii) { + QDeclarativeDebugEngineReference ref; + ds >> ref.m_name; + ds >> ref.m_debugId; + query->m_engines << ref; + } + + query->m_client = 0; + query->setState(QDeclarativeDebugQuery::Completed); + } else if (type == "LIST_OBJECTS_R") { + int queryId; + ds >> queryId; + + QDeclarativeDebugRootContextQuery *query = rootContextQuery.value(queryId); + if (!query) + return; + rootContextQuery.remove(queryId); + + if (!ds.atEnd()) + decode(ds, query->m_context); + + query->m_client = 0; + query->setState(QDeclarativeDebugQuery::Completed); + } else if (type == "FETCH_OBJECT_R") { + int queryId; + ds >> queryId; + + QDeclarativeDebugObjectQuery *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(QDeclarativeDebugQuery::Completed); + } else if (type == "EVAL_EXPRESSION_R") { + int queryId; + QVariant result; + ds >> queryId >> result; + + QDeclarativeDebugExpressionQuery *query = expressionQuery.value(queryId); + if (!query) + return; + expressionQuery.remove(queryId); + + query->m_result = result; + query->m_client = 0; + query->setState(QDeclarativeDebugQuery::Completed); + } else if (type == "WATCH_PROPERTY_R") { + int queryId; + bool ok; + ds >> queryId >> ok; + + QDeclarativeDebugWatch *watch = watched.value(queryId); + if (!watch) + return; + + watch->setState(ok ? QDeclarativeDebugWatch::Active : QDeclarativeDebugWatch::Inactive); + } else if (type == "WATCH_OBJECT_R") { + int queryId; + bool ok; + ds >> queryId >> ok; + + QDeclarativeDebugWatch *watch = watched.value(queryId); + if (!watch) + return; + + watch->setState(ok ? QDeclarativeDebugWatch::Active : QDeclarativeDebugWatch::Inactive); + } else if (type == "WATCH_EXPR_OBJECT_R") { + int queryId; + bool ok; + ds >> queryId >> ok; + + QDeclarativeDebugWatch *watch = watched.value(queryId); + if (!watch) + return; + + watch->setState(ok ? QDeclarativeDebugWatch::Active : QDeclarativeDebugWatch::Inactive); + } else if (type == "UPDATE_WATCH") { + int queryId; + int debugId; + QByteArray name; + QVariant value; + ds >> queryId >> debugId >> name >> value; + + QDeclarativeDebugWatch *watch = watched.value(queryId, 0); + if (!watch) + return; + emit watch->valueChanged(name, value); + } +} + +QDeclarativeEngineDebug::QDeclarativeEngineDebug(QDeclarativeDebugConnection *client, QObject *parent) +: QObject(*(new QDeclarativeEngineDebugPrivate(client)), parent) +{ +} + +QDeclarativeDebugPropertyWatch *QDeclarativeEngineDebug::addWatch(const QDeclarativeDebugPropertyReference &property, QObject *parent) +{ + Q_D(QDeclarativeEngineDebug); + + QDeclarativeDebugPropertyWatch *watch = new QDeclarativeDebugPropertyWatch(parent); + if (d->client->isConnected()) { + 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 = QDeclarativeDebugWatch::Dead; + } + + return watch; +} + +QDeclarativeDebugWatch *QDeclarativeEngineDebug::addWatch(const QDeclarativeDebugContextReference &, const QString &, QObject *) +{ + qWarning("QDeclarativeEngineDebug::addWatch(): Not implemented"); + return 0; +} + +QDeclarativeDebugObjectExpressionWatch *QDeclarativeEngineDebug::addWatch(const QDeclarativeDebugObjectReference &object, const QString &expr, QObject *parent) +{ + Q_D(QDeclarativeEngineDebug); + QDeclarativeDebugObjectExpressionWatch *watch = new QDeclarativeDebugObjectExpressionWatch(parent); + if (d->client->isConnected()) { + 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 = QDeclarativeDebugWatch::Dead; + } + return watch; +} + +QDeclarativeDebugWatch *QDeclarativeEngineDebug::addWatch(const QDeclarativeDebugObjectReference &object, QObject *parent) +{ + Q_D(QDeclarativeEngineDebug); + + QDeclarativeDebugWatch *watch = new QDeclarativeDebugWatch(parent); + if (d->client->isConnected()) { + 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 = QDeclarativeDebugWatch::Dead; + } + + return watch; +} + +QDeclarativeDebugWatch *QDeclarativeEngineDebug::addWatch(const QDeclarativeDebugFileReference &, QObject *) +{ + qWarning("QDeclarativeEngineDebug::addWatch(): Not implemented"); + return 0; +} + +void QDeclarativeEngineDebug::removeWatch(QDeclarativeDebugWatch *watch) +{ + Q_D(QDeclarativeEngineDebug); + + if (!watch || !watch->m_client) + return; + + watch->m_client = 0; + watch->setState(QDeclarativeDebugWatch::Inactive); + + d->watched.remove(watch->queryId()); + + if (d->client && d->client->isConnected()) { + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + ds << QByteArray("NO_WATCH") << watch->queryId(); + d->client->sendMessage(message); + } +} + +QDeclarativeDebugEnginesQuery *QDeclarativeEngineDebug::queryAvailableEngines(QObject *parent) +{ + Q_D(QDeclarativeEngineDebug); + + QDeclarativeDebugEnginesQuery *query = new QDeclarativeDebugEnginesQuery(parent); + if (d->client->isConnected()) { + 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 = QDeclarativeDebugQuery::Error; + } + + return query; +} + +QDeclarativeDebugRootContextQuery *QDeclarativeEngineDebug::queryRootContexts(const QDeclarativeDebugEngineReference &engine, QObject *parent) +{ + Q_D(QDeclarativeEngineDebug); + + QDeclarativeDebugRootContextQuery *query = new QDeclarativeDebugRootContextQuery(parent); + if (d->client->isConnected() && 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 = QDeclarativeDebugQuery::Error; + } + + return query; +} + +QDeclarativeDebugObjectQuery *QDeclarativeEngineDebug::queryObject(const QDeclarativeDebugObjectReference &object, QObject *parent) +{ + Q_D(QDeclarativeEngineDebug); + + QDeclarativeDebugObjectQuery *query = new QDeclarativeDebugObjectQuery(parent); + if (d->client->isConnected() && 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; + d->client->sendMessage(message); + } else { + query->m_state = QDeclarativeDebugQuery::Error; + } + + return query; +} + +QDeclarativeDebugObjectQuery *QDeclarativeEngineDebug::queryObjectRecursive(const QDeclarativeDebugObjectReference &object, QObject *parent) +{ + Q_D(QDeclarativeEngineDebug); + + QDeclarativeDebugObjectQuery *query = new QDeclarativeDebugObjectQuery(parent); + if (d->client->isConnected() && 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; + d->client->sendMessage(message); + } else { + query->m_state = QDeclarativeDebugQuery::Error; + } + + return query; +} + +QDeclarativeDebugExpressionQuery *QDeclarativeEngineDebug::queryExpressionResult(int objectDebugId, const QString &expr, QObject *parent) +{ + Q_D(QDeclarativeEngineDebug); + + QDeclarativeDebugExpressionQuery *query = new QDeclarativeDebugExpressionQuery(parent); + if (d->client->isConnected() && objectDebugId != -1) { + query->m_client = this; + query->m_expr = expr; + int queryId = d->getId(); + query->m_queryId = queryId; + d->expressionQuery.insert(queryId, query); + + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + ds << QByteArray("EVAL_EXPRESSION") << queryId << objectDebugId << expr; + d->client->sendMessage(message); + } else { + query->m_state = QDeclarativeDebugQuery::Error; + } + + return query; +} + +bool QDeclarativeEngineDebug::setBindingForObject(int objectDebugId, const QString &propertyName, + const QVariant &bindingExpression, + bool isLiteralValue) +{ + Q_D(QDeclarativeEngineDebug); + + if (d->client->isConnected() && objectDebugId != -1) { + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + ds << QByteArray("SET_BINDING") << objectDebugId << propertyName << bindingExpression << isLiteralValue; + d->client->sendMessage(message); + return true; + } else { + return false; + } +} + +bool QDeclarativeEngineDebug::resetBindingForObject(int objectDebugId, const QString &propertyName) +{ + Q_D(QDeclarativeEngineDebug); + + if (d->client->isConnected() && 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 QDeclarativeEngineDebug::setMethodBody(int objectDebugId, const QString &methodName, + const QString &methodBody) +{ + Q_D(QDeclarativeEngineDebug); + + if (d->client->isConnected() && 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; + } +} + +QDeclarativeDebugWatch::QDeclarativeDebugWatch(QObject *parent) +: QObject(parent), m_state(Waiting), m_queryId(-1), m_client(0), m_objectDebugId(-1) +{ +} + +QDeclarativeDebugWatch::~QDeclarativeDebugWatch() +{ +} + +int QDeclarativeDebugWatch::queryId() const +{ + return m_queryId; +} + +int QDeclarativeDebugWatch::objectDebugId() const +{ + return m_objectDebugId; +} + +QDeclarativeDebugWatch::State QDeclarativeDebugWatch::state() const +{ + return m_state; +} + +void QDeclarativeDebugWatch::setState(State s) +{ + if (m_state == s) + return; + m_state = s; + emit stateChanged(m_state); +} + +QDeclarativeDebugPropertyWatch::QDeclarativeDebugPropertyWatch(QObject *parent) + : QDeclarativeDebugWatch(parent) +{ +} + +QString QDeclarativeDebugPropertyWatch::name() const +{ + return m_name; +} + + +QDeclarativeDebugObjectExpressionWatch::QDeclarativeDebugObjectExpressionWatch(QObject *parent) + : QDeclarativeDebugWatch(parent) +{ +} + +QString QDeclarativeDebugObjectExpressionWatch::expression() const +{ + return m_expr; +} + +QDeclarativeDebugQuery::QDeclarativeDebugQuery(QObject *parent) +: QObject(parent), m_state(Waiting) +{ +} + +QDeclarativeDebugQuery::State QDeclarativeDebugQuery::state() const +{ + return m_state; +} + +bool QDeclarativeDebugQuery::isWaiting() const +{ + return m_state == Waiting; +} + +void QDeclarativeDebugQuery::setState(State s) +{ + if (m_state == s) + return; + m_state = s; + emit stateChanged(m_state); +} + +QDeclarativeDebugEnginesQuery::QDeclarativeDebugEnginesQuery(QObject *parent) +: QDeclarativeDebugQuery(parent), m_client(0), m_queryId(-1) +{ +} + +QDeclarativeDebugEnginesQuery::~QDeclarativeDebugEnginesQuery() +{ + if (m_client && m_queryId != -1) + QDeclarativeEngineDebugPrivate::remove(m_client, this); +} + +QList<QDeclarativeDebugEngineReference> QDeclarativeDebugEnginesQuery::engines() const +{ + return m_engines; +} + +QDeclarativeDebugRootContextQuery::QDeclarativeDebugRootContextQuery(QObject *parent) +: QDeclarativeDebugQuery(parent), m_client(0), m_queryId(-1) +{ +} + +QDeclarativeDebugRootContextQuery::~QDeclarativeDebugRootContextQuery() +{ + if (m_client && m_queryId != -1) + QDeclarativeEngineDebugPrivate::remove(m_client, this); +} + +QDeclarativeDebugContextReference QDeclarativeDebugRootContextQuery::rootContext() const +{ + return m_context; +} + +QDeclarativeDebugObjectQuery::QDeclarativeDebugObjectQuery(QObject *parent) +: QDeclarativeDebugQuery(parent), m_client(0), m_queryId(-1) +{ +} + +QDeclarativeDebugObjectQuery::~QDeclarativeDebugObjectQuery() +{ + if (m_client && m_queryId != -1) + QDeclarativeEngineDebugPrivate::remove(m_client, this); +} + +QDeclarativeDebugObjectReference QDeclarativeDebugObjectQuery::object() const +{ + return m_object; +} + +QDeclarativeDebugExpressionQuery::QDeclarativeDebugExpressionQuery(QObject *parent) +: QDeclarativeDebugQuery(parent), m_client(0), m_queryId(-1) +{ +} + +QDeclarativeDebugExpressionQuery::~QDeclarativeDebugExpressionQuery() +{ + if (m_client && m_queryId != -1) + QDeclarativeEngineDebugPrivate::remove(m_client, this); +} + +QVariant QDeclarativeDebugExpressionQuery::expression() const +{ + return m_expr; +} + +QVariant QDeclarativeDebugExpressionQuery::result() const +{ + return m_result; +} + +QDeclarativeDebugEngineReference::QDeclarativeDebugEngineReference() +: m_debugId(-1) +{ +} + +QDeclarativeDebugEngineReference::QDeclarativeDebugEngineReference(int debugId) +: m_debugId(debugId) +{ +} + +QDeclarativeDebugEngineReference::QDeclarativeDebugEngineReference(const QDeclarativeDebugEngineReference &o) +: m_debugId(o.m_debugId), m_name(o.m_name) +{ +} + +QDeclarativeDebugEngineReference & +QDeclarativeDebugEngineReference::operator=(const QDeclarativeDebugEngineReference &o) +{ + m_debugId = o.m_debugId; m_name = o.m_name; + return *this; +} + +int QDeclarativeDebugEngineReference::debugId() const +{ + return m_debugId; +} + +QString QDeclarativeDebugEngineReference::name() const +{ + return m_name; +} + +QDeclarativeDebugObjectReference::QDeclarativeDebugObjectReference() +: m_debugId(-1), m_contextDebugId(-1) +{ +} + +QDeclarativeDebugObjectReference::QDeclarativeDebugObjectReference(int debugId) +: m_debugId(debugId), m_contextDebugId(-1) +{ +} + +QDeclarativeDebugObjectReference::QDeclarativeDebugObjectReference(const QDeclarativeDebugObjectReference &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) +{ +} + +QDeclarativeDebugObjectReference & +QDeclarativeDebugObjectReference::operator=(const QDeclarativeDebugObjectReference &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 QDeclarativeDebugObjectReference::debugId() const +{ + return m_debugId; +} + +QString QDeclarativeDebugObjectReference::className() const +{ + return m_class; +} + +QString QDeclarativeDebugObjectReference::idString() const +{ + return m_idString; +} + +QString QDeclarativeDebugObjectReference::name() const +{ + return m_name; +} + +QDeclarativeDebugFileReference QDeclarativeDebugObjectReference::source() const +{ + return m_source; +} + +int QDeclarativeDebugObjectReference::contextDebugId() const +{ + return m_contextDebugId; +} + +QList<QDeclarativeDebugPropertyReference> QDeclarativeDebugObjectReference::properties() const +{ + return m_properties; +} + +QList<QDeclarativeDebugObjectReference> QDeclarativeDebugObjectReference::children() const +{ + return m_children; +} + +QDeclarativeDebugContextReference::QDeclarativeDebugContextReference() +: m_debugId(-1) +{ +} + +QDeclarativeDebugContextReference::QDeclarativeDebugContextReference(const QDeclarativeDebugContextReference &o) +: m_debugId(o.m_debugId), m_name(o.m_name), m_objects(o.m_objects), m_contexts(o.m_contexts) +{ +} + +QDeclarativeDebugContextReference &QDeclarativeDebugContextReference::operator=(const QDeclarativeDebugContextReference &o) +{ + m_debugId = o.m_debugId; m_name = o.m_name; m_objects = o.m_objects; + m_contexts = o.m_contexts; + return *this; +} + +int QDeclarativeDebugContextReference::debugId() const +{ + return m_debugId; +} + +QString QDeclarativeDebugContextReference::name() const +{ + return m_name; +} + +QList<QDeclarativeDebugObjectReference> QDeclarativeDebugContextReference::objects() const +{ + return m_objects; +} + +QList<QDeclarativeDebugContextReference> QDeclarativeDebugContextReference::contexts() const +{ + return m_contexts; +} + +QDeclarativeDebugFileReference::QDeclarativeDebugFileReference() +: m_lineNumber(-1), m_columnNumber(-1) +{ +} + +QDeclarativeDebugFileReference::QDeclarativeDebugFileReference(const QDeclarativeDebugFileReference &o) +: m_url(o.m_url), m_lineNumber(o.m_lineNumber), m_columnNumber(o.m_columnNumber) +{ +} + +QDeclarativeDebugFileReference &QDeclarativeDebugFileReference::operator=(const QDeclarativeDebugFileReference &o) +{ + m_url = o.m_url; m_lineNumber = o.m_lineNumber; m_columnNumber = o.m_columnNumber; + return *this; +} + +QUrl QDeclarativeDebugFileReference::url() const +{ + return m_url; +} + +void QDeclarativeDebugFileReference::setUrl(const QUrl &u) +{ + m_url = u; +} + +int QDeclarativeDebugFileReference::lineNumber() const +{ + return m_lineNumber; +} + +void QDeclarativeDebugFileReference::setLineNumber(int l) +{ + m_lineNumber = l; +} + +int QDeclarativeDebugFileReference::columnNumber() const +{ + return m_columnNumber; +} + +void QDeclarativeDebugFileReference::setColumnNumber(int c) +{ + m_columnNumber = c; +} + +QDeclarativeDebugPropertyReference::QDeclarativeDebugPropertyReference() +: m_objectDebugId(-1), m_hasNotifySignal(false) +{ +} + +QDeclarativeDebugPropertyReference::QDeclarativeDebugPropertyReference(const QDeclarativeDebugPropertyReference &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) +{ +} + +QDeclarativeDebugPropertyReference &QDeclarativeDebugPropertyReference::operator=(const QDeclarativeDebugPropertyReference &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 QDeclarativeDebugPropertyReference::objectDebugId() const +{ + return m_objectDebugId; +} + +QString QDeclarativeDebugPropertyReference::name() const +{ + return m_name; +} + +QString QDeclarativeDebugPropertyReference::valueTypeName() const +{ + return m_valueTypeName; +} + +QVariant QDeclarativeDebugPropertyReference::value() const +{ + return m_value; +} + +QString QDeclarativeDebugPropertyReference::binding() const +{ + return m_binding; +} + +bool QDeclarativeDebugPropertyReference::hasNotifySignal() const +{ + return m_hasNotifySignal; +} + +} + diff --git a/src/libs/qmljsdebugclient/qdeclarativedebug_p.h b/src/libs/qmljsdebugclient/qdeclarativedebug_p.h new file mode 100644 index 0000000000..2da1dea8a0 --- /dev/null +++ b/src/libs/qmljsdebugclient/qdeclarativedebug_p.h @@ -0,0 +1,377 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QDECLARATIVEDEBUG_H +#define QDECLARATIVEDEBUG_H + +#include <QtCore/qobject.h> +#include <QtCore/qurl.h> +#include <QtCore/qvariant.h> + +QT_BEGIN_HEADER + +namespace QmlJsDebugClient { + +class QDeclarativeDebugConnection; +class QDeclarativeDebugWatch; +class QDeclarativeDebugPropertyWatch; +class QDeclarativeDebugObjectExpressionWatch; +class QDeclarativeDebugEnginesQuery; +class QDeclarativeDebugRootContextQuery; +class QDeclarativeDebugObjectQuery; +class QDeclarativeDebugExpressionQuery; +class QDeclarativeDebugPropertyReference; +class QDeclarativeDebugContextReference; +class QDeclarativeDebugObjectReference; +class QDeclarativeDebugFileReference; +class QDeclarativeDebugEngineReference; +class QDeclarativeEngineDebugPrivate; +class QDeclarativeEngineDebug; + +class QDeclarativeEngineDebug : public QObject +{ +Q_OBJECT +public: + QDeclarativeEngineDebug(QDeclarativeDebugConnection *, QObject * = 0); + + QDeclarativeDebugPropertyWatch *addWatch(const QDeclarativeDebugPropertyReference &, + QObject *parent = 0); + QDeclarativeDebugWatch *addWatch(const QDeclarativeDebugContextReference &, const QString &, + QObject *parent = 0); + QDeclarativeDebugObjectExpressionWatch *addWatch(const QDeclarativeDebugObjectReference &, const QString &, + QObject *parent = 0); + QDeclarativeDebugWatch *addWatch(const QDeclarativeDebugObjectReference &, + QObject *parent = 0); + QDeclarativeDebugWatch *addWatch(const QDeclarativeDebugFileReference &, + QObject *parent = 0); + + void removeWatch(QDeclarativeDebugWatch *watch); + + QDeclarativeDebugEnginesQuery *queryAvailableEngines(QObject *parent = 0); + QDeclarativeDebugRootContextQuery *queryRootContexts(const QDeclarativeDebugEngineReference &, + QObject *parent = 0); + QDeclarativeDebugObjectQuery *queryObject(const QDeclarativeDebugObjectReference &, + QObject *parent = 0); + QDeclarativeDebugObjectQuery *queryObjectRecursive(const QDeclarativeDebugObjectReference &, + QObject *parent = 0); + QDeclarativeDebugExpressionQuery *queryExpressionResult(int objectDebugId, + const QString &expr, + QObject *parent = 0); + bool setBindingForObject(int objectDebugId, const QString &propertyName, + const QVariant &bindingExpression, bool isLiteralValue); + bool resetBindingForObject(int objectDebugId, const QString &propertyName); + bool setMethodBody(int objectDebugId, const QString &methodName, const QString &methodBody); + +private: + Q_DECLARE_PRIVATE(QDeclarativeEngineDebug) +}; + + +class QDeclarativeDebugWatch : public QObject +{ +Q_OBJECT +public: + enum State { Waiting, Active, Inactive, Dead }; + + QDeclarativeDebugWatch(QObject *); + ~QDeclarativeDebugWatch(); + + int queryId() const; + int objectDebugId() const; + State state() const; + +Q_SIGNALS: + void stateChanged(QDeclarativeDebugWatch::State); + //void objectChanged(int, const QDeclarativeDebugObjectReference &); + //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 QDeclarativeEngineDebug; + friend class QDeclarativeEngineDebugPrivate; + void setState(State); + State m_state; + int m_queryId; + QDeclarativeEngineDebug *m_client; + int m_objectDebugId; +}; + +class QDeclarativeDebugPropertyWatch : public QDeclarativeDebugWatch +{ + Q_OBJECT +public: + QDeclarativeDebugPropertyWatch(QObject *parent); + + QString name() const; + +private: + friend class QDeclarativeEngineDebug; + QString m_name; +}; + +class QDeclarativeDebugObjectExpressionWatch : public QDeclarativeDebugWatch +{ + Q_OBJECT +public: + QDeclarativeDebugObjectExpressionWatch(QObject *parent); + + QString expression() const; + +private: + friend class QDeclarativeEngineDebug; + QString m_expr; + int m_debugId; +}; + +class QDeclarativeDebugQuery : public QObject +{ +Q_OBJECT +public: + enum State { Waiting, Error, Completed }; + + State state() const; + bool isWaiting() const; + +// bool waitUntilCompleted(); + +Q_SIGNALS: + void stateChanged(QDeclarativeDebugQuery::State); + +protected: + QDeclarativeDebugQuery(QObject *); + +private: + friend class QDeclarativeEngineDebug; + friend class QDeclarativeEngineDebugPrivate; + void setState(State); + State m_state; +}; + +class QDeclarativeDebugFileReference +{ +public: + QDeclarativeDebugFileReference(); + QDeclarativeDebugFileReference(const QDeclarativeDebugFileReference &); + QDeclarativeDebugFileReference &operator=(const QDeclarativeDebugFileReference &); + + QUrl url() const; + void setUrl(const QUrl &); + int lineNumber() const; + void setLineNumber(int); + int columnNumber() const; + void setColumnNumber(int); + +private: + friend class QDeclarativeEngineDebugPrivate; + QUrl m_url; + int m_lineNumber; + int m_columnNumber; +}; + +class QDeclarativeDebugEngineReference +{ +public: + QDeclarativeDebugEngineReference(); + QDeclarativeDebugEngineReference(int); + QDeclarativeDebugEngineReference(const QDeclarativeDebugEngineReference &); + QDeclarativeDebugEngineReference &operator=(const QDeclarativeDebugEngineReference &); + + int debugId() const; + QString name() const; + +private: + friend class QDeclarativeEngineDebugPrivate; + int m_debugId; + QString m_name; +}; + +class QDeclarativeDebugObjectReference +{ +public: + QDeclarativeDebugObjectReference(); + QDeclarativeDebugObjectReference(int); + QDeclarativeDebugObjectReference(const QDeclarativeDebugObjectReference &); + QDeclarativeDebugObjectReference &operator=(const QDeclarativeDebugObjectReference &); + + int debugId() const; + QString className() const; + QString idString() const; + QString name() const; + + QDeclarativeDebugFileReference source() const; + int contextDebugId() const; + + QList<QDeclarativeDebugPropertyReference> properties() const; + QList<QDeclarativeDebugObjectReference> children() const; + +private: + friend class QDeclarativeEngineDebugPrivate; + int m_debugId; + QString m_class; + QString m_idString; + QString m_name; + QDeclarativeDebugFileReference m_source; + int m_contextDebugId; + QList<QDeclarativeDebugPropertyReference> m_properties; + QList<QDeclarativeDebugObjectReference> m_children; +}; + +class QDeclarativeDebugContextReference +{ +public: + QDeclarativeDebugContextReference(); + QDeclarativeDebugContextReference(const QDeclarativeDebugContextReference &); + QDeclarativeDebugContextReference &operator=(const QDeclarativeDebugContextReference &); + + int debugId() const; + QString name() const; + + QList<QDeclarativeDebugObjectReference> objects() const; + QList<QDeclarativeDebugContextReference> contexts() const; + +private: + friend class QDeclarativeEngineDebugPrivate; + int m_debugId; + QString m_name; + QList<QDeclarativeDebugObjectReference> m_objects; + QList<QDeclarativeDebugContextReference> m_contexts; +}; + +class QDeclarativeDebugPropertyReference +{ +public: + QDeclarativeDebugPropertyReference(); + QDeclarativeDebugPropertyReference(const QDeclarativeDebugPropertyReference &); + QDeclarativeDebugPropertyReference &operator=(const QDeclarativeDebugPropertyReference &); + + int objectDebugId() const; + QString name() const; + QVariant value() const; + QString valueTypeName() const; + QString binding() const; + bool hasNotifySignal() const; + +private: + friend class QDeclarativeEngineDebugPrivate; + int m_objectDebugId; + QString m_name; + QVariant m_value; + QString m_valueTypeName; + QString m_binding; + bool m_hasNotifySignal; +}; + + +class QDeclarativeDebugEnginesQuery : public QDeclarativeDebugQuery +{ +Q_OBJECT +public: + virtual ~QDeclarativeDebugEnginesQuery(); + QList<QDeclarativeDebugEngineReference> engines() const; +private: + friend class QDeclarativeEngineDebug; + friend class QDeclarativeEngineDebugPrivate; + QDeclarativeDebugEnginesQuery(QObject *); + QDeclarativeEngineDebug *m_client; + int m_queryId; + QList<QDeclarativeDebugEngineReference> m_engines; +}; + +class QDeclarativeDebugRootContextQuery : public QDeclarativeDebugQuery +{ +Q_OBJECT +public: + virtual ~QDeclarativeDebugRootContextQuery(); + QDeclarativeDebugContextReference rootContext() const; +private: + friend class QDeclarativeEngineDebug; + friend class QDeclarativeEngineDebugPrivate; + QDeclarativeDebugRootContextQuery(QObject *); + QDeclarativeEngineDebug *m_client; + int m_queryId; + QDeclarativeDebugContextReference m_context; +}; + +class QDeclarativeDebugObjectQuery : public QDeclarativeDebugQuery +{ +Q_OBJECT +public: + virtual ~QDeclarativeDebugObjectQuery(); + QDeclarativeDebugObjectReference object() const; +private: + friend class QDeclarativeEngineDebug; + friend class QDeclarativeEngineDebugPrivate; + QDeclarativeDebugObjectQuery(QObject *); + QDeclarativeEngineDebug *m_client; + int m_queryId; + QDeclarativeDebugObjectReference m_object; + +}; + +class QDeclarativeDebugExpressionQuery : public QDeclarativeDebugQuery +{ +Q_OBJECT +public: + virtual ~QDeclarativeDebugExpressionQuery(); + QVariant expression() const; + QVariant result() const; +private: + friend class QDeclarativeEngineDebug; + friend class QDeclarativeEngineDebugPrivate; + QDeclarativeDebugExpressionQuery(QObject *); + QDeclarativeEngineDebug *m_client; + int m_queryId; + QVariant m_expr; + QVariant m_result; + +}; + +} + +Q_DECLARE_METATYPE(QmlJsDebugClient::QDeclarativeDebugEngineReference) +Q_DECLARE_METATYPE(QmlJsDebugClient::QDeclarativeDebugObjectReference) +Q_DECLARE_METATYPE(QmlJsDebugClient::QDeclarativeDebugContextReference) +Q_DECLARE_METATYPE(QmlJsDebugClient::QDeclarativeDebugPropertyReference) + +QT_END_HEADER + +#endif // QDECLARATIVEDEBUG_H diff --git a/src/libs/qmljsdebugclient/qdeclarativedebugclient.cpp b/src/libs/qmljsdebugclient/qdeclarativedebugclient.cpp new file mode 100644 index 0000000000..7fa4ef3004 --- /dev/null +++ b/src/libs/qmljsdebugclient/qdeclarativedebugclient.cpp @@ -0,0 +1,198 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdeclarativedebugclient_p.h" + +#include "qpacketprotocol_p.h" + +#include <QtCore/qdebug.h> +#include <QtCore/qstringlist.h> + +namespace QmlJsDebugClient { + +class QDeclarativeDebugConnectionPrivate : public QObject +{ + Q_OBJECT +public: + QDeclarativeDebugConnectionPrivate(QDeclarativeDebugConnection *c); + QDeclarativeDebugConnection *q; + QPacketProtocol *protocol; + + QStringList enabled; + QHash<QString, QDeclarativeDebugClient *> plugins; +public Q_SLOTS: + void connected(); + void readyRead(); +}; + +QDeclarativeDebugConnectionPrivate::QDeclarativeDebugConnectionPrivate(QDeclarativeDebugConnection *c) +: QObject(c), q(c), protocol(0) +{ + protocol = new QPacketProtocol(q, this); + QObject::connect(c, SIGNAL(connected()), this, SLOT(connected())); + QObject::connect(protocol, SIGNAL(readyRead()), this, SLOT(readyRead())); +} + +void QDeclarativeDebugConnectionPrivate::connected() +{ + QPacket pack; + pack << QString(QLatin1String("QDeclarativeDebugServer")) << enabled; + protocol->send(pack); +} + +void QDeclarativeDebugConnectionPrivate::readyRead() +{ + QPacket pack = protocol->read(); + QString name; QByteArray message; + pack >> name >> message; + + QHash<QString, QDeclarativeDebugClient *>::Iterator iter = + plugins.find(name); + if (iter == plugins.end()) { + qWarning() << "QDeclarativeDebugConnection: Message received for missing plugin" << name; + } else { + (*iter)->messageReceived(message); + } +} + +QDeclarativeDebugConnection::QDeclarativeDebugConnection(QObject *parent) +: QTcpSocket(parent), d(new QDeclarativeDebugConnectionPrivate(this)) +{ +} + +bool QDeclarativeDebugConnection::isConnected() const +{ + return state() == ConnectedState; +} + +class QDeclarativeDebugClientPrivate +{ +public: + QDeclarativeDebugClientPrivate(); + + QString name; + QDeclarativeDebugConnection *client; + bool enabled; +}; + +QDeclarativeDebugClientPrivate::QDeclarativeDebugClientPrivate() +: client(0), enabled(false) +{ +} + +QDeclarativeDebugClient::QDeclarativeDebugClient(const QString &name, + QDeclarativeDebugConnection *parent) + : QObject(parent), d(new QDeclarativeDebugClientPrivate) +{ + d->name = name; + d->client = parent; + + if (!d->client) + return; + + if (d->client->d->plugins.contains(name)) { + qWarning() << "QDeclarativeDebugClient: Conflicting plugin name" << name; + d->client = 0; + } else { + d->client->d->plugins.insert(name, this); + } +} + +QDeclarativeDebugClient::~QDeclarativeDebugClient() {} + +QString QDeclarativeDebugClient::name() const +{ + return d->name; +} + +bool QDeclarativeDebugClient::isEnabled() const +{ + return d->enabled; +} + +void QDeclarativeDebugClient::setEnabled(bool e) +{ + if (e == d->enabled) + return; + + d->enabled = e; + + if (d->client) { + if (e) + d->client->d->enabled.append(d->name); + else + d->client->d->enabled.removeAll(d->name); + + if (d->client->state() == QTcpSocket::ConnectedState) { + QPacket pack; + pack << QString(QLatin1String("QDeclarativeDebugServer")); + if (e) pack << (int)1; + else pack << (int)2; + pack << d->name; + d->client->d->protocol->send(pack); + } + } +} + +bool QDeclarativeDebugClient::isConnected() const +{ + if (!d->client) + return false; + return d->client->isConnected(); +} + +void QDeclarativeDebugClient::sendMessage(const QByteArray &message) +{ + if (!d->client || !d->client->isConnected()) + return; + + QPacket pack; + pack << d->name << message; + d->client->d->protocol->send(pack); +} + +void QDeclarativeDebugClient::messageReceived(const QByteArray &) +{ +} + +} + +#include <qdeclarativedebugclient.moc> diff --git a/src/libs/qmljsdebugclient/qdeclarativedebugclient_p.h b/src/libs/qmljsdebugclient/qdeclarativedebugclient_p.h new file mode 100644 index 0000000000..ffc3b0d844 --- /dev/null +++ b/src/libs/qmljsdebugclient/qdeclarativedebugclient_p.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVEDEBUGCLIENT_H +#define QDECLARATIVEDEBUGCLIENT_H + +#include <QtNetwork/qtcpsocket.h> + +QT_BEGIN_HEADER + +namespace QmlJsDebugClient { + +class QDeclarativeDebugConnectionPrivate; +class QDeclarativeDebugConnection : public QTcpSocket +{ + Q_OBJECT + Q_DISABLE_COPY(QDeclarativeDebugConnection) +public: + QDeclarativeDebugConnection(QObject * = 0); + + bool isConnected() const; +private: + QDeclarativeDebugConnectionPrivate *d; + friend class QDeclarativeDebugClient; + friend class QDeclarativeDebugClientPrivate; +}; + +class QDeclarativeDebugClientPrivate; +class QDeclarativeDebugClient : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QDeclarativeDebugClient) + Q_DISABLE_COPY(QDeclarativeDebugClient) + +public: + QDeclarativeDebugClient(const QString &, QDeclarativeDebugConnection *parent); + ~QDeclarativeDebugClient(); + + QString name() const; + + bool isEnabled() const; + void setEnabled(bool); + + bool isConnected() const; + + void sendMessage(const QByteArray &); + +protected: + virtual void messageReceived(const QByteArray &); + +private: + friend class QDeclarativeDebugConnection; + friend class QDeclarativeDebugConnectionPrivate; + QScopedPointer<QDeclarativeDebugClientPrivate> d; +}; + +} + +QT_END_HEADER + +#endif // QDECLARATIVEDEBUGCLIENT_H diff --git a/src/libs/qmljsdebugclient/qmljsdebugclient-lib.pri b/src/libs/qmljsdebugclient/qmljsdebugclient-lib.pri new file mode 100644 index 0000000000..3fbd99cf98 --- /dev/null +++ b/src/libs/qmljsdebugclient/qmljsdebugclient-lib.pri @@ -0,0 +1,15 @@ + +## Input +HEADERS += \ +../../libs/qmljsdebugclient/qdeclarativedebug_p.h \ +../../libs/qmljsdebugclient/qpacketprotocol_p.h \ +../../libs/qmljsdebugclient/qdeclarativedebugclient_p.h + + +SOURCES += \ +../../libs/qmljsdebugclient/qdeclarativedebug.cpp \ +../../libs/qmljsdebugclient/qpacketprotocol.cpp \ +../../libs/qmljsdebugclient/qdeclarativedebugclient.cpp + + + diff --git a/src/libs/qmljsdebugclient/qpacketprotocol.cpp b/src/libs/qmljsdebugclient/qpacketprotocol.cpp new file mode 100644 index 0000000000..270a67c9ba --- /dev/null +++ b/src/libs/qmljsdebugclient/qpacketprotocol.cpp @@ -0,0 +1,498 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qpacketprotocol_p.h" + +#include <QBuffer> + +namespace QmlJsDebugClient { + +#define MAX_PACKET_SIZE 0x7FFFFFFF + +/*! + \class QPacketProtocol + \internal + + \brief The QPacketProtocol class encapsulates communicating discrete packets + across fragmented IO channels, such as TCP sockets. + + QPacketProtocol makes it simple to send arbitrary sized data "packets" across + fragmented transports such as TCP and UDP. + + As transmission boundaries are not respected, sending packets over protocols + like TCP frequently involves "stitching" them back together at the receiver. + QPacketProtocol makes this easier by performing this task for you. Packet + data sent using QPacketProtocol is prepended with a 4-byte size header + allowing the receiving QPacketProtocol to buffer the packet internally until + it has all been received. QPacketProtocol does not perform any sanity + checking on the size or on the data, so this class should only be used in + prototyping or trusted situations where DOS attacks are unlikely. + + QPacketProtocol does not perform any communications itself. Instead it can + operate on any QIODevice that supports the QIODevice::readyRead() signal. A + logical "packet" is encapsulated by the companion QPacket class. The + following example shows two ways to send data using QPacketProtocol. The + transmitted data is equivalent in both. + + \code + QTcpSocket socket; + // ... connect socket ... + + QPacketProtocol protocol(&socket); + + // Send packet the quick way + protocol.send() << "Hello world" << 123; + + // Send packet the longer way + QPacket packet; + packet << "Hello world" << 123; + protocol.send(packet); + \endcode + + Likewise, the following shows how to read data from QPacketProtocol, assuming + that the QPacketProtocol::readyRead() signal has been emitted. + + \code + // ... QPacketProtocol::readyRead() is emitted ... + + int a; + QByteArray b; + + // Receive packet the quick way + protocol.read() >> a >> b; + + // Receive packet the longer way + QPacket packet = protocol.read(); + p >> a >> b; + \endcode + + \ingroup io + \sa QPacket +*/ + +class QPacketProtocolPrivate : public QObject +{ +Q_OBJECT +public: + QPacketProtocolPrivate(QPacketProtocol * parent, QIODevice * _dev) + : QObject(parent), inProgressSize(-1), maxPacketSize(MAX_PACKET_SIZE), + dev(_dev) + { + Q_ASSERT(4 == sizeof(qint32)); + + QObject::connect(this, SIGNAL(readyRead()), + parent, SIGNAL(readyRead())); + QObject::connect(this, SIGNAL(packetWritten()), + parent, SIGNAL(packetWritten())); + QObject::connect(this, SIGNAL(invalidPacket()), + parent, SIGNAL(invalidPacket())); + QObject::connect(dev, SIGNAL(readyRead()), + this, SLOT(readyToRead())); + QObject::connect(dev, SIGNAL(aboutToClose()), + this, SLOT(aboutToClose())); + QObject::connect(dev, SIGNAL(bytesWritten(qint64)), + this, SLOT(bytesWritten(qint64))); + } + +Q_SIGNALS: + void readyRead(); + void packetWritten(); + void invalidPacket(); + +public Q_SLOTS: + void aboutToClose() + { + inProgress.clear(); + sendingPackets.clear(); + inProgressSize = -1; + } + + void bytesWritten(qint64 bytes) + { + Q_ASSERT(!sendingPackets.isEmpty()); + + while(bytes) { + if(sendingPackets.at(0) > bytes) { + sendingPackets[0] -= bytes; + bytes = 0; + } else { + bytes -= sendingPackets.at(0); + sendingPackets.removeFirst(); + emit packetWritten(); + } + } + } + + void readyToRead() + { + if(-1 == inProgressSize) { + // We need a size header of sizeof(qint32) + if(sizeof(qint32) > (uint)dev->bytesAvailable()) + return; + + // Read size header + int read = dev->read((char *)&inProgressSize, sizeof(qint32)); + Q_ASSERT(read == sizeof(qint32)); + Q_UNUSED(read); + + // Check sizing constraints + if(inProgressSize > maxPacketSize) { + QObject::disconnect(dev, SIGNAL(readyRead()), + this, SLOT(readyToRead())); + QObject::disconnect(dev, SIGNAL(aboutToClose()), + this, SLOT(aboutToClose())); + QObject::disconnect(dev, SIGNAL(bytesWritten(qint64)), + this, SLOT(bytesWritten(qint64))); + dev = 0; + emit invalidPacket(); + return; + } + + inProgressSize -= sizeof(qint32); + + // Need to get trailing data + readyToRead(); + } else { + inProgress.append(dev->read(inProgressSize - inProgress.size())); + + if(inProgressSize == inProgress.size()) { + // Packet has arrived! + packets.append(inProgress); + inProgressSize = -1; + inProgress.clear(); + + emit readyRead(); + + // Need to get trailing data + readyToRead(); + } + } + } + +public: + QList<qint64> sendingPackets; + QList<QByteArray> packets; + QByteArray inProgress; + qint32 inProgressSize; + qint32 maxPacketSize; + QIODevice * dev; +}; + +/*! + Construct a QPacketProtocol instance that works on \a dev with the + specified \a parent. + */ +QPacketProtocol::QPacketProtocol(QIODevice * dev, QObject * parent) +: QObject(parent), d(new QPacketProtocolPrivate(this, dev)) +{ + Q_ASSERT(dev); +} + +/*! + Destroys the QPacketProtocol instance. + */ +QPacketProtocol::~QPacketProtocol() +{ +} + +/*! + Returns the maximum packet size allowed. By default this is + 2,147,483,647 bytes. + + If a packet claiming to be larger than the maximum packet size is received, + the QPacketProtocol::invalidPacket() signal is emitted. + + \sa QPacketProtocol::setMaximumPacketSize() + */ +qint32 QPacketProtocol::maximumPacketSize() const +{ + return d->maxPacketSize; +} + +/*! + Sets the maximum allowable packet size to \a max. + + \sa QPacketProtocol::maximumPacketSize() + */ +qint32 QPacketProtocol::setMaximumPacketSize(qint32 max) +{ + if(max > (signed)sizeof(qint32)) + d->maxPacketSize = max; + return d->maxPacketSize; +} + +/*! + Returns a streamable object that is transmitted on destruction. For example + + \code + protocol.send() << "Hello world" << 123; + \endcode + + will send a packet containing "Hello world" and 123. To construct more + complex packets, explicitly construct a QPacket instance. + */ +QPacketAutoSend QPacketProtocol::send() +{ + return QPacketAutoSend(this); +} + +/*! + \fn void QPacketProtocol::send(const QPacket & packet) + + Transmit the \a packet. + */ +void QPacketProtocol::send(const QPacket & p) +{ + if(p.b.isEmpty()) + return; // We don't send empty packets + + qint64 sendSize = p.b.size() + sizeof(qint32); + + d->sendingPackets.append(sendSize); + qint32 sendSize32 = sendSize; + qint64 writeBytes = d->dev->write((char *)&sendSize32, sizeof(qint32)); + Q_ASSERT(writeBytes == sizeof(qint32)); + writeBytes = d->dev->write(p.b); + Q_ASSERT(writeBytes == p.b.size()); +} + +/*! + Returns the number of received packets yet to be read. + */ +qint64 QPacketProtocol::packetsAvailable() const +{ + return d->packets.count(); +} + +/*! + Discard any unread packets. + */ +void QPacketProtocol::clear() +{ + d->packets.clear(); +} + +/*! + Return the next unread packet, or an invalid QPacket instance if no packets + are available. This method does NOT block. + */ +QPacket QPacketProtocol::read() +{ + if(0 == d->packets.count()) + return QPacket(); + + QPacket rv(d->packets.at(0)); + d->packets.removeFirst(); + return rv; +} + +/*! + Return the QIODevice passed to the QPacketProtocol constructor. +*/ +QIODevice * QPacketProtocol::device() +{ + return d->dev; +} + +/*! + \fn void QPacketProtocol::readyRead() + + Emitted whenever a new packet is received. Applications may use + QPacketProtocol::read() to retrieve this packet. + */ + +/*! + \fn void QPacketProtocol::invalidPacket() + + A packet larger than the maximum allowable packet size was received. The + packet will be discarded and, as it indicates corruption in the protocol, no + further packets will be received. + */ + +/*! + \fn void QPacketProtocol::packetWritten() + + Emitted each time a packet is completing written to the device. This signal + may be used for communications flow control. + */ + +/*! + \class QPacket + \internal + + \brief The QPacket class encapsulates an unfragmentable packet of data to be + transmitted by QPacketProtocol. + + The QPacket class works together with QPacketProtocol to make it simple to + send arbitrary sized data "packets" across fragmented transports such as TCP + and UDP. + + QPacket provides a QDataStream interface to an unfragmentable packet. + Applications should construct a QPacket, propagate it with data and then + transmit it over a QPacketProtocol instance. For example: + \code + QPacketProtocol protocol(...); + + QPacket myPacket; + myPacket << "Hello world!" << 123; + protocol.send(myPacket); + \endcode + + As long as both ends of the connection are using the QPacketProtocol class, + the data within this packet will be delivered unfragmented at the other end, + ready for extraction. + + \code + QByteArray greeting; + int count; + + QPacket myPacket = protocol.read(); + + myPacket >> greeting >> count; + \endcode + + Only packets returned from QPacketProtocol::read() may be read from. QPacket + instances constructed by directly by applications are for transmission only + and are considered "write only". Attempting to read data from them will + result in undefined behavior. + + \ingroup io + \sa QPacketProtocol + */ + +/*! + Constructs an empty write-only packet. + */ +QPacket::QPacket() +: QDataStream(), buf(0) +{ + buf = new QBuffer(&b); + buf->open(QIODevice::WriteOnly); + setDevice(buf); +} + +/*! + Destroys the QPacket instance. + */ +QPacket::~QPacket() +{ + if(buf) { + delete buf; + buf = 0; + } +} + +/*! + Creates a copy of \a other. The initial stream positions are shared, but the + two packets are otherwise independant. + */ +QPacket::QPacket(const QPacket & other) +: QDataStream(), b(other.b), buf(0) +{ + buf = new QBuffer(&b); + buf->open(other.buf->openMode()); + setDevice(buf); +} + +/*! + \internal + */ +QPacket::QPacket(const QByteArray & ba) +: QDataStream(), b(ba), buf(0) +{ + buf = new QBuffer(&b); + buf->open(QIODevice::ReadOnly); + setDevice(buf); +} + +/*! + Returns true if this packet is empty - that is, contains no data. + */ +bool QPacket::isEmpty() const +{ + return b.isEmpty(); +} + +/*! + Clears data in the packet. This is useful for reusing one writable packet. + For example + \code + QPacketProtocol protocol(...); + + QPacket packet; + + packet << "Hello world!" << 123; + protocol.send(packet); + + packet.clear(); + packet << "Goodbyte world!" << 789; + protocol.send(packet); + \endcode + */ +void QPacket::clear() +{ + QBuffer::OpenMode oldMode = buf->openMode(); + buf->close(); + b.clear(); + buf->setBuffer(&b); // reset QBuffer internals with new size of b. + buf->open(oldMode); +} + +/*! + \class QPacketAutoSend + \internal + + \internal + */ +QPacketAutoSend::QPacketAutoSend(QPacketProtocol * _p) +: QPacket(), p(_p) +{ +} + +QPacketAutoSend::~QPacketAutoSend() +{ + if(!b.isEmpty()) + p->send(*this); +} + +} + +#include <qpacketprotocol.moc> diff --git a/src/libs/qmljsdebugclient/qpacketprotocol_p.h b/src/libs/qmljsdebugclient/qpacketprotocol_p.h new file mode 100644 index 0000000000..5b1803ad6b --- /dev/null +++ b/src/libs/qmljsdebugclient/qpacketprotocol_p.h @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPACKETPROTOCOL_H +#define QPACKETPROTOCOL_H + +#include <QtCore/qobject.h> +#include <QtCore/qdatastream.h> + +QT_BEGIN_HEADER + +class QIODevice; +class QBuffer; + +namespace QmlJsDebugClient { + +class QPacket; +class QPacketAutoSend; + +class QPacketProtocolPrivate; + +class QPacketProtocol : public QObject +{ +Q_OBJECT +public: + explicit QPacketProtocol(QIODevice * dev, QObject * parent = 0); + virtual ~QPacketProtocol(); + + qint32 maximumPacketSize() const; + qint32 setMaximumPacketSize(qint32); + + QPacketAutoSend send(); + void send(const QPacket &); + + qint64 packetsAvailable() const; + QPacket read(); + + void clear(); + + QIODevice * device(); + +Q_SIGNALS: + void readyRead(); + void invalidPacket(); + void packetWritten(); + +private: + QPacketProtocolPrivate * d; +}; + + +class QPacket : public QDataStream +{ +public: + QPacket(); + QPacket(const QPacket &); + virtual ~QPacket(); + + void clear(); + bool isEmpty() const; + +protected: + friend class QPacketProtocol; + QPacket(const QByteArray & ba); + QByteArray b; + QBuffer * buf; +}; + +class QPacketAutoSend : public QPacket +{ +public: + virtual ~QPacketAutoSend(); + +private: + friend class QPacketProtocol; + QPacketAutoSend(QPacketProtocol *); + QPacketProtocol * p; +}; + +} + +QT_END_HEADER + +#endif |