From 435fae071798817f57bc89bf5d1ac20aae488625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Fri, 10 Jul 2009 18:14:48 +0200 Subject: QGraphicsItem not updated properly when moving parent. Found during manual testing (manualtests/graphicsview/movableitems). Moving a child item (via its parent) outside the viewport, and then back again didn't trigger an update on the child. Reason was that we had a cut-off checking the wrong bit (geometryChanged). This bit means exactly the same as the paintedViewBoundingRectsNeedRepaint bit, except that it doesn't propagate to the children (and that's the bug). We use paintedViewBoundingRectsNeedRepaint instead. Auto-test included. --- src/gui/graphicsview/qgraphicsitem.cpp | 1 + src/gui/graphicsview/qgraphicsscene.cpp | 4 ++-- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 33 +++++++++++++++++++++++--- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 0cfaab7..b7385d4 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1822,6 +1822,7 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo q_ptr->setSelected(false); } else { geometryChanged = 1; + paintedViewBoundingRectsNeedRepaint = 1; if (isWidget && scene) { QGraphicsWidget *widget = static_cast(q_ptr); if (widget->windowType() == Qt::Popup) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index c7c0865..aa7fa4c 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4568,7 +4568,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool if (!item->d_ptr->dirty) continue; - if (!item->d_ptr->geometryChanged + if (!item->d_ptr->paintedViewBoundingRectsNeedRepaint && paintedViewBoundingRect.x() == -1 && paintedViewBoundingRect.y() == -1 && paintedViewBoundingRect.width() == -1 && paintedViewBoundingRect.height() == -1) { continue; // Outside viewport. @@ -4587,7 +4587,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool continue; // Discard updates outside the bounding rect. if (!updateHelper(viewPrivate, item->d_ptr, dirtyRect, itemIsUntransformable) - && item->d_ptr->geometryChanged) { + && item->d_ptr->paintedViewBoundingRectsNeedRepaint) { paintedViewBoundingRect = QRect(-1, -1, -1, -1); // Outside viewport. } } diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 4e669ae..4ca1b48 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -6614,9 +6614,9 @@ void tst_QGraphicsItem::update() qApp->processEvents(); QCOMPARE(item->repaints, 1); QCOMPARE(view.repaints, 1); - const QRect itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform()) - .mapRect(item->boundingRect()).toRect(); - const QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2); + QRect itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform()) + .mapRect(item->boundingRect()).toRect(); + QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2); // The entire item's bounding rect (adjusted for antialiasing) should have been painted. QCOMPARE(view.paintedRegion, expectedRegion); @@ -6684,6 +6684,33 @@ void tst_QGraphicsItem::update() QCOMPARE(item->repaints, 1); QCOMPARE(view.repaints, 1); QCOMPARE(view.paintedRegion, expectedRegion + expectedRegion.translated(50, 50)); + + // Make sure moving a parent item triggers an update on the children + // (even though the parent itself is outside the viewport). + QGraphicsRectItem *parent = new QGraphicsRectItem(0, 0, 10, 10); + parent->setPos(-400, 0); + item->setParentItem(parent); + item->setPos(400, 0); + scene.addItem(parent); + QTest::qWait(50); + itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform()) + .mapRect(item->boundingRect()).toRect(); + expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2); + view.reset(); + item->repaints = 0; + parent->translate(-400, 0); + qApp->processEvents(); + QCOMPARE(item->repaints, 0); + QCOMPARE(view.repaints, 1); + QCOMPARE(view.paintedRegion, expectedRegion); + view.reset(); + item->repaints = 0; + parent->translate(400, 0); + qApp->processEvents(); + QCOMPARE(item->repaints, 1); + QCOMPARE(view.repaints, 1); + QCOMPARE(view.paintedRegion, expectedRegion); + QCOMPARE(view.paintedRegion, expectedRegion); } void tst_QGraphicsItem::setTransformProperties_data() -- cgit v0.12