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