diff options
author | Lasse Holmstedt <lasse.holmstedt@nokia.com> | 2010-06-30 08:10:23 (GMT) |
---|---|---|
committer | Lasse Holmstedt <lasse.holmstedt@nokia.com> | 2010-06-30 08:16:45 (GMT) |
commit | ed82b3d0f93b9876201aa8145eafbaf4b50f2f36 (patch) | |
tree | 4af208b97ae052604a38addf8c39dfce40888b60 | |
parent | 730511f15bd619319e99fba484cf415b87a38052 (diff) | |
download | Qt-ed82b3d0f93b9876201aa8145eafbaf4b50f2f36.zip Qt-ed82b3d0f93b9876201aa8145eafbaf4b50f2f36.tar.gz Qt-ed82b3d0f93b9876201aa8145eafbaf4b50f2f36.tar.bz2 |
Added SET_BINDING message to QDeclarative debugger protocol
The new message currently enables resetting bindings, literal values and
signal handlers (onX: {...}) through the debugger.
Reviewed-by: Roberto Raggi
5 files changed, 112 insertions, 7 deletions
diff --git a/src/declarative/debugger/qdeclarativedebug.cpp b/src/declarative/debugger/qdeclarativedebug.cpp index cd5340b..e4a991b 100644 --- a/src/declarative/debugger/qdeclarativedebug.cpp +++ b/src/declarative/debugger/qdeclarativedebug.cpp @@ -562,6 +562,33 @@ QDeclarativeDebugExpressionQuery *QDeclarativeEngineDebug::queryExpressionResult return query; } +QDeclarativeDebugExpressionQuery *QDeclarativeEngineDebug::setBindingForObject(int objectDebugId, + const QString &propertyName, + const QVariant &bindingExpression, + bool isLiteralValue, + QObject *parent) +{ + Q_D(QDeclarativeEngineDebug); + + QDeclarativeDebugExpressionQuery *query = new QDeclarativeDebugExpressionQuery(parent); + if (d->client->isConnected() && objectDebugId != -1) { + query->m_client = this; + query->m_expr = bindingExpression; + int queryId = d->getId(); + query->m_queryId = queryId; + d->expressionQuery.insert(queryId, query); + + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + ds << QByteArray("SET_BINDING") << queryId << objectDebugId << propertyName << bindingExpression << isLiteralValue; + d->client->sendMessage(message); + } else { + query->m_state = QDeclarativeDebugQuery::Error; + } + + return query; +} + QDeclarativeDebugWatch::QDeclarativeDebugWatch(QObject *parent) : QObject(parent), m_state(Waiting), m_queryId(-1), m_client(0), m_objectDebugId(-1) { @@ -698,7 +725,7 @@ QDeclarativeDebugExpressionQuery::~QDeclarativeDebugExpressionQuery() QDeclarativeEngineDebugPrivate::remove(m_client, this); } -QString QDeclarativeDebugExpressionQuery::expression() const +QVariant QDeclarativeDebugExpressionQuery::expression() const { return m_expr; } diff --git a/src/declarative/debugger/qdeclarativedebug_p.h b/src/declarative/debugger/qdeclarativedebug_p.h index 4ead232..007cbd7 100644 --- a/src/declarative/debugger/qdeclarativedebug_p.h +++ b/src/declarative/debugger/qdeclarativedebug_p.h @@ -94,7 +94,11 @@ public: QDeclarativeDebugExpressionQuery *queryExpressionResult(int objectDebugId, const QString &expr, QObject *parent = 0); - + QDeclarativeDebugExpressionQuery *setBindingForObject(int objectDebugId, + const QString &propertyName, + const QVariant &bindingExpression, + bool isLiteralValue, + QObject *parent = 0); private: Q_DECLARE_PRIVATE(QDeclarativeEngineDebug) }; @@ -198,6 +202,11 @@ public: private: friend class QDeclarativeEngineDebugPrivate; + QDeclarativeDebugExpressionQuery *setBindingForObject(int objectDebugId, + const QString &propertyName, + const QVariant &bindingExpression, + bool isLiteralValue, + QObject *parent); QUrl m_url; int m_lineNumber; int m_columnNumber; @@ -215,6 +224,11 @@ public: QString name() const; private: + QDeclarativeDebugExpressionQuery *setBindingForObject(int objectDebugId, + const QString &propertyName, + const QVariant &bindingExpression, + bool isLiteralValue, + QObject *parent); friend class QDeclarativeEngineDebugPrivate; int m_debugId; QString m_name; @@ -348,7 +362,7 @@ class Q_DECLARATIVE_EXPORT QDeclarativeDebugExpressionQuery : public QDeclarativ Q_OBJECT public: virtual ~QDeclarativeDebugExpressionQuery(); - QString expression() const; + QVariant expression() const; QVariant result() const; private: friend class QDeclarativeEngineDebug; @@ -356,7 +370,7 @@ private: QDeclarativeDebugExpressionQuery(QObject *); QDeclarativeEngineDebug *m_client; int m_queryId; - QString m_expr; + QVariant m_expr; QVariant m_result; }; diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp index 7ae0050..d765649 100644 --- a/src/declarative/qml/qdeclarativeenginedebug.cpp +++ b/src/declarative/qml/qdeclarativeenginedebug.cpp @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE QList<QDeclarativeEngine *> QDeclarativeEngineDebugServer::m_engines; QDeclarativeEngineDebugServer::QDeclarativeEngineDebugServer(QObject *parent) : QDeclarativeDebugService(QLatin1String("QDeclarativeEngine"), parent), - m_watch(new QDeclarativeWatcher(this)) + m_watch(new QDeclarativeWatcher(this)) { QObject::connect(m_watch, SIGNAL(propertyChanged(int,int,QMetaProperty,QVariant)), this, SLOT(propertyChanged(int,int,QMetaProperty,QVariant))); @@ -99,6 +99,29 @@ QDataStream &operator>>(QDataStream &ds, return ds; } +static inline bool isSignalPropertyName(const QString &signalName) +{ + // see QmlCompiler::isSignalPropertyName + return signalName.length() >= 3 && signalName.startsWith(QLatin1String("on")) && + signalName.at(2).isLetter() && signalName.at(2).isUpper(); +} + +static bool hasValidSignal(QObject *object, const QString &propertyName) +{ + if (!isSignalPropertyName(propertyName)) + return false; + + QString signalName = propertyName.mid(2); + signalName[0] = signalName.at(0).toLower(); + + int sigIdx = QDeclarativePropertyPrivate::findSignalByName(object->metaObject(), signalName.toLatin1()).methodIndex(); + + if (sigIdx == -1) + return false; + + return true; +} + QDeclarativeEngineDebugServer::QDeclarativeObjectProperty QDeclarativeEngineDebugServer::propertyData(QObject *obj, int propIdx) { @@ -396,7 +419,6 @@ void QDeclarativeEngineDebugServer::messageReceived(const QByteArray &message) QByteArray reply; QDataStream rs(&reply, QIODevice::WriteOnly); rs << QByteArray("WATCH_EXPR_OBJECT_R") << queryId << ok; - sendMessage(reply); } else if (type == "NO_WATCH") { int queryId; @@ -430,7 +452,48 @@ void QDeclarativeEngineDebugServer::messageReceived(const QByteArray &message) rs << QByteArray("EVAL_EXPRESSION_R") << queryId << result; sendMessage(reply); + } else if (type == "SET_BINDING") { + int queryId; + int objectId; + QString propertyName; + QVariant expr; + bool isLiteralValue; + ds >> queryId >> objectId >> propertyName >> expr >> isLiteralValue; + setBinding(objectId, propertyName, expr, isLiteralValue); + } +} + +void QDeclarativeEngineDebugServer::setBinding(int objectId, + const QString &propertyName, + const QVariant &expression, + bool isLiteralValue) +{ + QObject *object = objectForId(objectId); + QDeclarativeContext *context = qmlContext(object); + + if (object && context) { + + if (isLiteralValue) { + QDeclarativeProperty literalProperty(object, propertyName, context); + literalProperty.write(expression); + } else { + if (hasValidSignal(object, propertyName)) { + QDeclarativeProperty property(object, propertyName); + QDeclarativeExpression *declarativeExpression = new QDeclarativeExpression(context, object, expression.toString()); + QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression); + } else { + QDeclarativeBinding *binding = new QDeclarativeBinding(expression.toString(), object, context); + QDeclarativeProperty property(object, propertyName); + binding->setTarget(property); + binding->setNotifyOnValueChanged(true); + QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, binding); + if (oldBinding) + oldBinding->destroy(); + binding->update(); + } + } } + } void QDeclarativeEngineDebugServer::propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value) diff --git a/src/declarative/qml/qdeclarativeenginedebug_p.h b/src/declarative/qml/qdeclarativeenginedebug_p.h index 9491411..b3c23bd 100644 --- a/src/declarative/qml/qdeclarativeenginedebug_p.h +++ b/src/declarative/qml/qdeclarativeenginedebug_p.h @@ -107,6 +107,7 @@ private: QDeclarativeObjectData objectData(QObject *); QDeclarativeObjectProperty propertyData(QObject *, int); QVariant valueContents(const QVariant &defaultValue) const; + void setBinding(int objectId, const QString &propertyName, const QVariant &expression, bool isLiteralValue); static QList<QDeclarativeEngine *> m_engines; QDeclarativeWatcher *m_watch; diff --git a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp index e2d3ee4..dcd1a85 100644 --- a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp +++ b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp @@ -694,7 +694,7 @@ void tst_QDeclarativeDebug::queryExpressionResult() delete q_expr; q_expr = m_dbg->queryExpressionResult(objectId, expr, this); - QCOMPARE(q_expr->expression(), expr); + QCOMPARE(q_expr->expression().toString(), expr); waitForQuery(q_expr); QCOMPARE(q_expr->result(), result); |