diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2020-03-10 15:09:37 +0100 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@qt.io> | 2020-03-12 15:03:03 +0100 |
commit | 26c5243491f495194f04b449128dae36118e28da (patch) | |
tree | 7fb14678a6fc9e44a10c9224d005e2cbdc6bcb63 /src/qmlmodels | |
parent | 1c7d264e3b2e9a2f0021786ea6967185f8282af0 (diff) | |
parent | c24c5baeda4101b0058689adf9200b77a722c3a2 (diff) |
Merge remote-tracking branch 'origin/dev' into wip/cmake
Conflicts:
dependencies.yaml
src/qml/qml/qqmlengine.cpp
Change-Id: I6a73fd1064286f4a2232de85c2ce7f80452d4641
Diffstat (limited to 'src/qmlmodels')
22 files changed, 153 insertions, 76 deletions
diff --git a/src/qmlmodels/dependencies.json b/src/qmlmodels/dependencies.json new file mode 100644 index 0000000000..0d4f101c7a --- /dev/null +++ b/src/qmlmodels/dependencies.json @@ -0,0 +1,2 @@ +[ +] diff --git a/src/qmlmodels/qmlmodels.pro b/src/qmlmodels/qmlmodels.pro index d3a7495599..34380ee14e 100644 --- a/src/qmlmodels/qmlmodels.pro +++ b/src/qmlmodels/qmlmodels.pro @@ -66,7 +66,7 @@ qtConfig(qml-delegate-model) { QMLTYPES_FILENAME = plugins.qmltypes QMLTYPES_INSTALL_DIR = $$[QT_INSTALL_QML]/QtQml/Models QML_IMPORT_NAME = QtQml.Models -IMPORT_VERSION = 2.15 +QML_IMPORT_VERSION = $$QT_VERSION CONFIG += qmltypes install_qmltypes install_metatypes load(qt_module) diff --git a/src/qmlmodels/qqmlabstractdelegatecomponent_p.h b/src/qmlmodels/qqmlabstractdelegatecomponent_p.h index 07cae6b092..853a7e8af8 100644 --- a/src/qmlmodels/qqmlabstractdelegatecomponent_p.h +++ b/src/qmlmodels/qqmlabstractdelegatecomponent_p.h @@ -65,6 +65,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlAbstractDelegateComponent : public QQmlComp { Q_OBJECT QML_NAMED_ELEMENT(AbstractDelegateComponent) + QML_ADDED_IN_VERSION(2, 0) QML_UNCREATABLE("Cannot create instance of abstract class AbstractDelegateComponent.") public: diff --git a/src/qmlmodels/qqmladaptormodel.cpp b/src/qmlmodels/qqmladaptormodel.cpp index fbb85327a7..8c8c37d237 100644 --- a/src/qmlmodels/qqmladaptormodel.cpp +++ b/src/qmlmodels/qqmladaptormodel.cpp @@ -93,7 +93,7 @@ class QQmlDMCachedModelData : public QQmlDelegateModelItem { public: QQmlDMCachedModelData( - QQmlDelegateModelItemMetaType *metaType, + const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType, VDMModelDelegateDataType *dataType, int index, int row, int column); @@ -255,7 +255,9 @@ public: bool hasModelData; }; -QQmlDMCachedModelData::QQmlDMCachedModelData(QQmlDelegateModelItemMetaType *metaType, VDMModelDelegateDataType *dataType, int index, int row, int column) +QQmlDMCachedModelData::QQmlDMCachedModelData( + const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType, + VDMModelDelegateDataType *dataType, int index, int row, int column) : QQmlDelegateModelItem(metaType, dataType, index, row, column) , type(dataType) { @@ -390,7 +392,7 @@ class QQmlDMAbstractItemModelData : public QQmlDMCachedModelData public: QQmlDMAbstractItemModelData( - QQmlDelegateModelItemMetaType *metaType, + const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType, VDMModelDelegateDataType *dataType, int index, int row, int column) : QQmlDMCachedModelData(metaType, dataType, index, row, column) @@ -458,7 +460,7 @@ public: void cleanup(QQmlAdaptorModel &) const override { - const_cast<VDMAbstractItemModelDataType *>(this)->release(); + release(); } QVariant value(const QQmlAdaptorModel &model, int index, const QString &role) const override @@ -512,7 +514,7 @@ public: QQmlDelegateModelItem *createItem( QQmlAdaptorModel &model, - QQmlDelegateModelItemMetaType *metaType, + const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType, int index, int row, int column) const override { VDMAbstractItemModelDataType *dataType = const_cast<VDMAbstractItemModelDataType *>(this); @@ -560,7 +562,7 @@ class QQmlDMListAccessorData : public QQmlDelegateModelItem Q_OBJECT Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged) public: - QQmlDMListAccessorData(QQmlDelegateModelItemMetaType *metaType, + QQmlDMListAccessorData(const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType, QQmlAdaptorModel::Accessors *accessor, int index, int row, int column, const QVariant &value) : QQmlDelegateModelItem(metaType, accessor, index, row, column) @@ -676,7 +678,7 @@ public: QQmlDelegateModelItem *createItem( QQmlAdaptorModel &model, - QQmlDelegateModelItemMetaType *metaType, + const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType, int index, int row, int column) const override { VDMListDelegateDataType *dataType = const_cast<VDMListDelegateDataType *>(this); @@ -719,7 +721,7 @@ class QQmlDMObjectData : public QQmlDelegateModelItem, public QQmlAdaptorModelPr Q_INTERFACES(QQmlAdaptorModelProxyInterface) public: QQmlDMObjectData( - QQmlDelegateModelItemMetaType *metaType, + const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType, VDMObjectDelegateDataType *dataType, int index, int row, int column, QObject *object); @@ -790,7 +792,7 @@ public: QQmlDelegateModelItem *createItem( QQmlAdaptorModel &model, - QQmlDelegateModelItemMetaType *metaType, + const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType, int index, int row, int column) const override { VDMObjectDelegateDataType *dataType = const_cast<VDMObjectDelegateDataType *>(this); @@ -930,7 +932,7 @@ public: VDMObjectDelegateDataType *m_type; }; -QQmlDMObjectData::QQmlDMObjectData(QQmlDelegateModelItemMetaType *metaType, +QQmlDMObjectData::QQmlDMObjectData(const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType, VDMObjectDelegateDataType *dataType, int index, int row, int column, QObject *object) @@ -975,6 +977,9 @@ void QQmlAdaptorModel::setModel(const QVariant &variant, QObject *parent, QQmlEn } else if (list.type() == QQmlListAccessor::ListProperty) { setObject(static_cast<const QQmlListReference *>(variant.constData())->object(), parent); accessors = new VDMObjectDelegateDataType; + } else if (list.type() == QQmlListAccessor::ObjectList) { + setObject(nullptr, parent); + accessors = new VDMObjectDelegateDataType; } else if (list.type() != QQmlListAccessor::Invalid && list.type() != QQmlListAccessor::Instance) { // Null QObject setObject(nullptr, parent); @@ -1030,9 +1035,9 @@ int QQmlAdaptorModel::indexAt(int row, int column) const return column * rowCount() + row; } -void QQmlAdaptorModel::useImportVersion(int minorVersion) +void QQmlAdaptorModel::useImportVersion(QTypeRevision revision) { - modelItemRevision = minorVersion; + modelItemRevision = revision; } void QQmlAdaptorModel::objectDestroyed(QObject *) diff --git a/src/qmlmodels/qqmladaptormodel_p.h b/src/qmlmodels/qqmladaptormodel_p.h index a4549127af..2c90ffc1d1 100644 --- a/src/qmlmodels/qqmladaptormodel_p.h +++ b/src/qmlmodels/qqmladaptormodel_p.h @@ -87,7 +87,7 @@ public: virtual QQmlDelegateModelItem *createItem( QQmlAdaptorModel &, - QQmlDelegateModelItemMetaType *, + const QQmlRefPointer<QQmlDelegateModelItemMetaType> &, int, int, int) const { return nullptr; } virtual bool notify( @@ -115,7 +115,7 @@ public: QPersistentModelIndex rootIndex; QQmlListAccessor list; - int modelItemRevision = 0; + QTypeRevision modelItemRevision = QTypeRevision::zero(); QQmlAdaptorModel(); ~QQmlAdaptorModel(); @@ -132,7 +132,7 @@ public: int columnAt(int index) const; int indexAt(int row, int column) const; - void useImportVersion(int minorVersion); + void useImportVersion(QTypeRevision revision); inline bool adaptsAim() const { return qobject_cast<QAbstractItemModel *>(object()); } inline QAbstractItemModel *aim() { return static_cast<QAbstractItemModel *>(object()); } @@ -140,10 +140,16 @@ public: inline QVariant value(int index, const QString &role) const { return accessors->value(*this, index, role); } - inline QQmlDelegateModelItem *createItem(QQmlDelegateModelItemMetaType *metaType, int index) { - return accessors->createItem(*this, metaType, index, rowAt(index), columnAt(index)); } + inline QQmlDelegateModelItem *createItem( + const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType, int index) + { + return accessors->createItem(*this, metaType, index, rowAt(index), columnAt(index)); + } inline bool hasProxyObject() const { - return list.type() == QQmlListAccessor::Instance || list.type() == QQmlListAccessor::ListProperty; } + return list.type() == QQmlListAccessor::Instance + || list.type() == QQmlListAccessor::ListProperty + || list.type() == QQmlListAccessor::ObjectList; + } inline bool notify( const QList<QQmlDelegateModelItem *> &items, diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp index 3a3903965c..3a05bf1689 100644 --- a/src/qmlmodels/qqmldelegatemodel.cpp +++ b/src/qmlmodels/qqmldelegatemodel.cpp @@ -731,7 +731,7 @@ QQmlListProperty<QQmlDelegateModelGroup> QQmlDelegateModel::groups() QQmlDelegateModelPrivate::group_append, QQmlDelegateModelPrivate::group_count, QQmlDelegateModelPrivate::group_at, - nullptr); + nullptr, nullptr, nullptr); } /*! @@ -1211,11 +1211,13 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ } Compositor::iterator it = m_compositor.find(group, index); + const auto flags = it->flags; + const auto modelIndex = it.modelIndex(); QQmlDelegateModelItem *cacheItem = it->inCache() ? m_cache.at(it.cacheIndex) : 0; if (!cacheItem || !cacheItem->delegate) { - QQmlComponent *delegate = resolveDelegate(it.modelIndex()); + QQmlComponent *delegate = resolveDelegate(modelIndex); if (!delegate) return nullptr; @@ -1226,17 +1228,17 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ // all related properties, and return the object (which // has already been incubated, otherwise it wouldn't be in the pool). addCacheItem(cacheItem, it); - reuseItem(cacheItem, index, it->flags); + reuseItem(cacheItem, index, flags); cacheItem->referenceObject(); return cacheItem->object; } // Since we could't find an available item in the pool, we create a new one - cacheItem = m_adaptorModel.createItem(m_cacheMetaType, it.modelIndex()); + cacheItem = m_adaptorModel.createItem(m_cacheMetaType, modelIndex); if (!cacheItem) return nullptr; - cacheItem->groups = it->flags; + cacheItem->groups = flags; addCacheItem(cacheItem, it); } @@ -2267,9 +2269,10 @@ void QV4::Heap::QQmlDelegateModelItemObject::destroy() } -QQmlDelegateModelItem::QQmlDelegateModelItem(QQmlDelegateModelItemMetaType *metaType, - QQmlAdaptorModel::Accessors *accessor, - int modelIndex, int row, int column) +QQmlDelegateModelItem::QQmlDelegateModelItem( + const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType, + QQmlAdaptorModel::Accessors *accessor, + int modelIndex, int row, int column) : v4(metaType->v4Engine) , metaType(metaType) , contextData(nullptr) @@ -2285,8 +2288,6 @@ QQmlDelegateModelItem::QQmlDelegateModelItem(QQmlDelegateModelItemMetaType *meta , row(row) , 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, @@ -2315,9 +2316,6 @@ QQmlDelegateModelItem::~QQmlDelegateModelItem() else delete incubationTask; } - - metaType->release(); - } void QQmlDelegateModelItem::Dispose() diff --git a/src/qmlmodels/qqmldelegatemodel_p.h b/src/qmlmodels/qqmldelegatemodel_p.h index adb5f7008b..f4578e130e 100644 --- a/src/qmlmodels/qqmldelegatemodel_p.h +++ b/src/qmlmodels/qqmldelegatemodel_p.h @@ -86,7 +86,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateModel : public QQmlInstanceModel, p Q_PROPERTY(QVariant rootIndex READ rootIndex WRITE setRootIndex NOTIFY rootIndexChanged) Q_CLASSINFO("DefaultProperty", "delegate") QML_NAMED_ELEMENT(DelegateModel) - QML_ADDED_IN_MINOR_VERSION(1) + QML_ADDED_IN_VERSION(2, 1) QML_ATTACHED(QQmlDelegateModelAttached) Q_INTERFACES(QQmlParserStatus) @@ -144,8 +144,6 @@ Q_SIGNALS: void defaultGroupsChanged(); void rootIndexChanged(); void delegateChanged(); - void itemPooled(int index, QObject *object); - void itemReused(int index, QObject *object); private Q_SLOTS: void _q_itemsChanged(int index, int count, const QVector<int> &roles); @@ -174,7 +172,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlDelegateModelGroup : public QObject Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(bool includeByDefault READ defaultInclude WRITE setDefaultInclude NOTIFY defaultIncludeChanged) QML_NAMED_ELEMENT(DelegateModelGroup) - QML_ADDED_IN_MINOR_VERSION(1) + QML_ADDED_IN_VERSION(2, 1) public: QQmlDelegateModelGroup(QObject *parent = nullptr); QQmlDelegateModelGroup(const QString &name, QQmlDelegateModel *model, int compositorType, QObject *parent = nullptr); diff --git a/src/qmlmodels/qqmldelegatemodel_p_p.h b/src/qmlmodels/qqmldelegatemodel_p_p.h index a1c4555d01..8684439508 100644 --- a/src/qmlmodels/qqmldelegatemodel_p_p.h +++ b/src/qmlmodels/qqmldelegatemodel_p_p.h @@ -100,11 +100,11 @@ class QQmlDelegateModelItem : public QObject { Q_OBJECT Q_PROPERTY(int index READ modelIndex NOTIFY modelIndexChanged) - Q_PROPERTY(int row READ modelRow NOTIFY rowChanged REVISION 12) - Q_PROPERTY(int column READ modelColumn NOTIFY columnChanged REVISION 12) + 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: - QQmlDelegateModelItem(QQmlDelegateModelItemMetaType *metaType, + QQmlDelegateModelItem(const QQmlRefPointer<QQmlDelegateModelItemMetaType> &metaType, QQmlAdaptorModel::Accessors *accessor, int modelIndex, int row, int column); ~QQmlDelegateModelItem(); @@ -148,7 +148,7 @@ public: static QV4::ReturnedValue get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg); QV4::ExecutionEngine *v4; - QQmlDelegateModelItemMetaType * const metaType; + QQmlRefPointer<QQmlDelegateModelItemMetaType> const metaType; QQmlContextDataRef contextData; QPointer<QObject> object; QPointer<QQmlDelegateModelAttached> attached; @@ -162,8 +162,8 @@ public: Q_SIGNALS: void modelIndexChanged(); - Q_REVISION(12) void rowChanged(); - Q_REVISION(12) void columnChanged(); + Q_REVISION(2, 12) void rowChanged(); + Q_REVISION(2, 12) void columnChanged(); protected: void objectDestroyed(QObject *); diff --git a/src/qmlmodels/qqmlinstantiator_p.h b/src/qmlmodels/qqmlinstantiator_p.h index 9f6d816d18..fec5c3888a 100644 --- a/src/qmlmodels/qqmlinstantiator_p.h +++ b/src/qmlmodels/qqmlinstantiator_p.h @@ -73,7 +73,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlInstantiator : public QObject, public QQmlP Q_PROPERTY(QObject *object READ object NOTIFY objectChanged) Q_CLASSINFO("DefaultProperty", "delegate") QML_NAMED_ELEMENT(Instantiator) - QML_ADDED_IN_MINOR_VERSION(1) + QML_ADDED_IN_VERSION(2, 1) public: QQmlInstantiator(QObject *parent = nullptr); diff --git a/src/qmlmodels/qqmllistaccessor.cpp b/src/qmlmodels/qqmllistaccessor.cpp index c450c616e7..69427df184 100644 --- a/src/qmlmodels/qqmllistaccessor.cpp +++ b/src/qmlmodels/qqmllistaccessor.cpp @@ -80,6 +80,8 @@ void QQmlListAccessor::setList(const QVariant &v, QQmlEngine *engine) m_type = StringList; } else if (d.userType() == QMetaType::QVariantList) { m_type = VariantList; + } else if (d.userType() == qMetaTypeId<QList<QObject *>>()) { + m_type = ObjectList; } else if (d.canConvert(QMetaType::Int)) { // Here we have to check for an upper limit, because down the line code might (well, will) // allocate memory depending on the number of elements. The upper limit cannot be INT_MAX: @@ -120,6 +122,8 @@ int QQmlListAccessor::count() const return qvariant_cast<QStringList>(d).count(); case VariantList: return qvariant_cast<QVariantList>(d).count(); + case ObjectList: + return qvariant_cast<QList<QObject *>>(d).count(); case ListProperty: return ((const QQmlListReference *)d.constData())->count(); case Instance: @@ -140,6 +144,8 @@ QVariant QQmlListAccessor::at(int idx) const return QVariant::fromValue(qvariant_cast<QStringList>(d).at(idx)); case VariantList: return qvariant_cast<QVariantList>(d).at(idx); + case ObjectList: + return QVariant::fromValue(qvariant_cast<QList<QObject *>>(d).at(idx)); case ListProperty: return QVariant::fromValue(((const QQmlListReference *)d.constData())->at(idx)); case Instance: diff --git a/src/qmlmodels/qqmllistaccessor_p.h b/src/qmlmodels/qqmllistaccessor_p.h index bcd079adef..a57e4173e3 100644 --- a/src/qmlmodels/qqmllistaccessor_p.h +++ b/src/qmlmodels/qqmllistaccessor_p.h @@ -70,7 +70,7 @@ public: int count() const; QVariant at(int) const; - enum Type { Invalid, StringList, VariantList, ListProperty, Instance, Integer }; + enum Type { Invalid, StringList, VariantList, ObjectList, ListProperty, Instance, Integer }; Type type() const { return m_type; } private: diff --git a/src/qmlmodels/qqmllistmodel.cpp b/src/qmlmodels/qqmllistmodel.cpp index 2c05b04429..e58fc19178 100644 --- a/src/qmlmodels/qqmllistmodel.cpp +++ b/src/qmlmodels/qqmllistmodel.cpp @@ -2786,10 +2786,12 @@ bool QQmlListModelParser::applyProperty( QV4::ScopedContext context(scope, QV4::QmlContext::create(v4->rootContext(), QQmlContextData::get(qmlContext(model->m_modelCache)), nullptr)); QV4::ScopedFunctionObject function(scope, QV4::FunctionObject::createScriptFunction(context, compilationUnit->runtimeFunctions[id])); - QV4::ReturnedValue result = function->call(v4->globalObject, nullptr, 0); - QJSValue v; - QJSValuePrivate::setValue(&v, v4, result); + QV4::ScopedValue result(scope, function->call(v4->globalObject, nullptr, 0)); + if (v4->hasException) + v4->catchException(); + else + QJSValuePrivate::setValue(&v, v4, result->asReturnedValue()); value.setValue<QJSValue>(v); } else { QByteArray script = scriptStr.toUtf8(); diff --git a/src/qmlmodels/qqmllistmodel_p.h b/src/qmlmodels/qqmllistmodel_p.h index dc5063eb97..bf4279cd05 100644 --- a/src/qmlmodels/qqmllistmodel_p.h +++ b/src/qmlmodels/qqmllistmodel_p.h @@ -82,8 +82,9 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlListModel : public QAbstractListModel Q_OBJECT Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(bool dynamicRoles READ dynamicRoles WRITE setDynamicRoles) - Q_PROPERTY(QObject *agent READ agent CONSTANT REVISION(14)) + Q_PROPERTY(QObject *agent READ agent CONSTANT REVISION(2, 14)) QML_NAMED_ELEMENT(ListModel) + QML_ADDED_IN_VERSION(2, 0) public: QQmlListModel(QObject *parent=nullptr); @@ -174,6 +175,7 @@ class QQmlListElement : public QObject { Q_OBJECT QML_NAMED_ELEMENT(ListElement) + QML_ADDED_IN_VERSION(2, 0) }; class QQmlListModelParser : public QQmlCustomParser diff --git a/src/qmlmodels/qqmllistmodelworkeragent_p.h b/src/qmlmodels/qqmllistmodelworkeragent_p.h index f65909dcec..1700ff755f 100644 --- a/src/qmlmodels/qqmllistmodelworkeragent_p.h +++ b/src/qmlmodels/qqmllistmodelworkeragent_p.h @@ -73,6 +73,7 @@ class QQmlListModelWorkerAgent : public QObject Q_PROPERTY(int count READ count) Q_PROPERTY(QV4::ExecutionEngine *engine READ engine WRITE setEngine NOTIFY engineChanged) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: QQmlListModelWorkerAgent(QQmlListModel *); diff --git a/src/qmlmodels/qqmlmodelsmodule_p.h b/src/qmlmodels/qqmlmodelsmodule_p.h index e3e43f3922..70268f53f2 100644 --- a/src/qmlmodels/qqmlmodelsmodule_p.h +++ b/src/qmlmodels/qqmlmodelsmodule_p.h @@ -67,7 +67,7 @@ struct QItemSelectionModelForeign Q_GADGET QML_FOREIGN(QItemSelectionModel) QML_NAMED_ELEMENT(ItemSelectionModel) - QML_ADDED_IN_MINOR_VERSION(2) + QML_ADDED_IN_VERSION(2, 2) }; #endif diff --git a/src/qmlmodels/qqmlobjectmodel.cpp b/src/qmlmodels/qqmlobjectmodel.cpp index 85e64cc2f9..dac868a0a2 100644 --- a/src/qmlmodels/qqmlobjectmodel.cpp +++ b/src/qmlmodels/qqmlobjectmodel.cpp @@ -91,6 +91,15 @@ public: static_cast<QQmlObjectModelPrivate *>(prop->data)->clear(); } + static void children_replace(QQmlListProperty<QObject> *prop, int index, QObject *item) { + static_cast<QQmlObjectModelPrivate *>(prop->data)->replace(index, item); + } + + static void children_removeLast(QQmlListProperty<QObject> *prop) { + auto data = static_cast<QQmlObjectModelPrivate *>(prop->data); + data->remove(data->children.count() - 1, 1); + } + void insert(int index, QObject *item) { Q_Q(QQmlObjectModel); children.insert(index, Item(item)); @@ -105,6 +114,18 @@ public: emit q->childrenChanged(); } + void replace(int index, QObject *item) { + Q_Q(QQmlObjectModel); + auto *attached = QQmlObjectModelAttached::properties(children.at(index).item); + attached->setIndex(-1); + children.replace(index, Item(item)); + QQmlObjectModelAttached::properties(children.at(index).item)->setIndex(index); + QQmlChangeSet changeSet; + changeSet.change(index, 1); + emit q->modelUpdated(changeSet, false); + emit q->childrenChanged(); + } + void move(int from, int to, int n) { Q_Q(QQmlObjectModel); if (from > to) { @@ -229,12 +250,13 @@ QQmlObjectModel::QQmlObjectModel(QObject *parent) QQmlListProperty<QObject> QQmlObjectModel::children() { Q_D(QQmlObjectModel); - return QQmlListProperty<QObject>(this, - d, - d->children_append, - d->children_count, - d->children_at, - d->children_clear); + return QQmlListProperty<QObject>(this, d, + QQmlObjectModelPrivate::children_append, + QQmlObjectModelPrivate::children_count, + QQmlObjectModelPrivate::children_at, + QQmlObjectModelPrivate::children_clear, + QQmlObjectModelPrivate::children_replace, + QQmlObjectModelPrivate::children_removeLast); } /*! diff --git a/src/qmlmodels/qqmlobjectmodel_p.h b/src/qmlmodels/qqmlobjectmodel_p.h index 6c68e55012..761e9c73ec 100644 --- a/src/qmlmodels/qqmlobjectmodel_p.h +++ b/src/qmlmodels/qqmlobjectmodel_p.h @@ -70,6 +70,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlInstanceModel : public QObject Q_PROPERTY(int count READ count NOTIFY countChanged) QML_ANONYMOUS + QML_ADDED_IN_VERSION(2, 0) public: enum ReusableFlag { @@ -104,6 +105,8 @@ Q_SIGNALS: void createdItem(int index, QObject *object); void initItem(int index, QObject *object); void destroyingItem(QObject *object); + Q_REVISION(2, 15) void itemPooled(int index, QObject *object); + Q_REVISION(2, 15) void itemReused(int index, QObject *object); protected: QQmlInstanceModel(QObjectPrivate &dd, QObject *parent = nullptr) @@ -123,7 +126,7 @@ class Q_QMLMODELS_PRIVATE_EXPORT QQmlObjectModel : public QQmlInstanceModel Q_PROPERTY(QQmlListProperty<QObject> children READ children NOTIFY childrenChanged DESIGNABLE false) Q_CLASSINFO("DefaultProperty", "children") QML_NAMED_ELEMENT(ObjectModel) - QML_ADDED_IN_MINOR_VERSION(1) + QML_ADDED_IN_VERSION(2, 1) QML_ATTACHED(QQmlObjectModelAttached) public: @@ -144,14 +147,14 @@ public: static QQmlObjectModelAttached *qmlAttachedProperties(QObject *obj); - Q_REVISION(3) Q_INVOKABLE QObject *get(int index) const; - Q_REVISION(3) Q_INVOKABLE void append(QObject *object); - Q_REVISION(3) Q_INVOKABLE void insert(int index, QObject *object); - Q_REVISION(3) Q_INVOKABLE void move(int from, int to, int n = 1); - Q_REVISION(3) Q_INVOKABLE void remove(int index, int n = 1); + Q_REVISION(2, 3) Q_INVOKABLE QObject *get(int index) const; + Q_REVISION(2, 3) Q_INVOKABLE void append(QObject *object); + Q_REVISION(2, 3) Q_INVOKABLE void insert(int index, QObject *object); + Q_REVISION(2, 3) Q_INVOKABLE void move(int from, int to, int n = 1); + Q_REVISION(2, 3) Q_INVOKABLE void remove(int index, int n = 1); public Q_SLOTS: - Q_REVISION(3) void clear(); + Q_REVISION(2, 3) void clear(); Q_SIGNALS: void childrenChanged(); diff --git a/src/qmlmodels/qqmltableinstancemodel.cpp b/src/qmlmodels/qqmltableinstancemodel.cpp index b4d1e61e31..8c034356f3 100644 --- a/src/qmlmodels/qqmltableinstancemodel.cpp +++ b/src/qmlmodels/qqmltableinstancemodel.cpp @@ -78,13 +78,14 @@ void QQmlTableInstanceModel::deleteModelItemLater(QQmlDelegateModelItem *modelIt QQmlTableInstanceModel::QQmlTableInstanceModel(QQmlContext *qmlContext, QObject *parent) : QQmlInstanceModel(*(new QObjectPrivate()), parent) , m_qmlContext(qmlContext) - , m_metaType(new QQmlDelegateModelItemMetaType(m_qmlContext->engine()->handle(), nullptr, QStringList())) + , m_metaType(new QQmlDelegateModelItemMetaType(m_qmlContext->engine()->handle(), nullptr, QStringList()), + QQmlRefPointer<QQmlDelegateModelItemMetaType>::Adopt) { } -void QQmlTableInstanceModel::useImportVersion(int minorVersion) +void QQmlTableInstanceModel::useImportVersion(QTypeRevision version) { - m_adaptorModel.useImportVersion(minorVersion); + m_adaptorModel.useImportVersion(version); } QQmlTableInstanceModel::~QQmlTableInstanceModel() @@ -149,7 +150,7 @@ QQmlDelegateModelItem *QQmlTableInstanceModel::resolveModelItem(int index) } // Create a new item from scratch - modelItem = m_adaptorModel.createItem(m_metaType, index); + modelItem = m_adaptorModel.createItem(m_metaType.data(), index); if (modelItem) { modelItem->delegate = delegate; m_modelItems.insert(index, modelItem); @@ -242,6 +243,25 @@ void QQmlTableInstanceModel::destroyModelItem(QQmlDelegateModelItem *modelItem) delete modelItem; } +void QQmlTableInstanceModel::dispose(QObject *object) +{ + Q_ASSERT(object); + auto modelItem = qvariant_cast<QQmlDelegateModelItem *>(object->property(kModelItemTag)); + Q_ASSERT(modelItem); + + modelItem->releaseObject(); + + // The item is not referenced by anyone + Q_ASSERT(!modelItem->isObjectReferenced()); + Q_ASSERT(!modelItem->isReferenced()); + + m_modelItems.remove(modelItem->index); + + emit destroyingItem(object); + delete object; + delete modelItem; +} + void QQmlTableInstanceModel::cancel(int index) { auto modelItem = m_modelItems.value(index); diff --git a/src/qmlmodels/qqmltableinstancemodel_p.h b/src/qmlmodels/qqmltableinstancemodel_p.h index d924455918..57b9b26e43 100644 --- a/src/qmlmodels/qqmltableinstancemodel_p.h +++ b/src/qmlmodels/qqmltableinstancemodel_p.h @@ -89,7 +89,7 @@ public: QQmlTableInstanceModel(QQmlContext *qmlContext, QObject *parent = nullptr); ~QQmlTableInstanceModel() override; - void useImportVersion(int minorVersion); + void useImportVersion(QTypeRevision version); int count() const override { return m_adaptorModel.count(); } int rows() const { return m_adaptorModel.rowCount(); } @@ -110,6 +110,7 @@ public: QObject *object(int index, QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested) override; ReleaseFlags release(QObject *object, ReusableFlag reusable = NotReusable) override; + void dispose(QObject *object); void cancel(int) override; void drainReusableItemsPool(int maxPoolTime) override; @@ -122,10 +123,6 @@ public: void setWatchedRoles(const QList<QByteArray> &) override { Q_UNREACHABLE(); } int indexOf(QObject *, QObject *) const override { Q_UNREACHABLE(); return 0; } -Q_SIGNALS: - void itemPooled(int index, QObject *object); - void itemReused(int index, QObject *object); - private: QQmlComponent *resolveDelegate(int index); @@ -133,7 +130,7 @@ private: QQmlAbstractDelegateComponent *m_delegateChooser = nullptr; QQmlComponent *m_delegate = nullptr; QPointer<QQmlContext> m_qmlContext; - QQmlDelegateModelItemMetaType *m_metaType; + QQmlRefPointer<QQmlDelegateModelItemMetaType> m_metaType; QHash<int, QQmlDelegateModelItem *> m_modelItems; QQmlReusableDelegateModelItemsPool m_reusableItemsPool; diff --git a/src/qmlmodels/qquickpackage.cpp b/src/qmlmodels/qquickpackage.cpp index 567381e5ab..42e7d0e09f 100644 --- a/src/qmlmodels/qquickpackage.cpp +++ b/src/qmlmodels/qquickpackage.cpp @@ -115,6 +115,14 @@ public: QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data); return list->count(); } + static void data_replace(QQmlListProperty<QObject> *prop, int index, QObject *o) { + QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data); + list->replace(index, DataGuard(o, list)); + } + static void data_removeLast(QQmlListProperty<QObject> *prop) { + QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data); + list->removeLast(); + } }; QHash<QObject *, QQuickPackageAttached *> QQuickPackageAttached::attached; @@ -152,10 +160,13 @@ QQuickPackage::~QQuickPackage() QQmlListProperty<QObject> QQuickPackage::data() { Q_D(QQuickPackage); - return QQmlListProperty<QObject>(this, &d->dataList, QQuickPackagePrivate::data_append, - QQuickPackagePrivate::data_count, - QQuickPackagePrivate::data_at, - QQuickPackagePrivate::data_clear); + return QQmlListProperty<QObject>(this, &d->dataList, + QQuickPackagePrivate::data_append, + QQuickPackagePrivate::data_count, + QQuickPackagePrivate::data_at, + QQuickPackagePrivate::data_clear, + QQuickPackagePrivate::data_replace, + QQuickPackagePrivate::data_removeLast); } bool QQuickPackage::hasPart(const QString &name) diff --git a/src/qmlmodels/qquickpackage_p.h b/src/qmlmodels/qquickpackage_p.h index 801b8d8409..f40ffe552a 100644 --- a/src/qmlmodels/qquickpackage_p.h +++ b/src/qmlmodels/qquickpackage_p.h @@ -67,6 +67,7 @@ class Q_AUTOTEST_EXPORT QQuickPackage : public QObject Q_CLASSINFO("DefaultProperty", "data") QML_NAMED_ELEMENT(Package) + QML_ADDED_IN_VERSION(2, 0) QML_ATTACHED(QQuickPackageAttached) Q_PROPERTY(QQmlListProperty<QObject> data READ data) diff --git a/src/qmlmodels/qtqmlmodelsglobal_p.h b/src/qmlmodels/qtqmlmodelsglobal_p.h index 145112c9c1..1a1157138d 100644 --- a/src/qmlmodels/qtqmlmodelsglobal_p.h +++ b/src/qmlmodels/qtqmlmodelsglobal_p.h @@ -58,4 +58,6 @@ #define Q_QMLMODELS_PRIVATE_EXPORT Q_QMLMODELS_EXPORT #define Q_QMLMODELS_AUTOTEST_EXPORT Q_AUTOTEST_EXPORT +void Q_QMLMODELS_PRIVATE_EXPORT qml_register_types_QtQml_Models(); + #endif // QTQMLMODELSGLOBAL_P_H |