src/gui/kernel/qgesturemanager.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
    50 #include "qgraphicsitem.h"
    50 #include "qgraphicsitem.h"
    51 
    51 
    52 #ifdef Q_WS_MAC
    52 #ifdef Q_WS_MAC
    53 #include "qmacgesturerecognizer_mac_p.h"
    53 #include "qmacgesturerecognizer_mac_p.h"
    54 #endif
    54 #endif
       
    55 #if defined(Q_OS_WIN) && !defined(QT_NO_NATIVE_GESTURES)
       
    56 #include "qwinnativepangesturerecognizer_win_p.h"
       
    57 #endif
    55 
    58 
    56 #include "qdebug.h"
    59 #include "qdebug.h"
    57 
    60 
    58 // #define GESTURE_DEBUG
    61 // #define GESTURE_DEBUG
    59 #ifndef GESTURE_DEBUG
    62 #ifndef GESTURE_DEBUG
    62 # define DEBUG qDebug
    65 # define DEBUG qDebug
    63 #endif
    66 #endif
    64 
    67 
    65 QT_BEGIN_NAMESPACE
    68 QT_BEGIN_NAMESPACE
    66 
    69 
       
    70 QGestureManager *qt_gestureManager = 0;
       
    71 
       
    72 QGestureManager* QGestureManager::instance()
       
    73 {
       
    74     if (!qt_gestureManager)
       
    75         qt_gestureManager = new QGestureManager(qApp);
       
    76     return qt_gestureManager;
       
    77 }
       
    78 
    67 QGestureManager::QGestureManager(QObject *parent)
    79 QGestureManager::QGestureManager(QObject *parent)
    68     : QObject(parent), state(NotGesture), lastCustomGestureId(0)
    80     : QObject(parent), state(NotGesture), m_lastCustomGestureId(0)
    69 {
    81 {
    70     qRegisterMetaType<Qt::GestureState>();
    82     qRegisterMetaType<Qt::GestureState>();
    71 
    83 
    72 #if defined(Q_WS_MAC)
    84 #if defined(Q_WS_MAC)
    73     registerGestureRecognizer(new QMacSwipeGestureRecognizer);
    85     registerGestureRecognizer(new QMacSwipeGestureRecognizer);
    75   #if defined(QT_MAC_USE_COCOA)
    87   #if defined(QT_MAC_USE_COCOA)
    76     registerGestureRecognizer(new QMacPanGestureRecognizer);
    88     registerGestureRecognizer(new QMacPanGestureRecognizer);
    77   #endif
    89   #endif
    78 #else
    90 #else
    79     registerGestureRecognizer(new QPanGestureRecognizer);
    91     registerGestureRecognizer(new QPanGestureRecognizer);
       
    92     registerGestureRecognizer(new QPinchGestureRecognizer);
       
    93     registerGestureRecognizer(new QSwipeGestureRecognizer);
       
    94     registerGestureRecognizer(new QTapGestureRecognizer);
    80 #endif
    95 #endif
       
    96 #if defined(Q_OS_WIN)
       
    97   #if !defined(QT_NO_NATIVE_GESTURES)
       
    98     registerGestureRecognizer(new QWinNativePanGestureRecognizer);
       
    99   #endif
       
   100 #else
       
   101     registerGestureRecognizer(new QTapAndHoldGestureRecognizer);
       
   102 #endif
    81 }
   103 }
    82 
   104 
    83 QGestureManager::~QGestureManager()
   105 QGestureManager::~QGestureManager()
    84 {
   106 {
    85 
   107     qDeleteAll(m_recognizers.values());
       
   108     foreach (QGestureRecognizer *recognizer, m_obsoleteGestures.keys()) {
       
   109         qDeleteAll(m_obsoleteGestures.value(recognizer));
       
   110         delete recognizer;
       
   111     }
       
   112     m_obsoleteGestures.clear();
    86 }
   113 }
    87 
   114 
    88 Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer)
   115 Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer)
    89 {
   116 {
    90     QGesture *dummy = recognizer->createGesture(0);
   117     QGesture *dummy = recognizer->create(0);
    91     if (!dummy) {
   118     if (!dummy) {
    92         qWarning("QGestureManager::registerGestureRecognizer: "
   119         qWarning("QGestureManager::registerGestureRecognizer: "
    93                  "the recognizer fails to create a gesture object, skipping registration.");
   120                  "the recognizer fails to create a gesture object, skipping registration.");
    94         return Qt::GestureType(0);
   121         return Qt::GestureType(0);
    95     }
   122     }
    96     Qt::GestureType type = dummy->gestureType();
   123     Qt::GestureType type = dummy->gestureType();
    97     if (type == Qt::CustomGesture) {
   124     if (type == Qt::CustomGesture) {
    98         // generate a new custom gesture id
   125         // generate a new custom gesture id
    99         ++lastCustomGestureId;
   126         ++m_lastCustomGestureId;
   100         type = Qt::GestureType(Qt::CustomGesture + lastCustomGestureId);
   127         type = Qt::GestureType(Qt::CustomGesture + m_lastCustomGestureId);
   101     }
   128     }
   102     recognizers.insertMulti(type, recognizer);
   129     m_recognizers.insertMulti(type, recognizer);
   103     delete dummy;
   130     delete dummy;
   104     return type;
   131     return type;
   105 }
   132 }
   106 
   133 
   107 void QGestureManager::unregisterGestureRecognizer(Qt::GestureType)
   134 void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type)
   108 {
   135 {
   109 
   136     QList<QGestureRecognizer *> list = m_recognizers.values(type);
   110 }
   137     m_recognizers.remove(type);
   111 
   138     foreach (QGesture *g, m_gestureToRecognizer.keys()) {
   112 QGesture *QGestureManager::getState(QObject *object, Qt::GestureType type)
   139         QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g);
       
   140         if (list.contains(recognizer)) {
       
   141             m_deletedRecognizers.insert(g, recognizer);
       
   142             m_gestureToRecognizer.remove(g);
       
   143         }
       
   144     }
       
   145 
       
   146     foreach (QGestureRecognizer *recognizer, list) {
       
   147         QList<QGesture *> obsoleteGestures;
       
   148         QMap<ObjectGesture, QList<QGesture *> >::Iterator iter = m_objectGestures.begin();
       
   149         while (iter != m_objectGestures.end()) {
       
   150             ObjectGesture objectGesture = iter.key();
       
   151             if (objectGesture.gesture == type)
       
   152                 obsoleteGestures << iter.value();
       
   153             ++iter;
       
   154         }
       
   155         m_obsoleteGestures.insert(recognizer, obsoleteGestures);
       
   156     }
       
   157 }
       
   158 
       
   159 void QGestureManager::cleanupCachedGestures(QObject *target, Qt::GestureType type)
       
   160 {
       
   161     QMap<ObjectGesture, QList<QGesture *> >::Iterator iter = m_objectGestures.begin();
       
   162     while (iter != m_objectGestures.end()) {
       
   163         ObjectGesture objectGesture = iter.key();
       
   164         if (objectGesture.gesture == type && target == objectGesture.object.data()) {
       
   165             qDeleteAll(iter.value());
       
   166             iter = m_objectGestures.erase(iter);
       
   167         } else {
       
   168             ++iter;
       
   169         }
       
   170     }
       
   171 }
       
   172 
       
   173 // get or create a QGesture object that will represent the state for a given object, used by the recognizer
       
   174 QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recognizer, Qt::GestureType type)
   113 {
   175 {
   114     // if the widget is being deleted we should be carefull and not to
   176     // if the widget is being deleted we should be carefull and not to
   115     // create a new state, as it will create QWeakPointer which doesnt work
   177     // create a new state, as it will create QWeakPointer which doesnt work
   116     // from the destructor.
   178     // from the destructor.
   117     if (object->isWidgetType()) {
   179     if (object->isWidgetType()) {
   118         if (static_cast<QWidget *>(object)->d_func()->data.in_destructor)
   180         if (static_cast<QWidget *>(object)->d_func()->data.in_destructor)
   119             return 0;
   181             return 0;
   120     } else if (QGesture *g = qobject_cast<QGesture *>(object)) {
   182     } else if (QGesture *g = qobject_cast<QGesture *>(object)) {
   121         return g;
   183         return g;
       
   184 #ifndef QT_NO_GRAPHICSVIEW
   122     } else {
   185     } else {
   123         Q_ASSERT(qobject_cast<QGraphicsObject *>(object));
   186         Q_ASSERT(qobject_cast<QGraphicsObject *>(object));
   124     }
   187 #endif
   125 
   188     }
   126     QGesture *state =
   189 
   127             objectGestures.value(QGestureManager::ObjectGesture(object, type));
   190     // check if the QGesture for this recognizer has already been created
   128     if (!state) {
   191     foreach (QGesture *state, m_objectGestures.value(QGestureManager::ObjectGesture(object, type))) {
   129         QGestureRecognizer *recognizer = recognizers.value(type);
   192         if (m_gestureToRecognizer.value(state) == recognizer)
   130         if (recognizer) {
   193             return state;
   131             state = recognizer->createGesture(object);
   194     }
   132             if (!state)
   195 
   133                 return 0;
   196     Q_ASSERT(recognizer);
   134             if (state->gestureType() == Qt::CustomGesture) {
   197     QGesture *state = recognizer->create(object);
   135                 // if the recognizer didn't fill in the gesture type, then this
   198     if (!state)
   136                 // is a custom gesture with autogenerated it and we fill it.
   199         return 0;
   137                 state->d_func()->gestureType = type;
   200     state->setParent(this);
       
   201     if (state->gestureType() == Qt::CustomGesture) {
       
   202         // if the recognizer didn't fill in the gesture type, then this
       
   203         // is a custom gesture with autogenerated id and we fill it.
       
   204         state->d_func()->gestureType = type;
   138 #if defined(GESTURE_DEBUG)
   205 #if defined(GESTURE_DEBUG)
   139                 state->setObjectName(QString::number((int)type));
   206         state->setObjectName(QString::number((int)type));
   140 #endif
   207 #endif
   141             }
   208     }
   142             objectGestures.insert(QGestureManager::ObjectGesture(object, type), state);
   209     m_objectGestures[QGestureManager::ObjectGesture(object, type)].append(state);
   143             gestureToRecognizer[state] = recognizer;
   210     m_gestureToRecognizer[state] = recognizer;
   144             gestureOwners[state] = object;
   211     m_gestureOwners[state] = object;
   145         }
   212 
   146     }
       
   147     return state;
   213     return state;
   148 }
   214 }
   149 
   215 
   150 bool QGestureManager::filterEventThroughContexts(const QMap<QObject *,
   216 bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *,
   151                                                  Qt::GestureType> &contexts,
   217                                                  Qt::GestureType> &contexts,
   152                                                  QEvent *event)
   218                                                  QEvent *event)
   153 {
   219 {
   154     QSet<QGesture *> triggeredGestures;
   220     QSet<QGesture *> triggeredGestures;
   155     QSet<QGesture *> finishedGestures;
   221     QSet<QGesture *> finishedGestures;
   156     QSet<QGesture *> newMaybeGestures;
   222     QSet<QGesture *> newMaybeGestures;
   157     QSet<QGesture *> canceledGestures;
       
   158     QSet<QGesture *> notGestures;
   223     QSet<QGesture *> notGestures;
   159 
   224 
   160     // TODO: sort contexts by the gesture type and check if one of the contexts
   225     // TODO: sort contexts by the gesture type and check if one of the contexts
   161     //       is already active.
   226     //       is already active.
   162 
   227 
       
   228     bool ret = false;
       
   229 
   163     // filter the event through recognizers
   230     // filter the event through recognizers
   164     typedef QMap<QObject *, Qt::GestureType>::const_iterator ContextIterator;
   231     typedef QMultiMap<QObject *, Qt::GestureType>::const_iterator ContextIterator;
   165     for (ContextIterator cit = contexts.begin(), ce = contexts.end(); cit != ce; ++cit) {
   232     for (ContextIterator cit = contexts.begin(), ce = contexts.end(); cit != ce; ++cit) {
   166         Qt::GestureType gestureType = cit.value();
   233         Qt::GestureType gestureType = cit.value();
   167         QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator
   234         QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator
   168                 rit = recognizers.lowerBound(gestureType),
   235                 rit = m_recognizers.lowerBound(gestureType),
   169                 re = recognizers.upperBound(gestureType);
   236                 re = m_recognizers.upperBound(gestureType);
   170         for (; rit != re; ++rit) {
   237         for (; rit != re; ++rit) {
   171             QGestureRecognizer *recognizer = rit.value();
   238             QGestureRecognizer *recognizer = rit.value();
   172             QObject *target = cit.key();
   239             QObject *target = cit.key();
   173             QGesture *state = getState(target, gestureType);
   240             QGesture *state = getState(target, recognizer, gestureType);
   174             if (!state)
   241             if (!state)
   175                 continue;
   242                 continue;
   176             QGestureRecognizer::Result result = recognizer->filterEvent(state, target, event);
   243             QGestureRecognizer::Result result = recognizer->recognize(state, target, event);
   177             QGestureRecognizer::Result type = result & QGestureRecognizer::ResultState_Mask;
   244             QGestureRecognizer::Result type = result & QGestureRecognizer::ResultState_Mask;
   178             if (type == QGestureRecognizer::GestureTriggered) {
   245             result &= QGestureRecognizer::ResultHint_Mask;
   179                 DEBUG() << "QGestureManager: gesture triggered: " << state;
   246             if (type == QGestureRecognizer::TriggerGesture) {
       
   247                 DEBUG() << "QGestureManager:Recognizer: gesture triggered: " << state;
   180                 triggeredGestures << state;
   248                 triggeredGestures << state;
   181             } else if (type == QGestureRecognizer::GestureFinished) {
   249             } else if (type == QGestureRecognizer::FinishGesture) {
   182                 DEBUG() << "QGestureManager: gesture finished: " << state;
   250                 DEBUG() << "QGestureManager:Recognizer: gesture finished: " << state;
   183                 finishedGestures << state;
   251                 finishedGestures << state;
   184             } else if (type == QGestureRecognizer::MaybeGesture) {
   252             } else if (type == QGestureRecognizer::MayBeGesture) {
   185                 DEBUG() << "QGestureManager: maybe gesture: " << state;
   253                 DEBUG() << "QGestureManager:Recognizer: maybe gesture: " << state;
   186                 newMaybeGestures << state;
   254                 newMaybeGestures << state;
   187             } else if (type == QGestureRecognizer::NotGesture) {
   255             } else if (type == QGestureRecognizer::CancelGesture) {
   188                 DEBUG() << "QGestureManager: not gesture: " << state;
   256                 DEBUG() << "QGestureManager:Recognizer: not gesture: " << state;
   189                 notGestures << state;
   257                 notGestures << state;
   190             } else if (type == QGestureRecognizer::Ignore) {
   258             } else if (type == QGestureRecognizer::Ignore) {
   191                 DEBUG() << "QGestureManager: gesture ignored the event: " << state;
   259                 DEBUG() << "QGestureManager:Recognizer: ignored the event: " << state;
   192             } else {
   260             } else {
   193                 DEBUG() << "QGestureManager: hm, lets assume the recognizer"
   261                 DEBUG() << "QGestureManager:Recognizer: hm, lets assume the recognizer"
   194                         << "ignored the event: " << state;
   262                         << "ignored the event: " << state;
   195             }
   263             }
   196             if (result & QGestureRecognizer::ConsumeEventHint) {
   264             if (result & QGestureRecognizer::ConsumeEventHint) {
   197                 DEBUG() << "QGestureManager: we were asked to consume the event: "
   265                 DEBUG() << "QGestureManager: we were asked to consume the event: "
   198                         << state;
   266                         << state;
   199                 //TODO: consume events if asked
   267                 ret = true;
   200             }
   268             }
   201         }
   269         }
   202     }
   270     }
   203 
   271     if (triggeredGestures.isEmpty() && finishedGestures.isEmpty()
   204     QSet<QGesture *> startedGestures = triggeredGestures - activeGestures;
   272         && newMaybeGestures.isEmpty() && notGestures.isEmpty())
   205     triggeredGestures &= activeGestures;
   273         return ret;
       
   274 
       
   275     QSet<QGesture *> startedGestures = triggeredGestures - m_activeGestures;
       
   276     triggeredGestures &= m_activeGestures;
   206 
   277 
   207     // check if a running gesture switched back to maybe state
   278     // check if a running gesture switched back to maybe state
   208     QSet<QGesture *> activeToMaybeGestures = activeGestures & newMaybeGestures;
   279     QSet<QGesture *> activeToMaybeGestures = m_activeGestures & newMaybeGestures;
   209 
   280 
   210     // check if a running gesture switched back to not gesture state,
   281     // check if a running gesture switched back to not gesture state,
   211     // i.e. were canceled
   282     // i.e. were canceled
   212     QSet<QGesture *> activeToCancelGestures = activeGestures & notGestures;
   283     QSet<QGesture *> canceledGestures = m_activeGestures & notGestures;
   213     canceledGestures += activeToCancelGestures;
       
   214 
   284 
   215     // start timers for new gestures in maybe state
   285     // start timers for new gestures in maybe state
   216     foreach (QGesture *state, newMaybeGestures) {
   286     foreach (QGesture *state, newMaybeGestures) {
   217         QBasicTimer &timer = maybeGestures[state];
   287         QBasicTimer &timer = m_maybeGestures[state];
   218         if (!timer.isActive())
   288         if (!timer.isActive())
   219             timer.start(3000, this);
   289             timer.start(3000, this);
   220     }
   290     }
   221     // kill timers for gestures that were in maybe state
   291     // kill timers for gestures that were in maybe state
   222     QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures
   292     QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures
   223                                          | finishedGestures | canceledGestures
   293                                          | finishedGestures | canceledGestures
   224                                          | notGestures);
   294                                          | notGestures);
   225     foreach(QGesture *gesture, notMaybeGestures) {
   295     foreach(QGesture *gesture, notMaybeGestures) {
   226         QMap<QGesture *, QBasicTimer>::iterator it =
   296         QHash<QGesture *, QBasicTimer>::iterator it =
   227                 maybeGestures.find(gesture);
   297                 m_maybeGestures.find(gesture);
   228         if (it != maybeGestures.end()) {
   298         if (it != m_maybeGestures.end()) {
   229             it.value().stop();
   299             it.value().stop();
   230             maybeGestures.erase(it);
   300             m_maybeGestures.erase(it);
   231         }
   301         }
   232     }
   302     }
   233 
   303 
   234     Q_ASSERT((startedGestures & finishedGestures).isEmpty());
   304     Q_ASSERT((startedGestures & finishedGestures).isEmpty());
   235     Q_ASSERT((startedGestures & newMaybeGestures).isEmpty());
   305     Q_ASSERT((startedGestures & newMaybeGestures).isEmpty());
   236     Q_ASSERT((startedGestures & canceledGestures).isEmpty());
   306     Q_ASSERT((startedGestures & canceledGestures).isEmpty());
   237     Q_ASSERT((finishedGestures & newMaybeGestures).isEmpty());
   307     Q_ASSERT((finishedGestures & newMaybeGestures).isEmpty());
   238     Q_ASSERT((finishedGestures & canceledGestures).isEmpty());
   308     Q_ASSERT((finishedGestures & canceledGestures).isEmpty());
   239     Q_ASSERT((canceledGestures & newMaybeGestures).isEmpty());
   309     Q_ASSERT((canceledGestures & newMaybeGestures).isEmpty());
   240 
   310 
   241     QSet<QGesture *> notStarted = finishedGestures - activeGestures;
   311     QSet<QGesture *> notStarted = finishedGestures - m_activeGestures;
   242     if (!notStarted.isEmpty()) {
   312     if (!notStarted.isEmpty()) {
   243         // there are some gestures that claim to be finished, but never started.
   313         // there are some gestures that claim to be finished, but never started.
   244         // probably those are "singleshot" gestures so we'll fake the started state.
   314         // probably those are "singleshot" gestures so we'll fake the started state.
   245         foreach (QGesture *gesture, notStarted)
   315         foreach (QGesture *gesture, notStarted)
   246             gesture->d_func()->state = Qt::GestureStarted;
   316             gesture->d_func()->state = Qt::GestureStarted;
   247         QSet<QGesture *> undeliveredGestures;
   317         QSet<QGesture *> undeliveredGestures;
   248         deliverEvents(notStarted, &undeliveredGestures);
   318         deliverEvents(notStarted, &undeliveredGestures);
   249         finishedGestures -= undeliveredGestures;
   319         finishedGestures -= undeliveredGestures;
   250     }
   320     }
   251 
   321 
   252     activeGestures += startedGestures;
   322     m_activeGestures += startedGestures;
   253     // sanity check: all triggered gestures should already be in active gestures list
   323     // sanity check: all triggered gestures should already be in active gestures list
   254     Q_ASSERT((activeGestures & triggeredGestures).size() == triggeredGestures.size());
   324     Q_ASSERT((m_activeGestures & triggeredGestures).size() == triggeredGestures.size());
   255     activeGestures -= finishedGestures;
   325     m_activeGestures -= finishedGestures;
   256     activeGestures -= activeToMaybeGestures;
   326     m_activeGestures -= activeToMaybeGestures;
   257     activeGestures -= canceledGestures;
   327     m_activeGestures -= canceledGestures;
   258 
   328 
   259     // set the proper gesture state on each gesture
   329     // set the proper gesture state on each gesture
   260     foreach (QGesture *gesture, startedGestures)
   330     foreach (QGesture *gesture, startedGestures)
   261         gesture->d_func()->state = Qt::GestureStarted;
   331         gesture->d_func()->state = Qt::GestureStarted;
   262     foreach (QGesture *gesture, triggeredGestures)
   332     foreach (QGesture *gesture, triggeredGestures)
   266     foreach (QGesture *gesture, canceledGestures)
   336     foreach (QGesture *gesture, canceledGestures)
   267         gesture->d_func()->state = Qt::GestureCanceled;
   337         gesture->d_func()->state = Qt::GestureCanceled;
   268     foreach (QGesture *gesture, activeToMaybeGestures)
   338     foreach (QGesture *gesture, activeToMaybeGestures)
   269         gesture->d_func()->state = Qt::GestureFinished;
   339         gesture->d_func()->state = Qt::GestureFinished;
   270 
   340 
   271     if (!activeGestures.isEmpty() || !maybeGestures.isEmpty() ||
   341     if (!m_activeGestures.isEmpty() || !m_maybeGestures.isEmpty() ||
   272         !startedGestures.isEmpty() || !triggeredGestures.isEmpty() ||
   342         !startedGestures.isEmpty() || !triggeredGestures.isEmpty() ||
   273         !finishedGestures.isEmpty() || !canceledGestures.isEmpty()) {
   343         !finishedGestures.isEmpty() || !canceledGestures.isEmpty()) {
   274         DEBUG() << "QGestureManager::filterEvent:"
   344         DEBUG() << "QGestureManager::filterEventThroughContexts:"
   275                 << "\n\tactiveGestures:" << activeGestures
   345                 << "\n\tactiveGestures:" << m_activeGestures
   276                 << "\n\tmaybeGestures:" << maybeGestures.keys()
   346                 << "\n\tmaybeGestures:" << m_maybeGestures.keys()
   277                 << "\n\tstarted:" << startedGestures
   347                 << "\n\tstarted:" << startedGestures
   278                 << "\n\ttriggered:" << triggeredGestures
   348                 << "\n\ttriggered:" << triggeredGestures
   279                 << "\n\tfinished:" << finishedGestures
   349                 << "\n\tfinished:" << finishedGestures
   280                 << "\n\tcanceled:" << canceledGestures;
   350                 << "\n\tcanceled:" << canceledGestures;
   281     }
   351     }
   282 
   352 
   283     QSet<QGesture *> undeliveredGestures;
   353     QSet<QGesture *> undeliveredGestures;
   284     deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures,
   354     deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures,
   285                   &undeliveredGestures);
   355                   &undeliveredGestures);
   286 
   356 
   287     activeGestures -= undeliveredGestures;
   357     foreach (QGesture *g, startedGestures) {
       
   358         if (undeliveredGestures.contains(g))
       
   359             continue;
       
   360         if (g->gestureCancelPolicy() == QGesture::CancelAllInContext) {
       
   361             DEBUG() << "lets try to cancel some";
       
   362             // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them
       
   363             cancelGesturesForChildren(g);
       
   364         }
       
   365     }
       
   366 
       
   367     m_activeGestures -= undeliveredGestures;
   288 
   368 
   289     // reset gestures that ended
   369     // reset gestures that ended
   290     QSet<QGesture *> endedGestures =
   370     QSet<QGesture *> endedGestures =
   291             finishedGestures + canceledGestures + undeliveredGestures;
   371             finishedGestures + canceledGestures + undeliveredGestures;
   292     foreach (QGesture *gesture, endedGestures) {
   372     foreach (QGesture *gesture, endedGestures) {
   293         if (QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0)) {
   373         recycle(gesture);
   294             recognizer->reset(gesture);
   374         m_gestureTargets.remove(gesture);
   295         }
   375     }
   296         gestureTargets.remove(gesture);
   376     return ret;
   297     }
   377 }
   298     return false;
   378 
   299 }
   379 // Cancel all gestures of children of the widget that original is associated with
   300 
   380 void QGestureManager::cancelGesturesForChildren(QGesture *original)
       
   381 {
       
   382     Q_ASSERT(original);
       
   383     QWidget *originatingWidget = m_gestureTargets.value(original);
       
   384     Q_ASSERT(originatingWidget);
       
   385 
       
   386     // iterate over all active gestures and all maybe gestures
       
   387     // for each find the owner
       
   388     // if the owner is part of our sub-hierarchy, cancel it.
       
   389 
       
   390     QSet<QGesture*> cancelledGestures;
       
   391     QSet<QGesture*>::Iterator iter = m_activeGestures.begin();
       
   392     while (iter != m_activeGestures.end()) {
       
   393         QWidget *widget = m_gestureTargets.value(*iter);
       
   394         // note that we don't touch the gestures for our originatingWidget
       
   395         if (widget != originatingWidget && originatingWidget->isAncestorOf(widget)) {
       
   396             DEBUG() << "  found a gesture to cancel" << (*iter);
       
   397             (*iter)->d_func()->state = Qt::GestureCanceled;
       
   398             cancelledGestures << *iter;
       
   399             iter = m_activeGestures.erase(iter);
       
   400         } else {
       
   401             ++iter;
       
   402         }
       
   403     }
       
   404 
       
   405     // TODO handle 'maybe' gestures too
       
   406 
       
   407     // sort them per target widget by cherry picking from almostCanceledGestures and delivering
       
   408     QSet<QGesture *> almostCanceledGestures = cancelledGestures;
       
   409     while (!almostCanceledGestures.isEmpty()) {
       
   410         QWidget *target = 0;
       
   411         QSet<QGesture*> gestures;
       
   412         iter = almostCanceledGestures.begin();
       
   413         // sort per target widget
       
   414         while (iter != almostCanceledGestures.end()) {
       
   415             QWidget *widget = m_gestureTargets.value(*iter);
       
   416             if (target == 0)
       
   417                 target = widget;
       
   418             if (target == widget) {
       
   419                 gestures << *iter;
       
   420                 iter = almostCanceledGestures.erase(iter);
       
   421             } else {
       
   422                 ++iter;
       
   423             }
       
   424         }
       
   425         Q_ASSERT(target);
       
   426 
       
   427         QSet<QGesture*> undeliveredGestures;
       
   428         deliverEvents(gestures, &undeliveredGestures);
       
   429     }
       
   430 
       
   431     for (iter = cancelledGestures.begin(); iter != cancelledGestures.end(); ++iter)
       
   432         recycle(*iter);
       
   433 }
       
   434 
       
   435 void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture)
       
   436 {
       
   437     QGestureRecognizer *recognizer = m_deletedRecognizers.value(gesture);
       
   438     Q_ASSERT(recognizer);
       
   439     m_deletedRecognizers.remove(gesture);
       
   440     if (m_deletedRecognizers.keys(recognizer).isEmpty()) {
       
   441         // no more active gestures, cleanup!
       
   442         qDeleteAll(m_obsoleteGestures.value(recognizer));
       
   443         m_obsoleteGestures.remove(recognizer);
       
   444         delete recognizer;
       
   445     }
       
   446 }
       
   447 
       
   448 // return true if accepted (consumed)
   301 bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
   449 bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
   302 {
   450 {
   303     QSet<Qt::GestureType> types;
   451     QMap<Qt::GestureType, int> types;
   304     QMap<QObject *, Qt::GestureType> contexts;
   452     QMultiMap<QObject *, Qt::GestureType> contexts;
   305     QWidget *w = receiver;
   453     QWidget *w = receiver;
   306     typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
   454     typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
   307     if (!w->d_func()->gestureContext.isEmpty()) {
   455     if (!w->d_func()->gestureContext.isEmpty()) {
   308         for(ContextIterator it = w->d_func()->gestureContext.begin(),
   456         for(ContextIterator it = w->d_func()->gestureContext.begin(),
   309             e = w->d_func()->gestureContext.end(); it != e; ++it) {
   457             e = w->d_func()->gestureContext.end(); it != e; ++it) {
   310             types.insert(it.key());
   458             types.insert(it.key(), 0);
   311             contexts.insertMulti(w, it.key());
   459             contexts.insertMulti(w, it.key());
   312         }
   460         }
   313     }
   461     }
   314     // find all gesture contexts for the widget tree
   462     // find all gesture contexts for the widget tree
   315     w = w->isWindow() ? 0 : w->parentWidget();
   463     w = w->isWindow() ? 0 : w->parentWidget();
   316     while (w)
   464     while (w)
   317     {
   465     {
   318         for (ContextIterator it = w->d_func()->gestureContext.begin(),
   466         for (ContextIterator it = w->d_func()->gestureContext.begin(),
   319              e = w->d_func()->gestureContext.end(); it != e; ++it) {
   467              e = w->d_func()->gestureContext.end(); it != e; ++it) {
   320             if (it.value() == Qt::WidgetWithChildrenGesture) {
   468             if (!(it.value() & Qt::DontStartGestureOnChildren)) {
   321                 if (!types.contains(it.key())) {
   469                 if (!types.contains(it.key())) {
   322                     types.insert(it.key());
   470                     types.insert(it.key(), 0);
   323                     contexts.insertMulti(w, it.key());
   471                     contexts.insertMulti(w, it.key());
   324                 }
   472                 }
   325             }
   473             }
   326         }
   474         }
   327         if (w->isWindow())
   475         if (w->isWindow())
   328             break;
   476             break;
   329         w = w->parentWidget();
   477         w = w->parentWidget();
   330     }
   478     }
   331     return filterEventThroughContexts(contexts, event);
   479     return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event);
   332 }
   480 }
   333 
   481 
       
   482 #ifndef QT_NO_GRAPHICSVIEW
   334 bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event)
   483 bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event)
   335 {
   484 {
   336     QSet<Qt::GestureType> types;
   485     QMap<Qt::GestureType, int> types;
   337     QMap<QObject *, Qt::GestureType> contexts;
   486     QMultiMap<QObject *, Qt::GestureType> contexts;
   338     QGraphicsObject *item = receiver;
   487     QGraphicsObject *item = receiver;
   339     if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) {
   488     if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) {
   340         typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
   489         typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
   341         for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
   490         for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
   342             e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
   491             e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
   343             types.insert(it.key());
   492             types.insert(it.key(), 0);
   344             contexts.insertMulti(item, it.key());
   493             contexts.insertMulti(item, it.key());
   345         }
   494         }
   346     }
   495     }
   347     // find all gesture contexts for the graphics object tree
   496     // find all gesture contexts for the graphics object tree
   348     item = item->parentObject();
   497     item = item->parentObject();
   349     while (item)
   498     while (item)
   350     {
   499     {
   351         typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
   500         typedef QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator ContextIterator;
   352         for (ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
   501         for (ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
   353              e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
   502              e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
   354             if (it.value() == Qt::ItemWithChildrenGesture) {
   503             if (!(it.value() & Qt::DontStartGestureOnChildren)) {
   355                 if (!types.contains(it.key()))
   504                 if (!types.contains(it.key())) {
       
   505                     types.insert(it.key(), 0);
   356                     contexts.insertMulti(item, it.key());
   506                     contexts.insertMulti(item, it.key());
       
   507                 }
   357             }
   508             }
   358         }
   509         }
   359         item = item->parentObject();
   510         item = item->parentObject();
   360     }
   511     }
   361     return filterEventThroughContexts(contexts, event);
   512     return contexts.isEmpty() ? false : filterEventThroughContexts(contexts, event);
   362 }
   513 }
   363 
   514 #endif
   364 bool QGestureManager::filterEvent(QGesture *state, QEvent *event)
   515 
   365 {
   516 bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
   366     QMap<QObject *, Qt::GestureType> contexts;
   517 {
       
   518     if (!m_gestureToRecognizer.contains(static_cast<QGesture *>(receiver)))
       
   519         return false;
       
   520     QGesture *state = static_cast<QGesture *>(receiver);
       
   521     QMultiMap<QObject *, Qt::GestureType> contexts;
   367     contexts.insert(state, state->gestureType());
   522     contexts.insert(state, state->gestureType());
   368     return filterEventThroughContexts(contexts, event);
   523     return filterEventThroughContexts(contexts, event);
   369 }
   524 }
   370 
   525 
   371 void QGestureManager::getGestureTargets(const QSet<QGesture*> &gestures,
   526 void QGestureManager::getGestureTargets(const QSet<QGesture*> &gestures,
   375     typedef QHash<Qt::GestureType, QHash<QWidget *, QGesture *> > GestureByTypes;
   530     typedef QHash<Qt::GestureType, QHash<QWidget *, QGesture *> > GestureByTypes;
   376     GestureByTypes gestureByTypes;
   531     GestureByTypes gestureByTypes;
   377 
   532 
   378     // sort gestures by types
   533     // sort gestures by types
   379     foreach (QGesture *gesture, gestures) {
   534     foreach (QGesture *gesture, gestures) {
   380         QWidget *receiver = gestureTargets.value(gesture, 0);
   535         QWidget *receiver = m_gestureTargets.value(gesture, 0);
   381         Q_ASSERT(receiver);
   536         Q_ASSERT(receiver);
   382         gestureByTypes[gesture->gestureType()].insert(receiver, gesture);
   537         gestureByTypes[gesture->gestureType()].insert(receiver, gesture);
   383     }
   538     }
   384 
   539 
   385     // for each gesture type
   540     // for each gesture type
   386     foreach (Qt::GestureType type, gestureByTypes.keys()) {
   541     foreach (Qt::GestureType type, gestureByTypes.keys()) {
   387         QHash<QWidget *, QGesture *> gestures = gestureByTypes.value(type);
   542         QHash<QWidget *, QGesture *> gestures = gestureByTypes.value(type);
   388         foreach (QWidget *widget, gestures.keys()) {
   543         foreach (QWidget *widget, gestures.keys()) {
   389             QWidget *w = widget->parentWidget();
   544             QWidget *w = widget->parentWidget();
   390             while (w) {
   545             while (w) {
   391                 QMap<Qt::GestureType, Qt::GestureContext>::const_iterator it
   546                 QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator it
   392                         = w->d_func()->gestureContext.find(type);
   547                         = w->d_func()->gestureContext.find(type);
   393                 if (it != w->d_func()->gestureContext.end()) {
   548                 if (it != w->d_func()->gestureContext.end()) {
   394                     // i.e. 'w' listens to gesture 'type'
   549                     // i.e. 'w' listens to gesture 'type'
   395                     Qt::GestureContext context = it.value();
   550                     Qt::GestureFlags flags = it.value();
   396                     if (context == Qt::WidgetWithChildrenGesture && w != widget) {
   551                     if (!(it.value() & Qt::DontStartGestureOnChildren) && w != widget) {
   397                         // conflicting gesture!
   552                         // conflicting gesture!
   398                         (*conflicts)[widget].append(gestures[widget]);
   553                         (*conflicts)[widget].append(gestures[widget]);
   399                         break;
   554                         break;
   400                     }
   555                     }
   401                 }
   556                 }
   424     QSet<QGesture *> startedGestures;
   579     QSet<QGesture *> startedGestures;
   425     // first figure out the initial receivers of gestures
   580     // first figure out the initial receivers of gestures
   426     for (QSet<QGesture *>::const_iterator it = gestures.begin(),
   581     for (QSet<QGesture *>::const_iterator it = gestures.begin(),
   427          e = gestures.end(); it != e; ++it) {
   582          e = gestures.end(); it != e; ++it) {
   428         QGesture *gesture = *it;
   583         QGesture *gesture = *it;
   429         QWidget *target = gestureTargets.value(gesture, 0);
   584         QWidget *target = m_gestureTargets.value(gesture, 0);
   430         if (!target) {
   585         if (!target) {
   431             // the gesture has just started and doesn't have a target yet.
   586             // the gesture has just started and doesn't have a target yet.
   432             Q_ASSERT(gesture->state() == Qt::GestureStarted);
   587             Q_ASSERT(gesture->state() == Qt::GestureStarted);
   433             if (gesture->hasHotSpot()) {
   588             if (gesture->hasHotSpot()) {
   434                 // guess the target widget using the hotspot of the gesture
   589                 // guess the target widget using the hotspot of the gesture
   436                 if (QWidget *w = qApp->topLevelAt(pt)) {
   591                 if (QWidget *w = qApp->topLevelAt(pt)) {
   437                     target = w->childAt(w->mapFromGlobal(pt));
   592                     target = w->childAt(w->mapFromGlobal(pt));
   438                 }
   593                 }
   439             } else {
   594             } else {
   440                 // or use the context of the gesture
   595                 // or use the context of the gesture
   441                 QObject *context = gestureOwners.value(gesture, 0);
   596                 QObject *context = m_gestureOwners.value(gesture, 0);
   442                 if (context->isWidgetType())
   597                 if (context->isWidgetType())
   443                     target = static_cast<QWidget *>(context);
   598                     target = static_cast<QWidget *>(context);
   444             }
   599             }
   445             if (target)
   600             if (target)
   446                 gestureTargets.insert(gesture, target);
   601                 m_gestureTargets.insert(gesture, target);
   447         }
   602         }
   448 
   603 
   449         Qt::GestureType gestureType = gesture->gestureType();
   604         Qt::GestureType gestureType = gesture->gestureType();
   450         Q_ASSERT(gestureType != Qt::CustomGesture);
   605         Q_ASSERT(gestureType != Qt::CustomGesture);
       
   606         Q_UNUSED(gestureType);
   451 
   607 
   452         if (target) {
   608         if (target) {
   453             if (gesture->state() == Qt::GestureStarted) {
   609             if (gesture->state() == Qt::GestureStarted) {
   454                 startedGestures.insert(gesture);
   610                 startedGestures.insert(gesture);
   455             } else {
   611             } else {
   485         foreach(QGesture *g, gestures)
   641         foreach(QGesture *g, gestures)
   486             event.setAccepted(g, false);
   642             event.setAccepted(g, false);
   487 
   643 
   488         QApplication::sendEvent(receiver, &event);
   644         QApplication::sendEvent(receiver, &event);
   489         bool eventAccepted = event.isAccepted();
   645         bool eventAccepted = event.isAccepted();
   490         foreach(QGesture *gesture, event.allGestures()) {
   646         foreach(QGesture *gesture, event.gestures()) {
   491             if (eventAccepted || event.isAccepted(gesture)) {
   647             if (eventAccepted || event.isAccepted(gesture)) {
   492                 QWidget *w = event.d_func()->targetWidgets.value(gesture->gestureType(), 0);
   648                 QWidget *w = event.d_func()->targetWidgets.value(gesture->gestureType(), 0);
   493                 Q_ASSERT(w);
   649                 Q_ASSERT(w);
   494                 DEBUG() << "override event: gesture was accepted:" << gesture << w;
   650                 DEBUG() << "override event: gesture was accepted:" << gesture << w;
   495                 QList<QGesture *> &gestures = normalStartedGestures[w];
   651                 QList<QGesture *> &gestures = normalStartedGestures[w];
   496                 gestures.append(gesture);
   652                 gestures.append(gesture);
   497                 // override the target
   653                 // override the target
   498                 gestureTargets[gesture] = w;
   654                 m_gestureTargets[gesture] = w;
   499             } else {
   655             } else {
   500                 DEBUG() << "override event: gesture wasn't accepted. putting back:" << gesture;
   656                 DEBUG() << "override event: gesture wasn't accepted. putting back:" << gesture;
   501                 QList<QGesture *> &gestures = normalStartedGestures[receiver];
   657                 QList<QGesture *> &gestures = normalStartedGestures[receiver];
   502                 gestures.append(gesture);
   658                 gestures.append(gesture);
   503             }
   659             }
   510         if (!it.value().isEmpty()) {
   666         if (!it.value().isEmpty()) {
   511             DEBUG() << "QGestureManager::deliverEvents: sending to" << it.key()
   667             DEBUG() << "QGestureManager::deliverEvents: sending to" << it.key()
   512                     << "gestures:" << it.value();
   668                     << "gestures:" << it.value();
   513             QGestureEvent event(it.value());
   669             QGestureEvent event(it.value());
   514             QApplication::sendEvent(it.key(), &event);
   670             QApplication::sendEvent(it.key(), &event);
       
   671             bool eventAccepted = event.isAccepted();
       
   672             foreach (QGesture *gesture, event.gestures()) {
       
   673                 if (gesture->state() == Qt::GestureStarted &&
       
   674                     (eventAccepted || event.isAccepted(gesture))) {
       
   675                     QWidget *w = event.d_func()->targetWidgets.value(gesture->gestureType(), 0);
       
   676                     Q_ASSERT(w);
       
   677                     DEBUG() << "started gesture was delivered and accepted by" << w;
       
   678                     m_gestureTargets[gesture] = w;
       
   679                 }
       
   680             }
   515         }
   681         }
   516     }
   682     }
   517 }
   683 }
   518 
   684 
   519 void QGestureManager::timerEvent(QTimerEvent *event)
   685 void QGestureManager::timerEvent(QTimerEvent *event)
   520 {
   686 {
   521     QMap<QGesture*, QBasicTimer>::iterator it = maybeGestures.begin(),
   687     QHash<QGesture *, QBasicTimer>::iterator it = m_maybeGestures.begin(),
   522                                             e = maybeGestures.end();
   688                                              e = m_maybeGestures.end();
   523     for (; it != e; ) {
   689     for (; it != e; ) {
   524         QBasicTimer &timer = it.value();
   690         QBasicTimer &timer = it.value();
   525         Q_ASSERT(timer.isActive());
   691         Q_ASSERT(timer.isActive());
   526         if (timer.timerId() == event->timerId()) {
   692         if (timer.timerId() == event->timerId()) {
   527             timer.stop();
   693             timer.stop();
   528             QGesture *gesture = it.key();
   694             QGesture *gesture = it.key();
   529             it = maybeGestures.erase(it);
   695             it = m_maybeGestures.erase(it);
   530             DEBUG() << "QGestureManager::timerEvent: gesture stopped due to timeout:"
   696             DEBUG() << "QGestureManager::timerEvent: gesture stopped due to timeout:"
   531                     << gesture;
   697                     << gesture;
   532             QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0);
   698             recycle(gesture);
   533             if (recognizer)
       
   534                 recognizer->reset(gesture);
       
   535         } else {
   699         } else {
   536             ++it;
   700             ++it;
   537         }
   701         }
   538     }
   702     }
   539 }
   703 }
   540 
   704 
       
   705 void QGestureManager::recycle(QGesture *gesture)
       
   706 {
       
   707     QGestureRecognizer *recognizer = m_gestureToRecognizer.value(gesture, 0);
       
   708     if (recognizer) {
       
   709         gesture->setGestureCancelPolicy(QGesture::CancelNone);
       
   710         recognizer->reset(gesture);
       
   711     } else {
       
   712         cleanupGesturesForRemovedRecognizer(gesture);
       
   713     }
       
   714 }
       
   715 
   541 QT_END_NAMESPACE
   716 QT_END_NAMESPACE
   542 
   717 
   543 #include "moc_qgesturemanager_p.cpp"
   718 #include "moc_qgesturemanager_p.cpp"