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) const
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)
103 else if (type == CELLTYPE_PLUGIN_IN)
107 else if (type == CELLTYPE_PLUGIN_OUT)
118 void DCContainer::setContent(DCContent *content)
123 void DCContainer::unselectCellObjectAll()
125 for ( TKCellMap::iterator it = mCells.begin(); it != mCells.end(); ++it ) {
126 DCCell *cell = dynamic_cast<DCCell*>(it->second);
128 cell->getVComponent()->setSelected(false,true);
132 QList<DCVComponent*> DCContainer::getSelectedCellObjects() const
134 QList<DCVComponent*> list;
136 for ( TKCellMap::const_iterator it = mCells.begin(); it != mCells.end(); ++it ) {
137 DCCell *cell = dynamic_cast<DCCell*>(it->second);
140 DCVComponent *object = NULL;
142 object = cell->getVComponent();
143 if (object && object->getIsSelected())
145 list.push_back(object);
149 DCAxon *axon = cell->getAxon();
150 object = axon->getVComponent();
151 if (object && object->getIsSelected())
153 list.push_back(object);
157 int n = axon->getNumberOfTerminals();
158 for (int i = 0; i < n; i++)
160 object = axon->getTerminalAt(i)->getVComponent();
161 if (object && object->getIsSelected())
163 list.push_back(object);
168 const TKReceptorMap *receptors = cell->getReceptors();
169 TKReceptorMap::const_iterator it = receptors->begin();
170 while( it != receptors->end())
172 object = ((DCReceptor*)(*it).second)->getVComponent();
173 if (object && object->getIsSelected())
175 list.push_back(object);
185 TKCell* DCContainer::addCell(std::string theLocation, std::string theName, std::string type, std::string customScript)
187 QMutexLocker lock(d_scene->getSceneLock());
189 DCCell *cell = dynamic_cast<DCCell*>(TKContainer::addCell(theLocation, theName, type, customScript));
191 saveCustomScriptToWorkFile(cell, customScript);
196 TKCell* DCContainer::addCell(std::string theLocation, std::string theName, TKCellCode *cellCode, std::string customScript)
198 QMutexLocker lock(d_scene->getSceneLock());
200 DCCell *cell = dynamic_cast<DCCell*>(TKContainer::addCell(theLocation, theName, cellCode, customScript));
202 saveCustomScriptToWorkFile(cell, customScript);
207 TKCellCode* DCContainer::addCellCode(std::string theName, std::string theAPIType, std::string code)
209 QMutexLocker lock(d_scene->getSceneLock());
211 DCCellCode *cellCode = dynamic_cast<DCCellCode*>(TKContainer::addCellCode(theName, theAPIType, code));
213 saveClassScriptToWorkFile(cellCode, code);
218 TKCell* DCContainer::cellFactory(std::string location, std::string name, std::string type, bool canInterfaceIn, bool canInterfaceOut)
220 if (location != d_factoryCachedLocation || d_factoryCachedPageObject.ref() == NULL)
222 d_factoryCachedPageObject.assign(d_scene->getPage(location));
223 if (d_factoryCachedPageObject.ref() == NULL)
225 d_factoryCachedPageObject.assign(d_scene->addPage(location));
228 d_factoryCachedLocation = location;
230 TKCell *cell = DCComponentUtil::createCell(this, dynamic_cast<DCVCPage*>(d_factoryCachedPageObject.ref()), location, name, type, canInterfaceIn, canInterfaceOut);
236 TKCell* DCContainer::pluginCellFactory(std::string location, std::string fullName, std::string type, std::string pluginName, std::string pluginValue, bool canInterfaceIn, bool canInterfaceOut)
238 return cellFactory(location, fullName, type, canInterfaceIn, canInterfaceOut );
242 TKAxon* DCContainer::axonFactory(TKCell *theOwner)
244 return DCComponentUtil::createAxon((DCCell*)theOwner);
247 TKReceptor* DCContainer::receptorFactory(TKCell *theOwner)
249 return DCComponentUtil::createReceptor((DCCell*)theOwner);
252 TKAxonTerminal* DCContainer::axonTerminalFactory(TKAxon *theOwner)
254 return DCComponentUtil::createAxonTerminal((DCAxon*)theOwner);
257 TKCellCode* DCContainer::cellCodeFactory(std::string name, std::string cellapi, std::string code)
259 DCVCPage *page = NULL;
260 if (name != TKContainer::CELLCODENAME_EMPTY)
262 std::string location = name;
263 if (location.find("#") != std::string::npos)
265 location = location.substr(0, location.find("#"));
267 if (location != d_factoryCachedLocation || d_factoryCachedPageObject.ref() == NULL)
269 d_factoryCachedPageObject.assign(d_scene->getPage(location));
270 if (d_factoryCachedPageObject.ref() == NULL)
272 d_factoryCachedPageObject.assign(d_scene->addPage(location));
275 d_factoryCachedLocation = location;
276 page = dynamic_cast<DCVCPage*>(d_factoryCachedPageObject.ref());
278 return DCComponentUtil::createCellCode(this, page, name, cellapi);
281 void DCContainer::beganParsePage(const char *docRoot, const char *path)
285 QDir workCellDir(d_workDirCellRoot + QString::fromLocal8Bit(path));
286 QDir workCellCodeDir(d_workDirCellCodeRoot + QString::fromLocal8Bit(path));
287 if (!workCellDir.exists())
289 workCellDir.mkpath(workCellDir.absolutePath());
291 if (!workCellCodeDir.exists())
293 workCellCodeDir.mkpath(workCellCodeDir.absolutePath());
296 std::string location = path;
297 d_factoryCachedPageObject.assign(d_scene->getPage(location));
298 if (d_factoryCachedPageObject.ref() == NULL)
300 d_factoryCachedPageObject.assign(d_scene->addPage(location));
302 d_factoryCachedLocation = location;
305 void DCContainer::endedParsePage(const char *docRoot, const char *path)
307 (void)docRoot; (void)path;
311 void DCContainer::beganBuildContainer()
313 DCUtil::removeDirRecursive(d_workDirRoot);
316 void DCContainer::endedBuildContainer()
322 bool DCContainer::removeCellCode(DCCellCode *cellcode)
324 for ( TKCellMap::iterator it = mCells.begin(); it != mCells.end(); ++it )
326 DCCell *cell = dynamic_cast<DCCell*>(it->second);
327 if (cell->getCellCode() == cellcode)
329 cell->setCellCode(mEmptyCellClass, cell->getCustomScript().toLocal8Bit().data());
334 for ( TKCellCodeMap::iterator it = mCellCodes.begin(); it != mCellCodes.end(); ++it )
336 if (it->second == cellcode)
338 mCellCodes.erase(it);
344 if (cellcode->getPageBelonging())
346 cellcode->getPageBelonging()->unregisterCellCodeClass(cellcode->getVComponent());
353 bool DCContainer::removeCell(DCCell *cell)
355 for ( TKCellMap::iterator it = mCells.begin(); it != mCells.end(); ++it )
357 if (it->second == cell)
360 if (cell->getPageBelonging())
362 cell->getPageBelonging()->unregisterCell(cell->getVComponent());
371 bool DCContainer::saveCustomScriptToWorkFile(const DCCell *cell, std::string customScript)
373 QFile workfile(getWorkFilePathForCustomScript(cell));
374 QFileInfo fileInfo(workfile);
375 if (!fileInfo.absoluteDir().exists())
378 dir.mkpath(fileInfo.absolutePath());
381 workfile.open(QIODevice::WriteOnly);
382 QTextStream out(&workfile);
383 out << QString::fromStdString(customScript);
388 bool DCContainer::saveClassScriptToWorkFile(const DCCellCode *cellCode, std::string code)
390 QString qNamePath = QString::fromStdString(cellCode->getFQNName());
391 QString name = DCUtil::getNameFromFQNPath(qNamePath);
393 if (name.length() == 0)
396 QFile workfile(getWorkFilePathForCellCode(cellCode));
397 QFileInfo fileInfo(workfile);
398 if (!fileInfo.absoluteDir().exists())
401 dir.mkpath(fileInfo.absolutePath());
403 workfile.open(QIODevice::WriteOnly);
404 QTextStream out(&workfile);
405 out << QString::fromStdString(code);
410 QString DCContainer::readCustomScriptFromWorkFile(const DCCell *cell)
412 QFile file(getWorkFilePathForCustomScript(cell));
419 file.open(QIODevice::ReadOnly);
420 QTextStream in(&file);
421 QString out = in.readAll();
427 QString DCContainer::readCellCodeScriptFromFile(const DCCellCode *cellCode)
429 QString qNamePath = QString::fromStdString(cellCode->getFQNName());
430 QString name = DCUtil::getNameFromFQNPath(qNamePath);
432 if (name.length() == 0)
435 QFile file(getWorkFilePathForCellCode(cellCode));
441 file.open(QIODevice::ReadOnly);
442 QTextStream in(&file);
443 QString out = in.readAll();
449 QString DCContainer::sysFilePathToContainerBasedPath(const QString &sysFilePath)
451 QString containerPath = QString::fromStdString(getContainerRootPath());
452 return "/" + QDir(containerPath).relativeFilePath(sysFilePath);
455 QString DCContainer::containerBasedPathToSysFilePath(const QString &containerBasedPath)
457 QString containerPath = QString::fromStdString(getContainerRootPath());
458 return containerPath + containerBasedPath;
461 bool DCContainer::renameCell(DCCell *cell, const QString &newName)
463 QString oldFqnName = DCUtil::getFQNPath(cell->getLocation(), cell->getName());
464 QString oldName = QString::fromStdString(cell->getName());
466 if (oldName == newName)
469 QString customScript = readCustomScriptFromWorkFile(cell);
470 QFile workFileOld(getWorkFilePathForCustomScript(cell));
472 cell->changeName(newName);
473 if (!saveCustomScriptToWorkFile(cell, customScript.toStdString()))
475 cell->changeName(oldName);
478 workFileOld.remove();
479 mCells.erase(oldFqnName.toStdString());
481 QString newFqnName = DCUtil::getFQNPath(cell->getLocation(), cell->getName());
482 std::pair<TKCellMap::iterator, bool> r = mCells.insert(TKCellMap::value_type(newFqnName.toStdString(), cell));
487 bool DCContainer::moveCell(DCCell *cell, const QString& pageNewContainerBasedPathName)
489 QString oldFqnName = DCUtil::getFQNPath(cell->getLocation(), cell->getName());
490 QString oldContainerPath = QString::fromStdString(cell->getLocation());
492 if (oldContainerPath == pageNewContainerBasedPathName)
495 QString customScript = readCustomScriptFromWorkFile(cell);
496 QFile workFileOld(getWorkFilePathForCustomScript(cell));
498 cell->changePath(pageNewContainerBasedPathName);
499 if (!saveCustomScriptToWorkFile(cell, customScript.toStdString()))
501 cell->changePath(oldContainerPath);
504 workFileOld.remove();
505 mCells.erase(oldFqnName.toStdString());
507 QString newFqnName = DCUtil::getFQNPath(pageNewContainerBasedPathName.toStdString(), cell->getName());
508 std::pair<TKCellMap::iterator, bool> r = mCells.insert(TKCellMap::value_type(newFqnName.toStdString(), cell));
512 bool DCContainer::renameCellCodeClass(DCCellCode *cellcode, const QString &newName)
514 QString oldFqnName = QString::fromStdString(cellcode->getFQNName());
515 QString oldPath = DCUtil::getContainerBasedPathFromFQNPath(oldFqnName);
516 QString oldName = DCUtil::getNameFromFQNPath(oldFqnName);
518 if (oldName == newName)
521 QFile oldFile(getWorkFilePathForCellCode(cellcode));
522 QString script = readCellCodeScriptFromFile(cellcode);
524 cellcode->changeName(newName);
525 if (!saveClassScriptToWorkFile(cellcode, script.toStdString()))
527 cellcode->changeName(oldName);
531 mCellCodes.erase(oldFqnName.toStdString());
533 std::pair<TKCellCodeMap::iterator, bool> r = mCellCodes.insert(TKCellCodeMap::value_type(cellcode->getFQNName(), cellcode));
538 bool DCContainer::moveCellCodeClass(DCCellCode *cellcode, const QString& pageNewContainerBasedPathName)
540 QString oldFqnName = QString::fromStdString(cellcode->getFQNName());
541 QString oldPath = DCUtil::getContainerBasedPathFromFQNPath(oldFqnName);
542 QString oldName = DCUtil::getNameFromFQNPath(oldFqnName);
544 if (oldPath == pageNewContainerBasedPathName)
547 QFile oldFile(getWorkFilePathForCellCode(cellcode));
548 QString script = readCellCodeScriptFromFile(cellcode);
550 cellcode->changePath(pageNewContainerBasedPathName);
551 if (!saveClassScriptToWorkFile(cellcode, script.toStdString()))
553 cellcode->changePath(oldPath);
557 mCellCodes.erase(oldFqnName.toStdString());
559 std::pair<TKCellCodeMap::iterator, bool> r = mCellCodes.insert(TKCellCodeMap::value_type(cellcode->getFQNName(), cellcode));
564 DCVCPage* DCContainer::movePage(const QString &oldContainerBasedPathName, const QString &newContainerBasedPathName)
567 DCVCPage *newPage = NULL;
568 DCScene *scene = getScene();
571 DCVCPage *oldPage = getScene()->getPage(oldContainerBasedPathName.toStdString());
572 newPage = getScene()->addPage(newContainerBasedPathName.toStdString());
574 if (oldPage && newPage)
576 r = oldPage->moveComponentsTo(newPage);
580 QString sysOldFilePath = containerBasedPathToSysFilePath(oldContainerBasedPathName);
581 QString sceneSettingFilePath = scene->getSceneSettingFilePathForPage(oldPage);
582 if (!DCTreeViewWidget::removeFile(sysOldFilePath))
587 dir.remove(sceneSettingFilePath);
589 if (!scene->removePage(oldPage))
596 return r ? newPage : NULL;
600 QList<QString> DCContainer::getAvailableCellTypes() const
604 list.append(QString::fromStdString(TKContainer::CELLTYPE_JSBASIC));
605 list.append(QString::fromStdString(TKContainer::CELLTYPE_BASICSTORAGE));
606 list.append(QString::fromStdString(TKContainer::CELLTYPE_IN));
607 list.append(QString::fromStdString(TKContainer::CELLTYPE_OUT));
608 list.append(QString::fromStdString(TKContainer::CELLTYPE_PLUGIN_IN));
609 list.append(QString::fromStdString(TKContainer::CELLTYPE_PLUGIN_OUT));
614 QList<QString> DCContainer::getAvailableScriptableCellTypes() const
618 list.append(QString::fromStdString(TKContainer::CELLTYPE_JSBASIC));
619 list.append(QString::fromStdString(TKContainer::CELLTYPE_BASICSTORAGE));
624 bool DCContainer::getIsScriptable(const QString& type) const
626 std::string t = type.toStdString();
628 if (t == TKContainer::CELLTYPE_JSBASIC)
632 else if (t == TKContainer::CELLTYPE_BASICSTORAGE)
636 else if (t == TKContainer::CELLTYPE_IN)
640 else if (t == TKContainer::CELLTYPE_OUT)
644 else if (t == TKContainer::CELLTYPE_PLUGIN_IN)
648 else if (t == TKContainer::CELLTYPE_PLUGIN_OUT)
657 bool DCContainer::getIsReceptorAvailable(const QString& type) const
659 std::string t = type.toStdString();
661 if (t == TKContainer::CELLTYPE_JSBASIC)
665 else if (t == TKContainer::CELLTYPE_BASICSTORAGE)
669 else if (t == TKContainer::CELLTYPE_IN)
673 else if (t == TKContainer::CELLTYPE_OUT)
677 else if (t == TKContainer::CELLTYPE_PLUGIN_IN)
681 else if (t == TKContainer::CELLTYPE_PLUGIN_OUT)
689 QString DCContainer::getWorkFilePathForCustomScript(const DCCell *cell) const
691 QDir workdir(d_workDirCellRoot + QString::fromStdString(cell->getLocation()));
692 return workdir.absoluteFilePath(QString::fromStdString(cell->getName()) + ".js");
695 QString DCContainer::getWorkFilePathForCellCode(const DCCellCode *cellCode) const
697 QString qNamePath = QString::fromStdString(cellCode->getFQNName());
698 QString path = DCUtil::getContainerBasedPathFromFQNPath(qNamePath);
699 QString name = DCUtil::getNameFromFQNPath(qNamePath);
701 QDir workdir(d_workDirCellCodeRoot + path);
702 return workdir.absoluteFilePath(name + ".js");
705 bool DCContainer::getIsPluginType(const QString &type) const
707 std::string t = type.toStdString();
709 if (t == TKContainer::CELLTYPE_PLUGIN_IN)
713 else if (t == TKContainer::CELLTYPE_PLUGIN_OUT)
721 QList<QString> DCContainer::getAvailablePluginLibraries() const
727 QList<QString> DCContainer::getPreDefinedPluginVariablesForPlugin(const QString& libraryName) const
733 QString DCContainer::createPluginCellName(const QString &name, const QString& type, const QString &libraryName)
735 QString cellName = name;
737 if (type == QString::fromStdString(TKContainer::CELLTYPE_PLUGIN_IN))
740 cellName += libraryName;
742 else if (type == QString::fromStdString(TKContainer::CELLTYPE_PLUGIN_OUT))
745 cellName += libraryName;