aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp19
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h4
-rw-r--r--src/qml/util/qqmladaptormodel.cpp78
-rw-r--r--src/qml/util/qqmladaptormodel_p.h5
4 files changed, 64 insertions, 42 deletions
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 48cc77bc3d..53e3f65553 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -2036,7 +2036,9 @@ void QV4::Heap::QQmlDelegateModelItemObject::destroy()
}
-QQmlDelegateModelItem::QQmlDelegateModelItem(QQmlDelegateModelItemMetaType *metaType, int modelIndex, int row, int column)
+QQmlDelegateModelItem::QQmlDelegateModelItem(QQmlDelegateModelItemMetaType *metaType,
+ QQmlAdaptorModel::Accessors *accessor,
+ int modelIndex, int row, int column)
: v4(metaType->v4Engine)
, metaType(metaType)
, contextData(nullptr)
@@ -2053,6 +2055,21 @@ QQmlDelegateModelItem::QQmlDelegateModelItem(QQmlDelegateModelItemMetaType *meta
, column(column)
{
metaType->addref();
+
+ if (accessor->propertyCache) {
+ // The property cache in the accessor is common for all the model
+ // items in the model it wraps. It describes available model roles,
+ // together with revisioned properties like row, column and index, all
+ // which should be available in the delegate. We assign this cache to the
+ // model item so that the QML engine can use the revision information
+ // when resolving the properties (rather than falling back to just
+ // inspecting the QObject in the model item directly).
+ QQmlData *qmldata = QQmlData::get(this, true);
+ if (qmldata->propertyCache)
+ qmldata->propertyCache->release();
+ qmldata->propertyCache = accessor->propertyCache.data();
+ qmldata->propertyCache->addref();
+ }
}
QQmlDelegateModelItem::~QQmlDelegateModelItem()
diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h
index 5e480f4df6..0cd772ede0 100644
--- a/src/qml/types/qqmldelegatemodel_p_p.h
+++ b/src/qml/types/qqmldelegatemodel_p_p.h
@@ -100,7 +100,9 @@ class QQmlDelegateModelItem : public QObject
Q_PROPERTY(int column MEMBER column NOTIFY columnChanged)
Q_PROPERTY(QObject *model READ modelObject CONSTANT)
public:
- QQmlDelegateModelItem(QQmlDelegateModelItemMetaType *metaType, int modelIndex, int row, int column);
+ QQmlDelegateModelItem(QQmlDelegateModelItemMetaType *metaType,
+ QQmlAdaptorModel::Accessors *accessor, int modelIndex,
+ int row, int column);
~QQmlDelegateModelItem();
void referenceObject() { ++objectRef; }
diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp
index 831663fb7b..8743e9ea7c 100644
--- a/src/qml/util/qqmladaptormodel.cpp
+++ b/src/qml/util/qqmladaptormodel.cpp
@@ -121,21 +121,12 @@ class VDMModelDelegateDataType
public:
VDMModelDelegateDataType(QQmlAdaptorModel *model)
: model(model)
- , metaObject(nullptr)
- , propertyCache(nullptr)
, propertyOffset(0)
, signalOffset(0)
, hasModelData(false)
{
}
- ~VDMModelDelegateDataType()
- {
- if (propertyCache)
- propertyCache->release();
- free(metaObject);
- }
-
bool notify(
const QQmlAdaptorModel &,
const QList<QQmlDelegateModelItem *> &items,
@@ -255,15 +246,13 @@ public:
QList<QByteArray> watchedRoles;
QHash<QByteArray, int> roleNames;
QQmlAdaptorModel *model;
- QMetaObject *metaObject;
- QQmlPropertyCache *propertyCache;
int propertyOffset;
int signalOffset;
bool hasModelData;
};
QQmlDMCachedModelData::QQmlDMCachedModelData(QQmlDelegateModelItemMetaType *metaType, VDMModelDelegateDataType *dataType, int index, int row, int column)
- : QQmlDelegateModelItem(metaType, index, row, column)
+ : QQmlDelegateModelItem(metaType, dataType, index, row, column)
, type(dataType)
{
if (index == -1)
@@ -272,10 +261,6 @@ QQmlDMCachedModelData::QQmlDMCachedModelData(QQmlDelegateModelItemMetaType *meta
QObjectPrivate::get(this)->metaObject = type;
type->addref();
-
- QQmlData *qmldata = QQmlData::get(this, true);
- qmldata->propertyCache = dataType->propertyCache;
- qmldata->propertyCache->addref();
}
int QQmlDMCachedModelData::metaCall(QMetaObject::Call call, int id, void **arguments)
@@ -538,9 +523,9 @@ public:
addProperty(&builder, 1, propertyName, propertyType);
}
- metaObject = builder.toMetaObject();
+ metaObject.reset(builder.toMetaObject());
*static_cast<QMetaObject *>(this) = *metaObject;
- propertyCache = new QQmlPropertyCache(metaObject);
+ propertyCache = new QQmlPropertyCache(metaObject.data(), model.modelItemRevision);
}
};
@@ -553,8 +538,10 @@ class QQmlDMListAccessorData : public QQmlDelegateModelItem
Q_OBJECT
Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged)
public:
- QQmlDMListAccessorData(QQmlDelegateModelItemMetaType *metaType, int index, int row, int column, const QVariant &value)
- : QQmlDelegateModelItem(metaType, index, row, column)
+ QQmlDMListAccessorData(QQmlDelegateModelItemMetaType *metaType,
+ QQmlAdaptorModel::Accessors *accessor,
+ int index, int row, int column, const QVariant &value)
+ : QQmlDelegateModelItem(metaType, accessor, index, row, column)
, cachedData(value)
{
}
@@ -635,10 +622,18 @@ private:
};
-class VDMListDelegateDataType : public QQmlAdaptorModel::Accessors
+class VDMListDelegateDataType : public QQmlRefCount, public QQmlAdaptorModel::Accessors
{
public:
- inline VDMListDelegateDataType() {}
+ VDMListDelegateDataType()
+ : QQmlRefCount()
+ , QQmlAdaptorModel::Accessors()
+ {}
+
+ void cleanup(QQmlAdaptorModel &) const override
+ {
+ const_cast<VDMListDelegateDataType *>(this)->release();
+ }
int rowCount(const QQmlAdaptorModel &model) const override
{
@@ -662,8 +657,15 @@ public:
QQmlDelegateModelItemMetaType *metaType,
int index, int row, int column) const override
{
+ VDMListDelegateDataType *dataType = const_cast<VDMListDelegateDataType *>(this);
+ if (!propertyCache) {
+ dataType->propertyCache = new QQmlPropertyCache(
+ &QQmlDMListAccessorData::staticMetaObject, model.modelItemRevision);
+ }
+
return new QQmlDMListAccessorData(
metaType,
+ dataType,
index, row, column,
index >= 0 && index < model.list.count() ? model.list.at(index) : QVariant());
}
@@ -721,15 +723,13 @@ Q_SIGNALS:
class VDMObjectDelegateDataType : public QQmlRefCount, public QQmlAdaptorModel::Accessors
{
public:
- QMetaObject *metaObject;
int propertyOffset;
int signalOffset;
bool shared;
QMetaObjectBuilder builder;
VDMObjectDelegateDataType()
- : metaObject(nullptr)
- , propertyOffset(0)
+ : propertyOffset(0)
, signalOffset(0)
, shared(true)
{
@@ -738,11 +738,10 @@ public:
VDMObjectDelegateDataType(const VDMObjectDelegateDataType &type)
: QQmlRefCount()
, QQmlAdaptorModel::Accessors()
- , metaObject(nullptr)
, propertyOffset(type.propertyOffset)
, signalOffset(type.signalOffset)
, shared(false)
- , builder(type.metaObject, QMetaObjectBuilder::Properties
+ , builder(type.metaObject.data(), QMetaObjectBuilder::Properties
| QMetaObjectBuilder::Signals
| QMetaObjectBuilder::SuperClass
| QMetaObjectBuilder::ClassName)
@@ -750,11 +749,6 @@ public:
builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
}
- ~VDMObjectDelegateDataType()
- {
- free(metaObject);
- }
-
int rowCount(const QQmlAdaptorModel &model) const override
{
return model.list.count();
@@ -785,11 +779,18 @@ public:
: nullptr;
}
- void initializeMetaType(QQmlAdaptorModel &)
+ void initializeMetaType(QQmlAdaptorModel &model)
{
+ Q_UNUSED(model);
setModelDataType<QQmlDMObjectData>(&builder, this);
- metaObject = builder.toMetaObject();
+ metaObject.reset(builder.toMetaObject());
+ // Note: ATM we cannot create a shared property cache for this class, since each model
+ // object can have different properties. And to make those properties available to the
+ // delegate, QQmlDMObjectData makes use of a QAbstractDynamicMetaObject subclass
+ // (QQmlDMObjectDataMetaObject), which we cannot represent in a QQmlPropertyCache.
+ // By not having a shared property cache, revisioned properties in QQmlDelegateModelItem
+ // will always be available to the delegate, regardless of the import version.
}
void cleanup(QQmlAdaptorModel &) const override
@@ -888,9 +889,7 @@ public:
propertyBuilder.setConstant(property.isConstant());
}
- if (m_type->metaObject)
- free(m_type->metaObject);
- m_type->metaObject = m_type->builder.toMetaObject();
+ m_type->metaObject.reset(m_type->builder.toMetaObject());
*static_cast<QMetaObject *>(this) = *m_type->metaObject;
notifierId = previousMethodCount;
@@ -913,7 +912,7 @@ QQmlDMObjectData::QQmlDMObjectData(QQmlDelegateModelItemMetaType *metaType,
VDMObjectDelegateDataType *dataType,
int index, int row, int column,
QObject *object)
- : QQmlDelegateModelItem(metaType, index, row, column)
+ : QQmlDelegateModelItem(metaType, dataType, index, row, column)
, object(object)
{
new QQmlDMObjectDataMetaObject(this, dataType);
@@ -924,7 +923,6 @@ QQmlDMObjectData::QQmlDMObjectData(QQmlDelegateModelItemMetaType *metaType,
//-----------------------------------------------------------------
static const QQmlAdaptorModel::Accessors qt_vdm_null_accessors;
-static const VDMListDelegateDataType qt_vdm_list_accessors;
QQmlAdaptorModel::Accessors::~Accessors()
{
@@ -958,7 +956,7 @@ void QQmlAdaptorModel::setModel(const QVariant &variant, QObject *parent, QQmlEn
} else if (list.type() != QQmlListAccessor::Invalid
&& list.type() != QQmlListAccessor::Instance) { // Null QObject
setObject(nullptr, parent);
- accessors = &qt_vdm_list_accessors;
+ accessors = new VDMListDelegateDataType;
} else {
setObject(nullptr, parent);
accessors = &qt_vdm_null_accessors;
diff --git a/src/qml/util/qqmladaptormodel_p.h b/src/qml/util/qqmladaptormodel_p.h
index b5e0881078..4ce3b0703a 100644
--- a/src/qml/util/qqmladaptormodel_p.h
+++ b/src/qml/util/qqmladaptormodel_p.h
@@ -104,12 +104,17 @@ public:
return QVariant(); }
virtual bool canFetchMore(const QQmlAdaptorModel &) const { return false; }
virtual void fetchMore(QQmlAdaptorModel &) const {}
+
+ QScopedPointer<QMetaObject, QScopedPointerPodDeleter> metaObject;
+ QQmlRefPointer<QQmlPropertyCache> propertyCache;
};
const Accessors *accessors;
QPersistentModelIndex rootIndex;
QQmlListAccessor list;
+ int modelItemRevision = 0;
+
QQmlAdaptorModel();
~QQmlAdaptorModel();