/* * SPDX-FileCopyrightText: 2006 Peter Penz * * SPDX-License-Identifier: GPL-2.0-or-later */ #include "pixmapviewer.h" #include #include #include #include #include PixmapViewer::PixmapViewer(QWidget *parent) : QWidget(parent) , m_animatedImage(nullptr) , m_sizeHint() , m_hasAnimatedImage(false) { setMinimumWidth(KIconLoader::SizeEnormous); setMinimumHeight(KIconLoader::SizeEnormous); } PixmapViewer::~PixmapViewer() { } void PixmapViewer::setPixmap(const QPixmap &pixmap) { if (pixmap.isNull()) { return; } m_pixmap = pixmap; // Avoid flicker with static pixmap if an animated image is running if (m_animatedImage && m_animatedImage->state() == QMovie::Running) { return; } update(); 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->start(); } } } void PixmapViewer::setSizeHint(const QSize &size) { if (m_animatedImage && size != m_sizeHint) { m_animatedImage->setScaledSize(QSize()); m_animatedImage->stop(); } m_sizeHint = size; updateGeometry(); } QSize PixmapViewer::sizeHint() const { return m_sizeHint; } void PixmapViewer::setAnimatedImageFileName(const QString &fileName) { if (!m_animatedImage) { m_animatedImage = new QMovie(this); connect(m_animatedImage, &QMovie::frameChanged, this, &PixmapViewer::updateAnimatedImageFrame); } if (m_animatedImage->fileName() != fileName) { m_animatedImage->setFileName(fileName); } m_hasAnimatedImage = m_animatedImage->isValid() && (m_animatedImage->frameCount() > 1); } QString PixmapViewer::animatedImageFileName() const { if (!m_hasAnimatedImage) { return QString(); } return m_animatedImage->fileName(); } void PixmapViewer::paintEvent(QPaintEvent *event) { QWidget::paintEvent(event); QPainter painter(this); if (!m_pixmap.isNull()) { style()->drawItemPixmap(&painter, rect(), Qt::AlignCenter, m_pixmap); } } void PixmapViewer::updateAnimatedImageFrame() { Q_ASSERT(m_animatedImage); m_pixmap = m_animatedImage->currentPixmap(); const auto physicalSize = m_sizeHint * devicePixelRatio(); if (m_pixmap.width() > physicalSize.width() || m_pixmap.height() > physicalSize.height()) { m_pixmap = m_pixmap.scaled(physicalSize, Qt::KeepAspectRatio); m_animatedImage->setScaledSize(m_pixmap.size()); } m_pixmap.setDevicePixelRatio(devicePixelRatio()); update(); } void PixmapViewer::stopAnimatedImage() { if (m_hasAnimatedImage) { m_animatedImage->stop(); m_hasAnimatedImage = false; delete m_animatedImage; m_animatedImage = nullptr; } } bool PixmapViewer::isAnimatedMimeType(const QString &mimeType) { const QList 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"