#include "toonz/scriptbinding_scene.h" #include "toonz/scriptbinding_level.h" #include "toonz/scriptbinding_files.h" #include "toonz/txshleveltypes.h" #include "tsystem.h" #include "tfiletype.h" #include "toonz/tproject.h" #include "toonz/toonzscene.h" #include "toonz/txsheet.h" #include "toonz/txshcell.h" #include "toonz/levelset.h" namespace TScriptBinding { Scene::Scene() { m_scene = new ToonzScene(); TProjectManager::instance()->initializeScene(m_scene); } Scene::~Scene() { delete m_scene; } QScriptValue Scene::ctor(QScriptContext *context, QScriptEngine *engine) { QScriptValue obj = create(engine, new Scene()); if (context->argumentCount() == 1) { return obj.property("load").call(obj, context->argumentsObject()); } return obj; } QScriptValue Scene::toString() { return QString("Scene (%1 frames)").arg(getFrameCount()); } int Scene::getFrameCount() { return m_scene->getFrameCount(); } int Scene::getColumnCount() { return m_scene->getXsheet()->getColumnCount(); } QScriptValue Scene::load(const QScriptValue &fpArg) { TFilePath fp; QScriptValue err = checkFilePath(context(), fpArg, fp); if (err.isError()) return err; if (!fp.isAbsolute()) fp = TProjectManager::instance()->getCurrentProject()->getScenesPath() + fp; try { if (!TSystem::doesExistFileOrLevel(fp)) { return context()->throwError( tr("File %1 doesn't exist").arg(fpArg.toString())); } m_scene->load(fp); return context()->thisObject(); } catch (...) { return context()->throwError( tr("Exception reading %1").arg(fpArg.toString())); } } QScriptValue Scene::save(const QScriptValue &fpArg) { TFilePath fp; QScriptValue err = checkFilePath(context(), fpArg, fp); if (err.isError()) return err; if (!fp.isAbsolute()) fp = TProjectManager::instance()->getCurrentProject()->getScenesPath() + fp; try { m_scene->save(fp); return context()->thisObject(); } catch (...) { return context()->throwError( tr("Exception writing %1").arg(fpArg.toString())); } } QScriptValue Scene::getLevels() const { QScriptValue result = engine()->newArray(); qint32 index = 0; std::vector levels; m_scene->getLevelSet()->listLevels(levels); for (std::vector::iterator it = levels.begin(); it != levels.end(); ++it) { TXshSimpleLevel *sl = (*it)->getSimpleLevel(); if (sl) { Level *level = new Level(sl); result.setProperty(index++, create(engine(), level)); } } return result; } QScriptValue Scene::getLevel(const QString &name) const { TXshLevel *xl = m_scene->getLevelSet()->getLevel(name.toStdWString()); TXshSimpleLevel *sl = xl ? xl->getSimpleLevel() : 0; if (sl) { Level *level = new Level(sl); return create(engine(), level); } else return QScriptValue(); } QScriptValue Scene::newLevel(const QString &levelTypeStr, const QString &levelName) const { int levelType = NO_XSHLEVEL; if (levelTypeStr == "Vector") levelType = PLI_XSHLEVEL; else if (levelTypeStr == "ToonzRaster") levelType = TZP_XSHLEVEL; else if (levelTypeStr == "Raster") levelType = OVL_XSHLEVEL; if (levelType == NO_XSHLEVEL) return context()->throwError( tr("Bad level type (%1): must be Vector,Raster or ToonzRaster") .arg(levelTypeStr)); if (m_scene->getLevelSet()->hasLevel(levelName.toStdWString())) return context()->throwError( tr("Can't add the level: name(%1) is already used").arg(levelName)); TXshLevel *xl = m_scene->createNewLevel(levelType, levelName.toStdWString()); xl->getSimpleLevel()->setDirtyFlag(true); return create(engine(), new Level(xl->getSimpleLevel())); } QScriptValue Scene::loadLevel(const QString &levelName, const QScriptValue &fpArg) const { if (m_scene->getLevelSet()->hasLevel(levelName.toStdWString())) return context()->throwError( tr("Can't add the level: name(%1) is already used").arg(levelName)); TFilePath fp; QScriptValue err = checkFilePath(context(), fpArg, fp); if (err.isError()) return err; TFileType::Type type = TFileType::getInfo(fp); if ((type & TFileType::VIEWABLE) == 0) return context()->throwError( tr("Can't load this kind of file as a level : %1") .arg(fpArg.toString())); TXshLevel *xl = m_scene->loadLevel(fp); if (!xl || !xl->getSimpleLevel()) return context()->throwError( tr("Could not load level %1").arg(fpArg.toString())); return create(engine(), new Level(xl->getSimpleLevel())); } QString Scene::doSetCell(int row, int col, const QScriptValue &levelArg, const QScriptValue &fidArg) { if (row < 0 || col < 0) { return "Bad row/col values"; } QString err; TXshCell cell; cell.m_frameId = Level::getFid(fidArg, err); if (err != "") return err; Level *level = qscriptvalue_cast(levelArg); if (level) { TXshSimpleLevel *sl = level->getSimpleLevel(); TXshLevel *xl = m_scene->getLevelSet()->getLevel(sl->getName()); if (!xl || xl->getSimpleLevel() != sl) { return tr("Level is not included in the scene : %1") .arg(levelArg.toString()); } cell.m_level = sl; } else { if (!levelArg.isString()) return tr("%1 : Expected a Level instance or a level name") .arg(levelArg.toString()); QString levelName = levelArg.toString(); TXshLevel *xl = m_scene->getLevelSet()->getLevel(levelName.toStdWString()); if (!xl) return tr("Level '%1' is not included in the scene").arg(levelName); cell.m_level = xl; } m_scene->getXsheet()->setCell(row, col, cell); return ""; } QScriptValue Scene::setCell(int row, int col, const QScriptValue &level, const QScriptValue &fid) { QString err = doSetCell(row, col, level, fid); if (err != "") return context()->throwError(err); return context()->thisObject(); } QScriptValue Scene::setCell(int row, int col, const QScriptValue &cellArg) { if (cellArg.isUndefined()) { if (row >= 0 && col >= 0) m_scene->getXsheet()->setCell(row, col, TXshCell()); } else { if (!cellArg.isObject() || cellArg.property("level").isUndefined() || cellArg.property("fid").isUndefined()) return context()->throwError( "Third argument should be an object with attributes 'level' and " "'fid'"); QScriptValue levelArg = cellArg.property("level"); QScriptValue fidArg = cellArg.property("fid"); QString err = doSetCell(row, col, levelArg, fidArg); if (err != "") return context()->throwError(err); } return context()->thisObject(); } QScriptValue Scene::getCell(int row, int col) { TXshCell cell = m_scene->getXsheet()->getCell(row, col); TXshSimpleLevel *sl = cell.getSimpleLevel(); if (sl) { QScriptValue level = create(engine(), new Level(sl)); QScriptValue fid; if (cell.m_frameId.getLetter() == 0) fid = cell.m_frameId.getNumber(); else fid = QString::fromStdString(cell.m_frameId.expand()); QScriptValue result = engine()->newObject(); result.setProperty("level", level); result.setProperty("fid", fid); return result; } else { return QScriptValue(); } } QScriptValue Scene::insertColumn(int col) { m_scene->getXsheet()->insertColumn(col); return context()->thisObject(); } QScriptValue Scene::deleteColumn(int col) { m_scene->getXsheet()->removeColumn(col); return context()->thisObject(); } } // namespace TScriptBinding