OSDN Git Service

[denncoCreator] fixed a crash bug.
[dennco/denncoCreator.git] / Source / dccontainersaver.cpp
1 //  Copyright (c) 2012 Dennco Project
2 //
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 //
17 //  Created by tkawata on Oct-2, 2012.
18 //
19 #include "dccontainersaver.h"
20
21 #include "dccontainer.h"
22 #include "dcscene.h"
23 #include "dcvcpage.h"
24 #include "dcvccellcode.h"
25 #include "dccell.h"
26 #include "dccellcode.h"
27 #include "dcreceptor.h"
28 #include "dcaxon.h"
29 #include "dcaxonterminal.h"
30 #include "dcvpagecomponent.h"
31 #include "dcscene.h"
32 #include "utils/dcutil.h"
33
34 #include <QDomDocument>
35 #include <QMap>
36 #include <QFile>
37 #include <QDir>
38 #include <QCryptographicHash>
39 #include <QByteArray>
40
41 static QDomDocument* constructDocumentForPage(DCContainer *container, const DCVCPage *page);
42
43 DCContainerSaver::DCContainerSaver(DCContainer *container) : d_container(container)
44 {
45
46 }
47
48 DCContainerSaver::~DCContainerSaver()
49 {
50
51 }
52
53 QString DCContainerSaver::calculateHashForPage(const DCVCPage *page)
54 {
55     QCryptographicHash hash(QCryptographicHash::Md5);
56     QDomDocument *pDoc1 = constructDocumentForPage(d_container, page);
57     if (pDoc1)
58     {
59         hash.addData(pDoc1->toString(-1).toLocal8Bit());
60         delete pDoc1;
61     }
62
63     QDomDocument doc2;
64     QDomElement doc2Root = doc2.createElement("denncoCreator");
65     page->saveAttributesToXML(&doc2, &doc2Root);
66     doc2.appendChild(doc2Root);
67     hash.addData(doc2.toString(-1).toLocal8Bit());
68
69     return QString(hash.result().toHex());
70 }
71
72 bool DCContainerSaver::saveAll(const QString& containerRootPath)
73 {
74     const QMap<QString,DCVCPage*> *pages = d_container->getScene()->getPages();
75     QMapIterator<QString, DCVCPage*> i(*pages);
76     bool r = true;
77     while (i.hasNext())
78     {
79         i.next();
80         DCVCPage *page = i.value();
81         if (!saveForPage(containerRootPath, page))
82         {
83             r = false;
84         }
85     }
86     return true;
87 }
88
89 bool DCContainerSaver::saveForPage(const QString& containerRootPath, DCVCPage *page)
90 {
91     QString pageFilePath = containerRootPath;
92     pageFilePath.append(page->getLocationPath());
93
94     QDomDocument *doc = constructDocumentForPage(d_container, page);
95     if (!doc)
96         return false;
97
98     QFile file(pageFilePath);
99     QFileInfo pathInfo = QFileInfo(pageFilePath);
100     QDir dir = pathInfo.dir();
101     if (!dir.exists())
102         dir.mkpath(dir.absolutePath());
103
104     bool r = false;
105     if (file.open(QFile::WriteOnly | QFile::Truncate))
106     {
107         QTextStream out(&file);
108         doc->save(out, 4);
109         r = true;
110     }
111     file.close();
112
113     delete doc;
114
115     if (r)
116     {
117         r = d_container->getScene()->saveSceneForPage(containerRootPath, page);
118     }
119
120     if (r)
121     {
122         page->updateSavedState(d_container);
123     }
124
125     return r;
126 }
127
128 QDomDocument* constructDocumentForPage(DCContainer *conteinr, const DCVCPage *page)
129 {
130     QDomDocument *doc = new QDomDocument("html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"");
131     doc->createProcessingInstruction("xml", "version=\"1.0\" encoding=\"utf-8\"");
132
133     QDomElement root = doc->createElementNS("http://www.w3.org/1999/xhtml","html");
134     root.setAttribute("lang", "en");
135     QDomElement body = doc->createElement("body");
136     root.appendChild(body);
137
138     const QList<DCVPageComponent*>* vcells = page->getCells();
139     for (int i = 0; i < vcells->length(); i++)
140     {
141         DCCell *cell = vcells->at(i)->getOwnerCell();
142         QString cellName = QString::fromStdString(cell->getName());
143
144         QDomElement aCellTag = doc->createElement("a");
145         aCellTag.setAttribute("define", "cell");
146         aCellTag.setAttribute("name", cellName);
147
148         QDomElement aCellCodeTag = doc->createElement("a");
149         aCellCodeTag.setAttribute("parameter", "cellcode");
150         if (cell->getIsCellCodeAssgined())
151         {
152             aCellCodeTag.setAttribute("href", QString::fromStdString(cell->getCellCode()->getFQNName()));
153         }
154         else
155         {
156             aCellCodeTag.setAttribute("type", cell->getType());
157         }
158         aCellTag.appendChild(aCellCodeTag);
159         DCAxon *axon = cell->getAxon();
160         for (int j = 0; j < axon->getNumberOfTerminals(); j++)
161         {
162             DCAxonTerminal *terminal = axon->getTerminalAt(j);
163             DCReceptor *receptor = terminal->getTarget();
164             if (receptor)
165             {
166                 DCCell *targetCell = receptor->getOwnerCell();
167                 if (targetCell)
168                 {
169                     QString connectionPath = QString::fromStdString(targetCell->getLocation());
170                     connectionPath.append("#");
171                     connectionPath.append(QString::fromStdString(targetCell->getName()));
172                     QString receptorName = QString::fromStdString(targetCell->getReceptorName(receptor));
173
174                     QDomElement aConnectionTag = doc->createElement("a");
175                     aConnectionTag.setAttribute("parameter", "connection");
176                     aConnectionTag.setAttribute("href", connectionPath);
177                     aConnectionTag.setAttribute("receptor", receptorName);
178                     aCellTag.appendChild(aConnectionTag);
179                 }
180             }
181         }
182         QDomElement preScriptTag = doc->createElement("pre");
183         preScriptTag.setAttribute("parameter", "script");
184         QDomCDATASection scriptCData = doc->createCDATASection(conteinr->readCustomScriptFromWorkFile(cell));
185         preScriptTag.appendChild(scriptCData);
186         aCellTag.appendChild(preScriptTag);
187         body.appendChild(aCellTag);
188     }
189
190     const QList<DCVPageComponent*>* vcellcodeclasses = page->getCellCodeClasses();
191     for (int i = 0; i < vcellcodeclasses->length(); i++)
192     {
193         DCCellCode *cellcodeclass = dynamic_cast<DCVCCellCode*>(vcellcodeclasses->at(i))->getOwnerCellCodeClass();
194         QString cellCodeClassName = DCUtil::getNameFromFQNPath(QString::fromStdString(cellcodeclass->getFQNName()));
195
196         QDomElement aCellCodeTag = doc->createElement("a");
197         aCellCodeTag.setAttribute("define", "cellcode");
198         aCellCodeTag.setAttribute("name", cellCodeClassName);
199         aCellCodeTag.setAttribute("type", QString::fromStdString(cellcodeclass->getCellAPIName()));
200         QDomElement preScriptTag = doc->createElement("pre");
201         preScriptTag.setAttribute("parameter", "script");
202         QDomCDATASection scriptCData = doc->createCDATASection(conteinr->readCellCodeScriptFromFile(cellcodeclass));
203         preScriptTag.appendChild(scriptCData);
204         aCellCodeTag.appendChild(preScriptTag);
205         body.appendChild(aCellCodeTag);
206     }
207
208     doc->appendChild(root);
209
210     return doc;
211 }