/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/


#include <QtTest/QtTest>
#include <QtTest/qtesttouch.h>

#include <qevent.h>
#include <qtouchdevice.h>
#include <qwidget.h>
#include <qlayout.h>
#include <qgesture.h>
#include <qgesturerecognizer.h>
#include <qgraphicsitem.h>
#include <qgraphicswidget.h>
#include <qgraphicsview.h>
#include <qmainwindow.h>

#include <qdebug.h>

static QPointF mapToGlobal(const QPointF &pt, QGraphicsItem *item, QGraphicsView *view)
{
    return view->viewport()->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;

    explicit 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:
                    emit gestureStarted(e->type(), g);
                    eventsPtr->started << g->gestureType();
                    break;
                case Qt::GestureUpdated:
                    emit gestureUpdated(e->type(), g);
                    eventsPtr->updated << g->gestureType();
                    break;
                case Qt::GestureFinished:
                    emit gestureFinished(e->type(), g);
                    eventsPtr->finished << g->gestureType();
                    break;
                case Qt::GestureCanceled:
                    emit gestureCanceled(e->type(), g);
                    eventsPtr->canceled << g->gestureType();
                    break;
                default:
                    qWarning() << "Unknown GestureState enum value:" << static_cast<int>(g->state());
                }
            }
        } else if (event->type() == CustomEvent::EventType) {
            ++customEventsReceived;
        } else {
            return QWidget::event(event);
        }
        return true;
    }

Q_SIGNALS:
    void gestureStarted(QEvent::Type, QGesture *);
    void gestureUpdated(QEvent::Type, QGesture *);
    void gestureFinished(QEvent::Type, QGesture *);
    void gestureCanceled(QEvent::Type, QGesture *);

public Q_SLOTS:
    void deleteThis() { delete this; }
};

// TODO rename to sendGestureSequence
static void sendCustomGesture(CustomEvent *event, QObject *object, QGraphicsScene *scene = 0)
{
    QPointer<QObject> receiver(object);
    for (int i = CustomGesture::SerialMaybeThreshold;
         i <= CustomGesture::SerialFinishedThreshold && receiver; ++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

private slots:
    void initTestCase();
    void cleanupTestCase();
    void customGesture();
    void autoCancelingGestures();
    void gestureOverChild();
    void multipleWidgetOnlyGestureInTree();
    void conflictingGestures();
    void conflictingGesturesInGraphicsView();
    void finishedWithoutStarted();
    void unknownGesture();
    void graphicsItemGesture();
    void graphicsView();
    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 graphicsViewParentPropagation();
    void panelPropagation();
    void panelStacksBehindParent();
#ifdef Q_OS_MACOS
    void deleteMacPanGestureRecognizerTargetWidget();
#endif
    void deleteGestureTargetWidget();
    void deleteGestureTargetItem_data();
    void deleteGestureTargetItem();
    void viewportCoordinates();
    void partialGesturePropagation();
    void testQGestureRecognizerCleanup();
    void testReuseCanceledGestures();
    void bug_13501_gesture_not_accepted();
};

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::customGesture()
{
    GestureWidget widget;
    widget.grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
    widget.show();
    QVERIFY(QTest::qWaitForWindowExposed(&widget));

    CustomEvent event;
    event.hotSpot = widget.mapToGlobal(QPoint(5,5));
    event.hasHotSpot = true;
    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
{
    Q_OBJECT
    static int InstanceCount;
public:
    GestureItem(const char *name = 0)
    {
        instanceNumber = InstanceCount++;
        if (name) {
            setObjectName(QLatin1String(name));
            setToolTip(name);
        }
        size = QRectF(0, 0, 100, 100);
        customEventsReceived = 0;
        gestureEventsReceived = 0;
        gestureOverrideEventsReceived = 0;
        events.clear();
        overrideEvents.clear();
        acceptGestureOverride = false;

        scene = 0;
    }
    ~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;
    QSet<Qt::GestureType> ignoredStartedGestures;
    QSet<Qt::GestureType> ignoredUpdatedGestures;
    QSet<Qt::GestureType> ignoredFinishedGestures;

    QRectF size;
    int instanceNumber;

    void reset()
    {
        customEventsReceived = 0;
        gestureEventsReceived = 0;
        gestureOverrideEventsReceived = 0;
        events.clear();
        overrideEvents.clear();
        ignoredGestures.clear();
        ignoredStartedGestures.clear();
        ignoredUpdatedGestures.clear();
        ignoredFinishedGestures.clear();
    }

    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));
            foreach(QGesture *g, e->gestures()) {
                switch (g->state()) {
                case Qt::GestureStarted:
                    if (ignoredStartedGestures.contains(g->gestureType()))
                        e->ignore(g);
                    break;
                case Qt::GestureUpdated:
                    if (ignoredUpdatedGestures.contains(g->gestureType()))
                        e->ignore(g);
                    break;
                case Qt::GestureFinished:
                    if (ignoredFinishedGestures.contains(g->gestureType()))
                        e->ignore(g);
                    break;
                default:
                    break;
                }
            }
        } 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();
                    emit gestureStarted(e->type(), g);
                    break;
                case Qt::GestureUpdated:
                    eventsPtr->updated << g->gestureType();
                    emit gestureUpdated(e->type(), g);
                    break;
                case Qt::GestureFinished:
                    eventsPtr->finished << g->gestureType();
                    emit gestureFinished(e->type(), g);
                    break;
                case Qt::GestureCanceled:
                    eventsPtr->canceled << g->gestureType();
                    emit gestureCanceled(e->type(), g);
                    break;
                default:
                    qWarning() << "Unknown GestureState enum value:" << static_cast<int>(g->state());
                }
            }
        } else if (event->type() == CustomEvent::EventType) {
            ++customEventsReceived;
        } else {
            return QGraphicsObject::event(event);
        }
        return true;
    }

Q_SIGNALS:
    void gestureStarted(QEvent::Type, QGesture *);
    void gestureUpdated(QEvent::Type, QGesture *);
    void gestureFinished(QEvent::Type, QGesture *);
    void gestureCanceled(QEvent::Type, QGesture *);

public:
    // some arguments for the slots below:
    QGraphicsScene *scene;

public Q_SLOTS:
    void deleteThis() { delete this; }
    void addSelfToScene(QEvent::Type eventType, QGesture *)
    {
        if (eventType == QEvent::Gesture) {
            disconnect(sender(), 0, this, SLOT(addSelfToScene(QEvent::Type,QGesture*)));
            scene->addItem(this);
        }
    }
};
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();
    QVERIFY(QTest::qWaitForWindowExposed(&view));
    view.ensureVisible(scene.sceneRect());

    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::graphicsView()
{
    QGraphicsScene scene;
    QGraphicsView view(&scene);
    view.setWindowFlags(Qt::X11BypassWindowManagerHint);

    GestureItem *item = new GestureItem("item");
    scene.addItem(item);
    item->setPos(100, 100);

    view.show();
    QVERIFY(QTest::qWaitForWindowExposed(&view));
    view.ensureVisible(scene.sceneRect());

    item->grabGesture(CustomGesture::GestureType);

    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
    static const int TotalCustomEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1;

    CustomEvent event;
    // 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);

    // change the viewport and try again
    QWidget *newViewport = new QWidget;
    view.setViewport(newViewport);

    item->reset();
    sendCustomGesture(&event, item, &scene);

    QCOMPARE(item->customEventsReceived, TotalCustomEventsCount);
    QCOMPARE(item->gestureEventsReceived, TotalGestureEventsCount);
    QCOMPARE(item->gestureOverrideEventsReceived, 0);

    // change the scene and try again
    QGraphicsScene newScene;
    item = new GestureItem("newItem");
    newScene.addItem(item);
    item->setPos(100, 100);
    view.setScene(&newScene);

    item->reset();
    // first without a gesture
    sendCustomGesture(&event, item, &newScene);

    QCOMPARE(item->customEventsReceived, TotalCustomEventsCount);
    QCOMPARE(item->gestureEventsReceived, 0);
    QCOMPARE(item->gestureOverrideEventsReceived, 0);

    // then grab the gesture and try again
    item->reset();
    item->grabGesture(CustomGesture::GestureType);
    sendCustomGesture(&event, item, &newScene);

    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();
    QVERIFY(QTest::qWaitForWindowExposed(&view));
    view.ensureVisible(scene.sceneRect());

    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();
    QVERIFY(QTest::qWaitForWindowExposed(&view));
    view.ensureVisible(scene.sceneRect());

    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();
    QVERIFY(QTest::qWaitForWindowExposed(&view));
    view.ensureVisible(scene.sceneRect());

    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
    QVERIFY(QTest::qWaitForWindowExposed(&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());
    QCOMPARE(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);
    //We changed the deletion of Gestures to lazy during QT-4022, so we can't ensure the QGesture is deleted until now
    QVERIFY(!customGestureB.isNull());

    a->gestures.clear();
    a->reset();
    // send again to 'b' and make sure a never gets it.
    sendCustomGesture(&event, b);
    //After all Gestures are processed in the QGestureManager, we can ensure the QGesture is now deleted
    QVERIFY(customGestureA.isNull());
    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), badGestureEvents(0) { }

        bool event(QEvent *event)
        {
            if (event->type() == QEvent::Gesture) {
                QGestureEvent *ge = static_cast<QGestureEvent*>(event);
                if (ge->gestures().count() != 1)
                    ++badGestureEvents;   // event should contain exactly one gesture
                ge->gestures().first()->setGestureCancelPolicy(QGesture::CancelAllInContext);
            }
            return GestureWidget::event(event);
        }

        int badGestureEvents;
    };

    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();
    QVERIFY(QTest::qWaitForWindowExposed(&parent));

    /*
      An event is sent 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);
    QCOMPARE(parent.badGestureEvents, 0);
}

void tst_Gestures::autoCancelGestures2()
{
    class MockItem : public GestureItem {
      public:
        MockItem(const char *name) : GestureItem(name), badGestureEvents(0) { }

        bool event(QEvent *event) {
            if (event->type() == QEvent::Gesture) {
                QGestureEvent *ge = static_cast<QGestureEvent*>(event);
                if (ge->gestures().count() != 1)
                    ++badGestureEvents;   // event should contain exactly one gesture
                ge->gestures().first()->setGestureCancelPolicy(QGesture::CancelAllInContext);
            }
            return GestureItem::event(event);
        }

        int badGestureEvents;
    };

    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);
    parent->grabGesture(CustomGesture::GestureType);
    child->grabGesture(secondGesture);

    view.show();
    QVERIFY(QTest::qWaitForWindowExposed(&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);
    QCOMPARE(parent->badGestureEvents, 0);
}

void tst_Gestures::graphicsViewParentPropagation()
{
    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(0, 0);
    item1->setZValue(5);

    GestureItem *item1_c1 = new GestureItem("item1_child1");
    item1_c1->setParentItem(item1);
    item1_c1->setPos(0, 0);

    GestureItem *item1_c1_c1 = new GestureItem("item1_child1_child1");
    item1_c1_c1->setParentItem(item1_c1);
    item1_c1_c1->setPos(0, 0);

    view.show();
    QVERIFY(QTest::qWaitForWindowExposed(&view));
    view.ensureVisible(scene.sceneRect());

    item0->grabGesture(CustomGesture::GestureType, Qt::ReceivePartialGestures | Qt::IgnoredGesturesPropagateToParent);
    item1->grabGesture(CustomGesture::GestureType, Qt::ReceivePartialGestures | Qt::IgnoredGesturesPropagateToParent);
    item1_c1->grabGesture(CustomGesture::GestureType, Qt::IgnoredGesturesPropagateToParent);
    item1_c1_c1->grabGesture(CustomGesture::GestureType, Qt::ReceivePartialGestures | Qt::IgnoredGesturesPropagateToParent);

    item0->ignoredUpdatedGestures << CustomGesture::GestureType;
    item0->ignoredFinishedGestures << CustomGesture::GestureType;
    item1->ignoredUpdatedGestures << CustomGesture::GestureType;
    item1->ignoredFinishedGestures << CustomGesture::GestureType;
    item1_c1->ignoredUpdatedGestures << CustomGesture::GestureType;
    item1_c1->ignoredFinishedGestures << CustomGesture::GestureType;
    item1_c1_c1->ignoredUpdatedGestures << CustomGesture::GestureType;
    item1_c1_c1->ignoredFinishedGestures << CustomGesture::GestureType;

    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;

    CustomEvent event;
    event.hotSpot = mapToGlobal(QPointF(10, 10), item1_c1, &view);
    event.hasHotSpot = true;
    sendCustomGesture(&event, item0, &scene);

    QCOMPARE(item1_c1_c1->gestureEventsReceived, TotalGestureEventsCount);
    QCOMPARE(item1_c1_c1->gestureOverrideEventsReceived, 1);
    QCOMPARE(item1_c1->gestureEventsReceived, TotalGestureEventsCount-1);
    QCOMPARE(item1_c1->gestureOverrideEventsReceived, 1);
    QCOMPARE(item1->gestureEventsReceived, TotalGestureEventsCount-1);
    QCOMPARE(item1->gestureOverrideEventsReceived, 1);
    QCOMPARE(item0->gestureEventsReceived, 0);
    QCOMPARE(item0->gestureOverrideEventsReceived, 1);
}

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();
    QVERIFY(QTest::qWaitForWindowExposed(&view));
    view.ensureVisible(scene.sceneRect());

    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();
    QVERIFY(QTest::qWaitForWindowExposed(&view));
    view.ensureVisible(scene.sceneRect());

    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);
}

#ifdef Q_OS_MACOS
void tst_Gestures::deleteMacPanGestureRecognizerTargetWidget()
{
    QWidget window;
    window.resize(400,400);
    QGraphicsScene scene;
    QGraphicsView *view = new QGraphicsView(&scene, &window);
    view->resize(400, 400);
    window.show();

    QVERIFY(QTest::qWaitForWindowExposed(&window));
    QTouchDevice *device = QTest::createTouchDevice();
    // QMacOSPenGestureRecognizer will start a timer on a touch press event
    QTest::touchEvent(&window, device).press(1, QPoint(100, 100), &window);
    delete view;

    // wait until after that the QMacOSPenGestureRecognizer timer (300ms) is triggered.
    // This is needed so that the whole test does not finish before the timer triggers
    // and to make sure it crashes while executing *this* function. (otherwise it might give the
    // impression that some of the subsequent test function caused the crash...)

    QTest::qWait(400);  // DO NOT CRASH while waiting
}
#endif

void tst_Gestures::deleteGestureTargetWidget()
{
}

void tst_Gestures::deleteGestureTargetItem_data()
{
    QTest::addColumn<bool>("propagateUpdateGesture");
    QTest::addColumn<QString>("emitter");
    QTest::addColumn<QString>("receiver");
    QTest::addColumn<QByteArray>("signalName");
    QTest::addColumn<QByteArray>("slotName");

    QByteArray gestureUpdated = SIGNAL(gestureUpdated(QEvent::Type,QGesture*));
    QByteArray gestureFinished = SIGNAL(gestureFinished(QEvent::Type,QGesture*));
    QByteArray deleteThis = SLOT(deleteThis());
    QByteArray deleteLater = SLOT(deleteLater());

    QTest::newRow("delete1")
            << false << "item1" << "item1" << gestureUpdated << deleteThis;
    QTest::newRow("delete2")
            << false << "item2" << "item2" << gestureUpdated << deleteThis;
    QTest::newRow("delete3")
            << false << "item1" << "item2" << gestureUpdated << deleteThis;

    QTest::newRow("deleteLater1")
            << false << "item1" << "item1" << gestureUpdated << deleteLater;
    QTest::newRow("deleteLater2")
            << false << "item2" << "item2" << gestureUpdated << deleteLater;
    QTest::newRow("deleteLater3")
            << false << "item1" << "item2" << gestureUpdated << deleteLater;
    QTest::newRow("deleteLater4")
            << false << "item2" << "item1" << gestureUpdated << deleteLater;

    QTest::newRow("delete-self-and-propagate")
            << true << "item2" << "item2" << gestureUpdated << deleteThis;
    QTest::newRow("deleteLater-self-and-propagate")
            << true << "item2" << "item2" << gestureUpdated << deleteLater;
    QTest::newRow("propagate-to-deletedLater")
            << true << "item2" << "item1" << gestureUpdated << deleteLater;
}

void tst_Gestures::deleteGestureTargetItem()
{
    QFETCH(bool, propagateUpdateGesture);
    QFETCH(QString, emitter);
    QFETCH(QString, receiver);
    QFETCH(QByteArray, signalName);
    QFETCH(QByteArray, slotName);

    QGraphicsScene scene;
    QGraphicsView view(&scene);
    view.setWindowFlags(Qt::X11BypassWindowManagerHint);

    GestureItem *item1 = new GestureItem("item1");
    item1->grabGesture(CustomGesture::GestureType);
    item1->setZValue(2);
    scene.addItem(item1);

    GestureItem *item2 = new GestureItem("item2");
    item2->grabGesture(CustomGesture::GestureType);
    item2->setZValue(5);
    scene.addItem(item2);

    QMap<QString, GestureItem *> items;
    items.insert(item1->objectName(), item1);
    items.insert(item2->objectName(), item2);

    view.show();
    QVERIFY(QTest::qWaitForWindowExposed(&view));
    view.ensureVisible(scene.sceneRect());

    if (propagateUpdateGesture)
        item2->ignoredUpdatedGestures << CustomGesture::GestureType;
    connect(items.value(emitter, 0), signalName, items.value(receiver, 0), slotName);

    // some debug output to see the current test data tag, so if we crash
    // we know which one caused the crash.
    qDebug() << "<-- testing";

    CustomEvent event;
    event.hotSpot = mapToGlobal(QPointF(5, 5), item2, &view);
    event.hasHotSpot = true;
    sendCustomGesture(&event, item1, &scene);
}

class GraphicsView : public QGraphicsView
{
public:
    GraphicsView(QGraphicsScene *scene, QWidget *parent = 0)
        : QGraphicsView(scene, parent)
    {
    }

    using QGraphicsView::setViewportMargins;
};

// just making sure that even if the graphicsview has margins hotspot still
// works properly. It should use viewport for converting global coordinates to
// scene coordinates.
void tst_Gestures::viewportCoordinates()
{
    QGraphicsScene scene;
    GraphicsView view(&scene);
    view.setViewportMargins(10,20,15,25);
    view.setWindowFlags(Qt::X11BypassWindowManagerHint);

    GestureItem *item1 = new GestureItem("item1");
    item1->grabGesture(CustomGesture::GestureType);
    item1->size = QRectF(0, 0, 3, 3);
    item1->setZValue(2);
    scene.addItem(item1);

    view.show();
    QVERIFY(QTest::qWaitForWindowExposed(&view));
    view.ensureVisible(scene.sceneRect());

    CustomEvent event;
    event.hotSpot = mapToGlobal(item1->boundingRect().center(), item1, &view);
    event.hasHotSpot = true;
    sendCustomGesture(&event, item1, &scene);
    QVERIFY(item1->gestureEventsReceived != 0);
}

void tst_Gestures::partialGesturePropagation()
{
    QGraphicsScene scene;
    QGraphicsView view(&scene);
    view.setWindowFlags(Qt::X11BypassWindowManagerHint);

    GestureItem *item1 = new GestureItem("item1");
    item1->grabGesture(CustomGesture::GestureType);
    item1->setZValue(8);
    scene.addItem(item1);

    GestureItem *item2 = new GestureItem("item2[partial]");
    item2->grabGesture(CustomGesture::GestureType, Qt::ReceivePartialGestures);
    item2->setZValue(6);
    scene.addItem(item2);

    GestureItem *item3 = new GestureItem("item3");
    item3->grabGesture(CustomGesture::GestureType);
    item3->setZValue(4);
    scene.addItem(item3);

    GestureItem *item4 = new GestureItem("item4[partial]");
    item4->grabGesture(CustomGesture::GestureType, Qt::ReceivePartialGestures);
    item4->setZValue(2);
    scene.addItem(item4);

    view.show();
    QVERIFY(QTest::qWaitForWindowExposed(&view));
    view.ensureVisible(scene.sceneRect());

    item1->ignoredUpdatedGestures << CustomGesture::GestureType;

    CustomEvent event;
    event.hotSpot = mapToGlobal(QPointF(5, 5), item1, &view);
    event.hasHotSpot = true;
    sendCustomGesture(&event, item1, &scene);

    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;

    QCOMPARE(item1->gestureOverrideEventsReceived, 1);
    QCOMPARE(item2->gestureOverrideEventsReceived, 1);
    QCOMPARE(item3->gestureOverrideEventsReceived, 1);
    QCOMPARE(item4->gestureOverrideEventsReceived, 1);

    QCOMPARE(item1->gestureEventsReceived, TotalGestureEventsCount);
    QCOMPARE(item2->gestureEventsReceived, TotalGestureEventsCount-2); // except for started and finished
    QCOMPARE(item3->gestureEventsReceived, 0);
    QCOMPARE(item4->gestureEventsReceived, 0);
}

class WinNativePan : public QPanGesture {
public:
    WinNativePan() {}
};

class Pan : public QPanGesture {
public:
    Pan() {}
};

class CustomPan : public QPanGesture {
public:
    CustomPan() {}
};

// Recognizer for active gesture triggers on mouse press
class PanRecognizer : public QGestureRecognizer {
public:
    enum PanType { Platform, Default, Custom };

    PanRecognizer(int id) : m_id(id) {}
    QGesture *create(QObject *) {
        switch(m_id) {
        case Platform: return new WinNativePan();
        case Default:  return new Pan();
        default:       return new CustomPan();
        }
    }

    Result recognize(QGesture *, QObject *, QEvent *) { return QGestureRecognizer::Ignore; }

    const int m_id;
};

void tst_Gestures::testQGestureRecognizerCleanup()
{
    // Clean first the current recognizers in QGManager
    QGestureRecognizer::unregisterRecognizer(Qt::PanGesture);

    // v-- Qt singleton QGManager initialization

    // Mimic QGestureManager: register both default and "platform" recognizers
    // (this is done in windows when QT_NO_NATIVE_GESTURES is not defined)
    PanRecognizer *def = new PanRecognizer(PanRecognizer::Default);
    QGestureRecognizer::registerRecognizer(def);
    PanRecognizer *plt = new PanRecognizer(PanRecognizer::Platform);
    QGestureRecognizer::registerRecognizer(plt);
    qDebug () << "register: default =" << def << "; platform =" << plt;

    // ^-- Qt singleton QGManager initialization

    // Here, application code would start

    // Create QGV (has a QAScrollArea, which uses Qt::PanGesture)
    QMainWindow    *w = new QMainWindow;
    QGraphicsView  *v = new QGraphicsView();
    w->setCentralWidget(v);

    // Unregister Qt recognizers
    QGestureRecognizer::unregisterRecognizer(Qt::PanGesture);

    // Register a custom Pan recognizer
    //QGestureRecognizer::registerRecognizer(new PanRecognizer(PanRecognizer::Custom));

    w->show();
    QVERIFY(QTest::qWaitForWindowExposed(w));
    delete w;
}

class ReuseCanceledGesturesRecognizer : public QGestureRecognizer
{
public:
    enum Type {
        RmbAndCancelAllType,
        LmbType
    };

    ReuseCanceledGesturesRecognizer(Type type) : m_type(type) {}

    QGesture *create(QObject *) {
        QGesture *g = new QGesture;
        return g;
    }

    Result recognize(QGesture *gesture, QObject *, QEvent *event) {
        QMouseEvent *me = static_cast<QMouseEvent *>(event);
        Qt::MouseButton mouseButton(m_type == LmbType ? Qt::LeftButton : Qt::RightButton);

        switch(event->type()) {
        case QEvent::MouseButtonPress:
            if (me->button() == mouseButton && gesture->state() == Qt::NoGesture) {
                gesture->setHotSpot(QPointF(me->globalPos()));
                if (m_type == RmbAndCancelAllType)
                    gesture->setGestureCancelPolicy(QGesture::CancelAllInContext);
                return QGestureRecognizer::TriggerGesture;
            }
            break;
        case QEvent::MouseButtonRelease:
            if (me->button() == mouseButton && gesture->state() > Qt::NoGesture)
                return QGestureRecognizer::FinishGesture;
        default:
            break;
        }
        return QGestureRecognizer::Ignore;
    }
private:
    Type m_type;
};

class ReuseCanceledGesturesWidget : public QGraphicsWidget
{
  public:
    ReuseCanceledGesturesWidget(Qt::GestureType gestureType = Qt::TapGesture, QGraphicsItem *parent = 0)
        : QGraphicsWidget(parent),
        m_gestureType(gestureType),
        m_started(0), m_updated(0), m_canceled(0), m_finished(0)
    {
    }

    bool event(QEvent *event) {
        if (event->type() == QEvent::Gesture) {
            QGesture *gesture = static_cast<QGestureEvent*>(event)->gesture(m_gestureType);
            if (gesture) {
                switch(gesture->state()) {
                case Qt::GestureStarted: m_started++; break;
                case Qt::GestureUpdated: m_updated++; break;
                case Qt::GestureFinished: m_finished++; break;
                case Qt::GestureCanceled: m_canceled++; break;
                default: break;
                }
            }
            return true;
        }
        if (event->type() == QEvent::GraphicsSceneMousePress) {
            return true;
        }
        return QGraphicsWidget::event(event);
    }

    int started() { return m_started; }
    int updated() { return m_updated; }
    int finished() { return m_finished; }
    int canceled() { return m_canceled; }

  private:
    Qt::GestureType m_gestureType;
    int m_started;
    int m_updated;
    int m_canceled;
    int m_finished;
};

void tst_Gestures::testReuseCanceledGestures()
{
    Qt::GestureType cancellingGestureTypeId = QGestureRecognizer::registerRecognizer(
            new ReuseCanceledGesturesRecognizer(ReuseCanceledGesturesRecognizer::RmbAndCancelAllType));
    Qt::GestureType tapGestureTypeId = QGestureRecognizer::registerRecognizer(
            new ReuseCanceledGesturesRecognizer(ReuseCanceledGesturesRecognizer::LmbType));

    QMainWindow mw;
    mw.setWindowFlags(Qt::X11BypassWindowManagerHint);
    QGraphicsView *gv = new QGraphicsView(&mw);
    QGraphicsScene *scene = new QGraphicsScene;

    gv->setScene(scene);
    scene->setSceneRect(0,0,100,100);

    // Create container and add to the scene
    ReuseCanceledGesturesWidget *container = new ReuseCanceledGesturesWidget;
    container->grabGesture(cancellingGestureTypeId); // << container grabs canceling gesture

    // Create widget and add to the scene
    ReuseCanceledGesturesWidget *target = new ReuseCanceledGesturesWidget(tapGestureTypeId, container);
    target->grabGesture(tapGestureTypeId);

    container->setGeometry(scene->sceneRect());

    scene->addItem(container);

    mw.setCentralWidget(gv);

    // Viewport needs to grab all gestures that widgets in scene grab
    gv->viewport()->grabGesture(cancellingGestureTypeId);
    gv->viewport()->grabGesture(tapGestureTypeId);

    mw.show();
    QVERIFY(QTest::qWaitForWindowExposed(&mw));

    QPoint targetPos(gv->mapFromScene(target->mapToScene(target->rect().center())));
    targetPos = gv->viewport()->mapFromParent(targetPos);

    // "Tap" starts on child widget
    QTest::mousePress(gv->viewport(), Qt::LeftButton, 0, targetPos);
    QCOMPARE(target->started(),  1);
    QCOMPARE(target->updated(),  0);
    QCOMPARE(target->finished(), 0);
    QCOMPARE(target->canceled(), 0);

    // Canceling gesture starts on parent
    QTest::mousePress(gv->viewport(), Qt::RightButton, 0, targetPos);
    QCOMPARE(target->started(),  1);
    QCOMPARE(target->updated(),  0);
    QCOMPARE(target->finished(), 0);
    QCOMPARE(target->canceled(), 1); // <- child canceled

    // Canceling gesture ends
    QTest::mouseRelease(gv->viewport(), Qt::RightButton, 0, targetPos);
    QCOMPARE(target->started(),  1);
    QCOMPARE(target->updated(),  0);
    QCOMPARE(target->finished(), 0);
    QCOMPARE(target->canceled(), 1);

    // Tap would end if not canceled
    QTest::mouseRelease(gv->viewport(), Qt::LeftButton, 0, targetPos);
    QCOMPARE(target->started(),  1);
    QCOMPARE(target->updated(),  0);
    QCOMPARE(target->finished(), 0);
    QCOMPARE(target->canceled(), 1);

    // New "Tap" starts
    QTest::mousePress(gv->viewport(), Qt::LeftButton, 0, targetPos);
    QCOMPARE(target->started(),  2);
    QCOMPARE(target->updated(),  0);
    QCOMPARE(target->finished(), 0);
    QCOMPARE(target->canceled(), 1);

    QTest::mouseRelease(gv->viewport(), Qt::LeftButton, 0, targetPos);
    QCOMPARE(target->started(),  2);
    QCOMPARE(target->updated(),  0);
    QCOMPARE(target->finished(), 1);
    QCOMPARE(target->canceled(), 1);
}

void tst_Gestures::conflictingGesturesInGraphicsView()
{
    QGraphicsScene scene;
    GraphicsView view(&scene);
    view.setWindowFlags(Qt::X11BypassWindowManagerHint);

    GestureItem *item1 = new GestureItem("item1");
    item1->grabGesture(CustomGesture::GestureType);
    item1->size = QRectF(0, 0, 100, 100);
    item1->setZValue(2);
    scene.addItem(item1);

    GestureItem *item2 = new GestureItem("item2");
    item2->grabGesture(CustomGesture::GestureType);
    item2->size = QRectF(0, 0, 100, 100);
    item2->setZValue(5);
    scene.addItem(item2);

    view.show();
    QVERIFY(QTest::qWaitForWindowExposed(&view));
    view.ensureVisible(scene.sceneRect());

    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;

    CustomEvent event;

    // nobody accepts override
    item1->acceptGestureOverride = false;
    item2->acceptGestureOverride = false;
    event.hotSpot = mapToGlobal(item2->boundingRect().center(), item2, &view);
    event.hasHotSpot = true;
    sendCustomGesture(&event, item2, &scene);
    QCOMPARE(item2->gestureOverrideEventsReceived, 1);
    QCOMPARE(item2->gestureEventsReceived, TotalGestureEventsCount);
    QCOMPARE(item1->gestureOverrideEventsReceived, 1);
    QCOMPARE(item1->gestureEventsReceived, 0);

    item1->reset(); item2->reset();

    // the original target accepts override
    item1->acceptGestureOverride = false;
    item2->acceptGestureOverride = true;
    event.hotSpot = mapToGlobal(item2->boundingRect().center(), item2, &view);
    event.hasHotSpot = true;
    sendCustomGesture(&event, item2, &scene);
    QCOMPARE(item2->gestureOverrideEventsReceived, 1);
    QCOMPARE(item2->gestureEventsReceived, TotalGestureEventsCount);
    QCOMPARE(item1->gestureOverrideEventsReceived, 0);
    QCOMPARE(item1->gestureEventsReceived, 0);

    item1->reset(); item2->reset();

    // the item behind accepts override
    item1->acceptGestureOverride = true;
    item2->acceptGestureOverride = false;
    event.hotSpot = mapToGlobal(item2->boundingRect().center(), item2, &view);
    event.hasHotSpot = true;
    sendCustomGesture(&event, item2, &scene);

    QCOMPARE(item2->gestureOverrideEventsReceived, 1);
    QCOMPARE(item2->gestureEventsReceived, 0);
    QCOMPARE(item1->gestureOverrideEventsReceived, 1);
    QCOMPARE(item1->gestureEventsReceived, TotalGestureEventsCount);
}

class NoConsumeWidgetBug13501 :public QWidget
{
    Q_OBJECT
protected:
    bool event(QEvent *e) {
        if(e->type() == QEvent::Gesture) {
            return false;
        }
        return QWidget::event(e);
    }
};

void tst_Gestures::bug_13501_gesture_not_accepted()
{
    // Create a gesture event that is not accepted by any widget
    // make sure this does not lead to an assert in QGestureManager
    NoConsumeWidgetBug13501 w;
    w.grabGesture(Qt::TapGesture);
    w.show();
    QVERIFY(QTest::qWaitForWindowExposed(&w));
    //QTest::mousePress(&ignoreEvent, Qt::LeftButton);
    QTouchDevice *device = QTest::createTouchDevice();
    QTest::touchEvent(&w, device).press(0, QPoint(10, 10), &w);
}

QTEST_MAIN(tst_Gestures)
#include "tst_gestures.moc"
