summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/dialogs
diff options
context:
space:
mode:
authorJo Asplin <jo.asplin@nokia.com>2011-10-20 13:17:26 +0200
committerQt by Nokia <qt-info@nokia.com>2011-10-20 19:45:41 +0200
commit9f1aa866bda7678261f2f441d4cfd5bb524c2411 (patch)
tree5028f578122e7feb9200d571405494c73d96db89 /tests/auto/widgets/dialogs
parent78d02e93aca5325fc5be9bfd275862795207abaa (diff)
Moved tests into integrationtests/ and widgets/
Task-number: QTBUG-19013 Change-Id: Ibb776f5967c0645ce6d22ef7afdc40657c575461 Reviewed-by: Holger Ihrig <holger.ihrig@nokia.com>
Diffstat (limited to 'tests/auto/widgets/dialogs')
-rw-r--r--tests/auto/widgets/dialogs/dialogs.pro18
-rw-r--r--tests/auto/widgets/dialogs/qabstractprintdialog/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qabstractprintdialog/qabstractprintdialog.pro9
-rw-r--r--tests/auto/widgets/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp146
-rw-r--r--tests/auto/widgets/dialogs/qcolordialog/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro6
-rw-r--r--tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp164
-rw-r--r--tests/auto/widgets/dialogs/qdialog/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qdialog/qdialog.pro5
-rw-r--r--tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp609
-rw-r--r--tests/auto/widgets/dialogs/qerrormessage/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qerrormessage/qerrormessage.pro10
-rw-r--r--tests/auto/widgets/dialogs/qerrormessage/tst_qerrormessage.cpp158
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog/qfiledialog.pro23
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog/resources/file.txt1
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp1349
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro20
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp1213
-rw-r--r--tests/auto/widgets/dialogs/qfilesystemmodel/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro7
-rw-r--r--tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp1046
-rw-r--r--tests/auto/widgets/dialogs/qfontdialog/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qfontdialog/qfontdialog.pro12
-rw-r--r--tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp186
-rw-r--r--tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog_mac_helpers.mm67
-rw-r--r--tests/auto/widgets/dialogs/qinputdialog/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qinputdialog/qinputdialog.pro5
-rw-r--r--tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp430
-rw-r--r--tests/auto/widgets/dialogs/qmessagebox/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qmessagebox/qmessagebox.pro9
-rw-r--r--tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp674
-rw-r--r--tests/auto/widgets/dialogs/qprogressdialog/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qprogressdialog/qprogressdialog.pro9
-rw-r--r--tests/auto/widgets/dialogs/qprogressdialog/tst_qprogressdialog.cpp157
-rw-r--r--tests/auto/widgets/dialogs/qsidebar/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qsidebar/qsidebar.pro6
-rw-r--r--tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp231
-rw-r--r--tests/auto/widgets/dialogs/qwizard/.gitignore1
-rw-r--r--tests/auto/widgets/dialogs/qwizard/images/background.pngbin0 -> 22932 bytes
-rw-r--r--tests/auto/widgets/dialogs/qwizard/images/banner.pngbin0 -> 4230 bytes
-rw-r--r--tests/auto/widgets/dialogs/qwizard/images/logo.pngbin0 -> 1661 bytes
-rw-r--r--tests/auto/widgets/dialogs/qwizard/images/watermark.pngbin0 -> 15788 bytes
-rw-r--r--tests/auto/widgets/dialogs/qwizard/qwizard.pro4
-rw-r--r--tests/auto/widgets/dialogs/qwizard/qwizard.qrc8
-rw-r--r--tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp2645
46 files changed, 9239 insertions, 0 deletions
diff --git a/tests/auto/widgets/dialogs/dialogs.pro b/tests/auto/widgets/dialogs/dialogs.pro
new file mode 100644
index 0000000000..e74323a305
--- /dev/null
+++ b/tests/auto/widgets/dialogs/dialogs.pro
@@ -0,0 +1,18 @@
+TEMPLATE=subdirs
+SUBDIRS=\
+ qabstractprintdialog \
+ qcolordialog \
+ qdialog \
+ qerrormessage \
+ qfiledialog \
+ qfiledialog2 \
+ qfilesystemmodel \
+ qfontdialog \
+ qinputdialog \
+ qmessagebox \
+ qprogressdialog \
+ qsidebar \
+ qwizard \
+
+!contains(QT_CONFIG, private_tests): SUBDIRS -= \
+ qsidebar \
diff --git a/tests/auto/widgets/dialogs/qabstractprintdialog/.gitignore b/tests/auto/widgets/dialogs/qabstractprintdialog/.gitignore
new file mode 100644
index 0000000000..a768494da5
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qabstractprintdialog/.gitignore
@@ -0,0 +1 @@
+tst_qabstractprintdialog
diff --git a/tests/auto/widgets/dialogs/qabstractprintdialog/qabstractprintdialog.pro b/tests/auto/widgets/dialogs/qabstractprintdialog/qabstractprintdialog.pro
new file mode 100644
index 0000000000..fb72bbf7a9
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qabstractprintdialog/qabstractprintdialog.pro
@@ -0,0 +1,9 @@
+############################################################
+# Project file for autotest for file qabstractprintdialog.h
+############################################################
+
+load(qttest_p4)
+QT += widgets printsupport
+SOURCES += tst_qabstractprintdialog.cpp
+
+CONFIG += insignificant_test # QTBUG-21402
diff --git a/tests/auto/widgets/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp b/tests/auto/widgets/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp
new file mode 100644
index 0000000000..5d6165d174
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <qcoreapplication.h>
+#include <qdebug.h>
+#include <qabstractprintdialog.h>
+#include <qprinter.h>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QAbstractPrintDialog : public QObject
+{
+Q_OBJECT
+
+#if defined(QT_NO_PRINTER) || defined(QT_NO_PRINTDIALOG)
+public slots:
+ void initTestCase();
+#else
+private slots:
+ void getSetCheck();
+ void setMinMax();
+ void setFromTo();
+#endif
+};
+
+#if defined(QT_NO_PRINTER) || defined(QT_NO_PRINTDIALOG)
+void tst_QAbstractPrintDialog::initTestCase()
+{
+ QSKIP("This test requires printing and print dialog support", SkipAll);
+}
+
+#else
+
+class MyAbstractPrintDialog : public QAbstractPrintDialog
+{
+public:
+ MyAbstractPrintDialog(QPrinter *p) : QAbstractPrintDialog(p) {}
+ int exec() { return 0; }
+};
+
+// Testing get/set functions
+void tst_QAbstractPrintDialog::getSetCheck()
+{
+ QPrinter printer;
+ MyAbstractPrintDialog obj1(&printer);
+ QCOMPARE(obj1.printer(), &printer);
+ // PrintDialogOptions QAbstractPrintDialog::enabledOptions()
+ // void QAbstractPrintDialog::setEnabledOptions(PrintDialogOptions)
+ obj1.setEnabledOptions(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::None));
+ QCOMPARE(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::None), obj1.enabledOptions());
+ obj1.setEnabledOptions(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintToFile));
+ QCOMPARE(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintToFile), obj1.enabledOptions());
+ obj1.setEnabledOptions(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintSelection));
+ QCOMPARE(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintSelection), obj1.enabledOptions());
+ obj1.setEnabledOptions(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintPageRange));
+ QCOMPARE(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintPageRange), obj1.enabledOptions());
+ obj1.setEnabledOptions(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintCollateCopies));
+ QCOMPARE(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::PrintCollateCopies), obj1.enabledOptions());
+
+ // PrintRange QAbstractPrintDialog::printRange()
+ // void QAbstractPrintDialog::setPrintRange(PrintRange)
+ obj1.setPrintRange(QAbstractPrintDialog::PrintRange(QAbstractPrintDialog::AllPages));
+ QCOMPARE(QAbstractPrintDialog::PrintRange(QAbstractPrintDialog::AllPages), obj1.printRange());
+ obj1.setPrintRange(QAbstractPrintDialog::PrintRange(QAbstractPrintDialog::Selection));
+ QCOMPARE(QAbstractPrintDialog::PrintRange(QAbstractPrintDialog::Selection), obj1.printRange());
+ obj1.setPrintRange(QAbstractPrintDialog::PrintRange(QAbstractPrintDialog::PageRange));
+ QCOMPARE(QAbstractPrintDialog::PrintRange(QAbstractPrintDialog::PageRange), obj1.printRange());
+}
+
+void tst_QAbstractPrintDialog::setMinMax()
+{
+ QPrinter printer;
+ MyAbstractPrintDialog obj1(&printer);
+ obj1.setEnabledOptions(QAbstractPrintDialog::PrintDialogOptions(QAbstractPrintDialog::None));
+ QCOMPARE(obj1.minPage(), 1);
+ QCOMPARE(obj1.maxPage(), INT_MAX);
+ QVERIFY(!obj1.isOptionEnabled(QAbstractPrintDialog::PrintPageRange));
+ obj1.setMinMax(2,5);
+ QCOMPARE(obj1.minPage(), 2);
+ QCOMPARE(obj1.maxPage(), 5);
+ QVERIFY(obj1.enabledOptions() & QAbstractPrintDialog::PrintPageRange);
+ QVERIFY(obj1.isOptionEnabled(QAbstractPrintDialog::PrintPageRange));
+}
+
+void tst_QAbstractPrintDialog::setFromTo()
+{
+ QPrinter printer;
+ MyAbstractPrintDialog obj1(&printer);
+ QCOMPARE(obj1.fromPage(), 0);
+ QCOMPARE(obj1.toPage(), 0);
+ obj1.setMinMax(0,0);
+ QCOMPARE(obj1.minPage(), 0);
+ QCOMPARE(obj1.maxPage(), 0);
+ obj1.setFromTo(20,50);
+ QCOMPARE(obj1.fromPage(), 20);
+ QCOMPARE(obj1.toPage(), 50);
+ QCOMPARE(obj1.minPage(), 1);
+ QCOMPARE(obj1.maxPage(), 50);
+}
+
+#endif
+
+QTEST_MAIN(tst_QAbstractPrintDialog)
+#include "tst_qabstractprintdialog.moc"
diff --git a/tests/auto/widgets/dialogs/qcolordialog/.gitignore b/tests/auto/widgets/dialogs/qcolordialog/.gitignore
new file mode 100644
index 0000000000..b7a8ebd8f8
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qcolordialog/.gitignore
@@ -0,0 +1 @@
+tst_qcolordialog
diff --git a/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro b/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro
new file mode 100644
index 0000000000..4f195dac2b
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qcolordialog/qcolordialog.pro
@@ -0,0 +1,6 @@
+load(qttest_p4)
+QT += widgets
+SOURCES += tst_qcolordialog.cpp
+
+
+
diff --git a/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp b/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp
new file mode 100644
index 0000000000..3ae1e63a8e
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QtGui/QtGui>
+#include <QtWidgets/QColorDialog>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+QT_FORWARD_DECLARE_CLASS(QtTestEventThread)
+
+class tst_QColorDialog : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QColorDialog();
+ virtual ~tst_QColorDialog();
+
+#ifndef Q_WS_MAC
+public slots:
+ void postKeyReturn();
+private slots:
+ void defaultOkButton();
+#endif
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void native_activeModalWidget();
+ void task247349_alpha();
+};
+
+class TestNativeDialog : public QColorDialog
+{
+ Q_OBJECT
+public:
+ QWidget *m_activeModalWidget;
+
+ TestNativeDialog(QWidget *parent = 0)
+ : 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::native_activeModalWidget()
+{
+ // Check that QApplication::activeModalWidget retruns the
+ // color dialog when it is executing, even when using a native
+ // dialog:
+ TestNativeDialog d;
+ QTimer::singleShot(1000, &d, SLOT(hide()));
+ d.exec();
+ QVERIFY(&d == d.m_activeModalWidget);
+}
+
+void tst_QColorDialog::initTestCase()
+{
+}
+
+void tst_QColorDialog::cleanupTestCase()
+{
+}
+
+void tst_QColorDialog::init()
+{
+}
+
+void tst_QColorDialog::cleanup()
+{
+}
+
+#ifndef Q_WS_MAC
+//copied from QFontDialogTest
+void tst_QColorDialog::postKeyReturn() {
+ QWidgetList list = QApplication::topLevelWidgets();
+ for (int i=0; i<list.count(); ++i) {
+ QColorDialog *dialog = qobject_cast<QColorDialog *>(list[i]);
+ if (dialog) {
+ QTest::keyClick( list[i], Qt::Key_Return, Qt::NoModifier );
+ return;
+ }
+ }
+}
+
+void tst_QColorDialog::defaultOkButton()
+{
+ bool ok = false;
+ QTimer::singleShot(500, this, SLOT(postKeyReturn()));
+ QColorDialog::getRgba(0xffffffff, &ok);
+ QVERIFY(ok);
+}
+#endif
+
+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()));
+}
+
+QTEST_MAIN(tst_QColorDialog)
+#include "tst_qcolordialog.moc"
diff --git a/tests/auto/widgets/dialogs/qdialog/.gitignore b/tests/auto/widgets/dialogs/qdialog/.gitignore
new file mode 100644
index 0000000000..4a4b5ebcbe
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qdialog/.gitignore
@@ -0,0 +1 @@
+tst_qdialog
diff --git a/tests/auto/widgets/dialogs/qdialog/qdialog.pro b/tests/auto/widgets/dialogs/qdialog/qdialog.pro
new file mode 100644
index 0000000000..a3596b60f6
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qdialog/qdialog.pro
@@ -0,0 +1,5 @@
+load(qttest_p4)
+QT += widgets
+SOURCES += tst_qdialog.cpp
+
+CONFIG += insignificant_test # QTBUG-21402
diff --git a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp
new file mode 100644
index 0000000000..0f4acdcc9e
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp
@@ -0,0 +1,609 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <qdialog.h>
+#include <qapplication.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qstyle.h>
+#include <QVBoxLayout>
+#include <QSizeGrip>
+
+Q_DECLARE_METATYPE(QSize)
+
+
+QT_FORWARD_DECLARE_CLASS(QDialog)
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QDialog : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QDialog();
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+private slots:
+ void getSetCheck();
+ void showExtension_data();
+ void showExtension();
+ void defaultButtons();
+ void showMaximized();
+ void showMinimized();
+ void showFullScreen();
+#if !defined(Q_WS_X11) && !defined(Q_OS_WINCE)
+ void showAsTool();
+#endif
+#ifndef Q_OS_WINCE
+ void toolDialogPosition();
+#endif
+ void deleteMainDefault();
+ void deleteInExec();
+#if !defined(QT_NO_EXCEPTIONS) && !defined(Q_OS_MAC) && !(defined(Q_OS_WINCE) && defined(_ARM_))
+ void throwInExec();
+#endif
+ void showSizeGrip();
+ void setVisible();
+ void reject();
+
+private:
+ QDialog *testWidget;
+};
+
+// Testing get/set functions
+void tst_QDialog::getSetCheck()
+{
+ QDialog obj1;
+ // QWidget* QDialog::extension()
+ // void QDialog::setExtension(QWidget*)
+ QWidget *var1 = new QWidget;
+ obj1.setExtension(var1);
+ QCOMPARE(var1, obj1.extension());
+ obj1.setExtension((QWidget *)0);
+ QCOMPARE((QWidget *)0, obj1.extension());
+ // No delete var1, since setExtension takes ownership
+
+ // 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());
+}
+
+// work around function being protected
+class DummyDialog : public QDialog {
+public:
+ DummyDialog(): QDialog(0) {}
+ void showExtension( bool b ) { QDialog::showExtension( b ); }
+};
+
+class ToolDialog : public QDialog
+{
+public:
+ ToolDialog(QWidget *parent = 0) : QDialog(parent, Qt::Tool), mWasActive(false), tId(-1) {
+ }
+ bool wasActive() const { return mWasActive; }
+
+ int exec() {
+ tId = startTimer(300);
+ return QDialog::exec();
+ }
+protected:
+ void timerEvent(QTimerEvent *event) {
+ if (tId == event->timerId()) {
+ killTimer(tId);
+ mWasActive = isActiveWindow();
+ reject();
+ }
+ }
+
+private:
+ int mWasActive;
+ int tId;
+};
+
+tst_QDialog::tst_QDialog()
+
+{
+}
+
+void tst_QDialog::initTestCase()
+{
+ // Create the test class
+ testWidget = new QDialog(0, Qt::X11BypassWindowManagerHint);
+ testWidget->resize(200,200);
+ testWidget->show();
+ qApp->setActiveWindow(testWidget);
+}
+
+void tst_QDialog::cleanupTestCase()
+{
+ if (testWidget) {
+ delete testWidget;
+ testWidget = 0;
+ }
+}
+
+void tst_QDialog::showExtension_data()
+{
+ QTest::addColumn<QSize>("dlgSize");
+ QTest::addColumn<QSize>("extSize");
+ QTest::addColumn<bool>("horizontal");
+ QTest::addColumn<QSize>("result");
+
+ //next we fill it with data
+ QTest::newRow( "data0" ) << QSize(100,100) << QSize(50,50) << (bool)FALSE << QSize(100,150);
+ QTest::newRow( "data1" ) << QSize(100,100) << QSize(120,50) << (bool)FALSE << QSize(120,150);
+ QTest::newRow( "data2" ) << QSize(100,100) << QSize(50,50) << (bool)TRUE << QSize(150,100);
+ QTest::newRow( "data3" ) << QSize(100,100) << QSize(50,120) << (bool)TRUE << QSize(150,120);
+}
+
+void tst_QDialog::showExtension()
+{
+ QFETCH( QSize, dlgSize );
+ QFETCH( QSize, extSize );
+ QFETCH( bool, horizontal );
+
+ // set geometry of main dialog and extension widget
+ testWidget->setFixedSize( dlgSize );
+ QWidget *ext = new QWidget( testWidget );
+ ext->setFixedSize( extSize );
+ testWidget->setExtension( ext );
+ testWidget->setOrientation( horizontal ? Qt::Horizontal : Qt::Vertical );
+
+ QCOMPARE( testWidget->size(), dlgSize );
+ QPoint oldPosition = testWidget->pos();
+
+ // show
+ ((DummyDialog*)testWidget)->showExtension( TRUE );
+// while ( testWidget->size() == dlgSize )
+// qApp->processEvents();
+
+ QTEST( testWidget->size(), "result" );
+
+ QCOMPARE(testWidget->pos(), oldPosition);
+
+ // hide extension. back to old size ?
+ ((DummyDialog*)testWidget)->showExtension( FALSE );
+ QCOMPARE( testWidget->size(), dlgSize );
+
+ testWidget->setExtension( 0 );
+}
+
+void tst_QDialog::defaultButtons()
+{
+ 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);
+
+ //we need to show the buttons. Otherwise they won't get the focus
+ push->show();
+ pushTwo->show();
+ pushThree->show();
+
+ 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);
+ QSizeGrip *sizeGrip = qFindChild<QSizeGrip *>(&dialog);
+ QVERIFY(sizeGrip);
+
+ dialog.showMaximized();
+ QVERIFY(dialog.isMaximized());
+ QVERIFY(dialog.isVisible());
+#if !defined(Q_OS_MAC) && !defined(Q_OS_IRIX) && !defined(Q_OS_HPUX)
+ QVERIFY(!sizeGrip->isVisible());
+#endif
+
+ dialog.showNormal();
+ QVERIFY(!dialog.isMaximized());
+ QVERIFY(dialog.isVisible());
+ QVERIFY(sizeGrip->isVisible());
+
+ dialog.showMaximized();
+ QVERIFY(dialog.isMaximized());
+ QVERIFY(dialog.isVisible());
+
+ dialog.hide();
+ QVERIFY(dialog.isMaximized());
+ QVERIFY(!dialog.isVisible());
+
+ dialog.show();
+ 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.show();
+ 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);
+ QSizeGrip *sizeGrip = qFindChild<QSizeGrip *>(&dialog);
+ QVERIFY(sizeGrip);
+
+ qApp->syncX();
+ dialog.showFullScreen();
+ QVERIFY(dialog.isFullScreen());
+ QVERIFY(dialog.isVisible());
+ QVERIFY(!sizeGrip->isVisible());
+
+ qApp->syncX();
+ dialog.showNormal();
+ QVERIFY(!dialog.isFullScreen());
+ QVERIFY(dialog.isVisible());
+ QVERIFY(sizeGrip->isVisible());
+
+ qApp->syncX();
+ dialog.showFullScreen();
+ QVERIFY(dialog.isFullScreen());
+ QVERIFY(dialog.isVisible());
+
+ qApp->syncX();
+ dialog.hide();
+ QVERIFY(dialog.isFullScreen());
+ QVERIFY(!dialog.isVisible());
+
+ qApp->syncX();
+ dialog.show();
+ QVERIFY(dialog.isFullScreen());
+ QVERIFY(dialog.isVisible());
+
+ qApp->syncX();
+ dialog.hide();
+ QVERIFY(dialog.isFullScreen());
+ QVERIFY(!dialog.isVisible());
+
+ qApp->syncX();
+ dialog.showFullScreen();
+ QVERIFY(dialog.isFullScreen());
+ QVERIFY(dialog.isVisible());
+
+ qApp->syncX();
+ dialog.hide();
+ QVERIFY(dialog.isFullScreen());
+ QVERIFY(!dialog.isVisible());
+}
+
+// Qt/X11: Skipped since activeWindow() is not respected by all window managers.
+// Qt/WinCE: No real support for Qt::Tool on WinCE.
+#if !defined(Q_WS_X11) && !defined(Q_OS_WINCE)
+void tst_QDialog::showAsTool()
+{
+ ToolDialog dialog(testWidget);
+ testWidget->activateWindow();
+ dialog.exec();
+ QTest::qWait(100);
+ if (testWidget->style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, testWidget)) {
+ QCOMPARE(dialog.wasActive(), true);
+ } else {
+ QCOMPARE(dialog.wasActive(), false);
+ }
+}
+#endif
+
+// Verify that pos() returns the same before and after show()
+// for a dialog with the Tool window type.
+// No real support for Qt::Tool on WinCE, so skip this test.
+#ifndef Q_OS_WINCE
+void tst_QDialog::toolDialogPosition()
+{
+ QDialog dialog(0, Qt::Tool);
+ dialog.move(QPoint(100,100));
+ const QPoint beforeShowPosition = dialog.pos();
+ dialog.show();
+ const QPoint afterShowPosition = dialog.pos();
+ QCOMPARE(afterShowPosition, beforeShowPosition);
+}
+#endif
+
+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));
+}
+
+// Throwing exceptions in exec() is not supported on Mac or on WinCE/ARM.
+#if !defined(QT_NO_EXCEPTIONS) && !defined(Q_OS_MAC) && !(defined(Q_OS_WINCE) && defined(_ARM_))
+class QDialogTestException : public std::exception { };
+
+class ExceptionDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ ExceptionDialog() : QDialog(0) { }
+public slots:
+ void throwException()
+ {
+ QDialogTestException e;
+ throw e;
+ }
+};
+
+void tst_QDialog::throwInExec()
+{
+#if defined(Q_OS_LINUX)
+ // C++ exceptions can't be passed through glib callbacks. Skip the test if
+ // we're using the glib event loop.
+ QByteArray dispatcher = QAbstractEventDispatcher::instance()->metaObject()->className();
+ if (dispatcher.contains("Glib")) {
+ QSKIP(
+ qPrintable(QString(
+ "Throwing exceptions in exec() won't work if %1 event dispatcher is used.\n"
+ "Try running with QT_NO_GLIB=1 in environment."
+ ).arg(QString::fromLatin1(dispatcher))),
+ SkipAll
+ );
+ }
+#endif
+
+ int caughtExceptions = 0;
+ try {
+ ExceptionDialog dialog;
+ QMetaObject::invokeMethod(&dialog, "throwException", Qt::QueuedConnection);
+ QMetaObject::invokeMethod(&dialog, "reject", Qt::QueuedConnection);
+ (void) dialog.exec();
+ } catch(...) {
+ ++caughtExceptions;
+ }
+ QCOMPARE(caughtExceptions, 1);
+}
+#endif
+
+// From Task 124269
+void tst_QDialog::showSizeGrip()
+{
+#ifndef QT_NO_SIZEGRIP
+ QDialog dialog(0);
+ dialog.show();
+ QWidget *ext = new QWidget(&dialog);
+ QVERIFY(!dialog.extension());
+ QVERIFY(!dialog.isSizeGripEnabled());
+
+ dialog.setSizeGripEnabled(true);
+ QPointer<QSizeGrip> sizeGrip = qFindChild<QSizeGrip *>(&dialog);
+ QVERIFY(sizeGrip);
+ QVERIFY(sizeGrip->isVisible());
+ QVERIFY(dialog.isSizeGripEnabled());
+
+ dialog.setExtension(ext);
+ QVERIFY(dialog.extension() && !dialog.extension()->isVisible());
+ QVERIFY(dialog.isSizeGripEnabled());
+
+ // normal show/hide sequence
+ dialog.showExtension(true);
+ QVERIFY(dialog.extension() && dialog.extension()->isVisible());
+ QVERIFY(!dialog.isSizeGripEnabled());
+ QVERIFY(!sizeGrip);
+
+ dialog.showExtension(false);
+ QVERIFY(dialog.extension() && !dialog.extension()->isVisible());
+ QVERIFY(dialog.isSizeGripEnabled());
+ sizeGrip = qFindChild<QSizeGrip *>(&dialog);
+ QVERIFY(sizeGrip);
+ QVERIFY(sizeGrip->isVisible());
+
+ // show/hide sequence with interleaved size grip update
+ dialog.showExtension(true);
+ QVERIFY(dialog.extension() && dialog.extension()->isVisible());
+ QVERIFY(!dialog.isSizeGripEnabled());
+ QVERIFY(!sizeGrip);
+
+ dialog.setSizeGripEnabled(false);
+ QVERIFY(!dialog.isSizeGripEnabled());
+
+ dialog.showExtension(false);
+ QVERIFY(dialog.extension() && !dialog.extension()->isVisible());
+ QVERIFY(!dialog.isSizeGripEnabled());
+
+ dialog.setSizeGripEnabled(true);
+ sizeGrip = qFindChild<QSizeGrip *>(&dialog);
+ QVERIFY(sizeGrip);
+ QVERIFY(sizeGrip->isVisible());
+ sizeGrip->hide();
+ dialog.hide();
+ dialog.show();
+ QVERIFY(!sizeGrip->isVisible());
+#endif
+}
+
+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()
+ {
+ called++;
+ if (!cancelReject)
+ QDialog::reject();
+ }
+ bool cancelReject;
+ int called;
+};
+
+void tst_QDialog::reject()
+{
+ TestRejectDialog dialog;
+ dialog.show();
+ QTest::qWaitForWindowShown(&dialog);
+ QTRY_VERIFY(dialog.isVisible());
+ dialog.reject();
+ QTRY_VERIFY(!dialog.isVisible());
+ QCOMPARE(dialog.called, 1);
+
+ dialog.show();
+ QTest::qWaitForWindowShown(&dialog);
+ QTRY_VERIFY(dialog.isVisible());
+ QVERIFY(dialog.close());
+ QTRY_VERIFY(!dialog.isVisible());
+ QCOMPARE(dialog.called, 2);
+
+ dialog.cancelReject = true;
+ dialog.show();
+ QTest::qWaitForWindowShown(&dialog);
+ QTRY_VERIFY(dialog.isVisible());
+ dialog.reject();
+ QTRY_VERIFY(dialog.isVisible());
+ QCOMPARE(dialog.called, 3);
+ QVERIFY(!dialog.close());
+ QTRY_VERIFY(dialog.isVisible());
+ QCOMPARE(dialog.called, 4);
+}
+
+
+QTEST_MAIN(tst_QDialog)
+#include "tst_qdialog.moc"
diff --git a/tests/auto/widgets/dialogs/qerrormessage/.gitignore b/tests/auto/widgets/dialogs/qerrormessage/.gitignore
new file mode 100644
index 0000000000..1bb653fb72
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qerrormessage/.gitignore
@@ -0,0 +1 @@
+tst_qerrormessage
diff --git a/tests/auto/widgets/dialogs/qerrormessage/qerrormessage.pro b/tests/auto/widgets/dialogs/qerrormessage/qerrormessage.pro
new file mode 100644
index 0000000000..363d085cbf
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qerrormessage/qerrormessage.pro
@@ -0,0 +1,10 @@
+load(qttest_p4)
+TEMPLATE = app
+TARGET = tst_qerrormessage
+DEPENDPATH += .
+INCLUDEPATH += .
+
+QT += widgets
+
+# Input
+SOURCES += tst_qerrormessage.cpp
diff --git a/tests/auto/widgets/dialogs/qerrormessage/tst_qerrormessage.cpp b/tests/auto/widgets/dialogs/qerrormessage/tst_qerrormessage.cpp
new file mode 100644
index 0000000000..d3ee640b1a
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qerrormessage/tst_qerrormessage.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtTest/QtTest>
+#include <QErrorMessage>
+#include <QDebug>
+#include <QCheckBox>
+
+class tst_QErrorMessage : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void dontShowAgain();
+ void dontShowCategoryAgain();
+
+};
+
+void tst_QErrorMessage::dontShowAgain()
+{
+ QString plainString = QLatin1String("foo");
+ QString htmlString = QLatin1String("foo<br>bar");
+ QCheckBox *checkBox = 0;
+
+ QErrorMessage errorMessageDialog(0);
+
+ // show an error with plain string
+ errorMessageDialog.showMessage(plainString);
+ QVERIFY(errorMessageDialog.isVisible());
+ checkBox = qFindChild<QCheckBox*>(&errorMessageDialog);
+ QVERIFY(checkBox);
+ QVERIFY(checkBox->isChecked());
+ errorMessageDialog.close();
+
+ errorMessageDialog.showMessage(plainString);
+ QVERIFY(errorMessageDialog.isVisible());
+ checkBox = qFindChild<QCheckBox*>(&errorMessageDialog);
+ 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 = qFindChild<QCheckBox*>(&errorMessageDialog);
+ QVERIFY(checkBox);
+ QVERIFY(!checkBox->isChecked());
+ checkBox->setChecked(true);
+ errorMessageDialog.close();
+
+ errorMessageDialog.showMessage(htmlString);
+ QVERIFY(errorMessageDialog.isVisible());
+ checkBox = qFindChild<QCheckBox*>(&errorMessageDialog);
+ 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 = 0;
+
+ QErrorMessage errorMessageDialog(0);
+
+ errorMessageDialog.showMessage(htmlString,"Cat 1");
+ QVERIFY(errorMessageDialog.isVisible());
+ checkBox = qFindChild<QCheckBox*>(&errorMessageDialog);
+ QVERIFY(checkBox);
+ QVERIFY(checkBox->isChecked());
+ checkBox->setChecked(true);
+ errorMessageDialog.close();
+
+ errorMessageDialog.showMessage(htmlString,"Cat 1");
+ QVERIFY(errorMessageDialog.isVisible());
+ checkBox = qFindChild<QCheckBox*>(&errorMessageDialog);
+ QVERIFY(checkBox);
+ QVERIFY(checkBox->isChecked());
+ checkBox->setChecked(true);
+ errorMessageDialog.close();
+
+ errorMessageDialog.showMessage(htmlString2,"Cat 1");
+ QVERIFY(errorMessageDialog.isVisible());
+ checkBox = qFindChild<QCheckBox*>(&errorMessageDialog);
+ QVERIFY(checkBox);
+ QVERIFY(checkBox->isChecked());
+ checkBox->setChecked(true);
+ errorMessageDialog.close();
+
+ errorMessageDialog.showMessage(htmlString,"Cat 1");
+ QVERIFY(errorMessageDialog.isVisible());
+ checkBox = qFindChild<QCheckBox*>(&errorMessageDialog);
+ 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());
+}
+
+QTEST_MAIN(tst_QErrorMessage)
+#include "tst_qerrormessage.moc"
diff --git a/tests/auto/widgets/dialogs/qfiledialog/.gitignore b/tests/auto/widgets/dialogs/qfiledialog/.gitignore
new file mode 100644
index 0000000000..a696596ee9
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfiledialog/.gitignore
@@ -0,0 +1 @@
+tst_qfiledialog
diff --git a/tests/auto/widgets/dialogs/qfiledialog/qfiledialog.pro b/tests/auto/widgets/dialogs/qfiledialog/qfiledialog.pro
new file mode 100644
index 0000000000..92fba98796
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfiledialog/qfiledialog.pro
@@ -0,0 +1,23 @@
+############################################################
+# Project file for autotest for file qfiledialog.h
+############################################################
+
+load(qttest_p4)
+QT += widgets widgets-private
+QT += core-private gui-private
+SOURCES += tst_qfiledialog.cpp
+
+wince* {
+ addFiles.files = *.cpp
+ addFiles.path = .
+ filesInDir.files = *.pro
+ filesInDir.path = someDir
+ DEPLOYMENT += addFiles filesInDir
+}
+
+wince* {
+ DEFINES += SRCDIR=\\\"./\\\"
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD/\\\"
+}
+
diff --git a/tests/auto/widgets/dialogs/qfiledialog/resources/file.txt b/tests/auto/widgets/dialogs/qfiledialog/resources/file.txt
new file mode 100644
index 0000000000..8a03e0e55f
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfiledialog/resources/file.txt
@@ -0,0 +1 @@
+This is a simple text file.
diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
new file mode 100644
index 0000000000..9abcd407d0
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
@@ -0,0 +1,1349 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <qcoreapplication.h>
+#include <qdebug.h>
+#include <qfiledialog.h>
+#include <qabstractitemdelegate.h>
+#include <qdirmodel.h>
+#include <qitemdelegate.h>
+#include <qlistview.h>
+#include <qcombobox.h>
+#include <qpushbutton.h>
+#include <qtoolbutton.h>
+#include <qtreeview.h>
+#include <qheaderview.h>
+#include <qcompleter.h>
+#include <qaction.h>
+#include <qdialogbuttonbox.h>
+#include <qsortfilterproxymodel.h>
+#include <qlineedit.h>
+#include <qlayout.h>
+#if defined QT_BUILD_INTERNAL
+#include "../../../src/widgets/dialogs/qsidebar_p.h"
+#include "../../../src/widgets/dialogs/qfilesystemmodel_p.h"
+#include "../../../src/widgets/dialogs/qfiledialog_p.h"
+#endif
+#include <QFileDialog>
+#include <QFileSystemModel>
+
+#include "../../../network-settings.h"
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+#if defined(Q_OS_UNIX)
+#ifdef QT_BUILD_INTERNAL
+QT_BEGIN_NAMESPACE
+extern Q_GUI_EXPORT QString qt_tildeExpansion(const QString &path, bool *expanded = 0);
+QT_END_NAMESPACE
+#endif
+#endif
+
+class QNonNativeFileDialog : public QFileDialog
+{
+ Q_OBJECT
+public:
+ QNonNativeFileDialog(QWidget *parent = 0, const QString &caption = QString(), const QString &directory = QString(), const QString &filter = QString())
+ : QFileDialog(parent, caption, directory, filter)
+ {
+ setOption(QFileDialog::DontUseNativeDialog, true);
+ }
+};
+
+class tst_QFiledialog : public QObject
+{
+Q_OBJECT
+
+public:
+ tst_QFiledialog();
+ virtual ~tst_QFiledialog();
+
+public slots:
+ void init();
+ void cleanup();
+
+private slots:
+ void currentChangedSignal();
+ void directoryEnteredSignal();
+ void filesSelectedSignal_data();
+ void filesSelectedSignal();
+ void filterSelectedSignal();
+
+ void args();
+ void directory();
+ void completer_data();
+ void completer();
+ void completer_up();
+ void acceptMode();
+ void confirmOverwrite();
+ void defaultSuffix();
+ void fileMode();
+ void filters();
+ void history();
+ void iconProvider();
+ void isReadOnly();
+ void itemDelegate();
+ void labelText();
+ void resolveSymlinks();
+ void selectFile_data();
+ void selectFile();
+ void selectFiles();
+ void selectFilter();
+ void viewMode();
+ void proxymodel();
+ void setNameFilter();
+ void focus();
+ void caption();
+ void historyBack();
+ void historyForward();
+ void disableSaveButton_data();
+ void disableSaveButton();
+ void saveButtonText_data();
+ void saveButtonText();
+ void clearLineEdit();
+ void enableChooseButton();
+ void hooks();
+#if defined(Q_OS_UNIX) && defined(QT_BUILD_INTERNAL)
+ void tildeExpansion_data();
+ void tildeExpansion();
+#endif
+
+private:
+ QByteArray userSettings;
+};
+
+tst_QFiledialog::tst_QFiledialog()
+{
+}
+
+tst_QFiledialog::~tst_QFiledialog()
+{
+}
+
+void tst_QFiledialog::init()
+{
+ // Save the developers settings so they don't get mad when their sidebar folders are gone.
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("Qt"));
+ userSettings = settings.value(QLatin1String("filedialog")).toByteArray();
+ settings.remove(QLatin1String("filedialog"));
+
+ // populate it with some default settings
+ QNonNativeFileDialog fd;
+#if defined(Q_OS_WINCE)
+ QTest::qWait(1000);
+#endif
+}
+
+void tst_QFiledialog::cleanup()
+{
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("Qt"));
+ settings.setValue(QLatin1String("filedialog"), userSettings);
+}
+
+class MyAbstractItemDelegate : public QAbstractItemDelegate
+{
+public:
+ MyAbstractItemDelegate() : QAbstractItemDelegate() {};
+ void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const {}
+ QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const { return QSize(); }
+};
+
+// emitted any time the selection model emits current changed
+void tst_QFiledialog::currentChangedSignal()
+{
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
+
+ QListView* listView = qFindChild<QListView*>(&fd, "listView");
+ QVERIFY(listView);
+ fd.setDirectory(QDir::root());
+ QModelIndex root = listView->rootIndex();
+ QTRY_COMPARE(listView->model()->rowCount(root) > 0, true);
+
+ QModelIndex folder;
+ for (int i = 0; i < listView->model()->rowCount(root); ++i) {
+ folder = listView->model()->index(i, 0, root);
+ if (listView->model()->hasChildren(folder))
+ break;
+ }
+ QVERIFY(listView->model()->hasChildren(folder));
+ listView->setCurrentIndex(folder);
+
+ QCOMPARE(spyCurrentChanged.count(), 1);
+}
+
+// only emitted from the views, sidebar, or lookin combo
+void tst_QFiledialog::directoryEnteredSignal()
+{
+#if defined QT_BUILD_INTERNAL
+ QNonNativeFileDialog fd(0, "", QDir::root().path());
+ fd.setOptions(QFileDialog::DontUseNativeDialog);
+ fd.show();
+ QTRY_COMPARE(fd.isVisible(), true);
+ QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
+
+ // sidebar
+ QSidebar *sidebar = qFindChild<QSidebar*>(&fd, "sidebar");
+ sidebar->setCurrentIndex(sidebar->model()->index(1, 0));
+ QTest::keyPress(sidebar->viewport(), Qt::Key_Return);
+ QCOMPARE(spyDirectoryEntered.count(), 1);
+ spyDirectoryEntered.clear();
+
+ // lookInCombo
+ QComboBox *comboBox = qFindChild<QComboBox*>(&fd, "lookInCombo");
+ comboBox->showPopup();
+ QVERIFY(comboBox->view()->model()->index(1, 0).isValid());
+ comboBox->view()->setCurrentIndex(comboBox->view()->model()->index(1, 0));
+ QTest::keyPress(comboBox->view()->viewport(), Qt::Key_Return);
+ QCOMPARE(spyDirectoryEntered.count(), 1);
+ spyDirectoryEntered.clear();
+
+ // view
+ /*
+ // platform specific
+ fd.setViewMode(QFileDialog::ViewMode(QFileDialog::List));
+ QListView* listView = qFindChild<QListView*>(&fd, "listView");
+ QVERIFY(listView);
+ QModelIndex root = listView->rootIndex();
+ QTRY_COMPARE(listView->model()->rowCount(root) > 0, true);
+
+ QModelIndex folder;
+ for (int i = 0; i < listView->model()->rowCount(root); ++i) {
+ folder = listView->model()->index(i, 0, root);
+ if (listView->model()->hasChildren(folder))
+ break;
+ }
+ QVERIFY(listView->model()->hasChildren(folder));
+ listView->setCurrentIndex(folder);
+ QTRY_COMPARE((listView->indexAt(listView->visualRect(folder).center())), folder);
+ QTest::mouseDClick(listView->viewport(), Qt::LeftButton, 0, listView->visualRect(folder).center());
+ QTRY_COMPARE(spyDirectoryEntered.count(), 1);
+ */
+#endif
+}
+
+Q_DECLARE_METATYPE(QFileDialog::FileMode)
+void tst_QFiledialog::filesSelectedSignal_data()
+{
+ QTest::addColumn<QFileDialog::FileMode>("fileMode");
+ QTest::newRow("any") << QFileDialog::AnyFile;
+ QTest::newRow("existing") << QFileDialog::ExistingFile;
+ QTest::newRow("directory") << QFileDialog::Directory;
+ QTest::newRow("directoryOnly") << QFileDialog::DirectoryOnly;
+ QTest::newRow("existingFiles") << QFileDialog::ExistingFiles;
+}
+
+// emitted when the dialog closes with the selected files
+void tst_QFiledialog::filesSelectedSignal()
+{
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ fd.setOptions(QFileDialog::DontUseNativeDialog);
+ QDir testDir(SRCDIR);
+ fd.setDirectory(testDir);
+ QFETCH(QFileDialog::FileMode, fileMode);
+ fd.setFileMode(fileMode);
+ QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
+
+ fd.show();
+ QTest::qWait(500);
+ QListView *listView = qFindChild<QListView*>(&fd, "listView");
+ QVERIFY(listView);
+
+ QModelIndex root = listView->rootIndex();
+ QTRY_COMPARE(listView->model()->rowCount(root) > 0, true);
+ QModelIndex file;
+ for (int i = 0; i < listView->model()->rowCount(root); ++i) {
+ file = listView->model()->index(i, 0, root);
+ if (fileMode == QFileDialog::Directory || fileMode == QFileDialog::DirectoryOnly) {
+ if (listView->model()->hasChildren(file))
+ break;
+ } else {
+ if (!listView->model()->hasChildren(file))
+ break;
+ }
+ file = QModelIndex();
+ }
+ QVERIFY(file.isValid());
+ listView->selectionModel()->select(file, QItemSelectionModel::Select | QItemSelectionModel::Rows);
+ listView->setCurrentIndex(file);
+
+ QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
+ QPushButton *button = buttonBox->button(QDialogButtonBox::Open);
+ QVERIFY(button);
+ QVERIFY(button->isEnabled());
+ button->animateClick();
+ QTRY_COMPARE(fd.isVisible(), false);
+ QCOMPARE(spyFilesSelected.count(), 1);
+}
+
+// only emitted when the combo box is activated
+void tst_QFiledialog::filterSelectedSignal()
+{
+ QNonNativeFileDialog fd;
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ fd.show();
+ QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
+
+ QStringList filterChoices;
+ filterChoices << "Image files (*.png *.xpm *.jpg)"
+ << "Text files (*.txt)"
+ << "Any files (*.*)";
+ fd.setFilters(filterChoices);
+ QCOMPARE(fd.filters(), filterChoices);
+
+ QComboBox *filters = qFindChild<QComboBox*>(&fd, "fileTypeCombo");
+ QVERIFY(filters);
+ QVERIFY(filters->view());
+ QCOMPARE(filters->isVisible(), true);
+
+ QTest::keyPress(filters, Qt::Key_Down);
+
+ QCOMPARE(spyFilterSelected.count(), 1);
+}
+
+void tst_QFiledialog::args()
+{
+ QWidget *parent = 0;
+ QString caption = "caption";
+ QString directory = QDir::tempPath();
+ QString filter = "*.mp3";
+ QNonNativeFileDialog fd(parent, caption, directory, filter);
+ QCOMPARE(fd.parent(), (QObject *)parent);
+ QCOMPARE(fd.windowTitle(), caption);
+#ifndef Q_OS_WIN
+ QCOMPARE(fd.directory(), QDir(directory));
+#endif
+ QCOMPARE(fd.filters(), QStringList(filter));
+}
+
+void tst_QFiledialog::directory()
+{
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QVERIFY(model);
+ fd.setDirectory(QDir::currentPath());
+ QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
+ QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
+ QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
+ QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
+
+ QCOMPARE(QDir::current().absolutePath(), fd.directory().absolutePath());
+ QDir temp = QDir::temp();
+ QString tempPath = temp.absolutePath();
+#ifdef Q_OS_WIN
+ // since the user can have lowercase temp dir, check that we are actually case-insensitive.
+ tempPath = tempPath.toLower();
+#endif
+ fd.setDirectory(tempPath);
+#ifndef Q_OS_WIN
+ QCOMPARE(tempPath, fd.directory().absolutePath());
+#endif
+ QCOMPARE(spyCurrentChanged.count(), 0);
+ QCOMPARE(spyDirectoryEntered.count(), 0);
+ QCOMPARE(spyFilesSelected.count(), 0);
+ QCOMPARE(spyFilterSelected.count(), 0);
+
+ // Check my way
+ QList<QListView*> list = qFindChildren<QListView*>(&fd, "listView");
+ QVERIFY(list.count() > 0);
+#ifdef Q_OS_WIN
+ QCOMPARE(list.at(0)->rootIndex().data().toString().toLower(), temp.dirName().toLower());
+#else
+ QCOMPARE(list.at(0)->rootIndex().data().toString(), temp.dirName());
+#endif
+ QNonNativeFileDialog *dlg = new QNonNativeFileDialog(0, "", tempPath);
+ QCOMPARE(model->index(tempPath), model->index(dlg->directory().absolutePath()));
+ QCOMPARE(model->index(tempPath).data(QFileSystemModel::FileNameRole).toString(),
+ model->index(dlg->directory().absolutePath()).data(QFileSystemModel::FileNameRole).toString());
+ delete dlg;
+ dlg = new QNonNativeFileDialog();
+ QCOMPARE(model->index(tempPath), model->index(dlg->directory().absolutePath()));
+ delete dlg;
+}
+
+void tst_QFiledialog::completer_data()
+{
+ QTest::addColumn<QString>("startPath");
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<int>("expected");
+
+ QTest::newRow("r, 10") << "" << "r" << 10;
+ QTest::newRow("x, 0") << "" << "x" << 0;
+ QTest::newRow("../, -1") << "" << "../" << -1;
+
+ QTest::newRow("goto root") << QString() << QDir::rootPath() << -1;
+ QTest::newRow("start at root") << QDir::rootPath() << QString() << -1;
+
+ QDir root = QDir::root();
+ QStringList list = root.entryList();
+ QString folder;
+ for (int i = 0; i < list.count(); ++i) {
+ if (list.at(0) == QChar('.'))
+ continue;
+ QFileInfo info(QDir::rootPath() + list[i]);
+ if (info.isDir()) {
+ folder = QDir::rootPath() + list[i];
+ break;
+ }
+ }
+
+ QTest::newRow("start at one below root r") << folder << "r" << -1;
+ QTest::newRow("start at one below root ../") << folder << "../" << -1;
+}
+
+void tst_QFiledialog::completer()
+{
+ QFETCH(QString, input);
+ QFETCH(QString, startPath);
+ QFETCH(int, expected);
+
+ QString tempPath = QDir::tempPath() + '/' + "QFileDialogTestDir";
+ if (startPath.isEmpty())
+ startPath = tempPath;
+
+ startPath = QDir::cleanPath(startPath);
+
+ // make temp dir and files
+ {
+ QDir cleanup(tempPath);
+ QStringList x = cleanup.entryList();
+ for (int i = 0; i < x.count(); ++i)
+ QFile::remove(tempPath + '/' + x[i]);
+ cleanup.rmdir(tempPath);
+ }
+ QDir tmp(QDir::tempPath());
+ if (!tmp.exists(tempPath))
+ QVERIFY(tmp.mkdir("QFileDialogTestDir"));
+ QList<QTemporaryFile*> files;
+ QT_TRY {
+ for (int i = 0; i < 10; ++i) {
+ QScopedPointer<QTemporaryFile> file(new QTemporaryFile(tempPath + "/rXXXXXX"));
+ file->open();
+ files.append(file.take());
+ }
+
+ // ### flesh this out more
+ QNonNativeFileDialog fd(0,QString("Test it"),startPath);
+ fd.setOptions(QFileDialog::DontUseNativeDialog);
+ fd.show();
+ QVERIFY(fd.isVisible());
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QVERIFY(model);
+ QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QVERIFY(lineEdit);
+ QCompleter *completer = lineEdit->completer();
+ QVERIFY(completer);
+ QAbstractItemModel *cModel = completer->completionModel();
+ QVERIFY(cModel);
+
+ //wait a bit
+ QTest::qWait(500);
+
+ // path C:\depot\qt\examples\dialogs\standarddialogs
+ // files
+ // [debug] [release] [tmp] dialog dialog main makefile makefile.debug makefile.release standarddialgos
+ //
+ // d -> D:\ debug dialog.cpp dialog.h
+ // ..\ -> ..\classwizard ..\configdialog ..\dialogs.pro
+ // c -> C:\ control panel
+ // c: -> C:\ (nothing more)
+ // C:\ -> C:\, C:\_viminfo, ...
+ // \ -> \_viminfo
+ // c:\depot -> 'nothing'
+ // c:\depot\ -> C:\depot\devtools, C:\depot\dteske
+ QCOMPARE(model->index(fd.directory().path()), model->index(startPath));
+
+ if (input.isEmpty()) {
+ QModelIndex r = model->index(model->rootPath());
+ QVERIFY(model->rowCount(r) > 0);
+ QModelIndex idx = model->index(0, 0, r);
+ input = idx.data().toString().at(0);
+ }
+
+ // press 'keys' for the input
+ for (int i = 0; i < input.count(); ++i)
+ QTest::keyPress(lineEdit, input[i].toAscii());
+
+ QStringList expectedFiles;
+ if (expected == -1) {
+ QString fullPath = startPath.isEmpty() ? tempPath : startPath;
+ if (!fullPath.endsWith(QLatin1Char('/')))
+ fullPath.append(QLatin1Char('/'));
+ fullPath.append(input);
+ bool inputStartsWithRootPath = false;
+ if (input.startsWith(QDir::rootPath())) {
+ fullPath = input;
+ input.clear();
+ inputStartsWithRootPath = true;
+ }
+
+ QFileInfo fi(fullPath);
+ QDir x(fi.absolutePath());
+ expectedFiles = x.entryList(model->filter());
+ expected = 0;
+ if (input.startsWith(".."))
+ input.clear();
+ for (int ii = 0; ii < expectedFiles.count(); ++ii) {
+#if defined(Q_OS_WIN)
+ if (expectedFiles.at(ii).startsWith(input,Qt::CaseInsensitive))
+#else
+ if (expectedFiles.at(ii).startsWith(input))
+#endif
+ ++expected;
+ }
+ }
+
+ QTest::qWait(1000);
+ if (cModel->rowCount() != expected) {
+ for (int i = 0; i < cModel->rowCount(); ++i) {
+ QString file = cModel->index(i, 0).data().toString();
+ expectedFiles.removeAll(file);
+ }
+ //qDebug() << expectedFiles;
+ }
+
+ QTRY_COMPARE(cModel->rowCount(), expected);
+ } QT_CATCH(...) {
+ qDeleteAll(files);
+ QT_RETHROW;
+ }
+ qDeleteAll(files);
+}
+
+void tst_QFiledialog::completer_up()
+{
+ QNonNativeFileDialog fd;
+ fd.setOptions(QFileDialog::DontUseNativeDialog);
+ QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
+ QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
+ QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
+ QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
+
+ fd.show();
+ QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QVERIFY(lineEdit);
+ QCOMPARE(spyFilesSelected.count(), 0);
+ int depth = QDir::currentPath().split('/').count();
+ for (int i = 0; i <= depth * 3 + 1; ++i) {
+ lineEdit->insert("../");
+ qApp->processEvents();
+ }
+ QCOMPARE(spyCurrentChanged.count(), 0);
+ QCOMPARE(spyDirectoryEntered.count(), 0);
+ QCOMPARE(spyFilesSelected.count(), 0);
+ QCOMPARE(spyFilterSelected.count(), 0);
+}
+
+void tst_QFiledialog::acceptMode()
+{
+ QNonNativeFileDialog fd;
+ fd.show();
+
+ QToolButton* newButton = qFindChild<QToolButton*>(&fd, "newFolderButton");
+ QVERIFY(newButton);
+
+ // default
+ QCOMPARE(fd.acceptMode(), QFileDialog::AcceptOpen);
+ QCOMPARE(newButton && newButton->isVisible(), true);
+
+ //fd.setDetailsExpanded(true);
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ QCOMPARE(fd.acceptMode(), QFileDialog::AcceptSave);
+ QCOMPARE(newButton->isVisible(), true);
+
+ fd.setAcceptMode(QFileDialog::AcceptOpen);
+ QCOMPARE(fd.acceptMode(), QFileDialog::AcceptOpen);
+ QCOMPARE(newButton->isVisible(), true);
+}
+
+void tst_QFiledialog::confirmOverwrite()
+{
+ QNonNativeFileDialog fd;
+ QCOMPARE(fd.confirmOverwrite(), true);
+ fd.setConfirmOverwrite(true);
+ QCOMPARE(fd.confirmOverwrite(), true);
+ fd.setConfirmOverwrite(false);
+ QCOMPARE(fd.confirmOverwrite(), false);
+ fd.setConfirmOverwrite(true);
+ QCOMPARE(fd.confirmOverwrite(), true);
+}
+
+void tst_QFiledialog::defaultSuffix()
+{
+ QNonNativeFileDialog fd;
+ QCOMPARE(fd.defaultSuffix(), QString());
+ fd.setDefaultSuffix("txt");
+ QCOMPARE(fd.defaultSuffix(), QString("txt"));
+ fd.setDefaultSuffix(QString());
+ QCOMPARE(fd.defaultSuffix(), QString());
+}
+
+void tst_QFiledialog::fileMode()
+{
+ QNonNativeFileDialog fd;
+ QCOMPARE(fd.fileMode(), QFileDialog::AnyFile);
+ fd.setFileMode(QFileDialog::ExistingFile);
+ QCOMPARE(fd.fileMode(), QFileDialog::ExistingFile);
+ fd.setFileMode(QFileDialog::Directory);
+ QCOMPARE(fd.fileMode(), QFileDialog::Directory);
+ fd.setFileMode(QFileDialog::DirectoryOnly);
+ QCOMPARE(fd.fileMode(), QFileDialog::DirectoryOnly);
+ fd.setFileMode(QFileDialog::ExistingFiles);
+ QCOMPARE(fd.fileMode(), QFileDialog::ExistingFiles);
+}
+
+void tst_QFiledialog::caption()
+{
+ QNonNativeFileDialog fd;
+ fd.setWindowTitle("testing");
+ fd.setFileMode(QFileDialog::Directory);
+ QCOMPARE(fd.windowTitle(), QString("testing"));
+}
+
+void tst_QFiledialog::filters()
+{
+ QNonNativeFileDialog fd;
+ fd.setOptions(QFileDialog::DontUseNativeDialog);
+ QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
+ QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
+ QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
+ QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
+ QCOMPARE(fd.filters(), QStringList("All Files (*)"));
+
+ // effects
+ QList<QComboBox*> views = qFindChildren<QComboBox*>(&fd, "fileTypeCombo");
+ QVERIFY(views.count() == 1);
+ QCOMPARE(views.at(0)->isVisible(), false);
+
+ QStringList filters;
+ filters << "Image files (*.png *.xpm *.jpg)"
+ << "Text files (*.txt)"
+ << "Any files (*.*)";
+ fd.setFilters(filters);
+ QCOMPARE(views.at(0)->isVisible(), false);
+ fd.show();
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ QCOMPARE(views.at(0)->isVisible(), true);
+ QCOMPARE(fd.filters(), filters);
+ fd.setFilter("Image files (*.png *.xpm *.jpg);;Text files (*.txt);;Any files (*.*)");
+ QCOMPARE(fd.filters(), filters);
+ QCOMPARE(spyCurrentChanged.count(), 0);
+ QCOMPARE(spyDirectoryEntered.count(), 0);
+ QCOMPARE(spyFilesSelected.count(), 0);
+ QCOMPARE(spyFilterSelected.count(), 0);
+
+ // setting shouldn't emit any signals
+ for (int i = views.at(0)->currentIndex(); i < views.at(0)->count(); ++i)
+ views.at(0)->setCurrentIndex(i);
+ QCOMPARE(spyFilterSelected.count(), 0);
+
+ //Let check if filters with whitespaces
+ QNonNativeFileDialog fd2;
+ QStringList expected;
+ expected << "C++ Source Files(*.cpp)";
+ expected << "Any(*.*)";
+ fd2.setFilter("C++ Source Files(*.cpp);;Any(*.*)");
+ QCOMPARE(expected, fd2.filters());
+ fd2.setFilter("C++ Source Files(*.cpp) ;;Any(*.*)");
+ QCOMPARE(expected, fd2.filters());
+ fd2.setFilter("C++ Source Files(*.cpp);; Any(*.*)");
+ QCOMPARE(expected, fd2.filters());
+ fd2.setFilter(" C++ Source Files(*.cpp);; Any(*.*)");
+ QCOMPARE(expected, fd2.filters());
+ fd2.setFilter("C++ Source Files(*.cpp) ;; Any(*.*)");
+ QCOMPARE(expected, fd2.filters());
+}
+
+void tst_QFiledialog::selectFilter()
+{
+ QNonNativeFileDialog fd;
+ QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
+ QCOMPARE(fd.selectedFilter(), QString("All Files (*)"));
+ QStringList filters;
+ filters << "Image files (*.png *.xpm *.jpg)"
+ << "Text files (*.txt)"
+ << "Any files (*.*)";
+ fd.setFilters(filters);
+ QCOMPARE(fd.selectedFilter(), filters.at(0));
+ fd.selectFilter(filters.at(1));
+ QCOMPARE(fd.selectedFilter(), filters.at(1));
+ fd.selectFilter(filters.at(2));
+ QCOMPARE(fd.selectedFilter(), filters.at(2));
+
+ fd.selectFilter("bob");
+ QCOMPARE(fd.selectedFilter(), filters.at(2));
+ fd.selectFilter("");
+ QCOMPARE(fd.selectedFilter(), filters.at(2));
+ QCOMPARE(spyFilterSelected.count(), 0);
+}
+
+void tst_QFiledialog::history()
+{
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QVERIFY(model);
+ QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
+ QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
+ QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
+ QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
+ QCOMPARE(model->index(fd.history().first()), model->index(QDir::toNativeSeparators(fd.directory().absolutePath())));
+ fd.setDirectory(QDir::current().absolutePath());
+ QStringList history;
+ history << QDir::toNativeSeparators(QDir::current().absolutePath())
+ << QDir::toNativeSeparators(QDir::home().absolutePath())
+ << QDir::toNativeSeparators(QDir::temp().absolutePath());
+ fd.setHistory(history);
+ if (fd.history() != history) {
+ qDebug() << fd.history() << history;
+ // quick and dirty output for windows failure.
+ QListView* list = qFindChild<QListView*>(&fd, "listView");
+ QVERIFY(list);
+ QModelIndex root = list->rootIndex();
+ while (root.isValid()) {
+ qDebug() << root.data();
+ root = root.parent();
+ }
+ }
+ QCOMPARE(fd.history(), history);
+
+ QStringList badHistory;
+ badHistory << "junk";
+ fd.setHistory(badHistory);
+ badHistory << QDir::toNativeSeparators(QDir::current().absolutePath());
+ QCOMPARE(fd.history(), badHistory);
+
+ QCOMPARE(spyCurrentChanged.count(), 0);
+ QCOMPARE(spyDirectoryEntered.count(), 0);
+ QCOMPARE(spyFilesSelected.count(), 0);
+ QCOMPARE(spyFilterSelected.count(), 0);
+}
+
+void tst_QFiledialog::iconProvider()
+{
+ QNonNativeFileDialog *fd = new QNonNativeFileDialog();
+ QVERIFY(fd->iconProvider() != 0);
+ QFileIconProvider *ip = new QFileIconProvider();
+ fd->setIconProvider(ip);
+ QCOMPARE(fd->iconProvider(), ip);
+ delete fd;
+ delete ip;
+}
+
+void tst_QFiledialog::isReadOnly()
+{
+ QNonNativeFileDialog fd;
+
+ QPushButton* newButton = qFindChild<QPushButton*>(&fd, "newFolderButton");
+ QAction* renameAction = qFindChild<QAction*>(&fd, "qt_rename_action");
+ QAction* deleteAction = qFindChild<QAction*>(&fd, "qt_delete_action");
+
+ QCOMPARE(fd.isReadOnly(), false);
+
+ // This is dependent upon the file/dir, find cross platform way to test
+ //fd.setDirectory(QDir::home());
+ //QCOMPARE(newButton && newButton->isEnabled(), true);
+ //QCOMPARE(renameAction && renameAction->isEnabled(), true);
+ //QCOMPARE(deleteAction && deleteAction->isEnabled(), true);
+
+ fd.setReadOnly(true);
+ QCOMPARE(fd.isReadOnly(), true);
+
+ QCOMPARE(newButton && newButton->isEnabled(), false);
+ QCOMPARE(renameAction && renameAction->isEnabled(), false);
+ QCOMPARE(deleteAction && deleteAction->isEnabled(), false);
+}
+
+void tst_QFiledialog::itemDelegate()
+{
+ QNonNativeFileDialog fd;
+ QVERIFY(fd.itemDelegate() != 0);
+ QItemDelegate *id = new QItemDelegate(&fd);
+ fd.setItemDelegate(id);
+ QCOMPARE(fd.itemDelegate(), (QAbstractItemDelegate *)id);
+}
+
+void tst_QFiledialog::labelText()
+{
+ QNonNativeFileDialog fd;
+ QDialogButtonBox buttonBox;
+ QPushButton *cancelButton = buttonBox.addButton(QDialogButtonBox::Cancel);
+ QCOMPARE(fd.labelText(QFileDialog::LookIn), QString("Look in:"));
+ QCOMPARE(fd.labelText(QFileDialog::FileName), QString("File &name:"));
+ QCOMPARE(fd.labelText(QFileDialog::FileType), QString("Files of type:"));
+ QCOMPARE(fd.labelText(QFileDialog::Accept), QString("&Open")); ///### see task 241462
+ QCOMPARE(fd.labelText(QFileDialog::Reject), cancelButton->text());
+
+ fd.setLabelText(QFileDialog::LookIn, "1");
+ QCOMPARE(fd.labelText(QFileDialog::LookIn), QString("1"));
+ fd.setLabelText(QFileDialog::FileName, "2");
+ QCOMPARE(fd.labelText(QFileDialog::FileName), QString("2"));
+ fd.setLabelText(QFileDialog::FileType, "3");
+ QCOMPARE(fd.labelText(QFileDialog::FileType), QString("3"));
+ fd.setLabelText(QFileDialog::Accept, "4");
+ QCOMPARE(fd.labelText(QFileDialog::Accept), QString("4"));
+ fd.setLabelText(QFileDialog::Reject, "5");
+ QCOMPARE(fd.labelText(QFileDialog::Reject), QString("5"));
+}
+
+void tst_QFiledialog::resolveSymlinks()
+{
+ QNonNativeFileDialog fd;
+
+ // default
+ QCOMPARE(fd.resolveSymlinks(), true);
+ fd.setResolveSymlinks(false);
+ QCOMPARE(fd.resolveSymlinks(), false);
+ fd.setResolveSymlinks(true);
+ QCOMPARE(fd.resolveSymlinks(), true);
+
+ // the file dialog doesn't do anything based upon this, just passes it to the model
+ // the model should fully test it, don't test it here
+}
+
+void tst_QFiledialog::selectFile_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<int>("count");
+ QTest::newRow("null") << QString() << 1;
+ QTest::newRow("file") << "foo" << 1;
+ QTest::newRow("tmp") << "temp" << 1;
+}
+
+void tst_QFiledialog::selectFile()
+{
+ QFETCH(QString, file);
+ QFETCH(int, count);
+ QNonNativeFileDialog fd;
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QVERIFY(model);
+ fd.setDirectory(QDir::currentPath());
+ // default value
+ QCOMPARE(fd.selectedFiles().count(), 1);
+
+ QTemporaryFile tempFile(QDir::tempPath() + "/aXXXXXX");
+ bool inTemp = (file == "temp");
+ if (inTemp) {
+ tempFile.open();
+ file = tempFile.fileName();
+ }
+
+ fd.selectFile(file);
+ QCOMPARE(fd.selectedFiles().count(), count);
+ if (inTemp) {
+ QCOMPARE(model->index(fd.directory().path()), model->index(QDir::tempPath()));
+ } else {
+ QCOMPARE(model->index(fd.directory().path()), model->index(QDir::currentPath()));
+ }
+}
+
+void tst_QFiledialog::selectFiles()
+{
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ QString tempPath = QDir::tempPath() + '/' + "QFileDialogTestDir4SelectFiles";
+ QDir dir;
+ QVERIFY(dir.mkpath(tempPath));
+ fd.setDirectory(tempPath);
+ QSignalSpy spyCurrentChanged(&fd, SIGNAL(currentChanged(const QString &)));
+ QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(const QString &)));
+ QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(const QStringList &)));
+ QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(const QString &)));
+ fd.show();
+ fd.setFileMode(QFileDialog::ExistingFiles);
+
+ QString filesPath = fd.directory().absolutePath();
+ for (int i=0; i < 5; ++i) {
+ QFile file(filesPath + QString::fromLatin1("/qfiledialog_auto_test_not_pres_%1").arg(i));
+ file.open(QIODevice::WriteOnly);
+ file.resize(1024);
+ file.flush();
+ file.close();
+ }
+
+ // Get a list of files in the view and then get the corresponding index's
+ QStringList list = fd.directory().entryList(QDir::Files);
+ QModelIndexList toSelect;
+ QVERIFY(list.count() > 1);
+ QListView* listView = qFindChild<QListView*>(&fd, "listView");
+ QVERIFY(listView);
+ for (int i = 0; i < list.count(); ++i) {
+ fd.selectFile(fd.directory().path() + "/" + list.at(i));
+#if defined(Q_WS_MAC) || defined(Q_WS_WIN)
+ QEXPECT_FAIL("", "This test does not work on Mac or Windows", Abort);
+#endif
+ QTRY_VERIFY(!listView->selectionModel()->selectedRows().isEmpty());
+ toSelect.append(listView->selectionModel()->selectedRows().last());
+ }
+ QCOMPARE(spyFilesSelected.count(), 0);
+
+ listView->selectionModel()->clear();
+ QCOMPARE(spyFilesSelected.count(), 0);
+
+ // select the indexes
+ for (int i = 0; i < toSelect.count(); ++i) {
+ listView->selectionModel()->select(toSelect.at(i),
+ QItemSelectionModel::Select | QItemSelectionModel::Rows);
+ }
+ QCOMPARE(fd.selectedFiles().count(), toSelect.count());
+ QCOMPARE(spyCurrentChanged.count(), 0);
+ QCOMPARE(spyDirectoryEntered.count(), 0);
+ QCOMPARE(spyFilesSelected.count(), 0);
+ QCOMPARE(spyFilterSelected.count(), 0);
+ for (int i=0; i < 5; ++i)
+ QFile::remove(filesPath + QString::fromLatin1("/qfiledialog_auto_test_not_pres_%1").arg(i));
+
+ //If the selection is invalid then we fill the line edit but without the /
+ QNonNativeFileDialog * dialog = new QNonNativeFileDialog( 0, "Save" );
+ dialog->setFileMode( QFileDialog::AnyFile );
+ dialog->setAcceptMode( QFileDialog::AcceptSave );
+ QString temporary = QDir::tempPath() + QLatin1String("/blah");
+ dialog->selectFile(temporary);
+ dialog->show();
+ QTest::qWait(500);
+ QLineEdit *lineEdit = qFindChild<QLineEdit*>(dialog, "fileNameEdit");
+ QVERIFY(lineEdit);
+ QCOMPARE(lineEdit->text(),QLatin1String("blah"));
+ delete dialog;
+}
+
+void tst_QFiledialog::viewMode()
+{
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ fd.show();
+
+ // find widgets
+ QList<QTreeView*> treeView = qFindChildren<QTreeView*>(&fd, "treeView");
+ QCOMPARE(treeView.count(), 1);
+ QList<QListView*> listView = qFindChildren<QListView*>(&fd, "listView");
+ QCOMPARE(listView.count(), 1);
+ QList<QToolButton*> listButton = qFindChildren<QToolButton*>(&fd, "listModeButton");
+ QCOMPARE(listButton.count(), 1);
+ QList<QToolButton*> treeButton = qFindChildren<QToolButton*>(&fd, "detailModeButton");
+ QCOMPARE(treeButton.count(), 1);
+
+ // default value
+ QCOMPARE(fd.viewMode(), QFileDialog::List);
+
+ // detail
+ fd.setViewMode(QFileDialog::ViewMode(QFileDialog::Detail));
+
+ QCOMPARE(QFileDialog::ViewMode(QFileDialog::Detail), fd.viewMode());
+ QCOMPARE(listView.at(0)->isVisible(), false);
+ QCOMPARE(listButton.at(0)->isDown(), false);
+ QCOMPARE(treeView.at(0)->isVisible(), true);
+ QCOMPARE(treeButton.at(0)->isDown(), true);
+
+ // list
+ fd.setViewMode(QFileDialog::ViewMode(QFileDialog::List));
+
+ QCOMPARE(QFileDialog::ViewMode(QFileDialog::List), fd.viewMode());
+ QCOMPARE(treeView.at(0)->isVisible(), false);
+ QCOMPARE(treeButton.at(0)->isDown(), false);
+ QCOMPARE(listView.at(0)->isVisible(), true);
+ QCOMPARE(listButton.at(0)->isDown(), true);
+}
+
+void tst_QFiledialog::proxymodel()
+{
+ QNonNativeFileDialog fd;
+ QCOMPARE(fd.proxyModel(), (QAbstractProxyModel*)0);
+
+ fd.setProxyModel(0);
+ QCOMPARE(fd.proxyModel(), (QAbstractProxyModel*)0);
+
+ QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(&fd);
+ fd.setProxyModel(proxyModel);
+ QCOMPARE(fd.proxyModel(), (QAbstractProxyModel *)proxyModel);
+
+ fd.setProxyModel(0);
+ QCOMPARE(fd.proxyModel(), (QAbstractProxyModel*)0);
+}
+
+void tst_QFiledialog::setNameFilter()
+{
+ QNonNativeFileDialog fd;
+ fd.setFilter(QString());
+ fd.setFilters(QStringList());
+}
+
+void tst_QFiledialog::focus()
+{
+ QNonNativeFileDialog fd;
+ fd.setDirectory(QDir::currentPath());
+ fd.show();
+ QApplication::setActiveWindow(&fd);
+ QTest::qWaitForWindowShown(&fd);
+ QTRY_COMPARE(fd.isVisible(), true);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd));
+ qApp->processEvents();
+
+ // make sure the tests work with focus follows mouse
+ QCursor::setPos(fd.geometry().center());
+ QApplication::syncX();
+
+ QList<QWidget*> treeView = qFindChildren<QWidget*>(&fd, "fileNameEdit");
+ QCOMPARE(treeView.count(), 1);
+ QVERIFY(treeView.at(0));
+ QTRY_COMPARE(treeView.at(0)->hasFocus(), true);
+ QCOMPARE(treeView.at(0)->hasFocus(), true);
+}
+
+
+void tst_QFiledialog::historyBack()
+{
+ QNonNativeFileDialog fd;
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QVERIFY(model);
+ QToolButton *backButton = qFindChild<QToolButton*>(&fd, "backButton");
+ QVERIFY(backButton);
+ QToolButton *forwardButton = qFindChild<QToolButton*>(&fd, "forwardButton");
+ QVERIFY(forwardButton);
+
+ QSignalSpy spy(model, SIGNAL(rootPathChanged(const QString &)));
+
+ QString home = fd.directory().absolutePath();
+ QString desktop = QDir::homePath();
+ QString temp = QDir::tempPath();
+
+ QCOMPARE(backButton->isEnabled(), false);
+ QCOMPARE(forwardButton->isEnabled(), false);
+ fd.setDirectory(temp);
+ qApp->processEvents();
+ QCOMPARE(backButton->isEnabled(), true);
+ QCOMPARE(forwardButton->isEnabled(), false);
+ fd.setDirectory(desktop);
+ QCOMPARE(spy.count(), 2);
+
+ backButton->click();
+ qApp->processEvents();
+ QCOMPARE(backButton->isEnabled(), true);
+ QCOMPARE(forwardButton->isEnabled(), true);
+ QCOMPARE(spy.count(), 3);
+ QString currentPath = qVariantValue<QString>(spy.last().first());
+ QCOMPARE(model->index(currentPath), model->index(temp));
+
+ backButton->click();
+ currentPath = qVariantValue<QString>(spy.last().first());
+ QCOMPARE(currentPath, home);
+ QCOMPARE(backButton->isEnabled(), false);
+ QCOMPARE(forwardButton->isEnabled(), true);
+ QCOMPARE(spy.count(), 4);
+
+ // nothing should change at this point
+ backButton->click();
+ QCOMPARE(spy.count(), 4);
+ QCOMPARE(backButton->isEnabled(), false);
+ QCOMPARE(forwardButton->isEnabled(), true);
+}
+
+void tst_QFiledialog::historyForward()
+{
+ QNonNativeFileDialog fd;
+ fd.setDirectory(QDir::currentPath());
+ QToolButton *backButton = qFindChild<QToolButton*>(&fd, "backButton");
+ QVERIFY(backButton);
+ QToolButton *forwardButton = qFindChild<QToolButton*>(&fd, "forwardButton");
+ QVERIFY(forwardButton);
+
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QVERIFY(model);
+ QSignalSpy spy(model, SIGNAL(rootPathChanged(const QString &)));
+
+ QString home = fd.directory().absolutePath();
+ QString desktop = QDir::homePath();
+ QString temp = QDir::tempPath();
+
+ fd.setDirectory(home);
+ fd.setDirectory(temp);
+ fd.setDirectory(desktop);
+
+ backButton->click();
+ QCOMPARE(forwardButton->isEnabled(), true);
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(temp));
+
+ forwardButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(desktop));
+ QCOMPARE(backButton->isEnabled(), true);
+ QCOMPARE(forwardButton->isEnabled(), false);
+ QCOMPARE(spy.count(), 4);
+
+ backButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(temp));
+ QCOMPARE(backButton->isEnabled(), true);
+
+ backButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(home));
+ QCOMPARE(backButton->isEnabled(), false);
+ QCOMPARE(forwardButton->isEnabled(), true);
+ QCOMPARE(spy.count(), 6);
+
+ forwardButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(temp));
+ backButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(home));
+ QCOMPARE(spy.count(), 8);
+
+ forwardButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(temp));
+ forwardButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(desktop));
+
+ backButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(temp));
+ backButton->click();
+ QCOMPARE(model->index(qVariantValue<QString>(spy.last().first())), model->index(home));
+ fd.setDirectory(desktop);
+ QCOMPARE(forwardButton->isEnabled(), false);
+}
+
+void tst_QFiledialog::disableSaveButton_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<bool>("isEnabled");
+
+ QTest::newRow("valid path") << QDir::temp().absolutePath() + QDir::separator() + "qfiledialog.new_file" << true;
+ QTest::newRow("no path") << "" << false;
+#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_OPENBSD)
+ QTest::newRow("too long path") << "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" << false;
+#endif
+ QTest::newRow("file") << "foo.html" << true;
+}
+
+void tst_QFiledialog::disableSaveButton()
+{
+ QFETCH(QString, path);
+ QFETCH(bool, isEnabled);
+
+ QNonNativeFileDialog fd(0, "caption", path);
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
+ QPushButton *button = buttonBox->button(QDialogButtonBox::Save);
+ QVERIFY(button);
+ QCOMPARE(button->isEnabled(), isEnabled);
+}
+
+void tst_QFiledialog::saveButtonText_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<QString>("label");
+ QTest::addColumn<QString>("caption");
+
+ QTest::newRow("empty path") << "" << QString() << QFileDialog::tr("&Save");
+ QTest::newRow("file path") << "qfiledialog.new_file" << QString() << QFileDialog::tr("&Save");
+ QTest::newRow("dir") << QDir::temp().absolutePath() << QString() << QFileDialog::tr("&Open");
+ QTest::newRow("setTextLabel") << "qfiledialog.new_file" << "Mooo" << "Mooo";
+ QTest::newRow("dir & label") << QDir::temp().absolutePath() << "Poo" << QFileDialog::tr("&Open");
+}
+
+void tst_QFiledialog::saveButtonText()
+{
+ QFETCH(QString, path);
+ QFETCH(QString, label);
+ QFETCH(QString, caption);
+
+ QNonNativeFileDialog fd(0, "auto test", QDir::temp().absolutePath());
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ if (!label.isNull())
+ fd.setLabelText(QFileDialog::Accept, label);
+ fd.setDirectory(QDir::temp());
+ fd.selectFile(path);
+ QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
+ QVERIFY(buttonBox);
+ QPushButton *button = buttonBox->button(QDialogButtonBox::Save);
+ QVERIFY(button);
+ QCOMPARE(button->text(), caption);
+}
+
+void tst_QFiledialog::clearLineEdit()
+{
+ QNonNativeFileDialog fd(0, "caption", "foo");
+ fd.setViewMode(QFileDialog::List);
+ fd.setFileMode(QFileDialog::AnyFile);
+ fd.setOptions(QFileDialog::DontUseNativeDialog);
+ fd.show();
+
+ //play it really safe by creating a directory
+ QDir::home().mkdir("_____aaaaaaaaaaaaaaaaaaaaaa");
+
+ QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QVERIFY(lineEdit);
+ QVERIFY(lineEdit->text() == "foo");
+ fd.setDirectory(QDir::home());
+
+ QListView* list = qFindChild<QListView*>(&fd, "listView");
+ QVERIFY(list);
+
+ // saving a file the text shouldn't be cleared
+ fd.setDirectory(QDir::home());
+
+ QTest::qWait(1000);
+#ifdef QT_KEYPAD_NAVIGATION
+ list->setEditFocus(true);
+#endif
+ QTest::keyClick(list, Qt::Key_Down);
+#ifndef Q_WS_MAC
+ QTest::keyClick(list, Qt::Key_Return);
+#else
+ QTest::keyClick(list, Qt::Key_O, Qt::ControlModifier);
+#endif
+
+ QTest::qWait(2000);
+ QVERIFY(fd.directory().absolutePath() != QDir::home().absolutePath());
+ QVERIFY(!lineEdit->text().isEmpty());
+
+ // selecting a dir the text should be cleared so one can just hit ok
+ // and it selects that directory
+ fd.setFileMode(QNonNativeFileDialog::Directory);
+ fd.setDirectory(QDir::home());
+
+ QTest::qWait(1000);
+ QTest::keyClick(list, Qt::Key_Down);
+#ifndef Q_WS_MAC
+ QTest::keyClick(list, Qt::Key_Return);
+#else
+ QTest::keyClick(list, Qt::Key_O, Qt::ControlModifier);
+#endif
+
+ QTest::qWait(2000);
+ QVERIFY(fd.directory().absolutePath() != QDir::home().absolutePath());
+ QVERIFY(lineEdit->text().isEmpty());
+
+ //remove the dir
+ QDir::home().rmdir("_____aaaaaaaaaaaaaaaaaaaaaa");
+}
+
+void tst_QFiledialog::enableChooseButton()
+{
+ QNonNativeFileDialog fd;
+ fd.setFileMode(QFileDialog::Directory);
+ fd.show();
+ QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
+ QPushButton *button = buttonBox->button(QDialogButtonBox::Open);
+ QVERIFY(button);
+ QCOMPARE(button->isEnabled(), true);
+}
+
+QT_BEGIN_NAMESPACE
+typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options);
+extern Q_GUI_EXPORT _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook;
+QT_END_NAMESPACE
+QString existing(QWidget *, const QString &, const QString &, QFileDialog::Options) {
+ return "dir";
+}
+
+QT_BEGIN_NAMESPACE
+typedef QString (*_qt_filedialog_open_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
+extern Q_GUI_EXPORT _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook;
+QT_END_NAMESPACE
+QString openName(QWidget *, const QString &, const QString &, const QString &, QString *, QFileDialog::Options) {
+ return "openName";
+}
+
+QT_BEGIN_NAMESPACE
+typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
+extern Q_GUI_EXPORT _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook;
+QT_END_NAMESPACE
+QStringList openNames(QWidget *, const QString &, const QString &, const QString &, QString *, QFileDialog::Options) {
+ return QStringList("openNames");
+}
+
+QT_BEGIN_NAMESPACE
+typedef QString (*_qt_filedialog_save_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
+extern Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook;
+QT_END_NAMESPACE
+QString saveName(QWidget *, const QString &, const QString &, const QString &, QString *, QFileDialog::Options) {
+ return "saveName";
+}
+
+
+void tst_QFiledialog::hooks()
+{
+ qt_filedialog_existing_directory_hook = &existing;
+ qt_filedialog_save_filename_hook = &saveName;
+ qt_filedialog_open_filename_hook = &openName;
+ qt_filedialog_open_filenames_hook = &openNames;
+
+ QCOMPARE(QFileDialog::getExistingDirectory(), QString("dir"));
+ QCOMPARE(QFileDialog::getOpenFileName(), QString("openName"));
+ QCOMPARE(QFileDialog::getOpenFileNames(), QStringList("openNames"));
+ QCOMPARE(QFileDialog::getSaveFileName(), QString("saveName"));
+}
+
+// Test case relies on developer build (AUTOTEST_EXPORT).
+#if defined(Q_OS_UNIX) && defined(QT_BUILD_INTERNAL)
+void tst_QFiledialog::tildeExpansion_data()
+{
+ QTest::addColumn<QString>("tildePath");
+ QTest::addColumn<QString>("expandedPath");
+
+ QTest::newRow("empty path") << QString() << QString();
+ QTest::newRow("~") << QString::fromLatin1("~") << QDir::homePath();
+ QTest::newRow("~/some/sub/dir/") << QString::fromLatin1("~/some/sub/dir") << QDir::homePath()
+ + QString::fromLatin1("/some/sub/dir");
+ QString userHome = QString(qgetenv("USER"));
+ userHome.prepend('~');
+ QTest::newRow("current user (~<user> syntax)") << userHome << QDir::homePath();
+ QString invalid = QString::fromLatin1("~thisIsNotAValidUserName");
+ QTest::newRow("invalid user name") << invalid << invalid;
+}
+
+void tst_QFiledialog::tildeExpansion()
+{
+ QFETCH(QString, tildePath);
+ QFETCH(QString, expandedPath);
+
+ QCOMPARE(qt_tildeExpansion(tildePath), expandedPath);
+}
+#endif
+
+QTEST_MAIN(tst_QFiledialog)
+#include "tst_qfiledialog.moc"
diff --git a/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro b/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro
new file mode 100644
index 0000000000..a2149c8a39
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfiledialog2/qfiledialog2.pro
@@ -0,0 +1,20 @@
+load(qttest_p4)
+
+QT += widgets widgets-private
+QT += core-private gui-private
+
+SOURCES += tst_qfiledialog2.cpp
+
+wince* {
+ addFiles.files = *.cpp
+ addFiles.path = .
+ filesInDir.files = *.pro
+ filesInDir.path = someDir
+ DEPLOYMENT += addFiles filesInDir
+}
+
+wince* {
+ DEFINES += SRCDIR=\\\"./\\\"
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD/\\\"
+}
diff --git a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
new file mode 100644
index 0000000000..a2d18eb847
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
@@ -0,0 +1,1213 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <qcoreapplication.h>
+#include <qdebug.h>
+#include <qfiledialog.h>
+#include <qabstractitemdelegate.h>
+#include <qdirmodel.h>
+#include <qitemdelegate.h>
+#include <qlistview.h>
+#include <qcombobox.h>
+#include <qpushbutton.h>
+#include <qtoolbutton.h>
+#include <qtreeview.h>
+#include <qheaderview.h>
+#include <qcompleter.h>
+#include <qaction.h>
+#include <qdialogbuttonbox.h>
+#include <qsortfilterproxymodel.h>
+#include <qlineedit.h>
+#include <qlayout.h>
+#include "../../../../../src/widgets/dialogs/qsidebar_p.h"
+#include "../../../../../src/widgets/dialogs/qfilesystemmodel_p.h"
+#include "../../../../../src/widgets/dialogs/qfiledialog_p.h"
+
+#include "../../../network-settings.h"
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+#if defined QT_BUILD_INTERNAL
+QT_BEGIN_NAMESPACE
+Q_GUI_EXPORT bool qt_test_isFetchedRoot();
+Q_GUI_EXPORT void qt_test_resetFetchedRoot();
+QT_END_NAMESPACE
+#endif
+
+class QNonNativeFileDialog : public QFileDialog
+{
+ Q_OBJECT
+public:
+ QNonNativeFileDialog(QWidget *parent = 0, const QString &caption = QString(), const QString &directory = QString(), const QString &filter = QString())
+ : QFileDialog(parent, caption, directory, filter)
+ {
+ setOption(QFileDialog::DontUseNativeDialog, true);
+ }
+};
+
+class tst_QFileDialog2 : public QObject
+{
+Q_OBJECT
+
+public:
+ tst_QFileDialog2();
+ virtual ~tst_QFileDialog2();
+
+public slots:
+ void init();
+ void cleanup();
+
+private slots:
+ void listRoot();
+ void heapCorruption();
+ void deleteDirAndFiles();
+ void filter();
+ void showNameFilterDetails();
+ void unc();
+ void emptyUncPath();
+
+ void task178897_minimumSize();
+ void task180459_lastDirectory_data();
+ void task180459_lastDirectory();
+ void task227304_proxyOnFileDialog();
+ void task227930_correctNavigationKeyboardBehavior();
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ void task226366_lowerCaseHardDriveWindows();
+#endif
+ void completionOnLevelAfterRoot();
+ void task233037_selectingDirectory();
+ void task235069_hideOnEscape();
+ void task236402_dontWatchDeletedDir();
+ void task203703_returnProperSeparator();
+ void task228844_ensurePreviousSorting();
+ void task239706_editableFilterCombo();
+ void task218353_relativePaths();
+ void task251321_sideBarHiddenEntries();
+ void task251341_sideBarRemoveEntries();
+ void task254490_selectFileMultipleTimes();
+ void task257579_sideBarWithNonCleanUrls();
+ void task259105_filtersCornerCases();
+
+ void QTBUG4419_lineEditSelectAll();
+ void QTBUG6558_showDirsOnly();
+ void QTBUG4842_selectFilterWithHideNameFilterDetails();
+ void dontShowCompleterOnRoot();
+
+private:
+ QByteArray userSettings;
+};
+
+tst_QFileDialog2::tst_QFileDialog2()
+{
+#if defined(Q_OS_WINCE)
+ qApp->setAutoMaximizeThreshold(-1);
+#endif
+}
+
+tst_QFileDialog2::~tst_QFileDialog2()
+{
+}
+
+void tst_QFileDialog2::init()
+{
+ // Save the developers settings so they don't get mad when their sidebar folders are gone.
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("Qt"));
+ userSettings = settings.value(QLatin1String("filedialog")).toByteArray();
+ settings.remove(QLatin1String("filedialog"));
+
+ // populate it with some default settings
+ QNonNativeFileDialog fd;
+#if defined(Q_OS_WINCE)
+ QTest::qWait(1000);
+#endif
+}
+
+void tst_QFileDialog2::cleanup()
+{
+ QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
+ settings.beginGroup(QLatin1String("Qt"));
+ settings.setValue(QLatin1String("filedialog"), userSettings);
+}
+
+void tst_QFileDialog2::listRoot()
+{
+#if defined QT_BUILD_INTERNAL
+ QFileInfoGatherer fileInfoGatherer;
+ fileInfoGatherer.start();
+ QTest::qWait(1500);
+ qt_test_resetFetchedRoot();
+ QString dir(QDir::currentPath());
+ QNonNativeFileDialog fd(0, QString(), dir);
+ fd.show();
+ QCOMPARE(qt_test_isFetchedRoot(),false);
+ fd.setDirectory("");
+#ifdef Q_OS_WINCE
+ QTest::qWait(1500);
+#else
+ QTest::qWait(500);
+#endif
+ QCOMPARE(qt_test_isFetchedRoot(),true);
+#endif
+}
+
+void tst_QFileDialog2::heapCorruption()
+{
+ QVector<QNonNativeFileDialog*> dialogs;
+ for (int i=0; i < 10; i++) {
+ QNonNativeFileDialog *f = new QNonNativeFileDialog(NULL);
+ dialogs << f;
+ }
+ qDeleteAll(dialogs);
+}
+
+struct FriendlyQFileDialog : public QNonNativeFileDialog
+{
+ friend class tst_QFileDialog2;
+ Q_DECLARE_PRIVATE(QFileDialog)
+};
+
+
+void tst_QFileDialog2::deleteDirAndFiles()
+{
+#if defined QT_BUILD_INTERNAL
+ QString tempPath = QDir::tempPath() + '/' + "QFileDialogTestDir4FullDelete";
+ QDir dir;
+ QVERIFY(dir.mkpath(tempPath + "/foo"));
+ QVERIFY(dir.mkpath(tempPath + "/foo/B"));
+ QVERIFY(dir.mkpath(tempPath + "/foo/B"));
+ QVERIFY(dir.mkpath(tempPath + "/foo/c"));
+ QVERIFY(dir.mkpath(tempPath + "/bar"));
+ QFile(tempPath + "/foo/a");
+ QTemporaryFile *t;
+ t = new QTemporaryFile(tempPath + "/foo/aXXXXXX");
+ t->setAutoRemove(false);
+ t->open();
+ t->close();
+ delete t;
+
+ t = new QTemporaryFile(tempPath + "/foo/B/yXXXXXX");
+ t->setAutoRemove(false);
+ t->open();
+ t->close();
+ delete t;
+ FriendlyQFileDialog fd;
+ fd.setOption(QFileDialog::DontUseNativeDialog);
+ fd.d_func()->removeDirectory(tempPath);
+ QFileInfo info(tempPath);
+ QTest::qWait(2000);
+ QVERIFY(!info.exists());
+#endif
+}
+
+void tst_QFileDialog2::filter()
+{
+ QNonNativeFileDialog fd;
+ QAction *hiddenAction = qFindChild<QAction*>(&fd, "qt_show_hidden_action");
+ QVERIFY(hiddenAction);
+ QVERIFY(hiddenAction->isEnabled());
+ QVERIFY(!hiddenAction->isChecked());
+ QDir::Filters filter = fd.filter();
+ filter |= QDir::Hidden;
+ fd.setFilter(filter);
+ QVERIFY(hiddenAction->isChecked());
+}
+
+void tst_QFileDialog2::showNameFilterDetails()
+{
+ QNonNativeFileDialog fd;
+ QComboBox *filters = qFindChild<QComboBox*>(&fd, "fileTypeCombo");
+ QVERIFY(filters);
+ QVERIFY(fd.isNameFilterDetailsVisible());
+
+
+ QStringList filterChoices;
+ filterChoices << "Image files (*.png *.xpm *.jpg)"
+ << "Text files (*.txt)"
+ << "Any files (*.*)";
+ fd.setFilters(filterChoices);
+
+ fd.setNameFilterDetailsVisible(false);
+ QCOMPARE(filters->itemText(0), QString("Image files"));
+ QCOMPARE(filters->itemText(1), QString("Text files"));
+ QCOMPARE(filters->itemText(2), QString("Any files"));
+
+ fd.setNameFilterDetailsVisible(true);
+ QCOMPARE(filters->itemText(0), filterChoices.at(0));
+ QCOMPARE(filters->itemText(1), filterChoices.at(1));
+ QCOMPARE(filters->itemText(2), filterChoices.at(2));
+}
+
+void tst_QFileDialog2::unc()
+{
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ // Only test UNC on Windows./
+ QString dir("\\\\" + QtNetworkSettings::winServerName() + "\\testsharewritable");
+#else
+ QString dir(QDir::currentPath());
+#endif
+ QVERIFY(QFile::exists(dir));
+ QNonNativeFileDialog fd(0, QString(), dir);
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QVERIFY(model);
+ QCOMPARE(model->index(fd.directory().absolutePath()), model->index(dir));
+}
+
+void tst_QFileDialog2::emptyUncPath()
+{
+ QNonNativeFileDialog fd;
+ fd.show();
+ QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QVERIFY(lineEdit);
+ // press 'keys' for the input
+ for (int i = 0; i < 3 ; ++i)
+ QTest::keyPress(lineEdit, Qt::Key_Backslash);
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QVERIFY(model);
+}
+
+void tst_QFileDialog2::task178897_minimumSize()
+{
+ QNonNativeFileDialog fd;
+ QSize oldMs = fd.layout()->minimumSize();
+ QStringList history = fd.history();
+ history << QDir::toNativeSeparators("/verylongdirectory/"
+ "aaaaaaaaaabbbbbbbbcccccccccccddddddddddddddeeeeeeeeeeeeffffffffffgggtggggggggghhhhhhhhiiiiiijjjk");
+ fd.setHistory(history);
+ fd.show();
+
+ QSize ms = fd.layout()->minimumSize();
+ QVERIFY(ms.width() <= oldMs.width());
+}
+
+void tst_QFileDialog2::task180459_lastDirectory_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::addColumn<QString>("directory");
+ QTest::addColumn<bool>("isEnabled");
+ QTest::addColumn<QString>("result");
+
+ QTest::newRow("path+file") << QDir::homePath() + QDir::separator() + "foo"
+ << QDir::homePath() << true
+ << QDir::homePath() + QDir::separator() + "foo" ;
+ QTest::newRow("no path") << ""
+ << QDir::tempPath() << false << QString();
+ QTest::newRow("file") << "foo"
+ << QDir::currentPath() << true
+ << QDir::currentPath() + QDir::separator() + "foo" ;
+ QTest::newRow("path") << QDir::homePath()
+ << QDir::homePath() << false << QString();
+ QTest::newRow("path not existing") << "/usr/bin/foo/bar/foo/foo.txt"
+ << QDir::tempPath() << true
+ << QDir::tempPath() + QDir::separator() + "foo.txt";
+
+}
+
+void tst_QFileDialog2::task180459_lastDirectory()
+{
+ //first visit the temp directory and close the dialog
+ QNonNativeFileDialog *dlg = new QNonNativeFileDialog(0, "", QDir::tempPath());
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(dlg, "qt_filesystem_model");
+ QVERIFY(model);
+ QCOMPARE(model->index(QDir::tempPath()), model->index(dlg->directory().absolutePath()));
+ delete dlg;
+
+ QFETCH(QString, path);
+ QFETCH(QString, directory);
+ QFETCH(bool, isEnabled);
+ QFETCH(QString, result);
+
+ dlg = new QNonNativeFileDialog(0, "", path);
+ model = qFindChild<QFileSystemModel*>(dlg, "qt_filesystem_model");
+ QVERIFY(model);
+ dlg->setAcceptMode(QFileDialog::AcceptSave);
+ QCOMPARE(model->index(dlg->directory().absolutePath()), model->index(directory));
+
+ QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(dlg, "buttonBox");
+ QPushButton *button = buttonBox->button(QDialogButtonBox::Save);
+ QVERIFY(button);
+ QCOMPARE(button->isEnabled(), isEnabled);
+ if (isEnabled)
+ QCOMPARE(model->index(result), model->index(dlg->selectedFiles().first()));
+
+ delete dlg;
+}
+
+
+
+class FilterDirModel : public QSortFilterProxyModel
+{
+
+public:
+ FilterDirModel(QString root, QObject* parent=0):QSortFilterProxyModel(parent), m_root(root)
+ {}
+ ~FilterDirModel()
+ {};
+
+protected:
+ bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
+ {
+ QModelIndex parentIndex;
+ parentIndex = source_parent;
+
+ QString path;
+ path = parentIndex.child(source_row,0).data(Qt::DisplayRole).toString();
+
+ do {
+ path = parentIndex.data(Qt::DisplayRole).toString() + "/" + path;
+ parentIndex = parentIndex.parent();
+ } while(parentIndex.isValid());
+
+ QFileInfo info(path);
+ if (info.isDir() && (QDir(path) != m_root))
+ return false;
+ return true;
+ }
+
+
+private:
+ QDir m_root;
+
+
+};
+
+class sortProxy : public QSortFilterProxyModel
+{
+public:
+ sortProxy(QObject *parent) : QSortFilterProxyModel(parent)
+ {
+ }
+protected:
+ virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const
+ {
+ QFileSystemModel * const model = qobject_cast<QFileSystemModel *>(sourceModel());
+ const QFileInfo leftInfo(model->fileInfo(left));
+ const QFileInfo rightInfo(model->fileInfo(right));
+
+ if (leftInfo.isDir() == rightInfo.isDir())
+ return(leftInfo.filePath().compare(rightInfo.filePath(),Qt::CaseInsensitive) < 0);
+ else if (leftInfo.isDir())
+ return(false);
+ else
+ return(true);
+ }
+};
+
+class CrashDialog : public QNonNativeFileDialog
+{
+ Q_OBJECT
+
+public:
+ CrashDialog(QWidget *parent, const QString &caption, const
+QString &dir, const QString &filter)
+ : QNonNativeFileDialog(parent, caption, dir, filter)
+ {
+ sortProxy *proxyModel = new sortProxy(this);
+ setProxyModel(proxyModel);
+ }
+};
+
+void tst_QFileDialog2::task227304_proxyOnFileDialog()
+{
+#if defined QT_BUILD_INTERNAL
+ QNonNativeFileDialog fd(0, "", QDir::currentPath(), 0);
+ fd.setProxyModel(new FilterDirModel(QDir::currentPath()));
+ fd.show();
+ QLineEdit *edit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QTest::qWait(200);
+ QTest::keyClick(edit, Qt::Key_T);
+ QTest::keyClick(edit, Qt::Key_S);
+ QTest::qWait(200);
+ QTest::keyClick(edit->completer()->popup(), Qt::Key_Down);
+
+ CrashDialog *dialog = new CrashDialog(0, QString("crash dialog test"), QDir::homePath(), QString("*") );
+ dialog->setFileMode(QFileDialog::ExistingFile);
+ dialog->show();
+
+ QListView *list = qFindChild<QListView*>(dialog, "listView");
+ QTest::qWait(200);
+ QTest::keyClick(list, Qt::Key_Down);
+ QTest::keyClick(list, Qt::Key_Return);
+ QTest::qWait(200);
+
+ dialog->close();
+ fd.close();
+
+ QNonNativeFileDialog fd2(0, "I should not crash with a proxy", QDir::tempPath(), 0);
+ QSortFilterProxyModel *pm = new QSortFilterProxyModel;
+ fd2.setProxyModel(pm);
+ fd2.show();
+ QSidebar *sidebar = qFindChild<QSidebar*>(&fd2, "sidebar");
+ sidebar->setFocus();
+ sidebar->selectUrl(QUrl::fromLocalFile(QDir::homePath()));
+ QTest::mouseClick(sidebar->viewport(), Qt::LeftButton, 0, sidebar->visualRect(sidebar->model()->index(1, 0)).center());
+ QTest::qWait(250);
+ //We shouldn't crash
+#endif
+}
+
+void tst_QFileDialog2::task227930_correctNavigationKeyboardBehavior()
+{
+ QDir current = QDir::currentPath();
+ current.mkdir("test");
+ current.cd("test");
+ QFile file("test/out.txt");
+ QFile file2("test/out2.txt");
+ QVERIFY(file.open(QIODevice::WriteOnly | QIODevice::Text));
+ QVERIFY(file2.open(QIODevice::WriteOnly | QIODevice::Text));
+ current.cdUp();
+ current.mkdir("test2");
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ fd.setDirectory(current.absolutePath());
+ fd.show();
+ QListView *list = qFindChild<QListView*>(&fd, "listView");
+ QTest::qWait(200);
+ QTest::keyClick(list, Qt::Key_Down);
+ QTest::keyClick(list, Qt::Key_Return);
+ QTest::qWait(200);
+ QTest::mouseClick(list->viewport(), Qt::LeftButton,0);
+ QTest::keyClick(list, Qt::Key_Down);
+ QTest::keyClick(list, Qt::Key_Backspace);
+ QTest::qWait(200);
+ QTest::keyClick(list, Qt::Key_Down);
+ QTest::keyClick(list, Qt::Key_Down);
+ QTest::keyClick(list, Qt::Key_Return);
+ QTest::qWait(200);
+ QCOMPARE(fd.isVisible(), true);
+ QTest::qWait(200);
+ file.close();
+ file2.close();
+ file.remove();
+ file2.remove();
+ current.rmdir("test");
+ current.rmdir("test2");
+}
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+void tst_QFileDialog2::task226366_lowerCaseHardDriveWindows()
+{
+ QNonNativeFileDialog fd;
+ fd.setDirectory(QDir::root().path());
+ fd.show();
+ QLineEdit *edit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QToolButton *buttonParent = qFindChild<QToolButton*>(&fd, "toParentButton");
+ QTest::qWait(200);
+ QTest::mouseClick(buttonParent, Qt::LeftButton,0,QPoint(0,0));
+ QTest::qWait(2000);
+ QTest::keyClick(edit, Qt::Key_C);
+ QTest::qWait(200);
+ QTest::keyClick(edit->completer()->popup(), Qt::Key_Down);
+ QTest::qWait(200);
+ QCOMPARE(edit->text(), QString("C:/"));
+ QTest::qWait(2000);
+ //i clear my previous selection in the completer
+ QTest::keyClick(edit->completer()->popup(), Qt::Key_Down);
+ edit->clear();
+ QTest::keyClick(edit, (char)(Qt::Key_C | Qt::SHIFT));
+ QTest::qWait(200);
+ QTest::keyClick(edit->completer()->popup(), Qt::Key_Down);
+ QCOMPARE(edit->text(), QString("C:/"));
+}
+#endif
+
+void tst_QFileDialog2::completionOnLevelAfterRoot()
+{
+ QNonNativeFileDialog fd;
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ fd.setDirectory("C:");
+ QDir current = fd.directory();
+ current.mkdir("completionOnLevelAfterRootTest");
+#else
+ fd.setFilter(QDir::Hidden | QDir::AllDirs | QDir::Files | QDir::System);
+ fd.setDirectory("/");
+ QDir etc("/etc");
+ if (!etc.exists())
+ QSKIP("This test requires to have an etc directory under /", SkipAll);
+#endif
+ fd.show();
+ QLineEdit *edit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QTest::qWait(2000);
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ //I love testlib :D
+ QTest::keyClick(edit, Qt::Key_C);
+ QTest::keyClick(edit, Qt::Key_O);
+ QTest::keyClick(edit, Qt::Key_M);
+ QTest::keyClick(edit, Qt::Key_P);
+ QTest::keyClick(edit, Qt::Key_L);
+#else
+ QTest::keyClick(edit, Qt::Key_E);
+ QTest::keyClick(edit, Qt::Key_T);
+#endif
+ QTest::qWait(200);
+ QTest::keyClick(edit->completer()->popup(), Qt::Key_Down);
+ QTest::qWait(200);
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ QCOMPARE(edit->text(), QString("completionOnLevelAfterRootTest"));
+ current.rmdir("completionOnLevelAfterRootTest");
+#else
+ QTRY_COMPARE(edit->text(), QString("etc"));
+#endif
+}
+
+void tst_QFileDialog2::task233037_selectingDirectory()
+{
+ QDir current = QDir::currentPath();
+ current.mkdir("test");
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ fd.setDirectory(current.absolutePath());
+ fd.setAcceptMode( QFileDialog::AcceptSave);
+ fd.show();
+ QListView *list = qFindChild<QListView*>(&fd, "listView");
+ QTest::qWait(3000); // Wait for sort to settle (I need a signal).
+#ifdef QT_KEYPAD_NAVIGATION
+ list->setEditFocus(true);
+#endif
+ QTest::keyClick(list, Qt::Key_Down);
+ QTest::qWait(100);
+ QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
+ QPushButton *button = buttonBox->button(QDialogButtonBox::Save);
+ QVERIFY(button);
+ QCOMPARE(button->isEnabled(), true);
+ current.rmdir("test");
+}
+
+void tst_QFileDialog2::task235069_hideOnEscape()
+{
+ QDir current = QDir::currentPath();
+ QNonNativeFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ fd.setDirectory(current.absolutePath());
+ fd.setAcceptMode( QFileDialog::AcceptSave);
+ fd.show();
+ QListView *list = qFindChild<QListView*>(&fd, "listView");
+ list->setFocus();
+ QTest::qWait(200);
+ QTest::keyClick(list, Qt::Key_Escape);
+ QCOMPARE(fd.isVisible(), false);
+ QNonNativeFileDialog fd2;
+ fd2.setDirectory(current.absolutePath());
+ fd2.setAcceptMode( QFileDialog::AcceptSave);
+ fd2.show();
+ QLineEdit *edit = qFindChild<QLineEdit*>(&fd2, "fileNameEdit");
+ QTest::keyClick(edit, Qt::Key_Escape);
+ QCOMPARE(fd2.isVisible(), false);
+}
+
+void tst_QFileDialog2::task236402_dontWatchDeletedDir()
+{
+#if defined QT_BUILD_INTERNAL
+ //THIS TEST SHOULD NOT DISPLAY WARNINGS
+ QDir current = QDir::currentPath();
+ //make sure it is the first on the list
+ current.mkdir("aaaaaaaaaa");
+ FriendlyQFileDialog fd;
+ fd.setViewMode(QFileDialog::List);
+ fd.setDirectory(current.absolutePath());
+ fd.setAcceptMode( QFileDialog::AcceptSave);
+ fd.show();
+ QListView *list = qFindChild<QListView*>(&fd, "listView");
+ list->setFocus();
+ QTest::qWait(200);
+ QTest::keyClick(list, Qt::Key_Return);
+ QTest::qWait(200);
+ QTest::keyClick(list, Qt::Key_Backspace);
+ QTest::keyClick(list, Qt::Key_Down);
+ QTest::qWait(200);
+ fd.d_func()->removeDirectory(current.absolutePath() + "/aaaaaaaaaa/");
+ QTest::qWait(1000);
+#endif
+}
+
+void tst_QFileDialog2::task203703_returnProperSeparator()
+{
+ QDir current = QDir::currentPath();
+ current.mkdir("aaaaaaaaaaaaaaaaaa");
+ QNonNativeFileDialog fd;
+ fd.setDirectory(current.absolutePath());
+ fd.setViewMode(QFileDialog::List);
+ fd.setFileMode(QFileDialog::Directory);
+ fd.show();
+ QTest::qWait(500);
+ QListView *list = qFindChild<QListView*>(&fd, "listView");
+ list->setFocus();
+ QTest::qWait(200);
+ QTest::keyClick(list, Qt::Key_Return);
+ QTest::qWait(1000);
+ QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
+ QPushButton *button = buttonBox->button(QDialogButtonBox::Cancel);
+ QTest::keyClick(button, Qt::Key_Return);
+ QTest::qWait(500);
+ QString result = fd.selectedFiles().first();
+ QVERIFY(result.at(result.count() - 1) != '/');
+ QVERIFY(!result.contains('\\'));
+ current.rmdir("aaaaaaaaaaaaaaaaaa");
+}
+
+void tst_QFileDialog2::task228844_ensurePreviousSorting()
+{
+ QDir current = QDir::currentPath();
+ current.mkdir("aaaaaaaaaaaaaaaaaa");
+ current.cd("aaaaaaaaaaaaaaaaaa");
+ current.mkdir("a");
+ current.mkdir("b");
+ current.mkdir("c");
+ current.mkdir("d");
+ current.mkdir("e");
+ current.mkdir("f");
+ current.mkdir("g");
+ QTemporaryFile *tempFile = new QTemporaryFile(current.absolutePath() + "/rXXXXXX");
+ tempFile->open();
+ current.cdUp();
+
+ QNonNativeFileDialog fd;
+ fd.setDirectory(current.absolutePath());
+ fd.setViewMode(QFileDialog::Detail);
+ fd.show();
+#if defined(Q_OS_WINCE)
+ QTest::qWait(1500);
+#else
+ QTest::qWait(500);
+#endif
+ QTreeView *tree = qFindChild<QTreeView*>(&fd, "treeView");
+ tree->header()->setSortIndicator(3,Qt::DescendingOrder);
+ QTest::qWait(200);
+ QDialogButtonBox *buttonBox = qFindChild<QDialogButtonBox*>(&fd, "buttonBox");
+ QPushButton *button = buttonBox->button(QDialogButtonBox::Open);
+ QTest::mouseClick(button, Qt::LeftButton);
+#if defined(Q_OS_WINCE)
+ QTest::qWait(1500);
+#else
+ QTest::qWait(500);
+#endif
+ QNonNativeFileDialog fd2;
+ fd2.setFileMode(QFileDialog::Directory);
+ fd2.restoreState(fd.saveState());
+ current.cd("aaaaaaaaaaaaaaaaaa");
+ fd2.setDirectory(current.absolutePath());
+ fd2.show();
+#if defined(Q_OS_WINCE)
+ QTest::qWait(1500);
+#else
+ QTest::qWait(500);
+#endif
+ QTreeView *tree2 = qFindChild<QTreeView*>(&fd2, "treeView");
+ tree2->setFocus();
+
+ QCOMPARE(tree2->rootIndex().data(QFileSystemModel::FilePathRole).toString(),current.absolutePath());
+
+ QDialogButtonBox *buttonBox2 = qFindChild<QDialogButtonBox*>(&fd2, "buttonBox");
+ QPushButton *button2 = buttonBox2->button(QDialogButtonBox::Open);
+ fd2.selectFile("g");
+ QTest::mouseClick(button2, Qt::LeftButton);
+#if defined(Q_OS_WINCE)
+ QTest::qWait(1500);
+#else
+ QTest::qWait(500);
+#endif
+ QCOMPARE(fd2.selectedFiles().first(), current.absolutePath() + QChar('/') + QLatin1String("g"));
+
+ QNonNativeFileDialog fd3(0, "This is a third file dialog", tempFile->fileName());
+ fd3.restoreState(fd.saveState());
+ fd3.setFileMode(QFileDialog::Directory);
+ fd3.show();
+#if defined(Q_OS_WINCE)
+ QTest::qWait(1500);
+#else
+ QTest::qWait(500);
+#endif
+ QTreeView *tree3 = qFindChild<QTreeView*>(&fd3, "treeView");
+ tree3->setFocus();
+
+ QCOMPARE(tree3->rootIndex().data(QFileSystemModel::FilePathRole).toString(), current.absolutePath());
+
+ QDialogButtonBox *buttonBox3 = qFindChild<QDialogButtonBox*>(&fd3, "buttonBox");
+ QPushButton *button3 = buttonBox3->button(QDialogButtonBox::Open);
+ QTest::mouseClick(button3, Qt::LeftButton);
+#if defined(Q_OS_WINCE)
+ QTest::qWait(1500);
+#else
+ QTest::qWait(500);
+#endif
+ QCOMPARE(fd3.selectedFiles().first(), tempFile->fileName());
+
+ current.cd("aaaaaaaaaaaaaaaaaa");
+ current.rmdir("a");
+ current.rmdir("b");
+ current.rmdir("c");
+ current.rmdir("d");
+ current.rmdir("e");
+ current.rmdir("f");
+ current.rmdir("g");
+ tempFile->close();
+ delete tempFile;
+ current.cdUp();
+ current.rmdir("aaaaaaaaaaaaaaaaaa");
+}
+
+
+void tst_QFileDialog2::task239706_editableFilterCombo()
+{
+ QNonNativeFileDialog d;
+ d.setNameFilter("*.cpp *.h");
+
+ d.show();
+ QTest::qWait(500);
+
+ QList<QComboBox *> comboList = d.findChildren<QComboBox *>();
+ QComboBox *filterCombo = 0;
+ foreach (QComboBox *combo, comboList) {
+ if (combo->objectName() == QString("fileTypeCombo")) {
+ filterCombo = combo;
+ break;
+ }
+ }
+ QVERIFY(filterCombo);
+ filterCombo->setEditable(true);
+ QTest::mouseClick(filterCombo, Qt::LeftButton);
+ QTest::keyPress(filterCombo, Qt::Key_X);
+ QTest::keyPress(filterCombo, Qt::Key_Enter); // should not trigger assertion failure
+}
+
+void tst_QFileDialog2::task218353_relativePaths()
+{
+ QDir appDir = QDir::current();
+ QVERIFY(appDir.cdUp() != false);
+ QNonNativeFileDialog d(0, "TestDialog", "..");
+ QCOMPARE(d.directory().absolutePath(), appDir.absolutePath());
+
+ d.setDirectory(appDir.absolutePath() + QLatin1String("/non-existing-directory/../another-non-existing-dir/../"));
+ QCOMPARE(d.directory().absolutePath(), appDir.absolutePath());
+
+ QDir::current().mkdir("test");
+ appDir = QDir::current();
+ d.setDirectory(appDir.absolutePath() + QLatin1String("/test/../test/../"));
+ QCOMPARE(d.directory().absolutePath(), appDir.absolutePath());
+ appDir.rmdir("test");
+}
+
+void tst_QFileDialog2::task251321_sideBarHiddenEntries()
+{
+#if defined QT_BUILD_INTERNAL
+ QNonNativeFileDialog fd;
+
+ QDir current = QDir::currentPath();
+ current.mkdir(".hidden");
+ QDir hiddenDir = QDir(".hidden");
+ hiddenDir.mkdir("subdir");
+ QDir hiddenSubDir = QDir(".hidden/subdir");
+ hiddenSubDir.mkdir("happy");
+ hiddenSubDir.mkdir("happy2");
+
+ QList<QUrl> urls;
+ urls << QUrl::fromLocalFile(hiddenSubDir.absolutePath());
+ fd.setSidebarUrls(urls);
+ fd.show();
+ QTest::qWait(250);
+
+ QSidebar *sidebar = qFindChild<QSidebar*>(&fd, "sidebar");
+ sidebar->setFocus();
+ sidebar->selectUrl(QUrl::fromLocalFile(hiddenSubDir.absolutePath()));
+ QTest::mouseClick(sidebar->viewport(), Qt::LeftButton, 0, sidebar->visualRect(sidebar->model()->index(0, 0)).center());
+ // give the background processes more time on windows mobile
+#ifdef Q_OS_WINCE
+ QTest::qWait(1000);
+#else
+ QTest::qWait(250);
+#endif
+
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QCOMPARE(model->rowCount(model->index(hiddenSubDir.absolutePath())), 2);
+
+ hiddenSubDir.rmdir("happy2");
+ hiddenSubDir.rmdir("happy");
+ hiddenDir.rmdir("subdir");
+ current.rmdir(".hidden");
+#endif
+}
+
+#if defined QT_BUILD_INTERNAL
+class MyQSideBar : public QSidebar
+{
+public :
+ MyQSideBar(QWidget *parent = 0) : QSidebar(parent)
+ {}
+
+ void removeSelection() {
+ QList<QModelIndex> idxs = selectionModel()->selectedIndexes();
+ QList<QPersistentModelIndex> indexes;
+ for (int i = 0; i < idxs.count(); i++)
+ indexes.append(idxs.at(i));
+
+ for (int i = 0; i < indexes.count(); ++i)
+ if (!indexes.at(i).data(Qt::UserRole + 1).toUrl().path().isEmpty())
+ model()->removeRow(indexes.at(i).row());
+ }
+};
+#endif
+
+void tst_QFileDialog2::task251341_sideBarRemoveEntries()
+{
+#if defined QT_BUILD_INTERNAL
+ QNonNativeFileDialog fd;
+
+ QDir current = QDir::currentPath();
+ current.mkdir("testDir");
+ QDir testSubDir = QDir("testDir");
+
+ QList<QUrl> urls;
+ urls << QUrl::fromLocalFile(testSubDir.absolutePath());
+ urls << QUrl::fromLocalFile("NotFound");
+ fd.setSidebarUrls(urls);
+ fd.show();
+ QTest::qWait(250);
+
+ QSidebar *sidebar = qFindChild<QSidebar*>(&fd, "sidebar");
+ sidebar->setFocus();
+ //We enter in the first bookmark
+ sidebar->selectUrl(QUrl::fromLocalFile(testSubDir.absolutePath()));
+ QTest::mouseClick(sidebar->viewport(), Qt::LeftButton, 0, sidebar->visualRect(sidebar->model()->index(0, 0)).center());
+ QTest::qWait(250);
+
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ //There is no file
+ QCOMPARE(model->rowCount(model->index(testSubDir.absolutePath())), 0);
+ //Icon is not enabled QUrlModel::EnabledRole
+ QVariant value = sidebar->model()->index(0, 0).data(Qt::UserRole + 2);
+ QCOMPARE(qvariant_cast<bool>(value), true);
+
+ sidebar->setFocus();
+ //We enter in the second bookmark which is invalid
+ sidebar->selectUrl(QUrl::fromLocalFile("NotFound"));
+ QTest::mouseClick(sidebar->viewport(), Qt::LeftButton, 0, sidebar->visualRect(sidebar->model()->index(1, 0)).center());
+ QTest::qWait(250);
+
+ //We fallback to root because the entry in the bookmark is invalid
+ QCOMPARE(model->rowCount(model->index("NotFound")), model->rowCount(model->index(model->rootPath())));
+ //Icon is not enabled QUrlModel::EnabledRole
+ value = sidebar->model()->index(1, 0).data(Qt::UserRole + 2);
+ QCOMPARE(qvariant_cast<bool>(value), false);
+
+ MyQSideBar mySideBar;
+ mySideBar.init(model, urls);
+ mySideBar.show();
+ mySideBar.selectUrl(QUrl::fromLocalFile(testSubDir.absolutePath()));
+ QTest::qWait(1000);
+ mySideBar.removeSelection();
+
+ //We remove the first entry
+ QList<QUrl> expected;
+ expected << QUrl::fromLocalFile("NotFound");
+ QCOMPARE(mySideBar.urls(), expected);
+
+ mySideBar.selectUrl(QUrl::fromLocalFile("NotFound"));
+ mySideBar.removeSelection();
+
+ //We remove the second entry
+ expected.clear();
+ QCOMPARE(mySideBar.urls(), expected);
+
+ current.rmdir("testDir");
+#endif
+}
+
+void tst_QFileDialog2::task254490_selectFileMultipleTimes()
+{
+ QString tempPath = QDir::tempPath();
+ QTemporaryFile *t;
+ t = new QTemporaryFile;
+ t->open();
+ QNonNativeFileDialog fd(0, "TestFileDialog");
+
+ fd.setDirectory(tempPath);
+ fd.setViewMode(QFileDialog::List);
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ fd.setFileMode(QFileDialog::AnyFile);
+
+ //This should select the file in the QFileDialog
+ fd.selectFile(t->fileName());
+
+ //This should clear the selection and write it into the filename line edit
+ fd.selectFile("new_file.txt");
+
+ fd.show();
+ QTest::qWait(250);
+
+ QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QVERIFY(lineEdit);
+ QCOMPARE(lineEdit->text(),QLatin1String("new_file.txt"));
+ QListView *list = qFindChild<QListView*>(&fd, "listView");
+ QVERIFY(list);
+ QCOMPARE(list->selectionModel()->selectedRows(0).count(), 0);
+
+ t->deleteLater();
+}
+
+void tst_QFileDialog2::task257579_sideBarWithNonCleanUrls()
+{
+#if defined QT_BUILD_INTERNAL
+ QDir tempDir = QDir::temp();
+ QLatin1String dirname("autotest_task257579");
+ tempDir.rmdir(dirname); //makes sure it doesn't exist any more
+ QVERIFY(tempDir.mkdir(dirname));
+ QString url = QString::fromLatin1("%1/%2/..").arg(tempDir.absolutePath()).arg(dirname);
+ QNonNativeFileDialog fd;
+ fd.setSidebarUrls(QList<QUrl>() << QUrl::fromLocalFile(url));
+ QSidebar *sidebar = qFindChild<QSidebar*>(&fd, "sidebar");
+ QCOMPARE(sidebar->urls().count(), 1);
+ QVERIFY(sidebar->urls().first().toLocalFile() != url);
+ QCOMPARE(sidebar->urls().first().toLocalFile(), QDir::cleanPath(url));
+
+#ifdef Q_OS_WIN
+ QCOMPARE(sidebar->model()->index(0,0).data().toString().toLower(), tempDir.dirName().toLower());
+#else
+ QCOMPARE(sidebar->model()->index(0,0).data().toString(), tempDir.dirName());
+#endif
+
+ //all tests are finished, we can remove the temporary dir
+ QVERIFY(tempDir.rmdir(dirname));
+#endif
+}
+
+void tst_QFileDialog2::task259105_filtersCornerCases()
+{
+ QNonNativeFileDialog fd(0, "TestFileDialog");
+ fd.setNameFilter(QLatin1String("All Files! (*);;Text Files (*.txt)"));
+ fd.setOption(QFileDialog::HideNameFilterDetails, true);
+ fd.show();
+ QTest::qWait(250);
+
+ //Extensions are hidden
+ QComboBox *filters = qFindChild<QComboBox*>(&fd, "fileTypeCombo");
+ QVERIFY(filters);
+ QCOMPARE(filters->currentText(), QLatin1String("All Files!"));
+ filters->setCurrentIndex(1);
+ QCOMPARE(filters->currentText(), QLatin1String("Text Files"));
+
+ //We should have the full names
+ fd.setOption(QFileDialog::HideNameFilterDetails, false);
+ QTest::qWait(250);
+ filters->setCurrentIndex(0);
+ QCOMPARE(filters->currentText(), QLatin1String("All Files! (*)"));
+ filters->setCurrentIndex(1);
+ QCOMPARE(filters->currentText(), QLatin1String("Text Files (*.txt)"));
+
+ //Corner case undocumented of the task
+ fd.setNameFilter(QLatin1String("\352 (I like cheese) All Files! (*);;Text Files (*.txt)"));
+ QCOMPARE(filters->currentText(), QLatin1String("\352 (I like cheese) All Files! (*)"));
+ filters->setCurrentIndex(1);
+ QCOMPARE(filters->currentText(), QLatin1String("Text Files (*.txt)"));
+
+ fd.setOption(QFileDialog::HideNameFilterDetails, true);
+ filters->setCurrentIndex(0);
+ QTest::qWait(500);
+ QCOMPARE(filters->currentText(), QLatin1String("\352 (I like cheese) All Files!"));
+ filters->setCurrentIndex(1);
+ QCOMPARE(filters->currentText(), QLatin1String("Text Files"));
+
+ fd.setOption(QFileDialog::HideNameFilterDetails, true);
+ filters->setCurrentIndex(0);
+ QTest::qWait(500);
+ QCOMPARE(filters->currentText(), QLatin1String("\352 (I like cheese) All Files!"));
+ filters->setCurrentIndex(1);
+ QCOMPARE(filters->currentText(), QLatin1String("Text Files"));
+}
+
+void tst_QFileDialog2::QTBUG4419_lineEditSelectAll()
+{
+ QString tempPath = QDir::tempPath();
+ QTemporaryFile *t;
+ t = new QTemporaryFile;
+ t->open();
+ QNonNativeFileDialog fd(0, "TestFileDialog", t->fileName());
+
+ fd.setDirectory(tempPath);
+ fd.setViewMode(QFileDialog::List);
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ fd.setFileMode(QFileDialog::AnyFile);
+
+ fd.show();
+ QApplication::setActiveWindow(&fd);
+ QTest::qWaitForWindowShown(&fd);
+ QTRY_COMPARE(fd.isVisible(), true);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd));
+
+ QTest::qWait(250);
+ QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+
+ QCOMPARE(tempPath + QChar('/') + lineEdit->text(), t->fileName());
+ QCOMPARE(tempPath + QChar('/') + lineEdit->selectedText(), t->fileName());
+}
+
+void tst_QFileDialog2::QTBUG6558_showDirsOnly()
+{
+ const QString tempPath = QDir::tempPath();
+ QDir dirTemp(tempPath);
+ const QString tempName = QLatin1String("showDirsOnly.") + QString::number(qrand());
+ dirTemp.mkdir(tempName);
+ dirTemp.cd(tempName);
+ QTRY_VERIFY(dirTemp.exists());
+
+ const QString dirPath = dirTemp.absolutePath();
+ QDir dir(dirPath);
+
+ //We create two dirs
+ dir.mkdir("a");
+ dir.mkdir("b");
+
+ //Create a file
+ QFile tempFile(dirPath + "/plop.txt");
+ tempFile.open(QIODevice::WriteOnly | QIODevice::Text);
+ QTextStream out(&tempFile);
+ out << "The magic number is: " << 49 << "\n";
+ tempFile.close();
+
+ QNonNativeFileDialog fd(0, "TestFileDialog");
+
+ fd.setDirectory(dir.absolutePath());
+ fd.setViewMode(QFileDialog::List);
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ fd.setOption(QFileDialog::ShowDirsOnly, true);
+ fd.show();
+
+ QApplication::setActiveWindow(&fd);
+ QTest::qWaitForWindowShown(&fd);
+ QTRY_COMPARE(fd.isVisible(), true);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd));
+
+ QFileSystemModel *model = qFindChild<QFileSystemModel*>(&fd, "qt_filesystem_model");
+ QTRY_COMPARE(model->rowCount(model->index(dir.absolutePath())), 2);
+
+ fd.setOption(QFileDialog::ShowDirsOnly, false);
+ QTRY_COMPARE(model->rowCount(model->index(dir.absolutePath())), 3);
+
+ fd.setOption(QFileDialog::ShowDirsOnly, true);
+ QTRY_COMPARE(model->rowCount(model->index(dir.absolutePath())), 2);
+
+ fd.setFileMode(QFileDialog::DirectoryOnly);
+ QTRY_COMPARE(model->rowCount(model->index(dir.absolutePath())), 2);
+ QTRY_COMPARE(bool(fd.options() & QFileDialog::ShowDirsOnly), true);
+
+ fd.setFileMode(QFileDialog::AnyFile);
+ QTRY_COMPARE(model->rowCount(model->index(dir.absolutePath())), 3);
+ QTRY_COMPARE(bool(fd.options() & QFileDialog::ShowDirsOnly), false);
+
+ fd.setDirectory(QDir::homePath());
+
+ //We remove the dirs
+ dir.rmdir("a");
+ dir.rmdir("b");
+
+ //we delete the file
+ tempFile.remove();
+
+ dirTemp.cdUp();
+ dirTemp.rmdir(tempName);
+}
+
+void tst_QFileDialog2::QTBUG4842_selectFilterWithHideNameFilterDetails()
+{
+ QStringList filtersStr;
+ filtersStr << "Images (*.png *.xpm *.jpg)" << "Text files (*.txt)" << "XML files (*.xml)";
+ QString chosenFilterString("Text files (*.txt)");
+
+ QNonNativeFileDialog fd(0, "TestFileDialog");
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ fd.setOption(QFileDialog::HideNameFilterDetails, true);
+ fd.setNameFilters(filtersStr);
+ fd.selectNameFilter(chosenFilterString);
+ fd.show();
+
+ QApplication::setActiveWindow(&fd);
+ QTest::qWaitForWindowShown(&fd);
+ QTRY_COMPARE(fd.isVisible(), true);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd));
+
+ QComboBox *filters = qFindChild<QComboBox*>(&fd, "fileTypeCombo");
+ //We compare the current combobox text with the stripped version
+ QCOMPARE(filters->currentText(), QString("Text files"));
+
+ QNonNativeFileDialog fd2(0, "TestFileDialog");
+ fd2.setAcceptMode(QFileDialog::AcceptSave);
+ fd2.setOption(QFileDialog::HideNameFilterDetails, false);
+ fd2.setNameFilters(filtersStr);
+ fd2.selectNameFilter(chosenFilterString);
+ fd2.show();
+
+ QApplication::setActiveWindow(&fd2);
+ QTest::qWaitForWindowShown(&fd2);
+ QTRY_COMPARE(fd2.isVisible(), true);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd2));
+
+ QComboBox *filters2 = qFindChild<QComboBox*>(&fd2, "fileTypeCombo");
+ //We compare the current combobox text with the non stripped version
+ QCOMPARE(filters2->currentText(), chosenFilterString);
+
+}
+
+void tst_QFileDialog2::dontShowCompleterOnRoot()
+{
+ QNonNativeFileDialog fd(0, "TestFileDialog");
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ fd.show();
+
+ QApplication::setActiveWindow(&fd);
+ QTest::qWaitForWindowShown(&fd);
+ QTRY_COMPARE(fd.isVisible(), true);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget*>(&fd));
+
+ fd.setDirectory("");
+ QLineEdit *lineEdit = qFindChild<QLineEdit*>(&fd, "fileNameEdit");
+ QTRY_VERIFY(lineEdit->text().isEmpty());
+
+ //The gatherer thread will then return the result
+ QApplication::processEvents();
+
+ QTRY_VERIFY(lineEdit->completer()->popup()->isHidden());
+}
+
+QTEST_MAIN(tst_QFileDialog2)
+#include "tst_qfiledialog2.moc"
diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/.gitignore b/tests/auto/widgets/dialogs/qfilesystemmodel/.gitignore
new file mode 100644
index 0000000000..9804e5a3d7
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfilesystemmodel/.gitignore
@@ -0,0 +1 @@
+tst_qfilesystemmodel
diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro b/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro
new file mode 100644
index 0000000000..a7d042ce5e
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro
@@ -0,0 +1,7 @@
+CONFIG += qttest_p4
+
+QT += widgets widgets-private
+QT += core-private gui
+
+SOURCES += tst_qfilesystemmodel.cpp
+TARGET = tst_qfilesystemmodel
diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
new file mode 100644
index 0000000000..26fa58e649
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
@@ -0,0 +1,1046 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#ifdef QT_BUILD_INTERNAL
+#include "../../../src/widgets/dialogs/qfilesystemmodel_p.h"
+#endif
+#include <QFileSystemModel>
+#include <QFileIconProvider>
+#include <QTreeView>
+#include <QHeaderView>
+#include <QTime>
+#include <QStyle>
+#include <QtGlobal>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+#define WAITTIME 1000
+
+// Will try to wait for the condition while allowing event processing
+// for a maximum of 5 seconds.
+#define TRY_WAIT(expr) \
+ do { \
+ const int step = 50; \
+ for (int __i = 0; __i < 5000 && !(expr); __i+=step) { \
+ QTest::qWait(step); \
+ } \
+ } while(0)
+
+class tst_QFileSystemModel : public QObject {
+ Q_OBJECT
+
+public:
+ tst_QFileSystemModel();
+ virtual ~tst_QFileSystemModel();
+
+public Q_SLOTS:
+ void init();
+ void cleanup();
+
+private slots:
+ void indexPath();
+
+ void rootPath();
+ void naturalCompare_data();
+ void naturalCompare();
+ void readOnly();
+ void iconProvider();
+
+ void rowCount();
+
+ void rowsInserted_data();
+ void rowsInserted();
+
+ void rowsRemoved_data();
+ void rowsRemoved();
+
+ void dataChanged_data();
+ void dataChanged();
+
+ void filters_data();
+ void filters();
+
+ void nameFilters();
+
+ void setData_data();
+ void setData();
+
+ void sort_data();
+ void sort();
+
+ void mkdir();
+
+ void caseSensitivity();
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ void Win32LongFileName();
+#endif
+
+ void drives_data();
+ void drives();
+ void dirsBeforeFiles();
+
+ void roleNames_data();
+ void roleNames();
+
+protected:
+ bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &intial_dirs = QStringList(), const QString &baseDir = QDir::temp().absolutePath());
+
+private:
+ QFileSystemModel *model;
+ QString flatDirTestPath;
+};
+
+tst_QFileSystemModel::tst_QFileSystemModel() : model(0)
+{
+ qRegisterMetaType<QModelIndex>("QModelIndex");
+
+ QTime midnight(0, 0, 0);
+ qsrand(midnight.secsTo(QTime::currentTime()));
+ // generating unique temporary directory name
+ flatDirTestPath = QDir::temp().path() + '/' + QString("flatdirtest.") + QString::number(qrand());
+}
+
+tst_QFileSystemModel::~tst_QFileSystemModel()
+{
+ QString tmp = flatDirTestPath;
+ QDir dir(tmp);
+ if (dir.exists() && !dir.rmdir(tmp))
+ qWarning("failed to remove tmp dir %s", dir.dirName().toAscii().data());
+}
+
+void tst_QFileSystemModel::init()
+{
+ cleanup();
+ QCOMPARE(model, (QFileSystemModel*)0);
+ model = new QFileSystemModel;
+}
+
+void tst_QFileSystemModel::cleanup()
+{
+ delete model;
+ model = 0;
+ QString tmp = flatDirTestPath;
+ QDir dir(tmp);
+ if (dir.exists(tmp)) {
+ QStringList list = dir.entryList(QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot);
+ for (int i = 0; i < list.count(); ++i) {
+ QFileInfo fi(dir.path() + '/' + list.at(i));
+ if (fi.exists() && fi.isFile()) {
+ QFile p(fi.absoluteFilePath());
+ p.setPermissions(QFile::ReadUser | QFile::ReadOwner | QFile::ExeOwner | QFile::ExeUser | QFile::WriteUser | QFile::WriteOwner | QFile::WriteOther);
+ QFile dead(dir.path() + '/' + list.at(i));
+ dead.remove();
+ }
+ if (fi.exists() && fi.isDir())
+ QVERIFY(dir.rmdir(list.at(i)));
+ }
+ list = dir.entryList(QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot);
+ QVERIFY(list.count() == 0);
+ }
+}
+
+void tst_QFileSystemModel::indexPath()
+{
+#if !defined(Q_OS_WIN)
+ int depth = QDir::currentPath().count('/');
+ model->setRootPath(QDir::currentPath());
+ QTest::qWait(WAITTIME);
+ QString backPath;
+ for (int i = 0; i <= depth * 2 + 1; ++i) {
+ backPath += "../";
+ QModelIndex idx = model->index(backPath);
+ QVERIFY(i != depth - 1 ? idx.isValid() : !idx.isValid());
+ }
+ QTest::qWait(WAITTIME * 3);
+ qApp->processEvents();
+#endif
+}
+
+void tst_QFileSystemModel::rootPath()
+{
+ QCOMPARE(model->rootPath(), QString(QDir().path()));
+
+ QSignalSpy rootChanged(model, SIGNAL(rootPathChanged(const QString &)));
+ QModelIndex root = model->setRootPath(model->rootPath());
+ root = model->setRootPath("this directory shouldn't exist");
+ QCOMPARE(rootChanged.count(), 0);
+
+ QString oldRootPath = model->rootPath();
+ root = model->setRootPath(QDir::homePath());
+
+ QTRY_VERIFY(model->rowCount(root) >= 0);
+ QCOMPARE(model->rootPath(), QString(QDir::homePath()));
+ QCOMPARE(rootChanged.count(), oldRootPath == model->rootPath() ? 0 : 1);
+ QCOMPARE(model->rootDirectory().absolutePath(), QDir::homePath());
+
+ model->setRootPath(QDir::rootPath());
+ int oldCount = rootChanged.count();
+ oldRootPath = model->rootPath();
+ root = model->setRootPath(QDir::homePath() + QLatin1String("/."));
+ QTRY_VERIFY(model->rowCount(root) >= 0);
+ QCOMPARE(model->rootPath(), QDir::homePath());
+ QCOMPARE(rootChanged.count(), oldRootPath == model->rootPath() ? oldCount : oldCount + 1);
+ QCOMPARE(model->rootDirectory().absolutePath(), QDir::homePath());
+
+ QDir newdir = QDir::home();
+ if (newdir.cdUp()) {
+ oldCount = rootChanged.count();
+ oldRootPath = model->rootPath();
+ root = model->setRootPath(QDir::homePath() + QLatin1String("/.."));
+ QTRY_VERIFY(model->rowCount(root) >= 0);
+ QCOMPARE(model->rootPath(), newdir.path());
+ QCOMPARE(rootChanged.count(), oldCount + 1);
+ QCOMPARE(model->rootDirectory().absolutePath(), newdir.path());
+ }
+}
+
+void tst_QFileSystemModel::naturalCompare_data()
+{
+ QTest::addColumn<QString>("s1");
+ QTest::addColumn<QString>("s2");
+ QTest::addColumn<int>("caseSensitive");
+ QTest::addColumn<int>("result");
+ QTest::addColumn<int>("swap");
+ for (int j = 0; j < 4; ++j) { // <- set a prefix and a postfix string (not numbers)
+ QString prefix = (j == 0 || j == 1) ? "b" : "";
+ QString postfix = (j == 1 || j == 2) ? "y" : "";
+
+ for (int k = 0; k < 3; ++k) { // <- make 0 not a special case
+ QString num = QString("%1").arg(k);
+ QString nump = QString("%1").arg(k + 1);
+ for (int i = 10; i < 12; ++i) { // <- swap s1 and s2 and reverse the result
+ QTest::newRow("basic") << prefix + "0" + postfix << prefix + "0" + postfix << int(Qt::CaseInsensitive) << 0;
+
+ // s1 should always be less then s2
+ QTest::newRow("just text") << prefix + "fred" + postfix << prefix + "jane" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("just numbers") << prefix + num + postfix << prefix + "9" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("zero") << prefix + num + postfix << prefix + "0" + nump + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("space b") << prefix + num + postfix << prefix + " " + nump + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("space a") << prefix + num + postfix << prefix + nump + " " + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("tab b") << prefix + num + postfix << prefix + " " + nump + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("tab a") << prefix + num + postfix << prefix + nump + " " + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("10 vs 2") << prefix + num + postfix << prefix + "10" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("diff len") << prefix + num + postfix << prefix + nump + postfix + "x" << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("01 before 1") << prefix + "0" + num + postfix << prefix + nump + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul nums 2nd") << prefix + "1-" + num + postfix << prefix + "1-" + nump + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul nums 2nd") << prefix + "10-" + num + postfix<< prefix + "10-10" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul nums 2nd") << prefix + "10-0"+ num + postfix<< prefix + "10-10" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul nums 2nd") << prefix + "10-" + num + postfix<< prefix + "10-010" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul nums big") << prefix + "10-" + num + postfix<< prefix + "20-0" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul nums big") << prefix + "2-" + num + postfix << prefix + "10-0" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul alphabet") << prefix + num + "-a" + postfix << prefix + num + "-c" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul alphabet2")<< prefix + num + "-a9" + postfix<< prefix + num + "-c0" + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("mul nums w\\0")<< prefix + num + "-"+ num + postfix<< prefix + num+"-0"+nump + postfix << int(Qt::CaseInsensitive) << i;
+ QTest::newRow("num first") << prefix + num + postfix << prefix + "a" + postfix << int(Qt::CaseInsensitive) << i;
+ }
+ }
+ }
+}
+
+void tst_QFileSystemModel::naturalCompare()
+{
+#ifdef QT_BUILD_INTERNAL
+ QFETCH(QString, s1);
+ QFETCH(QString, s2);
+ QFETCH(int, caseSensitive);
+ QFETCH(int, result);
+
+ if (result == 10)
+ QCOMPARE(QFileSystemModelPrivate::naturalCompare(s1, s2, Qt::CaseSensitivity(caseSensitive)), -1);
+ else
+ if (result == 11)
+ QCOMPARE(QFileSystemModelPrivate::naturalCompare(s2, s1, Qt::CaseSensitivity(caseSensitive)), 1);
+ else
+ QCOMPARE(QFileSystemModelPrivate::naturalCompare(s2, s1, Qt::CaseSensitivity(caseSensitive)), result);
+#if defined(Q_OS_WINCE)
+ // On Windows CE we need to wait after each test, otherwise no new threads can be
+ // created. The scheduler takes its time to recognize ended threads.
+ QTest::qWait(300);
+#endif
+#endif
+}
+
+void tst_QFileSystemModel::readOnly()
+{
+ QCOMPARE(model->isReadOnly(), true);
+ QTemporaryFile file;
+ file.open();
+ QModelIndex root = model->setRootPath(QDir::tempPath());
+
+ QTRY_VERIFY(model->rowCount(root) > 0);
+ QVERIFY(!(model->flags(model->index(file.fileName())) & Qt::ItemIsEditable));
+ model->setReadOnly(false);
+ QCOMPARE(model->isReadOnly(), false);
+ QVERIFY(model->flags(model->index(file.fileName())) & Qt::ItemIsEditable);
+}
+
+class CustomFileIconProvider : public QFileIconProvider
+{
+public:
+ CustomFileIconProvider() : QFileIconProvider() {
+ mb = qApp->style()->standardIcon(QStyle::SP_MessageBoxCritical);
+ dvd = qApp->style()->standardIcon(QStyle::SP_DriveDVDIcon);
+ }
+
+ virtual QIcon icon(const QFileInfo &info) const
+ {
+ if (info.isDir())
+ return mb;
+
+ return QFileIconProvider::icon(info);
+ }
+ virtual QIcon icon(IconType type) const
+ {
+ if (type == QFileIconProvider::Folder)
+ return dvd;
+
+ return QFileIconProvider::icon(type);
+ }
+private:
+ QIcon mb;
+ QIcon dvd;
+};
+
+void tst_QFileSystemModel::iconProvider()
+{
+ QVERIFY(model->iconProvider());
+ QFileIconProvider *p = new QFileIconProvider();
+ model->setIconProvider(p);
+ QCOMPARE(model->iconProvider(), p);
+ model->setIconProvider(0);
+ delete p;
+
+ QFileSystemModel *myModel = new QFileSystemModel();
+ myModel->setRootPath(QDir::homePath());
+ //Let's wait to populate the model
+ QTest::qWait(250);
+ //We change the provider, icons must me updated
+ CustomFileIconProvider *custom = new CustomFileIconProvider();
+ myModel->setIconProvider(custom);
+
+ QPixmap mb = qApp->style()->standardIcon(QStyle::SP_MessageBoxCritical).pixmap(50, 50);
+ QCOMPARE(myModel->fileIcon(myModel->index(QDir::homePath())).pixmap(50, 50), mb);
+ delete myModel;
+ delete custom;
+}
+
+bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount, const QStringList &initial_dirs, const QString &dir)
+{
+ QDir baseDir(dir);
+ if (!baseDir.exists(test_path)) {
+ if (!baseDir.mkdir(test_path) && false) {
+ qDebug() << "failed to create dir" << test_path;
+ return false;
+ }
+ }
+ //qDebug() << (model->rowCount(model->index(test_path))) << existingFileCount << initial_files;
+ TRY_WAIT((model->rowCount(model->index(test_path)) == existingFileCount));
+ for (int i = 0; i < initial_dirs.count(); ++i) {
+ QDir dir(test_path);
+ if (!dir.exists()) {
+ qWarning() << "error" << test_path << "doesn't exists";
+ return false;
+ }
+ if(!dir.mkdir(initial_dirs.at(i))) {
+ qWarning() << "error" << "failed to make" << initial_dirs.at(i);
+ return false;
+ }
+ //qDebug() << test_path + '/' + initial_dirs.at(i) << (QFile::exists(test_path + '/' + initial_dirs.at(i)));
+ }
+ for (int i = 0; i < initial_files.count(); ++i) {
+ QFile file(test_path + '/' + initial_files.at(i));
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) {
+ qDebug() << "failed to open file" << initial_files.at(i);
+ return false;
+ }
+ if (!file.resize(1024 + file.size())) {
+ qDebug() << "failed to resize file" << initial_files.at(i);
+ return false;
+ }
+ if (!file.flush()) {
+ qDebug() << "failed to flush file" << initial_files.at(i);
+ return false;
+ }
+ file.close();
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ if (initial_files.at(i)[0] == '.')
+ QProcess::execute(QString("attrib +h %1").arg(file.fileName()));
+#endif
+ //qDebug() << test_path + '/' + initial_files.at(i) << (QFile::exists(test_path + '/' + initial_files.at(i)));
+ }
+ return true;
+}
+
+void tst_QFileSystemModel::rowCount()
+{
+ QString tmp = flatDirTestPath;
+ QVERIFY(createFiles(tmp, QStringList()));
+
+ QSignalSpy spy2(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
+ QSignalSpy spy3(model, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)));
+
+#if !defined(Q_OS_WINCE)
+ QStringList files = QStringList() << "b" << "d" << "f" << "h" << "j" << ".a" << ".c" << ".e" << ".g";
+ QString l = "b,d,f,h,j,.a,.c,.e,.g";
+#else
+ // Cannot hide them on CE
+ QStringList files = QStringList() << "b" << "d" << "f" << "h" << "j";
+ QString l = "b,d,f,h,j";
+#endif
+ QVERIFY(createFiles(tmp, files));
+
+ QModelIndex root = model->setRootPath(tmp);
+ QTRY_COMPARE(model->rowCount(root), 5);
+ QVERIFY(spy2.count() > 0);
+ QVERIFY(spy3.count() > 0);
+}
+
+void tst_QFileSystemModel::rowsInserted_data()
+{
+ QTest::addColumn<int>("count");
+ QTest::addColumn<int>("assending");
+ for (int i = 0; i < 4; ++i) {
+ QTest::newRow(QString("Qt::AscendingOrder %1").arg(i).toLocal8Bit().constData()) << i << (int)Qt::AscendingOrder;
+ QTest::newRow(QString("Qt::DescendingOrder %1").arg(i).toLocal8Bit().constData()) << i << (int)Qt::DescendingOrder;
+ }
+}
+
+void tst_QFileSystemModel::rowsInserted()
+{
+#if defined(Q_OS_WINCE)
+ QSKIP("Watching directories does not work on CE(see #137910)", SkipAll);
+#endif
+ QString tmp = flatDirTestPath;
+ rowCount();
+ QModelIndex root = model->index(model->rootPath());
+
+ QFETCH(int, assending);
+ QFETCH(int, count);
+ model->sort(0, (Qt::SortOrder)assending);
+
+ QSignalSpy spy0(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
+ QSignalSpy spy1(model, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)));
+ int oldCount = model->rowCount(root);
+ QStringList files;
+ for (int i = 0; i < count; ++i)
+ files.append(QString("c%1").arg(i));
+ QVERIFY(createFiles(tmp, files, 5));
+ TRY_WAIT(model->rowCount(root) == oldCount + count);
+ QTRY_COMPARE(model->rowCount(root), oldCount + count);
+ QTest::qWait(100); // Let the sort settle.
+ int totalRowsInserted = 0;
+ for (int i = 0; i < spy0.count(); ++i) {
+ int start = spy0[i].value(1).toInt();
+ int end = spy0[i].value(2).toInt();
+ totalRowsInserted += end - start + 1;
+ }
+ QCOMPARE(totalRowsInserted, count);
+ if (assending == (Qt::SortOrder)Qt::AscendingOrder) {
+ QString letter = model->index(model->rowCount(root) - 1, 0, root).data().toString();
+ QCOMPARE(letter, QString("j"));
+ } else {
+ QCOMPARE(model->index(model->rowCount(root) - 1, 0, root).data().toString(), QString("b"));
+ }
+ if (spy0.count() > 0) {
+ if (count == 0)
+ QCOMPARE(spy0.count(), 0);
+ else
+ QVERIFY(spy0.count() >= 1);
+ }
+ if (count == 0) QCOMPARE(spy1.count(), 0); else QVERIFY(spy1.count() >= 1);
+
+ QVERIFY(createFiles(tmp, QStringList(".hidden_file"), 5 + count));
+
+ if (count != 0) QTRY_VERIFY(spy0.count() >= 1); else QTRY_VERIFY(spy0.count() == 0);
+ if (count != 0) QTRY_VERIFY(spy1.count() >= 1); else QTRY_VERIFY(spy1.count() == 0);
+}
+
+void tst_QFileSystemModel::rowsRemoved_data()
+{
+ rowsInserted_data();
+}
+
+void tst_QFileSystemModel::rowsRemoved()
+{
+#if defined(Q_OS_WINCE)
+ QSKIP("Watching directories does not work on CE(see #137910)", SkipAll);
+#endif
+ QString tmp = flatDirTestPath;
+ rowCount();
+ QModelIndex root = model->index(model->rootPath());
+
+ QFETCH(int, count);
+ QFETCH(int, assending);
+ model->sort(0, (Qt::SortOrder)assending);
+ QTest::qWait(WAITTIME);
+
+ QSignalSpy spy0(model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)));
+ QSignalSpy spy1(model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)));
+ int oldCount = model->rowCount(root);
+ for (int i = count - 1; i >= 0; --i) {
+ //qDebug() << "removing" << model->index(i, 0, root).data().toString();
+ QVERIFY(QFile::remove(tmp + '/' + model->index(i, 0, root).data().toString()));
+ }
+ for (int i = 0 ; i < 10; ++i) {
+ QTest::qWait(WAITTIME);
+ qApp->processEvents();
+ if (count != 0) {
+ if (i == 10 || spy0.count() != 0) {
+ QVERIFY(spy0.count() >= 1);
+ QVERIFY(spy1.count() >= 1);
+ }
+ } else {
+ if (i == 10 || spy0.count() == 0) {
+ QVERIFY(spy0.count() == 0);
+ QVERIFY(spy1.count() == 0);
+ }
+ }
+ QStringList lst;
+ for (int i = 0; i < model->rowCount(root); ++i)
+ lst.append(model->index(i, 0, root).data().toString());
+ if (model->rowCount(root) == oldCount - count)
+ break;
+ qDebug() << "still have:" << lst << QFile::exists(tmp + '/' + QString(".a"));
+ QDir tmpLister(tmp);
+ qDebug() << tmpLister.entryList();
+ }
+ QTRY_COMPARE(model->rowCount(root), oldCount - count);
+
+ QVERIFY(QFile::exists(tmp + '/' + QString(".a")));
+ QVERIFY(QFile::remove(tmp + '/' + QString(".a")));
+ QVERIFY(QFile::remove(tmp + '/' + QString(".c")));
+ QTest::qWait(WAITTIME);
+
+ if (count != 0) QVERIFY(spy0.count() >= 1); else QVERIFY(spy0.count() == 0);
+ if (count != 0) QVERIFY(spy1.count() >= 1); else QVERIFY(spy1.count() == 0);
+}
+
+void tst_QFileSystemModel::dataChanged_data()
+{
+ rowsInserted_data();
+}
+
+void tst_QFileSystemModel::dataChanged()
+{
+ // This can't be tested right now sense we don't watch files, only directories
+ return;
+
+ /*
+ QString tmp = flatDirTestPath;
+ rowCount();
+ QModelIndex root = model->index(model->rootPath());
+
+ QFETCH(int, count);
+ QFETCH(int, assending);
+ model->sort(0, (Qt::SortOrder)assending);
+
+ QSignalSpy spy(model, SIGNAL(dataChanged (const QModelIndex &, const QModelIndex &)));
+ QStringList files;
+ for (int i = 0; i < count; ++i)
+ files.append(model->index(i, 0, root).data().toString());
+ createFiles(tmp, files);
+
+ QTest::qWait(WAITTIME);
+
+ if (count != 0) QVERIFY(spy.count() >= 1); else QVERIFY(spy.count() == 0);
+ */
+}
+
+void tst_QFileSystemModel::filters_data()
+{
+ QTest::addColumn<QStringList>("files");
+ QTest::addColumn<QStringList>("dirs");
+ QTest::addColumn<int>("dirFilters");
+ QTest::addColumn<QStringList>("nameFilters");
+ QTest::addColumn<int>("rowCount");
+#if !defined(Q_OS_WINCE)
+ QTest::newRow("no dirs") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs) << QStringList() << 2;
+ QTest::newRow("no dirs - dot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 1;
+ QTest::newRow("no dirs - dotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 1;
+ QTest::newRow("no dirs - dotanddotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 0;
+ QTest::newRow("one dir - dot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 2;
+ QTest::newRow("one dir - dotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 2;
+ QTest::newRow("one dir - dotanddotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 1;
+ QTest::newRow("one dir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs) << QStringList() << 3;
+ QTest::newRow("no dir + hidden") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::Hidden) << QStringList() << 2;
+ QTest::newRow("dir+hid+files") << (QStringList() << "a" << "b" << "c") << QStringList() <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden) << QStringList() << 5;
+ QTest::newRow("dir+file+hid-dot .A") << (QStringList() << "a" << "b" << "c") << (QStringList() << ".A") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot) << QStringList() << 4;
+ QTest::newRow("dir+files+hid+dot A") << (QStringList() << "a" << "b" << "c") << (QStringList() << "AFolder") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot) << (QStringList() << "A*") << 2;
+ QTest::newRow("dir+files+hid+dot+cas1") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive) << (QStringList() << "Z") << 1;
+ QTest::newRow("dir+files+hid+dot+cas2") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive) << (QStringList() << "a") << 1;
+ QTest::newRow("dir+files+hid+dot+cas+alldir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive | QDir::AllDirs) << (QStringList() << "Z") << 1;
+#else
+ QTest::qWait(3000); // We need to calm down a bit...
+ QTest::newRow("no dirs") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs) << QStringList() << 0;
+ QTest::newRow("no dirs - dot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 1;
+ QTest::newRow("no dirs - dotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 1;
+ QTest::newRow("no dirs - dotanddotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 0;
+ QTest::newRow("one dir - dot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 2;
+ QTest::newRow("one dir - dotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 2;
+ QTest::newRow("one dir - dotanddotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 1;
+ QTest::newRow("one dir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs) << QStringList() << 1;
+ QTest::newRow("no dir + hidden") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::Hidden) << QStringList() << 0;
+ QTest::newRow("dir+hid+files") << (QStringList() << "a" << "b" << "c") << QStringList() <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden) << QStringList() << 3;
+ QTest::newRow("dir+file+hid-dot .A") << (QStringList() << "a" << "b" << "c") << (QStringList() << ".A") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot) << QStringList() << 4;
+ QTest::newRow("dir+files+hid+dot A") << (QStringList() << "a" << "b" << "c") << (QStringList() << "AFolder") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot) << (QStringList() << "A*") << 2;
+ QTest::newRow("dir+files+hid+dot+cas1") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive) << (QStringList() << "Z") << 1;
+ QTest::newRow("dir+files+hid+dot+cas2") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive) << (QStringList() << "a") << 1;
+ QTest::newRow("dir+files+hid+dot+cas+alldir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") <<
+ (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive | QDir::AllDirs) << (QStringList() << "Z") << 1;
+#endif
+
+ QTest::newRow("case sensitive") << (QStringList() << "Antiguagdb" << "Antiguamtd"
+ << "Antiguamtp" << "afghanistangdb" << "afghanistanmtd")
+ << QStringList() << (int)(QDir::Files) << QStringList() << 5;
+}
+
+void tst_QFileSystemModel::filters()
+{
+ QString tmp = flatDirTestPath;
+ QVERIFY(createFiles(tmp, QStringList()));
+ QModelIndex root = model->setRootPath(tmp);
+ QFETCH(QStringList, files);
+ QFETCH(QStringList, dirs);
+ QFETCH(int, dirFilters);
+ QFETCH(QStringList, nameFilters);
+ QFETCH(int, rowCount);
+
+ if (nameFilters.count() > 0)
+ model->setNameFilters(nameFilters);
+ model->setNameFilterDisables(false);
+ model->setFilter((QDir::Filters)dirFilters);
+
+ QVERIFY(createFiles(tmp, files, 0, dirs));
+ QTRY_COMPARE(model->rowCount(root), rowCount);
+
+ // Make sure that we do what QDir does
+ QDir xFactor(tmp);
+ QDir::Filters filters = (QDir::Filters)dirFilters;
+ QStringList dirEntries;
+
+ if (nameFilters.count() > 0)
+ dirEntries = xFactor.entryList(nameFilters, filters);
+ else
+ dirEntries = xFactor.entryList(filters);
+
+ QCOMPARE(dirEntries.count(), rowCount);
+
+ QStringList modelEntries;
+
+ for (int i = 0; i < rowCount; ++i)
+ modelEntries.append(model->data(model->index(i, 0, root), QFileSystemModel::FileNameRole).toString());
+
+ qSort(dirEntries);
+ qSort(modelEntries);
+ QCOMPARE(dirEntries, modelEntries);
+
+#ifdef Q_OS_LINUX
+ if (files.count() >= 3 && rowCount >= 3 && rowCount != 5) {
+ QString fileName1 = (tmp + '/' + files.at(0));
+ QString fileName2 = (tmp + '/' + files.at(1));
+ QString fileName3 = (tmp + '/' + files.at(2));
+ QFile::Permissions originalPermissions = QFile::permissions(fileName1);
+ QVERIFY(QFile::setPermissions(fileName1, QFile::WriteOwner));
+ QVERIFY(QFile::setPermissions(fileName2, QFile::ReadOwner));
+ QVERIFY(QFile::setPermissions(fileName3, QFile::ExeOwner));
+
+ model->setFilter((QDir::Files | QDir::Readable));
+ QTRY_COMPARE(model->rowCount(root), 1);
+
+ model->setFilter((QDir::Files | QDir::Writable));
+ QTRY_COMPARE(model->rowCount(root), 1);
+
+ model->setFilter((QDir::Files | QDir::Executable));
+ QTRY_COMPARE(model->rowCount(root), 1);
+
+ // reset permissions
+ QVERIFY(QFile::setPermissions(fileName1, originalPermissions));
+ QVERIFY(QFile::setPermissions(fileName2, originalPermissions));
+ QVERIFY(QFile::setPermissions(fileName3, originalPermissions));
+ }
+#endif
+}
+
+void tst_QFileSystemModel::nameFilters()
+{
+ QStringList list;
+ list << "a" << "b" << "c";
+ model->setNameFilters(list);
+ model->setNameFilterDisables(false);
+ QCOMPARE(model->nameFilters(), list);
+
+ QString tmp = flatDirTestPath;
+ QVERIFY(createFiles(tmp, list));
+ QModelIndex root = model->setRootPath(tmp);
+ QTRY_COMPARE(model->rowCount(root), 3);
+
+ QStringList filters;
+ filters << "a" << "b";
+ model->setNameFilters(filters);
+ QTRY_COMPARE(model->rowCount(root), 2);
+}
+void tst_QFileSystemModel::setData_data()
+{
+ QTest::addColumn<QStringList>("files");
+ QTest::addColumn<QString>("oldFileName");
+ QTest::addColumn<QString>("newFileName");
+ QTest::addColumn<bool>("success");
+ /*QTest::newRow("outside current dir") << (QStringList() << "a" << "b" << "c")
+ << flatDirTestPath + '/' + "a"
+ << QDir::temp().absolutePath() + '/' + "a"
+ << false;
+ */
+ QTest::newRow("in current dir") << (QStringList() << "a" << "b" << "c")
+ << "a"
+ << "d"
+ << true;
+}
+
+void tst_QFileSystemModel::setData()
+{
+ QSignalSpy spy(model, SIGNAL(fileRenamed(const QString&, const QString&, const QString&)));
+ QString tmp = flatDirTestPath;
+ QFETCH(QStringList, files);
+ QFETCH(QString, oldFileName);
+ QFETCH(QString, newFileName);
+ QFETCH(bool, success);
+
+ QVERIFY(createFiles(tmp, files));
+ QModelIndex root = model->setRootPath(tmp);
+ QTRY_COMPARE(model->rowCount(root), files.count());
+
+ QModelIndex idx = model->index(tmp + '/' + oldFileName);
+ QCOMPARE(idx.isValid(), true);
+ QCOMPARE(model->setData(idx, newFileName), false);
+
+ model->setReadOnly(false);
+ QCOMPARE(model->setData(idx, newFileName), success);
+ if (success) {
+ QCOMPARE(spy.count(), 1);
+ QList<QVariant> arguments = spy.takeFirst();
+ QCOMPARE(model->data(idx, QFileSystemModel::FileNameRole).toString(), newFileName);
+ QCOMPARE(model->index(arguments.at(0).toString()), model->index(tmp));
+ QCOMPARE(arguments.at(1).toString(), oldFileName);
+ QCOMPARE(arguments.at(2).toString(), newFileName);
+ QCOMPARE(QFile::rename(tmp + '/' + newFileName, tmp + '/' + oldFileName), true);
+ }
+ QTRY_COMPARE(model->rowCount(root), files.count());
+}
+
+class MyFriendFileSystemModel : public QFileSystemModel
+{
+ friend class tst_QFileSystemModel;
+ Q_DECLARE_PRIVATE(QFileSystemModel)
+};
+
+void tst_QFileSystemModel::sort_data()
+{
+ QTest::addColumn<bool>("fileDialogMode");
+ QTest::newRow("standard usage") << false;
+ QTest::newRow("QFileDialog usage") << true;
+}
+
+void tst_QFileSystemModel::sort()
+{
+ QTemporaryFile file;
+ file.open();
+ QModelIndex root = model->setRootPath(QDir::tempPath());
+ QTRY_VERIFY(model->rowCount(root) > 0);
+
+ QPersistentModelIndex idx = model->index(0, 1, root);
+ model->sort(0, Qt::AscendingOrder);
+ model->sort(0, Qt::DescendingOrder);
+ QVERIFY(idx.column() != 0);
+
+ model->setRootPath(QDir::homePath());
+
+ QFETCH(bool, fileDialogMode);
+
+ MyFriendFileSystemModel *myModel = new MyFriendFileSystemModel();
+ QTreeView *tree = new QTreeView();
+
+#ifdef QT_BUILD_INTERNAL
+ if (fileDialogMode)
+ myModel->d_func()->disableRecursiveSort = true;
+#endif
+
+ QDir dir(QDir::tempPath());
+ //initialize the randomness
+ qsrand(QDateTime::currentDateTime().toTime_t());
+ QString tempName = QLatin1String("sortTemp.") + QString::number(qrand());
+ dir.mkdir(tempName);
+ dir.cd(tempName);
+ QTRY_VERIFY(dir.exists());
+
+ const QString dirPath = dir.absolutePath();
+ QVERIFY(dir.exists());
+
+ //Create a file that will be at the end when sorting by name (For Mac, the default)
+ //but if we sort by size descending it will be the first
+ QFile tempFile(dirPath + "/plop2.txt");
+ tempFile.open(QIODevice::WriteOnly | QIODevice::Text);
+ QTextStream out(&tempFile);
+ out << "The magic number is: " << 49 << "\n";
+ tempFile.close();
+
+ QFile tempFile2(dirPath + "/plop.txt");
+ tempFile2.open(QIODevice::WriteOnly | QIODevice::Text);
+ QTextStream out2(&tempFile2);
+ out2 << "The magic number is : " << 49 << " but i write some stuff in the file \n";
+ tempFile2.close();
+
+ myModel->setRootPath("");
+ myModel->setFilter(QDir::AllEntries | QDir::System | QDir::Hidden);
+ tree->setSortingEnabled(true);
+ tree->setModel(myModel);
+ tree->show();
+ tree->resize(800, 800);
+ QTest::qWait(500);
+ tree->header()->setSortIndicator(1,Qt::DescendingOrder);
+ tree->header()->setResizeMode(0, QHeaderView::ResizeToContents);
+ QStringList dirsToOpen;
+ do
+ {
+ dirsToOpen<<dir.absolutePath();
+ } while (dir.cdUp());
+
+ for (int i = dirsToOpen.size() -1 ; i > 0 ; --i) {
+ QString path = dirsToOpen[i];
+ QTest::qWait(500);
+ tree->expand(myModel->index(path, 0));
+ }
+ tree->expand(myModel->index(dirPath, 0));
+ QTest::qWait(500);
+ QModelIndex parent = myModel->index(dirPath, 0);
+ QList<QString> expectedOrder;
+ expectedOrder << tempFile2.fileName() << tempFile.fileName() << dirPath + QChar('/') + "." << dirPath + QChar('/') + "..";
+ //File dialog Mode means sub trees are not sorted, only the current root
+ if (fileDialogMode) {
+ // FIXME: we were only able to disableRecursiveSort in developer builds, so we can only
+ // stably perform this test for developer builds
+#ifdef QT_BUILD_INTERNAL
+ QList<QString> actualRows;
+ for(int i = 0; i < myModel->rowCount(parent); ++i)
+ {
+ actualRows << dirPath + QChar('/') + myModel->index(i, 1, parent).data(QFileSystemModel::FileNameRole).toString();
+ }
+ QVERIFY(actualRows != expectedOrder);
+#endif
+ } else {
+ for(int i = 0; i < myModel->rowCount(parent); ++i)
+ {
+ QTRY_COMPARE(dirPath + QChar('/') + myModel->index(i, 1, parent).data(QFileSystemModel::FileNameRole).toString(), expectedOrder.at(i));
+ }
+ }
+
+ delete tree;
+ delete myModel;
+
+ dir.setPath(QDir::tempPath());
+ dir.cd(tempName);
+ tempFile.remove();
+ tempFile2.remove();
+ dir.cdUp();
+ dir.rmdir(tempName);
+
+}
+
+void tst_QFileSystemModel::mkdir()
+{
+ QString tmp = QDir::tempPath();
+ QString newFolderPath = QDir::toNativeSeparators(tmp + '/' + "NewFoldermkdirtest4");
+ QModelIndex tmpDir = model->index(tmp);
+ QVERIFY(tmpDir.isValid());
+ QDir bestatic(newFolderPath);
+ if (bestatic.exists()) {
+ if (!bestatic.rmdir(newFolderPath))
+ qWarning() << "unable to remove" << newFolderPath;
+ QTest::qWait(WAITTIME);
+ }
+ model->mkdir(tmpDir, "NewFoldermkdirtest3");
+ model->mkdir(tmpDir, "NewFoldermkdirtest5");
+ QModelIndex idx = model->mkdir(tmpDir, "NewFoldermkdirtest4");
+ QVERIFY(idx.isValid());
+ int oldRow = idx.row();
+ QTest::qWait(WAITTIME);
+ idx = model->index(newFolderPath);
+ QDir cleanup(tmp);
+ QVERIFY(cleanup.rmdir(QLatin1String("NewFoldermkdirtest3")));
+ QVERIFY(cleanup.rmdir(QLatin1String("NewFoldermkdirtest5")));
+ bestatic.rmdir(newFolderPath);
+ QVERIFY(0 != idx.row());
+ QCOMPARE(oldRow, idx.row());
+}
+
+void tst_QFileSystemModel::caseSensitivity()
+{
+ QString tmp = flatDirTestPath;
+ QStringList files;
+ files << "a" << "c" << "C";
+ QVERIFY(createFiles(tmp, files));
+ QModelIndex root = model->index(tmp);
+ QCOMPARE(model->rowCount(root), 0);
+ for (int i = 0; i < files.count(); ++i) {
+ QVERIFY(model->index(tmp + '/' + files.at(i)).isValid());
+ }
+}
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+void tst_QFileSystemModel::Win32LongFileName()
+{
+ QString tmp = flatDirTestPath;
+ QStringList files;
+ files << "aaaaaaaaaa" << "bbbbbbbbbb" << "cccccccccc";
+ QVERIFY(createFiles(tmp, files));
+ QModelIndex root = model->setRootPath(tmp);
+ QTRY_VERIFY(model->index(tmp + QLatin1String("/aaaaaa~1")).isValid());
+ QTRY_VERIFY(model->index(tmp + QLatin1String("/bbbbbb~1")).isValid());
+ QTRY_VERIFY(model->index(tmp + QLatin1String("/cccccc~1")).isValid());
+}
+#endif
+
+void tst_QFileSystemModel::drives_data()
+{
+ QTest::addColumn<QString>("path");
+ QTest::newRow("current") << QDir::currentPath();
+ QTest::newRow("slash") << "/";
+ QTest::newRow("My Computer") << "My Computer";
+}
+
+void tst_QFileSystemModel::drives()
+{
+ QFETCH(QString, path);
+ QFileSystemModel model;
+ model.setRootPath(path);
+ model.fetchMore(QModelIndex());
+ QFileInfoList drives = QDir::drives();
+ int driveCount = 0;
+ foreach(const QFileInfo& driveRoot, drives)
+ if (driveRoot.exists())
+ driveCount++;
+ QTest::qWait(5000);
+ QTRY_COMPARE(model.rowCount(), driveCount);
+}
+
+void tst_QFileSystemModel::dirsBeforeFiles()
+{
+ const QString dirPath = QString("%1/task221717_sortedOrder_test_dir").arg(QDir::tempPath());
+ QDir dir(dirPath);
+ // clean up from last time
+ if (dir.exists()) {
+ for (int i = 0; i < 3; ++i) {
+ QLatin1Char c('a' + i);
+ dir.rmdir(QString("%1-dir").arg(c));
+ QFile::remove(dirPath + QString("/%1-file").arg(c));
+ }
+ dir.rmdir(dirPath);
+ }
+ QVERIFY(dir.mkpath(dirPath));
+ QVERIFY(QDir(dirPath).exists());
+
+ for (int i = 0; i < 3; ++i) {
+ QLatin1Char c('a' + i);
+ dir.mkdir(QString("%1-dir").arg(c));
+ QFile file(dirPath + QString("/%1-file").arg(c));
+ file.open(QIODevice::ReadWrite);
+ file.close();
+ }
+
+ QModelIndex root = model->setRootPath(dirPath);
+ QTest::qWait(1000); // allow model to be notified by the file system watcher
+
+ // ensure that no file occurs before a directory
+ for (int i = 0; i < model->rowCount(root); ++i) {
+#ifndef Q_OS_MAC
+ QVERIFY(i == 0 ||
+ !(model->fileInfo(model->index(i - 1, 0, root)).isFile()
+ && model->fileInfo(model->index(i, 0, root)).isDir()));
+#else
+ QVERIFY(i == 0 ||
+ model->fileInfo(model->index(i - 1, 0, root)).fileName() <
+ model->fileInfo(model->index(i, 0, root)).fileName());
+#endif
+ }
+}
+
+void tst_QFileSystemModel::roleNames_data()
+{
+ QTest::addColumn<int>("role");
+ QTest::addColumn<QByteArray>("roleName");
+ QTest::newRow("decoration") << int(Qt::DecorationRole) << QByteArray("decoration");
+ QTest::newRow("display") << int(Qt::DisplayRole) << QByteArray("display");
+ QTest::newRow("fileIcon") << int(QFileSystemModel::FileIconRole) << QByteArray("fileIcon");
+ QTest::newRow("filePath") << int(QFileSystemModel::FilePathRole) << QByteArray("filePath");
+ QTest::newRow("fileName") << int(QFileSystemModel::FileNameRole) << QByteArray("fileName");
+ QTest::newRow("filePermissions") << int(QFileSystemModel::FilePermissions) << QByteArray("filePermissions");
+}
+
+void tst_QFileSystemModel::roleNames()
+{
+ QFileSystemModel model;
+ QHash<int, QByteArray> roles = model.roleNames();
+
+ QFETCH(int, role);
+ QVERIFY(roles.contains(role));
+
+ QFETCH(QByteArray, roleName);
+ QList<QByteArray> values = roles.values(role);
+ QVERIFY(values.contains(roleName));
+}
+
+QTEST_MAIN(tst_QFileSystemModel)
+#include "tst_qfilesystemmodel.moc"
+
diff --git a/tests/auto/widgets/dialogs/qfontdialog/.gitignore b/tests/auto/widgets/dialogs/qfontdialog/.gitignore
new file mode 100644
index 0000000000..5bd48d4951
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfontdialog/.gitignore
@@ -0,0 +1 @@
+tst_qfontdialog
diff --git a/tests/auto/widgets/dialogs/qfontdialog/qfontdialog.pro b/tests/auto/widgets/dialogs/qfontdialog/qfontdialog.pro
new file mode 100644
index 0000000000..5a0c2b66bf
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfontdialog/qfontdialog.pro
@@ -0,0 +1,12 @@
+load(qttest_p4)
+
+QT += widgets widgets-private
+QT += core-private gui-private
+
+SOURCES += tst_qfontdialog.cpp
+
+mac:!qpa {
+ OBJECTIVE_SOURCES += tst_qfontdialog_mac_helpers.mm
+ LIBS += -framework Cocoa
+}
+
diff --git a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp
new file mode 100644
index 0000000000..3f12b7501c
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+
+#include <qapplication.h>
+#include <qfontinfo.h>
+#include <qtimer.h>
+#include <qmainwindow.h>
+#include <qlistview.h>
+#include "qfontdialog.h"
+#include <private/qfontdialog_p.h>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+QT_FORWARD_DECLARE_CLASS(QtTestEventThread)
+
+class tst_QFontDialog : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QFontDialog();
+ virtual ~tst_QFontDialog();
+
+
+public slots:
+ void postKeyReturn();
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+private slots:
+ void defaultOkButton();
+ void setFont();
+ void task256466_wrongStyle();
+};
+
+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() {
+#ifndef Q_WS_MAC
+ QWidgetList list = QApplication::topLevelWidgets();
+ for (int i=0; i<list.count(); ++i) {
+ QFontDialog *dialog = qobject_cast<QFontDialog*>(list[i]);
+ if (dialog) {
+ QTest::keyClick( list[i], Qt::Key_Return, Qt::NoModifier );
+ return;
+ }
+ }
+#else
+ extern void click_cocoa_button();
+ click_cocoa_button();
+#endif
+}
+
+void tst_QFontDialog::defaultOkButton()
+{
+ bool ok = FALSE;
+ QTimer::singleShot(2000, this, SLOT(postKeyReturn()));
+ QFontDialog::getFont(&ok);
+ QVERIFY(ok == TRUE);
+}
+
+
+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
+ */
+ 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());
+}
+
+
+class FriendlyFontDialog : public QFontDialog
+{
+ friend class tst_QFontDialog;
+ Q_DECLARE_PRIVATE(QFontDialog);
+};
+
+void tst_QFontDialog::task256466_wrongStyle()
+{
+ QFontDatabase fdb;
+ FriendlyFontDialog dialog;
+ 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);
+ const QFont current = dialog.currentFont(),
+ expected = fdb.font(currentFamily.data().toString(),
+ styleList->currentIndex().data().toString(), sizeList->currentIndex().data().toInt());
+ QCOMPARE(current.family(), expected.family());
+ QCOMPARE(current.style(), expected.style());
+ QCOMPARE(current.pointSizeF(), expected.pointSizeF());
+ }
+}
+
+
+
+
+QTEST_MAIN(tst_QFontDialog)
+#include "tst_qfontdialog.moc"
diff --git a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog_mac_helpers.mm b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog_mac_helpers.mm
new file mode 100644
index 0000000000..d12f696f7e
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog_mac_helpers.mm
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qt_mac_p.h>
+#include <AppKit/AppKit.h>
+
+void click_cocoa_button()
+{
+ QMacCocoaAutoReleasePool pool;
+ NSArray *windows = [NSApp windows];
+ for (NSWindow *window in windows) {
+ // This is NOT how one should do RTTI, but since I don't want to leak the class too much...
+ if ([[window delegate] respondsToSelector:@selector(qtFont)]) {
+ NSArray *subviews = [[window contentView] subviews];
+ for (NSView *view in subviews) {
+ if ([view isKindOfClass:[NSButton class]]
+ && [[static_cast<NSButton *>(view) title] isEqualTo:@"OK"]) {
+ [static_cast<NSButton *>(view) performClick:view];
+ [NSApp postEvent:[NSEvent otherEventWithType:NSApplicationDefined location:NSZeroPoint
+ modifierFlags:0 timestamp:0. windowNumber:0 context:0
+ subtype:SHRT_MAX data1:0 data2:0] atStart:NO];
+
+ break;
+ }
+ }
+ break;
+ }
+ }
+}
diff --git a/tests/auto/widgets/dialogs/qinputdialog/.gitignore b/tests/auto/widgets/dialogs/qinputdialog/.gitignore
new file mode 100644
index 0000000000..b62797193c
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qinputdialog/.gitignore
@@ -0,0 +1 @@
+tst_qinputdialog
diff --git a/tests/auto/widgets/dialogs/qinputdialog/qinputdialog.pro b/tests/auto/widgets/dialogs/qinputdialog/qinputdialog.pro
new file mode 100644
index 0000000000..f7e56bd783
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qinputdialog/qinputdialog.pro
@@ -0,0 +1,5 @@
+load(qttest_p4)
+QT += widgets
+SOURCES += tst_qinputdialog.cpp
+
+
diff --git a/tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp b/tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp
new file mode 100644
index 0000000000..5c74ab217b
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp
@@ -0,0 +1,430 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QString>
+#include <QSpinBox>
+#include <QPushButton>
+#include <QLineEdit>
+#include <QComboBox>
+#include <QDialogButtonBox>
+#include <qinputdialog.h>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QInputDialog : public QObject
+{
+ Q_OBJECT
+ QWidget *parent;
+ QDialog::DialogCode doneCode;
+ void (*testFunc)(QInputDialog *);
+ static void testFuncGetInteger(QInputDialog *dialog);
+ static void testFuncGetDouble(QInputDialog *dialog);
+ static void testFuncGetText(QInputDialog *dialog);
+ static void testFuncGetItem(QInputDialog *dialog);
+ void timerEvent(QTimerEvent *event);
+private slots:
+ void getInteger_data();
+ void getInteger();
+ void getDouble_data();
+ void getDouble();
+ void task255502getDouble();
+ void getText_data();
+ void getText();
+ void getItem_data();
+ void getItem();
+ void task256299_getTextReturnNullStringOnRejected();
+ void inputMethodHintsOfChildWidget();
+};
+
+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.toAscii()); // ### 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.toAscii()); // ### 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 = qFindChild<SpinBoxType *>(dialog);
+ QVERIFY(sbox != 0);
+
+ QLineEdit *ledit = qFindChild<QLineEdit *>(static_cast<QObject *>(sbox));
+ QVERIFY(ledit != 0);
+
+ QDialogButtonBox *bbox = qFindChild<QDialogButtonBox *>(dialog);
+ 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("%1").arg(sbox->minimum()));
+ testTypingValue<SpinBoxType>(sbox, okButton, QString("%1").arg(sbox->maximum()));
+ testTypingValue<SpinBoxType>(sbox, okButton, QString("%1").arg(sbox->minimum() - 1));
+ testTypingValue<SpinBoxType>(sbox, okButton, QString("%1").arg(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 = qFindChild<QLineEdit *>(dialog);
+ QVERIFY(ledit);
+
+ QDialogButtonBox *bbox = qFindChild<QDialogButtonBox *>(dialog);
+ 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 = qFindChild<QComboBox *>(dialog);
+ QVERIFY(cbox);
+
+ QDialogButtonBox *bbox = qFindChild<QDialogButtonBox *>(dialog);
+ 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::testFuncGetInteger(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 = qFindChild<QInputDialog *>(parent);
+ QVERIFY(dialog);
+ if (testFunc)
+ testFunc(dialog);
+ dialog->done(doneCode); // cause static function call to return
+}
+
+void tst_QInputDialog::getInteger_data()
+{
+ QTest::addColumn<int>("min");
+ QTest::addColumn<int>("max");
+ QTest::newRow("getInteger() - -") << -20 << -10;
+ QTest::newRow("getInteger() - 0") << -20 << 0;
+ QTest::newRow("getInteger() - +") << -20 << 20;
+ QTest::newRow("getInteger() 0 +") << 0 << 20;
+ QTest::newRow("getInteger() + +") << 10 << 20;
+}
+
+void tst_QInputDialog::getInteger()
+{
+ QFETCH(int, min);
+ QFETCH(int, max);
+ QVERIFY(min < max);
+ parent = new QWidget;
+ doneCode = QDialog::Accepted;
+ testFunc = &tst_QInputDialog::testFuncGetInteger;
+ startTimer(0);
+ bool ok = false;
+ const int value = min + (max - min) / 2;
+ const int result = QInputDialog::getInteger(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);
+ 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);
+ QVERIFY(ok);
+ QCOMPARE(result, value);
+ delete parent;
+}
+
+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);
+ 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);
+}
+
+QTEST_MAIN(tst_QInputDialog)
+#include "tst_qinputdialog.moc"
diff --git a/tests/auto/widgets/dialogs/qmessagebox/.gitignore b/tests/auto/widgets/dialogs/qmessagebox/.gitignore
new file mode 100644
index 0000000000..19a0a35121
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qmessagebox/.gitignore
@@ -0,0 +1 @@
+tst_qmessagebox
diff --git a/tests/auto/widgets/dialogs/qmessagebox/qmessagebox.pro b/tests/auto/widgets/dialogs/qmessagebox/qmessagebox.pro
new file mode 100644
index 0000000000..e3f6ddb1f6
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qmessagebox/qmessagebox.pro
@@ -0,0 +1,9 @@
+load(qttest_p4)
+TEMPLATE = app
+TARGET = tst_qmessagebox
+QT += widgets
+DEPENDPATH += .
+INCLUDEPATH += .
+
+# Input
+SOURCES += tst_qmessagebox.cpp
diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp
new file mode 100644
index 0000000000..a07d7cf7a9
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp
@@ -0,0 +1,674 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtTest/QtTest>
+#include <QMessageBox>
+#include <QDebug>
+#include <QPair>
+#include <QList>
+#include <QPointer>
+#include <QTimer>
+#include <QApplication>
+#include <QPushButton>
+#include <QDialogButtonBox>
+#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
+#include <QMacStyle>
+#endif
+#if !defined(QT_NO_STYLE_CLEANLOOKS)
+#include <QCleanlooksStyle>
+#endif
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+#define CONVENIENCE_FUNC_SYMS(func) \
+ { \
+ int x1 = QMessageBox::func(0, "Foo", "Bar"); \
+ int x3 = QMessageBox::func(0, "Foo", "Bar", "Save"); \
+ int x6 = QMessageBox::func(0, "Foo", "Bar", "Save", "Save As"); \
+ int x7 = QMessageBox::func(0, "Foo", "Bar", "Save", "Save As", "Dont Save"); \
+ int x8 = QMessageBox::func(0, "Foo", "Bar", "Save", "Save As", "Dont Save", 1); \
+ int x9 = QMessageBox::func(0, "Foo", "Bar", "Save", "Save As", "Dont Save", 1, 2); \
+ int x10 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::YesAll, QMessageBox::Yes); \
+ int x11 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::YesAll, QMessageBox::Yes, \
+ QMessageBox::No); \
+ qDebug("%d %d %d %d %d %d %d %d", x1, x3, x6, x7, x8, x9, x10, x11); \
+ { \
+ int x4 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, (int)QMessageBox::No); \
+ int x5 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, (int)QMessageBox::No); \
+ int x6 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, (int)QMessageBox::No); \
+ int x7 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, QMessageBox::No); \
+ int x8 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, QMessageBox::No); \
+ int x9 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No); \
+ int x10 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, (int)QMessageBox::No, (int)QMessageBox::Ok); \
+ int x11 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, (int)QMessageBox::No, (int)QMessageBox::Ok); \
+ int x12 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, (int)QMessageBox::No, (int)QMessageBox::Ok); \
+ int x13 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, QMessageBox::No, (int)QMessageBox::Ok); \
+ int x14 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, QMessageBox::No, (int)QMessageBox::Ok); \
+ int x15 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, (int)QMessageBox::Ok); \
+ int x16 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, (int)QMessageBox::No, QMessageBox::Ok); \
+ int x17 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, (int)QMessageBox::No, QMessageBox::Ok); \
+ int x18 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, (int)QMessageBox::No, QMessageBox::Ok); \
+ int x19 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, QMessageBox::No, QMessageBox::Ok); \
+ int x20 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, QMessageBox::No, QMessageBox::Ok); \
+ int x21 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Ok); \
+ qDebug("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21); \
+ } \
+ }
+
+#define CONVENIENCE_FUNC_SYMS_EXTRA(func) \
+ { \
+ int x1 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes); \
+ int x2 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes); \
+ int x3 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default); \
+ qDebug("%d %d %d", x1, x2, x3); \
+ }
+
+class tst_QMessageBox : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QMessageBox();
+ int exec(QMessageBox *msgBox, int key = -1);
+ void sendKeySoon();
+
+public slots:
+ void sendKey();
+
+private slots:
+ void sanityTest();
+ void defaultButton();
+ void escapeButton();
+ void button();
+ void statics();
+ void about();
+ void detailsText();
+ void detailsButtonText();
+
+#ifndef Q_WS_MAC
+ void shortcut();
+#endif
+
+ void staticSourceCompat();
+ void instanceSourceCompat();
+
+ void testSymbols();
+ void incorrectDefaultButton();
+ void updateSize();
+
+ void setInformativeText();
+ void iconPixmap();
+
+ void init();
+ void initTestCase();
+
+private:
+ int keyToSend;
+ QTimer keySendTimer;
+};
+
+tst_QMessageBox::tst_QMessageBox() : keyToSend(-1)
+{
+ int argc = qApp->argc();
+ QT_REQUIRE_VERSION(argc, qApp->argv(), "4.6.2")
+}
+
+int tst_QMessageBox::exec(QMessageBox *msgBox, int key)
+{
+ if (key == -1) {
+ QTimer::singleShot(1000, msgBox, SLOT(close()));
+ } else {
+ keyToSend = key;
+ sendKeySoon();
+ }
+ return msgBox->exec();
+}
+
+void tst_QMessageBox::sendKey()
+{
+ if (keyToSend == -2) {
+ QApplication::activeModalWidget()->close();
+ keyToSend = -1;
+ return;
+ }
+ if (keyToSend == -1)
+ return;
+ QKeyEvent *ke = new QKeyEvent(QEvent::KeyPress, keyToSend, Qt::NoModifier);
+ qApp->postEvent(QApplication::activeModalWidget(), ke);
+ keyToSend = -1;
+}
+
+void tst_QMessageBox::sendKeySoon()
+{
+ keySendTimer.start();
+}
+
+void tst_QMessageBox::init()
+{
+ // if there is any pending key send from the last test, cancel it.
+ keySendTimer.stop();
+}
+
+void tst_QMessageBox::initTestCase()
+{
+ keySendTimer.setInterval(1000);
+ keySendTimer.setSingleShot(true);
+ QVERIFY(QObject::connect(&keySendTimer, SIGNAL(timeout()), this, SLOT(sendKey())));
+}
+
+void tst_QMessageBox::sanityTest()
+{
+ 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);
+ exec(&msgBox);
+}
+
+void tst_QMessageBox::button()
+{
+ QMessageBox msgBox;
+ msgBox.addButton("retry", QMessageBox::DestructiveRole);
+ QVERIFY(msgBox.button(QMessageBox::Ok) == 0); // not added yet
+ QPushButton *b1 = msgBox.addButton(QMessageBox::Ok);
+ QCOMPARE(msgBox.button(QMessageBox::Ok), (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) == 0);
+ QVERIFY(msgBox.button(QMessageBox::Yes) != 0);
+
+ // should not crash
+ QPushButton *b4 = new QPushButton;
+ msgBox.addButton(b4, QMessageBox::DestructiveRole);
+ msgBox.addButton(0, QMessageBox::ActionRole);
+}
+
+void tst_QMessageBox::defaultButton()
+{
+ QMessageBox msgBox;
+ QVERIFY(msgBox.defaultButton() == 0);
+ msgBox.addButton(QMessageBox::Ok);
+ msgBox.addButton(QMessageBox::Cancel);
+ QVERIFY(msgBox.defaultButton() == 0);
+ QPushButton pushButton;
+ msgBox.setDefaultButton(&pushButton);
+ QVERIFY(msgBox.defaultButton() == 0); // we have not added it yet
+ QPushButton *retryButton = msgBox.addButton(QMessageBox::Retry);
+ msgBox.setDefaultButton(retryButton);
+ QCOMPARE(msgBox.defaultButton(), retryButton);
+ exec(&msgBox);
+ QCOMPARE(msgBox.clickedButton(), msgBox.button(QMessageBox::Cancel));
+
+ exec(&msgBox, Qt::Key_Enter);
+ QCOMPARE(msgBox.clickedButton(), (QAbstractButton *)retryButton);
+
+ QAbstractButton *okButton = msgBox.button(QMessageBox::Ok);
+ msgBox.setDefaultButton(QMessageBox::Ok);
+ QCOMPARE(msgBox.defaultButton(), (QPushButton *)okButton);
+ exec(&msgBox, Qt::Key_Enter);
+ QCOMPARE(msgBox.clickedButton(), okButton);
+ msgBox.setDefaultButton(QMessageBox::Yes); // its not in there!
+ QVERIFY(msgBox.defaultButton() == okButton);
+ msgBox.removeButton(okButton);
+ delete okButton;
+ okButton = 0;
+ QVERIFY(msgBox.defaultButton() == 0);
+ msgBox.setDefaultButton(QMessageBox::Ok);
+ QVERIFY(msgBox.defaultButton() == 0);
+}
+
+void tst_QMessageBox::escapeButton()
+{
+ QMessageBox msgBox;
+ QVERIFY(msgBox.escapeButton() == 0);
+ msgBox.addButton(QMessageBox::Ok);
+ exec(&msgBox);
+ QVERIFY(msgBox.clickedButton() == msgBox.button(QMessageBox::Ok)); // auto detected (one button only)
+ msgBox.addButton(QMessageBox::Cancel);
+ QVERIFY(msgBox.escapeButton() == 0);
+ QPushButton invalidButton;
+ msgBox.setEscapeButton(&invalidButton);
+ QVERIFY(msgBox.escapeButton() == 0);
+ QAbstractButton *retryButton = msgBox.addButton(QMessageBox::Retry);
+
+ exec(&msgBox);
+ QVERIFY(msgBox.clickedButton() == msgBox.button(QMessageBox::Cancel)); // auto detected (cancel)
+
+ msgBox.setEscapeButton(retryButton);
+ QCOMPARE(msgBox.escapeButton(), (QAbstractButton *)retryButton);
+
+ // with escape
+ exec(&msgBox, Qt::Key_Escape);
+ QCOMPARE(msgBox.clickedButton(), retryButton);
+
+ // with close
+ exec(&msgBox);
+ QCOMPARE(msgBox.clickedButton(), (QAbstractButton *)retryButton);
+
+ QAbstractButton *okButton = msgBox.button(QMessageBox::Ok);
+ msgBox.setEscapeButton(QMessageBox::Ok);
+ QCOMPARE(msgBox.escapeButton(), okButton);
+ exec(&msgBox, Qt::Key_Escape);
+ QCOMPARE(msgBox.clickedButton(), okButton);
+ msgBox.setEscapeButton(QMessageBox::Yes); // its not in there!
+ QVERIFY(msgBox.escapeButton() == okButton);
+ msgBox.removeButton(okButton);
+ delete okButton;
+ okButton = 0;
+ QVERIFY(msgBox.escapeButton() == 0);
+ msgBox.setEscapeButton(QMessageBox::Ok);
+ QVERIFY(msgBox.escapeButton() == 0);
+
+ QMessageBox msgBox2;
+ msgBox2.addButton(QMessageBox::Yes);
+ msgBox2.addButton(QMessageBox::No);
+ exec(&msgBox2);
+ QVERIFY(msgBox2.clickedButton() == msgBox2.button(QMessageBox::No)); // auto detected (one No button only)
+
+ QPushButton *rejectButton = new QPushButton;
+ msgBox2.addButton(rejectButton, QMessageBox::RejectRole);
+ exec(&msgBox2);
+ QVERIFY(msgBox2.clickedButton() == rejectButton); // auto detected (one reject button only)
+
+ msgBox2.addButton(new QPushButton, QMessageBox::RejectRole);
+ exec(&msgBox2);
+ QVERIFY(msgBox2.clickedButton() == msgBox2.button(QMessageBox::No)); // auto detected (one No button only)
+}
+
+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;
+
+ for (int i = 0; i < 4; i++) {
+ keyToSend = Qt::Key_Escape;
+ sendKeySoon();
+ QMessageBox::StandardButton sb = (*statics[i])(0, "caption",
+ "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help | QMessageBox::Cancel,
+ QMessageBox::NoButton);
+ QCOMPARE(sb, QMessageBox::Cancel);
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = -2; // close()
+ sendKeySoon();
+ sb = (*statics[i])(0, "caption",
+ "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help | QMessageBox::Cancel,
+ QMessageBox::NoButton);
+ QCOMPARE(sb, QMessageBox::Cancel);
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Enter;
+ sendKeySoon();
+ sb = (*statics[i])(0, "caption",
+ "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help,
+ QMessageBox::Yes);
+ QCOMPARE(sb, QMessageBox::Yes);
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Enter;
+ sendKeySoon();
+ sb = (*statics[i])(0, "caption",
+ "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help,
+ QMessageBox::No);
+ QCOMPARE(sb, QMessageBox::No);
+ QCOMPARE(keyToSend, -1);
+ }
+}
+
+// Shortcuts are not used on Mac OS X.
+#ifndef Q_WS_MAC
+void tst_QMessageBox::shortcut()
+{
+ QMessageBox msgBox;
+ msgBox.addButton("O&k", QMessageBox::YesRole);
+ msgBox.addButton("&No", QMessageBox::YesRole);
+ msgBox.addButton("&Maybe", QMessageBox::YesRole);
+ QCOMPARE(exec(&msgBox, Qt::Key_M), 2);
+}
+#endif
+
+void tst_QMessageBox::about()
+{
+ keyToSend = Qt::Key_Escape;
+ sendKeySoon();
+ QMessageBox::about(0, "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_WS_MAC
+ QTRY_COMPARE(keyToSend, -1);
+#else
+ QCOMPARE(keyToSend, -1);
+#endif
+
+#if !defined(Q_OS_WINCE)
+ keyToSend = Qt::Key_Enter;
+#else
+ keyToSend = Qt::Key_Escape;
+#endif
+ sendKeySoon();
+ QMessageBox::aboutQt(0, "Caption");
+#ifdef Q_WS_MAC
+ QTRY_COMPARE(keyToSend, -1);
+#else
+ QCOMPARE(keyToSend, -1);
+#endif
+}
+
+void tst_QMessageBox::staticSourceCompat()
+{
+ int ret;
+
+ // source compat tests for < 4.2
+ keyToSend = Qt::Key_Enter;
+ sendKeySoon();
+ ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes, QMessageBox::No);
+ int expectedButton = int(QMessageBox::Yes);
+#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
+ if (qobject_cast<QMacStyle *>(qApp->style()))
+ expectedButton = int(QMessageBox::No);
+#elif !defined(QT_NO_STYLE_CLEANLOOKS)
+ if (qobject_cast<QCleanlooksStyle *>(qApp->style()))
+ expectedButton = int(QMessageBox::No);
+#endif
+ QCOMPARE(ret, expectedButton);
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Enter;
+ sendKeySoon();
+ ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No);
+ QCOMPARE(ret, int(QMessageBox::Yes));
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Enter;
+ sendKeySoon();
+ ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes, QMessageBox::No | QMessageBox::Default);
+ QCOMPARE(ret, int(QMessageBox::No));
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Enter;
+ sendKeySoon();
+ ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape);
+ QCOMPARE(ret, int(QMessageBox::Yes));
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Enter;
+ sendKeySoon();
+ ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes | QMessageBox::Escape, QMessageBox::No | QMessageBox::Default);
+ QCOMPARE(ret, int(QMessageBox::No));
+ QCOMPARE(keyToSend, -1);
+
+ // the button text versions
+ keyToSend = Qt::Key_Enter;
+ sendKeySoon();
+ ret = QMessageBox::information(0, "title", "text", "Yes", "No", QString(), 1);
+ QCOMPARE(ret, 1);
+ QCOMPARE(keyToSend, -1);
+
+ if (0) { // dont run these tests since the dialog wont close!
+ keyToSend = Qt::Key_Escape;
+ sendKeySoon();
+ ret = QMessageBox::information(0, "title", "text", "Yes", "No", QString(), 1);
+ QCOMPARE(ret, -1);
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Escape;
+ sendKeySoon();
+ ret = QMessageBox::information(0, "title", "text", "Yes", "No", QString(), 0, 1);
+ QCOMPARE(ret, 1);
+ QCOMPARE(keyToSend, -1);
+ }
+}
+
+void tst_QMessageBox::instanceSourceCompat()
+{
+ QMessageBox mb("Application name here",
+ "Saving the file will overwrite the original file on the disk.\n"
+ "Do you really want to save?",
+ QMessageBox::Information,
+ QMessageBox::Yes | QMessageBox::Default,
+ QMessageBox::No,
+ QMessageBox::Cancel | QMessageBox::Escape);
+ mb.setButtonText(QMessageBox::Yes, "Save");
+ mb.setButtonText(QMessageBox::No, "Discard");
+ mb.addButton("&Revert", QMessageBox::RejectRole);
+ mb.addButton("&Zoo", QMessageBox::ActionRole);
+
+ QCOMPARE(exec(&mb, Qt::Key_Enter), int(QMessageBox::Yes));
+ QCOMPARE(exec(&mb, Qt::Key_Escape), int(QMessageBox::Cancel));
+#ifndef Q_WS_MAC
+ // mnemonics are not used on Mac OS X
+ QCOMPARE(exec(&mb, Qt::ALT + Qt::Key_R), 0);
+ QCOMPARE(exec(&mb, Qt::ALT + Qt::Key_Z), 1);
+#endif
+}
+
+void tst_QMessageBox::testSymbols()
+{
+ return;
+
+ QMessageBox::Icon icon;
+ icon = QMessageBox::NoIcon;
+ icon = QMessageBox::Information;
+ icon = QMessageBox::Warning;
+ icon = QMessageBox::Critical;
+ icon = QMessageBox::Question;
+
+ QMessageBox mb1;
+ QMessageBox mb2(0);
+ QMessageBox mb3(&mb1);
+ QMessageBox mb3b("title", "text", QMessageBox::Critical, int(QMessageBox::Yes),
+ int(QMessageBox::No), int(QMessageBox::Cancel), &mb1, Qt::Dialog);
+
+ QMessageBox::Button button = QMessageBox::NoButton;
+ button = QMessageBox::Ok;
+ button = QMessageBox::Cancel;
+ button = QMessageBox::Yes;
+ button = QMessageBox::No;
+ button = QMessageBox::Abort;
+ button = QMessageBox::Retry;
+ button = QMessageBox::Ignore;
+ button = QMessageBox::YesAll;
+ button = QMessageBox::NoAll;
+ button = QMessageBox::ButtonMask;
+ button = QMessageBox::Default;
+ button = QMessageBox::Escape;
+ button = QMessageBox::FlagMask;
+
+ const QString text = QStringLiteral("Foo");
+ mb1.setText(text);
+ QCOMPARE(mb1.text(), text);
+
+ icon = mb1.icon();
+ QVERIFY(icon == QMessageBox::NoIcon);
+ mb1.setIcon(QMessageBox::Question);
+ QVERIFY(mb1.icon() == QMessageBox::Question);
+
+ QPixmap iconPixmap = mb1.iconPixmap();
+ mb1.setIconPixmap(iconPixmap);
+ QVERIFY(mb1.icon() == QMessageBox::NoIcon);
+
+ QCOMPARE(mb1.buttonText(QMessageBox::Ok), QLatin1String("OK"));
+ QCOMPARE(mb1.buttonText(QMessageBox::Cancel), QString());
+ QCOMPARE(mb1.buttonText(QMessageBox::Ok | QMessageBox::Default), QString());
+
+ const QString button1 = QStringLiteral("Bar");
+ mb2.setButtonText(QMessageBox::Cancel, QStringLiteral("Foo"));
+ mb2.setButtonText(QMessageBox::Ok, button1);
+ mb2.setButtonText(QMessageBox::Ok | QMessageBox::Default, QStringLiteral("Baz"));
+
+ QCOMPARE(mb2.buttonText(QMessageBox::Cancel), QString());
+ QCOMPARE(mb2.buttonText(QMessageBox::Ok), button1);
+
+ QVERIFY(mb3b.buttonText(QMessageBox::Yes).endsWith("Yes"));
+ QCOMPARE(mb3b.buttonText(QMessageBox::YesAll), QString());
+ QCOMPARE(mb3b.buttonText(QMessageBox::Ok), QString());
+
+ const QString button2 = QStringLiteral("Blah");
+ mb3b.setButtonText(QMessageBox::Yes, button2);
+ mb3b.setButtonText(QMessageBox::YesAll, QStringLiteral("Zoo"));
+ mb3b.setButtonText(QMessageBox::Ok, QStringLiteral("Zoo"));
+
+ QCOMPARE(mb3b.buttonText(QMessageBox::Yes), button2);
+ QCOMPARE(mb3b.buttonText(QMessageBox::YesAll), QString());
+ QCOMPARE(mb3b.buttonText(QMessageBox::Ok), QString());
+
+ QCOMPARE(mb1.textFormat(), Qt::AutoText);
+ mb1.setTextFormat(Qt::PlainText);
+ QCOMPARE(mb1.textFormat(), Qt::PlainText);
+
+ CONVENIENCE_FUNC_SYMS(information);
+ CONVENIENCE_FUNC_SYMS_EXTRA(information);
+ CONVENIENCE_FUNC_SYMS(question);
+ CONVENIENCE_FUNC_SYMS_EXTRA(question);
+ CONVENIENCE_FUNC_SYMS(warning);
+ CONVENIENCE_FUNC_SYMS(critical);
+
+ QSize sizeHint = mb1.sizeHint();
+ QVERIFY(sizeHint.width() > 20 && sizeHint.height() > 20);
+
+ QMessageBox::about(&mb1, "title", "text");
+ QMessageBox::aboutQt(&mb1);
+ QMessageBox::aboutQt(&mb1, "title");
+}
+
+void tst_QMessageBox::detailsText()
+{
+ QMessageBox box;
+ QString text("This is the details text.");
+ box.setDetailedText(text);
+ QCOMPARE(box.detailedText(), text);
+}
+
+void tst_QMessageBox::detailsButtonText()
+{
+ 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
+
+ QList<QAbstractButton *> list = bb->buttons();
+ QAbstractButton* btn = NULL;
+ foreach(btn, list) {
+ if (btn && (btn->inherits("QPushButton"))) {
+ if (btn->text() != QMessageBox::tr("OK") && btn->text() != QMessageBox::tr("Show Details...")) {
+ QFAIL(qPrintable(QString("Unexpected messagebox button text: %1").arg(btn->text())));
+ }
+ }
+ }
+}
+
+void tst_QMessageBox::incorrectDefaultButton()
+{
+ keyToSend = Qt::Key_Escape;
+ sendKeySoon();
+ //Do not crash here
+ QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
+ QMessageBox::question( 0, "", "I've been hit!",QMessageBox::Ok | QMessageBox::Cancel,QMessageBox::Save );
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Escape;
+ sendKeySoon();
+ QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
+ QMessageBox::question( 0, "", "I've been hit!",QFlag(QMessageBox::Ok | QMessageBox::Cancel),QMessageBox::Save );
+ QCOMPARE(keyToSend, -1);
+
+ keyToSend = Qt::Key_Escape;
+ sendKeySoon();
+ QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
+ QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
+ //do not crash here -> call old function of QMessageBox in this case
+ QMessageBox::question( 0, "", "I've been hit!",QMessageBox::Ok | QMessageBox::Cancel,QMessageBox::Save | QMessageBox::Cancel,QMessageBox::Ok);
+ QCOMPARE(keyToSend, -1);
+}
+
+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());
+}
+
+QTEST_MAIN(tst_QMessageBox)
+#include "tst_qmessagebox.moc"
diff --git a/tests/auto/widgets/dialogs/qprogressdialog/.gitignore b/tests/auto/widgets/dialogs/qprogressdialog/.gitignore
new file mode 100644
index 0000000000..ce3cd0d7dd
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qprogressdialog/.gitignore
@@ -0,0 +1 @@
+tst_qprogressdialog
diff --git a/tests/auto/widgets/dialogs/qprogressdialog/qprogressdialog.pro b/tests/auto/widgets/dialogs/qprogressdialog/qprogressdialog.pro
new file mode 100644
index 0000000000..f3861e4cd3
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qprogressdialog/qprogressdialog.pro
@@ -0,0 +1,9 @@
+############################################################
+# Project file for autotest for file qprogressdialog.h
+############################################################
+
+load(qttest_p4)
+QT += widgets
+SOURCES += tst_qprogressdialog.cpp
+
+
diff --git a/tests/auto/widgets/dialogs/qprogressdialog/tst_qprogressdialog.cpp b/tests/auto/widgets/dialogs/qprogressdialog/tst_qprogressdialog.cpp
new file mode 100644
index 0000000000..5fbd5d747a
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qprogressdialog/tst_qprogressdialog.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <qcoreapplication.h>
+#include <qdebug.h>
+#include <qprogressdialog.h>
+#include <qlabel.h>
+
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QProgressDialog : public QObject
+{
+Q_OBJECT
+
+public:
+ tst_QProgressDialog();
+ virtual ~tst_QProgressDialog();
+
+private slots:
+ void getSetCheck();
+ void task198202();
+};
+
+tst_QProgressDialog::tst_QProgressDialog()
+{
+}
+
+tst_QProgressDialog::~tst_QProgressDialog()
+{
+}
+
+// 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();
+ QTest::qWait(20);
+ int futureHeight = dlg.sizeHint().height() - qFindChild<QLabel*>(&dlg)->sizeHint().height();
+ dlg.setLabel(0);
+ QTest::ignoreMessage(QtWarningMsg, "QProgressDialog::setBar: Cannot set a null progress bar");
+ dlg.setBar(0);
+ QTest::qWait(20);
+ QCOMPARE(dlg.sizeHint().height(), futureHeight);
+}
+
+QTEST_MAIN(tst_QProgressDialog)
+#include "tst_qprogressdialog.moc"
diff --git a/tests/auto/widgets/dialogs/qsidebar/.gitignore b/tests/auto/widgets/dialogs/qsidebar/.gitignore
new file mode 100644
index 0000000000..194ca9f244
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qsidebar/.gitignore
@@ -0,0 +1 @@
+tst_qsidebar
diff --git a/tests/auto/widgets/dialogs/qsidebar/qsidebar.pro b/tests/auto/widgets/dialogs/qsidebar/qsidebar.pro
new file mode 100644
index 0000000000..9f6e094784
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qsidebar/qsidebar.pro
@@ -0,0 +1,6 @@
+CONFIG += qttest_p4
+
+QT += core-private
+QT += widgets widgets-private
+SOURCES += tst_qsidebar.cpp
+TARGET = tst_qsidebar
diff --git a/tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp b/tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp
new file mode 100644
index 0000000000..912719f76a
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qsidebar/tst_qsidebar.cpp
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include "../../../src/widgets/dialogs/qsidebar_p.h"
+#include "../../../src/widgets/dialogs/qfilesystemmodel_p.h"
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QSidebar : public QObject {
+ Q_OBJECT
+
+public:
+ tst_QSidebar();
+ virtual ~tst_QSidebar();
+
+public Q_SLOTS:
+ void init();
+ void cleanup();
+
+private slots:
+ void setUrls();
+ void selectUrls();
+ void addUrls();
+
+ void goToUrl();
+};
+
+tst_QSidebar::tst_QSidebar()
+{
+}
+
+tst_QSidebar::~tst_QSidebar()
+{
+}
+
+void tst_QSidebar::init()
+{
+}
+
+void tst_QSidebar::cleanup()
+{
+}
+
+void tst_QSidebar::setUrls()
+{
+ QList<QUrl> urls;
+ QFileSystemModel fsmodel;
+ QSidebar qsidebar;
+ qsidebar.init(&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.count());
+ qsidebar.setUrls(urls);
+ QCOMPARE(model->rowCount(), urls.count());
+}
+
+void tst_QSidebar::selectUrls()
+{
+ QList<QUrl> urls;
+ urls << QUrl::fromLocalFile(QDir::rootPath())
+ << QUrl::fromLocalFile(QDir::temp().absolutePath());
+ QFileSystemModel fsmodel;
+ QSidebar qsidebar;
+ qsidebar.init(&fsmodel, urls);
+
+ QSignalSpy spy(&qsidebar, SIGNAL(goToUrl(const QUrl &)));
+ qsidebar.selectUrl(urls.at(0));
+ QCOMPARE(spy.count(), 0);
+}
+
+void tst_QSidebar::addUrls()
+{
+ QList<QUrl> emptyUrls;
+ QFileSystemModel fsmodel;
+ QSidebar qsidebar;
+ qsidebar.init(&fsmodel, emptyUrls);
+ QAbstractItemModel *model = qsidebar.model();
+ QDir testDir = QDir::home();
+
+ // 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);
+
+#if defined(Q_OS_WIN)
+ //Windows is case insensitive so no duplicate entries in that case
+ doubleUrls << QUrl::fromLocalFile(testDir.absolutePath());
+ doubleUrls << QUrl::fromLocalFile(testDir.absolutePath().toUpper());
+ qsidebar.setUrls(emptyUrls);
+ qsidebar.addUrls(doubleUrls, 1);
+ QCOMPARE(qsidebar.urls().size(), 1);
+#else
+ //Two different paths we should have two entries
+ doubleUrls << QUrl::fromLocalFile(testDir.absolutePath());
+ doubleUrls << QUrl::fromLocalFile(testDir.absolutePath().toUpper());
+ qsidebar.setUrls(emptyUrls);
+ qsidebar.addUrls(doubleUrls, 1);
+ 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;
+ QSidebar qsidebar;
+ qsidebar.init(&fsmodel, urls);
+ qsidebar.show();
+
+ QSignalSpy spy(&qsidebar, SIGNAL(goToUrl(const QUrl &)));
+ QTest::mousePress(qsidebar.viewport(), Qt::LeftButton, 0, qsidebar.visualRect(qsidebar.model()->index(0, 0)).center());
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE((spy.value(0)).at(0).toUrl(), urls.first());
+}
+
+QTEST_MAIN(tst_QSidebar)
+#include "tst_qsidebar.moc"
+
diff --git a/tests/auto/widgets/dialogs/qwizard/.gitignore b/tests/auto/widgets/dialogs/qwizard/.gitignore
new file mode 100644
index 0000000000..9494c96da2
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qwizard/.gitignore
@@ -0,0 +1 @@
+tst_qwizard
diff --git a/tests/auto/widgets/dialogs/qwizard/images/background.png b/tests/auto/widgets/dialogs/qwizard/images/background.png
new file mode 100644
index 0000000000..db7d67dc3d
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qwizard/images/background.png
Binary files differ
diff --git a/tests/auto/widgets/dialogs/qwizard/images/banner.png b/tests/auto/widgets/dialogs/qwizard/images/banner.png
new file mode 100644
index 0000000000..be36202d99
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qwizard/images/banner.png
Binary files differ
diff --git a/tests/auto/widgets/dialogs/qwizard/images/logo.png b/tests/auto/widgets/dialogs/qwizard/images/logo.png
new file mode 100644
index 0000000000..9cf3350c4b
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qwizard/images/logo.png
Binary files differ
diff --git a/tests/auto/widgets/dialogs/qwizard/images/watermark.png b/tests/auto/widgets/dialogs/qwizard/images/watermark.png
new file mode 100644
index 0000000000..9305675549
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qwizard/images/watermark.png
Binary files differ
diff --git a/tests/auto/widgets/dialogs/qwizard/qwizard.pro b/tests/auto/widgets/dialogs/qwizard/qwizard.pro
new file mode 100644
index 0000000000..c27801b82f
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qwizard/qwizard.pro
@@ -0,0 +1,4 @@
+load(qttest_p4)
+QT += widgets
+SOURCES += tst_qwizard.cpp
+RESOURCES = qwizard.qrc
diff --git a/tests/auto/widgets/dialogs/qwizard/qwizard.qrc b/tests/auto/widgets/dialogs/qwizard/qwizard.qrc
new file mode 100644
index 0000000000..471da9def6
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qwizard/qwizard.qrc
@@ -0,0 +1,8 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>images/background.png</file>
+ <file>images/banner.png</file>
+ <file>images/logo.png</file>
+ <file>images/watermark.png</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
new file mode 100644
index 0000000000..2e05eb5bab
--- /dev/null
+++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
@@ -0,0 +1,2645 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QFont>
+#include <QtTest/QtTest>
+#include <QCheckBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QList>
+#include <QPushButton>
+#include <QToolButton>
+#include <QVBoxLayout>
+#include <QWizard>
+#include <QStyle>
+#include <QPlastiqueStyle>
+#include <QTreeWidget>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+static QImage grabWidget(QWidget *window)
+{
+ return QPixmap::grabWidget(window).toImage();
+}
+
+class tst_QWizard : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QWizard();
+
+public slots:
+ void init();
+ void cleanup();
+
+private slots:
+ void buttonText();
+ void setButtonLayout();
+ void setButton();
+ void setTitleFormatEtc();
+ void setPixmap();
+ void setDefaultProperty();
+ void addPage();
+ void setPage();
+ void setStartId();
+ void setOption_IndependentPages();
+ void setOption_IgnoreSubTitles();
+ void setOption_ExtendedWatermarkPixmap();
+ void setOption_NoDefaultButton();
+ void setOption_NoBackButtonOnStartPage();
+ void setOption_NoBackButtonOnLastPage();
+ void setOption_DisabledBackButtonOnLastPage();
+ void setOption_HaveNextButtonOnLastPage();
+ void setOption_HaveFinishButtonOnEarlyPages();
+ void setOption_NoCancelButton();
+ void setOption_CancelButtonOnLeft();
+ void setOption_HaveHelpButton();
+ void setOption_HelpButtonOnRight();
+ void setOption_HaveCustomButtonX();
+#ifndef Q_OS_WINCE
+ void combinations_data();
+ void combinations();
+#endif
+ void showCurrentPageOnly();
+ void setButtonText();
+ void setCommitPage();
+ void setWizardStyle();
+ void removePage();
+ void sideWidget();
+
+ // task-specific tests below me:
+ void task161660_buttonSpacing();
+ void task177716_disableCommitButton();
+ void task183550_stretchFactor();
+ void task161658_alignments();
+ void task177022_setFixedSize();
+ void task248107_backButton();
+ void task255350_fieldObjectDestroyed();
+
+ /*
+ Things that could be added:
+
+ 1. Test virtual functions that are called, signals that are
+ emitted, etc.
+
+ 2. Test QWizardPage more thorougly.
+
+ 3. Test the look and field a bit more (especially the
+ different wizard styles, and how they interact with
+ pixmaps, titles, subtitles, etc.).
+
+ 4. Test minimum sizes, sizes, maximum sizes, resizing, etc.
+
+ 5. Try setting various options and wizard styles in various
+ orders and check that the results are the same every time,
+ no matter the order in which the properties were set.
+
+ -> Initial version done (tst_QWizard::combinations())
+
+ 6. Test done() and restart().
+
+ 7. Test default properties of built-in widgets.
+
+ 8. Test mutual exclusiveness of Next and Commit buttons.
+ */
+};
+
+tst_QWizard::tst_QWizard()
+{
+}
+
+void tst_QWizard::init()
+{
+#ifdef Q_OS_WINCE //disable magic for WindowsCE
+ qApp->setAutoMaximizeThreshold(-1);
+#endif
+}
+
+void tst_QWizard::cleanup()
+{
+}
+
+void tst_QWizard::buttonText()
+{
+ QWizard wizard;
+ wizard.setWizardStyle(QWizard::ClassicStyle);
+
+ // Check the buttons' original text in Classic and Modern styles.
+ for (int pass = 0; pass < 2; ++pass) {
+ QCOMPARE(wizard.buttonText(QWizard::BackButton), QString("< &Back"));
+ QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next"));
+ QVERIFY(wizard.buttonText(QWizard::FinishButton).endsWith("Finish"));
+ QVERIFY(wizard.buttonText(QWizard::CancelButton).endsWith("Cancel"));
+ QVERIFY(wizard.buttonText(QWizard::HelpButton).endsWith("Help"));
+
+ QVERIFY(wizard.buttonText(QWizard::CustomButton1).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::CustomButton2).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::CustomButton3).isEmpty());
+
+ // robustness
+ QVERIFY(wizard.buttonText(QWizard::Stretch).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NoButton).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NStandardButtons).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NButtons).isEmpty());
+
+ wizard.setWizardStyle(QWizard::ModernStyle);
+ }
+
+ // Check the buttons' original text in Mac style.
+ wizard.setWizardStyle(QWizard::MacStyle);
+
+ QCOMPARE(wizard.buttonText(QWizard::BackButton), QString("Go Back"));
+ QCOMPARE(wizard.buttonText(QWizard::NextButton), QString("Continue"));
+ QCOMPARE(wizard.buttonText(QWizard::FinishButton), QString("Done"));
+ QCOMPARE(wizard.buttonText(QWizard::CancelButton), QString("Cancel"));
+ QCOMPARE(wizard.buttonText(QWizard::HelpButton), QString("Help"));
+
+ QVERIFY(wizard.buttonText(QWizard::CustomButton1).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::CustomButton2).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::CustomButton3).isEmpty());
+
+ // robustness
+ QVERIFY(wizard.buttonText(QWizard::Stretch).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NoButton).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NStandardButtons).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NButtons).isEmpty());
+
+ // Modify the buttons' text and see what happens.
+ wizard.setButtonText(QWizard::NextButton, "N&este");
+ wizard.setButtonText(QWizard::CustomButton2, "&Cucu");
+ wizard.setButtonText(QWizard::Stretch, "Stretch");
+
+ QCOMPARE(wizard.buttonText(QWizard::BackButton), QString("Go Back"));
+ QCOMPARE(wizard.buttonText(QWizard::NextButton), QString("N&este"));
+ QCOMPARE(wizard.buttonText(QWizard::FinishButton), QString("Done"));
+ QCOMPARE(wizard.buttonText(QWizard::CancelButton), QString("Cancel"));
+ QCOMPARE(wizard.buttonText(QWizard::HelpButton), QString("Help"));
+
+ QVERIFY(wizard.buttonText(QWizard::CustomButton1).isEmpty());
+ QCOMPARE(wizard.buttonText(QWizard::CustomButton2), QString("&Cucu"));
+ QVERIFY(wizard.buttonText(QWizard::CustomButton3).isEmpty());
+
+ // robustness
+ QVERIFY(wizard.buttonText(QWizard::Stretch).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NoButton).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NStandardButtons).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NButtons).isEmpty());
+
+ // Switch back to Classic style and see what happens.
+ wizard.setWizardStyle(QWizard::ClassicStyle);
+
+ for (int pass = 0; pass < 2; ++pass) {
+ QCOMPARE(wizard.buttonText(QWizard::BackButton), QString("< &Back"));
+ QCOMPARE(wizard.buttonText(QWizard::NextButton), QString("N&este"));
+ QVERIFY(wizard.buttonText(QWizard::FinishButton).endsWith("Finish"));
+ QVERIFY(wizard.buttonText(QWizard::CancelButton).endsWith("Cancel"));
+ QVERIFY(wizard.buttonText(QWizard::HelpButton).endsWith("Help"));
+
+ QVERIFY(wizard.buttonText(QWizard::CustomButton1).isEmpty());
+ QCOMPARE(wizard.buttonText(QWizard::CustomButton2), QString("&Cucu"));
+ QVERIFY(wizard.buttonText(QWizard::CustomButton3).isEmpty());
+
+ // robustness
+ QVERIFY(wizard.buttonText(QWizard::Stretch).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NoButton).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NStandardButtons).isEmpty());
+ QVERIFY(wizard.buttonText(QWizard::NButtons).isEmpty());
+
+ wizard.setOptions(QWizard::NoDefaultButton
+ | QWizard::NoBackButtonOnStartPage
+ | QWizard::NoBackButtonOnLastPage
+ | QWizard::DisabledBackButtonOnLastPage
+ | QWizard::NoCancelButton
+ | QWizard::CancelButtonOnLeft
+ | QWizard::HaveHelpButton
+ | QWizard::HelpButtonOnRight
+ | QWizard::HaveCustomButton1
+ | QWizard::HaveCustomButton2
+ | QWizard::HaveCustomButton3);
+ }
+}
+
+void tst_QWizard::setButtonLayout()
+{
+ QList<QWizard::WizardButton> layout;
+
+ QWizard wizard;
+ wizard.setWizardStyle(QWizard::ClassicStyle);
+ wizard.setOptions(0);
+ wizard.setButtonLayout(layout);
+ wizard.show();
+ qApp->processEvents();
+
+ // if these crash, this means there's a bug in QWizard
+ QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next"));
+ QVERIFY(wizard.button(QWizard::BackButton)->text().contains("Back"));
+ QVERIFY(wizard.button(QWizard::FinishButton)->text().contains("Finish"));
+ QVERIFY(wizard.button(QWizard::CancelButton)->text().contains("Cancel"));
+ QVERIFY(wizard.button(QWizard::HelpButton)->text().contains("Help"));
+ QVERIFY(wizard.button(QWizard::CustomButton1)->text().isEmpty());
+ QVERIFY(wizard.button(QWizard::CustomButton2)->text().isEmpty());
+ QVERIFY(wizard.button(QWizard::CustomButton3)->text().isEmpty());
+ QVERIFY(!wizard.button(QWizard::Stretch));
+ QVERIFY(!wizard.button(QWizard::NoButton));
+
+ QVERIFY(!wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::HelpButton)->isVisible());
+
+ layout << QWizard::NextButton << QWizard::HelpButton;
+ wizard.setButtonLayout(layout);
+ qApp->processEvents();
+
+ QVERIFY(!wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
+
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ qApp->processEvents();
+
+ QVERIFY(!wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
+
+ wizard.restart();
+ qApp->processEvents();
+
+ QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
+
+ layout.clear();
+ layout << QWizard::NextButton << QWizard::HelpButton << QWizard::BackButton
+ << QWizard::FinishButton << QWizard::CancelButton << QWizard::Stretch
+ << QWizard::CustomButton2;
+
+ // Turn on all the button-related wizard options. Some of these
+ // should have no impact on a custom layout; others should.
+ wizard.setButtonLayout(layout);
+ wizard.setOptions(QWizard::NoDefaultButton
+ | QWizard::NoBackButtonOnStartPage
+ | QWizard::NoBackButtonOnLastPage
+ | QWizard::DisabledBackButtonOnLastPage
+ | QWizard::HaveNextButtonOnLastPage
+ | QWizard::HaveFinishButtonOnEarlyPages
+ | QWizard::NoCancelButton
+ | QWizard::CancelButtonOnLeft
+ | QWizard::HaveHelpButton
+ | QWizard::HelpButtonOnRight
+ | QWizard::HaveCustomButton1
+ | QWizard::HaveCustomButton2
+ | QWizard::HaveCustomButton3);
+ qApp->processEvents();
+
+ // we're on first page
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::CancelButton)->isVisible()); // NoCancelButton overridden
+ QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::CustomButton1)->isVisible());
+ QVERIFY(wizard.button(QWizard::CustomButton2)->isVisible()); // HaveCustomButton2 overridden
+ QVERIFY(!wizard.button(QWizard::CustomButton3)->isVisible());
+
+ wizard.next();
+ qApp->processEvents();
+
+ // we're on last page
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::NextButton)->isEnabled());
+ QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::FinishButton)->isEnabled());
+ QVERIFY(wizard.button(QWizard::CancelButton)->isVisible()); // NoCancelButton overridden
+ QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::CustomButton1)->isVisible());
+ QVERIFY(wizard.button(QWizard::CustomButton2)->isVisible()); // HaveCustomButton2 overridden
+ QVERIFY(!wizard.button(QWizard::CustomButton3)->isVisible());
+
+ // Check that the buttons are in the right order on screen.
+ for (int pass = 0; pass < 2; ++pass) {
+ wizard.setLayoutDirection(pass == 0 ? Qt::LeftToRight : Qt::RightToLeft);
+ qApp->processEvents();
+
+ int sign = (pass == 0) ? +1 : -1;
+
+ int p[5];
+ p[0] = sign * wizard.button(QWizard::NextButton)->x();
+ p[1] = sign * wizard.button(QWizard::HelpButton)->x();
+ p[2] = sign * wizard.button(QWizard::FinishButton)->x();
+ p[3] = sign * wizard.button(QWizard::CancelButton)->x();
+ p[4] = sign * wizard.button(QWizard::CustomButton2)->x();
+
+ QVERIFY(p[0] < p[1]);
+ QVERIFY(p[1] < p[2]);
+ QVERIFY(p[2] < p[3]);
+ QVERIFY(p[3] < p[4]);
+ }
+
+ layout.clear();
+ wizard.setButtonLayout(layout);
+ qApp->processEvents();
+
+ for (int i = -1; i < 50; ++i) {
+ QAbstractButton *button = wizard.button(QWizard::WizardButton(i));
+ QVERIFY(!button || !button->isVisible());
+ }
+}
+
+void tst_QWizard::setButton()
+{
+ QPointer<QToolButton> toolButton = new QToolButton;
+
+ QWizard wizard;
+ wizard.setWizardStyle(QWizard::ClassicStyle);
+ wizard.setButton(QWizard::NextButton, toolButton);
+ wizard.setButton(QWizard::CustomButton2, new QCheckBox("Kustom 2"));
+
+ QVERIFY(qobject_cast<QToolButton *>(wizard.button(QWizard::NextButton)));
+ QVERIFY(qobject_cast<QCheckBox *>(wizard.button(QWizard::CustomButton2)));
+ QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::CustomButton1)));
+
+ QVERIFY(toolButton != 0);
+
+ // resetting the same button does nothing
+ wizard.setButton(QWizard::NextButton, toolButton);
+ QVERIFY(toolButton != 0);
+
+ // revert to default button
+ wizard.setButton(QWizard::NextButton, 0);
+ QVERIFY(toolButton == 0);
+ QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton)));
+ QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next"));
+}
+
+void tst_QWizard::setTitleFormatEtc()
+{
+ QWizard wizard;
+ QVERIFY(wizard.titleFormat() == Qt::AutoText);
+ QVERIFY(wizard.subTitleFormat() == Qt::AutoText);
+
+ wizard.setTitleFormat(Qt::RichText);
+ QVERIFY(wizard.titleFormat() == Qt::RichText);
+ QVERIFY(wizard.subTitleFormat() == Qt::AutoText);
+
+ wizard.setSubTitleFormat(Qt::PlainText);
+ QVERIFY(wizard.titleFormat() == Qt::RichText);
+ QVERIFY(wizard.subTitleFormat() == Qt::PlainText);
+}
+
+void tst_QWizard::setPixmap()
+{
+ QPixmap p1(1, 1);
+ QPixmap p2(2, 2);
+ QPixmap p3(3, 3);
+ QPixmap p4(4, 4);
+ QPixmap p5(5, 5);
+
+ QWizard wizard;
+ QWizardPage *page = new QWizardPage;
+ QWizardPage *page2 = new QWizardPage;
+
+ wizard.addPage(page);
+ wizard.addPage(page2);
+
+ QVERIFY(wizard.pixmap(QWizard::BannerPixmap).isNull());
+ QVERIFY(wizard.pixmap(QWizard::LogoPixmap).isNull());
+ QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).isNull());
+#ifdef Q_WS_MAC
+ if (QSysInfo::MacintoshVersion > QSysInfo::MV_10_3)
+ QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull() == false);
+ else // fall through since the image doesn't exist on a 10.3 system.
+ QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull());
+#else
+ QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull());
+#endif
+
+ QVERIFY(page->pixmap(QWizard::BannerPixmap).isNull());
+ QVERIFY(page->pixmap(QWizard::LogoPixmap).isNull());
+ QVERIFY(page->pixmap(QWizard::WatermarkPixmap).isNull());
+#ifdef Q_WS_MAC
+ if (QSysInfo::MacintoshVersion > QSysInfo::MV_10_3)
+ QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).isNull() == false);
+ else // fall through since the image doesn't exist on a 10.3 system.
+ QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull());
+#else
+ QVERIFY(page->pixmap(QWizard::BackgroundPixmap).isNull());
+#endif
+ wizard.setPixmap(QWizard::BannerPixmap, p1);
+ wizard.setPixmap(QWizard::LogoPixmap, p2);
+ wizard.setPixmap(QWizard::WatermarkPixmap, p3);
+ wizard.setPixmap(QWizard::BackgroundPixmap, p4);
+
+ page->setPixmap(QWizard::LogoPixmap, p5);
+
+ QVERIFY(wizard.pixmap(QWizard::BannerPixmap).size() == p1.size());
+ QVERIFY(wizard.pixmap(QWizard::LogoPixmap).size() == p2.size());
+ QVERIFY(wizard.pixmap(QWizard::WatermarkPixmap).size() == p3.size());
+ QVERIFY(wizard.pixmap(QWizard::BackgroundPixmap).size() == p4.size());
+
+ QVERIFY(page->pixmap(QWizard::BannerPixmap).size() == p1.size());
+ QVERIFY(page->pixmap(QWizard::LogoPixmap).size() == p5.size());
+ QVERIFY(page->pixmap(QWizard::WatermarkPixmap).size() == p3.size());
+ QVERIFY(page->pixmap(QWizard::BackgroundPixmap).size() == p4.size());
+
+ QVERIFY(page2->pixmap(QWizard::BannerPixmap).size() == p1.size());
+ QVERIFY(page2->pixmap(QWizard::LogoPixmap).size() == p2.size());
+ QVERIFY(page2->pixmap(QWizard::WatermarkPixmap).size() == p3.size());
+ QVERIFY(page2->pixmap(QWizard::BackgroundPixmap).size() == p4.size());
+}
+
+class MyPage1 : public QWizardPage
+{
+public:
+ MyPage1() {
+ edit1 = new QLineEdit("Bla 1", this);
+
+ edit2 = new QLineEdit("Bla 2", this);
+ edit2->setInputMask("Mask");
+
+ edit3 = new QLineEdit("Bla 3", this);
+ edit3->setMaxLength(25);
+
+ edit4 = new QLineEdit("Bla 4", this);
+ }
+
+ void registerField(const QString &name, QWidget *widget,
+ const char *property = 0,
+ const char *changedSignal = 0)
+ { QWizardPage::registerField(name, widget, property, changedSignal); }
+
+ QLineEdit *edit1;
+ QLineEdit *edit2;
+ QLineEdit *edit3;
+ QLineEdit *edit4;
+};
+
+void tst_QWizard::setDefaultProperty()
+{
+ QWizard wizard;
+ MyPage1 *page = new MyPage1;
+ wizard.addPage(page);
+
+ page->registerField("edit1", page->edit1);
+
+ wizard.setDefaultProperty("QLineEdit", "inputMask", 0);
+ page->registerField("edit2", page->edit2);
+
+ wizard.setDefaultProperty("QLineEdit", "maxLength", 0);
+ page->registerField("edit3", page->edit3);
+
+ wizard.setDefaultProperty("QLineEdit", "text", SIGNAL(textChanged(QString)));
+ page->registerField("edit3bis", page->edit3);
+
+ wizard.setDefaultProperty("QWidget", "enabled", 0); // less specific, i.e. ignored
+ page->registerField("edit4", page->edit4);
+ QTest::ignoreMessage(QtWarningMsg,"QWizard::setField: Couldn't write to property 'customProperty'");
+ wizard.setDefaultProperty("QLineEdit", "customProperty", 0);
+ page->registerField("edit4bis", page->edit4);
+
+ QCOMPARE(wizard.field("edit1").toString(), QString("Bla 1"));
+ QCOMPARE(wizard.field("edit2").toString(), page->edit2->inputMask());
+ QCOMPARE(wizard.field("edit3").toInt(), 25);
+ QCOMPARE(wizard.field("edit3bis").toString(), QString("Bla 3"));
+ QCOMPARE(wizard.field("edit4").toString(), QString("Bla 4"));
+ QCOMPARE(wizard.field("edit4bis").toString(), QString());
+
+ wizard.setField("edit1", "Alpha");
+ wizard.setField("edit2", "Beta");
+ wizard.setField("edit3", 50);
+ wizard.setField("edit3bis", "Gamma");
+ wizard.setField("edit4", "Delta");
+ wizard.setField("edit4bis", "Epsilon");
+
+ QCOMPARE(wizard.field("edit1").toString(), QString("Alpha"));
+ QVERIFY(wizard.field("edit2").toString().contains("Beta"));
+ QCOMPARE(wizard.field("edit3").toInt(), 50);
+ QCOMPARE(wizard.field("edit3bis").toString(), QString("Gamma"));
+ QCOMPARE(wizard.field("edit4").toString(), QString("Delta"));
+ QCOMPARE(wizard.field("edit4bis").toString(), QString("Epsilon"));
+
+ // make sure the data structure is reasonable
+ for (int i = 0; i < 200000; ++i) {
+ wizard.setDefaultProperty("QLineEdit", "x" + QByteArray::number(i), 0);
+ wizard.setDefaultProperty("QLabel", "y" + QByteArray::number(i), 0);
+ }
+}
+
+void tst_QWizard::addPage()
+{
+ QWidget *parent = new QWidget;
+ QWizard wizard;
+ const int N = 100;
+ QWizardPage *pages[N];
+ QSignalSpy spy(&wizard, SIGNAL(pageAdded(int)));
+
+ for (int i = 0; i < N; ++i) {
+ pages[i] = new QWizardPage(parent);
+ QCOMPARE(wizard.addPage(pages[i]), i);
+ QCOMPARE(pages[i]->window(), (QWidget *)&wizard);
+ QCOMPARE(wizard.startId(), 0);
+ QCOMPARE(spy.count(), 1);
+ QList<QVariant> arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), i);
+ }
+
+ for (int i = 0; i < N; ++i) {
+ QVERIFY(pages[i] == wizard.page(i));
+ }
+ QVERIFY(!wizard.page(-1));
+ QVERIFY(!wizard.page(N));
+ QVERIFY(!wizard.page(N + 1));
+
+ wizard.setPage(N + 50, new QWizardPage);
+ QCOMPARE(spy.count(), 1);
+ QList<QVariant> arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), N + 50);
+ wizard.setPage(-3000, new QWizardPage);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), -3000);
+
+ QWizardPage *pageX = new QWizardPage;
+ QCOMPARE(wizard.addPage(pageX), N + 51);
+ QCOMPARE(wizard.page(N + 51), pageX);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), N + 51);
+
+ QCOMPARE(wizard.addPage(new QWizardPage), N + 52);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), N + 52);
+
+ QTest::ignoreMessage(QtWarningMsg,"QWizard::setPage: Cannot insert null page");
+ wizard.addPage(0); // generates a warning
+ QCOMPARE(spy.count(), 0);
+ delete parent;
+}
+
+#define CHECK_VISITED(wizard, list) \
+ do { \
+ QList<int> myList = list; \
+ QCOMPARE((wizard).visitedPages(), myList); \
+ Q_FOREACH(int id, myList) \
+ QVERIFY((wizard).hasVisitedPage(id)); \
+ } while (0)
+
+void tst_QWizard::setPage()
+{
+ QWidget *parent = new QWidget;
+ QWizard wizard;
+ QWizardPage *page;
+ QSignalSpy spy(&wizard, SIGNAL(pageAdded(int)));
+
+ QCOMPARE(wizard.startId(), -1);
+ QCOMPARE(wizard.currentId(), -1);
+ QVERIFY(!wizard.currentPage());
+ QCOMPARE(wizard.nextId(), -1);
+
+ page = new QWizardPage(parent);
+ QTest::ignoreMessage(QtWarningMsg,"QWizard::setPage: Cannot insert page with ID -1");
+ wizard.setPage(-1, page); // gives a warning and does nothing
+ QCOMPARE(spy.count(), 0);
+ QVERIFY(!wizard.page(-2));
+ QVERIFY(!wizard.page(-1));
+ QVERIFY(!wizard.page(0));
+ QCOMPARE(wizard.startId(), -1);
+ QCOMPARE(wizard.currentId(), -1);
+ QVERIFY(!wizard.currentPage());
+ QCOMPARE(wizard.nextId(), -1);
+ CHECK_VISITED(wizard, QList<int>());
+
+ page = new QWizardPage(parent);
+ wizard.setPage(0, page);
+ QCOMPARE(spy.count(), 1);
+ QList<QVariant> arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 0);
+ QCOMPARE(page->window(), (QWidget *)&wizard);
+ QCOMPARE(wizard.page(0), page);
+ QCOMPARE(wizard.startId(), 0);
+ QCOMPARE(wizard.currentId(), -1);
+ QVERIFY(!wizard.currentPage());
+ QCOMPARE(wizard.nextId(), -1);
+ CHECK_VISITED(wizard, QList<int>());
+
+ page = new QWizardPage(parent);
+ wizard.setPage(-2, page);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), -2);
+ QCOMPARE(page->window(), (QWidget *)&wizard);
+ QCOMPARE(wizard.page(-2), page);
+ QCOMPARE(wizard.startId(), -2);
+ QCOMPARE(wizard.currentId(), -1);
+ QVERIFY(!wizard.currentPage());
+ QCOMPARE(wizard.nextId(), -1);
+ CHECK_VISITED(wizard, QList<int>());
+
+ wizard.restart();
+ QCOMPARE(wizard.page(-2), page);
+ QCOMPARE(wizard.startId(), -2);
+ QCOMPARE(wizard.currentId(), -2);
+ QVERIFY(wizard.currentPage() == page);
+ QCOMPARE(wizard.nextId(), 0);
+ CHECK_VISITED(wizard, QList<int>() << -2);
+
+ page = new QWizardPage(parent);
+ wizard.setPage(2, page);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 2);
+ QCOMPARE(wizard.page(2), page);
+ QCOMPARE(wizard.startId(), -2);
+ QCOMPARE(wizard.currentId(), -2);
+ QVERIFY(wizard.currentPage() == wizard.page(-2));
+ QCOMPARE(wizard.nextId(), 0);
+ CHECK_VISITED(wizard, QList<int>() << -2);
+
+ wizard.restart();
+ QCOMPARE(wizard.startId(), -2);
+ QCOMPARE(wizard.currentId(), -2);
+ QVERIFY(wizard.currentPage() == wizard.page(-2));
+ QCOMPARE(wizard.nextId(), 0);
+ CHECK_VISITED(wizard, QList<int>() << -2);
+
+ page = new QWizardPage(parent);
+ wizard.setPage(-3, page);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), -3);
+ QCOMPARE(wizard.page(-3), page);
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), -2);
+ QVERIFY(wizard.currentPage() == wizard.page(-2));
+ QCOMPARE(wizard.nextId(), 0);
+ CHECK_VISITED(wizard, QList<int>() << -2);
+
+ wizard.restart();
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), -3);
+ QVERIFY(wizard.currentPage() == wizard.page(-3));
+ QCOMPARE(wizard.nextId(), -2);
+ CHECK_VISITED(wizard, QList<int>() << -3);
+
+ wizard.next();
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), -2);
+ QVERIFY(wizard.currentPage() == wizard.page(-2));
+ QCOMPARE(wizard.nextId(), 0);
+ CHECK_VISITED(wizard, QList<int>() << -3 << -2);
+
+ wizard.next();
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), 0);
+ QVERIFY(wizard.currentPage() == wizard.page(0));
+ QCOMPARE(wizard.nextId(), 2);
+ CHECK_VISITED(wizard, QList<int>() << -3 << -2 << 0);
+
+ for (int i = 0; i < 100; ++i) {
+ wizard.next();
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), 2);
+ QVERIFY(wizard.currentPage() == wizard.page(2));
+ QCOMPARE(wizard.nextId(), -1);
+ CHECK_VISITED(wizard, QList<int>() << -3 << -2 << 0 << 2);
+ }
+
+ wizard.back();
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), 0);
+ QVERIFY(wizard.currentPage() == wizard.page(0));
+ QCOMPARE(wizard.nextId(), 2);
+ CHECK_VISITED(wizard, QList<int>() << -3 << -2 << 0);
+
+ wizard.back();
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), -2);
+ QVERIFY(wizard.currentPage() == wizard.page(-2));
+ QCOMPARE(wizard.nextId(), 0);
+ CHECK_VISITED(wizard, QList<int>() << -3 << -2);
+
+ for (int i = 0; i < 100; ++i) {
+ wizard.back();
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), -3);
+ QVERIFY(wizard.currentPage() == wizard.page(-3));
+ QCOMPARE(wizard.nextId(), -2);
+ CHECK_VISITED(wizard, QList<int>() << -3);
+ }
+
+ for (int i = 0; i < 100; ++i) {
+ wizard.restart();
+ QCOMPARE(wizard.startId(), -3);
+ QCOMPARE(wizard.currentId(), -3);
+ QVERIFY(wizard.currentPage() == wizard.page(-3));
+ QCOMPARE(wizard.nextId(), -2);
+ CHECK_VISITED(wizard, QList<int>() << -3);
+ }
+ QCOMPARE(spy.count(), 0);
+ delete parent;
+}
+
+void tst_QWizard::setStartId()
+{
+ QWizard wizard;
+ QCOMPARE(wizard.startId(), -1);
+
+ wizard.setPage(INT_MIN, new QWizardPage);
+ QCOMPARE(wizard.startId(), INT_MIN);
+
+ wizard.setPage(-2, new QWizardPage);
+ QCOMPARE(wizard.startId(), INT_MIN);
+
+ wizard.setPage(0, new QWizardPage);
+ QCOMPARE(wizard.startId(), INT_MIN);
+
+ wizard.setPage(1, new QWizardPage);
+ QCOMPARE(wizard.startId(), INT_MIN);
+
+ wizard.setPage(INT_MAX, new QWizardPage);
+ QCOMPARE(wizard.startId(), INT_MIN);
+
+ QTest::ignoreMessage(QtWarningMsg,"QWizard::setStartId: Invalid page ID 123");
+ wizard.setStartId(123);
+ QCOMPARE(wizard.startId(), INT_MIN);
+
+ wizard.setStartId(-1);
+ QCOMPARE(wizard.startId(), INT_MIN);
+
+ wizard.setStartId(-2);
+ QCOMPARE(wizard.startId(), -2);
+ QCOMPARE(wizard.nextId(), -1);
+
+ wizard.setStartId(-1);
+ QCOMPARE(wizard.startId(), INT_MIN);
+
+ wizard.setStartId(-2);
+ QCOMPARE(wizard.startId(), -2);
+ QCOMPARE(wizard.nextId(), -1);
+
+ wizard.restart();
+ QCOMPARE(wizard.startId(), -2);
+ QCOMPARE(wizard.currentId(), -2);
+ QVERIFY(wizard.currentPage() == wizard.page(-2));
+ QCOMPARE(wizard.nextId(), 0);
+
+ wizard.next();
+ QCOMPARE(wizard.startId(), -2);
+ QCOMPARE(wizard.currentId(), 0);
+ QVERIFY(wizard.currentPage() == wizard.page(0));
+ QCOMPARE(wizard.nextId(), 1);
+
+ wizard.setStartId(INT_MIN);
+ QCOMPARE(wizard.startId(), INT_MIN);
+ QCOMPARE(wizard.currentId(), 0);
+ QVERIFY(wizard.currentPage() == wizard.page(0));
+ QCOMPARE(wizard.nextId(), 1);
+
+ wizard.next();
+ QCOMPARE(wizard.startId(), INT_MIN);
+ QCOMPARE(wizard.currentId(), 1);
+ QVERIFY(wizard.currentPage() == wizard.page(1));
+ QCOMPARE(wizard.nextId(), INT_MAX);
+
+ wizard.next();
+ QCOMPARE(wizard.startId(), INT_MIN);
+ QCOMPARE(wizard.currentId(), INT_MAX);
+ QVERIFY(wizard.currentPage() == wizard.page(INT_MAX));
+ QCOMPARE(wizard.nextId(), -1);
+ CHECK_VISITED(wizard, QList<int>() << -2 << 0 << 1 << INT_MAX);
+}
+
+struct MyPage2 : public QWizardPage
+{
+public:
+ MyPage2() : init(0), cleanup(0), validate(0) {}
+
+ void initializePage() { ++init; QWizardPage::initializePage(); }
+ void cleanupPage() { ++cleanup; QWizardPage::cleanupPage(); }
+ bool validatePage() { ++validate; return QWizardPage::validatePage(); }
+
+ bool check(int init, int cleanup)
+ {
+ return init == this->init
+ && cleanup == this->cleanup
+ && (this->init == this->cleanup || this->init - 1 == this->cleanup);
+ }
+
+ int init;
+ int cleanup;
+ int validate;
+};
+
+#define CHECK_PAGE_INIT(i0, c0, i1, c1, i2, c2) \
+ QVERIFY(page0->check((i0), (c0))); \
+ QVERIFY(page1->check((i1), (c1))); \
+ QVERIFY(page2->check((i2), (c2)));
+
+void tst_QWizard::setOption_IndependentPages()
+{
+ MyPage2 *page0 = new MyPage2;
+ MyPage2 *page1 = new MyPage2;
+ MyPage2 *page2 = new MyPage2;
+
+ QWizard wizard;
+ wizard.addPage(page0);
+ wizard.addPage(page1);
+ wizard.addPage(page2);
+
+ QVERIFY(!wizard.testOption(QWizard::IndependentPages));
+
+ wizard.restart();
+
+ // Make sure initializePage() and cleanupPage() are called are
+ // they should when the
+ // wizard.testOption(QWizard::IndependentPages option is off.
+ for (int i = 0; i < 10; ++i) {
+ CHECK_PAGE_INIT(i + 1, i, i, i, i, i);
+
+ wizard.next();
+ CHECK_PAGE_INIT(i + 1, i, i + 1, i, i, i);
+
+ wizard.next();
+ CHECK_PAGE_INIT(i + 1, i, i + 1, i, i + 1, i);
+
+ wizard.next();
+ CHECK_PAGE_INIT(i + 1, i, i + 1, i, i + 1, i);
+
+ wizard.back();
+ CHECK_PAGE_INIT(i + 1, i, i + 1, i, i + 1, i + 1);
+
+ wizard.back();
+ CHECK_PAGE_INIT(i + 1, i, i + 1, i + 1, i + 1, i + 1);
+
+ wizard.back();
+ CHECK_PAGE_INIT(i + 1, i, i + 1, i + 1, i + 1, i + 1);
+
+ wizard.restart();
+ }
+
+ CHECK_PAGE_INIT(11, 10, 10, 10, 10, 10);
+
+ wizard.next();
+ CHECK_PAGE_INIT(11, 10, 11, 10, 10, 10);
+
+ // Now, turn on the option and check that they're called at the
+ // appropriate times (which aren't the same).
+ wizard.setOption(QWizard::IndependentPages, true);
+ CHECK_PAGE_INIT(11, 10, 11, 10, 10, 10);
+
+ wizard.back();
+ CHECK_PAGE_INIT(11, 10, 11, 10, 10, 10);
+
+ wizard.next();
+ CHECK_PAGE_INIT(11, 10, 11, 10, 10, 10);
+
+ wizard.next();
+ CHECK_PAGE_INIT(11, 10, 11, 10, 11, 10);
+
+ wizard.next();
+ CHECK_PAGE_INIT(11, 10, 11, 10, 11, 10);
+
+ wizard.back();
+ CHECK_PAGE_INIT(11, 10, 11, 10, 11, 10);
+
+ wizard.setStartId(2);
+
+ wizard.restart();
+ CHECK_PAGE_INIT(11, 11, 11, 11, 12, 11);
+
+ wizard.back();
+ CHECK_PAGE_INIT(11, 11, 11, 11, 12, 11);
+
+ wizard.next();
+ CHECK_PAGE_INIT(11, 11, 11, 11, 12, 11);
+
+ wizard.setStartId(0);
+ wizard.restart();
+ CHECK_PAGE_INIT(12, 11, 11, 11, 12, 12);
+
+ wizard.next();
+ CHECK_PAGE_INIT(12, 11, 12, 11, 12, 12);
+
+ wizard.next();
+ CHECK_PAGE_INIT(12, 11, 12, 11, 13, 12);
+
+ wizard.back();
+ CHECK_PAGE_INIT(12, 11, 12, 11, 13, 12);
+
+ // Fun stuff here.
+
+ wizard.setOption(QWizard::IndependentPages, false);
+ CHECK_PAGE_INIT(12, 11, 12, 11, 13, 13);
+
+ wizard.setOption(QWizard::IndependentPages, true);
+ CHECK_PAGE_INIT(12, 11, 12, 11, 13, 13);
+
+ wizard.setOption(QWizard::IndependentPages, false);
+ CHECK_PAGE_INIT(12, 11, 12, 11, 13, 13);
+
+ wizard.back();
+ CHECK_PAGE_INIT(12, 11, 12, 12, 13, 13);
+
+ wizard.back();
+ CHECK_PAGE_INIT(12, 11, 12, 12, 13, 13);
+}
+
+void tst_QWizard::setOption_IgnoreSubTitles()
+{
+#if defined(Q_OS_WINCE)
+ QSKIP("Skipped because of limited resources and potential crash. (Task: 166824)", SkipAll);
+#endif
+ QWizard wizard1;
+ wizard1.setButtonLayout(QList<QWizard::WizardButton>() << QWizard::CancelButton);
+ wizard1.resize(500, 500);
+ QVERIFY(!wizard1.testOption(QWizard::IgnoreSubTitles));
+ QWizardPage *page11 = new QWizardPage;
+ page11->setTitle("Page X");
+ page11->setSubTitle("Some subtitle");
+
+ QWizardPage *page12 = new QWizardPage;
+ page12->setTitle("Page X");
+
+ wizard1.addPage(page11);
+ wizard1.addPage(page12);
+
+ QWizard wizard2;
+ wizard2.setButtonLayout(QList<QWizard::WizardButton>() << QWizard::CancelButton);
+ wizard2.resize(500, 500);
+ wizard2.setOption(QWizard::IgnoreSubTitles, true);
+ QWizardPage *page21 = new QWizardPage;
+ page21->setTitle("Page X");
+ page21->setSubTitle("Some subtitle");
+
+ QWizardPage *page22 = new QWizardPage;
+ page22->setTitle("Page X");
+
+ wizard2.addPage(page21);
+ wizard2.addPage(page22);
+
+ wizard1.show();
+ wizard2.show();
+
+ // Check that subtitles are shown when they should (i.e.,
+ // they're set and IgnoreSubTitles is off).
+
+ qApp->setActiveWindow(0); // ensure no focus rectangle around cancel button
+ QImage i11 = grabWidget(&wizard1);
+ QImage i21 = grabWidget(&wizard2);
+ QVERIFY(i11 != i21);
+
+ wizard1.next();
+ wizard2.next();
+
+ QImage i12 = grabWidget(&wizard1);
+ QImage i22 = grabWidget(&wizard2);
+ QVERIFY(i12 == i22);
+ QVERIFY(i21 == i22);
+
+ wizard1.back();
+ wizard2.back();
+
+ QImage i13 = grabWidget(&wizard1);
+ QImage i23 = grabWidget(&wizard2);
+ QVERIFY(i13 == i11);
+ QVERIFY(i23 == i21);
+
+ wizard1.setOption(QWizard::IgnoreSubTitles, true);
+ wizard2.setOption(QWizard::IgnoreSubTitles, false);
+
+ QImage i14 = grabWidget(&wizard1);
+ QImage i24 = grabWidget(&wizard2);
+ QVERIFY(i14 == i21);
+ QVERIFY(i24 == i11);
+
+ // Check the impact of subtitles on the rest of the layout, by
+ // using a subtitle that looks empty (but that isn't). In
+ // Classic and Modern styles, this should be enough to trigger a
+ // "header"; in Mac style, this only creates a QLabel, with no
+ // text, i.e. it doesn't affect the layout.
+
+ page11->setSubTitle("<b></b>"); // not quite empty, but looks empty
+
+ for (int i = 0; i < 3; ++i) {
+ for (int j = 0; j < 2; ++j) {
+ wizard1.setOption(QWizard::IgnoreSubTitles, j == 0);
+
+ wizard1.setWizardStyle(i == 0 ? QWizard::ClassicStyle
+ : i == 1 ? QWizard::ModernStyle
+ : QWizard::MacStyle);
+ wizard1.restart();
+ QImage i1 = grabWidget(&wizard1);
+
+ wizard1.next();
+ QImage i2 = grabWidget(&wizard1);
+
+ if (j == 0 || wizard1.wizardStyle() == QWizard::MacStyle) {
+ QVERIFY(i1 == i2);
+ } else {
+ QVERIFY(i1 != i2);
+ }
+ }
+ }
+}
+
+void tst_QWizard::setOption_ExtendedWatermarkPixmap()
+{
+#if defined(Q_OS_WINCE)
+ QSKIP("Skipped because of limited resources and potential crash. (Task: 166824)", SkipAll);
+#endif
+ QPixmap watermarkPixmap(200, 400);
+ watermarkPixmap.fill(Qt::black);
+
+ QWizard wizard1;
+ wizard1.setButtonLayout(QList<QWizard::WizardButton>() << QWizard::CancelButton);
+ QVERIFY(!wizard1.testOption(QWizard::ExtendedWatermarkPixmap));
+ QWizardPage *page11 = new QWizardPage;
+ page11->setTitle("Page X");
+ page11->setPixmap(QWizard::WatermarkPixmap, watermarkPixmap);
+
+ QWizardPage *page12 = new QWizardPage;
+ page12->setTitle("Page X");
+
+ wizard1.addPage(page11);
+ wizard1.addPage(page12);
+
+ QWizard wizard2;
+ wizard2.setButtonLayout(QList<QWizard::WizardButton>() << QWizard::CancelButton);
+ wizard2.setOption(QWizard::ExtendedWatermarkPixmap, true);
+ QWizardPage *page21 = new QWizardPage;
+ page21->setTitle("Page X");
+ page21->setPixmap(QWizard::WatermarkPixmap, watermarkPixmap);
+
+ QWizardPage *page22 = new QWizardPage;
+ page22->setTitle("Page X");
+
+ wizard2.addPage(page21);
+ wizard2.addPage(page22);
+
+ wizard1.show();
+ wizard2.show();
+
+ // Check the impact of watermark pixmaps on the rest of the layout.
+
+ for (int i = 0; i < 3; ++i) {
+ QImage i1[2];
+ QImage i2[2];
+ for (int j = 0; j < 2; ++j) {
+ wizard1.setOption(QWizard::ExtendedWatermarkPixmap, j == 0);
+
+ wizard1.setWizardStyle(i == 0 ? QWizard::ClassicStyle
+ : i == 1 ? QWizard::ModernStyle
+ : QWizard::MacStyle);
+ wizard1.restart();
+ wizard1.setMaximumSize(1000, 1000);
+ wizard1.resize(600, 600);
+ i1[j] = grabWidget(&wizard1);
+
+ wizard1.next();
+ wizard1.setMaximumSize(1000, 1000);
+ wizard1.resize(600, 600);
+ i2[j] = grabWidget(&wizard1);
+ }
+
+ if (wizard1.wizardStyle() == QWizard::MacStyle) {
+ QVERIFY(i1[0] == i1[1]);
+ QVERIFY(i2[0] == i2[1]);
+ QVERIFY(i1[0] == i2[0]);
+ } else {
+ QVERIFY(i1[0] != i1[1]);
+ QVERIFY(i2[0] == i2[1]);
+ QVERIFY(i1[0] != i2[0]);
+ QVERIFY(i1[1] != i2[1]);
+ }
+ }
+}
+
+void tst_QWizard::setOption_NoDefaultButton()
+{
+ QWizard wizard;
+ wizard.setOption(QWizard::NoDefaultButton, false);
+ wizard.setOption(QWizard::HaveFinishButtonOnEarlyPages, true);
+ wizard.addPage(new QWizardPage);
+ wizard.page(0)->setFinalPage(true);
+ wizard.addPage(new QWizardPage);
+
+ if (QPushButton *pb = qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton)))
+ pb->setAutoDefault(false);
+ if (QPushButton *pb = qobject_cast<QPushButton *>(wizard.button(QWizard::FinishButton)))
+ pb->setAutoDefault(false);
+
+ wizard.show();
+ qApp->processEvents();
+ QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
+ QVERIFY(wizard.button(QWizard::FinishButton)->isEnabled());
+
+ wizard.next();
+ QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::FinishButton))->isDefault());
+
+ wizard.back();
+ QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
+
+ wizard.setOption(QWizard::NoDefaultButton, true);
+ QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
+ QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::FinishButton))->isDefault());
+
+ wizard.next();
+ QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
+ QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::FinishButton))->isDefault());
+
+ wizard.back();
+ QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
+ QVERIFY(!qobject_cast<QPushButton *>(wizard.button(QWizard::FinishButton))->isDefault());
+
+ wizard.setOption(QWizard::NoDefaultButton, false);
+ QVERIFY(qobject_cast<QPushButton *>(wizard.button(QWizard::NextButton))->isDefault());
+}
+
+void tst_QWizard::setOption_NoBackButtonOnStartPage()
+{
+ QWizard wizard;
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, true);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+
+ wizard.setStartId(1);
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, false);
+ qApp->processEvents();
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, true);
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, false);
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, true);
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.back();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+}
+
+void tst_QWizard::setOption_NoBackButtonOnLastPage()
+{
+ for (int i = 0; i < 2; ++i) {
+ QWizard wizard;
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, false);
+ wizard.setOption(QWizard::NoBackButtonOnLastPage, true);
+ wizard.setOption(QWizard::DisabledBackButtonOnLastPage, i == 0); // changes nothing
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.page(1)->setFinalPage(true); // changes nothing (final != last in general)
+ wizard.addPage(new QWizardPage);
+
+ wizard.setStartId(1);
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.back();
+ qApp->processEvents();
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.setOption(QWizard::NoBackButtonOnLastPage, false);
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.setOption(QWizard::NoBackButtonOnLastPage, true);
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible());
+
+ wizard.addPage(new QWizardPage);
+ QVERIFY(!wizard.button(QWizard::BackButton)->isVisible()); // this is maybe wrong
+ }
+}
+
+void tst_QWizard::setOption_DisabledBackButtonOnLastPage()
+{
+ QWizard wizard;
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, false);
+ wizard.setOption(QWizard::DisabledBackButtonOnLastPage, true);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.page(1)->setFinalPage(true); // changes nothing (final != last in general)
+ wizard.addPage(new QWizardPage);
+
+ wizard.setStartId(1);
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.back();
+ qApp->processEvents();
+ QVERIFY(wizard.button(QWizard::BackButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.setOption(QWizard::DisabledBackButtonOnLastPage, false);
+ QVERIFY(wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.setOption(QWizard::DisabledBackButtonOnLastPage, true);
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.addPage(new QWizardPage);
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled()); // this is maybe wrong
+}
+
+void tst_QWizard::setOption_HaveNextButtonOnLastPage()
+{
+ QWizard wizard;
+ wizard.setOption(QWizard::HaveNextButtonOnLastPage, false);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.page(1)->setFinalPage(true); // changes nothing (final != last in general)
+ wizard.addPage(new QWizardPage);
+
+ wizard.setStartId(1);
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::NextButton)->isEnabled());
+
+ wizard.next();
+ QVERIFY(!wizard.button(QWizard::NextButton)->isVisible());
+
+ wizard.setOption(QWizard::HaveNextButtonOnLastPage, true);
+ QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::NextButton)->isEnabled());
+
+ wizard.next();
+ QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::NextButton)->isEnabled());
+
+ wizard.back();
+ QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::NextButton)->isEnabled());
+
+ wizard.setOption(QWizard::HaveNextButtonOnLastPage, false);
+ QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(wizard.button(QWizard::NextButton)->isEnabled());
+
+ wizard.next();
+ QVERIFY(!wizard.button(QWizard::NextButton)->isVisible());
+
+ wizard.setOption(QWizard::HaveNextButtonOnLastPage, true);
+ QVERIFY(wizard.button(QWizard::NextButton)->isVisible());
+ QVERIFY(!wizard.button(QWizard::NextButton)->isEnabled());
+}
+
+void tst_QWizard::setOption_HaveFinishButtonOnEarlyPages()
+{
+ QWizard wizard;
+ QVERIFY(!wizard.testOption(QWizard::HaveFinishButtonOnEarlyPages));
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.page(1)->setFinalPage(true);
+ wizard.addPage(new QWizardPage);
+
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(!wizard.button(QWizard::FinishButton)->isVisible());
+
+ wizard.next();
+ QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
+
+ wizard.next();
+ QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
+
+ wizard.back();
+ QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
+
+ wizard.back();
+ QVERIFY(!wizard.button(QWizard::FinishButton)->isVisible());
+
+ wizard.setOption(QWizard::HaveFinishButtonOnEarlyPages, true);
+ QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
+
+ wizard.next();
+ QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
+
+ wizard.setOption(QWizard::HaveFinishButtonOnEarlyPages, false);
+ QVERIFY(wizard.button(QWizard::FinishButton)->isVisible());
+
+ wizard.back();
+ QVERIFY(!wizard.button(QWizard::FinishButton)->isVisible());
+}
+
+void tst_QWizard::setOption_NoCancelButton()
+{
+ for (int i = 0; i < 2; ++i) {
+ QWizard wizard;
+ wizard.setOption(QWizard::NoCancelButton, true);
+ wizard.setOption(QWizard::CancelButtonOnLeft, i == 0);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
+
+ wizard.next();
+ QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
+
+ wizard.setOption(QWizard::NoCancelButton, false);
+ QVERIFY(wizard.button(QWizard::CancelButton)->isVisible());
+
+ wizard.back();
+ QVERIFY(wizard.button(QWizard::CancelButton)->isVisible());
+
+ wizard.setOption(QWizard::NoCancelButton, true);
+ QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
+ }
+}
+
+void tst_QWizard::setOption_CancelButtonOnLeft()
+{
+ for (int i = 0; i < 2; ++i) {
+ int sign = (i == 0) ? +1 : -1;
+
+ QWizard wizard;
+ wizard.setLayoutDirection(i == 0 ? Qt::LeftToRight : Qt::RightToLeft);
+ wizard.setOption(QWizard::NoCancelButton, false);
+ wizard.setOption(QWizard::CancelButtonOnLeft, true);
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, false);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.show();
+ qApp->processEvents();
+
+ const QAbstractButton *refButton = wizard.button((wizard.wizardStyle() == QWizard::AeroStyle)
+ ? QWizard::NextButton : QWizard::BackButton);
+ const QAbstractButton *refButton2 = wizard.button((wizard.wizardStyle() == QWizard::AeroStyle)
+ ? QWizard::FinishButton : QWizard::BackButton);
+
+ QVERIFY(sign * wizard.button(QWizard::CancelButton)->x() < sign * refButton->x());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(sign * wizard.button(QWizard::CancelButton)->x() < sign * refButton->x());
+
+ wizard.setOption(QWizard::CancelButtonOnLeft, false);
+ qApp->processEvents();
+ QVERIFY(sign * wizard.button(QWizard::CancelButton)->x() > sign * refButton2->x());
+
+ wizard.back();
+ qApp->processEvents();
+ QVERIFY(sign * wizard.button(QWizard::CancelButton)->x() > sign * refButton->x());
+ }
+}
+
+void tst_QWizard::setOption_HaveHelpButton()
+{
+ for (int i = 0; i < 2; ++i) {
+ QWizard wizard;
+ QVERIFY(!wizard.testOption(QWizard::HaveHelpButton));
+ wizard.setOption(QWizard::HaveHelpButton, false);
+ wizard.setOption(QWizard::HelpButtonOnRight, i == 0);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(!wizard.button(QWizard::HelpButton)->isVisible());
+
+ wizard.next();
+ QVERIFY(!wizard.button(QWizard::HelpButton)->isVisible());
+
+ wizard.setOption(QWizard::HaveHelpButton, true);
+ QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
+
+ wizard.back();
+ QVERIFY(wizard.button(QWizard::HelpButton)->isVisible());
+
+ wizard.setOption(QWizard::HaveHelpButton, false);
+ QVERIFY(!wizard.button(QWizard::HelpButton)->isVisible());
+ }
+}
+
+void tst_QWizard::setOption_HelpButtonOnRight()
+{
+ for (int i = 0; i < 2; ++i) {
+ int sign = (i == 0) ? +1 : -1;
+
+ QWizard wizard;
+ wizard.setLayoutDirection(i == 0 ? Qt::LeftToRight : Qt::RightToLeft);
+ wizard.setOption(QWizard::HaveHelpButton, true);
+ wizard.setOption(QWizard::HelpButtonOnRight, false);
+ wizard.setOption(QWizard::NoBackButtonOnStartPage, false);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.show();
+ qApp->processEvents();
+
+ const QAbstractButton *refButton = wizard.button((wizard.wizardStyle() == QWizard::AeroStyle)
+ ? QWizard::NextButton : QWizard::BackButton);
+
+ QVERIFY(sign * wizard.button(QWizard::HelpButton)->x() < sign * refButton->x());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(sign * wizard.button(QWizard::HelpButton)->x() < sign * refButton->x());
+
+ wizard.setOption(QWizard::HelpButtonOnRight, true);
+ qApp->processEvents();
+ QVERIFY(sign * wizard.button(QWizard::HelpButton)->x() > sign * refButton->x());
+
+ wizard.back();
+ qApp->processEvents();
+ QVERIFY(sign * wizard.button(QWizard::HelpButton)->x() > sign * refButton->x());
+ }
+}
+
+void tst_QWizard::setOption_HaveCustomButtonX()
+{
+ for (int i = 0; i < 2; ++i) {
+ for (int j = 0; j < 2; ++j) {
+ for (int k = 0; k < 2; ++k) {
+ QWizard wizard;
+ wizard.setLayoutDirection(Qt::LeftToRight);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.show();
+
+ wizard.setButtonText(QWizard::CustomButton1, "Foo");
+ wizard.setButton(QWizard::CustomButton2, new QCheckBox("Bar"));
+ wizard.button(QWizard::CustomButton3)->setText("Baz");
+
+ wizard.setOption(QWizard::HaveCustomButton1, i == 0);
+ wizard.setOption(QWizard::HaveCustomButton2, j == 0);
+ wizard.setOption(QWizard::HaveCustomButton3, k == 0);
+
+ QVERIFY(wizard.button(QWizard::CustomButton1)->isHidden() == (i != 0));
+ QVERIFY(wizard.button(QWizard::CustomButton2)->isHidden() == (j != 0));
+ QVERIFY(wizard.button(QWizard::CustomButton3)->isHidden() == (k != 0));
+
+ if (i + j + k == 0) {
+ qApp->processEvents();
+ QVERIFY(wizard.button(QWizard::CustomButton1)->x()
+ < wizard.button(QWizard::CustomButton2)->x());
+ QVERIFY(wizard.button(QWizard::CustomButton2)->x()
+ < wizard.button(QWizard::CustomButton3)->x());
+ }
+ }
+ }
+ }
+}
+
+class Operation
+{
+public:
+ virtual void apply(QWizard *) const = 0;
+ virtual QString describe() const = 0;
+protected:
+ virtual ~Operation() {}
+};
+
+class SetPage : public Operation
+{
+ void apply(QWizard *wizard) const
+ {
+ wizard->restart();
+ for (int j = 0; j < page; ++j)
+ wizard->next();
+ }
+ QString describe() const { return QString("set page %1").arg(page); }
+ const int page;
+public:
+ SetPage(int page) : page(page) {}
+};
+
+class SetStyle : public Operation
+{
+ void apply(QWizard *wizard) const { wizard->setWizardStyle(style); }
+ QString describe() const { return QString("set style %1").arg(style); }
+ const QWizard::WizardStyle style;
+public:
+ SetStyle(QWizard::WizardStyle style) : style(style) {}
+};
+
+class SetOption : public Operation
+{
+ void apply(QWizard *wizard) const { wizard->setOption(option, on); }
+ QString describe() const;
+ const QWizard::WizardOption option;
+ const bool on;
+public:
+ SetOption(QWizard::WizardOption option, bool on) : option(option), on(on) {}
+};
+
+class OptionInfo
+{
+ OptionInfo()
+ {
+ tags[QWizard::IndependentPages] = "0/IPP";
+ tags[QWizard::IgnoreSubTitles] = "1/IST";
+ tags[QWizard::ExtendedWatermarkPixmap] = "2/EWP";
+ tags[QWizard::NoDefaultButton] = "3/NDB";
+ tags[QWizard::NoBackButtonOnStartPage] = "4/BSP";
+ tags[QWizard::NoBackButtonOnLastPage] = "5/BLP";
+ tags[QWizard::DisabledBackButtonOnLastPage] = "6/DLP";
+ tags[QWizard::HaveNextButtonOnLastPage] = "7/NLP";
+ tags[QWizard::HaveFinishButtonOnEarlyPages] = "8/FEP";
+ tags[QWizard::NoCancelButton] = "9/NCB";
+ tags[QWizard::CancelButtonOnLeft] = "10/CBL";
+ tags[QWizard::HaveHelpButton] = "11/HHB";
+ tags[QWizard::HelpButtonOnRight] = "12/HBR";
+ tags[QWizard::HaveCustomButton1] = "13/CB1";
+ tags[QWizard::HaveCustomButton2] = "14/CB2";
+ tags[QWizard::HaveCustomButton3] = "15/CB3";
+
+ for (int i = 0; i < 2; ++i) {
+ QMap<QWizard::WizardOption, Operation *> operations_;
+ foreach (QWizard::WizardOption option, tags.keys())
+ operations_[option] = new SetOption(option, i == 1);
+ operations << operations_;
+ }
+ }
+ OptionInfo(OptionInfo const&);
+ OptionInfo& operator=(OptionInfo const&);
+ QMap<QWizard::WizardOption, QString> tags;
+ QList<QMap<QWizard::WizardOption, Operation *> > operations;
+public:
+ static OptionInfo &instance()
+ {
+ static OptionInfo optionInfo;
+ return optionInfo;
+ }
+
+ QString tag(QWizard::WizardOption option) const { return tags.value(option); }
+ Operation * operation(QWizard::WizardOption option, bool on) const
+ { return operations.at(on).value(option); }
+ QList<QWizard::WizardOption> options() const { return tags.keys(); }
+};
+
+QString SetOption::describe() const
+{
+ return QString("set opt %1 %2").arg(OptionInfo::instance().tag(option)).arg(on);
+}
+
+Q_DECLARE_METATYPE(Operation *)
+Q_DECLARE_METATYPE(SetPage *)
+Q_DECLARE_METATYPE(SetStyle *)
+Q_DECLARE_METATYPE(SetOption *)
+Q_DECLARE_METATYPE(QList<Operation *>)
+
+class TestGroup
+{
+public:
+ enum Type {Equality, NonEquality};
+
+ TestGroup(const QString &name = QString("no name"), Type type = Equality)
+ : name(name), type(type), nRows_(0) {}
+
+ void reset(const QString &name, Type type = Equality)
+ {
+ this->name = name;
+ this->type = type;
+ combinations.clear();
+ }
+
+ QList<Operation *> &add()
+ { combinations << new QList<Operation *>; return *(combinations.last()); }
+
+ void createTestRows()
+ {
+ for (int i = 0; i < combinations.count(); ++i) {
+ QTest::newRow((name + QString(", row %1").arg(i)).toLatin1().data())
+ << (i == 0) << (type == Equality) << *(combinations.at(i));
+ ++nRows_;
+ }
+ }
+
+ int nRows() const { return nRows_; }
+
+private:
+ QString name;
+ Type type;
+ int nRows_;
+ QList<QList<Operation *> *> combinations;
+};
+
+class IntroPage : public QWizardPage
+{
+ Q_OBJECT
+public:
+ IntroPage()
+ {
+ setTitle(tr("Intro"));
+ setSubTitle(tr("Intro Subtitle"));
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(new QLabel(tr("Intro Label")));
+ setLayout(layout);
+ }
+};
+
+class MiddlePage : public QWizardPage
+{
+ Q_OBJECT
+public:
+ MiddlePage()
+ {
+ setTitle(tr("Middle"));
+ setSubTitle(tr("Middle Subtitle"));
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(new QLabel(tr("Middle Label")));
+ setLayout(layout);
+ }
+};
+
+class ConclusionPage : public QWizardPage
+{
+ Q_OBJECT
+public:
+ ConclusionPage()
+ {
+ setTitle(tr("Conclusion"));
+ setSubTitle(tr("Conclusion Subtitle"));
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(new QLabel(tr("Conclusion Label")));
+ setLayout(layout);
+ }
+};
+
+class TestWizard : public QWizard
+{
+ Q_OBJECT
+ QList<int> pageIds;
+ QString opsDescr;
+public:
+ TestWizard()
+ {
+ setPixmap(QWizard::BannerPixmap, QPixmap(":/images/banner.png"));
+ setPixmap(QWizard::BackgroundPixmap, QPixmap(":/images/background.png"));
+ setPixmap(QWizard::WatermarkPixmap, QPixmap(":/images/watermark.png"));
+ setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo.png"));
+ setButtonText(QWizard::CustomButton1, "custom 1");
+ setButtonText(QWizard::CustomButton2, "custom 2");
+ setButtonText(QWizard::CustomButton3, "custom 3");
+ pageIds << addPage(new IntroPage);
+ pageIds << addPage(new MiddlePage);
+ pageIds << addPage(new ConclusionPage);
+
+ // Disable antialiased font rendering since this may sometimes result in tiny
+ // and (apparent) non-deterministic pixel variations between images expected to be
+ // identical. This may only be a problem on X11.
+ QFont f = font();
+ f.setStyleStrategy(QFont::NoAntialias);
+ setFont(f);
+
+ // ### Required to work with a deficiency(?) in QWizard:
+// setFixedSize(800, 600);
+ }
+
+ ~TestWizard()
+ {
+ foreach (int id, pageIds) {
+ QWizardPage *page_to_delete = page(id);
+ removePage(id);
+ delete page_to_delete;
+ }
+ }
+
+ void applyOperations(const QList<Operation *> &operations)
+ {
+ foreach (Operation * op, operations) {
+ if (op) {
+ op->apply(this);
+ opsDescr += QString("(%1) ").arg(op->describe());
+ }
+ }
+ }
+
+ QImage createImage() const
+ {
+ return QPixmap::grabWidget(const_cast<TestWizard *>(this))
+ .toImage().convertToFormat(QImage::Format_ARGB32);
+ }
+
+ QString operationsDescription() const { return opsDescr; }
+};
+
+class CombinationsTestData
+{
+ TestGroup testGroup;
+ QList<Operation *> pageOps;
+ QList<Operation *> styleOps;
+ QMap<bool, QList<Operation *> *> setAllOptions;
+public:
+ CombinationsTestData()
+ {
+ QTest::addColumn<bool>("ref");
+ QTest::addColumn<bool>("testEquality");
+ QTest::addColumn<QList<Operation *> >("operations");
+ pageOps << new SetPage(0) << new SetPage(1) << new SetPage(2);
+ styleOps << new SetStyle(QWizard::ClassicStyle) << new SetStyle(QWizard::ModernStyle)
+ << new SetStyle(QWizard::MacStyle);
+#define SETPAGE(page) pageOps.at(page)
+#define SETSTYLE(style) styleOps.at(style)
+#define OPT(option, on) OptionInfo::instance().operation(option, on)
+#define CLROPT(option) OPT(option, false)
+#define SETOPT(option) OPT(option, true)
+ setAllOptions[false] = new QList<Operation *>;
+ setAllOptions[true] = new QList<Operation *>;
+ foreach (QWizard::WizardOption option, OptionInfo::instance().options()) {
+ *setAllOptions.value(false) << CLROPT(option);
+ *setAllOptions.value(true) << SETOPT(option);
+ }
+#define CLRALLOPTS *setAllOptions.value(false)
+#define SETALLOPTS *setAllOptions.value(true)
+ }
+
+ int nRows() const { return testGroup.nRows(); }
+
+ // Creates "all" possible test rows. (WARNING: This typically makes the test take too long!)
+ void createAllTestRows()
+ {
+ testGroup.reset("testAll 1.1");
+ testGroup.add(); // i.e. no operations applied!
+ testGroup.add() << SETPAGE(0);
+ testGroup.add() << SETSTYLE(0);
+ testGroup.add() << SETPAGE(0) << SETSTYLE(0);
+ testGroup.add() << SETSTYLE(0) << SETPAGE(0);
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 2.1");
+ testGroup.add();
+ testGroup.add() << CLRALLOPTS;
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 2.2");
+ testGroup.add() << SETALLOPTS;
+ testGroup.add() << SETALLOPTS << SETALLOPTS;
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 2.3");
+ testGroup.add() << CLRALLOPTS;
+ testGroup.add() << CLRALLOPTS << CLRALLOPTS;
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 2.4");
+ testGroup.add() << CLRALLOPTS;
+ testGroup.add() << SETALLOPTS << CLRALLOPTS;
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 2.5");
+ testGroup.add() << SETALLOPTS;
+ testGroup.add() << CLRALLOPTS << SETALLOPTS;
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 2.6");
+ testGroup.add() << SETALLOPTS;
+ testGroup.add() << SETALLOPTS << CLRALLOPTS << SETALLOPTS;
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 2.7");
+ testGroup.add() << CLRALLOPTS;
+ testGroup.add() << CLRALLOPTS << SETALLOPTS << CLRALLOPTS;
+ testGroup.createTestRows();
+
+ for (int i = 0; i < 2; ++i) {
+ QList<Operation *> setOptions = *setAllOptions.value(i == 1);
+
+ testGroup.reset("testAll 3.1");
+ testGroup.add() << setOptions;
+ testGroup.add() << SETPAGE(0) << setOptions;
+ testGroup.add() << setOptions << SETPAGE(0);
+ testGroup.add() << SETSTYLE(0) << setOptions;
+ testGroup.add() << setOptions << SETSTYLE(0);
+ testGroup.add() << setOptions << SETPAGE(0) << SETSTYLE(0);
+ testGroup.add() << SETPAGE(0) << setOptions << SETSTYLE(0);
+ testGroup.add() << SETPAGE(0) << SETSTYLE(0) << setOptions;
+ testGroup.add() << setOptions << SETSTYLE(0) << SETPAGE(0);
+ testGroup.add() << SETSTYLE(0) << setOptions << SETPAGE(0);
+ testGroup.add() << SETSTYLE(0) << SETPAGE(0) << setOptions;
+ testGroup.createTestRows();
+ }
+
+ foreach (Operation *pageOp, pageOps) {
+ testGroup.reset("testAll 4.1");
+ testGroup.add() << pageOp;
+ testGroup.add() << pageOp << pageOp;
+ testGroup.createTestRows();
+
+ for (int i = 0; i < 2; ++i) {
+ QList<Operation *> optionOps = *setAllOptions.value(i == 1);
+ testGroup.reset("testAll 4.2");
+ testGroup.add() << optionOps << pageOp;
+ testGroup.add() << pageOp << optionOps;
+ testGroup.createTestRows();
+
+ foreach (QWizard::WizardOption option, OptionInfo::instance().options()) {
+ Operation *optionOp = OPT(option, i == 1);
+ testGroup.reset("testAll 4.3");
+ testGroup.add() << optionOp << pageOp;
+ testGroup.add() << pageOp << optionOp;
+ testGroup.createTestRows();
+ }
+ }
+ }
+
+ foreach (Operation *styleOp, styleOps) {
+ testGroup.reset("testAll 5.1");
+ testGroup.add() << styleOp;
+ testGroup.add() << styleOp << styleOp;
+ testGroup.createTestRows();
+
+ for (int i = 0; i < 2; ++i) {
+ QList<Operation *> optionOps = *setAllOptions.value(i == 1);
+ testGroup.reset("testAll 5.2");
+ testGroup.add() << optionOps << styleOp;
+ testGroup.add() << styleOp << optionOps;
+ testGroup.createTestRows();
+
+ foreach (QWizard::WizardOption option, OptionInfo::instance().options()) {
+ Operation *optionOp = OPT(option, i == 1);
+ testGroup.reset("testAll 5.3");
+ testGroup.add() << optionOp << styleOp;
+ testGroup.add() << styleOp << optionOp;
+ testGroup.createTestRows();
+ }
+ }
+ }
+
+ foreach (Operation *pageOp, pageOps) {
+ foreach (Operation *styleOp, styleOps) {
+
+ testGroup.reset("testAll 6.1");
+ testGroup.add() << pageOp;
+ testGroup.add() << pageOp << pageOp;
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 6.2");
+ testGroup.add() << styleOp;
+ testGroup.add() << styleOp << styleOp;
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 6.3");
+ testGroup.add() << pageOp << styleOp;
+ testGroup.add() << styleOp << pageOp;
+ testGroup.createTestRows();
+
+ for (int i = 0; i < 2; ++i) {
+ QList<Operation *> optionOps = *setAllOptions.value(i == 1);
+ testGroup.reset("testAll 6.4");
+ testGroup.add() << optionOps << pageOp << styleOp;
+ testGroup.add() << pageOp << optionOps << styleOp;
+ testGroup.add() << pageOp << styleOp << optionOps;
+ testGroup.add() << optionOps << styleOp << pageOp;
+ testGroup.add() << styleOp << optionOps << pageOp;
+ testGroup.add() << styleOp << pageOp << optionOps;
+ testGroup.createTestRows();
+
+ foreach (QWizard::WizardOption option, OptionInfo::instance().options()) {
+ Operation *optionOp = OPT(option, i == 1);
+ testGroup.reset("testAll 6.5");
+ testGroup.add() << optionOp << pageOp << styleOp;
+ testGroup.add() << pageOp << optionOp << styleOp;
+ testGroup.add() << pageOp << styleOp << optionOp;
+ testGroup.add() << optionOp << styleOp << pageOp;
+ testGroup.add() << styleOp << optionOp << pageOp;
+ testGroup.add() << styleOp << pageOp << optionOp;
+ testGroup.createTestRows();
+ }
+ }
+ }
+ }
+
+ testGroup.reset("testAll 7.1", TestGroup::NonEquality);
+ testGroup.add() << SETPAGE(0);
+ testGroup.add() << SETPAGE(1);
+ testGroup.add() << SETPAGE(2);
+ testGroup.createTestRows();
+
+ testGroup.reset("testAll 7.2", TestGroup::NonEquality);
+ testGroup.add() << SETSTYLE(0);
+ testGroup.add() << SETSTYLE(1);
+ testGroup.add() << SETSTYLE(2);
+ testGroup.createTestRows();
+
+ // more to follow ...
+ }
+
+ // Creates a "small" number of interesting test rows.
+ void createTestRows1()
+ {
+ testGroup.reset("test1 1");
+ testGroup.add() << SETPAGE(0) << SETOPT(QWizard::HaveCustomButton3);
+ testGroup.add() << SETOPT(QWizard::HaveCustomButton3);
+ testGroup.createTestRows();
+
+ testGroup.reset("test1 2");
+ testGroup.add() << SETOPT(QWizard::HaveFinishButtonOnEarlyPages) << SETPAGE(0);
+ testGroup.add() << SETPAGE(0) << SETOPT(QWizard::HaveFinishButtonOnEarlyPages);
+ testGroup.createTestRows();
+
+ testGroup.reset("test1 3");
+ testGroup.add() << SETPAGE(2) << SETOPT(QWizard::HaveNextButtonOnLastPage);
+ testGroup.add() << SETOPT(QWizard::HaveNextButtonOnLastPage) << SETPAGE(2);
+ testGroup.createTestRows();
+ }
+};
+
+// Too much memory usage for testing on CE emulator.
+#ifndef Q_OS_WINCE
+void tst_QWizard::combinations_data()
+{
+ CombinationsTestData combTestData;
+// combTestData.createAllTestRows();
+ combTestData.createTestRows1();
+
+// qDebug() << "test rows:" << combTestData.nRows();
+}
+
+void tst_QWizard::combinations()
+{
+ QFETCH(bool, ref);
+ QFETCH(bool, testEquality);
+ QFETCH(QList<Operation *>, operations);
+
+ TestWizard wizard;
+#if !defined(QT_NO_STYLE_WINDOWSVISTA)
+ if (wizard.wizardStyle() == QWizard::AeroStyle)
+ return; // ### TODO: passes/fails in a unpredictable way, so disable for now
+#endif
+ wizard.applyOperations(operations);
+ wizard.show(); // ### TODO: Required, but why? Should wizard.createImage() care?
+
+ static QImage refImage;
+ static QSize refMinSize;
+ static QString refDescr;
+
+ if (ref) {
+ refImage = wizard.createImage();
+ refMinSize = wizard.minimumSizeHint();
+ refDescr = wizard.operationsDescription();
+ return;
+ }
+
+ QImage image = wizard.createImage();
+
+ bool minSizeTest = wizard.minimumSizeHint() != refMinSize;
+ bool imageTest = image != refImage;
+ QLatin1String otor("!=");
+ QLatin1String reason("differ");
+
+ if (!testEquality) {
+ minSizeTest = false; // the image test is sufficient!
+ imageTest = !imageTest;
+ otor = QLatin1String("==");
+ reason = QLatin1String("are equal");
+ }
+
+ if (minSizeTest)
+ qDebug() << "minimum sizes" << reason.latin1() << ";" << wizard.minimumSizeHint()
+ << otor.latin1() << refMinSize;
+
+ if (imageTest)
+ qDebug() << "images" << reason.latin1();
+
+ if (minSizeTest || imageTest) {
+ qDebug() << "\t row 0 operations:" << refDescr.toLatin1();
+ qDebug() << "\tcurrent row operations:" << wizard.operationsDescription().toLatin1();
+ QVERIFY(false);
+ }
+}
+#endif
+
+class WizardPage : public QWizardPage
+{
+ Q_OBJECT
+ bool shown_;
+ void showEvent(QShowEvent *) { shown_ = true; }
+ void hideEvent(QHideEvent *) { shown_ = false; }
+public:
+ WizardPage() : shown_(false) {}
+ bool shown() const { return shown_; }
+};
+
+class WizardPages
+{
+ QList<WizardPage *> pages;
+public:
+ void add(WizardPage *page) { pages << page; }
+ QList<WizardPage *> all() const { return pages; }
+ QList<WizardPage *> shown() const
+ {
+ QList<WizardPage *> result;
+ foreach (WizardPage *page, pages)
+ if (page->shown())
+ result << page;
+ return result;
+ }
+};
+
+void tst_QWizard::showCurrentPageOnly()
+{
+ QWizard wizard;
+ WizardPages pages;
+ for (int i = 0; i < 5; ++i) {
+ pages.add(new WizardPage);
+ wizard.addPage(pages.all().last());
+ }
+
+ wizard.show();
+
+ QCOMPARE(pages.shown().count(), 1);
+ QCOMPARE(pages.shown().first(), pages.all().first());
+
+ const int steps = 2;
+ for (int i = 0; i < steps; ++i)
+ wizard.next();
+
+ QCOMPARE(pages.shown().count(), 1);
+ QCOMPARE(pages.shown().first(), pages.all().at(steps));
+
+ wizard.restart();
+
+ QCOMPARE(pages.shown().count(), 1);
+ QCOMPARE(pages.shown().first(), pages.all().first());
+}
+
+void tst_QWizard::setButtonText()
+{
+ QWizard wizard;
+ wizard.setWizardStyle(QWizard::ClassicStyle);
+ QWizardPage* page1 = new QWizardPage;
+ QWizardPage* page2 = new QWizardPage;
+ wizard.addPage(page1);
+ wizard.addPage(page2);
+
+ wizard.show();
+ qApp->processEvents();
+ QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next"));
+ QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next"));
+ QVERIFY(page1->buttonText(QWizard::NextButton).contains("Next"));
+ QVERIFY(page2->buttonText(QWizard::NextButton).contains("Next"));
+
+ page2->setButtonText(QWizard::NextButton, "Page2");
+ QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next"));
+ QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next"));
+ QVERIFY(page1->buttonText(QWizard::NextButton).contains("Next"));
+ QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2"));
+
+ wizard.next();
+ qApp->processEvents();
+ QCOMPARE(wizard.button(QWizard::NextButton)->text(), QString("Page2"));
+ QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next"));
+ QVERIFY(page1->buttonText(QWizard::NextButton).contains("Next"));
+ QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2"));
+
+ wizard.back();
+ qApp->processEvents();
+ QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Next"));
+ QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Next"));
+ QVERIFY(page1->buttonText(QWizard::NextButton).contains("Next"));
+ QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2"));
+
+ wizard.setButtonText(QWizard::NextButton, "Wizard");
+ QVERIFY(wizard.button(QWizard::NextButton)->text().contains("Wizard"));
+ QCOMPARE(wizard.buttonText(QWizard::NextButton), QString("Wizard"));
+ QCOMPARE(page1->buttonText(QWizard::NextButton), QString("Wizard"));
+ QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2"));
+
+ wizard.next();
+ qApp->processEvents();
+ QCOMPARE(wizard.button(QWizard::NextButton)->text(), QString("Page2"));
+ QVERIFY(wizard.buttonText(QWizard::NextButton).contains("Wizard"));
+ QCOMPARE(page1->buttonText(QWizard::NextButton), QString("Wizard"));
+ QCOMPARE(page2->buttonText(QWizard::NextButton), QString("Page2"));
+}
+
+void tst_QWizard::setCommitPage()
+{
+ QWizard wizard;
+ QWizardPage* page1 = new QWizardPage;
+ QWizardPage* page2 = new QWizardPage;
+ wizard.addPage(page1);
+ wizard.addPage(page2);
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(!page1->isCommitPage());
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.next();
+ QVERIFY(wizard.button(QWizard::BackButton)->isEnabled());
+
+ page1->setCommitPage(true);
+ QVERIFY(page1->isCommitPage());
+
+ wizard.back();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.next();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ page1->setCommitPage(false);
+ QVERIFY(!page1->isCommitPage());
+
+ wizard.back();
+ QVERIFY(!wizard.button(QWizard::BackButton)->isEnabled());
+
+ wizard.next();
+ QVERIFY(wizard.button(QWizard::BackButton)->isEnabled());
+
+ // ### test relabeling of the Cancel button to "Close" once this is implemented
+}
+
+void tst_QWizard::setWizardStyle()
+{
+ QWizard wizard;
+ wizard.addPage(new QWizardPage);
+ wizard.show();
+ qApp->processEvents();
+
+ // defaults
+ const bool styleHintMatch =
+ wizard.wizardStyle() ==
+ QWizard::WizardStyle(wizard.style()->styleHint(QStyle::SH_WizardStyle, 0, &wizard));
+#if !defined(QT_NO_STYLE_WINDOWSVISTA)
+ QVERIFY(styleHintMatch || wizard.wizardStyle() == QWizard::AeroStyle);
+#else
+ QVERIFY(styleHintMatch);
+#endif
+
+ // set/get consistency
+ for (int wstyle = 0; wstyle < QWizard::NStyles; ++wstyle) {
+ wizard.setWizardStyle((QWizard::WizardStyle)wstyle);
+ QCOMPARE((int)wizard.wizardStyle(), wstyle);
+ }
+}
+
+void tst_QWizard::removePage()
+{
+ QWizard wizard;
+ QWizardPage *page0 = new QWizardPage;
+ QWizardPage *page1 = new QWizardPage;
+ QWizardPage *page2 = new QWizardPage;
+ QWizardPage *page3 = new QWizardPage;
+ QSignalSpy spy(&wizard, SIGNAL(pageRemoved(int)));
+
+ wizard.setPage(0, page0);
+ wizard.setPage(1, page1);
+ wizard.setPage(2, page2);
+ wizard.setPage(3, page3);
+
+ wizard.restart();
+ QCOMPARE(wizard.pageIds().size(), 4);
+ QCOMPARE(wizard.visitedPages().size(), 1);
+ QCOMPARE(spy.count(), 0);
+
+ // Removing a non-existent page
+ wizard.removePage(4);
+ QCOMPARE(wizard.pageIds().size(), 4);
+ QCOMPARE(spy.count(), 0);
+
+ // Removing and then reinserting a page
+ QCOMPARE(wizard.pageIds().size(), 4);
+ QVERIFY(wizard.pageIds().contains(2));
+ wizard.removePage(2);
+ QCOMPARE(spy.count(), 1);
+ QList<QVariant> arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 2);
+ QCOMPARE(wizard.pageIds().size(), 3);
+ QVERIFY(!wizard.pageIds().contains(2));
+ wizard.setPage(2, page2);
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(wizard.pageIds().size(), 4);
+ QVERIFY(wizard.pageIds().contains(2));
+
+ // Removing the same page twice
+ wizard.removePage(2); // restore
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 2);
+ QCOMPARE(wizard.pageIds().size(), 3);
+ QVERIFY(!wizard.pageIds().contains(2));
+ wizard.removePage(2);
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(wizard.pageIds().size(), 3);
+ QVERIFY(!wizard.pageIds().contains(2));
+
+ // Removing a page not in the history
+ wizard.setPage(2, page2); // restore
+ wizard.restart();
+ wizard.next();
+ QCOMPARE(wizard.visitedPages().size(), 2);
+ QCOMPARE(wizard.currentPage(), page1);
+ QCOMPARE(spy.count(), 0);
+ wizard.removePage(2);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 2);
+ QCOMPARE(wizard.visitedPages().size(), 2);
+ QVERIFY(!wizard.pageIds().contains(2));
+ QCOMPARE(wizard.currentPage(), page1);
+
+ // Removing a page in the history before the current page
+ wizard.setPage(2, page2); // restore
+ wizard.restart();
+ wizard.next();
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(wizard.visitedPages().size(), 2);
+ QCOMPARE(wizard.currentPage(), page1);
+ wizard.removePage(0);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 0);
+ QCOMPARE(wizard.visitedPages().size(), 1);
+ QVERIFY(!wizard.visitedPages().contains(0));
+ QVERIFY(!wizard.pageIds().contains(0));
+ QCOMPARE(wizard.currentPage(), page1);
+
+ // Remove the current page which is not the first one in the history
+ wizard.setPage(0, page0); // restore
+ wizard.restart();
+ wizard.next();
+ QCOMPARE(spy.count(), 0);
+ QCOMPARE(wizard.visitedPages().size(), 2);
+ QCOMPARE(wizard.currentPage(), page1);
+ wizard.removePage(1);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 1);
+ QCOMPARE(wizard.visitedPages().size(), 1);
+ QVERIFY(!wizard.visitedPages().contains(1));
+ QVERIFY(!wizard.pageIds().contains(1));
+ QCOMPARE(wizard.currentPage(), page0);
+
+ // Remove the current page which is the first (and only) one in the history
+ wizard.removePage(0);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 0);
+ QCOMPARE(wizard.visitedPages().size(), 1);
+ QVERIFY(!wizard.visitedPages().contains(0));
+ QCOMPARE(wizard.pageIds().size(), 2);
+ QVERIFY(!wizard.pageIds().contains(0));
+ QCOMPARE(wizard.currentPage(), page2);
+ //
+ wizard.removePage(2);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 2);
+ QCOMPARE(wizard.visitedPages().size(), 1);
+ QVERIFY(!wizard.visitedPages().contains(2));
+ QCOMPARE(wizard.pageIds().size(), 1);
+ QVERIFY(!wizard.pageIds().contains(2));
+ QCOMPARE(wizard.currentPage(), page3);
+ //
+ wizard.removePage(3);
+ QCOMPARE(spy.count(), 1);
+ arguments = spy.takeFirst();
+ QCOMPARE(arguments.at(0).toInt(), 3);
+ QVERIFY(wizard.visitedPages().empty());
+ QVERIFY(wizard.pageIds().empty());
+ QCOMPARE(wizard.currentPage(), static_cast<QWizardPage *>(0));
+}
+
+void tst_QWizard::sideWidget()
+{
+ QWizard wizard;
+
+ wizard.setSideWidget(0);
+ QVERIFY(wizard.sideWidget() == 0);
+ QWidget *w1 = new QWidget(&wizard);
+ wizard.setSideWidget(w1);
+ QVERIFY(wizard.sideWidget() == w1);
+ QWidget *w2 = new QWidget(&wizard);
+ wizard.setSideWidget(w2);
+ QVERIFY(wizard.sideWidget() == w2);
+ QVERIFY(w1->parent() != 0);
+ QCOMPARE(w1->window(), static_cast<QWidget *>(&wizard));
+ QCOMPARE(w2->window(), static_cast<QWidget *>(&wizard));
+ w1->setParent(0);
+ wizard.setSideWidget(0);
+ QVERIFY(wizard.sideWidget() == 0);
+}
+
+void tst_QWizard::task161660_buttonSpacing()
+{
+#ifndef QT_NO_STYLE_PLASTIQUE
+ QString origStyle = QApplication::style()->objectName();
+ QApplication::setStyle(new QPlastiqueStyle);
+ QWizard wizard;
+ wizard.addPage(new QWizardPage);
+ wizard.show();
+ const QAbstractButton *finishButton = wizard.button(QWizard::FinishButton);
+ const QAbstractButton *cancelButton = wizard.button(QWizard::CancelButton);
+ const int spacing = cancelButton->geometry().left() - finishButton->geometry().right() - 1;
+ QCOMPARE(spacing, wizard.style()->layoutSpacing(
+ QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal));
+ QApplication::setStyle(origStyle);
+#endif
+}
+
+class task177716_CommitPage : public QWizardPage
+{
+ Q_OBJECT
+public:
+ task177716_CommitPage()
+ {
+ setCommitPage(true);
+ QVBoxLayout *layout = new QVBoxLayout;
+ ledit = new QLineEdit(this);
+ registerField("foo*", ledit);
+ layout->addWidget(ledit);
+ setLayout(layout);
+ }
+ QLineEdit *ledit;
+};
+
+void tst_QWizard::task177716_disableCommitButton()
+{
+ QWizard wizard;
+ task177716_CommitPage *commitPage = new task177716_CommitPage;
+ wizard.addPage(commitPage);
+ // the following page must be there to prevent the first page from replacing the Commit button
+ // with the Finish button:
+ wizard.addPage(new QWizardPage);
+ wizard.show();
+ QVERIFY(!wizard.button(QWizard::CommitButton)->isEnabled());
+ commitPage->ledit->setText("some non-empty text");
+ QVERIFY(wizard.button(QWizard::CommitButton)->isEnabled());
+ commitPage->ledit->setText("");
+ QVERIFY(!wizard.button(QWizard::CommitButton)->isEnabled());
+}
+
+class WizardPage_task183550 : public QWizardPage
+{
+public:
+ WizardPage_task183550(QWidget *parent = 0)
+ : QWizardPage(parent)
+ , treeWidget(new QTreeWidget)
+ , verticalPolicy(QSizePolicy::MinimumExpanding) {}
+ void enableVerticalExpansion() { verticalPolicy = QSizePolicy::MinimumExpanding; }
+ void disableVerticalExpansion() { verticalPolicy = QSizePolicy::Preferred; }
+ int treeWidgetHeight() const { return treeWidget->height(); }
+ int treeWidgetSizeHintHeight() const { return treeWidget->sizeHint().height(); }
+
+private:
+ QTreeWidget *treeWidget;
+ QSizePolicy::Policy verticalPolicy;
+
+ void initializePage()
+ {
+ if (layout())
+ delete layout();
+ if (treeWidget)
+ delete treeWidget;
+
+ QLayout *layout_ = new QVBoxLayout(this);
+ layout_->addWidget(treeWidget = new QTreeWidget);
+
+ QSizePolicy policy = sizePolicy();
+ policy.setVerticalPolicy(verticalPolicy);
+ treeWidget->setSizePolicy(policy);
+ }
+};
+
+void tst_QWizard::task183550_stretchFactor()
+{
+ QWizard wizard;
+ WizardPage_task183550 *page1 = new WizardPage_task183550;
+ WizardPage_task183550 *page2 = new WizardPage_task183550;
+ wizard.addPage(page1);
+ wizard.addPage(page2);
+ wizard.resize(500, 2 * page2->treeWidgetSizeHintHeight());
+ wizard.show();
+
+ QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page1));
+
+ // ----
+ page2->disableVerticalExpansion();
+ wizard.next();
+ QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page2));
+ QVERIFY(page2->treeWidgetHeight() == page2->treeWidgetSizeHintHeight());
+
+ wizard.back();
+ QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page1));
+
+ // ----
+ page2->enableVerticalExpansion();
+ wizard.next();
+ QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page2));
+ QVERIFY(page2->treeWidgetHeight() > page2->treeWidgetSizeHintHeight());
+
+ wizard.back();
+ QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page1));
+
+ // ----
+ page2->disableVerticalExpansion();
+ wizard.next();
+ QCOMPARE(wizard.currentPage(), static_cast<QWizardPage*>(page2));
+ QVERIFY(page2->treeWidgetHeight() == page2->treeWidgetSizeHintHeight());
+}
+
+void tst_QWizard::task161658_alignments()
+{
+ QWizard wizard;
+ wizard.setWizardStyle(QWizard::MacStyle);
+
+ QWizardPage page;
+ page.setTitle("Title");
+ page.setSubTitle("SUBTITLE#: The subtitle bust be alligned with the rest of the widget");
+
+ QLabel label1("Field:");
+ QLineEdit lineEdit1;
+ QGridLayout *layout = new QGridLayout;
+ layout->addWidget(&label1, 0, 0);
+ layout->addWidget(&lineEdit1, 0, 1);
+ page.setLayout(layout);
+
+ int idx = wizard.addPage(&page);
+ wizard.setStartId(idx);
+ wizard.show();
+ QTest::qWait(100);
+
+ foreach (QLabel *subtitleLabel, qFindChildren<QLabel *>(&wizard)) {
+ if (subtitleLabel->text().startsWith("SUBTITLE#")) {
+ QCOMPARE(lineEdit1.mapToGlobal(lineEdit1.contentsRect().bottomRight()).x(),
+ subtitleLabel->mapToGlobal(subtitleLabel->contentsRect().bottomRight()).x());
+ return;
+ }
+ }
+ QFAIL("Subtitle label not found");
+}
+
+void tst_QWizard::task177022_setFixedSize()
+{
+ int width = 300;
+ int height = 200;
+ QWizard wiz;
+ QWizardPage page1;
+ QWizardPage page2;
+ int page1_id = wiz.addPage(&page1);
+ int page2_id = wiz.addPage(&page2);
+ wiz.setFixedSize(width, height);
+ if (wiz.wizardStyle() == QWizard::AeroStyle)
+ QEXPECT_FAIL("", "this probably relates to non-client area hack for AeroStyle titlebar "
+ "effect; not sure if it qualifies as a bug or not", Continue);
+ QCOMPARE(wiz.size(), QSize(width, height));
+ QCOMPARE(wiz.minimumWidth(), width);
+ QCOMPARE(wiz.minimumHeight(), height);
+ QCOMPARE(wiz.maximumWidth(), width);
+ QCOMPARE(wiz.maximumHeight(), height);
+
+ wiz.show();
+ QTest::qWait(100);
+ QCOMPARE(wiz.size(), QSize(width, height));
+ QCOMPARE(wiz.minimumWidth(), width);
+ QCOMPARE(wiz.minimumHeight(), height);
+ QCOMPARE(wiz.maximumWidth(), width);
+ QCOMPARE(wiz.maximumHeight(), height);
+
+ wiz.next();
+ QTest::qWait(100);
+ QCOMPARE(wiz.size(), QSize(width, height));
+ QCOMPARE(wiz.minimumWidth(), width);
+ QCOMPARE(wiz.minimumHeight(), height);
+ QCOMPARE(wiz.maximumWidth(), width);
+ QCOMPARE(wiz.maximumHeight(), height);
+
+ wiz.removePage(page1_id);
+ wiz.removePage(page2_id);
+}
+
+void tst_QWizard::task248107_backButton()
+{
+ QWizard wizard;
+ QWizardPage page1;
+ QWizardPage page2;
+ QWizardPage page3;
+ QWizardPage page4;
+ wizard.addPage(&page1);
+ wizard.addPage(&page2);
+ wizard.addPage(&page3);
+ wizard.addPage(&page4);
+
+ wizard.show();
+ QTest::qWait(100);
+ QCOMPARE(wizard.currentPage(), &page1);
+
+ QTest::mouseClick(wizard.button(QWizard::NextButton), Qt::LeftButton);
+ QCOMPARE(wizard.currentPage(), &page2);
+
+ QTest::mouseClick(wizard.button(QWizard::NextButton), Qt::LeftButton);
+ QCOMPARE(wizard.currentPage(), &page3);
+
+ QTest::mouseClick(wizard.button(QWizard::NextButton), Qt::LeftButton);
+ QCOMPARE(wizard.currentPage(), &page4);
+
+ QTest::mouseClick(wizard.button(QWizard::BackButton), Qt::LeftButton);
+ QCOMPARE(wizard.currentPage(), &page3);
+
+ QTest::mouseClick(wizard.button(QWizard::BackButton), Qt::LeftButton);
+ QCOMPARE(wizard.currentPage(), &page2);
+
+ QTest::mouseClick(wizard.button(QWizard::BackButton), Qt::LeftButton);
+ QCOMPARE(wizard.currentPage(), &page1);
+}
+
+class WizardPage_task255350 : public QWizardPage
+{
+public:
+ QLineEdit *lineEdit;
+ WizardPage_task255350()
+ : lineEdit(new QLineEdit)
+ {
+ registerField("dummy*", lineEdit);
+ }
+};
+
+void tst_QWizard::task255350_fieldObjectDestroyed()
+{
+ QWizard wizard;
+ WizardPage_task255350 *page = new WizardPage_task255350;
+ int id = wizard.addPage(page);
+ delete page->lineEdit;
+ wizard.removePage(id); // don't crash!
+ delete page;
+}
+
+QTEST_MAIN(tst_QWizard)
+#include "tst_qwizard.moc"