Qt 4.8
qgesturemanager.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
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"
49 #include "qgesture.h"
50 #include "qevent.h"
51 #include "qgraphicsitem.h"
52 
53 #ifdef Q_WS_MAC
55 #endif
56 #if defined(Q_OS_WIN) && !defined(QT_NO_NATIVE_GESTURES)
58 #endif
59 
60 #include "qdebug.h"
61 
62 // #define GESTURE_DEBUG
63 #ifndef GESTURE_DEBUG
64 # define DEBUG if (0) qDebug
65 #else
66 # define DEBUG qDebug
67 #endif
68 
69 #ifndef QT_NO_GESTURES
70 
72 
74  : QObject(parent), state(NotGesture), m_lastCustomGestureId(Qt::CustomGesture)
75 {
76  qRegisterMetaType<Qt::GestureState>();
77 
78 #if defined(Q_WS_MAC)
81  #if defined(QT_MAC_USE_COCOA)
82  registerGestureRecognizer(new QMacPanGestureRecognizer);
83  #endif
84 #else
89 #endif
90 #if defined(Q_OS_WIN)
91  #if !defined(QT_NO_NATIVE_GESTURES)
94  #endif
95 #else
97 #endif
98 }
99 
101 {
103  foreach (QGestureRecognizer *recognizer, m_obsoleteGestures.keys()) {
104  qDeleteAll(m_obsoleteGestures.value(recognizer));
105  delete recognizer;
106  }
108 }
109 
111 {
112  QGesture *dummy = recognizer->create(0);
113  if (!dummy) {
114  qWarning("QGestureManager::registerGestureRecognizer: "
115  "the recognizer fails to create a gesture object, skipping registration.");
116  return Qt::GestureType(0);
117  }
118  Qt::GestureType type = dummy->gestureType();
119  if (type == Qt::CustomGesture) {
120  // generate a new custom gesture id
123  }
124  m_recognizers.insertMulti(type, recognizer);
125  delete dummy;
126  return type;
127 }
128 
130 {
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
136  }
137  }
138  foreach (QGesture *g, m_gestureToRecognizer.keys()) {
140  if (list.contains(recognizer)) {
141  m_deletedRecognizers.insert(g, recognizer);
142  }
143  }
144 
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)) {
152  m_obsoleteGestures[recognizer].insert(g);
153  }
154  }
155  }
156  ++iter;
157  }
158 }
159 
161 {
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;
170  }
171  foreach (QGesture *g, gestures) {
179  }
180 
181  iter = m_objectGestures.erase(iter);
182  } else {
183  ++iter;
184  }
185  }
186 }
187 
188 // get or create a QGesture object that will represent the state for a given object, used by the recognizer
190 {
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)
196  return 0;
197  } else if (QGesture *g = qobject_cast<QGesture *>(object)) {
198  return g;
199 #ifndef QT_NO_GRAPHICSVIEW
200  } else {
201  Q_ASSERT(qobject_cast<QGraphicsObject *>(object));
202  QGraphicsObject *graphicsObject = static_cast<QGraphicsObject *>(object);
203  if (graphicsObject->QGraphicsItem::d_func()->inDestructor)
204  return 0;
205 #endif
206  }
207 
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)
211  return state;
212  }
213 
214  Q_ASSERT(recognizer);
215  QGesture *state = recognizer->create(object);
216  if (!state)
217  return 0;
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));
225 #endif
226  }
227  m_objectGestures[QGestureManager::ObjectGesture(object, type)].append(state);
228  m_gestureToRecognizer[state] = recognizer;
229  m_gestureOwners[state] = object;
230 
231  return state;
232 }
233 
235  Qt::GestureType> &contexts,
236  QEvent *event)
237 {
238  QSet<QGesture *> triggeredGestures;
239  QSet<QGesture *> finishedGestures;
240  QSet<QGesture *> newMaybeGestures;
241  QSet<QGesture *> notGestures;
242 
243  // TODO: sort contexts by the gesture type and check if one of the contexts
244  // is already active.
245 
246  bool consumeEventHint = false;
247 
248  // filter the event through recognizers
250  ContextIterator contextEnd = contexts.end();
251  for (ContextIterator context = contexts.begin(); context != contextEnd; ++context) {
252  Qt::GestureType gestureType = context.value();
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);
260  if (!state)
261  continue;
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;
279  } else {
280  DEBUG() << "QGestureManager:Recognizer: hm, lets assume the recognizer"
281  << "ignored the event: " << state;
282  }
283  if (resultHint & QGestureRecognizer::ConsumeEventHint) {
284  DEBUG() << "QGestureManager: we were asked to consume the event: "
285  << state;
286  consumeEventHint = true;
287  }
288  }
289  }
290  if (!triggeredGestures.isEmpty() || !finishedGestures.isEmpty()
291  || !newMaybeGestures.isEmpty() || !notGestures.isEmpty()) {
292  QSet<QGesture *> startedGestures = triggeredGestures - m_activeGestures;
293  triggeredGestures &= m_activeGestures;
294 
295  // check if a running gesture switched back to maybe state
296  QSet<QGesture *> activeToMaybeGestures = m_activeGestures & newMaybeGestures;
297 
298  // check if a maybe gesture switched to canceled - reset it but don't send an event
299  QSet<QGesture *> maybeToCanceledGestures = m_maybeGestures & notGestures;
300 
301  // check if a running gesture switched back to not gesture state,
302  // i.e. were canceled
303  QSet<QGesture *> canceledGestures = m_activeGestures & notGestures;
304 
305  // new gestures in maybe state
306  m_maybeGestures += newMaybeGestures;
307 
308  // gestures that were in maybe state
309  QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures
310  | finishedGestures | canceledGestures
311  | notGestures);
312  m_maybeGestures -= notMaybeGestures;
313 
314  Q_ASSERT((startedGestures & finishedGestures).isEmpty());
315  Q_ASSERT((startedGestures & newMaybeGestures).isEmpty());
316  Q_ASSERT((startedGestures & canceledGestures).isEmpty());
317  Q_ASSERT((finishedGestures & newMaybeGestures).isEmpty());
318  Q_ASSERT((finishedGestures & canceledGestures).isEmpty());
319  Q_ASSERT((canceledGestures & newMaybeGestures).isEmpty());
320 
321  QSet<QGesture *> notStarted = finishedGestures - m_activeGestures;
322  if (!notStarted.isEmpty()) {
323  // there are some gestures that claim to be finished, but never started.
324  // probably those are "singleshot" gestures so we'll fake the started state.
325  foreach (QGesture *gesture, notStarted)
326  gesture->d_func()->state = Qt::GestureStarted;
327  QSet<QGesture *> undeliveredGestures;
328  deliverEvents(notStarted, &undeliveredGestures);
329  finishedGestures -= undeliveredGestures;
330  }
331 
332  m_activeGestures += startedGestures;
333  // sanity check: all triggered gestures should already be in active gestures list
334  Q_ASSERT((m_activeGestures & triggeredGestures).size() == triggeredGestures.size());
335  m_activeGestures -= finishedGestures;
336  m_activeGestures -= activeToMaybeGestures;
337  m_activeGestures -= canceledGestures;
338 
339  // set the proper gesture state on each gesture
340  foreach (QGesture *gesture, startedGestures)
341  gesture->d_func()->state = Qt::GestureStarted;
342  foreach (QGesture *gesture, triggeredGestures)
343  gesture->d_func()->state = Qt::GestureUpdated;
344  foreach (QGesture *gesture, finishedGestures)
345  gesture->d_func()->state = Qt::GestureFinished;
346  foreach (QGesture *gesture, canceledGestures)
347  gesture->d_func()->state = Qt::GestureCanceled;
348  foreach (QGesture *gesture, activeToMaybeGestures)
349  gesture->d_func()->state = Qt::GestureFinished;
350 
351  if (!m_activeGestures.isEmpty() || !m_maybeGestures.isEmpty() ||
352  !startedGestures.isEmpty() || !triggeredGestures.isEmpty() ||
353  !finishedGestures.isEmpty() || !canceledGestures.isEmpty()) {
354  DEBUG() << "QGestureManager::filterEventThroughContexts:"
355  << "\n\tactiveGestures:" << m_activeGestures
356  << "\n\tmaybeGestures:" << m_maybeGestures
357  << "\n\tstarted:" << startedGestures
358  << "\n\ttriggered:" << triggeredGestures
359  << "\n\tfinished:" << finishedGestures
360  << "\n\tcanceled:" << canceledGestures
361  << "\n\tmaybe-canceled:" << maybeToCanceledGestures;
362  }
363 
364  QSet<QGesture *> undeliveredGestures;
365  deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures,
366  &undeliveredGestures);
367 
368  foreach (QGesture *g, startedGestures) {
369  if (undeliveredGestures.contains(g))
370  continue;
372  DEBUG() << "lets try to cancel some";
373  // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them
375  }
376  }
377 
378  m_activeGestures -= undeliveredGestures;
379 
380  // reset gestures that ended
381  QSet<QGesture *> endedGestures =
382  finishedGestures + canceledGestures + undeliveredGestures + maybeToCanceledGestures;
383  foreach (QGesture *gesture, endedGestures) {
384  recycle(gesture);
385  m_gestureTargets.remove(gesture);
386  }
387  }
388  //Clean up the Gestures
391 
392  return consumeEventHint;
393 }
394 
395 // Cancel all gestures of children of the widget that original is associated with
397 {
398  Q_ASSERT(original);
399  QWidget *originatingWidget = m_gestureTargets.value(original);
400  Q_ASSERT(originatingWidget);
401 
402  // iterate over all active gestures and all maybe gestures
403  // for each find the owner
404  // if the owner is part of our sub-hierarchy, cancel it.
405 
406  QSet<QGesture*> cancelledGestures;
408  while (iter != m_activeGestures.end()) {
410  // note that we don't touch the gestures for our originatingWidget
411  if (widget != originatingWidget && originatingWidget->isAncestorOf(widget)) {
412  DEBUG() << " found a gesture to cancel" << (*iter);
413  (*iter)->d_func()->state = Qt::GestureCanceled;
414  cancelledGestures << *iter;
415  iter = m_activeGestures.erase(iter);
416  } else {
417  ++iter;
418  }
419  }
420 
421  // TODO handle 'maybe' gestures too
422 
423  // sort them per target widget by cherry picking from almostCanceledGestures and delivering
424  QSet<QGesture *> almostCanceledGestures = cancelledGestures;
425  while (!almostCanceledGestures.isEmpty()) {
426  QWidget *target = 0;
427  QSet<QGesture*> gestures;
428  iter = almostCanceledGestures.begin();
429  // sort per target widget
430  while (iter != almostCanceledGestures.end()) {
432  if (target == 0)
433  target = widget;
434  if (target == widget) {
435  gestures << *iter;
436  iter = almostCanceledGestures.erase(iter);
437  } else {
438  ++iter;
439  }
440  }
441  Q_ASSERT(target);
442 
443  QSet<QGesture*> undeliveredGestures;
444  deliverEvents(gestures, &undeliveredGestures);
445  }
446 
447  for (iter = cancelledGestures.begin(); iter != cancelledGestures.end(); ++iter)
448  recycle(*iter);
449 }
450 
452 {
453  QGestureRecognizer *recognizer = m_deletedRecognizers.value(gesture);
454  if(!recognizer) //The Gesture is removed while in the even loop, so the recognizers for this gestures was removed
455  return;
456  m_deletedRecognizers.remove(gesture);
457  if (m_deletedRecognizers.keys(recognizer).isEmpty()) {
458  // no more active gestures, cleanup!
459  qDeleteAll(m_obsoleteGestures.value(recognizer));
460  m_obsoleteGestures.remove(recognizer);
461  delete recognizer;
462  }
463 }
464 
465 // return true if accepted (consumed)
467 {
470  QWidget *w = receiver;
472  if (!w->d_func()->gestureContext.isEmpty()) {
473  for(ContextIterator it = w->d_func()->gestureContext.begin(),
474  e = w->d_func()->gestureContext.end(); it != e; ++it) {
475  types.insert(it.key(), 0);
476  contexts.insertMulti(w, it.key());
477  }
478  }
479  // find all gesture contexts for the widget tree
480  w = w->isWindow() ? 0 : w->parentWidget();
481  while (w)
482  {
483  for (ContextIterator it = w->d_func()->gestureContext.begin(),
484  e = w->d_func()->gestureContext.end(); it != e; ++it) {
485  if (!(it.value() & Qt::DontStartGestureOnChildren)) {
486  if (!types.contains(it.key())) {
487  types.insert(it.key(), 0);
488  contexts.insertMulti(w, it.key());
489  }
490  }
491  }
492  if (w->isWindow())
493  break;
494  w = w->parentWidget();
495  }
496  return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event);
497 }
498 
499 #ifndef QT_NO_GRAPHICSVIEW
501 {
504  QGraphicsObject *item = receiver;
505  if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) {
507  for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
508  e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
509  types.insert(it.key(), 0);
510  contexts.insertMulti(item, it.key());
511  }
512  }
513  // find all gesture contexts for the graphics object tree
514  item = item->parentObject();
515  while (item)
516  {
518  for (ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
519  e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
520  if (!(it.value() & Qt::DontStartGestureOnChildren)) {
521  if (!types.contains(it.key())) {
522  types.insert(it.key(), 0);
523  contexts.insertMulti(item, it.key());
524  }
525  }
526  }
527  item = item->parentObject();
528  }
529  return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event);
530 }
531 #endif
532 
534 {
535  if (!m_gestureToRecognizer.contains(static_cast<QGesture *>(receiver)))
536  return false;
537  QGesture *state = static_cast<QGesture *>(receiver);
539  contexts.insert(state, state->gestureType());
540  return filterEventThroughContexts(contexts, event);
541 }
542 
544  QMap<QWidget *, QList<QGesture *> > *conflicts,
545  QMap<QWidget *, QList<QGesture *> > *normal)
546 {
548  GestureByTypes gestureByTypes;
549 
550  // sort gestures by types
551  foreach (QGesture *gesture, gestures) {
552  QWidget *receiver = m_gestureTargets.value(gesture, 0);
553  Q_ASSERT(receiver);
554  gestureByTypes[gesture->gestureType()].insert(receiver, gesture);
555  }
556 
557  // for each gesture type
558  foreach (Qt::GestureType type, gestureByTypes.keys()) {
559  QHash<QWidget *, QGesture *> gestures = gestureByTypes.value(type);
560  foreach (QWidget *widget, gestures.keys()) {
561  QWidget *w = widget->parentWidget();
562  while (w) {
564  = w->d_func()->gestureContext.find(type);
565  if (it != w->d_func()->gestureContext.end()) {
566  // i.e. 'w' listens to gesture 'type'
567  if (!(it.value() & Qt::DontStartGestureOnChildren) && w != widget) {
568  // conflicting gesture!
569  (*conflicts)[widget].append(gestures[widget]);
570  break;
571  }
572  }
573  if (w->isWindow()) {
574  w = 0;
575  break;
576  }
577  w = w->parentWidget();
578  }
579  if (!w)
580  (*normal)[widget].append(gestures[widget]);
581  }
582  }
583 }
584 
586  QSet<QGesture *> *undeliveredGestures)
587 {
588  if (gestures.isEmpty())
589  return;
590 
591  typedef QMap<QWidget *, QList<QGesture *> > GesturesPerWidget;
592  GesturesPerWidget conflictedGestures;
593  GesturesPerWidget normalStartedGestures;
594 
595  QSet<QGesture *> startedGestures;
596  // first figure out the initial receivers of gestures
597  for (QSet<QGesture *>::const_iterator it = gestures.begin(),
598  e = gestures.end(); it != e; ++it) {
599  QGesture *gesture = *it;
600  QWidget *target = m_gestureTargets.value(gesture, 0);
601  if (!target) {
602  // the gesture has just started and doesn't have a target yet.
603  Q_ASSERT(gesture->state() == Qt::GestureStarted);
604  if (gesture->hasHotSpot()) {
605  // guess the target widget using the hotspot of the gesture
606  QPoint pt = gesture->hotSpot().toPoint();
607  if (QWidget *topLevel = qApp->topLevelAt(pt)) {
608  QWidget *child = topLevel->childAt(topLevel->mapFromGlobal(pt));
609  target = child ? child : topLevel;
610  }
611  } else {
612  // or use the context of the gesture
613  QObject *context = m_gestureOwners.value(gesture, 0);
614  if (context->isWidgetType())
615  target = static_cast<QWidget *>(context);
616  }
617  if (target)
618  m_gestureTargets.insert(gesture, target);
619  }
620 
621  Qt::GestureType gestureType = gesture->gestureType();
622  Q_ASSERT(gestureType != Qt::CustomGesture);
623  Q_UNUSED(gestureType);
624 
625  if (target) {
626  if (gesture->state() == Qt::GestureStarted) {
627  startedGestures.insert(gesture);
628  } else {
629  normalStartedGestures[target].append(gesture);
630  }
631  } else {
632  DEBUG() << "QGestureManager::deliverEvent: could not find the target for gesture"
633  << gesture->gestureType();
634  qWarning("QGestureManager::deliverEvent: could not find the target for gesture");
635  undeliveredGestures->insert(gesture);
636  }
637  }
638 
639  getGestureTargets(startedGestures, &conflictedGestures, &normalStartedGestures);
640  DEBUG() << "QGestureManager::deliverEvents:"
641  << "\nstarted: " << startedGestures
642  << "\nconflicted: " << conflictedGestures
643  << "\nnormal: " << normalStartedGestures
644  << "\n";
645 
646  // if there are conflicting gestures, send the GestureOverride event
647  for (GesturesPerWidget::const_iterator it = conflictedGestures.begin(),
648  e = conflictedGestures.end(); it != e; ++it) {
649  QWidget *receiver = it.key();
650  QList<QGesture *> gestures = it.value();
651  DEBUG() << "QGestureManager::deliverEvents: sending GestureOverride to"
652  << receiver
653  << "gestures:" << gestures;
654  QGestureEvent event(gestures);
655  event.t = QEvent::GestureOverride;
656  // mark event and individual gestures as ignored
657  event.ignore();
658  foreach(QGesture *g, gestures)
659  event.setAccepted(g, false);
660 
661  QApplication::sendEvent(receiver, &event);
662  bool eventAccepted = event.isAccepted();
663  foreach(QGesture *gesture, event.gestures()) {
664  if (eventAccepted || event.isAccepted(gesture)) {
665  QWidget *w = event.d_func()->targetWidgets.value(gesture->gestureType(), 0);
666  Q_ASSERT(w);
667  DEBUG() << "override event: gesture was accepted:" << gesture << w;
668  QList<QGesture *> &gestures = normalStartedGestures[w];
669  gestures.append(gesture);
670  // override the target
671  m_gestureTargets[gesture] = w;
672  } else {
673  DEBUG() << "override event: gesture wasn't accepted. putting back:" << gesture;
674  QList<QGesture *> &gestures = normalStartedGestures[receiver];
675  gestures.append(gesture);
676  }
677  }
678  }
679 
680  // delivering gestures that are not in conflicted state
681  for (GesturesPerWidget::const_iterator it = normalStartedGestures.begin(),
682  e = normalStartedGestures.end(); it != e; ++it) {
683  if (!it.value().isEmpty()) {
684  DEBUG() << "QGestureManager::deliverEvents: sending to" << it.key()
685  << "gestures:" << it.value();
686  QGestureEvent event(it.value());
688  bool eventAccepted = event.isAccepted();
689  foreach (QGesture *gesture, event.gestures()) {
690  if (gesture->state() == Qt::GestureStarted &&
691  (eventAccepted || event.isAccepted(gesture))) {
692  QWidget *w = event.d_func()->targetWidgets.value(gesture->gestureType(), 0);
693  Q_ASSERT(w);
694  DEBUG() << "started gesture was delivered and accepted by" << w;
695  m_gestureTargets[gesture] = w;
696  }
697  }
698  }
699  }
700 }
701 
703 {
704  QGestureRecognizer *recognizer = m_gestureToRecognizer.value(gesture, 0);
705  if (recognizer) {
707  recognizer->reset(gesture);
708  m_activeGestures.remove(gesture);
709  } else {
711  }
712 }
713 
715 
716 #endif // QT_NO_GESTURES
717 
718 #include "moc_qgesturemanager_p.cpp"
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
The QMultiMap class is a convenience QMap subclass that provides multi-valued maps.
Definition: qcontainerfwd.h:59
QWidget * parentWidget() const
Returns the parent of this widget, or 0 if it does not have any parent widget.
Definition: qwidget.h:1035
int type
Definition: qmetatype.cpp:239
void recycle(QGesture *gesture)
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
const Key key(const T &value) const
Returns the first key with value value.
Definition: qmap.h:844
QPointer< QWidget > widget
void clear()
Removes all items from the hash.
Definition: qhash.h:574
int remove(const Key &key)
Removes all the items that have the key from the hash.
Definition: qhash.h:784
#define it(className, varName)
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition: qwidget.h:945
QMap< ObjectGesture, QList< QGesture * > > m_objectGestures
QMap< Key, T >::iterator insert(const Key &key, const T &value)
Inserts a new item with the key key and a value of value.
Definition: qmap.h:982
bool remove(const T &value)
Definition: qset.h:89
bool isEmpty() const
Definition: qset.h:77
QList< T > values() const
Returns a list containing all the values in the map, in ascending order of their keys.
Definition: qmap.h:863
bool filterEvent(QWidget *receiver, QEvent *event)
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
QGesture::GestureCancelPolicy gestureCancelPolicy
the policy for deciding what happens on accepting a gesture
Definition: qgesture.h:71
bool filterEventThroughContexts(const QMultiMap< QObject *, Qt::GestureType > &contexts, QEvent *event)
QHash< QGestureRecognizer *, QSet< QGesture * > > m_obsoleteGestures
QHash< QGesture *, QGestureRecognizer * > m_deletedRecognizers
QGestureManager(QObject *parent)
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
void cleanupCachedGestures(QObject *target, Qt::GestureType type)
void cleanupGesturesForRemovedRecognizer(QGesture *gesture)
virtual bool event(QEvent *)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition: qobject.cpp:1200
iterator begin()
Definition: qset.h:166
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
Definition: qhash.h:872
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
void setParent(QObject *)
Makes the object a child of parent.
Definition: qobject.cpp:1950
void setObjectName(const QString &name)
Definition: qobject.cpp:1112
iterator insertMulti(const Key &key, const T &value)
Inserts a new item with the key key and a value of value.
Definition: qmap.h:595
void deliverEvents(const QSet< QGesture *> &gestures, QSet< QGesture *> *undeliveredGestures)
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
virtual void reset(QGesture *state)
This function is called by the framework to reset a given gesture.
The QGestureEvent class provides the description of triggered gestures.
Definition: qevent.h:841
QBool contains(const T &t) const
Returns true if the list contains an occurrence of value; otherwise returns false.
Definition: qlist.h:880
virtual Result recognize(QGesture *state, QObject *watched, QEvent *event)=0
Handles the given event for the watched object, updating the state of the gesture object as required...
void unregisterGestureRecognizer(Qt::GestureType type)
static bool isEmpty(const char *str)
bool contains(const T &value) const
Definition: qset.h:91
#define qApp
QSet< QGesture * > m_gesturesToDelete
QWidget * childAt(int x, int y) const
Returns the visible child widget at the position ({x}, {y}) in the widget&#39;s coordinate system...
Definition: qwidget.h:934
const T value(const Key &key) const
Returns the value associated with the key key.
Definition: qmap.h:499
QGraphicsObject * parentObject() const
Returns a pointer to the item&#39;s parent, cast to a QGraphicsObject.
static QWidget * find(WId)
Returns a pointer to the widget with window identifer/handle id.
Definition: qwidget.cpp:2517
iterator end()
Definition: qset.h:169
Q_CORE_EXPORT void qWarning(const char *,...)
const_iterator insert(const T &value)
Definition: qset.h:179
void clear()
Definition: qset.h:87
static bool HasTouchSupport
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
QList< QGesture * > gestures() const
Returns all gestures that are delivered in the event.
Definition: qevent.cpp:4873
virtual QGesture * create(QObject *target)
This function is called by Qt to create a new QGesture object for the given target (QWidget or QGraph...
enum QGestureManager::State state
GestureType
Definition: qnamespace.h:1759
void getGestureTargets(const QSet< QGesture *> &gestures, QMap< QWidget *, QList< QGesture *> > *conflicts, QMap< QWidget *, QList< QGesture *> > *normal)
Qt::GestureType registerGestureRecognizer(QGestureRecognizer *recognizer)
QHash< QGesture *, QWidget * > m_gestureTargets
The QMap::const_iterator class provides an STL-style const iterator for QMap and QMultiMap.
Definition: qmap.h:301
QHash< QGesture *, QGestureRecognizer * > m_gestureToRecognizer
bool isWidgetType() const
Returns true if the object is a widget; otherwise returns false.
Definition: qobject.h:146
QHash< QGesture *, QObject * > m_gestureOwners
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:467
static const struct @32 types[]
The QGesture class represents a gesture, containing properties that describe the corresponding user i...
Definition: qgesture.h:64
QPointF hotSpot
The point that is used to find the receiver for the gesture event.
Definition: qgesture.h:72
Qt::GestureType gestureType
the type of the gesture
Definition: qgesture.h:70
QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
Definition: qpoint.h:376
#define DEBUG
iterator insert(const Key &key, const T &value)
Inserts a new item with the key key and a value of value.
Definition: qmap.h:559
QGesture * getState(QObject *widget, QGestureRecognizer *recognizer, Qt::GestureType gesture)
QSet< QGesture * > m_activeGestures
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
bool isEmpty() const
Returns true if the map contains no items; otherwise returns false.
Definition: qmap.h:203
The QGestureRecognizer class provides the infrastructure for gesture recognition. ...
bool isAncestorOf(const QWidget *child) const
Returns true if this widget is a parent, (or grandparent and so on to any level), of the given child...
Definition: qwidget.cpp:8573
Definition: qnamespace.h:54
iterator begin()
Returns an STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:464
const T & value() const
Returns the current item&#39;s value.
Definition: qmap.h:325
bool contains(const Key &key) const
Returns true if the map contains an item with key key; otherwise returns false.
Definition: qmap.h:553
void setGestureCancelPolicy(GestureCancelPolicy policy)
Definition: qgesture.cpp:226
bool isAccepted(QGesture *) const
Returns true if the gesture is accepted; otherwise returns false.
Definition: qevent.cpp:4968
iterator upperBound(const Key &key)
Returns an iterator pointing to the item that immediately follows the last item with key key in the m...
Definition: qmap.h:918
Qt::GestureState state
the current state of the gesture
Definition: qgesture.h:69
T take(const Key &key)
Removes the item with the key key from the map and returns the value associated with it...
Definition: qmap.h:692
iterator lowerBound(const Key &key)
Returns an iterator pointing to the first item with key key in the map.
Definition: qmap.h:899
QMultiMap< Qt::GestureType, QGestureRecognizer * > m_recognizers
iterator erase(iterator i)
Definition: qset.h:172
The QGraphicsObject class provides a base class for all graphics items that require signals...
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
Q_OUTOFLINE_TEMPLATE void qDeleteAll(ForwardIterator begin, ForwardIterator end)
Definition: qalgorithms.h:319
void cancelGesturesForChildren(QGesture *originatingGesture)
bool hasHotSpot
whether the gesture has a hot-spot
Definition: qgesture.h:73
QList< Key > keys() const
Returns a list containing all the keys in the hash, in an arbitrary order.
Definition: qhash.h:648
The QMap class is a template class that provides a skip-list-based dictionary.
Definition: qdatastream.h:67
QSet< QGesture * > m_maybeGestures
The QList class is a template class that provides lists.
Definition: qdatastream.h:62