Fix inconsistent playing / paused property setting and signals
authorDamian Jansen <damian.jansen@nokia.com>
Thu, 19 Jul 2012 04:09:47 +0000 (14:09 +1000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 25 Jul 2012 02:09:33 +0000 (04:09 +0200)
Playing should only indicate false if it has been set as such
in code, or in the event of a valid image but non-movie being
used.
Noted the edge case in documentation.
Signals were not being emitted for playing/paused in the cases
where an image was not loaded. Paused property was also being
incorrectly assigned, which supressed pause behavior.

Task-number: QTBUG-26478
Change-Id: I1aaab9b7c495811114b30b491a900804a75d590f
Reviewed-by: Alan Alpert <alan.alpert@nokia.com>
src/quick/items/qquickanimatedimage.cpp
src/quick/items/qquickanimatedimage_p_p.h
tests/auto/quick/qquickanimatedimage/data/green.png [new file with mode: 0644]
tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp

index fec5a02..d10148b 100644 (file)
@@ -148,7 +148,7 @@ bool QQuickAnimatedImage::isPaused() const
 {
     Q_D(const QQuickAnimatedImage);
     if (!d->_movie)
-        return false;
+        return d->paused;
     return d->_movie->state()==QMovie::Paused;
 }
 
@@ -157,10 +157,12 @@ void QQuickAnimatedImage::setPaused(bool pause)
     Q_D(QQuickAnimatedImage);
     if (pause == d->paused)
         return;
-    d->paused = pause;
-    if (!d->_movie)
-        return;
-    d->_movie->setPaused(pause);
+    if (!d->_movie) {
+        d->paused = pause;
+        emit pausedChanged();
+    } else {
+        d->_movie->setPaused(pause);
+    }
 }
 
 /*!
@@ -169,13 +171,23 @@ void QQuickAnimatedImage::setPaused(bool pause)
 
   By default, this property is true, meaning that the animation
   will start playing immediately.
+
+  \b Note: this property is affected by changes to the actual playing
+  state of AnimatedImage. If non-animated images are used, \a playing
+  will need to be manually set to \a true in order to animate
+  following images.
+  \qml
+  AnimatedImage {
+      onStatusChanged: playing = (status == AnimatedImage.Ready)
+  }
+  \endqml
 */
 
 bool QQuickAnimatedImage::isPlaying() const
 {
     Q_D(const QQuickAnimatedImage);
     if (!d->_movie)
-        return false;
+        return d->playing;
     return d->_movie->state()!=QMovie::NotRunning;
 }
 
@@ -184,9 +196,11 @@ void QQuickAnimatedImage::setPlaying(bool play)
     Q_D(QQuickAnimatedImage);
     if (play == d->playing)
         return;
-    d->playing = play;
-    if (!d->_movie)
+    if (!d->_movie) {
+        d->playing = play;
+        emit playingChanged();
         return;
+    }
     if (play)
         d->_movie->start();
     else
@@ -240,6 +254,7 @@ void QQuickAnimatedImage::setSource(const QUrl &url)
         d->reply = 0;
     }
 
+    d->oldPlaying = isPlaying();
     if (d->_movie) {
         delete d->_movie;
         d->_movie = 0;
@@ -270,6 +285,8 @@ void QQuickAnimatedImage::load()
             d->oldSourceSize = sourceSize();
             emit sourceSizeChanged();
         }
+        if (isPlaying() != d->oldPlaying)
+            emit playingChanged();
     } else {
         QString lf = QQmlFile::urlToLocalFileOrQrc(d->url);
         if (!lf.isEmpty()) {
@@ -334,6 +351,8 @@ void QQuickAnimatedImage::movieRequestFinished()
             d->oldSourceSize = sourceSize();
             emit sourceSizeChanged();
         }
+        if (isPlaying() != d->oldPlaying)
+            emit playingChanged();
         return;
     }
 
@@ -350,10 +369,12 @@ void QQuickAnimatedImage::movieRequestFinished()
         d->progress = 1.0;
         emit progressChanged(d->progress);
     }
-    if (d->playing)
-        d->_movie->start();
 
-    if (d->paused)
+    bool pausedAtStart = d->paused;
+    if (d->playing) {
+        d->_movie->start();
+    }
+    if (pausedAtStart)
         d->_movie->setPaused(true);
     if (d->paused || !d->playing) {
         d->_movie->jumpToFrame(d->preset_currentframe);
@@ -361,6 +382,8 @@ void QQuickAnimatedImage::movieRequestFinished()
     }
     d->setImage(d->_movie->currentPixmap().toImage());
 
+    if (isPlaying() != d->oldPlaying)
+        emit playingChanged();
     if (sourceSize() != d->oldSourceSize) {
         d->oldSourceSize = sourceSize();
         emit sourceSizeChanged();
@@ -386,7 +409,7 @@ void QQuickAnimatedImage::playingStatusChanged()
         emit playingChanged();
     }
     if ((d->_movie->state() == QMovie::Paused) != d->paused) {
-        d->playing = (d->_movie->state() == QMovie::Paused);
+        d->paused = (d->_movie->state() == QMovie::Paused);
         emit pausedChanged();
     }
 }
@@ -401,7 +424,6 @@ QSize QQuickAnimatedImage::sourceSize()
 
 void QQuickAnimatedImage::componentComplete()
 {
-    Q_D(QQuickAnimatedImage);
     QQuickItem::componentComplete(); // NOT QQuickImage
     load();
 }
index 95142f5..3aec63d 100644 (file)
@@ -78,6 +78,7 @@ public:
     QMovie *_movie;
     QNetworkReply *reply;
     int redirectCount;
+    bool oldPlaying;
 };
 
 QT_END_NAMESPACE
diff --git a/tests/auto/quick/qquickanimatedimage/data/green.png b/tests/auto/quick/qquickanimatedimage/data/green.png
new file mode 100644 (file)
index 0000000..0a2e153
Binary files /dev/null and b/tests/auto/quick/qquickanimatedimage/data/green.png differ
index c527ded..b8749c1 100644 (file)
@@ -77,6 +77,7 @@ private slots:
     void invalidSource();
     void qtbug_16520();
     void progressAndStatusChanges();
+    void playingAndPausedChanges();
 };
 
 void tst_qquickanimatedimage::cleanup()
@@ -115,7 +116,7 @@ void tst_qquickanimatedimage::stopped()
     QQmlComponent component(&engine, testFileUrl("stickmanstopped.qml"));
     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
     QVERIFY(anim);
-    QVERIFY(!anim->isPlaying());
+    QTRY_VERIFY(!anim->isPlaying());
     QCOMPARE(anim->currentFrame(), 0);
 
     delete anim;
@@ -303,11 +304,11 @@ void tst_qquickanimatedimage::invalidSource()
     QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
     QVERIFY(anim);
 
-    QVERIFY(!anim->isPlaying());
+    QVERIFY(anim->isPlaying());
     QVERIFY(!anim->isPaused());
     QCOMPARE(anim->currentFrame(), 0);
     QCOMPARE(anim->frameCount(), 0);
-    QTRY_VERIFY(anim->status() == 3);
+    QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Error);
 
     delete anim;
 }
@@ -459,6 +460,73 @@ void tst_qquickanimatedimage::progressAndStatusChanges()
     delete obj;
 }
 
+void tst_qquickanimatedimage::playingAndPausedChanges()
+{
+    QQmlEngine engine;
+    QString componentStr = "import QtQuick 2.0\nAnimatedImage { source: srcImage }";
+    QQmlContext *ctxt = engine.rootContext();
+    ctxt->setContextProperty("srcImage", QUrl(""));
+    QQmlComponent component(&engine);
+    component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickAnimatedImage *obj = qobject_cast<QQuickAnimatedImage*>(component.create());
+    QVERIFY(obj != 0);
+    QVERIFY(obj->status() == QQuickAnimatedImage::Null);
+    QTRY_VERIFY(obj->isPlaying());
+    QTRY_VERIFY(!obj->isPaused());
+    QSignalSpy playingSpy(obj, SIGNAL(playingChanged()));
+    QSignalSpy pausedSpy(obj, SIGNAL(pausedChanged()));
+
+    // initial state
+    obj->setProperty("playing", true);
+    obj->setProperty("paused", false);
+    QTRY_VERIFY(obj->isPlaying());
+    QTRY_VERIFY(!obj->isPaused());
+    QTRY_COMPARE(playingSpy.count(), 0);
+    QTRY_COMPARE(pausedSpy.count(), 0);
+
+    obj->setProperty("playing", false);
+    obj->setProperty("paused", true);
+    QTRY_VERIFY(!obj->isPlaying());
+    QTRY_VERIFY(obj->isPaused());
+    QTRY_COMPARE(playingSpy.count(), 1);
+    QTRY_COMPARE(pausedSpy.count(), 1);
+
+    obj->setProperty("playing", true);
+    obj->setProperty("paused", false);
+    QTRY_VERIFY(obj->isPlaying());
+    QTRY_VERIFY(!obj->isPaused());
+    QTRY_COMPARE(playingSpy.count(), 2);
+    QTRY_COMPARE(pausedSpy.count(), 2);
+
+    ctxt->setContextProperty("srcImage", testFileUrl("stickman.gif"));
+    QTRY_VERIFY(obj->isPlaying());
+    QTRY_VERIFY(!obj->isPaused());
+    QTRY_COMPARE(playingSpy.count(), 2);
+    QTRY_COMPARE(pausedSpy.count(), 2);
+
+    obj->setProperty("paused", true);
+    QTRY_VERIFY(obj->isPlaying());
+    QTRY_VERIFY(obj->isPaused());
+    QTRY_COMPARE(playingSpy.count(), 2);
+    QTRY_COMPARE(pausedSpy.count(), 3);
+
+    obj->setProperty("playing", false);
+    QTRY_VERIFY(!obj->isPlaying());
+    QTRY_VERIFY(!obj->isPaused());
+    QTRY_COMPARE(playingSpy.count(), 3);
+    QTRY_COMPARE(pausedSpy.count(), 4);
+
+    obj->setProperty("playing", true);
+
+    // Cannot animate this image, playing will be false
+    ctxt->setContextProperty("srcImage", testFileUrl("green.png"));
+    QTRY_VERIFY(!obj->isPlaying());
+    QTRY_VERIFY(!obj->isPaused());
+    QTRY_COMPARE(playingSpy.count(), 5);
+    QTRY_COMPARE(pausedSpy.count(), 4);
+
+    delete obj;
+}
 QTEST_MAIN(tst_qquickanimatedimage)
 
 #include "tst_qquickanimatedimage.moc"