diff options
4 files changed, 61 insertions, 0 deletions
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index fc393d1..ac683a7 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -880,6 +880,7 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *parentCon state->bindValues = enginePriv->bindValues; state->parserStatus = enginePriv->parserStatus; + state->finalizedParserStatus = enginePriv->finalizedParserStatus; state->componentAttached = enginePriv->componentAttached; if (state->componentAttached) state->componentAttached->prev = &state->componentAttached; @@ -887,6 +888,7 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *parentCon enginePriv->componentAttached = 0; enginePriv->bindValues.clear(); enginePriv->parserStatus.clear(); + enginePriv->finalizedParserStatus.clear(); state->completePending = true; enginePriv->inProgressCreations++; } @@ -917,6 +919,7 @@ void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeEnginePrivate *engi state->bindValues = enginePriv->bindValues; state->parserStatus = enginePriv->parserStatus; + state->finalizedParserStatus = enginePriv->finalizedParserStatus; state->componentAttached = enginePriv->componentAttached; if (state->componentAttached) state->componentAttached->prev = &state->componentAttached; @@ -924,6 +927,7 @@ void QDeclarativeComponentPrivate::beginDeferred(QDeclarativeEnginePrivate *engi enginePriv->componentAttached = 0; enginePriv->bindValues.clear(); enginePriv->parserStatus.clear(); + enginePriv->finalizedParserStatus.clear(); state->completePending = true; enginePriv->inProgressCreations++; } @@ -961,6 +965,18 @@ void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePri QDeclarativeEnginePrivate::clear(ps); } + for (int ii = 0; ii < state->finalizedParserStatus.count(); ++ii) { + QPair<QDeclarativeGuard<QObject>, int> status = state->finalizedParserStatus.at(ii); + QObject *obj = status.first; + if (obj) { + void *args[] = { 0 }; + QMetaObject::metacall(obj, QMetaObject::InvokeMetaMethod, + status.second, args); + } + } + + //componentComplete() can register additional finalization objects + //that are then never handled. Handle them manually here. if (1 == enginePriv->inProgressCreations) { for (int ii = 0; ii < enginePriv->finalizedParserStatus.count(); ++ii) { QPair<QDeclarativeGuard<QObject>, int> status = enginePriv->finalizedParserStatus.at(ii); @@ -986,6 +1002,7 @@ void QDeclarativeComponentPrivate::complete(QDeclarativeEnginePrivate *enginePri state->bindValues.clear(); state->parserStatus.clear(); + state->finalizedParserStatus.clear(); state->completePending = false; enginePriv->inProgressCreations--; diff --git a/src/declarative/qml/qdeclarativecomponent_p.h b/src/declarative/qml/qdeclarativecomponent_p.h index 020c5e0..f8bec2b 100644 --- a/src/declarative/qml/qdeclarativecomponent_p.h +++ b/src/declarative/qml/qdeclarativecomponent_p.h @@ -101,6 +101,7 @@ public: ConstructionState() : componentAttached(0), completePending(false) {} QList<QDeclarativeEnginePrivate::SimpleList<QDeclarativeAbstractBinding> > bindValues; QList<QDeclarativeEnginePrivate::SimpleList<QDeclarativeParserStatus> > parserStatus; + QList<QPair<QDeclarativeGuard<QObject>, int> > finalizedParserStatus; QDeclarativeComponentAttached *componentAttached; QList<QDeclarativeError> errors; bool completePending; diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/delayedRegistration.qml b/tests/auto/declarative/qdeclarativebehaviors/data/delayedRegistration.qml new file mode 100644 index 0000000..aa384c3 --- /dev/null +++ b/tests/auto/declarative/qdeclarativebehaviors/data/delayedRegistration.qml @@ -0,0 +1,25 @@ +import QtQuick 1.0 + +Rectangle { + id: container + + width: 400; height: 400; + property Item myItem + + function doCreate() { + myItem = myComponent.createObject(container) + myItem.x = 100 + } + + Component { + id: myComponent + Rectangle { + width: 100 + height: 100 + color: "green" + Behavior on x { NumberAnimation { duration: 500 } } + } + } + + Component.onCompleted: doCreate() +} diff --git a/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp b/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp index 80ba907..4536d9e 100644 --- a/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp +++ b/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp @@ -81,6 +81,7 @@ private slots: void groupedPropertyCrash(); void runningTrue(); void sameValue(); + void delayedRegistration(); }; void tst_qdeclarativebehaviors::simpleBehavior() @@ -412,6 +413,23 @@ void tst_qdeclarativebehaviors::sameValue() QTRY_VERIFY(target->x() != qreal(0) && target->x() != qreal(100)); } +//QTBUG-18362 +void tst_qdeclarativebehaviors::delayedRegistration() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, SRCDIR "/data/delayedRegistration.qml"); + QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(c.create()); + QVERIFY(rect != 0); + + QDeclarativeItem *innerRect = rect->property("myItem").value<QDeclarativeItem*>(); + QVERIFY(innerRect != 0); + + QCOMPARE(innerRect->property("x").toInt(), int(0)); + + QTRY_COMPARE(innerRect->property("x").toInt(), int(100)); +} + QTEST_MAIN(tst_qdeclarativebehaviors) #include "tst_qdeclarativebehaviors.moc" |
