]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/panels/information/pixmapviewer.cpp
panels/information: Fix preview size for animated images
[dolphin.git] / src / panels / information / pixmapviewer.cpp
index 2601e82ae50aba1915ada813f6f4453d3adbbc4f..b18c9e64ef4c0522ccd062274c431ef97aacce9c 100644 (file)
@@ -1,21 +1,8 @@
-/***************************************************************************
- *   Copyright (C) 2006 by Peter Penz <peter.penz19@gmail.com>             *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
- ***************************************************************************/
+/*
+ * SPDX-FileCopyrightText: 2006 Peter Penz <peter.penz19@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
 
 #include "pixmapviewer.h"
 
 #include <QPainter>
 #include <QStyle>
 
-PixmapViewer::PixmapViewer(QWidget* parent, Transition transition) :
-    QWidget(parent),
-    m_animatedImage(nullptr),
-    m_transition(transition),
-    m_animationStep(0),
-    m_sizeHint(),
-    m_hasAnimatedImage(false)
+PixmapViewer::PixmapViewer(QWidget *parent, Transition transition)
+    : QWidget(parent)
+    , m_animatedImage(nullptr)
+    , m_transition(transition)
+    , m_animationStep(0)
+    , m_sizeHint()
+    m_hasAnimatedImage(false)
 {
     setMinimumWidth(KIconLoader::SizeEnormous);
     setMinimumHeight(KIconLoader::SizeEnormous);
 
     m_animation.setDuration(150);
-    m_animation.setCurveShape(QTimeLine::LinearCurve);
+    m_animation.setEasingCurve(QEasingCurve::Linear);
 
     if (m_transition != NoTransition) {
         connect(&m_animation, &QTimeLine::valueChanged, this, QOverload<>::of(&PixmapViewer::update));
@@ -50,17 +37,12 @@ PixmapViewer::~PixmapViewer()
 {
 }
 
-void PixmapViewer::setPixmap(const QPixmappixmap)
+void PixmapViewer::setPixmap(const QPixmap &pixmap)
 {
     if (pixmap.isNull()) {
         return;
     }
 
-    // Avoid flicker with static pixmap if an animated image is running
-    if (m_animatedImage && m_animatedImage->state() == QMovie::Running) {
-        return;
-    }
-
     if ((m_transition != NoTransition) && (m_animation.state() == QTimeLine::Running)) {
         m_pendingPixmaps.enqueue(pixmap);
         if (m_pendingPixmaps.count() > 5) {
@@ -72,23 +54,27 @@ void PixmapViewer::setPixmap(const QPixmap& pixmap)
 
     m_oldPixmap = m_pixmap.isNull() ? pixmap : m_pixmap;
     m_pixmap = pixmap;
+
+    // Avoid flicker with static pixmap if an animated image is running
+    if (m_animatedImage && m_animatedImage->state() == QMovie::Running) {
+        return;
+    }
+
     update();
 
-    const bool animateTransition = (m_transition != NoTransition) &&
-                                   (m_pixmap.size() != m_oldPixmap.size());
+    const bool animateTransition = (m_transition != NoTransition) && (m_pixmap.size() != m_oldPixmap.size());
     if (animateTransition) {
         m_animation.start();
     } else if (m_hasAnimatedImage) {
         // If there is no transition animation but an animatedImage
         // and it is not already running, start animating now
         if (m_animatedImage->state() != QMovie::Running) {
-            m_animatedImage->setScaledSize(m_pixmap.size());
             m_animatedImage->start();
         }
     }
 }
 
-void PixmapViewer::setSizeHint(const QSizesize)
+void PixmapViewer::setSizeHint(const QSize &size)
 {
     if (m_animatedImage && size != m_sizeHint) {
         m_animatedImage->stop();
@@ -111,14 +97,12 @@ void PixmapViewer::setAnimatedImageFileName(const QString &fileName)
     }
 
     if (m_animatedImage->fileName() != fileName) {
-        m_animatedImage->stop();
         m_animatedImage->setFileName(fileName);
     }
 
     m_hasAnimatedImage = m_animatedImage->isValid() && (m_animatedImage->frameCount() > 1);
 }
 
-
 QString PixmapViewer::animatedImageFileName() const
 {
     if (!m_hasAnimatedImage) {
@@ -127,7 +111,7 @@ QString PixmapViewer::animatedImageFileName() const
     return m_animatedImage->fileName();
 }
 
-void PixmapViewer::paintEvent(QPaintEventevent)
+void PixmapViewer::paintEvent(QPaintEvent *event)
 {
     QWidget::paintEvent(event);
 
@@ -135,21 +119,18 @@ void PixmapViewer::paintEvent(QPaintEvent* event)
 
     if (m_transition != NoTransition || (m_hasAnimatedImage && m_animatedImage->state() != QMovie::Running)) {
         const float value = m_animation.currentValue();
-        const int scaledWidth  = static_cast<int>((m_oldPixmap.width()  * (1.0 - value)) + (m_pixmap.width()  * value));
+        const int scaledWidth = static_cast<int>((m_oldPixmap.width() * (1.0 - value)) + (m_pixmap.width() * value));
         const int scaledHeight = static_cast<int>((m_oldPixmap.height() * (1.0 - value)) + (m_pixmap.height() * value));
 
-        const bool useOldPixmap = (m_transition == SizeTransition) &&
-                                  (m_oldPixmap.width() > m_pixmap.width());
-        const QPixmap& largePixmap = useOldPixmap ? m_oldPixmap : m_pixmap;
+        const bool useOldPixmap = (m_transition == SizeTransition) && (m_oldPixmap.width() > m_pixmap.width());
+        const QPixmap &largePixmap = useOldPixmap ? m_oldPixmap : m_pixmap;
         if (!largePixmap.isNull()) {
-            const QPixmap scaledPixmap = largePixmap.scaled(scaledWidth,
-                                                            scaledHeight,
-                                                            Qt::IgnoreAspectRatio,
-                                                            Qt::FastTransformation);
+            QPixmap scaledPixmap = largePixmap.scaled(scaledWidth, scaledHeight, Qt::IgnoreAspectRatio, Qt::FastTransformation);
+            scaledPixmap.setDevicePixelRatio(devicePixelRatioF());
 
             style()->drawItemPixmap(&painter, rect(), Qt::AlignCenter, scaledPixmap);
         }
-    } else {
+    } else if (!m_pixmap.isNull()) {
         style()->drawItemPixmap(&painter, rect(), Qt::AlignCenter, m_pixmap);
     }
 }
@@ -172,9 +153,13 @@ void PixmapViewer::checkPendingPixmaps()
 
 void PixmapViewer::updateAnimatedImageFrame()
 {
-    Q_ASSERT (m_animatedImage);
+    Q_ASSERT(m_animatedImage);
 
     m_pixmap = m_animatedImage->currentPixmap();
+    if (m_pixmap.width() > m_sizeHint.width() || m_pixmap.height() > m_sizeHint.height()) {
+        m_pixmap = m_pixmap.scaled(m_sizeHint, Qt::KeepAspectRatio);
+        m_animatedImage->setScaledSize(m_pixmap.size());
+    }
     update();
 }
 
@@ -183,11 +168,17 @@ void PixmapViewer::stopAnimatedImage()
     if (m_hasAnimatedImage) {
         m_animatedImage->stop();
         m_hasAnimatedImage = false;
+        delete m_animatedImage;
+        m_animatedImage = nullptr;
     }
 }
 
-bool PixmapViewer::isAnimatedImage(const QString &fileName)
+bool PixmapViewer::isAnimatedMimeType(const QString &mimeType)
 {
-    const QByteArray imageFormat = QImageReader::imageFormat(fileName);
-    return !imageFormat.isEmpty() && QMovie::supportedFormats().contains(imageFormat);
+    const QList<QByteArray> imageFormats = QImageReader::imageFormatsForMimeType(mimeType.toUtf8());
+    return std::any_of(imageFormats.begin(), imageFormats.end(), [](const QByteArray &format) {
+        return QMovie::supportedFormats().contains(format);
+    });
 }
+
+#include "moc_pixmapviewer.cpp"