Skip to content

Commit

Permalink
QTableView: correctly toggle column selection when scrolled
Browse files Browse the repository at this point in the history
We need to check whether the horizontal header's selection includes the
index for the row at the top, rather than for row 0, as the index we
check is based on the scrolled position of the header, so would never be
included in the top row when the view is scrolled. This is correctly
done in selectRow already.

Add a test case that simulates selection of rows and columns by clicking
on the header.

Fixes: QTBUG-98444
Pick-to: 6.2
Change-Id: I2fa1b32bf75dc96225b40145b713bf7e2ffc29dd
Reviewed-by: Tor Arne Vestbø <[email protected]>
  • Loading branch information
vohi committed Dec 2, 2021
1 parent 97cfd49 commit d22bafe
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/widgets/itemviews/qtableview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3467,7 +3467,7 @@ void QTableViewPrivate::selectColumn(int column, bool anchor)
if (q->selectionMode() != QTableView::SingleSelection
&& command.testFlag(QItemSelectionModel::Toggle)) {
if (anchor)
ctrlDragSelectionFlag = horizontalHeader->selectionModel()->selectedColumns().contains(index)
ctrlDragSelectionFlag = horizontalHeader->selectionModel()->selectedColumns(row).contains(index)
? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
command &= ~QItemSelectionModel::Toggle;
command |= ctrlDragSelectionFlag;
Expand Down
56 changes: 56 additions & 0 deletions tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,8 @@ private slots:
void deselectRow();
void selectRowsAndCells();
void selectColumnsAndCells();
void selectWithHeader_data();
void selectWithHeader();

#if QT_CONFIG(wheelevent)
void mouseWheel_data();
Expand Down Expand Up @@ -4855,6 +4857,60 @@ void tst_QTableView::selectColumnsAndCells()
checkColumns(tw.selectionModel()->selectedColumns());
}

void tst_QTableView::selectWithHeader_data()
{
QTest::addColumn<Qt::Orientation>("orientation");

QTest::addRow("horizontal") << Qt::Horizontal;
QTest::addRow("vertical") << Qt::Vertical;
}

void tst_QTableView::selectWithHeader()
{
QFETCH(Qt::Orientation, orientation);

QTableWidget view(10, 10);
view.resize(200, 100);
view.show();

QVERIFY(QTest::qWaitForWindowExposed(&view));

QHeaderView *header;
QPoint clickPos;
QModelIndex lastIndex;

switch (orientation) {
case Qt::Horizontal:
header = view.horizontalHeader();
clickPos.rx() = header->sectionPosition(0) + header->sectionSize(0) / 2;
clickPos.ry() = header->height() / 2;
lastIndex = view.model()->index(9, 0);
break;
case Qt::Vertical:
header = view.verticalHeader();
clickPos.rx() = header->width() / 2;
clickPos.ry() = header->sectionPosition(0) + header->sectionSize(0) / 2;
lastIndex = view.model()->index(0, 9);
break;
}

const auto isSelected = [&]{
return orientation == Qt::Horizontal
? view.selectionModel()->isColumnSelected(0)
: view.selectionModel()->isRowSelected(0);
};

QTest::mouseClick(header->viewport(), Qt::LeftButton, {}, clickPos);
QVERIFY(isSelected());
QTest::mouseClick(header->viewport(), Qt::LeftButton, Qt::ControlModifier, clickPos);
QVERIFY(!isSelected());
QTest::mouseClick(header->viewport(), Qt::LeftButton, {}, clickPos);
QVERIFY(isSelected());
view.scrollTo(lastIndex);
QTest::mouseClick(header->viewport(), Qt::LeftButton, Qt::ControlModifier, clickPos);
QVERIFY(!isSelected());
}

// This has nothing to do with QTableView, but it's convenient to reuse the QtTestTableModel
#if QT_CONFIG(textmarkdownwriter)

Expand Down

0 comments on commit d22bafe

Please sign in to comment.