1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtGui module of the Qt Toolkit.
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
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.
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.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "private/qgesturemanager_p.h"
43 #include "private/qstandardgestures_p.h"
44 #include "private/qwidget_p.h"
45 #include "private/qgesture_p.h"
46 #include "private/qgraphicsitem_p.h"
47 #include "private/qevent_p.h"
48 #include "private/qapplication_p.h"
51 #include "qgraphicsitem.h"
54 #include "qmacgesturerecognizer_mac_p.h"
56 #if defined(Q_OS_WIN) && !defined(QT_NO_NATIVE_GESTURES)
57 #include "qwinnativepangesturerecognizer_win_p.h"
62 // #define GESTURE_DEBUG
64 # define DEBUG if (0) qDebug
69 #ifndef QT_NO_GESTURES
73 QGestureManager::QGestureManager(QObject *parent)
74 : QObject(parent), state(NotGesture), m_lastCustomGestureId(Qt::CustomGesture)
76 qRegisterMetaType<Qt::GestureState>();
79 registerGestureRecognizer(new QMacSwipeGestureRecognizer);
80 registerGestureRecognizer(new QMacPinchGestureRecognizer);
81 #if defined(QT_MAC_USE_COCOA)
82 registerGestureRecognizer(new QMacPanGestureRecognizer);
85 registerGestureRecognizer(new QPanGestureRecognizer);
86 registerGestureRecognizer(new QPinchGestureRecognizer);
87 registerGestureRecognizer(new QSwipeGestureRecognizer);
88 registerGestureRecognizer(new QTapGestureRecognizer);
91 #if !defined(QT_NO_NATIVE_GESTURES)
92 if (QApplicationPrivate::HasTouchSupport)
93 registerGestureRecognizer(new QWinNativePanGestureRecognizer);
96 registerGestureRecognizer(new QTapAndHoldGestureRecognizer);
100 QGestureManager::~QGestureManager()
102 qDeleteAll(m_recognizers.values());
103 foreach (QGestureRecognizer *recognizer, m_obsoleteGestures.keys()) {
104 qDeleteAll(m_obsoleteGestures.value(recognizer));
107 m_obsoleteGestures.clear();
110 Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer)
112 QGesture *dummy = recognizer->create(0);
114 qWarning("QGestureManager::registerGestureRecognizer: "
115 "the recognizer fails to create a gesture object, skipping registration.");
116 return Qt::GestureType(0);
118 Qt::GestureType type = dummy->gestureType();
119 if (type == Qt::CustomGesture) {
120 // generate a new custom gesture id
121 ++m_lastCustomGestureId;
122 type = Qt::GestureType(m_lastCustomGestureId);
124 m_recognizers.insertMulti(type, recognizer);
129 void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type)
131 QList<QGestureRecognizer *> list = m_recognizers.values(type);
132 while (QGestureRecognizer *recognizer = m_recognizers.take(type)) {
133 if (!m_obsoleteGestures.contains(recognizer)) {
134 // inserting even an empty QSet will cause the recognizer to be deleted on destruction of the manager
135 m_obsoleteGestures.insert(recognizer, QSet<QGesture *>());
138 foreach (QGesture *g, m_gestureToRecognizer.keys()) {
139 QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g);
140 if (list.contains(recognizer)) {
141 m_deletedRecognizers.insert(g, recognizer);
145 QMap<ObjectGesture, QList<QGesture *> >::const_iterator iter = m_objectGestures.begin();
146 while (iter != m_objectGestures.end()) {
147 ObjectGesture objectGesture = iter.key();
148 if (objectGesture.gesture == type) {
149 foreach (QGesture *g, iter.value()) {
150 if (QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g)) {
151 m_gestureToRecognizer.remove(g);
152 m_obsoleteGestures[recognizer].insert(g);
160 void QGestureManager::cleanupCachedGestures(QObject *target, Qt::GestureType type)
162 QMap<ObjectGesture, QList<QGesture *> >::Iterator iter = m_objectGestures.begin();
163 while (iter != m_objectGestures.end()) {
164 ObjectGesture objectGesture = iter.key();
165 if (objectGesture.gesture == type && target == objectGesture.object) {
166 QSet<QGesture *> gestures = iter.value().toSet();
167 for (QHash<QGestureRecognizer *, QSet<QGesture *> >::iterator
168 it = m_obsoleteGestures.begin(), e = m_obsoleteGestures.end(); it != e; ++it) {
169 it.value() -= gestures;
171 foreach (QGesture *g, gestures) {
172 m_deletedRecognizers.remove(g);
173 m_gestureToRecognizer.remove(g);
174 m_maybeGestures.remove(g);
175 m_activeGestures.remove(g);
176 m_gestureOwners.remove(g);
177 m_gestureTargets.remove(g);
178 m_gesturesToDelete.insert(g);
181 iter = m_objectGestures.erase(iter);
188 // get or create a QGesture object that will represent the state for a given object, used by the recognizer
189 QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recognizer, Qt::GestureType type)
191 // if the widget is being deleted we should be careful not to
192 // create a new state, as it will create QWeakPointer which doesn't work
193 // from the destructor.
194 if (object->isWidgetType()) {
195 if (static_cast<QWidget *>(object)->d_func()->data.in_destructor)
197 } else if (QGesture *g = qobject_cast<QGesture *>(object)) {
199 #ifndef QT_NO_GRAPHICSVIEW
201 Q_ASSERT(qobject_cast<QGraphicsObject *>(object));
202 QGraphicsObject *graphicsObject = static_cast<QGraphicsObject *>(object);
203 if (graphicsObject->QGraphicsItem::d_func()->inDestructor)
208 // check if the QGesture for this recognizer has already been created
209 foreach (QGesture *state, m_objectGestures.value(QGestureManager::ObjectGesture(object, type))) {
210 if (m_gestureToRecognizer.value(state) == recognizer)
214 Q_ASSERT(recognizer);
215 QGesture *state = recognizer->create(object);
218 state->setParent(this);
219 if (state->gestureType() == Qt::CustomGesture) {
220 // if the recognizer didn't fill in the gesture type, then this
221 // is a custom gesture with autogenerated id and we fill it.
222 state->d_func()->gestureType = type;
223 #if defined(GESTURE_DEBUG)
224 state->setObjectName(QString::number((int)type));
227 m_objectGestures[QGestureManager::ObjectGesture(object, type)].append(state);
228 m_gestureToRecognizer[state] = recognizer;
229 m_gestureOwners[state] = object;
234 bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *,
235 Qt::GestureType> &contexts,
238 QSet<QGesture *> triggeredGestures;
239 QSet<QGesture *> finishedGestures;
240 QSet<QGesture *> newMaybeGestures;
241 QSet<QGesture *> notGestures;
243 // TODO: sort contexts by the gesture type and check if one of the contexts
244 // is already active.
246 bool consumeEventHint = false;
248 // filter the event through recognizers
249 typedef QMultiMap<QObject *, Qt::GestureType>::const_iterator ContextIterator;
250 ContextIterator contextEnd = contexts.end();
251 for (ContextIterator context = contexts.begin(); context != contextEnd; ++context) {
252 Qt::GestureType gestureType = context.value();
253 QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator
254 typeToRecognizerIterator = m_recognizers.lowerBound(gestureType),
255 typeToRecognizerEnd = m_recognizers.upperBound(gestureType);
256 for (; typeToRecognizerIterator != typeToRecognizerEnd; ++typeToRecognizerIterator) {
257 QGestureRecognizer *recognizer = typeToRecognizerIterator.value();
258 QObject *target = context.key();
259 QGesture *state = getState(target, recognizer, gestureType);
262 QGestureRecognizer::Result recognizerResult = recognizer->recognize(state, target, event);
263 QGestureRecognizer::Result recognizerState = recognizerResult & QGestureRecognizer::ResultState_Mask;
264 QGestureRecognizer::Result resultHint = recognizerResult & QGestureRecognizer::ResultHint_Mask;
265 if (recognizerState == QGestureRecognizer::TriggerGesture) {
266 DEBUG() << "QGestureManager:Recognizer: gesture triggered: " << state;
267 triggeredGestures << state;
268 } else if (recognizerState == QGestureRecognizer::FinishGesture) {
269 DEBUG() << "QGestureManager:Recognizer: gesture finished: " << state;
270 finishedGestures << state;
271 } else if (recognizerState == QGestureRecognizer::MayBeGesture) {
272 DEBUG() << "QGestureManager:Recognizer: maybe gesture: " << state;
273 newMaybeGestures << state;
274 } else if (recognizerState == QGestureRecognizer::CancelGesture) {
275 DEBUG() << "QGestureManager:Recognizer: not gesture: " << state;
276 notGestures << state;
277 } else if (recognizerState == QGestureRecognizer::Ignore) {
278 DEBUG() << "QGestureManager:Recognizer: ignored the event: " << state;
280 DEBUG() << "QGestureManager:Recognizer: hm, lets assume the recognizer"
281 << "ignored the event: " << state;
283 if (resultHint & QGestureRecognizer::ConsumeEventHint) {
284 DEBUG() << "QGestureManager: we were asked to consume the event: "
286 consumeEventHint = true;
290 if (triggeredGestures.isEmpty() && finishedGestures.isEmpty()
291 && newMaybeGestures.isEmpty() && notGestures.isEmpty())
292 return consumeEventHint;
294 QSet<QGesture *> startedGestures = triggeredGestures - m_activeGestures;
295 triggeredGestures &= m_activeGestures;
297 // check if a running gesture switched back to maybe state
298 QSet<QGesture *> activeToMaybeGestures = m_activeGestures & newMaybeGestures;
300 // check if a maybe gesture switched to canceled - reset it but don't send an event
301 QSet<QGesture *> maybeToCanceledGestures = m_maybeGestures & notGestures;
303 // check if a running gesture switched back to not gesture state,
304 // i.e. were canceled
305 QSet<QGesture *> canceledGestures = m_activeGestures & notGestures;
307 // new gestures in maybe state
308 m_maybeGestures += newMaybeGestures;
310 // gestures that were in maybe state
311 QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures
312 | finishedGestures | canceledGestures
314 m_maybeGestures -= notMaybeGestures;
316 Q_ASSERT((startedGestures & finishedGestures).isEmpty());
317 Q_ASSERT((startedGestures & newMaybeGestures).isEmpty());
318 Q_ASSERT((startedGestures & canceledGestures).isEmpty());
319 Q_ASSERT((finishedGestures & newMaybeGestures).isEmpty());
320 Q_ASSERT((finishedGestures & canceledGestures).isEmpty());
321 Q_ASSERT((canceledGestures & newMaybeGestures).isEmpty());
323 QSet<QGesture *> notStarted = finishedGestures - m_activeGestures;
324 if (!notStarted.isEmpty()) {
325 // there are some gestures that claim to be finished, but never started.
326 // probably those are "singleshot" gestures so we'll fake the started state.
327 foreach (QGesture *gesture, notStarted)
328 gesture->d_func()->state = Qt::GestureStarted;
329 QSet<QGesture *> undeliveredGestures;
330 deliverEvents(notStarted, &undeliveredGestures);
331 finishedGestures -= undeliveredGestures;
334 m_activeGestures += startedGestures;
335 // sanity check: all triggered gestures should already be in active gestures list
336 Q_ASSERT((m_activeGestures & triggeredGestures).size() == triggeredGestures.size());
337 m_activeGestures -= finishedGestures;
338 m_activeGestures -= activeToMaybeGestures;
339 m_activeGestures -= canceledGestures;
341 // set the proper gesture state on each gesture
342 foreach (QGesture *gesture, startedGestures)
343 gesture->d_func()->state = Qt::GestureStarted;
344 foreach (QGesture *gesture, triggeredGestures)
345 gesture->d_func()->state = Qt::GestureUpdated;
346 foreach (QGesture *gesture, finishedGestures)
347 gesture->d_func()->state = Qt::GestureFinished;
348 foreach (QGesture *gesture, canceledGestures)
349 gesture->d_func()->state = Qt::GestureCanceled;
350 foreach (QGesture *gesture, activeToMaybeGestures)
351 gesture->d_func()->state = Qt::GestureFinished;
353 if (!m_activeGestures.isEmpty() || !m_maybeGestures.isEmpty() ||
354 !startedGestures.isEmpty() || !triggeredGestures.isEmpty() ||
355 !finishedGestures.isEmpty() || !canceledGestures.isEmpty()) {
356 DEBUG() << "QGestureManager::filterEventThroughContexts:"
357 << "\n\tactiveGestures:" << m_activeGestures
358 << "\n\tmaybeGestures:" << m_maybeGestures
359 << "\n\tstarted:" << startedGestures
360 << "\n\ttriggered:" << triggeredGestures
361 << "\n\tfinished:" << finishedGestures
362 << "\n\tcanceled:" << canceledGestures
363 << "\n\tmaybe-canceled:" << maybeToCanceledGestures;
366 QSet<QGesture *> undeliveredGestures;
367 deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures,
368 &undeliveredGestures);
370 foreach (QGesture *g, startedGestures) {
371 if (undeliveredGestures.contains(g))
373 if (g->gestureCancelPolicy() == QGesture::CancelAllInContext) {
374 DEBUG() << "lets try to cancel some";
375 // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them
376 cancelGesturesForChildren(g);
380 m_activeGestures -= undeliveredGestures;
382 // reset gestures that ended
383 QSet<QGesture *> endedGestures =
384 finishedGestures + canceledGestures + undeliveredGestures + maybeToCanceledGestures;
385 foreach (QGesture *gesture, endedGestures) {
387 m_gestureTargets.remove(gesture);
390 //Clean up the Gestures
391 qDeleteAll(m_gesturesToDelete);
392 m_gesturesToDelete.clear();
394 return consumeEventHint;
397 // Cancel all gestures of children of the widget that original is associated with
398 void QGestureManager::cancelGesturesForChildren(QGesture *original)
401 QWidget *originatingWidget = m_gestureTargets.value(original);
402 Q_ASSERT(originatingWidget);
404 // iterate over all active gestures and all maybe gestures
405 // for each find the owner
406 // if the owner is part of our sub-hierarchy, cancel it.
408 QSet<QGesture*> cancelledGestures;
409 QSet<QGesture*>::Iterator iter = m_activeGestures.begin();
410 while (iter != m_activeGestures.end()) {
411 QWidget *widget = m_gestureTargets.value(*iter);
412 // note that we don't touch the gestures for our originatingWidget
413 if (widget != originatingWidget && originatingWidget->isAncestorOf(widget)) {
414 DEBUG() << " found a gesture to cancel" << (*iter);
415 (*iter)->d_func()->state = Qt::GestureCanceled;
416 cancelledGestures << *iter;
417 iter = m_activeGestures.erase(iter);
423 // TODO handle 'maybe' gestures too
425 // sort them per target widget by cherry picking from almostCanceledGestures and delivering
426 QSet<QGesture *> almostCanceledGestures = cancelledGestures;
427 while (!almostCanceledGestures.isEmpty()) {
429 QSet<QGesture*> gestures;
430 iter = almostCanceledGestures.begin();
431 // sort per target widget
432 while (iter != almostCanceledGestures.end()) {
433 QWidget *widget = m_gestureTargets.value(*iter);
436 if (target == widget) {
438 iter = almostCanceledGestures.erase(iter);
445 QSet<QGesture*> undeliveredGestures;
446 deliverEvents(gestures, &undeliveredGestures);
449 for (iter = cancelledGestures.begin(); iter != cancelledGestures.end(); ++iter)
453 void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture)
455 QGestureRecognizer *recognizer = m_deletedRecognizers.value(gesture);
456 if(!recognizer) //The Gesture is removed while in the even loop, so the recognizers for this gestures was removed
458 m_deletedRecognizers.remove(gesture);
459 if (m_deletedRecognizers.keys(recognizer).isEmpty()) {
460 // no more active gestures, cleanup!
461 qDeleteAll(m_obsoleteGestures.value(recognizer));
462 m_obsoleteGestures.remove(recognizer);
467 // return true if accepted (consumed)
468 bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
470 QMap<Qt::GestureType, int> types;
471 QMultiMap<QObject *, Qt::GestureType> contexts;
472 QWidget *w = receiver;
473 typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
474 if (!w->d_func()->gestureContext.isEmpty()) {
475 for(ContextIterator it = w->d_func()->gestureContext.begin(),
476 e = w->d_func()->gestureContext.end(); it != e; ++it) {
477 types.insert(it.key(), 0);
478 contexts.insertMulti(w, it.key());
481 // find all gesture contexts for the widget tree
482 w = w->isWindow() ? 0 : w->parentWidget();
485 for (ContextIterator it = w->d_func()->gestureContext.begin(),
486 e = w->d_func()->gestureContext.end(); it != e; ++it) {
487 if (!(it.value() & Qt::DontStartGestureOnChildren)) {
488 if (!types.contains(it.key())) {
489 types.insert(it.key(), 0);
490 contexts.insertMulti(w, it.key());
496 w = w->parentWidget();
498 return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event);
501 #ifndef QT_NO_GRAPHICSVIEW
502 bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event)
504 QMap<Qt::GestureType, int> types;
505 QMultiMap<QObject *, Qt::GestureType> contexts;
506 QGraphicsObject *item = receiver;
507 if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) {
508 typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
509 for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
510 e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
511 types.insert(it.key(), 0);
512 contexts.insertMulti(item, it.key());
515 // find all gesture contexts for the graphics object tree
516 item = item->parentObject();
519 typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
520 for (ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
521 e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
522 if (!(it.value() & Qt::DontStartGestureOnChildren)) {
523 if (!types.contains(it.key())) {
524 types.insert(it.key(), 0);
525 contexts.insertMulti(item, it.key());
529 item = item->parentObject();
531 return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event);
535 bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
537 if (!m_gestureToRecognizer.contains(static_cast<QGesture *>(receiver)))
539 QGesture *state = static_cast<QGesture *>(receiver);
540 QMultiMap<QObject *, Qt::GestureType> contexts;
541 contexts.insert(state, state->gestureType());
542 return filterEventThroughContexts(contexts, event);
545 void QGestureManager::getGestureTargets(const QSet<QGesture*> &gestures,
546 QMap<QWidget *, QList<QGesture *> > *conflicts,
547 QMap<QWidget *, QList<QGesture *> > *normal)
549 typedef QHash<Qt::GestureType, QHash<QWidget *, QGesture *> > GestureByTypes;
550 GestureByTypes gestureByTypes;
552 // sort gestures by types
553 foreach (QGesture *gesture, gestures) {
554 QWidget *receiver = m_gestureTargets.value(gesture, 0);
556 gestureByTypes[gesture->gestureType()].insert(receiver, gesture);
559 // for each gesture type
560 foreach (Qt::GestureType type, gestureByTypes.keys()) {
561 QHash<QWidget *, QGesture *> gestures = gestureByTypes.value(type);
562 foreach (QWidget *widget, gestures.keys()) {
563 QWidget *w = widget->parentWidget();
565 QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator it
566 = w->d_func()->gestureContext.find(type);
567 if (it != w->d_func()->gestureContext.end()) {
568 // i.e. 'w' listens to gesture 'type'
569 Qt::GestureFlags flags = it.value();
570 if (!(it.value() & Qt::DontStartGestureOnChildren) && w != widget) {
571 // conflicting gesture!
572 (*conflicts)[widget].append(gestures[widget]);
580 w = w->parentWidget();
583 (*normal)[widget].append(gestures[widget]);
588 void QGestureManager::deliverEvents(const QSet<QGesture *> &gestures,
589 QSet<QGesture *> *undeliveredGestures)
591 if (gestures.isEmpty())
594 typedef QMap<QWidget *, QList<QGesture *> > GesturesPerWidget;
595 GesturesPerWidget conflictedGestures;
596 GesturesPerWidget normalStartedGestures;
598 QSet<QGesture *> startedGestures;
599 // first figure out the initial receivers of gestures
600 for (QSet<QGesture *>::const_iterator it = gestures.begin(),
601 e = gestures.end(); it != e; ++it) {
602 QGesture *gesture = *it;
603 QWidget *target = m_gestureTargets.value(gesture, 0);
605 // the gesture has just started and doesn't have a target yet.
606 Q_ASSERT(gesture->state() == Qt::GestureStarted);
607 if (gesture->hasHotSpot()) {
608 // guess the target widget using the hotspot of the gesture
609 QPoint pt = gesture->hotSpot().toPoint();
610 if (QWidget *topLevel = qApp->topLevelAt(pt)) {
611 QWidget *child = topLevel->childAt(topLevel->mapFromGlobal(pt));
612 target = child ? child : topLevel;
615 // or use the context of the gesture
616 QObject *context = m_gestureOwners.value(gesture, 0);
617 if (context->isWidgetType())
618 target = static_cast<QWidget *>(context);
621 m_gestureTargets.insert(gesture, target);
624 Qt::GestureType gestureType = gesture->gestureType();
625 Q_ASSERT(gestureType != Qt::CustomGesture);
626 Q_UNUSED(gestureType);
629 if (gesture->state() == Qt::GestureStarted) {
630 startedGestures.insert(gesture);
632 normalStartedGestures[target].append(gesture);
635 DEBUG() << "QGestureManager::deliverEvent: could not find the target for gesture"
636 << gesture->gestureType();
637 qWarning("QGestureManager::deliverEvent: could not find the target for gesture");
638 undeliveredGestures->insert(gesture);
642 getGestureTargets(startedGestures, &conflictedGestures, &normalStartedGestures);
643 DEBUG() << "QGestureManager::deliverEvents:"
644 << "\nstarted: " << startedGestures
645 << "\nconflicted: " << conflictedGestures
646 << "\nnormal: " << normalStartedGestures
649 // if there are conflicting gestures, send the GestureOverride event
650 for (GesturesPerWidget::const_iterator it = conflictedGestures.begin(),
651 e = conflictedGestures.end(); it != e; ++it) {
652 QWidget *receiver = it.key();
653 QList<QGesture *> gestures = it.value();
654 DEBUG() << "QGestureManager::deliverEvents: sending GestureOverride to"
656 << "gestures:" << gestures;
657 QGestureEvent event(gestures);
658 event.t = QEvent::GestureOverride;
659 // mark event and individual gestures as ignored
661 foreach(QGesture *g, gestures)
662 event.setAccepted(g, false);
664 QApplication::sendEvent(receiver, &event);
665 bool eventAccepted = event.isAccepted();
666 foreach(QGesture *gesture, event.gestures()) {
667 if (eventAccepted || event.isAccepted(gesture)) {
668 QWidget *w = event.d_func()->targetWidgets.value(gesture->gestureType(), 0);
670 DEBUG() << "override event: gesture was accepted:" << gesture << w;
671 QList<QGesture *> &gestures = normalStartedGestures[w];
672 gestures.append(gesture);
673 // override the target
674 m_gestureTargets[gesture] = w;
676 DEBUG() << "override event: gesture wasn't accepted. putting back:" << gesture;
677 QList<QGesture *> &gestures = normalStartedGestures[receiver];
678 gestures.append(gesture);
683 // delivering gestures that are not in conflicted state
684 for (GesturesPerWidget::const_iterator it = normalStartedGestures.begin(),
685 e = normalStartedGestures.end(); it != e; ++it) {
686 if (!it.value().isEmpty()) {
687 DEBUG() << "QGestureManager::deliverEvents: sending to" << it.key()
688 << "gestures:" << it.value();
689 QGestureEvent event(it.value());
690 QApplication::sendEvent(it.key(), &event);
691 bool eventAccepted = event.isAccepted();
692 foreach (QGesture *gesture, event.gestures()) {
693 if (gesture->state() == Qt::GestureStarted &&
694 (eventAccepted || event.isAccepted(gesture))) {
695 QWidget *w = event.d_func()->targetWidgets.value(gesture->gestureType(), 0);
697 DEBUG() << "started gesture was delivered and accepted by" << w;
698 m_gestureTargets[gesture] = w;
705 void QGestureManager::recycle(QGesture *gesture)
707 QGestureRecognizer *recognizer = m_gestureToRecognizer.value(gesture, 0);
709 gesture->setGestureCancelPolicy(QGesture::CancelNone);
710 recognizer->reset(gesture);
711 m_activeGestures.remove(gesture);
713 cleanupGesturesForRemovedRecognizer(gesture);
719 #endif // QT_NO_GESTURES
721 #include "moc_qgesturemanager_p.cpp"