From e333c1ac2d0e68a1820073e8f68f467fc73863b3 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 8 Dec 2015 12:50:08 +0100 Subject: Don't warn about non-existent default properties when one was found When at least one default property of a target object is considered valid by an animation, we don't need to warn about other default properties that weren't found. Change-Id: I648f17a55fdfcbed2b4c7e94d88206c3dc3d1a32 Task-number: QTBUG-22141 Reviewed-by: Michael Brasser --- src/quick/util/qquickanimation.cpp | 33 +++++++++++++++++++--- src/quick/util/qquickanimation_p_p.h | 2 +- .../data/defaultRotationAnimation.qml | 14 +++++++++ .../qquickanimations/tst_qquickanimations.cpp | 20 +++++++++++++ 4 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 tests/auto/quick/qquickanimations/data/defaultRotationAnimation.qml diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp index 1d0dbf64b3..22bfd7aef1 100644 --- a/src/quick/util/qquickanimation.cpp +++ b/src/quick/util/qquickanimation.cpp @@ -178,14 +178,22 @@ void QQuickAbstractAnimationPrivate::commence() } } -QQmlProperty QQuickAbstractAnimationPrivate::createProperty(QObject *obj, const QString &str, QObject *infoObj) +QQmlProperty QQuickAbstractAnimationPrivate::createProperty(QObject *obj, const QString &str, QObject *infoObj, QString *errorMessage) { QQmlProperty prop(obj, str, qmlContext(infoObj)); if (!prop.isValid()) { - qmlInfo(infoObj) << QQuickAbstractAnimation::tr("Cannot animate non-existent property \"%1\"").arg(str); + const QString message = QQuickAbstractAnimation::tr("Cannot animate non-existent property \"%1\"").arg(str); + if (errorMessage) + *errorMessage = message; + else + qmlInfo(infoObj) << message; return QQmlProperty(); } else if (!prop.isWritable()) { - qmlInfo(infoObj) << QQuickAbstractAnimation::tr("Cannot animate read-only property \"%1\"").arg(str); + const QString message = QQuickAbstractAnimation::tr("Cannot animate read-only property \"%1\"").arg(str); + if (errorMessage) + *errorMessage = message; + else + qmlInfo(infoObj) << message; return QQmlProperty(); } return prop; @@ -2584,18 +2592,28 @@ QQuickStateActions QQuickPropertyAnimation::createTransitionActions(QQuickStateA if (defaultTarget && targets.isEmpty()) targets << defaultTarget; + bool usingDefaultProperties = false; if (props.isEmpty() && !d->defaultProperties.isEmpty()) { props << d->defaultProperties.split(QLatin1Char(',')); + usingDefaultProperties = true; } bool hasExplicit = false; //an explicit animation has been specified if (d->toIsDefined) { + QVector errorMessages; + bool successfullyCreatedDefaultProperty = false; + for (int i = 0; i < props.count(); ++i) { for (int j = 0; j < targets.count(); ++j) { QQuickStateAction myAction; - myAction.property = d->createProperty(targets.at(j), props.at(i), this); + QString errorMessage; + const QString propertyName = props.at(i); + myAction.property = d->createProperty(targets.at(j), propertyName, this, &errorMessage); if (myAction.property.isValid()) { + if (usingDefaultProperties) + successfullyCreatedDefaultProperty = true; + if (d->fromIsDefined) { myAction.fromValue = d->from; d->convertVariant(myAction.fromValue, d->interpolatorType ? d->interpolatorType : myAction.property.propertyType()); @@ -2612,9 +2630,16 @@ QQuickStateActions QQuickPropertyAnimation::createTransitionActions(QQuickStateA break; //### any chance there could be multiples? } } + } else { + errorMessages.append(errorMessage); } } } + + if (!successfullyCreatedDefaultProperty) { + foreach (const QString &errorMessage, errorMessages) + qmlInfo(this) << errorMessage; + } } if (!hasExplicit) diff --git a/src/quick/util/qquickanimation_p_p.h b/src/quick/util/qquickanimation_p_p.h index b40e198cc1..a5960f5696 100644 --- a/src/quick/util/qquickanimation_p_p.h +++ b/src/quick/util/qquickanimation_p_p.h @@ -193,7 +193,7 @@ public: QQuickAnimationGroup *group; QAbstractAnimationJob* animationInstance; - static QQmlProperty createProperty(QObject *obj, const QString &str, QObject *infoObj); + static QQmlProperty createProperty(QObject *obj, const QString &str, QObject *infoObj, QString *errorMessage = Q_NULLPTR); }; class QQuickPauseAnimationPrivate : public QQuickAbstractAnimationPrivate diff --git a/tests/auto/quick/qquickanimations/data/defaultRotationAnimation.qml b/tests/auto/quick/qquickanimations/data/defaultRotationAnimation.qml new file mode 100644 index 0000000000..94692add60 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/defaultRotationAnimation.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + id: rect + + RotationAnimation { + target: rect + from: 0 + to: 360 + running: true + duration: 1000 + loops: Animation.Infinite + } +} diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp index d234cd2d94..5cad68b275 100644 --- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp +++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp @@ -105,6 +105,7 @@ private slots: void groupAnimationNullChildBug(); void scriptActionCrash(); void animatorInvalidTargetCrash(); + void defaultPropertyWarning(); }; #define QTIMED_COMPARE(lhs, rhs) do { \ @@ -1508,6 +1509,25 @@ void tst_qquickanimations::animatorInvalidTargetCrash() delete obj; } +Q_DECLARE_METATYPE(QList) + +// QTBUG-22141 +void tst_qquickanimations::defaultPropertyWarning() +{ + QQmlEngine engine; + + qRegisterMetaType >(); + + QSignalSpy warnings(&engine, SIGNAL(warnings(QList))); + QVERIFY(warnings.isValid()); + + QQmlComponent component(&engine, testFileUrl("defaultRotationAnimation.qml")); + QScopedPointer root(qobject_cast(component.create())); + QVERIFY(root); + + QVERIFY(warnings.isEmpty()); +} + QTEST_MAIN(tst_qquickanimations) #include "tst_qquickanimations.moc" -- cgit v1.2.3