summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/widgets/graphicsview/qgraphicsview.cpp27
-rw-r--r--src/widgets/graphicsview/qgraphicsview_p.h1
-rw-r--r--src/widgets/kernel/qwidget.cpp5
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp50
4 files changed, 66 insertions, 17 deletions
diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp
index 9505e2529aa..deb647a9729 100644
--- a/src/widgets/graphicsview/qgraphicsview.cpp
+++ b/src/widgets/graphicsview/qgraphicsview.cpp
@@ -885,16 +885,14 @@ void QGraphicsViewPrivate::populateSceneDragDropEvent(QGraphicsSceneDragDropEven
/*!
\internal
*/
-QRect QGraphicsViewPrivate::mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const
+QTransform QGraphicsViewPrivate::mapToViewTransform(const QGraphicsItem *item) const
{
Q_Q(const QGraphicsView);
if (dirtyScroll)
const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
- if (item->d_ptr->itemIsUntransformable()) {
- QTransform itv = item->deviceTransform(q->viewportTransform());
- return itv.mapRect(rect).toAlignedRect();
- }
+ if (item->d_ptr->itemIsUntransformable())
+ return item->deviceTransform(q->viewportTransform());
// Translate-only
// COMBINE
@@ -908,21 +906,20 @@ QRect QGraphicsViewPrivate::mapToViewRect(const QGraphicsItem *item, const QRect
offset += itemd->pos;
} while ((parentItem = itemd->parent));
- QRectF baseRect = rect.translated(offset.x(), offset.y());
+ QTransform move = QTransform::fromTranslate(offset.x(), offset.y());
if (!parentItem) {
- if (identityMatrix) {
- baseRect.translate(-scrollX, -scrollY);
- return baseRect.toAlignedRect();
- }
- return matrix.mapRect(baseRect).translated(-scrollX, -scrollY).toAlignedRect();
+ move.translate(-scrollX, -scrollY);
+ return identityMatrix ? move : matrix * move;
}
-
QTransform tr = parentItem->sceneTransform();
if (!identityMatrix)
tr *= matrix;
- QRectF r = tr.mapRect(baseRect);
- r.translate(-scrollX, -scrollY);
- return r.toAlignedRect();
+ return move * tr * QTransform::fromTranslate(-scrollX, -scrollY);
+}
+
+QRect QGraphicsViewPrivate::mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const
+{
+ return mapToViewTransform(item).mapRect(rect).toAlignedRect();
}
/*!
diff --git a/src/widgets/graphicsview/qgraphicsview_p.h b/src/widgets/graphicsview/qgraphicsview_p.h
index 7f1682becac..0a4699c9ca5 100644
--- a/src/widgets/graphicsview/qgraphicsview_p.h
+++ b/src/widgets/graphicsview/qgraphicsview_p.h
@@ -139,6 +139,7 @@ public:
void populateSceneDragDropEvent(QGraphicsSceneDragDropEvent *dest,
QDropEvent *source);
+ QTransform mapToViewTransform(const QGraphicsItem *item) const;
QRect mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const;
QRegion mapToViewRegion(const QGraphicsItem *item, const QRectF &rect) const;
QRegion dirtyRegion;
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 9b2348cad96..23e543ee3ee 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -60,6 +60,7 @@
#include "QtWidgets/qgraphicsproxywidget.h"
#include "QtWidgets/qgraphicsscene.h"
#include "private/qgraphicsproxywidget_p.h"
+#include "private/qgraphicsview_p.h"
#endif
#include "QtWidgets/qabstractscrollarea.h"
#include "private/qabstractscrollarea_p.h"
@@ -12682,8 +12683,8 @@ static MapToGlobalTransformResult mapToGlobalTransform(const QWidget *w)
if (const QGraphicsScene *scene = qgpw->scene()) {
const QList <QGraphicsView *> views = scene->views();
if (!views.isEmpty()) {
- result.transform *= qgpw->sceneTransform();
- result.transform *= views.first()->viewportTransform();
+ auto *viewP = static_cast<QGraphicsViewPrivate *>(qt_widget_private(views.constFirst()));
+ result.transform *= viewP->mapToViewTransform(qgpw);
w = views.first()->viewport();
}
}
diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
index 51f4ab90100..c7bb59a1815 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
@@ -165,6 +165,7 @@ private slots:
void QTBUG_6986_sendMouseEventToAlienWidget();
void mapToGlobal();
void mapToGlobalWithoutScene();
+ void mapToGlobalIgnoreTranformation();
void QTBUG_43780_visibility();
#if QT_CONFIG(wheelevent)
void wheelEventPropagation();
@@ -3551,6 +3552,55 @@ void tst_QGraphicsProxyWidget::mapToGlobalWithoutScene() // QTBUG-44509
QCOMPARE(embeddedWidget->mapFromGlobal(globalPos), localPos);
}
+// QTBUG-128913, QGraphicsProxyWidget with ItemIgnoresTransformations
+void tst_QGraphicsProxyWidget::mapToGlobalIgnoreTranformation()
+{
+ const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
+ const QSize size = availableGeometry.size() / 2;
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ view.setWindowTitle(QLatin1StringView(QTest::currentTestFunction()));
+ view.setAlignment(Qt::AlignLeft | Qt::AlignTop);
+ view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ view.setTransform(QTransform::fromScale(2, 2));
+ view.resize(size);
+ view.move(availableGeometry.bottomRight() - QPoint(size.width(), size.height())
+ - QPoint(100, 100));
+
+ static constexpr int labelWidth = 200;
+ static constexpr int labelHeight = 50;
+ auto *transforming = new QGraphicsProxyWidget();
+ auto *transformingLabel = new QLabel("Transforming"_L1);
+ transformingLabel->resize(labelWidth, labelHeight);
+ transforming->setWidget(transformingLabel);
+ transforming->setPos(0, 0);
+ scene.addItem(transforming);
+
+ auto *nonTransforming = new QGraphicsProxyWidget();
+ nonTransforming->setFlag(QGraphicsItem::ItemIgnoresTransformations);
+ auto *nonTransformingLabel = new QLabel("NonTransforming"_L1);
+ nonTransformingLabel->resize(labelWidth, labelHeight);
+ nonTransforming->setWidget(nonTransformingLabel);
+ nonTransforming->setPos(labelWidth, 0);
+ scene.addItem(nonTransforming);
+
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ const QPoint labelCenter{ labelWidth / 2, labelHeight / 2 };
+ const QPoint topPos = view.geometry().topLeft() + view.viewport()->geometry().topLeft();
+ const QPoint transformingGlobal = transformingLabel->mapToGlobal(labelCenter);
+ const QPoint nonTransformingGlobal = nonTransformingLabel->mapToGlobal(labelCenter);
+
+ // Center of label at 0,0 scaled by 2 should match size
+ QCOMPARE(transformingGlobal - topPos, QPoint(labelWidth, labelHeight));
+
+ // Center of non-transforming label at 200 (scaled by 2), 0
+ QCOMPARE(nonTransformingGlobal - topPos,
+ QPoint(labelWidth * 2 + labelWidth / 2, labelHeight / 2));
+}
+
// 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).