From 3a7804813d9dd4162e088bc19746abd20aaa7827 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Fri, 30 Oct 2009 13:23:27 +0100 Subject: Removed the margin in assistant on Mac. Change 9551b8c349ce4e15a57c24a2408ee1b73c2b7510 enabled documentMode on the tabbar in Assistant. To make it look more native we also remove the margin around the tabwidget. Reviewed-by: Prasanth --- tools/assistant/tools/assistant/centralwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp index 2722b2f..62b4736 100644 --- a/tools/assistant/tools/assistant/centralwidget.cpp +++ b/tools/assistant/tools/assistant/centralwidget.cpp @@ -222,8 +222,8 @@ CentralWidget::CentralWidget(QHelpEngine *engine, MainWindow *parent) QVBoxLayout *vboxLayout = new QVBoxLayout(this); QString resourcePath = QLatin1String(":/trolltech/assistant/images/"); -#ifndef Q_OS_MAC vboxLayout->setMargin(0); +#ifndef Q_OS_MAC resourcePath.append(QLatin1String("win")); #else resourcePath.append(QLatin1String("mac")); -- cgit v0.12 From acb10eefab985a32a619e2a1d590c93659732c00 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Fri, 30 Oct 2009 12:42:23 +0100 Subject: Fix unit test and add autoCancel test for graphicsview --- tests/auto/gestures/tst_gestures.cpp | 98 ++++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 26 deletions(-) diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index 02c8232..79de823 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -116,7 +116,7 @@ public: return new CustomGesture; } - QGestureRecognizer::Result filterEvent(QGesture *state, QObject*, QEvent *event) + QGestureRecognizer::Result filterEvent(QGesture *state, QObject*o , QEvent *event) { if (event->type() == CustomEvent::EventType) { QGestureRecognizer::Result result = 0; @@ -332,6 +332,7 @@ private slots: void consumeEventHint(); void unregisterRecognizer(); void autoCancelGestures(); + void autoCancelGestures2(); }; tst_Gestures::tst_Gestures() @@ -1295,20 +1296,6 @@ void tst_Gestures::unregisterRecognizer() // a method on QApplication void tst_Gestures::autoCancelGestures() { - class MockRecognizer : public QGestureRecognizer { - public: - QGestureRecognizer::Result filterEvent(QGesture *gesture, QObject *watched, QEvent *event) - { - Q_UNUSED(gesture); - Q_UNUSED(watched); - if (event->type() == QEvent::MouseButtonPress) - return QGestureRecognizer::GestureTriggered; - if (event->type() == QEvent::MouseButtonRelease) - return QGestureRecognizer::GestureFinished; - return QGestureRecognizer::Ignore; - } - }; - class MockWidget : public GestureWidget { public: MockWidget(const char *name) : GestureWidget(name) { } @@ -1324,14 +1311,18 @@ void tst_Gestures::autoCancelGestures() } }; + const Qt::GestureType secondGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); + MockWidget parent("parent"); // this one sets the cancel policy to CancelAllInContext parent.resize(300, 100); + parent.setWindowFlags(Qt::X11BypassWindowManagerHint); GestureWidget *child = new GestureWidget("child", &parent); child->setGeometry(10, 10, 100, 80); - Qt::GestureType type = QApplication::registerGestureRecognizer(new MockRecognizer()); - parent.grabGesture(type, Qt::WidgetWithChildrenGesture); - child->grabGesture(type, Qt::WidgetWithChildrenGesture); + parent.grabGesture(CustomGesture::GestureType, Qt::WidgetWithChildrenGesture); + child->grabGesture(secondGesture, Qt::WidgetWithChildrenGesture); + parent.show(); + QTest::qWaitForWindowShown(&parent); /* An event is send to both the child and the parent, when the child gets it a gesture is triggered @@ -1340,18 +1331,73 @@ void tst_Gestures::autoCancelGestures() parent gets it he accepts it and that causes the cancel policy to activate. The cause of that is the gesture for the child is cancelled and send to the child as such. */ - QMouseEvent event(QEvent::MouseButtonPress, QPoint(20,20), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + CustomEvent event; + event.serial = CustomGesture::SerialStartedThreshold; QApplication::sendEvent(child, &event); + QCOMPARE(child->events.all.count(), 2); QCOMPARE(child->events.started.count(), 1); - QCOMPARE(child->events.all.count(), 1); - QCOMPARE(parent.events.all.count(), 0); - child->reset(); - QApplication::sendEvent(&parent, &event); + QCOMPARE(child->events.canceled.count(), 1); QCOMPARE(parent.events.all.count(), 1); - QCOMPARE(parent.events.started.count(), 1); - QCOMPARE(child->events.started.count(), 0); - QCOMPARE(child->events.all.count(), 1); + + // clean up, make the parent gesture finish + event.serial = CustomGesture::SerialFinishedThreshold; + QApplication::sendEvent(child, &event); + QCOMPARE(parent.events.all.count(), 2); +} + +void tst_Gestures::autoCancelGestures2() +{ + class MockItem : public GestureItem { + public: + MockItem(const char *name) : GestureItem(name) { } + + bool event(QEvent *event) { + if (event->type() == QEvent::Gesture) { + QGestureEvent *ge = static_cast(event); + Q_ASSERT(ge->allGestures().count() == 1); // can't use QCOMPARE here... + ge->allGestures().first()->setGestureCancelPolicy(QGesture::CancelAllInContext); + } + return GestureItem::event(event); + } + }; + + const Qt::GestureType secondGesture = QApplication::registerGestureRecognizer(new CustomGestureRecognizer); + + QGraphicsScene scene; + QGraphicsView view(&scene); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); + + MockItem *parent = new MockItem("parent"); + GestureItem *child = new GestureItem("child"); + child->setParentItem(parent); + parent->setPos(0, 0); + child->setPos(10, 10); + scene.addItem(parent); + view.viewport()->grabGesture(CustomGesture::GestureType, Qt::WidgetGesture); + view.viewport()->grabGesture(secondGesture, Qt::WidgetGesture); + parent->grabGesture(CustomGesture::GestureType, Qt::WidgetWithChildrenGesture); + child->grabGesture(secondGesture, Qt::WidgetWithChildrenGesture); + + view.show(); + QTest::qWaitForWindowShown(&view); + view.ensureVisible(scene.sceneRect()); + + CustomEvent event; + event.serial = CustomGesture::SerialStartedThreshold; + event.hasHotSpot = true; + event.hotSpot = mapToGlobal(QPointF(5, 5), child, &view); + // qDebug() << event.hotSpot; + scene.sendEvent(child, &event); + //QEventLoop().exec(); + QCOMPARE(parent->events.all.count(), 1); + QCOMPARE(child->events.started.count(), 1); QCOMPARE(child->events.canceled.count(), 1); + QCOMPARE(child->events.all.count(), 2); + + // clean up, make the parent gesture finish + event.serial = CustomGesture::SerialFinishedThreshold; + scene.sendEvent(child, &event); + QCOMPARE(parent->events.all.count(), 2); } QTEST_MAIN(tst_Gestures) -- cgit v0.12 From da83365fbf7ff393f7dc99d28eda61b902081bb2 Mon Sep 17 00:00:00 2001 From: Thomas Zander Date: Fri, 30 Oct 2009 12:42:49 +0100 Subject: Make GestureCancelPolicy work for graphicsview Reviewed-By: Denis --- src/gui/graphicsview/qgraphicsscene.cpp | 90 +++++++++++++++++++++++++++++++++ src/gui/graphicsview/qgraphicsscene_p.h | 1 + src/gui/kernel/qgesture.h | 1 + src/gui/kernel/qgesturemanager.cpp | 37 ++++++-------- src/gui/kernel/qgesturemanager_p.h | 2 + 5 files changed, 109 insertions(+), 22 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index c459d21..9279fe3 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -5941,6 +5941,13 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) continue; } } + foreach (QGesture *g, startedGestures) { + if (g->gestureCancelPolicy() == QGesture::CancelAllInContext) { + DEBUG() << "lets try to cancel some"; + // find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them + cancelGesturesForChildren(g, event->widget()); + } + } // forget about targets for gestures that have ended foreach (QGesture *g, allGestures) { @@ -5955,6 +5962,89 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) } } +void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original, QWidget *viewport) +{ + Q_ASSERT(original); + QGraphicsItem *originalItem = gestureTargets.value(original); + Q_ASSERT(originalItem); + + // iterate over all active gestures and for each find the owner + // if the owner is part of our sub-hierarchy, cancel it. + + QSet canceledGestures; + QHash::Iterator iter = gestureTargets.begin(); + while (iter != gestureTargets.end()) { + QGraphicsObject *item = iter.value(); + // note that we don't touch the gestures for our originalItem + if (item != originalItem && originalItem->isAncestorOf(item)) { + DEBUG() << " found a gesture to cancel" << iter.key(); + iter.key()->d_func()->state = Qt::GestureCanceled; + canceledGestures << iter.key(); + } + ++iter; + } + + // sort them per target item by cherry picking from almostCanceledGestures and delivering + QSet almostCanceledGestures = canceledGestures; + QSet::Iterator setIter; + while (!almostCanceledGestures.isEmpty()) { + QGraphicsObject *target = 0; + QSet gestures; + setIter = almostCanceledGestures.begin(); + // sort per target item + while (setIter != almostCanceledGestures.end()) { + QGraphicsObject *item = gestureTargets.value(*setIter); + if (target == 0) + target = item; + if (target == item) { + gestures << *setIter; + setIter = almostCanceledGestures.erase(setIter); + } else { + ++setIter; + } + } + Q_ASSERT(target); + + QList list = gestures.toList(); + QGestureEvent ev(list); + sendEvent(target, &ev); + + foreach (QGesture *g, list) { + if (ev.isAccepted() || ev.isAccepted(g)) + gestures.remove(g); + } + + foreach (QGesture *g, gestures) { + if (!g->hasHotSpot()) + continue; + + QPoint screenPos = g->hotSpot().toPoint(); + QList items = itemsAtPosition(screenPos, QPointF(), viewport); + for (int j = 0; j < items.size(); ++j) { + QGraphicsObject *item = items.at(j)->toGraphicsObject(); + if (!item) + continue; + QGraphicsItemPrivate *d = item->QGraphicsItem::d_func(); + if (d->gestureContext.contains(g->gestureType())) { + QList list; + list << g; + QGestureEvent ev(list); + sendEvent(item, &ev); + if (ev.isAccepted() || ev.isAccepted(g)) + break; // successfully delivered + } + } + } + } + + QGestureManager *gm = QApplicationPrivate::instance()->gestureManager; + Q_ASSERT(gm); // it would be very odd if we got called without a manager. + for (setIter = canceledGestures.begin(); setIter != canceledGestures.end(); ++setIter) { + gm->recycle(*setIter); + gestureTargets.remove(*setIter); + } +} + QT_END_NAMESPACE #include "moc_qgraphicsscene.cpp" diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index cd20fd0..f8db084 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -288,6 +288,7 @@ public: QMap *conflictedGestures, QList > *conflictedItems, QHash *normalGestures); + void cancelGesturesForChildren(QGesture *original, QWidget *viewport); void updateInputMethodSensitivityInViews(); diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h index 524d26e..8614ecb 100644 --- a/src/gui/kernel/qgesture.h +++ b/src/gui/kernel/qgesture.h @@ -97,6 +97,7 @@ private: friend class QGestureEvent; friend class QGestureRecognizer; friend class QGestureManager; + friend class QGraphicsScenePrivate; }; class QPanGesturePrivate; diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index f1abc89..1d33c84 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -346,12 +346,7 @@ bool QGestureManager::filterEventThroughContexts(const QMultiHash endedGestures = finishedGestures + canceledGestures + undeliveredGestures; foreach (QGesture *gesture, endedGestures) { - if (QGestureRecognizer *recognizer = m_gestureToRecognizer.value(gesture, 0)) { - gesture->setGestureCancelPolicy(QGesture::CancelNone); - recognizer->reset(gesture); - } else { - cleanupGesturesForRemovedRecognizer(gesture); - } + recycle(gesture); m_gestureTargets.remove(gesture); } return ret; @@ -409,15 +404,8 @@ void QGestureManager::cancelGesturesForChildren(QGesture *original) deliverEvents(gestures, &undeliveredGestures); } - for (iter = cancelledGestures.begin(); iter != cancelledGestures.end(); ++iter) { - QGestureRecognizer *recognizer = m_gestureToRecognizer.value(*iter, 0); - if (recognizer) { - (*iter)->setGestureCancelPolicy(QGesture::CancelNone); - recognizer->reset(*iter); - } else { - cleanupGesturesForRemovedRecognizer(*iter); - } - } + for (iter = cancelledGestures.begin(); iter != cancelledGestures.end(); ++iter) + recycle(*iter); } void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture) @@ -667,19 +655,24 @@ void QGestureManager::timerEvent(QTimerEvent *event) it = m_maybeGestures.erase(it); DEBUG() << "QGestureManager::timerEvent: gesture stopped due to timeout:" << gesture; - QGestureRecognizer *recognizer = m_gestureToRecognizer.value(gesture, 0); - if (recognizer) { - gesture->setGestureCancelPolicy(QGesture::CancelNone); - recognizer->reset(gesture); - } else { - cleanupGesturesForRemovedRecognizer(gesture); - } + recycle(gesture); } else { ++it; } } } +void QGestureManager::recycle(QGesture *gesture) +{ + QGestureRecognizer *recognizer = m_gestureToRecognizer.value(gesture, 0); + if (recognizer) { + gesture->setGestureCancelPolicy(QGesture::CancelNone); + recognizer->reset(gesture); + } else { + cleanupGesturesForRemovedRecognizer(gesture); + } +} + QT_END_NAMESPACE #include "moc_qgesturemanager_p.cpp" diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h index 4958cdb..d60aedc 100644 --- a/src/gui/kernel/qgesturemanager_p.h +++ b/src/gui/kernel/qgesturemanager_p.h @@ -81,6 +81,8 @@ public: void cleanupCachedGestures(QObject *target, Qt::GestureType type); + void recycle(QGesture *gesture); + protected: void timerEvent(QTimerEvent *event); bool filterEventThroughContexts(const QMultiHash &contexts, -- cgit v0.12