File indexing completed on 2024-05-12 05:40:26

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 "mindmap/worker/fileserializer.h"
0021 
0022 #include "mindmap/data/linkcontroller.h"
0023 #include "mindmap/data/packagenode.h"
0024 #include "mindmap/model/imagemodel.h"
0025 #include "mindmap/model/minditemmodel.h"
0026 #include "mindmap/model/nodeimageprovider.h"
0027 
0028 #include <QBuffer>
0029 #include <QByteArray>
0030 #include <QDir>
0031 #include <QFile>
0032 #include <QJsonArray>
0033 #include <QJsonDocument>
0034 #include <QJsonObject>
0035 #include <QUrl>
0036 #include <random>
0037 
0038 namespace mindmap
0039 {
0040 FileSerializer::FileSerializer() {}
0041 
0042 bool FileSerializer::readTextFile(MindItemModel* nodeModel, const QString& filepath)
0043 {
0044     QFile file(QUrl(filepath).path());
0045     std::random_device rd;
0046     std::mt19937 gen(rd());
0047 
0048     if(!file.open(QFile::ReadOnly))
0049     {
0050         return false;
0051     }
0052 
0053     QVector<MindNode*> parent;
0054     MindNode* previousNode= nullptr;
0055     int depth= 0;
0056     while(!file.atEnd())
0057     {
0058         QByteArray line= file.readLine();
0059         auto text= QString::fromUtf8(line);
0060         auto trimmed= text.trimmed();
0061         if(text.trimmed().isEmpty())
0062             continue;
0063 
0064         auto node= new MindNode();
0065 
0066         auto newdepth= std::max(static_cast<qsizetype>(0), (text.indexOf(trimmed[0])) / 2);
0067 
0068         node->setText(text.trimmed());
0069         std::uniform_real_distribution<> dist(0.0, 1600.0);
0070         node->setPosition({dist(gen), dist(gen)});
0071         nodeModel->appendItem({node});
0072         if(newdepth > depth && previousNode != nullptr)
0073         {
0074             parent.append(previousNode);
0075         }
0076         while(newdepth < depth)
0077         {
0078             parent.removeLast();
0079             depth-= 1;
0080         }
0081 
0082         if(newdepth >= depth && !parent.isEmpty())
0083         {
0084             // parent.last(), node;
0085             auto link= new LinkController();
0086             link->setStart(parent.last());
0087             link->setEnd(node);
0088             nodeModel->appendItem({link});
0089         }
0090 
0091         previousNode= node;
0092         depth= newdepth;
0093     }
0094 
0095     // nodeModel->appendNode(nodes);
0096 
0097     return true;
0098 }
0099 
0100 void FileSerializer::fetchItemModel(MindItemModel* nodeModel, const QJsonObject& json)
0101 {
0102     /* QFile file(filepath);
0103      if(!file.open(QFile::ReadOnly))
0104      {
0105          return false;
0106      }
0107      auto data= file.readAll();
0108      QJsonDocument doc= QJsonDocument::fromJson(data);
0109 
0110      auto json= doc.object();*/
0111 
0112     // auto nodeModel= dynamic_cast<MindItemModel*>(controller->itemModel());
0113 
0114     auto linkArray= json["links"].toArray();
0115     auto nodeArray= json["nodes"].toArray();
0116     auto packagesArray= json["packages"].toArray();
0117 
0118     std::map<QString, PositionedItem*> nodeMap;
0119     for(auto const& nodeRef : qAsConst(nodeArray))
0120     {
0121         auto obj= nodeRef.toObject();
0122         auto node= new MindNode();
0123         node->setId(obj["id"].toString());
0124         auto x= obj["x"].toDouble();
0125         auto y= obj["y"].toDouble();
0126         node->setPosition(QPointF(x, y));
0127         node->setText(obj["text"].toString());
0128         node->setImageUri(obj["image"].toString());
0129         node->setVisible(obj["visible"].toBool());
0130         node->setOpen(obj["open"].toBool());
0131         node->setStyleIndex(obj["styleIndex"].toInt());
0132         node->setDescription(obj["description"].toString());
0133         QStringList tags;
0134         auto tagArray= obj["tags"].toArray();
0135         std::transform(std::begin(tagArray), std::end(tagArray), std::back_inserter(tags),
0136                        [](const QJsonValue& val) { return val.toString(); });
0137         node->setTags(tags);
0138 
0139         nodeModel->appendItem({node});
0140         nodeMap.insert({node->id(), node});
0141     }
0142 
0143     for(auto const& packRef : qAsConst(packagesArray))
0144     {
0145         auto obj= packRef.toObject();
0146         auto node= new PackageNode();
0147         node->setId(obj["id"].toString());
0148         auto x= obj["x"].toDouble();
0149         auto y= obj["y"].toDouble();
0150         node->setPosition(QPointF(x, y));
0151         node->setText(obj["text"].toString());
0152         node->setVisible(obj["visible"].toBool());
0153 
0154         nodeModel->appendItem({node});
0155         nodeMap.insert({node->id(), node});
0156     }
0157 
0158     for(auto const& linkRef : qAsConst(linkArray))
0159     {
0160         auto obj= linkRef.toObject();
0161         // auto link= new Link();
0162 
0163         auto idStart= obj["idStart"].toString();
0164         auto idEnd= obj["idEnd"].toString();
0165         auto text= obj["text"].toString();
0166         auto color= obj["color"].toBool();
0167         auto constraint= obj["constraint"].toBool();
0168 
0169         auto link= new LinkController();
0170         link->setStart(nodeMap[idStart]);
0171         link->setEnd(nodeMap[idEnd]);
0172         nodeMap[idEnd]->setParentNode(nodeMap[idStart]);
0173 
0174         link->setText(text);
0175         link->setVisible(obj["visible"].toBool());
0176         link->setColor(color);
0177         link->setConstraint(constraint);
0178         link->setDirection(static_cast<LinkController::Direction>(obj["Direction"].toInt()));
0179         nodeModel->appendItem({link});
0180     }
0181 }
0182 
0183 void FileSerializer::fetchImageModel(ImageModel* imgModel, const QJsonObject& json)
0184 {
0185     auto imgArray= json["imgs"].toArray();
0186     for(auto const& imgRef : qAsConst(imgArray))
0187     {
0188         auto img= imgRef.toObject();
0189         auto id= img["id"].toString();
0190         auto url= QUrl(img["url"].toString());
0191         auto data= QByteArray::fromBase64(img["data"].toString().toLocal8Bit());
0192         QPixmap map;
0193         if(map.loadFromData(data))
0194             imgModel->insertPixmap(id, map, url);
0195     }
0196 }
0197 
0198 QJsonObject FileSerializer::writeItemModel(MindItemModel* nodeModel, QJsonObject& json)
0199 {
0200 
0201     // NODES
0202     QJsonArray nodeArray;
0203     auto const& nodes= nodeModel->items(MindItem::NodeType);
0204     for(auto item : nodes)
0205     {
0206         auto node= dynamic_cast<MindNode*>(item);
0207         if(!node)
0208             continue;
0209         QJsonObject obj;
0210         obj["id"]= node->id();
0211         obj["x"]= node->position().x();
0212         obj["y"]= node->position().y();
0213         obj["text"]= node->text();
0214         obj["image"]= node->imageUri();
0215         obj["visible"]= node->isVisible();
0216         obj["open"]= node->open();
0217         obj["styleIndex"]= node->styleIndex();
0218         obj["description"]= node->description();
0219         obj["tags"]= QJsonArray::fromStringList(node->tags());
0220         nodeArray.append(obj);
0221     }
0222     json["nodes"]= nodeArray;
0223 
0224     // PACKAGES
0225     QJsonArray packageArray;
0226     auto const& packages= nodeModel->items(MindItem::PackageType);
0227     for(auto item : packages)
0228     {
0229         auto pack= dynamic_cast<PackageNode*>(item);
0230         if(!pack)
0231             continue;
0232         QJsonObject obj;
0233         obj["id"]= pack->id();
0234         obj["x"]= pack->position().x();
0235         obj["y"]= pack->position().y();
0236         obj["text"]= pack->text();
0237 
0238         obj["width"]= pack->width();
0239         obj["height"]= pack->height();
0240         obj["visible"]= pack->isVisible();
0241         packageArray.append(obj);
0242     }
0243     json["packages"]= packageArray;
0244 
0245     // LINKS
0246     QJsonArray linkArray;
0247     auto const& links= nodeModel->items(MindItem::LinkType);
0248     for(auto item : links)
0249     {
0250         auto link= dynamic_cast<LinkController*>(item);
0251         if(!link)
0252             continue;
0253         QJsonObject obj;
0254         obj["idStart"]= link->start()->id();
0255         obj["idEnd"]= link->end()->id();
0256         obj["visible"]= link->isVisible();
0257         obj["Direction"]= link->direction();
0258         obj["color"]= link->color();
0259         obj["constraint"]= link->constraint();
0260         obj["text"]= link->text();
0261         linkArray.append(obj);
0262     }
0263     json["links"]= linkArray;
0264 
0265     // Save image data
0266 
0267     /*auto imgModel= controller->imgModel();
0268     auto const& dataImg= imgModel->imageInfos();
0269     QJsonArray imgArray;
0270     for(auto& info : dataImg)
0271     {
0272         QJsonObject img;
0273         img["id"]= info.m_id;
0274         img["url"]= info.m_url.toString();
0275 
0276         auto pix= info.m_pixmap;
0277         QJsonArray linkArray;
0278         QByteArray bytes;
0279         {
0280             QBuffer buffer(&bytes);
0281             buffer.open(QIODevice::WriteOnly);
0282             pix.save(&buffer, "PNG");
0283         }
0284         img["data"]= QString(bytes.toBase64());
0285         imgArray.append(img);
0286     }
0287     data["imgs"]= imgArray;
0288 **/
0289     /*QJsonDocument doc;
0290     doc.setObject(data);
0291 
0292     QFile file(filepath);
0293     if(!file.open(QFile::WriteOnly))
0294     {
0295         return false;
0296     }
0297     file.write(doc.toJson());*/
0298     return json;
0299 }
0300 
0301 QJsonObject FileSerializer::writeImageModel(mindmap::ImageModel* model, QJsonObject& data)
0302 {
0303     auto const& dataImg= model->imageInfos();
0304     QJsonArray imgArray;
0305     for(auto& info : dataImg)
0306     {
0307         QJsonObject img;
0308         img["id"]= info.m_id;
0309         img["url"]= info.m_url.toString();
0310 
0311         auto pix= info.m_pixmap;
0312         QJsonArray linkArray;
0313         QByteArray bytes;
0314         {
0315             QBuffer buffer(&bytes);
0316             buffer.open(QIODevice::WriteOnly);
0317             pix.save(&buffer, "PNG");
0318         }
0319         img["data"]= QString(bytes.toBase64());
0320         imgArray.append(img);
0321     }
0322     data["imgs"]= imgArray;
0323     return data;
0324 }
0325 
0326 } // namespace mindmap