diff --git a/src/plugins/imageviewer/images/pause-small.png b/src/plugins/imageviewer/images/pause-small.png new file mode 100644 index 00000000000..114d89b12bd Binary files /dev/null and b/src/plugins/imageviewer/images/pause-small.png differ diff --git a/src/plugins/imageviewer/images/play-small.png b/src/plugins/imageviewer/images/play-small.png new file mode 100644 index 00000000000..011598a746f Binary files /dev/null and b/src/plugins/imageviewer/images/play-small.png differ diff --git a/src/plugins/imageviewer/imageview.cpp b/src/plugins/imageviewer/imageview.cpp index 61ebbed81ee..50b974d9255 100644 --- a/src/plugins/imageviewer/imageview.cpp +++ b/src/plugins/imageviewer/imageview.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #ifndef QT_NO_SVG @@ -53,7 +54,6 @@ #include #include - namespace ImageViewer { namespace Constants { const qreal DEFAULT_SCALE_FACTOR = 1.2; @@ -61,13 +61,40 @@ namespace Constants { namespace Internal { +class MovieItem : public QGraphicsPixmapItem +{ +public: + MovieItem(QMovie *movie) + : m_movie(movie) + { + setPixmap(m_movie->currentPixmap()); + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) + { + painter->setRenderHint(QPainter::SmoothPixmapTransform, true); + painter->drawPixmap(offset(), m_movie->currentPixmap()); + } + +private: + QMovie *m_movie; +}; + struct ImageViewPrivate { - ImageViewPrivate() : imageItem(0), backgroundItem(0), outlineItem(0) {} + ImageViewPrivate() + : imageItem(0) + , backgroundItem(0) + , outlineItem(0) + , movie(0) + , moviePaused(true) + {} + QGraphicsItem *imageItem; QGraphicsRectItem *backgroundItem; QGraphicsRectItem *outlineItem; - QSize naturalSize; + QMovie *movie; + bool moviePaused; }; ImageView::ImageView(QWidget *parent) @@ -121,7 +148,6 @@ bool ImageView::openFile(QString fileName) if (format.startsWith("svg")) isSvg = true; #endif - QGraphicsScene *s = scene(); bool drawBackground = (d->backgroundItem ? d->backgroundItem->isVisible() : false); @@ -129,20 +155,31 @@ bool ImageView::openFile(QString fileName) s->clear(); resetTransform(); + delete d->movie; + d->movie = 0; // image #ifndef QT_NO_SVG if (isSvg) { d->imageItem = new QGraphicsSvgItem(fileName); - d->naturalSize = QSize(); + emit imageSizeChanged(QSize()); } else #endif - { + if (QMovie::supportedFormats().contains(format)) { + d->movie = new QMovie(fileName, QByteArray(), this); + d->movie->setCacheMode(QMovie::CacheAll); + connect(d->movie, SIGNAL(finished()), d->movie, SLOT(start())); + connect(d->movie, SIGNAL(updated(QRect)), this, SLOT(updatePixmap(QRect))); + connect(d->movie, SIGNAL(resized(QSize)), this, SLOT(pixmapResized(QSize))); + d->movie->start(); + d->moviePaused = false; + d->imageItem = new MovieItem(d->movie); + } else { QPixmap pixmap(fileName); QGraphicsPixmapItem *pixmapItem = new QGraphicsPixmapItem(pixmap); pixmapItem->setTransformationMode(Qt::SmoothTransformation); d->imageItem = pixmapItem; - d->naturalSize = pixmap.size(); + emit imageSizeChanged(pixmap.size()); } d->imageItem->setCacheMode(QGraphicsItem::NoCache); d->imageItem->setZValue(0); @@ -175,9 +212,23 @@ bool ImageView::openFile(QString fileName) return true; } -QSize ImageView::imageSize() const +bool ImageView::isAnimated() const { - return d->naturalSize; + return d->movie; +} + +bool ImageView::isPaused() const +{ + return d->moviePaused; +} + +void ImageView::setPaused(bool paused) +{ + if (!d->movie) + return; + + d->movie->setPaused(paused); + d->moviePaused = paused; } void ImageView::setViewBackground(bool enable) @@ -211,6 +262,17 @@ void ImageView::doScale(qreal factor) emitScaleFactor(); } +void ImageView::updatePixmap(const QRect &rect) +{ + if (d->imageItem) + d->imageItem->update(rect); +} + +void ImageView::pixmapResized(const QSize &size) +{ + emit imageSizeChanged(size); +} + void ImageView::wheelEvent(QWheelEvent *event) { qreal factor = qPow(Constants::DEFAULT_SCALE_FACTOR, event->delta() / 240.0); @@ -247,5 +309,21 @@ void ImageView::emitScaleFactor() emit scaleFactorChanged(factor); } +void ImageView::showEvent(QShowEvent *) +{ + if (!d->movie) + return; + + d->movie->setPaused(d->moviePaused); +} + +void ImageView::hideEvent(QHideEvent *) +{ + if (!d->movie) + return; + + d->movie->setPaused(true); +} + } // namespace Internal } // namespace ImageView diff --git a/src/plugins/imageviewer/imageview.h b/src/plugins/imageviewer/imageview.h index a15aa356699..b6ba61ff9ce 100644 --- a/src/plugins/imageviewer/imageview.h +++ b/src/plugins/imageviewer/imageview.h @@ -44,7 +44,6 @@ #define IMAGEVIEW_H #include -#include namespace ImageViewer { namespace Internal { @@ -58,10 +57,13 @@ public: ~ImageView(); bool openFile(QString fileName); - QSize imageSize() const; + bool isAnimated() const; + bool isPaused() const; + void setPaused(bool paused); signals: void scaleFactorChanged(qreal factor); + void imageSizeChanged(const QSize &size); public slots: void setViewBackground(bool enable); @@ -74,9 +76,13 @@ public slots: private slots: void emitScaleFactor(); void doScale(qreal factor); + void updatePixmap(const QRect &rect); + void pixmapResized(const QSize &size); protected: void drawBackground(QPainter *p, const QRectF &rect); + void hideEvent(QHideEvent *event); + void showEvent(QShowEvent *event); void wheelEvent(QWheelEvent *event); private: diff --git a/src/plugins/imageviewer/imageviewer.cpp b/src/plugins/imageviewer/imageviewer.cpp index 53f728ce6d5..48d61dafc65 100644 --- a/src/plugins/imageviewer/imageviewer.cpp +++ b/src/plugins/imageviewer/imageviewer.cpp @@ -101,6 +101,10 @@ ImageViewer::ImageViewer(QWidget *parent) d->imageView, SLOT(setViewBackground(bool))); connect(d->ui_toolbar.toolButtonOutline, SIGNAL(toggled(bool)), d->imageView, SLOT(setViewOutline(bool))); + connect(d->ui_toolbar.toolButtonPlayPause, SIGNAL(clicked()), + this, SLOT(playToggled())); + connect(d->imageView, SIGNAL(imageSizeChanged(QSize)), + this, SLOT(imageSizeUpdated(QSize))); connect(d->imageView, SIGNAL(scaleFactorChanged(qreal)), this, SLOT(scaleFactorUpdate(qreal))); } @@ -126,11 +130,8 @@ bool ImageViewer::open(QString *errorString, const QString &fileName, const QStr } setDisplayName(QFileInfo(fileName).fileName()); d->file->setFileName(fileName); - const QSize imageSize = d->imageView->imageSize(); - QString imageSizeText; - if (imageSize.isValid()) - imageSizeText = QString::fromLatin1("%1x%2").arg(imageSize.width()).arg(imageSize.height()); - d->ui_toolbar.labelImageSize->setText(imageSizeText); + d->ui_toolbar.toolButtonPlayPause->setVisible(d->imageView->isAnimated()); + setPaused(!d->imageView->isAnimated()); // d_ptr->file->setMimeType emit changed(); return true; @@ -199,6 +200,14 @@ QWidget *ImageViewer::toolBar() return d->toolbar; } +void ImageViewer::imageSizeUpdated(const QSize &size) +{ + QString imageSizeText; + if (size.isValid()) + imageSizeText = QString::fromLatin1("%1x%2").arg(size.width()).arg(size.height()); + d->ui_toolbar.labelImageSize->setText(imageSizeText); +} + void ImageViewer::scaleFactorUpdate(qreal factor) { const QString info = QString::number(factor * 100, 'f', 2) + QLatin1Char('%'); @@ -248,5 +257,28 @@ void ImageViewer::fitToScreen() d->ui_toolbar.toolButtonFitToScreen->click(); } +void ImageViewer::togglePlay() +{ + d->ui_toolbar.toolButtonPlayPause->click(); +} + +void ImageViewer::playToggled() +{ + bool paused = d->imageView->isPaused(); + setPaused(!paused); +} + +void ImageViewer::setPaused(bool paused) +{ + d->imageView->setPaused(paused); + if (paused) { + d->ui_toolbar.toolButtonPlayPause->setToolTip(tr("Play Animation")); + d->ui_toolbar.toolButtonPlayPause->setIcon(QPixmap(QLatin1String(":/imageviewer/images/play-small.png"))); + } else { + d->ui_toolbar.toolButtonPlayPause->setToolTip(tr("Pause Animation")); + d->ui_toolbar.toolButtonPlayPause->setIcon(QPixmap(QLatin1String(":/imageviewer/images/pause-small.png"))); + } +} + } // namespace Internal } // namespace ImageViewer diff --git a/src/plugins/imageviewer/imageviewer.h b/src/plugins/imageviewer/imageviewer.h index ef9a23eda1c..e6cb3e43714 100644 --- a/src/plugins/imageviewer/imageviewer.h +++ b/src/plugins/imageviewer/imageviewer.h @@ -78,6 +78,7 @@ public: QWidget *toolBar(); public slots: + void imageSizeUpdated(const QSize &size); void scaleFactorUpdate(qreal factor); void switchViewBackground(); @@ -86,6 +87,10 @@ public slots: void zoomOut(); void resetToOriginalSize(); void fitToScreen(); + void togglePlay(); + +private slots: + void playToggled(); private: /*! @@ -95,6 +100,7 @@ private: \return true if icon is updated, false otherwise */ bool updateButtonIconByTheme(QAbstractButton *button, const QString &name); + void setPaused(bool paused); private: struct ImageViewerPrivate *d; diff --git a/src/plugins/imageviewer/imageviewer.qrc b/src/plugins/imageviewer/imageviewer.qrc index 396279668d8..d48561a89ef 100644 --- a/src/plugins/imageviewer/imageviewer.qrc +++ b/src/plugins/imageviewer/imageviewer.qrc @@ -7,5 +7,7 @@ images/fitinscreen.png images/originalsize.png images/background.png + images/pause-small.png + images/play-small.png diff --git a/src/plugins/imageviewer/imageviewertoolbar.ui b/src/plugins/imageviewer/imageviewertoolbar.ui index 9f6eeb25204..6b78452fae6 100644 --- a/src/plugins/imageviewer/imageviewertoolbar.ui +++ b/src/plugins/imageviewer/imageviewertoolbar.ui @@ -104,6 +104,13 @@ + + + + Pause Animation + + + @@ -144,6 +151,7 @@ +