source: trunk/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp@ 1119

Last change on this file since 1119 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 10.0 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtDeclarative module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "private/qdeclarativeanimatedimage_p.h"
43#include "private/qdeclarativeanimatedimage_p_p.h"
44
45#ifndef QT_NO_MOVIE
46
47#include <qdeclarativeinfo.h>
48#include <private/qdeclarativeengine_p.h>
49
50#include <QMovie>
51#include <QNetworkRequest>
52#include <QNetworkReply>
53
54QT_BEGIN_NAMESPACE
55
56/*!
57 \qmlclass AnimatedImage QDeclarativeAnimatedImage
58 \inherits Image
59 \since 4.7
60 \ingroup basic-visual-elements
61
62 The AnimatedImage element extends the features of the \l Image element, providing
63 a way to play animations stored as images containing a series of frames,
64 such as those stored in GIF files.
65
66 Information about the current frame and totla length of the animation can be
67 obtained using the \l currentFrame and \l frameCount properties. You can
68 start, pause and stop the animation by changing the values of the \l playing
69 and \l paused properties.
70
71 The full list of supported formats can be determined with QMovie::supportedFormats().
72
73 \section1 Example Usage
74
75 \beginfloatleft
76 \image animatedimageitem.gif
77 \endfloat
78
79 The following QML shows how to display an animated image and obtain information
80 about its state, such as the current frame and total number of frames.
81 The result is an animated image with a simple progress indicator underneath it.
82
83 \clearfloat
84 \snippet doc/src/snippets/declarative/animatedimage.qml document
85
86 \sa BorderImage, Image
87*/
88
89QDeclarativeAnimatedImage::QDeclarativeAnimatedImage(QDeclarativeItem *parent)
90 : QDeclarativeImage(*(new QDeclarativeAnimatedImagePrivate), parent)
91{
92}
93
94QDeclarativeAnimatedImage::~QDeclarativeAnimatedImage()
95{
96 Q_D(QDeclarativeAnimatedImage);
97 delete d->_movie;
98}
99
100/*!
101 \qmlproperty bool AnimatedImage::paused
102 This property holds whether the animated image is paused.
103
104 By default, this property is false. Set it to true when you want to pause
105 the animation.
106*/
107bool QDeclarativeAnimatedImage::isPaused() const
108{
109 Q_D(const QDeclarativeAnimatedImage);
110 if(!d->_movie)
111 return false;
112 return d->_movie->state()==QMovie::Paused;
113}
114
115void QDeclarativeAnimatedImage::setPaused(bool pause)
116{
117 Q_D(QDeclarativeAnimatedImage);
118 if(pause == d->paused)
119 return;
120 d->paused = pause;
121 if(!d->_movie)
122 return;
123 d->_movie->setPaused(pause);
124}
125/*!
126 \qmlproperty bool AnimatedImage::playing
127 This property holds whether the animated image is playing.
128
129 By defaults, this property is true, meaning that the animation
130 will start playing immediately.
131*/
132bool QDeclarativeAnimatedImage::isPlaying() const
133{
134 Q_D(const QDeclarativeAnimatedImage);
135 if (!d->_movie)
136 return false;
137 return d->_movie->state()!=QMovie::NotRunning;
138}
139
140void QDeclarativeAnimatedImage::setPlaying(bool play)
141{
142 Q_D(QDeclarativeAnimatedImage);
143 if(play == d->playing)
144 return;
145 d->playing = play;
146 if (!d->_movie)
147 return;
148 if (play)
149 d->_movie->start();
150 else
151 d->_movie->stop();
152}
153
154/*!
155 \qmlproperty int AnimatedImage::currentFrame
156 \qmlproperty int AnimatedImage::frameCount
157
158 currentFrame is the frame that is currently visible. By monitoring this property
159 for changes, you can animate other items at the same time as the image.
160
161 frameCount is the number of frames in the animation. For some animation formats,
162 frameCount is unknown and has a value of zero.
163*/
164int QDeclarativeAnimatedImage::currentFrame() const
165{
166 Q_D(const QDeclarativeAnimatedImage);
167 if (!d->_movie)
168 return d->preset_currentframe;
169 return d->_movie->currentFrameNumber();
170}
171
172void QDeclarativeAnimatedImage::setCurrentFrame(int frame)
173{
174 Q_D(QDeclarativeAnimatedImage);
175 if (!d->_movie) {
176 d->preset_currentframe = frame;
177 return;
178 }
179 d->_movie->jumpToFrame(frame);
180}
181
182int QDeclarativeAnimatedImage::frameCount() const
183{
184 Q_D(const QDeclarativeAnimatedImage);
185 if (!d->_movie)
186 return 0;
187 return d->_movie->frameCount();
188}
189
190void QDeclarativeAnimatedImage::setSource(const QUrl &url)
191{
192 Q_D(QDeclarativeAnimatedImage);
193 if (url == d->url)
194 return;
195
196 delete d->_movie;
197 d->_movie = 0;
198
199 if (d->reply) {
200 d->reply->deleteLater();
201 d->reply = 0;
202 }
203
204 d->url = url;
205
206 if (url.isEmpty()) {
207 delete d->_movie;
208 d->status = Null;
209 } else {
210#ifndef QT_NO_LOCALFILE_OPTIMIZED_QML
211 QString lf = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url);
212 if (!lf.isEmpty()) {
213 //### should be unified with movieRequestFinished
214 d->_movie = new QMovie(lf);
215 if (!d->_movie->isValid()){
216 qmlInfo(this) << "Error Reading Animated Image File " << d->url.toString();
217 delete d->_movie;
218 d->_movie = 0;
219 return;
220 }
221 connect(d->_movie, SIGNAL(stateChanged(QMovie::MovieState)),
222 this, SLOT(playingStatusChanged()));
223 connect(d->_movie, SIGNAL(frameChanged(int)),
224 this, SLOT(movieUpdate()));
225 d->_movie->setCacheMode(QMovie::CacheAll);
226 if(d->playing)
227 d->_movie->start();
228 else
229 d->_movie->jumpToFrame(0);
230 if(d->paused)
231 d->_movie->setPaused(true);
232 d->setPixmap(d->_movie->currentPixmap());
233 d->status = Ready;
234 d->progress = 1.0;
235 emit statusChanged(d->status);
236 emit sourceChanged(d->url);
237 emit progressChanged(d->progress);
238 return;
239 }
240#endif
241 d->status = Loading;
242 QNetworkRequest req(d->url);
243 req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
244 d->reply = qmlEngine(this)->networkAccessManager()->get(req);
245 QObject::connect(d->reply, SIGNAL(finished()),
246 this, SLOT(movieRequestFinished()));
247 }
248
249 emit statusChanged(d->status);
250}
251
252#define ANIMATEDIMAGE_MAXIMUM_REDIRECT_RECURSION 16
253
254void QDeclarativeAnimatedImage::movieRequestFinished()
255{
256 Q_D(QDeclarativeAnimatedImage);
257
258 d->redirectCount++;
259 if (d->redirectCount < ANIMATEDIMAGE_MAXIMUM_REDIRECT_RECURSION) {
260 QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
261 if (redirect.isValid()) {
262 QUrl url = d->reply->url().resolved(redirect.toUrl());
263 d->reply->deleteLater();
264 d->reply = 0;
265 setSource(url);
266 return;
267 }
268 }
269 d->redirectCount=0;
270
271 d->_movie = new QMovie(d->reply);
272 if (!d->_movie->isValid()){
273#ifndef QT_NO_DEBUG_STREAM
274 qmlInfo(this) << "Error Reading Animated Image File " << d->url;
275#endif
276 delete d->_movie;
277 d->_movie = 0;
278 return;
279 }
280 connect(d->_movie, SIGNAL(stateChanged(QMovie::MovieState)),
281 this, SLOT(playingStatusChanged()));
282 connect(d->_movie, SIGNAL(frameChanged(int)),
283 this, SLOT(movieUpdate()));
284 d->_movie->setCacheMode(QMovie::CacheAll);
285 if(d->playing)
286 d->_movie->start();
287 if (d->paused || !d->playing) {
288 d->_movie->jumpToFrame(d->preset_currentframe);
289 d->preset_currentframe = 0;
290 }
291 if(d->paused)
292 d->_movie->setPaused(true);
293 d->setPixmap(d->_movie->currentPixmap());
294}
295
296void QDeclarativeAnimatedImage::movieUpdate()
297{
298 Q_D(QDeclarativeAnimatedImage);
299 d->setPixmap(d->_movie->currentPixmap());
300 emit frameChanged();
301}
302
303void QDeclarativeAnimatedImage::playingStatusChanged()
304{
305 Q_D(QDeclarativeAnimatedImage);
306 if((d->_movie->state() != QMovie::NotRunning) != d->playing){
307 d->playing = (d->_movie->state() != QMovie::NotRunning);
308 emit playingChanged();
309 }
310 if((d->_movie->state() == QMovie::Paused) != d->paused){
311 d->playing = (d->_movie->state() == QMovie::Paused);
312 emit pausedChanged();
313 }
314}
315
316void QDeclarativeAnimatedImage::componentComplete()
317{
318 Q_D(QDeclarativeAnimatedImage);
319 QDeclarativeItem::componentComplete(); // NOT QDeclarativeImage
320 if (!d->reply) {
321 setCurrentFrame(d->preset_currentframe);
322 d->preset_currentframe = 0;
323 }
324}
325
326QT_END_NAMESPACE
327
328#endif // QT_NO_MOVIE
Note: See TracBrowser for help on using the repository browser.