diff options
author | Christian Ehrlicher <ch.ehrlicher@gmx.de> | 2021-04-21 21:29:19 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-07-13 06:31:31 +0000 |
commit | 631a02bc0f3e993683c059ddc145e36ceb860d86 (patch) | |
tree | 767c276f415d6b756196c740c0b803f29eaaa802 | |
parent | 8dcb3b226527e11882d5f50462b81e711d2c6900 (diff) |
QTableView: fix selection with rows and cells in ExtendedSelection mode
QTableView stored the current row/column selection start in an own
variable instead using currentSelectionStartIndex. This leads to an
inconsistent behavior when the selection is done with a click on the
header and then in a cell (and the other way round)
Fixes: QTBUG-92561
Change-Id: I4c8bda3a938de451b6eff2819141e86a6870fbef
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit e8b3d35a18e7e4cf6543868d89d6060c90314f39)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/widgets/itemviews/qtableview.cpp | 6 | ||||
-rw-r--r-- | src/widgets/itemviews/qtableview_p.h | 3 | ||||
-rw-r--r-- | tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp | 72 |
3 files changed, 76 insertions, 5 deletions
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index b261ee837d..654157f85f 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -3388,7 +3388,7 @@ void QTableViewPrivate::selectRow(int row, bool anchor) selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate); if ((anchor && !(command & QItemSelectionModel::Current)) || (q->selectionMode() == QTableView::SingleSelection)) - rowSectionAnchor = row; + currentSelectionStartIndex = model->index(row, column, root); if (q->selectionMode() != QTableView::SingleSelection && command.testFlag(QItemSelectionModel::Toggle)) { @@ -3401,6 +3401,7 @@ void QTableViewPrivate::selectRow(int row, bool anchor) command |= QItemSelectionModel::Current; } + const auto rowSectionAnchor = currentSelectionStartIndex.row(); QModelIndex upper = model->index(qMin(rowSectionAnchor, row), column, root); QModelIndex lower = model->index(qMax(rowSectionAnchor, row), column, root); if ((verticalHeader->sectionsMoved() && upper.row() != lower.row())) { @@ -3427,7 +3428,7 @@ void QTableViewPrivate::selectColumn(int column, bool anchor) selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate); if ((anchor && !(command & QItemSelectionModel::Current)) || (q->selectionMode() == QTableView::SingleSelection)) - columnSectionAnchor = column; + currentSelectionStartIndex = model->index(row, column, root); if (q->selectionMode() != QTableView::SingleSelection && command.testFlag(QItemSelectionModel::Toggle)) { @@ -3440,6 +3441,7 @@ void QTableViewPrivate::selectColumn(int column, bool anchor) command |= QItemSelectionModel::Current; } + const auto columnSectionAnchor = currentSelectionStartIndex.column(); QModelIndex left = model->index(row, qMin(columnSectionAnchor, column), root); QModelIndex right = model->index(row, qMax(columnSectionAnchor, column), root); if ((horizontalHeader->sectionsMoved() && left.column() != right.column())) { diff --git a/src/widgets/itemviews/qtableview_p.h b/src/widgets/itemviews/qtableview_p.h index 2b110f18a0..23095c0087 100644 --- a/src/widgets/itemviews/qtableview_p.h +++ b/src/widgets/itemviews/qtableview_p.h @@ -136,7 +136,6 @@ class QTableViewPrivate : public QAbstractItemViewPrivate public: QTableViewPrivate() : showGrid(true), gridStyle(Qt::SolidLine), - rowSectionAnchor(-1), columnSectionAnchor(-1), columnResizeTimerID(0), rowResizeTimerID(0), horizontalHeader(nullptr), verticalHeader(nullptr), sortingEnabled(false), geometryRecursionBlock(false), @@ -186,8 +185,6 @@ public: bool showGrid; Qt::PenStyle gridStyle; - int rowSectionAnchor; - int columnSectionAnchor; int columnResizeTimerID; int rowResizeTimerID; QList<int> columnsToUpdate; diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index 92bc30380a..662226de52 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -437,6 +437,8 @@ private slots: void taskQTBUG_30653_doItemsLayout(); void taskQTBUG_50171_selectRowAfterSwapColumns(); void deselectRow(); + void selectRowsAndCells(); + void selectColumnsAndCells(); #if QT_CONFIG(wheelevent) void mouseWheel_data(); @@ -4783,6 +4785,76 @@ void tst_QTableView::deselectRow() QVERIFY(!tw.selectionModel()->isRowSelected(1, QModelIndex())); } +class QTableViewSelectCells : public QTableView +{ +public: + QItemSelectionModel::SelectionFlags selectionCommand(const QModelIndex &index, + const QEvent *) const override + { + return QTableView::selectionCommand(index, shiftPressed ? &mouseEvent : nullptr); + } + QMouseEvent mouseEvent = QMouseEvent(QEvent::MouseButtonPress, QPointF(), Qt::LeftButton, Qt::LeftButton, Qt::ShiftModifier); + bool shiftPressed = false; +}; + +void tst_QTableView::selectRowsAndCells() +{ + const auto checkRows = [](const QModelIndexList &mil) + { + QCOMPARE(mil.size(), 3); + for (const auto &mi : mil) + QVERIFY(mi.row() >= 1 && mi.row() <= 3); + }; + QTableViewSelectCells tw; + QtTestTableModel model(5, 1); + tw.setSelectionBehavior(QAbstractItemView::SelectRows); + tw.setSelectionMode(QAbstractItemView::ExtendedSelection); + tw.setModel(&model); + tw.show(); + + tw.selectRow(1); + tw.shiftPressed = true; + tw.selectRow(2); + tw.shiftPressed = false; + QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::ShiftModifier, tw.visualRect(model.index(3, 0)).center()); + checkRows(tw.selectionModel()->selectedRows()); + + tw.clearSelection(); + QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::NoModifier, tw.visualRect(model.index(3, 0)).center()); + tw.shiftPressed = true; + tw.selectRow(1); + checkRows(tw.selectionModel()->selectedRows()); +} + +void tst_QTableView::selectColumnsAndCells() +{ + const auto checkColumns = [](const QModelIndexList &mil) + { + QCOMPARE(mil.size(), 3); + for (const auto &mi : mil) + QVERIFY(mi.column() >= 1 && mi.column() <= 3); + }; + QTableViewSelectCells tw; + QtTestTableModel model(1, 5); + tw.setSelectionBehavior(QAbstractItemView::SelectColumns); + tw.setSelectionMode(QAbstractItemView::ExtendedSelection); + tw.setModel(&model); + tw.show(); + + tw.selectColumn(1); + tw.shiftPressed = true; + tw.selectColumn(2); + tw.shiftPressed = false; + QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::ShiftModifier, tw.visualRect(model.index(0, 3)).center()); + checkColumns(tw.selectionModel()->selectedColumns()); + + tw.clearSelection(); + QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::NoModifier, tw.visualRect(model.index(0, 3)).center()); + tw.shiftPressed = true; + tw.selectColumn(1); + checkColumns(tw.selectionModel()->selectedColumns()); +} + // This has nothing to do with QTableView, but it's convenient to reuse the QtTestTableModel #if QT_CONFIG(textmarkdownwriter) |