1 // Commit: af33f9f2e7ec433b81f5c18e3e7395db4a56c5fe
2 /****************************************************************************
4 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
5 ** All rights reserved.
6 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 ** This file is part of the QtDeclarative module of the Qt Toolkit.
10 ** $QT_BEGIN_LICENSE:LGPL$
11 ** No Commercial Usage
12 ** This file contains pre-release code and may not be distributed.
13 ** You may use this file in accordance with the terms and conditions
14 ** contained in the Technology Preview License Agreement accompanying
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
41 ****************************************************************************/
43 #include "qsganimatedimage_p.h"
44 #include "qsganimatedimage_p_p.h"
48 #include <QtDeclarative/qdeclarativeinfo.h>
49 #include <QtGui/qmovie.h>
50 #include <QtNetwork/qnetworkrequest.h>
51 #include <QtNetwork/qnetworkreply.h>
53 #include <private/qdeclarativeengine_p.h>
57 QSGAnimatedImage::QSGAnimatedImage(QSGItem *parent)
58 : QSGImage(*(new QSGAnimatedImagePrivate), parent)
62 QSGAnimatedImage::~QSGAnimatedImage()
64 Q_D(QSGAnimatedImage);
68 bool QSGAnimatedImage::isPaused() const
70 Q_D(const QSGAnimatedImage);
73 return d->_movie->state()==QMovie::Paused;
76 void QSGAnimatedImage::setPaused(bool pause)
78 Q_D(QSGAnimatedImage);
79 if(pause == d->paused)
84 d->_movie->setPaused(pause);
87 bool QSGAnimatedImage::isPlaying() const
89 Q_D(const QSGAnimatedImage);
92 return d->_movie->state()!=QMovie::NotRunning;
95 void QSGAnimatedImage::setPlaying(bool play)
97 Q_D(QSGAnimatedImage);
98 if(play == d->playing)
109 int QSGAnimatedImage::currentFrame() const
111 Q_D(const QSGAnimatedImage);
113 return d->preset_currentframe;
114 return d->_movie->currentFrameNumber();
117 void QSGAnimatedImage::setCurrentFrame(int frame)
119 Q_D(QSGAnimatedImage);
121 d->preset_currentframe = frame;
124 d->_movie->jumpToFrame(frame);
127 int QSGAnimatedImage::frameCount() const
129 Q_D(const QSGAnimatedImage);
132 return d->_movie->frameCount();
135 void QSGAnimatedImage::setSource(const QUrl &url)
137 Q_D(QSGAnimatedImage);
145 d->reply->deleteLater();
150 emit sourceChanged(d->url);
152 if (isComponentComplete())
156 void QSGAnimatedImage::load()
158 Q_D(QSGAnimatedImage);
160 QSGImageBase::Status oldStatus = d->status;
161 qreal oldProgress = d->progress;
163 if (d->url.isEmpty()) {
165 d->setPixmap(QPixmap());
168 if (d->status != oldStatus)
169 emit statusChanged(d->status);
170 if (d->progress != oldProgress)
171 emit progressChanged(d->progress);
173 #ifndef QT_NO_LOCALFILE_OPTIMIZED_QML
174 QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(d->url);
176 //### should be unified with movieRequestFinished
177 d->_movie = new QMovie(lf);
178 if (!d->_movie->isValid()){
179 qmlInfo(this) << "Error Reading Animated Image File " << d->url.toString();
183 if (d->status != oldStatus)
184 emit statusChanged(d->status);
187 connect(d->_movie, SIGNAL(stateChanged(QMovie::MovieState)),
188 this, SLOT(playingStatusChanged()));
189 connect(d->_movie, SIGNAL(frameChanged(int)),
190 this, SLOT(movieUpdate()));
191 d->_movie->setCacheMode(QMovie::CacheAll);
195 d->_movie->jumpToFrame(0);
197 d->_movie->setPaused(true);
198 d->setPixmap(d->_movie->currentPixmap());
201 if (d->status != oldStatus)
202 emit statusChanged(d->status);
203 if (d->progress != oldProgress)
204 emit progressChanged(d->progress);
210 emit statusChanged(d->status);
211 emit progressChanged(d->progress);
212 QNetworkRequest req(d->url);
213 req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
214 d->reply = qmlEngine(this)->networkAccessManager()->get(req);
215 QObject::connect(d->reply, SIGNAL(finished()),
216 this, SLOT(movieRequestFinished()));
217 QObject::connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)),
218 this, SLOT(requestProgress(qint64,qint64)));
222 #define ANIMATEDIMAGE_MAXIMUM_REDIRECT_RECURSION 16
224 void QSGAnimatedImage::movieRequestFinished()
226 Q_D(QSGAnimatedImage);
229 if (d->redirectCount < ANIMATEDIMAGE_MAXIMUM_REDIRECT_RECURSION) {
230 QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
231 if (redirect.isValid()) {
232 QUrl url = d->reply->url().resolved(redirect.toUrl());
233 d->reply->deleteLater();
241 d->_movie = new QMovie(d->reply);
242 if (!d->_movie->isValid()){
243 #ifndef QT_NO_DEBUG_STREAM
244 qmlInfo(this) << "Error Reading Animated Image File " << d->url;
249 emit statusChanged(d->status);
252 connect(d->_movie, SIGNAL(stateChanged(QMovie::MovieState)),
253 this, SLOT(playingStatusChanged()));
254 connect(d->_movie, SIGNAL(frameChanged(int)),
255 this, SLOT(movieUpdate()));
256 d->_movie->setCacheMode(QMovie::CacheAll);
259 if (d->paused || !d->playing) {
260 d->_movie->jumpToFrame(d->preset_currentframe);
261 d->preset_currentframe = 0;
264 d->_movie->setPaused(true);
265 d->setPixmap(d->_movie->currentPixmap());
267 emit statusChanged(d->status);
270 void QSGAnimatedImage::movieUpdate()
272 Q_D(QSGAnimatedImage);
273 d->setPixmap(d->_movie->currentPixmap());
277 void QSGAnimatedImage::playingStatusChanged()
279 Q_D(QSGAnimatedImage);
280 if((d->_movie->state() != QMovie::NotRunning) != d->playing){
281 d->playing = (d->_movie->state() != QMovie::NotRunning);
282 emit playingChanged();
284 if((d->_movie->state() == QMovie::Paused) != d->paused){
285 d->playing = (d->_movie->state() == QMovie::Paused);
286 emit pausedChanged();
290 void QSGAnimatedImage::componentComplete()
292 Q_D(QSGAnimatedImage);
293 QSGItem::componentComplete(); // NOT QSGImage
294 if (d->url.isValid())
297 setCurrentFrame(d->preset_currentframe);
298 d->preset_currentframe = 0;
304 #endif // QT_NO_MOVIE