source: trunk/src/gui/image/qmovie.cpp@ 651

Last change on this file since 651 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 28.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui 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 [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \class QMovie
44
45 \brief The QMovie class is a convenience class for playing movies
46 with QImageReader.
47
48 \ingroup painting
49
50 This class is used to show simple animations without sound. If you want
51 to display video and media content, use the \l{Phonon Module}{Phonon}
52 multimedia framework instead.
53
54 First, create a QMovie object by passing either the name of a file or a
55 pointer to a QIODevice containing an animated image format to QMovie's
56 constructor. You can call isValid() to check if the image data is valid,
57 before starting the movie. To start the movie, call start(). QMovie will
58 enter \l Running state, and emit started() and stateChanged(). To get the
59 current state of the movie, call state().
60
61 To display the movie in your application, you can pass your QMovie object
62 to QLabel::setMovie(). Example:
63
64 \snippet doc/src/snippets/code/src_gui_image_qmovie.cpp 0
65
66 Whenever a new frame is available in the movie, QMovie will emit
67 updated(). If the size of the frame changes, resized() is emitted. You can
68 call currentImage() or currentPixmap() to get a copy of the current
69 frame. When the movie is done, QMovie emits finished(). If any error
70 occurs during playback (i.e, the image file is corrupt), QMovie will emit
71 error().
72
73 You can control the speed of the movie playback by calling setSpeed(),
74 which takes the percentage of the original speed as an argument. Pause the
75 movie by calling setPaused(true). QMovie will then enter \l Paused state
76 and emit stateChanged(). If you call setPaused(false), QMovie will reenter
77 \l Running state and start the movie again. To stop the movie, call
78 stop().
79
80 Certain animation formats allow you to set the background color. You can
81 call setBackgroundColor() to set the color, or backgroundColor() to
82 retrieve the current background color.
83
84 currentFrameNumber() returns the sequence number of the current frame. The
85 first frame in the animation has the sequence number 0. frameCount()
86 returns the total number of frames in the animation, if the image format
87 supports this. You can call loopCount() to get the number of times the
88 movie should loop before finishing. nextFrameDelay() returns the number of
89 milliseconds the current frame should be displayed.
90
91 QMovie can be instructed to cache frames of an animation by calling
92 setCacheMode().
93
94 Call supportedFormats() for a list of formats that QMovie supports.
95
96 \sa QLabel, QImageReader, {Movie Example}
97*/
98
99/*! \enum QMovie::MovieState
100
101 This enum describes the different states of QMovie.
102
103 \value NotRunning The movie is not running. This is QMovie's initial
104 state, and the state it enters after stop() has been called or the movie
105 is finished.
106
107 \value Paused The movie is paused, and QMovie stops emitting updated() or
108 resized(). This state is entered after calling pause() or
109 setPaused(true). The current frame number it kept, and the movie will
110 continue with the next frame when unpause() or setPaused(false) is called.
111
112 \value Running The movie is running.
113*/
114
115/*! \enum QMovie::CacheMode
116
117 This enum describes the different cache modes of QMovie.
118
119 \value CacheNone No frames are cached (the default).
120
121 \value CacheAll All frames are cached.
122*/
123
124/*! \fn void QMovie::started()
125
126 This signal is emitted after QMovie::start() has been called, and QMovie
127 has entered QMovie::Running state.
128*/
129
130/*! \fn void QMovie::resized(const QSize &size)
131
132 This signal is emitted when the current frame has been resized to \a
133 size. This effect is sometimes used in animations as an alternative to
134 replacing the frame. You can call currentImage() or currentPixmap() to get a
135 copy of the updated frame.
136*/
137
138/*! \fn void QMovie::updated(const QRect &rect)
139
140 This signal is emitted when the rect \a rect in the current frame has been
141 updated. You can call currentImage() or currentPixmap() to get a copy of the
142 updated frame.
143*/
144
145/*! \fn void QMovie::frameChanged(int frameNumber)
146 \since 4.1
147
148 This signal is emitted when the frame number has changed to
149 \a frameNumber. You can call currentImage() or currentPixmap() to get a
150 copy of the frame.
151*/
152
153/*!
154 \fn void QMovie::stateChanged(QMovie::MovieState state)
155
156 This signal is emitted every time the state of the movie changes. The new
157 state is specified by \a state.
158
159 \sa QMovie::state()
160*/
161
162/*! \fn void QMovie::error(QImageReader::ImageReaderError error)
163
164 This signal is emitted by QMovie when the error \a error occurred during
165 playback. QMovie will stop the movie, and enter QMovie::NotRunning state.
166*/
167
168/*! \fn void QMovie::finished()
169
170 This signal is emitted when the movie has finished.
171
172 \sa QMovie::stop()
173*/
174
175#include "qglobal.h"
176
177#ifndef QT_NO_MOVIE
178
179#include "qmovie.h"
180#include "qimage.h"
181#include "qimagereader.h"
182#include "qpixmap.h"
183#include "qrect.h"
184#include "qdatetime.h"
185#include "qtimer.h"
186#include "qpair.h"
187#include "qmap.h"
188#include "qlist.h"
189#include "qbuffer.h"
190#include "qdir.h"
191#include "private/qobject_p.h"
192
193#define QMOVIE_INVALID_DELAY -1
194
195QT_BEGIN_NAMESPACE
196
197class QFrameInfo
198{
199public:
200 QPixmap pixmap;
201 int delay;
202 bool endMark;
203 inline QFrameInfo(bool endMark)
204 : pixmap(QPixmap()), delay(QMOVIE_INVALID_DELAY), endMark(endMark)
205 { }
206
207 inline QFrameInfo()
208 : pixmap(QPixmap()), delay(QMOVIE_INVALID_DELAY), endMark(false)
209 { }
210
211 inline QFrameInfo(const QPixmap &pixmap, int delay)
212 : pixmap(pixmap), delay(delay), endMark(false)
213 { }
214
215 inline bool isValid()
216 {
217 return endMark || !(pixmap.isNull() && (delay == QMOVIE_INVALID_DELAY));
218 }
219
220 inline bool isEndMarker()
221 { return endMark; }
222
223 static inline QFrameInfo endMarker()
224 { return QFrameInfo(true); }
225};
226
227class QMoviePrivate : public QObjectPrivate
228{
229 Q_DECLARE_PUBLIC(QMovie)
230
231public:
232 QMoviePrivate(QMovie *qq);
233 bool isDone();
234 bool next();
235 int speedAdjustedDelay(int delay) const;
236 bool isValid() const;
237 bool jumpToFrame(int frameNumber);
238 int frameCount() const;
239 bool jumpToNextFrame();
240 QFrameInfo infoForFrame(int frameNumber);
241 void reset();
242
243 inline void enterState(QMovie::MovieState newState) {
244 movieState = newState;
245 emit q_func()->stateChanged(newState);
246 }
247
248 // private slots
249 void _q_loadNextFrame();
250 void _q_loadNextFrame(bool starting);
251
252 QImageReader *reader;
253 int speed;
254 QMovie::MovieState movieState;
255 QRect frameRect;
256 QPixmap currentPixmap;
257 int currentFrameNumber;
258 int nextFrameNumber;
259 int greatestFrameNumber;
260 int nextDelay;
261 int playCounter;
262 qint64 initialDevicePos;
263 QMovie::CacheMode cacheMode;
264 bool haveReadAll;
265 bool isFirstIteration;
266 QMap<int, QFrameInfo> frameMap;
267 QString absoluteFilePath;
268
269 QTimer nextImageTimer;
270};
271
272/*! \internal
273 */
274QMoviePrivate::QMoviePrivate(QMovie *qq)
275 : reader(0), speed(100), movieState(QMovie::NotRunning),
276 currentFrameNumber(-1), nextFrameNumber(0), greatestFrameNumber(-1),
277 nextDelay(0), playCounter(-1),
278 cacheMode(QMovie::CacheNone), haveReadAll(false), isFirstIteration(true)
279{
280 q_ptr = qq;
281 nextImageTimer.setSingleShot(true);
282}
283
284/*! \internal
285 */
286void QMoviePrivate::reset()
287{
288 nextImageTimer.stop();
289 if (reader->device())
290 initialDevicePos = reader->device()->pos();
291 currentFrameNumber = -1;
292 nextFrameNumber = 0;
293 greatestFrameNumber = -1;
294 nextDelay = 0;
295 playCounter = -1;
296 haveReadAll = false;
297 isFirstIteration = true;
298 frameMap.clear();
299}
300
301/*! \internal
302 */
303bool QMoviePrivate::isDone()
304{
305 return (playCounter == 0);
306}
307
308/*!
309 \internal
310
311 Given the original \a delay, this function returns the
312 actual number of milliseconds to delay according to
313 the current speed. E.g. if the speed is 200%, the
314 result will be half of the original delay.
315*/
316int QMoviePrivate::speedAdjustedDelay(int delay) const
317{
318 return int( (qint64(delay) * qint64(100) ) / qint64(speed) );
319}
320
321/*!
322 \internal
323
324 Returns the QFrameInfo for the given \a frameNumber.
325
326 If the frame number is invalid, an invalid QFrameInfo is
327 returned.
328
329 If the end of the animation has been reached, a
330 special end marker QFrameInfo is returned.
331
332*/
333QFrameInfo QMoviePrivate::infoForFrame(int frameNumber)
334{
335 if (frameNumber < 0)
336 return QFrameInfo(); // Invalid
337
338 if (haveReadAll && (frameNumber > greatestFrameNumber)) {
339 if (frameNumber == greatestFrameNumber+1)
340 return QFrameInfo::endMarker();
341 return QFrameInfo(); // Invalid
342 }
343
344 if (cacheMode == QMovie::CacheNone) {
345 if (frameNumber != currentFrameNumber+1) {
346 // Non-sequential frame access
347 if (!reader->jumpToImage(frameNumber)) {
348 if (frameNumber == 0) {
349 // Special case: Attempt to "rewind" so we can loop
350 // ### This could be implemented as QImageReader::rewind()
351 if (reader->device()->isSequential())
352 return QFrameInfo(); // Invalid
353 QString fileName = reader->fileName();
354 QByteArray format = reader->format();
355 QIODevice *device = reader->device();
356 QColor bgColor = reader->backgroundColor();
357 QSize scaledSize = reader->scaledSize();
358 delete reader;
359 if (fileName.isEmpty())
360 reader = new QImageReader(device, format);
361 else
362 reader = new QImageReader(absoluteFilePath, format);
363 (void)reader->canRead(); // Provoke a device->open() call
364 reader->device()->seek(initialDevicePos);
365 reader->setBackgroundColor(bgColor);
366 reader->setScaledSize(scaledSize);
367 } else {
368 return QFrameInfo(); // Invalid
369 }
370 }
371 }
372 if (reader->canRead()) {
373 // reader says we can read. Attempt to actually read image
374 QImage anImage = reader->read();
375 if (anImage.isNull()) {
376 // Reading image failed.
377 return QFrameInfo(); // Invalid
378 }
379 if (frameNumber > greatestFrameNumber)
380 greatestFrameNumber = frameNumber;
381 QPixmap aPixmap = QPixmap::fromImage(anImage);
382 int aDelay = reader->nextImageDelay();
383 return QFrameInfo(aPixmap, aDelay);
384 } else {
385 // We've read all frames now. Return an end marker
386 haveReadAll = true;
387 return QFrameInfo::endMarker();
388 }
389 }
390
391 // CacheMode == CacheAll
392 if (frameNumber > greatestFrameNumber) {
393 // Frame hasn't been read from file yet. Try to do it
394 for (int i = greatestFrameNumber + 1; i <= frameNumber; ++i) {
395 if (reader->canRead()) {
396 // reader says we can read. Attempt to actually read image
397 QImage anImage = reader->read();
398 if (anImage.isNull()) {
399 // Reading image failed.
400 return QFrameInfo(); // Invalid
401 }
402 greatestFrameNumber = i;
403 QPixmap aPixmap = QPixmap::fromImage(anImage);
404 int aDelay = reader->nextImageDelay();
405 QFrameInfo info(aPixmap, aDelay);
406 // Cache it!
407 frameMap.insert(i, info);
408 if (i == frameNumber) {
409 return info;
410 }
411 } else {
412 // We've read all frames now. Return an end marker
413 haveReadAll = true;
414 return QFrameInfo::endMarker();
415 }
416 }
417 }
418 // Return info for requested (cached) frame
419 return frameMap.value(frameNumber);
420}
421
422/*!
423 \internal
424
425 Attempts to advance the animation to the next frame.
426 If successful, currentFrameNumber, currentPixmap and
427 nextDelay are updated accordingly, and true is returned.
428 Otherwise, false is returned.
429 When false is returned, isDone() can be called to
430 determine whether the animation ended gracefully or
431 an error occurred when reading the frame.
432*/
433bool QMoviePrivate::next()
434{
435 QTime time;
436 time.start();
437 QFrameInfo info = infoForFrame(nextFrameNumber);
438 if (!info.isValid())
439 return false;
440 if (info.isEndMarker()) {
441 // We reached the end of the animation.
442 if (isFirstIteration) {
443 if (nextFrameNumber == 0) {
444 // No frames could be read at all (error).
445 return false;
446 }
447 // End of first iteration. Initialize play counter
448 playCounter = reader->loopCount();
449 isFirstIteration = false;
450 }
451 // Loop as appropriate
452 if (playCounter != 0) {
453 if (playCounter != -1) // Infinite?
454 playCounter--; // Nope
455 nextFrameNumber = 0;
456 return next();
457 }
458 // Loop no more. Done
459 return false;
460 }
461 // Image and delay OK, update internal state
462 currentFrameNumber = nextFrameNumber++;
463 QSize scaledSize = reader->scaledSize();
464 if (scaledSize.isValid() && (scaledSize != info.pixmap.size()))
465 currentPixmap = QPixmap::fromImage( info.pixmap.toImage().scaled(scaledSize) );
466 else
467 currentPixmap = info.pixmap;
468 nextDelay = speedAdjustedDelay(info.delay);
469 // Adjust delay according to the time it took to read the frame
470 int processingTime = time.elapsed();
471 if (processingTime > nextDelay)
472 nextDelay = 0;
473 else
474 nextDelay = nextDelay - processingTime;
475 return true;
476}
477
478/*! \internal
479 */
480void QMoviePrivate::_q_loadNextFrame()
481{
482 _q_loadNextFrame(false);
483}
484
485void QMoviePrivate::_q_loadNextFrame(bool starting)
486{
487 Q_Q(QMovie);
488 if (next()) {
489 if (starting && movieState == QMovie::NotRunning) {
490 enterState(QMovie::Running);
491 emit q->started();
492 }
493
494 if (frameRect.size() != currentPixmap.rect().size()) {
495 frameRect = currentPixmap.rect();
496 emit q->resized(frameRect.size());
497 }
498
499 emit q->updated(frameRect);
500 emit q->frameChanged(currentFrameNumber);
501
502 if (movieState == QMovie::Running)
503 nextImageTimer.start(nextDelay);
504 } else {
505 // Could not read another frame
506 if (!isDone()) {
507 emit q->error(reader->error());
508 }
509
510 // Graceful finish
511 if (movieState != QMovie::Paused) {
512 nextFrameNumber = 0;
513 isFirstIteration = true;
514 playCounter = -1;
515 enterState(QMovie::NotRunning);
516 emit q->finished();
517 }
518 }
519}
520
521/*!
522 \internal
523*/
524bool QMoviePrivate::isValid() const
525{
526 return (greatestFrameNumber >= 0) // have we seen valid data
527 || reader->canRead(); // or does the reader see valid data
528}
529
530/*!
531 \internal
532*/
533bool QMoviePrivate::jumpToFrame(int frameNumber)
534{
535 if (frameNumber < 0)
536 return false;
537 if (currentFrameNumber == frameNumber)
538 return true;
539 nextFrameNumber = frameNumber;
540 if (movieState == QMovie::Running)
541 nextImageTimer.stop();
542 _q_loadNextFrame();
543 return (nextFrameNumber == currentFrameNumber+1);
544}
545
546/*!
547 \internal
548*/
549int QMoviePrivate::frameCount() const
550{
551 int result;
552 if ((result = reader->imageCount()) != 0)
553 return result;
554 if (haveReadAll)
555 return greatestFrameNumber+1;
556 return 0; // Don't know
557}
558
559/*!
560 \internal
561*/
562bool QMoviePrivate::jumpToNextFrame()
563{
564 return jumpToFrame(currentFrameNumber+1);
565}
566
567/*!
568 Constructs a QMovie object, passing the \a parent object to QObject's
569 constructor.
570
571 \sa setFileName(), setDevice(), setFormat()
572 */
573QMovie::QMovie(QObject *parent)
574 : QObject(*new QMoviePrivate(this), parent)
575{
576 Q_D(QMovie);
577 d->reader = new QImageReader;
578 connect(&d->nextImageTimer, SIGNAL(timeout()), this, SLOT(_q_loadNextFrame()));
579}
580
581/*!
582 Constructs a QMovie object. QMovie will use read image data from \a
583 device, which it assumes is open and readable. If \a format is not empty,
584 QMovie will use the image format \a format for decoding the image
585 data. Otherwise, QMovie will attempt to guess the format.
586
587 The \a parent object is passed to QObject's constructor.
588 */
589QMovie::QMovie(QIODevice *device, const QByteArray &format, QObject *parent)
590 : QObject(*new QMoviePrivate(this), parent)
591{
592 Q_D(QMovie);
593 d->reader = new QImageReader(device, format);
594 d->initialDevicePos = device->pos();
595 connect(&d->nextImageTimer, SIGNAL(timeout()), this, SLOT(_q_loadNextFrame()));
596}
597
598/*!
599 Constructs a QMovie object. QMovie will use read image data from \a
600 fileName. If \a format is not empty, QMovie will use the image format \a
601 format for decoding the image data. Otherwise, QMovie will attempt to
602 guess the format.
603
604 The \a parent object is passed to QObject's constructor.
605 */
606QMovie::QMovie(const QString &fileName, const QByteArray &format, QObject *parent)
607 : QObject(*new QMoviePrivate(this), parent)
608{
609 Q_D(QMovie);
610 d->absoluteFilePath = QDir(fileName).absolutePath();
611 d->reader = new QImageReader(fileName, format);
612 if (d->reader->device())
613 d->initialDevicePos = d->reader->device()->pos();
614 connect(&d->nextImageTimer, SIGNAL(timeout()), this, SLOT(_q_loadNextFrame()));
615}
616
617/*!
618 Destructs the QMovie object.
619*/
620QMovie::~QMovie()
621{
622 Q_D(QMovie);
623 delete d->reader;
624}
625
626/*!
627 Sets the current device to \a device. QMovie will read image data from
628 this device when the movie is running.
629
630 \sa device(), setFormat()
631*/
632void QMovie::setDevice(QIODevice *device)
633{
634 Q_D(QMovie);
635 d->reader->setDevice(device);
636 d->reset();
637}
638
639/*!
640 Returns the device QMovie reads image data from. If no device has
641 currently been assigned, 0 is returned.
642
643 \sa setDevice(), fileName()
644*/
645QIODevice *QMovie::device() const
646{
647 Q_D(const QMovie);
648 return d->reader->device();
649}
650
651/*!
652 Sets the name of the file that QMovie reads image data from, to \a
653 fileName.
654
655 \sa fileName(), setDevice(), setFormat()
656*/
657void QMovie::setFileName(const QString &fileName)
658{
659 Q_D(QMovie);
660 d->absoluteFilePath = QDir(fileName).absolutePath();
661 d->reader->setFileName(fileName);
662 d->reset();
663}
664
665/*!
666 Returns the name of the file that QMovie reads image data from. If no file
667 name has been assigned, or if the assigned device is not a file, an empty
668 QString is returned.
669
670 \sa setFileName(), device()
671*/
672QString QMovie::fileName() const
673{
674 Q_D(const QMovie);
675 return d->reader->fileName();
676}
677
678/*!
679 Sets the format that QMovie will use when decoding image data, to \a
680 format. By default, QMovie will attempt to guess the format of the image
681 data.
682
683 You can call supportedFormats() for the full list of formats
684 QMovie supports.
685
686 \sa QImageReader::supportedImageFormats()
687*/
688void QMovie::setFormat(const QByteArray &format)
689{
690 Q_D(QMovie);
691 d->reader->setFormat(format);
692}
693
694/*!
695 Returns the format that QMovie uses when decoding image data. If no format
696 has been assigned, an empty QByteArray() is returned.
697
698 \sa setFormat()
699*/
700QByteArray QMovie::format() const
701{
702 Q_D(const QMovie);
703 return d->reader->format();
704}
705
706/*!
707 For image formats that support it, this function sets the background color
708 to \a color.
709
710 \sa backgroundColor()
711*/
712void QMovie::setBackgroundColor(const QColor &color)
713{
714 Q_D(QMovie);
715 d->reader->setBackgroundColor(color);
716}
717
718/*!
719 Returns the background color of the movie. If no background color has been
720 assigned, an invalid QColor is returned.
721
722 \sa setBackgroundColor()
723*/
724QColor QMovie::backgroundColor() const
725{
726 Q_D(const QMovie);
727 return d->reader->backgroundColor();
728}
729
730/*!
731 Returns the current state of QMovie.
732
733 \sa MovieState, stateChanged()
734*/
735QMovie::MovieState QMovie::state() const
736{
737 Q_D(const QMovie);
738 return d->movieState;
739}
740
741/*!
742 Returns the rect of the last frame. If no frame has yet been updated, an
743 invalid QRect is returned.
744
745 \sa currentImage(), currentPixmap()
746*/
747QRect QMovie::frameRect() const
748{
749 Q_D(const QMovie);
750 return d->frameRect;
751}
752
753/*! \fn QImage QMovie::framePixmap() const
754
755 Use currentPixmap() instead.
756*/
757
758/*! \fn void QMovie::pause()
759
760 Use setPaused(true) instead.
761*/
762
763/*! \fn void QMovie::unpause()
764
765 Use setPaused(false) instead.
766*/
767
768/*!
769 Returns the current frame as a QPixmap.
770
771 \sa currentImage(), updated()
772*/
773QPixmap QMovie::currentPixmap() const
774{
775 Q_D(const QMovie);
776 return d->currentPixmap;
777}
778
779/*! \fn QImage QMovie::frameImage() const
780
781 Use currentImage() instead.
782*/
783
784/*!
785 Returns the current frame as a QImage.
786
787 \sa currentPixmap(), updated()
788*/
789QImage QMovie::currentImage() const
790{
791 Q_D(const QMovie);
792 return d->currentPixmap.toImage();
793}
794
795/*!
796 Returns true if the movie is valid (e.g., the image data is readable and
797 the image format is supported); otherwise returns false.
798*/
799bool QMovie::isValid() const
800{
801 Q_D(const QMovie);
802 return d->isValid();
803}
804
805/*! \fn bool QMovie::running() const
806
807 Use state() instead.
808*/
809
810/*! \fn bool QMovie::isNull() const
811
812 Use isValid() instead.
813*/
814
815/*! \fn int QMovie::frameNumber() const
816
817 Use currentFrameNumber() instead.
818*/
819
820/*! \fn bool QMovie::paused() const
821
822 Use state() instead.
823*/
824
825/*! \fn bool QMovie::finished() const
826
827 Use state() instead.
828*/
829
830/*! \fn void QMovie::restart()
831
832 Use stop() and start() instead.
833*/
834
835/*!
836 \fn void QMovie::step()
837
838 Use jumpToNextFrame() instead.
839*/
840
841/*!
842 Returns the number of frames in the movie.
843
844 Certain animation formats do not support this feature, in which
845 case 0 is returned.
846*/
847int QMovie::frameCount() const
848{
849 Q_D(const QMovie);
850 return d->frameCount();
851}
852
853/*!
854 Returns the number of milliseconds QMovie will wait before updating the
855 next frame in the animation.
856*/
857int QMovie::nextFrameDelay() const
858{
859 Q_D(const QMovie);
860 return d->nextDelay;
861}
862
863/*!
864 Returns the sequence number of the current frame. The number of the first
865 frame in the movie is 0.
866*/
867int QMovie::currentFrameNumber() const
868{
869 Q_D(const QMovie);
870 return d->currentFrameNumber;
871}
872
873/*!
874 Jumps to the next frame. Returns true on success; otherwise returns false.
875*/
876bool QMovie::jumpToNextFrame()
877{
878 Q_D(QMovie);
879 return d->jumpToNextFrame();
880}
881
882/*!
883 Jumps to frame number \a frameNumber. Returns true on success; otherwise
884 returns false.
885*/
886bool QMovie::jumpToFrame(int frameNumber)
887{
888 Q_D(QMovie);
889 return d->jumpToFrame(frameNumber);
890}
891
892/*!
893 Returns the number of times the movie will loop before it finishes.
894 If the movie will only play once (no looping), loopCount returns 0.
895 If the movie loops forever, loopCount returns -1.
896
897 Note that, if the image data comes from a sequential device (e.g. a
898 socket), QMovie can only loop the movie if the cacheMode is set to
899 QMovie::CacheAll.
900*/
901int QMovie::loopCount() const
902{
903 Q_D(const QMovie);
904 return d->reader->loopCount();
905}
906
907/*!
908 If \a paused is true, QMovie will enter \l Paused state and emit
909 stateChanged(Paused); otherwise it will enter \l Running state and emit
910 stateChanged(Running).
911
912 \sa state()
913*/
914void QMovie::setPaused(bool paused)
915{
916 Q_D(QMovie);
917 if (paused) {
918 if (d->movieState == NotRunning)
919 return;
920 d->enterState(Paused);
921 d->nextImageTimer.stop();
922 } else {
923 if (d->movieState == Running)
924 return;
925 d->enterState(Running);
926 d->nextImageTimer.start(nextFrameDelay());
927 }
928}
929
930/*!
931 \property QMovie::speed
932 \brief the movie's speed
933
934 The speed is measured in percentage of the original movie speed.
935 The default speed is 100%.
936 Example:
937
938 \snippet doc/src/snippets/code/src_gui_image_qmovie.cpp 1
939*/
940void QMovie::setSpeed(int percentSpeed)
941{
942 Q_D(QMovie);
943 d->speed = percentSpeed;
944}
945
946int QMovie::speed() const
947{
948 Q_D(const QMovie);
949 return d->speed;
950}
951
952/*!
953 Starts the movie. QMovie will enter \l Running state, and start emitting
954 updated() and resized() as the movie progresses.
955
956 If QMovie is in the \l Paused state, this function is equivalent
957 to calling setPaused(false). If QMovie is already in the \l
958 Running state, this function does nothing.
959
960 \sa stop(), setPaused()
961*/
962void QMovie::start()
963{
964 Q_D(QMovie);
965 if (d->movieState == NotRunning) {
966 d->_q_loadNextFrame(true);
967 } else if (d->movieState == Paused) {
968 setPaused(false);
969 }
970}
971
972/*!
973 Stops the movie. QMovie enters \l NotRunning state, and stops emitting
974 updated() and resized(). If start() is called again, the movie will
975 restart from the beginning.
976
977 If QMovie is already in the \l NotRunning state, this function
978 does nothing.
979
980 \sa start(), setPaused()
981*/
982void QMovie::stop()
983{
984 Q_D(QMovie);
985 if (d->movieState == NotRunning)
986 return;
987 d->enterState(NotRunning);
988 d->nextImageTimer.stop();
989 d->nextFrameNumber = 0;
990}
991
992/*!
993 \since 4.1
994
995 Returns the scaled size of frames.
996
997 \sa QImageReader::scaledSize()
998*/
999QSize QMovie::scaledSize()
1000{
1001 Q_D(QMovie);
1002 return d->reader->scaledSize();
1003}
1004
1005/*!
1006 \since 4.1
1007
1008 Sets the scaled frame size to \a size.
1009
1010 \sa QImageReader::setScaledSize()
1011*/
1012void QMovie::setScaledSize(const QSize &size)
1013{
1014 Q_D(QMovie);
1015 d->reader->setScaledSize(size);
1016}
1017
1018/*!
1019 \since 4.1
1020
1021 Returns the list of image formats supported by QMovie.
1022
1023 \sa QImageReader::supportedImageFormats()
1024*/
1025QList<QByteArray> QMovie::supportedFormats()
1026{
1027 QList<QByteArray> list = QImageReader::supportedImageFormats();
1028 QMutableListIterator<QByteArray> it(list);
1029 QBuffer buffer;
1030 buffer.open(QIODevice::ReadOnly);
1031 while (it.hasNext()) {
1032 QImageReader reader(&buffer, it.next());
1033 if (!reader.supportsAnimation())
1034 it.remove();
1035 }
1036 return list;
1037}
1038
1039/*!
1040 \property QMovie::cacheMode
1041 \brief the movie's cache mode
1042
1043 Caching frames can be useful when the underlying animation format handler
1044 that QMovie relies on to decode the animation data does not support
1045 jumping to particular frames in the animation, or even "rewinding" the
1046 animation to the beginning (for looping). Furthermore, if the image data
1047 comes from a sequential device, it is not possible for the underlying
1048 animation handler to seek back to frames whose data has already been read
1049 (making looping altogether impossible).
1050
1051 To aid in such situations, a QMovie object can be instructed to cache the
1052 frames, at the added memory cost of keeping the frames in memory for the
1053 lifetime of the object.
1054
1055 By default, this property is set to \l CacheNone.
1056
1057 \sa QMovie::CacheMode
1058*/
1059
1060QMovie::CacheMode QMovie::cacheMode() const
1061{
1062 Q_D(const QMovie);
1063 return d->cacheMode;
1064}
1065
1066void QMovie::setCacheMode(CacheMode cacheMode)
1067{
1068 Q_D(QMovie);
1069 d->cacheMode = cacheMode;
1070}
1071
1072/*!
1073 \internal
1074*/
1075QMovie::CacheMode QMovie::cacheMode()
1076{
1077 Q_D(QMovie);
1078 return d->cacheMode;
1079}
1080
1081QT_END_NAMESPACE
1082
1083#include "moc_qmovie.cpp"
1084
1085#endif // QT_NO_MOVIE
Note: See TracBrowser for help on using the repository browser.