diff -r 4f2786c97bf4 -r 14fcccfb4c0c qt/qapplication/smoketest_qapplication.cpp --- a/qt/qapplication/smoketest_qapplication.cpp Fri Jun 11 11:44:06 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2202 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 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$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, 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. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -//#define QT_TST_QAPP_DEBUG -#include - -#include - -#include "qabstracteventdispatcher.h" -#include - -#include "private/qapplication_p.h" -#include "private/qstylesheetstyle_p.h" -#ifdef Q_OS_WINCE -#include -#endif -#ifdef Q_OS_SYMBIAN -#include -#endif - -//TESTED_CLASS= -//TESTED_FILES= - -#if defined(Q_OS_SYMBIAN) -// In Symbian, the PluginsPath doesn't specify the only absolute path; just the dir that can be found on any drive -/*static void addExpectedSymbianPluginsPath(QStringList& expected) -{ - QString installPathPlugins = QDir::fromNativeSeparators(QLibraryInfo::location(QLibraryInfo::PluginsPath)); - QFileInfoList driveList = QDir::drives(); - QListIterator iter(driveList); - while (iter.hasNext()) { - QFileInfo testFi(iter.next().canonicalPath().append(installPathPlugins)); - if (testFi.exists()) - expected << testFi.canonicalFilePath(); - } -} -*/ -#endif - -class tst_QApplication : public QObject -{ -Q_OBJECT - -public: - tst_QApplication(); - virtual ~tst_QApplication(); - -public slots: - void init(); - void cleanup(); -private slots: - /*void sendEventsOnProcessEvents(); // this must be the first test - void getSetCheck(); - void staticSetup(); - - void alert(); - - void multiple_data(); - void multiple(); - - void nonGui(); - - void setFont_data(); - void setFont(); - - void args_data(); - void args(); - - void lastWindowClosed(); - void quitOnLastWindowClosed(); - void testDeleteLater(); - void testDeleteLaterProcessEvents(); - - void libraryPaths(); - void libraryPaths_qt_plugin_path(); - void libraryPaths_qt_plugin_path_2(); - - void sendPostedEvents(); - - void thread(); - void desktopSettingsAware();*/ - - void setActiveWindow(); - - /*void focusChanged(); - void focusOut(); - - void execAfterExit(); - - void wheelScrollLines(); - - void task109149(); - - void style(); - - void allWidgets(); - void topLevelWidgets(); - - void setAttribute(); - - void windowsCommandLine_data(); - void windowsCommandLine(); - - void touchEventPropagation(); - - void symbianNoApplicationPanes(); - - void symbianNeedForTraps(); - void symbianLeaveThroughMain();*/ -}; - -/*class EventSpy : public QObject -{ - Q_OBJECT - -public: - QList recordedEvents; - bool eventFilter(QObject *, QEvent *event) - { - recordedEvents.append(event->type()); - return false; - } -}; -*/ - -/* -void tst_QApplication::sendEventsOnProcessEvents() -{ - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); - - EventSpy spy; - app.installEventFilter(&spy); - - QCoreApplication::postEvent(&app, new QEvent(QEvent::Type(QEvent::User + 1))); - QCoreApplication::processEvents(); - QVERIFY(spy.recordedEvents.contains(QEvent::User + 1)); -} - -class MyInputContext : public QInputContext -{ -public: - MyInputContext() : QInputContext() {} - QString identifierName() { return QString("NoName"); } - QString language() { return QString("NoLanguage"); } - void reset() {} - bool isComposing() const { return false; } -}; - -// Testing get/set functions -void tst_QApplication::getSetCheck() -{ - int argc = 0; - QApplication obj1(argc, 0, QApplication::GuiServer); - // QInputContext * QApplication::inputContext() - // void QApplication::setInputContext(QInputContext *) - MyInputContext *var1 = new MyInputContext; - obj1.setInputContext(var1); - QCOMPARE((QInputContext *)var1, obj1.inputContext()); - QTest::ignoreMessage(QtWarningMsg, "QApplication::setInputContext: called with 0 input context"); - obj1.setInputContext((QInputContext *)0); - QCOMPARE((QInputContext *)var1, obj1.inputContext()); - // delete var1; // No delete, since QApplication takes ownership -} - -class CloseEventTestWindow : public QWidget -{ -public: - CloseEventTestWindow(QWidget *parent = 0) - : QWidget(parent) - { - } - - void closeEvent(QCloseEvent *event) - { - QWidget dialog; - dialog.show(); - dialog.close(); - - hide(); - event->ignore(); - } -}; -*/ - -static char *argv0; - -tst_QApplication::tst_QApplication() -{ -#ifdef Q_OS_WINCE - // Clean up environment previously to launching test - qputenv("QT_PLUGIN_PATH", QByteArray()); -#endif -} - -tst_QApplication::~tst_QApplication() -{ - -} - -void tst_QApplication::init() -{ -// TODO: Add initialization code here. -// This will be executed immediately before each test is run. -} - -void tst_QApplication::cleanup() -{ -// TODO: Add cleanup code here. -// This will be executed immediately after each test is run. -} - -/* -void tst_QApplication::staticSetup() -{ - QVERIFY(!qApp); - - QStyle *style = QStyleFactory::create(QLatin1String("Windows")); - QVERIFY(style); - QApplication::setStyle(style); - - QPalette pal; - QApplication::setPalette(pal); - - //QFont font; - //QApplication::setFont(font); - - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); -} - - -// QApp subclass that exits the event loop after 150ms -class TestApplication : public QApplication -{ -public: - TestApplication( int &argc, char **argv ) - : QApplication( argc, argv, QApplication::GuiServer ) - { - startTimer( 150 ); - } - - void timerEvent( QTimerEvent * ) - { - quit(); - } -}; - -void tst_QApplication::alert() -{ - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); - app.alert(0, 0); - - QWidget widget; - QWidget widget2; - app.alert(&widget, 100); - widget.show(); - widget2.show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&widget); - qt_x11_wait_for_window_manager(&widget2); -#endif - QTest::qWait(100); - app.alert(&widget, -1); - app.alert(&widget, 250); - widget2.activateWindow(); - QApplication::setActiveWindow(&widget2); - app.alert(&widget, 0); - widget.activateWindow(); - QApplication::setActiveWindow(&widget); - app.alert(&widget, 200); - app.syncX(); -} - -void tst_QApplication::multiple_data() -{ - QTest::addColumn("features"); - - // return a list of things to try - QTest::newRow( "data0" ) << QStringList( "" ); - QTest::newRow( "data1" ) << QStringList( "QFont" ); - QTest::newRow( "data2" ) << QStringList( "QPixmap" ); - QTest::newRow( "data3" ) << QStringList( "QWidget" ); -} - -void tst_QApplication::multiple() -{ - QFETCH(QStringList,features); - - int i = 0; - int argc = 0; - while ( i++ < 5 ) { - TestApplication app( argc, 0 ); - - if ( features.contains( "QFont" ) ) { - // create font and force loading - QFont font( "Arial", 12 ); - QFontInfo finfo( font ); - finfo.exactMatch(); - } - if ( features.contains( "QPixmap" ) ) { - QPixmap pix( 100, 100 ); - pix.fill( Qt::black ); - } - if ( features.contains( "QWidget" ) ) { - QWidget widget; - } - - QVERIFY(!app.exec()); - } -} - -void tst_QApplication::nonGui() -{ -#ifdef Q_OS_HPUX - // ### This is only to allow us to generate a test report for now. - QSKIP("This test shuts down the window manager on HP-UX.", SkipAll); -#endif - - int argc = 0; - QApplication app(argc, 0, false); - QCOMPARE(qApp, &app); -} - -void tst_QApplication::setFont_data() -{ - QTest::addColumn("family"); - QTest::addColumn("pointsize"); - QTest::addColumn("beforeAppConstructor"); - - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); // Needed for QFontDatabase - - int cnt = 0; - QFontDatabase fdb; - QStringList families = fdb.families(); - for (QStringList::const_iterator itr = families.begin(); - itr != families.end(); - ++itr) { - if (cnt < 3) { - QString family = *itr; - QStringList styles = fdb.styles(family); - if (styles.size() > 0) { - QString style = styles.first(); - QList sizes = fdb.pointSizes(family, style); - if (!sizes.size()) - sizes = fdb.standardSizes(); - if (sizes.size() > 0) { - QTest::newRow(QString("data%1a").arg(cnt).toLatin1().constData()) - << family - << sizes.first() - << false; - QTest::newRow(QString("data%1b").arg(cnt).toLatin1().constData()) - << family - << sizes.first() - << true; - } - } - } - ++cnt; - } - - QTest::newRow("nonexistingfont") << "nosuchfont_probably_quiteunlikely" - << 0 << false; - QTest::newRow("nonexistingfont") << "nosuchfont_probably_quiteunlikely" - << 0 << true; - - QTest::newRow("largescaleable") << "smoothtimes" << 100 << false; - QTest::newRow("largescaleable") << "smoothtimes" << 100 << true; - - QTest::newRow("largeunscaleale") << "helvetica" << 100 << false; - QTest::newRow("largeunscaleale") << "helvetica" << 100 << true; -} - -void tst_QApplication::setFont() -{ - QFETCH( QString, family ); - QFETCH( int, pointsize ); - QFETCH( bool, beforeAppConstructor ); - - QFont font( family, pointsize ); - if (beforeAppConstructor) { - QApplication::setFont( font ); - QCOMPARE(QApplication::font(), font); - } - - int argc = 0; - QApplication app( argc, 0, QApplication::GuiServer ); - if (!beforeAppConstructor) - QApplication::setFont( font ); - - QCOMPARE( app.font(), font ); -} - -void tst_QApplication::args_data() -{ - QTest::addColumn("argc_in"); - QTest::addColumn("args_in"); - QTest::addColumn("argc_out"); - QTest::addColumn("args_out"); - - QTest::newRow( "App name" ) << 1 << "/usr/bin/appname" << 1 << "/usr/bin/appname"; - QTest::newRow( "No arguments" ) << 0 << QString() << 0 << QString(); - QTest::newRow( "App name, style" ) << 3 << "/usr/bin/appname -style motif" << 1 << "/usr/bin/appname"; - QTest::newRow( "App name, style, arbitrary, reverse" ) << 5 << "/usr/bin/appname -style motif -arbitrary -reverse" - << 2 << "/usr/bin/appname -arbitrary"; -} - -void tst_QApplication::task109149() -{ - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); - QApplication::setFont(QFont("helvetica", 100)); - - QWidget w; - w.setWindowTitle("hello"); - w.show(); - - app.processEvents(); -} - -static char ** QString2cstrings( const QString &args ) -{ - static QList cache; - - int i; - char **argarray = 0; - QStringList list = args.split(' ');; - argarray = new char*[list.count()+1]; - - for (i = 0; i < (int)list.count(); ++i ) { - QByteArray l1 = list[i].toLatin1(); - argarray[i] = l1.data(); - cache.append(l1); - } - argarray[i] = 0; - - return argarray; -} - -static QString cstrings2QString( char **args ) -{ - QString string; - if ( !args ) - return string; - - int i = 0; - while ( args[i] ) { - string += args[i]; - if ( args[i+1] ) - string += " "; - ++i; - } - return string; -} - -void tst_QApplication::args() -{ - QFETCH( int, argc_in ); - QFETCH( QString, args_in ); - QFETCH( int, argc_out ); - QFETCH( QString, args_out ); - - char **argv = QString2cstrings( args_in ); - - QApplication app( argc_in, argv, QApplication::GuiServer ); - QString argv_out = cstrings2QString(argv); - - QCOMPARE( argc_in, argc_out ); - QCOMPARE( argv_out, args_out ); - - delete [] argv; -} - -class CloseWidget : public QWidget -{ - Q_OBJECT -public: - CloseWidget() - { - startTimer(500); - } - -protected: - void timerEvent(QTimerEvent *) - { - close(); - } - -}; - -void tst_QApplication::lastWindowClosed() -{ - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); - - QSignalSpy spy(&app, SIGNAL(lastWindowClosed())); - - QPointer dialog = new QDialog; - QVERIFY(dialog->testAttribute(Qt::WA_QuitOnClose)); - QTimer::singleShot(1000, dialog, SLOT(accept())); - dialog->exec(); - QVERIFY(dialog); - QCOMPARE(spy.count(), 0); - - QPointerwidget = new CloseWidget; - QVERIFY(widget->testAttribute(Qt::WA_QuitOnClose)); - QObject::connect(&app, SIGNAL(lastWindowClosed()), widget, SLOT(deleteLater())); - app.exec(); - QVERIFY(!widget); - QCOMPARE(spy.count(), 1); - spy.clear(); - -#if 0 - // everything is closed, so doing this should not emit lastWindowClosed() again - QMetaObject::invokeMethod(dialog, "close", Qt::QueuedConnection); - QTimer::singleShot(1000, &app, SLOT(quit())); - app.exec(); - QCOMPARE(spy.count(), 0); -#endif - - delete dialog; - - // show 3 windows, close them, should only get lastWindowClosed once - QWidget w1; - QWidget w2; - QWidget w3; - w1.show(); - w2.show(); - w3.show(); - - QTimer::singleShot(1000, &app, SLOT(closeAllWindows())); - app.exec(); - QCOMPARE(spy.count(), 1); -} - -class QuitOnLastWindowClosedDialog : public QDialog -{ - Q_OBJECT -public: - QPushButton *okButton; - - QuitOnLastWindowClosedDialog() - { - QHBoxLayout *hbox = new QHBoxLayout(this); - okButton = new QPushButton("&ok", this); - - hbox->addWidget(okButton); - connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); - connect(okButton, SIGNAL(clicked()), this, SLOT(ok_clicked())); - } - -public slots: - void ok_clicked() - { - QDialog other; - - QTimer timer; - connect(&timer, SIGNAL(timeout()), &other, SLOT(accept())); - QSignalSpy spy(&timer, SIGNAL(timeout())); - QSignalSpy appSpy(qApp, SIGNAL(lastWindowClosed())); - - timer.start(1000); - other.exec(); - - // verify that the eventloop ran and let the timer fire - QCOMPARE(spy.count(), 1); - QCOMPARE(appSpy.count(), 1); - } -}; - -class QuitOnLastWindowClosedWindow : public QWidget -{ - Q_OBJECT - -public: - QuitOnLastWindowClosedWindow() - { } - -public slots: - void execDialogThenShow() - { - QDialog dialog; - QTimer timer1; - connect(&timer1, SIGNAL(timeout()), &dialog, SLOT(accept())); - QSignalSpy spy1(&timer1, SIGNAL(timeout())); - timer1.setSingleShot(true); - timer1.start(1000); - dialog.exec(); - QCOMPARE(spy1.count(), 1); - - show(); - } -}; - -void tst_QApplication::quitOnLastWindowClosed() -{ - { - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); - - QuitOnLastWindowClosedDialog d; - d.show(); - QTimer::singleShot(1000, d.okButton, SLOT(animateClick())); - - QSignalSpy appSpy(&app, SIGNAL(lastWindowClosed())); - app.exec(); - - // lastWindowClosed() signal should only be sent after the last dialog is closed - QCOMPARE(appSpy.count(), 2); - } - { - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); - QSignalSpy appSpy(&app, SIGNAL(lastWindowClosed())); - - QDialog dialog; - QTimer timer1; - connect(&timer1, SIGNAL(timeout()), &dialog, SLOT(accept())); - QSignalSpy spy1(&timer1, SIGNAL(timeout())); - timer1.setSingleShot(true); - timer1.start(1000); - dialog.exec(); - QCOMPARE(spy1.count(), 1); - QCOMPARE(appSpy.count(), 0); - - QTimer timer2; - connect(&timer2, SIGNAL(timeout()), &app, SLOT(quit())); - QSignalSpy spy2(&timer2, SIGNAL(timeout())); - timer2.setSingleShot(true); - timer2.start(1000); - int returnValue = app.exec(); - QCOMPARE(returnValue, 0); - QCOMPARE(spy2.count(), 1); - QCOMPARE(appSpy.count(), 0); - } - { - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); - QTimer timer; - timer.setInterval(100); - - QSignalSpy spy(&app, SIGNAL(aboutToQuit())); - QSignalSpy spy2(&timer, SIGNAL(timeout())); - - QPointer mainWindow = new QMainWindow; - QPointer dialog = new QDialog(mainWindow); - - QVERIFY(app.quitOnLastWindowClosed()); - QVERIFY(mainWindow->testAttribute(Qt::WA_QuitOnClose)); - QVERIFY(dialog->testAttribute(Qt::WA_QuitOnClose)); - - mainWindow->show(); - dialog->show(); - - timer.start(); - QTimer::singleShot(1000, mainWindow, SLOT(close())); // This should quit the application - QTimer::singleShot(2000, &app, SLOT(quit())); // This makes sure we quit even if it didn't - - app.exec(); - - QCOMPARE(spy.count(), 1); - QVERIFY(spy2.count() < 15); // Should be around 10 if closing caused the quit - } - { - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); - QTimer timer; - timer.setInterval(100); - - QSignalSpy spy(&app, SIGNAL(aboutToQuit())); - QSignalSpy spy2(&timer, SIGNAL(timeout())); - - QPointer mainWindow = new QMainWindow; - QPointer invisibleTopLevelWidget = new QWidget; - invisibleTopLevelWidget->setAttribute(Qt::WA_DontShowOnScreen); - - QVERIFY(app.quitOnLastWindowClosed()); - QVERIFY(mainWindow->testAttribute(Qt::WA_QuitOnClose)); - QVERIFY(invisibleTopLevelWidget->testAttribute(Qt::WA_QuitOnClose)); - QVERIFY(invisibleTopLevelWidget->testAttribute(Qt::WA_DontShowOnScreen)); - - mainWindow->show(); - invisibleTopLevelWidget->show(); - - timer.start(); - QTimer::singleShot(1000, mainWindow, SLOT(close())); // This should quit the application - QTimer::singleShot(2000, &app, SLOT(quit())); // This makes sure we quit even if it didn't - - app.exec(); - - QCOMPARE(spy.count(), 1); - QVERIFY(spy2.count() < 15); // Should be around 10 if closing caused the quit - } - { - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); - QTimer timer; - timer.setInterval(100); - - QSignalSpy spy(&app, SIGNAL(aboutToQuit())); - QSignalSpy spy2(&timer, SIGNAL(timeout())); - - QPointer mainWindow = new CloseEventTestWindow; - - QVERIFY(app.quitOnLastWindowClosed()); - QVERIFY(mainWindow->testAttribute(Qt::WA_QuitOnClose)); - - mainWindow->show(); - - timer.start(); - QTimer::singleShot(1000, mainWindow, SLOT(close())); // This should quit the application - QTimer::singleShot(2000, &app, SLOT(quit())); // This makes sure we quit even if it didn't - - app.exec(); - - QCOMPARE(spy.count(), 1); - QVERIFY(spy2.count() > 15); // Should be around 20 if closing did not caused the quit - } - { - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); - QSignalSpy appSpy(&app, SIGNAL(lastWindowClosed())); - - // exec a dialog for 1 second, then show the window - QuitOnLastWindowClosedWindow window; - QTimer::singleShot(0, &window, SLOT(execDialogThenShow())); - - QTimer timer; - QSignalSpy timerSpy(&timer, SIGNAL(timeout())); - connect(&timer, SIGNAL(timeout()), &window, SLOT(close())); - timer.setSingleShot(true); - timer.start(2000); - int returnValue = app.exec(); - QCOMPARE(returnValue, 0); - // failure here means the timer above didn't fire, and the - // quit was caused the the dialog being closed (not the window) - QCOMPARE(timerSpy.count(), 1); - QCOMPARE(appSpy.count(), 2); - } -} - -bool isPathListIncluded(const QStringList &l, const QStringList &r) -{ - int size = r.count(); - if (size > l.count()) - return false; -#if defined (Q_OS_WIN) - Qt::CaseSensitivity cs = Qt::CaseInsensitive; -#else - Qt::CaseSensitivity cs = Qt::CaseSensitive; -#endif - int i = 0, j = 0; - for ( ; i < l.count() && j < r.count(); ++i) { - if (QDir::toNativeSeparators(l[i]).compare(QDir::toNativeSeparators(r[j]), cs) == 0) { - ++j; - i = -1; - } - } - return j == r.count(); -} - -#define QT_TST_QAPP_DEBUG -void tst_QApplication::libraryPaths() -{ - { -#ifndef Q_OS_WINCE - QString testDir = QDir::current().canonicalPath() + "/test"; -#else - // On Windows CE we need QApplication object to have valid - // current Path. Therefore we need to identify it ourselves - // here for the test. - QFileInfo filePath; - wchar_t module_name[MAX_PATH]; - GetModuleFileName(0, module_name, MAX_PATH); - filePath = QString::fromWCharArray(module_name); - QString testDir = filePath.path() + "/test"; -#endif - QApplication::setLibraryPaths(QStringList() << testDir); - QCOMPARE(QApplication::libraryPaths(), (QStringList() << testDir)); - - // creating QApplication adds the applicationDirPath to the libraryPath - int argc = 1; - QApplication app(argc, &argv0, QApplication::GuiServer); - QString appDirPath = QDir(app.applicationDirPath()).canonicalPath(); - - QStringList actual = QApplication::libraryPaths(); - actual.sort(); - QStringList expected = QSet::fromList((QStringList() << testDir << appDirPath)).toList(); - expected.sort(); - - QVERIFY2(isPathListIncluded(actual, expected), - qPrintable("actual:\n - " + actual.join("\n - ") + - "\nexpected:\n - " + expected.join("\n - "))); - } - { - // creating QApplication adds the applicationDirPath and plugin install path to the libraryPath - int argc = 1; - QApplication app(argc, &argv0, QApplication::GuiServer); - QString appDirPath = app.applicationDirPath(); - QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath); - - QStringList actual = QApplication::libraryPaths(); - actual.sort(); - -#if defined(Q_OS_SYMBIAN) - QStringList expected; - addExpectedSymbianPluginsPath(expected); - expected << appDirPath; -#else - QStringList expected = QSet::fromList((QStringList() << installPathPlugins << appDirPath)).toList(); -#endif - expected.sort(); - - QVERIFY2(isPathListIncluded(actual, expected), - qPrintable("actual:\n - " + actual.join("\n - ") + - "\nexpected:\n - " + expected.join("\n - "))); - - // setting the library paths overrides everything - QString testDir = QDir::currentPath() + "/test"; - QApplication::setLibraryPaths(QStringList() << testDir); - QVERIFY2(isPathListIncluded(QApplication::libraryPaths(), (QStringList() << testDir)), - qPrintable("actual:\n - " + QApplication::libraryPaths().join("\n - ") + - "\nexpected:\n - " + testDir)); - } - { -#ifdef QT_TST_QAPP_DEBUG - qDebug() << "Initial library path:" << QApplication::libraryPaths(); -#endif - - int count = QApplication::libraryPaths().count(); -#if 0 - // this test doesn't work if KDE 4 is installed - QCOMPARE(count, 1); // before creating QApplication, only the PluginsPath is in the libraryPaths() -#endif - QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath); - QApplication::addLibraryPath(installPathPlugins); -#ifdef QT_TST_QAPP_DEBUG - qDebug() << "installPathPlugins" << installPathPlugins; - qDebug() << "After adding plugins path:" << QApplication::libraryPaths(); -#endif - QCOMPARE(QApplication::libraryPaths().count(), count); - - QApplication::addLibraryPath(QDir::currentPath() + "/test"); - QCOMPARE(QApplication::libraryPaths().count(), count + 1); - - // creating QApplication adds the applicationDirPath to the libraryPath - int argc = 1; - QApplication app(argc, &argv0, QApplication::GuiServer); - QString appDirPath = app.applicationDirPath(); - qDebug() << QApplication::libraryPaths(); - // On Windows CE these are identical and might also be the case for other - // systems too - if (appDirPath != installPathPlugins) - QCOMPARE(QApplication::libraryPaths().count(), count + 2); - } - { - int argc = 1; - QApplication app(argc, &argv0, QApplication::GuiServer); - -#ifdef QT_TST_QAPP_DEBUG - qDebug() << "Initial library path:" << app.libraryPaths(); -#endif - int count = app.libraryPaths().count(); - QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath); - app.addLibraryPath(installPathPlugins); -#ifdef QT_TST_QAPP_DEBUG - qDebug() << "installPathPlugins" << installPathPlugins; - qDebug() << "After adding plugins path:" << app.libraryPaths(); -#endif - QCOMPARE(app.libraryPaths().count(), count); - - QString appDirPath = app.applicationDirPath(); - - app.addLibraryPath(appDirPath); -#ifdef Q_OS_WINCE - app.addLibraryPath(appDirPath + "/../.."); -#else - app.addLibraryPath(appDirPath + "/.."); -#endif -#ifdef QT_TST_QAPP_DEBUG - qDebug() << "appDirPath" << appDirPath; - qDebug() << "After adding appDirPath && appDirPath + /..:" << app.libraryPaths(); -#endif - QCOMPARE(app.libraryPaths().count(), count + 1); -#ifdef Q_OS_MAC - app.addLibraryPath(appDirPath + "/../MacOS"); -#else - app.addLibraryPath(appDirPath + "/tmp/.."); -#endif -#ifdef QT_TST_QAPP_DEBUG - qDebug() << "After adding appDirPath + /tmp/..:" << app.libraryPaths(); -#endif - QCOMPARE(app.libraryPaths().count(), count + 1); - } -} - -void tst_QApplication::libraryPaths_qt_plugin_path() -{ - int argc = 1; - - QApplication app(argc, &argv0, QApplication::GuiServer); - QString appDirPath = app.applicationDirPath(); - - // Our hook into libraryPaths() initialization: Set the QT_PLUGIN_PATH environment variable - QString installPathPluginsDeCanon = appDirPath + QString::fromLatin1("/tmp/.."); - QByteArray ascii = installPathPluginsDeCanon.toAscii(); - qputenv("QT_PLUGIN_PATH", ascii); - - QVERIFY(!app.libraryPaths().contains(appDirPath + QString::fromLatin1("/tmp/.."))); -} - -void tst_QApplication::libraryPaths_qt_plugin_path_2() -{ -#ifdef Q_OS_SYMBIAN - QByteArray validPath = "C:\\data"; - QByteArray nonExistentPath = "Z:\\nonexistent"; - QByteArray pluginPath = validPath + ";" + nonExistentPath; -#elif defined(Q_OS_UNIX) - QByteArray validPath = QDir("/tmp").canonicalPath().toLatin1(); - QByteArray nonExistentPath = "/nonexistent"; - QByteArray pluginPath = validPath + ":" + nonExistentPath; -#elif defined(Q_OS_WIN) -# ifdef Q_OS_WINCE - QByteArray validPath = "/Temp"; - QByteArray nonExistentPath = "/nonexistent"; - QByteArray pluginPath = validPath + ";" + nonExistentPath; -# else - QByteArray validPath = "C:\\windows"; - QByteArray nonExistentPath = "Z:\\nonexistent"; - QByteArray pluginPath = validPath + ";" + nonExistentPath; -# endif -#endif - - { - // Our hook into libraryPaths() initialization: Set the QT_PLUGIN_PATH environment variable - qputenv("QT_PLUGIN_PATH", pluginPath); - - int argc = 1; - - QApplication app(argc, &argv0, QApplication::GuiServer); - - // library path list should contain the default plus the one valid path -#if defined(Q_OS_SYMBIAN) - // In Symbian, the PluginsPath doesn't specify the only absolute path; just the dir that can be found on any drive - QStringList expected; - addExpectedSymbianPluginsPath(expected); - expected << QDir(app.applicationDirPath()).canonicalPath() - << QDir(QDir::fromNativeSeparators(QString::fromLatin1(validPath))).canonicalPath(); -#else - QStringList expected = - QStringList() - << QLibraryInfo::location(QLibraryInfo::PluginsPath) - << QDir(app.applicationDirPath()).canonicalPath() - << QDir(QDir::fromNativeSeparators(QString::fromLatin1(validPath))).canonicalPath(); -# ifdef Q_OS_WINCE - expected = QSet::fromList(expected).toList(); -# endif -#endif - QVERIFY2(isPathListIncluded(app.libraryPaths(), expected), - qPrintable("actual:\n - " + app.libraryPaths().join("\n - ") + - "\nexpected:\n - " + expected.join("\n - "))); - } - - { - int argc = 1; - - QApplication app(argc, &argv0, QApplication::GuiServer); - - // library paths are initialized by the QApplication, setting - // the environment variable here doesn't work - qputenv("QT_PLUGIN_PATH", pluginPath); - - // library path list should contain the default -#if defined(Q_OS_SYMBIAN) - QStringList expected; - addExpectedSymbianPluginsPath(expected); - expected << app.applicationDirPath(); -#else - QStringList expected = - QStringList() - << QLibraryInfo::location(QLibraryInfo::PluginsPath) - << app.applicationDirPath(); -# ifdef Q_OS_WINCE - expected = QSet::fromList(expected).toList(); -# endif -#endif - QVERIFY(isPathListIncluded(app.libraryPaths(), expected)); - - qputenv("QT_PLUGIN_PATH", QByteArray()); - } -} - -class SendPostedEventsTester : public QObject -{ - Q_OBJECT -public: - QList eventSpy; - bool event(QEvent *e); -private slots: - void doTest(); -}; - -bool SendPostedEventsTester::event(QEvent *e) -{ - eventSpy.append(e->type()); - return QObject::event(e); -} - -void SendPostedEventsTester::doTest() -{ - QPointer p = this; - QApplication::postEvent(this, new QEvent(QEvent::User)); - // DeferredDelete should not be delivered until returning from this function - QApplication::postEvent(this, new QEvent(QEvent::DeferredDelete)); - - QEventLoop eventLoop; - QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection); - eventLoop.exec(); - QVERIFY(p != 0); - - QCOMPARE(eventSpy.count(), 2); - QCOMPARE(eventSpy.at(0), int(QEvent::MetaCall)); - QCOMPARE(eventSpy.at(1), int(QEvent::User)); - eventSpy.clear(); -} - -void tst_QApplication::sendPostedEvents() -{ - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); - SendPostedEventsTester *tester = new SendPostedEventsTester; - QMetaObject::invokeMethod(tester, "doTest", Qt::QueuedConnection); - QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection); - QPointer p = tester; - (void) app.exec(); - QVERIFY(p == 0); -} - -void tst_QApplication::thread() -{ - QThread *currentThread = QThread::currentThread(); - // no app, but still have a valid thread - QVERIFY(currentThread != 0); - - // the thread should be running and not finished - QVERIFY(currentThread->isRunning()); - QVERIFY(!currentThread->isFinished()); - - // this should probably be in the tst_QObject::thread() test, but - // we put it here since we want to make sure that objects created - // *before* the QApplication has a thread - QObject object; - QObject child(&object); - QVERIFY(object.thread() == currentThread); - QVERIFY(child.thread() == currentThread); - - { - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); - - // current thread still valid - QVERIFY(QThread::currentThread() != 0); - // thread should be the same as before - QCOMPARE(QThread::currentThread(), currentThread); - - // app's thread should be the current thread - QCOMPARE(app.thread(), currentThread); - - // the thread should still be running and not finished - QVERIFY(currentThread->isRunning()); - QVERIFY(!currentThread->isFinished()); - - QTestEventLoop::instance().enterLoop(1); - } - - // app dead, current thread still valid - QVERIFY(QThread::currentThread() != 0); - QCOMPARE(QThread::currentThread(), currentThread); - - // the thread should still be running and not finished - QVERIFY(currentThread->isRunning()); - QVERIFY(!currentThread->isFinished()); - - // should still have a thread - QVERIFY(object.thread() == currentThread); - QVERIFY(child.thread() == currentThread); - - // do the test again, making sure that the thread is the same as - // before - { - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); - - // current thread still valid - QVERIFY(QThread::currentThread() != 0); - // thread should be the same as before - QCOMPARE(QThread::currentThread(), currentThread); - - // app's thread should be the current thread - QCOMPARE(app.thread(), currentThread); - - // the thread should be running and not finished - QVERIFY(currentThread->isRunning()); - QVERIFY(!currentThread->isFinished()); - - // should still have a thread - QVERIFY(object.thread() == currentThread); - QVERIFY(child.thread() == currentThread); - - QTestEventLoop::instance().enterLoop(1); - } - - // app dead, current thread still valid - QVERIFY(QThread::currentThread() != 0); - QCOMPARE(QThread::currentThread(), currentThread); - - // the thread should still be running and not finished - QVERIFY(currentThread->isRunning()); - QVERIFY(!currentThread->isFinished()); - - // should still have a thread - QVERIFY(object.thread() == currentThread); - QVERIFY(child.thread() == currentThread); -} - -class DeleteLaterWidget : public QWidget -{ - Q_OBJECT -public: - DeleteLaterWidget(QApplication *_app, QWidget *parent = 0) - : QWidget(parent) { app = _app; child_deleted = false; } - - bool child_deleted; - QApplication *app; - -public slots: - void runTest(); - void checkDeleteLater(); - void childDeleted() { child_deleted = true; } -}; - - -void DeleteLaterWidget::runTest() -{ - QObject *stillAlive = qFindChild(this, "deleteLater"); - - QWidget *w = new QWidget(this); - connect(w, SIGNAL(destroyed()), this, SLOT(childDeleted())); - - w->deleteLater(); - QVERIFY(!child_deleted); - - QDialog dlg; - QTimer::singleShot(500, &dlg, SLOT(reject())); - dlg.exec(); - - QVERIFY(!child_deleted); - app->processEvents(); - QVERIFY(!child_deleted); - - QTimer::singleShot(500, this, SLOT(checkDeleteLater())); - - app->processEvents(); - - QVERIFY(!stillAlive); // verify at the end to make test terminate -} - -void DeleteLaterWidget::checkDeleteLater() -{ - QVERIFY(child_deleted); - - close(); -} - -void tst_QApplication::testDeleteLater() -{ - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); - connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit())); - - DeleteLaterWidget *wgt = new DeleteLaterWidget(&app); - QTimer::singleShot(500, wgt, SLOT(runTest())); - - QObject *object = new QObject(wgt); - object->setObjectName("deleteLater"); - object->deleteLater(); - - QObject *stillAlive = qFindChild(wgt, "deleteLater"); - QVERIFY(stillAlive); - - app.exec(); - - delete wgt; - -} - -class EventLoopNester : public QObject -{ - Q_OBJECT -public slots: - void deleteLaterAndEnterLoop() - { - QEventLoop eventLoop; - QPointer p(this); - deleteLater(); - - // DeferredDelete events are compressed, meaning this second - // deleteLater() will *not* delete the object in the nested - // event loop - QMetaObject::invokeMethod(this, "deleteLater", Qt::QueuedConnection); - QTimer::singleShot(1000, &eventLoop, SLOT(quit())); - eventLoop.exec(); - QVERIFY(p); - } - void deleteLaterAndExitLoop() - { - // Check that 'p' is not deleted before exec returns, since the call - // to QEventLoop::quit() should stop 'eventLoop' from processing - // any more events (that is, delete later) until we return to the - // _current_ event loop: - QEventLoop eventLoop; - QPointer p(this); - QMetaObject::invokeMethod(this, "deleteLater", Qt::QueuedConnection); - QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection); - eventLoop.exec(); - QVERIFY(p); // not dead yet - } - - void processEventsOnly() - { - QApplication::processEvents(); - } - void processEventsWithDeferredDeletion() - { - QApplication::processEvents(QEventLoop::DeferredDeletion); - } - void sendPostedEventsWithDeferredDelete() - { - QApplication::sendPostedEvents(0, QEvent::DeferredDelete); - } - void deleteLaterAndProcessEvents1() - { - QEventLoop eventLoop; - - QPointer p = this; - deleteLater(); - - // trying to delete this object in a deeper eventloop just won't work - QMetaObject::invokeMethod(this, - "processEventsOnly", - Qt::QueuedConnection); - QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection); - eventLoop.exec(); - QVERIFY(p); - QMetaObject::invokeMethod(this, - "processEventsWithDeferredDeletion", - Qt::QueuedConnection); - QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection); - eventLoop.exec(); - QVERIFY(p); - QMetaObject::invokeMethod(this, - "sendPostedEventsWithDeferredDelete", - Qt::QueuedConnection); - QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection); - eventLoop.exec(); - QVERIFY(p); - - // trying to delete it from this eventloop still doesn't work - QApplication::processEvents(); - QVERIFY(p); - - // however, it *will* work with this magic incantation - QApplication::processEvents(QEventLoop::DeferredDeletion); - QVERIFY(!p); - } - - void deleteLaterAndProcessEvents2() - { - QEventLoop eventLoop; - - QPointer p = this; - deleteLater(); - - // trying to delete this object in a deeper eventloop just won't work - QMetaObject::invokeMethod(this, - "processEventsOnly", - Qt::QueuedConnection); - QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection); - eventLoop.exec(); - QVERIFY(p); - QMetaObject::invokeMethod(this, - "processEventsWithDeferredDeletion", - Qt::QueuedConnection); - QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection); - eventLoop.exec(); - QVERIFY(p); - QMetaObject::invokeMethod(this, - "sendPostedEventsWithDeferredDelete", - Qt::QueuedConnection); - QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection); - eventLoop.exec(); - QVERIFY(p); - - // trying to delete it from this eventloop still doesn't work - QApplication::processEvents(); - QVERIFY(p); - - // however, it *will* work with this magic incantation - QApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(!p); - } -}; - -void tst_QApplication::testDeleteLaterProcessEvents() -{ - int argc = 0; - - // Calling processEvents() with no event dispatcher does nothing. - QObject *object = new QObject; - QPointer p(object); - object->deleteLater(); - QApplication::processEvents(); - QVERIFY(p); - delete object; - - { - QApplication app(argc, 0, QApplication::GuiServer); - // If you call processEvents() with an event dispatcher present, but - // outside any event loops, deferred deletes are not processed unless - // QEventLoop::DeferredDeletion is passed. - object = new QObject; - p = object; - object->deleteLater(); - app.processEvents(); - QVERIFY(p); - app.processEvents(QEventLoop::ProcessEventsFlag(0x10)); // 0x10 == QEventLoop::DeferredDeletion - QVERIFY(!p); - - // sendPostedEvents(0, DeferredDelete); also works - object = new QObject; - p = object; - object->deleteLater(); - app.processEvents(); - QVERIFY(p); - QApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(!p); - - // If you call deleteLater() on an object when there is no parent - // event loop, and then enter an event loop, the object will get - // deleted. - object = new QObject; - p = object; - object->deleteLater(); - QEventLoop loop; - QTimer::singleShot(1000, &loop, SLOT(quit())); - loop.exec(); - QVERIFY(!p); - } - { - // When an object is in an event loop, then calls deleteLater() and enters - // an event loop recursively, it should not die until the parent event - // loop continues. - QApplication app(argc, 0, QApplication::GuiServer); - QEventLoop loop; - EventLoopNester *nester = new EventLoopNester; - p = nester; - QTimer::singleShot(3000, &loop, SLOT(quit())); - QTimer::singleShot(0, nester, SLOT(deleteLaterAndEnterLoop())); - - loop.exec(); - QVERIFY(!p); - } - - { - // When the event loop that calls deleteLater() is exited - // immediately, the object should die when returning to the - // parent event loop - QApplication app(argc, 0, QApplication::GuiServer); - QEventLoop loop; - EventLoopNester *nester = new EventLoopNester; - p = nester; - QTimer::singleShot(3000, &loop, SLOT(quit())); - QTimer::singleShot(0, nester, SLOT(deleteLaterAndExitLoop())); - - loop.exec(); - QVERIFY(!p); - } - - { - // when the event loop that calls deleteLater() also calls - // processEvents() immediately afterwards, the object should - // not die until the parent loop continues - QApplication app(argc, 0, QApplication::GuiServer); - QEventLoop loop; - EventLoopNester *nester = new EventLoopNester(); - p = nester; - QTimer::singleShot(3000, &loop, SLOT(quit())); - QTimer::singleShot(0, nester, SLOT(deleteLaterAndProcessEvents1())); - - loop.exec(); - QVERIFY(!p); - } - - { - // when the event loop that calls deleteLater() also calls - // processEvents() immediately afterwards, the object should - // not die until the parent loop continues - QApplication app(argc, 0, QApplication::GuiServer); - QEventLoop loop; - EventLoopNester *nester = new EventLoopNester(); - p = nester; - QTimer::singleShot(3000, &loop, SLOT(quit())); - QTimer::singleShot(0, nester, SLOT(deleteLaterAndProcessEvents2())); - - loop.exec(); - QVERIFY(!p); - } -} - - -// Test for crash whith QApplication::setDesktopSettingsAware(false). - -void tst_QApplication::desktopSettingsAware() -{ -#ifndef QT_NO_PROCESS - QProcess testProcess; -#ifdef Q_OS_WINCE - int argc = 0; - QApplication tmpApp(argc, 0, QApplication::GuiServer); - testProcess.start("desktopsettingsaware/desktopsettingsaware"); -#else -#if defined(Q_OS_WIN) && defined(QT_DEBUG) - testProcess.start("desktopsettingsaware/debug/desktopsettingsaware"); -#elif defined(Q_OS_WIN) - testProcess.start("desktopsettingsaware/release/desktopsettingsaware"); -#elif defined(Q_OS_SYMBIAN) - testProcess.start("desktopsettingsaware"); -#if defined(Q_CC_NOKIAX86) - QEXPECT_FAIL("", "QProcess on Q_CC_NOKIAX86 cannot launch another Qt application, due to DLL conflicts.", Abort); - // TODO: Remove XFAIL, as soon as we can launch Qt applications from within Qt applications on Symbian - QVERIFY(testProcess.error() != QProcess::FailedToStart); -#endif // defined(Q_CC_NOKIAX86) -#else - testProcess.start("desktopsettingsaware/desktopsettingsaware"); -#endif -#endif - QVERIFY(testProcess.waitForFinished(10000)); - QCOMPARE(int(testProcess.state()), int(QProcess::NotRunning)); - QVERIFY(int(testProcess.error()) != int(QProcess::Crashed)); -#endif -} -*/ - -void tst_QApplication::setActiveWindow() -{ - int argc = 0; - QApplication MyApp(argc, 0, QApplication::GuiServer); - - QWidget* w = new QWidget; - QVBoxLayout* layout = new QVBoxLayout(w); - - QLineEdit* pb1 = new QLineEdit("Testbutton1", w); - QLineEdit* pb2 = new QLineEdit("Test Line Edit", w); - - layout->addWidget(pb1); - layout->addWidget(pb2); - - pb2->setFocus(); - pb2->setParent(0); - delete pb2; - - w->show(); - QApplication::setActiveWindow(w); // needs this on twm (focus follows mouse) - QVERIFY(pb1->hasFocus()); - delete w; -} - - -/* This might fail on some X11 window managers? */ -/* -void tst_QApplication::focusChanged() -{ - int argc = 0; - QApplication app(argc, 0, QApplication::GuiServer); - - QSignalSpy spy(&app, SIGNAL(focusChanged(QWidget *, QWidget *))); - QWidget *now = 0; - QWidget *old = 0; - - QWidget parent1; - QHBoxLayout hbox1(&parent1); - QLabel lb1(&parent1); - QLineEdit le1(&parent1); - QPushButton pb1(&parent1); - hbox1.addWidget(&lb1); - hbox1.addWidget(&le1); - hbox1.addWidget(&pb1); - - QCOMPARE(spy.count(), 0); - - parent1.show(); - QApplication::setActiveWindow(&parent1); // needs this on twm (focus follows mouse) - QCOMPARE(spy.count(), 1); - QCOMPARE(spy.at(0).count(), 2); - old = qVariantValue(spy.at(0).at(0)); - now = qVariantValue(spy.at(0).at(1)); - QVERIFY(now == &le1); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == 0); - spy.clear(); - QCOMPARE(spy.count(), 0); - - pb1.setFocus(); - QCOMPARE(spy.count(), 1); - old = qVariantValue(spy.at(0).at(0)); - now = qVariantValue(spy.at(0).at(1)); - QVERIFY(now == &pb1); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &le1); - spy.clear(); - - lb1.setFocus(); - QCOMPARE(spy.count(), 1); - old = qVariantValue(spy.at(0).at(0)); - now = qVariantValue(spy.at(0).at(1)); - QVERIFY(now == &lb1); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &pb1); - spy.clear(); - - lb1.clearFocus(); - QCOMPARE(spy.count(), 1); - old = qVariantValue(spy.at(0).at(0)); - now = qVariantValue(spy.at(0).at(1)); - QVERIFY(now == 0); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &lb1); - spy.clear(); - - QWidget parent2; - QHBoxLayout hbox2(&parent2); - QLabel lb2(&parent2); - QLineEdit le2(&parent2); - QPushButton pb2(&parent2); - hbox2.addWidget(&lb2); - hbox2.addWidget(&le2); - hbox2.addWidget(&pb2); - - parent2.show(); - QApplication::setActiveWindow(&parent2); // needs this on twm (focus follows mouse) - QVERIFY(spy.count() > 0); // one for deactivation, one for activation on Windows - old = qVariantValue(spy.at(spy.count()-1).at(0)); - now = qVariantValue(spy.at(spy.count()-1).at(1)); - QVERIFY(now == &le2); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == 0); - spy.clear(); - - QTestKeyEvent tab(QTest::Press, Qt::Key_Tab, 0, 0); - QTestKeyEvent backtab(QTest::Press, Qt::Key_Backtab, 0, 0); - QTestMouseEvent click(QTest::MouseClick, Qt::LeftButton, 0, QPoint(5, 5), 0); - - bool tabAllControls = true; -#ifdef Q_WS_MAC - // Mac has two modes, one where you tab to everything, one where you can - // only tab to input controls, here's what we get. Determine which ones we - // should get. - QSettings appleSettings(QLatin1String("apple.com")); - QVariant appleValue = appleSettings.value(QLatin1String("AppleKeyboardUIMode"), 0); - tabAllControls = (appleValue.toInt() & 0x2); -#endif - - tab.simulate(now); - if (!tabAllControls) { - QVERIFY(spy.count() == 0); - QVERIFY(now == QApplication::focusWidget()); - } else { - QVERIFY(spy.count() > 0); - old = qVariantValue(spy.at(0).at(0)); - now = qVariantValue(spy.at(0).at(1)); - QVERIFY(now == &pb2); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &le2); - spy.clear(); - } - - if (!tabAllControls) { - QVERIFY(spy.count() == 0); - QVERIFY(now == QApplication::focusWidget()); - } else { - tab.simulate(now); - QVERIFY(spy.count() > 0); - old = qVariantValue(spy.at(0).at(0)); - now = qVariantValue(spy.at(0).at(1)); - QVERIFY(now == &le2); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &pb2); - spy.clear(); - } - - if (!tabAllControls) { - QVERIFY(spy.count() == 0); - QVERIFY(now == QApplication::focusWidget()); - } else { - backtab.simulate(now); - QVERIFY(spy.count() > 0); - old = qVariantValue(spy.at(0).at(0)); - now = qVariantValue(spy.at(0).at(1)); - QVERIFY(now == &pb2); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &le2); - spy.clear(); - } - - - if (!tabAllControls) { - QVERIFY(spy.count() == 0); - QVERIFY(now == QApplication::focusWidget()); - old = &pb2; - } else { - backtab.simulate(now); - QVERIFY(spy.count() > 0); - old = qVariantValue(spy.at(0).at(0)); - now = qVariantValue(spy.at(0).at(1)); - QVERIFY(now == &le2); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &pb2); - spy.clear(); - } - - click.simulate(old); - if (!(pb2.focusPolicy() & Qt::ClickFocus)) { - QVERIFY(spy.count() == 0); - QVERIFY(now == QApplication::focusWidget()); - } else { - QVERIFY(spy.count() > 0); - old = qVariantValue(spy.at(0).at(0)); - now = qVariantValue(spy.at(0).at(1)); - QVERIFY(now == &pb2); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &le2); - spy.clear(); - - click.simulate(old); - QVERIFY(spy.count() > 0); - old = qVariantValue(spy.at(0).at(0)); - now = qVariantValue(spy.at(0).at(1)); - QVERIFY(now == &le2); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &pb2); - spy.clear(); - } - - parent1.activateWindow(); - QApplication::setActiveWindow(&parent1); // needs this on twm (focus follows mouse) - QVERIFY(spy.count() == 1 || spy.count() == 2); // one for deactivation, one for activation on Windows - - //on windows, the change of focus is made in 2 steps - //(the focusChanged SIGNAL is emitted twice) - if (spy.count()==1) - old = qVariantValue(spy.at(spy.count()-1).at(0)); - else - old = qVariantValue(spy.at(spy.count()-2).at(0)); - now = qVariantValue(spy.at(spy.count()-1).at(1)); - QVERIFY(now == &le1); - QVERIFY(now == QApplication::focusWidget()); - QVERIFY(old == &le2); - spy.clear(); -} - -class LineEdit : public QLineEdit -{ -public: - LineEdit(QWidget *parent = 0) : QLineEdit(parent) { } - -protected: - void focusOutEvent(QFocusEvent *e) { - QLineEdit::focusOutEvent(e); - if (objectName() == "le1") - setStyleSheet(""); - } - - void focusInEvent(QFocusEvent *e) { - QLineEdit::focusInEvent(e); - if (objectName() == "le2") - setStyleSheet(""); - } -}; - -void tst_QApplication::focusOut() -{ - int argc = 1; - QApplication app(argc, &argv0, QApplication::GuiServer); - - // Tests the case where the style pointer changes when on focus in/out - // (the above is the case when the stylesheet changes) - QWidget w; - QLineEdit *le1 = new LineEdit(&w); - le1->setObjectName("le1"); - le1->setStyleSheet("background: #fee"); - le1->setFocus(); - - QLineEdit *le2 = new LineEdit(&w); - le2->setObjectName("le2"); - le2->setStyleSheet("background: #fee"); - le2->move(100, 100); - w.show(); - - QTest::qWait(2000); - le2->setFocus(); - QTest::qWait(2000); -} - -void tst_QApplication::execAfterExit() -{ - int argc = 1; - QApplication app(argc, &argv0, QApplication::GuiServer); - QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection); - // this should be ignored, as exec() will reset the exitCode - QApplication::exit(1); - int exitCode = app.exec(); - QCOMPARE(exitCode, 0); - - // the quitNow flag should have been reset, so we can spin an - // eventloop after QApplication::exec() returns - QEventLoop eventLoop; - QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection); - exitCode = eventLoop.exec(); - QCOMPARE(exitCode, 0); -} - -void tst_QApplication::wheelScrollLines() -{ - int argc = 1; - QApplication app(argc, &argv0, QApplication::GuiServer); - // If wheelScrollLines returns 0, the mose wheel will be disabled. - QVERIFY(app.wheelScrollLines() > 0); -} - -void tst_QApplication::style() -{ - int argc = 1; - - { - QApplication app(argc, &argv0, QApplication::GuiServer); - QPointer style = app.style(); - app.setStyle(new QWindowsStyle); - QVERIFY(style.isNull()); - } - - QApplication app(argc, &argv0, QApplication::GuiServer); - - // qApp style can never be 0 - QVERIFY(QApplication::style() != 0); -} - -void tst_QApplication::allWidgets() -{ - int argc = 1; - QApplication app(argc, &argv0, QApplication::GuiServer); - QWidget *w = new QWidget; - QVERIFY(app.allWidgets().contains(w)); // uncreate widget test - QVERIFY(app.allWidgets().contains(w)); // created widget test - delete w; - w = 0; - QVERIFY(!app.allWidgets().contains(w)); // removal test -} - -void tst_QApplication::topLevelWidgets() -{ - int argc = 1; - QApplication app(argc, &argv0, QApplication::GuiServer); - QWidget *w = new QWidget; - w->show(); -#ifndef QT_NO_CLIPBOARD - QClipboard *clipboard = QApplication::clipboard(); - QString originalText = clipboard->text(); - clipboard->setText(QString("newText")); -#endif - app.processEvents(); - QVERIFY(QApplication::topLevelWidgets().contains(w)); - QCOMPARE(QApplication::topLevelWidgets().count(), 1); - delete w; - w = 0; - app.processEvents(); - QCOMPARE(QApplication::topLevelWidgets().count(), 0); -} - - - -void tst_QApplication::setAttribute() -{ - int argc = 1; - QApplication app(argc, &argv0, QApplication::GuiServer); - QVERIFY(!QApplication::testAttribute(Qt::AA_ImmediateWidgetCreation)); - QWidget *w = new QWidget; - QVERIFY(!w->testAttribute(Qt::WA_WState_Created)); - delete w; - - QApplication::setAttribute(Qt::AA_ImmediateWidgetCreation); - QVERIFY(QApplication::testAttribute(Qt::AA_ImmediateWidgetCreation)); - w = new QWidget; - QVERIFY(w->testAttribute(Qt::WA_WState_Created)); - QWidget *w2 = new QWidget(w); - w2->setParent(0); - QVERIFY(w2->testAttribute(Qt::WA_WState_Created)); - delete w; - delete w2; - - QApplication::setAttribute(Qt::AA_ImmediateWidgetCreation, false); - QVERIFY(!QApplication::testAttribute(Qt::AA_ImmediateWidgetCreation)); - w = new QWidget; - QVERIFY(!w->testAttribute(Qt::WA_WState_Created)); - delete w; -} - -void tst_QApplication::windowsCommandLine_data() -{ -#if defined(Q_OS_WIN) - QTest::addColumn("args"); - QTest::addColumn("expected"); - - QTest::newRow("hello world") - << QString("Hello \"World\"") - << QString("Hello \"World\""); - QTest::newRow("sql") - << QString("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PNR' AND TABLE_TYPE = 'VIEW' ORDER BY TABLE_NAME") - << QString("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PNR' AND TABLE_TYPE = 'VIEW' ORDER BY TABLE_NAME"); -#endif -} - -void tst_QApplication::windowsCommandLine() -{ -#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) - QFETCH(QString, args); - QFETCH(QString, expected); - - QProcess testProcess; -#if defined(QT_DEBUG) - testProcess.start("wincmdline/debug/wincmdline", QStringList(args)); -#else - testProcess.start("wincmdline/release/wincmdline", QStringList(args)); -#endif - QVERIFY(testProcess.waitForFinished(10000)); - QByteArray error = testProcess.readAllStandardError(); - QString procError(error); - QCOMPARE(procError, expected); -#endif -} - -class TouchEventPropagationTestWidget : public QWidget -{ - Q_OBJECT - -public: - bool seenTouchEvent, acceptTouchEvent, seenMouseEvent, acceptMouseEvent; - - TouchEventPropagationTestWidget(QWidget *parent = 0) - : QWidget(parent), seenTouchEvent(false), acceptTouchEvent(false), seenMouseEvent(false), acceptMouseEvent(false) - { } - - void reset() - { - seenTouchEvent = acceptTouchEvent = seenMouseEvent = acceptMouseEvent = false; - } - - bool event(QEvent *event) - { - switch (event->type()) { - case QEvent::MouseButtonPress: - case QEvent::MouseMove: - case QEvent::MouseButtonRelease: - // qDebug() << objectName() << "seenMouseEvent = true"; - seenMouseEvent = true; - event->setAccepted(acceptMouseEvent); - break; - case QEvent::TouchBegin: - case QEvent::TouchUpdate: - case QEvent::TouchEnd: - // qDebug() << objectName() << "seenTouchEvent = true"; - seenTouchEvent = true; - event->setAccepted(acceptTouchEvent); - break; - default: - return QWidget::event(event); - } - return true; - } -}; - -void tst_QApplication::touchEventPropagation() -{ - int argc = 1; - QApplication app(argc, &argv0, QApplication::GuiServer); - - QList pressedTouchPoints; - QTouchEvent::TouchPoint press(0); - press.setState(Qt::TouchPointPressed); - pressedTouchPoints << press; - - QList releasedTouchPoints; - QTouchEvent::TouchPoint release(0); - release.setState(Qt::TouchPointReleased); - releasedTouchPoints << release; - - { - // touch event behavior on a window - TouchEventPropagationTestWidget window; - window.setObjectName("1. window"); - - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); - QVERIFY(!window.seenTouchEvent); - QVERIFY(!window.seenMouseEvent); - - window.reset(); - window.setAttribute(Qt::WA_AcceptTouchEvents); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); - QVERIFY(window.seenTouchEvent); - QVERIFY(!window.seenMouseEvent); - - window.reset(); - window.acceptTouchEvent = true; - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); - QVERIFY(window.seenTouchEvent); - QVERIFY(!window.seenMouseEvent); - } - - { - // touch event behavior on a window with a child widget - TouchEventPropagationTestWidget window; - window.setObjectName("2. window"); - TouchEventPropagationTestWidget widget(&window); - widget.setObjectName("2. widget"); - - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); - QVERIFY(!widget.seenTouchEvent); - QVERIFY(!widget.seenMouseEvent); - QVERIFY(!window.seenTouchEvent); - QVERIFY(!window.seenMouseEvent); - - window.reset(); - widget.reset(); - widget.setAttribute(Qt::WA_AcceptTouchEvents); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); - QVERIFY(widget.seenTouchEvent); - QVERIFY(!widget.seenMouseEvent); - QVERIFY(!window.seenTouchEvent); - QVERIFY(!window.seenMouseEvent); - - window.reset(); - widget.reset(); - widget.acceptMouseEvent = true; - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); - QVERIFY(widget.seenTouchEvent); - QVERIFY(!widget.seenMouseEvent); - QVERIFY(!window.seenTouchEvent); - QVERIFY(!window.seenMouseEvent); - - window.reset(); - widget.reset(); - widget.acceptTouchEvent = true; - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); - QVERIFY(widget.seenTouchEvent); - QVERIFY(!widget.seenMouseEvent); - QVERIFY(!window.seenTouchEvent); - QVERIFY(!window.seenMouseEvent); - - window.reset(); - widget.reset(); - widget.setAttribute(Qt::WA_AcceptTouchEvents, false); - window.setAttribute(Qt::WA_AcceptTouchEvents); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); - QVERIFY(!widget.seenTouchEvent); - QVERIFY(!widget.seenMouseEvent); - QVERIFY(window.seenTouchEvent); - QVERIFY(!window.seenMouseEvent); - - window.reset(); - widget.reset(); - window.acceptTouchEvent = true; - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); - QVERIFY(!widget.seenTouchEvent); - QVERIFY(!widget.seenMouseEvent); - QVERIFY(window.seenTouchEvent); - QVERIFY(!window.seenMouseEvent); - - window.reset(); - widget.reset(); - widget.acceptMouseEvent = true; // doesn't matter, touch events are propagated first - window.acceptTouchEvent = true; - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints); - QVERIFY(!widget.seenTouchEvent); - QVERIFY(!widget.seenMouseEvent); - QVERIFY(window.seenTouchEvent); - QVERIFY(!window.seenMouseEvent); - } -} - -void tst_QApplication::symbianNoApplicationPanes() -{ -#ifndef Q_OS_SYMBIAN - QSKIP("This is a Symbian only test", SkipAll); -#else - QApplication::setAttribute(Qt::AA_S60DontConstructApplicationPanes); - - // Run in a block so that QApplication is destroyed before resetting the attribute. - { - // Actually I wasn't able to get the forced orientation change to work properly, - // but I'll leave the code here for the future in case we manage to test that - // later. If someone knows how to force an orientation switch in an autotest, do - // feel free to fix this testcase. - int argc = 0; - QApplication app(argc, 0); - QWidget *w; - - w = new QWidget; - w->show(); - QT_TRAP_THROWING(static_cast(CCoeEnv::Static()->AppUi()) - ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape)); - app.processEvents(); - delete w; - - w = new QWidget; - w->show(); - QT_TRAP_THROWING(static_cast(CCoeEnv::Static()->AppUi()) - ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait)); - app.processEvents(); - delete w; - - w = new QWidget; - w->showMaximized(); - QT_TRAP_THROWING(static_cast(CCoeEnv::Static()->AppUi()) - ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape)); - app.processEvents(); - delete w; - - w = new QWidget; - w->showMaximized(); - QT_TRAP_THROWING(static_cast(CCoeEnv::Static()->AppUi()) - ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait)); - app.processEvents(); - delete w; - - w = new QWidget; - w->showFullScreen(); - QT_TRAP_THROWING(static_cast(CCoeEnv::Static()->AppUi()) - ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape)); - app.processEvents(); - delete w; - - w = new QWidget; - w->showFullScreen(); - QT_TRAP_THROWING(static_cast(CCoeEnv::Static()->AppUi()) - ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait)); - app.processEvents(); - delete w; - - // These will have no effect, since there is no status pane, but they shouldn't - // crash either. - w = new QWidget; - w->show(); - w->setWindowTitle("Testing title"); - app.processEvents(); - delete w; - - w = new QWidget; - w->show(); - w->setWindowIcon(QIcon(QPixmap("heart.svg"))); - app.processEvents(); - delete w; - - QDesktopWidget desktop; - QCOMPARE(desktop.availableGeometry(), desktop.screenGeometry()); - } - - QApplication::setAttribute(Qt::AA_S60DontConstructApplicationPanes, false); - - // No other error condition. Program will crash if unsuccessful. -#endif -} - -#ifdef Q_OS_SYMBIAN -class CBaseDummy : public CBase -{ -public: - CBaseDummy(int *numDestroyed) : numDestroyed(numDestroyed) - { - } - ~CBaseDummy() - { - (*numDestroyed)++; - } - -private: - int *numDestroyed; -}; - -static void fakeMain(int *numDestroyed) -{ - // Push a few objects, just so that the cleanup stack has something to clean up. - CleanupStack::PushL(new (ELeave) CBaseDummy(numDestroyed)); - int argc = 0; - QApplication app(argc, 0); - CleanupStack::PushL(new (ELeave) CBaseDummy(numDestroyed)); - - User::Leave(KErrGeneral); // Fake error -} -#endif - -void tst_QApplication::symbianNeedForTraps() -{ -#ifndef Q_OS_SYMBIAN - QSKIP("This is a Symbian-only test", SkipAll); -#else - int argc = 0; - QApplication app(argc, 0); - int numDestroyed = 0; - - // This next part should not require a trap. If it does, the test will crash. - CleanupStack::PushL(new (ELeave) CBaseDummy(&numDestroyed)); - CleanupStack::PopAndDestroy(); - - QCOMPARE(numDestroyed, 1); - - // No other failure condition. The program will crash if it does not pass. -#endif -} - -void tst_QApplication::symbianLeaveThroughMain() -{ -#ifndef Q_OS_SYMBIAN - QSKIP("This is a Symbian-only test", SkipAll); -#else - int numDestroyed = 0; - TInt err; - TRAP(err, fakeMain(&numDestroyed)); - - QCOMPARE(numDestroyed, 2); -#endif -} -*/ - -//QTEST_APPLESS_MAIN(tst_QApplication) -int main(int argc, char *argv[]) -{ - tst_QApplication tc; - argv0 = argv[0]; - return QTest::qExec(&tc, argc, argv); -} - -#include "smoketest_qapplication.moc"