tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
branchRCL_3
changeset 7 3f74d0d4af4c
parent 5 d3bac044e0f0
child 13 c0432d11811c
--- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp	Mon Mar 15 12:43:09 2010 +0200
+++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp	Thu Apr 08 14:19:33 2010 +0300
@@ -90,6 +90,8 @@
 #define COMPARE_REGIONS QTRY_COMPARE
 #endif
 
+static QGraphicsRectItem staticItem; //QTBUG-7629, we should not crash at exit.
+
 static void sendMousePress(QGraphicsScene *scene, const QPointF &point, Qt::MouseButton button = Qt::LeftButton)
 {
     QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
@@ -251,6 +253,21 @@
     QBrush brush;
 };
 
+class MyGraphicsView : public QGraphicsView
+{
+public:
+    int repaints;
+    QRegion paintedRegion;
+    MyGraphicsView(QGraphicsScene *scene) : QGraphicsView(scene), repaints(0) {}
+    void paintEvent(QPaintEvent *e)
+    {
+        paintedRegion += e->region();
+        ++repaints;
+        QGraphicsView::paintEvent(e);
+    }
+    void reset() { repaints = 0; paintedRegion = QRegion(); }
+};
+
 class tst_QGraphicsItem : public QObject
 {
     Q_OBJECT
@@ -367,6 +384,7 @@
     void tabChangesFocus();
     void tabChangesFocus_data();
     void cacheMode();
+    void cacheMode2();
     void updateCachedItemAfterMove();
     void deviceTransform_data();
     void deviceTransform();
@@ -419,6 +437,10 @@
     void QTBUG_4233_updateCachedWithSceneRect();
     void QTBUG_5418_textItemSetDefaultColor();
     void QTBUG_6738_missingUpdateWithSetParent();
+    void QTBUG_7714_fullUpdateDiscardingOpacityUpdate2();
+    void QT_2653_fullUpdateDiscardingOpacityUpdate();
+    void QT_2649_focusScope();
+    void sortItemsWhileAdding();
 
 private:
     QList<QGraphicsItem *> paintedItems;
@@ -3165,7 +3187,6 @@
     childChild->setPos(500, 500);
     child->rotate(90);
 
-
     scene.addPolygon(parent->mapToScene(parent->boundingRect() | parent->childrenBoundingRect()))->setPen(QPen(Qt::red));;
 
     QGraphicsView view(&scene);
@@ -6252,13 +6273,6 @@
     QGraphicsScene scene;
     scene.addItem(parent);
 
-    class MyGraphicsView : public QGraphicsView
-    { public:
-        int repaints;
-        MyGraphicsView(QGraphicsScene *scene) : QGraphicsView(scene), repaints(0) {}
-        void paintEvent(QPaintEvent *e) { ++repaints; QGraphicsView::paintEvent(e); }
-    };
-
     MyGraphicsView view(&scene);
     view.show();
     QTest::qWaitForWindowShown(&view);
@@ -6336,20 +6350,6 @@
     QGraphicsScene scene;
     scene.addItem(parent);
 
-    class MyGraphicsView : public QGraphicsView
-    { public:
-        int repaints;
-        QRegion paintedRegion;
-        MyGraphicsView(QGraphicsScene *scene) : QGraphicsView(scene), repaints(0) {}
-        void paintEvent(QPaintEvent *e)
-        {
-            ++repaints;
-            paintedRegion += e->region();
-            QGraphicsView::paintEvent(e);
-        }
-        void reset() { repaints = 0; paintedRegion = QRegion(); }
-    };
-
     MyGraphicsView view(&scene);
     view.show();
     QTest::qWaitForWindowShown(&view);
@@ -6825,6 +6825,9 @@
     QTRY_COMPARE(tester->repaints, 4);
     QCOMPARE(testerChild->repaints, 4);
     QCOMPARE(testerChild2->repaints, 3);
+    tester->resetTransform();
+    testerChild->resetTransform();
+    testerChild2->resetTransform();
 
     // Explicit update causes a repaint.
     tester->update(0, 0, 5, 5);
@@ -6898,23 +6901,24 @@
     // because the parent is rotated with a perspective.
     testerChild->setPos(1, 1);
     QTest::qWait(25);
-    QTRY_COMPARE(tester->repaints, 10);
+    QTRY_COMPARE(tester->repaints, 11);
     QCOMPARE(testerChild->repaints, 10);
     QCOMPARE(testerChild2->repaints, 5);
+    tester->resetTransform();
 
     // Make a huge item
     tester->setGeometry(QRectF(-4000, -4000, 8000, 8000));
     QTest::qWait(25);
-    QTRY_COMPARE(tester->repaints, 11);
-    QCOMPARE(testerChild->repaints, 10);
+    QTRY_COMPARE(tester->repaints, 12);
+    QCOMPARE(testerChild->repaints, 11);
     QCOMPARE(testerChild2->repaints, 5);
 
     // Move the large item - will cause a repaint as the
     // cache is clipped.
     tester->setPos(5, 0);
     QTest::qWait(25);
-    QTRY_COMPARE(tester->repaints, 12);
-    QCOMPARE(testerChild->repaints, 10);
+    QTRY_COMPARE(tester->repaints, 13);
+    QCOMPARE(testerChild->repaints, 11);
     QCOMPARE(testerChild2->repaints, 5);
 
     // Hiding and showing should invalidate the cache
@@ -6922,11 +6926,83 @@
     QTest::qWait(25);
     tester->show();
     QTest::qWait(25);
-    QTRY_COMPARE(tester->repaints, 13);
-    QCOMPARE(testerChild->repaints, 11);
+    QTRY_COMPARE(tester->repaints, 14);
+    QCOMPARE(testerChild->repaints, 12);
     QCOMPARE(testerChild2->repaints, 6);
 }
 
+void tst_QGraphicsItem::cacheMode2()
+{
+    QGraphicsScene scene(0, 0, 100, 100);
+    QGraphicsView view(&scene);
+    view.resize(150, 150);
+    view.show();
+    QApplication::setActiveWindow(&view);
+    QTest::qWaitForWindowShown(&view);
+
+    // Increase the probability of window activation
+    // not causing another repaint of test items.
+    QTest::qWait(50);
+
+    EventTester *tester = new EventTester;
+    scene.addItem(tester);
+    QTest::qWait(10);
+    QTRY_COMPARE(tester->repaints, 1);
+
+    // Switching from NoCache to NoCache (no repaint)
+    tester->setCacheMode(QGraphicsItem::NoCache);
+    QTest::qWait(50);
+    QTRY_COMPARE(tester->repaints, 1);
+
+    // Switching from NoCache to DeviceCoordinateCache (no repaint)
+    tester->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
+    QTest::qWait(50);
+    QTRY_COMPARE(tester->repaints, 1);
+
+    // Switching from DeviceCoordinateCache to DeviceCoordinateCache (no repaint)
+    tester->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
+    QTest::qWait(50);
+    QTRY_COMPARE(tester->repaints, 1);
+
+    // Switching from DeviceCoordinateCache to NoCache (no repaint)
+    tester->setCacheMode(QGraphicsItem::NoCache);
+    QTest::qWait(50);
+    QTRY_COMPARE(tester->repaints, 1);
+
+    // Switching from NoCache to ItemCoordinateCache (repaint)
+    tester->setCacheMode(QGraphicsItem::ItemCoordinateCache);
+    QTest::qWait(50);
+    QTRY_COMPARE(tester->repaints, 2);
+
+    // Switching from ItemCoordinateCache to ItemCoordinateCache (no repaint)
+    tester->setCacheMode(QGraphicsItem::ItemCoordinateCache);
+    QTest::qWait(50);
+    QTRY_COMPARE(tester->repaints, 2);
+
+    // Switching from ItemCoordinateCache to ItemCoordinateCache with different size (repaint)
+    tester->setCacheMode(QGraphicsItem::ItemCoordinateCache, QSize(100, 100));
+    QTest::qWait(50);
+    QTRY_COMPARE(tester->repaints, 3);
+
+    // Switching from ItemCoordinateCache to NoCache (repaint)
+    tester->setCacheMode(QGraphicsItem::NoCache);
+    QTest::qWait(50);
+    QTRY_COMPARE(tester->repaints, 4);
+
+    // Switching from DeviceCoordinateCache to ItemCoordinateCache (repaint)
+    tester->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
+    QTest::qWait(50);
+    QTRY_COMPARE(tester->repaints, 4);
+    tester->setCacheMode(QGraphicsItem::ItemCoordinateCache);
+    QTest::qWait(50);
+    QTRY_COMPARE(tester->repaints, 5);
+
+    // Switching from ItemCoordinateCache to DeviceCoordinateCache (repaint)
+    tester->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
+    QTest::qWait(50);
+    QTRY_COMPARE(tester->repaints, 6);
+}
+
 void tst_QGraphicsItem::updateCachedItemAfterMove()
 {
     // A simple item that uses ItemCoordinateCache
@@ -7076,21 +7152,6 @@
     QCOMPARE(rect3->deviceTransform(deviceX).map(QPointF(50, 50)), mapResult3);
 }
 
-class MyGraphicsView : public QGraphicsView
-{
-public:
-    int repaints;
-    QRegion paintedRegion;
-    MyGraphicsView(QGraphicsScene *scene) : QGraphicsView(scene), repaints(0) {}
-    void paintEvent(QPaintEvent *e)
-    {
-        paintedRegion += e->region();
-        ++repaints;
-        QGraphicsView::paintEvent(e);
-    }
-    void reset() { repaints = 0; paintedRegion = QRegion(); }
-};
-
 void tst_QGraphicsItem::update()
 {
     QGraphicsScene scene;
@@ -9835,7 +9896,7 @@
     QCOMPARE(child2->changes.count(QGraphicsItem::ItemScenePositionHasChanged), 0);
 }
 
-void  tst_QGraphicsItem::QTBUG_5418_textItemSetDefaultColor()
+void tst_QGraphicsItem::QTBUG_5418_textItemSetDefaultColor()
 {
     struct Item : public QGraphicsTextItem
     {
@@ -9914,20 +9975,6 @@
     QGraphicsScene scene;
     scene.addItem(parent);
 
-    class MyGraphicsView : public QGraphicsView
-    { public:
-        int repaints;
-        QRegion paintedRegion;
-        MyGraphicsView(QGraphicsScene *scene) : QGraphicsView(scene), repaints(0) {}
-        void paintEvent(QPaintEvent *e)
-        {
-            ++repaints;
-            paintedRegion += e->region();
-            QGraphicsView::paintEvent(e);
-        }
-        void reset() { repaints = 0; paintedRegion = QRegion(); }
-    };
-
     MyGraphicsView view(&scene);
     view.show();
     QTest::qWaitForWindowShown(&view);
@@ -9955,5 +10002,184 @@
     QTRY_VERIFY(view.repaints == 1);
 }
 
+void tst_QGraphicsItem::QT_2653_fullUpdateDiscardingOpacityUpdate()
+{
+    QGraphicsScene scene(0, 0, 200, 200);
+    MyGraphicsView view(&scene);
+
+    EventTester *parentGreen = new EventTester();
+    parentGreen->setGeometry(QRectF(20, 20, 100, 100));
+    parentGreen->brush = Qt::green;
+
+    EventTester *childYellow = new EventTester(parentGreen);
+    childYellow->setGeometry(QRectF(10, 10, 50, 50));
+    childYellow->brush = Qt::yellow;
+
+    scene.addItem(parentGreen);
+
+    childYellow->setOpacity(0.0);
+    parentGreen->setOpacity(0.0);
+
+    // set any of the flags below to trigger a fullUpdate to reproduce the bug:
+    // ItemIgnoresTransformations, ItemClipsChildrenToShape, ItemIsSelectable
+    parentGreen->setFlag(QGraphicsItem::ItemIgnoresTransformations);
+
+    view.show();
+    QTest::qWaitForWindowShown(&view);
+    view.reset();
+
+    parentGreen->setOpacity(1.0);
+
+    QTRY_COMPARE(view.repaints, 1);
+
+    view.reset();
+    childYellow->repaints = 0;
+
+    childYellow->setOpacity(1.0);
+
+    QTRY_COMPARE(view.repaints, 1);
+    QTRY_COMPARE(childYellow->repaints, 1);
+}
+
+void tst_QGraphicsItem::QTBUG_7714_fullUpdateDiscardingOpacityUpdate2()
+{
+    QGraphicsScene scene(0, 0, 200, 200);
+    MyGraphicsView view(&scene);
+    MyGraphicsView origView(&scene);
+
+    EventTester *parentGreen = new EventTester();
+    parentGreen->setGeometry(QRectF(20, 20, 100, 100));
+    parentGreen->brush = Qt::green;
+
+    EventTester *childYellow = new EventTester(parentGreen);
+    childYellow->setGeometry(QRectF(10, 10, 50, 50));
+    childYellow->brush = Qt::yellow;
+
+    scene.addItem(parentGreen);
+
+    origView.show();
+    QTest::qWaitForWindowShown(&origView);
+    origView.setGeometry(origView.width() + 20, 20,
+                         origView.width(), origView.height());
+
+    parentGreen->setFlag(QGraphicsItem::ItemIgnoresTransformations);
+
+    origView.reset();
+    childYellow->setOpacity(0.0);
+
+    QTRY_COMPARE(origView.repaints, 1);
+
+    view.show();
+
+    QTest::qWaitForWindowShown(&view);
+    view.reset();
+    origView.reset();
+
+    childYellow->setOpacity(1.0);
+
+    QTRY_COMPARE(origView.repaints, 1);
+    QTRY_COMPARE(view.repaints, 1);
+}
+
+void tst_QGraphicsItem::QT_2649_focusScope()
+{
+    QGraphicsScene *scene = new QGraphicsScene;
+
+    QGraphicsRectItem *subFocusItem = new QGraphicsRectItem;
+    subFocusItem->setFlags(QGraphicsItem::ItemIsFocusable);
+    subFocusItem->setFocus();
+    QCOMPARE(subFocusItem->focusItem(), (QGraphicsItem *)subFocusItem);
+
+    QGraphicsRectItem *scope = new QGraphicsRectItem;
+    scope->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsFocusScope);
+    scope->setFocus();
+    subFocusItem->setParentItem(scope);
+    QCOMPARE(subFocusItem->focusItem(), (QGraphicsItem *)subFocusItem);
+    QCOMPARE(subFocusItem->focusScopeItem(), (QGraphicsItem *)0);
+    QCOMPARE(scope->focusItem(), (QGraphicsItem *)subFocusItem);
+    QCOMPARE(scope->focusScopeItem(), (QGraphicsItem *)subFocusItem);
+
+    QGraphicsRectItem *rootItem = new QGraphicsRectItem;
+    rootItem->setFlags(QGraphicsItem::ItemIsFocusable);
+    scope->setParentItem(rootItem);
+    QCOMPARE(rootItem->focusItem(), (QGraphicsItem *)subFocusItem);
+    QCOMPARE(rootItem->focusScopeItem(), (QGraphicsItem *)0);
+    QCOMPARE(subFocusItem->focusItem(), (QGraphicsItem *)subFocusItem);
+    QCOMPARE(subFocusItem->focusScopeItem(), (QGraphicsItem *)0);
+    QCOMPARE(scope->focusItem(), (QGraphicsItem *)subFocusItem);
+    QCOMPARE(scope->focusScopeItem(), (QGraphicsItem *)subFocusItem);
+
+    scene->addItem(rootItem);
+
+    QEvent windowActivate(QEvent::WindowActivate);
+    qApp->sendEvent(scene, &windowActivate);
+    scene->setFocus();
+
+    QCOMPARE(rootItem->focusItem(), (QGraphicsItem *)subFocusItem);
+    QCOMPARE(scope->focusItem(), (QGraphicsItem *)subFocusItem);
+    QCOMPARE(subFocusItem->focusItem(), (QGraphicsItem *)subFocusItem);
+    QCOMPARE(rootItem->focusScopeItem(), (QGraphicsItem *)0);
+    QCOMPARE(scope->focusScopeItem(), (QGraphicsItem *)subFocusItem);
+    QCOMPARE(subFocusItem->focusScopeItem(), (QGraphicsItem *)0);
+    QVERIFY(subFocusItem->hasFocus());
+
+    scope->hide();
+
+    QCOMPARE(rootItem->focusItem(), (QGraphicsItem *)0);
+    QCOMPARE(scope->focusItem(), (QGraphicsItem *)0);
+    QCOMPARE(subFocusItem->focusItem(), (QGraphicsItem *)0);
+    QCOMPARE(rootItem->focusScopeItem(), (QGraphicsItem *)0);
+    QCOMPARE(scope->focusScopeItem(), (QGraphicsItem *)subFocusItem);
+    QCOMPARE(subFocusItem->focusScopeItem(), (QGraphicsItem *)0);
+    QVERIFY(!subFocusItem->hasFocus());
+
+    scope->show();
+
+    QCOMPARE(rootItem->focusItem(), (QGraphicsItem *)subFocusItem);
+    QCOMPARE(scope->focusItem(), (QGraphicsItem *)subFocusItem);
+    QCOMPARE(subFocusItem->focusItem(), (QGraphicsItem *)subFocusItem);
+    QCOMPARE(rootItem->focusScopeItem(), (QGraphicsItem *)0);
+    QCOMPARE(scope->focusScopeItem(), (QGraphicsItem *)subFocusItem);
+    QCOMPARE(subFocusItem->focusScopeItem(), (QGraphicsItem *)0);
+    QVERIFY(subFocusItem->hasFocus());
+
+    // This should not crash
+    scope->hide();
+    delete scene;
+}
+
+class MyGraphicsItemWithItemChange : public QGraphicsWidget
+{
+public:
+    MyGraphicsItemWithItemChange(QGraphicsItem *parent = 0) : QGraphicsWidget(parent)
+    {}
+
+    QVariant itemChange(GraphicsItemChange change, const QVariant &value)
+    {
+        if (change == QGraphicsItem::ItemSceneHasChanged) {
+            foreach (QGraphicsView *view, scene()->views()) {
+                //We trigger a sort of unindexed items in the BSP
+                view->sceneRect();
+            }
+        }
+        return QGraphicsWidget::itemChange(change, value);
+    }
+};
+
+void tst_QGraphicsItem::sortItemsWhileAdding()
+{
+    QGraphicsScene scene;
+    QGraphicsView view(&scene);
+    QGraphicsWidget grandGrandParent;
+    grandGrandParent.resize(200, 200);
+    scene.addItem(&grandGrandParent);
+    QGraphicsWidget grandParent;
+    grandParent.resize(200, 200);
+    QGraphicsWidget parent(&grandParent);
+    parent.resize(200, 200);
+    MyGraphicsItemWithItemChange item(&parent);
+    grandParent.setParentItem(&grandGrandParent);
+}
+
 QTEST_MAIN(tst_QGraphicsItem)
 #include "tst_qgraphicsitem.moc"