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