aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@qt.io>2022-05-02 10:45:14 +0200
committerRichard Moe Gustavsen <richard.gustavsen@qt.io>2022-05-25 13:51:20 +0200
commit9918909ab8d7dc2548d63ef618f3323b34f877b8 (patch)
treeb537675114fb97f5064fa639b999d1c47043eadf
parent1c680287ff448ee3e196179cd6a586c9be0c012b (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.cpp14
-rw-r--r--tests/auto/quick/qquicktableview/tst_qquicktableview.cpp53
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");