aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2012-07-27 12:33:27 +1000
committerQt by Nokia <qt-info@nokia.com>2012-08-02 02:43:36 +0200
commitf915ea135fe4bf74432ffa3e6041ea60d4268c67 (patch)
treeeb10268a72d7e4494e7b02c215bc62d42fd82aa1 /src
parent8dabc28e4ea6fe7946ee7770ba39410c6d95bc1d (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.cpp17
-rw-r--r--src/quick/items/qquickvisualadaptormodel_p.h5
-rw-r--r--src/quick/items/qquickvisualdatamodel.cpp30
-rw-r--r--src/quick/items/qquickvisualdatamodel_p.h1
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> &);