summaryrefslogtreecommitdiffstats
path: root/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp')
-rw-r--r--tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp3416
1 files changed, 3416 insertions, 0 deletions
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
+