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>
This commit is contained in:
parent
7183d08095
commit
61f2e9a9a7
@ -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);
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user