diff options
Diffstat (limited to 'src/declarative/fx')
-rw-r--r-- | src/declarative/fx/qfximage.cpp | 106 | ||||
-rw-r--r-- | src/declarative/fx/qfximage.h | 5 | ||||
-rw-r--r-- | src/declarative/fx/qfximage_p.h | 12 | ||||
-rw-r--r-- | src/declarative/fx/qfxpixmap.cpp | 8 | ||||
-rw-r--r-- | src/declarative/fx/qfxpixmap.h | 3 |
5 files changed, 111 insertions, 23 deletions
diff --git a/src/declarative/fx/qfximage.cpp b/src/declarative/fx/qfximage.cpp index 106d551..d66846d 100644 --- a/src/declarative/fx/qfximage.cpp +++ b/src/declarative/fx/qfximage.cpp @@ -125,8 +125,8 @@ QFxImage::QFxImage(QFxImagePrivate &dd, QFxItem *parent) QFxImage::~QFxImage() { Q_D(const QFxImage); - if (d->reply) - d->reply->deleteLater(); + if (d->sciReply) + d->sciReply->deleteLater(); } /*! @@ -783,6 +783,19 @@ QString QFxImage::propertyInfo() const return d->url.toString(); } +/*! + \qmlproperty enum Image::status + + This property holds the status of image loading. It can be one of: + \list + \o Idle - no image has been set, or the image has been loaded + \o Loading - the images is currently being loaded + \o Error - an error occurred while loading the image + \endlist + + \sa progress +*/ + QFxImage::Status QFxImage::status() const { Q_D(const QFxImage); @@ -790,6 +803,21 @@ QFxImage::Status QFxImage::status() const } /*! + \qmlproperty real Image::progress + + This property holds the progress of image loading, from 0.0 (nothing loaded) + to 1.0 (finished). + + \sa status +*/ + +qreal QFxImage::progress() const +{ + Q_D(const QFxImage); + return d->progress; +} + +/*! \qmlproperty string Image::source Image can handle any image format supported by Qt, loaded from any URL scheme supported by Qt. @@ -831,9 +859,9 @@ void QFxImage::setSource(const QString &url) if (url == d->source) return; - if (d->reply) { - d->reply->deleteLater(); - d->reply = 0; + if (d->sciReply) { + d->sciReply->deleteLater(); + d->sciReply = 0; } if (!d->url.isEmpty()) @@ -844,10 +872,25 @@ void QFxImage::setSource(const QString &url) d->source = url; d->url = qmlContext(this)->resolvedUrl(url); d->sciurl = QUrl(); + if (d->progress != 0.0) { + d->progress = 0.0; + emit progressChanged(d->progress); + } if (url.isEmpty()) { setPixmap(QPixmap()); d->status = Idle; + d->progress = 1.0; + setImplicitWidth(0); + setImplicitHeight(0); +#if defined(QFX_RENDER_OPENGL) + d->_texDirty = true; + d->_tex.clear(); +#endif + emit statusChanged(d->status); + emit sourceChanged(d->source); + emit progressChanged(1.0); + update(); } else { d->status = Loading; if (d->url.path().endsWith(QLatin1String(".sci"))) { @@ -861,12 +904,19 @@ void QFxImage::setSource(const QString &url) { QNetworkRequest req(d->url); req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); - d->reply = qmlEngine(this)->networkAccessManager()->get(req); - QObject::connect(d->reply, SIGNAL(finished()), + d->sciReply = qmlEngine(this)->networkAccessManager()->get(req); + QObject::connect(d->sciReply, SIGNAL(finished()), this, SLOT(sciRequestFinished())); } } else { - QFxPixmap::get(qmlEngine(this), d->url, this, SLOT(requestFinished())); + d->reply = QFxPixmap::get(qmlEngine(this), d->url, this, SLOT(requestFinished())); + if (d->reply) { + connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), + this, SLOT(requestProgress(qint64,qint64))); + } else { + d->progress = 1.0; + emit progressChanged(d->progress); + } } } @@ -879,6 +929,12 @@ void QFxImage::requestFinished() if (d->url.path().endsWith(QLatin1String(".sci"))) { d->_pix = QFxPixmap(d->sciurl); } else { + if (d->reply) { + disconnect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), + this, SLOT(requestProgress(qint64,qint64))); + if (d->reply->error() != QNetworkReply::NoError) + d->status = Error; + } d->_pix = QFxPixmap(d->url); d->_pix.setOpaque(d->_opaque); setOptions(QFxImage::SimpleItem, true); @@ -886,32 +942,43 @@ void QFxImage::requestFinished() setImplicitWidth(d->_pix.width()); setImplicitHeight(d->_pix.height()); - d->status = Idle; + if (d->status == Loading) + d->status = Idle; + d->progress = 1.0; #if defined(QFX_RENDER_OPENGL) d->_texDirty = true; d->_tex.clear(); #endif emit statusChanged(d->status); emit sourceChanged(d->source); + emit progressChanged(1.0); update(); } void QFxImage::sciRequestFinished() { Q_D(QFxImage); - if (d->reply->error() != QNetworkReply::NoError) { + if (d->sciReply->error() != QNetworkReply::NoError) { d->status = Error; - d->reply->deleteLater(); - d->reply = 0; + d->sciReply->deleteLater(); + d->sciReply = 0; emit statusChanged(d->status); } else { - QFxGridScaledImage sci(d->reply); - d->reply->deleteLater(); - d->reply = 0; + QFxGridScaledImage sci(d->sciReply); + d->sciReply->deleteLater(); + d->sciReply = 0; setGridScaledImage(sci); } } +void QFxImage::requestProgress(qint64 received, qint64 total) +{ + Q_D(QFxImage); + if (d->status == Loading && total > 0) { + d->progress = qreal(received)/total; + emit progressChanged(d->progress); + } +} void QFxImage::setGridScaledImage(const QFxGridScaledImage& sci) { @@ -921,7 +988,14 @@ void QFxImage::setGridScaledImage(const QFxGridScaledImage& sci) emit statusChanged(d->status); } else { d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl())); - QFxPixmap::get(qmlEngine(this), d->sciurl, this, SLOT(requestFinished())); + d->reply = QFxPixmap::get(qmlEngine(this), d->sciurl, this, SLOT(requestFinished())); + if (d->reply) { + connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), + this, SLOT(requestProgress(qint64,qint64))); + } else { + d->progress = 1.0; + emit progressChanged(d->progress); + } QFxScaleGrid *sg = scaleGrid(); sg->setTop(sci.gridTop()); sg->setBottom(sci.gridBottom()); diff --git a/src/declarative/fx/qfximage.h b/src/declarative/fx/qfximage.h index 37fe5be..dc13a97 100644 --- a/src/declarative/fx/qfximage.h +++ b/src/declarative/fx/qfximage.h @@ -43,6 +43,7 @@ #define QFXIMAGE_H #include <qfxitem.h> +#include <QtNetwork/qnetworkreply.h> QT_BEGIN_HEADER @@ -58,6 +59,7 @@ class Q_DECLARATIVE_EXPORT QFxImage : public QFxItem Q_PROPERTY(Status status READ status NOTIFY statusChanged) Q_PROPERTY(QString source READ source WRITE setSource NOTIFY sourceChanged) + Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) Q_PROPERTY(QFxScaleGrid *scaleGrid READ scaleGrid) Q_PROPERTY(bool tile READ isTiled WRITE setTiled) @@ -84,6 +86,7 @@ public: enum Status { Idle, Loading, Error }; Status status() const; + qreal progress() const; QString source() const; virtual void setSource(const QString &url); @@ -101,6 +104,7 @@ public: Q_SIGNALS: void sourceChanged(const QString &); void statusChanged(Status); + void progressChanged(qreal progress); protected: QFxImage(QFxImagePrivate &dd, QFxItem *parent); @@ -109,6 +113,7 @@ protected: private Q_SLOTS: void requestFinished(); void sciRequestFinished(); + void requestProgress(qint64,qint64); private: Q_DISABLE_COPY(QFxImage) diff --git a/src/declarative/fx/qfximage_p.h b/src/declarative/fx/qfximage_p.h index fbb4c44..8227ce4 100644 --- a/src/declarative/fx/qfximage_p.h +++ b/src/declarative/fx/qfximage_p.h @@ -76,7 +76,7 @@ public: #if defined(QFX_RENDER_OPENGL) _texDirty(true), #endif - status(QFxImage::Idle), reply(0) + status(QFxImage::Idle), sciReply(0), progress(0.0) { } @@ -95,10 +95,10 @@ public: } QFxScaleGrid *_scaleGrid; - bool _tiled; QFxPixmap _pix; - bool _smooth; - bool _opaque; + bool _tiled : 1; + bool _smooth : 1; + bool _opaque : 1; #if defined(QFX_RENDER_OPENGL) void checkDirty(); bool _texDirty; @@ -109,7 +109,9 @@ public: QString source; QUrl url; QUrl sciurl; - QNetworkReply *reply; + QNetworkReply *sciReply; + QPointer<QNetworkReply> reply; + qreal progress; }; QT_END_NAMESPACE diff --git a/src/declarative/fx/qfxpixmap.cpp b/src/declarative/fx/qfxpixmap.cpp index 0d456c6..3fdd8e5 100644 --- a/src/declarative/fx/qfxpixmap.cpp +++ b/src/declarative/fx/qfxpixmap.cpp @@ -233,8 +233,11 @@ QFxPixmap::operator const QSimpleCanvasConfig::Image &() const Starts a network request to load \a url. When the URL is loaded, the given slot is invoked. Note that if the image is already cached, the slot may be invoked immediately. + + Returns a QNetworkReply if the image is not immediately available, otherwise + returns 0. The QNetworkReply must not be stored - it may be destroyed at any time. */ -void QFxPixmap::get(QmlEngine *engine, const QUrl& url, QObject* obj, const char* slot) +QNetworkReply *QFxPixmap::get(QmlEngine *engine, const QUrl& url, QObject* obj, const char* slot) { QString key = url.toString(); QFxPixmapCache::Iterator iter = qfxPixmapCache.find(key); @@ -259,11 +262,14 @@ void QFxPixmap::get(QmlEngine *engine, const QUrl& url, QObject* obj, const char if ((*iter)->reply) { // still loading QObject::connect((*iter)->reply, SIGNAL(finished()), obj, slot); + return (*iter)->reply; } else { // already loaded QObject dummy; QObject::connect(&dummy, SIGNAL(destroyed()), obj, slot); } + + return 0; } /*! diff --git a/src/declarative/fx/qfxpixmap.h b/src/declarative/fx/qfxpixmap.h index 9a3ba4e..748991e 100644 --- a/src/declarative/fx/qfxpixmap.h +++ b/src/declarative/fx/qfxpixmap.h @@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) class QmlEngine; +class QNetworkReply; class QFxPixmapPrivate; class Q_DECLARATIVE_EXPORT QFxPixmap { @@ -65,7 +66,7 @@ public: QFxPixmap &operator=(const QFxPixmap &); - static void get(QmlEngine *, const QUrl& url, QObject*, const char* slot); + static QNetworkReply *get(QmlEngine *, const QUrl& url, QObject*, const char* slot); static void cancelGet(const QUrl& url, QObject* obj, const char* slot); bool isNull() const; |