qt/qapplication/smoketest_qapplication.cpp
branchSymbian3
changeset 43 14fcccfb4c0c
parent 42 4f2786c97bf4
child 44 d7814d21adf0
equal deleted inserted replaced
42:4f2786c97bf4 43:14fcccfb4c0c
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 //#define QT_TST_QAPP_DEBUG
       
    44 #include <qdebug.h>
       
    45 
       
    46 #include <QtTest/QtTest>
       
    47 
       
    48 #include "qabstracteventdispatcher.h"
       
    49 #include <QtGui>
       
    50 
       
    51 #include "private/qapplication_p.h"
       
    52 #include "private/qstylesheetstyle_p.h"
       
    53 #ifdef Q_OS_WINCE
       
    54 #include <windows.h>
       
    55 #endif
       
    56 #ifdef Q_OS_SYMBIAN
       
    57 #include <aknenv.h>
       
    58 #endif
       
    59 
       
    60 //TESTED_CLASS=
       
    61 //TESTED_FILES=
       
    62 
       
    63 #if defined(Q_OS_SYMBIAN)
       
    64 // In Symbian, the PluginsPath doesn't specify the only absolute path; just the dir that can be found on any drive
       
    65 /*static void addExpectedSymbianPluginsPath(QStringList& expected)
       
    66 {
       
    67     QString installPathPlugins = QDir::fromNativeSeparators(QLibraryInfo::location(QLibraryInfo::PluginsPath));
       
    68     QFileInfoList driveList = QDir::drives();
       
    69     QListIterator<QFileInfo> iter(driveList);
       
    70     while (iter.hasNext()) {
       
    71         QFileInfo testFi(iter.next().canonicalPath().append(installPathPlugins));
       
    72         if (testFi.exists())
       
    73             expected << testFi.canonicalFilePath();
       
    74     }
       
    75 }
       
    76 */
       
    77 #endif
       
    78 
       
    79 class tst_QApplication : public QObject
       
    80 {
       
    81 Q_OBJECT
       
    82 
       
    83 public:
       
    84     tst_QApplication();
       
    85     virtual ~tst_QApplication();
       
    86 
       
    87 public slots:
       
    88     void init();
       
    89     void cleanup();
       
    90 private slots:
       
    91     /*void sendEventsOnProcessEvents(); // this must be the first test
       
    92     void getSetCheck();
       
    93     void staticSetup();
       
    94 
       
    95     void alert();
       
    96 
       
    97     void multiple_data();
       
    98     void multiple();
       
    99 
       
   100     void nonGui();
       
   101 
       
   102     void setFont_data();
       
   103     void setFont();
       
   104 
       
   105     void args_data();
       
   106     void args();
       
   107 
       
   108     void lastWindowClosed();
       
   109     void quitOnLastWindowClosed();
       
   110     void testDeleteLater();
       
   111     void testDeleteLaterProcessEvents();
       
   112 
       
   113     void libraryPaths();
       
   114     void libraryPaths_qt_plugin_path();
       
   115     void libraryPaths_qt_plugin_path_2();
       
   116 
       
   117     void sendPostedEvents();
       
   118 
       
   119     void thread();
       
   120     void desktopSettingsAware();*/
       
   121 
       
   122     void setActiveWindow();
       
   123 
       
   124     /*void focusChanged();
       
   125     void focusOut();
       
   126 
       
   127     void execAfterExit();
       
   128 
       
   129     void wheelScrollLines();
       
   130 
       
   131     void task109149();
       
   132 
       
   133     void style();
       
   134 
       
   135     void allWidgets();
       
   136     void topLevelWidgets();
       
   137 
       
   138     void setAttribute();
       
   139 
       
   140     void windowsCommandLine_data();
       
   141     void windowsCommandLine();
       
   142 
       
   143     void touchEventPropagation();
       
   144 
       
   145     void symbianNoApplicationPanes();
       
   146 
       
   147     void symbianNeedForTraps();
       
   148     void symbianLeaveThroughMain();*/
       
   149 };
       
   150 
       
   151 /*class EventSpy : public QObject
       
   152 {
       
   153    Q_OBJECT
       
   154 
       
   155 public:
       
   156     QList<int> recordedEvents;
       
   157     bool eventFilter(QObject *, QEvent *event)
       
   158     {
       
   159         recordedEvents.append(event->type());
       
   160         return false;
       
   161     }
       
   162 };
       
   163 */
       
   164 
       
   165 /*
       
   166 void tst_QApplication::sendEventsOnProcessEvents()
       
   167 {
       
   168     int argc = 0;
       
   169     QApplication app(argc, 0, QApplication::GuiServer);
       
   170 
       
   171     EventSpy spy;
       
   172     app.installEventFilter(&spy);
       
   173 
       
   174     QCoreApplication::postEvent(&app,  new QEvent(QEvent::Type(QEvent::User + 1)));
       
   175     QCoreApplication::processEvents();
       
   176     QVERIFY(spy.recordedEvents.contains(QEvent::User + 1));
       
   177 }
       
   178 
       
   179 class MyInputContext : public QInputContext
       
   180 {
       
   181 public:
       
   182     MyInputContext() : QInputContext() {}
       
   183     QString identifierName() { return QString("NoName"); }
       
   184     QString language() { return QString("NoLanguage"); }
       
   185     void reset() {}
       
   186     bool isComposing() const { return false; }
       
   187 };
       
   188 
       
   189 // Testing get/set functions
       
   190 void tst_QApplication::getSetCheck()
       
   191 {
       
   192     int argc = 0;
       
   193     QApplication obj1(argc, 0, QApplication::GuiServer);
       
   194     // QInputContext * QApplication::inputContext()
       
   195     // void QApplication::setInputContext(QInputContext *)
       
   196     MyInputContext *var1 = new MyInputContext;
       
   197     obj1.setInputContext(var1);
       
   198     QCOMPARE((QInputContext *)var1, obj1.inputContext());
       
   199     QTest::ignoreMessage(QtWarningMsg, "QApplication::setInputContext: called with 0 input context");
       
   200     obj1.setInputContext((QInputContext *)0);
       
   201     QCOMPARE((QInputContext *)var1, obj1.inputContext());
       
   202     // delete var1; // No delete, since QApplication takes ownership
       
   203 }
       
   204 
       
   205 class CloseEventTestWindow : public QWidget
       
   206 {
       
   207 public:
       
   208     CloseEventTestWindow(QWidget *parent = 0)
       
   209         : QWidget(parent)
       
   210     {
       
   211     }
       
   212 
       
   213     void closeEvent(QCloseEvent *event)
       
   214     {
       
   215         QWidget dialog;
       
   216         dialog.show();
       
   217         dialog.close();
       
   218 
       
   219         hide();
       
   220         event->ignore();
       
   221     }
       
   222 };
       
   223 */
       
   224 
       
   225 static  char *argv0;
       
   226 
       
   227 tst_QApplication::tst_QApplication()
       
   228 {
       
   229 #ifdef Q_OS_WINCE
       
   230     // Clean up environment previously to launching test
       
   231     qputenv("QT_PLUGIN_PATH", QByteArray());
       
   232 #endif
       
   233 }
       
   234 
       
   235 tst_QApplication::~tst_QApplication()
       
   236 {
       
   237 
       
   238 }
       
   239 
       
   240 void tst_QApplication::init()
       
   241 {
       
   242 // TODO: Add initialization code here.
       
   243 // This will be executed immediately before each test is run.
       
   244 }
       
   245 
       
   246 void tst_QApplication::cleanup()
       
   247 {
       
   248 // TODO: Add cleanup code here.
       
   249 // This will be executed immediately after each test is run.
       
   250 }
       
   251 
       
   252 /*
       
   253 void tst_QApplication::staticSetup()
       
   254 {
       
   255     QVERIFY(!qApp);
       
   256 
       
   257     QStyle *style = QStyleFactory::create(QLatin1String("Windows"));
       
   258     QVERIFY(style);
       
   259     QApplication::setStyle(style);
       
   260 
       
   261     QPalette pal;
       
   262     QApplication::setPalette(pal);
       
   263 
       
   264     //QFont font;
       
   265     //QApplication::setFont(font);
       
   266 
       
   267     int argc = 0;
       
   268     QApplication app(argc, 0, QApplication::GuiServer);
       
   269 }
       
   270 
       
   271 
       
   272 // QApp subclass that exits the event loop after 150ms
       
   273 class TestApplication : public QApplication
       
   274 {
       
   275 public:
       
   276     TestApplication( int &argc, char **argv )
       
   277 	: QApplication( argc, argv, QApplication::GuiServer )
       
   278     {
       
   279 	startTimer( 150 );
       
   280     }
       
   281 
       
   282     void timerEvent( QTimerEvent * )
       
   283     {
       
   284         quit();
       
   285     }
       
   286 };
       
   287 
       
   288 void tst_QApplication::alert()
       
   289 {
       
   290     int argc = 0;
       
   291     QApplication app(argc, 0, QApplication::GuiServer);
       
   292     app.alert(0, 0);
       
   293 
       
   294     QWidget widget;
       
   295     QWidget widget2;
       
   296     app.alert(&widget, 100);
       
   297     widget.show();
       
   298     widget2.show();
       
   299 #ifdef Q_WS_X11
       
   300     qt_x11_wait_for_window_manager(&widget);
       
   301     qt_x11_wait_for_window_manager(&widget2);
       
   302 #endif
       
   303     QTest::qWait(100);
       
   304     app.alert(&widget, -1);
       
   305     app.alert(&widget, 250);
       
   306     widget2.activateWindow();
       
   307     QApplication::setActiveWindow(&widget2);
       
   308     app.alert(&widget, 0);
       
   309     widget.activateWindow();
       
   310     QApplication::setActiveWindow(&widget);
       
   311     app.alert(&widget, 200);
       
   312     app.syncX();
       
   313 }
       
   314 
       
   315 void tst_QApplication::multiple_data()
       
   316 {
       
   317     QTest::addColumn<QStringList>("features");
       
   318 
       
   319     // return a list of things to try
       
   320     QTest::newRow( "data0" ) << QStringList( "" );
       
   321     QTest::newRow( "data1" ) << QStringList( "QFont" );
       
   322     QTest::newRow( "data2" ) << QStringList( "QPixmap" );
       
   323     QTest::newRow( "data3" ) << QStringList( "QWidget" );
       
   324 }
       
   325 
       
   326 void tst_QApplication::multiple()
       
   327 {
       
   328     QFETCH(QStringList,features);
       
   329 
       
   330     int i = 0;
       
   331     int argc = 0;
       
   332     while ( i++ < 5 ) {
       
   333 	TestApplication app( argc, 0 );
       
   334 
       
   335 	if ( features.contains( "QFont" ) ) {
       
   336 	    // create font and force loading
       
   337 	    QFont font( "Arial", 12 );
       
   338 	    QFontInfo finfo( font );
       
   339 	    finfo.exactMatch();
       
   340 	}
       
   341 	if ( features.contains( "QPixmap" ) ) {
       
   342 	    QPixmap pix( 100, 100 );
       
   343 	    pix.fill( Qt::black );
       
   344 	}
       
   345 	if ( features.contains( "QWidget" ) ) {
       
   346 	    QWidget widget;
       
   347 	}
       
   348 
       
   349 	QVERIFY(!app.exec());
       
   350     }
       
   351 }
       
   352 
       
   353 void tst_QApplication::nonGui()
       
   354 {
       
   355 #ifdef Q_OS_HPUX
       
   356     // ### This is only to allow us to generate a test report for now.
       
   357     QSKIP("This test shuts down the window manager on HP-UX.", SkipAll);
       
   358 #endif
       
   359 
       
   360     int argc = 0;
       
   361     QApplication app(argc, 0, false);
       
   362     QCOMPARE(qApp, &app);
       
   363 }
       
   364 
       
   365 void tst_QApplication::setFont_data()
       
   366 {
       
   367     QTest::addColumn<QString>("family");
       
   368     QTest::addColumn<int>("pointsize");
       
   369     QTest::addColumn<bool>("beforeAppConstructor");
       
   370 
       
   371     int argc = 0;
       
   372     QApplication app(argc, 0, QApplication::GuiServer); // Needed for QFontDatabase
       
   373 
       
   374     int cnt = 0;
       
   375     QFontDatabase fdb;
       
   376     QStringList families = fdb.families();
       
   377     for (QStringList::const_iterator itr = families.begin();
       
   378 	 itr != families.end();
       
   379 	 ++itr) {
       
   380 	if (cnt < 3) {
       
   381 	    QString family = *itr;
       
   382 	    QStringList styles = fdb.styles(family);
       
   383 	    if (styles.size() > 0) {
       
   384 		QString style = styles.first();
       
   385 		QList<int> sizes = fdb.pointSizes(family, style);
       
   386 		if (!sizes.size())
       
   387 		    sizes = fdb.standardSizes();
       
   388 		if (sizes.size() > 0) {
       
   389 		    QTest::newRow(QString("data%1a").arg(cnt).toLatin1().constData())
       
   390 			<< family
       
   391 			<< sizes.first()
       
   392                         << false;
       
   393 		    QTest::newRow(QString("data%1b").arg(cnt).toLatin1().constData())
       
   394 			<< family
       
   395 			<< sizes.first()
       
   396                         << true;
       
   397                 }
       
   398 	    }
       
   399 	}
       
   400 	++cnt;
       
   401     }
       
   402 
       
   403     QTest::newRow("nonexistingfont") << "nosuchfont_probably_quiteunlikely"
       
   404         << 0 << false;
       
   405     QTest::newRow("nonexistingfont") << "nosuchfont_probably_quiteunlikely"
       
   406         << 0 << true;
       
   407 
       
   408     QTest::newRow("largescaleable") << "smoothtimes" << 100 << false;
       
   409     QTest::newRow("largescaleable") << "smoothtimes" << 100 << true;
       
   410 
       
   411     QTest::newRow("largeunscaleale") << "helvetica" << 100 << false;
       
   412     QTest::newRow("largeunscaleale") << "helvetica" << 100 << true;
       
   413 }
       
   414 
       
   415 void tst_QApplication::setFont()
       
   416 {
       
   417     QFETCH( QString, family );
       
   418     QFETCH( int, pointsize );
       
   419     QFETCH( bool, beforeAppConstructor );
       
   420 
       
   421     QFont font( family, pointsize );
       
   422     if (beforeAppConstructor) {
       
   423         QApplication::setFont( font );
       
   424         QCOMPARE(QApplication::font(), font);
       
   425     }
       
   426 
       
   427     int argc = 0;
       
   428     QApplication app( argc, 0, QApplication::GuiServer );
       
   429     if (!beforeAppConstructor)
       
   430         QApplication::setFont( font );
       
   431 
       
   432     QCOMPARE( app.font(), font );
       
   433 }
       
   434 
       
   435 void tst_QApplication::args_data()
       
   436 {
       
   437     QTest::addColumn<int>("argc_in");
       
   438     QTest::addColumn<QString>("args_in");
       
   439     QTest::addColumn<int>("argc_out");
       
   440     QTest::addColumn<QString>("args_out");
       
   441 
       
   442     QTest::newRow( "App name" ) << 1 << "/usr/bin/appname" << 1 << "/usr/bin/appname";
       
   443     QTest::newRow( "No arguments" ) << 0 << QString() << 0 << QString();
       
   444     QTest::newRow( "App name, style" ) << 3 << "/usr/bin/appname -style motif" << 1 << "/usr/bin/appname";
       
   445     QTest::newRow( "App name, style, arbitrary, reverse" ) << 5 << "/usr/bin/appname -style motif -arbitrary -reverse"
       
   446 							<< 2 << "/usr/bin/appname -arbitrary";
       
   447 }
       
   448 
       
   449 void tst_QApplication::task109149()
       
   450 {
       
   451     int argc = 0;
       
   452     QApplication app(argc, 0, QApplication::GuiServer);
       
   453     QApplication::setFont(QFont("helvetica", 100));
       
   454 
       
   455     QWidget w;
       
   456     w.setWindowTitle("hello");
       
   457     w.show();
       
   458 
       
   459     app.processEvents();
       
   460 }
       
   461 
       
   462 static char ** QString2cstrings( const QString &args )
       
   463 {
       
   464     static QList<QByteArray> cache;
       
   465 
       
   466     int i;
       
   467     char **argarray = 0;
       
   468     QStringList list = args.split(' ');;
       
   469     argarray = new char*[list.count()+1];
       
   470 
       
   471     for (i = 0; i < (int)list.count(); ++i ) {
       
   472         QByteArray l1 = list[i].toLatin1();
       
   473         argarray[i] = l1.data();
       
   474         cache.append(l1);
       
   475     }
       
   476     argarray[i] = 0;
       
   477 
       
   478     return argarray;
       
   479 }
       
   480 
       
   481 static QString cstrings2QString( char **args )
       
   482 {
       
   483     QString string;
       
   484     if ( !args )
       
   485 	return string;
       
   486 
       
   487     int i = 0;
       
   488     while ( args[i] ) {
       
   489 	string += args[i];
       
   490 	if ( args[i+1] )
       
   491 	    string += " ";
       
   492 	++i;
       
   493     }
       
   494     return string;
       
   495 }
       
   496 
       
   497 void tst_QApplication::args()
       
   498 {
       
   499     QFETCH( int, argc_in );
       
   500     QFETCH( QString, args_in );
       
   501     QFETCH( int, argc_out );
       
   502     QFETCH( QString, args_out );
       
   503 
       
   504     char **argv = QString2cstrings( args_in );
       
   505 
       
   506     QApplication app( argc_in, argv, QApplication::GuiServer );
       
   507     QString argv_out = cstrings2QString(argv);
       
   508 
       
   509     QCOMPARE( argc_in, argc_out );
       
   510     QCOMPARE( argv_out, args_out );
       
   511 
       
   512     delete [] argv;
       
   513 }
       
   514 
       
   515 class CloseWidget : public QWidget
       
   516 {
       
   517     Q_OBJECT
       
   518 public:
       
   519     CloseWidget()
       
   520     {
       
   521         startTimer(500);
       
   522     }
       
   523 
       
   524 protected:
       
   525     void timerEvent(QTimerEvent *)
       
   526     {
       
   527         close();
       
   528     }
       
   529 
       
   530 };
       
   531 
       
   532 void tst_QApplication::lastWindowClosed()
       
   533 {
       
   534     int argc = 0;
       
   535     QApplication app(argc, 0, QApplication::GuiServer);
       
   536 
       
   537     QSignalSpy spy(&app, SIGNAL(lastWindowClosed()));
       
   538 
       
   539     QPointer<QDialog> dialog = new QDialog;
       
   540     QVERIFY(dialog->testAttribute(Qt::WA_QuitOnClose));
       
   541     QTimer::singleShot(1000, dialog, SLOT(accept()));
       
   542     dialog->exec();
       
   543     QVERIFY(dialog);
       
   544     QCOMPARE(spy.count(), 0);
       
   545 
       
   546     QPointer<CloseWidget>widget = new CloseWidget;
       
   547     QVERIFY(widget->testAttribute(Qt::WA_QuitOnClose));
       
   548     QObject::connect(&app, SIGNAL(lastWindowClosed()), widget, SLOT(deleteLater()));
       
   549     app.exec();
       
   550     QVERIFY(!widget);
       
   551     QCOMPARE(spy.count(), 1);
       
   552     spy.clear();
       
   553 
       
   554 #if 0
       
   555     // everything is closed, so doing this should not emit lastWindowClosed() again
       
   556     QMetaObject::invokeMethod(dialog, "close", Qt::QueuedConnection);
       
   557     QTimer::singleShot(1000, &app, SLOT(quit()));
       
   558     app.exec();
       
   559     QCOMPARE(spy.count(), 0);
       
   560 #endif
       
   561 
       
   562     delete dialog;
       
   563 
       
   564     // show 3 windows, close them, should only get lastWindowClosed once
       
   565     QWidget w1;
       
   566     QWidget w2;
       
   567     QWidget w3;
       
   568     w1.show();
       
   569     w2.show();
       
   570     w3.show();
       
   571 
       
   572     QTimer::singleShot(1000, &app, SLOT(closeAllWindows()));
       
   573     app.exec();
       
   574     QCOMPARE(spy.count(), 1);
       
   575 }
       
   576 
       
   577 class QuitOnLastWindowClosedDialog : public QDialog
       
   578 {
       
   579     Q_OBJECT
       
   580 public:
       
   581     QPushButton *okButton;
       
   582 
       
   583     QuitOnLastWindowClosedDialog()
       
   584     {
       
   585         QHBoxLayout *hbox = new QHBoxLayout(this);
       
   586         okButton = new QPushButton("&ok", this);
       
   587 
       
   588         hbox->addWidget(okButton);
       
   589         connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
       
   590         connect(okButton, SIGNAL(clicked()), this, SLOT(ok_clicked()));
       
   591     }
       
   592 
       
   593 public slots:
       
   594     void ok_clicked()
       
   595     {
       
   596         QDialog other;
       
   597 
       
   598         QTimer timer;
       
   599         connect(&timer, SIGNAL(timeout()), &other, SLOT(accept()));
       
   600         QSignalSpy spy(&timer, SIGNAL(timeout()));
       
   601         QSignalSpy appSpy(qApp, SIGNAL(lastWindowClosed()));
       
   602 
       
   603         timer.start(1000);
       
   604         other.exec();
       
   605 
       
   606         // verify that the eventloop ran and let the timer fire
       
   607         QCOMPARE(spy.count(), 1);
       
   608         QCOMPARE(appSpy.count(), 1);
       
   609     }
       
   610 };
       
   611 
       
   612 class QuitOnLastWindowClosedWindow : public QWidget
       
   613 {
       
   614     Q_OBJECT
       
   615 
       
   616 public:
       
   617     QuitOnLastWindowClosedWindow()
       
   618     { }
       
   619 
       
   620 public slots:
       
   621     void execDialogThenShow()
       
   622     {
       
   623         QDialog dialog;
       
   624         QTimer timer1;
       
   625         connect(&timer1, SIGNAL(timeout()), &dialog, SLOT(accept()));
       
   626         QSignalSpy spy1(&timer1, SIGNAL(timeout()));
       
   627         timer1.setSingleShot(true);
       
   628         timer1.start(1000);
       
   629         dialog.exec();
       
   630         QCOMPARE(spy1.count(), 1);
       
   631 
       
   632         show();
       
   633     }
       
   634 };
       
   635 
       
   636 void tst_QApplication::quitOnLastWindowClosed()
       
   637 {
       
   638     {
       
   639         int argc = 0;
       
   640         QApplication app(argc, 0, QApplication::GuiServer);
       
   641 
       
   642         QuitOnLastWindowClosedDialog d;
       
   643         d.show();
       
   644         QTimer::singleShot(1000, d.okButton, SLOT(animateClick()));
       
   645 
       
   646         QSignalSpy appSpy(&app, SIGNAL(lastWindowClosed()));
       
   647         app.exec();
       
   648 
       
   649         // lastWindowClosed() signal should only be sent after the last dialog is closed
       
   650         QCOMPARE(appSpy.count(), 2);
       
   651     }
       
   652     {
       
   653         int argc = 0;
       
   654         QApplication app(argc, 0, QApplication::GuiServer);
       
   655         QSignalSpy appSpy(&app, SIGNAL(lastWindowClosed()));
       
   656 
       
   657         QDialog dialog;
       
   658         QTimer timer1;
       
   659         connect(&timer1, SIGNAL(timeout()), &dialog, SLOT(accept()));
       
   660         QSignalSpy spy1(&timer1, SIGNAL(timeout()));
       
   661         timer1.setSingleShot(true);
       
   662         timer1.start(1000);
       
   663         dialog.exec();
       
   664         QCOMPARE(spy1.count(), 1);
       
   665         QCOMPARE(appSpy.count(), 0);
       
   666 
       
   667         QTimer timer2;
       
   668         connect(&timer2, SIGNAL(timeout()), &app, SLOT(quit()));
       
   669         QSignalSpy spy2(&timer2, SIGNAL(timeout()));
       
   670         timer2.setSingleShot(true);
       
   671         timer2.start(1000);
       
   672         int returnValue = app.exec();
       
   673         QCOMPARE(returnValue, 0);
       
   674         QCOMPARE(spy2.count(), 1);
       
   675         QCOMPARE(appSpy.count(), 0);
       
   676     }
       
   677     {
       
   678         int argc = 0;
       
   679         QApplication app(argc, 0, QApplication::GuiServer);
       
   680         QTimer timer;
       
   681         timer.setInterval(100);
       
   682 
       
   683         QSignalSpy spy(&app, SIGNAL(aboutToQuit()));
       
   684         QSignalSpy spy2(&timer, SIGNAL(timeout()));
       
   685 
       
   686         QPointer<QMainWindow> mainWindow = new QMainWindow;
       
   687         QPointer<QDialog> dialog = new QDialog(mainWindow);
       
   688 
       
   689         QVERIFY(app.quitOnLastWindowClosed());
       
   690         QVERIFY(mainWindow->testAttribute(Qt::WA_QuitOnClose));
       
   691         QVERIFY(dialog->testAttribute(Qt::WA_QuitOnClose));
       
   692 
       
   693         mainWindow->show();
       
   694         dialog->show();
       
   695 
       
   696         timer.start();
       
   697         QTimer::singleShot(1000, mainWindow, SLOT(close())); // This should quit the application
       
   698         QTimer::singleShot(2000, &app, SLOT(quit()));        // This makes sure we quit even if it didn't
       
   699 
       
   700         app.exec();
       
   701 
       
   702         QCOMPARE(spy.count(), 1);
       
   703         QVERIFY(spy2.count() < 15);      // Should be around 10 if closing caused the quit
       
   704     }
       
   705     {
       
   706         int argc = 0;
       
   707         QApplication app(argc, 0, QApplication::GuiServer);
       
   708         QTimer timer;
       
   709         timer.setInterval(100);
       
   710 
       
   711         QSignalSpy spy(&app, SIGNAL(aboutToQuit()));
       
   712         QSignalSpy spy2(&timer, SIGNAL(timeout()));
       
   713 
       
   714         QPointer<QMainWindow> mainWindow = new QMainWindow;
       
   715         QPointer<QWidget> invisibleTopLevelWidget = new QWidget;
       
   716         invisibleTopLevelWidget->setAttribute(Qt::WA_DontShowOnScreen);
       
   717 
       
   718         QVERIFY(app.quitOnLastWindowClosed());
       
   719         QVERIFY(mainWindow->testAttribute(Qt::WA_QuitOnClose));
       
   720         QVERIFY(invisibleTopLevelWidget->testAttribute(Qt::WA_QuitOnClose));
       
   721         QVERIFY(invisibleTopLevelWidget->testAttribute(Qt::WA_DontShowOnScreen));
       
   722 
       
   723         mainWindow->show();
       
   724         invisibleTopLevelWidget->show();
       
   725 
       
   726         timer.start();
       
   727         QTimer::singleShot(1000, mainWindow, SLOT(close())); // This should quit the application
       
   728         QTimer::singleShot(2000, &app, SLOT(quit()));        // This makes sure we quit even if it didn't
       
   729 
       
   730         app.exec();
       
   731 
       
   732         QCOMPARE(spy.count(), 1);
       
   733         QVERIFY(spy2.count() < 15);      // Should be around 10 if closing caused the quit
       
   734     }
       
   735     {
       
   736         int argc = 0;
       
   737         QApplication app(argc, 0, QApplication::GuiServer);
       
   738         QTimer timer;
       
   739         timer.setInterval(100);
       
   740 
       
   741         QSignalSpy spy(&app, SIGNAL(aboutToQuit()));
       
   742         QSignalSpy spy2(&timer, SIGNAL(timeout()));
       
   743 
       
   744         QPointer<CloseEventTestWindow> mainWindow = new CloseEventTestWindow;
       
   745 
       
   746         QVERIFY(app.quitOnLastWindowClosed());
       
   747         QVERIFY(mainWindow->testAttribute(Qt::WA_QuitOnClose));
       
   748 
       
   749         mainWindow->show();
       
   750 
       
   751         timer.start();
       
   752         QTimer::singleShot(1000, mainWindow, SLOT(close())); // This should quit the application
       
   753         QTimer::singleShot(2000, &app, SLOT(quit()));        // This makes sure we quit even if it didn't
       
   754 
       
   755         app.exec();
       
   756 
       
   757         QCOMPARE(spy.count(), 1);
       
   758         QVERIFY(spy2.count() > 15);      // Should be around 20 if closing did not caused the quit
       
   759     }
       
   760     {
       
   761         int argc = 0;
       
   762         QApplication app(argc, 0, QApplication::GuiServer);
       
   763         QSignalSpy appSpy(&app, SIGNAL(lastWindowClosed()));
       
   764 
       
   765         // exec a dialog for 1 second, then show the window
       
   766         QuitOnLastWindowClosedWindow window;
       
   767         QTimer::singleShot(0, &window, SLOT(execDialogThenShow()));
       
   768 
       
   769         QTimer timer;
       
   770         QSignalSpy timerSpy(&timer, SIGNAL(timeout()));
       
   771         connect(&timer, SIGNAL(timeout()), &window, SLOT(close()));
       
   772         timer.setSingleShot(true);
       
   773         timer.start(2000);
       
   774         int returnValue = app.exec();
       
   775         QCOMPARE(returnValue, 0);
       
   776         // failure here means the timer above didn't fire, and the
       
   777         // quit was caused the the dialog being closed (not the window)
       
   778         QCOMPARE(timerSpy.count(), 1);
       
   779         QCOMPARE(appSpy.count(), 2);
       
   780     }
       
   781 }
       
   782 
       
   783 bool isPathListIncluded(const QStringList &l, const QStringList &r)
       
   784 {
       
   785     int size = r.count();
       
   786     if (size > l.count())
       
   787         return false;
       
   788 #if defined (Q_OS_WIN)
       
   789     Qt::CaseSensitivity cs = Qt::CaseInsensitive;
       
   790 #else
       
   791     Qt::CaseSensitivity cs = Qt::CaseSensitive;
       
   792 #endif
       
   793     int i = 0, j = 0;
       
   794     for ( ; i < l.count() && j < r.count(); ++i) {
       
   795         if (QDir::toNativeSeparators(l[i]).compare(QDir::toNativeSeparators(r[j]), cs) == 0) {
       
   796             ++j;
       
   797             i = -1;
       
   798         }
       
   799     }
       
   800     return j == r.count();
       
   801 }
       
   802 
       
   803 #define QT_TST_QAPP_DEBUG
       
   804 void tst_QApplication::libraryPaths()
       
   805 {
       
   806     {
       
   807 #ifndef Q_OS_WINCE
       
   808         QString testDir = QDir::current().canonicalPath() + "/test";
       
   809 #else
       
   810         // On Windows CE we need QApplication object to have valid
       
   811         // current Path. Therefore we need to identify it ourselves
       
   812         // here for the test.
       
   813         QFileInfo filePath;
       
   814         wchar_t module_name[MAX_PATH];
       
   815         GetModuleFileName(0, module_name, MAX_PATH);
       
   816         filePath = QString::fromWCharArray(module_name);
       
   817         QString testDir = filePath.path() + "/test";
       
   818 #endif
       
   819         QApplication::setLibraryPaths(QStringList() << testDir);
       
   820         QCOMPARE(QApplication::libraryPaths(), (QStringList() << testDir));
       
   821 
       
   822         // creating QApplication adds the applicationDirPath to the libraryPath
       
   823         int argc = 1;
       
   824         QApplication app(argc, &argv0, QApplication::GuiServer);
       
   825         QString appDirPath = QDir(app.applicationDirPath()).canonicalPath();
       
   826 
       
   827         QStringList actual = QApplication::libraryPaths();
       
   828         actual.sort();
       
   829         QStringList expected = QSet<QString>::fromList((QStringList() << testDir << appDirPath)).toList();
       
   830         expected.sort();
       
   831 
       
   832         QVERIFY2(isPathListIncluded(actual, expected),
       
   833                  qPrintable("actual:\n - " + actual.join("\n - ") +
       
   834                             "\nexpected:\n - " + expected.join("\n - ")));
       
   835     }
       
   836     {
       
   837         // creating QApplication adds the applicationDirPath and plugin install path to the libraryPath
       
   838         int argc = 1;
       
   839         QApplication app(argc, &argv0, QApplication::GuiServer);
       
   840         QString appDirPath = app.applicationDirPath();
       
   841         QString installPathPlugins =  QLibraryInfo::location(QLibraryInfo::PluginsPath);
       
   842 
       
   843         QStringList actual = QApplication::libraryPaths();
       
   844         actual.sort();
       
   845 
       
   846 #if defined(Q_OS_SYMBIAN)
       
   847         QStringList expected;
       
   848         addExpectedSymbianPluginsPath(expected);
       
   849         expected << appDirPath;
       
   850 #else
       
   851         QStringList expected = QSet<QString>::fromList((QStringList() << installPathPlugins << appDirPath)).toList();
       
   852 #endif
       
   853         expected.sort();
       
   854 
       
   855         QVERIFY2(isPathListIncluded(actual, expected),
       
   856                  qPrintable("actual:\n - " + actual.join("\n - ") +
       
   857                             "\nexpected:\n - " + expected.join("\n - ")));
       
   858 
       
   859         // setting the library paths overrides everything
       
   860         QString testDir = QDir::currentPath() + "/test";
       
   861         QApplication::setLibraryPaths(QStringList() << testDir);
       
   862         QVERIFY2(isPathListIncluded(QApplication::libraryPaths(), (QStringList() << testDir)),
       
   863                  qPrintable("actual:\n - " + QApplication::libraryPaths().join("\n - ") +
       
   864                             "\nexpected:\n - " + testDir));
       
   865     }
       
   866     {
       
   867 #ifdef QT_TST_QAPP_DEBUG
       
   868         qDebug() << "Initial library path:" << QApplication::libraryPaths();
       
   869 #endif
       
   870 
       
   871         int count = QApplication::libraryPaths().count();
       
   872 #if 0
       
   873         // this test doesn't work if KDE 4 is installed
       
   874         QCOMPARE(count, 1); // before creating QApplication, only the PluginsPath is in the libraryPaths()
       
   875 #endif
       
   876         QString installPathPlugins =  QLibraryInfo::location(QLibraryInfo::PluginsPath);
       
   877         QApplication::addLibraryPath(installPathPlugins);
       
   878 #ifdef QT_TST_QAPP_DEBUG
       
   879         qDebug() << "installPathPlugins" << installPathPlugins;
       
   880         qDebug() << "After adding plugins path:" << QApplication::libraryPaths();
       
   881 #endif
       
   882         QCOMPARE(QApplication::libraryPaths().count(), count);
       
   883 
       
   884         QApplication::addLibraryPath(QDir::currentPath() + "/test");
       
   885         QCOMPARE(QApplication::libraryPaths().count(), count + 1);
       
   886 
       
   887         // creating QApplication adds the applicationDirPath to the libraryPath
       
   888         int argc = 1;
       
   889         QApplication app(argc, &argv0, QApplication::GuiServer);
       
   890         QString appDirPath = app.applicationDirPath();
       
   891         qDebug() << QApplication::libraryPaths();
       
   892         // On Windows CE these are identical and might also be the case for other
       
   893         // systems too
       
   894         if (appDirPath != installPathPlugins)
       
   895             QCOMPARE(QApplication::libraryPaths().count(), count + 2);
       
   896     }
       
   897     {
       
   898         int argc = 1;
       
   899         QApplication app(argc, &argv0, QApplication::GuiServer);
       
   900 
       
   901 #ifdef QT_TST_QAPP_DEBUG
       
   902         qDebug() << "Initial library path:" << app.libraryPaths();
       
   903 #endif
       
   904         int count = app.libraryPaths().count();
       
   905         QString installPathPlugins =  QLibraryInfo::location(QLibraryInfo::PluginsPath);
       
   906         app.addLibraryPath(installPathPlugins);
       
   907 #ifdef QT_TST_QAPP_DEBUG
       
   908         qDebug() << "installPathPlugins" << installPathPlugins;
       
   909         qDebug() << "After adding plugins path:" << app.libraryPaths();
       
   910 #endif
       
   911         QCOMPARE(app.libraryPaths().count(), count);
       
   912 
       
   913         QString appDirPath = app.applicationDirPath();
       
   914 
       
   915         app.addLibraryPath(appDirPath);
       
   916 #ifdef Q_OS_WINCE
       
   917         app.addLibraryPath(appDirPath + "/../..");
       
   918 #else
       
   919         app.addLibraryPath(appDirPath + "/..");
       
   920 #endif
       
   921 #ifdef QT_TST_QAPP_DEBUG
       
   922         qDebug() << "appDirPath" << appDirPath;
       
   923         qDebug() << "After adding appDirPath && appDirPath + /..:" << app.libraryPaths();
       
   924 #endif
       
   925         QCOMPARE(app.libraryPaths().count(), count + 1);
       
   926 #ifdef Q_OS_MAC
       
   927         app.addLibraryPath(appDirPath + "/../MacOS");
       
   928 #else
       
   929         app.addLibraryPath(appDirPath + "/tmp/..");
       
   930 #endif
       
   931 #ifdef QT_TST_QAPP_DEBUG
       
   932         qDebug() << "After adding appDirPath + /tmp/..:" << app.libraryPaths();
       
   933 #endif
       
   934         QCOMPARE(app.libraryPaths().count(), count + 1);
       
   935     }
       
   936 }
       
   937 
       
   938 void tst_QApplication::libraryPaths_qt_plugin_path()
       
   939 {
       
   940     int argc = 1;
       
   941 
       
   942     QApplication app(argc, &argv0, QApplication::GuiServer);
       
   943     QString appDirPath = app.applicationDirPath();
       
   944 
       
   945     // Our hook into libraryPaths() initialization: Set the QT_PLUGIN_PATH environment variable
       
   946     QString installPathPluginsDeCanon = appDirPath + QString::fromLatin1("/tmp/..");
       
   947     QByteArray ascii = installPathPluginsDeCanon.toAscii();
       
   948     qputenv("QT_PLUGIN_PATH", ascii);
       
   949 
       
   950     QVERIFY(!app.libraryPaths().contains(appDirPath + QString::fromLatin1("/tmp/..")));
       
   951 }
       
   952 
       
   953 void tst_QApplication::libraryPaths_qt_plugin_path_2()
       
   954 {
       
   955 #ifdef Q_OS_SYMBIAN
       
   956     QByteArray validPath = "C:\\data";
       
   957     QByteArray nonExistentPath = "Z:\\nonexistent";
       
   958     QByteArray pluginPath = validPath + ";" + nonExistentPath;
       
   959 #elif defined(Q_OS_UNIX)
       
   960     QByteArray validPath = QDir("/tmp").canonicalPath().toLatin1();
       
   961     QByteArray nonExistentPath = "/nonexistent";
       
   962     QByteArray pluginPath = validPath + ":" + nonExistentPath;
       
   963 #elif defined(Q_OS_WIN)
       
   964 # ifdef Q_OS_WINCE
       
   965     QByteArray validPath = "/Temp";
       
   966     QByteArray nonExistentPath = "/nonexistent";
       
   967     QByteArray pluginPath = validPath + ";" + nonExistentPath;
       
   968 # else
       
   969     QByteArray validPath = "C:\\windows";
       
   970     QByteArray nonExistentPath = "Z:\\nonexistent";
       
   971     QByteArray pluginPath = validPath + ";" + nonExistentPath;
       
   972 # endif
       
   973 #endif
       
   974 
       
   975     {
       
   976         // Our hook into libraryPaths() initialization: Set the QT_PLUGIN_PATH environment variable
       
   977         qputenv("QT_PLUGIN_PATH", pluginPath);
       
   978 
       
   979         int argc = 1;
       
   980 
       
   981         QApplication app(argc, &argv0, QApplication::GuiServer);
       
   982 
       
   983         // library path list should contain the default plus the one valid path
       
   984 #if defined(Q_OS_SYMBIAN)
       
   985         // In Symbian, the PluginsPath doesn't specify the only absolute path; just the dir that can be found on any drive
       
   986         QStringList expected;
       
   987         addExpectedSymbianPluginsPath(expected);
       
   988         expected << QDir(app.applicationDirPath()).canonicalPath()
       
   989             << QDir(QDir::fromNativeSeparators(QString::fromLatin1(validPath))).canonicalPath();
       
   990 #else
       
   991         QStringList expected =
       
   992             QStringList()
       
   993             << QLibraryInfo::location(QLibraryInfo::PluginsPath)
       
   994             << QDir(app.applicationDirPath()).canonicalPath()
       
   995             << QDir(QDir::fromNativeSeparators(QString::fromLatin1(validPath))).canonicalPath();
       
   996 # ifdef Q_OS_WINCE
       
   997         expected = QSet<QString>::fromList(expected).toList();
       
   998 # endif
       
   999 #endif
       
  1000         QVERIFY2(isPathListIncluded(app.libraryPaths(), expected),
       
  1001                  qPrintable("actual:\n - " + app.libraryPaths().join("\n - ") +
       
  1002                             "\nexpected:\n - " + expected.join("\n - ")));
       
  1003     }
       
  1004 
       
  1005     {
       
  1006         int argc = 1;
       
  1007 
       
  1008         QApplication app(argc, &argv0, QApplication::GuiServer);
       
  1009 
       
  1010         // library paths are initialized by the QApplication, setting
       
  1011         // the environment variable here doesn't work
       
  1012         qputenv("QT_PLUGIN_PATH", pluginPath);
       
  1013 
       
  1014         // library path list should contain the default
       
  1015 #if defined(Q_OS_SYMBIAN)
       
  1016         QStringList expected;
       
  1017         addExpectedSymbianPluginsPath(expected);
       
  1018         expected << app.applicationDirPath();
       
  1019 #else
       
  1020         QStringList expected =
       
  1021             QStringList()
       
  1022             << QLibraryInfo::location(QLibraryInfo::PluginsPath)
       
  1023             << app.applicationDirPath();
       
  1024 # ifdef Q_OS_WINCE
       
  1025         expected = QSet<QString>::fromList(expected).toList();
       
  1026 # endif
       
  1027 #endif
       
  1028         QVERIFY(isPathListIncluded(app.libraryPaths(), expected));
       
  1029 
       
  1030         qputenv("QT_PLUGIN_PATH", QByteArray());
       
  1031     }
       
  1032 }
       
  1033 
       
  1034 class SendPostedEventsTester : public QObject
       
  1035 {
       
  1036     Q_OBJECT
       
  1037 public:
       
  1038     QList<int> eventSpy;
       
  1039     bool event(QEvent *e);
       
  1040 private slots:
       
  1041     void doTest();
       
  1042 };
       
  1043 
       
  1044 bool SendPostedEventsTester::event(QEvent *e)
       
  1045 {
       
  1046     eventSpy.append(e->type());
       
  1047     return QObject::event(e);
       
  1048 }
       
  1049 
       
  1050 void SendPostedEventsTester::doTest()
       
  1051 {
       
  1052     QPointer<SendPostedEventsTester> p = this;
       
  1053     QApplication::postEvent(this, new QEvent(QEvent::User));
       
  1054     // DeferredDelete should not be delivered until returning from this function
       
  1055     QApplication::postEvent(this, new QEvent(QEvent::DeferredDelete));
       
  1056 
       
  1057     QEventLoop eventLoop;
       
  1058     QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
       
  1059     eventLoop.exec();
       
  1060     QVERIFY(p != 0);
       
  1061 
       
  1062     QCOMPARE(eventSpy.count(), 2);
       
  1063     QCOMPARE(eventSpy.at(0), int(QEvent::MetaCall));
       
  1064     QCOMPARE(eventSpy.at(1), int(QEvent::User));
       
  1065     eventSpy.clear();
       
  1066 }
       
  1067 
       
  1068 void tst_QApplication::sendPostedEvents()
       
  1069 {
       
  1070     int argc = 0;
       
  1071     QApplication app(argc, 0, QApplication::GuiServer);
       
  1072     SendPostedEventsTester *tester = new SendPostedEventsTester;
       
  1073     QMetaObject::invokeMethod(tester, "doTest", Qt::QueuedConnection);
       
  1074     QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection);
       
  1075     QPointer<SendPostedEventsTester> p = tester;
       
  1076     (void) app.exec();
       
  1077     QVERIFY(p == 0);
       
  1078 }
       
  1079 
       
  1080 void tst_QApplication::thread()
       
  1081 {
       
  1082     QThread *currentThread = QThread::currentThread();
       
  1083     // no app, but still have a valid thread
       
  1084     QVERIFY(currentThread != 0);
       
  1085 
       
  1086     // the thread should be running and not finished
       
  1087     QVERIFY(currentThread->isRunning());
       
  1088     QVERIFY(!currentThread->isFinished());
       
  1089 
       
  1090     // this should probably be in the tst_QObject::thread() test, but
       
  1091     // we put it here since we want to make sure that objects created
       
  1092     // *before* the QApplication has a thread
       
  1093     QObject object;
       
  1094     QObject child(&object);
       
  1095     QVERIFY(object.thread() == currentThread);
       
  1096     QVERIFY(child.thread() == currentThread);
       
  1097 
       
  1098     {
       
  1099         int argc = 0;
       
  1100         QApplication app(argc, 0, QApplication::GuiServer);
       
  1101 
       
  1102         // current thread still valid
       
  1103         QVERIFY(QThread::currentThread() != 0);
       
  1104         // thread should be the same as before
       
  1105         QCOMPARE(QThread::currentThread(), currentThread);
       
  1106 
       
  1107         // app's thread should be the current thread
       
  1108         QCOMPARE(app.thread(), currentThread);
       
  1109 
       
  1110         // the thread should still be running and not finished
       
  1111         QVERIFY(currentThread->isRunning());
       
  1112         QVERIFY(!currentThread->isFinished());
       
  1113 
       
  1114         QTestEventLoop::instance().enterLoop(1);
       
  1115     }
       
  1116 
       
  1117     // app dead, current thread still valid
       
  1118     QVERIFY(QThread::currentThread() != 0);
       
  1119     QCOMPARE(QThread::currentThread(), currentThread);
       
  1120 
       
  1121     // the thread should still be running and not finished
       
  1122     QVERIFY(currentThread->isRunning());
       
  1123     QVERIFY(!currentThread->isFinished());
       
  1124 
       
  1125     // should still have a thread
       
  1126     QVERIFY(object.thread() == currentThread);
       
  1127     QVERIFY(child.thread() == currentThread);
       
  1128 
       
  1129     // do the test again, making sure that the thread is the same as
       
  1130     // before
       
  1131     {
       
  1132         int argc = 0;
       
  1133         QApplication app(argc, 0, QApplication::GuiServer);
       
  1134 
       
  1135         // current thread still valid
       
  1136         QVERIFY(QThread::currentThread() != 0);
       
  1137         // thread should be the same as before
       
  1138         QCOMPARE(QThread::currentThread(), currentThread);
       
  1139 
       
  1140         // app's thread should be the current thread
       
  1141         QCOMPARE(app.thread(), currentThread);
       
  1142 
       
  1143         // the thread should be running and not finished
       
  1144         QVERIFY(currentThread->isRunning());
       
  1145         QVERIFY(!currentThread->isFinished());
       
  1146 
       
  1147         // should still have a thread
       
  1148         QVERIFY(object.thread() == currentThread);
       
  1149         QVERIFY(child.thread() == currentThread);
       
  1150 
       
  1151         QTestEventLoop::instance().enterLoop(1);
       
  1152     }
       
  1153 
       
  1154     // app dead, current thread still valid
       
  1155     QVERIFY(QThread::currentThread() != 0);
       
  1156     QCOMPARE(QThread::currentThread(), currentThread);
       
  1157 
       
  1158     // the thread should still be running and not finished
       
  1159     QVERIFY(currentThread->isRunning());
       
  1160     QVERIFY(!currentThread->isFinished());
       
  1161 
       
  1162     // should still have a thread
       
  1163     QVERIFY(object.thread() == currentThread);
       
  1164     QVERIFY(child.thread() == currentThread);
       
  1165 }
       
  1166 
       
  1167 class DeleteLaterWidget : public QWidget
       
  1168 {
       
  1169     Q_OBJECT
       
  1170 public:
       
  1171     DeleteLaterWidget(QApplication *_app, QWidget *parent = 0)
       
  1172         : QWidget(parent) { app = _app; child_deleted = false; }
       
  1173 
       
  1174     bool child_deleted;
       
  1175     QApplication *app;
       
  1176 
       
  1177 public slots:
       
  1178     void runTest();
       
  1179     void checkDeleteLater();
       
  1180     void childDeleted() { child_deleted = true; }
       
  1181 };
       
  1182 
       
  1183 
       
  1184 void DeleteLaterWidget::runTest()
       
  1185 {
       
  1186     QObject *stillAlive = qFindChild<QObject*>(this, "deleteLater");
       
  1187 
       
  1188     QWidget *w = new QWidget(this);
       
  1189     connect(w, SIGNAL(destroyed()), this, SLOT(childDeleted()));
       
  1190 
       
  1191     w->deleteLater();
       
  1192     QVERIFY(!child_deleted);
       
  1193 
       
  1194     QDialog dlg;
       
  1195     QTimer::singleShot(500, &dlg, SLOT(reject()));
       
  1196     dlg.exec();
       
  1197 
       
  1198     QVERIFY(!child_deleted);
       
  1199     app->processEvents();
       
  1200     QVERIFY(!child_deleted);
       
  1201 
       
  1202     QTimer::singleShot(500, this, SLOT(checkDeleteLater()));
       
  1203 
       
  1204     app->processEvents();
       
  1205 
       
  1206     QVERIFY(!stillAlive); // verify at the end to make test terminate
       
  1207 }
       
  1208 
       
  1209 void DeleteLaterWidget::checkDeleteLater()
       
  1210 {
       
  1211     QVERIFY(child_deleted);
       
  1212 
       
  1213     close();
       
  1214 }
       
  1215 
       
  1216 void tst_QApplication::testDeleteLater()
       
  1217 {
       
  1218     int argc = 0;
       
  1219     QApplication app(argc, 0, QApplication::GuiServer);
       
  1220     connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
       
  1221 
       
  1222     DeleteLaterWidget *wgt = new DeleteLaterWidget(&app);
       
  1223     QTimer::singleShot(500, wgt, SLOT(runTest()));
       
  1224 
       
  1225     QObject *object = new QObject(wgt);
       
  1226     object->setObjectName("deleteLater");
       
  1227     object->deleteLater();
       
  1228 
       
  1229     QObject *stillAlive = qFindChild<QObject*>(wgt, "deleteLater");
       
  1230     QVERIFY(stillAlive);
       
  1231 
       
  1232     app.exec();
       
  1233 
       
  1234     delete wgt;
       
  1235 
       
  1236 }
       
  1237 
       
  1238 class EventLoopNester : public QObject
       
  1239 {
       
  1240     Q_OBJECT
       
  1241 public slots:
       
  1242     void deleteLaterAndEnterLoop()
       
  1243     {
       
  1244         QEventLoop eventLoop;
       
  1245         QPointer<QObject> p(this);
       
  1246         deleteLater();
       
  1247         
       
  1248         // DeferredDelete events are compressed, meaning this second
       
  1249         // deleteLater() will *not* delete the object in the nested
       
  1250         // event loop
       
  1251         QMetaObject::invokeMethod(this, "deleteLater", Qt::QueuedConnection);
       
  1252         QTimer::singleShot(1000, &eventLoop, SLOT(quit()));
       
  1253         eventLoop.exec();
       
  1254         QVERIFY(p);
       
  1255     }
       
  1256     void deleteLaterAndExitLoop()
       
  1257     {
       
  1258         // Check that 'p' is not deleted before exec returns, since the call
       
  1259         // to QEventLoop::quit() should stop 'eventLoop' from processing
       
  1260         // any more events (that is, delete later) until we return to the
       
  1261         // _current_ event loop:
       
  1262         QEventLoop eventLoop;
       
  1263         QPointer<QObject> p(this);
       
  1264         QMetaObject::invokeMethod(this, "deleteLater", Qt::QueuedConnection);
       
  1265         QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
       
  1266         eventLoop.exec();
       
  1267         QVERIFY(p); // not dead yet
       
  1268     }
       
  1269 
       
  1270     void processEventsOnly()
       
  1271     {
       
  1272         QApplication::processEvents();
       
  1273     }
       
  1274     void processEventsWithDeferredDeletion()
       
  1275     {
       
  1276         QApplication::processEvents(QEventLoop::DeferredDeletion);
       
  1277     }
       
  1278     void sendPostedEventsWithDeferredDelete()
       
  1279     {
       
  1280         QApplication::sendPostedEvents(0, QEvent::DeferredDelete);
       
  1281     }
       
  1282     void deleteLaterAndProcessEvents1()
       
  1283     {
       
  1284         QEventLoop eventLoop;
       
  1285 
       
  1286         QPointer<QObject> p = this;
       
  1287         deleteLater();
       
  1288 
       
  1289         // trying to delete this object in a deeper eventloop just won't work
       
  1290         QMetaObject::invokeMethod(this,
       
  1291                                   "processEventsOnly",
       
  1292                                   Qt::QueuedConnection);
       
  1293         QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
       
  1294         eventLoop.exec();
       
  1295         QVERIFY(p);
       
  1296         QMetaObject::invokeMethod(this,
       
  1297                                   "processEventsWithDeferredDeletion",
       
  1298                                   Qt::QueuedConnection);
       
  1299         QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
       
  1300         eventLoop.exec();
       
  1301         QVERIFY(p);
       
  1302         QMetaObject::invokeMethod(this,
       
  1303                                   "sendPostedEventsWithDeferredDelete",
       
  1304                                   Qt::QueuedConnection);
       
  1305         QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
       
  1306         eventLoop.exec();
       
  1307         QVERIFY(p);
       
  1308 
       
  1309         // trying to delete it from this eventloop still doesn't work
       
  1310         QApplication::processEvents();
       
  1311         QVERIFY(p);
       
  1312 
       
  1313         // however, it *will* work with this magic incantation
       
  1314         QApplication::processEvents(QEventLoop::DeferredDeletion);
       
  1315         QVERIFY(!p);
       
  1316     }
       
  1317 
       
  1318     void deleteLaterAndProcessEvents2()
       
  1319     {
       
  1320         QEventLoop eventLoop;
       
  1321 
       
  1322         QPointer<QObject> p = this;
       
  1323         deleteLater();
       
  1324 
       
  1325         // trying to delete this object in a deeper eventloop just won't work
       
  1326         QMetaObject::invokeMethod(this,
       
  1327                                   "processEventsOnly",
       
  1328                                   Qt::QueuedConnection);
       
  1329         QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
       
  1330         eventLoop.exec();
       
  1331         QVERIFY(p);
       
  1332         QMetaObject::invokeMethod(this,
       
  1333                                   "processEventsWithDeferredDeletion",
       
  1334                                   Qt::QueuedConnection);
       
  1335         QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
       
  1336         eventLoop.exec();
       
  1337         QVERIFY(p);
       
  1338         QMetaObject::invokeMethod(this,
       
  1339                                   "sendPostedEventsWithDeferredDelete",
       
  1340                                   Qt::QueuedConnection);
       
  1341         QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
       
  1342         eventLoop.exec();
       
  1343         QVERIFY(p);
       
  1344 
       
  1345         // trying to delete it from this eventloop still doesn't work
       
  1346         QApplication::processEvents();
       
  1347         QVERIFY(p);
       
  1348 
       
  1349         // however, it *will* work with this magic incantation
       
  1350         QApplication::sendPostedEvents(0, QEvent::DeferredDelete);
       
  1351         QVERIFY(!p);
       
  1352     }
       
  1353 };
       
  1354 
       
  1355 void tst_QApplication::testDeleteLaterProcessEvents()
       
  1356 {
       
  1357     int argc = 0;
       
  1358 
       
  1359     // Calling processEvents() with no event dispatcher does nothing.
       
  1360     QObject *object = new QObject;
       
  1361     QPointer<QObject> p(object);
       
  1362     object->deleteLater();
       
  1363     QApplication::processEvents();
       
  1364     QVERIFY(p);
       
  1365     delete object;
       
  1366 
       
  1367     {
       
  1368         QApplication app(argc, 0, QApplication::GuiServer);
       
  1369         // If you call processEvents() with an event dispatcher present, but
       
  1370         // outside any event loops, deferred deletes are not processed unless
       
  1371         // QEventLoop::DeferredDeletion is passed.
       
  1372         object = new QObject;
       
  1373         p = object;
       
  1374         object->deleteLater();
       
  1375         app.processEvents();
       
  1376         QVERIFY(p);
       
  1377         app.processEvents(QEventLoop::ProcessEventsFlag(0x10)); // 0x10 == QEventLoop::DeferredDeletion
       
  1378         QVERIFY(!p);
       
  1379 
       
  1380         // sendPostedEvents(0, DeferredDelete); also works
       
  1381         object = new QObject;
       
  1382         p = object;
       
  1383         object->deleteLater();
       
  1384         app.processEvents();
       
  1385         QVERIFY(p);
       
  1386         QApplication::sendPostedEvents(0, QEvent::DeferredDelete);
       
  1387         QVERIFY(!p);
       
  1388 
       
  1389         // If you call deleteLater() on an object when there is no parent
       
  1390         // event loop, and then enter an event loop, the object will get
       
  1391         // deleted.
       
  1392         object = new QObject;
       
  1393         p = object;
       
  1394         object->deleteLater();
       
  1395         QEventLoop loop;
       
  1396         QTimer::singleShot(1000, &loop, SLOT(quit()));
       
  1397         loop.exec();
       
  1398         QVERIFY(!p);
       
  1399     }
       
  1400     {
       
  1401         // When an object is in an event loop, then calls deleteLater() and enters
       
  1402         // an event loop recursively, it should not die until the parent event
       
  1403         // loop continues.
       
  1404         QApplication app(argc, 0, QApplication::GuiServer);
       
  1405         QEventLoop loop;
       
  1406         EventLoopNester *nester = new EventLoopNester;
       
  1407         p = nester;
       
  1408         QTimer::singleShot(3000, &loop, SLOT(quit()));
       
  1409         QTimer::singleShot(0, nester, SLOT(deleteLaterAndEnterLoop()));
       
  1410 
       
  1411         loop.exec();
       
  1412         QVERIFY(!p);
       
  1413     }
       
  1414 
       
  1415     {
       
  1416         // When the event loop that calls deleteLater() is exited
       
  1417         // immediately, the object should die when returning to the
       
  1418         // parent event loop
       
  1419         QApplication app(argc, 0, QApplication::GuiServer);
       
  1420         QEventLoop loop;
       
  1421         EventLoopNester *nester = new EventLoopNester;
       
  1422         p = nester;
       
  1423         QTimer::singleShot(3000, &loop, SLOT(quit()));
       
  1424         QTimer::singleShot(0, nester, SLOT(deleteLaterAndExitLoop()));
       
  1425 
       
  1426         loop.exec();
       
  1427         QVERIFY(!p);
       
  1428     }
       
  1429 
       
  1430     {
       
  1431         // when the event loop that calls deleteLater() also calls
       
  1432         // processEvents() immediately afterwards, the object should
       
  1433         // not die until the parent loop continues
       
  1434         QApplication app(argc, 0, QApplication::GuiServer);
       
  1435         QEventLoop loop;
       
  1436         EventLoopNester *nester = new EventLoopNester();
       
  1437         p = nester;
       
  1438         QTimer::singleShot(3000, &loop, SLOT(quit()));
       
  1439         QTimer::singleShot(0, nester, SLOT(deleteLaterAndProcessEvents1()));
       
  1440 
       
  1441         loop.exec();
       
  1442         QVERIFY(!p);
       
  1443     }
       
  1444 
       
  1445     {
       
  1446         // when the event loop that calls deleteLater() also calls
       
  1447         // processEvents() immediately afterwards, the object should
       
  1448         // not die until the parent loop continues
       
  1449         QApplication app(argc, 0, QApplication::GuiServer);
       
  1450         QEventLoop loop;
       
  1451         EventLoopNester *nester = new EventLoopNester();
       
  1452         p = nester;
       
  1453         QTimer::singleShot(3000, &loop, SLOT(quit()));
       
  1454         QTimer::singleShot(0, nester, SLOT(deleteLaterAndProcessEvents2()));
       
  1455 
       
  1456         loop.exec();
       
  1457         QVERIFY(!p);
       
  1458     }
       
  1459 }
       
  1460 
       
  1461 
       
  1462 //    Test for crash whith QApplication::setDesktopSettingsAware(false).
       
  1463 
       
  1464 void tst_QApplication::desktopSettingsAware()
       
  1465 {
       
  1466 #ifndef QT_NO_PROCESS
       
  1467     QProcess testProcess;
       
  1468 #ifdef Q_OS_WINCE
       
  1469     int argc = 0;
       
  1470     QApplication tmpApp(argc, 0, QApplication::GuiServer);
       
  1471     testProcess.start("desktopsettingsaware/desktopsettingsaware");
       
  1472 #else
       
  1473 #if defined(Q_OS_WIN) && defined(QT_DEBUG)
       
  1474     testProcess.start("desktopsettingsaware/debug/desktopsettingsaware");
       
  1475 #elif defined(Q_OS_WIN)
       
  1476     testProcess.start("desktopsettingsaware/release/desktopsettingsaware");
       
  1477 #elif defined(Q_OS_SYMBIAN)
       
  1478     testProcess.start("desktopsettingsaware");
       
  1479 #if defined(Q_CC_NOKIAX86)
       
  1480     QEXPECT_FAIL("", "QProcess on Q_CC_NOKIAX86 cannot launch another Qt application, due to DLL conflicts.", Abort);
       
  1481     // TODO: Remove XFAIL, as soon as we can launch Qt applications from within Qt applications on Symbian
       
  1482     QVERIFY(testProcess.error() != QProcess::FailedToStart);
       
  1483 #endif // defined(Q_CC_NOKIAX86)
       
  1484 #else
       
  1485     testProcess.start("desktopsettingsaware/desktopsettingsaware");
       
  1486 #endif
       
  1487 #endif
       
  1488     QVERIFY(testProcess.waitForFinished(10000));
       
  1489     QCOMPARE(int(testProcess.state()), int(QProcess::NotRunning));
       
  1490     QVERIFY(int(testProcess.error()) != int(QProcess::Crashed));
       
  1491 #endif
       
  1492 }
       
  1493 */
       
  1494 
       
  1495 void tst_QApplication::setActiveWindow()
       
  1496 {
       
  1497     int argc = 0;
       
  1498     QApplication MyApp(argc, 0, QApplication::GuiServer);
       
  1499 
       
  1500     QWidget* w = new QWidget;
       
  1501     QVBoxLayout* layout = new QVBoxLayout(w);
       
  1502 
       
  1503     QLineEdit* pb1 = new QLineEdit("Testbutton1", w);
       
  1504     QLineEdit* pb2 = new QLineEdit("Test Line Edit", w);
       
  1505 
       
  1506     layout->addWidget(pb1);
       
  1507     layout->addWidget(pb2);
       
  1508 
       
  1509     pb2->setFocus();
       
  1510     pb2->setParent(0);
       
  1511     delete pb2;
       
  1512 
       
  1513     w->show();
       
  1514     QApplication::setActiveWindow(w); // needs this on twm (focus follows mouse)
       
  1515     QVERIFY(pb1->hasFocus());
       
  1516     delete w;
       
  1517 }
       
  1518 
       
  1519 
       
  1520 /* This might fail on some X11 window managers? */
       
  1521 /*
       
  1522 void tst_QApplication::focusChanged()
       
  1523 {
       
  1524     int argc = 0;
       
  1525     QApplication app(argc, 0, QApplication::GuiServer);
       
  1526 
       
  1527     QSignalSpy spy(&app, SIGNAL(focusChanged(QWidget *, QWidget *)));
       
  1528     QWidget *now = 0;
       
  1529     QWidget *old = 0;
       
  1530 
       
  1531     QWidget parent1;
       
  1532     QHBoxLayout hbox1(&parent1);
       
  1533     QLabel lb1(&parent1);
       
  1534     QLineEdit le1(&parent1);
       
  1535     QPushButton pb1(&parent1);
       
  1536     hbox1.addWidget(&lb1);
       
  1537     hbox1.addWidget(&le1);
       
  1538     hbox1.addWidget(&pb1);
       
  1539 
       
  1540     QCOMPARE(spy.count(), 0);
       
  1541 
       
  1542     parent1.show();
       
  1543     QApplication::setActiveWindow(&parent1); // needs this on twm (focus follows mouse)
       
  1544     QCOMPARE(spy.count(), 1);
       
  1545     QCOMPARE(spy.at(0).count(), 2);
       
  1546     old = qVariantValue<QWidget*>(spy.at(0).at(0));
       
  1547     now = qVariantValue<QWidget*>(spy.at(0).at(1));
       
  1548     QVERIFY(now == &le1);
       
  1549     QVERIFY(now == QApplication::focusWidget());
       
  1550     QVERIFY(old == 0);
       
  1551     spy.clear();
       
  1552     QCOMPARE(spy.count(), 0);
       
  1553 
       
  1554     pb1.setFocus();
       
  1555     QCOMPARE(spy.count(), 1);
       
  1556     old = qVariantValue<QWidget*>(spy.at(0).at(0));
       
  1557     now = qVariantValue<QWidget*>(spy.at(0).at(1));
       
  1558     QVERIFY(now == &pb1);
       
  1559     QVERIFY(now == QApplication::focusWidget());
       
  1560     QVERIFY(old == &le1);
       
  1561     spy.clear();
       
  1562 
       
  1563     lb1.setFocus();
       
  1564     QCOMPARE(spy.count(), 1);
       
  1565     old = qVariantValue<QWidget*>(spy.at(0).at(0));
       
  1566     now = qVariantValue<QWidget*>(spy.at(0).at(1));
       
  1567     QVERIFY(now == &lb1);
       
  1568     QVERIFY(now == QApplication::focusWidget());
       
  1569     QVERIFY(old == &pb1);
       
  1570     spy.clear();
       
  1571 
       
  1572     lb1.clearFocus();
       
  1573     QCOMPARE(spy.count(), 1);
       
  1574     old = qVariantValue<QWidget*>(spy.at(0).at(0));
       
  1575     now = qVariantValue<QWidget*>(spy.at(0).at(1));
       
  1576     QVERIFY(now == 0);
       
  1577     QVERIFY(now == QApplication::focusWidget());
       
  1578     QVERIFY(old == &lb1);
       
  1579     spy.clear();
       
  1580 
       
  1581     QWidget parent2;
       
  1582     QHBoxLayout hbox2(&parent2);
       
  1583     QLabel lb2(&parent2);
       
  1584     QLineEdit le2(&parent2);
       
  1585     QPushButton pb2(&parent2);
       
  1586     hbox2.addWidget(&lb2);
       
  1587     hbox2.addWidget(&le2);
       
  1588     hbox2.addWidget(&pb2);
       
  1589 
       
  1590     parent2.show();
       
  1591     QApplication::setActiveWindow(&parent2); // needs this on twm (focus follows mouse)
       
  1592     QVERIFY(spy.count() > 0); // one for deactivation, one for activation on Windows
       
  1593     old = qVariantValue<QWidget*>(spy.at(spy.count()-1).at(0));
       
  1594     now = qVariantValue<QWidget*>(spy.at(spy.count()-1).at(1));
       
  1595     QVERIFY(now == &le2);
       
  1596     QVERIFY(now == QApplication::focusWidget());
       
  1597     QVERIFY(old == 0);
       
  1598     spy.clear();
       
  1599 
       
  1600     QTestKeyEvent tab(QTest::Press, Qt::Key_Tab, 0, 0);
       
  1601     QTestKeyEvent backtab(QTest::Press, Qt::Key_Backtab, 0, 0);
       
  1602     QTestMouseEvent click(QTest::MouseClick, Qt::LeftButton, 0, QPoint(5, 5), 0);
       
  1603 
       
  1604     bool tabAllControls = true;
       
  1605 #ifdef Q_WS_MAC
       
  1606     // Mac has two modes, one where you tab to everything, one where you can
       
  1607     // only tab to input controls, here's what we get. Determine which ones we
       
  1608     // should get.
       
  1609     QSettings appleSettings(QLatin1String("apple.com"));
       
  1610     QVariant appleValue = appleSettings.value(QLatin1String("AppleKeyboardUIMode"), 0);
       
  1611     tabAllControls = (appleValue.toInt() & 0x2);
       
  1612 #endif
       
  1613 
       
  1614     tab.simulate(now);
       
  1615     if (!tabAllControls) {
       
  1616         QVERIFY(spy.count() == 0);
       
  1617         QVERIFY(now == QApplication::focusWidget());
       
  1618     } else {
       
  1619         QVERIFY(spy.count() > 0);
       
  1620         old = qVariantValue<QWidget*>(spy.at(0).at(0));
       
  1621         now = qVariantValue<QWidget*>(spy.at(0).at(1));
       
  1622         QVERIFY(now == &pb2);
       
  1623         QVERIFY(now == QApplication::focusWidget());
       
  1624         QVERIFY(old == &le2);
       
  1625         spy.clear();
       
  1626     }
       
  1627 
       
  1628     if (!tabAllControls) {
       
  1629         QVERIFY(spy.count() == 0);
       
  1630         QVERIFY(now == QApplication::focusWidget());
       
  1631     } else {
       
  1632         tab.simulate(now);
       
  1633         QVERIFY(spy.count() > 0);
       
  1634         old = qVariantValue<QWidget*>(spy.at(0).at(0));
       
  1635         now = qVariantValue<QWidget*>(spy.at(0).at(1));
       
  1636         QVERIFY(now == &le2);
       
  1637         QVERIFY(now == QApplication::focusWidget());
       
  1638         QVERIFY(old == &pb2);
       
  1639         spy.clear();
       
  1640     }
       
  1641 
       
  1642     if (!tabAllControls) {
       
  1643         QVERIFY(spy.count() == 0);
       
  1644         QVERIFY(now == QApplication::focusWidget());
       
  1645     } else {
       
  1646         backtab.simulate(now);
       
  1647         QVERIFY(spy.count() > 0);
       
  1648         old = qVariantValue<QWidget*>(spy.at(0).at(0));
       
  1649         now = qVariantValue<QWidget*>(spy.at(0).at(1));
       
  1650         QVERIFY(now == &pb2);
       
  1651         QVERIFY(now == QApplication::focusWidget());
       
  1652         QVERIFY(old == &le2);
       
  1653         spy.clear();
       
  1654     }
       
  1655 
       
  1656 
       
  1657     if (!tabAllControls) {
       
  1658         QVERIFY(spy.count() == 0);
       
  1659         QVERIFY(now == QApplication::focusWidget());
       
  1660         old = &pb2;
       
  1661     } else {
       
  1662         backtab.simulate(now);
       
  1663         QVERIFY(spy.count() > 0);
       
  1664         old = qVariantValue<QWidget*>(spy.at(0).at(0));
       
  1665         now = qVariantValue<QWidget*>(spy.at(0).at(1));
       
  1666         QVERIFY(now == &le2);
       
  1667         QVERIFY(now == QApplication::focusWidget());
       
  1668         QVERIFY(old == &pb2);
       
  1669         spy.clear();
       
  1670     }
       
  1671 
       
  1672     click.simulate(old);
       
  1673     if (!(pb2.focusPolicy() & Qt::ClickFocus)) {
       
  1674         QVERIFY(spy.count() == 0);
       
  1675         QVERIFY(now == QApplication::focusWidget());
       
  1676     } else {
       
  1677         QVERIFY(spy.count() > 0);
       
  1678         old = qVariantValue<QWidget*>(spy.at(0).at(0));
       
  1679         now = qVariantValue<QWidget*>(spy.at(0).at(1));
       
  1680         QVERIFY(now == &pb2);
       
  1681         QVERIFY(now == QApplication::focusWidget());
       
  1682         QVERIFY(old == &le2);
       
  1683         spy.clear();
       
  1684 
       
  1685         click.simulate(old);
       
  1686         QVERIFY(spy.count() > 0);
       
  1687         old = qVariantValue<QWidget*>(spy.at(0).at(0));
       
  1688         now = qVariantValue<QWidget*>(spy.at(0).at(1));
       
  1689         QVERIFY(now == &le2);
       
  1690         QVERIFY(now == QApplication::focusWidget());
       
  1691         QVERIFY(old == &pb2);
       
  1692         spy.clear();
       
  1693     }
       
  1694 
       
  1695     parent1.activateWindow();
       
  1696     QApplication::setActiveWindow(&parent1); // needs this on twm (focus follows mouse)
       
  1697     QVERIFY(spy.count() == 1 || spy.count() == 2); // one for deactivation, one for activation on Windows
       
  1698 
       
  1699     //on windows, the change of focus is made in 2 steps
       
  1700     //(the focusChanged SIGNAL is emitted twice)
       
  1701     if (spy.count()==1)
       
  1702         old = qVariantValue<QWidget*>(spy.at(spy.count()-1).at(0));
       
  1703     else
       
  1704         old = qVariantValue<QWidget*>(spy.at(spy.count()-2).at(0));
       
  1705     now = qVariantValue<QWidget*>(spy.at(spy.count()-1).at(1));
       
  1706     QVERIFY(now == &le1);
       
  1707     QVERIFY(now == QApplication::focusWidget());
       
  1708     QVERIFY(old == &le2);
       
  1709     spy.clear();
       
  1710 }
       
  1711 
       
  1712 class LineEdit : public QLineEdit
       
  1713 {
       
  1714 public:
       
  1715     LineEdit(QWidget *parent = 0) : QLineEdit(parent) { }
       
  1716 
       
  1717 protected:
       
  1718     void focusOutEvent(QFocusEvent *e) {
       
  1719         QLineEdit::focusOutEvent(e);
       
  1720         if (objectName() == "le1")
       
  1721             setStyleSheet("");
       
  1722     }
       
  1723 
       
  1724     void focusInEvent(QFocusEvent *e) {
       
  1725         QLineEdit::focusInEvent(e);
       
  1726         if (objectName() == "le2")
       
  1727             setStyleSheet("");
       
  1728     }
       
  1729 };
       
  1730 
       
  1731 void tst_QApplication::focusOut()
       
  1732 {
       
  1733     int argc = 1;
       
  1734     QApplication app(argc, &argv0, QApplication::GuiServer);
       
  1735 
       
  1736     // Tests the case where the style pointer changes when on focus in/out
       
  1737     // (the above is the case when the stylesheet changes)
       
  1738     QWidget w;
       
  1739     QLineEdit *le1 = new LineEdit(&w);
       
  1740     le1->setObjectName("le1");
       
  1741     le1->setStyleSheet("background: #fee");
       
  1742     le1->setFocus();
       
  1743 
       
  1744     QLineEdit *le2 = new LineEdit(&w);
       
  1745     le2->setObjectName("le2");
       
  1746     le2->setStyleSheet("background: #fee");
       
  1747     le2->move(100, 100);
       
  1748     w.show();
       
  1749 
       
  1750     QTest::qWait(2000);
       
  1751     le2->setFocus();
       
  1752     QTest::qWait(2000);
       
  1753 }
       
  1754 
       
  1755 void tst_QApplication::execAfterExit()
       
  1756 {
       
  1757     int argc = 1;
       
  1758     QApplication app(argc, &argv0, QApplication::GuiServer);
       
  1759     QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection);
       
  1760     // this should be ignored, as exec() will reset the exitCode
       
  1761     QApplication::exit(1);
       
  1762     int exitCode = app.exec();
       
  1763     QCOMPARE(exitCode, 0);
       
  1764 
       
  1765     // the quitNow flag should have been reset, so we can spin an
       
  1766     // eventloop after QApplication::exec() returns
       
  1767     QEventLoop eventLoop;
       
  1768     QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
       
  1769     exitCode = eventLoop.exec();
       
  1770     QCOMPARE(exitCode, 0);
       
  1771 }
       
  1772 
       
  1773 void tst_QApplication::wheelScrollLines()
       
  1774 {
       
  1775     int argc = 1;
       
  1776     QApplication app(argc, &argv0, QApplication::GuiServer);
       
  1777     // If wheelScrollLines returns 0, the mose wheel will be disabled.
       
  1778     QVERIFY(app.wheelScrollLines() > 0);
       
  1779 }
       
  1780 
       
  1781 void tst_QApplication::style()
       
  1782 {
       
  1783     int argc = 1;
       
  1784 
       
  1785     {
       
  1786         QApplication app(argc, &argv0, QApplication::GuiServer);
       
  1787         QPointer<QStyle> style = app.style();
       
  1788         app.setStyle(new QWindowsStyle);
       
  1789         QVERIFY(style.isNull());
       
  1790     }
       
  1791 
       
  1792     QApplication app(argc, &argv0, QApplication::GuiServer);
       
  1793 
       
  1794     // qApp style can never be 0
       
  1795     QVERIFY(QApplication::style() != 0);
       
  1796 }
       
  1797 
       
  1798 void tst_QApplication::allWidgets()
       
  1799 {
       
  1800     int argc = 1;
       
  1801     QApplication app(argc, &argv0, QApplication::GuiServer);
       
  1802     QWidget *w = new QWidget;
       
  1803     QVERIFY(app.allWidgets().contains(w)); // uncreate widget test
       
  1804     QVERIFY(app.allWidgets().contains(w)); // created widget test
       
  1805     delete w;
       
  1806     w = 0;
       
  1807     QVERIFY(!app.allWidgets().contains(w)); // removal test
       
  1808 }
       
  1809 
       
  1810 void tst_QApplication::topLevelWidgets()
       
  1811 {
       
  1812     int argc = 1;
       
  1813     QApplication app(argc, &argv0, QApplication::GuiServer);
       
  1814     QWidget *w = new QWidget;
       
  1815     w->show();
       
  1816 #ifndef QT_NO_CLIPBOARD
       
  1817     QClipboard *clipboard = QApplication::clipboard();
       
  1818     QString originalText = clipboard->text();
       
  1819     clipboard->setText(QString("newText"));
       
  1820 #endif
       
  1821     app.processEvents();
       
  1822     QVERIFY(QApplication::topLevelWidgets().contains(w));
       
  1823     QCOMPARE(QApplication::topLevelWidgets().count(), 1);
       
  1824     delete w;
       
  1825     w = 0;
       
  1826     app.processEvents();
       
  1827     QCOMPARE(QApplication::topLevelWidgets().count(), 0);
       
  1828 }
       
  1829 
       
  1830 
       
  1831 
       
  1832 void tst_QApplication::setAttribute()
       
  1833 {
       
  1834     int argc = 1;
       
  1835     QApplication app(argc, &argv0, QApplication::GuiServer);
       
  1836     QVERIFY(!QApplication::testAttribute(Qt::AA_ImmediateWidgetCreation));
       
  1837     QWidget  *w = new QWidget;
       
  1838     QVERIFY(!w->testAttribute(Qt::WA_WState_Created));
       
  1839     delete w;
       
  1840 
       
  1841     QApplication::setAttribute(Qt::AA_ImmediateWidgetCreation);
       
  1842     QVERIFY(QApplication::testAttribute(Qt::AA_ImmediateWidgetCreation));
       
  1843     w = new QWidget;
       
  1844     QVERIFY(w->testAttribute(Qt::WA_WState_Created));
       
  1845     QWidget *w2 = new QWidget(w);
       
  1846     w2->setParent(0);
       
  1847     QVERIFY(w2->testAttribute(Qt::WA_WState_Created));
       
  1848     delete w;
       
  1849     delete w2;
       
  1850 
       
  1851     QApplication::setAttribute(Qt::AA_ImmediateWidgetCreation, false);
       
  1852     QVERIFY(!QApplication::testAttribute(Qt::AA_ImmediateWidgetCreation));
       
  1853     w = new QWidget;
       
  1854     QVERIFY(!w->testAttribute(Qt::WA_WState_Created));
       
  1855     delete w;
       
  1856 }
       
  1857 
       
  1858 void tst_QApplication::windowsCommandLine_data()
       
  1859 {
       
  1860 #if defined(Q_OS_WIN)
       
  1861     QTest::addColumn<QString>("args");
       
  1862     QTest::addColumn<QString>("expected");
       
  1863 
       
  1864     QTest::newRow("hello world")
       
  1865         << QString("Hello \"World\"")
       
  1866         << QString("Hello \"World\"");
       
  1867     QTest::newRow("sql")
       
  1868         << QString("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PNR' AND TABLE_TYPE = 'VIEW' ORDER BY TABLE_NAME")
       
  1869         << QString("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PNR' AND TABLE_TYPE = 'VIEW' ORDER BY TABLE_NAME");
       
  1870 #endif
       
  1871 }
       
  1872 
       
  1873 void tst_QApplication::windowsCommandLine()
       
  1874 {
       
  1875 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
  1876     QFETCH(QString, args);
       
  1877     QFETCH(QString, expected);
       
  1878 
       
  1879     QProcess testProcess;
       
  1880 #if defined(QT_DEBUG)
       
  1881     testProcess.start("wincmdline/debug/wincmdline", QStringList(args));
       
  1882 #else
       
  1883     testProcess.start("wincmdline/release/wincmdline", QStringList(args));
       
  1884 #endif
       
  1885     QVERIFY(testProcess.waitForFinished(10000));
       
  1886     QByteArray error = testProcess.readAllStandardError();
       
  1887     QString procError(error);
       
  1888     QCOMPARE(procError, expected);
       
  1889 #endif
       
  1890 }
       
  1891 
       
  1892 class TouchEventPropagationTestWidget : public QWidget
       
  1893 {
       
  1894     Q_OBJECT
       
  1895 
       
  1896 public:
       
  1897     bool seenTouchEvent, acceptTouchEvent, seenMouseEvent, acceptMouseEvent;
       
  1898 
       
  1899     TouchEventPropagationTestWidget(QWidget *parent = 0)
       
  1900         : QWidget(parent), seenTouchEvent(false), acceptTouchEvent(false), seenMouseEvent(false), acceptMouseEvent(false)
       
  1901     { }
       
  1902 
       
  1903     void reset()
       
  1904     {
       
  1905         seenTouchEvent = acceptTouchEvent = seenMouseEvent = acceptMouseEvent = false;
       
  1906     }
       
  1907 
       
  1908     bool event(QEvent *event)
       
  1909     {
       
  1910         switch (event->type()) {
       
  1911         case QEvent::MouseButtonPress:
       
  1912         case QEvent::MouseMove:
       
  1913         case QEvent::MouseButtonRelease:
       
  1914             // qDebug() << objectName() << "seenMouseEvent = true";
       
  1915             seenMouseEvent = true;
       
  1916             event->setAccepted(acceptMouseEvent);
       
  1917             break;
       
  1918         case QEvent::TouchBegin:
       
  1919         case QEvent::TouchUpdate:
       
  1920         case QEvent::TouchEnd:
       
  1921             // qDebug() << objectName() << "seenTouchEvent = true";
       
  1922             seenTouchEvent = true;
       
  1923             event->setAccepted(acceptTouchEvent);
       
  1924             break;
       
  1925         default:
       
  1926             return QWidget::event(event);
       
  1927         }
       
  1928         return true;
       
  1929     }
       
  1930 };
       
  1931 
       
  1932 void tst_QApplication::touchEventPropagation()
       
  1933 {
       
  1934     int argc = 1;
       
  1935     QApplication app(argc, &argv0, QApplication::GuiServer);
       
  1936 
       
  1937     QList<QTouchEvent::TouchPoint> pressedTouchPoints;
       
  1938     QTouchEvent::TouchPoint press(0);
       
  1939     press.setState(Qt::TouchPointPressed);
       
  1940     pressedTouchPoints << press;
       
  1941 
       
  1942     QList<QTouchEvent::TouchPoint> releasedTouchPoints;
       
  1943     QTouchEvent::TouchPoint release(0);
       
  1944     release.setState(Qt::TouchPointReleased);
       
  1945     releasedTouchPoints << release;
       
  1946 
       
  1947     {
       
  1948         // touch event behavior on a window
       
  1949         TouchEventPropagationTestWidget window;
       
  1950         window.setObjectName("1. window");
       
  1951 
       
  1952         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
       
  1953         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
       
  1954         QVERIFY(!window.seenTouchEvent);
       
  1955         QVERIFY(!window.seenMouseEvent);
       
  1956 
       
  1957         window.reset();
       
  1958         window.setAttribute(Qt::WA_AcceptTouchEvents);
       
  1959         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
       
  1960         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
       
  1961         QVERIFY(window.seenTouchEvent);
       
  1962         QVERIFY(!window.seenMouseEvent);
       
  1963 
       
  1964         window.reset();
       
  1965         window.acceptTouchEvent = true;
       
  1966         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
       
  1967         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
       
  1968         QVERIFY(window.seenTouchEvent);
       
  1969         QVERIFY(!window.seenMouseEvent);
       
  1970     }
       
  1971 
       
  1972     {
       
  1973         // touch event behavior on a window with a child widget
       
  1974         TouchEventPropagationTestWidget window;
       
  1975         window.setObjectName("2. window");
       
  1976         TouchEventPropagationTestWidget widget(&window);
       
  1977         widget.setObjectName("2. widget");
       
  1978 
       
  1979         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
       
  1980         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
       
  1981         QVERIFY(!widget.seenTouchEvent);
       
  1982         QVERIFY(!widget.seenMouseEvent);
       
  1983         QVERIFY(!window.seenTouchEvent);
       
  1984         QVERIFY(!window.seenMouseEvent);
       
  1985 
       
  1986         window.reset();
       
  1987         widget.reset();
       
  1988         widget.setAttribute(Qt::WA_AcceptTouchEvents);
       
  1989         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
       
  1990         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
       
  1991         QVERIFY(widget.seenTouchEvent);
       
  1992         QVERIFY(!widget.seenMouseEvent);
       
  1993         QVERIFY(!window.seenTouchEvent);
       
  1994         QVERIFY(!window.seenMouseEvent);
       
  1995 
       
  1996         window.reset();
       
  1997         widget.reset();
       
  1998         widget.acceptMouseEvent = true;
       
  1999         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
       
  2000         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
       
  2001         QVERIFY(widget.seenTouchEvent);
       
  2002         QVERIFY(!widget.seenMouseEvent);
       
  2003         QVERIFY(!window.seenTouchEvent);
       
  2004         QVERIFY(!window.seenMouseEvent);
       
  2005 
       
  2006         window.reset();
       
  2007         widget.reset();
       
  2008         widget.acceptTouchEvent = true;
       
  2009         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
       
  2010         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
       
  2011         QVERIFY(widget.seenTouchEvent);
       
  2012         QVERIFY(!widget.seenMouseEvent);
       
  2013         QVERIFY(!window.seenTouchEvent);
       
  2014         QVERIFY(!window.seenMouseEvent);
       
  2015 
       
  2016         window.reset();
       
  2017         widget.reset();
       
  2018         widget.setAttribute(Qt::WA_AcceptTouchEvents, false);
       
  2019         window.setAttribute(Qt::WA_AcceptTouchEvents);
       
  2020         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
       
  2021         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
       
  2022         QVERIFY(!widget.seenTouchEvent);
       
  2023         QVERIFY(!widget.seenMouseEvent);
       
  2024         QVERIFY(window.seenTouchEvent);
       
  2025         QVERIFY(!window.seenMouseEvent);
       
  2026 
       
  2027         window.reset();
       
  2028         widget.reset();
       
  2029         window.acceptTouchEvent = true;
       
  2030         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
       
  2031         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
       
  2032         QVERIFY(!widget.seenTouchEvent);
       
  2033         QVERIFY(!widget.seenMouseEvent);
       
  2034         QVERIFY(window.seenTouchEvent);
       
  2035         QVERIFY(!window.seenMouseEvent);
       
  2036 
       
  2037         window.reset();
       
  2038         widget.reset();
       
  2039         widget.acceptMouseEvent = true; // doesn't matter, touch events are propagated first
       
  2040         window.acceptTouchEvent = true;
       
  2041         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
       
  2042         qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
       
  2043         QVERIFY(!widget.seenTouchEvent);
       
  2044         QVERIFY(!widget.seenMouseEvent);
       
  2045         QVERIFY(window.seenTouchEvent);
       
  2046         QVERIFY(!window.seenMouseEvent);
       
  2047     }
       
  2048 }
       
  2049 
       
  2050 void tst_QApplication::symbianNoApplicationPanes()
       
  2051 {
       
  2052 #ifndef Q_OS_SYMBIAN
       
  2053     QSKIP("This is a Symbian only test", SkipAll);
       
  2054 #else
       
  2055     QApplication::setAttribute(Qt::AA_S60DontConstructApplicationPanes);
       
  2056 
       
  2057     // Run in a block so that QApplication is destroyed before resetting the attribute.
       
  2058     {
       
  2059         // Actually I wasn't able to get the forced orientation change to work properly,
       
  2060         // but I'll leave the code here for the future in case we manage to test that
       
  2061         // later. If someone knows how to force an orientation switch in an autotest, do
       
  2062         // feel free to fix this testcase.
       
  2063         int argc = 0;
       
  2064         QApplication app(argc, 0);
       
  2065         QWidget *w;
       
  2066 
       
  2067         w = new QWidget;
       
  2068         w->show();
       
  2069         QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
       
  2070                 ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape));
       
  2071         app.processEvents();
       
  2072         delete w;
       
  2073 
       
  2074         w = new QWidget;
       
  2075         w->show();
       
  2076         QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
       
  2077                 ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait));
       
  2078         app.processEvents();
       
  2079         delete w;
       
  2080 
       
  2081         w = new QWidget;
       
  2082         w->showMaximized();
       
  2083         QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
       
  2084                 ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape));
       
  2085         app.processEvents();
       
  2086         delete w;
       
  2087 
       
  2088         w = new QWidget;
       
  2089         w->showMaximized();
       
  2090         QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
       
  2091                 ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait));
       
  2092         app.processEvents();
       
  2093         delete w;
       
  2094 
       
  2095         w = new QWidget;
       
  2096         w->showFullScreen();
       
  2097         QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
       
  2098                 ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape));
       
  2099         app.processEvents();
       
  2100         delete w;
       
  2101 
       
  2102         w = new QWidget;
       
  2103         w->showFullScreen();
       
  2104         QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
       
  2105                 ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait));
       
  2106         app.processEvents();
       
  2107         delete w;
       
  2108 
       
  2109         // These will have no effect, since there is no status pane, but they shouldn't
       
  2110         // crash either.
       
  2111         w = new QWidget;
       
  2112         w->show();
       
  2113         w->setWindowTitle("Testing title");
       
  2114         app.processEvents();
       
  2115         delete w;
       
  2116 
       
  2117         w = new QWidget;
       
  2118         w->show();
       
  2119         w->setWindowIcon(QIcon(QPixmap("heart.svg")));
       
  2120         app.processEvents();
       
  2121         delete w;
       
  2122 
       
  2123         QDesktopWidget desktop;
       
  2124         QCOMPARE(desktop.availableGeometry(), desktop.screenGeometry());
       
  2125     }
       
  2126 
       
  2127     QApplication::setAttribute(Qt::AA_S60DontConstructApplicationPanes, false);
       
  2128 
       
  2129     // No other error condition. Program will crash if unsuccessful.
       
  2130 #endif
       
  2131 }
       
  2132 
       
  2133 #ifdef Q_OS_SYMBIAN
       
  2134 class CBaseDummy : public CBase
       
  2135 {
       
  2136 public:
       
  2137     CBaseDummy(int *numDestroyed) : numDestroyed(numDestroyed)
       
  2138     {
       
  2139     }
       
  2140     ~CBaseDummy()
       
  2141     {
       
  2142         (*numDestroyed)++;
       
  2143     }
       
  2144 
       
  2145 private:
       
  2146     int *numDestroyed;
       
  2147 };
       
  2148 
       
  2149 static void fakeMain(int *numDestroyed)
       
  2150 {
       
  2151     // Push a few objects, just so that the cleanup stack has something to clean up.
       
  2152     CleanupStack::PushL(new (ELeave) CBaseDummy(numDestroyed));
       
  2153     int argc = 0;
       
  2154     QApplication app(argc, 0);
       
  2155     CleanupStack::PushL(new (ELeave) CBaseDummy(numDestroyed));
       
  2156 
       
  2157     User::Leave(KErrGeneral); // Fake error
       
  2158 }
       
  2159 #endif
       
  2160 
       
  2161 void tst_QApplication::symbianNeedForTraps()
       
  2162 {
       
  2163 #ifndef Q_OS_SYMBIAN
       
  2164     QSKIP("This is a Symbian-only test", SkipAll);
       
  2165 #else
       
  2166     int argc = 0;
       
  2167     QApplication app(argc, 0);
       
  2168     int numDestroyed = 0;
       
  2169 
       
  2170     // This next part should not require a trap. If it does, the test will crash.
       
  2171     CleanupStack::PushL(new (ELeave) CBaseDummy(&numDestroyed));
       
  2172     CleanupStack::PopAndDestroy();
       
  2173 
       
  2174     QCOMPARE(numDestroyed, 1);
       
  2175 
       
  2176     // No other failure condition. The program will crash if it does not pass.
       
  2177 #endif
       
  2178 }
       
  2179 
       
  2180 void tst_QApplication::symbianLeaveThroughMain()
       
  2181 {
       
  2182 #ifndef Q_OS_SYMBIAN
       
  2183     QSKIP("This is a Symbian-only test", SkipAll);
       
  2184 #else
       
  2185     int numDestroyed = 0;
       
  2186     TInt err;
       
  2187     TRAP(err, fakeMain(&numDestroyed));
       
  2188 
       
  2189     QCOMPARE(numDestroyed, 2);
       
  2190 #endif
       
  2191 }
       
  2192 */
       
  2193 
       
  2194 //QTEST_APPLESS_MAIN(tst_QApplication)
       
  2195 int main(int argc, char *argv[])
       
  2196 {
       
  2197     tst_QApplication tc;
       
  2198     argv0 = argv[0];
       
  2199     return QTest::qExec(&tc, argc, argv);
       
  2200 }
       
  2201 
       
  2202 #include "smoketest_qapplication.moc"