diff options
author | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2022-05-02 10:45:14 +0200 |
---|---|---|
committer | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2022-05-25 13:51:20 +0200 |
commit | 9918909ab8d7dc2548d63ef618f3323b34f877b8 (patch) | |
tree | b537675114fb97f5064fa639b999d1c47043eadf | |
parent | 1c680287ff448ee3e196179cd6a586c9be0c012b (diff) |
QQuickTableView: make top-left cell current on first key press
If TableView has focus, but currentIndex is not yet set, the
first press on an arrow key should make the top left cell
current. This will also make sure that if you e.g collapse
a tree node that contains the current index, you can still
continue to navigate using the arrow keys. This is
equal to how it works with widgets.
Change-Id: I1cd6266cd1a8269f7a4f2b1af989fddfc8ccd3c0
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
-rw-r--r-- | src/quick/items/qquicktableview.cpp | 14 | ||||
-rw-r--r-- | tests/auto/quick/qquicktableview/tst_qquicktableview.cpp | 53 |
2 files changed, 67 insertions, 0 deletions
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index bf47d43c8f..ecd302a761 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -4768,6 +4768,20 @@ void QQuickTableView::keyPressEvent(QKeyEvent *e) const QModelIndex currentIndex = d->selectionModel->currentIndex(); const QPoint currentCell = cellAtIndex(currentIndex); + if (!d->cellIsValid(currentCell)) { + switch (e->key()) { + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_Left: + case Qt::Key_Right: + // Special case: the current index doesn't map to a cell in the view (perhaps + // because it isn't set yet). In that case, we set it to be the top-left cell. + const QModelIndex topLeftIndex = modelIndex(leftColumn(), topRow()); + d->selectionModel->setCurrentIndex(topLeftIndex, QItemSelectionModel::NoUpdate); + } + return; + } + auto beginMoveCurrentIndex = [=](){ if (!select) { d->clearSelection(); diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp index 9a24bd18f9..2e02e5873d 100644 --- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp +++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp @@ -221,6 +221,8 @@ private slots: void moveCurrentIndexUsingArrowKeys(); void moveCurrentIndexUsingHomeAndEndKeys(); void moveCurrentIndexUsingPageUpDownKeys(); + void setCurrentIndexOnFirstKeyPress_data(); + void setCurrentIndexOnFirstKeyPress(); void setCurrentIndexFromMouse(); void disableKeyNavigation(); void disablePointerNavigation(); @@ -4438,6 +4440,57 @@ void tst_QQuickTableView::moveCurrentIndexUsingPageUpDownKeys() QCOMPARE(tableView->currentRow(), cellAtEnd.y()); } +void tst_QQuickTableView::setCurrentIndexOnFirstKeyPress_data() +{ + QTest::addColumn<Qt::Key>("arrowKey"); + + QTest::newRow("left") << Qt::Key_Left; + QTest::newRow("right") << Qt::Key_Right; + QTest::newRow("up") << Qt::Key_Up; + QTest::newRow("down") << Qt::Key_Down; +} + +void tst_QQuickTableView::setCurrentIndexOnFirstKeyPress() +{ + // Check that TableView has focus, but no cell is current, the + // first key press on any of the arrow keys will assign the + // top left cell to be current. + QFETCH(Qt::Key, arrowKey); + LOAD_TABLEVIEW("tableviewwithselected1.qml"); + + TestModel model(2, 2); + QItemSelectionModel selectionModel(&model); + + tableView->setModel(QVariant::fromValue(&model)); + tableView->setSelectionModel(&selectionModel); + tableView->setFocus(true); + QQuickWindow *window = tableView->window(); + const char kCurrent[] = "current"; + + WAIT_UNTIL_POLISHED; + + // Check that all delegates have current set to false upon start + for (auto fxItem : tableViewPrivate->loadedItems) + QVERIFY(!fxItem->item->property(kCurrent).toBool()); + + QCOMPARE(tableView->currentColumn(), -1); + QCOMPARE(tableView->currentRow(), -1); + + // Pressing a random key, e.g 'a', should not change current index + QTest::keyPress(window, Qt::Key_A); + QVERIFY(!selectionModel.currentIndex().isValid()); + QCOMPARE(tableView->currentColumn(), -1); + QCOMPARE(tableView->currentRow(), -1); + + // Press the given arrow key + const QPoint topLeftCell(0, 0); + QTest::keyPress(window, arrowKey); + QCOMPARE(selectionModel.currentIndex(), tableView->modelIndex(topLeftCell)); + QVERIFY(tableView->itemAtCell(topLeftCell)->property(kCurrent).toBool()); + QCOMPARE(tableView->currentColumn(), topLeftCell.x()); + QCOMPARE(tableView->currentRow(), topLeftCell.y()); +} + void tst_QQuickTableView::setCurrentIndexFromMouse() { LOAD_TABLEVIEW("tableviewwithselected1.qml"); |