tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtTest/QtTest>
       
    44 
       
    45 #include <private/qtextcontrol_p.h>
       
    46 #include <private/qgraphicsitem_p.h>
       
    47 #include <private/qgraphicsview_p.h>
       
    48 #include <QStyleOptionGraphicsItem>
       
    49 #include <QAbstractTextDocumentLayout>
       
    50 #include <QBitmap>
       
    51 #include <QCursor>
       
    52 #include <QLabel>
       
    53 #include <QDial>
       
    54 #include <QGraphicsItem>
       
    55 #include <QGraphicsScene>
       
    56 #include <QGraphicsSceneEvent>
       
    57 #include <QGraphicsView>
       
    58 #include <QGraphicsWidget>
       
    59 #include <QGraphicsProxyWidget>
       
    60 #include <QPainter>
       
    61 #include <QScrollBar>
       
    62 #include <QVBoxLayout>
       
    63 #include <QGraphicsEffect>
       
    64 
       
    65 #include "../../shared/util.h"
       
    66 
       
    67 //TESTED_CLASS=
       
    68 //TESTED_FILES=
       
    69 
       
    70 Q_DECLARE_METATYPE(QList<int>)
       
    71 Q_DECLARE_METATYPE(QList<QRectF>)
       
    72 Q_DECLARE_METATYPE(QPainterPath)
       
    73 Q_DECLARE_METATYPE(QPointF)
       
    74 Q_DECLARE_METATYPE(QRectF)
       
    75 
       
    76 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
    77 #include <windows.h>
       
    78 #define Q_CHECK_PAINTEVENTS \
       
    79     if (::SwitchDesktop(::GetThreadDesktop(::GetCurrentThreadId())) == 0) \
       
    80         QSKIP("The Graphics View doesn't get the paint events", SkipSingle);
       
    81 #else
       
    82 #define Q_CHECK_PAINTEVENTS
       
    83 #endif
       
    84 
       
    85 #if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
       
    86 // On mac (cocoa) we always get full update.
       
    87 // So check that the expected region is contained inside the actual
       
    88 #define COMPARE_REGIONS(ACTUAL, EXPECTED) QVERIFY((EXPECTED).subtracted(ACTUAL).isEmpty())
       
    89 #else
       
    90 #define COMPARE_REGIONS QTRY_COMPARE
       
    91 #endif
       
    92 
       
    93 static void sendMousePress(QGraphicsScene *scene, const QPointF &point, Qt::MouseButton button = Qt::LeftButton)
       
    94 {
       
    95     QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
       
    96     event.setScenePos(point);
       
    97     event.setButton(button);
       
    98     event.setButtons(button);
       
    99     QApplication::sendEvent(scene, &event);
       
   100 }
       
   101 
       
   102 static void sendMouseMove(QGraphicsScene *scene, const QPointF &point,
       
   103                           Qt::MouseButton button = Qt::NoButton, Qt::MouseButtons buttons = 0)
       
   104 {
       
   105     QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseMove);
       
   106     event.setScenePos(point);
       
   107     event.setButton(button);
       
   108     event.setButtons(button);
       
   109     QApplication::sendEvent(scene, &event);
       
   110 }
       
   111 
       
   112 static void sendMouseRelease(QGraphicsScene *scene, const QPointF &point, Qt::MouseButton button = Qt::LeftButton)
       
   113 {
       
   114     QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
       
   115     event.setScenePos(point);
       
   116     event.setButton(button);
       
   117     QApplication::sendEvent(scene, &event);
       
   118 }
       
   119 
       
   120 static void sendMouseClick(QGraphicsScene *scene, const QPointF &point, Qt::MouseButton button = Qt::LeftButton)
       
   121 {
       
   122     sendMousePress(scene, point, button);
       
   123     sendMouseRelease(scene, point, button);
       
   124 }
       
   125 
       
   126 static void sendKeyPress(QGraphicsScene *scene, Qt::Key key)
       
   127 {
       
   128     QKeyEvent keyEvent(QEvent::KeyPress, key, Qt::NoModifier);
       
   129     QApplication::sendEvent(scene, &keyEvent);
       
   130 }
       
   131 
       
   132 static void sendKeyRelease(QGraphicsScene *scene, Qt::Key key)
       
   133 {
       
   134     QKeyEvent keyEvent(QEvent::KeyRelease, key, Qt::NoModifier);
       
   135     QApplication::sendEvent(scene, &keyEvent);
       
   136 }
       
   137 
       
   138 static void sendKeyClick(QGraphicsScene *scene, Qt::Key key)
       
   139 {
       
   140     sendKeyPress(scene, key);
       
   141     sendKeyRelease(scene, key);
       
   142 }
       
   143 
       
   144 class EventSpy : public QGraphicsWidget
       
   145 {
       
   146     Q_OBJECT
       
   147 public:
       
   148     EventSpy(QObject *watched, QEvent::Type type)
       
   149         : _count(0), spied(type)
       
   150     {
       
   151         watched->installEventFilter(this);
       
   152     }
       
   153 
       
   154     EventSpy(QGraphicsScene *scene, QGraphicsItem *watched, QEvent::Type type)
       
   155         : _count(0), spied(type)
       
   156     {
       
   157         scene->addItem(this);
       
   158         watched->installSceneEventFilter(this);
       
   159     }
       
   160 
       
   161     int count() const { return _count; }
       
   162 
       
   163 protected:
       
   164     bool eventFilter(QObject *watched, QEvent *event)
       
   165     {
       
   166         Q_UNUSED(watched);
       
   167         if (event->type() == spied)
       
   168             ++_count;
       
   169         return false;
       
   170     }
       
   171 
       
   172     bool sceneEventFilter(QGraphicsItem *watched, QEvent *event)
       
   173     {
       
   174         Q_UNUSED(watched);
       
   175         if (event->type() == spied)
       
   176             ++_count;
       
   177         return false;
       
   178     }
       
   179 
       
   180     int _count;
       
   181     QEvent::Type spied;
       
   182 };
       
   183 
       
   184 class EventSpy2 : public QGraphicsWidget
       
   185 {
       
   186     Q_OBJECT
       
   187 public:
       
   188     EventSpy2(QObject *watched)
       
   189     {
       
   190         watched->installEventFilter(this);
       
   191     }
       
   192 
       
   193     EventSpy2(QGraphicsScene *scene, QGraphicsItem *watched)
       
   194     {
       
   195         scene->addItem(this);
       
   196         watched->installSceneEventFilter(this);
       
   197     }
       
   198 
       
   199     QMap<QEvent::Type, int> counts;
       
   200 
       
   201 protected:
       
   202     bool eventFilter(QObject *watched, QEvent *event)
       
   203     {
       
   204         Q_UNUSED(watched);
       
   205         ++counts[event->type()];
       
   206         return false;
       
   207     }
       
   208 
       
   209     bool sceneEventFilter(QGraphicsItem *watched, QEvent *event)
       
   210     {
       
   211         Q_UNUSED(watched);
       
   212         ++counts[event->type()];
       
   213         return false;
       
   214     }
       
   215 };
       
   216 
       
   217 class EventTester : public QGraphicsItem
       
   218 {
       
   219 public:
       
   220     EventTester(QGraphicsItem *parent = 0) : QGraphicsItem(parent), repaints(0)
       
   221     { br = QRectF(-10, -10, 20, 20); }
       
   222 
       
   223     void setGeometry(const QRectF &rect)
       
   224     {
       
   225         prepareGeometryChange();
       
   226         br = rect;
       
   227         update();
       
   228     }
       
   229 
       
   230     QRectF boundingRect() const
       
   231     { return br; }
       
   232 
       
   233     void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
       
   234     {
       
   235         hints = painter->renderHints();
       
   236         painter->drawRect(boundingRect());
       
   237         ++repaints;
       
   238     }
       
   239 
       
   240     bool sceneEvent(QEvent *event)
       
   241     {
       
   242         events << event->type();
       
   243         return QGraphicsItem::sceneEvent(event);
       
   244     }
       
   245 
       
   246     QList<QEvent::Type> events;
       
   247     QPainter::RenderHints hints;
       
   248     int repaints;
       
   249     QRectF br;
       
   250 };
       
   251 
       
   252 class tst_QGraphicsItem : public QObject
       
   253 {
       
   254     Q_OBJECT
       
   255 
       
   256 public slots:
       
   257     void init();
       
   258 
       
   259 private slots:
       
   260     void construction();
       
   261     void constructionWithParent();
       
   262     void destruction();
       
   263     void deleteChildItem();
       
   264     void scene();
       
   265     void parentItem();
       
   266     void setParentItem();
       
   267     void children();
       
   268     void flags();
       
   269     void inputMethodHints();
       
   270     void toolTip();
       
   271     void visible();
       
   272     void explicitlyVisible();
       
   273     void enabled();
       
   274     void explicitlyEnabled();
       
   275     void selected();
       
   276     void selected2();
       
   277     void selected_group();
       
   278     void selected_textItem();
       
   279     void selected_multi();
       
   280     void acceptedMouseButtons();
       
   281     void acceptsHoverEvents();
       
   282     void childAcceptsHoverEvents();
       
   283     void hasFocus();
       
   284     void pos();
       
   285     void scenePos();
       
   286     void matrix();
       
   287     void sceneMatrix();
       
   288     void setMatrix();
       
   289     void zValue();
       
   290     void shape();
       
   291     void contains();
       
   292     void collidesWith_item();
       
   293     void collidesWith_path_data();
       
   294     void collidesWith_path();
       
   295     void collidesWithItemWithClip();
       
   296     void isObscuredBy();
       
   297     void isObscured();
       
   298     void mapFromToParent();
       
   299     void mapFromToScene();
       
   300     void mapFromToItem();
       
   301     void mapRectFromToParent_data();
       
   302     void mapRectFromToParent();
       
   303     void isAncestorOf();
       
   304     void commonAncestorItem();
       
   305     void data();
       
   306     void type();
       
   307     void graphicsitem_cast();
       
   308     void hoverEventsGenerateRepaints();
       
   309     void boundingRects_data();
       
   310     void boundingRects();
       
   311     void boundingRects2();
       
   312     void sceneBoundingRect();
       
   313     void childrenBoundingRect();
       
   314     void childrenBoundingRectTransformed();
       
   315     void childrenBoundingRect2();
       
   316     void childrenBoundingRect3();
       
   317     void group();
       
   318     void setGroup();
       
   319     void nestedGroups();
       
   320     void warpChildrenIntoGroup();
       
   321     void removeFromGroup();
       
   322     void handlesChildEvents();
       
   323     void handlesChildEvents2();
       
   324     void handlesChildEvents3();
       
   325     void filtersChildEvents();
       
   326     void filtersChildEvents2();
       
   327     void ensureVisible();
       
   328     void cursor();
       
   329     //void textControlGetterSetter();
       
   330     void defaultItemTest_QGraphicsLineItem();
       
   331     void defaultItemTest_QGraphicsPixmapItem();
       
   332     void defaultItemTest_QGraphicsTextItem();
       
   333     void defaultItemTest_QGraphicsEllipseItem();
       
   334     void itemChange();
       
   335     void sceneEventFilter();
       
   336     void prepareGeometryChange();
       
   337     void paint();
       
   338     void deleteItemInEventHandlers();
       
   339     void itemClipsToShape();
       
   340     void itemClipsChildrenToShape();
       
   341     void itemClipsChildrenToShape2();
       
   342     void itemClipsChildrenToShape3();
       
   343     void itemClipsChildrenToShape4();
       
   344     void itemClipsTextChildToShape();
       
   345     void itemClippingDiscovery();
       
   346     void ancestorFlags();
       
   347     void untransformable();
       
   348     void contextMenuEventPropagation();
       
   349     void itemIsMovable();
       
   350     void boundingRegion_data();
       
   351     void boundingRegion();
       
   352     void itemTransform_parentChild();
       
   353     void itemTransform_siblings();
       
   354     void itemTransform_unrelated();
       
   355     void opacity_data();
       
   356     void opacity();
       
   357     void opacity2();
       
   358     void opacityZeroUpdates();
       
   359     void itemStacksBehindParent();
       
   360     void nestedClipping();
       
   361     void nestedClippingTransforms();
       
   362     void sceneTransformCache();
       
   363     void tabChangesFocus();
       
   364     void tabChangesFocus_data();
       
   365     void cacheMode();
       
   366     void updateCachedItemAfterMove();
       
   367     void deviceTransform_data();
       
   368     void deviceTransform();
       
   369     void update();
       
   370     void setTransformProperties_data();
       
   371     void setTransformProperties();
       
   372     void itemUsesExtendedStyleOption();
       
   373     void itemSendsGeometryChanges();
       
   374     void moveItem();
       
   375     void sorting_data();
       
   376     void sorting();
       
   377     void itemHasNoContents();
       
   378     void hitTestUntransformableItem();
       
   379     void hitTestGraphicsEffectItem();
       
   380     void focusProxy();
       
   381     void subFocus();
       
   382     void focusProxyDeletion();
       
   383     void negativeZStacksBehindParent();
       
   384     void setGraphicsEffect();
       
   385     void panel();
       
   386     void addPanelToActiveScene();
       
   387     void activate();
       
   388     void setActivePanelOnInactiveScene();
       
   389     void activationOnShowHide();
       
   390     void moveWhileDeleting();
       
   391     void ensureDirtySceneTransform();
       
   392     void focusScope();
       
   393     void stackBefore();
       
   394     void sceneModality();
       
   395     void panelModality();
       
   396     void mixedModality();
       
   397     void modality_hover();
       
   398     void modality_mouseGrabber();
       
   399     void modality_clickFocus();
       
   400     void modality_keyEvents();
       
   401     void itemIsInFront();
       
   402 
       
   403     // task specific tests below me
       
   404     void task141694_textItemEnsureVisible();
       
   405     void task128696_textItemEnsureMovable();
       
   406     void ensureUpdateOnTextItem();
       
   407     void task177918_lineItemUndetected();
       
   408     void task240400_clickOnTextItem_data();
       
   409     void task240400_clickOnTextItem();
       
   410     void task243707_addChildBeforeParent();
       
   411     void task197802_childrenVisibility();
       
   412     void QTBUG_4233_updateCachedWithSceneRect();
       
   413 
       
   414 private:
       
   415     QList<QGraphicsItem *> paintedItems;
       
   416 };
       
   417 
       
   418 void tst_QGraphicsItem::init()
       
   419 {
       
   420 #ifdef Q_OS_WINCE //disable magic for WindowsCE
       
   421     qApp->setAutoMaximizeThreshold(-1);
       
   422 #endif
       
   423 }
       
   424 
       
   425 void tst_QGraphicsItem::construction()
       
   426 {
       
   427     for (int i = 0; i < 7; ++i) {
       
   428         QGraphicsItem *item;
       
   429         switch (i) {
       
   430         case 0:
       
   431             item = new QGraphicsEllipseItem;
       
   432             QCOMPARE(int(item->type()), int(QGraphicsEllipseItem::Type));
       
   433             QCOMPARE(qgraphicsitem_cast<QGraphicsEllipseItem *>(item), (QGraphicsEllipseItem *)item);
       
   434             QCOMPARE(qgraphicsitem_cast<QGraphicsRectItem *>(item), (QGraphicsRectItem *)0);
       
   435             QCOMPARE(item->flags(), 0);
       
   436             break;
       
   437         case 1:
       
   438             item = new QGraphicsLineItem;
       
   439             QCOMPARE(int(item->type()), int(QGraphicsLineItem::Type));
       
   440             QCOMPARE(qgraphicsitem_cast<QGraphicsLineItem *>(item), (QGraphicsLineItem *)item);
       
   441             QCOMPARE(qgraphicsitem_cast<QGraphicsRectItem *>(item), (QGraphicsRectItem *)0);
       
   442             QCOMPARE(item->flags(), 0);
       
   443             break;
       
   444         case 2:
       
   445             item = new QGraphicsPathItem;
       
   446             QCOMPARE(int(item->type()), int(QGraphicsPathItem::Type));
       
   447             QCOMPARE(qgraphicsitem_cast<QGraphicsPathItem *>(item), (QGraphicsPathItem *)item);
       
   448             QCOMPARE(qgraphicsitem_cast<QGraphicsRectItem *>(item), (QGraphicsRectItem *)0);
       
   449             QCOMPARE(item->flags(), 0);
       
   450             break;
       
   451         case 3:
       
   452             item = new QGraphicsPixmapItem;
       
   453             QCOMPARE(int(item->type()), int(QGraphicsPixmapItem::Type));
       
   454             QCOMPARE(qgraphicsitem_cast<QGraphicsPixmapItem *>(item), (QGraphicsPixmapItem *)item);
       
   455             QCOMPARE(qgraphicsitem_cast<QGraphicsRectItem *>(item), (QGraphicsRectItem *)0);
       
   456             QCOMPARE(item->flags(), 0);
       
   457             break;
       
   458         case 4:
       
   459             item = new QGraphicsPolygonItem;
       
   460             QCOMPARE(int(item->type()), int(QGraphicsPolygonItem::Type));
       
   461             QCOMPARE(qgraphicsitem_cast<QGraphicsPolygonItem *>(item), (QGraphicsPolygonItem *)item);
       
   462             QCOMPARE(qgraphicsitem_cast<QGraphicsRectItem *>(item), (QGraphicsRectItem *)0);
       
   463             QCOMPARE(item->flags(), 0);
       
   464             break;
       
   465         case 5:
       
   466             item = new QGraphicsRectItem;
       
   467             QCOMPARE(int(item->type()), int(QGraphicsRectItem::Type));
       
   468             QCOMPARE(qgraphicsitem_cast<QGraphicsRectItem *>(item), (QGraphicsRectItem *)item);
       
   469             QCOMPARE(qgraphicsitem_cast<QGraphicsLineItem *>(item), (QGraphicsLineItem *)0);
       
   470             QCOMPARE(item->flags(), 0);
       
   471             break;
       
   472         case 6:
       
   473             item = new QGraphicsTextItem;
       
   474             QCOMPARE(int(item->type()), int(QGraphicsTextItem::Type));
       
   475             QCOMPARE(qgraphicsitem_cast<QGraphicsTextItem *>(item), (QGraphicsTextItem *)item);
       
   476             QCOMPARE(qgraphicsitem_cast<QGraphicsRectItem *>(item), (QGraphicsRectItem *)0);
       
   477             // This is the only item that uses an extended style option.
       
   478             QCOMPARE(item->flags(), QGraphicsItem::GraphicsItemFlags(QGraphicsItem::ItemUsesExtendedStyleOption));
       
   479             break;
       
   480         default:
       
   481             qFatal("You broke the logic, please fix!");
       
   482             break;
       
   483         }
       
   484 
       
   485         QCOMPARE(item->scene(), (QGraphicsScene *)0);
       
   486         QCOMPARE(item->parentItem(), (QGraphicsItem *)0);
       
   487         QVERIFY(item->children().isEmpty());
       
   488         QVERIFY(item->isVisible());
       
   489         QVERIFY(item->isEnabled());
       
   490         QVERIFY(!item->isSelected());
       
   491         QCOMPARE(item->acceptedMouseButtons(), Qt::MouseButtons(0x1f));
       
   492         if (item->type() == QGraphicsTextItem::Type)
       
   493             QVERIFY(item->acceptsHoverEvents());
       
   494         else
       
   495             QVERIFY(!item->acceptsHoverEvents());
       
   496         QVERIFY(!item->hasFocus());
       
   497         QCOMPARE(item->pos(), QPointF());
       
   498         QCOMPARE(item->matrix(), QMatrix());
       
   499         QCOMPARE(item->sceneMatrix(), QMatrix());
       
   500         QCOMPARE(item->zValue(), qreal(0));
       
   501         QCOMPARE(item->sceneBoundingRect(), QRectF());
       
   502         QCOMPARE(item->shape(), QPainterPath());
       
   503         QVERIFY(!item->contains(QPointF(0, 0)));
       
   504         QVERIFY(!item->collidesWithItem(0));
       
   505         QVERIFY(item->collidesWithItem(item));
       
   506         QVERIFY(!item->collidesWithPath(QPainterPath()));
       
   507         QVERIFY(!item->isAncestorOf(0));
       
   508         QVERIFY(!item->isAncestorOf(item));
       
   509         QCOMPARE(item->data(0), QVariant());
       
   510         delete item;
       
   511     }
       
   512 }
       
   513 
       
   514 class BoundingRectItem : public QGraphicsRectItem
       
   515 {
       
   516 public:
       
   517     BoundingRectItem(QGraphicsItem *parent = 0)
       
   518         : QGraphicsRectItem(0, 0, parent ? 200 : 100, parent ? 200 : 100,
       
   519                             parent)
       
   520     {}
       
   521 
       
   522     QRectF boundingRect() const
       
   523     {
       
   524         QRectF tmp = QGraphicsRectItem::boundingRect();
       
   525         foreach (QGraphicsItem *child, children())
       
   526             tmp |= child->boundingRect(); // <- might be pure virtual
       
   527         return tmp;
       
   528     }
       
   529 };
       
   530 
       
   531 void tst_QGraphicsItem::constructionWithParent()
       
   532 {
       
   533     // This test causes a crash if item1 calls item2's pure virtuals before the
       
   534     // object has been constructed.
       
   535     QGraphicsItem *item0 = new BoundingRectItem;
       
   536     QGraphicsItem *item1 = new BoundingRectItem;
       
   537     QGraphicsScene scene;
       
   538     scene.addItem(item0);
       
   539     scene.addItem(item1);
       
   540     QGraphicsItem *item2 = new BoundingRectItem(item1);
       
   541     QCOMPARE(item1->children(), QList<QGraphicsItem *>() << item2);
       
   542     QCOMPARE(item1->boundingRect(), QRectF(0, 0, 200, 200));
       
   543 
       
   544     item2->setParentItem(item0);
       
   545     QCOMPARE(item0->children(), QList<QGraphicsItem *>() << item2);
       
   546     QCOMPARE(item0->boundingRect(), QRectF(0, 0, 200, 200));
       
   547 }
       
   548 
       
   549 static int itemDeleted = 0;
       
   550 class Item : public QGraphicsRectItem
       
   551 {
       
   552 public:
       
   553     ~Item()
       
   554     { ++itemDeleted; }
       
   555 };
       
   556 
       
   557 void tst_QGraphicsItem::destruction()
       
   558 {
       
   559     QCOMPARE(itemDeleted, 0);
       
   560     {
       
   561         QGraphicsItem *parent = new QGraphicsRectItem;
       
   562         Item *child = new Item;
       
   563         child->setParentItem(parent);
       
   564         QCOMPARE(child->parentItem(), parent);
       
   565         delete parent;
       
   566         QCOMPARE(itemDeleted, 1);
       
   567     }
       
   568     {
       
   569         QGraphicsItem *parent = new QGraphicsRectItem;
       
   570         Item *child = new Item;
       
   571         child->setParentItem(parent);
       
   572         QCOMPARE(parent->children().size(), 1);
       
   573         delete child;
       
   574         QCOMPARE(parent->children().size(), 0);
       
   575         delete parent;
       
   576         QCOMPARE(itemDeleted, 2);
       
   577     }
       
   578     {
       
   579         QGraphicsScene scene;
       
   580         QGraphicsItem *parent = new QGraphicsRectItem;
       
   581         Item *child = new Item;
       
   582         QCOMPARE(child->parentItem(), (QGraphicsItem *)0);
       
   583         child->setParentItem(parent);
       
   584         QCOMPARE(child->parentItem(), parent);
       
   585         scene.addItem(parent);
       
   586         QCOMPARE(child->parentItem(), parent);
       
   587         delete parent;
       
   588         QCOMPARE(itemDeleted, 3);
       
   589     }
       
   590     {
       
   591         QGraphicsScene scene;
       
   592         QGraphicsItem *parent = new QGraphicsRectItem;
       
   593         Item *child = new Item;
       
   594         child->setParentItem(parent);
       
   595         scene.addItem(parent);
       
   596         QCOMPARE(child->scene(), &scene);
       
   597         QCOMPARE(parent->children().size(), 1);
       
   598         delete child;
       
   599         QCOMPARE(parent->children().size(), 0);
       
   600         delete parent;
       
   601         QCOMPARE(itemDeleted, 4);
       
   602     }
       
   603     {
       
   604         QGraphicsScene scene;
       
   605         QGraphicsItem *parent = new QGraphicsRectItem;
       
   606         Item *child = new Item;
       
   607         child->setParentItem(parent);
       
   608         scene.addItem(parent);
       
   609         QCOMPARE(child->scene(), &scene);
       
   610         scene.removeItem(parent);
       
   611         QCOMPARE(child->scene(), (QGraphicsScene *)0);
       
   612         delete parent;
       
   613         QCOMPARE(itemDeleted, 5);
       
   614     }
       
   615     {
       
   616         QGraphicsScene scene;
       
   617         QGraphicsItem *parent = new QGraphicsRectItem;
       
   618         Item *child = new Item;
       
   619         child->setParentItem(parent);
       
   620         QCOMPARE(child->scene(), (QGraphicsScene *)0);
       
   621         QCOMPARE(parent->scene(), (QGraphicsScene *)0);
       
   622         scene.addItem(parent);
       
   623         QCOMPARE(child->scene(), &scene);
       
   624         scene.removeItem(child);
       
   625         QCOMPARE(child->scene(), (QGraphicsScene *)0);
       
   626         QCOMPARE(parent->scene(), &scene);
       
   627         QCOMPARE(child->parentItem(), (QGraphicsItem *)0);
       
   628         QVERIFY(parent->children().isEmpty());
       
   629         delete parent;
       
   630         QCOMPARE(itemDeleted, 5);
       
   631         delete child;
       
   632         QCOMPARE(itemDeleted, 6);
       
   633     }
       
   634     {
       
   635         QGraphicsScene scene;
       
   636         QGraphicsItem *parent = new QGraphicsRectItem;
       
   637         Item *child = new Item;
       
   638         child->setParentItem(parent);
       
   639         scene.addItem(parent);
       
   640         scene.removeItem(child);
       
   641         scene.removeItem(parent);
       
   642         delete child;
       
   643         delete parent;
       
   644         QCOMPARE(itemDeleted, 7);
       
   645     }
       
   646     {
       
   647         QGraphicsScene scene;
       
   648         QGraphicsItem *parent = new QGraphicsRectItem;
       
   649         Item *child = new Item;
       
   650         child->setParentItem(parent);
       
   651         scene.addItem(parent);
       
   652         QGraphicsScene scene2;
       
   653         scene2.addItem(parent);
       
   654         delete parent;
       
   655         QCOMPARE(itemDeleted, 8);
       
   656     }
       
   657     {
       
   658         QGraphicsScene scene;
       
   659         QGraphicsItem *parent = new QGraphicsRectItem;
       
   660         Item *child = new Item;
       
   661         child->setParentItem(parent);
       
   662         scene.addItem(parent);
       
   663         QCOMPARE(child->scene(), &scene);
       
   664         QGraphicsScene scene2;
       
   665         scene2.addItem(parent);
       
   666         QCOMPARE(child->scene(), &scene2);
       
   667         scene.addItem(parent);
       
   668         QCOMPARE(child->scene(), &scene);
       
   669         scene2.addItem(parent);
       
   670         QCOMPARE(child->scene(), &scene2);
       
   671         delete parent;
       
   672         QCOMPARE(itemDeleted, 9);
       
   673     }
       
   674     {
       
   675         QGraphicsScene scene;
       
   676         QGraphicsItem *parent = new QGraphicsRectItem;
       
   677         Item *child = new Item;
       
   678         child->setParentItem(parent);
       
   679         scene.addItem(parent);
       
   680         QCOMPARE(child->scene(), &scene);
       
   681         QGraphicsScene scene2;
       
   682         scene2.addItem(child);
       
   683         QCOMPARE(child->scene(), &scene2);
       
   684         delete parent;
       
   685         QCOMPARE(itemDeleted, 9);
       
   686         delete child;
       
   687         QCOMPARE(itemDeleted, 10);
       
   688     }
       
   689     {
       
   690         QGraphicsScene scene;
       
   691         QGraphicsItem *root = new QGraphicsRectItem;
       
   692         QGraphicsItem *parent = root;
       
   693         QGraphicsItem *middleItem = 0;
       
   694         for (int i = 0; i < 99; ++i) {
       
   695             Item *child = new Item;
       
   696             child->setParentItem(parent);
       
   697             parent = child;
       
   698             if (i == 50)
       
   699                 middleItem = parent;
       
   700         }
       
   701         scene.addItem(root);
       
   702 
       
   703         QCOMPARE(scene.items().size(), 100);
       
   704 
       
   705         QGraphicsScene scene2;
       
   706         scene2.addItem(middleItem);
       
   707 
       
   708         delete middleItem;
       
   709         QCOMPARE(itemDeleted, 59);
       
   710     }
       
   711     QCOMPARE(itemDeleted, 109);
       
   712     {
       
   713         QGraphicsScene *scene = new QGraphicsScene;
       
   714         QGraphicsRectItem *parent = new QGraphicsRectItem;
       
   715         Item *child = new Item;
       
   716         child->setParentItem(parent);
       
   717         parent->setVisible(false);
       
   718         scene->addItem(parent);
       
   719         QCOMPARE(child->parentItem(), static_cast<QGraphicsItem*>(parent));
       
   720         delete scene;
       
   721         QCOMPARE(itemDeleted, 110);
       
   722     }
       
   723 }
       
   724 
       
   725 void tst_QGraphicsItem::deleteChildItem()
       
   726 {
       
   727     QGraphicsScene scene;
       
   728     QGraphicsItem *rect = scene.addRect(QRectF());
       
   729     QGraphicsItem *child1 = new QGraphicsRectItem(rect);
       
   730     QGraphicsItem *child2 = new QGraphicsRectItem(rect);
       
   731     QGraphicsItem *child3 = new QGraphicsRectItem(rect);
       
   732     delete child1;
       
   733     child2->setParentItem(0);
       
   734     delete child2;
       
   735 }
       
   736 
       
   737 void tst_QGraphicsItem::scene()
       
   738 {
       
   739     QGraphicsRectItem *item = new QGraphicsRectItem;
       
   740     QCOMPARE(item->scene(), (QGraphicsScene *)0);
       
   741 
       
   742     QGraphicsScene scene;
       
   743     scene.addItem(item);
       
   744     QCOMPARE(item->scene(), (QGraphicsScene *)&scene);
       
   745 
       
   746     QGraphicsScene scene2;
       
   747     scene2.addItem(item);
       
   748     QCOMPARE(item->scene(), (QGraphicsScene *)&scene2);
       
   749 
       
   750     scene2.removeItem(item);
       
   751     QCOMPARE(item->scene(), (QGraphicsScene *)0);
       
   752 
       
   753     delete item;
       
   754 }
       
   755 
       
   756 void tst_QGraphicsItem::parentItem()
       
   757 {
       
   758     QGraphicsRectItem item;
       
   759     QCOMPARE(item.parentItem(), (QGraphicsItem *)0);
       
   760 
       
   761     QGraphicsRectItem *item2 = new QGraphicsRectItem(QRectF(), &item);
       
   762     QCOMPARE(item2->parentItem(), (QGraphicsItem *)&item);
       
   763     item2->setParentItem(&item);
       
   764     QCOMPARE(item2->parentItem(), (QGraphicsItem *)&item);
       
   765     item2->setParentItem(0);
       
   766     QCOMPARE(item2->parentItem(), (QGraphicsItem *)0);
       
   767 
       
   768     delete item2;
       
   769 }
       
   770 
       
   771 void tst_QGraphicsItem::setParentItem()
       
   772 {
       
   773     QGraphicsScene scene;
       
   774     QGraphicsItem *item = scene.addRect(QRectF(0, 0, 10, 10));
       
   775     QCOMPARE(item->scene(), &scene);
       
   776 
       
   777     QGraphicsRectItem *child = new QGraphicsRectItem;
       
   778     QCOMPARE(child->scene(), (QGraphicsScene *)0);
       
   779 
       
   780     // This implicitly adds the item to the parent's scene
       
   781     child->setParentItem(item);
       
   782     QCOMPARE(child->scene(), &scene);
       
   783 
       
   784     // This just makes it a toplevel
       
   785     child->setParentItem(0);
       
   786     QCOMPARE(child->scene(), &scene);
       
   787 
       
   788     // Add the child back to the parent, then remove the parent from the scene
       
   789     child->setParentItem(item);
       
   790     scene.removeItem(item);
       
   791     QCOMPARE(child->scene(), (QGraphicsScene *)0);
       
   792 }
       
   793 
       
   794 void tst_QGraphicsItem::children()
       
   795 {
       
   796     QGraphicsRectItem item;
       
   797     QVERIFY(item.children().isEmpty());
       
   798 
       
   799     QGraphicsRectItem *item2 = new QGraphicsRectItem(QRectF(), &item);
       
   800     QCOMPARE(item.children().size(), 1);
       
   801     QCOMPARE(item.children().first(), (QGraphicsItem *)item2);
       
   802     QVERIFY(item2->children().isEmpty());
       
   803 
       
   804     delete item2;
       
   805     QVERIFY(item.children().isEmpty());
       
   806 }
       
   807 
       
   808 void tst_QGraphicsItem::flags()
       
   809 {
       
   810     QGraphicsRectItem *item = new QGraphicsRectItem(QRectF(-10, -10, 20, 20));
       
   811     QCOMPARE(item->flags(), 0);
       
   812 
       
   813     QGraphicsScene scene;
       
   814     QEvent activate(QEvent::WindowActivate);
       
   815     QApplication::sendEvent(&scene, &activate);
       
   816 
       
   817     scene.addItem(item);
       
   818 
       
   819     {
       
   820         // Focus
       
   821         item->setFlag(QGraphicsItem::ItemIsFocusable, false);
       
   822         QVERIFY(!item->hasFocus());
       
   823         item->setFocus();
       
   824         QVERIFY(!item->hasFocus());
       
   825 
       
   826         item->setFlag(QGraphicsItem::ItemIsFocusable, true);
       
   827         QVERIFY(!item->hasFocus());
       
   828         item->setFocus();
       
   829         QVERIFY(item->hasFocus());
       
   830         QVERIFY(scene.hasFocus());
       
   831 
       
   832         item->setFlag(QGraphicsItem::ItemIsFocusable, false);
       
   833         QVERIFY(!item->hasFocus());
       
   834         QVERIFY(scene.hasFocus());
       
   835     }
       
   836     {
       
   837         // Selectable
       
   838         item->setFlag(QGraphicsItem::ItemIsSelectable, false);
       
   839         QVERIFY(!item->isSelected());
       
   840         item->setSelected(true);
       
   841         QVERIFY(!item->isSelected());
       
   842 
       
   843         item->setFlag(QGraphicsItem::ItemIsSelectable, true);
       
   844         QVERIFY(!item->isSelected());
       
   845         item->setSelected(true);
       
   846         QVERIFY(item->isSelected());
       
   847         item->setFlag(QGraphicsItem::ItemIsSelectable, false);
       
   848         QVERIFY(!item->isSelected());
       
   849     }
       
   850     {
       
   851         // Movable
       
   852         item->setFlag(QGraphicsItem::ItemIsMovable, false);
       
   853         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
       
   854         event.setScenePos(QPointF(0, 0));
       
   855         event.setButton(Qt::LeftButton);
       
   856         event.setButtons(Qt::LeftButton);
       
   857         QApplication::sendEvent(&scene, &event);
       
   858         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0); // mouse grabber is reset
       
   859 
       
   860         QGraphicsSceneMouseEvent event2(QEvent::GraphicsSceneMouseMove);
       
   861         event2.setScenePos(QPointF(10, 10));
       
   862         event2.setButton(Qt::LeftButton);
       
   863         event2.setButtons(Qt::LeftButton);
       
   864         QApplication::sendEvent(&scene, &event2);
       
   865         QCOMPARE(item->pos(), QPointF());
       
   866 
       
   867         QGraphicsSceneMouseEvent event3(QEvent::GraphicsSceneMouseRelease);
       
   868         event3.setScenePos(QPointF(10, 10));
       
   869         event3.setButtons(0);
       
   870         QApplication::sendEvent(&scene, &event3);
       
   871         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
   872 
       
   873         item->setFlag(QGraphicsItem::ItemIsMovable, true);
       
   874         QGraphicsSceneMouseEvent event4(QEvent::GraphicsSceneMousePress);
       
   875         event4.setScenePos(QPointF(0, 0));
       
   876         event4.setButton(Qt::LeftButton);
       
   877         event4.setButtons(Qt::LeftButton);
       
   878         QApplication::sendEvent(&scene, &event4);
       
   879         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)item);
       
   880         QGraphicsSceneMouseEvent event5(QEvent::GraphicsSceneMouseMove);
       
   881         event5.setScenePos(QPointF(10, 10));
       
   882         event5.setButton(Qt::LeftButton);
       
   883         event5.setButtons(Qt::LeftButton);
       
   884         QApplication::sendEvent(&scene, &event5);
       
   885         QCOMPARE(item->pos(), QPointF(10, 10));
       
   886     }
       
   887     {
       
   888         QGraphicsItem* clippingParent = new QGraphicsRectItem;
       
   889         clippingParent->setFlag(QGraphicsItem::ItemClipsChildrenToShape, true);
       
   890 
       
   891         QGraphicsItem* nonClippingParent = new QGraphicsRectItem;
       
   892         nonClippingParent->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
       
   893 
       
   894         QGraphicsItem* child = new QGraphicsRectItem(nonClippingParent);
       
   895         QVERIFY(!child->isClipped());
       
   896 
       
   897         child->setParentItem(clippingParent);
       
   898         QVERIFY(child->isClipped());
       
   899 
       
   900         child->setParentItem(nonClippingParent);
       
   901         QVERIFY(!child->isClipped());
       
   902     }
       
   903 }
       
   904 
       
   905 class ImhTester : public QGraphicsItem
       
   906 {
       
   907     QRectF boundingRect() const { return QRectF(); }
       
   908     void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) {}
       
   909 };
       
   910 
       
   911 void tst_QGraphicsItem::inputMethodHints()
       
   912 {
       
   913     ImhTester item;
       
   914     QCOMPARE(item.inputMethodHints(), Qt::ImhNone);
       
   915 }
       
   916 
       
   917 void tst_QGraphicsItem::toolTip()
       
   918 {
       
   919     QString toolTip = "Qt rocks!";
       
   920 
       
   921     QGraphicsRectItem *item = new QGraphicsRectItem(QRectF(0, 0, 100, 100));
       
   922     item->setPen(QPen(Qt::red, 1));
       
   923     item->setBrush(QBrush(Qt::blue));
       
   924     QVERIFY(item->toolTip().isEmpty());
       
   925     item->setToolTip(toolTip);
       
   926     QCOMPARE(item->toolTip(), toolTip);
       
   927 
       
   928     QGraphicsScene scene;
       
   929     scene.addItem(item);
       
   930 
       
   931     QGraphicsView view(&scene);
       
   932     view.setFixedSize(200, 200);
       
   933     view.show();
       
   934     QTest::qWait(250);
       
   935     {
       
   936         QHelpEvent helpEvent(QEvent::ToolTip, view.viewport()->rect().topLeft(),
       
   937                              view.viewport()->mapToGlobal(view.viewport()->rect().topLeft()));
       
   938         QApplication::sendEvent(view.viewport(), &helpEvent);
       
   939         QTest::qWait(250);
       
   940 
       
   941         bool foundView = false;
       
   942         bool foundTipLabel = false;
       
   943         foreach (QWidget *widget, QApplication::topLevelWidgets()) {
       
   944             if (widget == &view)
       
   945                 foundView = true;
       
   946             if (widget->inherits("QTipLabel"))
       
   947                 foundTipLabel = true;
       
   948         }
       
   949         QVERIFY(foundView);
       
   950         QVERIFY(!foundTipLabel);
       
   951     }
       
   952 
       
   953     {
       
   954         QHelpEvent helpEvent(QEvent::ToolTip, view.viewport()->rect().center(),
       
   955                              view.viewport()->mapToGlobal(view.viewport()->rect().center()));
       
   956         QApplication::sendEvent(view.viewport(), &helpEvent);
       
   957         QTest::qWait(250);
       
   958 
       
   959         bool foundView = false;
       
   960         bool foundTipLabel = false;
       
   961         foreach (QWidget *widget, QApplication::topLevelWidgets()) {
       
   962             if (widget == &view)
       
   963                 foundView = true;
       
   964             if (widget->inherits("QTipLabel"))
       
   965                 foundTipLabel = true;
       
   966         }
       
   967         QVERIFY(foundView);
       
   968         QVERIFY(foundTipLabel);
       
   969     }
       
   970 
       
   971     {
       
   972         QHelpEvent helpEvent(QEvent::ToolTip, view.viewport()->rect().topLeft(),
       
   973                              view.viewport()->mapToGlobal(view.viewport()->rect().topLeft()));
       
   974         QApplication::sendEvent(view.viewport(), &helpEvent);
       
   975         QTest::qWait(1000);
       
   976 
       
   977         bool foundView = false;
       
   978         bool foundTipLabel = false;
       
   979         foreach (QWidget *widget, QApplication::topLevelWidgets()) {
       
   980             if (widget == &view)
       
   981                 foundView = true;
       
   982             if (widget->inherits("QTipLabel") && widget->isVisible())
       
   983                 foundTipLabel = true;
       
   984         }
       
   985         QVERIFY(foundView);
       
   986         QVERIFY(!foundTipLabel);
       
   987     }
       
   988 }
       
   989 
       
   990 void tst_QGraphicsItem::visible()
       
   991 {
       
   992     QGraphicsItem *item = new QGraphicsRectItem(QRectF(-10, -10, 20, 20));
       
   993     item->setFlag(QGraphicsItem::ItemIsMovable);
       
   994     QVERIFY(item->isVisible());
       
   995     item->setVisible(false);
       
   996     QVERIFY(!item->isVisible());
       
   997     item->setVisible(true);
       
   998     QVERIFY(item->isVisible());
       
   999 
       
  1000     QGraphicsScene scene;
       
  1001     QEvent activate(QEvent::WindowActivate);
       
  1002     QApplication::sendEvent(&scene, &activate);
       
  1003 
       
  1004     scene.addItem(item);
       
  1005     QVERIFY(item->isVisible());
       
  1006     QCOMPARE(scene.itemAt(0, 0), item);
       
  1007     item->setVisible(false);
       
  1008     QCOMPARE(scene.itemAt(0, 0), (QGraphicsItem *)0);
       
  1009     item->setVisible(true);
       
  1010     QCOMPARE(scene.itemAt(0, 0), item);
       
  1011 
       
  1012     QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
       
  1013     event.setButton(Qt::LeftButton);
       
  1014     event.setScenePos(QPointF(0, 0));
       
  1015     QApplication::sendEvent(&scene, &event);
       
  1016     QCOMPARE(scene.mouseGrabberItem(), item);
       
  1017     item->setVisible(false);
       
  1018     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
  1019     item->setVisible(true);
       
  1020     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
  1021 
       
  1022     item->setFlag(QGraphicsItem::ItemIsFocusable);
       
  1023     item->setFocus();
       
  1024     QVERIFY(item->hasFocus());
       
  1025     item->setVisible(false);
       
  1026     QVERIFY(!item->hasFocus());
       
  1027     item->setVisible(true);
       
  1028     QVERIFY(!item->hasFocus());
       
  1029 }
       
  1030 
       
  1031 void tst_QGraphicsItem::explicitlyVisible()
       
  1032 {
       
  1033     QGraphicsScene scene;
       
  1034     QGraphicsItem *parent = scene.addRect(QRectF(0, 0, 100, 100));
       
  1035     QGraphicsItem *child = scene.addRect(QRectF(25, 25, 50, 50));
       
  1036     child->setParentItem(parent);
       
  1037 
       
  1038     QVERIFY(parent->isVisible());
       
  1039     QVERIFY(child->isVisible());
       
  1040 
       
  1041     parent->hide();
       
  1042 
       
  1043     QVERIFY(!parent->isVisible());
       
  1044     QVERIFY(!child->isVisible());
       
  1045 
       
  1046     parent->show();
       
  1047     child->hide();
       
  1048 
       
  1049     QVERIFY(parent->isVisible());
       
  1050     QVERIFY(!child->isVisible());
       
  1051 
       
  1052     parent->hide();
       
  1053 
       
  1054     QVERIFY(!parent->isVisible());
       
  1055     QVERIFY(!child->isVisible());
       
  1056 
       
  1057     parent->show();
       
  1058 
       
  1059     QVERIFY(parent->isVisible());
       
  1060     QVERIFY(!child->isVisible()); // <- explicitly hidden
       
  1061 
       
  1062     child->show();
       
  1063 
       
  1064     QVERIFY(child->isVisible());
       
  1065 
       
  1066     parent->hide();
       
  1067 
       
  1068     QVERIFY(!parent->isVisible());
       
  1069     QVERIFY(!child->isVisible()); // <- explicit show doesn't work
       
  1070 
       
  1071     parent->show();
       
  1072 
       
  1073     QVERIFY(parent->isVisible());
       
  1074     QVERIFY(child->isVisible()); // <- no longer explicitly hidden
       
  1075 
       
  1076     // ------------------- Reparenting ------------------------------
       
  1077 
       
  1078     QGraphicsItem *parent2 = scene.addRect(-50, -50, 200, 200);
       
  1079     QVERIFY(parent2->isVisible());
       
  1080 
       
  1081     // Reparent implicitly hidden item to a visible parent.
       
  1082     parent->hide();
       
  1083     QVERIFY(!parent->isVisible());
       
  1084     QVERIFY(!child->isVisible());
       
  1085     child->setParentItem(parent2);
       
  1086     QVERIFY(parent2->isVisible());
       
  1087     QVERIFY(child->isVisible());
       
  1088 
       
  1089     // Reparent implicitly hidden item to a hidden parent.
       
  1090     child->setParentItem(parent);
       
  1091     parent2->hide();
       
  1092     child->setParentItem(parent2);
       
  1093     QVERIFY(!parent2->isVisible());
       
  1094     QVERIFY(!child->isVisible());
       
  1095 
       
  1096     // Reparent explicitly hidden item to a visible parent.
       
  1097     child->hide();
       
  1098     parent->show();
       
  1099     child->setParentItem(parent);
       
  1100     QVERIFY(parent->isVisible());
       
  1101     QVERIFY(!child->isVisible());
       
  1102 
       
  1103     // Reparent explicitly hidden item to a hidden parent.
       
  1104     child->setParentItem(parent2);
       
  1105     QVERIFY(!parent2->isVisible());
       
  1106     QVERIFY(!child->isVisible());
       
  1107 
       
  1108     // Reparent explicitly hidden item to a visible parent.
       
  1109     parent->show();
       
  1110     child->setParentItem(parent);
       
  1111     QVERIFY(parent->isVisible());
       
  1112     QVERIFY(!child->isVisible());
       
  1113 
       
  1114     // Reparent visible item to a hidden parent.
       
  1115     child->show();
       
  1116     parent2->hide();
       
  1117     child->setParentItem(parent2);
       
  1118     QVERIFY(!parent2->isVisible());
       
  1119     QVERIFY(!child->isVisible());
       
  1120     parent2->show();
       
  1121     QVERIFY(parent2->isVisible());
       
  1122     QVERIFY(child->isVisible());
       
  1123 
       
  1124     // Reparent implicitly hidden child to root.
       
  1125     parent2->hide();
       
  1126     QVERIFY(!child->isVisible());
       
  1127     child->setParentItem(0);
       
  1128     QVERIFY(child->isVisible());
       
  1129 
       
  1130     // Reparent an explicitly hidden child to root.
       
  1131     child->hide();
       
  1132     child->setParentItem(parent2);
       
  1133     parent2->show();
       
  1134     QVERIFY(!child->isVisible());
       
  1135     child->setParentItem(0);
       
  1136     QVERIFY(!child->isVisible());
       
  1137 }
       
  1138 
       
  1139 void tst_QGraphicsItem::enabled()
       
  1140 {
       
  1141     QGraphicsRectItem *item = new QGraphicsRectItem(QRectF(-10, -10, 20, 20));
       
  1142     item->setFlag(QGraphicsItem::ItemIsMovable);
       
  1143     QVERIFY(item->isEnabled());
       
  1144     item->setEnabled(false);
       
  1145     QVERIFY(!item->isEnabled());
       
  1146     item->setEnabled(true);
       
  1147     QVERIFY(item->isEnabled());
       
  1148     item->setEnabled(false);
       
  1149     item->setFlag(QGraphicsItem::ItemIsFocusable);
       
  1150     QGraphicsScene scene;
       
  1151     QEvent activate(QEvent::WindowActivate);
       
  1152     QApplication::sendEvent(&scene, &activate);
       
  1153 
       
  1154     scene.addItem(item);
       
  1155     item->setFocus();
       
  1156     QVERIFY(!item->hasFocus());
       
  1157     item->setEnabled(true);
       
  1158     item->setFocus();
       
  1159     QVERIFY(item->hasFocus());
       
  1160     item->setEnabled(false);
       
  1161     QVERIFY(!item->hasFocus());
       
  1162 
       
  1163     QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
       
  1164     event.setButton(Qt::LeftButton);
       
  1165     event.setScenePos(QPointF(0, 0));
       
  1166     QApplication::sendEvent(&scene, &event);
       
  1167     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
  1168     item->setEnabled(true);
       
  1169     QApplication::sendEvent(&scene, &event);
       
  1170     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)item);
       
  1171     item->setEnabled(false);
       
  1172     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
  1173 }
       
  1174 
       
  1175 void tst_QGraphicsItem::explicitlyEnabled()
       
  1176 {
       
  1177     QGraphicsScene scene;
       
  1178     QGraphicsItem *parent = scene.addRect(QRectF(0, 0, 100, 100));
       
  1179     QGraphicsItem *child = scene.addRect(QRectF(25, 25, 50, 50));
       
  1180     child->setParentItem(parent);
       
  1181 
       
  1182     QVERIFY(parent->isEnabled());
       
  1183     QVERIFY(child->isEnabled());
       
  1184 
       
  1185     parent->setEnabled(false);
       
  1186 
       
  1187     QVERIFY(!parent->isEnabled());
       
  1188     QVERIFY(!child->isEnabled());
       
  1189 
       
  1190     parent->setEnabled(true);
       
  1191     child->setEnabled(false);
       
  1192 
       
  1193     QVERIFY(parent->isEnabled());
       
  1194     QVERIFY(!child->isEnabled());
       
  1195 
       
  1196     parent->setEnabled(false);
       
  1197 
       
  1198     QVERIFY(!parent->isEnabled());
       
  1199     QVERIFY(!child->isEnabled());
       
  1200 
       
  1201     parent->setEnabled(true);
       
  1202 
       
  1203     QVERIFY(parent->isEnabled());
       
  1204     QVERIFY(!child->isEnabled()); // <- explicitly disabled
       
  1205 
       
  1206     child->setEnabled(true);
       
  1207 
       
  1208     QVERIFY(child->isEnabled());
       
  1209 
       
  1210     parent->setEnabled(false);
       
  1211 
       
  1212     QVERIFY(!parent->isEnabled());
       
  1213     QVERIFY(!child->isEnabled()); // <- explicit enabled doesn't work
       
  1214 
       
  1215     parent->setEnabled(true);
       
  1216 
       
  1217     QVERIFY(parent->isEnabled());
       
  1218     QVERIFY(child->isEnabled()); // <- no longer explicitly disabled
       
  1219 
       
  1220     // ------------------- Reparenting ------------------------------
       
  1221 
       
  1222     QGraphicsItem *parent2 = scene.addRect(-50, -50, 200, 200);
       
  1223     QVERIFY(parent2->isEnabled());
       
  1224 
       
  1225     // Reparent implicitly hidden item to a enabled parent.
       
  1226     parent->setEnabled(false);
       
  1227     QVERIFY(!parent->isEnabled());
       
  1228     QVERIFY(!child->isEnabled());
       
  1229     child->setParentItem(parent2);
       
  1230     QVERIFY(parent2->isEnabled());
       
  1231     QVERIFY(child->isEnabled());
       
  1232 
       
  1233     // Reparent implicitly hidden item to a hidden parent.
       
  1234     child->setParentItem(parent);
       
  1235     parent2->setEnabled(false);
       
  1236     child->setParentItem(parent2);
       
  1237     QVERIFY(!parent2->isEnabled());
       
  1238     QVERIFY(!child->isEnabled());
       
  1239 
       
  1240     // Reparent explicitly hidden item to a enabled parent.
       
  1241     child->setEnabled(false);
       
  1242     parent->setEnabled(true);
       
  1243     child->setParentItem(parent);
       
  1244     QVERIFY(parent->isEnabled());
       
  1245     QVERIFY(!child->isEnabled());
       
  1246 
       
  1247     // Reparent explicitly hidden item to a hidden parent.
       
  1248     child->setParentItem(parent2);
       
  1249     QVERIFY(!parent2->isEnabled());
       
  1250     QVERIFY(!child->isEnabled());
       
  1251 
       
  1252     // Reparent explicitly hidden item to a enabled parent.
       
  1253     parent->setEnabled(true);
       
  1254     child->setParentItem(parent);
       
  1255     QVERIFY(parent->isEnabled());
       
  1256     QVERIFY(!child->isEnabled());
       
  1257 
       
  1258     // Reparent enabled item to a hidden parent.
       
  1259     child->setEnabled(true);
       
  1260     parent2->setEnabled(false);
       
  1261     child->setParentItem(parent2);
       
  1262     QVERIFY(!parent2->isEnabled());
       
  1263     QVERIFY(!child->isEnabled());
       
  1264     parent2->setEnabled(true);
       
  1265     QVERIFY(parent2->isEnabled());
       
  1266     QVERIFY(child->isEnabled());
       
  1267 
       
  1268     // Reparent implicitly hidden child to root.
       
  1269     parent2->setEnabled(false);
       
  1270     QVERIFY(!child->isEnabled());
       
  1271     child->setParentItem(0);
       
  1272     QVERIFY(child->isEnabled());
       
  1273 
       
  1274     // Reparent an explicitly hidden child to root.
       
  1275     child->setEnabled(false);
       
  1276     child->setParentItem(parent2);
       
  1277     parent2->setEnabled(true);
       
  1278     QVERIFY(!child->isEnabled());
       
  1279     child->setParentItem(0);
       
  1280     QVERIFY(!child->isEnabled());
       
  1281 }
       
  1282 
       
  1283 class SelectChangeItem : public QGraphicsRectItem
       
  1284 {
       
  1285 public:
       
  1286     SelectChangeItem() : QGraphicsRectItem(-50, -50, 100, 100) { setBrush(Qt::blue); }
       
  1287     QList<bool> values;
       
  1288 
       
  1289 protected:
       
  1290     QVariant itemChange(GraphicsItemChange change, const QVariant &value)
       
  1291     {
       
  1292         if (change == ItemSelectedChange)
       
  1293             values << value.toBool();
       
  1294         return QGraphicsRectItem::itemChange(change, value);
       
  1295     }
       
  1296 };
       
  1297 
       
  1298 void tst_QGraphicsItem::selected()
       
  1299 {
       
  1300     SelectChangeItem *item = new SelectChangeItem;
       
  1301     item->setFlag(QGraphicsItem::ItemIsSelectable);
       
  1302     QVERIFY(!item->isSelected());
       
  1303     QVERIFY(item->values.isEmpty());
       
  1304     item->setSelected(true);
       
  1305     QCOMPARE(item->values.size(), 1);
       
  1306     QCOMPARE(item->values.last(), true);
       
  1307     QVERIFY(item->isSelected());
       
  1308     item->setSelected(false);
       
  1309     QCOMPARE(item->values.size(), 2);
       
  1310     QCOMPARE(item->values.last(), false);
       
  1311     QVERIFY(!item->isSelected());
       
  1312     item->setSelected(true);
       
  1313     QCOMPARE(item->values.size(), 3);
       
  1314     item->setEnabled(false);
       
  1315     QCOMPARE(item->values.size(), 4);
       
  1316     QCOMPARE(item->values.last(), false);
       
  1317     QVERIFY(!item->isSelected());
       
  1318     item->setEnabled(true);
       
  1319     QCOMPARE(item->values.size(), 4);
       
  1320     item->setSelected(true);
       
  1321     QCOMPARE(item->values.size(), 5);
       
  1322     QCOMPARE(item->values.last(), true);
       
  1323     QVERIFY(item->isSelected());
       
  1324     item->setVisible(false);
       
  1325     QCOMPARE(item->values.size(), 6);
       
  1326     QCOMPARE(item->values.last(), false);
       
  1327     QVERIFY(!item->isSelected());
       
  1328     item->setVisible(true);
       
  1329     QCOMPARE(item->values.size(), 6);
       
  1330     item->setSelected(true);
       
  1331     QCOMPARE(item->values.size(), 7);
       
  1332     QCOMPARE(item->values.last(), true);
       
  1333     QVERIFY(item->isSelected());
       
  1334 
       
  1335     QGraphicsScene scene(-100, -100, 200, 200);
       
  1336     scene.addItem(item);
       
  1337     QCOMPARE(scene.selectedItems(), QList<QGraphicsItem *>() << item);
       
  1338     item->setSelected(false);
       
  1339     QVERIFY(scene.selectedItems().isEmpty());
       
  1340     item->setSelected(true);
       
  1341     QCOMPARE(scene.selectedItems(), QList<QGraphicsItem *>() << item);
       
  1342     item->setSelected(false);
       
  1343     QVERIFY(scene.selectedItems().isEmpty());
       
  1344 
       
  1345     // Interactive selection
       
  1346     QGraphicsView view(&scene);
       
  1347     view.setFixedSize(250, 250);
       
  1348     view.show();
       
  1349 
       
  1350     qApp->processEvents();
       
  1351     qApp->processEvents();
       
  1352 
       
  1353     scene.clearSelection();
       
  1354     QCOMPARE(item->values.size(), 10);
       
  1355     QCOMPARE(item->values.last(), false);
       
  1356     QVERIFY(!item->isSelected());
       
  1357 
       
  1358     // Click inside and check that it's selected
       
  1359     QTest::mouseMove(view.viewport());
       
  1360     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(item->scenePos()));
       
  1361     QCOMPARE(item->values.size(), 11);
       
  1362     QCOMPARE(item->values.last(), true);
       
  1363     QVERIFY(item->isSelected());
       
  1364 
       
  1365     // Click outside and check that it's not selected
       
  1366     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(item->scenePos() + QPointF(item->boundingRect().width(), item->boundingRect().height())));
       
  1367     QCOMPARE(item->values.size(), 12);
       
  1368     QCOMPARE(item->values.last(), false);
       
  1369     QVERIFY(!item->isSelected());
       
  1370 
       
  1371     SelectChangeItem *item2 = new SelectChangeItem;
       
  1372     item2->setFlag(QGraphicsItem::ItemIsSelectable);
       
  1373     item2->setPos(100, 0);
       
  1374     scene.addItem(item2);
       
  1375 
       
  1376     // Click inside and check that it's selected
       
  1377     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(item->scenePos()));
       
  1378     QCOMPARE(item->values.size(), 13);
       
  1379     QCOMPARE(item->values.last(), true);
       
  1380     QVERIFY(item->isSelected());
       
  1381 
       
  1382     // Click inside item2 and check that it's selected, and item is not
       
  1383     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(item2->scenePos()));
       
  1384     QCOMPARE(item->values.size(), 14);
       
  1385     QCOMPARE(item->values.last(), false);
       
  1386     QVERIFY(!item->isSelected());
       
  1387     QCOMPARE(item2->values.size(), 1);
       
  1388     QCOMPARE(item2->values.last(), true);
       
  1389     QVERIFY(item2->isSelected());
       
  1390 }
       
  1391 
       
  1392 void tst_QGraphicsItem::selected2()
       
  1393 {
       
  1394     // Selecting an item, then moving another previously caused a crash.
       
  1395     QGraphicsScene scene;
       
  1396     QGraphicsItem *line1 = scene.addRect(QRectF(0, 0, 100, 100));
       
  1397     line1->setPos(-105, 0);
       
  1398     line1->setFlag(QGraphicsItem::ItemIsSelectable);
       
  1399 
       
  1400     QGraphicsItem *line2 = scene.addRect(QRectF(0, 0, 100, 100));
       
  1401     line2->setFlag(QGraphicsItem::ItemIsMovable);
       
  1402 
       
  1403     line1->setSelected(true);
       
  1404 
       
  1405     {
       
  1406         QGraphicsSceneMouseEvent mousePress(QEvent::GraphicsSceneMousePress);
       
  1407         mousePress.setScenePos(QPointF(50, 50));
       
  1408         mousePress.setButton(Qt::LeftButton);
       
  1409         QApplication::sendEvent(&scene, &mousePress);
       
  1410         QVERIFY(mousePress.isAccepted());
       
  1411     }
       
  1412     {
       
  1413         QGraphicsSceneMouseEvent mouseMove(QEvent::GraphicsSceneMouseMove);
       
  1414         mouseMove.setScenePos(QPointF(60, 60));
       
  1415         mouseMove.setButton(Qt::LeftButton);
       
  1416         mouseMove.setButtons(Qt::LeftButton);
       
  1417         QApplication::sendEvent(&scene, &mouseMove);
       
  1418         QVERIFY(mouseMove.isAccepted());
       
  1419     }
       
  1420 }
       
  1421 
       
  1422 void tst_QGraphicsItem::selected_group()
       
  1423 {
       
  1424     QGraphicsScene scene;
       
  1425     QGraphicsItem *item1 = scene.addRect(QRectF());
       
  1426     QGraphicsItem *item2 = scene.addRect(QRectF());
       
  1427     item1->setFlag(QGraphicsItem::ItemIsSelectable);
       
  1428     item2->setFlag(QGraphicsItem::ItemIsSelectable);
       
  1429     scene.addRect(QRectF())->setParentItem(item1);
       
  1430     QGraphicsItem *leaf = scene.addRect(QRectF());
       
  1431     leaf->setFlag(QGraphicsItem::ItemIsSelectable);
       
  1432     leaf->setParentItem(item2);
       
  1433 
       
  1434     QGraphicsItemGroup *group = scene.createItemGroup(QList<QGraphicsItem *>() << item1 << item2);
       
  1435     QCOMPARE(group->scene(), &scene);
       
  1436     group->setFlag(QGraphicsItem::ItemIsSelectable);
       
  1437     foreach (QGraphicsItem *item, scene.items()) {
       
  1438         if (item == group)
       
  1439             QVERIFY(!item->group());
       
  1440         else
       
  1441             QCOMPARE(item->group(), group);
       
  1442     }
       
  1443 
       
  1444     QVERIFY(group->handlesChildEvents());
       
  1445     QVERIFY(!group->isSelected());
       
  1446     group->setSelected(false);
       
  1447     QVERIFY(!group->isSelected());
       
  1448     group->setSelected(true);
       
  1449     QVERIFY(group->isSelected());
       
  1450     foreach (QGraphicsItem *item, scene.items())
       
  1451         QVERIFY(item->isSelected());
       
  1452     group->setSelected(false);
       
  1453     QVERIFY(!group->isSelected());
       
  1454     foreach (QGraphicsItem *item, scene.items())
       
  1455         QVERIFY(!item->isSelected());
       
  1456     leaf->setSelected(true);
       
  1457     foreach (QGraphicsItem *item, scene.items())
       
  1458         QVERIFY(item->isSelected());
       
  1459     leaf->setSelected(false);
       
  1460     foreach (QGraphicsItem *item, scene.items())
       
  1461         QVERIFY(!item->isSelected());
       
  1462 
       
  1463     leaf->setSelected(true);
       
  1464     QGraphicsScene scene2;
       
  1465     scene2.addItem(item1);
       
  1466     QVERIFY(!item1->isSelected());
       
  1467     QVERIFY(item2->isSelected());
       
  1468 }
       
  1469 
       
  1470 void tst_QGraphicsItem::selected_textItem()
       
  1471 {
       
  1472     QGraphicsScene scene;
       
  1473     QGraphicsTextItem *text = scene.addText(QLatin1String("Text"));
       
  1474     text->setFlag(QGraphicsItem::ItemIsSelectable);
       
  1475 
       
  1476     QGraphicsView view(&scene);
       
  1477     view.show();
       
  1478     QTest::qWaitForWindowShown(&view);
       
  1479     QTest::qWait(20);
       
  1480 
       
  1481     QTRY_VERIFY(!text->isSelected());
       
  1482     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0,
       
  1483                       view.mapFromScene(text->mapToScene(0, 0)));
       
  1484     QTRY_VERIFY(text->isSelected());
       
  1485 
       
  1486     text->setSelected(false);
       
  1487     text->setTextInteractionFlags(Qt::TextEditorInteraction);
       
  1488 
       
  1489     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0,
       
  1490                       view.mapFromScene(text->mapToScene(0, 0)));
       
  1491     QTRY_VERIFY(text->isSelected());
       
  1492 }
       
  1493 
       
  1494 void tst_QGraphicsItem::selected_multi()
       
  1495 {
       
  1496     // Test multiselection behavior
       
  1497     QGraphicsScene scene;
       
  1498 
       
  1499     // Create two disjoint items
       
  1500     QGraphicsItem *item1 = scene.addRect(QRectF(-10, -10, 20, 20));
       
  1501     QGraphicsItem *item2 = scene.addRect(QRectF(-10, -10, 20, 20));
       
  1502     item1->setPos(-15, 0);
       
  1503     item2->setPos(15, 20);
       
  1504 
       
  1505     // Make both items selectable
       
  1506     item1->setFlag(QGraphicsItem::ItemIsSelectable);
       
  1507     item2->setFlag(QGraphicsItem::ItemIsSelectable);
       
  1508 
       
  1509     // Create and show a view
       
  1510     QGraphicsView view(&scene);
       
  1511     view.show();
       
  1512     view.fitInView(scene.sceneRect());
       
  1513     qApp->processEvents();
       
  1514 
       
  1515     QVERIFY(!item1->isSelected());
       
  1516     QVERIFY(!item2->isSelected());
       
  1517 
       
  1518     // Start clicking
       
  1519     QTest::qWait(200);
       
  1520 
       
  1521     // Click on item1
       
  1522     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(item1->scenePos()));
       
  1523     QTest::qWait(20);
       
  1524     QVERIFY(item1->isSelected());
       
  1525     QVERIFY(!item2->isSelected());
       
  1526 
       
  1527     // Click on item2
       
  1528     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(item2->scenePos()));
       
  1529     QTest::qWait(20);
       
  1530     QVERIFY(item2->isSelected());
       
  1531     QVERIFY(!item1->isSelected());
       
  1532 
       
  1533     // Ctrl-click on item1
       
  1534     QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, view.mapFromScene(item1->scenePos()));
       
  1535     QTest::qWait(20);
       
  1536     QVERIFY(item2->isSelected());
       
  1537     QVERIFY(item1->isSelected());
       
  1538 
       
  1539     // Ctrl-click on item1 again
       
  1540     QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, view.mapFromScene(item1->scenePos()));
       
  1541     QTest::qWait(20);
       
  1542     QVERIFY(item2->isSelected());
       
  1543     QVERIFY(!item1->isSelected());
       
  1544 
       
  1545     // Ctrl-click on item2
       
  1546     QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, view.mapFromScene(item2->scenePos()));
       
  1547     QTest::qWait(20);
       
  1548     QVERIFY(!item2->isSelected());
       
  1549     QVERIFY(!item1->isSelected());
       
  1550 
       
  1551     // Click on item1
       
  1552     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(item1->scenePos()));
       
  1553     QTest::qWait(20);
       
  1554     QVERIFY(item1->isSelected());
       
  1555     QVERIFY(!item2->isSelected());
       
  1556 
       
  1557     // Click on scene
       
  1558     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(0, 0));
       
  1559     QTest::qWait(20);
       
  1560     QVERIFY(!item1->isSelected());
       
  1561     QVERIFY(!item2->isSelected());
       
  1562 
       
  1563     // Click on item1
       
  1564     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(item1->scenePos()));
       
  1565     QTest::qWait(20);
       
  1566     QVERIFY(item1->isSelected());
       
  1567     QVERIFY(!item2->isSelected());
       
  1568 
       
  1569     // Ctrl-click on scene
       
  1570     QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, view.mapFromScene(0, 0));
       
  1571     QTest::qWait(20);
       
  1572     QVERIFY(!item1->isSelected());
       
  1573     QVERIFY(!item2->isSelected());
       
  1574 
       
  1575     // Click on item1
       
  1576     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(item1->scenePos()));
       
  1577     QTest::qWait(20);
       
  1578     QVERIFY(item1->isSelected());
       
  1579     QVERIFY(!item2->isSelected());
       
  1580 
       
  1581     // Press on item2
       
  1582     QTest::mousePress(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(item2->scenePos()));
       
  1583     QTest::qWait(20);
       
  1584     QVERIFY(!item1->isSelected());
       
  1585     QVERIFY(item2->isSelected());
       
  1586 
       
  1587     // Release on item2
       
  1588     QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(item2->scenePos()));
       
  1589     QTest::qWait(20);
       
  1590     QVERIFY(!item1->isSelected());
       
  1591     QVERIFY(item2->isSelected());
       
  1592 
       
  1593     // Click on item1
       
  1594     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(item1->scenePos()));
       
  1595     QTest::qWait(20);
       
  1596     QVERIFY(item1->isSelected());
       
  1597     QVERIFY(!item2->isSelected());
       
  1598 
       
  1599     // Ctrl-click on item1
       
  1600     QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ControlModifier, view.mapFromScene(item1->scenePos()));
       
  1601     QTest::qWait(20);
       
  1602     QVERIFY(!item1->isSelected());
       
  1603     QVERIFY(!item2->isSelected());
       
  1604 
       
  1605     // Ctrl-press on item1
       
  1606     QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::ControlModifier, view.mapFromScene(item1->scenePos()));
       
  1607     QTest::qWait(20);
       
  1608     QVERIFY(!item1->isSelected());
       
  1609     QVERIFY(!item2->isSelected());
       
  1610 
       
  1611     {
       
  1612         // Ctrl-move on item1
       
  1613         QMouseEvent event(QEvent::MouseMove, view.mapFromScene(item1->scenePos()) + QPoint(1, 0), Qt::LeftButton, Qt::LeftButton, Qt::ControlModifier);
       
  1614         QApplication::sendEvent(view.viewport(), &event);
       
  1615         QTest::qWait(20);
       
  1616         QVERIFY(!item1->isSelected());
       
  1617         QVERIFY(!item2->isSelected());
       
  1618     }
       
  1619 
       
  1620     // Release on item1
       
  1621     QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::ControlModifier, view.mapFromScene(item1->scenePos()));
       
  1622     QTest::qWait(20);
       
  1623     QVERIFY(item1->isSelected());
       
  1624     QVERIFY(!item2->isSelected());
       
  1625 
       
  1626     item1->setFlag(QGraphicsItem::ItemIsMovable);
       
  1627     item1->setSelected(false);
       
  1628 
       
  1629     // Ctrl-press on item1
       
  1630     QTest::mousePress(view.viewport(), Qt::LeftButton, Qt::ControlModifier, view.mapFromScene(item1->scenePos()));
       
  1631     QTest::qWait(20);
       
  1632     QVERIFY(!item1->isSelected());
       
  1633     QVERIFY(!item2->isSelected());
       
  1634 
       
  1635     {
       
  1636         // Ctrl-move on item1
       
  1637         QMouseEvent event(QEvent::MouseMove, view.mapFromScene(item1->scenePos()) + QPoint(1, 0), Qt::LeftButton, Qt::LeftButton, Qt::ControlModifier);
       
  1638         QApplication::sendEvent(view.viewport(), &event);
       
  1639         QTest::qWait(20);
       
  1640         QVERIFY(item1->isSelected());
       
  1641         QVERIFY(!item2->isSelected());
       
  1642     }
       
  1643 
       
  1644     // Release on item1
       
  1645     QTest::mouseRelease(view.viewport(), Qt::LeftButton, Qt::ControlModifier, view.mapFromScene(item1->scenePos()));
       
  1646     QTest::qWait(20);
       
  1647     QVERIFY(item1->isSelected());
       
  1648     QVERIFY(!item2->isSelected());
       
  1649 }
       
  1650 
       
  1651 void tst_QGraphicsItem::acceptedMouseButtons()
       
  1652 {
       
  1653     QGraphicsScene scene;
       
  1654     QGraphicsRectItem *item1 = scene.addRect(QRectF(-10, -10, 20, 20));
       
  1655     QGraphicsRectItem *item2 = scene.addRect(QRectF(-10, -10, 20, 20));
       
  1656     item2->setZValue(1);
       
  1657 
       
  1658     item1->setFlag(QGraphicsItem::ItemIsMovable);
       
  1659     item2->setFlag(QGraphicsItem::ItemIsMovable);
       
  1660 
       
  1661     QCOMPARE(item1->acceptedMouseButtons(), Qt::MouseButtons(0x1f));
       
  1662     QCOMPARE(item2->acceptedMouseButtons(), Qt::MouseButtons(0x1f));
       
  1663 
       
  1664     QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
       
  1665     event.setButton(Qt::LeftButton);
       
  1666     event.setScenePos(QPointF(0, 0));
       
  1667     QApplication::sendEvent(&scene, &event);
       
  1668     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)item2);
       
  1669     item2->setAcceptedMouseButtons(0);
       
  1670     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
  1671     QApplication::sendEvent(&scene, &event);
       
  1672     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)item1);
       
  1673 }
       
  1674 
       
  1675 class HoverItem : public QGraphicsRectItem
       
  1676 {
       
  1677 public:
       
  1678     HoverItem(const QRectF &rect)
       
  1679         : QGraphicsRectItem(rect), hoverInCount(0),
       
  1680           hoverMoveCount(0), hoverOutCount(0)
       
  1681     { }
       
  1682 
       
  1683     int hoverInCount;
       
  1684     int hoverMoveCount;
       
  1685     int hoverOutCount;
       
  1686 protected:
       
  1687     void hoverEnterEvent(QGraphicsSceneHoverEvent *)
       
  1688     { ++hoverInCount; }
       
  1689 
       
  1690     void hoverMoveEvent(QGraphicsSceneHoverEvent *)
       
  1691     { ++hoverMoveCount; }
       
  1692 
       
  1693     void hoverLeaveEvent(QGraphicsSceneHoverEvent *)
       
  1694     { ++hoverOutCount; }
       
  1695 };
       
  1696 
       
  1697 void tst_QGraphicsItem::acceptsHoverEvents()
       
  1698 {
       
  1699     QGraphicsScene scene;
       
  1700     HoverItem *item1 = new HoverItem(QRectF(-10, -10, 20, 20));
       
  1701     HoverItem *item2 = new HoverItem(QRectF(-5, -5, 10, 10));
       
  1702     scene.addItem(item1);
       
  1703     scene.addItem(item2);
       
  1704     item2->setZValue(1);
       
  1705 
       
  1706     QVERIFY(!item1->acceptsHoverEvents());
       
  1707     QVERIFY(!item2->acceptsHoverEvents());
       
  1708     item1->setAcceptsHoverEvents(true);
       
  1709     item2->setAcceptsHoverEvents(true);
       
  1710 
       
  1711     QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseMove);
       
  1712     event.setScenePos(QPointF(-100, -100));
       
  1713     QApplication::sendEvent(&scene, &event);
       
  1714     event.setScenePos(QPointF(-2.5, -2.5));
       
  1715     QApplication::sendEvent(&scene, &event);
       
  1716 
       
  1717     QCOMPARE(item1->hoverInCount, 0);
       
  1718     QCOMPARE(item2->hoverInCount, 1);
       
  1719 
       
  1720     item1->setAcceptsHoverEvents(false);
       
  1721     item2->setAcceptsHoverEvents(false);
       
  1722 
       
  1723     event.setScenePos(QPointF(-100, -100));
       
  1724     QApplication::sendEvent(&scene, &event);
       
  1725     event.setScenePos(QPointF(-2.5, -2.5));
       
  1726     QApplication::sendEvent(&scene, &event);
       
  1727 
       
  1728     QCOMPARE(item1->hoverInCount, 0);
       
  1729     QCOMPARE(item2->hoverInCount, 1);
       
  1730 
       
  1731     item1->setAcceptsHoverEvents(true);
       
  1732     item2->setAcceptsHoverEvents(false);
       
  1733 
       
  1734     event.setScenePos(QPointF(-100, -100));
       
  1735     QApplication::sendEvent(&scene, &event);
       
  1736     event.setScenePos(QPointF(-2.5, -2.5));
       
  1737     QApplication::sendEvent(&scene, &event);
       
  1738 
       
  1739     QCOMPARE(item1->hoverInCount, 1);
       
  1740     QCOMPARE(item2->hoverInCount, 1);
       
  1741 }
       
  1742 
       
  1743 void tst_QGraphicsItem::childAcceptsHoverEvents()
       
  1744 {
       
  1745     QGraphicsScene scene;
       
  1746     HoverItem *item1 = new HoverItem(QRectF(-10, -10, 20, 20));
       
  1747     HoverItem *item2 = new HoverItem(QRectF(-5, -5, 10, 10));
       
  1748 
       
  1749     scene.addItem(item1);
       
  1750     scene.addItem(item2);
       
  1751     item2->setParentItem(item1);
       
  1752     item2->setAcceptHoverEvents(true);
       
  1753 
       
  1754     QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseMove);
       
  1755     event.setScenePos(QPointF(-100, -100));
       
  1756     QApplication::sendEvent(&scene, &event);
       
  1757     QCOMPARE(item2->hoverInCount, 0);
       
  1758     QCOMPARE(item2->hoverMoveCount, 0);
       
  1759     QCOMPARE(item2->hoverOutCount, 0);
       
  1760     QCOMPARE(item1->hoverInCount, 0);
       
  1761     QCOMPARE(item1->hoverMoveCount, 0);
       
  1762     QCOMPARE(item1->hoverOutCount, 0);
       
  1763 
       
  1764     event.setScenePos(QPointF(-2.5, -2.5));
       
  1765     QApplication::sendEvent(&scene, &event);
       
  1766 
       
  1767     QCOMPARE(item2->hoverInCount, 1);
       
  1768     QCOMPARE(item2->hoverMoveCount, 1);
       
  1769     QCOMPARE(item2->hoverOutCount, 0);
       
  1770     QCOMPARE(item1->hoverInCount, 0);
       
  1771     QCOMPARE(item1->hoverMoveCount, 0);
       
  1772     QCOMPARE(item1->hoverOutCount, 0);
       
  1773 
       
  1774     event.setScenePos(QPointF(0, 0));
       
  1775     QApplication::sendEvent(&scene, &event);
       
  1776 
       
  1777     QCOMPARE(item2->hoverInCount, 1);
       
  1778     QCOMPARE(item2->hoverMoveCount, 2);
       
  1779     QCOMPARE(item2->hoverOutCount, 0);
       
  1780     QCOMPARE(item1->hoverInCount, 0);
       
  1781     QCOMPARE(item1->hoverMoveCount, 0);
       
  1782     QCOMPARE(item1->hoverOutCount, 0);
       
  1783 
       
  1784     event.setScenePos(QPointF(-7, -7));
       
  1785     QApplication::sendEvent(&scene, &event);
       
  1786 
       
  1787     QCOMPARE(item2->hoverInCount, 1);
       
  1788     QCOMPARE(item2->hoverMoveCount, 2);
       
  1789     QCOMPARE(item2->hoverOutCount, 1);
       
  1790     QCOMPARE(item1->hoverInCount, 0);
       
  1791     QCOMPARE(item1->hoverMoveCount, 0);
       
  1792     QCOMPARE(item1->hoverOutCount, 0);
       
  1793 
       
  1794     event.setScenePos(QPointF(0, 0));
       
  1795     QApplication::sendEvent(&scene, &event);
       
  1796 
       
  1797     QCOMPARE(item2->hoverInCount, 2);
       
  1798     QCOMPARE(item2->hoverMoveCount, 3);
       
  1799     QCOMPARE(item2->hoverOutCount, 1);
       
  1800     QCOMPARE(item1->hoverInCount, 0);
       
  1801     QCOMPARE(item1->hoverMoveCount, 0);
       
  1802     QCOMPARE(item1->hoverOutCount, 0);
       
  1803 
       
  1804     HoverItem *item0 = new HoverItem(QRectF(-20, -20, 20, 20));
       
  1805     scene.addItem(item0);
       
  1806     item1->setParentItem(item0);
       
  1807     item0->setAcceptHoverEvents(true);
       
  1808 
       
  1809     event.setScenePos(QPointF(-100, -100));
       
  1810     QApplication::sendEvent(&scene, &event);
       
  1811 
       
  1812     event.setScenePos(QPointF(-15, -15));
       
  1813     QApplication::sendEvent(&scene, &event);
       
  1814 
       
  1815     QCOMPARE(item2->hoverInCount, 2);
       
  1816     QCOMPARE(item2->hoverMoveCount, 3);
       
  1817     QCOMPARE(item2->hoverOutCount, 2);
       
  1818     QCOMPARE(item1->hoverInCount, 0);
       
  1819     QCOMPARE(item1->hoverMoveCount, 0);
       
  1820     QCOMPARE(item1->hoverOutCount, 0);
       
  1821     QCOMPARE(item0->hoverInCount, 1);
       
  1822     QCOMPARE(item0->hoverMoveCount, 1);
       
  1823     QCOMPARE(item0->hoverOutCount, 0);
       
  1824 }
       
  1825 
       
  1826 void tst_QGraphicsItem::hasFocus()
       
  1827 {
       
  1828     QGraphicsLineItem *line = new QGraphicsLineItem;
       
  1829     QVERIFY(!line->hasFocus());
       
  1830     line->setFocus();
       
  1831     QVERIFY(!line->hasFocus());
       
  1832 
       
  1833     QGraphicsScene scene;
       
  1834     QEvent activate(QEvent::WindowActivate);
       
  1835     QApplication::sendEvent(&scene, &activate);
       
  1836 
       
  1837     scene.addItem(line);
       
  1838 
       
  1839     line->setFocus();
       
  1840     QVERIFY(!line->hasFocus());
       
  1841     line->setFlag(QGraphicsItem::ItemIsFocusable);
       
  1842     line->setFocus();
       
  1843     QVERIFY(line->hasFocus());
       
  1844 
       
  1845     QGraphicsScene scene2;
       
  1846     QApplication::sendEvent(&scene2, &activate);
       
  1847 
       
  1848     scene2.addItem(line);
       
  1849     QVERIFY(!line->hasFocus());
       
  1850 
       
  1851     QCOMPARE(scene.focusItem(), (QGraphicsItem *)0);
       
  1852     QCOMPARE(scene2.focusItem(), (QGraphicsItem *)0);
       
  1853 
       
  1854     line->setFocus();
       
  1855     QVERIFY(line->hasFocus());
       
  1856     line->clearFocus();
       
  1857     QVERIFY(!line->hasFocus());
       
  1858 
       
  1859     QGraphicsLineItem *line2 = new QGraphicsLineItem;
       
  1860     line2->setFlag(QGraphicsItem::ItemIsFocusable);
       
  1861     scene2.addItem(line2);
       
  1862 
       
  1863     line2->setFocus();
       
  1864     QVERIFY(!line->hasFocus());
       
  1865     QVERIFY(line2->hasFocus());
       
  1866     line->setFocus();
       
  1867     QVERIFY(line->hasFocus());
       
  1868     QVERIFY(!line2->hasFocus());
       
  1869 }
       
  1870 
       
  1871 void tst_QGraphicsItem::pos()
       
  1872 {
       
  1873     QGraphicsItem *child = new QGraphicsLineItem;
       
  1874     QGraphicsItem *parent = new QGraphicsLineItem;
       
  1875 
       
  1876     QCOMPARE(child->pos(), QPointF());
       
  1877     QCOMPARE(parent->pos(), QPointF());
       
  1878 
       
  1879     child->setParentItem(parent);
       
  1880     child->setPos(10, 10);
       
  1881 
       
  1882     QCOMPARE(child->pos(), QPointF(10, 10));
       
  1883 
       
  1884     parent->setPos(10, 10);
       
  1885 
       
  1886     QCOMPARE(parent->pos(), QPointF(10, 10));
       
  1887     QCOMPARE(child->pos(), QPointF(10, 10));
       
  1888 
       
  1889     delete child;
       
  1890     delete parent;
       
  1891 }
       
  1892 
       
  1893 void tst_QGraphicsItem::scenePos()
       
  1894 {
       
  1895     QGraphicsItem *child = new QGraphicsLineItem;
       
  1896     QGraphicsItem *parent = new QGraphicsLineItem;
       
  1897 
       
  1898     QCOMPARE(child->scenePos(), QPointF());
       
  1899     QCOMPARE(parent->scenePos(), QPointF());
       
  1900 
       
  1901     child->setParentItem(parent);
       
  1902     child->setPos(10, 10);
       
  1903 
       
  1904     QCOMPARE(child->scenePos(), QPointF(10, 10));
       
  1905 
       
  1906     parent->setPos(10, 10);
       
  1907 
       
  1908     QCOMPARE(parent->scenePos(), QPointF(10, 10));
       
  1909     QCOMPARE(child->scenePos(), QPointF(20, 20));
       
  1910 
       
  1911     parent->setPos(20, 20);
       
  1912 
       
  1913     QCOMPARE(parent->scenePos(), QPointF(20, 20));
       
  1914     QCOMPARE(child->scenePos(), QPointF(30, 30));
       
  1915 
       
  1916     delete child;
       
  1917     delete parent;
       
  1918 }
       
  1919 
       
  1920 void tst_QGraphicsItem::matrix()
       
  1921 {
       
  1922     QGraphicsLineItem line;
       
  1923     QCOMPARE(line.matrix(), QMatrix());
       
  1924     line.setMatrix(QMatrix().rotate(90));
       
  1925     QCOMPARE(line.matrix(), QMatrix().rotate(90));
       
  1926     line.setMatrix(QMatrix().rotate(90));
       
  1927     QCOMPARE(line.matrix(), QMatrix().rotate(90));
       
  1928     line.setMatrix(QMatrix().rotate(90), true);
       
  1929     QCOMPARE(line.matrix(), QMatrix().rotate(180));
       
  1930     line.setMatrix(QMatrix().rotate(-90), true);
       
  1931     QCOMPARE(line.matrix(), QMatrix().rotate(90));
       
  1932     line.resetMatrix();
       
  1933     QCOMPARE(line.matrix(), QMatrix());
       
  1934 
       
  1935     line.rotate(90);
       
  1936     QCOMPARE(line.matrix(), QMatrix().rotate(90));
       
  1937     line.rotate(90);
       
  1938     QCOMPARE(line.matrix(), QMatrix().rotate(90).rotate(90));
       
  1939     line.resetMatrix();
       
  1940 
       
  1941     line.scale(2, 4);
       
  1942     QCOMPARE(line.matrix(), QMatrix().scale(2, 4));
       
  1943     line.scale(2, 4);
       
  1944     QCOMPARE(line.matrix(), QMatrix().scale(2, 4).scale(2, 4));
       
  1945     line.resetMatrix();
       
  1946 
       
  1947     line.shear(2, 4);
       
  1948     QCOMPARE(line.matrix(), QMatrix().shear(2, 4));
       
  1949     line.shear(2, 4);
       
  1950     QCOMPARE(line.matrix(), QMatrix().shear(2, 4).shear(2, 4));
       
  1951     line.resetMatrix();
       
  1952 
       
  1953     line.translate(10, 10);
       
  1954     QCOMPARE(line.matrix(), QMatrix().translate(10, 10));
       
  1955     line.translate(10, 10);
       
  1956     QCOMPARE(line.matrix(), QMatrix().translate(10, 10).translate(10, 10));
       
  1957     line.resetMatrix();
       
  1958 }
       
  1959 
       
  1960 void tst_QGraphicsItem::sceneMatrix()
       
  1961 {
       
  1962     QGraphicsLineItem *parent = new QGraphicsLineItem;
       
  1963     QGraphicsLineItem *child = new QGraphicsLineItem(QLineF(), parent);
       
  1964 
       
  1965     QCOMPARE(parent->sceneMatrix(), QMatrix());
       
  1966     QCOMPARE(child->sceneMatrix(), QMatrix());
       
  1967 
       
  1968     parent->translate(10, 10);
       
  1969     QCOMPARE(parent->sceneMatrix(), QMatrix().translate(10, 10));
       
  1970     QCOMPARE(child->sceneMatrix(), QMatrix().translate(10, 10));
       
  1971 
       
  1972     child->translate(10, 10);
       
  1973     QCOMPARE(parent->sceneMatrix(), QMatrix().translate(10, 10));
       
  1974     QCOMPARE(child->sceneMatrix(), QMatrix().translate(20, 20));
       
  1975 
       
  1976     parent->rotate(90);
       
  1977     QCOMPARE(parent->sceneMatrix(), QMatrix().translate(10, 10).rotate(90));
       
  1978     QCOMPARE(child->sceneMatrix(), QMatrix().translate(10, 10).rotate(90).translate(10, 10));
       
  1979 
       
  1980     delete child;
       
  1981     delete parent;
       
  1982 }
       
  1983 
       
  1984 void tst_QGraphicsItem::setMatrix()
       
  1985 {
       
  1986     QGraphicsScene scene;
       
  1987     qRegisterMetaType<QList<QRectF> >("QList<QRectF>");
       
  1988     QSignalSpy spy(&scene, SIGNAL(changed(QList<QRectF>)));
       
  1989     QRectF unrotatedRect(-12, -34, 56, 78);
       
  1990     QGraphicsRectItem item(unrotatedRect, 0, &scene);
       
  1991     scene.update(scene.sceneRect());
       
  1992     QApplication::instance()->processEvents();
       
  1993 
       
  1994     QCOMPARE(spy.count(), 1);
       
  1995 
       
  1996     item.setMatrix(QMatrix().rotate(qreal(12.34)));
       
  1997     QRectF rotatedRect = scene.sceneRect();
       
  1998     QVERIFY(unrotatedRect != rotatedRect);
       
  1999     scene.update(scene.sceneRect());
       
  2000     QApplication::instance()->processEvents();
       
  2001 
       
  2002     QCOMPARE(spy.count(), 2);
       
  2003 
       
  2004     item.setMatrix(QMatrix());
       
  2005 
       
  2006     scene.update(scene.sceneRect());
       
  2007     QApplication::instance()->processEvents();
       
  2008 
       
  2009     QCOMPARE(spy.count(), 3);
       
  2010     QList<QRectF> rlist = qVariantValue<QList<QRectF> >(spy.last().at(0));
       
  2011 
       
  2012     QCOMPARE(rlist.size(), 3);
       
  2013     QCOMPARE(rlist.at(0), rotatedRect);   // From item.setMatrix() (clearing rotated rect)
       
  2014     QCOMPARE(rlist.at(1), rotatedRect);   // From scene.update()   (updating scene rect)
       
  2015     QCOMPARE(rlist.at(2), unrotatedRect); // From post-update      (update current state)
       
  2016 }
       
  2017 
       
  2018 static QList<QGraphicsItem *> _paintedItems;
       
  2019 class PainterItem : public QGraphicsItem
       
  2020 {
       
  2021 protected:
       
  2022     QRectF boundingRect() const
       
  2023     { return QRectF(-10, -10, 20, 20); }
       
  2024 
       
  2025     void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
       
  2026     { _paintedItems << this; painter->fillRect(boundingRect(), Qt::red); }
       
  2027 };
       
  2028 
       
  2029 void tst_QGraphicsItem::zValue()
       
  2030 {
       
  2031     Q_CHECK_PAINTEVENTS
       
  2032 
       
  2033     QGraphicsScene scene;
       
  2034 
       
  2035     QGraphicsItem *item1 = new PainterItem;
       
  2036     QGraphicsItem *item2 = new PainterItem;
       
  2037     QGraphicsItem *item3 = new PainterItem;
       
  2038     QGraphicsItem *item4 = new PainterItem;
       
  2039     scene.addItem(item1);
       
  2040     scene.addItem(item2);
       
  2041     scene.addItem(item3);
       
  2042     scene.addItem(item4);
       
  2043     item2->setZValue(-3);
       
  2044     item4->setZValue(-2);
       
  2045     item1->setZValue(-1);
       
  2046     item3->setZValue(0);
       
  2047 
       
  2048     QGraphicsView view(&scene);
       
  2049     view.show();
       
  2050 #ifdef Q_WS_X11
       
  2051     qt_x11_wait_for_window_manager(&view);
       
  2052 #endif
       
  2053     QApplication::processEvents();
       
  2054 #ifdef Q_WS_QWS
       
  2055     QApplication::sendPostedEvents(); //glib workaround
       
  2056 #endif
       
  2057 
       
  2058     QTRY_VERIFY(!_paintedItems.isEmpty());
       
  2059     QVERIFY((_paintedItems.size() % 4) == 0);
       
  2060     for (int i = 0; i < 3; ++i)
       
  2061         QVERIFY(_paintedItems.at(i)->zValue() < _paintedItems.at(i + 1)->zValue());
       
  2062 }
       
  2063 
       
  2064 void tst_QGraphicsItem::shape()
       
  2065 {
       
  2066     QGraphicsLineItem line(QLineF(-10, -10, 20, 20));
       
  2067 
       
  2068     // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0
       
  2069     // if we pass a value of 0.0 to QPainterPathStroker::setWidth()
       
  2070     const qreal penWidthZero = qreal(0.00000001);
       
  2071 
       
  2072     QPainterPathStroker ps;
       
  2073     ps.setWidth(penWidthZero);
       
  2074 
       
  2075     QPainterPath path(line.line().p1());
       
  2076     path.lineTo(line.line().p2());
       
  2077     QPainterPath p = ps.createStroke(path);
       
  2078     p.addPath(path);
       
  2079     QCOMPARE(line.shape(), p);
       
  2080 
       
  2081     QPen linePen;
       
  2082     linePen.setWidthF(5.0);
       
  2083     linePen.setCapStyle(Qt::RoundCap);
       
  2084     line.setPen(linePen);
       
  2085 
       
  2086     ps.setCapStyle(line.pen().capStyle());
       
  2087     ps.setWidth(line.pen().widthF());
       
  2088     p = ps.createStroke(path);
       
  2089     p.addPath(path);
       
  2090     QCOMPARE(line.shape(), p);
       
  2091 
       
  2092     linePen.setCapStyle(Qt::FlatCap);
       
  2093     line.setPen(linePen);
       
  2094     ps.setCapStyle(line.pen().capStyle());
       
  2095     p = ps.createStroke(path);
       
  2096     p.addPath(path);
       
  2097     QCOMPARE(line.shape(), p);
       
  2098 
       
  2099     linePen.setCapStyle(Qt::SquareCap);
       
  2100     line.setPen(linePen);
       
  2101     ps.setCapStyle(line.pen().capStyle());
       
  2102     p = ps.createStroke(path);
       
  2103     p.addPath(path);
       
  2104     QCOMPARE(line.shape(), p);
       
  2105 
       
  2106     QGraphicsRectItem rect(QRectF(-10, -10, 20, 20));
       
  2107     QPainterPathStroker ps1;
       
  2108     ps1.setWidth(penWidthZero);
       
  2109     path = QPainterPath();
       
  2110     path.addRect(rect.rect());
       
  2111     p = ps1.createStroke(path);
       
  2112     p.addPath(path);
       
  2113     QCOMPARE(rect.shape(), p);
       
  2114 
       
  2115     QGraphicsEllipseItem ellipse(QRectF(-10, -10, 20, 20));
       
  2116     QPainterPathStroker ps2;
       
  2117     ps2.setWidth(ellipse.pen().widthF() <= 0.0 ? penWidthZero : ellipse.pen().widthF());
       
  2118     path = QPainterPath();
       
  2119     path.addEllipse(ellipse.rect());
       
  2120     p = ps2.createStroke(path);
       
  2121     p.addPath(path);
       
  2122     QCOMPARE(ellipse.shape(), p);
       
  2123 
       
  2124     QPainterPathStroker ps3;
       
  2125     ps3.setWidth(penWidthZero);
       
  2126     p = ps3.createStroke(path);
       
  2127     p.addPath(path);
       
  2128     QGraphicsPathItem pathItem(path);
       
  2129     QCOMPARE(pathItem.shape(), p);
       
  2130 
       
  2131     QRegion region(QRect(0, 0, 300, 200));
       
  2132     region = region.subtracted(QRect(50, 50, 200, 100));
       
  2133 
       
  2134     QImage image(300, 200, QImage::Format_ARGB32_Premultiplied);
       
  2135     image.fill(0);
       
  2136     QPainter painter(&image);
       
  2137     painter.setClipRegion(region);
       
  2138     painter.fillRect(0, 0, 300, 200, Qt::green);
       
  2139     painter.end();
       
  2140     QPixmap pixmap = QPixmap::fromImage(image);
       
  2141 
       
  2142     QGraphicsPixmapItem pixmapItem(pixmap);
       
  2143     path = QPainterPath();
       
  2144     path.addRegion(region);
       
  2145 
       
  2146     {
       
  2147         QBitmap bitmap(300, 200);
       
  2148         bitmap.clear();
       
  2149         QPainter painter(&bitmap);
       
  2150         painter.setClipRegion(region);
       
  2151         painter.fillRect(0, 0, 300, 200, Qt::color1);
       
  2152         painter.end();
       
  2153 
       
  2154         QBitmap bitmap2(300, 200);
       
  2155         bitmap2.clear();
       
  2156         painter.begin(&bitmap2);
       
  2157         painter.setClipPath(pixmapItem.shape());
       
  2158         painter.fillRect(0, 0, 300, 200, Qt::color1);
       
  2159         painter.end();
       
  2160 
       
  2161         QCOMPARE(bitmap.toImage(), bitmap2.toImage());
       
  2162     }
       
  2163 
       
  2164     QPolygonF poly;
       
  2165     poly << QPointF(0, 0) << QPointF(10, 0) << QPointF(0, 10);
       
  2166     QGraphicsPolygonItem polygon(poly);
       
  2167     path = QPainterPath();
       
  2168     path.addPolygon(poly);
       
  2169 
       
  2170     QPainterPathStroker ps4;
       
  2171     ps4.setWidth(penWidthZero);
       
  2172     p = ps4.createStroke(path);
       
  2173     p.addPath(path);
       
  2174     QCOMPARE(polygon.shape(), p);
       
  2175 }
       
  2176 
       
  2177 void tst_QGraphicsItem::contains()
       
  2178 {
       
  2179     if (sizeof(qreal) != sizeof(double)) {
       
  2180         QSKIP("Skipped due to rounding errors", SkipAll);
       
  2181     }
       
  2182 
       
  2183     // Rect
       
  2184     QGraphicsRectItem rect(QRectF(-10, -10, 20, 20));
       
  2185     QVERIFY(!rect.contains(QPointF(-11, -10)));
       
  2186     QVERIFY(rect.contains(QPointF(-10, -10)));
       
  2187     QVERIFY(!rect.contains(QPointF(-11, 0)));
       
  2188     QVERIFY(rect.contains(QPointF(-10, 0)));
       
  2189     QVERIFY(rect.contains(QPointF(0, -10)));
       
  2190     QVERIFY(rect.contains(QPointF(0, 0)));
       
  2191     QVERIFY(rect.contains(QPointF(9, 9)));
       
  2192 
       
  2193     // Ellipse
       
  2194     QGraphicsEllipseItem ellipse(QRectF(-10, -10, 20, 20));
       
  2195     QVERIFY(!ellipse.contains(QPointF(-10, -10)));
       
  2196     QVERIFY(ellipse.contains(QPointF(-9, 0)));
       
  2197     QVERIFY(ellipse.contains(QPointF(0, -9)));
       
  2198     QVERIFY(ellipse.contains(QPointF(0, 0)));
       
  2199     QVERIFY(!ellipse.contains(QPointF(9, 9)));
       
  2200 
       
  2201     // Line
       
  2202     QGraphicsLineItem line(QLineF(-10, -10, 20, 20));
       
  2203     QVERIFY(!line.contains(QPointF(-10, 0)));
       
  2204     QVERIFY(!line.contains(QPointF(0, -10)));
       
  2205     QVERIFY(!line.contains(QPointF(10, 0)));
       
  2206     QVERIFY(!line.contains(QPointF(0, 10)));
       
  2207     QVERIFY(line.contains(QPointF(0, 0)));
       
  2208     QVERIFY(line.contains(QPointF(-9, -9)));
       
  2209     QVERIFY(line.contains(QPointF(9, 9)));
       
  2210 
       
  2211     // Polygon
       
  2212     QGraphicsPolygonItem polygon(QPolygonF()
       
  2213                                  << QPointF(0, 0)
       
  2214                                  << QPointF(10, 0)
       
  2215                                  << QPointF(0, 10));
       
  2216     QVERIFY(polygon.contains(QPointF(1, 1)));
       
  2217     QVERIFY(polygon.contains(QPointF(4, 4)));
       
  2218     QVERIFY(polygon.contains(QPointF(1, 4)));
       
  2219     QVERIFY(polygon.contains(QPointF(4, 1)));
       
  2220     QVERIFY(!polygon.contains(QPointF(8, 8)));
       
  2221     QVERIFY(polygon.contains(QPointF(1, 8)));
       
  2222     QVERIFY(polygon.contains(QPointF(8, 1)));
       
  2223 }
       
  2224 
       
  2225 void tst_QGraphicsItem::collidesWith_item()
       
  2226 {
       
  2227     // Rectangle
       
  2228     QGraphicsRectItem rect(QRectF(-10, -10, 20, 20));
       
  2229     QGraphicsRectItem rect2(QRectF(-10, -10, 20, 20));
       
  2230     QVERIFY(rect.collidesWithItem(&rect2));
       
  2231     QVERIFY(rect2.collidesWithItem(&rect));
       
  2232     rect2.setPos(21, 21);
       
  2233     QVERIFY(!rect.collidesWithItem(&rect2));
       
  2234     QVERIFY(!rect2.collidesWithItem(&rect));
       
  2235     rect2.setPos(-21, -21);
       
  2236     QVERIFY(!rect.collidesWithItem(&rect2));
       
  2237     QVERIFY(!rect2.collidesWithItem(&rect));
       
  2238     rect2.setPos(-17, -17);
       
  2239     QVERIFY(rect.collidesWithItem(&rect2));
       
  2240     QVERIFY(rect2.collidesWithItem(&rect));
       
  2241 
       
  2242     QGraphicsEllipseItem ellipse(QRectF(-10, -10, 20, 20));
       
  2243     QGraphicsEllipseItem ellipse2(QRectF(-10, -10, 20, 20));
       
  2244     QVERIFY(ellipse.collidesWithItem(&ellipse2));
       
  2245     QVERIFY(ellipse2.collidesWithItem(&ellipse));
       
  2246     ellipse2.setPos(21, 21);
       
  2247     QVERIFY(!ellipse.collidesWithItem(&ellipse2));
       
  2248     QVERIFY(!ellipse2.collidesWithItem(&ellipse));
       
  2249     ellipse2.setPos(-21, -21);
       
  2250     QVERIFY(!ellipse.collidesWithItem(&ellipse2));
       
  2251     QVERIFY(!ellipse2.collidesWithItem(&ellipse));
       
  2252 
       
  2253     ellipse2.setPos(-17, -17);
       
  2254     QVERIFY(!ellipse.collidesWithItem(&ellipse2));
       
  2255     QVERIFY(!ellipse2.collidesWithItem(&ellipse));
       
  2256 
       
  2257     {
       
  2258         QGraphicsScene scene;
       
  2259         QGraphicsRectItem rect(20, 20, 100, 100, 0, &scene);
       
  2260         QGraphicsRectItem rect2(40, 40, 50, 50, 0, &scene);
       
  2261         rect2.setZValue(1);
       
  2262         QGraphicsLineItem line(0, 0, 200, 200, 0, &scene);
       
  2263         line.setZValue(2);
       
  2264 
       
  2265         QCOMPARE(scene.items().size(), 3);
       
  2266 
       
  2267         QList<QGraphicsItem *> col1 = rect.collidingItems();
       
  2268         QCOMPARE(col1.size(), 2);
       
  2269         QCOMPARE(col1.first(), static_cast<QGraphicsItem *>(&line));
       
  2270         QCOMPARE(col1.last(), static_cast<QGraphicsItem *>(&rect2));
       
  2271 
       
  2272         QList<QGraphicsItem *> col2 = rect2.collidingItems();
       
  2273         QCOMPARE(col2.size(), 2);
       
  2274         QCOMPARE(col2.first(), static_cast<QGraphicsItem *>(&line));
       
  2275         QCOMPARE(col2.last(), static_cast<QGraphicsItem *>(&rect));
       
  2276 
       
  2277         QList<QGraphicsItem *> col3 = line.collidingItems();
       
  2278         QCOMPARE(col3.size(), 2);
       
  2279         QCOMPARE(col3.first(), static_cast<QGraphicsItem *>(&rect2));
       
  2280         QCOMPARE(col3.last(), static_cast<QGraphicsItem *>(&rect));
       
  2281     }
       
  2282 }
       
  2283 
       
  2284 void tst_QGraphicsItem::collidesWith_path_data()
       
  2285 {
       
  2286     QTest::addColumn<QPointF>("pos");
       
  2287     QTest::addColumn<QMatrix>("matrix");
       
  2288     QTest::addColumn<QPainterPath>("shape");
       
  2289     QTest::addColumn<bool>("rectCollides");
       
  2290     QTest::addColumn<bool>("ellipseCollides");
       
  2291 
       
  2292     QTest::newRow("nothing") << QPointF(0, 0) << QMatrix() << QPainterPath() << false << false;
       
  2293 
       
  2294     QPainterPath rect;
       
  2295     rect.addRect(0, 0, 20, 20);
       
  2296 
       
  2297     QTest::newRow("rect1") << QPointF(0, 0) << QMatrix() << rect << true << true;
       
  2298     QTest::newRow("rect2") << QPointF(0, 0) << QMatrix().translate(21, 21) << rect << false << false;
       
  2299     QTest::newRow("rect3") << QPointF(21, 21) << QMatrix() << rect << false << false;
       
  2300 }
       
  2301 
       
  2302 void tst_QGraphicsItem::collidesWith_path()
       
  2303 {
       
  2304     QFETCH(QPointF, pos);
       
  2305     QFETCH(QMatrix, matrix);
       
  2306     QFETCH(QPainterPath, shape);
       
  2307     QFETCH(bool, rectCollides);
       
  2308     QFETCH(bool, ellipseCollides);
       
  2309 
       
  2310     QGraphicsRectItem rect(QRectF(0, 0, 20, 20));
       
  2311     QGraphicsEllipseItem ellipse(QRectF(0, 0, 20, 20));
       
  2312 
       
  2313     rect.setPos(pos);
       
  2314     rect.setMatrix(matrix);
       
  2315 
       
  2316     ellipse.setPos(pos);
       
  2317     ellipse.setMatrix(matrix);
       
  2318 
       
  2319     QPainterPath mappedShape = rect.sceneMatrix().inverted().map(shape);
       
  2320 
       
  2321     if (rectCollides)
       
  2322         QVERIFY(rect.collidesWithPath(mappedShape));
       
  2323     else
       
  2324         QVERIFY(!rect.collidesWithPath(mappedShape));
       
  2325 
       
  2326     if (ellipseCollides)
       
  2327         QVERIFY(ellipse.collidesWithPath(mappedShape));
       
  2328     else
       
  2329         QVERIFY(!ellipse.collidesWithPath(mappedShape));
       
  2330 }
       
  2331 
       
  2332 void tst_QGraphicsItem::collidesWithItemWithClip()
       
  2333 {
       
  2334     QGraphicsScene scene;
       
  2335 
       
  2336     QGraphicsEllipseItem *ellipse = scene.addEllipse(0, 0, 100, 100);
       
  2337     ellipse->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  2338     QGraphicsEllipseItem *ellipse2 = scene.addEllipse(0, 0, 10, 10);
       
  2339     ellipse2->setParentItem(ellipse);
       
  2340     QGraphicsEllipseItem *ellipse3 = scene.addEllipse(0, 0, 10, 10);
       
  2341     ellipse3->setParentItem(ellipse);
       
  2342     QGraphicsEllipseItem *ellipse5 = scene.addEllipse(50, 50, 10, 10);
       
  2343     ellipse5->setParentItem(ellipse);
       
  2344     QGraphicsEllipseItem *ellipse4 = scene.addEllipse(0, 0, 10, 10);
       
  2345 
       
  2346     QVERIFY(ellipse2->collidesWithItem(ellipse3));
       
  2347     QVERIFY(ellipse3->collidesWithItem(ellipse2));
       
  2348     QVERIFY(!ellipse2->collidesWithItem(ellipse));
       
  2349     QVERIFY(!ellipse->collidesWithItem(ellipse2));
       
  2350     QVERIFY(!ellipse4->collidesWithItem(ellipse));
       
  2351     QVERIFY(!ellipse4->collidesWithItem(ellipse2));
       
  2352     QVERIFY(!ellipse4->collidesWithItem(ellipse3));
       
  2353     QVERIFY(!ellipse->collidesWithItem(ellipse4));
       
  2354     QVERIFY(!ellipse2->collidesWithItem(ellipse4));
       
  2355     QVERIFY(!ellipse3->collidesWithItem(ellipse4));
       
  2356     QVERIFY(ellipse->collidesWithItem(ellipse5));
       
  2357     QVERIFY(ellipse5->collidesWithItem(ellipse));
       
  2358 }
       
  2359 
       
  2360 class MyItem : public QGraphicsEllipseItem
       
  2361 {
       
  2362 public:
       
  2363     bool isObscuredBy(const QGraphicsItem *item) const
       
  2364     {
       
  2365         const MyItem *myItem = qgraphicsitem_cast<const MyItem *>(item);
       
  2366         if (myItem) {
       
  2367             if (item->zValue() > zValue()) {
       
  2368                 QRectF r = rect();
       
  2369                 QPointF topMid = (r.topRight()+r.topLeft())/2;
       
  2370                 QPointF botMid = (r.bottomRight()+r.bottomLeft())/2;
       
  2371                 QPointF leftMid = (r.topLeft()+r.bottomLeft())/2;
       
  2372                 QPointF rightMid = (r.topRight()+r.bottomRight())/2;
       
  2373 
       
  2374                 QPainterPath mappedShape = item->mapToItem(this, item->opaqueArea());
       
  2375 
       
  2376                 if (mappedShape.contains(topMid) &&
       
  2377                     mappedShape.contains(botMid) &&
       
  2378                     mappedShape.contains(leftMid) &&
       
  2379                     mappedShape.contains(rightMid))
       
  2380                     return true;
       
  2381                 else
       
  2382                     return false;
       
  2383             }
       
  2384             else return false;
       
  2385         }
       
  2386         else
       
  2387             return QGraphicsItem::isObscuredBy(item);
       
  2388     }
       
  2389 
       
  2390     QPainterPath opaqueArea() const
       
  2391     {
       
  2392         return shape();
       
  2393     }
       
  2394 
       
  2395     enum {
       
  2396         Type = UserType+1
       
  2397     };
       
  2398     int type() const { return Type; }
       
  2399 };
       
  2400 
       
  2401 void tst_QGraphicsItem::isObscuredBy()
       
  2402 {
       
  2403     QGraphicsScene scene;
       
  2404 
       
  2405     MyItem myitem1, myitem2;
       
  2406 
       
  2407     myitem1.setRect(QRectF(50, 50, 40, 200));
       
  2408     myitem1.rotate(67);
       
  2409 
       
  2410     myitem2.setRect(QRectF(25, 25, 20, 20));
       
  2411     myitem2.setZValue(-1.0);
       
  2412     scene.addItem(&myitem1);
       
  2413     scene.addItem(&myitem2);
       
  2414 
       
  2415     QVERIFY(!myitem2.isObscuredBy(&myitem1));
       
  2416     QVERIFY(!myitem1.isObscuredBy(&myitem2));
       
  2417 
       
  2418     myitem2.setRect(QRectF(-50, 85, 20, 20));
       
  2419     QVERIFY(myitem2.isObscuredBy(&myitem1));
       
  2420     QVERIFY(!myitem1.isObscuredBy(&myitem2));
       
  2421 
       
  2422     myitem2.setRect(QRectF(-30, 70, 20, 20));
       
  2423     QVERIFY(!myitem2.isObscuredBy(&myitem1));
       
  2424     QVERIFY(!myitem1.isObscuredBy(&myitem2));
       
  2425 
       
  2426     QGraphicsRectItem rect1, rect2;
       
  2427 
       
  2428     rect1.setRect(QRectF(-40, -40, 50, 50));
       
  2429     rect1.setBrush(QBrush(Qt::red));
       
  2430     rect2.setRect(QRectF(-30, -20, 20, 20));
       
  2431     rect2.setZValue(-1.0);
       
  2432     rect2.setBrush(QBrush(Qt::blue));
       
  2433 
       
  2434     QVERIFY(rect2.isObscuredBy(&rect1));
       
  2435     QVERIFY(!rect1.isObscuredBy(&rect2));
       
  2436 
       
  2437     rect2.setPos(QPointF(-20, -25));
       
  2438 
       
  2439     QVERIFY(!rect2.isObscuredBy(&rect1));
       
  2440     QVERIFY(!rect1.isObscuredBy(&rect2));
       
  2441 
       
  2442     rect2.setPos(QPointF(-100, -100));
       
  2443 
       
  2444     QVERIFY(!rect2.isObscuredBy(&rect1));
       
  2445     QVERIFY(!rect1.isObscuredBy(&rect2));
       
  2446 }
       
  2447 
       
  2448 class OpaqueItem : public QGraphicsRectItem
       
  2449 {
       
  2450 protected:
       
  2451     QPainterPath opaqueArea() const
       
  2452     {
       
  2453         return shape();
       
  2454     }
       
  2455 };
       
  2456 
       
  2457 void tst_QGraphicsItem::isObscured()
       
  2458 {
       
  2459     if (sizeof(qreal) != sizeof(double)) {
       
  2460         QSKIP("Skipped due to rounding errors", SkipAll);
       
  2461     }
       
  2462 
       
  2463     OpaqueItem *item1 = new OpaqueItem;
       
  2464     item1->setRect(0, 0, 100, 100);
       
  2465     item1->setZValue(0);
       
  2466 
       
  2467     OpaqueItem *item2 = new OpaqueItem;
       
  2468     item2->setZValue(1);
       
  2469     item2->setRect(0, 0, 100, 100);
       
  2470 
       
  2471     QGraphicsScene scene;
       
  2472     scene.addItem(item1);
       
  2473     scene.addItem(item2);
       
  2474 
       
  2475     QVERIFY(item1->isObscured());
       
  2476     QVERIFY(item1->isObscuredBy(item2));
       
  2477     QVERIFY(item1->isObscured(QRectF(0, 0, 50, 50)));
       
  2478     QVERIFY(item1->isObscured(QRectF(50, 0, 50, 50)));
       
  2479     QVERIFY(item1->isObscured(QRectF(50, 50, 50, 50)));
       
  2480     QVERIFY(item1->isObscured(QRectF(0, 50, 50, 50)));
       
  2481     QVERIFY(item1->isObscured(0, 0, 50, 50));
       
  2482     QVERIFY(item1->isObscured(50, 0, 50, 50));
       
  2483     QVERIFY(item1->isObscured(50, 50, 50, 50));
       
  2484     QVERIFY(item1->isObscured(0, 50, 50, 50));
       
  2485     QVERIFY(!item2->isObscured());
       
  2486     QVERIFY(!item2->isObscuredBy(item1));
       
  2487     QVERIFY(!item2->isObscured(QRectF(0, 0, 50, 50)));
       
  2488     QVERIFY(!item2->isObscured(QRectF(50, 0, 50, 50)));
       
  2489     QVERIFY(!item2->isObscured(QRectF(50, 50, 50, 50)));
       
  2490     QVERIFY(!item2->isObscured(QRectF(0, 50, 50, 50)));
       
  2491     QVERIFY(!item2->isObscured(0, 0, 50, 50));
       
  2492     QVERIFY(!item2->isObscured(50, 0, 50, 50));
       
  2493     QVERIFY(!item2->isObscured(50, 50, 50, 50));
       
  2494     QVERIFY(!item2->isObscured(0, 50, 50, 50));
       
  2495 
       
  2496     item2->moveBy(50, 0);
       
  2497 
       
  2498     QVERIFY(!item1->isObscured());
       
  2499     QVERIFY(!item1->isObscuredBy(item2));
       
  2500     QVERIFY(!item1->isObscured(QRectF(0, 0, 50, 50)));
       
  2501     QVERIFY(item1->isObscured(QRectF(50, 0, 50, 50)));
       
  2502     QVERIFY(item1->isObscured(QRectF(50, 50, 50, 50)));
       
  2503     QVERIFY(!item1->isObscured(QRectF(0, 50, 50, 50)));
       
  2504     QVERIFY(!item1->isObscured(0, 0, 50, 50));
       
  2505     QVERIFY(item1->isObscured(50, 0, 50, 50));
       
  2506     QVERIFY(item1->isObscured(50, 50, 50, 50));
       
  2507     QVERIFY(!item1->isObscured(0, 50, 50, 50));
       
  2508     QVERIFY(!item2->isObscured());
       
  2509     QVERIFY(!item2->isObscuredBy(item1));
       
  2510     QVERIFY(!item2->isObscured(QRectF(0, 0, 50, 50)));
       
  2511     QVERIFY(!item2->isObscured(QRectF(50, 0, 50, 50)));
       
  2512     QVERIFY(!item2->isObscured(QRectF(50, 50, 50, 50)));
       
  2513     QVERIFY(!item2->isObscured(QRectF(0, 50, 50, 50)));
       
  2514     QVERIFY(!item2->isObscured(0, 0, 50, 50));
       
  2515     QVERIFY(!item2->isObscured(50, 0, 50, 50));
       
  2516     QVERIFY(!item2->isObscured(50, 50, 50, 50));
       
  2517     QVERIFY(!item2->isObscured(0, 50, 50, 50));
       
  2518 }
       
  2519 
       
  2520 void tst_QGraphicsItem::mapFromToParent()
       
  2521 {
       
  2522     QPainterPath path1;
       
  2523     path1.addRect(0, 0, 200, 200);
       
  2524 
       
  2525     QPainterPath path2;
       
  2526     path2.addRect(0, 0, 100, 100);
       
  2527 
       
  2528     QPainterPath path3;
       
  2529     path3.addRect(0, 0, 50, 50);
       
  2530 
       
  2531     QPainterPath path4;
       
  2532     path4.addRect(0, 0, 25, 25);
       
  2533 
       
  2534     QGraphicsItem *item1 = new QGraphicsPathItem(path1);
       
  2535     QGraphicsItem *item2 = new QGraphicsPathItem(path2, item1);
       
  2536     QGraphicsItem *item3 = new QGraphicsPathItem(path3, item2);
       
  2537     QGraphicsItem *item4 = new QGraphicsPathItem(path4, item3);
       
  2538 
       
  2539     item1->setPos(10, 10);
       
  2540     item2->setPos(10, 10);
       
  2541     item3->setPos(10, 10);
       
  2542     item4->setPos(10, 10);
       
  2543 
       
  2544     for (int i = 0; i < 4; ++i) {
       
  2545         QMatrix matrix;
       
  2546         matrix.rotate(i * 90);
       
  2547         matrix.translate(i * 100, -i * 100);
       
  2548         matrix.scale(2, 4);
       
  2549         item1->setMatrix(matrix);
       
  2550 
       
  2551         QCOMPARE(item1->mapToParent(QPointF(0, 0)), item1->pos() + matrix.map(QPointF(0, 0)));
       
  2552         QCOMPARE(item2->mapToParent(QPointF(0, 0)), item2->pos());
       
  2553         QCOMPARE(item3->mapToParent(QPointF(0, 0)), item3->pos());
       
  2554         QCOMPARE(item4->mapToParent(QPointF(0, 0)), item4->pos());
       
  2555         QCOMPARE(item1->mapToParent(QPointF(10, -10)), item1->pos() + matrix.map(QPointF(10, -10)));
       
  2556         QCOMPARE(item2->mapToParent(QPointF(10, -10)), item2->pos() + QPointF(10, -10));
       
  2557         QCOMPARE(item3->mapToParent(QPointF(10, -10)), item3->pos() + QPointF(10, -10));
       
  2558         QCOMPARE(item4->mapToParent(QPointF(10, -10)), item4->pos() + QPointF(10, -10));
       
  2559         QCOMPARE(item1->mapToParent(QPointF(-10, 10)), item1->pos() + matrix.map(QPointF(-10, 10)));
       
  2560         QCOMPARE(item2->mapToParent(QPointF(-10, 10)), item2->pos() + QPointF(-10, 10));
       
  2561         QCOMPARE(item3->mapToParent(QPointF(-10, 10)), item3->pos() + QPointF(-10, 10));
       
  2562         QCOMPARE(item4->mapToParent(QPointF(-10, 10)), item4->pos() + QPointF(-10, 10));
       
  2563         QCOMPARE(item1->mapFromParent(item1->pos()), matrix.inverted().map(QPointF(0, 0)));
       
  2564         QCOMPARE(item2->mapFromParent(item2->pos()), QPointF(0, 0));
       
  2565         QCOMPARE(item3->mapFromParent(item3->pos()), QPointF(0, 0));
       
  2566         QCOMPARE(item4->mapFromParent(item4->pos()), QPointF(0, 0));
       
  2567         QCOMPARE(item1->mapFromParent(item1->pos() + QPointF(10, -10)),
       
  2568                  matrix.inverted().map(QPointF(10, -10)));
       
  2569         QCOMPARE(item2->mapFromParent(item2->pos() + QPointF(10, -10)), QPointF(10, -10));
       
  2570         QCOMPARE(item3->mapFromParent(item3->pos() + QPointF(10, -10)), QPointF(10, -10));
       
  2571         QCOMPARE(item4->mapFromParent(item4->pos() + QPointF(10, -10)), QPointF(10, -10));
       
  2572         QCOMPARE(item1->mapFromParent(item1->pos() + QPointF(-10, 10)),
       
  2573                  matrix.inverted().map(QPointF(-10, 10)));
       
  2574         QCOMPARE(item2->mapFromParent(item2->pos() + QPointF(-10, 10)), QPointF(-10, 10));
       
  2575         QCOMPARE(item3->mapFromParent(item3->pos() + QPointF(-10, 10)), QPointF(-10, 10));
       
  2576         QCOMPARE(item4->mapFromParent(item4->pos() + QPointF(-10, 10)), QPointF(-10, 10));
       
  2577     }
       
  2578 
       
  2579     delete item1;
       
  2580 }
       
  2581 
       
  2582 void tst_QGraphicsItem::mapFromToScene()
       
  2583 {
       
  2584     QGraphicsItem *item1 = new QGraphicsPathItem(QPainterPath());
       
  2585     QGraphicsItem *item2 = new QGraphicsPathItem(QPainterPath(), item1);
       
  2586     QGraphicsItem *item3 = new QGraphicsPathItem(QPainterPath(), item2);
       
  2587     QGraphicsItem *item4 = new QGraphicsPathItem(QPainterPath(), item3);
       
  2588 
       
  2589     item1->setPos(100, 100);
       
  2590     item2->setPos(100, 100);
       
  2591     item3->setPos(100, 100);
       
  2592     item4->setPos(100, 100);
       
  2593     QCOMPARE(item1->pos(), QPointF(100, 100));
       
  2594     QCOMPARE(item2->pos(), QPointF(100, 100));
       
  2595     QCOMPARE(item3->pos(), QPointF(100, 100));
       
  2596     QCOMPARE(item4->pos(), QPointF(100, 100));
       
  2597     QCOMPARE(item1->pos(), item1->mapToParent(0, 0));
       
  2598     QCOMPARE(item2->pos(), item2->mapToParent(0, 0));
       
  2599     QCOMPARE(item3->pos(), item3->mapToParent(0, 0));
       
  2600     QCOMPARE(item4->pos(), item4->mapToParent(0, 0));
       
  2601     QCOMPARE(item1->mapToParent(10, 10), QPointF(110, 110));
       
  2602     QCOMPARE(item2->mapToParent(10, 10), QPointF(110, 110));
       
  2603     QCOMPARE(item3->mapToParent(10, 10), QPointF(110, 110));
       
  2604     QCOMPARE(item4->mapToParent(10, 10), QPointF(110, 110));
       
  2605     QCOMPARE(item1->mapToScene(0, 0), QPointF(100, 100));
       
  2606     QCOMPARE(item2->mapToScene(0, 0), QPointF(200, 200));
       
  2607     QCOMPARE(item3->mapToScene(0, 0), QPointF(300, 300));
       
  2608     QCOMPARE(item4->mapToScene(0, 0), QPointF(400, 400));
       
  2609     QCOMPARE(item1->mapToScene(10, 0), QPointF(110, 100));
       
  2610     QCOMPARE(item2->mapToScene(10, 0), QPointF(210, 200));
       
  2611     QCOMPARE(item3->mapToScene(10, 0), QPointF(310, 300));
       
  2612     QCOMPARE(item4->mapToScene(10, 0), QPointF(410, 400));
       
  2613     QCOMPARE(item1->mapFromScene(100, 100), QPointF(0, 0));
       
  2614     QCOMPARE(item2->mapFromScene(200, 200), QPointF(0, 0));
       
  2615     QCOMPARE(item3->mapFromScene(300, 300), QPointF(0, 0));
       
  2616     QCOMPARE(item4->mapFromScene(400, 400), QPointF(0, 0));
       
  2617     QCOMPARE(item1->mapFromScene(110, 100), QPointF(10, 0));
       
  2618     QCOMPARE(item2->mapFromScene(210, 200), QPointF(10, 0));
       
  2619     QCOMPARE(item3->mapFromScene(310, 300), QPointF(10, 0));
       
  2620     QCOMPARE(item4->mapFromScene(410, 400), QPointF(10, 0));
       
  2621 
       
  2622     // Rotate item1 90 degrees clockwise
       
  2623     QMatrix matrix; matrix.rotate(90);
       
  2624     item1->setMatrix(matrix);
       
  2625     QCOMPARE(item1->pos(), item1->mapToParent(0, 0));
       
  2626     QCOMPARE(item2->pos(), item2->mapToParent(0, 0));
       
  2627     QCOMPARE(item3->pos(), item3->mapToParent(0, 0));
       
  2628     QCOMPARE(item4->pos(), item4->mapToParent(0, 0));
       
  2629     QCOMPARE(item1->mapToParent(10, 0), QPointF(100, 110));
       
  2630     QCOMPARE(item2->mapToParent(10, 0), QPointF(110, 100));
       
  2631     QCOMPARE(item3->mapToParent(10, 0), QPointF(110, 100));
       
  2632     QCOMPARE(item4->mapToParent(10, 0), QPointF(110, 100));
       
  2633     QCOMPARE(item1->mapToScene(0, 0), QPointF(100, 100));
       
  2634     QCOMPARE(item2->mapToScene(0, 0), QPointF(0, 200));
       
  2635     QCOMPARE(item3->mapToScene(0, 0), QPointF(-100, 300));
       
  2636     QCOMPARE(item4->mapToScene(0, 0), QPointF(-200, 400));
       
  2637     QCOMPARE(item1->mapToScene(10, 0), QPointF(100, 110));
       
  2638     QCOMPARE(item2->mapToScene(10, 0), QPointF(0, 210));
       
  2639     QCOMPARE(item3->mapToScene(10, 0), QPointF(-100, 310));
       
  2640     QCOMPARE(item4->mapToScene(10, 0), QPointF(-200, 410));
       
  2641     QCOMPARE(item1->mapFromScene(100, 100), QPointF(0, 0));
       
  2642     QCOMPARE(item2->mapFromScene(0, 200), QPointF(0, 0));
       
  2643     QCOMPARE(item3->mapFromScene(-100, 300), QPointF(0, 0));
       
  2644     QCOMPARE(item4->mapFromScene(-200, 400), QPointF(0, 0));
       
  2645     QCOMPARE(item1->mapFromScene(100, 110), QPointF(10, 0));
       
  2646     QCOMPARE(item2->mapFromScene(0, 210), QPointF(10, 0));
       
  2647     QCOMPARE(item3->mapFromScene(-100, 310), QPointF(10, 0));
       
  2648     QCOMPARE(item4->mapFromScene(-200, 410), QPointF(10, 0));
       
  2649 
       
  2650     // Rotate item2 90 degrees clockwise
       
  2651     item2->setMatrix(matrix);
       
  2652     QCOMPARE(item1->pos(), item1->mapToParent(0, 0));
       
  2653     QCOMPARE(item2->pos(), item2->mapToParent(0, 0));
       
  2654     QCOMPARE(item3->pos(), item3->mapToParent(0, 0));
       
  2655     QCOMPARE(item4->pos(), item4->mapToParent(0, 0));
       
  2656     QCOMPARE(item1->mapToParent(10, 0), QPointF(100, 110));
       
  2657     QCOMPARE(item2->mapToParent(10, 0), QPointF(100, 110));
       
  2658     QCOMPARE(item3->mapToParent(10, 0), QPointF(110, 100));
       
  2659     QCOMPARE(item4->mapToParent(10, 0), QPointF(110, 100));
       
  2660     QCOMPARE(item1->mapToScene(0, 0), QPointF(100, 100));
       
  2661     QCOMPARE(item2->mapToScene(0, 0), QPointF(0, 200));
       
  2662     QCOMPARE(item3->mapToScene(0, 0), QPointF(-100, 100));
       
  2663     QCOMPARE(item4->mapToScene(0, 0), QPointF(-200, 0));
       
  2664     QCOMPARE(item1->mapToScene(10, 0), QPointF(100, 110));
       
  2665     QCOMPARE(item2->mapToScene(10, 0), QPointF(-10, 200));
       
  2666     QCOMPARE(item3->mapToScene(10, 0), QPointF(-110, 100));
       
  2667     QCOMPARE(item4->mapToScene(10, 0), QPointF(-210, 0));
       
  2668     QCOMPARE(item1->mapFromScene(100, 100), QPointF(0, 0));
       
  2669     QCOMPARE(item2->mapFromScene(0, 200), QPointF(0, 0));
       
  2670     QCOMPARE(item3->mapFromScene(-100, 100), QPointF(0, 0));
       
  2671     QCOMPARE(item4->mapFromScene(-200, 0), QPointF(0, 0));
       
  2672     QCOMPARE(item1->mapFromScene(100, 110), QPointF(10, 0));
       
  2673     QCOMPARE(item2->mapFromScene(-10, 200), QPointF(10, 0));
       
  2674     QCOMPARE(item3->mapFromScene(-110, 100), QPointF(10, 0));
       
  2675     QCOMPARE(item4->mapFromScene(-210, 0), QPointF(10, 0));
       
  2676 
       
  2677     // Translate item3 50 points, then rotate 90 degrees counterclockwise
       
  2678     QMatrix matrix2;
       
  2679     matrix2.translate(50, 0);
       
  2680     matrix2.rotate(-90);
       
  2681     item3->setMatrix(matrix2);
       
  2682     QCOMPARE(item1->pos(), item1->mapToParent(0, 0));
       
  2683     QCOMPARE(item2->pos(), item2->mapToParent(0, 0));
       
  2684     QCOMPARE(item3->pos(), item3->mapToParent(0, 0) - QPointF(50, 0));
       
  2685     QCOMPARE(item4->pos(), item4->mapToParent(0, 0));
       
  2686     QCOMPARE(item1->mapToParent(10, 0), QPointF(100, 110));
       
  2687     QCOMPARE(item2->mapToParent(10, 0), QPointF(100, 110));
       
  2688     QCOMPARE(item3->mapToParent(10, 0), QPointF(150, 90));
       
  2689     QCOMPARE(item4->mapToParent(10, 0), QPointF(110, 100));
       
  2690     QCOMPARE(item1->mapToScene(0, 0), QPointF(100, 100));
       
  2691     QCOMPARE(item2->mapToScene(0, 0), QPointF(0, 200));
       
  2692     QCOMPARE(item3->mapToScene(0, 0), QPointF(-150, 100));
       
  2693     QCOMPARE(item4->mapToScene(0, 0), QPointF(-250, 200));
       
  2694     QCOMPARE(item1->mapToScene(10, 0), QPointF(100, 110));
       
  2695     QCOMPARE(item2->mapToScene(10, 0), QPointF(-10, 200));
       
  2696     QCOMPARE(item3->mapToScene(10, 0), QPointF(-150, 110));
       
  2697     QCOMPARE(item4->mapToScene(10, 0), QPointF(-250, 210));
       
  2698     QCOMPARE(item1->mapFromScene(100, 100), QPointF(0, 0));
       
  2699     QCOMPARE(item2->mapFromScene(0, 200), QPointF(0, 0));
       
  2700     QCOMPARE(item3->mapFromScene(-150, 100), QPointF(0, 0));
       
  2701     QCOMPARE(item4->mapFromScene(-250, 200), QPointF(0, 0));
       
  2702     QCOMPARE(item1->mapFromScene(100, 110), QPointF(10, 0));
       
  2703     QCOMPARE(item2->mapFromScene(-10, 200), QPointF(10, 0));
       
  2704     QCOMPARE(item3->mapFromScene(-150, 110), QPointF(10, 0));
       
  2705     QCOMPARE(item4->mapFromScene(-250, 210), QPointF(10, 0));
       
  2706 
       
  2707     delete item1;
       
  2708 }
       
  2709 
       
  2710 void tst_QGraphicsItem::mapFromToItem()
       
  2711 {
       
  2712     QGraphicsItem *item1 = new QGraphicsPathItem;
       
  2713     QGraphicsItem *item2 = new QGraphicsPathItem;
       
  2714     QGraphicsItem *item3 = new QGraphicsPathItem;
       
  2715     QGraphicsItem *item4 = new QGraphicsPathItem;
       
  2716 
       
  2717     item1->setPos(-100, -100);
       
  2718     item2->setPos(100, -100);
       
  2719     item3->setPos(100, 100);
       
  2720     item4->setPos(-100, 100);
       
  2721 
       
  2722     QCOMPARE(item1->mapFromItem(item2, 0, 0), QPointF(200, 0));
       
  2723     QCOMPARE(item2->mapFromItem(item3, 0, 0), QPointF(0, 200));
       
  2724     QCOMPARE(item3->mapFromItem(item4, 0, 0), QPointF(-200, 0));
       
  2725     QCOMPARE(item4->mapFromItem(item1, 0, 0), QPointF(0, -200));
       
  2726     QCOMPARE(item1->mapFromItem(item4, 0, 0), QPointF(0, 200));
       
  2727     QCOMPARE(item2->mapFromItem(item1, 0, 0), QPointF(-200, 0));
       
  2728     QCOMPARE(item3->mapFromItem(item2, 0, 0), QPointF(0, -200));
       
  2729     QCOMPARE(item4->mapFromItem(item3, 0, 0), QPointF(200, 0));
       
  2730 
       
  2731     QMatrix matrix;
       
  2732     matrix.translate(100, 100);
       
  2733     item1->setMatrix(matrix);
       
  2734 
       
  2735     QCOMPARE(item1->mapFromItem(item2, 0, 0), QPointF(100, -100));
       
  2736     QCOMPARE(item2->mapFromItem(item3, 0, 0), QPointF(0, 200));
       
  2737     QCOMPARE(item3->mapFromItem(item4, 0, 0), QPointF(-200, 0));
       
  2738     QCOMPARE(item4->mapFromItem(item1, 0, 0), QPointF(100, -100));
       
  2739     QCOMPARE(item1->mapFromItem(item4, 0, 0), QPointF(-100, 100));
       
  2740     QCOMPARE(item2->mapFromItem(item1, 0, 0), QPointF(-100, 100));
       
  2741     QCOMPARE(item3->mapFromItem(item2, 0, 0), QPointF(0, -200));
       
  2742     QCOMPARE(item4->mapFromItem(item3, 0, 0), QPointF(200, 0));
       
  2743 
       
  2744     matrix.rotate(90);
       
  2745     item1->setMatrix(matrix);
       
  2746     item2->setMatrix(matrix);
       
  2747     item3->setMatrix(matrix);
       
  2748     item4->setMatrix(matrix);
       
  2749 
       
  2750     QCOMPARE(item1->mapFromItem(item2, 0, 0), QPointF(0, -200));
       
  2751     QCOMPARE(item2->mapFromItem(item3, 0, 0), QPointF(200, 0));
       
  2752     QCOMPARE(item3->mapFromItem(item4, 0, 0), QPointF(0, 200));
       
  2753     QCOMPARE(item4->mapFromItem(item1, 0, 0), QPointF(-200, 0));
       
  2754     QCOMPARE(item1->mapFromItem(item4, 0, 0), QPointF(200, 0));
       
  2755     QCOMPARE(item2->mapFromItem(item1, 0, 0), QPointF(0, 200));
       
  2756     QCOMPARE(item3->mapFromItem(item2, 0, 0), QPointF(-200, 0));
       
  2757     QCOMPARE(item4->mapFromItem(item3, 0, 0), QPointF(0, -200));
       
  2758     QCOMPARE(item1->mapFromItem(item2, 10, -5), QPointF(10, -205));
       
  2759     QCOMPARE(item2->mapFromItem(item3, 10, -5), QPointF(210, -5));
       
  2760     QCOMPARE(item3->mapFromItem(item4, 10, -5), QPointF(10, 195));
       
  2761     QCOMPARE(item4->mapFromItem(item1, 10, -5), QPointF(-190, -5));
       
  2762     QCOMPARE(item1->mapFromItem(item4, 10, -5), QPointF(210, -5));
       
  2763     QCOMPARE(item2->mapFromItem(item1, 10, -5), QPointF(10, 195));
       
  2764     QCOMPARE(item3->mapFromItem(item2, 10, -5), QPointF(-190, -5));
       
  2765     QCOMPARE(item4->mapFromItem(item3, 10, -5), QPointF(10, -205));
       
  2766 
       
  2767     QCOMPARE(item1->mapFromItem(0, 10, -5), item1->mapFromScene(10, -5));
       
  2768     QCOMPARE(item2->mapFromItem(0, 10, -5), item2->mapFromScene(10, -5));
       
  2769     QCOMPARE(item3->mapFromItem(0, 10, -5), item3->mapFromScene(10, -5));
       
  2770     QCOMPARE(item4->mapFromItem(0, 10, -5), item4->mapFromScene(10, -5));
       
  2771     QCOMPARE(item1->mapToItem(0, 10, -5), item1->mapToScene(10, -5));
       
  2772     QCOMPARE(item2->mapToItem(0, 10, -5), item2->mapToScene(10, -5));
       
  2773     QCOMPARE(item3->mapToItem(0, 10, -5), item3->mapToScene(10, -5));
       
  2774     QCOMPARE(item4->mapToItem(0, 10, -5), item4->mapToScene(10, -5));
       
  2775 
       
  2776     delete item1;
       
  2777     delete item2;
       
  2778     delete item3;
       
  2779     delete item4;
       
  2780 }
       
  2781 
       
  2782 void tst_QGraphicsItem::mapRectFromToParent_data()
       
  2783 {
       
  2784     QTest::addColumn<bool>("parent");
       
  2785     QTest::addColumn<QPointF>("parentPos");
       
  2786     QTest::addColumn<QTransform>("parentTransform");
       
  2787     QTest::addColumn<QPointF>("pos");
       
  2788     QTest::addColumn<QTransform>("transform");
       
  2789     QTest::addColumn<QRectF>("inputRect");
       
  2790     QTest::addColumn<QRectF>("outputRect");
       
  2791 
       
  2792     QTest::newRow("nil") << false << QPointF() << QTransform() << QPointF() << QTransform() << QRectF() << QRectF();
       
  2793     QTest::newRow("simple") << false << QPointF() << QTransform() << QPointF() << QTransform()
       
  2794                             << QRectF(0, 0, 10, 10) << QRectF(0, 0, 10, 10);
       
  2795     QTest::newRow("simple w/parent") << true
       
  2796                                      << QPointF() << QTransform()
       
  2797                                      << QPointF() << QTransform()
       
  2798                                      << QRectF(0, 0, 10, 10) << QRectF(0, 0, 10, 10);
       
  2799     QTest::newRow("simple w/parent parentPos") << true
       
  2800                                                << QPointF(50, 50) << QTransform()
       
  2801                                                << QPointF() << QTransform()
       
  2802                                                << QRectF(0, 0, 10, 10) << QRectF(0, 0, 10, 10);
       
  2803     QTest::newRow("simple w/parent parentPos parentRotation") << true
       
  2804                                                               << QPointF(50, 50) << QTransform().rotate(45)
       
  2805                                                               << QPointF() << QTransform()
       
  2806                                                               << QRectF(0, 0, 10, 10) << QRectF(0, 0, 10, 10);
       
  2807     QTest::newRow("pos w/parent") << true
       
  2808                                   << QPointF() << QTransform()
       
  2809                                   << QPointF(50, 50) << QTransform()
       
  2810                                   << QRectF(0, 0, 10, 10) << QRectF(50, 50, 10, 10);
       
  2811     QTest::newRow("rotation w/parent") << true
       
  2812                                        << QPointF() << QTransform()
       
  2813                                        << QPointF() << QTransform().rotate(90)
       
  2814                                        << QRectF(0, 0, 10, 10) << QRectF(-10, 0, 10, 10);
       
  2815     QTest::newRow("pos rotation w/parent") << true
       
  2816                                            << QPointF() << QTransform()
       
  2817                                            << QPointF(50, 50) << QTransform().rotate(90)
       
  2818                                            << QRectF(0, 0, 10, 10) << QRectF(40, 50, 10, 10);
       
  2819     QTest::newRow("pos rotation w/parent parentPos parentRotation") << true
       
  2820                                                                     << QPointF(-170, -190) << QTransform().rotate(90)
       
  2821                                                                     << QPointF(50, 50) << QTransform().rotate(90)
       
  2822                                                                     << QRectF(0, 0, 10, 10) << QRectF(40, 50, 10, 10);
       
  2823 }
       
  2824 
       
  2825 void tst_QGraphicsItem::mapRectFromToParent()
       
  2826 {
       
  2827     QFETCH(bool, parent);
       
  2828     QFETCH(QPointF, parentPos);
       
  2829     QFETCH(QTransform, parentTransform);
       
  2830     QFETCH(QPointF, pos);
       
  2831     QFETCH(QTransform, transform);
       
  2832     QFETCH(QRectF, inputRect);
       
  2833     QFETCH(QRectF, outputRect);
       
  2834 
       
  2835     QGraphicsRectItem *rect = new QGraphicsRectItem;
       
  2836     rect->setPos(pos);
       
  2837     rect->setTransform(transform);
       
  2838 
       
  2839     if (parent) {
       
  2840         QGraphicsRectItem *rectParent = new QGraphicsRectItem;
       
  2841         rect->setParentItem(rectParent);
       
  2842         rectParent->setPos(parentPos);
       
  2843         rectParent->setTransform(parentTransform);
       
  2844     }
       
  2845 
       
  2846     // Make sure we use non-destructive transform operations (e.g., 90 degree
       
  2847     // rotations).
       
  2848     QCOMPARE(rect->mapRectToParent(inputRect), outputRect);
       
  2849     QCOMPARE(rect->mapRectFromParent(outputRect), inputRect);
       
  2850     QCOMPARE(rect->itemTransform(rect->parentItem()).mapRect(inputRect), outputRect);
       
  2851     QCOMPARE(rect->mapToParent(inputRect).boundingRect(), outputRect);
       
  2852     QCOMPARE(rect->mapToParent(QPolygonF(inputRect)).boundingRect(), outputRect);
       
  2853     QCOMPARE(rect->mapFromParent(outputRect).boundingRect(), inputRect);
       
  2854     QCOMPARE(rect->mapFromParent(QPolygonF(outputRect)).boundingRect(), inputRect);
       
  2855     QPainterPath inputPath;
       
  2856     inputPath.addRect(inputRect);
       
  2857     QPainterPath outputPath;
       
  2858     outputPath.addRect(outputRect);
       
  2859     QCOMPARE(rect->mapToParent(inputPath).boundingRect(), outputPath.boundingRect());
       
  2860     QCOMPARE(rect->mapFromParent(outputPath).boundingRect(), inputPath.boundingRect());
       
  2861 }
       
  2862 
       
  2863 void tst_QGraphicsItem::isAncestorOf()
       
  2864 {
       
  2865     QGraphicsItem *grandPa = new QGraphicsRectItem;
       
  2866     QGraphicsItem *parent = new QGraphicsRectItem;
       
  2867     QGraphicsItem *child = new QGraphicsRectItem;
       
  2868 
       
  2869     QVERIFY(!parent->isAncestorOf(0));
       
  2870     QVERIFY(!child->isAncestorOf(0));
       
  2871     QVERIFY(!parent->isAncestorOf(child));
       
  2872     QVERIFY(!child->isAncestorOf(parent));
       
  2873     QVERIFY(!parent->isAncestorOf(parent));
       
  2874 
       
  2875     child->setParentItem(parent);
       
  2876     parent->setParentItem(grandPa);
       
  2877 
       
  2878     QVERIFY(parent->isAncestorOf(child));
       
  2879     QVERIFY(grandPa->isAncestorOf(parent));
       
  2880     QVERIFY(grandPa->isAncestorOf(child));
       
  2881     QVERIFY(!child->isAncestorOf(parent));
       
  2882     QVERIFY(!parent->isAncestorOf(grandPa));
       
  2883     QVERIFY(!child->isAncestorOf(grandPa));
       
  2884     QVERIFY(!child->isAncestorOf(child));
       
  2885     QVERIFY(!parent->isAncestorOf(parent));
       
  2886     QVERIFY(!grandPa->isAncestorOf(grandPa));
       
  2887 
       
  2888     parent->setParentItem(0);
       
  2889 
       
  2890     delete child;
       
  2891     delete parent;
       
  2892     delete grandPa;
       
  2893 }
       
  2894 
       
  2895 void tst_QGraphicsItem::commonAncestorItem()
       
  2896 {
       
  2897     QGraphicsItem *ancestor = new QGraphicsRectItem;
       
  2898     QGraphicsItem *grandMa = new QGraphicsRectItem;
       
  2899     QGraphicsItem *grandPa = new QGraphicsRectItem;
       
  2900     QGraphicsItem *brotherInLaw = new QGraphicsRectItem;
       
  2901     QGraphicsItem *cousin = new QGraphicsRectItem;
       
  2902     QGraphicsItem *husband = new QGraphicsRectItem;
       
  2903     QGraphicsItem *child = new QGraphicsRectItem;
       
  2904     QGraphicsItem *wife = new QGraphicsRectItem;
       
  2905 
       
  2906     child->setParentItem(husband);
       
  2907     husband->setParentItem(grandPa);
       
  2908     brotherInLaw->setParentItem(grandPa);
       
  2909     cousin->setParentItem(brotherInLaw);
       
  2910     wife->setParentItem(grandMa);
       
  2911     grandMa->setParentItem(ancestor);
       
  2912     grandPa->setParentItem(ancestor);
       
  2913 
       
  2914     QCOMPARE(grandMa->commonAncestorItem(grandMa), grandMa);
       
  2915     QCOMPARE(grandMa->commonAncestorItem(0), (QGraphicsItem *)0);
       
  2916     QCOMPARE(grandMa->commonAncestorItem(grandPa), ancestor);
       
  2917     QCOMPARE(grandPa->commonAncestorItem(grandMa), ancestor);
       
  2918     QCOMPARE(grandPa->commonAncestorItem(husband), grandPa);
       
  2919     QCOMPARE(grandPa->commonAncestorItem(wife), ancestor);
       
  2920     QCOMPARE(grandMa->commonAncestorItem(husband), ancestor);
       
  2921     QCOMPARE(grandMa->commonAncestorItem(wife), grandMa);
       
  2922     QCOMPARE(wife->commonAncestorItem(grandMa), grandMa);
       
  2923     QCOMPARE(child->commonAncestorItem(cousin), grandPa);
       
  2924     QCOMPARE(cousin->commonAncestorItem(child), grandPa);
       
  2925     QCOMPARE(wife->commonAncestorItem(child), ancestor);
       
  2926     QCOMPARE(child->commonAncestorItem(wife), ancestor);
       
  2927 }
       
  2928 
       
  2929 void tst_QGraphicsItem::data()
       
  2930 {
       
  2931     QGraphicsTextItem text;
       
  2932 
       
  2933     QCOMPARE(text.data(0), QVariant());
       
  2934     text.setData(0, "TextItem");
       
  2935     QCOMPARE(text.data(0), QVariant(QString("TextItem")));
       
  2936     text.setData(0, QVariant());
       
  2937     QCOMPARE(text.data(0), QVariant());
       
  2938 }
       
  2939 
       
  2940 void tst_QGraphicsItem::type()
       
  2941 {
       
  2942     QCOMPARE(int(QGraphicsItem::Type), 1);
       
  2943     QCOMPARE(int(QGraphicsPathItem::Type), 2);
       
  2944     QCOMPARE(int(QGraphicsRectItem::Type), 3);
       
  2945     QCOMPARE(int(QGraphicsEllipseItem::Type), 4);
       
  2946     QCOMPARE(int(QGraphicsPolygonItem::Type), 5);
       
  2947     QCOMPARE(int(QGraphicsLineItem::Type), 6);
       
  2948     QCOMPARE(int(QGraphicsPixmapItem::Type), 7);
       
  2949     QCOMPARE(int(QGraphicsTextItem::Type), 8);
       
  2950 
       
  2951     QCOMPARE(QGraphicsPathItem().type(), 2);
       
  2952     QCOMPARE(QGraphicsRectItem().type(), 3);
       
  2953     QCOMPARE(QGraphicsEllipseItem().type(), 4);
       
  2954     QCOMPARE(QGraphicsPolygonItem().type(), 5);
       
  2955     QCOMPARE(QGraphicsLineItem().type(), 6);
       
  2956     QCOMPARE(QGraphicsPixmapItem().type(), 7);
       
  2957     QCOMPARE(QGraphicsTextItem().type(), 8);
       
  2958 }
       
  2959 
       
  2960 void tst_QGraphicsItem::graphicsitem_cast()
       
  2961 {
       
  2962     QGraphicsPathItem pathItem;
       
  2963     const QGraphicsPathItem *pPathItem = &pathItem;
       
  2964     QGraphicsRectItem rectItem;
       
  2965     const QGraphicsRectItem *pRectItem = &rectItem;
       
  2966     QGraphicsEllipseItem ellipseItem;
       
  2967     const QGraphicsEllipseItem *pEllipseItem = &ellipseItem;
       
  2968     QGraphicsPolygonItem polygonItem;
       
  2969     const QGraphicsPolygonItem *pPolygonItem = &polygonItem;
       
  2970     QGraphicsLineItem lineItem;
       
  2971     const QGraphicsLineItem *pLineItem = &lineItem;
       
  2972     QGraphicsPixmapItem pixmapItem;
       
  2973     const QGraphicsPixmapItem *pPixmapItem = &pixmapItem;
       
  2974     QGraphicsTextItem textItem;
       
  2975     const QGraphicsTextItem *pTextItem = &textItem;
       
  2976 
       
  2977     QVERIFY(qgraphicsitem_cast<QGraphicsPathItem *>(&pathItem));
       
  2978     //QVERIFY(qgraphicsitem_cast<QAbstractGraphicsPathItem *>(&pathItem));
       
  2979     QVERIFY(qgraphicsitem_cast<QGraphicsItem *>(&pathItem));
       
  2980     QVERIFY(qgraphicsitem_cast<const QGraphicsItem *>(pPathItem));
       
  2981     QVERIFY(qgraphicsitem_cast<const QGraphicsPathItem *>(pPathItem));
       
  2982 
       
  2983     QVERIFY(qgraphicsitem_cast<QGraphicsRectItem *>(&rectItem));
       
  2984     QVERIFY(qgraphicsitem_cast<QGraphicsItem *>(&rectItem));
       
  2985     QVERIFY(qgraphicsitem_cast<const QGraphicsItem *>(pRectItem));
       
  2986     QVERIFY(qgraphicsitem_cast<const QGraphicsRectItem *>(pRectItem));
       
  2987 
       
  2988     QVERIFY(qgraphicsitem_cast<QGraphicsEllipseItem *>(&ellipseItem));
       
  2989     QVERIFY(qgraphicsitem_cast<QGraphicsItem *>(&ellipseItem));
       
  2990     QVERIFY(qgraphicsitem_cast<const QGraphicsItem *>(pEllipseItem));
       
  2991     QVERIFY(qgraphicsitem_cast<const QGraphicsEllipseItem *>(pEllipseItem));
       
  2992 
       
  2993     QVERIFY(qgraphicsitem_cast<QGraphicsPolygonItem *>(&polygonItem));
       
  2994     //QVERIFY(qgraphicsitem_cast<QAbstractGraphicsPathItem *>(&polygonItem));
       
  2995     QVERIFY(qgraphicsitem_cast<QGraphicsItem *>(&polygonItem));
       
  2996     QVERIFY(qgraphicsitem_cast<const QGraphicsItem *>(pPolygonItem));
       
  2997     QVERIFY(qgraphicsitem_cast<const QGraphicsPolygonItem *>(pPolygonItem));
       
  2998 
       
  2999     QVERIFY(qgraphicsitem_cast<QGraphicsLineItem *>(&lineItem));
       
  3000     QVERIFY(qgraphicsitem_cast<QGraphicsItem *>(&lineItem));
       
  3001     QVERIFY(qgraphicsitem_cast<const QGraphicsItem *>(pLineItem));
       
  3002     QVERIFY(qgraphicsitem_cast<const QGraphicsLineItem *>(pLineItem));
       
  3003 
       
  3004     QVERIFY(qgraphicsitem_cast<QGraphicsPixmapItem *>(&pixmapItem));
       
  3005     QVERIFY(qgraphicsitem_cast<QGraphicsItem *>(&pixmapItem));
       
  3006     QVERIFY(qgraphicsitem_cast<const QGraphicsItem *>(pPixmapItem));
       
  3007     QVERIFY(qgraphicsitem_cast<const QGraphicsPixmapItem *>(pPixmapItem));
       
  3008 
       
  3009     QVERIFY(qgraphicsitem_cast<QGraphicsTextItem *>(&textItem));
       
  3010     QVERIFY(qgraphicsitem_cast<QGraphicsItem *>(&textItem));
       
  3011     QVERIFY(qgraphicsitem_cast<const QGraphicsItem *>(pTextItem));
       
  3012     QVERIFY(qgraphicsitem_cast<const QGraphicsTextItem *>(pTextItem));
       
  3013 
       
  3014     // and some casts that _should_ fail:
       
  3015     QVERIFY(!qgraphicsitem_cast<QGraphicsEllipseItem *>(&pathItem));
       
  3016     QVERIFY(!qgraphicsitem_cast<const QGraphicsTextItem *>(pPolygonItem));
       
  3017 
       
  3018     // and this shouldn't crash
       
  3019     QGraphicsItem *ptr = 0;
       
  3020     QVERIFY(!qgraphicsitem_cast<QGraphicsTextItem *>(ptr));
       
  3021     QVERIFY(!qgraphicsitem_cast<QGraphicsItem *>(ptr));
       
  3022 }
       
  3023 
       
  3024 void tst_QGraphicsItem::hoverEventsGenerateRepaints()
       
  3025 {
       
  3026     Q_CHECK_PAINTEVENTS
       
  3027 
       
  3028     QGraphicsScene scene;
       
  3029     QGraphicsView view(&scene);
       
  3030     view.show();
       
  3031     QTest::qWaitForWindowShown(&view);
       
  3032     QTest::qWait(150);
       
  3033 
       
  3034     EventTester *tester = new EventTester;
       
  3035     scene.addItem(tester);
       
  3036     tester->setAcceptsHoverEvents(true);
       
  3037 
       
  3038     QTRY_COMPARE(tester->repaints, 1);
       
  3039 
       
  3040     // Send a hover enter event
       
  3041     QGraphicsSceneHoverEvent hoverEnterEvent(QEvent::GraphicsSceneHoverEnter);
       
  3042     hoverEnterEvent.setScenePos(QPointF(0, 0));
       
  3043     hoverEnterEvent.setPos(QPointF(0, 0));
       
  3044     QApplication::sendEvent(&scene, &hoverEnterEvent);
       
  3045 
       
  3046     // Check that we get a repaint
       
  3047     int npaints = tester->repaints;
       
  3048     qApp->processEvents();
       
  3049     qApp->processEvents();
       
  3050     QCOMPARE(tester->events.size(), 2); //  enter + move
       
  3051     QCOMPARE(tester->repaints, npaints + 1);
       
  3052     QCOMPARE(tester->events.last(), QEvent::GraphicsSceneHoverMove);
       
  3053 
       
  3054     // Send a hover move event
       
  3055     QGraphicsSceneHoverEvent hoverMoveEvent(QEvent::GraphicsSceneHoverMove);
       
  3056     hoverMoveEvent.setScenePos(QPointF(0, 0));
       
  3057     hoverMoveEvent.setPos(QPointF(0, 0));
       
  3058     QApplication::sendEvent(&scene, &hoverMoveEvent);
       
  3059 
       
  3060     // Check that we don't get a repaint
       
  3061     qApp->processEvents();
       
  3062     qApp->processEvents();
       
  3063 
       
  3064     QCOMPARE(tester->events.size(), 3);
       
  3065     QCOMPARE(tester->repaints, npaints + 1);
       
  3066     QCOMPARE(tester->events.last(), QEvent::GraphicsSceneHoverMove);
       
  3067 
       
  3068     // Send a hover leave event
       
  3069     QGraphicsSceneHoverEvent hoverLeaveEvent(QEvent::GraphicsSceneHoverLeave);
       
  3070     hoverLeaveEvent.setScenePos(QPointF(-100, -100));
       
  3071     hoverLeaveEvent.setPos(QPointF(0, 0));
       
  3072     QApplication::sendEvent(&scene, &hoverLeaveEvent);
       
  3073 
       
  3074     // Check that we get a repaint
       
  3075     qApp->processEvents();
       
  3076     qApp->processEvents();
       
  3077 
       
  3078     QCOMPARE(tester->events.size(), 4);
       
  3079     QCOMPARE(tester->repaints, npaints + 2);
       
  3080     QCOMPARE(tester->events.last(), QEvent::GraphicsSceneHoverLeave);
       
  3081 }
       
  3082 
       
  3083 void tst_QGraphicsItem::boundingRects_data()
       
  3084 {
       
  3085     QTest::addColumn<QGraphicsItem *>("item");
       
  3086     QTest::addColumn<QRectF>("boundingRect");
       
  3087 
       
  3088     QRectF rect(0, 0, 100, 100);
       
  3089     QPainterPath path;
       
  3090     path.addRect(rect);
       
  3091 
       
  3092     QRectF adjustedRect(-0.5, -0.5, 101, 101);
       
  3093 
       
  3094     QTest::newRow("path") << (QGraphicsItem *)new QGraphicsPathItem(path) << adjustedRect;
       
  3095     QTest::newRow("rect") << (QGraphicsItem *)new QGraphicsRectItem(rect) << adjustedRect;
       
  3096     QTest::newRow("ellipse") << (QGraphicsItem *)new QGraphicsEllipseItem(rect) << adjustedRect;
       
  3097     QTest::newRow("polygon") << (QGraphicsItem *)new QGraphicsPolygonItem(rect) << adjustedRect;
       
  3098 }
       
  3099 
       
  3100 void tst_QGraphicsItem::boundingRects()
       
  3101 {
       
  3102     QFETCH(QGraphicsItem *, item);
       
  3103     QFETCH(QRectF, boundingRect);
       
  3104 
       
  3105     ((QAbstractGraphicsShapeItem *)item)->setPen(QPen(Qt::black, 1));
       
  3106     QCOMPARE(item->boundingRect(), boundingRect);
       
  3107 }
       
  3108 
       
  3109 void tst_QGraphicsItem::boundingRects2()
       
  3110 {
       
  3111     QGraphicsPixmapItem pixmap(QPixmap::fromImage(QImage(100, 100, QImage::Format_ARGB32_Premultiplied)));
       
  3112     QCOMPARE(pixmap.boundingRect(), QRectF(-0.5, -0.5, 101, 101));
       
  3113 
       
  3114     QGraphicsLineItem line(0, 0, 100, 0);
       
  3115     line.setPen(QPen(Qt::black, 1));
       
  3116     QCOMPARE(line.boundingRect(), QRectF(-0.5, -0.5, 101, 1));
       
  3117 }
       
  3118 
       
  3119 void tst_QGraphicsItem::sceneBoundingRect()
       
  3120 {
       
  3121     QGraphicsScene scene;
       
  3122     QGraphicsRectItem *item = scene.addRect(QRectF(0, 0, 100, 100), QPen(Qt::black, 0));
       
  3123     item->setPos(100, 100);
       
  3124 
       
  3125     QCOMPARE(item->boundingRect(), QRectF(0, 0, 100, 100));
       
  3126     QCOMPARE(item->sceneBoundingRect(), QRectF(100, 100, 100, 100));
       
  3127 
       
  3128     item->rotate(90);
       
  3129 
       
  3130     QCOMPARE(item->boundingRect(), QRectF(0, 0, 100, 100));
       
  3131     QCOMPARE(item->sceneBoundingRect(), QRectF(0, 100, 100, 100));
       
  3132 }
       
  3133 
       
  3134 void tst_QGraphicsItem::childrenBoundingRect()
       
  3135 {
       
  3136     QGraphicsScene scene;
       
  3137     QGraphicsRectItem *parent = scene.addRect(QRectF(0, 0, 100, 100), QPen(Qt::black, 0));
       
  3138     QGraphicsRectItem *child = scene.addRect(QRectF(0, 0, 100, 100), QPen(Qt::black, 0));
       
  3139     child->setParentItem(parent);
       
  3140     parent->setPos(100, 100);
       
  3141     child->setPos(100, 100);
       
  3142 
       
  3143     QCOMPARE(parent->boundingRect(), QRectF(0, 0, 100, 100));
       
  3144     QCOMPARE(child->boundingRect(), QRectF(0, 0, 100, 100));
       
  3145     QCOMPARE(child->childrenBoundingRect(), QRectF());
       
  3146     QCOMPARE(parent->childrenBoundingRect(), QRectF(100, 100, 100, 100));
       
  3147 
       
  3148     QGraphicsRectItem *child2 = scene.addRect(QRectF(0, 0, 100, 100), QPen(Qt::black, 0));
       
  3149     child2->setParentItem(parent);
       
  3150     child2->setPos(-100, -100);
       
  3151     QCOMPARE(parent->childrenBoundingRect(), QRectF(-100, -100, 300, 300));
       
  3152 
       
  3153     QGraphicsRectItem *childChild = scene.addRect(QRectF(0, 0, 100, 100), QPen(Qt::black, 0));
       
  3154     childChild->setParentItem(child);
       
  3155     childChild->setPos(500, 500);
       
  3156     child->rotate(90);
       
  3157 
       
  3158 
       
  3159     scene.addPolygon(parent->mapToScene(parent->boundingRect() | parent->childrenBoundingRect()))->setPen(QPen(Qt::red));;
       
  3160 
       
  3161     QGraphicsView view(&scene);
       
  3162     view.show();
       
  3163 
       
  3164     QTest::qWaitForWindowShown(&view);
       
  3165     QTest::qWait(30);
       
  3166 
       
  3167     QCOMPARE(parent->childrenBoundingRect(), QRectF(-500, -100, 600, 800));
       
  3168 }
       
  3169 
       
  3170 void tst_QGraphicsItem::childrenBoundingRectTransformed()
       
  3171 {
       
  3172     QGraphicsScene scene;
       
  3173 
       
  3174     QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100));
       
  3175     QGraphicsRectItem *rect2 = scene.addRect(QRectF(0, 0, 100, 100));
       
  3176     QGraphicsRectItem *rect3 = scene.addRect(QRectF(0, 0, 100, 100));
       
  3177     QGraphicsRectItem *rect4 = scene.addRect(QRectF(0, 0, 100, 100));
       
  3178     QGraphicsRectItem *rect5 = scene.addRect(QRectF(0, 0, 100, 100));
       
  3179     rect2->setParentItem(rect);
       
  3180     rect3->setParentItem(rect2);
       
  3181     rect4->setParentItem(rect3);
       
  3182     rect5->setParentItem(rect4);
       
  3183 
       
  3184     rect2->setTransform(QTransform().translate(50, 50).rotate(45));
       
  3185     rect2->setPos(25, 25);
       
  3186     rect3->setTransform(QTransform().translate(50, 50).rotate(45));
       
  3187     rect3->setPos(25, 25);
       
  3188     rect4->setTransform(QTransform().translate(50, 50).rotate(45));
       
  3189     rect4->setPos(25, 25);
       
  3190     rect5->setTransform(QTransform().translate(50, 50).rotate(45));
       
  3191     rect5->setPos(25, 25);
       
  3192 
       
  3193     QRectF subTreeRect = rect->childrenBoundingRect();
       
  3194     QCOMPARE(subTreeRect.left(), qreal(-206.0660171779821));
       
  3195     QCOMPARE(subTreeRect.top(), qreal(75.0));
       
  3196     QCOMPARE(subTreeRect.width(), qreal(351.7766952966369));
       
  3197     QCOMPARE(subTreeRect.height(), qreal(251.7766952966369));
       
  3198 
       
  3199     rect->rotate(45);
       
  3200     rect2->rotate(-45);
       
  3201     rect3->rotate(45);
       
  3202     rect4->rotate(-45);
       
  3203     rect5->rotate(45);
       
  3204 
       
  3205     subTreeRect = rect->childrenBoundingRect();
       
  3206     QCOMPARE(rect->childrenBoundingRect(), QRectF(-100, 75, 275, 250));
       
  3207 }
       
  3208 
       
  3209 void tst_QGraphicsItem::childrenBoundingRect2()
       
  3210 {
       
  3211     QGraphicsItemGroup box;
       
  3212     QGraphicsLineItem l1(0, 0, 100, 0, &box);
       
  3213     QGraphicsLineItem l2(100, 0, 100, 100, &box);
       
  3214     QGraphicsLineItem l3(0, 0, 0, 100, &box);
       
  3215     // Make sure lines (zero with/height) are included in the childrenBoundingRect.
       
  3216     QCOMPARE(box.childrenBoundingRect(), QRectF(0, 0, 100, 100));
       
  3217 }
       
  3218 
       
  3219 void tst_QGraphicsItem::childrenBoundingRect3()
       
  3220 {
       
  3221     QGraphicsScene scene;
       
  3222 
       
  3223     QGraphicsRectItem *rect = scene.addRect(QRectF(0, 0, 100, 100));
       
  3224     QGraphicsRectItem *rect2 = scene.addRect(QRectF(0, 0, 100, 100));
       
  3225     QGraphicsRectItem *rect3 = scene.addRect(QRectF(0, 0, 100, 100));
       
  3226     QGraphicsRectItem *rect4 = scene.addRect(QRectF(0, 0, 100, 100));
       
  3227     QGraphicsRectItem *rect5 = scene.addRect(QRectF(0, 0, 100, 100));
       
  3228     rect2->setParentItem(rect);
       
  3229     rect3->setParentItem(rect2);
       
  3230     rect4->setParentItem(rect3);
       
  3231     rect5->setParentItem(rect4);
       
  3232 
       
  3233     rect2->setTransform(QTransform().translate(50, 50).rotate(45));
       
  3234     rect2->setPos(25, 25);
       
  3235     rect3->setTransform(QTransform().translate(50, 50).rotate(45));
       
  3236     rect3->setPos(25, 25);
       
  3237     rect4->setTransform(QTransform().translate(50, 50).rotate(45));
       
  3238     rect4->setPos(25, 25);
       
  3239     rect5->setTransform(QTransform().translate(50, 50).rotate(45));
       
  3240     rect5->setPos(25, 25);
       
  3241 
       
  3242     // Try to mess up the cached bounding rect.
       
  3243     (void)rect2->childrenBoundingRect();
       
  3244 
       
  3245     QRectF subTreeRect = rect->childrenBoundingRect();
       
  3246     QCOMPARE(subTreeRect.left(), qreal(-206.0660171779821));
       
  3247     QCOMPARE(subTreeRect.top(), qreal(75.0));
       
  3248     QCOMPARE(subTreeRect.width(), qreal(351.7766952966369));
       
  3249     QCOMPARE(subTreeRect.height(), qreal(251.7766952966369));
       
  3250 }
       
  3251 
       
  3252 void tst_QGraphicsItem::group()
       
  3253 {
       
  3254     QGraphicsScene scene;
       
  3255     QGraphicsRectItem *parent = scene.addRect(QRectF(0, 0, 50, 50), QPen(Qt::black, 0), QBrush(Qt::green));
       
  3256     QGraphicsRectItem *child = scene.addRect(QRectF(0, 0, 50, 50), QPen(Qt::black, 0), QBrush(Qt::blue));
       
  3257     QGraphicsRectItem *parent2 = scene.addRect(QRectF(0, 0, 50, 50), QPen(Qt::black, 0), QBrush(Qt::red));
       
  3258     parent2->setPos(-50, 50);
       
  3259     child->rotate(45);
       
  3260     child->setParentItem(parent);
       
  3261     parent->setPos(25, 25);
       
  3262     child->setPos(25, 25);
       
  3263 
       
  3264     QCOMPARE(parent->group(), (QGraphicsItemGroup *)0);
       
  3265     QCOMPARE(parent2->group(), (QGraphicsItemGroup *)0);
       
  3266     QCOMPARE(child->group(), (QGraphicsItemGroup *)0);
       
  3267 
       
  3268     QGraphicsView view(&scene);
       
  3269     view.show();
       
  3270     QTest::qWaitForWindowShown(&view);
       
  3271     QApplication::processEvents();
       
  3272 
       
  3273     QGraphicsItemGroup *group = new QGraphicsItemGroup;
       
  3274     group->setSelected(true);
       
  3275     scene.addItem(group);
       
  3276 
       
  3277     QRectF parentSceneBoundingRect = parent->sceneBoundingRect();
       
  3278     group->addToGroup(parent);
       
  3279     QCOMPARE(parent->group(), group);
       
  3280     QCOMPARE(parent->sceneBoundingRect(), parentSceneBoundingRect);
       
  3281 
       
  3282     QCOMPARE(parent->parentItem(), (QGraphicsItem *)group);
       
  3283     QCOMPARE(group->children().size(), 1);
       
  3284     QCOMPARE(scene.items().size(), 4);
       
  3285     QCOMPARE(scene.items(group->sceneBoundingRect()).size(), 3);
       
  3286 
       
  3287     QTest::qWait(25);
       
  3288 
       
  3289     QRectF parent2SceneBoundingRect = parent2->sceneBoundingRect();
       
  3290     group->addToGroup(parent2);
       
  3291     QCOMPARE(parent2->group(), group);
       
  3292     QCOMPARE(parent2->sceneBoundingRect(), parent2SceneBoundingRect);
       
  3293 
       
  3294     QCOMPARE(parent2->parentItem(), (QGraphicsItem *)group);
       
  3295     QCOMPARE(group->children().size(), 2);
       
  3296     QCOMPARE(scene.items().size(), 4);
       
  3297     QCOMPARE(scene.items(group->sceneBoundingRect()).size(), 4);
       
  3298 
       
  3299     QTest::qWait(25);
       
  3300 
       
  3301     QList<QGraphicsItem *> newItems;
       
  3302     for (int i = 0; i < 100; ++i) {
       
  3303         QGraphicsItem *item = scene.addRect(QRectF(-25, -25, 50, 50), QPen(Qt::black, 0),
       
  3304                                             QBrush(QColor(rand() % 255, rand() % 255,
       
  3305                                                           rand() % 255, rand() % 255)));
       
  3306         newItems << item;
       
  3307         item->setPos(-1000 + rand() % 2000,
       
  3308                      -1000 + rand() % 2000);
       
  3309         item->rotate(rand() % 90);
       
  3310     }
       
  3311 
       
  3312     view.fitInView(scene.itemsBoundingRect());
       
  3313 
       
  3314     int n = 0;
       
  3315     foreach (QGraphicsItem *item, newItems) {
       
  3316         group->addToGroup(item);
       
  3317         QCOMPARE(item->group(), group);
       
  3318         if ((n++ % 100) == 0)
       
  3319             QTest::qWait(10);
       
  3320     }
       
  3321 }
       
  3322 
       
  3323 void tst_QGraphicsItem::setGroup()
       
  3324 {
       
  3325     QGraphicsItemGroup group1;
       
  3326     QGraphicsItemGroup group2;
       
  3327 
       
  3328     QGraphicsRectItem *rect = new QGraphicsRectItem;
       
  3329     QCOMPARE(rect->group(), (QGraphicsItemGroup *)0);
       
  3330     QCOMPARE(rect->parentItem(), (QGraphicsItem *)0);
       
  3331     rect->setGroup(&group1);
       
  3332     QCOMPARE(rect->group(), &group1);
       
  3333     QCOMPARE(rect->parentItem(), (QGraphicsItem *)&group1);
       
  3334     rect->setGroup(&group2);
       
  3335     QCOMPARE(rect->group(), &group2);
       
  3336     QCOMPARE(rect->parentItem(), (QGraphicsItem *)&group2);
       
  3337     rect->setGroup(0);
       
  3338     QCOMPARE(rect->group(), (QGraphicsItemGroup *)0);
       
  3339     QCOMPARE(rect->parentItem(), (QGraphicsItem *)0);
       
  3340 }
       
  3341 
       
  3342 void tst_QGraphicsItem::nestedGroups()
       
  3343 {
       
  3344     QGraphicsItemGroup *group1 = new QGraphicsItemGroup;
       
  3345     QGraphicsItemGroup *group2 = new QGraphicsItemGroup;
       
  3346 
       
  3347     QGraphicsRectItem *rect = new QGraphicsRectItem;
       
  3348     QGraphicsRectItem *rect2 = new QGraphicsRectItem;
       
  3349     rect2->setParentItem(rect);
       
  3350 
       
  3351     group1->addToGroup(rect);
       
  3352     QCOMPARE(rect->group(), group1);
       
  3353     QCOMPARE(rect2->group(), group1);
       
  3354 
       
  3355     group2->addToGroup(group1);
       
  3356     QCOMPARE(rect->group(), group1);
       
  3357     QCOMPARE(rect2->group(), group1);
       
  3358     QCOMPARE(group1->group(), group2);
       
  3359     QCOMPARE(group2->group(), (QGraphicsItemGroup *)0);
       
  3360 
       
  3361     QGraphicsScene scene;
       
  3362     scene.addItem(group1);
       
  3363 
       
  3364     QCOMPARE(rect->group(), group1);
       
  3365     QCOMPARE(rect2->group(), group1);
       
  3366     QCOMPARE(group1->group(), (QGraphicsItemGroup *)0);
       
  3367     QVERIFY(group2->children().isEmpty());
       
  3368 
       
  3369     delete group2;
       
  3370 }
       
  3371 
       
  3372 void tst_QGraphicsItem::warpChildrenIntoGroup()
       
  3373 {
       
  3374     QGraphicsScene scene;
       
  3375     QGraphicsRectItem *parentRectItem = scene.addRect(QRectF(0, 0, 100, 100));
       
  3376     QGraphicsRectItem *childRectItem = scene.addRect(QRectF(0, 0, 100, 100));
       
  3377     parentRectItem->rotate(90);
       
  3378     childRectItem->setPos(-50, -25);
       
  3379     childRectItem->setParentItem(parentRectItem);
       
  3380 
       
  3381     QCOMPARE(childRectItem->mapToScene(50, 0), QPointF(25, 0));
       
  3382     QCOMPARE(childRectItem->scenePos(), QPointF(25, -50));
       
  3383 
       
  3384     QGraphicsRectItem *parentOfGroup = scene.addRect(QRectF(0, 0, 100, 100));
       
  3385     parentOfGroup->setPos(-200, -200);
       
  3386     parentOfGroup->scale(2, 2);
       
  3387 
       
  3388     QGraphicsItemGroup *group = new QGraphicsItemGroup;
       
  3389     group->setPos(50, 50);
       
  3390     group->setParentItem(parentOfGroup);
       
  3391 
       
  3392     QCOMPARE(group->scenePos(), QPointF(-100, -100));
       
  3393 
       
  3394     group->addToGroup(childRectItem);
       
  3395 
       
  3396     QCOMPARE(childRectItem->mapToScene(50, 0), QPointF(25, 0));
       
  3397     QCOMPARE(childRectItem->scenePos(), QPointF(25, -50));
       
  3398 }
       
  3399 
       
  3400 void tst_QGraphicsItem::removeFromGroup()
       
  3401 {
       
  3402     QGraphicsScene scene;
       
  3403     QGraphicsRectItem *rect1 = scene.addRect(QRectF(-100, -100, 200, 200));
       
  3404     QGraphicsRectItem *rect2 = scene.addRect(QRectF(100, 100, 200, 200));
       
  3405     rect1->setFlag(QGraphicsItem::ItemIsSelectable);
       
  3406     rect2->setFlag(QGraphicsItem::ItemIsSelectable);
       
  3407     rect1->setSelected(true);
       
  3408     rect2->setSelected(true);
       
  3409 
       
  3410     QGraphicsView view(&scene);
       
  3411     view.show();
       
  3412 
       
  3413     qApp->processEvents(); // index items
       
  3414     qApp->processEvents(); // emit changed
       
  3415 
       
  3416     QGraphicsItemGroup *group = scene.createItemGroup(scene.selectedItems());
       
  3417     QVERIFY(group);
       
  3418     QCOMPARE(group->children().size(), 2);
       
  3419     qApp->processEvents(); // index items
       
  3420     qApp->processEvents(); // emit changed
       
  3421 
       
  3422     scene.destroyItemGroup(group); // calls removeFromGroup.
       
  3423 
       
  3424     qApp->processEvents(); // index items
       
  3425     qApp->processEvents(); // emit changed
       
  3426 
       
  3427     QCOMPARE(scene.items().size(), 2);
       
  3428     QVERIFY(!rect1->group());
       
  3429     QVERIFY(!rect2->group());
       
  3430 }
       
  3431 
       
  3432 class ChildEventTester : public QGraphicsRectItem
       
  3433 {
       
  3434 public:
       
  3435     ChildEventTester(const QRectF &rect, QGraphicsItem *parent = 0)
       
  3436         : QGraphicsRectItem(rect, parent), counter(0)
       
  3437     { }
       
  3438 
       
  3439     int counter;
       
  3440 
       
  3441 protected:
       
  3442     void focusInEvent(QFocusEvent *event)
       
  3443     { ++counter; QGraphicsRectItem::focusInEvent(event); }
       
  3444     void mousePressEvent(QGraphicsSceneMouseEvent *)
       
  3445     { ++counter; }
       
  3446     void mouseMoveEvent(QGraphicsSceneMouseEvent *)
       
  3447     { ++counter; }
       
  3448     void mouseReleaseEvent(QGraphicsSceneMouseEvent *)
       
  3449     { ++counter; }
       
  3450 };
       
  3451 
       
  3452 void tst_QGraphicsItem::handlesChildEvents()
       
  3453 {
       
  3454     ChildEventTester *blue = new ChildEventTester(QRectF(0, 0, 100, 100));
       
  3455     ChildEventTester *red = new ChildEventTester(QRectF(0, 0, 50, 50));
       
  3456     ChildEventTester *green = new ChildEventTester(QRectF(0, 0, 25, 25));
       
  3457     ChildEventTester *gray = new ChildEventTester(QRectF(0, 0, 25, 25));
       
  3458     ChildEventTester *yellow = new ChildEventTester(QRectF(0, 0, 50, 50));
       
  3459 
       
  3460     blue->setBrush(QBrush(Qt::blue));
       
  3461     red->setBrush(QBrush(Qt::red));
       
  3462     yellow->setBrush(QBrush(Qt::yellow));
       
  3463     green->setBrush(QBrush(Qt::green));
       
  3464     gray->setBrush(QBrush(Qt::gray));
       
  3465     red->setPos(50, 0);
       
  3466     yellow->setPos(50, 50);
       
  3467     green->setPos(25, 0);
       
  3468     gray->setPos(25, 25);
       
  3469     red->setParentItem(blue);
       
  3470     yellow->setParentItem(blue);
       
  3471     green->setParentItem(red);
       
  3472     gray->setParentItem(red);
       
  3473 
       
  3474     QGraphicsScene scene;
       
  3475     scene.addItem(blue);
       
  3476 
       
  3477     QGraphicsView view(&scene);
       
  3478     view.show();
       
  3479     QTest::qWaitForWindowShown(&view);
       
  3480     QTest::qWait(20);
       
  3481 
       
  3482     // Pull out the items, closest item first
       
  3483     QList<QGraphicsItem *> items = scene.items(scene.itemsBoundingRect());
       
  3484     QCOMPARE(items.at(0), (QGraphicsItem *)yellow);
       
  3485     QCOMPARE(items.at(1), (QGraphicsItem *)gray);
       
  3486     QCOMPARE(items.at(2), (QGraphicsItem *)green);
       
  3487     QCOMPARE(items.at(3), (QGraphicsItem *)red);
       
  3488     QCOMPARE(items.at(4), (QGraphicsItem *)blue);
       
  3489 
       
  3490     QCOMPARE(blue->counter, 0);
       
  3491 
       
  3492     // Send events to the toplevel item
       
  3493     QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress);
       
  3494     QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMouseRelease);
       
  3495 
       
  3496     pressEvent.setButton(Qt::LeftButton);
       
  3497     pressEvent.setScenePos(blue->mapToScene(5, 5));
       
  3498     pressEvent.setScreenPos(view.mapFromScene(pressEvent.scenePos()));
       
  3499     releaseEvent.setButton(Qt::LeftButton);
       
  3500     releaseEvent.setScenePos(blue->mapToScene(5, 5));
       
  3501     releaseEvent.setScreenPos(view.mapFromScene(pressEvent.scenePos()));
       
  3502     QApplication::sendEvent(&scene, &pressEvent);
       
  3503     QApplication::sendEvent(&scene, &releaseEvent);
       
  3504 
       
  3505     QCOMPARE(blue->counter, 2);
       
  3506 
       
  3507     // Send events to a level1 item
       
  3508     pressEvent.setScenePos(red->mapToScene(5, 5));
       
  3509     pressEvent.setScreenPos(view.mapFromScene(pressEvent.scenePos()));
       
  3510     releaseEvent.setScenePos(red->mapToScene(5, 5));
       
  3511     releaseEvent.setScreenPos(view.mapFromScene(releaseEvent.scenePos()));
       
  3512     QApplication::sendEvent(&scene, &pressEvent);
       
  3513     QApplication::sendEvent(&scene, &releaseEvent);
       
  3514 
       
  3515     QCOMPARE(blue->counter, 2);
       
  3516     QCOMPARE(red->counter, 2);
       
  3517 
       
  3518     // Send events to a level2 item
       
  3519     pressEvent.setScenePos(green->mapToScene(5, 5));
       
  3520     pressEvent.setScreenPos(view.mapFromScene(pressEvent.scenePos()));
       
  3521     releaseEvent.setScenePos(green->mapToScene(5, 5));
       
  3522     releaseEvent.setScreenPos(view.mapFromScene(releaseEvent.scenePos()));
       
  3523     QApplication::sendEvent(&scene, &pressEvent);
       
  3524     QApplication::sendEvent(&scene, &releaseEvent);
       
  3525 
       
  3526     QCOMPARE(blue->counter, 2);
       
  3527     QCOMPARE(red->counter, 2);
       
  3528     QCOMPARE(green->counter, 2);
       
  3529 
       
  3530     blue->setHandlesChildEvents(true);
       
  3531 
       
  3532     // Send events to a level1 item
       
  3533     pressEvent.setScenePos(red->mapToScene(5, 5));
       
  3534     pressEvent.setScreenPos(view.mapFromScene(pressEvent.scenePos()));
       
  3535     releaseEvent.setScenePos(red->mapToScene(5, 5));
       
  3536     releaseEvent.setScreenPos(view.mapFromScene(releaseEvent.scenePos()));
       
  3537     QApplication::sendEvent(&scene, &pressEvent);
       
  3538     QApplication::sendEvent(&scene, &releaseEvent);
       
  3539 
       
  3540     QCOMPARE(blue->counter, 4);
       
  3541     QCOMPARE(red->counter, 2);
       
  3542 
       
  3543     // Send events to a level2 item
       
  3544     pressEvent.setScenePos(green->mapToScene(5, 5));
       
  3545     pressEvent.setScreenPos(view.mapFromScene(pressEvent.scenePos()));
       
  3546     releaseEvent.setScenePos(green->mapToScene(5, 5));
       
  3547     releaseEvent.setScreenPos(view.mapFromScene(releaseEvent.scenePos()));
       
  3548     QApplication::sendEvent(&scene, &pressEvent);
       
  3549     QApplication::sendEvent(&scene, &releaseEvent);
       
  3550 
       
  3551     QCOMPARE(blue->counter, 6);
       
  3552     QCOMPARE(red->counter, 2);
       
  3553     QCOMPARE(green->counter, 2);
       
  3554 
       
  3555     blue->setHandlesChildEvents(false);
       
  3556 
       
  3557     // Send events to a level1 item
       
  3558     pressEvent.setScenePos(red->mapToScene(5, 5));
       
  3559     pressEvent.setScreenPos(view.mapFromScene(pressEvent.scenePos()));
       
  3560     releaseEvent.setScenePos(red->mapToScene(5, 5));
       
  3561     releaseEvent.setScreenPos(view.mapFromScene(releaseEvent.scenePos()));
       
  3562     QApplication::sendEvent(&scene, &pressEvent);
       
  3563     QApplication::sendEvent(&scene, &releaseEvent);
       
  3564 
       
  3565     QCOMPARE(blue->counter, 6);
       
  3566     QCOMPARE(red->counter, 4);
       
  3567 
       
  3568     // Send events to a level2 item
       
  3569     pressEvent.setScenePos(green->mapToScene(5, 5));
       
  3570     pressEvent.setScreenPos(view.mapFromScene(pressEvent.scenePos()));
       
  3571     releaseEvent.setScenePos(green->mapToScene(5, 5));
       
  3572     releaseEvent.setScreenPos(view.mapFromScene(releaseEvent.scenePos()));
       
  3573     QApplication::sendEvent(&scene, &pressEvent);
       
  3574     QApplication::sendEvent(&scene, &releaseEvent);
       
  3575 
       
  3576     QCOMPARE(blue->counter, 6);
       
  3577     QCOMPARE(red->counter, 4);
       
  3578     QCOMPARE(green->counter, 4);
       
  3579 }
       
  3580 
       
  3581 void tst_QGraphicsItem::handlesChildEvents2()
       
  3582 {
       
  3583     ChildEventTester *root = new ChildEventTester(QRectF(0, 0, 10, 10));
       
  3584     root->setHandlesChildEvents(true);
       
  3585     QVERIFY(root->handlesChildEvents());
       
  3586 
       
  3587     ChildEventTester *child = new ChildEventTester(QRectF(0, 0, 10, 10), root);
       
  3588     QVERIFY(!child->handlesChildEvents());
       
  3589 
       
  3590     ChildEventTester *child2 = new ChildEventTester(QRectF(0, 0, 10, 10));
       
  3591     ChildEventTester *child3 = new ChildEventTester(QRectF(0, 0, 10, 10), child2);
       
  3592     ChildEventTester *child4 = new ChildEventTester(QRectF(0, 0, 10, 10), child3);
       
  3593     child2->setParentItem(root);
       
  3594     QVERIFY(!child2->handlesChildEvents());
       
  3595     QVERIFY(!child3->handlesChildEvents());
       
  3596     QVERIFY(!child4->handlesChildEvents());
       
  3597 
       
  3598     QGraphicsScene scene;
       
  3599     scene.addItem(root);
       
  3600 
       
  3601     QGraphicsView view(&scene);
       
  3602     view.show();
       
  3603     QTest::qWaitForWindowShown(&view);
       
  3604     QApplication::processEvents();
       
  3605 
       
  3606     QMouseEvent event(QEvent::MouseButtonPress, view.mapFromScene(5, 5),
       
  3607                       view.viewport()->mapToGlobal(view.mapFromScene(5, 5)), Qt::LeftButton, 0, 0);
       
  3608     QApplication::sendEvent(view.viewport(), &event);
       
  3609 
       
  3610     QTRY_COMPARE(root->counter, 1);
       
  3611 }
       
  3612 
       
  3613 void tst_QGraphicsItem::handlesChildEvents3()
       
  3614 {
       
  3615     QGraphicsScene scene;
       
  3616     QEvent activate(QEvent::WindowActivate);
       
  3617     QApplication::sendEvent(&scene, &activate);
       
  3618 
       
  3619     ChildEventTester *group2 = new ChildEventTester(QRectF(), 0);
       
  3620     ChildEventTester *group1 = new ChildEventTester(QRectF(), group2);
       
  3621     ChildEventTester *leaf = new ChildEventTester(QRectF(), group1);
       
  3622     scene.addItem(group2);
       
  3623 
       
  3624     leaf->setFlag(QGraphicsItem::ItemIsFocusable);
       
  3625     group1->setFlag(QGraphicsItem::ItemIsFocusable);
       
  3626     group1->setHandlesChildEvents(true);
       
  3627     group2->setFlag(QGraphicsItem::ItemIsFocusable);
       
  3628     group2->setHandlesChildEvents(true);
       
  3629 
       
  3630     leaf->setFocus();
       
  3631     QVERIFY(leaf->hasFocus()); // group2 stole the event, but leaf still got focus
       
  3632     QVERIFY(!group1->hasFocus());
       
  3633     QVERIFY(!group2->hasFocus());
       
  3634     QCOMPARE(leaf->counter, 0);
       
  3635     QCOMPARE(group1->counter, 0);
       
  3636     QCOMPARE(group2->counter, 1);
       
  3637 
       
  3638     group1->setFocus();
       
  3639     QVERIFY(group1->hasFocus()); // group2 stole the event, but group1 still got focus
       
  3640     QVERIFY(!leaf->hasFocus());
       
  3641     QVERIFY(!group2->hasFocus());
       
  3642     QCOMPARE(leaf->counter, 0);
       
  3643     QCOMPARE(group1->counter, 0);
       
  3644     QCOMPARE(group2->counter, 2);
       
  3645 
       
  3646     group2->setFocus();
       
  3647     QVERIFY(group2->hasFocus()); // group2 stole the event, and now group2 also has focus
       
  3648     QVERIFY(!leaf->hasFocus());
       
  3649     QVERIFY(!group1->hasFocus());
       
  3650     QCOMPARE(leaf->counter, 0);
       
  3651     QCOMPARE(group1->counter, 0);
       
  3652     QCOMPARE(group2->counter, 3);
       
  3653 }
       
  3654 
       
  3655 
       
  3656 class ChildEventFilterTester : public ChildEventTester
       
  3657 {
       
  3658 public:
       
  3659     ChildEventFilterTester(const QRectF &rect, QGraphicsItem *parent = 0)
       
  3660         : ChildEventTester(rect, parent), filter(QEvent::None)
       
  3661     { }
       
  3662 
       
  3663     QEvent::Type filter;
       
  3664 
       
  3665 protected:
       
  3666     bool sceneEventFilter(QGraphicsItem *item, QEvent *event)
       
  3667     {
       
  3668         Q_UNUSED(item);
       
  3669         if (event->type() == filter) {
       
  3670             ++counter;
       
  3671             return true;
       
  3672         }
       
  3673         return false;
       
  3674     }
       
  3675 };
       
  3676 
       
  3677 void tst_QGraphicsItem::filtersChildEvents()
       
  3678 {
       
  3679     QGraphicsScene scene;
       
  3680     ChildEventFilterTester *root = new ChildEventFilterTester(QRectF(0, 0, 10, 10));
       
  3681     ChildEventFilterTester *filter = new ChildEventFilterTester(QRectF(10, 10, 10, 10), root);
       
  3682     ChildEventTester *child = new ChildEventTester(QRectF(20, 20, 10, 10), filter);
       
  3683 
       
  3684     // setup filter
       
  3685     filter->setFiltersChildEvents(true);
       
  3686     filter->filter = QEvent::GraphicsSceneMousePress;
       
  3687 
       
  3688     scene.addItem(root);
       
  3689 
       
  3690     QGraphicsView view(&scene);
       
  3691     view.show();
       
  3692     QTest::qWaitForWindowShown(&view);
       
  3693     QTest::qWait(20);
       
  3694 
       
  3695     QGraphicsSceneMouseEvent pressEvent(QEvent::GraphicsSceneMousePress);
       
  3696     QGraphicsSceneMouseEvent releaseEvent(QEvent::GraphicsSceneMouseRelease);
       
  3697 
       
  3698     // send event to child
       
  3699     pressEvent.setButton(Qt::LeftButton);
       
  3700     pressEvent.setScenePos(QPointF(25, 25));//child->mapToScene(5, 5));
       
  3701     pressEvent.setScreenPos(view.mapFromScene(pressEvent.scenePos()));
       
  3702     releaseEvent.setButton(Qt::LeftButton);
       
  3703     releaseEvent.setScenePos(QPointF(25, 25));//child->mapToScene(5, 5));
       
  3704     releaseEvent.setScreenPos(view.mapFromScene(pressEvent.scenePos()));
       
  3705     QApplication::sendEvent(&scene, &pressEvent);
       
  3706     QApplication::sendEvent(&scene, &releaseEvent);
       
  3707 
       
  3708     QTRY_COMPARE(child->counter, 1);  // mouse release is not filtered
       
  3709     QCOMPARE(filter->counter, 1); // mouse press is filtered
       
  3710     QCOMPARE(root->counter, 0);
       
  3711 
       
  3712     // add another filter
       
  3713     root->setFiltersChildEvents(true);
       
  3714     root->filter = QEvent::GraphicsSceneMouseRelease;
       
  3715 
       
  3716     // send event to child
       
  3717     QApplication::sendEvent(&scene, &pressEvent);
       
  3718     QApplication::sendEvent(&scene, &releaseEvent);
       
  3719 
       
  3720     QCOMPARE(child->counter, 1);
       
  3721     QCOMPARE(filter->counter, 2); // mouse press is filtered
       
  3722     QCOMPARE(root->counter, 1); // mouse release is filtered
       
  3723 
       
  3724     // reparent to another sub-graph
       
  3725     ChildEventTester *parent = new ChildEventTester(QRectF(10, 10, 10, 10), root);
       
  3726     child->setParentItem(parent);
       
  3727 
       
  3728     // send event to child
       
  3729     QApplication::sendEvent(&scene, &pressEvent);
       
  3730     QApplication::sendEvent(&scene, &releaseEvent);
       
  3731 
       
  3732     QCOMPARE(child->counter, 2); // mouse press is _not_ filtered
       
  3733     QCOMPARE(parent->counter, 0);
       
  3734     QCOMPARE(filter->counter, 2);
       
  3735     QCOMPARE(root->counter, 2); // mouse release is filtered
       
  3736 }
       
  3737 
       
  3738 void tst_QGraphicsItem::filtersChildEvents2()
       
  3739 {
       
  3740     ChildEventFilterTester *root = new ChildEventFilterTester(QRectF(0, 0, 10, 10));
       
  3741     root->setFiltersChildEvents(true);
       
  3742     root->filter = QEvent::GraphicsSceneMousePress;
       
  3743     QVERIFY(root->filtersChildEvents());
       
  3744 
       
  3745     ChildEventTester *child = new ChildEventTester(QRectF(0, 0, 10, 10), root);
       
  3746     QVERIFY(!child->filtersChildEvents());
       
  3747 
       
  3748     ChildEventTester *child2 = new ChildEventTester(QRectF(0, 0, 10, 10));
       
  3749     ChildEventTester *child3 = new ChildEventTester(QRectF(0, 0, 10, 10), child2);
       
  3750     ChildEventTester *child4 = new ChildEventTester(QRectF(0, 0, 10, 10), child3);
       
  3751 
       
  3752     child2->setParentItem(root);
       
  3753     QVERIFY(!child2->filtersChildEvents());
       
  3754     QVERIFY(!child3->filtersChildEvents());
       
  3755     QVERIFY(!child4->filtersChildEvents());
       
  3756 
       
  3757     QGraphicsScene scene;
       
  3758     scene.addItem(root);
       
  3759 
       
  3760     QGraphicsView view(&scene);
       
  3761     view.show();
       
  3762 
       
  3763     QTest::qWaitForWindowShown(&view);
       
  3764     QApplication::processEvents();
       
  3765 
       
  3766     QMouseEvent event(QEvent::MouseButtonPress, view.mapFromScene(5, 5),
       
  3767                       view.viewport()->mapToGlobal(view.mapFromScene(5, 5)), Qt::LeftButton, 0, 0);
       
  3768     QApplication::sendEvent(view.viewport(), &event);
       
  3769 
       
  3770     QTRY_COMPARE(root->counter, 1);
       
  3771     QCOMPARE(child->counter, 0);
       
  3772     QCOMPARE(child2->counter, 0);
       
  3773     QCOMPARE(child3->counter, 0);
       
  3774     QCOMPARE(child4->counter, 0);
       
  3775 }
       
  3776 
       
  3777 class CustomItem : public QGraphicsItem
       
  3778 {
       
  3779 public:
       
  3780     QRectF boundingRect() const
       
  3781     { return QRectF(-110, -110, 220, 220); }
       
  3782 
       
  3783     void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
       
  3784     {
       
  3785         for (int x = -100; x <= 100; x += 25)
       
  3786             painter->drawLine(x, -100, x, 100);
       
  3787         for (int y = -100; y <= 100; y += 25)
       
  3788             painter->drawLine(-100, y, 100, y);
       
  3789 
       
  3790         QFont font = painter->font();
       
  3791         font.setPointSize(4);
       
  3792         painter->setFont(font);
       
  3793         for (int x = -100; x < 100; x += 25) {
       
  3794             for (int y = -100; y < 100; y += 25) {
       
  3795                 painter->drawText(QRectF(x, y, 25, 25), Qt::AlignCenter, QString("%1x%2").arg(x).arg(y));
       
  3796             }
       
  3797         }
       
  3798     }
       
  3799 };
       
  3800 
       
  3801 void tst_QGraphicsItem::ensureVisible()
       
  3802 {
       
  3803     QGraphicsScene scene;
       
  3804     scene.setSceneRect(-200, -200, 400, 400);
       
  3805     QGraphicsItem *item = new CustomItem;
       
  3806     scene.addItem(item);
       
  3807 
       
  3808     QGraphicsView view(&scene);
       
  3809     view.setFixedSize(300, 300);
       
  3810     view.show();
       
  3811     QTest::qWaitForWindowShown(&view);
       
  3812 
       
  3813     for (int i = 0; i < 25; ++i) {
       
  3814         view.scale(qreal(1.06), qreal(1.06));
       
  3815         QApplication::processEvents();
       
  3816     }
       
  3817 
       
  3818     item->ensureVisible(-100, -100, 25, 25);
       
  3819     QTest::qWait(25);
       
  3820 
       
  3821     for (int x = -100; x < 100; x += 25) {
       
  3822         for (int y = -100; y < 100; y += 25) {
       
  3823             int xmargin = rand() % 75;
       
  3824             int ymargin = rand() % 75;
       
  3825             item->ensureVisible(x, y, 25, 25, xmargin, ymargin);
       
  3826             QApplication::processEvents();
       
  3827 
       
  3828             QPolygonF viewScenePoly;
       
  3829             viewScenePoly << view.mapToScene(view.rect().topLeft())
       
  3830                           << view.mapToScene(view.rect().topRight())
       
  3831                           << view.mapToScene(view.rect().bottomRight())
       
  3832                           << view.mapToScene(view.rect().bottomLeft());
       
  3833 
       
  3834             QVERIFY(scene.items(viewScenePoly).contains(item));
       
  3835 
       
  3836             QPainterPath path;
       
  3837             path.addPolygon(viewScenePoly);
       
  3838             QVERIFY(path.contains(item->mapToScene(x + 12, y + 12)));
       
  3839 
       
  3840             QPolygonF viewScenePolyMinusMargins;
       
  3841             viewScenePolyMinusMargins << view.mapToScene(view.rect().topLeft() + QPoint(xmargin, ymargin))
       
  3842                           << view.mapToScene(view.rect().topRight() + QPoint(-xmargin, ymargin))
       
  3843                           << view.mapToScene(view.rect().bottomRight() + QPoint(-xmargin, -ymargin))
       
  3844                           << view.mapToScene(view.rect().bottomLeft() + QPoint(xmargin, -ymargin));
       
  3845 
       
  3846             QPainterPath path2;
       
  3847             path2.addPolygon(viewScenePolyMinusMargins);
       
  3848             QVERIFY(path2.contains(item->mapToScene(x + 12, y + 12)));
       
  3849         }
       
  3850     }
       
  3851 
       
  3852     item->ensureVisible(100, 100, 25, 25);
       
  3853     QTest::qWait(25);
       
  3854 }
       
  3855 
       
  3856 void tst_QGraphicsItem::cursor()
       
  3857 {
       
  3858 #ifndef QT_NO_CURSOR
       
  3859     QGraphicsScene scene;
       
  3860     QGraphicsRectItem *item1 = scene.addRect(QRectF(0, 0, 50, 50));
       
  3861     QGraphicsRectItem *item2 = scene.addRect(QRectF(0, 0, 50, 50));
       
  3862     item1->setPos(-100, 0);
       
  3863     item2->setPos(50, 0);
       
  3864 
       
  3865     QVERIFY(!item1->hasCursor());
       
  3866     QVERIFY(!item2->hasCursor());
       
  3867 
       
  3868     item1->setCursor(Qt::IBeamCursor);
       
  3869     item2->setCursor(Qt::PointingHandCursor);
       
  3870 
       
  3871     QVERIFY(item1->hasCursor());
       
  3872     QVERIFY(item2->hasCursor());
       
  3873 
       
  3874     item1->setCursor(QCursor());
       
  3875     item2->setCursor(QCursor());
       
  3876 
       
  3877     QVERIFY(item1->hasCursor());
       
  3878     QVERIFY(item2->hasCursor());
       
  3879 
       
  3880     item1->unsetCursor();
       
  3881     item2->unsetCursor();
       
  3882 
       
  3883     QVERIFY(!item1->hasCursor());
       
  3884     QVERIFY(!item2->hasCursor());
       
  3885 
       
  3886     item1->setCursor(Qt::IBeamCursor);
       
  3887     item2->setCursor(Qt::PointingHandCursor);
       
  3888 
       
  3889     QGraphicsView view(&scene);
       
  3890     view.setFixedSize(200, 100);
       
  3891     view.show();
       
  3892     QTest::mouseMove(&view, view.rect().center());
       
  3893 
       
  3894     QTest::qWait(25);
       
  3895 
       
  3896     QCursor cursor = view.viewport()->cursor();
       
  3897 
       
  3898     {
       
  3899         QMouseEvent event(QEvent::MouseMove, QPoint(100, 50), Qt::NoButton, 0, 0);
       
  3900         QApplication::sendEvent(view.viewport(), &event);
       
  3901     }
       
  3902 
       
  3903     QTest::qWait(25);
       
  3904 
       
  3905     QCOMPARE(view.viewport()->cursor().shape(), cursor.shape());
       
  3906 
       
  3907     {
       
  3908         QTest::mouseMove(view.viewport(), view.mapFromScene(item1->sceneBoundingRect().center()));
       
  3909         QMouseEvent event(QEvent::MouseMove, view.mapFromScene(item1->sceneBoundingRect().center()), Qt::NoButton, 0, 0);
       
  3910         QApplication::sendEvent(view.viewport(), &event);
       
  3911     }
       
  3912 
       
  3913 #if !defined(Q_OS_WINCE)
       
  3914     QTest::qWait(250);
       
  3915 #else
       
  3916     // Test environment does not have any cursor, therefore no shape
       
  3917     return;
       
  3918 #endif
       
  3919 
       
  3920     QCOMPARE(view.viewport()->cursor().shape(), item1->cursor().shape());
       
  3921 
       
  3922     {
       
  3923         QTest::mouseMove(view.viewport(), view.mapFromScene(item2->sceneBoundingRect().center()));
       
  3924         QMouseEvent event(QEvent::MouseMove, view.mapFromScene(item2->sceneBoundingRect().center()), Qt::NoButton, 0, 0);
       
  3925         QApplication::sendEvent(view.viewport(), &event);
       
  3926     }
       
  3927 
       
  3928     QTest::qWait(25);
       
  3929 
       
  3930     QCOMPARE(view.viewport()->cursor().shape(), item2->cursor().shape());
       
  3931 
       
  3932     {
       
  3933         QTest::mouseMove(view.viewport(), view.rect().center());
       
  3934         QMouseEvent event(QEvent::MouseMove, QPoint(100, 25), Qt::NoButton, 0, 0);
       
  3935         QApplication::sendEvent(view.viewport(), &event);
       
  3936     }
       
  3937 
       
  3938     QTest::qWait(25);
       
  3939 
       
  3940     QCOMPARE(view.viewport()->cursor().shape(), cursor.shape());
       
  3941 #endif
       
  3942 }
       
  3943 /*
       
  3944 void tst_QGraphicsItem::textControlGetterSetter()
       
  3945 {
       
  3946     QGraphicsTextItem *item = new QGraphicsTextItem;
       
  3947     QVERIFY(item->textControl()->parent() == item);
       
  3948     QPointer<QTextControl> control = item->textControl();
       
  3949     delete item;
       
  3950     QVERIFY(!control);
       
  3951 
       
  3952     item = new QGraphicsTextItem;
       
  3953 
       
  3954     QPointer<QTextControl> oldControl = control;
       
  3955     control = new QTextControl;
       
  3956 
       
  3957     item->setTextControl(control);
       
  3958     QVERIFY(item->textControl() == control);
       
  3959     QVERIFY(!control->parent());
       
  3960     QVERIFY(!oldControl);
       
  3961 
       
  3962     // set some text to give it a size, to test that
       
  3963     // setTextControl (re)connects signals
       
  3964     const QRectF oldBoundingRect = item->boundingRect();
       
  3965     QVERIFY(oldBoundingRect.isValid());
       
  3966     item->setPlainText("Some text");
       
  3967     item->adjustSize();
       
  3968     QVERIFY(item->boundingRect().isValid());
       
  3969     QVERIFY(item->boundingRect() != oldBoundingRect);
       
  3970 
       
  3971     // test that on setting a control the item size
       
  3972     // is adjusted
       
  3973     oldControl = control;
       
  3974     control = new QTextControl;
       
  3975     control->setPlainText("foo!");
       
  3976     item->setTextControl(control);
       
  3977     QCOMPARE(item->boundingRect().size(), control->document()->documentLayout()->documentSize());
       
  3978 
       
  3979     QVERIFY(oldControl);
       
  3980     delete oldControl;
       
  3981 
       
  3982     delete item;
       
  3983     QVERIFY(control);
       
  3984     delete control;
       
  3985 }
       
  3986 */
       
  3987 
       
  3988 void tst_QGraphicsItem::defaultItemTest_QGraphicsLineItem()
       
  3989 {
       
  3990     QGraphicsLineItem item;
       
  3991     QCOMPARE(item.line(), QLineF());
       
  3992     QCOMPARE(item.pen(), QPen());
       
  3993     QCOMPARE(item.shape(), QPainterPath());
       
  3994 
       
  3995     item.setPen(QPen(Qt::black, 1));
       
  3996     QCOMPARE(item.pen(), QPen(Qt::black, 1));
       
  3997     item.setLine(QLineF(0, 0, 10, 0));
       
  3998     QCOMPARE(item.line(), QLineF(0, 0, 10, 0));
       
  3999     QCOMPARE(item.boundingRect(), QRectF(-0.5, -0.5, 11, 1));
       
  4000     QCOMPARE(item.shape().elementCount(), 11);
       
  4001 
       
  4002     QPainterPath path;
       
  4003     path.moveTo(0, -0.5);
       
  4004     path.lineTo(10, -0.5);
       
  4005     path.lineTo(10.5, -0.5);
       
  4006     path.lineTo(10.5, 0.5);
       
  4007     path.lineTo(10, 0.5);
       
  4008     path.lineTo(0, 0.5);
       
  4009     path.lineTo(-0.5, 0.5);
       
  4010     path.lineTo(-0.5, -0.5);
       
  4011     path.lineTo(0, -0.5);
       
  4012     path.lineTo(0, 0);
       
  4013     path.lineTo(10, 0);
       
  4014     path.closeSubpath();
       
  4015 
       
  4016     for (int i = 0; i < 11; ++i)
       
  4017         QCOMPARE(QPointF(item.shape().elementAt(i)), QPointF(path.elementAt(i)));
       
  4018 }
       
  4019 
       
  4020 void tst_QGraphicsItem::defaultItemTest_QGraphicsPixmapItem()
       
  4021 {
       
  4022     QGraphicsPixmapItem item;
       
  4023     QVERIFY(item.pixmap().isNull());
       
  4024     QCOMPARE(item.offset(), QPointF());
       
  4025     QCOMPARE(item.transformationMode(), Qt::FastTransformation);
       
  4026 
       
  4027     QPixmap pixmap(300, 200);
       
  4028     pixmap.fill(Qt::red);
       
  4029     item.setPixmap(pixmap);
       
  4030     QCOMPARE(item.pixmap(), pixmap);
       
  4031 
       
  4032     item.setTransformationMode(Qt::FastTransformation);
       
  4033     QCOMPARE(item.transformationMode(), Qt::FastTransformation);
       
  4034     item.setTransformationMode(Qt::SmoothTransformation);
       
  4035     QCOMPARE(item.transformationMode(), Qt::SmoothTransformation);
       
  4036 
       
  4037     item.setOffset(-15, -15);
       
  4038     QCOMPARE(item.offset(), QPointF(-15, -15));
       
  4039     item.setOffset(QPointF(-10, -10));
       
  4040     QCOMPARE(item.offset(), QPointF(-10, -10));
       
  4041 
       
  4042     QCOMPARE(item.boundingRect(), QRectF(-10.5, -10.5, 301, 201));
       
  4043 }
       
  4044 
       
  4045 void tst_QGraphicsItem::defaultItemTest_QGraphicsTextItem()
       
  4046 {
       
  4047     QGraphicsTextItem *text = new QGraphicsTextItem;
       
  4048     QVERIFY(!text->openExternalLinks());
       
  4049     QVERIFY(text->textCursor().isNull());
       
  4050     QCOMPARE(text->defaultTextColor(), QPalette().color(QPalette::Text));
       
  4051     QVERIFY(text->document() != 0);
       
  4052     QCOMPARE(text->font(), QApplication::font());
       
  4053     QCOMPARE(text->textInteractionFlags(), Qt::TextInteractionFlags(Qt::NoTextInteraction));
       
  4054     QCOMPARE(text->textWidth(), -1.0);
       
  4055     QCOMPARE(text->toPlainText(), QString(""));
       
  4056 
       
  4057     QGraphicsScene scene;
       
  4058     scene.addItem(text);
       
  4059     text->setPlainText("Hello world");
       
  4060     text->setFlag(QGraphicsItem::ItemIsMovable);
       
  4061 
       
  4062     {
       
  4063         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
       
  4064         event.setScenePos(QPointF(1, 1));
       
  4065         event.setButton(Qt::LeftButton);
       
  4066         event.setButtons(Qt::LeftButton);
       
  4067         QApplication::sendEvent(&scene, &event);
       
  4068         QGraphicsSceneMouseEvent event2(QEvent::GraphicsSceneMouseMove);
       
  4069         event2.setScenePos(QPointF(11, 11));
       
  4070         event2.setButton(Qt::LeftButton);
       
  4071         event2.setButtons(Qt::LeftButton);
       
  4072         QApplication::sendEvent(&scene, &event2);
       
  4073     }
       
  4074 
       
  4075     QCOMPARE(text->pos(), QPointF(10, 10));
       
  4076 
       
  4077     text->setTextInteractionFlags(Qt::TextEditorInteraction);
       
  4078     QCOMPARE(text->textInteractionFlags(), Qt::TextInteractionFlags(Qt::TextEditorInteraction));
       
  4079 
       
  4080     {
       
  4081         QGraphicsSceneMouseEvent event2(QEvent::GraphicsSceneMouseMove);
       
  4082         event2.setScenePos(QPointF(21, 21));
       
  4083         event2.setButton(Qt::LeftButton);
       
  4084         event2.setButtons(Qt::LeftButton);
       
  4085         QApplication::sendEvent(&scene, &event2);
       
  4086     }
       
  4087 
       
  4088     QCOMPARE(text->pos(), QPointF(20, 20)); // clicked on edge, item moved
       
  4089 }
       
  4090 
       
  4091 void tst_QGraphicsItem::defaultItemTest_QGraphicsEllipseItem()
       
  4092 {
       
  4093     QGraphicsEllipseItem item;
       
  4094     QVERIFY(item.rect().isNull());
       
  4095     QVERIFY(item.boundingRect().isNull());
       
  4096     QVERIFY(item.shape().isEmpty());
       
  4097     QCOMPARE(item.spanAngle(), 360 * 16);
       
  4098     QCOMPARE(item.startAngle(), 0);
       
  4099 
       
  4100     item.setRect(0, 0, 100, 100);
       
  4101     QCOMPARE(item.boundingRect(), QRectF(0, 0, 100, 100));
       
  4102 
       
  4103     item.setSpanAngle(90 * 16);
       
  4104     qFuzzyCompare(item.boundingRect().left(), qreal(50.0));
       
  4105     qFuzzyCompare(item.boundingRect().top(), qreal(0.0));
       
  4106     qFuzzyCompare(item.boundingRect().width(), qreal(50.0));
       
  4107     qFuzzyCompare(item.boundingRect().height(), qreal(50.0));
       
  4108 
       
  4109     item.setPen(QPen(Qt::black, 1));
       
  4110     QCOMPARE(item.boundingRect(), QRectF(49.5, -0.5, 51, 51));
       
  4111 
       
  4112     item.setSpanAngle(180 * 16);
       
  4113     QCOMPARE(item.boundingRect(), QRectF(-0.5, -0.5, 101, 51));
       
  4114 
       
  4115     item.setSpanAngle(360 * 16);
       
  4116     QCOMPARE(item.boundingRect(), QRectF(-0.5, -0.5, 101, 101));
       
  4117 }
       
  4118 
       
  4119 class ItemChangeTester : public QGraphicsRectItem
       
  4120 {
       
  4121 public:
       
  4122     ItemChangeTester()
       
  4123     { setFlag(ItemSendsGeometryChanges); clear(); }
       
  4124     ItemChangeTester(QGraphicsItem *parent) : QGraphicsRectItem(parent)
       
  4125     { setFlag(ItemSendsGeometryChanges); clear(); }
       
  4126 
       
  4127     void clear()
       
  4128     {
       
  4129         itemChangeReturnValue = QVariant();
       
  4130         itemSceneChangeTargetScene = 0;
       
  4131         changes.clear();
       
  4132         values.clear();
       
  4133         oldValues.clear();
       
  4134     }
       
  4135 
       
  4136     QVariant itemChangeReturnValue;
       
  4137     QGraphicsScene *itemSceneChangeTargetScene;
       
  4138 
       
  4139     QList<GraphicsItemChange> changes;
       
  4140     QList<QVariant> values;
       
  4141     QList<QVariant> oldValues;
       
  4142 protected:
       
  4143     QVariant itemChange(GraphicsItemChange change, const QVariant &value)
       
  4144     {
       
  4145         changes << change;
       
  4146         values << value;
       
  4147         switch (change) {
       
  4148         case QGraphicsItem::ItemPositionChange:
       
  4149             oldValues << pos();
       
  4150             break;
       
  4151         case QGraphicsItem::ItemPositionHasChanged:
       
  4152             break;
       
  4153         case QGraphicsItem::ItemMatrixChange: {
       
  4154             QVariant variant;
       
  4155             qVariantSetValue<QMatrix>(variant, matrix());
       
  4156             oldValues << variant;
       
  4157         }
       
  4158             break;
       
  4159         case QGraphicsItem::ItemTransformChange: {
       
  4160             QVariant variant;
       
  4161             qVariantSetValue<QTransform>(variant, transform());
       
  4162             oldValues << variant;
       
  4163         }
       
  4164             break;
       
  4165         case QGraphicsItem::ItemTransformHasChanged:
       
  4166             break;
       
  4167         case QGraphicsItem::ItemVisibleChange:
       
  4168             oldValues << isVisible();
       
  4169             break;
       
  4170         case QGraphicsItem::ItemVisibleHasChanged:
       
  4171             break;
       
  4172         case QGraphicsItem::ItemEnabledChange:
       
  4173             oldValues << isEnabled();
       
  4174             break;
       
  4175         case QGraphicsItem::ItemEnabledHasChanged:
       
  4176             break;
       
  4177         case QGraphicsItem::ItemSelectedChange:
       
  4178             oldValues << isSelected();
       
  4179             break;
       
  4180         case QGraphicsItem::ItemSelectedHasChanged:
       
  4181             break;
       
  4182         case QGraphicsItem::ItemParentChange:
       
  4183             oldValues << qVariantFromValue<void *>(parentItem());
       
  4184             break;
       
  4185         case QGraphicsItem::ItemParentHasChanged:
       
  4186             break;
       
  4187         case QGraphicsItem::ItemChildAddedChange:
       
  4188             oldValues << children().size();
       
  4189             break;
       
  4190         case QGraphicsItem::ItemChildRemovedChange:
       
  4191             oldValues << children().size();
       
  4192             break;
       
  4193         case QGraphicsItem::ItemSceneChange:
       
  4194             oldValues << qVariantFromValue<QGraphicsScene *>(scene());
       
  4195             if (itemSceneChangeTargetScene
       
  4196                 && qVariantValue<QGraphicsScene *>(value)
       
  4197                 && itemSceneChangeTargetScene != qVariantValue<QGraphicsScene *>(value)) {
       
  4198                 return qVariantFromValue<QGraphicsScene *>(itemSceneChangeTargetScene);
       
  4199             }
       
  4200             return value;
       
  4201         case QGraphicsItem::ItemSceneHasChanged:
       
  4202             break;
       
  4203         case QGraphicsItem::ItemCursorChange:
       
  4204 #ifndef QT_NO_CURSOR
       
  4205             oldValues << cursor();
       
  4206 #endif
       
  4207             break;
       
  4208         case QGraphicsItem::ItemCursorHasChanged:
       
  4209             break;
       
  4210         case QGraphicsItem::ItemToolTipChange:
       
  4211             oldValues << toolTip();
       
  4212             break;
       
  4213         case QGraphicsItem::ItemToolTipHasChanged:
       
  4214             break;
       
  4215         case QGraphicsItem::ItemFlagsChange:
       
  4216             oldValues << quint32(flags());
       
  4217             break;
       
  4218         case QGraphicsItem::ItemFlagsHaveChanged:
       
  4219             break;
       
  4220         case QGraphicsItem::ItemZValueChange:
       
  4221             oldValues << zValue();
       
  4222             break;
       
  4223         case QGraphicsItem::ItemZValueHasChanged:
       
  4224             break;
       
  4225         case QGraphicsItem::ItemOpacityChange:
       
  4226             oldValues << opacity();
       
  4227             break;
       
  4228         case QGraphicsItem::ItemOpacityHasChanged:
       
  4229             break;
       
  4230         }
       
  4231         return itemChangeReturnValue.isValid() ? itemChangeReturnValue : value;
       
  4232     }
       
  4233 };
       
  4234 
       
  4235 void tst_QGraphicsItem::itemChange()
       
  4236 {
       
  4237     ItemChangeTester tester;
       
  4238     tester.itemSceneChangeTargetScene = 0;
       
  4239 
       
  4240     ItemChangeTester testerHelper;
       
  4241     QVERIFY(tester.changes.isEmpty());
       
  4242     QVERIFY(tester.values.isEmpty());
       
  4243 
       
  4244     int changeCount = 0;
       
  4245     {
       
  4246         // ItemEnabledChange
       
  4247         tester.itemChangeReturnValue = true;
       
  4248         tester.setEnabled(false);
       
  4249         ++changeCount;
       
  4250         ++changeCount; // HasChanged
       
  4251         QCOMPARE(tester.changes.size(), changeCount);
       
  4252         QCOMPARE(tester.changes.at(tester.changes.size() - 2), QGraphicsItem::ItemEnabledChange);
       
  4253         QCOMPARE(tester.changes.at(tester.changes.size() - 1), QGraphicsItem::ItemEnabledHasChanged);
       
  4254         QCOMPARE(tester.values.at(tester.values.size() - 2), QVariant(false));
       
  4255         QCOMPARE(tester.values.at(tester.values.size() - 1), QVariant(true));
       
  4256         QCOMPARE(tester.oldValues.last(), QVariant(true));
       
  4257         QCOMPARE(tester.isEnabled(), true);
       
  4258     }
       
  4259     {
       
  4260         // ItemMatrixChange / ItemTransformHasChanged
       
  4261         qVariantSetValue<QMatrix>(tester.itemChangeReturnValue, QMatrix().rotate(90));
       
  4262         tester.setMatrix(QMatrix().translate(50, 0), true);
       
  4263         ++changeCount; // notification sent too
       
  4264         QCOMPARE(tester.changes.size(), ++changeCount);
       
  4265         QCOMPARE(int(tester.changes.at(tester.changes.size() - 2)), int(QGraphicsItem::ItemMatrixChange));
       
  4266         QCOMPARE(int(tester.changes.last()), int(QGraphicsItem::ItemTransformHasChanged));
       
  4267         QCOMPARE(qVariantValue<QMatrix>(tester.values.at(tester.values.size() - 2)),
       
  4268                  QMatrix().translate(50, 0));
       
  4269         QCOMPARE(tester.values.last(), QVariant(QTransform(QMatrix().rotate(90))));
       
  4270         QVariant variant;
       
  4271         qVariantSetValue<QMatrix>(variant, QMatrix());
       
  4272         QCOMPARE(tester.oldValues.last(), variant);
       
  4273         QCOMPARE(tester.matrix(), QMatrix().rotate(90));
       
  4274     }
       
  4275     {
       
  4276         tester.resetTransform();
       
  4277         ++changeCount;
       
  4278         ++changeCount; // notification sent too
       
  4279 
       
  4280         // ItemTransformChange / ItemTransformHasChanged
       
  4281         qVariantSetValue<QTransform>(tester.itemChangeReturnValue, QTransform().rotate(90));
       
  4282         tester.translate(50, 0);
       
  4283         ++changeCount; // notification sent too
       
  4284         ++changeCount;
       
  4285         QCOMPARE(tester.changes.size(), changeCount);
       
  4286         QCOMPARE(tester.changes.at(tester.changes.size() - 2), QGraphicsItem::ItemTransformChange);
       
  4287         QCOMPARE(tester.changes.at(tester.changes.size() - 1), QGraphicsItem::ItemTransformHasChanged);
       
  4288         QCOMPARE(qVariantValue<QTransform>(tester.values.at(tester.values.size() - 2)),
       
  4289                  QTransform().translate(50, 0));
       
  4290         QCOMPARE(qVariantValue<QTransform>(tester.values.at(tester.values.size() - 1)),
       
  4291                  QTransform().rotate(90));
       
  4292         QVariant variant;
       
  4293         qVariantSetValue<QTransform>(variant, QTransform());
       
  4294         QCOMPARE(tester.oldValues.last(), variant);
       
  4295         QCOMPARE(tester.transform(), QTransform().rotate(90));
       
  4296     }
       
  4297     {
       
  4298         // ItemPositionChange / ItemPositionHasChanged
       
  4299         tester.itemChangeReturnValue = QPointF(42, 0);
       
  4300         tester.setPos(0, 42);
       
  4301         ++changeCount; // notification sent too
       
  4302         ++changeCount;
       
  4303         QCOMPARE(tester.changes.size(), changeCount);
       
  4304         QCOMPARE(tester.changes.at(tester.changes.size() - 2), QGraphicsItem::ItemPositionChange);
       
  4305         QCOMPARE(tester.changes.at(tester.changes.size() - 1), QGraphicsItem::ItemPositionHasChanged);
       
  4306         QCOMPARE(tester.values.at(tester.changes.size() - 2), QVariant(QPointF(0, 42)));
       
  4307         QCOMPARE(tester.values.at(tester.changes.size() - 1), QVariant(QPointF(42, 0)));
       
  4308         QCOMPARE(tester.oldValues.last(), QVariant(QPointF()));
       
  4309         QCOMPARE(tester.pos(), QPointF(42, 0));
       
  4310     }
       
  4311     {
       
  4312         // ItemZValueChange / ItemZValueHasChanged
       
  4313         tester.itemChangeReturnValue = qreal(2.0);
       
  4314         tester.setZValue(1.0);
       
  4315         ++changeCount; // notification sent too
       
  4316         ++changeCount;
       
  4317         QCOMPARE(tester.changes.size(), changeCount);
       
  4318         QCOMPARE(tester.changes.at(tester.changes.size() - 2), QGraphicsItem::ItemZValueChange);
       
  4319         QCOMPARE(tester.changes.at(tester.changes.size() - 1), QGraphicsItem::ItemZValueHasChanged);
       
  4320         QCOMPARE(tester.values.at(tester.changes.size() - 2), QVariant(qreal(1.0)));
       
  4321         QCOMPARE(tester.values.at(tester.changes.size() - 1), QVariant(qreal(2.0)));
       
  4322         QCOMPARE(tester.oldValues.last(), QVariant(qreal(0.0)));
       
  4323         QCOMPARE(tester.zValue(), qreal(2.0));
       
  4324     }
       
  4325     {
       
  4326         // ItemFlagsChange
       
  4327         tester.itemChangeReturnValue = QGraphicsItem::ItemIsSelectable;
       
  4328         tester.setFlag(QGraphicsItem::ItemIsSelectable, false);
       
  4329         QCOMPARE(tester.changes.size(), changeCount);  // No change
       
  4330         tester.setFlag(QGraphicsItem::ItemIsSelectable, true);
       
  4331         ++changeCount;
       
  4332         ++changeCount; // ItemFlagsHasChanged
       
  4333         QCOMPARE(tester.changes.size(), changeCount);
       
  4334         QCOMPARE(tester.changes.at(tester.changes.size() - 2), QGraphicsItem::ItemFlagsChange);
       
  4335         QCOMPARE(tester.changes.at(tester.changes.size() - 1), QGraphicsItem::ItemFlagsHaveChanged);
       
  4336         QVariant expectedFlags = qVariantFromValue<quint32>(QGraphicsItem::GraphicsItemFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges));
       
  4337         QCOMPARE(tester.values.at(tester.values.size() - 2), expectedFlags);
       
  4338         QCOMPARE(tester.values.at(tester.values.size() - 1), qVariantFromValue<quint32>(QGraphicsItem::ItemIsSelectable));
       
  4339     }
       
  4340     {
       
  4341         // ItemSelectedChange
       
  4342         tester.setSelected(false);
       
  4343         QCOMPARE(tester.changes.size(), changeCount); // No change :-)
       
  4344         tester.itemChangeReturnValue = true;
       
  4345         tester.setSelected(true);
       
  4346         ++changeCount;
       
  4347         ++changeCount; // ItemSelectedHasChanged
       
  4348         QCOMPARE(tester.changes.size(), changeCount);
       
  4349         QCOMPARE(tester.changes.at(tester.changes.size() - 2), QGraphicsItem::ItemSelectedChange);
       
  4350         QCOMPARE(tester.changes.at(tester.changes.size() - 1), QGraphicsItem::ItemSelectedHasChanged);
       
  4351         QCOMPARE(tester.values.at(tester.values.size() - 2), QVariant(true));
       
  4352         QCOMPARE(tester.values.at(tester.values.size() - 1), QVariant(true));
       
  4353         QCOMPARE(tester.oldValues.last(), QVariant(false));
       
  4354         QCOMPARE(tester.isSelected(), true);
       
  4355 
       
  4356         tester.itemChangeReturnValue = false;
       
  4357         tester.setSelected(true);
       
  4358 
       
  4359         // the value hasn't changed to the itemChange return value
       
  4360         // bacause itemChange is never called (true -> true is a noop).
       
  4361         QCOMPARE(tester.isSelected(), true);
       
  4362     }
       
  4363     {
       
  4364         // ItemVisibleChange
       
  4365         tester.itemChangeReturnValue = false;
       
  4366         QVERIFY(tester.isVisible());
       
  4367         tester.setVisible(false);
       
  4368         ++changeCount; // ItemVisibleChange
       
  4369         ++changeCount; // ItemSelectedChange
       
  4370         ++changeCount; // ItemSelectedHasChanged
       
  4371         ++changeCount; // ItemVisibleHasChanged
       
  4372         QCOMPARE(tester.changes.size(), changeCount);
       
  4373         QCOMPARE(tester.changes.at(tester.changes.size() - 4), QGraphicsItem::ItemVisibleChange);
       
  4374         QCOMPARE(tester.changes.at(tester.changes.size() - 3), QGraphicsItem::ItemSelectedChange);
       
  4375         QCOMPARE(tester.changes.at(tester.changes.size() - 2), QGraphicsItem::ItemSelectedHasChanged);
       
  4376         QCOMPARE(tester.changes.at(tester.changes.size() - 1), QGraphicsItem::ItemVisibleHasChanged);
       
  4377         QCOMPARE(tester.values.at(tester.values.size() - 4), QVariant(false));
       
  4378         QCOMPARE(tester.values.at(tester.values.size() - 3), QVariant(false));
       
  4379         QCOMPARE(tester.values.at(tester.values.size() - 2), QVariant(false));
       
  4380         QCOMPARE(tester.values.at(tester.values.size() - 1), QVariant(false));
       
  4381         QCOMPARE(tester.isVisible(), false);
       
  4382     }
       
  4383     {
       
  4384         // ItemParentChange
       
  4385         qVariantSetValue<QGraphicsItem *>(tester.itemChangeReturnValue, 0);
       
  4386         tester.setParentItem(&testerHelper);
       
  4387         QCOMPARE(tester.changes.size(), ++changeCount);
       
  4388         QCOMPARE(tester.changes.last(), QGraphicsItem::ItemParentChange);
       
  4389         QCOMPARE(qVariantValue<QGraphicsItem *>(tester.values.last()), (QGraphicsItem *)&testerHelper);
       
  4390         QCOMPARE(qVariantValue<QGraphicsItem *>(tester.oldValues.last()), (QGraphicsItem *)0);
       
  4391         QCOMPARE(tester.parentItem(), (QGraphicsItem *)0);
       
  4392     }
       
  4393     {
       
  4394         // ItemOpacityChange
       
  4395         tester.itemChangeReturnValue = 1.0;
       
  4396         tester.setOpacity(0.7);
       
  4397         QCOMPARE(tester.changes.size(), ++changeCount);
       
  4398         QCOMPARE(tester.changes.last(), QGraphicsItem::ItemOpacityChange);
       
  4399         QVERIFY(qFuzzyCompare(qreal(tester.values.last().toDouble()), qreal(0.7)));
       
  4400         QCOMPARE(tester.oldValues.last().toDouble(), double(1.0));
       
  4401         QCOMPARE(tester.opacity(), qreal(1.0));
       
  4402         tester.itemChangeReturnValue = 0.7;
       
  4403         tester.setOpacity(0.7);
       
  4404         ++changeCount; // ItemOpacityChange
       
  4405         ++changeCount; // ItemOpacityHasChanged
       
  4406         QCOMPARE(tester.changes.size(), changeCount);
       
  4407         QCOMPARE(tester.changes.at(tester.changes.size() - 2), QGraphicsItem::ItemOpacityChange);
       
  4408         QCOMPARE(tester.changes.at(tester.changes.size() - 1), QGraphicsItem::ItemOpacityHasChanged);
       
  4409         QCOMPARE(tester.opacity(), qreal(0.7));
       
  4410     }
       
  4411     {
       
  4412         // ItemChildAddedChange
       
  4413         tester.itemChangeReturnValue.clear();
       
  4414         testerHelper.setParentItem(&tester);
       
  4415         QCOMPARE(tester.changes.size(), ++changeCount);
       
  4416         QCOMPARE(tester.changes.last(), QGraphicsItem::ItemChildAddedChange);
       
  4417         QCOMPARE(qVariantValue<QGraphicsItem *>(tester.values.last()), (QGraphicsItem *)&testerHelper);
       
  4418     }
       
  4419     {
       
  4420         // ItemChildRemovedChange 1
       
  4421         testerHelper.setParentItem(0);
       
  4422         QCOMPARE(tester.changes.size(), ++changeCount);
       
  4423         QCOMPARE(tester.changes.last(), QGraphicsItem::ItemChildRemovedChange);
       
  4424         QCOMPARE(qVariantValue<QGraphicsItem *>(tester.values.last()), (QGraphicsItem *)&testerHelper);
       
  4425 
       
  4426         // ItemChildRemovedChange 1
       
  4427         ItemChangeTester *test = new ItemChangeTester;
       
  4428         test->itemSceneChangeTargetScene = 0;
       
  4429         int count = 0;
       
  4430         QGraphicsScene *scene = new QGraphicsScene;
       
  4431         scene->addItem(test);
       
  4432         count = test->changes.size();
       
  4433         //We test here the fact that when a child is deleted the parent receive only one ItemChildRemovedChange
       
  4434         QGraphicsRectItem *child = new QGraphicsRectItem(test);
       
  4435         //We received ItemChildAddedChange
       
  4436         QCOMPARE(test->changes.size(), ++count);
       
  4437         QCOMPARE(test->changes.last(), QGraphicsItem::ItemChildAddedChange);
       
  4438         delete child;
       
  4439         child = 0;
       
  4440         QCOMPARE(test->changes.size(), ++count);
       
  4441         QCOMPARE(test->changes.last(), QGraphicsItem::ItemChildRemovedChange);
       
  4442 
       
  4443         ItemChangeTester *childTester = new ItemChangeTester(test);
       
  4444         //Changes contains all sceneHasChanged and so on, we don't want to test that
       
  4445         int childCount = childTester->changes.size();
       
  4446         //We received ItemChildAddedChange
       
  4447         QCOMPARE(test->changes.size(), ++count);
       
  4448         child = new QGraphicsRectItem(childTester);
       
  4449         //We received ItemChildAddedChange
       
  4450         QCOMPARE(childTester->changes.size(), ++childCount);
       
  4451         QCOMPARE(childTester->changes.last(), QGraphicsItem::ItemChildAddedChange);
       
  4452         //Delete the child of the top level with all its children
       
  4453         delete childTester;
       
  4454         //Only one removal
       
  4455         QCOMPARE(test->changes.size(), ++count);
       
  4456         QCOMPARE(test->changes.last(), QGraphicsItem::ItemChildRemovedChange);
       
  4457         delete scene;
       
  4458     }
       
  4459     {
       
  4460         // ItemChildRemovedChange 2
       
  4461         ItemChangeTester parent;
       
  4462         ItemChangeTester *child = new ItemChangeTester;
       
  4463         child->setParentItem(&parent);
       
  4464         QCOMPARE(parent.changes.last(), QGraphicsItem::ItemChildAddedChange);
       
  4465         QCOMPARE(qVariantValue<QGraphicsItem *>(parent.values.last()), (QGraphicsItem *)child);
       
  4466         delete child;
       
  4467         QCOMPARE(parent.changes.last(), QGraphicsItem::ItemChildRemovedChange);
       
  4468         QCOMPARE(qVariantValue<QGraphicsItem *>(parent.values.last()), (QGraphicsItem *)child);
       
  4469     }
       
  4470     {
       
  4471         // !!! Note: If this test crashes because of double-deletion, there's
       
  4472         // a bug somewhere in QGraphicsScene or QGraphicsItem.
       
  4473 
       
  4474         // ItemSceneChange
       
  4475         QGraphicsScene scene;
       
  4476         QGraphicsScene scene2;
       
  4477         scene.addItem(&tester);
       
  4478         ++changeCount; // ItemSceneChange (scene)
       
  4479         ++changeCount; // ItemSceneHasChanged (scene)
       
  4480         QCOMPARE(tester.changes.size(), changeCount);
       
  4481 
       
  4482         QCOMPARE(tester.scene(), &scene);
       
  4483         QCOMPARE(tester.changes.at(tester.changes.size() - 2), QGraphicsItem::ItemSceneChange);
       
  4484         QCOMPARE(tester.changes.at(tester.changes.size() - 1), QGraphicsItem::ItemSceneHasChanged);
       
  4485         // Item's old value was 0
       
  4486         // Item's current value is scene
       
  4487         QCOMPARE(qVariantValue<QGraphicsScene *>(tester.oldValues.last()), (QGraphicsScene *)0);
       
  4488         QCOMPARE(qVariantValue<QGraphicsScene *>(tester.values.last()), (QGraphicsScene *)&scene);
       
  4489         scene2.addItem(&tester);
       
  4490         ++changeCount; // ItemSceneChange (0) was: (scene)
       
  4491         ++changeCount; // ItemSceneHasChanged (0)
       
  4492         ++changeCount; // ItemSceneChange (scene2) was: (0)
       
  4493         ++changeCount; // ItemSceneHasChanged (scene2)
       
  4494         QCOMPARE(tester.changes.size(), changeCount);
       
  4495 
       
  4496         QCOMPARE(tester.scene(), &scene2);
       
  4497         QCOMPARE(tester.changes.at(tester.changes.size() - 4), QGraphicsItem::ItemSceneChange);
       
  4498         QCOMPARE(tester.changes.at(tester.changes.size() - 3), QGraphicsItem::ItemSceneHasChanged);
       
  4499         QCOMPARE(tester.changes.at(tester.changes.size() - 2), QGraphicsItem::ItemSceneChange);
       
  4500         QCOMPARE(tester.changes.at(tester.changes.size() - 1), QGraphicsItem::ItemSceneHasChanged);
       
  4501         // Item's last old value was scene
       
  4502         // Item's last current value is 0
       
  4503 
       
  4504         QCOMPARE(qVariantValue<QGraphicsScene *>(tester.oldValues.at(tester.oldValues.size() - 2)), (QGraphicsScene *)&scene);
       
  4505         QCOMPARE(qVariantValue<QGraphicsScene *>(tester.oldValues.at(tester.oldValues.size() - 1)), (QGraphicsScene *)0);
       
  4506         QCOMPARE(qVariantValue<QGraphicsScene *>(tester.values.at(tester.values.size() - 4)), (QGraphicsScene *)0);
       
  4507         QCOMPARE(qVariantValue<QGraphicsScene *>(tester.values.at(tester.values.size() - 3)), (QGraphicsScene *)0);
       
  4508         QCOMPARE(qVariantValue<QGraphicsScene *>(tester.values.at(tester.values.size() - 2)), (QGraphicsScene *)&scene2);
       
  4509         QCOMPARE(qVariantValue<QGraphicsScene *>(tester.values.at(tester.values.size() - 1)), (QGraphicsScene *)&scene2);
       
  4510         // Item's last old value was 0
       
  4511         // Item's last current value is scene2
       
  4512         QCOMPARE(qVariantValue<QGraphicsScene *>(tester.oldValues.last()), (QGraphicsScene *)0);
       
  4513         QCOMPARE(qVariantValue<QGraphicsScene *>(tester.values.last()), (QGraphicsScene *)&scene2);
       
  4514 
       
  4515         scene2.removeItem(&tester);
       
  4516         ++changeCount; // ItemSceneChange (0) was: (scene2)
       
  4517         ++changeCount; // ItemSceneHasChanged (0)
       
  4518         QCOMPARE(tester.changes.size(), changeCount);
       
  4519 
       
  4520         QCOMPARE(tester.scene(), (QGraphicsScene *)0);
       
  4521         QCOMPARE(tester.changes.at(tester.changes.size() - 2), QGraphicsItem::ItemSceneChange);
       
  4522         QCOMPARE(tester.changes.at(tester.changes.size() - 1), QGraphicsItem::ItemSceneHasChanged);
       
  4523         // Item's last old value was scene2
       
  4524         // Item's last current value is 0
       
  4525         QCOMPARE(qVariantValue<QGraphicsScene *>(tester.oldValues.last()), (QGraphicsScene *)&scene2);
       
  4526         QCOMPARE(qVariantValue<QGraphicsScene *>(tester.values.at(tester.values.size() - 2)), (QGraphicsScene *)0);
       
  4527         QCOMPARE(qVariantValue<QGraphicsScene *>(tester.values.at(tester.values.size() - 1)), (QGraphicsScene *)0);
       
  4528 
       
  4529         tester.itemSceneChangeTargetScene = &scene;
       
  4530         scene2.addItem(&tester);
       
  4531         ++changeCount; // ItemSceneChange (scene2) was: (0)
       
  4532         ++changeCount; // ItemSceneChange (scene) was: (0)
       
  4533         ++changeCount; // ItemSceneHasChanged (scene)
       
  4534         QCOMPARE(tester.values.size(), changeCount);
       
  4535 
       
  4536         QCOMPARE(qVariantValue<QGraphicsScene *>(tester.values.at(tester.values.size() - 3)), (QGraphicsScene *)&scene2);
       
  4537         QCOMPARE(qVariantValue<QGraphicsScene *>(tester.values.at(tester.values.size() - 2)), (QGraphicsScene *)&scene);
       
  4538         QCOMPARE(qVariantValue<QGraphicsScene *>(tester.values.at(tester.values.size() - 1)), (QGraphicsScene *)&scene);
       
  4539 
       
  4540         QCOMPARE(tester.scene(), &scene);
       
  4541         tester.itemSceneChangeTargetScene = 0;
       
  4542         tester.itemChangeReturnValue = QVariant();
       
  4543         scene.removeItem(&tester);
       
  4544         ++changeCount; // ItemSceneChange
       
  4545         ++changeCount; // ItemSceneHasChanged
       
  4546         QCOMPARE(tester.scene(), (QGraphicsScene *)0);
       
  4547     }
       
  4548     {
       
  4549         // ItemToolTipChange/ItemToolTipHasChanged
       
  4550         const QString toolTip(QLatin1String("I'm soo cool"));
       
  4551         const QString overridenToolTip(QLatin1String("No, you are not soo cool"));
       
  4552         tester.itemChangeReturnValue = overridenToolTip;
       
  4553         tester.setToolTip(toolTip);
       
  4554         ++changeCount; // ItemToolTipChange
       
  4555         ++changeCount; // ItemToolTipHasChanged
       
  4556         QCOMPARE(tester.changes.size(), changeCount);
       
  4557         QCOMPARE(tester.changes.at(changeCount - 2), QGraphicsItem::ItemToolTipChange);
       
  4558         QCOMPARE(tester.values.at(changeCount - 2).toString(), toolTip);
       
  4559         QCOMPARE(tester.changes.at(changeCount - 1), QGraphicsItem::ItemToolTipHasChanged);
       
  4560         QCOMPARE(tester.values.at(changeCount - 1).toString(), overridenToolTip);
       
  4561         QCOMPARE(tester.toolTip(), overridenToolTip);
       
  4562         tester.itemChangeReturnValue = QVariant();
       
  4563     }
       
  4564 }
       
  4565 
       
  4566 class EventFilterTesterItem : public QGraphicsLineItem
       
  4567 {
       
  4568 public:
       
  4569     QList<QEvent::Type> filteredEvents;
       
  4570     QList<QGraphicsItem *> filteredEventReceivers;
       
  4571     bool handlesSceneEvents;
       
  4572 
       
  4573     QList<QEvent::Type> receivedEvents;
       
  4574 
       
  4575     EventFilterTesterItem() : handlesSceneEvents(false) {}
       
  4576 
       
  4577 protected:
       
  4578     bool sceneEventFilter(QGraphicsItem *watched, QEvent *event)
       
  4579     {
       
  4580         filteredEvents << event->type();
       
  4581         filteredEventReceivers << watched;
       
  4582         return handlesSceneEvents;
       
  4583     }
       
  4584 
       
  4585     bool sceneEvent(QEvent *event)
       
  4586     {
       
  4587         return QGraphicsLineItem::sceneEvent(event);
       
  4588     }
       
  4589 };
       
  4590 
       
  4591 void tst_QGraphicsItem::sceneEventFilter()
       
  4592 {
       
  4593     QGraphicsScene scene;
       
  4594 
       
  4595     QGraphicsView view(&scene);
       
  4596     view.show();
       
  4597     QApplication::setActiveWindow(&view);
       
  4598     QTest::qWaitForWindowShown(&view);
       
  4599     QTest::qWait(25);
       
  4600 
       
  4601     QGraphicsTextItem *text1 = scene.addText(QLatin1String("Text1"));
       
  4602     QGraphicsTextItem *text2 = scene.addText(QLatin1String("Text2"));
       
  4603     QGraphicsTextItem *text3 = scene.addText(QLatin1String("Text3"));
       
  4604     text1->setFlag(QGraphicsItem::ItemIsFocusable);
       
  4605     text2->setFlag(QGraphicsItem::ItemIsFocusable);
       
  4606     text3->setFlag(QGraphicsItem::ItemIsFocusable);
       
  4607 
       
  4608     EventFilterTesterItem *tester = new EventFilterTesterItem;
       
  4609     scene.addItem(tester);
       
  4610 
       
  4611     QTRY_VERIFY(!text1->hasFocus());
       
  4612     text1->installSceneEventFilter(tester);
       
  4613     text1->setFocus();
       
  4614     QTRY_VERIFY(text1->hasFocus());
       
  4615 
       
  4616     QCOMPARE(tester->filteredEvents.size(), 1);
       
  4617     QCOMPARE(tester->filteredEvents.at(0), QEvent::FocusIn);
       
  4618     QCOMPARE(tester->filteredEventReceivers.at(0), static_cast<QGraphicsItem *>(text1));
       
  4619 
       
  4620     text2->installSceneEventFilter(tester);
       
  4621     text3->installSceneEventFilter(tester);
       
  4622 
       
  4623     text2->setFocus();
       
  4624     text3->setFocus();
       
  4625 
       
  4626     QCOMPARE(tester->filteredEvents.size(), 5);
       
  4627     QCOMPARE(tester->filteredEvents.at(1), QEvent::FocusOut);
       
  4628     QCOMPARE(tester->filteredEventReceivers.at(1), static_cast<QGraphicsItem *>(text1));
       
  4629     QCOMPARE(tester->filteredEvents.at(2), QEvent::FocusIn);
       
  4630     QCOMPARE(tester->filteredEventReceivers.at(2), static_cast<QGraphicsItem *>(text2));
       
  4631     QCOMPARE(tester->filteredEvents.at(3), QEvent::FocusOut);
       
  4632     QCOMPARE(tester->filteredEventReceivers.at(3), static_cast<QGraphicsItem *>(text2));
       
  4633     QCOMPARE(tester->filteredEvents.at(4), QEvent::FocusIn);
       
  4634     QCOMPARE(tester->filteredEventReceivers.at(4), static_cast<QGraphicsItem *>(text3));
       
  4635 
       
  4636     text1->removeSceneEventFilter(tester);
       
  4637     text1->setFocus();
       
  4638 
       
  4639     QCOMPARE(tester->filteredEvents.size(), 6);
       
  4640     QCOMPARE(tester->filteredEvents.at(5), QEvent::FocusOut);
       
  4641     QCOMPARE(tester->filteredEventReceivers.at(5), static_cast<QGraphicsItem *>(text3));
       
  4642 
       
  4643     tester->handlesSceneEvents = true;
       
  4644     text2->setFocus();
       
  4645 
       
  4646     QCOMPARE(tester->filteredEvents.size(), 7);
       
  4647     QCOMPARE(tester->filteredEvents.at(6), QEvent::FocusIn);
       
  4648     QCOMPARE(tester->filteredEventReceivers.at(6), static_cast<QGraphicsItem *>(text2));
       
  4649 
       
  4650     QVERIFY(text2->hasFocus());
       
  4651 
       
  4652     //Let check if the items are correctly removed from the sceneEventFilters array
       
  4653     //to avoid stale pointers.
       
  4654     QGraphicsView gv;
       
  4655     QGraphicsScene *anotherScene = new QGraphicsScene;
       
  4656     QGraphicsTextItem *ti = anotherScene->addText("This is a test #1");
       
  4657     ti->moveBy(50, 50);
       
  4658     QGraphicsTextItem *ti2 = anotherScene->addText("This is a test #2");
       
  4659     QGraphicsTextItem *ti3 = anotherScene->addText("This is a test #3");
       
  4660     gv.setScene(anotherScene);
       
  4661     gv.show();
       
  4662     QTest::qWaitForWindowShown(&gv);
       
  4663     QTest::qWait(25);
       
  4664     ti->installSceneEventFilter(ti2);
       
  4665     ti3->installSceneEventFilter(ti);
       
  4666     delete ti2;
       
  4667     //we souldn't crash
       
  4668     QTest::mouseMove(gv.viewport(), gv.mapFromScene(ti->scenePos()));
       
  4669     QTest::qWait(30);
       
  4670     delete ti;
       
  4671 }
       
  4672 
       
  4673 class GeometryChanger : public QGraphicsItem
       
  4674 {
       
  4675 public:
       
  4676     void changeGeometry()
       
  4677     { prepareGeometryChange(); }
       
  4678 };
       
  4679 
       
  4680 void tst_QGraphicsItem::prepareGeometryChange()
       
  4681 {
       
  4682     {
       
  4683         QGraphicsScene scene;
       
  4684         QGraphicsItem *item = scene.addRect(QRectF(0, 0, 100, 100));
       
  4685         QVERIFY(scene.items(QRectF(0, 0, 100, 100)).contains(item));
       
  4686         ((GeometryChanger *)item)->changeGeometry();
       
  4687         QVERIFY(scene.items(QRectF(0, 0, 100, 100)).contains(item));
       
  4688     }
       
  4689 }
       
  4690 
       
  4691 
       
  4692 class PaintTester : public QGraphicsRectItem
       
  4693 {
       
  4694 public:
       
  4695     PaintTester() : widget(NULL), painted(0) { setRect(QRectF(10, 10, 20, 20));}
       
  4696 
       
  4697     void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *w)
       
  4698     {
       
  4699         widget = w;
       
  4700         painted++;
       
  4701     }
       
  4702 
       
  4703     QWidget*  widget;
       
  4704     int painted;
       
  4705 };
       
  4706 
       
  4707 void tst_QGraphicsItem::paint()
       
  4708 {
       
  4709     QGraphicsScene scene;
       
  4710 
       
  4711     PaintTester paintTester;
       
  4712     scene.addItem(&paintTester);
       
  4713 
       
  4714     QGraphicsView view(&scene);
       
  4715 
       
  4716     view.show();
       
  4717     QTest::qWaitForWindowShown(&view);
       
  4718     QApplication::processEvents();
       
  4719 #ifdef Q_OS_WIN32
       
  4720     //we try to switch the desktop: if it fails, we skip the test
       
  4721     if (::SwitchDesktop( ::GetThreadDesktop( ::GetCurrentThreadId() ) ) == 0) {
       
  4722         QSKIP("The Graphics View doesn't get the paint events", SkipSingle);
       
  4723     }
       
  4724 #endif
       
  4725 
       
  4726     QTRY_COMPARE(paintTester.widget, view.viewport());
       
  4727 
       
  4728     view.hide();
       
  4729 
       
  4730     QGraphicsScene scene2;
       
  4731     QGraphicsView view2(&scene2);
       
  4732     view2.show();
       
  4733     QTest::qWaitForWindowShown(&view2);
       
  4734     QTest::qWait(25);
       
  4735 
       
  4736     PaintTester tester2;
       
  4737     scene2.addItem(&tester2);
       
  4738     qApp->processEvents();
       
  4739 
       
  4740     //First show one paint
       
  4741     QTRY_COMPARE(tester2.painted, 1);
       
  4742 
       
  4743     //nominal case, update call paint
       
  4744     tester2.update();
       
  4745     qApp->processEvents();
       
  4746     QTRY_VERIFY(tester2.painted == 2);
       
  4747 
       
  4748     //we remove the item from the scene, number of updates is still the same
       
  4749     tester2.update();
       
  4750     scene2.removeItem(&tester2);
       
  4751     qApp->processEvents();
       
  4752     QTRY_VERIFY(tester2.painted == 2);
       
  4753 
       
  4754     //We re-add the item, the number of paint should increase
       
  4755     scene2.addItem(&tester2);
       
  4756     tester2.update();
       
  4757     qApp->processEvents();
       
  4758     QTRY_VERIFY(tester2.painted == 3);
       
  4759 }
       
  4760 
       
  4761 class HarakiriItem : public QGraphicsRectItem
       
  4762 {
       
  4763 public:
       
  4764     HarakiriItem(int harakiriPoint)
       
  4765         : QGraphicsRectItem(QRectF(0, 0, 100, 100)), harakiri(harakiriPoint)
       
  4766     { dead = 0; }
       
  4767 
       
  4768     static int dead;
       
  4769 
       
  4770     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
       
  4771     {
       
  4772         QGraphicsRectItem::paint(painter, option, widget);
       
  4773         if (harakiri == 0) {
       
  4774             // delete unsupported since 4.5
       
  4775             /*
       
  4776             dead = 1;
       
  4777             delete this;
       
  4778             */
       
  4779         }
       
  4780     }
       
  4781 
       
  4782     void advance(int n)
       
  4783     {
       
  4784         if (harakiri == 1 && n == 0) {
       
  4785             // delete unsupported
       
  4786             /*
       
  4787             dead = 1;
       
  4788             delete this;
       
  4789             */
       
  4790         }
       
  4791         if (harakiri == 2 && n == 1) {
       
  4792             dead = 1;
       
  4793             delete this;
       
  4794         }
       
  4795     }
       
  4796 
       
  4797 protected:
       
  4798     void contextMenuEvent(QGraphicsSceneContextMenuEvent *)
       
  4799     {
       
  4800         if (harakiri == 3) {
       
  4801             dead = 1;
       
  4802             delete this;
       
  4803         }
       
  4804     }
       
  4805 
       
  4806     void dragEnterEvent(QGraphicsSceneDragDropEvent *event)
       
  4807     {
       
  4808         // ??
       
  4809         QGraphicsRectItem::dragEnterEvent(event);
       
  4810     }
       
  4811 
       
  4812     void dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
       
  4813     {
       
  4814         // ??
       
  4815         QGraphicsRectItem::dragLeaveEvent(event);
       
  4816     }
       
  4817 
       
  4818     void dragMoveEvent(QGraphicsSceneDragDropEvent *event)
       
  4819     {
       
  4820         // ??
       
  4821         QGraphicsRectItem::dragMoveEvent(event);
       
  4822     }
       
  4823 
       
  4824     void dropEvent(QGraphicsSceneDragDropEvent *event)
       
  4825     {
       
  4826         // ??
       
  4827         QGraphicsRectItem::dropEvent(event);
       
  4828     }
       
  4829 
       
  4830     void focusInEvent(QFocusEvent *)
       
  4831     {
       
  4832         if (harakiri == 4) {
       
  4833             dead = 1;
       
  4834             delete this;
       
  4835         }
       
  4836     }
       
  4837 
       
  4838     void focusOutEvent(QFocusEvent *)
       
  4839     {
       
  4840         if (harakiri == 5) {
       
  4841             dead = 1;
       
  4842             delete this;
       
  4843         }
       
  4844     }
       
  4845 
       
  4846     void hoverEnterEvent(QGraphicsSceneHoverEvent *)
       
  4847     {
       
  4848         if (harakiri == 6) {
       
  4849             dead = 1;
       
  4850             delete this;
       
  4851         }
       
  4852     }
       
  4853 
       
  4854     void hoverLeaveEvent(QGraphicsSceneHoverEvent *)
       
  4855     {
       
  4856         if (harakiri == 7) {
       
  4857             dead = 1;
       
  4858             delete this;
       
  4859         }
       
  4860     }
       
  4861 
       
  4862     void hoverMoveEvent(QGraphicsSceneHoverEvent *)
       
  4863     {
       
  4864         if (harakiri == 8) {
       
  4865             dead = 1;
       
  4866             delete this;
       
  4867         }
       
  4868     }
       
  4869 
       
  4870     void inputMethodEvent(QInputMethodEvent *event)
       
  4871     {
       
  4872         // ??
       
  4873         QGraphicsRectItem::inputMethodEvent(event);
       
  4874     }
       
  4875 
       
  4876     QVariant inputMethodQuery(Qt::InputMethodQuery query) const
       
  4877     {
       
  4878         // ??
       
  4879         return QGraphicsRectItem::inputMethodQuery(query);
       
  4880     }
       
  4881 
       
  4882     QVariant itemChange(GraphicsItemChange change, const QVariant &value)
       
  4883     {
       
  4884         // deletion not supported
       
  4885         return QGraphicsRectItem::itemChange(change, value);
       
  4886     }
       
  4887 
       
  4888     void keyPressEvent(QKeyEvent *)
       
  4889     {
       
  4890         if (harakiri == 9) {
       
  4891             dead = 1;
       
  4892             delete this;
       
  4893         }
       
  4894     }
       
  4895 
       
  4896     void keyReleaseEvent(QKeyEvent *)
       
  4897     {
       
  4898         if (harakiri == 10) {
       
  4899             dead = 1;
       
  4900             delete this;
       
  4901         }
       
  4902     }
       
  4903 
       
  4904     void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *)
       
  4905     {
       
  4906         if (harakiri == 11) {
       
  4907             dead = 1;
       
  4908             delete this;
       
  4909         }
       
  4910     }
       
  4911 
       
  4912     void mouseMoveEvent(QGraphicsSceneMouseEvent *)
       
  4913     {
       
  4914         if (harakiri == 12) {
       
  4915             dead = 1;
       
  4916             delete this;
       
  4917         }
       
  4918     }
       
  4919 
       
  4920     void mousePressEvent(QGraphicsSceneMouseEvent *)
       
  4921     {
       
  4922         if (harakiri == 13) {
       
  4923             dead = 1;
       
  4924             delete this;
       
  4925         }
       
  4926     }
       
  4927 
       
  4928     void mouseReleaseEvent(QGraphicsSceneMouseEvent *)
       
  4929     {
       
  4930         if (harakiri == 14) {
       
  4931             dead = 1;
       
  4932             delete this;
       
  4933         }
       
  4934     }
       
  4935 
       
  4936     bool sceneEvent(QEvent *event)
       
  4937     {
       
  4938         // deletion not supported
       
  4939         return QGraphicsRectItem::sceneEvent(event);
       
  4940     }
       
  4941 
       
  4942     bool sceneEventFilter(QGraphicsItem *watched, QEvent *event)
       
  4943     {
       
  4944         // deletion not supported
       
  4945         return QGraphicsRectItem::sceneEventFilter(watched, event);
       
  4946     }
       
  4947 
       
  4948     void wheelEvent(QGraphicsSceneWheelEvent *)
       
  4949     {
       
  4950         if (harakiri == 16) {
       
  4951             dead = 1;
       
  4952             delete this;
       
  4953         }
       
  4954     }
       
  4955 
       
  4956 private:
       
  4957     int harakiri;
       
  4958 };
       
  4959 
       
  4960 int HarakiriItem::dead;
       
  4961 
       
  4962 void tst_QGraphicsItem::deleteItemInEventHandlers()
       
  4963 {
       
  4964     for (int i = 0; i < 17; ++i) {
       
  4965         QGraphicsScene scene;
       
  4966         HarakiriItem *item = new HarakiriItem(i);
       
  4967         item->setAcceptsHoverEvents(true);
       
  4968         item->setFlag(QGraphicsItem::ItemIsFocusable);
       
  4969 
       
  4970         scene.addItem(item);
       
  4971 
       
  4972         item->installSceneEventFilter(item); // <- ehey!
       
  4973 
       
  4974         QGraphicsView view(&scene);
       
  4975         view.show();
       
  4976 
       
  4977         qApp->processEvents();
       
  4978         qApp->processEvents();
       
  4979 
       
  4980         if (!item->dead)
       
  4981             scene.advance();
       
  4982 
       
  4983         if (!item->dead) {
       
  4984             QContextMenuEvent event(QContextMenuEvent::Other,
       
  4985                                     view.mapFromScene(item->scenePos()));
       
  4986             QCoreApplication::sendEvent(view.viewport(), &event);
       
  4987         }
       
  4988         if (!item->dead)
       
  4989             QTest::mouseMove(view.viewport(), view.mapFromScene(item->scenePos()));
       
  4990         if (!item->dead)
       
  4991             QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(item->scenePos()));
       
  4992         if (!item->dead)
       
  4993             QTest::mouseDClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(item->scenePos()));
       
  4994         if (!item->dead)
       
  4995             QTest::mouseClick(view.viewport(), Qt::RightButton, 0, view.mapFromScene(item->scenePos()));
       
  4996         if (!item->dead)
       
  4997             QTest::mouseMove(view.viewport(), view.mapFromScene(item->scenePos() + QPointF(20, -20)));
       
  4998         if (!item->dead)
       
  4999             item->setFocus();
       
  5000         if (!item->dead)
       
  5001             item->clearFocus();
       
  5002         if (!item->dead)
       
  5003             item->setFocus();
       
  5004         if (!item->dead)
       
  5005             QTest::keyPress(view.viewport(), Qt::Key_A);
       
  5006         if (!item->dead)
       
  5007             QTest::keyRelease(view.viewport(), Qt::Key_A);
       
  5008         if (!item->dead)
       
  5009             QTest::keyPress(view.viewport(), Qt::Key_A);
       
  5010         if (!item->dead)
       
  5011             QTest::keyRelease(view.viewport(), Qt::Key_A);
       
  5012     }
       
  5013 }
       
  5014 
       
  5015 class ItemPaintsOutsideShape : public QGraphicsItem
       
  5016 {
       
  5017 public:
       
  5018     QRectF boundingRect() const
       
  5019     {
       
  5020         return QRectF(0, 0, 100, 100);
       
  5021     }
       
  5022 
       
  5023     void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
       
  5024     {
       
  5025         painter->fillRect(-50, -50, 200, 200, Qt::red);
       
  5026         painter->fillRect(0, 0, 100, 100, Qt::blue);
       
  5027     }
       
  5028 };
       
  5029 
       
  5030 void tst_QGraphicsItem::itemClipsToShape()
       
  5031 {
       
  5032     QGraphicsItem *clippedItem = new ItemPaintsOutsideShape;
       
  5033     clippedItem->setFlag(QGraphicsItem::ItemClipsToShape);
       
  5034 
       
  5035     QGraphicsItem *unclippedItem = new ItemPaintsOutsideShape;
       
  5036     unclippedItem->setPos(200, 0);
       
  5037 
       
  5038     QGraphicsScene scene(-50, -50, 400, 200);
       
  5039     scene.addItem(clippedItem);
       
  5040     scene.addItem(unclippedItem);
       
  5041 
       
  5042     QImage image(400, 200, QImage::Format_ARGB32_Premultiplied);
       
  5043     image.fill(0);
       
  5044     QPainter painter(&image);
       
  5045     painter.setRenderHint(QPainter::Antialiasing);
       
  5046     scene.render(&painter);
       
  5047     painter.end();
       
  5048 
       
  5049     QCOMPARE(image.pixel(45, 100), QRgb(0));
       
  5050     QCOMPARE(image.pixel(100, 45), QRgb(0));
       
  5051     QCOMPARE(image.pixel(155, 100), QRgb(0));
       
  5052     QCOMPARE(image.pixel(45, 155), QRgb(0));
       
  5053     QCOMPARE(image.pixel(55, 100), QColor(Qt::blue).rgba());
       
  5054     QCOMPARE(image.pixel(100, 55), QColor(Qt::blue).rgba());
       
  5055     QCOMPARE(image.pixel(145, 100), QColor(Qt::blue).rgba());
       
  5056     QCOMPARE(image.pixel(55, 145), QColor(Qt::blue).rgba());
       
  5057     QCOMPARE(image.pixel(245, 100), QColor(Qt::red).rgba());
       
  5058     QCOMPARE(image.pixel(300, 45), QColor(Qt::red).rgba());
       
  5059     QCOMPARE(image.pixel(355, 100), QColor(Qt::red).rgba());
       
  5060     QCOMPARE(image.pixel(245, 155), QColor(Qt::red).rgba());
       
  5061     QCOMPARE(image.pixel(255, 100), QColor(Qt::blue).rgba());
       
  5062     QCOMPARE(image.pixel(300, 55), QColor(Qt::blue).rgba());
       
  5063     QCOMPARE(image.pixel(345, 100), QColor(Qt::blue).rgba());
       
  5064     QCOMPARE(image.pixel(255, 145), QColor(Qt::blue).rgba());
       
  5065 }
       
  5066 
       
  5067 void tst_QGraphicsItem::itemClipsChildrenToShape()
       
  5068 {
       
  5069     QGraphicsScene scene;
       
  5070     QGraphicsItem *rect = scene.addRect(0, 0, 50, 50, QPen(Qt::NoPen), QBrush(Qt::yellow));
       
  5071 
       
  5072     QGraphicsItem *ellipse = scene.addEllipse(0, 0, 100, 100, QPen(Qt::NoPen), QBrush(Qt::green));
       
  5073     ellipse->setParentItem(rect);
       
  5074 
       
  5075     QGraphicsItem *clippedEllipse = scene.addEllipse(0, 0, 50, 50, QPen(Qt::NoPen), QBrush(Qt::blue));
       
  5076     clippedEllipse->setParentItem(ellipse);
       
  5077 
       
  5078     QGraphicsItem *clippedEllipse2 = scene.addEllipse(0, 0, 25, 25, QPen(Qt::NoPen), QBrush(Qt::red));
       
  5079     clippedEllipse2->setParentItem(clippedEllipse);
       
  5080 
       
  5081     QGraphicsItem *clippedEllipse3 = scene.addEllipse(50, 50, 25, 25, QPen(Qt::NoPen), QBrush(Qt::red));
       
  5082     clippedEllipse3->setParentItem(clippedEllipse);
       
  5083 
       
  5084     QVERIFY(!(ellipse->flags() & QGraphicsItem::ItemClipsChildrenToShape));
       
  5085     ellipse->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  5086     QVERIFY((ellipse->flags() & QGraphicsItem::ItemClipsChildrenToShape));
       
  5087 
       
  5088     QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
       
  5089     image.fill(0);
       
  5090     QPainter painter(&image);
       
  5091     painter.setRenderHint(QPainter::Antialiasing);
       
  5092     scene.render(&painter);
       
  5093     painter.end();
       
  5094 
       
  5095     QCOMPARE(image.pixel(16, 16), QColor(255, 0, 0).rgba());
       
  5096     QCOMPARE(image.pixel(32, 32), QColor(0, 0, 255).rgba());
       
  5097     QCOMPARE(image.pixel(50, 50), QColor(0, 255, 0).rgba());
       
  5098     QCOMPARE(image.pixel(12, 12), QColor(255, 255, 0).rgba());
       
  5099     QCOMPARE(image.pixel(60, 60), QColor(255, 0, 0).rgba());
       
  5100 }
       
  5101 
       
  5102 void tst_QGraphicsItem::itemClipsChildrenToShape2()
       
  5103 {
       
  5104     QGraphicsRectItem *parent = new QGraphicsRectItem(QRectF(0, 0, 10, 10));
       
  5105     QGraphicsEllipseItem *child1 = new QGraphicsEllipseItem(QRectF(50, 50, 100, 100));
       
  5106     QGraphicsRectItem *child2 = new QGraphicsRectItem(QRectF(15, 15, 80, 80));
       
  5107 
       
  5108     child1->setParentItem(parent);
       
  5109     child1->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  5110     child2->setParentItem(child1);
       
  5111 
       
  5112     parent->setBrush(Qt::blue);
       
  5113     child1->setBrush(Qt::green);
       
  5114     child2->setBrush(Qt::red);
       
  5115 
       
  5116     QGraphicsScene scene;
       
  5117     scene.addItem(parent);
       
  5118 
       
  5119     QCOMPARE(scene.itemAt(5, 5), (QGraphicsItem *)parent);
       
  5120     QCOMPARE(scene.itemAt(15, 5), (QGraphicsItem *)0);
       
  5121     QCOMPARE(scene.itemAt(5, 15), (QGraphicsItem *)0);
       
  5122     QCOMPARE(scene.itemAt(60, 60), (QGraphicsItem *)0);
       
  5123     QCOMPARE(scene.itemAt(140, 60), (QGraphicsItem *)0);
       
  5124     QCOMPARE(scene.itemAt(60, 140), (QGraphicsItem *)0);
       
  5125     QCOMPARE(scene.itemAt(140, 140), (QGraphicsItem *)0);
       
  5126     QCOMPARE(scene.itemAt(75, 75), (QGraphicsItem *)child2);
       
  5127     QCOMPARE(scene.itemAt(75, 100), (QGraphicsItem *)child1);
       
  5128     QCOMPARE(scene.itemAt(100, 75), (QGraphicsItem *)child1);
       
  5129 
       
  5130 #if 1
       
  5131     QImage image(100, 100, QImage::Format_ARGB32_Premultiplied);
       
  5132     image.fill(0);
       
  5133     QPainter painter(&image);
       
  5134     scene.render(&painter);
       
  5135     painter.end();
       
  5136 
       
  5137     QCOMPARE(image.pixel(5, 5), QColor(0, 0, 255).rgba());
       
  5138     QCOMPARE(image.pixel(5, 10), QRgb(0));
       
  5139     QCOMPARE(image.pixel(10, 5), QRgb(0));
       
  5140     QCOMPARE(image.pixel(40, 40), QRgb(0));
       
  5141     QCOMPARE(image.pixel(90, 40), QRgb(0));
       
  5142     QCOMPARE(image.pixel(40, 90), QRgb(0));
       
  5143     QCOMPARE(image.pixel(95, 95), QRgb(0));
       
  5144     QCOMPARE(image.pixel(50, 70), QColor(0, 255, 0).rgba());
       
  5145     QCOMPARE(image.pixel(70, 50), QColor(0, 255, 0).rgba());
       
  5146     QCOMPARE(image.pixel(50, 60), QColor(255, 0, 0).rgba());
       
  5147     QCOMPARE(image.pixel(60, 50), QColor(255, 0, 0).rgba());
       
  5148 #else
       
  5149     QGraphicsView view(&scene);
       
  5150     view.show();
       
  5151     QTest::qWait(5000);
       
  5152 #endif
       
  5153 }
       
  5154 
       
  5155 void tst_QGraphicsItem::itemClipsChildrenToShape3()
       
  5156 {
       
  5157     // Construct a scene with nested children, each 50 pixels offset from the elder.
       
  5158     // Set a top-level clipping flag
       
  5159     QGraphicsScene scene;
       
  5160     QGraphicsRectItem *parent = scene.addRect( 0, 0, 150, 150 );
       
  5161     QGraphicsRectItem *child = scene.addRect( 0, 0, 150, 150 );
       
  5162     QGraphicsRectItem *grandchild = scene.addRect( 0, 0, 150, 150 );
       
  5163     child->setParentItem(parent);
       
  5164     grandchild->setParentItem(child);
       
  5165     child->setPos( 50, 50 );
       
  5166     grandchild->setPos( 50, 50 );
       
  5167     parent->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  5168 
       
  5169     QCOMPARE(scene.itemAt(25,25), (QGraphicsItem *)parent);
       
  5170     QCOMPARE(scene.itemAt(75,75), (QGraphicsItem *)child);
       
  5171     QCOMPARE(scene.itemAt(125,125), (QGraphicsItem *)grandchild);
       
  5172     QCOMPARE(scene.itemAt(175,175), (QGraphicsItem *)0);
       
  5173 
       
  5174     // Move child to fully overlap the parent.  The grandchild should
       
  5175     // now occupy two-thirds of the scene
       
  5176     child->prepareGeometryChange();
       
  5177     child->setPos( 0, 0 );
       
  5178 
       
  5179     QCOMPARE(scene.itemAt(25,25), (QGraphicsItem *)child);
       
  5180     QCOMPARE(scene.itemAt(75,75), (QGraphicsItem *)grandchild);
       
  5181     QCOMPARE(scene.itemAt(125,125), (QGraphicsItem *)grandchild);
       
  5182     QCOMPARE(scene.itemAt(175,175), (QGraphicsItem *)0);
       
  5183 }
       
  5184 
       
  5185 class MyProxyWidget : public QGraphicsProxyWidget
       
  5186 {
       
  5187 public:
       
  5188     MyProxyWidget(QGraphicsItem *parent) : QGraphicsProxyWidget(parent)
       
  5189     {
       
  5190         painted = false;
       
  5191     }
       
  5192 
       
  5193     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
       
  5194     {
       
  5195         QGraphicsProxyWidget::paint(painter, option, widget);
       
  5196         painted = true;
       
  5197     }
       
  5198     bool painted;
       
  5199 };
       
  5200 
       
  5201 void tst_QGraphicsItem::itemClipsChildrenToShape4()
       
  5202 {
       
  5203     QGraphicsScene scene;
       
  5204     QGraphicsView view(&scene);
       
  5205 
       
  5206     QGraphicsWidget * outerWidget = new QGraphicsWidget();
       
  5207     outerWidget->setFlag(QGraphicsItem::ItemClipsChildrenToShape, true);
       
  5208     MyProxyWidget * innerWidget = new MyProxyWidget(outerWidget);
       
  5209     QLabel * label = new QLabel();
       
  5210     label->setText("Welcome back my friends to the show that never ends...");
       
  5211     innerWidget->setWidget(label);
       
  5212     view.resize(300, 300);
       
  5213     scene.addItem(outerWidget);
       
  5214     outerWidget->resize( 200, 100 );
       
  5215     scene.addEllipse( 100, 100, 100, 50 );   // <-- this is important to trigger the right codepath*
       
  5216     //now the label is shown
       
  5217     outerWidget->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false );
       
  5218     QApplication::setActiveWindow(&view);
       
  5219     view.show();
       
  5220     QTRY_COMPARE(QApplication::activeWindow(), (QWidget *)&view);
       
  5221     QTRY_COMPARE(innerWidget->painted, true);
       
  5222 }
       
  5223 
       
  5224 void tst_QGraphicsItem::itemClipsTextChildToShape()
       
  5225 {
       
  5226     // Construct a scene with a rect that clips its children, with one text
       
  5227     // child that has text that exceeds the size of the rect.
       
  5228     QGraphicsScene scene;
       
  5229     QGraphicsItem *rect = scene.addRect(0, 0, 50, 50, QPen(Qt::black), Qt::black);
       
  5230     rect->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  5231     QGraphicsTextItem *text = new QGraphicsTextItem("This is a long sentence that's wider than 50 pixels.");
       
  5232     text->setParentItem(rect);
       
  5233 
       
  5234     // Render this scene to a transparent image.
       
  5235     QRectF sr = scene.itemsBoundingRect();
       
  5236     QImage image(sr.size().toSize(), QImage::Format_ARGB32_Premultiplied);
       
  5237     image.fill(0);
       
  5238     QPainter painter(&image);
       
  5239     scene.render(&painter);
       
  5240 
       
  5241     // Erase the area immediately underneath the rect.
       
  5242     painter.setCompositionMode(QPainter::CompositionMode_Source);
       
  5243     painter.fillRect(rect->sceneBoundingRect().translated(-sr.topLeft()).adjusted(-0.5, -0.5, 0.5, 0.5),
       
  5244                      Qt::transparent);
       
  5245     painter.end();
       
  5246 
       
  5247     // Check that you get a truly transparent image back (i.e., the text was
       
  5248     // clipped away, so there should be no trails left after erasing only the
       
  5249     // rect's area).
       
  5250     QImage emptyImage(scene.itemsBoundingRect().size().toSize(), QImage::Format_ARGB32_Premultiplied);
       
  5251     emptyImage.fill(0);
       
  5252     QCOMPARE(image, emptyImage);
       
  5253 }
       
  5254 
       
  5255 void tst_QGraphicsItem::itemClippingDiscovery()
       
  5256 {
       
  5257     // A simple scene with an ellipse parent and two rect children, one a
       
  5258     // child of the other.
       
  5259     QGraphicsScene scene;
       
  5260     QGraphicsEllipseItem *clipItem = scene.addEllipse(0, 0, 100, 100);
       
  5261     QGraphicsRectItem *leftRectItem = scene.addRect(0, 0, 50, 100);
       
  5262     QGraphicsRectItem *rightRectItem = scene.addRect(50, 0, 50, 100);
       
  5263     leftRectItem->setParentItem(clipItem);
       
  5264     rightRectItem->setParentItem(clipItem);
       
  5265 
       
  5266     // The rects item are both visible at these points.
       
  5267     QCOMPARE(scene.itemAt(10, 10), (QGraphicsItem *)leftRectItem);
       
  5268     QCOMPARE(scene.itemAt(90, 90), (QGraphicsItem *)rightRectItem);
       
  5269 
       
  5270     // The ellipse clips the rects now.
       
  5271     clipItem->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  5272 
       
  5273     // The rect items are no longer visible at these points.
       
  5274     QCOMPARE(scene.itemAt(10, 10), (QGraphicsItem *)0);
       
  5275     if (sizeof(qreal) != sizeof(double))
       
  5276         QSKIP("This fails due to internal rounding errors", SkipSingle);
       
  5277     QCOMPARE(scene.itemAt(90, 90), (QGraphicsItem *)0);
       
  5278 }
       
  5279 
       
  5280 void tst_QGraphicsItem::ancestorFlags()
       
  5281 {
       
  5282     QGraphicsItem *level1 = new QGraphicsRectItem;
       
  5283     QGraphicsItem *level21 = new QGraphicsRectItem;
       
  5284     level21->setParentItem(level1);
       
  5285     QGraphicsItem *level22 = new QGraphicsRectItem;
       
  5286     level22->setParentItem(level1);
       
  5287     QGraphicsItem *level31 = new QGraphicsRectItem;
       
  5288     level31->setParentItem(level21);
       
  5289     QGraphicsItem *level32 = new QGraphicsRectItem;
       
  5290     level32->setParentItem(level21);
       
  5291 
       
  5292     QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5293     QCOMPARE(int(level21->d_ptr->ancestorFlags), 0);
       
  5294     QCOMPARE(int(level22->d_ptr->ancestorFlags), 0);
       
  5295     QCOMPARE(int(level31->d_ptr->ancestorFlags), 0);
       
  5296     QCOMPARE(int(level32->d_ptr->ancestorFlags), 0);
       
  5297 
       
  5298     // HandlesChildEvents: 1) Root level sets a flag
       
  5299     level1->setHandlesChildEvents(true);
       
  5300     QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5301     QCOMPARE(int(level21->d_ptr->ancestorFlags), 1);
       
  5302     QCOMPARE(int(level22->d_ptr->ancestorFlags), 1);
       
  5303     QCOMPARE(int(level31->d_ptr->ancestorFlags), 1);
       
  5304     QCOMPARE(int(level32->d_ptr->ancestorFlags), 1);
       
  5305 
       
  5306     // HandlesChildEvents: 2) Root level set it again
       
  5307     level1->setHandlesChildEvents(true);
       
  5308     QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5309     QCOMPARE(int(level21->d_ptr->ancestorFlags), 1);
       
  5310     QCOMPARE(int(level22->d_ptr->ancestorFlags), 1);
       
  5311     QCOMPARE(int(level31->d_ptr->ancestorFlags), 1);
       
  5312     QCOMPARE(int(level32->d_ptr->ancestorFlags), 1);
       
  5313 
       
  5314     // HandlesChildEvents: 3) Root level unsets a flag
       
  5315     level1->setHandlesChildEvents(false);
       
  5316     QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5317     QCOMPARE(int(level21->d_ptr->ancestorFlags), 0);
       
  5318     QCOMPARE(int(level22->d_ptr->ancestorFlags), 0);
       
  5319     QCOMPARE(int(level31->d_ptr->ancestorFlags), 0);
       
  5320     QCOMPARE(int(level32->d_ptr->ancestorFlags), 0);
       
  5321 
       
  5322     // HandlesChildEvents: 4) Child item sets a flag
       
  5323     level21->setHandlesChildEvents(true);
       
  5324     QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5325     QCOMPARE(int(level21->d_ptr->ancestorFlags), 0);
       
  5326     QCOMPARE(int(level22->d_ptr->ancestorFlags), 0);
       
  5327     QCOMPARE(int(level31->d_ptr->ancestorFlags), 1);
       
  5328     QCOMPARE(int(level32->d_ptr->ancestorFlags), 1);
       
  5329 
       
  5330     // HandlesChildEvents: 5) Parent item sets a flag
       
  5331     level1->setHandlesChildEvents(true);
       
  5332     QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5333     QCOMPARE(int(level21->d_ptr->ancestorFlags), 1);
       
  5334     QCOMPARE(int(level22->d_ptr->ancestorFlags), 1);
       
  5335     QCOMPARE(int(level31->d_ptr->ancestorFlags), 1);
       
  5336     QCOMPARE(int(level32->d_ptr->ancestorFlags), 1);
       
  5337 
       
  5338     // HandlesChildEvents: 6) Child item unsets a flag
       
  5339     level21->setHandlesChildEvents(false);
       
  5340     QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5341     QCOMPARE(int(level21->d_ptr->ancestorFlags), 1);
       
  5342     QCOMPARE(int(level22->d_ptr->ancestorFlags), 1);
       
  5343     QCOMPARE(int(level31->d_ptr->ancestorFlags), 1);
       
  5344     QCOMPARE(int(level32->d_ptr->ancestorFlags), 1);
       
  5345 
       
  5346     // HandlesChildEvents: 7) Parent item unsets a flag
       
  5347     level21->setHandlesChildEvents(true);
       
  5348     level1->setHandlesChildEvents(false);
       
  5349     QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5350     QCOMPARE(int(level21->d_ptr->ancestorFlags), 0);
       
  5351     QCOMPARE(int(level22->d_ptr->ancestorFlags), 0);
       
  5352     QCOMPARE(int(level31->d_ptr->ancestorFlags), 1);
       
  5353     QCOMPARE(int(level32->d_ptr->ancestorFlags), 1);
       
  5354 
       
  5355     // Reparent the child to root
       
  5356     level21->setParentItem(0);
       
  5357     QCOMPARE(int(level21->d_ptr->ancestorFlags), 0);
       
  5358     QCOMPARE(int(level22->d_ptr->ancestorFlags), 0);
       
  5359     QCOMPARE(int(level31->d_ptr->ancestorFlags), 1);
       
  5360     QCOMPARE(int(level32->d_ptr->ancestorFlags), 1);
       
  5361 
       
  5362     // Reparent the child to level1 again.
       
  5363     level1->setHandlesChildEvents(true);
       
  5364     level21->setParentItem(level1);
       
  5365     QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5366     QCOMPARE(int(level21->d_ptr->ancestorFlags), 1);
       
  5367     QCOMPARE(int(level22->d_ptr->ancestorFlags), 1);
       
  5368     QCOMPARE(int(level31->d_ptr->ancestorFlags), 1);
       
  5369     QCOMPARE(int(level32->d_ptr->ancestorFlags), 1);
       
  5370 
       
  5371     // Reparenting level31 back to level1.
       
  5372     level31->setParentItem(level1);
       
  5373     QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5374     QCOMPARE(int(level21->d_ptr->ancestorFlags), 1);
       
  5375     QCOMPARE(int(level22->d_ptr->ancestorFlags), 1);
       
  5376     QCOMPARE(int(level31->d_ptr->ancestorFlags), 1);
       
  5377     QCOMPARE(int(level32->d_ptr->ancestorFlags), 1);
       
  5378 
       
  5379     // Reparenting level31 back to level21.
       
  5380     level31->setParentItem(0);
       
  5381     QCOMPARE(int(level31->d_ptr->ancestorFlags), 0);
       
  5382     level31->setParentItem(level21);
       
  5383     QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5384     QCOMPARE(int(level21->d_ptr->ancestorFlags), 1);
       
  5385     QCOMPARE(int(level22->d_ptr->ancestorFlags), 1);
       
  5386     QCOMPARE(int(level31->d_ptr->ancestorFlags), 1);
       
  5387     QCOMPARE(int(level32->d_ptr->ancestorFlags), 1);
       
  5388 
       
  5389     // Level1 doesn't handle child events
       
  5390     level1->setHandlesChildEvents(false);
       
  5391     QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5392     QCOMPARE(int(level21->d_ptr->ancestorFlags), 0);
       
  5393     QCOMPARE(int(level22->d_ptr->ancestorFlags), 0);
       
  5394     QCOMPARE(int(level31->d_ptr->ancestorFlags), 1);
       
  5395     QCOMPARE(int(level32->d_ptr->ancestorFlags), 1);
       
  5396 
       
  5397     // Nobody handles child events
       
  5398     level21->setHandlesChildEvents(false);
       
  5399 
       
  5400     for (int i = 0; i < 2; ++i) {
       
  5401         QGraphicsItem::GraphicsItemFlag flag = !i ? QGraphicsItem::ItemClipsChildrenToShape
       
  5402                                                : QGraphicsItem::ItemIgnoresTransformations;
       
  5403         int ancestorFlag = !i ? QGraphicsItemPrivate::AncestorClipsChildren
       
  5404                            : QGraphicsItemPrivate::AncestorIgnoresTransformations;
       
  5405 
       
  5406         QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5407         QCOMPARE(int(level21->d_ptr->ancestorFlags), 0);
       
  5408         QCOMPARE(int(level22->d_ptr->ancestorFlags), 0);
       
  5409         QCOMPARE(int(level31->d_ptr->ancestorFlags), 0);
       
  5410         QCOMPARE(int(level32->d_ptr->ancestorFlags), 0);
       
  5411 
       
  5412         // HandlesChildEvents: 1) Root level sets a flag
       
  5413         level1->setFlag(flag, true);
       
  5414         QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5415         QCOMPARE(int(level21->d_ptr->ancestorFlags), ancestorFlag);
       
  5416         QCOMPARE(int(level22->d_ptr->ancestorFlags), ancestorFlag);
       
  5417         QCOMPARE(int(level31->d_ptr->ancestorFlags), ancestorFlag);
       
  5418         QCOMPARE(int(level32->d_ptr->ancestorFlags), ancestorFlag);
       
  5419 
       
  5420         // HandlesChildEvents: 2) Root level set it again
       
  5421         level1->setFlag(flag, true);
       
  5422         QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5423         QCOMPARE(int(level21->d_ptr->ancestorFlags), ancestorFlag);
       
  5424         QCOMPARE(int(level22->d_ptr->ancestorFlags), ancestorFlag);
       
  5425         QCOMPARE(int(level31->d_ptr->ancestorFlags), ancestorFlag);
       
  5426         QCOMPARE(int(level32->d_ptr->ancestorFlags), ancestorFlag);
       
  5427 
       
  5428         // HandlesChildEvents: 3) Root level unsets a flag
       
  5429         level1->setFlag(flag, false);
       
  5430         QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5431         QCOMPARE(int(level21->d_ptr->ancestorFlags), 0);
       
  5432         QCOMPARE(int(level22->d_ptr->ancestorFlags), 0);
       
  5433         QCOMPARE(int(level31->d_ptr->ancestorFlags), 0);
       
  5434         QCOMPARE(int(level32->d_ptr->ancestorFlags), 0);
       
  5435 
       
  5436         // HandlesChildEvents: 4) Child item sets a flag
       
  5437         level21->setFlag(flag, true);
       
  5438         QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5439         QCOMPARE(int(level21->d_ptr->ancestorFlags), 0);
       
  5440         QCOMPARE(int(level22->d_ptr->ancestorFlags), 0);
       
  5441         QCOMPARE(int(level31->d_ptr->ancestorFlags), ancestorFlag);
       
  5442         QCOMPARE(int(level32->d_ptr->ancestorFlags), ancestorFlag);
       
  5443 
       
  5444         // HandlesChildEvents: 5) Parent item sets a flag
       
  5445         level1->setFlag(flag, true);
       
  5446         QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5447         QCOMPARE(int(level21->d_ptr->ancestorFlags), ancestorFlag);
       
  5448         QCOMPARE(int(level22->d_ptr->ancestorFlags), ancestorFlag);
       
  5449         QCOMPARE(int(level31->d_ptr->ancestorFlags), ancestorFlag);
       
  5450         QCOMPARE(int(level32->d_ptr->ancestorFlags), ancestorFlag);
       
  5451 
       
  5452         // HandlesChildEvents: 6) Child item unsets a flag
       
  5453         level21->setFlag(flag, false);
       
  5454         QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5455         QCOMPARE(int(level21->d_ptr->ancestorFlags), ancestorFlag);
       
  5456         QCOMPARE(int(level22->d_ptr->ancestorFlags), ancestorFlag);
       
  5457         QCOMPARE(int(level31->d_ptr->ancestorFlags), ancestorFlag);
       
  5458         QCOMPARE(int(level32->d_ptr->ancestorFlags), ancestorFlag);
       
  5459 
       
  5460         // HandlesChildEvents: 7) Parent item unsets a flag
       
  5461         level21->setFlag(flag, true);
       
  5462         level1->setFlag(flag, false);
       
  5463         QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5464         QCOMPARE(int(level21->d_ptr->ancestorFlags), 0);
       
  5465         QCOMPARE(int(level22->d_ptr->ancestorFlags), 0);
       
  5466         QCOMPARE(int(level31->d_ptr->ancestorFlags), ancestorFlag);
       
  5467         QCOMPARE(int(level32->d_ptr->ancestorFlags), ancestorFlag);
       
  5468 
       
  5469         // Reparent the child to root
       
  5470         level21->setParentItem(0);
       
  5471         QCOMPARE(int(level21->d_ptr->ancestorFlags), 0);
       
  5472         QCOMPARE(int(level22->d_ptr->ancestorFlags), 0);
       
  5473         QCOMPARE(int(level31->d_ptr->ancestorFlags), ancestorFlag);
       
  5474         QCOMPARE(int(level32->d_ptr->ancestorFlags), ancestorFlag);
       
  5475 
       
  5476         // Reparent the child to level1 again.
       
  5477         level1->setFlag(flag, true);
       
  5478         level21->setParentItem(level1);
       
  5479         QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5480         QCOMPARE(int(level21->d_ptr->ancestorFlags), ancestorFlag);
       
  5481         QCOMPARE(int(level22->d_ptr->ancestorFlags), ancestorFlag);
       
  5482         QCOMPARE(int(level31->d_ptr->ancestorFlags), ancestorFlag);
       
  5483         QCOMPARE(int(level32->d_ptr->ancestorFlags), ancestorFlag);
       
  5484 
       
  5485         // Reparenting level31 back to level1.
       
  5486         level31->setParentItem(level1);
       
  5487         QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5488         QCOMPARE(int(level21->d_ptr->ancestorFlags), ancestorFlag);
       
  5489         QCOMPARE(int(level22->d_ptr->ancestorFlags), ancestorFlag);
       
  5490         QCOMPARE(int(level31->d_ptr->ancestorFlags), ancestorFlag);
       
  5491         QCOMPARE(int(level32->d_ptr->ancestorFlags), ancestorFlag);
       
  5492 
       
  5493         // Reparenting level31 back to level21.
       
  5494         level31->setParentItem(0);
       
  5495         QCOMPARE(int(level31->d_ptr->ancestorFlags), 0);
       
  5496         level31->setParentItem(level21);
       
  5497         QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5498         QCOMPARE(int(level21->d_ptr->ancestorFlags), ancestorFlag);
       
  5499         QCOMPARE(int(level22->d_ptr->ancestorFlags), ancestorFlag);
       
  5500         QCOMPARE(int(level31->d_ptr->ancestorFlags), ancestorFlag);
       
  5501         QCOMPARE(int(level32->d_ptr->ancestorFlags), ancestorFlag);
       
  5502 
       
  5503         // Level1 doesn't handle child events
       
  5504         level1->setFlag(flag, false);
       
  5505         QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5506         QCOMPARE(int(level21->d_ptr->ancestorFlags), 0);
       
  5507         QCOMPARE(int(level22->d_ptr->ancestorFlags), 0);
       
  5508         QCOMPARE(int(level31->d_ptr->ancestorFlags), ancestorFlag);
       
  5509         QCOMPARE(int(level32->d_ptr->ancestorFlags), ancestorFlag);
       
  5510 
       
  5511         // Nobody handles child events
       
  5512         level21->setFlag(flag, false);
       
  5513         QCOMPARE(int(level1->d_ptr->ancestorFlags), 0);
       
  5514         QCOMPARE(int(level21->d_ptr->ancestorFlags), 0);
       
  5515         QCOMPARE(int(level22->d_ptr->ancestorFlags), 0);
       
  5516         QCOMPARE(int(level31->d_ptr->ancestorFlags), 0);
       
  5517         QCOMPARE(int(level32->d_ptr->ancestorFlags), 0);
       
  5518     }
       
  5519 
       
  5520     delete level1;
       
  5521 }
       
  5522 
       
  5523 void tst_QGraphicsItem::untransformable()
       
  5524 {
       
  5525     QGraphicsItem *item1 = new QGraphicsEllipseItem(QRectF(-50, -50, 100, 100));
       
  5526     item1->setZValue(1);
       
  5527     item1->setFlag(QGraphicsItem::ItemIgnoresTransformations);
       
  5528     item1->rotate(45);
       
  5529     ((QGraphicsEllipseItem *)item1)->setBrush(Qt::red);
       
  5530 
       
  5531     QGraphicsItem *item2 = new QGraphicsEllipseItem(QRectF(-50, -50, 100, 100));
       
  5532     item2->setParentItem(item1);
       
  5533     item2->rotate(45);
       
  5534     item2->setPos(100, 0);
       
  5535     ((QGraphicsEllipseItem *)item2)->setBrush(Qt::green);
       
  5536 
       
  5537     QGraphicsItem *item3 = new QGraphicsEllipseItem(QRectF(-50, -50, 100, 100));
       
  5538     item3->setParentItem(item2);
       
  5539     item3->setPos(100, 0);
       
  5540     ((QGraphicsEllipseItem *)item3)->setBrush(Qt::blue);
       
  5541 
       
  5542     QGraphicsScene scene(-500, -500, 1000, 1000);
       
  5543     scene.addItem(item1);
       
  5544 
       
  5545     QGraphicsView view(&scene);
       
  5546     view.resize(300, 300);
       
  5547     view.show();
       
  5548     view.scale(8, 8);
       
  5549     view.centerOn(0, 0);
       
  5550 
       
  5551 // Painting with the DiagCrossPattern is really slow on Mac
       
  5552 // when zoomed out. (The test times out). Task to fix is 155567.
       
  5553 #if !defined(Q_WS_MAC) || 1
       
  5554     view.setBackgroundBrush(QBrush(Qt::black, Qt::DiagCrossPattern));
       
  5555 #endif
       
  5556 
       
  5557     QTest::qWaitForWindowShown(&view);
       
  5558 
       
  5559     for (int i = 0; i < 10; ++i) {
       
  5560         QPoint center = view.viewport()->rect().center();
       
  5561         QCOMPARE(view.itemAt(center), item1);
       
  5562         QCOMPARE(view.itemAt(center - QPoint(40, 0)), item1);
       
  5563         QCOMPARE(view.itemAt(center - QPoint(-40, 0)), item1);
       
  5564         QCOMPARE(view.itemAt(center - QPoint(0, 40)), item1);
       
  5565         QCOMPARE(view.itemAt(center - QPoint(0, -40)), item1);
       
  5566 
       
  5567         center += QPoint(70, 70);
       
  5568         QCOMPARE(view.itemAt(center - QPoint(40, 0)), item2);
       
  5569         QCOMPARE(view.itemAt(center - QPoint(-40, 0)), item2);
       
  5570         QCOMPARE(view.itemAt(center - QPoint(0, 40)), item2);
       
  5571         QCOMPARE(view.itemAt(center - QPoint(0, -40)), item2);
       
  5572 
       
  5573         center += QPoint(0, 100);
       
  5574         QCOMPARE(view.itemAt(center - QPoint(40, 0)), item3);
       
  5575         QCOMPARE(view.itemAt(center - QPoint(-40, 0)), item3);
       
  5576         QCOMPARE(view.itemAt(center - QPoint(0, 40)), item3);
       
  5577         QCOMPARE(view.itemAt(center - QPoint(0, -40)), item3);
       
  5578 
       
  5579         view.scale(0.5, 0.5);
       
  5580         view.rotate(13);
       
  5581         view.shear(qreal(0.01), qreal(0.01));
       
  5582         view.translate(10, 10);
       
  5583         QTest::qWait(25);
       
  5584     }
       
  5585 }
       
  5586 
       
  5587 class ContextMenuItem : public QGraphicsRectItem
       
  5588 {
       
  5589 public:
       
  5590     ContextMenuItem()
       
  5591         : ignoreEvent(true), gotEvent(false), eventWasAccepted(false)
       
  5592     { }
       
  5593     bool ignoreEvent;
       
  5594     bool gotEvent;
       
  5595     bool eventWasAccepted;
       
  5596 protected:
       
  5597     void contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
       
  5598     {
       
  5599         gotEvent = true;
       
  5600         eventWasAccepted = event->isAccepted();
       
  5601         if (ignoreEvent)
       
  5602             event->ignore();
       
  5603     }
       
  5604 };
       
  5605 
       
  5606 void tst_QGraphicsItem::contextMenuEventPropagation()
       
  5607 {
       
  5608     ContextMenuItem *bottomItem = new ContextMenuItem;
       
  5609     bottomItem->setRect(0, 0, 100, 100);
       
  5610     ContextMenuItem *topItem = new ContextMenuItem;
       
  5611     topItem->setParentItem(bottomItem);
       
  5612     topItem->setRect(0, 0, 100, 100);
       
  5613 
       
  5614     QGraphicsScene scene;
       
  5615 
       
  5616     QGraphicsView view(&scene);
       
  5617     view.setAlignment(Qt::AlignLeft | Qt::AlignTop);
       
  5618     view.show();
       
  5619     view.resize(200, 200);
       
  5620     QTest::qWaitForWindowShown(&view);
       
  5621     QTest::qWait(20);
       
  5622 
       
  5623     QContextMenuEvent event(QContextMenuEvent::Mouse, QPoint(10, 10),
       
  5624                             view.viewport()->mapToGlobal(QPoint(10, 10)));
       
  5625     event.ignore();
       
  5626     QApplication::sendEvent(view.viewport(), &event);
       
  5627     QVERIFY(!event.isAccepted());
       
  5628 
       
  5629     scene.addItem(bottomItem);
       
  5630     topItem->ignoreEvent = true;
       
  5631     bottomItem->ignoreEvent = true;
       
  5632 
       
  5633     QApplication::sendEvent(view.viewport(), &event);
       
  5634     QVERIFY(!event.isAccepted());
       
  5635     QCOMPARE(topItem->gotEvent, true);
       
  5636     QCOMPARE(topItem->eventWasAccepted, true);
       
  5637     QCOMPARE(bottomItem->gotEvent, true);
       
  5638     QCOMPARE(bottomItem->eventWasAccepted, true);
       
  5639 
       
  5640     topItem->ignoreEvent = false;
       
  5641     topItem->gotEvent = false;
       
  5642     bottomItem->gotEvent = false;
       
  5643 
       
  5644     QApplication::sendEvent(view.viewport(), &event);
       
  5645     QVERIFY(event.isAccepted());
       
  5646     QCOMPARE(topItem->gotEvent, true);
       
  5647     QCOMPARE(bottomItem->gotEvent, false);
       
  5648     QCOMPARE(topItem->eventWasAccepted, true);
       
  5649 }
       
  5650 
       
  5651 void tst_QGraphicsItem::itemIsMovable()
       
  5652 {
       
  5653     QGraphicsRectItem *rect = new QGraphicsRectItem(-50, -50, 100, 100);
       
  5654     rect->setFlag(QGraphicsItem::ItemIsMovable);
       
  5655 
       
  5656     QGraphicsScene scene;
       
  5657     scene.addItem(rect);
       
  5658 
       
  5659     {
       
  5660         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
       
  5661         event.setButton(Qt::LeftButton);
       
  5662         event.setButtons(Qt::LeftButton);
       
  5663         qApp->sendEvent(&scene, &event);
       
  5664     }
       
  5665     {
       
  5666         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseMove);
       
  5667         event.setButton(Qt::LeftButton);
       
  5668         event.setButtons(Qt::LeftButton);
       
  5669         qApp->sendEvent(&scene, &event);
       
  5670     }
       
  5671     QCOMPARE(rect->pos(), QPointF(0, 0));
       
  5672     {
       
  5673         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseMove);
       
  5674         event.setButtons(Qt::LeftButton);
       
  5675         event.setScenePos(QPointF(10, 10));
       
  5676         qApp->sendEvent(&scene, &event);
       
  5677     }
       
  5678     QCOMPARE(rect->pos(), QPointF(10, 10));
       
  5679     {
       
  5680         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseMove);
       
  5681         event.setButtons(Qt::RightButton);
       
  5682         event.setScenePos(QPointF(20, 20));
       
  5683         qApp->sendEvent(&scene, &event);
       
  5684     }
       
  5685     QCOMPARE(rect->pos(), QPointF(10, 10));
       
  5686     {
       
  5687         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseMove);
       
  5688         event.setButtons(Qt::LeftButton);
       
  5689         event.setScenePos(QPointF(30, 30));
       
  5690         qApp->sendEvent(&scene, &event);
       
  5691     }
       
  5692     QCOMPARE(rect->pos(), QPointF(30, 30));
       
  5693 }
       
  5694 
       
  5695 class ItemAddScene : public QGraphicsScene
       
  5696 {
       
  5697     Q_OBJECT
       
  5698 public:
       
  5699     ItemAddScene()
       
  5700     {
       
  5701         QTimer::singleShot(500, this, SLOT(newTextItem()));
       
  5702     }
       
  5703 
       
  5704 public slots:
       
  5705     void newTextItem()
       
  5706     {
       
  5707         // Add a text item
       
  5708         QGraphicsItem *item = new QGraphicsTextItem("This item will not ensure that it's visible", 0, this);
       
  5709         item->setPos(.0, .0);
       
  5710         item->show();
       
  5711     }
       
  5712 };
       
  5713 
       
  5714 void tst_QGraphicsItem::task141694_textItemEnsureVisible()
       
  5715 {
       
  5716     ItemAddScene scene;
       
  5717     scene.setSceneRect(-1000, -1000, 2000, 2000);
       
  5718 
       
  5719     QGraphicsView view(&scene);
       
  5720     view.setFixedSize(200, 200);
       
  5721     view.show();
       
  5722     QTest::qWaitForWindowShown(&view);
       
  5723 
       
  5724     view.ensureVisible(-1000, -1000, 5, 5);
       
  5725     int hscroll = view.horizontalScrollBar()->value();
       
  5726     int vscroll = view.verticalScrollBar()->value();
       
  5727 
       
  5728     QTest::qWait(10);
       
  5729 
       
  5730     // This should not cause the view to scroll
       
  5731     QTRY_COMPARE(view.horizontalScrollBar()->value(), hscroll);
       
  5732     QCOMPARE(view.verticalScrollBar()->value(), vscroll);
       
  5733 }
       
  5734 
       
  5735 void tst_QGraphicsItem::task128696_textItemEnsureMovable()
       
  5736 {
       
  5737     QGraphicsTextItem *item = new QGraphicsTextItem;
       
  5738     item->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
       
  5739     item->setTextInteractionFlags(Qt::TextEditorInteraction);
       
  5740     item->setPlainText("abc de\nf ghi\n   j k l");
       
  5741 
       
  5742     QGraphicsScene scene;
       
  5743     scene.setSceneRect(-100, -100, 200, 200);
       
  5744     scene.addItem(item);
       
  5745 
       
  5746     QGraphicsView view(&scene);
       
  5747     view.setFixedSize(200, 200);
       
  5748     view.show();
       
  5749 
       
  5750     QGraphicsSceneMouseEvent event1(QEvent::GraphicsSceneMousePress);
       
  5751     event1.setScenePos(QPointF(0, 0));
       
  5752     event1.setButton(Qt::LeftButton);
       
  5753     event1.setButtons(Qt::LeftButton);
       
  5754     QApplication::sendEvent(&scene, &event1);
       
  5755     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)item);
       
  5756 
       
  5757     QGraphicsSceneMouseEvent event2(QEvent::GraphicsSceneMouseMove);
       
  5758     event2.setScenePos(QPointF(10, 10));
       
  5759     event2.setButton(Qt::LeftButton);
       
  5760     event2.setButtons(Qt::LeftButton);
       
  5761     QApplication::sendEvent(&scene, &event2);
       
  5762     QCOMPARE(item->pos(), QPointF(10, 10));
       
  5763 }
       
  5764 
       
  5765 void tst_QGraphicsItem::task177918_lineItemUndetected()
       
  5766 {
       
  5767     QGraphicsScene scene;
       
  5768     QGraphicsLineItem *line = scene.addLine(10, 10, 10, 10);
       
  5769     QCOMPARE(line->boundingRect(), QRectF(10, 10, 0, 0));
       
  5770 
       
  5771     QVERIFY(!scene.items(9, 9, 2, 2, Qt::IntersectsItemShape).isEmpty());
       
  5772     QVERIFY(!scene.items(9, 9, 2, 2, Qt::ContainsItemShape).isEmpty());
       
  5773     QVERIFY(!scene.items(9, 9, 2, 2, Qt::IntersectsItemBoundingRect).isEmpty());
       
  5774     QVERIFY(!scene.items(9, 9, 2, 2, Qt::ContainsItemBoundingRect).isEmpty());
       
  5775 }
       
  5776 
       
  5777 void tst_QGraphicsItem::task240400_clickOnTextItem_data()
       
  5778 {
       
  5779     QTest::addColumn<int>("flags");
       
  5780     QTest::addColumn<int>("textFlags");
       
  5781     QTest::newRow("editor, noflags") << 0 << int(Qt::TextEditorInteraction);
       
  5782     QTest::newRow("editor, movable") << int(QGraphicsItem::ItemIsMovable) << int(Qt::TextEditorInteraction);
       
  5783     QTest::newRow("editor, selectable") << int(QGraphicsItem::ItemIsSelectable) << int(Qt::TextEditorInteraction);
       
  5784     QTest::newRow("editor, movable | selectable") << int(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable)
       
  5785                                                   << int(Qt::TextEditorInteraction);
       
  5786     QTest::newRow("noninteractive, noflags") << 0 << int(Qt::NoTextInteraction);
       
  5787     QTest::newRow("noninteractive, movable") << int(QGraphicsItem::ItemIsMovable) << int(Qt::NoTextInteraction);
       
  5788     QTest::newRow("noninteractive, selectable") << int(QGraphicsItem::ItemIsSelectable) << int(Qt::NoTextInteraction);
       
  5789     QTest::newRow("noninteractive, movable | selectable") << int(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable)
       
  5790                                                           << int(Qt::NoTextInteraction);
       
  5791 }
       
  5792 
       
  5793 void tst_QGraphicsItem::task240400_clickOnTextItem()
       
  5794 {
       
  5795     QFETCH(int, flags);
       
  5796     QFETCH(int, textFlags);
       
  5797 
       
  5798     QGraphicsScene scene;
       
  5799     QEvent activate(QEvent::WindowActivate);
       
  5800     QApplication::sendEvent(&scene, &activate);
       
  5801 
       
  5802     QGraphicsTextItem *item = scene.addText("Hello");
       
  5803     item->setFlags(QGraphicsItem::GraphicsItemFlags(flags));
       
  5804     item->setTextInteractionFlags(Qt::TextInteractionFlags(textFlags));
       
  5805     bool focusable = (item->flags() & QGraphicsItem::ItemIsFocusable);
       
  5806     QVERIFY(textFlags ? focusable : !focusable);
       
  5807 
       
  5808     int column = item->textCursor().columnNumber();
       
  5809     QCOMPARE(column, 0);
       
  5810 
       
  5811     QVERIFY(!item->hasFocus());
       
  5812 
       
  5813     // Click in the top-left corner of the item
       
  5814     {
       
  5815         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
       
  5816         event.setScenePos(item->sceneBoundingRect().topLeft() + QPointF(0.1, 0.1));
       
  5817         event.setButton(Qt::LeftButton);
       
  5818         event.setButtons(Qt::LeftButton);
       
  5819         QApplication::sendEvent(&scene, &event);
       
  5820     }
       
  5821     if (flags || textFlags)
       
  5822         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)item);
       
  5823     else
       
  5824         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
  5825     {
       
  5826         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
       
  5827         event.setScenePos(item->sceneBoundingRect().topLeft() + QPointF(0.1, 0.1));
       
  5828         event.setButton(Qt::LeftButton);
       
  5829         event.setButtons(0);
       
  5830         QApplication::sendEvent(&scene, &event);
       
  5831     }
       
  5832     if (textFlags)
       
  5833         QVERIFY(item->hasFocus());
       
  5834     else
       
  5835         QVERIFY(!item->hasFocus());
       
  5836     QVERIFY(!scene.mouseGrabberItem());
       
  5837     bool selectable = (flags & QGraphicsItem::ItemIsSelectable);
       
  5838     QVERIFY(selectable ? item->isSelected() : !item->isSelected());
       
  5839 
       
  5840     // Now click in the middle and check that the cursor moved.
       
  5841     {
       
  5842         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
       
  5843         event.setScenePos(item->sceneBoundingRect().center());
       
  5844         event.setButton(Qt::LeftButton);
       
  5845         event.setButtons(Qt::LeftButton);
       
  5846         QApplication::sendEvent(&scene, &event);
       
  5847     }
       
  5848     if (flags || textFlags)
       
  5849         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)item);
       
  5850     else
       
  5851         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
  5852     {
       
  5853         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
       
  5854         event.setScenePos(item->sceneBoundingRect().center());
       
  5855         event.setButton(Qt::LeftButton);
       
  5856         event.setButtons(0);
       
  5857         QApplication::sendEvent(&scene, &event);
       
  5858     }
       
  5859     if (textFlags)
       
  5860         QVERIFY(item->hasFocus());
       
  5861     else
       
  5862         QVERIFY(!item->hasFocus());
       
  5863     QVERIFY(!scene.mouseGrabberItem());
       
  5864 
       
  5865     QVERIFY(selectable ? item->isSelected() : !item->isSelected());
       
  5866 
       
  5867     //
       
  5868     if (textFlags & Qt::TextEditorInteraction)
       
  5869         QVERIFY(item->textCursor().columnNumber() > column);
       
  5870     else
       
  5871         QCOMPARE(item->textCursor().columnNumber(), 0);
       
  5872 }
       
  5873 
       
  5874 class TextItem : public QGraphicsSimpleTextItem
       
  5875 {
       
  5876 public:
       
  5877     TextItem(const QString& text) : QGraphicsSimpleTextItem(text)
       
  5878     {
       
  5879         updates = 0;
       
  5880     }
       
  5881 
       
  5882     void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
       
  5883     {
       
  5884         updates++;
       
  5885         QGraphicsSimpleTextItem::paint(painter, option, widget);
       
  5886     }
       
  5887 
       
  5888     int updates;
       
  5889 };
       
  5890 
       
  5891 void tst_QGraphicsItem::ensureUpdateOnTextItem()
       
  5892 {
       
  5893     QGraphicsScene scene;
       
  5894     QGraphicsView view(&scene);
       
  5895     view.show();
       
  5896     QTest::qWaitForWindowShown(&view);
       
  5897     QTest::qWait(25);
       
  5898     TextItem *text1 = new TextItem(QLatin1String("123"));
       
  5899     scene.addItem(text1);
       
  5900     qApp->processEvents();
       
  5901     QTRY_COMPARE(text1->updates,1);
       
  5902 
       
  5903     //same bouding rect but we have to update
       
  5904     text1->setText(QLatin1String("321"));
       
  5905     qApp->processEvents();
       
  5906     QTRY_COMPARE(text1->updates,2);
       
  5907 }
       
  5908 
       
  5909 void tst_QGraphicsItem::task243707_addChildBeforeParent()
       
  5910 {
       
  5911     // Task reports that adding the child before the parent leads to an
       
  5912     // inconsistent internal state that can cause a crash.  This test shows
       
  5913     // one such crash.
       
  5914     QGraphicsScene scene;
       
  5915     QGraphicsWidget *widget = new QGraphicsWidget;
       
  5916     QGraphicsWidget *widget2 = new QGraphicsWidget(widget);
       
  5917     scene.addItem(widget2);
       
  5918     QVERIFY(!widget2->parentItem());
       
  5919     scene.addItem(widget);
       
  5920     QVERIFY(!widget->commonAncestorItem(widget2));
       
  5921     QVERIFY(!widget2->commonAncestorItem(widget));
       
  5922 }
       
  5923 
       
  5924 void tst_QGraphicsItem::task197802_childrenVisibility()
       
  5925 {
       
  5926     QGraphicsScene scene;
       
  5927     QGraphicsRectItem item(QRectF(0,0,20,20));
       
  5928 
       
  5929     QGraphicsRectItem *item2 = new QGraphicsRectItem(QRectF(0,0,10,10), &item);
       
  5930     scene.addItem(&item);
       
  5931 
       
  5932     //freshly created: both visible
       
  5933     QVERIFY(item.isVisible());
       
  5934     QVERIFY(item2->isVisible());
       
  5935 
       
  5936     //hide child: parent visible, child not
       
  5937     item2->hide();
       
  5938     QVERIFY(item.isVisible());
       
  5939     QVERIFY(!item2->isVisible());
       
  5940 
       
  5941     //hide parent: parent and child invisible
       
  5942     item.hide();
       
  5943     QVERIFY(!item.isVisible());
       
  5944     QVERIFY(!item2->isVisible());
       
  5945 
       
  5946     //ask to show the child: parent and child invisible anyways
       
  5947     item2->show();
       
  5948     QVERIFY(!item.isVisible());
       
  5949     QVERIFY(!item2->isVisible());
       
  5950 
       
  5951     //show the parent: both parent and child visible
       
  5952     item.show();
       
  5953     QVERIFY(item.isVisible());
       
  5954     QVERIFY(item2->isVisible());
       
  5955 
       
  5956     delete item2;
       
  5957 }
       
  5958 
       
  5959 void tst_QGraphicsItem::boundingRegion_data()
       
  5960 {
       
  5961     QTest::addColumn<QLineF>("line");
       
  5962     QTest::addColumn<qreal>("granularity");
       
  5963     QTest::addColumn<QTransform>("transform");
       
  5964     QTest::addColumn<QRegion>("expectedRegion");
       
  5965 
       
  5966     QTest::newRow("(0, 0, 10, 10) | 0.0 | identity | {(0, 0, 10, 10)}") << QLineF(0, 0, 10, 10) << qreal(0.0) << QTransform()
       
  5967                                                                         << QRegion(QRect(0, 0, 10, 10));
       
  5968     {
       
  5969         QRegion r;
       
  5970         r += QRect(0, 0, 6, 2);
       
  5971         r += QRect(0, 2, 8, 2);
       
  5972         r += QRect(0, 4, 10, 2);
       
  5973         r += QRect(2, 6, 8, 2);
       
  5974         r += QRect(4, 8, 6, 2);
       
  5975         QTest::newRow("(0, 0, 10, 10) | 0.5 | identity | {(0, 0, 10, 10)}") << QLineF(0, 0, 10, 10) << qreal(0.5) << QTransform() << r;
       
  5976     }
       
  5977     {
       
  5978         QRegion r;
       
  5979         r += QRect(0, 0, 4, 1); r += QRect(0, 1, 5, 1); r += QRect(0, 2, 6, 1);
       
  5980         r += QRect(0, 3, 7, 1); r += QRect(1, 4, 7, 1); r += QRect(2, 5, 7, 1);
       
  5981         r += QRect(3, 6, 7, 1); r += QRect(4, 7, 6, 1); r += QRect(5, 8, 5, 1);
       
  5982         r += QRect(6, 9, 4, 1);
       
  5983         QTest::newRow("(0, 0, 10, 10) | 1.0 | identity | {(0, 0, 10, 10)}") << QLineF(0, 0, 10, 10) << qreal(1.0) << QTransform() << r;
       
  5984     }
       
  5985     QTest::newRow("(0, 0, 10, 0) | 0.0 | identity | {(0, 0, 10, 10)}") << QLineF(0, 0, 10, 0) << qreal(0.0) << QTransform()
       
  5986                                                                        << QRegion(QRect(0, 0, 10, 1));
       
  5987     QTest::newRow("(0, 0, 10, 0) | 0.5 | identity | {(0, 0, 10, 1)}") << QLineF(0, 0, 10, 0) << qreal(0.5) << QTransform()
       
  5988                                                                       << QRegion(QRect(0, 0, 10, 1));
       
  5989     QTest::newRow("(0, 0, 10, 0) | 1.0 | identity | {(0, 0, 10, 1)}") << QLineF(0, 0, 10, 0) << qreal(1.0) << QTransform()
       
  5990                                                                       << QRegion(QRect(0, 0, 10, 1));
       
  5991     QTest::newRow("(0, 0, 0, 10) | 0.0 | identity | {(0, 0, 10, 10)}") << QLineF(0, 0, 0, 10) << qreal(0.0) << QTransform()
       
  5992                                                                        << QRegion(QRect(0, 0, 1, 10));
       
  5993     QTest::newRow("(0, 0, 0, 10) | 0.5 | identity | {(0, 0, 1, 10)}") << QLineF(0, 0, 0, 10) << qreal(0.5) << QTransform()
       
  5994                                                                       << QRegion(QRect(0, 0, 1, 10));
       
  5995     QTest::newRow("(0, 0, 0, 10) | 1.0 | identity | {(0, 0, 1, 10)}") << QLineF(0, 0, 0, 10) << qreal(1.0) << QTransform()
       
  5996                                                                       << QRegion(QRect(0, 0, 1, 10));
       
  5997 }
       
  5998 
       
  5999 void tst_QGraphicsItem::boundingRegion()
       
  6000 {
       
  6001     QFETCH(QLineF, line);
       
  6002     QFETCH(qreal, granularity);
       
  6003     QFETCH(QTransform, transform);
       
  6004     QFETCH(QRegion, expectedRegion);
       
  6005 
       
  6006     QGraphicsLineItem item(line);
       
  6007     QCOMPARE(item.boundingRegionGranularity(), qreal(0.0));
       
  6008     item.setBoundingRegionGranularity(granularity);
       
  6009     QCOMPARE(item.boundingRegionGranularity(), granularity);
       
  6010     QCOMPARE(item.boundingRegion(transform), expectedRegion);
       
  6011 }
       
  6012 
       
  6013 void tst_QGraphicsItem::itemTransform_parentChild()
       
  6014 {
       
  6015     QGraphicsScene scene;
       
  6016     QGraphicsItem *parent = scene.addRect(0, 0, 100, 100);
       
  6017     QGraphicsItem *child = scene.addRect(0, 0, 100, 100);
       
  6018     child->setParentItem(parent);
       
  6019     child->setPos(10, 10);
       
  6020     child->scale(2, 2);
       
  6021     child->rotate(90);
       
  6022 
       
  6023     QCOMPARE(child->itemTransform(parent).map(QPointF(10, 10)), QPointF(-10, 30));
       
  6024     QCOMPARE(parent->itemTransform(child).map(QPointF(-10, 30)), QPointF(10, 10));
       
  6025 }
       
  6026 
       
  6027 void tst_QGraphicsItem::itemTransform_siblings()
       
  6028 {
       
  6029     QGraphicsScene scene;
       
  6030     QGraphicsItem *parent = scene.addRect(0, 0, 100, 100);
       
  6031     QGraphicsItem *brother = scene.addRect(0, 0, 100, 100);
       
  6032     QGraphicsItem *sister = scene.addRect(0, 0, 100, 100);
       
  6033     parent->scale(10, 5);
       
  6034     parent->rotate(-180);
       
  6035     parent->shear(2, 3);
       
  6036 
       
  6037     brother->setParentItem(parent);
       
  6038     sister->setParentItem(parent);
       
  6039 
       
  6040     brother->setPos(10, 10);
       
  6041     brother->scale(2, 2);
       
  6042     brother->rotate(90);
       
  6043     sister->setPos(10, 10);
       
  6044     sister->scale(2, 2);
       
  6045     sister->rotate(90);
       
  6046 
       
  6047     QCOMPARE(brother->itemTransform(sister).map(QPointF(10, 10)), QPointF(10, 10));
       
  6048     QCOMPARE(sister->itemTransform(brother).map(QPointF(10, 10)), QPointF(10, 10));
       
  6049 }
       
  6050 
       
  6051 void tst_QGraphicsItem::itemTransform_unrelated()
       
  6052 {
       
  6053     QGraphicsScene scene;
       
  6054     QGraphicsItem *stranger1 = scene.addRect(0, 0, 100, 100);
       
  6055     QGraphicsItem *stranger2 = scene.addRect(0, 0, 100, 100);
       
  6056     stranger1->setPos(10, 10);
       
  6057     stranger1->scale(2, 2);
       
  6058     stranger1->rotate(90);
       
  6059     stranger2->setPos(10, 10);
       
  6060     stranger2->scale(2, 2);
       
  6061     stranger2->rotate(90);
       
  6062 
       
  6063     QCOMPARE(stranger1->itemTransform(stranger2).map(QPointF(10, 10)), QPointF(10, 10));
       
  6064     QCOMPARE(stranger2->itemTransform(stranger1).map(QPointF(10, 10)), QPointF(10, 10));
       
  6065 }
       
  6066 
       
  6067 void tst_QGraphicsItem::opacity_data()
       
  6068 {
       
  6069     QTest::addColumn<qreal>("p_opacity");
       
  6070     QTest::addColumn<int>("p_opacityFlags");
       
  6071     QTest::addColumn<qreal>("c1_opacity");
       
  6072     QTest::addColumn<int>("c1_opacityFlags");
       
  6073     QTest::addColumn<qreal>("c2_opacity");
       
  6074     QTest::addColumn<int>("c2_opacityFlags");
       
  6075     QTest::addColumn<qreal>("p_effectiveOpacity");
       
  6076     QTest::addColumn<qreal>("c1_effectiveOpacity");
       
  6077     QTest::addColumn<qreal>("c2_effectiveOpacity");
       
  6078     QTest::addColumn<qreal>("c3_effectiveOpacity");
       
  6079 
       
  6080     // Modify the opacity and see how it propagates
       
  6081     QTest::newRow("A: 1.0 0 1.0 0 1.0 1.0 1.0 1.0 1.0") << qreal(1.0) << 0 << qreal(1.0) << 0 << qreal(1.0) << 0
       
  6082                                                         << qreal(1.0) << qreal(1.0) << qreal(1.0) << qreal(1.0);
       
  6083     QTest::newRow("B: 0.5 0 1.0 0 1.0 1.0 1.0 1.0 1.0") << qreal(0.5) << 0 << qreal(1.0) << 0 << qreal(1.0) << 0
       
  6084                                                         << qreal(0.5) << qreal(0.5) << qreal(0.5) << qreal(0.5);
       
  6085     QTest::newRow("C: 0.5 0 0.1 0 1.0 1.0 1.0 1.0 1.0") << qreal(0.5) << 0 << qreal(0.1) << 0 << qreal(1.0) << 0
       
  6086                                                         << qreal(0.5) << qreal(0.05) << qreal(0.05) << qreal(0.05);
       
  6087     QTest::newRow("D: 0.0 0 1.0 0 1.0 1.0 1.0 1.0 1.0") << qreal(0.0) << 0 << qreal(1.0) << 0 << qreal(1.0) << 0
       
  6088                                                         << qreal(0.0) << qreal(0.0) << qreal(0.0) << qreal(0.0);
       
  6089 
       
  6090     // Parent doesn't propagate to children - now modify the opacity and see how it propagates
       
  6091     int flags = QGraphicsItem::ItemDoesntPropagateOpacityToChildren;
       
  6092     QTest::newRow("E: 1.0 2 1.0 0 1.0 1.0 1.0 1.0 1.0") << qreal(1.0) << flags << qreal(1.0) << 0 << qreal(1.0) << 0
       
  6093                                                         << qreal(1.0) << qreal(1.0) << qreal(1.0) << qreal(1.0);
       
  6094     QTest::newRow("F: 0.5 2 1.0 0 1.0 1.0 1.0 1.0 1.0") << qreal(0.5) << flags << qreal(1.0) << 0 << qreal(1.0) << 0
       
  6095                                                         << qreal(0.5) << qreal(1.0) << qreal(1.0) << qreal(1.0);
       
  6096     QTest::newRow("G: 0.5 2 0.1 0 1.0 1.0 1.0 1.0 1.0") << qreal(0.5) << flags << qreal(0.1) << 0 << qreal(1.0) << 0
       
  6097                                                         << qreal(0.5) << qreal(0.1) << qreal(0.1) << qreal(0.1);
       
  6098     QTest::newRow("H: 0.0 2 1.0 0 1.0 1.0 1.0 1.0 1.0") << qreal(0.0) << flags << qreal(1.0) << 0 << qreal(1.0) << 0
       
  6099                                                         << qreal(0.0) << qreal(1.0) << qreal(1.0) << qreal(1.0);
       
  6100 
       
  6101     // Child ignores parent - now modify the opacity and see how it propagates
       
  6102     flags = QGraphicsItem::ItemIgnoresParentOpacity;
       
  6103     QTest::newRow("I: 1.0 0 1.0 1 1.0 1.0 1.0 1.0 1.0") << qreal(1.0) << 0 << qreal(1.0) << flags << qreal(1.0) << 0
       
  6104                                                         << qreal(1.0) << qreal(1.0) << qreal(1.0) << qreal(1.0);
       
  6105     QTest::newRow("J: 1.0 0 1.0 1 1.0 1.0 1.0 1.0 1.0") << qreal(0.5) << 0 << qreal(0.5) << flags << qreal(0.5) << 0
       
  6106                                                         << qreal(0.5) << qreal(0.5) << qreal(0.25) << qreal(0.25);
       
  6107     QTest::newRow("K: 1.0 0 1.0 1 1.0 1.0 1.0 1.0 1.0") << qreal(0.2) << 0 << qreal(0.2) << flags << qreal(0.2) << 0
       
  6108                                                         << qreal(0.2) << qreal(0.2) << qreal(0.04) << qreal(0.04);
       
  6109     QTest::newRow("L: 1.0 0 1.0 1 1.0 1.0 1.0 1.0 1.0") << qreal(0.0) << 0 << qreal(0.0) << flags << qreal(0.0) << 0
       
  6110                                                         << qreal(0.0) << qreal(0.0) << qreal(0.0) << qreal(0.0);
       
  6111 
       
  6112     // Child ignores parent and doesn't propagate - now modify the opacity and see how it propagates
       
  6113     flags = QGraphicsItem::ItemIgnoresParentOpacity | QGraphicsItem::ItemDoesntPropagateOpacityToChildren;
       
  6114     QTest::newRow("M: 1.0 0 1.0 1 1.0 1.0 1.0 1.0 1.0") << qreal(1.0) << 0 // p
       
  6115                                                         << qreal(1.0) << flags // c1 (no prop)
       
  6116                                                         << qreal(1.0) << 0 // c2
       
  6117                                                         << qreal(1.0) << qreal(1.0) << qreal(1.0) << qreal(1.0);
       
  6118     QTest::newRow("M: 0.5 0 1.0 1 1.0 1.0 1.0 1.0 1.0") << qreal(0.5) << 0 // p
       
  6119                                                         << qreal(1.0) << flags // c1 (no prop)
       
  6120                                                         << qreal(1.0) << 0 // c2
       
  6121                                                         << qreal(0.5) << qreal(1.0) << qreal(1.0) << qreal(1.0);
       
  6122     QTest::newRow("M: 0.5 0 0.5 1 1.0 1.0 1.0 1.0 1.0") << qreal(0.5) << 0 // p
       
  6123                                                         << qreal(0.5) << flags // c1 (no prop)
       
  6124                                                         << qreal(1.0) << 0 // c2
       
  6125                                                         << qreal(0.5) << qreal(0.5) << qreal(1.0) << qreal(1.0);
       
  6126     QTest::newRow("M: 0.5 0 0.5 1 0.5 1.0 1.0 1.0 1.0") << qreal(0.5) << 0 // p
       
  6127                                                         << qreal(0.5) << flags // c1 (no prop)
       
  6128                                                         << qreal(0.5) << 0 // c2
       
  6129                                                         << qreal(0.5) << qreal(0.5) << qreal(0.5) << qreal(0.5);
       
  6130     QTest::newRow("M: 1.0 0 0.5 1 0.5 1.0 1.0 1.0 1.0") << qreal(1.0) << 0 // p
       
  6131                                                         << qreal(0.5) << flags // c1 (no prop)
       
  6132                                                         << qreal(0.5) << 0 // c2
       
  6133                                                         << qreal(1.0) << qreal(0.5) << qreal(0.5) << qreal(0.5);
       
  6134 }
       
  6135 
       
  6136 void tst_QGraphicsItem::opacity()
       
  6137 {
       
  6138     QFETCH(qreal, p_opacity);
       
  6139     QFETCH(int, p_opacityFlags);
       
  6140     QFETCH(qreal, p_effectiveOpacity);
       
  6141     QFETCH(qreal, c1_opacity);
       
  6142     QFETCH(int, c1_opacityFlags);
       
  6143     QFETCH(qreal, c1_effectiveOpacity);
       
  6144     QFETCH(qreal, c2_opacity);
       
  6145     QFETCH(int, c2_opacityFlags);
       
  6146     QFETCH(qreal, c2_effectiveOpacity);
       
  6147     QFETCH(qreal, c3_effectiveOpacity);
       
  6148 
       
  6149     QGraphicsRectItem *p = new QGraphicsRectItem;
       
  6150     QGraphicsRectItem *c1 = new QGraphicsRectItem(p);
       
  6151     QGraphicsRectItem *c2 = new QGraphicsRectItem(c1);
       
  6152     QGraphicsRectItem *c3 = new QGraphicsRectItem(c2);
       
  6153 
       
  6154     QCOMPARE(p->opacity(), qreal(1.0));
       
  6155     QCOMPARE(p->effectiveOpacity(), qreal(1.0));
       
  6156     int opacityMask = QGraphicsItem::ItemIgnoresParentOpacity | QGraphicsItem::ItemDoesntPropagateOpacityToChildren;
       
  6157     QVERIFY(!(p->flags() & opacityMask));
       
  6158 
       
  6159     p->setOpacity(p_opacity);
       
  6160     c1->setOpacity(c1_opacity);
       
  6161     c2->setOpacity(c2_opacity);
       
  6162     p->setFlags(QGraphicsItem::GraphicsItemFlags(p->flags() | p_opacityFlags));
       
  6163     c1->setFlags(QGraphicsItem::GraphicsItemFlags(c1->flags() | c1_opacityFlags));
       
  6164     c2->setFlags(QGraphicsItem::GraphicsItemFlags(c2->flags() | c2_opacityFlags));
       
  6165 
       
  6166     QCOMPARE(int(p->flags() & opacityMask), p_opacityFlags);
       
  6167     QCOMPARE(int(c1->flags() & opacityMask), c1_opacityFlags);
       
  6168     QCOMPARE(int(c2->flags() & opacityMask), c2_opacityFlags);
       
  6169     QCOMPARE(p->opacity(), p_opacity);
       
  6170     QCOMPARE(p->effectiveOpacity(), p_effectiveOpacity);
       
  6171     QCOMPARE(c1->effectiveOpacity(), c1_effectiveOpacity);
       
  6172     QCOMPARE(c2->effectiveOpacity(), c2_effectiveOpacity);
       
  6173     QCOMPARE(c3->effectiveOpacity(), c3_effectiveOpacity);
       
  6174 }
       
  6175 
       
  6176 void tst_QGraphicsItem::opacity2()
       
  6177 {
       
  6178     EventTester *parent = new EventTester;
       
  6179     EventTester *child = new EventTester(parent);
       
  6180     EventTester *grandChild = new EventTester(child);
       
  6181 
       
  6182     QGraphicsScene scene;
       
  6183     scene.addItem(parent);
       
  6184 
       
  6185     class MyGraphicsView : public QGraphicsView
       
  6186     { public:
       
  6187         int repaints;
       
  6188         MyGraphicsView(QGraphicsScene *scene) : QGraphicsView(scene), repaints(0) {}
       
  6189         void paintEvent(QPaintEvent *e) { ++repaints; QGraphicsView::paintEvent(e); }
       
  6190     };
       
  6191 
       
  6192     MyGraphicsView view(&scene);
       
  6193     view.show();
       
  6194     QTest::qWaitForWindowShown(&view);
       
  6195     QTRY_VERIFY(view.repaints >= 1);
       
  6196 
       
  6197 #define RESET_REPAINT_COUNTERS \
       
  6198     parent->repaints = 0; \
       
  6199     child->repaints = 0; \
       
  6200     grandChild->repaints = 0; \
       
  6201     view.repaints = 0;
       
  6202 
       
  6203     RESET_REPAINT_COUNTERS
       
  6204 
       
  6205     child->setOpacity(0.0);
       
  6206     QTest::qWait(10);
       
  6207     QTRY_COMPARE(view.repaints, 1);
       
  6208     QCOMPARE(parent->repaints, 1);
       
  6209     QCOMPARE(child->repaints, 0);
       
  6210     QCOMPARE(grandChild->repaints, 0);
       
  6211 
       
  6212     RESET_REPAINT_COUNTERS
       
  6213 
       
  6214     child->setOpacity(1.0);
       
  6215     QTest::qWait(10);
       
  6216     QTRY_COMPARE(view.repaints, 1);
       
  6217     QCOMPARE(parent->repaints, 1);
       
  6218     QCOMPARE(child->repaints, 1);
       
  6219     QCOMPARE(grandChild->repaints, 1);
       
  6220 
       
  6221     RESET_REPAINT_COUNTERS
       
  6222 
       
  6223     parent->setOpacity(0.0);
       
  6224     QTest::qWait(10);
       
  6225     QTRY_COMPARE(view.repaints, 1);
       
  6226     QCOMPARE(parent->repaints, 0);
       
  6227     QCOMPARE(child->repaints, 0);
       
  6228     QCOMPARE(grandChild->repaints, 0);
       
  6229 
       
  6230     RESET_REPAINT_COUNTERS
       
  6231 
       
  6232     parent->setOpacity(1.0);
       
  6233     QTest::qWait(10);
       
  6234     QTRY_COMPARE(view.repaints, 1);
       
  6235     QCOMPARE(parent->repaints, 1);
       
  6236     QCOMPARE(child->repaints, 1);
       
  6237     QCOMPARE(grandChild->repaints, 1);
       
  6238 
       
  6239     grandChild->setFlag(QGraphicsItem::ItemIgnoresParentOpacity);
       
  6240     RESET_REPAINT_COUNTERS
       
  6241 
       
  6242     child->setOpacity(0.0);
       
  6243     QTest::qWait(10);
       
  6244     QTRY_COMPARE(view.repaints, 1);
       
  6245     QCOMPARE(parent->repaints, 1);
       
  6246     QCOMPARE(child->repaints, 0);
       
  6247     QCOMPARE(grandChild->repaints, 1);
       
  6248 
       
  6249     RESET_REPAINT_COUNTERS
       
  6250 
       
  6251     child->setOpacity(0.0); // Already 0.0; no change.
       
  6252     QTest::qWait(10);
       
  6253     QTRY_COMPARE(view.repaints, 0);
       
  6254     QCOMPARE(parent->repaints, 0);
       
  6255     QCOMPARE(child->repaints, 0);
       
  6256     QCOMPARE(grandChild->repaints, 0);
       
  6257 }
       
  6258 
       
  6259 void tst_QGraphicsItem::opacityZeroUpdates()
       
  6260 {
       
  6261     EventTester *parent = new EventTester;
       
  6262     EventTester *child = new EventTester(parent);
       
  6263 
       
  6264     child->setPos(10, 10);
       
  6265 
       
  6266     QGraphicsScene scene;
       
  6267     scene.addItem(parent);
       
  6268 
       
  6269     class MyGraphicsView : public QGraphicsView
       
  6270     { public:
       
  6271         int repaints;
       
  6272         QRegion paintedRegion;
       
  6273         MyGraphicsView(QGraphicsScene *scene) : QGraphicsView(scene), repaints(0) {}
       
  6274         void paintEvent(QPaintEvent *e)
       
  6275         {
       
  6276             ++repaints;
       
  6277             paintedRegion += e->region();
       
  6278             QGraphicsView::paintEvent(e);
       
  6279         }
       
  6280         void reset() { repaints = 0; paintedRegion = QRegion(); }
       
  6281     };
       
  6282 
       
  6283     MyGraphicsView view(&scene);
       
  6284     view.show();
       
  6285     QTest::qWaitForWindowShown(&view);
       
  6286     QTRY_VERIFY(view.repaints > 0);
       
  6287 
       
  6288     view.reset();
       
  6289     parent->setOpacity(0.0);
       
  6290 
       
  6291     QTest::qWait(20);
       
  6292 
       
  6293     // transforming items bounding rect to view coordinates
       
  6294     const QRect childDeviceBoundingRect = child->deviceTransform(view.viewportTransform())
       
  6295                                            .mapRect(child->boundingRect()).toRect();
       
  6296     const QRect parentDeviceBoundingRect = parent->deviceTransform(view.viewportTransform())
       
  6297                                            .mapRect(parent->boundingRect()).toRect();
       
  6298 
       
  6299     QRegion expectedRegion = parentDeviceBoundingRect.adjusted(-2, -2, 2, 2);
       
  6300     expectedRegion += childDeviceBoundingRect.adjusted(-2, -2, 2, 2);
       
  6301 
       
  6302     COMPARE_REGIONS(view.paintedRegion, expectedRegion);
       
  6303 }
       
  6304 
       
  6305 class StacksBehindParentHelper : public QGraphicsRectItem
       
  6306 {
       
  6307 public:
       
  6308     StacksBehindParentHelper(QList<QGraphicsItem *> *paintedItems, const QRectF &rect, QGraphicsItem *parent = 0)
       
  6309         : QGraphicsRectItem(rect, parent), paintedItems(paintedItems)
       
  6310     { }
       
  6311 
       
  6312     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
       
  6313     {
       
  6314         QGraphicsRectItem::paint(painter, option, widget);
       
  6315         paintedItems->append(this);
       
  6316     }
       
  6317 
       
  6318 private:
       
  6319     QList<QGraphicsItem *> *paintedItems;
       
  6320 };
       
  6321 
       
  6322 void tst_QGraphicsItem::itemStacksBehindParent()
       
  6323 {
       
  6324     StacksBehindParentHelper *parent1 = new StacksBehindParentHelper(&paintedItems, QRectF(0, 0, 100, 50));
       
  6325     StacksBehindParentHelper *child11 = new StacksBehindParentHelper(&paintedItems, QRectF(-10, 10, 50, 50), parent1);
       
  6326     StacksBehindParentHelper *grandChild111 = new StacksBehindParentHelper(&paintedItems, QRectF(-20, 20, 50, 50), child11);
       
  6327     StacksBehindParentHelper *child12 = new StacksBehindParentHelper(&paintedItems, QRectF(60, 10, 50, 50), parent1);
       
  6328     StacksBehindParentHelper *grandChild121 = new StacksBehindParentHelper(&paintedItems, QRectF(70, 20, 50, 50), child12);
       
  6329 
       
  6330     StacksBehindParentHelper *parent2 = new StacksBehindParentHelper(&paintedItems, QRectF(0, 0, 100, 50));
       
  6331     StacksBehindParentHelper *child21 = new StacksBehindParentHelper(&paintedItems, QRectF(-10, 10, 50, 50), parent2);
       
  6332     StacksBehindParentHelper *grandChild211 = new StacksBehindParentHelper(&paintedItems, QRectF(-20, 20, 50, 50), child21);
       
  6333     StacksBehindParentHelper *child22 = new StacksBehindParentHelper(&paintedItems, QRectF(60, 10, 50, 50), parent2);
       
  6334     StacksBehindParentHelper *grandChild221 = new StacksBehindParentHelper(&paintedItems, QRectF(70, 20, 50, 50), child22);
       
  6335 
       
  6336     parent1->setData(0, "parent1");
       
  6337     child11->setData(0, "child11");
       
  6338     grandChild111->setData(0, "grandChild111");
       
  6339     child12->setData(0, "child12");
       
  6340     grandChild121->setData(0, "grandChild121");
       
  6341     parent2->setData(0, "parent2");
       
  6342     child21->setData(0, "child21");
       
  6343     grandChild211->setData(0, "grandChild211");
       
  6344     child22->setData(0, "child22");
       
  6345     grandChild221->setData(0, "grandChild221");
       
  6346 
       
  6347     // Disambiguate siblings
       
  6348     parent1->setZValue(1);
       
  6349     child11->setZValue(1);
       
  6350     child21->setZValue(1);
       
  6351 
       
  6352     QGraphicsScene scene;
       
  6353     scene.addItem(parent1);
       
  6354     scene.addItem(parent2);
       
  6355 
       
  6356     QGraphicsView view(&scene);
       
  6357     view.show();
       
  6358     QTest::qWaitForWindowShown(&view);
       
  6359     QTRY_VERIFY(!paintedItems.isEmpty());
       
  6360     QTest::qWait(100);
       
  6361     paintedItems.clear();
       
  6362     view.viewport()->update();
       
  6363     QApplication::processEvents();
       
  6364     QTRY_COMPARE(scene.items(0, 0, 100, 100), (QList<QGraphicsItem *>()
       
  6365                                            << grandChild111 << child11
       
  6366                                            << grandChild121 << child12 << parent1
       
  6367                                            << grandChild211 << child21
       
  6368                                            << grandChild221 << child22 << parent2));
       
  6369     QTRY_COMPARE(paintedItems, QList<QGraphicsItem *>()
       
  6370              << parent2 << child22 << grandChild221
       
  6371              << child21 << grandChild211
       
  6372              << parent1 << child12 << grandChild121
       
  6373              << child11 << grandChild111);
       
  6374 
       
  6375     child11->setFlag(QGraphicsItem::ItemStacksBehindParent);
       
  6376     scene.update();
       
  6377     paintedItems.clear();
       
  6378     QApplication::processEvents();
       
  6379 
       
  6380     QTRY_COMPARE(scene.items(0, 0, 100, 100), (QList<QGraphicsItem *>()
       
  6381                                            << grandChild121 << child12 << parent1
       
  6382                                            << grandChild111 << child11
       
  6383                                            << grandChild211 << child21
       
  6384                                            << grandChild221 << child22 << parent2));
       
  6385     QCOMPARE(paintedItems, QList<QGraphicsItem *>()
       
  6386              << parent2 << child22 << grandChild221
       
  6387              << child21 << grandChild211
       
  6388              << child11 << grandChild111
       
  6389              << parent1 << child12 << grandChild121);
       
  6390 
       
  6391     child12->setFlag(QGraphicsItem::ItemStacksBehindParent);
       
  6392     paintedItems.clear();
       
  6393     scene.update();
       
  6394     QApplication::processEvents();
       
  6395 
       
  6396     QTRY_COMPARE(scene.items(0, 0, 100, 100), (QList<QGraphicsItem *>()
       
  6397                                            << parent1 << grandChild111 << child11
       
  6398                                            << grandChild121 << child12
       
  6399                                            << grandChild211 << child21
       
  6400                                            << grandChild221 << child22 << parent2));
       
  6401     QCOMPARE(paintedItems, QList<QGraphicsItem *>()
       
  6402              << parent2 << child22 << grandChild221
       
  6403              << child21 << grandChild211
       
  6404              << child12 << grandChild121
       
  6405              << child11 << grandChild111 << parent1);
       
  6406 }
       
  6407 
       
  6408 class ClippingAndTransformsScene : public QGraphicsScene
       
  6409 {
       
  6410 public:
       
  6411     QList<QGraphicsItem *> drawnItems;
       
  6412 protected:
       
  6413     void drawItems(QPainter *painter, int numItems, QGraphicsItem *items[],
       
  6414                    const QStyleOptionGraphicsItem options[], QWidget *widget = 0)
       
  6415     {
       
  6416         drawnItems.clear();
       
  6417         for (int i = 0; i < numItems; ++i)
       
  6418             drawnItems << items[i];
       
  6419         QGraphicsScene::drawItems(painter, numItems, items, options, widget);
       
  6420     }
       
  6421 };
       
  6422 
       
  6423 void tst_QGraphicsItem::nestedClipping()
       
  6424 {
       
  6425     ClippingAndTransformsScene scene;
       
  6426     scene.setSceneRect(-50, -50, 200, 200);
       
  6427 
       
  6428     QGraphicsRectItem *root = new QGraphicsRectItem(QRectF(0, 0, 100, 100));
       
  6429     root->setBrush(QColor(0, 0, 255));
       
  6430     root->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  6431     QGraphicsRectItem *l1 = new QGraphicsRectItem(QRectF(0, 0, 100, 100));
       
  6432     l1->setParentItem(root);
       
  6433     l1->setPos(-50, 0);
       
  6434     l1->setBrush(QColor(255, 0, 0));
       
  6435     l1->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  6436     QGraphicsEllipseItem *l2 = new QGraphicsEllipseItem(QRectF(0, 0, 100, 100));
       
  6437     l2->setParentItem(l1);
       
  6438     l2->setPos(50, 50);
       
  6439     l2->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  6440     l2->setBrush(QColor(255, 255, 0));
       
  6441     QGraphicsRectItem *l3 = new QGraphicsRectItem(QRectF(0, 0, 25, 25));
       
  6442     l3->setParentItem(l2);
       
  6443     l3->setBrush(QColor(0, 255, 0));
       
  6444     l3->setPos(50 - 12, -12);
       
  6445 
       
  6446     scene.addItem(root);
       
  6447 
       
  6448     root->setData(0, "root");
       
  6449     l1->setData(0, "l1");
       
  6450     l2->setData(0, "l2");
       
  6451     l3->setData(0, "l3");
       
  6452 
       
  6453     QGraphicsView view(&scene);
       
  6454     view.setOptimizationFlag(QGraphicsView::IndirectPainting);
       
  6455     view.show();
       
  6456     QTest::qWaitForWindowShown(&view);
       
  6457     QTest::qWait(25);
       
  6458 
       
  6459     QList<QGraphicsItem *> expected;
       
  6460     expected << root << l1 << l2 << l3;
       
  6461     QTRY_COMPARE(scene.drawnItems, expected);
       
  6462 
       
  6463     QImage image(200, 200, QImage::Format_ARGB32_Premultiplied);
       
  6464     image.fill(0);
       
  6465 
       
  6466     QPainter painter(&image);
       
  6467     scene.render(&painter);
       
  6468     painter.end();
       
  6469 
       
  6470     // Check transparent areas
       
  6471     QCOMPARE(image.pixel(100, 25), qRgba(0, 0, 0, 0));
       
  6472     QCOMPARE(image.pixel(100, 175), qRgba(0, 0, 0, 0));
       
  6473     QCOMPARE(image.pixel(25, 100), qRgba(0, 0, 0, 0));
       
  6474     QCOMPARE(image.pixel(175, 100), qRgba(0, 0, 0, 0));
       
  6475     QCOMPARE(image.pixel(70, 80), qRgba(255, 0, 0, 255));
       
  6476     QCOMPARE(image.pixel(80, 130), qRgba(255, 255, 0, 255));
       
  6477     QCOMPARE(image.pixel(92, 105), qRgba(0, 255, 0, 255));
       
  6478     QCOMPARE(image.pixel(105, 105), qRgba(0, 0, 255, 255));
       
  6479 #if 0
       
  6480     // Enable this to compare if the test starts failing.
       
  6481     image.save("nestedClipping_reference.png");
       
  6482 #endif
       
  6483 }
       
  6484 
       
  6485 class TransformDebugItem : public QGraphicsRectItem
       
  6486 {
       
  6487 public:
       
  6488     TransformDebugItem()
       
  6489         : QGraphicsRectItem(QRectF(-10, -10, 20, 20))
       
  6490     {
       
  6491         setBrush(QColor(qrand() % 256, qrand() % 256, qrand() % 256));
       
  6492     }
       
  6493 
       
  6494     QTransform x;
       
  6495 
       
  6496     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
       
  6497                QWidget *widget = 0)
       
  6498     {
       
  6499         x = painter->worldTransform();
       
  6500         QGraphicsRectItem::paint(painter, option, widget);
       
  6501     }
       
  6502 };
       
  6503 
       
  6504 void tst_QGraphicsItem::nestedClippingTransforms()
       
  6505 {
       
  6506     TransformDebugItem *rootClipper = new TransformDebugItem;
       
  6507     rootClipper->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  6508     TransformDebugItem *child = new TransformDebugItem;
       
  6509     child->setParentItem(rootClipper);
       
  6510     child->setPos(2, 2);
       
  6511     TransformDebugItem *grandChildClipper = new TransformDebugItem;
       
  6512     grandChildClipper->setParentItem(child);
       
  6513     grandChildClipper->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  6514     grandChildClipper->setPos(4, 4);
       
  6515     TransformDebugItem *greatGrandChild = new TransformDebugItem;
       
  6516     greatGrandChild->setPos(2, 2);
       
  6517     greatGrandChild->setParentItem(grandChildClipper);
       
  6518     TransformDebugItem *grandChildClipper2 = new TransformDebugItem;
       
  6519     grandChildClipper2->setParentItem(child);
       
  6520     grandChildClipper2->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  6521     grandChildClipper2->setPos(8, 8);
       
  6522     TransformDebugItem *greatGrandChild2 = new TransformDebugItem;
       
  6523     greatGrandChild2->setPos(2, 2);
       
  6524     greatGrandChild2->setParentItem(grandChildClipper2);
       
  6525     TransformDebugItem *grandChildClipper3 = new TransformDebugItem;
       
  6526     grandChildClipper3->setParentItem(child);
       
  6527     grandChildClipper3->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  6528     grandChildClipper3->setPos(12, 12);
       
  6529     TransformDebugItem *greatGrandChild3 = new TransformDebugItem;
       
  6530     greatGrandChild3->setPos(2, 2);
       
  6531     greatGrandChild3->setParentItem(grandChildClipper3);
       
  6532 
       
  6533     QGraphicsScene scene;
       
  6534     scene.addItem(rootClipper);
       
  6535 
       
  6536     QImage image(scene.itemsBoundingRect().size().toSize(), QImage::Format_ARGB32_Premultiplied);
       
  6537     image.fill(0);
       
  6538     QPainter p(&image);
       
  6539     scene.render(&p);
       
  6540     p.end();
       
  6541 
       
  6542     QCOMPARE(rootClipper->x, QTransform(1, 0, 0, 0, 1, 0, 10, 10, 1));
       
  6543     QCOMPARE(child->x, QTransform(1, 0, 0, 0, 1, 0, 12, 12, 1));
       
  6544     QCOMPARE(grandChildClipper->x, QTransform(1, 0, 0, 0, 1, 0, 16, 16, 1));
       
  6545     QCOMPARE(greatGrandChild->x, QTransform(1, 0, 0, 0, 1, 0, 18, 18, 1));
       
  6546     QCOMPARE(grandChildClipper2->x, QTransform(1, 0, 0, 0, 1, 0, 20, 20, 1));
       
  6547     QCOMPARE(greatGrandChild2->x, QTransform(1, 0, 0, 0, 1, 0, 22, 22, 1));
       
  6548     QCOMPARE(grandChildClipper3->x, QTransform(1, 0, 0, 0, 1, 0, 24, 24, 1));
       
  6549     QCOMPARE(greatGrandChild3->x, QTransform(1, 0, 0, 0, 1, 0, 26, 26, 1));
       
  6550 }
       
  6551 
       
  6552 void tst_QGraphicsItem::sceneTransformCache()
       
  6553 {
       
  6554     // Test that an item's scene transform is updated correctly when the
       
  6555     // parent is transformed.
       
  6556     QGraphicsScene scene;
       
  6557     QGraphicsRectItem *rect = scene.addRect(0, 0, 100, 100);
       
  6558     QGraphicsRectItem *rect2 = scene.addRect(0, 0, 100, 100);
       
  6559     rect2->setParentItem(rect);
       
  6560     rect2->rotate(90);
       
  6561     rect->translate(0, 50);
       
  6562     QGraphicsView view(&scene);
       
  6563     view.show();
       
  6564 #ifdef Q_WS_X11
       
  6565     qt_x11_wait_for_window_manager(&view);
       
  6566 #endif
       
  6567 
       
  6568     rect->translate(0, 100);
       
  6569     QTransform x;
       
  6570     x.translate(0, 150);
       
  6571     x.rotate(90);
       
  6572     QCOMPARE(rect2->sceneTransform(), x);
       
  6573 
       
  6574     scene.removeItem(rect);
       
  6575 
       
  6576     //Crazy use case : rect4 child of rect3 so the transformation of rect4 will be cached.Good!
       
  6577     //We remove rect4 from the scene, then the validTransform bit flag is set to 0 and the index of the cache
       
  6578     //add to the freeTransformSlots. The problem was that sceneTransformIndex was not set to -1 so if a new item arrive
       
  6579     //with a child (rect6) that will be cached then it will take the freeSlot (ex rect4) and put it his transform. But if rect4 is
       
  6580     //added back to the scene then it will set the transform to his old sceneTransformIndex value that will erase the new
       
  6581     //value of rect6 so rect6 transform will be wrong.
       
  6582     QGraphicsRectItem *rect3 = scene.addRect(0, 0, 100, 100);
       
  6583     QGraphicsRectItem *rect4 = scene.addRect(0, 0, 100, 100);
       
  6584     rect3->setPos(QPointF(10,10));
       
  6585 
       
  6586     rect4->setParentItem(rect3);
       
  6587     rect4->setPos(QPointF(10,10));
       
  6588 
       
  6589     QCOMPARE(rect4->mapToScene(rect4->boundingRect().topLeft()), QPointF(20,20));
       
  6590 
       
  6591     scene.removeItem(rect4);
       
  6592     //rect4 transform is local only
       
  6593     QCOMPARE(rect4->mapToScene(rect4->boundingRect().topLeft()), QPointF(10,10));
       
  6594 
       
  6595     QGraphicsRectItem *rect5 = scene.addRect(0, 0, 100, 100);
       
  6596     QGraphicsRectItem *rect6 = scene.addRect(0, 0, 100, 100);
       
  6597     rect5->setPos(QPointF(20,20));
       
  6598 
       
  6599     rect6->setParentItem(rect5);
       
  6600     rect6->setPos(QPointF(10,10));
       
  6601     //test if rect6 transform is ok
       
  6602     QCOMPARE(rect6->mapToScene(rect6->boundingRect().topLeft()), QPointF(30,30));
       
  6603 
       
  6604     scene.addItem(rect4);
       
  6605 
       
  6606     QCOMPARE(rect4->mapToScene(rect4->boundingRect().topLeft()), QPointF(10,10));
       
  6607     //test if rect6 transform is still correct
       
  6608     QCOMPARE(rect6->mapToScene(rect6->boundingRect().topLeft()), QPointF(30,30));
       
  6609 }
       
  6610 
       
  6611 void tst_QGraphicsItem::tabChangesFocus_data()
       
  6612 {
       
  6613     QTest::addColumn<bool>("tabChangesFocus");
       
  6614     QTest::newRow("tab changes focus") << true;
       
  6615     QTest::newRow("tab doesn't change focus") << false;
       
  6616 }
       
  6617 
       
  6618 void tst_QGraphicsItem::tabChangesFocus()
       
  6619 {
       
  6620     QFETCH(bool, tabChangesFocus);
       
  6621 
       
  6622     QGraphicsScene scene;
       
  6623     QGraphicsTextItem *item = scene.addText("Hello");
       
  6624     item->setTabChangesFocus(tabChangesFocus);
       
  6625     item->setTextInteractionFlags(Qt::TextEditorInteraction);
       
  6626     item->setFocus();
       
  6627 
       
  6628     QDial *dial1 = new QDial;
       
  6629     QGraphicsView *view = new QGraphicsView(&scene);
       
  6630 
       
  6631     QDial *dial2 = new QDial;
       
  6632     QVBoxLayout *layout = new QVBoxLayout;
       
  6633     layout->addWidget(dial1);
       
  6634     layout->addWidget(view);
       
  6635     layout->addWidget(dial2);
       
  6636 
       
  6637     QWidget widget;
       
  6638     widget.setLayout(layout);
       
  6639     widget.show();
       
  6640     QTest::qWaitForWindowShown(&widget);
       
  6641 
       
  6642     QTRY_VERIFY(scene.isActive());
       
  6643 
       
  6644     dial1->setFocus();
       
  6645     QTest::qWait(15);
       
  6646     QTRY_VERIFY(dial1->hasFocus());
       
  6647 
       
  6648     QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
       
  6649     QTest::qWait(15);
       
  6650     QTRY_VERIFY(view->hasFocus());
       
  6651     QTRY_VERIFY(item->hasFocus());
       
  6652 
       
  6653     QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
       
  6654     QTest::qWait(15);
       
  6655 
       
  6656     if (tabChangesFocus) {
       
  6657         QTRY_VERIFY(!view->hasFocus());
       
  6658         QTRY_VERIFY(!item->hasFocus());
       
  6659         QTRY_VERIFY(dial2->hasFocus());
       
  6660     } else {
       
  6661         QTRY_VERIFY(view->hasFocus());
       
  6662         QTRY_VERIFY(item->hasFocus());
       
  6663         QCOMPARE(item->toPlainText(), QString("\tHello"));
       
  6664     }
       
  6665 }
       
  6666 
       
  6667 void tst_QGraphicsItem::cacheMode()
       
  6668 {
       
  6669     QGraphicsScene scene(0, 0, 100, 100);
       
  6670     QGraphicsView view(&scene);
       
  6671     view.resize(150, 150);
       
  6672     view.show();
       
  6673     QApplication::setActiveWindow(&view);
       
  6674     QTest::qWaitForWindowShown(&view);
       
  6675 
       
  6676     // Increase the probability of window activation
       
  6677     // not causing another repaint of test items.
       
  6678     QTest::qWait(50);
       
  6679 
       
  6680     EventTester *tester = new EventTester;
       
  6681     EventTester *testerChild = new EventTester;
       
  6682     testerChild->setParentItem(tester);
       
  6683     EventTester *testerChild2 = new EventTester;
       
  6684     testerChild2->setParentItem(testerChild);
       
  6685     testerChild2->setFlag(QGraphicsItem::ItemIgnoresTransformations);
       
  6686 
       
  6687     scene.addItem(tester);
       
  6688     QTest::qWait(10);
       
  6689 
       
  6690     for (int i = 0; i < 2; ++i) {
       
  6691         // No visual change.
       
  6692         QTRY_COMPARE(tester->repaints, 1);
       
  6693         QCOMPARE(testerChild->repaints, 1);
       
  6694         QCOMPARE(testerChild2->repaints, 1);
       
  6695         tester->setCacheMode(QGraphicsItem::NoCache);
       
  6696         testerChild->setCacheMode(QGraphicsItem::NoCache);
       
  6697         testerChild2->setCacheMode(QGraphicsItem::NoCache);
       
  6698         QTest::qWait(25);
       
  6699         QTRY_COMPARE(tester->repaints, 1);
       
  6700         QCOMPARE(testerChild->repaints, 1);
       
  6701         QCOMPARE(testerChild2->repaints, 1);
       
  6702         tester->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
       
  6703         testerChild->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
       
  6704         testerChild2->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
       
  6705         QTest::qWait(25);
       
  6706     }
       
  6707 
       
  6708     // The first move causes a repaint as the item is painted into its pixmap.
       
  6709     // (Only occurs if the item has previously been painted without cache).
       
  6710     tester->setPos(10, 10);
       
  6711     testerChild->setPos(10, 10);
       
  6712     testerChild2->setPos(10, 10);
       
  6713     QTest::qWait(25);
       
  6714     QTRY_COMPARE(tester->repaints, 2);
       
  6715     QCOMPARE(testerChild->repaints, 2);
       
  6716     QCOMPARE(testerChild2->repaints, 2);
       
  6717 
       
  6718     // Consecutive moves should not repaint.
       
  6719     tester->setPos(20, 20);
       
  6720     testerChild->setPos(20, 20);
       
  6721     testerChild2->setPos(20, 20);
       
  6722     QTest::qWait(250);
       
  6723     QCOMPARE(tester->repaints, 2);
       
  6724     QCOMPARE(testerChild->repaints, 2);
       
  6725     QCOMPARE(testerChild2->repaints, 2);
       
  6726 
       
  6727     // Translating does not result in a repaint.
       
  6728     tester->translate(10, 10);
       
  6729     QTest::qWait(25);
       
  6730     QTRY_COMPARE(tester->repaints, 2);
       
  6731     QCOMPARE(testerChild->repaints, 2);
       
  6732     QCOMPARE(testerChild2->repaints, 2);
       
  6733 
       
  6734     // Rotating results in a repaint.
       
  6735     tester->rotate(45);
       
  6736     QTest::qWait(25);
       
  6737     QTRY_COMPARE(tester->repaints, 3);
       
  6738     QCOMPARE(testerChild->repaints, 3);
       
  6739     QCOMPARE(testerChild2->repaints, 2);
       
  6740 
       
  6741     // Change to ItemCoordinateCache (triggers repaint).
       
  6742     tester->setCacheMode(QGraphicsItem::ItemCoordinateCache); // autosize
       
  6743     testerChild->setCacheMode(QGraphicsItem::ItemCoordinateCache); // autosize
       
  6744     testerChild2->setCacheMode(QGraphicsItem::ItemCoordinateCache); // autosize
       
  6745     QTest::qWait(25);
       
  6746     QTRY_COMPARE(tester->repaints, 4);
       
  6747     QCOMPARE(testerChild->repaints, 4);
       
  6748     QCOMPARE(testerChild2->repaints, 3);
       
  6749 
       
  6750     // Rotating items with ItemCoordinateCache doesn't cause a repaint.
       
  6751     tester->rotate(22);
       
  6752     testerChild->rotate(22);
       
  6753     testerChild2->rotate(22);
       
  6754     QTest::qWait(25);
       
  6755     QTRY_COMPARE(tester->repaints, 4);
       
  6756     QCOMPARE(testerChild->repaints, 4);
       
  6757     QCOMPARE(testerChild2->repaints, 3);
       
  6758 
       
  6759     // Explicit update causes a repaint.
       
  6760     tester->update(0, 0, 5, 5);
       
  6761     QTest::qWait(25);
       
  6762     QTRY_COMPARE(tester->repaints, 5);
       
  6763     QCOMPARE(testerChild->repaints, 4);
       
  6764     QCOMPARE(testerChild2->repaints, 3);
       
  6765 
       
  6766     // Updating outside the item's bounds does not cause a repaint.
       
  6767     tester->update(10, 10, 5, 5);
       
  6768     QTest::qWait(25);
       
  6769     QTRY_COMPARE(tester->repaints, 5);
       
  6770     QCOMPARE(testerChild->repaints, 4);
       
  6771     QCOMPARE(testerChild2->repaints, 3);
       
  6772 
       
  6773     // Resizing an item should cause a repaint of that item. (because of
       
  6774     // autosize).
       
  6775     tester->setGeometry(QRectF(-15, -15, 30, 30));
       
  6776     QTest::qWait(25);
       
  6777     QTRY_COMPARE(tester->repaints, 6);
       
  6778     QCOMPARE(testerChild->repaints, 4);
       
  6779     QCOMPARE(testerChild2->repaints, 3);
       
  6780 
       
  6781     // Set fixed size.
       
  6782     tester->setCacheMode(QGraphicsItem::ItemCoordinateCache, QSize(30, 30));
       
  6783     testerChild->setCacheMode(QGraphicsItem::ItemCoordinateCache, QSize(30, 30));
       
  6784     testerChild2->setCacheMode(QGraphicsItem::ItemCoordinateCache, QSize(30, 30));
       
  6785     QTest::qWait(20);
       
  6786     QTRY_COMPARE(tester->repaints, 7);
       
  6787     QCOMPARE(testerChild->repaints, 5);
       
  6788     QCOMPARE(testerChild2->repaints, 4);
       
  6789 
       
  6790     // Resizing the item should cause a repaint.
       
  6791     testerChild->setGeometry(QRectF(-15, -15, 30, 30));
       
  6792     QTest::qWait(25);
       
  6793     QTRY_COMPARE(tester->repaints, 7);
       
  6794     QCOMPARE(testerChild->repaints, 6);
       
  6795     QCOMPARE(testerChild2->repaints, 4);
       
  6796 
       
  6797     // Scaling the view does not cause a repaint.
       
  6798     view.scale(0.7, 0.7);
       
  6799     QTest::qWait(25);
       
  6800     QTRY_COMPARE(tester->repaints, 7);
       
  6801     QCOMPARE(testerChild->repaints, 6);
       
  6802     QCOMPARE(testerChild2->repaints, 4);
       
  6803 
       
  6804     // Switch to device coordinate cache.
       
  6805     tester->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
       
  6806     testerChild->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
       
  6807     testerChild2->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
       
  6808     QTest::qWait(25);
       
  6809     QTRY_COMPARE(tester->repaints, 8);
       
  6810     QCOMPARE(testerChild->repaints, 7);
       
  6811     QCOMPARE(testerChild2->repaints, 5);
       
  6812 
       
  6813     // Scaling the view back should cause repaints for two of the items.
       
  6814     view.setTransform(QTransform());
       
  6815     QTest::qWait(25);
       
  6816     QTRY_COMPARE(tester->repaints, 9);
       
  6817     QCOMPARE(testerChild->repaints, 8);
       
  6818     QCOMPARE(testerChild2->repaints, 5);
       
  6819 
       
  6820     // Rotating the base item (perspective) should repaint two items.
       
  6821     tester->setTransform(QTransform().rotate(10, Qt::XAxis));
       
  6822     QTest::qWait(25);
       
  6823     QTRY_COMPARE(tester->repaints, 10);
       
  6824     QCOMPARE(testerChild->repaints, 9);
       
  6825     QCOMPARE(testerChild2->repaints, 5);
       
  6826 
       
  6827     // Moving the middle item should case a repaint even if it's a move,
       
  6828     // because the parent is rotated with a perspective.
       
  6829     testerChild->setPos(1, 1);
       
  6830     QTest::qWait(25);
       
  6831     QTRY_COMPARE(tester->repaints, 10);
       
  6832     QCOMPARE(testerChild->repaints, 10);
       
  6833     QCOMPARE(testerChild2->repaints, 5);
       
  6834 
       
  6835     // Make a huge item
       
  6836     tester->setGeometry(QRectF(-4000, -4000, 8000, 8000));
       
  6837     QTest::qWait(25);
       
  6838     QTRY_COMPARE(tester->repaints, 11);
       
  6839     QCOMPARE(testerChild->repaints, 10);
       
  6840     QCOMPARE(testerChild2->repaints, 5);
       
  6841 
       
  6842     // Move the large item - will cause a repaint as the
       
  6843     // cache is clipped.
       
  6844     tester->setPos(5, 0);
       
  6845     QTest::qWait(25);
       
  6846     QTRY_COMPARE(tester->repaints, 12);
       
  6847     QCOMPARE(testerChild->repaints, 10);
       
  6848     QCOMPARE(testerChild2->repaints, 5);
       
  6849 
       
  6850     // Hiding and showing should invalidate the cache
       
  6851     tester->hide();
       
  6852     QTest::qWait(25);
       
  6853     tester->show();
       
  6854     QTest::qWait(25);
       
  6855     QTRY_COMPARE(tester->repaints, 13);
       
  6856     QCOMPARE(testerChild->repaints, 11);
       
  6857     QCOMPARE(testerChild2->repaints, 6);
       
  6858 }
       
  6859 
       
  6860 void tst_QGraphicsItem::updateCachedItemAfterMove()
       
  6861 {
       
  6862     // A simple item that uses ItemCoordinateCache
       
  6863     EventTester *tester = new EventTester;
       
  6864     tester->setCacheMode(QGraphicsItem::ItemCoordinateCache);
       
  6865 
       
  6866     // Add to a scene, show in a view, ensure it's painted and reset its
       
  6867     // repaint counter.
       
  6868     QGraphicsScene scene;
       
  6869     scene.addItem(tester);
       
  6870     QGraphicsView view(&scene);
       
  6871     view.show();
       
  6872     QTest::qWaitForWindowShown(&view);
       
  6873 
       
  6874     QTest::qWait(12);
       
  6875     QTRY_VERIFY(tester->repaints > 0);
       
  6876     tester->repaints = 0;
       
  6877 
       
  6878     // Move the item, should not cause repaints
       
  6879     tester->setPos(10, 0);
       
  6880     QTest::qWait(12);
       
  6881     QCOMPARE(tester->repaints, 0);
       
  6882 
       
  6883     // Move then update, should cause one repaint
       
  6884     tester->setPos(20, 0);
       
  6885     tester->update();
       
  6886     QTest::qWait(12);
       
  6887     QCOMPARE(tester->repaints, 1);
       
  6888 
       
  6889     // Hiding the item doesn't cause a repaint
       
  6890     tester->hide();
       
  6891     QTest::qWait(12);
       
  6892     QCOMPARE(tester->repaints, 1);
       
  6893 
       
  6894     // Moving a hidden item doesn't cause a repaint
       
  6895     tester->setPos(30, 0);
       
  6896     tester->update();
       
  6897     QTest::qWait(12);
       
  6898     QCOMPARE(tester->repaints, 1);
       
  6899 }
       
  6900 
       
  6901 class Track : public QGraphicsRectItem
       
  6902 {
       
  6903 public:
       
  6904     Track(const QRectF &rect)
       
  6905         : QGraphicsRectItem(rect)
       
  6906     {
       
  6907         setAcceptHoverEvents(true);
       
  6908     }
       
  6909 
       
  6910     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0)
       
  6911     {
       
  6912         QGraphicsRectItem::paint(painter, option, widget);
       
  6913         painter->drawText(boundingRect(), Qt::AlignCenter, QString("%1x%2\n%3x%4").arg(p.x()).arg(p.y()).arg(sp.x()).arg(sp.y()));
       
  6914     }
       
  6915 
       
  6916 protected:
       
  6917     void hoverMoveEvent(QGraphicsSceneHoverEvent *event)
       
  6918     {
       
  6919         p = event->pos();
       
  6920         sp = event->widget()->mapFromGlobal(event->screenPos());
       
  6921         update();
       
  6922     }
       
  6923 private:
       
  6924     QPointF p;
       
  6925     QPoint sp;
       
  6926 };
       
  6927 
       
  6928 void tst_QGraphicsItem::deviceTransform_data()
       
  6929 {
       
  6930     QTest::addColumn<bool>("untransformable1");
       
  6931     QTest::addColumn<bool>("untransformable2");
       
  6932     QTest::addColumn<bool>("untransformable3");
       
  6933     QTest::addColumn<qreal>("rotation1");
       
  6934     QTest::addColumn<qreal>("rotation2");
       
  6935     QTest::addColumn<qreal>("rotation3");
       
  6936     QTest::addColumn<QTransform>("deviceX");
       
  6937     QTest::addColumn<QPointF>("mapResult1");
       
  6938     QTest::addColumn<QPointF>("mapResult2");
       
  6939     QTest::addColumn<QPointF>("mapResult3");
       
  6940 
       
  6941     QTest::newRow("nil") << false << false << false
       
  6942                          << qreal(0.0) << qreal(0.0) << qreal(0.0)
       
  6943                          << QTransform()
       
  6944                          << QPointF(150, 150) << QPointF(250, 250) << QPointF(350, 350);
       
  6945     QTest::newRow("deviceX rot 90") << false << false << false
       
  6946                          << qreal(0.0) << qreal(0.0) << qreal(0.0)
       
  6947                          << QTransform().rotate(90)
       
  6948                          << QPointF(-150, 150) << QPointF(-250, 250) << QPointF(-350, 350);
       
  6949     QTest::newRow("deviceX rot 90 100") << true << false << false
       
  6950                          << qreal(0.0) << qreal(0.0) << qreal(0.0)
       
  6951                          << QTransform().rotate(90)
       
  6952                          << QPointF(-50, 150) << QPointF(50, 250) << QPointF(150, 350);
       
  6953     QTest::newRow("deviceX rot 90 010") << false << true << false
       
  6954                          << qreal(0.0) << qreal(0.0) << qreal(0.0)
       
  6955                          << QTransform().rotate(90)
       
  6956                          << QPointF(-150, 150) << QPointF(-150, 250) << QPointF(-50, 350);
       
  6957     QTest::newRow("deviceX rot 90 001") << false << false << true
       
  6958                          << qreal(0.0) << qreal(0.0) << qreal(0.0)
       
  6959                          << QTransform().rotate(90)
       
  6960                          << QPointF(-150, 150) << QPointF(-250, 250) << QPointF(-250, 350);
       
  6961     QTest::newRow("deviceX rot 90 111") << true << true << true
       
  6962                          << qreal(0.0) << qreal(0.0) << qreal(0.0)
       
  6963                          << QTransform().rotate(90)
       
  6964                          << QPointF(-50, 150) << QPointF(50, 250) << QPointF(150, 350);
       
  6965     QTest::newRow("deviceX rot 90 101") << true << false << true
       
  6966                          << qreal(0.0) << qreal(0.0) << qreal(0.0)
       
  6967                          << QTransform().rotate(90)
       
  6968                          << QPointF(-50, 150) << QPointF(50, 250) << QPointF(150, 350);
       
  6969 }
       
  6970 
       
  6971 void tst_QGraphicsItem::deviceTransform()
       
  6972 {
       
  6973     QFETCH(bool, untransformable1);
       
  6974     QFETCH(bool, untransformable2);
       
  6975     QFETCH(bool, untransformable3);
       
  6976     QFETCH(qreal, rotation1);
       
  6977     QFETCH(qreal, rotation2);
       
  6978     QFETCH(qreal, rotation3);
       
  6979     QFETCH(QTransform, deviceX);
       
  6980     QFETCH(QPointF, mapResult1);
       
  6981     QFETCH(QPointF, mapResult2);
       
  6982     QFETCH(QPointF, mapResult3);
       
  6983 
       
  6984     QGraphicsScene scene;
       
  6985     Track *rect1 = new Track(QRectF(0, 0, 100, 100));
       
  6986     Track *rect2 = new Track(QRectF(0, 0, 100, 100));
       
  6987     Track *rect3 = new Track(QRectF(0, 0, 100, 100));
       
  6988     rect2->setParentItem(rect1);
       
  6989     rect3->setParentItem(rect2);
       
  6990     rect1->setPos(100, 100);
       
  6991     rect2->setPos(100, 100);
       
  6992     rect3->setPos(100, 100);
       
  6993     rect1->rotate(rotation1);
       
  6994     rect2->rotate(rotation2);
       
  6995     rect3->rotate(rotation3);
       
  6996     rect1->setFlag(QGraphicsItem::ItemIgnoresTransformations, untransformable1);
       
  6997     rect2->setFlag(QGraphicsItem::ItemIgnoresTransformations, untransformable2);
       
  6998     rect3->setFlag(QGraphicsItem::ItemIgnoresTransformations, untransformable3);
       
  6999     rect1->setBrush(Qt::red);
       
  7000     rect2->setBrush(Qt::green);
       
  7001     rect3->setBrush(Qt::blue);
       
  7002     scene.addItem(rect1);
       
  7003 
       
  7004     QCOMPARE(rect1->deviceTransform(deviceX).map(QPointF(50, 50)), mapResult1);
       
  7005     QCOMPARE(rect2->deviceTransform(deviceX).map(QPointF(50, 50)), mapResult2);
       
  7006     QCOMPARE(rect3->deviceTransform(deviceX).map(QPointF(50, 50)), mapResult3);
       
  7007 }
       
  7008 
       
  7009 class MyGraphicsView : public QGraphicsView
       
  7010 {
       
  7011 public:
       
  7012     int repaints;
       
  7013     QRegion paintedRegion;
       
  7014     MyGraphicsView(QGraphicsScene *scene) : QGraphicsView(scene), repaints(0) {}
       
  7015     void paintEvent(QPaintEvent *e)
       
  7016     {
       
  7017         paintedRegion += e->region();
       
  7018         ++repaints;
       
  7019         QGraphicsView::paintEvent(e);
       
  7020     }
       
  7021     void reset() { repaints = 0; paintedRegion = QRegion(); }
       
  7022 };
       
  7023 
       
  7024 void tst_QGraphicsItem::update()
       
  7025 {
       
  7026     QGraphicsScene scene;
       
  7027     scene.setSceneRect(-100, -100, 200, 200);
       
  7028     MyGraphicsView view(&scene);
       
  7029 
       
  7030     view.show();
       
  7031 #ifdef Q_WS_X11
       
  7032     qt_x11_wait_for_window_manager(&view);
       
  7033 #endif
       
  7034     QTest::qWait(100);
       
  7035 
       
  7036     EventTester *item = new EventTester;
       
  7037     scene.addItem(item);
       
  7038     QTest::qWait(100); // Make sure all pending updates are processed.
       
  7039     item->repaints = 0;
       
  7040 
       
  7041     item->update(); // Item marked as dirty
       
  7042     scene.update(); // Entire scene marked as dirty
       
  7043     qApp->processEvents();
       
  7044     QCOMPARE(item->repaints, 1);
       
  7045 
       
  7046     // Make sure the dirty state from the previous update is reset so that
       
  7047     // the item don't think it is already dirty and discards this update.
       
  7048     item->update();
       
  7049     qApp->processEvents();
       
  7050     QCOMPARE(item->repaints, 2);
       
  7051 
       
  7052     // Make sure a partial update doesn't cause a full update to be discarded.
       
  7053     view.reset();
       
  7054     item->repaints = 0;
       
  7055     item->update(QRectF(0, 0, 5, 5));
       
  7056     item->update();
       
  7057     qApp->processEvents();
       
  7058     QCOMPARE(item->repaints, 1);
       
  7059     QCOMPARE(view.repaints, 1);
       
  7060     QRect itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform())
       
  7061                                                          .mapRect(item->boundingRect()).toRect();
       
  7062     QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2);
       
  7063     // The entire item's bounding rect (adjusted for antialiasing) should have been painted.
       
  7064     QCOMPARE(view.paintedRegion, expectedRegion);
       
  7065 
       
  7066     // Make sure update requests outside the bounding rect are discarded.
       
  7067     view.reset();
       
  7068     item->repaints = 0;
       
  7069     item->update(-15, -15, 5, 5); // Item's brect: (-10, -10, 20, 20)
       
  7070     qApp->processEvents();
       
  7071     QCOMPARE(item->repaints, 0);
       
  7072     QCOMPARE(view.repaints, 0);
       
  7073 
       
  7074     // Make sure the area occupied by an item is repainted when hiding it.
       
  7075     view.reset();
       
  7076     item->repaints = 0;
       
  7077     item->update(); // Full update; all sub-sequent update requests are discarded.
       
  7078     item->hide(); // visible set to 0. ignoreVisible must be set to 1; the item won't be processed otherwise.
       
  7079     qApp->processEvents();
       
  7080     QCOMPARE(item->repaints, 0);
       
  7081     QCOMPARE(view.repaints, 1);
       
  7082     // The entire item's bounding rect (adjusted for antialiasing) should have been painted.
       
  7083     QCOMPARE(view.paintedRegion, expectedRegion);
       
  7084 
       
  7085     // Make sure item is repainted when shown (after being hidden).
       
  7086     view.reset();
       
  7087     item->repaints = 0;
       
  7088     item->show();
       
  7089     qApp->processEvents();
       
  7090     QCOMPARE(item->repaints, 1);
       
  7091     QCOMPARE(view.repaints, 1);
       
  7092     // The entire item's bounding rect (adjusted for antialiasing) should have been painted.
       
  7093     QCOMPARE(view.paintedRegion, expectedRegion);
       
  7094 
       
  7095     item->repaints = 0;
       
  7096     item->hide();
       
  7097     qApp->processEvents();
       
  7098     view.reset();
       
  7099     const QPointF originalPos = item->pos();
       
  7100     item->setPos(5000, 5000);
       
  7101     qApp->processEvents();
       
  7102     QCOMPARE(item->repaints, 0);
       
  7103     QCOMPARE(view.repaints, 0);
       
  7104     qApp->processEvents();
       
  7105 
       
  7106     item->setPos(originalPos);
       
  7107     qApp->processEvents();
       
  7108     QCOMPARE(item->repaints, 0);
       
  7109     QCOMPARE(view.repaints, 0);
       
  7110     item->show();
       
  7111     qApp->processEvents();
       
  7112     QCOMPARE(item->repaints, 1);
       
  7113     QCOMPARE(view.repaints, 1);
       
  7114     // The entire item's bounding rect (adjusted for antialiasing) should have been painted.
       
  7115     QCOMPARE(view.paintedRegion, expectedRegion);
       
  7116 
       
  7117     QGraphicsViewPrivate *viewPrivate = static_cast<QGraphicsViewPrivate *>(qt_widget_private(&view));
       
  7118     item->setPos(originalPos + QPoint(50, 50));
       
  7119     viewPrivate->updateAll();
       
  7120     QVERIFY(viewPrivate->fullUpdatePending);
       
  7121     QTest::qWait(50);
       
  7122     item->repaints = 0;
       
  7123     view.reset();
       
  7124     item->setPos(originalPos);
       
  7125     QTest::qWait(50);
       
  7126     qApp->processEvents();
       
  7127     QCOMPARE(item->repaints, 1);
       
  7128     QCOMPARE(view.repaints, 1);
       
  7129     COMPARE_REGIONS(view.paintedRegion, expectedRegion + expectedRegion.translated(50, 50));
       
  7130 
       
  7131     // Make sure moving a parent item triggers an update on the children
       
  7132     // (even though the parent itself is outside the viewport).
       
  7133     QGraphicsRectItem *parent = new QGraphicsRectItem(0, 0, 10, 10);
       
  7134     parent->setPos(-400, 0);
       
  7135     item->setParentItem(parent);
       
  7136     item->setPos(400, 0);
       
  7137     scene.addItem(parent);
       
  7138     QTest::qWait(50);
       
  7139     itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform())
       
  7140                                                    .mapRect(item->boundingRect()).toRect();
       
  7141     expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2);
       
  7142     view.reset();
       
  7143     item->repaints = 0;
       
  7144     parent->translate(-400, 0);
       
  7145     qApp->processEvents();
       
  7146     QCOMPARE(item->repaints, 0);
       
  7147     QCOMPARE(view.repaints, 1);
       
  7148     QCOMPARE(view.paintedRegion, expectedRegion);
       
  7149     view.reset();
       
  7150     item->repaints = 0;
       
  7151     parent->translate(400, 0);
       
  7152     qApp->processEvents();
       
  7153     QCOMPARE(item->repaints, 1);
       
  7154     QCOMPARE(view.repaints, 1);
       
  7155     QCOMPARE(view.paintedRegion, expectedRegion);
       
  7156     QCOMPARE(view.paintedRegion, expectedRegion);
       
  7157 }
       
  7158 
       
  7159 void tst_QGraphicsItem::setTransformProperties_data()
       
  7160 {
       
  7161     QTest::addColumn<QPointF>("origin");
       
  7162     QTest::addColumn<qreal>("rotation");
       
  7163     QTest::addColumn<qreal>("scale");
       
  7164 
       
  7165     QTest::newRow("nothing") << QPointF() << qreal(0.0) << qreal(1.0);
       
  7166 
       
  7167     QTest::newRow("rotation") << QPointF() << qreal(42.2) << qreal(1.0);
       
  7168 
       
  7169     QTest::newRow("rotation dicentred") << QPointF(qreal(22.3), qreal(-56.2))
       
  7170                                 << qreal(-2578.2)
       
  7171                                 << qreal(1.0);
       
  7172 
       
  7173     QTest::newRow("Scale")    << QPointF() << qreal(0.0)
       
  7174                                           << qreal(6);
       
  7175 
       
  7176     QTest::newRow("Everything dicentred")  << QPointF(qreal(22.3), qreal(-56.2)) << qreal(-175) << qreal(196);
       
  7177 }
       
  7178 
       
  7179 /**
       
  7180  * the normal QCOMPARE doesn't work because it doesn't use qFuzzyCompare
       
  7181  */
       
  7182 #define QCOMPARE_TRANSFORM(X1, X2)   QVERIFY(((X1)*(X2).inverted()).isIdentity())
       
  7183 
       
  7184 void tst_QGraphicsItem::setTransformProperties()
       
  7185 {
       
  7186     QFETCH(QPointF,origin);
       
  7187     QFETCH(qreal,rotation);
       
  7188     QFETCH(qreal,scale);
       
  7189 
       
  7190     QTransform result;
       
  7191     result.translate(origin.x(), origin.y());
       
  7192     result.rotate(rotation, Qt::ZAxis);
       
  7193     result.scale(scale, scale);
       
  7194     result.translate(-origin.x(), -origin.y());
       
  7195 
       
  7196     QGraphicsScene scene;
       
  7197     QGraphicsRectItem *item = new QGraphicsRectItem(QRectF(0, 0, 100, 100));
       
  7198     scene.addItem(item);
       
  7199 
       
  7200     item->setRotation(rotation);
       
  7201     item->setScale(scale);
       
  7202     item->setTransformOriginPoint(origin);
       
  7203 
       
  7204     QCOMPARE(item->rotation(), rotation);
       
  7205     QCOMPARE(item->scale(), scale);
       
  7206     QCOMPARE(item->transformOriginPoint(), origin);
       
  7207 
       
  7208     QCOMPARE(QTransform(), item->transform());
       
  7209     QCOMPARE(result, item->sceneTransform());
       
  7210 
       
  7211     //-----------------------------------------------------------------
       
  7212     //Change the rotation Z
       
  7213     item->setRotation(45);
       
  7214     QTransform result2;
       
  7215     result2.translate(origin.x(), origin.y());
       
  7216     result2.rotate(45);
       
  7217     result2.scale(scale, scale);
       
  7218     result2.translate(-origin.x(), -origin.y());
       
  7219 
       
  7220     QCOMPARE(item->rotation(), 45.);
       
  7221     QCOMPARE(item->scale(), scale);
       
  7222     QCOMPARE(item->transformOriginPoint(), origin);
       
  7223 
       
  7224     QCOMPARE(QTransform(), item->transform());
       
  7225     QCOMPARE(result2, item->sceneTransform());
       
  7226 
       
  7227     //-----------------------------------------------------------------
       
  7228     // calling setTransform() and setPos should change the sceneTransform
       
  7229     item->setTransform(result);
       
  7230     item->setPos(100, -150.5);
       
  7231 
       
  7232     QCOMPARE(item->rotation(), 45.);
       
  7233     QCOMPARE(item->scale(), scale);
       
  7234     QCOMPARE(item->transformOriginPoint(), origin);
       
  7235     QCOMPARE(result, item->transform());
       
  7236 
       
  7237     QTransform result3(result);
       
  7238 
       
  7239     result3.translate(origin.x(), origin.y());
       
  7240     result3.rotate(45);
       
  7241     result3.scale(scale, scale);
       
  7242     result3.translate(-origin.x(), -origin.y());
       
  7243 
       
  7244     result3 *= QTransform::fromTranslate(100, -150.5); //the pos;
       
  7245 
       
  7246     QCOMPARE(result3, item->sceneTransform());
       
  7247 
       
  7248     //-----------------------------------------------------
       
  7249     // setting the propertiees should be the same as setting a transform
       
  7250     {//with center origin on the matrix
       
  7251         QGraphicsRectItem *item1 = new QGraphicsRectItem(QRectF(50.2, -150, 230.5, 119));
       
  7252         scene.addItem(item1);
       
  7253         QGraphicsRectItem *item2 = new QGraphicsRectItem(QRectF(50.2, -150, 230.5, 119));
       
  7254         scene.addItem(item2);
       
  7255 
       
  7256         item1->setPos(12.3, -5);
       
  7257         item2->setPos(12.3, -5);
       
  7258         item1->setRotation(rotation);
       
  7259         item1->setScale(scale);
       
  7260         item1->setTransformOriginPoint(origin);
       
  7261 
       
  7262         item2->setTransform(result);
       
  7263 
       
  7264         QCOMPARE_TRANSFORM(item1->sceneTransform(), item2->sceneTransform());
       
  7265 
       
  7266         QCOMPARE_TRANSFORM(item1->itemTransform(item2), QTransform());
       
  7267         QCOMPARE_TRANSFORM(item2->itemTransform(item1), QTransform());
       
  7268     }
       
  7269 }
       
  7270 
       
  7271 class MyStyleOptionTester : public QGraphicsRectItem
       
  7272 {
       
  7273 public:
       
  7274     MyStyleOptionTester(const QRectF &rect)
       
  7275         : QGraphicsRectItem(rect), startTrack(false)
       
  7276     {}
       
  7277 
       
  7278     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0)
       
  7279     {
       
  7280         if (startTrack) {
       
  7281             //Doesn't use the extended style option so the exposed rect is the boundingRect
       
  7282             if (!(flags() & QGraphicsItem::ItemUsesExtendedStyleOption)) {
       
  7283                 QCOMPARE(option->exposedRect, boundingRect());
       
  7284                 QCOMPARE(option->matrix, QMatrix());
       
  7285             } else {
       
  7286                 QVERIFY(option->exposedRect != QRect());
       
  7287                 QVERIFY(option->exposedRect != boundingRect());
       
  7288                 QCOMPARE(option->matrix, sceneTransform().toAffine());
       
  7289             }
       
  7290         }
       
  7291         QGraphicsRectItem::paint(painter, option, widget);
       
  7292     }
       
  7293     bool startTrack;
       
  7294 };
       
  7295 
       
  7296 void tst_QGraphicsItem::itemUsesExtendedStyleOption()
       
  7297 {
       
  7298     QGraphicsScene scene(0, 0, 300, 300);
       
  7299     QGraphicsPixmapItem item;
       
  7300     item.setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true);
       
  7301     QCOMPARE(item.flags(), QGraphicsItem::GraphicsItemFlags(QGraphicsItem::ItemUsesExtendedStyleOption));
       
  7302     item.setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, false);
       
  7303     QCOMPARE(item.flags(), 0);
       
  7304 
       
  7305     //We now test the content of the style option
       
  7306     MyStyleOptionTester *rect = new MyStyleOptionTester(QRect(0, 0, 100, 100));
       
  7307     scene.addItem(rect);
       
  7308     rect->setPos(200, 200);
       
  7309     QGraphicsView view(&scene);
       
  7310     rect->startTrack = false;
       
  7311     view.show();
       
  7312     QTest::qWaitForWindowShown(&view);
       
  7313     QTest::qWait(60);
       
  7314     rect->startTrack = true;
       
  7315     rect->update(10, 10, 10, 10);
       
  7316     QTest::qWait(60);
       
  7317     rect->startTrack = false;
       
  7318     rect->setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true);
       
  7319     QVERIFY((rect->flags() & QGraphicsItem::ItemUsesExtendedStyleOption));
       
  7320     QTest::qWait(60);
       
  7321     rect->startTrack = true;
       
  7322     rect->update(10, 10, 10, 10);
       
  7323     QTest::qWait(60);
       
  7324 }
       
  7325 
       
  7326 void tst_QGraphicsItem::itemSendsGeometryChanges()
       
  7327 {
       
  7328     ItemChangeTester item;
       
  7329     item.setFlags(0);
       
  7330     item.clear();
       
  7331 
       
  7332     QTransform x = QTransform().rotate(45);
       
  7333     QPointF pos(10, 10);
       
  7334     qreal o(0.5);
       
  7335     item.setTransform(x);
       
  7336     item.setPos(pos);
       
  7337     QCOMPARE(item.transform(), x);
       
  7338     QCOMPARE(item.pos(), pos);
       
  7339     QCOMPARE(item.changes.size(), 0);
       
  7340 
       
  7341     item.setOpacity(o);
       
  7342     QCOMPARE(item.changes.size(), 2); // opacity
       
  7343 
       
  7344     item.setFlag(QGraphicsItem::ItemSendsGeometryChanges);
       
  7345     QCOMPARE(item.changes.size(), 4); // flags
       
  7346     item.setTransform(QTransform());
       
  7347     item.setPos(QPointF());
       
  7348     QCOMPARE(item.changes.size(), 8); // transform + pos
       
  7349     QCOMPARE(item.transform(), QTransform());
       
  7350     QCOMPARE(item.pos(), QPointF());
       
  7351     QCOMPARE(item.opacity(), o);
       
  7352 
       
  7353     QCOMPARE(item.changes, QList<QGraphicsItem::GraphicsItemChange>()
       
  7354              << QGraphicsItem::ItemOpacityChange
       
  7355              << QGraphicsItem::ItemOpacityHasChanged
       
  7356              << QGraphicsItem::ItemFlagsChange
       
  7357              << QGraphicsItem::ItemFlagsHaveChanged
       
  7358              << QGraphicsItem::ItemTransformChange
       
  7359              << QGraphicsItem::ItemTransformHasChanged
       
  7360              << QGraphicsItem::ItemPositionChange
       
  7361              << QGraphicsItem::ItemPositionHasChanged);
       
  7362 }
       
  7363 
       
  7364 // Make sure we update moved items correctly.
       
  7365 void tst_QGraphicsItem::moveItem()
       
  7366 {
       
  7367     QGraphicsScene scene;
       
  7368     scene.setSceneRect(-50, -50, 200, 200);
       
  7369 
       
  7370     MyGraphicsView view(&scene);
       
  7371     view.show();
       
  7372 #ifdef Q_WS_X11
       
  7373     qt_x11_wait_for_window_manager(&view);
       
  7374 #endif
       
  7375     QTest::qWait(100);
       
  7376 
       
  7377     EventTester *parent = new EventTester;
       
  7378     EventTester *child = new EventTester(parent);
       
  7379     EventTester *grandChild = new EventTester(child);
       
  7380 
       
  7381 #define RESET_COUNTERS \
       
  7382     parent->repaints = 0; \
       
  7383     child->repaints = 0; \
       
  7384     grandChild->repaints = 0; \
       
  7385     view.reset();
       
  7386 
       
  7387     scene.addItem(parent);
       
  7388     QTest::qWait(100);
       
  7389 
       
  7390     RESET_COUNTERS
       
  7391 
       
  7392     // Item's boundingRect:  (-10, -10, 20, 20).
       
  7393     QRect parentDeviceBoundingRect = parent->deviceTransform(view.viewportTransform())
       
  7394                                      .mapRect(parent->boundingRect()).toRect()
       
  7395                                      .adjusted(-2, -2, 2, 2); // Adjusted for antialiasing.
       
  7396 
       
  7397     parent->setPos(20, 20);
       
  7398     qApp->processEvents();
       
  7399     QCOMPARE(parent->repaints, 1);
       
  7400     QCOMPARE(view.repaints, 1);
       
  7401     QRegion expectedParentRegion = parentDeviceBoundingRect; // old position
       
  7402     parentDeviceBoundingRect.translate(20, 20);
       
  7403     expectedParentRegion += parentDeviceBoundingRect; // new position
       
  7404     COMPARE_REGIONS(view.paintedRegion, expectedParentRegion);
       
  7405 
       
  7406     RESET_COUNTERS
       
  7407 
       
  7408     child->setPos(20, 20);
       
  7409     qApp->processEvents();
       
  7410     QCOMPARE(parent->repaints, 1);
       
  7411     QCOMPARE(child->repaints, 1);
       
  7412     QCOMPARE(view.repaints, 1);
       
  7413     const QRegion expectedChildRegion = expectedParentRegion.translated(20, 20);
       
  7414     COMPARE_REGIONS(view.paintedRegion, expectedChildRegion);
       
  7415 
       
  7416     RESET_COUNTERS
       
  7417 
       
  7418     grandChild->setPos(20, 20);
       
  7419     qApp->processEvents();
       
  7420     QCOMPARE(parent->repaints, 1);
       
  7421     QCOMPARE(child->repaints, 1);
       
  7422     QCOMPARE(grandChild->repaints, 1);
       
  7423     QCOMPARE(view.repaints, 1);
       
  7424     const QRegion expectedGrandChildRegion = expectedParentRegion.translated(40, 40);
       
  7425     COMPARE_REGIONS(view.paintedRegion, expectedGrandChildRegion);
       
  7426 
       
  7427     RESET_COUNTERS
       
  7428 
       
  7429     parent->translate(20, 20);
       
  7430     qApp->processEvents();
       
  7431     QCOMPARE(parent->repaints, 1);
       
  7432     QCOMPARE(child->repaints, 1);
       
  7433     QCOMPARE(grandChild->repaints, 1);
       
  7434     QCOMPARE(view.repaints, 1);
       
  7435     expectedParentRegion.translate(20, 20);
       
  7436     expectedParentRegion += expectedChildRegion.translated(20, 20);
       
  7437     expectedParentRegion += expectedGrandChildRegion.translated(20, 20);
       
  7438     COMPARE_REGIONS(view.paintedRegion, expectedParentRegion);
       
  7439 }
       
  7440 
       
  7441 void tst_QGraphicsItem::sorting_data()
       
  7442 {
       
  7443     QTest::addColumn<int>("index");
       
  7444 
       
  7445     QTest::newRow("NoIndex") << int(QGraphicsScene::NoIndex);
       
  7446     QTest::newRow("BspTreeIndex") << int(QGraphicsScene::BspTreeIndex);
       
  7447 }
       
  7448 
       
  7449 void tst_QGraphicsItem::sorting()
       
  7450 {
       
  7451     _paintedItems.clear();
       
  7452 
       
  7453     QGraphicsScene scene;
       
  7454     QGraphicsItem *grid[100][100];
       
  7455     for (int x = 0; x < 100; ++x) {
       
  7456         for (int y = 0; y < 100; ++y) {
       
  7457             PainterItem *item = new PainterItem;
       
  7458             item->setPos(x * 25, y * 25);
       
  7459             item->setData(0, QString("%1x%2").arg(x).arg(y));
       
  7460             grid[x][y] = item;
       
  7461             scene.addItem(item);
       
  7462         }
       
  7463     }
       
  7464 
       
  7465     PainterItem *item1 = new PainterItem;
       
  7466     PainterItem *item2 = new PainterItem;
       
  7467     item1->setData(0, "item1");
       
  7468     item2->setData(0, "item2");
       
  7469     scene.addItem(item1);
       
  7470     scene.addItem(item2);
       
  7471 
       
  7472     QGraphicsView view(&scene);
       
  7473     view.setResizeAnchor(QGraphicsView::NoAnchor);
       
  7474     view.setTransformationAnchor(QGraphicsView::NoAnchor);
       
  7475     view.resize(120, 100);
       
  7476     view.setFrameStyle(0);
       
  7477     view.show();
       
  7478 #ifdef Q_WS_X11
       
  7479     qt_x11_wait_for_window_manager(&view);
       
  7480 #endif
       
  7481     QTest::qWait(100);
       
  7482 
       
  7483     _paintedItems.clear();
       
  7484 
       
  7485     view.viewport()->repaint();
       
  7486 #ifdef Q_WS_MAC
       
  7487     // There's no difference between repaint and update on the Mac,
       
  7488     // so we have to process events here to make sure we get the event.
       
  7489     QTest::qWait(100);
       
  7490 #endif
       
  7491 
       
  7492     QCOMPARE(_paintedItems, QList<QGraphicsItem *>()
       
  7493                  << grid[0][0] << grid[0][1] << grid[0][2] << grid[0][3]
       
  7494                  << grid[1][0] << grid[1][1] << grid[1][2] << grid[1][3]
       
  7495                  << grid[2][0] << grid[2][1] << grid[2][2] << grid[2][3]
       
  7496                  << grid[3][0] << grid[3][1] << grid[3][2] << grid[3][3]
       
  7497                  << grid[4][0] << grid[4][1] << grid[4][2] << grid[4][3]
       
  7498                  << item1 << item2);
       
  7499 }
       
  7500 
       
  7501 void tst_QGraphicsItem::itemHasNoContents()
       
  7502 {
       
  7503     PainterItem *item1 = new PainterItem;
       
  7504     PainterItem *item2 = new PainterItem;
       
  7505     item2->setParentItem(item1);
       
  7506     item2->setPos(50, 50);
       
  7507     item1->setFlag(QGraphicsItem::ItemHasNoContents);
       
  7508     item1->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  7509 
       
  7510     QGraphicsScene scene;
       
  7511     scene.addItem(item1);
       
  7512 
       
  7513     QGraphicsView view(&scene);
       
  7514     view.show();
       
  7515     QTest::qWaitForWindowShown(&view);
       
  7516     QTRY_VERIFY(!_paintedItems.isEmpty());
       
  7517 
       
  7518     _paintedItems.clear();
       
  7519 
       
  7520     view.viewport()->repaint();
       
  7521 #ifdef Q_WS_MAC
       
  7522     // There's no difference between update() and repaint() on the Mac,
       
  7523     // so we have to process events here to make sure we get the event.
       
  7524     QTest::qWait(10);
       
  7525 #endif
       
  7526 
       
  7527     QTRY_COMPARE(_paintedItems, QList<QGraphicsItem *>() << item2);
       
  7528 }
       
  7529 
       
  7530 void tst_QGraphicsItem::hitTestUntransformableItem()
       
  7531 {
       
  7532     QGraphicsScene scene;
       
  7533     scene.setSceneRect(-100, -100, 200, 200);
       
  7534 
       
  7535     QGraphicsView view(&scene);
       
  7536     view.show();
       
  7537 #ifdef Q_WS_X11
       
  7538     qt_x11_wait_for_window_manager(&view);
       
  7539 #endif
       
  7540     QTest::qWait(100);
       
  7541 
       
  7542     // Confuse the BSP with dummy items.
       
  7543     QGraphicsRectItem *dummy = new QGraphicsRectItem(0, 0, 20, 20);
       
  7544     dummy->setPos(-100, -100);
       
  7545     scene.addItem(dummy);
       
  7546     for (int i = 0; i < 100; ++i) {
       
  7547         QGraphicsItem *parent = dummy;
       
  7548         dummy = new QGraphicsRectItem(0, 0, 20, 20);
       
  7549         dummy->setPos(-100 + i, -100 + i);
       
  7550         dummy->setParentItem(parent);
       
  7551     }
       
  7552 
       
  7553     QGraphicsRectItem *item1 = new QGraphicsRectItem(0, 0, 20, 20);
       
  7554     item1->setPos(-200, -200);
       
  7555 
       
  7556     QGraphicsRectItem *item2 = new QGraphicsRectItem(0, 0, 20, 20);
       
  7557     item2->setFlag(QGraphicsItem::ItemIgnoresTransformations);
       
  7558     item2->setParentItem(item1);
       
  7559     item2->setPos(200, 200);
       
  7560 
       
  7561     QGraphicsRectItem *item3 = new QGraphicsRectItem(0, 0, 20, 20);
       
  7562     item3->setParentItem(item2);
       
  7563     item3->setPos(80, 80);
       
  7564 
       
  7565     scene.addItem(item1);
       
  7566     QTest::qWait(100);
       
  7567 
       
  7568     QList<QGraphicsItem *> items = scene.items(QPointF(80, 80));
       
  7569     QCOMPARE(items.size(), 1);
       
  7570     QCOMPARE(items.at(0), static_cast<QGraphicsItem*>(item3));
       
  7571 
       
  7572     scene.setItemIndexMethod(QGraphicsScene::NoIndex);
       
  7573     QTest::qWait(100);
       
  7574 
       
  7575     items = scene.items(QPointF(80, 80));
       
  7576     QCOMPARE(items.size(), 1);
       
  7577     QCOMPARE(items.at(0), static_cast<QGraphicsItem*>(item3));
       
  7578 }
       
  7579 
       
  7580 void tst_QGraphicsItem::hitTestGraphicsEffectItem()
       
  7581 {
       
  7582     QGraphicsScene scene;
       
  7583     scene.setSceneRect(-100, -100, 200, 200);
       
  7584 
       
  7585     QGraphicsView view(&scene);
       
  7586     view.show();
       
  7587 #ifdef Q_WS_X11
       
  7588     qt_x11_wait_for_window_manager(&view);
       
  7589 #endif
       
  7590     QTest::qWait(100);
       
  7591 
       
  7592     // Confuse the BSP with dummy items.
       
  7593     QGraphicsRectItem *dummy = new QGraphicsRectItem(0, 0, 20, 20);
       
  7594     dummy->setPos(-100, -100);
       
  7595     scene.addItem(dummy);
       
  7596     for (int i = 0; i < 100; ++i) {
       
  7597         QGraphicsItem *parent = dummy;
       
  7598         dummy = new QGraphicsRectItem(0, 0, 20, 20);
       
  7599         dummy->setPos(-100 + i, -100 + i);
       
  7600         dummy->setParentItem(parent);
       
  7601     }
       
  7602 
       
  7603     const QRectF itemBoundingRect(0, 0, 20, 20);
       
  7604     EventTester *item1 = new EventTester;
       
  7605     item1->br = itemBoundingRect;
       
  7606     item1->setPos(-200, -200);
       
  7607 
       
  7608     EventTester *item2 = new EventTester;
       
  7609     item2->br = itemBoundingRect;
       
  7610     item2->setFlag(QGraphicsItem::ItemIgnoresTransformations);
       
  7611     item2->setParentItem(item1);
       
  7612     item2->setPos(200, 200);
       
  7613 
       
  7614     EventTester *item3 = new EventTester;
       
  7615     item3->br = itemBoundingRect;
       
  7616     item3->setParentItem(item2);
       
  7617     item3->setPos(80, 80);
       
  7618 
       
  7619     scene.addItem(item1);
       
  7620     QTest::qWait(100);
       
  7621 
       
  7622     item1->repaints = 0;
       
  7623     item2->repaints = 0;
       
  7624     item3->repaints = 0;
       
  7625 
       
  7626     // Apply shadow effect to the entire sub-tree.
       
  7627     QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect;
       
  7628     shadow->setOffset(-20, -20);
       
  7629     item1->setGraphicsEffect(shadow);
       
  7630     QTest::qWait(50);
       
  7631 
       
  7632     // Make sure all items are repainted.
       
  7633     QCOMPARE(item1->repaints, 1);
       
  7634     QCOMPARE(item2->repaints, 1);
       
  7635     QCOMPARE(item3->repaints, 1);
       
  7636 
       
  7637     // Make sure an item doesn't respond to a click on its shadow.
       
  7638     QList<QGraphicsItem *> items = scene.items(QPointF(75, 75));
       
  7639     QVERIFY(items.isEmpty());
       
  7640     items = scene.items(QPointF(80, 80));
       
  7641     QCOMPARE(items.size(), 1);
       
  7642     QCOMPARE(items.at(0), static_cast<QGraphicsItem *>(item3));
       
  7643 
       
  7644     item1->repaints = 0;
       
  7645     item2->repaints = 0;
       
  7646     item3->repaints = 0;
       
  7647 
       
  7648     view.viewport()->update(75, 75, 20, 20);
       
  7649     QTest::qWait(50);
       
  7650 
       
  7651     // item1 is the effect source and must therefore be repainted.
       
  7652     // item2 intersects with the exposed region
       
  7653     // item3 is just another child outside the exposed region
       
  7654     QCOMPARE(item1->repaints, 1);
       
  7655     QCOMPARE(item2->repaints, 1);
       
  7656     QCOMPARE(item3->repaints, 0);
       
  7657 
       
  7658     scene.setItemIndexMethod(QGraphicsScene::NoIndex);
       
  7659     QTest::qWait(100);
       
  7660 
       
  7661     items = scene.items(QPointF(75, 75));
       
  7662     QVERIFY(items.isEmpty());
       
  7663     items = scene.items(QPointF(80, 80));
       
  7664     QCOMPARE(items.size(), 1);
       
  7665     QCOMPARE(items.at(0), static_cast<QGraphicsItem *>(item3));
       
  7666 }
       
  7667 
       
  7668 void tst_QGraphicsItem::focusProxy()
       
  7669 {
       
  7670     QGraphicsScene scene;
       
  7671     QEvent activate(QEvent::WindowActivate);
       
  7672     QApplication::sendEvent(&scene, &activate);
       
  7673 
       
  7674     QGraphicsItem *item = scene.addRect(0, 0, 10, 10);
       
  7675     item->setFlag(QGraphicsItem::ItemIsFocusable);
       
  7676     QVERIFY(!item->focusProxy());
       
  7677 
       
  7678     QGraphicsItem *item2 = scene.addRect(0, 0, 10, 10);
       
  7679     item2->setFlag(QGraphicsItem::ItemIsFocusable);
       
  7680     item->setFocusProxy(item2);
       
  7681     QCOMPARE(item->focusProxy(), item2);
       
  7682 
       
  7683     item->setFocus();
       
  7684     QVERIFY(item->hasFocus());
       
  7685     QVERIFY(item2->hasFocus());
       
  7686 
       
  7687     // Try to make a focus chain loop
       
  7688     QString err;
       
  7689     QTextStream stream(&err);
       
  7690     stream << "QGraphicsItem::setFocusProxy: "
       
  7691            << (void*)item << " is already in the focus proxy chain" << flush;
       
  7692     QTest::ignoreMessage(QtWarningMsg, err.toLatin1().constData());
       
  7693     item2->setFocusProxy(item); // fails
       
  7694     QCOMPARE(item->focusProxy(), (QGraphicsItem *)item2);
       
  7695     QCOMPARE(item2->focusProxy(), (QGraphicsItem *)0);
       
  7696 
       
  7697     // Try to assign self as focus proxy
       
  7698     QTest::ignoreMessage(QtWarningMsg, "QGraphicsItem::setFocusProxy: cannot assign self as focus proxy");
       
  7699     item->setFocusProxy(item); // fails
       
  7700     QCOMPARE(item->focusProxy(), (QGraphicsItem *)item2);
       
  7701     QCOMPARE(item2->focusProxy(), (QGraphicsItem *)0);
       
  7702 
       
  7703     // Reset the focus proxy
       
  7704     item->setFocusProxy(0);
       
  7705     QCOMPARE(item->focusProxy(), (QGraphicsItem *)0);
       
  7706     QVERIFY(!item->hasFocus());
       
  7707     QVERIFY(item2->hasFocus());
       
  7708 
       
  7709     // Test deletion
       
  7710     item->setFocusProxy(item2);
       
  7711     QCOMPARE(item->focusProxy(), (QGraphicsItem *)item2);
       
  7712     delete item2;
       
  7713     QCOMPARE(item->focusProxy(), (QGraphicsItem *)0);
       
  7714 
       
  7715     // Test event delivery
       
  7716     item2 = scene.addRect(0, 0, 10, 10);
       
  7717     item2->setFlag(QGraphicsItem::ItemIsFocusable);
       
  7718     item->setFocusProxy(item2);
       
  7719     item->clearFocus();
       
  7720 
       
  7721     EventSpy focusInSpy(&scene, item, QEvent::FocusIn);
       
  7722     EventSpy focusOutSpy(&scene, item, QEvent::FocusOut);
       
  7723     EventSpy focusInSpy2(&scene, item2, QEvent::FocusIn);
       
  7724     EventSpy focusOutSpy2(&scene, item2, QEvent::FocusOut);
       
  7725     QCOMPARE(focusInSpy.count(), 0);
       
  7726     QCOMPARE(focusOutSpy.count(), 0);
       
  7727     QCOMPARE(focusInSpy2.count(), 0);
       
  7728     QCOMPARE(focusOutSpy2.count(), 0);
       
  7729 
       
  7730     item->setFocus();
       
  7731     QCOMPARE(focusInSpy.count(), 0);
       
  7732     QCOMPARE(focusInSpy2.count(), 1);
       
  7733     item->clearFocus();
       
  7734     QCOMPARE(focusOutSpy.count(), 0);
       
  7735     QCOMPARE(focusOutSpy2.count(), 1);
       
  7736 
       
  7737     // Test two items proxying one item.
       
  7738     QGraphicsItem *item3 = scene.addRect(0, 0, 10, 10);
       
  7739     item3->setFlag(QGraphicsItem::ItemIsFocusable);
       
  7740     item3->setFocusProxy(item2); // item and item3 use item2 as proxy
       
  7741 
       
  7742     QCOMPARE(item->focusProxy(), item2);
       
  7743     QCOMPARE(item2->focusProxy(), (QGraphicsItem *)0);
       
  7744     QCOMPARE(item3->focusProxy(), item2);
       
  7745     delete item2;
       
  7746     QCOMPARE(item->focusProxy(), (QGraphicsItem *)0);
       
  7747     QCOMPARE(item3->focusProxy(), (QGraphicsItem *)0);
       
  7748 }
       
  7749 
       
  7750 void tst_QGraphicsItem::subFocus()
       
  7751 {
       
  7752     // Construct a text item that's not part of a scene (yet)
       
  7753     // and has no parent. Setting focus on it will not make
       
  7754     // the item gain input focus; that requires a scene. But
       
  7755     // it does set subfocus, indicating that the item wishes
       
  7756     // to gain focus later.
       
  7757     QGraphicsTextItem *text = new QGraphicsTextItem("Hello");
       
  7758     text->setTextInteractionFlags(Qt::TextEditorInteraction);
       
  7759     QVERIFY(!text->hasFocus());
       
  7760     text->setFocus();
       
  7761     QVERIFY(!text->hasFocus());
       
  7762     QCOMPARE(text->focusItem(), (QGraphicsItem *)text);
       
  7763 
       
  7764     // Add a sibling.
       
  7765     QGraphicsTextItem *text2 = new QGraphicsTextItem("Hi");
       
  7766     text2->setTextInteractionFlags(Qt::TextEditorInteraction);
       
  7767     text2->setPos(30, 30);
       
  7768 
       
  7769     // Add both items to a scene and check that it's text that
       
  7770     // got input focus.
       
  7771     QGraphicsScene scene;
       
  7772     QEvent activate(QEvent::WindowActivate);
       
  7773     QApplication::sendEvent(&scene, &activate);
       
  7774 
       
  7775     scene.addItem(text);
       
  7776     scene.addItem(text2);
       
  7777     QVERIFY(text->hasFocus());
       
  7778 
       
  7779     text->setData(0, "text");
       
  7780     text2->setData(0, "text2");
       
  7781 
       
  7782     // Remove text2 and set subfocus on it. Then readd. Reparent it onto the
       
  7783     // other item and see that it gains input focus.
       
  7784     scene.removeItem(text2);
       
  7785     text2->setFocus();
       
  7786     scene.addItem(text2);
       
  7787     QCOMPARE(text2->focusItem(), (QGraphicsItem *)text2);
       
  7788     text2->setParentItem(text);
       
  7789     QCOMPARE(text->focusItem(), (QGraphicsItem *)text2);
       
  7790     QCOMPARE(text2->focusItem(), (QGraphicsItem *)text2);
       
  7791     QVERIFY(!text->hasFocus());
       
  7792     QVERIFY(text2->hasFocus());
       
  7793 
       
  7794     // Remove both items from the scene, restore subfocus and
       
  7795     // readd them. Now the subfocus should kick in and give
       
  7796     // text2 focus.
       
  7797     scene.removeItem(text);
       
  7798     QCOMPARE(text->focusItem(), (QGraphicsItem *)0);
       
  7799     QCOMPARE(text2->focusItem(), (QGraphicsItem *)0);
       
  7800     text2->setFocus();
       
  7801     QCOMPARE(text->focusItem(), (QGraphicsItem *)text2);
       
  7802     QCOMPARE(text2->focusItem(), (QGraphicsItem *)text2);
       
  7803     scene.addItem(text);
       
  7804 
       
  7805     // Hiding and showing text should pass focus to text2.
       
  7806     QCOMPARE(text->focusItem(), (QGraphicsItem *)text2);
       
  7807     QVERIFY(text2->hasFocus());
       
  7808 
       
  7809     // Subfocus should repropagate to root when reparenting.
       
  7810     QGraphicsRectItem *rect = new QGraphicsRectItem;
       
  7811     QGraphicsRectItem *rect2 = new QGraphicsRectItem(rect);
       
  7812     QGraphicsRectItem *rect3 = new QGraphicsRectItem(rect2);
       
  7813     rect3->setFlag(QGraphicsItem::ItemIsFocusable);
       
  7814 
       
  7815     text->setData(0, "text");
       
  7816     text2->setData(0, "text2");
       
  7817     rect->setData(0, "rect");
       
  7818     rect2->setData(0, "rect2");
       
  7819     rect3->setData(0, "rect3");
       
  7820 
       
  7821     rect3->setFocus();
       
  7822     QVERIFY(!rect3->hasFocus());
       
  7823     QCOMPARE(rect->focusItem(), (QGraphicsItem *)rect3);
       
  7824     QCOMPARE(rect2->focusItem(), (QGraphicsItem *)rect3);
       
  7825     QCOMPARE(rect3->focusItem(), (QGraphicsItem *)rect3);
       
  7826     rect->setParentItem(text2);
       
  7827     QCOMPARE(text->focusItem(), (QGraphicsItem *)rect3);
       
  7828     QCOMPARE(text2->focusItem(), (QGraphicsItem *)rect3);
       
  7829     QCOMPARE(rect->focusItem(), (QGraphicsItem *)rect3);
       
  7830     QCOMPARE(rect2->focusItem(), (QGraphicsItem *)rect3);
       
  7831     QCOMPARE(rect3->focusItem(), (QGraphicsItem *)rect3);
       
  7832     QVERIFY(!rect->hasFocus());
       
  7833     QVERIFY(!rect2->hasFocus());
       
  7834     QVERIFY(rect3->hasFocus());
       
  7835 
       
  7836     delete rect2;
       
  7837     QCOMPARE(text->focusItem(), (QGraphicsItem *)0);
       
  7838     QCOMPARE(text2->focusItem(), (QGraphicsItem *)0);
       
  7839     QCOMPARE(rect->focusItem(), (QGraphicsItem *)0);
       
  7840 }
       
  7841 
       
  7842 void tst_QGraphicsItem::focusProxyDeletion()
       
  7843 {
       
  7844     QGraphicsRectItem *rect = new QGraphicsRectItem;
       
  7845     QGraphicsRectItem *rect2 = new QGraphicsRectItem;
       
  7846     rect->setFocusProxy(rect2);
       
  7847     QCOMPARE(rect->focusProxy(), (QGraphicsItem *)rect2);
       
  7848 
       
  7849     delete rect2;
       
  7850     QCOMPARE(rect->focusProxy(), (QGraphicsItem *)0);
       
  7851 
       
  7852     rect2 = new QGraphicsRectItem;
       
  7853     rect->setFocusProxy(rect2);
       
  7854     delete rect; // don't crash
       
  7855 
       
  7856     rect = new QGraphicsRectItem;
       
  7857     rect->setFocusProxy(rect2);
       
  7858     QGraphicsScene *scene = new QGraphicsScene;
       
  7859     scene->addItem(rect);
       
  7860     scene->addItem(rect2);
       
  7861     delete rect2;
       
  7862     QCOMPARE(rect->focusProxy(), (QGraphicsItem *)0);
       
  7863 
       
  7864     rect2 = new QGraphicsRectItem;
       
  7865     QTest::ignoreMessage(QtWarningMsg, "QGraphicsItem::setFocusProxy: focus proxy must be in same scene");
       
  7866     rect->setFocusProxy(rect2);
       
  7867     QCOMPARE(rect->focusProxy(), (QGraphicsItem *)0);
       
  7868     scene->addItem(rect2);
       
  7869     rect->setFocusProxy(rect2);
       
  7870     QCOMPARE(rect->focusProxy(), (QGraphicsItem *)rect2);
       
  7871     delete rect; // don't crash
       
  7872 
       
  7873     rect = new QGraphicsRectItem;
       
  7874     rect2 = new QGraphicsRectItem;
       
  7875     rect->setFocusProxy(rect2);
       
  7876     QCOMPARE(rect->focusProxy(), (QGraphicsItem *)rect2);
       
  7877     scene->addItem(rect);
       
  7878     scene->addItem(rect2);
       
  7879     rect->setFocusProxy(rect2);
       
  7880     delete scene; // don't crash
       
  7881 }
       
  7882 
       
  7883 void tst_QGraphicsItem::negativeZStacksBehindParent()
       
  7884 {
       
  7885     QGraphicsRectItem rect;
       
  7886     QCOMPARE(rect.zValue(), qreal(0.0));
       
  7887     QVERIFY(!(rect.flags() & QGraphicsItem::ItemNegativeZStacksBehindParent));
       
  7888     QVERIFY(!(rect.flags() & QGraphicsItem::ItemStacksBehindParent));
       
  7889     rect.setZValue(-1);
       
  7890     QCOMPARE(rect.zValue(), qreal(-1.0));
       
  7891     QVERIFY(!(rect.flags() & QGraphicsItem::ItemStacksBehindParent));
       
  7892     rect.setZValue(0);
       
  7893     rect.setFlag(QGraphicsItem::ItemNegativeZStacksBehindParent);
       
  7894     QVERIFY(rect.flags() & QGraphicsItem::ItemNegativeZStacksBehindParent);
       
  7895     QVERIFY(!(rect.flags() & QGraphicsItem::ItemStacksBehindParent));
       
  7896     rect.setZValue(-1);
       
  7897     QVERIFY(rect.flags() & QGraphicsItem::ItemStacksBehindParent);
       
  7898     rect.setZValue(0);
       
  7899     QVERIFY(!(rect.flags() & QGraphicsItem::ItemStacksBehindParent));
       
  7900     rect.setFlag(QGraphicsItem::ItemNegativeZStacksBehindParent, false);
       
  7901     rect.setZValue(-1);
       
  7902     rect.setFlag(QGraphicsItem::ItemNegativeZStacksBehindParent, true);
       
  7903     QVERIFY(rect.flags() & QGraphicsItem::ItemStacksBehindParent);
       
  7904     rect.setFlag(QGraphicsItem::ItemNegativeZStacksBehindParent, false);
       
  7905     QVERIFY(rect.flags() & QGraphicsItem::ItemStacksBehindParent);
       
  7906 }
       
  7907 
       
  7908 void tst_QGraphicsItem::setGraphicsEffect()
       
  7909 {
       
  7910     // Check that we don't have any effect by default.
       
  7911     QGraphicsItem *item = new QGraphicsRectItem(0, 0, 10, 10);
       
  7912     QVERIFY(!item->graphicsEffect());
       
  7913 
       
  7914     // SetGet check.
       
  7915     QPointer<QGraphicsEffect> blurEffect = new QGraphicsBlurEffect;
       
  7916     item->setGraphicsEffect(blurEffect);
       
  7917     QCOMPARE(item->graphicsEffect(), static_cast<QGraphicsEffect *>(blurEffect));
       
  7918 
       
  7919     // Ensure the existing effect is deleted when setting a new one.
       
  7920     QPointer<QGraphicsEffect> shadowEffect = new QGraphicsDropShadowEffect;
       
  7921     item->setGraphicsEffect(shadowEffect);
       
  7922     QVERIFY(!blurEffect);
       
  7923     QCOMPARE(item->graphicsEffect(), static_cast<QGraphicsEffect *>(shadowEffect));
       
  7924     blurEffect = new QGraphicsBlurEffect;
       
  7925 
       
  7926     // Ensure the effect is uninstalled when setting it on a new target.
       
  7927     QGraphicsItem *anotherItem = new QGraphicsRectItem(0, 0, 10, 10);
       
  7928     anotherItem->setGraphicsEffect(blurEffect);
       
  7929     item->setGraphicsEffect(blurEffect);
       
  7930     QVERIFY(!anotherItem->graphicsEffect());
       
  7931     QVERIFY(!shadowEffect);
       
  7932 
       
  7933     // Ensure the existing effect is deleted when deleting the item.
       
  7934     delete item;
       
  7935     QVERIFY(!blurEffect);
       
  7936     delete anotherItem;
       
  7937 }
       
  7938 
       
  7939 void tst_QGraphicsItem::panel()
       
  7940 {
       
  7941     QGraphicsScene scene;
       
  7942 
       
  7943     QGraphicsRectItem *panel1 = new QGraphicsRectItem;
       
  7944     QGraphicsRectItem *panel2 = new QGraphicsRectItem;
       
  7945     QGraphicsRectItem *panel3 = new QGraphicsRectItem;
       
  7946     QGraphicsRectItem *panel4 = new QGraphicsRectItem;
       
  7947     QGraphicsRectItem *notPanel1 = new QGraphicsRectItem;
       
  7948     QGraphicsRectItem *notPanel2 = new QGraphicsRectItem;
       
  7949     panel1->setFlag(QGraphicsItem::ItemIsPanel);
       
  7950     panel2->setFlag(QGraphicsItem::ItemIsPanel);
       
  7951     panel3->setFlag(QGraphicsItem::ItemIsPanel);
       
  7952     panel4->setFlag(QGraphicsItem::ItemIsPanel);
       
  7953     scene.addItem(panel1);
       
  7954     scene.addItem(panel2);
       
  7955     scene.addItem(panel3);
       
  7956     scene.addItem(panel4);
       
  7957     scene.addItem(notPanel1);
       
  7958     scene.addItem(notPanel2);
       
  7959 
       
  7960     EventSpy spy_activate_panel1(&scene, panel1, QEvent::WindowActivate);
       
  7961     EventSpy spy_deactivate_panel1(&scene, panel1, QEvent::WindowDeactivate);
       
  7962     EventSpy spy_activate_panel2(&scene, panel2, QEvent::WindowActivate);
       
  7963     EventSpy spy_deactivate_panel2(&scene, panel2, QEvent::WindowDeactivate);
       
  7964     EventSpy spy_activate_panel3(&scene, panel3, QEvent::WindowActivate);
       
  7965     EventSpy spy_deactivate_panel3(&scene, panel3, QEvent::WindowDeactivate);
       
  7966     EventSpy spy_activate_panel4(&scene, panel4, QEvent::WindowActivate);
       
  7967     EventSpy spy_deactivate_panel4(&scene, panel4, QEvent::WindowDeactivate);
       
  7968     EventSpy spy_activate_notPanel1(&scene, notPanel1, QEvent::WindowActivate);
       
  7969     EventSpy spy_deactivate_notPanel1(&scene, notPanel1, QEvent::WindowDeactivate);
       
  7970     EventSpy spy_activate_notPanel2(&scene, notPanel1, QEvent::WindowActivate);
       
  7971     EventSpy spy_deactivate_notPanel2(&scene, notPanel1, QEvent::WindowDeactivate);
       
  7972 
       
  7973     QCOMPARE(spy_activate_panel1.count(), 0);
       
  7974     QCOMPARE(spy_deactivate_panel1.count(), 0);
       
  7975     QCOMPARE(spy_activate_panel2.count(), 0);
       
  7976     QCOMPARE(spy_deactivate_panel2.count(), 0);
       
  7977     QCOMPARE(spy_activate_panel3.count(), 0);
       
  7978     QCOMPARE(spy_deactivate_panel3.count(), 0);
       
  7979     QCOMPARE(spy_activate_panel4.count(), 0);
       
  7980     QCOMPARE(spy_deactivate_panel4.count(), 0);
       
  7981     QCOMPARE(spy_activate_notPanel1.count(), 0);
       
  7982     QCOMPARE(spy_deactivate_notPanel1.count(), 0);
       
  7983     QCOMPARE(spy_activate_notPanel2.count(), 0);
       
  7984     QCOMPARE(spy_deactivate_notPanel2.count(), 0);
       
  7985 
       
  7986     QVERIFY(!scene.activePanel());
       
  7987     QVERIFY(!scene.isActive());
       
  7988 
       
  7989     QEvent activate(QEvent::WindowActivate);
       
  7990     QEvent deactivate(QEvent::WindowDeactivate);
       
  7991 
       
  7992     QApplication::sendEvent(&scene, &activate);
       
  7993 
       
  7994     // No previous activation, so the scene is active.
       
  7995     QVERIFY(scene.isActive());
       
  7996     QCOMPARE(scene.activePanel(), (QGraphicsItem *)panel1);
       
  7997     QVERIFY(panel1->isActive());
       
  7998     QVERIFY(!panel2->isActive());
       
  7999     QVERIFY(!panel3->isActive());
       
  8000     QVERIFY(!panel4->isActive());
       
  8001     QVERIFY(!notPanel1->isActive());
       
  8002     QVERIFY(!notPanel2->isActive());
       
  8003     QCOMPARE(spy_deactivate_notPanel1.count(), 0);
       
  8004     QCOMPARE(spy_deactivate_notPanel2.count(), 0);
       
  8005     QCOMPARE(spy_activate_panel1.count(), 1);
       
  8006     QCOMPARE(spy_activate_panel2.count(), 0);
       
  8007     QCOMPARE(spy_activate_panel3.count(), 0);
       
  8008     QCOMPARE(spy_activate_panel4.count(), 0);
       
  8009 
       
  8010     // Switch back to scene.
       
  8011     scene.setActivePanel(0);
       
  8012     QVERIFY(!scene.activePanel());
       
  8013     QVERIFY(!panel1->isActive());
       
  8014     QVERIFY(!panel2->isActive());
       
  8015     QVERIFY(!panel3->isActive());
       
  8016     QVERIFY(!panel4->isActive());
       
  8017     QVERIFY(notPanel1->isActive());
       
  8018     QVERIFY(notPanel2->isActive());
       
  8019     QCOMPARE(spy_activate_notPanel1.count(), 1);
       
  8020     QCOMPARE(spy_activate_notPanel2.count(), 1);
       
  8021 
       
  8022     // Deactivate the scene
       
  8023     QApplication::sendEvent(&scene, &deactivate);
       
  8024     QVERIFY(!scene.activePanel());
       
  8025     QVERIFY(!panel1->isActive());
       
  8026     QVERIFY(!panel2->isActive());
       
  8027     QVERIFY(!panel3->isActive());
       
  8028     QVERIFY(!panel4->isActive());
       
  8029     QVERIFY(!notPanel1->isActive());
       
  8030     QVERIFY(!notPanel2->isActive());
       
  8031     QCOMPARE(spy_deactivate_notPanel1.count(), 1);
       
  8032     QCOMPARE(spy_deactivate_notPanel2.count(), 1);
       
  8033 
       
  8034     // Reactivate the scene
       
  8035     QApplication::sendEvent(&scene, &activate);
       
  8036     QVERIFY(!scene.activePanel());
       
  8037     QVERIFY(!panel1->isActive());
       
  8038     QVERIFY(!panel2->isActive());
       
  8039     QVERIFY(!panel3->isActive());
       
  8040     QVERIFY(!panel4->isActive());
       
  8041     QVERIFY(notPanel1->isActive());
       
  8042     QVERIFY(notPanel2->isActive());
       
  8043     QCOMPARE(spy_activate_notPanel1.count(), 2);
       
  8044     QCOMPARE(spy_activate_notPanel2.count(), 2);
       
  8045 
       
  8046     // Switch to panel1
       
  8047     scene.setActivePanel(panel1);
       
  8048     QVERIFY(panel1->isActive());
       
  8049     QCOMPARE(spy_deactivate_notPanel1.count(), 2);
       
  8050     QCOMPARE(spy_deactivate_notPanel2.count(), 2);
       
  8051     QCOMPARE(spy_activate_panel1.count(), 2);
       
  8052 
       
  8053     // Deactivate the scene
       
  8054     QApplication::sendEvent(&scene, &deactivate);
       
  8055     QVERIFY(!panel1->isActive());
       
  8056     QCOMPARE(spy_deactivate_panel1.count(), 2);
       
  8057 
       
  8058     // Reactivate the scene
       
  8059     QApplication::sendEvent(&scene, &activate);
       
  8060     QVERIFY(panel1->isActive());
       
  8061     QCOMPARE(spy_activate_panel1.count(), 3);
       
  8062 
       
  8063     // Deactivate the scene
       
  8064     QApplication::sendEvent(&scene, &deactivate);
       
  8065     QVERIFY(!panel1->isActive());
       
  8066     QVERIFY(!scene.activePanel());
       
  8067     scene.setActivePanel(0);
       
  8068 
       
  8069     // Reactivate the scene
       
  8070     QApplication::sendEvent(&scene, &activate);
       
  8071     QVERIFY(!panel1->isActive());
       
  8072 }
       
  8073 
       
  8074 void tst_QGraphicsItem::addPanelToActiveScene()
       
  8075 {
       
  8076     QGraphicsScene scene;
       
  8077     QVERIFY(!scene.isActive());
       
  8078 
       
  8079     QGraphicsRectItem *rect = new QGraphicsRectItem;
       
  8080     scene.addItem(rect);
       
  8081     QVERIFY(!rect->isActive());
       
  8082     scene.removeItem(rect);
       
  8083 
       
  8084     QEvent activate(QEvent::WindowActivate);
       
  8085     QEvent deactivate(QEvent::WindowDeactivate);
       
  8086 
       
  8087     QApplication::sendEvent(&scene, &activate);
       
  8088     QVERIFY(scene.isActive());
       
  8089     scene.addItem(rect);
       
  8090     QVERIFY(rect->isActive());
       
  8091     scene.removeItem(rect);
       
  8092 
       
  8093     rect->setFlag(QGraphicsItem::ItemIsPanel);
       
  8094     scene.addItem(rect);
       
  8095     QVERIFY(rect->isActive());
       
  8096     QCOMPARE(scene.activePanel(), (QGraphicsItem *)rect);
       
  8097 
       
  8098     QGraphicsRectItem *rect2 = new QGraphicsRectItem;
       
  8099     scene.addItem(rect2);
       
  8100     QVERIFY(rect->isActive());
       
  8101     QCOMPARE(scene.activePanel(), (QGraphicsItem *)rect);
       
  8102 }
       
  8103 
       
  8104 void tst_QGraphicsItem::activate()
       
  8105 {
       
  8106     QGraphicsScene scene;
       
  8107     QGraphicsRectItem *rect = scene.addRect(-10, -10, 20, 20);
       
  8108     QVERIFY(!rect->isActive());
       
  8109 
       
  8110     QEvent activate(QEvent::WindowActivate);
       
  8111     QEvent deactivate(QEvent::WindowDeactivate);
       
  8112 
       
  8113     QApplication::sendEvent(&scene, &activate);
       
  8114 
       
  8115     // Non-panel item (active when scene is active).
       
  8116     QVERIFY(rect->isActive());
       
  8117 
       
  8118     QGraphicsRectItem *rect2 = new QGraphicsRectItem;
       
  8119     rect2->setFlag(QGraphicsItem::ItemIsPanel);
       
  8120     QGraphicsRectItem *rect3 = new QGraphicsRectItem;
       
  8121     rect3->setFlag(QGraphicsItem::ItemIsPanel);
       
  8122 
       
  8123     // Test normal activation.
       
  8124     QVERIFY(!rect2->isActive());
       
  8125     scene.addItem(rect2);
       
  8126     QVERIFY(rect2->isActive()); // first panel item is activated
       
  8127     scene.addItem(rect3);
       
  8128     QVERIFY(!rect3->isActive()); // second panel item is _not_ activated
       
  8129     rect3->setActive(true);
       
  8130     QVERIFY(rect3->isActive());
       
  8131     scene.removeItem(rect3);
       
  8132     QVERIFY(!rect3->isActive()); // no panel is active anymore
       
  8133     QCOMPARE(scene.activePanel(), (QGraphicsItem *)0);
       
  8134     scene.addItem(rect3);
       
  8135     QVERIFY(rect3->isActive()); // second panel item is activated
       
  8136 
       
  8137     // Test pending activation.
       
  8138     scene.removeItem(rect3);
       
  8139     rect2->setActive(true);
       
  8140     QVERIFY(rect2->isActive()); // first panel item is activated
       
  8141     rect3->setActive(true);
       
  8142     QVERIFY(!rect3->isActive()); // not active (yet)
       
  8143     scene.addItem(rect3);
       
  8144     QVERIFY(rect3->isActive()); // now becomes active
       
  8145 
       
  8146     // Test pending deactivation.
       
  8147     scene.removeItem(rect3);
       
  8148     rect3->setActive(false);
       
  8149     scene.addItem(rect3);
       
  8150     QVERIFY(!rect3->isActive()); // doesn't become active
       
  8151 
       
  8152     // Child of panel activation.
       
  8153     rect3->setActive(true);
       
  8154     QGraphicsRectItem *rect4 = new QGraphicsRectItem;
       
  8155     rect4->setFlag(QGraphicsItem::ItemIsPanel);
       
  8156     QGraphicsRectItem *rect5 = new QGraphicsRectItem(rect4);
       
  8157     QGraphicsRectItem *rect6 = new QGraphicsRectItem(rect5);
       
  8158     scene.addItem(rect4);
       
  8159     QCOMPARE(scene.activePanel(), (QGraphicsItem *)rect3);
       
  8160     scene.removeItem(rect4);
       
  8161     rect6->setActive(true);
       
  8162     scene.addItem(rect4);
       
  8163     QVERIFY(rect4->isActive());
       
  8164     QVERIFY(rect5->isActive());
       
  8165     QVERIFY(rect6->isActive());
       
  8166     QCOMPARE(scene.activePanel(), (QGraphicsItem *)rect4);
       
  8167     scene.removeItem(rect4); // no active panel
       
  8168     rect6->setActive(false);
       
  8169     scene.addItem(rect4);
       
  8170     QVERIFY(!rect4->isActive());
       
  8171     QVERIFY(!rect5->isActive());
       
  8172     QVERIFY(!rect6->isActive());
       
  8173     QCOMPARE(scene.activePanel(), (QGraphicsItem *)0);
       
  8174 
       
  8175     // Controlling auto-activation when the scene changes activation.
       
  8176     rect4->setActive(true);
       
  8177     QApplication::sendEvent(&scene, &deactivate);
       
  8178     QVERIFY(!scene.isActive());
       
  8179     QVERIFY(!rect4->isActive());
       
  8180     rect4->setActive(false);
       
  8181     QApplication::sendEvent(&scene, &activate);
       
  8182     QVERIFY(scene.isActive());
       
  8183     QVERIFY(!scene.activePanel());
       
  8184     QVERIFY(!rect4->isActive());
       
  8185 }
       
  8186 
       
  8187 void tst_QGraphicsItem::setActivePanelOnInactiveScene()
       
  8188 {
       
  8189     QGraphicsScene scene;
       
  8190     QGraphicsRectItem *item = scene.addRect(QRectF());
       
  8191     QGraphicsRectItem *panel = scene.addRect(QRectF());
       
  8192     panel->setFlag(QGraphicsItem::ItemIsPanel);
       
  8193 
       
  8194     EventSpy itemActivateSpy(&scene, item, QEvent::WindowActivate);
       
  8195     EventSpy itemDeactivateSpy(&scene, item, QEvent::WindowDeactivate);
       
  8196     EventSpy panelActivateSpy(&scene, panel, QEvent::WindowActivate);
       
  8197     EventSpy panelDeactivateSpy(&scene, panel, QEvent::WindowDeactivate);
       
  8198     EventSpy sceneActivationChangeSpy(&scene, QEvent::ActivationChange);
       
  8199 
       
  8200     scene.setActivePanel(panel);
       
  8201     QCOMPARE(scene.activePanel(), (QGraphicsItem *)0);
       
  8202     QCOMPARE(itemActivateSpy.count(), 0);
       
  8203     QCOMPARE(itemDeactivateSpy.count(), 0);
       
  8204     QCOMPARE(panelActivateSpy.count(), 0);
       
  8205     QCOMPARE(panelDeactivateSpy.count(), 0);
       
  8206     QCOMPARE(sceneActivationChangeSpy.count(), 0);
       
  8207 }
       
  8208 
       
  8209 void tst_QGraphicsItem::activationOnShowHide()
       
  8210 {
       
  8211     QGraphicsScene scene;
       
  8212     QEvent activate(QEvent::WindowActivate);
       
  8213     QApplication::sendEvent(&scene, &activate);
       
  8214 
       
  8215     QGraphicsRectItem *rootPanel = scene.addRect(QRectF());
       
  8216     rootPanel->setFlag(QGraphicsItem::ItemIsPanel);
       
  8217     rootPanel->setActive(true);
       
  8218 
       
  8219     QGraphicsRectItem *subPanel = new QGraphicsRectItem;
       
  8220     subPanel->setFlag(QGraphicsItem::ItemIsPanel);
       
  8221 
       
  8222     // Reparenting onto an active panel auto-activates the child panel.
       
  8223     subPanel->setParentItem(rootPanel);
       
  8224     QVERIFY(subPanel->isActive());
       
  8225     QVERIFY(!rootPanel->isActive());
       
  8226 
       
  8227     // Hiding an active child panel will reactivate the parent panel.
       
  8228     subPanel->hide();
       
  8229     QVERIFY(rootPanel->isActive());
       
  8230 
       
  8231     // Showing a child panel will auto-activate it.
       
  8232     subPanel->show();
       
  8233     QVERIFY(subPanel->isActive());
       
  8234     QVERIFY(!rootPanel->isActive());
       
  8235 
       
  8236     // Adding an unrelated panel doesn't affect activation.
       
  8237     QGraphicsRectItem *otherPanel = new QGraphicsRectItem;
       
  8238     otherPanel->setFlag(QGraphicsItem::ItemIsPanel);
       
  8239     scene.addItem(otherPanel);
       
  8240     QVERIFY(subPanel->isActive());
       
  8241 
       
  8242     // Showing an unrelated panel doesn't affect activation.
       
  8243     otherPanel->hide();
       
  8244     otherPanel->show();
       
  8245     QVERIFY(subPanel->isActive());
       
  8246 
       
  8247     // Add a non-panel item.
       
  8248     QGraphicsRectItem *otherItem = new QGraphicsRectItem;
       
  8249     scene.addItem(otherItem);
       
  8250     otherItem->setActive(true);
       
  8251     QVERIFY(otherItem->isActive());
       
  8252 
       
  8253     // Reparent a panel onto an active non-panel item.
       
  8254     subPanel->setParentItem(otherItem);
       
  8255     QVERIFY(subPanel->isActive());
       
  8256 
       
  8257     // Showing a child panel of a non-panel item will activate it.
       
  8258     subPanel->hide();
       
  8259     QVERIFY(!subPanel->isActive());
       
  8260     QVERIFY(otherItem->isActive());
       
  8261     subPanel->show();
       
  8262     QVERIFY(subPanel->isActive());
       
  8263 
       
  8264     // Hiding a toplevel active panel will pass activation back
       
  8265     // to the non-panel items.
       
  8266     rootPanel->setActive(true);
       
  8267     rootPanel->hide();
       
  8268     QVERIFY(!rootPanel->isActive());
       
  8269     QVERIFY(otherItem->isActive());
       
  8270 }
       
  8271 
       
  8272 class MoveWhileDying : public QGraphicsRectItem
       
  8273 {
       
  8274 public:
       
  8275     MoveWhileDying(QGraphicsItem *parent = 0)
       
  8276         : QGraphicsRectItem(parent)
       
  8277     { }
       
  8278     ~MoveWhileDying()
       
  8279     {
       
  8280         foreach (QGraphicsItem *c, childItems()) {
       
  8281             foreach (QGraphicsItem *cc, c->childItems()) {
       
  8282                 cc->moveBy(10, 10);
       
  8283             }
       
  8284             c->moveBy(10, 10);
       
  8285         }
       
  8286         if (QGraphicsItem *p = parentItem()) { p->moveBy(10, 10); }
       
  8287     }
       
  8288 };
       
  8289 
       
  8290 void tst_QGraphicsItem::moveWhileDeleting()
       
  8291 {
       
  8292     QGraphicsScene scene;
       
  8293     QGraphicsRectItem *rect = new QGraphicsRectItem;
       
  8294     MoveWhileDying *silly = new MoveWhileDying(rect);
       
  8295     QGraphicsRectItem *child = new QGraphicsRectItem(silly);
       
  8296     scene.addItem(rect);
       
  8297     delete rect; // don't crash!
       
  8298 
       
  8299     rect = new QGraphicsRectItem;
       
  8300     silly = new MoveWhileDying(rect);
       
  8301     child = new QGraphicsRectItem(silly);
       
  8302 
       
  8303     QGraphicsView view(&scene);
       
  8304     view.show();
       
  8305 #ifdef Q_WS_X11
       
  8306     qt_x11_wait_for_window_manager(&view);
       
  8307 #endif
       
  8308     QTest::qWait(125);
       
  8309 
       
  8310     delete rect;
       
  8311 
       
  8312     rect = new QGraphicsRectItem;
       
  8313     rect->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  8314     silly = new MoveWhileDying(rect);
       
  8315     child = new QGraphicsRectItem(silly);
       
  8316 
       
  8317     QTest::qWait(125);
       
  8318 
       
  8319     delete rect;
       
  8320 
       
  8321     rect = new MoveWhileDying;
       
  8322     rect->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  8323     child = new QGraphicsRectItem(rect);
       
  8324     silly = new MoveWhileDying(child);
       
  8325 
       
  8326     QTest::qWait(125);
       
  8327 
       
  8328     delete rect;
       
  8329 }
       
  8330 
       
  8331 class MyRectItem : public QGraphicsWidget
       
  8332 {
       
  8333     Q_OBJECT
       
  8334 public:
       
  8335     MyRectItem(QGraphicsItem *parent = 0) : QGraphicsWidget(parent)
       
  8336     {
       
  8337 
       
  8338     }
       
  8339 
       
  8340     void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
       
  8341     {
       
  8342         painter->setBrush(brush);
       
  8343         painter->drawRect(boundingRect());
       
  8344     }
       
  8345     void move()
       
  8346     {
       
  8347         setPos(-100,-100);
       
  8348         topLevel->collidingItems(Qt::IntersectsItemBoundingRect);
       
  8349     }
       
  8350 public:
       
  8351     QGraphicsItem *topLevel;
       
  8352     QBrush brush;
       
  8353 };
       
  8354 
       
  8355 
       
  8356 void tst_QGraphicsItem::ensureDirtySceneTransform()
       
  8357 {
       
  8358     QGraphicsScene scene;
       
  8359 
       
  8360     MyRectItem *topLevel = new MyRectItem;
       
  8361     topLevel->setGeometry(0, 0, 100, 100);
       
  8362     topLevel->setPos(-50, -50);
       
  8363     topLevel->brush = QBrush(QColor(Qt::black));
       
  8364     scene.addItem(topLevel);
       
  8365 
       
  8366     MyRectItem *parent = new MyRectItem;
       
  8367     parent->topLevel = topLevel;
       
  8368     parent->setGeometry(0, 0, 100, 100);
       
  8369     parent->setPos(0, 0);
       
  8370     parent->brush = QBrush(QColor(Qt::magenta));
       
  8371     parent->setObjectName("parent");
       
  8372     scene.addItem(parent);
       
  8373 
       
  8374     MyRectItem *child = new MyRectItem(parent);
       
  8375     child->setGeometry(0, 0, 80, 80);
       
  8376     child->setPos(10, 10);
       
  8377     child->setObjectName("child");
       
  8378     child->brush = QBrush(QColor(Qt::blue));
       
  8379 
       
  8380     MyRectItem *child2 = new MyRectItem(parent);
       
  8381     child2->setGeometry(0, 0, 80, 80);
       
  8382     child2->setPos(15, 15);
       
  8383     child2->setObjectName("child2");
       
  8384     child2->brush = QBrush(QColor(Qt::green));
       
  8385 
       
  8386     MyRectItem *child3 = new MyRectItem(parent);
       
  8387     child3->setGeometry(0, 0, 80, 80);
       
  8388     child3->setPos(20, 20);
       
  8389     child3->setObjectName("child3");
       
  8390     child3->brush = QBrush(QColor(Qt::gray));
       
  8391 
       
  8392     QGraphicsView view(&scene);
       
  8393     view.show();
       
  8394     QTest::qWaitForWindowShown(&view);
       
  8395     QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
       
  8396 
       
  8397     //We move the parent
       
  8398     parent->move();
       
  8399     QApplication::processEvents();
       
  8400 
       
  8401     //We check if all items moved
       
  8402     QCOMPARE(child->pos(), QPointF(10, 10));
       
  8403     QCOMPARE(child2->pos(), QPointF(15, 15));
       
  8404     QCOMPARE(child3->pos(), QPointF(20, 20));
       
  8405 
       
  8406     QCOMPARE(child->sceneBoundingRect(), QRectF(-90, -90, 80, 80));
       
  8407     QCOMPARE(child2->sceneBoundingRect(), QRectF(-85, -85, 80, 80));
       
  8408     QCOMPARE(child3->sceneBoundingRect(), QRectF(-80, -80, 80, 80));
       
  8409 
       
  8410     QCOMPARE(child->sceneTransform(), QTransform::fromTranslate(-90, -90));
       
  8411     QCOMPARE(child2->sceneTransform(), QTransform::fromTranslate(-85, -85));
       
  8412     QCOMPARE(child3->sceneTransform(), QTransform::fromTranslate(-80, -80));
       
  8413 }
       
  8414 
       
  8415 void tst_QGraphicsItem::focusScope()
       
  8416 {
       
  8417     // ItemIsFocusScope is an internal feature (for now).
       
  8418     QGraphicsScene scene;
       
  8419 
       
  8420     QGraphicsRectItem *scope3 = new QGraphicsRectItem;
       
  8421     scope3->setData(0, "scope3");
       
  8422     scope3->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsFocusScope);
       
  8423     scope3->setFocus();
       
  8424     QVERIFY(!scope3->focusScopeItem());
       
  8425     QCOMPARE(scope3->focusItem(), (QGraphicsItem *)scope3);
       
  8426 
       
  8427     QGraphicsRectItem *scope2 = new QGraphicsRectItem;
       
  8428     scope2->setData(0, "scope2");
       
  8429     scope2->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsFocusScope);
       
  8430     scope2->setFocus();
       
  8431     QVERIFY(!scope2->focusScopeItem());
       
  8432     scope3->setParentItem(scope2);
       
  8433     QCOMPARE(scope2->focusScopeItem(), (QGraphicsItem *)scope3);
       
  8434     QCOMPARE(scope2->focusItem(), (QGraphicsItem *)scope2);
       
  8435 
       
  8436     QGraphicsRectItem *scope1 = new QGraphicsRectItem;
       
  8437     scope1->setData(0, "scope1");
       
  8438     scope1->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsFocusScope);
       
  8439     scope1->setFocus();
       
  8440     QVERIFY(!scope1->focusScopeItem());
       
  8441     scope2->setParentItem(scope1);
       
  8442 
       
  8443     QCOMPARE(scope1->focusItem(), (QGraphicsItem *)scope1);
       
  8444     QCOMPARE(scope2->focusItem(), (QGraphicsItem *)0);
       
  8445     QCOMPARE(scope3->focusItem(), (QGraphicsItem *)0);
       
  8446     QCOMPARE(scope1->focusScopeItem(), (QGraphicsItem *)scope2);
       
  8447     QCOMPARE(scope2->focusScopeItem(), (QGraphicsItem *)scope3);
       
  8448     QCOMPARE(scope3->focusScopeItem(), (QGraphicsItem *)0);
       
  8449 
       
  8450     scene.addItem(scope1);
       
  8451 
       
  8452     QEvent windowActivate(QEvent::WindowActivate);
       
  8453     qApp->sendEvent(&scene, &windowActivate);
       
  8454     scene.setFocus();
       
  8455 
       
  8456     QCOMPARE(scope1->focusItem(), (QGraphicsItem *)scope3);
       
  8457     QCOMPARE(scope2->focusItem(), (QGraphicsItem *)scope3);
       
  8458     QCOMPARE(scope3->focusItem(), (QGraphicsItem *)scope3);
       
  8459     QCOMPARE(scope1->focusScopeItem(), (QGraphicsItem *)scope2);
       
  8460     QCOMPARE(scope2->focusScopeItem(), (QGraphicsItem *)scope3);
       
  8461     QCOMPARE(scope3->focusScopeItem(), (QGraphicsItem *)0);
       
  8462 
       
  8463     QVERIFY(scope3->hasFocus());
       
  8464 
       
  8465     scope3->hide();
       
  8466     QVERIFY(scope2->hasFocus());
       
  8467     scope2->hide();
       
  8468     QVERIFY(scope1->hasFocus());
       
  8469     scope2->show();
       
  8470     QVERIFY(scope2->hasFocus());
       
  8471     scope3->show();
       
  8472     QVERIFY(scope3->hasFocus());
       
  8473     scope1->hide();
       
  8474     QVERIFY(!scope3->hasFocus());
       
  8475     scope1->show();
       
  8476     QVERIFY(scope3->hasFocus());
       
  8477     scope3->clearFocus();
       
  8478     QVERIFY(scope2->hasFocus());
       
  8479     scope2->clearFocus();
       
  8480     QVERIFY(scope1->hasFocus());
       
  8481     scope2->hide();
       
  8482     scope2->show();
       
  8483     QVERIFY(!scope2->hasFocus());
       
  8484     QVERIFY(scope3->hasFocus());
       
  8485 
       
  8486     QGraphicsRectItem *rect4 = new QGraphicsRectItem;
       
  8487     rect4->setData(0, "rect4");
       
  8488     rect4->setParentItem(scope3);
       
  8489 
       
  8490     QGraphicsRectItem *rect5 = new QGraphicsRectItem;
       
  8491     rect5->setData(0, "rect5");
       
  8492     rect5->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsFocusScope);
       
  8493     rect5->setFocus();
       
  8494     rect5->setParentItem(rect4);
       
  8495     QCOMPARE(scope3->focusScopeItem(), (QGraphicsItem *)rect5);
       
  8496     QVERIFY(!rect5->hasFocus());
       
  8497 
       
  8498     rect4->setParentItem(0);
       
  8499     QCOMPARE(scope3->focusScopeItem(), (QGraphicsItem *)0);
       
  8500     QVERIFY(scope3->hasFocus());
       
  8501 
       
  8502     QGraphicsRectItem *rectA = new QGraphicsRectItem;
       
  8503     QGraphicsRectItem *scopeA = new QGraphicsRectItem(rectA);
       
  8504     scopeA->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsFocusScope);
       
  8505     scopeA->setFocus();
       
  8506     QGraphicsRectItem *scopeB = new QGraphicsRectItem(scopeA);
       
  8507     scopeB->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsFocusScope);
       
  8508     scopeB->setFocus();
       
  8509 
       
  8510     scene.addItem(rectA);
       
  8511     QVERIFY(!rect5->hasFocus());
       
  8512     QVERIFY(!scopeB->hasFocus());
       
  8513 
       
  8514     scopeA->setFocus();
       
  8515     QVERIFY(scopeB->hasFocus());
       
  8516     QCOMPARE(scopeB->focusItem(), (QGraphicsItem *)scopeB);
       
  8517 }
       
  8518 
       
  8519 void tst_QGraphicsItem::stackBefore()
       
  8520 {
       
  8521     QGraphicsRectItem parent;
       
  8522     QGraphicsRectItem *child1 = new QGraphicsRectItem(QRectF(0, 0, 5, 5), &parent);
       
  8523     QGraphicsRectItem *child2 = new QGraphicsRectItem(QRectF(0, 0, 5, 5), &parent);
       
  8524     QGraphicsRectItem *child3 = new QGraphicsRectItem(QRectF(0, 0, 5, 5), &parent);
       
  8525     QGraphicsRectItem *child4 = new QGraphicsRectItem(QRectF(0, 0, 5, 5), &parent);
       
  8526     QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child1 << child2 << child3 << child4));
       
  8527     child1->setData(0, "child1");
       
  8528     child2->setData(0, "child2");
       
  8529     child3->setData(0, "child3");
       
  8530     child4->setData(0, "child4");
       
  8531 
       
  8532     // Remove and append
       
  8533     child2->setParentItem(0);
       
  8534     child2->setParentItem(&parent);
       
  8535     QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child1 << child3 << child4 << child2));
       
  8536 
       
  8537     // Move child2 before child1
       
  8538     child2->stackBefore(child1);
       
  8539     QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4));
       
  8540     child2->stackBefore(child2);
       
  8541     QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4));
       
  8542     child1->setZValue(1);
       
  8543     QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child3 << child4 << child1));
       
  8544     child1->stackBefore(child2); // no effect
       
  8545     QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child3 << child4 << child1));
       
  8546     child1->setZValue(0);
       
  8547     QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4));
       
  8548     child4->stackBefore(child1);
       
  8549     QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child4 << child1 << child3));
       
  8550     child4->setZValue(1);
       
  8551     QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4));
       
  8552     child3->stackBefore(child1);
       
  8553     QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child3 << child1 << child4));
       
  8554     child4->setZValue(0);
       
  8555     QCOMPARE(parent.childItems(), (QList<QGraphicsItem *>() << child2 << child4 << child3 << child1));
       
  8556 
       
  8557     // Make them all toplevels
       
  8558     child1->setParentItem(0);
       
  8559     child2->setParentItem(0);
       
  8560     child3->setParentItem(0);
       
  8561     child4->setParentItem(0);
       
  8562 
       
  8563     QGraphicsScene scene;
       
  8564     scene.addItem(child1);
       
  8565     scene.addItem(child2);
       
  8566     scene.addItem(child3);
       
  8567     scene.addItem(child4);
       
  8568     QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder),
       
  8569              (QList<QGraphicsItem *>() << child1 << child2 << child3 << child4));
       
  8570 
       
  8571     // Remove and append
       
  8572     scene.removeItem(child2);
       
  8573     scene.addItem(child2);
       
  8574     QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child1 << child3 << child4 << child2));
       
  8575 
       
  8576     // Move child2 before child1
       
  8577     child2->stackBefore(child1);
       
  8578     QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4));
       
  8579     child2->stackBefore(child2);
       
  8580     QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4));
       
  8581     child1->setZValue(1);
       
  8582     QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child3 << child4 << child1));
       
  8583     child1->stackBefore(child2); // no effect
       
  8584     QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child3 << child4 << child1));
       
  8585     child1->setZValue(0);
       
  8586     QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4));
       
  8587     child4->stackBefore(child1);
       
  8588     QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child4 << child1 << child3));
       
  8589     child4->setZValue(1);
       
  8590     QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child1 << child3 << child4));
       
  8591     child3->stackBefore(child1);
       
  8592     QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child3 << child1 << child4));
       
  8593     child4->setZValue(0);
       
  8594     QCOMPARE(scene.items(QPointF(2, 2), Qt::IntersectsItemBoundingRect, Qt::AscendingOrder), (QList<QGraphicsItem *>() << child2 << child4 << child3 << child1));
       
  8595 }
       
  8596 
       
  8597 void tst_QGraphicsItem::QTBUG_4233_updateCachedWithSceneRect()
       
  8598 {
       
  8599     EventTester *tester = new EventTester;
       
  8600     tester->setCacheMode(QGraphicsItem::ItemCoordinateCache);
       
  8601 
       
  8602     QGraphicsScene scene;
       
  8603     scene.addItem(tester);
       
  8604     scene.setSceneRect(-100, -100, 200, 200); // contains the tester item
       
  8605 
       
  8606     QGraphicsView view(&scene);
       
  8607     view.show();
       
  8608     QTest::qWaitForWindowShown(&view);
       
  8609     QTRY_COMPARE(QApplication::activeWindow(), (QWidget *)&view);
       
  8610 
       
  8611     QTRY_COMPARE(tester->repaints, 1);
       
  8612 
       
  8613     scene.update(); // triggers "updateAll" optimization
       
  8614     qApp->processEvents();
       
  8615     qApp->processEvents(); // in 4.6 only one processEvents is necessary
       
  8616 
       
  8617     QCOMPARE(tester->repaints, 1);
       
  8618 
       
  8619     scene.update(); // triggers "updateAll" optimization
       
  8620     tester->update();
       
  8621     qApp->processEvents();
       
  8622     qApp->processEvents(); // in 4.6 only one processEvents is necessary
       
  8623 
       
  8624     QCOMPARE(tester->repaints, 2);
       
  8625 }
       
  8626 
       
  8627 void tst_QGraphicsItem::sceneModality()
       
  8628 {
       
  8629     // 1) Test mouse events (delivery/propagation/redirection)
       
  8630     // 2) Test hover events (incl. leave on block, enter on unblock)
       
  8631     // 3) Test cursor stuff (incl. unset on block, set on unblock)
       
  8632     // 4) Test clickfocus
       
  8633     // 5) Test grab/ungrab events (possibly ungrab on block, regrab on unblock)
       
  8634     // 6) ### modality for non-panels is unsupported for now
       
  8635     QGraphicsScene scene;
       
  8636 
       
  8637     QGraphicsRectItem *bottomItem = scene.addRect(-150, -100, 300, 200);
       
  8638     bottomItem->setFlag(QGraphicsItem::ItemIsFocusable);
       
  8639     bottomItem->setBrush(Qt::yellow);
       
  8640 
       
  8641     QGraphicsRectItem *leftParent = scene.addRect(-50, -50, 100, 100);
       
  8642     leftParent->setFlag(QGraphicsItem::ItemIsPanel);
       
  8643     leftParent->setBrush(Qt::blue);
       
  8644 
       
  8645     QGraphicsRectItem *leftChild = scene.addRect(-25, -25, 50, 50);
       
  8646     leftChild->setFlag(QGraphicsItem::ItemIsPanel);
       
  8647     leftChild->setBrush(Qt::green);
       
  8648     leftChild->setParentItem(leftParent);
       
  8649 
       
  8650     QGraphicsRectItem *rightParent = scene.addRect(-50, -50, 100, 100);
       
  8651     rightParent->setFlag(QGraphicsItem::ItemIsPanel);
       
  8652     rightParent->setBrush(Qt::red);
       
  8653     QGraphicsRectItem *rightChild = scene.addRect(-25, -25, 50, 50);
       
  8654     rightChild->setFlag(QGraphicsItem::ItemIsPanel);
       
  8655     rightChild->setBrush(Qt::gray);
       
  8656     rightChild->setParentItem(rightParent);
       
  8657 
       
  8658     leftParent->setPos(-75, 0);
       
  8659     rightParent->setPos(75, 0);
       
  8660 
       
  8661     bottomItem->setData(0, "bottomItem");
       
  8662     leftParent->setData(0, "leftParent");
       
  8663     leftChild->setData(0, "leftChild");
       
  8664     rightParent->setData(0, "rightParent");
       
  8665     rightChild->setData(0, "rightChild");
       
  8666 
       
  8667     scene.setSceneRect(scene.itemsBoundingRect().adjusted(-50, -50, 50, 50));
       
  8668 
       
  8669     EventSpy2 leftParentSpy(&scene, leftParent);
       
  8670     EventSpy2 leftChildSpy(&scene, leftChild);
       
  8671     EventSpy2 rightParentSpy(&scene, rightParent);
       
  8672     EventSpy2 rightChildSpy(&scene, rightChild);
       
  8673     EventSpy2 bottomItemSpy(&scene, bottomItem);
       
  8674 
       
  8675     // Scene modality, also test multiple scene modal items
       
  8676     leftChild->setPanelModality(QGraphicsItem::SceneModal);
       
  8677     QCOMPARE(leftChildSpy.counts[QEvent::WindowBlocked], 0);
       
  8678     QCOMPARE(leftParentSpy.counts[QEvent::WindowBlocked], 1);
       
  8679     QCOMPARE(rightParentSpy.counts[QEvent::WindowBlocked], 1);
       
  8680     QCOMPARE(rightChildSpy.counts[QEvent::WindowBlocked], 1);
       
  8681     QCOMPARE(bottomItemSpy.counts[QEvent::WindowBlocked], 0); // not a panel
       
  8682 
       
  8683     // Click inside left child
       
  8684     sendMouseClick(&scene, leftChild->scenePos(), Qt::LeftButton);
       
  8685     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMousePress], 1);
       
  8686     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMouseRelease], 0); // no grab
       
  8687     QCOMPARE(leftParentSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8688     QCOMPARE(rightParentSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8689     QCOMPARE(rightChildSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8690     QCOMPARE(bottomItemSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8691 
       
  8692     // Click on left parent, event goes to modal child
       
  8693     sendMouseClick(&scene, leftParent->sceneBoundingRect().topLeft() + QPointF(5, 5), Qt::LeftButton);
       
  8694     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMousePress], 2);
       
  8695     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMouseRelease], 0); // no grab
       
  8696     QCOMPARE(leftParentSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8697     QCOMPARE(rightParentSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8698     QCOMPARE(rightChildSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8699     QCOMPARE(bottomItemSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8700 
       
  8701     // Click on all other items and outside the items
       
  8702     sendMouseClick(&scene, rightParent->sceneBoundingRect().topLeft() + QPointF(5, 5), Qt::LeftButton);
       
  8703     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMousePress], 3);
       
  8704     sendMouseClick(&scene, rightChild->scenePos(), Qt::LeftButton);
       
  8705     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMousePress], 4);
       
  8706     sendMouseClick(&scene, bottomItem->scenePos(), Qt::LeftButton);
       
  8707     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMousePress], 5);
       
  8708     sendMouseClick(&scene, QPointF(10000, 10000), Qt::LeftButton);
       
  8709     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMousePress], 6);
       
  8710     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMouseRelease], 0); // no grab
       
  8711     QCOMPARE(leftParentSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8712     QCOMPARE(rightParentSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8713     QCOMPARE(rightChildSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8714     QCOMPARE(bottomItemSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8715 
       
  8716     leftChildSpy.counts.clear();
       
  8717     rightChildSpy.counts.clear();
       
  8718     leftParentSpy.counts.clear();
       
  8719     rightParentSpy.counts.clear();
       
  8720     bottomItemSpy.counts.clear();
       
  8721 
       
  8722     leftChild->setPanelModality(QGraphicsItem::NonModal);
       
  8723     QCOMPARE(leftChildSpy.counts[QEvent::WindowUnblocked], 0);
       
  8724     QCOMPARE(rightChildSpy.counts[QEvent::WindowUnblocked], 1);
       
  8725     QCOMPARE(leftParentSpy.counts[QEvent::WindowUnblocked], 1);
       
  8726     QCOMPARE(rightParentSpy.counts[QEvent::WindowUnblocked], 1);
       
  8727     QCOMPARE(bottomItemSpy.counts[QEvent::WindowUnblocked], 0);
       
  8728 
       
  8729     // Left parent enters scene modality.
       
  8730     leftParent->setPanelModality(QGraphicsItem::SceneModal);
       
  8731     QCOMPARE(leftChildSpy.counts[QEvent::WindowBlocked], 0);
       
  8732     QCOMPARE(rightChildSpy.counts[QEvent::WindowBlocked], 1);
       
  8733     QCOMPARE(leftParentSpy.counts[QEvent::WindowBlocked], 0);
       
  8734     QCOMPARE(rightParentSpy.counts[QEvent::WindowBlocked], 1);
       
  8735     QCOMPARE(bottomItemSpy.counts[QEvent::WindowBlocked], 0);
       
  8736 
       
  8737     // Click inside left child.
       
  8738     sendMouseClick(&scene, leftChild->scenePos(), Qt::LeftButton);
       
  8739     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMousePress], 1);
       
  8740     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMouseRelease], 0);
       
  8741     QCOMPARE(leftParentSpy.counts[QEvent::GraphicsSceneMousePress], 0); // panel stops propagation
       
  8742     QCOMPARE(rightParentSpy.counts[QEvent::GraphicsSceneMousePress], 0);
       
  8743     QCOMPARE(rightChildSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8744     QCOMPARE(bottomItemSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8745 
       
  8746    // Click on left parent.
       
  8747     sendMouseClick(&scene, leftParent->sceneBoundingRect().topLeft() + QPointF(5, 5), Qt::LeftButton);
       
  8748     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMousePress], 1);
       
  8749     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMouseRelease], 0);
       
  8750     QCOMPARE(leftParentSpy.counts[QEvent::GraphicsSceneMousePress], 1);
       
  8751     QCOMPARE(rightParentSpy.counts[QEvent::GraphicsSceneMousePress], 0);
       
  8752     QCOMPARE(rightChildSpy.counts[QEvent::GraphicsSceneMousePress], 0);
       
  8753     QCOMPARE(bottomItemSpy.counts[QEvent::GraphicsSceneMousePress], 0);
       
  8754 
       
  8755     // Click on all other items and outside the items
       
  8756     sendMouseClick(&scene, rightParent->sceneBoundingRect().topLeft() + QPointF(5, 5), Qt::LeftButton);
       
  8757     QCOMPARE(leftParentSpy.counts[QEvent::GraphicsSceneMousePress], 2);
       
  8758     sendMouseClick(&scene, rightChild->scenePos(), Qt::LeftButton);
       
  8759     QCOMPARE(leftParentSpy.counts[QEvent::GraphicsSceneMousePress], 3);
       
  8760     sendMouseClick(&scene, bottomItem->scenePos(), Qt::LeftButton);
       
  8761     QCOMPARE(leftParentSpy.counts[QEvent::GraphicsSceneMousePress], 4);
       
  8762     sendMouseClick(&scene, QPointF(10000, 10000), Qt::LeftButton);
       
  8763     QCOMPARE(leftParentSpy.counts[QEvent::GraphicsSceneMousePress], 5);
       
  8764     QCOMPARE(leftParentSpy.counts[QEvent::GraphicsSceneMouseRelease], 0);
       
  8765     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMousePress], 1);
       
  8766     QCOMPARE(rightParentSpy.counts[QEvent::GraphicsSceneMousePress], 0);
       
  8767     QCOMPARE(rightChildSpy.counts[QEvent::GraphicsSceneMousePress], 0);
       
  8768     QCOMPARE(bottomItemSpy.counts[QEvent::GraphicsSceneMousePress], 0);
       
  8769 
       
  8770     leftChildSpy.counts.clear();
       
  8771     rightChildSpy.counts.clear();
       
  8772     leftParentSpy.counts.clear();
       
  8773     rightParentSpy.counts.clear();
       
  8774     bottomItemSpy.counts.clear();
       
  8775 
       
  8776     // Now both left parent and child are scene modal. Left parent is blocked.
       
  8777     leftChild->setPanelModality(QGraphicsItem::SceneModal);
       
  8778     QCOMPARE(leftChildSpy.counts[QEvent::WindowBlocked], 0);
       
  8779     QCOMPARE(rightChildSpy.counts[QEvent::WindowBlocked], 0);
       
  8780     QCOMPARE(leftParentSpy.counts[QEvent::WindowBlocked], 1);
       
  8781     QCOMPARE(rightParentSpy.counts[QEvent::WindowBlocked], 0);
       
  8782     QCOMPARE(bottomItemSpy.counts[QEvent::WindowBlocked], 0);
       
  8783 
       
  8784     // Click inside left child
       
  8785     sendMouseClick(&scene, leftChild->scenePos(), Qt::LeftButton);
       
  8786     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMousePress], 1);
       
  8787     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMouseRelease], 0); // no grab
       
  8788     QCOMPARE(leftParentSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8789     QCOMPARE(rightParentSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8790     QCOMPARE(rightChildSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8791     QCOMPARE(bottomItemSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8792 
       
  8793     // Click on left parent, event goes to modal child
       
  8794     sendMouseClick(&scene, leftParent->sceneBoundingRect().topLeft() + QPointF(5, 5), Qt::LeftButton);
       
  8795     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMousePress], 2);
       
  8796     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMouseRelease], 0); // no grab
       
  8797     QCOMPARE(leftParentSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8798     QCOMPARE(rightParentSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8799     QCOMPARE(rightChildSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8800     QCOMPARE(bottomItemSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8801 
       
  8802     // Click on all other items and outside the items
       
  8803     sendMouseClick(&scene, rightParent->sceneBoundingRect().topLeft() + QPointF(5, 5), Qt::LeftButton);
       
  8804     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMousePress], 3);
       
  8805     sendMouseClick(&scene, rightChild->scenePos(), Qt::LeftButton);
       
  8806     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMousePress], 4);
       
  8807     sendMouseClick(&scene, bottomItem->scenePos(), Qt::LeftButton);
       
  8808     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMousePress], 5);
       
  8809     sendMouseClick(&scene, QPointF(10000, 10000), Qt::LeftButton);
       
  8810     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMousePress], 6);
       
  8811     QCOMPARE(leftChildSpy.counts[QEvent::GraphicsSceneMouseRelease], 0); // no grab
       
  8812     QCOMPARE(leftParentSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8813     QCOMPARE(rightParentSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8814     QCOMPARE(rightChildSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8815     QCOMPARE(bottomItemSpy.counts[QEvent::GraphicsSceneMousePress], 0); // blocked
       
  8816 
       
  8817     leftChildSpy.counts.clear();
       
  8818     rightChildSpy.counts.clear();
       
  8819     leftParentSpy.counts.clear();
       
  8820     rightParentSpy.counts.clear();
       
  8821     bottomItemSpy.counts.clear();
       
  8822 
       
  8823     // Right child enters scene modality, only left child is blocked.
       
  8824     rightChild->setPanelModality(QGraphicsItem::SceneModal);
       
  8825     QCOMPARE(leftChildSpy.counts[QEvent::WindowBlocked], 1);
       
  8826     QCOMPARE(rightChildSpy.counts[QEvent::WindowBlocked], 0);
       
  8827     QCOMPARE(leftParentSpy.counts[QEvent::WindowBlocked], 0);
       
  8828     QCOMPARE(rightParentSpy.counts[QEvent::WindowBlocked], 0);
       
  8829     QCOMPARE(bottomItemSpy.counts[QEvent::WindowBlocked], 0);
       
  8830 }
       
  8831 
       
  8832 void tst_QGraphicsItem::panelModality()
       
  8833 {
       
  8834     // 1) Test mouse events (delivery/propagation/redirection)
       
  8835     // 2) Test hover events (incl. leave on block, enter on unblock)
       
  8836     // 3) Test cursor stuff (incl. unset on block, set on unblock)
       
  8837     // 4) Test clickfocus
       
  8838     // 5) Test grab/ungrab events (possibly ungrab on block, regrab on unblock)
       
  8839     // 6) ### modality for non-panels is unsupported for now
       
  8840     QGraphicsScene scene;
       
  8841 
       
  8842     QGraphicsRectItem *bottomItem = scene.addRect(-150, -100, 300, 200);
       
  8843     bottomItem->setFlag(QGraphicsItem::ItemIsFocusable);
       
  8844     bottomItem->setBrush(Qt::yellow);
       
  8845 
       
  8846     QGraphicsRectItem *leftParent = scene.addRect(-50, -50, 100, 100);
       
  8847     leftParent->setFlag(QGraphicsItem::ItemIsPanel);
       
  8848     leftParent->setBrush(Qt::blue);
       
  8849 
       
  8850     QGraphicsRectItem *leftChild = scene.addRect(-25, -25, 50, 50);
       
  8851     leftChild->setFlag(QGraphicsItem::ItemIsPanel);
       
  8852     leftChild->setBrush(Qt::green);
       
  8853     leftChild->setParentItem(leftParent);
       
  8854 
       
  8855     QGraphicsRectItem *rightParent = scene.addRect(-50, -50, 100, 100);
       
  8856     rightParent->setFlag(QGraphicsItem::ItemIsPanel);
       
  8857     rightParent->setBrush(Qt::red);
       
  8858     QGraphicsRectItem *rightChild = scene.addRect(-25, -25, 50, 50);
       
  8859     rightChild->setFlag(QGraphicsItem::ItemIsPanel);
       
  8860     rightChild->setBrush(Qt::gray);
       
  8861     rightChild->setParentItem(rightParent);
       
  8862 
       
  8863     leftParent->setPos(-75, 0);
       
  8864     rightParent->setPos(75, 0);
       
  8865 
       
  8866     bottomItem->setData(0, "bottomItem");
       
  8867     leftParent->setData(0, "leftParent");
       
  8868     leftChild->setData(0, "leftChild");
       
  8869     rightParent->setData(0, "rightParent");
       
  8870     rightChild->setData(0, "rightChild");
       
  8871 
       
  8872     scene.setSceneRect(scene.itemsBoundingRect().adjusted(-50, -50, 50, 50));
       
  8873 
       
  8874     EventSpy2 leftParentSpy(&scene, leftParent);
       
  8875     EventSpy2 leftChildSpy(&scene, leftChild);
       
  8876     EventSpy2 rightParentSpy(&scene, rightParent);
       
  8877     EventSpy2 rightChildSpy(&scene, rightChild);
       
  8878     EventSpy2 bottomItemSpy(&scene, bottomItem);
       
  8879 
       
  8880     // Left Child enters panel modality, only left parent is blocked.
       
  8881     leftChild->setPanelModality(QGraphicsItem::PanelModal);
       
  8882     QCOMPARE(leftChildSpy.counts[QEvent::WindowBlocked], 0);
       
  8883     QCOMPARE(rightChildSpy.counts[QEvent::WindowBlocked], 0);
       
  8884     QCOMPARE(leftParentSpy.counts[QEvent::WindowBlocked], 1);
       
  8885     QCOMPARE(rightParentSpy.counts[QEvent::WindowBlocked], 0);
       
  8886     QCOMPARE(bottomItemSpy.counts[QEvent::WindowBlocked], 0);
       
  8887 
       
  8888     leftChild->setPanelModality(QGraphicsItem::NonModal);
       
  8889     leftChildSpy.counts.clear();
       
  8890     rightChildSpy.counts.clear();
       
  8891     leftParentSpy.counts.clear();
       
  8892     rightParentSpy.counts.clear();
       
  8893     bottomItemSpy.counts.clear();
       
  8894 
       
  8895     // Left parent enter panel modality, nothing is blocked.
       
  8896     leftParent->setPanelModality(QGraphicsItem::PanelModal);
       
  8897     QCOMPARE(leftChildSpy.counts[QEvent::WindowBlocked], 0);
       
  8898     QCOMPARE(rightChildSpy.counts[QEvent::WindowBlocked], 0);
       
  8899     QCOMPARE(leftParentSpy.counts[QEvent::WindowBlocked], 0);
       
  8900     QCOMPARE(rightParentSpy.counts[QEvent::WindowBlocked], 0);
       
  8901     QCOMPARE(bottomItemSpy.counts[QEvent::WindowBlocked], 0);
       
  8902 
       
  8903     // Left child enters panel modality, left parent is blocked again.
       
  8904     leftChild->setPanelModality(QGraphicsItem::PanelModal);
       
  8905     QCOMPARE(leftChildSpy.counts[QEvent::WindowBlocked], 0);
       
  8906     QCOMPARE(rightChildSpy.counts[QEvent::WindowBlocked], 0);
       
  8907     QCOMPARE(leftParentSpy.counts[QEvent::WindowBlocked], 1);
       
  8908     QCOMPARE(rightParentSpy.counts[QEvent::WindowBlocked], 0);
       
  8909     QCOMPARE(bottomItemSpy.counts[QEvent::WindowBlocked], 0);
       
  8910 
       
  8911     leftChildSpy.counts.clear();
       
  8912     rightChildSpy.counts.clear();
       
  8913     leftParentSpy.counts.clear();
       
  8914     rightParentSpy.counts.clear();
       
  8915     bottomItemSpy.counts.clear();
       
  8916 
       
  8917     leftChild->setPanelModality(QGraphicsItem::NonModal);
       
  8918     QCOMPARE(leftParentSpy.counts[QEvent::WindowUnblocked], 1);
       
  8919     leftParent->setPanelModality(QGraphicsItem::NonModal);
       
  8920     QCOMPARE(leftChildSpy.counts[QEvent::WindowUnblocked], 0);
       
  8921     QCOMPARE(rightChildSpy.counts[QEvent::WindowUnblocked], 0);
       
  8922     QCOMPARE(leftParentSpy.counts[QEvent::WindowUnblocked], 1);
       
  8923     QCOMPARE(rightParentSpy.counts[QEvent::WindowUnblocked], 0);
       
  8924     QCOMPARE(bottomItemSpy.counts[QEvent::WindowUnblocked], 0);
       
  8925 
       
  8926     leftChildSpy.counts.clear();
       
  8927     rightChildSpy.counts.clear();
       
  8928     leftParentSpy.counts.clear();
       
  8929     rightParentSpy.counts.clear();
       
  8930     bottomItemSpy.counts.clear();
       
  8931 
       
  8932     // Left and right child enter panel modality, both parents are blocked.
       
  8933     rightChild->setPanelModality(QGraphicsItem::PanelModal);
       
  8934     QCOMPARE(leftParentSpy.counts[QEvent::WindowBlocked], 0);
       
  8935     QCOMPARE(rightParentSpy.counts[QEvent::WindowBlocked], 1);
       
  8936     leftChild->setPanelModality(QGraphicsItem::PanelModal);
       
  8937     QCOMPARE(leftParentSpy.counts[QEvent::WindowBlocked], 1);
       
  8938     QCOMPARE(rightParentSpy.counts[QEvent::WindowBlocked], 1);
       
  8939 }
       
  8940 
       
  8941 void tst_QGraphicsItem::mixedModality()
       
  8942 {
       
  8943     // 1) Test mouse events (delivery/propagation/redirection)
       
  8944     // 2) Test hover events (incl. leave on block, enter on unblock)
       
  8945     // 3) Test cursor stuff (incl. unset on block, set on unblock)
       
  8946     // 4) Test clickfocus
       
  8947     // 5) Test grab/ungrab events (possibly ungrab on block, regrab on unblock)
       
  8948     // 6) ### modality for non-panels is unsupported for now
       
  8949     QGraphicsScene scene;
       
  8950 
       
  8951     QGraphicsRectItem *bottomItem = scene.addRect(-150, -100, 300, 200);
       
  8952     bottomItem->setFlag(QGraphicsItem::ItemIsFocusable);
       
  8953     bottomItem->setBrush(Qt::yellow);
       
  8954 
       
  8955     QGraphicsRectItem *leftParent = scene.addRect(-50, -50, 100, 100);
       
  8956     leftParent->setFlag(QGraphicsItem::ItemIsPanel);
       
  8957     leftParent->setBrush(Qt::blue);
       
  8958 
       
  8959     QGraphicsRectItem *leftChild = scene.addRect(-25, -25, 50, 50);
       
  8960     leftChild->setFlag(QGraphicsItem::ItemIsPanel);
       
  8961     leftChild->setBrush(Qt::green);
       
  8962     leftChild->setParentItem(leftParent);
       
  8963 
       
  8964     QGraphicsRectItem *rightParent = scene.addRect(-50, -50, 100, 100);
       
  8965     rightParent->setFlag(QGraphicsItem::ItemIsPanel);
       
  8966     rightParent->setBrush(Qt::red);
       
  8967     QGraphicsRectItem *rightChild = scene.addRect(-25, -25, 50, 50);
       
  8968     rightChild->setFlag(QGraphicsItem::ItemIsPanel);
       
  8969     rightChild->setBrush(Qt::gray);
       
  8970     rightChild->setParentItem(rightParent);
       
  8971 
       
  8972     leftParent->setPos(-75, 0);
       
  8973     rightParent->setPos(75, 0);
       
  8974 
       
  8975     bottomItem->setData(0, "bottomItem");
       
  8976     leftParent->setData(0, "leftParent");
       
  8977     leftChild->setData(0, "leftChild");
       
  8978     rightParent->setData(0, "rightParent");
       
  8979     rightChild->setData(0, "rightChild");
       
  8980 
       
  8981     scene.setSceneRect(scene.itemsBoundingRect().adjusted(-50, -50, 50, 50));
       
  8982 
       
  8983     EventSpy2 leftParentSpy(&scene, leftParent);
       
  8984     EventSpy2 leftChildSpy(&scene, leftChild);
       
  8985     EventSpy2 rightParentSpy(&scene, rightParent);
       
  8986     EventSpy2 rightChildSpy(&scene, rightChild);
       
  8987     EventSpy2 bottomItemSpy(&scene, bottomItem);
       
  8988 
       
  8989     // Left Child enters panel modality, only left parent is blocked.
       
  8990     leftChild->setPanelModality(QGraphicsItem::PanelModal);
       
  8991     QCOMPARE(leftChildSpy.counts[QEvent::WindowBlocked], 0);
       
  8992     QCOMPARE(rightChildSpy.counts[QEvent::WindowBlocked], 0);
       
  8993     QCOMPARE(leftParentSpy.counts[QEvent::WindowBlocked], 1);
       
  8994     QCOMPARE(rightParentSpy.counts[QEvent::WindowBlocked], 0);
       
  8995 
       
  8996     // Left parent enters scene modality, which blocks everything except the child.
       
  8997     leftParent->setPanelModality(QGraphicsItem::SceneModal);
       
  8998     QCOMPARE(leftChildSpy.counts[QEvent::WindowBlocked], 0);
       
  8999     QCOMPARE(leftChildSpy.counts[QEvent::WindowUnblocked], 0);
       
  9000     QCOMPARE(rightChildSpy.counts[QEvent::WindowBlocked], 1);
       
  9001     QCOMPARE(rightChildSpy.counts[QEvent::WindowUnblocked], 0);
       
  9002     QCOMPARE(leftParentSpy.counts[QEvent::WindowBlocked], 1);
       
  9003     QCOMPARE(leftParentSpy.counts[QEvent::WindowUnblocked], 0);
       
  9004     QCOMPARE(rightParentSpy.counts[QEvent::WindowBlocked], 1);
       
  9005     QCOMPARE(rightParentSpy.counts[QEvent::WindowUnblocked], 0);
       
  9006 
       
  9007     // Right child enters panel modality (changes nothing).
       
  9008     rightChild->setPanelModality(QGraphicsItem::PanelModal);
       
  9009     QCOMPARE(leftChildSpy.counts[QEvent::WindowBlocked], 0);
       
  9010     QCOMPARE(leftChildSpy.counts[QEvent::WindowUnblocked], 0);
       
  9011     QCOMPARE(rightChildSpy.counts[QEvent::WindowBlocked], 1);
       
  9012     QCOMPARE(rightChildSpy.counts[QEvent::WindowUnblocked], 0);
       
  9013     QCOMPARE(leftParentSpy.counts[QEvent::WindowBlocked], 1);
       
  9014     QCOMPARE(leftParentSpy.counts[QEvent::WindowUnblocked], 0);
       
  9015     QCOMPARE(rightParentSpy.counts[QEvent::WindowBlocked], 1);
       
  9016     QCOMPARE(rightParentSpy.counts[QEvent::WindowUnblocked], 0);
       
  9017 
       
  9018     // Left parent leaves modality. Right child is unblocked.
       
  9019     leftParent->setPanelModality(QGraphicsItem::NonModal);
       
  9020     QCOMPARE(leftChildSpy.counts[QEvent::WindowBlocked], 0);
       
  9021     QCOMPARE(leftChildSpy.counts[QEvent::WindowUnblocked], 0);
       
  9022     QCOMPARE(rightChildSpy.counts[QEvent::WindowBlocked], 1);
       
  9023     QCOMPARE(rightChildSpy.counts[QEvent::WindowUnblocked], 1);
       
  9024     QCOMPARE(leftParentSpy.counts[QEvent::WindowBlocked], 1);
       
  9025     QCOMPARE(leftParentSpy.counts[QEvent::WindowUnblocked], 0);
       
  9026     QCOMPARE(rightParentSpy.counts[QEvent::WindowBlocked], 1);
       
  9027     QCOMPARE(rightParentSpy.counts[QEvent::WindowUnblocked], 0);
       
  9028 
       
  9029     // Right child "upgrades" its modality to scene modal. Left child is blocked.
       
  9030     // Right parent is unaffected.
       
  9031     rightChild->setPanelModality(QGraphicsItem::SceneModal);
       
  9032     QCOMPARE(leftChildSpy.counts[QEvent::WindowBlocked], 1);
       
  9033     QCOMPARE(leftChildSpy.counts[QEvent::WindowUnblocked], 0);
       
  9034     QCOMPARE(rightChildSpy.counts[QEvent::WindowBlocked], 1);
       
  9035     QCOMPARE(rightChildSpy.counts[QEvent::WindowUnblocked], 1);
       
  9036     QCOMPARE(leftParentSpy.counts[QEvent::WindowBlocked], 1);
       
  9037     QCOMPARE(leftParentSpy.counts[QEvent::WindowUnblocked], 0);
       
  9038     QCOMPARE(rightParentSpy.counts[QEvent::WindowBlocked], 1);
       
  9039     QCOMPARE(rightParentSpy.counts[QEvent::WindowUnblocked], 0);
       
  9040 
       
  9041     // "downgrade" right child back to panel modal, left child is unblocked
       
  9042     rightChild->setPanelModality(QGraphicsItem::PanelModal);
       
  9043     QCOMPARE(leftChildSpy.counts[QEvent::WindowBlocked], 1);
       
  9044     QCOMPARE(leftChildSpy.counts[QEvent::WindowUnblocked], 1);
       
  9045     QCOMPARE(rightChildSpy.counts[QEvent::WindowBlocked], 1);
       
  9046     QCOMPARE(rightChildSpy.counts[QEvent::WindowUnblocked], 1);
       
  9047     QCOMPARE(leftParentSpy.counts[QEvent::WindowBlocked], 1);
       
  9048     QCOMPARE(leftParentSpy.counts[QEvent::WindowUnblocked], 0);
       
  9049     QCOMPARE(rightParentSpy.counts[QEvent::WindowBlocked], 1);
       
  9050     QCOMPARE(rightParentSpy.counts[QEvent::WindowUnblocked], 0);
       
  9051 }
       
  9052 
       
  9053 void tst_QGraphicsItem::modality_hover()
       
  9054 {
       
  9055     QGraphicsScene scene;
       
  9056     QGraphicsRectItem *rect1 = scene.addRect(-50, -50, 100, 100);
       
  9057     rect1->setFlag(QGraphicsItem::ItemIsPanel);
       
  9058     rect1->setAcceptHoverEvents(true);
       
  9059     rect1->setData(0, "rect1");
       
  9060 
       
  9061     QGraphicsRectItem *rect2 = scene.addRect(-50, -50, 100, 100);
       
  9062     rect2->setParentItem(rect1);
       
  9063     rect2->setFlag(QGraphicsItem::ItemIsPanel);
       
  9064     rect2->setAcceptHoverEvents(true);
       
  9065     rect2->setPos(50, 50);
       
  9066     rect2->setPanelModality(QGraphicsItem::SceneModal);
       
  9067     rect2->setData(0, "rect2");
       
  9068 
       
  9069     EventSpy2 rect1Spy(&scene, rect1);
       
  9070     EventSpy2 rect2Spy(&scene, rect2);
       
  9071 
       
  9072     sendMouseMove(&scene, QPointF(-25, -25));
       
  9073 
       
  9074     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverEnter], 0);
       
  9075     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverMove], 0);
       
  9076     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverLeave], 0);
       
  9077 
       
  9078     sendMouseMove(&scene, QPointF(75, 75));
       
  9079 
       
  9080     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverEnter], 0);
       
  9081     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverMove], 0);
       
  9082     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverLeave], 0);
       
  9083     QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneHoverEnter], 1);
       
  9084     QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneHoverMove], 1);
       
  9085     QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneHoverLeave], 0);
       
  9086 
       
  9087     sendMouseMove(&scene, QPointF(-25, -25));
       
  9088 
       
  9089     QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneHoverLeave], 1);
       
  9090     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverEnter], 0);
       
  9091     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverMove], 0);
       
  9092     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverLeave], 0);
       
  9093 
       
  9094     rect2->setPanelModality(QGraphicsItem::NonModal);
       
  9095 
       
  9096     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverEnter], 1);
       
  9097     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverMove], 1);
       
  9098 
       
  9099     sendMouseMove(&scene, QPointF(75, 75));
       
  9100 
       
  9101     QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneHoverEnter], 2);
       
  9102     QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneHoverMove], 2);
       
  9103 
       
  9104     rect2->setPanelModality(QGraphicsItem::SceneModal);
       
  9105 
       
  9106     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverLeave], 1);
       
  9107     QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneHoverEnter], 2);
       
  9108     // changing modality causes a spurious GraphicsSceneHoveMove, even though the mouse didn't
       
  9109     // actually move
       
  9110     QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneHoverMove], 3);
       
  9111 
       
  9112     sendMouseMove(&scene, QPointF(-25, -25));
       
  9113 
       
  9114     QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneHoverLeave], 2);
       
  9115     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverEnter], 1);
       
  9116     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverMove], 1);
       
  9117     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverLeave], 1);
       
  9118 
       
  9119     rect2->setPanelModality(QGraphicsItem::PanelModal);
       
  9120 
       
  9121     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverEnter], 1);
       
  9122     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverMove], 1);
       
  9123     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverLeave], 1);
       
  9124     QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneHoverEnter], 2);
       
  9125     QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneHoverMove], 3);
       
  9126     QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneHoverLeave], 2);
       
  9127 
       
  9128     rect2->setPanelModality(QGraphicsItem::NonModal);
       
  9129 
       
  9130     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverEnter], 2);
       
  9131     QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneHoverMove], 2);
       
  9132     QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneHoverEnter], 2);
       
  9133     QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneHoverMove], 3);
       
  9134     QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneHoverLeave], 2);
       
  9135 }
       
  9136 
       
  9137 void tst_QGraphicsItem::modality_mouseGrabber()
       
  9138 {
       
  9139     QGraphicsScene scene;
       
  9140     QGraphicsRectItem *rect1 = scene.addRect(-50, -50, 100, 100);
       
  9141     rect1->setFlag(QGraphicsItem::ItemIsPanel);
       
  9142     rect1->setFlag(QGraphicsItem::ItemIsMovable);
       
  9143     rect1->setData(0, "rect1");
       
  9144 
       
  9145     QGraphicsRectItem *rect2 = scene.addRect(-50, -50, 100, 100);
       
  9146     rect2->setParentItem(rect1);
       
  9147     rect2->setFlag(QGraphicsItem::ItemIsPanel);
       
  9148     rect2->setFlag(QGraphicsItem::ItemIsMovable);
       
  9149     rect2->setPos(50, 50);
       
  9150     rect2->setData(0, "rect2");
       
  9151 
       
  9152     EventSpy2 rect1Spy(&scene, rect1);
       
  9153     EventSpy2 rect2Spy(&scene, rect2);
       
  9154 
       
  9155     {
       
  9156         // pressing mouse on rect1 starts implicit grab
       
  9157         sendMousePress(&scene, QPoint(-25, -25));
       
  9158         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 1);
       
  9159         QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneMousePress], 1);
       
  9160         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 0);
       
  9161         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 0);
       
  9162         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 0);
       
  9163         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) rect1);
       
  9164 
       
  9165         // grab lost when rect1 is modally shadowed
       
  9166         rect2->setPanelModality(QGraphicsItem::SceneModal);
       
  9167         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 1);
       
  9168         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 1);
       
  9169         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 0);
       
  9170         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 0);
       
  9171         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) 0);
       
  9172 
       
  9173         // releasing goes nowhere
       
  9174         sendMouseRelease(&scene, QPoint(-25, -25));
       
  9175         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 1);
       
  9176         QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneMouseRelease], 0);
       
  9177         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 1);
       
  9178         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 0);
       
  9179         QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneMouseRelease], 0);
       
  9180         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 0);
       
  9181         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) 0);
       
  9182 
       
  9183         // pressing mouse on rect1 starts implicit grab on rect2 (since it is modal)
       
  9184         sendMouseClick(&scene, QPoint(-25, -25));
       
  9185         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 1);
       
  9186         QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneMousePress], 1);
       
  9187         QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneMouseRelease], 0);
       
  9188         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 1);
       
  9189         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 1);
       
  9190         QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneMousePress], 1);
       
  9191         QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneMouseRelease], 1);
       
  9192         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 1);
       
  9193 
       
  9194         rect2->setPanelModality(QGraphicsItem::NonModal);
       
  9195 
       
  9196         // pressing mouse on rect1 starts implicit grab
       
  9197         sendMousePress(&scene, QPoint(-25, -25));
       
  9198         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 2);
       
  9199         QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneMousePress], 2);
       
  9200         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 1);
       
  9201         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 1);
       
  9202         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 1);
       
  9203         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) rect1);
       
  9204 
       
  9205         // grab lost to rect2 when rect1 is modally shadowed
       
  9206         rect2->setPanelModality(QGraphicsItem::SceneModal);
       
  9207         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 2);
       
  9208         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 2);
       
  9209         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 1);
       
  9210         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 1);
       
  9211         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) 0);
       
  9212 
       
  9213         // rect1 does *not* re-grab when rect2 is no longer modal
       
  9214         rect2->setPanelModality(QGraphicsItem::NonModal);
       
  9215         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 2);
       
  9216         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 2);
       
  9217         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 1);
       
  9218         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 1);
       
  9219         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) 0);
       
  9220 
       
  9221         // release goes nowhere
       
  9222         sendMouseRelease(&scene, QPoint(-25, -25));
       
  9223         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 2);
       
  9224         QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneMouseRelease], 0);
       
  9225         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 2);
       
  9226         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 1);
       
  9227         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 1);
       
  9228         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) 0);
       
  9229     }
       
  9230     {
       
  9231         // repeat the test using PanelModal
       
  9232         rect2->setPanelModality(QGraphicsItem::NonModal);
       
  9233         rect1Spy.counts.clear();
       
  9234         rect2Spy.counts.clear();
       
  9235 
       
  9236         // pressing mouse on rect1 starts implicit grab
       
  9237         sendMousePress(&scene, QPoint(-25, -25));
       
  9238         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 1);
       
  9239         QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneMousePress], 1);
       
  9240         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 0);
       
  9241         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 0);
       
  9242         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 0);
       
  9243         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) rect1);
       
  9244 
       
  9245         // grab lost when rect1 is modally shadowed
       
  9246         rect2->setPanelModality(QGraphicsItem::PanelModal);
       
  9247         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 1);
       
  9248         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 1);
       
  9249         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 0);
       
  9250         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 0);
       
  9251         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) 0);
       
  9252 
       
  9253         // releasing goes nowhere
       
  9254         sendMouseRelease(&scene, QPoint(-25, -25));
       
  9255         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 1);
       
  9256         QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneMouseRelease], 0);
       
  9257         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 1);
       
  9258         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 0);
       
  9259         QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneMouseRelease], 0);
       
  9260         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 0);
       
  9261         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) 0);
       
  9262 
       
  9263         // pressing mouse on rect1 starts implicit grab on rect2 (since it is modal)
       
  9264         sendMouseClick(&scene, QPoint(-25, -25));
       
  9265         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 1);
       
  9266         QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneMousePress], 1);
       
  9267         QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneMouseRelease], 0);
       
  9268         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 1);
       
  9269         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 1);
       
  9270         QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneMousePress], 1);
       
  9271         QCOMPARE(rect2Spy.counts[QEvent::GraphicsSceneMouseRelease], 1);
       
  9272         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 1);
       
  9273 
       
  9274         rect2->setPanelModality(QGraphicsItem::NonModal);
       
  9275 
       
  9276         // pressing mouse on rect1 starts implicit grab
       
  9277         sendMousePress(&scene, QPoint(-25, -25));
       
  9278         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 2);
       
  9279         QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneMousePress], 2);
       
  9280         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 1);
       
  9281         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 1);
       
  9282         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 1);
       
  9283         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) rect1);
       
  9284 
       
  9285         // grab lost to rect2 when rect1 is modally shadowed
       
  9286         rect2->setPanelModality(QGraphicsItem::PanelModal);
       
  9287         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 2);
       
  9288         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 2);
       
  9289         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 1);
       
  9290         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 1);
       
  9291         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) 0);
       
  9292 
       
  9293         // rect1 does *not* re-grab when rect2 is no longer modal
       
  9294         rect2->setPanelModality(QGraphicsItem::NonModal);
       
  9295         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 2);
       
  9296         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 2);
       
  9297         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 1);
       
  9298         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 1);
       
  9299         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) 0);
       
  9300 
       
  9301         // release goes nowhere
       
  9302         sendMouseRelease(&scene, QPoint(-25, -25));
       
  9303         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 2);
       
  9304         QCOMPARE(rect1Spy.counts[QEvent::GraphicsSceneMouseRelease], 0);
       
  9305         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 2);
       
  9306         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 1);
       
  9307         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 1);
       
  9308         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) 0);
       
  9309     }
       
  9310 
       
  9311     {
       
  9312         // repeat the PanelModal tests, but this time the mouse events will be on a non-modal item,
       
  9313         // meaning normal grabbing should work
       
  9314         rect2->setPanelModality(QGraphicsItem::NonModal);
       
  9315         rect1Spy.counts.clear();
       
  9316         rect2Spy.counts.clear();
       
  9317 
       
  9318         QGraphicsRectItem *rect3 = scene.addRect(-50, -50, 100, 100);
       
  9319         rect3->setFlag(QGraphicsItem::ItemIsPanel);
       
  9320         rect3->setFlag(QGraphicsItem::ItemIsMovable);
       
  9321         rect3->setPos(150, 50);
       
  9322         rect3->setData(0, "rect3");
       
  9323 
       
  9324         EventSpy2 rect3Spy(&scene, rect3);
       
  9325 
       
  9326         // pressing mouse on rect3 starts implicit grab
       
  9327         sendMousePress(&scene, QPoint(150, 50));
       
  9328         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 0);
       
  9329         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 0);
       
  9330         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 0);
       
  9331         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 0);
       
  9332         QCOMPARE(rect3Spy.counts[QEvent::GrabMouse], 1);
       
  9333         QCOMPARE(rect3Spy.counts[QEvent::GraphicsSceneMousePress], 1);
       
  9334         QCOMPARE(rect3Spy.counts[QEvent::UngrabMouse], 0);
       
  9335         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) rect3);
       
  9336 
       
  9337         // grab is *not* lost when rect1 is modally shadowed by rect2
       
  9338         rect2->setPanelModality(QGraphicsItem::PanelModal);
       
  9339         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 0);
       
  9340         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 0);
       
  9341         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 0);
       
  9342         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 0);
       
  9343         QCOMPARE(rect3Spy.counts[QEvent::GrabMouse], 1);
       
  9344         QCOMPARE(rect3Spy.counts[QEvent::UngrabMouse], 0);
       
  9345         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) rect3);
       
  9346 
       
  9347         // releasing goes to rect3
       
  9348         sendMouseRelease(&scene, QPoint(150, 50));
       
  9349         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 0);
       
  9350         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 0);
       
  9351         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 0);
       
  9352         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 0);
       
  9353         QCOMPARE(rect3Spy.counts[QEvent::GrabMouse], 1);
       
  9354         QCOMPARE(rect3Spy.counts[QEvent::GraphicsSceneMouseRelease], 1);
       
  9355         QCOMPARE(rect3Spy.counts[QEvent::UngrabMouse], 1);
       
  9356         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) 0);
       
  9357 
       
  9358         rect2->setPanelModality(QGraphicsItem::NonModal);
       
  9359 
       
  9360         // pressing mouse on rect3 starts implicit grab
       
  9361         sendMousePress(&scene, QPoint(150, 50));
       
  9362         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 0);
       
  9363         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 0);
       
  9364         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 0);
       
  9365         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 0);
       
  9366         QCOMPARE(rect3Spy.counts[QEvent::GrabMouse], 2);
       
  9367         QCOMPARE(rect3Spy.counts[QEvent::UngrabMouse], 1);
       
  9368         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) rect3);
       
  9369 
       
  9370         // grab is not lost
       
  9371         rect2->setPanelModality(QGraphicsItem::PanelModal);
       
  9372         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 0);
       
  9373         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 0);
       
  9374         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 0);
       
  9375         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 0);
       
  9376         QCOMPARE(rect3Spy.counts[QEvent::GrabMouse], 2);
       
  9377         QCOMPARE(rect3Spy.counts[QEvent::UngrabMouse], 1);
       
  9378         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) rect3);
       
  9379 
       
  9380         // grab stays on rect3
       
  9381         rect2->setPanelModality(QGraphicsItem::NonModal);
       
  9382         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 0);
       
  9383         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 0);
       
  9384         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 0);
       
  9385         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 0);
       
  9386         QCOMPARE(rect3Spy.counts[QEvent::GrabMouse], 2);
       
  9387         QCOMPARE(rect3Spy.counts[QEvent::UngrabMouse], 1);
       
  9388         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) rect3);
       
  9389 
       
  9390         // release goes to rect3
       
  9391         sendMouseRelease(&scene, QPoint(150, 50));
       
  9392         QCOMPARE(rect1Spy.counts[QEvent::GrabMouse], 0);
       
  9393         QCOMPARE(rect1Spy.counts[QEvent::UngrabMouse], 0);
       
  9394         QCOMPARE(rect2Spy.counts[QEvent::GrabMouse], 0);
       
  9395         QCOMPARE(rect2Spy.counts[QEvent::UngrabMouse], 0);
       
  9396         QCOMPARE(rect3Spy.counts[QEvent::GrabMouse], 2);
       
  9397         QCOMPARE(rect3Spy.counts[QEvent::UngrabMouse], 2);
       
  9398         QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *) 0);
       
  9399     }
       
  9400 }
       
  9401 
       
  9402 void tst_QGraphicsItem::modality_clickFocus()
       
  9403 {
       
  9404     QGraphicsScene scene;
       
  9405     QGraphicsRectItem *rect1 = scene.addRect(-50, -50, 100, 100);
       
  9406     rect1->setFlag(QGraphicsItem::ItemIsPanel);
       
  9407     rect1->setFlag(QGraphicsItem::ItemIsFocusable);
       
  9408     rect1->setData(0, "rect1");
       
  9409 
       
  9410     QGraphicsRectItem *rect2 = scene.addRect(-50, -50, 100, 100);
       
  9411     rect2->setParentItem(rect1);
       
  9412     rect2->setFlag(QGraphicsItem::ItemIsPanel);
       
  9413     rect2->setFlag(QGraphicsItem::ItemIsFocusable);
       
  9414     rect2->setPos(50, 50);
       
  9415     rect2->setData(0, "rect2");
       
  9416 
       
  9417     QEvent windowActivateEvent(QEvent::WindowActivate);
       
  9418     QApplication::sendEvent(&scene, &windowActivateEvent);
       
  9419 
       
  9420     EventSpy2 rect1Spy(&scene, rect1);
       
  9421     EventSpy2 rect2Spy(&scene, rect2);
       
  9422 
       
  9423     // activate rect1, it should not get focus
       
  9424     rect1->setActive(true);
       
  9425     QCOMPARE(scene.focusItem(), (QGraphicsItem *) 0);
       
  9426 
       
  9427     // focus stays unset when rect2 becomes modal
       
  9428     rect2->setPanelModality(QGraphicsItem::SceneModal);
       
  9429     QCOMPARE(scene.focusItem(), (QGraphicsItem *) 0);
       
  9430     QCOMPARE(rect1Spy.counts[QEvent::FocusIn], 0);
       
  9431     QCOMPARE(rect1Spy.counts[QEvent::FocusOut], 0);
       
  9432     QCOMPARE(rect2Spy.counts[QEvent::FocusIn], 0);
       
  9433     QCOMPARE(rect2Spy.counts[QEvent::FocusOut], 0);
       
  9434 
       
  9435     // clicking on rect1 should not set it's focus item
       
  9436     sendMouseClick(&scene, QPointF(-25, -25));
       
  9437     QCOMPARE(rect1->focusItem(), (QGraphicsItem *) 0);
       
  9438     QCOMPARE(rect1Spy.counts[QEvent::FocusIn], 0);
       
  9439     QCOMPARE(rect1Spy.counts[QEvent::FocusOut], 0);
       
  9440     QCOMPARE(rect2Spy.counts[QEvent::FocusIn], 0);
       
  9441     QCOMPARE(rect2Spy.counts[QEvent::FocusOut], 0);
       
  9442 
       
  9443     // clicking on rect2 gives it focus
       
  9444     rect2->setActive(true);
       
  9445     sendMouseClick(&scene, QPointF(75, 75));
       
  9446     QCOMPARE(scene.focusItem(), (QGraphicsItem *) rect2);
       
  9447     QCOMPARE(rect1Spy.counts[QEvent::FocusIn], 0);
       
  9448     QCOMPARE(rect1Spy.counts[QEvent::FocusOut], 0);
       
  9449     QCOMPARE(rect2Spy.counts[QEvent::FocusIn], 1);
       
  9450     QCOMPARE(rect2Spy.counts[QEvent::FocusOut], 0);
       
  9451 
       
  9452     // clicking on rect1 does *not* give it focus
       
  9453     rect1->setActive(true);
       
  9454     sendMouseClick(&scene, QPointF(-25, -25));
       
  9455     QCOMPARE(scene.focusItem(), (QGraphicsItem *) 0);
       
  9456     QCOMPARE(rect1Spy.counts[QEvent::FocusIn], 0);
       
  9457     QCOMPARE(rect1Spy.counts[QEvent::FocusOut], 0);
       
  9458     QCOMPARE(rect2Spy.counts[QEvent::FocusIn], 1);
       
  9459     QCOMPARE(rect2Spy.counts[QEvent::FocusOut], 1);
       
  9460 
       
  9461     // focus doesn't change when leaving modality either
       
  9462     rect2->setPanelModality(QGraphicsItem::NonModal);
       
  9463     QCOMPARE(scene.focusItem(), (QGraphicsItem *) 0);
       
  9464     QCOMPARE(rect1Spy.counts[QEvent::FocusIn], 0);
       
  9465     QCOMPARE(rect1Spy.counts[QEvent::FocusOut], 0);
       
  9466     QCOMPARE(rect2Spy.counts[QEvent::FocusIn], 1);
       
  9467     QCOMPARE(rect2Spy.counts[QEvent::FocusOut], 1);
       
  9468 
       
  9469     // click on rect1, it should get focus now
       
  9470     sendMouseClick(&scene, QPointF(-25, -25));
       
  9471     QCOMPARE(scene.focusItem(), (QGraphicsItem *) rect1);
       
  9472     QCOMPARE(rect1Spy.counts[QEvent::FocusIn], 1);
       
  9473     QCOMPARE(rect1Spy.counts[QEvent::FocusOut], 0);
       
  9474     QCOMPARE(rect2Spy.counts[QEvent::FocusIn], 1);
       
  9475     QCOMPARE(rect2Spy.counts[QEvent::FocusOut], 1);
       
  9476 }
       
  9477 
       
  9478 void tst_QGraphicsItem::modality_keyEvents()
       
  9479 {
       
  9480     QGraphicsScene scene;
       
  9481     QGraphicsRectItem *rect1 = scene.addRect(-50, -50, 100, 100);
       
  9482     rect1->setFlag(QGraphicsItem::ItemIsPanel);
       
  9483     rect1->setFlag(QGraphicsItem::ItemIsFocusable);
       
  9484     rect1->setData(0, "rect1");
       
  9485 
       
  9486     QGraphicsRectItem *rect1child = scene.addRect(-10, -10, 20, 20);
       
  9487     rect1child->setParentItem(rect1);
       
  9488     rect1child->setFlag(QGraphicsItem::ItemIsFocusable);
       
  9489     rect1child->setData(0, "rect1child1");
       
  9490 
       
  9491     QGraphicsRectItem *rect2 = scene.addRect(-50, -50, 100, 100);
       
  9492     rect2->setParentItem(rect1);
       
  9493     rect2->setFlag(QGraphicsItem::ItemIsPanel);
       
  9494     rect2->setFlag(QGraphicsItem::ItemIsFocusable);
       
  9495     rect2->setPos(50, 50);
       
  9496     rect2->setData(0, "rect2");
       
  9497 
       
  9498     QGraphicsRectItem *rect2child = scene.addRect(-10, -10, 20, 20);
       
  9499     rect2child->setParentItem(rect2);
       
  9500     rect2child->setFlag(QGraphicsItem::ItemIsFocusable);
       
  9501     rect2child->setData(0, "rect2child1");
       
  9502 
       
  9503     QEvent windowActivateEvent(QEvent::WindowActivate);
       
  9504     QApplication::sendEvent(&scene, &windowActivateEvent);
       
  9505 
       
  9506     EventSpy2 rect1Spy(&scene, rect1);
       
  9507     EventSpy2 rect1childSpy(&scene, rect1child);
       
  9508     EventSpy2 rect2Spy(&scene, rect2);
       
  9509     EventSpy2 rect2childSpy(&scene, rect2child);
       
  9510 
       
  9511     // activate rect1 and give it rect1child focus
       
  9512     rect1->setActive(true);
       
  9513     rect1child->setFocus();
       
  9514     QCOMPARE(scene.focusItem(), (QGraphicsItem *) rect1child);
       
  9515 
       
  9516     // focus stays on rect1child when rect2 becomes modal
       
  9517     rect2->setPanelModality(QGraphicsItem::SceneModal);
       
  9518     QCOMPARE(scene.focusItem(), (QGraphicsItem *) rect1child);
       
  9519 
       
  9520     // but key events to rect1child should be neither delivered nor propagated
       
  9521     sendKeyClick(&scene, Qt::Key_A);
       
  9522     sendKeyClick(&scene, Qt::Key_S);
       
  9523     sendKeyClick(&scene, Qt::Key_D);
       
  9524     sendKeyClick(&scene, Qt::Key_F);
       
  9525     QCOMPARE(rect1childSpy.counts[QEvent::KeyPress], 0);
       
  9526     QCOMPARE(rect1childSpy.counts[QEvent::KeyRelease], 0);
       
  9527     QCOMPARE(rect1Spy.counts[QEvent::KeyPress], 0);
       
  9528     QCOMPARE(rect1Spy.counts[QEvent::KeyRelease], 0);
       
  9529 
       
  9530     // change to panel modality, rect1child1 keeps focus
       
  9531     rect2->setPanelModality(QGraphicsItem::PanelModal);
       
  9532     QCOMPARE(scene.focusItem(), (QGraphicsItem *) rect1child);
       
  9533 
       
  9534     // still no key events
       
  9535     sendKeyClick(&scene, Qt::Key_J);
       
  9536     sendKeyClick(&scene, Qt::Key_K);
       
  9537     sendKeyClick(&scene, Qt::Key_L);
       
  9538     sendKeyClick(&scene, Qt::Key_Semicolon);
       
  9539     QCOMPARE(rect1childSpy.counts[QEvent::KeyPress], 0);
       
  9540     QCOMPARE(rect1childSpy.counts[QEvent::KeyRelease], 0);
       
  9541     QCOMPARE(rect1Spy.counts[QEvent::KeyPress], 0);
       
  9542     QCOMPARE(rect1Spy.counts[QEvent::KeyRelease], 0);
       
  9543 }
       
  9544 
       
  9545 void tst_QGraphicsItem::itemIsInFront()
       
  9546 {
       
  9547     QGraphicsScene scene;
       
  9548     QGraphicsRectItem *rect1 = new QGraphicsRectItem;
       
  9549     rect1->setData(0, "rect1");
       
  9550     scene.addItem(rect1);
       
  9551 
       
  9552     QGraphicsRectItem *rect1child1 = new QGraphicsRectItem(rect1);
       
  9553     rect1child1->setZValue(1);
       
  9554     rect1child1->setData(0, "rect1child1");
       
  9555 
       
  9556     QGraphicsRectItem *rect1child2 = new QGraphicsRectItem(rect1);
       
  9557     rect1child2->setParentItem(rect1);
       
  9558     rect1child2->setData(0, "rect1child2");
       
  9559 
       
  9560     QGraphicsRectItem *rect1child1_1 = new QGraphicsRectItem(rect1child1);
       
  9561     rect1child1_1->setData(0, "rect1child1_1");
       
  9562 
       
  9563     QGraphicsRectItem *rect1child1_2 = new QGraphicsRectItem(rect1child1);
       
  9564     rect1child1_2->setFlag(QGraphicsItem::ItemStacksBehindParent);
       
  9565     rect1child1_2->setData(0, "rect1child1_2");
       
  9566 
       
  9567     QGraphicsRectItem *rect2 = new QGraphicsRectItem;
       
  9568     rect2->setData(0, "rect2");
       
  9569     scene.addItem(rect2);
       
  9570 
       
  9571     QGraphicsRectItem *rect2child1 = new QGraphicsRectItem(rect2);
       
  9572     rect2child1->setData(0, "rect2child1");
       
  9573 
       
  9574     QCOMPARE(qt_closestItemFirst(rect1, rect1), false);
       
  9575     QCOMPARE(qt_closestItemFirst(rect1, rect2), false);
       
  9576     QCOMPARE(qt_closestItemFirst(rect1child1, rect2child1), false);
       
  9577     QCOMPARE(qt_closestItemFirst(rect1child1, rect1child2), true);
       
  9578     QCOMPARE(qt_closestItemFirst(rect1child1_1, rect1child2), true);
       
  9579     QCOMPARE(qt_closestItemFirst(rect1child1_1, rect1child1), true);
       
  9580     QCOMPARE(qt_closestItemFirst(rect1child1_2, rect1child2), true);
       
  9581     QCOMPARE(qt_closestItemFirst(rect1child1_2, rect1child1), false);
       
  9582     QCOMPARE(qt_closestItemFirst(rect1child1_2, rect1), true);
       
  9583     QCOMPARE(qt_closestItemFirst(rect1child1_2, rect2), false);
       
  9584     QCOMPARE(qt_closestItemFirst(rect1child1_2, rect2child1), false);
       
  9585 }
       
  9586 
       
  9587 QTEST_MAIN(tst_QGraphicsItem)
       
  9588 #include "tst_qgraphicsitem.moc"