#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<TXshLevel *> levels;
m_scene->getLevelSet()->listLevels(levels);
for (std::vector<TXshLevel *>::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<Level *>(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().isEmpty())
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