diff options
Diffstat (limited to 'src/declarative')
-rw-r--r-- | src/declarative/debugger/qmldebug.cpp | 81 | ||||
-rw-r--r-- | src/declarative/debugger/qmldebug.h | 24 | ||||
-rw-r--r-- | src/declarative/qml/qmlenginedebug.cpp | 81 | ||||
-rw-r--r-- | src/declarative/qml/qmlenginedebug_p.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlexpression.cpp | 16 | ||||
-rw-r--r-- | src/declarative/qml/qmlexpression.h | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlexpression_p.h | 4 |
7 files changed, 179 insertions, 31 deletions
diff --git a/src/declarative/debugger/qmldebug.cpp b/src/declarative/debugger/qmldebug.cpp index 1ef7503..2537ec0 100644 --- a/src/declarative/debugger/qmldebug.cpp +++ b/src/declarative/debugger/qmldebug.cpp @@ -32,10 +32,12 @@ public: static void remove(QmlEngineDebug *, QmlDebugEnginesQuery *); static void remove(QmlEngineDebug *, QmlDebugRootContextQuery *); static void remove(QmlEngineDebug *, QmlDebugObjectQuery *); + static void remove(QmlEngineDebug *, QmlDebugExpressionQuery *); QHash<int, QmlDebugEnginesQuery *> enginesQuery; QHash<int, QmlDebugRootContextQuery *> rootContextQuery; QHash<int, QmlDebugObjectQuery *> objectQuery; + QHash<int, QmlDebugExpressionQuery *> expressionQuery; QHash<int, QmlDebugWatch *> watched; }; @@ -81,6 +83,12 @@ void QmlEngineDebugPrivate::remove(QmlEngineDebug *c, QmlDebugObjectQuery *q) p->objectQuery.remove(q->m_queryId); } +void QmlEngineDebugPrivate::remove(QmlEngineDebug *c, QmlDebugExpressionQuery *q) +{ + QmlEngineDebugPrivate *p = (QmlEngineDebugPrivate *)QObjectPrivate::get(c); + p->expressionQuery.remove(q->m_queryId); +} + Q_DECLARE_METATYPE(QmlDebugObjectReference); void QmlEngineDebugPrivate::decode(QDataStream &ds, QmlDebugObjectReference &o, bool simple) @@ -109,6 +117,7 @@ void QmlEngineDebugPrivate::decode(QDataStream &ds, QmlDebugObjectReference &o, prop.m_name = data.name; prop.m_binding = data.binding; prop.m_hasNotifySignal = data.hasNotifySignal; + prop.m_valueTypeName = data.valueTypeName; if (data.type == QmlEngineDebugServer::QmlObjectProperty::Basic) prop.m_value = data.value; else if (data.type == QmlEngineDebugServer::QmlObjectProperty::Object) { @@ -116,7 +125,6 @@ void QmlEngineDebugPrivate::decode(QDataStream &ds, QmlDebugObjectReference &o, obj.m_debugId = prop.m_value.toInt(); prop.m_value = qVariantFromValue(obj); } - o.m_properties << prop; } @@ -212,6 +220,19 @@ void QmlEngineDebugPrivate::message(const QByteArray &data) query->m_client = 0; query->setState(QmlDebugQuery::Completed); + } else if (type == "EVAL_EXPRESSION_R") { + int queryId; + QVariant result; + ds >> queryId >> result; + + QmlDebugExpressionQuery *query = expressionQuery.value(queryId); + if (!query) + return; + expressionQuery.remove(queryId); + + query->m_result = result; + query->m_client = 0; + query->setState(QmlDebugQuery::Completed); } else if (type == "WATCH_PROPERTY_R") { int queryId; bool ok; @@ -267,7 +288,6 @@ QmlDebugPropertyWatch *QmlEngineDebug::addWatch(const QmlDebugPropertyReference QmlDebugPropertyWatch *watch = new QmlDebugPropertyWatch(parent); if (d->client->isConnected()) { - //query->m_client = this; int queryId = d->getId(); watch->m_queryId = queryId; watch->m_objectDebugId = property.objectDebugId(); @@ -445,6 +465,29 @@ QmlDebugObjectQuery *QmlEngineDebug::queryObjectRecursive(const QmlDebugObjectRe return query; } +QmlDebugExpressionQuery *QmlEngineDebug::queryExpressionResult(int objectDebugId, const QString &expr, QObject *parent) +{ + Q_D(QmlEngineDebug); + + QmlDebugExpressionQuery *query = new QmlDebugExpressionQuery(parent); + if (d->client->isConnected() && objectDebugId != -1) { + query->m_client = this; + query->m_expr = expr; + int queryId = d->getId(); + query->m_queryId = queryId; + d->expressionQuery.insert(queryId, query); + + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + ds << QByteArray("EVAL_EXPRESSION") << queryId << objectDebugId << expr; + d->client->sendMessage(message); + } else { + query->m_state = QmlDebugQuery::Error; + } + + return query; +} + QmlDebugWatch::QmlDebugWatch(QObject *parent) : QObject(parent), m_state(Waiting), m_queryId(-1), m_objectDebugId(-1) { @@ -566,6 +609,27 @@ QmlDebugObjectReference QmlDebugObjectQuery::object() const return m_object; } +QmlDebugExpressionQuery::QmlDebugExpressionQuery(QObject *parent) +: QmlDebugQuery(parent), m_client(0), m_queryId(-1) +{ +} + +QmlDebugExpressionQuery::~QmlDebugExpressionQuery() +{ + if (m_client && m_queryId != -1) + QmlEngineDebugPrivate::remove(m_client, this); +} + +QString QmlDebugExpressionQuery::expression() const +{ + return m_expr; +} + +QVariant QmlDebugExpressionQuery::result() const +{ + return m_result; +} + QmlDebugEngineReference::QmlDebugEngineReference() : m_debugId(-1) { @@ -748,13 +812,17 @@ QmlDebugPropertyReference::QmlDebugPropertyReference() } QmlDebugPropertyReference::QmlDebugPropertyReference(const QmlDebugPropertyReference &o) -: m_objectDebugId(o.m_objectDebugId), m_name(o.m_name), m_value(o.m_value), m_binding(o.m_binding), m_hasNotifySignal(o.m_hasNotifySignal) +: m_objectDebugId(o.m_objectDebugId), m_name(o.m_name), m_value(o.m_value), + m_valueTypeName(o.m_valueTypeName), m_binding(o.m_binding), + m_hasNotifySignal(o.m_hasNotifySignal) { } QmlDebugPropertyReference &QmlDebugPropertyReference::operator=(const QmlDebugPropertyReference &o) { - m_objectDebugId = o.m_objectDebugId; m_name = o.m_name; m_value = o.m_value; m_binding = o.m_binding; m_hasNotifySignal = o.m_hasNotifySignal; + m_objectDebugId = o.m_objectDebugId; m_name = o.m_name; m_value = o.m_value; + m_valueTypeName = o.m_valueTypeName; m_binding = o.m_binding; + m_hasNotifySignal = o.m_hasNotifySignal; return *this; } @@ -768,6 +836,11 @@ QString QmlDebugPropertyReference::name() const return m_name; } +QString QmlDebugPropertyReference::valueTypeName() const +{ + return m_valueTypeName; +} + QVariant QmlDebugPropertyReference::value() const { return m_value; diff --git a/src/declarative/debugger/qmldebug.h b/src/declarative/debugger/qmldebug.h index 681ee08..bd076ff 100644 --- a/src/declarative/debugger/qmldebug.h +++ b/src/declarative/debugger/qmldebug.h @@ -12,6 +12,7 @@ class QmlDebugObjectExpressionWatch; class QmlDebugEnginesQuery; class QmlDebugRootContextQuery; class QmlDebugObjectQuery; +class QmlDebugExpressionQuery; class QmlDebugPropertyReference; class QmlDebugContextReference; class QmlDebugObjectReference; @@ -44,6 +45,9 @@ public: QObject *parent = 0); QmlDebugObjectQuery *queryObjectRecursive(const QmlDebugObjectReference &, QObject *parent = 0); + QmlDebugExpressionQuery *queryExpressionResult(int objectDebugId, + const QString &expr, + QObject *parent = 0); private: Q_DECLARE_PRIVATE(QmlEngineDebug) @@ -228,6 +232,7 @@ public: int objectDebugId() const; QString name() const; QVariant value() const; + QString valueTypeName() const; QString binding() const; bool hasNotifySignal() const; @@ -236,6 +241,7 @@ private: int m_objectDebugId; QString m_name; QVariant m_value; + QString m_valueTypeName; QString m_binding; bool m_hasNotifySignal; }; @@ -287,4 +293,22 @@ private: }; +class Q_DECLARATIVE_EXPORT QmlDebugExpressionQuery : public QmlDebugQuery +{ +Q_OBJECT +public: + virtual ~QmlDebugExpressionQuery(); + QString expression() const; + QVariant result() const; +private: + friend class QmlEngineDebug; + friend class QmlEngineDebugPrivate; + QmlDebugExpressionQuery(QObject *); + QmlEngineDebug *m_client; + int m_queryId; + QString m_expr; + QVariant m_result; + +}; + #endif // QMLDEBUG_H diff --git a/src/declarative/qml/qmlenginedebug.cpp b/src/declarative/qml/qmlenginedebug.cpp index e20616a..7178e6c 100644 --- a/src/declarative/qml/qmlenginedebug.cpp +++ b/src/declarative/qml/qmlenginedebug.cpp @@ -80,7 +80,8 @@ QDataStream &operator>>(QDataStream &ds, QDataStream &operator<<(QDataStream &ds, const QmlEngineDebugServer::QmlObjectProperty &data) { - ds << (int)data.type << data.name << data.value << data.binding << data.hasNotifySignal; + ds << (int)data.type << data.name << data.value << data.valueTypeName + << data.binding << data.hasNotifySignal; return ds; } @@ -88,7 +89,8 @@ QDataStream &operator>>(QDataStream &ds, QmlEngineDebugServer::QmlObjectProperty &data) { int type; - ds >> type >> data.name >> data.value >> data.binding >> data.hasNotifySignal; + ds >> type >> data.name >> data.value >> data.valueTypeName + >> data.binding >> data.hasNotifySignal; data.type = (QmlEngineDebugServer::QmlObjectProperty::Type)type; return ds; } @@ -101,6 +103,7 @@ QmlEngineDebugServer::propertyData(QObject *obj, int propIdx) QMetaProperty prop = obj->metaObject()->property(propIdx); rv.type = QmlObjectProperty::Unknown; + rv.valueTypeName = QString::fromUtf8(prop.typeName()); rv.name = prop.name(); rv.hasNotifySignal = prop.hasNotifySignal(); QmlAbstractBinding *binding = QmlMetaProperty(obj, rv.name).binding(); @@ -116,6 +119,7 @@ QmlEngineDebugServer::propertyData(QObject *obj, int propIdx) QmlMetaType::isQmlList(prop.userType())) { rv.type = QmlObjectProperty::List; } + return rv; } @@ -149,7 +153,7 @@ void QmlEngineDebugServer::buildObjectList(QDataStream &message, int ctxtId = QmlDebugService::idForObject(ctxt); message << ctxtName << ctxtId; - + int count = 0; for (QSet<QmlContext *>::ConstIterator iter = p->childContexts.begin(); @@ -184,6 +188,32 @@ void QmlEngineDebugServer::buildObjectList(QDataStream &message, } } +QVariant QmlEngineDebugServer::serializableVariant(const QVariant &value) +{ + if (value.type() < QVariant::UserType) + return value; + + if (!value.toString().isEmpty()) + return value.toString(); + + QVariant v; + if (value.type() == QVariant::UserType || QmlMetaType::isObject(value.userType())) { + QObject *o = QmlMetaType::toQObject(value); + if (o) { + QString objectName = o->objectName(); + if (objectName.isEmpty()) + objectName = QLatin1String("<unnamed>"); + v = QString::fromUtf8(o->metaObject()->className()) + + QLatin1String(": ") + objectName; + } + } + + if (v.isNull()) + v = QString::fromUtf8(value.typeName()); + + return v; +} + QmlEngineDebugServer::QmlObjectData QmlEngineDebugServer::objectData(QObject *object) { @@ -310,29 +340,42 @@ void QmlEngineDebugServer::messageReceived(const QByteArray &message) ds >> queryId; m_watch->removeWatch(queryId); + } else if (type == "EVAL_EXPRESSION") { + int queryId; + int objectId; + QString expr; + + ds >> queryId >> objectId >> expr; + + QObject *object = QmlDebugService::objectForId(objectId); + QmlContext *context = qmlContext(object); + QVariant result; + if (object && context) { + QmlExpression *exprObj = new QmlExpression(context, expr, object); + bool undefined = false; + QVariant value = exprObj->value(&undefined); + if (undefined) + result = QLatin1String("<undefined>"); + else + result = serializableVariant(value); + delete exprObj; + } else { + result = QLatin1String("<unknown context>"); + } + + QByteArray reply; + QDataStream rs(&reply, QIODevice::WriteOnly); + rs << QByteArray("EVAL_EXPRESSION_R") << queryId << result; + + sendMessage(reply); } } void QmlEngineDebugServer::propertyChanged(int id, int objectId, const QByteArray &property, const QVariant &value) { QByteArray reply; - QVariant v; + QVariant v = serializableVariant(value); QDataStream rs(&reply, QIODevice::WriteOnly); - - if (value.type() == QVariant::UserType || QmlMetaType::isObject(value.userType())) { - QObject *o = QmlMetaType::toQObject(value); - if (o) { - QString objectName = o->objectName(); - if (objectName.isEmpty()) - objectName = QLatin1String("<unnamed>"); - v = QString::fromUtf8(o->metaObject()->className()) + - QLatin1String(": ") + objectName; - } - if (v.isNull()) - v = value.toString(); - } else { - v = value; - } rs << QByteArray("UPDATE_WATCH") << id << objectId << property << v; diff --git a/src/declarative/qml/qmlenginedebug_p.h b/src/declarative/qml/qmlenginedebug_p.h index e2f903c..075a711 100644 --- a/src/declarative/qml/qmlenginedebug_p.h +++ b/src/declarative/qml/qmlenginedebug_p.h @@ -85,6 +85,7 @@ public: Type type; QString name; QVariant value; + QString valueTypeName; QString binding; bool hasNotifySignal; }; @@ -103,6 +104,7 @@ private: void buildObjectDump(QDataStream &, QObject *, bool); QmlObjectData objectData(QObject *); QmlObjectProperty propertyData(QObject *, int); + QVariant serializableVariant(const QVariant &value); static QList<QmlEngine *> m_engines; QmlWatcher *m_watch; diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp index 356c3c6..b07ee4c 100644 --- a/src/declarative/qml/qmlexpression.cpp +++ b/src/declarative/qml/qmlexpression.cpp @@ -281,7 +281,7 @@ void QmlExpressionPrivate::printException(QScriptEngine *scriptEngine) } } -QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope) +QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope, bool *isUndefined) { #ifdef Q_ENABLE_PERFORMANCE_LOG QFxPerfTimer<QFxPerf::BindValueQt> perfqt; @@ -318,6 +318,9 @@ QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope) QScriptValue svalue = data->expressionFunction.call(); + if (isUndefined) + *isUndefined = svalue.isUndefined(); + if (scriptEngine->hasUncaughtException()) printException(scriptEngine); @@ -355,7 +358,7 @@ QVariant QmlExpressionPrivate::evalQtScript(QObject *secondaryScope) return rv; } -QVariant QmlExpressionPrivate::value(QObject *secondaryScope) +QVariant QmlExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined) { Q_Q(QmlExpression); @@ -382,7 +385,7 @@ QVariant QmlExpressionPrivate::value(QObject *secondaryScope) if (data->sse.isValid()) { rv = evalSSE(); } else { - rv = evalQtScript(secondaryScope); + rv = evalQtScript(secondaryScope, isUndefined); } ep->currentExpression = lastCurrentExpression; @@ -406,11 +409,14 @@ QVariant QmlExpressionPrivate::value(QObject *secondaryScope) /*! Returns the value of the expression, or an invalid QVariant if the expression is invalid or has an error. + + \a isUndefined is set to true if the expression resulted in an + undefined value. */ -QVariant QmlExpression::value() +QVariant QmlExpression::value(bool *isUndefined) { Q_D(QmlExpression); - return d->value(); + return d->value(0, isUndefined); } /*! diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h index 73682f1..96694d6 100644 --- a/src/declarative/qml/qmlexpression.h +++ b/src/declarative/qml/qmlexpression.h @@ -83,7 +83,7 @@ public: QObject *scopeObject() const; public Q_SLOTS: - QVariant value(); + QVariant value(bool *isUndefined = 0); Q_SIGNALS: virtual void valueChanged(); diff --git a/src/declarative/qml/qmlexpression_p.h b/src/declarative/qml/qmlexpression_p.h index d9bb27b..3ec8d1c 100644 --- a/src/declarative/qml/qmlexpression_p.h +++ b/src/declarative/qml/qmlexpression_p.h @@ -140,9 +140,9 @@ public: QmlExpressionData *data; - QVariant value(QObject *secondaryScope = 0); + QVariant value(QObject *secondaryScope = 0, bool *isUndefined = 0); QVariant evalSSE(); - QVariant evalQtScript(QObject *secondaryScope); + QVariant evalQtScript(QObject *secondaryScope, bool *isUndefined = 0); void updateGuards(const QPODVector<QmlEnginePrivate::CapturedProperty> &properties); void clearGuards(); |