File indexing completed on 2024-05-05 05:40:27

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