5#ifndef QQMLDATAMODEL_P_P_H
6#define QQMLDATAMODEL_P_P_H
9#include <private/qv4qobjectwrapper_p.h>
11#include <QtQml/qqmlcontext.h>
12#include <QtQml/qqmlincubator.h>
14#include <private/qqmladaptormodel_p.h>
15#include <private/qqmlopenmetaobject_p.h>
17#include <QtCore/qloggingcategory.h>
18#include <QtCore/qpointer.h>
39class QQmlDelegateModelAttachedMetaObject;
40class QQmlAbstractDelegateComponent;
41class QQmlTableInstanceModel;
43class Q_QMLMODELS_EXPORT QQmlDelegateModelItemMetaType final
44 :
public QQmlRefCounted<QQmlDelegateModelItemMetaType>
47 enum class ModelKind : quint8 {
53 QQmlDelegateModelItemMetaType(
54 QV4::ExecutionEngine *engine, QQmlDelegateModel *model,
const QStringList &groupNames);
55 QQmlDelegateModelItemMetaType(
56 QV4::ExecutionEngine *engine, QQmlTableInstanceModel *model);
57 ~QQmlDelegateModelItemMetaType();
59 void initializeAttachedMetaObject();
60 void initializePrototype();
62 int parseGroups(
const QStringList &groupNames)
const;
63 int parseGroups(
const QV4::Value &groupNames)
const;
65 QQmlDelegateModel *delegateModel()
const
67 return modelKind == ModelKind::DelegateModel
68 ?
static_cast<QQmlDelegateModel *>(model.get())
72 qsizetype groupCount()
const {
return groupNames.size(); }
74 void emitModelChanged()
const;
76 QPointer<QQmlInstanceModel> model;
77 QV4::ExecutionEngine *
const v4Engine;
78 QQmlRefPointer<QQmlDelegateModelAttachedMetaObject> attachedMetaObject;
79 const QStringList groupNames;
80 QV4::PersistentValue modelItemProto;
81 ModelKind modelKind = ModelKind::InstanceModel;
84class QQmlAdaptorModel;
90 Q_PROPERTY(
int index READ modelIndex NOTIFY modelIndexChanged)
148 QQmlAdaptorModel::Accessors *accessor,
int modelIndex,
149 int row,
int column);
161 if (m_objectWeakRef > 0)
172 return m_objectWeakRef != 0
173 || m_objectStrongRef != 0
174 || (m_groups & Compositor::PersistedFlag);
181 || ((m_groups & Compositor::UnresolvedFlag) && (m_groups & Compositor::GroupMask));
199 virtual void setModelIndex(
int idx,
int newRow,
int newColumn,
bool alwaysEmit =
false);
205 virtual void setValue(
const QString &role,
const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); }
206 virtual bool resolveIndex(
const QQmlAdaptorModel &,
int) {
return false; }
209 static QV4::
ReturnedValue get_model(
const QV4::FunctionObject *,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc);
210 static QV4::
ReturnedValue get_groups(
const QV4::FunctionObject *,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc);
211 static QV4::
ReturnedValue set_groups(
const QV4::FunctionObject *,
const QV4::Value *thisObject,
const QV4::Value *argv,
int argc);
222 QQmlData *ddata = QQmlData::get(m_object);
223 if (!ddata || !ddata->hasExtendedData())
227 ddata->attachedProperties()->value(
228 QQmlPrivate::attachedPropertiesFunc<QQmlDelegateModel>()));
235 return std::exchange(d_ptr->metaObject, metaObject);
242 Q_ASSERT(!m_incubationTask);
243 Q_ASSERT(incubationTask);
244 m_incubationTask = incubationTask;
259 void setDelegate(QQmlComponent *delegate) { m_delegate = delegate; }
264 m_contextData = contextData;
281 void objectDestroyed(QObject *);
283 void referenceSript() { ++m_scriptRef; }
286 Q_ASSERT(m_scriptRef > 0);
287 return --m_scriptRef == 0;
290 QQmlRefPointer<QQmlDelegateModelItemMetaType> m_metaType;
291 QQmlRefPointer<QQmlContextData> m_contextData;
292 QPointer<QObject> m_object;
294 QQmlComponent *m_delegate =
nullptr;
303 quint16 m_objectStrongRef = 0;
310 quint16 m_objectWeakRef = 0;
322 quint16 m_scriptRef = 0;
324 bool m_useStructuredModelData =
true;
337 return reinterpret_cast<
const QQmlDelegateModelItem::ScriptReference *>(&ref)->data();
353 new (ref) QQmlDelegateModelItem::ScriptReference(modelItem);
362 void drain(
int maxPoolTime, std::function<
void(QQmlDelegateModelItem *cacheItem)> releaseItem);
365 Q_ASSERT(m_reusableItemsPool.size() <= MaxSize);
366 return int(m_reusableItemsPool.size());
376 static constexpr size_t MaxSize = size_t(std::numeric_limits<
int>::max());
378 std::vector<PoolItem> m_reusableItemsPool;
381template<
typename Target>
425 QDynamicMetaObjectData *original =
nullptr;
426 int readOnlyProperty = -1;
440 QQmlDelegateModel::DelegateModelAccess access);
469 Q_DECLARE_PUBLIC(QQmlDelegateModelGroup)
482 void initPackage(
int index, QQuickPackage *package);
485 bool parseIndex(
const QV4::Value &value,
int *index, Compositor::Group *group)
const;
487 QQmlV4FunctionPtr args, Compositor::Group *group,
int *index,
int *count,
int *groups)
const;
501 Q_DECLARE_PUBLIC(QQmlDelegateModel)
507 return static_cast<QQmlDelegateModelPrivate *>(QObjectPrivate::get(m));
516 QObject *
object(Compositor::Group group,
int index, QQmlIncubator::IncubationMode incubationMode);
522 Q_EMIT q_func()->createdItem(incubationTask->index[m_compositorGroup], item); }
524 Q_EMIT q_func()->initItem(incubationTask->index[m_compositorGroup], item); }
536 void addGroups(Compositor::iterator from,
int count, Compositor::Group group,
int groupFlags);
537 void removeGroups(Compositor::iterator from,
int count, Compositor::Group group,
int groupFlags);
538 void setGroups(Compositor::iterator from,
int count, Compositor::Group group,
int groupFlags);
541 const QList<Compositor::Insert> &inserts,
542 QVarLengthArray<QList<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> *translatedInserts,
543 QHash<
int, QList<QQmlDelegateModelItem *> > *movedItems =
nullptr);
544 void itemsInserted(
const QList<Compositor::Insert> &inserts);
546 const QList<Compositor::Remove> &removes,
547 QVarLengthArray<QList<QQmlChangeSet::Change>, Compositor::MaximumGroupCount> *translatedRemoves,
548 QHash<
int, QList<QQmlDelegateModelItem *> > *movedItems =
nullptr);
549 void itemsRemoved(
const QList<Compositor::Remove> &removes);
551 const QList<Compositor::Remove> &removes,
const QList<Compositor::Insert> &inserts);
552 void itemsChanged(
const QList<Compositor::Change> &changes);
566 static void group_append(QQmlListProperty<QQmlDelegateModelGroup> *property, QQmlDelegateModelGroup *group);
568 static QQmlDelegateModelGroup *
group_at(QQmlListProperty<QQmlDelegateModelGroup> *property, qsizetype index);
608 QQmlDelegateModelGroup *
m_groups[Compositor::MaximumGroupCount];
615 Q_PROPERTY(QString filterOnGroup READ filterGroup WRITE setFilterGroup NOTIFY filterGroupChanged RESET resetFilterGroup FINAL)
635 int indexOf(QObject *item, QObject *objectContext)
const override;
640 void initPackage(
int index, QQuickPackage *package)
override;
647 QQmlDelegateModel *m_model;
648 QMultiHash<QObject *, QQuickPackage *> m_packaged;
650 QString m_filterGroup;
651 QList<QByteArray> m_watchedRoles;
652 QList<
int> m_pendingPackageInitializations;
653 Compositor::Group m_compositorGroup;
655 bool m_modelUpdatePending =
true;
658class QMetaPropertyBuilder;
680class QQmlDelegateModelAttachedMetaObject
final
681 :
public QAbstractDynamicMetaObject,
682 public QQmlRefCounted<QQmlDelegateModelAttachedMetaObject>
686 QQmlDelegateModelItemMetaType *metaType, QMetaObject *metaObject);
693 QQmlDelegateModelItemMetaType *
const metaType;
694 QMetaObject *
const metaObject;
695 const int memberPropertyOffset;
696 const int indexPropertyOffset;
void initializeRequiredProperties(QQmlDelegateModelItem *modelItemToIncubate, QObject *object, QQmlDelegateModel::DelegateModelAccess access)
QPointer< QObject > proxiedObject
QQmlRefPointer< QQmlContextData > proxyContext
void statusChanged(Status) override
Called when the status of the incubator changes.
void setInitialState(QObject *) override
Called after the object is first created, but before complex property bindings are evaluated and,...
int index[QQmlListCompositor::MaximumGroupCount]
QQmlDelegateModelItem * incubating
QQDMIncubationTask(QQmlDelegateModelPrivate *l, IncubationMode mode)
QQmlDelegateModelPrivate * vdm
QQmlDelegateModelAttached(QQmlDelegateModelItem *cacheItem, QObject *parent)
void setInItems(bool inItems)
void setGroups(const QStringList &groups)
bool isUnresolved() const
\qmlattachedproperty bool QtQml.Models::DelegateModel::isUnresolved
void emitChanges()
\qmlattachedproperty bool QtQml.Models::DelegateModel::inItems
void setInPersistedItems(bool inPersisted)
~QQmlDelegateModelAttached()
QQmlDelegateModel * model() const
\qmlattachedproperty model QtQml.Models::DelegateModel::model
QStringList groups() const
\qmlattachedproperty stringlist QtQml.Models::DelegateModel::groups
int persistedItemsIndex() const
QQmlDelegateModelItem * m_cacheItem
bool inPersistedItems() const
~QQmlDelegateModelEngineData()
QV4::PersistentValue changeProto
QV4::ReturnedValue array(QV4::ExecutionEngine *engine, const QList< QQmlChangeSet::Change > &changes)
QQmlDelegateModelEngineData(QV4::ExecutionEngine *v4)
virtual void initPackage(int, QQuickPackage *)
virtual void destroyingPackage(QQuickPackage *)
virtual ~QQmlDelegateModelGroupEmitter()
virtual void emitModelUpdated(const QQmlChangeSet &changeSet, bool reset)=0
virtual void createdPackage(int, QQuickPackage *)
QIntrusiveListNode emitterNode
bool parseIndex(const QV4::Value &value, int *index, Compositor::Group *group) const
void createdPackage(int index, QQuickPackage *package)
QPointer< QQmlDelegateModel > model
bool parseGroupArgs(QQmlV4FunctionPtr args, Compositor::Group *group, int *index, int *count, int *groups) const
bool isChangedConnected()
void initPackage(int index, QQuickPackage *package)
void emitModelUpdated(bool reset)
QQmlDelegateModelGroupEmitterList emitters
void destroyingPackage(QQuickPackage *package)
void emitChanges(QV4::ExecutionEngine *engine)
const QQmlRefPointer< QQmlDelegateModelItemMetaType > & metaType() const
void destroyObjectLater()
void disableStructuredModelData()
void setObject(QObject *object)
void setContextData(const QQmlRefPointer< QQmlContextData > &contextData)
static QV4::ReturnedValue set_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg)
quint16 scriptRef() const
void childContextObjectDestroyed(QObject *childContextObject)
virtual void setValue(const QString &role, const QVariant &value)
quint16 objectStrongRef() const
virtual QV4::ReturnedValue get()
quint16 objectWeakRef() const
static QV4::ReturnedValue get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &)
bool isScriptReferenced() const
static QV4::ReturnedValue get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg)
bool hasValidModelIndex() const
static QV4::ReturnedValue get_groups(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
int groupIndex(Compositor::Group group)
void addGroups(int groups)
QDynamicMetaObjectData * exchangeMetaObject(QDynamicMetaObjectData *metaObject)
virtual bool resolveIndex(const QQmlAdaptorModel &, int)
QQmlComponent * delegate() const
void setGroups(int groups)
void setDelegate(QQmlComponent *delegate)
void removeGroups(int groups)
void setIncubationTask(QQDMIncubationTask *incubationTask)
static QQmlDelegateModelItem * dataForObject(QObject *object)
static QV4::ReturnedValue get_model(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
virtual void setModelIndex(int idx, int newRow, int newColumn, bool alwaysEmit=false)
virtual QQmlRefPointer< QQmlContextData > initProxy()
QObject * referenceObjectWeak()
bool isObjectReferenced() const
void clearObjectWeakReferences()
QQmlDelegateModelItem(const QQmlRefPointer< QQmlDelegateModelItemMetaType > &metaType, QQmlAdaptorModel::Accessors *accessor, int modelIndex, int row, int column)
bool usesStructuredModelData() const
void clearIncubationTask()
QQmlDelegateModelAttached * attached() const
static QV4::ReturnedValue set_groups(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
const QQmlRefPointer< QQmlContextData > & contextData() const
QQDMIncubationTask * incubationTask() const
Q_REVISION(2, 12) void rowChanged()
QList< QQmlPartsModel * > models
QQmlDelegateModel * model
void setInitialState(QQDMIncubationTask *incubationTask, QObject *o)
void removeCacheItem(QQmlDelegateModelItem *cacheItem)
QVariant variantValue(Compositor::Group group, int index, const QString &name)
bool m_incubatorCleanupScheduled
void emitCreatedPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package)
QList< QQDMIncubationTask * > m_finishedIncubating
void connectModel(QQmlAdaptorModel *model)
QList< QQmlDelegateModelItem * > m_cache
void itemsMoved(const QList< Compositor::Remove > &removes, const QList< Compositor::Insert > &inserts)
QQmlDelegateModelParts * m_parts
static qsizetype group_count(QQmlListProperty< QQmlDelegateModelGroup > *property)
QList< QByteArray > m_watchedRoles
QQmlAbstractDelegateComponent * m_delegateChooser
QPointer< QQmlContext > m_context
void itemsInserted(const QList< Compositor::Insert > &inserts)
void emitCreatedItem(QQDMIncubationTask *incubationTask, QObject *item)
void emitInitItem(QQDMIncubationTask *incubationTask, QObject *item)
static void group_append(QQmlListProperty< QQmlDelegateModelGroup > *property, QQmlDelegateModelGroup *group)
QQmlStrongJSQObjectReference< QQmlComponent > m_delegate
void emitDestroyingItem(QObject *item)
void addCacheItem(QQmlDelegateModelItem *item, Compositor::iterator it)
QQmlRefPointer< QQmlDelegateModelItemMetaType > m_cacheMetaType
void reuseItem(QQmlDelegateModelItem *item, int newModelIndex, int newGroups)
void drainReusableItemsPool(int maxPoolTime)
QQmlDelegateModelGroup * m_persistedItems
static QQmlDelegateModelGroup * group_at(QQmlListProperty< QQmlDelegateModelGroup > *property, qsizetype index)
void itemsRemoved(const QList< Compositor::Remove > &removes, QVarLengthArray< QList< QQmlChangeSet::Change >, Compositor::MaximumGroupCount > *translatedRemoves, QHash< int, QList< QQmlDelegateModelItem * > > *movedItems=nullptr)
QQmlDelegateModelGroupEmitterList m_pendingParts
void emitModelUpdated(const QQmlChangeSet &changeSet, bool reset) override
QQmlDelegateModelGroup * m_cacheItems
QObject * object(Compositor::Group group, int index, QQmlIncubator::IncubationMode incubationMode)
void destroyCacheItem(QQmlDelegateModelItem *cacheItem)
void itemsRemoved(const QList< Compositor::Remove > &removes)
void connectToAbstractItemModel()
int adaptorModelCount() const
InsertionResult insert(Compositor::insert_iterator &before, const QV4::Value &object, int groups)
void setGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags)
void delegateChanged(bool add=true, bool remove=true)
QQmlListCompositor m_compositor
QQmlDelegateModelGroup * m_items
void releaseIncubator(QQDMIncubationTask *incubationTask)
bool m_waitingToFetchMore
void itemsInserted(const QList< Compositor::Insert > &inserts, QVarLengthArray< QList< QQmlChangeSet::Change >, Compositor::MaximumGroupCount > *translatedInserts, QHash< int, QList< QQmlDelegateModelItem * > > *movedItems=nullptr)
void incubatorStatusChanged(QQDMIncubationTask *incubationTask, QQmlIncubator::Status status)
void emitInitPackage(QQDMIncubationTask *incubationTask, QQuickPackage *package)
void addGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags)
void emitDestroyingPackage(QQuickPackage *package)
void requestMoreIfNecessary()
QQmlComponent * resolveDelegate(int index)
QMetaObject::Connection m_delegateChooserChanged
QQmlDelegateModelGroup * m_groups[Compositor::MaximumGroupCount]
void removeGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags)
void itemsChanged(const QList< Compositor::Change > &changes)
void disconnectFromAbstractItemModel()
QQmlReusableDelegateModelItemsPool m_reusableItemsPool
QQmlAdaptorModel m_adaptorModel
~QQmlDelegateModelPrivate()
QQmlListCompositor::Group m_compositorGroup
static QQmlDelegateModelPrivate * get(QQmlDelegateModel *m)
void emitModelUpdated(const QQmlChangeSet &changeSet, bool reset) override
QVariant variantValue(int index, const QString &role) override
int count() const override
QObject * object(int index, QQmlIncubator::IncubationMode incubationMode=QQmlIncubator::AsynchronousIfNested) override
QList< QByteArray > watchedRoles() const
void updateFilterGroup(Compositor::Group group, const QQmlChangeSet &changeSet)
void setFilterGroup(const QString &group)
QQmlIncubator::Status incubationStatus(int index) override
int indexOf(QObject *item, QObject *objectContext) const override
void destroyingPackage(QQuickPackage *package) override
void setWatchedRoles(const QList< QByteArray > &roles) override
ReleaseFlags release(QObject *item, ReusableFlag reusable=NotReusable) override
void createdPackage(int index, QQuickPackage *package) override
void initPackage(int index, QQuickPackage *package) override
QString filterGroup() const
bool isValid() const override
bool insertItem(QQmlDelegateModelItem *modelItem)
void reuseItem(QQmlDelegateModelItem *item, int newModelIndex)
void drain(int maxPoolTime, std::function< void(QQmlDelegateModelItem *cacheItem)> releaseItem)
QQmlDelegateModelItem * takeItem(const QQmlComponent *delegate, int newIndexHint)
Combined button and popup list for selecting options.
QT_REQUIRE_CONFIG(animation)
QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcQIORing)
QT_REQUIRE_CONFIG(qml_delegate_model)
static bool isDoneIncubating(QQmlIncubator::Status status)
DEFINE_OBJECT_VTABLE(QQmlDelegateModelGroupChange)
DEFINE_OBJECT_VTABLE(QV4::DelegateModelGroupFunction)
DEFINE_OBJECT_VTABLE(QQmlDelegateModelItemObject)
static void incrementIndexes(QQmlDelegateModelItem *cacheItem, int count, const int *deltas)
DEFINE_OBJECT_VTABLE(QQmlDelegateModelGroupChangeArray)
QQmlDelegateModelGroupEmitterList::iterator GroupEmitterListIt
QIntrusiveList< QQmlDelegateModelGroupEmitter, &QQmlDelegateModelGroupEmitter::emitterNode > QQmlDelegateModelGroupEmitterList
QT_BEGIN_NAMESPACE typedef QQmlListCompositor Compositor
void init(ExecutionEngine *engine, uint flag, QV4::ReturnedValue(*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg))
QV4::ReturnedValue(* code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg)
void init(const QList< QQmlChangeSet::Change > &changes)
QList< QQmlChangeSet::Change > * changes
QQmlChangeSet::ChangeData change
QQmlDelegateModelItem * item() const
void init(QQmlDelegateModelItem *item)
std::byte ref[sizeof(QQmlDelegateModelItem::ScriptReference)]