summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/qml/qdeclarativeenginedebug.cpp110
-rw-r--r--src/declarative/qml/qdeclarativeenginedebug_p.h5
-rw-r--r--tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp101
3 files changed, 196 insertions, 20 deletions
diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp
index 5f338db..4d6e50c 100644
--- a/src/declarative/qml/qdeclarativeenginedebug.cpp
+++ b/src/declarative/qml/qdeclarativeenginedebug.cpp
@@ -52,6 +52,7 @@
#include "private/qdeclarativevaluetype_p.h"
#include "private/qdeclarativevmemetaobject_p.h"
#include "private/qdeclarativeexpression_p.h"
+#include "private/qdeclarativepropertychanges_p.h"
#include <QtCore/qdebug.h>
#include <QtCore/qmetaobject.h>
@@ -304,6 +305,35 @@ void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, QDecla
}
}
+void QDeclarativeEngineDebugServer::buildStatesList(QDeclarativeContext *ctxt, bool cleanList=false)
+{
+ if (cleanList)
+ m_allStates.clear();
+
+ QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(ctxt);
+ for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
+ buildStatesList(ctxtPriv->instances.at(ii));
+ }
+
+ QDeclarativeContextData *child = QDeclarativeContextData::get(ctxt)->childContexts;
+ while (child) {
+ buildStatesList(child->asQDeclarativeContext());
+ child = child->nextChild;
+ }
+}
+
+void QDeclarativeEngineDebugServer::buildStatesList(QObject *obj)
+{
+ if (QDeclarativeState *state = dynamic_cast<QDeclarativeState *>(obj)) {
+ m_allStates.append(state);
+ }
+
+ QObjectList children = obj->children();
+ for (int ii = 0; ii < children.count(); ++ii) {
+ buildStatesList(children.at(ii));
+ }
+}
+
QDeclarativeEngineDebugServer::QDeclarativeObjectData
QDeclarativeEngineDebugServer::objectData(QObject *object)
{
@@ -382,8 +412,10 @@ void QDeclarativeEngineDebugServer::messageReceived(const QByteArray &message)
QDataStream rs(&reply, QIODevice::WriteOnly);
rs << QByteArray("LIST_OBJECTS_R") << queryId;
- if (engine)
+ if (engine) {
buildObjectList(rs, engine->rootContext());
+ buildStatesList(engine->rootContext(), true);
+ }
sendMessage(reply);
} else if (type == "FETCH_OBJECT") {
@@ -504,26 +536,66 @@ void QDeclarativeEngineDebugServer::setBinding(int objectId,
{
QObject *object = objectForId(objectId);
QDeclarativeContext *context = qmlContext(object);
+ QByteArray propertyNameArray = propertyName.toUtf8();
if (object && context) {
-
QDeclarativeProperty property(object, propertyName, context);
- if (isLiteralValue) {
- property.write(expression);
- } else if (hasValidSignal(object, propertyName)) {
- QDeclarativeExpression *declarativeExpression = new QDeclarativeExpression(context, object, expression.toString());
- QDeclarativeExpression *oldExpression = QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression);
- declarativeExpression->setSourceLocation(oldExpression->sourceFile(), oldExpression->lineNumber());
- } else if (property.isProperty()) {
- QDeclarativeBinding *binding = new QDeclarativeBinding(expression.toString(), object, context);
- binding->setTarget(property);
- binding->setNotifyOnValueChanged(true);
- QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, binding);
- if (oldBinding)
- oldBinding->destroy();
- binding->update();
+ if (property.isValid()) {
+
+ bool inBaseState = true;
+
+ foreach(QWeakPointer<QDeclarativeState> statePointer, m_allStates) {
+ if (QDeclarativeState *state = statePointer.data()) {
+ // here we assume that the revert list on itself defines the base state
+ if ( state->isStateActive() && state->containsPropertyInRevertList(object, propertyNameArray) ) {
+ inBaseState = false;
+
+ QDeclarativeBinding *newBinding = 0;
+ if (!isLiteralValue) {
+ newBinding = new QDeclarativeBinding(expression.toString(), object, context);
+ newBinding->setTarget(property);
+ newBinding->setNotifyOnValueChanged(true);
+ }
+
+ state->changeBindingInRevertList(object,propertyNameArray, newBinding);
+
+ if (isLiteralValue)
+ state->changeValueInRevertList(object, propertyNameArray, expression);
+ }
+ }
+ }
+
+ if (inBaseState) {
+ if (isLiteralValue) {
+ property.write(expression);
+ } else if (hasValidSignal(object, propertyName)) {
+ QDeclarativeExpression *declarativeExpression = new QDeclarativeExpression(context, object, expression.toString());
+ QDeclarativeExpression *oldExpression = QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression);
+ declarativeExpression->setSourceLocation(oldExpression->sourceFile(), oldExpression->lineNumber());
+ } else if (property.isProperty()) {
+ QDeclarativeBinding *binding = new QDeclarativeBinding(expression.toString(), object, context);
+ binding->setTarget(property);
+ binding->setNotifyOnValueChanged(true);
+ QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, binding);
+ if (oldBinding)
+ oldBinding->destroy();
+ binding->update();
+ } else {
+ qWarning() << "QDeclarativeEngineDebugServer::setBinding: unable to set property" << propertyName << "on object" << object;
+ }
+ }
+
} else {
- qWarning() << "QDeclarativeEngineDebugServer::setBinding: unable to set property" << propertyName << "on object" << object;
+ // not a valid property
+ if (QDeclarativePropertyChanges *propertyChanges = dynamic_cast<QDeclarativePropertyChanges *>(object)) {
+ if (isLiteralValue) {
+ propertyChanges->changeValue(propertyName.toUtf8(),expression);
+ } else {
+ propertyChanges->changeExpression(propertyName.toUtf8(),expression.toString());
+ }
+ } else {
+ qWarning() << "QDeclarativeEngineDebugServer::setBinding: unable to set property" << propertyName << "on object" << object;
+ }
}
}
}
@@ -546,6 +618,10 @@ void QDeclarativeEngineDebugServer::resetBinding(int objectId, const QString &pr
property.reset();
}
}
+ } else {
+ if (QDeclarativePropertyChanges *propertyChanges = dynamic_cast<QDeclarativePropertyChanges *>(object)) {
+ propertyChanges->removeProperty(propertyName.toUtf8());
+ }
}
}
}
diff --git a/src/declarative/qml/qdeclarativeenginedebug_p.h b/src/declarative/qml/qdeclarativeenginedebug_p.h
index dc8bc85..65eb1ff 100644
--- a/src/declarative/qml/qdeclarativeenginedebug_p.h
+++ b/src/declarative/qml/qdeclarativeenginedebug_p.h
@@ -57,6 +57,7 @@
#include <QtCore/qurl.h>
#include <QtCore/qvariant.h>
+#include <QWeakPointer>
QT_BEGIN_NAMESPACE
@@ -64,6 +65,7 @@ class QDeclarativeEngine;
class QDeclarativeContext;
class QDeclarativeWatcher;
class QDataStream;
+class QDeclarativeState;
class QDeclarativeEngineDebugServer : public QDeclarativeDebugService
{
@@ -108,6 +110,8 @@ private:
void prepareDeferredObjects(QObject *);
void buildObjectList(QDataStream &, QDeclarativeContext *);
void buildObjectDump(QDataStream &, QObject *, bool, bool);
+ void buildStatesList(QDeclarativeContext *, bool);
+ void buildStatesList(QObject *obj);
QDeclarativeObjectData objectData(QObject *);
QDeclarativeObjectProperty propertyData(QObject *, int);
QVariant valueContents(const QVariant &defaultValue) const;
@@ -117,6 +121,7 @@ private:
QList<QDeclarativeEngine *> m_engines;
QDeclarativeWatcher *m_watch;
+ QList<QWeakPointer<QDeclarativeState> > m_allStates;
};
Q_DECLARATIVE_PRIVATE_EXPORT QDataStream &operator<<(QDataStream &, const QDeclarativeEngineDebugServer::QDeclarativeObjectData &);
Q_DECLARATIVE_PRIVATE_EXPORT QDataStream &operator>>(QDataStream &, QDeclarativeEngineDebugServer::QDeclarativeObjectData &);
diff --git a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp
index 20a3fa6..fac32d7 100644
--- a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp
+++ b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp
@@ -72,7 +72,7 @@ class tst_QDeclarativeDebug : public QObject
Q_OBJECT
private:
- QDeclarativeDebugObjectReference findRootObject(int context = 0);
+ QDeclarativeDebugObjectReference findRootObject(int context = 0, bool recursive = false);
QDeclarativeDebugPropertyReference findProperty(const QList<QDeclarativeDebugPropertyReference> &props, const QString &name) const;
void waitForQuery(QDeclarativeDebugQuery *query);
@@ -115,9 +115,10 @@ private slots:
void setMethodBody();
void queryObjectTree();
+ void setBindingInStates();
};
-QDeclarativeDebugObjectReference tst_QDeclarativeDebug::findRootObject(int context)
+QDeclarativeDebugObjectReference tst_QDeclarativeDebug::findRootObject(int context, bool recursive)
{
QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this);
waitForQuery(q_engines);
@@ -129,7 +130,9 @@ QDeclarativeDebugObjectReference tst_QDeclarativeDebug::findRootObject(int conte
if (q_context->rootContext().objects().count() == 0)
return QDeclarativeDebugObjectReference();
- QDeclarativeDebugObjectQuery *q_obj = m_dbg->queryObject(q_context->rootContext().objects()[context], this);
+ QDeclarativeDebugObjectQuery *q_obj = recursive ?
+ m_dbg->queryObjectRecursive(q_context->rootContext().objects()[context], this) :
+ m_dbg->queryObject(q_context->rootContext().objects()[context], this);
waitForQuery(q_obj);
QDeclarativeDebugObjectReference result = q_obj->object();
@@ -926,6 +929,98 @@ void tst_QDeclarativeDebug::tst_QDeclarativeDebugPropertyReference()
compareProperties(r, ref);
}
+void tst_QDeclarativeDebug::setBindingInStates()
+{
+ // Check if changing bindings of propertychanges works
+
+ const int sourceIndex = 3;
+
+ QDeclarativeDebugObjectReference obj = findRootObject(sourceIndex);
+
+ QVERIFY(obj.debugId() != -1);
+ QVERIFY(obj.children().count() >= 2);
+
+ // We are going to switch state a couple of times, we need to get rid of the transition before
+ QDeclarativeDebugExpressionQuery *q_deleteTransition = m_dbg->queryExpressionResult(obj.debugId(),QString("transitions = []"),this);
+ waitForQuery(q_deleteTransition);
+ delete q_deleteTransition;
+
+
+ // check initial value of the property that is changing
+ QDeclarativeDebugExpressionQuery *q_setState;
+ q_setState = m_dbg->queryExpressionResult(obj.debugId(),QString("state=\"state1\""),this);
+ waitForQuery(q_setState);
+ delete q_setState;
+
+ obj = findRootObject(sourceIndex);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(),200);
+
+
+ q_setState = m_dbg->queryExpressionResult(obj.debugId(),QString("state=\"\""),this);
+ waitForQuery(q_setState);
+ delete q_setState;
+
+
+ obj = findRootObject(sourceIndex, true);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(),100);
+
+
+ // change the binding
+ QDeclarativeDebugObjectReference state = obj.children()[0];
+ QCOMPARE(state.className(), QString("State"));
+ QVERIFY(state.children().count() > 0);
+
+ QDeclarativeDebugObjectReference propertyChange = state.children()[0];
+ QVERIFY(propertyChange.debugId() != -1);
+
+ QVERIFY( m_dbg->setBindingForObject(propertyChange.debugId(), "width",QVariant(300),true) );
+
+ // check properties changed in state
+ obj = findRootObject(sourceIndex);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(),100);
+
+
+ q_setState = m_dbg->queryExpressionResult(obj.debugId(),QString("state=\"state1\""),this);
+ waitForQuery(q_setState);
+ delete q_setState;
+
+ obj = findRootObject(sourceIndex);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(),300);
+
+ // check changing properties of base state from within a state
+ QVERIFY(m_dbg->setBindingForObject(obj.debugId(),"width","height*2",false));
+ QVERIFY(m_dbg->setBindingForObject(obj.debugId(),"height","200",true));
+
+ obj = findRootObject(sourceIndex);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(),300);
+
+ q_setState = m_dbg->queryExpressionResult(obj.debugId(),QString("state=\"\""),this);
+ waitForQuery(q_setState);
+ delete q_setState;
+
+ obj = findRootObject(sourceIndex);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(), 400);
+
+ // reset binding while in a state
+ q_setState = m_dbg->queryExpressionResult(obj.debugId(),QString("state=\"state1\""),this);
+ waitForQuery(q_setState);
+ delete q_setState;
+
+ obj = findRootObject(sourceIndex);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(), 300);
+
+ m_dbg->resetBindingForObject(propertyChange.debugId(), "width");
+
+ obj = findRootObject(sourceIndex);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(), 400);
+
+ // re-add binding
+ m_dbg->setBindingForObject(propertyChange.debugId(), "width", "300", true);
+
+ obj = findRootObject(sourceIndex);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(), 300);
+}
+
void tst_QDeclarativeDebug::queryObjectTree()
{
const int sourceIndex = 3;