aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@qt.io>2022-12-20 15:57:23 +0100
committerRichard Moe Gustavsen <richard.gustavsen@qt.io>2023-01-20 20:39:11 +0100
commitea5200b82f21e0f4d080d3fc256b218e0ee56f3d (patch)
treebe8473c4b27dec02305d71e0e36600646004a5cb /tests/auto
parente34142e6cda177b601d8e5daba00a2ab84828db1 (diff)
QQuickTableView: set active focus directly on the edit item
When starting to edit a cell, the current implementation calls editItem->nextItemInFocusChain(true) to resolve the child to get active focus. But a better way is to instead rely on the edit item being a FocusScope. That way, we can simply set active focus on the edit item directly, and rely on the FocusScope forwarding active focus to the right child. After all, that is what FocusScopes are for. This patch will therefore change the implementation to set active focus directly on the edit item. But doing so turns out to cause tabbing from one cell to the next to stop working. The reason is that QQuickItem refuses to change setActiveFocusOnTab() on an item that has active focus. Instead, the focus item will eat the tab event, and use it to transfer focus to the next control in the chain. We therefore change the implementation to use an event filter on the focus object. That way, we're are guaranteed to always get a first shot at handling all critical key events that are needed for editing to work correctly. This includes tabbing, but even more imporantant, also Qt::Key_Enter, which is needed to allow the user to commit and close the editor. Pick-to: 6.5 Change-Id: I215b7efc52093eb0bd7f6a4fb60a57f83101e288 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/quick/qquicktableview/data/editdelegate_combobox.qml67
-rw-r--r--tests/auto/quick/qquicktableview/tst_qquicktableview.cpp68
2 files changed, 135 insertions, 0 deletions
diff --git a/tests/auto/quick/qquicktableview/data/editdelegate_combobox.qml b/tests/auto/quick/qquicktableview/data/editdelegate_combobox.qml
new file mode 100644
index 0000000000..b7de4cd406
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/data/editdelegate_combobox.qml
@@ -0,0 +1,67 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import QtQuick
+import QtQuick.Window
+import QtQuick.Controls
+
+Item {
+ width: 640
+ height: 450
+
+ property alias tableView: tableView
+
+ TableView {
+ id: tableView
+ anchors.fill: parent
+ clip: true
+
+ property Item editItem: null
+ property Item focusItem: null
+ property var editIndex
+ property int commitCount: 0
+ property int comboFocusCount: 0
+
+ selectionModel: ItemSelectionModel {}
+
+ delegate: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 50
+
+ required property bool editing
+
+ Text {
+ anchors.centerIn: parent
+ text: display
+ visible: !editing
+ }
+
+ TableView.editDelegate: FocusScope {
+ id: editRoot
+ anchors.fill: parent
+ required property bool current
+ required property bool selected
+ required property bool editing
+
+ TableView.onCommit: tableView.commitCount++;
+
+ Component.onCompleted: {
+ tableView.editItem = editRoot
+ tableView.editIndex = tableView.modelIndex(row, column)
+ }
+
+ Component.onDestruction: {
+ tableView.editItem = null
+ tableView.editIndex = tableView.modelIndex(-1, -1)
+ }
+
+ ComboBox {
+ focus: true
+ model: 4
+ onActiveFocusChanged: if (activeFocus) tableView.comboFocusCount++;
+ }
+ }
+ }
+ }
+
+}
diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
index b0134a94d4..ecea4adfd5 100644
--- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
+++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
@@ -256,6 +256,7 @@ private slots:
void editUsingEditTriggers_data();
void editUsingEditTriggers();
void editUsingTab();
+ void editDelegateComboBox();
void editOnNonEditableCell_data();
void editOnNonEditableCell();
void noEditDelegate_data();
@@ -6752,6 +6753,73 @@ void tst_QQuickTableView::editUsingTab()
QVERIFY(editItem3);
}
+void tst_QQuickTableView::editDelegateComboBox()
+{
+ // Using a ComboBox as an edit delegate should be a quite common
+ // use case. So test that it works.
+ LOAD_TABLEVIEW("editdelegate_combobox.qml");
+
+ auto model = TestModel(4, 4);
+ tableView->setModel(QVariant::fromValue(&model));
+ tableView->forceActiveFocus();
+
+ const char kEditItem[] = "editItem";
+ const char kEditIndex[] = "editIndex";
+ const char kCommitCount[] = "commitCount";
+ const char kComboFocusCount[] = "comboFocusCount";
+
+ WAIT_UNTIL_POLISHED;
+
+ const QPoint cell1(1, 1);
+ const QPoint cell2(2, 1);
+ const QModelIndex index1 = tableView->modelIndex(cell1);
+ const QModelIndex index2 = tableView->modelIndex(cell2);
+
+ QQuickWindow *window = tableView->window();
+
+ // Edit cell 1
+ tableView->edit(index1);
+ QCOMPARE(tableView->property(kEditIndex).value<QModelIndex>(), index1);
+ const QQuickItem *editItem1 = tableView->property(kEditItem).value<QQuickItem *>();
+ QVERIFY(editItem1);
+ QCOMPARE(tableView->property(kComboFocusCount).value<int>(), 1);
+
+ // Press Tab to edit cell 2
+ QTest::keyClick(window, Qt::Key_Tab);
+ QCOMPARE(tableView->property(kCommitCount).value<int>(), 1);
+ QCOMPARE(tableView->property(kEditIndex).value<QModelIndex>(), index2);
+ const QQuickItem *editItem2 = tableView->property(kEditItem).value<QQuickItem *>();
+ QVERIFY(editItem2);
+ QCOMPARE(tableView->property(kComboFocusCount).value<int>(), 2);
+
+ // Press Enter to commit
+ QTest::keyClick(window, Qt::Key_Enter);
+ QCOMPARE(tableView->property(kCommitCount).value<int>(), 2);
+ QCOMPARE(tableView->property(kComboFocusCount).value<int>(), 2);
+ QVERIFY(!tableView->property(kEditIndex).value<QModelIndex>().isValid());
+ QVERIFY(!tableView->property(kEditItem).value<QQuickItem *>());
+
+ // Edit cell 1
+ tableView->edit(index1);
+ // Press escape to close editor
+ QTest::keyClick(window, Qt::Key_Escape);
+ QCOMPARE(tableView->property(kCommitCount).value<int>(), 2);
+ QCOMPARE(tableView->property(kComboFocusCount).value<int>(), 3);
+ QVERIFY(!tableView->property(kEditIndex).value<QModelIndex>().isValid());
+ QVERIFY(!tableView->property(kEditItem).value<QQuickItem *>());
+
+ // Edit cell 2
+ tableView->edit(index2);
+ // Press space to open combo menu
+ QTest::keyClick(window, Qt::Key_Space);
+ // Press Enter to commit and close the editor
+ QTest::keyClick(window, Qt::Key_Enter);
+ QCOMPARE(tableView->property(kCommitCount).value<int>(), 3);
+ QCOMPARE(tableView->property(kComboFocusCount).value<int>(), 4);
+ QVERIFY(!tableView->property(kEditIndex).value<QModelIndex>().isValid());
+ QVERIFY(!tableView->property(kEditItem).value<QQuickItem *>());
+}
+
void tst_QQuickTableView::editOnNonEditableCell_data()
{
QTest::addColumn<QQuickTableView::EditTriggers>("editTriggers");