summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Erik Nilsen <bjorn.nilsen@nokia.com>2010-02-24 10:11:21 (GMT)
committerBjørn Erik Nilsen <bjorn.nilsen@nokia.com>2010-02-24 13:22:56 (GMT)
commitbc3e50ec44fd9ae9a665826a40f325a61087568b (patch)
treed7000555477f8c54164faa1dadbec3a9e892fc54
parent9be49ff72e7f34bd22b0375dccf142bd79f94fb6 (diff)
downloadQt-bc3e50ec44fd9ae9a665826a40f325a61087568b.zip
Qt-bc3e50ec44fd9ae9a665826a40f325a61087568b.tar.gz
Qt-bc3e50ec44fd9ae9a665826a40f325a61087568b.tar.bz2
GV: Update issues if drawItems() is overridden and IndirectPainting is used.
Problem was that the cached view bounding rect was never updated when overriding QGraphicsScene::drawItems or QGraphicsView::drawItems, without calling the base class implementation. The same for 'updateAll' boolean. We also have to make sure there are no unpolished items before we draw. Regression against 4.5. Auto-test included. Task-number: QTBUG-7880 Reviewed-by: yoann
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp27
-rw-r--r--tests/auto/qgraphicsview/tst_qgraphicsview.cpp26
2 files changed, 51 insertions, 2 deletions
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 06b7438..1ced3d7 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -3400,6 +3400,13 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
if (!d->scene->d_func()->painterStateProtection)
painter.setWorldTransform(viewTransform);
} else {
+ // Make sure we don't have unpolished items before we draw
+ if (!d->scene->d_func()->unpolishedItems.isEmpty())
+ d->scene->d_func()->_q_polishItems();
+ // We reset updateAll here (after we've issued polish events)
+ // so that we can discard update requests coming from polishEvent().
+ d->scene->d_func()->updateAll = false;
+
// Find all exposed items
bool allItems = false;
QList<QGraphicsItem *> itemList = d->findItems(d->exposedRegion, &allItems, viewTransform);
@@ -3408,9 +3415,25 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
const int numItems = itemList.size();
QGraphicsItem **itemArray = &itemList[0]; // Relies on QList internals, but is perfectly valid.
QStyleOptionGraphicsItem *styleOptionArray = d->allocStyleOptionsArray(numItems);
+ QTransform transform(Qt::Uninitialized);
for (int i = 0; i < numItems; ++i) {
- itemArray[i]->d_ptr->initStyleOption(&styleOptionArray[i], viewTransform,
- d->exposedRegion, allItems);
+ QGraphicsItem *item = itemArray[i];
+ QGraphicsItemPrivate *itemd = item->d_ptr.data();
+ itemd->initStyleOption(&styleOptionArray[i], viewTransform, d->exposedRegion, allItems);
+ // Cache the item's area in view coordinates.
+ // Note that we have to do this here in case the base class implementation
+ // (QGraphicsScene::drawItems) is not called. If it is, we'll do this
+ // operation twice, but that's the price one has to pay for using indirect
+ // painting :-/.
+ const QRectF brect = adjustedItemEffectiveBoundingRect(item);
+ if (!itemd->itemIsUntransformable()) {
+ transform = item->sceneTransform();
+ if (viewTransformed)
+ transform *= viewTransform;
+ } else {
+ transform = item->deviceTransform(viewTransform);
+ }
+ itemd->paintedViewBoundingRects.insert(d->viewport, transform.mapRect(brect).toRect());
}
// Draw the items.
drawItems(&painter, numItems, itemArray, styleOptionArray);
diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
index 59bffeb..c77f76d 100644
--- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
+++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
@@ -218,6 +218,7 @@ private slots:
void update();
void inputMethodSensitivity();
void inputContextReset();
+ void indirectPainting();
// task specific tests below me
void task172231_untransformableItems();
@@ -3799,6 +3800,31 @@ void tst_QGraphicsView::inputContextReset()
QCOMPARE(inputContext.resets, 0);
}
+void tst_QGraphicsView::indirectPainting()
+{
+ class MyScene : public QGraphicsScene
+ { public:
+ MyScene() : QGraphicsScene(), drawCount(0) {}
+ void drawItems(QPainter *, int, QGraphicsItem **, const QStyleOptionGraphicsItem *, QWidget *)
+ { ++drawCount; }
+ int drawCount;
+ };
+
+ MyScene scene;
+ QGraphicsItem *item = scene.addRect(0, 0, 50, 50);
+
+ QGraphicsView view(&scene);
+ view.setOptimizationFlag(QGraphicsView::IndirectPainting);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+ QTest::qWait(100);
+
+ scene.drawCount = 0;
+ item->setPos(20, 20);
+ QApplication::processEvents();
+ QTRY_VERIFY(scene.drawCount > 0);
+}
+
void tst_QGraphicsView::task253415_reconnectUpdateSceneOnSceneChanged()
{
QGraphicsView view;