summaryrefslogtreecommitdiffstats
path: root/tests/auto/qgraphicswidget
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /tests/auto/qgraphicswidget
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'tests/auto/qgraphicswidget')
-rw-r--r--tests/auto/qgraphicswidget/.gitignore1
-rw-r--r--tests/auto/qgraphicswidget/qgraphicswidget.pro4
-rw-r--r--tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp3416
3 files changed, 3421 insertions, 0 deletions
diff --git a/tests/auto/qgraphicswidget/.gitignore b/tests/auto/qgraphicswidget/.gitignore
new file mode 100644
index 0000000000..ae39b803e5
--- /dev/null
+++ b/tests/auto/qgraphicswidget/.gitignore
@@ -0,0 +1 @@
+tst_qgraphicswidget
diff --git a/tests/auto/qgraphicswidget/qgraphicswidget.pro b/tests/auto/qgraphicswidget/qgraphicswidget.pro
new file mode 100644
index 0000000000..ae61c2abca
--- /dev/null
+++ b/tests/auto/qgraphicswidget/qgraphicswidget.pro
@@ -0,0 +1,4 @@
+load(qttest_p4)
+SOURCES += tst_qgraphicswidget.cpp
+
+
diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp
new file mode 100644
index 0000000000..e8e2e23a9e
--- /dev/null
+++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp
@@ -0,0 +1,3416 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <qgraphicswidget.h>
+#include <qgraphicsscene.h>
+#include <qgraphicssceneevent.h>
+#include <qgraphicsview.h>
+#include <qstyleoption.h>
+#include <qgraphicslinearlayout.h>
+#include <qcleanlooksstyle.h>
+#include <qlineedit.h>
+#include <qboxlayout.h>
+#include <qaction.h>
+#include <qwidgetaction.h>
+#include "../../shared/util.h"
+#include "../platformquirks.h"
+
+
+class EventSpy : public QObject
+{
+ Q_OBJECT
+public:
+ EventSpy(QObject *watched, QEvent::Type type)
+ : _count(0), spied(type)
+ {
+ watched->installEventFilter(this);
+ }
+
+ int count() const { return _count; }
+
+protected:
+ bool eventFilter(QObject *watched, QEvent *event)
+ {
+ Q_UNUSED(watched);
+ if (event->type() == spied)
+ ++_count;
+ return false;
+ }
+
+ int _count;
+ QEvent::Type spied;
+};
+
+#ifndef QT_NO_STYLE_CLEANLOOKS
+class tst_QGraphicsWidget : public QObject {
+Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void qgraphicswidget();
+
+ void activation();
+ void boundingRect_data();
+ void boundingRect();
+ void dumpFocusChain_data();
+ void dumpFocusChain();
+ void focusWidget_data();
+ void focusWidget();
+ void focusWidget2();
+ void focusWidget3();
+ void focusPolicy_data();
+ void focusPolicy();
+ void font_data();
+ void font();
+ void fontPropagation();
+ void fontChangedEvent();
+ void fontPropagationWidgetItemWidget();
+ void fontPropagationSceneChange();
+ void geometry_data();
+ void geometry();
+ void geometryChanged();
+ void width();
+ void height();
+ void getContentsMargins_data();
+ void getContentsMargins();
+ void initStyleOption_data();
+ void initStyleOption();
+ void layout_data();
+ void layout();
+ void layoutDirection_data();
+ void layoutDirection();
+ void paint_data();
+ void paint();
+ void palettePropagation();
+ void parentWidget_data();
+ void parentWidget();
+ void resize_data();
+ void resize();
+ void setAttribute_data();
+ void setAttribute();
+ void setStyle_data();
+ void setStyle();
+ void setTabOrder_data();
+ void setTabOrder();
+ void setTabOrderAndReparent();
+ void topLevelWidget_data();
+ void topLevelWidget();
+ void unsetLayoutDirection_data();
+ void unsetLayoutDirection();
+ void focusNextPrevChild_data();
+ void focusNextPrevChild();
+ void verifyFocusChain();
+ void updateFocusChainWhenChildDie();
+ void sizeHint_data();
+ void sizeHint();
+ void consistentPosSizeGeometry_data();
+ void consistentPosSizeGeometry();
+ void setSizes_data();
+ void setSizes();
+ void closePopupOnOutsideClick();
+ void defaultSize();
+ void explicitMouseGrabber();
+ void implicitMouseGrabber();
+ void doubleClickAfterExplicitMouseGrab();
+ void popupMouseGrabber();
+ void windowFlags_data();
+ void windowFlags();
+ void shortcutsDeletion();
+ void painterStateProtectionOnWindowFrame();
+ void ensureClipping();
+ void widgetSendsGeometryChanges();
+ void respectHFW();
+ void addChildInpolishEvent();
+ void polishEvent();
+ void polishEvent2();
+ void autoFillBackground();
+ void initialShow();
+ void initialShow2();
+ void itemChangeEvents();
+ void itemSendGeometryPosChangesDeactivated();
+
+ void fontPropagatesResolveToChildren();
+ void fontPropagatesResolveToGrandChildren();
+ void fontPropagatesResolveInParentChange();
+ void fontPropagatesResolveViaNonWidget();
+ void fontPropagatesResolveFromScene();
+
+ // Task fixes
+ void task236127_bspTreeIndexFails();
+ void task243004_setStyleCrash();
+ void task250119_shortcutContext();
+ void QT_BUG_6544_tabFocusFirstUnsetWhenRemovingItems();
+ void QT_BUG_12056_tabFocusFirstUnsetWhenRemovingItems();
+ void QT_BUG_13865_doublePaintWhenAddingASubItem();
+};
+
+
+static void sendMouseMove(QWidget *widget, const QPoint &point, Qt::MouseButton button = Qt::NoButton, Qt::MouseButtons buttons = 0)
+{
+ QTest::mouseMove(widget, point);
+ QMouseEvent event(QEvent::MouseMove, point, button, buttons, 0);
+ QApplication::sendEvent(widget, &event);
+}
+
+// Subclass that exposes the protected functions.
+class SubQGraphicsWidget : public QGraphicsWidget {
+public:
+ SubQGraphicsWidget(QGraphicsItem *parent = 0, Qt::WindowFlags windowFlags = 0)
+ : QGraphicsWidget(parent, windowFlags), eventCount(0)
+ { }
+
+ void initStyleOption(QStyleOption *option)
+ { QGraphicsWidget::initStyleOption(option); }
+
+ void call_changeEvent(QEvent* event)
+ { return QGraphicsWidget::changeEvent(event); }
+
+ bool call_event(QEvent *e)
+ { return event(e); }
+
+ void call_focusInEvent(QFocusEvent* event)
+ { return QGraphicsWidget::focusInEvent(event); }
+
+ bool call_focusNextPrevChild(bool next)
+ { return QGraphicsWidget::focusNextPrevChild(next); }
+
+ void call_focusOutEvent(QFocusEvent* event)
+ { return QGraphicsWidget::focusOutEvent(event); }
+
+ void call_hideEvent(QHideEvent* event)
+ { return QGraphicsWidget::hideEvent(event); }
+
+ QVariant call_itemChange(QGraphicsItem::GraphicsItemChange change, QVariant const& value)
+ { return QGraphicsWidget::itemChange(change, value); }
+
+ void call_moveEvent(QGraphicsSceneMoveEvent* event)
+ { return QGraphicsWidget::moveEvent(event); }
+
+ void call_polishEvent()
+ { return QGraphicsWidget::polishEvent(); }
+
+ QVariant call_propertyChange(QString const& propertyName, QVariant const& value)
+ { return QGraphicsWidget::propertyChange(propertyName, value); }
+
+ void call_resizeEvent(QGraphicsSceneResizeEvent* event)
+ { return QGraphicsWidget::resizeEvent(event); }
+
+ bool call_sceneEvent(QEvent* event)
+ { return QGraphicsWidget::sceneEvent(event); }
+
+ void call_showEvent(QShowEvent* event)
+ { return QGraphicsWidget::showEvent(event); }
+
+ QSizeF call_sizeHint(Qt::SizeHint which, QSizeF const& constraint = QSizeF()) const
+ { return QGraphicsWidget::sizeHint(which, constraint); }
+
+ void call_updateGeometry()
+ { return QGraphicsWidget::updateGeometry(); }
+
+ int eventCount;
+ Qt::LayoutDirection m_painterLayoutDirection;
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ {
+ m_painterLayoutDirection = painter->layoutDirection();
+ QGraphicsWidget::paint(painter, option, widget);
+ if (hasFocus()) {
+ painter->setPen(Qt::DotLine);
+ painter->drawRect(rect());
+ }
+ //painter->drawText(QPointF(0,15), data(0).toString());
+ }
+
+protected:
+ bool event(QEvent *event)
+ {
+ eventCount++;
+ return QGraphicsWidget::event(event);
+ }
+};
+
+// This will be called before the first test function is executed.
+// It is only called once.
+void tst_QGraphicsWidget::initTestCase()
+{
+}
+
+// This will be called after the last test function is executed.
+// It is only called once.
+void tst_QGraphicsWidget::cleanupTestCase()
+{
+}
+
+// This will be called before each test function is executed.
+void tst_QGraphicsWidget::init()
+{
+}
+
+// This will be called after every test function.
+void tst_QGraphicsWidget::cleanup()
+{
+}
+
+class SizeHinter : public QGraphicsWidget
+{
+public:
+ SizeHinter(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0,
+ const QSizeF &min = QSizeF(5,5),
+ const QSizeF &pref = QSizeF(50, 50),
+ const QSizeF &max = QSizeF(500, 500))
+ : QGraphicsWidget(parent, wFlags)
+ {
+ m_sizes[Qt::MinimumSize] = min;
+ m_sizes[Qt::PreferredSize] = pref;
+ m_sizes[Qt::MaximumSize] = max;
+
+ }
+ void setSizeHint(Qt::SizeHint which, const QSizeF &newSizeHint)
+ {
+ m_sizes[which] = newSizeHint;
+ }
+
+protected:
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const
+ {
+ Q_UNUSED(constraint);
+ return m_sizes[which];
+ }
+private:
+ QSizeF m_sizes[4];
+};
+
+void tst_QGraphicsWidget::qgraphicswidget()
+{
+ SubQGraphicsWidget widget;
+ QVERIFY(widget.isVisible());
+
+ QVERIFY(!widget.isWindow());
+ QCOMPARE(widget.boundingRect(), QRectF(0, 0, 0, 0));
+ QCOMPARE(widget.focusWidget(), (QGraphicsWidget*)0);
+ QCOMPARE(widget.focusPolicy(), Qt::NoFocus);
+ QCOMPARE(widget.font(), QFont());
+ QCOMPARE(widget.geometry(), QRectF(widget.pos(), widget.size()));
+ QCOMPARE(widget.layout(), (QGraphicsLayout*)0);
+ QCOMPARE(widget.layoutDirection(), Qt::LeftToRight);
+ QCOMPARE(widget.palette(), QPalette());
+ QCOMPARE(widget.parentWidget(), (QGraphicsWidget*)0);
+ QCOMPARE(widget.rect(), QRectF(QPointF(), widget.size()));
+ QCOMPARE(widget.size(), QSizeF(0, 0));
+ QVERIFY(widget.style() != (QStyle*)0);
+ QCOMPARE(widget.testAttribute(Qt::WA_AcceptDrops), false);
+ QCOMPARE(widget.topLevelWidget(), (QGraphicsWidget*)&widget);
+ QCOMPARE(widget.type(), (int)QGraphicsWidget::Type);
+ QCOMPARE(widget.call_propertyChange(QString(), QVariant()), QVariant());
+ widget.call_sizeHint(Qt::PreferredSize, QSizeF());
+
+ QGraphicsScene scene;
+ QGraphicsWidget *parent = new QGraphicsWidget;
+ SizeHinter *child = new SizeHinter(parent);
+
+ QCOMPARE(child->minimumSize(), QSizeF(5, 5));
+}
+
+void tst_QGraphicsWidget::activation()
+{
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ QGraphicsWidget *window1 = new QGraphicsWidget(0, Qt::Window);
+ QGraphicsWidget *window2 = new QGraphicsWidget(0, Qt::Window);
+ QVERIFY(!widget->isActiveWindow());
+ QVERIFY(!window1->isActiveWindow());
+ QVERIFY(!window2->isActiveWindow());
+
+ QGraphicsScene scene;
+ scene.addItem(widget);
+ scene.addItem(window1);
+ scene.addItem(window2);
+
+ QVERIFY(!widget->isActiveWindow());
+ QVERIFY(!window1->isActiveWindow());
+ QVERIFY(!window2->isActiveWindow());
+
+ QEvent activateEvent(QEvent::WindowActivate);
+ QApplication::sendEvent(&scene, &activateEvent);
+
+ QVERIFY(!widget->isActiveWindow());
+ QVERIFY(window1->isActiveWindow());
+ QVERIFY(!window2->isActiveWindow());
+
+ scene.setActiveWindow(window1);
+ QVERIFY(!widget->isActiveWindow());
+ QVERIFY(window1->isActiveWindow());
+ QVERIFY(!window2->isActiveWindow());
+
+ QEvent deactivateEvent(QEvent::WindowDeactivate);
+ QApplication::sendEvent(&scene, &deactivateEvent);
+
+ QVERIFY(!widget->isActiveWindow());
+ QVERIFY(!window1->isActiveWindow());
+ QVERIFY(!window2->isActiveWindow());
+}
+
+void tst_QGraphicsWidget::boundingRect_data()
+{
+ QTest::addColumn<QSizeF>("size");
+ QTest::newRow("null") << QSizeF(0, 0);
+ QTest::newRow("avg") << QSizeF(10, 10);
+}
+
+// QRectF boundingRect() const public
+void tst_QGraphicsWidget::boundingRect()
+{
+ QFETCH(QSizeF, size);
+ SubQGraphicsWidget widget;
+ widget.resize(size);
+ QCOMPARE(widget.rect(), QRectF(QPointF(), size));
+ QCOMPARE(widget.boundingRect(), QRectF(QPointF(0, 0), size));
+}
+
+void tst_QGraphicsWidget::dumpFocusChain_data()
+{
+ QTest::addColumn<bool>("scene");
+ QTest::addColumn<int>("children");
+ QTest::addColumn<bool>("setFocus");
+ QTest::newRow("empty world") << false << 0 << false;
+ QTest::newRow("one world") << true << 2 << false;
+ QTest::newRow("one world w/focus") << true << 2 << true;
+}
+
+// void dumpFocusChain(QGraphicsScene* scene) public (static)
+void tst_QGraphicsWidget::dumpFocusChain()
+{
+ // ### this test is very strange...
+ QFETCH(bool, scene);
+ SubQGraphicsWidget *parent = new SubQGraphicsWidget;
+ QGraphicsScene *theScene = 0;
+ if (scene) {
+ theScene = new QGraphicsScene(this);
+ theScene->addItem(parent);
+ }
+ QFETCH(int, children);
+ QFETCH(bool, setFocus);
+ for (int i = 0; i < children; ++i) {
+ SubQGraphicsWidget *widget = new SubQGraphicsWidget(parent);
+ if (setFocus) {
+ widget->setFlag(QGraphicsItem::ItemIsFocusable, true);
+ if (scene)
+ theScene->setFocusItem(widget);
+ }
+ }
+
+ if (!scene)
+ delete parent;
+}
+
+void tst_QGraphicsWidget::focusWidget_data()
+{
+ QTest::addColumn<int>("childCount");
+ QTest::addColumn<int>("childWithFocus");
+ QTest::newRow("none") << 0 << 0;
+ QTest::newRow("first") << 3 << 0;
+ QTest::newRow("last") << 3 << 2;
+}
+
+// QGraphicsWidget* focusWidget() const public
+void tst_QGraphicsWidget::focusWidget()
+{
+ SubQGraphicsWidget *parent = new SubQGraphicsWidget;
+ QCOMPARE(parent->focusWidget(), (QGraphicsWidget *)0);
+ QGraphicsScene scene;
+ QEvent windowActivate(QEvent::WindowActivate);
+ qApp->sendEvent(&scene, &windowActivate);
+ scene.addItem(parent);
+
+ QFETCH(int, childCount);
+ QList<SubQGraphicsWidget *> children;
+ for (int i = 0; i < childCount; ++i) {
+ SubQGraphicsWidget *widget = new SubQGraphicsWidget(parent);
+ widget->setFlag(QGraphicsItem::ItemIsFocusable, true);
+ children.append(widget);
+ }
+ if (childCount > 0) {
+ QFETCH(int, childWithFocus);
+ SubQGraphicsWidget *widget = children[childWithFocus];
+ widget->setFocus();
+ QTRY_VERIFY(widget->hasFocus());
+ QCOMPARE(parent->focusWidget(), static_cast<QGraphicsWidget*>(widget));
+ }
+}
+
+void tst_QGraphicsWidget::focusWidget2()
+{
+ QGraphicsScene scene;
+ QEvent windowActivate(QEvent::WindowActivate);
+ qApp->sendEvent(&scene, &windowActivate);
+
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ EventSpy focusInSpy(widget, QEvent::FocusIn);
+ EventSpy focusOutSpy(widget, QEvent::FocusOut);
+
+ scene.addItem(widget);
+
+ QTRY_VERIFY(!widget->hasFocus());
+ widget->setFocusPolicy(Qt::StrongFocus);
+ QTRY_VERIFY(!widget->hasFocus());
+
+ QGraphicsWidget *subWidget = new QGraphicsWidget(widget);
+ QTRY_VERIFY(!subWidget->hasFocus());
+
+ scene.setFocus();
+
+ QTRY_VERIFY(!widget->hasFocus());
+ QTRY_VERIFY(!subWidget->hasFocus());
+
+ widget->setFocus();
+
+ QTRY_VERIFY(widget->hasFocus());
+ QTRY_COMPARE(focusInSpy.count(), 1);
+ QTRY_VERIFY(!subWidget->hasFocus());
+
+ QGraphicsWidget *otherSubWidget = new QGraphicsWidget;
+ EventSpy otherFocusInSpy(otherSubWidget, QEvent::FocusIn);
+ EventSpy otherFocusOutSpy(otherSubWidget, QEvent::FocusOut);
+
+ otherSubWidget->setFocusPolicy(Qt::StrongFocus);
+ otherSubWidget->setParentItem(widget);
+
+ QTRY_VERIFY(widget->hasFocus());
+ QCOMPARE(scene.focusItem(), (QGraphicsItem *)widget);
+ QTRY_VERIFY(!subWidget->hasFocus());
+ QTRY_VERIFY(!otherSubWidget->hasFocus());
+
+ widget->hide();
+ QTRY_VERIFY(!widget->hasFocus()); // lose but still has subfocus
+ QCOMPARE(focusInSpy.count(), 1);
+ QCOMPARE(focusOutSpy.count(), 1);
+
+ widget->show();
+ QTRY_VERIFY(!widget->hasFocus()); // no regain
+ QCOMPARE(focusInSpy.count(), 1);
+ QCOMPARE(focusOutSpy.count(), 1);
+
+ widget->hide();
+
+ // try to setup subFocus on item that can't take focus
+ subWidget->setFocus();
+ QTRY_VERIFY(!subWidget->hasFocus());
+ QVERIFY(!scene.focusItem()); // but isn't the scene's focus item
+
+ // try to setup subFocus on item that can take focus
+ otherSubWidget->setFocus();
+ QTRY_VERIFY(!otherSubWidget->hasFocus());
+ QCOMPARE(widget->focusWidget(), otherSubWidget);
+ QVERIFY(!scene.focusItem()); // but isn't the scene's focus item
+
+ widget->show();
+
+ QTRY_COMPARE(scene.focusItem(), (QGraphicsItem *)otherSubWidget); // but isn't the scene's focus item
+ QCOMPARE(otherFocusInSpy.count(), 1);
+ QCOMPARE(otherFocusOutSpy.count(), 0);
+
+ delete otherSubWidget;
+
+ QTRY_COMPARE(otherFocusOutSpy.count(), 1);
+ QVERIFY(!scene.focusItem());
+ QVERIFY(!widget->focusWidget());
+}
+
+class FocusWatchWidget : public QGraphicsWidget
+{
+public:
+ FocusWatchWidget(QGraphicsItem *parent = 0) : QGraphicsWidget(parent) { gotFocusInCount = 0; gotFocusOutCount = 0; }
+ int gotFocusInCount, gotFocusOutCount;
+protected:
+ void focusInEvent(QFocusEvent *fe) { gotFocusInCount++; QGraphicsWidget::focusInEvent(fe); }
+ void focusOutEvent(QFocusEvent *fe) { gotFocusOutCount++; QGraphicsWidget::focusOutEvent(fe); }
+};
+
+void tst_QGraphicsWidget::focusWidget3()
+{
+ QGraphicsScene scene;
+ QEvent windowActivate(QEvent::WindowActivate);
+ qApp->sendEvent(&scene, &windowActivate);
+
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ FocusWatchWidget *subWidget = new FocusWatchWidget(widget);
+ subWidget->setFocusPolicy(Qt::StrongFocus);
+
+ scene.addItem(widget);
+ widget->show();
+
+ QTRY_VERIFY(!widget->hasFocus());
+ QTRY_VERIFY(!subWidget->hasFocus());
+
+ subWidget->setFocus();
+ QCOMPARE(subWidget->gotFocusInCount, 1);
+ QCOMPARE(subWidget->gotFocusOutCount, 0);
+ widget->hide();
+ QCOMPARE(subWidget->gotFocusOutCount, 1);
+}
+
+Q_DECLARE_METATYPE(Qt::FocusPolicy)
+void tst_QGraphicsWidget::focusPolicy_data()
+{
+ QTest::addColumn<Qt::FocusPolicy>("focusPolicy1");
+ QTest::addColumn<Qt::FocusPolicy>("focusPolicy2");
+
+ for (int i = 0; i < 25; ++i) {
+ QTestData &data = QTest::newRow(QString("%1").arg(i).toLatin1());
+ switch(i % 5) {
+ case 0: data << Qt::TabFocus; break;
+ case 1: data << Qt::ClickFocus; break;
+ case 2: data << Qt::StrongFocus; break;
+ case 3: data << Qt::WheelFocus; break;
+ case 4: data << Qt::NoFocus; break;
+ }
+ switch(i / 5) {
+ case 0: data << Qt::TabFocus; break;
+ case 1: data << Qt::ClickFocus; break;
+ case 2: data << Qt::StrongFocus; break;
+ case 3: data << Qt::WheelFocus; break;
+ case 4: data << Qt::NoFocus; break;
+ }
+ }
+}
+
+// Qt::FocusPolicy focusPolicy() const public
+void tst_QGraphicsWidget::focusPolicy()
+{
+ QGraphicsScene scene;
+ QEvent windowActivate(QEvent::WindowActivate);
+ qApp->sendEvent(&scene, &windowActivate);
+
+ SubQGraphicsWidget *widget = new SubQGraphicsWidget;
+ scene.addItem(widget);
+ QTRY_COMPARE(Qt::NoFocus, widget->focusPolicy());
+
+ QFETCH(Qt::FocusPolicy, focusPolicy1);
+ widget->setFocusPolicy(focusPolicy1);
+ QTRY_COMPARE(widget->focusPolicy(), focusPolicy1);
+ bool isFocusable = widget->flags() & QGraphicsItem::ItemIsFocusable;
+ bool wasFocusable = isFocusable;
+ QTRY_VERIFY(isFocusable == (focusPolicy1 != Qt::NoFocus));
+ widget->setFocus();
+ QTRY_COMPARE(widget->hasFocus(), isFocusable);
+
+ QFETCH(Qt::FocusPolicy, focusPolicy2);
+ widget->setFocusPolicy(focusPolicy2);
+ QCOMPARE(widget->focusPolicy(), focusPolicy2);
+ isFocusable = widget->flags() & QGraphicsItem::ItemIsFocusable;
+ QVERIFY(isFocusable == (focusPolicy2 != Qt::NoFocus));
+ QCOMPARE(widget->hasFocus(), wasFocusable && isFocusable);
+}
+
+void tst_QGraphicsWidget::font_data()
+{
+ QTest::addColumn<QString>("fontName");
+ QTest::newRow("Helvetica") << "Helvetica";
+}
+
+// QFont font() const public
+void tst_QGraphicsWidget::font()
+{
+ QFETCH(QString, fontName);
+ SubQGraphicsWidget widget;
+ QCOMPARE(widget.font(), QFont());
+
+ QFont font(fontName);
+ widget.setFont(font);
+ QCOMPARE(widget.font().family(), font.family());
+}
+
+void tst_QGraphicsWidget::fontPropagatesResolveToChildren()
+{
+ QGraphicsWidget *root = new QGraphicsWidget();
+ QGraphicsWidget *child1 = new QGraphicsWidget(root);
+
+ QGraphicsScene scene;
+ scene.addItem(root);
+
+ QFont font;
+ font.setItalic(true);
+ root->setFont(font);
+
+ QGraphicsWidget *child2 = new QGraphicsWidget(root);
+ QGraphicsWidget *child3 = new QGraphicsWidget();
+ child3->setParentItem(root);
+
+ QGraphicsView view;
+ view.setScene(&scene);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+
+ QCOMPARE(font.resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(root->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(child1->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(child2->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(child3->font().resolve(), uint(QFont::StyleResolved));
+}
+
+void tst_QGraphicsWidget::fontPropagatesResolveToGrandChildren()
+{
+ QGraphicsWidget *root = new QGraphicsWidget();
+ QGraphicsWidget *child1 = new QGraphicsWidget(root);
+ QGraphicsWidget *grandChild1 = new QGraphicsWidget(child1);
+
+ QGraphicsScene scene;
+ scene.addItem(root);
+
+ QFont font;
+ font.setItalic(true);
+ root->setFont(font);
+
+ QGraphicsWidget *child2 = new QGraphicsWidget(root);
+ QGraphicsWidget *grandChild2 = new QGraphicsWidget(child2);
+ QGraphicsWidget *grandChild3 = new QGraphicsWidget(child2);
+
+ QGraphicsWidget *child3 = new QGraphicsWidget();
+ QGraphicsWidget *grandChild4 = new QGraphicsWidget(child3);
+ QGraphicsWidget *grandChild5 = new QGraphicsWidget(child3);
+ child3->setParentItem(root);
+ grandChild5->setParentItem(child3);
+
+ QGraphicsView view;
+ view.setScene(&scene);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+
+ QCOMPARE(font.resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild1->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild2->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild3->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild4->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild5->font().resolve(), uint(QFont::StyleResolved));
+}
+
+void tst_QGraphicsWidget::fontPropagatesResolveViaNonWidget()
+{
+ QGraphicsWidget *root = new QGraphicsWidget();
+ QGraphicsPixmapItem *child1 = new QGraphicsPixmapItem(root);
+ QGraphicsWidget *grandChild1 = new QGraphicsWidget(child1);
+
+ QGraphicsScene scene;
+ scene.addItem(root);
+
+ QFont font;
+ font.setItalic(true);
+ root->setFont(font);
+
+ QGraphicsPixmapItem *child2 = new QGraphicsPixmapItem(root);
+ QGraphicsWidget *grandChild2 = new QGraphicsWidget(child2);
+ QGraphicsWidget *grandChild3 = new QGraphicsWidget(child2);
+
+ QGraphicsPixmapItem *child3 = new QGraphicsPixmapItem();
+ QGraphicsWidget *grandChild4 = new QGraphicsWidget(child3);
+ QGraphicsWidget *grandChild5 = new QGraphicsWidget(child3);
+ child3->setParentItem(root);
+ grandChild5->setParentItem(child3);
+
+ QGraphicsView view;
+ view.setScene(&scene);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+
+ QCOMPARE(font.resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild1->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild2->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild3->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild4->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild5->font().resolve(), uint(QFont::StyleResolved));
+}
+
+void tst_QGraphicsWidget::fontPropagatesResolveFromScene()
+{
+ QGraphicsWidget *root = new QGraphicsWidget();
+ QGraphicsWidget *child1 = new QGraphicsWidget(root);
+ QGraphicsWidget *grandChild1 = new QGraphicsWidget(child1);
+
+ QGraphicsScene scene;
+ scene.addItem(root);
+
+ QFont font;
+ font.setItalic(true);
+ scene.setFont(font);
+
+ QGraphicsWidget *child2 = new QGraphicsWidget(root);
+ QGraphicsWidget *grandChild2 = new QGraphicsWidget(child2);
+ QGraphicsWidget *grandChild3 = new QGraphicsWidget(child2);
+
+ QGraphicsWidget *child3 = new QGraphicsWidget();
+ QGraphicsWidget *grandChild4 = new QGraphicsWidget(child3);
+ QGraphicsWidget *grandChild5 = new QGraphicsWidget(child3);
+ child3->setParentItem(root);
+ grandChild5->setParentItem(child3);
+
+ QGraphicsView view;
+ view.setScene(&scene);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+
+ QCOMPARE(font.resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(root->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(child1->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(child2->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(child3->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild1->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild2->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild3->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild4->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild5->font().resolve(), uint(QFont::StyleResolved));
+}
+
+void tst_QGraphicsWidget::fontPropagatesResolveInParentChange()
+{
+ QGraphicsWidget *root = new QGraphicsWidget();
+
+ QGraphicsWidget *child1 = new QGraphicsWidget(root);
+ QGraphicsWidget *grandChild1 = new QGraphicsWidget(child1);
+
+ QGraphicsWidget *child2 = new QGraphicsWidget(root);
+ QGraphicsWidget *grandChild2 = new QGraphicsWidget(child2);
+
+ QGraphicsScene scene;
+ scene.addItem(root);
+
+ QFont italicFont;
+ italicFont.setItalic(true);
+ child1->setFont(italicFont);
+
+ QFont boldFont;
+ boldFont.setBold(true);
+ child2->setFont(boldFont);
+
+ QVERIFY(grandChild1->font().italic());
+ QVERIFY(!grandChild1->font().bold());
+ QVERIFY(!grandChild2->font().italic());
+ QVERIFY(grandChild2->font().bold());
+
+ QCOMPARE(grandChild1->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild2->font().resolve(), uint(QFont::WeightResolved));
+
+ grandChild2->setParentItem(child1);
+
+ QGraphicsView view;
+ view.setScene(&scene);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+
+ QVERIFY(grandChild1->font().italic());
+ QVERIFY(!grandChild1->font().bold());
+ QVERIFY(grandChild2->font().italic());
+ QVERIFY(!grandChild2->font().bold());
+
+ QCOMPARE(grandChild1->font().resolve(), uint(QFont::StyleResolved));
+ QCOMPARE(grandChild2->font().resolve(), uint(QFont::StyleResolved));
+
+}
+
+void tst_QGraphicsWidget::fontPropagation()
+{
+ QGraphicsWidget *root = new QGraphicsWidget;
+ QGraphicsWidget *child0 = new QGraphicsWidget(root);
+ QGraphicsWidget *child1 = new QGraphicsWidget(child0);
+ QGraphicsWidget *child2 = new QGraphicsWidget(child1);
+ QGraphicsScene scene;
+ scene.addItem(root);
+
+ // Check that only the application fonts apply.
+ QFont appFont = QApplication::font();
+ QCOMPARE(scene.font(), appFont);
+ QCOMPARE(root->font(), appFont);
+ QCOMPARE(child0->font(), appFont);
+ QCOMPARE(child1->font(), appFont);
+
+ // Set child0's Text, and set ToolTipBase on child1.
+ QFont boldFont;
+ boldFont.setBold(true);
+ child0->setFont(boldFont);
+ QFont italicFont;
+ italicFont.setItalic(true);
+ child1->setFont(italicFont);
+
+ // Check that the above settings propagate correctly.
+ QCOMPARE(root->font(), appFont);
+ QCOMPARE(scene.font(), appFont);
+ QVERIFY(child0->font().bold());
+ QVERIFY(!child0->font().italic());
+ QVERIFY(child1->font().bold());
+ QVERIFY(child1->font().italic());
+ QVERIFY(child2->font().bold());
+ QVERIFY(child2->font().italic());
+
+ QGraphicsWidget *child3 = new QGraphicsWidget(child2);
+ QVERIFY(child3->font().bold());
+ QVERIFY(child3->font().italic());
+
+ QGraphicsWidget *child4 = new QGraphicsWidget;
+ child4->setParentItem(child3);
+ QVERIFY(child4->font().bold());
+ QVERIFY(child4->font().italic());
+
+ // Replace the app font for child2. Button should propagate but Text
+ // should still be ignored. The previous ToolTipBase setting is gone.
+ QFont sizeFont;
+ sizeFont.setPointSize(43);
+ child1->setFont(sizeFont);
+
+ // Check that the above settings propagate correctly.
+ QCOMPARE(root->font(), appFont);
+ QCOMPARE(scene.font(), appFont);
+ QVERIFY(child0->font().bold());
+ QVERIFY(!child0->font().italic());
+ QVERIFY(child1->font().bold());
+ QVERIFY(!child1->font().italic());
+ QCOMPARE(child1->font().pointSize(), 43);
+ QVERIFY(child2->font().bold());
+ QVERIFY(!child2->font().italic());
+ QCOMPARE(child2->font().pointSize(), 43);
+}
+
+void tst_QGraphicsWidget::fontChangedEvent()
+{
+ QGraphicsWidget *root = new QGraphicsWidget;
+ QGraphicsScene scene;
+ scene.addItem(root);
+
+ // Check that only the application fonts apply.
+ QFont appFont = QApplication::font();
+ QCOMPARE(scene.font(), appFont);
+ QCOMPARE(root->font(), appFont);
+
+ EventSpy rootSpyFont(root, QEvent::FontChange);
+ EventSpy rootSpyPolish(root, QEvent::Polish);
+ QTRY_COMPARE(rootSpyFont.count(), 0);
+ QTRY_COMPARE(rootSpyPolish.count(), 1);
+ //The font is still the same so no fontChangeEvent
+ QTRY_COMPARE(rootSpyFont.count(), 0);
+
+ QFont font;
+ font.setPointSize(43);
+ root->setFont(font);
+ //The font changed
+ QTRY_COMPARE(rootSpyFont.count(), 1);
+
+ //then roll back to the default one.
+ root->setFont(appFont);
+ //The font changed
+ QTRY_COMPARE(rootSpyFont.count(), 2);
+}
+
+void tst_QGraphicsWidget::fontPropagationWidgetItemWidget()
+{
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ QGraphicsRectItem *rect = new QGraphicsRectItem(widget);
+ QGraphicsWidget *widget2 = new QGraphicsWidget(rect);
+
+ QGraphicsScene scene;
+ scene.addItem(widget);
+
+ QFont font;
+ font.setPointSize(43);
+ widget->setFont(font);
+
+ QCOMPARE(widget2->font().pointSize(), 43);
+ QCOMPARE(widget2->font().resolve(), uint(QFont::SizeResolved));
+
+ widget->setFont(QFont());
+
+ QCOMPARE(widget2->font().pointSize(), qApp->font().pointSize());
+ QCOMPARE(widget2->font().resolve(), QFont().resolve());
+}
+
+void tst_QGraphicsWidget::fontPropagationSceneChange()
+{
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ QGraphicsRectItem *rect = new QGraphicsRectItem(widget);
+ QGraphicsWidget *widget2 = new QGraphicsWidget(rect);
+
+ QGraphicsScene scene;
+ QGraphicsScene scene2;
+
+ QFont font;
+ font.setPointSize(47);
+ scene.setFont(font);
+
+ QFont font2;
+ font2.setPointSize(74);
+ scene2.setFont(font2);
+
+ scene.addItem(widget);
+ QCOMPARE(widget2->font().pointSize(), 47);
+ scene2.addItem(widget);
+ QCOMPARE(widget2->font().pointSize(), 74);
+}
+
+void tst_QGraphicsWidget::geometry_data()
+{
+ QTest::addColumn<QPointF>("pos");
+ QTest::addColumn<QSizeF>("size");
+ QTest::newRow("null, null") << QPointF() << QSizeF(0, 0);
+ QTest::newRow("null, normal") << QPointF() << QSizeF(10, 10);
+ QTest::newRow("neg, normal") << QPointF(-5, -5) << QSizeF(10, 10);
+}
+
+// QRectF geometry() const public
+void tst_QGraphicsWidget::geometry()
+{
+ SubQGraphicsWidget widget;
+ QCOMPARE(widget.geometry(), QRectF(widget.pos(), widget.size()));
+ QSignalSpy spy(&widget, SIGNAL(geometryChanged()));
+ QFETCH(QPointF, pos);
+ QFETCH(QSizeF, size);
+ widget.setPos(pos);
+ widget.resize(size);
+ if (!size.isNull() && !pos.isNull())
+ QCOMPARE(spy.count(), 2);
+ if (!size.isNull() && pos.isNull())
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(widget.geometry(), QRectF(pos, size));
+}
+
+void tst_QGraphicsWidget::geometryChanged()
+{
+ QGraphicsWidget w;
+ w.setGeometry(0, 0, 200, 200);
+ QCOMPARE(w.geometry(), QRectF(0, 0, 200, 200));
+ QSignalSpy spy(&w, SIGNAL(geometryChanged()));
+ w.setGeometry(0, 0, 100, 100);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(w.geometry(), QRectF(0, 0, 100, 100));
+ w.setPos(10, 10);
+ QCOMPARE(spy.count(), 2);
+ QCOMPARE(w.geometry(), QRectF(10, 10, 100, 100));
+
+}
+
+void tst_QGraphicsWidget::width()
+{
+ QGraphicsWidget w;
+ QCOMPARE(w.property("width").toReal(), qreal(0));
+ QSignalSpy spy(&w, SIGNAL(widthChanged()));
+ w.setProperty("width", qreal(50));
+ QCOMPARE(w.property("width").toReal(), qreal(50));
+ QCOMPARE(spy.count(), 1);
+ //calling old school setGeometry should work too
+ w.setGeometry(0, 0, 200, 200);
+ QCOMPARE(spy.count(), 2);
+}
+
+void tst_QGraphicsWidget::height()
+{
+ QGraphicsWidget w;
+ QCOMPARE(w.property("height").toReal(), qreal(0));
+ QSignalSpy spy(&w, SIGNAL(heightChanged()));
+ w.setProperty("height", qreal(50));
+ QCOMPARE(w.property("height").toReal(), qreal(50));
+ QCOMPARE(spy.count(), 1);
+ //calling old school setGeometry should work too
+ w.setGeometry(0, 0, 200, 200);
+ QCOMPARE(spy.count(), 2);
+}
+
+void tst_QGraphicsWidget::getContentsMargins_data()
+{
+ QTest::addColumn<qreal>("left");
+ QTest::addColumn<qreal>("top");
+ QTest::addColumn<qreal>("right");
+ QTest::addColumn<qreal>("bottom");
+ QTest::newRow("null") << (qreal)0 << (qreal)0 << (qreal)0 << (qreal)0;
+ QTest::newRow("something") << (qreal)10 << (qreal)5 << (qreal)3 << (qreal)7;
+ QTest::newRow("real") << (qreal)1.7 << (qreal)5.9 << (qreal)3.2 << (qreal)9.7;
+}
+
+// void getContentsMargins(qreal* left, qreal* top, qreal* right, qreal* bottom) const public
+void tst_QGraphicsWidget::getContentsMargins()
+{
+ qreal gleft;
+ qreal gtop;
+ qreal gright;
+ qreal gbottom;
+
+ SubQGraphicsWidget widget;
+ widget.getContentsMargins(&gleft, &gtop, &gright, &gbottom);
+ QCOMPARE(gleft, (qreal)0);
+ QCOMPARE(gtop, (qreal)0);
+ QCOMPARE(gright, (qreal)0);
+ QCOMPARE(gbottom, (qreal)0);
+
+ QFETCH(qreal, left);
+ QFETCH(qreal, top);
+ QFETCH(qreal, right);
+ QFETCH(qreal, bottom);
+ int oldEventCounts = widget.eventCount;
+ widget.setContentsMargins(left, top, right, bottom);
+ QVERIFY(left == 0 || oldEventCounts != widget.eventCount);
+ widget.getContentsMargins(&gleft, &gtop, &gright, &gbottom);
+ QCOMPARE(gleft, left);
+ QCOMPARE(gtop, top);
+ QCOMPARE(gright, right);
+ QCOMPARE(gbottom, bottom);
+}
+
+Q_DECLARE_METATYPE(Qt::LayoutDirection)
+void tst_QGraphicsWidget::initStyleOption_data()
+{
+ QTest::addColumn<bool>("enabled");
+ QTest::addColumn<bool>("focus");
+ QTest::addColumn<bool>("underMouse");
+ QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::addColumn<QSizeF>("size");
+ QTest::addColumn<QPalette>("palette");
+ QTest::addColumn<QString>("fontName");
+ QTest::newRow("none") << false << false << false << Qt::LeftToRight << QSizeF(0, 0) << QPalette() << QString();
+ QTest::newRow("all") << true << true << true << Qt::RightToLeft << QSizeF(300, 300) << QPalette(Qt::magenta) << "Helvetica";
+ QTest::newRow("rand") << true << false << false << Qt::RightToLeft << QSizeF(1, 0) << QPalette(Qt::darkCyan) << "Times";
+}
+
+// void initStyleOption(QStyleOption* option) const public
+void tst_QGraphicsWidget::initStyleOption()
+{
+#ifdef Q_WS_MAEMO_5
+ QSKIP("The test passes, but it doesn't work when the display is in energy saving mode", SkipAll);
+#endif
+
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QApplication::setActiveWindow(&view);
+ QTRY_COMPARE(QApplication::activeWindow(), (QWidget*)&view);
+
+ view.setAlignment(Qt::AlignTop | Qt::AlignLeft);
+ SubQGraphicsWidget *widget = new SubQGraphicsWidget;
+ widget->setAcceptsHoverEvents(true);
+ QStyleOption option;
+ scene.addItem(widget);
+
+ QFETCH(QSizeF, size);
+ widget->resize(size);
+
+ QFETCH(bool, enabled);
+ widget->setEnabled(enabled);
+ QFETCH(bool, focus);
+ if (focus) {
+ widget->setFlag(QGraphicsItem::ItemIsFocusable, true);
+ widget->setFocus();
+ QVERIFY(widget->hasFocus());
+ }
+ QFETCH(bool, underMouse);
+ if (underMouse) {
+ view.resize(300, 300);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+ sendMouseMove(view.viewport(), view.mapFromScene(widget->mapToScene(widget->boundingRect().center())));
+ }
+
+ QFETCH(QPalette, palette);
+ widget->setPalette(palette);
+
+ QFETCH(QString, fontName);
+ widget->setFont(QFont(fontName));
+
+ // The test
+ widget->initStyleOption(&option);
+
+ bool isEnabled = option.state & QStyle::State_Enabled;
+ QCOMPARE(isEnabled, enabled);
+ bool hasFocus = option.state & QStyle::State_HasFocus;
+ QCOMPARE(hasFocus, focus);
+ bool isUnderMouse = option.state & QStyle::State_MouseOver;
+#ifndef Q_OS_WINCE
+ QCOMPARE(isUnderMouse, underMouse);
+#endif
+ // if (layoutDirection != Qt::LeftToRight)
+ //QEXPECT_FAIL("", "QApplicaiton::layoutDirection doesn't propagate to QGraphicsWidget", Continue);
+ //QCOMPARE(option.direction, layoutDirection);
+ QCOMPARE(option.rect, QRectF(QPointF(), size).toRect());
+ QCOMPARE(option.palette, palette.resolve(QApplication::palette()));
+ QCOMPARE(option.fontMetrics, QFontMetrics(widget->font()));
+}
+
+void tst_QGraphicsWidget::layout_data()
+{
+ QTest::addColumn<int>("childCount");
+ QTest::newRow("empty") << 0;
+ QTest::newRow("10") << 10;
+}
+
+// QGraphicsLayout* layout() const public
+void tst_QGraphicsWidget::layout()
+{
+ SubQGraphicsWidget widget;
+ widget.setContentsMargins(10, 5, 50, 100);
+ QCOMPARE(widget.layout(), (QGraphicsLayout *)0);
+ QFETCH(int, childCount);
+
+ QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
+ QList<SubQGraphicsWidget*> children;
+ for (int i = 0; i < childCount; ++i) {
+ SubQGraphicsWidget *item = new SubQGraphicsWidget;
+ layout->addItem(item);
+ children.append(item);
+ }
+ QSignalSpy spy(&widget, SIGNAL(layoutChanged()));
+ widget.setLayout(layout);
+
+ QTRY_COMPARE(widget.layout(), static_cast<QGraphicsLayout*>(layout));
+ for (int i = 0; i < children.count(); ++i) {
+ SubQGraphicsWidget *item = children[i];
+ QCOMPARE(item->parentWidget(), (QGraphicsWidget *)&widget);
+ QVERIFY(item->geometry() != QRectF(0, 0, -1, -1));
+ }
+ QCOMPARE(spy.count(), 1);
+ // don't crash
+ widget.setLayout(0);
+}
+
+void tst_QGraphicsWidget::layoutDirection_data()
+{
+ QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::newRow("rtl") << Qt::RightToLeft;
+ QTest::newRow("ltr") << Qt::LeftToRight;
+}
+
+// Qt::LayoutDirection layoutDirection() const public
+void tst_QGraphicsWidget::layoutDirection()
+{
+ QFETCH(Qt::LayoutDirection, layoutDirection);
+ QGraphicsScene scene;
+ QGraphicsView *view = new QGraphicsView(&scene);
+ SubQGraphicsWidget widget;
+ scene.addItem(&widget);
+ QCOMPARE(widget.layoutDirection(), Qt::LeftToRight);
+ QCOMPARE(widget.testAttribute(Qt::WA_SetLayoutDirection), false);
+
+ QList<SubQGraphicsWidget*> children;
+ for (int i = 0; i < 10; ++i) {
+ SubQGraphicsWidget *item = new SubQGraphicsWidget(&widget);
+ children.append(item);
+ QCOMPARE(item->testAttribute(Qt::WA_SetLayoutDirection), false);
+ }
+ widget.setLayoutDirection(layoutDirection);
+ QCOMPARE(widget.testAttribute(Qt::WA_SetLayoutDirection), true);
+ view->show();
+ QTest::qWaitForWindowShown(view);
+ for (int i = 0; i < children.count(); ++i) {
+ QTRY_COMPARE(children[i]->layoutDirection(), layoutDirection);
+ QTRY_COMPARE(children[i]->testAttribute(Qt::WA_SetLayoutDirection), false);
+ view->repaint();
+ QTRY_COMPARE(children[i]->m_painterLayoutDirection, layoutDirection);
+ }
+ delete view;
+}
+
+void tst_QGraphicsWidget::paint_data()
+{
+ // currently QGraphicsWidget doesn't paint or do anything ...
+}
+
+// void paint(QPainter* painter, QStyleOptionGraphicsItem const* option, QWidget* widget) public
+void tst_QGraphicsWidget::paint()
+{
+ SubQGraphicsWidget widget;
+ QPainter painter;
+ QStyleOptionGraphicsItem option;
+ widget.paint(&painter, &option, 0); // check that widget = 0 works.
+}
+
+void tst_QGraphicsWidget::palettePropagation()
+{
+ QGraphicsWidget *root = new QGraphicsWidget;
+ QGraphicsWidget *child0 = new QGraphicsWidget(root);
+ QGraphicsWidget *child1 = new QGraphicsWidget(child0);
+ QGraphicsWidget *child2 = new QGraphicsWidget(child1);
+ QGraphicsScene scene;
+ scene.addItem(root);
+
+ // These colors are unlikely to be imposed on the default palette of
+ // QWidget ;-).
+ QColor sysPalText(21, 22, 23);
+ QColor sysPalToolTipBase(12, 13, 14);
+ QColor overridePalText(42, 43, 44);
+ QColor overridePalToolTipBase(45, 46, 47);
+ QColor sysPalButton(99, 98, 97);
+
+ // Check that only the application fonts apply.
+ QPalette appPal = QApplication::palette();
+ QCOMPARE(scene.palette(), appPal);
+ QCOMPARE(root->palette(), appPal);
+ QCOMPARE(child0->palette(), appPal);
+ QCOMPARE(child1->palette(), appPal);
+
+ // Set child0's Text, and set ToolTipBase on child1.
+ QPalette textPalette;
+ textPalette.setColor(QPalette::Text, overridePalText);
+ child0->setPalette(textPalette);
+ QPalette toolTipPalette;
+ toolTipPalette.setColor(QPalette::ToolTipBase, overridePalToolTipBase);
+ child1->setPalette(toolTipPalette);
+
+ // Check that the above settings propagate correctly.
+ QCOMPARE(root->palette(), appPal);
+ QCOMPARE(scene.palette(), appPal);
+ QCOMPARE(child0->palette().color(QPalette::Text), overridePalText);
+ QCOMPARE(child0->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
+ QCOMPARE(child1->palette().color(QPalette::Text), overridePalText);
+ QCOMPARE(child1->palette().color(QPalette::ToolTipBase), overridePalToolTipBase);
+ QCOMPARE(child2->palette().color(QPalette::Text), overridePalText);
+ QCOMPARE(child2->palette().color(QPalette::ToolTipBase), overridePalToolTipBase);
+
+ QGraphicsWidget *child3 = new QGraphicsWidget(child2);
+ QCOMPARE(child3->palette().color(QPalette::Text), overridePalText);
+ QCOMPARE(child3->palette().color(QPalette::ToolTipBase), overridePalToolTipBase);
+
+ QGraphicsWidget *child4 = new QGraphicsWidget;
+ child4->setParentItem(child3);
+ QCOMPARE(child4->palette().color(QPalette::Text), overridePalText);
+ QCOMPARE(child4->palette().color(QPalette::ToolTipBase), overridePalToolTipBase);
+
+ // Replace the app palette for child2. Button should propagate but Text
+ // should still be ignored. The previous ToolTipBase setting is gone.
+ QPalette buttonPalette;
+ buttonPalette.setColor(QPalette::Button, sysPalButton);
+ child1->setPalette(buttonPalette);
+
+ QCOMPARE(root->palette(), appPal);
+ QCOMPARE(scene.palette(), appPal);
+ QCOMPARE(child0->palette().color(QPalette::Text), overridePalText);
+ QCOMPARE(child0->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
+ QCOMPARE(child1->palette().color(QPalette::Text), overridePalText);
+ QCOMPARE(child1->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
+ QCOMPARE(child1->palette().color(QPalette::Button), sysPalButton);
+ QCOMPARE(child2->palette().color(QPalette::Text), overridePalText);
+ QCOMPARE(child2->palette().color(QPalette::ToolTipBase), appPal.color(QPalette::ToolTipBase));
+ QCOMPARE(child2->palette().color(QPalette::Button), sysPalButton);
+}
+
+void tst_QGraphicsWidget::parentWidget_data()
+{
+ QTest::addColumn<int>("childrenCount");
+ QTest::newRow("0") << 0;
+ QTest::newRow("1") << 1;
+ QTest::newRow("10") << 10;
+}
+
+// QGraphicsWidget* parentWidget() const public
+void tst_QGraphicsWidget::parentWidget()
+{
+ QFETCH(int, childrenCount);
+ SubQGraphicsWidget standAlongWidget;
+ QGraphicsLineItem standAlongItem;
+
+ SubQGraphicsWidget widgetChild(&standAlongWidget);
+ SubQGraphicsWidget itemChild(&standAlongItem);
+
+ QCOMPARE(standAlongWidget.parentWidget(), (QGraphicsWidget*)0);
+ QCOMPARE(widgetChild.parentWidget(), static_cast<QGraphicsWidget*>(&standAlongWidget));
+ QCOMPARE(itemChild.parentWidget(), (QGraphicsWidget*)0);
+
+ for (int i = 0; i < childrenCount; ++i) {
+ SubQGraphicsWidget *item = new SubQGraphicsWidget(&standAlongWidget);
+ QCOMPARE(item->parentWidget(), static_cast<QGraphicsWidget*>(&standAlongWidget));
+ }
+}
+
+void tst_QGraphicsWidget::resize_data()
+{
+ QTest::addColumn<QSizeF>("size");
+ QTest::newRow("null") << QSizeF();
+ QTest::newRow("10x10") << QSizeF(10, 10);
+ QTest::newRow("10x-1") << QSizeF(10, -1);
+}
+
+// void resize(qreal w, qreal h) public
+void tst_QGraphicsWidget::resize()
+{
+ QFETCH(QSizeF, size);
+ SubQGraphicsWidget widget;
+
+ int oldEventCounts = widget.eventCount;
+ QSizeF oldSize = widget.size();
+ widget.resize(size);
+
+ QSizeF boundedSize = size.expandedTo(widget.minimumSize()).boundedTo(widget.maximumSize());
+ QCOMPARE(widget.eventCount, oldEventCounts + ((oldSize == boundedSize) ? 0 : 1));
+ QCOMPARE(widget.size(), boundedSize);
+}
+
+Q_DECLARE_METATYPE(Qt::WidgetAttribute)
+void tst_QGraphicsWidget::setAttribute_data()
+{
+ QTest::addColumn<Qt::WidgetAttribute>("attribute");
+ QTest::addColumn<bool>("supported");
+ QTest::newRow("WA_SetLayoutDirection") << Qt::WA_SetLayoutDirection << true;
+ QTest::newRow("WA_RightToLeft") << Qt::WA_RightToLeft << true;
+ QTest::newRow("WA_SetStyle") << Qt::WA_SetStyle << true;
+ QTest::newRow("WA_Resized") << Qt::WA_Resized << true;
+ QTest::newRow("unsupported") << Qt::WA_PaintOutsidePaintEvent << false;
+}
+
+// void setAttribute(Qt::WidgetAttribute attribute, bool on = true) public
+void tst_QGraphicsWidget::setAttribute()
+{
+ QFETCH(Qt::WidgetAttribute, attribute);
+ QFETCH(bool, supported);
+ SubQGraphicsWidget widget;
+ if (attribute == Qt::WA_PaintOutsidePaintEvent)
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsWidget::setAttribute: unsupported attribute 13");
+ widget.setAttribute(attribute);
+ QCOMPARE(widget.testAttribute(attribute), supported);
+}
+
+void tst_QGraphicsWidget::setStyle_data()
+{
+ QTest::addColumn<QString>("style");
+ QTest::newRow("null") << "";
+ QTest::newRow("cleanlooks") << "QCleanlooksStyle";
+}
+
+// void setStyle(QStyle* style) public
+void tst_QGraphicsWidget::setStyle()
+{
+ SubQGraphicsWidget widget;
+ QCleanlooksStyle cleanlooksStyle;
+
+ int oldEventCounts = widget.eventCount;
+
+ QFETCH(QString, style);
+ if (style == "QCleanlooksStyle") {
+ widget.setStyle(&cleanlooksStyle);
+ QCOMPARE(widget.style(), static_cast<QStyle*>(&cleanlooksStyle));
+ } else {
+ widget.setStyle(0);
+ QVERIFY(widget.style() != (QStyle *)0);
+ }
+ QCOMPARE(widget.eventCount, oldEventCounts + 1);
+ QCOMPARE(widget.testAttribute(Qt::WA_SetStyle), !style.isEmpty());
+
+ // cleanup
+ widget.setStyle(0);
+}
+
+void tst_QGraphicsWidget::setTabOrder_data()
+{
+ QTest::addColumn<int>("childrenCount");
+ QTest::newRow("0") << 0;
+ QTest::newRow("1") << 1;
+ QTest::newRow("10") << 10;
+}
+
+// void setTabOrder(QGraphicsWidget* first, QGraphicsWidget* second) public
+void tst_QGraphicsWidget::setTabOrder()
+{
+ QFETCH(int, childrenCount);
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QApplication::setActiveWindow(&view);
+ QTRY_COMPARE(QApplication::activeWindow(), (QWidget*)&view);
+
+ QGraphicsWidget *lastItem = 0;
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsWidget::setTabOrder(0, 0) is undefined");
+ QGraphicsWidget::setTabOrder(0, 0);
+
+ QList<SubQGraphicsWidget*> children;
+ for (int i = 0; i < childrenCount; ++i) {
+ SubQGraphicsWidget *item = new SubQGraphicsWidget();
+ item->setFocusPolicy(Qt::TabFocus);
+ children.append(item);
+ scene.addItem(item);
+ if (lastItem)
+ QGraphicsWidget::setTabOrder(lastItem, item);
+ lastItem = item;
+ }
+
+ if (!children.isEmpty()) {
+ QGraphicsWidget *first = children.first();
+ view.viewport()->setFocus();
+ QTRY_VERIFY(view.viewport()->hasFocus());
+ first->setFocus();
+ QVERIFY(first->hasFocus());
+ QVERIFY(scene.hasFocus());
+ QVERIFY(view.viewport()->hasFocus());
+
+ int currentItem = 0;
+ while (currentItem < children.count() - 1) {
+ QTest::keyPress(view.viewport(), Qt::Key_Tab);
+ ++currentItem;
+ QVERIFY(children[currentItem % children.size()]->hasFocus());
+ }
+ }
+}
+
+static bool compareFocusChain(QGraphicsView *view, const QList<QGraphicsItem*> &order)
+{
+ QGraphicsScene *scene = view->scene();
+ QStringList actual;
+ QGraphicsItem *oldFocusItem = scene->focusItem();
+ for (int i = 0; i < order.count(); ++i) {
+ QGraphicsItem *focusItem = scene->focusItem();
+ actual << focusItem->data(0).toString();
+ //qDebug() << "i:" << i << "expected:" << QString::number(uint(order.at(i)), 16) << QString::number(uint(focusItem), 16);
+ if (focusItem != order.at(i)) {
+ qDebug() << "actual:" << actual;
+ scene->setFocusItem(oldFocusItem);
+ return false;
+ }
+ if (i < order.count() - 1)
+ QTest::keyPress(view, Qt::Key_Tab);
+ }
+ scene->setFocusItem(oldFocusItem);
+ return true;
+}
+
+void tst_QGraphicsWidget::setTabOrderAndReparent()
+{
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ view.show();
+ QApplication::setActiveWindow(&view);
+ QTest::qWaitForWindowShown(&view);
+ QTRY_COMPARE(QApplication::activeWindow(), (QWidget*)&view);
+
+ int i;
+ QGraphicsWidget *w1, *w2, *w3, *w4;
+ for (i = 1; i < 4; ++i) {
+ QGraphicsWidget *wid = new QGraphicsWidget;
+ wid->setFocusPolicy(Qt::StrongFocus);
+ wid->setData(0, QString::fromAscii("w%1").arg(i));
+ scene.addItem(wid);
+ if (i == 1)
+ w1 = wid;
+ else if (i == 2)
+ w2 = wid;
+ else if (i == 3)
+ w3 = wid;
+ }
+
+ w1->setFocus();
+ QTRY_VERIFY(w1->hasFocus());
+ QVERIFY(compareFocusChain(&view, QList<QGraphicsItem*>() << w1 << w2 << w3));
+
+ QGraphicsWidget *p = new QGraphicsWidget;
+ p->setData(0, QLatin1String("parent"));
+ p->setFocusPolicy(Qt::StrongFocus);
+
+ w1->setFocus();
+ QVERIFY(compareFocusChain(&view, QList<QGraphicsItem*>() << w1 << w2 << w3));
+
+ w1->setParentItem(p);
+ w2->setFocus();
+ QVERIFY(compareFocusChain(&view, QList<QGraphicsItem*>() << w2 << w3));
+
+ w2->setParentItem(p);
+ w3->setFocus();
+ QVERIFY(compareFocusChain(&view, QList<QGraphicsItem*>() << w3));
+ w3->setParentItem(p);
+ QCOMPARE(scene.focusItem(), static_cast<QGraphicsItem*>(0));
+
+ scene.addItem(p);
+ p->setFocus();
+
+ QVERIFY(compareFocusChain(&view, QList<QGraphicsItem*>() << p << w1 << w2 << w3));
+ delete p;
+
+ for (i = 1; i < 5; ++i) {
+ QGraphicsWidget *wid = new QGraphicsWidget;
+ wid->setFocusPolicy(Qt::StrongFocus);
+ wid->setData(0, QString::fromAscii("w%1").arg(i));
+ scene.addItem(wid);
+ if (i == 1)
+ w1 = wid;
+ else if (i == 2)
+ w2 = wid;
+ else if (i == 3)
+ w3 = wid;
+ else if (i == 4)
+ w4 = wid;
+ }
+ w4->setParentItem(w1);
+ QGraphicsWidget::setTabOrder(w1, w4);
+ w1->setFocus();
+ QVERIFY(compareFocusChain(&view, QList<QGraphicsItem*>() << w1 << w4 << w2 << w3));
+
+ p = new QGraphicsWidget;
+ p->setData(0, QLatin1String("parent"));
+ p->setFocusPolicy(Qt::StrongFocus);
+
+ w1->setParentItem(p);
+ w2->setFocus();
+ QVERIFY(compareFocusChain(&view, QList<QGraphicsItem*>() << w2 << w3));
+
+ scene.addItem(p);
+ w2->setFocus();
+ QVERIFY(compareFocusChain(&view, QList<QGraphicsItem*>() << w2 << w3 << p << w1 << w4));
+}
+
+void tst_QGraphicsWidget::topLevelWidget_data()
+{
+ QTest::addColumn<QString>("str");
+ QTest::newRow("test one") << "foo";
+}
+
+// QGraphicsWidget* topLevelWidget() const public
+void tst_QGraphicsWidget::topLevelWidget()
+{
+ QFETCH(QString, str);
+ SubQGraphicsWidget widget;
+ QCOMPARE(widget.topLevelWidget(), (QGraphicsWidget *)&widget);
+}
+
+void tst_QGraphicsWidget::unsetLayoutDirection_data()
+{
+ QTest::addColumn<Qt::LayoutDirection>("layoutDirection");
+ QTest::newRow("rtl") << Qt::RightToLeft;
+ QTest::newRow("ltr") << Qt::LeftToRight;
+}
+
+// void unsetLayoutDirection() public
+void tst_QGraphicsWidget::unsetLayoutDirection()
+{
+ QApplication::setLayoutDirection(Qt::LeftToRight);
+ QFETCH(Qt::LayoutDirection, layoutDirection);
+ SubQGraphicsWidget widget;
+ QCOMPARE(Qt::LeftToRight, widget.layoutDirection());
+
+ QList<SubQGraphicsWidget*> children;
+ for (int i = 0; i < 10; ++i) {
+ SubQGraphicsWidget *item = new SubQGraphicsWidget(&widget);
+ children.append(item);
+ }
+ widget.setLayoutDirection(layoutDirection);
+ widget.unsetLayoutDirection();
+ QCOMPARE(widget.testAttribute(Qt::WA_SetLayoutDirection), false);
+ for (int i = 0; i < children.count(); ++i) {
+ QCOMPARE(children[i]->layoutDirection(), Qt::LeftToRight);
+ }
+}
+
+void tst_QGraphicsWidget::focusNextPrevChild_data()
+{
+ QTest::addColumn<QString>("str");
+ QTest::newRow("test one") << "foo";
+}
+
+// bool focusNextPrevChild(bool next) protected
+void tst_QGraphicsWidget::focusNextPrevChild()
+{
+ QFETCH(QString, str);
+ SubQGraphicsWidget widget;
+ // ### write test after just calling it stops crashing :)
+ widget.call_focusNextPrevChild(true);
+}
+
+void tst_QGraphicsWidget::verifyFocusChain()
+{
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ view.show();
+ QApplication::setActiveWindow(&view);
+ QTest::qWaitForWindowShown(&view);
+ QTRY_COMPARE(QApplication::activeWindow(), (QWidget*)&view);
+
+ {
+ // parent/child focus
+ SubQGraphicsWidget *w = new SubQGraphicsWidget(0, Qt::Window);
+ w->setFocusPolicy(Qt::StrongFocus);
+ SubQGraphicsWidget *w1_1 = new SubQGraphicsWidget(w);
+ w1_1->setFocusPolicy(Qt::StrongFocus);
+ scene.addItem(w);
+ w->setFocus();
+ QVERIFY(w->hasFocus());
+ w->call_focusNextPrevChild(true);
+ QVERIFY(w1_1->hasFocus());
+ delete w;
+ }
+
+ {
+ // delete item in focus chain and verify chain
+ SubQGraphicsWidget *w = new SubQGraphicsWidget(0, Qt::Window);
+ SubQGraphicsWidget *w1_1 = new SubQGraphicsWidget(w);
+ SubQGraphicsWidget *w1_2 = new SubQGraphicsWidget(w);
+ SubQGraphicsWidget *w1_3 = new SubQGraphicsWidget(w);
+ w1_1->setFocusPolicy(Qt::StrongFocus);
+ w1_2->setFocusPolicy(Qt::StrongFocus);
+ w1_3->setFocusPolicy(Qt::StrongFocus);
+ scene.addItem(w);
+ w1_1->setFocus();
+ QVERIFY(w1_1->hasFocus());
+ QCOMPARE(w->call_focusNextPrevChild(true), true);
+ QVERIFY(w1_2->hasFocus());
+ QCOMPARE(w->call_focusNextPrevChild(true), true);
+ QVERIFY(w1_3->hasFocus());
+ w1_1->setFocus();
+ delete w1_2;
+ w->call_focusNextPrevChild(true);
+ QVERIFY(w1_3->hasFocus());
+ delete w;
+ }
+ {
+ // parent/child focus
+ SubQGraphicsWidget *w = new SubQGraphicsWidget(0, Qt::Window);
+ w->setFocusPolicy(Qt::StrongFocus);
+ SubQGraphicsWidget *w1_1 = new SubQGraphicsWidget(w);
+ w1_1->setFocusPolicy(Qt::StrongFocus);
+ scene.addItem(w);
+ w->setFocus();
+ QVERIFY(w->hasFocus());
+ w->call_focusNextPrevChild(true);
+ QVERIFY(w1_1->hasFocus());
+ delete w;
+ }
+ {
+ // remove the tabFocusFirst widget from the scene.
+ QWidget *window = new QWidget;
+ QVBoxLayout *layout = new QVBoxLayout;
+ window->setLayout(layout);
+ QLineEdit *lineEdit = new QLineEdit;
+ layout->addWidget(lineEdit);
+ QGraphicsView *view = new QGraphicsView(&scene);
+ scene.setSceneRect(-20, -20, 200, 50);
+ layout->addWidget(view);
+ view->setMinimumSize(150, 50);
+ SubQGraphicsWidget *w1_1 = new SubQGraphicsWidget;
+ w1_1->setData(0, "w1_1");
+ w1_1->setGeometry(0,0,25, 25);
+ w1_1->setFocusPolicy(Qt::StrongFocus);
+ scene.addItem(w1_1);
+ SubQGraphicsWidget *w1_2 = new SubQGraphicsWidget;
+ w1_2->setData(0, "w1_2");
+ w1_2->setGeometry(25,0,25, 25);
+ w1_2->setFocusPolicy(Qt::StrongFocus);
+ scene.addItem(w1_2);
+ window->show();
+ QApplication::setActiveWindow(window);
+ QTest::qWaitForWindowShown(window);
+
+ lineEdit->setFocus();
+ QTRY_VERIFY(lineEdit->hasFocus());
+ QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
+ QTRY_VERIFY(w1_1->hasFocus());
+ QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
+ QTRY_VERIFY(w1_2->hasFocus());
+
+ // remove the tabFocusFirst and insert new item
+ delete w1_1; // calls _q_removeItemLater
+ SubQGraphicsWidget *w1_3 = new SubQGraphicsWidget;
+ w1_3->setFocusPolicy(Qt::StrongFocus);
+ w1_3->setData(0, "w1_3");
+ w1_3->setGeometry(50,0,25, 25);
+ scene.addItem(w1_3);
+ QTRY_VERIFY(w1_2->hasFocus());
+ QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
+ QTRY_VERIFY(lineEdit->hasFocus());
+ // tabFocusFirst should now point to w1_2
+ QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
+ QTRY_VERIFY(w1_2->hasFocus());
+ QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
+ QTRY_VERIFY(w1_3->hasFocus());
+ scene.removeItem(w1_2); // does not call _q_removeItemLater
+ delete w1_2; // calls _q_removeItemLater
+
+ SubQGraphicsWidget *w1_4 = new SubQGraphicsWidget;
+ w1_4->setFocusPolicy(Qt::StrongFocus);
+ w1_4->setData(0, "w1_4");
+ w1_4->setGeometry(75,0,25, 25);
+ scene.addItem(w1_4);
+ QTRY_VERIFY(w1_3->hasFocus());
+ QTRY_VERIFY(compareFocusChain(view, QList<QGraphicsItem*>() << w1_3 << w1_4));
+ QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
+ QTRY_VERIFY(lineEdit->hasFocus());
+ // tabFocusFirst should now point to w1_3
+ QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
+ QTRY_VERIFY(w1_3->hasFocus());
+ QTRY_VERIFY(compareFocusChain(view, QList<QGraphicsItem*>() << w1_3 << w1_4));
+ delete window;
+ }
+}
+
+void tst_QGraphicsWidget::updateFocusChainWhenChildDie()
+{
+#ifdef Q_WS_MAEMO_5
+ QSKIP("On Maemo 5 the Display Manager is shown on Window change, so the test won't work", SkipAll);
+#endif
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QApplication::setActiveWindow(&view);
+ QTRY_COMPARE(QApplication::activeWindow(), (QWidget*)&view);
+
+ // delete item in focus chain with no focus and verify chain
+ SubQGraphicsWidget *parent = new SubQGraphicsWidget(0, Qt::Window);
+ SubQGraphicsWidget *w = new SubQGraphicsWidget(0, Qt::Window);
+ w->resize(50,50);
+ w->resize(100,100);
+ SubQGraphicsWidget *w1_1 = new SubQGraphicsWidget(w);
+ w1_1->setFocusPolicy(Qt::StrongFocus);
+ w->setFocusPolicy(Qt::StrongFocus);
+ scene.addItem(w);
+ scene.addItem(parent);
+ w1_1->setFocus();
+
+ QVERIFY(w1_1->hasFocus());
+ QWidget myWidget(0);
+ QLineEdit edit(&myWidget);
+ myWidget.show();
+ edit.setFocus();
+ QTRY_VERIFY(edit.hasFocus());
+ delete w1_1;
+ myWidget.hide();
+ w->setParentItem(parent);
+ //We don't crash perfect
+ QVERIFY(w);
+ QTest::mouseMove(view.viewport());
+ QTest::mouseClick(view.viewport(), Qt::LeftButton, 0);
+ QTRY_COMPARE(qApp->activeWindow(), static_cast<QWidget *>(&view));
+ QTRY_COMPARE(scene.focusItem(), static_cast<QGraphicsItem *>(w));
+}
+
+void tst_QGraphicsWidget::sizeHint_data()
+{
+ QTest::addColumn<bool>("layout");
+ QTest::newRow("no layout") << false;
+ QTest::newRow("layout") << true;
+}
+
+// QSizeF sizeHint(Qt::SizeHint which, QSizeF const& constraint = QSizeF()) const protected
+void tst_QGraphicsWidget::sizeHint()
+{
+ QFETCH(bool, layout);
+ SubQGraphicsWidget widget;
+
+ if (layout) {
+ QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
+ widget.setLayout(layout);
+ }
+ widget.call_sizeHint(Qt::MinimumSize, QSizeF());
+}
+
+void tst_QGraphicsWidget::consistentPosSizeGeometry_data()
+{
+ QTest::addColumn<QSizeF>("minSize");
+ QTest::addColumn<QSizeF>("maxSize");
+ QTest::addColumn<QRectF>("geometry");
+ QTest::addColumn<QRectF>("expectedGeometry");
+
+ QTest::newRow("size is valid") << QSizeF(0, 0) << QSizeF(200, 200) << QRectF(0, 0, 100, 100) << QRectF(0, 0, 100, 100);
+ QTest::newRow("size is larger than max") << QSizeF(0, 0) << QSizeF(50, 50) << QRectF(0, 0, 100, 100) << QRectF(0, 0, 50, 50);
+ QTest::newRow("size is smaller than min") << QSizeF(50, 50) << QSizeF(150, 150) << QRectF(0, 0, 10, 10) << QRectF(0, 0, 50, 50);
+}
+
+void tst_QGraphicsWidget::consistentPosSizeGeometry()
+{
+ QFETCH(QSizeF, minSize);
+ QFETCH(QSizeF, maxSize);
+ QFETCH(QRectF, geometry);
+ QFETCH(QRectF, expectedGeometry);
+
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ QGraphicsWidget *w = new QGraphicsWidget;
+ scene.addItem(w);
+ w->setMinimumSize(minSize);
+ w->setMaximumSize(maxSize);
+ w->setGeometry(geometry);
+ QCOMPARE(w->geometry(), expectedGeometry);
+ QCOMPARE(w->pos(), expectedGeometry.topLeft());
+ QCOMPARE(w->size(), expectedGeometry.size());
+
+ QRectF otherGeom = QRectF(QPointF(12.34,12.34), minSize);
+ w->setGeometry(otherGeom);
+ QCOMPARE(w->geometry(), otherGeom);
+ QCOMPARE(w->pos(), otherGeom.topLeft());
+ QCOMPARE(w->size(), otherGeom.size());
+
+ w->setPos(geometry.topLeft());
+ QCOMPARE(w->geometry().topLeft(), expectedGeometry.topLeft());
+ QCOMPARE(w->pos(), expectedGeometry.topLeft());
+
+ w->resize(geometry.size());
+ QCOMPARE(w->geometry().size(), expectedGeometry.size());
+ QCOMPARE(w->geometry(), expectedGeometry);
+
+ view.show();
+
+}
+
+
+enum WhichSize {
+ MinimumWidth,
+ PreferredWidth,
+ MaximumWidth,
+ MinimumHeight,
+ PreferredHeight,
+ MaximumHeight,
+ MinimumSize,
+ PreferredSize,
+ MaximumSize,
+ MinimumSizeHint,
+ PreferredSizeHint,
+ MaximumSizeHint,
+ Size,
+ None,
+};
+
+typedef QPair<int, QVariant> Inst;
+
+Q_DECLARE_METATYPE(Inst)
+Q_DECLARE_METATYPE(QVector<Inst>)
+
+void tst_QGraphicsWidget::setSizes_data()
+{
+
+ QTest::addColumn<QVector<Inst> >("inputInstructions");
+ QTest::addColumn<QVector<Inst> >("compareInstructions");
+
+ QTest::newRow("minSize1") << (QVector<Inst>() << Inst(Size, QSize(25, 25)) << Inst(MinimumSize, QSize(10, 10)))
+ << (QVector<Inst>() << Inst(Size, QSize(25,25)));
+ QTest::newRow("minSize2") << (QVector<Inst>() << Inst(Size, QSizeF(20, 20)) << Inst(MinimumSize, QSizeF(25, 25)))
+ << (QVector<Inst>() << Inst(Size, QSizeF(25, 25)));
+ QTest::newRow("minWidth1") << (QVector<Inst>() << Inst(Size, QSizeF(20, 20)) << Inst(MinimumWidth, 5.0))
+ << (QVector<Inst>() << Inst(Size, QSizeF(20, 20)));
+ QTest::newRow("minWidth2") << (QVector<Inst>() << Inst(Size, QSizeF(20, 20)) << Inst(MinimumWidth, 25.0))
+ << (QVector<Inst>() << Inst(Size, QSizeF(25, 20)));
+ QTest::newRow("minHeight1") << (QVector<Inst>() << Inst(Size, QSizeF(20, 20)) << Inst(MinimumHeight, 5.0))
+ << (QVector<Inst>() << Inst(Size, QSizeF(20, 20)));
+ QTest::newRow("minHeight2") << (QVector<Inst>() << Inst(Size, QSizeF(20, 20)) << Inst(MinimumHeight, 25.0))
+ << (QVector<Inst>() << Inst(Size, QSizeF(20, 25)));
+ QTest::newRow("maxSize1") << (QVector<Inst>() << Inst(Size, QSizeF(40, 40)) << Inst(MaximumSize, QSizeF(30, 30)))
+ << (QVector<Inst>() << Inst(Size, QSizeF(30, 30)));
+ QTest::newRow("maxSize2") << (QVector<Inst>() << Inst(Size, QSizeF(40, 40)) << Inst(MaximumSize, QSizeF(30, -1)))
+ << (QVector<Inst>() << Inst(Size, QSizeF(30, 40)));
+ QTest::newRow("maxSize3") << (QVector<Inst>() << Inst(Size, QSizeF(40, 40)) << Inst(MaximumSize, QSizeF(-1, 30)))
+ << (QVector<Inst>() << Inst(Size, QSizeF(40, 30)));
+ QTest::newRow("maxWidth1")<< (QVector<Inst>() << Inst(Size, QSizeF(40, 40)) << Inst(MaximumWidth, 30))
+ << (QVector<Inst>() << Inst(Size, QSizeF(30, 40)));
+ QTest::newRow("maxHeight")<< (QVector<Inst>() << Inst(Size, QSizeF(40, 40)) << Inst(MaximumHeight, 20))
+ << (QVector<Inst>() << Inst(Size, QSizeF(40, 20)));
+ QTest::newRow("unsetMinSize")<< (QVector<Inst>() << Inst(Size, QSizeF(40, 40)) << Inst(MinimumSize, QSizeF(-1, -1)))
+ << (QVector<Inst>() << Inst(MinimumSize, QSizeF(5, 5)));
+ QTest::newRow("unsetMaxSize")<< (QVector<Inst>() << Inst(Size, QSizeF(40, 40)) << Inst(MaximumSize, QSizeF(-1, -1)))
+ << (QVector<Inst>() << Inst(MaximumSize, QSizeF(500, 500)));
+ QTest::newRow("unsetMinSize, expand size to minimumSizeHint") << (QVector<Inst>()
+ << Inst(MinimumSize, QSize(0, 0))
+ << Inst(Size, QSize(1,1))
+ << Inst(MinimumSize, QSize(-1.0, -1.0))
+ )
+ << (QVector<Inst>()
+ << Inst(Size, QSize(5,5))
+ << Inst(MinimumSize, QSize(5,5))
+ );
+
+}
+
+void tst_QGraphicsWidget::setSizes()
+{
+ QFETCH(QVector<Inst>, inputInstructions);
+ QFETCH(QVector<Inst>, compareInstructions);
+
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ SizeHinter *widget = new SizeHinter(0, Qt::Window);
+ QSizeF min = QSizeF(10, 10);
+ QSizeF pref = QSizeF(25, 25);
+ QSizeF max = QSizeF(50, 50);
+
+ int i;
+ for (i = 0; i < inputInstructions.count(); ++i) {
+ Inst input = inputInstructions.at(i);
+
+ // defaults
+ switch (input.first) {
+ case MinimumSize:
+ min = input.second.toSizeF();
+ break;
+ case PreferredSize:
+ pref = input.second.toSizeF();
+ break;
+ case MaximumSize:
+ max = input.second.toSizeF();
+ break;
+ case Size:
+ widget->resize(input.second.toSizeF());
+ break;
+ case MinimumWidth:
+ widget->setMinimumWidth(qreal(input.second.toDouble()));
+ break;
+ case PreferredWidth:
+ widget->setPreferredWidth(qreal(input.second.toDouble()));
+ break;
+ case MaximumWidth:
+ widget->setMaximumWidth(qreal(input.second.toDouble()));
+ break;
+ case MinimumHeight:
+ widget->setMinimumHeight(qreal(input.second.toDouble()));
+ break;
+ case PreferredHeight:
+ widget->setPreferredHeight(qreal(input.second.toDouble()));
+ break;
+ case MaximumHeight:
+ widget->setMaximumHeight(qreal(input.second.toDouble()));
+ break;
+ case MinimumSizeHint:
+ widget->setSizeHint(Qt::MinimumSize, input.second.toSizeF());
+ break;
+ case PreferredSizeHint:
+ widget->setSizeHint(Qt::PreferredSize, input.second.toSizeF());
+ break;
+ case MaximumSizeHint:
+ widget->setSizeHint(Qt::MaximumSize, input.second.toSizeF());
+ break;
+ default:
+ qWarning("instruction not implemented");
+ break;
+ }
+ }
+
+ widget->setMinimumSize(min);
+ widget->setPreferredSize(pref);
+ widget->setMaximumSize(max);
+
+ for (i = 0; i < compareInstructions.count(); ++i) {
+ Inst input = compareInstructions.at(i);
+ switch (input.first) {
+ case MinimumSize:
+ QTRY_COMPARE(widget->minimumSize(), input.second.toSizeF());
+ break;
+ case PreferredSize:
+ QTRY_COMPARE(widget->preferredSize(), input.second.toSizeF());
+ break;
+ case MaximumSize:
+ QTRY_COMPARE(widget->maximumSize(), input.second.toSizeF());
+ break;
+ case Size:
+ QTRY_COMPARE(widget->size(), input.second.toSizeF());
+ break;
+ case MinimumWidth:
+ QTRY_COMPARE(widget->minimumWidth(), qreal(input.second.toDouble()));
+ break;
+ case PreferredWidth:
+ QTRY_COMPARE(widget->preferredWidth(), qreal(input.second.toDouble()));
+ break;
+ case MaximumWidth:
+ QTRY_COMPARE(widget->maximumWidth(), qreal(input.second.toDouble()));
+ break;
+ default:
+ qWarning("instruction not implemented");
+ break;
+ }
+ }
+ delete widget;
+}
+
+void tst_QGraphicsWidget::closePopupOnOutsideClick()
+{
+ QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Popup);
+ widget->resize(100, 100);
+
+ QGraphicsScene scene;
+ scene.addItem(widget);
+
+ QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
+ event.ignore();
+ event.setScenePos(QPointF(50, 50));
+ qApp->sendEvent(&scene, &event);
+
+ QVERIFY(widget->isVisible());
+ QVERIFY(event.isAccepted());
+
+ event.ignore();
+ event.setScenePos(QPointF(150, 150));
+ qApp->sendEvent(&scene, &event);
+
+ QVERIFY(!widget->isVisible());
+ QVERIFY(event.isAccepted());
+}
+
+void tst_QGraphicsWidget::task236127_bspTreeIndexFails()
+{
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ QGraphicsWidget *widget2 = new QGraphicsWidget;
+ widget->resize(10, 10);
+ widget2->resize(10, 10);
+ widget2->setZValue(1);
+ QCOMPARE(widget2->zValue(), qreal(1));
+ QCOMPARE(widget->zValue(), qreal(0));
+ widget->setData(0, "widget");
+ widget2->setData(0, "widget2");
+
+ QGraphicsScene scene;
+ scene.addItem(widget);
+ scene.addItem(widget2);
+
+ QGraphicsView view(&scene);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+
+ QTRY_VERIFY(!scene.itemAt(25, 25));
+ widget->setGeometry(0, 112, 360, 528);
+ QTRY_COMPARE(scene.itemAt(15, 120), (QGraphicsItem *)widget);
+ widget2->setGeometry(0, 573, 360, 67);
+ QTRY_COMPARE(scene.itemAt(15, 120), (QGraphicsItem *)widget);
+ QTRY_COMPARE(scene.itemAt(50, 585), (QGraphicsItem *)widget2);
+}
+
+void tst_QGraphicsWidget::defaultSize()
+{
+ SubQGraphicsWidget *widget = new SubQGraphicsWidget;
+ widget->setMinimumSize(40, 40);
+ QGraphicsScene scene;
+ scene.addItem(widget);
+
+ QGraphicsView view(&scene);
+ view.show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&view);
+#endif
+ QSizeF initialSize = widget->size();
+
+ widget->resize(initialSize);
+ QCOMPARE(widget->geometry().size(), initialSize);
+ widget->setVisible(false);
+ widget->setMinimumSize(10, 10);
+ widget->setPreferredSize(60, 60);
+ widget->setMaximumSize(110, 110);
+ widget->setVisible(true);
+ // should still have its size set to initialsize
+ QTRY_COMPARE(widget->geometry().size(), initialSize);
+
+}
+
+void tst_QGraphicsWidget::explicitMouseGrabber()
+{
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ EventSpy widgetGrabEventSpy(widget, QEvent::GrabMouse);
+ EventSpy widgetUngrabEventSpy(widget, QEvent::UngrabMouse);
+
+ // Grab without scene
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsItem::grabMouse: cannot grab mouse without scene");
+ widget->grabMouse();
+ QCOMPARE(widgetGrabEventSpy.count(), 0);
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsItem::ungrabMouse: cannot ungrab mouse without scene");
+ widget->ungrabMouse();
+ QCOMPARE(widgetUngrabEventSpy.count(), 0);
+
+ // Add to scene
+ QGraphicsScene scene;
+ scene.addItem(widget);
+
+ // Ungrab while not grabber
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsItem::ungrabMouse: not a mouse grabber");
+ widget->ungrabMouse();
+
+ // Simple grab with scene
+ QVERIFY(!scene.mouseGrabberItem());
+ widget->grabMouse();
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
+ QCOMPARE(widgetGrabEventSpy.count(), 1);
+ widget->ungrabMouse();
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
+ QCOMPARE(widgetUngrabEventSpy.count(), 1);
+
+ // Grab while grabbing
+ widget->grabMouse();
+ QCOMPARE(widgetGrabEventSpy.count(), 2);
+ QTest::ignoreMessage(QtWarningMsg, "QGraphicsItem::grabMouse: already a mouse grabber");
+ widget->grabMouse();
+ QCOMPARE(widgetGrabEventSpy.count(), 2);
+ QCOMPARE(widgetUngrabEventSpy.count(), 1);
+ widget->ungrabMouse();
+ QCOMPARE(widgetUngrabEventSpy.count(), 2);
+
+ // Add two more widgets to the scene
+ QGraphicsWidget *widget2 = new QGraphicsWidget;
+ scene.addItem(widget2);
+ EventSpy widget2GrabEventSpy(widget2, QEvent::GrabMouse);
+ EventSpy widget2UngrabEventSpy(widget2, QEvent::UngrabMouse);
+ QGraphicsWidget *widget3 = new QGraphicsWidget;
+ scene.addItem(widget3);
+ EventSpy widget3GrabEventSpy(widget3, QEvent::GrabMouse);
+ EventSpy widget3UngrabEventSpy(widget3, QEvent::UngrabMouse);
+
+ widget->setData(0, "widget");
+ widget2->setData(0, "widget2");
+ widget3->setData(0, "widget3");
+
+ // Simple nested grabbing
+ widget->grabMouse();
+ QCOMPARE(widgetGrabEventSpy.count(), 3);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
+ widget2->grabMouse();
+ QCOMPARE(widgetUngrabEventSpy.count(), 3);
+ QCOMPARE(widget2GrabEventSpy.count(), 1);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget2);
+ widget3->grabMouse();
+ QCOMPARE(widget2UngrabEventSpy.count(), 1);
+ QCOMPARE(widget3GrabEventSpy.count(), 1);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget3);
+ widget3->ungrabMouse();
+ QCOMPARE(widget3UngrabEventSpy.count(), 1);
+ QCOMPARE(widget2GrabEventSpy.count(), 2);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget2);
+ widget2->ungrabMouse();
+ QCOMPARE(widget2UngrabEventSpy.count(), 2);
+ QCOMPARE(widgetGrabEventSpy.count(), 4);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
+ widget->ungrabMouse();
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
+
+ // Out of order ungrab
+ widget->grabMouse();
+ QCOMPARE(widgetGrabEventSpy.count(), 5);
+ widget2->grabMouse();
+ QCOMPARE(widget2GrabEventSpy.count(), 3);
+ widget3->grabMouse();
+ QCOMPARE(widget3GrabEventSpy.count(), 2);
+ widget2->ungrabMouse();
+ QCOMPARE(widget3UngrabEventSpy.count(), 2);
+ QCOMPARE(widget2UngrabEventSpy.count(), 4);
+ QCOMPARE(widgetGrabEventSpy.count(), 6);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
+}
+
+void tst_QGraphicsWidget::implicitMouseGrabber()
+{
+ QGraphicsScene scene;
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ widget->setFlag(QGraphicsItem::ItemIsMovable); // can grab mouse
+ widget->resize(200, 200);
+ EventSpy widgetGrabEventSpy(widget, QEvent::GrabMouse);
+ EventSpy widgetUngrabEventSpy(widget, QEvent::UngrabMouse);
+ scene.addItem(widget);
+
+ QVERIFY(!scene.mouseGrabberItem());
+
+ // Click on an item, see if gain and lose implicit mouse grab.
+ {
+ QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
+ event.ignore();
+ event.setButton(Qt::LeftButton);
+ event.setScenePos(QPointF(50, 50));
+ qApp->sendEvent(&scene, &event);
+ }
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
+ QCOMPARE(widgetGrabEventSpy.count(), 1);
+ {
+ QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
+ event.ignore();
+ event.setButton(Qt::LeftButton);
+ event.setScenePos(QPointF(50, 50));
+ qApp->sendEvent(&scene, &event);
+ }
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
+ QCOMPARE(widgetGrabEventSpy.count(), 1);
+ QCOMPARE(widgetUngrabEventSpy.count(), 1);
+
+ // Click on an item that already grabs the mouse. Shouldn't have any effect.
+ widget->grabMouse();
+ QCOMPARE(widgetGrabEventSpy.count(), 2);
+ {
+ QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
+ event.ignore();
+ event.setButton(Qt::LeftButton);
+ event.setScenePos(QPointF(50, 50));
+ qApp->sendEvent(&scene, &event);
+ }
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
+ QCOMPARE(widgetGrabEventSpy.count(), 2);
+ {
+ QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
+ event.ignore();
+ event.setButton(Qt::LeftButton);
+ event.setScenePos(QPointF(50, 50));
+ qApp->sendEvent(&scene, &event);
+ }
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
+ QCOMPARE(widgetGrabEventSpy.count(), 2);
+ QCOMPARE(widgetUngrabEventSpy.count(), 1);
+ widget->ungrabMouse();
+ QCOMPARE(widgetUngrabEventSpy.count(), 2);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
+
+ // Implicit mouse grabber tries to explicitly grab the mouse
+ {
+ QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
+ event.ignore();
+ event.setButton(Qt::LeftButton);
+ event.setScenePos(QPointF(50, 50));
+ qApp->sendEvent(&scene, &event);
+ }
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
+ QCOMPARE(widgetGrabEventSpy.count(), 3);
+ widget->grabMouse();
+ QCOMPARE(widgetUngrabEventSpy.count(), 2);
+ {
+ QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
+ event.ignore();
+ event.setButton(Qt::LeftButton);
+ event.setScenePos(QPointF(50, 50));
+ qApp->sendEvent(&scene, &event);
+ }
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
+ QCOMPARE(widgetGrabEventSpy.count(), 3);
+ QCOMPARE(widgetUngrabEventSpy.count(), 2);
+ widget->ungrabMouse();
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
+ QCOMPARE(widgetGrabEventSpy.count(), 3);
+ QCOMPARE(widgetUngrabEventSpy.count(), 3);
+
+ // Arrival of a new widget
+ QGraphicsWidget *widget2 = new QGraphicsWidget;
+ widget2->setFlag(QGraphicsItem::ItemIsMovable); // can grab mouse
+ widget2->resize(200, 200);
+ widget2->setPos(205, 0);
+ EventSpy widget2GrabEventSpy(widget2, QEvent::GrabMouse);
+ EventSpy widget2UngrabEventSpy(widget2, QEvent::UngrabMouse);
+ scene.addItem(widget2);
+
+ // Implicit grab while there's an explicit grab is not possible.
+ widget->grabMouse();
+ QCOMPARE(widgetGrabEventSpy.count(), 4);
+ {
+ QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
+ event.ignore();
+ event.setButton(Qt::LeftButton);
+ event.setScenePos(QPointF(250, 50));
+ qApp->sendEvent(&scene, &event);
+ }
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
+ QCOMPARE(widgetGrabEventSpy.count(), 4);
+ QCOMPARE(widget2GrabEventSpy.count(), 0);
+ QCOMPARE(widget2UngrabEventSpy.count(), 0);
+
+ scene.removeItem(widget);
+ QCOMPARE(widgetUngrabEventSpy.count(), 4);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
+}
+
+class GrabOnPressItem : public QGraphicsRectItem
+{
+public:
+ GrabOnPressItem(const QRectF &rect)
+ : QGraphicsRectItem(rect),
+ npress(0), nrelease(0), ndoubleClick(0),
+ ngrab(0), nungrab(0)
+ {
+ }
+ int npress;
+ int nrelease;
+ int ndoubleClick;
+ int ngrab;
+ int nungrab;
+protected:
+ bool sceneEvent(QEvent *event)
+ {
+ switch (event->type()) {
+ case QEvent::GrabMouse:
+ ++ngrab;
+ break;
+ case QEvent::UngrabMouse:
+ ++nungrab;
+ break;
+ default:
+ break;
+ }
+ return QGraphicsRectItem::sceneEvent(event);
+ }
+
+ void mousePressEvent(QGraphicsSceneMouseEvent *)
+ {
+ grabMouse();
+ ++npress;
+ }
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *)
+ {
+ ungrabMouse();
+ ++nrelease;
+ }
+ void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *)
+ {
+ ++ndoubleClick;
+ }
+};
+
+void tst_QGraphicsWidget::doubleClickAfterExplicitMouseGrab()
+{
+ QGraphicsScene scene;
+ GrabOnPressItem *item = new GrabOnPressItem(QRectF(0, 0, 100, 100));
+ scene.addItem(item);
+
+ {
+ QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
+ event.setButton(Qt::LeftButton);
+ event.setButtons(Qt::LeftButton);
+ event.ignore();
+ event.setScenePos(QPointF(50, 50));
+ qApp->sendEvent(&scene, &event);
+ }
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)item);
+ QCOMPARE(item->npress, 1);
+ QCOMPARE(item->ngrab, 1);
+ {
+ QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
+ event.setButton(Qt::LeftButton);
+ event.setButtons(0);
+ event.ignore();
+ event.setScenePos(QPointF(50, 50));
+ qApp->sendEvent(&scene, &event);
+ }
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
+ QCOMPARE(item->nrelease, 1);
+ QCOMPARE(item->nungrab, 1);
+ {
+ QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseDoubleClick);
+ event.setButton(Qt::LeftButton);
+ event.setButtons(Qt::LeftButton);
+ event.ignore();
+ event.setScenePos(QPointF(50, 50));
+ qApp->sendEvent(&scene, &event);
+ }
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)item);
+ QCOMPARE(item->ndoubleClick, 1);
+ QCOMPARE(item->ngrab, 2);
+ {
+ QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMouseRelease);
+ event.setButton(Qt::LeftButton);
+ event.setButtons(0);
+ event.ignore();
+ event.setScenePos(QPointF(50, 50));
+ qApp->sendEvent(&scene, &event);
+ }
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
+ QCOMPARE(item->nrelease, 2);
+ QCOMPARE(item->nungrab, 2);
+}
+
+void tst_QGraphicsWidget::popupMouseGrabber()
+{
+ QGraphicsScene scene;
+ QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Popup);
+ widget->setFlag(QGraphicsItem::ItemIsMovable); // can grab mouse
+ widget->resize(200, 200);
+ EventSpy widgetGrabEventSpy(widget, QEvent::GrabMouse);
+ EventSpy widgetUngrabEventSpy(widget, QEvent::UngrabMouse);
+
+ // Simply adding a visible popup to the scene immediately grabs the mouse.
+ scene.addItem(widget);
+ QCOMPARE(widgetGrabEventSpy.count(), 1);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
+
+ // Hiding it loses the grab again.
+ widget->hide();
+ QCOMPARE(widgetUngrabEventSpy.count(), 1);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)0);
+
+ // Showing it grabs the mosue again
+ widget->show();
+ QCOMPARE(widgetGrabEventSpy.count(), 2);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget);
+
+ // Add two popups
+ QGraphicsWidget *widget2 = new QGraphicsWidget(0, Qt::Popup);
+ widget2->setFlag(QGraphicsItem::ItemIsMovable); // can grab mouse
+ widget2->resize(200, 200);
+ EventSpy widget2GrabEventSpy(widget2, QEvent::GrabMouse);
+ EventSpy widget2UngrabEventSpy(widget2, QEvent::UngrabMouse);
+ QGraphicsWidget *widget3 = new QGraphicsWidget(0, Qt::Popup);
+ widget3->setFlag(QGraphicsItem::ItemIsMovable); // can grab mouse
+ widget3->resize(200, 200);
+ EventSpy widget3GrabEventSpy(widget3, QEvent::GrabMouse);
+ EventSpy widget3UngrabEventSpy(widget3, QEvent::UngrabMouse);
+
+ // Adding to the scene grabs
+ scene.addItem(widget2);
+ QCOMPARE(widgetUngrabEventSpy.count(), 2);
+ QCOMPARE(widget2GrabEventSpy.count(), 1);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget2);
+
+ // Adding to the scene grabs again
+ scene.addItem(widget3);
+ QCOMPARE(widget2UngrabEventSpy.count(), 1);
+ QCOMPARE(widget3GrabEventSpy.count(), 1);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget3);
+
+ // Hiding the topmost widget causes widget 2 to regain grab.
+ widget3->hide();
+ QCOMPARE(widget2GrabEventSpy.count(), 2);
+ QCOMPARE(widget3UngrabEventSpy.count(), 1);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget2);
+ widget3->show();
+ QCOMPARE(widget2UngrabEventSpy.count(), 2);
+ QCOMPARE(widget3GrabEventSpy.count(), 2);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget3);
+
+ // Clicking outside the popup still causes it to close (despite that it's
+ // an explicit mouse grabber).
+ {
+ QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
+ event.ignore();
+ event.setButton(Qt::LeftButton);
+ event.setScenePos(QPointF(500, 500)); // outside
+ qApp->sendEvent(&scene, &event);
+ }
+ QVERIFY(!widget3->isVisible());
+ QCOMPARE(widget3UngrabEventSpy.count(), 2);
+ QCOMPARE(widget2GrabEventSpy.count(), 3);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget2);
+ QVERIFY(widget2->isVisible());
+ QVERIFY(widget->isVisible());
+ widget3->show();
+ QCOMPARE(widget3GrabEventSpy.count(), 3);
+ QCOMPARE(widget2UngrabEventSpy.count(), 3);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget3);
+
+ // This is something of a curiosity. What happens if you call
+ // ungrabMouse() on a popup? The answer is - it loses the grab. If you
+ // hide and show the popup again, it will regain the grab.
+ widget3->ungrabMouse();
+ QCOMPARE(widget3UngrabEventSpy.count(), 3);
+ QCOMPARE(widget2GrabEventSpy.count(), 4);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget2);
+ widget3->hide();
+ widget3->show();
+ QCOMPARE(widget3GrabEventSpy.count(), 4);
+ QCOMPARE(widget2UngrabEventSpy.count(), 4);
+ QCOMPARE(scene.mouseGrabberItem(), (QGraphicsItem *)widget3);
+}
+
+void tst_QGraphicsWidget::windowFlags_data()
+{
+ QTest::addColumn<int>("inputFlags");
+ QTest::addColumn<int>("outputFlags");
+
+ QTest::newRow("nil") << 0 << 0;
+
+ // Window types
+ QTest::newRow("Qt::Window") << int(Qt::Window)
+ << int(Qt::Window | Qt::WindowTitleHint | Qt::WindowSystemMenuHint
+ | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
+ QTest::newRow("Qt::SubWindow") << int(Qt::SubWindow)
+ << int(Qt::SubWindow | Qt::WindowTitleHint | Qt::WindowSystemMenuHint
+ | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
+ QTest::newRow("Qt::Dialog") << int(Qt::Dialog)
+ << int(Qt::Dialog | Qt::WindowTitleHint | Qt::WindowSystemMenuHint
+ | Qt::WindowContextHelpButtonHint);
+ QTest::newRow("Qt::Sheet") << int(Qt::Sheet)
+ << int(Qt::Sheet | Qt::WindowTitleHint | Qt::WindowSystemMenuHint
+ | Qt::WindowContextHelpButtonHint);
+ QTest::newRow("Qt::Tool") << int(Qt::Tool)
+ << int(Qt::Tool | Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
+
+ // Custom window flags
+ QTest::newRow("Qt::FramelessWindowHint") << int(Qt::FramelessWindowHint)
+ << int(Qt::FramelessWindowHint);
+ QTest::newRow("Qt::CustomizeWindowHint") << int(Qt::CustomizeWindowHint)
+ << int(Qt::CustomizeWindowHint);
+}
+
+void tst_QGraphicsWidget::windowFlags()
+{
+ QFETCH(int, inputFlags);
+ QFETCH(int, outputFlags);
+
+ // Construct with flags set already
+ QGraphicsWidget widget(0, Qt::WindowFlags(inputFlags));
+ QCOMPARE(widget.windowFlags(), Qt::WindowFlags(outputFlags));
+
+ // Set flags after construction
+ QGraphicsWidget widget2;
+ widget2.setWindowFlags(Qt::WindowFlags(inputFlags));
+ QCOMPARE(widget2.windowFlags(), Qt::WindowFlags(outputFlags));
+
+ // Reset flags
+ widget2.setWindowFlags(0);
+ QVERIFY(!widget2.windowFlags());
+
+ // Set flags back again
+ widget2.setWindowFlags(Qt::WindowFlags(inputFlags));
+ QCOMPARE(widget2.windowFlags(), Qt::WindowFlags(outputFlags));
+
+ // Construct with custom flags set already
+ QGraphicsWidget widget3(0, Qt::WindowFlags(inputFlags | Qt::FramelessWindowHint));
+ QCOMPARE(widget3.windowFlags(), Qt::WindowFlags(inputFlags | Qt::FramelessWindowHint));
+
+ // Set custom flags after construction
+ QGraphicsWidget widget4;
+ widget4.setWindowFlags(Qt::WindowFlags(inputFlags | Qt::FramelessWindowHint));
+ QCOMPARE(widget4.windowFlags(), Qt::WindowFlags(inputFlags | Qt::FramelessWindowHint));
+
+ // Reset flags
+ widget4.setWindowFlags(0);
+ QVERIFY(!widget4.windowFlags());
+
+ // Set custom flags back again
+ widget4.setWindowFlags(Qt::WindowFlags(inputFlags | Qt::FramelessWindowHint));
+ QCOMPARE(widget4.windowFlags(), Qt::WindowFlags(inputFlags | Qt::FramelessWindowHint));
+
+ QGraphicsWidget *widget5 = new QGraphicsWidget;
+ widget5->setWindowFlags(Qt::WindowFlags(inputFlags));
+ QCOMPARE(widget5->windowFlags(), Qt::WindowFlags(outputFlags));
+ QGraphicsWidget window(0, Qt::Window);
+ widget5->setParentItem(&window);
+ QCOMPARE(widget5->windowFlags(), Qt::WindowFlags(outputFlags));
+}
+
+void tst_QGraphicsWidget::shortcutsDeletion()
+{
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ QGraphicsWidget *widget2 = new QGraphicsWidget;
+ widget->setMinimumSize(40, 40);
+ QWidgetAction *del = new QWidgetAction(widget);
+ del->setIcon(QIcon("edit-delete"));
+ del->setShortcut(Qt::Key_Delete);
+ del->setShortcutContext(Qt::WidgetShortcut);
+ widget2->addAction(del);
+ widget2->addAction(del);
+ delete widget;
+}
+
+class MessUpPainterWidget : public QGraphicsWidget
+{
+public:
+ MessUpPainterWidget(QGraphicsItem * parent = 0, Qt::WindowFlags wFlags = 0)
+ : QGraphicsWidget(parent, wFlags)
+ {}
+
+ void paintWindowFrame(QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ {
+ QCOMPARE(painter->opacity(), 1.0);
+ painter->setOpacity(0.0);
+ QGraphicsWidget::paintWindowFrame(painter, option, widget);
+ }
+ void paint(QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ {
+ QCOMPARE(painter->opacity(), 1.0);
+ painter->drawRect(0, 0, 100, 100);
+ QGraphicsWidget::paint(painter, option, widget);
+ }
+
+};
+
+void tst_QGraphicsWidget::painterStateProtectionOnWindowFrame()
+{
+ MessUpPainterWidget *widget = new MessUpPainterWidget(0, Qt::Window);
+ QGraphicsScene scene(0, 0, 300, 300);
+ QGraphicsView view(&scene);
+ scene.addItem(widget);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+}
+
+class ProxyStyle : public QCommonStyle
+{
+public:
+ ProxyStyle(QStyle *proxyStyle) : QCommonStyle()
+ {
+ m_proxyStyle = proxyStyle;
+ }
+
+ int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const
+ {
+ return m_proxyStyle->pixelMetric(metric, option, widget);
+ }
+
+private:
+ QStyle *m_proxyStyle;
+};
+
+class StyledGraphicsWidget : public QGraphicsWidget
+{
+public:
+ StyledGraphicsWidget(bool useOwnStyle) : QGraphicsWidget(), m_style(0) {
+ if (useOwnStyle) {
+ QStyle *oldStyle = style();
+ m_style = new ProxyStyle(oldStyle);
+ setStyle(m_style);
+ }
+
+ style()->pixelMetric(QStyle::PM_SmallIconSize); // crash when style() is still in widgetStyles
+ }
+
+ ~StyledGraphicsWidget() {
+ delete m_style;
+ }
+
+private:
+ QStyle *m_style;
+};
+
+void tst_QGraphicsWidget::task243004_setStyleCrash()
+{
+ QGraphicsItem *item1 = new StyledGraphicsWidget(true);
+ delete item1; // item1 not removed from widgetStyles
+
+ QGraphicsItem *item2 = new StyledGraphicsWidget(false);
+ delete item2;
+}
+
+class GraphicsWidget_task250119 : public QGraphicsWidget
+{
+public:
+ GraphicsWidget_task250119()
+ : shortcutEvents(0)
+ {
+ setFocusPolicy(Qt::StrongFocus);
+ resize(100, 100);
+ }
+
+ int shortcutEvents;
+
+private:
+ bool event(QEvent *event)
+ {
+ if (event->type() == QEvent::Shortcut)
+ shortcutEvents++;
+ return QGraphicsWidget::event(event);
+ }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+ {
+ if (hasFocus()) {
+ painter->setPen(QPen(Qt::black, 0, Qt::DashLine));
+ painter->drawRect(rect());
+ }
+ painter->setPen(QPen(Qt::black, 0, Qt::SolidLine));
+ painter->fillRect(rect().adjusted(2, 2, -2, -2), Qt::yellow);
+ painter->drawRect(rect().adjusted(2, 2, -2, -2));
+ }
+};
+
+void tst_QGraphicsWidget::task250119_shortcutContext()
+{
+ QGraphicsScene scene;
+ QGraphicsView view;
+ view.setScene(&scene);
+ view.show();
+ QApplication::setActiveWindow(&view);
+ QTRY_COMPARE(QApplication::activeWindow(), (QWidget*)&view);
+
+
+ // *** Event: ***
+
+ GraphicsWidget_task250119 w_event;
+ scene.addItem(&w_event);
+
+ const int id = w_event.grabShortcut(Qt::Key_A, Qt::WidgetWithChildrenShortcut);
+ w_event.setShortcutEnabled(id, true);
+
+ w_event.setFocus();
+ QTest::keyPress(&view, Qt::Key_A);
+ QCOMPARE(w_event.shortcutEvents, 1);
+
+ w_event.clearFocus();
+ QTest::keyPress(&view, Qt::Key_A);
+ QCOMPARE(w_event.shortcutEvents, 1);
+
+ scene.removeItem(&w_event);
+
+
+ // *** Signal: ***
+
+ GraphicsWidget_task250119 w_signal;
+ scene.addItem(&w_signal);
+
+ QAction action(0);
+ action.setShortcut(Qt::Key_B);
+ action.setShortcutContext(Qt::WidgetWithChildrenShortcut);
+ QSignalSpy spy(&action, SIGNAL(triggered()));
+
+ w_signal.addAction(&action);
+
+ w_signal.setFocus();
+ QTest::keyPress(&view, Qt::Key_B);
+ QCOMPARE(spy.count(), 1);
+
+ w_signal.clearFocus();
+ QTest::keyPress(&view, Qt::Key_B);
+ QCOMPARE(spy.count(), 1);
+
+ scene.removeItem(&w_signal);
+}
+
+class ClippingAndTransformsScene : public QGraphicsScene
+{
+public:
+ QList<QGraphicsItem *> drawnItems;
+protected:
+ void drawItems(QPainter *painter, int numItems, QGraphicsItem *items[],
+ const QStyleOptionGraphicsItem options[], QWidget *widget = 0)
+ {
+ drawnItems.clear();
+ for (int i = 0; i < numItems; ++i)
+ drawnItems << items[i];
+ QGraphicsScene::drawItems(painter, numItems, items, options, widget);
+ }
+};
+
+class RectWidget : public QGraphicsWidget
+{
+public:
+
+ RectWidget(Qt::GlobalColor color, QGraphicsItem *parent=0) : QGraphicsWidget(parent), mColor(color) {}
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+ {
+ painter->setBrush(QBrush(mColor));
+ painter->drawRect(boundingRect());
+ }
+
+ Qt::GlobalColor mColor;
+};
+
+class RectItem : public QGraphicsItem
+{
+public:
+
+ RectItem(Qt::GlobalColor color, QGraphicsItem *parent=0) : QGraphicsItem(parent), mColor(color) {}
+
+ QRectF boundingRect() const
+ {return QRectF(10,10,50,50);}
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+ {
+ painter->setBrush(QBrush(mColor));
+ painter->drawRect(boundingRect());
+ }
+
+ Qt::GlobalColor mColor;
+};
+
+void tst_QGraphicsWidget::ensureClipping()
+{
+ ClippingAndTransformsScene scene;
+ scene.setSceneRect(-50, -50, 200, 200);
+
+ //A root that clip children
+ RectWidget *clipWidget = new RectWidget(Qt::black);
+ scene.addItem(clipWidget);
+
+ clipWidget->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
+
+ //a child
+ RectWidget *childWidget = new RectWidget(Qt::red, clipWidget);
+ clipWidget->setGeometry(QRectF(10, 10, 100, 100));
+ childWidget->setGeometry(QRectF(25, 25, 50, 50));
+
+ //We put a QGraphicsItem to be sure this one is also paint
+ RectItem *childitem = new RectItem(Qt::blue, clipWidget);
+
+ QGraphicsView view(&scene);
+ view.setOptimizationFlag(QGraphicsView::IndirectPainting);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+
+ QList<QGraphicsItem *> expected;
+ expected << clipWidget << childWidget << childitem;
+ QTRY_VERIFY(scene.drawnItems.contains(clipWidget));
+ QVERIFY(scene.drawnItems.contains(childWidget));
+ QVERIFY(scene.drawnItems.contains(childitem));
+}
+
+class ItemChangeTester : public QGraphicsWidget
+{
+public:
+ ItemChangeTester()
+ { setFlag(ItemSendsGeometryChanges); clear(); }
+ ItemChangeTester(QGraphicsItem *parent) : QGraphicsWidget(parent)
+ { setFlag(ItemSendsGeometryChanges); clear(); }
+
+ void clear()
+ {
+ changes.clear();
+ values.clear();
+ oldValues.clear();
+ }
+ QList<GraphicsItemChange> changes;
+ QList<QVariant> values;
+ QList<QVariant> oldValues;
+protected:
+ QVariant itemChange(GraphicsItemChange change, const QVariant &value)
+ {
+ changes << change;
+ values << value;
+ switch (change) {
+ case QGraphicsItem::ItemPositionChange:
+ oldValues << pos();
+ break;
+ case QGraphicsItem::ItemPositionHasChanged:
+ break;
+ default:
+ break;
+ }
+ return value;
+ }
+};
+
+void tst_QGraphicsWidget::widgetSendsGeometryChanges()
+{
+ ItemChangeTester widget;
+ widget.setFlags(0);
+ widget.clear();
+
+ QPointF pos(10, 10);
+ widget.setPos(pos);
+
+ QCOMPARE(widget.pos(), pos);
+ QCOMPARE(widget.changes.size(), 0);
+
+ widget.setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
+ QCOMPARE(widget.changes.size(), 2);
+
+ widget.setPos(QPointF());
+ QCOMPARE(widget.changes.size(), 4);
+
+ QCOMPARE(widget.pos(), QPointF());
+
+ QRectF geometry(20, 20, 50, 50);
+ widget.setGeometry(geometry);
+ QCOMPARE(widget.changes.size(), 6);
+
+ QCOMPARE(widget.geometry(), geometry);
+
+ QCOMPARE(widget.changes, QList<QGraphicsItem::GraphicsItemChange>()
+ << QGraphicsItem::ItemFlagsChange
+ << QGraphicsItem::ItemFlagsHaveChanged
+ << QGraphicsItem::ItemPositionChange
+ << QGraphicsItem::ItemPositionHasChanged
+ << QGraphicsItem::ItemPositionChange
+ << QGraphicsItem::ItemPositionHasChanged);
+}
+
+class HFWWidget : public QGraphicsWidget
+{
+public:
+ HFWWidget() : QGraphicsWidget(0, Qt::Window)
+ {
+ QSizePolicy sp;
+ sp.setHeightForWidth(true);
+ setSizePolicy(sp);
+ }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ {
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+ qreal w = rect().width();
+ QRectF box(0, 0, w, 2400/w);
+ painter->drawRoundRect(box);
+ painter->drawLine(box.topLeft(), box.bottomRight());
+ painter->drawLine(box.bottomLeft(), box.topRight());
+ }
+
+protected:
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const
+ {
+ qreal w = constraint.width();
+ switch (which) {
+ case Qt::MinimumSize:
+ if (w >= 0 && constraint.height() < 0) {
+ // keep the same area of 60x40 = 2400
+ return QSizeF(w, 2400.0/w);
+ } else {
+ return QSizeF(10, 10);
+ }
+ break;
+ case Qt::PreferredSize:
+ return QSizeF(48.989794, 48.989794);
+ default:
+ break;
+ }
+ return QGraphicsWidget::sizeHint(which, constraint);
+ }
+};
+
+void tst_QGraphicsWidget::respectHFW()
+{
+#if defined(Q_OS_WINCE) || defined(Q_OS_MAC) || defined(Q_WS_QWS)
+ qDebug("This test is platform dependent, it fails on wince, mac and qws. Please fix.");
+#else
+ QGraphicsScene scene;
+ HFWWidget *window = new HFWWidget;
+ scene.addItem(window);
+ QGraphicsView *view = new QGraphicsView(&scene);
+ view->resize(400, 400);
+ view->setSceneRect(-100, -100, 300,300);
+
+ view->show();
+ window->setGeometry(0, 0, 70, 70);
+ QTest::qWaitForWindowShown(view);
+
+ { // here we go - simulate a interactive resize of the window
+ QTest::mouseMove(view, view->mapFromScene(71, 71)); // bottom right corner
+
+ QTest::mousePress(view->viewport(), Qt::LeftButton, 0, view->mapFromScene(71, 71), 200);
+ view->grabMouse();
+ // move both mouse cursor and set correct event in order to emulate resize
+ QTest::mouseMove(view->viewport(), view->mapFromScene(60, 30), 200);
+ QMouseEvent e = QMouseEvent(QEvent::MouseMove,
+ view->mapFromScene(60, 20),
+ Qt::NoButton,
+ Qt::LeftButton,
+ Qt::NoModifier);
+ QApplication::sendEvent(view->viewport(), &e);
+ view->releaseMouse();
+ }
+ const QSizeF winSize = window->size();
+ qreal minHFW = window->effectiveSizeHint(Qt::MinimumSize, QSizeF(winSize.width(), -1)).height();
+ QTRY_VERIFY(qAbs(minHFW - winSize.height()) < 1);
+#endif
+}
+
+class PolishWidget : public QGraphicsWidget
+{
+public:
+
+ PolishWidget(Qt::GlobalColor color, QGraphicsItem *parent=0) :
+ QGraphicsWidget(parent), mColor(color)
+ {
+ }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+ {
+ painter->setBrush(QBrush(mColor));
+ painter->drawRect(boundingRect());
+ }
+
+ void polishEvent()
+ {
+ if (!parentWidget()) {
+ //We add a child in the polish event for the parent
+ PolishWidget *childWidget = new PolishWidget(Qt::black, this);
+ childWidget->setGeometry(QRectF(10,10,30,30));
+ }
+
+ QGraphicsWidget::polishEvent();
+ mColor = Qt::red;
+ update();
+ numberOfPolish++;
+ }
+
+ static int numberOfPolish;
+
+private:
+ Qt::GlobalColor mColor;
+};
+
+int PolishWidget::numberOfPolish = 0;
+
+void tst_QGraphicsWidget::addChildInpolishEvent()
+{
+ QGraphicsScene scene;
+
+ PolishWidget *parentWidget = new PolishWidget(Qt::white);
+ scene.addItem(parentWidget);
+
+ QGraphicsView view(&scene);
+ view.resize(200, 200);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+ QTRY_COMPARE(PolishWidget::numberOfPolish, 2);
+}
+
+void tst_QGraphicsWidget::polishEvent()
+{
+ class MyGraphicsWidget : public QGraphicsWidget
+ { public:
+ void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *)
+ { events << QEvent::Paint; }
+ void polishEvent()
+ { events << QEvent::Polish; }
+ QList<QEvent::Type> events;
+ };
+
+ QGraphicsScene scene;
+
+ MyGraphicsWidget *widget = new MyGraphicsWidget;
+ scene.addItem(widget);
+
+ QGraphicsView view(&scene);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+
+ // Make sure the item is painted.
+ QTRY_VERIFY(widget->events.contains(QEvent::Paint));
+
+ // Make sure the item got polish before paint.
+ QCOMPARE(widget->events.at(0), QEvent::Polish);
+}
+
+void tst_QGraphicsWidget::polishEvent2()
+{
+ class MyGraphicsWidget : public QGraphicsWidget
+ { public:
+ void polishEvent()
+ { events << QEvent::Polish; }
+ QList<QEvent::Type> events;
+ };
+
+ QGraphicsScene scene;
+
+ MyGraphicsWidget *widget = new MyGraphicsWidget;
+ widget->hide();
+ scene.addItem(widget);
+
+ widget->events.clear();
+
+ // Make sure the item got polish event.
+ QTRY_VERIFY(widget->events.contains(QEvent::Polish));
+}
+
+void tst_QGraphicsWidget::autoFillBackground()
+{
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ QCOMPARE(widget->autoFillBackground(), false);
+ widget->setAutoFillBackground(true);
+ QCOMPARE(widget->autoFillBackground(), true);
+
+ const QColor color(Qt::red);
+ const QRect rect(0, 0, 1, 1);
+
+ QGraphicsScene scene;
+ scene.addItem(widget);
+ widget->setGeometry(rect);
+
+ QPalette palette = widget->palette();
+ palette.setColor(QPalette::Window, color);
+ widget->setPalette(palette);
+
+ QImage image(rect.size(), QImage::Format_RGB32);
+ QPainter painter;
+ painter.begin(&image);
+ scene.render(&painter, rect, rect);
+ painter.end();
+ QCOMPARE(image.pixel(0, 0), color.rgb());
+}
+
+void tst_QGraphicsWidget::initialShow()
+{
+ class MyGraphicsWidget : public QGraphicsWidget
+ { public:
+ MyGraphicsWidget() : repaints(0) {}
+ int repaints;
+ void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget*) { ++repaints; }
+ void polishEvent() { update(); }
+ };
+
+ QGraphicsScene scene;
+ MyGraphicsWidget *widget = new MyGraphicsWidget;
+
+ QGraphicsView view(&scene);
+ if(PlatformQuirks::isAutoMaximizing())
+ view.showFullScreen();
+ else
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+
+ scene.addItem(widget);
+
+ QTRY_COMPARE(widget->repaints, 1);
+}
+
+void tst_QGraphicsWidget::initialShow2()
+{
+ class MyGraphicsWidget : public QGraphicsWidget
+ { public:
+ MyGraphicsWidget() : repaints(0) {}
+ int repaints;
+ void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget*) { ++repaints; }
+ void polishEvent() { update(); }
+ };
+
+ // Don't let paint events triggered by the windowing system
+ // influence our test case. We're only interested in knowing
+ // whether a QGraphicsWidget generates an additional repaint
+ // on the inital show. Hence create a dummy scenario to find out
+ // how many repaints we should expect.
+ QGraphicsScene dummyScene(0, 0, 200, 200);
+ dummyScene.addItem(new QGraphicsRectItem(0, 0, 100, 100));
+
+ QGraphicsView *dummyView = new QGraphicsView(&dummyScene);
+ dummyView->setWindowFlags(Qt::X11BypassWindowManagerHint);
+ EventSpy paintSpy(dummyView->viewport(), QEvent::Paint);
+ dummyView->show();
+ QTest::qWaitForWindowShown(dummyView);
+ const int expectedRepaintCount = paintSpy.count();
+ delete dummyView;
+ dummyView = 0;
+
+ MyGraphicsWidget *widget = new MyGraphicsWidget;
+ widget->resize(100, 100);
+
+ QGraphicsScene scene(0, 0, 200, 200);
+ scene.addItem(widget);
+
+ QGraphicsView view(&scene);
+ view.setWindowFlags(view.windowFlags()|Qt::X11BypassWindowManagerHint);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+
+ QTRY_COMPARE(widget->repaints, expectedRepaintCount);
+}
+
+void tst_QGraphicsWidget::itemChangeEvents()
+{
+ class TestGraphicsWidget : public QGraphicsWidget
+ { public:
+ TestGraphicsWidget() : QGraphicsWidget() {}
+ QHash<QEvent::Type, QVariant> valueDuringEvents;
+ bool event(QEvent *event) {
+ Q_UNUSED(event);
+ switch (event->type()) {
+ case QEvent::EnabledChange: {
+ valueDuringEvents.insert(QEvent::EnabledChange, isEnabled());
+ break;
+ }
+ case QEvent::ParentAboutToChange: {
+ valueDuringEvents.insert(QEvent::ParentAboutToChange, qVariantFromValue(parentItem()));
+ break;
+ }
+ case QEvent::ParentChange: {
+ valueDuringEvents.insert(QEvent::ParentChange, qVariantFromValue(parentItem()));
+ break;
+ }
+ case QEvent::CursorChange: {
+ valueDuringEvents.insert(QEvent::CursorChange, int(cursor().shape()));
+ break;
+ }
+ case QEvent::ToolTipChange: {
+ valueDuringEvents.insert(QEvent::ToolTipChange, toolTip());
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ return true;
+ }
+ void showEvent(QShowEvent *event) {
+ Q_UNUSED(event);
+ valueDuringEvents.insert(QEvent::Show, isVisible());
+ }
+ void hideEvent(QHideEvent *event) {
+ Q_UNUSED(event);
+ valueDuringEvents.insert(QEvent::Hide, isVisible());
+ }
+ };
+
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ QGraphicsWidget *parent = new QGraphicsWidget;
+ scene.addItem(parent);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+
+ TestGraphicsWidget *item = new TestGraphicsWidget;
+ item->setParentItem(parent);
+ // ParentAboutToChange should be triggered before the parent has changed
+ QTRY_COMPARE(qVariantValue<QGraphicsItem *>(item->valueDuringEvents.value(QEvent::ParentAboutToChange)),
+ static_cast<QGraphicsItem *>(0));
+ // ParentChange should be triggered after the parent has changed
+ QTRY_COMPARE(qVariantValue<QGraphicsItem *>(item->valueDuringEvents.value(QEvent::ParentChange)),
+ static_cast<QGraphicsItem *>(parent));
+
+ // ShowEvent should be triggered before the item is shown
+ QTRY_VERIFY(!item->valueDuringEvents.value(QEvent::Show).toBool());
+
+ // HideEvent should be triggered after the item is hidden
+ QVERIFY(item->isVisible());
+ item->setVisible(false);
+ QVERIFY(!item->isVisible());
+ QTRY_VERIFY(!item->valueDuringEvents.value(QEvent::Hide).toBool());
+
+ // CursorChange should be triggered after the cursor has changed
+ item->setCursor(Qt::PointingHandCursor);
+ QTRY_COMPARE(item->valueDuringEvents.value(QEvent::CursorChange).toInt(), int(item->cursor().shape()));
+
+ // ToolTipChange should be triggered after the tooltip has changed
+ item->setToolTip("tooltipText");
+ QTRY_COMPARE(item->valueDuringEvents.value(QEvent::ToolTipChange).toString(), item->toolTip());
+
+ // EnabledChange should be triggered after the enabled state has changed
+ QVERIFY(item->isEnabled());
+ item->setEnabled(false);
+ QVERIFY(!item->isEnabled());
+ QTRY_VERIFY(!item->valueDuringEvents.value(QEvent::EnabledChange).toBool());
+}
+
+void tst_QGraphicsWidget::itemSendGeometryPosChangesDeactivated()
+{
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ QGraphicsWidget *item = new QGraphicsWidget;
+ scene.addItem(item);
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+ item->setGeometry(QRectF(0, 0, 50, 50));
+ QTRY_COMPARE(item->geometry(), QRectF(0, 0, 50, 50));
+
+ item->setFlag(QGraphicsItem::ItemSendsGeometryChanges, false);
+ item->setGeometry(QRectF(0, 0, 60, 60));
+ QCOMPARE(item->geometry(), QRectF(0, 0, 60, 60));
+ QCOMPARE(item->pos(), QPointF(0, 0));
+ item->setPos(QPointF(10, 10));
+ QCOMPARE(item->pos(), QPointF(10, 10));
+ QCOMPARE(item->geometry(), QRectF(10, 10, 60, 60));
+
+ item->setFlag(QGraphicsItem::ItemSendsScenePositionChanges, false);
+ item->setGeometry(QRectF(0, 0, 60, 60));
+ QCOMPARE(item->geometry(), QRectF(0, 0, 60, 60));
+ QCOMPARE(item->pos(), QPointF(0, 0));
+ item->setPos(QPointF(10, 10));
+ QCOMPARE(item->pos(), QPointF(10, 10));
+ QCOMPARE(item->geometry(), QRectF(10, 10, 60, 60));
+}
+
+void tst_QGraphicsWidget::QT_BUG_6544_tabFocusFirstUnsetWhenRemovingItems()
+{
+ QGraphicsScene scene;
+ QGraphicsWidget* parent1 = new QGraphicsWidget;
+ QGraphicsWidget* child1_0 = new QGraphicsWidget;
+ QGraphicsWidget* child1_1 = new QGraphicsWidget;
+
+ QGraphicsWidget* parent2 = new QGraphicsWidget;
+
+ // Add the parent and child to the scene.
+ scene.addItem(parent1);
+ child1_0->setParentItem(parent1);
+ child1_1->setParentItem(parent1);
+
+ // Hide and show the child.
+ child1_0->setParentItem(NULL);
+ scene.removeItem(child1_0);
+
+ // Remove parent from the scene.
+ scene.removeItem(parent1);
+
+ delete child1_0;
+ delete child1_1;
+ delete parent1;
+
+ // Add an item into the scene.
+ scene.addItem(parent2);
+
+ //This should not crash
+}
+void tst_QGraphicsWidget::QT_BUG_12056_tabFocusFirstUnsetWhenRemovingItems()
+{
+ QGraphicsScene scene;
+ QGraphicsWidget* item1 = new QGraphicsWidget;
+ QGraphicsWidget* item2 = new QGraphicsWidget;
+ QGraphicsWidget* item3 = new QGraphicsWidget;
+
+ scene.addItem(item1);
+ scene.addItem(item2);
+
+ scene.removeItem(item2);
+ scene.removeItem(item1);
+ delete item2;
+ delete item1;
+
+ scene.addItem(item3);
+
+ //This should not crash
+}
+
+
+struct GreenWidget : public QGraphicsWidget
+{
+ GreenWidget() : count(0)
+ {
+ }
+
+ void paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * )
+ {
+ count++;
+ painter->setPen(Qt::green);
+ painter->drawRect(option->rect.adjusted(0,0,-1,-1));
+ }
+
+ int count;
+};
+
+void tst_QGraphicsWidget::QT_BUG_13865_doublePaintWhenAddingASubItem()
+{
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ QGraphicsWidget *widget = new QGraphicsWidget;
+ widget->resize(100, 100);
+ scene.addItem(widget);
+ QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(widget);
+
+ view.show();
+ QTest::qWaitForWindowShown(&view);
+ QApplication::processEvents();
+
+
+ GreenWidget *sub = new GreenWidget;
+ layout->addItem(sub);
+
+ QTest::qWait(100);
+ QCOMPARE(sub->count, 1); //it should only be painted once
+
+}
+
+
+QTEST_MAIN(tst_QGraphicsWidget)
+#include "tst_qgraphicswidget.moc"
+
+#else // QT_NO_STYLE_CLEANLOOKS
+QTEST_NOOP_MAIN
+#endif
+