1 // Copyright (c) 2012 Dennco Project
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.
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.
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/>.
17 // Created by tkawata on Sep-30, 2012.
19 #include "dccontainer.h"
22 #include "dccellcode.h"
24 #include "dcaxonterminal.h"
25 #include "dcreceptor.h"
27 #include "dccontent.h"
28 #include "dccreator.h"
29 #include "dcvpagecomponent.h"
30 #include "utils/dccomponentutil.h"
31 #include "dctreeviewwidget.h"
33 #include "DNFileList.h"
34 #include "DNDirectory.h"
35 #include "utils/dcutil.h"
37 #include <QMutexLocker>
39 #include <QDirIterator>
43 TKContainer* TKContainer::createContainer()
45 TKContainer *container = new DCContainer();
50 DCContainer::DCContainer() : d_content(NULL), d_factoryCachedLocation("")
52 d_scene = new DCScene(this);
54 d_workDirRoot = QDir::homePath() + "/.denncoCreator/work";
55 d_workDirCellRoot = d_workDirRoot + "/cells";
56 d_workDirCellCodeRoot = d_workDirRoot + "/cellcodes";
60 DCContainer::~DCContainer()
69 bool DCContainer::getIsModified() const
73 return d_scene->getIsModified();
81 bool DCContainer::isScriptableCell(DCCell *cell)
83 bool noScript = false;
85 std::string type = cell->getType().toStdString();
87 if (type == CELLTYPE_JSBASIC || type.length() == 0)
91 else if (type == CELLTYPE_IN)
95 else if (type == CELLTYPE_OUT)
99 else if (type == CELLTYPE_BASICSTORAGE)
110 void DCContainer::setContent(DCContent *content)
115 void DCContainer::unselectCellObjectAll()
117 for ( TKCellMap::iterator it = mCells.begin(); it != mCells.end(); ++it ) {
118 DCCell *cell = dynamic_cast<DCCell*>(it->second);
120 cell->getVComponent()->setSelected(false,true);
124 QList<DCVComponent*> DCContainer::getSelectedCellObjects() const
126 QList<DCVComponent*> list;
128 for ( TKCellMap::const_iterator it = mCells.begin(); it != mCells.end(); ++it ) {
129 DCCell *cell = dynamic_cast<DCCell*>(it->second);
132 DCVComponent *object = NULL;
134 object = cell->getVComponent();
135 if (object && object->getIsSelected())
137 list.push_back(object);
141 DCAxon *axon = cell->getAxon();
142 object = axon->getVComponent();
143 if (object && object->getIsSelected())
145 list.push_back(object);
149 int n = axon->getNumberOfTerminals();
150 for (int i = 0; i < n; i++)
152 object = axon->getTerminalAt(i)->getVComponent();
153 if (object && object->getIsSelected())
155 list.push_back(object);
160 const TKReceptorMap *receptors = cell->getReceptors();
161 TKReceptorMap::const_iterator it = receptors->begin();
162 while( it != receptors->end())
164 object = ((DCReceptor*)(*it).second)->getVComponent();
165 if (object && object->getIsSelected())
167 list.push_back(object);
177 TKCell* DCContainer::addCell(std::string theLocation, std::string theName, std::string type, std::string customScript)
179 QMutexLocker(d_scene->getSceneLock());
181 DCCell *cell = dynamic_cast<DCCell*>(TKContainer::addCell(theLocation, theName, type, customScript));
183 saveCustomScriptToWorkFile(cell, customScript);
188 TKCell* DCContainer::addCell(std::string theLocation, std::string theName, TKCellCode *cellCode, std::string customScript)
190 QMutexLocker(d_scene->getSceneLock());
192 DCCell *cell = dynamic_cast<DCCell*>(TKContainer::addCell(theLocation, theName, cellCode, customScript));
194 saveCustomScriptToWorkFile(cell, customScript);
199 TKCellCode* DCContainer::addCellCode(std::string theName, std::string theAPIType, std::string code)
201 QMutexLocker(d_scene->getSceneLock());
203 DCCellCode *cellCode = dynamic_cast<DCCellCode*>(TKContainer::addCellCode(theName, theAPIType, code));
205 saveClassScriptToWorkFile(cellCode, code);
210 TKCell* DCContainer::cellFactory(std::string location, std::string name, std::string type, bool canInterface)
212 if (location != d_factoryCachedLocation || d_factoryCachedPageObject.ref() == NULL)
214 d_factoryCachedPageObject.assign(d_scene->getPage(location));
215 if (d_factoryCachedPageObject.ref() == NULL)
217 d_factoryCachedPageObject.assign(d_scene->addPage(location));
220 d_factoryCachedLocation = location;
222 TKCell *cell = DCComponentUtil::createCell(this, dynamic_cast<DCVCPage*>(d_factoryCachedPageObject.ref()), location, name, type, canInterface);
228 TKAxon* DCContainer::axonFactory(TKCell *theOwner)
230 return DCComponentUtil::createAxon((DCCell*)theOwner);
233 TKReceptor* DCContainer::receptorFactory(TKCell *theOwner)
235 return DCComponentUtil::createReceptor((DCCell*)theOwner);
238 TKAxonTerminal* DCContainer::axonTerminalFactory(TKAxon *theOwner)
240 return DCComponentUtil::createAxonTerminal((DCAxon*)theOwner);
243 TKCellCode* DCContainer::cellCodeFactory(std::string name, std::string cellapi, std::string code)
245 DCVCPage *page = NULL;
246 if (name != TKContainer::CELLCODENAME_EMPTY)
248 std::string location = name;
249 if (location.find("#") != std::string::npos)
251 location = location.substr(0, location.find("#"));
253 if (location != d_factoryCachedLocation || d_factoryCachedPageObject.ref() == NULL)
255 d_factoryCachedPageObject.assign(d_scene->getPage(location));
256 if (d_factoryCachedPageObject.ref() == NULL)
258 d_factoryCachedPageObject.assign(d_scene->addPage(location));
261 d_factoryCachedLocation = location;
262 page = dynamic_cast<DCVCPage*>(d_factoryCachedPageObject.ref());
264 return DCComponentUtil::createCellCode(this, page, name, cellapi);
267 void DCContainer::beganParsePage(const char *docRoot, const char *path)
269 QDir workCellDir(d_workDirCellRoot + "/" + QString::fromLocal8Bit(path));
270 QDir workCellCodeDir(d_workDirCellCodeRoot + "/" + QString::fromLocal8Bit(path));
271 if (!workCellDir.exists())
273 workCellDir.mkpath(workCellDir.absolutePath());
275 if (!workCellCodeDir.exists())
277 workCellCodeDir.mkpath(workCellCodeDir.absolutePath());
280 std::string location = path;
281 d_factoryCachedPageObject.assign(d_scene->getPage(location));
282 if (d_factoryCachedPageObject.ref() == NULL)
284 d_factoryCachedPageObject.assign(d_scene->addPage(location));
286 d_factoryCachedLocation = location;
289 void DCContainer::endedParsePage(const char *docRoot, const char *path)
295 void DCContainer::beganBuildContainer()
297 DCUtil::removeDirRecursive(d_workDirRoot);
300 void DCContainer::endedBuildContainer()
306 bool DCContainer::removeCellCode(DCCellCode *cellcode)
308 for ( TKCellMap::iterator it = mCells.begin(); it != mCells.end(); ++it )
310 DCCell *cell = dynamic_cast<DCCell*>(it->second);
311 if (cell->getCellCode() == cellcode)
313 cell->setCellCode(mEmptyCellClass, cell->getCustomScript().toLocal8Bit().data());
318 for ( TKCellCodeMap::iterator it = mCellCodes.begin(); it != mCellCodes.end(); ++it )
320 if (it->second == cellcode)
322 mCellCodes.erase(it);
328 if (cellcode->getPageBelonging())
330 cellcode->getPageBelonging()->unregisterCellCodeClass(cellcode->getVComponent());
337 bool DCContainer::removeCell(DCCell *cell)
339 for ( TKCellMap::iterator it = mCells.begin(); it != mCells.end(); ++it )
341 if (it->second == cell)
344 if (cell->getPageBelonging())
346 cell->getPageBelonging()->unregisterCell(cell->getVComponent());
355 bool DCContainer::saveCustomScriptToWorkFile(DCCell *cell, std::string customScript)
357 QDir workdir(d_workDirCellRoot + "/" + QString::fromStdString(cell->getLocation()));
358 if (!workdir.exists())
360 workdir.mkpath(workdir.absolutePath());
362 QFile workfile(workdir.absoluteFilePath(QString::fromStdString(cell->getName()) + ".js"));
363 workfile.open(QIODevice::WriteOnly);
364 QTextStream out(&workfile);
365 out << QString::fromStdString(customScript);
370 bool DCContainer::saveClassScriptToWorkFile(DCCellCode *cellCode, std::string code)
372 QString qNamePath = QString::fromStdString(cellCode->getFQNName());
373 QString path = DCUtil::getContainerBasedPathFromFQNPath(qNamePath);
374 QString name = DCUtil::getNameFromFQNPath(qNamePath);
376 QDir workdir(d_workDirCellCodeRoot + "/" + path);
377 if (!workdir.exists())
379 workdir.mkpath(workdir.absolutePath());
381 QFile workfile(workdir.absoluteFilePath(name + ".js"));
382 workfile.open(QIODevice::WriteOnly);
383 QTextStream out(&workfile);
384 out << QString::fromStdString(code);
389 QString DCContainer::readCustomScriptFromWorkFile(const DCCell *cell)
391 QFile file(d_workDirCellRoot + "/" + QString::fromStdString(cell->getLocation()) + "/" + QString::fromStdString(cell->getName()) + ".js");
398 file.open(QIODevice::ReadOnly);
399 QTextStream in(&file);
400 QString out = in.readAll();
406 QString DCContainer::readCellCodeScriptFromFile(const DCCellCode *cellCode)
408 QString qNamePath = QString::fromStdString(cellCode->getFQNName());
409 QString path = DCUtil::getContainerBasedPathFromFQNPath(qNamePath);
410 QString name = DCUtil::getNameFromFQNPath(qNamePath);
412 QFile file(d_workDirCellCodeRoot + "/" + path + "/" + name + ".js");
418 file.open(QIODevice::ReadOnly);
419 QTextStream in(&file);
420 QString out = in.readAll();
426 QString DCContainer::sysFilePathToContainerBasedPath(const QString &sysFilePath)
428 QString containerPath = QString::fromStdString(getContainerRootPath());
429 return "/" + QDir(containerPath).relativeFilePath(sysFilePath);
432 QString DCContainer::containerBasedPathToSysFilePath(const QString &containerBasedPath)
434 QString containerPath = QString::fromStdString(getContainerRootPath());
435 return containerPath + containerBasedPath;
438 bool DCContainer::renameCell(DCCell *cell, const QString &newName)
440 QString fqnName = DCUtil::getFQNPath(cell->getLocation(), cell->getName());
441 mCells.erase(fqnName.toStdString());
443 cell->changeName(newName);
445 QString newFqnName = DCUtil::getFQNPath(cell->getLocation(), cell->getName());
446 std::pair<TKCellMap::iterator, bool> r = mCells.insert(TKCellMap::value_type(newFqnName.toStdString(), cell));
451 bool DCContainer::moveCell(DCCell *cell, const QString& pageNewContainerBasedPathName)
453 QString fqnName = DCUtil::getFQNPath(cell->getLocation(), cell->getName());
454 QString customScript = readCustomScriptFromWorkFile(cell);
455 mCells.erase(fqnName.toStdString());
457 cell->changePath(pageNewContainerBasedPathName);
458 saveCustomScriptToWorkFile(cell, customScript.toStdString());
460 QString newFqnName = DCUtil::getFQNPath(pageNewContainerBasedPathName.toStdString(), cell->getName());
461 std::pair<TKCellMap::iterator, bool> r = mCells.insert(TKCellMap::value_type(newFqnName.toStdString(), cell));
465 bool DCContainer::renameCellCodeClass(DCCellCode *cellcode, const QString &newName)
467 mCellCodes.erase(cellcode->getFQNName());
468 cellcode->changeName(newName);
469 std::pair<TKCellCodeMap::iterator, bool> r = mCellCodes.insert(TKCellCodeMap::value_type(cellcode->getFQNName(), cellcode));
474 bool DCContainer::moveCellCodeClass(DCCellCode *cellcode, const QString& pageNewContainerBasedPathName)
476 QString script = readCellCodeScriptFromFile(cellcode);
477 mCellCodes.erase(cellcode->getFQNName());
479 cellcode->changePath(pageNewContainerBasedPathName);
480 saveClassScriptToWorkFile(cellcode, script.toStdString());
482 std::pair<TKCellCodeMap::iterator, bool> r = mCellCodes.insert(TKCellCodeMap::value_type(cellcode->getFQNName(), cellcode));
487 DCVCPage* DCContainer::movePage(const QString &oldContainerBasedPathName, const QString &newContainerBasedPathName)
490 DCVCPage *newPage = NULL;
491 DCScene *scene = getScene();
494 DCVCPage *oldPage = getScene()->getPage(oldContainerBasedPathName.toStdString());
495 newPage = getScene()->addPage(newContainerBasedPathName.toStdString());
497 if (oldPage && newPage)
499 r = oldPage->moveComponentsTo(newPage);
503 QString sysOldFilePath = containerBasedPathToSysFilePath(oldContainerBasedPathName);
504 QString sceneSettingFilePath = scene->getSceneSettingFilePathForPage(oldPage);
505 if (!DCTreeViewWidget::removeFile(sysOldFilePath))
510 dir.remove(sceneSettingFilePath);
512 if (!scene->removePage(oldPage))
519 return r ? newPage : NULL;
523 QList<QString> DCContainer::getAvailableCellTypes() const
527 list.append(QString::fromStdString(TKContainer::CELLTYPE_JSBASIC));
528 list.append(QString::fromStdString(TKContainer::CELLTYPE_BASICSTORAGE));
529 list.append(QString::fromStdString(TKContainer::CELLTYPE_IN));
530 list.append(QString::fromStdString(TKContainer::CELLTYPE_OUT));
535 QList<QString> DCContainer::getAvailableScriptableCellTypes() const
539 list.append(QString::fromStdString(TKContainer::CELLTYPE_JSBASIC));
540 list.append(QString::fromStdString(TKContainer::CELLTYPE_BASICSTORAGE));
545 bool DCContainer::getIsScriptable(const QString& type) const
547 std::string t = type.toStdString();
549 if (t == TKContainer::CELLTYPE_JSBASIC)
553 else if (t == TKContainer::CELLTYPE_BASICSTORAGE)
557 else if (t == TKContainer::CELLTYPE_IN)
561 else if (t == TKContainer::CELLTYPE_OUT)
570 bool DCContainer::getIsReceptorAvailable(const QString& type) const
572 std::string t = type.toStdString();
574 if (t == TKContainer::CELLTYPE_JSBASIC)
578 else if (t == TKContainer::CELLTYPE_BASICSTORAGE)
582 else if (t == TKContainer::CELLTYPE_IN)
586 else if (t == TKContainer::CELLTYPE_OUT)