diff options
Diffstat (limited to 'tests')
5 files changed, 234 insertions, 14 deletions
diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index ac50a5cdae7..e42fb4419a8 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -3518,12 +3518,33 @@ void tst_QTreeView::styleOptionViewItem() model.clear(); model.appendRow({ new QStandardItem("Hidden"), new QStandardItem("OnlyOne Last") }); + view.setModel(&model); view.setColumnHidden(0, true); view.setColumnHidden(1, false); - view.setModel(&model); delegate.count = 0; QTRY_COMPARE_GE(delegate.count, 1); + + // special case, four columns, only one is updated but + // calcLogicalIndices() returns the correct value + { + model.clear(); + model.appendRow({ new QStandardItem("Hidden"), + new QStandardItem("Beginning Last"), + new QStandardItem("Middle Last"), + new QStandardItem("End Last") }); + view.setColumnHidden(0, true); + delegate.count = 0; + QTRY_COMPARE_GE(delegate.count, 4); + + // do not rely on paintEvent() as this might redraw a bigger + // rect than we expect + QList<int> logicalIndices; + QList<QStyleOptionViewItem::ViewItemPosition> itemPositions; + view.d_func()->calcLogicalIndices(&logicalIndices, &itemPositions, 3, 3); + QCOMPARE(itemPositions.size(), 1); + QCOMPARE(itemPositions.at(0), QStyleOptionViewItem::End); + } } class task174627_TreeView : public QTreeView diff --git a/tests/auto/widgets/kernel/qgesturerecognizer/tst_qgesturerecognizer.cpp b/tests/auto/widgets/kernel/qgesturerecognizer/tst_qgesturerecognizer.cpp index febb9e2c9dc..255bcaa5bec 100644 --- a/tests/auto/widgets/kernel/qgesturerecognizer/tst_qgesturerecognizer.cpp +++ b/tests/auto/widgets/kernel/qgesturerecognizer/tst_qgesturerecognizer.cpp @@ -9,11 +9,14 @@ #include <QtGui/QScreen> #include <QtGui/QPointingDevice> #include <QtCore/QList> +#include <QtCore/QLoggingCategory> #include <QtCore/QString> #include <QtCore/QHash> #include <QtCore/QDebug> #include <memory> +Q_LOGGING_CATEGORY(lcTests, "qt.widgets.tests") + class tst_QGestureRecognizer : public QObject { Q_OBJECT @@ -60,14 +63,30 @@ public: bool gestureReceived(Qt::GestureType gestureType) const { return m_receivedGestures.value(gestureType); } -protected: - bool event(QEvent * event) override; + void clearReceivedGestures(); -private: - typedef QHash<Qt::GestureType, bool> GestureTypeHash; - GestureTypeHash m_receivedGestures; + qreal lastSwipeAngle = 0; + QSwipeGesture::SwipeDirection lastHorizontalDirection = QSwipeGesture::NoDirection; + QSwipeGesture::SwipeDirection lastVerticalDirection = QSwipeGesture::NoDirection; + Qt::GestureState lastSwipeState = Qt::NoGesture; + + protected: + bool event(QEvent *event) override; + + private: + typedef QHash<Qt::GestureType, bool> GestureTypeHash; + GestureTypeHash m_receivedGestures; }; +void TestWidget::clearReceivedGestures() +{ + m_receivedGestures.clear(); + lastSwipeAngle = {}; + lastHorizontalDirection = QSwipeGesture::NoDirection; + lastVerticalDirection = QSwipeGesture::NoDirection; + lastSwipeState = Qt::NoGesture; +} + TestWidget::TestWidget(const GestureTypeVector &gestureTypes) { setAttribute(Qt::WA_AcceptTouchEvents); @@ -95,8 +114,22 @@ bool TestWidget::event(QEvent * event) it.value() = true; } } - } + for (const QGesture *gesture : gestureEvent->activeGestures()) { + switch (gesture->gestureType()) { + case Qt::SwipeGesture: { + const auto *swipe = static_cast<const QSwipeGesture *>(gesture); + lastSwipeAngle = swipe->swipeAngle(); + lastHorizontalDirection = swipe->horizontalDirection(); + lastVerticalDirection = swipe->verticalDirection(); + lastSwipeState = gesture->state(); + break; + } + default: + break; + } + } break; + } default: break; } @@ -241,10 +274,26 @@ enum SwipeSubTest { void tst_QGestureRecognizer::swipeGesture_data() { QTest::addColumn<int>("swipeSubTest"); + QTest::addColumn<QPoint>("moveDelta"); QTest::addColumn<bool>("gestureExpected"); - QTest::newRow("Line") << int(SwipeLineSubTest) << true; - QTest::newRow("DirectionChange") << int(SwipeDirectionChangeSubTest) << false; - QTest::newRow("SmallDirectionChange") << int(SwipeSmallDirectionChangeSubTest) << true; + QTest::addColumn<int>("expectedAngle"); + QTest::addColumn<QSwipeGesture::SwipeDirection>("expectedHorizontalDirection"); + QTest::addColumn<QSwipeGesture::SwipeDirection>("expectedVerticalDirection"); + + QTest::newRow("UpRight Line") << int(SwipeLineSubTest) << QPoint(42, -25) + << true << 30 << QSwipeGesture::Right << QSwipeGesture::Up; + QTest::newRow("DownRight Line") << int(SwipeLineSubTest) << QPoint(42, 25) + << true << 329 << QSwipeGesture::Right << QSwipeGesture::Down; + QTest::newRow("OutRight Line") << int(SwipeLineSubTest) << QPoint(42, 0) + << true << 360 << QSwipeGesture::Right << QSwipeGesture::NoDirection; + QTest::newRow("DownLeft Line") << int(SwipeLineSubTest) << QPoint(-42, 25) + << true << 211 << QSwipeGesture::Left << QSwipeGesture::Down; + QTest::newRow("Up Line") << int(SwipeLineSubTest) << QPoint(0, -25) + << true << 90 << QSwipeGesture::NoDirection << QSwipeGesture::Up; + QTest::newRow("DirectionChange") << int(SwipeDirectionChangeSubTest) << QPoint(42, 25) + << false << 0 << QSwipeGesture::NoDirection << QSwipeGesture::NoDirection; + QTest::newRow("SmallDirectionChange") << int(SwipeSmallDirectionChangeSubTest) << QPoint(42, -25) + << true << 359 << QSwipeGesture::Right << QSwipeGesture::Down; } void tst_QGestureRecognizer::swipeGesture() @@ -252,7 +301,11 @@ void tst_QGestureRecognizer::swipeGesture() enum { swipePoints = 3 }; QFETCH(int, swipeSubTest); + QFETCH(QPoint, moveDelta); QFETCH(bool, gestureExpected); + QFETCH(int, expectedAngle); + QFETCH(QSwipeGesture::SwipeDirection, expectedHorizontalDirection); + QFETCH(QSwipeGesture::SwipeDirection, expectedVerticalDirection); const Qt::GestureType gestureType = Qt::SwipeGesture; TestWidget widget(GestureTypeVector(1, gestureType)); @@ -264,20 +317,27 @@ void tst_QGestureRecognizer::swipeGesture() // Start a swipe sequence with 2 points (QTBUG-15768) const QPoint fingerDistance(m_fingerDistance, m_fingerDistance); QList<QPoint> points; - for (int i = 0; i < swipePoints - 1; ++i) + for (int i = 1; i < swipePoints; ++i) points.append(fingerDistance + i * fingerDistance); QTest::QTouchEventWidgetSequence swipeSequence = QTest::touchEvent(&widget, m_touchDevice.get()); pressSequence(swipeSequence, points, &widget); + // Move a little: nothing happens + points[0] += {1, 1}; + points[1] += {1, 1}; + swipeSequence.move(0, points[0], &widget).move(1, points[1], &widget).commit(); + QCoreApplication::processEvents(); + QVERIFY(!widget.gestureReceived(gestureType)); + // Press point #3 points.append(points.last() + fingerDistance); swipeSequence.stationary(0).stationary(1).press(points.size() - 1, points.last(), &widget); swipeSequence.commit(); Q_ASSERT(points.size() == swipePoints); + QCOMPARE(widget.lastSwipeState, Qt::NoGesture); // Move. - const QPoint moveDelta(60, 20); switch (swipeSubTest) { case SwipeLineSubTest: linearSequence(5, moveDelta, swipeSequence, points, &widget); @@ -294,15 +354,37 @@ void tst_QGestureRecognizer::swipeGesture() } break; } + QCOMPARE(widget.lastSwipeState, Qt::GestureUpdated); - releaseSequence(swipeSequence, points, &widget); - + // release any point: the gesture ends + swipeSequence.release(0, points[0], &widget).commit(); if (gestureExpected) { QTRY_VERIFY(widget.gestureReceived(gestureType)); + qCDebug(lcTests) << "started @" << fingerDistance + << "; ended with angle" << widget.lastSwipeAngle + << "expected" << expectedAngle + << "dirns" << widget.lastHorizontalDirection << widget.lastVerticalDirection; + QCOMPARE(qRound(widget.lastSwipeAngle), expectedAngle); + QEXPECT_FAIL("Up Line", "90 degrees (up) should be NoDirection on horizontal axis", Continue); + QCOMPARE(widget.lastHorizontalDirection, expectedHorizontalDirection); + QEXPECT_FAIL("OutRight Line", "0 degrees (to the right) should be NoDirection on the vertical axis", Continue); + QCOMPARE(widget.lastVerticalDirection, expectedVerticalDirection); + QCOMPARE(widget.lastSwipeState, Qt::GestureFinished); } else { QCoreApplication::processEvents(); QVERIFY(!widget.gestureReceived(gestureType)); + QCOMPARE(widget.lastSwipeState, Qt::GestureUpdated); } + + // move the others a little, then release: no further swipe (it needs 3 fingers) + widget.clearReceivedGestures(); + points[1] += {1, 1}; + points[2] += {1, 1}; + swipeSequence.move(1, points[1], &widget).move(2, points[2], &widget).commit(); + swipeSequence.release(1, points[1], &widget).release(2, points[2], &widget).commit(); + QCoreApplication::processEvents(); + QVERIFY(!widget.gestureReceived(gestureType)); + QCOMPARE(widget.lastSwipeState, Qt::NoGesture); } void tst_QGestureRecognizer::touchReplay() diff --git a/tests/manual/widgets/itemviews/CMakeLists.txt b/tests/manual/widgets/itemviews/CMakeLists.txt index 4a67078103c..bae613b4fb9 100644 --- a/tests/manual/widgets/itemviews/CMakeLists.txt +++ b/tests/manual/widgets/itemviews/CMakeLists.txt @@ -5,3 +5,4 @@ add_subdirectory(qheaderview) add_subdirectory(qtreeview) add_subdirectory(qtreewidget) add_subdirectory(tableview-span-navigation) +add_subdirectory(qtablewidget-sort-indicator) diff --git a/tests/manual/widgets/itemviews/qtablewidget-sort-indicator/CMakeLists.txt b/tests/manual/widgets/itemviews/qtablewidget-sort-indicator/CMakeLists.txt new file mode 100644 index 00000000000..9d1ef6e7931 --- /dev/null +++ b/tests/manual/widgets/itemviews/qtablewidget-sort-indicator/CMakeLists.txt @@ -0,0 +1,16 @@ +# Copyright (C) 2025 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## qtablewidget-sort-indicator Binary: +##################################################################### + +qt_internal_add_manual_test(qtablewidget-sort-indicator + GUI + SOURCES + main.cpp + LIBRARIES + Qt::CorePrivate + Qt::Gui + Qt::Widgets +) diff --git a/tests/manual/widgets/itemviews/qtablewidget-sort-indicator/main.cpp b/tests/manual/widgets/itemviews/qtablewidget-sort-indicator/main.cpp new file mode 100644 index 00000000000..b3464c67c89 --- /dev/null +++ b/tests/manual/widgets/itemviews/qtablewidget-sort-indicator/main.cpp @@ -0,0 +1,100 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QApplication> +#include <QTableWidget> +#include <QHeaderView> +#include <QVBoxLayout> +#include <QGroupBox> +#include <QRadioButton> +#include <QLabel> + +QString createStyleSheet(const char *sortArrowPos) +{ + QString styleSheet {R"( + QHeaderView::section { + background-color: #f0f0f0; + padding: 5px; + border: 1px solid #ffffff; + font-weight: bold; + } + + QHeaderView::up-arrow, QHeaderView::down-arrow { + width: 24px; + height: 24px; + subcontrol-position: %1; + subcontrol-origin: padding; + } + )"}; + + return styleSheet.arg(sortArrowPos); +} + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + QWidget mainWidget; + mainWidget.setWindowTitle("QTableWidget sort indicator overlap with clipping"); + + const QStringList headerLabels { "Header", "LongHeaderText"}; + const QStringList column1 { "Alpha", "Beta", "Gamma" }; + const QStringList column2 { "1", "2", "3" }; + + QTableWidget tableWidget(3, 2, &mainWidget); + tableWidget.setHorizontalHeaderLabels(headerLabels); + + for (int i {0} ; i < column1.size() ; ++i) { + tableWidget.setItem(i, 0, new QTableWidgetItem(column1[i])); + tableWidget.setItem(i, 1, new QTableWidgetItem(column2[i])); + } + + tableWidget.setSortingEnabled(true); + tableWidget.setStyleSheet(createStyleSheet("center right")); + tableWidget.adjustSize(); + + QVBoxLayout mainLayout {&mainWidget}; + QGroupBox buttonBox; + QVBoxLayout buttonLayout {&buttonBox}; + QRadioButton leftButton {"Left-aligned sort indicator"}; + QRadioButton centerButton {"Center-aligned sort indicator"}; + QRadioButton rightButton {"Right-aligned sort indicator"}; + + buttonLayout.addWidget(&leftButton); + buttonLayout.addWidget(¢erButton); + buttonLayout.addWidget(&rightButton); + + mainLayout.addWidget(&tableWidget); + mainLayout.addWidget(&buttonBox); + + QLabel instructions { QT_TR_NOOP(R"(<html>Instructions: +<ol> +<li>There are 3 options for alignment of the column header sort arrow: left, center, and right. Click one of the 3 radio buttons to select the sort arrow alignment. +</li> +<li>Click the left column header to sort the table. The sort arrow should appear at its correct alignment without overlapping the text. +</li> +<li>Click the right column header. The sort arrow should appear at its correct alignment. The left and right alignment should clip the text without changing its position. The center alignment should not clip the text at all. +</ol> + </html>)")}; + instructions.setTextFormat(Qt::AutoText); + instructions.setWordWrap(true); + mainLayout.addWidget(&instructions); + + QObject::connect(&leftButton, &QRadioButton::clicked, &app, [&](bool checked) { + if (checked) + tableWidget.setStyleSheet(createStyleSheet("center left")); + }); + QObject::connect(¢erButton, &QRadioButton::clicked, &app, [&](bool checked) { + if (checked) + tableWidget.setStyleSheet(createStyleSheet("top center")); + }); + QObject::connect(&rightButton, &QRadioButton::clicked, &app, [&](bool checked) { + if (checked) + tableWidget.setStyleSheet(createStyleSheet("center right")); + }); + + leftButton.click(); + mainWidget.show(); + + return app.exec(); +} |
