tests/auto/qgraphicswidget/tst_qgraphicswidget.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 #include <qgraphicswidget.h>
       
    45 #include <qgraphicsscene.h>
       
    46 #include <qgraphicssceneevent.h>
       
    47 #include <qgraphicsview.h>
       
    48 #include <qstyleoption.h>
       
    49 #include <qgraphicslinearlayout.h>
       
    50 #include <qcleanlooksstyle.h>
       
    51 #include <qlineedit.h>
       
    52 #include <qboxlayout.h>
       
    53 #include <qaction.h>
       
    54 #include <qwidgetaction.h>
       
    55 #include "../../shared/util.h"
       
    56 
       
    57 
       
    58 class EventSpy : public QObject
       
    59 {
       
    60     Q_OBJECT
       
    61 public:
       
    62     EventSpy(QObject *watched, QEvent::Type type)
       
    63         : _count(0), spied(type)
       
    64     {
       
    65         watched->installEventFilter(this);
       
    66     }
       
    67 
       
    68     int count() const { return _count; }
       
    69 
       
    70 protected:
       
    71     bool eventFilter(QObject *watched, QEvent *event)
       
    72     {
       
    73         Q_UNUSED(watched);
       
    74         if (event->type() == spied)
       
    75             ++_count;
       
    76         return false;
       
    77     }
       
    78 
       
    79     int _count;
       
    80     QEvent::Type spied;
       
    81 };
       
    82 
       
    83 #ifndef QT_NO_STYLE_CLEANLOOKS
       
    84 class tst_QGraphicsWidget : public QObject {
       
    85 Q_OBJECT
       
    86 
       
    87 public slots:
       
    88     void initTestCase();
       
    89     void cleanupTestCase();
       
    90     void init();
       
    91     void cleanup();
       
    92 
       
    93 private slots:
       
    94     void qgraphicswidget();
       
    95 
       
    96     void activation();
       
    97     void boundingRect_data();
       
    98     void boundingRect();
       
    99     void dumpFocusChain_data();
       
   100     void dumpFocusChain();
       
   101     void focusWidget_data();
       
   102     void focusWidget();
       
   103     void focusWidget2();
       
   104     void focusPolicy_data();
       
   105     void focusPolicy();
       
   106     void font_data();
       
   107     void font();
       
   108     void fontPropagation();
       
   109     void fontPropagationWidgetItemWidget();
       
   110     void fontPropagationSceneChange();
       
   111     void geometry_data();
       
   112     void geometry();
       
   113     void getContentsMargins_data();
       
   114     void getContentsMargins();
       
   115     void initStyleOption_data();
       
   116     void initStyleOption();
       
   117     void layout_data();
       
   118     void layout();
       
   119     void layoutDirection_data();
       
   120     void layoutDirection();
       
   121     void paint_data();
       
   122     void paint();
       
   123     void palettePropagation();
       
   124     void parentWidget_data();
       
   125     void parentWidget();
       
   126     void resize_data();
       
   127     void resize();
       
   128     void setAttribute_data();
       
   129     void setAttribute();
       
   130     void setStyle_data();
       
   131     void setStyle();
       
   132     void setTabOrder_data();
       
   133     void setTabOrder();
       
   134     void setTabOrderAndReparent();
       
   135     void topLevelWidget_data();
       
   136     void topLevelWidget();
       
   137     void unsetLayoutDirection_data();
       
   138     void unsetLayoutDirection();
       
   139     void focusNextPrevChild_data();
       
   140     void focusNextPrevChild();
       
   141     void verifyFocusChain();
       
   142     void updateFocusChainWhenChildDie();
       
   143     void sizeHint_data();
       
   144     void sizeHint();
       
   145     void consistentPosSizeGeometry_data();
       
   146     void consistentPosSizeGeometry();
       
   147     void setSizes_data();
       
   148     void setSizes();
       
   149     void closePopupOnOutsideClick();
       
   150     void defaultSize();
       
   151     void explicitMouseGrabber();
       
   152     void implicitMouseGrabber();
       
   153     void doubleClickAfterExplicitMouseGrab();
       
   154     void popupMouseGrabber();
       
   155     void windowFlags_data();
       
   156     void windowFlags();
       
   157     void shortcutsDeletion();
       
   158     void painterStateProtectionOnWindowFrame();
       
   159     void ensureClipping();
       
   160     void widgetSendsGeometryChanges();
       
   161     void respectHFW();
       
   162     void addChildInpolishEvent();
       
   163 
       
   164     // Task fixes
       
   165     void task236127_bspTreeIndexFails();
       
   166     void task243004_setStyleCrash();
       
   167     void task250119_shortcutContext();
       
   168 };
       
   169 
       
   170 
       
   171 static void sendMouseMove(QWidget *widget, const QPoint &point, Qt::MouseButton button = Qt::NoButton, Qt::MouseButtons buttons = 0)
       
   172 {
       
   173     QTest::mouseMove(widget, point);
       
   174     QMouseEvent event(QEvent::MouseMove, point, button, buttons, 0);
       
   175     QApplication::sendEvent(widget, &event);
       
   176 }
       
   177 
       
   178 // Subclass that exposes the protected functions.
       
   179 class SubQGraphicsWidget : public QGraphicsWidget {
       
   180 public:
       
   181     SubQGraphicsWidget(QGraphicsItem *parent = 0, Qt::WindowFlags windowFlags = 0)
       
   182         : QGraphicsWidget(parent, windowFlags), eventCount(0)
       
   183         { }
       
   184 
       
   185     void initStyleOption(QStyleOption *option)
       
   186         { QGraphicsWidget::initStyleOption(option); }
       
   187 
       
   188     void call_changeEvent(QEvent* event)
       
   189         { return QGraphicsWidget::changeEvent(event); }
       
   190 
       
   191     bool call_event(QEvent *e)
       
   192         { return event(e); }
       
   193 
       
   194     void call_focusInEvent(QFocusEvent* event)
       
   195         { return QGraphicsWidget::focusInEvent(event); }
       
   196 
       
   197     bool call_focusNextPrevChild(bool next)
       
   198         { return QGraphicsWidget::focusNextPrevChild(next); }
       
   199 
       
   200     void call_focusOutEvent(QFocusEvent* event)
       
   201         { return QGraphicsWidget::focusOutEvent(event); }
       
   202 
       
   203     void call_hideEvent(QHideEvent* event)
       
   204         { return QGraphicsWidget::hideEvent(event); }
       
   205 
       
   206     QVariant call_itemChange(QGraphicsItem::GraphicsItemChange change, QVariant const& value)
       
   207         { return QGraphicsWidget::itemChange(change, value); }
       
   208 
       
   209     void call_moveEvent(QGraphicsSceneMoveEvent* event)
       
   210         { return QGraphicsWidget::moveEvent(event); }
       
   211 
       
   212     void call_polishEvent()
       
   213         { return QGraphicsWidget::polishEvent(); }
       
   214 
       
   215     QVariant call_propertyChange(QString const& propertyName, QVariant const& value)
       
   216         { return QGraphicsWidget::propertyChange(propertyName, value); }
       
   217 
       
   218     void call_resizeEvent(QGraphicsSceneResizeEvent* event)
       
   219         { return QGraphicsWidget::resizeEvent(event); }
       
   220 
       
   221     bool call_sceneEvent(QEvent* event)
       
   222         { return QGraphicsWidget::sceneEvent(event); }
       
   223 
       
   224     void call_showEvent(QShowEvent* event)
       
   225         { return QGraphicsWidget::showEvent(event); }
       
   226 
       
   227     QSizeF call_sizeHint(Qt::SizeHint which, QSizeF const& constraint = QSizeF()) const
       
   228         { return QGraphicsWidget::sizeHint(which, constraint); }
       
   229 
       
   230     void call_updateGeometry()
       
   231         { return QGraphicsWidget::updateGeometry(); }
       
   232 
       
   233     int eventCount;
       
   234     Qt::LayoutDirection m_painterLayoutDirection;
       
   235 
       
   236     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
       
   237     {
       
   238         m_painterLayoutDirection = painter->layoutDirection();
       
   239         QGraphicsWidget::paint(painter, option, widget);
       
   240         if (hasFocus()) {
       
   241             painter->setPen(Qt::DotLine);
       
   242             painter->drawRect(rect());
       
   243         }
       
   244         //painter->drawText(QPointF(0,15), data(0).toString());
       
   245     }
       
   246 
       
   247 protected:
       
   248     bool event(QEvent *event)
       
   249     {
       
   250         eventCount++;
       
   251         return QGraphicsWidget::event(event);
       
   252     }
       
   253 };
       
   254 
       
   255 // This will be called before the first test function is executed.
       
   256 // It is only called once.
       
   257 void tst_QGraphicsWidget::initTestCase()
       
   258 {
       
   259 }
       
   260 
       
   261 // This will be called after the last test function is executed.
       
   262 // It is only called once.
       
   263 void tst_QGraphicsWidget::cleanupTestCase()
       
   264 {
       
   265 }
       
   266 
       
   267 // This will be called before each test function is executed.
       
   268 void tst_QGraphicsWidget::init()
       
   269 {
       
   270 }
       
   271 
       
   272 // This will be called after every test function.
       
   273 void tst_QGraphicsWidget::cleanup()
       
   274 {
       
   275 }
       
   276 
       
   277 class SizeHinter : public QGraphicsWidget
       
   278 {
       
   279 public:
       
   280     SizeHinter(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0,
       
   281                 const QSizeF &min = QSizeF(5,5),
       
   282                 const QSizeF &pref = QSizeF(50, 50),
       
   283                 const QSizeF &max = QSizeF(500, 500))
       
   284         : QGraphicsWidget(parent, wFlags)
       
   285     {
       
   286         m_sizes[Qt::MinimumSize] = min;
       
   287         m_sizes[Qt::PreferredSize] = pref;
       
   288         m_sizes[Qt::MaximumSize] = max;
       
   289 
       
   290     }
       
   291     void setSizeHint(Qt::SizeHint which, const QSizeF &newSizeHint)
       
   292     {
       
   293         m_sizes[which] = newSizeHint;
       
   294     }
       
   295 
       
   296 protected:
       
   297     QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const
       
   298     {
       
   299         Q_UNUSED(constraint);
       
   300         return m_sizes[which];
       
   301     }
       
   302 private:
       
   303     QSizeF m_sizes[4];
       
   304 };
       
   305 
       
   306 void tst_QGraphicsWidget::qgraphicswidget()
       
   307 {
       
   308     SubQGraphicsWidget widget;
       
   309     QVERIFY(widget.isVisible());
       
   310 
       
   311     QVERIFY(!widget.isWindow());
       
   312     QCOMPARE(widget.boundingRect(), QRectF(0, 0, 0, 0));
       
   313     QCOMPARE(widget.focusWidget(), (QGraphicsWidget*)0);
       
   314     QCOMPARE(widget.focusPolicy(), Qt::NoFocus);
       
   315     QCOMPARE(widget.font(), QFont());
       
   316     QCOMPARE(widget.geometry(), QRectF(widget.pos(), widget.size()));
       
   317     QCOMPARE(widget.layout(), (QGraphicsLayout*)0);
       
   318     QCOMPARE(widget.layoutDirection(), Qt::LeftToRight);
       
   319     QCOMPARE(widget.palette(), QPalette());
       
   320     QCOMPARE(widget.parentWidget(), (QGraphicsWidget*)0);
       
   321     QCOMPARE(widget.rect(), QRectF(QPointF(), widget.size()));
       
   322     QCOMPARE(widget.size(), QSizeF(0, 0));
       
   323     QVERIFY(widget.style() != (QStyle*)0);
       
   324     QCOMPARE(widget.testAttribute(Qt::WA_AcceptDrops), false);
       
   325     QCOMPARE(widget.topLevelWidget(), (QGraphicsWidget*)&widget);
       
   326     QCOMPARE(widget.type(), (int)QGraphicsWidget::Type);
       
   327     QCOMPARE(widget.call_propertyChange(QString(), QVariant()), QVariant());
       
   328     widget.call_sizeHint(Qt::PreferredSize, QSizeF());
       
   329 
       
   330     QGraphicsScene scene;
       
   331     QGraphicsWidget *parent = new QGraphicsWidget;
       
   332     SizeHinter *child = new SizeHinter(parent);
       
   333 
       
   334     QCOMPARE(child->minimumSize(), QSizeF(5, 5));
       
   335 }
       
   336 
       
   337 void tst_QGraphicsWidget::activation()
       
   338 {
       
   339     QGraphicsWidget *widget = new QGraphicsWidget;
       
   340     QGraphicsWidget *window1 = new QGraphicsWidget(0, Qt::Window);
       
   341     QGraphicsWidget *window2 = new QGraphicsWidget(0, Qt::Window);
       
   342     QVERIFY(!widget->isActiveWindow());
       
   343     QVERIFY(!window1->isActiveWindow());
       
   344     QVERIFY(!window2->isActiveWindow());
       
   345 
       
   346     QGraphicsScene scene;
       
   347     scene.addItem(widget);
       
   348     scene.addItem(window1);
       
   349     scene.addItem(window2);
       
   350 
       
   351     QVERIFY(!widget->isActiveWindow());
       
   352     QVERIFY(!window1->isActiveWindow());
       
   353     QVERIFY(!window2->isActiveWindow());
       
   354 
       
   355     QEvent activateEvent(QEvent::WindowActivate);
       
   356     QApplication::sendEvent(&scene, &activateEvent);
       
   357 
       
   358     QVERIFY(!widget->isActiveWindow());
       
   359     QVERIFY(window1->isActiveWindow());
       
   360     QVERIFY(!window2->isActiveWindow());
       
   361 
       
   362     scene.setActiveWindow(window1);
       
   363     QVERIFY(!widget->isActiveWindow());
       
   364     QVERIFY(window1->isActiveWindow());
       
   365     QVERIFY(!window2->isActiveWindow());
       
   366 
       
   367     QEvent deactivateEvent(QEvent::WindowDeactivate);
       
   368     QApplication::sendEvent(&scene, &deactivateEvent);
       
   369 
       
   370     QVERIFY(!widget->isActiveWindow());
       
   371     QVERIFY(!window1->isActiveWindow());
       
   372     QVERIFY(!window2->isActiveWindow());
       
   373 }
       
   374 
       
   375 void tst_QGraphicsWidget::boundingRect_data()
       
   376 {
       
   377     QTest::addColumn<QSizeF>("size");
       
   378     QTest::newRow("null") << QSizeF(0, 0);
       
   379     QTest::newRow("avg") << QSizeF(10, 10);
       
   380 }
       
   381 
       
   382 // QRectF boundingRect() const public
       
   383 void tst_QGraphicsWidget::boundingRect()
       
   384 {
       
   385     QFETCH(QSizeF, size);
       
   386     SubQGraphicsWidget widget;
       
   387     widget.resize(size);
       
   388     QCOMPARE(widget.rect(), QRectF(QPointF(), size));
       
   389     QCOMPARE(widget.boundingRect(), QRectF(QPointF(0, 0), size));
       
   390 }
       
   391 
       
   392 void tst_QGraphicsWidget::dumpFocusChain_data()
       
   393 {
       
   394     QTest::addColumn<bool>("scene");
       
   395     QTest::addColumn<int>("children");
       
   396     QTest::addColumn<bool>("setFocus");
       
   397     QTest::newRow("empty world") << false << 0 << false;
       
   398     QTest::newRow("one world") << true << 2 << false;
       
   399     QTest::newRow("one world w/focus") << true << 2 << true;
       
   400 }
       
   401 
       
   402 // void dumpFocusChain(QGraphicsScene* scene) public (static)
       
   403 void tst_QGraphicsWidget::dumpFocusChain()
       
   404 {
       
   405     // ### this test is very strange...
       
   406     QFETCH(bool, scene);
       
   407     SubQGraphicsWidget *parent = new SubQGraphicsWidget;
       
   408     QGraphicsScene *theScene = 0;
       
   409     if (scene) {
       
   410         theScene = new QGraphicsScene(this);
       
   411         theScene->addItem(parent);
       
   412     }
       
   413     QFETCH(int, children);
       
   414     QFETCH(bool, setFocus);
       
   415     for (int i = 0; i < children; ++i) {
       
   416         SubQGraphicsWidget *widget = new SubQGraphicsWidget(parent);
       
   417         if (setFocus) {
       
   418             widget->setFlag(QGraphicsItem::ItemIsFocusable, true);
       
   419             if (scene)
       
   420                 theScene->setFocusItem(widget);
       
   421         }
       
   422     }
       
   423 
       
   424     if (!scene)
       
   425         delete parent;
       
   426 }
       
   427 
       
   428 void tst_QGraphicsWidget::focusWidget_data()
       
   429 {
       
   430     QTest::addColumn<int>("childCount");
       
   431     QTest::addColumn<int>("childWithFocus");
       
   432     QTest::newRow("none") << 0 << 0;
       
   433     QTest::newRow("first") << 3 << 0;
       
   434     QTest::newRow("last") << 3 << 2;
       
   435 }
       
   436 
       
   437 // QGraphicsWidget* focusWidget() const public
       
   438 void tst_QGraphicsWidget::focusWidget()
       
   439 {
       
   440     SubQGraphicsWidget *parent = new SubQGraphicsWidget;
       
   441     QCOMPARE(parent->focusWidget(), (QGraphicsWidget *)0);
       
   442     QGraphicsScene scene;
       
   443     QEvent windowActivate(QEvent::WindowActivate);
       
   444     qApp->sendEvent(&scene, &windowActivate);
       
   445     scene.addItem(parent);
       
   446 
       
   447     QFETCH(int, childCount);
       
   448     QList<SubQGraphicsWidget *> children;
       
   449     for (int i = 0; i < childCount; ++i) {
       
   450         SubQGraphicsWidget *widget = new SubQGraphicsWidget(parent);
       
   451         widget->setFlag(QGraphicsItem::ItemIsFocusable, true);
       
   452         children.append(widget);
       
   453     }
       
   454     if (childCount > 0) {
       
   455         QFETCH(int, childWithFocus);
       
   456         SubQGraphicsWidget *widget = children[childWithFocus];
       
   457         widget->setFocus();
       
   458         QVERIFY(widget->hasFocus());
       
   459         QCOMPARE(parent->focusWidget(), static_cast<QGraphicsWidget*>(widget));
       
   460     }
       
   461 }
       
   462 
       
   463 void tst_QGraphicsWidget::focusWidget2()
       
   464 {
       
   465     QGraphicsScene scene;
       
   466     QEvent windowActivate(QEvent::WindowActivate);
       
   467     qApp->sendEvent(&scene, &windowActivate);
       
   468 
       
   469     QGraphicsWidget *widget = new QGraphicsWidget;
       
   470     EventSpy focusInSpy(widget, QEvent::FocusIn);
       
   471     EventSpy focusOutSpy(widget, QEvent::FocusOut);
       
   472 
       
   473     scene.addItem(widget);
       
   474 
       
   475     QVERIFY(!widget->hasFocus());
       
   476     widget->setFocusPolicy(Qt::StrongFocus);
       
   477     QVERIFY(!widget->hasFocus());
       
   478 
       
   479     QGraphicsWidget *subWidget = new QGraphicsWidget(widget);
       
   480     QVERIFY(!subWidget->hasFocus());
       
   481 
       
   482     scene.setFocus();
       
   483 
       
   484     QVERIFY(!widget->hasFocus());
       
   485     QVERIFY(!subWidget->hasFocus());
       
   486 
       
   487     widget->setFocus();
       
   488 
       
   489     QVERIFY(widget->hasFocus());
       
   490     QCOMPARE(focusInSpy.count(), 1);
       
   491     QVERIFY(!subWidget->hasFocus());
       
   492 
       
   493     QGraphicsWidget *otherSubWidget = new QGraphicsWidget;
       
   494     EventSpy otherFocusInSpy(otherSubWidget, QEvent::FocusIn);
       
   495     EventSpy otherFocusOutSpy(otherSubWidget, QEvent::FocusOut);
       
   496 
       
   497     otherSubWidget->setFocusPolicy(Qt::StrongFocus);
       
   498     otherSubWidget->setParentItem(widget);
       
   499 
       
   500     QVERIFY(widget->hasFocus());
       
   501     QCOMPARE(scene.focusItem(), (QGraphicsItem *)widget);
       
   502     QVERIFY(!subWidget->hasFocus());
       
   503     QVERIFY(!otherSubWidget->hasFocus());
       
   504 
       
   505     widget->hide();
       
   506     QVERIFY(!widget->hasFocus()); // lose but still has subfocus
       
   507     QCOMPARE(focusInSpy.count(), 1);
       
   508     QCOMPARE(focusOutSpy.count(), 1);
       
   509 
       
   510     widget->show();
       
   511     QVERIFY(!widget->hasFocus()); // no regain
       
   512     QCOMPARE(focusInSpy.count(), 1);
       
   513     QCOMPARE(focusOutSpy.count(), 1);
       
   514 
       
   515     widget->hide();
       
   516 
       
   517     // try to setup subFocus on item that can't take focus
       
   518     subWidget->setFocus();
       
   519     QVERIFY(!subWidget->hasFocus());
       
   520     QVERIFY(!scene.focusItem()); // but isn't the scene's focus item
       
   521 
       
   522     // try to setup subFocus on item that can take focus
       
   523     otherSubWidget->setFocus();
       
   524     QVERIFY(!otherSubWidget->hasFocus());
       
   525     QCOMPARE(widget->focusWidget(), otherSubWidget);
       
   526     QVERIFY(!scene.focusItem()); // but isn't the scene's focus item
       
   527 
       
   528     widget->show();
       
   529 
       
   530     QCOMPARE(scene.focusItem(), (QGraphicsItem *)otherSubWidget); // but isn't the scene's focus item
       
   531     QCOMPARE(otherFocusInSpy.count(), 1);
       
   532     QCOMPARE(otherFocusOutSpy.count(), 0);
       
   533 
       
   534     delete otherSubWidget;
       
   535 
       
   536     QCOMPARE(otherFocusOutSpy.count(), 1);
       
   537     QVERIFY(!scene.focusItem());
       
   538     QVERIFY(!widget->focusWidget());
       
   539 }
       
   540 
       
   541 Q_DECLARE_METATYPE(Qt::FocusPolicy)
       
   542 void tst_QGraphicsWidget::focusPolicy_data()
       
   543 {
       
   544     QTest::addColumn<Qt::FocusPolicy>("focusPolicy1");
       
   545     QTest::addColumn<Qt::FocusPolicy>("focusPolicy2");
       
   546 
       
   547     for (int i = 0; i < 25; ++i) {
       
   548         QTestData &data = QTest::newRow(QString("%1").arg(i).toLatin1());
       
   549         switch(i % 5) {
       
   550         case 0: data << Qt::TabFocus; break;
       
   551         case 1: data << Qt::ClickFocus; break;
       
   552         case 2: data << Qt::StrongFocus; break;
       
   553         case 3: data << Qt::WheelFocus; break;
       
   554         case 4: data << Qt::NoFocus; break;
       
   555         }
       
   556         switch(i / 5) {
       
   557         case 0: data << Qt::TabFocus; break;
       
   558         case 1: data << Qt::ClickFocus; break;
       
   559         case 2: data << Qt::StrongFocus; break;
       
   560         case 3: data << Qt::WheelFocus; break;
       
   561         case 4: data << Qt::NoFocus; break;
       
   562         }
       
   563     }
       
   564 }
       
   565 
       
   566 // Qt::FocusPolicy focusPolicy() const public
       
   567 void tst_QGraphicsWidget::focusPolicy()
       
   568 {
       
   569     QGraphicsScene scene;
       
   570     QEvent windowActivate(QEvent::WindowActivate);
       
   571     qApp->sendEvent(&scene, &windowActivate);
       
   572 
       
   573     SubQGraphicsWidget *widget = new SubQGraphicsWidget;
       
   574     scene.addItem(widget);
       
   575     QCOMPARE(Qt::NoFocus, widget->focusPolicy());
       
   576 
       
   577     QFETCH(Qt::FocusPolicy, focusPolicy1);
       
   578     widget->setFocusPolicy(focusPolicy1);
       
   579     QCOMPARE(widget->focusPolicy(), focusPolicy1);
       
   580     bool isFocusable = widget->flags() & QGraphicsItem::ItemIsFocusable;
       
   581     bool wasFocusable = isFocusable;
       
   582     QVERIFY(isFocusable == (focusPolicy1 != Qt::NoFocus));
       
   583     widget->setFocus();
       
   584     QCOMPARE(widget->hasFocus(), isFocusable);
       
   585 
       
   586     QFETCH(Qt::FocusPolicy, focusPolicy2);
       
   587     widget->setFocusPolicy(focusPolicy2);
       
   588     QCOMPARE(widget->focusPolicy(), focusPolicy2);
       
   589     isFocusable = widget->flags() & QGraphicsItem::ItemIsFocusable;
       
   590     QVERIFY(isFocusable == (focusPolicy2 != Qt::NoFocus));
       
   591     QCOMPARE(widget->hasFocus(), wasFocusable && isFocusable);
       
   592 }
       
   593 
       
   594 void tst_QGraphicsWidget::font_data()
       
   595 {
       
   596     QTest::addColumn<QString>("fontName");
       
   597     QTest::newRow("Helvetica") << "Helvetica";
       
   598 }
       
   599 
       
   600 // QFont font() const public
       
   601 void tst_QGraphicsWidget::font()
       
   602 {
       
   603     QFETCH(QString, fontName);
       
   604     SubQGraphicsWidget widget;
       
   605     QCOMPARE(widget.font(), QFont());
       
   606 
       
   607     QFont font(fontName);
       
   608     widget.setFont(font);
       
   609     QCOMPARE(widget.font().family(), font.family());
       
   610 }
       
   611 
       
   612 void tst_QGraphicsWidget::fontPropagation()
       
   613 {
       
   614     QGraphicsWidget *root = new QGraphicsWidget;
       
   615     QGraphicsWidget *child0 = new QGraphicsWidget(root);
       
   616     QGraphicsWidget *child1 = new QGraphicsWidget(child0);
       
   617     QGraphicsWidget *child2 = new QGraphicsWidget(child1);
       
   618     QGraphicsScene scene;
       
   619     scene.addItem(root);
       
   620 
       
   621     // Check that only the application fonts apply.
       
   622     QFont appFont = QApplication::font();
       
   623     QCOMPARE(scene.font(), appFont);
       
   624     QCOMPARE(root->font(), appFont);
       
   625     QCOMPARE(child0->font(), appFont);
       
   626     QCOMPARE(child1->font(), appFont);
       
   627 
       
   628     // Set child0's Text, and set ToolTipBase on child1.
       
   629     QFont boldFont;
       
   630     boldFont.setBold(true);
       
   631     child0->setFont(boldFont);
       
   632     QFont italicFont;
       
   633     italicFont.setItalic(true);
       
   634     child1->setFont(italicFont);
       
   635 
       
   636     // Check that the above settings propagate correctly.
       
   637     QCOMPARE(root->font(), appFont);
       
   638     QCOMPARE(scene.font(), appFont);
       
   639     QVERIFY(child0->font().bold());
       
   640     QVERIFY(!child0->font().italic());
       
   641     QVERIFY(child1->font().bold());
       
   642     QVERIFY(child1->font().italic());
       
   643     QVERIFY(child2->font().bold());
       
   644     QVERIFY(child2->font().italic());
       
   645 
       
   646     QGraphicsWidget *child3 = new QGraphicsWidget(child2);
       
   647     QVERIFY(child3->font().bold());
       
   648     QVERIFY(child3->font().italic());
       
   649 
       
   650     QGraphicsWidget *child4 = new QGraphicsWidget;
       
   651     child4->setParentItem(child3);
       
   652     QVERIFY(child4->font().bold());
       
   653     QVERIFY(child4->font().italic());
       
   654 
       
   655     // Replace the app font for child2. Button should propagate but Text
       
   656     // should still be ignored. The previous ToolTipBase setting is gone.
       
   657     QFont sizeFont;
       
   658     sizeFont.setPointSize(43);
       
   659     child1->setFont(sizeFont);
       
   660 
       
   661     // Check that the above settings propagate correctly.
       
   662     QCOMPARE(root->font(), appFont);
       
   663     QCOMPARE(scene.font(), appFont);
       
   664     QVERIFY(child0->font().bold());
       
   665     QVERIFY(!child0->font().italic());
       
   666     QVERIFY(child1->font().bold());
       
   667     QVERIFY(!child1->font().italic());
       
   668     QCOMPARE(child1->font().pointSize(), 43);
       
   669     QVERIFY(child2->font().bold());
       
   670     QVERIFY(!child2->font().italic());
       
   671     QCOMPARE(child2->font().pointSize(), 43);
       
   672 }
       
   673 
       
   674 void tst_QGraphicsWidget::fontPropagationWidgetItemWidget()
       
   675 {
       
   676     QGraphicsWidget *widget = new QGraphicsWidget;
       
   677     QGraphicsRectItem *rect = new QGraphicsRectItem(widget);
       
   678     QGraphicsWidget *widget2 = new QGraphicsWidget(rect);
       
   679 
       
   680     QGraphicsScene scene;
       
   681     scene.addItem(widget);
       
   682 
       
   683     QFont font;
       
   684     font.setPointSize(43);
       
   685     widget->setFont(font);
       
   686 
       
   687     QCOMPARE(widget2->font().pointSize(), 43);
       
   688     QCOMPARE(widget2->font().resolve(), QFont().resolve());
       
   689 
       
   690     widget->setFont(QFont());
       
   691 
       
   692     QCOMPARE(widget2->font().pointSize(), qApp->font().pointSize());
       
   693 }
       
   694 
       
   695 void tst_QGraphicsWidget::fontPropagationSceneChange()
       
   696 {
       
   697     QGraphicsWidget *widget = new QGraphicsWidget;
       
   698     QGraphicsRectItem *rect = new QGraphicsRectItem(widget);
       
   699     QGraphicsWidget *widget2 = new QGraphicsWidget(rect);
       
   700 
       
   701     QGraphicsScene scene;
       
   702     QGraphicsScene scene2;
       
   703 
       
   704     QFont font;
       
   705     font.setPointSize(47);
       
   706     scene.setFont(font);
       
   707 
       
   708     QFont font2;
       
   709     font2.setPointSize(74);
       
   710     scene2.setFont(font2);
       
   711 
       
   712     scene.addItem(widget);
       
   713     QCOMPARE(widget2->font().pointSize(), 47);
       
   714     scene2.addItem(widget);
       
   715     QCOMPARE(widget2->font().pointSize(), 74);
       
   716 }
       
   717 
       
   718 void tst_QGraphicsWidget::geometry_data()
       
   719 {
       
   720     QTest::addColumn<QPointF>("pos");
       
   721     QTest::addColumn<QSizeF>("size");
       
   722     QTest::newRow("null, null") << QPointF() << QSizeF(0, 0);
       
   723     QTest::newRow("null, normal") << QPointF() << QSizeF(10, 10);
       
   724     QTest::newRow("neg, normal") << QPointF(-5, -5) << QSizeF(10, 10);
       
   725 }
       
   726 
       
   727 // QRectF geometry() const public
       
   728 void tst_QGraphicsWidget::geometry()
       
   729 {
       
   730     SubQGraphicsWidget widget;
       
   731     QCOMPARE(widget.geometry(), QRectF(widget.pos(), widget.size()));
       
   732 
       
   733     QFETCH(QPointF, pos);
       
   734     QFETCH(QSizeF, size);
       
   735     widget.setPos(pos);
       
   736     widget.resize(size);
       
   737     QCOMPARE(widget.geometry(), QRectF(pos, size));
       
   738 }
       
   739 
       
   740 void tst_QGraphicsWidget::getContentsMargins_data()
       
   741 {
       
   742     QTest::addColumn<qreal>("left");
       
   743     QTest::addColumn<qreal>("top");
       
   744     QTest::addColumn<qreal>("right");
       
   745     QTest::addColumn<qreal>("bottom");
       
   746     QTest::newRow("null") << (qreal)0 << (qreal)0 << (qreal)0 << (qreal)0;
       
   747     QTest::newRow("something") << (qreal)10 << (qreal)5 << (qreal)3 << (qreal)7;
       
   748     QTest::newRow("real") << (qreal)1.7 << (qreal)5.9 << (qreal)3.2 << (qreal)9.7;
       
   749 }
       
   750 
       
   751 // void getContentsMargins(qreal* left, qreal* top, qreal* right, qreal* bottom) const public
       
   752 void tst_QGraphicsWidget::getContentsMargins()
       
   753 {
       
   754     qreal gleft;
       
   755     qreal gtop;
       
   756     qreal gright;
       
   757     qreal gbottom;
       
   758 
       
   759     SubQGraphicsWidget widget;
       
   760     widget.getContentsMargins(&gleft, &gtop, &gright, &gbottom);
       
   761     QCOMPARE(gleft, (qreal)0);
       
   762     QCOMPARE(gtop, (qreal)0);
       
   763     QCOMPARE(gright, (qreal)0);
       
   764     QCOMPARE(gbottom, (qreal)0);
       
   765 
       
   766     QFETCH(qreal, left);
       
   767     QFETCH(qreal, top);
       
   768     QFETCH(qreal, right);
       
   769     QFETCH(qreal, bottom);
       
   770     int oldEventCounts = widget.eventCount;
       
   771     widget.setContentsMargins(left, top, right, bottom);
       
   772     QVERIFY(left == 0 || oldEventCounts != widget.eventCount);
       
   773     widget.getContentsMargins(&gleft, &gtop, &gright, &gbottom);
       
   774     QCOMPARE(gleft, left);
       
   775     QCOMPARE(gtop, top);
       
   776     QCOMPARE(gright, right);
       
   777     QCOMPARE(gbottom, bottom);
       
   778 }
       
   779 
       
   780 Q_DECLARE_METATYPE(Qt::LayoutDirection)
       
   781 void tst_QGraphicsWidget::initStyleOption_data()
       
   782 {
       
   783     QTest::addColumn<bool>("enabled");
       
   784     QTest::addColumn<bool>("focus");
       
   785     QTest::addColumn<bool>("underMouse");
       
   786     QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
       
   787     QTest::addColumn<QSizeF>("size");
       
   788     QTest::addColumn<QPalette>("palette");
       
   789     QTest::addColumn<QString>("fontName");
       
   790     QTest::newRow("none") << false << false << false << Qt::LeftToRight << QSizeF(0, 0) << QPalette() << QString();
       
   791     QTest::newRow("all") << true << true << true << Qt::RightToLeft << QSizeF(300, 300) << QPalette(Qt::magenta) << "Helvetica";
       
   792     QTest::newRow("rand") << true << false << false << Qt::RightToLeft << QSizeF(1, 0) << QPalette(Qt::darkCyan) << "Times";
       
   793 }
       
   794 
       
   795 // void initStyleOption(QStyleOption* option) const public
       
   796 void tst_QGraphicsWidget::initStyleOption()
       
   797 {
       
   798     QGraphicsScene scene;
       
   799     QGraphicsView view(&scene);
       
   800     view.show();
       
   801 #ifdef Q_WS_X11
       
   802     qt_x11_wait_for_window_manager(&view);
       
   803 #endif
       
   804     QApplication::setActiveWindow(&view);
       
   805     QTest::qWait(25);
       
   806     QTRY_COMPARE(QApplication::activeWindow(), &view);
       
   807 
       
   808     view.setAlignment(Qt::AlignTop | Qt::AlignLeft);
       
   809     SubQGraphicsWidget *widget = new SubQGraphicsWidget;
       
   810     widget->setAcceptsHoverEvents(true);
       
   811     QStyleOption option;
       
   812     scene.addItem(widget);
       
   813 
       
   814     QFETCH(QSizeF, size);
       
   815     widget->resize(size);
       
   816 
       
   817     QFETCH(bool, enabled);
       
   818     widget->setEnabled(enabled);
       
   819     QFETCH(bool, focus);
       
   820     if (focus) {
       
   821         widget->setFlag(QGraphicsItem::ItemIsFocusable, true);
       
   822         widget->setFocus();
       
   823         QVERIFY(widget->hasFocus());
       
   824     }
       
   825     QFETCH(bool, underMouse);
       
   826     if (underMouse) {
       
   827         view.resize(300, 300);
       
   828         view.show();
       
   829         QTest::qWaitForWindowShown(&view);
       
   830         QTest::qWait(20);
       
   831         sendMouseMove(view.viewport(), view.mapFromScene(widget->mapToScene(widget->boundingRect().center())));
       
   832     }
       
   833 
       
   834     QFETCH(QPalette, palette);
       
   835     widget->setPalette(palette);
       
   836 
       
   837     QFETCH(QString, fontName);
       
   838     widget->setFont(QFont(fontName));
       
   839 
       
   840     // The test
       
   841     widget->initStyleOption(&option);
       
   842 
       
   843     bool isEnabled = option.state & QStyle::State_Enabled;
       
   844     QCOMPARE(isEnabled, enabled);
       
   845     bool hasFocus = option.state & QStyle::State_HasFocus;
       
   846     QCOMPARE(hasFocus, focus);
       
   847     bool isUnderMouse = option.state & QStyle::State_MouseOver;
       
   848 #ifndef Q_OS_WINCE
       
   849     QCOMPARE(isUnderMouse, underMouse);
       
   850 #endif
       
   851     // if (layoutDirection != Qt::LeftToRight)
       
   852     //QEXPECT_FAIL("", "QApplicaiton::layoutDirection doesn't propagate to QGraphicsWidget", Continue);
       
   853     //QCOMPARE(option.direction, layoutDirection);
       
   854     QCOMPARE(option.rect, QRectF(QPointF(), size).toRect());
       
   855     QCOMPARE(option.palette, palette.resolve(QApplication::palette()));
       
   856     QCOMPARE(option.fontMetrics, QFontMetrics(widget->font()));
       
   857 }
       
   858 
       
   859 void tst_QGraphicsWidget::layout_data()
       
   860 {
       
   861     QTest::addColumn<int>("childCount");
       
   862     QTest::newRow("empty") << 0;
       
   863     QTest::newRow("10") << 10;
       
   864 }
       
   865 
       
   866 // QGraphicsLayout* layout() const public
       
   867 void tst_QGraphicsWidget::layout()
       
   868 {
       
   869     SubQGraphicsWidget widget;
       
   870     widget.setContentsMargins(10, 5, 50, 100);
       
   871     QCOMPARE(widget.layout(), (QGraphicsLayout *)0);
       
   872     QFETCH(int, childCount);
       
   873 
       
   874     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
       
   875     QList<SubQGraphicsWidget*> children;
       
   876     for (int i = 0; i < childCount; ++i) {
       
   877         SubQGraphicsWidget *item = new SubQGraphicsWidget;
       
   878         layout->addItem(item);
       
   879         children.append(item);
       
   880     }
       
   881     widget.setLayout(layout);
       
   882 
       
   883     QTest::qWait(25);
       
   884 
       
   885     QCOMPARE(widget.layout(), static_cast<QGraphicsLayout*>(layout));
       
   886     for (int i = 0; i < children.count(); ++i) {
       
   887         SubQGraphicsWidget *item = children[i];
       
   888         QCOMPARE(item->parentWidget(), (QGraphicsWidget *)&widget);
       
   889         QVERIFY(item->geometry() != QRectF(0, 0, -1, -1));
       
   890     }
       
   891 
       
   892     // don't crash
       
   893     widget.setLayout(0);
       
   894 }
       
   895 
       
   896 void tst_QGraphicsWidget::layoutDirection_data()
       
   897 {
       
   898     QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
       
   899     QTest::newRow("rtl") << Qt::RightToLeft;
       
   900     QTest::newRow("ltr") << Qt::LeftToRight;
       
   901 }
       
   902 
       
   903 // Qt::LayoutDirection layoutDirection() const public
       
   904 void tst_QGraphicsWidget::layoutDirection()
       
   905 {
       
   906     QFETCH(Qt::LayoutDirection, layoutDirection);
       
   907     QGraphicsScene scene;
       
   908     QGraphicsView *view = new QGraphicsView(&scene);
       
   909     SubQGraphicsWidget widget;
       
   910     scene.addItem(&widget);
       
   911     QCOMPARE(widget.layoutDirection(), Qt::LeftToRight);
       
   912     QCOMPARE(widget.testAttribute(Qt::WA_SetLayoutDirection), false);
       
   913 
       
   914     QList<SubQGraphicsWidget*> children;
       
   915     for (int i = 0; i < 10; ++i) {
       
   916         SubQGraphicsWidget *item = new SubQGraphicsWidget(&widget);
       
   917         children.append(item);
       
   918         QCOMPARE(item->testAttribute(Qt::WA_SetLayoutDirection), false);
       
   919     }
       
   920     widget.setLayoutDirection(layoutDirection);
       
   921     QCOMPARE(widget.testAttribute(Qt::WA_SetLayoutDirection), true);
       
   922     view->show();
       
   923     QTest::qWaitForWindowShown(view);
       
   924     for (int i = 0; i < children.count(); ++i) {
       
   925         QCOMPARE(children[i]->layoutDirection(), layoutDirection);
       
   926         QCOMPARE(children[i]->testAttribute(Qt::WA_SetLayoutDirection), false);
       
   927         view->repaint();
       
   928         QApplication::processEvents();
       
   929         QTRY_COMPARE(children[i]->m_painterLayoutDirection, layoutDirection);
       
   930     }
       
   931     delete view;
       
   932 }
       
   933 
       
   934 void tst_QGraphicsWidget::paint_data()
       
   935 {
       
   936     // currently QGraphicsWidget doesn't paint or do anything ...
       
   937 }
       
   938 
       
   939 // void paint(QPainter* painter, QStyleOptionGraphicsItem const* option, QWidget* widget) public
       
   940 void tst_QGraphicsWidget::paint()
       
   941 {
       
   942     SubQGraphicsWidget widget;
       
   943     QPainter painter;
       
   944     QStyleOptionGraphicsItem option;
       
   945     widget.paint(&painter, &option, 0); // check that widget = 0 works.
       
   946 }
       
   947 
       
   948 void tst_QGraphicsWidget::palettePropagation()
       
   949 {
       
   950     QGraphicsWidget *root = new QGraphicsWidget;
       
   951     QGraphicsWidget *child0 = new QGraphicsWidget(root);
       
   952     QGraphicsWidget *child1 = new QGraphicsWidget(child0);
       
   953     QGraphicsWidget *child2 = new QGraphicsWidget(child1);
       
   954     QGraphicsScene scene;
       
   955     scene.addItem(root);
       
   956 
       
   957     // These colors are unlikely to be imposed on the default palette of
       
   958     // QWidget ;-).
       
   959     QColor sysPalText(21, 22, 23);
       
   960     QColor sysPalToolTipBase(12, 13, 14);
       
   961     QColor overridePalText(42, 43, 44);
       
   962     QColor overridePalToolTipBase(45, 46, 47);
       
   963     QColor sysPalButton(99, 98, 97);
       
   964 
       
   965     // Check that only the application fonts apply.
       
   966     QPalette appPal = QApplication::palette();
       
   967     QCOMPARE(scene.palette(), appPal);
       
   968     QCOMPARE(root->palette(), appPal);
       
   969     QCOMPARE(child0->palette(), appPal);
       
   970     QCOMPARE(child1->palette(), appPal);
       
   971 
       
   972     // Set child0's Text, and set ToolTipBase on child1.
       
   973     QPalette textPalette;
       
   974     textPalette.setColor(QPalette::Text, overridePalText);
       
   975     child0->setPalette(textPalette);
       
   976     QPalette toolTipPalette;
       
   977     toolTipPalette.setColor(QPalette::ToolTipBase, overridePalToolTipBase);
       
   978     child1->setPalette(toolTipPalette);
       
   979 
       
   980     // Check that the above settings propagate correctly.
       
   981     QCOMPARE(root->palette(), appPal);
       
   982     QCOMPARE(scene.palette(), appPal);
       
   983     QCOMPARE(child0->palette().color(QPalette::Text), overridePalText);
       
   984     QCOMPARE(child0->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
       
   985     QCOMPARE(child1->palette().color(QPalette::Text), overridePalText);
       
   986     QCOMPARE(child1->palette().color(QPalette::ToolTipBase), overridePalToolTipBase);
       
   987     QCOMPARE(child2->palette().color(QPalette::Text), overridePalText);
       
   988     QCOMPARE(child2->palette().color(QPalette::ToolTipBase), overridePalToolTipBase);
       
   989 
       
   990     QGraphicsWidget *child3 = new QGraphicsWidget(child2);
       
   991     QCOMPARE(child3->palette().color(QPalette::Text), overridePalText);
       
   992     QCOMPARE(child3->palette().color(QPalette::ToolTipBase), overridePalToolTipBase);
       
   993 
       
   994     QGraphicsWidget *child4 = new QGraphicsWidget;
       
   995     child4->setParentItem(child3);
       
   996     QCOMPARE(child4->palette().color(QPalette::Text), overridePalText);
       
   997     QCOMPARE(child4->palette().color(QPalette::ToolTipBase), overridePalToolTipBase);
       
   998 
       
   999     // Replace the app palette for child2. Button should propagate but Text
       
  1000     // should still be ignored. The previous ToolTipBase setting is gone.
       
  1001     QPalette buttonPalette;
       
  1002     buttonPalette.setColor(QPalette::Button, sysPalButton);
       
  1003     child1->setPalette(buttonPalette);
       
  1004 
       
  1005     QCOMPARE(root->palette(), appPal);
       
  1006     QCOMPARE(scene.palette(), appPal);
       
  1007     QCOMPARE(child0->palette().color(QPalette::Text), overridePalText);
       
  1008     QCOMPARE(child0->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
       
  1009     QCOMPARE(child1->palette().color(QPalette::Text), overridePalText);
       
  1010     QCOMPARE(child1->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
       
  1011     QCOMPARE(child1->palette().color(QPalette::Button), sysPalButton);
       
  1012     QCOMPARE(child2->palette().color(QPalette::Text), overridePalText);
       
  1013     QCOMPARE(child2->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
       
  1014     QCOMPARE(child2->palette().color(QPalette::Button), sysPalButton);
       
  1015 }
       
  1016 
       
  1017 void tst_QGraphicsWidget::parentWidget_data()
       
  1018 {
       
  1019     QTest::addColumn<int>("childrenCount");
       
  1020     QTest::newRow("0") << 0;
       
  1021     QTest::newRow("1") << 1;
       
  1022     QTest::newRow("10") << 10;
       
  1023 }
       
  1024 
       
  1025 // QGraphicsWidget* parentWidget() const public
       
  1026 void tst_QGraphicsWidget::parentWidget()
       
  1027 {
       
  1028     QFETCH(int, childrenCount);
       
  1029     SubQGraphicsWidget standAlongWidget;
       
  1030     QGraphicsLineItem standAlongItem;
       
  1031 
       
  1032     SubQGraphicsWidget widgetChild(&standAlongWidget);
       
  1033     SubQGraphicsWidget itemChild(&standAlongItem);
       
  1034 
       
  1035     QCOMPARE(standAlongWidget.parentWidget(), (QGraphicsWidget*)0);
       
  1036     QCOMPARE(widgetChild.parentWidget(), static_cast<QGraphicsWidget*>(&standAlongWidget));
       
  1037     QCOMPARE(itemChild.parentWidget(), (QGraphicsWidget*)0);
       
  1038 
       
  1039     for (int i = 0; i < childrenCount; ++i) {
       
  1040         SubQGraphicsWidget *item = new SubQGraphicsWidget(&standAlongWidget);
       
  1041         QCOMPARE(item->parentWidget(), static_cast<QGraphicsWidget*>(&standAlongWidget));
       
  1042     }
       
  1043 }
       
  1044 
       
  1045 void tst_QGraphicsWidget::resize_data()
       
  1046 {
       
  1047     QTest::addColumn<QSizeF>("size");
       
  1048     QTest::newRow("null") << QSizeF();
       
  1049     QTest::newRow("10x10") << QSizeF(10, 10);
       
  1050     QTest::newRow("10x-1") << QSizeF(10, -1);
       
  1051 }
       
  1052 
       
  1053 // void resize(qreal w, qreal h) public
       
  1054 void tst_QGraphicsWidget::resize()
       
  1055 {
       
  1056     QFETCH(QSizeF, size);
       
  1057     SubQGraphicsWidget widget;
       
  1058 
       
  1059     int oldEventCounts = widget.eventCount;
       
  1060     QSizeF oldSize = widget.size();
       
  1061     widget.resize(size);
       
  1062 
       
  1063     QSizeF boundedSize = size.expandedTo(widget.minimumSize()).boundedTo(widget.maximumSize());
       
  1064     QCOMPARE(widget.eventCount, oldEventCounts + ((oldSize == boundedSize) ? 0 : 1));
       
  1065     QCOMPARE(widget.size(), boundedSize);
       
  1066 }
       
  1067 
       
  1068 Q_DECLARE_METATYPE(Qt::WidgetAttribute)
       
  1069 void tst_QGraphicsWidget::setAttribute_data()
       
  1070 {
       
  1071     QTest::addColumn<Qt::WidgetAttribute>("attribute");
       
  1072     QTest::addColumn<bool>("supported");
       
  1073     QTest::newRow("WA_SetLayoutDirection") << Qt::WA_SetLayoutDirection << true;
       
  1074     QTest::newRow("WA_RightToLeft") << Qt::WA_RightToLeft << true;
       
  1075     QTest::newRow("WA_SetStyle") << Qt::WA_SetStyle << true;
       
  1076     QTest::newRow("WA_Resized") << Qt::WA_Resized << true;
       
  1077     QTest::newRow("unsupported") << Qt::WA_PaintOutsidePaintEvent << false;
       
  1078 }
       
  1079 
       
  1080 // void setAttribute(Qt::WidgetAttribute attribute, bool on = true) public
       
  1081 void tst_QGraphicsWidget::setAttribute()
       
  1082 {
       
  1083     QFETCH(Qt::WidgetAttribute, attribute);
       
  1084     QFETCH(bool, supported);
       
  1085     SubQGraphicsWidget widget;
       
  1086     if (attribute == Qt::WA_PaintOutsidePaintEvent)
       
  1087         QTest::ignoreMessage(QtWarningMsg, "QGraphicsWidget::setAttribute: unsupported attribute 13");
       
  1088     widget.setAttribute(attribute);
       
  1089     QCOMPARE(widget.testAttribute(attribute), supported);
       
  1090 }
       
  1091 
       
  1092 void tst_QGraphicsWidget::setStyle_data()
       
  1093 {
       
  1094     QTest::addColumn<QString>("style");
       
  1095     QTest::newRow("null") << "";
       
  1096     QTest::newRow("cleanlooks") << "QCleanlooksStyle";
       
  1097 }
       
  1098 
       
  1099 // void setStyle(QStyle* style) public
       
  1100 void tst_QGraphicsWidget::setStyle()
       
  1101 {
       
  1102     SubQGraphicsWidget widget;
       
  1103     QCleanlooksStyle cleanlooksStyle;
       
  1104 
       
  1105     int oldEventCounts = widget.eventCount;
       
  1106 
       
  1107     QFETCH(QString, style);
       
  1108     if (style == "QCleanlooksStyle") {
       
  1109         widget.setStyle(&cleanlooksStyle);
       
  1110         QCOMPARE(widget.style(), static_cast<QStyle*>(&cleanlooksStyle));
       
  1111     } else {
       
  1112         widget.setStyle(0);
       
  1113         QVERIFY(widget.style() != (QStyle *)0);
       
  1114     }
       
  1115     QCOMPARE(widget.eventCount, oldEventCounts + 1);
       
  1116     QCOMPARE(widget.testAttribute(Qt::WA_SetStyle), !style.isEmpty());
       
  1117 
       
  1118     // cleanup
       
  1119     widget.setStyle(0);
       
  1120 }
       
  1121 
       
  1122 void tst_QGraphicsWidget::setTabOrder_data()
       
  1123 {
       
  1124     QTest::addColumn<int>("childrenCount");
       
  1125     QTest::newRow("0") << 0;
       
  1126     QTest::newRow("1") << 1;
       
  1127     QTest::newRow("10") << 10;
       
  1128 }
       
  1129 
       
  1130 // void setTabOrder(QGraphicsWidget* first, QGraphicsWidget* second) public
       
  1131 void tst_QGraphicsWidget::setTabOrder()
       
  1132 {
       
  1133     QFETCH(int, childrenCount);
       
  1134     QGraphicsScene scene;
       
  1135     QGraphicsView view(&scene);
       
  1136     view.show();
       
  1137 #ifdef Q_WS_X11
       
  1138     qt_x11_wait_for_window_manager(&view);
       
  1139 #endif
       
  1140     QApplication::setActiveWindow(&view);
       
  1141     QTest::qWait(25);
       
  1142     QTRY_COMPARE(QApplication::activeWindow(), &view);
       
  1143 
       
  1144     QGraphicsWidget *lastItem = 0;
       
  1145     QTest::ignoreMessage(QtWarningMsg, "QGraphicsWidget::setTabOrder(0, 0) is undefined");
       
  1146     QGraphicsWidget::setTabOrder(0, 0);
       
  1147 
       
  1148     QList<SubQGraphicsWidget*> children;
       
  1149     for (int i = 0; i < childrenCount; ++i) {
       
  1150         SubQGraphicsWidget *item = new SubQGraphicsWidget();
       
  1151         item->setFocusPolicy(Qt::TabFocus);
       
  1152         children.append(item);
       
  1153         scene.addItem(item);
       
  1154         if (lastItem)
       
  1155             QGraphicsWidget::setTabOrder(lastItem, item);
       
  1156         lastItem = item;
       
  1157     }
       
  1158 
       
  1159     if (!children.isEmpty()) {
       
  1160         QGraphicsWidget *first = children.first();
       
  1161         view.viewport()->setFocus();
       
  1162         QApplication::processEvents();
       
  1163         QTRY_VERIFY(view.viewport()->hasFocus());
       
  1164         first->setFocus();
       
  1165         QVERIFY(first->hasFocus());
       
  1166         QVERIFY(scene.hasFocus());
       
  1167         QVERIFY(view.viewport()->hasFocus());
       
  1168 
       
  1169         int currentItem = 0;
       
  1170         while (currentItem < children.count() - 1) {
       
  1171             QTest::keyPress(view.viewport(), Qt::Key_Tab);
       
  1172             ++currentItem;
       
  1173             QVERIFY(children[currentItem % children.size()]->hasFocus());
       
  1174         }
       
  1175     }
       
  1176 }
       
  1177 
       
  1178 static bool compareFocusChain(QGraphicsView *view, const QList<QGraphicsItem*> &order)
       
  1179 {
       
  1180     QGraphicsScene *scene = view->scene();
       
  1181     QStringList actual;
       
  1182     QGraphicsItem *oldFocusItem = scene->focusItem();
       
  1183     for (int i = 0; i < order.count(); ++i) {
       
  1184         QGraphicsItem *focusItem = scene->focusItem();
       
  1185         actual << focusItem->data(0).toString();
       
  1186         //qDebug() << "i:" << i << "expected:" << QString::number(uint(order.at(i)), 16) << QString::number(uint(focusItem), 16);
       
  1187         if (focusItem != order.at(i)) {
       
  1188             qDebug() << "actual:"  << actual;
       
  1189             scene->setFocusItem(oldFocusItem);
       
  1190             return false;
       
  1191         }
       
  1192         if (i < order.count() - 1)
       
  1193             QTest::keyPress(view, Qt::Key_Tab);
       
  1194     }
       
  1195     scene->setFocusItem(oldFocusItem);
       
  1196     return true;
       
  1197 }
       
  1198 
       
  1199 void tst_QGraphicsWidget::setTabOrderAndReparent()
       
  1200 {
       
  1201     QGraphicsScene scene;
       
  1202     QGraphicsView view(&scene);
       
  1203     view.show();
       
  1204     QApplication::setActiveWindow(&view);
       
  1205     QTest::qWaitForWindowShown(&view);
       
  1206     QTRY_COMPARE(QApplication::activeWindow(), &view);
       
  1207 
       
  1208     int i;
       
  1209     QGraphicsWidget *w1, *w2, *w3, *w4;
       
  1210     for (i = 1; i < 4; ++i) {
       
  1211         QGraphicsWidget *wid = new QGraphicsWidget;
       
  1212         wid->setFocusPolicy(Qt::StrongFocus);
       
  1213         wid->setData(0, QString::fromAscii("w%1").arg(i));
       
  1214         scene.addItem(wid);
       
  1215         if (i == 1)
       
  1216             w1 = wid;
       
  1217         else if (i == 2)
       
  1218             w2 = wid;
       
  1219         else if (i == 3)
       
  1220             w3 = wid;
       
  1221     }
       
  1222 
       
  1223     w1->setFocus();
       
  1224     QTRY_VERIFY(w1->hasFocus());
       
  1225     QVERIFY(compareFocusChain(&view, QList<QGraphicsItem*>() << w1 << w2 << w3));
       
  1226 
       
  1227     QGraphicsWidget *p = new QGraphicsWidget;
       
  1228     p->setData(0, QLatin1String("parent"));
       
  1229     p->setFocusPolicy(Qt::StrongFocus);
       
  1230 
       
  1231     w1->setFocus();
       
  1232     QVERIFY(compareFocusChain(&view, QList<QGraphicsItem*>() << w1 << w2 << w3));
       
  1233 
       
  1234     w1->setParentItem(p);
       
  1235     w2->setFocus();
       
  1236     QVERIFY(compareFocusChain(&view, QList<QGraphicsItem*>() <<  w2 << w3));
       
  1237 
       
  1238     w2->setParentItem(p);
       
  1239     w3->setFocus();
       
  1240     QVERIFY(compareFocusChain(&view, QList<QGraphicsItem*>() << w3));
       
  1241     w3->setParentItem(p);
       
  1242     QCOMPARE(scene.focusItem(), static_cast<QGraphicsItem*>(0));
       
  1243 
       
  1244     scene.addItem(p);
       
  1245     p->setFocus();
       
  1246 
       
  1247     QVERIFY(compareFocusChain(&view, QList<QGraphicsItem*>() << p << w1 << w2 << w3));
       
  1248     delete p;
       
  1249 
       
  1250     for (i = 1; i < 5; ++i) {
       
  1251         QGraphicsWidget *wid = new QGraphicsWidget;
       
  1252         wid->setFocusPolicy(Qt::StrongFocus);
       
  1253         wid->setData(0, QString::fromAscii("w%1").arg(i));
       
  1254         scene.addItem(wid);
       
  1255         if (i == 1)
       
  1256             w1 = wid;
       
  1257         else if (i == 2)
       
  1258             w2 = wid;
       
  1259         else if (i == 3)
       
  1260             w3 = wid;
       
  1261         else if (i == 4)
       
  1262             w4 = wid;
       
  1263     }
       
  1264     w4->setParentItem(w1);
       
  1265     QGraphicsWidget::setTabOrder(w1, w4);
       
  1266     w1->setFocus();
       
  1267     QVERIFY(compareFocusChain(&view, QList<QGraphicsItem*>() << w1 << w4 << w2 << w3));
       
  1268 
       
  1269     p = new QGraphicsWidget;
       
  1270     p->setData(0, QLatin1String("parent"));
       
  1271     p->setFocusPolicy(Qt::StrongFocus);
       
  1272 
       
  1273     w1->setParentItem(p);
       
  1274     w2->setFocus();
       
  1275     QVERIFY(compareFocusChain(&view, QList<QGraphicsItem*>() << w2 << w3));
       
  1276 
       
  1277     scene.addItem(p);
       
  1278     w2->setFocus();
       
  1279     QVERIFY(compareFocusChain(&view, QList<QGraphicsItem*>() << w2 << w3 << p << w1 << w4));
       
  1280 }
       
  1281 
       
  1282 void tst_QGraphicsWidget::topLevelWidget_data()
       
  1283 {
       
  1284     QTest::addColumn<QString>("str");
       
  1285     QTest::newRow("test one") << "foo";
       
  1286 }
       
  1287 
       
  1288 // QGraphicsWidget* topLevelWidget() const public
       
  1289 void tst_QGraphicsWidget::topLevelWidget()
       
  1290 {
       
  1291     QFETCH(QString, str);
       
  1292     SubQGraphicsWidget widget;
       
  1293     QCOMPARE(widget.topLevelWidget(), (QGraphicsWidget *)&widget);
       
  1294 }
       
  1295 
       
  1296 void tst_QGraphicsWidget::unsetLayoutDirection_data()
       
  1297 {
       
  1298     QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
       
  1299     QTest::newRow("rtl") << Qt::RightToLeft;
       
  1300     QTest::newRow("ltr") << Qt::LeftToRight;
       
  1301 }
       
  1302 
       
  1303 // void unsetLayoutDirection() public
       
  1304 void tst_QGraphicsWidget::unsetLayoutDirection()
       
  1305 {
       
  1306     QApplication::setLayoutDirection(Qt::LeftToRight);
       
  1307     QFETCH(Qt::LayoutDirection, layoutDirection);
       
  1308     SubQGraphicsWidget widget;
       
  1309     QCOMPARE(Qt::LeftToRight, widget.layoutDirection());
       
  1310 
       
  1311     QList<SubQGraphicsWidget*> children;
       
  1312     for (int i = 0; i < 10; ++i) {
       
  1313         SubQGraphicsWidget *item = new SubQGraphicsWidget(&widget);
       
  1314         children.append(item);
       
  1315     }
       
  1316     widget.setLayoutDirection(layoutDirection);
       
  1317     widget.unsetLayoutDirection();
       
  1318     QCOMPARE(widget.testAttribute(Qt::WA_SetLayoutDirection), false);
       
  1319     for (int i = 0; i < children.count(); ++i) {
       
  1320         QCOMPARE(children[i]->layoutDirection(), Qt::LeftToRight);
       
  1321     }
       
  1322 }
       
  1323 
       
  1324 void tst_QGraphicsWidget::focusNextPrevChild_data()
       
  1325 {
       
  1326     QTest::addColumn<QString>("str");
       
  1327     QTest::newRow("test one") << "foo";
       
  1328 }
       
  1329 
       
  1330 // bool focusNextPrevChild(bool next) protected
       
  1331 void tst_QGraphicsWidget::focusNextPrevChild()
       
  1332 {
       
  1333     QFETCH(QString, str);
       
  1334     SubQGraphicsWidget widget;
       
  1335     // ### write test after just calling it stops crashing :)
       
  1336     widget.call_focusNextPrevChild(true);
       
  1337 }
       
  1338 
       
  1339 void tst_QGraphicsWidget::verifyFocusChain()
       
  1340 {
       
  1341     QGraphicsScene scene;
       
  1342     QGraphicsView view(&scene);
       
  1343     view.show();
       
  1344     QApplication::setActiveWindow(&view);
       
  1345     QTest::qWaitForWindowShown(&view);
       
  1346     QTRY_COMPARE(QApplication::activeWindow(), &view);
       
  1347 
       
  1348     {
       
  1349         // parent/child focus
       
  1350         SubQGraphicsWidget *w = new SubQGraphicsWidget(0, Qt::Window);
       
  1351         w->setFocusPolicy(Qt::StrongFocus);
       
  1352         SubQGraphicsWidget *w1_1 = new SubQGraphicsWidget(w);
       
  1353         w1_1->setFocusPolicy(Qt::StrongFocus);
       
  1354         scene.addItem(w);
       
  1355         w->setFocus();
       
  1356         QVERIFY(w->hasFocus());
       
  1357         w->call_focusNextPrevChild(true);
       
  1358         QVERIFY(w1_1->hasFocus());
       
  1359         delete w;
       
  1360     }
       
  1361 
       
  1362     {
       
  1363         // delete item in focus chain and verify chain
       
  1364         SubQGraphicsWidget *w = new SubQGraphicsWidget(0, Qt::Window);
       
  1365         SubQGraphicsWidget *w1_1 = new SubQGraphicsWidget(w);
       
  1366         SubQGraphicsWidget *w1_2 = new SubQGraphicsWidget(w);
       
  1367         SubQGraphicsWidget *w1_3 = new SubQGraphicsWidget(w);
       
  1368         w1_1->setFocusPolicy(Qt::StrongFocus);
       
  1369         w1_2->setFocusPolicy(Qt::StrongFocus);
       
  1370         w1_3->setFocusPolicy(Qt::StrongFocus);
       
  1371         scene.addItem(w);
       
  1372         w1_1->setFocus();
       
  1373         QVERIFY(w1_1->hasFocus());
       
  1374         QCOMPARE(w->call_focusNextPrevChild(true), true);
       
  1375         QVERIFY(w1_2->hasFocus());
       
  1376         QCOMPARE(w->call_focusNextPrevChild(true), true);
       
  1377         QVERIFY(w1_3->hasFocus());
       
  1378         w1_1->setFocus();
       
  1379         delete w1_2;
       
  1380         w->call_focusNextPrevChild(true);
       
  1381         QVERIFY(w1_3->hasFocus());
       
  1382         delete w;
       
  1383     }
       
  1384     {
       
  1385         // parent/child focus
       
  1386         SubQGraphicsWidget *w = new SubQGraphicsWidget(0, Qt::Window);
       
  1387         w->setFocusPolicy(Qt::StrongFocus);
       
  1388         SubQGraphicsWidget *w1_1 = new SubQGraphicsWidget(w);
       
  1389         w1_1->setFocusPolicy(Qt::StrongFocus);
       
  1390         scene.addItem(w);
       
  1391         w->setFocus();
       
  1392         QVERIFY(w->hasFocus());
       
  1393         w->call_focusNextPrevChild(true);
       
  1394         QVERIFY(w1_1->hasFocus());
       
  1395         delete w;
       
  1396     }
       
  1397     {
       
  1398         // remove the tabFocusFirst widget from the scene.
       
  1399         QWidget *window = new QWidget;
       
  1400         QVBoxLayout *layout = new QVBoxLayout;
       
  1401         window->setLayout(layout);
       
  1402         QLineEdit *lineEdit = new QLineEdit;
       
  1403         layout->addWidget(lineEdit);
       
  1404         QGraphicsView *view = new QGraphicsView(&scene);
       
  1405         scene.setSceneRect(-20, -20, 200, 50);
       
  1406         layout->addWidget(view);
       
  1407         view->setMinimumSize(150, 50);
       
  1408         SubQGraphicsWidget *w1_1 = new SubQGraphicsWidget;
       
  1409         w1_1->setData(0, "w1_1");
       
  1410         w1_1->setGeometry(0,0,25, 25);
       
  1411         w1_1->setFocusPolicy(Qt::StrongFocus);
       
  1412         scene.addItem(w1_1);
       
  1413         SubQGraphicsWidget *w1_2 = new SubQGraphicsWidget;
       
  1414         w1_2->setData(0, "w1_2");
       
  1415         w1_2->setGeometry(25,0,25, 25);
       
  1416         w1_2->setFocusPolicy(Qt::StrongFocus);
       
  1417         scene.addItem(w1_2);
       
  1418         window->show();
       
  1419         QApplication::setActiveWindow(window);
       
  1420         QTest::qWaitForWindowShown(window);
       
  1421 
       
  1422         lineEdit->setFocus();
       
  1423         QTest::qWait(25);
       
  1424         QTRY_VERIFY(lineEdit->hasFocus());
       
  1425         QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
       
  1426         QTest::qWait(25);
       
  1427         QTRY_VERIFY(w1_1->hasFocus());
       
  1428         QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
       
  1429         QTest::qWait(25);
       
  1430         QTRY_VERIFY(w1_2->hasFocus());
       
  1431 
       
  1432         // remove the tabFocusFirst and insert new item
       
  1433         delete w1_1;            // calls _q_removeItemLater
       
  1434         QTest::qWait(25);
       
  1435         SubQGraphicsWidget *w1_3 = new SubQGraphicsWidget;
       
  1436         w1_3->setFocusPolicy(Qt::StrongFocus);
       
  1437         w1_3->setData(0, "w1_3");
       
  1438         w1_3->setGeometry(50,0,25, 25);
       
  1439         scene.addItem(w1_3);
       
  1440         QTRY_VERIFY(w1_2->hasFocus());
       
  1441         QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
       
  1442         QTest::qWait(25);
       
  1443         QTRY_VERIFY(lineEdit->hasFocus());
       
  1444         // tabFocusFirst should now point to w1_2
       
  1445         QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
       
  1446         QTest::qWait(25);
       
  1447         QTRY_VERIFY(w1_2->hasFocus());
       
  1448         QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
       
  1449         QTest::qWait(25);
       
  1450         QTRY_VERIFY(w1_3->hasFocus());
       
  1451         scene.removeItem(w1_2);   // does not call _q_removeItemLater
       
  1452         delete w1_2;            // calls _q_removeItemLater
       
  1453 
       
  1454         SubQGraphicsWidget *w1_4 = new SubQGraphicsWidget;
       
  1455         w1_4->setFocusPolicy(Qt::StrongFocus);
       
  1456         w1_4->setData(0, "w1_4");
       
  1457         w1_4->setGeometry(75,0,25, 25);
       
  1458         scene.addItem(w1_4);
       
  1459         QTRY_VERIFY(w1_3->hasFocus());
       
  1460         QTest::qWait(25);
       
  1461         QTRY_VERIFY(compareFocusChain(view, QList<QGraphicsItem*>() << w1_3 << w1_4));
       
  1462         QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
       
  1463         QTest::qWait(25);
       
  1464         QTRY_VERIFY(lineEdit->hasFocus());
       
  1465         // tabFocusFirst should now point to w1_3
       
  1466         QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
       
  1467         QTest::qWait(25);
       
  1468         QTRY_VERIFY(w1_3->hasFocus());
       
  1469         QTest::qWait(25);
       
  1470         QTRY_VERIFY(compareFocusChain(view, QList<QGraphicsItem*>() << w1_3 << w1_4));
       
  1471         delete window;
       
  1472     }
       
  1473 }
       
  1474 
       
  1475 void tst_QGraphicsWidget::updateFocusChainWhenChildDie()
       
  1476 {
       
  1477     QGraphicsScene scene;
       
  1478     QGraphicsView view(&scene);
       
  1479     view.show();
       
  1480 #ifdef Q_WS_X11
       
  1481     qt_x11_wait_for_window_manager(&view);
       
  1482 #endif
       
  1483     QApplication::setActiveWindow(&view);
       
  1484     QTest::qWait(25);
       
  1485     QTRY_COMPARE(QApplication::activeWindow(), &view);
       
  1486 
       
  1487     // delete item in focus chain with no focus and verify chain
       
  1488     SubQGraphicsWidget *parent = new SubQGraphicsWidget(0, Qt::Window);
       
  1489     SubQGraphicsWidget *w = new SubQGraphicsWidget(0, Qt::Window);
       
  1490     w->resize(50,50);
       
  1491     w->resize(100,100);
       
  1492     SubQGraphicsWidget *w1_1 = new SubQGraphicsWidget(w);
       
  1493     w1_1->setFocusPolicy(Qt::StrongFocus);
       
  1494     w->setFocusPolicy(Qt::StrongFocus);
       
  1495     scene.addItem(w);
       
  1496     scene.addItem(parent);
       
  1497     w1_1->setFocus();
       
  1498 
       
  1499     QVERIFY(w1_1->hasFocus());
       
  1500     QWidget myWidget(0);
       
  1501     QLineEdit edit(&myWidget);
       
  1502     myWidget.show();
       
  1503     edit.setFocus();
       
  1504     QTRY_VERIFY(edit.hasFocus());
       
  1505     delete w1_1;
       
  1506     myWidget.hide();
       
  1507     w->setParentItem(parent);
       
  1508     //We don't crash perfect
       
  1509     QVERIFY(w);
       
  1510     QTest::mouseMove(view.viewport());
       
  1511     QTest::mouseClick(view.viewport(), Qt::LeftButton, 0);
       
  1512     QTRY_COMPARE(qApp->activeWindow(), static_cast<QWidget *>(&view));
       
  1513     QTRY_COMPARE(scene.focusItem(), static_cast<QGraphicsItem *>(w));
       
  1514 }
       
  1515 
       
  1516 void tst_QGraphicsWidget::sizeHint_data()
       
  1517 {
       
  1518     QTest::addColumn<bool>("layout");
       
  1519     QTest::newRow("no layout") << false;
       
  1520     QTest::newRow("layout") << true;
       
  1521 }
       
  1522 
       
  1523 // QSizeF sizeHint(Qt::SizeHint which, QSizeF const& constraint = QSizeF()) const protected
       
  1524 void tst_QGraphicsWidget::sizeHint()
       
  1525 {
       
  1526     QFETCH(bool, layout);
       
  1527     SubQGraphicsWidget widget;
       
  1528 
       
  1529     if (layout) {
       
  1530         QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
       
  1531         widget.setLayout(layout);
       
  1532     }
       
  1533     widget.call_sizeHint(Qt::MinimumSize, QSizeF());
       
  1534 }
       
  1535 
       
  1536 void tst_QGraphicsWidget::consistentPosSizeGeometry_data()
       
  1537 {
       
  1538     QTest::addColumn<QSizeF>("minSize");
       
  1539     QTest::addColumn<QSizeF>("maxSize");
       
  1540     QTest::addColumn<QRectF>("geometry");
       
  1541     QTest::addColumn<QRectF>("expectedGeometry");
       
  1542 
       
  1543     QTest::newRow("size is valid") << QSizeF(0, 0) << QSizeF(200, 200) << QRectF(0, 0, 100, 100) << QRectF(0, 0, 100, 100);
       
  1544     QTest::newRow("size is larger than max") << QSizeF(0, 0) << QSizeF(50, 50) << QRectF(0, 0, 100, 100) << QRectF(0, 0, 50, 50);
       
  1545     QTest::newRow("size is smaller than min") << QSizeF(50, 50) << QSizeF(150, 150) << QRectF(0, 0, 10, 10) << QRectF(0, 0, 50, 50);
       
  1546 }
       
  1547 
       
  1548 void tst_QGraphicsWidget::consistentPosSizeGeometry()
       
  1549 {
       
  1550     QFETCH(QSizeF, minSize);
       
  1551     QFETCH(QSizeF, maxSize);
       
  1552     QFETCH(QRectF, geometry);
       
  1553     QFETCH(QRectF, expectedGeometry);
       
  1554 
       
  1555     QGraphicsScene scene;
       
  1556     QGraphicsView view(&scene);
       
  1557     QGraphicsWidget *w = new QGraphicsWidget;
       
  1558     scene.addItem(w);
       
  1559     w->setMinimumSize(minSize);
       
  1560     w->setMaximumSize(maxSize);
       
  1561     w->setGeometry(geometry);
       
  1562     QCOMPARE(w->geometry(), expectedGeometry);
       
  1563     QCOMPARE(w->pos(), expectedGeometry.topLeft());
       
  1564     QCOMPARE(w->size(), expectedGeometry.size());
       
  1565 
       
  1566     QRectF otherGeom = QRectF(QPointF(12.34,12.34), minSize);
       
  1567     w->setGeometry(otherGeom);
       
  1568     QCOMPARE(w->geometry(), otherGeom);
       
  1569     QCOMPARE(w->pos(), otherGeom.topLeft());
       
  1570     QCOMPARE(w->size(), otherGeom.size());
       
  1571 
       
  1572     w->setPos(geometry.topLeft());
       
  1573     QCOMPARE(w->geometry().topLeft(), expectedGeometry.topLeft());
       
  1574     QCOMPARE(w->pos(), expectedGeometry.topLeft());
       
  1575 
       
  1576     w->resize(geometry.size());
       
  1577     QCOMPARE(w->geometry().size(), expectedGeometry.size());
       
  1578     QCOMPARE(w->geometry(), expectedGeometry);
       
  1579 
       
  1580     view.show();
       
  1581 
       
  1582 }
       
  1583 
       
  1584 
       
  1585 enum WhichSize {
       
  1586     MinimumWidth,
       
  1587     PreferredWidth,
       
  1588     MaximumWidth,
       
  1589     MinimumHeight,
       
  1590     PreferredHeight,
       
  1591     MaximumHeight,
       
  1592     MinimumSize,
       
  1593     PreferredSize,
       
  1594     MaximumSize,
       
  1595     MinimumSizeHint,
       
  1596     PreferredSizeHint,
       
  1597     MaximumSizeHint,
       
  1598     Size,
       
  1599     None,
       
  1600 };
       
  1601 
       
  1602 typedef QPair<int, QVariant> Inst;
       
  1603 
       
  1604 Q_DECLARE_METATYPE(Inst)
       
  1605 Q_DECLARE_METATYPE(QVector<Inst>)
       
  1606 
       
  1607 void tst_QGraphicsWidget::setSizes_data()
       
  1608 {
       
  1609 
       
  1610     QTest::addColumn<QVector<Inst> >("inputInstructions");
       
  1611     QTest::addColumn<QVector<Inst> >("compareInstructions");
       
  1612 
       
  1613     QTest::newRow("minSize1") << (QVector<Inst>() << Inst(Size, QSize(25, 25)) << Inst(MinimumSize, QSize(10, 10)))
       
  1614                                 << (QVector<Inst>() << Inst(Size, QSize(25,25)));
       
  1615     QTest::newRow("minSize2") << (QVector<Inst>() << Inst(Size, QSizeF(20, 20)) << Inst(MinimumSize, QSizeF(25, 25)))
       
  1616                                  << (QVector<Inst>() << Inst(Size, QSizeF(25, 25)));
       
  1617     QTest::newRow("minWidth1") << (QVector<Inst>() << Inst(Size, QSizeF(20, 20)) << Inst(MinimumWidth, 5.0))
       
  1618                                  << (QVector<Inst>() << Inst(Size, QSizeF(20, 20)));
       
  1619     QTest::newRow("minWidth2") << (QVector<Inst>() << Inst(Size, QSizeF(20, 20)) << Inst(MinimumWidth, 25.0))
       
  1620                                  << (QVector<Inst>() << Inst(Size, QSizeF(25, 20)));
       
  1621     QTest::newRow("minHeight1") << (QVector<Inst>() << Inst(Size, QSizeF(20, 20)) << Inst(MinimumHeight, 5.0))
       
  1622                                  << (QVector<Inst>() << Inst(Size, QSizeF(20, 20)));
       
  1623     QTest::newRow("minHeight2") << (QVector<Inst>() << Inst(Size, QSizeF(20, 20)) << Inst(MinimumHeight, 25.0))
       
  1624                                  << (QVector<Inst>() << Inst(Size, QSizeF(20, 25)));
       
  1625     QTest::newRow("maxSize1") << (QVector<Inst>() << Inst(Size, QSizeF(40, 40)) << Inst(MaximumSize, QSizeF(30, 30)))
       
  1626                                  << (QVector<Inst>() << Inst(Size, QSizeF(30, 30)));
       
  1627     QTest::newRow("maxSize2") << (QVector<Inst>() << Inst(Size, QSizeF(40, 40)) << Inst(MaximumSize, QSizeF(30, -1)))
       
  1628                                  << (QVector<Inst>() << Inst(Size, QSizeF(30, 40)));
       
  1629     QTest::newRow("maxSize3") << (QVector<Inst>() << Inst(Size, QSizeF(40, 40)) << Inst(MaximumSize, QSizeF(-1, 30)))
       
  1630                                  << (QVector<Inst>() << Inst(Size, QSizeF(40, 30)));
       
  1631     QTest::newRow("maxWidth1")<< (QVector<Inst>() << Inst(Size, QSizeF(40, 40)) << Inst(MaximumWidth, 30))
       
  1632                                  << (QVector<Inst>() << Inst(Size, QSizeF(30, 40)));
       
  1633     QTest::newRow("maxHeight")<< (QVector<Inst>() << Inst(Size, QSizeF(40, 40)) << Inst(MaximumHeight, 20))
       
  1634                                  << (QVector<Inst>() << Inst(Size, QSizeF(40, 20)));
       
  1635     QTest::newRow("unsetMinSize")<< (QVector<Inst>() << Inst(Size, QSizeF(40, 40)) << Inst(MinimumSize, QSizeF(-1, -1)))
       
  1636                                  << (QVector<Inst>() << Inst(MinimumSize, QSizeF(5, 5)));
       
  1637     QTest::newRow("unsetMaxSize")<< (QVector<Inst>() << Inst(Size, QSizeF(40, 40)) << Inst(MaximumSize, QSizeF(-1, -1)))
       
  1638                                  << (QVector<Inst>() << Inst(MaximumSize, QSizeF(500, 500)));
       
  1639     QTest::newRow("unsetMinSize, expand size to minimumSizeHint") << (QVector<Inst>()
       
  1640                                         << Inst(MinimumSize, QSize(0, 0))
       
  1641                                         << Inst(Size, QSize(1,1))
       
  1642                                         << Inst(MinimumSize, QSize(-1.0, -1.0))
       
  1643                                         )
       
  1644                                     << (QVector<Inst>()
       
  1645                                         << Inst(Size, QSize(5,5))
       
  1646                                         << Inst(MinimumSize, QSize(5,5))
       
  1647                                         );
       
  1648 
       
  1649 }
       
  1650 
       
  1651 void tst_QGraphicsWidget::setSizes()
       
  1652 {
       
  1653     QFETCH(QVector<Inst>, inputInstructions);
       
  1654     QFETCH(QVector<Inst>, compareInstructions);
       
  1655 
       
  1656     QGraphicsScene scene;
       
  1657     QGraphicsView view(&scene);
       
  1658     SizeHinter *widget = new SizeHinter(0, Qt::Window);
       
  1659     QSizeF min = QSizeF(10, 10);
       
  1660     QSizeF pref = QSizeF(25, 25);
       
  1661     QSizeF max = QSizeF(50, 50);
       
  1662 
       
  1663     int i;
       
  1664     for (i = 0; i < inputInstructions.count(); ++i) {
       
  1665         Inst input = inputInstructions.at(i);
       
  1666 
       
  1667         // defaults
       
  1668         switch (input.first) {
       
  1669             case MinimumSize:
       
  1670                 min = input.second.toSizeF();
       
  1671                 break;
       
  1672             case PreferredSize:
       
  1673                 pref = input.second.toSizeF();
       
  1674                 break;
       
  1675             case MaximumSize:
       
  1676                 max = input.second.toSizeF();
       
  1677                 break;
       
  1678             case Size:
       
  1679                 widget->resize(input.second.toSizeF());
       
  1680                 break;
       
  1681             case MinimumWidth:
       
  1682                 widget->setMinimumWidth(qreal(input.second.toDouble()));
       
  1683                 break;
       
  1684             case PreferredWidth:
       
  1685                 widget->setPreferredWidth(qreal(input.second.toDouble()));
       
  1686                 break;
       
  1687             case MaximumWidth:
       
  1688                 widget->setMaximumWidth(qreal(input.second.toDouble()));
       
  1689                 break;
       
  1690             case MinimumHeight:
       
  1691                 widget->setMinimumHeight(qreal(input.second.toDouble()));
       
  1692                 break;
       
  1693             case PreferredHeight:
       
  1694                 widget->setPreferredHeight(qreal(input.second.toDouble()));
       
  1695                 break;
       
  1696             case MaximumHeight:
       
  1697                 widget->setMaximumHeight(qreal(input.second.toDouble()));
       
  1698                 break;
       
  1699             case MinimumSizeHint:
       
  1700                 widget->setSizeHint(Qt::MinimumSize, input.second.toSizeF());
       
  1701                 break;
       
  1702             case PreferredSizeHint:
       
  1703                 widget->setSizeHint(Qt::PreferredSize, input.second.toSizeF());
       
  1704                 break;
       
  1705             case MaximumSizeHint:
       
  1706                 widget->setSizeHint(Qt::MaximumSize, input.second.toSizeF());
       
  1707                 break;
       
  1708             default:
       
  1709                 qWarning("instruction not implemented");
       
  1710                 break;
       
  1711         }
       
  1712     }
       
  1713 
       
  1714     widget->setMinimumSize(min);
       
  1715     widget->setPreferredSize(pref);
       
  1716     widget->setMaximumSize(max);
       
  1717 
       
  1718     QApplication::processEvents();
       
  1719 
       
  1720     for (i = 0; i < compareInstructions.count(); ++i) {
       
  1721         Inst input = compareInstructions.at(i);
       
  1722         switch (input.first) {
       
  1723             case MinimumSize:
       
  1724                 QCOMPARE(widget->minimumSize(), input.second.toSizeF());
       
  1725                 break;
       
  1726             case PreferredSize:
       
  1727                 QCOMPARE(widget->preferredSize(), input.second.toSizeF());
       
  1728                 break;
       
  1729             case MaximumSize:
       
  1730                 QCOMPARE(widget->maximumSize(), input.second.toSizeF());
       
  1731                 break;
       
  1732             case Size:
       
  1733                 QCOMPARE(widget->size(), input.second.toSizeF());
       
  1734                 break;
       
  1735             case MinimumWidth:
       
  1736                 QCOMPARE(widget->minimumWidth(), qreal(input.second.toDouble()));
       
  1737                 break;
       
  1738             case PreferredWidth:
       
  1739                 QCOMPARE(widget->preferredWidth(), qreal(input.second.toDouble()));
       
  1740                 break;
       
  1741             case MaximumWidth:
       
  1742                 QCOMPARE(widget->maximumWidth(), qreal(input.second.toDouble()));
       
  1743                 break;
       
  1744             default:
       
  1745                 qWarning("instruction not implemented");
       
  1746                 break;
       
  1747         }
       
  1748     }
       
  1749     delete widget;
       
  1750 }
       
  1751 
       
  1752 void tst_QGraphicsWidget::closePopupOnOutsideClick()
       
  1753 {
       
  1754     QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Popup);
       
  1755     widget->resize(100, 100);
       
  1756 
       
  1757     QGraphicsScene scene;
       
  1758     scene.addItem(widget);
       
  1759 
       
  1760     QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
       
  1761     event.ignore();
       
  1762     event.setScenePos(QPointF(50, 50));
       
  1763     qApp->sendEvent(&scene, &event);
       
  1764 
       
  1765     QVERIFY(widget->isVisible());
       
  1766     QVERIFY(event.isAccepted());
       
  1767 
       
  1768     event.ignore();
       
  1769     event.setScenePos(QPointF(150, 150));
       
  1770     qApp->sendEvent(&scene, &event);
       
  1771 
       
  1772     QVERIFY(!widget->isVisible());
       
  1773     QVERIFY(event.isAccepted());
       
  1774 }
       
  1775 
       
  1776 void tst_QGraphicsWidget::task236127_bspTreeIndexFails()
       
  1777 {
       
  1778     QGraphicsWidget *widget = new QGraphicsWidget;
       
  1779     QGraphicsWidget *widget2 = new QGraphicsWidget;
       
  1780     widget->resize(10, 10);
       
  1781     widget2->resize(10, 10);
       
  1782     widget2->setZValue(1);
       
  1783     QCOMPARE(widget2->zValue(), qreal(1));
       
  1784     QCOMPARE(widget->zValue(), qreal(0));
       
  1785     widget->setData(0, "widget");
       
  1786     widget2->setData(0, "widget2");
       
  1787 
       
  1788     QGraphicsScene scene;
       
  1789     scene.addItem(widget);
       
  1790     scene.addItem(widget2);
       
  1791 
       
  1792     QGraphicsView view(&scene);
       
  1793     view.show();
       
  1794 #ifdef Q_WS_X11
       
  1795     qt_x11_wait_for_window_manager(&view);
       
  1796 #endif
       
  1797     QTest::qWait(100);
       
  1798 
       
  1799     QVERIFY(!scene.itemAt(25, 25));
       
  1800     widget->setGeometry(0, 112, 360, 528);
       
  1801     QCOMPARE(scene.itemAt(15, 120), (QGraphicsItem *)widget);
       
  1802     widget2->setGeometry(0, 573, 360, 67);
       
  1803     QCOMPARE(scene.itemAt(15, 120), (QGraphicsItem *)widget);
       
  1804     QCOMPARE(scene.itemAt(50, 585), (QGraphicsItem *)widget2);
       
  1805 }
       
  1806 
       
  1807 void tst_QGraphicsWidget::defaultSize()
       
  1808 {
       
  1809     SubQGraphicsWidget *widget = new SubQGraphicsWidget;
       
  1810     widget->setMinimumSize(40, 40);
       
  1811     QGraphicsScene scene;
       
  1812     scene.addItem(widget);
       
  1813 
       
  1814     QGraphicsView view(&scene);
       
  1815     view.show();
       
  1816 #ifdef Q_WS_X11
       
  1817     qt_x11_wait_for_window_manager(&view);
       
  1818 #endif
       
  1819     QTest::qWait(50);
       
  1820     QSizeF initialSize = widget->size();
       
  1821 
       
  1822     widget->resize(initialSize);
       
  1823     QCOMPARE(widget->geometry().size(), initialSize);
       
  1824     widget->setVisible(false);
       
  1825     widget->setMinimumSize(10, 10);
       
  1826     widget->setPreferredSize(60, 60);
       
  1827     widget->setMaximumSize(110, 110);
       
  1828     widget->setVisible(true);
       
  1829     QTest::qWait(50);
       
  1830     // should still have its size set to initialsize
       
  1831     QCOMPARE(widget->geometry().size(), initialSize);
       
  1832 
       
  1833 }
       
  1834 
       
  1835 void tst_QGraphicsWidget::explicitMouseGrabber()
       
  1836 {
       
  1837     QGraphicsWidget *widget = new QGraphicsWidget;
       
  1838     EventSpy widgetGrabEventSpy(widget, QEvent::GrabMouse);
       
  1839     EventSpy widgetUngrabEventSpy(widget, QEvent::UngrabMouse);
       
  1840 
       
  1841     // Grab without scene
       
  1842     QTest::ignoreMessage(QtWarningMsg, "QGraphicsItem::grabMouse: cannot grab mouse without scene");
       
  1843     widget->grabMouse();
       
  1844     QCOMPARE(widgetGrabEventSpy.count(), 0);
       
  1845     QTest::ignoreMessage(QtWarningMsg, "QGraphicsItem::ungrabMouse: cannot ungrab mouse without scene");
       
  1846     widget->ungrabMouse();
       
  1847     QCOMPARE(widgetUngrabEventSpy.count(), 0);
       
  1848 
       
  1849     // Add to scene
       
  1850     QGraphicsScene scene;
       
  1851     scene.addItem(widget);
       
  1852 
       
  1853     // Ungrab while not grabber
       
  1854     QTest::ignoreMessage(QtWarningMsg, "QGraphicsItem::ungrabMouse: not a mouse grabber");
       
  1855     widget->ungrabMouse();
       
  1856 
       
  1857     // Simple grab with scene
       
  1858     QVERIFY(!scene.mouseGrabberItem());
       
  1859     widget->grabMouse();
       
  1860     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
       
  1861     QCOMPARE(widgetGrabEventSpy.count(), 1);
       
  1862     widget->ungrabMouse();
       
  1863     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
  1864     QCOMPARE(widgetUngrabEventSpy.count(), 1);
       
  1865 
       
  1866     // Grab while grabbing
       
  1867     widget->grabMouse();
       
  1868     QCOMPARE(widgetGrabEventSpy.count(), 2);
       
  1869     QTest::ignoreMessage(QtWarningMsg, "QGraphicsItem::grabMouse: already a mouse grabber");
       
  1870     widget->grabMouse();
       
  1871     QCOMPARE(widgetGrabEventSpy.count(), 2);
       
  1872     QCOMPARE(widgetUngrabEventSpy.count(), 1);
       
  1873     widget->ungrabMouse();
       
  1874     QCOMPARE(widgetUngrabEventSpy.count(), 2);
       
  1875 
       
  1876     // Add two more widgets to the scene
       
  1877     QGraphicsWidget *widget2 = new QGraphicsWidget;
       
  1878     scene.addItem(widget2);
       
  1879     EventSpy widget2GrabEventSpy(widget2, QEvent::GrabMouse);
       
  1880     EventSpy widget2UngrabEventSpy(widget2, QEvent::UngrabMouse);
       
  1881     QGraphicsWidget *widget3 = new QGraphicsWidget;
       
  1882     scene.addItem(widget3);
       
  1883     EventSpy widget3GrabEventSpy(widget3, QEvent::GrabMouse);
       
  1884     EventSpy widget3UngrabEventSpy(widget3, QEvent::UngrabMouse);
       
  1885 
       
  1886     widget->setData(0, "widget");
       
  1887     widget2->setData(0, "widget2");
       
  1888     widget3->setData(0, "widget3");
       
  1889 
       
  1890     // Simple nested grabbing
       
  1891     widget->grabMouse();
       
  1892     QCOMPARE(widgetGrabEventSpy.count(), 3);
       
  1893     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
       
  1894     widget2->grabMouse();
       
  1895     QCOMPARE(widgetUngrabEventSpy.count(), 3);
       
  1896     QCOMPARE(widget2GrabEventSpy.count(), 1);
       
  1897     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget2);
       
  1898     widget3->grabMouse();
       
  1899     QCOMPARE(widget2UngrabEventSpy.count(), 1);
       
  1900     QCOMPARE(widget3GrabEventSpy.count(), 1);
       
  1901     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget3);
       
  1902     widget3->ungrabMouse();
       
  1903     QCOMPARE(widget3UngrabEventSpy.count(), 1);
       
  1904     QCOMPARE(widget2GrabEventSpy.count(), 2);
       
  1905     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget2);
       
  1906     widget2->ungrabMouse();
       
  1907     QCOMPARE(widget2UngrabEventSpy.count(), 2);
       
  1908     QCOMPARE(widgetGrabEventSpy.count(), 4);
       
  1909     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
       
  1910     widget->ungrabMouse();
       
  1911     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
  1912 
       
  1913     // Out of order ungrab
       
  1914     widget->grabMouse();
       
  1915     QCOMPARE(widgetGrabEventSpy.count(), 5);
       
  1916     widget2->grabMouse();
       
  1917     QCOMPARE(widget2GrabEventSpy.count(), 3);
       
  1918     widget3->grabMouse();
       
  1919     QCOMPARE(widget3GrabEventSpy.count(), 2);
       
  1920     widget2->ungrabMouse();
       
  1921     QCOMPARE(widget3UngrabEventSpy.count(), 2);
       
  1922     QCOMPARE(widget2UngrabEventSpy.count(), 4);
       
  1923     QCOMPARE(widgetGrabEventSpy.count(), 6);
       
  1924     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
       
  1925 }
       
  1926 
       
  1927 void tst_QGraphicsWidget::implicitMouseGrabber()
       
  1928 {
       
  1929     QGraphicsScene scene;
       
  1930     QGraphicsWidget *widget = new QGraphicsWidget;
       
  1931     widget->setFlag(QGraphicsItem::ItemIsMovable); // can grab mouse
       
  1932     widget->resize(200, 200);
       
  1933     EventSpy widgetGrabEventSpy(widget, QEvent::GrabMouse);
       
  1934     EventSpy widgetUngrabEventSpy(widget, QEvent::UngrabMouse);
       
  1935     scene.addItem(widget);
       
  1936 
       
  1937     QVERIFY(!scene.mouseGrabberItem());
       
  1938 
       
  1939     // Click on an item, see if gain and lose implicit mouse grab.
       
  1940     {
       
  1941         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
       
  1942         event.ignore();
       
  1943         event.setButton(Qt::LeftButton);
       
  1944         event.setScenePos(QPointF(50, 50));
       
  1945         qApp->sendEvent(&scene, &event);
       
  1946     }
       
  1947     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
       
  1948     QCOMPARE(widgetGrabEventSpy.count(), 1);
       
  1949     {
       
  1950         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
       
  1951         event.ignore();
       
  1952         event.setButton(Qt::LeftButton);
       
  1953         event.setScenePos(QPointF(50, 50));
       
  1954         qApp->sendEvent(&scene, &event);
       
  1955     }
       
  1956     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
  1957     QCOMPARE(widgetGrabEventSpy.count(), 1);
       
  1958     QCOMPARE(widgetUngrabEventSpy.count(), 1);
       
  1959 
       
  1960     // Click on an item that already grabs the mouse. Shouldn't have any effect.
       
  1961     widget->grabMouse();
       
  1962     QCOMPARE(widgetGrabEventSpy.count(), 2);
       
  1963     {
       
  1964         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
       
  1965         event.ignore();
       
  1966         event.setButton(Qt::LeftButton);
       
  1967         event.setScenePos(QPointF(50, 50));
       
  1968         qApp->sendEvent(&scene, &event);
       
  1969     }
       
  1970     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
       
  1971     QCOMPARE(widgetGrabEventSpy.count(), 2);
       
  1972     {
       
  1973         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
       
  1974         event.ignore();
       
  1975         event.setButton(Qt::LeftButton);
       
  1976         event.setScenePos(QPointF(50, 50));
       
  1977         qApp->sendEvent(&scene, &event);
       
  1978     }
       
  1979     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
       
  1980     QCOMPARE(widgetGrabEventSpy.count(), 2);
       
  1981     QCOMPARE(widgetUngrabEventSpy.count(), 1);
       
  1982     widget->ungrabMouse();
       
  1983     QCOMPARE(widgetUngrabEventSpy.count(), 2);
       
  1984     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
  1985 
       
  1986     // Implicit mouse grabber tries to explicitly grab the mouse
       
  1987     {
       
  1988         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
       
  1989         event.ignore();
       
  1990         event.setButton(Qt::LeftButton);
       
  1991         event.setScenePos(QPointF(50, 50));
       
  1992         qApp->sendEvent(&scene, &event);
       
  1993     }
       
  1994     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
       
  1995     QCOMPARE(widgetGrabEventSpy.count(), 3);
       
  1996     widget->grabMouse();
       
  1997     QCOMPARE(widgetUngrabEventSpy.count(), 2);
       
  1998     {
       
  1999         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
       
  2000         event.ignore();
       
  2001         event.setButton(Qt::LeftButton);
       
  2002         event.setScenePos(QPointF(50, 50));
       
  2003         qApp->sendEvent(&scene, &event);
       
  2004     }
       
  2005     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
       
  2006     QCOMPARE(widgetGrabEventSpy.count(), 3);
       
  2007     QCOMPARE(widgetUngrabEventSpy.count(), 2);
       
  2008     widget->ungrabMouse();
       
  2009     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
  2010     QCOMPARE(widgetGrabEventSpy.count(), 3);
       
  2011     QCOMPARE(widgetUngrabEventSpy.count(), 3);
       
  2012 
       
  2013     // Arrival of a new widget
       
  2014     QGraphicsWidget *widget2 = new QGraphicsWidget;
       
  2015     widget2->setFlag(QGraphicsItem::ItemIsMovable); // can grab mouse
       
  2016     widget2->resize(200, 200);
       
  2017     widget2->setPos(205, 0);
       
  2018     EventSpy widget2GrabEventSpy(widget2, QEvent::GrabMouse);
       
  2019     EventSpy widget2UngrabEventSpy(widget2, QEvent::UngrabMouse);
       
  2020     scene.addItem(widget2);
       
  2021 
       
  2022     // Implicit grab while there's an explicit grab is not possible.
       
  2023     widget->grabMouse();
       
  2024     QCOMPARE(widgetGrabEventSpy.count(), 4);
       
  2025     {
       
  2026         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
       
  2027         event.ignore();
       
  2028         event.setButton(Qt::LeftButton);
       
  2029         event.setScenePos(QPointF(250, 50));
       
  2030         qApp->sendEvent(&scene, &event);
       
  2031     }
       
  2032     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
       
  2033     QCOMPARE(widgetGrabEventSpy.count(), 4);
       
  2034     QCOMPARE(widget2GrabEventSpy.count(), 0);
       
  2035     QCOMPARE(widget2UngrabEventSpy.count(), 0);
       
  2036 
       
  2037     scene.removeItem(widget);
       
  2038     QCOMPARE(widgetUngrabEventSpy.count(), 4);
       
  2039     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
  2040 }
       
  2041 
       
  2042 class GrabOnPressItem : public QGraphicsRectItem
       
  2043 {
       
  2044 public:
       
  2045     GrabOnPressItem(const QRectF &rect)
       
  2046         : QGraphicsRectItem(rect),
       
  2047           npress(0), nrelease(0), ndoubleClick(0),
       
  2048           ngrab(0), nungrab(0)
       
  2049     {
       
  2050     }
       
  2051     int npress;
       
  2052     int nrelease;
       
  2053     int ndoubleClick;
       
  2054     int ngrab;
       
  2055     int nungrab;
       
  2056 protected:
       
  2057     bool sceneEvent(QEvent *event)
       
  2058     {
       
  2059         switch (event->type()) {
       
  2060         case QEvent::GrabMouse:
       
  2061             ++ngrab;
       
  2062             break;
       
  2063         case QEvent::UngrabMouse:
       
  2064             ++nungrab;
       
  2065             break;
       
  2066         default:
       
  2067             break;
       
  2068         }
       
  2069         return QGraphicsRectItem::sceneEvent(event);
       
  2070     }
       
  2071 
       
  2072     void mousePressEvent(QGraphicsSceneMouseEvent *)
       
  2073     {
       
  2074         grabMouse();
       
  2075         ++npress;
       
  2076     }
       
  2077     void mouseReleaseEvent(QGraphicsSceneMouseEvent *)
       
  2078     {
       
  2079         ungrabMouse();
       
  2080         ++nrelease;
       
  2081     }
       
  2082     void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *)
       
  2083     {
       
  2084         ++ndoubleClick;
       
  2085     }
       
  2086 };
       
  2087 
       
  2088 void tst_QGraphicsWidget::doubleClickAfterExplicitMouseGrab()
       
  2089 {
       
  2090     QGraphicsScene scene;
       
  2091     GrabOnPressItem *item = new GrabOnPressItem(QRectF(0, 0, 100, 100));
       
  2092     scene.addItem(item);
       
  2093 
       
  2094     {
       
  2095         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
       
  2096         event.setButton(Qt::LeftButton);
       
  2097         event.setButtons(Qt::LeftButton);
       
  2098         event.ignore();
       
  2099         event.setScenePos(QPointF(50, 50));
       
  2100         qApp->sendEvent(&scene, &event);
       
  2101     }
       
  2102     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)item);
       
  2103     QCOMPARE(item->npress, 1);
       
  2104     QCOMPARE(item->ngrab, 1);
       
  2105     {
       
  2106         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
       
  2107         event.setButton(Qt::LeftButton);
       
  2108         event.setButtons(0);
       
  2109         event.ignore();
       
  2110         event.setScenePos(QPointF(50, 50));
       
  2111         qApp->sendEvent(&scene, &event);
       
  2112     }
       
  2113     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
  2114     QCOMPARE(item->nrelease, 1);
       
  2115     QCOMPARE(item->nungrab, 1);
       
  2116     {
       
  2117         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseDoubleClick);
       
  2118         event.setButton(Qt::LeftButton);
       
  2119         event.setButtons(Qt::LeftButton);
       
  2120         event.ignore();
       
  2121         event.setScenePos(QPointF(50, 50));
       
  2122         qApp->sendEvent(&scene, &event);
       
  2123     }
       
  2124     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)item);
       
  2125     QCOMPARE(item->ndoubleClick, 1);
       
  2126     QCOMPARE(item->ngrab, 2);
       
  2127     {
       
  2128         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
       
  2129         event.setButton(Qt::LeftButton);
       
  2130         event.setButtons(0);
       
  2131         event.ignore();
       
  2132         event.setScenePos(QPointF(50, 50));
       
  2133         qApp->sendEvent(&scene, &event);
       
  2134     }
       
  2135     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
  2136     QCOMPARE(item->nrelease, 2);
       
  2137     QCOMPARE(item->nungrab, 2);
       
  2138 }
       
  2139 
       
  2140 void tst_QGraphicsWidget::popupMouseGrabber()
       
  2141 {
       
  2142     QGraphicsScene scene;
       
  2143     QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Popup);
       
  2144     widget->setFlag(QGraphicsItem::ItemIsMovable); // can grab mouse
       
  2145     widget->resize(200, 200);
       
  2146     EventSpy widgetGrabEventSpy(widget, QEvent::GrabMouse);
       
  2147     EventSpy widgetUngrabEventSpy(widget, QEvent::UngrabMouse);
       
  2148 
       
  2149     // Simply adding a visible popup to the scene immediately grabs the mouse.
       
  2150     scene.addItem(widget);
       
  2151     QCOMPARE(widgetGrabEventSpy.count(), 1);
       
  2152     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
       
  2153 
       
  2154     // Hiding it loses the grab again.
       
  2155     widget->hide();
       
  2156     QCOMPARE(widgetUngrabEventSpy.count(), 1);
       
  2157     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
       
  2158 
       
  2159     // Showing it grabs the mosue again
       
  2160     widget->show();
       
  2161     QCOMPARE(widgetGrabEventSpy.count(), 2);
       
  2162     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
       
  2163 
       
  2164     // Add two popups
       
  2165     QGraphicsWidget *widget2 = new QGraphicsWidget(0, Qt::Popup);
       
  2166     widget2->setFlag(QGraphicsItem::ItemIsMovable); // can grab mouse
       
  2167     widget2->resize(200, 200);
       
  2168     EventSpy widget2GrabEventSpy(widget2, QEvent::GrabMouse);
       
  2169     EventSpy widget2UngrabEventSpy(widget2, QEvent::UngrabMouse);
       
  2170     QGraphicsWidget *widget3 = new QGraphicsWidget(0, Qt::Popup);
       
  2171     widget3->setFlag(QGraphicsItem::ItemIsMovable); // can grab mouse
       
  2172     widget3->resize(200, 200);
       
  2173     EventSpy widget3GrabEventSpy(widget3, QEvent::GrabMouse);
       
  2174     EventSpy widget3UngrabEventSpy(widget3, QEvent::UngrabMouse);
       
  2175 
       
  2176     // Adding to the scene grabs
       
  2177     scene.addItem(widget2);
       
  2178     QCOMPARE(widgetUngrabEventSpy.count(), 2);
       
  2179     QCOMPARE(widget2GrabEventSpy.count(), 1);
       
  2180     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget2);
       
  2181 
       
  2182     // Adding to the scene grabs again
       
  2183     scene.addItem(widget3);
       
  2184     QCOMPARE(widget2UngrabEventSpy.count(), 1);
       
  2185     QCOMPARE(widget3GrabEventSpy.count(), 1);
       
  2186     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget3);
       
  2187 
       
  2188     // Hiding the topmost widget causes widget 2 to regain grab.
       
  2189     widget3->hide();
       
  2190     QCOMPARE(widget2GrabEventSpy.count(), 2);
       
  2191     QCOMPARE(widget3UngrabEventSpy.count(), 1);
       
  2192     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget2);
       
  2193     widget3->show();
       
  2194     QCOMPARE(widget2UngrabEventSpy.count(), 2);
       
  2195     QCOMPARE(widget3GrabEventSpy.count(), 2);
       
  2196     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget3);
       
  2197 
       
  2198     // Clicking outside the popup still causes it to close (despite that it's
       
  2199     // an explicit mouse grabber).
       
  2200     {
       
  2201         QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
       
  2202         event.ignore();
       
  2203         event.setButton(Qt::LeftButton);
       
  2204         event.setScenePos(QPointF(500, 500)); // outside
       
  2205         qApp->sendEvent(&scene, &event);
       
  2206     }
       
  2207     QVERIFY(!widget3->isVisible());
       
  2208     QCOMPARE(widget3UngrabEventSpy.count(), 2);
       
  2209     QCOMPARE(widget2GrabEventSpy.count(), 3);
       
  2210     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget2);
       
  2211     QVERIFY(widget2->isVisible());
       
  2212     QVERIFY(widget->isVisible());
       
  2213     widget3->show();
       
  2214     QCOMPARE(widget3GrabEventSpy.count(), 3);
       
  2215     QCOMPARE(widget2UngrabEventSpy.count(), 3);
       
  2216     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget3);
       
  2217 
       
  2218     // This is something of a curiosity. What happens if you call
       
  2219     // ungrabMouse() on a popup? The answer is - it loses the grab. If you
       
  2220     // hide and show the popup again, it will regain the grab.
       
  2221     widget3->ungrabMouse();
       
  2222     QCOMPARE(widget3UngrabEventSpy.count(), 3);
       
  2223     QCOMPARE(widget2GrabEventSpy.count(), 4);
       
  2224     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget2);
       
  2225     widget3->hide();
       
  2226     widget3->show();
       
  2227     QCOMPARE(widget3GrabEventSpy.count(), 4);
       
  2228     QCOMPARE(widget2UngrabEventSpy.count(), 4);
       
  2229     QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget3);
       
  2230 }
       
  2231 
       
  2232 void tst_QGraphicsWidget::windowFlags_data()
       
  2233 {
       
  2234     QTest::addColumn<int>("inputFlags");
       
  2235     QTest::addColumn<int>("outputFlags");
       
  2236 
       
  2237     QTest::newRow("nil") << 0 << 0;
       
  2238 
       
  2239     // Window types
       
  2240     QTest::newRow("Qt::Window") << int(Qt::Window)
       
  2241                                 << int(Qt::Window | Qt::WindowTitleHint | Qt::WindowSystemMenuHint
       
  2242                                        | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
       
  2243     QTest::newRow("Qt::SubWindow") << int(Qt::SubWindow)
       
  2244                                    << int(Qt::SubWindow | Qt::WindowTitleHint | Qt::WindowSystemMenuHint
       
  2245                                           | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
       
  2246     QTest::newRow("Qt::Dialog") << int(Qt::Dialog)
       
  2247                                 << int(Qt::Dialog | Qt::WindowTitleHint | Qt::WindowSystemMenuHint
       
  2248                                        | Qt::WindowContextHelpButtonHint);
       
  2249     QTest::newRow("Qt::Sheet") << int(Qt::Sheet)
       
  2250                                << int(Qt::Sheet | Qt::WindowTitleHint | Qt::WindowSystemMenuHint
       
  2251                                       | Qt::WindowContextHelpButtonHint);
       
  2252     QTest::newRow("Qt::Tool") << int(Qt::Tool)
       
  2253                               << int(Qt::Tool | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
       
  2254 
       
  2255     // Custom window flags
       
  2256     QTest::newRow("Qt::FramelessWindowHint") << int(Qt::FramelessWindowHint)
       
  2257                                              << int(Qt::FramelessWindowHint);
       
  2258     QTest::newRow("Qt::CustomizeWindowHint") << int(Qt::CustomizeWindowHint)
       
  2259                                              << int(Qt::CustomizeWindowHint);
       
  2260 }
       
  2261 
       
  2262 void tst_QGraphicsWidget::windowFlags()
       
  2263 {
       
  2264     QFETCH(int, inputFlags);
       
  2265     QFETCH(int, outputFlags);
       
  2266 
       
  2267     // Construct with flags set already
       
  2268     QGraphicsWidget widget(0, Qt::WindowFlags(inputFlags));
       
  2269     QCOMPARE(widget.windowFlags(), Qt::WindowFlags(outputFlags));
       
  2270 
       
  2271     // Set flags after construction
       
  2272     QGraphicsWidget widget2;
       
  2273     widget2.setWindowFlags(Qt::WindowFlags(inputFlags));
       
  2274     QCOMPARE(widget2.windowFlags(), Qt::WindowFlags(outputFlags));
       
  2275 
       
  2276     // Reset flags
       
  2277     widget2.setWindowFlags(0);
       
  2278     QVERIFY(!widget2.windowFlags());
       
  2279 
       
  2280     // Set flags back again
       
  2281     widget2.setWindowFlags(Qt::WindowFlags(inputFlags));
       
  2282     QCOMPARE(widget2.windowFlags(), Qt::WindowFlags(outputFlags));
       
  2283 
       
  2284     // Construct with custom flags set already
       
  2285     QGraphicsWidget widget3(0, Qt::WindowFlags(inputFlags | Qt::FramelessWindowHint));
       
  2286     QCOMPARE(widget3.windowFlags(), Qt::WindowFlags(inputFlags | Qt::FramelessWindowHint));
       
  2287 
       
  2288     // Set custom flags after construction
       
  2289     QGraphicsWidget widget4;
       
  2290     widget4.setWindowFlags(Qt::WindowFlags(inputFlags | Qt::FramelessWindowHint));
       
  2291     QCOMPARE(widget4.windowFlags(), Qt::WindowFlags(inputFlags | Qt::FramelessWindowHint));
       
  2292 
       
  2293     // Reset flags
       
  2294     widget4.setWindowFlags(0);
       
  2295     QVERIFY(!widget4.windowFlags());
       
  2296 
       
  2297     // Set custom flags back again
       
  2298     widget4.setWindowFlags(Qt::WindowFlags(inputFlags | Qt::FramelessWindowHint));
       
  2299     QCOMPARE(widget4.windowFlags(), Qt::WindowFlags(inputFlags | Qt::FramelessWindowHint));
       
  2300 
       
  2301     QGraphicsWidget *widget5 = new QGraphicsWidget;
       
  2302     widget5->setWindowFlags(Qt::WindowFlags(inputFlags));
       
  2303     QCOMPARE(widget5->windowFlags(), Qt::WindowFlags(outputFlags));
       
  2304     QGraphicsWidget window(0, Qt::Window);
       
  2305     widget5->setParentItem(&window);
       
  2306     QCOMPARE(widget5->windowFlags(), Qt::WindowFlags(outputFlags));
       
  2307 }
       
  2308 
       
  2309 void tst_QGraphicsWidget::shortcutsDeletion()
       
  2310 {
       
  2311     QGraphicsWidget *widget = new QGraphicsWidget;
       
  2312     QGraphicsWidget *widget2 = new QGraphicsWidget;
       
  2313     widget->setMinimumSize(40, 40);
       
  2314     QWidgetAction *del = new QWidgetAction(widget);
       
  2315     del->setIcon(QIcon("edit-delete"));
       
  2316     del->setShortcut(Qt::Key_Delete);
       
  2317     del->setShortcutContext(Qt::WidgetShortcut);
       
  2318     widget2->addAction(del);
       
  2319     widget2->addAction(del);
       
  2320     delete widget;
       
  2321 }
       
  2322 
       
  2323 class MessUpPainterWidget : public QGraphicsWidget
       
  2324 {
       
  2325 public:
       
  2326     MessUpPainterWidget(QGraphicsItem * parent = 0, Qt::WindowFlags wFlags = 0)
       
  2327     : QGraphicsWidget(parent, wFlags)
       
  2328     {}
       
  2329 
       
  2330     void paintWindowFrame(QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
       
  2331     {
       
  2332         QCOMPARE(painter->opacity(), 1.0);
       
  2333         painter->setOpacity(0.0);
       
  2334         QGraphicsWidget::paintWindowFrame(painter, option, widget);
       
  2335     }
       
  2336     void paint(QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
       
  2337     {
       
  2338         QCOMPARE(painter->opacity(), 1.0);
       
  2339         painter->drawRect(0, 0, 100, 100);
       
  2340         QGraphicsWidget::paint(painter, option, widget);
       
  2341     }
       
  2342 
       
  2343 };
       
  2344 
       
  2345 void tst_QGraphicsWidget::painterStateProtectionOnWindowFrame()
       
  2346 {
       
  2347     MessUpPainterWidget *widget = new MessUpPainterWidget(0, Qt::Window);
       
  2348     QGraphicsScene scene(0, 0, 300, 300);
       
  2349     QGraphicsView view(&scene);
       
  2350     scene.addItem(widget);
       
  2351     view.show();
       
  2352     QTest::qWaitForWindowShown(&view);
       
  2353     QTest::qWait(500);
       
  2354 }
       
  2355 
       
  2356 class ProxyStyle : public QCommonStyle
       
  2357 {
       
  2358 public:
       
  2359     ProxyStyle(QStyle *proxyStyle) : QCommonStyle()
       
  2360     {
       
  2361         m_proxyStyle = proxyStyle;
       
  2362     }
       
  2363 
       
  2364     int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const
       
  2365     {
       
  2366         return m_proxyStyle->pixelMetric(metric, option, widget);
       
  2367     }
       
  2368 
       
  2369 private:
       
  2370     QStyle *m_proxyStyle;
       
  2371 };
       
  2372 
       
  2373 class StyledGraphicsWidget : public QGraphicsWidget
       
  2374 {
       
  2375 public:
       
  2376     StyledGraphicsWidget(bool useOwnStyle) : QGraphicsWidget(), m_style(0) {
       
  2377         if (useOwnStyle) {
       
  2378             QStyle *oldStyle = style();
       
  2379             m_style = new ProxyStyle(oldStyle);
       
  2380             setStyle(m_style);
       
  2381         }
       
  2382 
       
  2383         style()->pixelMetric(QStyle::PM_SmallIconSize); // crash when style() is still in widgetStyles
       
  2384     }
       
  2385 
       
  2386     ~StyledGraphicsWidget() {
       
  2387         delete m_style;
       
  2388     }
       
  2389 
       
  2390 private:
       
  2391     QStyle *m_style;
       
  2392 };
       
  2393 
       
  2394 void tst_QGraphicsWidget::task243004_setStyleCrash()
       
  2395 {
       
  2396     QGraphicsItem *item1 = new StyledGraphicsWidget(true);
       
  2397     delete item1; // item1 not removed from widgetStyles
       
  2398 
       
  2399     QGraphicsItem *item2 = new StyledGraphicsWidget(false);
       
  2400     delete item2;
       
  2401 }
       
  2402 
       
  2403 class GraphicsWidget_task250119 : public QGraphicsWidget
       
  2404 {
       
  2405 public:
       
  2406     GraphicsWidget_task250119()
       
  2407         : shortcutEvents(0)
       
  2408     {
       
  2409         setFocusPolicy(Qt::StrongFocus);
       
  2410         resize(100, 100);
       
  2411     }
       
  2412 
       
  2413     int shortcutEvents;
       
  2414 
       
  2415 private:
       
  2416     bool event(QEvent *event)
       
  2417     {
       
  2418         if (event->type() == QEvent::Shortcut)
       
  2419             shortcutEvents++;
       
  2420         return QGraphicsWidget::event(event);
       
  2421     }
       
  2422 
       
  2423     void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
       
  2424     {
       
  2425         if (hasFocus()) {
       
  2426             painter->setPen(QPen(Qt::black, 0, Qt::DashLine));
       
  2427             painter->drawRect(rect());
       
  2428         }
       
  2429         painter->setPen(QPen(Qt::black, 0, Qt::SolidLine));
       
  2430         painter->fillRect(rect().adjusted(2, 2, -2, -2), Qt::yellow);
       
  2431         painter->drawRect(rect().adjusted(2, 2, -2, -2));
       
  2432     }
       
  2433 };
       
  2434 
       
  2435 void tst_QGraphicsWidget::task250119_shortcutContext()
       
  2436 {
       
  2437     QGraphicsScene scene;
       
  2438     QGraphicsView view;
       
  2439     view.setScene(&scene);
       
  2440     view.show();
       
  2441     QApplication::setActiveWindow(&view);
       
  2442     QTest::qWait(25);
       
  2443     QTRY_COMPARE(QApplication::activeWindow(), &view);
       
  2444 
       
  2445 
       
  2446     // *** Event: ***
       
  2447 
       
  2448     GraphicsWidget_task250119 w_event;
       
  2449     scene.addItem(&w_event);
       
  2450 
       
  2451     const int id = w_event.grabShortcut(Qt::Key_A, Qt::WidgetWithChildrenShortcut);
       
  2452     w_event.setShortcutEnabled(id, true);
       
  2453 
       
  2454     w_event.setFocus();
       
  2455     QTest::keyPress(&view, Qt::Key_A);
       
  2456     QCOMPARE(w_event.shortcutEvents, 1);
       
  2457 
       
  2458     w_event.clearFocus();
       
  2459     QTest::keyPress(&view, Qt::Key_A);
       
  2460     QCOMPARE(w_event.shortcutEvents, 1);
       
  2461 
       
  2462     scene.removeItem(&w_event);
       
  2463 
       
  2464 
       
  2465     // *** Signal: ***
       
  2466 
       
  2467     GraphicsWidget_task250119 w_signal;
       
  2468     scene.addItem(&w_signal);
       
  2469 
       
  2470     QAction action(0);
       
  2471     action.setShortcut(Qt::Key_B);
       
  2472     action.setShortcutContext(Qt::WidgetWithChildrenShortcut);
       
  2473     QSignalSpy spy(&action, SIGNAL(triggered()));
       
  2474 
       
  2475     w_signal.addAction(&action);
       
  2476 
       
  2477     w_signal.setFocus();
       
  2478     QTest::keyPress(&view, Qt::Key_B);
       
  2479     QCOMPARE(spy.count(), 1);
       
  2480 
       
  2481     w_signal.clearFocus();
       
  2482     QTest::keyPress(&view, Qt::Key_B);
       
  2483     QCOMPARE(spy.count(), 1);
       
  2484 
       
  2485     scene.removeItem(&w_signal);
       
  2486 }
       
  2487 
       
  2488 class ClippingAndTransformsScene : public QGraphicsScene
       
  2489 {
       
  2490 public:
       
  2491     QList<QGraphicsItem *> drawnItems;
       
  2492 protected:
       
  2493     void drawItems(QPainter *painter, int numItems, QGraphicsItem *items[],
       
  2494                    const QStyleOptionGraphicsItem options[], QWidget *widget = 0)
       
  2495     {
       
  2496         drawnItems.clear();
       
  2497         for (int i = 0; i < numItems; ++i)
       
  2498             drawnItems << items[i];
       
  2499         QGraphicsScene::drawItems(painter, numItems, items, options, widget);
       
  2500     }
       
  2501 };
       
  2502 
       
  2503 class RectWidget : public QGraphicsWidget
       
  2504 {
       
  2505 public:
       
  2506 
       
  2507     RectWidget(Qt::GlobalColor color, QGraphicsItem *parent=0) : QGraphicsWidget(parent), mColor(color) {}
       
  2508 
       
  2509     void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
       
  2510     {
       
  2511         painter->setBrush(QBrush(mColor));
       
  2512         painter->drawRect(boundingRect());
       
  2513     }
       
  2514 
       
  2515     Qt::GlobalColor mColor;
       
  2516 };
       
  2517 
       
  2518 class RectItem : public QGraphicsItem
       
  2519 {
       
  2520 public:
       
  2521 
       
  2522     RectItem(Qt::GlobalColor color, QGraphicsItem *parent=0) : QGraphicsItem(parent), mColor(color) {}
       
  2523 
       
  2524     QRectF boundingRect() const
       
  2525     {return QRectF(10,10,50,50);}
       
  2526 
       
  2527     void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
       
  2528     {
       
  2529         painter->setBrush(QBrush(mColor));
       
  2530         painter->drawRect(boundingRect());
       
  2531     }
       
  2532 
       
  2533     Qt::GlobalColor mColor;
       
  2534 };
       
  2535 
       
  2536 void tst_QGraphicsWidget::ensureClipping()
       
  2537 {
       
  2538     ClippingAndTransformsScene scene;
       
  2539     scene.setSceneRect(-50, -50, 200, 200);
       
  2540 
       
  2541     //A root that clip children
       
  2542     RectWidget *clipWidget = new RectWidget(Qt::black);
       
  2543     scene.addItem(clipWidget);
       
  2544 
       
  2545     clipWidget->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
       
  2546 
       
  2547     //a child
       
  2548     RectWidget *childWidget = new RectWidget(Qt::red, clipWidget);
       
  2549     clipWidget->setGeometry(QRectF(10, 10, 100, 100));
       
  2550     childWidget->setGeometry(QRectF(25, 25, 50, 50));
       
  2551 
       
  2552     //We put a QGraphicsItem to be sure this one is also paint
       
  2553     RectItem *childitem = new RectItem(Qt::blue, clipWidget);
       
  2554 
       
  2555     QGraphicsView view(&scene);
       
  2556     view.setOptimizationFlag(QGraphicsView::IndirectPainting);
       
  2557     view.show();
       
  2558     QTest::qWaitForWindowShown(&view);
       
  2559 
       
  2560     QList<QGraphicsItem *> expected;
       
  2561     expected << clipWidget << childWidget << childitem;
       
  2562     QTRY_VERIFY(scene.drawnItems.contains(clipWidget));
       
  2563     QVERIFY(scene.drawnItems.contains(childWidget));
       
  2564     QVERIFY(scene.drawnItems.contains(childitem));
       
  2565 }
       
  2566 
       
  2567 class ItemChangeTester : public QGraphicsWidget
       
  2568 {
       
  2569 public:
       
  2570     ItemChangeTester()
       
  2571     { setFlag(ItemSendsGeometryChanges); clear(); }
       
  2572     ItemChangeTester(QGraphicsItem *parent) : QGraphicsWidget(parent)
       
  2573     { setFlag(ItemSendsGeometryChanges); clear(); }
       
  2574 
       
  2575     void clear()
       
  2576     {
       
  2577         changes.clear();
       
  2578         values.clear();
       
  2579         oldValues.clear();
       
  2580     }
       
  2581     QList<GraphicsItemChange> changes;
       
  2582     QList<QVariant> values;
       
  2583     QList<QVariant> oldValues;
       
  2584 protected:
       
  2585     QVariant itemChange(GraphicsItemChange change, const QVariant &value)
       
  2586     {
       
  2587         changes << change;
       
  2588         values << value;
       
  2589         switch (change) {
       
  2590         case QGraphicsItem::ItemPositionChange:
       
  2591             oldValues << pos();
       
  2592             break;
       
  2593         case QGraphicsItem::ItemPositionHasChanged:
       
  2594             break;
       
  2595         default:
       
  2596             break;
       
  2597         }
       
  2598         return value;
       
  2599     }
       
  2600 };
       
  2601 
       
  2602 void tst_QGraphicsWidget::widgetSendsGeometryChanges()
       
  2603 {
       
  2604     ItemChangeTester widget;
       
  2605     widget.setFlags(0);
       
  2606     widget.clear();
       
  2607 
       
  2608     QPointF pos(10, 10);
       
  2609     widget.setPos(pos);
       
  2610 
       
  2611     QCOMPARE(widget.pos(), pos);
       
  2612     QCOMPARE(widget.changes.size(), 0);
       
  2613 
       
  2614     widget.setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
       
  2615     QCOMPARE(widget.changes.size(), 2);
       
  2616 
       
  2617     widget.setPos(QPointF());
       
  2618     QCOMPARE(widget.changes.size(), 4);
       
  2619 
       
  2620     QCOMPARE(widget.pos(), QPointF());
       
  2621 
       
  2622     QRectF geometry(20, 20, 50, 50);
       
  2623     widget.setGeometry(geometry);
       
  2624     QCOMPARE(widget.changes.size(), 6);
       
  2625 
       
  2626     QCOMPARE(widget.geometry(), geometry);
       
  2627 
       
  2628     QCOMPARE(widget.changes, QList<QGraphicsItem::GraphicsItemChange>()
       
  2629          << QGraphicsItem::ItemFlagsChange
       
  2630          << QGraphicsItem::ItemFlagsHaveChanged
       
  2631          << QGraphicsItem::ItemPositionChange
       
  2632          << QGraphicsItem::ItemPositionHasChanged
       
  2633          << QGraphicsItem::ItemPositionChange
       
  2634          << QGraphicsItem::ItemPositionHasChanged);
       
  2635 }
       
  2636 
       
  2637 class HFWWidget : public QGraphicsWidget
       
  2638 {
       
  2639 public:
       
  2640     HFWWidget() : QGraphicsWidget(0, Qt::Window)
       
  2641     {
       
  2642         QSizePolicy sp;
       
  2643         sp.setHeightForWidth(true);
       
  2644         setSizePolicy(sp);
       
  2645     }
       
  2646 
       
  2647     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
       
  2648     {
       
  2649         Q_UNUSED(option);
       
  2650         Q_UNUSED(widget);
       
  2651         qreal w = rect().width();
       
  2652         QRectF box(0, 0, w, 2400/w);
       
  2653         painter->drawRoundRect(box);
       
  2654         painter->drawLine(box.topLeft(), box.bottomRight());
       
  2655         painter->drawLine(box.bottomLeft(), box.topRight());
       
  2656     }
       
  2657 
       
  2658 protected:
       
  2659     QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const
       
  2660     {
       
  2661         qreal w = constraint.width();
       
  2662         switch (which) {
       
  2663         case Qt::MinimumSize:
       
  2664             if (w >= 0 && constraint.height() < 0) {
       
  2665                 // keep the same area of 60x40 = 2400
       
  2666                 return QSizeF(w, 2400.0/w);
       
  2667             } else {
       
  2668                 return QSizeF(10, 10);
       
  2669             }
       
  2670             break;
       
  2671         case Qt::PreferredSize:
       
  2672             return QSizeF(48.989794, 48.989794);
       
  2673             default:
       
  2674             break;
       
  2675         }
       
  2676         return QGraphicsWidget::sizeHint(which, constraint);
       
  2677     }
       
  2678 };
       
  2679 
       
  2680 void tst_QGraphicsWidget::respectHFW()
       
  2681 {
       
  2682 #if defined(Q_OS_WINCE) || defined(Q_OS_MAC) || defined(Q_WS_QWS)
       
  2683     qDebug("This test is platform dependent, it fails on wince, mac and qws. Please fix.");
       
  2684 #else
       
  2685     QGraphicsScene scene;
       
  2686     HFWWidget *window = new HFWWidget;
       
  2687     scene.addItem(window);
       
  2688     QGraphicsView *view = new QGraphicsView(&scene);
       
  2689     view->resize(400, 400);
       
  2690     view->setSceneRect(-100, -100, 300,300);
       
  2691 
       
  2692     view->show();
       
  2693     window->setGeometry(0, 0, 70, 70);
       
  2694     QTest::qWaitForWindowShown(view);
       
  2695 
       
  2696     {   // here we go - simulate a interactive resize of the window
       
  2697         QTest::qWait(100);
       
  2698         QTest::mouseMove(view, view->mapFromScene(71, 71)); // bottom right corner
       
  2699         QTest::qWait(100);
       
  2700 
       
  2701         QTest::mousePress(view->viewport(), Qt::LeftButton, 0, view->mapFromScene(71, 71), 200);
       
  2702         view->grabMouse();
       
  2703         // move both mouse cursor and set correct event in order to emulate resize
       
  2704         QTest::mouseMove(view->viewport(), view->mapFromScene(60, 30), 200);
       
  2705         QMouseEvent e = QMouseEvent(QEvent::MouseMove,
       
  2706                       view->mapFromScene(60, 20),
       
  2707                       Qt::NoButton,
       
  2708                       Qt::LeftButton,
       
  2709                       Qt::NoModifier);
       
  2710         QApplication::sendEvent(view->viewport(), &e);
       
  2711         view->releaseMouse();
       
  2712     }
       
  2713     QTest::qWait(100);
       
  2714     const QSizeF winSize = window->size();
       
  2715     qreal minHFW = window->effectiveSizeHint(Qt::MinimumSize, QSizeF(winSize.width(), -1)).height();
       
  2716     QVERIFY(qAbs(minHFW - winSize.height()) < 1);
       
  2717 #endif
       
  2718 }
       
  2719 
       
  2720 class PolishWidget : public QGraphicsWidget
       
  2721 {
       
  2722 public:
       
  2723 
       
  2724     PolishWidget(Qt::GlobalColor color, QGraphicsItem *parent=0) :
       
  2725     QGraphicsWidget(parent), mColor(color)
       
  2726     {
       
  2727     }
       
  2728 
       
  2729     void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
       
  2730     {
       
  2731         painter->setBrush(QBrush(mColor));
       
  2732         painter->drawRect(boundingRect());
       
  2733     }
       
  2734 
       
  2735     void polishEvent()
       
  2736     {
       
  2737         if (!parentWidget()) {
       
  2738             //We add a child in the polish event for the parent
       
  2739             PolishWidget *childWidget = new PolishWidget(Qt::black, this);
       
  2740             childWidget->setGeometry(QRectF(10,10,30,30));
       
  2741         }
       
  2742 
       
  2743         QGraphicsWidget::polishEvent();
       
  2744         mColor = Qt::red;
       
  2745         update();
       
  2746         numberOfPolish++;
       
  2747     }
       
  2748 
       
  2749     static int numberOfPolish;
       
  2750 
       
  2751 private:
       
  2752     Qt::GlobalColor mColor;
       
  2753 };
       
  2754 
       
  2755 int PolishWidget::numberOfPolish = 0;
       
  2756 
       
  2757 void tst_QGraphicsWidget::addChildInpolishEvent()
       
  2758 {
       
  2759     QGraphicsScene scene;
       
  2760 
       
  2761     PolishWidget *parentWidget = new PolishWidget(Qt::white);
       
  2762     scene.addItem(parentWidget);
       
  2763 
       
  2764     QGraphicsView view(&scene);
       
  2765     view.resize(200, 200);
       
  2766     view.show();
       
  2767     QTest::qWaitForWindowShown(&view);
       
  2768     QCOMPARE(PolishWidget::numberOfPolish, 2);
       
  2769 }
       
  2770 
       
  2771 
       
  2772 QTEST_MAIN(tst_QGraphicsWidget)
       
  2773 #include "tst_qgraphicswidget.moc"
       
  2774 
       
  2775 #else // QT_NO_STYLE_CLEANLOOKS
       
  2776 QTEST_NOOP_MAIN
       
  2777 #endif
       
  2778