summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2015-06-18 10:08:01 +0200
committerMarc Mutz <marc.mutz@kdab.com>2015-06-21 00:17:41 +0000
commit56aad2ad6074237537fecf10d0cda0f3872e7f71 (patch)
tree68403096ce957ab3bf097064777b98a9a50af1e4
parent54675bdf7d0332d0643f5a95ae63d60b972770ce (diff)
Fix global coordinate mapping for child widgets in QGraphicsView.
Move the code path handling widgets embedded in QGraphicsProxyWidget into the loop moving up the parent hierarchy. Add child widget to test. Task-number: QTBUG-41135 Change-Id: Ibd86413faaa927145a85a2f5864f162979135053 Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
-rw-r--r--src/widgets/kernel/qwidget.cpp46
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp25
2 files changed, 45 insertions, 26 deletions
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index e701eb07ba..88d7cdce76 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -12264,20 +12264,21 @@ QPaintEngine *QWidget::paintEngine() const
*/
QPoint QWidget::mapToGlobal(const QPoint &pos) const
{
-#ifndef QT_NO_GRAPHICSVIEW
- Q_D(const QWidget);
- if (d->extra && d->extra->proxyWidget && d->extra->proxyWidget->scene()) {
- const QList <QGraphicsView *> views = d->extra->proxyWidget->scene()->views();
- if (!views.isEmpty()) {
- const QPointF scenePos = d->extra->proxyWidget->mapToScene(pos);
- const QPoint viewPortPos = views.first()->mapFromScene(scenePos);
- return views.first()->viewport()->mapToGlobal(viewPortPos);
- }
- }
-#endif // !QT_NO_GRAPHICSVIEW
int x = pos.x(), y = pos.y();
const QWidget *w = this;
while (w) {
+#ifndef QT_NO_GRAPHICSVIEW
+ const QWidgetPrivate *d = w->d_func();
+ if (d->extra && d->extra->proxyWidget && d->extra->proxyWidget->scene()) {
+ const QList <QGraphicsView *> views = d->extra->proxyWidget->scene()->views();
+ if (!views.isEmpty()) {
+ const QPointF scenePos = d->extra->proxyWidget->mapToScene(QPoint(x, y));
+ const QPoint viewPortPos = views.first()->mapFromScene(scenePos);
+ return views.first()->viewport()->mapToGlobal(viewPortPos);
+ }
+ }
+#endif // !QT_NO_GRAPHICSVIEW
+
QWindow *window = w->windowHandle();
if (window && window->handle())
return window->mapToGlobal(QPoint(x, y));
@@ -12299,20 +12300,21 @@ QPoint QWidget::mapToGlobal(const QPoint &pos) const
*/
QPoint QWidget::mapFromGlobal(const QPoint &pos) const
{
-#ifndef QT_NO_GRAPHICSVIEW
- Q_D(const QWidget);
- if (d->extra && d->extra->proxyWidget && d->extra->proxyWidget->scene()) {
- const QList <QGraphicsView *> views = d->extra->proxyWidget->scene()->views();
- if (!views.isEmpty()) {
- const QPoint viewPortPos = views.first()->viewport()->mapFromGlobal(pos);
- const QPointF scenePos = views.first()->mapToScene(viewPortPos);
- return d->extra->proxyWidget->mapFromScene(scenePos).toPoint();
- }
- }
-#endif // !QT_NO_GRAPHICSVIEW
int x = pos.x(), y = pos.y();
const QWidget *w = this;
while (w) {
+#ifndef QT_NO_GRAPHICSVIEW
+ const QWidgetPrivate *d = w->d_func();
+ if (d->extra && d->extra->proxyWidget && d->extra->proxyWidget->scene()) {
+ const QList <QGraphicsView *> views = d->extra->proxyWidget->scene()->views();
+ if (!views.isEmpty()) {
+ const QPoint viewPortPos = views.first()->viewport()->mapFromGlobal(QPoint(x, y));
+ const QPointF scenePos = views.first()->mapToScene(viewPortPos);
+ return d->extra->proxyWidget->mapFromScene(scenePos).toPoint();
+ }
+ }
+#endif // !QT_NO_GRAPHICSVIEW
+
QWindow *window = w->windowHandle();
if (window && window->handle())
return window->mapFromGlobal(QPoint(x, y));
diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
index f8d852888c..cd40c5541c 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
@@ -3670,6 +3670,14 @@ void tst_QGraphicsProxyWidget::QTBUG_6986_sendMouseEventToAlienWidget()
QTRY_COMPARE(scene.hoverButton->hoverLeaveReceived, true);
}
+static QByteArray msgPointMismatch(const QPoint &actual, const QPoint &expected)
+{
+ QString result;
+ QDebug(&result) << actual << " != " << expected << " manhattanLength="
+ << (expected - actual).manhattanLength();
+ return result.toLocal8Bit();
+}
+
void tst_QGraphicsProxyWidget::mapToGlobal() // QTBUG-41135
{
const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
@@ -3681,20 +3689,29 @@ void tst_QGraphicsProxyWidget::mapToGlobal() // QTBUG-41135
view.move(availableGeometry.bottomRight() - QPoint(size.width(), size.height()) - QPoint(100, 100));
QWidget *embeddedWidget = new QWidget;
embeddedWidget->setFixedSize(size / 2);
+ QWidget *childWidget = new QWidget(embeddedWidget);
+ childWidget->setStyleSheet(QLatin1String("background-color: \"red\"; "));
+ childWidget->resize(embeddedWidget->size() / 2);
+ childWidget->move(embeddedWidget->width() / 4, embeddedWidget->height() / 4); // center in embeddedWidget
scene.addWidget(embeddedWidget);
QApplication::setActiveWindow(&view);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
- const QPoint embeddedCenter = embeddedWidget->geometry().center();
+ const QPoint embeddedCenter = embeddedWidget->rect().center();
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();
QVERIFY2((viewCenter - embeddedCenterGlobal).manhattanLength() <= 2,
- qPrintable(QStringLiteral("%1, %2 != %3, %4")
- .arg(viewCenter.x()).arg(viewCenter.y())
- .arg(embeddedCenterGlobal.x()).arg(embeddedCenterGlobal.y())));
+ msgPointMismatch(embeddedCenterGlobal, viewCenter).constData());
+
+ // Same test with child centered on embeddedWidget
+ 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());
}
void tst_QGraphicsProxyWidget::mapToGlobalWithoutScene() // QTBUG-44509