diff options
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/qml/qqmlguard_p.h | 28 | ||||
-rw-r--r-- | src/qml/types/qqmldelegatemodel.cpp | 6 | ||||
-rw-r--r-- | src/qml/types/qqmldelegatemodel_p_p.h | 2 | ||||
-rw-r--r-- | src/qml/util/qqmladaptormodel.cpp | 8 | ||||
-rw-r--r-- | src/qml/util/qqmladaptormodel_p.h | 2 |
5 files changed, 37 insertions, 9 deletions
diff --git a/src/qml/qml/qqmlguard_p.h b/src/qml/qml/qqmlguard_p.h index 808bf4c709..3ac63926a0 100644 --- a/src/qml/qml/qqmlguard_p.h +++ b/src/qml/qml/qqmlguard_p.h @@ -106,6 +106,34 @@ protected: virtual void objectDestroyed(T *) {} }; +template <typename T> +class QQmlStrongJSQObjectReference : public QQmlGuard<T> +{ +public: + void setObject(T *o, QObject *parent) { + T *old = this->object(); + if (o == old) + return; + + if (m_jsOwnership && old && old->parent() == parent) + QQml_setParent_noEvent(old, nullptr); + + this->QQmlGuard<T>::operator=(o); + + if (o && !o->parent() && !QQmlData::keepAliveDuringGarbageCollection(o)) { + m_jsOwnership = true; + QQml_setParent_noEvent(o, parent); + } else { + m_jsOwnership = false; + } + } + +private: + using QQmlGuard<T>::setObject; + using QQmlGuard<T>::operator=; + bool m_jsOwnership = false; +}; + QT_END_NAMESPACE Q_DECLARE_METATYPE(QQmlGuard<QObject>) diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index 1c0da2875c..61cbb8700a 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -200,8 +200,7 @@ QQmlDelegateModelParts::QQmlDelegateModelParts(QQmlDelegateModel *parent) */ QQmlDelegateModelPrivate::QQmlDelegateModelPrivate(QQmlContext *ctxt) - : m_delegate(nullptr) - , m_cacheMetaType(nullptr) + : m_cacheMetaType(nullptr) , m_context(ctxt) , m_parts(nullptr) , m_filterGroup(QStringLiteral("items")) @@ -263,6 +262,7 @@ QQmlDelegateModel::QQmlDelegateModel(QQmlContext *ctxt, QObject *parent) QQmlDelegateModel::~QQmlDelegateModel() { Q_D(QQmlDelegateModel); + d->m_adaptorModel.setObject(nullptr, this); for (QQmlDelegateModelItem *cacheItem : qAsConst(d->m_cache)) { if (cacheItem->object) { @@ -409,7 +409,7 @@ void QQmlDelegateModel::setDelegate(QQmlComponent *delegate) return; } bool wasValid = d->m_delegate != nullptr; - d->m_delegate = delegate; + d->m_delegate.setObject(delegate, this); d->m_delegateValidated = false; if (wasValid && d->m_complete) { for (int i = 1; i < d->m_groupCount; ++i) { diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h index fc46986e23..3f9dd12243 100644 --- a/src/qml/types/qqmldelegatemodel_p_p.h +++ b/src/qml/types/qqmldelegatemodel_p_p.h @@ -305,7 +305,7 @@ public: QQmlAdaptorModel m_adaptorModel; QQmlListCompositor m_compositor; - QQmlComponent *m_delegate; + QQmlStrongJSQObjectReference<QQmlComponent> m_delegate; QQmlDelegateModelItemMetaType *m_cacheMetaType; QPointer<QQmlContext> m_context; QQmlDelegateModelParts *m_parts; diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp index c430074f56..15844017aa 100644 --- a/src/qml/util/qqmladaptormodel.cpp +++ b/src/qml/util/qqmladaptormodel.cpp @@ -956,7 +956,7 @@ void QQmlAdaptorModel::setModel(const QVariant &variant, QQmlDelegateModel *vdm, list.setList(variant, engine); if (QObject *object = qvariant_cast<QObject *>(list.list())) { - setObject(object); + setObject(object, vdm); if (QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(object)) { accessors = new VDMAbstractItemModelDataType(this); @@ -978,14 +978,14 @@ void QQmlAdaptorModel::setModel(const QVariant &variant, QQmlDelegateModel *vdm, accessors = new VDMObjectDelegateDataType; } } else if (list.type() == QQmlListAccessor::ListProperty) { - setObject(static_cast<const QQmlListReference *>(variant.constData())->object()); + setObject(static_cast<const QQmlListReference *>(variant.constData())->object(), vdm); accessors = new VDMObjectDelegateDataType; } else if (list.type() != QQmlListAccessor::Invalid && list.type() != QQmlListAccessor::Instance) { // Null QObject - setObject(nullptr); + setObject(nullptr, vdm); accessors = &qt_vdm_list_accessors; } else { - setObject(nullptr); + setObject(nullptr, vdm); accessors = &qt_vdm_null_accessors; } } diff --git a/src/qml/util/qqmladaptormodel_p.h b/src/qml/util/qqmladaptormodel_p.h index b706fcb5f2..3b2d180ca7 100644 --- a/src/qml/util/qqmladaptormodel_p.h +++ b/src/qml/util/qqmladaptormodel_p.h @@ -68,7 +68,7 @@ class QQmlDelegateModel; class QQmlDelegateModelItem; class QQmlDelegateModelItemMetaType; -class QQmlAdaptorModel : public QQmlGuard<QObject> +class QQmlAdaptorModel : public QQmlStrongJSQObjectReference<QObject> { public: class Accessors |