From f643b31728d82f42838b24b43ccb241d35d76e81 Mon Sep 17 00:00:00 2001 From: Nicolas Tisserand Date: Wed, 5 Dec 2012 02:12:50 +0100 Subject: Fix crash when mapping coordinates to & from the root item. The crash triggered by our (supported & documented) use-cases (calling map{From,To}Item with a null value), has been introduced earlier this year, by this change: https://qt.gitorious.org/qt/qt/commit/bec02b3f3 Also: * Clarify QDeclarativeItem::map{From,To}Item statement ordering. * Handle the engine-less item corner case. This change is a backport from the following commit in qtquick1: cae858768f7d16b79f3627cd5b077da89dc0c7c9 Change-Id: I6d387fb02ca65ab40365edda26a0ea60ff14446c Reviewed-by: Martin Jones --- src/declarative/graphicsitems/qdeclarativeitem.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index c104ac4..9d22bb4 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -2623,10 +2623,17 @@ QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, qreal x, qr return 0; } - QScriptValue sv = item.engine()->newObject(); - // If QGraphicsItem::mapFromItem() is called with 0, behaves the same as mapFromScene() QPointF p = qobject_cast(this)->mapFromItem(itemObj, x, y); + + // Use the script engine from the passed item, if available. Use this item's one otherwise. + QScriptEngine* const se = itemObj ? item.engine() : QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this)); + + // Engine-less items are unlikely, but nevertheless possible. Handle them. + if (0 == se) + return QScriptValue(QScriptValue::UndefinedValue); + + QScriptValue sv = se->newObject(); sv.setProperty(QLatin1String("x"), p.x()); sv.setProperty(QLatin1String("y"), p.y()); return sv; @@ -2661,10 +2668,17 @@ QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, qreal x, qrea return 0; } - QScriptValue sv = item.engine()->newObject(); - // If QGraphicsItem::mapToItem() is called with 0, behaves the same as mapToScene() QPointF p = qobject_cast(this)->mapToItem(itemObj, x, y); + + // Use the script engine from the passed item, if available. Use this item's one otherwise. + QScriptEngine* const se = itemObj ? item.engine() : QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this)); + + // Engine-less items are unlikely, but nevertheless possible. Handle them. + if (0 == se) + return QScriptValue(QScriptValue::UndefinedValue); + + QScriptValue sv = se->newObject(); sv.setProperty(QLatin1String("x"), p.x()); sv.setProperty(QLatin1String("y"), p.y()); return sv; -- cgit v0.12