src/gui/graphicsview/qgraphicsscene.cpp
branchRCL_3
changeset 4 3b1da2848fc7
parent 3 41300fa6a67c
child 5 d3bac044e0f0
--- a/src/gui/graphicsview/qgraphicsscene.cpp	Tue Feb 02 00:43:10 2010 +0200
+++ b/src/gui/graphicsview/qgraphicsscene.cpp	Fri Feb 19 23:40:16 2010 +0200
@@ -1,6 +1,6 @@
 /****************************************************************************
 **
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
 **
@@ -292,6 +292,7 @@
       processDirtyItemsEmitted(false),
       selectionChanging(0),
       needSortTopLevelItems(true),
+      unpolishedItemsModified(true),
       holesInTopLevelSiblingIndex(false),
       topLevelSequentialOrdering(true),
       scenePosDescendantsUpdatePending(false),
@@ -428,12 +429,12 @@
 */
 void QGraphicsScenePrivate::_q_polishItems()
 {
-    QSet<QGraphicsItem *>::Iterator it;
+    QSet<QGraphicsItem *>::Iterator it = unpolishedItems.begin();
     const QVariant booleanTrueVariant(true);
     while (!unpolishedItems.isEmpty()) {
-        it = unpolishedItems.begin();
         QGraphicsItem *item = *it;
-        unpolishedItems.erase(it);
+        it = unpolishedItems.erase(it);
+        unpolishedItemsModified = false;
         if (!item->d_ptr->explicitlyHidden) {
             item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant);
             item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant);
@@ -442,6 +443,8 @@
             QEvent event(QEvent::Polish);
             QApplication::sendEvent((QGraphicsWidget *)item, &event);
         }
+        if (unpolishedItemsModified)
+            it = unpolishedItems.begin();
     }
 }
 
@@ -636,6 +639,7 @@
     hoverItems.removeAll(item);
     cachedItemsUnderMouse.removeAll(item);
     unpolishedItems.remove(item);
+    unpolishedItemsModified = true;
     resetDirtyItem(item);
 
     //We remove all references of item from the sceneEventFilter arrays
@@ -1132,8 +1136,9 @@
 bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event)
 {
     if (QGraphicsObject *object = item->toGraphicsObject()) {
-        if (qt_gestureManager) {
-            if (qt_gestureManager->filterEvent(object, event))
+        QGestureManager *gestureManager = QApplicationPrivate::instance()->gestureManager;
+        if (gestureManager) {
+            if (gestureManager->filterEvent(object, event))
                 return true;
         }
     }
@@ -1561,7 +1566,10 @@
 }
 
 /*!
-    Destroys the QGraphicsScene object.
+  Removes and deletes all items from the scene object
+  before destroying the scene object. The scene object
+  is removed from the application's global scene list,
+  and it is removed from all associated views.
 */
 QGraphicsScene::~QGraphicsScene()
 {
@@ -2443,23 +2451,26 @@
 }
 
 /*!
-    Adds or moves the item \a item and all its childen to the scene.
+    Adds or moves the \a item and all its childen to this scene.
+    This scene takes ownership of the \a item.
 
     If the item is visible (i.e., QGraphicsItem::isVisible() returns
     true), QGraphicsScene will emit changed() once control goes back
     to the event loop.
 
-    If the item is already in a different scene, it will first be removed from
-    its old scene, and then added to this scene as a top-level.
-
-    QGraphicsScene will send ItemSceneChange notifications to \a item while
-    it is added to the scene. If item does not currently belong to a scene, only one
-    notification is sent. If it does belong to scene already (i.e., it is
-    moved to this scene), QGraphicsScene will send an addition notification as
-    the item is removed from its previous scene.
-
-    If the item is a panel, the scene is active, and there is no active panel
-    in the scene, then the item will be activated.
+    If the item is already in a different scene, it will first be
+    removed from its old scene, and then added to this scene as a
+    top-level.
+
+    QGraphicsScene will send ItemSceneChange notifications to \a item
+    while it is added to the scene. If item does not currently belong
+    to a scene, only one notification is sent. If it does belong to
+    scene already (i.e., it is moved to this scene), QGraphicsScene
+    will send an addition notification as the item is removed from its
+    previous scene.
+
+    If the item is a panel, the scene is active, and there is no
+    active panel in the scene, then the item will be activated.
 
     \sa removeItem(), addEllipse(), addLine(), addPath(), addPixmap(),
     addRect(), addText(), addWidget(), {QGraphicsItem#Sorting}{Sorting}
@@ -2571,9 +2582,10 @@
     item->d_ptr->resolveFont(d->font.resolve());
     item->d_ptr->resolvePalette(d->palette.resolve());
 
-   if (d->unpolishedItems.isEmpty())
-       QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection);
-   d->unpolishedItems.insert(item);
+    if (d->unpolishedItems.isEmpty())
+        QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection);
+    d->unpolishedItems.insert(item);
+    d->unpolishedItemsModified = true;
 
     // Reenable selectionChanged() for individual items
     --d->selectionChanging;
@@ -4674,8 +4686,31 @@
         if (sourced->currentCachedSystem() != Qt::LogicalCoordinates
             && sourced->lastEffectTransform != painter->worldTransform())
         {
+            bool unclipped = false;
+            if (sourced->lastEffectTransform.type() <= QTransform::TxTranslate
+                && painter->worldTransform().type() <= QTransform::TxTranslate)
+            {
+                QRectF itemRect = item->boundingRect();
+                if (!item->d_ptr->children.isEmpty())
+                    itemRect |= item->childrenBoundingRect();
+
+                QRectF oldSourceRect = sourced->lastEffectTransform.mapRect(itemRect);
+                QRectF newSourceRect = painter->worldTransform().mapRect(itemRect);
+
+                QRect oldEffectRect = sourced->paddedEffectRect(sourced->currentCachedSystem(), sourced->currentCachedMode(), oldSourceRect);
+                QRect newEffectRect = sourced->paddedEffectRect(sourced->currentCachedSystem(), sourced->currentCachedMode(), newSourceRect);
+
+                QRect deviceRect(0, 0, painter->device()->width(), painter->device()->height());
+                if (deviceRect.contains(oldEffectRect) && deviceRect.contains(newEffectRect)) {
+                    sourced->setCachedOffset(newEffectRect.topLeft());
+                    unclipped = true;
+                }
+            }
+
             sourced->lastEffectTransform = painter->worldTransform();
-            sourced->invalidateCache(QGraphicsEffectSourcePrivate::TransformChanged);
+
+            if (!unclipped)
+                sourced->invalidateCache(QGraphicsEffectSourcePrivate::TransformChanged);
         }
 
         item->d_ptr->graphicsEffect->draw(painter);
@@ -5089,6 +5124,10 @@
 
     \snippet doc/src/snippets/graphicssceneadditemsnippet.cpp 0
 
+    \obsolete Since Qt 4.6, this function is not called anymore unless
+    the QGraphicsView::IndirectPainting flag is given as an Optimization
+    flag.
+
     \sa drawBackground(), drawForeground()
 */
 void QGraphicsScene::drawItems(QPainter *painter,
@@ -6142,9 +6181,10 @@
         }
     }
 
-    Q_ASSERT(qt_gestureManager); // it would be very odd if we got called without a manager.
+    QGestureManager *gestureManager = QApplicationPrivate::instance()->gestureManager;
+    Q_ASSERT(gestureManager); // it would be very odd if we got called without a manager.
     for (setIter = canceledGestures.begin(); setIter != canceledGestures.end(); ++setIter) {
-        qt_gestureManager->recycle(*setIter);
+        gestureManager->recycle(*setIter);
         gestureTargets.remove(*setIter);
     }
 }