--- a/src/gui/graphicsview/qgraphicsscene.cpp Tue Jul 06 15:10:48 2010 +0300
+++ b/src/gui/graphicsview/qgraphicsscene.cpp Wed Aug 18 10:37:55 2010 +0300
@@ -699,6 +699,7 @@
if (!selectionChanging && selectedItems.size() != oldSelectedItemsSize)
emit q->selectionChanged();
+#ifndef QT_NO_GESTURES
QHash<QGesture *, QGraphicsObject *>::iterator it;
for (it = gestureTargets.begin(); it != gestureTargets.end();) {
if (it.value() == item)
@@ -706,6 +707,7 @@
else
++it;
}
+
QGraphicsObject *dummy = static_cast<QGraphicsObject *>(item);
cachedTargetItems.removeOne(dummy);
cachedItemGestures.remove(dummy);
@@ -713,6 +715,7 @@
foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys())
ungrabGesture(item, gesture);
+#endif // QT_NO_GESTURES
}
/*!
@@ -882,8 +885,7 @@
ungrabKeyboard(static_cast<QGraphicsItem *>(widget), itemIsDying);
}
if (!itemIsDying && widget->isVisible()) {
- widget->hide();
- widget->QGraphicsItem::d_ptr->explicitlyHidden = 0;
+ widget->QGraphicsItem::d_ptr->setVisibleHelper(false, /* explicit = */ false);
}
}
}
@@ -1180,11 +1182,13 @@
bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event)
{
if (QGraphicsObject *object = item->toGraphicsObject()) {
+#ifndef QT_NO_GESTURES
QGestureManager *gestureManager = QApplicationPrivate::instance()->gestureManager;
if (gestureManager) {
if (gestureManager->filterEvent(object, event))
return true;
}
+#endif // QT_NO_GESTURES
}
if (filterEvent(item, event))
@@ -1331,6 +1335,8 @@
break;
}
}
+ if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation)
+ break;
if (item->isPanel())
break;
}
@@ -2602,8 +2608,10 @@
d->enableTouchEventsOnViews();
}
+#ifndef QT_NO_GESTURES
foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys())
d->grabGesture(item, gesture);
+#endif
// Update selection lists
if (item->isSelected())
@@ -3525,10 +3533,12 @@
case QEvent::TouchEnd:
d->touchEventHandler(static_cast<QTouchEvent *>(event));
break;
+#ifndef QT_NO_GESTURES
case QEvent::Gesture:
case QEvent::GestureOverride:
d->gestureEventHandler(static_cast<QGestureEvent *>(event));
break;
+#endif // QT_NO_GESTURES
default:
return QObject::event(event);
}
@@ -4154,6 +4164,25 @@
wheelEvent->scenePos(),
wheelEvent->widget());
+#ifdef Q_WS_MAC
+ // On Mac, ignore the event if the first item under the mouse is not the last opened
+ // popup (or one of its descendant)
+ if (!d->popupWidgets.isEmpty() && !wheelCandidates.isEmpty() && wheelCandidates.first() != d->popupWidgets.back() && !d->popupWidgets.back()->isAncestorOf(wheelCandidates.first())) {
+ wheelEvent->accept();
+ return;
+ }
+#else
+ // Find the first popup under the mouse (including the popup's descendants) starting from the last.
+ // Remove all popups after the one found, or all or them if no popup is under the mouse.
+ // Then continue with the event.
+ QList<QGraphicsWidget *>::const_iterator iter = d->popupWidgets.end();
+ while (--iter >= d->popupWidgets.begin() && !wheelCandidates.isEmpty()) {
+ if (wheelCandidates.first() == *iter || (*iter)->isAncestorOf(wheelCandidates.first()))
+ break;
+ d->removePopup(*iter);
+ }
+#endif
+
bool hasSetFocus = false;
foreach (QGraphicsItem *item, wheelCandidates) {
if (!hasSetFocus && item->isEnabled()
@@ -4889,6 +4918,24 @@
if (updateAll)
return;
+ if (removingItemFromScene && !ignoreOpacity && !item->d_ptr->ignoreOpacity) {
+ // If any of the item's ancestors ignore opacity, it means that the opacity
+ // was set to 0 (and the update request has not yet been processed). That
+ // also means that we have to ignore the opacity for the item itself; otherwise
+ // things like: parent->setOpacity(0); scene->removeItem(child) won't work.
+ // Note that we only do this when removing items from the scene. In all other
+ // cases the ignoreOpacity bit propagates properly in processDirtyItems, but
+ // since the item is removed immediately it won't be processed there.
+ QGraphicsItem *p = item->d_ptr->parent;
+ while (p) {
+ if (p->d_ptr->ignoreOpacity) {
+ item->d_ptr->ignoreOpacity = true;
+ break;
+ }
+ p = p->d_ptr->parent;
+ }
+ }
+
if (item->d_ptr->discardUpdateRequest(/*ignoreVisibleBit=*/force,
/*ignoreDirtyBit=*/removingItemFromScene || invalidateChildren,
/*ignoreOpacity=*/ignoreOpacity)) {
@@ -5131,7 +5178,12 @@
// Process children.
if (itemHasChildren && item->d_ptr->dirtyChildren) {
const bool itemClipsChildrenToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape;
- if (itemClipsChildrenToShape) {
+ // Items with no content are threated as 'dummy' items which means they are never drawn and
+ // 'processed', so the painted view bounding rect is never up-to-date. This means that whenever
+ // such an item changes geometry, its children have to take care of the update regardless
+ // of whether the item clips children to shape or not.
+ const bool bypassUpdateClip = !itemHasContents && wasDirtyParentViewBoundingRects;
+ if (itemClipsChildrenToShape && !bypassUpdateClip) {
// Make sure child updates are clipped to the item's bounding rect.
for (int i = 0; i < views.size(); ++i)
views.at(i)->d_func()->setUpdateClip(item);
@@ -5619,8 +5671,10 @@
void QGraphicsScenePrivate::addView(QGraphicsView *view)
{
views << view;
+#ifndef QT_NO_GESTURES
foreach (Qt::GestureType gesture, grabbedGestures.keys())
view->viewport()->grabGesture(gesture);
+#endif
}
void QGraphicsScenePrivate::removeView(QGraphicsView *view)
@@ -5950,6 +6004,7 @@
dispatchHoverEvent(&hoverEvent);
}
+#ifndef QT_NO_GESTURES
void QGraphicsScenePrivate::gestureTargetsAtHotSpots(const QSet<QGesture *> &gestures,
Qt::GestureFlag flag,
QHash<QGraphicsObject *, QSet<QGesture *> > *targets,
@@ -6070,8 +6125,15 @@
if (ev.isAccepted() || ev.isAccepted(g)) {
conflictedGestures.remove(g);
// mark the item as a gesture target
- if (item)
+ if (item) {
gestureTargets.insert(g, item.data());
+ QHash<QGraphicsObject *, QSet<QGesture *> >::iterator it, e;
+ it = cachedItemGestures.begin();
+ e = cachedItemGestures.end();
+ for(; it != e; ++it)
+ it.value().remove(g);
+ cachedItemGestures[item.data()].insert(g);
+ }
DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
<< "override was accepted:"
<< g << item.data();
@@ -6240,7 +6302,8 @@
{
Q_ASSERT(original);
QGraphicsItem *originalItem = gestureTargets.value(original);
- Q_ASSERT(originalItem);
+ if (originalItem == 0) // we only act on accepted gestures, which implies it has a target.
+ return;
// iterate over all active gestures and for each find the owner
// if the owner is part of our sub-hierarchy, cancel it.
@@ -6338,6 +6401,7 @@
view->viewport()->ungrabGesture(gesture);
}
}
+#endif // QT_NO_GESTURES
QT_END_NAMESPACE