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 ++ src/qml/util/qqmladaptormodel.cpp | 58 +++++++-------------------------- 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)), + 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); 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)), - vdm, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector))); - 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,QAbstractItemModel::LayoutChangeHint)), - vdm, SLOT(_q_layoutChanged(QList,QAbstractItemModel::LayoutChangeHint))); - } - const_cast(this)->release(); } @@ -783,7 +765,7 @@ public: metaObject = builder.toMetaObject(); } - void cleanup(QQmlAdaptorModel &, QQmlDelegateModel *) const override + void cleanup(QQmlAdaptorModel &) const override { const_cast(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(list.list())) { - setObject(object, vdm); - if (QAbstractItemModel *model = qobject_cast(object)) { + setObject(object, parent); + if (qobject_cast(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)), - vdm, QQmlDelegateModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector))); - 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,QAbstractItemModel::LayoutChangeHint)), - vdm, QQmlDelegateModel, SLOT(_q_layoutChanged(QList,QAbstractItemModel::LayoutChangeHint))); - } else { + else accessors = new VDMObjectDelegateDataType; - } } else if (list.type() == QQmlListAccessor::ListProperty) { - setObject(static_cast(variant.constData())->object(), vdm); + setObject(static_cast(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 +class Q_QML_PRIVATE_EXPORT QQmlAdaptorModel : public QQmlStrongJSQObjectReference { 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(object()); } inline QAbstractItemModel *aim() { return static_cast(object()); } inline const QAbstractItemModel *aim() const { return static_cast(object()); } -- cgit v1.2.3