/*************************************************************************** * scriptcontainer.cpp * This file is part of the KDE project * copyright (C)2004-2005 by Sebastian Sauer (mail@dipe.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * You should have received a copy of the GNU Library General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. ***************************************************************************/ #include "scriptcontainer.h" #include "../api/object.h" #include "../api/list.h" #include "../api/interpreter.h" #include "../api/script.h" #include "../main/manager.h" #include "mainmodule.h" #include <tqfile.h> #include <tdelocale.h> using namespace Kross::Api; namespace Kross { namespace Api { /// @internal class ScriptContainerPrivate { public: /** * The \a Script instance the \a ScriptContainer uses * if initialized. It will be NULL as long as we * didn't initialized it what will be done on * demand. */ Script* script; /** * The unique name the \a ScriptContainer is * reachable as. */ TQString name; /** * The scripting code. */ TQString code; /** * The name of the interpreter. This could be * something like "python" for the python * binding. */ TQString interpretername; /** * The name of the scriptfile that should be * executed. Those scriptfile will be readed * and the content will be used to set the * scripting code and, if not defined, the * used interpreter. */ TQString scriptfile; /** * Map of options that overwritte the \a InterpreterInfo::Option::Map * standard options. */ TQStringVariantMap options; }; }} ScriptContainer::ScriptContainer(const TQString& name) : MainModule(name) , d( new ScriptContainerPrivate() ) // initialize d-pointer class { //krossdebug( TQString("ScriptContainer::ScriptContainer() Ctor name='%1'").arg(name) ); d->script = 0; d->name = name; } ScriptContainer::~ScriptContainer() { //krossdebug( TQString("ScriptContainer::~ScriptContainer() Dtor name='%1'").arg(d->name) ); finalize(); delete d; } const TQString ScriptContainer::getName() const { return d->name; } void ScriptContainer::setName(const TQString& name) { d->name = name; } TQString ScriptContainer::getCode() const { return d->code; } void ScriptContainer::setCode(const TQString& code) { finalize(); d->code = code; } TQString ScriptContainer::getInterpreterName() const { return d->interpretername; } void ScriptContainer::setInterpreterName(const TQString& interpretername) { finalize(); d->interpretername = interpretername; } TQString ScriptContainer::getFile() const { return d->scriptfile; } void ScriptContainer::setFile(const TQString& scriptfile) { finalize(); d->scriptfile = scriptfile; } TQStringVariantMap& ScriptContainer::getOptions() { return d->options; } TQVariant ScriptContainer::getOption(const TQString name, TQVariant defaultvalue, bool /*recursive*/) { if(d->options.contains(name)) return d->options[name]; Kross::Api::InterpreterInfo* info = Kross::Api::Manager::scriptManager()->getInterpreterInfo( d->interpretername ); return info ? info->getOptionValue(name, defaultvalue) : defaultvalue; } bool ScriptContainer::setOption(const TQString name, const TQVariant& value) { Kross::Api::InterpreterInfo* info = Kross::Api::Manager::scriptManager()->getInterpreterInfo( d->interpretername ); if(info) { if(info->hasOption(name)) { d->options.replace(name, value); return true; } else krosswarning( TQString("Kross::Api::ScriptContainer::setOption(%1, %2): No such option").arg(name).arg(value.toString()) ); } else krosswarning( TQString("Kross::Api::ScriptContainer::setOption(%1, %2): No such interpreterinfo").arg(name).arg(value.toString()) ); return false; } Object::Ptr ScriptContainer::execute() { if(! d->script) if(! initialize()) return 0; if(hadException()) return 0; Object::Ptr r = d->script->execute(); if(d->script->hadException()) { setException( d->script->getException() ); finalize(); return 0; } return r; } const TQStringList ScriptContainer::getFunctionNames() { return d->script ? d->script->getFunctionNames() : TQStringList(); //FIXME init before if needed? } Object::Ptr ScriptContainer::callFunction(const TQString& functionname, List::Ptr arguments) { if(! d->script) if(! initialize()) return 0; if(hadException()) return 0; if(functionname.isEmpty()) { setException( new Exception(i18n("No functionname defined for ScriptContainer::callFunction().")) ); finalize(); return 0; } Object::Ptr r = d->script->callFunction(functionname, arguments); if(d->script->hadException()) { setException( d->script->getException() ); finalize(); return 0; } return r; } TQStringList ScriptContainer::getClassNames() { return d->script ? d->script->getClassNames() : TQStringList(); //FIXME init before if needed? } Object::Ptr ScriptContainer::classInstance(const TQString& classname) { if(! d->script) if(! initialize()) return 0; if(hadException()) return 0; Object::Ptr r = d->script->classInstance(classname); if(d->script->hadException()) { setException( d->script->getException() ); finalize(); return 0; } return r; } bool ScriptContainer::initialize() { finalize(); if(! d->scriptfile.isNull()) { krossdebug( TQString("Kross::Api::ScriptContainer::initialize() file=%1").arg(d->scriptfile) ); if(d->interpretername.isNull()) { d->interpretername = Manager::scriptManager()->getInterpreternameForFile( d->scriptfile ); if(d->interpretername.isNull()) { setException( new Exception(i18n("Failed to determinate interpreter for scriptfile '%1'").arg(d->scriptfile)) ); return false; } } TQFile f( d->scriptfile ); if(! f.open(IO_ReadOnly)) { setException( new Exception(i18n("Failed to open scriptfile '%1'").arg(d->scriptfile)) ); return false; } d->code = TQString( f.readAll() ); f.close(); } Interpreter* interpreter = Manager::scriptManager()->getInterpreter(d->interpretername); if(! interpreter) { setException( new Exception(i18n("Unknown interpreter '%1'").arg(d->interpretername)) ); return false; } d->script = interpreter->createScript(this); if(! d->script) { setException( new Exception(i18n("Failed to create script for interpreter '%1'").arg(d->interpretername)) ); return false; } if(d->script->hadException()) { setException( d->script->getException() ); finalize(); return false; } setException( 0 ); // clear old exception return true; } void ScriptContainer::finalize() { delete d->script; d->script = 0; }