Revision control
Copy as Markdown
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:significant
#ifndef QQMLDATAMODEL_P_P_H
#define QQMLDATAMODEL_P_P_H
#include "qqmldelegatemodel_p.h"
#include <private/qv4qobjectwrapper_p.h>
#include <QtQml/qqmlcontext.h>
#include <QtQml/qqmlincubator.h>
#include <private/qqmladaptormodel_p.h>
#include <private/qqmlopenmetaobject_p.h>
#include <QtCore/qloggingcategory.h>
#include <QtCore/qpointer.h>
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
QT_REQUIRE_CONFIG(qml_delegate_model);
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcItemViewDelegateRecycling)
typedef QQmlListCompositor Compositor;
class QQmlDelegateModelAttachedMetaObject;
class QQmlAbstractDelegateComponent;
class QQmlTableInstanceModel;
class Q_QMLMODELS_EXPORT QQmlDelegateModelItemMetaType final
: public QQmlRefCounted<QQmlDelegateModelItemMetaType>
{
public:
enum class ModelKind : quint8 {
InstanceModel,
DelegateModel,
TableInstanceModel,
};
QQmlDelegateModelItemMetaType(
QV4::ExecutionEngine *engine, QQmlDelegateModel *model, const QStringList &groupNames);
QQmlDelegateModelItemMetaType(
QV4::ExecutionEngine *engine, QQmlTableInstanceModel *model);
~QQmlDelegateModelItemMetaType();
void initializeAttachedMetaObject();
void initializePrototype();
int parseGroups(const QStringList &groupNames) const;
int parseGroups(const QV4::Value &groupNames) const;
QQmlDelegateModel *delegateModel() const
{
return modelKind == ModelKind::DelegateModel
? static_cast<QQmlDelegateModel *>(model.get())
: nullptr;
}
qsizetype groupCount() const { return groupNames.size(); }
void emitModelChanged() const;
QPointer<QQmlInstanceModel> model;
QV4::ExecutionEngine * const v4Engine;
QQmlRefPointer<QQmlDelegateModelAttachedMetaObject> attachedMetaObject;
const QStringList groupNames;
QV4::PersistentValue modelItemProto;
ModelKind modelKind = ModelKind::InstanceModel;
};
class QQmlAdaptorModel;
class QQDMIncubationTask;
class Q_QMLMODELS_EXPORT QQmlDelegateModelItem : public QObject
{
Q_OBJECT
Q_PROPERTY(int index READ modelIndex NOTIFY modelIndexChanged)
Q_PROPERTY(int row READ modelRow NOTIFY rowChanged REVISION(2, 12))
Q_PROPERTY(int column READ modelColumn NOTIFY columnChanged REVISION(2, 12))
Q_PROPERTY(QObject *model READ modelObject CONSTANT)
public:
struct ObjectReference
{
Q_DISABLE_COPY_MOVE(ObjectReference)
ObjectReference(QQmlDelegateModelItem *item) : item(item)
{
++item->m_objectStrongRef;
}
~ObjectReference()
{
Q_ASSERT(item->m_objectStrongRef > 0);
--item->m_objectStrongRef;
}
private:
QQmlDelegateModelItem *item = nullptr;
};
struct ObjectSpanReference
{
Q_DISABLE_COPY_MOVE(ObjectSpanReference)
ObjectSpanReference(QSpan<QQmlDelegateModelItem *const> span) : items(std::move(span))
{
for (QQmlDelegateModelItem *item : items)
++item->m_objectStrongRef;
}
~ObjectSpanReference()
{
for (QQmlDelegateModelItem *item : items) {
Q_ASSERT(item->m_objectStrongRef > 0);
--item->m_objectStrongRef;
}
}
private:
const QSpan<QQmlDelegateModelItem *const> items;
};
struct ScriptReference
{
Q_DISABLE_COPY_MOVE(ScriptReference)
ScriptReference(QQmlDelegateModelItem *item) : item(item) { item->referenceSript(); }
~ScriptReference() { item->releaseScript(); }
QQmlDelegateModelItem *data() const { return item; }
private:
QQmlDelegateModelItem *item = nullptr;
};
QQmlDelegateModelItem(const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType,
QQmlAdaptorModel::Accessors *accessor, int modelIndex,
int row, int column);
~QQmlDelegateModelItem();
[[nodiscard]] QObject *referenceObjectWeak()
{
Q_ASSERT(m_object);
++m_objectWeakRef;
return m_object;
}
bool releaseObjectWeak()
{
if (m_objectWeakRef > 0)
--m_objectWeakRef;
return !isObjectReferenced();
}
void clearObjectWeakReferences()
{
m_objectWeakRef = 0;
}
bool isObjectReferenced() const
{
return m_objectWeakRef != 0
|| m_objectStrongRef != 0
|| (m_groups & Compositor::PersistedFlag);
}
void childContextObjectDestroyed(QObject *childContextObject);
bool isScriptReferenced() const {
return m_scriptRef
|| m_incubationTask
|| ((m_groups & Compositor::UnresolvedFlag) && (m_groups & Compositor::GroupMask));
}
void dispose();
QObject *modelObject() { return this; }
void destroyObject();
void destroyObjectLater();
static QQmlDelegateModelItem *dataForObject(QObject *object);
int groupIndex(Compositor::Group group);
int modelRow() const { return m_row; }
int modelColumn() const { return m_column; }
int modelIndex() const { return m_index; }
bool hasValidModelIndex() const { return m_index >= 0; }
virtual void setModelIndex(int idx, int newRow, int newColumn, bool alwaysEmit = false);
void setPersistentModelIndex(const QPersistentModelIndex &index) { m_persistentIndex = index; }
QPersistentModelIndex persistentModelIndex() const { return m_persistentIndex; }
bool usesStructuredModelData() const { return m_useStructuredModelData; }
virtual QV4::ReturnedValue get() { return QV4::QObjectWrapper::wrap(m_metaType->v4Engine, this); }
virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); }
virtual bool resolveIndex(const QQmlAdaptorModel &, int) { return false; }
virtual QQmlRefPointer<QQmlContextData> initProxy() { return m_contextData; }
static QV4::ReturnedValue get_model(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
static QV4::ReturnedValue get_groups(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
static QV4::ReturnedValue set_groups(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
static QV4::ReturnedValue get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &);
static QV4::ReturnedValue set_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
static QV4::ReturnedValue get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
QQmlDelegateModelAttached *attached() const
{
if (!m_object)
return nullptr;
QQmlData *ddata = QQmlData::get(m_object);
if (!ddata || !ddata->hasExtendedData())
return nullptr;
return static_cast<QQmlDelegateModelAttached *>(
ddata->attachedProperties()->value(
QQmlPrivate::attachedPropertiesFunc<QQmlDelegateModel>()));
}
void disableStructuredModelData() { m_useStructuredModelData = false; }
QDynamicMetaObjectData *exchangeMetaObject(QDynamicMetaObjectData *metaObject)
{
return std::exchange(d_ptr->metaObject, metaObject);
}
QQDMIncubationTask *incubationTask() const { return m_incubationTask; }
void clearIncubationTask() { m_incubationTask = nullptr; }
void setIncubationTask(QQDMIncubationTask *incubationTask)
{
Q_ASSERT(!m_incubationTask);
Q_ASSERT(incubationTask);
m_incubationTask = incubationTask;
}
quint16 objectStrongRef() const { return m_objectStrongRef; }
quint16 objectWeakRef() const { return m_objectWeakRef; }
quint16 scriptRef() const { return m_scriptRef; }
QObject *object() const { return m_object; }
void setObject(QObject *object) {
Q_ASSERT(!m_object);
Q_ASSERT(object);
m_object = object;
}
QQmlComponent *delegate() const { return m_delegate; }
void setDelegate(QQmlComponent *delegate) { m_delegate = delegate; }
const QQmlRefPointer<QQmlContextData> &contextData() const { return m_contextData; }
void setContextData(const QQmlRefPointer<QQmlContextData> &contextData)
{
m_contextData = contextData;
}
int groups() const { return m_groups; }
void setGroups(int groups) { m_groups = groups; }
void addGroups(int groups) { m_groups |= groups; }
void removeGroups(int groups) { m_groups &= ~groups; }
void clearGroups() { m_groups = 0; }
const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType() const { return m_metaType; }
Q_SIGNALS:
void modelIndexChanged();
Q_REVISION(2, 12) void rowChanged();
Q_REVISION(2, 12) void columnChanged();
private:
void objectDestroyed(QObject *);
void referenceSript() { ++m_scriptRef; }
bool releaseScript()
{
Q_ASSERT(m_scriptRef > 0);
return --m_scriptRef == 0;
}
QQmlRefPointer<QQmlDelegateModelItemMetaType> m_metaType;
QQmlRefPointer<QQmlContextData> m_contextData;
QPointer<QObject> m_object;
QQDMIncubationTask *m_incubationTask = nullptr;
QQmlComponent *m_delegate = nullptr;
int m_groups = 0;
int m_index = -1;
int m_row = -1;
int m_column = -1;
// A strong reference to the object prevents the deletion of the object. We use them as
// temporary guards with ObjectReference or ObjectSpanReference to make sure the objects we're
// currently manipulating don't disappear.
quint16 m_objectStrongRef = 0;
// A weak reference to the object is added when handing the object out to the view via object().
// It is dropped when the view calls release(). Weak references are advisory. We try not to
// delete an object while weak references are still in place. However, during destruction, the
// weak refernces may be ignored. Views are expected to use QPointer or similar guards in
// addition.
quint16 m_objectWeakRef = 0;
// A script reference is a strong reference to the QQmlDelegateModelItem itself. We don't delete
// the QQmlDelegateModelItem while script references are still in place. We can use them as
// temporary guards to hold on to an item while working on it, or we can attach them to
// Heap::QQmlDelegateModelItemObject in order to extend the life time of a QQmlDelegateModelItem
// to the life time of its heap object.
// The latter case is particular in that it contradicts our usual mechanism of only holding weak
// references to QObjects in e.g. QV4::QObjectWrapper. The trick here is that the actual
// QQmlDelegateModelItem is never exposed to the user, so that the user has no chance of
// manually deleting it.
// TODO: This is brittle.
quint16 m_scriptRef = 0;
bool m_useStructuredModelData = true;
QPersistentModelIndex m_persistentIndex;
};
namespace QV4 {
namespace Heap {
struct QQmlDelegateModelItemObject : Object {
inline void init(QQmlDelegateModelItem *item);
void destroy();
alignas(alignof(QQmlDelegateModelItem::ScriptReference))
std::byte ref[sizeof(QQmlDelegateModelItem::ScriptReference)];
QQmlDelegateModelItem *item() const {
return reinterpret_cast<const QQmlDelegateModelItem::ScriptReference *>(&ref)->data();
}
};
}
}
struct QQmlDelegateModelItemObject : QV4::Object
{
V4_OBJECT2(QQmlDelegateModelItemObject, QV4::Object)
V4_NEEDS_DESTROY
};
void QV4::Heap::QQmlDelegateModelItemObject::init(QQmlDelegateModelItem *modelItem)
{
Object::init();
new (ref) QQmlDelegateModelItem::ScriptReference(modelItem);
}
class QQmlReusableDelegateModelItemsPool
{
public:
bool insertItem(QQmlDelegateModelItem *modelItem);
QQmlDelegateModelItem *takeItem(const QQmlComponent *delegate, int newIndexHint);
void reuseItem(QQmlDelegateModelItem *item, int newModelIndex);
void drain(int maxPoolTime, std::function<void(QQmlDelegateModelItem *cacheItem)> releaseItem);
int size()
{
Q_ASSERT(m_reusableItemsPool.size() <= MaxSize);
return int(m_reusableItemsPool.size());
}
private:
struct PoolItem
{
QQmlDelegateModelItem *item = nullptr;
int poolTime = 0;
};
static constexpr size_t MaxSize = size_t(std::numeric_limits<int>::max());
std::vector<PoolItem> m_reusableItemsPool;
};
template<typename Target>
class QQmlDelegateModelReadOnlyMetaObject : QDynamicMetaObjectData
{
Q_DISABLE_COPY_MOVE(QQmlDelegateModelReadOnlyMetaObject)
public:
QQmlDelegateModelReadOnlyMetaObject(const Target &target, int readOnlyProperty)
: target(target)
, readOnlyProperty(readOnlyProperty)
{
if (QQmlDelegateModelItem *object = target)
original = object->exchangeMetaObject(this);
}
~QQmlDelegateModelReadOnlyMetaObject()
{
if (QQmlDelegateModelItem *object = target)
object->exchangeMetaObject(original);
}
void objectDestroyed(QObject *o) final
{
if (target)
original->objectDestroyed(o);
}
QMetaObject *toDynamicMetaObject(QObject *o) final
{
return target ? original->toDynamicMetaObject(o) : nullptr;
}
int metaCall(QObject *o, QMetaObject::Call call, int id, void **argv) final
{
if (!target)
return 0;
if (id == readOnlyProperty && call == QMetaObject::WriteProperty)
return 0;
return original->metaCall(o, call, id, argv);
}
private:
Target target = {};
QDynamicMetaObjectData *original = nullptr;
int readOnlyProperty = -1;
};
class QQmlDelegateModelPrivate;
class QQDMIncubationTask : public QQmlIncubator
{
public:
QQDMIncubationTask(QQmlDelegateModelPrivate *l, IncubationMode mode)
: QQmlIncubator(mode)
, incubating(nullptr)
, vdm(l) {}
void initializeRequiredProperties(
QQmlDelegateModelItem *modelItemToIncubate, QObject* object,
QQmlDelegateModel::DelegateModelAccess access);
void statusChanged(Status) override;
void setInitialState(QObject *) override;
QQmlDelegateModelItem *incubating = nullptr;
QQmlDelegateModelPrivate *vdm = nullptr;
QQmlRefPointer<QQmlContextData> proxyContext;
QPointer<QObject> proxiedObject = nullptr; // the proxied object might disapear, so we use a QPointer instead of a raw one
int index[QQmlListCompositor::MaximumGroupCount];
};
class QQmlDelegateModelGroupEmitter
{
public:
virtual ~QQmlDelegateModelGroupEmitter();
virtual void emitModelUpdated(const QQmlChangeSet &changeSet, bool reset) = 0;
virtual void createdPackage(int, QQuickPackage *);
virtual void initPackage(int, QQuickPackage *);
virtual void destroyingPackage(QQuickPackage *);
QIntrusiveListNode emitterNode;
};
typedef QIntrusiveList<QQmlDelegateModelGroupEmitter, &QQmlDelegateModelGroupEmitter::emitterNode> QQmlDelegateModelGroupEmitterList;
class QQmlDelegateModelGroupPrivate : public QObjectPrivate
{
public:
Q_DECLARE_PUBLIC(QQmlDelegateModelGroup)
QQmlDelegateModelGroupPrivate() : group(Compositor::Cache), defaultInclude(false) {}
static QQmlDelegateModelGroupPrivate *get(QQmlDelegateModelGroup *group) {
return static_cast<QQmlDelegateModelGroupPrivate *>(QObjectPrivate::get(group)); }
void setModel(QQmlDelegateModel *model, Compositor::Group group);
bool isChangedConnected();
void emitChanges(QV4::ExecutionEngine *engine);
void emitModelUpdated(bool reset);
void createdPackage(int index, QQuickPackage *package);
void initPackage(int index, QQuickPackage *package);
void destroyingPackage(QQuickPackage *package);
bool parseIndex(const QV4::Value &value, int *index, Compositor::Group *group) const;
bool parseGroupArgs(
QQmlV4FunctionPtr args, Compositor::Group *group, int *index, int *count, int *groups) const;
Compositor::Group group;
QPointer<QQmlDelegateModel> model;
QQmlDelegateModelGroupEmitterList emitters;
QQmlChangeSet changeSet;
QString name;
bool defaultInclude;
};
class QQmlDelegateModelParts;
class QQmlDelegateModelPrivate : public QObjectPrivate, public QQmlDelegateModelGroupEmitter
{
Q_DECLARE_PUBLIC(QQmlDelegateModel)
public:
QQmlDelegateModelPrivate(QQmlContext *);
~QQmlDelegateModelPrivate();
static QQmlDelegateModelPrivate *get(QQmlDelegateModel *m) {
return static_cast<QQmlDelegateModelPrivate *>(QObjectPrivate::get(m));
}
void init();
void connectModel(QQmlAdaptorModel *model);
void connectToAbstractItemModel();
void disconnectFromAbstractItemModel();
void requestMoreIfNecessary();
QObject *object(Compositor::Group group, int index, QQmlIncubator::IncubationMode incubationMode);
QQmlDelegateModel::ReleaseFlags release(QObject *object, QQmlInstanceModel::ReusableFlag reusable = QQmlInstanceModel::NotReusable);
QVariant variantValue(Compositor::Group group, int index, const QString &name);
void emitCreatedPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package);
void emitInitPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package);
void emitCreatedItem(QQDMIncubationTask *incubationTask, QObject *item) {
Q_EMIT q_func()->createdItem(incubationTask->index[m_compositorGroup], item); }
void emitInitItem(QQDMIncubationTask *incubationTask, QObject *item) {
Q_EMIT q_func()->initItem(incubationTask->index[m_compositorGroup], item); }
void emitDestroyingPackage(QQuickPackage *package);
void emitDestroyingItem(QObject *item) { Q_EMIT q_func()->destroyingItem(item); }
void addCacheItem(QQmlDelegateModelItem *item, Compositor::iterator it);
void removeCacheItem(QQmlDelegateModelItem *cacheItem);
void destroyCacheItem(QQmlDelegateModelItem *cacheItem);
void updateFilterGroup();
void reuseItem(QQmlDelegateModelItem *item, int newModelIndex, int newGroups);
void drainReusableItemsPool(int maxPoolTime);
QQmlComponent *resolveDelegate(int index);
void addGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags);
void removeGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags);
void setGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags);
void itemsInserted(
const QList<Compositor::Insert> &inserts,
QVarLengthArray<QList<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> *translatedInserts,
QHash<int, QList<QQmlDelegateModelItem *> > *movedItems = nullptr);
void itemsInserted(const QList<Compositor::Insert> &inserts);
void itemsRemoved(
const QList<Compositor::Remove> &removes,
QVarLengthArray<QList<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> *translatedRemoves,
QHash<int, QList<QQmlDelegateModelItem *> > *movedItems = nullptr);
void itemsRemoved(const QList<Compositor::Remove> &removes);
void itemsMoved(
const QList<Compositor::Remove> &removes, const QList<Compositor::Insert> &inserts);
void itemsChanged(const QList<Compositor::Change> &changes);
void emitChanges();
void emitModelUpdated(const QQmlChangeSet &changeSet, bool reset) override;
void delegateChanged(bool add = true, bool remove = true);
enum class InsertionResult {
Success,
Error,
Retry
};
InsertionResult insert(Compositor::insert_iterator &before, const QV4::Value &object, int groups);
int adaptorModelCount() const;
static void group_append(QQmlListProperty<QQmlDelegateModelGroup> *property, QQmlDelegateModelGroup *group);
static qsizetype group_count(QQmlListProperty<QQmlDelegateModelGroup> *property);
static QQmlDelegateModelGroup *group_at(QQmlListProperty<QQmlDelegateModelGroup> *property, qsizetype index);
void releaseIncubator(QQDMIncubationTask *incubationTask);
void incubatorStatusChanged(QQDMIncubationTask *incubationTask, QQmlIncubator::Status status);
void setInitialState(QQDMIncubationTask *incubationTask, QObject *o);
QQmlAdaptorModel m_adaptorModel;
QQmlListCompositor m_compositor;
QQmlStrongJSQObjectReference<QQmlComponent> m_delegate;
QQmlAbstractDelegateComponent *m_delegateChooser;
QMetaObject::Connection m_delegateChooserChanged;
QQmlRefPointer<QQmlDelegateModelItemMetaType> m_cacheMetaType;
QPointer<QQmlContext> m_context;
QQmlDelegateModelParts *m_parts;
QQmlDelegateModelGroupEmitterList m_pendingParts;
QList<QQmlDelegateModelItem *> m_cache;
QQmlReusableDelegateModelItemsPool m_reusableItemsPool;
QList<QQDMIncubationTask *> m_finishedIncubating;
QList<QByteArray> m_watchedRoles;
QString m_filterGroup;
int m_count;
int m_groupCount;
QQmlListCompositor::Group m_compositorGroup;
bool m_complete : 1;
bool m_delegateValidated : 1;
bool m_reset : 1;
bool m_transaction : 1;
bool m_incubatorCleanupScheduled : 1;
bool m_waitingToFetchMore : 1;
union {
struct {
QQmlDelegateModelGroup *m_cacheItems;
QQmlDelegateModelGroup *m_items;
QQmlDelegateModelGroup *m_persistedItems;
};
QQmlDelegateModelGroup *m_groups[Compositor::MaximumGroupCount];
};
};
class QQmlPartsModel : public QQmlInstanceModel, public QQmlDelegateModelGroupEmitter
{
Q_OBJECT
Q_PROPERTY(QString filterOnGroup READ filterGroup WRITE setFilterGroup NOTIFY filterGroupChanged RESET resetFilterGroup FINAL)
public:
QQmlPartsModel(QQmlDelegateModel *model, const QString &part, QObject *parent = nullptr);
~QQmlPartsModel();
QString filterGroup() const;
void setFilterGroup(const QString &group);
void resetFilterGroup();
void updateFilterGroup();
void updateFilterGroup(Compositor::Group group, const QQmlChangeSet &changeSet);
int count() const override;
bool isValid() const override;
QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) override;
ReleaseFlags release(QObject *item, ReusableFlag reusable = NotReusable) override;
QVariant variantValue(int index, const QString &role) override;
QList<QByteArray> watchedRoles() const { return m_watchedRoles; }
void setWatchedRoles(const QList<QByteArray> &roles) override;
QQmlIncubator::Status incubationStatus(int index) override;
int indexOf(QObject *item, QObject *objectContext) const override;
void emitModelUpdated(const QQmlChangeSet &changeSet, bool reset) override;
void createdPackage(int index, QQuickPackage *package) override;
void initPackage(int index, QQuickPackage *package) override;
void destroyingPackage(QQuickPackage *package) override;
Q_SIGNALS:
void filterGroupChanged();
private:
QQmlDelegateModel *m_model;
QMultiHash<QObject *, QQuickPackage *> m_packaged;
QString m_part;
QString m_filterGroup;
QList<QByteArray> m_watchedRoles;
QList<int> m_pendingPackageInitializations; // vector holds model indices
Compositor::Group m_compositorGroup;
bool m_inheritGroup;
bool m_modelUpdatePending = true;
};
class QMetaPropertyBuilder;
class QQmlDelegateModelPartsMetaObject : public QQmlOpenMetaObject
{
public:
QQmlDelegateModelPartsMetaObject(QObject *parent)
: QQmlOpenMetaObject(parent) {}
void propertyCreated(int, QMetaPropertyBuilder &) override;
QVariant initialValue(int) override;
};
class QQmlDelegateModelParts : public QObject
{
Q_OBJECT
public:
QQmlDelegateModelParts(QQmlDelegateModel *parent);
QQmlDelegateModel *model;
QList<QQmlPartsModel *> models;
};
class QQmlDelegateModelAttachedMetaObject final
: public QAbstractDynamicMetaObject,
public QQmlRefCounted<QQmlDelegateModelAttachedMetaObject>
{
public:
QQmlDelegateModelAttachedMetaObject(
QQmlDelegateModelItemMetaType *metaType, QMetaObject *metaObject);
~QQmlDelegateModelAttachedMetaObject();
void objectDestroyed(QObject *) override;
int metaCall(QObject *, QMetaObject::Call, int _id, void **) override;
private:
QQmlDelegateModelItemMetaType * const metaType;
QMetaObject * const metaObject;
const int memberPropertyOffset;
const int indexPropertyOffset;
};
QT_END_NAMESPACE
#endif