src/gui/graphicsview/qgraphicsscene.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
   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;
  6336     if (!--grabbedGestures[gesture]) {
  6399     if (!--grabbedGestures[gesture]) {
  6337         foreach (QGraphicsView *view, views)
  6400         foreach (QGraphicsView *view, views)
  6338             view->viewport()->ungrabGesture(gesture);
  6401             view->viewport()->ungrabGesture(gesture);
  6339     }
  6402     }
  6340 }
  6403 }
       
  6404 #endif // QT_NO_GESTURES
  6341 
  6405 
  6342 QT_END_NAMESPACE
  6406 QT_END_NAMESPACE
  6343 
  6407 
  6344 #include "moc_qgraphicsscene.cpp"
  6408 #include "moc_qgraphicsscene.cpp"
  6345 
  6409