aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/qqmlcomponent.cpp4
-rw-r--r--src/qml/qml/qqmlcomponent_p.h2
-rw-r--r--src/qml/qml/qqmlincubator.cpp4
-rw-r--r--src/qml/qml/qqmlincubator_p.h2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp24
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h8
-rw-r--r--src/qmlmodels/qqmldelegatemodel.cpp2
-rw-r--r--src/quick/items/qquicklistview.cpp2
-rw-r--r--tests/auto/quick/qquicklistview2/data/innerRequired.qml33
-rw-r--r--tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp22
-rw-r--r--tests/auto/quick/qquickrepeater/data/innerRequired.qml33
-rw-r--r--tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp22
12 files changed, 138 insertions, 20 deletions
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 41af4ed67b..26a7b9afbf 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -349,9 +349,9 @@ RequiredProperties &QQmlComponentPrivate::requiredProperties()
return state.creator->requiredProperties();
}
-bool QQmlComponentPrivate::hadRequiredProperties() const
+bool QQmlComponentPrivate::hadTopLevelRequiredProperties() const
{
- return state.creator->componentHadRequiredProperties();
+ return state.creator->componentHadTopLevelRequiredProperties();
}
void QQmlComponentPrivate::clear()
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index 26f275f861..55330c6837 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -108,7 +108,7 @@ public:
int start;
RequiredProperties& requiredProperties();
- bool hadRequiredProperties() const;
+ bool hadTopLevelRequiredProperties() const;
QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit;
struct ConstructionState {
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index 5a3fd2a1f4..52d9fe07ed 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -696,9 +696,9 @@ RequiredProperties &QQmlIncubatorPrivate::requiredProperties()
return creator->requiredProperties();
}
-bool QQmlIncubatorPrivate::hadRequiredProperties() const
+bool QQmlIncubatorPrivate::hadTopLevelRequiredProperties() const
{
- return creator->componentHadRequiredProperties();
+ return creator->componentHadTopLevelRequiredProperties();
}
/*!
diff --git a/src/qml/qml/qqmlincubator_p.h b/src/qml/qml/qqmlincubator_p.h
index b178c6aa29..0d91e63f17 100644
--- a/src/qml/qml/qqmlincubator_p.h
+++ b/src/qml/qml/qqmlincubator_p.h
@@ -106,7 +106,7 @@ public:
void forceCompletion(QQmlInstantiationInterrupt &i);
void incubate(QQmlInstantiationInterrupt &i);
RequiredProperties &requiredProperties();
- bool hadRequiredProperties() const;
+ bool hadTopLevelRequiredProperties() const;
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index b1bedc7c37..f3af43577d 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -82,6 +82,7 @@ QQmlObjectCreator::QQmlObjectCreator(
, propertyCaches(&compilationUnit->propertyCaches)
, sharedState(new QQmlObjectCreatorSharedState, QQmlRefPointer<QQmlObjectCreatorSharedState>::Adopt)
, topLevelCreator(true)
+ , isContextObject(true)
, incubator(incubator)
{
init(std::move(parentContext));
@@ -93,7 +94,7 @@ QQmlObjectCreator::QQmlObjectCreator(
sharedState->allJavaScriptObjects = nullptr;
sharedState->creationContext = creationContext;
sharedState->rootContext.reset();
- sharedState->hadRequiredProperties = false;
+ sharedState->hadTopLevelRequiredProperties = false;
if (auto profiler = QQmlEnginePrivate::get(engine)->profiler) {
Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, profiler,
@@ -103,15 +104,15 @@ QQmlObjectCreator::QQmlObjectCreator(
}
}
-QQmlObjectCreator::QQmlObjectCreator(
- QQmlRefPointer<QQmlContextData> parentContext,
+QQmlObjectCreator::QQmlObjectCreator(QQmlRefPointer<QQmlContextData> parentContext,
const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
- QQmlObjectCreatorSharedState *inheritedSharedState)
+ QQmlObjectCreatorSharedState *inheritedSharedState, bool isContextObject)
: phase(Startup)
, compilationUnit(compilationUnit)
, propertyCaches(&compilationUnit->propertyCaches)
, sharedState(inheritedSharedState)
, topLevelCreator(false)
+ , isContextObject(isContextObject)
, incubator(nullptr)
{
init(std::move(parentContext));
@@ -1249,7 +1250,8 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
}
if (!type.isInlineComponentType()) {
- QQmlObjectCreator subCreator(context, compilationUnit, sharedState.data());
+ QQmlObjectCreator subCreator(context, compilationUnit, sharedState.data(),
+ isContextObject);
instance = subCreator.create();
if (!instance) {
errors += subCreator.errors;
@@ -1258,7 +1260,8 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
} else {
int subObjectId = type.inlineComponentId();
QScopedValueRollback<int> rollback {compilationUnit->icRoot, subObjectId};
- QQmlObjectCreator subCreator(context, compilationUnit, sharedState.data());
+ QQmlObjectCreator subCreator(context, compilationUnit, sharedState.data(),
+ isContextObject);
instance = subCreator.create(subObjectId, nullptr, nullptr, CreationFlags::InlineComponent);
if (!instance) {
errors += subCreator.errors;
@@ -1559,7 +1562,8 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
continue;
if (postHocIt != postHocRequired.end())
postHocRequired.erase(postHocIt);
- sharedState->hadRequiredProperties = true;
+ if (isContextObject)
+ sharedState->hadTopLevelRequiredProperties = true;
sharedState->requiredProperties.insert(propertyData,
RequiredPropertyInfo {compilationUnit->stringAt(property->nameIndex), compilationUnit->finalUrl(), property->location, {}});
@@ -1617,7 +1621,8 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
if (postHocIt != postHocRequired.end())
postHocRequired.erase(postHocIt);
- sharedState->hadRequiredProperties = true;
+ if (isContextObject)
+ sharedState->hadTopLevelRequiredProperties = true;
sharedState->requiredProperties.insert(
propertyData,
RequiredPropertyInfo {
@@ -1647,7 +1652,8 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
continue;
postHocRequired.erase(postHocIt);
- sharedState->hadRequiredProperties = true;
+ if (isContextObject)
+ sharedState->hadTopLevelRequiredProperties = true;
sharedState->requiredProperties.insert(
propertyData,
RequiredPropertyInfo {
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index 194a071d95..3e036c0970 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -111,7 +111,7 @@ struct QQmlObjectCreatorSharedState : QQmlRefCount
QRecursionNode recursionNode;
RequiredProperties requiredProperties;
QList<DeferredQPropertyBinding> allQPropertyBindings;
- bool hadRequiredProperties;
+ bool hadTopLevelRequiredProperties;
};
class Q_QML_PRIVATE_EXPORT QQmlObjectCreator
@@ -150,7 +150,7 @@ public:
QFiniteStack<QQmlGuard<QObject> > &allCreatedObjects() { return sharedState->allCreatedObjects; }
RequiredProperties &requiredProperties() {return sharedState->requiredProperties;}
- bool componentHadRequiredProperties() const {return sharedState->hadRequiredProperties;}
+ bool componentHadTopLevelRequiredProperties() const {return sharedState->hadTopLevelRequiredProperties;}
static QQmlComponent *createComponent(QQmlEngine *engine,
QV4::ExecutableCompilationUnit *compilationUnit,
@@ -160,7 +160,8 @@ public:
private:
QQmlObjectCreator(QQmlRefPointer<QQmlContextData> contextData,
const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit,
- QQmlObjectCreatorSharedState *inheritedSharedState);
+ QQmlObjectCreatorSharedState *inheritedSharedState,
+ bool isContextObject);
void init(QQmlRefPointer<QQmlContextData> parentContext);
@@ -218,6 +219,7 @@ private:
const QQmlPropertyCacheVector *propertyCaches;
QQmlRefPointer<QQmlObjectCreatorSharedState> sharedState;
bool topLevelCreator;
+ bool isContextObject;
QQmlIncubatorPrivate *incubator;
QObject *_qobject;
diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp
index 0c763a71be..8ecbadc262 100644
--- a/src/qmlmodels/qqmldelegatemodel.cpp
+++ b/src/qmlmodels/qqmldelegatemodel.cpp
@@ -961,7 +961,7 @@ static void bindingFunction(
void QQDMIncubationTask::initializeRequiredProperties(QQmlDelegateModelItem *modelItemToIncubate, QObject *object)
{
auto incubatorPriv = QQmlIncubatorPrivate::get(this);
- if (incubatorPriv->hadRequiredProperties()) {
+ if (incubatorPriv->hadTopLevelRequiredProperties()) {
QQmlData *d = QQmlData::get(object);
auto contextData = d ? d->context : nullptr;
if (contextData) {
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 7ddda6196f..cf5d6e02ae 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -1102,7 +1102,7 @@ QQuickItem * QQuickListViewPrivate::getSectionItem(const QString &section)
QQmlComponentPrivate* delegatePriv = QQmlComponentPrivate::get(delegate);
QObject *nobj = delegate->beginCreate(context);
if (nobj) {
- if (delegatePriv->hadRequiredProperties()) {
+ if (delegatePriv->hadTopLevelRequiredProperties()) {
delegate->setInitialProperties(nobj, {{QLatin1String("section"), section}});
} else {
context->setContextProperty(QLatin1String("section"), section);
diff --git a/tests/auto/quick/qquicklistview2/data/innerRequired.qml b/tests/auto/quick/qquicklistview2/data/innerRequired.qml
new file mode 100644
index 0000000000..b45181c0d2
--- /dev/null
+++ b/tests/auto/quick/qquicklistview2/data/innerRequired.qml
@@ -0,0 +1,33 @@
+import QtQuick
+
+Item {
+ ListModel {
+ id: myModel
+ ListElement { type: "Dog"; age: 8; noise: "meow" }
+ ListElement { type: "Cat"; age: 5; noise: "woof" }
+ }
+
+ component SomeDelegate: Item {
+ required property int age
+ property string text
+ }
+
+ component AnotherDelegate: Item {
+ property int age
+ property string text
+
+ SomeDelegate {
+ age: 0
+ text: ""
+ }
+ }
+
+ ListView {
+ id: listView
+ model: myModel
+ delegate: AnotherDelegate {
+ age: model.age
+ text: model.noise
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp b/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp
index 27bf389891..bdc99d2301 100644
--- a/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp
+++ b/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp
@@ -60,6 +60,7 @@ private slots:
void sectionsNoOverlap();
void metaSequenceAsModel();
void noCrashOnIndexChange();
+ void innerRequired();
};
tst_QQuickListView2::tst_QQuickListView2()
@@ -307,6 +308,27 @@ void tst_QQuickListView2::noCrashOnIndexChange()
QCOMPARE(items->property("count").toInt(), 4);
}
+void tst_QQuickListView2::innerRequired()
+{
+ QQmlEngine engine;
+ const QUrl url(testFileUrl("innerRequired.qml"));
+ QQmlComponent component(&engine, url);
+ QVERIFY2(component.isReady(), qPrintable(component.errorString()));
+
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY2(!o.isNull(), qPrintable(component.errorString()));
+
+ QQuickListView *a = qobject_cast<QQuickListView *>(
+ qmlContext(o.data())->objectForName(QStringLiteral("listView")));
+ QVERIFY(a);
+
+ QCOMPARE(a->count(), 2);
+ QCOMPARE(a->itemAtIndex(0)->property("age").toInt(), 8);
+ QCOMPARE(a->itemAtIndex(0)->property("text").toString(), u"meow");
+ QCOMPARE(a->itemAtIndex(1)->property("age").toInt(), 5);
+ QCOMPARE(a->itemAtIndex(1)->property("text").toString(), u"woof");
+}
+
class SingletonModel : public QStringListModel
{
Q_OBJECT
diff --git a/tests/auto/quick/qquickrepeater/data/innerRequired.qml b/tests/auto/quick/qquickrepeater/data/innerRequired.qml
new file mode 100644
index 0000000000..5498232fc1
--- /dev/null
+++ b/tests/auto/quick/qquickrepeater/data/innerRequired.qml
@@ -0,0 +1,33 @@
+import QtQuick
+
+Item {
+ ListModel {
+ id: myModel
+ ListElement { type: "Dog"; age: 8; noise: "meow" }
+ ListElement { type: "Cat"; age: 5; noise: "woof" }
+ }
+
+ component SomeDelegate: Item {
+ required property int age
+ property string text
+ }
+
+ component AnotherDelegate: Item {
+ property int age
+ property string text
+
+ SomeDelegate {
+ age: 0
+ text: ""
+ }
+ }
+
+ Repeater {
+ id: repeater
+ model: myModel
+ delegate: AnotherDelegate {
+ age: model.age
+ text: model.noise
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
index e8b53d046f..9cc2ef4de7 100644
--- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
+++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
@@ -84,6 +84,7 @@ private slots:
void ownership();
void requiredProperties();
void contextProperties();
+ void innerRequired();
};
class TestObject : public QObject
@@ -1174,6 +1175,27 @@ void tst_QQuickRepeater::contextProperties()
}
}
+void tst_QQuickRepeater::innerRequired()
+{
+ QQmlEngine engine;
+ const QUrl url(testFileUrl("innerRequired.qml"));
+ QQmlComponent component(&engine, url);
+ QVERIFY2(component.isReady(), qPrintable(component.errorString()));
+
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY2(!o.isNull(), qPrintable(component.errorString()));
+
+ QQuickRepeater *a = qobject_cast<QQuickRepeater *>(
+ qmlContext(o.data())->objectForName(QStringLiteral("repeater")));
+ QVERIFY(a);
+
+ QCOMPARE(a->count(), 2);
+ QCOMPARE(a->itemAt(0)->property("age").toInt(), 8);
+ QCOMPARE(a->itemAt(0)->property("text").toString(), u"meow");
+ QCOMPARE(a->itemAt(1)->property("age").toInt(), 5);
+ QCOMPARE(a->itemAt(1)->property("text").toString(), u"woof");
+}
+
QTEST_MAIN(tst_QQuickRepeater)
#include "tst_qquickrepeater.moc"