summaryrefslogtreecommitdiffstats
path: root/tests/auto/qabstractitemmodel
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2009-07-31 11:00:40 (GMT)
committerOlivier Goffart <ogoffart@trolltech.com>2009-08-28 09:34:24 (GMT)
commit4d197ec0eaeae61499d8ee6dc0e98147800f583e (patch)
tree606dd9392cc8e3bab799c38b118fc0f2c761a30f /tests/auto/qabstractitemmodel
parent7091ec8cd1ec94fb889230d69fc70d40a9f69b2d (diff)
downloadQt-4d197ec0eaeae61499d8ee6dc0e98147800f583e.zip
Qt-4d197ec0eaeae61499d8ee6dc0e98147800f583e.tar.gz
Qt-4d197ec0eaeae61499d8ee6dc0e98147800f583e.tar.bz2
Fix the API for resetting QAbstractItemModels.
This commit deprecates the QAIM::reset() method, and adds beginResetModel() and endResetModel() methods, addressing Qt issue 247023. http://www.qtsoftware.com/developer/task-tracker/index_html?method=entry&id=247023 If models and proxies use QAIM::reset() alone, then proxies will emit modelAboutToBeReset after its source model is reset. This means that mapToSource will not behave as expected (Will always return an invalid index) in a slot connected to modelAboutToBeReset. The usecase for this is maintaining viewstate (which items are selected, expanded) when the model is reset. See BrowserWidget::modelChanged here: http://websvn.kde.org/trunk/KDE/kdepim/akonadi/akonadiconsole/browserwidget.cpp?view=markup Task-number: 247023 Reviewed-by: Olivier Goffart <ogoffart@trolltech.com> Merge-request: 1072
Diffstat (limited to 'tests/auto/qabstractitemmodel')
-rw-r--r--tests/auto/qabstractitemmodel/dynamictreemodel.cpp118
-rw-r--r--tests/auto/qabstractitemmodel/dynamictreemodel.h39
-rw-r--r--tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp106
3 files changed, 234 insertions, 29 deletions
diff --git a/tests/auto/qabstractitemmodel/dynamictreemodel.cpp b/tests/auto/qabstractitemmodel/dynamictreemodel.cpp
index 6c3e0cb..374b7db 100644
--- a/tests/auto/qabstractitemmodel/dynamictreemodel.cpp
+++ b/tests/auto/qabstractitemmodel/dynamictreemodel.cpp
@@ -204,42 +204,106 @@ ModelMoveCommand::ModelMoveCommand(DynamicTreeModel *model, QObject *parent)
{
}
+bool ModelMoveCommand::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow)
+{
+ return m_model->beginMoveRows(srcParent, srcStart, srcEnd, destParent, destRow);
+}
void ModelMoveCommand::doCommand()
{
- QModelIndex srcParent = findIndex(m_rowNumbers);
- QModelIndex destParent = findIndex(m_destRowNumbers);
-
- if (!m_model->beginMoveRows(srcParent, m_startRow, m_endRow, destParent, m_destRow))
- {
- return;
- }
-
- for (int column = 0; column < m_numCols; ++column)
- {
- QList<qint64> l = m_model->m_childItems.value(srcParent.internalId())[column].mid(m_startRow, m_endRow - m_startRow + 1 );
+ QModelIndex srcParent = findIndex(m_rowNumbers);
+ QModelIndex destParent = findIndex(m_destRowNumbers);
- for (int i = m_startRow; i <= m_endRow ; i++)
+ if (!emitPreSignal(srcParent, m_startRow, m_endRow, destParent, m_destRow))
{
- m_model->m_childItems[srcParent.internalId()][column].removeAt(m_startRow);
- }
- int d;
- if (m_destRow < m_startRow)
- d = m_destRow;
- else
- {
- if (srcParent == destParent)
- d = m_destRow - (m_endRow - m_startRow + 1);
- else
- d = m_destRow - (m_endRow - m_startRow) + 1;
+ return;
}
- foreach(const qint64 id, l)
+ for (int column = 0; column < m_numCols; ++column)
{
- m_model->m_childItems[destParent.internalId()][column].insert(d++, id);
+ QList<qint64> l = m_model->m_childItems.value(srcParent.internalId())[column].mid(m_startRow, m_endRow - m_startRow + 1 );
+
+ for (int i = m_startRow; i <= m_endRow ; i++)
+ {
+ m_model->m_childItems[srcParent.internalId()][column].removeAt(m_startRow);
+ }
+ int d;
+ if (m_destRow < m_startRow)
+ d = m_destRow;
+ else
+ {
+ if (srcParent == destParent)
+ d = m_destRow - (m_endRow - m_startRow + 1);
+ else
+ d = m_destRow - (m_endRow - m_startRow) + 1;
+ }
+
+ foreach(const qint64 id, l)
+ {
+ m_model->m_childItems[destParent.internalId()][column].insert(d++, id);
+ }
}
- }
- m_model->endMoveRows();
+ emitPostSignal();
+}
+
+void ModelMoveCommand::emitPostSignal()
+{
+ m_model->endMoveRows();
+}
+
+ModelResetCommand::ModelResetCommand(DynamicTreeModel* model, QObject* parent)
+ : ModelMoveCommand(model, parent)
+{
+
+}
+
+ModelResetCommand::~ModelResetCommand()
+{
+
+}
+
+bool ModelResetCommand::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow)
+{
+ Q_UNUSED(srcParent);
+ Q_UNUSED(srcStart);
+ Q_UNUSED(srcEnd);
+ Q_UNUSED(destParent);
+ Q_UNUSED(destRow);
+
+ return true;
+}
+
+void ModelResetCommand::emitPostSignal()
+{
+ m_model->reset();
+}
+
+ModelResetCommandFixed::ModelResetCommandFixed(DynamicTreeModel* model, QObject* parent)
+ : ModelMoveCommand(model, parent)
+{
+
+}
+
+ModelResetCommandFixed::~ModelResetCommandFixed()
+{
+
+}
+
+bool ModelResetCommandFixed::emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow)
+{
+ Q_UNUSED(srcParent);
+ Q_UNUSED(srcStart);
+ Q_UNUSED(srcEnd);
+ Q_UNUSED(destParent);
+ Q_UNUSED(destRow);
+
+ m_model->beginResetModel();
+ return true;
+}
+
+void ModelResetCommandFixed::emitPostSignal()
+{
+ m_model->endResetModel();
}
diff --git a/tests/auto/qabstractitemmodel/dynamictreemodel.h b/tests/auto/qabstractitemmodel/dynamictreemodel.h
index 88e293c..c19ed9d 100644
--- a/tests/auto/qabstractitemmodel/dynamictreemodel.h
+++ b/tests/auto/qabstractitemmodel/dynamictreemodel.h
@@ -70,6 +70,8 @@ private:
friend class ModelInsertCommand;
friend class ModelMoveCommand;
+ friend class ModelResetCommand;
+ friend class ModelResetCommandFixed;
};
@@ -118,6 +120,7 @@ public:
virtual void doCommand();
};
+
class ModelMoveCommand : public ModelChangeCommand
{
Q_OBJECT
@@ -126,8 +129,12 @@ public:
virtual ~ModelMoveCommand() {}
+ virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow);
+
virtual void doCommand();
+ virtual void emitPostSignal();
+
void setDestAncestors( QList<int> rows ) { m_destRowNumbers = rows; }
void setDestRow(int row) { m_destRow = row; }
@@ -137,5 +144,37 @@ protected:
int m_destRow;
};
+/**
+ A command which does a move and emits a reset signal.
+*/
+class ModelResetCommand : public ModelMoveCommand
+{
+ Q_OBJECT
+public:
+ ModelResetCommand(DynamicTreeModel* model, QObject* parent = 0);
+
+ virtual ~ModelResetCommand();
+
+ virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow);
+ virtual void emitPostSignal();
+
+};
+
+/**
+ A command which does a move and emits a beginResetModel and endResetModel signals.
+*/
+class ModelResetCommandFixed : public ModelMoveCommand
+{
+ Q_OBJECT
+public:
+ ModelResetCommandFixed(DynamicTreeModel* model, QObject* parent = 0);
+
+ virtual ~ModelResetCommandFixed();
+
+ virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow);
+ virtual void emitPostSignal();
+
+};
+
#endif
diff --git a/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp b/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp
index 9c83474..61eeae7 100644
--- a/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp
+++ b/tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp
@@ -43,6 +43,8 @@
#include <QtTest/QtTest>
#include <QtCore/QtCore>
+#include <QSortFilterProxyModel>
+
//TESTED_CLASS=QAbstractListModel QAbstractTableModel
//TESTED_FILES=
@@ -110,6 +112,8 @@ private slots:
void testMoveWithinOwnRange_data();
void testMoveWithinOwnRange();
+ void testReset();
+
private:
DynamicTreeModel *m_model;
@@ -814,7 +818,7 @@ void tst_QAbstractItemModel::complexChangesWithPersistent()
//remove a bunch of columns
model.removeColumns(2, 4);
-
+
QVERIFY(a == model.index(1, 1, QModelIndex()));
QVERIFY(b == model.index(9, 3, QModelIndex()));
QVERIFY(c == model.index(5, 2, QModelIndex()));
@@ -825,7 +829,7 @@ void tst_QAbstractItemModel::complexChangesWithPersistent()
QVERIFY(!e[i].isValid());
for (int i=6; i <10 ; i++)
QVERIFY(e[i] == model.index(2, i-4 , QModelIndex()));
-
+
//move some indexes around
model.setPersistent(model.index(1, 1 , QModelIndex()), model.index(9, 3 , QModelIndex()));
model.setPersistent(model.index(9, 3 , QModelIndex()), model.index(8, 4 , QModelIndex()));
@@ -1652,6 +1656,104 @@ void tst_QAbstractItemModel::testMoveWithinOwnRange()
}
+class ListenerObject : public QObject
+{
+ Q_OBJECT
+public:
+ ListenerObject(QAbstractProxyModel *parent);
+
+protected:
+ void fillIndexStores(const QModelIndex &parent);
+
+public slots:
+ void slotAboutToBeReset();
+ void slotReset();
+
+private:
+ QAbstractProxyModel *m_model;
+ QList<QPersistentModelIndex> m_persistentIndexes;
+ QModelIndexList m_nonPersistentIndexes;
+};
+
+
+ListenerObject::ListenerObject(QAbstractProxyModel *parent)
+ : QObject(parent), m_model(parent)
+{
+ connect(m_model, SIGNAL(modelAboutToBeReset()), SLOT(slotAboutToBeReset()));
+ connect(m_model, SIGNAL(modelReset()), SLOT(slotReset()));
+
+ fillIndexStores(QModelIndex());
+}
+
+void ListenerObject::fillIndexStores(const QModelIndex &parent)
+{
+ const int column = 0;
+ int row = 0;
+ QModelIndex idx = m_model->index(row, column, parent);
+ while (idx.isValid())
+ {
+ m_persistentIndexes << QPersistentModelIndex(idx);
+ m_nonPersistentIndexes << idx;
+ if (m_model->hasChildren(idx))
+ {
+ fillIndexStores(idx);
+ }
+ ++row;
+ idx = m_model->index(row, column, parent);
+ }
+}
+
+void ListenerObject::slotAboutToBeReset()
+{
+ // Nothing has been changed yet. All indexes should be the same.
+ for (int i = 0; i < m_persistentIndexes.size(); ++i)
+ {
+ QModelIndex idx = m_persistentIndexes.at(i);
+ QVERIFY(idx == m_nonPersistentIndexes.at(i));
+ QVERIFY(m_model->mapToSource(idx).isValid());
+ }
+}
+
+void ListenerObject::slotReset()
+{
+ foreach(const QModelIndex &idx, m_persistentIndexes)
+ {
+ QVERIFY(!idx.isValid());
+ }
+}
+
+
+void tst_QAbstractItemModel::testReset()
+{
+ QSignalSpy beforeResetSpy(m_model, SIGNAL(modelAboutToBeReset()));
+ QSignalSpy afterResetSpy(m_model, SIGNAL(modelReset()));
+
+
+ QSortFilterProxyModel *nullProxy = new QSortFilterProxyModel(this);
+ nullProxy->setSourceModel(m_model);
+
+ // Makes sure the model and proxy are in a consistent state. before and after reset.
+ new ListenerObject(nullProxy);
+
+ ModelResetCommandFixed *resetCommand = new ModelResetCommandFixed(m_model, this);
+
+ resetCommand->setNumCols(4);
+ resetCommand->setStartRow(0);
+ resetCommand->setEndRow(0);
+ resetCommand->setDestRow(0);
+ resetCommand->setDestAncestors(QList<int>() << 5);
+ resetCommand->doCommand();
+
+ // Verify that the correct signals were emitted
+ QVERIFY(beforeResetSpy.size() == 1);
+ QVERIFY(afterResetSpy.size() == 1);
+
+ // Verify that the move actually happened.
+ QVERIFY(m_model->rowCount() == 9);
+ QModelIndex destIndex = m_model->index(4, 0);
+ QVERIFY(m_model->rowCount(destIndex) == 11);
+
+}
QTEST_MAIN(tst_QAbstractItemModel)