From 5345306c9a0a3b10dbf640253b8b2287c762b081 Mon Sep 17 00:00:00 2001
From: Thierry Bastian <thierry.bastian@nokia.com>
Date: Tue, 26 May 2009 11:36:16 +0200
Subject: Fixed a bug in animation when you set a start value that doesn't have
 the same type as the property

For example, if you set a start value of 0 (integer) for a qreal
animation, it would not work.

Reviewed-by: janarve
---
 src/corelib/animation/qvariantanimation.cpp        | 10 ++-
 .../qpropertyanimation/tst_qpropertyanimation.cpp  | 77 ++++++++++++++++------
 2 files changed, 65 insertions(+), 22 deletions(-)

diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp
index 4542a86..239add9 100644
--- a/src/corelib/animation/qvariantanimation.cpp
+++ b/src/corelib/animation/qvariantanimation.cpp
@@ -179,10 +179,14 @@ void QVariantAnimationPrivate::convertValues(int t)
     //this ensures that all the keyValues are of type t
     for (int i = 0; i < keyValues.count(); ++i) {
         QVariantAnimation::KeyValue &pair = keyValues[i];
-        if (pair.second.userType() != t)
-            pair.second.convert(static_cast<QVariant::Type>(t));
+        pair.second.convert(static_cast<QVariant::Type>(t));
     }
-    interpolator = 0; // if the type changed we need to update the interpolator
+    //we also need update to the current interval if needed
+    currentInterval.start.second.convert(static_cast<QVariant::Type>(t));
+    currentInterval.end.second.convert(static_cast<QVariant::Type>(t));
+
+    //... and the interpolator
+    interpolator = 0;
 }
 
 /*!
diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp
index 7e910d4..0aeac91 100644
--- a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp
+++ b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp
@@ -63,6 +63,18 @@ protected:
     }
 };
 
+class MyObject : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(qreal x READ x WRITE setX) 
+public:
+    MyObject() : m_x(0) { }
+    qreal x() const { return m_x; }
+    void setX(qreal x) { m_x = x; }
+private:
+    qreal m_x;
+};
+
 class tst_QPropertyAnimation : public QObject
 {
   Q_OBJECT
@@ -92,6 +104,7 @@ private slots:
     void startWithoutStartValue();
     void playForwardBackward();
     void interpolated();
+    void setStartEndValues_data();
     void setStartEndValues();
     void zeroDurationStart();
     void operationsInStates_data();
@@ -283,7 +296,7 @@ void tst_QPropertyAnimation::statesAndSignals()
 void tst_QPropertyAnimation::deletion1()
 {
     QObject *object = new QWidget;
-    QPointer<QPropertyAnimation> anim = new QPropertyAnimation(object,"minimumWidth");
+    QPointer<QPropertyAnimation> anim = new QPropertyAnimation(object, "minimumWidth");
 
     //test that the animation is deleted correctly depending of the deletion flag passed in start()
     QSignalSpy runningSpy(anim, SIGNAL(stateChanged(QAbstractAnimation::State, QAbstractAnimation::State)));
@@ -686,52 +699,78 @@ void tst_QPropertyAnimation::interpolated()
     }
 }
 
+Q_DECLARE_METATYPE(QVariant)
+
+void tst_QPropertyAnimation::setStartEndValues_data()
+{
+    QTest::addColumn<QByteArray>("propertyName");
+    QTest::addColumn<QVariant>("initialValue");
+    QTest::addColumn<QVariant>("startValue");
+    QTest::addColumn<QVariant>("endValue");
+
+    QTest::newRow("dynamic property")  << QByteArray("ole") << QVariant(42) << QVariant(0) << QVariant(10);
+    QTest::newRow("real property, with unmatching types") << QByteArray("x") << QVariant(42.) << QVariant(0) << QVariant(10.);
+}
+
 void tst_QPropertyAnimation::setStartEndValues()
 {
+    MyObject object;
+    QFETCH(QByteArray, propertyName);
+    QFETCH(QVariant, initialValue);
+    QFETCH(QVariant, startValue);
+    QFETCH(QVariant, endValue);
+
     //this tests the start value, end value and default start value
-    QObject o;
-    o.setProperty("ole", 42);
-    QPropertyAnimation anim(&o, "ole");
+    object.setProperty(propertyName, initialValue);
+    QPropertyAnimation anim(&object, propertyName);
     QVariantAnimation::KeyValues values;
     QCOMPARE(anim.keyValues(), values);
 
     //let's add a start value
-    anim.setStartValue(0);
-    values << QVariantAnimation::KeyValue(0, 0);
+    anim.setStartValue(startValue);
+    values << QVariantAnimation::KeyValue(0, startValue);
     QCOMPARE(anim.keyValues(), values);
 
-    anim.setEndValue(10);
-    values << QVariantAnimation::KeyValue(1, 10);
+    anim.setEndValue(endValue);
+    values << QVariantAnimation::KeyValue(1, endValue);
     QCOMPARE(anim.keyValues(), values);
 
     //now we can play with objects
-    QCOMPARE(o.property("ole").toInt(), 42);
-    QCOMPARE(o.property("ole").toInt(), 42);
+    QCOMPARE(object.property(propertyName).toDouble(), initialValue.toDouble());
     anim.start();
     QVERIFY(anim.startValue().isValid());
-    QCOMPARE(o.property("ole"), anim.startValue());
+    QCOMPARE(object.property(propertyName), anim.startValue());
+    anim.setCurrentTime(anim.duration()/2);
+    QCOMPARE(object.property(propertyName).toDouble(), (startValue.toDouble() + endValue.toDouble())/2 ); //just in the middle of the animation
+    anim.setCurrentTime(anim.duration()); //we go to the end of the animation
+    QCOMPARE(anim.state(), QAnimationGroup::Stopped); //it should have stopped
+    QVERIFY(anim.endValue().isValid());
+    QCOMPARE(object.property(propertyName), anim.endValue()); //end of the animations
 
     //now we remove the explicit start value and test the implicit one
     anim.stop();
-    o.setProperty("ole", 42);
+    object.setProperty(propertyName, initialValue);
+
+    //let's reset the start value
     values.remove(0);
-    anim.setStartValue(QVariant()); //reset the start value
+    anim.setStartValue(QVariant());
     QCOMPARE(anim.keyValues(), values);
     QVERIFY(!anim.startValue().isValid());
+
     anim.start();
-    QCOMPARE(o.property("ole").toInt(), 42);
+    QCOMPARE(object.property(propertyName), initialValue);
     anim.setCurrentTime(anim.duration()/2);
-    QCOMPARE(o.property("ole").toInt(), 26); //just in the middle of the animation
-    anim.setCurrentTime(anim.duration());
+    QCOMPARE(object.property(propertyName).toDouble(), (initialValue.toDouble() + endValue.toDouble())/2 ); //just in the middle of the animation
+    anim.setCurrentTime(anim.duration()); //we go to the end of the animation
     QCOMPARE(anim.state(), QAnimationGroup::Stopped); //it should have stopped
     QVERIFY(anim.endValue().isValid());
-    QCOMPARE(o.property("ole"), anim.endValue()); //end of the animations
+    QCOMPARE(object.property(propertyName), anim.endValue()); //end of the animations
 
     //now we set back the startValue
-    anim.setStartValue(5);
+    anim.setStartValue(startValue);
     QVERIFY(anim.startValue().isValid());
     anim.start();
-    QCOMPARE(o.property("ole").toInt(), 5);
+    QCOMPARE(object.property(propertyName), startValue);
 }
 
 void tst_QPropertyAnimation::zeroDurationStart()
-- 
cgit v0.12