summaryrefslogtreecommitdiffstats
path: root/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp')
-rw-r--r--tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp435
1 files changed, 428 insertions, 7 deletions
diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
index 0f2d671..58a17ea 100644
--- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -42,10 +42,6 @@
#include <QtTest/QtTest>
-#if QT_VERSION < 0x040200
-QTEST_NOOP_MAIN
-#else
-
#include <private/qtextcontrol_p.h>
#include <private/qgraphicsitem_p.h>
#include <QAbstractTextDocumentLayout>
@@ -82,8 +78,7 @@ Q_DECLARE_METATYPE(QRectF)
class EventTester : public QGraphicsItem
{
public:
- EventTester()
- : repaints(0)
+ EventTester(QGraphicsItem *parent = 0) : QGraphicsItem(parent), repaints(0)
{ br = QRectF(-10, -10, 20, 20); }
void setGeometry(const QRectF &rect)
@@ -162,6 +157,8 @@ private slots:
void mapFromToParent();
void mapFromToScene();
void mapFromToItem();
+ void mapRectFromToParent_data();
+ void mapRectFromToParent();
void isAncestorOf();
void commonAncestorItem();
void data();
@@ -209,6 +206,7 @@ private slots:
void itemTransform_unrelated();
void opacity_data();
void opacity();
+ void opacity2();
void itemStacksBehindParent();
void nestedClipping();
void nestedClippingTransforms();
@@ -216,10 +214,14 @@ private slots:
void tabChangesFocus();
void tabChangesFocus_data();
void cacheMode();
+ void updateCachedItemAfterMove();
+ void deviceTransform_data();
+ void deviceTransform();
// task specific tests below me
void task141694_textItemEnsureVisible();
void task128696_textItemEnsureMovable();
+ void ensureUpdateOnTextItem();
void task177918_lineItemUndetected();
void task240400_clickOnTextItem_data();
void task240400_clickOnTextItem();
@@ -2515,6 +2517,87 @@ void tst_QGraphicsItem::mapFromToItem()
delete item4;
}
+void tst_QGraphicsItem::mapRectFromToParent_data()
+{
+ QTest::addColumn<bool>("parent");
+ QTest::addColumn<QPointF>("parentPos");
+ QTest::addColumn<QTransform>("parentTransform");
+ QTest::addColumn<QPointF>("pos");
+ QTest::addColumn<QTransform>("transform");
+ QTest::addColumn<QRectF>("inputRect");
+ QTest::addColumn<QRectF>("outputRect");
+
+ QTest::newRow("nil") << false << QPointF() << QTransform() << QPointF() << QTransform() << QRectF() << QRectF();
+ QTest::newRow("simple") << false << QPointF() << QTransform() << QPointF() << QTransform()
+ << QRectF(0, 0, 10, 10) << QRectF(0, 0, 10, 10);
+ QTest::newRow("simple w/parent") << true
+ << QPointF() << QTransform()
+ << QPointF() << QTransform()
+ << QRectF(0, 0, 10, 10) << QRectF(0, 0, 10, 10);
+ QTest::newRow("simple w/parent parentPos") << true
+ << QPointF(50, 50) << QTransform()
+ << QPointF() << QTransform()
+ << QRectF(0, 0, 10, 10) << QRectF(0, 0, 10, 10);
+ QTest::newRow("simple w/parent parentPos parentRotation") << true
+ << QPointF(50, 50) << QTransform().rotate(45)
+ << QPointF() << QTransform()
+ << QRectF(0, 0, 10, 10) << QRectF(0, 0, 10, 10);
+ QTest::newRow("pos w/parent") << true
+ << QPointF() << QTransform()
+ << QPointF(50, 50) << QTransform()
+ << QRectF(0, 0, 10, 10) << QRectF(50, 50, 10, 10);
+ QTest::newRow("rotation w/parent") << true
+ << QPointF() << QTransform()
+ << QPointF() << QTransform().rotate(90)
+ << QRectF(0, 0, 10, 10) << QRectF(-10, 0, 10, 10);
+ QTest::newRow("pos rotation w/parent") << true
+ << QPointF() << QTransform()
+ << QPointF(50, 50) << QTransform().rotate(90)
+ << QRectF(0, 0, 10, 10) << QRectF(40, 50, 10, 10);
+ QTest::newRow("pos rotation w/parent parentPos parentRotation") << true
+ << QPointF(-170, -190) << QTransform().rotate(90)
+ << QPointF(50, 50) << QTransform().rotate(90)
+ << QRectF(0, 0, 10, 10) << QRectF(40, 50, 10, 10);
+}
+
+void tst_QGraphicsItem::mapRectFromToParent()
+{
+ QFETCH(bool, parent);
+ QFETCH(QPointF, parentPos);
+ QFETCH(QTransform, parentTransform);
+ QFETCH(QPointF, pos);
+ QFETCH(QTransform, transform);
+ QFETCH(QRectF, inputRect);
+ QFETCH(QRectF, outputRect);
+
+ QGraphicsRectItem *rect = new QGraphicsRectItem;
+ rect->setPos(pos);
+ rect->setTransform(transform);
+
+ if (parent) {
+ QGraphicsRectItem *rectParent = new QGraphicsRectItem;
+ rect->setParentItem(rectParent);
+ rectParent->setPos(parentPos);
+ rectParent->setTransform(parentTransform);
+ }
+
+ // Make sure we use non-destructive transform operations (e.g., 90 degree
+ // rotations).
+ QCOMPARE(rect->mapRectToParent(inputRect), outputRect);
+ QCOMPARE(rect->mapRectFromParent(outputRect), inputRect);
+ QCOMPARE(rect->itemTransform(rect->parentItem()).mapRect(inputRect), outputRect);
+ QCOMPARE(rect->mapToParent(inputRect).boundingRect(), outputRect);
+ QCOMPARE(rect->mapToParent(QPolygonF(inputRect)).boundingRect(), outputRect);
+ QCOMPARE(rect->mapFromParent(outputRect).boundingRect(), inputRect);
+ QCOMPARE(rect->mapFromParent(QPolygonF(outputRect)).boundingRect(), inputRect);
+ QPainterPath inputPath;
+ inputPath.addRect(inputRect);
+ QPainterPath outputPath;
+ outputPath.addRect(outputRect);
+ QCOMPARE(rect->mapToParent(inputPath).boundingRect(), outputPath.boundingRect());
+ QCOMPARE(rect->mapFromParent(outputPath).boundingRect(), inputPath.boundingRect());
+}
+
void tst_QGraphicsItem::isAncestorOf()
{
QGraphicsItem *grandPa = new QGraphicsRectItem;
@@ -3574,6 +3657,8 @@ void tst_QGraphicsItem::defaultItemTest_QGraphicsEllipseItem()
class ItemChangeTester : public QGraphicsRectItem
{
public:
+ ItemChangeTester(){}
+ ItemChangeTester(QGraphicsItem *parent) : QGraphicsRectItem(parent) {}
QVariant itemChangeReturnValue;
QGraphicsScene *itemSceneChangeTargetScene;
@@ -3848,6 +3933,39 @@ void tst_QGraphicsItem::itemChange()
QCOMPARE(tester.changes.size(), ++changeCount);
QCOMPARE(tester.changes.last(), QGraphicsItem::ItemChildRemovedChange);
QCOMPARE(qVariantValue<QGraphicsItem *>(tester.values.last()), (QGraphicsItem *)&testerHelper);
+
+ // ItemChildRemovedChange 1
+ ItemChangeTester *test = new ItemChangeTester;
+ test->itemSceneChangeTargetScene = 0;
+ int count = 0;
+ QGraphicsScene *scene = new QGraphicsScene;
+ scene->addItem(test);
+ count = test->changes.size();
+ //We test here the fact that when a child is deleted the parent receive only one ItemChildRemovedChange
+ QGraphicsRectItem *child = new QGraphicsRectItem(test);
+ //We received ItemChildAddedChange
+ QCOMPARE(test->changes.size(), ++count);
+ QCOMPARE(test->changes.last(), QGraphicsItem::ItemChildAddedChange);
+ delete child;
+ child = 0;
+ QCOMPARE(test->changes.size(), ++count);
+ QCOMPARE(test->changes.last(), QGraphicsItem::ItemChildRemovedChange);
+
+ ItemChangeTester *childTester = new ItemChangeTester(test);
+ //Changes contains all sceneHasChanged and so on, we don't want to test that
+ int childCount = childTester->changes.size();
+ //We received ItemChildAddedChange
+ QCOMPARE(test->changes.size(), ++count);
+ child = new QGraphicsRectItem(childTester);
+ //We received ItemChildAddedChange
+ QCOMPARE(childTester->changes.size(), ++childCount);
+ QCOMPARE(childTester->changes.last(), QGraphicsItem::ItemChildAddedChange);
+ //Delete the child of the top level with all its children
+ delete childTester;
+ //Only one removal
+ QCOMPARE(test->changes.size(), ++count);
+ QCOMPARE(test->changes.last(), QGraphicsItem::ItemChildRemovedChange);
+ delete scene;
}
{
// ItemChildRemovedChange 2
@@ -3934,8 +4052,26 @@ void tst_QGraphicsItem::itemChange()
tester.itemSceneChangeTargetScene = 0;
tester.itemChangeReturnValue = QVariant();
scene.removeItem(&tester);
+ ++changeCount; // ItemSceneChange
+ ++changeCount; // ItemSceneHasChanged
QCOMPARE(tester.scene(), (QGraphicsScene *)0);
}
+ {
+ // ItemToolTipChange/ItemToolTipHasChanged
+ const QString toolTip(QLatin1String("I'm soo cool"));
+ const QString overridenToolTip(QLatin1String("No, you are not soo cool"));
+ tester.itemChangeReturnValue = overridenToolTip;
+ tester.setToolTip(toolTip);
+ ++changeCount; // ItemToolTipChange
+ ++changeCount; // ItemToolTipHasChanged
+ QCOMPARE(tester.changes.size(), changeCount);
+ QCOMPARE(tester.changes.at(changeCount - 2), QGraphicsItem::ItemToolTipChange);
+ QCOMPARE(tester.values.at(changeCount - 2).toString(), toolTip);
+ QCOMPARE(tester.changes.at(changeCount - 1), QGraphicsItem::ItemToolTipHasChanged);
+ QCOMPARE(tester.values.at(changeCount - 1).toString(), overridenToolTip);
+ QCOMPARE(tester.toolTip(), overridenToolTip);
+ tester.itemChangeReturnValue = QVariant();
+ }
}
class EventFilterTesterItem : public QGraphicsLineItem
@@ -4019,6 +4155,25 @@ void tst_QGraphicsItem::sceneEventFilter()
QCOMPARE(tester->filteredEventReceivers.at(6), static_cast<QGraphicsItem *>(text2));
QVERIFY(text2->hasFocus());
+
+ //Let check if the items are correctly removed from the sceneEventFilters array
+ //to avoid stale pointers.
+ QGraphicsView gv;
+ QGraphicsScene *anotherScene = new QGraphicsScene;
+ QGraphicsTextItem *ti = anotherScene->addText("This is a test #1");
+ ti->moveBy(50, 50);
+ QGraphicsTextItem *ti2 = anotherScene->addText("This is a test #2");
+ QGraphicsTextItem *ti3 = anotherScene->addText("This is a test #3");
+ gv.setScene(anotherScene);
+ gv.show();
+ QTest::qWait(250);
+ ti->installSceneEventFilter(ti2);
+ ti3->installSceneEventFilter(ti);
+ delete ti2;
+ //we souldn't crash
+ QTest::mouseMove(gv.viewport(), gv.mapFromScene(ti->scenePos()));
+ QTest::qWait(250);
+ delete ti;
}
class GeometryChanger : public QGraphicsItem
@@ -5152,6 +5307,39 @@ void tst_QGraphicsItem::task240400_clickOnTextItem()
QCOMPARE(item->textCursor().columnNumber(), 0);
}
+class TextItem : public QGraphicsSimpleTextItem
+{
+public:
+ TextItem(const QString& text) : QGraphicsSimpleTextItem(text)
+ {
+ updates = 0;
+ }
+
+ void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
+ {
+ updates++;
+ QGraphicsSimpleTextItem::paint(painter, option, widget);
+ }
+
+ int updates;
+};
+
+void tst_QGraphicsItem::ensureUpdateOnTextItem()
+{
+ QGraphicsScene scene;
+ TextItem *text1 = new TextItem(QLatin1String("123"));
+ scene.addItem(text1);
+ QGraphicsView view(&scene);
+ view.show();
+ QTest::qWait(250);
+ QCOMPARE(text1->updates,1);
+
+ //same bouding rect but we have to update
+ text1->setText(QLatin1String("321"));
+ QTest::qWait(250);
+ QCOMPARE(text1->updates,2);
+}
+
void tst_QGraphicsItem::task243707_addChildBeforeParent()
{
// Task reports that adding the child before the parent leads to an
@@ -5384,6 +5572,91 @@ void tst_QGraphicsItem::opacity()
QCOMPARE(c3->effectiveOpacity(), c3_effectiveOpacity);
}
+void tst_QGraphicsItem::opacity2()
+{
+ EventTester *parent = new EventTester;
+ EventTester *child = new EventTester(parent);
+ EventTester *grandChild = new EventTester(child);
+
+ 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();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QTest::qWait(250);
+
+#define RESET_REPAINT_COUNTERS \
+ parent->repaints = 0; \
+ child->repaints = 0; \
+ grandChild->repaints = 0; \
+ view.repaints = 0;
+
+ RESET_REPAINT_COUNTERS
+
+ child->setOpacity(0.0);
+ QTest::qWait(100);
+ QCOMPARE(view.repaints, 1);
+ QCOMPARE(parent->repaints, 1);
+ QCOMPARE(child->repaints, 0);
+ QCOMPARE(grandChild->repaints, 0);
+
+ RESET_REPAINT_COUNTERS
+
+ child->setOpacity(1.0);
+ QTest::qWait(100);
+ QCOMPARE(view.repaints, 1);
+ QCOMPARE(parent->repaints, 1);
+ QCOMPARE(child->repaints, 1);
+ QCOMPARE(grandChild->repaints, 1);
+
+ RESET_REPAINT_COUNTERS
+
+ parent->setOpacity(0.0);
+ QTest::qWait(100);
+ QCOMPARE(view.repaints, 1);
+ QCOMPARE(parent->repaints, 0);
+ QCOMPARE(child->repaints, 0);
+ QCOMPARE(grandChild->repaints, 0);
+
+ RESET_REPAINT_COUNTERS
+
+ parent->setOpacity(1.0);
+ QTest::qWait(100);
+ QCOMPARE(view.repaints, 1);
+ QCOMPARE(parent->repaints, 1);
+ QCOMPARE(child->repaints, 1);
+ QCOMPARE(grandChild->repaints, 1);
+
+ grandChild->setFlag(QGraphicsItem::ItemIgnoresParentOpacity);
+ RESET_REPAINT_COUNTERS
+
+ child->setOpacity(0.0);
+ QTest::qWait(100);
+ QCOMPARE(view.repaints, 1);
+ QCOMPARE(parent->repaints, 1);
+ QCOMPARE(child->repaints, 0);
+ QCOMPARE(grandChild->repaints, 1);
+
+ RESET_REPAINT_COUNTERS
+
+ child->setOpacity(0.0); // Already 0.0; no change.
+ QTest::qWait(100);
+ QCOMPARE(view.repaints, 0);
+ QCOMPARE(parent->repaints, 0);
+ QCOMPARE(child->repaints, 0);
+ QCOMPARE(grandChild->repaints, 0);
+}
+
void tst_QGraphicsItem::itemStacksBehindParent()
{
QGraphicsRectItem *parent1 = new QGraphicsRectItem(QRectF(0, 0, 100, 50));
@@ -5888,6 +6161,154 @@ void tst_QGraphicsItem::cacheMode()
QCOMPARE(testerChild2->repaints, 6);
}
+void tst_QGraphicsItem::updateCachedItemAfterMove()
+{
+ // A simple item that uses ItemCoordinateCache
+ EventTester *tester = new EventTester;
+ tester->setCacheMode(QGraphicsItem::ItemCoordinateCache);
+
+ // Add to a scene, show in a view, ensure it's painted and reset its
+ // repaint counter.
+ QGraphicsScene scene;
+ scene.addItem(tester);
+ QGraphicsView view(&scene);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QTest::qWait(125);
+ tester->repaints = 0;
+
+ // Move the item, should not cause repaints
+ tester->setPos(10, 0);
+ QTest::qWait(125);
+ QCOMPARE(tester->repaints, 0);
+
+ // Move then update, should cause one repaint
+ tester->setPos(20, 0);
+ tester->update();
+ QTest::qWait(125);
+ QCOMPARE(tester->repaints, 1);
+
+ // Hiding the item doesn't cause a repaint
+ tester->hide();
+ QTest::qWait(125);
+ QCOMPARE(tester->repaints, 1);
+
+ // Moving a hidden item doesn't cause a repaint
+ tester->setPos(30, 0);
+ tester->update();
+ QTest::qWait(125);
+ QCOMPARE(tester->repaints, 1);
+}
+
+class Track : public QGraphicsRectItem
+{
+public:
+ Track(const QRectF &rect)
+ : QGraphicsRectItem(rect)
+ {
+ setAcceptHoverEvents(true);
+ }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0)
+ {
+ QGraphicsRectItem::paint(painter, option, widget);
+ painter->drawText(boundingRect(), Qt::AlignCenter, QString("%1x%2\n%3x%4").arg(p.x()).arg(p.y()).arg(sp.x()).arg(sp.y()));
+ }
+
+protected:
+ void hoverMoveEvent(QGraphicsSceneHoverEvent *event)
+ {
+ p = event->pos();
+ sp = event->widget()->mapFromGlobal(event->screenPos());
+ update();
+ }
+private:
+ QPointF p;
+ QPoint sp;
+};
+
+void tst_QGraphicsItem::deviceTransform_data()
+{
+ QTest::addColumn<bool>("untransformable1");
+ QTest::addColumn<bool>("untransformable2");
+ QTest::addColumn<bool>("untransformable3");
+ QTest::addColumn<qreal>("rotation1");
+ QTest::addColumn<qreal>("rotation2");
+ QTest::addColumn<qreal>("rotation3");
+ QTest::addColumn<QTransform>("deviceX");
+ QTest::addColumn<QPointF>("mapResult1");
+ QTest::addColumn<QPointF>("mapResult2");
+ QTest::addColumn<QPointF>("mapResult3");
+
+ QTest::newRow("nil") << false << false << false
+ << qreal(0.0) << qreal(0.0) << qreal(0.0)
+ << QTransform()
+ << QPointF(150, 150) << QPointF(250, 250) << QPointF(350, 350);
+ QTest::newRow("deviceX rot 90") << false << false << false
+ << qreal(0.0) << qreal(0.0) << qreal(0.0)
+ << QTransform().rotate(90)
+ << QPointF(-150, 150) << QPointF(-250, 250) << QPointF(-350, 350);
+ QTest::newRow("deviceX rot 90 100") << true << false << false
+ << qreal(0.0) << qreal(0.0) << qreal(0.0)
+ << QTransform().rotate(90)
+ << QPointF(-50, 150) << QPointF(50, 250) << QPointF(150, 350);
+ QTest::newRow("deviceX rot 90 010") << false << true << false
+ << qreal(0.0) << qreal(0.0) << qreal(0.0)
+ << QTransform().rotate(90)
+ << QPointF(-150, 150) << QPointF(-150, 250) << QPointF(-50, 350);
+ QTest::newRow("deviceX rot 90 001") << false << false << true
+ << qreal(0.0) << qreal(0.0) << qreal(0.0)
+ << QTransform().rotate(90)
+ << QPointF(-150, 150) << QPointF(-250, 250) << QPointF(-250, 350);
+ QTest::newRow("deviceX rot 90 111") << true << true << true
+ << qreal(0.0) << qreal(0.0) << qreal(0.0)
+ << QTransform().rotate(90)
+ << QPointF(-50, 150) << QPointF(50, 250) << QPointF(150, 350);
+ QTest::newRow("deviceX rot 90 101") << true << false << true
+ << qreal(0.0) << qreal(0.0) << qreal(0.0)
+ << QTransform().rotate(90)
+ << QPointF(-50, 150) << QPointF(50, 250) << QPointF(150, 350);
+}
+
+void tst_QGraphicsItem::deviceTransform()
+{
+ QFETCH(bool, untransformable1);
+ QFETCH(bool, untransformable2);
+ QFETCH(bool, untransformable3);
+ QFETCH(qreal, rotation1);
+ QFETCH(qreal, rotation2);
+ QFETCH(qreal, rotation3);
+ QFETCH(QTransform, deviceX);
+ QFETCH(QPointF, mapResult1);
+ QFETCH(QPointF, mapResult2);
+ QFETCH(QPointF, mapResult3);
+
+ QGraphicsScene scene;
+ Track *rect1 = new Track(QRectF(0, 0, 100, 100));
+ Track *rect2 = new Track(QRectF(0, 0, 100, 100));
+ Track *rect3 = new Track(QRectF(0, 0, 100, 100));
+ rect2->setParentItem(rect1);
+ rect3->setParentItem(rect2);
+ rect1->setPos(100, 100);
+ rect2->setPos(100, 100);
+ rect3->setPos(100, 100);
+ rect1->rotate(rotation1);
+ rect2->rotate(rotation2);
+ rect3->rotate(rotation3);
+ rect1->setFlag(QGraphicsItem::ItemIgnoresTransformations, untransformable1);
+ rect2->setFlag(QGraphicsItem::ItemIgnoresTransformations, untransformable2);
+ rect3->setFlag(QGraphicsItem::ItemIgnoresTransformations, untransformable3);
+ rect1->setBrush(Qt::red);
+ rect2->setBrush(Qt::green);
+ rect3->setBrush(Qt::blue);
+ scene.addItem(rect1);
+
+ QCOMPARE(rect1->deviceTransform(deviceX).map(QPointF(50, 50)), mapResult1);
+ QCOMPARE(rect2->deviceTransform(deviceX).map(QPointF(50, 50)), mapResult2);
+ QCOMPARE(rect3->deviceTransform(deviceX).map(QPointF(50, 50)), mapResult3);
+}
+
QTEST_MAIN(tst_QGraphicsItem)
#include "tst_qgraphicsitem.moc"
-#endif