697 // Reenable selectionChanged() for individual items |
697 // Reenable selectionChanged() for individual items |
698 --selectionChanging; |
698 --selectionChanging; |
699 if (!selectionChanging && selectedItems.size() != oldSelectedItemsSize) |
699 if (!selectionChanging && selectedItems.size() != oldSelectedItemsSize) |
700 emit q->selectionChanged(); |
700 emit q->selectionChanged(); |
701 |
701 |
|
702 #ifndef QT_NO_GESTURES |
702 QHash<QGesture *, QGraphicsObject *>::iterator it; |
703 QHash<QGesture *, QGraphicsObject *>::iterator it; |
703 for (it = gestureTargets.begin(); it != gestureTargets.end();) { |
704 for (it = gestureTargets.begin(); it != gestureTargets.end();) { |
704 if (it.value() == item) |
705 if (it.value() == item) |
705 it = gestureTargets.erase(it); |
706 it = gestureTargets.erase(it); |
706 else |
707 else |
707 ++it; |
708 ++it; |
708 } |
709 } |
|
710 |
709 QGraphicsObject *dummy = static_cast<QGraphicsObject *>(item); |
711 QGraphicsObject *dummy = static_cast<QGraphicsObject *>(item); |
710 cachedTargetItems.removeOne(dummy); |
712 cachedTargetItems.removeOne(dummy); |
711 cachedItemGestures.remove(dummy); |
713 cachedItemGestures.remove(dummy); |
712 cachedAlreadyDeliveredGestures.remove(dummy); |
714 cachedAlreadyDeliveredGestures.remove(dummy); |
713 |
715 |
714 foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys()) |
716 foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys()) |
715 ungrabGesture(item, gesture); |
717 ungrabGesture(item, gesture); |
|
718 #endif // QT_NO_GESTURES |
716 } |
719 } |
717 |
720 |
718 /*! |
721 /*! |
719 \internal |
722 \internal |
720 */ |
723 */ |
880 sendEvent(focusItem, &event); |
883 sendEvent(focusItem, &event); |
881 } else if (keyboardGrabberItems.contains(static_cast<QGraphicsItem *>(widget))) { |
884 } else if (keyboardGrabberItems.contains(static_cast<QGraphicsItem *>(widget))) { |
882 ungrabKeyboard(static_cast<QGraphicsItem *>(widget), itemIsDying); |
885 ungrabKeyboard(static_cast<QGraphicsItem *>(widget), itemIsDying); |
883 } |
886 } |
884 if (!itemIsDying && widget->isVisible()) { |
887 if (!itemIsDying && widget->isVisible()) { |
885 widget->hide(); |
888 widget->QGraphicsItem::d_ptr->setVisibleHelper(false, /* explicit = */ false); |
886 widget->QGraphicsItem::d_ptr->explicitlyHidden = 0; |
|
887 } |
889 } |
888 } |
890 } |
889 } |
891 } |
890 |
892 |
891 /*! |
893 /*! |
1178 enabled, the event is sent; otherwise it is stopped. |
1180 enabled, the event is sent; otherwise it is stopped. |
1179 */ |
1181 */ |
1180 bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event) |
1182 bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event) |
1181 { |
1183 { |
1182 if (QGraphicsObject *object = item->toGraphicsObject()) { |
1184 if (QGraphicsObject *object = item->toGraphicsObject()) { |
|
1185 #ifndef QT_NO_GESTURES |
1183 QGestureManager *gestureManager = QApplicationPrivate::instance()->gestureManager; |
1186 QGestureManager *gestureManager = QApplicationPrivate::instance()->gestureManager; |
1184 if (gestureManager) { |
1187 if (gestureManager) { |
1185 if (gestureManager->filterEvent(object, event)) |
1188 if (gestureManager->filterEvent(object, event)) |
1186 return true; |
1189 return true; |
1187 } |
1190 } |
|
1191 #endif // QT_NO_GESTURES |
1188 } |
1192 } |
1189 |
1193 |
1190 if (filterEvent(item, event)) |
1194 if (filterEvent(item, event)) |
1191 return false; |
1195 return false; |
1192 if (filterDescendantEvent(item, event)) |
1196 if (filterDescendantEvent(item, event)) |
1329 if (item != q->focusItem() && item->d_ptr->mouseSetsFocus) |
1333 if (item != q->focusItem() && item->d_ptr->mouseSetsFocus) |
1330 q->setFocusItem(item, Qt::MouseFocusReason); |
1334 q->setFocusItem(item, Qt::MouseFocusReason); |
1331 break; |
1335 break; |
1332 } |
1336 } |
1333 } |
1337 } |
|
1338 if (item->d_ptr->flags & QGraphicsItem::ItemStopsClickFocusPropagation) |
|
1339 break; |
1334 if (item->isPanel()) |
1340 if (item->isPanel()) |
1335 break; |
1341 break; |
1336 } |
1342 } |
1337 |
1343 |
1338 // Check for scene modality. |
1344 // Check for scene modality. |
2600 if (d->allItemsIgnoreTouchEvents && item->d_ptr->acceptTouchEvents) { |
2606 if (d->allItemsIgnoreTouchEvents && item->d_ptr->acceptTouchEvents) { |
2601 d->allItemsIgnoreTouchEvents = false; |
2607 d->allItemsIgnoreTouchEvents = false; |
2602 d->enableTouchEventsOnViews(); |
2608 d->enableTouchEventsOnViews(); |
2603 } |
2609 } |
2604 |
2610 |
|
2611 #ifndef QT_NO_GESTURES |
2605 foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys()) |
2612 foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys()) |
2606 d->grabGesture(item, gesture); |
2613 d->grabGesture(item, gesture); |
|
2614 #endif |
2607 |
2615 |
2608 // Update selection lists |
2616 // Update selection lists |
2609 if (item->isSelected()) |
2617 if (item->isSelected()) |
2610 d->selectedItems << item; |
2618 d->selectedItems << item; |
2611 if (item->isWidget() && item->isVisible() && static_cast<QGraphicsWidget *>(item)->windowType() == Qt::Popup) |
2619 if (item->isWidget() && item->isVisible() && static_cast<QGraphicsWidget *>(item)->windowType() == Qt::Popup) |
3523 case QEvent::TouchBegin: |
3531 case QEvent::TouchBegin: |
3524 case QEvent::TouchUpdate: |
3532 case QEvent::TouchUpdate: |
3525 case QEvent::TouchEnd: |
3533 case QEvent::TouchEnd: |
3526 d->touchEventHandler(static_cast<QTouchEvent *>(event)); |
3534 d->touchEventHandler(static_cast<QTouchEvent *>(event)); |
3527 break; |
3535 break; |
|
3536 #ifndef QT_NO_GESTURES |
3528 case QEvent::Gesture: |
3537 case QEvent::Gesture: |
3529 case QEvent::GestureOverride: |
3538 case QEvent::GestureOverride: |
3530 d->gestureEventHandler(static_cast<QGestureEvent *>(event)); |
3539 d->gestureEventHandler(static_cast<QGestureEvent *>(event)); |
3531 break; |
3540 break; |
|
3541 #endif // QT_NO_GESTURES |
3532 default: |
3542 default: |
3533 return QObject::event(event); |
3543 return QObject::event(event); |
3534 } |
3544 } |
3535 return true; |
3545 return true; |
3536 } |
3546 } |
4152 Q_D(QGraphicsScene); |
4162 Q_D(QGraphicsScene); |
4153 QList<QGraphicsItem *> wheelCandidates = d->itemsAtPosition(wheelEvent->screenPos(), |
4163 QList<QGraphicsItem *> wheelCandidates = d->itemsAtPosition(wheelEvent->screenPos(), |
4154 wheelEvent->scenePos(), |
4164 wheelEvent->scenePos(), |
4155 wheelEvent->widget()); |
4165 wheelEvent->widget()); |
4156 |
4166 |
|
4167 #ifdef Q_WS_MAC |
|
4168 // On Mac, ignore the event if the first item under the mouse is not the last opened |
|
4169 // popup (or one of its descendant) |
|
4170 if (!d->popupWidgets.isEmpty() && !wheelCandidates.isEmpty() && wheelCandidates.first() != d->popupWidgets.back() && !d->popupWidgets.back()->isAncestorOf(wheelCandidates.first())) { |
|
4171 wheelEvent->accept(); |
|
4172 return; |
|
4173 } |
|
4174 #else |
|
4175 // Find the first popup under the mouse (including the popup's descendants) starting from the last. |
|
4176 // Remove all popups after the one found, or all or them if no popup is under the mouse. |
|
4177 // Then continue with the event. |
|
4178 QList<QGraphicsWidget *>::const_iterator iter = d->popupWidgets.end(); |
|
4179 while (--iter >= d->popupWidgets.begin() && !wheelCandidates.isEmpty()) { |
|
4180 if (wheelCandidates.first() == *iter || (*iter)->isAncestorOf(wheelCandidates.first())) |
|
4181 break; |
|
4182 d->removePopup(*iter); |
|
4183 } |
|
4184 #endif |
|
4185 |
4157 bool hasSetFocus = false; |
4186 bool hasSetFocus = false; |
4158 foreach (QGraphicsItem *item, wheelCandidates) { |
4187 foreach (QGraphicsItem *item, wheelCandidates) { |
4159 if (!hasSetFocus && item->isEnabled() |
4188 if (!hasSetFocus && item->isEnabled() |
4160 && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) { |
4189 && ((item->flags() & QGraphicsItem::ItemIsFocusable) && item->d_ptr->mouseSetsFocus)) { |
4161 if (item->isWidget() && static_cast<QGraphicsWidget *>(item)->focusPolicy() == Qt::WheelFocus) { |
4190 if (item->isWidget() && static_cast<QGraphicsWidget *>(item)->focusPolicy() == Qt::WheelFocus) { |
4887 { |
4916 { |
4888 Q_ASSERT(item); |
4917 Q_ASSERT(item); |
4889 if (updateAll) |
4918 if (updateAll) |
4890 return; |
4919 return; |
4891 |
4920 |
|
4921 if (removingItemFromScene && !ignoreOpacity && !item->d_ptr->ignoreOpacity) { |
|
4922 // If any of the item's ancestors ignore opacity, it means that the opacity |
|
4923 // was set to 0 (and the update request has not yet been processed). That |
|
4924 // also means that we have to ignore the opacity for the item itself; otherwise |
|
4925 // things like: parent->setOpacity(0); scene->removeItem(child) won't work. |
|
4926 // Note that we only do this when removing items from the scene. In all other |
|
4927 // cases the ignoreOpacity bit propagates properly in processDirtyItems, but |
|
4928 // since the item is removed immediately it won't be processed there. |
|
4929 QGraphicsItem *p = item->d_ptr->parent; |
|
4930 while (p) { |
|
4931 if (p->d_ptr->ignoreOpacity) { |
|
4932 item->d_ptr->ignoreOpacity = true; |
|
4933 break; |
|
4934 } |
|
4935 p = p->d_ptr->parent; |
|
4936 } |
|
4937 } |
|
4938 |
4892 if (item->d_ptr->discardUpdateRequest(/*ignoreVisibleBit=*/force, |
4939 if (item->d_ptr->discardUpdateRequest(/*ignoreVisibleBit=*/force, |
4893 /*ignoreDirtyBit=*/removingItemFromScene || invalidateChildren, |
4940 /*ignoreDirtyBit=*/removingItemFromScene || invalidateChildren, |
4894 /*ignoreOpacity=*/ignoreOpacity)) { |
4941 /*ignoreOpacity=*/ignoreOpacity)) { |
4895 if (item->d_ptr->dirty) { |
4942 if (item->d_ptr->dirty) { |
4896 // The item is already marked as dirty and will be processed later. However, |
4943 // The item is already marked as dirty and will be processed later. However, |
5129 } |
5176 } |
5130 |
5177 |
5131 // Process children. |
5178 // Process children. |
5132 if (itemHasChildren && item->d_ptr->dirtyChildren) { |
5179 if (itemHasChildren && item->d_ptr->dirtyChildren) { |
5133 const bool itemClipsChildrenToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape; |
5180 const bool itemClipsChildrenToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape; |
5134 if (itemClipsChildrenToShape) { |
5181 // Items with no content are threated as 'dummy' items which means they are never drawn and |
|
5182 // 'processed', so the painted view bounding rect is never up-to-date. This means that whenever |
|
5183 // such an item changes geometry, its children have to take care of the update regardless |
|
5184 // of whether the item clips children to shape or not. |
|
5185 const bool bypassUpdateClip = !itemHasContents && wasDirtyParentViewBoundingRects; |
|
5186 if (itemClipsChildrenToShape && !bypassUpdateClip) { |
5135 // Make sure child updates are clipped to the item's bounding rect. |
5187 // Make sure child updates are clipped to the item's bounding rect. |
5136 for (int i = 0; i < views.size(); ++i) |
5188 for (int i = 0; i < views.size(); ++i) |
5137 views.at(i)->d_func()->setUpdateClip(item); |
5189 views.at(i)->d_func()->setUpdateClip(item); |
5138 } |
5190 } |
5139 if (!dirtyAncestorContainsChildren) { |
5191 if (!dirtyAncestorContainsChildren) { |
5617 } |
5669 } |
5618 |
5670 |
5619 void QGraphicsScenePrivate::addView(QGraphicsView *view) |
5671 void QGraphicsScenePrivate::addView(QGraphicsView *view) |
5620 { |
5672 { |
5621 views << view; |
5673 views << view; |
|
5674 #ifndef QT_NO_GESTURES |
5622 foreach (Qt::GestureType gesture, grabbedGestures.keys()) |
5675 foreach (Qt::GestureType gesture, grabbedGestures.keys()) |
5623 view->viewport()->grabGesture(gesture); |
5676 view->viewport()->grabGesture(gesture); |
|
5677 #endif |
5624 } |
5678 } |
5625 |
5679 |
5626 void QGraphicsScenePrivate::removeView(QGraphicsView *view) |
5680 void QGraphicsScenePrivate::removeView(QGraphicsView *view) |
5627 { |
5681 { |
5628 views.removeAll(view); |
5682 views.removeAll(view); |
5948 QGraphicsSceneHoverEvent hoverEvent; |
6002 QGraphicsSceneHoverEvent hoverEvent; |
5949 hoverEvent.setScenePos(lastSceneMousePos); |
6003 hoverEvent.setScenePos(lastSceneMousePos); |
5950 dispatchHoverEvent(&hoverEvent); |
6004 dispatchHoverEvent(&hoverEvent); |
5951 } |
6005 } |
5952 |
6006 |
|
6007 #ifndef QT_NO_GESTURES |
5953 void QGraphicsScenePrivate::gestureTargetsAtHotSpots(const QSet<QGesture *> &gestures, |
6008 void QGraphicsScenePrivate::gestureTargetsAtHotSpots(const QSet<QGesture *> &gestures, |
5954 Qt::GestureFlag flag, |
6009 Qt::GestureFlag flag, |
5955 QHash<QGraphicsObject *, QSet<QGesture *> > *targets, |
6010 QHash<QGraphicsObject *, QSet<QGesture *> > *targets, |
5956 QSet<QGraphicsObject *> *itemsSet, |
6011 QSet<QGraphicsObject *> *itemsSet, |
5957 QSet<QGesture *> *normal, |
6012 QSet<QGesture *> *normal, |
6068 // mark all accepted gestures to deliver them as normal gesture events |
6123 // mark all accepted gestures to deliver them as normal gesture events |
6069 foreach (QGesture *g, gestures) { |
6124 foreach (QGesture *g, gestures) { |
6070 if (ev.isAccepted() || ev.isAccepted(g)) { |
6125 if (ev.isAccepted() || ev.isAccepted(g)) { |
6071 conflictedGestures.remove(g); |
6126 conflictedGestures.remove(g); |
6072 // mark the item as a gesture target |
6127 // mark the item as a gesture target |
6073 if (item) |
6128 if (item) { |
6074 gestureTargets.insert(g, item.data()); |
6129 gestureTargets.insert(g, item.data()); |
|
6130 QHash<QGraphicsObject *, QSet<QGesture *> >::iterator it, e; |
|
6131 it = cachedItemGestures.begin(); |
|
6132 e = cachedItemGestures.end(); |
|
6133 for(; it != e; ++it) |
|
6134 it.value().remove(g); |
|
6135 cachedItemGestures[item.data()].insert(g); |
|
6136 } |
6075 DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" |
6137 DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" |
6076 << "override was accepted:" |
6138 << "override was accepted:" |
6077 << g << item.data(); |
6139 << g << item.data(); |
6078 } |
6140 } |
6079 // remember the first item that received the override event |
6141 // remember the first item that received the override event |
6238 |
6300 |
6239 void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original) |
6301 void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original) |
6240 { |
6302 { |
6241 Q_ASSERT(original); |
6303 Q_ASSERT(original); |
6242 QGraphicsItem *originalItem = gestureTargets.value(original); |
6304 QGraphicsItem *originalItem = gestureTargets.value(original); |
6243 Q_ASSERT(originalItem); |
6305 if (originalItem == 0) // we only act on accepted gestures, which implies it has a target. |
|
6306 return; |
6244 |
6307 |
6245 // iterate over all active gestures and for each find the owner |
6308 // iterate over all active gestures and for each find the owner |
6246 // if the owner is part of our sub-hierarchy, cancel it. |
6309 // if the owner is part of our sub-hierarchy, cancel it. |
6247 |
6310 |
6248 QSet<QGesture *> canceledGestures; |
6311 QSet<QGesture *> canceledGestures; |