/**************************************************************************** | |
** | |
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). | |
** All rights reserved. | |
** Contact: Nokia Corporation (qt-info@nokia.com) | |
** | |
** This file is part of the QtGui module of the Qt Toolkit. | |
** | |
** $QT_BEGIN_LICENSE:LGPL$ | |
** GNU Lesser General Public License Usage | |
** This file may be used under the terms of the GNU Lesser General Public | |
** License version 2.1 as published by the Free Software Foundation and | |
** appearing in the file LICENSE.LGPL included in the packaging of this | |
** file. Please review the following information to ensure the GNU Lesser | |
** General Public License version 2.1 requirements will be met: | |
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | |
** | |
** In addition, as a special exception, Nokia gives you certain additional | |
** rights. These rights are described in the Nokia Qt LGPL Exception | |
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | |
** | |
** GNU General Public License Usage | |
** Alternatively, this file may be used under the terms of the GNU General | |
** Public License version 3.0 as published by the Free Software Foundation | |
** and appearing in the file LICENSE.GPL included in the packaging of this | |
** file. Please review the following information to ensure the GNU General | |
** Public License version 3.0 requirements will be met: | |
** http://www.gnu.org/copyleft/gpl.html. | |
** | |
** Other Usage | |
** Alternatively, this file may be used in accordance with the terms and | |
** conditions contained in a signed written agreement between you and Nokia. | |
** | |
** | |
** | |
** | |
** | |
** $QT_END_LICENSE$ | |
** | |
****************************************************************************/ | |
/*! | |
\class QMovie | |
\brief The QMovie class is a convenience class for playing movies | |
with QImageReader. | |
\ingroup painting | |
This class is used to show simple animations without sound. If you want | |
to display video and media content, use the \l{Phonon Module}{Phonon} | |
multimedia framework instead. | |
First, create a QMovie object by passing either the name of a file or a | |
pointer to a QIODevice containing an animated image format to QMovie's | |
constructor. You can call isValid() to check if the image data is valid, | |
before starting the movie. To start the movie, call start(). QMovie will | |
enter \l Running state, and emit started() and stateChanged(). To get the | |
current state of the movie, call state(). | |
To display the movie in your application, you can pass your QMovie object | |
to QLabel::setMovie(). Example: | |
\snippet doc/src/snippets/code/src_gui_image_qmovie.cpp 0 | |
Whenever a new frame is available in the movie, QMovie will emit | |
updated(). If the size of the frame changes, resized() is emitted. You can | |
call currentImage() or currentPixmap() to get a copy of the current | |
frame. When the movie is done, QMovie emits finished(). If any error | |
occurs during playback (i.e, the image file is corrupt), QMovie will emit | |
error(). | |
You can control the speed of the movie playback by calling setSpeed(), | |
which takes the percentage of the original speed as an argument. Pause the | |
movie by calling setPaused(true). QMovie will then enter \l Paused state | |
and emit stateChanged(). If you call setPaused(false), QMovie will reenter | |
\l Running state and start the movie again. To stop the movie, call | |
stop(). | |
Certain animation formats allow you to set the background color. You can | |
call setBackgroundColor() to set the color, or backgroundColor() to | |
retrieve the current background color. | |
currentFrameNumber() returns the sequence number of the current frame. The | |
first frame in the animation has the sequence number 0. frameCount() | |
returns the total number of frames in the animation, if the image format | |
supports this. You can call loopCount() to get the number of times the | |
movie should loop before finishing. nextFrameDelay() returns the number of | |
milliseconds the current frame should be displayed. | |
QMovie can be instructed to cache frames of an animation by calling | |
setCacheMode(). | |
Call supportedFormats() for a list of formats that QMovie supports. | |
\sa QLabel, QImageReader, {Movie Example} | |
*/ | |
/*! \enum QMovie::MovieState | |
This enum describes the different states of QMovie. | |
\value NotRunning The movie is not running. This is QMovie's initial | |
state, and the state it enters after stop() has been called or the movie | |
is finished. | |
\value Paused The movie is paused, and QMovie stops emitting updated() or | |
resized(). This state is entered after calling pause() or | |
setPaused(true). The current frame number it kept, and the movie will | |
continue with the next frame when unpause() or setPaused(false) is called. | |
\value Running The movie is running. | |
*/ | |
/*! \enum QMovie::CacheMode | |
This enum describes the different cache modes of QMovie. | |
\value CacheNone No frames are cached (the default). | |
\value CacheAll All frames are cached. | |
*/ | |
/*! \fn void QMovie::started() | |
This signal is emitted after QMovie::start() has been called, and QMovie | |
has entered QMovie::Running state. | |
*/ | |
/*! \fn void QMovie::resized(const QSize &size) | |
This signal is emitted when the current frame has been resized to \a | |
size. This effect is sometimes used in animations as an alternative to | |
replacing the frame. You can call currentImage() or currentPixmap() to get a | |
copy of the updated frame. | |
*/ | |
/*! \fn void QMovie::updated(const QRect &rect) | |
This signal is emitted when the rect \a rect in the current frame has been | |
updated. You can call currentImage() or currentPixmap() to get a copy of the | |
updated frame. | |
*/ | |
/*! \fn void QMovie::frameChanged(int frameNumber) | |
\since 4.1 | |
This signal is emitted when the frame number has changed to | |
\a frameNumber. You can call currentImage() or currentPixmap() to get a | |
copy of the frame. | |
*/ | |
/*! | |
\fn void QMovie::stateChanged(QMovie::MovieState state) | |
This signal is emitted every time the state of the movie changes. The new | |
state is specified by \a state. | |
\sa QMovie::state() | |
*/ | |
/*! \fn void QMovie::error(QImageReader::ImageReaderError error) | |
This signal is emitted by QMovie when the error \a error occurred during | |
playback. QMovie will stop the movie, and enter QMovie::NotRunning state. | |
*/ | |
/*! \fn void QMovie::finished() | |
This signal is emitted when the movie has finished. | |
\sa QMovie::stop() | |
*/ | |
#include "qglobal.h" | |
#ifndef QT_NO_MOVIE | |
#include "qmovie.h" | |
#include "qimage.h" | |
#include "qimagereader.h" | |
#include "qpixmap.h" | |
#include "qrect.h" | |
#include "qdatetime.h" | |
#include "qtimer.h" | |
#include "qpair.h" | |
#include "qmap.h" | |
#include "qlist.h" | |
#include "qbuffer.h" | |
#include "qdir.h" | |
#include "private/qobject_p.h" | |
#define QMOVIE_INVALID_DELAY -1 | |
QT_BEGIN_NAMESPACE | |
class QFrameInfo | |
{ | |
public: | |
QPixmap pixmap; | |
int delay; | |
bool endMark; | |
inline QFrameInfo(bool endMark) | |
: pixmap(QPixmap()), delay(QMOVIE_INVALID_DELAY), endMark(endMark) | |
{ } | |
inline QFrameInfo() | |
: pixmap(QPixmap()), delay(QMOVIE_INVALID_DELAY), endMark(false) | |
{ } | |
inline QFrameInfo(const QPixmap &pixmap, int delay) | |
: pixmap(pixmap), delay(delay), endMark(false) | |
{ } | |
inline bool isValid() | |
{ | |
return endMark || !(pixmap.isNull() && (delay == QMOVIE_INVALID_DELAY)); | |
} | |
inline bool isEndMarker() | |
{ return endMark; } | |
static inline QFrameInfo endMarker() | |
{ return QFrameInfo(true); } | |
}; | |
class QMoviePrivate : public QObjectPrivate | |
{ | |
Q_DECLARE_PUBLIC(QMovie) | |
public: | |
QMoviePrivate(QMovie *qq); | |
bool isDone(); | |
bool next(); | |
int speedAdjustedDelay(int delay) const; | |
bool isValid() const; | |
bool jumpToFrame(int frameNumber); | |
int frameCount() const; | |
bool jumpToNextFrame(); | |
QFrameInfo infoForFrame(int frameNumber); | |
void reset(); | |
inline void enterState(QMovie::MovieState newState) { | |
movieState = newState; | |
emit q_func()->stateChanged(newState); | |
} | |
// private slots | |
void _q_loadNextFrame(); | |
void _q_loadNextFrame(bool starting); | |
QImageReader *reader; | |
int speed; | |
QMovie::MovieState movieState; | |
QRect frameRect; | |
QPixmap currentPixmap; | |
int currentFrameNumber; | |
int nextFrameNumber; | |
int greatestFrameNumber; | |
int nextDelay; | |
int playCounter; | |
qint64 initialDevicePos; | |
QMovie::CacheMode cacheMode; | |
bool haveReadAll; | |
bool isFirstIteration; | |
QMap<int, QFrameInfo> frameMap; | |
QString absoluteFilePath; | |
QTimer nextImageTimer; | |
}; | |
/*! \internal | |
*/ | |
QMoviePrivate::QMoviePrivate(QMovie *qq) | |
: reader(0), speed(100), movieState(QMovie::NotRunning), | |
currentFrameNumber(-1), nextFrameNumber(0), greatestFrameNumber(-1), | |
nextDelay(0), playCounter(-1), | |
cacheMode(QMovie::CacheNone), haveReadAll(false), isFirstIteration(true) | |
{ | |
q_ptr = qq; | |
nextImageTimer.setSingleShot(true); | |
} | |
/*! \internal | |
*/ | |
void QMoviePrivate::reset() | |
{ | |
nextImageTimer.stop(); | |
if (reader->device()) | |
initialDevicePos = reader->device()->pos(); | |
currentFrameNumber = -1; | |
nextFrameNumber = 0; | |
greatestFrameNumber = -1; | |
nextDelay = 0; | |
playCounter = -1; | |
haveReadAll = false; | |
isFirstIteration = true; | |
frameMap.clear(); | |
} | |
/*! \internal | |
*/ | |
bool QMoviePrivate::isDone() | |
{ | |
return (playCounter == 0); | |
} | |
/*! | |
\internal | |
Given the original \a delay, this function returns the | |
actual number of milliseconds to delay according to | |
the current speed. E.g. if the speed is 200%, the | |
result will be half of the original delay. | |
*/ | |
int QMoviePrivate::speedAdjustedDelay(int delay) const | |
{ | |
return int( (qint64(delay) * qint64(100) ) / qint64(speed) ); | |
} | |
/*! | |
\internal | |
Returns the QFrameInfo for the given \a frameNumber. | |
If the frame number is invalid, an invalid QFrameInfo is | |
returned. | |
If the end of the animation has been reached, a | |
special end marker QFrameInfo is returned. | |
*/ | |
QFrameInfo QMoviePrivate::infoForFrame(int frameNumber) | |
{ | |
if (frameNumber < 0) | |
return QFrameInfo(); // Invalid | |
if (haveReadAll && (frameNumber > greatestFrameNumber)) { | |
if (frameNumber == greatestFrameNumber+1) | |
return QFrameInfo::endMarker(); | |
return QFrameInfo(); // Invalid | |
} | |
if (cacheMode == QMovie::CacheNone) { | |
if (frameNumber != currentFrameNumber+1) { | |
// Non-sequential frame access | |
if (!reader->jumpToImage(frameNumber)) { | |
if (frameNumber == 0) { | |
// Special case: Attempt to "rewind" so we can loop | |
// ### This could be implemented as QImageReader::rewind() | |
if (reader->device()->isSequential()) | |
return QFrameInfo(); // Invalid | |
QString fileName = reader->fileName(); | |
QByteArray format = reader->format(); | |
QIODevice *device = reader->device(); | |
QColor bgColor = reader->backgroundColor(); | |
QSize scaledSize = reader->scaledSize(); | |
delete reader; | |
if (fileName.isEmpty()) | |
reader = new QImageReader(device, format); | |
else | |
reader = new QImageReader(absoluteFilePath, format); | |
(void)reader->canRead(); // Provoke a device->open() call | |
reader->device()->seek(initialDevicePos); | |
reader->setBackgroundColor(bgColor); | |
reader->setScaledSize(scaledSize); | |
} else { | |
return QFrameInfo(); // Invalid | |
} | |
} | |
} | |
if (reader->canRead()) { | |
// reader says we can read. Attempt to actually read image | |
QImage anImage = reader->read(); | |
if (anImage.isNull()) { | |
// Reading image failed. | |
return QFrameInfo(); // Invalid | |
} | |
if (frameNumber > greatestFrameNumber) | |
greatestFrameNumber = frameNumber; | |
QPixmap aPixmap = QPixmap::fromImage(anImage); | |
int aDelay = reader->nextImageDelay(); | |
return QFrameInfo(aPixmap, aDelay); | |
} else { | |
// We've read all frames now. Return an end marker | |
haveReadAll = true; | |
return QFrameInfo::endMarker(); | |
} | |
} | |
// CacheMode == CacheAll | |
if (frameNumber > greatestFrameNumber) { | |
// Frame hasn't been read from file yet. Try to do it | |
for (int i = greatestFrameNumber + 1; i <= frameNumber; ++i) { | |
if (reader->canRead()) { | |
// reader says we can read. Attempt to actually read image | |
QImage anImage = reader->read(); | |
if (anImage.isNull()) { | |
// Reading image failed. | |
return QFrameInfo(); // Invalid | |
} | |
greatestFrameNumber = i; | |
QPixmap aPixmap = QPixmap::fromImage(anImage); | |
int aDelay = reader->nextImageDelay(); | |
QFrameInfo info(aPixmap, aDelay); | |
// Cache it! | |
frameMap.insert(i, info); | |
if (i == frameNumber) { | |
return info; | |
} | |
} else { | |
// We've read all frames now. Return an end marker | |
haveReadAll = true; | |
return QFrameInfo::endMarker(); | |
} | |
} | |
} | |
// Return info for requested (cached) frame | |
return frameMap.value(frameNumber); | |
} | |
/*! | |
\internal | |
Attempts to advance the animation to the next frame. | |
If successful, currentFrameNumber, currentPixmap and | |
nextDelay are updated accordingly, and true is returned. | |
Otherwise, false is returned. | |
When false is returned, isDone() can be called to | |
determine whether the animation ended gracefully or | |
an error occurred when reading the frame. | |
*/ | |
bool QMoviePrivate::next() | |
{ | |
QTime time; | |
time.start(); | |
QFrameInfo info = infoForFrame(nextFrameNumber); | |
if (!info.isValid()) | |
return false; | |
if (info.isEndMarker()) { | |
// We reached the end of the animation. | |
if (isFirstIteration) { | |
if (nextFrameNumber == 0) { | |
// No frames could be read at all (error). | |
return false; | |
} | |
// End of first iteration. Initialize play counter | |
playCounter = reader->loopCount(); | |
isFirstIteration = false; | |
} | |
// Loop as appropriate | |
if (playCounter != 0) { | |
if (playCounter != -1) // Infinite? | |
playCounter--; // Nope | |
nextFrameNumber = 0; | |
return next(); | |
} | |
// Loop no more. Done | |
return false; | |
} | |
// Image and delay OK, update internal state | |
currentFrameNumber = nextFrameNumber++; | |
QSize scaledSize = reader->scaledSize(); | |
if (scaledSize.isValid() && (scaledSize != info.pixmap.size())) | |
currentPixmap = QPixmap::fromImage( info.pixmap.toImage().scaled(scaledSize) ); | |
else | |
currentPixmap = info.pixmap; | |
nextDelay = speedAdjustedDelay(info.delay); | |
// Adjust delay according to the time it took to read the frame | |
int processingTime = time.elapsed(); | |
if (processingTime > nextDelay) | |
nextDelay = 0; | |
else | |
nextDelay = nextDelay - processingTime; | |
return true; | |
} | |
/*! \internal | |
*/ | |
void QMoviePrivate::_q_loadNextFrame() | |
{ | |
_q_loadNextFrame(false); | |
} | |
void QMoviePrivate::_q_loadNextFrame(bool starting) | |
{ | |
Q_Q(QMovie); | |
if (next()) { | |
if (starting && movieState == QMovie::NotRunning) { | |
enterState(QMovie::Running); | |
emit q->started(); | |
} | |
if (frameRect.size() != currentPixmap.rect().size()) { | |
frameRect = currentPixmap.rect(); | |
emit q->resized(frameRect.size()); | |
} | |
emit q->updated(frameRect); | |
emit q->frameChanged(currentFrameNumber); | |
if (movieState == QMovie::Running) | |
nextImageTimer.start(nextDelay); | |
} else { | |
// Could not read another frame | |
if (!isDone()) { | |
emit q->error(reader->error()); | |
} | |
// Graceful finish | |
if (movieState != QMovie::Paused) { | |
nextFrameNumber = 0; | |
isFirstIteration = true; | |
playCounter = -1; | |
enterState(QMovie::NotRunning); | |
emit q->finished(); | |
} | |
} | |
} | |
/*! | |
\internal | |
*/ | |
bool QMoviePrivate::isValid() const | |
{ | |
return (greatestFrameNumber >= 0) // have we seen valid data | |
|| reader->canRead(); // or does the reader see valid data | |
} | |
/*! | |
\internal | |
*/ | |
bool QMoviePrivate::jumpToFrame(int frameNumber) | |
{ | |
if (frameNumber < 0) | |
return false; | |
if (currentFrameNumber == frameNumber) | |
return true; | |
nextFrameNumber = frameNumber; | |
if (movieState == QMovie::Running) | |
nextImageTimer.stop(); | |
_q_loadNextFrame(); | |
return (nextFrameNumber == currentFrameNumber+1); | |
} | |
/*! | |
\internal | |
*/ | |
int QMoviePrivate::frameCount() const | |
{ | |
int result; | |
if ((result = reader->imageCount()) != 0) | |
return result; | |
if (haveReadAll) | |
return greatestFrameNumber+1; | |
return 0; // Don't know | |
} | |
/*! | |
\internal | |
*/ | |
bool QMoviePrivate::jumpToNextFrame() | |
{ | |
return jumpToFrame(currentFrameNumber+1); | |
} | |
/*! | |
Constructs a QMovie object, passing the \a parent object to QObject's | |
constructor. | |
\sa setFileName(), setDevice(), setFormat() | |
*/ | |
QMovie::QMovie(QObject *parent) | |
: QObject(*new QMoviePrivate(this), parent) | |
{ | |
Q_D(QMovie); | |
d->reader = new QImageReader; | |
connect(&d->nextImageTimer, SIGNAL(timeout()), this, SLOT(_q_loadNextFrame())); | |
} | |
/*! | |
Constructs a QMovie object. QMovie will use read image data from \a | |
device, which it assumes is open and readable. If \a format is not empty, | |
QMovie will use the image format \a format for decoding the image | |
data. Otherwise, QMovie will attempt to guess the format. | |
The \a parent object is passed to QObject's constructor. | |
*/ | |
QMovie::QMovie(QIODevice *device, const QByteArray &format, QObject *parent) | |
: QObject(*new QMoviePrivate(this), parent) | |
{ | |
Q_D(QMovie); | |
d->reader = new QImageReader(device, format); | |
d->initialDevicePos = device->pos(); | |
connect(&d->nextImageTimer, SIGNAL(timeout()), this, SLOT(_q_loadNextFrame())); | |
} | |
/*! | |
Constructs a QMovie object. QMovie will use read image data from \a | |
fileName. If \a format is not empty, QMovie will use the image format \a | |
format for decoding the image data. Otherwise, QMovie will attempt to | |
guess the format. | |
The \a parent object is passed to QObject's constructor. | |
*/ | |
QMovie::QMovie(const QString &fileName, const QByteArray &format, QObject *parent) | |
: QObject(*new QMoviePrivate(this), parent) | |
{ | |
Q_D(QMovie); | |
d->absoluteFilePath = QDir(fileName).absolutePath(); | |
d->reader = new QImageReader(fileName, format); | |
if (d->reader->device()) | |
d->initialDevicePos = d->reader->device()->pos(); | |
connect(&d->nextImageTimer, SIGNAL(timeout()), this, SLOT(_q_loadNextFrame())); | |
} | |
/*! | |
Destructs the QMovie object. | |
*/ | |
QMovie::~QMovie() | |
{ | |
Q_D(QMovie); | |
delete d->reader; | |
} | |
/*! | |
Sets the current device to \a device. QMovie will read image data from | |
this device when the movie is running. | |
\sa device(), setFormat() | |
*/ | |
void QMovie::setDevice(QIODevice *device) | |
{ | |
Q_D(QMovie); | |
d->reader->setDevice(device); | |
d->reset(); | |
} | |
/*! | |
Returns the device QMovie reads image data from. If no device has | |
currently been assigned, 0 is returned. | |
\sa setDevice(), fileName() | |
*/ | |
QIODevice *QMovie::device() const | |
{ | |
Q_D(const QMovie); | |
return d->reader->device(); | |
} | |
/*! | |
Sets the name of the file that QMovie reads image data from, to \a | |
fileName. | |
\sa fileName(), setDevice(), setFormat() | |
*/ | |
void QMovie::setFileName(const QString &fileName) | |
{ | |
Q_D(QMovie); | |
d->absoluteFilePath = QDir(fileName).absolutePath(); | |
d->reader->setFileName(fileName); | |
d->reset(); | |
} | |
/*! | |
Returns the name of the file that QMovie reads image data from. If no file | |
name has been assigned, or if the assigned device is not a file, an empty | |
QString is returned. | |
\sa setFileName(), device() | |
*/ | |
QString QMovie::fileName() const | |
{ | |
Q_D(const QMovie); | |
return d->reader->fileName(); | |
} | |
/*! | |
Sets the format that QMovie will use when decoding image data, to \a | |
format. By default, QMovie will attempt to guess the format of the image | |
data. | |
You can call supportedFormats() for the full list of formats | |
QMovie supports. | |
\sa QImageReader::supportedImageFormats() | |
*/ | |
void QMovie::setFormat(const QByteArray &format) | |
{ | |
Q_D(QMovie); | |
d->reader->setFormat(format); | |
} | |
/*! | |
Returns the format that QMovie uses when decoding image data. If no format | |
has been assigned, an empty QByteArray() is returned. | |
\sa setFormat() | |
*/ | |
QByteArray QMovie::format() const | |
{ | |
Q_D(const QMovie); | |
return d->reader->format(); | |
} | |
/*! | |
For image formats that support it, this function sets the background color | |
to \a color. | |
\sa backgroundColor() | |
*/ | |
void QMovie::setBackgroundColor(const QColor &color) | |
{ | |
Q_D(QMovie); | |
d->reader->setBackgroundColor(color); | |
} | |
/*! | |
Returns the background color of the movie. If no background color has been | |
assigned, an invalid QColor is returned. | |
\sa setBackgroundColor() | |
*/ | |
QColor QMovie::backgroundColor() const | |
{ | |
Q_D(const QMovie); | |
return d->reader->backgroundColor(); | |
} | |
/*! | |
Returns the current state of QMovie. | |
\sa MovieState, stateChanged() | |
*/ | |
QMovie::MovieState QMovie::state() const | |
{ | |
Q_D(const QMovie); | |
return d->movieState; | |
} | |
/*! | |
Returns the rect of the last frame. If no frame has yet been updated, an | |
invalid QRect is returned. | |
\sa currentImage(), currentPixmap() | |
*/ | |
QRect QMovie::frameRect() const | |
{ | |
Q_D(const QMovie); | |
return d->frameRect; | |
} | |
/*! \fn QImage QMovie::framePixmap() const | |
Use currentPixmap() instead. | |
*/ | |
/*! \fn void QMovie::pause() | |
Use setPaused(true) instead. | |
*/ | |
/*! \fn void QMovie::unpause() | |
Use setPaused(false) instead. | |
*/ | |
/*! | |
Returns the current frame as a QPixmap. | |
\sa currentImage(), updated() | |
*/ | |
QPixmap QMovie::currentPixmap() const | |
{ | |
Q_D(const QMovie); | |
return d->currentPixmap; | |
} | |
/*! \fn QImage QMovie::frameImage() const | |
Use currentImage() instead. | |
*/ | |
/*! | |
Returns the current frame as a QImage. | |
\sa currentPixmap(), updated() | |
*/ | |
QImage QMovie::currentImage() const | |
{ | |
Q_D(const QMovie); | |
return d->currentPixmap.toImage(); | |
} | |
/*! | |
Returns true if the movie is valid (e.g., the image data is readable and | |
the image format is supported); otherwise returns false. | |
*/ | |
bool QMovie::isValid() const | |
{ | |
Q_D(const QMovie); | |
return d->isValid(); | |
} | |
/*! \fn bool QMovie::running() const | |
Use state() instead. | |
*/ | |
/*! \fn bool QMovie::isNull() const | |
Use isValid() instead. | |
*/ | |
/*! \fn int QMovie::frameNumber() const | |
Use currentFrameNumber() instead. | |
*/ | |
/*! \fn bool QMovie::paused() const | |
Use state() instead. | |
*/ | |
/*! \fn bool QMovie::finished() const | |
Use state() instead. | |
*/ | |
/*! \fn void QMovie::restart() | |
Use stop() and start() instead. | |
*/ | |
/*! | |
\fn void QMovie::step() | |
Use jumpToNextFrame() instead. | |
*/ | |
/*! | |
Returns the number of frames in the movie. | |
Certain animation formats do not support this feature, in which | |
case 0 is returned. | |
*/ | |
int QMovie::frameCount() const | |
{ | |
Q_D(const QMovie); | |
return d->frameCount(); | |
} | |
/*! | |
Returns the number of milliseconds QMovie will wait before updating the | |
next frame in the animation. | |
*/ | |
int QMovie::nextFrameDelay() const | |
{ | |
Q_D(const QMovie); | |
return d->nextDelay; | |
} | |
/*! | |
Returns the sequence number of the current frame. The number of the first | |
frame in the movie is 0. | |
*/ | |
int QMovie::currentFrameNumber() const | |
{ | |
Q_D(const QMovie); | |
return d->currentFrameNumber; | |
} | |
/*! | |
Jumps to the next frame. Returns true on success; otherwise returns false. | |
*/ | |
bool QMovie::jumpToNextFrame() | |
{ | |
Q_D(QMovie); | |
return d->jumpToNextFrame(); | |
} | |
/*! | |
Jumps to frame number \a frameNumber. Returns true on success; otherwise | |
returns false. | |
*/ | |
bool QMovie::jumpToFrame(int frameNumber) | |
{ | |
Q_D(QMovie); | |
return d->jumpToFrame(frameNumber); | |
} | |
/*! | |
Returns the number of times the movie will loop before it finishes. | |
If the movie will only play once (no looping), loopCount returns 0. | |
If the movie loops forever, loopCount returns -1. | |
Note that, if the image data comes from a sequential device (e.g. a | |
socket), QMovie can only loop the movie if the cacheMode is set to | |
QMovie::CacheAll. | |
*/ | |
int QMovie::loopCount() const | |
{ | |
Q_D(const QMovie); | |
return d->reader->loopCount(); | |
} | |
/*! | |
If \a paused is true, QMovie will enter \l Paused state and emit | |
stateChanged(Paused); otherwise it will enter \l Running state and emit | |
stateChanged(Running). | |
\sa state() | |
*/ | |
void QMovie::setPaused(bool paused) | |
{ | |
Q_D(QMovie); | |
if (paused) { | |
if (d->movieState == NotRunning) | |
return; | |
d->enterState(Paused); | |
d->nextImageTimer.stop(); | |
} else { | |
if (d->movieState == Running) | |
return; | |
d->enterState(Running); | |
d->nextImageTimer.start(nextFrameDelay()); | |
} | |
} | |
/*! | |
\property QMovie::speed | |
\brief the movie's speed | |
The speed is measured in percentage of the original movie speed. | |
The default speed is 100%. | |
Example: | |
\snippet doc/src/snippets/code/src_gui_image_qmovie.cpp 1 | |
*/ | |
void QMovie::setSpeed(int percentSpeed) | |
{ | |
Q_D(QMovie); | |
d->speed = percentSpeed; | |
} | |
int QMovie::speed() const | |
{ | |
Q_D(const QMovie); | |
return d->speed; | |
} | |
/*! | |
Starts the movie. QMovie will enter \l Running state, and start emitting | |
updated() and resized() as the movie progresses. | |
If QMovie is in the \l Paused state, this function is equivalent | |
to calling setPaused(false). If QMovie is already in the \l | |
Running state, this function does nothing. | |
\sa stop(), setPaused() | |
*/ | |
void QMovie::start() | |
{ | |
Q_D(QMovie); | |
if (d->movieState == NotRunning) { | |
d->_q_loadNextFrame(true); | |
} else if (d->movieState == Paused) { | |
setPaused(false); | |
} | |
} | |
/*! | |
Stops the movie. QMovie enters \l NotRunning state, and stops emitting | |
updated() and resized(). If start() is called again, the movie will | |
restart from the beginning. | |
If QMovie is already in the \l NotRunning state, this function | |
does nothing. | |
\sa start(), setPaused() | |
*/ | |
void QMovie::stop() | |
{ | |
Q_D(QMovie); | |
if (d->movieState == NotRunning) | |
return; | |
d->enterState(NotRunning); | |
d->nextImageTimer.stop(); | |
d->nextFrameNumber = 0; | |
} | |
/*! | |
\since 4.1 | |
Returns the scaled size of frames. | |
\sa QImageReader::scaledSize() | |
*/ | |
QSize QMovie::scaledSize() | |
{ | |
Q_D(QMovie); | |
return d->reader->scaledSize(); | |
} | |
/*! | |
\since 4.1 | |
Sets the scaled frame size to \a size. | |
\sa QImageReader::setScaledSize() | |
*/ | |
void QMovie::setScaledSize(const QSize &size) | |
{ | |
Q_D(QMovie); | |
d->reader->setScaledSize(size); | |
} | |
/*! | |
\since 4.1 | |
Returns the list of image formats supported by QMovie. | |
\sa QImageReader::supportedImageFormats() | |
*/ | |
QList<QByteArray> QMovie::supportedFormats() | |
{ | |
QList<QByteArray> list = QImageReader::supportedImageFormats(); | |
QMutableListIterator<QByteArray> it(list); | |
QBuffer buffer; | |
buffer.open(QIODevice::ReadOnly); | |
while (it.hasNext()) { | |
QImageReader reader(&buffer, it.next()); | |
if (!reader.supportsAnimation()) | |
it.remove(); | |
} | |
return list; | |
} | |
/*! | |
\property QMovie::cacheMode | |
\brief the movie's cache mode | |
Caching frames can be useful when the underlying animation format handler | |
that QMovie relies on to decode the animation data does not support | |
jumping to particular frames in the animation, or even "rewinding" the | |
animation to the beginning (for looping). Furthermore, if the image data | |
comes from a sequential device, it is not possible for the underlying | |
animation handler to seek back to frames whose data has already been read | |
(making looping altogether impossible). | |
To aid in such situations, a QMovie object can be instructed to cache the | |
frames, at the added memory cost of keeping the frames in memory for the | |
lifetime of the object. | |
By default, this property is set to \l CacheNone. | |
\sa QMovie::CacheMode | |
*/ | |
QMovie::CacheMode QMovie::cacheMode() const | |
{ | |
Q_D(const QMovie); | |
return d->cacheMode; | |
} | |
void QMovie::setCacheMode(CacheMode cacheMode) | |
{ | |
Q_D(QMovie); | |
d->cacheMode = cacheMode; | |
} | |
/*! | |
\internal | |
*/ | |
QMovie::CacheMode QMovie::cacheMode() | |
{ | |
Q_D(QMovie); | |
return d->cacheMode; | |
} | |
QT_END_NAMESPACE | |
#include "moc_qmovie.cpp" | |
#endif // QT_NO_MOVIE |