File indexing completed on 2025-03-16 11:28:39
0001 /*************************************************************************** 0002 * Copyright (C) 2020 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 "media/mediafactory.h" 0021 0022 #include <QFileInfo> 0023 #include <QVariant> 0024 0025 #include "controller/view_controller/charactersheetcontroller.h" 0026 #include "controller/view_controller/imagecontroller.h" 0027 #include "controller/view_controller/mindmapcontroller.h" 0028 #include "controller/view_controller/notecontroller.h" 0029 #include "controller/view_controller/pdfcontroller.h" 0030 0031 #include "controller/view_controller/sharednotecontroller.h" 0032 #include "controller/view_controller/vectorialmapcontroller.h" 0033 #include "controller/view_controller/webpagecontroller.h" 0034 0035 #include "charactersheet/charactersheetmodel.h" 0036 #include "charactersheet/imagemodel.h" 0037 #include "charactersheet/worker/ioworker.h" 0038 0039 #include "mindmap/data/mindnode.h" 0040 #include "mindmap/data/minditem.h" 0041 0042 #include "mindmap/data/linkcontroller.h" 0043 #include "mindmap/data/minditem.h" 0044 #include "mindmap/data/mindnode.h" 0045 0046 #include "mindmap/model/imagemodel.h" 0047 0048 #include "network/networkmessagereader.h" 0049 #include "worker/iohelper.h" 0050 #include "worker/messagehelper.h" 0051 #include "worker/utilshelper.h" 0052 #include "worker/vectorialmapmessagehelper.h" 0053 0054 namespace Media 0055 { 0056 0057 namespace 0058 { 0059 ImageController* image(const QString& uuid, const QHash<QString, QVariant>& map) 0060 { 0061 QByteArray serializedData= map.value(Core::keys::KEY_SERIALIZED).toByteArray(); 0062 QByteArray pix= map.value(Core::keys::KEY_DATA).toByteArray(); 0063 QUrl url= map.value(Core::keys::KEY_URL).toUrl(); 0064 QString name= map.value(Core::keys::KEY_NAME).toString(); 0065 0066 return new ImageController(uuid, name, url, pix); 0067 } 0068 0069 CharacterSheetController* sheetCtrl(const QString& uuid, const QHash<QString, QVariant>& params) 0070 { 0071 auto path= params.value(Core::keys::KEY_PATH).toString(); 0072 0073 CharacterSheetController* sheetCtrl= new CharacterSheetController(uuid, path); 0074 0075 namespace ck= Core::keys; 0076 namespace hu= helper::utils; 0077 using std::placeholders::_1; 0078 0079 std::map<QString, QVariant> mapData; 0080 0081 for(auto it= std::begin(params); it != std::end(params); ++it) 0082 { 0083 mapData.insert({it.key(), it.value()}); 0084 } 0085 hu::setParamIfAny<QString>(ck::KEY_NAME, mapData, std::bind(&CharacterSheetController::setName, sheetCtrl, _1)); 0086 hu::setParamIfAny<QString>(ck::KEY_QML, mapData, std::bind(&CharacterSheetController::setQmlCode, sheetCtrl, _1)); 0087 hu::setParamIfAny<QString>(ck::KEY_GMID, mapData, 0088 std::bind(&CharacterSheetController::setGameMasterId, sheetCtrl, _1)); 0089 hu::setParamIfAny<QByteArray>(ck::KEY_IMAGEDATA, mapData, 0090 [sheetCtrl](const QByteArray& array) 0091 { 0092 auto imgModel= sheetCtrl->imageModel(); 0093 IOWorker::fetchImageModel(imgModel, IOHelper::byteArrayToJsonArray(array)); 0094 }); 0095 hu::setParamIfAny<QByteArray>(ck::KEY_ROOTSECTION, mapData, 0096 [sheetCtrl](const QByteArray& array) 0097 { 0098 auto sheetModel= sheetCtrl->model(); 0099 // sheetModel->setRootSection(IOHelper::byteArrayToJsonObj(array)); 0100 }); 0101 hu::setParamIfAny<QByteArray>( 0102 ck::KEY_DATA, mapData, 0103 [sheetCtrl, mapData](const QByteArray& array) 0104 { 0105 hu::setParamIfAny<QString>( 0106 ck::KEY_CHARACTERID, mapData, 0107 [sheetCtrl, array](const QString& characterId) 0108 { sheetCtrl->addCharacterSheet(IOHelper::byteArrayToJsonObj(array), characterId); }); 0109 }); 0110 hu::setParamIfAny<QByteArray>(ck::KEY_SERIALIZED, mapData, 0111 [sheetCtrl](const QByteArray& array) 0112 { IOHelper::readCharacterSheetController(sheetCtrl, array); }); 0113 return sheetCtrl; 0114 } 0115 0116 VectorialMapController* vectorialMap(const QString& uuid, const QHash<QString, QVariant>& params, bool isRemote= false) 0117 { 0118 auto vmapCtrl= new VectorialMapController(uuid); 0119 0120 QByteArray serializedData= params.value(Core::keys::KEY_SERIALIZED).toByteArray(); 0121 0122 if(!params.isEmpty() /*&& serializedData.isEmpty()*/) 0123 { 0124 namespace ck= Core::keys; 0125 namespace hu= helper::utils; 0126 using std::placeholders::_1; 0127 0128 std::map<QString, QVariant> mapData; 0129 0130 for(auto it= std::begin(params); it != std::end(params); ++it) 0131 { 0132 mapData.insert({it.key(), it.value()}); 0133 } 0134 0135 // clang-format off 0136 hu::setParamIfAny<QString>(ck::KEY_NAME, mapData, std::bind(&VectorialMapController::setName, vmapCtrl, _1)); 0137 hu::setParamIfAny<Core::Layer>(ck::KEY_LAYER, mapData, std::bind(&VectorialMapController::setLayer, vmapCtrl, _1)); 0138 hu::setParamIfAny<Core::PermissionMode>(ck::KEY_PERMISSION, mapData, std::bind(&VectorialMapController::setPermission, vmapCtrl, _1)); 0139 hu::setParamIfAny<QColor>(ck::KEY_BGCOLOR, mapData, std::bind(&VectorialMapController::setBackgroundColor, vmapCtrl, _1)); 0140 hu::setParamIfAny<Core::VisibilityMode>(ck::KEY_VISIBILITY, mapData, std::bind(&VectorialMapController::setVisibility, vmapCtrl, _1)); 0141 hu::setParamIfAny<int>(ck::KEY_ZINDEX, mapData, std::bind(&VectorialMapController::setZindex, vmapCtrl, _1)); 0142 hu::setParamIfAny<bool>(ck::KEY_CHARACTERVISION, mapData, std::bind(&VectorialMapController::setCharacterVision, vmapCtrl, _1)); 0143 hu::setParamIfAny<Core::GridPattern>(ck::KEY_GRIDPATTERN, mapData, std::bind(&VectorialMapController::setGridPattern, vmapCtrl, _1)); 0144 hu::setParamIfAny<bool>(ck::KEY_GRIDVISIBILITY, mapData, std::bind(&VectorialMapController::setGridVisibility, vmapCtrl, _1)); 0145 hu::setParamIfAny<int>(ck::KEY_GRIDSIZE, mapData, std::bind(&VectorialMapController::setGridSize, vmapCtrl, _1)); 0146 hu::setParamIfAny<qreal>(ck::KEY_GRIDSCALE, mapData, std::bind(&VectorialMapController::setGridScale, vmapCtrl, _1)); 0147 hu::setParamIfAny<bool>(ck::KEY_GRIDABOVE, mapData, std::bind(&VectorialMapController::setGridAbove, vmapCtrl, _1)); 0148 hu::setParamIfAny<Core::ScaleUnit>(ck::KEY_UNIT, mapData, std::bind(&VectorialMapController::setScaleUnit, vmapCtrl, _1)); 0149 hu::setParamIfAny<QColor>(ck::KEY_GRIDCOLOR, mapData, std::bind(&VectorialMapController::setGridColor, vmapCtrl, _1)); 0150 hu::setParamIfAny<bool>(Core::vmapkeys::KEY_LOCKED, mapData, std::bind(&VectorialMapController::setGridVisibility, vmapCtrl, _1)); 0151 auto sightCtrl = vmapCtrl->sightController(); 0152 auto sightParam = params.value(Core::keys::KEY_SIGHT).toHash(); 0153 VectorialMapMessageHelper::fetchSightController(sightCtrl, sightParam); 0154 // clang-format on 0155 0156 vmapCtrl->setIdle(true); 0157 0158 auto items= params.value(ck::KEY_ITEMS).toHash(); 0159 VectorialMapMessageHelper::fetchModelFromMap(items, vmapCtrl, isRemote); 0160 } 0161 0162 if(!serializedData.isEmpty()) 0163 VectorialMapMessageHelper::readVectorialMapController(vmapCtrl, serializedData); 0164 0165 return vmapCtrl; 0166 } 0167 0168 PdfController* pdf(const QString& uuid, const QHash<QString, QVariant>& params) 0169 { 0170 auto ownerid= params.value(Core::keys::KEY_OWNERID).toString(); 0171 auto array= params.value(Core::keys::KEY_DATA).toByteArray(); 0172 auto path= QUrl::fromUserInput(params.value(Core::keys::KEY_PATH).toString()); 0173 auto seriaziledData= params.value(Core::keys::KEY_SERIALIZED).toByteArray(); 0174 auto pdfCtrl= new PdfController(uuid, path, array.isEmpty() ? seriaziledData : array); 0175 pdfCtrl->setOwnerId(ownerid); 0176 if(!seriaziledData.isEmpty()) 0177 IOHelper::readPdfController(pdfCtrl, seriaziledData); 0178 return pdfCtrl; 0179 } 0180 0181 NoteController* note(const QString& uuid, const QHash<QString, QVariant>& map) 0182 { 0183 auto name= map.value(Core::keys::KEY_NAME).toString(); 0184 auto url= map.value(Core::keys::KEY_URL).toUrl(); 0185 0186 auto ownerid= map.value(Core::keys::KEY_OWNERID).toString(); 0187 auto serializedData= map.value(Core::keys::KEY_SERIALIZED).toByteArray(); 0188 0189 auto noteCtrl= new NoteController(uuid); 0190 0191 if(!name.isEmpty()) 0192 noteCtrl->setName(name); 0193 noteCtrl->setOwnerId(ownerid); 0194 noteCtrl->setUrl(url); 0195 0196 if(!serializedData.isEmpty()) 0197 IOHelper::readNoteController(noteCtrl, serializedData); 0198 0199 return noteCtrl; 0200 } 0201 MindMapController* mindmap(const QString& uuid, const QHash<QString, QVariant>& map) 0202 { 0203 auto name= map.value(Core::keys::KEY_NAME).toString(); 0204 auto url= map.value(Core::keys::KEY_URL).toUrl(); 0205 0206 auto ownerid= map.value(Core::keys::KEY_OWNERID).toString(); 0207 auto serializedData= map.value(Core::keys::KEY_SERIALIZED).toByteArray(); 0208 0209 auto mindmapCtrl= new MindMapController(uuid); 0210 0211 if(map.contains("indexStyle")) 0212 mindmapCtrl->setDefaultStyleIndex(map.value("indexStyle").toBool()); 0213 0214 QHash<QString, mindmap::MindNode*> data; 0215 if(map.contains("nodes")) 0216 { 0217 QHash<QString, QVariant> nodes= map.value("nodes").toHash(); 0218 0219 auto model= dynamic_cast<mindmap::MindItemModel*>(mindmapCtrl->itemModel()); 0220 QHash<QString, QString> parentData; 0221 QList<mindmap::MindItem*> nodesList; 0222 for(const auto& var : nodes) 0223 { 0224 auto node= new mindmap::MindNode(); 0225 auto nodeV= var.toHash(); 0226 node->setId(nodeV["uuid"].toString()); 0227 node->setText(nodeV["text"].toString()); 0228 node->setImageUri(nodeV["imageUri"].toString()); 0229 QPointF pos(nodeV["x"].toReal(), nodeV["y"].toReal()); 0230 node->setPosition(pos); 0231 node->setStyleIndex(nodeV["index"].toInt()); 0232 nodesList.append(node); 0233 data.insert(node->id(), node); 0234 parentData.insert(node->id(), nodeV["parentId"].toString()); 0235 } 0236 model->appendItem(nodesList); 0237 0238 for(const auto& key : data.keys()) 0239 { 0240 auto node= data.value(key); 0241 auto parentId= parentData.value(key); 0242 0243 if(!parentId.isEmpty()) 0244 { 0245 auto parent= data.value(parentId); 0246 if(parent) 0247 node->setParentNode(parent); 0248 } 0249 } 0250 } 0251 0252 if(map.contains("links")) 0253 { 0254 QHash<QString, QVariant> links= map.value("links").toHash(); 0255 0256 auto model= dynamic_cast<mindmap::MindItemModel*>(mindmapCtrl->itemModel()); 0257 0258 QList<mindmap::MindItem*> linkList; 0259 for(const auto& var : links) 0260 { 0261 auto link= new mindmap::LinkController(); 0262 auto linkV= var.toHash(); 0263 link->setId(linkV["uuid"].toString()); 0264 link->setText(linkV["text"].toString()); 0265 link->setDirection(static_cast<mindmap::LinkController::Direction>(linkV["direction"].toInt())); 0266 auto startId= linkV["startId"].toString(); 0267 auto endId= linkV["endId"].toString(); 0268 0269 Q_ASSERT(data.contains(endId) && data.contains(startId)); 0270 0271 link->setStart(data.value(startId)); 0272 link->setEnd(data.value(endId)); 0273 0274 linkList << link; 0275 } 0276 model->appendItem(linkList); 0277 } 0278 0279 if(map.contains("packages")) 0280 { 0281 QHash<QString, QVariant> links= map.value("links").toHash(); 0282 0283 auto model= dynamic_cast<mindmap::MindItemModel*>(mindmapCtrl->itemModel()); 0284 0285 QList<mindmap::MindItem*> linkList; 0286 for(const auto& var : links) 0287 { 0288 auto pack= new mindmap::PackageNode(); 0289 auto packV= var.toHash(); 0290 pack->setId(packV["uuid"].toString()); 0291 pack->setTitle(packV["title"].toString()); 0292 auto childrenId= packV["children"].toStringList(); 0293 for(auto const& id : childrenId) 0294 { 0295 pack->addChild(model->positionItem(id)); 0296 } 0297 } 0298 model->appendItem(linkList); 0299 } 0300 0301 if(map.contains("imageInfoData")) 0302 { 0303 QHash<QString, QVariant> imgInfos= map.value("imageInfoData").toHash(); 0304 auto model= mindmapCtrl->imgModel(); 0305 for(const auto& var : imgInfos) 0306 { 0307 auto img= var.toHash(); 0308 auto pix= img["pixmap"].value<QPixmap>(); 0309 auto id= img["id"].toString(); 0310 auto url= QUrl(img["url"].toString()); 0311 model->insertPixmap(id, pix, url); 0312 } 0313 } 0314 0315 if(!name.isEmpty()) 0316 mindmapCtrl->setName(name); 0317 0318 mindmapCtrl->setOwnerId(ownerid); 0319 mindmapCtrl->setUrl(url); 0320 0321 if(!serializedData.isEmpty()) 0322 IOHelper::readMindmapController(mindmapCtrl, serializedData); 0323 0324 return mindmapCtrl; 0325 } 0326 SharedNoteController* sharedNote(const QString& uuid, const QHash<QString, QVariant>& params, const QString& localId) 0327 { 0328 auto ownerId= params.value(Core::keys::KEY_OWNERID).toString(); 0329 auto b= params.value(Core::keys::KEY_MARKDOWN, false).toBool(); 0330 auto url= params.value(Core::keys::KEY_URL).toUrl(); 0331 auto text= params.value(Core::keys::KEY_TEXT).toString(); 0332 auto noteCtrl= new SharedNoteController(ownerId, localId, uuid); 0333 0334 if(!url.isEmpty()) 0335 { 0336 noteCtrl->setUrl(url); 0337 QFileInfo info(url.toLocalFile()); 0338 noteCtrl->setName(info.fileName()); 0339 b= url.toLocalFile().endsWith(".md"); 0340 } 0341 0342 noteCtrl->setHighligthedSyntax(b ? SharedNoteController::HighlightedSyntax::MarkDown : 0343 SharedNoteController::HighlightedSyntax::None); 0344 if(!text.isEmpty()) 0345 noteCtrl->setText(text); 0346 0347 return noteCtrl; 0348 } 0349 WebpageController* webPage(const QString& uuid, const QHash<QString, QVariant>& params) 0350 { 0351 QByteArray serializedData= params.value(Core::keys::KEY_SERIALIZED).toByteArray(); 0352 auto webCtrl= new WebpageController(uuid); 0353 0354 if(!serializedData.isEmpty()) 0355 IOHelper::readWebpageController(webCtrl, serializedData); 0356 else 0357 { 0358 webCtrl->setOwnerId(params.value(Core::keys::KEY_OWNERID).toString()); 0359 0360 if(params.contains(Core::keys::KEY_MODE)) 0361 { 0362 auto mode= static_cast<WebpageController::SharingMode>(params.value(Core::keys::KEY_MODE).toInt()); 0363 auto data= params.value(Core::keys::KEY_DATA).toString(); 0364 0365 if(mode == WebpageController::Url) 0366 webCtrl->setUrl(data); 0367 else if(mode == WebpageController::Html) 0368 webCtrl->setHtml(data); 0369 } 0370 if(params.contains(Core::keys::KEY_NAME)) 0371 { 0372 webCtrl->setName(params.value(Core::keys::KEY_NAME).toString()); 0373 } 0374 if(params.contains(Core::keys::KEY_STATE)) 0375 { 0376 webCtrl->setState(static_cast<WebpageController::State>(params.value(Core::keys::KEY_STATE).toInt())); 0377 } 0378 if(params.contains(Core::keys::KEY_PATH)) 0379 { 0380 auto url= params.value(Core::keys::KEY_PATH).toString(); 0381 webCtrl->setPageUrl(QUrl::fromUserInput(url)); 0382 } 0383 if(params.contains(Core::keys::KEY_URL)) 0384 { 0385 auto url= params.value(Core::keys::KEY_URL).toString(); 0386 webCtrl->setUrl(QUrl::fromUserInput(url)); 0387 } 0388 } 0389 0390 return webCtrl; 0391 } 0392 } // namespace 0393 0394 QString MediaFactory::m_localId= ""; 0395 0396 MediaControllerBase* MediaFactory::createLocalMedia(const QString& uuid, Core::ContentType type, 0397 const std::map<QString, QVariant>& map, const QColor& localColor, 0398 bool localIsGM) 0399 { 0400 QHash<QString, QVariant> params(map.begin(), map.end()); 0401 using C= Core::ContentType; 0402 MediaControllerBase* base= nullptr; 0403 0404 switch(type) 0405 { 0406 case C::VECTORIALMAP: 0407 base= vectorialMap(uuid, params); 0408 break; 0409 case C::PICTURE: 0410 // case C::ONLINEPICTURE: 0411 base= image(uuid, params); 0412 break; 0413 case C::NOTES: 0414 base= note(uuid, params); 0415 break; 0416 case C::CHARACTERSHEET: 0417 base= sheetCtrl(uuid, params); 0418 break; 0419 case C::SHAREDNOTE: 0420 base= sharedNote(uuid, params, m_localId); 0421 break; 0422 case C::PDF: 0423 base= pdf(uuid, params); 0424 break; 0425 case C::WEBVIEW: 0426 base= webPage(uuid, params); 0427 break; 0428 case C::MINDMAP: 0429 base= mindmap(uuid, params); 0430 break; 0431 default: 0432 break; 0433 } 0434 Q_ASSERT(base != nullptr); 0435 base->setLocalGM(localIsGM); 0436 base->setLocalId(m_localId); 0437 base->setOwnerId(m_localId); 0438 base->setLocalColor(localColor); 0439 return base; 0440 } 0441 0442 MediaControllerBase* MediaFactory::createRemoteMedia(Core::ContentType type, NetworkMessageReader* msg, 0443 const QColor& localColor, bool localIsGM) 0444 { 0445 using C= Core::ContentType; 0446 MediaControllerBase* base= nullptr; 0447 0448 QString uuid; 0449 0450 switch(type) 0451 { 0452 case C::VECTORIALMAP: 0453 { 0454 auto data= MessageHelper::readVectorialMapData(msg); 0455 uuid= data[Core::keys::KEY_UUID].toString(); 0456 base= vectorialMap(uuid, data, true); 0457 } 0458 break; 0459 case C::PICTURE: 0460 // case C::ONLINEPICTURE: 0461 { 0462 auto data= MessageHelper::readImageData(msg); 0463 uuid= data[Core::keys::KEY_UUID].toString(); 0464 base= image(uuid, data); 0465 } 0466 break; 0467 case C::MINDMAP: 0468 { 0469 auto data= MessageHelper::readMindMap(msg); 0470 uuid= data[Core::keys::KEY_UUID].toString(); 0471 base= mindmap(uuid, data); 0472 } 0473 break; 0474 case C::NOTES: 0475 { 0476 // base= note(uuid, map); 0477 } 0478 break; 0479 case C::CHARACTERSHEET: 0480 { 0481 auto data= MessageHelper::readCharacterSheet(msg); 0482 uuid= data[Core::keys::KEY_UUID].toString(); 0483 base= sheetCtrl(uuid, data); 0484 } 0485 break; 0486 case C::SHAREDNOTE: 0487 { 0488 auto data= MessageHelper::readSharedNoteData(msg); 0489 uuid= data[Core::keys::KEY_UUID].toString(); 0490 base= sharedNote(uuid, data, m_localId); 0491 } 0492 break; 0493 case C::PDF: 0494 { 0495 auto data= MessageHelper::readPdfData(msg); 0496 uuid= data[Core::keys::KEY_UUID].toString(); 0497 base= pdf(uuid, data); 0498 } 0499 break; 0500 case C::WEBVIEW: 0501 { 0502 auto data= MessageHelper::readWebPageData(msg); 0503 uuid= data[Core::keys::KEY_UUID].toString(); 0504 base= webPage(uuid, data); 0505 } 0506 break; 0507 default: 0508 break; 0509 } 0510 Q_ASSERT(base != nullptr); 0511 base->setRemote(true); 0512 base->setLocalGM(localIsGM); 0513 base->setLocalId(m_localId); 0514 base->setLocalColor(localColor); 0515 return base; 0516 } 0517 0518 void MediaFactory::setLocalId(const QString& id) 0519 { 0520 m_localId= id; 0521 } 0522 } // namespace Media