diff options
author | Stephen Kelly <stephen.kelly@kdab.com> | 2010-10-21 08:37:46 (GMT) |
---|---|---|
committer | Gabriel de Dietrich <gabriel.dietrich-de@nokia.com> | 2010-10-21 08:38:29 (GMT) |
commit | defe418c16e5e79033812752416efa874c70e622 (patch) | |
tree | ddfcaf84417e0b027d0b68053b01a4198142d00b | |
parent | 8331e9700b830594d3c015308bf0aa351997862c (diff) | |
download | Qt-defe418c16e5e79033812752416efa874c70e622.zip Qt-defe418c16e5e79033812752416efa874c70e622.tar.gz Qt-defe418c16e5e79033812752416efa874c70e622.tar.bz2 |
Make sure d->ranges does not have invalid ranges before processing it.
Reviewed-by: gabi
Merge-request: 831
-rw-r--r-- | src/gui/itemviews/qitemselectionmodel.cpp | 13 | ||||
-rw-r--r-- | tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp | 66 |
2 files changed, 79 insertions, 0 deletions
diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp index f848321..e69cd65 100644 --- a/src/gui/itemviews/qitemselectionmodel.cpp +++ b/src/gui/itemviews/qitemselectionmodel.cpp @@ -1059,6 +1059,19 @@ void QItemSelectionModel::select(const QItemSelection &selection, QItemSelection // store old selection QItemSelection sel = selection; + // If d->ranges is non-empty when the source model is reset the persistent indexes + // it contains will be invalid. We can't clear them in a modelReset slot because that might already + // be too late if another model observer is connected to the same modelReset slot and is invoked first + // it might call select() on this selection model before any such QItemSelectionModelPrivate::_q_modelReset() slot + // is invoked, so it would not be cleared yet. We clear it invalid ranges in it here. + QItemSelection::iterator it = d->ranges.begin(); + while (it != d->ranges.end()) { + if (!it->isValid()) + it = d->ranges.erase(it); + else + ++it; + } + QItemSelection old = d->ranges; old.merge(d->currentSelection, d->currentCommand); diff --git a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp index 3b2a716..8058294 100644 --- a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp +++ b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp @@ -95,6 +95,8 @@ private slots: void QTBUG5671_layoutChangedWithAllSelected(); void QTBUG2804_layoutChangedTreeSelection(); + void testValidRangesInSelectionsAfterReset(); + private: QAbstractItemModel *model; QItemSelectionModel *selection; @@ -2353,6 +2355,70 @@ void tst_QItemSelectionModel::QTBUG2804_layoutChangedTreeSelection() QCOMPARE(selModel.selectedIndexes().count(), 4); } +class SelectionObserver : public QObject +{ + Q_OBJECT +public: + SelectionObserver(QAbstractItemModel *model, QObject *parent = 0) + : QObject(parent), m_model(model), m_selectionModel(0) + { + connect(model, SIGNAL(modelReset()), SLOT(modelReset())); + } + + void setSelectionModel(QItemSelectionModel *selectionModel) + { + m_selectionModel = selectionModel; + connect(m_selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(selectionChanged(QItemSelection,QItemSelection))); + } + + private slots: + void modelReset() + { + const QModelIndex idx = m_model->index(2, 0); + QVERIFY(idx.isValid()); + m_selectionModel->select(QItemSelection(idx, idx), QItemSelectionModel::Clear); + } + + void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) + { + foreach(const QItemSelectionRange &range, selected) + QVERIFY(range.isValid()); + foreach(const QItemSelectionRange &range, deselected) + QVERIFY(range.isValid()); + } + +private: + QAbstractItemModel *m_model; + QItemSelectionModel *m_selectionModel; +}; + +void tst_QItemSelectionModel::testValidRangesInSelectionsAfterReset() +{ + QStringListModel model; + + QStringList strings; + strings << "one" + << "two" + << "three" + << "four" + << "five"; + + model.setStringList(strings); + + SelectionObserver observer(&model); + + QItemSelectionModel selectionModel(&model); + + selectionModel.select(QItemSelection(model.index(1, 0), model.index(3, 0)), QItemSelectionModel::Select); + + // Cause d->ranges to contain something. + model.insertRows(2, 1); + + observer.setSelectionModel(&selectionModel); + + model.setStringList(strings); + +} QTEST_MAIN(tst_QItemSelectionModel) #include "tst_qitemselectionmodel.moc" |