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