diff options
author | Andrew den Exter <andrew.den-exter@nokia.com> | 2012-07-27 12:33:27 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-08-02 02:43:36 +0200 |
commit | f915ea135fe4bf74432ffa3e6041ea60d4268c67 (patch) | |
tree | eb10268a72d7e4494e7b02c215bc62d42fd82aa1 /src | |
parent | 8dabc28e4ea6fe7946ee7770ba39410c6d95bc1d (diff) |
Fix handling of changes to the root index of a VisualDataModel.
Store the root index as a QPersistentModelIndex so the index remains
valid as the model changes, and in the case the root index is
removed from the model invalidate the contents of the VisualDataModel
until a new root index or model is set.
Change-Id: I1cbc27f2068f99a02ff3d43373905dec7e35e900
Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/items/qquickvisualadaptormodel.cpp | 17 | ||||
-rw-r--r-- | src/quick/items/qquickvisualadaptormodel_p.h | 5 | ||||
-rw-r--r-- | src/quick/items/qquickvisualdatamodel.cpp | 30 | ||||
-rw-r--r-- | src/quick/items/qquickvisualdatamodel_p.h | 1 |
4 files changed, 49 insertions, 4 deletions
diff --git a/src/quick/items/qquickvisualadaptormodel.cpp b/src/quick/items/qquickvisualadaptormodel.cpp index b17ab26373..5076d84b81 100644 --- a/src/quick/items/qquickvisualadaptormodel.cpp +++ b/src/quick/items/qquickvisualadaptormodel.cpp @@ -459,6 +459,8 @@ public: 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>)), @@ -898,6 +900,8 @@ void QQuickVisualAdaptorModel::setModel(const QVariant &variant, QQuickVisualDat vdm, QQuickVisualDataModel, SLOT(_q_rowsInserted(QModelIndex,int,int))); qmlobject_connect(model, QAbstractItemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), vdm, QQuickVisualDataModel, SLOT(_q_rowsRemoved(QModelIndex,int,int))); + qmlobject_connect(model, QAbstractItemModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), + vdm, QQuickVisualDataModel, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); qmlobject_connect(model, QAbstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), vdm, QQuickVisualDataModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>))); qmlobject_connect(model, QAbstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), @@ -922,6 +926,19 @@ void QQuickVisualAdaptorModel::setModel(const QVariant &variant, QQuickVisualDat } } +void QQuickVisualAdaptorModel::invalidateModel(QQuickVisualDataModel *vdm) +{ + accessors->cleanup(*this, vdm); + 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. +} + +bool QQuickVisualAdaptorModel::isValid() const +{ + return accessors != &qt_vdm_null_accessors; +} + void QQuickVisualAdaptorModel::objectDestroyed(QObject *) { setModel(QVariant(), 0, 0); diff --git a/src/quick/items/qquickvisualadaptormodel_p.h b/src/quick/items/qquickvisualadaptormodel_p.h index d1b66a9963..ff42c4908d 100644 --- a/src/quick/items/qquickvisualadaptormodel_p.h +++ b/src/quick/items/qquickvisualadaptormodel_p.h @@ -96,7 +96,7 @@ public: }; const Accessors *accessors; - QModelIndex rootIndex; + QPersistentModelIndex rootIndex; QQuickListAccessor list; QQuickVisualAdaptorModel(); @@ -104,6 +104,9 @@ public: inline QVariant model() const { return list.list(); } void setModel(const QVariant &variant, QQuickVisualDataModel *vdm, QQmlEngine *engine); + void invalidateModel(QQuickVisualDataModel *vdm); + + bool isValid() const; inline QAbstractItemModel *aim() { return static_cast<QAbstractItemModel *>(object()); } inline const QAbstractItemModel *aim() const { return static_cast<const QAbstractItemModel *>(object()); } diff --git a/src/quick/items/qquickvisualdatamodel.cpp b/src/quick/items/qquickvisualdatamodel.cpp index 92cce3238e..2ce6ead7f3 100644 --- a/src/quick/items/qquickvisualdatamodel.cpp +++ b/src/quick/items/qquickvisualdatamodel.cpp @@ -391,7 +391,7 @@ void QQuickVisualDataModel::setDelegate(QQmlComponent *delegate) QVariant QQuickVisualDataModel::rootIndex() const { Q_D(const QQuickVisualDataModel); - return QVariant::fromValue(d->m_adaptorModel.rootIndex); + return QVariant::fromValue(QModelIndex(d->m_adaptorModel.rootIndex)); } void QQuickVisualDataModel::setRootIndex(const QVariant &root) @@ -399,9 +399,12 @@ void QQuickVisualDataModel::setRootIndex(const QVariant &root) Q_D(QQuickVisualDataModel); QModelIndex modelIndex = qvariant_cast<QModelIndex>(root); - if (d->m_adaptorModel.rootIndex != modelIndex) { + const bool changed = d->m_adaptorModel.rootIndex != modelIndex; + 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. + d->m_adaptorModel.setModel(d->m_adaptorModel.list.list(), this, d->m_context->engine()); if (d->m_adaptorModel.canFetchMore()) d->m_adaptorModel.fetchMore(); if (d->m_complete) { @@ -411,7 +414,8 @@ void QQuickVisualDataModel::setRootIndex(const QVariant &root) if (newCount) _q_itemsInserted(0, newCount); } - emit rootIndexChanged(); + if (changed) + emit rootIndexChanged(); } } @@ -1433,6 +1437,26 @@ void QQuickVisualDataModel::_q_rowsInserted(const QModelIndex &parent, int begin _q_itemsInserted(begin, end - begin + 1); } +void QQuickVisualDataModel::_q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end) +{ + Q_D(QQuickVisualDataModel); + if (!d->m_adaptorModel.rootIndex.isValid()) + return; + const QModelIndex index = d->m_adaptorModel.rootIndex; + 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); + + if (d->m_complete && oldCount > 0) { + QVector<Compositor::Remove> removes; + d->m_compositor.listItemsRemoved(&d->m_adaptorModel, 0, oldCount, &removes); + d->itemsRemoved(removes); + d->emitChanges(); + } + } +} + void QQuickVisualDataModel::_q_rowsRemoved(const QModelIndex &parent, int begin, int end) { Q_D(QQuickVisualDataModel); diff --git a/src/quick/items/qquickvisualdatamodel_p.h b/src/quick/items/qquickvisualdatamodel_p.h index 1a8541f43c..8c52a2c9ef 100644 --- a/src/quick/items/qquickvisualdatamodel_p.h +++ b/src/quick/items/qquickvisualdatamodel_p.h @@ -137,6 +137,7 @@ private Q_SLOTS: void _q_itemsMoved(int from, int to, int count); void _q_modelReset(); void _q_rowsInserted(const QModelIndex &,int,int); + void _q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end); void _q_rowsRemoved(const QModelIndex &,int,int); void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int); void _q_dataChanged(const QModelIndex&,const QModelIndex&,const QVector<int> &); |