diff options
-rw-r--r-- | src/qml/types/qqmldelegatemodel.cpp | 61 | ||||
-rw-r--r-- | src/qml/types/qqmldelegatemodel_p_p.h | 2 | ||||
-rw-r--r-- | src/qml/util/qqmladaptormodel.cpp | 58 | ||||
-rw-r--r-- | src/qml/util/qqmladaptormodel_p.h | 9 |
4 files changed, 78 insertions, 52 deletions
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index d62cc5d334..deea6121f0 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -268,6 +268,7 @@ QQmlDelegateModel::QQmlDelegateModel(QQmlContext *ctxt, QObject *parent) QQmlDelegateModel::~QQmlDelegateModel() { Q_D(QQmlDelegateModel); + d->disconnectFromAbstractItemModel(); d->m_adaptorModel.setObject(nullptr, this); for (QQmlDelegateModelItem *cacheItem : qAsConst(d->m_cache)) { @@ -374,6 +375,54 @@ QVariant QQmlDelegateModel::model() const return d->m_adaptorModel.model(); } +void QQmlDelegateModelPrivate::connectToAbstractItemModel() +{ + Q_Q(QQmlDelegateModel); + if (!m_adaptorModel.adaptsAim()) + return; + + auto aim = m_adaptorModel.aim(); + + qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsInserted(QModelIndex,int,int)), + q, QQmlDelegateModel, SLOT(_q_rowsInserted(QModelIndex,int,int))); + qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), + q, QQmlDelegateModel, SLOT(_q_rowsRemoved(QModelIndex,int,int))); + qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), + q, QQmlDelegateModel, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); + qmlobject_connect(aim, QAbstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), + q, QQmlDelegateModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>))); + qmlobject_connect(aim, QAbstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), + q, QQmlDelegateModel, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int))); + qmlobject_connect(aim, QAbstractItemModel, SIGNAL(modelReset()), + q, QQmlDelegateModel, SLOT(_q_modelReset())); + qmlobject_connect(aim, QAbstractItemModel, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)), + q, QQmlDelegateModel, SLOT(_q_layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint))); +} + +void QQmlDelegateModelPrivate::disconnectFromAbstractItemModel() +{ + Q_Q(QQmlDelegateModel); + if (!m_adaptorModel.adaptsAim()) + return; + + auto aim = m_adaptorModel.aim(); + + QObject::disconnect(aim, SIGNAL(rowsInserted(QModelIndex,int,int)), + q, SLOT(_q_rowsInserted(QModelIndex,int,int))); + QObject::disconnect(aim, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), + q, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); + QObject::disconnect(aim, SIGNAL(rowsRemoved(QModelIndex,int,int)), + q, SLOT(_q_rowsRemoved(QModelIndex,int,int))); + QObject::disconnect(aim, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), + q, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>))); + QObject::disconnect(aim, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), + q, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int))); + QObject::disconnect(aim, SIGNAL(modelReset()), + q, SLOT(_q_modelReset())); + QObject::disconnect(aim, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)), + q, SLOT(_q_layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint))); +} + void QQmlDelegateModel::setModel(const QVariant &model) { Q_D(QQmlDelegateModel); @@ -381,7 +430,10 @@ void QQmlDelegateModel::setModel(const QVariant &model) if (d->m_complete) _q_itemsRemoved(0, d->m_count); + d->disconnectFromAbstractItemModel(); d->m_adaptorModel.setModel(model, this, d->m_context->engine()); + d->connectToAbstractItemModel(); + d->m_adaptorModel.replaceWatchedRoles(QList<QByteArray>(), d->m_watchedRoles); for (int i = 0; d->m_parts && i < d->m_parts->models.count(); ++i) { d->m_adaptorModel.replaceWatchedRoles( @@ -476,8 +528,12 @@ void QQmlDelegateModel::setRootIndex(const QVariant &root) if (changed || !d->m_adaptorModel.isValid()) { const int oldCount = d->m_count; d->m_adaptorModel.rootIndex = modelIndex; - if (!d->m_adaptorModel.isValid() && d->m_adaptorModel.aim()) // The previous root index was invalidated, so we need to reconnect the model. + if (!d->m_adaptorModel.isValid() && d->m_adaptorModel.aim()) { + // The previous root index was invalidated, so we need to reconnect the model. + d->disconnectFromAbstractItemModel(); d->m_adaptorModel.setModel(d->m_adaptorModel.list.list(), this, d->m_context->engine()); + d->connectToAbstractItemModel(); + } if (d->m_adaptorModel.canFetchMore()) d->m_adaptorModel.fetchMore(); if (d->m_complete) { @@ -1613,7 +1669,8 @@ void QQmlDelegateModel::_q_rowsAboutToBeRemoved(const QModelIndex &parent, int b if (index.parent() == parent && index.row() >= begin && index.row() <= end) { const int oldCount = d->m_count; d->m_count = 0; - d->m_adaptorModel.invalidateModel(this); + d->disconnectFromAbstractItemModel(); + d->m_adaptorModel.invalidateModel(); if (d->m_complete && oldCount > 0) { QVector<Compositor::Remove> removes; diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h index 0c24e79c1b..4c7069966b 100644 --- a/src/qml/types/qqmldelegatemodel_p_p.h +++ b/src/qml/types/qqmldelegatemodel_p_p.h @@ -262,6 +262,8 @@ public: void init(); void connectModel(QQmlAdaptorModel *model); + void connectToAbstractItemModel(); + void disconnectFromAbstractItemModel(); void requestMoreIfNecessary(); QObject *object(Compositor::Group group, int index, QQmlIncubator::IncubationMode incubationMode); diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp index faae38abec..24d9c14611 100644 --- a/src/qml/util/qqmladaptormodel.cpp +++ b/src/qml/util/qqmladaptormodel.cpp @@ -462,26 +462,8 @@ public: return model.aim()->columnCount(model.rootIndex); } - void cleanup(QQmlAdaptorModel &model, QQmlDelegateModel *vdm) const override + void cleanup(QQmlAdaptorModel &) const override { - QAbstractItemModel * const aim = model.aim(); - if (aim && vdm) { - QObject::disconnect(aim, SIGNAL(rowsInserted(QModelIndex,int,int)), - vdm, SLOT(_q_rowsInserted(QModelIndex,int,int))); - QObject::disconnect(aim, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - vdm, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); - QObject::disconnect(aim, SIGNAL(rowsRemoved(QModelIndex,int,int)), - vdm, SLOT(_q_rowsRemoved(QModelIndex,int,int))); - QObject::disconnect(aim, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), - vdm, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>))); - QObject::disconnect(aim, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), - vdm, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int))); - QObject::disconnect(aim, SIGNAL(modelReset()), - vdm, SLOT(_q_modelReset())); - QObject::disconnect(aim, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)), - vdm, SLOT(_q_layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint))); - } - const_cast<VDMAbstractItemModelDataType *>(this)->release(); } @@ -783,7 +765,7 @@ public: metaObject = builder.toMetaObject(); } - void cleanup(QQmlAdaptorModel &, QQmlDelegateModel *) const override + void cleanup(QQmlAdaptorModel &) const override { const_cast<VDMObjectDelegateDataType *>(this)->release(); } @@ -917,50 +899,34 @@ QQmlAdaptorModel::~QQmlAdaptorModel() accessors->cleanup(*this); } -void QQmlAdaptorModel::setModel(const QVariant &variant, QQmlDelegateModel *vdm, QQmlEngine *engine) +void QQmlAdaptorModel::setModel(const QVariant &variant, QObject *parent, QQmlEngine *engine) { - accessors->cleanup(*this, vdm); + accessors->cleanup(*this); list.setList(variant, engine); if (QObject *object = qvariant_cast<QObject *>(list.list())) { - setObject(object, vdm); - if (QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(object)) { + setObject(object, parent); + if (qobject_cast<QAbstractItemModel *>(object)) accessors = new VDMAbstractItemModelDataType(this); - - qmlobject_connect(model, QAbstractItemModel, SIGNAL(rowsInserted(QModelIndex,int,int)), - vdm, QQmlDelegateModel, SLOT(_q_rowsInserted(QModelIndex,int,int))); - qmlobject_connect(model, QAbstractItemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), - vdm, QQmlDelegateModel, SLOT(_q_rowsRemoved(QModelIndex,int,int))); - qmlobject_connect(model, QAbstractItemModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - vdm, QQmlDelegateModel, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); - qmlobject_connect(model, QAbstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), - vdm, QQmlDelegateModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>))); - qmlobject_connect(model, QAbstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), - vdm, QQmlDelegateModel, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int))); - qmlobject_connect(model, QAbstractItemModel, SIGNAL(modelReset()), - vdm, QQmlDelegateModel, SLOT(_q_modelReset())); - qmlobject_connect(model, QAbstractItemModel, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)), - vdm, QQmlDelegateModel, SLOT(_q_layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint))); - } else { + else accessors = new VDMObjectDelegateDataType; - } } else if (list.type() == QQmlListAccessor::ListProperty) { - setObject(static_cast<const QQmlListReference *>(variant.constData())->object(), vdm); + setObject(static_cast<const QQmlListReference *>(variant.constData())->object(), parent); accessors = new VDMObjectDelegateDataType; } else if (list.type() != QQmlListAccessor::Invalid && list.type() != QQmlListAccessor::Instance) { // Null QObject - setObject(nullptr, vdm); + setObject(nullptr, parent); accessors = &qt_vdm_list_accessors; } else { - setObject(nullptr, vdm); + setObject(nullptr, parent); accessors = &qt_vdm_null_accessors; } } -void QQmlAdaptorModel::invalidateModel(QQmlDelegateModel *vdm) +void QQmlAdaptorModel::invalidateModel() { - accessors->cleanup(*this, vdm); + accessors->cleanup(*this); accessors = &qt_vdm_null_accessors; // Don't clear the model object as we still need the guard to clear the list variant if the // object is destroyed. diff --git a/src/qml/util/qqmladaptormodel_p.h b/src/qml/util/qqmladaptormodel_p.h index af0917cf3b..b834704163 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 QQmlStrongJSQObjectReference<QObject> +class Q_QML_PRIVATE_EXPORT QQmlAdaptorModel : public QQmlStrongJSQObjectReference<QObject> { public: class Accessors @@ -78,7 +78,7 @@ public: virtual ~Accessors(); virtual int rowCount(const QQmlAdaptorModel &) const { return 0; } virtual int columnCount(const QQmlAdaptorModel &) const { return 0; } - virtual void cleanup(QQmlAdaptorModel &, QQmlDelegateModel * = nullptr) const {} + virtual void cleanup(QQmlAdaptorModel &) const {} virtual QVariant value(const QQmlAdaptorModel &, int, const QString &) const { return QVariant(); } @@ -114,8 +114,8 @@ public: ~QQmlAdaptorModel(); inline QVariant model() const { return list.list(); } - void setModel(const QVariant &variant, QQmlDelegateModel *vdm, QQmlEngine *engine); - void invalidateModel(QQmlDelegateModel *vdm); + void setModel(const QVariant &variant, QObject *parent, QQmlEngine *engine); + void invalidateModel(); bool isValid() const; int count() const; @@ -125,6 +125,7 @@ public: int columnAt(int index) const; int indexAt(int row, int column) const; + inline bool adaptsAim() const { return qobject_cast<QAbstractItemModel *>(object()); } inline QAbstractItemModel *aim() { return static_cast<QAbstractItemModel *>(object()); } inline const QAbstractItemModel *aim() const { return static_cast<const QAbstractItemModel *>(object()); } |