File indexing completed on 2024-05-19 05:40:34

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/item_controllers/imageitemcontroller.h"
0021 
0022 #include "controller/view_controller/vectorialmapcontroller.h"
0023 #include "worker/utilshelper.h"
0024 #include <QBuffer>
0025 #include <QDebug>
0026 #include <QFile>
0027 #include <QMovie>
0028 
0029 namespace vmap
0030 {
0031 QByteArray readImage(const QString& path)
0032 {
0033     QFile file(path);
0034     if(!file.open(QIODevice::ReadOnly))
0035         return {};
0036     return file.readAll();
0037 }
0038 
0039 ImageItemController::ImageItemController(const std::map<QString, QVariant>& params, VectorialMapController* ctrl,
0040                                          QObject* parent)
0041     : VisualItemController(VisualItemController::IMAGE, params, ctrl, parent)
0042 {
0043 
0044     m_tool= Core::SelectableTool::IMAGE;
0045 
0046     namespace hu= helper::utils;
0047     namespace cv= Core::vmapkeys;
0048     using std::placeholders::_1;
0049 
0050     hu::setParamIfAny<QString>(cv::KEY_PATH, params,
0051                                [this](const QString& path)
0052                                {
0053                                    setPath(path);
0054                                    setData(readImage(path));
0055                                });
0056     hu::setParamIfAny<QByteArray>(cv::KEY_DATA, params, std::bind(&ImageItemController::setData, this, _1));
0057 
0058     checkMovie();
0059 
0060     hu::setParamIfAny<QRectF>(cv::KEY_RECT, params, std::bind(&ImageItemController::setRect, this, _1));
0061 
0062     if(rect().isNull())
0063         setRect(m_pix.rect());
0064 
0065     connect(this, &vmap::ImageItemController::pixmapChanged, this, [this] { setModified(); });
0066     connect(this, &vmap::ImageItemController::dataChanged, this, [this] { setModified(); });
0067     connect(this, &vmap::ImageItemController::rectChanged, this, [this] { setModified(); });
0068     connect(this, &vmap::ImageItemController::pathChanged, this, [this] { setModified(); });
0069 }
0070 
0071 QRectF ImageItemController::rect() const
0072 {
0073     return m_rect;
0074 }
0075 
0076 QPixmap ImageItemController::pixmap() const
0077 {
0078     return m_pix;
0079 }
0080 
0081 void ImageItemController::setRect(QRectF rect)
0082 {
0083     if(rect == m_rect)
0084         return;
0085     m_rect= rect;
0086     emit rectChanged();
0087     m_editingRect= true;
0088 }
0089 
0090 void ImageItemController::setImage(QPixmap pix)
0091 {
0092     if(pix.toImage() == m_pix.toImage())
0093         return;
0094     m_pix= pix;
0095     emit pixmapChanged();
0096 }
0097 
0098 void ImageItemController::setCorner(const QPointF& move, int corner, Core::TransformType tt)
0099 {
0100     if(move.isNull())
0101         return;
0102 
0103     auto rect= m_rect;
0104     qreal x2= rect.right();
0105     qreal y2= rect.bottom();
0106     qreal x= rect.x();
0107     qreal y= rect.y();
0108     switch(corner)
0109     {
0110     case TopLeft:
0111         x+= move.x();
0112         y+= move.y();
0113         break;
0114     case TopRight:
0115         x2+= move.x();
0116         y+= move.y();
0117         break;
0118     case BottomRight:
0119         x2+= move.x();
0120         y2+= move.y();
0121         break;
0122     case BottomLeft:
0123         x+= move.x();
0124         y2+= move.y();
0125         break;
0126     }
0127     rect.setCoords(x, y, x2, y2);
0128     if(!rect.isValid())
0129         rect= rect.normalized();
0130     setRect(rect);
0131 }
0132 
0133 void ImageItemController::aboutToBeRemoved()
0134 {
0135     emit removeItem();
0136 }
0137 
0138 QString ImageItemController::path() const
0139 {
0140     return m_path;
0141 }
0142 
0143 qreal ImageItemController::ratio() const
0144 {
0145     if(m_pix.isNull() || (m_pix.height() == 0))
0146         return 1.0;
0147     return m_pix.width() / m_pix.height();
0148 }
0149 
0150 QByteArray ImageItemController::data() const
0151 {
0152     return m_data;
0153 }
0154 
0155 void ImageItemController::setData(QByteArray data)
0156 {
0157     if(m_data == data)
0158         return;
0159 
0160     m_data= data;
0161     emit dataChanged(m_data);
0162 }
0163 void ImageItemController::setPath(QString path)
0164 {
0165     if(m_path == path)
0166         return;
0167 
0168     m_path= path;
0169     emit pathChanged(m_path);
0170 }
0171 
0172 void ImageItemController::checkMovie()
0173 {
0174     auto buf= new QBuffer(&m_data);
0175     buf->open(QIODevice::ReadOnly);
0176 
0177     auto movie= new QMovie(buf, QByteArray(), this);
0178     if((movie->isValid()) && (movie->frameCount() > 1))
0179     {
0180         connect(movie, &QMovie::updated, this, [this, movie]() { setImage(movie->currentPixmap()); });
0181         movie->start();
0182         // m_rect= m_movie->frameRect();
0183     }
0184     else
0185     {
0186         delete movie;
0187         QPixmap img;
0188         img.loadFromData(m_data);
0189         setImage(img);
0190     }
0191 }
0192 
0193 void ImageItemController::endGeometryChange()
0194 {
0195     VisualItemController::endGeometryChange();
0196 
0197     if(m_editingRect)
0198     {
0199         emit rectEditFinished();
0200         m_editingRect= false;
0201     }
0202 }
0203 } // namespace vmap