StatusChanged signals are now always emitted.
Other properties only emit when altered.
AnimatedImage local and remote loading was also unified in this fix.
BorderImage duplicated loading code is streamlined.
Task-number: QTBUG-26405
Change-Id: Ib412d5879e0007229a8098e1fa960003051508de
Reviewed-by: Alan Alpert <alan.alpert@nokia.com>
QQuickAnimatedImage::~QQuickAnimatedImage()
{
Q_D(QQuickAnimatedImage);
+ if (d->reply)
+ d->reply->deleteLater();
delete d->_movie;
}
if (url == d->url)
return;
- delete d->_movie;
- d->_movie = 0;
-
if (d->reply) {
d->reply->deleteLater();
d->reply = 0;
}
+ if (d->_movie) {
+ delete d->_movie;
+ d->_movie = 0;
+ }
+
d->url = url;
emit sourceChanged(d->url);
{
Q_D(QQuickAnimatedImage);
- QQuickImageBase::Status oldStatus = d->status;
- qreal oldProgress = d->progress;
-
if (d->url.isEmpty()) {
- delete d->_movie;
+ if (d->progress != 0) {
+ d->progress = 0;
+ emit progressChanged(d->progress);
+ }
+
d->setImage(QImage());
- d->progress = 0;
d->status = Null;
- if (d->status != oldStatus)
- emit statusChanged(d->status);
- if (d->progress != oldProgress)
- emit progressChanged(d->progress);
+ emit statusChanged(d->status);
+
+ if (sourceSize() != d->oldSourceSize) {
+ d->oldSourceSize = sourceSize();
+ emit sourceSizeChanged();
+ }
} else {
QString lf = QQmlFile::urlToLocalFileOrQrc(d->url);
if (!lf.isEmpty()) {
- //### should be unified with movieRequestFinished
d->_movie = new QMovie(lf);
- if (!d->_movie->isValid()){
- qmlInfo(this) << "Error Reading Animated Image File " << d->url.toString();
- delete d->_movie;
- d->_movie = 0;
- d->status = Error;
- if (d->status != oldStatus)
- emit statusChanged(d->status);
- return;
- }
- connect(d->_movie, SIGNAL(stateChanged(QMovie::MovieState)),
- this, SLOT(playingStatusChanged()));
- connect(d->_movie, SIGNAL(frameChanged(int)),
- this, SLOT(movieUpdate()));
- d->_movie->setCacheMode(QMovie::CacheAll);
- if (d->playing)
- d->_movie->start();
- else
- d->_movie->jumpToFrame(0);
- if (d->paused)
- d->_movie->setPaused(true);
- d->setImage(d->_movie->currentPixmap().toImage());
- d->status = Ready;
- d->progress = 1.0;
- if (d->status != oldStatus)
+ movieRequestFinished();
+ } else {
+ if (d->status != Loading) {
+ d->status = Loading;
emit statusChanged(d->status);
- if (d->progress != oldProgress)
+ }
+ if (d->progress != 0) {
+ d->progress = 0;
emit progressChanged(d->progress);
- return;
+ }
+ QNetworkRequest req(d->url);
+ req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
+
+ d->reply = qmlEngine(this)->networkAccessManager()->get(req);
+ QObject::connect(d->reply, SIGNAL(finished()),
+ this, SLOT(movieRequestFinished()));
+ QObject::connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)),
+ this, SLOT(requestProgress(qint64,qint64)));
}
-
- d->status = Loading;
- d->progress = 0;
- emit statusChanged(d->status);
- emit progressChanged(d->progress);
- QNetworkRequest req(d->url);
- req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
- d->reply = qmlEngine(this)->networkAccessManager()->get(req);
- QObject::connect(d->reply, SIGNAL(finished()),
- this, SLOT(movieRequestFinished()));
- QObject::connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)),
- this, SLOT(requestProgress(qint64,qint64)));
}
}
{
Q_D(QQuickAnimatedImage);
- d->redirectCount++;
- if (d->redirectCount < ANIMATEDIMAGE_MAXIMUM_REDIRECT_RECURSION) {
- QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
- if (redirect.isValid()) {
- QUrl url = d->reply->url().resolved(redirect.toUrl());
- d->reply->deleteLater();
- d->reply = 0;
- setSource(url);
- return;
+ if (d->reply) {
+ d->redirectCount++;
+ if (d->redirectCount < ANIMATEDIMAGE_MAXIMUM_REDIRECT_RECURSION) {
+ QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
+ if (redirect.isValid()) {
+ QUrl url = d->reply->url().resolved(redirect.toUrl());
+ d->reply->deleteLater();
+ setSource(url);
+ return;
+ }
}
+
+ d->redirectCount=0;
+ d->_movie = new QMovie(d->reply);
}
- d->redirectCount=0;
- d->_movie = new QMovie(d->reply);
- if (!d->_movie->isValid()){
-#ifndef QT_NO_DEBUG_STREAM
- qmlInfo(this) << "Error Reading Animated Image File " << d->url;
-#endif
+ if (!d->_movie->isValid()) {
+ qmlInfo(this) << "Error Reading Animated Image File " << d->url.toString();
delete d->_movie;
d->_movie = 0;
+ d->setImage(QImage());
+ if (d->progress != 0) {
+ d->progress = 0;
+ emit progressChanged(d->progress);
+ }
d->status = Error;
emit statusChanged(d->status);
+
+ if (sourceSize() != d->oldSourceSize) {
+ d->oldSourceSize = sourceSize();
+ emit sourceSizeChanged();
+ }
return;
}
+
connect(d->_movie, SIGNAL(stateChanged(QMovie::MovieState)),
this, SLOT(playingStatusChanged()));
connect(d->_movie, SIGNAL(frameChanged(int)),
this, SLOT(movieUpdate()));
d->_movie->setCacheMode(QMovie::CacheAll);
+
+ d->status = Ready;
+ emit statusChanged(d->status);
+
+ if (d->progress != 1.0) {
+ d->progress = 1.0;
+ emit progressChanged(d->progress);
+ }
if (d->playing)
d->_movie->start();
+
+ if (d->paused)
+ d->_movie->setPaused(true);
if (d->paused || !d->playing) {
d->_movie->jumpToFrame(d->preset_currentframe);
d->preset_currentframe = 0;
}
- if (d->paused)
- d->_movie->setPaused(true);
d->setImage(d->_movie->currentPixmap().toImage());
- d->status = Ready;
- emit statusChanged(d->status);
+
+ if (sourceSize() != d->oldSourceSize) {
+ d->oldSourceSize = sourceSize();
+ emit sourceSizeChanged();
+ }
}
void QQuickAnimatedImage::movieUpdate()
{
Q_D(QQuickAnimatedImage);
- d->setImage(d->_movie->currentPixmap().toImage());
- emit frameChanged();
+
+ if (d->_movie) {
+ d->setImage(d->_movie->currentPixmap().toImage());
+ emit frameChanged();
+ }
}
void QQuickAnimatedImage::playingStatusChanged()
{
Q_D(QQuickAnimatedImage);
+
if ((d->_movie->state() != QMovie::NotRunning) != d->playing) {
d->playing = (d->_movie->state() != QMovie::NotRunning);
emit playingChanged();
}
}
+QSize QQuickAnimatedImage::sourceSize()
+{
+ Q_D(QQuickAnimatedImage);
+ if (!d->_movie)
+ return QSize(0, 0);
+ return QSize(d->_movie->currentPixmap().size());
+}
+
void QQuickAnimatedImage::componentComplete()
{
Q_D(QQuickAnimatedImage);
QQuickItem::componentComplete(); // NOT QQuickImage
- if (d->url.isValid())
- load();
- if (!d->reply) {
- setCurrentFrame(d->preset_currentframe);
- d->preset_currentframe = 0;
- }
+ load();
}
QT_END_NAMESPACE
int frameCount() const;
- // Extends QQuickImage's src property*/
+ // Extends QQuickImage's src property
virtual void setSource(const QUrl&);
+ virtual QSize sourceSize();
Q_SIGNALS:
void playingChanged();
void QQuickBorderImage::load()
{
Q_D(QQuickBorderImage);
- if (d->progress != 0.0) {
- d->progress = 0.0;
- emit progressChanged(d->progress);
- }
if (d->url.isEmpty()) {
d->pix.clear(this);
d->status = Null;
setImplicitSize(0, 0);
emit statusChanged(d->status);
+ if (d->progress != 0.0) {
+ d->progress = 0.0;
+ emit progressChanged(d->progress);
+ }
+ if (sourceSize() != d->oldSourceSize) {
+ d->oldSourceSize = sourceSize();
+ emit sourceSizeChanged();
+ }
update();
return;
} else {
- d->status = Loading;
if (d->url.path().endsWith(QLatin1String("sci"))) {
QString lf = QQmlFile::urlToLocalFileOrQrc(d->url);
if (!lf.isEmpty()) {
QFile file(lf);
file.open(QIODevice::ReadOnly);
setGridScaledImage(QQuickGridScaledImage(&file));
+ return;
} else {
+ if (d->progress != 0.0) {
+ d->progress = 0.0;
+ emit progressChanged(d->progress);
+ }
+ d->status = Loading;
QNetworkRequest req(d->url);
d->sciReply = qmlEngine(this)->networkAccessManager()->get(req);
qmlobject_connect(d->sciReply, QNetworkReply, SIGNAL(finished()),
this, QQuickBorderImage, SLOT(sciRequestFinished()))
}
} else {
-
QQuickPixmap::Options options;
if (d->async)
options |= QQuickPixmap::Asynchronous;
d->pix.load(qmlEngine(this), d->url, options);
if (d->pix.isLoading()) {
+ if (d->progress != 0.0) {
+ d->progress = 0.0;
+ emit progressChanged(d->progress);
+ }
+ d->status = Loading;
d->pix.connectFinished(this, SLOT(requestFinished()));
d->pix.connectDownloadProgress(this, SLOT(requestProgress(qint64,qint64)));
} else {
- QSize impsize = d->pix.implicitSize();
- setImplicitSize(impsize.width(), impsize.height());
-
- if (d->pix.isReady()) {
- d->status = Ready;
- } else {
- d->status = Error;
- qmlInfo(this) << d->pix.error();
- }
-
- d->progress = 1.0;
- emit statusChanged(d->status);
- emit progressChanged(d->progress);
- update();
+ requestFinished();
return;
}
}
d->pix.load(qmlEngine(this), d->sciurl, options);
if (d->pix.isLoading()) {
+ if (d->progress != 0.0) {
+ d->progress = 0.0;
+ emit progressChanged(d->progress);
+ }
+ if (d->status != Loading) {
+ d->status = Loading;
+ emit statusChanged(d->status);
+ }
static int thisRequestProgress = -1;
static int thisRequestFinished = -1;
if (thisRequestProgress == -1) {
d->pix.connectDownloadProgress(this, thisRequestProgress);
} else {
-
- QSize impsize = d->pix.implicitSize();
- setImplicitSize(impsize.width(), impsize.height());
-
- if (d->pix.isReady()) {
- d->status = Ready;
- } else {
- d->status = Error;
- qmlInfo(this) << d->pix.error();
- }
-
- d->progress = 1.0;
- emit statusChanged(d->status);
- emit progressChanged(1.0);
- update();
-
+ requestFinished();
}
}
}
if (d->pix.isError()) {
d->status = Error;
qmlInfo(this) << d->pix.error();
+ if (d->progress != 0) {
+ d->progress = 0;
+ emit progressChanged(d->progress);
+ }
} else {
d->status = Ready;
+ if (d->progress != 1.0) {
+ d->progress = 1.0;
+ emit progressChanged(d->progress);
+ }
}
setImplicitSize(impsize.width(), impsize.height());
-
- if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height())
+ emit statusChanged(d->status);
+ if (sourceSize() != d->oldSourceSize) {
+ d->oldSourceSize = sourceSize();
emit sourceSizeChanged();
+ }
- d->progress = 1.0;
- emit statusChanged(d->status);
- emit progressChanged(1.0);
update();
}
if (d->url.isEmpty()) {
d->pix.clear(this);
- d->status = Null;
- d->progress = 0.0;
+ if (d->progress != 0.0) {
+ d->progress = 0.0;
+ emit progressChanged(d->progress);
+ }
pixmapChange();
- emit progressChanged(d->progress);
+ d->status = Null;
emit statusChanged(d->status);
+
+ if (sourceSize() != d->oldSourceSize) {
+ d->oldSourceSize = sourceSize();
+ emit sourceSizeChanged();
+ }
update();
+
} else {
QQuickPixmap::Options options;
if (d->async)
options |= QQuickPixmap::Asynchronous;
if (d->cache)
options |= QQuickPixmap::Cache;
- d->pix.clear(this);
- pixmapChange();
d->pix.load(qmlEngine(this), d->url, d->sourcesize, options);
if (d->pix.isLoading()) {
- d->progress = 0.0;
- d->status = Loading;
- emit progressChanged(d->progress);
- emit statusChanged(d->status);
+ if (d->progress != 0.0) {
+ d->progress = 0.0;
+ emit progressChanged(d->progress);
+ }
+ if (d->status != Loading) {
+ d->status = Loading;
+ emit statusChanged(d->status);
+ }
static int thisRequestProgress = -1;
static int thisRequestFinished = -1;
{
Q_D(QQuickImageBase);
- QQuickImageBase::Status oldStatus = d->status;
- qreal oldProgress = d->progress;
-
if (d->pix.isError()) {
- d->status = Error;
qmlInfo(this) << d->pix.error();
+ d->pix.clear(this);
+ d->status = Error;
+ if (d->progress != 0.0) {
+ d->progress = 0.0;
+ emit progressChanged(d->progress);
+ }
} else {
d->status = Ready;
+ if (d->progress != 1.0) {
+ d->progress = 1.0;
+ emit progressChanged(d->progress);
+ }
}
-
- d->progress = 1.0;
-
pixmapChange();
-
- if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height())
+ emit statusChanged(d->status);
+ if (sourceSize() != d->oldSourceSize) {
+ d->oldSourceSize = sourceSize();
emit sourceSizeChanged();
-
- if (d->status != oldStatus)
- emit statusChanged(d->status);
- if (d->progress != oldProgress)
- emit progressChanged(d->progress);
-
+ }
update();
}
QUrl url;
qreal progress;
QSize sourcesize;
+ QSize oldSourceSize;
bool async : 1;
bool cache : 1;
bool mirror: 1;
tst_qquickanimatedimage() {}
private slots:
+ void cleanup();
void play();
void pause();
void stopped();
void remote();
void remote_data();
void sourceSize();
+ void sourceSizeChanges();
void sourceSizeReadOnly();
void invalidSource();
void qtbug_16520();
void progressAndStatusChanges();
-
};
+void tst_qquickanimatedimage::cleanup()
+{
+ QQuickCanvas canvas;
+ canvas.releaseResources();
+}
+
void tst_qquickanimatedimage::play()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("stickmanpause.qml"));
QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(component.create());
QVERIFY(anim);
- QVERIFY(anim->isPlaying());
- QVERIFY(anim->isPaused());
+
+ QTRY_VERIFY(anim->isPaused());
+ QTRY_VERIFY(anim->isPlaying());
delete anim;
}
QCOMPARE(frame0_flipped, frame0_expected);
QCOMPARE(frame1_flipped, frame1_expected);
+
+ delete anim;
}
void tst_qquickanimatedimage::mirror_notRunning()
anim->setProperty("mirror", true);
screenshot = QPixmap::fromImage(canvas.grabFrameBuffer());
- QSKIP("Skip while QTBUG-19351 and QTBUG-19252 are not resolved");
QCOMPARE(screenshot, expected);
// mirroring should not change the current frame or playing status
QCOMPARE(anim->currentFrame(), frame);
QCOMPARE(anim->isPlaying(), playing);
QCOMPARE(anim->isPaused(), paused);
+
+ delete anim;
}
void tst_qquickanimatedimage::mirror_notRunning_data()
QTest::newRow("stopped") << testFileUrl("stickmanstopped.qml");
}
+void tst_qquickanimatedimage::remote_data()
+{
+ QTest::addColumn<QString>("fileName");
+ QTest::addColumn<bool>("paused");
+
+ QTest::newRow("playing") << "stickman.qml" << false;
+ QTest::newRow("paused") << "stickmanpause.qml" << true;
+}
+
void tst_qquickanimatedimage::remote()
{
QFETCH(QString, fileName);
QCOMPARE(component.errors().at(0).description(), QString("Invalid property assignment: \"sourceSize\" is a read-only property"));
}
-void tst_qquickanimatedimage::remote_data()
-{
- QTest::addColumn<QString>("fileName");
- QTest::addColumn<bool>("paused");
-
- QTest::newRow("playing") << "stickman.qml" << false;
- QTest::newRow("paused") << "stickmanpause.qml" << true;
-}
-
void tst_qquickanimatedimage::invalidSource()
{
QQmlEngine engine;
QCOMPARE(anim->currentFrame(), 0);
QCOMPARE(anim->frameCount(), 0);
QTRY_VERIFY(anim->status() == 3);
+
+ delete anim;
+}
+
+void tst_qquickanimatedimage::sourceSizeChanges()
+{
+ TestHTTPServer server(14449);
+ QVERIFY(server.isValid());
+ server.serveDirectory(dataDirectory());
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0\nAnimatedImage { source: srcImage }", QUrl::fromLocalFile(""));
+ QTRY_VERIFY(component.isReady());
+ QQmlContext *ctxt = engine.rootContext();
+ ctxt->setContextProperty("srcImage", "");
+ QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage*>(component.create());
+ QVERIFY(anim != 0);
+
+ QSignalSpy sourceSizeSpy(anim, SIGNAL(sourceSizeChanged()));
+
+ // Local
+ ctxt->setContextProperty("srcImage", QUrl(""));
+ QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Null);
+ QTRY_VERIFY(sourceSizeSpy.count() == 0);
+
+ ctxt->setContextProperty("srcImage", testFileUrl("hearts.gif"));
+ QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
+ QTRY_VERIFY(sourceSizeSpy.count() == 1);
+
+ ctxt->setContextProperty("srcImage", testFileUrl("hearts.gif"));
+ QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
+ QTRY_VERIFY(sourceSizeSpy.count() == 1);
+
+ ctxt->setContextProperty("srcImage", testFileUrl("hearts_copy.gif"));
+ QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
+ QTRY_VERIFY(sourceSizeSpy.count() == 1);
+
+ ctxt->setContextProperty("srcImage", testFileUrl("colors.gif"));
+ QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
+ QTRY_VERIFY(sourceSizeSpy.count() == 2);
+
+ ctxt->setContextProperty("srcImage", QUrl(""));
+ QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Null);
+ QTRY_VERIFY(sourceSizeSpy.count() == 3);
+
+ // Remote
+ ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/hearts.gif"));
+ QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
+ QTRY_VERIFY(sourceSizeSpy.count() == 4);
+
+ ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/hearts.gif"));
+ QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
+ QTRY_VERIFY(sourceSizeSpy.count() == 4);
+
+ ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/hearts_copy.gif"));
+ QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
+ QTRY_VERIFY(sourceSizeSpy.count() == 4);
+
+ ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/colors.gif"));
+ QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Ready);
+ QTRY_VERIFY(sourceSizeSpy.count() == 5);
+
+ ctxt->setContextProperty("srcImage", QUrl(""));
+ QTRY_COMPARE(anim->status(), QQuickAnimatedImage::Null);
+ QTRY_VERIFY(sourceSizeSpy.count() == 6);
+
+ delete anim;
}
void tst_qquickanimatedimage::qtbug_16520()
QQuickRectangle *root = qobject_cast<QQuickRectangle *>(component.create());
QVERIFY(root);
QQuickAnimatedImage *anim = root->findChild<QQuickAnimatedImage*>("anim");
+ QVERIFY(anim != 0);
anim->setProperty("source", "http://127.0.0.1:14449/stickman.gif");
-
QTRY_VERIFY(anim->opacity() == 0);
QTRY_VERIFY(anim->opacity() == 1);
delete anim;
+ delete root;
}
void tst_qquickanimatedimage::progressAndStatusChanges()
QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal)));
QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QQuickImageBase::Status)));
+ // Same image
+ ctxt->setContextProperty("srcImage", testFileUrl("stickman.gif"));
+ QTRY_VERIFY(obj->status() == QQuickImage::Ready);
+ QTRY_VERIFY(obj->progress() == 1.0);
+ QTRY_COMPARE(sourceSpy.count(), 0);
+ QTRY_COMPARE(progressSpy.count(), 0);
+ QTRY_COMPARE(statusSpy.count(), 0);
+
// Loading local file
ctxt->setContextProperty("srcImage", testFileUrl("colors.gif"));
QTRY_VERIFY(obj->status() == QQuickImage::Ready);
QTRY_VERIFY(obj->progress() == 1.0);
QTRY_COMPARE(sourceSpy.count(), 1);
QTRY_COMPARE(progressSpy.count(), 0);
- QTRY_COMPARE(statusSpy.count(), 0);
+ QTRY_COMPARE(statusSpy.count(), 1);
// Loading remote file
ctxt->setContextProperty("srcImage", "http://127.0.0.1:14449/stickman.gif");
QTRY_VERIFY(obj->progress() == 1.0);
QTRY_COMPARE(sourceSpy.count(), 2);
QTRY_VERIFY(progressSpy.count() > 1);
- QTRY_COMPARE(statusSpy.count(), 2);
+ QTRY_COMPARE(statusSpy.count(), 3);
ctxt->setContextProperty("srcImage", "");
QTRY_VERIFY(obj->status() == QQuickImage::Null);
QTRY_VERIFY(obj->progress() == 0.0);
QTRY_COMPARE(sourceSpy.count(), 3);
QTRY_VERIFY(progressSpy.count() > 2);
- QTRY_COMPARE(statusSpy.count(), 3);
+ QTRY_COMPARE(statusSpy.count(), 4);
+
+ delete obj;
}
QTEST_MAIN(tst_qquickanimatedimage)
tst_qquickborderimage();
private slots:
+ void cleanup();
void noSource();
void imageSource();
void imageSource_data();
void validSciFiles();
void pendingRemoteRequest();
void pendingRemoteRequest_data();
-
void statusChanges();
void statusChanges_data();
+ void sourceSizeChanges();
+ void progressAndStatusChanges();
private:
QQmlEngine engine;
};
+void tst_qquickborderimage::cleanup()
+{
+ QQuickCanvas canvas;
+ canvas.releaseResources();
+ engine.clearComponentCache();
+}
+
tst_qquickborderimage::tst_qquickborderimage()
{
}
QVERIFY(obj->status() == QQuickBorderImage::Null);
QCOMPARE(obj->width(), 0.);
QCOMPARE(obj->height(), 0.);
+
+ delete obj;
}
void tst_qquickborderimage::resized()
delete server;
}
+void tst_qquickborderimage::sourceSizeChanges()
+{
+ TestHTTPServer server(14449);
+ QVERIFY(server.isValid());
+ server.serveDirectory(dataDirectory());
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0\nBorderImage { source: srcImage }", QUrl::fromLocalFile(""));
+ QTRY_VERIFY(component.isReady());
+ QQmlContext *ctxt = engine.rootContext();
+ ctxt->setContextProperty("srcImage", "");
+ QQuickBorderImage *obj = qobject_cast<QQuickBorderImage*>(component.create());
+ QVERIFY(obj != 0);
+
+ QSignalSpy sourceSizeSpy(obj, SIGNAL(sourceSizeChanged()));
+
+ // Local
+ ctxt->setContextProperty("srcImage", QUrl(""));
+ QTRY_COMPARE(obj->status(), QQuickBorderImage::Null);
+ QTRY_COMPARE(sourceSizeSpy.count(), 0);
+
+ ctxt->setContextProperty("srcImage", testFileUrl("heart200.png"));
+ QTRY_COMPARE(obj->status(), QQuickBorderImage::Ready);
+ QTRY_COMPARE(sourceSizeSpy.count(), 1);
+
+ ctxt->setContextProperty("srcImage", testFileUrl("heart200.png"));
+ QTRY_COMPARE(obj->status(), QQuickBorderImage::Ready);
+ QTRY_COMPARE(sourceSizeSpy.count(), 1);
+
+ ctxt->setContextProperty("srcImage", testFileUrl("heart200_copy.png"));
+ QTRY_COMPARE(obj->status(), QQuickBorderImage::Ready);
+ QTRY_COMPARE(sourceSizeSpy.count(), 1);
+
+ ctxt->setContextProperty("srcImage", testFileUrl("colors.png"));
+ QTRY_COMPARE(obj->status(), QQuickBorderImage::Ready);
+ QTRY_COMPARE(sourceSizeSpy.count(), 2);
+
+ ctxt->setContextProperty("srcImage", QUrl(""));
+ QTRY_COMPARE(obj->status(), QQuickBorderImage::Null);
+ QTRY_COMPARE(sourceSizeSpy.count(), 3);
+
+ // Remote
+ ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/heart200.png"));
+ QTRY_COMPARE(obj->status(), QQuickBorderImage::Ready);
+ QTRY_COMPARE(sourceSizeSpy.count(), 4);
+
+ ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/heart200.png"));
+ QTRY_COMPARE(obj->status(), QQuickBorderImage::Ready);
+ QTRY_COMPARE(sourceSizeSpy.count(), 4);
+
+ ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/heart200_copy.png"));
+ QTRY_COMPARE(obj->status(), QQuickBorderImage::Ready);
+ QTRY_COMPARE(sourceSizeSpy.count(), 4);
+
+ ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/colors.png"));
+ QTRY_COMPARE(obj->status(), QQuickBorderImage::Ready);
+ QTRY_COMPARE(sourceSizeSpy.count(), 5);
+
+ ctxt->setContextProperty("srcImage", QUrl(""));
+ QTRY_COMPARE(obj->status(), QQuickBorderImage::Null);
+ QTRY_COMPARE(sourceSizeSpy.count(), 6);
+
+ delete obj;
+}
+
+void tst_qquickborderimage::progressAndStatusChanges()
+{
+ TestHTTPServer server(14449);
+ QVERIFY(server.isValid());
+ server.serveDirectory(dataDirectory());
+
+ QQmlEngine engine;
+ QString componentStr = "import QtQuick 2.0\nBorderImage { source: srcImage }";
+ QQmlContext *ctxt = engine.rootContext();
+ ctxt->setContextProperty("srcImage", testFileUrl("heart200.png"));
+ QQmlComponent component(&engine);
+ component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickBorderImage *obj = qobject_cast<QQuickBorderImage*>(component.create());
+ QVERIFY(obj != 0);
+ QVERIFY(obj->status() == QQuickBorderImage::Ready);
+ QTRY_VERIFY(obj->progress() == 1.0);
+
+ qRegisterMetaType<QQuickBorderImage::Status>();
+ QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &)));
+ QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal)));
+ QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QQuickImageBase::Status)));
+
+ // Same file
+ ctxt->setContextProperty("srcImage", testFileUrl("heart200.png"));
+ QTRY_VERIFY(obj->status() == QQuickBorderImage::Ready);
+ QTRY_VERIFY(obj->progress() == 1.0);
+ QTRY_COMPARE(sourceSpy.count(), 0);
+ QTRY_COMPARE(progressSpy.count(), 0);
+ QTRY_COMPARE(statusSpy.count(), 0);
+
+ // Loading local file
+ ctxt->setContextProperty("srcImage", testFileUrl("colors.png"));
+ QTRY_VERIFY(obj->status() == QQuickBorderImage::Ready);
+ QTRY_VERIFY(obj->progress() == 1.0);
+ QTRY_COMPARE(sourceSpy.count(), 1);
+ QTRY_COMPARE(progressSpy.count(), 0);
+ QTRY_COMPARE(statusSpy.count(), 1);
+
+ // Loading remote file
+ ctxt->setContextProperty("srcImage", "http://127.0.0.1:14449/heart200.png");
+ QTRY_VERIFY(obj->status() == QQuickBorderImage::Loading);
+ QTRY_VERIFY(obj->progress() == 0.0);
+ QTRY_VERIFY(obj->status() == QQuickBorderImage::Ready);
+ QTRY_VERIFY(obj->progress() == 1.0);
+ QTRY_COMPARE(sourceSpy.count(), 2);
+ QTRY_VERIFY(progressSpy.count() > 1);
+ QTRY_COMPARE(statusSpy.count(), 3);
+
+ ctxt->setContextProperty("srcImage", "");
+ QTRY_VERIFY(obj->status() == QQuickBorderImage::Null);
+ QTRY_VERIFY(obj->progress() == 0.0);
+ QTRY_COMPARE(sourceSpy.count(), 3);
+ QTRY_VERIFY(progressSpy.count() > 2);
+ QTRY_COMPARE(statusSpy.count(), 4);
+
+ delete obj;
+}
+
QTEST_MAIN(tst_qquickborderimage)
#include "tst_qquickborderimage.moc"
#include <QtTest/QSignalSpy>
#include <QtGui/QPainter>
#include <QtGui/QImageReader>
+#include <QQuickCanvas>
#include "../../shared/util.h"
#include "../../shared/testhttpserver.h"
tst_qquickimage();
private slots:
+ void cleanup();
void noSource();
void imageSource();
void imageSource_data();
void imageCrash_QTBUG_22125();
void sourceSize_data();
void sourceSize();
+ void progressAndStatusChanges();
+ void sourceSizeChanges();
private:
QQmlEngine engine;
{
}
+void tst_qquickimage::cleanup()
+{
+ QQuickCanvas canvas;
+ canvas.releaseResources();
+ engine.clearComponentCache();
+}
+
void tst_qquickimage::noSource()
{
QString componentStr = "import QtQuick 2.0\nImage { source: \"\" }";
QTRY_VERIFY(obj->progress() == 1.0);
QTRY_COMPARE(sourceSpy.count(), 1);
QTRY_COMPARE(progressSpy.count(), 0);
- QTRY_COMPARE(statusSpy.count(), 0);
+ QTRY_COMPARE(statusSpy.count(), 1);
// Loading remote file
ctxt->setContextProperty("srcImage", QString(SERVER_ADDR) + "/rect.png");
QTRY_VERIFY(obj->progress() == 1.0);
QTRY_COMPARE(sourceSpy.count(), 2);
QTRY_COMPARE(progressSpy.count(), 2);
- QTRY_COMPARE(statusSpy.count(), 2);
+ QTRY_COMPARE(statusSpy.count(), 3);
// Loading remote file again - should not go through 'Loading' state.
ctxt->setContextProperty("srcImage", testFileUrl("green.png"));
QTRY_VERIFY(obj->progress() == 1.0);
QTRY_COMPARE(sourceSpy.count(), 4);
QTRY_COMPARE(progressSpy.count(), 2);
- QTRY_COMPARE(statusSpy.count(), 2);
+ QTRY_COMPARE(statusSpy.count(), 5);
delete obj;
}
delete canvas;
}
+void tst_qquickimage::sourceSizeChanges()
+{
+ TestHTTPServer server(14449);
+ QVERIFY(server.isValid());
+ server.serveDirectory(dataDirectory());
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0\nImage { source: srcImage }", QUrl::fromLocalFile(""));
+ QTRY_VERIFY(component.isReady());
+ QQmlContext *ctxt = engine.rootContext();
+ ctxt->setContextProperty("srcImage", "");
+ QQuickImage *img = qobject_cast<QQuickImage*>(component.create());
+ QVERIFY(img != 0);
+
+ QSignalSpy sourceSizeSpy(img, SIGNAL(sourceSizeChanged()));
+
+ // Local
+ ctxt->setContextProperty("srcImage", QUrl(""));
+ QTRY_COMPARE(img->status(), QQuickImage::Null);
+ QTRY_COMPARE(sourceSizeSpy.count(), 0);
+
+ ctxt->setContextProperty("srcImage", testFileUrl("heart.png"));
+ QTRY_COMPARE(img->status(), QQuickImage::Ready);
+ QTRY_COMPARE(sourceSizeSpy.count(), 1);
+
+ ctxt->setContextProperty("srcImage", testFileUrl("heart.png"));
+ QTRY_COMPARE(img->status(), QQuickImage::Ready);
+ QTRY_COMPARE(sourceSizeSpy.count(), 1);
+
+ ctxt->setContextProperty("srcImage", testFileUrl("heart_copy.png"));
+ QTRY_COMPARE(img->status(), QQuickImage::Ready);
+ QTRY_COMPARE(sourceSizeSpy.count(), 1);
+
+ ctxt->setContextProperty("srcImage", testFileUrl("colors.png"));
+ QTRY_COMPARE(img->status(), QQuickImage::Ready);
+ QTRY_COMPARE(sourceSizeSpy.count(), 2);
+
+ ctxt->setContextProperty("srcImage", QUrl(""));
+ QTRY_COMPARE(img->status(), QQuickImage::Null);
+ QTRY_COMPARE(sourceSizeSpy.count(), 3);
+
+ // Remote
+ ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/heart.png"));
+ QTRY_COMPARE(img->status(), QQuickImage::Ready);
+ QTRY_COMPARE(sourceSizeSpy.count(), 4);
+
+ ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/heart.png"));
+ QTRY_COMPARE(img->status(), QQuickImage::Ready);
+ QTRY_COMPARE(sourceSizeSpy.count(), 4);
+
+ ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/heart_copy.png"));
+ QTRY_COMPARE(img->status(), QQuickImage::Ready);
+ QTRY_COMPARE(sourceSizeSpy.count(), 4);
+
+ ctxt->setContextProperty("srcImage", QUrl("http://127.0.0.1:14449/colors.png"));
+ QTRY_COMPARE(img->status(), QQuickImage::Ready);
+ QTRY_COMPARE(sourceSizeSpy.count(), 5);
+
+ ctxt->setContextProperty("srcImage", QUrl(""));
+ QTRY_COMPARE(img->status(), QQuickImage::Null);
+ QTRY_COMPARE(sourceSizeSpy.count(), 6);
+
+ delete img;
+}
+
+void tst_qquickimage::progressAndStatusChanges()
+{
+ TestHTTPServer server(14449);
+ QVERIFY(server.isValid());
+ server.serveDirectory(dataDirectory());
+
+ QQmlEngine engine;
+ QString componentStr = "import QtQuick 2.0\nImage { source: srcImage }";
+ QQmlContext *ctxt = engine.rootContext();
+ ctxt->setContextProperty("srcImage", testFileUrl("heart.png"));
+ QQmlComponent component(&engine);
+ component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+ QVERIFY(obj != 0);
+ QVERIFY(obj->status() == QQuickImage::Ready);
+ QTRY_VERIFY(obj->progress() == 1.0);
+
+ qRegisterMetaType<QQuickImageBase::Status>();
+ QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &)));
+ QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal)));
+ QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QQuickImageBase::Status)));
+
+ // Same image
+ ctxt->setContextProperty("srcImage", testFileUrl("heart.png"));
+ QTRY_VERIFY(obj->status() == QQuickImage::Ready);
+ QTRY_VERIFY(obj->progress() == 1.0);
+ QTRY_COMPARE(sourceSpy.count(), 0);
+ QTRY_COMPARE(progressSpy.count(), 0);
+ QTRY_COMPARE(statusSpy.count(), 0);
+
+ // Loading local file
+ ctxt->setContextProperty("srcImage", testFileUrl("colors.png"));
+ QTRY_VERIFY(obj->status() == QQuickImage::Ready);
+ QTRY_VERIFY(obj->progress() == 1.0);
+ QTRY_COMPARE(sourceSpy.count(), 1);
+ QTRY_COMPARE(progressSpy.count(), 0);
+ QTRY_COMPARE(statusSpy.count(), 1);
+
+ // Loading remote file
+ ctxt->setContextProperty("srcImage", "http://127.0.0.1:14449/heart.png");
+ QTRY_VERIFY(obj->status() == QQuickImage::Loading);
+ QTRY_VERIFY(obj->progress() == 0.0);
+ QTRY_VERIFY(obj->status() == QQuickImage::Ready);
+ QTRY_VERIFY(obj->progress() == 1.0);
+ QTRY_COMPARE(sourceSpy.count(), 2);
+ QTRY_VERIFY(progressSpy.count() > 1);
+ QTRY_COMPARE(statusSpy.count(), 3);
+
+ ctxt->setContextProperty("srcImage", "");
+ QTRY_VERIFY(obj->status() == QQuickImage::Null);
+ QTRY_VERIFY(obj->progress() == 0.0);
+ QTRY_COMPARE(sourceSpy.count(), 3);
+ QTRY_VERIFY(progressSpy.count() > 2);
+ QTRY_COMPARE(statusSpy.count(), 4);
+
+ delete obj;
+}
+
QTEST_MAIN(tst_qquickimage)
#include "tst_qquickimage.moc"