tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp
changeset 7 f7bc934e204c
parent 3 41300fa6a67c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the test suite of the Qt Toolkit.
     7 ** This file is part of the test suite of the Qt Toolkit.
     8 **
     8 **
   242     void dragAndDrop_disabledOrInvisible();
   242     void dragAndDrop_disabledOrInvisible();
   243     void dragAndDrop_propagate();
   243     void dragAndDrop_propagate();
   244 #endif
   244 #endif
   245     void render_data();
   245     void render_data();
   246     void render();
   246     void render();
       
   247     void renderItemsWithNegativeWidthOrHeight();
   247     void contextMenuEvent();
   248     void contextMenuEvent();
   248     void contextMenuEvent_ItemIgnoresTransformations();
   249     void contextMenuEvent_ItemIgnoresTransformations();
   249     void update();
   250     void update();
   250     void update2();
   251     void update2();
   251     void views();
   252     void views();
   268     void inputMethod();
   269     void inputMethod();
   269     void dispatchHoverOnPress();
   270     void dispatchHoverOnPress();
   270     void initialFocus_data();
   271     void initialFocus_data();
   271     void initialFocus();
   272     void initialFocus();
   272     void polishItems();
   273     void polishItems();
       
   274     void polishItems2();
   273     void isActive();
   275     void isActive();
   274     void siblingIndexAlwaysValid();
   276     void siblingIndexAlwaysValid();
   275 
   277 
   276     // task specific tests below me
   278     // task specific tests below me
   277     void task139710_bspTreeCrash();
   279     void task139710_bspTreeCrash();
   279     void task176178_itemIndexMethodBreaksSceneRect();
   281     void task176178_itemIndexMethodBreaksSceneRect();
   280     void task160653_selectionChanged();
   282     void task160653_selectionChanged();
   281     void task250680_childClip();
   283     void task250680_childClip();
   282     void taskQTBUG_5904_crashWithDeviceCoordinateCache();
   284     void taskQTBUG_5904_crashWithDeviceCoordinateCache();
   283     void taskQT657_paintIntoCacheWithTransparentParts();
   285     void taskQT657_paintIntoCacheWithTransparentParts();
       
   286     void taskQTBUG_7863_paintIntoCacheWithTransparentParts();
   284 };
   287 };
   285 
   288 
   286 void tst_QGraphicsScene::initTestCase()
   289 void tst_QGraphicsScene::initTestCase()
   287 {
   290 {
   288 #ifdef Q_OS_WINCE //disable magic for WindowsCE
   291 #ifdef Q_OS_WINCE //disable magic for WindowsCE
  2747         qDebug() << "Updating" << QTest::currentDataTag() << ":" << bigImage.save(fileName, "png");
  2750         qDebug() << "Updating" << QTest::currentDataTag() << ":" << bigImage.save(fileName, "png");
  2748 #endif
  2751 #endif
  2749     }
  2752     }
  2750 }
  2753 }
  2751 
  2754 
       
  2755 void tst_QGraphicsScene::renderItemsWithNegativeWidthOrHeight()
       
  2756 {
       
  2757     QGraphicsScene scene(0, 0, 150, 150);
       
  2758 
       
  2759     // Add item with negative width.
       
  2760     QGraphicsRectItem *item1 = new QGraphicsRectItem(0, 0, -150, 50);
       
  2761     item1->setBrush(Qt::red);
       
  2762     item1->setPos(150, 50);
       
  2763     scene.addItem(item1);
       
  2764 
       
  2765     // Add item with negative height.
       
  2766     QGraphicsRectItem *item2 = new QGraphicsRectItem(0, 0, 50, -150);
       
  2767     item2->setBrush(Qt::blue);
       
  2768     item2->setPos(50, 150);
       
  2769     scene.addItem(item2);
       
  2770 
       
  2771     QGraphicsView view(&scene);
       
  2772     view.setFrameStyle(QFrame::NoFrame);
       
  2773     view.resize(150, 150);
       
  2774     view.show();
       
  2775     QCOMPARE(view.viewport()->size(), QSize(150, 150));
       
  2776 
       
  2777     QImage expected(view.viewport()->size(), QImage::Format_RGB32);
       
  2778     view.viewport()->render(&expected);
       
  2779 
       
  2780     // Make sure the scene background is the same as the viewport background.
       
  2781     scene.setBackgroundBrush(view.viewport()->palette().brush(view.viewport()->backgroundRole()));
       
  2782     QImage actual(150, 150, QImage::Format_RGB32);
       
  2783     QPainter painter(&actual);
       
  2784     scene.render(&painter);
       
  2785     painter.end();
       
  2786 
       
  2787     QCOMPARE(actual, expected);
       
  2788 }
       
  2789 
  2752 void tst_QGraphicsScene::contextMenuEvent()
  2790 void tst_QGraphicsScene::contextMenuEvent()
  2753 {
  2791 {
  2754     QGraphicsScene scene;
  2792     QGraphicsScene scene;
  2755     QEvent activate(QEvent::WindowActivate);
  2793     QEvent activate(QEvent::WindowActivate);
  2756     QApplication::sendEvent(&scene, &activate);
  2794     QApplication::sendEvent(&scene, &activate);
  2803     qt_x11_wait_for_window_manager(&view);
  2841     qt_x11_wait_for_window_manager(&view);
  2804 #endif
  2842 #endif
  2805 
  2843 
  2806     {
  2844     {
  2807         QPoint pos(50, 50);
  2845         QPoint pos(50, 50);
  2808         QContextMenuEvent event(QContextMenuEvent::Keyboard, pos, view.mapToGlobal(pos));
  2846         QContextMenuEvent event(QContextMenuEvent::Keyboard, pos, view.viewport()->mapToGlobal(pos));
  2809         event.ignore();
  2847         event.ignore();
  2810         QApplication::sendEvent(view.viewport(), &event);
  2848         QApplication::sendEvent(view.viewport(), &event);
  2811         QVERIFY(event.isAccepted());
  2849         QVERIFY(event.isAccepted());
  2812     }
  2850     }
  2813     {
  2851     {
  2814         QPoint pos(150, 150);
  2852         QPoint pos(150, 150);
  2815         QContextMenuEvent event(QContextMenuEvent::Keyboard, pos, view.mapToGlobal(pos));
  2853         QContextMenuEvent event(QContextMenuEvent::Keyboard, pos, view.viewport()->mapToGlobal(pos));
  2816         event.ignore();
  2854         event.ignore();
  2817         QApplication::sendEvent(view.viewport(), &event);
  2855         QApplication::sendEvent(view.viewport(), &event);
  2818         QVERIFY(!event.isAccepted());
  2856         QVERIFY(!event.isAccepted());
  2819     }
  2857     }
  2820     view.scale(1.5, 1.5);
  2858     view.scale(1.5, 1.5);
  2821     {
  2859     {
  2822         QPoint pos(25, 25);
  2860         QPoint pos(25, 25);
  2823         QContextMenuEvent event(QContextMenuEvent::Keyboard, pos, view.mapToGlobal(pos));
  2861         QContextMenuEvent event(QContextMenuEvent::Keyboard, pos, view.viewport()->mapToGlobal(pos));
  2824         event.ignore();
  2862         event.ignore();
  2825         QApplication::sendEvent(view.viewport(), &event);
  2863         QApplication::sendEvent(view.viewport(), &event);
  2826         QVERIFY(event.isAccepted());
  2864         QVERIFY(event.isAccepted());
  2827     }
  2865     }
  2828     {
  2866     {
  2829         QPoint pos(55, 55);
  2867         QPoint pos(55, 55);
  2830         QContextMenuEvent event(QContextMenuEvent::Keyboard, pos, view.mapToGlobal(pos));
  2868         QContextMenuEvent event(QContextMenuEvent::Keyboard, pos, view.viewport()->mapToGlobal(pos));
  2831         event.ignore();
  2869         event.ignore();
  2832         QApplication::sendEvent(view.viewport(), &event);
  2870         QApplication::sendEvent(view.viewport(), &event);
  2833         QVERIFY(!event.isAccepted());
  2871         QVERIFY(!event.isAccepted());
  2834     }
  2872     }
  2835 }
  2873 }
  3940 }
  3978 }
  3941 
  3979 
  3942 class PolishItem : public QGraphicsTextItem
  3980 class PolishItem : public QGraphicsTextItem
  3943 {
  3981 {
  3944 public:
  3982 public:
  3945     PolishItem(QGraphicsItem *parent = 0) : QGraphicsTextItem(parent) { }
  3983     PolishItem(QGraphicsItem *parent = 0)
  3946 
  3984         : QGraphicsTextItem(parent), polished(false), deleteChildrenInPolish(true), addChildrenInPolish(false) { }
       
  3985 
       
  3986     bool polished;
       
  3987     bool deleteChildrenInPolish;
       
  3988     bool addChildrenInPolish;
  3947 protected:
  3989 protected:
  3948     QVariant itemChange(GraphicsItemChange change, const QVariant& value)
  3990     QVariant itemChange(GraphicsItemChange change, const QVariant& value)
  3949     {
  3991     {
  3950         if (change == ItemVisibleChange) {
  3992         if (change == ItemVisibleChange) {
  3951             if (value.toBool())
  3993             polished = true;
       
  3994             if (deleteChildrenInPolish)
  3952                 qDeleteAll(childItems());
  3995                 qDeleteAll(childItems());
       
  3996             if (addChildrenInPolish) {
       
  3997                 for (int i = 0; i < 10; ++i)
       
  3998                     new PolishItem(this);
       
  3999             }
  3953         }
  4000         }
  3954         return QGraphicsItem::itemChange(change, value);
  4001         return QGraphicsItem::itemChange(change, value);
  3955     }
  4002     }
  3956 };
  4003 };
  3957 
  4004 
  3962     scene.addItem(parent);
  4009     scene.addItem(parent);
  3963     PolishItem *child = new PolishItem(parent);
  4010     PolishItem *child = new PolishItem(parent);
  3964     Q_UNUSED(child)
  4011     Q_UNUSED(child)
  3965     // test that QGraphicsScenePrivate::_q_polishItems() doesn't crash
  4012     // test that QGraphicsScenePrivate::_q_polishItems() doesn't crash
  3966     QMetaObject::invokeMethod(&scene,"_q_polishItems");
  4013     QMetaObject::invokeMethod(&scene,"_q_polishItems");
       
  4014 }
       
  4015 
       
  4016 void tst_QGraphicsScene::polishItems2()
       
  4017 {
       
  4018     QGraphicsScene scene;
       
  4019     PolishItem *item = new PolishItem;
       
  4020     item->addChildrenInPolish = true;
       
  4021     item->deleteChildrenInPolish = true;
       
  4022     // These children should be deleted in the polish.
       
  4023     for (int i = 0; i < 20; ++i)
       
  4024         new PolishItem(item);
       
  4025     scene.addItem(item);
       
  4026 
       
  4027     // Wait for the polish event to be delivered.
       
  4028     QVERIFY(!item->polished);
       
  4029     QApplication::sendPostedEvents(&scene, QEvent::MetaCall);
       
  4030     QVERIFY(item->polished);
       
  4031 
       
  4032     // We deleted the children we added above, but we also
       
  4033     // added 10 new children. These should be polished in the next
       
  4034     // event loop iteration.
       
  4035     QList<QGraphicsItem *> children = item->childItems();
       
  4036     QCOMPARE(children.count(), 10);
       
  4037     foreach (QGraphicsItem *child, children)
       
  4038         QVERIFY(!static_cast<PolishItem *>(child)->polished);
       
  4039 
       
  4040     QApplication::sendPostedEvents(&scene, QEvent::MetaCall);
       
  4041     foreach (QGraphicsItem *child, children)
       
  4042         QVERIFY(static_cast<PolishItem *>(child)->polished);
  3967 }
  4043 }
  3968 
  4044 
  3969 void tst_QGraphicsScene::isActive()
  4045 void tst_QGraphicsScene::isActive()
  3970 {
  4046 {
  3971     QGraphicsScene scene1;
  4047     QGraphicsScene scene1;
  4271     // No crash, then it passed!
  4347     // No crash, then it passed!
  4272 }
  4348 }
  4273 
  4349 
  4274 void tst_QGraphicsScene::taskQT657_paintIntoCacheWithTransparentParts()
  4350 void tst_QGraphicsScene::taskQT657_paintIntoCacheWithTransparentParts()
  4275 {
  4351 {
       
  4352     // Test using DeviceCoordinateCache and opaque item
  4276     QWidget *w = new QWidget();
  4353     QWidget *w = new QWidget();
  4277     w->setPalette(Qt::blue);
  4354     w->setPalette(QColor(0, 0, 255));
  4278     w->setGeometry(0, 0, 50, 50);
  4355     w->setGeometry(0, 0, 50, 50);
  4279 
  4356 
  4280     QGraphicsScene *scene = new QGraphicsScene();
  4357     QGraphicsScene *scene = new QGraphicsScene();
  4281     QGraphicsView *view = new QGraphicsView(scene);
  4358     CustomView *view = new CustomView;
       
  4359     view->setScene(scene);
  4282 
  4360 
  4283     QGraphicsProxyWidget *proxy = scene->addWidget(w);
  4361     QGraphicsProxyWidget *proxy = scene->addWidget(w);
  4284     proxy->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
  4362     proxy->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
  4285     proxy->rotate(15);
  4363     proxy->rotate(15);
  4286 
  4364 
  4287     view->show();
  4365     view->show();
  4288     QTest::qWaitForWindowShown(view);
  4366     QTest::qWaitForWindowShown(view);
  4289     w->update(10,10,10,10);
  4367     view->repaints = 0;
       
  4368     proxy->update(10, 10, 10, 10);
  4290     QTest::qWait(50);
  4369     QTest::qWait(50);
       
  4370     QTRY_VERIFY(view->repaints > 0);
  4291 
  4371 
  4292     QPixmap pix;
  4372     QPixmap pix;
  4293     QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(proxy);
  4373     QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(proxy);
  4294     QPixmapCache::Key key = itemp->extraItemCache()->deviceData.value(view->viewport()).key;
  4374     QTRY_VERIFY(QPixmapCache::find(itemp->extraItemCache()->deviceData.value(view->viewport()).key, &pix));
  4295     QVERIFY(QPixmapCache::find(key, &pix));
       
  4296 
  4375 
  4297     QTransform t = proxy->sceneTransform();
  4376     QTransform t = proxy->sceneTransform();
  4298     // Map from scene coordinates to pixmap coordinates.
  4377     // Map from scene coordinates to pixmap coordinates.
  4299     // X origin in the pixmap is the most-left point
  4378     // X origin in the pixmap is the most-left point
  4300     // of the item's boundingRect in the scene.
  4379     // of the item's boundingRect in the scene.
  4305     QImage im = subpix.toImage();
  4384     QImage im = subpix.toImage();
  4306     for(int i = 0; i < im.width(); i++) {
  4385     for(int i = 0; i < im.width(); i++) {
  4307         for(int j = 0; j < im.height(); j++)
  4386         for(int j = 0; j < im.height(); j++)
  4308             QCOMPARE(qAlpha(im.pixel(i, j)), 255);
  4387             QCOMPARE(qAlpha(im.pixel(i, j)), 255);
  4309     }
  4388     }
       
  4389 
       
  4390     delete w;
       
  4391 }
       
  4392 
       
  4393 void tst_QGraphicsScene::taskQTBUG_7863_paintIntoCacheWithTransparentParts()
       
  4394 {
       
  4395     // Test using DeviceCoordinateCache and semi-transparent item
       
  4396     {
       
  4397         QGraphicsRectItem *backItem = new QGraphicsRectItem(0, 0, 100, 100);
       
  4398         backItem->setBrush(QColor(255, 255, 0));
       
  4399         QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 50, 50);
       
  4400         rectItem->setBrush(QColor(0, 0, 255, 125));
       
  4401         rectItem->setParentItem(backItem);
       
  4402 
       
  4403         QGraphicsScene *scene = new QGraphicsScene();
       
  4404         CustomView *view = new CustomView;
       
  4405         view->setScene(scene);
       
  4406 
       
  4407         scene->addItem(backItem);
       
  4408         rectItem->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
       
  4409         backItem->rotate(15);
       
  4410 
       
  4411         view->show();
       
  4412         QTest::qWaitForWindowShown(view);
       
  4413         view->repaints = 0;
       
  4414         rectItem->update(10, 10, 10, 10);
       
  4415         QTest::qWait(50);
       
  4416         QTRY_VERIFY(view->repaints > 0);
       
  4417 
       
  4418         QPixmap pix;
       
  4419         QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(rectItem);
       
  4420         QTRY_VERIFY(QPixmapCache::find(itemp->extraItemCache()->deviceData.value(view->viewport()).key, &pix));
       
  4421 
       
  4422         QTransform t = rectItem->sceneTransform();
       
  4423         // Map from scene coordinates to pixmap coordinates.
       
  4424         // X origin in the pixmap is the most-left point
       
  4425         // of the item's boundingRect in the scene.
       
  4426         qreal adjust = t.mapRect(rectItem->boundingRect().toRect()).left();
       
  4427         QRect rect = t.mapRect(QRect(10, 10, 10, 10)).adjusted(-adjust, 0, -adjust + 1, 1);
       
  4428         QPixmap subpix = pix.copy(rect);
       
  4429 
       
  4430         QImage im = subpix.toImage();
       
  4431         for(int i = 0; i < im.width(); i++) {
       
  4432             for(int j = 0; j < im.height(); j++) {
       
  4433                 QCOMPARE(qAlpha(im.pixel(i, j)), 125);
       
  4434             }
       
  4435         }
       
  4436 
       
  4437         delete view;
       
  4438     }
       
  4439 
       
  4440     // Test using ItemCoordinateCache and opaque item
       
  4441     {
       
  4442         QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 50, 50);
       
  4443         rectItem->setBrush(QColor(0, 0, 255));
       
  4444 
       
  4445         QGraphicsScene *scene = new QGraphicsScene();
       
  4446         CustomView *view = new CustomView;
       
  4447         view->setScene(scene);
       
  4448 
       
  4449         scene->addItem(rectItem);
       
  4450         rectItem->setCacheMode(QGraphicsItem::ItemCoordinateCache);
       
  4451         rectItem->rotate(15);
       
  4452 
       
  4453         view->show();
       
  4454         QTest::qWaitForWindowShown(view);
       
  4455         view->repaints = 0;
       
  4456         rectItem->update(10, 10, 10, 10);
       
  4457         QTest::qWait(50);
       
  4458         QTRY_VERIFY(view->repaints > 0);
       
  4459 
       
  4460         QPixmap pix;
       
  4461         QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(rectItem);
       
  4462         QTRY_VERIFY(QPixmapCache::find(itemp->extraItemCache()->key, &pix));
       
  4463 
       
  4464         QTransform t = rectItem->sceneTransform();
       
  4465         // Map from scene coordinates to pixmap coordinates.
       
  4466         // X origin in the pixmap is the most-left point
       
  4467         // of the item's boundingRect in the scene.
       
  4468         qreal adjust = t.mapRect(rectItem->boundingRect().toRect()).left();
       
  4469         QRect rect = t.mapRect(QRect(10, 10, 10, 10)).adjusted(-adjust, 0, -adjust + 1, 1);
       
  4470         QPixmap subpix = pix.copy(rect);
       
  4471 
       
  4472         QImage im = subpix.toImage();
       
  4473         for(int i = 0; i < im.width(); i++) {
       
  4474             for(int j = 0; j < im.height(); j++)
       
  4475                 QCOMPARE(qAlpha(im.pixel(i, j)), 255);
       
  4476         }
       
  4477 
       
  4478         delete view;
       
  4479     }
       
  4480 
       
  4481     // Test using ItemCoordinateCache and semi-transparent item
       
  4482     {
       
  4483         QGraphicsRectItem *rectItem = new QGraphicsRectItem(0, 0, 50, 50);
       
  4484         rectItem->setBrush(QColor(0, 0, 255, 125));
       
  4485 
       
  4486         QGraphicsScene *scene = new QGraphicsScene();
       
  4487         CustomView *view = new CustomView;
       
  4488         view->setScene(scene);
       
  4489 
       
  4490         scene->addItem(rectItem);
       
  4491         rectItem->setCacheMode(QGraphicsItem::ItemCoordinateCache);
       
  4492         rectItem->rotate(15);
       
  4493 
       
  4494         view->show();
       
  4495         QTest::qWaitForWindowShown(view);
       
  4496         view->repaints = 0;
       
  4497         rectItem->update(10, 10, 10, 10);
       
  4498         QTest::qWait(50);
       
  4499         QTRY_VERIFY(view->repaints > 0);
       
  4500 
       
  4501         QPixmap pix;
       
  4502         QGraphicsItemPrivate* itemp = QGraphicsItemPrivate::get(rectItem);
       
  4503         QTRY_VERIFY(QPixmapCache::find(itemp->extraItemCache()->key, &pix));
       
  4504 
       
  4505         QTransform t = rectItem->sceneTransform();
       
  4506         // Map from scene coordinates to pixmap coordinates.
       
  4507         // X origin in the pixmap is the most-left point
       
  4508         // of the item's boundingRect in the scene.
       
  4509         qreal adjust = t.mapRect(rectItem->boundingRect().toRect()).left();
       
  4510         QRect rect = t.mapRect(QRect(10, 10, 10, 10)).adjusted(-adjust, 0, -adjust + 1, 1);
       
  4511         QPixmap subpix = pix.copy(rect);
       
  4512 
       
  4513         QImage im = subpix.toImage();
       
  4514         for(int i = 0; i < im.width(); i++) {
       
  4515             for(int j = 0; j < im.height(); j++)
       
  4516                 QCOMPARE(qAlpha(im.pixel(i, j)), 125);
       
  4517         }
       
  4518 
       
  4519         delete view;
       
  4520     }
  4310 }
  4521 }
  4311 
  4522 
  4312 QTEST_MAIN(tst_QGraphicsScene)
  4523 QTEST_MAIN(tst_QGraphicsScene)
  4313 #include "tst_qgraphicsscene.moc"
  4524 #include "tst_qgraphicsscene.moc"