Merge Symbian3
authorBrendan Donegan <brendand@symbian.org>
Fri, 11 Jun 2010 11:44:06 +0100
branchSymbian3
changeset 42 4f2786c97bf4
parent 41 72f7e4177ac7 (diff)
parent 40 2870b072e108 (current diff)
child 43 14fcccfb4c0c
Merge
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qt/gestures/smoketest_qgestures.pro	Fri Jun 11 11:44:06 2010 +0100
@@ -0,0 +1,5 @@
+load(qttest_p4)
+SOURCES  += tst_gestures.cpp
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qt/gestures/tst_gestures.cpp	Fri Jun 11 11:44:06 2010 +0100
@@ -0,0 +1,1660 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include "../shared/util.h"
+
+#include <qevent.h>
+#include <qwidget.h>
+#include <qlayout.h>
+#include <qgesture.h>
+#include <qgesturerecognizer.h>
+#include <qgraphicsitem.h>
+#include <qgraphicsview.h>
+
+#include <qdebug.h>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+static QPointF mapToGlobal(const QPointF &pt, QGraphicsItem *item, QGraphicsView *view)
+{
+    return view->mapToGlobal(view->mapFromScene(item->mapToScene(pt)));
+}
+
+class CustomGesture : public QGesture
+{
+    Q_OBJECT
+public:
+    static Qt::GestureType GestureType;
+
+    CustomGesture(QObject *parent = 0)
+        : QGesture(parent), serial(0)
+    {
+    }
+
+    int serial;
+
+    static const int SerialMaybeThreshold;
+    static const int SerialStartedThreshold;
+    static const int SerialFinishedThreshold;
+};
+Qt::GestureType CustomGesture::GestureType = Qt::CustomGesture;
+const int CustomGesture::SerialMaybeThreshold = 1;
+const int CustomGesture::SerialStartedThreshold = 3;
+const int CustomGesture::SerialFinishedThreshold = 6;
+
+class CustomEvent : public QEvent
+{
+public:
+    static int EventType;
+
+    CustomEvent(int serial_ = 0)
+        : QEvent(QEvent::Type(CustomEvent::EventType)),
+          serial(serial_), hasHotSpot(false)
+    {
+    }
+
+    int serial;
+    QPointF hotSpot;
+    bool hasHotSpot;
+};
+int CustomEvent::EventType = 0;
+
+class CustomGestureRecognizer : public QGestureRecognizer
+{
+public:
+    static bool ConsumeEvents;
+
+    CustomGestureRecognizer()
+    {
+        if (!CustomEvent::EventType)
+            CustomEvent::EventType = QEvent::registerEventType();
+    }
+
+    QGesture* create(QObject *)
+    {
+        return new CustomGesture;
+    }
+
+    QGestureRecognizer::Result recognize(QGesture *state, QObject*, QEvent *event)
+    {
+        if (event->type() == CustomEvent::EventType) {
+            QGestureRecognizer::Result result = 0;
+            if (CustomGestureRecognizer::ConsumeEvents)
+                result |= QGestureRecognizer::ConsumeEventHint;
+            CustomGesture *g = static_cast<CustomGesture*>(state);
+            CustomEvent *e = static_cast<CustomEvent*>(event);
+            g->serial = e->serial;
+            if (e->hasHotSpot)
+                g->setHotSpot(e->hotSpot);
+            if (g->serial >= CustomGesture::SerialFinishedThreshold)
+                result |= QGestureRecognizer::FinishGesture;
+            else if (g->serial >= CustomGesture::SerialStartedThreshold)
+                result |= QGestureRecognizer::TriggerGesture;
+            else if (g->serial >= CustomGesture::SerialMaybeThreshold)
+                result |= QGestureRecognizer::MayBeGesture;
+            else
+                result = QGestureRecognizer::CancelGesture;
+            return result;
+        }
+        return QGestureRecognizer::Ignore;
+    }
+
+    void reset(QGesture *state)
+    {
+        CustomGesture *g = static_cast<CustomGesture *>(state);
+        g->serial = 0;
+        QGestureRecognizer::reset(state);
+    }
+};
+bool CustomGestureRecognizer::ConsumeEvents = false;
+
+// same as CustomGestureRecognizer but triggers early without the maybe state
+class CustomContinuousGestureRecognizer : public QGestureRecognizer
+{
+public:
+    CustomContinuousGestureRecognizer()
+    {
+        if (!CustomEvent::EventType)
+            CustomEvent::EventType = QEvent::registerEventType();
+    }
+
+    QGesture* create(QObject *)
+    {
+        return new CustomGesture;
+    }
+
+    QGestureRecognizer::Result recognize(QGesture *state, QObject*, QEvent *event)
+    {
+        if (event->type() == CustomEvent::EventType) {
+            QGestureRecognizer::Result result = QGestureRecognizer::ConsumeEventHint;
+            CustomGesture *g = static_cast<CustomGesture *>(state);
+            CustomEvent *e = static_cast<CustomEvent *>(event);
+            g->serial = e->serial;
+            if (e->hasHotSpot)
+                g->setHotSpot(e->hotSpot);
+            if (g->serial >= CustomGesture::SerialFinishedThreshold)
+                result |= QGestureRecognizer::FinishGesture;
+            else if (g->serial >= CustomGesture::SerialMaybeThreshold)
+                result |= QGestureRecognizer::TriggerGesture;
+            else
+                result = QGestureRecognizer::CancelGesture;
+            return result;
+        }
+        return QGestureRecognizer::Ignore;
+    }
+
+    void reset(QGesture *state)
+    {
+        CustomGesture *g = static_cast<CustomGesture *>(state);
+        g->serial = 0;
+        QGestureRecognizer::reset(state);
+    }
+};
+
+class GestureWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    GestureWidget(const char *name = 0, QWidget *parent = 0)
+        : QWidget(parent)
+    {
+        if (name)
+            setObjectName(QLatin1String(name));
+        reset();
+        acceptGestureOverride = false;
+    }
+    void reset()
+    {
+        customEventsReceived = 0;
+        gestureEventsReceived = 0;
+        gestureOverrideEventsReceived = 0;
+        events.clear();
+        overrideEvents.clear();
+        ignoredGestures.clear();
+    }
+
+    int customEventsReceived;
+    int gestureEventsReceived;
+    int gestureOverrideEventsReceived;
+    struct Events
+    {
+        QList<Qt::GestureType> all;
+        QList<Qt::GestureType> started;
+        QList<Qt::GestureType> updated;
+        QList<Qt::GestureType> finished;
+        QList<Qt::GestureType> canceled;
+
+        void clear()
+        {
+            all.clear();
+            started.clear();
+            updated.clear();
+            finished.clear();
+            canceled.clear();
+        }
+    } events, overrideEvents;
+
+    bool acceptGestureOverride;
+    QSet<Qt::GestureType> ignoredGestures;
+
+protected:
+    bool event(QEvent *event)
+    {
+        Events *eventsPtr = 0;
+        if (event->type() == QEvent::Gesture) {
+            QGestureEvent *e = static_cast<QGestureEvent*>(event);
+            ++gestureEventsReceived;
+            eventsPtr = &events;
+            foreach(Qt::GestureType type, ignoredGestures)
+                e->ignore(e->gesture(type));
+        } else if (event->type() == QEvent::GestureOverride) {
+            ++gestureOverrideEventsReceived;
+            eventsPtr = &overrideEvents;
+            if (acceptGestureOverride)
+                event->accept();
+        }
+        if (eventsPtr) {
+            QGestureEvent *e = static_cast<QGestureEvent*>(event);
+            QList<QGesture*> gestures = e->gestures();
+            foreach(QGesture *g, gestures) {
+                eventsPtr->all << g->gestureType();
+                switch(g->state()) {
+                case Qt::GestureStarted:
+                    eventsPtr->started << g->gestureType();
+                    break;
+                case Qt::GestureUpdated:
+                    eventsPtr->updated << g->gestureType();
+                    break;
+                case Qt::GestureFinished:
+                    eventsPtr->finished << g->gestureType();
+                    break;
+                case Qt::GestureCanceled:
+                    eventsPtr->canceled << g->gestureType();
+                    break;
+                default:
+                    Q_ASSERT(false);
+                }
+            }
+        } else if (event->type() == CustomEvent::EventType) {
+            ++customEventsReceived;
+        } else {
+            return QWidget::event(event);
+        }
+        return true;
+    }
+};
+
+// TODO rename to sendGestureSequence
+static void sendCustomGesture(CustomEvent *event, QObject *object, QGraphicsScene *scene = 0)
+{
+    for (int i = CustomGesture::SerialMaybeThreshold;
+         i <= CustomGesture::SerialFinishedThreshold; ++i) {
+        event->serial = i;
+        if (scene)
+            scene->sendEvent(qobject_cast<QGraphicsObject *>(object), event);
+        else
+            QApplication::sendEvent(object, event);
+    }
+}
+
+class tst_Gestures : public QObject
+{
+Q_OBJECT
+
+public:
+    tst_Gestures();
+    virtual ~tst_Gestures();
+
+public slots:
+    void initTestCase();
+    void cleanupTestCase();
+    void init();
+    void cleanup();
+
+private slots:
+    void customGesture();
+	/*
+    void autoCancelingGestures();
+    void gestureOverChild();
+    void multipleWidgetOnlyGestureInTree();
+    void conflictingGestures();
+    void finishedWithoutStarted();
+    void unknownGesture();
+    void graphicsItemGesture();
+    void graphicsItemTreeGesture();
+    void explicitGraphicsObjectTarget();
+    void gestureOverChildGraphicsItem();
+    void twoGesturesOnDifferentLevel();
+    void multipleGesturesInTree();
+    void multipleGesturesInComplexTree();
+    void testMapToScene();
+    void ungrabGesture();
+    void consumeEventHint();
+    void unregisterRecognizer();
+    void autoCancelGestures();
+    void autoCancelGestures2();
+    void panelPropagation();
+    void panelStacksBehindParent();
+	*/
+};
+
+tst_Gestures::tst_Gestures()
+{
+}
+
+tst_Gestures::~tst_Gestures()
+{
+}
+
+void tst_Gestures::initTestCase()
+{
+    CustomGesture::GestureType = QGestureRecognizer::registerRecognizer(new CustomGestureRecognizer);
+    QVERIFY(CustomGesture::GestureType != Qt::GestureType(0));
+    QVERIFY(CustomGesture::GestureType != Qt::CustomGesture);
+}
+
+void tst_Gestures::cleanupTestCase()
+{
+    QGestureRecognizer::unregisterRecognizer(CustomGesture::GestureType);
+}
+
+void tst_Gestures::init()
+{
+}
+
+void tst_Gestures::cleanup()
+{
+}
+
+void tst_Gestures::customGesture()
+{
+    GestureWidget widget;
+    widget.grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+    CustomEvent event;
+    sendCustomGesture(&event, &widget);
+
+    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
+    static const int TotalCustomEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1;
+    QCOMPARE(widget.customEventsReceived, TotalCustomEventsCount);
+    QCOMPARE(widget.gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(widget.gestureOverrideEventsReceived, 0);
+    QCOMPARE(widget.events.all.size(), TotalGestureEventsCount);
+    for(int i = 0; i < widget.events.all.size(); ++i)
+        QCOMPARE(widget.events.all.at(i), CustomGesture::GestureType);
+    QCOMPARE(widget.events.started.size(), 1);
+    QCOMPARE(widget.events.updated.size(), TotalGestureEventsCount - 2);
+    QCOMPARE(widget.events.finished.size(), 1);
+    QCOMPARE(widget.events.canceled.size(), 0);
+}
+
+/*
+void tst_Gestures::consumeEventHint()
+{
+    GestureWidget widget;
+    widget.grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+
+    CustomGestureRecognizer::ConsumeEvents = true;
+    CustomEvent event;
+    sendCustomGesture(&event, &widget);
+    CustomGestureRecognizer::ConsumeEvents = false;
+
+    QCOMPARE(widget.customEventsReceived, 0);
+}
+*/
+
+/*
+
+void tst_Gestures::autoCancelingGestures()
+{
+    GestureWidget widget;
+    widget.grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+    // send partial gesture. The gesture will be in the "maybe" state, but will
+    // never get enough events to fire, so Qt will have to kill it.
+    CustomEvent ev;
+    for (int i = CustomGesture::SerialMaybeThreshold;
+         i < CustomGesture::SerialStartedThreshold; ++i) {
+        ev.serial = i;
+        QApplication::sendEvent(&widget, &ev);
+    }
+    // wait long enough so the gesture manager will cancel the gesture
+    QTest::qWait(5000);
+    QCOMPARE(widget.customEventsReceived, CustomGesture::SerialStartedThreshold - CustomGesture::SerialMaybeThreshold);
+    QCOMPARE(widget.gestureEventsReceived, 0);
+    QCOMPARE(widget.gestureOverrideEventsReceived, 0);
+    QCOMPARE(widget.events.all.size(), 0);
+}
+
+void tst_Gestures::gestureOverChild()
+{
+    GestureWidget widget("widget");
+    QVBoxLayout *l = new QVBoxLayout(&widget);
+    GestureWidget *child = new GestureWidget("child");
+    l->addWidget(child);
+
+    widget.grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+
+    CustomEvent event;
+    sendCustomGesture(&event, child);
+
+    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
+    static const int TotalCustomEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1;
+
+    QCOMPARE(child->customEventsReceived, TotalCustomEventsCount);
+    QCOMPARE(widget.customEventsReceived, 0);
+    QCOMPARE(child->gestureEventsReceived, 0);
+    QCOMPARE(child->gestureOverrideEventsReceived, 0);
+    QCOMPARE(widget.gestureEventsReceived, 0);
+    QCOMPARE(widget.gestureOverrideEventsReceived, 0);
+
+    // enable gestures over the children
+    widget.grabGesture(CustomGesture::GestureType);
+
+    widget.reset();
+    child->reset();
+
+    sendCustomGesture(&event, child);
+
+    QCOMPARE(child->customEventsReceived, TotalCustomEventsCount);
+    QCOMPARE(widget.customEventsReceived, 0);
+
+    QCOMPARE(child->gestureEventsReceived, 0);
+    QCOMPARE(child->gestureOverrideEventsReceived, 0);
+    QCOMPARE(widget.gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(widget.gestureOverrideEventsReceived, 0);
+    for(int i = 0; i < widget.events.all.size(); ++i)
+        QCOMPARE(widget.events.all.at(i), CustomGesture::GestureType);
+    QCOMPARE(widget.events.started.size(), 1);
+    QCOMPARE(widget.events.updated.size(), TotalGestureEventsCount - 2);
+    QCOMPARE(widget.events.finished.size(), 1);
+    QCOMPARE(widget.events.canceled.size(), 0);
+}
+
+void tst_Gestures::multipleWidgetOnlyGestureInTree()
+{
+    GestureWidget parent("parent");
+    QVBoxLayout *l = new QVBoxLayout(&parent);
+    GestureWidget *child = new GestureWidget("child");
+    l->addWidget(child);
+
+    parent.grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+    child->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+
+    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
+    static const int TotalCustomEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1;
+
+    // sending events to the child and making sure there is no conflict
+    CustomEvent event;
+    sendCustomGesture(&event, child);
+
+    QCOMPARE(child->customEventsReceived, TotalCustomEventsCount);
+    QCOMPARE(parent.customEventsReceived, 0);
+    QCOMPARE(child->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(child->gestureOverrideEventsReceived, 0);
+    QCOMPARE(parent.gestureEventsReceived, 0);
+    QCOMPARE(parent.gestureOverrideEventsReceived, 0);
+
+    parent.reset();
+    child->reset();
+
+    // same for the parent widget
+    sendCustomGesture(&event, &parent);
+
+    QCOMPARE(child->customEventsReceived, 0);
+    QCOMPARE(parent.customEventsReceived, TotalCustomEventsCount);
+    QCOMPARE(child->gestureEventsReceived, 0);
+    QCOMPARE(child->gestureOverrideEventsReceived, 0);
+    QCOMPARE(parent.gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(parent.gestureOverrideEventsReceived, 0);
+}
+
+void tst_Gestures::conflictingGestures()
+{
+    GestureWidget parent("parent");
+    QVBoxLayout *l = new QVBoxLayout(&parent);
+    GestureWidget *child = new GestureWidget("child");
+    l->addWidget(child);
+
+    parent.grabGesture(CustomGesture::GestureType);
+    child->grabGesture(CustomGesture::GestureType);
+
+    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
+
+    // child accepts the override, parent will not receive anything
+    parent.acceptGestureOverride = false;
+    child->acceptGestureOverride = true;
+
+    // sending events to the child and making sure there is no conflict
+    CustomEvent event;
+    sendCustomGesture(&event, child);
+
+    QCOMPARE(child->gestureOverrideEventsReceived, 1);
+    QCOMPARE(child->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(parent.gestureOverrideEventsReceived, 0);
+    QCOMPARE(parent.gestureEventsReceived, 0);
+
+    parent.reset();
+    child->reset();
+
+    // parent accepts the override
+    parent.acceptGestureOverride = true;
+    child->acceptGestureOverride = false;
+
+    // sending events to the child and making sure there is no conflict
+    sendCustomGesture(&event, child);
+
+    QCOMPARE(child->gestureOverrideEventsReceived, 1);
+    QCOMPARE(child->gestureEventsReceived, 0);
+    QCOMPARE(parent.gestureOverrideEventsReceived, 1);
+    QCOMPARE(parent.gestureEventsReceived, TotalGestureEventsCount);
+
+    parent.reset();
+    child->reset();
+
+    // nobody accepts the override, we will send normal events to the closest
+    // context (i.e. to the child widget) and it will be propagated and
+    // accepted by the parent widget
+    parent.acceptGestureOverride = false;
+    child->acceptGestureOverride = false;
+    child->ignoredGestures << CustomGesture::GestureType;
+
+    // sending events to the child and making sure there is no conflict
+    sendCustomGesture(&event, child);
+
+    QCOMPARE(child->gestureOverrideEventsReceived, 1);
+    QCOMPARE(child->gestureEventsReceived, 1);
+    QCOMPARE(parent.gestureOverrideEventsReceived, 1);
+    QCOMPARE(parent.gestureEventsReceived, TotalGestureEventsCount);
+
+    parent.reset();
+    child->reset();
+
+    // nobody accepts the override, and nobody accepts the gesture event
+    parent.acceptGestureOverride = false;
+    child->acceptGestureOverride = false;
+    parent.ignoredGestures << CustomGesture::GestureType;
+    child->ignoredGestures << CustomGesture::GestureType;
+
+    // sending events to the child and making sure there is no conflict
+    sendCustomGesture(&event, child);
+
+    QCOMPARE(child->gestureOverrideEventsReceived, 1);
+    QCOMPARE(child->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(parent.gestureOverrideEventsReceived, 1);
+    QCOMPARE(parent.gestureEventsReceived, 1);
+
+    parent.reset();
+    child->reset();
+
+    // we set an attribute to make sure all gesture events are propagated
+    parent.grabGesture(CustomGesture::GestureType, Qt::ReceivePartialGestures);
+    parent.acceptGestureOverride = false;
+    child->acceptGestureOverride = false;
+    parent.ignoredGestures << CustomGesture::GestureType;
+    child->ignoredGestures << CustomGesture::GestureType;
+
+    // sending events to the child and making sure there is no conflict
+    sendCustomGesture(&event, child);
+
+    QCOMPARE(child->gestureOverrideEventsReceived, 1);
+    QCOMPARE(child->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(parent.gestureOverrideEventsReceived, 1);
+    QCOMPARE(parent.gestureEventsReceived, TotalGestureEventsCount);
+
+    parent.reset();
+    child->reset();
+
+    Qt::GestureType ContinuousGesture = QGestureRecognizer::registerRecognizer(new CustomContinuousGestureRecognizer);
+    static const int ContinuousGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1;
+    child->grabGesture(ContinuousGesture);
+    // child accepts override. And it also receives another custom gesture.
+    parent.acceptGestureOverride = false;
+    child->acceptGestureOverride = true;
+    sendCustomGesture(&event, child);
+
+    QCOMPARE(child->gestureOverrideEventsReceived, 1);
+    QVERIFY(child->gestureEventsReceived > TotalGestureEventsCount);
+    QCOMPARE(child->events.all.count(), TotalGestureEventsCount + ContinuousGestureEventsCount);
+    QCOMPARE(parent.gestureOverrideEventsReceived, 0);
+    QCOMPARE(parent.gestureEventsReceived, 0);
+
+    QGestureRecognizer::unregisterRecognizer(ContinuousGesture);
+}
+
+void tst_Gestures::finishedWithoutStarted()
+{
+    GestureWidget widget;
+    widget.grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+
+    // the gesture will claim it finished, but it was never started.
+    CustomEvent ev;
+    ev.serial = CustomGesture::SerialFinishedThreshold;
+    QApplication::sendEvent(&widget, &ev);
+
+    QCOMPARE(widget.customEventsReceived, 1);
+    QCOMPARE(widget.gestureEventsReceived, 2);
+    QCOMPARE(widget.gestureOverrideEventsReceived, 0);
+    QCOMPARE(widget.events.all.size(), 2);
+    QCOMPARE(widget.events.started.size(), 1);
+    QCOMPARE(widget.events.updated.size(), 0);
+    QCOMPARE(widget.events.finished.size(), 1);
+    QCOMPARE(widget.events.canceled.size(), 0);
+}
+
+*/
+
+/*
+void tst_Gestures::unknownGesture()
+{
+    GestureWidget widget;
+    widget.grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+    widget.grabGesture(Qt::CustomGesture, Qt::DontStartGestureOnChildren);
+    widget.grabGesture(Qt::GestureType(Qt::PanGesture+512), Qt::DontStartGestureOnChildren);
+
+    CustomEvent event;
+    sendCustomGesture(&event, &widget);
+
+    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
+
+    QCOMPARE(widget.gestureEventsReceived, TotalGestureEventsCount);
+}
+*/
+
+static const QColor InstanceColors[] = {
+    Qt::blue, Qt::red, Qt::green, Qt::gray, Qt::yellow
+};
+
+class GestureItem : public QGraphicsObject
+{
+    static int InstanceCount;
+
+public:
+    GestureItem(const char *name = 0)
+    {
+        instanceNumber = InstanceCount++;
+        if (name)
+            setObjectName(QLatin1String(name));
+        size = QRectF(0, 0, 100, 100);
+        customEventsReceived = 0;
+        gestureEventsReceived = 0;
+        gestureOverrideEventsReceived = 0;
+        events.clear();
+        overrideEvents.clear();
+        acceptGestureOverride = false;
+    }
+    ~GestureItem()
+    {
+        --InstanceCount;
+    }
+
+    int customEventsReceived;
+    int gestureEventsReceived;
+    int gestureOverrideEventsReceived;
+    struct Events
+    {
+        QList<Qt::GestureType> all;
+        QList<Qt::GestureType> started;
+        QList<Qt::GestureType> updated;
+        QList<Qt::GestureType> finished;
+        QList<Qt::GestureType> canceled;
+
+        void clear()
+        {
+            all.clear();
+            started.clear();
+            updated.clear();
+            finished.clear();
+            canceled.clear();
+        }
+    } events, overrideEvents;
+
+    bool acceptGestureOverride;
+    QSet<Qt::GestureType> ignoredGestures;
+
+    QRectF size;
+    int instanceNumber;
+
+    void reset()
+    {
+        customEventsReceived = 0;
+        gestureEventsReceived = 0;
+        gestureOverrideEventsReceived = 0;
+        events.clear();
+        overrideEvents.clear();
+        ignoredGestures.clear();
+    }
+
+protected:
+    QRectF boundingRect() const
+    {
+        return size;
+    }
+    void paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
+    {
+        QColor color = InstanceColors[instanceNumber % (sizeof(InstanceColors)/sizeof(InstanceColors[0]))];
+        p->fillRect(boundingRect(), color);
+    }
+
+    bool event(QEvent *event)
+    {
+        Events *eventsPtr = 0;
+        if (event->type() == QEvent::Gesture) {
+            ++gestureEventsReceived;
+            eventsPtr = &events;
+            QGestureEvent *e = static_cast<QGestureEvent *>(event);
+            foreach(Qt::GestureType type, ignoredGestures)
+                e->ignore(e->gesture(type));
+        } else if (event->type() == QEvent::GestureOverride) {
+            ++gestureOverrideEventsReceived;
+            eventsPtr = &overrideEvents;
+            if (acceptGestureOverride)
+                event->accept();
+        }
+        if (eventsPtr) {
+            QGestureEvent *e = static_cast<QGestureEvent*>(event);
+            QList<QGesture*> gestures = e->gestures();
+            foreach(QGesture *g, gestures) {
+                eventsPtr->all << g->gestureType();
+                switch(g->state()) {
+                case Qt::GestureStarted:
+                    eventsPtr->started << g->gestureType();
+                    break;
+                case Qt::GestureUpdated:
+                    eventsPtr->updated << g->gestureType();
+                    break;
+                case Qt::GestureFinished:
+                    eventsPtr->finished << g->gestureType();
+                    break;
+                case Qt::GestureCanceled:
+                    eventsPtr->canceled << g->gestureType();
+                    break;
+                default:
+                    Q_ASSERT(false);
+                }
+            }
+        } else if (event->type() == CustomEvent::EventType) {
+            ++customEventsReceived;
+        } else {
+            return QGraphicsObject::event(event);
+        }
+        return true;
+    }
+};
+int GestureItem::InstanceCount = 0;
+
+/*
+void tst_Gestures::graphicsItemGesture()
+{
+    QGraphicsScene scene;
+    QGraphicsView view(&scene);
+    view.setWindowFlags(Qt::X11BypassWindowManagerHint);
+
+    GestureItem *item = new GestureItem("item");
+    scene.addItem(item);
+    item->setPos(100, 100);
+
+    view.show();
+    QTest::qWaitForWindowShown(&view);
+    view.ensureVisible(scene.sceneRect());
+
+    view.viewport()->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+    item->grabGesture(CustomGesture::GestureType);
+
+    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
+    static const int TotalCustomEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1;
+
+    CustomEvent event;
+    // gesture without hotspot should not be delivered to items in the view
+    QTest::ignoreMessage(QtWarningMsg, "QGestureManager::deliverEvent: could not find the target for gesture");
+    QTest::ignoreMessage(QtWarningMsg, "QGestureManager::deliverEvent: could not find the target for gesture");
+    QTest::ignoreMessage(QtWarningMsg, "QGestureManager::deliverEvent: could not find the target for gesture");
+    QTest::ignoreMessage(QtWarningMsg, "QGestureManager::deliverEvent: could not find the target for gesture");
+    sendCustomGesture(&event, item, &scene);
+
+    QCOMPARE(item->customEventsReceived, TotalCustomEventsCount);
+    QCOMPARE(item->gestureEventsReceived, 0);
+    QCOMPARE(item->gestureOverrideEventsReceived, 0);
+
+    item->reset();
+
+    // make sure the event is properly delivered if only the hotspot is set.
+    event.hotSpot = mapToGlobal(QPointF(10, 10), item, &view);
+    event.hasHotSpot = true;
+    sendCustomGesture(&event, item, &scene);
+
+    QCOMPARE(item->customEventsReceived, TotalCustomEventsCount);
+    QCOMPARE(item->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(item->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item->events.all.size(), TotalGestureEventsCount);
+    for(int i = 0; i < item->events.all.size(); ++i)
+        QCOMPARE(item->events.all.at(i), CustomGesture::GestureType);
+    QCOMPARE(item->events.started.size(), 1);
+    QCOMPARE(item->events.updated.size(), TotalGestureEventsCount - 2);
+    QCOMPARE(item->events.finished.size(), 1);
+    QCOMPARE(item->events.canceled.size(), 0);
+
+    item->reset();
+
+    // send gesture to the item which ignores it.
+    item->ignoredGestures << CustomGesture::GestureType;
+
+    event.hotSpot = mapToGlobal(QPointF(10, 10), item, &view);
+    event.hasHotSpot = true;
+    sendCustomGesture(&event, item, &scene);
+    QCOMPARE(item->customEventsReceived, TotalCustomEventsCount);
+    QCOMPARE(item->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(item->gestureOverrideEventsReceived, 0);
+}
+
+void tst_Gestures::graphicsItemTreeGesture()
+{
+    QGraphicsScene scene;
+    QGraphicsView view(&scene);
+    view.setWindowFlags(Qt::X11BypassWindowManagerHint);
+
+    GestureItem *item1 = new GestureItem("item1");
+    item1->setPos(100, 100);
+    item1->size = QRectF(0, 0, 350, 200);
+    scene.addItem(item1);
+
+    GestureItem *item1_child1 = new GestureItem("item1_child1");
+    item1_child1->setPos(50, 50);
+    item1_child1->size = QRectF(0, 0, 100, 100);
+    item1_child1->setParentItem(item1);
+
+    GestureItem *item1_child2 = new GestureItem("item1_child2");
+    item1_child2->size = QRectF(0, 0, 100, 100);
+    item1_child2->setPos(200, 50);
+    item1_child2->setParentItem(item1);
+
+    view.show();
+    QTest::qWaitForWindowShown(&view);
+    view.ensureVisible(scene.sceneRect());
+
+    view.viewport()->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+    item1->grabGesture(CustomGesture::GestureType);
+
+    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
+
+    CustomEvent event;
+    event.hotSpot = mapToGlobal(QPointF(10, 10), item1_child1, &view);
+    event.hasHotSpot = true;
+
+    item1->ignoredGestures << CustomGesture::GestureType;
+    sendCustomGesture(&event, item1_child1, &scene);
+    QCOMPARE(item1_child1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item1_child1->gestureEventsReceived, 0);
+    QCOMPARE(item1_child2->gestureEventsReceived, 0);
+    QCOMPARE(item1_child2->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item1->gestureEventsReceived, TotalGestureEventsCount);
+
+    item1->reset(); item1_child1->reset(); item1_child2->reset();
+
+    item1_child1->grabGesture(CustomGesture::GestureType);
+
+    item1->ignoredGestures << CustomGesture::GestureType;
+    item1_child1->ignoredGestures << CustomGesture::GestureType;
+    sendCustomGesture(&event, item1_child1, &scene);
+    QCOMPARE(item1_child1->gestureOverrideEventsReceived, 1);
+    QCOMPARE(item1_child1->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(item1_child2->gestureEventsReceived, 0);
+    QCOMPARE(item1_child2->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item1->gestureOverrideEventsReceived, 1);
+    QCOMPARE(item1->gestureEventsReceived, 1);
+}
+
+void tst_Gestures::explicitGraphicsObjectTarget()
+{
+    QGraphicsScene scene;
+    QGraphicsView view(&scene);
+    view.setWindowFlags(Qt::X11BypassWindowManagerHint);
+
+    GestureItem *item1 = new GestureItem("item1");
+    scene.addItem(item1);
+    item1->setPos(100, 100);
+    item1->setZValue(1);
+
+    GestureItem *item2 = new GestureItem("item2");
+    scene.addItem(item2);
+    item2->setPos(100, 100);
+    item2->setZValue(5);
+
+    GestureItem *item2_child1 = new GestureItem("item2_child1");
+    scene.addItem(item2_child1);
+    item2_child1->setParentItem(item2);
+    item2_child1->setPos(10, 10);
+
+    view.show();
+    QTest::qWaitForWindowShown(&view);
+    view.ensureVisible(scene.sceneRect());
+
+    view.viewport()->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+    item1->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+    item2->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+    item2_child1->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+
+    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
+
+    // sending events to item1, but the hotSpot is set to item2
+    CustomEvent event;
+    event.hotSpot = mapToGlobal(QPointF(15, 15), item2, &view);
+    event.hasHotSpot = true;
+
+    sendCustomGesture(&event, item1, &scene);
+
+    QCOMPARE(item1->gestureEventsReceived, 0);
+    QCOMPARE(item1->gestureOverrideEventsReceived, 1);
+    QCOMPARE(item2_child1->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(item2_child1->gestureOverrideEventsReceived, 1);
+    QCOMPARE(item2_child1->events.all.size(), TotalGestureEventsCount);
+    for(int i = 0; i < item2_child1->events.all.size(); ++i)
+        QCOMPARE(item2_child1->events.all.at(i), CustomGesture::GestureType);
+    QCOMPARE(item2_child1->events.started.size(), 1);
+    QCOMPARE(item2_child1->events.updated.size(), TotalGestureEventsCount - 2);
+    QCOMPARE(item2_child1->events.finished.size(), 1);
+    QCOMPARE(item2_child1->events.canceled.size(), 0);
+    QCOMPARE(item2->gestureEventsReceived, 0);
+    QCOMPARE(item2->gestureOverrideEventsReceived, 1);
+}
+
+void tst_Gestures::gestureOverChildGraphicsItem()
+{
+    QGraphicsScene scene;
+    QGraphicsView view(&scene);
+    view.setWindowFlags(Qt::X11BypassWindowManagerHint);
+
+    GestureItem *item0 = new GestureItem("item0");
+    scene.addItem(item0);
+    item0->setPos(0, 0);
+    item0->grabGesture(CustomGesture::GestureType);
+    item0->setZValue(1);
+
+    GestureItem *item1 = new GestureItem("item1");
+    scene.addItem(item1);
+    item1->setPos(100, 100);
+    item1->setZValue(5);
+
+    GestureItem *item2 = new GestureItem("item2");
+    scene.addItem(item2);
+    item2->setPos(100, 100);
+    item2->setZValue(10);
+
+    GestureItem *item2_child1 = new GestureItem("item2_child1");
+    scene.addItem(item2_child1);
+    item2_child1->setParentItem(item2);
+    item2_child1->setPos(0, 0);
+
+    view.show();
+    QTest::qWaitForWindowShown(&view);
+    view.ensureVisible(scene.sceneRect());
+
+    view.viewport()->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+    item1->grabGesture(CustomGesture::GestureType);
+
+    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
+    static const int TotalCustomEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1;
+
+    CustomEvent event;
+    event.hotSpot = mapToGlobal(QPointF(10, 10), item2_child1, &view);
+    event.hasHotSpot = true;
+    sendCustomGesture(&event, item0, &scene);
+
+    QCOMPARE(item0->customEventsReceived, TotalCustomEventsCount);
+    QCOMPARE(item2_child1->gestureEventsReceived, 0);
+    QCOMPARE(item2_child1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item2->gestureEventsReceived, 0);
+    QCOMPARE(item2->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item1->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(item1->gestureOverrideEventsReceived, 0);
+
+    item0->reset(); item1->reset(); item2->reset(); item2_child1->reset();
+    item2->grabGesture(CustomGesture::GestureType);
+    item2->ignoredGestures << CustomGesture::GestureType;
+
+    event.hotSpot = mapToGlobal(QPointF(10, 10), item2_child1, &view);
+    event.hasHotSpot = true;
+    sendCustomGesture(&event, item0, &scene);
+
+    QCOMPARE(item2_child1->gestureEventsReceived, 0);
+    QCOMPARE(item2_child1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item2->gestureEventsReceived, 1);
+    QCOMPARE(item2->gestureOverrideEventsReceived, 1);
+    QCOMPARE(item1->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(item1->gestureOverrideEventsReceived, 1);
+
+    item0->reset(); item1->reset(); item2->reset(); item2_child1->reset();
+    item2->grabGesture(CustomGesture::GestureType);
+    item2->ignoredGestures << CustomGesture::GestureType;
+    item1->ignoredGestures << CustomGesture::GestureType;
+
+    event.hotSpot = mapToGlobal(QPointF(10, 10), item2_child1, &view);
+    event.hasHotSpot = true;
+    sendCustomGesture(&event, item0, &scene);
+
+    QCOMPARE(item2_child1->gestureEventsReceived, 0);
+    QCOMPARE(item2_child1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item2->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(item2->gestureOverrideEventsReceived, 1);
+    QCOMPARE(item1->gestureEventsReceived, 1);
+    QCOMPARE(item1->gestureOverrideEventsReceived, 1);
+
+    item0->reset(); item1->reset(); item2->reset(); item2_child1->reset();
+    item2->grabGesture(CustomGesture::GestureType);
+    item2->ignoredGestures << CustomGesture::GestureType;
+    item1->ignoredGestures << CustomGesture::GestureType;
+    item1->grabGesture(CustomGesture::GestureType, Qt::ReceivePartialGestures);
+
+    event.hotSpot = mapToGlobal(QPointF(10, 10), item2_child1, &view);
+    event.hasHotSpot = true;
+    sendCustomGesture(&event, item0, &scene);
+
+    QCOMPARE(item2_child1->gestureEventsReceived, 0);
+    QCOMPARE(item2_child1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item2->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(item2->gestureOverrideEventsReceived, 1);
+    QCOMPARE(item1->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(item1->gestureOverrideEventsReceived, 1);
+}
+
+void tst_Gestures::twoGesturesOnDifferentLevel()
+{
+    GestureWidget parent("parent");
+    QVBoxLayout *l = new QVBoxLayout(&parent);
+    GestureWidget *child = new GestureWidget("child");
+    l->addWidget(child);
+
+    Qt::GestureType SecondGesture = QGestureRecognizer::registerRecognizer(new CustomGestureRecognizer);
+
+    parent.grabGesture(CustomGesture::GestureType);
+    child->grabGesture(SecondGesture);
+
+    CustomEvent event;
+    // sending events that form a gesture to one widget, but they will be
+    // filtered by two different gesture recognizers and will generate two
+    // QGesture objects. Check that those gesture objects are delivered to
+    // different widgets properly.
+    sendCustomGesture(&event, child);
+
+    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
+    static const int TotalCustomEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1;
+
+    QCOMPARE(child->customEventsReceived, TotalCustomEventsCount);
+    QCOMPARE(child->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(child->gestureOverrideEventsReceived, 0);
+    QCOMPARE(child->events.all.size(), TotalGestureEventsCount);
+    for(int i = 0; i < child->events.all.size(); ++i)
+        QCOMPARE(child->events.all.at(i), SecondGesture);
+
+    QCOMPARE(parent.gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(parent.gestureOverrideEventsReceived, 0);
+    QCOMPARE(parent.events.all.size(), TotalGestureEventsCount);
+    for(int i = 0; i < child->events.all.size(); ++i)
+        QCOMPARE(parent.events.all.at(i), CustomGesture::GestureType);
+
+    QGestureRecognizer::unregisterRecognizer(SecondGesture);
+}
+
+void tst_Gestures::multipleGesturesInTree()
+{
+    GestureWidget a("A");
+    GestureWidget *A = &a;
+    GestureWidget *B = new GestureWidget("B", A);
+    GestureWidget *C = new GestureWidget("C", B);
+    GestureWidget *D = new GestureWidget("D", C);
+
+    Qt::GestureType FirstGesture  = CustomGesture::GestureType;
+    Qt::GestureType SecondGesture = QGestureRecognizer::registerRecognizer(new CustomGestureRecognizer);
+    Qt::GestureType ThirdGesture  = QGestureRecognizer::registerRecognizer(new CustomGestureRecognizer);
+
+    Qt::GestureFlags flags = Qt::ReceivePartialGestures;
+    A->grabGesture(FirstGesture,  flags);   // A [1   3]
+    A->grabGesture(ThirdGesture,  flags);   // |
+    B->grabGesture(SecondGesture, flags);   // B [  2 3]
+    B->grabGesture(ThirdGesture,  flags);   // |
+    C->grabGesture(FirstGesture,  flags);   // C [1 2 3]
+    C->grabGesture(SecondGesture, flags);   // |
+    C->grabGesture(ThirdGesture,  flags);   // D [1   3]
+    D->grabGesture(FirstGesture,  flags);
+    D->grabGesture(ThirdGesture,  flags);
+
+    // make sure all widgets ignore events, so they get propagated.
+    A->ignoredGestures << FirstGesture << ThirdGesture;
+    B->ignoredGestures << SecondGesture << ThirdGesture;
+    C->ignoredGestures << FirstGesture << SecondGesture << ThirdGesture;
+    D->ignoredGestures << FirstGesture << ThirdGesture;
+
+    CustomEvent event;
+    sendCustomGesture(&event, D);
+
+    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
+
+    // gesture override events
+    QCOMPARE(D->overrideEvents.all.count(FirstGesture), 1);
+    QCOMPARE(D->overrideEvents.all.count(SecondGesture), 0);
+    QCOMPARE(D->overrideEvents.all.count(ThirdGesture), 1);
+
+    QCOMPARE(C->overrideEvents.all.count(FirstGesture), 1);
+    QCOMPARE(C->overrideEvents.all.count(SecondGesture), 1);
+    QCOMPARE(C->overrideEvents.all.count(ThirdGesture), 1);
+
+    QCOMPARE(B->overrideEvents.all.count(FirstGesture), 0);
+    QCOMPARE(B->overrideEvents.all.count(SecondGesture), 1);
+    QCOMPARE(B->overrideEvents.all.count(ThirdGesture), 1);
+
+    QCOMPARE(A->overrideEvents.all.count(FirstGesture), 1);
+    QCOMPARE(A->overrideEvents.all.count(SecondGesture), 0);
+    QCOMPARE(A->overrideEvents.all.count(ThirdGesture), 1);
+
+    // normal gesture events
+    QCOMPARE(D->events.all.count(FirstGesture), TotalGestureEventsCount);
+    QCOMPARE(D->events.all.count(SecondGesture), 0);
+    QCOMPARE(D->events.all.count(ThirdGesture), TotalGestureEventsCount);
+
+    QCOMPARE(C->events.all.count(FirstGesture), TotalGestureEventsCount);
+    QCOMPARE(C->events.all.count(SecondGesture), TotalGestureEventsCount);
+    QCOMPARE(C->events.all.count(ThirdGesture), TotalGestureEventsCount);
+
+    QCOMPARE(B->events.all.count(FirstGesture), 0);
+    QCOMPARE(B->events.all.count(SecondGesture), TotalGestureEventsCount);
+    QCOMPARE(B->events.all.count(ThirdGesture), TotalGestureEventsCount);
+
+    QCOMPARE(A->events.all.count(FirstGesture), TotalGestureEventsCount);
+    QCOMPARE(A->events.all.count(SecondGesture), 0);
+    QCOMPARE(A->events.all.count(ThirdGesture), TotalGestureEventsCount);
+
+    QGestureRecognizer::unregisterRecognizer(SecondGesture);
+    QGestureRecognizer::unregisterRecognizer(ThirdGesture);
+}
+
+void tst_Gestures::multipleGesturesInComplexTree()
+{
+    GestureWidget a("A");
+    GestureWidget *A = &a;
+    GestureWidget *B = new GestureWidget("B", A);
+    GestureWidget *C = new GestureWidget("C", B);
+    GestureWidget *D = new GestureWidget("D", C);
+
+    Qt::GestureType FirstGesture   = CustomGesture::GestureType;
+    Qt::GestureType SecondGesture  = QGestureRecognizer::registerRecognizer(new CustomGestureRecognizer);
+    Qt::GestureType ThirdGesture   = QGestureRecognizer::registerRecognizer(new CustomGestureRecognizer);
+    Qt::GestureType FourthGesture  = QGestureRecognizer::registerRecognizer(new CustomGestureRecognizer);
+    Qt::GestureType FifthGesture   = QGestureRecognizer::registerRecognizer(new CustomGestureRecognizer);
+    Qt::GestureType SixthGesture   = QGestureRecognizer::registerRecognizer(new CustomGestureRecognizer);
+    Qt::GestureType SeventhGesture = QGestureRecognizer::registerRecognizer(new CustomGestureRecognizer);
+
+    Qt::GestureFlags flags = Qt::ReceivePartialGestures;
+    A->grabGesture(FirstGesture,   flags); // A [1,3,4]
+    A->grabGesture(ThirdGesture,   flags); // |
+    A->grabGesture(FourthGesture,  flags); // B [2,3,5]
+    B->grabGesture(SecondGesture,  flags); // |
+    B->grabGesture(ThirdGesture,   flags); // C [1,2,3,6]
+    B->grabGesture(FifthGesture,   flags); // |
+    C->grabGesture(FirstGesture,   flags); // D [1,3,7]
+    C->grabGesture(SecondGesture,  flags);
+    C->grabGesture(ThirdGesture,   flags);
+    C->grabGesture(SixthGesture,   flags);
+    D->grabGesture(FirstGesture,   flags);
+    D->grabGesture(ThirdGesture,   flags);
+    D->grabGesture(SeventhGesture, flags);
+
+    // make sure all widgets ignore events, so they get propagated.
+    QSet<Qt::GestureType> allGestureTypes;
+    allGestureTypes << FirstGesture << SecondGesture << ThirdGesture
+            << FourthGesture << FifthGesture << SixthGesture << SeventhGesture;
+    A->ignoredGestures = B->ignoredGestures = allGestureTypes;
+    C->ignoredGestures = D->ignoredGestures = allGestureTypes;
+
+    CustomEvent event;
+    sendCustomGesture(&event, D);
+
+    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
+
+    // gesture override events
+    QCOMPARE(D->overrideEvents.all.count(FirstGesture), 1);
+    QCOMPARE(D->overrideEvents.all.count(SecondGesture), 0);
+    QCOMPARE(D->overrideEvents.all.count(ThirdGesture), 1);
+
+    QCOMPARE(C->overrideEvents.all.count(FirstGesture), 1);
+    QCOMPARE(C->overrideEvents.all.count(SecondGesture), 1);
+    QCOMPARE(C->overrideEvents.all.count(ThirdGesture), 1);
+
+    QCOMPARE(B->overrideEvents.all.count(FirstGesture), 0);
+    QCOMPARE(B->overrideEvents.all.count(SecondGesture), 1);
+    QCOMPARE(B->overrideEvents.all.count(ThirdGesture), 1);
+
+    QCOMPARE(A->overrideEvents.all.count(FirstGesture), 1);
+    QCOMPARE(A->overrideEvents.all.count(SecondGesture), 0);
+    QCOMPARE(A->overrideEvents.all.count(ThirdGesture), 1);
+
+    // normal gesture events
+    QCOMPARE(D->events.all.count(FirstGesture), TotalGestureEventsCount);
+    QCOMPARE(D->events.all.count(SecondGesture), 0);
+    QCOMPARE(D->events.all.count(ThirdGesture), TotalGestureEventsCount);
+    QCOMPARE(D->events.all.count(FourthGesture), 0);
+    QCOMPARE(D->events.all.count(FifthGesture), 0);
+    QCOMPARE(D->events.all.count(SixthGesture), 0);
+    QCOMPARE(D->events.all.count(SeventhGesture), TotalGestureEventsCount);
+
+    QCOMPARE(C->events.all.count(FirstGesture), TotalGestureEventsCount);
+    QCOMPARE(C->events.all.count(SecondGesture), TotalGestureEventsCount);
+    QCOMPARE(C->events.all.count(ThirdGesture), TotalGestureEventsCount);
+    QCOMPARE(C->events.all.count(FourthGesture), 0);
+    QCOMPARE(C->events.all.count(FifthGesture), 0);
+    QCOMPARE(C->events.all.count(SixthGesture), TotalGestureEventsCount);
+    QCOMPARE(C->events.all.count(SeventhGesture), 0);
+
+    QCOMPARE(B->events.all.count(FirstGesture), 0);
+    QCOMPARE(B->events.all.count(SecondGesture), TotalGestureEventsCount);
+    QCOMPARE(B->events.all.count(ThirdGesture), TotalGestureEventsCount);
+    QCOMPARE(B->events.all.count(FourthGesture), 0);
+    QCOMPARE(B->events.all.count(FifthGesture), TotalGestureEventsCount);
+    QCOMPARE(B->events.all.count(SixthGesture), 0);
+    QCOMPARE(B->events.all.count(SeventhGesture), 0);
+
+    QCOMPARE(A->events.all.count(FirstGesture), TotalGestureEventsCount);
+    QCOMPARE(A->events.all.count(SecondGesture), 0);
+    QCOMPARE(A->events.all.count(ThirdGesture), TotalGestureEventsCount);
+    QCOMPARE(A->events.all.count(FourthGesture), TotalGestureEventsCount);
+    QCOMPARE(A->events.all.count(FifthGesture), 0);
+    QCOMPARE(A->events.all.count(SixthGesture), 0);
+    QCOMPARE(A->events.all.count(SeventhGesture), 0);
+
+    QGestureRecognizer::unregisterRecognizer(SecondGesture);
+    QGestureRecognizer::unregisterRecognizer(ThirdGesture);
+    QGestureRecognizer::unregisterRecognizer(FourthGesture);
+    QGestureRecognizer::unregisterRecognizer(FifthGesture);
+    QGestureRecognizer::unregisterRecognizer(SixthGesture);
+    QGestureRecognizer::unregisterRecognizer(SeventhGesture);
+}
+
+void tst_Gestures::testMapToScene()
+{
+    QGesture gesture;
+    QList<QGesture*> list;
+    list << &gesture;
+    QGestureEvent event(list);
+    QCOMPARE(event.mapToGraphicsScene(gesture.hotSpot()), QPointF()); // not set, can't do much
+
+    QGraphicsScene scene;
+    QGraphicsView view(&scene);
+    view.setWindowFlags(Qt::X11BypassWindowManagerHint);
+
+    GestureItem *item0 = new GestureItem;
+    scene.addItem(item0);
+    item0->setPos(14, 16);
+
+    view.show(); // need to show to give it a global coordinate
+    QTest::qWaitForWindowShown(&view);
+    view.ensureVisible(scene.sceneRect());
+
+    QPoint origin = view.mapToGlobal(QPoint());
+    event.setWidget(view.viewport());
+
+    QCOMPARE(event.mapToGraphicsScene(origin + QPoint(100, 200)), view.mapToScene(QPoint(100, 200)));
+}
+*/
+
+/*
+void tst_Gestures::ungrabGesture() // a method on QWidget
+{
+    class MockGestureWidget : public GestureWidget {
+    public:
+        MockGestureWidget(const char *name = 0, QWidget *parent = 0)
+            : GestureWidget(name, parent) { }
+
+
+        QSet<QGesture*> gestures;
+    protected:
+        bool event(QEvent *event)
+        {
+            if (event->type() == QEvent::Gesture) {
+                QGestureEvent *gestureEvent = static_cast<QGestureEvent*>(event);
+                if (gestureEvent)
+                    foreach (QGesture *g, gestureEvent->gestures())
+                        gestures.insert(g);
+            }
+            return GestureWidget::event(event);
+        }
+    };
+
+    MockGestureWidget parent("A");
+    MockGestureWidget *a = &parent;
+    MockGestureWidget *b = new MockGestureWidget("B", a);
+
+    a->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+    b->grabGesture(CustomGesture::GestureType);
+    b->ignoredGestures << CustomGesture::GestureType;
+
+    CustomEvent event;
+    // sending an event will cause the QGesture objects to be instantiated for the widgets
+    sendCustomGesture(&event, b);
+
+    QCOMPARE(a->gestures.count(), 1);
+    QPointer<QGesture> customGestureA;
+    customGestureA = *(a->gestures.begin());
+    QVERIFY(!customGestureA.isNull());
+    QCOMPARE(customGestureA->gestureType(), CustomGesture::GestureType);
+
+    QCOMPARE(b->gestures.count(), 1);
+    QPointer<QGesture> customGestureB;
+    customGestureB = *(b->gestures.begin());
+    QVERIFY(!customGestureB.isNull());
+    QVERIFY(customGestureA.data() == customGestureB.data());
+    QCOMPARE(customGestureB->gestureType(), CustomGesture::GestureType);
+
+    a->gestures.clear();
+    // sending an event will cause the QGesture objects to be instantiated for the widget
+    sendCustomGesture(&event, a);
+
+    QCOMPARE(a->gestures.count(), 1);
+    customGestureA = *(a->gestures.begin());
+    QVERIFY(!customGestureA.isNull());
+    QCOMPARE(customGestureA->gestureType(), CustomGesture::GestureType);
+    QVERIFY(customGestureA.data() != customGestureB.data());
+
+    a->ungrabGesture(CustomGesture::GestureType);
+    QVERIFY(customGestureA.isNull());
+    QVERIFY(!customGestureB.isNull());
+
+    a->gestures.clear();
+    a->reset();
+    // send again to 'b' and make sure a never gets it.
+    sendCustomGesture(&event, b);
+    QCOMPARE(a->gestureEventsReceived, 0);
+    QCOMPARE(a->gestureOverrideEventsReceived, 0);
+}
+*/
+
+/*
+void tst_Gestures::unregisterRecognizer() // a method on QApplication
+{
+     The hardest usecase to get right is when we remove a recognizer while several
+     of the gestures it created are in active state and we immediately add a new recognizer
+     for the same type (thus replacing the old one).
+     The expected result is that all old gestures continue till they are finished/cancelled
+     and the new recognizer starts creating gestures immediately at registration.
+
+     This implies that deleting of the recognizer happens only when there are no more gestures
+     that it created. (since gestures might have a pointer to the recognizer)
+}
+*/
+
+/*
+void tst_Gestures::autoCancelGestures()
+{
+    class MockWidget : public GestureWidget {
+      public:
+        MockWidget(const char *name) : GestureWidget(name) { }
+
+        bool event(QEvent *event)
+        {
+            if (event->type() == QEvent::Gesture) {
+                QGestureEvent *ge = static_cast<QGestureEvent*>(event);
+                Q_ASSERT(ge->gestures().count() == 1); // can't use QCOMPARE here...
+                ge->gestures().first()->setGestureCancelPolicy(QGesture::CancelAllInContext);
+            }
+            return GestureWidget::event(event);
+        }
+    };
+
+    const Qt::GestureType secondGesture = QGestureRecognizer::registerRecognizer(new CustomGestureRecognizer);
+
+    MockWidget parent("parent"); // this one sets the cancel policy to CancelAllInContext
+    parent.resize(300, 100);
+    parent.setWindowFlags(Qt::X11BypassWindowManagerHint);
+    GestureWidget *child = new GestureWidget("child", &parent);
+    child->setGeometry(10, 10, 100, 80);
+
+    parent.grabGesture(CustomGesture::GestureType);
+    child->grabGesture(secondGesture);
+    parent.show();
+    QTest::qWaitForWindowShown(&parent);
+
+      An event is send to both the child and the parent, when the child gets it a gesture is triggered
+      and send to the child.
+      When the parent gets the event a new gesture is triggered and delivered to the parent. When the
+      parent gets it he accepts it and that causes the cancel policy to activate.
+      The cause of that is the gesture for the child is cancelled and send to the child as such.
+
+    CustomEvent event;
+    event.serial = CustomGesture::SerialStartedThreshold;
+    QApplication::sendEvent(child, &event);
+    QCOMPARE(child->events.all.count(), 2);
+    QCOMPARE(child->events.started.count(), 1);
+    QCOMPARE(child->events.canceled.count(), 1);
+    QCOMPARE(parent.events.all.count(), 1);
+
+    // clean up, make the parent gesture finish
+    event.serial = CustomGesture::SerialFinishedThreshold;
+    QApplication::sendEvent(child, &event);
+    QCOMPARE(parent.events.all.count(), 2);
+}
+
+void tst_Gestures::autoCancelGestures2()
+{
+    class MockItem : public GestureItem {
+      public:
+        MockItem(const char *name) : GestureItem(name) { }
+
+        bool event(QEvent *event) {
+            if (event->type() == QEvent::Gesture) {
+                QGestureEvent *ge = static_cast<QGestureEvent*>(event);
+                Q_ASSERT(ge->gestures().count() == 1); // can't use QCOMPARE here...
+                ge->gestures().first()->setGestureCancelPolicy(QGesture::CancelAllInContext);
+            }
+            return GestureItem::event(event);
+        }
+    };
+
+    const Qt::GestureType secondGesture = QGestureRecognizer ::registerRecognizer(new CustomGestureRecognizer);
+
+    QGraphicsScene scene;
+    QGraphicsView view(&scene);
+    view.setWindowFlags(Qt::X11BypassWindowManagerHint);
+
+    MockItem *parent = new MockItem("parent");
+    GestureItem *child = new GestureItem("child");
+    child->setParentItem(parent);
+    parent->setPos(0, 0);
+    child->setPos(10, 10);
+    scene.addItem(parent);
+    view.viewport()->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+    view.viewport()->grabGesture(secondGesture, Qt::DontStartGestureOnChildren);
+    parent->grabGesture(CustomGesture::GestureType);
+    child->grabGesture(secondGesture);
+
+    view.show();
+    QTest::qWaitForWindowShown(&view);
+    view.ensureVisible(scene.sceneRect());
+
+    CustomEvent event;
+    event.serial = CustomGesture::SerialStartedThreshold;
+    event.hasHotSpot = true;
+    event.hotSpot = mapToGlobal(QPointF(5, 5), child, &view);
+    scene.sendEvent(child, &event);
+    QCOMPARE(parent->events.all.count(), 1);
+    QCOMPARE(child->events.started.count(), 1);
+    QCOMPARE(child->events.canceled.count(), 1);
+    QCOMPARE(child->events.all.count(), 2);
+
+    // clean up, make the parent gesture finish
+    event.serial = CustomGesture::SerialFinishedThreshold;
+    scene.sendEvent(child, &event);
+    QCOMPARE(parent->events.all.count(), 2);
+}
+*/
+
+/*
+void tst_Gestures::panelPropagation()
+{
+    QGraphicsScene scene;
+    QGraphicsView view(&scene);
+    view.setWindowFlags(Qt::X11BypassWindowManagerHint);
+
+    GestureItem *item0 = new GestureItem("item0");
+    scene.addItem(item0);
+    item0->setPos(0, 0);
+    item0->size = QRectF(0, 0, 200, 200);
+    item0->grabGesture(CustomGesture::GestureType);
+    item0->setZValue(1);
+
+    GestureItem *item1 = new GestureItem("item1");
+    item1->grabGesture(CustomGesture::GestureType);
+    scene.addItem(item1);
+    item1->setPos(10, 10);
+    item1->size = QRectF(0, 0, 180, 180);
+    item1->setZValue(2);
+
+    GestureItem *item1_child1 = new GestureItem("item1_child1[panel]");
+    item1_child1->setFlags(QGraphicsItem::ItemIsPanel);
+    item1_child1->setParentItem(item1);
+    item1_child1->grabGesture(CustomGesture::GestureType);
+    item1_child1->setPos(10, 10);
+    item1_child1->size = QRectF(0, 0, 160, 160);
+    item1_child1->setZValue(5);
+
+    GestureItem *item1_child1_child1 = new GestureItem("item1_child1_child1");
+    item1_child1_child1->setParentItem(item1_child1);
+    item1_child1_child1->grabGesture(CustomGesture::GestureType);
+    item1_child1_child1->setPos(10, 10);
+    item1_child1_child1->size = QRectF(0, 0, 140, 140);
+    item1_child1_child1->setZValue(10);
+
+    view.show();
+    QTest::qWaitForWindowShown(&view);
+    view.ensureVisible(scene.sceneRect());
+
+    view.viewport()->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+
+    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
+    static const int TotalCustomEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1;
+
+    CustomEvent event;
+    event.hotSpot = mapToGlobal(QPointF(5, 5), item1_child1_child1, &view);
+    event.hasHotSpot = true;
+    sendCustomGesture(&event, item0, &scene);
+
+    QCOMPARE(item0->customEventsReceived, TotalCustomEventsCount);
+    QCOMPARE(item1_child1_child1->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(item1_child1_child1->gestureOverrideEventsReceived, 1);
+    QCOMPARE(item1_child1->gestureOverrideEventsReceived, 1);
+    QCOMPARE(item1->gestureEventsReceived, 0);
+    QCOMPARE(item1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item0->gestureEventsReceived, 0);
+    QCOMPARE(item0->gestureOverrideEventsReceived, 0);
+
+    item0->reset(); item1->reset(); item1_child1->reset(); item1_child1_child1->reset();
+
+    event.hotSpot = mapToGlobal(QPointF(5, 5), item1, &view);
+    event.hasHotSpot = true;
+    sendCustomGesture(&event, item1, &scene);
+
+    QCOMPARE(item1_child1_child1->gestureEventsReceived, 0);
+    QCOMPARE(item1_child1_child1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item1_child1->gestureEventsReceived, 0);
+    QCOMPARE(item1_child1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item1->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(item1->gestureOverrideEventsReceived, 1);
+    QCOMPARE(item0->gestureEventsReceived, 0);
+    QCOMPARE(item0->gestureOverrideEventsReceived, 1);
+
+    item0->reset(); item1->reset(); item1_child1->reset(); item1_child1_child1->reset();
+    // try with a modal panel
+    item1_child1->setPanelModality(QGraphicsItem::PanelModal);
+
+    event.hotSpot = mapToGlobal(QPointF(5, 5), item1, &view);
+    event.hasHotSpot = true;
+    sendCustomGesture(&event, item1, &scene);
+
+    QCOMPARE(item1_child1_child1->gestureEventsReceived, 0);
+    QCOMPARE(item1_child1_child1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item1_child1->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(item1_child1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item1->gestureEventsReceived, 0);
+    QCOMPARE(item1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item0->gestureEventsReceived, 0);
+    QCOMPARE(item0->gestureOverrideEventsReceived, 0);
+
+    item0->reset(); item1->reset(); item1_child1->reset(); item1_child1_child1->reset();
+    // try with a modal panel, however set the hotspot to be outside of the
+    // panel and its parent
+    item1_child1->setPanelModality(QGraphicsItem::PanelModal);
+
+    event.hotSpot = mapToGlobal(QPointF(5, 5), item0, &view);
+    event.hasHotSpot = true;
+    sendCustomGesture(&event, item1, &scene);
+
+    QCOMPARE(item1_child1_child1->gestureEventsReceived, 0);
+    QCOMPARE(item1_child1_child1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item1_child1->gestureEventsReceived, 0);
+    QCOMPARE(item1_child1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item1->gestureEventsReceived, 0);
+    QCOMPARE(item1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item0->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(item0->gestureOverrideEventsReceived, 0);
+
+    item0->reset(); item1->reset(); item1_child1->reset(); item1_child1_child1->reset();
+    // try with a scene modal panel
+    item1_child1->setPanelModality(QGraphicsItem::SceneModal);
+
+    event.hotSpot = mapToGlobal(QPointF(5, 5), item0, &view);
+    event.hasHotSpot = true;
+    sendCustomGesture(&event, item0, &scene);
+
+    QCOMPARE(item1_child1_child1->gestureEventsReceived, 0);
+    QCOMPARE(item1_child1_child1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item1_child1->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(item1_child1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item1->gestureEventsReceived, 0);
+    QCOMPARE(item1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(item0->gestureEventsReceived, 0);
+    QCOMPARE(item0->gestureOverrideEventsReceived, 0);
+}
+*/
+
+/*
+void tst_Gestures::panelStacksBehindParent()
+{
+    QGraphicsScene scene;
+    QGraphicsView view(&scene);
+    view.setWindowFlags(Qt::X11BypassWindowManagerHint);
+
+    GestureItem *item1 = new GestureItem("item1");
+    item1->grabGesture(CustomGesture::GestureType);
+    scene.addItem(item1);
+    item1->setPos(10, 10);
+    item1->size = QRectF(0, 0, 180, 180);
+    item1->setZValue(2);
+
+    GestureItem *panel = new GestureItem("panel");
+    panel->setFlags(QGraphicsItem::ItemIsPanel | QGraphicsItem::ItemStacksBehindParent);
+    panel->setPanelModality(QGraphicsItem::PanelModal);
+    panel->setParentItem(item1);
+    panel->grabGesture(CustomGesture::GestureType);
+    panel->setPos(-10, -10);
+    panel->size = QRectF(0, 0, 200, 200);
+    panel->setZValue(5);
+
+    view.show();
+    QTest::qWaitForWindowShown(&view);
+    view.ensureVisible(scene.sceneRect());
+
+    view.viewport()->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+
+    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
+
+    CustomEvent event;
+    event.hotSpot = mapToGlobal(QPointF(5, 5), item1, &view);
+    event.hasHotSpot = true;
+    sendCustomGesture(&event, item1, &scene);
+
+    QCOMPARE(item1->gestureEventsReceived, 0);
+    QCOMPARE(item1->gestureOverrideEventsReceived, 0);
+    QCOMPARE(panel->gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(panel->gestureOverrideEventsReceived, 0);
+}
+*/
+
+QTEST_MAIN(tst_Gestures)
+#include "tst_gestures.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qt/qapplication/smoketest_qapplication.cpp	Fri Jun 11 11:44:06 2010 +0100
@@ -0,0 +1,2202 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+//#define QT_TST_QAPP_DEBUG
+#include <qdebug.h>
+
+#include <QtTest/QtTest>
+
+#include "qabstracteventdispatcher.h"
+#include <QtGui>
+
+#include "private/qapplication_p.h"
+#include "private/qstylesheetstyle_p.h"
+#ifdef Q_OS_WINCE
+#include <windows.h>
+#endif
+#ifdef Q_OS_SYMBIAN
+#include <aknenv.h>
+#endif
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+#if defined(Q_OS_SYMBIAN)
+// In Symbian, the PluginsPath doesn't specify the only absolute path; just the dir that can be found on any drive
+/*static void addExpectedSymbianPluginsPath(QStringList& expected)
+{
+    QString installPathPlugins = QDir::fromNativeSeparators(QLibraryInfo::location(QLibraryInfo::PluginsPath));
+    QFileInfoList driveList = QDir::drives();
+    QListIterator<QFileInfo> iter(driveList);
+    while (iter.hasNext()) {
+        QFileInfo testFi(iter.next().canonicalPath().append(installPathPlugins));
+        if (testFi.exists())
+            expected << testFi.canonicalFilePath();
+    }
+}
+*/
+#endif
+
+class tst_QApplication : public QObject
+{
+Q_OBJECT
+
+public:
+    tst_QApplication();
+    virtual ~tst_QApplication();
+
+public slots:
+    void init();
+    void cleanup();
+private slots:
+    /*void sendEventsOnProcessEvents(); // this must be the first test
+    void getSetCheck();
+    void staticSetup();
+
+    void alert();
+
+    void multiple_data();
+    void multiple();
+
+    void nonGui();
+
+    void setFont_data();
+    void setFont();
+
+    void args_data();
+    void args();
+
+    void lastWindowClosed();
+    void quitOnLastWindowClosed();
+    void testDeleteLater();
+    void testDeleteLaterProcessEvents();
+
+    void libraryPaths();
+    void libraryPaths_qt_plugin_path();
+    void libraryPaths_qt_plugin_path_2();
+
+    void sendPostedEvents();
+
+    void thread();
+    void desktopSettingsAware();*/
+
+    void setActiveWindow();
+
+    /*void focusChanged();
+    void focusOut();
+
+    void execAfterExit();
+
+    void wheelScrollLines();
+
+    void task109149();
+
+    void style();
+
+    void allWidgets();
+    void topLevelWidgets();
+
+    void setAttribute();
+
+    void windowsCommandLine_data();
+    void windowsCommandLine();
+
+    void touchEventPropagation();
+
+    void symbianNoApplicationPanes();
+
+    void symbianNeedForTraps();
+    void symbianLeaveThroughMain();*/
+};
+
+/*class EventSpy : public QObject
+{
+   Q_OBJECT
+
+public:
+    QList<int> recordedEvents;
+    bool eventFilter(QObject *, QEvent *event)
+    {
+        recordedEvents.append(event->type());
+        return false;
+    }
+};
+*/
+
+/*
+void tst_QApplication::sendEventsOnProcessEvents()
+{
+    int argc = 0;
+    QApplication app(argc, 0, QApplication::GuiServer);
+
+    EventSpy spy;
+    app.installEventFilter(&spy);
+
+    QCoreApplication::postEvent(&app,  new QEvent(QEvent::Type(QEvent::User + 1)));
+    QCoreApplication::processEvents();
+    QVERIFY(spy.recordedEvents.contains(QEvent::User + 1));
+}
+
+class MyInputContext : public QInputContext
+{
+public:
+    MyInputContext() : QInputContext() {}
+    QString identifierName() { return QString("NoName"); }
+    QString language() { return QString("NoLanguage"); }
+    void reset() {}
+    bool isComposing() const { return false; }
+};
+
+// Testing get/set functions
+void tst_QApplication::getSetCheck()
+{
+    int argc = 0;
+    QApplication obj1(argc, 0, QApplication::GuiServer);
+    // QInputContext * QApplication::inputContext()
+    // void QApplication::setInputContext(QInputContext *)
+    MyInputContext *var1 = new MyInputContext;
+    obj1.setInputContext(var1);
+    QCOMPARE((QInputContext *)var1, obj1.inputContext());
+    QTest::ignoreMessage(QtWarningMsg, "QApplication::setInputContext: called with 0 input context");
+    obj1.setInputContext((QInputContext *)0);
+    QCOMPARE((QInputContext *)var1, obj1.inputContext());
+    // delete var1; // No delete, since QApplication takes ownership
+}
+
+class CloseEventTestWindow : public QWidget
+{
+public:
+    CloseEventTestWindow(QWidget *parent = 0)
+        : QWidget(parent)
+    {
+    }
+
+    void closeEvent(QCloseEvent *event)
+    {
+        QWidget dialog;
+        dialog.show();
+        dialog.close();
+
+        hide();
+        event->ignore();
+    }
+};
+*/
+
+static  char *argv0;
+
+tst_QApplication::tst_QApplication()
+{
+#ifdef Q_OS_WINCE
+    // Clean up environment previously to launching test
+    qputenv("QT_PLUGIN_PATH", QByteArray());
+#endif
+}
+
+tst_QApplication::~tst_QApplication()
+{
+
+}
+
+void tst_QApplication::init()
+{
+// TODO: Add initialization code here.
+// This will be executed immediately before each test is run.
+}
+
+void tst_QApplication::cleanup()
+{
+// TODO: Add cleanup code here.
+// This will be executed immediately after each test is run.
+}
+
+/*
+void tst_QApplication::staticSetup()
+{
+    QVERIFY(!qApp);
+
+    QStyle *style = QStyleFactory::create(QLatin1String("Windows"));
+    QVERIFY(style);
+    QApplication::setStyle(style);
+
+    QPalette pal;
+    QApplication::setPalette(pal);
+
+    //QFont font;
+    //QApplication::setFont(font);
+
+    int argc = 0;
+    QApplication app(argc, 0, QApplication::GuiServer);
+}
+
+
+// QApp subclass that exits the event loop after 150ms
+class TestApplication : public QApplication
+{
+public:
+    TestApplication( int &argc, char **argv )
+	: QApplication( argc, argv, QApplication::GuiServer )
+    {
+	startTimer( 150 );
+    }
+
+    void timerEvent( QTimerEvent * )
+    {
+        quit();
+    }
+};
+
+void tst_QApplication::alert()
+{
+    int argc = 0;
+    QApplication app(argc, 0, QApplication::GuiServer);
+    app.alert(0, 0);
+
+    QWidget widget;
+    QWidget widget2;
+    app.alert(&widget, 100);
+    widget.show();
+    widget2.show();
+#ifdef Q_WS_X11
+    qt_x11_wait_for_window_manager(&widget);
+    qt_x11_wait_for_window_manager(&widget2);
+#endif
+    QTest::qWait(100);
+    app.alert(&widget, -1);
+    app.alert(&widget, 250);
+    widget2.activateWindow();
+    QApplication::setActiveWindow(&widget2);
+    app.alert(&widget, 0);
+    widget.activateWindow();
+    QApplication::setActiveWindow(&widget);
+    app.alert(&widget, 200);
+    app.syncX();
+}
+
+void tst_QApplication::multiple_data()
+{
+    QTest::addColumn<QStringList>("features");
+
+    // return a list of things to try
+    QTest::newRow( "data0" ) << QStringList( "" );
+    QTest::newRow( "data1" ) << QStringList( "QFont" );
+    QTest::newRow( "data2" ) << QStringList( "QPixmap" );
+    QTest::newRow( "data3" ) << QStringList( "QWidget" );
+}
+
+void tst_QApplication::multiple()
+{
+    QFETCH(QStringList,features);
+
+    int i = 0;
+    int argc = 0;
+    while ( i++ < 5 ) {
+	TestApplication app( argc, 0 );
+
+	if ( features.contains( "QFont" ) ) {
+	    // create font and force loading
+	    QFont font( "Arial", 12 );
+	    QFontInfo finfo( font );
+	    finfo.exactMatch();
+	}
+	if ( features.contains( "QPixmap" ) ) {
+	    QPixmap pix( 100, 100 );
+	    pix.fill( Qt::black );
+	}
+	if ( features.contains( "QWidget" ) ) {
+	    QWidget widget;
+	}
+
+	QVERIFY(!app.exec());
+    }
+}
+
+void tst_QApplication::nonGui()
+{
+#ifdef Q_OS_HPUX
+    // ### This is only to allow us to generate a test report for now.
+    QSKIP("This test shuts down the window manager on HP-UX.", SkipAll);
+#endif
+
+    int argc = 0;
+    QApplication app(argc, 0, false);
+    QCOMPARE(qApp, &app);
+}
+
+void tst_QApplication::setFont_data()
+{
+    QTest::addColumn<QString>("family");
+    QTest::addColumn<int>("pointsize");
+    QTest::addColumn<bool>("beforeAppConstructor");
+
+    int argc = 0;
+    QApplication app(argc, 0, QApplication::GuiServer); // Needed for QFontDatabase
+
+    int cnt = 0;
+    QFontDatabase fdb;
+    QStringList families = fdb.families();
+    for (QStringList::const_iterator itr = families.begin();
+	 itr != families.end();
+	 ++itr) {
+	if (cnt < 3) {
+	    QString family = *itr;
+	    QStringList styles = fdb.styles(family);
+	    if (styles.size() > 0) {
+		QString style = styles.first();
+		QList<int> sizes = fdb.pointSizes(family, style);
+		if (!sizes.size())
+		    sizes = fdb.standardSizes();
+		if (sizes.size() > 0) {
+		    QTest::newRow(QString("data%1a").arg(cnt).toLatin1().constData())
+			<< family
+			<< sizes.first()
+                        << false;
+		    QTest::newRow(QString("data%1b").arg(cnt).toLatin1().constData())
+			<< family
+			<< sizes.first()
+                        << true;
+                }
+	    }
+	}
+	++cnt;
+    }
+
+    QTest::newRow("nonexistingfont") << "nosuchfont_probably_quiteunlikely"
+        << 0 << false;
+    QTest::newRow("nonexistingfont") << "nosuchfont_probably_quiteunlikely"
+        << 0 << true;
+
+    QTest::newRow("largescaleable") << "smoothtimes" << 100 << false;
+    QTest::newRow("largescaleable") << "smoothtimes" << 100 << true;
+
+    QTest::newRow("largeunscaleale") << "helvetica" << 100 << false;
+    QTest::newRow("largeunscaleale") << "helvetica" << 100 << true;
+}
+
+void tst_QApplication::setFont()
+{
+    QFETCH( QString, family );
+    QFETCH( int, pointsize );
+    QFETCH( bool, beforeAppConstructor );
+
+    QFont font( family, pointsize );
+    if (beforeAppConstructor) {
+        QApplication::setFont( font );
+        QCOMPARE(QApplication::font(), font);
+    }
+
+    int argc = 0;
+    QApplication app( argc, 0, QApplication::GuiServer );
+    if (!beforeAppConstructor)
+        QApplication::setFont( font );
+
+    QCOMPARE( app.font(), font );
+}
+
+void tst_QApplication::args_data()
+{
+    QTest::addColumn<int>("argc_in");
+    QTest::addColumn<QString>("args_in");
+    QTest::addColumn<int>("argc_out");
+    QTest::addColumn<QString>("args_out");
+
+    QTest::newRow( "App name" ) << 1 << "/usr/bin/appname" << 1 << "/usr/bin/appname";
+    QTest::newRow( "No arguments" ) << 0 << QString() << 0 << QString();
+    QTest::newRow( "App name, style" ) << 3 << "/usr/bin/appname -style motif" << 1 << "/usr/bin/appname";
+    QTest::newRow( "App name, style, arbitrary, reverse" ) << 5 << "/usr/bin/appname -style motif -arbitrary -reverse"
+							<< 2 << "/usr/bin/appname -arbitrary";
+}
+
+void tst_QApplication::task109149()
+{
+    int argc = 0;
+    QApplication app(argc, 0, QApplication::GuiServer);
+    QApplication::setFont(QFont("helvetica", 100));
+
+    QWidget w;
+    w.setWindowTitle("hello");
+    w.show();
+
+    app.processEvents();
+}
+
+static char ** QString2cstrings( const QString &args )
+{
+    static QList<QByteArray> cache;
+
+    int i;
+    char **argarray = 0;
+    QStringList list = args.split(' ');;
+    argarray = new char*[list.count()+1];
+
+    for (i = 0; i < (int)list.count(); ++i ) {
+        QByteArray l1 = list[i].toLatin1();
+        argarray[i] = l1.data();
+        cache.append(l1);
+    }
+    argarray[i] = 0;
+
+    return argarray;
+}
+
+static QString cstrings2QString( char **args )
+{
+    QString string;
+    if ( !args )
+	return string;
+
+    int i = 0;
+    while ( args[i] ) {
+	string += args[i];
+	if ( args[i+1] )
+	    string += " ";
+	++i;
+    }
+    return string;
+}
+
+void tst_QApplication::args()
+{
+    QFETCH( int, argc_in );
+    QFETCH( QString, args_in );
+    QFETCH( int, argc_out );
+    QFETCH( QString, args_out );
+
+    char **argv = QString2cstrings( args_in );
+
+    QApplication app( argc_in, argv, QApplication::GuiServer );
+    QString argv_out = cstrings2QString(argv);
+
+    QCOMPARE( argc_in, argc_out );
+    QCOMPARE( argv_out, args_out );
+
+    delete [] argv;
+}
+
+class CloseWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    CloseWidget()
+    {
+        startTimer(500);
+    }
+
+protected:
+    void timerEvent(QTimerEvent *)
+    {
+        close();
+    }
+
+};
+
+void tst_QApplication::lastWindowClosed()
+{
+    int argc = 0;
+    QApplication app(argc, 0, QApplication::GuiServer);
+
+    QSignalSpy spy(&app, SIGNAL(lastWindowClosed()));
+
+    QPointer<QDialog> dialog = new QDialog;
+    QVERIFY(dialog->testAttribute(Qt::WA_QuitOnClose));
+    QTimer::singleShot(1000, dialog, SLOT(accept()));
+    dialog->exec();
+    QVERIFY(dialog);
+    QCOMPARE(spy.count(), 0);
+
+    QPointer<CloseWidget>widget = new CloseWidget;
+    QVERIFY(widget->testAttribute(Qt::WA_QuitOnClose));
+    QObject::connect(&app, SIGNAL(lastWindowClosed()), widget, SLOT(deleteLater()));
+    app.exec();
+    QVERIFY(!widget);
+    QCOMPARE(spy.count(), 1);
+    spy.clear();
+
+#if 0
+    // everything is closed, so doing this should not emit lastWindowClosed() again
+    QMetaObject::invokeMethod(dialog, "close", Qt::QueuedConnection);
+    QTimer::singleShot(1000, &app, SLOT(quit()));
+    app.exec();
+    QCOMPARE(spy.count(), 0);
+#endif
+
+    delete dialog;
+
+    // show 3 windows, close them, should only get lastWindowClosed once
+    QWidget w1;
+    QWidget w2;
+    QWidget w3;
+    w1.show();
+    w2.show();
+    w3.show();
+
+    QTimer::singleShot(1000, &app, SLOT(closeAllWindows()));
+    app.exec();
+    QCOMPARE(spy.count(), 1);
+}
+
+class QuitOnLastWindowClosedDialog : public QDialog
+{
+    Q_OBJECT
+public:
+    QPushButton *okButton;
+
+    QuitOnLastWindowClosedDialog()
+    {
+        QHBoxLayout *hbox = new QHBoxLayout(this);
+        okButton = new QPushButton("&ok", this);
+
+        hbox->addWidget(okButton);
+        connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
+        connect(okButton, SIGNAL(clicked()), this, SLOT(ok_clicked()));
+    }
+
+public slots:
+    void ok_clicked()
+    {
+        QDialog other;
+
+        QTimer timer;
+        connect(&timer, SIGNAL(timeout()), &other, SLOT(accept()));
+        QSignalSpy spy(&timer, SIGNAL(timeout()));
+        QSignalSpy appSpy(qApp, SIGNAL(lastWindowClosed()));
+
+        timer.start(1000);
+        other.exec();
+
+        // verify that the eventloop ran and let the timer fire
+        QCOMPARE(spy.count(), 1);
+        QCOMPARE(appSpy.count(), 1);
+    }
+};
+
+class QuitOnLastWindowClosedWindow : public QWidget
+{
+    Q_OBJECT
+
+public:
+    QuitOnLastWindowClosedWindow()
+    { }
+
+public slots:
+    void execDialogThenShow()
+    {
+        QDialog dialog;
+        QTimer timer1;
+        connect(&timer1, SIGNAL(timeout()), &dialog, SLOT(accept()));
+        QSignalSpy spy1(&timer1, SIGNAL(timeout()));
+        timer1.setSingleShot(true);
+        timer1.start(1000);
+        dialog.exec();
+        QCOMPARE(spy1.count(), 1);
+
+        show();
+    }
+};
+
+void tst_QApplication::quitOnLastWindowClosed()
+{
+    {
+        int argc = 0;
+        QApplication app(argc, 0, QApplication::GuiServer);
+
+        QuitOnLastWindowClosedDialog d;
+        d.show();
+        QTimer::singleShot(1000, d.okButton, SLOT(animateClick()));
+
+        QSignalSpy appSpy(&app, SIGNAL(lastWindowClosed()));
+        app.exec();
+
+        // lastWindowClosed() signal should only be sent after the last dialog is closed
+        QCOMPARE(appSpy.count(), 2);
+    }
+    {
+        int argc = 0;
+        QApplication app(argc, 0, QApplication::GuiServer);
+        QSignalSpy appSpy(&app, SIGNAL(lastWindowClosed()));
+
+        QDialog dialog;
+        QTimer timer1;
+        connect(&timer1, SIGNAL(timeout()), &dialog, SLOT(accept()));
+        QSignalSpy spy1(&timer1, SIGNAL(timeout()));
+        timer1.setSingleShot(true);
+        timer1.start(1000);
+        dialog.exec();
+        QCOMPARE(spy1.count(), 1);
+        QCOMPARE(appSpy.count(), 0);
+
+        QTimer timer2;
+        connect(&timer2, SIGNAL(timeout()), &app, SLOT(quit()));
+        QSignalSpy spy2(&timer2, SIGNAL(timeout()));
+        timer2.setSingleShot(true);
+        timer2.start(1000);
+        int returnValue = app.exec();
+        QCOMPARE(returnValue, 0);
+        QCOMPARE(spy2.count(), 1);
+        QCOMPARE(appSpy.count(), 0);
+    }
+    {
+        int argc = 0;
+        QApplication app(argc, 0, QApplication::GuiServer);
+        QTimer timer;
+        timer.setInterval(100);
+
+        QSignalSpy spy(&app, SIGNAL(aboutToQuit()));
+        QSignalSpy spy2(&timer, SIGNAL(timeout()));
+
+        QPointer<QMainWindow> mainWindow = new QMainWindow;
+        QPointer<QDialog> dialog = new QDialog(mainWindow);
+
+        QVERIFY(app.quitOnLastWindowClosed());
+        QVERIFY(mainWindow->testAttribute(Qt::WA_QuitOnClose));
+        QVERIFY(dialog->testAttribute(Qt::WA_QuitOnClose));
+
+        mainWindow->show();
+        dialog->show();
+
+        timer.start();
+        QTimer::singleShot(1000, mainWindow, SLOT(close())); // This should quit the application
+        QTimer::singleShot(2000, &app, SLOT(quit()));        // This makes sure we quit even if it didn't
+
+        app.exec();
+
+        QCOMPARE(spy.count(), 1);
+        QVERIFY(spy2.count() < 15);      // Should be around 10 if closing caused the quit
+    }
+    {
+        int argc = 0;
+        QApplication app(argc, 0, QApplication::GuiServer);
+        QTimer timer;
+        timer.setInterval(100);
+
+        QSignalSpy spy(&app, SIGNAL(aboutToQuit()));
+        QSignalSpy spy2(&timer, SIGNAL(timeout()));
+
+        QPointer<QMainWindow> mainWindow = new QMainWindow;
+        QPointer<QWidget> invisibleTopLevelWidget = new QWidget;
+        invisibleTopLevelWidget->setAttribute(Qt::WA_DontShowOnScreen);
+
+        QVERIFY(app.quitOnLastWindowClosed());
+        QVERIFY(mainWindow->testAttribute(Qt::WA_QuitOnClose));
+        QVERIFY(invisibleTopLevelWidget->testAttribute(Qt::WA_QuitOnClose));
+        QVERIFY(invisibleTopLevelWidget->testAttribute(Qt::WA_DontShowOnScreen));
+
+        mainWindow->show();
+        invisibleTopLevelWidget->show();
+
+        timer.start();
+        QTimer::singleShot(1000, mainWindow, SLOT(close())); // This should quit the application
+        QTimer::singleShot(2000, &app, SLOT(quit()));        // This makes sure we quit even if it didn't
+
+        app.exec();
+
+        QCOMPARE(spy.count(), 1);
+        QVERIFY(spy2.count() < 15);      // Should be around 10 if closing caused the quit
+    }
+    {
+        int argc = 0;
+        QApplication app(argc, 0, QApplication::GuiServer);
+        QTimer timer;
+        timer.setInterval(100);
+
+        QSignalSpy spy(&app, SIGNAL(aboutToQuit()));
+        QSignalSpy spy2(&timer, SIGNAL(timeout()));
+
+        QPointer<CloseEventTestWindow> mainWindow = new CloseEventTestWindow;
+
+        QVERIFY(app.quitOnLastWindowClosed());
+        QVERIFY(mainWindow->testAttribute(Qt::WA_QuitOnClose));
+
+        mainWindow->show();
+
+        timer.start();
+        QTimer::singleShot(1000, mainWindow, SLOT(close())); // This should quit the application
+        QTimer::singleShot(2000, &app, SLOT(quit()));        // This makes sure we quit even if it didn't
+
+        app.exec();
+
+        QCOMPARE(spy.count(), 1);
+        QVERIFY(spy2.count() > 15);      // Should be around 20 if closing did not caused the quit
+    }
+    {
+        int argc = 0;
+        QApplication app(argc, 0, QApplication::GuiServer);
+        QSignalSpy appSpy(&app, SIGNAL(lastWindowClosed()));
+
+        // exec a dialog for 1 second, then show the window
+        QuitOnLastWindowClosedWindow window;
+        QTimer::singleShot(0, &window, SLOT(execDialogThenShow()));
+
+        QTimer timer;
+        QSignalSpy timerSpy(&timer, SIGNAL(timeout()));
+        connect(&timer, SIGNAL(timeout()), &window, SLOT(close()));
+        timer.setSingleShot(true);
+        timer.start(2000);
+        int returnValue = app.exec();
+        QCOMPARE(returnValue, 0);
+        // failure here means the timer above didn't fire, and the
+        // quit was caused the the dialog being closed (not the window)
+        QCOMPARE(timerSpy.count(), 1);
+        QCOMPARE(appSpy.count(), 2);
+    }
+}
+
+bool isPathListIncluded(const QStringList &l, const QStringList &r)
+{
+    int size = r.count();
+    if (size > l.count())
+        return false;
+#if defined (Q_OS_WIN)
+    Qt::CaseSensitivity cs = Qt::CaseInsensitive;
+#else
+    Qt::CaseSensitivity cs = Qt::CaseSensitive;
+#endif
+    int i = 0, j = 0;
+    for ( ; i < l.count() && j < r.count(); ++i) {
+        if (QDir::toNativeSeparators(l[i]).compare(QDir::toNativeSeparators(r[j]), cs) == 0) {
+            ++j;
+            i = -1;
+        }
+    }
+    return j == r.count();
+}
+
+#define QT_TST_QAPP_DEBUG
+void tst_QApplication::libraryPaths()
+{
+    {
+#ifndef Q_OS_WINCE
+        QString testDir = QDir::current().canonicalPath() + "/test";
+#else
+        // On Windows CE we need QApplication object to have valid
+        // current Path. Therefore we need to identify it ourselves
+        // here for the test.
+        QFileInfo filePath;
+        wchar_t module_name[MAX_PATH];
+        GetModuleFileName(0, module_name, MAX_PATH);
+        filePath = QString::fromWCharArray(module_name);
+        QString testDir = filePath.path() + "/test";
+#endif
+        QApplication::setLibraryPaths(QStringList() << testDir);
+        QCOMPARE(QApplication::libraryPaths(), (QStringList() << testDir));
+
+        // creating QApplication adds the applicationDirPath to the libraryPath
+        int argc = 1;
+        QApplication app(argc, &argv0, QApplication::GuiServer);
+        QString appDirPath = QDir(app.applicationDirPath()).canonicalPath();
+
+        QStringList actual = QApplication::libraryPaths();
+        actual.sort();
+        QStringList expected = QSet<QString>::fromList((QStringList() << testDir << appDirPath)).toList();
+        expected.sort();
+
+        QVERIFY2(isPathListIncluded(actual, expected),
+                 qPrintable("actual:\n - " + actual.join("\n - ") +
+                            "\nexpected:\n - " + expected.join("\n - ")));
+    }
+    {
+        // creating QApplication adds the applicationDirPath and plugin install path to the libraryPath
+        int argc = 1;
+        QApplication app(argc, &argv0, QApplication::GuiServer);
+        QString appDirPath = app.applicationDirPath();
+        QString installPathPlugins =  QLibraryInfo::location(QLibraryInfo::PluginsPath);
+
+        QStringList actual = QApplication::libraryPaths();
+        actual.sort();
+
+#if defined(Q_OS_SYMBIAN)
+        QStringList expected;
+        addExpectedSymbianPluginsPath(expected);
+        expected << appDirPath;
+#else
+        QStringList expected = QSet<QString>::fromList((QStringList() << installPathPlugins << appDirPath)).toList();
+#endif
+        expected.sort();
+
+        QVERIFY2(isPathListIncluded(actual, expected),
+                 qPrintable("actual:\n - " + actual.join("\n - ") +
+                            "\nexpected:\n - " + expected.join("\n - ")));
+
+        // setting the library paths overrides everything
+        QString testDir = QDir::currentPath() + "/test";
+        QApplication::setLibraryPaths(QStringList() << testDir);
+        QVERIFY2(isPathListIncluded(QApplication::libraryPaths(), (QStringList() << testDir)),
+                 qPrintable("actual:\n - " + QApplication::libraryPaths().join("\n - ") +
+                            "\nexpected:\n - " + testDir));
+    }
+    {
+#ifdef QT_TST_QAPP_DEBUG
+        qDebug() << "Initial library path:" << QApplication::libraryPaths();
+#endif
+
+        int count = QApplication::libraryPaths().count();
+#if 0
+        // this test doesn't work if KDE 4 is installed
+        QCOMPARE(count, 1); // before creating QApplication, only the PluginsPath is in the libraryPaths()
+#endif
+        QString installPathPlugins =  QLibraryInfo::location(QLibraryInfo::PluginsPath);
+        QApplication::addLibraryPath(installPathPlugins);
+#ifdef QT_TST_QAPP_DEBUG
+        qDebug() << "installPathPlugins" << installPathPlugins;
+        qDebug() << "After adding plugins path:" << QApplication::libraryPaths();
+#endif
+        QCOMPARE(QApplication::libraryPaths().count(), count);
+
+        QApplication::addLibraryPath(QDir::currentPath() + "/test");
+        QCOMPARE(QApplication::libraryPaths().count(), count + 1);
+
+        // creating QApplication adds the applicationDirPath to the libraryPath
+        int argc = 1;
+        QApplication app(argc, &argv0, QApplication::GuiServer);
+        QString appDirPath = app.applicationDirPath();
+        qDebug() << QApplication::libraryPaths();
+        // On Windows CE these are identical and might also be the case for other
+        // systems too
+        if (appDirPath != installPathPlugins)
+            QCOMPARE(QApplication::libraryPaths().count(), count + 2);
+    }
+    {
+        int argc = 1;
+        QApplication app(argc, &argv0, QApplication::GuiServer);
+
+#ifdef QT_TST_QAPP_DEBUG
+        qDebug() << "Initial library path:" << app.libraryPaths();
+#endif
+        int count = app.libraryPaths().count();
+        QString installPathPlugins =  QLibraryInfo::location(QLibraryInfo::PluginsPath);
+        app.addLibraryPath(installPathPlugins);
+#ifdef QT_TST_QAPP_DEBUG
+        qDebug() << "installPathPlugins" << installPathPlugins;
+        qDebug() << "After adding plugins path:" << app.libraryPaths();
+#endif
+        QCOMPARE(app.libraryPaths().count(), count);
+
+        QString appDirPath = app.applicationDirPath();
+
+        app.addLibraryPath(appDirPath);
+#ifdef Q_OS_WINCE
+        app.addLibraryPath(appDirPath + "/../..");
+#else
+        app.addLibraryPath(appDirPath + "/..");
+#endif
+#ifdef QT_TST_QAPP_DEBUG
+        qDebug() << "appDirPath" << appDirPath;
+        qDebug() << "After adding appDirPath && appDirPath + /..:" << app.libraryPaths();
+#endif
+        QCOMPARE(app.libraryPaths().count(), count + 1);
+#ifdef Q_OS_MAC
+        app.addLibraryPath(appDirPath + "/../MacOS");
+#else
+        app.addLibraryPath(appDirPath + "/tmp/..");
+#endif
+#ifdef QT_TST_QAPP_DEBUG
+        qDebug() << "After adding appDirPath + /tmp/..:" << app.libraryPaths();
+#endif
+        QCOMPARE(app.libraryPaths().count(), count + 1);
+    }
+}
+
+void tst_QApplication::libraryPaths_qt_plugin_path()
+{
+    int argc = 1;
+
+    QApplication app(argc, &argv0, QApplication::GuiServer);
+    QString appDirPath = app.applicationDirPath();
+
+    // Our hook into libraryPaths() initialization: Set the QT_PLUGIN_PATH environment variable
+    QString installPathPluginsDeCanon = appDirPath + QString::fromLatin1("/tmp/..");
+    QByteArray ascii = installPathPluginsDeCanon.toAscii();
+    qputenv("QT_PLUGIN_PATH", ascii);
+
+    QVERIFY(!app.libraryPaths().contains(appDirPath + QString::fromLatin1("/tmp/..")));
+}
+
+void tst_QApplication::libraryPaths_qt_plugin_path_2()
+{
+#ifdef Q_OS_SYMBIAN
+    QByteArray validPath = "C:\\data";
+    QByteArray nonExistentPath = "Z:\\nonexistent";
+    QByteArray pluginPath = validPath + ";" + nonExistentPath;
+#elif defined(Q_OS_UNIX)
+    QByteArray validPath = QDir("/tmp").canonicalPath().toLatin1();
+    QByteArray nonExistentPath = "/nonexistent";
+    QByteArray pluginPath = validPath + ":" + nonExistentPath;
+#elif defined(Q_OS_WIN)
+# ifdef Q_OS_WINCE
+    QByteArray validPath = "/Temp";
+    QByteArray nonExistentPath = "/nonexistent";
+    QByteArray pluginPath = validPath + ";" + nonExistentPath;
+# else
+    QByteArray validPath = "C:\\windows";
+    QByteArray nonExistentPath = "Z:\\nonexistent";
+    QByteArray pluginPath = validPath + ";" + nonExistentPath;
+# endif
+#endif
+
+    {
+        // Our hook into libraryPaths() initialization: Set the QT_PLUGIN_PATH environment variable
+        qputenv("QT_PLUGIN_PATH", pluginPath);
+
+        int argc = 1;
+
+        QApplication app(argc, &argv0, QApplication::GuiServer);
+
+        // library path list should contain the default plus the one valid path
+#if defined(Q_OS_SYMBIAN)
+        // In Symbian, the PluginsPath doesn't specify the only absolute path; just the dir that can be found on any drive
+        QStringList expected;
+        addExpectedSymbianPluginsPath(expected);
+        expected << QDir(app.applicationDirPath()).canonicalPath()
+            << QDir(QDir::fromNativeSeparators(QString::fromLatin1(validPath))).canonicalPath();
+#else
+        QStringList expected =
+            QStringList()
+            << QLibraryInfo::location(QLibraryInfo::PluginsPath)
+            << QDir(app.applicationDirPath()).canonicalPath()
+            << QDir(QDir::fromNativeSeparators(QString::fromLatin1(validPath))).canonicalPath();
+# ifdef Q_OS_WINCE
+        expected = QSet<QString>::fromList(expected).toList();
+# endif
+#endif
+        QVERIFY2(isPathListIncluded(app.libraryPaths(), expected),
+                 qPrintable("actual:\n - " + app.libraryPaths().join("\n - ") +
+                            "\nexpected:\n - " + expected.join("\n - ")));
+    }
+
+    {
+        int argc = 1;
+
+        QApplication app(argc, &argv0, QApplication::GuiServer);
+
+        // library paths are initialized by the QApplication, setting
+        // the environment variable here doesn't work
+        qputenv("QT_PLUGIN_PATH", pluginPath);
+
+        // library path list should contain the default
+#if defined(Q_OS_SYMBIAN)
+        QStringList expected;
+        addExpectedSymbianPluginsPath(expected);
+        expected << app.applicationDirPath();
+#else
+        QStringList expected =
+            QStringList()
+            << QLibraryInfo::location(QLibraryInfo::PluginsPath)
+            << app.applicationDirPath();
+# ifdef Q_OS_WINCE
+        expected = QSet<QString>::fromList(expected).toList();
+# endif
+#endif
+        QVERIFY(isPathListIncluded(app.libraryPaths(), expected));
+
+        qputenv("QT_PLUGIN_PATH", QByteArray());
+    }
+}
+
+class SendPostedEventsTester : public QObject
+{
+    Q_OBJECT
+public:
+    QList<int> eventSpy;
+    bool event(QEvent *e);
+private slots:
+    void doTest();
+};
+
+bool SendPostedEventsTester::event(QEvent *e)
+{
+    eventSpy.append(e->type());
+    return QObject::event(e);
+}
+
+void SendPostedEventsTester::doTest()
+{
+    QPointer<SendPostedEventsTester> p = this;
+    QApplication::postEvent(this, new QEvent(QEvent::User));
+    // DeferredDelete should not be delivered until returning from this function
+    QApplication::postEvent(this, new QEvent(QEvent::DeferredDelete));
+
+    QEventLoop eventLoop;
+    QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
+    eventLoop.exec();
+    QVERIFY(p != 0);
+
+    QCOMPARE(eventSpy.count(), 2);
+    QCOMPARE(eventSpy.at(0), int(QEvent::MetaCall));
+    QCOMPARE(eventSpy.at(1), int(QEvent::User));
+    eventSpy.clear();
+}
+
+void tst_QApplication::sendPostedEvents()
+{
+    int argc = 0;
+    QApplication app(argc, 0, QApplication::GuiServer);
+    SendPostedEventsTester *tester = new SendPostedEventsTester;
+    QMetaObject::invokeMethod(tester, "doTest", Qt::QueuedConnection);
+    QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection);
+    QPointer<SendPostedEventsTester> p = tester;
+    (void) app.exec();
+    QVERIFY(p == 0);
+}
+
+void tst_QApplication::thread()
+{
+    QThread *currentThread = QThread::currentThread();
+    // no app, but still have a valid thread
+    QVERIFY(currentThread != 0);
+
+    // the thread should be running and not finished
+    QVERIFY(currentThread->isRunning());
+    QVERIFY(!currentThread->isFinished());
+
+    // this should probably be in the tst_QObject::thread() test, but
+    // we put it here since we want to make sure that objects created
+    // *before* the QApplication has a thread
+    QObject object;
+    QObject child(&object);
+    QVERIFY(object.thread() == currentThread);
+    QVERIFY(child.thread() == currentThread);
+
+    {
+        int argc = 0;
+        QApplication app(argc, 0, QApplication::GuiServer);
+
+        // current thread still valid
+        QVERIFY(QThread::currentThread() != 0);
+        // thread should be the same as before
+        QCOMPARE(QThread::currentThread(), currentThread);
+
+        // app's thread should be the current thread
+        QCOMPARE(app.thread(), currentThread);
+
+        // the thread should still be running and not finished
+        QVERIFY(currentThread->isRunning());
+        QVERIFY(!currentThread->isFinished());
+
+        QTestEventLoop::instance().enterLoop(1);
+    }
+
+    // app dead, current thread still valid
+    QVERIFY(QThread::currentThread() != 0);
+    QCOMPARE(QThread::currentThread(), currentThread);
+
+    // the thread should still be running and not finished
+    QVERIFY(currentThread->isRunning());
+    QVERIFY(!currentThread->isFinished());
+
+    // should still have a thread
+    QVERIFY(object.thread() == currentThread);
+    QVERIFY(child.thread() == currentThread);
+
+    // do the test again, making sure that the thread is the same as
+    // before
+    {
+        int argc = 0;
+        QApplication app(argc, 0, QApplication::GuiServer);
+
+        // current thread still valid
+        QVERIFY(QThread::currentThread() != 0);
+        // thread should be the same as before
+        QCOMPARE(QThread::currentThread(), currentThread);
+
+        // app's thread should be the current thread
+        QCOMPARE(app.thread(), currentThread);
+
+        // the thread should be running and not finished
+        QVERIFY(currentThread->isRunning());
+        QVERIFY(!currentThread->isFinished());
+
+        // should still have a thread
+        QVERIFY(object.thread() == currentThread);
+        QVERIFY(child.thread() == currentThread);
+
+        QTestEventLoop::instance().enterLoop(1);
+    }
+
+    // app dead, current thread still valid
+    QVERIFY(QThread::currentThread() != 0);
+    QCOMPARE(QThread::currentThread(), currentThread);
+
+    // the thread should still be running and not finished
+    QVERIFY(currentThread->isRunning());
+    QVERIFY(!currentThread->isFinished());
+
+    // should still have a thread
+    QVERIFY(object.thread() == currentThread);
+    QVERIFY(child.thread() == currentThread);
+}
+
+class DeleteLaterWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    DeleteLaterWidget(QApplication *_app, QWidget *parent = 0)
+        : QWidget(parent) { app = _app; child_deleted = false; }
+
+    bool child_deleted;
+    QApplication *app;
+
+public slots:
+    void runTest();
+    void checkDeleteLater();
+    void childDeleted() { child_deleted = true; }
+};
+
+
+void DeleteLaterWidget::runTest()
+{
+    QObject *stillAlive = qFindChild<QObject*>(this, "deleteLater");
+
+    QWidget *w = new QWidget(this);
+    connect(w, SIGNAL(destroyed()), this, SLOT(childDeleted()));
+
+    w->deleteLater();
+    QVERIFY(!child_deleted);
+
+    QDialog dlg;
+    QTimer::singleShot(500, &dlg, SLOT(reject()));
+    dlg.exec();
+
+    QVERIFY(!child_deleted);
+    app->processEvents();
+    QVERIFY(!child_deleted);
+
+    QTimer::singleShot(500, this, SLOT(checkDeleteLater()));
+
+    app->processEvents();
+
+    QVERIFY(!stillAlive); // verify at the end to make test terminate
+}
+
+void DeleteLaterWidget::checkDeleteLater()
+{
+    QVERIFY(child_deleted);
+
+    close();
+}
+
+void tst_QApplication::testDeleteLater()
+{
+    int argc = 0;
+    QApplication app(argc, 0, QApplication::GuiServer);
+    connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
+
+    DeleteLaterWidget *wgt = new DeleteLaterWidget(&app);
+    QTimer::singleShot(500, wgt, SLOT(runTest()));
+
+    QObject *object = new QObject(wgt);
+    object->setObjectName("deleteLater");
+    object->deleteLater();
+
+    QObject *stillAlive = qFindChild<QObject*>(wgt, "deleteLater");
+    QVERIFY(stillAlive);
+
+    app.exec();
+
+    delete wgt;
+
+}
+
+class EventLoopNester : public QObject
+{
+    Q_OBJECT
+public slots:
+    void deleteLaterAndEnterLoop()
+    {
+        QEventLoop eventLoop;
+        QPointer<QObject> p(this);
+        deleteLater();
+        
+        // DeferredDelete events are compressed, meaning this second
+        // deleteLater() will *not* delete the object in the nested
+        // event loop
+        QMetaObject::invokeMethod(this, "deleteLater", Qt::QueuedConnection);
+        QTimer::singleShot(1000, &eventLoop, SLOT(quit()));
+        eventLoop.exec();
+        QVERIFY(p);
+    }
+    void deleteLaterAndExitLoop()
+    {
+        // Check that 'p' is not deleted before exec returns, since the call
+        // to QEventLoop::quit() should stop 'eventLoop' from processing
+        // any more events (that is, delete later) until we return to the
+        // _current_ event loop:
+        QEventLoop eventLoop;
+        QPointer<QObject> p(this);
+        QMetaObject::invokeMethod(this, "deleteLater", Qt::QueuedConnection);
+        QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
+        eventLoop.exec();
+        QVERIFY(p); // not dead yet
+    }
+
+    void processEventsOnly()
+    {
+        QApplication::processEvents();
+    }
+    void processEventsWithDeferredDeletion()
+    {
+        QApplication::processEvents(QEventLoop::DeferredDeletion);
+    }
+    void sendPostedEventsWithDeferredDelete()
+    {
+        QApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+    }
+    void deleteLaterAndProcessEvents1()
+    {
+        QEventLoop eventLoop;
+
+        QPointer<QObject> p = this;
+        deleteLater();
+
+        // trying to delete this object in a deeper eventloop just won't work
+        QMetaObject::invokeMethod(this,
+                                  "processEventsOnly",
+                                  Qt::QueuedConnection);
+        QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
+        eventLoop.exec();
+        QVERIFY(p);
+        QMetaObject::invokeMethod(this,
+                                  "processEventsWithDeferredDeletion",
+                                  Qt::QueuedConnection);
+        QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
+        eventLoop.exec();
+        QVERIFY(p);
+        QMetaObject::invokeMethod(this,
+                                  "sendPostedEventsWithDeferredDelete",
+                                  Qt::QueuedConnection);
+        QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
+        eventLoop.exec();
+        QVERIFY(p);
+
+        // trying to delete it from this eventloop still doesn't work
+        QApplication::processEvents();
+        QVERIFY(p);
+
+        // however, it *will* work with this magic incantation
+        QApplication::processEvents(QEventLoop::DeferredDeletion);
+        QVERIFY(!p);
+    }
+
+    void deleteLaterAndProcessEvents2()
+    {
+        QEventLoop eventLoop;
+
+        QPointer<QObject> p = this;
+        deleteLater();
+
+        // trying to delete this object in a deeper eventloop just won't work
+        QMetaObject::invokeMethod(this,
+                                  "processEventsOnly",
+                                  Qt::QueuedConnection);
+        QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
+        eventLoop.exec();
+        QVERIFY(p);
+        QMetaObject::invokeMethod(this,
+                                  "processEventsWithDeferredDeletion",
+                                  Qt::QueuedConnection);
+        QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
+        eventLoop.exec();
+        QVERIFY(p);
+        QMetaObject::invokeMethod(this,
+                                  "sendPostedEventsWithDeferredDelete",
+                                  Qt::QueuedConnection);
+        QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
+        eventLoop.exec();
+        QVERIFY(p);
+
+        // trying to delete it from this eventloop still doesn't work
+        QApplication::processEvents();
+        QVERIFY(p);
+
+        // however, it *will* work with this magic incantation
+        QApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+        QVERIFY(!p);
+    }
+};
+
+void tst_QApplication::testDeleteLaterProcessEvents()
+{
+    int argc = 0;
+
+    // Calling processEvents() with no event dispatcher does nothing.
+    QObject *object = new QObject;
+    QPointer<QObject> p(object);
+    object->deleteLater();
+    QApplication::processEvents();
+    QVERIFY(p);
+    delete object;
+
+    {
+        QApplication app(argc, 0, QApplication::GuiServer);
+        // If you call processEvents() with an event dispatcher present, but
+        // outside any event loops, deferred deletes are not processed unless
+        // QEventLoop::DeferredDeletion is passed.
+        object = new QObject;
+        p = object;
+        object->deleteLater();
+        app.processEvents();
+        QVERIFY(p);
+        app.processEvents(QEventLoop::ProcessEventsFlag(0x10)); // 0x10 == QEventLoop::DeferredDeletion
+        QVERIFY(!p);
+
+        // sendPostedEvents(0, DeferredDelete); also works
+        object = new QObject;
+        p = object;
+        object->deleteLater();
+        app.processEvents();
+        QVERIFY(p);
+        QApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+        QVERIFY(!p);
+
+        // If you call deleteLater() on an object when there is no parent
+        // event loop, and then enter an event loop, the object will get
+        // deleted.
+        object = new QObject;
+        p = object;
+        object->deleteLater();
+        QEventLoop loop;
+        QTimer::singleShot(1000, &loop, SLOT(quit()));
+        loop.exec();
+        QVERIFY(!p);
+    }
+    {
+        // When an object is in an event loop, then calls deleteLater() and enters
+        // an event loop recursively, it should not die until the parent event
+        // loop continues.
+        QApplication app(argc, 0, QApplication::GuiServer);
+        QEventLoop loop;
+        EventLoopNester *nester = new EventLoopNester;
+        p = nester;
+        QTimer::singleShot(3000, &loop, SLOT(quit()));
+        QTimer::singleShot(0, nester, SLOT(deleteLaterAndEnterLoop()));
+
+        loop.exec();
+        QVERIFY(!p);
+    }
+
+    {
+        // When the event loop that calls deleteLater() is exited
+        // immediately, the object should die when returning to the
+        // parent event loop
+        QApplication app(argc, 0, QApplication::GuiServer);
+        QEventLoop loop;
+        EventLoopNester *nester = new EventLoopNester;
+        p = nester;
+        QTimer::singleShot(3000, &loop, SLOT(quit()));
+        QTimer::singleShot(0, nester, SLOT(deleteLaterAndExitLoop()));
+
+        loop.exec();
+        QVERIFY(!p);
+    }
+
+    {
+        // when the event loop that calls deleteLater() also calls
+        // processEvents() immediately afterwards, the object should
+        // not die until the parent loop continues
+        QApplication app(argc, 0, QApplication::GuiServer);
+        QEventLoop loop;
+        EventLoopNester *nester = new EventLoopNester();
+        p = nester;
+        QTimer::singleShot(3000, &loop, SLOT(quit()));
+        QTimer::singleShot(0, nester, SLOT(deleteLaterAndProcessEvents1()));
+
+        loop.exec();
+        QVERIFY(!p);
+    }
+
+    {
+        // when the event loop that calls deleteLater() also calls
+        // processEvents() immediately afterwards, the object should
+        // not die until the parent loop continues
+        QApplication app(argc, 0, QApplication::GuiServer);
+        QEventLoop loop;
+        EventLoopNester *nester = new EventLoopNester();
+        p = nester;
+        QTimer::singleShot(3000, &loop, SLOT(quit()));
+        QTimer::singleShot(0, nester, SLOT(deleteLaterAndProcessEvents2()));
+
+        loop.exec();
+        QVERIFY(!p);
+    }
+}
+
+
+//    Test for crash whith QApplication::setDesktopSettingsAware(false).
+
+void tst_QApplication::desktopSettingsAware()
+{
+#ifndef QT_NO_PROCESS
+    QProcess testProcess;
+#ifdef Q_OS_WINCE
+    int argc = 0;
+    QApplication tmpApp(argc, 0, QApplication::GuiServer);
+    testProcess.start("desktopsettingsaware/desktopsettingsaware");
+#else
+#if defined(Q_OS_WIN) && defined(QT_DEBUG)
+    testProcess.start("desktopsettingsaware/debug/desktopsettingsaware");
+#elif defined(Q_OS_WIN)
+    testProcess.start("desktopsettingsaware/release/desktopsettingsaware");
+#elif defined(Q_OS_SYMBIAN)
+    testProcess.start("desktopsettingsaware");
+#if defined(Q_CC_NOKIAX86)
+    QEXPECT_FAIL("", "QProcess on Q_CC_NOKIAX86 cannot launch another Qt application, due to DLL conflicts.", Abort);
+    // TODO: Remove XFAIL, as soon as we can launch Qt applications from within Qt applications on Symbian
+    QVERIFY(testProcess.error() != QProcess::FailedToStart);
+#endif // defined(Q_CC_NOKIAX86)
+#else
+    testProcess.start("desktopsettingsaware/desktopsettingsaware");
+#endif
+#endif
+    QVERIFY(testProcess.waitForFinished(10000));
+    QCOMPARE(int(testProcess.state()), int(QProcess::NotRunning));
+    QVERIFY(int(testProcess.error()) != int(QProcess::Crashed));
+#endif
+}
+*/
+
+void tst_QApplication::setActiveWindow()
+{
+    int argc = 0;
+    QApplication MyApp(argc, 0, QApplication::GuiServer);
+
+    QWidget* w = new QWidget;
+    QVBoxLayout* layout = new QVBoxLayout(w);
+
+    QLineEdit* pb1 = new QLineEdit("Testbutton1", w);
+    QLineEdit* pb2 = new QLineEdit("Test Line Edit", w);
+
+    layout->addWidget(pb1);
+    layout->addWidget(pb2);
+
+    pb2->setFocus();
+    pb2->setParent(0);
+    delete pb2;
+
+    w->show();
+    QApplication::setActiveWindow(w); // needs this on twm (focus follows mouse)
+    QVERIFY(pb1->hasFocus());
+    delete w;
+}
+
+
+/* This might fail on some X11 window managers? */
+/*
+void tst_QApplication::focusChanged()
+{
+    int argc = 0;
+    QApplication app(argc, 0, QApplication::GuiServer);
+
+    QSignalSpy spy(&app, SIGNAL(focusChanged(QWidget *, QWidget *)));
+    QWidget *now = 0;
+    QWidget *old = 0;
+
+    QWidget parent1;
+    QHBoxLayout hbox1(&parent1);
+    QLabel lb1(&parent1);
+    QLineEdit le1(&parent1);
+    QPushButton pb1(&parent1);
+    hbox1.addWidget(&lb1);
+    hbox1.addWidget(&le1);
+    hbox1.addWidget(&pb1);
+
+    QCOMPARE(spy.count(), 0);
+
+    parent1.show();
+    QApplication::setActiveWindow(&parent1); // needs this on twm (focus follows mouse)
+    QCOMPARE(spy.count(), 1);
+    QCOMPARE(spy.at(0).count(), 2);
+    old = qVariantValue<QWidget*>(spy.at(0).at(0));
+    now = qVariantValue<QWidget*>(spy.at(0).at(1));
+    QVERIFY(now == &le1);
+    QVERIFY(now == QApplication::focusWidget());
+    QVERIFY(old == 0);
+    spy.clear();
+    QCOMPARE(spy.count(), 0);
+
+    pb1.setFocus();
+    QCOMPARE(spy.count(), 1);
+    old = qVariantValue<QWidget*>(spy.at(0).at(0));
+    now = qVariantValue<QWidget*>(spy.at(0).at(1));
+    QVERIFY(now == &pb1);
+    QVERIFY(now == QApplication::focusWidget());
+    QVERIFY(old == &le1);
+    spy.clear();
+
+    lb1.setFocus();
+    QCOMPARE(spy.count(), 1);
+    old = qVariantValue<QWidget*>(spy.at(0).at(0));
+    now = qVariantValue<QWidget*>(spy.at(0).at(1));
+    QVERIFY(now == &lb1);
+    QVERIFY(now == QApplication::focusWidget());
+    QVERIFY(old == &pb1);
+    spy.clear();
+
+    lb1.clearFocus();
+    QCOMPARE(spy.count(), 1);
+    old = qVariantValue<QWidget*>(spy.at(0).at(0));
+    now = qVariantValue<QWidget*>(spy.at(0).at(1));
+    QVERIFY(now == 0);
+    QVERIFY(now == QApplication::focusWidget());
+    QVERIFY(old == &lb1);
+    spy.clear();
+
+    QWidget parent2;
+    QHBoxLayout hbox2(&parent2);
+    QLabel lb2(&parent2);
+    QLineEdit le2(&parent2);
+    QPushButton pb2(&parent2);
+    hbox2.addWidget(&lb2);
+    hbox2.addWidget(&le2);
+    hbox2.addWidget(&pb2);
+
+    parent2.show();
+    QApplication::setActiveWindow(&parent2); // needs this on twm (focus follows mouse)
+    QVERIFY(spy.count() > 0); // one for deactivation, one for activation on Windows
+    old = qVariantValue<QWidget*>(spy.at(spy.count()-1).at(0));
+    now = qVariantValue<QWidget*>(spy.at(spy.count()-1).at(1));
+    QVERIFY(now == &le2);
+    QVERIFY(now == QApplication::focusWidget());
+    QVERIFY(old == 0);
+    spy.clear();
+
+    QTestKeyEvent tab(QTest::Press, Qt::Key_Tab, 0, 0);
+    QTestKeyEvent backtab(QTest::Press, Qt::Key_Backtab, 0, 0);
+    QTestMouseEvent click(QTest::MouseClick, Qt::LeftButton, 0, QPoint(5, 5), 0);
+
+    bool tabAllControls = true;
+#ifdef Q_WS_MAC
+    // Mac has two modes, one where you tab to everything, one where you can
+    // only tab to input controls, here's what we get. Determine which ones we
+    // should get.
+    QSettings appleSettings(QLatin1String("apple.com"));
+    QVariant appleValue = appleSettings.value(QLatin1String("AppleKeyboardUIMode"), 0);
+    tabAllControls = (appleValue.toInt() & 0x2);
+#endif
+
+    tab.simulate(now);
+    if (!tabAllControls) {
+        QVERIFY(spy.count() == 0);
+        QVERIFY(now == QApplication::focusWidget());
+    } else {
+        QVERIFY(spy.count() > 0);
+        old = qVariantValue<QWidget*>(spy.at(0).at(0));
+        now = qVariantValue<QWidget*>(spy.at(0).at(1));
+        QVERIFY(now == &pb2);
+        QVERIFY(now == QApplication::focusWidget());
+        QVERIFY(old == &le2);
+        spy.clear();
+    }
+
+    if (!tabAllControls) {
+        QVERIFY(spy.count() == 0);
+        QVERIFY(now == QApplication::focusWidget());
+    } else {
+        tab.simulate(now);
+        QVERIFY(spy.count() > 0);
+        old = qVariantValue<QWidget*>(spy.at(0).at(0));
+        now = qVariantValue<QWidget*>(spy.at(0).at(1));
+        QVERIFY(now == &le2);
+        QVERIFY(now == QApplication::focusWidget());
+        QVERIFY(old == &pb2);
+        spy.clear();
+    }
+
+    if (!tabAllControls) {
+        QVERIFY(spy.count() == 0);
+        QVERIFY(now == QApplication::focusWidget());
+    } else {
+        backtab.simulate(now);
+        QVERIFY(spy.count() > 0);
+        old = qVariantValue<QWidget*>(spy.at(0).at(0));
+        now = qVariantValue<QWidget*>(spy.at(0).at(1));
+        QVERIFY(now == &pb2);
+        QVERIFY(now == QApplication::focusWidget());
+        QVERIFY(old == &le2);
+        spy.clear();
+    }
+
+
+    if (!tabAllControls) {
+        QVERIFY(spy.count() == 0);
+        QVERIFY(now == QApplication::focusWidget());
+        old = &pb2;
+    } else {
+        backtab.simulate(now);
+        QVERIFY(spy.count() > 0);
+        old = qVariantValue<QWidget*>(spy.at(0).at(0));
+        now = qVariantValue<QWidget*>(spy.at(0).at(1));
+        QVERIFY(now == &le2);
+        QVERIFY(now == QApplication::focusWidget());
+        QVERIFY(old == &pb2);
+        spy.clear();
+    }
+
+    click.simulate(old);
+    if (!(pb2.focusPolicy() & Qt::ClickFocus)) {
+        QVERIFY(spy.count() == 0);
+        QVERIFY(now == QApplication::focusWidget());
+    } else {
+        QVERIFY(spy.count() > 0);
+        old = qVariantValue<QWidget*>(spy.at(0).at(0));
+        now = qVariantValue<QWidget*>(spy.at(0).at(1));
+        QVERIFY(now == &pb2);
+        QVERIFY(now == QApplication::focusWidget());
+        QVERIFY(old == &le2);
+        spy.clear();
+
+        click.simulate(old);
+        QVERIFY(spy.count() > 0);
+        old = qVariantValue<QWidget*>(spy.at(0).at(0));
+        now = qVariantValue<QWidget*>(spy.at(0).at(1));
+        QVERIFY(now == &le2);
+        QVERIFY(now == QApplication::focusWidget());
+        QVERIFY(old == &pb2);
+        spy.clear();
+    }
+
+    parent1.activateWindow();
+    QApplication::setActiveWindow(&parent1); // needs this on twm (focus follows mouse)
+    QVERIFY(spy.count() == 1 || spy.count() == 2); // one for deactivation, one for activation on Windows
+
+    //on windows, the change of focus is made in 2 steps
+    //(the focusChanged SIGNAL is emitted twice)
+    if (spy.count()==1)
+        old = qVariantValue<QWidget*>(spy.at(spy.count()-1).at(0));
+    else
+        old = qVariantValue<QWidget*>(spy.at(spy.count()-2).at(0));
+    now = qVariantValue<QWidget*>(spy.at(spy.count()-1).at(1));
+    QVERIFY(now == &le1);
+    QVERIFY(now == QApplication::focusWidget());
+    QVERIFY(old == &le2);
+    spy.clear();
+}
+
+class LineEdit : public QLineEdit
+{
+public:
+    LineEdit(QWidget *parent = 0) : QLineEdit(parent) { }
+
+protected:
+    void focusOutEvent(QFocusEvent *e) {
+        QLineEdit::focusOutEvent(e);
+        if (objectName() == "le1")
+            setStyleSheet("");
+    }
+
+    void focusInEvent(QFocusEvent *e) {
+        QLineEdit::focusInEvent(e);
+        if (objectName() == "le2")
+            setStyleSheet("");
+    }
+};
+
+void tst_QApplication::focusOut()
+{
+    int argc = 1;
+    QApplication app(argc, &argv0, QApplication::GuiServer);
+
+    // Tests the case where the style pointer changes when on focus in/out
+    // (the above is the case when the stylesheet changes)
+    QWidget w;
+    QLineEdit *le1 = new LineEdit(&w);
+    le1->setObjectName("le1");
+    le1->setStyleSheet("background: #fee");
+    le1->setFocus();
+
+    QLineEdit *le2 = new LineEdit(&w);
+    le2->setObjectName("le2");
+    le2->setStyleSheet("background: #fee");
+    le2->move(100, 100);
+    w.show();
+
+    QTest::qWait(2000);
+    le2->setFocus();
+    QTest::qWait(2000);
+}
+
+void tst_QApplication::execAfterExit()
+{
+    int argc = 1;
+    QApplication app(argc, &argv0, QApplication::GuiServer);
+    QMetaObject::invokeMethod(&app, "quit", Qt::QueuedConnection);
+    // this should be ignored, as exec() will reset the exitCode
+    QApplication::exit(1);
+    int exitCode = app.exec();
+    QCOMPARE(exitCode, 0);
+
+    // the quitNow flag should have been reset, so we can spin an
+    // eventloop after QApplication::exec() returns
+    QEventLoop eventLoop;
+    QMetaObject::invokeMethod(&eventLoop, "quit", Qt::QueuedConnection);
+    exitCode = eventLoop.exec();
+    QCOMPARE(exitCode, 0);
+}
+
+void tst_QApplication::wheelScrollLines()
+{
+    int argc = 1;
+    QApplication app(argc, &argv0, QApplication::GuiServer);
+    // If wheelScrollLines returns 0, the mose wheel will be disabled.
+    QVERIFY(app.wheelScrollLines() > 0);
+}
+
+void tst_QApplication::style()
+{
+    int argc = 1;
+
+    {
+        QApplication app(argc, &argv0, QApplication::GuiServer);
+        QPointer<QStyle> style = app.style();
+        app.setStyle(new QWindowsStyle);
+        QVERIFY(style.isNull());
+    }
+
+    QApplication app(argc, &argv0, QApplication::GuiServer);
+
+    // qApp style can never be 0
+    QVERIFY(QApplication::style() != 0);
+}
+
+void tst_QApplication::allWidgets()
+{
+    int argc = 1;
+    QApplication app(argc, &argv0, QApplication::GuiServer);
+    QWidget *w = new QWidget;
+    QVERIFY(app.allWidgets().contains(w)); // uncreate widget test
+    QVERIFY(app.allWidgets().contains(w)); // created widget test
+    delete w;
+    w = 0;
+    QVERIFY(!app.allWidgets().contains(w)); // removal test
+}
+
+void tst_QApplication::topLevelWidgets()
+{
+    int argc = 1;
+    QApplication app(argc, &argv0, QApplication::GuiServer);
+    QWidget *w = new QWidget;
+    w->show();
+#ifndef QT_NO_CLIPBOARD
+    QClipboard *clipboard = QApplication::clipboard();
+    QString originalText = clipboard->text();
+    clipboard->setText(QString("newText"));
+#endif
+    app.processEvents();
+    QVERIFY(QApplication::topLevelWidgets().contains(w));
+    QCOMPARE(QApplication::topLevelWidgets().count(), 1);
+    delete w;
+    w = 0;
+    app.processEvents();
+    QCOMPARE(QApplication::topLevelWidgets().count(), 0);
+}
+
+
+
+void tst_QApplication::setAttribute()
+{
+    int argc = 1;
+    QApplication app(argc, &argv0, QApplication::GuiServer);
+    QVERIFY(!QApplication::testAttribute(Qt::AA_ImmediateWidgetCreation));
+    QWidget  *w = new QWidget;
+    QVERIFY(!w->testAttribute(Qt::WA_WState_Created));
+    delete w;
+
+    QApplication::setAttribute(Qt::AA_ImmediateWidgetCreation);
+    QVERIFY(QApplication::testAttribute(Qt::AA_ImmediateWidgetCreation));
+    w = new QWidget;
+    QVERIFY(w->testAttribute(Qt::WA_WState_Created));
+    QWidget *w2 = new QWidget(w);
+    w2->setParent(0);
+    QVERIFY(w2->testAttribute(Qt::WA_WState_Created));
+    delete w;
+    delete w2;
+
+    QApplication::setAttribute(Qt::AA_ImmediateWidgetCreation, false);
+    QVERIFY(!QApplication::testAttribute(Qt::AA_ImmediateWidgetCreation));
+    w = new QWidget;
+    QVERIFY(!w->testAttribute(Qt::WA_WState_Created));
+    delete w;
+}
+
+void tst_QApplication::windowsCommandLine_data()
+{
+#if defined(Q_OS_WIN)
+    QTest::addColumn<QString>("args");
+    QTest::addColumn<QString>("expected");
+
+    QTest::newRow("hello world")
+        << QString("Hello \"World\"")
+        << QString("Hello \"World\"");
+    QTest::newRow("sql")
+        << QString("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PNR' AND TABLE_TYPE = 'VIEW' ORDER BY TABLE_NAME")
+        << QString("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PNR' AND TABLE_TYPE = 'VIEW' ORDER BY TABLE_NAME");
+#endif
+}
+
+void tst_QApplication::windowsCommandLine()
+{
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+    QFETCH(QString, args);
+    QFETCH(QString, expected);
+
+    QProcess testProcess;
+#if defined(QT_DEBUG)
+    testProcess.start("wincmdline/debug/wincmdline", QStringList(args));
+#else
+    testProcess.start("wincmdline/release/wincmdline", QStringList(args));
+#endif
+    QVERIFY(testProcess.waitForFinished(10000));
+    QByteArray error = testProcess.readAllStandardError();
+    QString procError(error);
+    QCOMPARE(procError, expected);
+#endif
+}
+
+class TouchEventPropagationTestWidget : public QWidget
+{
+    Q_OBJECT
+
+public:
+    bool seenTouchEvent, acceptTouchEvent, seenMouseEvent, acceptMouseEvent;
+
+    TouchEventPropagationTestWidget(QWidget *parent = 0)
+        : QWidget(parent), seenTouchEvent(false), acceptTouchEvent(false), seenMouseEvent(false), acceptMouseEvent(false)
+    { }
+
+    void reset()
+    {
+        seenTouchEvent = acceptTouchEvent = seenMouseEvent = acceptMouseEvent = false;
+    }
+
+    bool event(QEvent *event)
+    {
+        switch (event->type()) {
+        case QEvent::MouseButtonPress:
+        case QEvent::MouseMove:
+        case QEvent::MouseButtonRelease:
+            // qDebug() << objectName() << "seenMouseEvent = true";
+            seenMouseEvent = true;
+            event->setAccepted(acceptMouseEvent);
+            break;
+        case QEvent::TouchBegin:
+        case QEvent::TouchUpdate:
+        case QEvent::TouchEnd:
+            // qDebug() << objectName() << "seenTouchEvent = true";
+            seenTouchEvent = true;
+            event->setAccepted(acceptTouchEvent);
+            break;
+        default:
+            return QWidget::event(event);
+        }
+        return true;
+    }
+};
+
+void tst_QApplication::touchEventPropagation()
+{
+    int argc = 1;
+    QApplication app(argc, &argv0, QApplication::GuiServer);
+
+    QList<QTouchEvent::TouchPoint> pressedTouchPoints;
+    QTouchEvent::TouchPoint press(0);
+    press.setState(Qt::TouchPointPressed);
+    pressedTouchPoints << press;
+
+    QList<QTouchEvent::TouchPoint> releasedTouchPoints;
+    QTouchEvent::TouchPoint release(0);
+    release.setState(Qt::TouchPointReleased);
+    releasedTouchPoints << release;
+
+    {
+        // touch event behavior on a window
+        TouchEventPropagationTestWidget window;
+        window.setObjectName("1. window");
+
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
+        QVERIFY(!window.seenTouchEvent);
+        QVERIFY(!window.seenMouseEvent);
+
+        window.reset();
+        window.setAttribute(Qt::WA_AcceptTouchEvents);
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
+        QVERIFY(window.seenTouchEvent);
+        QVERIFY(!window.seenMouseEvent);
+
+        window.reset();
+        window.acceptTouchEvent = true;
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
+        QVERIFY(window.seenTouchEvent);
+        QVERIFY(!window.seenMouseEvent);
+    }
+
+    {
+        // touch event behavior on a window with a child widget
+        TouchEventPropagationTestWidget window;
+        window.setObjectName("2. window");
+        TouchEventPropagationTestWidget widget(&window);
+        widget.setObjectName("2. widget");
+
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
+        QVERIFY(!widget.seenTouchEvent);
+        QVERIFY(!widget.seenMouseEvent);
+        QVERIFY(!window.seenTouchEvent);
+        QVERIFY(!window.seenMouseEvent);
+
+        window.reset();
+        widget.reset();
+        widget.setAttribute(Qt::WA_AcceptTouchEvents);
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
+        QVERIFY(widget.seenTouchEvent);
+        QVERIFY(!widget.seenMouseEvent);
+        QVERIFY(!window.seenTouchEvent);
+        QVERIFY(!window.seenMouseEvent);
+
+        window.reset();
+        widget.reset();
+        widget.acceptMouseEvent = true;
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
+        QVERIFY(widget.seenTouchEvent);
+        QVERIFY(!widget.seenMouseEvent);
+        QVERIFY(!window.seenTouchEvent);
+        QVERIFY(!window.seenMouseEvent);
+
+        window.reset();
+        widget.reset();
+        widget.acceptTouchEvent = true;
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
+        QVERIFY(widget.seenTouchEvent);
+        QVERIFY(!widget.seenMouseEvent);
+        QVERIFY(!window.seenTouchEvent);
+        QVERIFY(!window.seenMouseEvent);
+
+        window.reset();
+        widget.reset();
+        widget.setAttribute(Qt::WA_AcceptTouchEvents, false);
+        window.setAttribute(Qt::WA_AcceptTouchEvents);
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
+        QVERIFY(!widget.seenTouchEvent);
+        QVERIFY(!widget.seenMouseEvent);
+        QVERIFY(window.seenTouchEvent);
+        QVERIFY(!window.seenMouseEvent);
+
+        window.reset();
+        widget.reset();
+        window.acceptTouchEvent = true;
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
+        QVERIFY(!widget.seenTouchEvent);
+        QVERIFY(!widget.seenMouseEvent);
+        QVERIFY(window.seenTouchEvent);
+        QVERIFY(!window.seenMouseEvent);
+
+        window.reset();
+        widget.reset();
+        widget.acceptMouseEvent = true; // doesn't matter, touch events are propagated first
+        window.acceptTouchEvent = true;
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints);
+        qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints);
+        QVERIFY(!widget.seenTouchEvent);
+        QVERIFY(!widget.seenMouseEvent);
+        QVERIFY(window.seenTouchEvent);
+        QVERIFY(!window.seenMouseEvent);
+    }
+}
+
+void tst_QApplication::symbianNoApplicationPanes()
+{
+#ifndef Q_OS_SYMBIAN
+    QSKIP("This is a Symbian only test", SkipAll);
+#else
+    QApplication::setAttribute(Qt::AA_S60DontConstructApplicationPanes);
+
+    // Run in a block so that QApplication is destroyed before resetting the attribute.
+    {
+        // Actually I wasn't able to get the forced orientation change to work properly,
+        // but I'll leave the code here for the future in case we manage to test that
+        // later. If someone knows how to force an orientation switch in an autotest, do
+        // feel free to fix this testcase.
+        int argc = 0;
+        QApplication app(argc, 0);
+        QWidget *w;
+
+        w = new QWidget;
+        w->show();
+        QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
+                ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape));
+        app.processEvents();
+        delete w;
+
+        w = new QWidget;
+        w->show();
+        QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
+                ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait));
+        app.processEvents();
+        delete w;
+
+        w = new QWidget;
+        w->showMaximized();
+        QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
+                ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape));
+        app.processEvents();
+        delete w;
+
+        w = new QWidget;
+        w->showMaximized();
+        QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
+                ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait));
+        app.processEvents();
+        delete w;
+
+        w = new QWidget;
+        w->showFullScreen();
+        QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
+                ->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape));
+        app.processEvents();
+        delete w;
+
+        w = new QWidget;
+        w->showFullScreen();
+        QT_TRAP_THROWING(static_cast<CAknAppUi *>(CCoeEnv::Static()->AppUi())
+                ->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait));
+        app.processEvents();
+        delete w;
+
+        // These will have no effect, since there is no status pane, but they shouldn't
+        // crash either.
+        w = new QWidget;
+        w->show();
+        w->setWindowTitle("Testing title");
+        app.processEvents();
+        delete w;
+
+        w = new QWidget;
+        w->show();
+        w->setWindowIcon(QIcon(QPixmap("heart.svg")));
+        app.processEvents();
+        delete w;
+
+        QDesktopWidget desktop;
+        QCOMPARE(desktop.availableGeometry(), desktop.screenGeometry());
+    }
+
+    QApplication::setAttribute(Qt::AA_S60DontConstructApplicationPanes, false);
+
+    // No other error condition. Program will crash if unsuccessful.
+#endif
+}
+
+#ifdef Q_OS_SYMBIAN
+class CBaseDummy : public CBase
+{
+public:
+    CBaseDummy(int *numDestroyed) : numDestroyed(numDestroyed)
+    {
+    }
+    ~CBaseDummy()
+    {
+        (*numDestroyed)++;
+    }
+
+private:
+    int *numDestroyed;
+};
+
+static void fakeMain(int *numDestroyed)
+{
+    // Push a few objects, just so that the cleanup stack has something to clean up.
+    CleanupStack::PushL(new (ELeave) CBaseDummy(numDestroyed));
+    int argc = 0;
+    QApplication app(argc, 0);
+    CleanupStack::PushL(new (ELeave) CBaseDummy(numDestroyed));
+
+    User::Leave(KErrGeneral); // Fake error
+}
+#endif
+
+void tst_QApplication::symbianNeedForTraps()
+{
+#ifndef Q_OS_SYMBIAN
+    QSKIP("This is a Symbian-only test", SkipAll);
+#else
+    int argc = 0;
+    QApplication app(argc, 0);
+    int numDestroyed = 0;
+
+    // This next part should not require a trap. If it does, the test will crash.
+    CleanupStack::PushL(new (ELeave) CBaseDummy(&numDestroyed));
+    CleanupStack::PopAndDestroy();
+
+    QCOMPARE(numDestroyed, 1);
+
+    // No other failure condition. The program will crash if it does not pass.
+#endif
+}
+
+void tst_QApplication::symbianLeaveThroughMain()
+{
+#ifndef Q_OS_SYMBIAN
+    QSKIP("This is a Symbian-only test", SkipAll);
+#else
+    int numDestroyed = 0;
+    TInt err;
+    TRAP(err, fakeMain(&numDestroyed));
+
+    QCOMPARE(numDestroyed, 2);
+#endif
+}
+*/
+
+//QTEST_APPLESS_MAIN(tst_QApplication)
+int main(int argc, char *argv[])
+{
+    tst_QApplication tc;
+    argv0 = argv[0];
+    return QTest::qExec(&tc, argc, argv);
+}
+
+#include "smoketest_qapplication.moc"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qt/qapplication/smoketest_qapplication.pro	Fri Jun 11 11:44:06 2010 +0100
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+SUBDIRS = test \
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qt/qapplication/test/test.pro	Fri Jun 11 11:44:06 2010 +0100
@@ -0,0 +1,15 @@
+load(qttest_p4)
+
+SOURCES += ../smoketest_qapplication.cpp
+TARGET = ../smoketest_qapplication
+
+someTest.sources = test.pro
+someTest.path = test
+DEPLOYMENT = additional deploy someTest windowIcon
+LIBS += -lcone -lavkon
+
+symbian {
+    TARGET = ../../release/smoketest_qapplication
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qt/shared/filesystem.h	Fri Jun 11 11:44:06 2010 +0100
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+// Helper functions for creating file-system hierarchies and cleaning up.
+
+#ifndef QT_TESTS_SHARED_FILESYSTEM_H_INCLUDED
+#define QT_TESTS_SHARED_FILESYSTEM_H_INCLUDED
+
+#include <QString>
+#include <QStringList>
+#include <QDir>
+#include <QFile>
+
+struct FileSystem
+{
+    ~FileSystem()
+    {
+        Q_FOREACH(QString fileName, createdFiles)
+            QFile::remove(fileName);
+
+        Q_FOREACH(QString dirName, createdDirectories)
+            currentDir.rmdir(dirName);
+    }
+
+    bool createDirectory(const QString &dirName)
+    {
+        if (currentDir.mkdir(dirName)) {
+            createdDirectories.prepend(dirName);
+            return true;
+        }
+        return false;
+    }
+
+    bool createFile(const QString &fileName)
+    {
+        QFile file(fileName);
+        if (file.open(QIODevice::WriteOnly)) {
+            createdFiles << fileName;
+            return true;
+        }
+        return false;
+    }
+
+    bool createLink(const QString &destination, const QString &linkName)
+    {
+        if (QFile::link(destination, linkName)) {
+            createdFiles << linkName;
+            return true;
+        }
+        return false;
+    }
+
+private:
+    QDir currentDir;
+
+    QStringList createdDirectories;
+    QStringList createdFiles;
+};
+
+#endif // include guard
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qt/shared/util.h	Fri Jun 11 11:44:06 2010 +0100
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+// Functions and macros that really need to be in QTestLib
+
+// Will try to wait for the condition while allowing event processing
+#define QTRY_VERIFY(__expr) \
+    do { \
+        const int __step = 50; \
+        const int __timeout = 5000; \
+        if (!(__expr)) { \
+            QTest::qWait(0); \
+        } \
+        for (int __i = 0; __i < __timeout && !(__expr); __i+=__step) { \
+            QTest::qWait(__step); \
+        } \
+        QVERIFY(__expr); \
+    } while(0)
+
+// Will try to wait for the condition while allowing event processing
+#define QTRY_COMPARE(__expr, __expected) \
+    do { \
+        const int __step = 50; \
+        const int __timeout = 5000; \
+        if ((__expr) != (__expected)) { \
+            QTest::qWait(0); \
+        } \
+        for (int __i = 0; __i < __timeout && ((__expr) != (__expected)); __i+=__step) { \
+            QTest::qWait(__step); \
+        } \
+        QCOMPARE(__expr, __expected); \
+    } while(0)
+