diff options
author | Andy Shaw <andy.shaw@qt.io> | 2017-11-01 12:11:33 +0100 |
---|---|---|
committer | Andy Shaw <andy.shaw@qt.io> | 2017-11-22 13:49:52 +0000 |
commit | 53f48fceeec7af4439ee45111e327dd4e7a226e8 (patch) | |
tree | cfaf3b6ca8189d18b11a3dd61cf7c4a24dc661a1 | |
parent | 048c380629e91231b3327949c98a49142eacbeba (diff) |
Start from the first visible item when doing a search
Since the first item in a treeview might be hidden, start from the
first visible item in the view when starting or wrapping round
during a keyboard search.
Task-number: QTBUG-63869
Change-Id: I202bea567c6d4484c3ffaf8a5f9af8ea2e13708d
Reviewed-by: Thorbjørn Lund Martsum <tmartsum@gmail.com>
-rw-r--r-- | src/widgets/itemviews/qtreeview.cpp | 18 | ||||
-rw-r--r-- | tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp | 97 |
2 files changed, 110 insertions, 5 deletions
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 805b855b9d..bbbadecff8 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -1014,11 +1014,16 @@ void QTreeView::keyboardSearch(const QString &search) if (!d->model->rowCount(d->root) || !d->model->columnCount(d->root)) return; + // Do a relayout nows, so that we can utilize viewItems + d->executePostedLayout(); + if (d->viewItems.isEmpty()) + return; + QModelIndex start; if (currentIndex().isValid()) start = currentIndex(); else - start = d->model->index(0, 0, d->root); + start = d->viewItems.at(0).index; bool skipRow = false; bool keyboardTimeWasValid = d->keyboardInputTime.isValid(); @@ -1046,13 +1051,16 @@ void QTreeView::keyboardSearch(const QString &search) // skip if we are searching for the same key or a new search started if (skipRow) { - if (indexBelow(start).isValid()) + if (indexBelow(start).isValid()) { start = indexBelow(start); - else - start = d->model->index(0, start.column(), d->root); + } else { + const int origCol = start.column(); + start = d->viewItems.at(0).index; + if (origCol != start.column()) + start = start.sibling(start.row(), origCol); + } } - d->executePostedLayout(); int startIndex = d->viewIndex(start); if (startIndex <= -1) return; diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 3260d7c968..dfcaa9b5b9 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -1067,6 +1067,103 @@ void tst_QTreeView::keyboardSearch() // The item that starts with B is selected. view.keyboardSearch(QLatin1String("B")); QVERIFY(view.selectionModel()->isSelected(model.index(1, 0))); + + // Test that it wraps round + model.appendRow(new QStandardItem("Andy")); + QTest::qWait(QApplication::keyboardInputInterval() * 2); + view.keyboardSearch(QLatin1String("A")); + QVERIFY(view.selectionModel()->isSelected(model.index(3, 0))); + QTest::qWait(QApplication::keyboardInputInterval() * 2); + view.keyboardSearch(QLatin1String("A")); + QVERIFY(view.selectionModel()->isSelected(model.index(0, 0))); + QTest::qWait(QApplication::keyboardInputInterval() * 2); + view.keyboardSearch(QLatin1String("A")); + QVERIFY(view.selectionModel()->isSelected(model.index(3, 0))); + + // Test that it handles the case where the first item is hidden correctly + model.insertRow(0, new QStandardItem("Hidden item")); + view.setRowHidden(0, QModelIndex(), true); + + QTest::qWait(QApplication::keyboardInputInterval() * 2); + view.keyboardSearch(QLatin1String("A")); + QVERIFY(view.selectionModel()->isSelected(model.index(1, 0))); + QTest::qWait(QApplication::keyboardInputInterval() * 2); + view.keyboardSearch(QLatin1String("A")); + QVERIFY(view.selectionModel()->isSelected(model.index(4, 0))); + QTest::qWait(QApplication::keyboardInputInterval() * 2); + view.keyboardSearch(QLatin1String("A")); + QVERIFY(view.selectionModel()->isSelected(model.index(1, 0))); + + QTest::qWait(QApplication::keyboardInputInterval() * 2); + model.clear(); + view.setCurrentIndex(QModelIndex()); + QList<QStandardItem *> items = { new QStandardItem("Andreas"), new QStandardItem("Alicia") }; + model.appendRow(items); + items = { new QStandardItem("Baldrian"), new QStandardItem("Belinda") }; + model.appendRow(items); + items = { new QStandardItem("Cecilie"), new QStandardItem("Claire") }; + model.appendRow(items); + QVERIFY(!view.selectionModel()->hasSelection()); + QVERIFY(!view.selectionModel()->isSelected(model.index(0, 0))); + + // We want to search on the 2nd column so we have to force it to have + // an index in that column as a starting point + view.setCurrentIndex(QModelIndex(model.index(0, 1))); + // Second item in first row is selected + view.keyboardSearch(QLatin1String("A")); + QTRY_VERIFY(view.selectionModel()->isSelected(model.index(0, 1))); + QVERIFY(view.currentIndex() == model.index(0, 1)); + + // Second item in first row is still selected + view.keyboardSearch(QLatin1String("l")); + QVERIFY(view.selectionModel()->isSelected(model.index(0, 1))); + QCOMPARE(view.currentIndex(), model.index(0, 1)); + + // No "AnB" item - keep the same selection. + view.keyboardSearch(QLatin1String("B")); + QVERIFY(view.selectionModel()->isSelected(model.index(0, 1))); + QCOMPARE(view.currentIndex(), model.index(0, 1)); + + // Wait a bit. + QTest::qWait(QApplication::keyboardInputInterval() * 2); + + // The item that starts with B is selected. + view.keyboardSearch(QLatin1String("B")); + QVERIFY(view.selectionModel()->isSelected(model.index(1, 1))); + QCOMPARE(view.currentIndex(), model.index(1, 1)); + + // Test that it wraps round + items = { new QStandardItem("Andy"), new QStandardItem("Adele") }; + model.appendRow(items); + QTest::qWait(QApplication::keyboardInputInterval() * 2); + view.keyboardSearch(QLatin1String("A")); + QVERIFY(view.selectionModel()->isSelected(model.index(3, 1))); + QCOMPARE(view.currentIndex(), model.index(3, 1)); + QTest::qWait(QApplication::keyboardInputInterval() * 2); + view.keyboardSearch(QLatin1String("A")); + QVERIFY(view.selectionModel()->isSelected(model.index(0, 1))); + QCOMPARE(view.currentIndex(), model.index(0, 1)); + QTest::qWait(QApplication::keyboardInputInterval() * 2); + view.keyboardSearch(QLatin1String("A")); + QVERIFY(view.selectionModel()->isSelected(model.index(3, 1))); + QCOMPARE(view.currentIndex(), model.index(3, 1)); + + // Test that it handles the case where the first item is hidden correctly + model.insertRow(0, new QStandardItem("Hidden item")); + view.setRowHidden(0, QModelIndex(), true); + + QTest::qWait(QApplication::keyboardInputInterval() * 2); + view.keyboardSearch(QLatin1String("A")); + QVERIFY(view.selectionModel()->isSelected(model.index(1, 1))); + QCOMPARE(view.currentIndex(), model.index(1, 1)); + QTest::qWait(QApplication::keyboardInputInterval() * 2); + view.keyboardSearch(QLatin1String("A")); + QVERIFY(view.selectionModel()->isSelected(model.index(4, 1))); + QCOMPARE(view.currentIndex(), model.index(4, 1)); + QTest::qWait(QApplication::keyboardInputInterval() * 2); + view.keyboardSearch(QLatin1String("A")); + QVERIFY(view.selectionModel()->isSelected(model.index(1, 1))); + QCOMPARE(view.currentIndex(), model.index(1, 1)); } void tst_QTreeView::keyboardSearchMultiColumn() |