File indexing completed on 2024-05-19 05:40:35
0001 /*************************************************************************** 0002 * Copyright (C) 2019 by Renaud Guezennec * 0003 * http://www.rolisteam.org/contact * 0004 * * 0005 * This software is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 #include "controller/view_controller/imagecontroller.h" 0021 0022 #include <QBuffer> 0023 #include <QDebug> 0024 #include <QFile> 0025 #include <QMovie> 0026 0027 #include "utils/iohelper.h" 0028 0029 constexpr char const* RESOURCE_SCHEME{"qrc"}; 0030 ImageController::ImageController(const QString& id, const QString& name, const QUrl& url, const QByteArray& data, 0031 QObject* parent) 0032 : MediaControllerBase(id, Core::ContentType::PICTURE, parent), m_data(data) 0033 { 0034 setName(name); 0035 setUrl(url); 0036 if(m_data.isEmpty() && !url.isEmpty() && (url.isLocalFile() || url.scheme() == RESOURCE_SCHEME)) 0037 { 0038 QString path 0039 = url.isLocalFile() ? url.toLocalFile() : QString(":%1").arg(url.toDisplayString(QUrl::RemoveScheme)); 0040 0041 m_data= utils::IOHelper::loadFile(path); 0042 } 0043 checkMovie(); 0044 } 0045 0046 ImageController::~ImageController()= default; 0047 0048 bool ImageController::fitWindow() const 0049 { 0050 return m_fitWindow; 0051 } 0052 0053 QByteArray ImageController::data() const 0054 { 0055 return m_data; 0056 } 0057 0058 qreal ImageController::zoomLevel() const 0059 { 0060 return m_zoomLevel; 0061 } 0062 0063 const QPixmap& ImageController::pixmap() const 0064 { 0065 return m_image; 0066 } 0067 0068 Qt::CursorShape ImageController::cursor() const 0069 { 0070 return m_fitWindow ? Qt::ArrowCursor : Qt::OpenHandCursor; 0071 } 0072 0073 bool ImageController::isMovie() const 0074 { 0075 if(!m_movie) 0076 return false; 0077 return m_movie->isValid(); 0078 } 0079 0080 ImageController::Status ImageController::status() const 0081 { 0082 return m_status; 0083 } 0084 0085 qreal ImageController::ratioV() const 0086 { 0087 if(m_image.isNull()) 0088 return 0; 0089 return static_cast<qreal>(m_image.size().width()) / m_image.size().height(); 0090 } 0091 0092 qreal ImageController::ratioH() const 0093 { 0094 if(m_image.isNull()) 0095 return 0; 0096 return static_cast<qreal>(m_image.size().height()) / m_image.size().width(); 0097 } 0098 0099 void ImageController::setZoomLevel(qreal lvl) 0100 { 0101 lvl= qBound(0.2, lvl, 4.0); 0102 if(qFuzzyCompare(lvl, m_zoomLevel)) 0103 return; 0104 0105 m_zoomLevel= lvl; 0106 emit zoomLevelChanged(); 0107 } 0108 0109 void ImageController::setFitWindow(bool b) 0110 { 0111 0112 if(m_fitWindow == b) 0113 return; 0114 m_fitWindow= b; 0115 emit fitWindowChanged(); 0116 emit cursorChanged(); 0117 } 0118 0119 void ImageController::setStatus(Status status) 0120 { 0121 if(m_status == status) 0122 return; 0123 m_status= status; 0124 emit statusChanged(m_status); 0125 } 0126 0127 void ImageController::zoomIn(qreal step) 0128 { 0129 setZoomLevel(m_zoomLevel + step); 0130 } 0131 0132 void ImageController::zoomOut(qreal step) 0133 { 0134 setZoomLevel(m_zoomLevel - step); 0135 } 0136 0137 void ImageController::play() 0138 { 0139 if(!m_movie) 0140 return; 0141 if(m_status == Playing) 0142 m_movie->setPaused(true); 0143 else if(m_status == Paused) 0144 m_movie->start(); 0145 } 0146 0147 void ImageController::stop() 0148 { 0149 if(!m_movie) 0150 return; 0151 m_movie->stop(); 0152 } 0153 0154 void ImageController::setPixmap(const QPixmap& pix) 0155 { 0156 m_image= pix; 0157 emit pixmapChanged(); 0158 } 0159 0160 void ImageController::checkMovie() 0161 { 0162 auto buf= new QBuffer(&m_data); 0163 buf->open(QIODevice::ReadOnly); 0164 0165 m_movie.reset(new QMovie(buf, QByteArray(), this)); 0166 if((m_movie->isValid()) && (m_movie->frameCount() > 1)) 0167 { 0168 connect(m_movie.get(), &QMovie::updated, this, [this]() { setPixmap(m_movie->currentPixmap()); }); 0169 connect(m_movie.get(), &QMovie::stateChanged, this, [this](const QMovie::MovieState& state) { 0170 switch(state) 0171 { 0172 case QMovie::NotRunning: 0173 setStatus(ImageController::Stopped); 0174 break; 0175 case QMovie::Paused: 0176 setStatus(ImageController::Paused); 0177 break; 0178 case QMovie::Running: 0179 setStatus(ImageController::Playing); 0180 break; 0181 } 0182 }); 0183 m_movie->start(); 0184 } 0185 else 0186 { 0187 m_movie.reset(); 0188 QPixmap img; 0189 img.loadFromData(m_data); 0190 setPixmap(img); 0191 } 0192 } 0193 0194 void ImageController::setData(QByteArray& array) 0195 { 0196 if(m_data == array) 0197 return; 0198 m_data= array; 0199 emit dataChanged(); 0200 checkMovie(); 0201 } 0202 0203 const QPixmap ImageController::scaledPixmap() const 0204 { 0205 return m_image.scaled(static_cast<int>(m_image.width() * m_zoomLevel), 0206 static_cast<int>(m_image.height() * m_zoomLevel)); 0207 }