diff options
author | Stephen Kelly <steveire@gmail.com> | 2009-07-31 11:00:40 (GMT) |
---|---|---|
committer | Olivier Goffart <ogoffart@trolltech.com> | 2009-08-28 09:34:24 (GMT) |
commit | 4d197ec0eaeae61499d8ee6dc0e98147800f583e (patch) | |
tree | 606dd9392cc8e3bab799c38b118fc0f2c761a30f /tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp | |
parent | 7091ec8cd1ec94fb889230d69fc70d40a9f69b2d (diff) | |
download | Qt-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/tst_qabstractitemmodel.cpp')
-rw-r--r-- | tests/auto/qabstractitemmodel/tst_qabstractitemmodel.cpp | 106 |
1 files changed, 104 insertions, 2 deletions
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) |