diff --git a/src/panels/information/informationpanelcontent.h b/src/panels/information/informationpanelcontent.h --- a/src/panels/information/informationpanelcontent.h +++ b/src/panels/information/informationpanelcontent.h @@ -144,6 +144,7 @@ QPointer m_previewJob; QTimer* m_outdatedPreviewTimer; + QStringList m_animatedMimeTypes; PixmapViewer* m_preview; PhononWidget* m_phononWidget; diff --git a/src/panels/information/informationpanelcontent.cpp b/src/panels/information/informationpanelcontent.cpp --- a/src/panels/information/informationpanelcontent.cpp +++ b/src/panels/information/informationpanelcontent.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include "dolphin_informationpanelsettings.h" #include "phononwidget.h" @@ -90,6 +91,11 @@ connect(m_phononWidget, &PhononWidget::hasVideoChanged, this, &InformationPanelContent::slotHasVideoChanged); + // mimetypes that can be animated by QMovie (gif/mng/webp) + for ( const auto format : QMovie::supportedFormats() ) { + m_animatedMimeTypes << QString("image/%1").arg(QString(format)); + } + // name m_nameLabel = new QLabel(parent); QFont font = m_nameLabel->font(); @@ -174,6 +180,10 @@ m_previewJob->kill(); } + if (!m_preview->movieFileName().isEmpty()) { + m_preview->setMovieFileName(QString::null); + } + setNameLabelText(m_item.text()); if (InformationPanelSettings::previewsShown()) { @@ -218,6 +228,10 @@ const bool isVideo = mimeType.startsWith(QLatin1String("video/")); const bool usePhonon = mimeType.startsWith(QLatin1String("audio/")) || isVideo; + if (m_animatedMimeTypes.contains(mimeType)) { + m_preview->setMovieFileName(itemUrl.toLocalFile()); + } + if (usePhonon) { if (InformationPanelSettings::previewsAutoPlay() && isVideo) { @@ -319,7 +333,6 @@ const QPixmap& pixmap) { m_outdatedPreviewTimer->stop(); - Q_UNUSED(item); QPixmap p = pixmap; KIconLoader::global()->drawOverlays(item.overlays(), p, KIconLoader::Desktop); diff --git a/src/panels/information/pixmapviewer.h b/src/panels/information/pixmapviewer.h --- a/src/panels/information/pixmapviewer.h +++ b/src/panels/information/pixmapviewer.h @@ -24,6 +24,7 @@ #include #include #include +#include class QPaintEvent; @@ -73,15 +74,21 @@ void setSizeHint(const QSize& size); QSize sizeHint() const override; + void setMovieFileName(const QString& fileName); + QString movieFileName() const; + + protected: void paintEvent(QPaintEvent* event) override; private Q_SLOTS: void checkPendingPixmaps(); + void updateAnimationFrame(); private: QPixmap m_pixmap; QPixmap m_oldPixmap; + QMovie* m_movie; QQueue m_pendingPixmaps; QTimeLine m_animation; Transition m_transition; diff --git a/src/panels/information/pixmapviewer.cpp b/src/panels/information/pixmapviewer.cpp --- a/src/panels/information/pixmapviewer.cpp +++ b/src/panels/information/pixmapviewer.cpp @@ -23,6 +23,7 @@ #include #include +#include PixmapViewer::PixmapViewer(QWidget* parent, Transition transition) : QWidget(parent), @@ -40,10 +41,14 @@ connect(&m_animation, &QTimeLine::valueChanged, this, QOverload<>::of(&PixmapViewer::update)); connect(&m_animation, &QTimeLine::finished, this, &PixmapViewer::checkPendingPixmaps); } + + m_movie = new QMovie(this); + connect(m_movie, &QMovie::frameChanged, this, &PixmapViewer::updateAnimationFrame); } PixmapViewer::~PixmapViewer() { + delete m_movie; } void PixmapViewer::setPixmap(const QPixmap& pixmap) @@ -83,13 +88,24 @@ return m_sizeHint; } +void PixmapViewer::setMovieFileName(const QString &fileName) +{ + m_movie->stop(); + m_movie->setFileName(fileName); +} + +QString PixmapViewer::movieFileName() const +{ + return m_movie->fileName(); +} + void PixmapViewer::paintEvent(QPaintEvent* event) { QWidget::paintEvent(event); QPainter painter(this); - if (m_transition != NoTransition) { + if (m_transition != NoTransition || m_movie->state() != QMovie::Running) { const float value = m_animation.currentValue(); const int scaledWidth = static_cast((m_oldPixmap.width() * (1.0 - value)) + (m_pixmap.width() * value)); const int scaledHeight = static_cast((m_oldPixmap.height() * (1.0 - value)) + (m_pixmap.height() * value)); @@ -118,8 +134,16 @@ m_pixmap = pixmap; update(); m_animation.start(); + } else if (m_movie->isValid() && m_movie->frameCount() > 1) { + m_movie->setScaledSize(m_pixmap.size()); + m_movie->start(); } else { m_oldPixmap = m_pixmap; } } +void PixmapViewer::updateAnimationFrame() +{ + m_pixmap = m_movie->currentPixmap(); + update(); +}