summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/itemviews
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/widgets/itemviews')
-rw-r--r--tests/auto/widgets/itemviews/CMakeLists.txt3
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/BLACKLIST9
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/qtlogo.pngbin0 -> 2991 bytes
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp1123
-rw-r--r--tests/auto/widgets/itemviews/qcolumnview/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp69
-rw-r--r--tests/auto/widgets/itemviews/qdatawidgetmapper/CMakeLists.txt12
-rw-r--r--tests/auto/widgets/itemviews/qdatawidgetmapper/tst_qdatawidgetmapper.cpp50
-rw-r--r--tests/auto/widgets/itemviews/qfileiconprovider/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp30
-rw-r--r--tests/auto/widgets/itemviews/qheaderview/BLACKLIST2
-rw-r--r--tests/auto/widgets/itemviews/qheaderview/CMakeLists.txt13
-rw-r--r--tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp267
-rw-r--r--tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST6
-rw-r--r--tests/auto/widgets/itemviews/qitemdelegate/CMakeLists.txt13
-rw-r--r--tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp177
-rw-r--r--tests/auto/widgets/itemviews/qitemeditorfactory/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/itemviews/qitemeditorfactory/tst_qitemeditorfactory.cpp29
-rw-r--r--tests/auto/widgets/itemviews/qitemview/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp29
-rw-r--r--tests/auto/widgets/itemviews/qitemview/viewstotest.cpp29
-rw-r--r--tests/auto/widgets/itemviews/qlistview/CMakeLists.txt13
-rw-r--r--tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp578
-rw-r--r--tests/auto/widgets/itemviews/qlistwidget/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp308
-rw-r--r--tests/auto/widgets/itemviews/qtableview/BLACKLIST7
-rw-r--r--tests/auto/widgets/itemviews/qtableview/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp362
-rw-r--r--tests/auto/widgets/itemviews/qtablewidget/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp261
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/BLACKLIST5
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp183
-rw-r--r--tests/auto/widgets/itemviews/qtreewidget/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp305
-rw-r--r--tests/auto/widgets/itemviews/qtreewidgetitemiterator/CMakeLists.txt11
-rw-r--r--tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp31
38 files changed, 2979 insertions, 1056 deletions
diff --git a/tests/auto/widgets/itemviews/CMakeLists.txt b/tests/auto/widgets/itemviews/CMakeLists.txt
index ec6e00ec7f..60e05fadb4 100644
--- a/tests/auto/widgets/itemviews/CMakeLists.txt
+++ b/tests/auto/widgets/itemviews/CMakeLists.txt
@@ -1,4 +1,5 @@
-# Generated from itemviews.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(qabstractitemview)
add_subdirectory(qdatawidgetmapper)
diff --git a/tests/auto/widgets/itemviews/qabstractitemview/BLACKLIST b/tests/auto/widgets/itemviews/qabstractitemview/BLACKLIST
index 249c91c3c4..778a25b2e4 100644
--- a/tests/auto/widgets/itemviews/qabstractitemview/BLACKLIST
+++ b/tests/auto/widgets/itemviews/qabstractitemview/BLACKLIST
@@ -1,5 +1,4 @@
-[task200665_itemEntered]
-macos # Can't move cursor (QTBUG-76312)
-# QTBUG-87400
-[task200665_itemEntered]
-android
+[focusNextOnHide]
+wayland
+[selectionAutoScrolling]
+wayland
diff --git a/tests/auto/widgets/itemviews/qabstractitemview/CMakeLists.txt b/tests/auto/widgets/itemviews/qabstractitemview/CMakeLists.txt
index e779b1a165..ca39501a95 100644
--- a/tests/auto/widgets/itemviews/qabstractitemview/CMakeLists.txt
+++ b/tests/auto/widgets/itemviews/qabstractitemview/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qabstractitemview.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qabstractitemview Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qabstractitemview LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qabstractitemview
SOURCES
tst_qabstractitemview.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::GuiPrivate
Qt::TestPrivate
diff --git a/tests/auto/widgets/itemviews/qabstractitemview/qtlogo.png b/tests/auto/widgets/itemviews/qabstractitemview/qtlogo.png
new file mode 100644
index 0000000000..4f68e162de
--- /dev/null
+++ b/tests/auto/widgets/itemviews/qabstractitemview/qtlogo.png
Binary files differ
diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
index 10320c80d6..4f2495375d 100644
--- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
+++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <private/qguiapplication_p.h>
@@ -35,11 +10,13 @@
#include <QHeaderView>
#include <QIdentityProxyModel>
#include <QItemDelegate>
+#include <QLabel>
#include <QLineEdit>
#include <QListWidget>
#include <QProxyStyle>
#include <QPushButton>
#include <QScrollBar>
+#include <QScroller>
#include <QSignalSpy>
#include <QSortFilterProxyModel>
#include <QSpinBox>
@@ -47,11 +24,13 @@
#include <QStringListModel>
#include <QStyledItemDelegate>
#include <QTableWidget>
+#include <QTimer>
#include <QTreeWidget>
#include <QTest>
#include <QVBoxLayout>
#include <QtTest/private/qtesthelpers_p.h>
#include <private/qabstractitemview_p.h>
+#include <QtWidgets/private/qapplication_p.h>
Q_DECLARE_METATYPE(Qt::ItemFlags);
@@ -100,6 +79,7 @@ private slots:
void selectAll();
void ctrlA();
void persistentEditorFocus();
+ void pressClosesReleaseDoesntOpenEditor();
void setItemDelegate();
void setItemDelegate_data();
// The dragAndDrop() test doesn't work, and is thus disabled on Mac and Windows
@@ -129,6 +109,7 @@ private slots:
void QTBUG6407_extendedSelection();
void QTBUG6753_selectOnSelection();
void testDelegateDestroyEditor();
+ void testDelegateDestroyEditorChild();
void testClickedSignal();
void testChangeEditorState();
void deselectInSingleSelection();
@@ -154,8 +135,24 @@ private slots:
void checkFocusAfterActivationChanges_data();
void checkFocusAfterActivationChanges();
void dragSelectAfterNewPress();
+ void dragWithSecondClick_data();
+ void dragWithSecondClick();
+ void clickAfterDoubleClick();
void selectionCommand_data();
void selectionCommand();
+ void mouseSelection_data();
+ void mouseSelection();
+ void keepSingleSelectionOnEmptyAreaClick();
+ void scrollerSmoothScroll();
+ void inputMethodOpensEditor_data();
+ void inputMethodOpensEditor();
+ void selectionAutoScrolling_data();
+ void selectionAutoScrolling();
+ void testSpinBoxAsEditor_data();
+ void testSpinBoxAsEditor();
+ void removeIndexWhileEditing();
+ void focusNextOnHide();
+
private:
static QAbstractItemView *viewFromString(const QByteArray &viewType, QWidget *parent = nullptr)
{
@@ -181,17 +178,19 @@ public:
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const override
{
openedEditor = new QWidget(parent);
+ virtualCtorCallCount++;
return openedEditor;
}
void destroyEditor(QWidget *editor, const QModelIndex &) const override
{
- calledVirtualDtor = true;
+ virtualDtorCallCount++;
editor->deleteLater();
}
void changeSize() { size = QSize(50, 50); emit sizeHintChanged(QModelIndex()); }
mutable QWidget *openedEditor = nullptr;
QSize size;
- mutable bool calledVirtualDtor = false;
+ mutable int virtualCtorCallCount = 0;
+ mutable int virtualDtorCallCount = 0;
};
class DialogItemDelegate : public QStyledItemDelegate
@@ -434,12 +433,12 @@ void tst_QAbstractItemView::basic_tests(QAbstractItemView *view)
QVERIFY(spy.isValid());
view->setIconSize(QSize(32, 32));
QCOMPARE(view->iconSize(), QSize(32, 32));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(0).value<QSize>(), QSize(32, 32));
// Should this happen?
view->setIconSize(QSize(-1, -1));
QCOMPARE(view->iconSize(), QSize(-1, -1));
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
QCOMPARE(view->currentIndex(), QModelIndex());
QCOMPARE(view->rootIndex(), QModelIndex());
@@ -673,9 +672,9 @@ void tst_QAbstractItemView::selectAll()
GeometriesTestView view;
view.setModel(&model);
- QCOMPARE(view.selectedIndexes().count(), 0);
+ QCOMPARE(view.selectedIndexes().size(), 0);
view.selectAll();
- QCOMPARE(view.selectedIndexes().count(), 4 * 4);
+ QCOMPARE(view.selectedIndexes().size(), 4 * 4);
}
void tst_QAbstractItemView::ctrlA()
@@ -684,9 +683,9 @@ void tst_QAbstractItemView::ctrlA()
GeometriesTestView view;
view.setModel(&model);
- QCOMPARE(view.selectedIndexes().count(), 0);
+ QCOMPARE(view.selectedIndexes().size(), 0);
QTest::keyClick(&view, Qt::Key_A, Qt::ControlModifier);
- QCOMPARE(view.selectedIndexes().count(), 4 * 4);
+ QCOMPARE(view.selectedIndexes().size(), 4 * 4);
}
void tst_QAbstractItemView::persistentEditorFocus()
@@ -703,7 +702,7 @@ void tst_QAbstractItemView::persistentEditorFocus()
//these are spinboxes because we put numbers inside
const QList<QSpinBox*> list = view.viewport()->findChildren<QSpinBox*>();
- QCOMPARE(list.count(), 2); //these should be the 2 editors
+ QCOMPARE(list.size(), 2); //these should be the 2 editors
view.setCurrentIndex(model.index(0, 0));
QCOMPARE(view.currentIndex(), model.index(0, 0));
@@ -715,8 +714,8 @@ void tst_QAbstractItemView::persistentEditorFocus()
const QPoint p(5, 5);
for (QSpinBox *sb : list) {
QTRY_VERIFY(sb->isVisible());
- QMouseEvent mouseEvent(QEvent::MouseButtonPress, p, Qt::LeftButton,
- Qt::LeftButton, Qt::NoModifier);
+ QMouseEvent mouseEvent(QEvent::MouseButtonPress, p, sb->mapToGlobal(p),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QCoreApplication::sendEvent(sb, &mouseEvent);
if (!QApplication::focusWidget())
QSKIP("Some window managers don't handle focus that well");
@@ -724,6 +723,47 @@ void tst_QAbstractItemView::persistentEditorFocus()
}
}
+/*!
+ A press into the selection area of an item being edited, but outside the editor,
+ closes the editor by transferring focus to the view. The corresponding release
+ should then not re-open the editor.
+
+ QTBUG-20456.
+*/
+void tst_QAbstractItemView::pressClosesReleaseDoesntOpenEditor()
+{
+ QStandardItemModel model(0, 1);
+ auto *parent = new QStandardItem("parent");
+ for (const auto &childText : {"child1", "child2"}) {
+ auto *child = new QStandardItem(childText);
+ child->setFlags(Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsEditable | Qt::ItemIsSelectable);
+ parent->appendRow(child);
+ }
+ model.appendRow(parent);
+
+ QTreeView view;
+ view.setModel(&model);
+ view.setExpanded(model.indexFromItem(parent), true);
+ view.setSelectionMode(QAbstractItemView::SingleSelection);
+ view.setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::DoubleClicked);
+
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ const QRect childRect = view.visualRect(model.indexFromItem(parent->child(0)));
+ QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, childRect.center()); // select
+ QVERIFY(view.selectionModel()->selectedIndexes().contains(model.indexFromItem(parent->child(0))));
+ QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, childRect.center()); // edit
+ QTRY_COMPARE(view.state(), QAbstractItemView::EditingState);
+ QPoint inChildOutsideEditor = QPoint(view.indentation() / 2, childRect.center().y());
+ QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::NoModifier, inChildOutsideEditor); // focus itemview, editor closes
+ QCOMPARE(view.state(), QAbstractItemView::NoState);
+ QTest::qWait(10); // process some events, let the internal timer time out
+ QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, inChildOutsideEditor); // should not reopen editor
+ QTest::qWait(QApplication::doubleClickInterval() * 2);
+ QCOMPARE(view.state(), QAbstractItemView::NoState);
+}
+
#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN)
@@ -901,7 +941,7 @@ void tst_QAbstractItemView::dragAndDrop()
if (successes < attempts) {
QString msg = QString("# successes (%1) < # attempts (%2)").arg(successes).arg(attempts);
- QWARN(msg.toLatin1());
+ qWarning() << qPrintable(msg);
}
QVERIFY(successes > 0); // allow for some "event unstability" (i.e. unless
// successes == 0, QAbstractItemView is probably ok!)
@@ -1011,7 +1051,6 @@ void tst_QAbstractItemView::setItemDelegate()
centerOnScreen(&v);
moveCursorAway(&v);
v.show();
- QApplication::setActiveWindow(&v);
QVERIFY(QTest::qWaitForWindowActive(&v));
QModelIndex index = model.index(cellToEdit.y(), cellToEdit.x());
@@ -1220,7 +1259,6 @@ void tst_QAbstractItemView::task221955_selectedEditor()
tree.show();
tree.setFocus();
tree.setCurrentIndex(tree.model()->index(1,0));
- QApplication::setActiveWindow(&tree);
QVERIFY(QTest::qWaitForWindowActive(&tree));
QVERIFY(! tree.selectionModel()->selectedIndexes().contains(tree.model()->index(3,0)));
@@ -1286,7 +1324,13 @@ void tst_QAbstractItemView::task200665_itemEntered()
{
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
QSKIP("Wayland: This fails. Figure out why.");
-
+ {
+ // skip if we can't move mouse
+ const QPoint cursorPos = QCursor::pos() + QPoint(10, 10);
+ QCursor::setPos(cursorPos);
+ if (!QTest::qWaitFor([cursorPos] { return QCursor::pos() == cursorPos; }, 500))
+ QSKIP("Can't move mouse");
+ }
//we test that view will emit entered
//when the scrollbar move but not the mouse itself
QStandardItemModel model(1000, 1);
@@ -1301,7 +1345,7 @@ void tst_QAbstractItemView::task200665_itemEntered()
QSignalSpy spy(&view, &QAbstractItemView::entered);
view.verticalScrollBar()->setValue(view.verticalScrollBar()->maximum());
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
}
void tst_QAbstractItemView::task257481_emptyEditor()
@@ -1324,17 +1368,17 @@ void tst_QAbstractItemView::task257481_emptyEditor()
treeView.edit(model.index(0, 0));
QList<QLineEdit *> lineEditors = treeView.viewport()->findChildren<QLineEdit *>();
- QCOMPARE(lineEditors.count(), 1);
+ QCOMPARE(lineEditors.size(), 1);
QVERIFY(!lineEditors.constFirst()->size().isEmpty());
treeView.edit(model.index(1, 0));
lineEditors = treeView.viewport()->findChildren<QLineEdit *>();
- QCOMPARE(lineEditors.count(), 1);
+ QCOMPARE(lineEditors.size(), 1);
QVERIFY(!lineEditors.constFirst()->size().isEmpty());
treeView.edit(model.index(2, 0));
lineEditors = treeView.viewport()->findChildren<QLineEdit *>();
- QCOMPARE(lineEditors.count(), 1);
+ QCOMPARE(lineEditors.size(), 1);
QVERIFY(!lineEditors.constFirst()->size().isEmpty());
}
@@ -1368,7 +1412,7 @@ void tst_QAbstractItemView::shiftArrowSelectionAfterScrolling()
QCOMPARE(view.currentIndex(), index1);
QModelIndexList selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 2);
+ QCOMPARE(selected.size(), 2);
QVERIFY(selected.contains(index0));
QVERIFY(selected.contains(index1));
}
@@ -1408,7 +1452,8 @@ void tst_QAbstractItemView::shiftSelectionAfterRubberbandSelection()
// The mouse move event has to be created manually because the QTest framework does not
// contain a function for mouse moves with buttons pressed
QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::NoModifier, pressPos);
- QMouseEvent moveEvent(QEvent::MouseMove, releasePos, Qt::NoButton, Qt::LeftButton, Qt::NoModifier);
+ QMouseEvent moveEvent(QEvent::MouseMove, releasePos, view.viewport()->mapToGlobal(releasePos),
+ Qt::NoButton, Qt::LeftButton, Qt::NoModifier);
bool moveEventReceived = qApp->notify(view.viewport(), &moveEvent);
QVERIFY(moveEventReceived);
QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, releasePos);
@@ -1421,7 +1466,7 @@ void tst_QAbstractItemView::shiftSelectionAfterRubberbandSelection()
// Verify that the selection worked OK
QModelIndexList selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 2);
+ QCOMPARE(selected.size(), 2);
QVERIFY(selected.contains(index1));
QVERIFY(selected.contains(index2));
@@ -1431,7 +1476,8 @@ void tst_QAbstractItemView::shiftSelectionAfterRubberbandSelection()
// Repeat the same steps as above, but with a Shift-Arrow selection
QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::NoModifier, pressPos);
- QMouseEvent moveEvent2(QEvent::MouseMove, releasePos, Qt::NoButton, Qt::LeftButton, Qt::NoModifier);
+ QMouseEvent moveEvent2(QEvent::MouseMove, releasePos, view.viewport()->mapToGlobal(releasePos),
+ Qt::NoButton, Qt::LeftButton, Qt::NoModifier);
moveEventReceived = qApp->notify(view.viewport(), &moveEvent2);
QVERIFY(moveEventReceived);
QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, releasePos);
@@ -1443,7 +1489,7 @@ void tst_QAbstractItemView::shiftSelectionAfterRubberbandSelection()
// Verify that the selection worked OK
selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 2);
+ QCOMPARE(selected.size(), 2);
QVERIFY(selected.contains(index1));
QVERIFY(selected.contains(index2));
}
@@ -1472,7 +1518,7 @@ void tst_QAbstractItemView::ctrlRubberbandSelection()
// Select item 1
view.setCurrentIndex(index1);
QModelIndexList selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 1);
+ QCOMPARE(selected.size(), 1);
QVERIFY(selected.contains(index1));
// Now press control and draw a rubberband around items 1 and 2.
@@ -1481,14 +1527,15 @@ void tst_QAbstractItemView::ctrlRubberbandSelection()
QPoint pressPos = view.visualRect(index1).topLeft() - QPoint(1, 1);
QPoint releasePos = view.visualRect(index2).bottomRight() + QPoint(1, 1);
QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::ControlModifier, pressPos);
- QMouseEvent moveEvent(QEvent::MouseMove, releasePos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
+ QMouseEvent moveEvent(QEvent::MouseMove, releasePos, view.viewport()->mapToGlobal(releasePos),
+ Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
bool moveEventReceived = qApp->notify(view.viewport(), &moveEvent);
QVERIFY(moveEventReceived);
QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::ControlModifier, releasePos);
// Verify that item 2 is selected now
selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 1);
+ QCOMPARE(selected.size(), 1);
QVERIFY(selected.contains(index2));
}
@@ -1510,7 +1557,6 @@ void tst_QAbstractItemView::QTBUG6407_extendedSelection()
moveCursorAway(&view);
view.show();
- QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(&view, QApplication::activeWindow());
@@ -1521,21 +1567,21 @@ void tst_QAbstractItemView::QTBUG6407_extendedSelection()
QVERIFY(view.viewport()->rect().contains(p));
QTest::mouseClick(view.viewport(), Qt::LeftButton, {}, p);
QCOMPARE(view.currentIndex(), index49);
- QCOMPARE(view.selectedItems().count(), 1);
+ QCOMPARE(view.selectedItems().size(), 1);
QModelIndex index47 = view.model()->index(47,0);
p = view.visualRect(index47).center();
QVERIFY(view.viewport()->rect().contains(p));
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, p);
QCOMPARE(view.currentIndex(), index47);
- QCOMPARE(view.selectedItems().count(), 3); //49, 48, 47;
+ QCOMPARE(view.selectedItems().size(), 3); //49, 48, 47;
QModelIndex index44 = view.model()->index(44,0);
p = view.visualRect(index44).center();
QVERIFY(view.viewport()->rect().contains(p));
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, p);
QCOMPARE(view.currentIndex(), index44);
- QCOMPARE(view.selectedItems().count(), 6); //49 .. 44;
+ QCOMPARE(view.selectedItems().size(), 6); //49 .. 44;
}
@@ -1560,7 +1606,7 @@ void tst_QAbstractItemView::QTBUG6753_selectOnSelection()
QTest::mouseMove(table.viewport(), itemRect.center());
QTest::mouseClick(table.viewport(), Qt::LeftButton, Qt::NoModifier, itemRect.center());
- QCOMPARE(table.selectedItems().count(), 1);
+ QCOMPARE(table.selectedItems().size(), 1);
QCOMPARE(table.selectedItems().first(), table.item(item.row(), item.column()));
}
@@ -1571,9 +1617,31 @@ void tst_QAbstractItemView::testDelegateDestroyEditor()
table.setItemDelegate(&delegate);
table.edit(table.model()->index(1, 1));
QAbstractItemView *tv = &table;
- QVERIFY(!delegate.calledVirtualDtor);
+ QCOMPARE(delegate.virtualDtorCallCount, 0);
tv->closeEditor(delegate.openedEditor, QAbstractItemDelegate::NoHint);
- QVERIFY(delegate.calledVirtualDtor);
+ QCOMPARE(delegate.virtualDtorCallCount, 1);
+}
+
+void tst_QAbstractItemView::testDelegateDestroyEditorChild()
+{
+ QTreeWidget tree;
+ MyAbstractItemDelegate delegate;
+ tree.setItemDelegate(&delegate);
+ QTreeWidgetItem *topLevel = new QTreeWidgetItem;
+ QTreeWidgetItem *levelOne1 = new QTreeWidgetItem(topLevel);
+ QTreeWidgetItem *levelTwo1 = new QTreeWidgetItem(levelOne1);
+ QTreeWidgetItem *levelOne2 = new QTreeWidgetItem(topLevel);
+ QTreeWidgetItem *levelTwo2 = new QTreeWidgetItem(levelOne2);
+ tree.insertTopLevelItem(0, topLevel);
+ tree.openPersistentEditor(levelOne1);
+ tree.openPersistentEditor(levelTwo1);
+ tree.openPersistentEditor(levelOne2);
+ tree.openPersistentEditor(levelTwo2);
+ QCOMPARE(delegate.virtualCtorCallCount, 4);
+ levelOne1->removeChild(levelTwo1);
+ QCOMPARE(delegate.virtualDtorCallCount, 1);
+ topLevel->removeChild(levelOne2);
+ QCOMPARE(delegate.virtualDtorCallCount, 3);
}
void tst_QAbstractItemView::testClickedSignal()
@@ -1586,7 +1654,6 @@ void tst_QAbstractItemView::testClickedSignal()
centerOnScreen(&view);
moveCursorAway(&view);
view.showNormal();
- QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(&view, QApplication::activeWindow());
@@ -1597,12 +1664,12 @@ void tst_QAbstractItemView::testClickedSignal()
QSignalSpy clickedSpy(&view, &QTableWidget::clicked);
QTest::mouseClick(view.viewport(), Qt::LeftButton, {}, p);
- QCOMPARE(clickedSpy.count(), 1);
+ QCOMPARE(clickedSpy.size(), 1);
QTest::mouseClick(view.viewport(), Qt::RightButton, {}, p);
// We expect that right-clicks do not cause the clicked() signal to
// be emitted.
- QCOMPARE(clickedSpy.count(), 1);
+ QCOMPARE(clickedSpy.size(), 1);
}
@@ -1637,7 +1704,6 @@ void tst_QAbstractItemView::testChangeEditorState()
centerOnScreen(&view);
moveCursorAway(&view);
view.show();
- QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(&view, QApplication::activeWindow());
@@ -1658,7 +1724,6 @@ void tst_QAbstractItemView::deselectInSingleSelection()
QVERIFY(QTest::qWaitForWindowExposed(&view));
view.setSelectionMode(QAbstractItemView::SingleSelection);
view.setEditTriggers(QAbstractItemView::NoEditTriggers);
- QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowExposed(&view));
// mouse
QModelIndex index22 = s.index(2, 2);
@@ -1666,28 +1731,28 @@ void tst_QAbstractItemView::deselectInSingleSelection()
QPoint clickpos = rect22.center();
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, clickpos);
QCOMPARE(view.currentIndex(), index22);
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), 1);
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, clickpos);
QCOMPARE(view.currentIndex(), index22);
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), 0);
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), 0);
// second click with modifier however does select
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, clickpos);
QCOMPARE(view.currentIndex(), index22);
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), 1);
// keyboard
QTest::keyClick(&view, Qt::Key_Space, Qt::NoModifier);
QCOMPARE(view.currentIndex(), index22);
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), 1);
QTest::keyClick(&view, Qt::Key_Space, Qt::ControlModifier);
QCOMPARE(view.currentIndex(), index22);
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), 0);
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), 0);
// second keypress with modifier however does select
QTest::keyClick(&view, Qt::Key_Space, Qt::ControlModifier);
QCOMPARE(view.currentIndex(), index22);
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), 1);
}
void tst_QAbstractItemView::testNoActivateOnDisabledItem()
@@ -1705,7 +1770,6 @@ void tst_QAbstractItemView::testNoActivateOnDisabledItem()
moveCursorAway(&treeView);
treeView.show();
- QApplication::setActiveWindow(&treeView);
QVERIFY(QTest::qWaitForWindowActive(&treeView));
QSignalSpy activatedSpy(&treeView, &QAbstractItemView::activated);
@@ -1715,7 +1779,7 @@ void tst_QAbstractItemView::testNoActivateOnDisabledItem()
QPoint clickPos = treeView.visualRect(itemIndex).center();
QTest::mouseClick(treeView.viewport(), Qt::LeftButton, {}, clickPos);
- QCOMPARE(activatedSpy.count(), 0);
+ QCOMPARE(activatedSpy.size(), 0);
}
void tst_QAbstractItemView::testFocusPolicy_data()
@@ -1752,7 +1816,6 @@ void tst_QAbstractItemView::testFocusPolicy()
moveCursorAway(&window);
window.show();
- QApplication::setActiveWindow(&window);
QVERIFY(QTest::qWaitForWindowActive(&window));
// itemview accepts focus => editor is closed => return focus to the itemview
@@ -1790,7 +1853,6 @@ void tst_QAbstractItemView::QTBUG31411_noSelection()
moveCursorAway(&window);
window.show();
- QApplication::setActiveWindow(&window);
QVERIFY(QTest::qWaitForWindowActive(&window));
qRegisterMetaType<QItemSelection>();
@@ -1809,7 +1871,7 @@ void tst_QAbstractItemView::QTBUG31411_noSelection()
QVERIFY(editor2);
QTest::keyClick(editor2, Qt::Key_Escape, Qt::NoModifier);
- QCOMPARE(selectionChangeSpy.count(), 0);
+ QCOMPARE(selectionChangeSpy.size(), 0);
}
void tst_QAbstractItemView::QTBUG39324_settingSameInstanceOfIndexWidget()
@@ -1851,7 +1913,7 @@ void tst_QAbstractItemView::shiftSelectionAfterChangingModelContents()
// Click "C"
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, view.visualRect(indexC).center());
QModelIndexList selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 1);
+ QCOMPARE(selected.size(), 1);
QVERIFY(selected.contains(indexC));
// Insert new item "B1"
@@ -1861,14 +1923,14 @@ void tst_QAbstractItemView::shiftSelectionAfterChangingModelContents()
// Shift-click "D" -> we expect that "C" and "D" are selected
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, view.visualRect(indexD).center());
selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 2);
+ QCOMPARE(selected.size(), 2);
QVERIFY(selected.contains(indexC));
QVERIFY(selected.contains(indexD));
// Click "D"
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, view.visualRect(indexD).center());
selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 1);
+ QCOMPARE(selected.size(), 1);
QVERIFY(selected.contains(indexD));
// Remove items "B" and "C"
@@ -1880,7 +1942,7 @@ void tst_QAbstractItemView::shiftSelectionAfterChangingModelContents()
// Shift-click "F" -> we expect that "D", "E", and "F" are selected
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, view.visualRect(indexF).center());
selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 3);
+ QCOMPARE(selected.size(), 3);
QVERIFY(selected.contains(indexD));
QVERIFY(selected.contains(indexE));
QVERIFY(selected.contains(indexF));
@@ -1889,7 +1951,7 @@ void tst_QAbstractItemView::shiftSelectionAfterChangingModelContents()
while (view.currentIndex() != indexA)
QTest::keyClick(&view, Qt::Key_Up);
selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 1);
+ QCOMPARE(selected.size(), 1);
QVERIFY(selected.contains(indexA));
// Change the sort order
@@ -1898,7 +1960,7 @@ void tst_QAbstractItemView::shiftSelectionAfterChangingModelContents()
// Shift-click "F" -> All items should be selected
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, view.visualRect(indexF).center());
selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), model.rowCount());
+ QCOMPARE(selected.size(), model.rowCount());
// Restore the old sort order
proxyModel.sort(0, Qt::AscendingOrder);
@@ -1906,7 +1968,7 @@ void tst_QAbstractItemView::shiftSelectionAfterChangingModelContents()
// Click "D"
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, view.visualRect(indexD).center());
selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 1);
+ QCOMPARE(selected.size(), 1);
QVERIFY(selected.contains(indexD));
// Insert new item "B2"
@@ -1916,7 +1978,7 @@ void tst_QAbstractItemView::shiftSelectionAfterChangingModelContents()
// Press Shift+Down -> "D" and "E" should be selected.
QTest::keyClick(&view, Qt::Key_Down, Qt::ShiftModifier);
selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 2);
+ QCOMPARE(selected.size(), 2);
QVERIFY(selected.contains(indexD));
QVERIFY(selected.contains(indexE));
@@ -1925,7 +1987,7 @@ void tst_QAbstractItemView::shiftSelectionAfterChangingModelContents()
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, view.visualRect(indexA).center());
view.setCurrentIndex(indexD);
selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 1);
+ QCOMPARE(selected.size(), 1);
QVERIFY(selected.contains(indexD));
// Insert new item "B3"
@@ -1935,7 +1997,7 @@ void tst_QAbstractItemView::shiftSelectionAfterChangingModelContents()
// Press Shift+Down -> "D" and "E" should be selected.
QTest::keyClick(&view, Qt::Key_Down, Qt::ShiftModifier);
selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 2);
+ QCOMPARE(selected.size(), 2);
QVERIFY(selected.contains(indexD));
QVERIFY(selected.contains(indexE));
}
@@ -2213,14 +2275,14 @@ void tst_QAbstractItemView::testClickToSelect()
// Click the center of the visualRect of item "A"
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, centerA);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.back().front().value<QRect>(), QRect(centerA, QSize(1, 1)));
// Click a point slightly away from the center
const QPoint nearCenterA = centerA + QPoint(1, 1);
QVERIFY(visualRectA.contains(nearCenterA));
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, nearCenterA);
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
QCOMPARE(spy.back().front().value<QRect>(), QRect(nearCenterA, QSize(1, 1)));
}
@@ -2390,15 +2452,11 @@ void tst_QAbstractItemView::inputMethodEnabled()
// Check focus by switching the activation of the window to force a focus in
view->setCurrentIndex(model->index(1, 0));
- QApplication::setActiveWindow(nullptr);
- QApplication::setActiveWindow(view.data());
QVERIFY(QTest::qWaitForWindowActive(view.data()));
QCOMPARE(view->testAttribute(Qt::WA_InputMethodEnabled), result);
view->setCurrentIndex(QModelIndex());
QVERIFY(!view->testAttribute(Qt::WA_InputMethodEnabled));
- QApplication::setActiveWindow(nullptr);
- QApplication::setActiveWindow(view.data());
QVERIFY(QTest::qWaitForWindowActive(view.data()));
QModelIndex index = model->index(1, 0);
QPoint p = view->visualRect(index).center();
@@ -2408,8 +2466,6 @@ void tst_QAbstractItemView::inputMethodEnabled()
QCOMPARE(view->testAttribute(Qt::WA_InputMethodEnabled), result);
index = model->index(0, 0);
- QApplication::setActiveWindow(nullptr);
- QApplication::setActiveWindow(view.data());
QVERIFY(QTest::qWaitForWindowActive(view.data()));
p = view->visualRect(index).center();
QTest::mouseClick(view->viewport(), Qt::LeftButton, Qt::NoModifier, p);
@@ -2419,11 +2475,11 @@ void tst_QAbstractItemView::inputMethodEnabled()
// There is a case when it goes to the first visible item so we
// make the flags of the first item match the ones we are testing
// to check the attribute correctly
- QApplication::setActiveWindow(nullptr);
+ QApplicationPrivate::setActiveWindow(nullptr);
view->setCurrentIndex(QModelIndex());
view->reset();
item->setFlags(Qt::ItemFlags(itemFlags));
- QApplication::setActiveWindow(view.data());
+ QApplicationPrivate::setActiveWindow(view.data());
QVERIFY(QTest::qWaitForWindowActive(view.data()));
QCOMPARE(view->testAttribute(Qt::WA_InputMethodEnabled), result);
}
@@ -2534,11 +2590,11 @@ void tst_QAbstractItemView::checkFocusAfterActivationChanges()
QVERIFY(QTest::qWaitForWindowExposed(delegate.openedEditor));
QVERIFY(delegate.openedEditor->hasFocus());
- QApplication::setActiveWindow(&otherTopLevel);
+ QApplicationPrivate::setActiveWindow(&otherTopLevel);
otherTopLevel.setFocus();
QTRY_VERIFY(!delegate.openedEditor);
- QApplication::setActiveWindow(&w);
+ QApplicationPrivate::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
QVERIFY(view->hasFocus());
}
@@ -2578,7 +2634,7 @@ void tst_QAbstractItemView::dragSelectAfterNewPress()
// Verify that the selection worked OK
QModelIndexList selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 3);
+ QCOMPARE(selected.size(), 3);
for (int i = 0; i < 2; ++i)
QVERIFY(selected.contains(model.index(i, 0)));
@@ -2586,8 +2642,8 @@ void tst_QAbstractItemView::dragSelectAfterNewPress()
const QPoint releasePos = view.visualRect(index5).center();
// The mouse move event has to be created manually because the QTest framework does not
// contain a function for mouse moves with buttons pressed
- QMouseEvent moveEvent2(QEvent::MouseMove, releasePos, Qt::NoButton, Qt::LeftButton,
- Qt::ShiftModifier);
+ QMouseEvent moveEvent2(QEvent::MouseMove, releasePos, view.viewport()->mapToGlobal(releasePos),
+ Qt::NoButton, Qt::LeftButton, Qt::ShiftModifier);
const bool moveEventReceived = qApp->notify(view.viewport(), &moveEvent2);
QVERIFY(moveEventReceived);
QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, releasePos);
@@ -2595,11 +2651,141 @@ void tst_QAbstractItemView::dragSelectAfterNewPress()
// Verify that the selection worked OK
selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 6);
+ QCOMPARE(selected.size(), 6);
for (int i = 0; i < 5; ++i)
QVERIFY(selected.contains(model.index(i, 0)));
}
+void tst_QAbstractItemView::dragWithSecondClick_data()
+{
+ QTest::addColumn<QByteArray>("viewClass");
+ QTest::addColumn<bool>("doubleClick");
+ const QList<QByteArray> widgets { "QListView", "QTreeView" };
+ for (const QByteArray &widget : widgets) {
+ QTest::newRow(widget + ": DoubleClick") << widget << true;
+ QTest::newRow(widget + ": Two Single Clicks") << widget << false;
+ }
+}
+
+// inject the ability to record which indexes get dragged into any QAbstractItemView class
+struct DragRecorder
+{
+ virtual ~DragRecorder() = default;
+ bool dragStarted = false;
+ QModelIndexList draggedIndexes;
+ QAbstractItemView *view;
+};
+
+template<class ViewClass>
+class DragRecorderView : public ViewClass, public DragRecorder
+{
+public:
+ DragRecorderView()
+ { view = this; }
+protected:
+ void startDrag(Qt::DropActions) override
+ {
+ draggedIndexes = ViewClass::selectedIndexes();
+ dragStarted = true;
+ }
+};
+
+void tst_QAbstractItemView::dragWithSecondClick()
+{
+ QFETCH(QByteArray, viewClass);
+ QFETCH(bool, doubleClick);
+
+ QStandardItemModel model;
+ QStandardItem *parentItem = model.invisibleRootItem();
+ for (int i = 0; i < 10; ++i) {
+ QStandardItem *item = new QStandardItem(QString("item %0").arg(i));
+ item->setDragEnabled(true);
+ item->setEditable(false);
+ parentItem->appendRow(item);
+ }
+
+ std::unique_ptr<DragRecorder> dragRecorder;
+ if (viewClass == "QTreeView")
+ dragRecorder.reset(new DragRecorderView<QTreeView>);
+ else if (viewClass == "QListView")
+ dragRecorder.reset(new DragRecorderView<QListView>);
+
+ QAbstractItemView *view = dragRecorder->view;
+ view->setModel(&model);
+ view->setFixedSize(160, 650); // Minimum width for windows with frame on Windows 8
+ view->setSelectionMode(QAbstractItemView::MultiSelection);
+ view->setDragDropMode(QAbstractItemView::InternalMove);
+ centerOnScreen(view);
+ moveCursorAway(view);
+ view->show();
+ QVERIFY(QTest::qWaitForWindowExposed(view));
+
+ QModelIndex index0 = model.index(0, 0);
+ QModelIndex index1 = model.index(1, 0);
+ // Select item 0 using a single click
+ QTest::mouseClick(view->viewport(), Qt::LeftButton, Qt::NoModifier,
+ view->visualRect(index0).center());
+ QCOMPARE(view->currentIndex(), index0);
+
+ if (doubleClick) {
+ // press on same item within the double click interval
+ QTest::mouseDClick(view->viewport(), Qt::LeftButton, Qt::NoModifier,
+ view->visualRect(index0).center());
+ } else {
+ // or on different item with a slow second press
+ QTest::mousePress(view->viewport(), Qt::LeftButton, Qt::NoModifier,
+ view->visualRect(index1).center());
+ }
+ // then drag far enough with left button held
+ const QPoint dragTo = view->visualRect(index1).center()
+ + QPoint(2 * QApplication::startDragDistance(),
+ 2 * QApplication::startDragDistance());
+ QMouseEvent mouseMoveEvent(QEvent::MouseMove, dragTo, view->viewport()->mapToGlobal(dragTo),
+ Qt::NoButton, Qt::LeftButton, Qt::NoModifier);
+ QVERIFY(QApplication::sendEvent(view->viewport(), &mouseMoveEvent));
+ // twice since the view will first enter dragging state, then start the drag
+ // (not necessary to actually move the mouse)
+ QVERIFY(QApplication::sendEvent(view->viewport(), &mouseMoveEvent));
+ QVERIFY(dragRecorder->dragStarted);
+ QTest::mouseRelease(view->viewport(), Qt::LeftButton, Qt::NoModifier, dragTo);
+}
+
+void tst_QAbstractItemView::clickAfterDoubleClick()
+{
+ QTableWidget view(5, 5);
+ view.horizontalHeader()->hide();
+ view.verticalHeader()->hide();
+ view.setEditTriggers(QAbstractItemView::NoEditTriggers);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ const QModelIndex index = view.model()->index(1, 1);
+ QVERIFY(index.isValid());
+ const QPoint clickPoint = view.visualRect(index).center();
+
+ // must use the QWindow overloads so that modality is respected
+ QWindow *window = view.window()->windowHandle();
+ int clickCount = 0;
+
+ connect(&view, &QAbstractItemView::doubleClicked, [&]{
+ QDialog dialog(&view);
+ dialog.setModal(true);
+ QTimer::singleShot(0, [&]{ dialog.close(); });
+ dialog.exec();
+ });
+ connect(&view, &QAbstractItemView::clicked, [&]{
+ ++clickCount;
+ });
+
+ QTest::mouseClick(window, Qt::LeftButton, {}, clickPoint);
+ QCOMPARE(clickCount, 1);
+ // generates a click followed by a double click; double click opens
+ // dialog that eats second release
+ QTest::mouseDClick(window, Qt::LeftButton, {}, clickPoint);
+ QCOMPARE(clickCount, 2);
+ QTest::mouseClick(window, Qt::LeftButton, {}, clickPoint);
+ QCOMPARE(clickCount, 3);
+}
+
void tst_QAbstractItemView::selectionCommand_data()
{
QTest::addColumn<QAbstractItemView::SelectionMode>("selectionMode");
@@ -2644,5 +2830,736 @@ void tst_QAbstractItemView::selectionCommand()
QCOMPARE(selectionFlag, view.selectionCommand(QModelIndex(), nullptr));
}
+struct SelectionEvent
+{
+ enum MouseEvent
+ { Press, Release, Click, Move };
+ constexpr SelectionEvent(MouseEvent type, int r = -1) noexcept
+ : eventType(type), row(r) {}
+ constexpr SelectionEvent(MouseEvent type, Qt::KeyboardModifiers mod, int r = -1) noexcept
+ : eventType(type), keyboardModifiers(mod), row(r) {}
+ MouseEvent eventType = Press;
+ Qt::KeyboardModifiers keyboardModifiers = Qt::NoModifier;
+ int row = -1;
+};
+
+void tst_QAbstractItemView::mouseSelection_data()
+{
+ QTest::addColumn<QAbstractItemView::SelectionMode>("selectionMode");
+ QTest::addColumn<bool>("dragEnabled");
+ QTest::addColumn<QAbstractItemView::EditTrigger>("editTrigger");
+ QTest::addColumn<QList<SelectionEvent>>("selectionEvents");
+ QTest::addColumn<QList<int>>("selectedRows");
+
+ // single selection mode - always one row selected, modifiers ignored
+ QTest::addRow("Single:Press") << QAbstractItemView::SingleSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 1)}
+ << QList{1};
+ QTest::addRow("Single:Click") << QAbstractItemView::SingleSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent{SelectionEvent::Click, 1}}
+ << QList{1};
+ QTest::addRow("Single:Press+Drag") << QAbstractItemView::SingleSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 1),
+ SelectionEvent{SelectionEvent::Move, 2},
+ SelectionEvent{SelectionEvent::Release}}
+ << QList{2};
+ QTest::addRow("Single:Shift+Click") << QAbstractItemView::SingleSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent{SelectionEvent::Click, Qt::ShiftModifier, 2}}
+ << QList{2};
+ QTest::addRow("Single:Press;Ctrl+Press") << QAbstractItemView::SingleSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent{SelectionEvent::Press, 3},
+ SelectionEvent{SelectionEvent::Press, Qt::ControlModifier, 3}}
+ << QList{3};
+ QTest::addRow("Single:Ctrl+Click") << QAbstractItemView::SingleSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent{SelectionEvent::Click, Qt::ControlModifier, 3}}
+ << QList{3};
+ QTest::addRow("Single:Click;Ctrl+Click") << QAbstractItemView::SingleSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent{SelectionEvent::Click, 3},
+ SelectionEvent{SelectionEvent::Click, Qt::ControlModifier, 3}}
+ << QList<int>{};
+
+ // multi selection mode - selection toggles on press, selection can be drag-extended
+ // modifiers ignored
+ QTest::addRow("Multi:Press") << QAbstractItemView::MultiSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 1)}
+ << QList{1};
+ QTest::addRow("Multi:Press twice") << QAbstractItemView::MultiSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 1),
+ SelectionEvent(SelectionEvent::Press, 1)}
+ << QList<int>{};
+ QTest::addRow("Multi:Press twice with drag enabled") << QAbstractItemView::MultiSelection << true
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Click, 1),
+ SelectionEvent(SelectionEvent::Press, 1)}
+ << QList{1};
+ QTest::addRow("Multi:Press and click with drag enabled") << QAbstractItemView::MultiSelection << true
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 1),
+ SelectionEvent(SelectionEvent::Click, 1)}
+ << QList<int>{};
+ QTest::addRow("Multi:Press,Press") << QAbstractItemView::MultiSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 2),
+ SelectionEvent(SelectionEvent::Press, 3)}
+ << QList{2, 3};
+ QTest::addRow("Multi:Press,Drag") << QAbstractItemView::MultiSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 1),
+ SelectionEvent(SelectionEvent::Move, 5),
+ SelectionEvent(SelectionEvent::Release)}
+ << QList{1, 2, 3, 4, 5};
+ QTest::addRow("Multi:Press,Drag,Deselect") << QAbstractItemView::MultiSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 1),
+ SelectionEvent(SelectionEvent::Move, 5),
+ SelectionEvent(SelectionEvent::Release),
+ SelectionEvent(SelectionEvent::Press, 3)}
+ << QList{1, 2, 4, 5};
+ // drag-select a few indices; then drag-select a larger area that includes the first
+ QTest::addRow("Multi:Press,Drag;Surround") << QAbstractItemView::MultiSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 3),
+ SelectionEvent(SelectionEvent::Move, 5),
+ SelectionEvent(SelectionEvent::Release),
+ SelectionEvent(SelectionEvent::Press, 1),
+ SelectionEvent(SelectionEvent::Move, 8),
+ SelectionEvent(SelectionEvent::Release)}
+ << QList{1, 2, 3, 4, 5, 6, 7, 8};
+ // drag-select a few indices; then try to select more starting with the last -> not working
+ QTest::addRow("Multi:Press,Drag;Expand") << QAbstractItemView::MultiSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 3),
+ SelectionEvent(SelectionEvent::Move, 5),
+ SelectionEvent(SelectionEvent::Release),
+ SelectionEvent(SelectionEvent::Press, 5), // this will deselect #5 and not select 6/7/8
+ SelectionEvent(SelectionEvent::Move, 8),
+ SelectionEvent(SelectionEvent::Release)}
+ << QList{3, 4};
+ // Multi: Press-dragging a selection should not deselect #QTBUG-59888
+ QTest::addRow("Multi:Press-Drag selection") << QAbstractItemView::MultiSelection << true
+ // with drag'n'drop enabled, we cannot drag a selection
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Click, 2),
+ SelectionEvent(SelectionEvent::Click, 3),
+ SelectionEvent(SelectionEvent::Click, 4),
+ SelectionEvent(SelectionEvent::Click, 5),
+ SelectionEvent(SelectionEvent::Press, 3),
+ // two moves needed because of distance and state logic in QAbstractItemView
+ SelectionEvent(SelectionEvent::Move, 5),
+ SelectionEvent(SelectionEvent::Move, 6)}
+ << QList{2, 3, 4, 5};
+
+ // Extended selection: Press selects a single item
+ QTest::addRow("Extended:Press") << QAbstractItemView::ExtendedSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 3)}
+ << QList{3};
+ QTest::addRow("Extended:Press twice") << QAbstractItemView::ExtendedSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 3),
+ SelectionEvent(SelectionEvent::Press, 3)}
+ << QList{3};
+ QTest::addRow("Extended:Press,Press") << QAbstractItemView::ExtendedSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 2),
+ SelectionEvent(SelectionEvent::Press, 3)}
+ << QList{3};
+ // Extended selection: press with Ctrl toggles item
+ QTest::addRow("Extended:Press,Toggle") << QAbstractItemView::ExtendedSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 3),
+ SelectionEvent(SelectionEvent::Click, Qt::ControlModifier, 3)}
+ << QList<int>{};
+ QTest::addRow("Extended:Press,Add") << QAbstractItemView::ExtendedSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 1),
+ SelectionEvent(SelectionEvent::Click, Qt::ControlModifier, 3)}
+ << QList{1, 3};
+ // Extended selection: Shift creates a range between first and last pressed
+ QTest::addRow("Extended:Press,Range") << QAbstractItemView::ExtendedSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 1),
+ SelectionEvent(SelectionEvent::Press, Qt::ShiftModifier, 5)}
+ << QList{1, 2, 3, 4, 5};
+ QTest::addRow("Extended:Press,Range,Fix Range") << QAbstractItemView::ExtendedSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 1),
+ SelectionEvent(SelectionEvent::Press, Qt::ShiftModifier, 5),
+ SelectionEvent(SelectionEvent::Press, Qt::ShiftModifier, 3)}
+ << QList{1, 2, 3};
+ // Extended: dragging extends the selection
+ QTest::addRow("Extended:Press,Drag") << QAbstractItemView::ExtendedSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 2),
+ SelectionEvent(SelectionEvent::Move, 5)}
+ << QList{2, 3, 4, 5};
+ // Extended: Ctrl+Press-dragging extends the selection
+ QTest::addRow("Extended:Press,Drag;Ctrl-Press,Drag") << QAbstractItemView::ExtendedSelection << false
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Press, 2),
+ SelectionEvent(SelectionEvent::Move, 5),
+ SelectionEvent(SelectionEvent::Release),
+ SelectionEvent(SelectionEvent::Press, Qt::ControlModifier, 6),
+ SelectionEvent(SelectionEvent::Move, Qt::ControlModifier, 8),
+ SelectionEvent(SelectionEvent::Release, Qt::ControlModifier, 8)}
+ << QList{2, 3, 4, 5, 6, 7, 8};
+ // Extended: Ctrl+Press-dragging in a selection should not deselect #QTBUG-59888
+ QTest::addRow("Extended:Ctrl-Drag selection,no deselect") << QAbstractItemView::ExtendedSelection << true
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Click, 2),
+ SelectionEvent(SelectionEvent::Click, Qt::ShiftModifier, 5),
+ SelectionEvent(SelectionEvent::Press, Qt::ControlModifier, 3),
+ SelectionEvent(SelectionEvent::Move, Qt::ControlModifier, 5),
+ // two moves needed because of distance and state logic in QAbstractItemView
+ SelectionEvent(SelectionEvent::Move, Qt::ControlModifier, 6)}
+ << QList{2, 3, 4, 5};
+ // Extended: Ctrl+Press-dragging with a selection extends, then drags #QTBUG-59888
+ QTest::addRow("Extended:Ctrl-Drag selection") << QAbstractItemView::ExtendedSelection << true
+ << QAbstractItemView::NoEditTriggers
+ << QList{SelectionEvent(SelectionEvent::Click, 2),
+ SelectionEvent(SelectionEvent::Click, Qt::ShiftModifier, 5),
+ SelectionEvent(SelectionEvent::Press, Qt::ControlModifier, 6),
+ SelectionEvent(SelectionEvent::Move, Qt::ControlModifier, 7),
+ // two moves needed because of distance and state logic in 7QAbstractItemView
+ SelectionEvent(SelectionEvent::Move, Qt::ControlModifier, 8)}
+ << QList{2, 3, 4, 5, 6};
+ // Extended: when drag is enabled, click with Ctrl toggles item instead of editing # QTBUG-111131
+ QTest::addRow("Extended:Click,Toggle,editable") << QAbstractItemView::ExtendedSelection << false
+ << QAbstractItemView::SelectedClicked
+ << QList{SelectionEvent(SelectionEvent::Click, 3),
+ SelectionEvent(SelectionEvent::Click, Qt::ControlModifier, 3)}
+ << QList<int>{};
+ QTest::addRow("Extended:Click,Toggle,dragable,editable") << QAbstractItemView::ExtendedSelection << true
+ << QAbstractItemView::SelectedClicked
+ << QList{SelectionEvent(SelectionEvent::Click, 3),
+ SelectionEvent(SelectionEvent::Click, Qt::ControlModifier, 3)}
+ << QList<int>{};
+ // Extended: when drag is enabled, click on selected without Ctrl clears before editing
+ QTest::addRow("Extended:Range,Click,editable") << QAbstractItemView::ExtendedSelection << false
+ << QAbstractItemView::SelectedClicked
+ << QList{SelectionEvent(SelectionEvent::Click, 1),
+ SelectionEvent(SelectionEvent::Click, Qt::ShiftModifier, 3),
+ SelectionEvent(SelectionEvent::Click, 2)}
+ << QList<int>{2};
+ QTest::addRow("Extended:Range,Click,dragable,editable") << QAbstractItemView::ExtendedSelection << true
+ << QAbstractItemView::SelectedClicked
+ << QList{SelectionEvent(SelectionEvent::Click, 1),
+ SelectionEvent(SelectionEvent::Click, Qt::ShiftModifier, 3),
+ SelectionEvent(SelectionEvent::Click, 2)}
+ << QList<int>{2};
+}
+
+void tst_QAbstractItemView::mouseSelection()
+{
+ QFETCH(QAbstractItemView::SelectionMode, selectionMode);
+ QFETCH(bool, dragEnabled);
+ QFETCH(QAbstractItemView::EditTrigger, editTrigger);
+ QFETCH(QList<SelectionEvent>, selectionEvents);
+ QFETCH(QList<int>, selectedRows);
+
+ QStandardItemModel model;
+ QStandardItem *parentItem = model.invisibleRootItem();
+ for (int i = 0; i < 10; ++i) {
+ QStandardItem *item = new QStandardItem(QString("item %0").arg(i));
+ item->setDragEnabled(dragEnabled);
+ item->setEditable(editTrigger != QAbstractItemView::NoEditTriggers);
+ parentItem->appendRow(item);
+ }
+
+ std::unique_ptr<DragRecorder> dragRecorder(new DragRecorderView<QTreeView>);
+ QAbstractItemView *view = dragRecorder->view;
+ QVERIFY(view);
+ view->setModel(&model);
+ view->setDragEnabled(dragEnabled);
+ view->setSelectionMode(selectionMode);
+ view->setEditTriggers(editTrigger);
+ view->show();
+ QVERIFY(QTest::qWaitForWindowActive(view));
+
+ Qt::MouseButton buttonDown = Qt::NoButton;
+ int targetRow = -1;
+ QModelIndex pressedIndex;
+ for (const auto &event : std::as_const(selectionEvents)) {
+ if (event.row != -1)
+ targetRow = event.row;
+ const QModelIndex targetIndex = model.index(targetRow, 0);
+ const QPoint targetPoint = view->visualRect(targetIndex).center();
+ switch (event.eventType) {
+ case SelectionEvent::Press:
+ if (buttonDown != Qt::NoButton) {
+ QTest::mouseRelease(view->viewport(), buttonDown, event.keyboardModifiers,
+ view->visualRect(pressedIndex).center());
+ }
+ buttonDown = Qt::LeftButton;
+ pressedIndex = model.index(targetRow, 0);
+ QTest::mousePress(view->viewport(), buttonDown, event.keyboardModifiers, targetPoint);
+ break;
+ case SelectionEvent::Release:
+ QTest::mouseRelease(view->viewport(), buttonDown, event.keyboardModifiers, targetPoint);
+ buttonDown = Qt::NoButton;
+ pressedIndex = QModelIndex();
+ break;
+ case SelectionEvent::Click:
+ QTest::mouseClick(view->viewport(), Qt::LeftButton, event.keyboardModifiers, targetPoint);
+ buttonDown = Qt::NoButton;
+ break;
+ case SelectionEvent::Move: {
+ QMouseEvent mouseMoveEvent(QEvent::MouseMove, targetPoint,
+ view->viewport()->mapToGlobal(targetPoint),
+ Qt::NoButton, buttonDown, event.keyboardModifiers);
+ QApplication::sendEvent(view->viewport(), &mouseMoveEvent);
+ }
+ break;
+ }
+ }
+
+ QList<int> actualSelected;
+ const auto selectedIndexes = dragRecorder->dragStarted
+ ? dragRecorder->draggedIndexes
+ : view->selectionModel()->selectedIndexes();
+ for (auto index : selectedIndexes)
+ actualSelected << index.row();
+
+ QCOMPARE(actualSelected, selectedRows);
+}
+
+/*!
+ Make sure that when clicking on empty space in the view, we don't
+ unselect the current row.
+ QTBUG-105870
+*/
+void tst_QAbstractItemView::keepSingleSelectionOnEmptyAreaClick()
+{
+ QListWidget view;
+ view.setSelectionMode(QAbstractItemView::SingleSelection);
+ QListWidgetItem *lastItem;
+ for (int i = 0; i < 5; i++)
+ lastItem = new QListWidgetItem("item " + QString::number(i), &view);
+
+ // Make widget large enough so that there is empty area below the last item
+ view.setFixedSize(300, 500);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowActive(&view));
+
+ // Select third row
+ view.setCurrentRow(2);
+
+ // Click below the last row
+ QPoint targetPoint = view.visualItemRect(lastItem).bottomLeft();
+ targetPoint += QPoint(10, 10);
+
+ QTest::mouseClick(view.viewport(), Qt::MouseButton::LeftButton, Qt::NoModifier, targetPoint);
+
+ QCOMPARE(view.currentRow(), 2);
+ QVERIFY(view.currentItem()->isSelected());
+}
+
+/*!
+ Verify that scrolling an autoScroll enabled itemview with a QScroller
+ produces a continuous, smooth scroll without any jumping around due to
+ the currentItem negotiation between QAbstractItemView and QScroller.
+ QTBUG-64543.
+*/
+void tst_QAbstractItemView::scrollerSmoothScroll()
+{
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
+ QSKIP("QWindow::requestActivate() is not supported.");
+
+ QListWidget view;
+ view.setAutoScroll(true);
+ view.setVerticalScrollMode(QListView::ScrollPerPixel);
+
+ QScroller::grabGesture(view.viewport(), QScroller::TouchGesture);
+ QScroller::grabGesture(view.viewport(), QScroller::LeftMouseButtonGesture);
+
+ for (int i = 0; i < 50; i++) {
+ QListWidgetItem* item = new QListWidgetItem("item " + QString::number(i), &view);
+ // gives items a touch friendly size so that only a few fit into the viewport
+ item->setSizeHint(QSize(100,50));
+ }
+
+ // make sure we have space for only a few items
+ view.setFixedSize(120, 200);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowActive(&view));
+
+ // we flick up, so we should never scroll back
+ int lastScrollPosition = 0;
+ bool scrollBack = false;
+ connect(view.verticalScrollBar(), &QScrollBar::valueChanged, [&](int value){
+ scrollBack |= (value < lastScrollPosition);
+ lastScrollPosition = value;
+ });
+
+ // start in the middle
+ view.scrollToItem(view.item(25));
+ QCOMPARE(view.currentItem(), view.item(0));
+ QListWidgetItem *pressItem = view.item(23);
+ QPoint dragPosition = view.visualRect(view.indexFromItem(pressItem)).center();
+ // the mouse press changes the current item temporarily, but the press is delayed
+ // by the gesture machinery. this is not what we are testing here, so skip the test
+ // if this fails within a reasonable amount of time.
+ QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::NoModifier, dragPosition);
+ if (!(QTest::qWaitFor([&]{ return view.currentItem() == pressItem; })))
+ QSKIP("Current item didn't change on press, skipping test");
+
+ // QAIV will reset the current item when the scroller changes state to Dragging
+ for (int y = 0; y < QApplication::startDragDistance() * 2; ++y) {
+ // gesture recognizer needs some throttling
+ QTest::qWait(10);
+ dragPosition -= QPoint(0, 10);
+ const QPoint globalPos = view.viewport()->mapToGlobal(dragPosition);
+ QMouseEvent mouseMoveEvent(QEvent::MouseMove, dragPosition, dragPosition, globalPos,
+ Qt::NoButton, Qt::LeftButton, Qt::NoModifier);
+ QApplication::sendEvent(view.viewport(), &mouseMoveEvent);
+ QVERIFY(!scrollBack);
+ }
+
+ QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::NoModifier, dragPosition);
+}
+
+/*!
+ Verify that starting the editing of an item with a key press while a composing
+ input method is active doesn't break the input method. See QTBUG-54848.
+*/
+void tst_QAbstractItemView::inputMethodOpensEditor_data()
+{
+ QTest::addColumn<QPoint>("editItem");
+ QTest::addColumn<QString>("preedit");
+ QTest::addColumn<QString>("commit");
+
+ QTest::addRow("IM accepted") << QPoint(1, 1) << "chang" << QString("é•¿");
+ QTest::addRow("IM cancelled") << QPoint(25, 25) << "chang" << QString();
+}
+
+void tst_QAbstractItemView::inputMethodOpensEditor()
+{
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
+ QSKIP("QWindow::requestActivate() is not supported.");
+
+ QTableWidget tableWidget(50, 50);
+ tableWidget.setEditTriggers(QAbstractItemView::AnyKeyPressed);
+ for (int r = 0; r < 50; ++r) {
+ for (int c = 0; c < 50; ++c )
+ tableWidget.setItem(r, c, new QTableWidgetItem(QString("Item %1:%2").arg(r).arg(c)));
+ }
+
+ tableWidget.show();
+ QVERIFY(QTest::qWaitForWindowActive(&tableWidget));
+
+ const auto sendInputMethodEvent = [](const QString &preeditText, const QString &commitString = {}){
+ QInputMethodEvent imEvent(preeditText, {});
+ imEvent.setCommitString(commitString);
+ QApplication::sendEvent(QApplication::focusWidget(), &imEvent);
+ };
+
+ QCOMPARE(QApplication::focusWidget(), &tableWidget);
+
+ QFETCH(QPoint, editItem);
+ QFETCH(QString, preedit);
+ QFETCH(QString, commit);
+
+ tableWidget.setCurrentCell(editItem.y(), editItem.x());
+ const QString orgText = tableWidget.currentItem()->text();
+ const QModelIndex currentIndex = tableWidget.currentIndex();
+ QCOMPARE(tableWidget.inputMethodQuery(Qt::ImCursorRectangle), tableWidget.visualRect(currentIndex));
+
+ // simulate the start of input via a composing input method
+ sendInputMethodEvent(preedit.left(1));
+ QCOMPARE(tableWidget.state(), QAbstractItemView::EditingState);
+ QLineEdit *editor = tableWidget.findChild<QLineEdit*>();
+ QVERIFY(editor);
+ QCOMPARE(editor->text(), QString());
+ // the focus must remain with the tableWidget, as otherwise the compositing is interrupted
+ QCOMPARE(QApplication::focusWidget(), &tableWidget);
+ // the item view delegates input method queries to the editor
+ const QRect cursorRect = tableWidget.inputMethodQuery(Qt::ImCursorRectangle).toRect();
+ QVERIFY(cursorRect.isValid());
+ QVERIFY(tableWidget.visualRect(currentIndex).intersects(cursorRect));
+
+ // finish preediting, then commit or cancel the input
+ sendInputMethodEvent(preedit);
+ sendInputMethodEvent(QString(), commit);
+ // editing continues, the editor now has focus
+ QCOMPARE(tableWidget.state(), QAbstractItemView::EditingState);
+ QVERIFY(editor->hasFocus());
+ // finish editing
+ QTest::keyClick(editor, Qt::Key_Return);
+ if (commit.isEmpty()) {
+ // if composition was cancelled, then the item's value is unchanged
+ QCOMPARE(tableWidget.currentItem()->text(), orgText);
+ } else {
+ // otherwise, the item's value is now the commit string
+ QTRY_COMPARE(tableWidget.currentItem()->text(), commit);
+ }
+}
+
+void tst_QAbstractItemView::selectionAutoScrolling_data()
+{
+ QTest::addColumn<Qt::Orientation>("orientation");
+ QTest::addColumn<int>("direction"); // negative or positive
+
+ QTest::addRow("scroll up") << Qt::Vertical << -1;
+ QTest::addRow("scroll left") << Qt::Horizontal << -1;
+ QTest::addRow("scroll down") << Qt::Vertical << +1;
+ QTest::addRow("scroll right") << Qt::Horizontal << +1;
+}
+
+void tst_QAbstractItemView::selectionAutoScrolling()
+{
+ QFETCH(Qt::Orientation, orientation);
+ QFETCH(int, direction);
+
+ QListView listview;
+ listview.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ listview.setResizeMode(QListView::Fixed);
+ listview.setAutoScroll(true);
+ listview.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ listview.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ listview.setSpacing(10);
+ listview.setGeometry(0, 0, 500, 500);
+ listview.setFrameShape(QFrame::Shape::NoFrame);
+ listview.setEditTriggers(QListView::NoEditTriggers);
+
+ QStandardItemModel *listModel = new QStandardItemModel(&listview);
+ listview.setModel(listModel);
+ listview.setViewMode(QListView::IconMode);
+ listview.setSelectionMode(QListView::ExtendedSelection);
+
+ QPixmap pm(50, 50);
+ pm.fill(Qt::red);
+ for (int i = 0; i < 80; i++) {
+ QStandardItem *item = new QStandardItem(pm, QString::number(i));
+ listModel->appendRow(item);
+ }
+
+ listview.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&listview));
+
+ listview.resize(200, 200);
+ // scroll to the middle
+ listview.verticalScrollBar()->setValue(listview.verticalScrollBar()->maximum() / 2);
+ listview.horizontalScrollBar()->setValue(listview.horizontalScrollBar()->maximum() / 2);
+
+ // remove all visible items so that we don't select any items at the edges, as that
+ // would scroll the view already
+ for (int x = 0; x < listview.viewport()->width(); x += 5) {
+ for (int y = 0; y < listview.viewport()->height(); y += 5) {
+ const QModelIndex index = listview.indexAt(QPoint(x, y));
+ if (index.isValid())
+ delete listModel->itemFromIndex(index);
+ }
+ }
+ // remove all items around the edges of the model
+ QRect topLeftRect = listview.visualRect(listModel->index(0, 0));
+ const QPoint topLeftCenter(topLeftRect.center());
+ QPoint bottomRightCenter;
+ for (int x = 0; x < listview.horizontalScrollBar()->maximum() + listview.viewport()->width(); x += 5) {
+ const QModelIndex index = listview.indexAt(topLeftCenter + QPoint(x, 0));
+ if (index.isValid()) {
+ delete listModel->itemFromIndex(index);
+ bottomRightCenter.rx() = x;
+ }
+ }
+ for (int y = 0; y < listview.verticalScrollBar()->maximum() + listview.viewport()->height(); y += 5) {
+ const QModelIndex index = listview.indexAt(topLeftCenter + QPoint(0, y));
+ if (index.isValid()) {
+ delete listModel->itemFromIndex(index);
+ bottomRightCenter.ry() = y;
+ }
+ }
+ for (int x = 0; x < bottomRightCenter.x(); x += 5) {
+ const QModelIndex index = listview.indexAt(topLeftCenter + QPoint(x, bottomRightCenter.y()));
+ if (index.isValid())
+ delete listModel->itemFromIndex(index);
+ }
+ for (int y = 0; y < bottomRightCenter.y(); y += 5) {
+ const QModelIndex index = listview.indexAt(topLeftCenter + QPoint(bottomRightCenter.x(), y));
+ if (index.isValid())
+ delete listModel->itemFromIndex(index);
+ }
+
+
+ // Simulate multiple select behavior; start in the middle, drag to the edge
+ const QPoint pressPoint(listview.viewport()->width() / 2, listview.viewport()->height() / 2);
+ QPoint dragPoint = pressPoint;
+ if (orientation == Qt::Vertical) {
+ dragPoint.rx() += 50;
+ dragPoint.ry() = direction > 0 ? listview.viewport()->height() : 0;
+ } else {
+ dragPoint.rx() = direction > 0 ? listview.viewport()->width() : 0;
+ dragPoint.ry() += 50;
+ }
+
+ QTest::mousePress(listview.viewport(), Qt::LeftButton, Qt::NoModifier, pressPoint);
+ QMouseEvent mmEvent(QEvent::MouseMove, dragPoint, listview.viewport()->mapToGlobal(dragPoint),
+ Qt::NoButton, Qt::LeftButton, Qt::NoModifier);
+ QApplication::sendEvent(listview.viewport(), &mmEvent); // QTest::mouseMove is useless
+
+ // check that we scrolled to the end
+ QScrollBar *scrollBar = orientation == Qt::Vertical
+ ? listview.verticalScrollBar()
+ : listview.horizontalScrollBar();
+
+ if (direction < 0)
+ QTRY_COMPARE(scrollBar->value(), 0);
+ else
+ QTRY_COMPARE(scrollBar->value(), scrollBar->maximum());
+ QVERIFY(listview.selectionModel()->selectedIndexes().size() > 0);
+
+ QTest::mouseRelease(listview.viewport(), Qt::LeftButton, Qt::NoModifier, dragPoint);
+}
+class SpinBoxDelegate : public QStyledItemDelegate
+{
+public:
+ using QStyledItemDelegate::QStyledItemDelegate;
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const override
+ {
+ QSpinBox *spinboxEditor = new QSpinBox(parent);
+ return spinboxEditor;
+ }
+
+ void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
+ {
+ if (QSpinBox *spin = qobject_cast<QSpinBox *>(editor)) {
+ model->setData(index, spin->value());
+ }
+ }
+};
+
+void tst_QAbstractItemView::testSpinBoxAsEditor_data()
+{
+ QTest::addColumn<bool>("keyboardTracking");
+ QTest::newRow("true") << true;
+ QTest::newRow("false")<< false;
+}
+
+void tst_QAbstractItemView::testSpinBoxAsEditor()
+{
+ QFETCH(bool, keyboardTracking);
+
+ QStandardItemModel model(2, 2);
+ SpinBoxDelegate delegate;
+
+ QTableView view;
+ view.setModel(&model);
+ view.setItemDelegate(&delegate);
+
+ view.setCurrentIndex(model.index(0, 1));
+ view.openPersistentEditor(model.index(0, 1));
+ const QList<QSpinBox *> list = view.viewport()->findChildren<QSpinBox *>();
+ QCOMPARE(list.size(), 1);
+ QSpinBox *sb = list.first();
+ QVERIFY(sb);
+
+ sb->setKeyboardTracking(keyboardTracking);
+
+ centerOnScreen(&view);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ QTRY_COMPARE(QApplication::focusWidget(), sb);
+
+ QTest::keyClick(sb, Qt::Key_1, Qt::NoModifier);
+ QPoint clickpos = view.visualRect(model.index(0, 0)).center();
+ QTest::mouseDClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, clickpos);
+
+ QCOMPARE(model.data(model.index(0, 1)).toInt(), 1);
+}
+
+void tst_QAbstractItemView::removeIndexWhileEditing()
+{
+ QTreeView view;
+ QStandardItemModel treeModel;
+ auto editableItem1 = new QStandardItem("aa");
+ auto editableItem2 = new QStandardItem("ab");
+ auto editableItem3 = new QStandardItem("ac");
+ auto item = new QStandardItem("a");
+ item->appendRow(editableItem1);
+ item->appendRow(editableItem2);
+ item->appendRow(editableItem3);
+ treeModel.setItem(0, 0, item);
+ QSortFilterProxyModel filterModel;
+ filterModel.setSourceModel(&treeModel);
+ view.setModel(&filterModel);
+ view.show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ view.setExpanded(item->index(), true);
+
+ filterModel.setFilterRegularExpression("a.*");
+
+ QTest::failOnWarning(QRegularExpression("QAbstractItemView::closeEditor called with an editor "
+ "that does not belong to this view"));
+
+ // Verify that we shut editing down cleanly if the index we are editing is
+ // filtered out after committing
+ {
+ const QModelIndex filteredIndex = filterModel.mapFromSource(editableItem1->index());
+ QVERIFY(filteredIndex.isValid());
+ view.edit(filteredIndex);
+ QCOMPARE(view.state(), QAbstractItemView::EditingState);
+ QTRY_VERIFY(QApplication::focusWidget());
+ QPointer<QLineEdit> lineEdit = qobject_cast<QLineEdit *>(QApplication::focusWidget());
+ QVERIFY(lineEdit);
+ lineEdit->setText("c");
+ QTest::keyClick(lineEdit, Qt::Key_Enter);
+ QTRY_VERIFY(!lineEdit);
+ QCOMPARE(editableItem1->data(Qt::DisplayRole), "c");
+ QCOMPARE(view.state(), QAbstractItemView::NoState);
+ }
+
+ // If we change the filter while we edit, then we should clean up state as well
+ {
+ const QModelIndex filteredIndex = filterModel.mapFromSource(editableItem2->index());
+ QVERIFY(filteredIndex.isValid());
+ view.edit(filteredIndex);
+ QCOMPARE(view.state(), QAbstractItemView::EditingState);
+ QTRY_VERIFY(QApplication::focusWidget());
+ QPointer<QLineEdit> lineEdit = qobject_cast<QLineEdit *>(QApplication::focusWidget());
+ QVERIFY(lineEdit);
+ filterModel.setFilterFixedString("c");
+ QVERIFY(!filterModel.mapFromSource(editableItem2->index()).isValid());
+ QTRY_VERIFY(!lineEdit);
+ QCOMPARE(view.state(), QAbstractItemView::NoState);
+ }
+}
+
+void tst_QAbstractItemView::focusNextOnHide()
+{
+ QWidget widget;
+ QTableWidget table(10, 10);
+ table.setTabKeyNavigation(true);
+ QLineEdit lineEdit;
+
+ QHBoxLayout layout;
+ layout.addWidget(&table);
+ layout.addWidget(&lineEdit);
+ widget.setLayout(&layout);
+
+ widget.setTabOrder({&table, &lineEdit});
+
+ widget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&widget));
+
+ QVERIFY(table.hasFocus());
+ QCOMPARE(table.currentIndex(), table.model()->index(0, 0));
+ QTest::keyPress(&table, Qt::Key_Tab);
+ QCOMPARE(table.currentIndex(), table.model()->index(0, 1));
+
+ table.hide();
+ QCOMPARE(table.currentIndex(), table.model()->index(0, 1));
+ QVERIFY(lineEdit.hasFocus());
+}
+
QTEST_MAIN(tst_QAbstractItemView)
#include "tst_qabstractitemview.moc"
diff --git a/tests/auto/widgets/itemviews/qcolumnview/CMakeLists.txt b/tests/auto/widgets/itemviews/qcolumnview/CMakeLists.txt
index 886971004b..8cf19c703e 100644
--- a/tests/auto/widgets/itemviews/qcolumnview/CMakeLists.txt
+++ b/tests/auto/widgets/itemviews/qcolumnview/CMakeLists.txt
@@ -1,14 +1,21 @@
-# Generated from qcolumnview.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qcolumnview Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qcolumnview LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qcolumnview
SOURCES
../../../../shared/fakedirmodel.h
tst_qcolumnview.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
diff --git a/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp b/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp
index 6dd39d5d2a..1ff9973e00 100644
--- a/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp
+++ b/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QColumnView>
#include <QScrollBar>
@@ -522,11 +497,11 @@ void tst_QColumnView::selectAll()
view.setModel(&m_fakeDirModel);
view.selectAll();
- QVERIFY(view.selectionModel()->selectedIndexes().count() >= 0);
+ QVERIFY(view.selectionModel()->selectedIndexes().size() >= 0);
view.setCurrentIndex(m_fakeDirHomeIndex);
view.selectAll();
- QVERIFY(view.selectionModel()->selectedIndexes().count() > 0);
+ QVERIFY(view.selectionModel()->selectedIndexes().size() > 0);
QModelIndex file;
for (int i = 0; i < m_fakeDirModel.rowCount(m_fakeDirHomeIndex); ++i) {
@@ -537,10 +512,10 @@ void tst_QColumnView::selectAll()
}
view.setCurrentIndex(file);
view.selectAll();
- QVERIFY(view.selectionModel()->selectedIndexes().count() > 0);
+ QVERIFY(view.selectionModel()->selectedIndexes().size() > 0);
view.setCurrentIndex(QModelIndex());
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), 0);
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), 0);
}
void tst_QColumnView::clicked()
@@ -561,13 +536,13 @@ void tst_QColumnView::clicked()
QPoint localPoint = view.visualRect(m_fakeDirHomeIndex).center();
QTest::mouseClick(view.viewport(), Qt::LeftButton, {}, localPoint);
- QCOMPARE(clickedSpy.count(), 1);
+ QCOMPARE(clickedSpy.size(), 1);
QCoreApplication::processEvents();
if (sizeof(qreal) != sizeof(double))
QSKIP("Skipped due to rounding errors");
- for (int i = 0; i < view.createdColumns.count(); ++i) {
+ for (int i = 0; i < view.createdColumns.size(); ++i) {
QAbstractItemView *column = view.createdColumns.at(i);
if (column && column->selectionModel() && (column->rootIndex() == m_fakeDirHomeIndex))
QVERIFY(column->selectionModel()->selectedIndexes().isEmpty());
@@ -585,7 +560,7 @@ void tst_QColumnView::selectedColumns()
QTest::qWait(ANIMATION_DELAY);
- for (int i = 0; i < view.createdColumns.count(); ++i) {
+ for (int i = 0; i < view.createdColumns.size(); ++i) {
QAbstractItemView *column = view.createdColumns.at(i);
if (!column)
continue;
@@ -616,7 +591,7 @@ void tst_QColumnView::setSelectionModel()
view.setSelectionModel(selectionModel);
bool found = false;
- for (int i = 0; i < view.createdColumns.count(); ++i) {
+ for (int i = 0; i < view.createdColumns.size(); ++i) {
if (view.createdColumns.at(i)->selectionModel() == selectionModel) {
found = true;
break;
@@ -656,7 +631,7 @@ void tst_QColumnView::moveGrip_basic()
view.setMinimumWidth(200);
grip->moveGrip(-800);
QCOMPARE(view.width(), 200);
- QCOMPARE(spy.count(), 5);
+ QCOMPARE(spy.size(), 5);
}
void tst_QColumnView::moveGrip_data()
@@ -684,7 +659,7 @@ void tst_QColumnView::moveGrip()
topLevel.show();
QVERIFY(QTest::qWaitForWindowActive(&topLevel));
- int columnNum = view.createdColumns.count() - 2;
+ int columnNum = view.createdColumns.size() - 2;
QVERIFY(columnNum >= 0);
const QObjectList list = view.createdColumns[columnNum]->children();
QColumnViewGrip *grip = nullptr;
@@ -712,7 +687,7 @@ void tst_QColumnView::doubleClick()
QCOMPARE(view.width(), 200);
QTest::mouseDClick(grip, Qt::LeftButton);
QCOMPARE(view.width(), view.sizeHint().width());
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
void tst_QColumnView::gripMoved()
@@ -736,7 +711,7 @@ void tst_QColumnView::gripMoved()
QCoreApplication::processEvents();
QTest::mouseRelease(grip, Qt::LeftButton);
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(view.width(), oldWidth + 65);
}
@@ -801,7 +776,7 @@ void tst_QColumnView::setPreviewWidget()
void tst_QColumnView::sizes()
{
QColumnView view;
- QCOMPARE(view.columnWidths().count(), 0);
+ QCOMPARE(view.columnWidths().size(), 0);
const QList<int> newSizes{ 10, 4, 50, 6 };
@@ -812,16 +787,16 @@ void tst_QColumnView::sizes()
view.setModel(&m_fakeDirModel);
view.setCurrentIndex(m_fakeDirHomeIndex);
- QList<int> postSizes = view.columnWidths().mid(0, newSizes.count());
- QCOMPARE(postSizes, newSizes.mid(0, postSizes.count()));
+ QList<int> postSizes = view.columnWidths().mid(0, newSizes.size());
+ QCOMPARE(postSizes, newSizes.mid(0, postSizes.size()));
- QVERIFY(view.columnWidths().count() > 1);
+ QVERIFY(view.columnWidths().size() > 1);
QList<int> smallerSizes{ 6 };
view.setColumnWidths(smallerSizes);
QList<int> expectedSizes = newSizes;
expectedSizes[0] = 6;
- postSizes = view.columnWidths().mid(0, newSizes.count());
- QCOMPARE(postSizes, expectedSizes.mid(0, postSizes.count()));
+ postSizes = view.columnWidths().mid(0, newSizes.size());
+ QCOMPARE(postSizes, expectedSizes.mid(0, postSizes.size()));
}
void tst_QColumnView::rowDelegate()
@@ -831,7 +806,7 @@ void tst_QColumnView::rowDelegate()
view.setItemDelegateForRow(3, d);
view.setModel(&m_fakeDirModel);
- for (int i = 0; i < view.createdColumns.count(); ++i) {
+ for (int i = 0; i < view.createdColumns.size(); ++i) {
QAbstractItemView *column = view.createdColumns.at(i);
QCOMPARE(column->itemDelegateForRow(3), d);
}
@@ -981,7 +956,7 @@ void tst_QColumnView::dynamicModelChanges()
model.appendRow(item);
QVERIFY(QTest::qWaitForWindowExposed(&view)); //let the time for painting to occur
- QTRY_COMPARE(delegate.paintedIndexes.count(), 1);
+ QTRY_COMPARE(delegate.paintedIndexes.size(), 1);
QCOMPARE(*delegate.paintedIndexes.begin(), model.index(0,0));
}
diff --git a/tests/auto/widgets/itemviews/qdatawidgetmapper/CMakeLists.txt b/tests/auto/widgets/itemviews/qdatawidgetmapper/CMakeLists.txt
index 325e8af9b0..e4b2c52fb2 100644
--- a/tests/auto/widgets/itemviews/qdatawidgetmapper/CMakeLists.txt
+++ b/tests/auto/widgets/itemviews/qdatawidgetmapper/CMakeLists.txt
@@ -1,13 +1,21 @@
-# Generated from qdatawidgetmapper.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qdatawidgetmapper Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qdatawidgetmapper LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qdatawidgetmapper
SOURCES
tst_qdatawidgetmapper.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
+ Qt::WidgetsPrivate
)
diff --git a/tests/auto/widgets/itemviews/qdatawidgetmapper/tst_qdatawidgetmapper.cpp b/tests/auto/widgets/itemviews/qdatawidgetmapper/tst_qdatawidgetmapper.cpp
index 856672b957..c3527e4215 100644
--- a/tests/auto/widgets/itemviews/qdatawidgetmapper/tst_qdatawidgetmapper.cpp
+++ b/tests/auto/widgets/itemviews/qdatawidgetmapper/tst_qdatawidgetmapper.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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QComboBox>
#include <QDataWidgetMapper>
@@ -36,6 +11,8 @@
#include <QTextEdit>
#include <QVBoxLayout>
+#include <QtWidgets/private/qapplication_p.h>
+
class tst_QDataWidgetMapper: public QObject
{
Q_OBJECT
@@ -277,22 +254,22 @@ void tst_QDataWidgetMapper::currentIndexChanged()
QSignalSpy spy(&mapper, &QDataWidgetMapper::currentIndexChanged);
mapper.toFirst();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().at(0).toInt(), 0);
mapper.toNext();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().at(0).toInt(), 1);
mapper.setCurrentIndex(7);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().at(0).toInt(), 7);
mapper.setCurrentIndex(-1);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
mapper.setCurrentIndex(42);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
}
void tst_QDataWidgetMapper::changingValues()
@@ -443,27 +420,26 @@ void tst_QDataWidgetMapper::textEditDoesntChangeFocusOnTab_qtbug3305()
container.show();
- QApplication::setActiveWindow(&container);
QVERIFY(QTest::qWaitForWindowActive(&container));
int closeEditorSpyCount = 0;
const QString textEditContents = textEdit->toPlainText();
- QCOMPARE(closeEditorSpy.count(), closeEditorSpyCount);
+ QCOMPARE(closeEditorSpy.size(), closeEditorSpyCount);
QVERIFY(lineEdit->hasFocus());
QVERIFY(!textEdit->hasFocus());
// this will generate a closeEditor for the tab key, and another for the focus out
QTest::keyClick(QApplication::focusWidget(), Qt::Key_Tab);
closeEditorSpyCount += 2;
- QTRY_COMPARE(closeEditorSpy.count(), closeEditorSpyCount);
+ QTRY_COMPARE(closeEditorSpy.size(), closeEditorSpyCount);
QTRY_VERIFY(textEdit->hasFocus());
QVERIFY(!lineEdit->hasFocus());
// now that the text edit is focused, a tab keypress will insert a tab, not change focus
QTest::keyClick(QApplication::focusWidget(), Qt::Key_Tab);
- QTRY_COMPARE(closeEditorSpy.count(), closeEditorSpyCount);
+ QTRY_COMPARE(closeEditorSpy.size(), closeEditorSpyCount);
QVERIFY(!lineEdit->hasFocus());
QVERIFY(textEdit->hasFocus());
@@ -474,7 +450,7 @@ void tst_QDataWidgetMapper::textEditDoesntChangeFocusOnTab_qtbug3305()
QTRY_VERIFY(lineEdit->hasFocus());
QVERIFY(!textEdit->hasFocus());
++closeEditorSpyCount;
- QCOMPARE(closeEditorSpy.count(), closeEditorSpyCount);
+ QCOMPARE(closeEditorSpy.size(), closeEditorSpyCount);
}
QTEST_MAIN(tst_QDataWidgetMapper)
diff --git a/tests/auto/widgets/itemviews/qfileiconprovider/CMakeLists.txt b/tests/auto/widgets/itemviews/qfileiconprovider/CMakeLists.txt
index 4f626e3b8c..88ded71aac 100644
--- a/tests/auto/widgets/itemviews/qfileiconprovider/CMakeLists.txt
+++ b/tests/auto/widgets/itemviews/qfileiconprovider/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qfileiconprovider.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qfileiconprovider Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qfileiconprovider LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qfileiconprovider
SOURCES
tst_qfileiconprovider.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp b/tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp
index 39f6946b1d..3cba6dbf8b 100644
--- a/tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp
+++ b/tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QFileIconProvider>
@@ -73,6 +48,7 @@ void tst_QFileIconProvider::iconType_data()
// public QIcon icon(QFileIconProvider::IconType const& type) const
void tst_QFileIconProvider::iconType()
{
+ QGuiApplication::setDesktopSettingsAware(false);
QFETCH(QFileIconProvider::IconType, type);
QFileIconProvider provider;
QVERIFY(!provider.icon(type).isNull());
diff --git a/tests/auto/widgets/itemviews/qheaderview/BLACKLIST b/tests/auto/widgets/itemviews/qheaderview/BLACKLIST
index b8a4435fe1..7c9152a16c 100644
--- a/tests/auto/widgets/itemviews/qheaderview/BLACKLIST
+++ b/tests/auto/widgets/itemviews/qheaderview/BLACKLIST
@@ -1,5 +1,3 @@
-[stretchAndRestoreLastSection]
-opensuse-leap
# QTBUG-87406
[stretchAndRestoreLastSection]
android
diff --git a/tests/auto/widgets/itemviews/qheaderview/CMakeLists.txt b/tests/auto/widgets/itemviews/qheaderview/CMakeLists.txt
index de83539f56..a13454085c 100644
--- a/tests/auto/widgets/itemviews/qheaderview/CMakeLists.txt
+++ b/tests/auto/widgets/itemviews/qheaderview/CMakeLists.txt
@@ -1,15 +1,20 @@
-# Generated from qheaderview.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qheaderview Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qheaderview LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qheaderview
SOURCES
tst_qheaderview.cpp
- DEFINES
- QT_DISABLE_DEPRECATED_BEFORE=0
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
index 8856a8ef6a..57efa3e349 100644
--- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
@@ -1,31 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
-** 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) 2016 The Qt Company Ltd.
+// Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QHeaderView>
#include <QProxyStyle>
@@ -37,6 +12,7 @@
#include <QTest>
#include <QTreeWidget>
#include <QtWidgets/private/qheaderview_p.h>
+#include <QtWidgets/private/qapplication_p.h>
using BoolList = QList<bool>;
using IntList = QList<int>;
@@ -171,7 +147,7 @@ private slots:
void moveSectionAndReset();
void moveSectionAndRemove();
void saveRestore();
- void restoreQt4State();
+ void QTBUG99487_saveRestoreQt5Compat();
void restoreToMoreColumns();
void restoreToMoreColumnsNoMovedColumns();
void restoreBeforeSetModel();
@@ -250,6 +226,8 @@ private slots:
void testResetCachedSizeHint();
void statusTips();
void testRemovingColumnsViaLayoutChanged();
+ void testModelMovingColumns();
+ void testModelMovingRows();
protected:
void setupTestData(bool use_reset_model = false);
@@ -330,6 +308,12 @@ public:
endRemoveRows();
}
+ void moveRow(int from, int to)
+ {
+ beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
+ endMoveRows();
+ }
+
void removeOneColumn(int col)
{
beginRemoveColumns(QModelIndex(), col, col);
@@ -351,6 +335,12 @@ public:
endRemoveColumns();
}
+ void moveColumn(int from, int to)
+ {
+ beginMoveColumns(QModelIndex(), from, from, QModelIndex(), to);
+ endMoveColumns();
+ }
+
void cleanup()
{
emit layoutAboutToBeChanged();
@@ -492,7 +482,7 @@ void tst_QHeaderView::init()
QSignalSpy spy(view, &QHeaderView::sectionCountChanged);
view->setModel(model);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
view->resize(200,200);
}
@@ -813,10 +803,10 @@ void tst_QHeaderView::visualIndexAt()
for (int i : hidden)
view->setSectionHidden(i, true);
- for (int j = 0; j < from.count(); ++j)
+ for (int j = 0; j < from.size(); ++j)
view->moveSection(from.at(j), to.at(j));
- for (int k = 0; k < coordinate.count(); ++k)
+ for (int k = 0; k < coordinate.size(); ++k)
QTRY_COMPARE(view->visualIndexAt(coordinate.at(k)), visual.at(k));
}
@@ -928,14 +918,14 @@ void tst_QHeaderView::swapSections()
QCOMPARE(view->sectionsMoved(), true);
for (int i = 0; i < view->count(); ++i)
QCOMPARE(view->logicalIndex(i), logical.at(i));
- QCOMPARE(spy1.count(), 4);
+ QCOMPARE(spy1.size(), 4);
logical = { 3, 1, 2, 0 };
view->swapSections(3, 0);
QCOMPARE(view->sectionsMoved(), true);
for (int j = 0; j < view->count(); ++j)
QCOMPARE(view->logicalIndex(j), logical.at(j));
- QCOMPARE(spy1.count(), 6);
+ QCOMPARE(spy1.size(), 6);
}
void tst_QHeaderView::moveSection_data()
@@ -981,9 +971,9 @@ void tst_QHeaderView::moveSection()
QFETCH(const IntList, logical);
QFETCH(int, count);
- QCOMPARE(from.count(), to.count());
- QCOMPARE(from.count(), moved.count());
- QCOMPARE(view->count(), logical.count());
+ QCOMPARE(from.size(), to.size());
+ QCOMPARE(from.size(), moved.size());
+ QCOMPARE(view->count(), logical.size());
QSignalSpy spy1(view, &QHeaderView::sectionMoved);
QCOMPARE(view->sectionsMoved(), false);
@@ -991,7 +981,7 @@ void tst_QHeaderView::moveSection()
for (int h : hidden)
view->setSectionHidden(h, true);
- for (int i = 0; i < from.count(); ++i) {
+ for (int i = 0; i < from.size(); ++i) {
view->moveSection(from.at(i), to.at(i));
QCOMPARE(view->sectionsMoved(), moved.at(i));
}
@@ -999,7 +989,7 @@ void tst_QHeaderView::moveSection()
for (int j = 0; j < view->count(); ++j)
QCOMPARE(view->logicalIndex(j), logical.at(j));
- QCOMPARE(spy1.count(), count);
+ QCOMPARE(spy1.size(), count);
}
void tst_QHeaderView::resizeAndMoveSection_data()
@@ -1184,14 +1174,14 @@ void tst_QHeaderView::resizeWithResizeModes()
QFETCH(const IntList, expected);
view->setStretchLastSection(false);
- for (int i = 0; i < sections.count(); ++i) {
+ for (int i = 0; i < sections.size(); ++i) {
view->resizeSection(i, sections.at(i));
view->setSectionResizeMode(i, modes.at(i));
}
topLevel->show();
QVERIFY(QTest::qWaitForWindowExposed(topLevel));
view->resize(size, size);
- for (int j = 0; j < expected.count(); ++j)
+ for (int j = 0; j < expected.size(); ++j)
QCOMPARE(view->sectionSize(j), expected.at(j));
}
@@ -1218,7 +1208,7 @@ void tst_QHeaderView::moveAndInsertSection()
view->moveSection(from, to);
model->insertRow(insert);
- for (int i = 0; i < mapping.count(); ++i)
+ for (int i = 0; i < mapping.size(); ++i)
QCOMPARE(view->logicalIndex(i), mapping.at(i));
}
@@ -1289,21 +1279,21 @@ void tst_QHeaderView::resizeSection()
view->setSectionsMovable(true);
view->setStretchLastSection(false);
- for (int i = 0; i < logical.count(); ++i)
+ for (int i = 0; i < logical.size(); ++i)
if (logical.at(i) > -1 && logical.at(i) < view->count()) // for now
view->setSectionResizeMode(logical.at(i), mode.at(i));
- for (int j = 0; j < logical.count(); ++j)
+ for (int j = 0; j < logical.size(); ++j)
view->resizeSection(logical.at(j), initial);
QSignalSpy spy(view, &QHeaderView::sectionResized);
- for (int k = 0; k < logical.count(); ++k)
+ for (int k = 0; k < logical.size(); ++k)
view->resizeSection(logical.at(k), size.at(k));
- QCOMPARE(spy.count(), resized);
+ QCOMPARE(spy.size(), resized);
- for (int l = 0; l < logical.count(); ++l)
+ for (int l = 0; l < logical.size(); ++l)
QCOMPARE(view->sectionSize(logical.at(l)), expected.at(l));
}
@@ -1356,19 +1346,19 @@ void tst_QHeaderView::clearSectionSorting()
QSignalSpy sectionClickedSpy(&h, &QHeaderView::sectionClicked);
QVERIFY(sectionClickedSpy.isValid());
- QCOMPARE(sectionClickedSpy.count(), 0);
+ QCOMPARE(sectionClickedSpy.size(), 0);
QSignalSpy sortIndicatorChangedSpy(&h, &QHeaderView::sortIndicatorChanged);
QVERIFY(sortIndicatorChangedSpy.isValid());
- QCOMPARE(sortIndicatorChangedSpy.count(), 0);
+ QCOMPARE(sortIndicatorChangedSpy.size(), 0);
enum { Count = 30 };
// normal behavior: clicking multiple times will just toggle the sort indicator
for (int i = 0; i < Count; ++i) {
QTest::mouseClick(h.viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
- QCOMPARE(sectionClickedSpy.count(), i + 1);
- QCOMPARE(sortIndicatorChangedSpy.count(), i + 1);
+ QCOMPARE(sectionClickedSpy.size(), i + 1);
+ QCOMPARE(sortIndicatorChangedSpy.size(), i + 1);
QCOMPARE(h.sortIndicatorSection(), 0);
const auto expectedOrder = (i % 2) == 0 ? Qt::AscendingOrder : Qt::DescendingOrder;
QCOMPARE(h.sortIndicatorOrder(), expectedOrder);
@@ -1385,8 +1375,8 @@ void tst_QHeaderView::clearSectionSorting()
// clearing behavior: clicking multiple times will be tristate (asc, desc, nothing)
for (int i = 0; i < Count; ++i) {
QTest::mouseClick(h.viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
- QCOMPARE(sectionClickedSpy.count(), i + 1);
- QCOMPARE(sortIndicatorChangedSpy.count(), i + 1);
+ QCOMPARE(sectionClickedSpy.size(), i + 1);
+ QCOMPARE(sortIndicatorChangedSpy.size(), i + 1);
switch (i % 3) {
case 0:
QCOMPARE(h.sortIndicatorSection(), 0);
@@ -1511,11 +1501,11 @@ void tst_QHeaderView::testEvent()
void protected_QHeaderView::testEvent()
{
// No crashy please
- QHoverEvent enterEvent(QEvent::HoverEnter, QPoint(), QPoint());
+ QHoverEvent enterEvent(QEvent::HoverEnter, QPoint(), QPoint(), QPoint());
event(&enterEvent);
- QHoverEvent eventLeave(QEvent::HoverLeave, QPoint(), QPoint());
+ QHoverEvent eventLeave(QEvent::HoverLeave, QPoint(), QPoint(), QPoint());
event(&eventLeave);
- QHoverEvent eventMove(QEvent::HoverMove, QPoint(), QPoint());
+ QHoverEvent eventMove(QEvent::HoverMove, QPoint(), QPoint(), QPoint());
event(&eventMove);
}
@@ -1630,7 +1620,6 @@ void tst_QHeaderView::focusPolicy()
widget.show();
widget.setFocus(Qt::OtherFocusReason);
- QApplication::setActiveWindow(&widget);
widget.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&widget));
QVERIFY(widget.hasFocus());
@@ -1735,18 +1724,26 @@ static QByteArray savedState()
return h1.saveState();
}
-void tst_QHeaderView::saveRestore()
+// As generated by savedState()
+static const QByteArray qt5SavedSate = QByteArrayLiteral("\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x02\x01\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\b\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00""d\x00\x00\x00\xD2\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00""d\x00\x00\x00\x00\x00\x00\x00\x84\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00""d\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00""d\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\xE8\x00\x00\x00\x00\x00\x00\x00\x00\x00");
+
+enum class SaveRestoreOption
+{
+ CheckGeneratedState,
+ DoNotCheckGeneratedState,
+};
+
+static void saveRestoreImpl(const QByteArray &state, SaveRestoreOption option)
{
QStandardItemModel m(4, 4);
- const QByteArray s1 = savedState();
QHeaderView h2(Qt::Vertical);
QSignalSpy spy(&h2, &QHeaderView::sortIndicatorChanged);
h2.setModel(&m);
- QVERIFY(h2.restoreState(s1));
+ QVERIFY(h2.restoreState(state));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy.at(0).at(0).toInt(), 2);
QCOMPARE(h2.logicalIndex(0), 2);
@@ -1759,50 +1756,28 @@ void tst_QHeaderView::saveRestore()
QVERIFY(h2.isSectionHidden(3));
QCOMPARE(h2.hiddenSectionCount(), 1);
- QByteArray s2 = h2.saveState();
- QCOMPARE(s1, s2);
+ switch (option) {
+ case SaveRestoreOption::CheckGeneratedState:
+ {
+ QByteArray s2 = h2.saveState();
+ QCOMPARE(state, s2);
+ break;
+ }
+ case SaveRestoreOption::DoNotCheckGeneratedState:
+ break;
+ };
QVERIFY(!h2.restoreState(QByteArrayLiteral("Garbage")));
}
-void tst_QHeaderView::restoreQt4State()
+void tst_QHeaderView::saveRestore()
{
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- // QTBUG-40462
- // Setting from Qt4, where information about multiple sections were grouped together in one
- // sectionItem object
- QStandardItemModel m(4, 10);
- QHeaderView h2(Qt::Vertical);
- QByteArray settings_qt4 =
- QByteArray::fromHex("000000ff00000000000000010000000100000000010000000000000000000000000000"
- "0000000003e80000000a0101000100000000000000000000000064ffffffff00000081"
- "0000000000000001000003e80000000a00000000");
- QVERIFY(h2.restoreState(settings_qt4));
- int sectionItemsLengthTotal = 0;
- for (int i = 0; i < h2.count(); ++i)
- sectionItemsLengthTotal += h2.sectionSize(i);
- QCOMPARE(sectionItemsLengthTotal, h2.length());
-
- // Buggy setting where sum(sectionItems) != length. Check false is returned and this corrupted
- // state isn't restored
- QByteArray settings_buggy_length =
- QByteArray::fromHex("000000ff000000000000000100000000000000050100000000000000000000000a4000"
- "000000010000000600000258000000fb0000000a010100010000000000000000000000"
- "0064ffffffff00000081000000000000000a000000d30000000100000000000000c800"
- "000001000000000000008000000001000000000000005c00000001000000000000003c"
- "0000000100000000000002580000000100000000000000000000000100000000000002"
- "580000000100000000000002580000000100000000000003c000000001000000000000"
- "03e8");
- int old_length = h2.length();
- QByteArray old_state = h2.saveState();
- // Check setting is correctly recognized as corrupted
- QVERIFY(!h2.restoreState(settings_buggy_length));
- // Check nothing has been actually restored
- QCOMPARE(h2.length(), old_length);
- QCOMPARE(h2.saveState(), old_state);
-#else
- QSKIP("Qt4 compatibility no longer needed in Qt6");
-#endif
+ saveRestoreImpl(savedState(), SaveRestoreOption::CheckGeneratedState);
+}
+
+void tst_QHeaderView::QTBUG99487_saveRestoreQt5Compat()
+{
+ saveRestoreImpl(qt5SavedSate, SaveRestoreOption::DoNotCheckGeneratedState);
}
void tst_QHeaderView::restoreToMoreColumns()
@@ -2072,9 +2047,9 @@ void tst_QHeaderView::sectionPressedSignal()
QSignalSpy spy(&h, &QHeaderView::sectionPressed);
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QTest::mousePress(h.viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
- QCOMPARE(spy.count(), count);
+ QCOMPARE(spy.size(), count);
}
void tst_QHeaderView::sectionClickedSignal()
@@ -2094,19 +2069,19 @@ void tst_QHeaderView::sectionClickedSignal()
QSignalSpy spy(&h, &QHeaderView::sectionClicked);
QSignalSpy spy2(&h, &QHeaderView::sortIndicatorChanged);
- QCOMPARE(spy.count(), 0);
- QCOMPARE(spy2.count(), 0);
+ QCOMPARE(spy.size(), 0);
+ QCOMPARE(spy2.size(), 0);
QTest::mouseClick(h.viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
- QCOMPARE(spy.count(), count);
- QCOMPARE(spy2.count(), count);
+ QCOMPARE(spy.size(), count);
+ QCOMPARE(spy2.size(), count);
//now let's try with the sort indicator hidden (the result should be the same
spy.clear();
spy2.clear();
h.setSortIndicatorShown(false);
QTest::mouseClick(h.viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(5, 5));
- QCOMPARE(spy.count(), count);
- QCOMPARE(spy2.count(), count);
+ QCOMPARE(spy.size(), count);
+ QCOMPARE(spy2.size(), count);
}
void tst_QHeaderView::defaultSectionSize_data()
@@ -2222,6 +2197,9 @@ void tst_QHeaderView::preserveHiddenSectionWidth()
void tst_QHeaderView::invisibleStretchLastSection()
{
+ if (QGuiApplication::platformName().startsWith(QLatin1String("eglfs"), Qt::CaseInsensitive))
+ QSKIP("EGLFS does not allow resizing on top window");
+
int count = 6;
QStandardItemModel model(1, count);
QHeaderView view(Qt::Horizontal);
@@ -2287,7 +2265,7 @@ void tst_QHeaderView::task236450_hidden()
for (int i : hide1)
view.hideSection(i);
- QCOMPARE(view.hiddenSectionCount(), hide1.count());
+ QCOMPARE(view.hiddenSectionCount(), hide1.size());
for (int i = 0; i < 6; i++)
QCOMPARE(!view.isSectionHidden(i), !hide1.contains(i));
@@ -2295,13 +2273,13 @@ void tst_QHeaderView::task236450_hidden()
view.scheduleDelayedItemsLayout();
view.executeDelayedItemsLayout(); //force to do a relayout
- QCOMPARE(view.hiddenSectionCount(), hide1.count());
+ QCOMPARE(view.hiddenSectionCount(), hide1.size());
for (int i = 0; i < 6; i++) {
QCOMPARE(!view.isSectionHidden(i), !hide1.contains(i));
view.setSectionHidden(i, hide2.contains(i));
}
- QCOMPARE(view.hiddenSectionCount(), hide2.count());
+ QCOMPARE(view.hiddenSectionCount(), hide2.size());
for (int i = 0; i < 6; i++)
QCOMPARE(!view.isSectionHidden(i), !hide2.contains(i));
}
@@ -2333,10 +2311,10 @@ void tst_QHeaderView::task248050_hideRow()
//returns 0 if everything is fine.
static int checkHeaderViewOrder(const QHeaderView *view, const IntList &expected)
{
- if (view->count() != expected.count())
+ if (view->count() != expected.size())
return 1;
- for (int i = 0; i < expected.count(); i++) {
+ for (int i = 0; i < expected.size(); i++) {
if (view->logicalIndex(i) != expected.at(i))
return i + 10;
if (view->visualIndex(expected.at(i)) != i)
@@ -2427,8 +2405,8 @@ void tst_QHeaderView::QTBUG7833_sectionClicked()
QTest::mouseClick(tv.horizontalHeader()->viewport(), Qt::LeftButton, Qt::NoModifier,
QPoint(tv.horizontalHeader()->sectionViewportPosition(11) +
tv.horizontalHeader()->sectionSize(11) / 2, 5));
- QCOMPARE(clickedSpy.count(), 1);
- QCOMPARE(pressedSpy.count(), 1);
+ QCOMPARE(clickedSpy.size(), 1);
+ QCOMPARE(pressedSpy.size(), 1);
QCOMPARE(clickedSpy.at(0).at(0).toInt(), 11);
QCOMPARE(pressedSpy.at(0).at(0).toInt(), 11);
@@ -2436,8 +2414,8 @@ void tst_QHeaderView::QTBUG7833_sectionClicked()
QPoint(tv.horizontalHeader()->sectionViewportPosition(8) +
tv.horizontalHeader()->sectionSize(0) / 2, 5));
- QCOMPARE(clickedSpy.count(), 2);
- QCOMPARE(pressedSpy.count(), 2);
+ QCOMPARE(clickedSpy.size(), 2);
+ QCOMPARE(pressedSpy.size(), 2);
QCOMPARE(clickedSpy.at(1).at(0).toInt(), 8);
QCOMPARE(pressedSpy.at(1).at(0).toInt(), 8);
@@ -2445,8 +2423,8 @@ void tst_QHeaderView::QTBUG7833_sectionClicked()
QPoint(tv.horizontalHeader()->sectionViewportPosition(0) +
tv.horizontalHeader()->sectionSize(0) / 2, 5));
- QCOMPARE(clickedSpy.count(), 3);
- QCOMPARE(pressedSpy.count(), 3);
+ QCOMPARE(clickedSpy.size(), 3);
+ QCOMPARE(pressedSpy.size(), 3);
QCOMPARE(clickedSpy.at(2).at(0).toInt(), 0);
QCOMPARE(pressedSpy.at(2).at(0).toInt(), 0);
}
@@ -2573,7 +2551,7 @@ public:
void insertRowAtBeginning()
{
Q_EMIT layoutAboutToBeChanged();
- m_displayNames.insert(0, QStringLiteral("Item %1").arg(m_displayNames.count()));
+ m_displayNames.insert(0, QStringLiteral("Item %1").arg(m_displayNames.size()));
// Rows are always inserted at the beginning, so move all others.
const auto pl = persistentIndexList();
// The vertical header view will have a persistent index stored here on the second call to insertRowAtBeginning.
@@ -2589,7 +2567,7 @@ public:
QModelIndex index(int row, int column, const QModelIndex &) const override { return createIndex(row, column); }
QModelIndex parent(const QModelIndex &) const override { return QModelIndex(); }
- int rowCount(const QModelIndex &) const override { return m_displayNames.count(); }
+ int rowCount(const QModelIndex &) const override { return m_displayNames.size(); }
int columnCount(const QModelIndex &) const override { return 1; }
private:
@@ -2873,10 +2851,6 @@ void tst_QHeaderView::calculateAndCheck(int cppline, const int precalced_compare
int sum_visual = 0;
int sum_logical = 0;
- int sum_size = 0;
- int sum_hidden_size = 0;
- int sum_lookup_visual = 0;
- int sum_lookup_logical = 0;
int chk_visual = 1;
int chk_logical = 1;
@@ -2896,7 +2870,6 @@ void tst_QHeaderView::calculateAndCheck(int cppline, const int precalced_compare
sum_visual += visual;
sum_logical += logical;
- sum_size += ssize;
if (visual >= 0) {
chk_visual %= p2;
@@ -2916,7 +2889,6 @@ void tst_QHeaderView::calculateAndCheck(int cppline, const int precalced_compare
if (view->isSectionHidden(i)) {
view->showSection(i);
int hiddensize = view->sectionSize(i);
- sum_hidden_size += hiddensize;
chk_hidden_size %= p2;
chk_hidden_size += ( (hiddensize + 1) * (i + 1) * p1);
// (hiddensize + 1) in the above to differ between hidden and size 0
@@ -2935,8 +2907,6 @@ void tst_QHeaderView::calculateAndCheck(int cppline, const int precalced_compare
for (int u = 0; u < max_lookup_count; ++u) {
int visu = view->visualIndexAt(u);
int logi = view->logicalIndexAt(u);
- sum_lookup_visual += logi;
- sum_lookup_logical += visu;
chk_lookup_visual %= p2;
chk_lookup_visual *= ( (u + 1) * p1 * (visu + 2));
chk_lookup_logical %= p2;
@@ -3412,7 +3382,7 @@ void tst_QHeaderView::stretchAndRestoreLastSection()
const int someOtherSectionSize = 40;
const int biggerSizeThanAnySection = 50;
- QVERIFY(QTest::qWaitForWindowExposed(&tv));
+ QVERIFY(QTest::qWaitForWindowActive(&tv));
QHeaderView &header = *tv.horizontalHeader();
// set minimum size before resizeSections() is called
@@ -3641,7 +3611,6 @@ void tst_QHeaderView::statusTips()
headerView.setGeometry(QRect(QPoint(QGuiApplication::primaryScreen()->geometry().center() - QPoint(250, 250)),
QSize(500, 500)));
headerView.show();
- QApplication::setActiveWindow(&headerView);
QVERIFY(QTest::qWaitForWindowActive(&headerView));
// Ensure it is moved away first and then moved to the relevant section
@@ -3676,5 +3645,41 @@ void tst_QHeaderView::testRemovingColumnsViaLayoutChanged()
// The main point of this test is that the section-size restoring code didn't go out of bounds.
}
+void tst_QHeaderView::testModelMovingColumns()
+{
+ QtTestModel model(10, 10);
+ QHeaderView hv(Qt::Horizontal);
+ hv.setModel(&model);
+ hv.resizeSections(QHeaderView::ResizeToContents);
+ hv.show();
+ hv.hideSection(3);
+ QVERIFY(!hv.isSectionHidden(1));
+ QVERIFY(hv.isSectionHidden(3));
+
+ QPersistentModelIndex index3 = model.index(0, 3);
+ model.moveColumn(3, 1);
+ QCOMPARE(index3.column(), 1);
+ QVERIFY(hv.isSectionHidden(1));
+ QVERIFY(!hv.isSectionHidden(3));
+}
+
+void tst_QHeaderView::testModelMovingRows()
+{
+ QtTestModel model(10, 10);
+ QHeaderView hv(Qt::Vertical);
+ hv.setModel(&model);
+ hv.resizeSections(QHeaderView::ResizeToContents);
+ hv.show();
+ hv.hideSection(3);
+ QVERIFY(!hv.isSectionHidden(1));
+ QVERIFY(hv.isSectionHidden(3));
+
+ QPersistentModelIndex index3 = model.index(3, 0);
+ model.moveRow(3, 1);
+ QCOMPARE(index3.row(), 1);
+ QVERIFY(hv.isSectionHidden(1));
+ QVERIFY(!hv.isSectionHidden(3));
+}
+
QTEST_MAIN(tst_QHeaderView)
#include "tst_qheaderview.moc"
diff --git a/tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST b/tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST
deleted file mode 100644
index 5eda888af6..0000000000
--- a/tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST
+++ /dev/null
@@ -1,6 +0,0 @@
-[enterKey]
-opensuse-42.3 ci
-[testLineEditValidation]
-opensuse-42.3 ci
-[editorKeyPress]
-ubuntu-20.04
diff --git a/tests/auto/widgets/itemviews/qitemdelegate/CMakeLists.txt b/tests/auto/widgets/itemviews/qitemdelegate/CMakeLists.txt
index 50057bbd7c..58a00fdc9d 100644
--- a/tests/auto/widgets/itemviews/qitemdelegate/CMakeLists.txt
+++ b/tests/auto/widgets/itemviews/qitemdelegate/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qitemdelegate.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qitemdelegate Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qitemdelegate LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qitemdelegate
SOURCES
tst_qitemdelegate.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
Qt::WidgetsPrivate
@@ -17,6 +24,6 @@ qt_internal_add_test(tst_qitemdelegate
#####################################################################
qt_internal_extend_target(tst_qitemdelegate CONDITION WIN32
- PUBLIC_LIBRARIES
+ LIBRARIES
user32
)
diff --git a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
index 25212373a4..769456951f 100644
--- a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
+++ b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
@@ -1,35 +1,11 @@
-/****************************************************************************
-**
-** 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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "../../../shared/highdpi.h"
#include <QTest>
#include <QTimeZone>
+#include <QDateTime>
#include <QTimer>
#include <QTestEventLoop>
#include <QSignalSpy>
@@ -59,11 +35,12 @@
#include <qscreen.h>
#include <QtWidgets/private/qabstractitemdelegate_p.h>
+#include <QtWidgets/private/qapplication_p.h>
Q_DECLARE_METATYPE(QAbstractItemDelegate::EndEditHint)
#if defined (Q_OS_WIN)
-#include <windows.h>
+#include <qt_windows.h>
#define Q_CHECK_PAINTEVENTS \
if (::SwitchDesktop(::GetThreadDesktop(::GetCurrentThreadId())) == 0) \
QSKIP("The widgets don't get the paint events");
@@ -230,6 +207,8 @@ private slots:
void dateTextForRole_data();
void dateTextForRole();
+ void reuseEditor();
+
private:
#ifdef QT_BUILD_INTERNAL
struct RoleDelegate : public QItemDelegate
@@ -350,16 +329,15 @@ void tst_QItemDelegate::editorKeyPress()
view.edit(index);
QList<QLineEdit*> lineEditors = view.viewport()->findChildren<QLineEdit *>();
- QCOMPARE(lineEditors.count(), 1);
+ QCOMPARE(lineEditors.size(), 1);
QLineEdit *editor = lineEditors.at(0);
QCOMPARE(editor->selectedText(), initial);
QTest::keyClicks(editor, expected);
QTest::keyClick(editor, Qt::Key_Enter);
- QApplication::processEvents();
- QCOMPARE(index.data().toString(), expected);
+ QTRY_COMPARE(index.data().toString(), expected);
}
void tst_QItemDelegate::doubleEditorNegativeInput()
@@ -379,7 +357,7 @@ void tst_QItemDelegate::doubleEditorNegativeInput()
view.edit(index);
QList<QDoubleSpinBox*> editors = view.viewport()->findChildren<QDoubleSpinBox *>();
- QCOMPARE(editors.count(), 1);
+ QCOMPARE(editors.size(), 1);
QDoubleSpinBox *editor = editors.at(0);
QCOMPARE(editor->value(), double(10));
@@ -696,33 +674,33 @@ void tst_QItemDelegate::testEventFilter()
//For each test we send a key event and check if signals were emitted.
event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier);
QVERIFY(delegate.eventFilter(&widget, event));
- QCOMPARE(closeEditorSpy.count(), 1);
- QCOMPARE(commitDataSpy.count(), 1);
+ QCOMPARE(closeEditorSpy.size(), 1);
+ QCOMPARE(commitDataSpy.size(), 1);
delete event;
event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier);
QVERIFY(delegate.eventFilter(&widget, event));
- QCOMPARE(closeEditorSpy.count(), 2);
- QCOMPARE(commitDataSpy.count(), 2);
+ QCOMPARE(closeEditorSpy.size(), 2);
+ QCOMPARE(commitDataSpy.size(), 2);
delete event;
event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier);
QVERIFY(delegate.eventFilter(&widget, event));
- QCOMPARE(closeEditorSpy.count(), 3);
- QCOMPARE(commitDataSpy.count(), 2);
+ QCOMPARE(closeEditorSpy.size(), 3);
+ QCOMPARE(commitDataSpy.size(), 2);
delete event;
event = new QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier);
QVERIFY(!delegate.eventFilter(&widget, event));
- QCOMPARE(closeEditorSpy.count(), 3);
- QCOMPARE(commitDataSpy.count(), 2);
+ QCOMPARE(closeEditorSpy.size(), 3);
+ QCOMPARE(commitDataSpy.size(), 2);
delete event;
//Subtest focusEvent
event = new QFocusEvent(QEvent::FocusOut);
QVERIFY(!delegate.eventFilter(&widget, event));
- QCOMPARE(closeEditorSpy.count(), 4);
- QCOMPARE(commitDataSpy.count(), 3);
+ QCOMPARE(closeEditorSpy.size(), 4);
+ QCOMPARE(commitDataSpy.size(), 3);
delete event;
}
@@ -769,7 +747,6 @@ void tst_QItemDelegate::dateTimeEditor()
widget.setItem(0, 2, item3);
widget.show();
QVERIFY(QTest::qWaitForWindowExposed(&widget));
- QApplication::setActiveWindow(&widget);
widget.editItem(item1);
@@ -785,7 +762,6 @@ void tst_QItemDelegate::dateTimeEditor()
timeEditor->setTime(time.addSecs(60));
widget.clearFocus();
- qApp->setActiveWindow(&widget);
widget.setFocus();
widget.editItem(item2);
@@ -1049,7 +1025,6 @@ void tst_QItemDelegate::decoration()
TestItemDelegate delegate;
table.setItemDelegate(&delegate);
table.show();
- QApplication::setActiveWindow(&table);
QVERIFY(QTest::qWaitForWindowActive(&table));
QVariant value;
@@ -1245,7 +1220,7 @@ void tst_QItemDelegate::editorEvent()
QPoint pos = inCheck ? qApp->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &option, 0).center() + QPoint(checkMargin, 0) : QPoint(200,200);
QEvent *event = new QMouseEvent((QEvent::Type)type,
- pos,
+ pos, pos,
(Qt::MouseButton)button,
(Qt::MouseButton)button,
Qt::NoModifier);
@@ -1304,7 +1279,6 @@ void tst_QItemDelegate::enterKey()
QListView view;
view.setModel(&model);
view.show();
- QApplication::setActiveWindow(&view);
view.setFocus();
QVERIFY(QTest::qWaitForWindowActive(&view));
@@ -1338,7 +1312,7 @@ void tst_QItemDelegate::enterKey()
view.edit(index);
QList<QWidget*> lineEditors = view.viewport()->findChildren<QWidget *>(QString::fromLatin1("TheEditor"));
- QCOMPARE(lineEditors.count(), 1);
+ QCOMPARE(lineEditors.size(), 1);
QPointer<QWidget> editor = lineEditors.at(0);
QCOMPARE(editor->hasFocus(), true);
@@ -1364,7 +1338,6 @@ void tst_QItemDelegate::task257859_finalizeEdit()
QListView view;
view.setModel(&model);
view.show();
- QApplication::setActiveWindow(&view);
view.setFocus();
QVERIFY(QTest::qWaitForWindowActive(&view));
@@ -1372,7 +1345,7 @@ void tst_QItemDelegate::task257859_finalizeEdit()
view.edit(index);
QList<QLineEdit *> lineEditors = view.viewport()->findChildren<QLineEdit *>();
- QCOMPARE(lineEditors.count(), 1);
+ QCOMPARE(lineEditors.size(), 1);
QPointer<QWidget> editor = lineEditors.at(0);
QCOMPARE(editor->hasFocus(), true);
@@ -1394,6 +1367,7 @@ void tst_QItemDelegate::QTBUG4435_keepSelectionOnCheck()
}
QTableView view;
view.setModel(&model);
+ view.setSelectionMode(QAbstractItemView::MultiSelection);
view.setItemDelegate(new TestItemDelegate(&view));
view.show();
view.selectAll();
@@ -1404,11 +1378,16 @@ void tst_QItemDelegate::QTBUG4435_keepSelectionOnCheck()
option.features = QStyleOptionViewItem::HasDisplay | QStyleOptionViewItem::HasCheckIndicator;
option.checkState = Qt::CheckState(model.index(0, 0).data(Qt::CheckStateRole).toInt());
const int checkMargin = qApp->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, 0) + 1;
- QPoint pos = qApp->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &option, 0).center()
- + QPoint(checkMargin, 0);
- QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, pos);
- QTRY_VERIFY(view.selectionModel()->isColumnSelected(0, QModelIndex()));
+ QRect checkRect = qApp->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &option, 0);
+ checkRect.translate(checkMargin, 0);
+ // click into the check mark checks, but doesn't change selection
+ QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, checkRect.center());
QCOMPARE(model.item(0)->checkState(), Qt::Checked);
+ QTRY_VERIFY(view.selectionModel()->isColumnSelected(0, QModelIndex()));
+ // click outside the check mark doesn't check, and changes selection
+ QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier,
+ checkRect.center() + QPoint(checkRect.width(), 0));
+ QTRY_VERIFY(!view.selectionModel()->isColumnSelected(0, QModelIndex()));
}
void tst_QItemDelegate::comboBox()
@@ -1420,7 +1399,7 @@ void tst_QItemDelegate::comboBox()
widget.setItem(0, 0, item1);
widget.show();
QVERIFY(QTest::qWaitForWindowExposed(&widget));
- QApplication::setActiveWindow(&widget);
+ QApplicationPrivate::setActiveWindow(&widget);
widget.editItem(item1);
@@ -1485,7 +1464,6 @@ void tst_QItemDelegate::testLineEditValidation()
view.setItemDelegate(&delegate);
view.show();
view.setFocus();
- QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
QPointer<QLineEdit> editor;
@@ -1497,7 +1475,7 @@ void tst_QItemDelegate::testLineEditValidation()
const auto findEditors = [&]() {
return view.findChildren<QLineEdit *>(QStringLiteral("TheEditor"));
};
- QCOMPARE(findEditors().count(), 1);
+ QCOMPARE(findEditors().size(), 1);
editor = findEditors().at(0);
editor->clear();
@@ -1517,7 +1495,7 @@ void tst_QItemDelegate::testLineEditValidation()
view.setCurrentIndex(index);
view.edit(index);
- QTRY_COMPARE(findEditors().count(), 1);
+ QTRY_COMPARE(findEditors().size(), 1);
editor = findEditors().at(0);
editor->clear();
@@ -1539,13 +1517,13 @@ void tst_QItemDelegate::testLineEditValidation()
// reset the view to forcibly close the editor
view.reset();
- QTRY_COMPARE(findEditors().count(), 0);
+ QTRY_COMPARE(findEditors().size(), 0);
// set a valid text again
view.setCurrentIndex(index);
view.edit(index);
- QTRY_COMPARE(findEditors().count(), 1);
+ QTRY_COMPARE(findEditors().size(), 1);
editor = findEditors().at(0);
editor->clear();
@@ -1609,12 +1587,12 @@ void tst_QItemDelegate::dateTextForRole_data()
QDate date(2013, 12, 11);
QTime time(10, 9, 8, 765);
// Ensure we exercise every time-spec variant:
- QTest::newRow("local") << QDateTime(date, time, Qt::LocalTime);
- QTest::newRow("UTC") << QDateTime(date, time, Qt::UTC);
-#if QT_CONFIG(timezone)
+ QTest::newRow("local") << QDateTime(date, time);
+ QTest::newRow("UTC") << QDateTime(date, time, QTimeZone::UTC);
+# if QT_CONFIG(timezone)
QTest::newRow("zone") << QDateTime(date, time, QTimeZone("Europe/Dublin"));
-#endif
- QTest::newRow("offset") << QDateTime(date, time, Qt::OffsetFromUTC, 36000);
+# endif
+ QTest::newRow("offset") << QDateTime(date, time, QTimeZone::fromSecondsAheadOfUtc(36000));
#endif
}
@@ -1637,6 +1615,75 @@ void tst_QItemDelegate::dateTextForRole()
#endif
}
+void tst_QItemDelegate::reuseEditor()
+{
+ class ReusingDelegate: public QItemDelegate {
+ public:
+ using QItemDelegate::QItemDelegate;
+ ~ReusingDelegate()
+ {
+ if (cached)
+ cached->deleteLater();
+ }
+
+ QWidget* createEditor(QWidget* parent,
+ const QStyleOptionViewItem&,
+ const QModelIndex&) const override
+ {
+ auto *cb = new QComboBox(parent);
+ cb->addItem("One");
+ cb->addItem("Two");
+ cb->setEditable(true);
+ return cb;
+ }
+
+ void setEditorData(QWidget* editor, const QModelIndex& index)
+ const override
+ {
+ auto *cb = qobject_cast<QComboBox*>(editor);
+ cb->setCurrentText(index.data(Qt::DisplayRole).toString());
+ }
+
+ void setModelData(QWidget* editor,
+ QAbstractItemModel* model,
+ const QModelIndex& index) const override
+ {
+ auto *cb = qobject_cast<QComboBox*>(editor);
+ model->setData(index, cb->currentText(), Qt::DisplayRole);
+ }
+
+ void destroyEditor(QWidget* editor, const QModelIndex&) const override
+ {
+ auto *cb = qobject_cast<QComboBox*>(editor);
+ cb->setParent(nullptr); // How to completely detach the editor from treeview ?
+ cb->hide();
+ cb->setEnabled(false);
+ cached = cb;
+ }
+
+ private:
+ mutable QComboBox* cached = nullptr;
+ };
+
+ QStandardItemModel model;
+ model.appendRow(new QStandardItem("One"));
+ model.appendRow(new QStandardItem("Two"));
+
+ ReusingDelegate delegate;
+
+ QTreeView tree;
+ tree.setModel(&model);
+ tree.setItemDelegate(&delegate);
+
+ tree.show();
+ QVERIFY(QTest::qWaitForWindowActive(&tree));
+
+ tree.edit(model.index(0, 0));
+ QTRY_VERIFY(qobject_cast<QComboBox *>(tree.focusWidget()));
+
+ tree.close();
+}
+
// ### _not_ covered:
// editing with a custom editor factory
diff --git a/tests/auto/widgets/itemviews/qitemeditorfactory/CMakeLists.txt b/tests/auto/widgets/itemviews/qitemeditorfactory/CMakeLists.txt
index e57ee0d01c..608c323b44 100644
--- a/tests/auto/widgets/itemviews/qitemeditorfactory/CMakeLists.txt
+++ b/tests/auto/widgets/itemviews/qitemeditorfactory/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qitemeditorfactory.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qitemeditorfactory Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qitemeditorfactory LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qitemeditorfactory
SOURCES
tst_qitemeditorfactory.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/itemviews/qitemeditorfactory/tst_qitemeditorfactory.cpp b/tests/auto/widgets/itemviews/qitemeditorfactory/tst_qitemeditorfactory.cpp
index 6f176c4ba5..dcd751c696 100644
--- a/tests/auto/widgets/itemviews/qitemeditorfactory/tst_qitemeditorfactory.cpp
+++ b/tests/auto/widgets/itemviews/qitemeditorfactory/tst_qitemeditorfactory.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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QDoubleSpinBox>
diff --git a/tests/auto/widgets/itemviews/qitemview/CMakeLists.txt b/tests/auto/widgets/itemviews/qitemview/CMakeLists.txt
index 93f10f0fbf..8ff1fd67c9 100644
--- a/tests/auto/widgets/itemviews/qitemview/CMakeLists.txt
+++ b/tests/auto/widgets/itemviews/qitemview/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qitemview.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qitemview Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qitemview LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qitemview
SOURCES
tst_qitemview.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp b/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp
index 244998eb1c..d5a6ddea6e 100644
--- a/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp
+++ b/tests/auto/widgets/itemviews/qitemview/tst_qitemview.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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QRandomGenerator>
#include <QStack>
diff --git a/tests/auto/widgets/itemviews/qitemview/viewstotest.cpp b/tests/auto/widgets/itemviews/qitemview/viewstotest.cpp
index 19f0b80cc6..0c7c17503e 100644
--- a/tests/auto/widgets/itemviews/qitemview/viewstotest.cpp
+++ b/tests/auto/widgets/itemviews/qitemview/viewstotest.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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QHeaderView>
#include <QListView>
diff --git a/tests/auto/widgets/itemviews/qlistview/CMakeLists.txt b/tests/auto/widgets/itemviews/qlistview/CMakeLists.txt
index bd440ff203..f6c9f154de 100644
--- a/tests/auto/widgets/itemviews/qlistview/CMakeLists.txt
+++ b/tests/auto/widgets/itemviews/qlistview/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qlistview.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qlistview Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qlistview LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qlistview
SOURCES
tst_qlistview.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
@@ -20,6 +27,6 @@ qt_internal_add_test(tst_qlistview
#####################################################################
qt_internal_extend_target(tst_qlistview CONDITION WIN32
- PUBLIC_LIBRARIES
+ LIBRARIES
user32
)
diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
index 98dec7ded9..236cd6212f 100644
--- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
+++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.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 <QListWidget>
@@ -37,14 +12,18 @@
#include <QTest>
#include <QTimer>
#include <QtMath>
+#include <QProxyStyle>
+#include <QVBoxLayout>
+#include <QDialog>
#include <QtTest/private/qtesthelpers_p.h>
#include <QtWidgets/private/qlistview_p.h>
+#include <QtWidgets/private/qapplication_p.h>
using namespace QTestPrivate;
#if defined(Q_OS_WIN)
-# include <windows.h>
+# include <qt_windows.h>
# include <QDialog>
# include <QGuiApplication>
# include <QVBoxLayout>
@@ -89,8 +68,14 @@ public:
{
return QListView::visualRegionForSelection(selectionModel()->selection());
}
+ void moveEvent(QMoveEvent *e) override
+ {
+ QListView::moveEvent(e);
+ m_gotValidResizeEvent = !e->pos().isNull();
+ }
friend class tst_QListView;
+ bool m_gotValidResizeEvent = false;
};
class tst_QListView : public QObject
@@ -109,6 +94,8 @@ private slots:
void moveCursor();
void moveCursor2();
void moveCursor3();
+ void moveCursor4();
+ void moveCursor5();
void indexAt();
void clicked();
void singleSelectionRemoveRow();
@@ -164,11 +151,18 @@ private slots:
void taskQTBUG_39902_mutualScrollBars();
void horizontalScrollingByVerticalWheelEvents();
void taskQTBUG_7232_AllowUserToControlSingleStep();
+ void taskQTBUG_58749_adjustToContent();
void taskQTBUG_51086_skippingIndexesInSelectedIndexes();
void taskQTBUG_47694_indexOutOfBoundBatchLayout();
+ void moveLastRow();
void itemAlignment();
void internalDragDropMove_data();
void internalDragDropMove();
+ void spacingWithWordWrap_data();
+ void spacingWithWordWrap();
+ void scrollOnRemove_data();
+ void scrollOnRemove();
+ void wordWrapNullIcon();
};
// Testing get/set functions
@@ -434,7 +428,7 @@ void tst_QListView::cursorMove()
}
break;
default:
- QVERIFY(false);
+ QFAIL(qPrintable(QStringLiteral("Unexpected key: %1").arg(key)));
}
QCoreApplication::processEvents();
@@ -572,6 +566,76 @@ void tst_QListView::moveCursor3()
QCOMPARE(view.selectionModel()->currentIndex(), model.index(0, 0));
}
+void tst_QListView::moveCursor4()
+{
+ int indexCount = 100;
+ PublicListView listView;
+ QStandardItemModel model;
+ for (int i = 0; i < 100; i++)
+ {
+ QStandardItem* item = new QStandardItem(QString("item 0%0").arg(i));
+ QFont font = item->font();
+ font.setPixelSize(14);
+ item->setFont(font);
+ model.appendRow(item);
+ }
+ QFont font = model.item(0)->font();
+ font.setPixelSize(50);
+ font.setBold(true);
+ model.item(0)->setFont(font);
+ listView.setModel(&model);
+ listView.setFixedSize(200, 200);
+ listView.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ listView.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ listView.show();
+ listView.selectionModel()->setCurrentIndex(model.index(0, 0), QItemSelectionModel::SelectCurrent);
+
+ QModelIndex idx = listView.moveCursor(PublicListView::MovePageDown, Qt::NoModifier);
+
+ int actualIndex = 0;
+ int indexHeight = 0;
+ while (indexHeight <= listView.viewport()->height()) {
+ indexHeight += listView.visualRect(model.item(actualIndex)->index()).height();
+ actualIndex++;
+ }
+ QTRY_COMPARE(idx, model.index(actualIndex - 2, 0));
+ idx = listView.moveCursor(PublicListView::MoveUp, Qt::NoModifier);
+ QTRY_COMPARE(idx, model.index(0, 0));
+
+ listView.setCurrentIndex(model.index(indexCount - 2, 0));
+ idx = listView.moveCursor(PublicListView::MovePageDown, Qt::NoModifier);
+ QTRY_COMPARE(idx, model.index(99, 0));
+
+ listView.setCurrentIndex(model.index(3, 0));
+ actualIndex = 3;
+ indexHeight = 0;
+ while (indexHeight <= listView.viewport()->height()) {
+ indexHeight += listView.visualRect(model.item(actualIndex)->index()).height();
+ actualIndex++;
+ }
+ idx = listView.moveCursor(PublicListView::MovePageDown, Qt::NoModifier);
+ QTRY_COMPARE(idx, model.index(actualIndex - 2, 0));
+}
+
+void tst_QListView::moveCursor5()
+{
+ PublicListView listView;
+ QStandardItemModel model;
+ QIcon icon(QPixmap(300,300));
+ model.appendRow(new QStandardItem(icon,"11"));
+ model.appendRow(new QStandardItem(icon,"22"));
+ model.appendRow(new QStandardItem(icon,"33"));
+ listView.setModel(&model);
+ listView.setGeometry(10,10,200,200);
+ listView.setIconSize(QSize(300,300));
+ listView.setViewMode(QListView::IconMode);
+ listView.setCurrentIndex(model.index(0, 0));
+
+ QModelIndex idx = listView.moveCursor(PublicListView::MovePageDown, Qt::NoModifier);
+ QTRY_COMPARE(idx, model.index(1, 0));
+ idx = listView.moveCursor(PublicListView::MovePageUp, Qt::NoModifier);
+ QTRY_COMPARE(idx, model.index(0, 0));
+}
class QListViewShowEventListener : public QListView
{
@@ -662,7 +726,7 @@ void tst_QListView::clicked()
continue;
QSignalSpy spy(&view, &QListView::clicked);
QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
}
@@ -1091,7 +1155,7 @@ void tst_QListView::selection()
v.setSelection(selectionRect, QItemSelectionModel::ClearAndSelect);
const QModelIndexList selected = v.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), expectedItems.count());
+ QCOMPARE(selected.size(), expectedItems.size());
for (const auto &idx : selected)
QVERIFY(expectedItems.contains(idx.row()));
}
@@ -1501,7 +1565,7 @@ void tst_QListView::task203585_selectAll()
QVERIFY(view.selectionModel()->selectedIndexes().isEmpty());
view.setRowHidden(0, false);
view.selectAll();
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), 1);
}
void tst_QListView::task228566_infiniteRelayout()
@@ -1586,7 +1650,7 @@ void tst_QListView::task196118_visualRegionForSelection()
view.selectionModel()->select(top1.index(), QItemSelectionModel::Select);
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), 1);
QVERIFY(view.getVisualRegionForSelection().isEmpty());
}
@@ -1643,7 +1707,6 @@ void tst_QListView::keyboardSearch()
QListView view;
view.setModel(&model);
view.show();
- QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
QTest::keyClick(&view, Qt::Key_K);
@@ -1684,7 +1747,7 @@ void tst_QListView::shiftSelectionWithNonUniformItemSizes()
QTRY_COMPARE(view.currentIndex(), model.index(1, 0));
QModelIndexList selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 3);
+ QCOMPARE(selected.size(), 3);
QVERIFY(!selected.contains(model.index(0, 0)));
}
{ // Second test: QListView::TopToBottom flow
@@ -1711,7 +1774,7 @@ void tst_QListView::shiftSelectionWithNonUniformItemSizes()
QTRY_COMPARE(view.currentIndex(), model.index(1, 0));
QModelIndexList selected = view.selectionModel()->selectedIndexes();
- QCOMPARE(selected.count(), 3);
+ QCOMPARE(selected.size(), 3);
QVERIFY(!selected.contains(model.index(0, 0)));
}
}
@@ -1745,7 +1808,6 @@ void tst_QListView::shiftSelectionWithItemAlignment()
view.resize(300, view.sizeHintForRow(0) * items.size() / 2 + view.horizontalScrollBar()->height());
view.show();
- QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(static_cast<QWidget *>(&view), QApplication::activeWindow());
@@ -1773,7 +1835,7 @@ void tst_QListView::clickOnViewportClearsSelection()
view.selectAll();
QModelIndex index = model.index(0);
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), 1);
QVERIFY(view.selectionModel()->isSelected(index));
//we try to click outside of the index
@@ -1781,7 +1843,7 @@ void tst_QListView::clickOnViewportClearsSelection()
QTest::mousePress(view.viewport(), Qt::LeftButton, {}, point);
//at this point, the selection shouldn't have changed
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), 1);
QVERIFY(view.selectionModel()->isSelected(index));
QTest::mouseRelease(view.viewport(), Qt::LeftButton, {}, point);
@@ -1804,7 +1866,6 @@ void tst_QListView::task262152_setModelColumnNavigate()
view.setModelColumn(1);
view.show();
- QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
QCOMPARE(&view, QApplication::activeWindow());
QTest::keyClick(&view, Qt::Key_Down);
@@ -1890,7 +1951,7 @@ void tst_QListView::taskQTBUG_435_deselectOnViewportClick()
view.setModel(&model);
view.setSelectionMode(QAbstractItemView::ExtendedSelection);
view.selectAll();
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), model.rowCount());
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), model.rowCount());
const QRect itemRect = view.visualRect(model.index(model.rowCount() - 1));
@@ -1900,7 +1961,7 @@ void tst_QListView::taskQTBUG_435_deselectOnViewportClick()
QVERIFY(!view.selectionModel()->hasSelection());
view.selectAll();
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), model.rowCount());
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), model.rowCount());
//and now the right button
QTest::mouseClick(view.viewport(), Qt::RightButton, {}, p);
@@ -2471,6 +2532,46 @@ void tst_QListView::taskQTBUG_7232_AllowUserToControlSingleStep()
QCOMPARE(hStep1, lv.horizontalScrollBar()->singleStep());
}
+void tst_QListView::taskQTBUG_58749_adjustToContent()
+{
+ QStandardItemModel model;
+ model.setRowCount(20);
+ model.setColumnCount(1);
+ const QString rowStr = QStringLiteral("Row number txt:");
+ for (int u = 0; u < model.rowCount(); ++u)
+ model.setData(model.index(u, 0), rowStr + QString::number(u));
+
+ QDialog w; // It really should work for QWidget, too, but sometimes an event (like move)
+ // is needed to get the resize triggered.
+ QVBoxLayout *l = new QVBoxLayout(&w);
+ l->setSizeConstraint(QLayout::SetFixedSize);
+ auto *view = new QListView;
+ view->setModel(&model);
+ view->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
+ l->addWidget(view);
+ l->setSizeConstraint(QLayout::SetFixedSize);
+ w.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&w));
+
+ const QString longText = "Here we have a row text that is somewhat longer ...";
+
+ QFontMetrics fm(w.font(), &w);
+ QRect r = fm.boundingRect(model.data(model.index(0, 0)).toString());
+ const int longTextWidth = fm.horizontalAdvance(longText);
+ QVERIFY(w.height() > r.height() * model.rowCount());
+ // We have a width longer than the width for the given index data.
+ QVERIFY(w.width() > r.width());
+ // but ... the width should not have a width matching the much longer text.
+ QVERIFY(w.width() < longTextWidth);
+
+ // use the long text and make sure the width is adjusted.
+ model.setData(model.index(0, 0), longText);
+ QApplication::processEvents();
+ const QRect itemRect = view->visualRect(model.index(0, 0));
+ QVERIFY(w.width() > itemRect.width());
+ QCOMPARE_GE(view->width(), itemRect.width());
+}
+
void tst_QListView::taskQTBUG_51086_skippingIndexesInSelectedIndexes()
{
QStandardItemModel data(10, 1);
@@ -2504,6 +2605,221 @@ void tst_QListView::taskQTBUG_47694_indexOutOfBoundBatchLayout()
view.scrollTo(model.index(batchSize - 1, 0));
}
+class TstMoveItem
+{
+ friend class TstMoveModel;
+public:
+ TstMoveItem(TstMoveItem *parent = nullptr)
+ : parentItem(parent)
+ {
+ if (parentItem)
+ parentItem->childItems.append(this);
+ }
+
+ ~TstMoveItem()
+ {
+ QList<TstMoveItem *> delItms;
+ delItms.swap(childItems);
+ qDeleteAll(delItms);
+
+ if (parentItem)
+ parentItem->childItems.removeAll(this);
+ }
+
+ int row()
+ {
+ if (parentItem)
+ return parentItem->childItems.indexOf(this);
+ return -1;
+ }
+
+public:
+ TstMoveItem *parentItem = nullptr;
+ QList<TstMoveItem *> childItems;
+ QHash<int, QVariant> data;
+};
+
+/*!
+ Test that removing the last row in an IconView mode QListView
+ doesn't crash. The model is specifically crafted to provoke a
+ stale QBspTree by returning a 0 column count for indexes without
+ children, which changes the column count after moving the last row.
+
+ See QTBUG_95463.
+*/
+class TstMoveModel : public QAbstractItemModel
+{
+ Q_OBJECT
+public:
+ TstMoveModel(QObject *parent = nullptr)
+ : QAbstractItemModel(parent)
+ {
+ rootItem = new TstMoveItem;
+ rootItem->data.insert(Qt::DisplayRole, "root");
+
+ TstMoveItem *itm = new TstMoveItem(rootItem);
+ itm->data.insert(Qt::DisplayRole, "parentItem1");
+
+ TstMoveItem *itmCh = new TstMoveItem(itm);
+ itmCh->data.insert(Qt::DisplayRole, "childItem");
+
+ itm = new TstMoveItem(rootItem);
+ itm->data.insert(Qt::DisplayRole, "parentItem2");
+ }
+
+ ~TstMoveModel()
+ {
+ delete rootItem;
+ }
+
+ QModelIndex index(int row, int column, const QModelIndex &idxPar = QModelIndex()) const override
+ {
+ QModelIndex idx;
+ if (hasIndex(row, column, idxPar)) {
+ TstMoveItem *parentItem = nullptr;
+ if (idxPar.isValid())
+ parentItem = static_cast<TstMoveItem *>(idxPar.internalPointer());
+ else
+ parentItem = rootItem;
+
+ Q_ASSERT(parentItem);
+ TstMoveItem *childItem = parentItem->childItems.at(row);
+ if (childItem)
+ idx = createIndex(row, column, childItem);
+ }
+ return idx;
+ }
+
+ QModelIndex parent(const QModelIndex &index) const override
+ {
+ QModelIndex idxPar;
+ if (index.isValid()) {
+ TstMoveItem *childItem = static_cast<TstMoveItem *>(index.internalPointer());
+ TstMoveItem *parentItem = childItem->parentItem;
+ if (parentItem != rootItem)
+ idxPar = createIndex(parentItem->row(), 0, parentItem);
+ }
+ return idxPar;
+ }
+
+ int columnCount(const QModelIndex &idxPar = QModelIndex()) const override
+ {
+ int cnt = 0;
+ if (idxPar.isValid()) {
+ TstMoveItem *parentItem = static_cast<TstMoveItem *>(idxPar.internalPointer());
+ Q_ASSERT(parentItem);
+ cnt = parentItem->childItems.isEmpty() ? 0 : 1;
+ } else {
+ cnt = rootItem->childItems.isEmpty() ? 0 : 1;
+ }
+ return cnt;
+ }
+
+ int rowCount(const QModelIndex &idxPar = QModelIndex()) const override
+ {
+ int cnt = 0;
+ if (idxPar.isValid()) {
+ TstMoveItem *parentItem = static_cast<TstMoveItem *>(idxPar.internalPointer());
+ Q_ASSERT(parentItem);
+ cnt = parentItem->childItems.size();
+ } else {
+ cnt = rootItem->childItems.size();
+ }
+ return cnt;
+ }
+
+ Qt::ItemFlags flags(const QModelIndex &index) const override
+ {
+ Q_UNUSED(index)
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+ }
+
+ bool hasChildren(const QModelIndex &parent = QModelIndex()) const override
+ {
+ bool ret = false;
+ if (parent.isValid()) {
+ TstMoveItem *parentItem = static_cast<TstMoveItem *>(parent.internalPointer());
+ Q_ASSERT(parentItem);
+ ret = parentItem->childItems.size() > 0;
+ } else {
+ ret = rootItem->childItems.size() > 0;
+ }
+ return ret;
+ }
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
+ {
+ QVariant dt;
+ if (index.isValid()) {
+ TstMoveItem *item = static_cast<TstMoveItem *>(index.internalPointer());
+ if (item)
+ dt = item->data.value(role);
+ }
+ return dt;
+ }
+
+ bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override
+ {
+ TstMoveItem *itmSrcParent = itemAt(sourceParent);
+ TstMoveItem *itmDestParent = itemAt(destinationParent);
+
+ if (itmSrcParent && sourceRow >= 0
+ && sourceRow + count <= itmSrcParent->childItems.size()
+ && itmDestParent && destinationChild <= itmDestParent->childItems.size()) {
+ beginMoveRows(sourceParent, sourceRow, sourceRow + count - 1,
+ destinationParent, destinationChild);
+ QList<TstMoveItem *> itemsToMove;
+ for (int i = 0; i < count; ++i) {
+ TstMoveItem *itm = itmSrcParent->childItems.at(sourceRow+i);
+ itemsToMove.append(itm);
+ }
+ for (int i = itemsToMove.size() -1; i >= 0; --i) {
+ TstMoveItem *itm = itemsToMove.at(i);
+ itm->parentItem->childItems.removeAll(itm);
+ itm->parentItem = itmDestParent;
+ itmDestParent->childItems.insert(destinationChild, itm);
+ }
+ endMoveRows();
+ return true;
+ }
+ return false;
+ }
+
+private:
+ TstMoveItem *itemAt(const QModelIndex &index) const
+ {
+ TstMoveItem *item = nullptr;
+ if (index.isValid()) {
+ Q_ASSERT(index.model() == this);
+ item = static_cast<TstMoveItem *>(index.internalPointer());
+ } else {
+ item = rootItem;
+ }
+ return item;
+ }
+
+private:
+ TstMoveItem *rootItem = nullptr;
+};
+
+void tst_QListView::moveLastRow()
+{
+ TstMoveModel model;
+ QListView view;
+ view.setModel(&model);
+ view.setRootIndex(model.index(0, 0, QModelIndex()));
+ view.setViewMode(QListView::IconMode);
+ view.show();
+
+ QVERIFY(QTest::qWaitForWindowActive(&view));
+
+ QModelIndex sourceParent = model.index(0, 0);
+ QModelIndex destinationParent = model.index(1, 0);
+ // must not crash when paint event is processed
+ model.moveRow(sourceParent, 0, destinationParent, 0);
+ QTest::qWait(100);
+}
+
void tst_QListView::itemAlignment()
{
auto item1 = new QStandardItem("111");
@@ -2542,6 +2858,7 @@ void tst_QListView::internalDragDropMove_data()
| Qt::ItemIsEditable
| Qt::ItemIsDragEnabled;
+ const QStringList unchanged = QStringList{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
const QStringList reordered = QStringList{"0", "2", "3", "4", "5", "6", "7", "8", "9", "1"};
const QStringList replaced = QStringList{"0", "2", "3", "4", "1", "6", "7", "8", "9"};
@@ -2556,7 +2873,8 @@ void tst_QListView::internalDragDropMove_data()
<< Qt::MoveAction
<< defaultFlags
<< modelMoves
- << reordered;
+ // listview in IconMode doesn't change the model
+ << ((viewMode == QListView::IconMode && !modelMoves) ? unchanged : reordered);
QTest::newRow((rowName + ", only move").constData())
<< viewMode
@@ -2565,7 +2883,8 @@ void tst_QListView::internalDragDropMove_data()
<< Qt::MoveAction
<< defaultFlags
<< modelMoves
- << reordered;
+ // listview in IconMode doesn't change the model
+ << ((viewMode == QListView::IconMode && !modelMoves) ? unchanged : reordered);
QTest::newRow((rowName + ", replace item").constData())
<< viewMode
@@ -2678,6 +2997,7 @@ void tst_QListView::internalDragDropMove()
// The test relies on the global position of mouse events; make sure
// the window is properly mapped on X11.
QVERIFY(QTest::qWaitForWindowActive(&list));
+ QVERIFY(QTest::qWaitFor([&]() { return list.m_gotValidResizeEvent; }));
// execute as soon as the eventloop is running again
// which is the case inside list.startDrag()
QTimer::singleShot(0, [&]()
@@ -2710,6 +3030,176 @@ void tst_QListView::internalDragDropMove()
}
}
+/*!
+ Verify fix for QTBUG-92366
+*/
+void tst_QListView::spacingWithWordWrap_data()
+{
+ QTest::addColumn<bool>("scrollBarOverlap");
+
+ QTest::addRow("Without overlap") << false;
+ QTest::addRow("With overlap") << true;
+}
+
+void tst_QListView::spacingWithWordWrap()
+{
+ QFETCH(bool, scrollBarOverlap);
+
+ class MyStyle : public QProxyStyle
+ {
+ bool scrollBarOverlap;
+ public:
+ MyStyle(bool scrollBarOverlap) : scrollBarOverlap(scrollBarOverlap) {}
+
+ int pixelMetric(PixelMetric metric, const QStyleOption *option = nullptr,
+ const QWidget *widget = nullptr) const override{
+ switch (metric) {
+ case QStyle::PM_ScrollView_ScrollBarOverlap: return scrollBarOverlap;
+ default:
+ break;
+ }
+ return QProxyStyle::pixelMetric(metric, option, widget);
+ }
+ };
+
+ QStyle *oldStyle = QApplication::style();
+ oldStyle->setParent(nullptr);
+ const auto resetStyle = qScopeGuard([oldStyle]{
+ QApplication::setStyle(oldStyle);
+ });
+ QApplication::setStyle(new MyStyle(scrollBarOverlap));
+
+ const int listViewResizeCount = 200;
+ QWidget window;
+ window.resize(300, 200);
+ QListView lv(&window);
+
+ lv.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ lv.setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ lv.setFlow(QListView::TopToBottom);
+ lv.setWordWrap(true);
+ lv.setSpacing(0);
+ lv.setGeometry(0, 0, 200, 150);
+
+ QStandardItem *it1 = new QStandardItem("qqqqqqqqqqqqqqqqqqqqq-ttttttttttttttttt");
+ QStandardItem *it2 = new QStandardItem("qqqqqqqqqqqqqqqq-tttttttttttt");
+ QStandardItemModel model;
+ lv.setModel(&model);
+ model.appendRow(it1);
+ model.appendRow(it2);
+
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+
+ QVERIFY(!lv.verticalScrollBar()->isVisible());
+ for (int i = 0; i < listViewResizeCount; ++i) {
+ lv.resize(lv.width() + 1, lv.height());
+ QRect rectForRowOne = lv.visualRect(model.index(0, 0));
+ QRect rectForRowTwo = lv.visualRect(model.index(1, 0));
+
+ QCOMPARE(rectForRowOne.y() + rectForRowOne.height(), rectForRowTwo.y());
+ }
+
+ lv.resize(200, 150);
+ const QStringList &stringList = generateList(QStringLiteral("Test_Abnormal_Spacing"), 30);
+ for (const QString &item_string : stringList) {
+ QStandardItem *item = new QStandardItem(item_string);
+ model.appendRow(item);
+ }
+
+ // test whether the height of item is correct if the vbar is shown.
+ QTRY_VERIFY(lv.verticalScrollBar()->isVisible());
+ for (int i = 0; i < listViewResizeCount; ++i) {
+ lv.resize(lv.width() + 1, lv.height());
+ QRect rectForRowOne = lv.visualRect(model.index(0, 0));
+ QRect rectForRowTwo = lv.visualRect(model.index(1, 0));
+
+ QCOMPARE(rectForRowOne.y() + rectForRowOne.height(), rectForRowTwo.y());
+ }
+}
+
+void tst_QListView::scrollOnRemove_data()
+{
+ QTest::addColumn<QListView::ViewMode>("viewMode");
+ QTest::addColumn<QAbstractItemView::SelectionMode>("selectionMode");
+
+ const QMetaObject &mo = QListView::staticMetaObject;
+ const auto viewModeEnum = mo.enumerator(mo.indexOfEnumerator("ViewMode"));
+ const auto selectionModeEnum = mo.enumerator(mo.indexOfEnumerator("SelectionMode"));
+ for (auto viewMode : { QListView::ListMode, QListView::IconMode }) {
+ const char *viewModeName = viewModeEnum.valueToKey(viewMode);
+ for (int index = 0; index < selectionModeEnum.keyCount(); ++index) {
+ const auto selectionMode = QAbstractItemView::SelectionMode(selectionModeEnum.value(index));
+ const char *selectionModeName = selectionModeEnum.valueToKey(selectionMode);
+ QTest::addRow("%s, %s", viewModeName, selectionModeName) << viewMode << selectionMode;
+ }
+ }
+}
+
+void tst_QListView::scrollOnRemove()
+{
+ QFETCH(QListView::ViewMode, viewMode);
+ QFETCH(QAbstractItemView::SelectionMode, selectionMode);
+
+ QPixmap pixmap;
+ if (viewMode == QListView::IconMode) {
+ pixmap = QPixmap(25, 25);
+ pixmap.fill(Qt::red);
+ }
+
+ QStandardItemModel model;
+ for (int i = 0; i < 50; ++i) {
+ QStandardItem *item = new QStandardItem(QString::number(i));
+ item->setIcon(pixmap);
+ model.appendRow(item);
+ }
+
+ QWidget widget;
+ QListView view(&widget);
+ view.setFixedSize(100, 100);
+ view.setAutoScroll(true);
+ if (viewMode == QListView::IconMode)
+ view.setWrapping(true);
+ view.setModel(&model);
+ view.setSelectionMode(selectionMode);
+ view.setViewMode(viewMode);
+
+ widget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&widget));
+
+ QCOMPARE(view.verticalScrollBar()->value(), 0);
+ const QModelIndex item25 = model.index(25, 0);
+ view.scrollTo(item25);
+ QTRY_VERIFY(view.verticalScrollBar()->value() > 0); // layout and scrolling are delayed
+ const int item25Position = view.verticalScrollBar()->value();
+ // selecting a fully visible item shouldn't scroll
+ view.selectionModel()->setCurrentIndex(item25, QItemSelectionModel::SelectCurrent);
+ QTRY_COMPARE(view.verticalScrollBar()->value(), item25Position);
+
+ // removing the selected item might scroll if another item is selected
+ model.removeRow(25);
+
+ // if nothing is selected now, then the view should not have scrolled
+ if (!view.selectionModel()->selectedIndexes().size())
+ QTRY_COMPARE(view.verticalScrollBar()->value(), item25Position);
+}
+
+void tst_QListView::wordWrapNullIcon()
+{
+ QListView listView;
+ listView.setViewMode(QListView::IconMode);
+ listView.setWrapping(true);
+ listView.setWordWrap(true);
+ listView.setFixedSize(QSize(100, 500));
+
+ QStandardItemModel model;
+ QStandardItem *item = new QStandardItem(QIcon(), "This is a long text for word wrapping Item_");
+ model.appendRow(item);
+ listView.setModel(&model);
+
+ listView.indexAt(QPoint(0, 0));
+}
+
QTEST_MAIN(tst_QListView)
#include "tst_qlistview.moc"
diff --git a/tests/auto/widgets/itemviews/qlistwidget/CMakeLists.txt b/tests/auto/widgets/itemviews/qlistwidget/CMakeLists.txt
index 2c02f57324..fea17e1d75 100644
--- a/tests/auto/widgets/itemviews/qlistwidget/CMakeLists.txt
+++ b/tests/auto/widgets/itemviews/qlistwidget/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qlistwidget.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qlistwidget Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qlistwidget LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qlistwidget
SOURCES
tst_qlistwidget.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
diff --git a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
index 48b0cb8d6b..14a6cee0d9 100644
--- a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
+++ b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QCompleter>
#include <QHBoxLayout>
@@ -33,8 +8,11 @@
#include <QSignalSpy>
#include <QStyledItemDelegate>
#include <QTest>
+#include <QLabel>
#include <private/qlistwidget_p.h>
+#include <QtWidgets/private/qapplication_p.h>
+
using IntList = QList<int>;
class tst_QListWidget : public QObject
@@ -97,6 +75,8 @@ private slots:
void sortItems();
void sortHiddenItems();
void sortHiddenItems_data();
+ void sortCheckStability_data();
+ void sortCheckStability();
void closeEditor();
void setData_data();
void setData();
@@ -118,6 +98,8 @@ private slots:
void QTBUG14363_completerWithAnyKeyPressedEditTriggers();
void mimeData();
void QTBUG50891_ensureSelectionModelSignalConnectionsAreSet();
+ void createPersistentOnLayoutAboutToBeChanged();
+ void createPersistentOnLayoutAboutToBeChangedAutoSort();
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
void clearItemData();
#endif
@@ -126,6 +108,7 @@ private slots:
void moveRows();
void moveRowsInvalid_data();
void moveRowsInvalid();
+ void noopDragDrop();
protected slots:
void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last)
@@ -367,7 +350,7 @@ void tst_QListWidget::addItems()
QString::number(testWidget->count() + 3),
label};
testWidget->addItems(stringList);
- QCOMPARE(testWidget->count(), count + stringList.count());
+ QCOMPARE(testWidget->count(), count + stringList.size());
QCOMPARE(testWidget->item(testWidget->count()-1)->text(), label);
}
@@ -379,30 +362,30 @@ void tst_QListWidget::openPersistentEditor()
QListWidgetItem *item = new QListWidgetItem(QString::number(testWidget->count()));
testWidget->openPersistentEditor(item);
- int childCount = testWidget->viewport()->children().count();
+ int childCount = testWidget->viewport()->children().size();
testWidget->addItem(item);
testWidget->openPersistentEditor(item);
- QCOMPARE(childCount + 1, testWidget->viewport()->children().count());
+ QCOMPARE(childCount + 1, testWidget->viewport()->children().size());
}
void tst_QListWidget::closePersistentEditor()
{
// Boundary checking
- int childCount = testWidget->viewport()->children().count();
+ int childCount = testWidget->viewport()->children().size();
testWidget->closePersistentEditor(nullptr);
QListWidgetItem *item = new QListWidgetItem(QString::number(testWidget->count()));
testWidget->closePersistentEditor(item);
- QCOMPARE(childCount, testWidget->viewport()->children().count());
+ QCOMPARE(childCount, testWidget->viewport()->children().size());
// Create something
testWidget->addItem(item);
testWidget->openPersistentEditor(item);
// actual test
- childCount = testWidget->viewport()->children().count();
+ childCount = testWidget->viewport()->children().size();
testWidget->closePersistentEditor(item);
QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
- QCOMPARE(testWidget->viewport()->children().count(), childCount - 1);
+ QCOMPARE(testWidget->viewport()->children().size(), childCount - 1);
}
void tst_QListWidget::setItemHidden()
@@ -552,7 +535,7 @@ void tst_QListWidget::editItem()
item->setFlags(item->flags() | Qt::ItemIsEditable);
testWidget->addItem(item);
- int childCount = testWidget->viewport()->children().count();
+ int childCount = testWidget->viewport()->children().size();
QWidget *existsAlready = testWidget->indexWidget(testWidget->model()->index(testWidget->row(item), 0));
testWidget->editItem(item);
Qt::ItemFlags flags = item->flags();
@@ -560,7 +543,7 @@ void tst_QListWidget::editItem()
// There doesn't seem to be a way to detect if the item has already been edited...
if (!existsAlready && flags & Qt::ItemIsEditable && flags & Qt::ItemIsEnabled) {
QList<QObject *> children = testWidget->viewport()->children();
- QVERIFY(children.count() > childCount);
+ QVERIFY(children.size() > childCount);
bool found = false;
for (int i = 0; i < children.size(); ++i) {
if (children.at(i)->inherits("QExpandingLineEdit"))
@@ -568,7 +551,7 @@ void tst_QListWidget::editItem()
}
QVERIFY(found);
} else {
- QCOMPARE(testWidget->viewport()->children().count(), childCount);
+ QCOMPARE(testWidget->viewport()->children().size(), childCount);
}
}
@@ -577,12 +560,12 @@ void tst_QListWidget::findItems()
// This really just tests that the items that are returned are converted from index's to items correctly.
// Boundary checking
- QCOMPARE(testWidget->findItems("GirlsCanWearJeansAndCutTheirHairShort", Qt::MatchExactly).count(), 0);
+ QCOMPARE(testWidget->findItems("GirlsCanWearJeansAndCutTheirHairShort", Qt::MatchExactly).size(), 0);
populate();
for (int i = 0; i < testWidget->count(); ++i)
- QCOMPARE(testWidget->findItems(testWidget->item(i)->text(), Qt::MatchExactly).count(), 1);
+ QCOMPARE(testWidget->findItems(testWidget->item(i)->text(), Qt::MatchExactly).size(), 1);
}
@@ -597,8 +580,8 @@ void tst_QListWidget::insertItem_data()
QTest::newRow("Insert less then 0") << initialItems << -1 << "inserted" << 0;
QTest::newRow("Insert at 0") << initialItems << 0 << "inserted" << 0;
- QTest::newRow("Insert beyond count") << initialItems << initialItems.count()+1 << "inserted" << initialItems.count();
- QTest::newRow("Insert at count") << initialItems << initialItems.count() << "inserted" << initialItems.count();
+ QTest::newRow("Insert beyond count") << initialItems << initialItems.size()+1 << "inserted" << initialItems.size();
+ QTest::newRow("Insert at count") << initialItems << initialItems.size() << "inserted" << initialItems.size();
QTest::newRow("Insert in the middle") << initialItems << 1 << "inserted" << 1;
}
@@ -610,7 +593,7 @@ void tst_QListWidget::insertItem()
QFETCH(int, expectedIndex);
testWidget->insertItems(0, initialItems);
- QCOMPARE(testWidget->count(), initialItems.count());
+ QCOMPARE(testWidget->count(), initialItems.size());
testWidget->insertItem(insertIndex, itemLabel);
@@ -619,7 +602,7 @@ void tst_QListWidget::insertItem()
QCOMPARE(rcFirst[RowsInserted], expectedIndex);
QCOMPARE(rcLast[RowsInserted], expectedIndex);
- QCOMPARE(testWidget->count(), initialItems.count() + 1);
+ QCOMPARE(testWidget->count(), initialItems.size() + 1);
QCOMPARE(testWidget->item(expectedIndex)->text(), itemLabel);
}
@@ -692,8 +675,8 @@ void tst_QListWidget::insertItems()
for (int i = 0; i < testWidget->count(); ++i)
QCOMPARE(testWidget->item(i)->listWidget(), testWidget);
- QCOMPARE(itemChangedSpy.count(), 0);
- QCOMPARE(dataChangedSpy.count(), 0);
+ QCOMPARE(itemChangedSpy.size(), 0);
+ QCOMPARE(dataChangedSpy.size(), 0);
}
void tst_QListWidget::itemAssignment()
@@ -848,7 +831,7 @@ void tst_QListWidget::selectedItems()
QListWidgetItem *item = testWidget->item(i);
item->setSelected(true);
QVERIFY(item->isSelected());
- QCOMPARE(testWidget->selectedItems().count(), 1);
+ QCOMPARE(testWidget->selectedItems().size(), 1);
}
//let's clear the selection
testWidget->clearSelection();
@@ -866,7 +849,7 @@ void tst_QListWidget::selectedItems()
// check that the correct number of items and the expected items are there
QList<QListWidgetItem *> selectedItems = testWidget->selectedItems();
- QCOMPARE(selectedItems.count(), expectedRows.count());
+ QCOMPARE(selectedItems.size(), expectedRows.size());
for (int row : expectedRows)
QVERIFY(selectedItems.contains(testWidget->item(row)));
@@ -962,20 +945,20 @@ void tst_QListWidget::moveItemsPriv()
else
QCOMPARE(testWidget->item(dstRow)->text(), QString::number(srcRow));
- QCOMPARE(beginMoveSpy.count(), 1);
+ QCOMPARE(beginMoveSpy.size(), 1);
const QList<QVariant> &beginMoveArgs = beginMoveSpy.takeFirst();
QCOMPARE(beginMoveArgs.at(1).toInt(), srcRow);
QCOMPARE(beginMoveArgs.at(2).toInt(), srcRow);
QCOMPARE(beginMoveArgs.at(4).toInt(), dstRow);
- QCOMPARE(movedSpy.count(), 1);
+ QCOMPARE(movedSpy.size(), 1);
const QList<QVariant> &movedArgs = movedSpy.takeFirst();
QCOMPARE(movedArgs.at(1).toInt(), srcRow);
QCOMPARE(movedArgs.at(2).toInt(), srcRow);
QCOMPARE(movedArgs.at(4).toInt(), dstRow);
} else {
- QCOMPARE(beginMoveSpy.count(), 0);
- QCOMPARE(movedSpy.count(), 0);
+ QCOMPARE(beginMoveSpy.size(), 0);
+ QCOMPARE(movedSpy.size(), 0);
}
}
@@ -1068,7 +1051,7 @@ void tst_QListWidget::sortItems()
testWidget->sortItems(order);
- QCOMPARE(testWidget->count(), expectedList.count());
+ QCOMPARE(testWidget->count(), expectedList.size());
for (int i = 0; i < testWidget->count(); ++i)
QCOMPARE(testWidget->item(i)->text(), expectedList.at(i).toString());
@@ -1138,7 +1121,7 @@ void tst_QListWidget::sortHiddenItems()
tw->setSortingEnabled(true);
tw->sortItems(order);
- QCOMPARE(tw->count(), expectedList.count());
+ QCOMPARE(tw->count(), expectedList.size());
for (int i = 0; i < tw->count(); ++i) {
QCOMPARE(tw->item(i)->text(), expectedList.at(i));
QCOMPARE(tw->item(i)->isHidden(), !expectedVisibility.at(i));
@@ -1150,6 +1133,64 @@ void tst_QListWidget::sortHiddenItems()
delete tw;
}
+void tst_QListWidget::sortCheckStability_data() {
+ QTest::addColumn<Qt::SortOrder>("order");
+ QTest::addColumn<QVariantList>("initialList");
+ QTest::addColumn<QVariantList>("expectedList");
+
+ QTest::newRow("ascending strings")
+ << Qt::AscendingOrder
+ << QVariantList{ QString("a"), QString("b"), QString("b"), QString("a")}
+ << QVariantList{ QString("a"), QString("a"), QString("b"), QString("b")};
+
+ QTest::newRow("descending strings")
+ << Qt::DescendingOrder
+ << QVariantList{ QString("a"), QString("b"), QString("b"), QString("a")}
+ << QVariantList{ QString("b"), QString("b"), QString("a"), QString("a")};
+
+ QTest::newRow("ascending numbers")
+ << Qt::AscendingOrder
+ << QVariantList{ 1, 2, 2, 1}
+ << QVariantList{ 1, 1, 2, 2};
+
+ QTest::newRow("descending numbers")
+ << Qt::DescendingOrder
+ << QVariantList{ 1, 2, 2, 1}
+ << QVariantList{ 2, 2, 1, 1};
+}
+
+void tst_QListWidget::sortCheckStability() {
+ QFETCH(Qt::SortOrder, order);
+ QFETCH(const QVariantList, initialList);
+ QFETCH(const QVariantList, expectedList);
+
+ for (const QVariant &data : initialList) {
+ QListWidgetItem *item = new QListWidgetItem(testWidget);
+ item->setData(Qt::DisplayRole, data);
+ }
+
+ QAbstractItemModel *model = testWidget->model();
+ QList<QPersistentModelIndex> persistent;
+ for (int j = 0; j < model->rowCount(QModelIndex()); ++j)
+ persistent << model->index(j, 0, QModelIndex());
+
+ testWidget->sortItems(order);
+
+ QCOMPARE(testWidget->count(), expectedList.size());
+ for (int i = 0; i < testWidget->count(); ++i)
+ QCOMPARE(testWidget->item(i)->text(), expectedList.at(i).toString());
+
+ QVector<QListWidgetItem*> itemOrder(testWidget->count());
+ for (int i = 0; i < testWidget->count(); ++i)
+ itemOrder[i] = testWidget->item(i);
+
+ qobject_cast<QListModel*>(testWidget->model())->ensureSorted(0, order, 1, 1);
+ testWidget->sortItems(order);
+
+ for (int i = 0; i < testWidget->count(); ++i)
+ QCOMPARE(itemOrder[i],testWidget->item(i));
+}
+
class TestListWidget : public QListWidget
{
Q_OBJECT
@@ -1235,17 +1276,17 @@ void tst_QListWidget::setData()
QFETCH(QVariantList, values);
QFETCH(int, expectedSignalCount);
- QCOMPARE(roles.count(), values.count());
+ QCOMPARE(roles.size(), values.size());
for (int manipulateModel = 0; manipulateModel < 2; ++manipulateModel) {
testWidget->clear();
testWidget->insertItems(0, initialItems);
- QCOMPARE(testWidget->count(), initialItems.count());
+ QCOMPARE(testWidget->count(), initialItems.size());
QSignalSpy itemChanged(testWidget, &QListWidget::itemChanged);
QSignalSpy dataChanged(testWidget->model(), &QAbstractItemModel::dataChanged);
- for (int i = 0; i < roles.count(); ++i) {
+ for (int i = 0; i < roles.size(); ++i) {
if (manipulateModel)
testWidget->model()->setData(
testWidget->model()->index(itemIndex, 0, testWidget->rootIndex()),
@@ -1256,12 +1297,12 @@ void tst_QListWidget::setData()
}
// make sure the data is actually set
- for (int i = 0; i < roles.count(); ++i)
+ for (int i = 0; i < roles.size(); ++i)
QCOMPARE(testWidget->item(itemIndex)->data(roles.at(i)), values.at(i));
// make sure we get the right number of emits
- QCOMPARE(itemChanged.count(), expectedSignalCount);
- QCOMPARE(dataChanged.count(), expectedSignalCount);
+ QCOMPARE(itemChanged.size(), expectedSignalCount);
+ QCOMPARE(dataChanged.size(), expectedSignalCount);
}
}
@@ -1403,11 +1444,11 @@ void tst_QListWidget::insertItemsWithSorting()
w.addItem(str);
break;
}
- QCOMPARE(w.count(), expectedItems.count());
+ QCOMPARE(w.count(), expectedItems.size());
for (int i = 0; i < w.count(); ++i)
QCOMPARE(w.item(i)->text(), expectedItems.at(i));
- for (int k = 0; k < persistent.count(); ++k)
+ for (int k = 0; k < persistent.size(); ++k)
QCOMPARE(persistent.at(k).row(), expectedRows.at(k));
}
}
@@ -1503,7 +1544,7 @@ void tst_QListWidget::itemData()
QCOMPARE(widget.currentRoles, QList<int> { Qt::UserRole + i });
}
QMap<int, QVariant> flags = widget.model()->itemData(widget.model()->index(0, 0));
- QCOMPARE(flags.count(), 6);
+ QCOMPARE(flags.size(), 6);
for (int i = 0; i < 4; ++i)
QCOMPARE(flags[Qt::UserRole + i].toString(), QString::number(i + 1));
@@ -1547,19 +1588,19 @@ void tst_QListWidget::changeDataWithSorting()
QListWidgetItem *item = w.item(itemIndex);
item->setText(newValue);
- for (int i = 0; i < expectedItems.count(); ++i) {
+ for (int i = 0; i < expectedItems.size(); ++i) {
QCOMPARE(w.item(i)->text(), expectedItems.at(i));
- for (int j = 0; j < persistent.count(); ++j) {
+ for (int j = 0; j < persistent.size(); ++j) {
if (persistent.at(j).row() == i) // the same toplevel row
QCOMPARE(persistent.at(j).internalPointer(), static_cast<void *>(w.item(i)));
}
}
- for (int k = 0; k < persistent.count(); ++k)
+ for (int k = 0; k < persistent.size(); ++k)
QCOMPARE(persistent.at(k).row(), expectedRows.at(k));
- QCOMPARE(dataChangedSpy.count(), 1);
- QCOMPARE(layoutChangedSpy.count(), reorderingExpected ? 1 : 0);
+ QCOMPARE(dataChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), reorderingExpected ? 1 : 0);
}
void tst_QListWidget::itemWidget()
@@ -1638,7 +1679,7 @@ void tst_QListWidget::insertUnchanged()
QListWidget w;
QSignalSpy itemChangedSpy(&w, &QListWidget::itemChanged);
QListWidgetItem item("foo", &w);
- QCOMPARE(itemChangedSpy.count(), 0);
+ QCOMPARE(itemChangedSpy.size(), 0);
}
void tst_QListWidget::setSortingEnabled()
@@ -1729,12 +1770,12 @@ void tst_QListWidget::QTBUG8086_currentItemChangedOnClick()
QVERIFY(QTest::qWaitForWindowExposed(&win));
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
QTest::mouseClick(list.viewport(), Qt::LeftButton, {},
list.visualItemRect(list.item(2)).center());
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
@@ -1769,7 +1810,6 @@ void tst_QListWidget::QTBUG14363_completerWithAnyKeyPressedEditTriggers()
new QListWidgetItem(QLatin1String("completer"), &listWidget);
listWidget.show();
listWidget.setCurrentItem(item);
- QApplication::setActiveWindow(&listWidget);
QVERIFY(QTest::qWaitForWindowActive(&listWidget));
listWidget.setFocus();
QCOMPARE(QApplication::focusWidget(), &listWidget);
@@ -1833,15 +1873,133 @@ void tst_QListWidget::QTBUG50891_ensureSelectionModelSignalConnectionsAreSet()
QSignalSpy currentItemChangedSpy(&list, &QListWidget::currentItemChanged);
QSignalSpy itemSelectionChangedSpy(&list, &QListWidget::itemSelectionChanged);
- QCOMPARE(currentItemChangedSpy.count(), 0);
- QCOMPARE(itemSelectionChangedSpy.count(), 0);
+ QCOMPARE(currentItemChangedSpy.size(), 0);
+ QCOMPARE(itemSelectionChangedSpy.size(), 0);
QTest::mouseClick(list.viewport(), Qt::LeftButton, {},
list.visualItemRect(list.item(2)).center());
- QCOMPARE(currentItemChangedSpy.count(), 1);
- QCOMPARE(itemSelectionChangedSpy.count(), 1);
+ QCOMPARE(currentItemChangedSpy.size(), 1);
+ QCOMPARE(itemSelectionChangedSpy.size(), 1);
+
+}
+
+void tst_QListWidget::createPersistentOnLayoutAboutToBeChanged() // QTBUG-93466
+{
+ QListWidget widget;
+ QCOMPARE(widget.model()->columnCount(), 1);
+ widget.model()->insertRows(0, 3);
+ for (int row = 0; row < 3; ++row)
+ widget.model()->setData(widget.model()->index(row, 0), row);
+ QList<QPersistentModelIndex> idxList;
+ QSignalSpy layoutAboutToBeChangedSpy(widget.model(), &QAbstractItemModel::layoutAboutToBeChanged);
+ QSignalSpy layoutChangedSpy(widget.model(), &QAbstractItemModel::layoutChanged);
+ connect(widget.model(), &QAbstractItemModel::layoutAboutToBeChanged, this, [&idxList, &widget](){
+ idxList.clear();
+ for (int row = 0; row < 3; ++row)
+ idxList << QPersistentModelIndex(widget.model()->index(row, 0));
+ });
+ connect(widget.model(), &QAbstractItemModel::layoutChanged, this, [&idxList](){
+ QCOMPARE(idxList.size(), 3);
+ QCOMPARE(idxList.at(0).row(), 1);
+ QCOMPARE(idxList.at(0).column(), 0);
+ QCOMPARE(idxList.at(0).data().toInt(), 0);
+ QCOMPARE(idxList.at(1).row(), 0);
+ QCOMPARE(idxList.at(1).column(), 0);
+ QCOMPARE(idxList.at(1).data().toInt(), -1);
+ QCOMPARE(idxList.at(2).row(), 2);
+ QCOMPARE(idxList.at(2).column(), 0);
+ QCOMPARE(idxList.at(2).data().toInt(), 2);
+ });
+ widget.model()->setData(widget.model()->index(1, 0), -1);
+ widget.model()->sort(0);
+ QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), 1);
+}
+
+void tst_QListWidget::createPersistentOnLayoutAboutToBeChangedAutoSort() // QTBUG-93466
+{
+ QListWidget widget;
+ QCOMPARE(widget.model()->columnCount(), 1);
+ widget.model()->insertRows(0, 3);
+ for (int row = 0; row < 3; ++row)
+ widget.model()->setData(widget.model()->index(row, 0), row);
+ widget.setSortingEnabled(true);
+ QList<QPersistentModelIndex> idxList;
+ QSignalSpy layoutAboutToBeChangedSpy(widget.model(), &QAbstractItemModel::layoutAboutToBeChanged);
+ QSignalSpy layoutChangedSpy(widget.model(), &QAbstractItemModel::layoutChanged);
+ connect(widget.model(), &QAbstractItemModel::layoutAboutToBeChanged, this, [&idxList, &widget](){
+ idxList.clear();
+ for (int row = 0; row < 3; ++row)
+ idxList << QPersistentModelIndex(widget.model()->index(row, 0));
+ });
+ connect(widget.model(), &QAbstractItemModel::layoutChanged, this, [&idxList](){
+ QCOMPARE(idxList.size(), 3);
+ QCOMPARE(idxList.at(0).row(), 1);
+ QCOMPARE(idxList.at(0).column(), 0);
+ QCOMPARE(idxList.at(0).data().toInt(), 0);
+ QCOMPARE(idxList.at(1).row(), 0);
+ QCOMPARE(idxList.at(1).column(), 0);
+ QCOMPARE(idxList.at(1).data().toInt(), -1);
+ QCOMPARE(idxList.at(2).row(), 2);
+ QCOMPARE(idxList.at(2).column(), 0);
+ QCOMPARE(idxList.at(2).data().toInt(), 2);
+ });
+ widget.model()->setData(widget.model()->index(1, 0), -1);
+ QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), 1);
+}
+
+// Test that dropping an item on or beneath itself remains a no-op
+void tst_QListWidget::noopDragDrop() // QTBUG-100128
+{
+ QListWidget listWidget;
+ QList<QListWidgetItem *> items;
+ for (int i = 0; i < 5; ++i) {
+ const QString number = QString::number(i);
+ QListWidgetItem *item = new QListWidgetItem(&listWidget);
+ item->setData(Qt::UserRole, number);
+ QLabel *label = new QLabel(number);
+ listWidget.setItemWidget(item, label);
+ items.append(item);
+ }
+
+ listWidget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&listWidget));
+
+ const QRect &lastItemRect = listWidget.visualItemRect(items.at(4));
+ const QPoint &dragStart = lastItemRect.center();
+ const QPoint &dropPointNirvana = lastItemRect.center() + QPoint(20, 2 * lastItemRect.height());
+
+ // Implement check as a macro (not a method) to safely determine the error location.
+ // The macro checks that item data and item widget remain unchanged when drag&drop are executed.
+ // In order to verify that the assets do *not* change, we can't use QTRY*: These macros would
+ // spin the event loop only once, while 3/4 mouse events need to get processed.
+ // That's why we spin the event loop 13 times, to make sure other unexpected or pending events
+ // get processed.
+#define CHECK_ITEM {\
+ const QString number = QString::number(4);\
+ for (int i = 0; i < 13; ++i)\
+ QApplication::processEvents();\
+ QLabel *label = qobject_cast<QLabel *>(listWidget.itemWidget(items.at(4)));\
+ QVERIFY(label);\
+ QCOMPARE(label->text(), number);\
+ const QString &data = items.at(4)->data(Qt::UserRole).toString();\
+ QCOMPARE(data, number);\
+ }
+ // Test dropping last item beneath itself
+ QTest::mousePress(&listWidget, Qt::LeftButton, Qt::KeyboardModifiers(), dragStart);
+ QTest::mouseMove(&listWidget, dropPointNirvana);
+ QTest::mouseRelease(&listWidget, Qt::LeftButton);
+ CHECK_ITEM;
+
+ // Test dropping last item on itself
+ QTest::mousePress(&listWidget, Qt::LeftButton, Qt::KeyboardModifiers(), dragStart);
+ QTest::mouseMove(&listWidget, dropPointNirvana);
+ QTest::mouseMove(&listWidget, dragStart);
+ QTest::mouseRelease(&listWidget, Qt::LeftButton);
+ CHECK_ITEM;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
diff --git a/tests/auto/widgets/itemviews/qtableview/BLACKLIST b/tests/auto/widgets/itemviews/qtableview/BLACKLIST
index c8fc59bc46..ff870915be 100644
--- a/tests/auto/widgets/itemviews/qtableview/BLACKLIST
+++ b/tests/auto/widgets/itemviews/qtableview/BLACKLIST
@@ -3,10 +3,3 @@ osx
[mouseWheel:scroll down per pixel]
macos
-# QTBUG-87407
-[rowViewportPosition]
-android
-[columnViewportPosition]
-android
-[task191545_dragSelectRows]
-android
diff --git a/tests/auto/widgets/itemviews/qtableview/CMakeLists.txt b/tests/auto/widgets/itemviews/qtableview/CMakeLists.txt
index 23e6a01f7d..af78c0f5d3 100644
--- a/tests/auto/widgets/itemviews/qtableview/CMakeLists.txt
+++ b/tests/auto/widgets/itemviews/qtableview/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qtableview.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qtableview Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtableview LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtableview
SOURCES
tst_qtableview.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
index 92bc30380a..681be2491d 100644
--- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QIdentityProxyModel>
#include <QLabel>
@@ -77,6 +52,13 @@ public:
: QAbstractTableModel(parent), row_count(rows), column_count(columns)
{}
+ void insertRows(int rows)
+ {
+ beginInsertRows(QModelIndex(), row_count, row_count + rows - 1);
+ row_count += rows;
+ endInsertRows();
+ }
+
int rowCount(const QModelIndex& = QModelIndex()) const override
{
return row_count;
@@ -409,6 +391,7 @@ private slots:
void resizeToContents();
void resizeToContentsSpans();
+ void resizeToContentsEarly();
void tabFocus();
void bigModel();
@@ -437,6 +420,11 @@ private slots:
void taskQTBUG_30653_doItemsLayout();
void taskQTBUG_50171_selectRowAfterSwapColumns();
void deselectRow();
+ void selectRowsAndCells();
+ void selectColumnsAndCells();
+ void selectWithHeader_data();
+ void selectWithHeader();
+ void resetDefaultSectionSize();
#if QT_CONFIG(wheelevent)
void mouseWheel_data();
@@ -450,6 +438,7 @@ private slots:
void viewOptions();
void taskQTBUG_7232_AllowUserToControlSingleStep();
+ void rowsInVerticalHeader();
#if QT_CONFIG(textmarkdownwriter)
void markdownWriter();
@@ -524,7 +513,7 @@ void tst_QTableView::emptyModel()
QSignalSpy spy(&model, &QtTestTableModel::invalidIndexEncountered);
view.setModel(&model);
view.show();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
}
void tst_QTableView::removeRows_data()
@@ -549,10 +538,10 @@ void tst_QTableView::removeRows()
view.show();
model.removeLastRow();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
model.removeAllRows();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
}
void tst_QTableView::removeColumns_data()
@@ -577,10 +566,10 @@ void tst_QTableView::removeColumns()
view.show();
model.removeLastColumn();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
model.removeAllColumns();
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
}
void tst_QTableView::keyboardNavigation_data()
@@ -621,7 +610,6 @@ void tst_QTableView::keyboardNavigation()
view.setCurrentIndex(index);
view.show();
- QApplication::setActiveWindow(&view);
QVERIFY(QTest::qWaitForWindowActive(&view));
int row = rowCount - 1;
@@ -1618,7 +1606,7 @@ void tst_QTableView::selection()
view.setSelection(QRect(x, y, width, height), command);
- QCOMPARE(view.selectedIndexes().count(), selectedCount);
+ QCOMPARE(view.selectedIndexes().size(), selectedCount);
}
void tst_QTableView::selectRow_data()
@@ -1731,12 +1719,12 @@ void tst_QTableView::selectRow()
view.setSelectionMode(mode);
view.setSelectionBehavior(behavior);
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), 0);
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), 0);
view.selectRow(row);
//test we have 10 items selected
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), selectedItems);
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), selectedItems);
//test that all 10 items are in the same row
for (int i = 0; selectedItems > 0 && i < rowCount; ++i)
QCOMPARE(view.selectionModel()->selectedIndexes().at(i).row(), row);
@@ -1852,11 +1840,11 @@ void tst_QTableView::selectColumn()
view.setSelectionMode(mode);
view.setSelectionBehavior(behavior);
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), 0);
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), 0);
view.selectColumn(column);
- QCOMPARE(view.selectionModel()->selectedIndexes().count(), selectedItems);
+ QCOMPARE(view.selectionModel()->selectedIndexes().size(), selectedItems);
for (int i = 0; selectedItems > 0 && i < columnCount; ++i)
QCOMPARE(view.selectionModel()->selectedIndexes().at(i).column(), column);
}
@@ -2001,22 +1989,22 @@ void tst_QTableView::selectall()
// try slot first
view.clearSelection();
- QCOMPARE(view.selectedIndexes().count(), 0);
+ QCOMPARE(view.selectedIndexes().size(), 0);
view.selectAll();
- QCOMPARE(view.selectedIndexes().count(), selectedCount);
+ QCOMPARE(view.selectedIndexes().size(), selectedCount);
// try by key sequence
view.clearSelection();
- QCOMPARE(view.selectedIndexes().count(), 0);
+ QCOMPARE(view.selectedIndexes().size(), 0);
QTest__keySequence(&view, QKeySequence(QKeySequence::SelectAll));
- QCOMPARE(view.selectedIndexes().count(), selectedCount);
+ QCOMPARE(view.selectedIndexes().size(), selectedCount);
// check again with no selection mode
view.clearSelection();
view.setSelectionMode(QAbstractItemView::NoSelection);
- QCOMPARE(view.selectedIndexes().count(), 0);
+ QCOMPARE(view.selectedIndexes().size(), 0);
QTest__keySequence(&view, QKeySequence(QKeySequence::SelectAll));
- QCOMPARE(view.selectedIndexes().count(), 0);
+ QCOMPARE(view.selectedIndexes().size(), 0);
}
#endif // QT_CONFIG(shortcut)
@@ -2209,7 +2197,7 @@ void tst_QTableView::resizeRowsToContents()
QSignalSpy resizedSpy(view.verticalHeader(), &QHeaderView::sectionResized);
view.resizeRowsToContents();
- QCOMPARE(resizedSpy.count(), model.rowCount());
+ QCOMPARE(resizedSpy.size(), model.rowCount());
for (int r = 0; r < model.rowCount(); ++r)
QCOMPARE(view.rowHeight(r), rowHeight);
}
@@ -2255,7 +2243,7 @@ void tst_QTableView::resizeColumnsToContents()
QSignalSpy resizedSpy(view.horizontalHeader(), &QHeaderView::sectionResized);
view.resizeColumnsToContents();
- QCOMPARE(resizedSpy.count(), model.columnCount());
+ QCOMPARE(resizedSpy.size(), model.columnCount());
for (int c = 0; c < model.columnCount(); ++c)
QCOMPARE(view.columnWidth(c), columnWidth);
}
@@ -2270,46 +2258,46 @@ void tst_QTableView::rowViewportPosition_data()
QTest::addColumn<int>("rowViewportPosition");
QTest::newRow("row 0, scroll per item 0")
- << 10 << 40 << 0 << QAbstractItemView::ScrollPerItem << 0 << 0;
+ << 100 << 40 << 0 << QAbstractItemView::ScrollPerItem << 0 << 0;
QTest::newRow("row 1, scroll per item, 0")
- << 10 << 40 << 1 << QAbstractItemView::ScrollPerItem << 0 << 1 * 40;
+ << 100 << 40 << 1 << QAbstractItemView::ScrollPerItem << 0 << 1 * 40;
QTest::newRow("row 1, scroll per item, 1")
- << 10 << 40 << 1 << QAbstractItemView::ScrollPerItem << 1 << 0;
+ << 100 << 40 << 1 << QAbstractItemView::ScrollPerItem << 1 << 0;
QTest::newRow("row 5, scroll per item, 0")
- << 10 << 40 << 5 << QAbstractItemView::ScrollPerItem << 0 << 5 * 40;
+ << 100 << 40 << 5 << QAbstractItemView::ScrollPerItem << 0 << 5 * 40;
QTest::newRow("row 5, scroll per item, 5")
- << 10 << 40 << 5 << QAbstractItemView::ScrollPerItem << 5 << 0;
+ << 100 << 40 << 5 << QAbstractItemView::ScrollPerItem << 5 << 0;
QTest::newRow("row 9, scroll per item, 0")
- << 10 << 40 << 9 << QAbstractItemView::ScrollPerItem << 0 << 9 * 40;
+ << 100 << 40 << 9 << QAbstractItemView::ScrollPerItem << 0 << 9 * 40;
QTest::newRow("row 9, scroll per item, 5")
- << 10 << 40 << 9 << QAbstractItemView::ScrollPerItem << 5 << 4 * 40;
+ << 100 << 40 << 9 << QAbstractItemView::ScrollPerItem << 5 << 4 * 40;
QTest::newRow("row 0, scroll per pixel 0")
- << 10 << 40 << 0 << QAbstractItemView::ScrollPerPixel << 0 << 0;
+ << 100 << 40 << 0 << QAbstractItemView::ScrollPerPixel << 0 << 0;
QTest::newRow("row 1, scroll per pixel, 0")
- << 10 << 40 << 1 << QAbstractItemView::ScrollPerPixel << 0 << 1 * 40;
+ << 100 << 40 << 1 << QAbstractItemView::ScrollPerPixel << 0 << 1 * 40;
QTest::newRow("row 1, scroll per pixel, 1")
- << 10 << 40 << 1 << QAbstractItemView::ScrollPerPixel << 1 * 40 << 0;
+ << 100 << 40 << 1 << QAbstractItemView::ScrollPerPixel << 1 * 40 << 0;
QTest::newRow("row 5, scroll per pixel, 0")
- << 10 << 40 << 5 << QAbstractItemView::ScrollPerPixel << 0 << 5 * 40;
+ << 100 << 40 << 5 << QAbstractItemView::ScrollPerPixel << 0 << 5 * 40;
QTest::newRow("row 5, scroll per pixel, 5")
- << 10 << 40 << 5 << QAbstractItemView::ScrollPerPixel << 5 * 40 << 0;
+ << 100 << 40 << 5 << QAbstractItemView::ScrollPerPixel << 5 * 40 << 0;
QTest::newRow("row 9, scroll per pixel, 0")
- << 10 << 40 << 9 << QAbstractItemView::ScrollPerPixel << 0 << 9 * 40;
+ << 100 << 40 << 9 << QAbstractItemView::ScrollPerPixel << 0 << 9 * 40;
QTest::newRow("row 9, scroll per pixel, 5")
- << 10 << 40 << 9 << QAbstractItemView::ScrollPerPixel << 5 * 40 << 4 * 40;
+ << 100 << 40 << 9 << QAbstractItemView::ScrollPerPixel << 5 * 40 << 4 * 40;
}
void tst_QTableView::rowViewportPosition()
@@ -2369,7 +2357,7 @@ void tst_QTableView::rowAt()
for (int r = 0; r < rowCount; ++r)
view.setRowHeight(r, rowHeight);
- for (int i = 0; i < hiddenRows.count(); ++i)
+ for (int i = 0; i < hiddenRows.size(); ++i)
view.hideRow(hiddenRows.at(i));
QCOMPARE(view.rowAt(coordinate), row);
@@ -2433,46 +2421,46 @@ void tst_QTableView::columnViewportPosition_data()
QTest::addColumn<int>("columnViewportPosition");
QTest::newRow("column 0, scroll per item 0")
- << 10 << 40 << 0 << QAbstractItemView::ScrollPerItem << 0 << 0;
+ << 100 << 40 << 0 << QAbstractItemView::ScrollPerItem << 0 << 0;
QTest::newRow("column 1, scroll per item, 0")
- << 10 << 40 << 1 << QAbstractItemView::ScrollPerItem << 0 << 1 * 40;
+ << 100 << 40 << 1 << QAbstractItemView::ScrollPerItem << 0 << 1 * 40;
QTest::newRow("column 1, scroll per item, 1")
- << 10 << 40 << 1 << QAbstractItemView::ScrollPerItem << 1 << 0;
+ << 100 << 40 << 1 << QAbstractItemView::ScrollPerItem << 1 << 0;
QTest::newRow("column 5, scroll per item, 0")
- << 10 << 40 << 5 << QAbstractItemView::ScrollPerItem << 0 << 5 * 40;
+ << 100 << 40 << 5 << QAbstractItemView::ScrollPerItem << 0 << 5 * 40;
QTest::newRow("column 5, scroll per item, 5")
- << 10 << 40 << 5 << QAbstractItemView::ScrollPerItem << 5 << 0;
+ << 100 << 40 << 5 << QAbstractItemView::ScrollPerItem << 5 << 0;
QTest::newRow("column 9, scroll per item, 0")
- << 10 << 40 << 9 << QAbstractItemView::ScrollPerItem << 0 << 9 * 40;
+ << 100 << 40 << 9 << QAbstractItemView::ScrollPerItem << 0 << 9 * 40;
QTest::newRow("column 9, scroll per item, 5")
- << 10 << 40 << 9 << QAbstractItemView::ScrollPerItem << 5 << 4 * 40;
+ << 100 << 40 << 9 << QAbstractItemView::ScrollPerItem << 5 << 4 * 40;
QTest::newRow("column 0, scroll per pixel 0")
- << 10 << 40 << 0 << QAbstractItemView::ScrollPerPixel << 0 << 0;
+ << 100 << 40 << 0 << QAbstractItemView::ScrollPerPixel << 0 << 0;
QTest::newRow("column 1, scroll per pixel 0")
- << 10 << 40 << 1 << QAbstractItemView::ScrollPerPixel << 0 << 1 * 40;
+ << 100 << 40 << 1 << QAbstractItemView::ScrollPerPixel << 0 << 1 * 40;
QTest::newRow("column 1, scroll per pixel 1")
- << 10 << 40 << 1 << QAbstractItemView::ScrollPerPixel << 1 * 40 << 0;
+ << 100 << 40 << 1 << QAbstractItemView::ScrollPerPixel << 1 * 40 << 0;
QTest::newRow("column 5, scroll per pixel 0")
- << 10 << 40 << 5 << QAbstractItemView::ScrollPerPixel << 0 << 5 * 40;
+ << 100 << 40 << 5 << QAbstractItemView::ScrollPerPixel << 0 << 5 * 40;
QTest::newRow("column 5, scroll per pixel 5")
- << 10 << 40 << 5 << QAbstractItemView::ScrollPerPixel << 5 * 40 << 0;
+ << 100 << 40 << 5 << QAbstractItemView::ScrollPerPixel << 5 * 40 << 0;
QTest::newRow("column 9, scroll per pixel 0")
- << 10 << 40 << 9 << QAbstractItemView::ScrollPerPixel << 0 << 9 * 40;
+ << 100 << 40 << 9 << QAbstractItemView::ScrollPerPixel << 0 << 9 * 40;
QTest::newRow("column 9, scroll per pixel 5")
- << 10 << 40 << 9 << QAbstractItemView::ScrollPerPixel << 5 * 40 << 4 * 40;
+ << 100 << 40 << 9 << QAbstractItemView::ScrollPerPixel << 5 * 40 << 4 * 40;
}
void tst_QTableView::columnViewportPosition()
@@ -2532,7 +2520,7 @@ void tst_QTableView::columnAt()
for (int c = 0; c < columnCount; ++c)
view.setColumnWidth(c, columnWidth);
- for (int i = 0; i < hiddenColumns.count(); ++i)
+ for (int i = 0; i < hiddenColumns.size(); ++i)
view.hideColumn(hiddenColumns.at(i));
QCOMPARE(view.columnAt(coordinate), column);
@@ -3789,6 +3777,35 @@ void tst_QTableView::resizeToContentsSpans()
QCOMPARE(view2.columnWidth(0), view3.columnWidth(0) - view2.columnWidth(1));
}
+void tst_QTableView::resizeToContentsEarly()
+{
+ QStringListModel model;
+ QTableView view;
+
+ // connect to the model before setting it on the view
+ connect(&model, &QStringListModel::modelReset, &model, [&view]{
+ view.resizeColumnsToContents();
+ });
+ connect(&model, &QStringListModel::modelReset, &model, [&view]{
+ view.resizeRowsToContents();
+ });
+
+ // the view only connects now to the model's signals, so responds to the
+ // reset signal *after* the lambdas above
+ view.setModel(&model);
+
+ QStringList data(200, QString("Hello World"));
+ model.setStringList(data);
+
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ view.verticalScrollBar()->setValue(view.verticalScrollBar()->maximum());
+
+ data = data.sliced(data.size() / 2);
+ model.setStringList(data);
+}
+
QT_BEGIN_NAMESPACE
extern bool Q_WIDGETS_EXPORT qt_tab_all_widgets(); // qapplication.cpp
QT_END_NAMESPACE
@@ -3811,7 +3828,6 @@ void tst_QTableView::tabFocus()
QLineEdit *edit = new QLineEdit(&window);
window.show();
- QApplication::setActiveWindow(&window);
window.setFocus();
window.activateWindow();
QVERIFY(QTest::qWaitForWindowActive(&window));
@@ -4351,15 +4367,18 @@ void tst_QTableView::task191545_dragSelectRows()
QHeaderView *vHeader = table.verticalHeader();
QWidget *vHeaderVp = vHeader->viewport();
QPoint rowPos(cellRect.center());
- QMouseEvent rowPressEvent(QEvent::MouseButtonPress, rowPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
+ QMouseEvent rowPressEvent(QEvent::MouseButtonPress, rowPos, rowPos, vHeaderVp->mapToGlobal(rowPos),
+ Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
QCoreApplication::sendEvent(vHeaderVp, &rowPressEvent);
for (int i = 0; i < 4; ++i) {
rowPos.setY(rowPos.y() + cellRect.height());
- QMouseEvent moveEvent(QEvent::MouseMove, rowPos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
+ QMouseEvent moveEvent(QEvent::MouseMove, rowPos, rowPos, vHeaderVp->mapToGlobal(rowPos),
+ Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
QCoreApplication::sendEvent(vHeaderVp, &moveEvent);
}
- QMouseEvent rowReleaseEvent(QEvent::MouseButtonRelease, rowPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
+ QMouseEvent rowReleaseEvent(QEvent::MouseButtonRelease, rowPos, vHeaderVp->mapToGlobal(rowPos),
+ Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
QCoreApplication::sendEvent(vHeaderVp, &rowReleaseEvent);
for (int i = 0; i < 4; ++i) {
@@ -4373,15 +4392,18 @@ void tst_QTableView::task191545_dragSelectRows()
QHeaderView *hHeader = table.horizontalHeader();
QWidget *hHeaderVp = hHeader->viewport();
QPoint colPos((cellRect.left() + cellRect.right()) / 2, 5);
- QMouseEvent colPressEvent(QEvent::MouseButtonPress, colPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
+ QMouseEvent colPressEvent(QEvent::MouseButtonPress, colPos, hHeaderVp->mapToGlobal(colPos),
+ Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
QCoreApplication::sendEvent(hHeaderVp, &colPressEvent);
for (int i = 0; i < 4; ++i) {
colPos.setX(colPos.x() + cellRect.width());
- QMouseEvent moveEvent(QEvent::MouseMove, colPos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
+ QMouseEvent moveEvent(QEvent::MouseMove, colPos, hHeaderVp->mapToGlobal(colPos),
+ Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
QCoreApplication::sendEvent(hHeaderVp, &moveEvent);
}
- QMouseEvent colReleaseEvent(QEvent::MouseButtonRelease, colPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
+ QMouseEvent colReleaseEvent(QEvent::MouseButtonRelease, colPos, hHeaderVp->mapToGlobal(colPos),
+ Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
QCoreApplication::sendEvent(hHeaderVp, &colReleaseEvent);
for (int i = 0; i < 4; ++i) {
@@ -4394,16 +4416,19 @@ void tst_QTableView::task191545_dragSelectRows()
QRect cellRect = table.visualRect(model.index(2, 2));
QWidget *tableVp = table.viewport();
QPoint cellPos = cellRect.center();
- QMouseEvent cellPressEvent(QEvent::MouseButtonPress, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
+ QMouseEvent cellPressEvent(QEvent::MouseButtonPress, cellPos, tableVp->mapToGlobal(cellPos),
+ Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
QCoreApplication::sendEvent(tableVp, &cellPressEvent);
for (int i = 0; i < 6; ++i) {
cellPos.setX(cellPos.x() + cellRect.width());
cellPos.setY(cellPos.y() + cellRect.height());
- QMouseEvent moveEvent(QEvent::MouseMove, cellPos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
+ QMouseEvent moveEvent(QEvent::MouseMove, cellPos, tableVp->mapToGlobal(cellPos),
+ Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
QCoreApplication::sendEvent(tableVp, &moveEvent);
}
- QMouseEvent cellReleaseEvent(QEvent::MouseButtonRelease, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
+ QMouseEvent cellReleaseEvent(QEvent::MouseButtonRelease, cellPos, tableVp->mapToGlobal(cellPos),
+ Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
QCoreApplication::sendEvent(tableVp, &cellReleaseEvent);
for (int i = 0; i < 6; ++i) {
@@ -4418,16 +4443,21 @@ void tst_QTableView::task191545_dragSelectRows()
QRect cellRect = table.visualRect(model.index(3, 3));
QWidget *tableVp = table.viewport();
QPoint cellPos = cellRect.center();
- QMouseEvent cellPressEvent(QEvent::MouseButtonPress, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
+ QMouseEvent cellPressEvent(QEvent::MouseButtonPress, cellPos, tableVp->mapToGlobal(cellPos),
+ Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
QCoreApplication::sendEvent(tableVp, &cellPressEvent);
for (int i = 0; i < 6; ++i) {
+ // cellPos might have been updated by scrolling, so refresh
+ cellPos = table.visualRect(model.index(3+i, 3+i)).center();
cellPos.setX(cellPos.x() + cellRect.width());
cellPos.setY(cellPos.y() + cellRect.height());
- QMouseEvent moveEvent(QEvent::MouseMove, cellPos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
+ QMouseEvent moveEvent(QEvent::MouseMove, cellPos, tableVp->mapToGlobal(cellPos),
+ Qt::NoButton, Qt::LeftButton, Qt::ControlModifier);
QCoreApplication::sendEvent(tableVp, &moveEvent);
}
- QMouseEvent cellReleaseEvent(QEvent::MouseButtonRelease, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
+ QMouseEvent cellReleaseEvent(QEvent::MouseButtonRelease, cellPos, tableVp->mapToGlobal(cellPos),
+ Qt::LeftButton, Qt::NoButton, Qt::ControlModifier);
QCoreApplication::sendEvent(tableVp, &cellReleaseEvent);
QTest::qWait(200);
@@ -4783,6 +4813,147 @@ void tst_QTableView::deselectRow()
QVERIFY(!tw.selectionModel()->isRowSelected(1, QModelIndex()));
}
+class QTableViewSelectCells : public QTableView
+{
+public:
+ QItemSelectionModel::SelectionFlags selectionCommand(const QModelIndex &index,
+ const QEvent *) const override
+ {
+ return QTableView::selectionCommand(index, shiftPressed ? &mouseEvent : nullptr);
+ }
+ QMouseEvent mouseEvent = QMouseEvent(QEvent::MouseButtonPress, QPointF(), QPointF(),
+ Qt::LeftButton, Qt::LeftButton, Qt::ShiftModifier);
+ bool shiftPressed = false;
+};
+
+void tst_QTableView::selectRowsAndCells()
+{
+ const auto checkRows = [](const QModelIndexList &mil)
+ {
+ QCOMPARE(mil.size(), 3);
+ for (const auto &mi : mil)
+ QVERIFY(mi.row() >= 1 && mi.row() <= 3);
+ };
+ QTableViewSelectCells tw;
+ QtTestTableModel model(5, 1);
+ tw.setSelectionBehavior(QAbstractItemView::SelectRows);
+ tw.setSelectionMode(QAbstractItemView::ExtendedSelection);
+ tw.setModel(&model);
+ tw.show();
+
+ tw.selectRow(1);
+ tw.shiftPressed = true;
+ tw.selectRow(2);
+ tw.shiftPressed = false;
+ QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::ShiftModifier, tw.visualRect(model.index(3, 0)).center());
+ checkRows(tw.selectionModel()->selectedRows());
+
+ tw.clearSelection();
+ QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::NoModifier, tw.visualRect(model.index(3, 0)).center());
+ tw.shiftPressed = true;
+ tw.selectRow(1);
+ checkRows(tw.selectionModel()->selectedRows());
+}
+
+void tst_QTableView::selectColumnsAndCells()
+{
+ const auto checkColumns = [](const QModelIndexList &mil)
+ {
+ QCOMPARE(mil.size(), 3);
+ for (const auto &mi : mil)
+ QVERIFY(mi.column() >= 1 && mi.column() <= 3);
+ };
+ QTableViewSelectCells tw;
+ QtTestTableModel model(1, 5);
+ tw.setSelectionBehavior(QAbstractItemView::SelectColumns);
+ tw.setSelectionMode(QAbstractItemView::ExtendedSelection);
+ tw.setModel(&model);
+ tw.show();
+
+ tw.selectColumn(1);
+ tw.shiftPressed = true;
+ tw.selectColumn(2);
+ tw.shiftPressed = false;
+ QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::ShiftModifier, tw.visualRect(model.index(0, 3)).center());
+ checkColumns(tw.selectionModel()->selectedColumns());
+
+ tw.clearSelection();
+ QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::NoModifier, tw.visualRect(model.index(0, 3)).center());
+ tw.shiftPressed = true;
+ tw.selectColumn(1);
+ checkColumns(tw.selectionModel()->selectedColumns());
+}
+
+void tst_QTableView::selectWithHeader_data()
+{
+ QTest::addColumn<Qt::Orientation>("orientation");
+
+ QTest::addRow("horizontal") << Qt::Horizontal;
+ QTest::addRow("vertical") << Qt::Vertical;
+}
+
+void tst_QTableView::selectWithHeader()
+{
+ QFETCH(Qt::Orientation, orientation);
+
+ QTableWidget view(10, 10);
+ view.resize(200, 100);
+ view.show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ QHeaderView *header = nullptr;
+ QPoint clickPos;
+ QModelIndex lastIndex;
+
+ switch (orientation) {
+ case Qt::Horizontal:
+ header = view.horizontalHeader();
+ clickPos.rx() = header->sectionPosition(0) + header->sectionSize(0) / 2;
+ clickPos.ry() = header->height() / 2;
+ lastIndex = view.model()->index(9, 0);
+ break;
+ case Qt::Vertical:
+ header = view.verticalHeader();
+ clickPos.rx() = header->width() / 2;
+ clickPos.ry() = header->sectionPosition(0) + header->sectionSize(0) / 2;
+ lastIndex = view.model()->index(0, 9);
+ break;
+ }
+
+ const auto isSelected = [&]{
+ return orientation == Qt::Horizontal
+ ? view.selectionModel()->isColumnSelected(0)
+ : view.selectionModel()->isRowSelected(0);
+ };
+
+ QTest::mouseClick(header->viewport(), Qt::LeftButton, {}, clickPos);
+ QVERIFY(isSelected());
+ QTest::mouseClick(header->viewport(), Qt::LeftButton, Qt::ControlModifier, clickPos);
+ QVERIFY(!isSelected());
+ QTest::mouseClick(header->viewport(), Qt::LeftButton, {}, clickPos);
+ QVERIFY(isSelected());
+ view.scrollTo(lastIndex);
+ QTest::mouseClick(header->viewport(), Qt::LeftButton, Qt::ControlModifier, clickPos);
+ QVERIFY(!isSelected());
+}
+
+void tst_QTableView::resetDefaultSectionSize()
+{
+ // Create a table and change its default section size and then reset it.
+ // This should be a no op so clicking on row 1 should select row 1 and not row
+ // 0 as previously. QTBUG-116013
+ QTableWidget view(10, 10);
+ view.resize(300, 300);
+ view.verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
+ view.verticalHeader()->setDefaultSectionSize(120);
+ view.verticalHeader()->resetDefaultSectionSize();
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ QEXPECT_FAIL("", "Reverted fix for QTBUG-116013 due to QTBUG-122109", Continue);
+ QCOMPARE(view.verticalHeader()->logicalIndexAt(9, 45), 1);
+}
+
// This has nothing to do with QTableView, but it's convenient to reuse the QtTestTableModel
#if QT_CONFIG(textmarkdownwriter)
@@ -4811,5 +4982,18 @@ void tst_QTableView::markdownWriter()
}
#endif
+void tst_QTableView::rowsInVerticalHeader()
+{
+ QtTestTableModel model(0, 2);
+ QTableView view;
+ view.setModel(&model);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ auto *verticalHeader = view.verticalHeader();
+ QCOMPARE(verticalHeader->count(), 0);
+ model.insertRows(2);
+ QCOMPARE(verticalHeader->count(), 2);
+}
+
QTEST_MAIN(tst_QTableView)
#include "tst_qtableview.moc"
diff --git a/tests/auto/widgets/itemviews/qtablewidget/CMakeLists.txt b/tests/auto/widgets/itemviews/qtablewidget/CMakeLists.txt
index 5409741dd9..306ba4bdff 100644
--- a/tests/auto/widgets/itemviews/qtablewidget/CMakeLists.txt
+++ b/tests/auto/widgets/itemviews/qtablewidget/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qtablewidget.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qtablewidget Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtablewidget LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtablewidget
SOURCES
tst_qtablewidget.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp
index 6ee923662e..34972bc3e8 100644
--- a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp
+++ b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp
@@ -1,34 +1,10 @@
-/****************************************************************************
-**
-** 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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QHeaderView>
#include <QLineEdit>
#include <QMimeData>
+#include <QScrollBar>
#include <QSignalSpy>
#include <QTableWidget>
#include <QTest>
@@ -49,6 +25,7 @@ private slots:
void initTestCase();
void init();
void getSetCheck();
+ void selectionRange();
void clear();
void clearContents();
void rowCount();
@@ -60,6 +37,8 @@ private slots:
void takeItem();
void selectedItems_data();
void selectedItems();
+ void selectedSpannedCells_data();
+ void selectedSpannedCells();
void removeRow_data();
void removeRow();
void removeColumn_data();
@@ -85,12 +64,15 @@ private slots:
void task219380_removeLastRow();
void task262056_sortDuplicate();
void itemWithHeaderItems();
+ void checkHeaderItemFlagsConflict();
void mimeData();
void selectedRowAfterSorting();
void search();
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
void clearItemData();
#endif
+ void createPersistentOnLayoutAboutToBeChanged();
+ void createPersistentOnLayoutAboutToBeChangedAutoSort();
private:
std::unique_ptr<QTableWidget> testWidget;
@@ -153,6 +135,19 @@ void tst_QTableWidget::getSetCheck()
QCOMPARE(obj1.itemPrototype(), nullptr);
}
+void tst_QTableWidget::selectionRange()
+{
+ QTableWidgetSelectionRange defaultSelection;
+ QTableWidgetSelectionRange selection(1, 2, 3, 4);
+
+ QTableWidgetSelectionRange copy(selection);
+ QCOMPARE(copy, selection);
+ QVERIFY(copy != defaultSelection);
+
+ defaultSelection = copy;
+ QCOMPARE(defaultSelection, copy);
+}
+
void tst_QTableWidget::initTestCase()
{
testWidget.reset(new QTableWidget);
@@ -199,8 +194,8 @@ void tst_QTableWidget::clear()
QVERIFY(bla.isNull());
QVERIFY(!testWidget->item(0,0));
- QVERIFY(!testWidget->selectedRanges().count());
- QVERIFY(!testWidget->selectedItems().count());
+ QVERIFY(!testWidget->selectedRanges().size());
+ QVERIFY(!testWidget->selectedItems().size());
}
void tst_QTableWidget::rowCount()
@@ -367,7 +362,7 @@ void tst_QTableWidget::takeItem()
QCOMPARE(item->text(), QString::number(row * column + column));
delete item;
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
const QList<QVariant> arguments = spy.takeFirst();
QCOMPARE(arguments.size(), 2);
QCOMPARE(arguments.at(0).toInt(), row);
@@ -532,24 +527,24 @@ void tst_QTableWidget::selectedItems()
testWidget->setColumnHidden(column, true);
// make sure we don't have any previous selections hanging around
- QVERIFY(!testWidget->selectedRanges().count());
- QVERIFY(!testWidget->selectedItems().count());
+ QVERIFY(!testWidget->selectedRanges().size());
+ QVERIFY(!testWidget->selectedItems().size());
// select range and check that it is set correctly
testWidget->setRangeSelected(selectionRange, true);
if (selectionRange.topRow() >= 0) {
- QCOMPARE(testWidget->selectedRanges().count(), 1);
+ QCOMPARE(testWidget->selectedRanges().size(), 1);
QCOMPARE(testWidget->selectedRanges().at(0).topRow(), selectionRange.topRow());
QCOMPARE(testWidget->selectedRanges().at(0).bottomRow(), selectionRange.bottomRow());
QCOMPARE(testWidget->selectedRanges().at(0).leftColumn(), selectionRange.leftColumn());
QCOMPARE(testWidget->selectedRanges().at(0).rightColumn(), selectionRange.rightColumn());
} else {
- QCOMPARE(testWidget->selectedRanges().count(), 0);
+ QCOMPARE(testWidget->selectedRanges().size(), 0);
}
// check that the correct number of items and the expected items are there
const QList<QTableWidgetItem *> selectedItems = testWidget->selectedItems();
- QCOMPARE(selectedItems.count(), expectedItems.count());
+ QCOMPARE(selectedItems.size(), expectedItems.size());
for (const auto &intPair : expectedItems)
QVERIFY(selectedItems.contains(testWidget->item(intPair.first, intPair.second)));
@@ -569,6 +564,75 @@ void tst_QTableWidget::selectedItems()
}
}
+void tst_QTableWidget::selectedSpannedCells_data()
+{
+ QTest::addColumn<QRect>("spannedCells"); // in cells, not pixels
+ QTest::addColumn<QPoint>("selectionStartCell");
+ QTest::addColumn<QPoint>("selectionEndCell");
+ QTest::addColumn<int>("expectedSelectionRangeCount");
+ QTest::addColumn<QTableWidgetSelectionRange>("expectedFirstSelectionRange");
+
+ QTest::newRow("merge 2 cells in column, select adjacent left")
+ << QRect(1, 2, 1, 2) << QPoint(0, 1) << QPoint(0, 3)
+ << 1 << QTableWidgetSelectionRange(1, 0, 3, 0);
+
+ QTest::newRow("merge 2 cells in column, select those and one more")
+ << QRect(1, 2, 1, 2) << QPoint(1, 1) << QPoint(1, 3)
+ << 3 << QTableWidgetSelectionRange(1, 1, 1, 1);
+
+ QTest::newRow("merge 2 cells in column, select rows above")
+ << QRect(1, 2, 1, 2) << QPoint(0, 0) << QPoint(3, 1)
+ << 1 << QTableWidgetSelectionRange(0, 0, 1, 3);
+
+ QTest::newRow("merge 4 cells in column, select adjacent right")
+ << QRect(1, 0, 1, 4) << QPoint(2, 0) << QPoint(3, 3)
+ << 1 << QTableWidgetSelectionRange(0, 2, 3, 3);
+
+ QTest::newRow("merge 3 cells in row, select those and one more")
+ << QRect(0, 1, 3, 1) << QPoint(0, 1) << QPoint(3, 1)
+ << 4 << QTableWidgetSelectionRange(1, 0, 1, 0);
+
+ QTest::newRow("merge 3 cells in row, select adjacent to right")
+ << QRect(0, 1, 3, 1) << QPoint(3, 0) << QPoint(3, 2)
+ << 1 << QTableWidgetSelectionRange(0, 3, 2, 3);
+
+ QTest::newRow("merge 3 cells in row, select adjacent above")
+ << QRect(0, 2, 3, 2) << QPoint(0, 1) << QPoint(2, 1)
+ << 1 << QTableWidgetSelectionRange(1, 0, 1, 2);
+}
+
+void tst_QTableWidget::selectedSpannedCells() // QTBUG-255
+{
+ QFETCH(QRect, spannedCells);
+ QFETCH(QPoint, selectionStartCell);
+ QFETCH(QPoint, selectionEndCell);
+ QFETCH(int, expectedSelectionRangeCount);
+ QFETCH(const QTableWidgetSelectionRange, expectedFirstSelectionRange);
+
+ QTableWidget testWidget(4, 4);
+ testWidget.resize(600, 200);
+ testWidget.show();
+
+ // create and set items
+ for (int c = 0; c < 4; ++c) {
+ for (int r = 0; r < 4; ++r)
+ testWidget.setItem(r, c, new QTableWidgetItem(QString("Item %1 %2").arg(c).arg(r)));
+ }
+
+ // merge some cells
+ testWidget.setSpan(spannedCells.top(), spannedCells.left(), spannedCells.height(), spannedCells.width());
+
+ // click one cell and shift-click another, to select a range
+ QTest::mouseClick(testWidget.viewport(), Qt::LeftButton, Qt::NoModifier,
+ testWidget.visualRect(testWidget.model()->index(selectionStartCell.y(), selectionStartCell.x())).center());
+ QTest::mouseClick(testWidget.viewport(), Qt::LeftButton, Qt::ShiftModifier,
+ testWidget.visualRect(testWidget.model()->index(selectionEndCell.y(), selectionEndCell.x())).center());
+
+ auto ranges = testWidget.selectedRanges();
+ QCOMPARE(ranges.size(), expectedSelectionRangeCount);
+ QCOMPARE(ranges.first(), expectedFirstSelectionRange);
+}
+
void tst_QTableWidget::removeRow_data()
{
QTest::addColumn<int>("rowCount");
@@ -1132,15 +1196,15 @@ void tst_QTableWidget::sortItems()
persistent << model->index(r, sortColumn, QModelIndex());
}
- for (int h = 0; h < initialHidden.count(); ++h)
+ for (int h = 0; h < initialHidden.size(); ++h)
testWidget->hideRow(initialHidden.at(h));
- QCOMPARE(testWidget->verticalHeader()->hiddenSectionCount(), initialHidden.count());
+ QCOMPARE(testWidget->verticalHeader()->hiddenSectionCount(), initialHidden.size());
testWidget->sortItems(sortColumn, sortOrder);
int te = 0;
- for (int i = 0; i < rows.count(); ++i) {
+ for (int i = 0; i < rows.size(); ++i) {
for (int j = 0; j < columnCount; ++j) {
QString value;
QTableWidgetItem *itm = testWidget->item(i, j);
@@ -1154,7 +1218,7 @@ void tst_QTableWidget::sortItems()
// << "expected" << rows.at(i);
}
- for (int k = 0; k < expectedHidden.count(); ++k)
+ for (int k = 0; k < expectedHidden.size(); ++k)
QVERIFY(testWidget->isRowHidden(expectedHidden.at(k)));
}
@@ -1335,18 +1399,18 @@ void tst_QTableWidget::setItemWithSorting()
}
}
- for (int k = 0; k < persistent.count(); ++k) {
+ for (int k = 0; k < persistent.size(); ++k) {
QCOMPARE(persistent.at(k).row(), expectedRows.at(k));
int i = (persistent.at(k).row() * columnCount) + sortColumn;
QCOMPARE(persistent.at(k).data().toString(), expectedValues.at(i));
}
if (i == 0)
- QCOMPARE(dataChangedSpy.count(), reorderingExpected ? 0 : 1);
+ QCOMPARE(dataChangedSpy.size(), reorderingExpected ? 0 : 1);
else
- QCOMPARE(dataChangedSpy.count(), 1);
+ QCOMPARE(dataChangedSpy.size(), 1);
- QCOMPARE(layoutChangedSpy.count(), reorderingExpected ? 1 : 0);
+ QCOMPARE(layoutChangedSpy.size(), reorderingExpected ? 1 : 0);
}
}
@@ -1382,7 +1446,7 @@ void tst_QTableWidget::itemData()
QCOMPARE(widget.currentRoles, QList<int> { Qt::UserRole + i });
}
QMap<int, QVariant> flags = widget.model()->itemData(widget.model()->index(0, 0));
- QCOMPARE(flags.count(), 6);
+ QCOMPARE(flags.size(), 6);
for (int i = 0; i < 4; ++i)
QCOMPARE(flags[Qt::UserRole + i].toString(), QString::number(i + 1));
}
@@ -1395,7 +1459,7 @@ void tst_QTableWidget::setItemData()
QTableWidgetItem *item = new QTableWidgetItem;
table.setItem(0, 0, item);
- QCOMPARE(dataChangedSpy.count(), 1);
+ QCOMPARE(dataChangedSpy.size(), 1);
QModelIndex idx = qvariant_cast<QModelIndex>(dataChangedSpy.takeFirst().at(0));
QMap<int, QVariant> data;
@@ -1407,7 +1471,7 @@ void tst_QTableWidget::setItemData()
QCOMPARE(table.model()->data(idx, Qt::DisplayRole).toString(), QLatin1String("Display"));
QCOMPARE(table.model()->data(idx, Qt::EditRole).toString(), QLatin1String("Display"));
QCOMPARE(table.model()->data(idx, Qt::ToolTipRole).toString(), QLatin1String("ToolTip"));
- QCOMPARE(dataChangedSpy.count(), 1);
+ QCOMPARE(dataChangedSpy.size(), 1);
QCOMPARE(idx, qvariant_cast<QModelIndex>(dataChangedSpy.first().at(0)));
QCOMPARE(idx, qvariant_cast<QModelIndex>(dataChangedSpy.first().at(1)));
const auto roles = qvariant_cast<QList<int>>(dataChangedSpy.first().at(2));
@@ -1418,13 +1482,13 @@ void tst_QTableWidget::setItemData()
dataChangedSpy.clear();
table.model()->setItemData(idx, data);
- QCOMPARE(dataChangedSpy.count(), 0);
+ QCOMPARE(dataChangedSpy.size(), 0);
data.clear();
data.insert(Qt::DisplayRole, QLatin1String("dizplaye"));
table.model()->setItemData(idx, data);
QCOMPARE(table.model()->data(idx, Qt::DisplayRole).toString(), QLatin1String("dizplaye"));
- QCOMPARE(dataChangedSpy.count(), 1);
+ QCOMPARE(dataChangedSpy.size(), 1);
QCOMPARE(QList<int>({ Qt::DisplayRole, Qt::EditRole }),
qvariant_cast<QList<int>>(dataChangedSpy.first().at(2)));
@@ -1493,6 +1557,12 @@ void tst_QTableWidget::sizeHint()
QFETCH(Qt::ScrollBarPolicy, scrollBarPolicy);
QFETCH(QSize, viewSize);
+ const QString defaultStyle = QApplication::style()->name();
+ QApplication::setStyle("windows");
+ const auto resetStyle = qScopeGuard([defaultStyle]{
+ QApplication::setStyle(defaultStyle);
+ });
+
QTableWidget view(2, 2);
view.setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
view.setVerticalScrollBarPolicy(scrollBarPolicy);
@@ -1512,18 +1582,21 @@ void tst_QTableWidget::sizeHint()
QTRY_COMPARE(view.size(), viewSize);
}
+ QApplication::processEvents(); // execute delayed layouts
auto sizeHint = view.sizeHint();
view.hide();
QCOMPARE(view.sizeHint(), sizeHint);
view.horizontalHeader()->hide();
view.show();
+ QApplication::processEvents(); // execute delayed layouts
sizeHint = view.sizeHint();
view.hide();
QCOMPARE(view.sizeHint(), sizeHint);
view.verticalHeader()->hide();
view.show();
+ QApplication::processEvents(); // execute delayed layouts
sizeHint = view.sizeHint();
view.hide();
QCOMPARE(view.sizeHint(), sizeHint);
@@ -1587,7 +1660,7 @@ void tst_QTableWidget::task262056_sortDuplicate()
QSignalSpy layoutChangedSpy(testWidget->model(), &QAbstractItemModel::layoutChanged);
testWidget->item(3,0)->setBackground(Qt::red);
- QCOMPARE(layoutChangedSpy.count(),0);
+ QCOMPARE(layoutChangedSpy.size(),0);
}
@@ -1607,6 +1680,25 @@ void tst_QTableWidget::itemWithHeaderItems()
QCOMPARE(table.item(0, 1), nullptr);
}
+void tst_QTableWidget::checkHeaderItemFlagsConflict()
+{
+ // QTBUG-113209
+ // Check that setting header item doesn't set Qt::ItemNeverHasChildren
+ // Chech that header items do not emit itemChanged.
+ QTableWidget table(1, 1);
+ QSignalSpy itemChangeSpy(&table, &QTableWidget::itemChanged);
+ QVERIFY(itemChangeSpy.isValid());
+
+ QTableWidgetItem *item = new QTableWidgetItem("Initial");
+ table.setHorizontalHeaderItem(0, item);
+
+ QVERIFY(!(item->flags() & Qt::ItemNeverHasChildren));
+
+ item->setData(Qt::DisplayRole, "updated");
+
+ QCOMPARE(itemChangeSpy.size(), 0);
+}
+
class TestTableWidget : public QTableWidget
{
Q_OBJECT
@@ -1684,7 +1776,7 @@ void tst_QTableWidget::selectedRowAfterSorting()
table.setProperty("sortingEnabled",true);
table.selectRow(1);
table.item(1,1)->setText("9");
- QCOMPARE(table.selectedItems().count(),3);
+ QCOMPARE(table.selectedItems().size(),3);
const auto selectedItems = table.selectedItems();
for (QTableWidgetItem *item : selectedItems)
QCOMPARE(item->row(), 0);
@@ -1756,5 +1848,74 @@ void tst_QTableWidget::clearItemData()
}
#endif
+void tst_QTableWidget::createPersistentOnLayoutAboutToBeChanged() // QTBUG-93466
+{
+ QTableWidget widget;
+ widget.model()->insertColumn(0);
+ QCOMPARE(widget.model()->columnCount(), 1);
+ widget.model()->insertRows(0, 3);
+ for (int row = 0; row < 3; ++row)
+ widget.model()->setData(widget.model()->index(row, 0), row);
+ QList<QPersistentModelIndex> idxList;
+ QSignalSpy layoutAboutToBeChangedSpy(widget.model(), &QAbstractItemModel::layoutAboutToBeChanged);
+ QSignalSpy layoutChangedSpy(widget.model(), &QAbstractItemModel::layoutChanged);
+ connect(widget.model(), &QAbstractItemModel::layoutAboutToBeChanged, this, [&idxList, &widget](){
+ idxList.clear();
+ for (int row = 0; row < 3; ++row)
+ idxList << QPersistentModelIndex(widget.model()->index(row, 0));
+ });
+ connect(widget.model(), &QAbstractItemModel::layoutChanged, this, [&idxList](){
+ QCOMPARE(idxList.size(), 3);
+ QCOMPARE(idxList.at(0).row(), 1);
+ QCOMPARE(idxList.at(0).column(), 0);
+ QCOMPARE(idxList.at(0).data().toInt(), 0);
+ QCOMPARE(idxList.at(1).row(), 0);
+ QCOMPARE(idxList.at(1).column(), 0);
+ QCOMPARE(idxList.at(1).data().toInt(), -1);
+ QCOMPARE(idxList.at(2).row(), 2);
+ QCOMPARE(idxList.at(2).column(), 0);
+ QCOMPARE(idxList.at(2).data().toInt(), 2);
+ });
+ widget.model()->setData(widget.model()->index(1, 0), -1);
+ widget.model()->sort(0);
+ QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), 1);
+}
+
+void tst_QTableWidget::createPersistentOnLayoutAboutToBeChangedAutoSort() // QTBUG-93466
+{
+ QTableWidget widget;
+ widget.model()->insertColumn(0);
+ QCOMPARE(widget.model()->columnCount(), 1);
+ widget.model()->insertRows(0, 3);
+ for (int row = 0; row < 3; ++row)
+ widget.model()->setData(widget.model()->index(row, 0), row);
+ widget.sortByColumn(0, Qt::AscendingOrder);
+ widget.setSortingEnabled(true);
+ QList<QPersistentModelIndex> idxList;
+ QSignalSpy layoutAboutToBeChangedSpy(widget.model(), &QAbstractItemModel::layoutAboutToBeChanged);
+ QSignalSpy layoutChangedSpy(widget.model(), &QAbstractItemModel::layoutChanged);
+ connect(widget.model(), &QAbstractItemModel::layoutAboutToBeChanged, this, [&idxList, &widget](){
+ idxList.clear();
+ for (int row = 0; row < 3; ++row)
+ idxList << QPersistentModelIndex(widget.model()->index(row, 0));
+ });
+ connect(widget.model(), &QAbstractItemModel::layoutChanged, this, [&idxList](){
+ QCOMPARE(idxList.size(), 3);
+ QCOMPARE(idxList.at(0).row(), 1);
+ QCOMPARE(idxList.at(0).column(), 0);
+ QCOMPARE(idxList.at(0).data().toInt(), 0);
+ QCOMPARE(idxList.at(1).row(), 0);
+ QCOMPARE(idxList.at(1).column(), 0);
+ QCOMPARE(idxList.at(1).data().toInt(), -1);
+ QCOMPARE(idxList.at(2).row(), 2);
+ QCOMPARE(idxList.at(2).column(), 0);
+ QCOMPARE(idxList.at(2).data().toInt(), 2);
+ });
+ widget.model()->setData(widget.model()->index(1, 0), -1);
+ QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), 1);
+}
+
QTEST_MAIN(tst_QTableWidget)
#include "tst_qtablewidget.moc"
diff --git a/tests/auto/widgets/itemviews/qtreeview/BLACKLIST b/tests/auto/widgets/itemviews/qtreeview/BLACKLIST
deleted file mode 100644
index 3aaf1e4e64..0000000000
--- a/tests/auto/widgets/itemviews/qtreeview/BLACKLIST
+++ /dev/null
@@ -1,5 +0,0 @@
-# QTBUG-87408
-[horizontalScrollMode]
-android
-[setSelection]
-android
diff --git a/tests/auto/widgets/itemviews/qtreeview/CMakeLists.txt b/tests/auto/widgets/itemviews/qtreeview/CMakeLists.txt
index 57267e1694..deccd71f59 100644
--- a/tests/auto/widgets/itemviews/qtreeview/CMakeLists.txt
+++ b/tests/auto/widgets/itemviews/qtreeview/CMakeLists.txt
@@ -1,14 +1,21 @@
-# Generated from qtreeview.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qtreeview Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtreeview LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtreeview
SOURCES
../../../../shared/fakedirmodel.h
tst_qtreeview.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
index 579c2d234f..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)
@@ -890,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);
@@ -1263,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));
@@ -1304,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);
@@ -1359,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);
@@ -1542,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");
@@ -1556,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);
}
}
@@ -1597,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);
@@ -1656,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);
@@ -1665,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);
@@ -1678,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();
@@ -1690,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();
@@ -1753,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);
@@ -1780,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);
@@ -1878,7 +1854,7 @@ void tst_QTreeView::keyboardNavigation()
}
break;
default:
- QVERIFY(false);
+ QFAIL(qPrintable(QStringLiteral("Unexpected key: %1").arg(key)));
}
QCOMPARE(view.currentIndex().row(), row);
@@ -1949,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
@@ -2050,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;
@@ -2068,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())));
}
@@ -2172,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);
}
}
@@ -2253,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);
}
@@ -2565,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)));
@@ -2599,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()));
@@ -2615,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()
@@ -2655,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()
@@ -2895,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));
@@ -2937,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()) {
@@ -2949,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);
@@ -2968,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
{
@@ -3559,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()
@@ -3728,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());
@@ -4065,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()
@@ -4104,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());
@@ -4114,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));
@@ -4125,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()
@@ -4206,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());
@@ -4792,7 +4764,6 @@ void tst_QTreeView::statusTip()
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)));
@@ -4843,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);
@@ -4920,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);
@@ -5142,7 +5119,7 @@ void tst_QTreeView::fetchUntilScreenFull()
TreeItem* parentItem = parent.isValid() ? static_cast<TreeItem*>(parent.internalPointer())
: m_root;
- return parentItem->children.count();
+ return parentItem->children.size();
}
int columnCount(const QModelIndex&) const override { return 2; }
@@ -5221,6 +5198,10 @@ void tst_QTreeView::fetchUntilScreenFull()
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);
diff --git a/tests/auto/widgets/itemviews/qtreewidget/CMakeLists.txt b/tests/auto/widgets/itemviews/qtreewidget/CMakeLists.txt
index 8a9dba604e..251dbb9b79 100644
--- a/tests/auto/widgets/itemviews/qtreewidget/CMakeLists.txt
+++ b/tests/auto/widgets/itemviews/qtreewidget/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qtreewidget.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qtreewidget Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtreewidget LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtreewidget
SOURCES
tst_qtreewidget.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
index 2a02afb36b..f4423831ca 100644
--- a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
+++ b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
@@ -1,35 +1,11 @@
-/****************************************************************************
-**
-** 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 <QApplication>
#include <QHeaderView>
#include <QLineEdit>
+#include <QScopeGuard>
#include <QScrollBar>
#include <QSignalSpy>
#include <QStyledItemDelegate>
@@ -151,6 +127,9 @@ private slots:
void getMimeDataWithInvalidItem();
void testVisualItemRect();
void reparentHiddenItem();
+ void persistentChildIndex();
+ void createPersistentOnLayoutAboutToBeChanged();
+ void createPersistentOnLayoutAboutToBeChangedAutoSort();
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
void clearItemData();
#endif
@@ -302,8 +281,8 @@ void tst_QTreeWidget::addTopLevelItem()
while (!tops.isEmpty()) {
TreeItem *ti = tops.takeFirst();
delete ti;
- QCOMPARE(tree.topLevelItemCount(), tops.count());
- for (int i = 0; i < tops.count(); ++i)
+ QCOMPARE(tree.topLevelItemCount(), tops.size());
+ for (int i = 0; i < tops.size(); ++i)
QCOMPARE(tree.topLevelItem(i), tops.at(i));
}
@@ -344,6 +323,7 @@ void tst_QTreeWidget::addTopLevelItem()
// invalid insert
{
tops.clear();
+ const auto sg = qScopeGuard([&] { qDeleteAll(std::exchange(tops, {})); });
for (int i = 0; i < 10; ++i)
tops << new TreeItem();
int count = tree.topLevelItemCount();
@@ -398,12 +378,12 @@ void tst_QTreeWidget::currentItem()
tree.setCurrentItem(item);
QCOMPARE(tree.currentItem(), item);
- QCOMPARE(currentItemChangedSpy.count(), 1);
+ QCOMPARE(currentItemChangedSpy.size(), 1);
QVariantList args = currentItemChangedSpy.takeFirst();
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(1)), previous);
- QCOMPARE(itemSelectionChangedSpy.count(), 1);
+ QCOMPARE(itemSelectionChangedSpy.size(), 1);
itemSelectionChangedSpy.clear();
previous = item;
@@ -416,15 +396,15 @@ void tst_QTreeWidget::currentItem()
if (!currentItemChangedSpy.isEmpty()) {
// ### we get a currentItemChanged() when what really
// changed was just currentColumn(). Should it be like this?
- QCOMPARE(currentItemChangedSpy.count(), 1);
+ QCOMPARE(currentItemChangedSpy.size(), 1);
QVariantList args = currentItemChangedSpy.takeFirst();
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(1)), item);
if (tree.selectionBehavior() == QAbstractItemView::SelectItems) {
- QCOMPARE(itemSelectionChangedSpy.count(), 1);
+ QCOMPARE(itemSelectionChangedSpy.size(), 1);
itemSelectionChangedSpy.clear();
} else {
- QCOMPARE(itemSelectionChangedSpy.count(), 0);
+ QCOMPARE(itemSelectionChangedSpy.size(), 0);
}
}
}
@@ -484,7 +464,7 @@ void tst_QTreeWidget::editItem()
QTest::keyClick(editor, Qt::Key_A);
QTest::keyClick(editor, Qt::Key_Enter);
QCoreApplication::processEvents();
- QCOMPARE(itemChangedSpy.count(), 1);
+ QCOMPARE(itemChangedSpy.size(), 1);
QVariantList args = itemChangedSpy.takeFirst();
QCOMPARE(qvariant_cast<QTreeWidgetItem *>(args.at(0)), item);
QCOMPARE(qvariant_cast<int>(args.at(1)), col);
@@ -640,7 +620,7 @@ void tst_QTreeWidget::setItemHidden2()
{
// From Task 78587
const QStringList hl({"ID", "Desc"});
- testWidget->setColumnCount(hl.count());
+ testWidget->setColumnCount(hl.size());
testWidget->setHeaderLabels(hl);
testWidget->setSortingEnabled(true);
@@ -841,7 +821,7 @@ void tst_QTreeWidget::selectedItems()
// check selectedItems
const auto sel = testWidget->selectedItems();
- QCOMPARE(sel.count(), expectedItems.count());
+ QCOMPARE(sel.size(), expectedItems.size());
for (const auto &itemPath : expectedItems) {
QTreeWidgetItem *item = nullptr;
for (int index : itemPath) {
@@ -877,7 +857,7 @@ void tst_QTreeWidget::selectedItems()
}
item->setSelected(false);
}
- QCOMPARE(testWidget->selectedItems().count(), 0);
+ QCOMPARE(testWidget->selectedItems().size(), 0);
}
void tst_QTreeWidget::itemAssignment()
@@ -1110,9 +1090,9 @@ void tst_QTreeWidget::findItems()
QList<QTreeWidgetItem*> result = testWidget->findItems(pattern,
Qt::MatchExactly|Qt::MatchRecursive);
- QCOMPARE(result.count(), resultCount);
+ QCOMPARE(result.size(), resultCount);
- for (int k = 0; k < result.count() && k < resultText.count(); ++k)
+ for (int k = 0; k < result.size() && k < resultText.size(); ++k)
QCOMPARE(result.at(k)->text(column), resultText.at(k));
}
@@ -1130,7 +1110,7 @@ void tst_QTreeWidget::findItemsInColumn()
// Recursively search column one for 400.
QList<QTreeWidgetItem*> items = testWidget->findItems("400", Qt::MatchExactly|Qt::MatchRecursive, 1);
- QCOMPARE(items.count(), 1);
+ QCOMPARE(items.size(), 1);
}
void tst_QTreeWidget::sortItems_data()
@@ -1197,16 +1177,16 @@ void tst_QTreeWidget::sortItems()
testWidget->sortItems(column, order);
QCOMPARE(testWidget->sortColumn(), column);
- for (int k = 0; k < topLevelResult.count(); ++k) {
+ for (int k = 0; k < topLevelResult.size(); ++k) {
QTreeWidgetItem *item = testWidget->topLevelItem(k);
QCOMPARE(item->text(column), topLevelResult.at(k));
- for (int l = 0; l < childResult.count(); ++l)
+ for (int l = 0; l < childResult.size(); ++l)
QCOMPARE(item->child(l)->text(column), childResult.at(l));
}
- for (int m = 0; m < tops.count(); ++m)
+ for (int m = 0; m < tops.size(); ++m)
QCOMPARE(tops.at(m).row(), expectedTopRows.at(m));
- for (int n = 0; n < children.count(); ++n)
+ for (int n = 0; n < children.size(); ++n)
QCOMPARE(children.at(n).row(), expectedChildRows.at(n));
}
@@ -1366,17 +1346,17 @@ void tst_QTreeWidget::insertTopLevelItems_data()
const QStringList insert{ "baz" };
QTest::newRow("Insert at count") << initial << insert
- << initial.count() << initial.count()
- << initial.count() << initial.count();
+ << initial.size() << initial.size()
+ << initial.size() << initial.size();
QTest::newRow("Insert in the middle") << initial << insert
- << (initial.count() / 2) << (initial.count() / 2)
- << (initial.count() / 2) << (initial.count() / 2);
+ << (initial.size() / 2) << (initial.size() / 2)
+ << (initial.size() / 2) << (initial.size() / 2);
QTest::newRow("Insert less than 0") << initial << insert
<< -1 << -1
<< -1 << -1;
QTest::newRow("Insert beyond count") << initial << insert
- << initial.count() + 1 << -1
- << initial.count() + 1 << -1;
+ << initial.size() + 1 << -1
+ << initial.size() + 1 << -1;
}
void tst_QTreeWidget::insertTopLevelItems()
@@ -1391,26 +1371,26 @@ void tst_QTreeWidget::insertTopLevelItems()
{ // insert the initial items
QCOMPARE(testWidget->topLevelItemCount(), 0);
- for (int i = 0; i < initialText.count(); ++i) {
+ for (int i = 0; i < initialText.size(); ++i) {
QTreeWidgetItem *top = new QTreeWidgetItem(QStringList(initialText.at(i)));
testWidget->addTopLevelItem(top);
QCOMPARE(testWidget->indexOfTopLevelItem(top), i);
}
- QCOMPARE(testWidget->topLevelItemCount(), initialText.count());
+ QCOMPARE(testWidget->topLevelItemCount(), initialText.size());
}
{ // test adding children
QTreeWidgetItem *topLevel = testWidget->topLevelItem(0);
- for (int i = 0; i < initialText.count(); ++i)
+ for (int i = 0; i < initialText.size(); ++i)
topLevel->addChild(new QTreeWidgetItem(QStringList(initialText.at(i))));
- QCOMPARE(topLevel->childCount(), initialText.count());
+ QCOMPARE(topLevel->childCount(), initialText.size());
}
{ // test adding more top level items
QTreeWidgetItem *topsy = new QTreeWidgetItem(QStringList(insertText.at(0)));
testWidget->insertTopLevelItem(insertTopLevelIndex, topsy);
if (expectedTopLevelIndex == -1) {
- QCOMPARE(testWidget->topLevelItemCount(), initialText.count());
+ QCOMPARE(testWidget->topLevelItemCount(), initialText.size());
delete topsy;
} else {
QTreeWidgetItem *item = testWidget->topLevelItem(expectedTopLevelIndex);
@@ -1426,7 +1406,7 @@ void tst_QTreeWidget::insertTopLevelItems()
QTreeWidgetItem *child = new QTreeWidgetItem(QStringList(insertText.at(0)));
topLevel->insertChild(insertChildIndex, child);
if (expectedChildIndex == -1) {
- QCOMPARE(topLevel->childCount(), initialText.count());
+ QCOMPARE(topLevel->childCount(), initialText.size());
delete child;
} else {
QTreeWidgetItem *item = topLevel->child(expectedChildIndex);
@@ -1524,7 +1504,7 @@ void tst_QTreeWidget::keyboardNavigation()
if (testWidget->currentItem() != item) {
QCOMPARE(testWidget->currentItem(), item->parent());
item = testWidget->currentItem();
- row = item->parent() ? item->parent()->indexOfChild(item) : testWidget->indexOfTopLevelItem(item);;
+ row = item->parent() ? item->parent()->indexOfChild(item) : testWidget->indexOfTopLevelItem(item);
}
break;
case Qt::Key_Right:
@@ -1539,7 +1519,7 @@ void tst_QTreeWidget::keyboardNavigation()
}
break;
default:
- QVERIFY(false);
+ QFAIL(qPrintable(QStringLiteral("Unexpected key: %1").arg(key)));
}
QTreeWidgetItem *current = testWidget->currentItem();
@@ -1612,7 +1592,7 @@ void tst_QTreeWidget::scrollToItem()
void tst_QTreeWidget::setSortingEnabled()
{
const QStringList hl{ "ID" };
- testWidget->setColumnCount(hl.count());
+ testWidget->setColumnCount(hl.size());
testWidget->setHeaderLabels(hl);
QTreeWidgetItem *item1 = new QTreeWidgetItem(testWidget);
@@ -1681,7 +1661,7 @@ void tst_QTreeWidget::addChild()
QList<QTreeWidgetItem*> taken = item->takeChildren();
QCOMPARE(taken, children);
QCOMPARE(item->childCount(), 0);
- for (int i = 0; i < taken.count(); ++i) {
+ for (int i = 0; i < taken.size(); ++i) {
QCOMPARE(taken.at(i)->parent(), nullptr);
QCOMPARE(taken.at(i)->treeWidget(), nullptr);
item->addChild(taken.at(i)); // re-add
@@ -1691,8 +1671,8 @@ void tst_QTreeWidget::addChild()
while (!children.isEmpty()) {
QTreeWidgetItem *ti = children.takeFirst();
delete ti;
- QCOMPARE(item->childCount(), children.count());
- for (int i = 0; i < children.count(); ++i)
+ QCOMPARE(item->childCount(), children.size());
+ for (int i = 0; i < children.size(); ++i)
QCOMPARE(item->child(i), children.at(i));
}
@@ -1739,9 +1719,9 @@ void tst_QTreeWidget::setData()
QSignalSpy itemChangedSpy(
testWidget, &QTreeWidget::itemChanged);
headerItem->setText(0, "test");
- QCOMPARE(dataChangedSpy.count(), 0);
- QCOMPARE(headerDataChangedSpy.count(), 1);
- QCOMPARE(itemChangedSpy.count(), 0); // no itemChanged() signal for header item
+ QCOMPARE(dataChangedSpy.size(), 0);
+ QCOMPARE(headerDataChangedSpy.size(), 1);
+ QCOMPARE(itemChangedSpy.size(), 0); // no itemChanged() signal for header item
headerItem->setData(-1, -1, QVariant());
}
@@ -1759,24 +1739,24 @@ void tst_QTreeWidget::setData()
const QString text = QLatin1String("text ") + iS;
item->setText(j, text);
QCOMPARE(item->text(j), text);
- QCOMPARE(itemChangedSpy.count(), 1);
+ QCOMPARE(itemChangedSpy.size(), 1);
args = itemChangedSpy.takeFirst();
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
QCOMPARE(qvariant_cast<int>(args.at(1)), j);
item->setText(j, text);
- QCOMPARE(itemChangedSpy.count(), 0);
+ QCOMPARE(itemChangedSpy.size(), 0);
QPixmap pixmap(32, 32);
pixmap.fill((i == 1) ? Qt::red : Qt::green);
QIcon icon(pixmap);
item->setIcon(j, icon);
QCOMPARE(item->icon(j), icon);
- QCOMPARE(itemChangedSpy.count(), 1);
+ QCOMPARE(itemChangedSpy.size(), 1);
args = itemChangedSpy.takeFirst();
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
QCOMPARE(qvariant_cast<int>(args.at(1)), j);
item->setIcon(j, icon);
- QCOMPARE(itemChangedSpy.count(), 1);
+ QCOMPARE(itemChangedSpy.size(), 1);
args = itemChangedSpy.takeFirst();
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
QCOMPARE(qvariant_cast<int>(args.at(1)), j);
@@ -1784,94 +1764,94 @@ void tst_QTreeWidget::setData()
const QString toolTip = QLatin1String("toolTip ") + iS;
item->setToolTip(j, toolTip);
QCOMPARE(item->toolTip(j), toolTip);
- QCOMPARE(itemChangedSpy.count(), 1);
+ QCOMPARE(itemChangedSpy.size(), 1);
args = itemChangedSpy.takeFirst();
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
QCOMPARE(qvariant_cast<int>(args.at(1)), j);
item->setToolTip(j, toolTip);
- QCOMPARE(itemChangedSpy.count(), 0);
+ QCOMPARE(itemChangedSpy.size(), 0);
const QString statusTip = QLatin1String("statusTip ") + iS;
item->setStatusTip(j, statusTip);
QCOMPARE(item->statusTip(j), statusTip);
- QCOMPARE(itemChangedSpy.count(), 1);
+ QCOMPARE(itemChangedSpy.size(), 1);
args = itemChangedSpy.takeFirst();
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
QCOMPARE(qvariant_cast<int>(args.at(1)), j);
item->setStatusTip(j, statusTip);
- QCOMPARE(itemChangedSpy.count(), 0);
+ QCOMPARE(itemChangedSpy.size(), 0);
const QString whatsThis = QLatin1String("whatsThis ") + iS;
item->setWhatsThis(j, whatsThis);
QCOMPARE(item->whatsThis(j), whatsThis);
- QCOMPARE(itemChangedSpy.count(), 1);
+ QCOMPARE(itemChangedSpy.size(), 1);
args = itemChangedSpy.takeFirst();
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
QCOMPARE(qvariant_cast<int>(args.at(1)), j);
item->setWhatsThis(j, whatsThis);
- QCOMPARE(itemChangedSpy.count(), 0);
+ QCOMPARE(itemChangedSpy.size(), 0);
QSize sizeHint(64*i, 48*i);
item->setSizeHint(j, sizeHint);
QCOMPARE(item->sizeHint(j), sizeHint);
- QCOMPARE(itemChangedSpy.count(), 1);
+ QCOMPARE(itemChangedSpy.size(), 1);
args = itemChangedSpy.takeFirst();
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
QCOMPARE(qvariant_cast<int>(args.at(1)), j);
item->setSizeHint(j, sizeHint);
- QCOMPARE(itemChangedSpy.count(), 0);
+ QCOMPARE(itemChangedSpy.size(), 0);
QFont font;
item->setFont(j, font);
QCOMPARE(item->font(j), font);
- QCOMPARE(itemChangedSpy.count(), 1);
+ QCOMPARE(itemChangedSpy.size(), 1);
args = itemChangedSpy.takeFirst();
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
QCOMPARE(qvariant_cast<int>(args.at(1)), j);
item->setFont(j, font);
- QCOMPARE(itemChangedSpy.count(), 0);
+ QCOMPARE(itemChangedSpy.size(), 0);
Qt::Alignment textAlignment((i == 1)
? Qt::AlignLeft|Qt::AlignVCenter
: Qt::AlignRight);
item->setTextAlignment(j, textAlignment);
QCOMPARE(item->textAlignment(j), int(textAlignment));
- QCOMPARE(itemChangedSpy.count(), 1);
+ QCOMPARE(itemChangedSpy.size(), 1);
args = itemChangedSpy.takeFirst();
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
QCOMPARE(qvariant_cast<int>(args.at(1)), j);
item->setTextAlignment(j, textAlignment);
- QCOMPARE(itemChangedSpy.count(), 0);
+ QCOMPARE(itemChangedSpy.size(), 0);
QColor backgroundColor((i == 1) ? Qt::blue : Qt::yellow);
item->setBackground(j, backgroundColor);
QCOMPARE(item->background(j).color(), backgroundColor);
- QCOMPARE(itemChangedSpy.count(), 1);
+ QCOMPARE(itemChangedSpy.size(), 1);
args = itemChangedSpy.takeFirst();
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
QCOMPARE(qvariant_cast<int>(args.at(1)), j);
item->setBackground(j, backgroundColor);
- QCOMPARE(itemChangedSpy.count(), 0);
+ QCOMPARE(itemChangedSpy.size(), 0);
const QColor foregroundColor((i == 1) ? Qt::green : Qt::cyan);
item->setForeground(j, foregroundColor);
QCOMPARE(item->foreground(j), foregroundColor);
- QCOMPARE(itemChangedSpy.count(), 1);
+ QCOMPARE(itemChangedSpy.size(), 1);
args = itemChangedSpy.takeFirst();
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
QCOMPARE(qvariant_cast<int>(args.at(1)), j);
item->setForeground(j, foregroundColor);
- QCOMPARE(itemChangedSpy.count(), 0);
+ QCOMPARE(itemChangedSpy.size(), 0);
Qt::CheckState checkState((i == 1) ? Qt::PartiallyChecked : Qt::Checked);
item->setCheckState(j, checkState);
QCOMPARE(item->checkState(j), checkState);
- QCOMPARE(itemChangedSpy.count(), 1);
+ QCOMPARE(itemChangedSpy.size(), 1);
args = itemChangedSpy.takeFirst();
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
QCOMPARE(qvariant_cast<int>(args.at(1)), j);
item->setCheckState(j, checkState);
- QCOMPARE(itemChangedSpy.count(), 0);
+ QCOMPARE(itemChangedSpy.size(), 0);
QCOMPARE(item->text(j), text);
QCOMPARE(item->icon(j), icon);
@@ -1904,7 +1884,7 @@ void tst_QTreeWidget::setData()
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
QCOMPARE(qvariant_cast<int>(args.at(1)), j);
item->setBackground(j, pixmap);
- QCOMPARE(itemChangedSpy.count(), 0);
+ QCOMPARE(itemChangedSpy.size(), 0);
item->setData(j, Qt::DisplayRole, QVariant());
item->setData(j, Qt::DecorationRole, QVariant());
@@ -1917,7 +1897,7 @@ void tst_QTreeWidget::setData()
item->setData(j, Qt::BackgroundRole, QVariant());
item->setData(j, Qt::ForegroundRole, QVariant());
item->setData(j, Qt::CheckStateRole, QVariant());
- QCOMPARE(itemChangedSpy.count(), 11);
+ QCOMPARE(itemChangedSpy.size(), 11);
itemChangedSpy.clear();
QCOMPARE(item->data(j, Qt::DisplayRole).toString(), QString());
@@ -1980,11 +1960,11 @@ void tst_QTreeWidget::itemData()
QCOMPARE(widget.currentRoles, QList<int> { Qt::UserRole + i });
}
QMap<int, QVariant> flags = widget.model()->itemData(widget.model()->index(0, 0));
- QCOMPARE(flags.count(), 6);
+ QCOMPARE(flags.size(), 6);
for (int i = 0; i < 4; ++i)
QCOMPARE(flags[Qt::UserRole + i].toString(), QString::number(i + 1));
flags = widget.model()->itemData(widget.model()->index(0, 1));
- QCOMPARE(flags.count(), 0);
+ QCOMPARE(flags.size(), 0);
item.setBackground(0, QBrush(Qt::red));
item.setForeground(0, QBrush(Qt::green));
@@ -2053,7 +2033,7 @@ void tst_QTreeWidget::setHeaderLabels()
{
QStringList list = QString("a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z").split(QLatin1Char(','));
testWidget->setHeaderLabels(list);
- QCOMPARE(testWidget->header()->count(), list.count());
+ QCOMPARE(testWidget->header()->count(), list.size());
}
void tst_QTreeWidget::setHeaderItem()
@@ -2283,11 +2263,11 @@ void tst_QTreeWidget::insertItemsWithSorting()
w.addTopLevelItem(new QTreeWidgetItem({ txt }));
break;
}
- QCOMPARE(w.topLevelItemCount(), expectedItems.count());
+ QCOMPARE(w.topLevelItemCount(), expectedItems.size());
for (int i = 0; i < w.topLevelItemCount(); ++i)
QCOMPARE(w.topLevelItem(i)->text(0), expectedItems.at(i));
- for (int k = 0; k < persistent.count(); ++k)
+ for (int k = 0; k < persistent.size(); ++k)
QCOMPARE(persistent.at(k).row(), expectedRows.at(k));
}
}
@@ -2328,13 +2308,13 @@ void tst_QTreeWidget::insertExpandedItemsWithSorting()
QTreeWidgetItem *child = new QTreeWidgetItem(parent, {text});
items << child;
}
- QCOMPARE(parent->childCount(), childTexts.count());
+ QCOMPARE(parent->childCount(), childTexts.size());
QVERIFY(parent->isExpanded());
}
- QCOMPARE(tree.model()->rowCount(), parentTexts.count());
+ QCOMPARE(tree.model()->rowCount(), parentTexts.size());
// verify that the items are still expanded
- for (const QTreeWidgetItem *item : qAsConst(items)) {
+ for (const QTreeWidgetItem *item : std::as_const(items)) {
if (item->childCount() > 0)
QVERIFY(item->isExpanded());
QModelIndex idx = tree.indexFromItem(item);
@@ -2352,10 +2332,10 @@ void tst_QTreeWidget::insertExpandedItemsWithSorting()
PersistentModelIndexVec children;
for (int i = 0; i < model->rowCount(parents.constFirst()); ++i)
children.push_back(model->index(i, 0, parents.constFirst()));
- for (int i = 0; i < parentResult.count(); ++i) {
+ for (int i = 0; i < parentResult.size(); ++i) {
QTreeWidgetItem *item = tree.topLevelItem(i);
QCOMPARE(item->text(0), parentResult.at(i));
- for (int j = 0; j < childResult.count(); ++j)
+ for (int j = 0; j < childResult.size(); ++j)
QCOMPARE(item->child(j)->text(0), childResult.at(j));
}
}
@@ -2447,19 +2427,19 @@ void tst_QTreeWidget::changeDataWithSorting()
QTreeWidgetItem *item = w.topLevelItem(itemIndex);
item->setText(0, newValue);
- for (int i = 0; i < expectedItems.count(); ++i) {
+ for (int i = 0; i < expectedItems.size(); ++i) {
QCOMPARE(w.topLevelItem(i)->text(0), expectedItems.at(i));
- for (const QPersistentModelIndex &p : qAsConst(persistent)) {
+ for (const QPersistentModelIndex &p : std::as_const(persistent)) {
if (p.row() == i) // the same toplevel row
QCOMPARE(p.internalPointer(), static_cast<void *>(w.topLevelItem(i)));
}
}
- for (int k = 0; k < persistent.count(); ++k)
+ for (int k = 0; k < persistent.size(); ++k)
QCOMPARE(persistent.at(k).row(), expectedRows.at(k));
- QCOMPARE(dataChangedSpy.count(), 1);
- QCOMPARE(layoutChangedSpy.count(), reorderingExpected ? 1 : 0);
+ QCOMPARE(dataChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), reorderingExpected ? 1 : 0);
}
void tst_QTreeWidget::changeDataWithStableSorting_data()
@@ -2616,19 +2596,19 @@ void tst_QTreeWidget::changeDataWithStableSorting()
item->setText(0, newValue);
if (forceChange)
item->emitDataChanged();
- for (int i = 0; i < expectedItems.count(); ++i) {
+ for (int i = 0; i < expectedItems.size(); ++i) {
QCOMPARE(w.topLevelItem(i)->text(0), expectedItems.at(i));
- for (const QPersistentModelIndex &p : qAsConst(persistent)) {
+ for (const QPersistentModelIndex &p : std::as_const(persistent)) {
if (p.row() == i) // the same toplevel row
QCOMPARE(p.internalPointer(), static_cast<void *>(w.topLevelItem(i)));
}
}
- for (int k = 0; k < persistent.count(); ++k)
+ for (int k = 0; k < persistent.size(); ++k)
QCOMPARE(persistent.at(k).row(), expectedRows.at(k));
- QCOMPARE(dataChangedSpy.count(), 1);
- QCOMPARE(layoutChangedSpy.count(), reorderingExpected ? 1 : 0);
+ QCOMPARE(dataChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), reorderingExpected ? 1 : 0);
}
void tst_QTreeWidget::sizeHint_data()
@@ -2647,6 +2627,12 @@ void tst_QTreeWidget::sizeHint()
QFETCH(Qt::ScrollBarPolicy, scrollBarPolicy);
QFETCH(QSize, viewSize);
+ const QString defaultStyle = QApplication::style()->name();
+ QApplication::setStyle("fusion");
+ const auto resetStyle = qScopeGuard([defaultStyle]{
+ QApplication::setStyle(defaultStyle);
+ });
+
QTreeWidget view;
view.setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
view.setVerticalScrollBarPolicy(scrollBarPolicy);
@@ -2664,6 +2650,7 @@ void tst_QTreeWidget::sizeHint()
QTRY_COMPARE(view.size(), viewSize);
}
+ QApplication::processEvents(); // execute delayed layouts
auto sizeHint = view.sizeHint();
view.hide();
QCOMPARE(view.sizeHint(), sizeHint);
@@ -2734,8 +2721,8 @@ void tst_QTreeWidget::sortedIndexOfChild()
tw.sortItems(0, sortOrder);
tw.expandAll();
- QCOMPARE(itms.count(), expectedIndexes.count());
- for (int j = 0; j < expectedIndexes.count(); ++j)
+ QCOMPARE(itms.size(), expectedIndexes.size());
+ for (int j = 0; j < expectedIndexes.size(); ++j)
QCOMPARE(top->indexOfChild(itms.at(j)), expectedIndexes.at(j));
}
@@ -2760,8 +2747,8 @@ void tst_QTreeWidget::expandAndCallapse()
tw.collapseItem(top);
tw.collapseItem(top);
- QCOMPARE(spy0.count(), 3);
- QCOMPARE(spy1.count(), 2);
+ QCOMPARE(spy0.size(), 3);
+ QCOMPARE(spy1.size(), 2);
}
void tst_QTreeWidget::setDisabled()
@@ -2874,13 +2861,13 @@ void tst_QTreeWidget::removeSelectedItem()
QItemSelectionModel *selModel = w->selectionModel();
QCOMPARE(selModel->hasSelection(), true);
- QCOMPARE(selModel->selectedRows().count(), 1);
+ QCOMPARE(selModel->selectedRows().size(), 1);
const QScopedPointer<QTreeWidgetItem> taken(w->takeTopLevelItem(2));
QCOMPARE(taken->text(0), QLatin1String("C"));
QCOMPARE(selModel->hasSelection(), false);
- QCOMPARE(selModel->selectedRows().count(), 0);
+ QCOMPARE(selModel->selectedRows().size(), 0);
QItemSelection sel = selModel->selection();
QCOMPARE(selModel->isSelected(w->model()->index(0,0)), false);
}
@@ -2991,7 +2978,7 @@ protected:
auto newItem = new QTreeWidgetItem({QString::number(i++)});
m_list.append(newItem);
insertTopLevelItem(0, newItem);
- while (m_list.count() > 10)
+ while (m_list.size() > 10)
delete m_list.takeFirst();
}
QTreeWidget::timerEvent(event);
@@ -3305,7 +3292,7 @@ void tst_QTreeWidget::emitDataChanged()
auto item = new PublicTreeItem;
tree.insertTopLevelItem(0, item);
item->emitDataChanged();
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
}
void tst_QTreeWidget::setCurrentItemExpandsParent()
@@ -3587,6 +3574,21 @@ void tst_QTreeWidget::reparentHiddenItem()
QVERIFY(grandChild->isHidden());
}
+void tst_QTreeWidget::persistentChildIndex() // QTBUG-90030
+{
+ QTreeWidget tree;
+ QTreeWidgetItem *toplevel = new QTreeWidgetItem(QStringList{QStringLiteral("toplevel")});
+ tree.addTopLevelItem(toplevel);
+ QModelIndex firstIndex = tree.model()->index(0, 0);
+ QTreeWidgetItem *child1 = new QTreeWidgetItem(QStringList{QStringLiteral("child1")});
+ QTreeWidgetItem *child2 = new QTreeWidgetItem(QStringList{QStringLiteral("child2")});
+ toplevel->addChildren({child1, child2});
+ QPersistentModelIndex persistentIdx = tree.model()->index(1, 0, firstIndex);
+ QCOMPARE(persistentIdx.data().toString(), QStringLiteral("child2"));
+ tree.model()->removeRows(0, 1, firstIndex);
+ QCOMPARE(persistentIdx.data().toString(), QStringLiteral("child2"));
+}
+
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
void tst_QTreeWidget::clearItemData()
{
@@ -3625,5 +3627,72 @@ void tst_QTreeWidget::clearItemData()
}
#endif
+void tst_QTreeWidget::createPersistentOnLayoutAboutToBeChanged() // QTBUG-93466
+{
+ QTreeWidget widget;
+ QCOMPARE(widget.model()->columnCount(), 1);
+ widget.model()->insertRows(0, 3);
+ for (int row = 0; row < 3; ++row)
+ widget.model()->setData(widget.model()->index(row, 0), row);
+ QList<QPersistentModelIndex> idxList;
+ QSignalSpy layoutAboutToBeChangedSpy(widget.model(), &QAbstractItemModel::layoutAboutToBeChanged);
+ QSignalSpy layoutChangedSpy(widget.model(), &QAbstractItemModel::layoutChanged);
+ connect(widget.model(), &QAbstractItemModel::layoutAboutToBeChanged, this, [&idxList, &widget](){
+ idxList.clear();
+ for (int row = 0; row < 3; ++row)
+ idxList << QPersistentModelIndex(widget.model()->index(row, 0));
+ });
+ connect(widget.model(), &QAbstractItemModel::layoutChanged, this, [&idxList](){
+ QCOMPARE(idxList.size(), 3);
+ QCOMPARE(idxList.at(0).row(), 1);
+ QCOMPARE(idxList.at(0).column(), 0);
+ QCOMPARE(idxList.at(0).data().toInt(), 0);
+ QCOMPARE(idxList.at(1).row(), 0);
+ QCOMPARE(idxList.at(1).column(), 0);
+ QCOMPARE(idxList.at(1).data().toInt(), -1);
+ QCOMPARE(idxList.at(2).row(), 2);
+ QCOMPARE(idxList.at(2).column(), 0);
+ QCOMPARE(idxList.at(2).data().toInt(), 2);
+ });
+ widget.model()->setData(widget.model()->index(1, 0), -1);
+ widget.model()->sort(0);
+ QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), 1);
+}
+
+void tst_QTreeWidget::createPersistentOnLayoutAboutToBeChangedAutoSort() // QTBUG-93466
+{
+ QTreeWidget widget;
+ QCOMPARE(widget.model()->columnCount(), 1);
+ widget.model()->insertRows(0, 3);
+ for (int row = 0; row < 3; ++row)
+ widget.model()->setData(widget.model()->index(row, 0), row);
+ widget.sortByColumn(0, Qt::AscendingOrder);
+ widget.setSortingEnabled(true);
+ QList<QPersistentModelIndex> idxList;
+ QSignalSpy layoutAboutToBeChangedSpy(widget.model(), &QAbstractItemModel::layoutAboutToBeChanged);
+ QSignalSpy layoutChangedSpy(widget.model(), &QAbstractItemModel::layoutChanged);
+ connect(widget.model(), &QAbstractItemModel::layoutAboutToBeChanged, this, [&idxList, &widget](){
+ idxList.clear();
+ for (int row = 0; row < 3; ++row)
+ idxList << QPersistentModelIndex(widget.model()->index(row, 0));
+ });
+ connect(widget.model(), &QAbstractItemModel::layoutChanged, this, [&idxList](){
+ QCOMPARE(idxList.size(), 3);
+ QCOMPARE(idxList.at(0).row(), 1);
+ QCOMPARE(idxList.at(0).column(), 0);
+ QCOMPARE(idxList.at(0).data().toInt(), 0);
+ QCOMPARE(idxList.at(1).row(), 0);
+ QCOMPARE(idxList.at(1).column(), 0);
+ QCOMPARE(idxList.at(1).data().toInt(), -1);
+ QCOMPARE(idxList.at(2).row(), 2);
+ QCOMPARE(idxList.at(2).column(), 0);
+ QCOMPARE(idxList.at(2).data().toInt(), 2);
+ });
+ widget.model()->setData(widget.model()->index(1, 0), -1);
+ QCOMPARE(layoutAboutToBeChangedSpy.size(), 1);
+ QCOMPARE(layoutChangedSpy.size(), 1);
+}
+
QTEST_MAIN(tst_QTreeWidget)
#include "tst_qtreewidget.moc"
diff --git a/tests/auto/widgets/itemviews/qtreewidgetitemiterator/CMakeLists.txt b/tests/auto/widgets/itemviews/qtreewidgetitemiterator/CMakeLists.txt
index c62b0d4c6f..d82eaadced 100644
--- a/tests/auto/widgets/itemviews/qtreewidgetitemiterator/CMakeLists.txt
+++ b/tests/auto/widgets/itemviews/qtreewidgetitemiterator/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Generated from qtreewidgetitemiterator.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
#####################################################################
## tst_qtreewidgetitemiterator Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qtreewidgetitemiterator LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_test(tst_qtreewidgetitemiterator
SOURCES
tst_qtreewidgetitemiterator.cpp
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Gui
Qt::Widgets
)
diff --git a/tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp b/tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp
index 68d149fc6e..a650eb229e 100644
--- a/tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp
+++ b/tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.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) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTreeWidget>
@@ -891,7 +866,7 @@ void tst_QTreeWidgetItemIterator::iteratorflags()
QTreeWidgetItemIterator it(testWidget, iteratorflags);
it += start;
int iMatch = 0;
- while (*it && iMatch < matches.count()) {
+ while (*it && iMatch < matches.size()) {
QTreeWidgetItem *item = *it;
QCOMPARE(item->text(0), matches[iMatch]);
++it;