diff options
Diffstat (limited to 'tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp')
-rw-r--r-- | tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp | 181 |
1 files changed, 169 insertions, 12 deletions
diff --git a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp index 430e5034af..3e7dc92da1 100644 --- a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp +++ b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp @@ -1,13 +1,17 @@ // Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> #include <QSignalSpy> #include <QtWidgets/QPushButton> #include <QtWidgets/QStyle> #include <QtWidgets/QLayout> #include <QtWidgets/QDialog> +#include <QtWidgets/QLineEdit> #include <QtGui/QAction> +#include <QtGui/QStyleHints> #include <qdialogbuttonbox.h> +#include <QtWidgets/private/qdialogbuttonbox_p.h> +#include <QtWidgets/private/qabstractbutton_p.h> #include <limits.h> Q_DECLARE_METATYPE(QDialogButtonBox::ButtonRole) @@ -49,6 +53,10 @@ private slots: void clear(); void removeButton_data(); void removeButton(); +#ifdef QT_BUILD_INTERNAL + void hideAndShowButton(); +#endif + void hideAndShowStandardButton(); void buttonRole_data(); void buttonRole(); void setStandardButtons_data(); @@ -74,6 +82,9 @@ private slots: void task191642_default(); void testDeletedStandardButton(); + void automaticDefaultButton(); + void initialFocus_data(); + void initialFocus(); private: qint64 timeStamp; @@ -372,6 +383,70 @@ void tst_QDialogButtonBox::removeButton() delete button; } +#ifdef QT_BUILD_INTERNAL +void tst_QDialogButtonBox::hideAndShowButton() +{ + if (QGuiApplication::styleHints()->tabFocusBehavior() == Qt::NoTabFocus) + QSKIP("Test skipped with Qt::NoTabFocus"); + + QDialogButtonBox buttonBox; + QDialogButtonBoxPrivate *d = static_cast<QDialogButtonBoxPrivate *>(QObjectPrivate::get(&buttonBox)); + auto *apply = buttonBox.addButton( "Apply", QDialogButtonBox::ApplyRole ); + auto *accept = buttonBox.addButton( "Accept", QDialogButtonBox::AcceptRole ); + buttonBox.addButton( "Reject", QDialogButtonBox::RejectRole ); + auto *widget = new QWidget(); + auto *layout = new QHBoxLayout(widget); + layout->addWidget(&buttonBox); + + // apply button shows first on macOS. accept button on all other OSes. + QAbstractButton *hideButton; +#ifdef Q_OS_MACOS + hideButton = apply; + Q_UNUSED(accept); +#else + hideButton = accept; + Q_UNUSED(apply); +#endif + + hideButton->hide(); + widget->show(); + QVERIFY(QTest::qWaitForWindowExposed(widget)); + QTRY_VERIFY(buttonBox.focusWidget()); // QTBUG-114377: Without fixing, focusWidget() == nullptr + QCOMPARE(d->visibleButtons().count(), 2); + QCOMPARE(d->hiddenButtons.count(), 1); + QVERIFY(d->hiddenButtons.contains(hideButton)); + QCOMPARE(buttonBox.buttons().count(), 3); + QSignalSpy spy(qApp, &QApplication::focusChanged); + QTest::sendKeyEvent(QTest::KeyAction::Click, &buttonBox, Qt::Key_Tab, QString(), Qt::KeyboardModifiers()); + QCOMPARE(spy.count(), 1); // QTBUG-114377: Without fixing, tabbing wouldn't work. + hideButton->show(); + QCOMPARE_GE(spy.count(), 1); + QTRY_COMPARE(QApplication::focusWidget(), hideButton); + QCOMPARE(d->visibleButtons().count(), 3); + QCOMPARE(d->hiddenButtons.count(), 0); + QCOMPARE(buttonBox.buttons().count(), 3); + spy.clear(); + QTest::sendKeyEvent(QTest::KeyAction::Click, &buttonBox, Qt::Key_Backtab, QString(), Qt::KeyboardModifiers()); + QCOMPARE(spy.count(), 1); +} +#endif + +void tst_QDialogButtonBox::hideAndShowStandardButton() +{ + QDialogButtonBox buttonBox; + buttonBox.setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + buttonBox.show(); + QVERIFY(QTest::qWaitForWindowExposed(&buttonBox)); + auto *button = buttonBox.button(QDialogButtonBox::Cancel); + QVERIFY(button); + button->hide(); + QVERIFY(QTest::qWaitFor([button](){ return !button->isVisible(); })); + QCOMPARE(button, buttonBox.button(QDialogButtonBox::Cancel)); + button->show(); + QVERIFY(QTest::qWaitForWindowExposed(button)); + QCOMPARE(button, buttonBox.button(QDialogButtonBox::Cancel)); +} + void tst_QDialogButtonBox::testDelete() { QDialogButtonBox buttonBox; @@ -425,8 +500,8 @@ void tst_QDialogButtonBox::testSignalEmissionAfterDelete_QTBUG_45835() button->click(); QCOMPARE(buttonBox.buttons().size(), 0); - QCOMPARE(buttonClickedSpy.count(), 1); - QCOMPARE(buttonBoxAcceptedSpy.count(), 1); + QCOMPARE(buttonClickedSpy.size(), 1); + QCOMPARE(buttonBoxAcceptedSpy.size(), 1); } { @@ -448,8 +523,8 @@ void tst_QDialogButtonBox::testSignalEmissionAfterDelete_QTBUG_45835() button->click(); QVERIFY(buttonBox.isNull()); - QCOMPARE(buttonClickedSpy.count(), 1); - QCOMPARE(buttonBoxAcceptedSpy.count(), 0); + QCOMPARE(buttonClickedSpy.size(), 1); + QCOMPARE(buttonBoxAcceptedSpy.size(), 0); } } @@ -594,13 +669,13 @@ void tst_QDialogButtonBox::testSignals() if (clickMe) clickMe->click(); - QTRY_COMPARE(clicked2.count(), clicked2Count); - if (clicked2.count() > 0) + QTRY_COMPARE(clicked2.size(), clicked2Count); + if (clicked2.size() > 0) QCOMPARE(qvariant_cast<QAbstractButton *>(clicked2.at(0).at(0)), clickMe); - QTEST(int(accept.count()), "acceptCount"); - QTEST(int(reject.count()), "rejectCount"); - QTEST(int(helpRequested.count()), "helpRequestedCount"); + QTEST(int(accept.size()), "acceptCount"); + QTEST(int(reject.size()), "rejectCount"); + QTEST(int(helpRequested.size()), "helpRequestedCount"); } void tst_QDialogButtonBox::testSignalOrder() @@ -756,7 +831,7 @@ void tst_QDialogButtonBox::testRemove() button->click(); QTest::qWait(100); - QCOMPARE(clicked.count(), 0); + QCOMPARE(clicked.size(), 0); delete button; } @@ -818,7 +893,7 @@ void tst_QDialogButtonBox::task191642_default() QVERIFY(QTest::qWaitForWindowActive(&dlg)); QVERIFY(def->isDefault()); QTest::keyPress( &dlg, Qt::Key_Enter ); - QCOMPARE(clicked.count(), 1); + QCOMPARE(clicked.size(), 1); } void tst_QDialogButtonBox::testDeletedStandardButton() @@ -838,5 +913,87 @@ void tst_QDialogButtonBox::testDeletedStandardButton() QVERIFY(!buttonC); } +void tst_QDialogButtonBox::automaticDefaultButton() +{ + // Having a QDialogButtonBox inside a QDialog triggers Qt to + // enable autoDefault for QPushButtons inside the button box. + // Check that the logic for resolving a default button based + // on the Accept role is not overridden by the first button + // in the dialog (the focus proxy) taking focus, and hence + // stealing the default button state. + + { + QDialog dialog; + QDialogButtonBox *bb = new QDialogButtonBox(&dialog); + // Force horizontal orientation, where we know the order between + // Reset and Accept roles are always the same for all layouts. + bb->setOrientation(Qt::Horizontal); + auto *okButton = bb->addButton(QDialogButtonBox::Ok); + auto *resetButton = bb->addButton(QDialogButtonBox::Reset); + // Double check our assumption about Reset being first + QCOMPARE(bb->layout()->itemAt(0)->widget(), resetButton); + + dialog.show(); + QVERIFY(QTest::qWaitForWindowActive(&dialog)); + + QVERIFY(okButton->isDefault()); + QSignalSpy buttonClicked(okButton, &QPushButton::clicked); + QTest::keyPress(&dialog, Qt::Key_Enter); + QCOMPARE(buttonClicked.count(), 1); + } + + // However, if an explicit button has been focused, we respect that. + + { + QDialog dialog; + QDialogButtonBox *bb = new QDialogButtonBox(&dialog); + bb->setOrientation(Qt::Horizontal); + bb->addButton(QDialogButtonBox::Ok); + auto *resetButton = bb->addButton(QDialogButtonBox::Reset); + resetButton->setFocus(); + dialog.show(); + QVERIFY(QTest::qWaitForWindowActive(&dialog)); + + QVERIFY(resetButton->isDefault()); + QSignalSpy buttonClicked(resetButton, &QPushButton::clicked); + QTest::keyPress(&dialog, Qt::Key_Enter); + QCOMPARE(buttonClicked.count(), 1); + } +} + +void tst_QDialogButtonBox::initialFocus_data() +{ + QTest::addColumn<Qt::FocusPolicy>("focusPolicy"); + QTest::addColumn<bool>("lineEditHasFocus"); + + QTest::addRow("TabFocus") << Qt::FocusPolicy::TabFocus << false; + QTest::addRow("StrongFocus") << Qt::FocusPolicy::StrongFocus << true; + QTest::addRow("NoFocus") << Qt::FocusPolicy::NoFocus << false; + QTest::addRow("ClickFocus") << Qt::FocusPolicy::ClickFocus << false; + QTest::addRow("WheelFocus") << Qt::FocusPolicy::WheelFocus << false; +} + +void tst_QDialogButtonBox::initialFocus() +{ + QFETCH(const Qt::FocusPolicy, focusPolicy); + QFETCH(const bool, lineEditHasFocus); + QDialog dialog; + QVBoxLayout *layout = new QVBoxLayout(&dialog); + QLineEdit *lineEdit = new QLineEdit(&dialog); + lineEdit->setFocusPolicy(focusPolicy); + layout->addWidget(lineEdit); + QDialogButtonBox *dialogButtonBox = new QDialogButtonBox(&dialog); + layout->addWidget(dialogButtonBox); + dialogButtonBox->addButton(QDialogButtonBox::Reset); + const auto *firstAcceptButton = dialogButtonBox->addButton(QDialogButtonBox::Ok); + dialogButtonBox->addButton(QDialogButtonBox::Cancel); + dialog.show(); + dialog.activateWindow(); + if (lineEditHasFocus) + QTRY_VERIFY(lineEdit->hasFocus()); + else + QTRY_VERIFY(firstAcceptButton->hasFocus()); +} + QTEST_MAIN(tst_QDialogButtonBox) #include "tst_qdialogbuttonbox.moc" |