diff options
Diffstat (limited to 'tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp')
-rw-r--r-- | tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp | 435 |
1 files changed, 317 insertions, 118 deletions
diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 0c9c3dc3ad..9b02b0e80d 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "../../../../shared/fakedirmodel.h" @@ -49,6 +24,8 @@ #include <private/qtreeview_p.h> #include <private/qtesthelpers_p.h> +#include <QtWidgets/private/qapplication_p.h> + using namespace QTestPrivate; #if QT_CONFIG(draganddrop) @@ -250,7 +227,10 @@ private slots: void taskQTBUG_7232_AllowUserToControlSingleStep(); void taskQTBUG_8376(); void taskQTBUG_61476(); + void taskQTBUG_42469_crash(); void testInitialFocus(); + void fetchUntilScreenFull(); + void expandAfterTake(); }; class QtTestModel: public QAbstractItemModel @@ -887,8 +867,8 @@ void tst_QTreeView::horizontalScrollMode() QTreeView view; setFrameless(&view); view.setModel(&model); - view.setFixedSize(100, 100); - view.header()->resizeSection(0, 200); + view.setFixedSize(100, 1000); + view.header()->resizeSection(0, 2000); view.show(); QCOMPARE(view.horizontalScrollMode(), QAbstractItemView::ScrollPerPixel); @@ -1069,7 +1049,7 @@ void tst_QTreeView::itemDelegateForColumnOrRow() QVERIFY(!view.itemDelegateForRow(0)); QVERIFY(!view.itemDelegateForColumn(0)); - QCOMPARE(view.itemDelegate(QModelIndex()), defaultDelegate); + QCOMPARE(view.itemDelegateForIndex(QModelIndex()), defaultDelegate); QStandardItemModel model; for (int i = 0; i < 100; ++i) { @@ -1085,26 +1065,26 @@ void tst_QTreeView::itemDelegateForColumnOrRow() QVERIFY(!view.itemDelegateForRow(0)); QVERIFY(!view.itemDelegateForColumn(0)); - QCOMPARE(view.itemDelegate(QModelIndex()), defaultDelegate); - QCOMPARE(view.itemDelegate(view.model()->index(0, 0)), defaultDelegate); + QCOMPARE(view.itemDelegateForIndex(QModelIndex()), defaultDelegate); + QCOMPARE(view.itemDelegateForIndex(view.model()->index(0, 0)), defaultDelegate); QPointer<QAbstractItemDelegate> rowDelegate = new QStyledItemDelegate; view.setItemDelegateForRow(0, rowDelegate); QVERIFY(!rowDelegate->parent()); QCOMPARE(view.itemDelegateForRow(0), rowDelegate); - QCOMPARE(view.itemDelegate(view.model()->index(0, 0)), rowDelegate); - QCOMPARE(view.itemDelegate(view.model()->index(0, 1)), rowDelegate); - QCOMPARE(view.itemDelegate(view.model()->index(1, 0)), defaultDelegate); - QCOMPARE(view.itemDelegate(view.model()->index(1, 1)), defaultDelegate); + QCOMPARE(view.itemDelegateForIndex(view.model()->index(0, 0)), rowDelegate); + QCOMPARE(view.itemDelegateForIndex(view.model()->index(0, 1)), rowDelegate); + QCOMPARE(view.itemDelegateForIndex(view.model()->index(1, 0)), defaultDelegate); + QCOMPARE(view.itemDelegateForIndex(view.model()->index(1, 1)), defaultDelegate); QPointer<QAbstractItemDelegate> columnDelegate = new QStyledItemDelegate; view.setItemDelegateForColumn(1, columnDelegate); QVERIFY(!columnDelegate->parent()); QCOMPARE(view.itemDelegateForColumn(1), columnDelegate); - QCOMPARE(view.itemDelegate(view.model()->index(0, 0)), rowDelegate); - QCOMPARE(view.itemDelegate(view.model()->index(0, 1)), rowDelegate); // row wins - QCOMPARE(view.itemDelegate(view.model()->index(1, 0)), defaultDelegate); - QCOMPARE(view.itemDelegate(view.model()->index(1, 1)), columnDelegate); + QCOMPARE(view.itemDelegateForIndex(view.model()->index(0, 0)), rowDelegate); + QCOMPARE(view.itemDelegateForIndex(view.model()->index(0, 1)), rowDelegate); // row wins + QCOMPARE(view.itemDelegateForIndex(view.model()->index(1, 0)), defaultDelegate); + QCOMPARE(view.itemDelegateForIndex(view.model()->index(1, 1)), columnDelegate); view.setItemDelegateForRow(0, nullptr); QVERIFY(!view.itemDelegateForRow(0)); @@ -1260,7 +1240,6 @@ void tst_QTreeView::keyboardSearchMultiColumn() view.setModel(&model); view.show(); - QApplication::setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowActive(&view)); view.setCurrentIndex(model.index(0, 1)); @@ -1301,7 +1280,7 @@ void tst_QTreeView::setModel() QCOMPARE(view.header()->model(), model); QCOMPARE(view.selectionModel() != oldSelectionModel, (i == 0)); } - QTRY_COMPARE(modelDestroyedSpy.count(), 0); + QTRY_COMPARE(modelDestroyedSpy.size(), 0); view.setModel(nullptr); QCOMPARE(view.model(), nullptr); @@ -1356,7 +1335,7 @@ void tst_QTreeView::setHeader() Qt::Orientation orient = x ? Qt::Vertical : Qt::Horizontal; QHeaderView *head = new QHeaderView(orient); view.setHeader(head); - QCOMPARE(destroyedSpy.count(), 1); + QCOMPARE(destroyedSpy.size(), 1); QCOMPARE(head->parent(), &view); QCOMPARE(view.header(), head); view.setHeader(head); @@ -1539,10 +1518,10 @@ void tst_QTreeView::limitedExpand() QVERIFY(spy.isValid()); view.expand(model.index(0, 0)); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); view.expand(model.index(1, 0)); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); } { QStringListModel model(QStringList() << "one" << "two"); @@ -1553,9 +1532,9 @@ void tst_QTreeView::limitedExpand() QVERIFY(spy.isValid()); view.expand(model.index(0, 0)); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); view.expandAll(); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); } } @@ -1594,58 +1573,58 @@ void tst_QTreeView::expandAndCollapse() view.expand(QModelIndex()); QCOMPARE(view.isExpanded(QModelIndex()), false); view.collapse(QModelIndex()); - QCOMPARE(expandedSpy.count(), 0); - QCOMPARE(collapsedSpy.count(), 0); + QCOMPARE(expandedSpy.size(), 0); + QCOMPARE(collapsedSpy.size(), 0); // expand a first level item QVERIFY(!view.isExpanded(a)); view.expand(a); QVERIFY(view.isExpanded(a)); - QCOMPARE(expandedSpy.count(), 1); - QCOMPARE(collapsedSpy.count(), 0); + QCOMPARE(expandedSpy.size(), 1); + QCOMPARE(collapsedSpy.size(), 0); args = expandedSpy.takeFirst(); QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), a); view.expand(a); QVERIFY(view.isExpanded(a)); - QCOMPARE(expandedSpy.count(), 0); - QCOMPARE(collapsedSpy.count(), 0); + QCOMPARE(expandedSpy.size(), 0); + QCOMPARE(collapsedSpy.size(), 0); // expand a second level item QVERIFY(!view.isExpanded(b)); view.expand(b); QVERIFY(view.isExpanded(a)); QVERIFY(view.isExpanded(b)); - QCOMPARE(expandedSpy.count(), 1); - QCOMPARE(collapsedSpy.count(), 0); + QCOMPARE(expandedSpy.size(), 1); + QCOMPARE(collapsedSpy.size(), 0); args = expandedSpy.takeFirst(); QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), b); view.expand(b); QVERIFY(view.isExpanded(b)); - QCOMPARE(expandedSpy.count(), 0); - QCOMPARE(collapsedSpy.count(), 0); + QCOMPARE(expandedSpy.size(), 0); + QCOMPARE(collapsedSpy.size(), 0); // collapse the first level item view.collapse(a); QVERIFY(!view.isExpanded(a)); QVERIFY(view.isExpanded(b)); - QCOMPARE(expandedSpy.count(), 0); - QCOMPARE(collapsedSpy.count(), 1); + QCOMPARE(expandedSpy.size(), 0); + QCOMPARE(collapsedSpy.size(), 1); args = collapsedSpy.takeFirst(); QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), a); view.collapse(a); QVERIFY(!view.isExpanded(a)); - QCOMPARE(expandedSpy.count(), 0); - QCOMPARE(collapsedSpy.count(), 0); + QCOMPARE(expandedSpy.size(), 0); + QCOMPARE(collapsedSpy.size(), 0); // expand the first level item again view.expand(a); QVERIFY(view.isExpanded(a)); QVERIFY(view.isExpanded(b)); - QCOMPARE(expandedSpy.count(), 1); - QCOMPARE(collapsedSpy.count(), 0); + QCOMPARE(expandedSpy.size(), 1); + QCOMPARE(collapsedSpy.size(), 0); args = expandedSpy.takeFirst(); QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), a); @@ -1653,8 +1632,8 @@ void tst_QTreeView::expandAndCollapse() view.collapse(b); QVERIFY(view.isExpanded(a)); QVERIFY(!view.isExpanded(b)); - QCOMPARE(expandedSpy.count(), 0); - QCOMPARE(collapsedSpy.count(), 1); + QCOMPARE(expandedSpy.size(), 0); + QCOMPARE(collapsedSpy.size(), 1); args = collapsedSpy.takeFirst(); QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), b); @@ -1662,8 +1641,8 @@ void tst_QTreeView::expandAndCollapse() view.collapse(a); QVERIFY(!view.isExpanded(a)); QVERIFY(!view.isExpanded(b)); - QCOMPARE(expandedSpy.count(), 0); - QCOMPARE(collapsedSpy.count(), 1); + QCOMPARE(expandedSpy.size(), 0); + QCOMPARE(collapsedSpy.size(), 1); args = collapsedSpy.takeFirst(); QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), a); @@ -1675,8 +1654,8 @@ void tst_QTreeView::expandAndCollapse() QVERIFY(view.isExpanded(a)); QVERIFY(view.isExpanded(b)); QVERIFY(!view.isExpanded(c)); - QCOMPARE(expandedSpy.count(), 2); - QCOMPARE(collapsedSpy.count(), 0); + QCOMPARE(expandedSpy.size(), 2); + QCOMPARE(collapsedSpy.size(), 0); args = expandedSpy.takeFirst(); QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), a); args = expandedSpy.takeFirst(); @@ -1687,8 +1666,8 @@ void tst_QTreeView::expandAndCollapse() QVERIFY(!view.isExpanded(a)); QVERIFY(!view.isExpanded(b)); QVERIFY(!view.isExpanded(c)); - QCOMPARE(expandedSpy.count(), 0); - QCOMPARE(collapsedSpy.count(), 2); + QCOMPARE(expandedSpy.size(), 0); + QCOMPARE(collapsedSpy.size(), 2); args = collapsedSpy.takeFirst(); QCOMPARE(qvariant_cast<QModelIndex>(args.at(0)), a); args = collapsedSpy.takeFirst(); @@ -1750,22 +1729,22 @@ void tst_QTreeView::expandAndCollapseAll() view.expandAll(); checkExpandState(model, view, QModelIndex(), true, &count); - QCOMPARE(collapsedSpy.count(), 0); - QCOMPARE(expandedSpy.count(), 39); // == 3 (first) + 9 (second) + 27 (third level) + QCOMPARE(collapsedSpy.size(), 0); + QCOMPARE(expandedSpy.size(), 39); // == 3 (first) + 9 (second) + 27 (third level) QCOMPARE(count, 39); collapsedSpy.clear(); expandedSpy.clear(); view.collapseAll(); checkExpandState(model, view, QModelIndex(), false, &count); - QCOMPARE(collapsedSpy.count(), 39); - QCOMPARE(expandedSpy.count(), 0); + QCOMPARE(collapsedSpy.size(), 39); + QCOMPARE(expandedSpy.size(), 0); QCOMPARE(count, 39); collapsedSpy.clear(); expandedSpy.clear(); view.expandRecursively(model.index(0, 0)); - QCOMPARE(expandedSpy.count(), 13); // 1 + 3 + 9 + QCOMPARE(expandedSpy.size(), 13); // 1 + 3 + 9 checkExpandState(model, view, model.index(0, 0), true, &count); QCOMPARE(count, 13); @@ -1777,9 +1756,9 @@ void tst_QTreeView::expandAndCollapseAll() expandedSpy.clear(); view.collapseAll(); view.expandRecursively(model.index(0, 0), 1); - QCOMPARE(expandedSpy.count(), 4); // 1 + 3 + QCOMPARE(expandedSpy.size(), 4); // 1 + 3 view.expandRecursively(model.index(0, 0), 2); - QCOMPARE(expandedSpy.count(), 13); // (1 + 3) + 9 + QCOMPARE(expandedSpy.size(), 13); // (1 + 3) + 9 checkExpandState(model, view, model.index(0, 0), true, &count); QCOMPARE(count, 13); @@ -1875,7 +1854,7 @@ void tst_QTreeView::keyboardNavigation() } break; default: - QVERIFY(false); + QFAIL(qPrintable(QStringLiteral("Unexpected key: %1").arg(key))); } QCOMPARE(view.currentIndex().row(), row); @@ -1946,7 +1925,6 @@ void tst_QTreeView::moveCursor() view.setColumnHidden(0, true); QVERIFY(view.isColumnHidden(0)); view.show(); - QApplication::setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowActive(&view)); //here the first visible index should be selected @@ -2047,7 +2025,7 @@ void tst_QTreeView::setSelection() QFETCH(PointList, expectedItems); QFETCH(int, verticalOffset); - QtTestModel model(10, 5); + QtTestModel model(100, 5); model.levels = 1; model.setDecorationsEnabled(true); QTreeView view; @@ -2065,7 +2043,7 @@ void tst_QTreeView::setSelection() QVERIFY(selectionModel); const QModelIndexList selectedIndexes = selectionModel->selectedIndexes(); - QCOMPARE(selectedIndexes.count(), expectedItems.count()); + QCOMPARE(selectedIndexes.size(), expectedItems.size()); for (const QModelIndex &idx : selectedIndexes) QVERIFY(expectedItems.contains(QPoint(idx.column(), idx.row()))); } @@ -2169,7 +2147,7 @@ void tst_QTreeView::clicked() continue; QSignalSpy spy(&view, &QTreeView::clicked); QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p); - QTRY_COMPARE(spy.count(), 1); + QTRY_COMPARE(spy.size(), 1); } } @@ -2250,7 +2228,7 @@ void tst_QTreeView::rowsAboutToBeRemoved() model.removeRows(1,1); QCOMPARE((view.state()), 0); // Should not be 5 (or any other number for that sake :) - QCOMPARE(spy1.count(), 1); + QCOMPARE(spy1.size(), 1); } @@ -2490,12 +2468,13 @@ void tst_QTreeView::spanningItems() // size hint // every second row is un-spanned - QStyleOptionViewItem option = view.viewOptions(); + QStyleOptionViewItem option; + view.initViewItemOption(&option); int w = view.header()->sectionSizeHint(0); for (int i = 0; i < model.rowCount(QModelIndex()); ++i) { if (!view.isFirstColumnSpanned(i, QModelIndex())) { QModelIndex index = model.index(i, 0, QModelIndex()); - w = qMax(w, view.itemDelegate(index)->sizeHint(option, index).width() + view.indentation()); + w = qMax(w, view.itemDelegateForIndex(index)->sizeHint(option, index).width() + view.indentation()); } } QCOMPARE(view.sizeHintForColumn(0), w); @@ -2561,28 +2540,28 @@ void tst_QTreeView::selectionWithHiddenItems() //child should not be selected as it is hidden (its parent is not expanded) view.selectAll(); - QCOMPARE(view.selectionModel()->selection().count(), 1); //one range - QCOMPARE(view.selectionModel()->selectedRows().count(), 4); + QCOMPARE(view.selectionModel()->selection().size(), 1); //one range + QCOMPARE(view.selectionModel()->selectedRows().size(), 4); view.expandAll(); QVERIFY(view.isExpanded(item1.index())); - QCOMPARE(view.selectionModel()->selection().count(), 1); - QCOMPARE(view.selectionModel()->selectedRows().count(), 4); + QCOMPARE(view.selectionModel()->selection().size(), 1); + QCOMPARE(view.selectionModel()->selectedRows().size(), 4); QVERIFY( !view.selectionModel()->isSelected(model.indexFromItem(&child))); view.clearSelection(); QVERIFY(view.isExpanded(item1.index())); //child should be selected as it is visible (its parent is expanded) view.selectAll(); - QCOMPARE(view.selectionModel()->selection().count(), 2); - QCOMPARE(view.selectionModel()->selectedRows().count(), 5); //everything is selected + QCOMPARE(view.selectionModel()->selection().size(), 2); + QCOMPARE(view.selectionModel()->selectedRows().size(), 5); //everything is selected view.clearSelection(); //we hide the node with a child (there should then be 3 items selected in 2 ranges) view.setRowHidden(1, QModelIndex(), true); QVERIFY(view.isExpanded(item1.index())); view.selectAll(); - QCOMPARE(view.selectionModel()->selection().count(), 2); - QCOMPARE(view.selectionModel()->selectedRows().count(), 3); + QCOMPARE(view.selectionModel()->selection().size(), 2); + QCOMPARE(view.selectionModel()->selectedRows().size(), 3); QVERIFY(!view.selectionModel()->isSelected(model.indexFromItem(&item1))); QVERIFY(!view.selectionModel()->isSelected(model.indexFromItem(&child))); @@ -2595,8 +2574,8 @@ void tst_QTreeView::selectionWithHiddenItems() QVERIFY(view.isExpanded(item1.index())); view.selectAll(); QVERIFY(view.isExpanded(item1.index())); - QCOMPARE(view.selectionModel()->selection().count(), 3); - QCOMPARE(view.selectionModel()->selectedRows().count(), 4); + QCOMPARE(view.selectionModel()->selection().size(), 3); + QCOMPARE(view.selectionModel()->selectedRows().size(), 4); QVERIFY( !view.selectionModel()->isSelected(model.indexFromItem(&item2))); view.setRowHidden(2, QModelIndex(), false); QVERIFY(view.isExpanded(item1.index())); @@ -2611,21 +2590,21 @@ void tst_QTreeView::selectAll() view2.setSelectionMode(QAbstractItemView::ExtendedSelection); view2.selectAll(); // Should work with an empty model //everything should be selected since we are in ExtendedSelection mode - QCOMPARE(view2.selectedIndexes().count(), model.rowCount() * model.columnCount()); + QCOMPARE(view2.selectedIndexes().size(), model.rowCount() * model.columnCount()); for (int i = 0; i < model.rowCount(); ++i) model.setData(model.index(i,0), QLatin1String("row ") + QString::number(i)); QTreeView view; view.setModel(&model); - int selectedCount = view.selectedIndexes().count(); + int selectedCount = view.selectedIndexes().size(); view.selectAll(); - QCOMPARE(view.selectedIndexes().count(), selectedCount); + QCOMPARE(view.selectedIndexes().size(), selectedCount); QTreeView view3; view3.setModel(&model); view3.setSelectionMode(QAbstractItemView::NoSelection); view3.selectAll(); - QCOMPARE(view3.selectedIndexes().count(), 0); + QCOMPARE(view3.selectedIndexes().size(), 0); } void tst_QTreeView::extendedSelection_data() @@ -2651,7 +2630,7 @@ void tst_QTreeView::extendedSelection() topLevel.show(); QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); QTest::mousePress(view.viewport(), Qt::LeftButton, {}, mousePressPos); - QCOMPARE(view.selectionModel()->selectedIndexes().count(), selectedCount); + QCOMPARE(view.selectionModel()->selectedIndexes().size(), selectedCount); } void tst_QTreeView::rowSizeHint() @@ -2851,6 +2830,14 @@ void tst_QTreeView::sortByColumn() QCOMPARE(view.model()->data(view.model()->index(1, 0)).toString(), QString::fromLatin1("d")); QCOMPARE(view.model()->data(view.model()->index(0, 1)).toString(), QString::fromLatin1("e")); QCOMPARE(view.model()->data(view.model()->index(1, 1)).toString(), QString::fromLatin1("g")); + + // a new 'sortByColumn()' should do a re-sort (e.g. due to the data changed), QTBUG-86268 + view.setModel(&model); + view.sortByColumn(0, Qt::AscendingOrder); + QCOMPARE(view.model()->data(view.model()->index(0, 0)).toString(), QString::fromLatin1("a")); + model.setItem(0, 0, new QStandardItem("x")); + view.sortByColumn(0, Qt::AscendingOrder); + QCOMPARE(view.model()->data(view.model()->index(0, 0)).toString(), QString::fromLatin1("b")); } /* @@ -2883,7 +2870,7 @@ public: } void kill() { - for (int i = children.count() -1; i >= 0; --i) { + for (int i = children.size() -1; i >= 0; --i) { children.at(i)->kill(); if (parent == nullptr) { deadChildren.append(children.at(i)); @@ -2925,7 +2912,7 @@ public: emit layoutAboutToBeChanged(); QModelIndexList oldList = persistentIndexList(); QList<QStack<int>> oldListPath; - for (int i = 0; i < oldList.count(); ++i) { + for (int i = 0; i < oldList.size(); ++i) { QModelIndex idx = oldList.at(i); QStack<int> path; while (idx.isValid()) { @@ -2937,7 +2924,7 @@ public: root->kill(); QModelIndexList newList; - for (auto path : qAsConst(oldListPath)) { + for (auto path : std::as_const(oldListPath)) { QModelIndex idx; while (!path.isEmpty()) idx = index(path.pop(), 0, idx); @@ -2956,7 +2943,7 @@ public: if (parentNode->isDead) qFatal("%s: parentNode is dead!", Q_FUNC_INFO); } - return parentNode->children.count(); + return parentNode->children.size(); } int columnCount(const QModelIndex &parent = QModelIndex()) const override { @@ -3547,7 +3534,7 @@ void tst_QTreeView::task174627_moveLeftToRoot() QSignalSpy spy(&view, &task174627_TreeView::signalCurrentChanged); QTest::keyClick(&view, Qt::Key_Left); - QCOMPARE(spy.count(), 0); + QCOMPARE(spy.size(), 0); } void tst_QTreeView::task171902_expandWith1stColHidden() @@ -3716,7 +3703,6 @@ void tst_QTreeView::task224091_appendColumns() treeView->setModel(model); topLevel->show(); treeView->resize(50, 50); - QApplication::setActiveWindow(topLevel); QVERIFY(QTest::qWaitForWindowActive(topLevel)); QVERIFY(!treeView->verticalScrollBar()->isVisible()); @@ -4053,7 +4039,7 @@ void tst_QTreeView::task248022_changeSelection() &view, &TreeView::handleSelectionChanged); QTest::mouseClick(view.viewport(), Qt::LeftButton, {}, view.visualRect(model.index(1)).center()); - QCOMPARE(view.selectionModel()->selectedIndexes().count(), list.count()); + QCOMPARE(view.selectionModel()->selectedIndexes().size(), list.size()); } void tst_QTreeView::task245654_changeModelAndExpandAll() @@ -4092,7 +4078,6 @@ void tst_QTreeView::doubleClickedWithSpans() view.setModel(&model); view.setFirstColumnSpanned(0, QModelIndex(), true); view.show(); - QApplication::setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowActive(&view)); QVERIFY(view.isActiveWindow()); @@ -4102,7 +4087,7 @@ void tst_QTreeView::doubleClickedWithSpans() QTest::mousePress(view.viewport(), Qt::LeftButton, {}, p); QTest::mouseDClick(view.viewport(), Qt::LeftButton, {}, p); QTest::mouseRelease(view.viewport(), Qt::LeftButton, {}, p); - QCOMPARE(spy.count(), 1); + QCOMPARE(spy.size(), 1); //let's click on the 2nd column p.setX(p.x() + view.header()->sectionSize(0)); @@ -4113,7 +4098,7 @@ void tst_QTreeView::doubleClickedWithSpans() QTest::mousePress(view.viewport(), Qt::LeftButton, {}, p); QTest::mouseDClick(view.viewport(), Qt::LeftButton, {}, p); QTest::mouseRelease(view.viewport(), Qt::LeftButton, {}, p); - QTRY_COMPARE(spy.count(), 2); + QTRY_COMPARE(spy.size(), 2); } void tst_QTreeView::taskQTBUG_6450_selectAllWith1stColumnHidden() @@ -4194,7 +4179,6 @@ void tst_QTreeView::keyboardNavigationWithDisabled() view.resize(200, view.visualRect(model.index(0,0)).height()*10); topLevel.show(); - QApplication::setActiveWindow(&topLevel); QVERIFY(QTest::qWaitForWindowActive(&topLevel)); QVERIFY(topLevel.isActiveWindow()); @@ -4777,10 +4761,9 @@ void tst_QTreeView::statusTip() mw.setCentralWidget(view); } mw.statusBar(); - mw.setGeometry(QRect(QPoint(QApplication::desktop()->geometry().center() - QPoint(250, 250)), + mw.setGeometry(QRect(QPoint(QGuiApplication::primaryScreen()->geometry().center() - QPoint(250, 250)), QSize(500, 500))); mw.show(); - QApplication::setActiveWindow(&mw); QVERIFY(QTest::qWaitForWindowActive(&mw)); // Ensure it is moved away first and then moved to the relevant section QTest::mouseMove(mw.windowHandle(), view->mapTo(&mw, view->rect().bottomLeft() + QPoint(20, 20))); @@ -4831,6 +4814,9 @@ void tst_QTreeView::fetchMoreOnScroll() if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); + if (QGuiApplication::platformName().startsWith(QLatin1String("eglfs"), Qt::CaseInsensitive)) + QSKIP("EGLFS does not allow resizing on top level window"); + QTreeView tw; FetchMoreModel im; tw.setModel(&im); @@ -4850,13 +4836,13 @@ void tst_QTreeView::checkIntersectedRect_data() { QStandardItemModel *model = new QStandardItemModel; for (int i = 0; i < rowCount; ++i) { - const QList<QStandardItem *> sil({new QStandardItem(QLatin1String("Row %1 Item").arg(i)), - new QStandardItem(QLatin1String("2nd column"))}); + const QList<QStandardItem *> sil({new QStandardItem(QString("Row %1 Item").arg(i)), + new QStandardItem(QString("2nd column"))}); model->appendRow(sil); } for (int i = 2; i < 4; ++i) { - const QList<QStandardItem *> sil({new QStandardItem(QLatin1String("Row %1 Item").arg(i)), - new QStandardItem(QLatin1String("2nd column"))}); + const QList<QStandardItem *> sil({new QStandardItem(QString("Row %1 Item").arg(i)), + new QStandardItem(QString("2nd column"))}); model->item(i)->appendRow(sil); } return model; @@ -4908,6 +4894,9 @@ void tst_QTreeView::checkIntersectedRect_data() void tst_QTreeView::checkIntersectedRect() { + if (QGuiApplication::platformName().startsWith(QLatin1String("eglfs"), Qt::CaseInsensitive)) + QSKIP("EGLFS does not allow resizing on top level window"); + QFETCH(QStandardItemModel *, model); QFETCH(const QList<QModelIndex>, changedIndexes); QFETCH(bool, isEmpty); @@ -5059,5 +5048,215 @@ void tst_QTreeView::taskQTBUG_61476() QCOMPARE(lastTopLevel->checkState(), Qt::Checked); } +void tst_QTreeView::taskQTBUG_42469_crash() +{ + QTreeWidget treeWidget; + QTreeWidgetItem *itemOne = new QTreeWidgetItem(QStringList("item1")); + QTreeWidgetItem *itemTwo = new QTreeWidgetItem(QStringList("item2")); + treeWidget.addTopLevelItem(itemOne); + treeWidget.addTopLevelItem(itemTwo); + treeWidget.topLevelItem(1)->addChild(new QTreeWidgetItem(QStringList("child1"))); + + treeWidget.setAnimated(true); + QObject::connect(&treeWidget, &QTreeWidget::itemExpanded, [&](QTreeWidgetItem* p_item) { + auto tempCount = treeWidget.topLevelItemCount(); + for (int j = 0; j < tempCount; ++j) + if (treeWidget.topLevelItem(j) != p_item) { + auto temp = treeWidget.topLevelItem(j); + temp->setHidden(true); + } + }); + + treeWidget.show(); + itemTwo->setExpanded(true); +} + +void tst_QTreeView::fetchUntilScreenFull() +{ + class TreeModel : public QAbstractItemModel + { + public: + const int maxChildren = 49; + explicit TreeModel(QObject* parent = nullptr) : QAbstractItemModel(parent) + { + QVariant rootData1("Parent Col 1"); + QVariant rootData2("Parent Col 2"); + QVector<QVariant> rootData; + rootData.append(rootData1); + rootData.append(rootData2); + + m_root = new TreeItem(rootData, nullptr); + + QVariant childData1("Col 1"); + QVariant childData2("Col 2"); + QVector<QVariant> childData; + childData.append(childData1); + childData.append(childData2); + + TreeItem* item_1 = new TreeItem(childData, m_root); + m_root->children.append(item_1); + + TreeItem* item_2 = new TreeItem(childData, item_1); + item_1->children.append(item_2); + } + + QModelIndex index(const int row, const int column, + const QModelIndex& parent = QModelIndex()) const override + { + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + TreeItem* parentItem = + parent.isValid() ? static_cast<TreeItem*>(parent.internalPointer()) : m_root; + TreeItem* childItem = parentItem->children.at(row); + return createIndex(row, column, childItem); + } + + int rowCount(const QModelIndex& parent) const override + { + if (parent.column() > 0) + return 0; + + TreeItem* parentItem = parent.isValid() ? static_cast<TreeItem*>(parent.internalPointer()) + : m_root; + return parentItem->children.size(); + } + + int columnCount(const QModelIndex&) const override { return 2; } + + QModelIndex parent(const QModelIndex& childIndex) const override + { + if (!childIndex.isValid()) + return QModelIndex(); + + TreeItem* parentItem = + static_cast<TreeItem*>(childIndex.internalPointer())->parent; + return parentItem == m_root ? QModelIndex() + : createIndex(parentItem->rowInParent(), 0, parentItem); + } + + QVariant data(const QModelIndex& index, const int role) const override + { + if (!index.isValid() || role != Qt::DisplayRole) + return QVariant(); + + TreeItem* item = static_cast<TreeItem*>(index.internalPointer()); + return item->data.at(index.column()); + } + + bool canFetchMore(const QModelIndex& parent) const override + { + if (!parent.isValid()) { + return false; + } else { + TreeItem* item = static_cast<TreeItem*>(parent.internalPointer()); + return item->children.size() < maxChildren; + } + } + + void fetchMore(const QModelIndex& parent) override + { + if (!parent.isValid()) + return; + + fetchMoreCount++; + TreeItem* parentItem = static_cast<TreeItem*>(parent.internalPointer()); + int childCount = parentItem->children.size(); + + beginInsertRows(parent, childCount, childCount); + + QVariant childData1("Col 1"); + QVariant childData2("Col 2"); + QVector<QVariant> childData; + childData.append(childData1); + childData.append(childData2); + TreeItem* newChild = new TreeItem(childData, parentItem); + parentItem->children.append(newChild); + + endInsertRows(); + } + + int fetchMoreCount = 0; + private: + struct TreeItem + { + TreeItem(const QVector<QVariant>& values, TreeItem* parent) + : data(values), parent(parent) + { + } + ~TreeItem() { qDeleteAll(children); } + int rowInParent() const + { + if (parent) + return parent->children.indexOf(const_cast<TreeItem*>(this)); + return 0; + } + QVector<QVariant> data; + QVector<TreeItem*> children; + TreeItem* parent = nullptr; + }; + TreeItem* m_root; + }; + + if (QGuiApplication::platformName().startsWith(QLatin1String("eglfs"), Qt::CaseInsensitive)) + QSKIP("EGLFS does not allow resizing on top level window"); + + + QTreeView tv; + TreeModel model; + tv.setModel(&model); + + const int itemHeight = tv.sizeHintForRow(0); + tv.resize(250, itemHeight * 10); + tv.show(); + QVERIFY(QTest::qWaitForWindowExposed(&tv)); + + tv.expand(model.index(0, 0)); + const int viewportHeight = tv.viewport()->height(); + const int itemCount = viewportHeight / itemHeight; + const int minFetchCount = itemCount - 1; + const int maxFetchCount = itemCount + 1; + + const bool expectedItemNumberFetched = model.fetchMoreCount >= minFetchCount + && model.fetchMoreCount <= maxFetchCount; + if (!expectedItemNumberFetched) + qDebug() << model.fetchMoreCount << minFetchCount << maxFetchCount; + QVERIFY(expectedItemNumberFetched); +} + +static void populateModel(QStandardItemModel *model) +{ + const int depth = 10; + for (int i1 = 0; i1 < depth; ++i1) { + QStandardItem *s1 = new QStandardItem; + s1->setText(QString::number(i1)); + model->appendRow(s1); + for (int i2 = 0; i2 < depth; ++i2) { + QStandardItem *s2 = new QStandardItem; + s2->setText(QStringLiteral("%1 - %2").arg(i1).arg(i2)); + s1->appendRow(s2); + for (int i3 = 0; i3 < depth; ++i3) { + QStandardItem *s3 = new QStandardItem; + s3->setText(QStringLiteral("%1 - %2 - %3").arg(i1).arg(i2).arg(i3)); + s2->appendRow(s3); + } + } + } +} + +void tst_QTreeView::expandAfterTake() +{ + QStandardItemModel model; + populateModel(&model); + QTreeView view; + view.setUniformRowHeights(true); + view.setModel(&model); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + view.expandAll(); + model.takeItem(0); + populateModel(&model); // populate model again, having corrupted items inside QTreeViewPrivate::expandedIndexes + view.expandAll(); // adding new items to QTreeViewPrivate::expandedIndexes with corrupted persistent indices, causing crash sometimes +} QTEST_MAIN(tst_QTreeView) #include "tst_qtreeview.moc" |