tests/auto/qgraphicsview/tst_qgraphicsview.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 <qgraphicsitem.h>
       
    46 #include <qgraphicsscene.h>
       
    47 #include <qgraphicssceneevent.h>
       
    48 #include <qgraphicsview.h>
       
    49 #include <qgraphicswidget.h>
       
    50 #include <qgraphicsproxywidget.h>
       
    51 
       
    52 #include <math.h>
       
    53 
       
    54 #include <QtGui/QLabel>
       
    55 #if !defined(QT_NO_STYLE_MOTIF)
       
    56 #include <QtGui/QMotifStyle>
       
    57 #endif
       
    58 #if !defined(QT_NO_STYLE_WINDOWS)
       
    59 #include <QtGui/QWindowsStyle>
       
    60 #endif
       
    61 #if !defined(QT_NO_STYLE_PLASTIQUE)
       
    62 #include <QtGui/QPlastiqueStyle>
       
    63 #endif
       
    64 #include <QtGui/QPainterPath>
       
    65 #include <QtGui/QRubberBand>
       
    66 #include <QtGui/QScrollBar>
       
    67 #include <QtGui/QStyleOption>
       
    68 #include <QtGui/QBoxLayout>
       
    69 #include <QtGui/QStyle>
       
    70 #include <QtGui/QPushButton>
       
    71 #include <QtGui/QInputContext>
       
    72 #include <private/qgraphicsview_p.h>
       
    73 #include "../../shared/util.h"
       
    74 
       
    75 //TESTED_CLASS=
       
    76 //TESTED_FILES=
       
    77 
       
    78 Q_DECLARE_METATYPE(QList<int>)
       
    79 Q_DECLARE_METATYPE(QList<QRectF>)
       
    80 Q_DECLARE_METATYPE(QMatrix)
       
    81 Q_DECLARE_METATYPE(QPainterPath)
       
    82 Q_DECLARE_METATYPE(QPointF)
       
    83 Q_DECLARE_METATYPE(QPolygonF)
       
    84 Q_DECLARE_METATYPE(QRectF)
       
    85 Q_DECLARE_METATYPE(Qt::ScrollBarPolicy)
       
    86 
       
    87 #ifdef Q_WS_MAC
       
    88 //On mac we get full update. So check that the expected region is contained inside the actual
       
    89 #define COMPARE_REGIONS(ACTUAL, EXPECTED) QVERIFY((EXPECTED).subtracted(ACTUAL).isEmpty())
       
    90 #else
       
    91 #define COMPARE_REGIONS QCOMPARE
       
    92 #endif
       
    93 
       
    94 static void sendMousePress(QWidget *widget, const QPoint &point, Qt::MouseButton button = Qt::LeftButton)
       
    95 {
       
    96     QMouseEvent event(QEvent::MouseButtonPress, point, widget->mapToGlobal(point), button, 0, 0);
       
    97     QApplication::sendEvent(widget, &event);
       
    98 }
       
    99 
       
   100 static void sendMouseMove(QWidget *widget, const QPoint &point, Qt::MouseButton button = Qt::NoButton, Qt::MouseButtons buttons = 0)
       
   101 {
       
   102     QTest::mouseMove(widget, point);
       
   103     QMouseEvent event(QEvent::MouseMove, point, button, buttons, 0);
       
   104     QApplication::sendEvent(widget, &event);
       
   105 }
       
   106 
       
   107 static void sendMouseRelease(QWidget *widget, const QPoint &point, Qt::MouseButton button = Qt::LeftButton)
       
   108 {
       
   109     QMouseEvent event(QEvent::MouseButtonRelease, point, widget->mapToGlobal(point), button, 0, 0);
       
   110     QApplication::sendEvent(widget, &event);
       
   111 }
       
   112 
       
   113 class EventSpy : public QObject
       
   114 {
       
   115     Q_OBJECT
       
   116 public:
       
   117     EventSpy(QObject *watched, QEvent::Type type)
       
   118         : _count(0), spied(type)
       
   119     {
       
   120         watched->installEventFilter(this);
       
   121     }
       
   122 
       
   123     int count() const { return _count; }
       
   124     void reset() { _count = 0; }
       
   125 
       
   126 protected:
       
   127     bool eventFilter(QObject *watched, QEvent *event)
       
   128     {
       
   129         Q_UNUSED(watched);
       
   130         if (event->type() == spied)
       
   131             ++_count;
       
   132         return false;
       
   133     }
       
   134 
       
   135     int _count;
       
   136     QEvent::Type spied;
       
   137 };
       
   138 
       
   139 class tst_QGraphicsView : public QObject
       
   140 {
       
   141     Q_OBJECT
       
   142 
       
   143 private slots:
       
   144     void initTestCase();
       
   145     void construction();
       
   146     void renderHints();
       
   147     void alignment();
       
   148     void interactive();
       
   149     void scene();
       
   150     void setScene();
       
   151     void deleteScene();
       
   152     void sceneRect();
       
   153     void sceneRect_growing();
       
   154     void setSceneRect();
       
   155     void viewport();
       
   156     void dragMode_scrollHand();
       
   157     void dragMode_rubberBand();
       
   158     void rubberBandSelectionMode();
       
   159     void backgroundBrush();
       
   160     void foregroundBrush();
       
   161     void matrix();
       
   162     void matrix_convenience();
       
   163     void matrix_combine();
       
   164     void centerOnPoint();
       
   165     void centerOnItem();
       
   166     void ensureVisibleRect();
       
   167     void fitInView();
       
   168     void itemsAtPoint();
       
   169     void itemsInRect();
       
   170     void itemsInRect_cosmeticAdjust_data();
       
   171     void itemsInRect_cosmeticAdjust();
       
   172     void itemsInPoly();
       
   173     void itemsInPath();
       
   174     void itemAt();
       
   175     void itemAt2();
       
   176     void mapToScene();
       
   177     void mapToScenePoint();
       
   178     void mapToSceneRect_data();
       
   179     void mapToSceneRect();
       
   180     void mapToScenePoly();
       
   181     void mapToScenePath();
       
   182     void mapFromScenePoint();
       
   183     void mapFromSceneRect();
       
   184     void mapFromScenePoly();
       
   185     void mapFromScenePath();
       
   186     void sendEvent();
       
   187     void wheelEvent();
       
   188     void cursor();
       
   189     void cursor2();
       
   190     void transformationAnchor();
       
   191     void resizeAnchor();
       
   192     void viewportUpdateMode();
       
   193     void viewportUpdateMode2();
       
   194     void acceptDrops();
       
   195     void optimizationFlags();
       
   196     void optimizationFlags_dontSavePainterState();
       
   197     void levelOfDetail_data();
       
   198     void levelOfDetail();
       
   199     void scrollBarRanges_data();
       
   200     void scrollBarRanges();
       
   201     void acceptMousePressEvent();
       
   202     void replayMouseMove();
       
   203     void itemsUnderMouse();
       
   204     void embeddedViews();
       
   205     void scrollAfterResize_data();
       
   206     void scrollAfterResize();
       
   207     void moveItemWhileScrolling_data();
       
   208     void moveItemWhileScrolling();
       
   209     void centerOnDirtyItem();
       
   210     void mouseTracking();
       
   211     void mouseTracking2();
       
   212     void render();
       
   213     void exposeRegion();
       
   214     void update_data();
       
   215     void update();
       
   216     void inputMethodSensitivity();
       
   217     void inputContextReset();
       
   218 
       
   219     // task specific tests below me
       
   220     void task172231_untransformableItems();
       
   221     void task180429_mouseReleaseDragMode();
       
   222     void task187791_setSceneCausesUpdate();
       
   223     void task186827_deleteReplayedItem();
       
   224     void task207546_focusCrash();
       
   225     void task210599_unsetDragWhileDragging();
       
   226     void task236394_sendShortcutOverrideEvent();
       
   227     void task239729_noViewUpdate_data();
       
   228     void task239729_noViewUpdate();
       
   229     void task239047_fitInViewSmallViewport();
       
   230     void task245469_itemsAtPointWithClip();
       
   231     void task253415_reconnectUpdateSceneOnSceneChanged();
       
   232     void task255529_transformationAnchorMouseAndViewportMargins();
       
   233     void task259503_scrollingArtifacts();
       
   234     void QTBUG_4151_clipAndIgnore_data();
       
   235     void QTBUG_4151_clipAndIgnore();
       
   236 };
       
   237 
       
   238 void tst_QGraphicsView::initTestCase()
       
   239 {
       
   240 #ifdef Q_OS_WINCE_WM
       
   241     qApp->setAutoMaximizeThreshold(-1);
       
   242 #endif
       
   243 }
       
   244 
       
   245 void tst_QGraphicsView::construction()
       
   246 {
       
   247     QGraphicsView view;
       
   248     QCOMPARE(view.renderHints(), QPainter::TextAntialiasing);
       
   249     QCOMPARE(view.dragMode(), QGraphicsView::NoDrag);
       
   250     QVERIFY(view.isInteractive());
       
   251     QVERIFY(!view.scene());
       
   252     QCOMPARE(view.sceneRect(), QRectF());
       
   253     QVERIFY(view.viewport());
       
   254     QCOMPARE(view.viewport()->metaObject()->className(), "QWidget");
       
   255     QCOMPARE(view.matrix(), QMatrix());
       
   256     QVERIFY(view.items().isEmpty());
       
   257     QVERIFY(view.items(QPoint()).isEmpty());
       
   258     QVERIFY(view.items(QRect()).isEmpty());
       
   259     QVERIFY(view.items(QPolygon()).isEmpty());
       
   260     QVERIFY(view.items(QPainterPath()).isEmpty());
       
   261     QVERIFY(!view.itemAt(QPoint()));
       
   262     QCOMPARE(view.mapToScene(QPoint()), QPointF());
       
   263     QCOMPARE(view.mapToScene(QRect()), QPolygonF());
       
   264     QCOMPARE(view.mapToScene(QPolygon()), QPolygonF());
       
   265     QCOMPARE(view.mapFromScene(QPointF()), QPoint());
       
   266     QPolygon poly;
       
   267     poly << QPoint() << QPoint() << QPoint() << QPoint();
       
   268     QCOMPARE(view.mapFromScene(QRectF()), poly);
       
   269     QCOMPARE(view.mapFromScene(QPolygonF()), QPolygon());
       
   270     QCOMPARE(view.transformationAnchor(), QGraphicsView::AnchorViewCenter);
       
   271     QCOMPARE(view.resizeAnchor(), QGraphicsView::NoAnchor);
       
   272     view.show();
       
   273     QTest::qWaitForWindowShown(&view);
       
   274 }
       
   275 
       
   276 class TestItem : public QGraphicsItem
       
   277 {
       
   278 public:
       
   279     QRectF boundingRect() const
       
   280     { return QRectF(-10, -10, 20, 20); }
       
   281 
       
   282     void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
       
   283     { hints = painter->renderHints(); painter->drawRect(boundingRect()); }
       
   284 
       
   285     bool sceneEvent(QEvent *event)
       
   286     {
       
   287         events << event->type();
       
   288         return QGraphicsItem::sceneEvent(event);
       
   289     }
       
   290 
       
   291     QList<QEvent::Type> events;
       
   292     QPainter::RenderHints hints;
       
   293 };
       
   294 
       
   295 void tst_QGraphicsView::renderHints()
       
   296 {
       
   297     QGraphicsView view;
       
   298     QCOMPARE(view.renderHints(), QPainter::TextAntialiasing);
       
   299     view.setRenderHint(QPainter::TextAntialiasing, false);
       
   300     QCOMPARE(view.renderHints(), 0);
       
   301     view.setRenderHint(QPainter::Antialiasing, false);
       
   302     QCOMPARE(view.renderHints(), 0);
       
   303     view.setRenderHint(QPainter::TextAntialiasing, true);
       
   304     QCOMPARE(view.renderHints(), QPainter::TextAntialiasing);
       
   305     view.setRenderHint(QPainter::Antialiasing);
       
   306     QCOMPARE(view.renderHints(), QPainter::TextAntialiasing | QPainter::Antialiasing);
       
   307     view.setRenderHints(0);
       
   308     QCOMPARE(view.renderHints(), 0);
       
   309 
       
   310     TestItem *item = new TestItem;
       
   311     QGraphicsScene scene;
       
   312     scene.addItem(item);
       
   313 
       
   314     view.setScene(&scene);
       
   315 
       
   316     view.setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing | QPainter::NonCosmeticDefaultPen);
       
   317     QCOMPARE(view.renderHints(), QPainter::TextAntialiasing | QPainter::Antialiasing | QPainter::NonCosmeticDefaultPen);
       
   318 
       
   319     QCOMPARE(item->hints, 0);
       
   320     view.show();
       
   321     QTest::qWaitForWindowShown(&view);
       
   322     view.repaint();
       
   323     QTRY_COMPARE(item->hints, view.renderHints());
       
   324 
       
   325     view.setRenderHints(QPainter::Antialiasing | QPainter::NonCosmeticDefaultPen);
       
   326     QCOMPARE(view.renderHints(), QPainter::Antialiasing | QPainter::NonCosmeticDefaultPen);
       
   327 
       
   328     view.repaint();
       
   329     QTRY_COMPARE(item->hints, view.renderHints());
       
   330 }
       
   331 
       
   332 void tst_QGraphicsView::alignment()
       
   333 {
       
   334     QGraphicsScene scene;
       
   335     scene.addRect(QRectF(-10, -10, 20, 20));
       
   336 
       
   337     QGraphicsView view(&scene);
       
   338     view.show();
       
   339     QTest::qWaitForWindowShown(&view);
       
   340 
       
   341     for (int i = 0; i < 3; ++i) {
       
   342         for (int j = 0; j < 3; ++j) {
       
   343             Qt::Alignment alignment = 0;
       
   344             switch (i) {
       
   345             case 0:
       
   346                 alignment |= Qt::AlignLeft;
       
   347                 break;
       
   348             case 1:
       
   349                 alignment |= Qt::AlignHCenter;
       
   350                 break;
       
   351             case 2:
       
   352             default:
       
   353                 alignment |= Qt::AlignRight;
       
   354                 break;
       
   355             }
       
   356             switch (j) {
       
   357             case 0:
       
   358                 alignment |= Qt::AlignTop;
       
   359                 break;
       
   360             case 1:
       
   361                 alignment |= Qt::AlignVCenter;
       
   362                 break;
       
   363             case 2:
       
   364             default:
       
   365                 alignment |= Qt::AlignBottom;
       
   366                 break;
       
   367             }
       
   368             view.setAlignment(alignment);
       
   369             QCOMPARE(view.alignment(), alignment);
       
   370 
       
   371             for (int k = 0; k < 3; ++k) {
       
   372                 view.resize(100 + k * 25, 100 + k * 25);
       
   373                 QApplication::processEvents();
       
   374             }
       
   375         }
       
   376     }
       
   377 }
       
   378 
       
   379 void tst_QGraphicsView::interactive()
       
   380 {
       
   381     TestItem *item = new TestItem;
       
   382     item->setFlags(QGraphicsItem::ItemIsMovable);
       
   383     QCOMPARE(item->events.size(), 0);
       
   384 
       
   385     QGraphicsScene scene(-200, -200, 400, 400);
       
   386     scene.addItem(item);
       
   387 
       
   388     QGraphicsView view(&scene);
       
   389     view.setFixedSize(300, 300);
       
   390     QCOMPARE(item->events.size(), 0);
       
   391     view.show();
       
   392     QTest::qWaitForWindowShown(&view);
       
   393 
       
   394     QApplication::processEvents();
       
   395     QTRY_COMPARE(item->events.size(), 1); // activate
       
   396 
       
   397     QPoint itemPoint = view.mapFromScene(item->scenePos());
       
   398 
       
   399     QVERIFY(view.itemAt(itemPoint));
       
   400 
       
   401     for (int i = 0; i < 100; ++i) {
       
   402         sendMousePress(view.viewport(), itemPoint);
       
   403         QCOMPARE(item->events.size(), i * 5 + 3);
       
   404         QCOMPARE(item->events.at(item->events.size() - 2), QEvent::GrabMouse);
       
   405         QCOMPARE(item->events.at(item->events.size() - 1), QEvent::GraphicsSceneMousePress);
       
   406         sendMouseRelease(view.viewport(), itemPoint);
       
   407         QCOMPARE(item->events.size(), i * 5 + 5);
       
   408         QCOMPARE(item->events.at(item->events.size() - 2), QEvent::GraphicsSceneMouseRelease);
       
   409         QCOMPARE(item->events.at(item->events.size() - 1), QEvent::UngrabMouse);
       
   410         QContextMenuEvent contextEvent(QContextMenuEvent::Mouse, itemPoint, view.mapToGlobal(itemPoint));
       
   411         QApplication::sendEvent(view.viewport(), &contextEvent);
       
   412         QCOMPARE(item->events.size(), i * 5 + 6);
       
   413         QCOMPARE(item->events.last(), QEvent::GraphicsSceneContextMenu);
       
   414     }
       
   415 
       
   416     view.setInteractive(false);
       
   417 
       
   418     for (int i = 0; i < 100; ++i) {
       
   419         sendMousePress(view.viewport(), itemPoint);
       
   420         QCOMPARE(item->events.size(), 501);
       
   421         QCOMPARE(item->events.last(), QEvent::GraphicsSceneContextMenu);
       
   422         sendMouseRelease(view.viewport(), itemPoint);
       
   423         QCOMPARE(item->events.size(), 501);
       
   424         QCOMPARE(item->events.last(), QEvent::GraphicsSceneContextMenu);
       
   425         QContextMenuEvent contextEvent(QContextMenuEvent::Mouse, itemPoint, view.mapToGlobal(itemPoint));
       
   426         QApplication::sendEvent(view.viewport(), &contextEvent);
       
   427         QCOMPARE(item->events.size(), 501);
       
   428         QCOMPARE(item->events.last(), QEvent::GraphicsSceneContextMenu);
       
   429     }
       
   430 }
       
   431 
       
   432 void tst_QGraphicsView::scene()
       
   433 {
       
   434     QGraphicsView view;
       
   435     QVERIFY(!view.scene());
       
   436     view.setScene(0);
       
   437     QVERIFY(!view.scene());
       
   438 
       
   439     {
       
   440         QGraphicsScene scene;
       
   441         view.setScene(&scene);
       
   442         QCOMPARE(view.scene(), &scene);
       
   443     }
       
   444 
       
   445     QCOMPARE(view.scene(), (QGraphicsScene *)0);
       
   446 }
       
   447 
       
   448 void tst_QGraphicsView::setScene()
       
   449 {
       
   450     QGraphicsScene scene(-1000, -1000, 2000, 2000);
       
   451 
       
   452     QGraphicsView view(&scene);
       
   453     view.show();
       
   454     QTest::qWaitForWindowShown(&view);
       
   455 
       
   456     QCOMPARE(view.sceneRect(), scene.sceneRect());
       
   457 
       
   458     QVERIFY(view.horizontalScrollBar()->isVisible());
       
   459     QVERIFY(view.verticalScrollBar()->isVisible());
       
   460     QVERIFY(!view.horizontalScrollBar()->isHidden());
       
   461     QVERIFY(!view.verticalScrollBar()->isHidden());
       
   462 
       
   463     view.setScene(0);
       
   464 
       
   465     QTest::qWait(25);
       
   466 
       
   467     QVERIFY(!view.horizontalScrollBar()->isVisible());
       
   468     QVERIFY(!view.verticalScrollBar()->isVisible());
       
   469     QVERIFY(!view.horizontalScrollBar()->isHidden());
       
   470     QVERIFY(!view.verticalScrollBar()->isHidden());
       
   471 
       
   472     QCOMPARE(view.sceneRect(), QRectF());
       
   473 }
       
   474 
       
   475 void tst_QGraphicsView::deleteScene()
       
   476 {
       
   477     QGraphicsScene *scene = new QGraphicsScene;
       
   478     QGraphicsView view1(scene);
       
   479     view1.show();
       
   480     QGraphicsView view2(scene);
       
   481     view2.show();
       
   482     QGraphicsView view3(scene);
       
   483     view3.show();
       
   484     delete scene;
       
   485     QCOMPARE(view1.scene(), (QGraphicsScene *)0);
       
   486     QCOMPARE(view2.scene(), (QGraphicsScene *)0);
       
   487     QCOMPARE(view3.scene(), (QGraphicsScene *)0);
       
   488 }
       
   489 
       
   490 void tst_QGraphicsView::sceneRect()
       
   491 {
       
   492     QGraphicsView view;
       
   493     QCOMPARE(view.sceneRect(), QRectF());
       
   494 
       
   495     view.setSceneRect(QRectF(-100, -100, 200, 200));
       
   496     QCOMPARE(view.sceneRect(), QRectF(-100, -100, 200, 200));
       
   497     view.setSceneRect(-100, -100, 200, 200);
       
   498     QCOMPARE(view.sceneRect(), QRectF(-100, -100, 200, 200));
       
   499 
       
   500     view.setSceneRect(QRectF());
       
   501     QCOMPARE(view.sceneRect(), QRectF());
       
   502     QGraphicsScene scene;
       
   503     QGraphicsRectItem *item = scene.addRect(QRectF(-100, -100, 100, 100));
       
   504 
       
   505     view.setScene(&scene);
       
   506 
       
   507     QCOMPARE(view.sceneRect(), QRectF(-100, -100, 100, 100));
       
   508     item->moveBy(-100, -100);
       
   509     QCOMPARE(view.sceneRect(), QRectF(-200, -200, 200, 200));
       
   510     item->moveBy(100, 100);
       
   511     QCOMPARE(view.sceneRect(), QRectF(-200, -200, 200, 200));
       
   512 
       
   513     view.setScene(0);
       
   514     view.setSceneRect(QRectF());
       
   515     QCOMPARE(view.sceneRect(), QRectF());
       
   516 }
       
   517 
       
   518 void tst_QGraphicsView::sceneRect_growing()
       
   519 {
       
   520     QGraphicsScene scene;
       
   521     for (int i = 0; i < 100; ++i)
       
   522         scene.addText(QString("(0, %1)").arg((i - 50) * 20))->setPos(0, (i - 50) * 20);
       
   523 
       
   524     QGraphicsView view(&scene);
       
   525     view.setFixedSize(200, 200);
       
   526     view.show();
       
   527 
       
   528     int size = 200;
       
   529     scene.setSceneRect(-size, -size, size * 2, size * 2);
       
   530     QCOMPARE(view.sceneRect(), scene.sceneRect());
       
   531 
       
   532     QTest::qWait(25);
       
   533 
       
   534     QPointF topLeft = view.mapToScene(0, 0);
       
   535 
       
   536     for (int i = 0; i < 5; ++i) {
       
   537         size *= 2;
       
   538         scene.setSceneRect(-size, -size, size * 2, size * 2);
       
   539 
       
   540         QApplication::processEvents();
       
   541 
       
   542         QCOMPARE(view.sceneRect(), scene.sceneRect());
       
   543         QCOMPARE(view.mapToScene(0, 0), topLeft);
       
   544         view.setSceneRect(-size, -size, size * 2, size * 2);
       
   545         QCOMPARE(view.mapToScene(0, 0), topLeft);
       
   546         view.setSceneRect(QRectF());
       
   547     }
       
   548 }
       
   549 
       
   550 void tst_QGraphicsView::setSceneRect()
       
   551 {
       
   552     QRectF rect1(-100, -100, 200, 200);
       
   553     QRectF rect2(-300, -300, 150, 150);
       
   554 
       
   555     QGraphicsScene scene;
       
   556     QGraphicsView view(&scene);
       
   557 
       
   558     scene.setSceneRect(rect1);
       
   559     QCOMPARE(scene.sceneRect(), rect1);
       
   560     QCOMPARE(view.sceneRect(), rect1);
       
   561 
       
   562     scene.setSceneRect(rect2);
       
   563     QCOMPARE(scene.sceneRect(), rect2);
       
   564     QCOMPARE(view.sceneRect(), rect2);
       
   565 
       
   566     view.setSceneRect(rect1);
       
   567     QCOMPARE(scene.sceneRect(), rect2);
       
   568     QCOMPARE(view.sceneRect(), rect1);
       
   569 
       
   570     view.setSceneRect(rect2);
       
   571     QCOMPARE(scene.sceneRect(), rect2);
       
   572     QCOMPARE(view.sceneRect(), rect2);
       
   573 
       
   574     scene.setSceneRect(rect1);
       
   575     QCOMPARE(scene.sceneRect(), rect1);
       
   576     QCOMPARE(view.sceneRect(), rect2);
       
   577 
       
   578     // extreme transformations will max out the scrollbars' ranges.
       
   579     view.setSceneRect(-2000000, -2000000, 4000000, 4000000);
       
   580     view.scale(9000, 9000);
       
   581     QCOMPARE(view.horizontalScrollBar()->minimum(), INT_MIN);
       
   582     QCOMPARE(view.horizontalScrollBar()->maximum(), INT_MAX);
       
   583     QCOMPARE(view.verticalScrollBar()->minimum(), INT_MIN);
       
   584     QCOMPARE(view.verticalScrollBar()->maximum(), INT_MAX);
       
   585 }
       
   586 
       
   587 void tst_QGraphicsView::viewport()
       
   588 {
       
   589     QGraphicsScene scene;
       
   590     scene.addText("GraphicsView");
       
   591 
       
   592     QGraphicsView view(&scene);
       
   593     QVERIFY(view.viewport() != 0);
       
   594 
       
   595     view.show();
       
   596     QTest::qWait(25);
       
   597 
       
   598     QPointer<QWidget> widget = new QWidget;
       
   599     view.setViewport(widget);
       
   600     QCOMPARE(view.viewport(), (QWidget *)widget);
       
   601 
       
   602     view.show();
       
   603     QTest::qWait(25);
       
   604 
       
   605     view.setViewport(0);
       
   606     QVERIFY(widget.isNull());
       
   607     QVERIFY(view.viewport() != 0);
       
   608     QVERIFY(view.viewport() != widget);
       
   609 
       
   610     view.show();
       
   611     QTest::qWait(25);
       
   612 }
       
   613 
       
   614 void tst_QGraphicsView::dragMode_scrollHand()
       
   615 {
       
   616     for (int j = 0; j < 2; ++j) {
       
   617         QGraphicsView view;
       
   618         QCOMPARE(view.dragMode(), QGraphicsView::NoDrag);
       
   619 
       
   620         view.setSceneRect(-1000, -1000, 2000, 2000);
       
   621         view.setFixedSize(100, 100);
       
   622         view.show();
       
   623 
       
   624         QTest::qWaitForWindowShown(&view);
       
   625         QApplication::processEvents();
       
   626 
       
   627         view.setInteractive(j ? false : true);
       
   628 
       
   629         QGraphicsScene scene;
       
   630         scene.addRect(QRectF(-100, -100, 5, 5));
       
   631         scene.addRect(QRectF(95, -100, 5, 5));
       
   632         scene.addRect(QRectF(95, 95, 5, 5));
       
   633         QGraphicsItem *item = scene.addRect(QRectF(-100, 95, 5, 5));
       
   634         item->setFlag(QGraphicsItem::ItemIsSelectable);
       
   635         item->setSelected(true);
       
   636         QVERIFY(item->isSelected());
       
   637         QVERIFY(!view.scene());
       
   638 
       
   639         view.setDragMode(QGraphicsView::ScrollHandDrag);
       
   640 
       
   641         for (int i = 0; i < 2; ++i) {
       
   642             // ScrollHandDrag
       
   643 #ifndef QT_NO_CURSOR
       
   644             Qt::CursorShape cursorShape = view.viewport()->cursor().shape();
       
   645 #endif
       
   646             int horizontalScrollBarValue = view.horizontalScrollBar()->value();
       
   647             int verticalScrollBarValue = view.verticalScrollBar()->value();
       
   648             {
       
   649                 // Press
       
   650                 QMouseEvent event(QEvent::MouseButtonPress,
       
   651                                   view.viewport()->rect().center(),
       
   652                                   Qt::LeftButton, Qt::LeftButton, 0);
       
   653                 event.setAccepted(true);
       
   654                 QApplication::sendEvent(view.viewport(), &event);
       
   655                 QVERIFY(event.isAccepted());
       
   656             }
       
   657             QApplication::processEvents();
       
   658 
       
   659             QTRY_VERIFY(item->isSelected());
       
   660 
       
   661             for (int k = 0; k < 4; ++k) {
       
   662 #ifndef QT_NO_CURSOR
       
   663                 QCOMPARE(view.viewport()->cursor().shape(), Qt::ClosedHandCursor);
       
   664 #endif
       
   665                 {
       
   666                     // Move
       
   667                     QMouseEvent event(QEvent::MouseMove,
       
   668                                       view.viewport()->rect().center() + QPoint(10, 0),
       
   669                                       Qt::LeftButton, Qt::LeftButton, 0);
       
   670                     event.setAccepted(true);
       
   671                     QApplication::sendEvent(view.viewport(), &event);
       
   672                     QVERIFY(event.isAccepted());
       
   673                 }
       
   674                 QVERIFY(item->isSelected());
       
   675                 QCOMPARE(view.horizontalScrollBar()->value(), horizontalScrollBarValue - 10);
       
   676                 QCOMPARE(view.verticalScrollBar()->value(), verticalScrollBarValue);
       
   677                 {
       
   678                     // Move
       
   679                     QMouseEvent event(QEvent::MouseMove,
       
   680                                       view.viewport()->rect().center() + QPoint(10, 10),
       
   681                                       Qt::LeftButton, Qt::LeftButton, 0);
       
   682                     event.setAccepted(true);
       
   683                     QApplication::sendEvent(view.viewport(), &event);
       
   684                     QVERIFY(event.isAccepted());
       
   685                 }
       
   686                 QVERIFY(item->isSelected());
       
   687                 QCOMPARE(view.horizontalScrollBar()->value(), horizontalScrollBarValue - 10);
       
   688                 QCOMPARE(view.verticalScrollBar()->value(), verticalScrollBarValue - 10);
       
   689             }
       
   690 
       
   691             {
       
   692                 // Release
       
   693                 QMouseEvent event(QEvent::MouseButtonRelease,
       
   694                                   view.viewport()->rect().center() + QPoint(10, 10),
       
   695                                   Qt::LeftButton, Qt::LeftButton, 0);
       
   696                 event.setAccepted(true);
       
   697                 QApplication::sendEvent(view.viewport(), &event);
       
   698                 QVERIFY(event.isAccepted());
       
   699             }
       
   700             QApplication::processEvents();
       
   701 
       
   702             QTRY_VERIFY(item->isSelected());
       
   703             QCOMPARE(view.horizontalScrollBar()->value(), horizontalScrollBarValue - 10);
       
   704             QCOMPARE(view.verticalScrollBar()->value(), verticalScrollBarValue - 10);
       
   705 #ifndef QT_NO_CURSOR
       
   706             QCOMPARE(view.viewport()->cursor().shape(), cursorShape);
       
   707 #endif
       
   708 
       
   709             // Check that items are not unselected because of a scroll hand drag.
       
   710             QVERIFY(item->isSelected());
       
   711 
       
   712             // Check that a click will still unselect the item.
       
   713             {
       
   714                 // Press
       
   715                 QMouseEvent event(QEvent::MouseButtonPress,
       
   716                                   view.viewport()->rect().center() + QPoint(10, 10),
       
   717                                   Qt::LeftButton, Qt::LeftButton, 0);
       
   718                 QApplication::sendEvent(view.viewport(), &event);
       
   719             }
       
   720             {
       
   721                 // Release
       
   722                 QMouseEvent event(QEvent::MouseButtonRelease,
       
   723                                   view.viewport()->rect().center() + QPoint(10, 10),
       
   724                                   Qt::LeftButton, Qt::LeftButton, 0);
       
   725                 QApplication::sendEvent(view.viewport(), &event);
       
   726             }
       
   727 
       
   728             if (view.isInteractive()) {
       
   729                 if (view.scene()) {
       
   730                     QVERIFY(!item->isSelected());
       
   731                     item->setSelected(true);
       
   732                 } else {
       
   733                     QVERIFY(item->isSelected());
       
   734                 }
       
   735             } else {
       
   736                 QVERIFY(item->isSelected());
       
   737             }
       
   738 
       
   739             view.setScene(&scene);
       
   740         }
       
   741     }
       
   742 }
       
   743 
       
   744 void tst_QGraphicsView::dragMode_rubberBand()
       
   745 {
       
   746     QGraphicsView view;
       
   747     QCOMPARE(view.dragMode(), QGraphicsView::NoDrag);
       
   748 
       
   749     view.setSceneRect(-1000, -1000, 2000, 2000);
       
   750     view.show();
       
   751 
       
   752     QGraphicsScene scene;
       
   753     scene.addRect(QRectF(-100, -100, 25, 25))->setFlag(QGraphicsItem::ItemIsSelectable);
       
   754     scene.addRect(QRectF(75, -100, 25, 25))->setFlag(QGraphicsItem::ItemIsSelectable);
       
   755     scene.addRect(QRectF(75, 75, 25, 25))->setFlag(QGraphicsItem::ItemIsSelectable);
       
   756     scene.addRect(QRectF(-100, 75, 25, 25))->setFlag(QGraphicsItem::ItemIsSelectable);
       
   757 
       
   758     view.setDragMode(QGraphicsView::RubberBandDrag);
       
   759 
       
   760     QTest::qWaitForWindowShown(&view);
       
   761     QApplication::processEvents();
       
   762 
       
   763     for (int i = 0; i < 2; ++i) {
       
   764         // RubberBandDrag
       
   765 #ifndef QT_NO_CURSOR
       
   766         Qt::CursorShape cursorShape = view.viewport()->cursor().shape();
       
   767 #endif
       
   768         int horizontalScrollBarValue = view.horizontalScrollBar()->value();
       
   769         int verticalScrollBarValue = view.verticalScrollBar()->value();
       
   770         {
       
   771             // Press
       
   772             QMouseEvent event(QEvent::MouseButtonPress,
       
   773                               view.viewport()->rect().center(),
       
   774                               Qt::LeftButton, Qt::LeftButton, 0);
       
   775             event.setAccepted(true);
       
   776             QApplication::sendEvent(view.viewport(), &event);
       
   777             QVERIFY(event.isAccepted());
       
   778         }
       
   779 #ifndef QT_NO_CURSOR
       
   780         QCOMPARE(view.viewport()->cursor().shape(), cursorShape);
       
   781 #endif
       
   782 
       
   783         QApplication::processEvents();
       
   784 
       
   785         {
       
   786             // Move
       
   787             QMouseEvent event(QEvent::MouseMove,
       
   788                               view.viewport()->rect().center() + QPoint(100, 0),
       
   789                               Qt::LeftButton, Qt::LeftButton, 0);
       
   790             event.setAccepted(true);
       
   791             QApplication::sendEvent(view.viewport(), &event);
       
   792             QVERIFY(event.isAccepted());
       
   793         }
       
   794         QCOMPARE(view.horizontalScrollBar()->value(), horizontalScrollBarValue);
       
   795         QCOMPARE(view.verticalScrollBar()->value(), verticalScrollBarValue);
       
   796 
       
   797         // We don't use QRubberBand as of 4.3; the band is drawn internally.
       
   798         QVERIFY(!qFindChild<QRubberBand *>(&view));
       
   799 
       
   800         QTest::qWait(25);
       
   801 
       
   802         {
       
   803             // Move
       
   804             QMouseEvent event(QEvent::MouseMove,
       
   805                               view.viewport()->rect().center() + QPoint(100, 100),
       
   806                               Qt::LeftButton, Qt::LeftButton, 0);
       
   807             event.setAccepted(true);
       
   808             QApplication::sendEvent(view.viewport(), &event);
       
   809             QVERIFY(event.isAccepted());
       
   810         }
       
   811         QCOMPARE(view.horizontalScrollBar()->value(), horizontalScrollBarValue);
       
   812         QCOMPARE(view.verticalScrollBar()->value(), verticalScrollBarValue);
       
   813 
       
   814         QTest::qWait(25);
       
   815 
       
   816         {
       
   817             // Release
       
   818             QMouseEvent event(QEvent::MouseButtonRelease,
       
   819                               view.viewport()->rect().center() + QPoint(100, 100),
       
   820                               Qt::LeftButton, Qt::LeftButton, 0);
       
   821             event.setAccepted(true);
       
   822             QApplication::sendEvent(view.viewport(), &event);
       
   823             QVERIFY(event.isAccepted());
       
   824         }
       
   825         QCOMPARE(view.horizontalScrollBar()->value(), horizontalScrollBarValue);
       
   826         QCOMPARE(view.verticalScrollBar()->value(), verticalScrollBarValue);
       
   827 #ifndef QT_NO_CURSOR
       
   828         QCOMPARE(view.viewport()->cursor().shape(), cursorShape);
       
   829 #endif
       
   830 
       
   831         QTest::qWait(25);
       
   832 
       
   833         if (view.scene())
       
   834             QCOMPARE(scene.selectedItems().size(), 1);
       
   835 
       
   836         view.setScene(&scene);
       
   837         view.centerOn(0, 0);
       
   838     }
       
   839 }
       
   840 
       
   841 void tst_QGraphicsView::rubberBandSelectionMode()
       
   842 {
       
   843     QGraphicsScene scene;
       
   844     QGraphicsRectItem *rect = scene.addRect(QRectF(10, 10, 80, 80));
       
   845     rect->setFlag(QGraphicsItem::ItemIsSelectable);
       
   846 
       
   847     QGraphicsView view(&scene);
       
   848     QCOMPARE(view.rubberBandSelectionMode(), Qt::IntersectsItemShape);
       
   849     view.setDragMode(QGraphicsView::RubberBandDrag);
       
   850     view.resize(120, 120);
       
   851     view.show();
       
   852 
       
   853     // Disable mouse tracking to prevent the window system from sending mouse
       
   854     // move events to the viewport while we are synthesizing events. If
       
   855     // QGraphicsView gets a mouse move event with no buttons down, it'll
       
   856     // terminate the rubber band.
       
   857     view.viewport()->setMouseTracking(false);
       
   858 
       
   859     QCOMPARE(scene.selectedItems(), QList<QGraphicsItem *>());
       
   860     sendMousePress(view.viewport(), QPoint(), Qt::LeftButton);
       
   861     sendMouseMove(view.viewport(), view.viewport()->rect().center(),
       
   862                   Qt::LeftButton, Qt::LeftButton);
       
   863     QCOMPARE(scene.selectedItems(), QList<QGraphicsItem *>() << rect);
       
   864     sendMouseRelease(view.viewport(), QPoint(), Qt::LeftButton);
       
   865 
       
   866     view.setRubberBandSelectionMode(Qt::ContainsItemShape);
       
   867     QCOMPARE(view.rubberBandSelectionMode(), Qt::ContainsItemShape);
       
   868     sendMousePress(view.viewport(), QPoint(), Qt::LeftButton);
       
   869     QCOMPARE(scene.selectedItems(), QList<QGraphicsItem *>());
       
   870     sendMouseMove(view.viewport(), view.viewport()->rect().center(),
       
   871                   Qt::LeftButton, Qt::LeftButton);
       
   872     QCOMPARE(scene.selectedItems(), QList<QGraphicsItem *>());
       
   873     sendMouseMove(view.viewport(), view.viewport()->rect().bottomRight(),
       
   874                   Qt::LeftButton, Qt::LeftButton);
       
   875     QCOMPARE(scene.selectedItems(), QList<QGraphicsItem *>() << rect);
       
   876 }
       
   877 
       
   878 void tst_QGraphicsView::backgroundBrush()
       
   879 {
       
   880     QGraphicsScene scene;
       
   881     QGraphicsView view(&scene);
       
   882     scene.setBackgroundBrush(Qt::blue);
       
   883     QCOMPARE(scene.backgroundBrush(), QBrush(Qt::blue));
       
   884 
       
   885     view.show();
       
   886     QTest::qWait(25);
       
   887 
       
   888     scene.setBackgroundBrush(QBrush());
       
   889     QCOMPARE(scene.backgroundBrush(), QBrush());
       
   890     QTest::qWait(25);
       
   891 
       
   892     QRadialGradient gradient(0, 0, 10);
       
   893     gradient.setSpread(QGradient::RepeatSpread);
       
   894     scene.setBackgroundBrush(gradient);
       
   895 
       
   896     QCOMPARE(scene.backgroundBrush(), QBrush(gradient));
       
   897     QTest::qWait(25);
       
   898 }
       
   899 
       
   900 void tst_QGraphicsView::foregroundBrush()
       
   901 {
       
   902     QGraphicsScene scene;
       
   903     QGraphicsView view(&scene);
       
   904     scene.setForegroundBrush(Qt::blue);
       
   905     QCOMPARE(scene.foregroundBrush(), QBrush(Qt::blue));
       
   906 
       
   907     view.show();
       
   908     QTest::qWait(25);
       
   909 
       
   910     scene.setForegroundBrush(QBrush());
       
   911     QCOMPARE(scene.foregroundBrush(), QBrush());
       
   912     QTest::qWait(25);
       
   913 
       
   914     QRadialGradient gradient(0, 0, 10);
       
   915     gradient.setSpread(QGradient::RepeatSpread);
       
   916     scene.setForegroundBrush(gradient);
       
   917 
       
   918     QCOMPARE(scene.foregroundBrush(), QBrush(gradient));
       
   919     QTest::qWait(25);
       
   920 
       
   921     for (int i = 0; i < 50; ++i) {
       
   922         QRadialGradient gradient(view.rect().center() + QPoint(int(sin(i / 2.0) * 10), int(cos(i / 2.0) * 10)), 10);
       
   923         gradient.setColorAt(0, Qt::transparent);
       
   924         gradient.setColorAt(0.5, Qt::black);
       
   925         gradient.setColorAt(1, Qt::transparent);
       
   926         gradient.setSpread(QGradient::RepeatSpread);
       
   927         scene.setForegroundBrush(gradient);
       
   928 
       
   929         QRadialGradient gradient2(view.rect().center() + QPoint(int(sin(i / 1.7) * 10), int(cos(i / 1.7) * 10)), 10);
       
   930         gradient2.setColorAt(0, Qt::transparent);
       
   931         gradient2.setColorAt(0.5, Qt::black);
       
   932         gradient2.setColorAt(1, Qt::transparent);
       
   933         gradient2.setSpread(QGradient::RepeatSpread);
       
   934         scene.setBackgroundBrush(gradient2);
       
   935 
       
   936         QRadialGradient gradient3(view.rect().center() + QPoint(int(sin(i / 1.85) * 10), int(cos(i / 1.85) * 10)), 10);
       
   937         gradient3.setColorAt(0, Qt::transparent);
       
   938         gradient3.setColorAt(0.5, Qt::black);
       
   939         gradient3.setColorAt(1, Qt::transparent);
       
   940         gradient3.setSpread(QGradient::RepeatSpread);
       
   941         scene.setBackgroundBrush(gradient3);
       
   942 
       
   943         QApplication::processEvents();
       
   944     }
       
   945 
       
   946     view.setSceneRect(-1000, -1000, 2000, 2000);
       
   947     for (int i = -500; i < 500; i += 10) {
       
   948         view.centerOn(i, 0);
       
   949         QApplication::processEvents();
       
   950         QApplication::processEvents();
       
   951     }
       
   952     for (int i = -500; i < 500; i += 10) {
       
   953         view.centerOn(0, i);
       
   954         QApplication::processEvents();
       
   955         QApplication::processEvents();
       
   956     }
       
   957 }
       
   958 
       
   959 void tst_QGraphicsView::matrix()
       
   960 {
       
   961     {
       
   962         QGraphicsScene scene;
       
   963         QGraphicsView view(&scene);
       
   964         view.show();
       
   965 
       
   966         // Show rendering of background with no scene
       
   967         for (int i = 0; i < 50; ++i) {
       
   968             view.rotate(5);
       
   969             QRadialGradient gradient(view.rect().center() + QPoint(int(sin(i / 2.0) * 10), int(cos(i / 2.0) * 10)), 10);
       
   970             gradient.setColorAt(0, Qt::transparent);
       
   971             gradient.setColorAt(0.5, Qt::black);
       
   972             gradient.setColorAt(1, Qt::transparent);
       
   973             gradient.setSpread(QGradient::RepeatSpread);
       
   974             scene.setForegroundBrush(gradient);
       
   975             QRadialGradient gradient2(view.rect().center() + QPoint(int(sin(i / 1.7) * 10), int(cos(i / 1.7) * 10)), 10);
       
   976             gradient2.setColorAt(0, Qt::transparent);
       
   977             gradient2.setColorAt(0.5, Qt::black);
       
   978             gradient2.setColorAt(1, Qt::transparent);
       
   979             gradient2.setSpread(QGradient::RepeatSpread);
       
   980             scene.setBackgroundBrush(gradient2);
       
   981             QApplication::processEvents();
       
   982             QApplication::processEvents();
       
   983         }
       
   984     }
       
   985 
       
   986     // Test transformation extremes, see if they cause crashes
       
   987     {
       
   988         QGraphicsScene scene;
       
   989         scene.addText("GraphicsView rotated clockwise");
       
   990 
       
   991         QGraphicsView view(&scene);
       
   992         view.show();
       
   993         for (int i = 0; i < 160; ++i) {
       
   994             view.rotate(18);
       
   995             QApplication::processEvents();
       
   996             QApplication::processEvents();
       
   997         }
       
   998         /*
       
   999           // These cause a crash
       
  1000         for (int i = 0; i < 40; ++i) {
       
  1001             view.shear(1.2, 1.2);
       
  1002             QTest::qWait(20);
       
  1003         }
       
  1004         for (int i = 0; i < 40; ++i) {
       
  1005             view.shear(-1.2, -1.2);
       
  1006             QTest::qWait(20);
       
  1007         }
       
  1008         */
       
  1009         for (int i = 0; i < 20; ++i) {
       
  1010             view.scale(1.2, 1.2);
       
  1011             QApplication::processEvents();
       
  1012             QApplication::processEvents();
       
  1013         }
       
  1014         for (int i = 0; i < 20; ++i) {
       
  1015             view.scale(0.6, 0.6);
       
  1016             QApplication::processEvents();
       
  1017             QApplication::processEvents();
       
  1018         }
       
  1019     }
       
  1020 }
       
  1021 
       
  1022 void tst_QGraphicsView::matrix_convenience()
       
  1023 {
       
  1024     QGraphicsView view;
       
  1025     QCOMPARE(view.matrix(), QMatrix());
       
  1026 
       
  1027     // Check the convenience functions
       
  1028     view.rotate(90);
       
  1029     QCOMPARE(view.matrix(), QMatrix().rotate(90));
       
  1030     view.scale(2, 2);
       
  1031     QCOMPARE(view.matrix(), QMatrix().scale(2, 2) * QMatrix().rotate(90));
       
  1032     view.shear(1.2, 1.2);
       
  1033     QCOMPARE(view.matrix(), QMatrix().shear(1.2, 1.2) * QMatrix().scale(2, 2) * QMatrix().rotate(90));
       
  1034     view.translate(1, 1);
       
  1035     QCOMPARE(view.matrix(), QMatrix().translate(1, 1) * QMatrix().shear(1.2, 1.2) * QMatrix().scale(2, 2) * QMatrix().rotate(90));
       
  1036 }
       
  1037 
       
  1038 void tst_QGraphicsView::matrix_combine()
       
  1039 {
       
  1040     // Check matrix combining
       
  1041     QGraphicsView view;
       
  1042     QCOMPARE(view.matrix(), QMatrix());
       
  1043     view.setMatrix(QMatrix().rotate(90), true);
       
  1044     view.setMatrix(QMatrix().rotate(90), true);
       
  1045     view.setMatrix(QMatrix().rotate(90), true);
       
  1046     view.setMatrix(QMatrix().rotate(90), true);
       
  1047     QCOMPARE(view.matrix(), QMatrix());
       
  1048 
       
  1049     view.resetMatrix();
       
  1050     QCOMPARE(view.matrix(), QMatrix());
       
  1051     view.setMatrix(QMatrix().rotate(90), false);
       
  1052     view.setMatrix(QMatrix().rotate(90), false);
       
  1053     view.setMatrix(QMatrix().rotate(90), false);
       
  1054     view.setMatrix(QMatrix().rotate(90), false);
       
  1055     QCOMPARE(view.matrix(), QMatrix().rotate(90));
       
  1056 }
       
  1057 
       
  1058 void tst_QGraphicsView::centerOnPoint()
       
  1059 {
       
  1060     QGraphicsScene scene;
       
  1061     scene.addEllipse(QRectF(-100, -100, 50, 50));
       
  1062     scene.addEllipse(QRectF(50, -100, 50, 50));
       
  1063     scene.addEllipse(QRectF(-100, 50, 50, 50));
       
  1064     scene.addEllipse(QRectF(50, 50, 50, 50));
       
  1065 
       
  1066     QGraphicsView view(&scene);
       
  1067     view.setSceneRect(-400, -400, 800, 800);
       
  1068     view.setFixedSize(100, 100);
       
  1069     view.show();
       
  1070 
       
  1071     int tolerance = 5;
       
  1072 
       
  1073     for (int i = 0; i < 3; ++i) {
       
  1074         for (int y = -100; y < 100; y += 23) {
       
  1075             for (int x = -100; x < 100; x += 23) {
       
  1076                 view.centerOn(x, y);
       
  1077                 QPoint viewCenter = view.mapToScene(view.viewport()->rect().center()).toPoint();
       
  1078 
       
  1079                 // Fuzzy compare
       
  1080                 if (viewCenter.x() < x - tolerance || viewCenter.x() > x + tolerance
       
  1081                     || viewCenter.y() < y - tolerance || viewCenter.y() > y + tolerance) {
       
  1082                     QString error = QString("Compared values are not the same\n\tActual: (%1, %2)\n\tExpected: (%3, %4)")
       
  1083                                     .arg(viewCenter.x()).arg(viewCenter.y()).arg(x).arg(y);
       
  1084                     QFAIL(qPrintable(error));
       
  1085                 }
       
  1086 
       
  1087                 QApplication::processEvents();
       
  1088             }
       
  1089         }
       
  1090 
       
  1091         view.rotate(13);
       
  1092         view.scale(1.5, 1.5);
       
  1093         view.shear(1.25, 1.25);
       
  1094     }
       
  1095 }
       
  1096 
       
  1097 void tst_QGraphicsView::centerOnItem()
       
  1098 {
       
  1099     QGraphicsScene scene;
       
  1100     QGraphicsItem *items[4];
       
  1101     items[0] = scene.addEllipse(QRectF(-25, -25, 50, 50));
       
  1102     items[1] = scene.addEllipse(QRectF(-25, -25, 50, 50));
       
  1103     items[2] = scene.addEllipse(QRectF(-25, -25, 50, 50));
       
  1104     items[3] = scene.addEllipse(QRectF(-25, -25, 50, 50));
       
  1105     items[0]->setPos(-100, -100);
       
  1106     items[1]->setPos(100, -100);
       
  1107     items[2]->setPos(-100, 100);
       
  1108     items[3]->setPos(100, 100);
       
  1109 
       
  1110     QGraphicsView view(&scene);
       
  1111     view.setSceneRect(-1000, -1000, 2000, 2000);
       
  1112     view.show();
       
  1113     QTest::qWaitForWindowShown(&view);
       
  1114     int tolerance = 7;
       
  1115 
       
  1116     for (int x = 0; x < 3; ++x) {
       
  1117         for (int i = 0; i < 4; ++i) {
       
  1118             QApplication::processEvents();
       
  1119             view.centerOn(items[i]);
       
  1120 
       
  1121             QPoint viewCenter = view.mapToScene(view.viewport()->rect().center()).toPoint();
       
  1122             qreal x = items[i]->pos().x();
       
  1123             qreal y = items[i]->pos().y();
       
  1124 
       
  1125             // Fuzzy compare
       
  1126             if (viewCenter.x() < x - tolerance || viewCenter.x() > x + tolerance
       
  1127                 || viewCenter.y() < y - tolerance || viewCenter.y() > y + tolerance) {
       
  1128                 QString error = QString("Compared values are not the same\n\tActual: (%1, %2)\n\tExpected: (%3, %4)")
       
  1129                                 .arg(viewCenter.x()).arg(viewCenter.y()).arg(x).arg(y);
       
  1130                 QFAIL(qPrintable(error));
       
  1131             }
       
  1132 
       
  1133             QApplication::processEvents();
       
  1134         }
       
  1135 
       
  1136         view.rotate(13);
       
  1137         view.scale(1.5, 1.5);
       
  1138         view.shear(1.25, 1.25);
       
  1139     }
       
  1140 }
       
  1141 
       
  1142 void tst_QGraphicsView::ensureVisibleRect()
       
  1143 {
       
  1144     QGraphicsScene scene;
       
  1145     QGraphicsItem *items[4];
       
  1146     items[0] = scene.addEllipse(QRectF(-25, -25, 50, 50), QPen(Qt::black), QBrush(Qt::green));
       
  1147     items[1] = scene.addEllipse(QRectF(-25, -25, 50, 50), QPen(Qt::black), QBrush(Qt::red));
       
  1148     items[2] = scene.addEllipse(QRectF(-25, -25, 50, 50), QPen(Qt::black), QBrush(Qt::blue));
       
  1149     items[3] = scene.addEllipse(QRectF(-25, -25, 50, 50), QPen(Qt::black), QBrush(Qt::yellow));
       
  1150     scene.addLine(QLineF(0, -100, 0, 100), QPen(Qt::blue, 2));
       
  1151     scene.addLine(QLineF(-100, 0, 100, 0), QPen(Qt::blue, 2));
       
  1152     items[0]->setPos(-100, -100);
       
  1153     items[1]->setPos(100, -100);
       
  1154     items[2]->setPos(-100, 100);
       
  1155     items[3]->setPos(100, 100);
       
  1156 
       
  1157     QGraphicsItem *icon = scene.addEllipse(QRectF(-10, -10, 20, 20), QPen(Qt::black), QBrush(Qt::gray));
       
  1158 
       
  1159     QGraphicsView view(&scene);
       
  1160     view.setSceneRect(-500, -500, 1000, 1000);
       
  1161     view.setFixedSize(250, 250);
       
  1162     view.show();
       
  1163     QTest::qWaitForWindowShown(&view);
       
  1164 
       
  1165     for (int y = -100; y < 100; y += 25) {
       
  1166         for (int x = -100; x < 100; x += 13) {
       
  1167 
       
  1168             icon->setPos(x, y);
       
  1169 
       
  1170             switch (x & 3) {
       
  1171             case 0:
       
  1172                 view.centerOn(-500, -500);
       
  1173                 break;
       
  1174             case 1:
       
  1175                 view.centerOn(500, -500);
       
  1176                 break;
       
  1177             case 2:
       
  1178                 view.centerOn(-500, 500);
       
  1179                 break;
       
  1180             case 3:
       
  1181             default:
       
  1182                 view.centerOn(500, 500);
       
  1183                 break;
       
  1184             }
       
  1185 
       
  1186             QVERIFY(!view.viewport()->rect().contains(view.mapFromScene(x, y)));
       
  1187 
       
  1188             for (int margin = 10; margin < 60; margin += 15) {
       
  1189                 view.ensureVisible(x, y, 0, 0, margin, margin);
       
  1190 
       
  1191                 QRect viewRect = view.viewport()->rect();
       
  1192                 QPoint viewPoint = view.mapFromScene(x, y);
       
  1193 
       
  1194                 QVERIFY(viewRect.contains(viewPoint));
       
  1195                 QVERIFY(qAbs(viewPoint.x() - viewRect.left()) >= margin -1);
       
  1196                 QVERIFY(qAbs(viewPoint.x() - viewRect.right()) >= margin -1);
       
  1197                 QVERIFY(qAbs(viewPoint.y() - viewRect.top()) >= margin -1);
       
  1198                 QVERIFY(qAbs(viewPoint.y() - viewRect.bottom()) >= margin -1);
       
  1199 
       
  1200                 QApplication::processEvents();
       
  1201             }
       
  1202         }
       
  1203         view.rotate(5);
       
  1204         view.scale(1.05, 1.05);
       
  1205         view.translate(30, -30);
       
  1206     }
       
  1207 }
       
  1208 
       
  1209 void tst_QGraphicsView::fitInView()
       
  1210 {
       
  1211     QGraphicsScene scene;
       
  1212     QGraphicsItem *items[4];
       
  1213     items[0] = scene.addEllipse(QRectF(-25, -25, 100, 20), QPen(Qt::black), QBrush(Qt::green));
       
  1214     items[1] = scene.addEllipse(QRectF(-25, -25, 20, 100), QPen(Qt::black), QBrush(Qt::red));
       
  1215     items[2] = scene.addEllipse(QRectF(-25, -25, 50, 50), QPen(Qt::black), QBrush(Qt::blue));
       
  1216     items[3] = scene.addEllipse(QRectF(-25, -25, 50, 50), QPen(Qt::black), QBrush(Qt::yellow));
       
  1217     scene.addLine(QLineF(0, -100, 0, 100), QPen(Qt::blue, 2));
       
  1218     scene.addLine(QLineF(-100, 0, 100, 0), QPen(Qt::blue, 2));
       
  1219     items[0]->setPos(-100, -100);
       
  1220     items[1]->setPos(100, -100);
       
  1221     items[2]->setPos(-100, 100);
       
  1222     items[3]->setPos(100, 100);
       
  1223 
       
  1224     items[0]->rotate(30);
       
  1225     items[1]->rotate(-30);
       
  1226 
       
  1227 #if defined(Q_OS_WINCE)
       
  1228     //Is the standard scrollbar size
       
  1229     int scrollbarSize = qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent) - 13;
       
  1230 #endif
       
  1231 
       
  1232     QGraphicsView view(&scene);
       
  1233     view.setSceneRect(-400, -400, 800, 800);
       
  1234 
       
  1235 #if defined(Q_OS_WINCE)
       
  1236     //We need to take in account the scrollbar size for the WindowsMobilStyle
       
  1237     view.setFixedSize(400 + scrollbarSize, 200 + scrollbarSize);
       
  1238 #else
       
  1239     view.setFixedSize(400, 200);
       
  1240 #endif
       
  1241 
       
  1242     view.show();
       
  1243     view.fitInView(scene.itemsBoundingRect(), Qt::IgnoreAspectRatio);
       
  1244     qApp->processEvents();
       
  1245 
       
  1246     // Sampled coordinates.
       
  1247     QVERIFY(!view.itemAt(45, 41));
       
  1248     QVERIFY(!view.itemAt(297, 44));
       
  1249     QVERIFY(!view.itemAt(359, 143));
       
  1250     QCOMPARE(view.itemAt(79, 22), items[0]);
       
  1251     QCOMPARE(view.itemAt(329, 41), items[1]);
       
  1252     QCOMPARE(view.itemAt(38, 158), items[2]);
       
  1253     QCOMPARE(view.itemAt(332, 160), items[3]);
       
  1254 
       
  1255     view.fitInView(items[0], Qt::IgnoreAspectRatio);
       
  1256     qApp->processEvents();
       
  1257 
       
  1258     QCOMPARE(view.itemAt(19, 13), items[0]);
       
  1259     QCOMPARE(view.itemAt(91, 47), items[0]);
       
  1260     QCOMPARE(view.itemAt(202, 94), items[0]);
       
  1261     QCOMPARE(view.itemAt(344, 161), items[0]);
       
  1262     QVERIFY(!view.itemAt(236, 54));
       
  1263     QVERIFY(!view.itemAt(144, 11));
       
  1264     QVERIFY(!view.itemAt(29, 69));
       
  1265     QVERIFY(!view.itemAt(251, 167));
       
  1266 
       
  1267     view.fitInView(items[0], Qt::KeepAspectRatio);
       
  1268     qApp->processEvents();
       
  1269 
       
  1270     QCOMPARE(view.itemAt(325, 170), items[0]);
       
  1271     QCOMPARE(view.itemAt(206, 74), items[0]);
       
  1272     QCOMPARE(view.itemAt(190, 115), items[0]);
       
  1273     QCOMPARE(view.itemAt(55, 14), items[0]);
       
  1274     QVERIFY(!view.itemAt(109, 4));
       
  1275     QVERIFY(!view.itemAt(244, 68));
       
  1276     QVERIFY(!view.itemAt(310, 125));
       
  1277     QVERIFY(!view.itemAt(261, 168));
       
  1278 
       
  1279     view.fitInView(items[0], Qt::KeepAspectRatioByExpanding);
       
  1280     qApp->processEvents();
       
  1281 
       
  1282     QCOMPARE(view.itemAt(18, 10), items[0]);
       
  1283     QCOMPARE(view.itemAt(95, 4), items[0]);
       
  1284     QCOMPARE(view.itemAt(279, 175), items[0]);
       
  1285     QCOMPARE(view.itemAt(359, 170), items[0]);
       
  1286     QVERIFY(!view.itemAt(370, 166));
       
  1287     QVERIFY(!view.itemAt(136, 7));
       
  1288     QVERIFY(!view.itemAt(31, 44));
       
  1289     QVERIFY(!view.itemAt(203, 153));
       
  1290 }
       
  1291 
       
  1292 void tst_QGraphicsView::itemsAtPoint()
       
  1293 {
       
  1294     QGraphicsScene scene;
       
  1295     scene.addRect(QRectF(-10, -10, 20, 20))->setZValue(1);
       
  1296     scene.addRect(QRectF(-10, -10, 20, 20))->setZValue(0);
       
  1297     scene.addRect(QRectF(-10, -10, 20, 20))->setZValue(2);
       
  1298     scene.addRect(QRectF(-10, -10, 20, 20))->setZValue(-1);
       
  1299     scene.addRect(QRectF(-10, -10, 20, 20))->setZValue(3);
       
  1300 
       
  1301     QGraphicsView view;
       
  1302     QVERIFY(view.items(0, 0).isEmpty());
       
  1303 
       
  1304     view.setScene(&scene);
       
  1305     view.setSceneRect(-10000, -10000, 20000, 20000);
       
  1306     view.show();
       
  1307 
       
  1308     QList<QGraphicsItem *> items = view.items(view.viewport()->rect().center());
       
  1309     QCOMPARE(items.size(), 5);
       
  1310     QCOMPARE(items.takeFirst()->zValue(), qreal(3));
       
  1311     QCOMPARE(items.takeFirst()->zValue(), qreal(2));
       
  1312     QCOMPARE(items.takeFirst()->zValue(), qreal(1));
       
  1313     QCOMPARE(items.takeFirst()->zValue(), qreal(0));
       
  1314     QCOMPARE(items.takeFirst()->zValue(), qreal(-1));
       
  1315 }
       
  1316 
       
  1317 void tst_QGraphicsView::itemsInRect()
       
  1318 {
       
  1319     QGraphicsScene scene;
       
  1320     scene.addRect(QRectF(-30, -10, 20, 20))->setZValue(1);
       
  1321     scene.addRect(QRectF(-30, -10, 20, 20))->setZValue(0);
       
  1322     scene.addRect(QRectF(-30, -10, 20, 20))->setZValue(2);
       
  1323     scene.addRect(QRectF(-30, -10, 20, 20))->setZValue(-1);
       
  1324     scene.addRect(QRectF(-30, -10, 20, 20))->setZValue(3);
       
  1325 
       
  1326     scene.addRect(QRectF(30, -10, 20, 20))->setZValue(5);
       
  1327     scene.addRect(QRectF(30, -10, 20, 20))->setZValue(4);
       
  1328     scene.addRect(QRectF(30, -10, 20, 20))->setZValue(6);
       
  1329     scene.addRect(QRectF(30, -10, 20, 20))->setZValue(3);
       
  1330     scene.addRect(QRectF(30, -10, 20, 20))->setZValue(7);
       
  1331 
       
  1332     QGraphicsView view;
       
  1333     QVERIFY(view.items(QRect(-100, -100, 200, 200)).isEmpty());
       
  1334     view.setScene(&scene);
       
  1335     view.setSceneRect(-10000, -10000, 20000, 20000);
       
  1336     view.show();
       
  1337 
       
  1338     QPoint centerPoint = view.viewport()->rect().center();
       
  1339     QRect leftRect = view.mapFromScene(-30, -10, 20, 20).boundingRect();
       
  1340     QRect rightRect = view.mapFromScene(30, -10, 20, 20).boundingRect();
       
  1341 
       
  1342     QList<QGraphicsItem *> items = view.items(leftRect);
       
  1343     QCOMPARE(items.size(), 5);
       
  1344     QCOMPARE(items.takeFirst()->zValue(), qreal(3));
       
  1345     QCOMPARE(items.takeFirst()->zValue(), qreal(2));
       
  1346     QCOMPARE(items.takeFirst()->zValue(), qreal(1));
       
  1347     QCOMPARE(items.takeFirst()->zValue(), qreal(0));
       
  1348     QCOMPARE(items.takeFirst()->zValue(), qreal(-1));
       
  1349 
       
  1350     items = view.items(rightRect);
       
  1351     QCOMPARE(items.size(), 5);
       
  1352     QCOMPARE(items.takeFirst()->zValue(), qreal(7));
       
  1353     QCOMPARE(items.takeFirst()->zValue(), qreal(6));
       
  1354     QCOMPARE(items.takeFirst()->zValue(), qreal(5));
       
  1355     QCOMPARE(items.takeFirst()->zValue(), qreal(4));
       
  1356     QCOMPARE(items.takeFirst()->zValue(), qreal(3));
       
  1357 }
       
  1358 
       
  1359 class CountPaintItem : public QGraphicsRectItem
       
  1360 {
       
  1361 public:
       
  1362     int numPaints;
       
  1363 
       
  1364     CountPaintItem(const QRectF &rect)
       
  1365         : QGraphicsRectItem(rect), numPaints(0)
       
  1366     { }
       
  1367 
       
  1368     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0)
       
  1369     {
       
  1370         ++numPaints;
       
  1371         QGraphicsRectItem::paint(painter, option, widget);
       
  1372     }
       
  1373 };
       
  1374 
       
  1375 void tst_QGraphicsView::itemsInRect_cosmeticAdjust_data()
       
  1376 {
       
  1377     QTest::addColumn<QRect>("updateRect");
       
  1378     QTest::addColumn<int>("numPaints");
       
  1379 
       
  1380     QTest::newRow("nil") << QRect() << 1;
       
  1381     QTest::newRow("0, 0, 300, 100") << QRect(0, 0, 300, 100) << 1;
       
  1382     QTest::newRow("0, 0, 100, 300") << QRect(0, 0, 100, 300) << 1;
       
  1383     QTest::newRow("200, 0, 100, 300") << QRect(200, 0, 100, 300) << 1;
       
  1384     QTest::newRow("0, 200, 300, 100") << QRect(0, 200, 300, 100) << 1;
       
  1385     QTest::newRow("0, 0, 300, 99") << QRect(0, 0, 300, 99) << 0;
       
  1386     QTest::newRow("0, 0, 99, 300") << QRect(0, 0, 99, 300) << 0;
       
  1387     QTest::newRow("201, 0, 99, 300") << QRect(201, 0, 99, 300) << 0;
       
  1388     QTest::newRow("0, 201, 300, 99") << QRect(0, 201, 300, 99) << 0;
       
  1389 }
       
  1390 
       
  1391 void tst_QGraphicsView::itemsInRect_cosmeticAdjust()
       
  1392 {
       
  1393     QFETCH(QRect, updateRect);
       
  1394     QFETCH(int, numPaints);
       
  1395 
       
  1396     QGraphicsScene scene(-100, -100, 200, 200);
       
  1397     CountPaintItem *rect = new CountPaintItem(QRectF(-50, -50, 100, 100));
       
  1398     scene.addItem(rect);
       
  1399 
       
  1400     QGraphicsView view(&scene);
       
  1401     view.setFrameStyle(0);
       
  1402     view.resize(300, 300);
       
  1403     view.show();
       
  1404     QTest::qWaitForWindowShown(&view) ;
       
  1405     QTRY_VERIFY(rect->numPaints > 0);
       
  1406 
       
  1407     rect->numPaints = 0;
       
  1408     if (updateRect.isNull())
       
  1409         view.viewport()->update();
       
  1410     else
       
  1411         view.viewport()->update(updateRect);
       
  1412     qApp->processEvents();
       
  1413     QTRY_COMPARE(rect->numPaints, numPaints);
       
  1414 }
       
  1415 
       
  1416 void tst_QGraphicsView::itemsInPoly()
       
  1417 {
       
  1418     QGraphicsScene scene;
       
  1419     scene.addRect(QRectF(-30, -10, 20, 20))->setZValue(1);
       
  1420     scene.addRect(QRectF(-30, -10, 20, 20))->setZValue(0);
       
  1421     scene.addRect(QRectF(-30, -10, 20, 20))->setZValue(2);
       
  1422     scene.addRect(QRectF(-30, -10, 20, 20))->setZValue(-1);
       
  1423     scene.addRect(QRectF(-30, -10, 20, 20))->setZValue(3);
       
  1424 
       
  1425     scene.addRect(QRectF(30, -10, 20, 20))->setZValue(5);
       
  1426     scene.addRect(QRectF(30, -10, 20, 20))->setZValue(4);
       
  1427     scene.addRect(QRectF(30, -10, 20, 20))->setZValue(6);
       
  1428     scene.addRect(QRectF(30, -10, 20, 20))->setZValue(3);
       
  1429     scene.addRect(QRectF(30, -10, 20, 20))->setZValue(7);
       
  1430 
       
  1431     QGraphicsView view;
       
  1432     QVERIFY(view.items(QPolygon()).isEmpty());
       
  1433     view.setScene(&scene);
       
  1434     view.setSceneRect(-10000, -10000, 20000, 20000);
       
  1435     view.show();
       
  1436 
       
  1437     QPoint centerPoint = view.viewport()->rect().center();
       
  1438     QPolygon leftPoly = view.mapFromScene(QRectF(-30, -10, 20, 20));
       
  1439     QPolygon rightPoly = view.mapFromScene(QRectF(30, -10, 20, 20));
       
  1440 
       
  1441     QList<QGraphicsItem *> items = view.items(leftPoly);
       
  1442     QCOMPARE(items.size(), 5);
       
  1443     QCOMPARE(items.takeFirst()->zValue(), qreal(3));
       
  1444     QCOMPARE(items.takeFirst()->zValue(), qreal(2));
       
  1445     QCOMPARE(items.takeFirst()->zValue(), qreal(1));
       
  1446     QCOMPARE(items.takeFirst()->zValue(), qreal(0));
       
  1447     QCOMPARE(items.takeFirst()->zValue(), qreal(-1));
       
  1448 
       
  1449     items = view.items(rightPoly);
       
  1450     QCOMPARE(items.size(), 5);
       
  1451     QCOMPARE(items.takeFirst()->zValue(), qreal(7));
       
  1452     QCOMPARE(items.takeFirst()->zValue(), qreal(6));
       
  1453     QCOMPARE(items.takeFirst()->zValue(), qreal(5));
       
  1454     QCOMPARE(items.takeFirst()->zValue(), qreal(4));
       
  1455     QCOMPARE(items.takeFirst()->zValue(), qreal(3));
       
  1456 }
       
  1457 
       
  1458 void tst_QGraphicsView::itemsInPath()
       
  1459 {
       
  1460     QGraphicsScene scene;
       
  1461     scene.addRect(QRectF(-30, -10, 20, 20))->setZValue(1);
       
  1462     scene.addRect(QRectF(-30, -10, 20, 20))->setZValue(0);
       
  1463     scene.addRect(QRectF(-30, -10, 20, 20))->setZValue(2);
       
  1464     scene.addRect(QRectF(-30, -10, 20, 20))->setZValue(-1);
       
  1465     scene.addRect(QRectF(-30, -10, 20, 20))->setZValue(3);
       
  1466 
       
  1467     scene.addRect(QRectF(30, -10, 20, 20))->setZValue(5);
       
  1468     scene.addRect(QRectF(30, -10, 20, 20))->setZValue(4);
       
  1469     scene.addRect(QRectF(30, -10, 20, 20))->setZValue(6);
       
  1470     scene.addRect(QRectF(30, -10, 20, 20))->setZValue(3);
       
  1471     scene.addRect(QRectF(30, -10, 20, 20))->setZValue(7);
       
  1472 
       
  1473     QGraphicsView view;
       
  1474     QVERIFY(view.items(QPainterPath()).isEmpty());
       
  1475     view.setScene(&scene);
       
  1476     view.translate(100, 400);
       
  1477     view.rotate(22.3);
       
  1478     view.setSceneRect(-10000, -10000, 20000, 20000);
       
  1479     view.show();
       
  1480 
       
  1481     QPoint centerPoint = view.viewport()->rect().center();
       
  1482     QPainterPath leftPath;
       
  1483     leftPath.addEllipse(QRect(view.mapFromScene(-30, -10), QSize(20, 20)));
       
  1484 
       
  1485     QPainterPath rightPath;
       
  1486     rightPath.addEllipse(QRect(view.mapFromScene(30, -10), QSize(20, 20)));
       
  1487 
       
  1488     QList<QGraphicsItem *> items = view.items(leftPath);
       
  1489 
       
  1490     QCOMPARE(items.size(), 5);
       
  1491     QCOMPARE(items.takeFirst()->zValue(), qreal(3));
       
  1492     QCOMPARE(items.takeFirst()->zValue(), qreal(2));
       
  1493     QCOMPARE(items.takeFirst()->zValue(), qreal(1));
       
  1494     QCOMPARE(items.takeFirst()->zValue(), qreal(0));
       
  1495     QCOMPARE(items.takeFirst()->zValue(), qreal(-1));
       
  1496 
       
  1497     items = view.items(rightPath);
       
  1498     QCOMPARE(items.size(), 5);
       
  1499     QCOMPARE(items.takeFirst()->zValue(), qreal(7));
       
  1500     QCOMPARE(items.takeFirst()->zValue(), qreal(6));
       
  1501     QCOMPARE(items.takeFirst()->zValue(), qreal(5));
       
  1502     QCOMPARE(items.takeFirst()->zValue(), qreal(4));
       
  1503     QCOMPARE(items.takeFirst()->zValue(), qreal(3));
       
  1504 }
       
  1505 
       
  1506 void tst_QGraphicsView::itemAt()
       
  1507 {
       
  1508     QGraphicsScene scene;
       
  1509     scene.addRect(QRectF(-10, -10, 20, 20))->setZValue(1);
       
  1510     scene.addRect(QRectF(-10, -10, 20, 20))->setZValue(0);
       
  1511     scene.addRect(QRectF(-10, -10, 20, 20))->setZValue(2);
       
  1512     scene.addRect(QRectF(-10, -10, 20, 20))->setZValue(-1);
       
  1513     scene.addRect(QRectF(-10, -10, 20, 20))->setZValue(3);
       
  1514 
       
  1515     QGraphicsView view;
       
  1516     QCOMPARE(view.itemAt(0, 0), (QGraphicsItem *)0);
       
  1517 
       
  1518     view.setScene(&scene);
       
  1519     view.setSceneRect(-10000, -10000, 20000, 20000);
       
  1520     view.show();
       
  1521 
       
  1522     QCOMPARE(view.itemAt(0, 0), (QGraphicsItem *)0);
       
  1523     QGraphicsItem* item = view.itemAt(view.viewport()->rect().center());
       
  1524     QVERIFY(item);
       
  1525     QCOMPARE(item->zValue(), qreal(3));
       
  1526 }
       
  1527 
       
  1528 void tst_QGraphicsView::itemAt2()
       
  1529 {
       
  1530     // test precision of the itemAt() function with items that are smaller
       
  1531     // than 1 pixel.
       
  1532     QGraphicsScene scene(0, 0, 100, 100);
       
  1533 
       
  1534     // Add a 0.5x0.5 item at position 0 on the scene, top-left corner at -0.25, -0.25.
       
  1535     QGraphicsItem *item = scene.addRect(QRectF(-0.25, -0.25, 0.5, 0.5), QPen(Qt::black, 0.1));
       
  1536 
       
  1537     QGraphicsView view(&scene);
       
  1538     view.setFixedSize(200, 200);
       
  1539     view.setTransformationAnchor(QGraphicsView::NoAnchor);
       
  1540     view.setRenderHint(QPainter::Antialiasing);
       
  1541     view.show();
       
  1542     QTest::qWaitForWindowShown(&view);
       
  1543     QApplication::processEvents();
       
  1544 
       
  1545     QPoint itemViewPoint = view.mapFromScene(item->scenePos());
       
  1546 
       
  1547     for (int i = 0; i < 3; ++i) {
       
  1548         QVERIFY(view.itemAt(itemViewPoint));
       
  1549         QVERIFY(!view.items(itemViewPoint).isEmpty());
       
  1550         QVERIFY(view.itemAt(itemViewPoint + QPoint(-1, 0)));
       
  1551         QVERIFY(!view.items(itemViewPoint + QPoint(-1, 0)).isEmpty());
       
  1552         QVERIFY(view.itemAt(itemViewPoint + QPoint(-1, -1)));
       
  1553         QVERIFY(!view.items(itemViewPoint + QPoint(-1, -1)).isEmpty());
       
  1554         QVERIFY(view.itemAt(itemViewPoint + QPoint(0, -1)));
       
  1555         QVERIFY(!view.items(itemViewPoint + QPoint(0, -1)).isEmpty());
       
  1556         item->moveBy(0.1, 0);
       
  1557     }
       
  1558 
       
  1559     // Here
       
  1560     QVERIFY(view.itemAt(itemViewPoint));
       
  1561     QVERIFY(!view.items(itemViewPoint).isEmpty());
       
  1562     QVERIFY(view.itemAt(itemViewPoint + QPoint(0, -1)));
       
  1563     QVERIFY(!view.items(itemViewPoint + QPoint(0, -1)).isEmpty());
       
  1564 
       
  1565     if (sizeof(qreal) != sizeof(double)) {
       
  1566         QSKIP("Skipped due to rounding errors", SkipAll);
       
  1567     }
       
  1568     // Not here
       
  1569     QVERIFY(!view.itemAt(itemViewPoint + QPoint(-1, 0)));
       
  1570     QVERIFY(view.items(itemViewPoint + QPoint(-1, 0)).isEmpty());
       
  1571     QVERIFY(!view.itemAt(itemViewPoint + QPoint(-1, -1)));
       
  1572     QVERIFY(view.items(itemViewPoint + QPoint(-1, -1)).isEmpty());
       
  1573 }
       
  1574 
       
  1575 void tst_QGraphicsView::mapToScene()
       
  1576 {
       
  1577     // Uncomment the commented-out code to see what's going on. It doesn't
       
  1578     // affect the test; it just slows it down.
       
  1579 
       
  1580     QGraphicsScene scene;
       
  1581     scene.addPixmap(QPixmap("3D-Qt-1-2.png"));
       
  1582 
       
  1583     QGraphicsView view;
       
  1584     view.setScene(&scene);
       
  1585     view.setSceneRect(-500, -500, 1000, 1000);
       
  1586 #if defined(Q_OS_WINCE)
       
  1587     QSize viewSize(200,200);
       
  1588 #else
       
  1589     QSize viewSize(300,300);
       
  1590 #endif
       
  1591 
       
  1592     view.setFixedSize(viewSize);
       
  1593     view.show();
       
  1594     QApplication::processEvents();
       
  1595     QVERIFY(view.isVisible());
       
  1596     QCOMPARE(view.size(), viewSize);
       
  1597 
       
  1598     // First once without setting the scene rect
       
  1599 #ifdef QT_ARCH_ARM
       
  1600     const int step = 20;
       
  1601 #else
       
  1602     const int step = 1;
       
  1603 #endif
       
  1604 
       
  1605     for (int x = 0; x < view.width(); x += step) {
       
  1606         for (int y = 0; y < view.height(); y += step) {
       
  1607             QCOMPARE(view.mapToScene(QPoint(x, y)),
       
  1608                      QPointF(view.horizontalScrollBar()->value() + x,
       
  1609                              view.verticalScrollBar()->value() + y));
       
  1610         }
       
  1611     }
       
  1612 
       
  1613     for (int sceneRectHeight = 250; sceneRectHeight < 1000; sceneRectHeight += 250) {
       
  1614         for (int sceneRectWidth = 250; sceneRectWidth < 1000; sceneRectWidth += 250) {
       
  1615             view.setSceneRect(QRectF(-int(sceneRectWidth / 2), -int(sceneRectHeight / 2),
       
  1616                                      sceneRectWidth, sceneRectHeight));
       
  1617             QApplication::processEvents();
       
  1618 
       
  1619             int hmin = view.horizontalScrollBar()->minimum();
       
  1620             int hmax = view.horizontalScrollBar()->maximum();
       
  1621             int hstep = (hmax - hmin) / 3;
       
  1622             int vmin = view.verticalScrollBar()->minimum();
       
  1623             int vmax = view.verticalScrollBar()->maximum();
       
  1624             int vstep = (vmax - vmin) / 3;
       
  1625 
       
  1626             for (int hscrollValue = hmin; hscrollValue < hmax; hscrollValue += hstep) {
       
  1627                 for (int vscrollValue = vmin; vscrollValue < vmax; vscrollValue += vstep) {
       
  1628 
       
  1629                     view.horizontalScrollBar()->setValue(hscrollValue);
       
  1630                     view.verticalScrollBar()->setValue(vscrollValue);
       
  1631                     QApplication::processEvents();
       
  1632 
       
  1633                     int h = view.horizontalScrollBar()->value();
       
  1634                     int v = view.verticalScrollBar()->value();
       
  1635 
       
  1636                     for (int x = 0; x < view.width(); x += step) {
       
  1637                         for (int y = 0; y < view.height(); y += step) {
       
  1638                             QCOMPARE(view.mapToScene(QPoint(x, y)), QPointF(h + x, v + y));
       
  1639                             QCOMPARE(view.mapFromScene(QPointF(h + x, v + y)), QPoint(x, y));
       
  1640                         }
       
  1641                     }
       
  1642                 }
       
  1643             }
       
  1644         }
       
  1645     }
       
  1646 }
       
  1647 
       
  1648 void tst_QGraphicsView::mapToScenePoint()
       
  1649 {
       
  1650     QGraphicsScene scene;
       
  1651     QGraphicsView view(&scene);
       
  1652     view.rotate(90);
       
  1653     view.setFixedSize(117, 117);
       
  1654     view.show();
       
  1655     QPoint center = view.viewport()->rect().center();
       
  1656     QCOMPARE(view.mapToScene(center + QPoint(10, 0)),
       
  1657              view.mapToScene(center) + QPointF(0, -10));
       
  1658 }
       
  1659 
       
  1660 void tst_QGraphicsView::mapToSceneRect_data()
       
  1661 {
       
  1662     QTest::addColumn<QRect>("viewRect");
       
  1663     QTest::addColumn<QPolygonF>("scenePoly");
       
  1664     QTest::addColumn<qreal>("rotation");
       
  1665 
       
  1666     QTest::newRow("nil") << QRect() << QPolygonF() << qreal(0);
       
  1667     QTest::newRow("0, 0, 1, 1") << QRect(0, 0, 1, 1) << QPolygonF(QRectF(0, 0, 1, 1)) << qreal(0);
       
  1668     QTest::newRow("0, 0, 10, 10") << QRect(0, 0, 10, 10) << QPolygonF(QRectF(0, 0, 10, 10)) << qreal(0);
       
  1669     QTest::newRow("nil") << QRect() << QPolygonF() << qreal(90);
       
  1670     QPolygonF p;
       
  1671     p << QPointF(0, 0) << QPointF(0, -1) << QPointF(1, -1) << QPointF(1, 0) << QPointF(0, 0);
       
  1672     QTest::newRow("0, 0, 1, 1") << QRect(0, 0, 1, 1)
       
  1673                                 << p
       
  1674                                 << qreal(90);
       
  1675     p.clear();
       
  1676     p << QPointF(0, 0) << QPointF(0, -10) << QPointF(10, -10) << QPointF(10, 0) << QPointF(0, 0);
       
  1677     QTest::newRow("0, 0, 10, 10") << QRect(0, 0, 10, 10)
       
  1678                                   << p
       
  1679                                   << qreal(90);
       
  1680 }
       
  1681 
       
  1682 void tst_QGraphicsView::mapToSceneRect()
       
  1683 {
       
  1684     QFETCH(QRect, viewRect);
       
  1685     QFETCH(QPolygonF, scenePoly);
       
  1686     QFETCH(qreal, rotation);
       
  1687 
       
  1688     QGraphicsScene scene(-1000, -1000, 2000, 2000);
       
  1689     scene.addRect(25, -25, 50, 50);
       
  1690     QGraphicsView view(&scene);
       
  1691     view.setFrameStyle(0);
       
  1692     view.setAlignment(Qt::AlignTop | Qt::AlignLeft);
       
  1693     view.setFixedSize(200, 200);
       
  1694     view.setTransformationAnchor(QGraphicsView::NoAnchor);
       
  1695     view.setResizeAnchor(QGraphicsView::NoAnchor);
       
  1696     view.show();
       
  1697 
       
  1698     view.rotate(rotation);
       
  1699 
       
  1700     QPolygonF poly = view.mapToScene(viewRect);
       
  1701     if (!poly.isEmpty())
       
  1702         poly << poly[0];
       
  1703 
       
  1704     QCOMPARE(poly, scenePoly);
       
  1705 }
       
  1706 
       
  1707 void tst_QGraphicsView::mapToScenePoly()
       
  1708 {
       
  1709     QGraphicsScene scene;
       
  1710     QGraphicsView view(&scene);
       
  1711     view.translate(100, 100);
       
  1712     view.setFixedSize(117, 117);
       
  1713     view.show();
       
  1714     QPoint center = view.viewport()->rect().center();
       
  1715     QRect rect(center + QPoint(10, 0), QSize(10, 10));
       
  1716 
       
  1717     QPolygon poly;
       
  1718     poly << rect.topLeft();
       
  1719     poly << rect.topRight();
       
  1720     poly << rect.bottomRight();
       
  1721     poly << rect.bottomLeft();
       
  1722 
       
  1723     QPolygonF poly2;
       
  1724     poly2 << view.mapToScene(rect.topLeft());
       
  1725     poly2 << view.mapToScene(rect.topRight());
       
  1726     poly2 << view.mapToScene(rect.bottomRight());
       
  1727     poly2 << view.mapToScene(rect.bottomLeft());
       
  1728 
       
  1729     QCOMPARE(view.mapToScene(poly), poly2);
       
  1730 }
       
  1731 
       
  1732 void tst_QGraphicsView::mapToScenePath()
       
  1733 {
       
  1734     QGraphicsScene scene;
       
  1735     QGraphicsView view(&scene);
       
  1736     view.setSceneRect(-300, -300, 600, 600);
       
  1737     view.translate(10, 10);
       
  1738     view.setFixedSize(300, 300);
       
  1739     view.show();
       
  1740     QPoint center = view.viewport()->rect().center();
       
  1741     QRect rect(QPoint(10, 0), QSize(10, 10));
       
  1742 
       
  1743     QPainterPath path;
       
  1744     path.addRect(rect);
       
  1745 
       
  1746     QPainterPath path2;
       
  1747     path2.addRect(rect.translated(view.horizontalScrollBar()->value() - 10,
       
  1748                                   view.verticalScrollBar()->value() - 10));
       
  1749     QCOMPARE(view.mapToScene(path), path2);
       
  1750 }
       
  1751 
       
  1752 void tst_QGraphicsView::mapFromScenePoint()
       
  1753 {
       
  1754     {
       
  1755         QGraphicsScene scene;
       
  1756         QGraphicsView view(&scene);
       
  1757         view.rotate(90);
       
  1758         view.scale(10, 10);
       
  1759         view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
  1760         view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
  1761         view.show();
       
  1762 
       
  1763         QPoint mapped = view.mapFromScene(0, 0);
       
  1764         QPoint center = view.viewport()->rect().center();
       
  1765         if (qAbs(mapped.x() - center.x()) >= 2
       
  1766             || qAbs(mapped.y() - center.y()) >= 2) {
       
  1767             QString error = QString("Compared values are not the same\n\tActual: (%1, %2)\n\tExpected: (%3, %4)")
       
  1768                             .arg(mapped.x()).arg(mapped.y()).arg(center.x()).arg(center.y());
       
  1769             QFAIL(qPrintable(error));
       
  1770         }
       
  1771     }
       
  1772     {
       
  1773         QGraphicsScene scene(0, 0, 200, 200);
       
  1774         scene.addRect(QRectF(0, 0, 200, 200), QPen(Qt::black, 1));
       
  1775         QGraphicsView view(&scene);
       
  1776         view.resize(view.sizeHint());
       
  1777         view.show();
       
  1778 
       
  1779         QCOMPARE(view.mapFromScene(0, 0), QPoint(0, 0));
       
  1780         QCOMPARE(view.mapFromScene(0.4, 0.4), QPoint(0, 0));
       
  1781         QCOMPARE(view.mapFromScene(0.5, 0.5), QPoint(1, 1));
       
  1782         QCOMPARE(view.mapFromScene(0.9, 0.9), QPoint(1, 1));
       
  1783         QCOMPARE(view.mapFromScene(1.0, 1.0), QPoint(1, 1));
       
  1784         QCOMPARE(view.mapFromScene(100, 100), QPoint(100, 100));
       
  1785         QCOMPARE(view.mapFromScene(100.5, 100.5), QPoint(101, 101));
       
  1786         QCOMPARE(view.mapToScene(0, 0), QPointF(0, 0));
       
  1787         QCOMPARE(view.mapToScene(1, 1), QPointF(1, 1));
       
  1788         QCOMPARE(view.mapToScene(100, 100), QPointF(100, 100));
       
  1789     }
       
  1790 }
       
  1791 
       
  1792 void tst_QGraphicsView::mapFromSceneRect()
       
  1793 {
       
  1794     QGraphicsScene scene;
       
  1795     QGraphicsView view(&scene);
       
  1796     view.rotate(90);
       
  1797     view.setFixedSize(200, 200);
       
  1798     view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
  1799     view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
  1800     view.show();
       
  1801     QTest::qWait(25);
       
  1802 
       
  1803     QPolygon polygon;
       
  1804     polygon << QPoint(98, 98);
       
  1805     polygon << QPoint(98, 108);
       
  1806     polygon << QPoint(88, 108);
       
  1807     polygon << QPoint(88, 98);
       
  1808 
       
  1809 
       
  1810     QPolygon viewPolygon = view.mapFromScene(0, 0, 10, 10);
       
  1811     for (int i = 0; i < 4; ++i) {
       
  1812         QVERIFY(qAbs(viewPolygon[i].x() - polygon[i].x()) < 3);
       
  1813         QVERIFY(qAbs(viewPolygon[i].y() - polygon[i].y()) < 3);
       
  1814     }
       
  1815 
       
  1816     QPoint pt = view.mapFromScene(QPointF());
       
  1817     QPolygon p;
       
  1818     p << pt << pt << pt << pt;
       
  1819     QCOMPARE(view.mapFromScene(QRectF()), p);
       
  1820 }
       
  1821 
       
  1822 void tst_QGraphicsView::mapFromScenePoly()
       
  1823 {
       
  1824     QGraphicsScene scene;
       
  1825     QGraphicsView view(&scene);
       
  1826     view.rotate(90);
       
  1827     view.setFixedSize(200, 200);
       
  1828     view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
  1829     view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
  1830     view.show();
       
  1831 
       
  1832     QPolygonF polygon;
       
  1833     polygon << QPoint(0, 0);
       
  1834     polygon << QPoint(10, 0);
       
  1835     polygon << QPoint(10, 10);
       
  1836     polygon << QPoint(0, 10);
       
  1837 
       
  1838     QPolygon polygon2;
       
  1839     polygon2 << QPoint(98, 98);
       
  1840     polygon2 << QPoint(98, 108);
       
  1841     polygon2 << QPoint(88, 108);
       
  1842     polygon2 << QPoint(88, 98);
       
  1843 
       
  1844     QPolygon viewPolygon = view.mapFromScene(polygon);
       
  1845     for (int i = 0; i < 4; ++i) {
       
  1846         QVERIFY(qAbs(viewPolygon[i].x() - polygon2[i].x()) < 3);
       
  1847         QVERIFY(qAbs(viewPolygon[i].y() - polygon2[i].y()) < 3);
       
  1848     }
       
  1849 }
       
  1850 
       
  1851 void tst_QGraphicsView::mapFromScenePath()
       
  1852 {
       
  1853     QGraphicsScene scene;
       
  1854     QGraphicsView view(&scene);
       
  1855     view.rotate(90);
       
  1856     view.setFixedSize(200, 200);
       
  1857     view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
  1858     view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
  1859     view.show();
       
  1860 
       
  1861     QPolygonF polygon;
       
  1862     polygon << QPoint(0, 0);
       
  1863     polygon << QPoint(10, 0);
       
  1864     polygon << QPoint(10, 10);
       
  1865     polygon << QPoint(0, 10);
       
  1866     QPainterPath path;
       
  1867     path.addPolygon(polygon);
       
  1868 
       
  1869     QPolygon polygon2;
       
  1870     polygon2 << QPoint(98, 98);
       
  1871     polygon2 << QPoint(98, 108);
       
  1872     polygon2 << QPoint(88, 108);
       
  1873     polygon2 << QPoint(88, 98);
       
  1874     QPainterPath path2;
       
  1875     path2.addPolygon(polygon2);
       
  1876 
       
  1877     QPolygonF pathPoly = view.mapFromScene(path).toFillPolygon();
       
  1878     QPolygonF path2Poly = path2.toFillPolygon();
       
  1879 
       
  1880     for (int i = 0; i < pathPoly.size(); ++i) {
       
  1881         QVERIFY(qAbs(pathPoly[i].x() - path2Poly[i].x()) < 3);
       
  1882         QVERIFY(qAbs(pathPoly[i].y() - path2Poly[i].y()) < 3);
       
  1883     }
       
  1884 }
       
  1885 
       
  1886 void tst_QGraphicsView::sendEvent()
       
  1887 {
       
  1888     QGraphicsScene scene;
       
  1889 
       
  1890     TestItem *item = new TestItem;
       
  1891     scene.addItem(item);
       
  1892     item->setFlag(QGraphicsItem::ItemIsFocusable);
       
  1893     item->setFlag(QGraphicsItem::ItemIsMovable);
       
  1894 
       
  1895     QGraphicsView view(&scene);
       
  1896     view.show();
       
  1897     QTest::qWaitForWindowShown(&view);
       
  1898     QApplication::setActiveWindow(&view);
       
  1899     QTest::qWait(20);
       
  1900     QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
       
  1901 
       
  1902     item->setFocus();
       
  1903 
       
  1904     QCOMPARE(scene.focusItem(), (QGraphicsItem *)item);
       
  1905     QCOMPARE(item->events.size(), 2);
       
  1906     QCOMPARE(item->events.last(), QEvent::FocusIn);
       
  1907 
       
  1908     QPoint itemPoint = view.mapFromScene(item->scenePos());
       
  1909     sendMousePress(view.viewport(), itemPoint);
       
  1910     QCOMPARE(item->events.size(), 4);
       
  1911     QCOMPARE(item->events.at(item->events.size() - 2), QEvent::GrabMouse);
       
  1912     QCOMPARE(item->events.at(item->events.size() - 1), QEvent::GraphicsSceneMousePress);
       
  1913 
       
  1914     QMouseEvent mouseMoveEvent(QEvent::MouseMove, itemPoint, view.viewport()->mapToGlobal(itemPoint),
       
  1915                                 Qt::LeftButton, Qt::LeftButton, 0);
       
  1916     QApplication::sendEvent(view.viewport(), &mouseMoveEvent);
       
  1917     QCOMPARE(item->events.size(), 5);
       
  1918     QCOMPARE(item->events.last(), QEvent::GraphicsSceneMouseMove);
       
  1919 
       
  1920     QMouseEvent mouseReleaseEvent(QEvent::MouseButtonRelease, itemPoint,
       
  1921                                   view.viewport()->mapToGlobal(itemPoint),
       
  1922                                   Qt::LeftButton, 0, 0);
       
  1923     QApplication::sendEvent(view.viewport(), &mouseReleaseEvent);
       
  1924     QCOMPARE(item->events.size(), 7);
       
  1925     QCOMPARE(item->events.at(item->events.size() - 2), QEvent::GraphicsSceneMouseRelease);
       
  1926     QCOMPARE(item->events.at(item->events.size() - 1), QEvent::UngrabMouse);
       
  1927 
       
  1928     QKeyEvent keyPress(QEvent::KeyPress, Qt::Key_Space, 0);
       
  1929     QApplication::sendEvent(view.viewport(), &keyPress);
       
  1930     QCOMPARE(item->events.size(), 9);
       
  1931     QCOMPARE(item->events.at(item->events.size() - 2), QEvent::ShortcutOverride);
       
  1932     QCOMPARE(item->events.last(), QEvent::KeyPress);
       
  1933 }
       
  1934 
       
  1935 class MouseWheelScene : public QGraphicsScene
       
  1936 {
       
  1937 public:
       
  1938     Qt::Orientation orientation;
       
  1939 
       
  1940     void wheelEvent(QGraphicsSceneWheelEvent *event)
       
  1941     {
       
  1942         orientation = event->orientation();
       
  1943         QGraphicsScene::wheelEvent(event);
       
  1944     }
       
  1945 };
       
  1946 
       
  1947 void tst_QGraphicsView::wheelEvent()
       
  1948 {
       
  1949     // Create a scene with an invalid orientation.
       
  1950     MouseWheelScene scene;
       
  1951     scene.orientation = Qt::Orientation(-1);
       
  1952 
       
  1953     QGraphicsWidget *widget = new QGraphicsWidget;
       
  1954     widget->setGeometry(0, 0, 400, 400);
       
  1955     widget->setFocusPolicy(Qt::WheelFocus);
       
  1956 
       
  1957     EventSpy spy(widget, QEvent::GraphicsSceneWheel);
       
  1958     QCOMPARE(spy.count(), 0);
       
  1959 
       
  1960     scene.addItem(widget);
       
  1961 
       
  1962     // Assign a view.
       
  1963     QGraphicsView view(&scene);
       
  1964     view.show();
       
  1965     QTest::qWaitForWindowShown(&view);
       
  1966     QApplication::setActiveWindow(&view);
       
  1967     QTest::qWait(20);
       
  1968     QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
       
  1969 
       
  1970 
       
  1971     // Send a wheel event with horizontal orientation.
       
  1972     {
       
  1973         QWheelEvent event(view.mapFromScene(widget->boundingRect().center()),
       
  1974                           view.mapToGlobal(view.mapFromScene(widget->boundingRect().center())),
       
  1975                           120, 0, 0, Qt::Horizontal);
       
  1976         QApplication::sendEvent(view.viewport(), &event);
       
  1977         QCOMPARE(scene.orientation, Qt::Horizontal);
       
  1978     }
       
  1979 
       
  1980     // Send a wheel event with vertical orientation.
       
  1981     {
       
  1982         QWheelEvent event(view.mapFromScene(widget->boundingRect().center()),
       
  1983                           view.mapToGlobal(view.mapFromScene(widget->boundingRect().center())),
       
  1984                           120, 0, 0, Qt::Vertical);
       
  1985         QApplication::sendEvent(view.viewport(), &event);
       
  1986         QCOMPARE(scene.orientation, Qt::Vertical);
       
  1987     }
       
  1988 
       
  1989     QCOMPARE(spy.count(), 2);
       
  1990     QVERIFY(widget->hasFocus());
       
  1991 }
       
  1992 
       
  1993 void tst_QGraphicsView::cursor()
       
  1994 {
       
  1995 #ifndef QT_NO_CURSOR
       
  1996 #if defined(Q_OS_WINCE)
       
  1997     QSKIP("Qt/CE does not have regular cursor support", SkipAll);
       
  1998 #endif
       
  1999     QGraphicsScene scene;
       
  2000     QGraphicsItem *item = scene.addRect(QRectF(-10, -10, 20, 20));
       
  2001     item->setCursor(Qt::IBeamCursor);
       
  2002 
       
  2003     QGraphicsView view(&scene);
       
  2004     view.setFixedSize(400, 400);
       
  2005     view.show();
       
  2006     QTest::qWaitForWindowShown(&view);
       
  2007 
       
  2008     QCOMPARE(view.viewport()->cursor().shape(), QCursor().shape());
       
  2009     view.viewport()->setCursor(Qt::PointingHandCursor);
       
  2010     QCOMPARE(view.viewport()->cursor().shape(), Qt::PointingHandCursor);
       
  2011 
       
  2012     sendMouseMove(view.viewport(), view.mapFromScene(0, 0));
       
  2013     QCOMPARE(view.viewport()->cursor().shape(), Qt::IBeamCursor);
       
  2014 
       
  2015     sendMouseMove(view.viewport(), QPoint(5, 5));
       
  2016     QCOMPARE(view.viewport()->cursor().shape(), Qt::PointingHandCursor);
       
  2017 #endif
       
  2018 }
       
  2019 
       
  2020 void tst_QGraphicsView::cursor2()
       
  2021 {
       
  2022 #ifndef QT_NO_CURSOR
       
  2023 #if defined(Q_OS_WINCE)
       
  2024     QSKIP("Qt/CE does not have regular cursor support", SkipAll);
       
  2025 #endif
       
  2026     QGraphicsScene scene;
       
  2027     QGraphicsItem *item = scene.addRect(QRectF(-10, -10, 20, 20));
       
  2028     item->setCursor(Qt::IBeamCursor);
       
  2029     item->setZValue(1);
       
  2030 
       
  2031     QGraphicsItem *item2 = scene.addRect(QRectF(-20, -20, 40, 40));
       
  2032     item2->setZValue(0);
       
  2033 
       
  2034     QGraphicsView view(&scene);
       
  2035     view.viewport()->setCursor(Qt::PointingHandCursor);
       
  2036     view.setFixedSize(400, 400);
       
  2037     view.show();
       
  2038     QTest::qWaitForWindowShown(&view);
       
  2039 
       
  2040     sendMouseMove(view.viewport(), view.mapFromScene(-30, -30));
       
  2041     QCOMPARE(view.viewport()->cursor().shape(), Qt::PointingHandCursor);
       
  2042     sendMouseMove(view.viewport(), view.mapFromScene(0, 0));
       
  2043     QCOMPARE(view.viewport()->cursor().shape(), Qt::IBeamCursor);
       
  2044     sendMouseMove(view.viewport(), view.mapFromScene(-30, -30));
       
  2045     QCOMPARE(view.viewport()->cursor().shape(), Qt::PointingHandCursor);
       
  2046     sendMouseMove(view.viewport(), view.mapFromScene(0, 0));
       
  2047     QCOMPARE(view.viewport()->cursor().shape(), Qt::IBeamCursor);
       
  2048     sendMouseMove(view.viewport(), view.mapFromScene(-15, 0));
       
  2049     QCOMPARE(view.viewport()->cursor().shape(), Qt::PointingHandCursor);
       
  2050 
       
  2051     view.setDragMode(QGraphicsView::ScrollHandDrag);
       
  2052 
       
  2053     sendMouseMove(view.viewport(), view.mapFromScene(-30, -30));
       
  2054     QCOMPARE(view.viewport()->cursor().shape(), Qt::OpenHandCursor);
       
  2055     sendMouseMove(view.viewport(), view.mapFromScene(0, 0));
       
  2056     QCOMPARE(view.viewport()->cursor().shape(), Qt::IBeamCursor);
       
  2057     sendMouseMove(view.viewport(), view.mapFromScene(-15, -15));
       
  2058     QCOMPARE(view.viewport()->cursor().shape(), Qt::OpenHandCursor);
       
  2059 
       
  2060     view.setDragMode(QGraphicsView::NoDrag);
       
  2061     QCOMPARE(view.viewport()->cursor().shape(), Qt::ArrowCursor);
       
  2062     view.viewport()->setCursor(Qt::PointingHandCursor);
       
  2063     QCOMPARE(view.viewport()->cursor().shape(), Qt::PointingHandCursor);
       
  2064 
       
  2065     item2->setCursor(Qt::SizeAllCursor);
       
  2066 
       
  2067     sendMouseMove(view.viewport(), view.mapFromScene(-30, -30));
       
  2068     QCOMPARE(view.viewport()->cursor().shape(), Qt::PointingHandCursor);
       
  2069     sendMouseMove(view.viewport(), view.mapFromScene(-15, -15));
       
  2070     QCOMPARE(view.viewport()->cursor().shape(), Qt::SizeAllCursor);
       
  2071     sendMouseMove(view.viewport(), view.mapFromScene(0, 0));
       
  2072     QCOMPARE(view.viewport()->cursor().shape(), Qt::IBeamCursor);
       
  2073     sendMouseMove(view.viewport(), view.mapFromScene(-15, -15));
       
  2074     QCOMPARE(view.viewport()->cursor().shape(), Qt::SizeAllCursor);
       
  2075     sendMouseMove(view.viewport(), view.mapFromScene(0, 0));
       
  2076     QCOMPARE(view.viewport()->cursor().shape(), Qt::IBeamCursor);
       
  2077     sendMouseMove(view.viewport(), view.mapFromScene(-30, -30));
       
  2078     QCOMPARE(view.viewport()->cursor().shape(), Qt::PointingHandCursor);
       
  2079 
       
  2080     view.setDragMode(QGraphicsView::ScrollHandDrag);
       
  2081 
       
  2082     sendMouseMove(view.viewport(), view.mapFromScene(-30, -30));
       
  2083     QCOMPARE(view.viewport()->cursor().shape(), Qt::OpenHandCursor);
       
  2084     sendMouseMove(view.viewport(), view.mapFromScene(0, 0));
       
  2085     QCOMPARE(view.viewport()->cursor().shape(), Qt::IBeamCursor);
       
  2086     sendMouseMove(view.viewport(), view.mapFromScene(-15, -15));
       
  2087     QCOMPARE(view.viewport()->cursor().shape(), Qt::SizeAllCursor);
       
  2088 #endif
       
  2089 }
       
  2090 
       
  2091 void tst_QGraphicsView::transformationAnchor()
       
  2092 {
       
  2093     QGraphicsScene scene(-1000, -1000, 2000, 2000);
       
  2094     scene.addRect(QRectF(-50, -50, 100, 100), QPen(Qt::black), QBrush(Qt::blue));
       
  2095 
       
  2096     QGraphicsView view(&scene);
       
  2097 
       
  2098     for (int i = 0; i < 2; ++i) {
       
  2099         view.resize(100, 100);
       
  2100         view.show();
       
  2101 
       
  2102         if (i == 0) {
       
  2103             QCOMPARE(view.transformationAnchor(), QGraphicsView::AnchorViewCenter);
       
  2104         } else {
       
  2105             view.setTransformationAnchor(QGraphicsView::NoAnchor);
       
  2106         }
       
  2107         view.centerOn(0, 0);
       
  2108         view.horizontalScrollBar()->setValue(100);
       
  2109         QApplication::processEvents();
       
  2110 
       
  2111         QPointF center = view.mapToScene(view.viewport()->rect().center());
       
  2112 
       
  2113         view.scale(10, 10);
       
  2114 
       
  2115         QPointF newCenter = view.mapToScene(view.viewport()->rect().center());
       
  2116 
       
  2117         if (i == 0) {
       
  2118             qreal slack = 3;
       
  2119             QVERIFY(qAbs(newCenter.x() - center.x()) < slack);
       
  2120             QVERIFY(qAbs(newCenter.y() - center.y()) < slack);
       
  2121         } else {
       
  2122             qreal slack = qreal(0.3);
       
  2123             QVERIFY(qAbs(newCenter.x() - center.x() / 10) < slack);
       
  2124             QVERIFY(qAbs(newCenter.y() - center.y() / 10) < slack);
       
  2125         }
       
  2126     }
       
  2127 }
       
  2128 
       
  2129 void tst_QGraphicsView::resizeAnchor()
       
  2130 {
       
  2131     QGraphicsScene scene(-1000, -1000, 2000, 2000);
       
  2132     scene.addRect(QRectF(-50, -50, 100, 100), QPen(Qt::black), QBrush(Qt::blue));
       
  2133 
       
  2134     QGraphicsView view(&scene);
       
  2135 
       
  2136     for (int i = 0; i < 2; ++i) {
       
  2137         view.resize(100, 100);
       
  2138         view.show();
       
  2139         QTest::qWaitForWindowShown(&view);
       
  2140         QApplication::processEvents();
       
  2141 
       
  2142         if (i == 0) {
       
  2143             QCOMPARE(view.resizeAnchor(), QGraphicsView::NoAnchor);
       
  2144         } else {
       
  2145             view.setResizeAnchor(QGraphicsView::AnchorViewCenter);
       
  2146         }
       
  2147         view.centerOn(0, 0);
       
  2148         QTest::qWait(25);
       
  2149 
       
  2150         QPointF f = view.mapToScene(50, 50);
       
  2151         QPointF center = view.mapToScene(view.viewport()->rect().center());
       
  2152 
       
  2153         QApplication::processEvents();
       
  2154 
       
  2155         for (int size = 200; size <= 400; size += 25) {
       
  2156             view.resize(size, size);
       
  2157             if (i == 0) {
       
  2158                 QTRY_COMPARE(view.mapToScene(50, 50), f);
       
  2159                 QTRY_VERIFY(view.mapToScene(view.viewport()->rect().center()) != center);
       
  2160             } else {
       
  2161                 QTRY_VERIFY(view.mapToScene(50, 50) != f);
       
  2162 
       
  2163                 QPointF newCenter = view.mapToScene(view.viewport()->rect().center());
       
  2164                 int slack = 3;
       
  2165                 QVERIFY(qAbs(newCenter.x() - center.x()) < slack);
       
  2166                 QVERIFY(qAbs(newCenter.y() - center.y()) < slack);
       
  2167             }
       
  2168             QApplication::processEvents();
       
  2169         }
       
  2170     }
       
  2171 }
       
  2172 
       
  2173 class CustomView : public QGraphicsView
       
  2174 {
       
  2175     Q_OBJECT
       
  2176 public:
       
  2177     CustomView(QGraphicsScene *s = 0) : QGraphicsView(s) {}
       
  2178     QList<QRegion> lastUpdateRegions;
       
  2179     bool painted;
       
  2180 
       
  2181 protected:
       
  2182     void paintEvent(QPaintEvent *event)
       
  2183     {
       
  2184         lastUpdateRegions << event->region();
       
  2185         painted = true;
       
  2186         QGraphicsView::paintEvent(event);
       
  2187     }
       
  2188 };
       
  2189 
       
  2190 void tst_QGraphicsView::viewportUpdateMode()
       
  2191 {
       
  2192     QGraphicsScene scene(0, 0, 100, 100);
       
  2193     scene.setBackgroundBrush(Qt::red);
       
  2194 
       
  2195     CustomView view;
       
  2196     view.setFixedSize(500, 500);
       
  2197     view.setScene(&scene);
       
  2198     QCOMPARE(view.viewportUpdateMode(), QGraphicsView::MinimalViewportUpdate);
       
  2199 
       
  2200     // Show the view, and initialize our test.
       
  2201     view.show();
       
  2202     QTest::qWaitForWindowShown(&view);
       
  2203     QTRY_VERIFY(!view.lastUpdateRegions.isEmpty());
       
  2204     view.lastUpdateRegions.clear();
       
  2205 
       
  2206     // Issue two scene updates.
       
  2207     scene.update(QRectF(0, 0, 10, 10));
       
  2208     scene.update(QRectF(20, 0, 10, 10));
       
  2209     QTest::qWait(50);
       
  2210 
       
  2211     // The view gets two updates for the update scene updates.
       
  2212     QTRY_VERIFY(!view.lastUpdateRegions.isEmpty());
       
  2213 #ifndef QT_MAC_USE_COCOA //cocoa doesn't support drawing regions
       
  2214     QCOMPARE(view.lastUpdateRegions.last().rects().size(), 2);
       
  2215     QCOMPARE(view.lastUpdateRegions.last().rects().at(0).size(), QSize(15, 15));
       
  2216     QCOMPARE(view.lastUpdateRegions.last().rects().at(1).size(), QSize(15, 15));
       
  2217 #endif
       
  2218 
       
  2219     // Set full update mode.
       
  2220     view.setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
       
  2221     QCOMPARE(view.viewportUpdateMode(), QGraphicsView::FullViewportUpdate);
       
  2222     view.lastUpdateRegions.clear();
       
  2223 
       
  2224     // Issue two scene updates.
       
  2225     scene.update(QRectF(0, 0, 10, 10));
       
  2226     scene.update(QRectF(20, 0, 10, 10));
       
  2227     qApp->processEvents();
       
  2228     qApp->processEvents();
       
  2229 
       
  2230     // The view gets one full viewport update for the update scene updates.
       
  2231     QCOMPARE(view.lastUpdateRegions.last().rects().size(), 1);
       
  2232     QCOMPARE(view.lastUpdateRegions.last().rects().at(0).size(), view.viewport()->size());
       
  2233     view.lastUpdateRegions.clear();
       
  2234 
       
  2235     // Set smart update mode
       
  2236     view.setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
       
  2237     QCOMPARE(view.viewportUpdateMode(), QGraphicsView::SmartViewportUpdate);
       
  2238 
       
  2239     // Issue 100 mini-updates
       
  2240     for (int i = 0; i < 10; ++i) {
       
  2241         for (int j = 0; j < 10; ++j) {
       
  2242             scene.update(QRectF(i * 3, j * 3, 1, 1));
       
  2243         }
       
  2244     }
       
  2245     qApp->processEvents();
       
  2246     qApp->processEvents();
       
  2247 
       
  2248     // The view gets one bounding rect update.
       
  2249     QCOMPARE(view.lastUpdateRegions.last().rects().size(), 1);
       
  2250     QCOMPARE(view.lastUpdateRegions.last().rects().at(0).size(), QSize(33, 33));
       
  2251 
       
  2252     // Set no update mode
       
  2253     view.setViewportUpdateMode(QGraphicsView::NoViewportUpdate);
       
  2254     QCOMPARE(view.viewportUpdateMode(), QGraphicsView::NoViewportUpdate);
       
  2255 
       
  2256     // Issue two scene updates.
       
  2257     view.lastUpdateRegions.clear();
       
  2258     TestItem item;
       
  2259     scene.addItem(&item);
       
  2260     item.moveBy(10, 10);
       
  2261     scene.update(QRectF(0, 0, 10, 10));
       
  2262     scene.update(QRectF(20, 0, 10, 10));
       
  2263     qApp->processEvents();
       
  2264     qApp->processEvents();
       
  2265 
       
  2266     // The view should not get any painting calls from the scene updates
       
  2267     QCOMPARE(view.lastUpdateRegions.size(), 0);
       
  2268 }
       
  2269 
       
  2270 void tst_QGraphicsView::viewportUpdateMode2()
       
  2271 {
       
  2272     // Create a view with viewport rect equal to QRect(0, 0, 200, 200).
       
  2273     QGraphicsScene dummyScene;
       
  2274     CustomView view;
       
  2275     view.painted = false;
       
  2276     view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
       
  2277     view.setScene(&dummyScene);
       
  2278     int left, top, right, bottom;
       
  2279     view.getContentsMargins(&left, &top, &right, &bottom);
       
  2280     view.resize(200 + left + right, 200 + top + bottom);
       
  2281     view.show();
       
  2282     QTest::qWaitForWindowShown(&view);
       
  2283     QTest::qWait(50);
       
  2284     QTRY_VERIFY(view.painted);
       
  2285     const QRect viewportRect = view.viewport()->rect();
       
  2286     QCOMPARE(viewportRect, QRect(0, 0, 200, 200));
       
  2287 
       
  2288 #if defined QT_BUILD_INTERNAL
       
  2289     QGraphicsViewPrivate *viewPrivate = static_cast<QGraphicsViewPrivate *>(qt_widget_private(&view));
       
  2290 
       
  2291     QRect boundingRect;
       
  2292     const QRect rect1(0, 0, 10, 10);
       
  2293     QVERIFY(viewPrivate->updateRect(rect1));
       
  2294     QVERIFY(!viewPrivate->fullUpdatePending);
       
  2295     boundingRect |= rect1;
       
  2296     QCOMPARE(viewPrivate->dirtyBoundingRect, boundingRect);
       
  2297 
       
  2298     const QRect rect2(50, 50, 10, 10);
       
  2299     QVERIFY(viewPrivate->updateRect(rect2));
       
  2300     QVERIFY(!viewPrivate->fullUpdatePending);
       
  2301     boundingRect |= rect2;
       
  2302     QCOMPARE(viewPrivate->dirtyBoundingRect, boundingRect);
       
  2303 
       
  2304     const QRect rect3(190, 190, 10, 10);
       
  2305     QVERIFY(viewPrivate->updateRect(rect3));
       
  2306     QVERIFY(viewPrivate->fullUpdatePending);
       
  2307     boundingRect |= rect3;
       
  2308     QCOMPARE(viewPrivate->dirtyBoundingRect, boundingRect);
       
  2309 
       
  2310     view.lastUpdateRegions.clear();
       
  2311     viewPrivate->processPendingUpdates();
       
  2312     QTest::qWait(50);
       
  2313     QCOMPARE(view.lastUpdateRegions.size(), 1);
       
  2314     // Note that we adjust by 2 for antialiasing.
       
  2315     QCOMPARE(view.lastUpdateRegions.at(0), QRegion(boundingRect.adjusted(-2, -2, 2, 2) & viewportRect));
       
  2316 #endif
       
  2317 }
       
  2318 
       
  2319 void tst_QGraphicsView::acceptDrops()
       
  2320 {
       
  2321 #ifdef QT_NO_DRAGANDDROP
       
  2322     QSKIP("Drag'n drop disabled in this build", SkipAll);
       
  2323 #else
       
  2324     QGraphicsView view;
       
  2325 
       
  2326     // Excepted default behavior.
       
  2327     QVERIFY(view.acceptDrops());
       
  2328     QVERIFY(view.viewport()->acceptDrops());
       
  2329 
       
  2330     // Excepted behavior with no drops.
       
  2331     view.setAcceptDrops(false);
       
  2332     QVERIFY(!view.acceptDrops());
       
  2333     QVERIFY(!view.viewport()->acceptDrops());
       
  2334 
       
  2335     // Setting a widget with drops on a QGraphicsView without drops.
       
  2336     QWidget *widget = new QWidget;
       
  2337     widget->setAcceptDrops(true);
       
  2338     view.setViewport(widget);
       
  2339     QVERIFY(!view.acceptDrops());
       
  2340     QVERIFY(!view.viewport()->acceptDrops());
       
  2341 
       
  2342     // Switching the view to accept drops.
       
  2343     view.setAcceptDrops(true);
       
  2344     QVERIFY(view.acceptDrops());
       
  2345     QVERIFY(view.viewport()->acceptDrops());
       
  2346 
       
  2347     // Setting a widget with no drops on a QGraphicsView with drops.
       
  2348     widget = new QWidget;
       
  2349     widget->setAcceptDrops(false);
       
  2350     view.setViewport(widget);
       
  2351     QVERIFY(view.viewport()->acceptDrops());
       
  2352     QVERIFY(view.acceptDrops());
       
  2353 
       
  2354     // Switching the view to not accept drops.
       
  2355     view.setAcceptDrops(false);
       
  2356     QVERIFY(!view.viewport()->acceptDrops());
       
  2357 #endif
       
  2358 }
       
  2359 
       
  2360 void tst_QGraphicsView::optimizationFlags()
       
  2361 {
       
  2362     QGraphicsView view;
       
  2363     QVERIFY(!view.optimizationFlags());
       
  2364 
       
  2365     view.setOptimizationFlag(QGraphicsView::DontClipPainter);
       
  2366     QVERIFY(view.optimizationFlags() & QGraphicsView::DontClipPainter);
       
  2367     view.setOptimizationFlag(QGraphicsView::DontClipPainter, false);
       
  2368     QVERIFY(!view.optimizationFlags());
       
  2369 
       
  2370     view.setOptimizationFlag(QGraphicsView::DontSavePainterState);
       
  2371     QVERIFY(view.optimizationFlags() & QGraphicsView::DontSavePainterState);
       
  2372     view.setOptimizationFlag(QGraphicsView::DontSavePainterState, false);
       
  2373     QVERIFY(!view.optimizationFlags());
       
  2374 
       
  2375     view.setOptimizationFlag(QGraphicsView::DontAdjustForAntialiasing);
       
  2376     QVERIFY(view.optimizationFlags() & QGraphicsView::DontAdjustForAntialiasing);
       
  2377     view.setOptimizationFlag(QGraphicsView::DontAdjustForAntialiasing, false);
       
  2378     QVERIFY(!view.optimizationFlags());
       
  2379 
       
  2380     view.setOptimizationFlags(QGraphicsView::DontAdjustForAntialiasing
       
  2381                               | QGraphicsView::DontClipPainter);
       
  2382     QCOMPARE(view.optimizationFlags(), QGraphicsView::OptimizationFlags(QGraphicsView::DontAdjustForAntialiasing
       
  2383              | QGraphicsView::DontClipPainter));
       
  2384 }
       
  2385 
       
  2386 class MessUpPainterItem : public QGraphicsRectItem
       
  2387 {
       
  2388 public:
       
  2389     MessUpPainterItem(const QRectF &rect) : QGraphicsRectItem(rect), dirtyPainter(false)
       
  2390     { }
       
  2391 
       
  2392     bool dirtyPainter;
       
  2393 
       
  2394     void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
       
  2395     {
       
  2396         dirtyPainter = (painter->pen().width() != 0);
       
  2397         painter->setPen(QPen(Qt::black, 1.0));
       
  2398     }
       
  2399 };
       
  2400 
       
  2401 class MyGraphicsView : public QGraphicsView
       
  2402 {
       
  2403 public:
       
  2404       MyGraphicsView(QGraphicsScene * scene) : QGraphicsView(scene)
       
  2405       { }
       
  2406 
       
  2407       void drawBackground(QPainter * painter, const QRectF & rect) {
       
  2408           painter->setCompositionMode(QPainter::CompositionMode_Source);
       
  2409           painter->drawRect(rect);
       
  2410       }
       
  2411 
       
  2412       void drawItems (QPainter * painter, int numItems, QGraphicsItem *items[], const QStyleOptionGraphicsItem options[]) {
       
  2413            if (!(optimizationFlags() & QGraphicsView::DontSavePainterState))
       
  2414                QCOMPARE(painter->compositionMode(),QPainter::CompositionMode_SourceOver);
       
  2415            else
       
  2416                QCOMPARE(painter->compositionMode(),QPainter::CompositionMode_Source);
       
  2417            QGraphicsView::drawItems(painter,numItems,items,options);
       
  2418       }
       
  2419 };
       
  2420 
       
  2421 void tst_QGraphicsView::optimizationFlags_dontSavePainterState()
       
  2422 {
       
  2423     MessUpPainterItem *parent = new MessUpPainterItem(QRectF(0, 0, 100, 100));
       
  2424     MessUpPainterItem *child = new MessUpPainterItem(QRectF(0, 0, 100, 100));
       
  2425     child->setParentItem(parent);
       
  2426 
       
  2427     QGraphicsScene scene;
       
  2428     scene.addItem(parent);
       
  2429 
       
  2430     QGraphicsView view(&scene);
       
  2431     view.show();
       
  2432     QTest::qWaitForWindowShown(&view);
       
  2433     view.viewport()->repaint();
       
  2434 
       
  2435     QVERIFY(!parent->dirtyPainter);
       
  2436     QVERIFY(!child->dirtyPainter);
       
  2437 
       
  2438     view.setOptimizationFlags(QGraphicsView::DontSavePainterState);
       
  2439     view.viewport()->repaint();
       
  2440 
       
  2441 #ifdef Q_WS_MAC
       
  2442     // Repaint on Mac OS X actually does require spinning the event loop.
       
  2443     QTest::qWait(100);
       
  2444 #endif
       
  2445     QVERIFY(!parent->dirtyPainter);
       
  2446     QVERIFY(child->dirtyPainter);
       
  2447 
       
  2448     MyGraphicsView painter(&scene);
       
  2449     painter.show();
       
  2450     QTest::qWaitForWindowShown(&painter);
       
  2451 
       
  2452     MyGraphicsView painter2(&scene);
       
  2453     painter2.setOptimizationFlag(QGraphicsView::DontSavePainterState,true);
       
  2454     painter2.show();
       
  2455     QTest::qWaitForWindowShown(&painter2);
       
  2456 }
       
  2457 
       
  2458 class LodItem : public QGraphicsRectItem
       
  2459 {
       
  2460 public:
       
  2461     LodItem(const QRectF &rect) : QGraphicsRectItem(rect), lastLod(-42)
       
  2462     { }
       
  2463 
       
  2464     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *viewport)
       
  2465     {
       
  2466         lastLod = option->levelOfDetailFromTransform(painter->worldTransform());
       
  2467         QGraphicsRectItem::paint(painter, option, viewport);
       
  2468     }
       
  2469 
       
  2470     qreal lastLod;
       
  2471 };
       
  2472 
       
  2473 void tst_QGraphicsView::levelOfDetail_data()
       
  2474 {
       
  2475     QTest::addColumn<QTransform>("transform");
       
  2476     QTest::addColumn<qreal>("lod");
       
  2477 
       
  2478     QTest::newRow("1:4, 1:4") << QTransform().scale(0.25, 0.25) << qreal(0.25);
       
  2479     QTest::newRow("1:2, 1:4") << QTransform().scale(0.5, 0.25) << qreal(::sqrt(0.125));
       
  2480     QTest::newRow("4:1, 1:2") << QTransform().scale(0.25, 0.5) << qreal(::sqrt(0.125));
       
  2481 
       
  2482     QTest::newRow("1:2, 1:2") << QTransform().scale(0.5, 0.5) << qreal(0.5);
       
  2483     QTest::newRow("1:1, 1:2") << QTransform().scale(1, 0.5) << qreal(::sqrt(0.5));
       
  2484     QTest::newRow("2:1, 1:1") << QTransform().scale(0.5, 1) << qreal(::sqrt(0.5));
       
  2485 
       
  2486     QTest::newRow("1:1, 1:1") << QTransform().scale(1, 1) << qreal(1.0);
       
  2487     QTest::newRow("2:1, 1:1") << QTransform().scale(2, 1) << qreal(::sqrt(2.0));
       
  2488     QTest::newRow("1:1, 2:1") << QTransform().scale(2, 1) << qreal(::sqrt(2.0));
       
  2489     QTest::newRow("2:1, 2:1") << QTransform().scale(2, 2) << qreal(2.0);
       
  2490     QTest::newRow("2:1, 4:1") << QTransform().scale(2, 4) << qreal(::sqrt(8.0));
       
  2491     QTest::newRow("4:1, 2:1") << QTransform().scale(4, 2) << qreal(::sqrt(8.0));
       
  2492     QTest::newRow("4:1, 4:1") << QTransform().scale(4, 4) << qreal(4.0);
       
  2493 }
       
  2494 
       
  2495 void tst_QGraphicsView::levelOfDetail()
       
  2496 {
       
  2497     QFETCH(QTransform, transform);
       
  2498     QFETCH(qreal, lod);
       
  2499 
       
  2500     LodItem *item = new LodItem(QRectF(0, 0, 100, 100));
       
  2501 
       
  2502     QGraphicsScene scene;
       
  2503     scene.addItem(item);
       
  2504 
       
  2505     QGraphicsView view(&scene);
       
  2506     view.show();
       
  2507     QTest::qWaitForWindowShown(&view);
       
  2508 
       
  2509     QTRY_COMPARE(item->lastLod, qreal(1));
       
  2510 
       
  2511     view.setTransform(transform);
       
  2512 
       
  2513     QTRY_COMPARE(item->lastLod, lod);
       
  2514 }
       
  2515 
       
  2516 // Moved to tst_qgraphicsview_2.cpp
       
  2517 extern void _scrollBarRanges_data();
       
  2518 
       
  2519 void tst_QGraphicsView::scrollBarRanges_data()
       
  2520 {
       
  2521     _scrollBarRanges_data();
       
  2522 }
       
  2523 
       
  2524 void tst_QGraphicsView::scrollBarRanges()
       
  2525 {
       
  2526     QFETCH(QSize, viewportSize);
       
  2527     QFETCH(QRectF, sceneRect);
       
  2528     QFETCH(QTransform, transform);
       
  2529     QFETCH(Qt::ScrollBarPolicy, hbarpolicy);
       
  2530     QFETCH(Qt::ScrollBarPolicy, vbarpolicy);
       
  2531     QFETCH(int, hmin);
       
  2532     QFETCH(int, hmax);
       
  2533     QFETCH(int, vmin);
       
  2534     QFETCH(int, vmax);
       
  2535     QFETCH(bool, useMotif);
       
  2536     QFETCH(bool, useStyledPanel);
       
  2537 
       
  2538     QGraphicsScene scene(sceneRect);
       
  2539     scene.addRect(sceneRect, QPen(Qt::blue), QBrush(QColor(Qt::green)));
       
  2540     QGraphicsView view(&scene);
       
  2541     view.setRenderHint(QPainter::Antialiasing);
       
  2542     view.setTransform(transform);
       
  2543     view.setFrameStyle(useStyledPanel ? QFrame::StyledPanel : QFrame::NoFrame);
       
  2544 
       
  2545     if (useMotif) {
       
  2546 #if !defined(QT_NO_STYLE_MOTIF)
       
  2547         view.setStyle(new QMotifStyle);
       
  2548 #else
       
  2549         QSKIP("No Motif style compiled.", SkipSingle);
       
  2550 #endif
       
  2551     } else {
       
  2552 #if defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
       
  2553         view.setStyle(new QWindowsStyle);
       
  2554 #elif !defined(QT_NO_STYLE_PLASTIQUE)
       
  2555         view.setStyle(new QPlastiqueStyle);
       
  2556 #endif
       
  2557     }
       
  2558     view.setStyleSheet(" "); // enables style propagation ;-)
       
  2559 
       
  2560     int adjust = 0;
       
  2561     if (useStyledPanel)
       
  2562         adjust = view.style()->pixelMetric(QStyle::PM_DefaultFrameWidth) * 2;
       
  2563     view.resize(viewportSize + QSize(adjust, adjust));
       
  2564 
       
  2565     view.setHorizontalScrollBarPolicy(hbarpolicy);
       
  2566     view.setVerticalScrollBarPolicy(vbarpolicy);
       
  2567 
       
  2568     view.show();
       
  2569 
       
  2570     QCOMPARE(view.horizontalScrollBar()->minimum(), hmin);
       
  2571     QCOMPARE(view.verticalScrollBar()->minimum(), vmin);
       
  2572     QCOMPARE(view.horizontalScrollBar()->maximum(), hmax);
       
  2573     QCOMPARE(view.verticalScrollBar()->maximum(), vmax);
       
  2574 }
       
  2575 
       
  2576 class TestView : public QGraphicsView
       
  2577 {
       
  2578 public:
       
  2579     TestView(QGraphicsScene *scene)
       
  2580         : QGraphicsView(scene), accepted(false)
       
  2581     { }
       
  2582 
       
  2583     bool accepted;
       
  2584 
       
  2585 protected:
       
  2586     void mousePressEvent(QMouseEvent *event)
       
  2587     {
       
  2588         QGraphicsView::mousePressEvent(event);
       
  2589         accepted = event->isAccepted();
       
  2590     }
       
  2591 };
       
  2592 
       
  2593 void tst_QGraphicsView::acceptMousePressEvent()
       
  2594 {
       
  2595     QGraphicsScene scene;
       
  2596 
       
  2597     TestView view(&scene);
       
  2598     view.show();
       
  2599     QTest::qWaitForWindowShown(&view);
       
  2600 
       
  2601     QMouseEvent event(QEvent::MouseButtonPress,
       
  2602                       view.viewport()->rect().center(),
       
  2603                       view.viewport()->mapToGlobal(view.viewport()->rect().center()),
       
  2604                       Qt::LeftButton, 0, 0);
       
  2605     event.setAccepted(false);
       
  2606     QApplication::sendEvent(view.viewport(), &event);
       
  2607     QVERIFY(!view.accepted);
       
  2608 
       
  2609     scene.addRect(0, 0, 2000, 2000)->setFlag(QGraphicsItem::ItemIsMovable);
       
  2610 
       
  2611     qApp->processEvents(); // ensure scene rect is updated
       
  2612 
       
  2613     QApplication::sendEvent(view.viewport(), &event);
       
  2614     QVERIFY(view.accepted);
       
  2615 }
       
  2616 
       
  2617 void tst_QGraphicsView::replayMouseMove()
       
  2618 {
       
  2619     // An empty scene in a view. The view will send the events to the scene in
       
  2620     // any case. Note that the view doesn't have to be shown - the mouse event
       
  2621     // sending functions below send the events directly to the viewport.
       
  2622     QGraphicsScene scene(-10000, -10000, 20000, 20000);
       
  2623     QGraphicsView view(&scene);
       
  2624 
       
  2625     EventSpy sceneSpy(&scene, QEvent::GraphicsSceneMouseMove);
       
  2626     EventSpy viewSpy(view.viewport(), QEvent::MouseMove);
       
  2627 
       
  2628     sendMousePress(view.viewport(), view.viewport()->rect().center());
       
  2629 
       
  2630     // One mouse event should be translated into one scene event.
       
  2631     for (int i = 0; i < 3; ++i) {
       
  2632         sendMouseMove(view.viewport(), view.viewport()->rect().center(),
       
  2633                       Qt::LeftButton, Qt::MouseButtons(Qt::LeftButton));
       
  2634         QCOMPARE(viewSpy.count(), i + 1);
       
  2635         QCOMPARE(sceneSpy.count(), i + 1);
       
  2636     }
       
  2637 
       
  2638     // When the view is transformed, the view should get no more events.  But
       
  2639     // the scene should get replays.
       
  2640     for (int i = 0; i < 3; ++i) {
       
  2641         view.rotate(10);
       
  2642         QCOMPARE(viewSpy.count(), 3);
       
  2643         QCOMPARE(sceneSpy.count(), 3 + i + 1);
       
  2644     }
       
  2645 
       
  2646     // When the view is scrolled, the view should get no more events.  But the
       
  2647     // scene should get replays.
       
  2648     for (int i = 0; i < 3; ++i) {
       
  2649         view.horizontalScrollBar()->setValue((i + 1) * 10);
       
  2650         QCOMPARE(viewSpy.count(), 3);
       
  2651         QCOMPARE(sceneSpy.count(), 6 + i + 1);
       
  2652     }
       
  2653 }
       
  2654 
       
  2655 void tst_QGraphicsView::itemsUnderMouse()
       
  2656 {
       
  2657    QGraphicsScene scene;
       
  2658    QGraphicsProxyWidget w;
       
  2659    w.setWidget(new QPushButton("W"));
       
  2660    w.resize(50,50);
       
  2661    QGraphicsProxyWidget w2(&w);
       
  2662    w2.setWidget(new QPushButton("W2"));
       
  2663    w2.resize(50,50);
       
  2664    QGraphicsProxyWidget w3(&w2);
       
  2665    w3.setWidget(new QPushButton("W3"));
       
  2666    w3.resize(50,50);
       
  2667    w.setZValue(150);
       
  2668    w2.setZValue(50);
       
  2669    w3.setZValue(0);
       
  2670    scene.addItem(&w);
       
  2671 
       
  2672    QGraphicsView view(&scene);
       
  2673    view.show();
       
  2674    QTest::qWaitForWindowShown(&view);
       
  2675 
       
  2676    QCOMPARE(view.items(view.mapFromScene(w3.boundingRect().center())).first(),
       
  2677             static_cast<QGraphicsItem *>(&w3));
       
  2678    w2.setFlag(QGraphicsItem::ItemIgnoresTransformations, true);
       
  2679    QCOMPARE(view.items(view.mapFromScene(w3.boundingRect().center())).first(),
       
  2680             static_cast<QGraphicsItem *>(&w3));
       
  2681 }
       
  2682 
       
  2683 class QGraphicsTextItem_task172231 : public QGraphicsTextItem
       
  2684 {
       
  2685 public:
       
  2686     QGraphicsTextItem_task172231(const QString & text, QGraphicsItem * parent = 0)
       
  2687         : QGraphicsTextItem(text, parent) {}
       
  2688     QRectF exposedRect;
       
  2689     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
       
  2690     {
       
  2691         exposedRect = option->exposedRect;
       
  2692         QGraphicsTextItem::paint(painter, option, widget);
       
  2693     }
       
  2694 };
       
  2695 
       
  2696 void tst_QGraphicsView::task172231_untransformableItems()
       
  2697 {
       
  2698     // check fix in QGraphicsView::paintEvent()
       
  2699 
       
  2700     QGraphicsScene scene;
       
  2701 
       
  2702     QGraphicsTextItem_task172231 *text =
       
  2703         new QGraphicsTextItem_task172231("abcdefghijklmnopqrstuvwxyz");
       
  2704     text->setFlag(QGraphicsItem::ItemIgnoresTransformations);
       
  2705     scene.addItem(text);
       
  2706 
       
  2707     QGraphicsView view(&scene);
       
  2708 
       
  2709     view.scale(2, 1);
       
  2710     view.show();
       
  2711     QTest::qWaitForWindowShown(&view);
       
  2712     QApplication::setActiveWindow(&view);
       
  2713     QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
       
  2714 
       
  2715     QRectF origExposedRect = text->exposedRect;
       
  2716 
       
  2717     view.resize(int(0.75 * view.width()), view.height());
       
  2718     qApp->processEvents();
       
  2719 
       
  2720     QCOMPARE(text->exposedRect, origExposedRect);
       
  2721 
       
  2722     // notice that the fix also goes into QGraphicsView::render()
       
  2723     // and QGraphicsScene::render(), but in duplicated code that
       
  2724     // is pending a refactoring, so for now we omit autotesting
       
  2725     // these functions separately
       
  2726 }
       
  2727 
       
  2728 class MousePressReleaseScene : public QGraphicsScene
       
  2729 {
       
  2730 public:
       
  2731     MousePressReleaseScene()
       
  2732         : presses(0), releases(0)
       
  2733     { }
       
  2734     int presses;
       
  2735     int releases;
       
  2736 
       
  2737 protected:
       
  2738     void mousePressEvent(QGraphicsSceneMouseEvent *event)
       
  2739     { ++presses; QGraphicsScene::mousePressEvent(event); }
       
  2740     void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
       
  2741     { ++releases; QGraphicsScene::mouseReleaseEvent(event); }
       
  2742 };
       
  2743 
       
  2744 void tst_QGraphicsView::task180429_mouseReleaseDragMode()
       
  2745 {
       
  2746     MousePressReleaseScene scene;
       
  2747 
       
  2748     QGraphicsView view(&scene);
       
  2749     view.show();
       
  2750 
       
  2751     sendMousePress(view.viewport(), view.viewport()->rect().center());
       
  2752     QCOMPARE(scene.presses, 1);
       
  2753     QCOMPARE(scene.releases, 0);
       
  2754     sendMouseRelease(view.viewport(), view.viewport()->rect().center());
       
  2755     QCOMPARE(scene.presses, 1);
       
  2756     QCOMPARE(scene.releases, 1);
       
  2757 
       
  2758     view.setDragMode(QGraphicsView::RubberBandDrag);
       
  2759     sendMousePress(view.viewport(), view.viewport()->rect().center());
       
  2760     QCOMPARE(scene.presses, 2);
       
  2761     QCOMPARE(scene.releases, 1);
       
  2762     sendMouseRelease(view.viewport(), view.viewport()->rect().center());
       
  2763     QCOMPARE(scene.presses, 2);
       
  2764     QCOMPARE(scene.releases, 2);
       
  2765 }
       
  2766 
       
  2767 void tst_QGraphicsView::task187791_setSceneCausesUpdate()
       
  2768 {
       
  2769     QGraphicsScene scene(0, 0, 200, 200);
       
  2770     QGraphicsView view(&scene);
       
  2771     view.show();
       
  2772     QTest::qWaitForWindowShown(&view);
       
  2773 
       
  2774     EventSpy updateSpy(view.viewport(), QEvent::Paint);
       
  2775     QCOMPARE(updateSpy.count(), 0);
       
  2776 
       
  2777     view.setScene(0);
       
  2778     QApplication::processEvents();
       
  2779     QTRY_COMPARE(updateSpy.count(), 1);
       
  2780     view.setScene(&scene);
       
  2781     QApplication::processEvents();
       
  2782     QTRY_COMPARE(updateSpy.count(), 2);
       
  2783 }
       
  2784 
       
  2785 class MouseMoveCounter : public QGraphicsView
       
  2786 {
       
  2787 public:
       
  2788     MouseMoveCounter() : mouseMoves(0)
       
  2789     { }
       
  2790     int mouseMoves;
       
  2791 protected:
       
  2792     void mouseMoveEvent(QMouseEvent *event)
       
  2793     {
       
  2794         ++mouseMoves;
       
  2795         QGraphicsView::mouseMoveEvent(event);
       
  2796         foreach (QGraphicsItem *item, scene()->items()) {
       
  2797             scene()->removeItem(item);
       
  2798             delete item;
       
  2799         }
       
  2800         scene()->addRect(0, 0, 50, 50);
       
  2801         scene()->addRect(0, 0, 100, 100);
       
  2802     }
       
  2803 };
       
  2804 
       
  2805 void tst_QGraphicsView::task186827_deleteReplayedItem()
       
  2806 {
       
  2807     // make sure the mouse is not over the window, causing spontaneous mouse moves
       
  2808     QCursor::setPos(0, 0);
       
  2809 
       
  2810     QGraphicsScene scene;
       
  2811     scene.addRect(0, 0, 50, 50);
       
  2812     scene.addRect(0, 0, 100, 100);
       
  2813 
       
  2814     MouseMoveCounter view;
       
  2815     view.setScene(&scene);
       
  2816     view.show();
       
  2817     QTest::qWaitForWindowShown(&view);
       
  2818     view.viewport()->setMouseTracking(true);
       
  2819 
       
  2820     QCOMPARE(view.mouseMoves, 0);
       
  2821     {
       
  2822         QMouseEvent event(QEvent::MouseMove, view.mapFromScene(25, 25), Qt::NoButton, 0, 0);
       
  2823         QApplication::sendEvent(view.viewport(), &event);
       
  2824     }
       
  2825     QCOMPARE(view.mouseMoves, 1);
       
  2826     QTest::qWait(25);
       
  2827     QTRY_COMPARE(view.mouseMoves, 1);
       
  2828     QTest::qWait(25);
       
  2829     {
       
  2830         QMouseEvent event(QEvent::MouseMove, view.mapFromScene(25, 25), Qt::NoButton, 0, 0);
       
  2831         QApplication::sendEvent(view.viewport(), &event);
       
  2832     }
       
  2833     QCOMPARE(view.mouseMoves, 2);
       
  2834     QTest::qWait(15);
       
  2835 }
       
  2836 
       
  2837 void tst_QGraphicsView::task207546_focusCrash()
       
  2838 {
       
  2839     class _Widget : public QWidget
       
  2840     {
       
  2841     public:
       
  2842         bool focusNextPrevChild(bool next) { return QWidget::focusNextPrevChild(next); }
       
  2843     } widget;
       
  2844 
       
  2845     widget.setLayout(new QVBoxLayout());
       
  2846     QGraphicsView *gr1 = new QGraphicsView(&widget);
       
  2847     QGraphicsView *gr2 = new QGraphicsView(&widget);
       
  2848     widget.layout()->addWidget(gr1);
       
  2849     widget.layout()->addWidget(gr2);
       
  2850     widget.show();
       
  2851     QTest::qWaitForWindowShown(&widget);
       
  2852     widget.activateWindow();
       
  2853     QApplication::setActiveWindow(&widget);
       
  2854     QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&widget));
       
  2855     widget.focusNextPrevChild(true);
       
  2856     QCOMPARE(static_cast<QWidget *>(gr2), widget.focusWidget());
       
  2857 }
       
  2858 
       
  2859 void tst_QGraphicsView::task210599_unsetDragWhileDragging()
       
  2860 {
       
  2861     QGraphicsScene scene(0, 0, 400, 400);
       
  2862     QGraphicsView view(&scene);
       
  2863     view.setGeometry(0, 0, 200, 200);
       
  2864     view.show();
       
  2865 
       
  2866     QPoint origPos = QPoint(100, 100);
       
  2867     QPoint step1Pos = QPoint(100, 110);
       
  2868     QPoint step2Pos = QPoint(100, 120);
       
  2869 
       
  2870     // Enable and do a drag
       
  2871     {
       
  2872         view.setDragMode(QGraphicsView::ScrollHandDrag);
       
  2873         QMouseEvent press(QEvent::MouseButtonPress, origPos, Qt::LeftButton, 0, 0);
       
  2874         QMouseEvent move(QEvent::MouseMove, step1Pos, Qt::LeftButton, 0, 0);
       
  2875         QApplication::sendEvent(view.viewport(), &press);
       
  2876         QApplication::sendEvent(view.viewport(), &move);
       
  2877     }
       
  2878 
       
  2879     // unset drag and release mouse, inverse order
       
  2880     {
       
  2881         view.setDragMode(QGraphicsView::NoDrag);
       
  2882         QMouseEvent release(QEvent::MouseButtonRelease, step1Pos, Qt::LeftButton, 0, 0);
       
  2883         QApplication::sendEvent(view.viewport(), &release);
       
  2884     }
       
  2885 
       
  2886     QPoint basePos = view.mapFromScene(0, 0);
       
  2887 
       
  2888     // reset drag, and move mouse without holding button down.
       
  2889     {
       
  2890         view.setDragMode(QGraphicsView::ScrollHandDrag);
       
  2891         QMouseEvent move(QEvent::MouseMove, step2Pos, Qt::LeftButton, 0, 0);
       
  2892         QApplication::sendEvent(view.viewport(), &move);
       
  2893     }
       
  2894 
       
  2895     // Check that no draggin has occured...
       
  2896     QCOMPARE(basePos, view.mapFromScene(0, 0));
       
  2897 }
       
  2898 
       
  2899 void tst_QGraphicsView::task236394_sendShortcutOverrideEvent()
       
  2900 {
       
  2901     QGraphicsView view;
       
  2902     view.show();
       
  2903     QKeyEvent event(QEvent::ShortcutOverride, Qt::Key_A, 0, QString("A"));
       
  2904     QApplication::sendEvent(&view, &event);
       
  2905 }
       
  2906 
       
  2907 class ChangedListener : public QObject
       
  2908 {
       
  2909     Q_OBJECT
       
  2910 public:
       
  2911     QList<QList<QRectF> > changes;
       
  2912 
       
  2913 public slots:
       
  2914     void changed(const QList<QRectF> &dirty)
       
  2915     {
       
  2916         changes << dirty;
       
  2917     }
       
  2918 };
       
  2919 
       
  2920 void tst_QGraphicsView::task239729_noViewUpdate_data()
       
  2921 {
       
  2922     QTest::addColumn<bool>("a");
       
  2923 
       
  2924     QTest::newRow("a") << false;
       
  2925     QTest::newRow("b") << true;
       
  2926 }
       
  2927 
       
  2928 void tst_QGraphicsView::task239729_noViewUpdate()
       
  2929 {
       
  2930     QFETCH(bool, a);
       
  2931     // The scene's changed signal is connected to something that isn't a view.
       
  2932     QGraphicsScene scene;
       
  2933     ChangedListener cl;
       
  2934     QGraphicsView *view = 0;
       
  2935 
       
  2936     if (a) {
       
  2937         view = new QGraphicsView(&scene);
       
  2938         connect(&scene, SIGNAL(changed(const QList<QRectF> &)), &cl, SLOT(changed(const QList<QRectF> &)));
       
  2939     } else {
       
  2940         connect(&scene, SIGNAL(changed(const QList<QRectF> &)), &cl, SLOT(changed(const QList<QRectF> &)));
       
  2941         view = new QGraphicsView(&scene);
       
  2942     }
       
  2943 
       
  2944     EventSpy spy(view->viewport(), QEvent::Paint);
       
  2945     QCOMPARE(spy.count(), 0);
       
  2946 
       
  2947     view->show();
       
  2948     QTest::qWaitForWindowShown(view);
       
  2949 
       
  2950     QTRY_VERIFY(spy.count() >= 1);
       
  2951     spy.reset();
       
  2952     scene.update();
       
  2953     QApplication::processEvents();
       
  2954     QTRY_COMPARE(spy.count(), 1);
       
  2955 
       
  2956     delete view;
       
  2957 }
       
  2958 
       
  2959 void tst_QGraphicsView::task239047_fitInViewSmallViewport()
       
  2960 {
       
  2961     // Ensure that with a small viewport, fitInView doesn't mirror the
       
  2962     // scene.
       
  2963     QWidget widget;
       
  2964     QGraphicsScene scene;
       
  2965     QGraphicsView *view = new QGraphicsView(&scene, &widget);
       
  2966     view->resize(3, 3);
       
  2967     QCOMPARE(view->size(), QSize(3, 3));
       
  2968     widget.show();
       
  2969     view->fitInView(0, 0, 100, 100);
       
  2970     QPointF topLeft = view->mapToScene(0, 0);
       
  2971     QPointF bottomRight = view->mapToScene(100, 100);
       
  2972     QVERIFY(bottomRight.x() > topLeft.x());
       
  2973     QVERIFY(bottomRight.y() > topLeft.y());
       
  2974 
       
  2975     view->fitInView(0, 0, 0, 100);
       
  2976 
       
  2977     // Don't crash
       
  2978     view->scale(0, 0);
       
  2979     view->fitInView(0, 0, 100, 100);
       
  2980 }
       
  2981 
       
  2982 void tst_QGraphicsView::task245469_itemsAtPointWithClip()
       
  2983 {
       
  2984     QGraphicsScene scene;
       
  2985     QGraphicsItem *parent = scene.addRect(0, 0, 100, 100);
       
  2986     QGraphicsItem *child = new QGraphicsRectItem(40, 40, 20, 20, parent);
       
  2987     parent->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  2988 
       
  2989     QGraphicsView view(&scene);
       
  2990     view.resize(150,150);
       
  2991     view.rotate(90);
       
  2992     view.show();
       
  2993     QTest::qWaitForWindowShown(&view);
       
  2994 
       
  2995     QList<QGraphicsItem *> itemsAtCenter = view.items(view.viewport()->rect().center());
       
  2996     QCOMPARE(itemsAtCenter, (QList<QGraphicsItem *>() << child << parent));
       
  2997 
       
  2998     QPolygonF p = view.mapToScene(QRect(view.viewport()->rect().center(), QSize(1, 1)));
       
  2999     QList<QGraphicsItem *> itemsAtCenter2 = scene.items(p);
       
  3000     QCOMPARE(itemsAtCenter2, itemsAtCenter);
       
  3001 }
       
  3002 
       
  3003 static QGraphicsView *createSimpleViewAndScene()
       
  3004 {
       
  3005     QGraphicsView *view = new QGraphicsView;
       
  3006     QGraphicsScene *scene = new QGraphicsScene;
       
  3007     view->setScene(scene);
       
  3008 
       
  3009     view->setBackgroundBrush(Qt::blue);
       
  3010 
       
  3011     QGraphicsRectItem *rect = scene->addRect(0, 0, 10, 10);
       
  3012     rect->setBrush(Qt::red);
       
  3013     rect->setPen(Qt::NoPen);
       
  3014     return view;
       
  3015 }
       
  3016 
       
  3017 class SpyItem : public QGraphicsRectItem
       
  3018 {
       
  3019 public:
       
  3020     SpyItem()
       
  3021         : QGraphicsRectItem(QRectF(0, 0, 100, 100))
       
  3022     {
       
  3023     }
       
  3024 
       
  3025     void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
       
  3026     {
       
  3027         transform = painter->transform();
       
  3028     }
       
  3029 
       
  3030     QTransform transform;
       
  3031 };
       
  3032 
       
  3033 void tst_QGraphicsView::embeddedViews()
       
  3034 {
       
  3035     QGraphicsView *v1 = createSimpleViewAndScene();
       
  3036     QGraphicsView *v2 = createSimpleViewAndScene();
       
  3037 
       
  3038     QGraphicsProxyWidget *proxy = v1->scene()->addWidget(v2);
       
  3039 
       
  3040     SpyItem *item = new SpyItem;
       
  3041     v2->scene()->addItem(item);
       
  3042 
       
  3043     proxy->translate(5, 5);
       
  3044 
       
  3045     QImage actual(64, 64, QImage::Format_ARGB32_Premultiplied);
       
  3046     actual.fill(0);
       
  3047     v1->QWidget::render(&actual);
       
  3048     QTransform a = item->transform;
       
  3049 
       
  3050     v2->QWidget::render(&actual);
       
  3051     QTransform b = item->transform;
       
  3052 
       
  3053     QVERIFY(a == b);
       
  3054     delete v1;
       
  3055 }
       
  3056 
       
  3057 void tst_QGraphicsView::scrollAfterResize_data()
       
  3058 {
       
  3059     QTest::addColumn<bool>("reverse");
       
  3060     QTest::addColumn<QTransform>("x1");
       
  3061     QTest::addColumn<QTransform>("x2");
       
  3062     QTest::addColumn<QTransform>("x3");
       
  3063 
       
  3064 #if !defined(QT_NO_STYLE_PLASTIQUE)
       
  3065     QPlastiqueStyle style;
       
  3066 #elif !defined(QT_NO_STYLE_WINDOWS)
       
  3067     QWindowsStyle style;
       
  3068 #else
       
  3069     QCommonStyle style;
       
  3070 #endif
       
  3071 
       
  3072     int frameWidth = style.pixelMetric(QStyle::PM_DefaultFrameWidth);
       
  3073     int extent = style.pixelMetric(QStyle::PM_ScrollBarExtent);
       
  3074     int inside = style.styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents);
       
  3075     int viewportWidth = 300;
       
  3076     int scrollBarIndent = viewportWidth - extent - (inside ? 4 : 2)*frameWidth;
       
  3077 
       
  3078     QTest::newRow("normal") << false
       
  3079                             << QTransform()
       
  3080                             << QTransform()
       
  3081                             << QTransform().translate(-10, 0);
       
  3082     QTest::newRow("reverse") << true
       
  3083                              << QTransform().translate(scrollBarIndent, 0)
       
  3084                              << QTransform().translate(scrollBarIndent + 100, 0)
       
  3085                              << QTransform().translate(scrollBarIndent + 110, 0);
       
  3086 }
       
  3087 
       
  3088 void tst_QGraphicsView::scrollAfterResize()
       
  3089 {
       
  3090     QFETCH(bool, reverse);
       
  3091     QFETCH(QTransform, x1);
       
  3092     QFETCH(QTransform, x2);
       
  3093     QFETCH(QTransform, x3);
       
  3094 
       
  3095 #if !defined(QT_NO_STYLE_PLASTIQUE)
       
  3096     QPlastiqueStyle style;
       
  3097 #elif !defined(QT_NO_STYLE_WINDOWS)
       
  3098     QWindowsStyle style;
       
  3099 #else
       
  3100     QCommonStyle style;
       
  3101 #endif
       
  3102     QGraphicsView view;
       
  3103     view.setStyle(&style);
       
  3104     if (reverse)
       
  3105         view.setLayoutDirection(Qt::RightToLeft);
       
  3106 
       
  3107     view.setSceneRect(-1000, -1000, 2000, 2000);
       
  3108     view.resize(300, 300);
       
  3109     view.show();
       
  3110     QTest::qWaitForWindowShown(&view);
       
  3111     view.horizontalScrollBar()->setValue(0);
       
  3112     view.verticalScrollBar()->setValue(0);
       
  3113     QCOMPARE(view.viewportTransform(), x1);
       
  3114     view.resize(400, 300);
       
  3115     QCOMPARE(view.viewportTransform(), x2);
       
  3116     view.horizontalScrollBar()->setValue(10);
       
  3117     QCOMPARE(view.viewportTransform(), x3);
       
  3118 }
       
  3119 
       
  3120 void tst_QGraphicsView::moveItemWhileScrolling_data()
       
  3121 {
       
  3122     QTest::addColumn<bool>("adjustForAntialiasing");
       
  3123 
       
  3124     QTest::newRow("no adjust") << false;
       
  3125     QTest::newRow("adjust") << true;
       
  3126 }
       
  3127 
       
  3128 void tst_QGraphicsView::moveItemWhileScrolling()
       
  3129 {
       
  3130     QFETCH(bool, adjustForAntialiasing);
       
  3131 
       
  3132     class MoveItemScrollView : public QGraphicsView
       
  3133     {
       
  3134     public:
       
  3135         MoveItemScrollView()
       
  3136         {
       
  3137             setWindowFlags(Qt::X11BypassWindowManagerHint);
       
  3138             setScene(new QGraphicsScene(0, 0, 1000, 1000));
       
  3139             rect = scene()->addRect(0, 0, 10, 10);
       
  3140             rect->setPos(50, 50);
       
  3141             painted = false;
       
  3142         }
       
  3143         QRegion lastPaintedRegion;
       
  3144         QGraphicsItem *rect;
       
  3145         bool painted;
       
  3146         void waitForPaintEvent()
       
  3147         {
       
  3148             QTimer::singleShot(2000, &eventLoop, SLOT(quit()));
       
  3149             eventLoop.exec();
       
  3150         }
       
  3151     protected:
       
  3152         QEventLoop eventLoop;
       
  3153         void paintEvent(QPaintEvent *event)
       
  3154         {
       
  3155             painted = true;
       
  3156             lastPaintedRegion = event->region();
       
  3157             QGraphicsView::paintEvent(event);
       
  3158             if (eventLoop.isRunning())
       
  3159                 eventLoop.quit();
       
  3160         }
       
  3161     };
       
  3162 
       
  3163     MoveItemScrollView view;
       
  3164     view.setFrameStyle(0);
       
  3165     view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
  3166     view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
  3167     view.setResizeAnchor(QGraphicsView::NoAnchor);
       
  3168     view.setTransformationAnchor(QGraphicsView::NoAnchor);
       
  3169     if (!adjustForAntialiasing)
       
  3170         view.setOptimizationFlag(QGraphicsView::DontAdjustForAntialiasing);
       
  3171     view.resize(200, 200);
       
  3172     view.painted = false;
       
  3173     view.show();
       
  3174     QTest::qWaitForWindowShown(&view);
       
  3175     QApplication::processEvents();
       
  3176     QTRY_VERIFY(view.painted);
       
  3177     view.painted = false;
       
  3178     view.lastPaintedRegion = QRegion();
       
  3179     view.horizontalScrollBar()->setValue(view.horizontalScrollBar()->value() + 10);
       
  3180     view.rect->moveBy(0, 10);
       
  3181     view.waitForPaintEvent();
       
  3182     QTRY_VERIFY(view.painted);
       
  3183 
       
  3184     QRegion expectedRegion;
       
  3185     expectedRegion += QRect(0, 0, 200, 200);
       
  3186     expectedRegion -= QRect(0, 0, 190, 200);
       
  3187     int a = adjustForAntialiasing ? 2 : 1;
       
  3188     expectedRegion += QRect(40, 50, 10, 10).adjusted(-a, -a, a, a);
       
  3189     expectedRegion += QRect(40, 60, 10, 10).adjusted(-a, -a, a, a);
       
  3190     COMPARE_REGIONS(view.lastPaintedRegion, expectedRegion);
       
  3191 }
       
  3192 
       
  3193 void tst_QGraphicsView::centerOnDirtyItem()
       
  3194 {
       
  3195     QGraphicsView view;
       
  3196     view.setWindowFlags(view.windowFlags() | Qt::WindowStaysOnTopHint);
       
  3197     view.resize(200, 200);
       
  3198 
       
  3199     QGraphicsScene *scene = new QGraphicsScene;
       
  3200     view.setScene(scene);
       
  3201     view.setSceneRect(-1000, -1000, 2000, 2000);
       
  3202 
       
  3203     QGraphicsRectItem *item = new QGraphicsRectItem(0, 0, 10, 10);
       
  3204     item->setBrush(Qt::red);
       
  3205     scene->addItem(item);
       
  3206     view.centerOn(item);
       
  3207 
       
  3208     view.show();
       
  3209     QTest::qWaitForWindowShown(&view);
       
  3210 
       
  3211     QImage before(view.viewport()->size(), QImage::Format_ARGB32);
       
  3212     view.viewport()->render(&before);
       
  3213 
       
  3214     item->setPos(20, 0);
       
  3215     view.centerOn(item);
       
  3216 
       
  3217     QTest::qWait(50);
       
  3218 
       
  3219     QImage after(view.viewport()->size(), QImage::Format_ARGB32);
       
  3220     view.viewport()->render(&after);
       
  3221 
       
  3222     QCOMPARE(before, after);
       
  3223 }
       
  3224 
       
  3225 void tst_QGraphicsView::mouseTracking()
       
  3226 {
       
  3227     // Mouse tracking should only be automatically enabled if items either accept hover events
       
  3228     // or have a cursor set. We never disable mouse tracking if it is already enabled.
       
  3229 
       
  3230     { // Make sure mouse tracking is disabled by default.
       
  3231         QGraphicsScene scene(-10000, -10000, 20000, 20000);
       
  3232         QGraphicsView view(&scene);
       
  3233         QVERIFY(!view.viewport()->hasMouseTracking());
       
  3234     }
       
  3235 
       
  3236     { // Make sure we don't disable mouse tracking in setupViewport/setScene.
       
  3237         QGraphicsView view;
       
  3238         QWidget *viewport = new QWidget;
       
  3239         viewport->setMouseTracking(true);
       
  3240         view.setViewport(viewport);
       
  3241         QVERIFY(viewport->hasMouseTracking());
       
  3242 
       
  3243         QGraphicsScene scene(-10000, -10000, 20000, 20000);
       
  3244         view.setScene(&scene);
       
  3245         QVERIFY(viewport->hasMouseTracking());
       
  3246     }
       
  3247 
       
  3248     // Make sure we enable mouse tracking when having items that accept hover events.
       
  3249     {
       
  3250         // Adding an item to the scene after the scene is set on the view.
       
  3251         QGraphicsScene scene(-10000, -10000, 20000, 20000);
       
  3252         QGraphicsView view(&scene);
       
  3253 
       
  3254         QGraphicsRectItem *item = new QGraphicsRectItem(10, 10, 10, 10);
       
  3255         item->setAcceptHoverEvents(true);
       
  3256         scene.addItem(item);
       
  3257         QVERIFY(view.viewport()->hasMouseTracking());
       
  3258     }
       
  3259     {
       
  3260         // Adding an item to the scene before the scene is set on the view.
       
  3261         QGraphicsScene scene(-10000, -10000, 20000, 20000);
       
  3262         QGraphicsRectItem *item = new QGraphicsRectItem(10, 10, 10, 10);
       
  3263         item->setAcceptHoverEvents(true);
       
  3264         scene.addItem(item);
       
  3265 
       
  3266         QGraphicsView view(&scene);
       
  3267         QVERIFY(view.viewport()->hasMouseTracking());
       
  3268     }
       
  3269     {
       
  3270         // QGraphicsWidget implicitly accepts hover if it has window decoration.
       
  3271         QGraphicsScene scene(-10000, -10000, 20000, 20000);
       
  3272         QGraphicsView view(&scene);
       
  3273 
       
  3274         QGraphicsWidget *widget = new QGraphicsWidget;
       
  3275         scene.addItem(widget);
       
  3276         QVERIFY(!view.viewport()->hasMouseTracking());
       
  3277         // Enable window decoraton.
       
  3278         widget->setWindowFlags(Qt::Window | Qt::WindowTitleHint);
       
  3279         QVERIFY(view.viewport()->hasMouseTracking());
       
  3280     }
       
  3281 
       
  3282     // Make sure we enable mouse tracking when having items with a cursor set.
       
  3283     {
       
  3284         // Adding an item to the scene after the scene is set on the view.
       
  3285         QGraphicsScene scene(-10000, -10000, 20000, 20000);
       
  3286         QGraphicsView view(&scene);
       
  3287 
       
  3288         QGraphicsRectItem *item = new QGraphicsRectItem(10, 10, 10, 10);
       
  3289 #ifndef QT_NO_CURSOR
       
  3290         item->setCursor(Qt::CrossCursor);
       
  3291 #endif
       
  3292         scene.addItem(item);
       
  3293         QVERIFY(view.viewport()->hasMouseTracking());
       
  3294     }
       
  3295     {
       
  3296         // Adding an item to the scene before the scene is set on the view.
       
  3297         QGraphicsScene scene(-10000, -10000, 20000, 20000);
       
  3298         QGraphicsRectItem *item = new QGraphicsRectItem(10, 10, 10, 10);
       
  3299 #ifndef QT_NO_CURSOR
       
  3300         item->setCursor(Qt::CrossCursor);
       
  3301 #endif
       
  3302         scene.addItem(item);
       
  3303 
       
  3304         QGraphicsView view(&scene);
       
  3305         QVERIFY(view.viewport()->hasMouseTracking());
       
  3306     }
       
  3307 
       
  3308     // Make sure we propagate mouse tracking to all views.
       
  3309     {
       
  3310         QGraphicsScene scene(-10000, -10000, 20000, 20000);
       
  3311         QGraphicsView view1(&scene);
       
  3312         QGraphicsView view2(&scene);
       
  3313         QGraphicsView view3(&scene);
       
  3314 
       
  3315         QGraphicsRectItem *item = new QGraphicsRectItem(10, 10, 10, 10);
       
  3316 #ifndef QT_NO_CURSOR
       
  3317         item->setCursor(Qt::CrossCursor);
       
  3318 #endif
       
  3319         scene.addItem(item);
       
  3320 
       
  3321         QVERIFY(view1.viewport()->hasMouseTracking());
       
  3322         QVERIFY(view2.viewport()->hasMouseTracking());
       
  3323         QVERIFY(view3.viewport()->hasMouseTracking());
       
  3324     }
       
  3325 }
       
  3326 
       
  3327 void tst_QGraphicsView::mouseTracking2()
       
  3328 {
       
  3329     // Make sure mouse move events propagates to the scene when
       
  3330     // mouse tracking is explicitly enabled on the view,
       
  3331     // even when all items ignore hover events / use default cursor.
       
  3332 
       
  3333     QGraphicsScene scene;
       
  3334     scene.addRect(0, 0, 100, 100);
       
  3335 
       
  3336     QGraphicsView view(&scene);
       
  3337     view.show();
       
  3338     QTest::qWaitForWindowShown(&view);
       
  3339 
       
  3340     QVERIFY(!view.viewport()->hasMouseTracking());
       
  3341     view.viewport()->setMouseTracking(true); // Explicitly enable mouse tracking.
       
  3342     QVERIFY(view.viewport()->hasMouseTracking());
       
  3343 
       
  3344     EventSpy spy(&scene, QEvent::GraphicsSceneMouseMove);
       
  3345     QCOMPARE(spy.count(), 0);
       
  3346     QMouseEvent event(QEvent::MouseMove,view.viewport()->rect().center(), Qt::NoButton,
       
  3347                       Qt::MouseButtons(Qt::NoButton), 0);
       
  3348     QApplication::sendEvent(view.viewport(), &event);
       
  3349     QCOMPARE(spy.count(), 1);
       
  3350 }
       
  3351 
       
  3352 class RenderTester : public QGraphicsRectItem
       
  3353 {
       
  3354 public:
       
  3355     RenderTester(const QRectF &rect)
       
  3356         : QGraphicsRectItem(rect), paints(0)
       
  3357     { }
       
  3358 
       
  3359     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
       
  3360                QWidget *widget)
       
  3361     {
       
  3362         QGraphicsRectItem::paint(painter, option, widget);
       
  3363         ++paints;
       
  3364     }
       
  3365 
       
  3366     int paints;
       
  3367 };
       
  3368 
       
  3369 void tst_QGraphicsView::render()
       
  3370 {
       
  3371     // ### This test can be much more thorough - see QGraphicsScene::render.
       
  3372     QGraphicsScene scene;
       
  3373     CustomView view(&scene);
       
  3374     view.setFrameStyle(0);
       
  3375     view.resize(200, 200);
       
  3376     view.painted = false;
       
  3377     view.show();
       
  3378     QTest::qWaitForWindowShown(&view);
       
  3379     QApplication::processEvents();
       
  3380     QTRY_VERIFY(view.painted > 0);
       
  3381 
       
  3382     RenderTester *r1 = new RenderTester(QRectF(0, 0, 50, 50));
       
  3383     RenderTester *r2 = new RenderTester(QRectF(50, 50, 50, 50));
       
  3384     RenderTester *r3 = new RenderTester(QRectF(0, 50, 50, 50));
       
  3385     RenderTester *r4 = new RenderTester(QRectF(50, 0, 50, 50));
       
  3386     scene.addItem(r1);
       
  3387     scene.addItem(r2);
       
  3388     scene.addItem(r3);
       
  3389     scene.addItem(r4);
       
  3390 
       
  3391     qApp->processEvents();
       
  3392 
       
  3393     QTRY_COMPARE(r1->paints, 1);
       
  3394     QCOMPARE(r2->paints, 1);
       
  3395     QCOMPARE(r3->paints, 1);
       
  3396     QCOMPARE(r4->paints, 1);
       
  3397 
       
  3398     QPixmap pix(200, 200);
       
  3399     pix.fill(Qt::transparent);
       
  3400     QPainter painter(&pix);
       
  3401     view.render(&painter);
       
  3402     painter.end();
       
  3403 
       
  3404     QCOMPARE(r1->paints, 2);
       
  3405     QCOMPARE(r2->paints, 2);
       
  3406     QCOMPARE(r3->paints, 2);
       
  3407     QCOMPARE(r4->paints, 2);
       
  3408 }
       
  3409 
       
  3410 void tst_QGraphicsView::exposeRegion()
       
  3411 {
       
  3412     RenderTester *item = new RenderTester(QRectF(0, 0, 20, 20));
       
  3413     QGraphicsScene scene;
       
  3414     scene.addItem(item);
       
  3415 
       
  3416     item->paints = 0;
       
  3417     CustomView view;
       
  3418     view.setScene(&scene);
       
  3419     view.show();
       
  3420     QTest::qWaitForWindowShown(&view);
       
  3421     QTRY_VERIFY(item->paints > 0);
       
  3422 
       
  3423     item->paints = 0;
       
  3424     view.lastUpdateRegions.clear();
       
  3425 
       
  3426     // Update a small area in the viewport's topLeft() and bottomRight().
       
  3427     // (the boundingRect() of this area covers the entire viewport).
       
  3428     QWidget *viewport = view.viewport();
       
  3429     QRegion expectedExposeRegion = QRect(0, 0, 5, 5);
       
  3430     expectedExposeRegion += QRect(viewport->rect().bottomRight() - QPoint(5, 5), QSize(5, 5));
       
  3431     viewport->update(expectedExposeRegion);
       
  3432     QApplication::processEvents();
       
  3433 
       
  3434     // Make sure it triggers correct repaint on the view.
       
  3435     QTRY_COMPARE(view.lastUpdateRegions.size(), 1);
       
  3436     COMPARE_REGIONS(view.lastUpdateRegions.at(0), expectedExposeRegion);
       
  3437 
       
  3438     // Make sure the item didn't get any repaints.
       
  3439 #ifndef QT_MAC_USE_COCOA
       
  3440     QCOMPARE(item->paints, 0);
       
  3441 #endif
       
  3442 }
       
  3443 
       
  3444 void tst_QGraphicsView::update_data()
       
  3445 {
       
  3446     // In view.viewport() coordinates. (viewport rect: QRect(0, 0, 200, 200))
       
  3447     QTest::addColumn<QRect>("updateRect");
       
  3448     QTest::newRow("empty") << QRect();
       
  3449     QTest::newRow("outside left") << QRect(-200, 0, 100, 100);
       
  3450     QTest::newRow("outside right") << QRect(400, 0 ,100, 100);
       
  3451     QTest::newRow("outside top") << QRect(0, -200, 100, 100);
       
  3452     QTest::newRow("outside bottom") << QRect(0, 400, 100, 100);
       
  3453     QTest::newRow("partially inside left") << QRect(-50, 0, 100, 100);
       
  3454     QTest::newRow("partially inside right") << QRect(-150, 0, 100, 100);
       
  3455     QTest::newRow("partially inside top") << QRect(0, -150, 100, 100);
       
  3456     QTest::newRow("partially inside bottom") << QRect(0, 150, 100, 100);
       
  3457     QTest::newRow("on topLeft edge") << QRect(-100, -100, 100, 100);
       
  3458     QTest::newRow("on topRight edge") << QRect(200, -100, 100, 100);
       
  3459     QTest::newRow("on bottomRight edge") << QRect(200, 200, 100, 100);
       
  3460     QTest::newRow("on bottomLeft edge") << QRect(-200, 200, 100, 100);
       
  3461     QTest::newRow("inside topLeft") << QRect(-99, -99, 100, 100);
       
  3462     QTest::newRow("inside topRight") << QRect(199, -99, 100, 100);
       
  3463     QTest::newRow("inside bottomRight") << QRect(199, 199, 100, 100);
       
  3464     QTest::newRow("inside bottomLeft") << QRect(-199, 199, 100, 100);
       
  3465     QTest::newRow("large1") << QRect(50, -100, 100, 400);
       
  3466     QTest::newRow("large2") << QRect(-100, 50, 400, 100);
       
  3467     QTest::newRow("large3") << QRect(-100, -100, 400, 400);
       
  3468     QTest::newRow("viewport rect") << QRect(0, 0, 200, 200);
       
  3469 }
       
  3470 
       
  3471 void tst_QGraphicsView::update()
       
  3472 {
       
  3473     QFETCH(QRect, updateRect);
       
  3474 
       
  3475     // Create a view with viewport rect equal to QRect(0, 0, 200, 200).
       
  3476     QGraphicsScene dummyScene;
       
  3477     CustomView view;
       
  3478     view.setScene(&dummyScene);
       
  3479     int left, top, right, bottom;
       
  3480     view.getContentsMargins(&left, &top, &right, &bottom);
       
  3481     view.resize(200 + left + right, 200 + top + bottom);
       
  3482     view.show();
       
  3483     QTest::qWaitForWindowShown(&view);
       
  3484 
       
  3485     QApplication::setActiveWindow(&view);
       
  3486     QApplication::processEvents();
       
  3487     QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
       
  3488 
       
  3489     const QRect viewportRect = view.viewport()->rect();
       
  3490     QCOMPARE(viewportRect, QRect(0, 0, 200, 200));
       
  3491 
       
  3492 #if defined QT_BUILD_INTERNAL
       
  3493     const bool intersects = updateRect.intersects(viewportRect);
       
  3494     QGraphicsViewPrivate *viewPrivate = static_cast<QGraphicsViewPrivate *>(qt_widget_private(&view));
       
  3495     QTRY_COMPARE(viewPrivate->updateRect(updateRect), intersects);
       
  3496     QCOMPARE(viewPrivate->updateRegion(updateRect), intersects);
       
  3497 
       
  3498     view.lastUpdateRegions.clear();
       
  3499     viewPrivate->processPendingUpdates();
       
  3500     QVERIFY(viewPrivate->dirtyRegion.isEmpty());
       
  3501     QVERIFY(viewPrivate->dirtyBoundingRect.isEmpty());
       
  3502     QApplication::processEvents();
       
  3503     if (!intersects) {
       
  3504         QTRY_VERIFY(view.lastUpdateRegions.isEmpty());
       
  3505     } else {
       
  3506         QTRY_COMPARE(view.lastUpdateRegions.size(), 1);
       
  3507         // Note that we adjust by 2 for antialiasing.
       
  3508         QTRY_COMPARE(view.lastUpdateRegions.at(0), QRegion(updateRect.adjusted(-2, -2, 2, 2) & viewportRect));
       
  3509     }
       
  3510     QTRY_VERIFY(!viewPrivate->fullUpdatePending);
       
  3511 #endif
       
  3512 }
       
  3513 
       
  3514 void tst_QGraphicsView::inputMethodSensitivity()
       
  3515 {
       
  3516     QGraphicsScene scene;
       
  3517     QGraphicsView view(&scene);
       
  3518     view.show();
       
  3519     QTest::qWaitForWindowShown(&view);
       
  3520     QApplication::setActiveWindow(&view);
       
  3521     QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
       
  3522 
       
  3523     QGraphicsRectItem *item = new QGraphicsRectItem;
       
  3524 
       
  3525     view.setAttribute(Qt::WA_InputMethodEnabled, true);
       
  3526 
       
  3527     scene.addItem(item);
       
  3528     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false);
       
  3529 
       
  3530     scene.removeItem(item);
       
  3531     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false);
       
  3532 
       
  3533     item->setFlag(QGraphicsItem::ItemAcceptsInputMethod);
       
  3534     scene.addItem(item);
       
  3535     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false);
       
  3536 
       
  3537     scene.removeItem(item);
       
  3538     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false);
       
  3539 
       
  3540     scene.addItem(item);
       
  3541     scene.setFocusItem(item);
       
  3542     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false);
       
  3543 
       
  3544     scene.removeItem(item);
       
  3545     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false);
       
  3546 
       
  3547     item->setFlag(QGraphicsItem::ItemIsFocusable);
       
  3548     scene.addItem(item);
       
  3549     scene.setFocusItem(item);
       
  3550     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true);
       
  3551 
       
  3552     item->setFlag(QGraphicsItem::ItemAcceptsInputMethod, false);
       
  3553     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false);
       
  3554 
       
  3555     item->setFlag(QGraphicsItem::ItemAcceptsInputMethod, true);
       
  3556     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true);
       
  3557 
       
  3558     // introduce another item that is focusable but does not accept input methods
       
  3559     QGraphicsRectItem *item2 = new QGraphicsRectItem;
       
  3560     item2->setFlag(QGraphicsItem::ItemIsFocusable);
       
  3561     scene.addItem(item2);
       
  3562     scene.setFocusItem(item2);
       
  3563     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false);
       
  3564 
       
  3565     scene.setFocusItem(item);
       
  3566     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true);
       
  3567 
       
  3568     view.setScene(0);
       
  3569     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false);
       
  3570 
       
  3571     view.setScene(&scene);
       
  3572     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true);
       
  3573 
       
  3574     scene.setFocusItem(item2);
       
  3575     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false);
       
  3576 
       
  3577     view.setScene(0);
       
  3578     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false);
       
  3579 
       
  3580     scene.setFocusItem(item);
       
  3581     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), false);
       
  3582 
       
  3583     view.setScene(&scene);
       
  3584     QCOMPARE(view.testAttribute(Qt::WA_InputMethodEnabled), true);
       
  3585 }
       
  3586 
       
  3587 class InputContextTester : public QInputContext
       
  3588 {
       
  3589     Q_OBJECT
       
  3590 public:
       
  3591     QString identifierName() { return QString(); }
       
  3592     bool isComposing() const { return false; }
       
  3593     QString language() { return QString(); }
       
  3594     void reset() { ++resets; }
       
  3595     int resets;
       
  3596 };
       
  3597 
       
  3598 void tst_QGraphicsView::inputContextReset()
       
  3599 {
       
  3600     QGraphicsScene scene;
       
  3601     QGraphicsView view(&scene);
       
  3602     QVERIFY(view.testAttribute(Qt::WA_InputMethodEnabled));
       
  3603 
       
  3604     InputContextTester inputContext;
       
  3605     view.setInputContext(&inputContext);
       
  3606 
       
  3607     view.show();
       
  3608     QTest::qWaitForWindowShown(&view);
       
  3609     QApplication::setActiveWindow(&view);
       
  3610     QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&view));
       
  3611 
       
  3612     QGraphicsItem *item1 = new QGraphicsRectItem;
       
  3613     item1->setFlags(QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemAcceptsInputMethod);
       
  3614 
       
  3615     inputContext.resets = 0;
       
  3616     scene.addItem(item1);
       
  3617     QCOMPARE(inputContext.resets, 0);
       
  3618 
       
  3619     inputContext.resets = 0;
       
  3620     scene.setFocusItem(item1);
       
  3621     QCOMPARE(scene.focusItem(), (QGraphicsItem *)item1);
       
  3622     QVERIFY(view.testAttribute(Qt::WA_InputMethodEnabled));
       
  3623     QCOMPARE(inputContext.resets, 0);
       
  3624 
       
  3625     inputContext.resets = 0;
       
  3626     scene.setFocusItem(0);
       
  3627     QCOMPARE(inputContext.resets, 1);
       
  3628 
       
  3629     // introduce another item that is focusable but does not accept input methods
       
  3630     QGraphicsItem *item2 = new QGraphicsRectItem;
       
  3631     item1->setFlags(QGraphicsItem::ItemIsFocusable);
       
  3632 
       
  3633     inputContext.resets = 0;
       
  3634     scene.setFocusItem(item2);
       
  3635     QCOMPARE(inputContext.resets, 0);
       
  3636 
       
  3637     inputContext.resets = 0;
       
  3638     scene.setFocusItem(item1);
       
  3639     QCOMPARE(inputContext.resets, 0);
       
  3640 }
       
  3641 
       
  3642 void tst_QGraphicsView::task253415_reconnectUpdateSceneOnSceneChanged()
       
  3643 {
       
  3644     QGraphicsView view;
       
  3645     QGraphicsView dummyView;
       
  3646     view.setWindowFlags(view.windowFlags() | Qt::WindowStaysOnTopHint);
       
  3647     view.resize(200, 200);
       
  3648 
       
  3649     QGraphicsScene scene1;
       
  3650     QObject::connect(&scene1, SIGNAL(changed(QList<QRectF>)), &dummyView, SLOT(updateScene(QList<QRectF>)));
       
  3651     view.setScene(&scene1);
       
  3652 
       
  3653     QTest::qWait(12);
       
  3654 
       
  3655     QGraphicsScene scene2;
       
  3656     QObject::connect(&scene2, SIGNAL(changed(QList<QRectF>)), &dummyView, SLOT(updateScene(QList<QRectF>)));
       
  3657     view.setScene(&scene2);
       
  3658 
       
  3659     QTest::qWait(12);
       
  3660 
       
  3661     bool wasConnected2 = QObject::disconnect(&scene2, SIGNAL(changed(QList<QRectF>)), &view, 0);
       
  3662     QVERIFY(wasConnected2);
       
  3663 }
       
  3664 
       
  3665 void tst_QGraphicsView::task255529_transformationAnchorMouseAndViewportMargins()
       
  3666 {
       
  3667 #if defined(Q_OS_WINCE)
       
  3668     QSKIP("Qt/CE does not implement mouse tracking at this point", SkipAll);
       
  3669 #endif
       
  3670 
       
  3671     QGraphicsScene scene(-100, -100, 200, 200);
       
  3672     scene.addRect(QRectF(-50, -50, 100, 100), QPen(Qt::black), QBrush(Qt::blue));
       
  3673 
       
  3674     class VpGraphicsView: public QGraphicsView
       
  3675     {
       
  3676     public:
       
  3677         VpGraphicsView(QGraphicsScene *scene)
       
  3678             : QGraphicsView(scene)
       
  3679         {
       
  3680             setViewportMargins(8, 16, 12, 20);
       
  3681             setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
       
  3682             setMouseTracking(true);
       
  3683         }
       
  3684     };
       
  3685 
       
  3686     VpGraphicsView view(&scene);
       
  3687     view.setWindowFlags(Qt::X11BypassWindowManagerHint);
       
  3688     view.show();
       
  3689     QTest::qWaitForWindowShown(&view);
       
  3690     QTest::qWait(50);
       
  3691     QPoint mouseViewPos(20, 20);
       
  3692     sendMouseMove(view.viewport(), mouseViewPos);
       
  3693 
       
  3694     QPointF mouseScenePos = view.mapToScene(mouseViewPos);
       
  3695     view.setTransform(QTransform().scale(5, 5).rotate(5, Qt::ZAxis), true);
       
  3696 
       
  3697     QPointF newMouseScenePos = view.mapToScene(mouseViewPos);
       
  3698 
       
  3699     qreal slack = 1;
       
  3700     QVERIFY(qAbs(newMouseScenePos.x() - mouseScenePos.x()) < slack);
       
  3701     QVERIFY(qAbs(newMouseScenePos.y() - mouseScenePos.y()) < slack);
       
  3702 }
       
  3703 
       
  3704 void tst_QGraphicsView::task259503_scrollingArtifacts()
       
  3705 {
       
  3706     QGraphicsScene scene(0, 0, 800, 600);
       
  3707 
       
  3708     QGraphicsRectItem card;
       
  3709     card.setRect(0, 0, 50, 50);
       
  3710     card.setPen(QPen(Qt::darkRed));
       
  3711     card.setBrush(QBrush(Qt::cyan));
       
  3712     card.setZValue(2.0);
       
  3713     card.setPos(300, 300);
       
  3714     scene.addItem(&card);
       
  3715 
       
  3716     class SAGraphicsView: public QGraphicsView
       
  3717     {
       
  3718     public:
       
  3719         SAGraphicsView(QGraphicsScene *scene)
       
  3720             : QGraphicsView(scene)
       
  3721             , itSTimeToTest(false)
       
  3722         {
       
  3723             setViewportUpdateMode( QGraphicsView::MinimalViewportUpdate );
       
  3724             resize(QSize(640, 480));
       
  3725         }
       
  3726 
       
  3727         QRegion updateRegion;
       
  3728         bool itSTimeToTest;
       
  3729 
       
  3730         void paintEvent(QPaintEvent *event)
       
  3731         {
       
  3732             QGraphicsView::paintEvent(event);
       
  3733 
       
  3734             if (itSTimeToTest)
       
  3735             {
       
  3736 //                qDebug() << event->region();
       
  3737 //                qDebug() << updateRegion;
       
  3738                 QEXPECT_FAIL("", "The event region doesn't include the original item position region. See task #259503.", Continue);
       
  3739                 QCOMPARE(event->region(), updateRegion);
       
  3740             }
       
  3741         }
       
  3742     };
       
  3743 
       
  3744     SAGraphicsView view(&scene);
       
  3745     view.show();
       
  3746     QTest::qWaitForWindowShown(&view);
       
  3747 
       
  3748     int hsbValue = view.horizontalScrollBar()->value();
       
  3749     view.horizontalScrollBar()->setValue(hsbValue / 2);
       
  3750     QTest::qWait(10);
       
  3751     view.horizontalScrollBar()->setValue(0);
       
  3752     QTest::qWait(10);
       
  3753 
       
  3754     QRect itemDeviceBoundingRect = card.deviceTransform(view.viewportTransform()).mapRect(card.boundingRect()).toRect();
       
  3755     itemDeviceBoundingRect.adjust(-2, -2, 2, 2);
       
  3756     view.updateRegion = itemDeviceBoundingRect;
       
  3757     view.updateRegion += itemDeviceBoundingRect.translated(-100, 0);
       
  3758     view.itSTimeToTest = true;
       
  3759     card.setPos(200, 300);
       
  3760     QTest::qWait(10);
       
  3761 }
       
  3762 
       
  3763 void tst_QGraphicsView::QTBUG_4151_clipAndIgnore_data()
       
  3764 {
       
  3765     QTest::addColumn<bool>("clip");
       
  3766     QTest::addColumn<bool>("ignoreTransformations");
       
  3767     QTest::addColumn<int>("numItems");
       
  3768 
       
  3769     QTest::newRow("none") << false << false << 3;
       
  3770     QTest::newRow("clip") << true << false << 3;
       
  3771     QTest::newRow("ignore") << false << true << 3;
       
  3772     QTest::newRow("clip+ignore") << true << true << 3;
       
  3773 }
       
  3774 
       
  3775 void tst_QGraphicsView::QTBUG_4151_clipAndIgnore()
       
  3776 {
       
  3777     QFETCH(bool, clip);
       
  3778     QFETCH(bool, ignoreTransformations);
       
  3779     QFETCH(int, numItems);
       
  3780 
       
  3781     QGraphicsScene scene;
       
  3782 
       
  3783     QGraphicsRectItem *parent = new QGraphicsRectItem(QRectF(0, 0, 50, 50), 0);
       
  3784     QGraphicsRectItem *child = new QGraphicsRectItem(QRectF(-10, -10, 40, 40), parent);
       
  3785     QGraphicsRectItem *ignore = new QGraphicsRectItem(QRectF(60, 60, 50, 50), 0);
       
  3786 
       
  3787     if (clip)
       
  3788         parent->setFlags(QGraphicsItem::ItemClipsChildrenToShape);
       
  3789     if (ignoreTransformations)
       
  3790         ignore->setFlag(QGraphicsItem::ItemIgnoresTransformations);
       
  3791 
       
  3792     parent->setBrush(Qt::red);
       
  3793     child->setBrush(QColor(0, 0, 255, 128));
       
  3794     ignore->setBrush(Qt::green);
       
  3795 
       
  3796     scene.addItem(parent);
       
  3797     scene.addItem(ignore);
       
  3798 
       
  3799     QGraphicsView view(&scene);
       
  3800     view.setFrameStyle(0);
       
  3801     view.resize(75, 75);
       
  3802     view.show();
       
  3803     QTRY_COMPARE(QApplication::activeWindow(), (QWidget *)&view);
       
  3804 
       
  3805     QCOMPARE(view.items(view.rect()).size(), numItems);
       
  3806 }
       
  3807 
       
  3808 QTEST_MAIN(tst_QGraphicsView)
       
  3809 #include "tst_qgraphicsview.moc"