summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoni Poikelin <joni.poikelin@theqtcompany.com>2015-09-23 13:42:11 +0300
committerJoni Poikelin <joni.poikelin@theqtcompany.com>2015-09-24 08:13:07 +0000
commit61f2e9a9a72ba4daa96960bf3cb7a605c0b4634c (patch)
tree0233735440ded55a35313f910813bdf06c6335b0
parent7183d08095f4598fc0f7702608bd726986bf1307 (diff)
Fix QItemSelectionModel deselection range
Left and right were swapped which caused invalid selection ranges to be emitted through selectionChanged. Task-number: QTBUG-48402 Change-Id: I18692c2b50c49ab39065f9b360b37b7615227ee9 Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@theqtcompany.com>
-rw-r--r--src/corelib/itemmodels/qitemselectionmodel.cpp8
-rw-r--r--tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp94
2 files changed, 98 insertions, 4 deletions
diff --git a/src/corelib/itemmodels/qitemselectionmodel.cpp b/src/corelib/itemmodels/qitemselectionmodel.cpp
index ba97543c44..51c670f79e 100644
--- a/src/corelib/itemmodels/qitemselectionmodel.cpp
+++ b/src/corelib/itemmodels/qitemselectionmodel.cpp
@@ -729,11 +729,11 @@ void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &pare
deselected.append(*it);
it = ranges.erase(it);
} else if (start <= it->top() && it->top() <= end) { // Top intersection
- deselected.append(QItemSelectionRange(it->topLeft(), model->index(end, it->left(), it->parent())));
+ deselected.append(QItemSelectionRange(it->topLeft(), model->index(end, it->right(), it->parent())));
*it = QItemSelectionRange(model->index(end + 1, it->left(), it->parent()), it->bottomRight());
++it;
} else if (start <= it->bottom() && it->bottom() <= end) { // Bottom intersection
- deselected.append(QItemSelectionRange(model->index(start, it->right(), it->parent()), it->bottomRight()));
+ deselected.append(QItemSelectionRange(model->index(start, it->left(), it->parent()), it->bottomRight()));
*it = QItemSelectionRange(it->topLeft(), model->index(start - 1, it->right(), it->parent()));
++it;
} else if (it->top() < start && end < it->bottom()) { // Middle intersection
@@ -741,8 +741,8 @@ void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &pare
// and [4, 5] is removed, we need to split [3, 4, 5, 6] into [3], [4, 5] and [6].
// [4, 5] is appended to deselected, and [3] and [6] remain part of the selection
// in ranges.
- const QItemSelectionRange removedRange(model->index(start, it->right(), it->parent()),
- model->index(end, it->left(), it->parent()));
+ const QItemSelectionRange removedRange(model->index(start, it->left(), it->parent()),
+ model->index(end, it->right(), it->parent()));
deselected.append(removedRange);
QItemSelection::split(*it, removedRange, &newParts);
it = ranges.erase(it);
diff --git a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp
index 23cd254477..888ffba282 100644
--- a/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp
+++ b/tests/auto/corelib/itemmodels/qitemselectionmodel/tst_qitemselectionmodel.cpp
@@ -94,6 +94,9 @@ private slots:
void testChainedSelectionClear();
void testClearCurrentIndex();
+ void QTBUG48402_data();
+ void QTBUG48402();
+
private:
QAbstractItemModel *model;
QItemSelectionModel *selection;
@@ -2756,5 +2759,96 @@ void tst_QItemSelectionModel::testClearCurrentIndex()
QVERIFY(currentIndexSpy.size() == 2);
}
+void tst_QItemSelectionModel::QTBUG48402_data()
+{
+ QTest::addColumn<int>("rows");
+ QTest::addColumn<int>("columns");
+
+ QTest::addColumn<int>("selectTop");
+ QTest::addColumn<int>("selectLeft");
+ QTest::addColumn<int>("selectBottom");
+ QTest::addColumn<int>("selectRight");
+
+ QTest::addColumn<int>("removeTop");
+ QTest::addColumn<int>("removeBottom");
+
+ QTest::addColumn<int>("deselectTop");
+ QTest::addColumn<int>("deselectLeft");
+ QTest::addColumn<int>("deselectBottom");
+ QTest::addColumn<int>("deselectRight");
+
+ QTest::newRow("4x4 top intersection")
+ << 4 << 4
+ << 0 << 2 << 1 << 3
+ << 1 << 1
+ << 1 << 2 << 1 << 3;
+
+ QTest::newRow("4x4 bottom intersection")
+ << 4 << 4
+ << 0 << 2 << 1 << 3
+ << 0 << 0
+ << 0 << 2 << 0 << 3;
+
+ QTest::newRow("4x4 middle intersection")
+ << 4 << 4
+ << 0 << 2 << 2 << 3
+ << 1 << 1
+ << 1 << 2 << 1 << 3;
+
+ QTest::newRow("4x4 full inclusion")
+ << 4 << 4
+ << 0 << 2 << 1 << 3
+ << 0 << 1
+ << 0 << 2 << 1 << 3;
+}
+class QTBUG48402_helper : public QObject
+{
+ Q_OBJECT
+public:
+ QModelIndex tl;
+ QModelIndex br;
+public slots:
+ void changed(const QItemSelection &selected, const QItemSelection &deselected)
+ {
+ tl = deselected.first().topLeft();
+ br = deselected.first().bottomRight();
+ }
+};
+
+void tst_QItemSelectionModel::QTBUG48402()
+{
+ QFETCH(int, rows);
+ QFETCH(int, columns);
+ QFETCH(int, selectTop);
+ QFETCH(int, selectLeft);
+ QFETCH(int, selectBottom);
+ QFETCH(int, selectRight);
+ QFETCH(int, removeTop);
+ QFETCH(int, removeBottom);
+ QFETCH(int, deselectTop);
+ QFETCH(int, deselectLeft);
+ QFETCH(int, deselectBottom);
+ QFETCH(int, deselectRight);
+
+ MyStandardItemModel model(rows, columns);
+ QItemSelectionModel selections(&model);
+
+ QModelIndex stl = model.index(selectTop, selectLeft);
+ QModelIndex sbr = model.index(selectBottom, selectRight);
+ QModelIndex dtl = model.index(deselectTop, deselectLeft);
+ QModelIndex dbr = model.index(deselectBottom, deselectRight);
+
+ selections.select(QItemSelection(stl, sbr), QItemSelectionModel::ClearAndSelect);
+ QTBUG48402_helper helper;
+ helper.connect(&selections, &QItemSelectionModel::selectionChanged, &helper, &QTBUG48402_helper::changed);
+ QVERIFY(selections.isSelected(stl));
+ QVERIFY(selections.isSelected(sbr));
+ QVERIFY(selections.hasSelection());
+
+ model.removeRows(removeTop, removeBottom - removeTop + 1);
+
+ QCOMPARE(QItemSelectionRange(helper.tl, helper.br), QItemSelectionRange(dtl, dbr));
+}
+
QTEST_MAIN(tst_QItemSelectionModel)
#include "tst_qitemselectionmodel.moc"