File indexing completed on 2024-05-12 05:39:37
0001 /*************************************************************************** 0002 * Copyright (C) 2014 by Renaud Guezennec * 0003 * http://www.rolisteam.org/ * 0004 * * 0005 * This file is part of rcse * 0006 * * 0007 * rcse is free software; you can redistribute it and/or modify * 0008 * it under the terms of the GNU General Public License as published by * 0009 * the Free Software Foundation; either version 2 of the License, or * 0010 * (at your option) any later version. * 0011 * * 0012 * rcse is distributed in the hope that it will be useful, * 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0015 * GNU General Public License for more details. * 0016 * * 0017 * You should have received a copy of the GNU General Public License * 0018 * along with this program; if not, write to the * 0019 * Free Software Foundation, Inc., * 0020 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0021 ***************************************************************************/ 0022 #include "canvas.h" 0023 #include <QDebug> 0024 #include <QGraphicsSceneDragDropEvent> 0025 #include <QMimeData> 0026 #include <QUrl> 0027 #include <cmath> 0028 #include <QCryptographicHash> 0029 0030 #include "undo/addfieldcommand.h" 0031 #include "undo/deletefieldcommand.h" 0032 #include "undo/movefieldcommand.h" 0033 #include "undo/setbackgroundimage.h" 0034 #include "utils/iohelper.h" 0035 #include "controllers/editorcontroller.h" 0036 #include "controllers/imagecontroller.h" 0037 0038 #include "tablecanvasfield.h" 0039 0040 //#include "charactersheetbutton.h" 0041 0042 Canvas::Canvas(EditorController* ctrl, QObject* parent) 0043 : QGraphicsScene(parent), m_ctrl(ctrl), m_bg(new QGraphicsPixmapItem()), m_currentItem(nullptr), m_model(nullptr) 0044 { 0045 setSceneRect(QRect(0, 0, 800, 600)); 0046 m_bg->setFlag(QGraphicsItem::ItemIsSelectable, false); 0047 m_bg->setFlag(QGraphicsItem::ItemSendsGeometryChanges, false); 0048 m_bg->setFlag(QGraphicsItem::ItemIsMovable, false); 0049 m_bg->setFlag(QGraphicsItem::ItemIsFocusable, false); 0050 m_bg->setAcceptedMouseButtons(Qt::NoButton); 0051 } 0052 0053 void Canvas::dragEnterEvent(QGraphicsSceneDragDropEvent* event) 0054 { 0055 const QMimeData* mimeData= event->mimeData(); 0056 if(mimeData->hasUrls()) 0057 { 0058 event->acceptProposedAction(); 0059 } 0060 } 0061 0062 void Canvas::dragMoveEvent(QGraphicsSceneDragDropEvent* event) 0063 { 0064 event->acceptProposedAction(); 0065 } 0066 void Canvas::dropEvent(QGraphicsSceneDragDropEvent* event) 0067 { 0068 const QMimeData* mimeData= event->mimeData(); 0069 if(mimeData->hasUrls()) 0070 { 0071 for(const QUrl& url : mimeData->urls()) 0072 { 0073 if(url.isLocalFile()) 0074 { 0075 emit dropFileOnCanvas(url); 0076 } 0077 } 0078 } 0079 } 0080 0081 void Canvas::setCurrentTool(Canvas::Tool tool) 0082 { 0083 m_currentTool= tool; 0084 if(nullptr != m_currentItem) 0085 { 0086 m_currentItem= nullptr; 0087 } 0088 } 0089 void Canvas::deleteItem(QGraphicsItem* item) 0090 { 0091 auto fieldItem= dynamic_cast<CanvasField*>(item); 0092 if(nullptr != fieldItem) 0093 { 0094 DeleteFieldCommand* deleteCommand= new DeleteFieldCommand(fieldItem->controller(), this, m_model, m_pageId); 0095 emit performCommand(deleteCommand); 0096 } 0097 } 0098 void Canvas::mousePressEvent(QGraphicsSceneMouseEvent* mouseEvent) 0099 { 0100 if(mouseEvent->button() == Qt::RightButton) 0101 { 0102 mouseEvent->accept(); 0103 return; 0104 } 0105 0106 if(mouseEvent->button() != Qt::LeftButton) 0107 QGraphicsScene::mousePressEvent(mouseEvent); 0108 0109 if(forwardEvent()) 0110 { 0111 m_oldPos.clear(); 0112 QPointF mousePos(mouseEvent->buttonDownScenePos(Qt::LeftButton).x(), 0113 mouseEvent->buttonDownScenePos(Qt::LeftButton).y()); 0114 const QList<QGraphicsItem*> itemList= items(mousePos); 0115 m_movingItems.append(itemList.isEmpty() ? nullptr : itemList.first()); 0116 0117 if(m_movingItems.first() != nullptr && mouseEvent->button() == Qt::LeftButton) 0118 { 0119 m_oldPos.append(m_movingItems.first()->pos()); 0120 } 0121 0122 // clearSelection(); 0123 QGraphicsScene::mousePressEvent(mouseEvent); 0124 } 0125 if(m_currentTool == Canvas::DELETETOOL) 0126 { 0127 QList<QGraphicsItem*> itemList= items(mouseEvent->scenePos()); 0128 for(QGraphicsItem* item : itemList) 0129 { 0130 if(item != m_bg) 0131 { 0132 deleteItem(item); 0133 } 0134 } 0135 mouseEvent->accept(); 0136 } 0137 else if((m_currentTool <= Canvas::ADDCHECKBOX) || (m_currentTool == Canvas::BUTTON)) 0138 { 0139 auto imageController= m_ctrl->imageController(); 0140 0141 charactersheet::ImageModel* model= nullptr; 0142 if(nullptr != imageController) 0143 model= imageController->model(); 0144 0145 AddFieldCommand* addCommand 0146 = new AddFieldCommand(m_currentTool, this, m_model, m_pageId, model, mouseEvent->scenePos()); 0147 0148 emit performCommand(addCommand); 0149 mouseEvent->accept(); 0150 } 0151 0152 QGraphicsScene::mousePressEvent(mouseEvent); 0153 } 0154 void Canvas::mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent) 0155 { 0156 if(forwardEvent()) 0157 { 0158 QGraphicsScene::mouseMoveEvent(mouseEvent); 0159 } 0160 else if(m_currentItem != nullptr) 0161 { 0162 m_currentItem->setNewEnd(m_currentItem->mapFromScene(mouseEvent->scenePos())); 0163 update(); 0164 } 0165 } 0166 bool Canvas::forwardEvent() 0167 { 0168 return (Canvas::MOVE == m_currentTool) || (Canvas::NONE == m_currentTool); 0169 } 0170 0171 void Canvas::mouseReleaseEvent(QGraphicsSceneMouseEvent* mouseEvent) 0172 { 0173 Q_UNUSED(mouseEvent); 0174 0175 if(forwardEvent()) 0176 { 0177 if(!m_movingItems.isEmpty()) 0178 { 0179 if(m_movingItems.first() != nullptr && mouseEvent->button() == Qt::LeftButton) 0180 { 0181 if(m_oldPos.first() != m_movingItems.first()->pos()) 0182 { 0183 MoveFieldCommand* moveCmd= new MoveFieldCommand(m_movingItems, m_oldPos); 0184 emit performCommand(moveCmd); 0185 } 0186 m_movingItems.clear(); 0187 m_oldPos.clear(); 0188 } 0189 } 0190 QGraphicsScene::mouseReleaseEvent(mouseEvent); 0191 } 0192 else 0193 { 0194 adjustNewItem(m_currentItem); 0195 m_currentItem= nullptr; 0196 } 0197 } 0198 void Canvas::adjustNewItem(CanvasField* field) 0199 { 0200 if(nullptr == field) 0201 return; 0202 0203 auto ctrl= field->controller(); 0204 if(ctrl->width() < 0) 0205 { 0206 ctrl->setX(ctrl->x() + ctrl->width()); 0207 ctrl->setWidth(fabs(ctrl->width())); 0208 } 0209 0210 if(ctrl->height() < 0) 0211 { 0212 ctrl->setY(ctrl->y() + ctrl->height()); 0213 ctrl->setHeight(fabs(ctrl->height())); 0214 } 0215 } 0216 0217 void Canvas::addField(CSItem* itemCtrl) 0218 { 0219 CanvasField* cf= nullptr; 0220 switch(itemCtrl->itemType()) 0221 { 0222 case TreeSheetItem::FieldItem: 0223 cf= new CanvasField(dynamic_cast<FieldController*>(itemCtrl)); 0224 break; 0225 case TreeSheetItem::TableItem: 0226 cf= new TableCanvasField(dynamic_cast<FieldController*>(itemCtrl)); 0227 break; 0228 default: 0229 break; 0230 } 0231 if(cf) 0232 { 0233 m_currentItem= cf; 0234 addItem(m_currentItem); 0235 m_currentItem->setPos({itemCtrl->x(), itemCtrl->y()}); 0236 } 0237 } 0238 0239 Canvas::Tool Canvas::currentTool() const 0240 { 0241 return m_currentTool; 0242 } 0243 0244 int Canvas::pageId() const 0245 { 0246 return m_pageId; 0247 } 0248 0249 void Canvas::setPageId(int pageId) 0250 { 0251 if(pageId == m_pageId) 0252 return; 0253 m_pageId= pageId; 0254 emit pageIdChanged(); 0255 } 0256 FieldModel* Canvas::model() const 0257 { 0258 return m_model; 0259 } 0260 0261 void Canvas::setModel(FieldModel* model) 0262 { 0263 m_model= model; 0264 } 0265 0266 const QPixmap Canvas::pixmap() const 0267 { 0268 return m_bg ? m_bg->pixmap() : QPixmap(); 0269 } 0270 void Canvas::setPixmap(const QPixmap& pix) 0271 { 0272 static QString md5; 0273 auto key = QCryptographicHash::hash(utils::IOHelper::imageToData(pix.toImage()), QCryptographicHash::Md5); 0274 0275 if(md5 == key) 0276 return; 0277 m_bg->setPixmap(pix); 0278 emit pixmapChanged(); 0279 0280 if(pix.isNull()) 0281 removeItem(m_bg); 0282 else 0283 { 0284 addItem(m_bg); 0285 setSceneRect(m_bg->boundingRect()); 0286 } 0287 md5 = key; 0288 }