Fixes warnings about unused variables
[profile/ivi/qtbase.git] / src / gui / util / qflickgesture.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qgesture.h"
43 #include "qapplication.h"
44 #include "qevent.h"
45 #include "qwidget.h"
46 #include "qgraphicsitem.h"
47 #include "qgraphicsscene.h"
48 #include "qgraphicssceneevent.h"
49 #include "qgraphicsview.h"
50 #include "qscroller.h"
51 #include "private/qevent_p.h"
52 #include "private/qflickgesture_p.h"
53 #include "qdebug.h"
54
55 #ifndef QT_NO_GESTURES
56
57 QT_BEGIN_NAMESPACE
58
59 //#define QFLICKGESTURE_DEBUG
60
61 #ifdef QFLICKGESTURE_DEBUG
62 #  define qFGDebug  qDebug
63 #else
64 #  define qFGDebug  while (false) qDebug
65 #endif
66
67 extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
68
69 static QMouseEvent *copyMouseEvent(QEvent *e)
70 {
71     switch (e->type()) {
72     case QEvent::MouseButtonPress:
73     case QEvent::MouseButtonRelease:
74     case QEvent::MouseMove: {
75         QMouseEvent *me = static_cast<QMouseEvent *>(e);
76         return new QMouseEvent(me->type(), QPoint(0, 0), me->globalPos(), me->button(), me->buttons(), me->modifiers());
77     }
78 #ifndef QT_NO_GRAPHICSVIEW
79     case QEvent::GraphicsSceneMousePress:
80     case QEvent::GraphicsSceneMouseRelease:
81     case QEvent::GraphicsSceneMouseMove: {
82         QGraphicsSceneMouseEvent *me = static_cast<QGraphicsSceneMouseEvent *>(e);
83 #if 1
84         QEvent::Type met = me->type() == QEvent::GraphicsSceneMousePress ? QEvent::MouseButtonPress :
85                            (me->type() == QEvent::GraphicsSceneMouseRelease ? QEvent::MouseButtonRelease : QEvent::MouseMove);
86         return new QMouseEvent(met, QPoint(0, 0), me->screenPos(), me->button(), me->buttons(), me->modifiers());
87 #else
88         QGraphicsSceneMouseEvent *copy = new QGraphicsSceneMouseEvent(me->type());
89         copy->setPos(me->pos());
90         copy->setScenePos(me->scenePos());
91         copy->setScreenPos(me->screenPos());
92         for (int i = 0x1; i <= 0x10; i <<= 1) {
93             Qt::MouseButton button = Qt::MouseButton(i);
94             copy->setButtonDownPos(button, me->buttonDownPos(button));
95             copy->setButtonDownScenePos(button, me->buttonDownScenePos(button));
96             copy->setButtonDownScreenPos(button, me->buttonDownScreenPos(button));
97         }
98         copy->setLastPos(me->lastPos());
99         copy->setLastScenePos(me->lastScenePos());
100         copy->setLastScreenPos(me->lastScreenPos());
101         copy->setButtons(me->buttons());
102         copy->setButton(me->button());
103         copy->setModifiers(me->modifiers());
104         return copy;
105 #endif
106     }
107 #endif // QT_NO_GRAPHICSVIEW
108     default:
109         return 0;
110     }
111 }
112
113 class PressDelayHandler : public QObject
114 {
115 private:
116     PressDelayHandler(QObject *parent = 0)
117         : QObject(parent)
118         , pressDelayTimer(0)
119         , sendingEvent(false)
120         , mouseButton(Qt::NoButton)
121         , mouseTarget(0)
122     { }
123
124     static PressDelayHandler *inst;
125
126 public:
127     enum {
128         UngrabMouseBefore = 1,
129         RegrabMouseAfterwards = 2
130     };
131
132     static PressDelayHandler *instance()
133     {
134         static PressDelayHandler *inst = 0;
135         if (!inst)
136             inst = new PressDelayHandler(QCoreApplication::instance());
137         return inst;
138     }
139
140     bool shouldEventBeIgnored(QEvent *) const
141     {
142         return sendingEvent;
143     }
144
145     bool isDelaying() const
146     {
147         return !pressDelayEvent.isNull();
148     }
149
150     void pressed(QEvent *e, int delay)
151     {
152         if (!pressDelayEvent) {
153             pressDelayEvent.reset(copyMouseEvent(e));
154             pressDelayTimer = startTimer(delay);
155             mouseTarget = QApplication::widgetAt(pressDelayEvent->globalPos());
156             mouseButton = pressDelayEvent->button();
157             qFGDebug() << "QFG: consuming/delaying mouse press";
158         } else {
159             qFGDebug() << "QFG: NOT consuming/delaying mouse press";
160         }
161         e->setAccepted(true);
162     }
163
164     bool released(QEvent *e, bool scrollerWasActive, bool scrollerIsActive)
165     {
166         // consume this event if the scroller was or is active
167         bool result = scrollerWasActive || scrollerIsActive;
168
169         // stop the timer
170         if (pressDelayTimer) {
171             killTimer(pressDelayTimer);
172             pressDelayTimer = 0;
173         }
174         // we still haven't even sent the press, so do it now
175         if (pressDelayEvent && mouseTarget && !scrollerIsActive) {
176             QScopedPointer<QMouseEvent> releaseEvent(copyMouseEvent(e));
177
178             qFGDebug() << "QFG: re-sending mouse press (due to release) for " << mouseTarget;
179             sendMouseEvent(pressDelayEvent.data(), UngrabMouseBefore);
180
181             qFGDebug() << "QFG: faking mouse release (due to release) for " << mouseTarget;
182             sendMouseEvent(releaseEvent.data());
183
184             result = true; // consume this event
185         } else if (mouseTarget && scrollerIsActive) {
186             // we grabbed the mouse expicitly when the scroller became active, so undo that now
187             sendMouseEvent(0, UngrabMouseBefore);
188         }
189         pressDelayEvent.reset(0);
190         mouseTarget = 0;
191         return result;
192     }
193
194     void scrollerWasIntercepted()
195     {
196         qFGDebug() << "QFG: deleting delayed mouse press, since scroller was only intercepted";
197         if (pressDelayEvent) {
198             // we still haven't even sent the press, so just throw it away now
199             if (pressDelayTimer) {
200                 killTimer(pressDelayTimer);
201                 pressDelayTimer = 0;
202             }
203             pressDelayEvent.reset(0);
204         }
205         mouseTarget = 0;
206     }
207
208     void scrollerBecameActive()
209     {
210         if (pressDelayEvent) {
211             // we still haven't even sent the press, so just throw it away now
212             qFGDebug() << "QFG: deleting delayed mouse press, since scroller is active now";
213             if (pressDelayTimer) {
214                 killTimer(pressDelayTimer);
215                 pressDelayTimer = 0;
216             }
217             pressDelayEvent.reset(0);
218             mouseTarget = 0;
219         } else if (mouseTarget) {
220             // we did send a press, so we need to fake a release now
221
222             // release all pressed mouse buttons
223             /* Qt::MouseButtons mouseButtons = QApplication::mouseButtons();
224             for (int i = 0; i < 32; ++i) {
225                 if (mouseButtons & (1 << i)) {
226                     Qt::MouseButton b = static_cast<Qt::MouseButton>(1 << i);
227                     mouseButtons &= ~b;
228                     QPoint farFarAway(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX);
229
230                     qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget;
231                     QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway,
232                                    b, mouseButtons, QApplication::keyboardModifiers());
233                     sendMouseEvent(&re);
234                 }
235             }*/
236
237             QPoint farFarAway(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX);
238
239             qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget;
240             QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway,
241                            mouseButton, QApplication::mouseButtons() & ~mouseButton,
242                            QApplication::keyboardModifiers());
243             sendMouseEvent(&re, RegrabMouseAfterwards);
244             // don't clear the mouseTarget just yet, since we need to explicitly ungrab the mouse on release!
245         }
246     }
247
248 protected:
249     void timerEvent(QTimerEvent *e)
250     {
251         if (e->timerId() == pressDelayTimer) {
252             if (pressDelayEvent && mouseTarget) {
253                 qFGDebug() << "QFG: timer event: re-sending mouse press to " << mouseTarget;
254                 sendMouseEvent(pressDelayEvent.data(), UngrabMouseBefore);
255             }
256             pressDelayEvent.reset(0);
257
258             if (pressDelayTimer) {
259                 killTimer(pressDelayTimer);
260                 pressDelayTimer = 0;
261             }
262         }
263     }
264
265     void sendMouseEvent(QMouseEvent *me, int flags = 0)
266     {
267         if (mouseTarget) {
268             sendingEvent = true;
269
270 #ifndef QT_NO_GRAPHICSVIEW
271             QGraphicsItem *grabber = 0;
272             if (mouseTarget->parentWidget()) {
273                 if (QGraphicsView *gv = qobject_cast<QGraphicsView *>(mouseTarget->parentWidget())) {
274                     if (gv->scene())
275                         grabber = gv->scene()->mouseGrabberItem();
276                 }
277             }
278
279             if (grabber && (flags & UngrabMouseBefore)) {
280                 // GraphicsView Mouse Handling Workaround #1:
281                 // we need to ungrab the mouse before re-sending the press,
282                 // since the scene had already set the mouse grabber to the
283                 // original (and consumed) event's receiver
284                 qFGDebug() << "QFG: ungrabbing" << grabber;
285                 grabber->ungrabMouse();
286             }
287 #endif // QT_NO_GRAPHICSVIEW
288
289             if (me) {
290                 QMouseEvent copy(me->type(), mouseTarget->mapFromGlobal(me->globalPos()), me->globalPos(), me->button(), me->buttons(), me->modifiers());
291                 qt_sendSpontaneousEvent(mouseTarget, &copy);
292             }
293
294 #ifndef QT_NO_GRAPHICSVIEW
295             if (grabber && (flags & RegrabMouseAfterwards)) {
296                 // GraphicsView Mouse Handling Workaround #2:
297                 // we need to re-grab the mouse after sending a faked mouse
298                 // release, since we still need the mouse moves for the gesture
299                 // (the scene will clear the item's mouse grabber status on
300                 // release).
301                 qFGDebug() << "QFG: re-grabbing" << grabber;
302                 grabber->grabMouse();
303             }
304 #endif
305             sendingEvent = false;
306         }
307     }
308
309
310 private:
311     int pressDelayTimer;
312     QScopedPointer<QMouseEvent> pressDelayEvent;
313     bool sendingEvent;
314     Qt::MouseButton mouseButton;
315     QPointer<QWidget> mouseTarget;
316 };
317
318
319 /*!
320     \internal
321     \class QFlickGesture
322     \since 4.8
323     \brief The QFlickGesture class describes a flicking gesture made by the user.
324     \ingroup gestures
325     The QFlickGesture is more complex than the QPanGesture that uses QScroller and QScrollerProperties
326     to decide if it is triggered.
327     This gesture is reacting on touch event as compared to the QMouseFlickGesture.
328
329     \sa {Gestures Programming}, QScroller, QScrollerProperties, QMouseFlickGesture
330 */
331
332 /*!
333     \internal
334 */
335 QFlickGesture::QFlickGesture(QObject *receiver, Qt::MouseButton button, QObject *parent)
336     : QGesture(*new QFlickGesturePrivate, parent)
337 {
338     d_func()->q_ptr = this;
339     d_func()->receiver = receiver;
340     d_func()->receiverScroller = (receiver && QScroller::hasScroller(receiver)) ? QScroller::scroller(receiver) : 0;
341     d_func()->button = button;
342 }
343
344 QFlickGesture::~QFlickGesture()
345 { }
346
347 QFlickGesturePrivate::QFlickGesturePrivate()
348     : receiverScroller(0), button(Qt::NoButton), macIgnoreWheel(false)
349 { }
350
351
352 //
353 // QFlickGestureRecognizer
354 //
355
356
357 QFlickGestureRecognizer::QFlickGestureRecognizer(Qt::MouseButton button)
358 {
359     this->button = button;
360 }
361
362 /*! \reimp
363  */
364 QGesture *QFlickGestureRecognizer::create(QObject *target)
365 {
366 #ifndef QT_NO_GRAPHICSVIEW
367     QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target);
368     if (go && button == Qt::NoButton) {
369         go->setAcceptTouchEvents(true);
370     }
371 #endif
372     return new QFlickGesture(target, button);
373 }
374
375 /*! \internal
376     The recognize function detects a touch event suitable to start the attached QScroller.
377     The QFlickGesture will be triggered as soon as the scroller is no longer in the state
378     QScroller::Inactive or QScroller::Pressed. It will be finished or canceled
379     at the next QEvent::TouchEnd.
380     Note that the QScroller might continue scrolling (kinetically) at this point.
381  */
382 QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state,
383                                                               QObject *watched,
384                                                               QEvent *event)
385 {
386     Q_UNUSED(watched);
387
388     static QElapsedTimer monotonicTimer;
389     if (!monotonicTimer.isValid())
390         monotonicTimer.start();
391
392     QFlickGesture *q = static_cast<QFlickGesture *>(state);
393     QFlickGesturePrivate *d = q->d_func();
394
395     QScroller *scroller = d->receiverScroller;
396     if (!scroller)
397         return Ignore; // nothing to do without a scroller?
398
399     QWidget *receiverWidget = qobject_cast<QWidget *>(d->receiver);
400 #ifndef QT_NO_GRAPHICSVIEW
401     QGraphicsObject *receiverGraphicsObject = qobject_cast<QGraphicsObject *>(d->receiver);
402 #endif
403
404     // this is only set for events that we inject into the event loop via sendEvent()
405     if (PressDelayHandler::instance()->shouldEventBeIgnored(event)) {
406         //qFGDebug() << state << "QFG: ignored event: " << event->type();
407         return Ignore;
408     }
409
410     const QMouseEvent *me = 0;
411 #ifndef QT_NO_GRAPHICSVIEW
412     const QGraphicsSceneMouseEvent *gsme = 0;
413 #endif
414     const QTouchEvent *te = 0;
415     QPoint globalPos;
416
417     // qFGDebug() << "FlickGesture "<<state<<"watched:"<<watched<<"receiver"<<d->receiver<<"event"<<event->type()<<"button"<<button;
418
419     switch (event->type()) {
420     case QEvent::MouseButtonPress:
421     case QEvent::MouseButtonRelease:
422     case QEvent::MouseMove:
423         if (!receiverWidget)
424             return Ignore;
425         if (button != Qt::NoButton) {
426             me = static_cast<const QMouseEvent *>(event);
427             globalPos = me->globalPos();
428         }
429         break;
430 #ifndef QT_NO_GRAPHICSVIEW
431     case QEvent::GraphicsSceneMousePress:
432     case QEvent::GraphicsSceneMouseRelease:
433     case QEvent::GraphicsSceneMouseMove:
434         if (!receiverGraphicsObject)
435             return Ignore;
436         if (button != Qt::NoButton) {
437             gsme = static_cast<const QGraphicsSceneMouseEvent *>(event);
438             globalPos = gsme->screenPos();
439         }
440         break;
441 #endif
442     case QEvent::TouchBegin:
443     case QEvent::TouchEnd:
444     case QEvent::TouchUpdate:
445         if (button == Qt::NoButton) {
446             te = static_cast<const QTouchEvent *>(event);
447             if (!te->touchPoints().isEmpty())
448                 globalPos = te->touchPoints().at(0).screenPos().toPoint();
449         }
450         break;
451
452 #if defined(Q_WS_MAC)
453     // the only way to distinguish between real mouse wheels and wheel
454     // events generated by the native 2 finger swipe gesture is to listen
455     // for these events (according to Apple's Cocoa Event-Handling Guide)
456
457     case QEvent::NativeGesture: {
458         QNativeGestureEvent *nge = static_cast<QNativeGestureEvent *>(event);
459         if (nge->gestureType == QNativeGestureEvent::GestureBegin)
460             d->macIgnoreWheel = true;
461         else if (nge->gestureType == QNativeGestureEvent::GestureEnd)
462             d->macIgnoreWheel = false;
463         break;
464     }
465 #endif
466
467     // consume all wheel events if the scroller is active
468     case QEvent::Wheel:
469         if (d->macIgnoreWheel || (scroller->state() != QScroller::Inactive))
470             return Ignore | ConsumeEventHint;
471         break;
472
473     // consume all dbl click events if the scroller is active
474     case QEvent::MouseButtonDblClick:
475         if (scroller->state() != QScroller::Inactive)
476             return Ignore | ConsumeEventHint;
477         break;
478
479     default:
480         break;
481     }
482
483     if (!me
484 #ifndef QT_NO_GRAPHICSVIEW
485         && !gsme
486 #endif
487         && !te) // Neither mouse nor touch
488         return Ignore;
489
490     // get the current pointer position in local coordinates.
491     QPointF point;
492     QScroller::Input inputType = (QScroller::Input) 0;
493
494     switch (event->type()) {
495     case QEvent::MouseButtonPress:
496         if (me && me->button() == button && me->buttons() == button) {
497             point = me->globalPos();
498             inputType = QScroller::InputPress;
499         } else if (me) {
500             scroller->stop();
501             return CancelGesture;
502         }
503         break;
504     case QEvent::MouseButtonRelease:
505         if (me && me->button() == button) {
506             point = me->globalPos();
507             inputType = QScroller::InputRelease;
508         }
509         break;
510     case QEvent::MouseMove:
511 #ifdef Q_OS_SYMBIAN
512         // Qt on Symbian tracks the button state internally, while Qt on Win/Mac/Unix
513         // relies on the windowing system to report the current buttons state.
514         if (me && (me->buttons() == button || !me->buttons())) {
515 #else
516         if (me && me->buttons() == button) {
517 #endif
518             point = me->globalPos();
519             inputType = QScroller::InputMove;
520         }
521         break;
522
523 #ifndef QT_NO_GRAPHICSVIEW
524     case QEvent::GraphicsSceneMousePress:
525         if (gsme && gsme->button() == button && gsme->buttons() == button) {
526             point = gsme->scenePos();
527             inputType = QScroller::InputPress;
528         } else if (gsme) {
529             scroller->stop();
530             return CancelGesture;
531         }
532         break;
533     case QEvent::GraphicsSceneMouseRelease:
534         if (gsme && gsme->button() == button) {
535             point = gsme->scenePos();
536             inputType = QScroller::InputRelease;
537         }
538         break;
539     case QEvent::GraphicsSceneMouseMove:
540 #ifdef Q_OS_SYMBIAN
541         // Qt on Symbian tracks the button state internally, while Qt on Win/Mac/Unix
542         // relies on the windowing system to report the current buttons state.
543         if (gsme && (gsme->buttons() == button || !me->buttons())) {
544 #else
545         if (gsme && gsme->buttons() == button) {
546 #endif
547             point = gsme->scenePos();
548             inputType = QScroller::InputMove;
549         }
550         break;
551 #endif
552
553     case QEvent::TouchBegin:
554         inputType = QScroller::InputPress;
555         // fall through
556     case QEvent::TouchEnd:
557         if (!inputType)
558             inputType = QScroller::InputRelease;
559         // fallthrough
560     case QEvent::TouchUpdate:
561         if (!inputType)
562             inputType = QScroller::InputMove;
563
564         if (te->deviceType() == QTouchEvent::TouchPad) {
565             if (te->touchPoints().count() != 2)  // 2 fingers on pad
566                 return Ignore;
567
568             point = te->touchPoints().at(0).startScenePos() +
569                     ((te->touchPoints().at(0).scenePos() - te->touchPoints().at(0).startScenePos()) +
570                      (te->touchPoints().at(1).scenePos() - te->touchPoints().at(1).startScenePos())) / 2;
571         } else { // TouchScreen
572             if (te->touchPoints().count() != 1) // 1 finger on screen
573                 return Ignore;
574
575             point = te->touchPoints().at(0).scenePos();
576         }
577         break;
578
579     default:
580         break;
581     }
582
583     // Check for an active scroller at globalPos
584     if (inputType == QScroller::InputPress) {
585         foreach (QScroller *as, QScroller::activeScrollers()) {
586             if (as != scroller) {
587                 QRegion scrollerRegion;
588
589                 if (QWidget *w = qobject_cast<QWidget *>(as->target())) {
590                     scrollerRegion = QRect(w->mapToGlobal(QPoint(0, 0)), w->size());
591 #ifndef QT_NO_GRAPHICSVIEW
592                 } else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(as->target())) {
593                     if (go->scene() && !go->scene()->views().isEmpty()) {
594                         foreach (QGraphicsView *gv, go->scene()->views())
595                             scrollerRegion |= gv->mapFromScene(go->mapToScene(go->boundingRect()))
596                                               .translated(gv->mapToGlobal(QPoint(0, 0)));
597                     }
598 #endif
599                 }
600                 // active scrollers always have priority
601                 if (scrollerRegion.contains(globalPos))
602                     return Ignore;
603             }
604         }
605     }
606
607     bool scrollerWasDragging = (scroller->state() == QScroller::Dragging);
608     bool scrollerWasScrolling = (scroller->state() == QScroller::Scrolling);
609
610     if (inputType) {
611         if (QWidget *w = qobject_cast<QWidget *>(d->receiver))
612             point = w->mapFromGlobal(point.toPoint());
613 #ifndef QT_NO_GRAPHICSVIEW
614         else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(d->receiver))
615             point = go->mapFromScene(point);
616 #endif
617
618         // inform the scroller about the new event
619         scroller->handleInput(inputType, point, monotonicTimer.elapsed());
620     }
621
622     // depending on the scroller state return the gesture state
623     Result result(0);
624     bool scrollerIsActive = (scroller->state() == QScroller::Dragging ||
625                              scroller->state() == QScroller::Scrolling);
626
627     // Consume all mouse events while dragging or scrolling to avoid nasty
628     // side effects with Qt's standard widgets.
629     if ((me
630 #ifndef QT_NO_GRAPHICSVIEW
631          || gsme
632 #endif
633          ) && scrollerIsActive)
634         result |= ConsumeEventHint;
635
636     // The only problem with this approach is that we consume the
637     // MouseRelease when we start the scrolling with a flick gesture, so we
638     // have to fake a MouseRelease "somewhere" to not mess with the internal
639     // states of Qt's widgets (a QPushButton would stay in 'pressed' state
640     // forever, if it doesn't receive a MouseRelease).
641     if (me
642 #ifndef QT_NO_GRAPHICSVIEW
643         || gsme
644 #endif
645         ) {
646         if (!scrollerWasDragging && !scrollerWasScrolling && scrollerIsActive)
647             PressDelayHandler::instance()->scrollerBecameActive();
648         else if (scrollerWasScrolling && (scroller->state() == QScroller::Dragging || scroller->state() == QScroller::Inactive))
649             PressDelayHandler::instance()->scrollerWasIntercepted();
650     }
651
652     if (!inputType) {
653         result |= Ignore;
654     } else {
655         switch (event->type()) {
656         case QEvent::MouseButtonPress:
657 #ifndef QT_NO_GRAPHICSVIEW
658         case QEvent::GraphicsSceneMousePress:
659 #endif
660             if (scroller->state() == QScroller::Pressed) {
661                 int pressDelay = int(1000 * scroller->scrollerProperties().scrollMetric(QScrollerProperties::MousePressEventDelay).toReal());
662                 if (pressDelay > 0) {
663                     result |= ConsumeEventHint;
664
665                     PressDelayHandler::instance()->pressed(event, pressDelay);
666                     event->accept();
667                 }
668             }
669             // fall through
670         case QEvent::TouchBegin:
671             q->setHotSpot(globalPos);
672             result |= scrollerIsActive ? TriggerGesture : MayBeGesture;
673             break;
674
675         case QEvent::MouseMove:
676 #ifndef QT_NO_GRAPHICSVIEW
677         case QEvent::GraphicsSceneMouseMove:
678 #endif
679             if (PressDelayHandler::instance()->isDelaying())
680                 result |= ConsumeEventHint;
681             // fall through
682         case QEvent::TouchUpdate:
683             result |= scrollerIsActive ? TriggerGesture : Ignore;
684             break;
685
686 #ifndef QT_NO_GRAPHICSVIEW
687         case QEvent::GraphicsSceneMouseRelease:
688 #endif
689         case QEvent::MouseButtonRelease:
690             if (PressDelayHandler::instance()->released(event, scrollerWasDragging || scrollerWasScrolling, scrollerIsActive))
691                 result |= ConsumeEventHint;
692             // fall through
693         case QEvent::TouchEnd:
694             result |= scrollerIsActive ? FinishGesture : CancelGesture;
695             break;
696
697         default:
698             result |= Ignore;
699             break;
700         }
701     }
702     return result;
703 }
704
705
706 /*! \reimp
707  */
708 void QFlickGestureRecognizer::reset(QGesture *state)
709 {
710     QGestureRecognizer::reset(state);
711 }
712
713 QT_END_NAMESPACE
714
715 #endif // QT_NO_GESTURES