File indexing completed on 2024-05-05 05:40:38
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 "worker/iohelper.h" 0021 0022 #include <QBuffer> 0023 #include <QCborValue> 0024 #include <QClipboard> 0025 #include <QColor> 0026 #include <QDataStream> 0027 #include <QDir> 0028 #include <QFile> 0029 #include <QGuiApplication> 0030 #include <QMimeData> 0031 #include <QMutex> 0032 #include <QMutexLocker> 0033 #include <QSaveFile> 0034 #include <QString> 0035 #include <QStyleFactory> 0036 #include <QVariant> 0037 #include <map> 0038 0039 #include "charactersheet/charactersheetmodel.h" 0040 #include "charactersheet/imagemodel.h" 0041 #include "charactersheet/worker/ioworker.h" 0042 #include "controller/audioplayercontroller.h" 0043 #include "controller/view_controller/charactersheetcontroller.h" 0044 #include "controller/view_controller/imagecontroller.h" 0045 #include "controller/view_controller/mediacontrollerbase.h" 0046 #include "controller/view_controller/mindmapcontroller.h" 0047 #include "controller/view_controller/mindmapcontrollerbase.h" 0048 #include "controller/view_controller/notecontroller.h" 0049 #include "controller/view_controller/pdfcontroller.h" 0050 #include "controller/view_controller/sharednotecontroller.h" 0051 #include "controller/view_controller/vectorialmapcontroller.h" 0052 #include "controller/view_controller/webpagecontroller.h" 0053 #include "data/character.h" 0054 #include "data/rolisteamtheme.h" 0055 #include "diceparser/dicealias.h" 0056 #include "media/mediatype.h" 0057 #include "mindmap/data/linkcontroller.h" 0058 #include "mindmap/data/mindnode.h" 0059 #include "mindmap/model/imagemodel.h" 0060 #include "mindmap/model/minditemmodel.h" 0061 #include "model/musicmodel.h" 0062 #include "model/nonplayablecharactermodel.h" 0063 #include "utils/iohelper.h" 0064 #include "worker/utilshelper.h" 0065 #include "worker/vectorialmapmessagehelper.h" 0066 0067 constexpr char const* k_language_dir_path{":/translations"}; 0068 constexpr char const* k_rolisteam_pattern{"rolisteam"}; 0069 constexpr char const* k_qt_pattern{"qt"}; 0070 constexpr char const* k_state_id{"id"}; 0071 constexpr char const* k_state_label{"label"}; 0072 constexpr char const* k_state_color{"color"}; 0073 constexpr char const* k_state_image{"image"}; 0074 0075 namespace 0076 { 0077 template <class T> 0078 T* convertField(CharacterField* field) 0079 { 0080 return dynamic_cast<T*>(field); 0081 } 0082 } // namespace 0083 0084 IOHelper::IOHelper() {} 0085 0086 /*bool IOHelper::loadToken(campaign::NonPlayableCharacter* character, const QString& root, 0087 std::map<QString, QVariant>& params) 0088 { 0089 bool ok; 0090 auto obj= loadJsonFileIntoObject(QString("%1/%2").arg(root, character->tokenPath()), ok); 0091 0092 if(!ok) 0093 return false; 0094 0095 params["side"]= obj[Core::JsonKey::JSON_TOKEN_SIZE].toDouble(); 0096 0097 0098 character->setName(obj[Core::JsonKey::JSON_TOKEN_SIZE].toString()); 0099 character->setColor(obj[Core::JsonKey::JSON_NPC_COLOR].toString()); 0100 character->setHealthPointsMax(obj[Core::JsonKey::JSON_NPC_MAXHP].toInt()); 0101 character->setHealthPointsMin(obj[Core::JsonKey::JSON_NPC_MINHP].toInt()); 0102 character->setHealthPointsCurrent(obj[Core::JsonKey::JSON_NPC_HP].toInt()); 0103 0104 character->setInitiativeScore(obj[Core::JsonKey::JSON_NPC_INITVALUE].toInt()); 0105 character->setInitCommand(obj[Core::JsonKey::JSON_NPC_INITCOMMAND].toString()); 0106 // character->setAvatarPath(obj["avatarUri"].toString()); 0107 0108 auto img= loadFile(QString("%1/%2").arg(root, obj[Core::JsonKey::JSON_NPC_AVATAR].toString())); 0109 0110 character->setAvatar(img); 0111 0112 auto actionArray= obj[Core::JsonKey::JSON_NPC_ACTIONS].toArray(); 0113 for(auto act : actionArray) 0114 { 0115 auto actObj= act.toObject(); 0116 auto action= new CharacterAction(); 0117 action->setName(actObj[Core::JsonKey::JSON_NPC_ACTION_NAME].toString()); 0118 action->setCommand(actObj[Core::JsonKey::JSON_NPC_ACTION_COMMAND].toString()); 0119 character->addAction(action); 0120 } 0121 0122 auto propertyArray= obj[Core::JsonKey::JSON_NPC_PROPERTIES].toArray(); 0123 for(auto pro : propertyArray) 0124 { 0125 auto proObj= pro.toObject(); 0126 auto property= new CharacterProperty(); 0127 property->setName(proObj[Core::JsonKey::JSON_NPC_PROPERTY_NAME].toString()); 0128 property->setValue(proObj[Core::JsonKey::JSON_NPC_PROPERTY_VALUE].toString()); 0129 character->addProperty(property); 0130 } 0131 0132 auto shapeArray= obj[Core::JsonKey::JSON_NPC_SHAPES].toArray(); 0133 for(auto sha : shapeArray) 0134 { 0135 auto objSha= sha.toObject(); 0136 auto shape= new CharacterShape(); 0137 shape->setName(objSha[Core::JsonKey::JSON_NPC_SHAPE_NAME].toString()); 0138 auto avatarData= QByteArray::fromBase64(objSha[Core::JsonKey::JSON_NPC_SHAPE_DATAIMG].toString().toUtf8()); 0139 QImage img= QImage::fromData(avatarData); 0140 shape->setImage(img); 0141 character->addShape(shape); 0142 } 0143 0144 params["character"]= QVariant::fromValue(character); 0145 return true; 0146 }*/ 0147 0148 QList<QUrl> IOHelper::readM3uPlayList(const QString& filepath) 0149 { 0150 QList<QUrl> res; 0151 QFile file(filepath); 0152 /// @todo make this job in thread. 0153 if(file.open(QIODevice::ReadOnly)) 0154 { 0155 QTextStream read(&file); 0156 QString line; 0157 while(!read.atEnd()) 0158 { 0159 line= read.readLine(); 0160 if(line.startsWith("#EXTINF", Qt::CaseSensitive) || line.isEmpty()) 0161 continue; 0162 0163 auto url= QUrl::fromUserInput(line); 0164 if(url.isValid()) 0165 res.append(url); 0166 } 0167 } 0168 return res; 0169 } 0170 0171 QJsonObject IOHelper::byteArrayToJsonObj(const QByteArray& data) 0172 { 0173 auto doc= QCborValue(data); 0174 return doc.toJsonValue().toObject(); 0175 } 0176 0177 QJsonObject IOHelper::textByteArrayToJsonObj(const QByteArray& data) 0178 { 0179 QJsonDocument doc= QJsonDocument::fromJson(data); 0180 return doc.object(); 0181 } 0182 0183 QJsonArray IOHelper::byteArrayToJsonArray(const QByteArray& data) 0184 { 0185 auto doc= QCborValue(data); 0186 return doc.toJsonValue().toArray(); 0187 } 0188 0189 QByteArray IOHelper::jsonObjectToByteArray(const QJsonObject& obj) 0190 { 0191 QJsonDocument doc; 0192 doc.setObject(obj); 0193 return doc.toJson(QJsonDocument::Indented); 0194 } 0195 0196 QJsonObject IOHelper::loadJsonFileIntoObject(const QString& filename, bool& ok) 0197 { 0198 QJsonDocument doc= QJsonDocument::fromJson(utils::IOHelper::loadFile(filename)); 0199 ok= !doc.isEmpty(); 0200 return doc.object(); 0201 } 0202 0203 QJsonArray IOHelper::loadJsonFileIntoArray(const QString& filename, bool& ok) 0204 { 0205 QJsonDocument doc= QJsonDocument::fromJson(utils::IOHelper::loadFile(filename)); 0206 ok= !doc.isEmpty(); 0207 return doc.array(); 0208 } 0209 0210 QJsonArray IOHelper::fetchLanguageModel() 0211 { 0212 QJsonArray array; 0213 QDir dir(k_language_dir_path); 0214 0215 auto list= dir.entryList(QStringList() << QStringLiteral("*.qm"), QDir::Files); 0216 0217 static QRegularExpression reQt(QStringLiteral("%1_(.*)\\.qm").arg(k_qt_pattern)); 0218 QHash<QString, QString> hash; 0219 for(const auto& info : qAsConst(list)) 0220 { 0221 auto match= reQt.match(info); 0222 if(match.hasMatch()) 0223 { 0224 hash.insert(match.captured(1), info); 0225 } 0226 } 0227 0228 static QRegularExpression reRolisteam(QStringLiteral("%1_(.*)\\.qm").arg(k_rolisteam_pattern)); 0229 for(auto info : qAsConst(list)) 0230 { 0231 auto match= reRolisteam.match(info); 0232 if(match.hasMatch()) 0233 { 0234 auto iso= match.captured(1); 0235 QJsonObject obj; 0236 QJsonArray paths; 0237 paths << QString("%1/%2").arg(k_language_dir_path, info); 0238 if(hash.contains(iso)) 0239 paths << QString("%1/%2").arg(k_language_dir_path, hash.value(iso)); 0240 // else 0241 // qWarning() << "No Qt translation for " << iso; 0242 0243 QLocale local(iso); 0244 0245 obj[Core::i18n::KEY_PATH]= paths; 0246 obj[Core::i18n::KEY_CODE]= iso; 0247 obj[Core::i18n::KEY_COMMONNAME]= QLocale::languageToString(local.language()); 0248 obj[Core::i18n::KEY_LANGNAME]= local.nativeLanguageName(); 0249 array.append(obj); 0250 } 0251 } 0252 0253 return array; 0254 } 0255 0256 void IOHelper::saveBase(MediaControllerBase* base, QDataStream& output) 0257 { 0258 if(!base) 0259 return; 0260 0261 output << base->contentType(); 0262 output << base->uuid(); 0263 output << base->url(); 0264 output << base->name(); 0265 output << base->ownerId(); 0266 } 0267 0268 void IOHelper::saveMediaBaseIntoJSon(MediaControllerBase* base, QJsonObject& obj) 0269 { 0270 if(!base) 0271 return; 0272 0273 obj[Core::jsonctrl::base::JSON_CONTENT_TYPE]= static_cast<int>(base->contentType()); 0274 obj[Core::jsonctrl::base::JSON_UUID]= base->uuid(); 0275 obj[Core::jsonctrl::base::JSON_PATH]= base->url().toString(); 0276 obj[Core::jsonctrl::base::JSON_NAME]= base->name(); 0277 obj[Core::jsonctrl::base::JSON_OWNERID]= base->ownerId(); 0278 } 0279 0280 void IOHelper::readBaseFromJson(MediaControllerBase* base, const QJsonObject& data) 0281 { 0282 if(!base) 0283 return; 0284 0285 base->setUuid(data[Core::jsonctrl::base::JSON_UUID].toString()); 0286 base->setUrl(QUrl::fromUserInput(data[Core::jsonctrl::base::JSON_PATH].toString())); 0287 base->setName(data[Core::jsonctrl::base::JSON_NAME].toString()); 0288 base->setOwnerId(data[Core::jsonctrl::base::JSON_OWNERID].toString()); 0289 } 0290 0291 QByteArray IOHelper::pixmapToData(const QPixmap& pix) 0292 { 0293 QByteArray bytes; 0294 QBuffer buffer(&bytes); 0295 buffer.open(QIODevice::WriteOnly); 0296 pix.save(&buffer, "PNG"); 0297 return bytes; 0298 } 0299 0300 QByteArray IOHelper::imageToData(const QImage& pix) 0301 { 0302 QByteArray bytes; 0303 QBuffer buffer(&bytes); 0304 buffer.open(QIODevice::WriteOnly); 0305 pix.save(&buffer, "PNG"); 0306 return bytes; 0307 } 0308 0309 const QMimeData* IOHelper::clipboardMineData() 0310 { 0311 auto clipboard= QGuiApplication::clipboard(); 0312 if(!clipboard) 0313 return {}; 0314 0315 return clipboard->mimeData(); 0316 } 0317 0318 QString IOHelper::htmlToTitle(const QMimeData& data, const QString& defaultName) 0319 { 0320 QString name= defaultName; 0321 if(data.hasHtml()) 0322 { 0323 QRegularExpression reg("src=\\\"([^\\s]+)\\\""); 0324 auto match= reg.match(data.html()); 0325 if(match.hasMatch()) 0326 { 0327 auto urlString= QUrl::fromUserInput(match.captured(1)); 0328 name= urlString.fileName(); 0329 } 0330 } 0331 return name; 0332 } 0333 0334 QImage IOHelper::readImageFromURL(const QUrl& url) 0335 { 0336 QImage img; 0337 if(url.isLocalFile()) 0338 { 0339 img= readImageFromFile(url.toLocalFile()); 0340 } 0341 return img; 0342 } 0343 0344 QImage IOHelper::readImageFromFile(const QString& url) 0345 { 0346 return QImage(url); 0347 } 0348 0349 QPixmap IOHelper::dataToPixmap(const QByteArray& data) 0350 { 0351 QPixmap pix; 0352 pix.loadFromData(data); 0353 return pix; 0354 } 0355 0356 QByteArray saveImage(ImageController* ctrl) 0357 { 0358 QByteArray data; 0359 if(!ctrl) 0360 return data; 0361 0362 QDataStream output(&data, QIODevice::WriteOnly); 0363 0364 IOHelper::saveBase(ctrl, output); 0365 0366 output << ctrl->fitWindow(); 0367 output << ctrl->data(); 0368 output << ctrl->zoomLevel(); 0369 0370 return data; 0371 } 0372 0373 QByteArray saveNotes(NoteController* ctrl) 0374 { 0375 QByteArray data; 0376 if(!ctrl) 0377 return data; 0378 QDataStream output(&data, QIODevice::WriteOnly); 0379 IOHelper::saveBase(ctrl, output); 0380 0381 output << ctrl->text(); 0382 return data; 0383 } 0384 0385 QByteArray saveCharacterSheet(CharacterSheetController* ctrl) 0386 { 0387 QByteArray data; 0388 if(!ctrl) 0389 return data; 0390 QDataStream output(&data, QIODevice::WriteOnly); 0391 IOHelper::saveBase(ctrl, output); 0392 0393 QJsonDocument doc; 0394 QJsonObject obj; //= //ctrl->rootObject(); 0395 auto model= ctrl->model(); 0396 QJsonObject dataObj; 0397 model->writeModel(dataObj); 0398 0399 obj["character"]= dataObj; 0400 0401 auto images= ctrl->imageModel(); 0402 0403 auto array= IOWorker::saveImageModel(images); 0404 0405 obj["images"]= array; 0406 0407 doc.setObject(obj); 0408 0409 QCborValue val(doc.toJson()); 0410 output << val; 0411 0412 return data; 0413 } 0414 0415 QByteArray saveSharedNote(SharedNoteController* ctrl) 0416 { 0417 QByteArray data; 0418 if(!ctrl) 0419 return data; 0420 QDataStream output(&data, QIODevice::WriteOnly); 0421 0422 IOHelper::saveBase(ctrl, output); 0423 0424 // output << ctrl->permission(); 0425 output << ctrl->text(); 0426 output << ctrl->highligthedSyntax(); 0427 output << ctrl->markdownVisible(); 0428 return data; 0429 } 0430 0431 QByteArray saveWebView(WebpageController* ctrl) 0432 { 0433 QByteArray data; 0434 if(!ctrl) 0435 return data; 0436 QDataStream output(&data, QIODevice::WriteOnly); 0437 0438 IOHelper::saveBase(ctrl, output); 0439 0440 output << ctrl->hideUrl(); 0441 output << ctrl->keepSharing(); 0442 output << ctrl->htmlSharing(); 0443 output << ctrl->urlSharing(); 0444 output << ctrl->html(); 0445 output << ctrl->url(); 0446 output << ctrl->pageUrl(); 0447 output << ctrl->state(); 0448 output << ctrl->sharingMode(); 0449 return data; 0450 } 0451 0452 QByteArray saveMindmap(MindMapController* ctrl) 0453 { 0454 if(!ctrl) 0455 return {}; 0456 0457 QJsonObject objCtrl; 0458 IOHelper::saveMediaBaseIntoJSon(ctrl, objCtrl); 0459 0460 objCtrl[Core::jsonctrl::Mindmap::JSON_CTRL_DEFAULT_INDEX_STYLE]= ctrl->defaultStyleIndex(); 0461 objCtrl[Core::jsonctrl::Mindmap::JSON_CTRL_SPACING]= ctrl->spacing(); 0462 objCtrl[Core::jsonctrl::Mindmap::JSON_CTRL_LINK_LABEL_VISIBILITY]= ctrl->linkLabelVisibility(); 0463 0464 auto updateMindItem= [](QJsonObject& obj, mindmap::MindItem* item) 0465 { 0466 namespace ujm= Core::jsonctrl::Mindmap; 0467 obj[ujm::JSON_MINDITEM_ID]= item->id(); 0468 obj[ujm::JSON_MINDITEM_TEXT]= item->text(); 0469 obj[ujm::JSON_MINDITEM_VISIBLE]= item->isVisible(); 0470 obj[ujm::JSON_MINDITEM_SELECTED]= item->selected(); 0471 obj[ujm::JSON_MINDITEM_TYPE]= item->type(); 0472 }; 0473 0474 auto updatePositionItem= [updateMindItem](QJsonObject& obj, mindmap::PositionedItem* pitem) 0475 { 0476 namespace ujm= Core::jsonctrl::Mindmap; 0477 updateMindItem(obj, pitem); 0478 obj[ujm::JSON_POSITIONED_POSITIONX]= pitem->position().x(); 0479 obj[ujm::JSON_POSITIONED_POSITIONY]= pitem->position().y(); 0480 obj[ujm::JSON_POSITIONED_CENTERX]= pitem->centerPoint().x(); 0481 obj[ujm::JSON_POSITIONED_CENTERY]= pitem->centerPoint().y(); 0482 obj[ujm::JSON_POSITIONED_WIDTH]= pitem->width(); 0483 obj[ujm::JSON_POSITIONED_HEIGHT]= pitem->height(); 0484 obj[ujm::JSON_POSITIONED_DRAGGED]= pitem->isDragged(); 0485 obj[ujm::JSON_POSITIONED_OPEN]= pitem->open(); 0486 obj[ujm::JSON_POSITIONED_LOCKED]= pitem->isLocked(); 0487 obj[ujm::JSON_POSITIONED_MASS]= pitem->mass(); 0488 }; 0489 0490 auto model= dynamic_cast<mindmap::MindItemModel*>(ctrl->itemModel()); 0491 auto nodes= model->items(mindmap::MindItem::NodeType); 0492 QJsonArray nodeArray; 0493 for(auto const& i : nodes) 0494 { 0495 auto node= dynamic_cast<mindmap::MindNode*>(i); 0496 if(!node) 0497 continue; 0498 QJsonObject obj; 0499 updatePositionItem(obj, node); 0500 obj[Core::jsonctrl::Mindmap::JSON_NODE_IMAGE]= node->imageUri(); 0501 obj[Core::jsonctrl::Mindmap::JSON_NODE_STYLE]= node->styleIndex(); 0502 obj[Core::jsonctrl::Mindmap::JSON_NODE_DESC]= node->description(); 0503 obj[Core::jsonctrl::Mindmap::JSON_NODE_TAGS]= QJsonArray::fromStringList(node->tags()); 0504 0505 nodeArray.append(obj); 0506 } 0507 0508 objCtrl[Core::jsonctrl::Mindmap::JSON_NODES]= nodeArray; 0509 0510 QJsonArray packagesArray; 0511 auto packagesItem= model->items(mindmap::MindItem::PackageType); 0512 for(auto const& i : packagesItem) 0513 { 0514 0515 auto pack= dynamic_cast<mindmap::PackageNode*>(i); 0516 if(!pack) 0517 continue; 0518 QJsonObject obj; 0519 updatePositionItem(obj, pack); 0520 obj[Core::jsonctrl::Mindmap::JSON_PACK_TITLE]= pack->title(); 0521 obj[Core::jsonctrl::Mindmap::JSON_PACK_MINMARGE]= pack->minimumMargin(); 0522 0523 obj[Core::jsonctrl::Mindmap::JSON_PACK_INTERNAL_CHILDREN]= QJsonArray::fromStringList(pack->childrenId()); 0524 packagesArray.append(obj); 0525 } 0526 objCtrl[Core::jsonctrl::Mindmap::JSON_PACK_PACKAGES]= packagesArray; 0527 0528 QJsonArray linkArray; 0529 auto links= model->items(mindmap::MindItem::LinkType); 0530 for(auto const& i : links) 0531 { 0532 0533 auto link= dynamic_cast<mindmap::LinkController*>(i); 0534 if(!link) 0535 continue; 0536 0537 QJsonObject obj; 0538 updateMindItem(obj, link); 0539 auto start= link->start(); 0540 obj[Core::jsonctrl::Mindmap::JSON_LINK_IDSTART]= start ? start->id() : QString(); 0541 auto end= link->end(); 0542 obj[Core::jsonctrl::Mindmap::JSON_LINK_IDEND]= end ? end->id() : QString(); 0543 obj[Core::jsonctrl::Mindmap::JSON_LINK_DIRECTION]= static_cast<int>(link->direction()); 0544 linkArray.append(obj); 0545 } 0546 objCtrl[Core::jsonctrl::Mindmap::JSON_LINKS]= linkArray; 0547 0548 auto imgModel= ctrl->imgModel(); 0549 auto imgs= imgModel->imageInfos(); 0550 QJsonArray imgArray; 0551 for(const auto& img : imgs) 0552 { 0553 QJsonObject obj; 0554 obj[Core::jsonctrl::Mindmap::JSON_IMG_ID]= img.m_id; 0555 obj[Core::jsonctrl::Mindmap::JSON_IMG_DATA]= QString::fromUtf8(IOHelper::pixmapToData(img.m_pixmap).toBase64()); 0556 obj[Core::jsonctrl::Mindmap::JSON_IMG_URL]= img.m_url.toString(); 0557 imgArray.append(obj); 0558 } 0559 objCtrl[Core::jsonctrl::Mindmap::JSON_IMGS]= imgArray; 0560 0561 return IOHelper::jsonObjectToByteArray(objCtrl); 0562 } 0563 0564 QByteArray savePdfView(PdfController* ctrl) 0565 { 0566 QByteArray data; 0567 if(!ctrl) 0568 return data; 0569 QDataStream output(&data, QIODevice::WriteOnly); 0570 0571 IOHelper::saveBase(ctrl, output); 0572 0573 output << ctrl->data(); 0574 return data; 0575 } 0576 0577 QByteArray IOHelper::saveController(MediaControllerBase* media) 0578 { 0579 QByteArray data; 0580 0581 if(!media) 0582 return data; 0583 0584 auto uri= media->contentType(); 0585 switch(uri) 0586 { 0587 case Core::ContentType::VECTORIALMAP: 0588 data= VectorialMapMessageHelper::saveVectorialMap(dynamic_cast<VectorialMapController*>(media)); 0589 break; 0590 case Core::ContentType::PICTURE: 0591 data= saveImage(dynamic_cast<ImageController*>(media)); 0592 break; 0593 case Core::ContentType::NOTES: 0594 data= saveNotes(dynamic_cast<NoteController*>(media)); 0595 break; 0596 case Core::ContentType::CHARACTERSHEET: 0597 data= saveCharacterSheet(dynamic_cast<CharacterSheetController*>(media)); 0598 break; 0599 case Core::ContentType::SHAREDNOTE: 0600 data= saveSharedNote(dynamic_cast<SharedNoteController*>(media)); 0601 break; 0602 case Core::ContentType::WEBVIEW: 0603 data= saveWebView(dynamic_cast<WebpageController*>(media)); 0604 break; 0605 case Core::ContentType::MINDMAP: 0606 data= saveMindmap(dynamic_cast<MindMapController*>(media)); 0607 break; 0608 case Core::ContentType::PDF: 0609 data= savePdfView(dynamic_cast<PdfController*>(media)); 0610 break; 0611 default: 0612 break; 0613 } 0614 0615 return data; 0616 } 0617 0618 /*MediaControllerBase* IOHelper::loadController(const QByteArray& data) 0619 { 0620 QDataStream input(data); 0621 Core::ContentType type; 0622 input >> type; 0623 0624 MediaControllerBase* value= nullptr; 0625 switch(type) 0626 { 0627 case Core::ContentType::VECTORIALMAP: 0628 { 0629 auto ctrl= new VectorialMapController(); 0630 value= ctrl; 0631 VectorialMapMessageHelper::readVectorialMapController(ctrl, data); 0632 } 0633 break; 0634 case Core::ContentType::PICTURE: 0635 { 0636 auto ctrl= new ImageController(); 0637 value= ctrl; 0638 readImageController(ctrl, data); 0639 } 0640 break; 0641 case Core::ContentType::NOTES: 0642 { 0643 auto ctrl= new NoteController(); 0644 value= ctrl; 0645 readNoteController(ctrl, data); 0646 } 0647 break; 0648 case Core::ContentType::CHARACTERSHEET: 0649 { 0650 auto ctrl= new CharacterSheetController(); 0651 value= ctrl; 0652 readCharacterSheetController(ctrl, data); 0653 } 0654 break; 0655 case Core::ContentType::SHAREDNOTE: 0656 { 0657 auto ctrl= new SharedNoteController(); 0658 value= ctrl; 0659 readSharedNoteController(ctrl, data); 0660 } 0661 break; 0662 case Core::ContentType::WEBVIEW: 0663 { 0664 auto ctrl= new WebpageController(); 0665 value= ctrl; 0666 readWebpageController(ctrl, data); 0667 } 0668 break; 0669 case Core::ContentType::MINDMAP: 0670 { 0671 auto ctrl= new MindMapController({}); 0672 value= ctrl; 0673 readMindmapController(ctrl, data); 0674 } 0675 case Core::ContentType::PDF: 0676 { 0677 auto ctrl= new PdfController(); 0678 value= ctrl; 0679 readPdfController(ctrl, data); 0680 } 0681 break; 0682 default: 0683 Q_ASSERT(false); // No valid contentType 0684 break; 0685 } 0686 0687 return value; 0688 }*/ 0689 0690 void IOHelper::writePlaylist(const QString& path, const QList<QUrl>& urls) 0691 { 0692 QByteArray array; 0693 QTextStream stream(array); 0694 for(auto const& url : urls) 0695 { 0696 stream << url.toString(); 0697 } 0698 0699 utils::IOHelper::writeFile(path, array); 0700 } 0701 0702 QJsonObject IOHelper::saveAudioPlayerController(AudioPlayerController* controller) 0703 { 0704 QJsonObject obj; 0705 if(!controller) 0706 return obj; 0707 obj[Core::jsonctrl::Audio::JSON_AUDIO_VOLUME]= static_cast<int>(controller->volume()); 0708 obj[Core::jsonctrl::Audio::JSON_AUDIO_VISIBLE]= controller->visible(); 0709 obj[Core::jsonctrl::Audio::JSON_PLAYING_MODE]= controller->mode(); 0710 0711 auto m= controller->model()->urls(); 0712 QJsonArray array; 0713 std::transform(std::begin(m), std::end(m), std::back_inserter(array), 0714 [](const QUrl& url) { return url.toString(); }); 0715 obj[Core::jsonctrl::Audio::JSON_AUDIO_URLS]= array; 0716 0717 return obj; 0718 } 0719 0720 void IOHelper::fetchAudioPlayerController(AudioPlayerController* controller, const QJsonObject& obj) 0721 { 0722 if(!controller) 0723 return; 0724 0725 controller->setVolume(static_cast<uint>(obj[Core::jsonctrl::Audio::JSON_AUDIO_VOLUME].toInt())); 0726 controller->setVisible(obj[Core::jsonctrl::Audio::JSON_AUDIO_VISIBLE].toBool()); 0727 controller->setPlayingMode( 0728 static_cast<AudioPlayerController::PlayingMode>(obj[Core::jsonctrl::Audio::JSON_PLAYING_MODE].toInt())); 0729 0730 auto urlArray= obj[Core::jsonctrl::Audio::JSON_AUDIO_URLS].toArray(); 0731 QList<QUrl> urls; 0732 std::transform(std::begin(urlArray), std::end(urlArray), std::back_inserter(urls), 0733 [](const QJsonValueRef& ref) { return QUrl::fromUserInput(ref.toString()); }); 0734 0735 controller->clear(); 0736 controller->addSong(urls); 0737 } 0738 0739 void IOHelper::readBase(MediaControllerBase* base, QDataStream& input) 0740 { 0741 if(!base) 0742 return; 0743 0744 Core::ContentType type; 0745 input >> type; 0746 QString uuid; 0747 input >> uuid; 0748 QUrl path; 0749 input >> path; 0750 0751 QString name; 0752 input >> name; 0753 0754 QString ownerId; 0755 input >> ownerId; 0756 0757 base->setUuid(uuid); 0758 base->setName(name); 0759 base->setUrl(path); 0760 base->setOwnerId(ownerId); 0761 } 0762 0763 void IOHelper::readCharacterSheetController(CharacterSheetController* ctrl, const QByteArray& array) 0764 { 0765 if(!ctrl || array.isEmpty()) 0766 return; 0767 0768 qDebug() << "array" << array.size(); 0769 auto data= IOHelper::textByteArrayToJsonObj(array); 0770 qDebug() << "\n\n\n\n\ndata" << data.size(); 0771 IOHelper::readBaseFromJson(ctrl, data); 0772 0773 // auto charactersData= data[Core::jsonctrl::sheet::JSON_CHARACTER_CONTENT].toArray(); 0774 auto images= data[Core::jsonctrl::sheet::JSON_IMAGES_CONTENT].toArray(); 0775 ctrl->setQmlCode(data[Core::jsonctrl::sheet::JSON_QML_CONTENT].toString()); 0776 0777 auto model= ctrl->model(); 0778 model->readModel(data, true); 0779 auto imagesModel= ctrl->imageModel(); 0780 IOWorker::fetchImageModel(imagesModel, images); 0781 } 0782 0783 QString IOHelper::copyImageFileIntoCampaign(const QString& path, const QString& dest) 0784 { 0785 if(path.startsWith(dest)) 0786 return path; 0787 else 0788 return utils::IOHelper::copyFile(path, dest); 0789 } 0790 0791 Character* IOHelper::dupplicateCharacter(const Character *obj) 0792 { 0793 auto res = new Character(); 0794 0795 res->setHealthPointsCurrent(obj->getHealthPointsCurrent()); 0796 res->setHealthPointsMax(obj->getHealthPointsMax()); 0797 res->setHealthPointsMin(obj->getHealthPointsMin()); 0798 res->setNpc(obj->isNpc()); 0799 res->setInitCommand(obj->initCommand()); 0800 res->setInitiativeScore(obj->getInitiativeScore()); 0801 res->setImageProvider(obj->getImageProvider()); 0802 res->setCurrentShape(obj->currentShape()); 0803 res->setLifeColor(obj->getLifeColor()); 0804 res->setStateId(obj->stateId()); 0805 res->setDistancePerTurn(obj->getDistancePerTurn()); 0806 res->setNumber(obj->number()); 0807 res->setName(obj->name()); 0808 res->setUuid(obj->uuid()); 0809 res->setColor(obj->getColor()); 0810 res->setSheet(obj->getSheet()); 0811 res->defineActionList(obj->actionList()); 0812 res->defineShapeList(obj->shapeList()); 0813 res->definePropertiesList(obj->propertiesList()); 0814 res->setAvatar(obj->avatar()); 0815 0816 return res; 0817 } 0818 0819 void IOHelper::readPdfController(PdfController* ctrl, const QByteArray& array) 0820 { 0821 if(!ctrl || array.isEmpty()) 0822 return; 0823 auto data= array; 0824 QDataStream input(&data, QIODevice::ReadOnly); 0825 0826 IOHelper::readBase(ctrl, input); 0827 0828 QByteArray pdfData; 0829 input >> pdfData; 0830 if(!pdfData.isEmpty()) 0831 ctrl->setData(pdfData); 0832 } 0833 0834 void IOHelper::readImageController(ImageController* ctrl, const QByteArray& array) 0835 { 0836 if(!ctrl || array.isEmpty()) 0837 return; 0838 0839 auto data= array; 0840 QDataStream input(&data, QIODevice::ReadOnly); 0841 0842 IOHelper::readBase(ctrl, input); 0843 0844 bool b; 0845 input >> b; 0846 0847 QByteArray dataByte; 0848 input >> dataByte; 0849 0850 qreal zoom; 0851 input >> zoom; 0852 0853 ctrl->setFitWindow(b); 0854 ctrl->setData(dataByte); 0855 ctrl->setZoomLevel(zoom); 0856 } 0857 0858 void IOHelper::readWebpageController(WebpageController* ctrl, const QByteArray& array) 0859 { 0860 if(!ctrl || array.isEmpty()) 0861 return; 0862 auto data= array; 0863 QDataStream input(&data, QIODevice::ReadOnly); 0864 0865 IOHelper::readBase(ctrl, input); 0866 0867 bool hide; 0868 input >> hide; 0869 0870 bool keepSharing; 0871 input >> keepSharing; 0872 0873 bool htmlSharing; 0874 input >> htmlSharing; 0875 0876 bool urlSharing; 0877 input >> urlSharing; 0878 0879 QString html; 0880 input >> html; 0881 0882 QUrl url; 0883 input >> url; 0884 0885 QUrl pageUrl; 0886 input >> pageUrl; 0887 0888 WebpageController::State state; 0889 input >> state; 0890 0891 WebpageController::SharingMode mode; 0892 input >> mode; 0893 0894 ctrl->setHideUrl(hide); 0895 ctrl->setKeepSharing(keepSharing); 0896 ctrl->setHtmlSharing(htmlSharing); 0897 ctrl->setUrlSharing(urlSharing); 0898 ctrl->setState(state); 0899 ctrl->setSharingMode(mode); 0900 ctrl->setPageUrl(pageUrl); 0901 ctrl->setUrl(url); 0902 } 0903 QJsonObject IOHelper::readMindmapController(MindMapController* ctrl, const QByteArray& array) 0904 { 0905 if(!ctrl || array.isEmpty()) 0906 return {}; 0907 0908 auto objCtrl= IOHelper::textByteArrayToJsonObj(array); 0909 0910 IOHelper::readMindmapControllerBase(ctrl, objCtrl); 0911 0912 return objCtrl; 0913 } 0914 void IOHelper::readMindmapControllerBase(mindmap::MindMapControllerBase* ctrl, const QJsonObject& objCtrl) 0915 { 0916 if(!ctrl) 0917 return; 0918 0919 IOHelper::readBaseFromJson(ctrl, objCtrl); 0920 0921 ctrl->setDefaultStyleIndex(objCtrl[Core::jsonctrl::Mindmap::JSON_CTRL_DEFAULT_INDEX_STYLE].toInt()); 0922 ctrl->setSpacing(objCtrl[Core::jsonctrl::Mindmap::JSON_CTRL_SPACING].toBool()); 0923 ctrl->setLinkLabelVisibility(objCtrl[Core::jsonctrl::Mindmap::JSON_CTRL_LINK_LABEL_VISIBILITY].toBool()); 0924 0925 auto imgs= objCtrl[Core::jsonctrl::Mindmap::JSON_IMGS].toArray(); 0926 auto imgModel= ctrl->imgModel(); 0927 for(auto const& imgRef : imgs) 0928 { 0929 auto img= imgRef.toObject(); 0930 auto pixmap= IOHelper::dataToPixmap( 0931 QByteArray::fromBase64(img[Core::jsonctrl::Mindmap::JSON_IMG_DATA].toString().toUtf8())); 0932 auto id= img[Core::jsonctrl::Mindmap::JSON_IMG_ID].toString(); 0933 auto url= QUrl::fromUserInput(img[Core::jsonctrl::Mindmap::JSON_IMG_URL].toString()); 0934 imgModel->insertPixmap(id, pixmap, url); 0935 } 0936 0937 auto updateMindItem= [](const QJsonObject& obj, mindmap::MindItem* item) 0938 { 0939 namespace ujm= Core::jsonctrl::Mindmap; 0940 item->setId(obj[ujm::JSON_MINDITEM_ID].toString()); 0941 item->setText(obj[ujm::JSON_MINDITEM_TEXT].toString()); 0942 item->setVisible(obj[ujm::JSON_MINDITEM_VISIBLE].toBool()); 0943 item->setSelected(false); // obj[ujm::JSON_MINDITEM_SELECTED].toBool() 0944 }; 0945 0946 auto updatePositionItem= [updateMindItem](const QJsonObject& obj, mindmap::PositionedItem* pitem) 0947 { 0948 namespace ujm= Core::jsonctrl::Mindmap; 0949 updateMindItem(obj, pitem); 0950 pitem->setPosition( 0951 {obj[ujm::JSON_POSITIONED_POSITIONX].toDouble(), obj[ujm::JSON_POSITIONED_POSITIONY].toDouble()}); 0952 0953 qDebug() << "position" << pitem->position(); 0954 0955 pitem->setWidth(obj[ujm::JSON_POSITIONED_WIDTH].toDouble()); 0956 pitem->setHeight(obj[ujm::JSON_POSITIONED_HEIGHT].toDouble()); 0957 pitem->setDragged(obj[ujm::JSON_POSITIONED_DRAGGED].toBool()); 0958 pitem->setOpen(obj[ujm::JSON_POSITIONED_OPEN].toBool()); 0959 pitem->setLocked(obj[ujm::JSON_POSITIONED_LOCKED].toBool()); 0960 pitem->setMass(obj[ujm::JSON_POSITIONED_MASS].toInt()); 0961 }; 0962 0963 auto nodes= objCtrl[Core::jsonctrl::Mindmap::JSON_NODES].toArray(); 0964 auto model= dynamic_cast<mindmap::MindItemModel*>(ctrl->itemModel()); 0965 for(auto const& nodeRef : nodes) 0966 { 0967 auto nodeJson= nodeRef.toObject(); 0968 auto node= new mindmap::MindNode(); 0969 updatePositionItem(nodeJson, node); 0970 0971 node->setImageUri(nodeJson[Core::jsonctrl::Mindmap::JSON_NODE_IMAGE].toString()); 0972 node->setStyleIndex(nodeJson[Core::jsonctrl::Mindmap::JSON_NODE_STYLE].toInt()); 0973 node->setDescription(nodeJson[Core::jsonctrl::Mindmap::JSON_NODE_DESC].toString()); 0974 auto tagArray= nodeJson[Core::jsonctrl::Mindmap::JSON_NODE_TAGS].toArray(); 0975 QStringList tags; 0976 std::transform(std::begin(tagArray), std::end(tagArray), std::back_inserter(tags), 0977 [](const QJsonValue& val) { return val.toString(); }); 0978 node->setTags(tags); 0979 0980 model->appendItem({node}); 0981 } 0982 0983 auto packages= objCtrl[Core::jsonctrl::Mindmap::JSON_PACK_PACKAGES].toArray(); 0984 for(auto const& packRef : packages) 0985 { 0986 auto pack= packRef.toObject(); 0987 auto node= new mindmap::PackageNode(); 0988 updatePositionItem(pack, node); 0989 0990 node->setTitle(pack[Core::jsonctrl::Mindmap::JSON_PACK_TITLE].toString()); 0991 node->setMinimumMargin(pack[Core::jsonctrl::Mindmap::JSON_PACK_MINMARGE].toInt()); 0992 0993 auto childArray= pack[Core::jsonctrl::Mindmap::JSON_PACK_INTERNAL_CHILDREN].toArray(); 0994 std::for_each(std::begin(childArray), std::end(childArray), 0995 [node, model](const QJsonValue& val) { node->addChild(model->positionItem(val.toString())); }); 0996 0997 model->appendItem({node}); 0998 } 0999 1000 auto linkArrays= objCtrl[Core::jsonctrl::Mindmap::JSON_LINKS].toArray(); 1001 for(auto const& linkRef : linkArrays) 1002 { 1003 auto obj= linkRef.toObject(); 1004 auto link= new mindmap::LinkController(); 1005 updateMindItem(obj, link); 1006 1007 auto startId= obj[Core::jsonctrl::Mindmap::JSON_LINK_IDSTART].toString(); 1008 auto endId= obj[Core::jsonctrl::Mindmap::JSON_LINK_IDEND].toString(); 1009 auto start= model->positionItem(startId); 1010 auto end= model->positionItem(endId); 1011 1012 link->setStart(start); 1013 link->setEnd(end); 1014 link->setDirection( 1015 static_cast<mindmap::LinkController::Direction>(obj[Core::jsonctrl::Mindmap::JSON_LINK_DIRECTION].toInt())); 1016 model->appendItem({link}); 1017 } 1018 1019 // TODO read data to define mindmapcontroller. 1020 } 1021 1022 bool IOHelper::mergePlayList(const QString& source, const QString& dest) 1023 { 1024 bool ok; 1025 auto sourceJson= loadJsonFileIntoObject(source, ok); 1026 if(!ok) 1027 return ok; 1028 auto destJson= loadJsonFileIntoObject(dest, ok); 1029 1030 if(!ok) 1031 { 1032 utils::IOHelper::copyFile(source, dest); 1033 return true; 1034 } 1035 1036 auto arraySrc= sourceJson[Core::jsonctrl::Audio::JSON_AUDIO_URLS].toArray(); 1037 auto arrayDst= destJson[Core::jsonctrl::Audio::JSON_AUDIO_URLS].toArray(); 1038 1039 arrayDst.append(arraySrc); 1040 destJson[Core::jsonctrl::Audio::JSON_AUDIO_URLS]= arrayDst; 1041 1042 writeJsonObjectIntoFile(dest, destJson); 1043 return true; 1044 } 1045 1046 QStringList IOHelper::mediaList(const QString& source, Core::MediaType type) 1047 { 1048 QDir dir(source); 1049 return dir.entryList(helper::utils::extentionPerType(helper::utils::mediaTypeToContentType(type), false, true), 1050 QDir::Files | QDir::Readable); 1051 } 1052 1053 bool IOHelper::copyArrayModelAndFile(const QString& source, const QString& sourceDir, const QString& dest, 1054 const QString& destDir) 1055 { 1056 bool ok; 1057 auto sourceJson= loadJsonFileIntoArray(source, ok); 1058 if(!ok) 1059 return false; // nothing to do 1060 auto destJson= loadJsonFileIntoArray(dest, ok); 1061 1062 if(!ok) 1063 { 1064 utils::IOHelper::copyFile(source, dest); 1065 } 1066 1067 destJson.append(sourceJson); 1068 writeJsonArrayIntoFile(dest, destJson); 1069 1070 // Copy npcs files 1071 QDir dir(sourceDir); 1072 auto fileList= dir.entryList(QDir::Files | QDir::Readable); 1073 for(auto const& file : fileList) 1074 { 1075 utils::IOHelper::copyFile(QString("%1/%2").arg(sourceDir, file), QString("%1/%2").arg(destDir, file)); 1076 } 1077 return true; 1078 } 1079 1080 /*bool IOHelper::copyMedia(const QString &source, const QString &dest, Core::MediaType type) 1081 { 1082 1083 }*/ 1084 1085 /*QString IOHelper::shortNameFromPath(const QString& path) 1086 { 1087 QFileInfo info(path); 1088 return info.baseName(); 1089 } 1090 1091 QString IOHelper::shortNameFromUrl(const QUrl& url) 1092 { 1093 return shortNameFromPath(url.fileName()); 1094 } 1095 1096 QString IOHelper::absoluteToRelative(const QString& absolute, const QString& root) 1097 { 1098 QDir dir(root); 1099 QFileInfo path(absolute); 1100 if(!path.isAbsolute()) 1101 return absolute; 1102 1103 return dir.relativeFilePath(absolute); 1104 }*/ 1105 1106 QJsonObject IOHelper::stateToJSonObject(CharacterState* state, const QString& root) 1107 { 1108 QJsonObject stateJson; 1109 1110 stateJson[k_state_id]= state->id(); 1111 stateJson[k_state_label]= state->label(); 1112 stateJson[k_state_color]= state->color().name(); 1113 auto pathImg= state->imagePath(); 1114 pathImg= utils::IOHelper::absoluteToRelative(pathImg, root); 1115 stateJson[k_state_image]= pathImg; 1116 return stateJson; 1117 } 1118 1119 QJsonObject IOHelper::npcToJsonObject(const campaign::NonPlayableCharacter* npc, const QString& destination) 1120 { 1121 if(nullptr == npc) 1122 return {}; 1123 QJsonObject obj; 1124 1125 obj[Core::JsonKey::JSON_NPC_ID]= npc->uuid(); 1126 obj[Core::JsonKey::JSON_NPC_NAME]= npc->name(); 1127 obj[Core::JsonKey::JSON_NPC_AVATAR]= utils::IOHelper::absoluteToRelative(npc->avatarPath(), destination); 1128 obj[Core::JsonKey::JSON_NPC_TAGS]= QJsonArray::fromStringList(npc->tags()); 1129 obj[Core::JsonKey::JSON_NPC_DESCRIPTION]= npc->description(); 1130 1131 obj[Core::JsonKey::JSON_NPC_INITCOMMAND]= npc->initCommand(); 1132 obj[Core::JsonKey::JSON_NPC_INITVALUE]= npc->getInitiativeScore(); 1133 obj[Core::JsonKey::JSON_NPC_COLOR]= npc->getColor().name(); 1134 obj[Core::JsonKey::JSON_NPC_HP]= npc->getHealthPointsCurrent(); 1135 obj[Core::JsonKey::JSON_NPC_MAXHP]= npc->getHealthPointsMax(); 1136 obj[Core::JsonKey::JSON_NPC_MINHP]= npc->getHealthPointsMin(); 1137 obj[Core::JsonKey::JSON_NPC_DIST_PER_TURN]= npc->getDistancePerTurn(); 1138 obj[Core::JsonKey::JSON_NPC_STATEID]= npc->stateId(); 1139 obj[Core::JsonKey::JSON_NPC_LIFECOLOR]= npc->getLifeColor().name(); 1140 obj[Core::JsonKey::JSON_TOKEN_SIZE]= npc->size(); 1141 1142 QJsonArray actionArray; 1143 auto actionList= npc->actionList(); 1144 for(auto act : actionList) 1145 { 1146 if(act == nullptr) 1147 continue; 1148 QJsonObject actJson; 1149 actJson[Core::JsonKey::JSON_NPC_ACTION_NAME]= act->name(); 1150 actJson[Core::JsonKey::JSON_NPC_ACTION_COMMAND]= act->command(); 1151 actionArray.append(actJson); 1152 } 1153 obj[Core::JsonKey::JSON_NPC_ACTIONS]= actionArray; 1154 1155 QJsonArray propertyArray; 1156 auto properties= npc->propertiesList(); 1157 for(auto property : properties) 1158 { 1159 if(property == nullptr) 1160 continue; 1161 QJsonObject actJson; 1162 actJson[Core::JsonKey::JSON_NPC_PROPERTY_NAME]= property->name(); 1163 actJson[Core::JsonKey::JSON_NPC_PROPERTY_VALUE]= property->value(); 1164 propertyArray.append(actJson); 1165 } 1166 obj[Core::JsonKey::JSON_NPC_PROPERTIES]= propertyArray; 1167 1168 QJsonArray shapeArray; 1169 auto shapes= npc->shapeList(); 1170 for(auto shape : shapes) 1171 { 1172 if(shape == nullptr) 1173 continue; 1174 QJsonObject actJson; 1175 actJson[Core::JsonKey::JSON_NPC_SHAPE_NAME]= shape->name(); 1176 1177 auto data= IOHelper::imageToData(shape->image()); 1178 1179 actJson[Core::JsonKey::JSON_NPC_SHAPE_DATAIMG]= QString::fromUtf8(data.toBase64()); 1180 shapeArray.append(actJson); 1181 } 1182 obj[Core::JsonKey::JSON_NPC_SHAPES]= shapeArray; 1183 1184 return obj; 1185 } 1186 1187 campaign::NonPlayableCharacter* IOHelper::jsonObjectToNpc(const QJsonObject& obj, const QString& rootDir) 1188 { 1189 auto npc= new campaign::NonPlayableCharacter(); 1190 auto uuid= obj[Core::JsonKey::JSON_NPC_ID].toString(); 1191 auto desc= obj[Core::JsonKey::JSON_NPC_DESCRIPTION].toString(); 1192 auto name= obj[Core::JsonKey::JSON_NPC_NAME].toString(); 1193 auto avatar= obj[Core::JsonKey::JSON_NPC_AVATAR].toString(); 1194 auto stateid= obj[Core::JsonKey::JSON_NPC_STATEID].toString(); 1195 auto tags= obj[Core::JsonKey::JSON_NPC_TAGS].toArray(); 1196 auto tokenPath= obj[Core::JsonKey::JSON_NPC_TOKEN].toString(); 1197 QStringList list; 1198 std::transform(std::begin(tags), std::end(tags), std::back_inserter(list), 1199 [](const QJsonValue& val) { return val.toString(); }); 1200 1201 npc->setUuid(uuid); 1202 npc->setName(name); 1203 npc->setDescription(desc); 1204 npc->setStateId(stateid); 1205 npc->setAvatar(utils::IOHelper::loadFile(QString("%1/%2").arg(rootDir, avatar))); 1206 npc->setAvatarPath(avatar); 1207 npc->setTags(list); 1208 1209 npc->setSize(obj[Core::JsonKey::JSON_TOKEN_SIZE].toInt()); 1210 npc->setColor(obj[Core::JsonKey::JSON_NPC_COLOR].toString()); 1211 npc->setHealthPointsMax(obj[Core::JsonKey::JSON_NPC_MAXHP].toInt()); 1212 npc->setHealthPointsMin(obj[Core::JsonKey::JSON_NPC_MINHP].toInt()); 1213 npc->setHealthPointsCurrent(obj[Core::JsonKey::JSON_NPC_HP].toInt()); 1214 1215 npc->setInitiativeScore(obj[Core::JsonKey::JSON_NPC_INITVALUE].toInt()); 1216 npc->setInitCommand(obj[Core::JsonKey::JSON_NPC_INITCOMMAND].toString()); 1217 1218 auto actionArray= obj[Core::JsonKey::JSON_NPC_ACTIONS].toArray(); 1219 for(auto act : actionArray) 1220 { 1221 auto actObj= act.toObject(); 1222 auto action= new CharacterAction(); 1223 action->setName(actObj[Core::JsonKey::JSON_NPC_ACTION_NAME].toString()); 1224 action->setCommand(actObj[Core::JsonKey::JSON_NPC_ACTION_COMMAND].toString()); 1225 npc->addAction(action); 1226 } 1227 1228 auto propertyArray= obj[Core::JsonKey::JSON_NPC_PROPERTIES].toArray(); 1229 for(auto pro : propertyArray) 1230 { 1231 auto proObj= pro.toObject(); 1232 auto property= new CharacterProperty(); 1233 property->setName(proObj[Core::JsonKey::JSON_NPC_PROPERTY_NAME].toString()); 1234 property->setValue(proObj[Core::JsonKey::JSON_NPC_PROPERTY_VALUE].toString()); 1235 npc->addProperty(property); 1236 } 1237 1238 auto shapeArray= obj[Core::JsonKey::JSON_NPC_SHAPES].toArray(); 1239 for(auto sha : shapeArray) 1240 { 1241 auto objSha= sha.toObject(); 1242 auto shape= new CharacterShape(); 1243 shape->setName(objSha[Core::JsonKey::JSON_NPC_SHAPE_NAME].toString()); 1244 auto avatarData= QByteArray::fromBase64(objSha[Core::JsonKey::JSON_NPC_SHAPE_DATAIMG].toString().toUtf8()); 1245 QImage img= QImage::fromData(avatarData); 1246 shape->setImage(img); 1247 npc->addShape(shape); 1248 } 1249 1250 return npc; 1251 } 1252 1253 QJsonObject IOHelper::diceAliasToJSonObject(DiceAlias* alias) 1254 { 1255 QJsonObject aliasJson; 1256 aliasJson[Core::DiceAlias::k_dice_command]= alias->command(); 1257 aliasJson[Core::DiceAlias::k_dice_comment]= alias->comment(); 1258 aliasJson[Core::DiceAlias::k_dice_pattern]= alias->pattern(); 1259 aliasJson[Core::DiceAlias::k_dice_enabled]= alias->isEnable(); 1260 aliasJson[Core::DiceAlias::k_dice_replacement]= alias->isReplace(); 1261 return aliasJson; 1262 } 1263 1264 RolisteamTheme* IOHelper::jsonToTheme(const QJsonObject& json) 1265 { 1266 auto theme= new RolisteamTheme(); 1267 theme->setName(json["name"].toString()); 1268 theme->setRemovable(json["removable"].toBool()); 1269 theme->setCss(json["css"].toString()); 1270 theme->setBackgroundPosition(json["position"].toInt()); 1271 QString bgColorName= json["bgColor"].toString(); 1272 QColor color; 1273 color.setNamedColor(bgColorName); 1274 theme->setBackgroundColor(color); 1275 1276 theme->setBackgroundImage(json["bgPath"].toString()); 1277 theme->setStyle(QStyleFactory::create(json["stylename"].toString())); 1278 QColor diceColor; 1279 diceColor.setNamedColor(json["diceHighlight"].toString()); 1280 theme->setDiceHighlightColor(diceColor); 1281 QJsonArray colors= json["colors"].toArray(); 1282 int i= 0; 1283 auto model= theme->paletteModel(); 1284 for(auto const& ref : colors) 1285 { 1286 QJsonObject paletteObject= ref.toObject(); 1287 QColor color; 1288 color.setNamedColor(paletteObject["color"].toString()); 1289 model->setColor(i, color); 1290 ++i; 1291 } 1292 1293 return theme; 1294 } 1295 1296 QJsonObject IOHelper::themeToObject(const RolisteamTheme* theme) 1297 { 1298 QJsonObject json; 1299 json["name"]= theme->getName(); 1300 json["removable"]= theme->isRemovable(); 1301 json["css"]= theme->getCss(); 1302 json["position"]= theme->getBackgroundPosition(); 1303 json["bgColor"]= theme->getBackgroundColor().name(); 1304 json["diceHighlight"]= theme->getDiceHighlightColor().name(); 1305 json["bgPath"]= theme->getBackgroundImage(); 1306 json["stylename"]= theme->getStyleName(); 1307 1308 QJsonArray colors; 1309 auto const& data= theme->paletteModel()->data(); 1310 for(auto const& tmp : data) 1311 { 1312 QJsonObject paletteObject; 1313 tmp->writeTo(paletteObject); 1314 /*json["role"]= static_cast<int>(tmp->getRole()); 1315 json["group"]= static_cast<int>(tmp->getGroup()); 1316 json["name"]= tmp->getName();*/ 1317 json["color"]= tmp->getColor().name(); 1318 colors.append(paletteObject); 1319 } 1320 json["colors"]= colors; 1321 return json; 1322 } 1323 1324 void IOHelper::writeJsonArrayIntoFile(const QString& destination, const QJsonArray& array) 1325 { 1326 static QMutex mutex; 1327 QMutexLocker locker(&mutex); 1328 QJsonDocument doc; 1329 doc.setArray(array); 1330 1331 QFile file(destination); 1332 if(file.open(QIODevice::WriteOnly)) 1333 { 1334 file.write(doc.toJson(QJsonDocument::Indented)); 1335 } 1336 } 1337 1338 void IOHelper::writeJsonObjectIntoFile(const QString& destination, const QJsonObject& obj) 1339 { 1340 static QMutex mutex; 1341 QMutexLocker locker(&mutex); 1342 QJsonDocument doc; 1343 doc.setObject(obj); 1344 1345 QFile file(destination); 1346 if(file.open(QIODevice::WriteOnly)) 1347 { 1348 file.write(doc.toJson(QJsonDocument::Indented)); 1349 } 1350 } 1351 1352 void IOHelper::readNoteController(NoteController* ctrl, const QByteArray& array) 1353 { 1354 if(!ctrl || array.isEmpty()) 1355 return; 1356 auto data= array; 1357 QDataStream input(&data, QIODevice::ReadOnly); 1358 1359 IOHelper::readBase(ctrl, input); 1360 1361 QString text; 1362 input >> text; 1363 ctrl->setText(text); 1364 } 1365 1366 void IOHelper::readSharedNoteController(SharedNoteController* ctrl, const QByteArray& array) 1367 { 1368 if(!ctrl || array.isEmpty()) 1369 return; 1370 auto data= array; 1371 QDataStream input(&data, QIODevice::ReadOnly); 1372 1373 IOHelper::readBase(ctrl, input); 1374 1375 /*ParticipantModel::Permission perm; 1376 input >> perm;*/ 1377 1378 QString text; 1379 input >> text; 1380 1381 SharedNoteController::HighlightedSyntax syntax; 1382 input >> syntax; 1383 1384 bool b; 1385 input >> b; 1386 1387 ctrl->setMarkdownVisible(b); 1388 ctrl->setText(text); 1389 ctrl->setHighligthedSyntax(syntax); 1390 // ctrl->setPermission(perm); 1391 } 1392 1393 QUrl IOHelper::findSong(const QString& name, QStringList list) 1394 { 1395 QUrl url(name, QUrl::StrictMode); 1396 if(!url.scheme().isEmpty()) 1397 { 1398 return url; 1399 } 1400 else 1401 { 1402 for(auto const& path : list) 1403 { 1404 QFileInfo info(QString("%1/%2").arg(path, name)); 1405 if(info.exists()) 1406 return QUrl::fromLocalFile(info.absoluteFilePath()); 1407 } 1408 } 1409 1410 return {}; 1411 } 1412 // QHash<QString, std::map<QString, QVariant>>