AnimatedImage: Fix value of sourceSize property

Cache the source size of the internal QMovie object during the
change of the 'source' property to ensure that always a valid source
size is returned without emitting more sourceSizeChanged() signals
than necessary.

Change-Id: I637b80efb133197b7345b09fcf8a7bb80c5643c9
Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
This commit is contained in:
Tobias Koenig 2016-04-27 08:12:12 +02:00
parent 1650377af7
commit be031102c2
3 changed files with 40 additions and 10 deletions

View File

@ -294,8 +294,9 @@ void QQuickAnimatedImage::load()
d->status = Null;
emit statusChanged(d->status);
if (sourceSize() != d->oldSourceSize) {
d->oldSourceSize = sourceSize();
d->currentSourceSize = QSize(0, 0);
if (d->currentSourceSize != d->oldSourceSize) {
d->oldSourceSize = d->currentSourceSize;
emit sourceSizeChanged();
}
if (isPlaying() != d->oldPlaying)
@ -366,8 +367,9 @@ void QQuickAnimatedImage::movieRequestFinished()
d->status = Error;
emit statusChanged(d->status);
if (sourceSize() != d->oldSourceSize) {
d->oldSourceSize = sourceSize();
d->currentSourceSize = QSize(0, 0);
if (d->currentSourceSize != d->oldSourceSize) {
d->oldSourceSize = d->currentSourceSize;
emit sourceSizeChanged();
}
if (isPlaying() != d->oldPlaying)
@ -404,8 +406,14 @@ void QQuickAnimatedImage::movieRequestFinished()
if (isPlaying() != d->oldPlaying)
emit playingChanged();
if (sourceSize() != d->oldSourceSize) {
d->oldSourceSize = sourceSize();
if (d->_movie)
d->currentSourceSize = d->_movie->currentPixmap().size();
else
d->currentSourceSize = QSize(0, 0);
if (d->currentSourceSize != d->oldSourceSize) {
d->oldSourceSize = d->currentSourceSize;
emit sourceSizeChanged();
}
}
@ -458,9 +466,7 @@ void QQuickAnimatedImage::onCacheChanged()
QSize QQuickAnimatedImage::sourceSize()
{
Q_D(QQuickAnimatedImage);
if (!d->_movie)
return QSize(0, 0);
return QSize(d->_movie->currentPixmap().size());
return d->currentSourceSize;
}
void QQuickAnimatedImage::componentComplete()

View File

@ -60,7 +60,7 @@ class QQuickAnimatedImagePrivate : public QQuickImagePrivate
public:
QQuickAnimatedImagePrivate()
: playing(true), paused(false), preset_currentframe(0), _movie(0), reply(0), redirectCount(0), oldPlaying(false)
: playing(true), paused(false), preset_currentframe(0), _movie(0), reply(0), redirectCount(0), oldPlaying(false), currentSourceSize(0, 0)
{
}
@ -74,6 +74,7 @@ public:
int redirectCount;
bool oldPlaying;
QMap<int, QQuickPixmap *> frameMap;
QSize currentSourceSize;
};
QT_END_NAMESPACE

View File

@ -65,6 +65,7 @@ private slots:
void remote_data();
void sourceSize();
void sourceSizeChanges();
void sourceSizeChanges_intermediate();
void sourceSizeReadOnly();
void invalidSource();
void qtbug_16520();
@ -375,6 +376,28 @@ void tst_qquickanimatedimage::sourceSizeChanges()
delete anim;
}
void tst_qquickanimatedimage::sourceSizeChanges_intermediate()
{
QQmlEngine engine;
QQmlComponent component(&engine);
component.setData("import QtQuick 2.0\nAnimatedImage { readonly property int testWidth: status === AnimatedImage.Ready ? sourceSize.width : -1; source: srcImage }", QUrl::fromLocalFile(""));
QTRY_VERIFY(component.isReady());
QQmlContext *ctxt = engine.rootContext();
ctxt->setContextProperty("srcImage", "");
QScopedPointer<QQuickAnimatedImage> anim(qobject_cast<QQuickAnimatedImage*>(component.create()));
QVERIFY(anim != 0);
ctxt->setContextProperty("srcImage", testFileUrl("hearts.gif"));
QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
QTRY_COMPARE(anim->property("testWidth").toInt(), anim->sourceSize().width());
ctxt->setContextProperty("srcImage", testFileUrl("hearts_copy.gif"));
QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
QTRY_COMPARE(anim->property("testWidth").toInt(), anim->sourceSize().width());
}
void tst_qquickanimatedimage::qtbug_16520()
{
TestHTTPServer server;