mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-06 17:25:24 +08:00
qt 6.5.1 original
This commit is contained in:
19
tests/auto/widgets/dialogs/CMakeLists.txt
Normal file
19
tests/auto/widgets/dialogs/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
add_subdirectory(qcolordialog)
|
||||
add_subdirectory(qdialog)
|
||||
add_subdirectory(qerrormessage)
|
||||
add_subdirectory(qfiledialog2)
|
||||
add_subdirectory(qfontdialog)
|
||||
add_subdirectory(qinputdialog)
|
||||
add_subdirectory(qprogressdialog)
|
||||
add_subdirectory(qwizard)
|
||||
add_subdirectory(qfiledialog)
|
||||
# QTBUG-101217, qmessagebox hangs on Android
|
||||
if(NOT ANDROID)
|
||||
add_subdirectory(qmessagebox)
|
||||
endif()
|
||||
if(QT_FEATURE_private_tests)
|
||||
add_subdirectory(qsidebar)
|
||||
endif()
|
14
tests/auto/widgets/dialogs/qcolordialog/CMakeLists.txt
Normal file
14
tests/auto/widgets/dialogs/qcolordialog/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qcolordialog Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qcolordialog
|
||||
SOURCES
|
||||
tst_qcolordialog.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
183
tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp
Normal file
183
tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
#include <QtGui/QtGui>
|
||||
#include <QtWidgets/QColorDialog>
|
||||
#include <QtWidgets/QLineEdit>
|
||||
#include <QSignalSpy>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QtTestEventThread)
|
||||
|
||||
class tst_QColorDialog : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
tst_QColorDialog();
|
||||
virtual ~tst_QColorDialog();
|
||||
|
||||
public slots:
|
||||
void postKeyReturn();
|
||||
void testGetRgba();
|
||||
void testNativeActiveModalWidget();
|
||||
|
||||
private slots:
|
||||
void defaultOkButton();
|
||||
void native_activeModalWidget();
|
||||
void task247349_alpha();
|
||||
void QTBUG_43548_initialColor();
|
||||
void hexColor_data();
|
||||
void hexColor();
|
||||
};
|
||||
|
||||
class TestNativeDialog : public QColorDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QWidget *m_activeModalWidget;
|
||||
|
||||
TestNativeDialog(QWidget *parent = nullptr)
|
||||
: QColorDialog(parent), m_activeModalWidget(0)
|
||||
{
|
||||
QTimer::singleShot(1, this, SLOT(test_activeModalWidgetSignal()));
|
||||
}
|
||||
|
||||
public slots:
|
||||
void test_activeModalWidgetSignal()
|
||||
{
|
||||
m_activeModalWidget = qApp->activeModalWidget();
|
||||
}
|
||||
};
|
||||
|
||||
tst_QColorDialog::tst_QColorDialog()
|
||||
{
|
||||
}
|
||||
|
||||
tst_QColorDialog::~tst_QColorDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QColorDialog::testNativeActiveModalWidget()
|
||||
{
|
||||
// Check that QApplication::activeModalWidget retruns the
|
||||
// color dialog when it is executing, even when using a native
|
||||
// dialog:
|
||||
#if defined(Q_OS_LINUX)
|
||||
QSKIP("This test crashes sometimes. Although rarely, but it happens. See QTBUG-50842.");
|
||||
#endif
|
||||
TestNativeDialog d;
|
||||
QTimer::singleShot(1000, &d, SLOT(hide()));
|
||||
d.exec();
|
||||
QCOMPARE(&d, d.m_activeModalWidget);
|
||||
}
|
||||
|
||||
void tst_QColorDialog::native_activeModalWidget()
|
||||
{
|
||||
QTimer::singleShot(3000, qApp, SLOT(quit()));
|
||||
QTimer::singleShot(0, this, SLOT(testNativeActiveModalWidget()));
|
||||
qApp->exec();
|
||||
}
|
||||
|
||||
void tst_QColorDialog::postKeyReturn() {
|
||||
QWidgetList list = QApplication::topLevelWidgets();
|
||||
for (int i=0; i<list.size(); ++i) {
|
||||
QColorDialog *dialog = qobject_cast<QColorDialog *>(list[i]);
|
||||
if (dialog) {
|
||||
QTest::keyClick( list[i], Qt::Key_Return, Qt::NoModifier );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QColorDialog::testGetRgba()
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
QEXPECT_FAIL("", "Sending QTest::keyClick to OSX color dialog helper fails, see QTBUG-24320", Continue);
|
||||
#endif
|
||||
QTimer::singleShot(500, this, &tst_QColorDialog::postKeyReturn);
|
||||
const QColor color = QColorDialog::getColor(QColor::fromRgba(0xffffffff), nullptr, QString(),
|
||||
QColorDialog::ShowAlphaChannel);
|
||||
QVERIFY(color.isValid());
|
||||
}
|
||||
|
||||
void tst_QColorDialog::defaultOkButton()
|
||||
{
|
||||
#if defined(Q_OS_LINUX)
|
||||
QSKIP("This test crashes sometimes. Although rarely, but it happens. See QTBUG-50842.");
|
||||
#endif
|
||||
QTimer::singleShot(4000, qApp, SLOT(quit()));
|
||||
QTimer::singleShot(0, this, SLOT(testGetRgba()));
|
||||
qApp->exec();
|
||||
}
|
||||
|
||||
void tst_QColorDialog::task247349_alpha()
|
||||
{
|
||||
QColorDialog dialog;
|
||||
dialog.setOption(QColorDialog::ShowAlphaChannel, true);
|
||||
int alpha = 0x17;
|
||||
dialog.setCurrentColor(QColor(0x01, 0x02, 0x03, alpha));
|
||||
QCOMPARE(alpha, dialog.currentColor().alpha());
|
||||
QCOMPARE(alpha, qAlpha(dialog.currentColor().rgba()));
|
||||
}
|
||||
|
||||
void tst_QColorDialog::QTBUG_43548_initialColor()
|
||||
{
|
||||
QColorDialog dialog;
|
||||
dialog.setOption(QColorDialog::DontUseNativeDialog);
|
||||
dialog.setCurrentColor(QColor(Qt::red));
|
||||
QColor a(Qt::red);
|
||||
QCOMPARE(a, dialog.currentColor());
|
||||
}
|
||||
|
||||
void tst_QColorDialog::hexColor_data()
|
||||
{
|
||||
QTest::addColumn<const QString>("colorString");
|
||||
QTest::addColumn<const QString>("expectedHexColor");
|
||||
QTest::addColumn<const int>("expectedSignalCount");
|
||||
|
||||
QTest::newRow("White-#") << "#FFFFFE" << "#FFFFFE" << 1;
|
||||
QTest::newRow("White") << "FFFFFD" << "#FFFFFD" << 1;
|
||||
QTest::newRow("Blue-#") << "#77fffb" << "#77fffb" << 2;
|
||||
QTest::newRow("Blue") << "77fffa" << "#77fffa" << 2;
|
||||
}
|
||||
|
||||
void tst_QColorDialog::hexColor()
|
||||
{
|
||||
QColorDialog dialog;
|
||||
dialog.setOption(QColorDialog::DontUseNativeDialog);
|
||||
dialog.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
||||
|
||||
QLineEdit *lineEdit = dialog.findChild<QLineEdit *>("qt_colorname_lineedit",
|
||||
Qt::FindChildrenRecursively);
|
||||
QVERIFY2(lineEdit, "QLineEdit for color not found. Adapt this test.");
|
||||
QVERIFY(lineEdit); // eliminate compiler warning
|
||||
|
||||
QFETCH(const QString, colorString);
|
||||
QFETCH(const QString, expectedHexColor);
|
||||
QFETCH(const int, expectedSignalCount);
|
||||
|
||||
QSignalSpy spy(&dialog, &QColorDialog::currentColorChanged);
|
||||
|
||||
// Delete existing color
|
||||
lineEdit->activateWindow();
|
||||
QVERIFY(QTest::qWaitForWindowActive(lineEdit));
|
||||
for (int i = 0; i < 8; ++i)
|
||||
QTest::keyEvent(QTest::KeyAction::Click, lineEdit, Qt::Key_Backspace);
|
||||
QVERIFY(lineEdit->text().isEmpty());
|
||||
|
||||
// Enter new color
|
||||
for (const QChar &key : colorString)
|
||||
QTest::keyEvent(QTest::KeyAction::Click, lineEdit, key.toLatin1());
|
||||
QCOMPARE(lineEdit->text().toLower(), expectedHexColor.toLower());
|
||||
|
||||
// Consume all color change signals
|
||||
QTRY_COMPARE(spy.count(), expectedSignalCount);
|
||||
|
||||
const QColor color = qvariant_cast<QColor>(spy.last().at(0));
|
||||
QCOMPARE(color.name(QColor::HexRgb), expectedHexColor.toLower());
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QColorDialog)
|
||||
#include "tst_qcolordialog.moc"
|
4
tests/auto/widgets/dialogs/qdialog/BLACKLIST
Normal file
4
tests/auto/widgets/dialogs/qdialog/BLACKLIST
Normal file
@ -0,0 +1,4 @@
|
||||
[snapToDefaultButton]
|
||||
macos
|
||||
[showFullScreen]
|
||||
macos ci
|
17
tests/auto/widgets/dialogs/qdialog/CMakeLists.txt
Normal file
17
tests/auto/widgets/dialogs/qdialog/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qdialog Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qdialog
|
||||
SOURCES
|
||||
tst_qdialog.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
772
tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp
Normal file
772
tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp
Normal file
@ -0,0 +1,772 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "../../../shared/highdpi.h"
|
||||
|
||||
#include <QTest>
|
||||
#include <QTestEventLoop>
|
||||
|
||||
#include <qdialog.h>
|
||||
#include <qapplication.h>
|
||||
#include <qlineedit.h>
|
||||
#include <qpushbutton.h>
|
||||
#include <qstyle.h>
|
||||
#include <QVBoxLayout>
|
||||
#include <QSignalSpy>
|
||||
#include <QSizeGrip>
|
||||
#include <QTimer>
|
||||
#include <QGraphicsProxyWidget>
|
||||
#include <QGraphicsView>
|
||||
#include <QWindow>
|
||||
#include <private/qguiapplication_p.h>
|
||||
#include <qpa/qplatformtheme.h>
|
||||
#include <qpa/qplatformtheme_p.h>
|
||||
|
||||
#include <QtWidgets/private/qapplication_p.h>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QDialog)
|
||||
|
||||
// work around function being protected
|
||||
class DummyDialog : public QDialog
|
||||
{
|
||||
public:
|
||||
DummyDialog(): QDialog() {}
|
||||
};
|
||||
|
||||
class tst_QDialog : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
tst_QDialog();
|
||||
|
||||
private slots:
|
||||
void cleanup();
|
||||
void getSetCheck();
|
||||
void defaultButtons();
|
||||
void showMaximized();
|
||||
void showMinimized();
|
||||
void showFullScreen();
|
||||
void showAsTool();
|
||||
void showWithoutActivating_data();
|
||||
void showWithoutActivating();
|
||||
void toolDialogPosition();
|
||||
void deleteMainDefault();
|
||||
void deleteInExec();
|
||||
#if QT_CONFIG(sizegrip)
|
||||
void showSizeGrip();
|
||||
#endif
|
||||
void setVisible();
|
||||
void reject();
|
||||
void snapToDefaultButton();
|
||||
void transientParent_data();
|
||||
void transientParent();
|
||||
void dialogInGraphicsView();
|
||||
void keepPositionOnClose();
|
||||
void virtualsOnClose();
|
||||
void deleteOnDone();
|
||||
void quitOnDone();
|
||||
void focusWidgetAfterOpen();
|
||||
};
|
||||
|
||||
// Testing get/set functions
|
||||
void tst_QDialog::getSetCheck()
|
||||
{
|
||||
QDialog obj1;
|
||||
// int QDialog::result()
|
||||
// void QDialog::setResult(int)
|
||||
obj1.setResult(0);
|
||||
QCOMPARE(0, obj1.result());
|
||||
obj1.setResult(INT_MIN);
|
||||
QCOMPARE(INT_MIN, obj1.result());
|
||||
obj1.setResult(INT_MAX);
|
||||
QCOMPARE(INT_MAX, obj1.result());
|
||||
}
|
||||
|
||||
class ToolDialog : public QDialog
|
||||
{
|
||||
public:
|
||||
ToolDialog(QWidget *parent = nullptr)
|
||||
: QDialog(parent, Qt::Tool), mWasActive(false), mWasModalWindow(false), tId(-1) {}
|
||||
|
||||
bool wasActive() const { return mWasActive; }
|
||||
bool wasModalWindow() const { return mWasModalWindow; }
|
||||
|
||||
int exec() override
|
||||
{
|
||||
tId = startTimer(300);
|
||||
return QDialog::exec();
|
||||
}
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *event) override
|
||||
{
|
||||
if (tId == event->timerId()) {
|
||||
killTimer(tId);
|
||||
mWasActive = isActiveWindow();
|
||||
mWasModalWindow = QGuiApplication::modalWindow() == windowHandle();
|
||||
reject();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int mWasActive;
|
||||
bool mWasModalWindow;
|
||||
int tId;
|
||||
};
|
||||
|
||||
tst_QDialog::tst_QDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QDialog::cleanup()
|
||||
{
|
||||
QVERIFY(QApplication::topLevelWidgets().isEmpty());
|
||||
}
|
||||
|
||||
|
||||
void tst_QDialog::defaultButtons()
|
||||
{
|
||||
DummyDialog testWidget;
|
||||
testWidget.resize(200, 200);
|
||||
testWidget.setWindowTitle(QTest::currentTestFunction());
|
||||
QLineEdit *lineEdit = new QLineEdit(&testWidget);
|
||||
QPushButton *push = new QPushButton("Button 1", &testWidget);
|
||||
QPushButton *pushTwo = new QPushButton("Button 2", &testWidget);
|
||||
QPushButton *pushThree = new QPushButton("Button 3", &testWidget);
|
||||
pushThree->setAutoDefault(false);
|
||||
|
||||
testWidget.show();
|
||||
QApplicationPrivate::setActiveWindow(&testWidget);
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&testWidget));
|
||||
|
||||
push->setDefault(true);
|
||||
QVERIFY(push->isDefault());
|
||||
|
||||
pushTwo->setFocus();
|
||||
QVERIFY(pushTwo->isDefault());
|
||||
pushThree->setFocus();
|
||||
QVERIFY(push->isDefault());
|
||||
lineEdit->setFocus();
|
||||
QVERIFY(push->isDefault());
|
||||
|
||||
pushTwo->setDefault(true);
|
||||
QVERIFY(pushTwo->isDefault());
|
||||
|
||||
pushTwo->setFocus();
|
||||
QVERIFY(pushTwo->isDefault());
|
||||
lineEdit->setFocus();
|
||||
QVERIFY(pushTwo->isDefault());
|
||||
}
|
||||
|
||||
void tst_QDialog::showMaximized()
|
||||
{
|
||||
QDialog dialog(0);
|
||||
dialog.setSizeGripEnabled(true);
|
||||
#if QT_CONFIG(sizegrip)
|
||||
QSizeGrip *sizeGrip = dialog.findChild<QSizeGrip *>();
|
||||
QVERIFY(sizeGrip);
|
||||
#endif
|
||||
|
||||
dialog.showMaximized();
|
||||
QVERIFY(dialog.isMaximized());
|
||||
QVERIFY(dialog.isVisible());
|
||||
#if QT_CONFIG(sizegrip) && !defined(Q_OS_DARWIN) && !defined(Q_OS_HPUX)
|
||||
QVERIFY(!sizeGrip->isVisible());
|
||||
#endif
|
||||
|
||||
dialog.showNormal();
|
||||
QVERIFY(!dialog.isMaximized());
|
||||
QVERIFY(dialog.isVisible());
|
||||
#if QT_CONFIG(sizegrip)
|
||||
QVERIFY(sizeGrip->isVisible());
|
||||
#endif
|
||||
|
||||
dialog.showMaximized();
|
||||
QVERIFY(dialog.isMaximized());
|
||||
QVERIFY(dialog.isVisible());
|
||||
|
||||
dialog.hide();
|
||||
QVERIFY(dialog.isMaximized());
|
||||
QVERIFY(!dialog.isVisible());
|
||||
|
||||
dialog.setVisible(true);
|
||||
QVERIFY(dialog.isMaximized());
|
||||
QVERIFY(dialog.isVisible());
|
||||
|
||||
dialog.hide();
|
||||
QVERIFY(dialog.isMaximized());
|
||||
QVERIFY(!dialog.isVisible());
|
||||
|
||||
dialog.showMaximized();
|
||||
QVERIFY(dialog.isMaximized());
|
||||
QVERIFY(dialog.isVisible());
|
||||
}
|
||||
|
||||
void tst_QDialog::showMinimized()
|
||||
{
|
||||
QDialog dialog(0);
|
||||
|
||||
dialog.showMinimized();
|
||||
QVERIFY(dialog.isMinimized());
|
||||
QVERIFY(dialog.isVisible());
|
||||
|
||||
dialog.showNormal();
|
||||
QVERIFY(!dialog.isMinimized());
|
||||
QVERIFY(dialog.isVisible());
|
||||
|
||||
dialog.showMinimized();
|
||||
QVERIFY(dialog.isMinimized());
|
||||
QVERIFY(dialog.isVisible());
|
||||
|
||||
dialog.hide();
|
||||
QVERIFY(dialog.isMinimized());
|
||||
QVERIFY(!dialog.isVisible());
|
||||
|
||||
dialog.setVisible(true);
|
||||
QVERIFY(dialog.isMinimized());
|
||||
QVERIFY(dialog.isVisible());
|
||||
|
||||
dialog.hide();
|
||||
QVERIFY(dialog.isMinimized());
|
||||
QVERIFY(!dialog.isVisible());
|
||||
|
||||
dialog.showMinimized();
|
||||
QVERIFY(dialog.isMinimized());
|
||||
QVERIFY(dialog.isVisible());
|
||||
}
|
||||
|
||||
void tst_QDialog::showFullScreen()
|
||||
{
|
||||
QDialog dialog(0, Qt::X11BypassWindowManagerHint);
|
||||
dialog.setSizeGripEnabled(true);
|
||||
#if QT_CONFIG(sizegrip)
|
||||
QSizeGrip *sizeGrip = dialog.findChild<QSizeGrip *>();
|
||||
QVERIFY(sizeGrip);
|
||||
#endif
|
||||
|
||||
dialog.showFullScreen();
|
||||
QVERIFY(dialog.isFullScreen());
|
||||
QVERIFY(dialog.isVisible());
|
||||
#if QT_CONFIG(sizegrip)
|
||||
QVERIFY(!sizeGrip->isVisible());
|
||||
#endif
|
||||
|
||||
dialog.showNormal();
|
||||
QVERIFY(!dialog.isFullScreen());
|
||||
QVERIFY(dialog.isVisible());
|
||||
#if QT_CONFIG(sizegrip)
|
||||
QVERIFY(sizeGrip->isVisible());
|
||||
#endif
|
||||
|
||||
dialog.showFullScreen();
|
||||
QVERIFY(dialog.isFullScreen());
|
||||
QVERIFY(dialog.isVisible());
|
||||
|
||||
dialog.hide();
|
||||
QVERIFY(dialog.isFullScreen());
|
||||
QVERIFY(!dialog.isVisible());
|
||||
|
||||
dialog.setVisible(true);
|
||||
QVERIFY(dialog.isFullScreen());
|
||||
QVERIFY(dialog.isVisible());
|
||||
|
||||
dialog.hide();
|
||||
QVERIFY(dialog.isFullScreen());
|
||||
QVERIFY(!dialog.isVisible());
|
||||
|
||||
dialog.showFullScreen();
|
||||
QVERIFY(dialog.isFullScreen());
|
||||
QVERIFY(dialog.isVisible());
|
||||
|
||||
dialog.hide();
|
||||
QVERIFY(dialog.isFullScreen());
|
||||
QVERIFY(!dialog.isVisible());
|
||||
}
|
||||
|
||||
void tst_QDialog::showAsTool()
|
||||
{
|
||||
if (QStringList{"xcb", "offscreen"}.contains(QGuiApplication::platformName()))
|
||||
QSKIP("activeWindow() is not respected by all Xcb window managers and the offscreen plugin");
|
||||
|
||||
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))
|
||||
QSKIP("QWindow::requestActivate() is not supported.");
|
||||
|
||||
DummyDialog testWidget;
|
||||
testWidget.resize(200, 200);
|
||||
testWidget.setWindowTitle(QTest::currentTestFunction());
|
||||
ToolDialog dialog(&testWidget);
|
||||
testWidget.show();
|
||||
testWidget.activateWindow();
|
||||
QVERIFY(QTest::qWaitForWindowActive(&testWidget));
|
||||
dialog.exec();
|
||||
if (testWidget.style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, &testWidget)) {
|
||||
QCOMPARE(dialog.wasActive(), true);
|
||||
} else {
|
||||
QCOMPARE(dialog.wasActive(), false);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QDialog::showWithoutActivating_data()
|
||||
{
|
||||
QTest::addColumn<bool>("showWithoutActivating");
|
||||
QTest::addColumn<int>("focusInCount");
|
||||
|
||||
QTest::addRow("showWithoutActivating") << true << 0;
|
||||
QTest::addRow("showWithActivating") << false << 1;
|
||||
}
|
||||
|
||||
void tst_QDialog::showWithoutActivating()
|
||||
{
|
||||
QFETCH(bool, showWithoutActivating);
|
||||
QFETCH(int, focusInCount);
|
||||
|
||||
struct Dialog : public QDialog
|
||||
{
|
||||
int focusInCount = 0;
|
||||
protected:
|
||||
void focusInEvent(QFocusEvent *) override { ++focusInCount; }
|
||||
} dialog;
|
||||
dialog.setAttribute(Qt::WA_ShowWithoutActivating, showWithoutActivating);
|
||||
|
||||
dialog.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
||||
QCOMPARE(dialog.focusInCount, focusInCount);
|
||||
}
|
||||
|
||||
// Verify that pos() returns the same before and after show()
|
||||
// for a dialog with the Tool window type.
|
||||
void tst_QDialog::toolDialogPosition()
|
||||
{
|
||||
QDialog dialog(0, Qt::Tool);
|
||||
dialog.move(QPoint(100,100));
|
||||
const QPoint beforeShowPosition = dialog.pos();
|
||||
dialog.show();
|
||||
const int fuzz = int(dialog.devicePixelRatio());
|
||||
const QPoint afterShowPosition = dialog.pos();
|
||||
QVERIFY2(HighDpi::fuzzyCompare(afterShowPosition, beforeShowPosition, fuzz),
|
||||
HighDpi::msgPointMismatch(afterShowPosition, beforeShowPosition).constData());
|
||||
}
|
||||
|
||||
class Dialog : public QDialog
|
||||
{
|
||||
public:
|
||||
Dialog(QPushButton *&button)
|
||||
{
|
||||
button = new QPushButton(this);
|
||||
}
|
||||
};
|
||||
|
||||
void tst_QDialog::deleteMainDefault()
|
||||
{
|
||||
QPushButton *button;
|
||||
Dialog dialog(button);
|
||||
button->setDefault(true);
|
||||
delete button;
|
||||
dialog.show();
|
||||
QTestEventLoop::instance().enterLoop(2);
|
||||
}
|
||||
|
||||
void tst_QDialog::deleteInExec()
|
||||
{
|
||||
QDialog *dialog = new QDialog(0);
|
||||
QMetaObject::invokeMethod(dialog, "deleteLater", Qt::QueuedConnection);
|
||||
QCOMPARE(dialog->exec(), int(QDialog::Rejected));
|
||||
}
|
||||
|
||||
#if QT_CONFIG(sizegrip)
|
||||
|
||||
void tst_QDialog::showSizeGrip()
|
||||
{
|
||||
QDialog dialog(nullptr);
|
||||
dialog.show();
|
||||
new QWidget(&dialog);
|
||||
QVERIFY(!dialog.isSizeGripEnabled());
|
||||
|
||||
dialog.setSizeGripEnabled(true);
|
||||
QPointer<QSizeGrip> sizeGrip = dialog.findChild<QSizeGrip *>();
|
||||
QVERIFY(sizeGrip);
|
||||
QVERIFY(sizeGrip->isVisible());
|
||||
QVERIFY(dialog.isSizeGripEnabled());
|
||||
|
||||
dialog.setSizeGripEnabled(false);
|
||||
QVERIFY(!dialog.isSizeGripEnabled());
|
||||
|
||||
dialog.setSizeGripEnabled(true);
|
||||
sizeGrip = dialog.findChild<QSizeGrip *>();
|
||||
QVERIFY(sizeGrip);
|
||||
QVERIFY(sizeGrip->isVisible());
|
||||
sizeGrip->hide();
|
||||
dialog.hide();
|
||||
dialog.show();
|
||||
QVERIFY(!sizeGrip->isVisible());
|
||||
}
|
||||
|
||||
#endif // QT_CONFIG(sizegrip)
|
||||
|
||||
void tst_QDialog::setVisible()
|
||||
{
|
||||
QWidget topLevel;
|
||||
topLevel.show();
|
||||
|
||||
QDialog *dialog = new QDialog;
|
||||
dialog->setLayout(new QVBoxLayout);
|
||||
dialog->layout()->addWidget(new QPushButton("dialog button"));
|
||||
|
||||
QWidget *widget = new QWidget(&topLevel);
|
||||
widget->setLayout(new QVBoxLayout);
|
||||
widget->layout()->addWidget(dialog);
|
||||
|
||||
QVERIFY(!dialog->isVisible());
|
||||
QVERIFY(!dialog->isHidden());
|
||||
|
||||
widget->show();
|
||||
QVERIFY(dialog->isVisible());
|
||||
QVERIFY(!dialog->isHidden());
|
||||
|
||||
widget->hide();
|
||||
dialog->hide();
|
||||
widget->show();
|
||||
QVERIFY(!dialog->isVisible());
|
||||
QVERIFY(dialog->isHidden());
|
||||
}
|
||||
|
||||
class TestRejectDialog : public QDialog
|
||||
{
|
||||
public:
|
||||
TestRejectDialog() : cancelReject(false), called(0) {}
|
||||
void reject() override
|
||||
{
|
||||
called++;
|
||||
if (!cancelReject)
|
||||
QDialog::reject();
|
||||
}
|
||||
bool cancelReject;
|
||||
int called;
|
||||
};
|
||||
|
||||
void tst_QDialog::reject()
|
||||
{
|
||||
TestRejectDialog dialog;
|
||||
dialog.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
||||
QVERIFY(dialog.isVisible());
|
||||
dialog.reject();
|
||||
QTRY_VERIFY(!dialog.isVisible());
|
||||
QCOMPARE(dialog.called, 1);
|
||||
|
||||
dialog.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
||||
QVERIFY(dialog.isVisible());
|
||||
QVERIFY(dialog.close());
|
||||
QTRY_VERIFY(!dialog.isVisible());
|
||||
QCOMPARE(dialog.called, 2);
|
||||
|
||||
dialog.cancelReject = true;
|
||||
dialog.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
||||
QVERIFY(dialog.isVisible());
|
||||
dialog.reject();
|
||||
QTRY_VERIFY(dialog.isVisible());
|
||||
QCOMPARE(dialog.called, 3);
|
||||
QVERIFY(!dialog.close());
|
||||
QTRY_VERIFY(dialog.isVisible());
|
||||
QCOMPARE(dialog.called, 4);
|
||||
}
|
||||
|
||||
static QByteArray formatPoint(QPoint p)
|
||||
{
|
||||
return QByteArray::number(p.x()) + ", " + QByteArray::number(p.y());
|
||||
}
|
||||
|
||||
void tst_QDialog::snapToDefaultButton()
|
||||
{
|
||||
#ifdef QT_NO_CURSOR
|
||||
QSKIP("Test relies on there being a cursor");
|
||||
#else
|
||||
if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive))
|
||||
QSKIP("This platform does not support setting the cursor position.");
|
||||
#ifdef Q_OS_ANDROID
|
||||
QSKIP("Android does not support cursor");
|
||||
#endif
|
||||
|
||||
const QRect dialogGeometry(QGuiApplication::primaryScreen()->availableGeometry().topLeft()
|
||||
+ QPoint(100, 100), QSize(200, 200));
|
||||
const QPoint startingPos = dialogGeometry.bottomRight() + QPoint(100, 100);
|
||||
QCursor::setPos(startingPos);
|
||||
#ifdef Q_OS_MACOS
|
||||
// On OS X we use CGEventPost to move the cursor, it needs at least
|
||||
// some time before the event handled and the position really set.
|
||||
QTest::qWait(100);
|
||||
#endif
|
||||
QCOMPARE(QCursor::pos(), startingPos);
|
||||
QDialog dialog;
|
||||
QPushButton *button = new QPushButton(&dialog);
|
||||
button->setDefault(true);
|
||||
dialog.setGeometry(dialogGeometry);
|
||||
dialog.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
||||
const QPoint localPos = button->mapFromGlobal(QCursor::pos());
|
||||
if (QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::DialogSnapToDefaultButton).toBool())
|
||||
QVERIFY2(button->rect().contains(localPos), formatPoint(localPos).constData());
|
||||
else
|
||||
QVERIFY2(!button->rect().contains(localPos), formatPoint(localPos).constData());
|
||||
#endif // !QT_NO_CURSOR
|
||||
}
|
||||
|
||||
void tst_QDialog::transientParent_data()
|
||||
{
|
||||
QTest::addColumn<bool>("nativewidgets");
|
||||
QTest::newRow("Non-native") << false;
|
||||
QTest::newRow("Native") << true;
|
||||
}
|
||||
|
||||
void tst_QDialog::transientParent()
|
||||
{
|
||||
QFETCH(bool, nativewidgets);
|
||||
QWidget topLevel;
|
||||
topLevel.resize(200, 200);
|
||||
topLevel.move(QGuiApplication::primaryScreen()->availableGeometry().center() - QPoint(100, 100));
|
||||
QVBoxLayout *layout = new QVBoxLayout(&topLevel);
|
||||
QWidget *innerWidget = new QWidget(&topLevel);
|
||||
layout->addWidget(innerWidget);
|
||||
if (nativewidgets)
|
||||
innerWidget->winId();
|
||||
topLevel.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&topLevel));
|
||||
QDialog dialog(innerWidget);
|
||||
dialog.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
||||
// Transient parent should always be the top level, also when using
|
||||
// native child widgets.
|
||||
QCOMPARE(dialog.windowHandle()->transientParent(), topLevel.windowHandle());
|
||||
}
|
||||
|
||||
void tst_QDialog::dialogInGraphicsView()
|
||||
{
|
||||
// QTBUG-49124: A dialog embedded into QGraphicsView has Qt::WA_DontShowOnScreen
|
||||
// set (as has a native dialog). It must not trigger the modal handling though
|
||||
// as not to lock up.
|
||||
QGraphicsScene scene;
|
||||
QGraphicsView view(&scene);
|
||||
view.setWindowTitle(QTest::currentTestFunction());
|
||||
const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
|
||||
view.resize(availableGeometry.size() / 2);
|
||||
view.move(availableGeometry.left() + availableGeometry.width() / 4,
|
||||
availableGeometry.top() + availableGeometry.height() / 4);
|
||||
ToolDialog *dialog = new ToolDialog;
|
||||
scene.addWidget(dialog);
|
||||
view.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&view));
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
dialog->exec();
|
||||
QVERIFY(!dialog->wasModalWindow());
|
||||
}
|
||||
}
|
||||
|
||||
// QTBUG-79147 (Windows): Closing a dialog by clicking the 'X' in the title
|
||||
// bar would offset the dialog position when shown next time.
|
||||
void tst_QDialog::keepPositionOnClose()
|
||||
{
|
||||
QDialog dialog;
|
||||
dialog.setWindowTitle(QTest::currentTestFunction());
|
||||
const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
|
||||
dialog.resize(availableGeometry.size() / 4);
|
||||
QPoint pos = availableGeometry.topLeft() + QPoint(100, 100);
|
||||
dialog.move(pos);
|
||||
dialog.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
||||
pos = dialog.pos();
|
||||
dialog.close();
|
||||
dialog.windowHandle()->destroy(); // Emulate a click on close by destroying the window.
|
||||
QTest::qWait(50);
|
||||
dialog.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
||||
QTest::qWait(50);
|
||||
QCOMPARE(dialog.pos(), pos);
|
||||
}
|
||||
|
||||
/*!
|
||||
Verify that the virtual functions related to closing a dialog are
|
||||
called exactly once, no matter how the dialog gets closed.
|
||||
*/
|
||||
void tst_QDialog::virtualsOnClose()
|
||||
{
|
||||
class Dialog : public QDialog
|
||||
{
|
||||
public:
|
||||
using QDialog::QDialog;
|
||||
int closeEventCount = 0;
|
||||
int acceptCount = 0;
|
||||
int rejectCount = 0;
|
||||
int doneCount = 0;
|
||||
|
||||
void accept() override
|
||||
{
|
||||
++acceptCount;
|
||||
QDialog::accept();
|
||||
}
|
||||
void reject() override
|
||||
{
|
||||
++rejectCount;
|
||||
QDialog::reject();
|
||||
}
|
||||
void done(int result) override
|
||||
{
|
||||
++doneCount;
|
||||
QDialog::done(result);
|
||||
}
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *e) override
|
||||
{
|
||||
++closeEventCount;
|
||||
QDialog::closeEvent(e);
|
||||
}
|
||||
};
|
||||
|
||||
{
|
||||
Dialog dialog;
|
||||
dialog.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
||||
dialog.accept();
|
||||
// we used to only hide the dialog, and we still don't want a
|
||||
// closeEvent call for application-triggered calls to QDialog::done
|
||||
QCOMPARE(dialog.closeEventCount, 0);
|
||||
QCOMPARE(dialog.acceptCount, 1);
|
||||
QCOMPARE(dialog.rejectCount, 0);
|
||||
QCOMPARE(dialog.doneCount, 1);
|
||||
}
|
||||
|
||||
{
|
||||
Dialog dialog;
|
||||
dialog.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
||||
dialog.reject();
|
||||
QCOMPARE(dialog.closeEventCount, 0);
|
||||
QCOMPARE(dialog.acceptCount, 0);
|
||||
QCOMPARE(dialog.rejectCount, 1);
|
||||
QCOMPARE(dialog.doneCount, 1);
|
||||
}
|
||||
|
||||
{
|
||||
Dialog dialog;
|
||||
dialog.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
||||
dialog.close();
|
||||
QCOMPARE(dialog.closeEventCount, 1);
|
||||
QCOMPARE(dialog.acceptCount, 0);
|
||||
QCOMPARE(dialog.rejectCount, 1);
|
||||
QCOMPARE(dialog.doneCount, 1);
|
||||
}
|
||||
|
||||
{
|
||||
// user clicks close button in title bar
|
||||
Dialog dialog;
|
||||
dialog.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
||||
QWindowSystemInterface::handleCloseEvent(dialog.windowHandle());
|
||||
QApplication::processEvents();
|
||||
QCOMPARE(dialog.closeEventCount, 1);
|
||||
QCOMPARE(dialog.acceptCount, 0);
|
||||
QCOMPARE(dialog.rejectCount, 1);
|
||||
QCOMPARE(dialog.doneCount, 1);
|
||||
}
|
||||
|
||||
{
|
||||
struct EventFilter : QObject {
|
||||
EventFilter(Dialog *dialog)
|
||||
{ dialog->installEventFilter(this); }
|
||||
int closeEventCount = 0;
|
||||
bool eventFilter(QObject *r, QEvent *e) override
|
||||
{
|
||||
if (e->type() == QEvent::Close) {
|
||||
++closeEventCount;
|
||||
}
|
||||
return QObject::eventFilter(r, e);
|
||||
}
|
||||
};
|
||||
// dialog gets destroyed while shown
|
||||
Dialog *dialog = new Dialog;
|
||||
QSignalSpy rejectedSpy(dialog, &QDialog::rejected);
|
||||
EventFilter filter(dialog);
|
||||
|
||||
dialog->show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(dialog));
|
||||
delete dialog;
|
||||
// Qt doesn't deliver events to QWidgets closed during destruction
|
||||
QCOMPARE(filter.closeEventCount, 0);
|
||||
// QDialog doesn't emit signals when closed by destruction
|
||||
QCOMPARE(rejectedSpy.size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
QDialog::done is documented to respect Qt::WA_DeleteOnClose.
|
||||
*/
|
||||
void tst_QDialog::deleteOnDone()
|
||||
{
|
||||
{
|
||||
std::unique_ptr<QDialog> dialog(new QDialog);
|
||||
QPointer<QDialog> watcher(dialog.get());
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(dialog.get()));
|
||||
|
||||
dialog->accept();
|
||||
QTRY_COMPARE(watcher.isNull(), true);
|
||||
dialog.release(); // if we get here, the dialog is destroyed
|
||||
}
|
||||
|
||||
// it is still safe to delete the dialog explicitly as long as events
|
||||
// have not yet been processed
|
||||
{
|
||||
std::unique_ptr<QDialog> dialog(new QDialog);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(dialog.get()));
|
||||
|
||||
dialog->accept();
|
||||
dialog.reset();
|
||||
QApplication::processEvents();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
QDialog::done is documented to make QApplication emit lastWindowClosed if
|
||||
the dialog was the last window.
|
||||
*/
|
||||
void tst_QDialog::quitOnDone()
|
||||
{
|
||||
QSignalSpy quitSpy(qApp, &QGuiApplication::lastWindowClosed);
|
||||
|
||||
QDialog dialog;
|
||||
dialog.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&dialog));
|
||||
|
||||
// QGuiApplication::lastWindowClosed is documented to only be emitted
|
||||
// when we are in exec()
|
||||
QTimer::singleShot(0, &dialog, &QDialog::accept);
|
||||
// also quit with a timer in case the test fails
|
||||
QTimer::singleShot(1000, QApplication::instance(), &QApplication::quit);
|
||||
QApplication::exec();
|
||||
QCOMPARE(quitSpy.size(), 1);
|
||||
}
|
||||
|
||||
void tst_QDialog::focusWidgetAfterOpen()
|
||||
{
|
||||
QDialog dialog;
|
||||
dialog.setLayout(new QVBoxLayout);
|
||||
|
||||
QPushButton *pb1 = new QPushButton;
|
||||
QPushButton *pb2 = new QPushButton;
|
||||
dialog.layout()->addWidget(pb1);
|
||||
dialog.layout()->addWidget(pb2);
|
||||
|
||||
pb2->setFocus();
|
||||
QCOMPARE(dialog.focusWidget(), static_cast<QWidget *>(pb2));
|
||||
|
||||
dialog.open();
|
||||
QCOMPARE(dialog.focusWidget(), static_cast<QWidget *>(pb2));
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QDialog)
|
||||
#include "tst_qdialog.moc"
|
15
tests/auto/widgets/dialogs/qerrormessage/CMakeLists.txt
Normal file
15
tests/auto/widgets/dialogs/qerrormessage/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qerrormessage Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qerrormessage
|
||||
SOURCES
|
||||
tst_qerrormessage.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
)
|
150
tests/auto/widgets/dialogs/qerrormessage/tst_qerrormessage.cpp
Normal file
150
tests/auto/widgets/dialogs/qerrormessage/tst_qerrormessage.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
#include <QTest>
|
||||
#include <QErrorMessage>
|
||||
#include <QDebug>
|
||||
#include <QCheckBox>
|
||||
|
||||
#include <qpa/qplatformtheme.h>
|
||||
#include <private/qguiapplication_p.h>
|
||||
|
||||
class tst_QErrorMessage : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase_data();
|
||||
void init();
|
||||
|
||||
void dontShowAgain();
|
||||
void dontShowCategoryAgain();
|
||||
void baseClassSetVisible();
|
||||
|
||||
};
|
||||
|
||||
void tst_QErrorMessage::initTestCase_data()
|
||||
{
|
||||
QTest::addColumn<bool>("useNativeDialog");
|
||||
QTest::newRow("widget") << false;
|
||||
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
|
||||
if (theme->usePlatformNativeDialog(QPlatformTheme::MessageDialog))
|
||||
QTest::newRow("native") << true;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QErrorMessage::init()
|
||||
{
|
||||
QFETCH_GLOBAL(bool, useNativeDialog);
|
||||
qApp->setAttribute(Qt::AA_DontUseNativeDialogs, !useNativeDialog);
|
||||
}
|
||||
|
||||
void tst_QErrorMessage::dontShowAgain()
|
||||
{
|
||||
QString plainString = QLatin1String("foo");
|
||||
QString htmlString = QLatin1String("foo<br>bar");
|
||||
QCheckBox *checkBox = nullptr;
|
||||
|
||||
QErrorMessage errorMessageDialog(0);
|
||||
|
||||
// show an error with plain string
|
||||
errorMessageDialog.showMessage(plainString);
|
||||
QVERIFY(errorMessageDialog.isVisible());
|
||||
checkBox = errorMessageDialog.findChild<QCheckBox*>();
|
||||
QVERIFY(checkBox);
|
||||
QVERIFY(checkBox->isChecked());
|
||||
errorMessageDialog.close();
|
||||
|
||||
errorMessageDialog.showMessage(plainString);
|
||||
QVERIFY(errorMessageDialog.isVisible());
|
||||
checkBox = errorMessageDialog.findChild<QCheckBox*>();
|
||||
QVERIFY(checkBox);
|
||||
QVERIFY(checkBox->isChecked());
|
||||
checkBox->setChecked(false);
|
||||
errorMessageDialog.close();
|
||||
|
||||
errorMessageDialog.showMessage(plainString);
|
||||
QVERIFY(!errorMessageDialog.isVisible());
|
||||
|
||||
// show an error with an html string
|
||||
errorMessageDialog.showMessage(htmlString);
|
||||
QVERIFY(errorMessageDialog.isVisible());
|
||||
checkBox = errorMessageDialog.findChild<QCheckBox*>();
|
||||
QVERIFY(checkBox);
|
||||
QVERIFY(checkBox->isChecked());
|
||||
errorMessageDialog.close();
|
||||
|
||||
errorMessageDialog.showMessage(htmlString);
|
||||
QVERIFY(errorMessageDialog.isVisible());
|
||||
checkBox = errorMessageDialog.findChild<QCheckBox*>();
|
||||
QVERIFY(checkBox);
|
||||
QVERIFY(checkBox->isChecked());
|
||||
checkBox->setChecked(false);
|
||||
errorMessageDialog.close();
|
||||
|
||||
errorMessageDialog.showMessage(htmlString);
|
||||
QVERIFY(!errorMessageDialog.isVisible());
|
||||
}
|
||||
|
||||
void tst_QErrorMessage::dontShowCategoryAgain()
|
||||
{
|
||||
QString htmlString = QLatin1String("foo<br>bar");
|
||||
QString htmlString2 = QLatin1String("foo2<br>bar2");
|
||||
QCheckBox *checkBox = nullptr;
|
||||
|
||||
QErrorMessage errorMessageDialog(0);
|
||||
|
||||
errorMessageDialog.showMessage(htmlString,"Cat 1");
|
||||
QVERIFY(errorMessageDialog.isVisible());
|
||||
checkBox = errorMessageDialog.findChild<QCheckBox*>();
|
||||
QVERIFY(checkBox);
|
||||
QVERIFY(checkBox->isChecked());
|
||||
checkBox->setChecked(true);
|
||||
errorMessageDialog.close();
|
||||
|
||||
errorMessageDialog.showMessage(htmlString,"Cat 1");
|
||||
QVERIFY(errorMessageDialog.isVisible());
|
||||
checkBox = errorMessageDialog.findChild<QCheckBox*>();
|
||||
QVERIFY(checkBox);
|
||||
QVERIFY(checkBox->isChecked());
|
||||
checkBox->setChecked(true);
|
||||
errorMessageDialog.close();
|
||||
|
||||
errorMessageDialog.showMessage(htmlString2,"Cat 1");
|
||||
QVERIFY(errorMessageDialog.isVisible());
|
||||
checkBox = errorMessageDialog.findChild<QCheckBox*>();
|
||||
QVERIFY(checkBox);
|
||||
QVERIFY(checkBox->isChecked());
|
||||
checkBox->setChecked(true);
|
||||
errorMessageDialog.close();
|
||||
|
||||
errorMessageDialog.showMessage(htmlString,"Cat 1");
|
||||
QVERIFY(errorMessageDialog.isVisible());
|
||||
checkBox = errorMessageDialog.findChild<QCheckBox*>();
|
||||
QVERIFY(checkBox);
|
||||
QVERIFY(checkBox->isChecked());
|
||||
checkBox->setChecked(false);
|
||||
errorMessageDialog.close();
|
||||
|
||||
errorMessageDialog.showMessage(htmlString2,"Cat 1");
|
||||
QVERIFY(!errorMessageDialog.isVisible());
|
||||
|
||||
errorMessageDialog.showMessage(htmlString,"Cat 1");
|
||||
QVERIFY(!errorMessageDialog.isVisible());
|
||||
|
||||
errorMessageDialog.showMessage(htmlString);
|
||||
QVERIFY(errorMessageDialog.isVisible());
|
||||
|
||||
errorMessageDialog.showMessage(htmlString,"Cat 2");
|
||||
QVERIFY(errorMessageDialog.isVisible());
|
||||
}
|
||||
|
||||
void tst_QErrorMessage::baseClassSetVisible()
|
||||
{
|
||||
QErrorMessage errorMessage;
|
||||
errorMessage.QDialog::setVisible(true);
|
||||
QCOMPARE(errorMessage.isVisible(), true);
|
||||
errorMessage.close();
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QErrorMessage)
|
||||
#include "tst_qerrormessage.moc"
|
10
tests/auto/widgets/dialogs/qfiledialog/BLACKLIST
Normal file
10
tests/auto/widgets/dialogs/qfiledialog/BLACKLIST
Normal file
@ -0,0 +1,10 @@
|
||||
[filesSelectedSignal]
|
||||
android # QTBUG-101194
|
||||
[historyForward]
|
||||
android # QTBUG-101194
|
||||
[historyBack]
|
||||
android # QTBUG-101194
|
||||
[completer_data]
|
||||
android # QTBUG-108329
|
||||
[completer]
|
||||
android # QTBUG-101194
|
17
tests/auto/widgets/dialogs/qfiledialog/CMakeLists.txt
Normal file
17
tests/auto/widgets/dialogs/qfiledialog/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qfiledialog Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qfiledialog
|
||||
SOURCES
|
||||
tst_qfiledialog.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
@ -0,0 +1 @@
|
||||
This is a simple text file.
|
1644
tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
Normal file
1644
tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
Normal file
File diff suppressed because it is too large
Load Diff
7
tests/auto/widgets/dialogs/qfiledialog2/BLACKLIST
Normal file
7
tests/auto/widgets/dialogs/qfiledialog2/BLACKLIST
Normal file
@ -0,0 +1,7 @@
|
||||
[QTBUG4419_lineEditSelectAll]
|
||||
macos
|
||||
# QTBUG-87393
|
||||
[task227930_correctNavigationKeyboardBehavior]
|
||||
android
|
||||
[QTBUG4419_lineEditSelectAll]
|
||||
android
|
17
tests/auto/widgets/dialogs/qfiledialog2/CMakeLists.txt
Normal file
17
tests/auto/widgets/dialogs/qfiledialog2/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qfiledialog2 Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qfiledialog2
|
||||
SOURCES
|
||||
tst_qfiledialog2.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
1385
tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
Normal file
1385
tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
Normal file
File diff suppressed because it is too large
Load Diff
34
tests/auto/widgets/dialogs/qfontdialog/CMakeLists.txt
Normal file
34
tests/auto/widgets/dialogs/qfontdialog/CMakeLists.txt
Normal file
@ -0,0 +1,34 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qfontdialog Test:
|
||||
#####################################################################
|
||||
|
||||
# Resources:
|
||||
set_source_files_properties("../../../shared/resources/test.ttf"
|
||||
PROPERTIES QT_RESOURCE_ALIAS "test.ttf"
|
||||
)
|
||||
set_source_files_properties("../../../shared/resources/testfont.ttf"
|
||||
PROPERTIES QT_RESOURCE_ALIAS "testfont.ttf"
|
||||
)
|
||||
set(testfonts_resource_files
|
||||
"../../../shared/resources/test.ttf"
|
||||
"../../../shared/resources/testfont.ttf"
|
||||
)
|
||||
|
||||
qt_internal_add_test(tst_qfontdialog
|
||||
SOURCES
|
||||
tst_qfontdialog.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
TESTDATA ${testfonts_resource_files}
|
||||
BUILTIN_TESTDATA
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
#####################################################################
|
242
tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp
Normal file
242
tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp
Normal file
@ -0,0 +1,242 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
|
||||
|
||||
#include <qapplication.h>
|
||||
#include <qfontdatabase.h>
|
||||
#include <qfontinfo.h>
|
||||
#include <qtimer.h>
|
||||
#include <qmainwindow.h>
|
||||
#include <qlistview.h>
|
||||
#include "qfontdialog.h"
|
||||
#include <private/qfontdialog_p.h>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QtTestEventThread)
|
||||
|
||||
class tst_QFontDialog : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QFontDialog();
|
||||
virtual ~tst_QFontDialog();
|
||||
|
||||
|
||||
public slots:
|
||||
void postKeyReturn();
|
||||
void testGetFont();
|
||||
void testSetFont();
|
||||
void testNonStandardFontSize();
|
||||
|
||||
public slots:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
void init();
|
||||
void cleanup();
|
||||
private slots:
|
||||
void defaultOkButton();
|
||||
void setFont();
|
||||
void task256466_wrongStyle();
|
||||
void setNonStandardFontSize();
|
||||
#ifndef QT_NO_STYLE_STYLESHEET
|
||||
void qtbug_41513_stylesheetStyle();
|
||||
#endif
|
||||
|
||||
|
||||
private:
|
||||
void runSlotWithFailsafeTimer(const char *member);
|
||||
};
|
||||
|
||||
tst_QFontDialog::tst_QFontDialog()
|
||||
{
|
||||
}
|
||||
|
||||
tst_QFontDialog::~tst_QFontDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QFontDialog::initTestCase()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QFontDialog::cleanupTestCase()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QFontDialog::init()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QFontDialog::cleanup()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QFontDialog::postKeyReturn() {
|
||||
QWidgetList list = QApplication::topLevelWidgets();
|
||||
for (int i=0; i<list.size(); ++i) {
|
||||
QFontDialog *dialog = qobject_cast<QFontDialog*>(list[i]);
|
||||
if (dialog) {
|
||||
QTest::keyClick( list[i], Qt::Key_Return, Qt::NoModifier );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QFontDialog::testGetFont()
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
QEXPECT_FAIL("", "Sending QTest::keyClick to OSX font dialog helper fails, see QTBUG-24321", Continue);
|
||||
#endif
|
||||
bool ok = false;
|
||||
QTimer::singleShot(2000, this, SLOT(postKeyReturn()));
|
||||
QFontDialog::getFont(&ok);
|
||||
QVERIFY(ok);
|
||||
}
|
||||
|
||||
void tst_QFontDialog::runSlotWithFailsafeTimer(const char *member)
|
||||
{
|
||||
// FailSafeTimer quits the nested event loop if the dialog closing doesn't do it.
|
||||
QTimer failSafeTimer;
|
||||
failSafeTimer.setInterval(4000);
|
||||
failSafeTimer.setSingleShot(true);
|
||||
connect(&failSafeTimer, SIGNAL(timeout()), qApp, SLOT(quit()));
|
||||
failSafeTimer.start();
|
||||
|
||||
QTimer::singleShot(0, this, member);
|
||||
qApp->exec();
|
||||
|
||||
// FailSafeTimer stops once it goes out of scope.
|
||||
}
|
||||
|
||||
void tst_QFontDialog::defaultOkButton()
|
||||
{
|
||||
runSlotWithFailsafeTimer(SLOT(testGetFont()));
|
||||
}
|
||||
|
||||
void tst_QFontDialog::testSetFont()
|
||||
{
|
||||
bool ok = false;
|
||||
#if defined Q_OS_HPUX
|
||||
QString fontName = "Courier";
|
||||
int fontSize = 25;
|
||||
#elif defined Q_OS_AIX
|
||||
QString fontName = "Charter";
|
||||
int fontSize = 13;
|
||||
#else
|
||||
QString fontName = "Arial";
|
||||
int fontSize = 24;
|
||||
#endif
|
||||
QFont f1(fontName, fontSize);
|
||||
f1.setPixelSize(QFontInfo(f1).pixelSize());
|
||||
QTimer::singleShot(2000, this, SLOT(postKeyReturn()));
|
||||
QFont f2 = QFontDialog::getFont(&ok, f1);
|
||||
QCOMPARE(QFontInfo(f2).pointSize(), QFontInfo(f1).pointSize());
|
||||
}
|
||||
|
||||
void tst_QFontDialog::setFont()
|
||||
{
|
||||
/* The font should be the same before as it is after if nothing changed
|
||||
while the font dialog was open.
|
||||
Task #27662
|
||||
*/
|
||||
runSlotWithFailsafeTimer(SLOT(testSetFont()));
|
||||
}
|
||||
|
||||
|
||||
class FriendlyFontDialog : public QFontDialog
|
||||
{
|
||||
friend class tst_QFontDialog;
|
||||
Q_DECLARE_PRIVATE(QFontDialog)
|
||||
};
|
||||
|
||||
void tst_QFontDialog::task256466_wrongStyle()
|
||||
{
|
||||
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
|
||||
QSKIP("Wayland: This freezes. Figure out why.");
|
||||
|
||||
FriendlyFontDialog dialog;
|
||||
dialog.setOption(QFontDialog::DontUseNativeDialog);
|
||||
QListView *familyList = reinterpret_cast<QListView*>(dialog.d_func()->familyList);
|
||||
QListView *styleList = reinterpret_cast<QListView*>(dialog.d_func()->styleList);
|
||||
QListView *sizeList = reinterpret_cast<QListView*>(dialog.d_func()->sizeList);
|
||||
for (int i = 0; i < familyList->model()->rowCount(); ++i) {
|
||||
QModelIndex currentFamily = familyList->model()->index(i, 0);
|
||||
familyList->setCurrentIndex(currentFamily);
|
||||
int expectedSize = sizeList->currentIndex().data().toInt();
|
||||
const QFont current = dialog.currentFont(),
|
||||
expected = QFontDatabase::font(currentFamily.data().toString(),
|
||||
styleList->currentIndex().data().toString(), expectedSize);
|
||||
QCOMPARE(current.family(), expected.family());
|
||||
QCOMPARE(current.style(), expected.style());
|
||||
if (expectedSize == 0 && !QFontDatabase::isScalable(current.family(), current.styleName()))
|
||||
QEXPECT_FAIL("", "QTBUG-53299: Smooth sizes for unscalable font contains unsupported size", Continue);
|
||||
QCOMPARE(current.pointSizeF(), expected.pointSizeF());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QFontDialog::setNonStandardFontSize()
|
||||
{
|
||||
runSlotWithFailsafeTimer(SLOT(testNonStandardFontSize()));
|
||||
}
|
||||
#ifndef QT_NO_STYLE_STYLESHEET
|
||||
static const QString offendingStyleSheet = QStringLiteral("* { font-family: \"QtBidiTestFont\"; }");
|
||||
|
||||
void tst_QFontDialog::qtbug_41513_stylesheetStyle()
|
||||
{
|
||||
if (QFontDatabase::addApplicationFont(QFINDTESTDATA("test.ttf")) < 0)
|
||||
QSKIP("Test fonts not found.");
|
||||
if (QFontDatabase::addApplicationFont(QFINDTESTDATA("testfont.ttf")) < 0)
|
||||
QSKIP("Test fonts not found.");
|
||||
QFont testFont = QFont(QStringLiteral("QtsSpecialTestFont"));
|
||||
qApp->setStyleSheet(offendingStyleSheet);
|
||||
bool accepted = false;
|
||||
QTimer::singleShot(2000, this, SLOT(postKeyReturn()));
|
||||
QFont resultFont = QFontDialog::getFont(&accepted, testFont,
|
||||
QApplication::activeWindow(),
|
||||
QLatin1String("QFontDialog - Stylesheet Test"),
|
||||
QFontDialog::DontUseNativeDialog);
|
||||
QVERIFY(accepted);
|
||||
|
||||
// The fontdialog sets the styleName, when the fontdatabase knows the style name.
|
||||
resultFont.setStyleName(testFont.styleName());
|
||||
testFont.setFamilies(QStringList(testFont.family()));
|
||||
QCOMPARE(resultFont, testFont);
|
||||
|
||||
// reset stylesheet
|
||||
qApp->setStyleSheet(QString());
|
||||
}
|
||||
#endif // QT_NO_STYLE_STYLESHEET
|
||||
|
||||
void tst_QFontDialog::testNonStandardFontSize()
|
||||
{
|
||||
QList<int> standardSizesList = QFontDatabase::standardSizes();
|
||||
int nonStandardFontSize;
|
||||
if (!standardSizesList.isEmpty()) {
|
||||
nonStandardFontSize = standardSizesList.at(standardSizesList.size()-1); // get the maximum standard size.
|
||||
nonStandardFontSize += 1; // the increment of 1 to mock a non-standard font size.
|
||||
} else {
|
||||
QSKIP("QFontDatabase::standardSizes() is empty.");
|
||||
}
|
||||
|
||||
QFont testFont;
|
||||
testFont.setPointSize(nonStandardFontSize);
|
||||
|
||||
bool accepted = false;
|
||||
QTimer::singleShot(2000, this, SLOT(postKeyReturn()));
|
||||
QFont resultFont = QFontDialog::getFont(&accepted, testFont,
|
||||
QApplication::activeWindow(),
|
||||
QLatin1String("QFontDialog - NonStandardFontSize Test"),
|
||||
QFontDialog::DontUseNativeDialog);
|
||||
QVERIFY(accepted);
|
||||
|
||||
if (accepted)
|
||||
QCOMPARE(testFont.pointSize(), resultFont.pointSize());
|
||||
else
|
||||
qWarning("Fail using a non-standard font size.");
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QFontDialog)
|
||||
#include "tst_qfontdialog.moc"
|
14
tests/auto/widgets/dialogs/qinputdialog/CMakeLists.txt
Normal file
14
tests/auto/widgets/dialogs/qinputdialog/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qinputdialog Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qinputdialog
|
||||
SOURCES
|
||||
tst_qinputdialog.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::WidgetsPrivate
|
||||
)
|
523
tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp
Normal file
523
tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp
Normal file
@ -0,0 +1,523 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
#include <QString>
|
||||
#include <QSpinBox>
|
||||
#include <QPushButton>
|
||||
#include <QLineEdit>
|
||||
#include <QComboBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QTimer>
|
||||
|
||||
#include <qinputdialog.h>
|
||||
#include <QtWidgets/private/qdialog_p.h>
|
||||
|
||||
class tst_QInputDialog : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
QWidget *parent;
|
||||
QDialog::DialogCode doneCode;
|
||||
void (*testFunc)(QInputDialog *);
|
||||
static void testFuncGetInt(QInputDialog *dialog);
|
||||
static void testFuncGetDouble(QInputDialog *dialog);
|
||||
static void testFuncGetText(QInputDialog *dialog);
|
||||
static void testFuncGetItem(QInputDialog *dialog);
|
||||
static void testFuncSingleStepDouble(QInputDialog *dialog);
|
||||
void timerEvent(QTimerEvent *event) override;
|
||||
private slots:
|
||||
void getInt_data();
|
||||
void getInt();
|
||||
void getDouble_data();
|
||||
void getDouble();
|
||||
void taskQTBUG_54693_crashWhenParentIsDeletedWhileDialogIsOpen();
|
||||
void task255502getDouble();
|
||||
void getText_data();
|
||||
void getText();
|
||||
void getItem_data();
|
||||
void getItem();
|
||||
void task256299_getTextReturnNullStringOnRejected();
|
||||
void inputMethodHintsOfChildWidget();
|
||||
void setDoubleStep_data();
|
||||
void setDoubleStep();
|
||||
};
|
||||
|
||||
QString stripFraction(const QString &s)
|
||||
{
|
||||
int period;
|
||||
if (s.contains('.'))
|
||||
period = s.indexOf('.');
|
||||
else if (s.contains(','))
|
||||
period = s.indexOf(',');
|
||||
else
|
||||
return s;
|
||||
int end;
|
||||
for (end = s.size() - 1; end > period && s[end] == '0'; --end) ;
|
||||
return s.left(end + (end == period ? 0 : 1));
|
||||
}
|
||||
|
||||
QString normalizeNumericString(const QString &s)
|
||||
{
|
||||
return stripFraction(s); // assumed to be sufficient
|
||||
}
|
||||
|
||||
void _keyClick(QWidget *widget, char key)
|
||||
{
|
||||
QTest::keyClick(widget, key);
|
||||
}
|
||||
|
||||
void _keyClick(QWidget *widget, Qt::Key key)
|
||||
{
|
||||
QTest::keyClick(widget, key);
|
||||
}
|
||||
|
||||
template <typename SpinBoxType>
|
||||
void testTypingValue(
|
||||
SpinBoxType* sbox, QPushButton *okButton, const QString &value)
|
||||
{
|
||||
sbox->selectAll();
|
||||
for (int i = 0; i < value.size(); ++i) {
|
||||
const QChar valChar = value[i];
|
||||
_keyClick(static_cast<QWidget *>(sbox), valChar.toLatin1()); // ### always guaranteed to work?
|
||||
if (sbox->hasAcceptableInput())
|
||||
QVERIFY(okButton->isEnabled());
|
||||
else
|
||||
QVERIFY(!okButton->isEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
void testTypingValue(QLineEdit *ledit, QPushButton *okButton, const QString &value)
|
||||
{
|
||||
ledit->selectAll();
|
||||
for (int i = 0; i < value.size(); ++i) {
|
||||
const QChar valChar = value[i];
|
||||
_keyClick(ledit, valChar.toLatin1()); // ### always guaranteed to work?
|
||||
QVERIFY(ledit->hasAcceptableInput());
|
||||
QVERIFY(okButton->isEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SpinBoxType, typename ValueType>
|
||||
void testInvalidateAndRestore(
|
||||
SpinBoxType* sbox, QPushButton *okButton, QLineEdit *ledit, ValueType * = 0)
|
||||
{
|
||||
const ValueType lastValidValue = sbox->value();
|
||||
|
||||
sbox->selectAll();
|
||||
_keyClick(ledit, Qt::Key_Delete);
|
||||
QVERIFY(!sbox->hasAcceptableInput());
|
||||
QVERIFY(!okButton->isEnabled());
|
||||
|
||||
_keyClick(ledit, Qt::Key_Return); // should work with Qt::Key_Enter too
|
||||
QVERIFY(sbox->hasAcceptableInput());
|
||||
QVERIFY(okButton->isEnabled());
|
||||
QCOMPARE(sbox->value(), lastValidValue);
|
||||
QLocale loc;
|
||||
QCOMPARE(
|
||||
normalizeNumericString(ledit->text()),
|
||||
normalizeNumericString(loc.toString(sbox->value())));
|
||||
}
|
||||
|
||||
template <typename SpinBoxType, typename ValueType>
|
||||
void testGetNumeric(QInputDialog *dialog, SpinBoxType * = 0, ValueType * = 0)
|
||||
{
|
||||
SpinBoxType *sbox = dialog->findChild<SpinBoxType *>();
|
||||
QVERIFY(sbox != 0);
|
||||
|
||||
QLineEdit *ledit = static_cast<QObject *>(sbox)->findChild<QLineEdit *>();
|
||||
QVERIFY(ledit != 0);
|
||||
|
||||
QDialogButtonBox *bbox = dialog->findChild<QDialogButtonBox *>();
|
||||
QVERIFY(bbox != 0);
|
||||
QPushButton *okButton = bbox->button(QDialogButtonBox::Ok);
|
||||
QVERIFY(okButton != 0);
|
||||
|
||||
QVERIFY(sbox->value() >= sbox->minimum());
|
||||
QVERIFY(sbox->value() <= sbox->maximum());
|
||||
QVERIFY(sbox->hasAcceptableInput());
|
||||
QLocale loc;
|
||||
QCOMPARE(
|
||||
normalizeNumericString(ledit->selectedText()),
|
||||
normalizeNumericString(loc.toString(sbox->value())));
|
||||
QVERIFY(okButton->isEnabled());
|
||||
|
||||
const ValueType origValue = sbox->value();
|
||||
|
||||
testInvalidateAndRestore<SpinBoxType, ValueType>(sbox, okButton, ledit);
|
||||
testTypingValue<SpinBoxType>(sbox, okButton, QString::number(sbox->minimum()));
|
||||
testTypingValue<SpinBoxType>(sbox, okButton, QString::number(sbox->maximum()));
|
||||
testTypingValue<SpinBoxType>(sbox, okButton, QString::number(sbox->minimum() - 1));
|
||||
testTypingValue<SpinBoxType>(sbox, okButton, QString::number(sbox->maximum() + 1));
|
||||
testTypingValue<SpinBoxType>(sbox, okButton, "0");
|
||||
testTypingValue<SpinBoxType>(sbox, okButton, "0.0");
|
||||
testTypingValue<SpinBoxType>(sbox, okButton, "foobar");
|
||||
|
||||
testTypingValue<SpinBoxType>(sbox, okButton, loc.toString(origValue));
|
||||
}
|
||||
|
||||
void testGetText(QInputDialog *dialog)
|
||||
{
|
||||
QLineEdit *ledit = dialog->findChild<QLineEdit *>();
|
||||
QVERIFY(ledit);
|
||||
|
||||
QDialogButtonBox *bbox = dialog->findChild<QDialogButtonBox *>();
|
||||
QVERIFY(bbox);
|
||||
QPushButton *okButton = bbox->button(QDialogButtonBox::Ok);
|
||||
QVERIFY(okButton);
|
||||
|
||||
QVERIFY(ledit->hasAcceptableInput());
|
||||
QCOMPARE(ledit->selectedText(), ledit->text());
|
||||
QVERIFY(okButton->isEnabled());
|
||||
const QString origValue = ledit->text();
|
||||
|
||||
testTypingValue(ledit, okButton, origValue);
|
||||
}
|
||||
|
||||
void testGetItem(QInputDialog *dialog)
|
||||
{
|
||||
QComboBox *cbox = dialog->findChild<QComboBox *>();
|
||||
QVERIFY(cbox);
|
||||
|
||||
QDialogButtonBox *bbox = dialog->findChild<QDialogButtonBox *>();
|
||||
QVERIFY(bbox);
|
||||
QPushButton *okButton = bbox->button(QDialogButtonBox::Ok);
|
||||
QVERIFY(okButton);
|
||||
|
||||
QVERIFY(okButton->isEnabled());
|
||||
const int origIndex = cbox->currentIndex();
|
||||
cbox->setCurrentIndex(origIndex - 1);
|
||||
cbox->setCurrentIndex(origIndex);
|
||||
QVERIFY(okButton->isEnabled());
|
||||
}
|
||||
|
||||
void tst_QInputDialog::testFuncGetInt(QInputDialog *dialog)
|
||||
{
|
||||
testGetNumeric<QSpinBox, int>(dialog);
|
||||
}
|
||||
|
||||
void tst_QInputDialog::testFuncGetDouble(QInputDialog *dialog)
|
||||
{
|
||||
testGetNumeric<QDoubleSpinBox, double>(dialog);
|
||||
}
|
||||
|
||||
void tst_QInputDialog::testFuncGetText(QInputDialog *dialog)
|
||||
{
|
||||
::testGetText(dialog);
|
||||
}
|
||||
|
||||
void tst_QInputDialog::testFuncGetItem(QInputDialog *dialog)
|
||||
{
|
||||
::testGetItem(dialog);
|
||||
}
|
||||
|
||||
void tst_QInputDialog::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
killTimer(event->timerId());
|
||||
QInputDialog *dialog = parent->findChild<QInputDialog *>();
|
||||
QVERIFY(dialog);
|
||||
if (testFunc)
|
||||
testFunc(dialog);
|
||||
dialog->done(doneCode); // cause static function call to return
|
||||
}
|
||||
|
||||
void tst_QInputDialog::getInt_data()
|
||||
{
|
||||
QTest::addColumn<int>("min");
|
||||
QTest::addColumn<int>("max");
|
||||
QTest::newRow("getInt() - -") << -20 << -10;
|
||||
QTest::newRow("getInt() - 0") << -20 << 0;
|
||||
QTest::newRow("getInt() - +") << -20 << 20;
|
||||
QTest::newRow("getInt() 0 +") << 0 << 20;
|
||||
QTest::newRow("getInt() + +") << 10 << 20;
|
||||
}
|
||||
|
||||
void tst_QInputDialog::getInt()
|
||||
{
|
||||
QFETCH(int, min);
|
||||
QFETCH(int, max);
|
||||
QVERIFY(min < max);
|
||||
|
||||
#if defined(Q_OS_MACOS)
|
||||
if (QSysInfo::productVersion() == QLatin1String("10.12")) {
|
||||
QSKIP("Test hangs on macOS 10.12 -- QTQAINFRA-1356");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
parent = new QWidget;
|
||||
doneCode = QDialog::Accepted;
|
||||
testFunc = &tst_QInputDialog::testFuncGetInt;
|
||||
startTimer(0);
|
||||
bool ok = false;
|
||||
const int value = min + (max - min) / 2;
|
||||
const int result = QInputDialog::getInt(parent, "", "", value, min, max, 1, &ok);
|
||||
QVERIFY(ok);
|
||||
QCOMPARE(result, value);
|
||||
delete parent;
|
||||
}
|
||||
|
||||
void tst_QInputDialog::getDouble_data()
|
||||
{
|
||||
QTest::addColumn<double>("min");
|
||||
QTest::addColumn<double>("max");
|
||||
QTest::addColumn<int>("decimals");
|
||||
QTest::newRow("getDouble() - - d0") << -20.0 << -10.0 << 0;
|
||||
QTest::newRow("getDouble() - 0 d0") << -20.0 << 0.0 << 0;
|
||||
QTest::newRow("getDouble() - + d0") << -20.0 << 20.0 << 0;
|
||||
QTest::newRow("getDouble() 0 + d0") << 0.0 << 20.0 << 0;
|
||||
QTest::newRow("getDouble() + + d0") << 10.0 << 20.0 << 0;
|
||||
QTest::newRow("getDouble() - - d1") << -20.5 << -10.5 << 1;
|
||||
QTest::newRow("getDouble() - 0 d1") << -20.5 << 0.0 << 1;
|
||||
QTest::newRow("getDouble() - + d1") << -20.5 << 20.5 << 1;
|
||||
QTest::newRow("getDouble() 0 + d1") << 0.0 << 20.5 << 1;
|
||||
QTest::newRow("getDouble() + + d1") << 10.5 << 20.5 << 1;
|
||||
QTest::newRow("getDouble() - - d2") << -20.05 << -10.05 << 2;
|
||||
QTest::newRow("getDouble() - 0 d2") << -20.05 << 0.0 << 2;
|
||||
QTest::newRow("getDouble() - + d2") << -20.05 << 20.05 << 2;
|
||||
QTest::newRow("getDouble() 0 + d2") << 0.0 << 20.05 << 2;
|
||||
QTest::newRow("getDouble() + + d2") << 10.05 << 20.05 << 2;
|
||||
}
|
||||
|
||||
void tst_QInputDialog::getDouble()
|
||||
{
|
||||
QFETCH(double, min);
|
||||
QFETCH(double, max);
|
||||
QFETCH(int, decimals);
|
||||
QVERIFY(min < max && decimals >= 0 && decimals <= 13);
|
||||
|
||||
#if defined(Q_OS_MACOS)
|
||||
if (QSysInfo::productVersion() == QLatin1String("10.12")) {
|
||||
QSKIP("Test hangs on macOS 10.12 -- QTQAINFRA-1356");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
parent = new QWidget;
|
||||
doneCode = QDialog::Accepted;
|
||||
testFunc = &tst_QInputDialog::testFuncGetDouble;
|
||||
startTimer(0);
|
||||
bool ok = false;
|
||||
// avoid decimals due to inconsistent roundoff behavior in QInputDialog::getDouble()
|
||||
// (at one decimal, 10.25 is rounded off to 10.2, while at two decimals, 10.025 is
|
||||
// rounded off to 10.03)
|
||||
const double value = static_cast<int>(min + (max - min) / 2);
|
||||
const double result =
|
||||
QInputDialog::getDouble(parent, "", "", value, min, max, decimals, &ok, Qt::WindowFlags(), 1);
|
||||
QVERIFY(ok);
|
||||
QCOMPARE(result, value);
|
||||
delete parent;
|
||||
}
|
||||
|
||||
namespace {
|
||||
class SelfDestructParent : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SelfDestructParent(int delay = 100)
|
||||
: QWidget(nullptr)
|
||||
{
|
||||
QTimer::singleShot(delay, this, SLOT(deleteLater()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void tst_QInputDialog::taskQTBUG_54693_crashWhenParentIsDeletedWhileDialogIsOpen()
|
||||
{
|
||||
// getText
|
||||
{
|
||||
QAutoPointer<SelfDestructParent> dialog(new SelfDestructParent);
|
||||
bool ok = true;
|
||||
const QString result = QInputDialog::getText(dialog.get(), "Title", "Label", QLineEdit::Normal, "Text", &ok);
|
||||
QVERIFY(!dialog);
|
||||
QVERIFY(!ok);
|
||||
QVERIFY(result.isNull());
|
||||
}
|
||||
|
||||
// getMultiLineText
|
||||
{
|
||||
QAutoPointer<SelfDestructParent> dialog(new SelfDestructParent);
|
||||
bool ok = true;
|
||||
const QString result = QInputDialog::getMultiLineText(dialog.get(), "Title", "Label", "Text", &ok);
|
||||
QVERIFY(!dialog);
|
||||
QVERIFY(!ok);
|
||||
QVERIFY(result.isNull());
|
||||
}
|
||||
|
||||
// getItem
|
||||
for (int editable = 0; editable < 2; ++editable) {
|
||||
QAutoPointer<SelfDestructParent> dialog(new SelfDestructParent);
|
||||
bool ok = true;
|
||||
const QString result = QInputDialog::getItem(dialog.get(), "Title", "Label",
|
||||
QStringList() << "1" << "2", 1,
|
||||
editable != 0, &ok);
|
||||
QVERIFY(!dialog);
|
||||
QVERIFY(!ok);
|
||||
QCOMPARE(result, QLatin1String("2"));
|
||||
}
|
||||
|
||||
// getInt
|
||||
{
|
||||
const int initial = 7;
|
||||
QAutoPointer<SelfDestructParent> dialog(new SelfDestructParent);
|
||||
bool ok = true;
|
||||
const int result = QInputDialog::getInt(dialog.get(), "Title", "Label", initial, -10, +10, 1, &ok);
|
||||
QVERIFY(!dialog);
|
||||
QVERIFY(!ok);
|
||||
QCOMPARE(result, initial);
|
||||
}
|
||||
|
||||
// getDouble
|
||||
{
|
||||
const double initial = 7;
|
||||
QAutoPointer<SelfDestructParent> dialog(new SelfDestructParent);
|
||||
bool ok = true;
|
||||
const double result = QInputDialog::getDouble(dialog.get(), "Title", "Label", initial, -10, +10, 2, &ok,
|
||||
Qt::WindowFlags(), 1);
|
||||
QVERIFY(!dialog);
|
||||
QVERIFY(!ok);
|
||||
QCOMPARE(result, initial);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QInputDialog::task255502getDouble()
|
||||
{
|
||||
parent = new QWidget;
|
||||
doneCode = QDialog::Accepted;
|
||||
testFunc = &tst_QInputDialog::testFuncGetDouble;
|
||||
startTimer(0);
|
||||
bool ok = false;
|
||||
const double value = 0.001;
|
||||
const double result =
|
||||
QInputDialog::getDouble(parent, "", "", value, -1, 1, 4, &ok, Qt::WindowFlags(), 1);
|
||||
QVERIFY(ok);
|
||||
QCOMPARE(result, value);
|
||||
delete parent;
|
||||
}
|
||||
|
||||
void tst_QInputDialog::getText_data()
|
||||
{
|
||||
QTest::addColumn<QString>("text");
|
||||
QTest::newRow("getText() 1") << "";
|
||||
QTest::newRow("getText() 2") << "foobar";
|
||||
QTest::newRow("getText() 3") << " foobar";
|
||||
QTest::newRow("getText() 4") << "foobar ";
|
||||
QTest::newRow("getText() 5") << "aAzZ`1234567890-=~!@#$%^&*()_+[]{}\\|;:'\",.<>/?";
|
||||
}
|
||||
|
||||
void tst_QInputDialog::getText()
|
||||
{
|
||||
QFETCH(QString, text);
|
||||
parent = new QWidget;
|
||||
doneCode = QDialog::Accepted;
|
||||
testFunc = &tst_QInputDialog::testFuncGetText;
|
||||
startTimer(0);
|
||||
bool ok = false;
|
||||
const QString result = QInputDialog::getText(parent, "", "", QLineEdit::Normal, text, &ok);
|
||||
QVERIFY(ok);
|
||||
QCOMPARE(result, text);
|
||||
delete parent;
|
||||
}
|
||||
|
||||
void tst_QInputDialog::task256299_getTextReturnNullStringOnRejected()
|
||||
{
|
||||
parent = new QWidget;
|
||||
doneCode = QDialog::Rejected;
|
||||
testFunc = 0;
|
||||
startTimer(0);
|
||||
bool ok = true;
|
||||
const QString result = QInputDialog::getText(parent, "", "", QLineEdit::Normal, "foobar", &ok);
|
||||
QVERIFY(!ok);
|
||||
QVERIFY(result.isNull());
|
||||
delete parent;
|
||||
}
|
||||
|
||||
void tst_QInputDialog::getItem_data()
|
||||
{
|
||||
QTest::addColumn<QStringList>("items");
|
||||
QTest::addColumn<bool>("editable");
|
||||
QTest::newRow("getItem() 1 true") << (QStringList() << "") << true;
|
||||
QTest::newRow("getItem() 2 true") <<
|
||||
(QStringList() << "spring" << "summer" << "fall" << "winter") << true;
|
||||
QTest::newRow("getItem() 1 false") << (QStringList() << "") << false;
|
||||
QTest::newRow("getItem() 2 false") <<
|
||||
(QStringList() << "spring" << "summer" << "fall" << "winter") << false;
|
||||
}
|
||||
|
||||
void tst_QInputDialog::getItem()
|
||||
{
|
||||
QFETCH(QStringList, items);
|
||||
QFETCH(bool, editable);
|
||||
parent = new QWidget;
|
||||
doneCode = QDialog::Accepted;
|
||||
testFunc = &tst_QInputDialog::testFuncGetItem;
|
||||
startTimer(0);
|
||||
bool ok = false;
|
||||
const int index = items.size() / 2;
|
||||
const QString result = QInputDialog::getItem(parent, "", "", items, index, editable, &ok);
|
||||
QVERIFY(ok);
|
||||
QCOMPARE(result, items[index]);
|
||||
delete parent;
|
||||
}
|
||||
|
||||
void tst_QInputDialog::inputMethodHintsOfChildWidget()
|
||||
{
|
||||
QInputDialog dialog;
|
||||
dialog.setInputMode(QInputDialog::TextInput);
|
||||
QList<QObject *> children = dialog.children();
|
||||
QLineEdit *editWidget = 0;
|
||||
for (int c = 0; c < children.size(); c++) {
|
||||
editWidget = qobject_cast<QLineEdit *>(children.at(c));
|
||||
if (editWidget)
|
||||
break;
|
||||
}
|
||||
QVERIFY(editWidget);
|
||||
QCOMPARE(editWidget->inputMethodHints(), dialog.inputMethodHints());
|
||||
QCOMPARE(editWidget->inputMethodHints(), Qt::ImhNone);
|
||||
dialog.setInputMethodHints(Qt::ImhDigitsOnly);
|
||||
QCOMPARE(editWidget->inputMethodHints(), dialog.inputMethodHints());
|
||||
QCOMPARE(editWidget->inputMethodHints(), Qt::ImhDigitsOnly);
|
||||
}
|
||||
|
||||
void tst_QInputDialog::testFuncSingleStepDouble(QInputDialog *dialog)
|
||||
{
|
||||
QDoubleSpinBox *sbox = dialog->findChild<QDoubleSpinBox *>();
|
||||
QVERIFY(sbox);
|
||||
QTest::keyClick(sbox, Qt::Key_Up);
|
||||
}
|
||||
|
||||
void tst_QInputDialog::setDoubleStep_data()
|
||||
{
|
||||
QTest::addColumn<double>("min");
|
||||
QTest::addColumn<double>("max");
|
||||
QTest::addColumn<int>("decimals");
|
||||
QTest::addColumn<double>("doubleStep");
|
||||
QTest::addColumn<double>("actualResult");
|
||||
QTest::newRow("step 2.0") << 0.0 << 10.0 << 0 << 2.0 << 2.0;
|
||||
QTest::newRow("step 2.5") << 0.5 << 10.5 << 1 << 2.5 << 3.0;
|
||||
QTest::newRow("step 2.25") << 10.05 << 20.05 << 2 << 2.25 << 12.30;
|
||||
QTest::newRow("step 2.25 fewer decimals") << 0.5 << 10.5 << 1 << 2.25 << 2.75;
|
||||
}
|
||||
|
||||
void tst_QInputDialog::setDoubleStep()
|
||||
{
|
||||
QFETCH(double, min);
|
||||
QFETCH(double, max);
|
||||
QFETCH(int, decimals);
|
||||
QFETCH(double, doubleStep);
|
||||
QFETCH(double, actualResult);
|
||||
QWidget p;
|
||||
parent = &p;
|
||||
doneCode = QDialog::Accepted;
|
||||
testFunc = &tst_QInputDialog::testFuncSingleStepDouble;
|
||||
startTimer(0);
|
||||
bool ok = false;
|
||||
const double result = QInputDialog::getDouble(parent, QString(), QString(), min, min,
|
||||
max, decimals, &ok, QFlags<Qt::WindowType>(),
|
||||
doubleStep);
|
||||
QVERIFY(ok);
|
||||
QCOMPARE(result, actualResult);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QInputDialog)
|
||||
#include "tst_qinputdialog.moc"
|
0
tests/auto/widgets/dialogs/qmessagebox/BLACKLIST
Normal file
0
tests/auto/widgets/dialogs/qmessagebox/BLACKLIST
Normal file
16
tests/auto/widgets/dialogs/qmessagebox/CMakeLists.txt
Normal file
16
tests/auto/widgets/dialogs/qmessagebox/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qmessagebox Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qmessagebox
|
||||
SOURCES
|
||||
tst_qmessagebox.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
Qt::Widgets
|
||||
)
|
745
tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp
Normal file
745
tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp
Normal file
@ -0,0 +1,745 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
#include <QPair>
|
||||
#include <QSet>
|
||||
#include <QList>
|
||||
#include <QPointer>
|
||||
#include <QTimer>
|
||||
#include <QApplication>
|
||||
#include <QPushButton>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include <qpa/qplatformtheme.h>
|
||||
#include <private/qguiapplication_p.h>
|
||||
|
||||
class tst_QMessageBox : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase_data();
|
||||
void init();
|
||||
|
||||
void sanityTest();
|
||||
void baseClassSetVisible();
|
||||
void defaultButton();
|
||||
void escapeButton();
|
||||
void clickedButton();
|
||||
void button();
|
||||
void statics();
|
||||
void about();
|
||||
void detailsText();
|
||||
void detailsButtonText();
|
||||
void expandDetailsWithoutMoving();
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
void shortcut();
|
||||
#endif
|
||||
|
||||
void staticSourceCompat();
|
||||
void instanceSourceCompat();
|
||||
|
||||
void incorrectDefaultButton();
|
||||
void updateSize();
|
||||
|
||||
void setInformativeText();
|
||||
void iconPixmap();
|
||||
|
||||
// QTBUG-44131
|
||||
void acceptedRejectedSignals();
|
||||
void acceptedRejectedSignals_data();
|
||||
|
||||
void cleanup();
|
||||
};
|
||||
|
||||
class tst_ResizingMessageBox : public QMessageBox
|
||||
{
|
||||
public:
|
||||
tst_ResizingMessageBox() : QMessageBox(), resized(false) { }
|
||||
bool resized;
|
||||
|
||||
protected:
|
||||
void resizeEvent ( QResizeEvent * event ) override
|
||||
{
|
||||
resized = true;
|
||||
QMessageBox::resizeEvent(event);
|
||||
}
|
||||
};
|
||||
|
||||
// ExecCloseHelper: Closes a modal QDialog during its exec() function by either
|
||||
// sending a key event or closing it (CloseWindow) once it becomes the active
|
||||
// modal window. Pass nullptr to "autodetect" the instance for static methods.
|
||||
class ExecCloseHelper : public QObject
|
||||
{
|
||||
public:
|
||||
enum { CloseWindow = -1 };
|
||||
|
||||
explicit ExecCloseHelper(QObject *parent = nullptr)
|
||||
: QObject(parent), m_key(0), m_timerId(0), m_testCandidate(nullptr) { }
|
||||
|
||||
void start(int key, QWidget *testCandidate = nullptr)
|
||||
{
|
||||
m_key = key;
|
||||
m_testCandidate = testCandidate;
|
||||
m_timerId = startTimer(50);
|
||||
}
|
||||
|
||||
bool done() const { return !m_timerId; }
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *te) override;
|
||||
|
||||
private:
|
||||
int m_key;
|
||||
int m_timerId;
|
||||
QWidget *m_testCandidate;
|
||||
};
|
||||
|
||||
void ExecCloseHelper::timerEvent(QTimerEvent *te)
|
||||
{
|
||||
if (te->timerId() != m_timerId)
|
||||
return;
|
||||
|
||||
QWidget *modalWidget = QApplication::activeModalWidget();
|
||||
if (!m_testCandidate && modalWidget)
|
||||
m_testCandidate = modalWidget;
|
||||
|
||||
QWidget *activeWindow = QApplication::activeWindow();
|
||||
if (!m_testCandidate && activeWindow)
|
||||
m_testCandidate = activeWindow;
|
||||
|
||||
if (!m_testCandidate)
|
||||
return;
|
||||
|
||||
bool shouldHelp = (m_testCandidate->isModal() && m_testCandidate == modalWidget)
|
||||
|| (!m_testCandidate->isModal() && m_testCandidate == activeWindow);
|
||||
|
||||
if (shouldHelp) {
|
||||
if (m_key == CloseWindow) {
|
||||
m_testCandidate->close();
|
||||
} else {
|
||||
QKeyEvent *ke = new QKeyEvent(QEvent::KeyPress, m_key, Qt::NoModifier);
|
||||
QCoreApplication::postEvent(m_testCandidate, ke);
|
||||
}
|
||||
m_testCandidate = nullptr;
|
||||
killTimer(m_timerId);
|
||||
m_timerId = m_key = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMessageBox::initTestCase_data()
|
||||
{
|
||||
QTest::addColumn<bool>("useNativeDialog");
|
||||
QTest::newRow("widget") << false;
|
||||
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
|
||||
if (theme->usePlatformNativeDialog(QPlatformTheme::MessageDialog))
|
||||
QTest::newRow("native") << true;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMessageBox::init()
|
||||
{
|
||||
QFETCH_GLOBAL(bool, useNativeDialog);
|
||||
qApp->setAttribute(Qt::AA_DontUseNativeDialogs, !useNativeDialog);
|
||||
}
|
||||
|
||||
void tst_QMessageBox::cleanup()
|
||||
{
|
||||
QTRY_VERIFY(QApplication::topLevelWidgets().isEmpty()); // OS X requires TRY
|
||||
}
|
||||
|
||||
void tst_QMessageBox::sanityTest()
|
||||
{
|
||||
#if defined(Q_OS_MACOS)
|
||||
if (QSysInfo::productVersion() == QLatin1String("10.12")) {
|
||||
QSKIP("Test hangs on macOS 10.12 -- QTQAINFRA-1362");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText("This is insane");
|
||||
for (int i = 0; i < 10; i++)
|
||||
msgBox.setIcon(QMessageBox::Icon(i));
|
||||
msgBox.setIconPixmap(QPixmap());
|
||||
msgBox.setIconPixmap(QPixmap("whatever.png"));
|
||||
msgBox.setTextFormat(Qt::RichText);
|
||||
msgBox.setTextFormat(Qt::PlainText);
|
||||
ExecCloseHelper closeHelper;
|
||||
closeHelper.start(ExecCloseHelper::CloseWindow, &msgBox);
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
void tst_QMessageBox::baseClassSetVisible()
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText("Hello World");
|
||||
msgBox.QDialog::setVisible(true);
|
||||
QCOMPARE(msgBox.isVisible(), true);
|
||||
msgBox.close();
|
||||
}
|
||||
|
||||
void tst_QMessageBox::button()
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.addButton("retry", QMessageBox::DestructiveRole);
|
||||
QVERIFY(msgBox.button(QMessageBox::Ok) == nullptr); // not added yet
|
||||
QPushButton *b1 = msgBox.addButton(QMessageBox::Ok);
|
||||
QCOMPARE(msgBox.button(QMessageBox::Ok), static_cast<QAbstractButton *>(b1)); // just added
|
||||
QCOMPARE(msgBox.standardButton(b1), QMessageBox::Ok);
|
||||
msgBox.addButton(QMessageBox::Cancel);
|
||||
QCOMPARE(msgBox.standardButtons(), QMessageBox::Ok | QMessageBox::Cancel);
|
||||
|
||||
// remove the cancel, should not exist anymore
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
QVERIFY(!msgBox.button(QMessageBox::Cancel));
|
||||
QVERIFY(msgBox.button(QMessageBox::Yes) != nullptr);
|
||||
|
||||
// should not crash
|
||||
QPushButton *b4 = new QPushButton;
|
||||
msgBox.addButton(b4, QMessageBox::DestructiveRole);
|
||||
msgBox.addButton(nullptr, QMessageBox::ActionRole);
|
||||
}
|
||||
|
||||
void tst_QMessageBox::defaultButton()
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
QVERIFY(!msgBox.defaultButton());
|
||||
msgBox.addButton(QMessageBox::Ok);
|
||||
msgBox.addButton(QMessageBox::Cancel);
|
||||
QVERIFY(!msgBox.defaultButton());
|
||||
QPushButton pushButton;
|
||||
msgBox.setDefaultButton(&pushButton);
|
||||
QVERIFY(msgBox.defaultButton() == nullptr); // we have not added it yet
|
||||
QPushButton *retryButton = msgBox.addButton(QMessageBox::Retry);
|
||||
msgBox.setDefaultButton(retryButton);
|
||||
QCOMPARE(msgBox.defaultButton(), retryButton);
|
||||
ExecCloseHelper closeHelper;
|
||||
closeHelper.start(ExecCloseHelper::CloseWindow, &msgBox);
|
||||
msgBox.exec();
|
||||
QCOMPARE(msgBox.clickedButton(), msgBox.button(QMessageBox::Cancel));
|
||||
|
||||
closeHelper.start(Qt::Key_Enter, &msgBox);
|
||||
msgBox.exec();
|
||||
QCOMPARE(msgBox.clickedButton(), static_cast<QAbstractButton *>(retryButton));
|
||||
|
||||
QAbstractButton *okButton = msgBox.button(QMessageBox::Ok);
|
||||
msgBox.setDefaultButton(QMessageBox::Ok);
|
||||
QCOMPARE(msgBox.defaultButton(), static_cast<QPushButton *>(okButton));
|
||||
closeHelper.start(Qt::Key_Enter, &msgBox);
|
||||
msgBox.exec();
|
||||
QCOMPARE(msgBox.clickedButton(), okButton);
|
||||
msgBox.setDefaultButton(QMessageBox::Yes); // its not in there!
|
||||
QCOMPARE(msgBox.defaultButton(), okButton);
|
||||
msgBox.removeButton(okButton);
|
||||
delete okButton;
|
||||
okButton = nullptr;
|
||||
QVERIFY(!msgBox.defaultButton());
|
||||
msgBox.setDefaultButton(QMessageBox::Ok);
|
||||
QVERIFY(!msgBox.defaultButton());
|
||||
}
|
||||
|
||||
void tst_QMessageBox::escapeButton()
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
QVERIFY(!msgBox.escapeButton());
|
||||
msgBox.addButton(QMessageBox::Ok);
|
||||
ExecCloseHelper closeHelper;
|
||||
closeHelper.start(ExecCloseHelper::CloseWindow, &msgBox);
|
||||
msgBox.exec();
|
||||
QVERIFY(msgBox.clickedButton() == msgBox.button(QMessageBox::Ok)); // auto detected (one button only)
|
||||
msgBox.addButton(QMessageBox::Cancel);
|
||||
QVERIFY(!msgBox.escapeButton());
|
||||
QPushButton invalidButton;
|
||||
msgBox.setEscapeButton(&invalidButton);
|
||||
QVERIFY(!msgBox.escapeButton());
|
||||
QAbstractButton *retryButton = msgBox.addButton(QMessageBox::Retry);
|
||||
|
||||
closeHelper.start(ExecCloseHelper::CloseWindow, &msgBox);
|
||||
msgBox.exec();
|
||||
QVERIFY(msgBox.clickedButton() == msgBox.button(QMessageBox::Cancel)); // auto detected (cancel)
|
||||
|
||||
msgBox.setEscapeButton(retryButton);
|
||||
QCOMPARE(msgBox.escapeButton(), static_cast<QAbstractButton *>(retryButton));
|
||||
|
||||
// with escape
|
||||
closeHelper.start(Qt::Key_Escape, &msgBox);
|
||||
msgBox.exec();
|
||||
QCOMPARE(msgBox.clickedButton(), retryButton);
|
||||
|
||||
// with close
|
||||
closeHelper.start(ExecCloseHelper::CloseWindow, &msgBox);
|
||||
msgBox.exec();
|
||||
QCOMPARE(msgBox.clickedButton(), static_cast<QAbstractButton *>(retryButton));
|
||||
|
||||
QAbstractButton *okButton = msgBox.button(QMessageBox::Ok);
|
||||
msgBox.setEscapeButton(QMessageBox::Ok);
|
||||
QCOMPARE(msgBox.escapeButton(), okButton);
|
||||
closeHelper.start(Qt::Key_Escape, &msgBox);
|
||||
msgBox.exec();
|
||||
QCOMPARE(msgBox.clickedButton(), okButton);
|
||||
msgBox.setEscapeButton(QMessageBox::Yes); // its not in there!
|
||||
QCOMPARE(msgBox.escapeButton(), okButton);
|
||||
msgBox.removeButton(okButton);
|
||||
delete okButton;
|
||||
okButton = nullptr;
|
||||
QVERIFY(!msgBox.escapeButton());
|
||||
msgBox.setEscapeButton(QMessageBox::Ok);
|
||||
QVERIFY(!msgBox.escapeButton());
|
||||
|
||||
QMessageBox msgBox2;
|
||||
msgBox2.addButton(QMessageBox::Yes);
|
||||
msgBox2.addButton(QMessageBox::No);
|
||||
closeHelper.start(ExecCloseHelper::CloseWindow, &msgBox2);
|
||||
msgBox2.exec();
|
||||
QVERIFY(msgBox2.clickedButton() == msgBox2.button(QMessageBox::No)); // auto detected (one No button only)
|
||||
|
||||
QPushButton *rejectButton = new QPushButton;
|
||||
msgBox2.addButton(rejectButton, QMessageBox::RejectRole);
|
||||
closeHelper.start(ExecCloseHelper::CloseWindow, &msgBox2);
|
||||
msgBox2.exec();
|
||||
QVERIFY(msgBox2.clickedButton() == rejectButton); // auto detected (one reject button only)
|
||||
|
||||
msgBox2.addButton(new QPushButton, QMessageBox::RejectRole);
|
||||
closeHelper.start(ExecCloseHelper::CloseWindow, &msgBox2);
|
||||
msgBox2.exec();
|
||||
QVERIFY(msgBox2.clickedButton() == msgBox2.button(QMessageBox::No)); // auto detected (one No button only)
|
||||
|
||||
QMessageBox msgBox3;
|
||||
msgBox3.setDetailedText("Details");
|
||||
closeHelper.start(ExecCloseHelper::CloseWindow, &msgBox3);
|
||||
msgBox3.exec();
|
||||
QVERIFY(msgBox3.clickedButton() == msgBox3.button(QMessageBox::Ok)); // auto detected
|
||||
}
|
||||
|
||||
void tst_QMessageBox::clickedButton()
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.addButton(QMessageBox::Yes);
|
||||
msgBox.addButton(QMessageBox::No);
|
||||
msgBox.addButton(QMessageBox::Retry);
|
||||
|
||||
QVERIFY(!msgBox.clickedButton());
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
QAbstractButton *clickedButtonAfterExex = nullptr;
|
||||
QTimer::singleShot(100, [&] {
|
||||
clickedButtonAfterExex = msgBox.clickedButton();
|
||||
msgBox.close();
|
||||
});
|
||||
msgBox.exec();
|
||||
|
||||
QVERIFY(!clickedButtonAfterExex);
|
||||
QVERIFY(msgBox.clickedButton());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMessageBox::statics()
|
||||
{
|
||||
QMessageBox::StandardButton (*statics[4])(QWidget *, const QString &,
|
||||
const QString&, QMessageBox::StandardButtons buttons,
|
||||
QMessageBox::StandardButton);
|
||||
|
||||
statics[0] = QMessageBox::information;
|
||||
statics[1] = QMessageBox::critical;
|
||||
statics[2] = QMessageBox::question;
|
||||
statics[3] = QMessageBox::warning;
|
||||
|
||||
ExecCloseHelper closeHelper;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
closeHelper.start(Qt::Key_Escape);
|
||||
QMessageBox::StandardButton sb = (*statics[i])(nullptr, "caption",
|
||||
"text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help | QMessageBox::Cancel,
|
||||
QMessageBox::NoButton);
|
||||
QCOMPARE(sb, QMessageBox::Cancel);
|
||||
QVERIFY(closeHelper.done());
|
||||
|
||||
closeHelper.start(ExecCloseHelper::CloseWindow);
|
||||
sb = (*statics[i])(nullptr, "caption",
|
||||
"text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help | QMessageBox::Cancel,
|
||||
QMessageBox::NoButton);
|
||||
QCOMPARE(sb, QMessageBox::Cancel);
|
||||
QVERIFY(closeHelper.done());
|
||||
|
||||
closeHelper.start(Qt::Key_Enter);
|
||||
sb = (*statics[i])(nullptr, "caption",
|
||||
"text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help,
|
||||
QMessageBox::Yes);
|
||||
QCOMPARE(sb, QMessageBox::Yes);
|
||||
QVERIFY(closeHelper.done());
|
||||
|
||||
closeHelper.start(Qt::Key_Enter);
|
||||
sb = (*statics[i])(nullptr, "caption",
|
||||
"text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help,
|
||||
QMessageBox::No);
|
||||
QCOMPARE(sb, QMessageBox::No);
|
||||
QVERIFY(closeHelper.done());
|
||||
}
|
||||
}
|
||||
|
||||
// shortcuts are not used on OS X
|
||||
#ifndef Q_OS_MAC
|
||||
void tst_QMessageBox::shortcut()
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.addButton("O&k", QMessageBox::YesRole);
|
||||
msgBox.addButton("&No", QMessageBox::YesRole);
|
||||
msgBox.addButton("&Maybe", QMessageBox::YesRole);
|
||||
ExecCloseHelper closeHelper;
|
||||
closeHelper.start(Qt::Key_M, &msgBox);
|
||||
QCOMPARE(msgBox.exec(), 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
void tst_QMessageBox::about()
|
||||
{
|
||||
ExecCloseHelper closeHelper;
|
||||
closeHelper.start(Qt::Key_Escape);
|
||||
QMessageBox::about(nullptr, "Caption", "This is an auto test");
|
||||
// On Mac, about and aboutQt are not modal, so we need to
|
||||
// explicitly run the event loop
|
||||
#ifdef Q_OS_MAC
|
||||
QTRY_VERIFY(closeHelper.done());
|
||||
#else
|
||||
QVERIFY(closeHelper.done());
|
||||
#endif
|
||||
|
||||
const int keyToSend = Qt::Key_Enter;
|
||||
|
||||
closeHelper.start(keyToSend);
|
||||
QMessageBox::aboutQt(nullptr, "Caption");
|
||||
#ifdef Q_OS_MAC
|
||||
QTRY_VERIFY(closeHelper.done());
|
||||
#else
|
||||
QVERIFY(closeHelper.done());
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QMessageBox::staticSourceCompat()
|
||||
{
|
||||
int ret;
|
||||
|
||||
// source compat tests for < 4.2
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
ExecCloseHelper closeHelper;
|
||||
closeHelper.start(Qt::Key_Enter);
|
||||
ret = QMessageBox::information(nullptr, "title", "text", QMessageBox::Yes, QMessageBox::No);
|
||||
int expectedButton = int(QMessageBox::Yes);
|
||||
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
|
||||
const int dialogButtonBoxLayout = theme->themeHint(QPlatformTheme::DialogButtonBoxLayout).toInt();
|
||||
if (dialogButtonBoxLayout == QDialogButtonBox::MacLayout
|
||||
|| dialogButtonBoxLayout == QDialogButtonBox::GnomeLayout)
|
||||
expectedButton = int(QMessageBox::No);
|
||||
}
|
||||
QCOMPARE(ret, expectedButton);
|
||||
QVERIFY(closeHelper.done());
|
||||
|
||||
closeHelper.start(Qt::Key_Enter);
|
||||
ret = QMessageBox::information(nullptr, "title", "text", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No);
|
||||
QCOMPARE(ret, int(QMessageBox::Yes));
|
||||
QVERIFY(closeHelper.done());
|
||||
|
||||
#if QT_DEPRECATED_SINCE(6, 2)
|
||||
// The overloads below are valid only before 6.2
|
||||
closeHelper.start(Qt::Key_Enter);
|
||||
ret = QMessageBox::information(nullptr, "title", "text", QMessageBox::Yes, QMessageBox::No | QMessageBox::Default);
|
||||
QCOMPARE(ret, int(QMessageBox::No));
|
||||
QVERIFY(closeHelper.done());
|
||||
|
||||
closeHelper.start(Qt::Key_Enter);
|
||||
ret = QMessageBox::information(nullptr, "title", "text", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape);
|
||||
QCOMPARE(ret, int(QMessageBox::Yes));
|
||||
QVERIFY(closeHelper.done());
|
||||
|
||||
closeHelper.start(Qt::Key_Enter);
|
||||
ret = QMessageBox::information(nullptr, "title", "text", QMessageBox::Yes | QMessageBox::Escape, QMessageBox::No | QMessageBox::Default);
|
||||
QCOMPARE(ret, int(QMessageBox::No));
|
||||
QVERIFY(closeHelper.done());
|
||||
|
||||
// the button text versions
|
||||
closeHelper.start(Qt::Key_Enter);
|
||||
ret = QMessageBox::information(nullptr, "title", "text", "Yes", "No", QString(), 1);
|
||||
QCOMPARE(ret, 1);
|
||||
QVERIFY(closeHelper.done());
|
||||
|
||||
if (0) { // don't run these tests since the dialog won't close!
|
||||
closeHelper.start(Qt::Key_Escape);
|
||||
ret = QMessageBox::information(nullptr, "title", "text", "Yes", "No", QString(), 1);
|
||||
QCOMPARE(ret, -1);
|
||||
QVERIFY(closeHelper.done());
|
||||
|
||||
closeHelper.start(Qt::Key_Escape);
|
||||
ret = QMessageBox::information(nullptr, "title", "text", "Yes", "No", QString(), 0, 1);
|
||||
QCOMPARE(ret, 1);
|
||||
QVERIFY(closeHelper.done());
|
||||
}
|
||||
#endif // QT_DEPRECATED_SINCE(6, 2)
|
||||
QT_WARNING_POP
|
||||
}
|
||||
|
||||
void tst_QMessageBox::instanceSourceCompat()
|
||||
{
|
||||
QMessageBox mb(QMessageBox::Information,
|
||||
"Application name here",
|
||||
"Saving the file will overwrite the original file on the disk.\n"
|
||||
"Do you really want to save?",
|
||||
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
|
||||
mb.setDefaultButton(QMessageBox::Yes);
|
||||
mb.setEscapeButton(QMessageBox::Cancel);
|
||||
mb.button(QMessageBox::Yes)->setText("Save");
|
||||
mb.button(QMessageBox::No)->setText("Discard");
|
||||
mb.addButton("&Revert", QMessageBox::RejectRole);
|
||||
mb.addButton("&Zoo", QMessageBox::ActionRole);
|
||||
|
||||
ExecCloseHelper closeHelper;
|
||||
closeHelper.start(Qt::Key_Enter, &mb);
|
||||
QCOMPARE(mb.exec(), int(QMessageBox::Yes));
|
||||
closeHelper.start(Qt::Key_Escape, &mb);
|
||||
QCOMPARE(mb.exec(), int(QMessageBox::Cancel));
|
||||
#ifndef Q_OS_MAC
|
||||
// mnemonics are not used on OS X
|
||||
closeHelper.start(QKeyCombination(Qt::ALT | Qt::Key_R).toCombined(), &mb);
|
||||
QCOMPARE(mb.exec(), 0);
|
||||
closeHelper.start(QKeyCombination(Qt::ALT | Qt::Key_Z).toCombined(), &mb);
|
||||
QCOMPARE(mb.exec(), 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QMessageBox::detailsText()
|
||||
{
|
||||
QFETCH_GLOBAL(bool, useNativeDialog);
|
||||
if (useNativeDialog)
|
||||
QSKIP("Native dialogs do not propagate expose events");
|
||||
|
||||
QMessageBox box;
|
||||
QString text("This is the details text.");
|
||||
box.setDetailedText(text);
|
||||
QCOMPARE(box.detailedText(), text);
|
||||
box.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&box));
|
||||
// QTBUG-39334, the box should now have the default "Ok" button as well as
|
||||
// the "Show Details.." button.
|
||||
QCOMPARE(box.findChildren<QAbstractButton *>().size(), 2);
|
||||
}
|
||||
|
||||
void tst_QMessageBox::detailsButtonText()
|
||||
{
|
||||
QFETCH_GLOBAL(bool, useNativeDialog);
|
||||
if (useNativeDialog)
|
||||
QSKIP("Native dialogs do not propagate expose events");
|
||||
|
||||
QMessageBox box;
|
||||
box.setDetailedText("bla");
|
||||
box.open();
|
||||
QApplication::postEvent(&box, new QEvent(QEvent::LanguageChange));
|
||||
QApplication::processEvents();
|
||||
QDialogButtonBox* bb = box.findChild<QDialogButtonBox*>("qt_msgbox_buttonbox");
|
||||
QVERIFY(bb); //get the detail button
|
||||
|
||||
auto list = bb->buttons();
|
||||
for (auto btn : list) {
|
||||
if (btn && (btn->inherits("QPushButton"))) {
|
||||
if (btn->text().remove(QLatin1Char('&')) != QMessageBox::tr("OK")
|
||||
&& btn->text() != QMessageBox::tr("Show Details...")) {
|
||||
QFAIL(qPrintable(QString("Unexpected messagebox button text: %1").arg(btn->text())));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QMessageBox::expandDetailsWithoutMoving() // QTBUG-32473
|
||||
{
|
||||
QFETCH_GLOBAL(bool, useNativeDialog);
|
||||
if (useNativeDialog)
|
||||
QSKIP("Native dialogs do not propagate expose events");
|
||||
|
||||
tst_ResizingMessageBox box;
|
||||
box.setDetailedText("bla");
|
||||
box.show();
|
||||
QApplication::postEvent(&box, new QEvent(QEvent::LanguageChange));
|
||||
QApplication::processEvents();
|
||||
QDialogButtonBox* bb = box.findChild<QDialogButtonBox*>("qt_msgbox_buttonbox");
|
||||
QVERIFY(bb);
|
||||
|
||||
auto list = bb->buttons();
|
||||
auto it = std::find_if(list.rbegin(), list.rend(), [&](QAbstractButton *btn) {
|
||||
return btn && bb->buttonRole(btn) == QDialogButtonBox::ActionRole; });
|
||||
QVERIFY(it != list.rend());
|
||||
auto moreButton = *it;
|
||||
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&box));
|
||||
QTRY_VERIFY2(!box.geometry().topLeft().isNull(), "window manager is expected to decorate and position the dialog");
|
||||
QRect geom = box.geometry();
|
||||
box.resized = false;
|
||||
// now click the "more" button, and verify that the dialog resizes but does not move
|
||||
moreButton->click();
|
||||
QTRY_VERIFY(box.resized);
|
||||
QVERIFY(box.geometry().height() > geom.height());
|
||||
QCOMPARE(box.geometry().topLeft(), geom.topLeft());
|
||||
}
|
||||
|
||||
void tst_QMessageBox::incorrectDefaultButton()
|
||||
{
|
||||
ExecCloseHelper closeHelper;
|
||||
closeHelper.start(Qt::Key_Escape);
|
||||
//Do not crash here
|
||||
QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
|
||||
QMessageBox::question(nullptr, "", "I've been hit!",QMessageBox::Ok | QMessageBox::Cancel,QMessageBox::Save);
|
||||
QVERIFY(closeHelper.done());
|
||||
|
||||
closeHelper.start(Qt::Key_Escape);
|
||||
QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
|
||||
QMessageBox::question(nullptr, "", "I've been hit!",QFlag(QMessageBox::Ok | QMessageBox::Cancel),QMessageBox::Save);
|
||||
QVERIFY(closeHelper.done());
|
||||
|
||||
#if QT_DEPRECATED_SINCE(6, 2)
|
||||
closeHelper.start(Qt::Key_Escape);
|
||||
QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
|
||||
QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
//do not crash here -> call old function of QMessageBox in this case
|
||||
QMessageBox::question(nullptr, "", "I've been hit!",QMessageBox::Ok | QMessageBox::Cancel,QMessageBox::Save | QMessageBox::Cancel,QMessageBox::Ok);
|
||||
QT_WARNING_POP
|
||||
QVERIFY(closeHelper.done());
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QMessageBox::updateSize()
|
||||
{
|
||||
QMessageBox box;
|
||||
box.setText("This is awesome");
|
||||
box.show();
|
||||
QSize oldSize = box.size();
|
||||
QString longText;
|
||||
for (int i = 0; i < 20; i++)
|
||||
longText += box.text();
|
||||
box.setText(longText);
|
||||
QVERIFY(box.size() != oldSize); // should have grown
|
||||
QVERIFY(box.width() > oldSize.width() || box.height() > oldSize.height());
|
||||
oldSize = box.size();
|
||||
box.setStandardButtons(QMessageBox::StandardButtons(0xFFFF));
|
||||
QVERIFY(box.size() != oldSize); // should have grown
|
||||
QVERIFY(box.width() > oldSize.width() || box.height() > oldSize.height());
|
||||
}
|
||||
|
||||
void tst_QMessageBox::setInformativeText()
|
||||
{
|
||||
QMessageBox msgbox(QMessageBox::Warning, "", "", QMessageBox::Ok);
|
||||
QString itext = "This is a very long message and it should make the dialog have enough width to fit this message in";
|
||||
msgbox.setInformativeText(itext);
|
||||
msgbox.show();
|
||||
QCOMPARE(msgbox.informativeText(), itext);
|
||||
QVERIFY2(msgbox.width() > 190, //verify it's big enough (task181688)
|
||||
qPrintable(QString("%1 > 190").arg(msgbox.width())));
|
||||
}
|
||||
|
||||
void tst_QMessageBox::iconPixmap()
|
||||
{
|
||||
QMessageBox messageBox;
|
||||
QCOMPARE(messageBox.iconPixmap(), QPixmap());
|
||||
}
|
||||
|
||||
using SignalSignature = void(QDialog::*)();
|
||||
Q_DECLARE_METATYPE(SignalSignature);
|
||||
Q_DECLARE_METATYPE(QMessageBox::ButtonRole)
|
||||
|
||||
using ButtonsCreator = std::function<QList<QPushButton *>(QMessageBox &)>;
|
||||
Q_DECLARE_METATYPE(ButtonsCreator);
|
||||
|
||||
using RoleSet = QSet<QMessageBox::ButtonRole>;
|
||||
Q_DECLARE_METATYPE(RoleSet);
|
||||
|
||||
void tst_QMessageBox::acceptedRejectedSignals()
|
||||
{
|
||||
QFETCH_GLOBAL(bool, useNativeDialog);
|
||||
if (useNativeDialog)
|
||||
QSKIP("Native dialogs do not propagate expose events");
|
||||
|
||||
QMessageBox messageBox(QMessageBox::Information, "Test window", "Test text");
|
||||
|
||||
QFETCH(ButtonsCreator, buttonsCreator);
|
||||
QVERIFY(buttonsCreator);
|
||||
|
||||
const auto buttons = buttonsCreator(messageBox);
|
||||
QVERIFY(!buttons.isEmpty());
|
||||
|
||||
QFETCH(RoleSet, roles);
|
||||
QFETCH(SignalSignature, signalSignature);
|
||||
for (auto button: buttons) {
|
||||
QVERIFY(button);
|
||||
|
||||
messageBox.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&messageBox));
|
||||
|
||||
QSignalSpy spy(&messageBox, signalSignature);
|
||||
QVERIFY(spy.isValid());
|
||||
button->click();
|
||||
|
||||
if (roles.contains(messageBox.buttonRole(button)))
|
||||
QCOMPARE(spy.size(), 1);
|
||||
else
|
||||
QVERIFY(spy.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
static void addAcceptedRow(const char *title, ButtonsCreator bc)
|
||||
{
|
||||
QTest::newRow(title) << (RoleSet() << QMessageBox::AcceptRole << QMessageBox::YesRole)
|
||||
<< &QDialog::accepted << bc;
|
||||
}
|
||||
|
||||
static void addRejectedRow(const char *title, ButtonsCreator bc)
|
||||
{
|
||||
QTest::newRow(title) << (RoleSet() << QMessageBox::RejectRole << QMessageBox::NoRole)
|
||||
<< &QDialog::rejected << bc;
|
||||
}
|
||||
|
||||
static void addCustomButtonsData()
|
||||
{
|
||||
ButtonsCreator buttonsCreator = [](QMessageBox &messageBox) {
|
||||
QList<QPushButton *> buttons(QMessageBox::NRoles);
|
||||
for (int i = QMessageBox::AcceptRole; i < QMessageBox::NRoles; ++i) {
|
||||
buttons[i] = messageBox.addButton(
|
||||
QString("Button role: %1").arg(i), QMessageBox::ButtonRole(i));
|
||||
}
|
||||
|
||||
return buttons;
|
||||
};
|
||||
|
||||
addAcceptedRow("Accepted_CustomButtons", buttonsCreator);
|
||||
addRejectedRow("Rejected_CustomButtons", buttonsCreator);
|
||||
}
|
||||
|
||||
static void addStandardButtonsData()
|
||||
{
|
||||
ButtonsCreator buttonsCreator = [](QMessageBox &messageBox) {
|
||||
QList<QPushButton *> buttons;
|
||||
for (int i = QMessageBox::FirstButton; i <= QMessageBox::LastButton; i <<= 1)
|
||||
buttons << messageBox.addButton(QMessageBox::StandardButton(i));
|
||||
|
||||
return buttons;
|
||||
};
|
||||
|
||||
addAcceptedRow("Accepted_StandardButtons", buttonsCreator);
|
||||
addRejectedRow("Rejected_StandardButtons", buttonsCreator);
|
||||
}
|
||||
|
||||
void tst_QMessageBox::acceptedRejectedSignals_data()
|
||||
{
|
||||
QTest::addColumn<RoleSet>("roles");
|
||||
QTest::addColumn<SignalSignature>("signalSignature");
|
||||
QTest::addColumn<ButtonsCreator>("buttonsCreator");
|
||||
|
||||
addStandardButtonsData();
|
||||
addCustomButtonsData();
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QMessageBox)
|
||||
#include "tst_qmessagebox.moc"
|
2
tests/auto/widgets/dialogs/qprogressdialog/BLACKLIST
Normal file
2
tests/auto/widgets/dialogs/qprogressdialog/BLACKLIST
Normal file
@ -0,0 +1,2 @@
|
||||
[autoShow]
|
||||
macos
|
14
tests/auto/widgets/dialogs/qprogressdialog/CMakeLists.txt
Normal file
14
tests/auto/widgets/dialogs/qprogressdialog/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qprogressdialog Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qprogressdialog
|
||||
SOURCES
|
||||
tst_qprogressdialog.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
@ -0,0 +1,318 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
|
||||
#include <qapplication.h>
|
||||
#include <qdebug.h>
|
||||
#include <qprogressbar.h>
|
||||
#include <qprogressdialog.h>
|
||||
#include <qpushbutton.h>
|
||||
#include <qlabel.h>
|
||||
#include <qpointer.h>
|
||||
#include <qthread.h>
|
||||
#include <qtranslator.h>
|
||||
|
||||
class tst_QProgressDialog : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void cleanup();
|
||||
void autoShow_data();
|
||||
void autoShow();
|
||||
void autoShowCtor();
|
||||
void getSetCheck();
|
||||
void task198202();
|
||||
void QTBUG_31046();
|
||||
void QTBUG_19983();
|
||||
void settingCustomWidgets();
|
||||
void i18n();
|
||||
void setValueReentrancyGuard();
|
||||
};
|
||||
|
||||
void tst_QProgressDialog::cleanup()
|
||||
{
|
||||
QVERIFY(QApplication::topLevelWindows().empty());
|
||||
}
|
||||
|
||||
void tst_QProgressDialog::autoShow_data()
|
||||
{
|
||||
QTest::addColumn<int>("min");
|
||||
QTest::addColumn<int>("max");
|
||||
QTest::addColumn<int>("value"); // initial setValue call
|
||||
QTest::addColumn<int>("delay"); // then we wait for this long, and setValue(min+1)
|
||||
QTest::addColumn<int>("minDuration");
|
||||
QTest::addColumn<bool>("expectedAutoShow");
|
||||
|
||||
// Check that autoshow works even when not starting at 0
|
||||
QTest::newRow("50_to_100_slow_shown") << 50 << 100 << 50 << 100 << 100 << true; // 50*100ms = 5s
|
||||
QTest::newRow("50_to_100_fast_not_shown") << 50 << 100 << 50 << 1 << 100 << false; // 1ms is too short to even start estimating
|
||||
QTest::newRow("50_to_60_high_minDuration_not_shown") << 50 << 60 << 50 << 100 << 2000 << false; // 10*100ms = 1s < 2s
|
||||
|
||||
// Check that setValue(0) still starts the timer as previously documented
|
||||
QTest::newRow("50_to_100_slow_0_compat") << 50 << 100 << 0 << 100 << 100 << true; // 50*100ms = 5s
|
||||
QTest::newRow("50_to_100_fast_0_compat") << 50 << 100 << 0 << 1 << 100 << false; // 1ms is too short to even start estimating
|
||||
QTest::newRow("50_to_60_high_minDuration_0_compat") << 50 << 60 << 0 << 100 << 2000 << false; // 10*100ms = 1s < 2s
|
||||
|
||||
// Check the typical case of starting at 0
|
||||
QTest::newRow("0_to_100_slow_shown") << 0 << 100 << 0 << 100 << 100 << true; // 100*100ms = 10s > 100ms
|
||||
QTest::newRow("0_to_10_slow_shown") << 0 << 10 << 0 << 100 << 500 << true; // 10*100ms = 1s > 0.5s
|
||||
QTest::newRow("0_to_10_high_minDuration_not_shown") << 0 << 10 << 0 << 100 << 2000 << false; // 10*100ms = 1s < 2s
|
||||
|
||||
// Check the special case of going via 0 at some point
|
||||
QTest::newRow("-1_to_1_slow_shown") << -1 << 1 << -1 << 200 << 100 << true; // 1*200ms = 200ms > 100ms
|
||||
QTest::newRow("-1_to_1_fast_not_shown") << -1 << 1 << -1 << 10 << 100 << false; // 10ms is too short to even start estimating
|
||||
QTest::newRow("-1_to_1_high_minDuration_not_shown") << -1 << 1 << -1 << 100 << 2000 << false; // 1*100ms = 100ms < 2s
|
||||
|
||||
}
|
||||
|
||||
void tst_QProgressDialog::autoShow()
|
||||
{
|
||||
QFETCH(int, min);
|
||||
QFETCH(int, max);
|
||||
QFETCH(int, value);
|
||||
QFETCH(int, delay);
|
||||
QFETCH(int, minDuration);
|
||||
QFETCH(bool, expectedAutoShow);
|
||||
|
||||
QProgressDialog dlg("", "", min, max);
|
||||
if (minDuration != dlg.minimumDuration())
|
||||
dlg.setMinimumDuration(minDuration);
|
||||
dlg.reset(); // cancel the timer started in the constructor,
|
||||
// in order to test for the setValue() behavior instead
|
||||
// See autoShowCtor() for the ctor timer check
|
||||
dlg.setValue(value);
|
||||
QThread::msleep(delay);
|
||||
dlg.setValue(min+1);
|
||||
QCOMPARE(dlg.isVisible(), expectedAutoShow);
|
||||
}
|
||||
|
||||
void tst_QProgressDialog::autoShowCtor()
|
||||
{
|
||||
QProgressDialog dlg;
|
||||
QVERIFY(!dlg.isVisible());
|
||||
QThread::msleep(dlg.minimumDuration());
|
||||
QTRY_VERIFY(dlg.isVisible());
|
||||
}
|
||||
|
||||
// Testing get/set functions
|
||||
void tst_QProgressDialog::getSetCheck()
|
||||
{
|
||||
QProgressDialog obj1;
|
||||
// bool QProgressDialog::autoReset()
|
||||
// void QProgressDialog::setAutoReset(bool)
|
||||
obj1.setAutoReset(false);
|
||||
QCOMPARE(false, obj1.autoReset());
|
||||
obj1.setAutoReset(true);
|
||||
QCOMPARE(true, obj1.autoReset());
|
||||
|
||||
// bool QProgressDialog::autoClose()
|
||||
// void QProgressDialog::setAutoClose(bool)
|
||||
obj1.setAutoClose(false);
|
||||
QCOMPARE(false, obj1.autoClose());
|
||||
obj1.setAutoClose(true);
|
||||
QCOMPARE(true, obj1.autoClose());
|
||||
|
||||
// int QProgressDialog::maximum()
|
||||
// void QProgressDialog::setMaximum(int)
|
||||
obj1.setMaximum(0);
|
||||
QCOMPARE(0, obj1.maximum());
|
||||
obj1.setMaximum(INT_MIN);
|
||||
QCOMPARE(INT_MIN, obj1.maximum());
|
||||
obj1.setMaximum(INT_MAX);
|
||||
QCOMPARE(INT_MAX, obj1.maximum());
|
||||
|
||||
// int QProgressDialog::minimum()
|
||||
// void QProgressDialog::setMinimum(int)
|
||||
obj1.setMinimum(0);
|
||||
QCOMPARE(0, obj1.minimum());
|
||||
obj1.setMinimum(INT_MIN);
|
||||
QCOMPARE(INT_MIN, obj1.minimum());
|
||||
obj1.setMinimum(INT_MAX);
|
||||
QCOMPARE(INT_MAX, obj1.minimum());
|
||||
|
||||
// int QProgressDialog::value()
|
||||
// void QProgressDialog::setValue(int)
|
||||
obj1.setMaximum(INT_MAX);
|
||||
obj1.setMinimum(INT_MIN);
|
||||
obj1.setValue(0);
|
||||
QCOMPARE(0, obj1.value());
|
||||
obj1.setValue(INT_MIN+1);
|
||||
QCOMPARE(INT_MIN+1, obj1.value());
|
||||
obj1.setValue(INT_MIN);
|
||||
QCOMPARE(INT_MIN, obj1.value());
|
||||
obj1.setValue(INT_MAX-1);
|
||||
QCOMPARE(INT_MAX-1, obj1.value());
|
||||
|
||||
obj1.setValue(INT_MAX);
|
||||
QCOMPARE(INT_MIN, obj1.value()); // We set autoReset, the thing is reset
|
||||
|
||||
obj1.setAutoReset(false);
|
||||
obj1.setValue(INT_MAX);
|
||||
QCOMPARE(INT_MAX, obj1.value());
|
||||
obj1.setAutoReset(true);
|
||||
|
||||
// int QProgressDialog::minimumDuration()
|
||||
// void QProgressDialog::setMinimumDuration(int)
|
||||
obj1.setMinimumDuration(0);
|
||||
QCOMPARE(0, obj1.minimumDuration());
|
||||
obj1.setMinimumDuration(INT_MIN);
|
||||
QCOMPARE(INT_MIN, obj1.minimumDuration());
|
||||
obj1.setMinimumDuration(INT_MAX);
|
||||
QCOMPARE(INT_MAX, obj1.minimumDuration());
|
||||
}
|
||||
|
||||
void tst_QProgressDialog::task198202()
|
||||
{
|
||||
//should not crash
|
||||
QProgressDialog dlg(QLatin1String("test"),QLatin1String("test"),1,10);
|
||||
dlg.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&dlg));
|
||||
int futureHeight = dlg.sizeHint().height() - dlg.findChild<QLabel*>()->sizeHint().height();
|
||||
dlg.setLabel(0);
|
||||
QTest::ignoreMessage(QtWarningMsg, "QProgressDialog::setBar: Cannot set a null progress bar");
|
||||
dlg.setBar(0);
|
||||
QTRY_COMPARE(dlg.sizeHint().height(), futureHeight);
|
||||
}
|
||||
|
||||
void tst_QProgressDialog::QTBUG_31046()
|
||||
{
|
||||
QProgressDialog dlg("", "", 50, 60);
|
||||
dlg.setValue(0);
|
||||
QThread::msleep(200);
|
||||
dlg.setValue(50);
|
||||
QCOMPARE(50, dlg.value());
|
||||
}
|
||||
|
||||
void tst_QProgressDialog::QTBUG_19983()
|
||||
{
|
||||
QProgressDialog tempDlg;
|
||||
tempDlg.setRange(0, 0);
|
||||
tempDlg.setLabelText("This is a test.");
|
||||
|
||||
QPushButton *btnOne = new QPushButton("Cancel", &tempDlg);
|
||||
tempDlg.setCancelButton(btnOne);
|
||||
tempDlg.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&tempDlg));
|
||||
const auto btnOneGeometry = btnOne->geometry();
|
||||
QVERIFY(QPoint(0,0) != btnOneGeometry.topLeft());
|
||||
|
||||
tempDlg.cancel();
|
||||
QVERIFY(!tempDlg.isVisible());
|
||||
|
||||
QPushButton *btnTwo = new QPushButton("Cancel", &tempDlg);
|
||||
tempDlg.setCancelButton(btnTwo);
|
||||
tempDlg.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&tempDlg));
|
||||
QCOMPARE(btnOneGeometry, btnTwo->geometry());
|
||||
}
|
||||
|
||||
void tst_QProgressDialog::settingCustomWidgets()
|
||||
{
|
||||
QPointer<QLabel> l = new QLabel;
|
||||
QPointer<QPushButton> btn = new QPushButton;
|
||||
QPointer<QProgressBar> bar = new QProgressBar;
|
||||
QVERIFY(!l->parent());
|
||||
QVERIFY(!btn->parent());
|
||||
QVERIFY(!bar->parent());
|
||||
|
||||
{
|
||||
QProgressDialog dlg;
|
||||
|
||||
QVERIFY(!dlg.isAncestorOf(l));
|
||||
dlg.setLabel(l);
|
||||
QVERIFY(dlg.isAncestorOf(l));
|
||||
QTest::ignoreMessage(QtWarningMsg, "QProgressDialog::setLabel: Attempt to set the same label again");
|
||||
dlg.setLabel(l); // setting the same widget again should not crash
|
||||
QVERIFY(l); // and not delete the (old == new) widget
|
||||
|
||||
QVERIFY(!dlg.isAncestorOf(btn));
|
||||
dlg.setCancelButton(btn);
|
||||
QVERIFY(dlg.isAncestorOf(btn));
|
||||
QTest::ignoreMessage(QtWarningMsg, "QProgressDialog::setCancelButton: Attempt to set the same button again");
|
||||
dlg.setCancelButton(btn); // setting the same widget again should not crash
|
||||
QVERIFY(btn); // and not delete the (old == new) widget
|
||||
|
||||
QVERIFY(!dlg.isAncestorOf(bar));
|
||||
dlg.setBar(bar);
|
||||
QVERIFY(dlg.isAncestorOf(bar));
|
||||
QTest::ignoreMessage(QtWarningMsg, "QProgressDialog::setBar: Attempt to set the same progress bar again");
|
||||
dlg.setBar(bar); // setting the same widget again should not crash
|
||||
QVERIFY(bar); // and not delete the (old == new) widget
|
||||
}
|
||||
|
||||
QVERIFY(!l);
|
||||
QVERIFY(!btn);
|
||||
QVERIFY(!bar);
|
||||
}
|
||||
|
||||
class QTestTranslator : public QTranslator
|
||||
{
|
||||
const QString m_str;
|
||||
public:
|
||||
explicit QTestTranslator(QString str) : m_str(std::move(str)) {}
|
||||
|
||||
QString translate(const char *, const char *sourceText, const char *, int) const override
|
||||
{ return m_str + sourceText + m_str; }
|
||||
|
||||
bool isEmpty() const override { return false; }
|
||||
};
|
||||
|
||||
template <typename Translator>
|
||||
class QTranslatorGuard {
|
||||
Translator t;
|
||||
public:
|
||||
template <typename Arg>
|
||||
explicit QTranslatorGuard(Arg a) : t(std::move(a))
|
||||
{ qApp->installTranslator(&t); }
|
||||
~QTranslatorGuard()
|
||||
{ qApp->removeTranslator(&t); }
|
||||
};
|
||||
|
||||
void tst_QProgressDialog::i18n()
|
||||
{
|
||||
QProgressDialog dlg;
|
||||
QPushButton *btn = dlg.findChild<QPushButton*>();
|
||||
QVERIFY(btn);
|
||||
const QString xxx = QStringLiteral("xxx");
|
||||
{
|
||||
QTranslatorGuard<QTestTranslator> guard(xxx);
|
||||
{
|
||||
QPushButton *btn = dlg.findChild<QPushButton*>();
|
||||
QVERIFY(btn);
|
||||
QTRY_COMPARE(btn->text(), QProgressDialog::tr("Cancel"));
|
||||
QVERIFY(btn->text().startsWith(xxx));
|
||||
}
|
||||
}
|
||||
QVERIFY(btn);
|
||||
QTRY_COMPARE(btn->text(), QProgressDialog::tr("Cancel"));
|
||||
QVERIFY(!btn->text().startsWith(xxx));
|
||||
}
|
||||
|
||||
void tst_QProgressDialog::setValueReentrancyGuard()
|
||||
{
|
||||
// Tests setValue() of window modal QProgressBar with
|
||||
// Qt::QueuedConnection:
|
||||
// This test crashes with a stack overflow if the boolean
|
||||
// guard "processingEvents" that prevents reentranct calls
|
||||
// to QCoreApplication::processEvents() within setValue()
|
||||
// has not been implemented
|
||||
|
||||
constexpr int steps = 100; // Should be at least 50 to test for crash
|
||||
|
||||
QProgressDialog dlg("Testing setValue reentrancy guard...", QString(), 0, steps);
|
||||
dlg.setWindowModality(Qt::WindowModal);
|
||||
dlg.setMinimumDuration(0);
|
||||
dlg.setAutoReset(false);
|
||||
|
||||
// Simulate a quick work loop
|
||||
for (int i = 0; i <= steps; ++i)
|
||||
QMetaObject::invokeMethod(&dlg, "setValue", Qt::QueuedConnection, Q_ARG(int, i));
|
||||
|
||||
QTRY_COMPARE(dlg.value(), steps);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QProgressDialog)
|
||||
#include "tst_qprogressdialog.moc"
|
16
tests/auto/widgets/dialogs/qsidebar/CMakeLists.txt
Normal file
16
tests/auto/widgets/dialogs/qsidebar/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qsidebar Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qsidebar
|
||||
SOURCES
|
||||
tst_qsidebar.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
)
|
180
tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp
Normal file
180
tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp
Normal file
@ -0,0 +1,180 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
#include <QSignalSpy>
|
||||
|
||||
#include <QtWidgets/private/qsidebar_p.h>
|
||||
#include <QtGui/private/qfilesystemmodel_p.h>
|
||||
#include <QtWidgets/qfileiconprovider.h>
|
||||
|
||||
class tst_QSidebar : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void setUrls();
|
||||
void selectUrls();
|
||||
void addUrls();
|
||||
|
||||
void goToUrl();
|
||||
|
||||
private:
|
||||
QFileIconProvider defaultIconProvider;
|
||||
};
|
||||
|
||||
void tst_QSidebar::setUrls()
|
||||
{
|
||||
QList<QUrl> urls;
|
||||
QFileSystemModel fsmodel;
|
||||
fsmodel.setIconProvider(&defaultIconProvider);
|
||||
QSidebar qsidebar;
|
||||
qsidebar.setModelAndUrls(&fsmodel, urls);
|
||||
QAbstractItemModel *model = qsidebar.model();
|
||||
|
||||
urls << QUrl::fromLocalFile(QDir::rootPath())
|
||||
<< QUrl::fromLocalFile(QDir::temp().absolutePath());
|
||||
|
||||
QCOMPARE(model->rowCount(), 0);
|
||||
qsidebar.setUrls(urls);
|
||||
QCOMPARE(qsidebar.urls(), urls);
|
||||
QCOMPARE(model->rowCount(), urls.size());
|
||||
qsidebar.setUrls(urls);
|
||||
QCOMPARE(model->rowCount(), urls.size());
|
||||
}
|
||||
|
||||
void tst_QSidebar::selectUrls()
|
||||
{
|
||||
QList<QUrl> urls;
|
||||
urls << QUrl::fromLocalFile(QDir::rootPath())
|
||||
<< QUrl::fromLocalFile(QDir::temp().absolutePath());
|
||||
QFileSystemModel fsmodel;
|
||||
fsmodel.setIconProvider(&defaultIconProvider);
|
||||
QSidebar qsidebar;
|
||||
qsidebar.setModelAndUrls(&fsmodel, urls);
|
||||
|
||||
QSignalSpy spy(&qsidebar, SIGNAL(goToUrl(QUrl)));
|
||||
qsidebar.selectUrl(urls.at(0));
|
||||
QCOMPARE(spy.size(), 0);
|
||||
}
|
||||
|
||||
void tst_QSidebar::addUrls()
|
||||
{
|
||||
QList<QUrl> emptyUrls;
|
||||
QFileSystemModel fsmodel;
|
||||
fsmodel.setIconProvider(&defaultIconProvider);
|
||||
QSidebar qsidebar;
|
||||
qsidebar.setModelAndUrls(&fsmodel, emptyUrls);
|
||||
QAbstractItemModel *model = qsidebar.model();
|
||||
QDir testDir = QDir::home();
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
// temp and home is the same directory on Android
|
||||
testDir.mkdir(QStringLiteral("test"));
|
||||
QVERIFY(testDir.cd(QStringLiteral("test")));
|
||||
#endif
|
||||
|
||||
// default
|
||||
QCOMPARE(model->rowCount(), 0);
|
||||
|
||||
QList<QUrl> urls;
|
||||
urls << QUrl::fromLocalFile(QDir::rootPath())
|
||||
<< QUrl::fromLocalFile(QDir::temp().absolutePath());
|
||||
|
||||
// test < 0
|
||||
qsidebar.addUrls(urls, -1);
|
||||
QCOMPARE(model->rowCount(), 2);
|
||||
|
||||
// test = 0
|
||||
qsidebar.setUrls(emptyUrls);
|
||||
qsidebar.addUrls(urls, 0);
|
||||
QCOMPARE(model->rowCount(), 2);
|
||||
|
||||
// test > 0
|
||||
qsidebar.setUrls(emptyUrls);
|
||||
qsidebar.addUrls(urls, 100);
|
||||
QCOMPARE(model->rowCount(), 2);
|
||||
|
||||
// test inserting with already existing rows
|
||||
QList<QUrl> moreUrls;
|
||||
moreUrls << QUrl::fromLocalFile(testDir.absolutePath());
|
||||
qsidebar.addUrls(moreUrls, -1);
|
||||
QCOMPARE(model->rowCount(), 3);
|
||||
|
||||
// make sure invalid urls are still added
|
||||
QList<QUrl> badUrls;
|
||||
badUrls << QUrl::fromLocalFile(testDir.absolutePath() + "/I used to exist");
|
||||
qsidebar.addUrls(badUrls, 0);
|
||||
QCOMPARE(model->rowCount(), 4);
|
||||
|
||||
// check that every item has text and an icon including the above invalid one
|
||||
for (int i = 0; i < model->rowCount(); ++i) {
|
||||
QVERIFY(!model->index(i, 0).data().toString().isEmpty());
|
||||
QIcon icon = qvariant_cast<QIcon>(model->index(i, 0).data(Qt::DecorationRole));
|
||||
QVERIFY(!icon.isNull());
|
||||
}
|
||||
|
||||
// test moving up the list
|
||||
qsidebar.setUrls(emptyUrls);
|
||||
qsidebar.addUrls(urls, 100);
|
||||
qsidebar.addUrls(moreUrls, 100);
|
||||
QCOMPARE(model->rowCount(), 3);
|
||||
qsidebar.addUrls(moreUrls, 1);
|
||||
QCOMPARE(qsidebar.urls()[1], moreUrls[0]);
|
||||
|
||||
// test appending with -1
|
||||
qsidebar.setUrls(emptyUrls);
|
||||
qsidebar.addUrls(urls, -1);
|
||||
qsidebar.addUrls(moreUrls, -1);
|
||||
QCOMPARE(qsidebar.urls()[0], urls[0]);
|
||||
|
||||
QList<QUrl> doubleUrls;
|
||||
//tow exact same paths, we have only one entry
|
||||
doubleUrls << QUrl::fromLocalFile(testDir.absolutePath());
|
||||
doubleUrls << QUrl::fromLocalFile(testDir.absolutePath());
|
||||
qsidebar.setUrls(emptyUrls);
|
||||
qsidebar.addUrls(doubleUrls, 1);
|
||||
QCOMPARE(qsidebar.urls().size(), 1);
|
||||
|
||||
// Two paths that are effectively pointing to the same location
|
||||
doubleUrls << QUrl::fromLocalFile(testDir.absolutePath());
|
||||
doubleUrls << QUrl::fromLocalFile(testDir.absolutePath() + "/.");
|
||||
qsidebar.setUrls(emptyUrls);
|
||||
qsidebar.addUrls(doubleUrls, 1);
|
||||
QCOMPARE(qsidebar.urls().size(), 1);
|
||||
|
||||
doubleUrls << QUrl::fromLocalFile(testDir.absolutePath());
|
||||
doubleUrls << QUrl::fromLocalFile(testDir.absolutePath().toUpper());
|
||||
qsidebar.setUrls(emptyUrls);
|
||||
qsidebar.addUrls(doubleUrls, 1);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
//Windows is case insensitive so no duplicate entries in that case
|
||||
QCOMPARE(qsidebar.urls().size(), 1);
|
||||
#else
|
||||
//Two different paths we should have two entries
|
||||
QCOMPARE(qsidebar.urls().size(), 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QSidebar::goToUrl()
|
||||
{
|
||||
QList<QUrl> urls;
|
||||
urls << QUrl::fromLocalFile(QDir::rootPath())
|
||||
<< QUrl::fromLocalFile(QDir::temp().absolutePath());
|
||||
QFileSystemModel fsmodel;
|
||||
fsmodel.setIconProvider(&defaultIconProvider);
|
||||
QSidebar qsidebar;
|
||||
qsidebar.setModelAndUrls(&fsmodel, urls);
|
||||
qsidebar.show();
|
||||
|
||||
QSignalSpy spy(&qsidebar, SIGNAL(goToUrl(QUrl)));
|
||||
QTest::mousePress(qsidebar.viewport(), Qt::LeftButton, {},
|
||||
qsidebar.visualRect(qsidebar.model()->index(0, 0)).center());
|
||||
QCOMPARE(spy.size(), 1);
|
||||
QCOMPARE((spy.value(0)).at(0).toUrl(), urls.first());
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QSidebar)
|
||||
#include "tst_qsidebar.moc"
|
||||
|
3
tests/auto/widgets/dialogs/qwizard/BLACKLIST
Normal file
3
tests/auto/widgets/dialogs/qwizard/BLACKLIST
Normal file
@ -0,0 +1,3 @@
|
||||
# QTBUG-87394
|
||||
[setOption_IgnoreSubTitles]
|
||||
android
|
27
tests/auto/widgets/dialogs/qwizard/CMakeLists.txt
Normal file
27
tests/auto/widgets/dialogs/qwizard/CMakeLists.txt
Normal file
@ -0,0 +1,27 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qwizard Test:
|
||||
#####################################################################
|
||||
|
||||
# Resources:
|
||||
set(qwizard_resource_files
|
||||
"images/background.png"
|
||||
"images/banner.png"
|
||||
"images/logo.png"
|
||||
"images/watermark.png"
|
||||
)
|
||||
|
||||
qt_internal_add_test(tst_qwizard
|
||||
SOURCES
|
||||
tst_qwizard.cpp
|
||||
tst_qwizard_2.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
Qt::WidgetsPrivate
|
||||
TESTDATA ${qwizard_resource_files}
|
||||
BUILTIN_TESTDATA
|
||||
)
|
||||
|
BIN
tests/auto/widgets/dialogs/qwizard/images/background.png
Normal file
BIN
tests/auto/widgets/dialogs/qwizard/images/background.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
BIN
tests/auto/widgets/dialogs/qwizard/images/banner.png
Normal file
BIN
tests/auto/widgets/dialogs/qwizard/images/banner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
BIN
tests/auto/widgets/dialogs/qwizard/images/logo.png
Normal file
BIN
tests/auto/widgets/dialogs/qwizard/images/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
BIN
tests/auto/widgets/dialogs/qwizard/images/watermark.png
Normal file
BIN
tests/auto/widgets/dialogs/qwizard/images/watermark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
2743
tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
Normal file
2743
tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
Normal file
File diff suppressed because it is too large
Load Diff
170
tests/auto/widgets/dialogs/qwizard/tst_qwizard_2.cpp
Normal file
170
tests/auto/widgets/dialogs/qwizard/tst_qwizard_2.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDebug>
|
||||
#include <QLineEdit>
|
||||
#include <QMainWindow>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWizard>
|
||||
#include <QWizardPage>
|
||||
|
||||
#include <QTest>
|
||||
|
||||
class taskQTBUG_25691 : public QWizard
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
taskQTBUG_25691( QWidget * parent = nullptr );
|
||||
|
||||
~taskQTBUG_25691(void);
|
||||
};
|
||||
|
||||
class taskQTBUG_25691Page1 : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
taskQTBUG_25691Page1( QWidget * parent = nullptr );
|
||||
|
||||
~taskQTBUG_25691Page1(void);
|
||||
};
|
||||
|
||||
class taskQTBUG_25691Page2 : public QWizardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
taskQTBUG_25691Page2( QWidget * parent = nullptr );
|
||||
|
||||
virtual void initializePage(void) override;
|
||||
|
||||
~taskQTBUG_25691Page2(void);
|
||||
|
||||
private:
|
||||
QVBoxLayout * layout;
|
||||
QLineEdit * field0_value;
|
||||
QLineEdit * field1_value;
|
||||
QLineEdit * field2_value;
|
||||
};
|
||||
|
||||
|
||||
taskQTBUG_25691::taskQTBUG_25691( QWidget * parent )
|
||||
: QWizard( parent )
|
||||
{
|
||||
this->addPage( new taskQTBUG_25691Page1 );
|
||||
this->addPage( new taskQTBUG_25691Page2 );
|
||||
this->show();
|
||||
}
|
||||
|
||||
taskQTBUG_25691::~taskQTBUG_25691(void)
|
||||
{
|
||||
}
|
||||
|
||||
taskQTBUG_25691Page1::taskQTBUG_25691Page1( QWidget * parent )
|
||||
: QWizardPage( parent )
|
||||
{
|
||||
QComboBox * field0_needed = new QComboBox( this );
|
||||
field0_needed->addItem( "No" );
|
||||
field0_needed->addItem( "Yes" );
|
||||
field0_needed->setCurrentIndex(0);
|
||||
this->registerField( "field0_needed", field0_needed );
|
||||
|
||||
QComboBox * field1_needed = new QComboBox( this );
|
||||
field1_needed->addItem( "No" );
|
||||
field1_needed->addItem( "Yes" );
|
||||
field1_needed->setCurrentIndex(0);
|
||||
this->registerField( "field1_needed", field1_needed );
|
||||
|
||||
QComboBox * field2_needed = new QComboBox( this );
|
||||
field2_needed->addItem( "No" );
|
||||
field2_needed->addItem( "Yes" );
|
||||
field2_needed->setCurrentIndex(0);
|
||||
this->registerField( "field2_needed", field2_needed );
|
||||
|
||||
QVBoxLayout * layout = new QVBoxLayout;
|
||||
layout->addWidget( field0_needed );
|
||||
layout->addWidget( field1_needed );
|
||||
layout->addWidget( field2_needed );
|
||||
this->setLayout( layout );
|
||||
}
|
||||
|
||||
taskQTBUG_25691Page1::~taskQTBUG_25691Page1(void)
|
||||
{
|
||||
}
|
||||
|
||||
taskQTBUG_25691Page2::taskQTBUG_25691Page2( QWidget * parent )
|
||||
: QWizardPage( parent )
|
||||
{
|
||||
this->layout = new QVBoxLayout;
|
||||
this->setLayout( this->layout );
|
||||
|
||||
this->field0_value = 0;
|
||||
this->field1_value = 0;
|
||||
this->field2_value = 0;
|
||||
}
|
||||
|
||||
void taskQTBUG_25691Page2::initializePage(void)
|
||||
{
|
||||
QWizard * wizard = this->wizard();
|
||||
bool field0_needed = wizard->field( "field0_needed" ).toBool();
|
||||
bool field1_needed = wizard->field( "field1_needed" ).toBool();
|
||||
bool field2_needed = wizard->field( "field2_needed" ).toBool();
|
||||
|
||||
if ( field0_needed && this->field0_value == 0 ){
|
||||
this->field0_value = new QLineEdit( "field0_default" );
|
||||
this->registerField( "field0_value", this->field0_value );
|
||||
this->layout->addWidget( this->field0_value );
|
||||
} else if ( ! field0_needed && this->field0_value != 0 ){
|
||||
this->layout->removeWidget( this->field0_value );
|
||||
delete this->field0_value;
|
||||
this->field0_value = 0;
|
||||
}
|
||||
|
||||
if ( field1_needed && this->field1_value == 0 ){
|
||||
this->field1_value = new QLineEdit( "field1_default" );
|
||||
this->registerField( "field1_value", this->field1_value );
|
||||
this->layout->addWidget( this->field1_value );
|
||||
} else if ( ! field1_needed && this->field1_value != 0 ){
|
||||
this->layout->removeWidget( this->field1_value );
|
||||
delete this->field1_value;
|
||||
this->field1_value = 0;
|
||||
}
|
||||
|
||||
if ( field2_needed && this->field2_value == 0 ){
|
||||
this->field2_value = new QLineEdit( "field2_default" );
|
||||
this->registerField( "field2_value", this->field2_value );
|
||||
this->layout->addWidget( this->field2_value );
|
||||
} else if ( ! field2_needed && this->field2_value != 0 ){
|
||||
this->layout->removeWidget( this->field2_value );
|
||||
delete this->field2_value;
|
||||
this->field2_value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
taskQTBUG_25691Page2::~taskQTBUG_25691Page2(void)
|
||||
{
|
||||
}
|
||||
|
||||
void taskQTBUG_25691_fieldObjectDestroyed2(void)
|
||||
{
|
||||
QMainWindow mw;
|
||||
taskQTBUG_25691 wb( &mw );
|
||||
|
||||
wb.setField( "field0_needed", true );
|
||||
wb.setField( "field1_needed", true );
|
||||
wb.setField( "field2_needed", true );
|
||||
wb.next(); // Results in registration of all three field_Nvalue fields
|
||||
wb.back(); // Back up to cancel need for field1_value
|
||||
wb.setField( "field1_needed", false ); // cancel need for field1_value
|
||||
wb.next(); // Results in destruction of field field1_value's widget
|
||||
wb.next(); // Commit wizard's results
|
||||
|
||||
// Now collect the value from fields that was not destroyed.
|
||||
QString field0_value = wb.field( "field0_value" ).toString();
|
||||
QCOMPARE( field0_value, QString("field0_default") );
|
||||
|
||||
QString field2_value = wb.field( "field2_value" ).toString();
|
||||
QCOMPARE( field2_value, QString("field2_default") );
|
||||
}
|
||||
|
||||
#include "tst_qwizard_2.moc"
|
Reference in New Issue
Block a user