summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml')
-rw-r--r--src/declarative/qml/qmlcontextscriptclass.cpp9
-rw-r--r--src/declarative/qml/qmlcontextscriptclass_p.h3
-rw-r--r--src/declarative/qml/qmlenginedebug.cpp81
-rw-r--r--src/declarative/qml/qmlenginedebug_p.h2
-rw-r--r--src/declarative/qml/qmlexpression.cpp16
-rw-r--r--src/declarative/qml/qmlexpression.h2
-rw-r--r--src/declarative/qml/qmlexpression_p.h4
7 files changed, 86 insertions, 31 deletions
diff --git a/src/declarative/qml/qmlcontextscriptclass.cpp b/src/declarative/qml/qmlcontextscriptclass.cpp
index ae86fb1..4df23f0 100644
--- a/src/declarative/qml/qmlcontextscriptclass.cpp
+++ b/src/declarative/qml/qmlcontextscriptclass.cpp
@@ -99,10 +99,12 @@ QmlContextScriptClass::queryProperty(Object *object, const Identifier &name,
if (!bindContext)
return 0;
+ bool includeTypes = true;
while (bindContext) {
QScriptClass::QueryFlags rv =
- queryProperty(bindContext, scopeObject, name, flags);
+ queryProperty(bindContext, scopeObject, name, flags, includeTypes);
scopeObject = 0; // Only applies to the first context
+ includeTypes = false; // Only applies to the first context
if (rv) return rv;
bindContext = bindContext->parentContext();
}
@@ -113,7 +115,8 @@ QmlContextScriptClass::queryProperty(Object *object, const Identifier &name,
QScriptClass::QueryFlags
QmlContextScriptClass::queryProperty(QmlContext *bindContext, QObject *scopeObject,
const Identifier &name,
- QScriptClass::QueryFlags flags)
+ QScriptClass::QueryFlags flags,
+ bool includeTypes)
{
QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);
QmlContextPrivate *cp = QmlContextPrivate::get(bindContext);
@@ -124,7 +127,7 @@ QmlContextScriptClass::queryProperty(QmlContext *bindContext, QObject *scopeObje
return QScriptClass::HandlesReadAccess;
}
- if (cp->imports) {
+ if (includeTypes && cp->imports) {
QmlTypeNameCache::Data *data = cp->imports->data(name);
if (data) {
diff --git a/src/declarative/qml/qmlcontextscriptclass_p.h b/src/declarative/qml/qmlcontextscriptclass_p.h
index 126c8fe..95dff5b 100644
--- a/src/declarative/qml/qmlcontextscriptclass_p.h
+++ b/src/declarative/qml/qmlcontextscriptclass_p.h
@@ -80,7 +80,8 @@ protected:
private:
QScriptClass::QueryFlags queryProperty(QmlContext *, QObject *scopeObject,
const Identifier &,
- QScriptClass::QueryFlags flags);
+ QScriptClass::QueryFlags flags,
+ bool includeTypes);
QmlEngine *engine;
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();