2011-04-27 10:05:43 +00:00
|
|
|
/****************************************************************************
|
|
|
|
**
|
2016-01-15 12:36:27 +00:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2011-04-27 10:05:43 +00:00
|
|
|
**
|
|
|
|
** This file is part of the test suite of the Qt Toolkit.
|
|
|
|
**
|
2016-01-15 12:36:27 +00:00
|
|
|
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
2012-09-19 12:28:29 +00:00
|
|
|
** Commercial License Usage
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
2015-01-28 08:44:43 +00:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
2016-01-15 12:36:27 +00:00
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2012-09-19 12:28:29 +00:00
|
|
|
**
|
2016-01-15 12:36:27 +00:00
|
|
|
** GNU General Public License Usage
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
2011-04-27 10:05:43 +00:00
|
|
|
**
|
|
|
|
** $QT_END_LICENSE$
|
|
|
|
**
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
|
2020-11-26 16:31:50 +00:00
|
|
|
#include <QTest>
|
2011-04-27 10:05:43 +00:00
|
|
|
#include <QtGui>
|
2011-09-16 12:07:05 +00:00
|
|
|
#include <QtWidgets>
|
2011-04-27 10:05:43 +00:00
|
|
|
#include <private/qgraphicsproxywidget_p.h>
|
|
|
|
#include <private/qlayoutengine_p.h> // qSmartMin functions...
|
|
|
|
|
|
|
|
/*
|
|
|
|
Notes:
|
|
|
|
|
|
|
|
1) The proxy and the widget geometries are linked.
|
|
|
|
proxy resize => widget resize => stop (no livelock)
|
|
|
|
widget resize => proxy resize => stop (no livelock)
|
|
|
|
|
|
|
|
2) As far as possible, the properties are linked.
|
|
|
|
proxy enable => widget enable => stop
|
|
|
|
widget disabled => proxy disabled => stop
|
|
|
|
|
|
|
|
3) Windowed state is linked
|
|
|
|
Windowed proxy state => windowed widget state => stop
|
|
|
|
Windowed widget state => windowed proxy state => stop
|
|
|
|
*/
|
|
|
|
|
|
|
|
class EventSpy : public QObject
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
EventSpy(QObject *receiver)
|
|
|
|
{
|
|
|
|
receiver->installEventFilter(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
QMap<QEvent::Type, int> counts;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
bool eventFilter(QObject *, QEvent *event)
|
|
|
|
{
|
|
|
|
++counts[event->type()];
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class tst_QGraphicsProxyWidget : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
2015-12-03 15:59:30 +00:00
|
|
|
private slots:
|
2011-04-27 10:05:43 +00:00
|
|
|
void initTestCase();
|
|
|
|
void cleanup();
|
|
|
|
void qgraphicsproxywidget_data();
|
|
|
|
void qgraphicsproxywidget();
|
|
|
|
void paint();
|
|
|
|
void paint_2();
|
|
|
|
void setWidget_data();
|
|
|
|
void setWidget();
|
2015-07-28 08:11:52 +00:00
|
|
|
void testEventFilter_data();
|
|
|
|
void testEventFilter();
|
2011-04-27 10:05:43 +00:00
|
|
|
void focusInEvent_data();
|
|
|
|
void focusInEvent();
|
|
|
|
void focusInEventNoWidget();
|
|
|
|
void focusNextPrevChild_data();
|
|
|
|
void focusNextPrevChild();
|
|
|
|
void focusOutEvent_data();
|
|
|
|
void focusOutEvent();
|
2020-01-24 23:48:48 +00:00
|
|
|
void focusProxy_QTBUG_51856();
|
2011-04-27 10:05:43 +00:00
|
|
|
void hoverEnterLeaveEvent_data();
|
|
|
|
void hoverEnterLeaveEvent();
|
|
|
|
void hoverMoveEvent_data();
|
|
|
|
void hoverMoveEvent();
|
|
|
|
void keyPressEvent_data();
|
|
|
|
void keyPressEvent();
|
|
|
|
void keyReleaseEvent_data();
|
|
|
|
void keyReleaseEvent();
|
|
|
|
void mouseDoubleClickEvent_data();
|
|
|
|
void mouseDoubleClickEvent();
|
|
|
|
void mousePressReleaseEvent_data();
|
|
|
|
void mousePressReleaseEvent();
|
|
|
|
void resizeEvent_data();
|
|
|
|
void resizeEvent();
|
|
|
|
void paintEvent();
|
2017-05-30 20:22:22 +00:00
|
|
|
#if QT_CONFIG(wheelevent)
|
2011-04-27 10:05:43 +00:00
|
|
|
void wheelEvent();
|
2015-02-27 09:22:36 +00:00
|
|
|
#endif
|
2011-04-27 10:05:43 +00:00
|
|
|
void sizeHint_data();
|
|
|
|
void sizeHint();
|
|
|
|
void sizePolicy();
|
|
|
|
void minimumSize();
|
|
|
|
void maximumSize();
|
|
|
|
void scrollUpdate();
|
|
|
|
void setWidget_simple();
|
|
|
|
void setWidget_ownership();
|
|
|
|
void resize_simple_data();
|
|
|
|
void resize_simple();
|
|
|
|
void symmetricMove();
|
|
|
|
void symmetricResize();
|
|
|
|
void symmetricEnabled();
|
|
|
|
void symmetricVisible();
|
|
|
|
void tabFocus_simpleWidget();
|
|
|
|
void tabFocus_simpleTwoWidgets();
|
|
|
|
void tabFocus_complexWidget();
|
|
|
|
void tabFocus_complexTwoWidgets();
|
|
|
|
void setFocus_simpleWidget();
|
|
|
|
void setFocus_simpleTwoWidgets();
|
|
|
|
void setFocus_complexTwoWidgets();
|
|
|
|
void popup_basic();
|
|
|
|
void popup_subwidget();
|
|
|
|
void changingCursor_basic();
|
|
|
|
void tooltip_basic();
|
|
|
|
void childPos_data();
|
|
|
|
void childPos();
|
|
|
|
void autoShow();
|
|
|
|
void windowOpacity();
|
|
|
|
void stylePropagation();
|
|
|
|
void palettePropagation();
|
|
|
|
void fontPropagation();
|
|
|
|
void dontCrashWhenDie();
|
2018-11-17 13:58:15 +00:00
|
|
|
void dontCrashNoParent();
|
2011-04-27 10:05:43 +00:00
|
|
|
void createProxyForChildWidget();
|
2015-09-04 03:07:27 +00:00
|
|
|
#ifndef QT_NO_CONTEXTMENU
|
2011-04-27 10:05:43 +00:00
|
|
|
void actionsContextMenu();
|
2015-09-04 03:07:27 +00:00
|
|
|
#endif // QT_NO_CONTEXTMENU
|
2011-04-27 10:05:43 +00:00
|
|
|
void actionsContextMenu_data();
|
|
|
|
void deleteProxyForChildWidget();
|
|
|
|
void bypassGraphicsProxyWidget_data();
|
|
|
|
void bypassGraphicsProxyWidget();
|
|
|
|
void dragDrop();
|
|
|
|
void windowFlags_data();
|
|
|
|
void windowFlags();
|
|
|
|
void comboboxWindowFlags();
|
|
|
|
void updateAndDelete();
|
|
|
|
void inputMethod();
|
|
|
|
void clickFocus();
|
|
|
|
void windowFrameMargins();
|
|
|
|
void QTBUG_6986_sendMouseEventToAlienWidget();
|
2014-10-21 10:24:52 +00:00
|
|
|
void mapToGlobal();
|
2015-02-17 08:53:27 +00:00
|
|
|
void mapToGlobalWithoutScene();
|
2015-01-19 15:57:20 +00:00
|
|
|
void QTBUG_43780_visibility();
|
2015-09-03 16:53:53 +00:00
|
|
|
void forwardTouchEvent();
|
2011-04-27 10:05:43 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Subclass that exposes the protected functions.
|
|
|
|
class SubQGraphicsProxyWidget : public QGraphicsProxyWidget
|
|
|
|
{
|
|
|
|
|
|
|
|
public:
|
2020-10-07 11:05:48 +00:00
|
|
|
SubQGraphicsProxyWidget(QGraphicsItem *parent = nullptr) : QGraphicsProxyWidget(parent),
|
2011-04-27 10:05:43 +00:00
|
|
|
paintCount(0), keyPress(0), focusOut(0)
|
|
|
|
{}
|
|
|
|
|
|
|
|
bool call_eventFilter(QObject* object, QEvent* event)
|
|
|
|
{ return SubQGraphicsProxyWidget::eventFilter(object, event); }
|
|
|
|
|
|
|
|
void call_focusInEvent(QFocusEvent* event)
|
|
|
|
{ return SubQGraphicsProxyWidget::focusInEvent(event); }
|
|
|
|
|
|
|
|
bool call_focusNextPrevChild(bool next)
|
|
|
|
{ return SubQGraphicsProxyWidget::focusNextPrevChild(next); }
|
|
|
|
|
|
|
|
void call_focusOutEvent(QFocusEvent* event)
|
|
|
|
{ return SubQGraphicsProxyWidget::focusOutEvent(event); }
|
|
|
|
|
|
|
|
void call_hideEvent(QHideEvent* event)
|
|
|
|
{ return SubQGraphicsProxyWidget::hideEvent(event); }
|
|
|
|
|
|
|
|
void call_hoverEnterEvent(QGraphicsSceneHoverEvent* event)
|
|
|
|
{ return SubQGraphicsProxyWidget::hoverEnterEvent(event); }
|
|
|
|
|
|
|
|
void call_hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
|
|
|
|
{ return SubQGraphicsProxyWidget::hoverLeaveEvent(event); }
|
|
|
|
|
|
|
|
void call_hoverMoveEvent(QGraphicsSceneHoverEvent* event)
|
|
|
|
{ return SubQGraphicsProxyWidget::hoverMoveEvent(event); }
|
|
|
|
|
|
|
|
void call_keyPressEvent(QKeyEvent* event)
|
|
|
|
{ return SubQGraphicsProxyWidget::keyPressEvent(event); }
|
|
|
|
|
|
|
|
void call_keyReleaseEvent(QKeyEvent* event)
|
|
|
|
{ return SubQGraphicsProxyWidget::keyReleaseEvent(event); }
|
|
|
|
|
|
|
|
void call_mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
|
|
|
|
{ return SubQGraphicsProxyWidget::mouseDoubleClickEvent(event); }
|
|
|
|
|
|
|
|
void call_mouseMoveEvent(QGraphicsSceneMouseEvent* event)
|
|
|
|
{ return SubQGraphicsProxyWidget::mouseMoveEvent(event); }
|
|
|
|
|
|
|
|
void call_mousePressEvent(QGraphicsSceneMouseEvent* event)
|
|
|
|
{ return SubQGraphicsProxyWidget::mousePressEvent(event); }
|
|
|
|
|
|
|
|
void call_mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
|
|
|
|
{ return SubQGraphicsProxyWidget::mouseReleaseEvent(event); }
|
|
|
|
|
|
|
|
void call_resizeEvent(QGraphicsSceneResizeEvent* event)
|
|
|
|
{ return SubQGraphicsProxyWidget::resizeEvent(event); }
|
|
|
|
|
|
|
|
QSizeF call_sizeHint(Qt::SizeHint which, QSizeF const& constraint = QSizeF()) const
|
|
|
|
{ return SubQGraphicsProxyWidget::sizeHint(which, constraint); }
|
|
|
|
|
|
|
|
void call_showEvent(QShowEvent* event)
|
|
|
|
{ return SubQGraphicsProxyWidget::showEvent(event); }
|
|
|
|
|
2020-10-07 11:05:48 +00:00
|
|
|
void paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) {
|
2011-04-27 10:05:43 +00:00
|
|
|
paintCount++;
|
|
|
|
QGraphicsProxyWidget::paint(painter, option, widget);
|
|
|
|
}
|
|
|
|
|
|
|
|
void focusOutEvent(QFocusEvent *event)
|
|
|
|
{
|
|
|
|
focusOut++;
|
|
|
|
QGraphicsProxyWidget::focusOutEvent(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool eventFilter(QObject *object, QEvent *event) {
|
|
|
|
if (event->type() == QEvent::KeyPress && object == widget())
|
|
|
|
keyPress++;
|
|
|
|
return QGraphicsProxyWidget::eventFilter(object, event);
|
|
|
|
}
|
|
|
|
int paintCount;
|
|
|
|
int keyPress;
|
|
|
|
int focusOut;
|
|
|
|
};
|
|
|
|
|
2017-05-30 20:22:22 +00:00
|
|
|
#if QT_CONFIG(wheelevent)
|
2011-04-27 10:05:43 +00:00
|
|
|
class WheelWidget : public QWidget
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
WheelWidget() : wheelEventCalled(false) { setFocusPolicy(Qt::WheelFocus); }
|
|
|
|
|
|
|
|
virtual void wheelEvent(QWheelEvent *event) { event->accept(); wheelEventCalled = true; }
|
|
|
|
|
|
|
|
bool wheelEventCalled;
|
|
|
|
};
|
2017-05-30 20:22:22 +00:00
|
|
|
#endif // QT_CONFIG(wheelevent)
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
// This will be called before the first test function is executed.
|
|
|
|
// It is only called once.
|
|
|
|
void tst_QGraphicsProxyWidget::initTestCase()
|
|
|
|
{
|
2014-07-25 08:49:38 +00:00
|
|
|
// Disable menu animations to prevent the alpha widget from getting in the way
|
|
|
|
// in actionsContextMenu().
|
|
|
|
QApplication::setEffectEnabled(Qt::UI_AnimateMenu, false);
|
2015-01-19 15:57:20 +00:00
|
|
|
// Disable combo for QTBUG_43780_visibility()/Windows Vista.
|
|
|
|
QApplication::setEffectEnabled(Qt::UI_AnimateCombo, false);
|
2016-08-15 09:42:21 +00:00
|
|
|
QCoreApplication::setAttribute(Qt::AA_DontUseNativeDialogs);
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// This will be called after every test function.
|
|
|
|
void tst_QGraphicsProxyWidget::cleanup()
|
|
|
|
{
|
2017-12-07 15:31:43 +00:00
|
|
|
QTRY_VERIFY(QApplication::topLevelWidgets().isEmpty());
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::qgraphicsproxywidget_data()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::qgraphicsproxywidget()
|
|
|
|
{
|
|
|
|
SubQGraphicsProxyWidget proxy;
|
|
|
|
proxy.paint(0, 0, 0);
|
|
|
|
proxy.setWidget(0);
|
2015-07-30 13:16:36 +00:00
|
|
|
QCOMPARE(proxy.type(), int(QGraphicsProxyWidget::Type));
|
2011-04-27 10:05:43 +00:00
|
|
|
QVERIFY(!proxy.widget());
|
|
|
|
QEvent event(QEvent::None);
|
|
|
|
proxy.call_eventFilter(0, &event);
|
|
|
|
QFocusEvent focusEvent(QEvent::FocusIn);
|
|
|
|
focusEvent.ignore();
|
|
|
|
proxy.call_focusInEvent(&focusEvent);
|
|
|
|
QCOMPARE(focusEvent.isAccepted(), false);
|
|
|
|
QCOMPARE(proxy.call_focusNextPrevChild(false), false);
|
|
|
|
QCOMPARE(proxy.call_focusNextPrevChild(true), false);
|
|
|
|
proxy.call_focusOutEvent(&focusEvent);
|
|
|
|
QHideEvent hideEvent;
|
|
|
|
proxy.call_hideEvent(&hideEvent);
|
|
|
|
QGraphicsSceneHoverEvent hoverEvent;
|
|
|
|
proxy.call_hoverEnterEvent(&hoverEvent);
|
|
|
|
proxy.call_hoverLeaveEvent(&hoverEvent);
|
|
|
|
proxy.call_hoverMoveEvent(&hoverEvent);
|
|
|
|
QKeyEvent keyEvent(QEvent::KeyPress, 0, Qt::NoModifier);
|
|
|
|
proxy.call_keyPressEvent(&keyEvent);
|
|
|
|
proxy.call_keyReleaseEvent(&keyEvent);
|
|
|
|
QGraphicsSceneMouseEvent mouseEvent;
|
|
|
|
proxy.call_mouseDoubleClickEvent(&mouseEvent);
|
|
|
|
proxy.call_mouseMoveEvent(&mouseEvent);
|
|
|
|
proxy.call_mousePressEvent(&mouseEvent);
|
|
|
|
proxy.call_mouseReleaseEvent(&mouseEvent);
|
|
|
|
QGraphicsSceneResizeEvent resizeEvent;
|
|
|
|
proxy.call_resizeEvent(&resizeEvent);
|
|
|
|
QShowEvent showEvent;
|
|
|
|
proxy.call_showEvent(&showEvent);
|
|
|
|
proxy.call_sizeHint(Qt::PreferredSize, QSizeF());
|
|
|
|
}
|
|
|
|
|
|
|
|
// public void paint(QPainter* painter, QStyleOptionGraphicsItem const* option, QWidget* widget)
|
|
|
|
void tst_QGraphicsProxyWidget::paint()
|
|
|
|
{
|
|
|
|
SubQGraphicsProxyWidget proxy;
|
|
|
|
proxy.paint(0, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
class MyProxyWidget : public QGraphicsProxyWidget
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
|
|
|
{
|
|
|
|
// Make sure QGraphicsProxyWidget::paint does not modify the render hints set on the painter.
|
|
|
|
painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform
|
2019-05-11 11:37:12 +00:00
|
|
|
| QPainter::TextAntialiasing);
|
2011-04-27 10:05:43 +00:00
|
|
|
const QPainter::RenderHints oldRenderHints = painter->renderHints();
|
|
|
|
QGraphicsProxyWidget::paint(painter, option, widget);
|
|
|
|
QCOMPARE(painter->renderHints(), oldRenderHints);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::paint_2()
|
|
|
|
{
|
|
|
|
MyProxyWidget *proxyWidget = new MyProxyWidget;
|
|
|
|
proxyWidget->setWidget(new QLineEdit);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
scene.addItem(proxyWidget);
|
|
|
|
scene.setSceneRect(scene.itemsBoundingRect());
|
|
|
|
|
|
|
|
// Trigger repaint.
|
|
|
|
QPixmap pixmap(scene.sceneRect().toRect().size());
|
|
|
|
QPainter painter(&pixmap);
|
|
|
|
scene.render(&painter);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::setWidget_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<bool>("widgetExists");
|
|
|
|
QTest::addColumn<bool>("insertWidget");
|
|
|
|
QTest::addColumn<bool>("hasParent");
|
|
|
|
QTest::addColumn<bool>("proxyHasParent");
|
|
|
|
|
|
|
|
QTest::newRow("setWidget(0)") << false << false << false << false;
|
|
|
|
QTest::newRow("setWidget(widget)") << false << true << false << false;
|
|
|
|
QTest::newRow("setWidget(widgetWParent)") << false << true << true << false;
|
|
|
|
QTest::newRow("setWidget(1), setWidget(0)") << true << false << false << false;
|
|
|
|
QTest::newRow("setWidget(1), setWidget(widget)") << true << true << false << false;
|
|
|
|
QTest::newRow("setWidget(1), setWidget(widgetWParent)") << true << true << true << false;
|
|
|
|
QTest::newRow("p setWidget(0)") << false << false << false << true;
|
|
|
|
QTest::newRow("p setWidget(widget)") << false << true << false << true;
|
|
|
|
QTest::newRow("p setWidget(widgetWParent)") << false << true << true << true;
|
|
|
|
QTest::newRow("p setWidget(1), setWidget(0)") << true << false << false << true;
|
|
|
|
QTest::newRow("p setWidget(1), setWidget(widget)") << true << true << false << true;
|
|
|
|
QTest::newRow("p setWidget(1), setWidget(widgetWParent)") << true << true << true << true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// public void setWidget(QWidget* widget)
|
|
|
|
void tst_QGraphicsProxyWidget::setWidget()
|
|
|
|
{
|
|
|
|
QFETCH(bool, widgetExists);
|
|
|
|
QFETCH(bool, insertWidget);
|
|
|
|
QFETCH(bool, hasParent);
|
|
|
|
QFETCH(bool, proxyHasParent);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
view.show();
|
2016-08-03 13:20:09 +00:00
|
|
|
QScopedPointer<QStyle> style(QStyleFactory::create(QLatin1String("Fusion")));
|
2012-07-18 11:12:59 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
QPointer<SubQGraphicsProxyWidget> proxy = new SubQGraphicsProxyWidget;
|
|
|
|
SubQGraphicsProxyWidget parentProxy;
|
|
|
|
scene.addItem(proxy);
|
|
|
|
scene.addItem(&parentProxy);
|
|
|
|
if (proxyHasParent)
|
|
|
|
proxy->setParent(&parentProxy);
|
|
|
|
QPointer<QWidget> existingSubWidget = new QWidget;
|
|
|
|
proxy->setVisible(false);
|
|
|
|
proxy->setEnabled(false);
|
|
|
|
|
|
|
|
if (widgetExists) {
|
|
|
|
existingSubWidget->setAttribute(Qt::WA_QuitOnClose, true);
|
|
|
|
proxy->setWidget(existingSubWidget);
|
|
|
|
}
|
|
|
|
|
|
|
|
QWidget *widget = new QWidget;
|
2016-04-11 08:56:36 +00:00
|
|
|
#ifndef QT_NO_CURSOR
|
2011-04-27 10:05:43 +00:00
|
|
|
widget->setCursor(Qt::IBeamCursor);
|
|
|
|
#endif
|
|
|
|
widget->setPalette(QPalette(Qt::magenta));
|
|
|
|
widget->setLayoutDirection(Qt::RightToLeft);
|
2016-08-03 13:20:09 +00:00
|
|
|
widget->setStyle(style.data());
|
2011-04-27 10:05:43 +00:00
|
|
|
widget->setFont(QFont("Times"));
|
|
|
|
widget->setVisible(true);
|
|
|
|
QApplication::setActiveWindow(widget);
|
|
|
|
widget->activateWindow();
|
|
|
|
widget->setEnabled(true);
|
|
|
|
widget->resize(325, 241);
|
|
|
|
widget->setMinimumSize(100, 200);
|
|
|
|
widget->setMaximumSize(1000, 2000);
|
|
|
|
widget->setFocusPolicy(Qt::TabFocus);
|
|
|
|
widget->setContentsMargins(10, 29, 19, 81);
|
|
|
|
widget->setFocus(Qt::TabFocusReason);
|
|
|
|
widget->setAcceptDrops(true);
|
|
|
|
QTRY_VERIFY(widget->hasFocus());
|
|
|
|
QVERIFY(widget->isActiveWindow());
|
|
|
|
|
|
|
|
QWidget parentWidget;
|
|
|
|
if (hasParent)
|
|
|
|
widget->setParent(&parentWidget);
|
|
|
|
|
|
|
|
QWidget *subWidget = insertWidget ? widget : 0;
|
|
|
|
bool shouldBeInsertable = !hasParent && subWidget;
|
|
|
|
if (shouldBeInsertable)
|
|
|
|
subWidget->setAttribute(Qt::WA_QuitOnClose, true);
|
|
|
|
|
|
|
|
proxy->setWidget(subWidget);
|
|
|
|
|
|
|
|
if (shouldBeInsertable) {
|
|
|
|
QCOMPARE(proxy->widget(), subWidget);
|
|
|
|
QVERIFY(subWidget->testAttribute(Qt::WA_DontShowOnScreen));
|
|
|
|
QVERIFY(!subWidget->testAttribute(Qt::WA_QuitOnClose));
|
|
|
|
QCOMPARE(proxy->acceptHoverEvents(), true);
|
2016-04-11 08:56:36 +00:00
|
|
|
#ifndef QT_NO_CURSOR
|
2011-04-27 10:05:43 +00:00
|
|
|
QVERIFY(proxy->hasCursor());
|
|
|
|
|
|
|
|
// These should match
|
|
|
|
QCOMPARE(proxy->cursor().shape(), widget->cursor().shape());
|
|
|
|
#endif
|
|
|
|
//###QCOMPARE(proxy->palette(), widget->palette());
|
|
|
|
QCOMPARE(proxy->layoutDirection(), widget->layoutDirection());
|
|
|
|
QCOMPARE(proxy->style(), widget->style());
|
|
|
|
QCOMPARE(proxy->isVisible(), widget->isVisible());
|
|
|
|
QCOMPARE(proxy->isEnabled(), widget->isEnabled());
|
|
|
|
QVERIFY(proxy->flags() & QGraphicsItem::ItemIsFocusable);
|
|
|
|
QCOMPARE(proxy->effectiveSizeHint(Qt::MinimumSize).toSize(),
|
|
|
|
qSmartMinSize(widget));
|
|
|
|
QCOMPARE(proxy->minimumSize().toSize(),
|
|
|
|
qSmartMinSize(widget) );
|
|
|
|
QCOMPARE(proxy->maximumSize().toSize(), QSize(1000, 2000));
|
|
|
|
QCOMPARE(proxy->effectiveSizeHint(Qt::PreferredSize).toSize(),
|
|
|
|
qSmartMinSize(widget));
|
|
|
|
QCOMPARE(proxy->size().toSize(), widget->size());
|
|
|
|
QCOMPARE(proxy->rect().toRect(), widget->rect());
|
|
|
|
QCOMPARE(proxy->focusPolicy(), Qt::WheelFocus);
|
|
|
|
QVERIFY(proxy->acceptDrops());
|
2015-08-21 12:33:56 +00:00
|
|
|
QCOMPARE(proxy->acceptHoverEvents(), true); // to get widget enter events
|
2019-07-31 05:28:28 +00:00
|
|
|
const QMarginsF margins = QMarginsF{widget->contentsMargins()};
|
2011-04-27 10:05:43 +00:00
|
|
|
qreal rleft, rtop, rright, rbottom;
|
|
|
|
proxy->getContentsMargins(&rleft, &rtop, &rright, &rbottom);
|
2019-07-31 05:28:28 +00:00
|
|
|
QCOMPARE(margins.left(), rleft);
|
|
|
|
QCOMPARE(margins.top(), rtop);
|
|
|
|
QCOMPARE(margins.right(), rright);
|
|
|
|
QCOMPARE(margins.bottom(), rbottom);
|
2011-04-27 10:05:43 +00:00
|
|
|
} else {
|
|
|
|
// proxy shouldn't mess with the widget if it can't insert it.
|
2016-09-30 13:16:55 +00:00
|
|
|
QCOMPARE(proxy->widget(), nullptr);
|
2011-04-27 10:05:43 +00:00
|
|
|
QCOMPARE(proxy->acceptHoverEvents(), false);
|
|
|
|
if (subWidget) {
|
|
|
|
QVERIFY(!subWidget->testAttribute(Qt::WA_DontShowOnScreen));
|
|
|
|
QVERIFY(subWidget->testAttribute(Qt::WA_QuitOnClose));
|
|
|
|
// reset
|
|
|
|
subWidget->setAttribute(Qt::WA_QuitOnClose, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (widgetExists) {
|
2016-09-30 13:16:55 +00:00
|
|
|
QCOMPARE(existingSubWidget->parent(), nullptr);
|
2011-04-27 10:05:43 +00:00
|
|
|
QVERIFY(!existingSubWidget->testAttribute(Qt::WA_DontShowOnScreen));
|
|
|
|
QVERIFY(!existingSubWidget->testAttribute(Qt::WA_QuitOnClose));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hasParent)
|
|
|
|
widget->setParent(0);
|
|
|
|
|
|
|
|
delete widget;
|
|
|
|
if (shouldBeInsertable)
|
|
|
|
QVERIFY(!proxy);
|
|
|
|
delete existingSubWidget;
|
|
|
|
if (!shouldBeInsertable) {
|
|
|
|
QVERIFY(proxy);
|
|
|
|
delete proxy;
|
|
|
|
}
|
|
|
|
QVERIFY(!proxy);
|
|
|
|
}
|
|
|
|
|
|
|
|
Q_DECLARE_METATYPE(QEvent::Type)
|
2015-07-28 08:11:52 +00:00
|
|
|
void tst_QGraphicsProxyWidget::testEventFilter_data()
|
2011-04-27 10:05:43 +00:00
|
|
|
{
|
|
|
|
QTest::addColumn<QEvent::Type>("eventType");
|
|
|
|
QTest::addColumn<bool>("fromObject"); // big grin evil
|
|
|
|
QTest::newRow("none") << QEvent::None << false;
|
|
|
|
for (int i = 0; i < 2; ++i) {
|
|
|
|
bool fromObject = (i == 0);
|
2015-10-16 07:38:51 +00:00
|
|
|
const char fromObjectC = fromObject ? '1' : '0';
|
|
|
|
QTest::newRow((QByteArrayLiteral("resize ") + fromObjectC).constData()) << QEvent::Resize << fromObject;
|
|
|
|
QTest::newRow((QByteArrayLiteral("move ") + fromObjectC).constData()) << QEvent::Move << fromObject;
|
|
|
|
QTest::newRow((QByteArrayLiteral("hide ") + fromObjectC).constData()) << QEvent::Hide << fromObject;
|
|
|
|
QTest::newRow((QByteArrayLiteral("show ") + fromObjectC).constData()) << QEvent::Show << fromObject;
|
|
|
|
QTest::newRow((QByteArrayLiteral("enabled ") + fromObjectC).constData()) << QEvent::EnabledChange << fromObject;
|
|
|
|
QTest::newRow((QByteArrayLiteral("focusIn ") + fromObjectC).constData()) << QEvent::FocusIn << fromObject;
|
|
|
|
QTest::newRow((QByteArrayLiteral("focusOut ") + fromObjectC).constData()) << QEvent::FocusOut << fromObject;
|
|
|
|
QTest::newRow((QByteArrayLiteral("keyPress ") + fromObjectC).constData()) << QEvent::KeyPress << fromObject;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected bool eventFilter(QObject* object, QEvent* event)
|
2015-07-28 08:11:52 +00:00
|
|
|
void tst_QGraphicsProxyWidget::testEventFilter()
|
2011-04-27 10:05:43 +00:00
|
|
|
{
|
|
|
|
QFETCH(QEvent::Type, eventType);
|
|
|
|
QFETCH(bool, fromObject);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QEvent windowActivate(QEvent::WindowActivate);
|
|
|
|
qApp->sendEvent(&scene, &windowActivate);
|
|
|
|
|
|
|
|
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
|
|
|
|
scene.addItem(proxy);
|
|
|
|
|
|
|
|
QWidget *widget = new QWidget(0, Qt::FramelessWindowHint);
|
|
|
|
widget->setFocusPolicy(Qt::TabFocus);
|
|
|
|
widget->resize(10, 10);
|
|
|
|
widget->show();
|
|
|
|
proxy->setWidget(widget);
|
|
|
|
proxy->show();
|
|
|
|
|
|
|
|
// mirror whatever is happening to the widget
|
|
|
|
// don't get in a loop
|
|
|
|
switch (eventType) {
|
|
|
|
case QEvent::None: {
|
|
|
|
QEvent event(QEvent::None);
|
|
|
|
proxy->call_eventFilter(widget, &event);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case QEvent::Resize: {
|
|
|
|
QSize newSize = QSize(100, 100);
|
|
|
|
if (fromObject) {
|
|
|
|
widget->resize(newSize);
|
|
|
|
} else {
|
|
|
|
proxy->resize(newSize);
|
|
|
|
}
|
|
|
|
QCOMPARE(proxy->size().toSize(), newSize);
|
|
|
|
QCOMPARE(widget->size(), newSize);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case QEvent::Move: {
|
|
|
|
QPoint newPoint = QPoint(100, 100);
|
|
|
|
if (fromObject) {
|
|
|
|
widget->move(newPoint);
|
|
|
|
} else {
|
|
|
|
proxy->setPos(newPoint);
|
|
|
|
}
|
|
|
|
QCOMPARE(proxy->pos().toPoint(), newPoint);
|
|
|
|
QCOMPARE(widget->pos(), newPoint);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case QEvent::Hide: {
|
|
|
|
// A hide event can only come from a widget
|
|
|
|
if (fromObject) {
|
|
|
|
widget->setFocus(Qt::TabFocusReason);
|
|
|
|
widget->hide();
|
|
|
|
} else {
|
|
|
|
QHideEvent event;
|
|
|
|
proxy->call_eventFilter(widget, &event);
|
|
|
|
}
|
|
|
|
QCOMPARE(proxy->isVisible(), false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case QEvent::Show: {
|
|
|
|
// A show event can either come from a widget or somewhere else
|
|
|
|
widget->hide();
|
|
|
|
if (fromObject) {
|
|
|
|
widget->show();
|
|
|
|
} else {
|
|
|
|
QShowEvent event;
|
|
|
|
proxy->call_eventFilter(widget, &event);
|
|
|
|
}
|
|
|
|
QCOMPARE(proxy->isVisible(), true);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case QEvent::EnabledChange: {
|
|
|
|
widget->setEnabled(false);
|
|
|
|
proxy->setEnabled(false);
|
|
|
|
if (fromObject) {
|
|
|
|
widget->setEnabled(true);
|
|
|
|
QCOMPARE(proxy->isEnabled(), true);
|
|
|
|
widget->setEnabled(false);
|
|
|
|
QCOMPARE(proxy->isEnabled(), false);
|
|
|
|
} else {
|
|
|
|
QEvent event(QEvent::EnabledChange);
|
|
|
|
proxy->call_eventFilter(widget, &event);
|
|
|
|
// match the widget not the event
|
|
|
|
QCOMPARE(proxy->isEnabled(), false);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case QEvent::FocusIn: {
|
|
|
|
if (fromObject) {
|
|
|
|
widget->setFocus(Qt::TabFocusReason);
|
|
|
|
QVERIFY(proxy->hasFocus());
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case QEvent::FocusOut: {
|
|
|
|
widget->setFocus(Qt::TabFocusReason);
|
|
|
|
QVERIFY(proxy->hasFocus());
|
|
|
|
QVERIFY(widget->hasFocus());
|
|
|
|
if (fromObject) {
|
|
|
|
widget->clearFocus();
|
|
|
|
QVERIFY(!proxy->hasFocus());
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case QEvent::KeyPress: {
|
|
|
|
if (fromObject) {
|
|
|
|
QTest::keyPress(widget, Qt::Key_A, Qt::NoModifier);
|
|
|
|
} else {
|
|
|
|
QKeyEvent event(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier);
|
|
|
|
proxy->call_eventFilter(widget, &event);
|
|
|
|
}
|
|
|
|
QCOMPARE(proxy->keyPress, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::focusInEvent_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<bool>("widgetHasFocus");
|
|
|
|
QTest::addColumn<bool>("widgetCanHaveFocus");
|
|
|
|
QTest::newRow("no focus, can't get") << false << false;
|
|
|
|
QTest::newRow("no focus, can get") << false << true;
|
|
|
|
QTest::newRow("has focus, can't get") << true << false;
|
|
|
|
QTest::newRow("has focus, can get") << true << true;
|
|
|
|
// ### add test for widget having a focusNextPrevChild
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected void focusInEvent(QFocusEvent* event)
|
|
|
|
void tst_QGraphicsProxyWidget::focusInEvent()
|
|
|
|
{
|
2012-06-18 14:26:30 +00:00
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
// Fails on Windows due QPlatformWindow::isActive() check required for embedded native widgets.
|
|
|
|
// Since the test is apparently broken anyway, just skip it.
|
|
|
|
QSKIP("Broken test.");
|
|
|
|
#endif
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
// ### This test is just plain old broken
|
|
|
|
QFETCH(bool, widgetHasFocus);
|
|
|
|
QFETCH(bool, widgetCanHaveFocus);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QEvent windowActivate(QEvent::WindowActivate);
|
|
|
|
qApp->sendEvent(&scene, &windowActivate);
|
|
|
|
|
|
|
|
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
|
|
|
|
proxy->setEnabled(true);
|
|
|
|
scene.addItem(proxy);
|
|
|
|
|
|
|
|
QWidget *widget = new QWidget;
|
|
|
|
widget->resize(100, 100);
|
|
|
|
if (widgetCanHaveFocus)
|
|
|
|
widget->setFocusPolicy(Qt::WheelFocus);
|
|
|
|
widget->show();
|
|
|
|
|
|
|
|
if (widgetHasFocus)
|
|
|
|
widget->setFocus(Qt::TabFocusReason);
|
|
|
|
|
|
|
|
proxy->setWidget(widget);
|
|
|
|
proxy->setFlag(QGraphicsItem::ItemIsFocusable, true); // <- shouldn't need to do this
|
|
|
|
|
|
|
|
// ### This test is just plain old broken - sending a focus in event
|
|
|
|
// does not cause items to gain input focus. The widget has focus
|
|
|
|
// because the proxy has focus, not because it got this event.
|
|
|
|
|
|
|
|
QFocusEvent event(QEvent::FocusIn, Qt::TabFocusReason);
|
|
|
|
event.ignore();
|
|
|
|
proxy->call_focusInEvent(&event);
|
|
|
|
QTRY_COMPARE(widget->hasFocus(), widgetCanHaveFocus);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::focusInEventNoWidget()
|
|
|
|
{
|
|
|
|
QGraphicsView view;
|
|
|
|
QGraphicsScene scene(&view);
|
|
|
|
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
|
|
|
|
proxy->setEnabled(true);
|
|
|
|
scene.addItem(proxy);
|
|
|
|
view.show();
|
|
|
|
|
|
|
|
proxy->setFlag(QGraphicsItem::ItemIsFocusable, true); // <- shouldn't need to do this
|
|
|
|
QFocusEvent event(QEvent::FocusIn, Qt::TabFocusReason);
|
|
|
|
event.ignore();
|
|
|
|
//should not crash
|
|
|
|
proxy->call_focusInEvent(&event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::focusNextPrevChild_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<bool>("hasWidget");
|
|
|
|
QTest::addColumn<bool>("hasScene");
|
|
|
|
QTest::addColumn<bool>("next");
|
|
|
|
QTest::addColumn<bool>("focusNextPrevChild");
|
|
|
|
|
|
|
|
for (int i = 0; i < 2; ++i) {
|
|
|
|
for (int j = 0; j < 2; ++j) {
|
|
|
|
for (int k = 0; k < 2; ++k) {
|
|
|
|
bool next = (i == 0);
|
|
|
|
bool hasWidget = (j == 0);
|
|
|
|
bool hasScene = (k == 0);
|
|
|
|
bool result = hasScene && hasWidget;
|
2015-10-16 07:38:51 +00:00
|
|
|
QByteArray name = QByteArrayLiteral("Forward: ") + (next ? '1' : '0')
|
|
|
|
+ ", hasWidget: " + (hasWidget ? '1' : '0') + ", hasScene: "
|
|
|
|
+ (hasScene ? '1' : '0') + ", result: " + (result ? '1' : '0');
|
|
|
|
QTest::newRow(name.constData()) << hasWidget << hasScene << next << result;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected bool focusNextPrevChild(bool next)
|
|
|
|
void tst_QGraphicsProxyWidget::focusNextPrevChild()
|
|
|
|
{
|
|
|
|
QFETCH(bool, next);
|
|
|
|
QFETCH(bool, focusNextPrevChild);
|
|
|
|
QFETCH(bool, hasWidget);
|
|
|
|
QFETCH(bool, hasScene);
|
|
|
|
|
|
|
|
// If a widget has its own focusNextPrevChild we need to respect it
|
|
|
|
// otherwise respect the scene
|
|
|
|
// Respect the widget over the scene!
|
|
|
|
|
|
|
|
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
|
|
|
|
|
|
|
|
QLabel *widget = new QLabel;
|
|
|
|
// I can't believe designer adds this much junk!
|
|
|
|
widget->setText("<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\"> p, li { white-space: pre-wrap; } </style></head><body style=\" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;\"> <p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><a href=\"http://www.slashdot.org\"><span style=\" text-decoration: underline; color:#0000ff;\">old</span></a> foo <a href=\"http://www.reddit.org\"><span style=\" text-decoration: underline; color:#0000ff;\">new</span></a></p></body></html>");
|
|
|
|
widget->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
|
|
|
|
|
|
|
if (hasWidget)
|
|
|
|
proxy->setWidget(widget);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
view.show();
|
|
|
|
QApplication::setActiveWindow(&view);
|
2012-07-18 11:12:59 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
if (hasScene) {
|
|
|
|
scene.addItem(proxy);
|
|
|
|
proxy->show();
|
|
|
|
|
|
|
|
// widget should take precedence over scene so make scene.focusNextPrevChild return false
|
|
|
|
// so we know that a true can only come from the widget
|
|
|
|
if (!(hasWidget && hasScene)) {
|
|
|
|
QGraphicsTextItem *item = new QGraphicsTextItem("Foo");
|
|
|
|
item->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
|
|
|
scene.addItem(item);
|
|
|
|
item->setPos(50, 40);
|
|
|
|
}
|
|
|
|
scene.setFocusItem(proxy);
|
|
|
|
QVERIFY(proxy->hasFocus());
|
|
|
|
}
|
|
|
|
|
|
|
|
QCOMPARE(proxy->call_focusNextPrevChild(next), focusNextPrevChild);
|
|
|
|
|
|
|
|
if (!hasScene)
|
|
|
|
delete proxy;
|
2013-08-20 13:50:18 +00:00
|
|
|
if (!hasWidget)
|
|
|
|
delete widget;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::focusOutEvent_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<bool>("hasWidget");
|
|
|
|
QTest::addColumn<bool>("call");
|
|
|
|
QTest::newRow("no widget, focus to other widget") << false << false;
|
|
|
|
QTest::newRow("no widget, focusOutCalled") << false << true;
|
|
|
|
QTest::newRow("widget, focus to other widget") << true << false;
|
|
|
|
QTest::newRow("widget, focusOutCalled") << true << true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected void focusOutEvent(QFocusEvent* event)
|
|
|
|
void tst_QGraphicsProxyWidget::focusOutEvent()
|
|
|
|
{
|
|
|
|
QFETCH(bool, hasWidget);
|
|
|
|
QFETCH(bool, call);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
|
|
|
|
scene.addItem(proxy);
|
|
|
|
view.show();
|
|
|
|
QApplication::setActiveWindow(&view);
|
|
|
|
view.activateWindow();
|
|
|
|
view.setFocus();
|
2017-09-08 16:42:25 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
QTRY_VERIFY(view.isVisible());
|
|
|
|
QTRY_COMPARE(QApplication::activeWindow(), (QWidget*)&view);
|
|
|
|
|
2014-07-25 08:49:38 +00:00
|
|
|
QScopedPointer<QWidget> widgetGuard(new QWidget);
|
|
|
|
QWidget *widget = widgetGuard.data();
|
2011-04-27 10:05:43 +00:00
|
|
|
widget->setFocusPolicy(Qt::WheelFocus);
|
|
|
|
if (hasWidget)
|
2014-07-25 08:49:38 +00:00
|
|
|
proxy->setWidget(widgetGuard.take());
|
2011-04-27 10:05:43 +00:00
|
|
|
proxy->show();
|
|
|
|
proxy->setFocus();
|
|
|
|
QVERIFY(proxy->hasFocus());
|
|
|
|
QEXPECT_FAIL("widget, focus to other widget", "Widget should have focus but doesn't", Continue);
|
|
|
|
QEXPECT_FAIL("widget, focusOutCalled", "Widget should have focus but doesn't", Continue);
|
|
|
|
QCOMPARE(widget->hasFocus(), hasWidget);
|
|
|
|
|
|
|
|
if (!call) {
|
|
|
|
QWidget *other = new QLineEdit(&view);
|
|
|
|
other->show();
|
|
|
|
QApplication::processEvents();
|
|
|
|
QTRY_VERIFY(other->isVisible());
|
|
|
|
other->setFocus();
|
|
|
|
QTRY_VERIFY(other->hasFocus());
|
|
|
|
qApp->processEvents();
|
|
|
|
QTRY_COMPARE(proxy->hasFocus(), false);
|
|
|
|
QVERIFY(proxy->focusOut);
|
|
|
|
QCOMPARE(widget->hasFocus(), false);
|
|
|
|
} else {
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
### Test doesn't make sense
|
|
|
|
QFocusEvent focusEvent(QEvent::FocusOut);
|
|
|
|
proxy->call_focusOutEvent(&focusEvent);
|
|
|
|
QCOMPARE(focusEvent.isAccepted(), hasWidget);
|
|
|
|
qApp->processEvents();
|
|
|
|
QCOMPARE(proxy->paintCount, hasWidget ? 1 : 0);
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
### Test doesn't make sense
|
|
|
|
proxy->setFlag(QGraphicsItem::ItemIsFocusable, false);
|
|
|
|
QFocusEvent focusEvent(QEvent::FocusOut);
|
|
|
|
proxy->call_focusOutEvent(&focusEvent);
|
|
|
|
QCOMPARE(focusEvent.isAccepted(), hasWidget);
|
|
|
|
qApp->processEvents();
|
|
|
|
QCOMPARE(proxy->paintCount, 0);
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-24 23:48:48 +00:00
|
|
|
void tst_QGraphicsProxyWidget::focusProxy_QTBUG_51856()
|
|
|
|
{
|
|
|
|
// QSpinBox has an internal QLineEdit; this QLineEdit has the spinbox
|
|
|
|
// as its focus proxy.
|
|
|
|
struct FocusedSpinBox : QSpinBox
|
|
|
|
{
|
|
|
|
int focusCount = 0;
|
|
|
|
|
|
|
|
bool event(QEvent *event) override
|
|
|
|
{
|
|
|
|
switch (event->type()) {
|
|
|
|
case QEvent::FocusIn:
|
|
|
|
++focusCount;
|
|
|
|
break;
|
|
|
|
case QEvent::FocusOut:
|
|
|
|
--focusCount;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return QSpinBox::event(event);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
|
|
|
|
scene.addItem(proxy);
|
|
|
|
view.show();
|
|
|
|
view.raise();
|
|
|
|
view.activateWindow();
|
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
|
|
|
|
|
|
|
FocusedSpinBox *spinBox = new FocusedSpinBox;
|
|
|
|
|
|
|
|
proxy->setWidget(spinBox);
|
|
|
|
proxy->show();
|
|
|
|
proxy->setFocus();
|
|
|
|
QVERIFY(proxy->hasFocus());
|
|
|
|
QEXPECT_FAIL("", "Widget should have focus but doesn't", Continue);
|
|
|
|
QVERIFY(spinBox->hasFocus());
|
|
|
|
QEXPECT_FAIL("", "Widget should have focus but doesn't", Continue);
|
|
|
|
QCOMPARE(spinBox->focusCount, 1);
|
|
|
|
|
|
|
|
enum { Count = 10 };
|
|
|
|
|
|
|
|
for (int i = 0; i < Count; ++i) {
|
|
|
|
for (int clickCount = 0; clickCount < Count; ++clickCount) {
|
|
|
|
auto proxyCenter = proxy->boundingRect().center();
|
|
|
|
auto proxyCenterInScene = proxy->mapToScene(proxyCenter);
|
|
|
|
auto proxyCenterInView = view.mapFromScene(proxyCenterInScene);
|
|
|
|
|
|
|
|
QTest::mouseClick(view.viewport(), Qt::LeftButton, {}, proxyCenterInView);
|
|
|
|
QTRY_COMPARE(spinBox->focusCount, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
QLineEdit *edit = new QLineEdit(&view);
|
|
|
|
edit->show();
|
|
|
|
QTRY_VERIFY(edit->isVisible());
|
|
|
|
edit->setFocus();
|
|
|
|
QTRY_VERIFY(edit->hasFocus());
|
|
|
|
QTRY_VERIFY(!proxy->hasFocus());
|
|
|
|
QTRY_COMPARE(proxy->focusOut, i + 1);
|
|
|
|
QTRY_VERIFY(!spinBox->hasFocus());
|
|
|
|
QTRY_COMPARE(spinBox->focusCount, 0);
|
|
|
|
delete edit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
class EventLogger : public QWidget
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
EventLogger() : QWidget(), enterCount(0), leaveCount(0), moveCount(0),
|
|
|
|
hoverEnter(0), hoverLeave(0), hoverMove(0)
|
|
|
|
{
|
|
|
|
installEventFilter(this);
|
|
|
|
}
|
|
|
|
|
2020-09-02 10:04:07 +00:00
|
|
|
void enterEvent(QEnterEvent *event)
|
2011-04-27 10:05:43 +00:00
|
|
|
{
|
|
|
|
enterCount++;
|
|
|
|
QWidget::enterEvent(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void leaveEvent(QEvent *event )
|
|
|
|
{
|
|
|
|
leaveCount++;
|
|
|
|
QWidget::leaveEvent(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void mouseMoveEvent(QMouseEvent *event)
|
|
|
|
{
|
|
|
|
event->setAccepted(true);
|
|
|
|
moveCount++;
|
|
|
|
QWidget::mouseMoveEvent(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
int enterCount;
|
|
|
|
int leaveCount;
|
|
|
|
int moveCount;
|
|
|
|
|
|
|
|
int hoverEnter;
|
|
|
|
int hoverLeave;
|
|
|
|
int hoverMove;
|
|
|
|
protected:
|
|
|
|
bool eventFilter(QObject *object, QEvent *event)
|
|
|
|
{
|
|
|
|
switch (event->type()) {
|
|
|
|
case QEvent::HoverEnter:
|
|
|
|
hoverEnter++;
|
|
|
|
break;
|
|
|
|
case QEvent::HoverLeave:
|
|
|
|
hoverLeave++;
|
|
|
|
break;
|
|
|
|
case QEvent::HoverMove:
|
|
|
|
hoverMove++;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return QWidget::eventFilter(object, event);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::hoverEnterLeaveEvent_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<bool>("hasWidget");
|
|
|
|
QTest::addColumn<bool>("hoverEnabled");
|
|
|
|
QTest::newRow("widget, no hover") << true << false;
|
|
|
|
QTest::newRow("no widget, no hover") << false << false;
|
|
|
|
QTest::newRow("widget, hover") << true << true;
|
|
|
|
QTest::newRow("no widget, hover") << false << true;
|
|
|
|
}
|
|
|
|
|
2011-11-15 01:36:18 +00:00
|
|
|
// protected void hoverEnterEvent(QGraphicsSceneHoverEvent* event)
|
2011-04-27 10:05:43 +00:00
|
|
|
void tst_QGraphicsProxyWidget::hoverEnterLeaveEvent()
|
|
|
|
{
|
|
|
|
QFETCH(bool, hasWidget);
|
|
|
|
QFETCH(bool, hoverEnabled);
|
|
|
|
|
|
|
|
// proxy should translate this into events that the widget would expect
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
view.show();
|
2012-07-18 11:12:59 +00:00
|
|
|
QApplication::setActiveWindow(&view);
|
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
|
2014-07-25 08:49:38 +00:00
|
|
|
QScopedPointer<EventLogger> widgetGuard(new EventLogger);
|
|
|
|
EventLogger *widget = widgetGuard.data();
|
2011-04-27 10:05:43 +00:00
|
|
|
widget->resize(50, 50);
|
|
|
|
widget->setAttribute(Qt::WA_Hover, hoverEnabled);
|
|
|
|
widget->setMouseTracking(true);
|
|
|
|
view.resize(100, 100);
|
|
|
|
if (hasWidget)
|
2014-07-25 08:49:38 +00:00
|
|
|
proxy->setWidget(widgetGuard.take());
|
2011-04-27 10:05:43 +00:00
|
|
|
proxy->setPos(50, 0);
|
2017-10-31 16:07:07 +00:00
|
|
|
QSignalSpy sceneChangedSpy(&scene, &QGraphicsScene::changed);
|
2011-04-27 10:05:43 +00:00
|
|
|
scene.addItem(proxy);
|
2017-10-31 16:07:07 +00:00
|
|
|
QTRY_VERIFY(sceneChangedSpy.count() > 0);
|
|
|
|
|
|
|
|
// outside graphics item
|
2011-04-27 10:05:43 +00:00
|
|
|
QTest::mouseMove(&view, QPoint(10, 10));
|
|
|
|
|
2017-10-31 16:07:07 +00:00
|
|
|
QCOMPARE(widget->testAttribute(Qt::WA_UnderMouse), false);
|
|
|
|
QCOMPARE(widget->enterCount, 0);
|
|
|
|
QCOMPARE(widget->hoverEnter, 0);
|
|
|
|
// over graphics item
|
2011-04-27 10:05:43 +00:00
|
|
|
QTest::mouseMove(&view, QPoint(50, 50));
|
2014-09-09 13:18:54 +00:00
|
|
|
QTRY_COMPARE(widget->testAttribute(Qt::WA_UnderMouse), hasWidget);
|
2011-04-27 10:05:43 +00:00
|
|
|
QCOMPARE(widget->enterCount, hasWidget ? 1 : 0);
|
|
|
|
QCOMPARE(widget->hoverEnter, (hasWidget && hoverEnabled) ? 1 : 0);
|
|
|
|
|
2017-10-31 16:07:07 +00:00
|
|
|
QTRY_COMPARE(widget->leaveCount, 0);
|
|
|
|
QTRY_COMPARE(widget->hoverLeave, 0);
|
|
|
|
// outside graphics item
|
2011-04-27 10:05:43 +00:00
|
|
|
QTest::mouseMove(&view, QPoint(10, 10));
|
2017-10-31 16:07:07 +00:00
|
|
|
QTRY_COMPARE(widget->testAttribute(Qt::WA_UnderMouse), false);
|
2011-04-27 10:05:43 +00:00
|
|
|
QTRY_COMPARE(widget->leaveCount, hasWidget ? 1 : 0);
|
|
|
|
QTRY_COMPARE(widget->hoverLeave, (hasWidget && hoverEnabled) ? 1 : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::hoverMoveEvent_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<bool>("hasWidget");
|
|
|
|
QTest::addColumn<bool>("hoverEnabled");
|
|
|
|
QTest::addColumn<bool>("mouseTracking");
|
|
|
|
QTest::addColumn<bool>("mouseDown");
|
|
|
|
for (int i = 0; i < 2; ++i) {
|
|
|
|
for (int j = 0; j < 2; ++j) {
|
|
|
|
for (int k = 0; k < 2; ++k) {
|
|
|
|
for (int l = 0; l < 2; ++l) {
|
|
|
|
bool hasWidget = (i == 0);
|
|
|
|
bool hoverEnabled = (j == 0);
|
|
|
|
bool mouseTracking = (k == 0);
|
|
|
|
bool mouseDown = (l == 0);
|
2015-10-16 07:38:51 +00:00
|
|
|
QByteArray name = QByteArrayLiteral("hasWidget:") + (hasWidget ? '1' : '0') + ", hover:"
|
|
|
|
+ (hoverEnabled ? '1' : '0') + ", mouseTracking:"
|
|
|
|
+ (mouseTracking ? '1' : '0') + ", mouseDown: " + (mouseDown ? '1' : '0');
|
|
|
|
QTest::newRow(name.constData()) << hasWidget << hoverEnabled << mouseTracking << mouseDown;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected void hoverMoveEvent(QGraphicsSceneHoverEvent* event)
|
|
|
|
void tst_QGraphicsProxyWidget::hoverMoveEvent()
|
|
|
|
{
|
|
|
|
QFETCH(bool, hasWidget);
|
|
|
|
QFETCH(bool, hoverEnabled);
|
|
|
|
QFETCH(bool, mouseTracking);
|
|
|
|
QFETCH(bool, mouseDown);
|
|
|
|
|
2011-10-19 02:53:13 +00:00
|
|
|
QSKIP("Ambiguous test...");
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
// proxy should translate the move events to what the widget would expect
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
view.show();
|
|
|
|
|
|
|
|
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
|
|
|
|
proxy->setFlag(QGraphicsItem::ItemIsFocusable, true); // ### remove me!!!
|
|
|
|
EventLogger *widget = new EventLogger;
|
|
|
|
widget->resize(50, 50);
|
|
|
|
widget->setAttribute(Qt::WA_Hover, hoverEnabled);
|
|
|
|
if (mouseTracking)
|
|
|
|
widget->setMouseTracking(true);
|
|
|
|
view.resize(100, 100);
|
|
|
|
if (hasWidget)
|
|
|
|
proxy->setWidget(widget);
|
|
|
|
proxy->setPos(50, 0);
|
|
|
|
scene.addItem(proxy);
|
|
|
|
|
|
|
|
// in
|
|
|
|
QTest::mouseMove(&view, QPoint(50, 50));
|
|
|
|
QTest::qWait(12);
|
|
|
|
|
|
|
|
if (mouseDown)
|
|
|
|
QTest::mousePress(view.viewport(), Qt::LeftButton);
|
|
|
|
|
|
|
|
// move a little bit
|
|
|
|
QTest::mouseMove(&view, QPoint(60, 60));
|
|
|
|
QTRY_COMPARE(widget->hoverEnter, (hasWidget && hoverEnabled) ? 1 : 0);
|
|
|
|
QCOMPARE(widget->moveCount, (hasWidget && mouseTracking) || (hasWidget && mouseDown) ? 1 : 0);
|
|
|
|
|
|
|
|
if (!hasWidget)
|
|
|
|
delete widget;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::keyPressEvent_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<bool>("hasWidget");
|
|
|
|
QTest::newRow("widget") << true;
|
|
|
|
QTest::newRow("no widget") << false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected void keyPressEvent(QKeyEvent* event)
|
|
|
|
void tst_QGraphicsProxyWidget::keyPressEvent()
|
|
|
|
{
|
|
|
|
QFETCH(bool, hasWidget);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
view.show();
|
|
|
|
view.viewport()->setFocus();
|
|
|
|
QApplication::setActiveWindow(&view);
|
2012-07-30 10:36:02 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
|
|
|
QCOMPARE(QApplication::activeWindow(), (QWidget*)&view);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
|
|
|
|
proxy->setFlag(QGraphicsItem::ItemIsFocusable, true); // ### remove me!!!
|
|
|
|
|
|
|
|
QLineEdit *widget = new QLineEdit;
|
|
|
|
widget->resize(50, 50);
|
|
|
|
view.resize(100, 100);
|
|
|
|
if (hasWidget) {
|
|
|
|
proxy->setWidget(widget);
|
|
|
|
proxy->show();
|
|
|
|
}
|
|
|
|
proxy->setPos(50, 0);
|
|
|
|
scene.addItem(proxy);
|
|
|
|
proxy->setFocus();
|
|
|
|
|
|
|
|
QTest::keyPress(view.viewport(), 'x');
|
|
|
|
|
|
|
|
QTRY_COMPARE(widget->text(), hasWidget ? QString("x") : QString());
|
|
|
|
|
|
|
|
if (!hasWidget)
|
|
|
|
delete widget;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::keyReleaseEvent_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<bool>("hasWidget");
|
|
|
|
QTest::newRow("widget") << true;
|
|
|
|
QTest::newRow("no widget") << false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected void keyReleaseEvent(QKeyEvent* event)
|
|
|
|
void tst_QGraphicsProxyWidget::keyReleaseEvent()
|
|
|
|
{
|
|
|
|
QFETCH(bool, hasWidget);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
view.show();
|
|
|
|
QApplication::setActiveWindow(&view);
|
2012-07-30 10:36:02 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
|
|
|
QCOMPARE(QApplication::activeWindow(), (QWidget*)&view);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
|
|
|
|
proxy->setFlag(QGraphicsItem::ItemIsFocusable, true); // ### remove me!!!
|
|
|
|
QPushButton *widget = new QPushButton;
|
|
|
|
QSignalSpy spy(widget, SIGNAL(clicked()));
|
|
|
|
widget->resize(50, 50);
|
|
|
|
view.resize(100, 100);
|
|
|
|
if (hasWidget) {
|
|
|
|
proxy->setWidget(widget);
|
|
|
|
proxy->show();
|
|
|
|
}
|
|
|
|
proxy->setPos(50, 0);
|
|
|
|
scene.addItem(proxy);
|
|
|
|
proxy->setFocus();
|
|
|
|
|
|
|
|
QTest::keyPress(view.viewport(), Qt::Key_Space);
|
|
|
|
QTRY_COMPARE(spy.count(), 0);
|
|
|
|
QTest::keyRelease(view.viewport(), Qt::Key_Space);
|
|
|
|
QTRY_COMPARE(spy.count(), (hasWidget) ? 1 : 0);
|
|
|
|
|
|
|
|
if (!hasWidget)
|
|
|
|
delete widget;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::mouseDoubleClickEvent_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<bool>("hasWidget");
|
|
|
|
QTest::newRow("widget") << true;
|
|
|
|
QTest::newRow("no widget") << false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
|
|
|
|
void tst_QGraphicsProxyWidget::mouseDoubleClickEvent()
|
|
|
|
{
|
|
|
|
QFETCH(bool, hasWidget);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
view.show();
|
|
|
|
|
|
|
|
QApplication::setActiveWindow(&view);
|
2012-07-30 10:36:02 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
|
|
|
QCOMPARE(QApplication::activeWindow(), (QWidget*)&view);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
|
|
|
|
proxy->setFlag(QGraphicsItem::ItemIsFocusable, true); // ### remove me!!!
|
|
|
|
QLineEdit *widget = new QLineEdit;
|
|
|
|
widget->setText("foo");
|
|
|
|
widget->resize(50, 50);
|
|
|
|
view.resize(100, 100);
|
2017-10-31 16:07:07 +00:00
|
|
|
if (hasWidget)
|
2011-04-27 10:05:43 +00:00
|
|
|
proxy->setWidget(widget);
|
|
|
|
proxy->setPos(50, 0);
|
2017-10-31 16:07:07 +00:00
|
|
|
QSignalSpy sceneChangedSpy(&scene, &QGraphicsScene::changed);
|
2011-04-27 10:05:43 +00:00
|
|
|
scene.addItem(proxy);
|
|
|
|
proxy->setFocus();
|
|
|
|
|
2017-10-31 16:07:07 +00:00
|
|
|
// wait for scene to be updated before doing any coordinate mappings on it
|
|
|
|
QTRY_VERIFY(sceneChangedSpy.count() > 0);
|
|
|
|
|
|
|
|
QPoint pointInLineEdit = view.mapFromScene(proxy->mapToScene(15, proxy->boundingRect().center().y()));
|
|
|
|
QTest::mousePress(view.viewport(), Qt::LeftButton, 0, pointInLineEdit);
|
|
|
|
QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, pointInLineEdit);
|
|
|
|
QTest::mouseDClick(view.viewport(), Qt::LeftButton, 0, pointInLineEdit);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QTRY_COMPARE(widget->selectedText(), hasWidget ? QString("foo") : QString());
|
|
|
|
|
|
|
|
if (!hasWidget)
|
|
|
|
delete widget;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::mousePressReleaseEvent_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<bool>("hasWidget");
|
|
|
|
QTest::newRow("widget") << true;
|
|
|
|
QTest::newRow("no widget") << false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected void mousePressEvent(QGraphicsSceneMouseEvent* event)
|
|
|
|
void tst_QGraphicsProxyWidget::mousePressReleaseEvent()
|
|
|
|
{
|
|
|
|
QFETCH(bool, hasWidget);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
2015-05-22 11:18:36 +00:00
|
|
|
view.resize(500, 500);
|
2011-04-27 10:05:43 +00:00
|
|
|
view.show();
|
2012-07-30 10:36:02 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
|
|
|
|
proxy->setFlag(QGraphicsItem::ItemIsFocusable, true); // ### remove me!!!
|
|
|
|
QPushButton *widget = new QPushButton;
|
|
|
|
QSignalSpy spy(widget, SIGNAL(clicked()));
|
|
|
|
widget->resize(50, 50);
|
2017-10-31 16:07:07 +00:00
|
|
|
if (hasWidget)
|
2011-04-27 10:05:43 +00:00
|
|
|
proxy->setWidget(widget);
|
|
|
|
proxy->setPos(50, 0);
|
2017-10-31 16:07:07 +00:00
|
|
|
QSignalSpy sceneChangedSpy(&scene, &QGraphicsScene::changed);
|
2011-04-27 10:05:43 +00:00
|
|
|
scene.addItem(proxy);
|
|
|
|
proxy->setFocus();
|
|
|
|
|
2017-10-31 16:07:07 +00:00
|
|
|
// wait for scene to be updated before doing any coordinate mappings on it
|
|
|
|
QTRY_VERIFY(sceneChangedSpy.count() > 0);
|
|
|
|
|
|
|
|
QPoint buttonCenter = view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center()));
|
|
|
|
QTest::mousePress(view.viewport(), Qt::LeftButton, 0, buttonCenter);
|
2011-04-27 10:05:43 +00:00
|
|
|
QTRY_COMPARE(spy.count(), 0);
|
2017-10-31 16:07:07 +00:00
|
|
|
QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, buttonCenter);
|
2011-04-27 10:05:43 +00:00
|
|
|
QTRY_COMPARE(spy.count(), (hasWidget) ? 1 : 0);
|
|
|
|
|
|
|
|
if (!hasWidget)
|
|
|
|
delete widget;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::resizeEvent_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<bool>("hasWidget");
|
|
|
|
QTest::newRow("widget") << true;
|
|
|
|
QTest::newRow("no widget") << false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected void resizeEvent(QGraphicsSceneResizeEvent* event)
|
|
|
|
void tst_QGraphicsProxyWidget::resizeEvent()
|
|
|
|
{
|
|
|
|
QFETCH(bool, hasWidget);
|
|
|
|
|
|
|
|
SubQGraphicsProxyWidget proxy;
|
|
|
|
QWidget *widget = new QWidget;
|
|
|
|
if (hasWidget)
|
|
|
|
proxy.setWidget(widget);
|
|
|
|
|
|
|
|
QSize newSize(100, 100);
|
|
|
|
QGraphicsSceneResizeEvent event;
|
|
|
|
event.setOldSize(QSize(10, 10));
|
|
|
|
event.setNewSize(newSize);
|
|
|
|
proxy.call_resizeEvent(&event);
|
|
|
|
if (hasWidget)
|
|
|
|
QCOMPARE(widget->size(), newSize);
|
|
|
|
if (!hasWidget)
|
|
|
|
delete widget;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::paintEvent()
|
|
|
|
{
|
|
|
|
//we test that calling update on a widget inside a QGraphicsView is triggering a repaint
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
view.show();
|
|
|
|
QApplication::setActiveWindow(&view);
|
2012-07-30 10:36:02 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
|
|
|
QVERIFY(view.isActiveWindow());
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
SubQGraphicsProxyWidget proxy;
|
|
|
|
|
|
|
|
QWidget *w = new QWidget;
|
|
|
|
//showing the widget here seems to create a bug in Graphics View
|
|
|
|
//this bug prevents the widget from being updated
|
|
|
|
|
|
|
|
w->show();
|
2012-07-30 10:36:02 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(w));
|
2011-04-27 10:05:43 +00:00
|
|
|
proxy.setWidget(w);
|
2017-10-31 16:07:07 +00:00
|
|
|
QSignalSpy sceneChangedSpy(&scene, &QGraphicsScene::changed);
|
2011-04-27 10:05:43 +00:00
|
|
|
scene.addItem(&proxy);
|
|
|
|
|
2017-10-31 16:07:07 +00:00
|
|
|
QTRY_VERIFY(sceneChangedSpy.count() > 0); // make sure the scene is ready
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2017-10-31 16:07:07 +00:00
|
|
|
proxy.paintCount = 0;
|
2011-04-27 10:05:43 +00:00
|
|
|
w->update();
|
2016-03-29 04:05:30 +00:00
|
|
|
QTRY_VERIFY(proxy.paintCount >= 1); //the widget should have been painted now
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-05-30 20:22:22 +00:00
|
|
|
#if QT_CONFIG(wheelevent)
|
2011-04-27 10:05:43 +00:00
|
|
|
void tst_QGraphicsProxyWidget::wheelEvent()
|
|
|
|
{
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
view.show();
|
2012-07-18 11:12:59 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
WheelWidget *wheelWidget = new WheelWidget();
|
|
|
|
wheelWidget->setFixedSize(400, 400);
|
|
|
|
|
|
|
|
QGraphicsProxyWidget *proxy = scene.addWidget(wheelWidget);
|
|
|
|
proxy->setVisible(true);
|
|
|
|
|
|
|
|
QGraphicsSceneWheelEvent event(QEvent::GraphicsSceneWheel);
|
|
|
|
event.setScenePos(QPoint(50, 50));
|
|
|
|
event.setAccepted(false);
|
|
|
|
wheelWidget->wheelEventCalled = false;
|
|
|
|
|
|
|
|
QApplication::sendEvent(&scene, &event);
|
|
|
|
|
|
|
|
QVERIFY(event.isAccepted());
|
|
|
|
QVERIFY(wheelWidget->wheelEventCalled);
|
|
|
|
}
|
2017-05-30 20:22:22 +00:00
|
|
|
#endif // QT_CONFIG(wheelevent)
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
Q_DECLARE_METATYPE(Qt::SizeHint)
|
|
|
|
void tst_QGraphicsProxyWidget::sizeHint_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<Qt::SizeHint>("which");
|
|
|
|
QTest::addColumn<QSizeF>("constraint");
|
|
|
|
QTest::addColumn<QSizeF>("sizeHint");
|
|
|
|
QTest::addColumn<bool>("hasWidget");
|
|
|
|
|
|
|
|
for (int i = 0; i < 2; ++i) {
|
|
|
|
bool hasWidget = (i == 0);
|
|
|
|
// ### What should these do?
|
|
|
|
QTest::newRow("min") << Qt::MinimumSize << QSizeF() << QSizeF() << hasWidget;
|
|
|
|
QTest::newRow("pre") << Qt::PreferredSize << QSizeF() << QSizeF() << hasWidget;
|
|
|
|
QTest::newRow("max") << Qt::MaximumSize << QSizeF() << QSizeF() << hasWidget;
|
|
|
|
QTest::newRow("mindes") << Qt::MinimumDescent << QSizeF() << QSizeF() << hasWidget;
|
|
|
|
QTest::newRow("nsize") << Qt::NSizeHints << QSizeF() << QSizeF() << hasWidget;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// protected QSizeF sizeHint(Qt::SizeHint which, QSizeF const& constraint = QSizeF()) const
|
|
|
|
void tst_QGraphicsProxyWidget::sizeHint()
|
|
|
|
{
|
|
|
|
QFETCH(Qt::SizeHint, which);
|
|
|
|
QFETCH(QSizeF, constraint);
|
|
|
|
QFETCH(QSizeF, sizeHint);
|
|
|
|
QFETCH(bool, hasWidget);
|
2011-10-19 02:53:13 +00:00
|
|
|
QSKIP("Broken test");
|
2011-04-27 10:05:43 +00:00
|
|
|
SubQGraphicsProxyWidget proxy;
|
|
|
|
QWidget *widget = new QWidget;
|
|
|
|
if (hasWidget)
|
|
|
|
proxy.setWidget(widget);
|
|
|
|
QCOMPARE(proxy.call_sizeHint(which, constraint), sizeHint);
|
|
|
|
if (!hasWidget)
|
|
|
|
delete widget;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::sizePolicy()
|
|
|
|
{
|
|
|
|
for (int p = 0; p < 2; ++p) {
|
2014-09-09 13:18:54 +00:00
|
|
|
bool hasWidget = (p == 0);
|
2011-04-27 10:05:43 +00:00
|
|
|
SubQGraphicsProxyWidget proxy;
|
|
|
|
QWidget *widget = new QWidget;
|
|
|
|
QSizePolicy proxyPol(QSizePolicy::Maximum, QSizePolicy::Expanding);
|
|
|
|
proxy.setSizePolicy(proxyPol);
|
|
|
|
QSizePolicy widgetPol(QSizePolicy::Fixed, QSizePolicy::Minimum);
|
|
|
|
widget->setSizePolicy(widgetPol);
|
|
|
|
|
|
|
|
QCOMPARE(proxy.sizePolicy(), proxyPol);
|
|
|
|
QCOMPARE(widget->sizePolicy(), widgetPol);
|
|
|
|
if (hasWidget) {
|
|
|
|
proxy.setWidget(widget);
|
|
|
|
QCOMPARE(proxy.sizePolicy(), widgetPol);
|
|
|
|
} else {
|
|
|
|
QCOMPARE(proxy.sizePolicy(), proxyPol);
|
|
|
|
}
|
|
|
|
QCOMPARE(widget->sizePolicy(), widgetPol);
|
|
|
|
|
|
|
|
proxy.setSizePolicy(widgetPol);
|
|
|
|
widget->setSizePolicy(proxyPol);
|
|
|
|
if (hasWidget)
|
|
|
|
QCOMPARE(proxy.sizePolicy(), proxyPol);
|
|
|
|
else
|
|
|
|
QCOMPARE(proxy.sizePolicy(), widgetPol);
|
2013-08-20 13:50:18 +00:00
|
|
|
|
|
|
|
if (!hasWidget)
|
|
|
|
delete widget;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::minimumSize()
|
|
|
|
{
|
|
|
|
SubQGraphicsProxyWidget proxy;
|
|
|
|
QWidget *widget = new QWidget;
|
|
|
|
QSize minSize(50, 50);
|
|
|
|
widget->setMinimumSize(minSize);
|
|
|
|
proxy.resize(30, 30);
|
|
|
|
widget->resize(30,30);
|
|
|
|
QCOMPARE(proxy.size(), QSizeF(30, 30));
|
|
|
|
proxy.setWidget(widget);
|
|
|
|
QCOMPARE(proxy.size().toSize(), minSize);
|
|
|
|
QCOMPARE(proxy.minimumSize().toSize(), minSize);
|
|
|
|
widget->setMinimumSize(70, 70);
|
|
|
|
QCOMPARE(proxy.minimumSize(), QSizeF(70, 70));
|
|
|
|
QCOMPARE(proxy.size(), QSizeF(70, 70));
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::maximumSize()
|
|
|
|
{
|
|
|
|
SubQGraphicsProxyWidget proxy;
|
|
|
|
QWidget *widget = new QWidget;
|
|
|
|
QSize maxSize(150, 150);
|
|
|
|
widget->setMaximumSize(maxSize);
|
|
|
|
proxy.resize(200, 200);
|
|
|
|
widget->resize(200,200);
|
|
|
|
QCOMPARE(proxy.size(), QSizeF(200, 200));
|
|
|
|
proxy.setWidget(widget);
|
|
|
|
QCOMPARE(proxy.size().toSize(), maxSize);
|
|
|
|
QCOMPARE(proxy.maximumSize().toSize(), maxSize);
|
|
|
|
widget->setMaximumSize(70, 70);
|
|
|
|
QCOMPARE(proxy.maximumSize(), QSizeF(70, 70));
|
|
|
|
QCOMPARE(proxy.size(), QSizeF(70, 70));
|
|
|
|
}
|
|
|
|
|
|
|
|
class View : public QGraphicsView
|
|
|
|
{
|
|
|
|
public:
|
2020-10-07 11:05:48 +00:00
|
|
|
View(QGraphicsScene *scene, QWidget *parent = nullptr)
|
2014-01-13 14:48:44 +00:00
|
|
|
: QGraphicsView(scene, parent), npaints(0)
|
2011-04-27 10:05:43 +00:00
|
|
|
{ }
|
|
|
|
QRegion paintEventRegion;
|
|
|
|
int npaints;
|
|
|
|
protected:
|
|
|
|
void paintEvent(QPaintEvent *event)
|
|
|
|
{
|
2014-01-13 14:48:44 +00:00
|
|
|
++npaints;
|
|
|
|
paintEventRegion += event->region();
|
|
|
|
QGraphicsView::paintEvent(event);
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class ScrollWidget : public QWidget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
ScrollWidget() : npaints(0)
|
|
|
|
{
|
2014-01-13 14:48:44 +00:00
|
|
|
resize(200, 200);
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
QRegion paintEventRegion;
|
|
|
|
int npaints;
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
void updateScroll()
|
|
|
|
{
|
2014-01-13 14:48:44 +00:00
|
|
|
update(0, 0, 200, 10);
|
|
|
|
scroll(0, 10, QRect(0, 0, 100, 20));
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void paintEvent(QPaintEvent *event)
|
|
|
|
{
|
2014-01-13 14:48:44 +00:00
|
|
|
++npaints;
|
|
|
|
paintEventRegion += event->region();
|
|
|
|
QPainter painter(this);
|
|
|
|
painter.fillRect(event->rect(), Qt::blue);
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-06-22 14:15:32 +00:00
|
|
|
// ### work around missing QList ctor from iterator pair:
|
|
|
|
static QList<QRect> rects(const QRegion ®ion)
|
2017-12-07 08:50:08 +00:00
|
|
|
{
|
2020-06-22 14:15:32 +00:00
|
|
|
QList<QRect> result;
|
2017-12-07 08:50:08 +00:00
|
|
|
for (QRect r : region)
|
|
|
|
result.push_back(r);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
void tst_QGraphicsProxyWidget::scrollUpdate()
|
|
|
|
{
|
|
|
|
ScrollWidget *widget = new ScrollWidget;
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
scene.addWidget(widget);
|
|
|
|
|
|
|
|
View view(&scene);
|
|
|
|
view.show();
|
2012-07-18 11:12:59 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
QTRY_VERIFY(view.npaints >= 1);
|
|
|
|
QTest::qWait(20);
|
|
|
|
widget->paintEventRegion = QRegion();
|
|
|
|
widget->npaints = 0;
|
|
|
|
view.paintEventRegion = QRegion();
|
|
|
|
view.npaints = 0;
|
|
|
|
QTimer::singleShot(0, widget, SLOT(updateScroll()));
|
|
|
|
QTRY_COMPARE(view.npaints, 2);
|
|
|
|
// QRect(0, 0, 200, 12) is the first update, expanded (-2, -2, 2, 2)
|
|
|
|
// QRect(0, 12, 102, 10) is the scroll update, expanded (-2, -2, 2, 2),
|
|
|
|
// intersected with the above update.
|
2017-12-07 08:50:08 +00:00
|
|
|
QCOMPARE(rects(view.paintEventRegion),
|
2020-06-22 14:15:32 +00:00
|
|
|
QList<QRect>() << QRect(0, 0, 200, 12) << QRect(0, 12, 102, 10));
|
2011-04-27 10:05:43 +00:00
|
|
|
QCOMPARE(widget->npaints, 2);
|
2017-12-07 08:50:08 +00:00
|
|
|
QCOMPARE(rects(widget->paintEventRegion),
|
2020-06-22 14:15:32 +00:00
|
|
|
QList<QRect>() << QRect(0, 0, 200, 12) << QRect(0, 12, 102, 10));
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::setWidget_simple()
|
|
|
|
{
|
|
|
|
QGraphicsProxyWidget proxy;
|
|
|
|
QLineEdit *lineEdit = new QLineEdit;
|
|
|
|
proxy.setWidget(lineEdit);
|
|
|
|
|
|
|
|
QVERIFY(lineEdit->testAttribute(Qt::WA_DontShowOnScreen));
|
|
|
|
// Size hints
|
|
|
|
// ### size hints are tested in a different test
|
|
|
|
// QCOMPARE(proxy.effectiveSizeHint(Qt::MinimumSize).toSize(), lineEdit->minimumSizeHint());
|
|
|
|
// QCOMPARE(proxy.effectiveSizeHint(Qt::MaximumSize).toSize(), lineEdit->maximumSize());
|
|
|
|
// QCOMPARE(proxy.effectiveSizeHint(Qt::PreferredSize).toSize(), lineEdit->sizeHint());
|
|
|
|
QCOMPARE(proxy.size().toSize(), lineEdit->minimumSizeHint().expandedTo(lineEdit->size()));
|
|
|
|
QRect rect = lineEdit->rect();
|
|
|
|
rect.setSize(rect.size().expandedTo(lineEdit->minimumSizeHint()));
|
|
|
|
QCOMPARE(proxy.rect().toRect(), rect);
|
|
|
|
|
|
|
|
// Properties
|
|
|
|
// QCOMPARE(proxy.focusPolicy(), lineEdit->focusPolicy());
|
|
|
|
// QCOMPARE(proxy.palette(), lineEdit->palette());
|
2016-04-11 08:56:36 +00:00
|
|
|
#ifndef QT_NO_CURSOR
|
2011-04-27 10:05:43 +00:00
|
|
|
QCOMPARE(proxy.cursor().shape(), lineEdit->cursor().shape());
|
|
|
|
#endif
|
|
|
|
QCOMPARE(proxy.layoutDirection(), lineEdit->layoutDirection());
|
|
|
|
QCOMPARE(proxy.style(), lineEdit->style());
|
|
|
|
QCOMPARE(proxy.font(), lineEdit->font());
|
|
|
|
QCOMPARE(proxy.isEnabled(), lineEdit->isEnabled());
|
|
|
|
QCOMPARE(proxy.isVisible(), lineEdit->isVisible());
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::setWidget_ownership()
|
|
|
|
{
|
|
|
|
QPointer<QLineEdit> lineEdit = new QLineEdit;
|
|
|
|
QPointer<QLineEdit> lineEdit2 = new QLineEdit;
|
|
|
|
QVERIFY(lineEdit);
|
|
|
|
{
|
|
|
|
// Create a proxy and transfer ownership to it
|
|
|
|
QGraphicsProxyWidget proxy;
|
|
|
|
proxy.setWidget(lineEdit);
|
|
|
|
QCOMPARE(proxy.widget(), (QWidget *)lineEdit);
|
|
|
|
|
|
|
|
// Remove the widget without destroying it.
|
|
|
|
proxy.setWidget(0);
|
|
|
|
QVERIFY(!proxy.widget());
|
|
|
|
QVERIFY(lineEdit);
|
|
|
|
|
|
|
|
// Assign the widget again and switch to another widget.
|
|
|
|
proxy.setWidget(lineEdit);
|
|
|
|
proxy.setWidget(lineEdit2);
|
|
|
|
QCOMPARE(proxy.widget(), (QWidget *)lineEdit2);
|
|
|
|
|
|
|
|
// Assign the first widget, and destroy the proxy.
|
|
|
|
proxy.setWidget(lineEdit);
|
|
|
|
}
|
|
|
|
QVERIFY(!lineEdit);
|
|
|
|
QVERIFY(lineEdit2);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QPointer<QGraphicsProxyWidget> proxy = scene.addWidget(lineEdit2);
|
|
|
|
|
|
|
|
delete lineEdit2;
|
|
|
|
QVERIFY(!proxy);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::resize_simple_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<QSizeF>("size");
|
|
|
|
|
|
|
|
QTest::newRow("200, 200") << QSizeF(200, 200);
|
2016-03-08 14:51:15 +00:00
|
|
|
#if !defined(Q_PROCESSOR_ARM)
|
2011-04-27 10:05:43 +00:00
|
|
|
QTest::newRow("1000, 1000") << QSizeF(1000, 1000);
|
|
|
|
// Since 4.5, 10000x10000 runs out of memory.
|
|
|
|
// QTest::newRow("10000, 10000") << QSizeF(10000, 10000);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::resize_simple()
|
|
|
|
{
|
|
|
|
QFETCH(QSizeF, size);
|
|
|
|
|
|
|
|
QGraphicsProxyWidget proxy;
|
|
|
|
QWidget *widget = new QWidget;
|
|
|
|
widget->setGeometry(0, 0, (int)size.width(), (int)size.height());
|
|
|
|
proxy.setWidget(widget);
|
|
|
|
widget->show();
|
|
|
|
QCOMPARE(widget->pos(), QPoint());
|
|
|
|
|
|
|
|
// The proxy resizes itself, the line edit follows
|
|
|
|
proxy.resize(size);
|
|
|
|
QCOMPARE(proxy.size(), size);
|
|
|
|
QCOMPARE(proxy.size().toSize(), widget->size());
|
|
|
|
|
|
|
|
// The line edit resizes itself, the proxy follows (no loopback/live lock)
|
|
|
|
QSize doubleSize = size.toSize() * 2;
|
|
|
|
widget->resize(doubleSize);
|
|
|
|
QCOMPARE(widget->size(), doubleSize);
|
|
|
|
QCOMPARE(widget->size(), proxy.size().toSize());
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::symmetricMove()
|
|
|
|
{
|
|
|
|
QGraphicsProxyWidget proxy;
|
|
|
|
QLineEdit *lineEdit = new QLineEdit;
|
|
|
|
proxy.setWidget(lineEdit);
|
|
|
|
lineEdit->show();
|
|
|
|
|
|
|
|
proxy.setPos(10, 10);
|
|
|
|
QCOMPARE(proxy.pos(), QPointF(10, 10));
|
|
|
|
QCOMPARE(lineEdit->pos(), QPoint(10, 10));
|
|
|
|
|
|
|
|
lineEdit->move(5, 5);
|
|
|
|
QCOMPARE(proxy.pos(), QPointF(5, 5));
|
|
|
|
QCOMPARE(lineEdit->pos(), QPoint(5, 5));
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::symmetricResize()
|
|
|
|
{
|
|
|
|
QGraphicsProxyWidget proxy;
|
|
|
|
QLineEdit *lineEdit = new QLineEdit;
|
|
|
|
proxy.setWidget(lineEdit);
|
|
|
|
lineEdit->show();
|
|
|
|
|
|
|
|
proxy.resize(256, 256);
|
|
|
|
QCOMPARE(proxy.size(), QSizeF(256, 256));
|
|
|
|
QCOMPARE(lineEdit->size(), QSize(256, 256));
|
|
|
|
|
|
|
|
lineEdit->resize(512, 512);
|
|
|
|
QCOMPARE(proxy.size(), QSizeF(512, 512));
|
|
|
|
QCOMPARE(lineEdit->size(), QSize(512, 512));
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::symmetricVisible()
|
|
|
|
{
|
|
|
|
QGraphicsProxyWidget proxy;
|
|
|
|
QLineEdit *lineEdit = new QLineEdit;
|
|
|
|
proxy.setWidget(lineEdit);
|
|
|
|
lineEdit->show();
|
|
|
|
|
|
|
|
QCOMPARE(proxy.isVisible(), lineEdit->isVisible());
|
|
|
|
|
|
|
|
proxy.hide();
|
|
|
|
QCOMPARE(proxy.isVisible(), lineEdit->isVisible());
|
|
|
|
proxy.show();
|
|
|
|
QCOMPARE(proxy.isVisible(), lineEdit->isVisible());
|
|
|
|
lineEdit->hide();
|
|
|
|
QCOMPARE(proxy.isVisible(), lineEdit->isVisible());
|
|
|
|
lineEdit->show();
|
|
|
|
QCOMPARE(proxy.isVisible(), lineEdit->isVisible());
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::symmetricEnabled()
|
|
|
|
{
|
|
|
|
QGraphicsProxyWidget proxy;
|
|
|
|
QLineEdit *lineEdit = new QLineEdit;
|
|
|
|
proxy.setWidget(lineEdit);
|
|
|
|
lineEdit->show();
|
|
|
|
|
|
|
|
QCOMPARE(proxy.isEnabled(), lineEdit->isEnabled());
|
|
|
|
proxy.setEnabled(false);
|
|
|
|
QCOMPARE(proxy.isEnabled(), lineEdit->isEnabled());
|
|
|
|
proxy.setEnabled(true);
|
|
|
|
QCOMPARE(proxy.isEnabled(), lineEdit->isEnabled());
|
|
|
|
lineEdit->setEnabled(false);
|
|
|
|
QCOMPARE(proxy.isEnabled(), lineEdit->isEnabled());
|
|
|
|
lineEdit->setEnabled(true);
|
|
|
|
QCOMPARE(proxy.isEnabled(), lineEdit->isEnabled());
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::tabFocus_simpleWidget()
|
|
|
|
{
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QLineEdit *edit = new QLineEdit;
|
|
|
|
QGraphicsProxyWidget *editProxy = scene.addWidget(edit);
|
|
|
|
editProxy->show();
|
|
|
|
|
|
|
|
QDial *leftDial = new QDial;
|
|
|
|
QDial *rightDial = new QDial;
|
|
|
|
QGraphicsView *view = new QGraphicsView(&scene);
|
|
|
|
|
|
|
|
QWidget window;
|
|
|
|
QHBoxLayout *layout = new QHBoxLayout;
|
|
|
|
layout->addWidget(leftDial);
|
|
|
|
layout->addWidget(view);
|
|
|
|
layout->addWidget(rightDial);
|
|
|
|
window.setLayout(layout);
|
|
|
|
|
|
|
|
window.show();
|
|
|
|
QApplication::setActiveWindow(&window);
|
|
|
|
window.activateWindow();
|
2012-07-30 10:36:02 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&window));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
leftDial->setFocus();
|
|
|
|
QApplication::processEvents();
|
|
|
|
QTRY_VERIFY(leftDial->hasFocus());
|
|
|
|
|
|
|
|
EventSpy eventSpy(edit);
|
|
|
|
|
|
|
|
// Tab into line edit
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QTRY_VERIFY(!leftDial->hasFocus());
|
|
|
|
QTRY_VERIFY(view->hasFocus());
|
|
|
|
QVERIFY(view->viewport()->hasFocus());
|
|
|
|
QVERIFY(scene.hasFocus());
|
|
|
|
QVERIFY(editProxy->hasFocus());
|
|
|
|
QVERIFY(edit->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 0);
|
|
|
|
|
|
|
|
// Tab into right dial
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QTRY_VERIFY(!view->hasFocus());
|
|
|
|
QVERIFY(!view->viewport()->hasFocus());
|
|
|
|
QVERIFY(!scene.hasFocus());
|
|
|
|
QVERIFY(!editProxy->hasFocus());
|
|
|
|
QVERIFY(!edit->hasFocus());
|
|
|
|
QTRY_VERIFY(rightDial->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1);
|
|
|
|
|
|
|
|
// Backtab into line edit
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QTRY_VERIFY(view->hasFocus());
|
|
|
|
QVERIFY(view->viewport()->hasFocus());
|
|
|
|
QTRY_VERIFY(scene.hasFocus());
|
|
|
|
QVERIFY(editProxy->hasFocus());
|
|
|
|
QVERIFY(edit->hasFocus());
|
|
|
|
QVERIFY(!rightDial->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 2);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1);
|
|
|
|
|
|
|
|
// Backtab into left dial
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QTRY_VERIFY(!view->hasFocus());
|
|
|
|
QVERIFY(!view->viewport()->hasFocus());
|
|
|
|
QVERIFY(!scene.hasFocus());
|
|
|
|
QVERIFY(!editProxy->hasFocus());
|
|
|
|
QVERIFY(!edit->hasFocus());
|
|
|
|
QTRY_VERIFY(leftDial->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 2);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 2);
|
|
|
|
|
|
|
|
delete view;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::tabFocus_simpleTwoWidgets()
|
|
|
|
{
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QLineEdit *edit = new QLineEdit;
|
|
|
|
QLineEdit *edit2 = new QLineEdit;
|
|
|
|
QGraphicsProxyWidget *editProxy = scene.addWidget(edit);
|
|
|
|
editProxy->show();
|
|
|
|
QGraphicsProxyWidget *editProxy2 = scene.addWidget(edit2);
|
|
|
|
editProxy2->show();
|
|
|
|
editProxy2->setPos(0, editProxy->rect().height() * 1.1);
|
|
|
|
|
|
|
|
QDial *leftDial = new QDial;
|
|
|
|
QDial *rightDial = new QDial;
|
|
|
|
QGraphicsView *view = new QGraphicsView(&scene);
|
|
|
|
|
|
|
|
QWidget window;
|
|
|
|
QHBoxLayout *layout = new QHBoxLayout;
|
|
|
|
layout->addWidget(leftDial);
|
|
|
|
layout->addWidget(view);
|
|
|
|
layout->addWidget(rightDial);
|
|
|
|
window.setLayout(layout);
|
|
|
|
|
|
|
|
window.show();
|
|
|
|
QApplication::setActiveWindow(&window);
|
|
|
|
window.activateWindow();
|
2012-07-30 10:36:02 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&window));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
leftDial->setFocus();
|
|
|
|
QApplication::processEvents();
|
|
|
|
QTRY_VERIFY(leftDial->hasFocus());
|
|
|
|
|
|
|
|
EventSpy eventSpy(edit);
|
|
|
|
EventSpy eventSpy2(edit2);
|
|
|
|
|
|
|
|
// Tab into line edit
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!leftDial->hasFocus());
|
|
|
|
QVERIFY(view->hasFocus());
|
|
|
|
QVERIFY(view->viewport()->hasFocus());
|
|
|
|
QVERIFY(scene.hasFocus());
|
|
|
|
QVERIFY(editProxy->hasFocus());
|
|
|
|
QVERIFY(edit->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 0);
|
|
|
|
|
|
|
|
// Tab into second line edit
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(view->hasFocus());
|
|
|
|
QVERIFY(view->viewport()->hasFocus());
|
|
|
|
QVERIFY(scene.hasFocus());
|
|
|
|
QVERIFY(!editProxy->hasFocus());
|
|
|
|
QVERIFY(!edit->hasFocus());
|
|
|
|
QVERIFY(editProxy2->hasFocus());
|
|
|
|
QVERIFY(edit2->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1);
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 0);
|
|
|
|
|
|
|
|
// Tab into right dial
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!view->hasFocus());
|
|
|
|
QVERIFY(!view->viewport()->hasFocus());
|
|
|
|
QVERIFY(!scene.hasFocus());
|
|
|
|
QVERIFY(!editProxy->hasFocus());
|
|
|
|
QVERIFY(!edit->hasFocus());
|
|
|
|
QVERIFY(!editProxy2->hasFocus());
|
|
|
|
QVERIFY(!edit2->hasFocus());
|
|
|
|
QVERIFY(rightDial->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1);
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 1);
|
|
|
|
|
|
|
|
// Backtab into line edit 2
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(view->hasFocus());
|
|
|
|
QVERIFY(view->viewport()->hasFocus());
|
|
|
|
QVERIFY(scene.hasFocus());
|
|
|
|
QVERIFY(!editProxy->hasFocus());
|
|
|
|
QVERIFY(!edit->hasFocus());
|
|
|
|
QVERIFY(editProxy2->hasFocus());
|
|
|
|
QVERIFY(edit2->hasFocus());
|
|
|
|
QVERIFY(!rightDial->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1);
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusIn], 2);
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 1);
|
|
|
|
|
|
|
|
// Backtab into line edit 1
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(view->hasFocus());
|
|
|
|
QVERIFY(view->viewport()->hasFocus());
|
|
|
|
QVERIFY(scene.hasFocus());
|
|
|
|
QVERIFY(editProxy->hasFocus());
|
|
|
|
QVERIFY(edit->hasFocus());
|
|
|
|
QVERIFY(!editProxy2->hasFocus());
|
|
|
|
QVERIFY(!edit2->hasFocus());
|
|
|
|
QVERIFY(!rightDial->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 2);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1);
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusIn], 2);
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 2);
|
|
|
|
|
|
|
|
// Backtab into left dial
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!view->hasFocus());
|
|
|
|
QVERIFY(!view->viewport()->hasFocus());
|
|
|
|
QVERIFY(!scene.hasFocus());
|
|
|
|
QVERIFY(!editProxy->hasFocus());
|
|
|
|
QVERIFY(!edit->hasFocus());
|
|
|
|
QVERIFY(leftDial->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 2);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 2);
|
|
|
|
|
|
|
|
delete view;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::tabFocus_complexWidget()
|
|
|
|
{
|
|
|
|
QGraphicsScene scene;
|
|
|
|
|
|
|
|
QLineEdit *edit1 = new QLineEdit;
|
|
|
|
edit1->setText("QLineEdit 1");
|
|
|
|
QLineEdit *edit2 = new QLineEdit;
|
|
|
|
edit2->setText("QLineEdit 2");
|
|
|
|
QVBoxLayout *vlayout = new QVBoxLayout;
|
|
|
|
vlayout->addWidget(edit1);
|
|
|
|
vlayout->addWidget(edit2);
|
|
|
|
|
|
|
|
QGroupBox *box = new QGroupBox("QGroupBox");
|
|
|
|
box->setCheckable(true);
|
|
|
|
box->setChecked(true);
|
|
|
|
box->setLayout(vlayout);
|
|
|
|
|
|
|
|
QGraphicsProxyWidget *proxy = scene.addWidget(box);
|
|
|
|
proxy->show();
|
|
|
|
|
|
|
|
QDial *leftDial = new QDial;
|
|
|
|
QDial *rightDial = new QDial;
|
|
|
|
QGraphicsView *view = new QGraphicsView(&scene);
|
|
|
|
|
|
|
|
QWidget window;
|
|
|
|
QHBoxLayout *layout = new QHBoxLayout;
|
|
|
|
layout->addWidget(leftDial);
|
|
|
|
layout->addWidget(view);
|
|
|
|
layout->addWidget(rightDial);
|
|
|
|
window.setLayout(layout);
|
|
|
|
|
|
|
|
window.show();
|
|
|
|
QApplication::setActiveWindow(&window);
|
|
|
|
window.activateWindow();
|
2012-07-30 10:36:02 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&window));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
leftDial->setFocus();
|
|
|
|
QApplication::processEvents();
|
|
|
|
QTRY_VERIFY(leftDial->hasFocus());
|
|
|
|
|
|
|
|
EventSpy eventSpy(edit1);
|
|
|
|
EventSpy eventSpy2(edit2);
|
|
|
|
EventSpy eventSpyBox(box);
|
|
|
|
|
|
|
|
// Tab into group box
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!leftDial->hasFocus());
|
|
|
|
QVERIFY(view->hasFocus());
|
|
|
|
QVERIFY(view->viewport()->hasFocus());
|
|
|
|
QVERIFY(scene.hasFocus());
|
|
|
|
QVERIFY(proxy->hasFocus());
|
|
|
|
QVERIFY(box->hasFocus());
|
|
|
|
|
|
|
|
// Tab into line edit
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
edit1->hasFocus();
|
|
|
|
QVERIFY(!box->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 0);
|
|
|
|
|
|
|
|
// Tab into line edit 2
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
edit2->hasFocus();
|
|
|
|
QVERIFY(!edit1->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1);
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 0);
|
|
|
|
|
|
|
|
// Tab into right dial
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!edit2->hasFocus());
|
|
|
|
rightDial->hasFocus();
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 1);
|
|
|
|
|
|
|
|
// Backtab into line edit 2
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!rightDial->hasFocus());
|
|
|
|
edit2->hasFocus();
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusIn], 2);
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 1);
|
|
|
|
|
|
|
|
// Backtab into line edit 1
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!edit2->hasFocus());
|
|
|
|
edit1->hasFocus();
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 2);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 2);
|
|
|
|
|
|
|
|
// Backtab into line box
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!edit1->hasFocus());
|
|
|
|
box->hasFocus();
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 2);
|
|
|
|
|
|
|
|
// Backtab into left dial
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!box->hasFocus());
|
|
|
|
leftDial->hasFocus();
|
|
|
|
|
|
|
|
delete view;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::tabFocus_complexTwoWidgets()
|
|
|
|
{
|
|
|
|
// ### add event spies to this test.
|
|
|
|
QGraphicsScene scene;
|
|
|
|
|
|
|
|
QLineEdit *edit1 = new QLineEdit;
|
|
|
|
edit1->setText("QLineEdit 1");
|
|
|
|
QLineEdit *edit2 = new QLineEdit;
|
|
|
|
edit2->setText("QLineEdit 2");
|
|
|
|
QFontComboBox *fontComboBox = new QFontComboBox;
|
|
|
|
QVBoxLayout *vlayout = new QVBoxLayout;
|
|
|
|
vlayout->addWidget(edit1);
|
|
|
|
vlayout->addWidget(fontComboBox);
|
|
|
|
vlayout->addWidget(edit2);
|
|
|
|
|
|
|
|
QGroupBox *box = new QGroupBox("QGroupBox");
|
|
|
|
box->setCheckable(true);
|
|
|
|
box->setChecked(true);
|
|
|
|
box->setLayout(vlayout);
|
|
|
|
|
|
|
|
QLineEdit *edit1_2 = new QLineEdit;
|
|
|
|
edit1_2->setText("QLineEdit 1_2");
|
|
|
|
QLineEdit *edit2_2 = new QLineEdit;
|
|
|
|
edit2_2->setText("QLineEdit 2_2");
|
|
|
|
QFontComboBox *fontComboBox2 = new QFontComboBox;
|
|
|
|
vlayout = new QVBoxLayout;
|
|
|
|
vlayout->addWidget(edit1_2);
|
|
|
|
vlayout->addWidget(fontComboBox2);
|
|
|
|
vlayout->addWidget(edit2_2);
|
|
|
|
|
|
|
|
QGroupBox *box_2 = new QGroupBox("QGroupBox 2");
|
|
|
|
box_2->setCheckable(true);
|
|
|
|
box_2->setChecked(true);
|
|
|
|
box_2->setLayout(vlayout);
|
|
|
|
|
|
|
|
QGraphicsProxyWidget *proxy = scene.addWidget(box);
|
|
|
|
proxy->show();
|
|
|
|
|
|
|
|
QGraphicsProxyWidget *proxy_2 = scene.addWidget(box_2);
|
|
|
|
proxy_2->setPos(proxy->boundingRect().width() * 1.2, 0);
|
|
|
|
proxy_2->show();
|
|
|
|
|
|
|
|
QDial *leftDial = new QDial;
|
|
|
|
QDial *rightDial = new QDial;
|
|
|
|
QGraphicsView *view = new QGraphicsView(&scene);
|
|
|
|
view->setRenderHint(QPainter::Antialiasing);
|
|
|
|
view->rotate(45);
|
|
|
|
view->scale(0.5, 0.5);
|
|
|
|
|
|
|
|
QWidget window;
|
|
|
|
QHBoxLayout *layout = new QHBoxLayout;
|
|
|
|
layout->addWidget(leftDial);
|
|
|
|
layout->addWidget(view);
|
|
|
|
layout->addWidget(rightDial);
|
|
|
|
window.setLayout(layout);
|
|
|
|
|
|
|
|
window.show();
|
|
|
|
QApplication::setActiveWindow(&window);
|
|
|
|
window.activateWindow();
|
2012-07-18 11:12:59 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&window));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
leftDial->setFocus();
|
|
|
|
QApplication::processEvents();
|
|
|
|
QTRY_VERIFY(leftDial->hasFocus());
|
|
|
|
|
|
|
|
EventSpy eventSpy(edit1);
|
|
|
|
EventSpy eventSpy2(edit2);
|
|
|
|
EventSpy eventSpy3(fontComboBox);
|
|
|
|
EventSpy eventSpy1_2(edit1_2);
|
|
|
|
EventSpy eventSpy2_2(edit2_2);
|
|
|
|
EventSpy eventSpy2_3(fontComboBox2);
|
|
|
|
EventSpy eventSpyBox(box);
|
|
|
|
|
|
|
|
// Tab into group box
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!leftDial->hasFocus());
|
|
|
|
QVERIFY(view->hasFocus());
|
|
|
|
QVERIFY(view->viewport()->hasFocus());
|
|
|
|
QVERIFY(scene.hasFocus());
|
|
|
|
QVERIFY(proxy->hasFocus());
|
|
|
|
QVERIFY(box->hasFocus());
|
|
|
|
|
|
|
|
// Tab into line edit
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
edit1->hasFocus();
|
|
|
|
QVERIFY(!box->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 0);
|
|
|
|
|
|
|
|
// Tab to the font combobox
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
fontComboBox->hasFocus();
|
|
|
|
QVERIFY(!edit2->hasFocus());
|
|
|
|
QCOMPARE(eventSpy3.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy3.counts[QEvent::FocusOut], 0);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1);
|
|
|
|
|
|
|
|
// Tab into line edit 2
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
edit2->hasFocus();
|
|
|
|
QVERIFY(!edit1->hasFocus());
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy2.counts[QEvent::FocusOut], 0);
|
|
|
|
QCOMPARE(eventSpy3.counts[QEvent::FocusOut], 1);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1);
|
|
|
|
|
|
|
|
// Tab into right box
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!edit2->hasFocus());
|
|
|
|
box_2->hasFocus();
|
|
|
|
|
|
|
|
// Tab into right top line edit
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!box_2->hasFocus());
|
|
|
|
edit1_2->hasFocus();
|
|
|
|
QCOMPARE(eventSpy1_2.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy1_2.counts[QEvent::FocusOut], 0);
|
|
|
|
|
|
|
|
// Tab into right font combobox
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!edit1_2->hasFocus());
|
|
|
|
fontComboBox2->hasFocus();
|
|
|
|
QCOMPARE(eventSpy1_2.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy1_2.counts[QEvent::FocusOut], 1);
|
|
|
|
QCOMPARE(eventSpy2_3.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy2_3.counts[QEvent::FocusOut], 0);
|
|
|
|
|
|
|
|
// Tab into right bottom line edit
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!edit1_2->hasFocus());
|
|
|
|
edit2_2->hasFocus();
|
|
|
|
QCOMPARE(eventSpy1_2.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy1_2.counts[QEvent::FocusOut], 1);
|
|
|
|
QCOMPARE(eventSpy2_3.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy2_3.counts[QEvent::FocusOut], 1);
|
|
|
|
QCOMPARE(eventSpy2_2.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy2_2.counts[QEvent::FocusOut], 0);
|
|
|
|
|
|
|
|
// Tab into right dial
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!edit2->hasFocus());
|
|
|
|
rightDial->hasFocus();
|
|
|
|
QCOMPARE(eventSpy2_2.counts[QEvent::FocusOut], 1);
|
|
|
|
|
|
|
|
// Backtab into line edit 2
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!rightDial->hasFocus());
|
|
|
|
edit2_2->hasFocus();
|
|
|
|
|
|
|
|
// Backtab into the right font combobox
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!edit2_2->hasFocus());
|
|
|
|
fontComboBox2->hasFocus();
|
|
|
|
|
|
|
|
// Backtab into line edit 1
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!edit2_2->hasFocus());
|
|
|
|
edit1_2->hasFocus();
|
|
|
|
|
|
|
|
// Backtab into line box
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!edit1_2->hasFocus());
|
|
|
|
box_2->hasFocus();
|
|
|
|
|
|
|
|
// Backtab into line edit 2
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!rightDial->hasFocus());
|
|
|
|
edit2->hasFocus();
|
|
|
|
|
|
|
|
// Backtab into the font combobox
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!edit2->hasFocus());
|
|
|
|
fontComboBox->hasFocus();
|
|
|
|
|
|
|
|
// Backtab into line edit 1
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!fontComboBox->hasFocus());
|
|
|
|
edit1->hasFocus();
|
|
|
|
|
|
|
|
// Backtab into line box
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!edit1->hasFocus());
|
|
|
|
box->hasFocus();
|
|
|
|
|
|
|
|
// Backtab into left dial
|
|
|
|
QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab);
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!box->hasFocus());
|
|
|
|
leftDial->hasFocus();
|
|
|
|
|
|
|
|
delete view;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::setFocus_simpleWidget()
|
|
|
|
{
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QLineEdit *edit = new QLineEdit;
|
|
|
|
QGraphicsProxyWidget *editProxy = scene.addWidget(edit);
|
|
|
|
editProxy->show();
|
|
|
|
|
|
|
|
QDial *leftDial = new QDial;
|
|
|
|
QDial *rightDial = new QDial;
|
|
|
|
QGraphicsView *view = new QGraphicsView(&scene);
|
|
|
|
|
|
|
|
QWidget window;
|
|
|
|
QHBoxLayout *layout = new QHBoxLayout;
|
|
|
|
layout->addWidget(leftDial);
|
|
|
|
layout->addWidget(view);
|
|
|
|
layout->addWidget(rightDial);
|
|
|
|
window.setLayout(layout);
|
|
|
|
|
|
|
|
window.show();
|
|
|
|
QApplication::setActiveWindow(&window);
|
|
|
|
window.activateWindow();
|
2012-07-30 10:36:02 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&window));
|
|
|
|
QCOMPARE(QApplication::activeWindow(), &window);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
leftDial->setFocus();
|
|
|
|
QApplication::processEvents();
|
|
|
|
QTRY_VERIFY(leftDial->hasFocus());
|
|
|
|
|
|
|
|
EventSpy eventSpy(edit);
|
|
|
|
|
|
|
|
// Calling setFocus for the line edit when the view doesn't have input
|
|
|
|
// focus does not steal focus from the dial. The edit, proxy and scene
|
|
|
|
// have focus but only in their own little space.
|
|
|
|
edit->setFocus();
|
|
|
|
QVERIFY(scene.hasFocus());
|
|
|
|
QVERIFY(edit->hasFocus());
|
|
|
|
QVERIFY(!view->hasFocus());
|
|
|
|
QVERIFY(!view->viewport()->hasFocus());
|
|
|
|
QVERIFY(leftDial->hasFocus());
|
|
|
|
|
|
|
|
// Clearing focus is a local operation.
|
|
|
|
edit->clearFocus();
|
|
|
|
QVERIFY(scene.hasFocus());
|
|
|
|
QVERIFY(!edit->hasFocus());
|
|
|
|
QVERIFY(!view->hasFocus());
|
|
|
|
QVERIFY(leftDial->hasFocus());
|
|
|
|
|
|
|
|
view->setFocus();
|
|
|
|
QVERIFY(scene.hasFocus());
|
|
|
|
QVERIFY(view->hasFocus());
|
|
|
|
QVERIFY(!leftDial->hasFocus());
|
|
|
|
QVERIFY(!edit->hasFocus());
|
|
|
|
|
|
|
|
scene.clearFocus();
|
|
|
|
QVERIFY(!scene.hasFocus());
|
|
|
|
|
|
|
|
edit->setFocus();
|
|
|
|
QVERIFY(scene.hasFocus());
|
|
|
|
QVERIFY(edit->hasFocus());
|
|
|
|
QVERIFY(editProxy->hasFocus());
|
|
|
|
|
|
|
|
// Symmetry
|
|
|
|
editProxy->clearFocus();
|
|
|
|
QVERIFY(!edit->hasFocus());
|
|
|
|
|
|
|
|
delete view;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::setFocus_simpleTwoWidgets()
|
|
|
|
{
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QLineEdit *edit = new QLineEdit;
|
|
|
|
QGraphicsProxyWidget *editProxy = scene.addWidget(edit);
|
|
|
|
editProxy->show();
|
|
|
|
QLineEdit *edit2 = new QLineEdit;
|
|
|
|
QGraphicsProxyWidget *edit2Proxy = scene.addWidget(edit2);
|
|
|
|
edit2Proxy->show();
|
|
|
|
edit2Proxy->setPos(editProxy->boundingRect().width() * 1.01, 0);
|
|
|
|
|
|
|
|
QDial *leftDial = new QDial;
|
|
|
|
QDial *rightDial = new QDial;
|
|
|
|
QGraphicsView *view = new QGraphicsView(&scene);
|
|
|
|
|
|
|
|
QWidget window;
|
|
|
|
QHBoxLayout *layout = new QHBoxLayout;
|
|
|
|
layout->addWidget(leftDial);
|
|
|
|
layout->addWidget(view);
|
|
|
|
layout->addWidget(rightDial);
|
|
|
|
window.setLayout(layout);
|
|
|
|
|
|
|
|
window.show();
|
|
|
|
QApplication::setActiveWindow(&window);
|
|
|
|
window.activateWindow();
|
2012-07-30 10:36:02 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&window));
|
|
|
|
QCOMPARE(QApplication::activeWindow(), &window);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
leftDial->setFocus();
|
|
|
|
QApplication::processEvents();
|
|
|
|
QTRY_VERIFY(leftDial->hasFocus());
|
|
|
|
|
|
|
|
EventSpy eventSpy(edit);
|
|
|
|
|
|
|
|
view->setFocus();
|
|
|
|
QVERIFY(!edit->hasFocus());
|
|
|
|
|
|
|
|
edit->setFocus();
|
|
|
|
QVERIFY(scene.hasFocus());
|
|
|
|
QVERIFY(edit->hasFocus());
|
|
|
|
QVERIFY(editProxy->hasFocus());
|
|
|
|
|
|
|
|
edit2->setFocus();
|
|
|
|
QVERIFY(scene.hasFocus());
|
|
|
|
QVERIFY(!edit->hasFocus());
|
|
|
|
QVERIFY(!editProxy->hasFocus());
|
|
|
|
QVERIFY(edit2->hasFocus());
|
|
|
|
QVERIFY(edit2Proxy->hasFocus());
|
|
|
|
|
|
|
|
delete view;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::setFocus_complexTwoWidgets()
|
|
|
|
{
|
|
|
|
// ### add event spies to this test.
|
|
|
|
QGraphicsScene scene;
|
|
|
|
|
|
|
|
QLineEdit *edit1 = new QLineEdit;
|
|
|
|
edit1->setText("QLineEdit 1");
|
|
|
|
QLineEdit *edit2 = new QLineEdit;
|
|
|
|
edit2->setText("QLineEdit 2");
|
|
|
|
QVBoxLayout *vlayout = new QVBoxLayout;
|
|
|
|
vlayout->addWidget(edit1);
|
|
|
|
vlayout->addWidget(edit2);
|
|
|
|
|
|
|
|
QGroupBox *box = new QGroupBox("QGroupBox");
|
|
|
|
box->setCheckable(true);
|
|
|
|
box->setChecked(true);
|
|
|
|
box->setLayout(vlayout);
|
|
|
|
|
|
|
|
QLineEdit *edit1_2 = new QLineEdit;
|
|
|
|
edit1_2->setText("QLineEdit 1_2");
|
|
|
|
QLineEdit *edit2_2 = new QLineEdit;
|
|
|
|
edit2_2->setText("QLineEdit 2_2");
|
|
|
|
vlayout = new QVBoxLayout;
|
|
|
|
vlayout->addWidget(edit1_2);
|
|
|
|
vlayout->addWidget(edit2_2);
|
|
|
|
|
|
|
|
QGroupBox *box_2 = new QGroupBox("QGroupBox 2");
|
|
|
|
box_2->setCheckable(true);
|
|
|
|
box_2->setChecked(true);
|
|
|
|
box_2->setLayout(vlayout);
|
|
|
|
|
|
|
|
QGraphicsProxyWidget *proxy = scene.addWidget(box);
|
|
|
|
proxy->show();
|
|
|
|
|
|
|
|
QGraphicsProxyWidget *proxy_2 = scene.addWidget(box_2);
|
|
|
|
proxy_2->setPos(proxy->boundingRect().width() * 1.2, 0);
|
|
|
|
proxy_2->show();
|
|
|
|
|
|
|
|
QDial *leftDial = new QDial;
|
|
|
|
QDial *rightDial = new QDial;
|
|
|
|
QGraphicsView *view = new QGraphicsView(&scene);
|
|
|
|
|
|
|
|
QWidget window;
|
|
|
|
QHBoxLayout *layout = new QHBoxLayout;
|
|
|
|
layout->addWidget(leftDial);
|
|
|
|
layout->addWidget(view);
|
|
|
|
layout->addWidget(rightDial);
|
|
|
|
window.setLayout(layout);
|
|
|
|
|
|
|
|
window.show();
|
|
|
|
QApplication::setActiveWindow(&window);
|
|
|
|
window.activateWindow();
|
2012-07-30 10:36:02 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&window));
|
|
|
|
QCOMPARE(QApplication::activeWindow(), &window);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
leftDial->setFocus();
|
|
|
|
QApplication::processEvents();
|
|
|
|
QTRY_VERIFY(leftDial->hasFocus());
|
|
|
|
|
|
|
|
EventSpy eventSpy(edit1);
|
|
|
|
EventSpy eventSpy2(edit2);
|
|
|
|
EventSpy eventSpyBox(box);
|
|
|
|
EventSpy eventSpy_2(edit1_2);
|
|
|
|
EventSpy eventSpy2_2(edit2_2);
|
|
|
|
EventSpy eventSpyBox_2(box_2);
|
|
|
|
|
|
|
|
view->setFocus();
|
|
|
|
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 0);
|
|
|
|
|
|
|
|
edit1->setFocus();
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(scene.hasFocus());
|
|
|
|
QVERIFY(edit1->hasFocus());
|
|
|
|
QVERIFY(!box->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpyBox.counts[QEvent::FocusIn], 0);
|
|
|
|
|
|
|
|
edit2_2->setFocus();
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!edit1->hasFocus());
|
|
|
|
QVERIFY(!box_2->hasFocus());
|
|
|
|
QVERIFY(edit2_2->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1);
|
|
|
|
QCOMPARE(eventSpy2_2.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpyBox.counts[QEvent::FocusIn], 0);
|
|
|
|
QCOMPARE(eventSpyBox_2.counts[QEvent::FocusIn], 0);
|
|
|
|
|
|
|
|
box->setFocus();
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(!edit2_2->hasFocus());
|
|
|
|
QVERIFY(!edit1->hasFocus());
|
|
|
|
QVERIFY(box->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1);
|
|
|
|
QCOMPARE(eventSpy2_2.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy2_2.counts[QEvent::FocusOut], 1);
|
|
|
|
QCOMPARE(eventSpyBox.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpyBox.counts[QEvent::FocusOut], 0);
|
|
|
|
QCOMPARE(eventSpyBox_2.counts[QEvent::FocusIn], 0);
|
|
|
|
QCOMPARE(eventSpyBox_2.counts[QEvent::FocusOut], 0);
|
|
|
|
|
|
|
|
edit2_2->setFocus();
|
|
|
|
QApplication::processEvents();
|
|
|
|
QVERIFY(edit2_2->hasFocus());
|
|
|
|
QVERIFY(!edit1->hasFocus());
|
|
|
|
QVERIFY(!box->hasFocus());
|
|
|
|
QVERIFY(!box_2->hasFocus());
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::FocusOut], 1);
|
|
|
|
QCOMPARE(eventSpy2_2.counts[QEvent::FocusIn], 2);
|
|
|
|
QCOMPARE(eventSpy2_2.counts[QEvent::FocusOut], 1);
|
|
|
|
QCOMPARE(eventSpyBox.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(eventSpyBox.counts[QEvent::FocusOut], 1);
|
|
|
|
QCOMPARE(eventSpyBox_2.counts[QEvent::FocusIn], 0);
|
|
|
|
QCOMPARE(eventSpyBox_2.counts[QEvent::FocusOut], 0);
|
|
|
|
|
|
|
|
delete view;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::popup_basic()
|
|
|
|
{
|
2014-07-25 08:49:38 +00:00
|
|
|
QScopedPointer<QComboBox> box(new QComboBox);
|
|
|
|
QStyleOptionComboBox opt;
|
|
|
|
opt.initFrom(box.data());
|
|
|
|
opt.editable = box->isEditable();
|
|
|
|
if (box->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt))
|
|
|
|
QSKIP("Does not work due to SH_Combobox_Popup");
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
// ProxyWidget should automatically create proxy's when the widget creates a child
|
|
|
|
QGraphicsScene *scene = new QGraphicsScene;
|
|
|
|
QGraphicsView view(scene);
|
|
|
|
view.setAlignment(Qt::AlignLeft | Qt::AlignTop);
|
|
|
|
view.setGeometry(0, 100, 480, 500);
|
|
|
|
view.show();
|
|
|
|
|
|
|
|
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
|
|
|
|
box->setGeometry(0, 0, 320, 40);
|
|
|
|
box->addItems(QStringList() << "monday" << "tuesday" << "wednesday"
|
2014-01-13 14:48:44 +00:00
|
|
|
<< "thursday" << "saturday" << "sunday");
|
2011-04-27 10:05:43 +00:00
|
|
|
QCOMPARE(proxy->childItems().count(), 0);
|
2014-07-25 08:49:38 +00:00
|
|
|
proxy->setWidget(box.data());
|
2011-04-27 10:05:43 +00:00
|
|
|
proxy->show();
|
|
|
|
scene->addItem(proxy);
|
|
|
|
|
|
|
|
QCOMPARE(box->pos(), QPoint());
|
|
|
|
QCOMPARE(proxy->pos(), QPointF());
|
|
|
|
|
2012-07-30 10:36:02 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
QTest::qWait(125);
|
|
|
|
QApplication::processEvents();
|
|
|
|
|
|
|
|
QTest::mousePress(view.viewport(), Qt::LeftButton, 0,
|
2014-01-13 14:48:44 +00:00
|
|
|
view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center())));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QTRY_COMPARE(box->pos(), QPoint());
|
|
|
|
|
|
|
|
QCOMPARE(proxy->childItems().count(), 1);
|
|
|
|
QGraphicsProxyWidget *child = (QGraphicsProxyWidget*)(proxy->childItems())[0];
|
|
|
|
QVERIFY(child->isWidget());
|
|
|
|
QVERIFY(child->widget());
|
2014-07-25 08:49:38 +00:00
|
|
|
QCOMPARE(child->widget()->parent(), static_cast<QObject*>(box.data()));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QTRY_COMPARE(proxy->pos(), QPointF(box->pos()));
|
|
|
|
QCOMPARE(child->x(), qreal(box->x()));
|
|
|
|
QCOMPARE(child->y(), qreal(box->rect().bottom()));
|
|
|
|
#ifndef Q_OS_WIN
|
|
|
|
// The popup's coordinates on Windows are in global space,
|
|
|
|
// regardless.
|
|
|
|
QCOMPARE(child->widget()->x(), box->x());
|
|
|
|
QCOMPARE(child->widget()->y(), box->rect().bottom());
|
|
|
|
QCOMPARE(child->geometry().toRect(), child->widget()->geometry());
|
|
|
|
#endif
|
|
|
|
QTest::qWait(12);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::popup_subwidget()
|
|
|
|
{
|
|
|
|
QGroupBox *groupBox = new QGroupBox;
|
|
|
|
groupBox->setTitle("GroupBox");
|
|
|
|
groupBox->setCheckable(true);
|
|
|
|
|
|
|
|
QComboBox *box = new QComboBox;
|
|
|
|
box->addItems(QStringList() << "monday" << "tuesday" << "wednesday"
|
2014-01-13 14:48:44 +00:00
|
|
|
<< "thursday" << "saturday" << "sunday");
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QVBoxLayout *layout = new QVBoxLayout;
|
|
|
|
layout->addWidget(new QLineEdit("QLineEdit"));
|
|
|
|
layout->addWidget(box);
|
|
|
|
layout->addWidget(new QLineEdit("QLineEdit"));
|
|
|
|
groupBox->setLayout(layout);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsProxyWidget *groupBoxProxy = scene.addWidget(groupBox);
|
|
|
|
groupBox->show();
|
|
|
|
groupBox->move(10000, 10000);
|
|
|
|
QCOMPARE(groupBox->pos(), QPoint(10000, 10000));
|
|
|
|
QCOMPARE(groupBoxProxy->pos(), QPointF(10000, 10000));
|
|
|
|
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
view.show();
|
2012-07-18 11:12:59 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
box->showPopup();
|
|
|
|
|
|
|
|
QVERIFY(!groupBoxProxy->childItems().isEmpty());
|
|
|
|
|
|
|
|
QStyleOptionComboBox opt;
|
|
|
|
opt.initFrom(box);
|
|
|
|
opt.editable = box->isEditable();
|
|
|
|
if (box->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt))
|
2011-10-19 02:53:13 +00:00
|
|
|
QSKIP("Does not work due to SH_Combobox_Popup");
|
2011-04-27 10:05:43 +00:00
|
|
|
QGraphicsProxyWidget *child = (QGraphicsProxyWidget*)(groupBoxProxy->childItems())[0];
|
|
|
|
QWidget *popup = child->widget();
|
|
|
|
QCOMPARE(popup->parent(), static_cast<QObject*>(box));
|
|
|
|
QCOMPARE(popup->x(), box->mapToGlobal(QPoint()).x());
|
|
|
|
QCOMPARE(popup->y(), QRect(box->mapToGlobal(QPoint()), box->size()).bottom());
|
|
|
|
QCOMPARE(popup->size(), child->size().toSize());
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::changingCursor_basic()
|
|
|
|
{
|
2017-10-31 16:07:07 +00:00
|
|
|
#if !QT_CONFIG(cursor)
|
|
|
|
QSKIP("This test requires the QCursor API");
|
|
|
|
#else
|
2011-04-27 10:05:43 +00:00
|
|
|
// Confirm that mouse events are working properly by checking that
|
|
|
|
// when moving the mouse over a line edit it will change the cursor into the I
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
view.show();
|
2017-10-31 16:07:07 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
SubQGraphicsProxyWidget *proxy = new SubQGraphicsProxyWidget;
|
|
|
|
QLineEdit *widget = new QLineEdit;
|
|
|
|
proxy->setWidget(widget);
|
2017-10-31 16:07:07 +00:00
|
|
|
QSignalSpy sceneChangedSpy(&scene, &QGraphicsScene::changed);
|
2011-04-27 10:05:43 +00:00
|
|
|
scene.addItem(proxy);
|
2017-10-31 16:07:07 +00:00
|
|
|
QTRY_VERIFY(sceneChangedSpy.count() > 0); // make sure the scene is ready
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
// in
|
|
|
|
QTest::mouseMove(view.viewport(), view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center())));
|
|
|
|
QTRY_COMPARE(view.viewport()->cursor().shape(), Qt::IBeamCursor);
|
|
|
|
|
|
|
|
// out
|
|
|
|
QTest::mouseMove(view.viewport(), QPoint(1, 1));
|
|
|
|
QTRY_COMPARE(view.viewport()->cursor().shape(), Qt::ArrowCursor);
|
2017-10-31 16:07:07 +00:00
|
|
|
#endif // !QT_CONFIG(cursor)
|
2011-11-15 01:36:18 +00:00
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2017-12-07 15:31:43 +00:00
|
|
|
static bool findViewAndTipLabel(const QWidget *view)
|
|
|
|
{
|
|
|
|
bool foundView = false;
|
|
|
|
bool foundTipLabel = false;
|
|
|
|
const QWidgetList &topLevels = QApplication::topLevelWidgets();
|
|
|
|
for (const QWidget *widget : topLevels) {
|
|
|
|
if (widget == view)
|
|
|
|
foundView = true;
|
|
|
|
if (widget->inherits("QTipLabel"))
|
|
|
|
foundTipLabel = true;
|
|
|
|
if (foundView && foundTipLabel)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
void tst_QGraphicsProxyWidget::tooltip_basic()
|
|
|
|
{
|
|
|
|
QString toolTip = "Qt rocks!";
|
|
|
|
QString toolTip2 = "Qt rocks even more!";
|
|
|
|
|
|
|
|
QPushButton *button = new QPushButton("button");
|
|
|
|
QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget;
|
|
|
|
QGraphicsProxyWidgetPrivate *proxyd = static_cast<QGraphicsProxyWidgetPrivate *>(QGraphicsItemPrivate::get(proxy));
|
|
|
|
proxy->setWidget(button);
|
|
|
|
proxyd->lastWidgetUnderMouse = button; // force widget under mouse
|
|
|
|
|
|
|
|
QVERIFY(button->toolTip().isEmpty());
|
|
|
|
QVERIFY(proxy->toolTip().isEmpty());
|
|
|
|
// Check that setting the tooltip on the proxy also set it on the widget
|
|
|
|
proxy->setToolTip(toolTip);
|
|
|
|
QCOMPARE(proxy->toolTip(), toolTip);
|
|
|
|
QCOMPARE(button->toolTip(), toolTip);
|
|
|
|
// Check that setting the tooltip on the widget also set it on the proxy
|
|
|
|
button->setToolTip(toolTip2);
|
|
|
|
QCOMPARE(proxy->toolTip(), toolTip2);
|
|
|
|
QCOMPARE(button->toolTip(), toolTip2);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
scene.addItem(proxy);
|
|
|
|
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
view.setFixedSize(200, 200);
|
|
|
|
view.show();
|
2012-07-18 11:12:59 +00:00
|
|
|
QApplication::setActiveWindow(&view);
|
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
{
|
|
|
|
QHelpEvent helpEvent(QEvent::ToolTip, view.viewport()->rect().topLeft(),
|
|
|
|
view.viewport()->mapToGlobal(view.viewport()->rect().topLeft()));
|
|
|
|
QApplication::sendEvent(view.viewport(), &helpEvent);
|
|
|
|
QTest::qWait(350);
|
|
|
|
|
|
|
|
bool foundView = false;
|
|
|
|
bool foundTipLabel = false;
|
|
|
|
foreach (QWidget *widget, QApplication::topLevelWidgets()) {
|
|
|
|
if (widget == &view)
|
|
|
|
foundView = true;
|
|
|
|
if (widget->inherits("QTipLabel"))
|
|
|
|
foundTipLabel = true;
|
|
|
|
}
|
|
|
|
QVERIFY(foundView);
|
|
|
|
QVERIFY(!foundTipLabel);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
QHelpEvent helpEvent(QEvent::ToolTip, view.mapFromScene(proxy->boundingRect().center()),
|
|
|
|
view.viewport()->mapToGlobal(view.mapFromScene(proxy->boundingRect().center())));
|
|
|
|
QApplication::sendEvent(view.viewport(), &helpEvent);
|
2017-12-07 15:31:43 +00:00
|
|
|
QTRY_VERIFY(findViewAndTipLabel(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::childPos_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<bool>("moveCombo");
|
|
|
|
QTest::addColumn<QPoint>("comboPos");
|
|
|
|
QTest::addColumn<QPointF>("proxyPos");
|
2011-11-17 14:52:53 +00:00
|
|
|
|
|
|
|
QTest::newRow("0") << true << QPoint() << QPointF();
|
|
|
|
QTest::newRow("1") << true << QPoint(10, 0) << QPointF(10, 0);
|
|
|
|
QTest::newRow("2") << true << QPoint(100, 0) << QPointF(100, 0);
|
|
|
|
QTest::newRow("3") << true << QPoint(1000, 0) << QPointF(1000, 0);
|
|
|
|
QTest::newRow("4") << true << QPoint(10000, 0) << QPointF(10000, 0);
|
|
|
|
QTest::newRow("5") << true << QPoint(-10000, 0) << QPointF(-10000, 0);
|
|
|
|
QTest::newRow("6") << true << QPoint(-1000, 0) << QPointF(-1000, 0);
|
|
|
|
QTest::newRow("7") << true << QPoint(-100, 0) << QPointF(-100, 0);
|
|
|
|
QTest::newRow("8") << true << QPoint(-10, 0) << QPointF(-10, 0);
|
|
|
|
QTest::newRow("0-") << false << QPoint() << QPointF();
|
|
|
|
QTest::newRow("1-") << false << QPoint(10, 0) << QPointF(10, 0);
|
|
|
|
QTest::newRow("2-") << false << QPoint(100, 0) << QPointF(100, 0);
|
|
|
|
QTest::newRow("3-") << false << QPoint(1000, 0) << QPointF(1000, 0);
|
|
|
|
QTest::newRow("4-") << false << QPoint(10000, 0) << QPointF(10000, 0);
|
|
|
|
QTest::newRow("5-") << false << QPoint(-10000, 0) << QPointF(-10000, 0);
|
|
|
|
QTest::newRow("6-") << false << QPoint(-1000, 0) << QPointF(-1000, 0);
|
|
|
|
QTest::newRow("7-") << false << QPoint(-100, 0) << QPointF(-100, 0);
|
|
|
|
QTest::newRow("8-") << false << QPoint(-10, 0) << QPointF(-10, 0);
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::childPos()
|
|
|
|
{
|
|
|
|
QFETCH(bool, moveCombo);
|
|
|
|
QFETCH(QPoint, comboPos);
|
|
|
|
QFETCH(QPointF, proxyPos);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
|
|
|
|
QComboBox *box = new QComboBox;
|
|
|
|
box->addItem("Item 1");
|
|
|
|
box->addItem("Item 2");
|
|
|
|
box->addItem("Item 3");
|
|
|
|
box->addItem("Item 4");
|
|
|
|
|
|
|
|
if (moveCombo)
|
|
|
|
box->move(comboPos);
|
|
|
|
|
|
|
|
QGraphicsProxyWidget *proxy = scene.addWidget(box);
|
|
|
|
proxy->show();
|
|
|
|
QVERIFY(proxy->isVisible());
|
|
|
|
QVERIFY(box->isVisible());
|
|
|
|
|
|
|
|
if (!moveCombo)
|
|
|
|
proxy->setPos(proxyPos);
|
|
|
|
|
|
|
|
QCOMPARE(proxy->pos(), proxyPos);
|
|
|
|
QCOMPARE(box->pos(), comboPos);
|
|
|
|
|
|
|
|
for (int i = 0; i < 2; ++i) {
|
|
|
|
box->showPopup();
|
|
|
|
QApplication::processEvents();
|
|
|
|
QApplication::processEvents();
|
|
|
|
|
2020-10-07 11:05:48 +00:00
|
|
|
QWidget *menu = nullptr;
|
2011-04-27 10:05:43 +00:00
|
|
|
foreach (QObject *child, box->children()) {
|
|
|
|
if ((menu = qobject_cast<QWidget *>(child)))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
QVERIFY(menu);
|
|
|
|
QVERIFY(menu->isVisible());
|
|
|
|
QVERIFY(menu->testAttribute(Qt::WA_DontShowOnScreen));
|
|
|
|
|
|
|
|
QCOMPARE(proxy->childItems().size(), 1);
|
|
|
|
QGraphicsProxyWidget *proxyChild = 0;
|
|
|
|
foreach (QGraphicsItem *child, proxy->childItems()) {
|
|
|
|
if (child->isWidget() && (proxyChild = qobject_cast<QGraphicsProxyWidget *>(static_cast<QGraphicsWidget *>(child))))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
QVERIFY(proxyChild);
|
|
|
|
QVERIFY(proxyChild->isVisible());
|
|
|
|
qreal expectedXPosition = 0.0;
|
2012-01-16 10:49:53 +00:00
|
|
|
#if defined(Q_OS_MAC) && !defined(QT_NO_STYLE_MAC)
|
2011-04-27 10:05:43 +00:00
|
|
|
// The Mac style wants the popup to show up at QPoint(4 - 11, 1).
|
|
|
|
// See QMacStyle::subControlRect SC_ComboBoxListBoxPopup.
|
2012-11-16 23:52:26 +00:00
|
|
|
if (QApplication::style()->inherits("QMacStyle"))
|
2011-04-27 10:05:43 +00:00
|
|
|
expectedXPosition = qreal(4 - 11);
|
|
|
|
#endif
|
|
|
|
QCOMPARE(proxyChild->pos().x(), expectedXPosition);
|
|
|
|
menu->hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::autoShow()
|
|
|
|
{
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
|
|
|
|
QGraphicsProxyWidget *proxy1 = scene.addWidget(new QPushButton("Button1"));
|
|
|
|
|
|
|
|
QPushButton *button2 = new QPushButton("Button2");
|
|
|
|
button2->hide();
|
|
|
|
QGraphicsProxyWidget *proxy2 = new QGraphicsProxyWidget();
|
|
|
|
proxy2->setWidget(button2);
|
|
|
|
scene.addItem(proxy2);
|
|
|
|
|
|
|
|
view.show();
|
|
|
|
QApplication::processEvents();
|
|
|
|
|
|
|
|
QCOMPARE(proxy1->isVisible(), true);
|
|
|
|
QCOMPARE(proxy2->isVisible(), false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::windowOpacity()
|
|
|
|
{
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
|
|
|
|
QWidget *widget = new QWidget;
|
|
|
|
widget->resize(100, 100);
|
|
|
|
QGraphicsProxyWidget *proxy = scene.addWidget(widget);
|
|
|
|
proxy->setCacheMode(QGraphicsItem::ItemCoordinateCache);
|
|
|
|
|
|
|
|
QApplication::setActiveWindow(&view);
|
|
|
|
view.show();
|
2012-07-18 11:12:59 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
|
|
|
QVERIFY(view.isActiveWindow());
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
qRegisterMetaType<QList<QRectF> >("QList<QRectF>");
|
2012-10-16 09:08:13 +00:00
|
|
|
QSignalSpy signalSpy(&scene, SIGNAL(changed(QList<QRectF>)));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
EventSpy eventSpy(widget);
|
|
|
|
QVERIFY(widget->isVisible());
|
|
|
|
|
|
|
|
widget->setWindowOpacity(0.5);
|
|
|
|
QApplication::processEvents();
|
|
|
|
|
|
|
|
// Make sure setWindowOpacity triggers an update on the scene,
|
|
|
|
// and not on the widget or the proxy itself. The entire proxy needs an update
|
|
|
|
// in case it has a window decoration. Update: QGraphicsItem::CacheMode is
|
|
|
|
// disabled on platforms without alpha channel support in QPixmap (e.g.,
|
|
|
|
// X11 without XRender).
|
|
|
|
int paints = 0;
|
|
|
|
QTRY_COMPARE(eventSpy.counts[QEvent::UpdateRequest], 0);
|
|
|
|
QTRY_COMPARE(eventSpy.counts[QEvent::Paint], paints);
|
|
|
|
|
|
|
|
QCOMPARE(signalSpy.count(), 1);
|
|
|
|
const QList<QVariant> arguments = signalSpy.takeFirst();
|
|
|
|
const QList<QRectF> updateRects = qvariant_cast<QList<QRectF> >(arguments.at(0));
|
|
|
|
QCOMPARE(updateRects.size(), 1);
|
|
|
|
QCOMPARE(updateRects.at(0), proxy->sceneBoundingRect());
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::stylePropagation()
|
|
|
|
{
|
2012-11-27 17:22:05 +00:00
|
|
|
QPointer<QStyle> windowsStyle = QStyleFactory::create("windows");
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QLineEdit *edit = new QLineEdit;
|
|
|
|
QGraphicsProxyWidget proxy;
|
|
|
|
proxy.setWidget(edit);
|
|
|
|
|
|
|
|
EventSpy editSpy(edit);
|
|
|
|
EventSpy proxySpy(&proxy);
|
|
|
|
|
|
|
|
// Widget to proxy
|
|
|
|
QCOMPARE(proxy.style(), QApplication::style());
|
|
|
|
edit->setStyle(windowsStyle);
|
|
|
|
QCOMPARE(editSpy.counts[QEvent::StyleChange], 1);
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::StyleChange], 1);
|
|
|
|
QCOMPARE(proxy.style(), (QStyle *)windowsStyle);
|
|
|
|
edit->setStyle(0);
|
|
|
|
QCOMPARE(editSpy.counts[QEvent::StyleChange], 2);
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::StyleChange], 2);
|
|
|
|
QCOMPARE(proxy.style(), QApplication::style());
|
|
|
|
QCOMPARE(edit->style(), QApplication::style());
|
|
|
|
QVERIFY(windowsStyle); // not deleted
|
|
|
|
|
|
|
|
// Proxy to widget
|
|
|
|
proxy.setStyle(windowsStyle);
|
|
|
|
QCOMPARE(editSpy.counts[QEvent::StyleChange], 3);
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::StyleChange], 3);
|
|
|
|
QCOMPARE(edit->style(), (QStyle *)windowsStyle);
|
|
|
|
proxy.setStyle(0);
|
|
|
|
QCOMPARE(editSpy.counts[QEvent::StyleChange], 4);
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::StyleChange], 4);
|
|
|
|
QCOMPARE(proxy.style(), QApplication::style());
|
|
|
|
QCOMPARE(edit->style(), QApplication::style());
|
|
|
|
QVERIFY(windowsStyle); // not deleted
|
|
|
|
|
|
|
|
delete windowsStyle;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::palettePropagation()
|
|
|
|
{
|
|
|
|
// Construct a palette with an unlikely setup
|
|
|
|
QPalette lineEditPalette = QApplication::palette("QLineEdit");
|
|
|
|
QPalette palette = lineEditPalette;
|
|
|
|
palette.setBrush(QPalette::Text, Qt::red);
|
|
|
|
|
|
|
|
QLineEdit *edit = new QLineEdit;
|
|
|
|
QGraphicsProxyWidget proxy;
|
|
|
|
proxy.setWidget(edit);
|
|
|
|
|
|
|
|
EventSpy editSpy(edit);
|
|
|
|
EventSpy proxySpy(&proxy);
|
|
|
|
|
|
|
|
// Widget to proxy (no change)
|
|
|
|
QVERIFY(!edit->testAttribute(Qt::WA_SetPalette));
|
|
|
|
edit->setPalette(palette);
|
|
|
|
QCOMPARE(editSpy.counts[QEvent::PaletteChange], 1);
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::PaletteChange], 0);
|
|
|
|
QVERIFY(edit->testAttribute(Qt::WA_SetPalette));
|
|
|
|
QVERIFY(!proxy.testAttribute(Qt::WA_SetPalette));
|
|
|
|
QCOMPARE(proxy.palette(), QPalette());
|
|
|
|
edit->setPalette(QPalette());
|
|
|
|
QCOMPARE(editSpy.counts[QEvent::PaletteChange], 2);
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::PaletteChange], 0);
|
|
|
|
QVERIFY(!edit->testAttribute(Qt::WA_SetPalette));
|
|
|
|
QVERIFY(!proxy.testAttribute(Qt::WA_SetPalette));
|
|
|
|
QCOMPARE(proxy.palette(), QPalette());
|
|
|
|
|
|
|
|
// Proxy to widget
|
|
|
|
proxy.setPalette(palette);
|
|
|
|
QVERIFY(proxy.testAttribute(Qt::WA_SetPalette));
|
|
|
|
QCOMPARE(editSpy.counts[QEvent::PaletteChange], 3);
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::PaletteChange], 1);
|
|
|
|
QVERIFY(!edit->testAttribute(Qt::WA_SetPalette));
|
|
|
|
QCOMPARE(edit->palette(), palette);
|
|
|
|
QCOMPARE(edit->palette(), proxy.palette());
|
|
|
|
QCOMPARE(edit->palette().color(QPalette::Text), QColor(Qt::red));
|
|
|
|
proxy.setPalette(QPalette());
|
|
|
|
QVERIFY(!proxy.testAttribute(Qt::WA_SetPalette));
|
|
|
|
QVERIFY(!edit->testAttribute(Qt::WA_SetPalette));
|
|
|
|
QCOMPARE(editSpy.counts[QEvent::PaletteChange], 4);
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::PaletteChange], 2);
|
|
|
|
QCOMPARE(edit->palette(), lineEditPalette);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::fontPropagation()
|
|
|
|
{
|
|
|
|
// Construct a font with an unlikely setup
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QFont lineEditFont = QApplication::font("QLineEdit");
|
|
|
|
QFont font = lineEditFont;
|
|
|
|
font.setPointSize(43);
|
|
|
|
|
|
|
|
QLineEdit *edit = new QLineEdit;
|
|
|
|
QGraphicsProxyWidget proxy;
|
|
|
|
proxy.setWidget(edit);
|
|
|
|
|
|
|
|
scene.addItem(&proxy);
|
|
|
|
EventSpy editSpy(edit);
|
|
|
|
EventSpy proxySpy(&proxy);
|
|
|
|
|
|
|
|
// Widget to proxy (no change)
|
|
|
|
QVERIFY(!edit->testAttribute(Qt::WA_SetFont));
|
|
|
|
edit->setFont(font);
|
|
|
|
QCOMPARE(editSpy.counts[QEvent::FontChange], 1);
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::FontChange], 0);
|
|
|
|
QVERIFY(edit->testAttribute(Qt::WA_SetFont));
|
|
|
|
QVERIFY(!proxy.testAttribute(Qt::WA_SetFont));
|
|
|
|
QCOMPARE(proxy.font(), lineEditFont);
|
|
|
|
edit->setFont(QFont());
|
|
|
|
QCOMPARE(editSpy.counts[QEvent::FontChange], 2);
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::FontChange], 0);
|
|
|
|
QVERIFY(!edit->testAttribute(Qt::WA_SetFont));
|
|
|
|
QVERIFY(!proxy.testAttribute(Qt::WA_SetFont));
|
|
|
|
QCOMPARE(proxy.font(), lineEditFont);
|
|
|
|
|
|
|
|
// Proxy to widget
|
|
|
|
proxy.setFont(font);
|
|
|
|
QApplication::processEvents(); // wait for QEvent::Polish
|
|
|
|
QVERIFY(proxy.testAttribute(Qt::WA_SetFont));
|
|
|
|
QCOMPARE(editSpy.counts[QEvent::FontChange], 3);
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::FontChange], 1);
|
|
|
|
QVERIFY(!edit->testAttribute(Qt::WA_SetFont));
|
|
|
|
QCOMPARE(edit->font(), font);
|
|
|
|
QCOMPARE(edit->font(), proxy.font());
|
|
|
|
QCOMPARE(edit->font().pointSize(), 43);
|
|
|
|
proxy.setFont(QFont());
|
|
|
|
QVERIFY(!proxy.testAttribute(Qt::WA_SetFont));
|
|
|
|
QVERIFY(!edit->testAttribute(Qt::WA_SetFont));
|
|
|
|
QCOMPARE(editSpy.counts[QEvent::FontChange], 4);
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::FontChange], 2);
|
|
|
|
QCOMPARE(edit->font(), lineEditFont);
|
|
|
|
|
|
|
|
proxy.setFont(font);
|
|
|
|
QLineEdit *edit2 = new QLineEdit;
|
|
|
|
proxy.setWidget(edit2);
|
|
|
|
delete edit;
|
|
|
|
QCOMPARE(edit2->font().pointSize(), 43);
|
|
|
|
}
|
|
|
|
|
|
|
|
class MainWidget : public QMainWindow
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
MainWidget() : QMainWindow() {
|
|
|
|
view = new QGraphicsView(this);
|
|
|
|
scene = new QGraphicsScene(this);
|
|
|
|
item = new QGraphicsWidget();
|
|
|
|
widget = new QGraphicsProxyWidget(item);
|
|
|
|
layout = new QGraphicsLinearLayout(item);
|
|
|
|
layout->addItem(widget);
|
|
|
|
item->setLayout(layout);
|
|
|
|
button = new QPushButton("Push me");
|
|
|
|
widget->setWidget(button);
|
|
|
|
setCentralWidget(view);
|
|
|
|
scene->addItem(item);
|
|
|
|
view->setScene(scene);
|
|
|
|
scene->setFocusItem(item);
|
|
|
|
layout->activate();
|
|
|
|
}
|
|
|
|
QGraphicsView* view;
|
|
|
|
QGraphicsScene* scene;
|
|
|
|
QGraphicsWidget * item;
|
|
|
|
QGraphicsLinearLayout * layout;
|
|
|
|
QGraphicsProxyWidget * widget;
|
|
|
|
QPushButton * button;
|
|
|
|
};
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::dontCrashWhenDie()
|
|
|
|
{
|
|
|
|
MainWidget *w = new MainWidget();
|
|
|
|
w->show();
|
2012-07-30 10:36:02 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(w));
|
2017-10-31 16:07:07 +00:00
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
QTest::mouseMove(w->view->viewport(), w->view->mapFromScene(w->widget->mapToScene(w->widget->boundingRect().center())));
|
|
|
|
delete w->item;
|
|
|
|
|
|
|
|
QApplication::processEvents();
|
|
|
|
delete w;
|
2014-07-25 08:49:38 +00:00
|
|
|
// This leaves an invisible proxy widget behind.
|
|
|
|
qDeleteAll(QApplication::topLevelWidgets());
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
2018-11-17 13:58:15 +00:00
|
|
|
void tst_QGraphicsProxyWidget::dontCrashNoParent() // QTBUG-15442
|
|
|
|
{
|
|
|
|
QGraphicsProxyWidget *parent(new QGraphicsProxyWidget);
|
|
|
|
QGraphicsProxyWidget *child(new QGraphicsProxyWidget);
|
|
|
|
QScopedPointer<QLabel> label0(new QLabel);
|
|
|
|
QScopedPointer<QLabel> label1(new QLabel);
|
|
|
|
|
|
|
|
child->setParentItem(parent);
|
|
|
|
// Set the first label as the proxied widget.
|
|
|
|
parent->setWidget(label0.data());
|
|
|
|
// If we attempt to change the proxied widget we get a crash.
|
|
|
|
parent->setWidget(label1.data());
|
|
|
|
}
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
void tst_QGraphicsProxyWidget::createProxyForChildWidget()
|
|
|
|
{
|
|
|
|
QGraphicsScene scene;
|
|
|
|
|
|
|
|
QLineEdit *edit1 = new QLineEdit;
|
|
|
|
edit1->setText("QLineEdit 1");
|
|
|
|
QLineEdit *edit2 = new QLineEdit;
|
|
|
|
edit2->setText("QLineEdit 2");
|
|
|
|
QCheckBox *checkbox = new QCheckBox("QCheckBox");
|
|
|
|
QVBoxLayout *vlayout = new QVBoxLayout;
|
|
|
|
|
|
|
|
vlayout->addWidget(edit1);
|
|
|
|
vlayout->addWidget(edit2);
|
|
|
|
vlayout->addWidget(checkbox);
|
|
|
|
vlayout->insertStretch(-1);
|
|
|
|
|
|
|
|
QGroupBox *box = new QGroupBox("QGroupBox");
|
|
|
|
box->setCheckable(true);
|
|
|
|
box->setChecked(true);
|
|
|
|
box->setLayout(vlayout);
|
|
|
|
|
|
|
|
QDial *leftDial = new QDial;
|
|
|
|
QDial *rightDial = new QDial;
|
|
|
|
|
|
|
|
QWidget window;
|
|
|
|
QHBoxLayout *layout = new QHBoxLayout;
|
|
|
|
layout->addWidget(leftDial);
|
|
|
|
layout->addWidget(box);
|
|
|
|
layout->addWidget(rightDial);
|
|
|
|
window.setLayout(layout);
|
|
|
|
|
2015-07-30 13:16:36 +00:00
|
|
|
QVERIFY(!window.graphicsProxyWidget());
|
|
|
|
QVERIFY(!checkbox->graphicsProxyWidget());
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QGraphicsProxyWidget *windowProxy = scene.addWidget(&window);
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
view.show();
|
|
|
|
view.resize(500,500);
|
|
|
|
|
2015-07-30 13:16:36 +00:00
|
|
|
QCOMPARE(window.graphicsProxyWidget(), windowProxy);
|
|
|
|
QVERIFY(!box->graphicsProxyWidget());
|
|
|
|
QVERIFY(!checkbox->graphicsProxyWidget());
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QPointer<QGraphicsProxyWidget> checkboxProxy = windowProxy->createProxyForChildWidget(checkbox);
|
|
|
|
|
|
|
|
QGraphicsProxyWidget *boxProxy = box->graphicsProxyWidget();
|
|
|
|
|
|
|
|
QVERIFY(boxProxy);
|
2015-07-30 13:16:36 +00:00
|
|
|
QCOMPARE(checkbox->graphicsProxyWidget(), checkboxProxy.data());
|
|
|
|
QCOMPARE(checkboxProxy->parentItem(), boxProxy);
|
|
|
|
QCOMPARE(boxProxy->parentItem(), windowProxy);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QVERIFY(checkboxProxy->mapToScene(QPointF()) == checkbox->mapTo(&window, QPoint()));
|
2015-07-30 13:16:36 +00:00
|
|
|
QCOMPARE(checkboxProxy->size().toSize(), checkbox->size());
|
|
|
|
QCOMPARE(boxProxy->size().toSize(), box->size());
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
window.resize(500,500);
|
2015-07-30 13:16:36 +00:00
|
|
|
QCOMPARE(windowProxy->size().toSize(), QSize(500,500));
|
2011-04-27 10:05:43 +00:00
|
|
|
QVERIFY(checkboxProxy->mapToScene(QPointF()) == checkbox->mapTo(&window, QPoint()));
|
2015-07-30 13:16:36 +00:00
|
|
|
QCOMPARE(checkboxProxy->size().toSize(), checkbox->size());
|
|
|
|
QCOMPARE(boxProxy->size().toSize(), box->size());
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QTest::qWait(10);
|
|
|
|
|
|
|
|
|
|
|
|
QSignalSpy spy(checkbox, SIGNAL(clicked()));
|
|
|
|
|
|
|
|
QTest::mousePress(view.viewport(), Qt::LeftButton, 0,
|
|
|
|
view.mapFromScene(checkboxProxy->mapToScene(QPointF(8,8))));
|
|
|
|
QTRY_COMPARE(spy.count(), 0);
|
|
|
|
QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0,
|
|
|
|
view.mapFromScene(checkboxProxy->mapToScene(QPointF(8,8))));
|
|
|
|
QTRY_COMPARE(spy.count(), 1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
boxProxy->setWidget(0);
|
|
|
|
|
2015-07-30 13:16:36 +00:00
|
|
|
QVERIFY(!checkbox->graphicsProxyWidget());
|
|
|
|
QVERIFY(!box->graphicsProxyWidget());
|
|
|
|
QVERIFY(checkboxProxy.isNull());
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
delete boxProxy;
|
|
|
|
}
|
|
|
|
|
2015-09-04 03:07:27 +00:00
|
|
|
#ifndef QT_NO_CONTEXTMENU
|
2014-03-28 09:43:53 +00:00
|
|
|
class ContextMenuWidget : public QLabel
|
2011-04-27 10:05:43 +00:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
ContextMenuWidget()
|
2014-03-28 09:43:53 +00:00
|
|
|
: QLabel(QStringLiteral("ContextMenuWidget"))
|
|
|
|
, embeddedPopup(false)
|
|
|
|
, gotContextMenuEvent(false)
|
|
|
|
, m_embeddedPopupSet(false)
|
|
|
|
, m_timer(0)
|
2011-04-27 10:05:43 +00:00
|
|
|
{ }
|
|
|
|
bool embeddedPopup;
|
|
|
|
bool gotContextMenuEvent;
|
|
|
|
protected:
|
|
|
|
bool event(QEvent *event)
|
|
|
|
{
|
2014-03-28 09:43:53 +00:00
|
|
|
if (event->type() == QEvent::ContextMenu) {
|
|
|
|
if (!m_timer) {
|
|
|
|
m_timer = new QTimer(this);
|
|
|
|
m_timer->setInterval(10);
|
|
|
|
connect(m_timer, SIGNAL(timeout()), this, SLOT(checkMenu()));
|
|
|
|
m_timer->start();
|
|
|
|
}
|
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
return QWidget::event(event);
|
|
|
|
}
|
|
|
|
void contextMenuEvent(QContextMenuEvent *)
|
|
|
|
{
|
|
|
|
gotContextMenuEvent = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void checkMenu()
|
|
|
|
{
|
2014-03-28 09:43:53 +00:00
|
|
|
QMenu *menu = findChild<QMenu *>();
|
|
|
|
if (!m_embeddedPopupSet) {
|
|
|
|
m_embeddedPopupSet = true;
|
|
|
|
embeddedPopup = menu != 0;
|
|
|
|
}
|
|
|
|
if (menu && menu->isVisible())
|
|
|
|
menu->hide();
|
2011-04-27 10:05:43 +00:00
|
|
|
hide();
|
|
|
|
}
|
2014-03-28 09:43:53 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
bool m_embeddedPopupSet;
|
|
|
|
QTimer *m_timer;
|
2011-04-27 10:05:43 +00:00
|
|
|
};
|
2015-09-04 03:07:27 +00:00
|
|
|
#endif // QT_NO_CONTEXTMENU
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::actionsContextMenu_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<bool>("actionsContextMenu");
|
|
|
|
QTest::addColumn<bool>("hasFocus");
|
|
|
|
|
|
|
|
QTest::newRow("without actionsContextMenu and with focus") << false << true;
|
|
|
|
QTest::newRow("without actionsContextMenu and without focus") << false << false;
|
|
|
|
QTest::newRow("with actionsContextMenu and focus") << true << true;
|
|
|
|
QTest::newRow("with actionsContextMenu without focus") << true << false;
|
|
|
|
}
|
|
|
|
|
2015-09-04 03:07:27 +00:00
|
|
|
#ifndef QT_NO_CONTEXTMENU
|
2011-04-27 10:05:43 +00:00
|
|
|
void tst_QGraphicsProxyWidget::actionsContextMenu()
|
|
|
|
{
|
|
|
|
QFETCH(bool, hasFocus);
|
|
|
|
QFETCH(bool, actionsContextMenu);
|
|
|
|
|
|
|
|
ContextMenuWidget *widget = new ContextMenuWidget;
|
|
|
|
if (actionsContextMenu) {
|
|
|
|
widget->addAction(new QAction("item 1", widget));
|
|
|
|
widget->addAction(new QAction("item 2", widget));
|
|
|
|
widget->addAction(new QAction("item 3", widget));
|
|
|
|
widget->setContextMenuPolicy(Qt::ActionsContextMenu);
|
|
|
|
}
|
|
|
|
QGraphicsScene scene;
|
2014-03-28 09:43:53 +00:00
|
|
|
QGraphicsProxyWidget *proxyWidget = scene.addWidget(widget);
|
2011-04-27 10:05:43 +00:00
|
|
|
QGraphicsView view(&scene);
|
2014-03-28 09:43:53 +00:00
|
|
|
view.setWindowTitle(QStringLiteral("actionsContextMenu"));
|
|
|
|
view.resize(200, 200);
|
|
|
|
view.move(QGuiApplication::primaryScreen()->geometry().center() - QPoint(100, 100));
|
2011-04-27 10:05:43 +00:00
|
|
|
view.show();
|
|
|
|
QApplication::setActiveWindow(&view);
|
2012-07-30 10:36:02 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
view.setFocus();
|
|
|
|
QTRY_VERIFY(view.hasFocus());
|
|
|
|
|
|
|
|
if (hasFocus)
|
2014-03-28 09:43:53 +00:00
|
|
|
proxyWidget->setFocus();
|
2011-04-27 10:05:43 +00:00
|
|
|
else
|
2014-03-28 09:43:53 +00:00
|
|
|
proxyWidget->clearFocus();
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QApplication::processEvents();
|
|
|
|
|
|
|
|
QContextMenuEvent contextMenuEvent(QContextMenuEvent::Mouse,
|
|
|
|
view.viewport()->rect().center(),
|
|
|
|
view.viewport()->mapToGlobal(view.viewport()->rect().center()));
|
|
|
|
contextMenuEvent.accept();
|
|
|
|
qApp->sendEvent(view.viewport(), &contextMenuEvent);
|
|
|
|
|
|
|
|
if (hasFocus) {
|
|
|
|
if (actionsContextMenu) {
|
|
|
|
//actionsContextMenu embedded popup but no contextMenuEvent (widget has focus)
|
|
|
|
QVERIFY(widget->embeddedPopup);
|
|
|
|
QVERIFY(!widget->gotContextMenuEvent);
|
|
|
|
} else {
|
|
|
|
//no embedded popup but contextMenuEvent (widget has focus)
|
|
|
|
QVERIFY(!widget->embeddedPopup);
|
|
|
|
QVERIFY(widget->gotContextMenuEvent);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
//qgraphicsproxywidget doesn't have the focus, the widget must not receive any contextMenuEvent and must not create any QMenu
|
|
|
|
QVERIFY(!widget->embeddedPopup);
|
|
|
|
QVERIFY(!widget->gotContextMenuEvent);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2015-09-04 03:07:27 +00:00
|
|
|
#endif // QT_NO_CONTEXTMENU
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::deleteProxyForChildWidget()
|
|
|
|
{
|
|
|
|
QDialog dialog;
|
|
|
|
dialog.resize(320, 120);
|
|
|
|
dialog.move(80, 40);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
scene.setSceneRect(QRectF(0, 0, 640, 480));
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
QComboBox *combo = new QComboBox;
|
|
|
|
combo->addItems(QStringList() << "red" << "green" << "blue" << "white" << "black" << "yellow" << "cyan" << "magenta");
|
|
|
|
dialog.setLayout(new QVBoxLayout);
|
|
|
|
dialog.layout()->addWidget(combo);
|
|
|
|
|
|
|
|
QGraphicsProxyWidget *proxy = scene.addWidget(&dialog);
|
|
|
|
view.show();
|
|
|
|
|
|
|
|
proxy->setWidget(0);
|
|
|
|
//just don't crash
|
|
|
|
QApplication::processEvents();
|
|
|
|
delete combo;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::bypassGraphicsProxyWidget_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<bool>("bypass");
|
|
|
|
|
|
|
|
QTest::newRow("autoembed") << false;
|
|
|
|
QTest::newRow("bypass") << true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::bypassGraphicsProxyWidget()
|
|
|
|
{
|
|
|
|
QFETCH(bool, bypass);
|
|
|
|
|
|
|
|
QWidget *widget = new QWidget;
|
|
|
|
widget->resize(100, 100);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
view.show();
|
2017-10-31 16:07:07 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QGraphicsProxyWidget *proxy = scene.addWidget(widget);
|
|
|
|
|
|
|
|
QCOMPARE(proxy->widget(), widget);
|
|
|
|
QVERIFY(proxy->childItems().isEmpty());
|
|
|
|
|
|
|
|
Qt::WindowFlags flags;
|
|
|
|
flags |= Qt::Dialog;
|
|
|
|
if (bypass)
|
|
|
|
flags |= Qt::BypassGraphicsProxyWidget;
|
|
|
|
QFileDialog *dialog = new QFileDialog(widget, flags);
|
|
|
|
dialog->setOption(QFileDialog::DontUseNativeDialog, true);
|
|
|
|
dialog->show();
|
2017-10-31 16:07:07 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(dialog));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QCOMPARE(proxy->childItems().size(), bypass ? 0 : 1);
|
|
|
|
if (!bypass)
|
|
|
|
QCOMPARE(((QGraphicsProxyWidget *)proxy->childItems().first())->widget(), (QWidget *)dialog);
|
|
|
|
|
|
|
|
dialog->hide();
|
|
|
|
QApplication::processEvents();
|
|
|
|
delete dialog;
|
|
|
|
delete widget;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void makeDndEvent(QGraphicsSceneDragDropEvent *event, QGraphicsView *view, const QPointF &pos)
|
|
|
|
{
|
|
|
|
event->setScenePos(pos);
|
|
|
|
event->setScreenPos(view->mapToGlobal(view->mapFromScene(pos)));
|
|
|
|
event->setButtons(Qt::LeftButton);
|
|
|
|
event->setModifiers(0);
|
|
|
|
event->setPossibleActions(Qt::CopyAction);
|
|
|
|
event->setProposedAction(Qt::CopyAction);
|
|
|
|
event->setDropAction(Qt::CopyAction);
|
|
|
|
event->setWidget(view->viewport());
|
|
|
|
event->setSource(view->viewport());
|
|
|
|
event->ignore();
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::dragDrop()
|
|
|
|
{
|
|
|
|
QPushButton *button = new QPushButton; // acceptDrops(false)
|
|
|
|
QLineEdit *edit = new QLineEdit; // acceptDrops(true)
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsProxyWidget *buttonProxy = scene.addWidget(button);
|
|
|
|
QGraphicsProxyWidget *editProxy = scene.addWidget(edit);
|
|
|
|
QVERIFY(buttonProxy->acceptDrops());
|
|
|
|
QVERIFY(editProxy->acceptDrops());
|
|
|
|
|
|
|
|
button->setGeometry(0, 0, 100, 50);
|
|
|
|
edit->setGeometry(0, 60, 100, 50);
|
|
|
|
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
view.show();
|
2012-07-18 11:12:59 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QMimeData data;
|
|
|
|
data.setText("hei");
|
|
|
|
{
|
|
|
|
QGraphicsSceneDragDropEvent event(QEvent::GraphicsSceneDragEnter);
|
|
|
|
makeDndEvent(&event, &view, QPointF(50, 25));
|
|
|
|
event.setMimeData(&data);
|
|
|
|
qApp->sendEvent(&scene, &event);
|
|
|
|
QVERIFY(event.isAccepted());
|
|
|
|
}
|
|
|
|
{
|
|
|
|
QGraphicsSceneDragDropEvent event(QEvent::GraphicsSceneDragMove);
|
|
|
|
makeDndEvent(&event, &view, QPointF(50, 25));
|
|
|
|
event.setMimeData(&data);
|
|
|
|
qApp->sendEvent(&scene, &event);
|
|
|
|
QVERIFY(!event.isAccepted());
|
|
|
|
}
|
|
|
|
{
|
|
|
|
QGraphicsSceneDragDropEvent event(QEvent::GraphicsSceneDragMove);
|
|
|
|
makeDndEvent(&event, &view, QPointF(50, 75));
|
|
|
|
event.setMimeData(&data);
|
|
|
|
qApp->sendEvent(&scene, &event);
|
|
|
|
QVERIFY(event.isAccepted());
|
|
|
|
}
|
|
|
|
{
|
|
|
|
QGraphicsSceneDragDropEvent event(QEvent::GraphicsSceneDrop);
|
|
|
|
makeDndEvent(&event, &view, QPointF(50, 75));
|
|
|
|
event.setMimeData(&data);
|
|
|
|
qApp->sendEvent(&scene, &event);
|
|
|
|
QVERIFY(event.isAccepted());
|
|
|
|
}
|
|
|
|
QCOMPARE(edit->text(), QString("hei"));
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::windowFlags_data()
|
|
|
|
{
|
|
|
|
QTest::addColumn<int>("proxyFlags");
|
|
|
|
QTest::addColumn<int>("widgetFlags");
|
|
|
|
QTest::addColumn<int>("resultingProxyFlags");
|
|
|
|
QTest::addColumn<int>("resultingWidgetFlags");
|
|
|
|
|
|
|
|
QTest::newRow("proxy(0) widget(0)") << 0 << 0 << 0 << int(Qt::Window);
|
|
|
|
QTest::newRow("proxy(window)") << int(Qt::Window) << 0 << int(Qt::Window) << int(Qt::Window);
|
|
|
|
QTest::newRow("proxy(window) widget(window)") << int(Qt::Window) << int(Qt::Window) << int(Qt::Window) << int(Qt::Window);
|
|
|
|
QTest::newRow("proxy(0) widget(window)") << int(0) << int(Qt::Window) << int(0) << int(Qt::Window);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::windowFlags()
|
|
|
|
{
|
|
|
|
QFETCH(int, proxyFlags);
|
|
|
|
QFETCH(int, widgetFlags);
|
|
|
|
QFETCH(int, resultingProxyFlags);
|
|
|
|
QFETCH(int, resultingWidgetFlags);
|
|
|
|
Qt::WindowFlags proxyWFlags = Qt::WindowFlags(proxyFlags);
|
|
|
|
Qt::WindowFlags widgetWFlags = Qt::WindowFlags(widgetFlags);
|
|
|
|
Qt::WindowFlags resultingProxyWFlags = Qt::WindowFlags(resultingProxyFlags);
|
|
|
|
Qt::WindowFlags resultingWidgetWFlags = Qt::WindowFlags(resultingWidgetFlags);
|
|
|
|
|
|
|
|
QGraphicsProxyWidget proxy(0, proxyWFlags);
|
|
|
|
QVERIFY((proxy.windowFlags() & proxyWFlags) == proxyWFlags);
|
|
|
|
|
|
|
|
QWidget *widget = new QWidget(0, widgetWFlags);
|
|
|
|
QVERIFY((widget->windowFlags() & widgetWFlags) == widgetWFlags);
|
|
|
|
|
|
|
|
proxy.setWidget(widget);
|
|
|
|
|
|
|
|
if (resultingProxyFlags == 0)
|
|
|
|
QVERIFY(!proxy.windowFlags());
|
|
|
|
else
|
|
|
|
QVERIFY((proxy.windowFlags() & resultingProxyWFlags) == resultingProxyWFlags);
|
|
|
|
QVERIFY((widget->windowFlags() & resultingWidgetWFlags) == resultingWidgetWFlags);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::comboboxWindowFlags()
|
|
|
|
{
|
|
|
|
QComboBox *comboBox = new QComboBox;
|
|
|
|
comboBox->addItem("Item 1");
|
|
|
|
comboBox->addItem("Item 2");
|
|
|
|
comboBox->addItem("Item 3");
|
|
|
|
QWidget *embedWidget = comboBox;
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsProxyWidget *proxy = scene.addWidget(embedWidget);
|
|
|
|
proxy->setWindowFlags(Qt::Window);
|
|
|
|
QVERIFY(embedWidget->isWindow());
|
|
|
|
QVERIFY(proxy->isWindow());
|
|
|
|
|
|
|
|
comboBox->showPopup();
|
|
|
|
|
|
|
|
QCOMPARE(proxy->childItems().size(), 1);
|
|
|
|
QGraphicsItem *popupProxy = proxy->childItems().first();
|
|
|
|
QVERIFY(popupProxy->isWindow());
|
|
|
|
QVERIFY((static_cast<QGraphicsWidget *>(popupProxy)->windowFlags() & Qt::Popup) == Qt::Popup);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::updateAndDelete()
|
|
|
|
{
|
2012-04-17 15:30:06 +00:00
|
|
|
#ifdef Q_OS_MAC
|
|
|
|
QSKIP("Test case unstable on this platform, QTBUG-23700");
|
|
|
|
#endif
|
2011-04-27 10:05:43 +00:00
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsProxyWidget *proxy = scene.addWidget(new QPushButton("Hello World"));
|
|
|
|
View view(&scene);
|
|
|
|
view.show();
|
2012-07-18 11:12:59 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
QTRY_VERIFY(view.npaints > 0);
|
2012-04-17 15:30:06 +00:00
|
|
|
// Wait a bit to clear all pending paint events
|
|
|
|
QTest::qWait(10);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
const QRect itemDeviceBoundingRect = proxy->deviceTransform(view.viewportTransform())
|
|
|
|
.mapRect(proxy->boundingRect()).toRect();
|
|
|
|
const QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2);
|
|
|
|
|
|
|
|
view.npaints = 0;
|
|
|
|
view.paintEventRegion = QRegion();
|
|
|
|
|
|
|
|
// Update and hide.
|
|
|
|
proxy->update();
|
|
|
|
proxy->hide();
|
2012-04-17 05:29:24 +00:00
|
|
|
QTRY_COMPARE(view.npaints, 1);
|
2011-04-27 10:05:43 +00:00
|
|
|
QCOMPARE(view.paintEventRegion, expectedRegion);
|
|
|
|
|
|
|
|
proxy->show();
|
|
|
|
QTest::qWait(50);
|
|
|
|
view.npaints = 0;
|
|
|
|
view.paintEventRegion = QRegion();
|
|
|
|
|
|
|
|
// Update and delete.
|
|
|
|
proxy->update();
|
|
|
|
delete proxy;
|
|
|
|
QTRY_COMPARE(view.npaints, 1);
|
|
|
|
QCOMPARE(view.paintEventRegion, expectedRegion);
|
|
|
|
}
|
|
|
|
|
|
|
|
class InputMethod_LineEdit : public QLineEdit
|
|
|
|
{
|
|
|
|
bool event(QEvent *e)
|
|
|
|
{
|
|
|
|
if (e->type() == QEvent::InputMethod)
|
|
|
|
++inputMethodEvents;
|
|
|
|
return QLineEdit::event(e);
|
|
|
|
}
|
|
|
|
public:
|
|
|
|
int inputMethodEvents;
|
|
|
|
};
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::inputMethod()
|
|
|
|
{
|
|
|
|
QGraphicsScene scene;
|
|
|
|
|
|
|
|
// check that the proxy is initialized with the correct input method sensitivity
|
|
|
|
for (int i = 0; i < 2; ++i)
|
|
|
|
{
|
|
|
|
QLineEdit *lineEdit = new QLineEdit;
|
|
|
|
lineEdit->setAttribute(Qt::WA_InputMethodEnabled, !!i);
|
|
|
|
QGraphicsProxyWidget *proxy = scene.addWidget(lineEdit);
|
|
|
|
QCOMPARE(!!(proxy->flags() & QGraphicsItem::ItemAcceptsInputMethod), !!i);
|
|
|
|
}
|
|
|
|
|
|
|
|
// check that input method events are only forwarded to widgets with focus
|
|
|
|
for (int i = 0; i < 2; ++i)
|
|
|
|
{
|
|
|
|
InputMethod_LineEdit *lineEdit = new InputMethod_LineEdit;
|
|
|
|
lineEdit->setAttribute(Qt::WA_InputMethodEnabled, true);
|
|
|
|
QGraphicsProxyWidget *proxy = scene.addWidget(lineEdit);
|
|
|
|
|
|
|
|
if (i)
|
|
|
|
lineEdit->setFocus();
|
|
|
|
|
|
|
|
lineEdit->inputMethodEvents = 0;
|
|
|
|
QInputMethodEvent event;
|
|
|
|
qApp->sendEvent(proxy, &event);
|
|
|
|
QCOMPARE(lineEdit->inputMethodEvents, i);
|
|
|
|
}
|
|
|
|
|
|
|
|
scene.clear();
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
QWidget *w = new QWidget;
|
|
|
|
w->setLayout(new QVBoxLayout(w));
|
|
|
|
QLineEdit *lineEdit = new QLineEdit;
|
|
|
|
lineEdit->setEchoMode(QLineEdit::Password);
|
|
|
|
w->layout()->addWidget(lineEdit);
|
|
|
|
lineEdit->setAttribute(Qt::WA_InputMethodEnabled, true);
|
|
|
|
QGraphicsProxyWidget *proxy = scene.addWidget(w);
|
|
|
|
view.show();
|
2012-07-18 11:12:59 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
|
|
|
QVERIFY(!(proxy->flags() & QGraphicsItem::ItemAcceptsInputMethod));
|
2011-04-27 10:05:43 +00:00
|
|
|
lineEdit->setFocus();
|
|
|
|
QVERIFY((proxy->flags() & QGraphicsItem::ItemAcceptsInputMethod));
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::clickFocus()
|
|
|
|
{
|
|
|
|
QGraphicsScene scene;
|
|
|
|
scene.setItemIndexMethod(QGraphicsScene::NoIndex);
|
2014-07-25 08:49:38 +00:00
|
|
|
QLineEdit *le1 = new QLineEdit;
|
|
|
|
QGraphicsProxyWidget *proxy = scene.addWidget(le1);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QGraphicsView view(&scene);
|
|
|
|
|
|
|
|
{
|
|
|
|
EventSpy proxySpy(proxy);
|
|
|
|
EventSpy widgetSpy(proxy->widget());
|
|
|
|
|
|
|
|
view.setFrameStyle(0);
|
|
|
|
view.resize(300, 300);
|
|
|
|
view.show();
|
|
|
|
QApplication::setActiveWindow(&view);
|
2012-07-18 11:12:59 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QVERIFY(!proxy->hasFocus());
|
|
|
|
QVERIFY(!proxy->widget()->hasFocus());
|
|
|
|
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::FocusIn], 0);
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::FocusOut], 0);
|
|
|
|
QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 0);
|
|
|
|
QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 0);
|
|
|
|
|
|
|
|
QPointF lineEditCenter = proxy->mapToScene(proxy->boundingRect().center());
|
|
|
|
// Spontaneous mouse click sets focus on a clickable widget.
|
|
|
|
for (int retry = 0; retry < 50 && !proxy->hasFocus(); retry++)
|
|
|
|
QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(lineEditCenter));
|
|
|
|
QVERIFY(proxy->hasFocus());
|
|
|
|
QVERIFY(proxy->widget()->hasFocus());
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
|
|
|
|
scene.setFocusItem(0);
|
|
|
|
QVERIFY(!proxy->hasFocus());
|
|
|
|
QVERIFY(!proxy->widget()->hasFocus());
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::FocusOut], 1);
|
|
|
|
QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 1);
|
|
|
|
|
|
|
|
// Non-spontaneous mouse click sets focus if the widget has been clicked before
|
|
|
|
{
|
|
|
|
QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
|
|
|
|
event.setScenePos(lineEditCenter);
|
|
|
|
event.setButton(Qt::LeftButton);
|
|
|
|
qApp->sendEvent(&scene, &event);
|
|
|
|
QVERIFY(proxy->hasFocus());
|
|
|
|
QVERIFY(proxy->widget()->hasFocus());
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::FocusIn], 2);
|
|
|
|
QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
scene.setFocusItem(0);
|
|
|
|
proxy->setWidget(new QLineEdit); // resets focusWidget
|
2014-07-25 08:49:38 +00:00
|
|
|
delete le1;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
QPointF lineEditCenter = proxy->mapToScene(proxy->boundingRect().center());
|
|
|
|
EventSpy proxySpy(proxy);
|
|
|
|
EventSpy widgetSpy(proxy->widget());
|
|
|
|
QVERIFY(!proxy->hasFocus());
|
|
|
|
QVERIFY(!proxy->widget()->hasFocus());
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::FocusOut], 0);
|
|
|
|
QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 0);
|
|
|
|
|
|
|
|
// Non-spontaneous mouse click does not set focus on the embedded widget.
|
|
|
|
{
|
|
|
|
QGraphicsSceneMouseEvent event(QEvent::GraphicsSceneMousePress);
|
|
|
|
event.setScenePos(lineEditCenter);
|
|
|
|
event.setButton(Qt::LeftButton);
|
|
|
|
qApp->sendEvent(&scene, &event);
|
|
|
|
QVERIFY(!proxy->hasFocus());
|
|
|
|
QVERIFY(!proxy->widget()->hasFocus());
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::FocusIn], 0);
|
|
|
|
QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
scene.setFocusItem(0);
|
|
|
|
QVERIFY(!proxy->hasFocus());
|
|
|
|
QVERIFY(!proxy->widget()->hasFocus());
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::FocusOut], 0);
|
|
|
|
QCOMPARE(widgetSpy.counts[QEvent::FocusOut], 0);
|
|
|
|
|
|
|
|
// Spontaneous click on non-clickable widget does not give focus.
|
|
|
|
proxy->widget()->setFocusPolicy(Qt::NoFocus);
|
|
|
|
QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(lineEditCenter));
|
|
|
|
QVERIFY(!proxy->hasFocus());
|
|
|
|
QVERIFY(!proxy->widget()->hasFocus());
|
|
|
|
|
|
|
|
// Multiple clicks should only result in one FocusIn.
|
|
|
|
proxy->widget()->setFocusPolicy(Qt::StrongFocus);
|
|
|
|
scene.setFocusItem(0);
|
|
|
|
QVERIFY(!proxy->hasFocus());
|
|
|
|
QVERIFY(!proxy->widget()->hasFocus());
|
|
|
|
QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(lineEditCenter));
|
|
|
|
QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(lineEditCenter));
|
|
|
|
QVERIFY(proxy->hasFocus());
|
|
|
|
QVERIFY(proxy->widget()->hasFocus());
|
|
|
|
QCOMPARE(widgetSpy.counts[QEvent::FocusIn], 1);
|
|
|
|
QCOMPARE(proxySpy.counts[QEvent::FocusIn], 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::windowFrameMargins()
|
|
|
|
{
|
|
|
|
// Make sure the top margin is non-zero when passing Qt::Window.
|
|
|
|
QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(0, Qt::Window);
|
|
|
|
|
|
|
|
qreal left, top, right, bottom;
|
|
|
|
proxy->getWindowFrameMargins(&left, &top, &right, &bottom);
|
|
|
|
QVERIFY(top > 0);
|
|
|
|
|
|
|
|
proxy->setWidget(new QPushButton("testtest"));
|
|
|
|
proxy->getWindowFrameMargins(&left, &top, &right, &bottom);
|
|
|
|
QVERIFY(top > 0);
|
|
|
|
|
|
|
|
QGraphicsScene scene;
|
|
|
|
scene.addItem(proxy);
|
|
|
|
proxy->getWindowFrameMargins(&left, &top, &right, &bottom);
|
|
|
|
QVERIFY(top > 0);
|
|
|
|
|
|
|
|
proxy->unsetWindowFrameMargins();
|
|
|
|
proxy->getWindowFrameMargins(&left, &top, &right, &bottom);
|
|
|
|
QVERIFY(top > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
class HoverButton : public QPushButton
|
|
|
|
{
|
|
|
|
public:
|
2020-10-07 11:05:48 +00:00
|
|
|
HoverButton(QWidget *parent = nullptr) : QPushButton(parent), hoverLeaveReceived(false)
|
2011-04-27 10:05:43 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
bool hoverLeaveReceived;
|
|
|
|
|
|
|
|
bool event(QEvent* e)
|
|
|
|
{
|
|
|
|
if(QEvent::HoverLeave == e->type())
|
|
|
|
hoverLeaveReceived = true;
|
|
|
|
return QPushButton::event(e);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Scene : public QGraphicsScene
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
Scene() {
|
|
|
|
QWidget *background = new QWidget;
|
|
|
|
background->setGeometry(0, 0, 500, 500);
|
|
|
|
hoverButton = new HoverButton;
|
|
|
|
hoverButton->setParent(background);
|
|
|
|
hoverButton->setText("Second button");
|
|
|
|
hoverButton->setGeometry(10, 10, 200, 50);
|
|
|
|
addWidget(background);
|
|
|
|
|
|
|
|
QPushButton *hideButton = new QPushButton("I'm a button with a very very long text");
|
|
|
|
hideButton->setGeometry(10, 10, 400, 50);
|
|
|
|
topButton = addWidget(hideButton);
|
2017-10-31 16:07:07 +00:00
|
|
|
connect(hideButton, &QPushButton::clicked, this, [&]() { topButton->hide(); });
|
2011-04-27 10:05:43 +00:00
|
|
|
topButton->setFocus();
|
|
|
|
}
|
|
|
|
|
|
|
|
QGraphicsProxyWidget *topButton;
|
|
|
|
HoverButton *hoverButton;
|
|
|
|
};
|
|
|
|
|
|
|
|
void tst_QGraphicsProxyWidget::QTBUG_6986_sendMouseEventToAlienWidget()
|
|
|
|
{
|
2017-10-31 16:07:07 +00:00
|
|
|
if (QGuiApplication::platformName() == QLatin1String("cocoa")) {
|
|
|
|
// The "Second button" does not receive QEvent::HoverLeave
|
|
|
|
QSKIP("This test fails only on Cocoa. Investigate why. See QTBUG-69219");
|
|
|
|
}
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
QGraphicsView view;
|
|
|
|
Scene scene;
|
|
|
|
view.setScene(&scene);
|
|
|
|
view.resize(600, 600);
|
|
|
|
QApplication::setActiveWindow(&view);
|
|
|
|
view.show();
|
2012-07-30 10:36:02 +00:00
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&view));
|
2017-10-31 16:07:07 +00:00
|
|
|
|
|
|
|
QPoint topButtonTopLeftCorner = view.mapFromScene(scene.topButton->scenePos());
|
|
|
|
QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, topButtonTopLeftCorner);
|
|
|
|
// move to the bottom right corner (buttons are placed in the top left corner)
|
|
|
|
QCOMPARE(scene.hoverButton->hoverLeaveReceived, false);
|
|
|
|
QTest::mouseMove(view.viewport(), view.viewport()->rect().bottomRight());
|
2011-04-27 10:05:43 +00:00
|
|
|
QTRY_COMPARE(scene.hoverButton->hoverLeaveReceived, true);
|
|
|
|
}
|
|
|
|
|
2015-06-18 08:08:01 +00:00
|
|
|
static QByteArray msgPointMismatch(const QPoint &actual, const QPoint &expected)
|
|
|
|
{
|
|
|
|
QString result;
|
|
|
|
QDebug(&result) << actual << " != " << expected << " manhattanLength="
|
|
|
|
<< (expected - actual).manhattanLength();
|
|
|
|
return result.toLocal8Bit();
|
|
|
|
}
|
|
|
|
|
2014-10-21 10:24:52 +00:00
|
|
|
void tst_QGraphicsProxyWidget::mapToGlobal() // QTBUG-41135
|
|
|
|
{
|
|
|
|
const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
|
2016-01-21 07:15:18 +00:00
|
|
|
const QSize size = availableGeometry.size() / 4;
|
2014-10-21 10:24:52 +00:00
|
|
|
QGraphicsScene scene;
|
|
|
|
QGraphicsView view(&scene);
|
2016-01-21 07:15:18 +00:00
|
|
|
view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
|
|
view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
2015-12-22 16:15:57 +00:00
|
|
|
view.setTransform(QTransform::fromScale(2, 2)); // QTBUG-50136, use transform.
|
2014-10-21 10:24:52 +00:00
|
|
|
view.setWindowTitle(QTest::currentTestFunction());
|
|
|
|
view.resize(size);
|
|
|
|
view.move(availableGeometry.bottomRight() - QPoint(size.width(), size.height()) - QPoint(100, 100));
|
2016-01-21 07:15:18 +00:00
|
|
|
QWidget *embeddedWidget = new QGroupBox(QLatin1String("Embedded"));
|
|
|
|
embeddedWidget->setStyleSheet(QLatin1String("background-color: \"yellow\"; "));
|
|
|
|
embeddedWidget->setFixedSize((size - QSize(10, 10)) / 2);
|
|
|
|
QWidget *childWidget = new QGroupBox(QLatin1String("Child"), embeddedWidget);
|
2015-06-18 08:08:01 +00:00
|
|
|
childWidget->setStyleSheet(QLatin1String("background-color: \"red\"; "));
|
|
|
|
childWidget->resize(embeddedWidget->size() / 2);
|
|
|
|
childWidget->move(embeddedWidget->width() / 4, embeddedWidget->height() / 4); // center in embeddedWidget
|
2014-10-21 10:24:52 +00:00
|
|
|
scene.addWidget(embeddedWidget);
|
|
|
|
QApplication::setActiveWindow(&view);
|
|
|
|
view.show();
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(&view));
|
2015-06-18 08:08:01 +00:00
|
|
|
const QPoint embeddedCenter = embeddedWidget->rect().center();
|
2014-10-21 10:24:52 +00:00
|
|
|
const QPoint embeddedCenterGlobal = embeddedWidget->mapToGlobal(embeddedCenter);
|
|
|
|
QCOMPARE(embeddedWidget->mapFromGlobal(embeddedCenterGlobal), embeddedCenter);
|
|
|
|
// This should be equivalent to the view center give or take rounding
|
|
|
|
// errors due to odd window margins
|
|
|
|
const QPoint viewCenter = view.geometry().center();
|
2016-01-21 07:15:18 +00:00
|
|
|
QVERIFY2((viewCenter - embeddedCenterGlobal).manhattanLength() <= 3,
|
2015-06-18 08:08:01 +00:00
|
|
|
msgPointMismatch(embeddedCenterGlobal, viewCenter).constData());
|
|
|
|
|
2016-01-21 07:15:18 +00:00
|
|
|
// Same test with child centered on embeddedWidget. Also make sure
|
2015-12-22 16:15:57 +00:00
|
|
|
// the roundtrip maptoGlobal()/mapFromGlobal() returns the same
|
|
|
|
// point since that is important for mouse event handling (QTBUG-50030,
|
|
|
|
// QTBUG-50136).
|
2015-06-18 08:08:01 +00:00
|
|
|
const QPoint childCenter = childWidget->rect().center();
|
|
|
|
const QPoint childCenterGlobal = childWidget->mapToGlobal(childCenter);
|
|
|
|
QCOMPARE(childWidget->mapFromGlobal(childCenterGlobal), childCenter);
|
|
|
|
QVERIFY2((viewCenter - childCenterGlobal).manhattanLength() <= 4,
|
|
|
|
msgPointMismatch(childCenterGlobal, viewCenter).constData());
|
2014-10-21 10:24:52 +00:00
|
|
|
}
|
|
|
|
|
2015-02-17 08:53:27 +00:00
|
|
|
void tst_QGraphicsProxyWidget::mapToGlobalWithoutScene() // QTBUG-44509
|
|
|
|
{
|
|
|
|
QGraphicsProxyWidget proxyWidget;
|
|
|
|
QWidget *embeddedWidget = new QWidget;
|
|
|
|
proxyWidget.setWidget(embeddedWidget);
|
|
|
|
const QPoint localPos(0, 0);
|
|
|
|
const QPoint globalPos = embeddedWidget->mapToGlobal(localPos);
|
|
|
|
QCOMPARE(embeddedWidget->mapFromGlobal(globalPos), localPos);
|
|
|
|
}
|
|
|
|
|
2015-01-19 15:57:20 +00:00
|
|
|
// QTBUG_43780: Embedded widgets have isWindow()==true but showing them should not
|
|
|
|
// trigger the top-level widget code path of show() that closes all popups
|
|
|
|
// (for example combo popups).
|
|
|
|
void tst_QGraphicsProxyWidget::QTBUG_43780_visibility()
|
|
|
|
{
|
|
|
|
const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
|
|
|
|
const QSize size = availableGeometry.size() / 4;
|
|
|
|
QWidget mainWindow;
|
|
|
|
QVBoxLayout *layout = new QVBoxLayout(&mainWindow);
|
|
|
|
QComboBox *combo = new QComboBox(&mainWindow);
|
|
|
|
combo->addItems(QStringList() << "i1" << "i2" << "i3");
|
|
|
|
layout->addWidget(combo);
|
|
|
|
QGraphicsScene *scene = new QGraphicsScene(&mainWindow);
|
|
|
|
QGraphicsView *view = new QGraphicsView(scene, &mainWindow);
|
|
|
|
layout->addWidget(view);
|
|
|
|
mainWindow.setWindowTitle(QTest::currentTestFunction());
|
|
|
|
mainWindow.resize(size);
|
|
|
|
mainWindow.move(availableGeometry.topLeft()
|
|
|
|
+ QPoint(availableGeometry.width() - size.width(),
|
|
|
|
availableGeometry.height() - size.height()) / 2);
|
|
|
|
QLabel *label = new QLabel(QTest::currentTestFunction());
|
|
|
|
scene->addWidget(label);
|
|
|
|
label->hide();
|
|
|
|
mainWindow.show();
|
|
|
|
combo->setFocus();
|
|
|
|
mainWindow.activateWindow();
|
|
|
|
QVERIFY(QTest::qWaitForWindowActive(&mainWindow));
|
|
|
|
combo->showPopup();
|
|
|
|
QWidget *comboPopup = combo->view()->window();
|
|
|
|
QVERIFY(comboPopup);
|
|
|
|
QVERIFY(QTest::qWaitForWindowExposed(comboPopup));
|
|
|
|
label->show();
|
|
|
|
QTRY_VERIFY(label->isVisible());
|
|
|
|
QVERIFY(comboPopup->isVisible());
|
|
|
|
}
|
|
|
|
|
2015-09-03 16:53:53 +00:00
|
|
|
class TouchWidget : public QWidget
|
|
|
|
{
|
|
|
|
public:
|
2020-10-07 11:05:48 +00:00
|
|
|
TouchWidget(QWidget *parent = nullptr) : QWidget(parent) {}
|
2015-09-03 16:53:53 +00:00
|
|
|
|
|
|
|
bool event(QEvent *event)
|
|
|
|
{
|
|
|
|
switch (event->type()) {
|
|
|
|
case QEvent::TouchBegin:
|
|
|
|
case QEvent::TouchUpdate:
|
|
|
|
case QEvent::TouchEnd:
|
|
|
|
event->accept();
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return QWidget::event(event);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// QTBUG_45737
|
|
|
|
void tst_QGraphicsProxyWidget::forwardTouchEvent()
|
|
|
|
{
|
|
|
|
QGraphicsScene *scene = new QGraphicsScene;
|
|
|
|
|
|
|
|
TouchWidget *widget = new TouchWidget;
|
|
|
|
|
|
|
|
widget->setAttribute(Qt::WA_AcceptTouchEvents);
|
|
|
|
|
|
|
|
QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget;
|
|
|
|
|
|
|
|
proxy->setAcceptTouchEvents(true);
|
|
|
|
proxy->setWidget(widget);
|
|
|
|
|
|
|
|
scene->addItem(proxy);
|
|
|
|
|
|
|
|
QGraphicsView *view = new QGraphicsView(scene);
|
|
|
|
|
|
|
|
view->show();
|
|
|
|
|
|
|
|
EventSpy eventSpy(widget);
|
|
|
|
|
Introduce QInputDevice hierarchy; replace QTouchDevice
We have seen during the Qt 5 series that QMouseEvent::source() does
not provide enough information: if it is synthesized, it could have
come from any device for which mouse events are synthesized, not only
from a touchscreen. By providing in every QInputEvent as complete
information about the actual source device as possible, we will enable
very fine-tuned behavior in the object that handles each event.
Further, we would like to support multiple keyboards, pointing devices,
and named groups of devices that are known as "seats" in Wayland.
In Qt 5, QPA plugins registered each touchscreen as it was discovered.
Now we extend this pattern to all input devices. This new requirement
can be implemented gradually; for now, if a QTWSI input event is
received wtihout a device pointer, a default "core" device will be
created on-the-fly, and a warning emitted.
In Qt 5, QTouchEvent::TouchPoint::id() was forced to be unique even when
multiple devices were in use simultaneously. Now that each event
identifies the device it came from, this hack is no longer needed.
A stub of the new QPointerEvent is added; it will be developed further
in subsequent patches.
[ChangeLog][QtGui][QInputEvent] Every QInputEvent now carries a pointer
to an instance of QInputDevice, or the subclass QPointingDevice in case
of mouse, touch and tablet events. Each platform plugin is expected to
create the device instances, register them, and provide valid pointers
with all input events. If this is not done, warnings are emitted and
default devices are created as necessary. When the device has accurate
information, it provides the opportunity to fine-tune behavior depending
on device type and capabilities: for example if a QMouseEvent is
synthesized from a touchscreen, the recipient can see which touchscreen
it came from. Each device also has a seatName to distinguish users on
multi-user windowing systems. Touchpoint IDs are no longer unique on
their own, but the combination of ID and device is.
Fixes: QTBUG-46412
Fixes: QTBUG-72167
Task-number: QTBUG-69433
Task-number: QTBUG-52430
Change-Id: I933fb2b86182efa722037b7a33e404c5daf5292a
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2019-05-31 06:38:16 +00:00
|
|
|
QPointingDevice *device = QTest::createTouchDevice();
|
2015-09-03 16:53:53 +00:00
|
|
|
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::TouchBegin], 0);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::TouchUpdate], 0);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::TouchEnd], 0);
|
|
|
|
|
|
|
|
QTest::touchEvent(view, device).press(0, QPoint(10, 10), view);
|
|
|
|
QTest::touchEvent(view, device).move(0, QPoint(15, 15), view);
|
|
|
|
QTest::touchEvent(view, device).move(0, QPoint(16, 16), view);
|
|
|
|
QTest::touchEvent(view, device).release(0, QPoint(15, 15), view);
|
|
|
|
|
|
|
|
QApplication::processEvents();
|
|
|
|
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::TouchBegin], 1);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::TouchUpdate], 2);
|
|
|
|
QCOMPARE(eventSpy.counts[QEvent::TouchEnd], 1);
|
|
|
|
|
|
|
|
delete view;
|
|
|
|
delete proxy;
|
|
|
|
delete scene;
|
|
|
|
}
|
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
QTEST_MAIN(tst_QGraphicsProxyWidget)
|
|
|
|
#include "tst_qgraphicsproxywidget.moc"
|