From 67f0da5f285b0400bfa5aeda2d335da0668d1b27 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 22 Jun 2018 10:44:34 +0200 Subject: QQmlAdaptorModel: move connection set-up code to QQmlDelegateModel There is no need that QQmlAdaptorModel sets up the connection between QQmlDelegateModel and QAIM. QQmlDelegateModel can do this internally. This removes more of the dependency to QQmlDelegateModel, and will make it easier to reuse the class also for other models as well (first and foremost the upcoming QQmlTableInstanceModel). Change-Id: I957ac7bf85c6976ac79df0500a3c1ec3f8be42e2 Reviewed-by: Mitch Curtis --- src/qml/types/qqmldelegatemodel.cpp | 61 +++++++++++++++++++++++++++++++++-- src/qml/types/qqmldelegatemodel_p_p.h | 2 ++ 2 files changed, 61 insertions(+), 2 deletions(-) (limited to 'src/qml/types') 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)), + q, QQmlDelegateModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector))); + 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,QAbstractItemModel::LayoutChangeHint)), + q, QQmlDelegateModel, SLOT(_q_layoutChanged(QList,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)), + q, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector))); + 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,QAbstractItemModel::LayoutChangeHint)), + q, SLOT(_q_layoutChanged(QList,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(), 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 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); -- cgit v1.2.3