diff options
Diffstat (limited to 'tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp')
-rw-r--r-- | tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp | 274 |
1 files changed, 203 insertions, 71 deletions
diff --git a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp index 2e7e248db7..3e7dc92da1 100644 --- a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp +++ b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp @@ -1,38 +1,17 @@ -/**************************************************************************** -** -** 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 <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) @@ -74,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(); @@ -99,6 +82,9 @@ private slots: void task191642_default(); void testDeletedStandardButton(); + void automaticDefaultButton(); + void initialFocus_data(); + void initialFocus(); private: qint64 timeStamp; @@ -122,7 +108,7 @@ void tst_QDialogButtonBox::testConstructor1() QDialogButtonBox buttonbox; QCOMPARE(buttonbox.orientation(), Qt::Horizontal); - QCOMPARE(buttonbox.buttons().count(), 0); + QCOMPARE(buttonbox.buttons().size(), 0); } void tst_QDialogButtonBox::layoutReuse() @@ -155,7 +141,7 @@ void tst_QDialogButtonBox::testConstructor2() QDialogButtonBox buttonBox(orient); QCOMPARE(buttonBox.orientation(), orient); - QCOMPARE(buttonBox.buttons().count(), 0); + QCOMPARE(buttonBox.buttons().size(), 0); } void tst_QDialogButtonBox::testConstructor3_data() @@ -192,7 +178,7 @@ void tst_QDialogButtonBox::testConstructor3() QDialogButtonBox buttonBox(buttons, (Qt::Orientation)orientation); QCOMPARE(int(buttonBox.orientation()), orientation); - QTEST(int(buttonBox.buttons().count()), "buttonCount"); + QTEST(int(buttonBox.buttons().size()), "buttonCount"); } void tst_QDialogButtonBox::testConstructor4_data() @@ -227,7 +213,7 @@ void tst_QDialogButtonBox::testConstructor4() QDialogButtonBox buttonBox(buttons); QCOMPARE(buttonBox.orientation(), Qt::Horizontal); - QTEST(int(buttonBox.buttons().count()), "buttonCount"); + QTEST(int(buttonBox.buttons().size()), "buttonCount"); } void tst_QDialogButtonBox::setOrientation_data() @@ -290,12 +276,12 @@ void tst_QDialogButtonBox::addButton1() { QFETCH(QDialogButtonBox::ButtonRole, role); QDialogButtonBox buttonBox; - QCOMPARE(buttonBox.buttons().count(), 0); + QCOMPARE(buttonBox.buttons().size(), 0); QPushButton *button = new QPushButton(); buttonBox.addButton(button, role); - QTEST(int(buttonBox.buttons().count()), "totalCount"); + QTEST(int(buttonBox.buttons().size()), "totalCount"); QList<QAbstractButton *> children = buttonBox.findChildren<QAbstractButton *>(); - QTEST(int(children.count()), "totalCount"); + QTEST(int(children.size()), "totalCount"); delete button; } @@ -318,11 +304,11 @@ void tst_QDialogButtonBox::addButton2() QFETCH(QString, text); QFETCH(QDialogButtonBox::ButtonRole, role); QDialogButtonBox buttonBox; - QCOMPARE(buttonBox.buttons().count(), 0); + QCOMPARE(buttonBox.buttons().size(), 0); buttonBox.addButton(text, role); - QTEST(int(buttonBox.buttons().count()), "totalCount"); + QTEST(int(buttonBox.buttons().size()), "totalCount"); QList<QAbstractButton *> children = buttonBox.findChildren<QAbstractButton *>(); - QTEST(int(children.count()), "totalCount"); + QTEST(int(children.size()), "totalCount"); } void tst_QDialogButtonBox::addButton3_data() @@ -345,11 +331,11 @@ void tst_QDialogButtonBox::addButton3() { QFETCH(QDialogButtonBox::StandardButton, button); QDialogButtonBox buttonBox; - QCOMPARE(buttonBox.buttons().count(), 0); + QCOMPARE(buttonBox.buttons().size(), 0); buttonBox.addButton(button); - QTEST(int(buttonBox.buttons().count()), "totalCount"); + QTEST(int(buttonBox.buttons().size()), "totalCount"); QList<QAbstractButton *> children = buttonBox.findChildren<QAbstractButton *>(); - QTEST(int(children.count()), "totalCount"); + QTEST(int(children.size()), "totalCount"); } void tst_QDialogButtonBox::clear_data() @@ -369,9 +355,9 @@ void tst_QDialogButtonBox::clear() for (int i = 1; i < rolesToAdd; ++i) buttonBox.addButton("Happy", QDialogButtonBox::ButtonRole(i)); buttonBox.clear(); - QCOMPARE(buttonBox.buttons().count(), 0); + QCOMPARE(buttonBox.buttons().size(), 0); QList<QAbstractButton *> children = buttonBox.findChildren<QAbstractButton *>(); - QCOMPARE(children.count(), 0); + QCOMPARE(children.size(), 0); } void tst_QDialogButtonBox::removeButton_data() @@ -387,31 +373,95 @@ void tst_QDialogButtonBox::removeButton() QFETCH(QDialogButtonBox::ButtonRole, roleToAdd); QDialogButtonBox buttonBox; - QCOMPARE(buttonBox.buttons().count(), 0); + QCOMPARE(buttonBox.buttons().size(), 0); QPushButton *button = new QPushButton("RemoveButton test"); buttonBox.addButton(button, roleToAdd); - QTEST(int(buttonBox.buttons().count()), "expectedCount"); + QTEST(int(buttonBox.buttons().size()), "expectedCount"); buttonBox.removeButton(button); - QCOMPARE(buttonBox.buttons().count(), 0); + QCOMPARE(buttonBox.buttons().size(), 0); 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; - QCOMPARE(buttonBox.buttons().count(), 0); + QCOMPARE(buttonBox.buttons().size(), 0); QPushButton *deleteMe = new QPushButton("Happy"); buttonBox.addButton(deleteMe, QDialogButtonBox::HelpRole); - QCOMPARE(buttonBox.buttons().count(), 1); + QCOMPARE(buttonBox.buttons().size(), 1); QList<QAbstractButton *> children = buttonBox.findChildren<QAbstractButton *>(); - QCOMPARE(children.count(), 1); + QCOMPARE(children.size(), 1); delete deleteMe; children = buttonBox.findChildren<QAbstractButton *>(); - QCOMPARE(children.count(), 0); - QCOMPARE(buttonBox.buttons().count(), 0); + QCOMPARE(children.size(), 0); + QCOMPARE(buttonBox.buttons().size(), 0); } class ObjectDeleter : public QObject @@ -433,7 +483,7 @@ void tst_QDialogButtonBox::testSignalEmissionAfterDelete_QTBUG_45835() { { QDialogButtonBox buttonBox; - QCOMPARE(buttonBox.buttons().count(), 0); + QCOMPARE(buttonBox.buttons().size(), 0); QSignalSpy buttonClickedSpy(&buttonBox, &QDialogButtonBox::clicked); QVERIFY(buttonClickedSpy.isValid()); @@ -442,21 +492,21 @@ void tst_QDialogButtonBox::testSignalEmissionAfterDelete_QTBUG_45835() QVERIFY(buttonBoxAcceptedSpy.isValid()); QPushButton *button = buttonBox.addButton("Test", QDialogButtonBox::AcceptRole); - QCOMPARE(buttonBox.buttons().count(), 1); + QCOMPARE(buttonBox.buttons().size(), 1); ObjectDeleter objectDeleter; connect(&buttonBox, &QDialogButtonBox::clicked, &objectDeleter, &ObjectDeleter::deleteButton); button->click(); - QCOMPARE(buttonBox.buttons().count(), 0); - QCOMPARE(buttonClickedSpy.count(), 1); - QCOMPARE(buttonBoxAcceptedSpy.count(), 1); + QCOMPARE(buttonBox.buttons().size(), 0); + QCOMPARE(buttonClickedSpy.size(), 1); + QCOMPARE(buttonBoxAcceptedSpy.size(), 1); } { QPointer<QDialogButtonBox> buttonBox(new QDialogButtonBox); - QCOMPARE(buttonBox->buttons().count(), 0); + QCOMPARE(buttonBox->buttons().size(), 0); QSignalSpy buttonClickedSpy(buttonBox.data(), &QDialogButtonBox::clicked); QVERIFY(buttonClickedSpy.isValid()); @@ -465,7 +515,7 @@ void tst_QDialogButtonBox::testSignalEmissionAfterDelete_QTBUG_45835() QVERIFY(buttonBoxAcceptedSpy.isValid()); QPushButton *button = buttonBox->addButton("Test", QDialogButtonBox::AcceptRole); - QCOMPARE(buttonBox->buttons().count(), 1); + QCOMPARE(buttonBox->buttons().size(), 1); ObjectDeleter objectDeleter; connect(buttonBox.data(), &QDialogButtonBox::clicked, &objectDeleter, &ObjectDeleter::deleteSender); @@ -473,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); } } @@ -482,24 +532,24 @@ void tst_QDialogButtonBox::testMultipleAdd() { // Add a button into the thing multiple times. QDialogButtonBox buttonBox; - QCOMPARE(buttonBox.buttons().count(), 0); + QCOMPARE(buttonBox.buttons().size(), 0); QPushButton *button = new QPushButton("Foo away"); buttonBox.addButton(button, QDialogButtonBox::AcceptRole); - QCOMPARE(buttonBox.buttons().count(), 1); + QCOMPARE(buttonBox.buttons().size(), 1); QCOMPARE(buttonBox.buttonRole(button), QDialogButtonBox::AcceptRole); buttonBox.addButton(button, QDialogButtonBox::AcceptRole); - QCOMPARE(buttonBox.buttons().count(), 1); + QCOMPARE(buttonBox.buttons().size(), 1); QCOMPARE(buttonBox.buttonRole(button), QDialogButtonBox::AcceptRole); // Add it again with a different role buttonBox.addButton(button, QDialogButtonBox::RejectRole); - QCOMPARE(buttonBox.buttons().count(), 1); + QCOMPARE(buttonBox.buttons().size(), 1); QCOMPARE(buttonBox.buttonRole(button), QDialogButtonBox::RejectRole); // Add it as an "invalid" role buttonBox.addButton(button, QDialogButtonBox::InvalidRole); - QCOMPARE(buttonBox.buttons().count(), 1); + QCOMPARE(buttonBox.buttons().size(), 1); QCOMPARE(buttonBox.buttonRole(button), QDialogButtonBox::RejectRole); } @@ -619,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() @@ -781,7 +831,7 @@ void tst_QDialogButtonBox::testRemove() button->click(); QTest::qWait(100); - QCOMPARE(clicked.count(), 0); + QCOMPARE(clicked.size(), 0); delete button; } @@ -843,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() @@ -863,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" |