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

Last change on this file since 503 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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