From 37aef8c7d55d3f5bf036d66613e87f89fcd9b897 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Fri, 6 Nov 2009 15:33:45 +1000 Subject: Fix crash when using anchors inside a positioner. Task-number: QTBUG-5428 --- .../graphicsitems/qmlgraphicsanchors.cpp | 47 +++++++++++++++------- .../graphicsitems/qmlgraphicsanchors_p_p.h | 4 +- tests/auto/declarative/anchors/data/crash1.qml | 11 +++++ tests/auto/declarative/anchors/tst_anchors.cpp | 15 +++++++ 4 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 tests/auto/declarative/anchors/data/crash1.qml diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp index 404daad..f6dc5fd 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp @@ -152,13 +152,23 @@ void QmlGraphicsAnchorsPrivate::fillChanged() if (!fill || !isItemComplete()) return; - if (fill == item->parentItem()) { //child-parent - setItemPos(QPointF(leftMargin, topMargin)); - } else if (fill->parentItem() == item->parentItem()) { //siblings - setItemPos(QPointF(fill->x()+leftMargin, fill->y()+topMargin)); + if (updatingFill < 2) { + ++updatingFill; + + if (fill == item->parentItem()) { //child-parent + setItemPos(QPointF(leftMargin, topMargin)); + } else if (fill->parentItem() == item->parentItem()) { //siblings + setItemPos(QPointF(fill->x()+leftMargin, fill->y()+topMargin)); + } + setItemWidth(fill->width()-leftMargin-rightMargin); + setItemHeight(fill->height()-topMargin-bottomMargin); + + --updatingFill; + } else { + // ### Make this certain :) + qmlInfo(QmlGraphicsAnchors::tr("Possible anchor loop detected on fill."), item); } - setItemWidth(fill->width()-leftMargin-rightMargin); - setItemHeight(fill->height()-topMargin-bottomMargin); + } void QmlGraphicsAnchorsPrivate::centerInChanged() @@ -166,16 +176,25 @@ void QmlGraphicsAnchorsPrivate::centerInChanged() if (!centerIn || fill || !isItemComplete()) return; - if (centerIn == item->parentItem()) { - QPointF p((item->parentItem()->width() - item->width()) / 2., - (item->parentItem()->height() - item->height()) / 2.); - setItemPos(p); + if (updatingCenterIn < 2) { + ++updatingCenterIn; - } else if (centerIn->parentItem() == item->parentItem()) { + if (centerIn == item->parentItem()) { + QPointF p((item->parentItem()->width() - item->width()) / 2., + (item->parentItem()->height() - item->height()) / 2.); + setItemPos(p); - QPointF p(centerIn->x() + (centerIn->width() - item->width()) / 2., - centerIn->y() + (centerIn->height() - item->height()) / 2.); - setItemPos(p); + } else if (centerIn->parentItem() == item->parentItem()) { + + QPointF p(centerIn->x() + (centerIn->width() - item->width()) / 2., + centerIn->y() + (centerIn->height() - item->height()) / 2.); + setItemPos(p); + } + + --updatingCenterIn; + } else { + // ### Make this certain :) + qmlInfo(QmlGraphicsAnchors::tr("Possible anchor loop detected on centerIn."), item); } } diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h b/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h index 5f8b2c1..d21d9c5 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h @@ -89,7 +89,7 @@ class QmlGraphicsAnchorsPrivate : public QObjectPrivate public: QmlGraphicsAnchorsPrivate() : updatingMe(false), updatingHorizontalAnchor(0), - updatingVerticalAnchor(0), item(0), usedAnchors(0), fill(0), + updatingVerticalAnchor(0), updatingFill(0), updatingCenterIn(0), item(0), usedAnchors(0), fill(0), centerIn(0), leftMargin(0), rightMargin(0), topMargin(0), bottomMargin(0), vCenterOffset(0), hCenterOffset(0), baselineOffset(0), componentComplete(true) @@ -109,6 +109,8 @@ public: bool updatingMe; int updatingHorizontalAnchor; int updatingVerticalAnchor; + int updatingFill; + int updatingCenterIn; void setItemHeight(qreal); void setItemWidth(qreal); diff --git a/tests/auto/declarative/anchors/data/crash1.qml b/tests/auto/declarative/anchors/data/crash1.qml new file mode 100644 index 0000000..fd9dc55 --- /dev/null +++ b/tests/auto/declarative/anchors/data/crash1.qml @@ -0,0 +1,11 @@ +import Qt 4.6 + +Column { + Text { + text: "foo" + anchors.fill: parent + } + Text { + text: "bar" + } +} diff --git a/tests/auto/declarative/anchors/tst_anchors.cpp b/tests/auto/declarative/anchors/tst_anchors.cpp index c3a857c..4c85d2d 100644 --- a/tests/auto/declarative/anchors/tst_anchors.cpp +++ b/tests/auto/declarative/anchors/tst_anchors.cpp @@ -62,6 +62,7 @@ private slots: void illegalSets(); void reset(); void nullItem(); + void crash1(); }; /* @@ -248,6 +249,20 @@ void tst_anchors::nullItem() item->anchors()->setBottom(anchor); } +void tst_anchors::crash1() +{ + QmlView *view = new QmlView; + + view->setUrl(QUrl("file://" SRCDIR "/data/crash1.qml")); + + QString expect = "QML QmlGraphicsText (" + view->url().toString() + ":4:5" + ") Possible anchor loop detected on fill."; + QTest::ignoreMessage(QtWarningMsg, expect.toLatin1()); + view->execute(); + qApp->processEvents(); + + delete view; +} + QTEST_MAIN(tst_anchors) #include "tst_anchors.moc" -- cgit v0.12