|
|
|
/***************************************************************************
|
|
|
|
* 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 <klocale.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.
|
|
|
|
*/
|
|
|
|
TQMap<TQString, TQVariant> options;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
ScriptContainer::ScriptContainer(const TQString& name)
|
|
|
|
: MainModule(name)
|
|
|
|
, d( new ScriptContainerPrivate() ) // initialize d-pointer class
|
|
|
|
{
|
|
|
|
//krossdebug( TQString("ScriptContainer::ScriptContainer() Ctor name='%1'").tqarg(name) );
|
|
|
|
|
|
|
|
d->script = 0;
|
|
|
|
d->name = name;
|
|
|
|
}
|
|
|
|
|
|
|
|
ScriptContainer::~ScriptContainer()
|
|
|
|
{
|
|
|
|
//krossdebug( TQString("ScriptContainer::~ScriptContainer() Dtor name='%1'").tqarg(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;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQMap<TQString, TQVariant>& ScriptContainer::getOptions()
|
|
|
|
{
|
|
|
|
return d->options;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQVariant ScriptContainer::getOption(const TQString name, TQVariant defaultvalue, bool /*recursive*/)
|
|
|
|
{
|
|
|
|
if(d->options.tqcontains(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.tqreplace(name, value);
|
|
|
|
return true;
|
|
|
|
} else krosswarning( TQString("Kross::Api::ScriptContainer::setOption(%1, %2): No such option").tqarg(name).tqarg(value.toString()) );
|
|
|
|
} else krosswarning( TQString("Kross::Api::ScriptContainer::setOption(%1, %2): No such interpreterinfo").tqarg(name).tqarg(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").tqarg(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'").tqarg(d->scriptfile)) );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQFile f( d->scriptfile );
|
|
|
|
if(! f.open(IO_ReadOnly)) {
|
|
|
|
setException( new Exception(i18n("Failed to open scriptfile '%1'").tqarg(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'").tqarg(d->interpretername)) );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
d->script = interpreter->createScript(this);
|
|
|
|
if(! d->script) {
|
|
|
|
setException( new Exception(i18n("Failed to create script for interpreter '%1'").tqarg(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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|