You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/lib/kross/main/scriptcontainer.cpp

294 lines
8.0 KiB

/***************************************************************************
* 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'").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;
}
TQMap<TQString, TQVariant>& 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;
}