aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlmodels/qqmltableinstancemodel.cpp
diff options
context:
space:
mode:
authorUlf Hermann <[email protected]>2022-07-12 08:47:11 +0200
committerUlf Hermann <[email protected]>2022-07-21 13:19:04 +0200
commite4f4e7341f5fbfbb246c7fc4ee99fed5cce42fca (patch)
treeade043953c41cee5882ac2fca49630de1d91831e /src/qmlmodels/qqmltableinstancemodel.cpp
parent80cb4091d6cc5b7d13b80668f6e393788d763b3e (diff)
QmlModels: Fix context and extra object handling
If we have a bound context, we still need to record the information that the object's context belongs to a delegate. For this purpose we have the extra object. Even when we create the object in the component's creation context, the object creator still produces a private internal context for each object. We unconditionally attach the extra object to that one, and check the whole context hierarchy for extra objects. As we now record the creation context for model items incubated from bound components, we need to make sure not to (re)set its context object and not to forcibly invalidate it. We have QQmlRefPointer::reset() for that anyway. As a drive-by we also assert that the object ref count doesn't overflow, as that has happened during testing. Pick-to: 6.4 Fixes: QTBUG-104884 Change-Id: I836916c63656124a0f9d7b04902debba59b9f3a3 Reviewed-by: Fabian Kosmale <[email protected]>
Diffstat (limited to 'src/qmlmodels/qqmltableinstancemodel.cpp')
-rw-r--r--src/qmlmodels/qqmltableinstancemodel.cpp47
1 files changed, 27 insertions, 20 deletions
diff --git a/src/qmlmodels/qqmltableinstancemodel.cpp b/src/qmlmodels/qqmltableinstancemodel.cpp
index e145702463..39102c27c9 100644
--- a/src/qmlmodels/qqmltableinstancemodel.cpp
+++ b/src/qmlmodels/qqmltableinstancemodel.cpp
@@ -29,13 +29,7 @@ void QQmlTableInstanceModel::deleteModelItemLater(QQmlDelegateModelItem *modelIt
delete modelItem->object;
modelItem->object = nullptr;
-
- if (modelItem->contextData) {
- modelItem->contextData->invalidate();
- Q_ASSERT(modelItem->contextData->refCount() == 1);
- modelItem->contextData = nullptr;
- }
-
+ modelItem->contextData.reset();
modelItem->deleteLater();
}
@@ -67,8 +61,7 @@ QQmlTableInstanceModel::~QQmlTableInstanceModel()
if (modelItem->object) {
delete modelItem->object;
modelItem->object = nullptr;
- modelItem->contextData->invalidate();
- modelItem->contextData = nullptr;
+ modelItem->contextData.reset();
}
}
@@ -295,17 +288,31 @@ void QQmlTableInstanceModel::incubateModelItem(QQmlDelegateModelItem *modelItem,
modelItem->incubationTask = new QQmlTableInstanceModelIncubationTask(this, modelItem, incubationMode);
QQmlContext *creationContext = modelItem->delegate->creationContext();
- QQmlRefPointer<QQmlContextData> ctxt = QQmlContextData::createRefCounted(
- QQmlContextData::get(creationContext ? creationContext : m_qmlContext.data()));
- ctxt->setContextObject(modelItem);
- modelItem->contextData = ctxt;
-
- QQmlComponentPrivate::get(modelItem->delegate)->incubateObject(
- modelItem->incubationTask,
- modelItem->delegate,
- m_qmlContext->engine(),
- ctxt,
- QQmlContextData::get(m_qmlContext));
+ const QQmlRefPointer<QQmlContextData> componentContext
+ = QQmlContextData::get(creationContext ? creationContext : m_qmlContext.data());
+
+ QQmlComponentPrivate *cp = QQmlComponentPrivate::get(modelItem->delegate);
+ if (cp->isBound()) {
+ modelItem->contextData = componentContext;
+ cp->incubateObject(
+ modelItem->incubationTask,
+ modelItem->delegate,
+ m_qmlContext->engine(),
+ componentContext,
+ QQmlContextData::get(m_qmlContext));
+ } else {
+ QQmlRefPointer<QQmlContextData> ctxt = QQmlContextData::createRefCounted(
+ QQmlContextData::get(creationContext ? creationContext : m_qmlContext.data()));
+ ctxt->setContextObject(modelItem);
+ modelItem->contextData = ctxt;
+
+ cp->incubateObject(
+ modelItem->incubationTask,
+ modelItem->delegate,
+ m_qmlContext->engine(),
+ ctxt,
+ QQmlContextData::get(m_qmlContext));
+ }
}
// Remove the temporary guard