From d13418effc5f00474541ae513a30c9a42c2a1cb3 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 7 Aug 2009 17:14:31 +0200 Subject: QItemSelectionModel did not send selectionChanged signal when deleting an item in a tree-like model with one of its grand-children being selected. Added recursive deselection for the model. Task-number: 232634 Reviewed-by: thierry --- src/gui/itemviews/qitemselectionmodel.cpp | 22 +++++++++++++++++++- src/gui/itemviews/qitemselectionmodel_p.h | 2 ++ .../tst_qitemselectionmodel.cpp | 24 ++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp index 9dad95f..0f35ac1 100644 --- a/src/gui/itemviews/qitemselectionmodel.cpp +++ b/src/gui/itemviews/qitemselectionmodel.cpp @@ -593,10 +593,30 @@ void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &pare // update selectionsx QModelIndex tl = model->index(start, 0, parent); QModelIndex br = model->index(end, model->columnCount(parent) - 1, parent); - q->select(QItemSelection(tl, br), QItemSelectionModel::Deselect); + recursiveDeselect(QItemSelectionRange(tl, br)); finalize(); } +void QItemSelectionModelPrivate::recursiveDeselect(const QItemSelectionRange &range) +{ + Q_Q(QItemSelectionModel); + + QItemSelection sel(range.topLeft(), range.bottomRight()); + q->select(sel, QItemSelectionModel::Deselect); + + QModelIndexList idxList = range.indexes(); + QModelIndexList::const_iterator it = idxList.begin(); + for (; it != idxList.end(); ++it) + { + if (!model->hasChildren(*it)) + continue; + + const QModelIndex &firstChild = it->child(0,0); + const QModelIndex &lastChild = it->child(model->rowCount(*it) - 1, model->columnCount(*it) - 1); + recursiveDeselect(QItemSelectionRange(firstChild, lastChild)); + } +} + /*! \internal */ diff --git a/src/gui/itemviews/qitemselectionmodel_p.h b/src/gui/itemviews/qitemselectionmodel_p.h index 18ad506..8176d4c 100644 --- a/src/gui/itemviews/qitemselectionmodel_p.h +++ b/src/gui/itemviews/qitemselectionmodel_p.h @@ -77,6 +77,8 @@ public: void _q_layoutAboutToBeChanged(); void _q_layoutChanged(); + void recursiveDeselect(const QItemSelectionRange &range); + inline void remove(QList &r) { QList::const_iterator it = r.constBegin(); diff --git a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp index 0541b46..05e23f1 100644 --- a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp +++ b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp @@ -90,6 +90,7 @@ private slots: void merge(); void task119433_isRowSelected(); void task252069_rowIntersectsSelection(); + void task232634_childrenDeselectionSignal(); private: QAbstractItemModel *model; @@ -2187,5 +2188,28 @@ void tst_QItemSelectionModel::task252069_rowIntersectsSelection() QVERIFY(!selected.columnIntersectsSelection(5, QModelIndex())); } +void tst_QItemSelectionModel::task232634_childrenDeselectionSignal() +{ + QStandardItemModel model; + + QStandardItem *parentItem = model.invisibleRootItem(); + for (int i = 0; i < 4; ++i) { + QStandardItem *item = new QStandardItem(QString("item %0").arg(i)); + parentItem->appendRow(item); + parentItem = item; + } + + QModelIndex root = model.index(0,0); + QModelIndex par = root.child(0,0); + QModelIndex sel = par.child(0,0); + + QItemSelectionModel selectionModel(&model); + selectionModel.select(sel, QItemSelectionModel::SelectCurrent); + + QSignalSpy deselectSpy(&selectionModel, SIGNAL(selectionChanged(const QItemSelection& , const QItemSelection&))); + model.removeRows(0, 1, root); + QVERIFY(deselectSpy.count() == 1); +} + QTEST_MAIN(tst_QItemSelectionModel) #include "tst_qitemselectionmodel.moc" -- cgit v0.12