diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 90825e2392b2d70e43c7a25b8a3752299a933894 (patch) | |
tree | e33aa27f02b74604afbfd0ea4f1cfca8833d882a /kjsembed/kjsembedpart.cpp | |
download | tdebindings-90825e2392b2d70e43c7a25b8a3752299a933894.tar.gz tdebindings-90825e2392b2d70e43c7a25b8a3752299a933894.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebindings@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kjsembed/kjsembedpart.cpp')
-rw-r--r-- | kjsembed/kjsembedpart.cpp | 449 |
1 files changed, 449 insertions, 0 deletions
diff --git a/kjsembed/kjsembedpart.cpp b/kjsembed/kjsembedpart.cpp new file mode 100644 index 00000000..319bfde8 --- /dev/null +++ b/kjsembed/kjsembedpart.cpp @@ -0,0 +1,449 @@ +/* + * Copyright (C) 2001-2003, Richard J. Moore <rich@kde.org> + * + * This library 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 library 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 library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#include <qobject.h> +#include <qdialog.h> +#include <qfile.h> +#include <qtextstream.h> +#include <qwidget.h> +#include <qwidgetfactory.h> + +#ifndef QT_ONLY +#include <kaction.h> +#endif // QT_ONLY + +#include <kjs/interpreter.h> +#include <kjs/object.h> +#include <kjs/ustring.h> +#include <kjs/types.h> +#include <kjs/value.h> + +#include "global.h" +#include "jsfactory.h" +#include "jsbinding.h" +#include "jsobjectproxy.h" +#include "jsconsolewidget.h" +#include "jsbuiltin.h" + +#ifndef QT_ONLY +#include "bindings/image_imp.h" +#endif // QT_ONLY + +#include "kjsembedpart_imp.h" +#include "kjsembedpart.h" + +#ifndef QT_ONLY + +#include "kjsembedpart.moc" + +namespace KJSEmbed { + +class KJSEmbedActionRunner : public XMLActionRunner +{ +public: + KJSEmbedActionRunner( KJSEmbedPart *jspart ) : XMLActionRunner(), part(jspart) {} + virtual ~KJSEmbedActionRunner() {} + + virtual bool run( XMLActionClient *client, const XMLActionClient::XMLActionScript &script ) { + if ( script.type == "js" ) + return part->runFile( script.src ); + else + return XMLActionRunner::run( client, script ); + } + +private: + KJSEmbedPart *part; +}; + +} // namespace KJSEmbed + +#else // QT_ONLY + +#include "qtstubs.h" + +#endif // QT_ONLY + +namespace KJSEmbed { + +// +// KPart +// + +KJSEmbedPart::KJSEmbedPart( QObject *parent, const char *name ) + : KParts::ReadOnlyPart( parent, name ? name : "kjsembed_part" ), + jsConsole(0), jsfactory(0), + widgetparent(0), widgetname(name ? name : "kjsembed_part"), deletejs(false) +{ + createInterpreter(); + createBuiltIn( js->globalExec(), js->globalObject() ); + createActionClient(); +} + +KJSEmbedPart::KJSEmbedPart( QWidget *wparent, const char *wname, QObject *parent, const char *name ) + : KParts::ReadOnlyPart( parent, name ? name : (wname?wname:"jsembed_part") ), + jsConsole(0), jsfactory(0), + widgetparent(wparent), widgetname(wname), deletejs(false) +{ + createInterpreter(); + createBuiltIn( js->globalExec(), js->globalObject() ); + createActionClient(); +} + +KJSEmbedPart::KJSEmbedPart( KJS::Interpreter *jsi, QWidget *wparent, const char *wname, + QObject *parent, const char *name ) + : KParts::ReadOnlyPart( parent, name ? name : (wname?wname:"jsembed_part") ), + jsConsole(0), jsfactory(0), builtins(0), + widgetparent(wparent), widgetname(wname), js(jsi), deletejs(false) +{ + if ( !js ) { + createInterpreter(); + createBuiltIn( js->globalExec(), js->globalObject() ); + } + createActionClient(); +} + +KJSEmbedPart::~KJSEmbedPart() +{ + if ( deletejs ) + delete js; + delete jsfactory; + delete builtins; +} + +void KJSEmbedPart::createInterpreter() +{ + deletejs = true; + js = new KJS::Interpreter(); + + jsfactory = new JSFactory( this ); + jsfactory->addType( className() ); + jsfactory->addTypes( js->globalExec(), js->globalObject() ); +} + +void KJSEmbedPart::createBuiltIn( KJS::ExecState *exec, KJS::Object &parent ) +{ + partobj = addObject( this, parent, "part" ); + + builtins = new JSBuiltIn( this ); + builtins->add( exec, parent ); +} + +void KJSEmbedPart::createActionClient() +{ +#ifndef QT_ONLY + xmlclient = new KJSEmbed::XMLActionClient( this ); + xmlclient->setActionCollection( actionCollection() ); + xmlclient->setRunner( new KJSEmbedActionRunner(this) ); +#endif // QT_ONLY +} + +JSConsoleWidget *KJSEmbedPart::view() +{ +#ifndef QT_ONLY + if ( !jsConsole ) { + QCString name = widgetname ? widgetname : QCString("jsembed_console"); + jsConsole = new JSConsoleWidget( this, widgetparent, name ); + setWidget( jsConsole ); + jsfactory->addType( jsConsole->className() ); + } + return jsConsole; +#endif // QT_ONLY +return 0L; +} + +QStringList KJSEmbedPart::constructorNames() const +{ + QStringList classes; + + KJS::List cons = constructorList(); + KJS::ListIterator it = cons.begin(); + while ( it != cons.end() ) { + KJS::Value v = *it; + classes += v.toString( js->globalExec() ).qstring(); + it++; + } + + return classes; +} + +KJS::Value KJSEmbedPart::constructors() const +{ + KJS::List items = constructorList(); + kdDebug(80001) << "KJSEmbedPart::constructors() returning " << items.size() << " items" << endl; + return KJS::Object( js->builtinArray().construct( js->globalExec(), items ) ); +} + +KJS::List KJSEmbedPart::constructorList() const +{ + KJS::List items; + + KJS::Object obj = js->globalObject(); + KJS::ExecState *exec = js->globalExec(); + + KJS::ReferenceList l = obj.propList( exec ); + KJS::ReferenceListIterator propIt = l.begin(); + while ( propIt != l.end() ) { + + KJS::Identifier name = propIt->getPropertyName( exec ); + + if ( obj.hasProperty( exec, name ) ) { + KJS::Value v = obj.get( exec, name ); + KJS::Object vobj = v.toObject( exec ); + + if ( vobj.implementsConstruct() ) + items.append( KJS::String( name.ustring() ) ); + } + + propIt++; + } + + return items; +} + +// +// Version information +// + +QCString KJSEmbedPart::versionString() const +{ + return QCString(KJSEMBED_VERSION_STRING); +} + +int KJSEmbedPart::versionMajor() const +{ + return KJSEMBED_VERSION_MAJOR; +} + +int KJSEmbedPart::versionMinor() const +{ + return KJSEMBED_VERSION_MINOR; +} + +// +// Execute a JS script. +// + +KJS::Value KJSEmbedPart::evaluate( const QString &script, const KJS::Value &self ) +{ + if ( execute( res, script, self ) ) + return res.value(); + + return KJS::Null(); +} + +bool KJSEmbedPart::execute( const QString &script, const KJS::Value &self ) +{ + return execute( res, script, self ); +} + +bool KJSEmbedPart::execute( KJS::Completion &result, const QString &script, const KJS::Value &self ) +{ + KJS::Value val( self ); + result = js->evaluate( script, self.isNull() ? partobj : val ); + return (result.complType() == KJS::Normal) || (result.complType() == KJS::ReturnValue); +} + +bool KJSEmbedPart::openURL( const KURL &url ) +{ + if ( url.protocol() == "javascript" ) { +// kdDebug(80001) << "KJSEmbedPart: openURL '" << url.url() << "' is javascript" << endl; + +#ifndef QT_ONLY + QString cmd = url.url(); +#else + QString cmd = url.toString(); +#endif + + QString js( "javascript:" ); + cmd = cmd.replace( 0, js.length(), QString("") ); + +// kdDebug(80001) << "KJSEmbedPart: JS command is '" << cmd << "'" << endl; + return execute( cmd ); + } + return false; +} + +// +// Invoke a script file. +// + +bool KJSEmbedPart::runFile( const QString &name, const KJS::Value &self ) +{ + kdDebug(80001) << "KJSEmbedPart::runFile(): file is '" << name << "'" << endl; + QString script = loadFile( name ); + return execute( script, self ); +} + +bool KJSEmbedPart::loadActionSet( const QString &file ) +{ +#ifndef QT_ONLY + return xmlclient->load( file ); +#else // QT_ONLY + Q_UNUSED( file ); + return false; +#endif // QT_ONLY +} + +QString KJSEmbedPart::loadFile( const QString &src ) +{ + QString script; + + if ( src == "-" ) { + QTextStream ts( stdin, IO_ReadOnly ); + script = ts.read(); + } + else { + QFile file( src ); + if ( file.open( IO_ReadOnly ) ) { + script = QString( file.readAll() ); + } + else { + kdWarning() << "Could not open file '" << src << "', " + << strerror( errno ) << endl; + return QString::null; + } + } + + if ( script.startsWith( "#!" ) ) { + int pos = script.find( "\n" ); + if ( pos > 0 ) + script = script.mid( pos ); + } + + return script; +} + +// +// Publishing objects. +// + +KJS::Object KJSEmbedPart::bind( QObject *obj ) +{ + KJS::Object jsobj = jsfactory->createProxy( js->globalExec(), obj ); + JSProxy::toObjectProxy(jsobj.imp() )->setOwner(JSProxy::Native); + return jsobj; +} + +KJS::Object KJSEmbedPart::addObject( QObject *obj, KJS::Object &parent, const char *name ) +{ + KJS::Object jsobj = bind( obj ); + parent.put( js->globalExec(), name ? name : obj->name(), jsobj ); + + return jsobj; +} + +KJS::Object KJSEmbedPart::addObject( QObject *obj, const char *name ) +{ + return addObject( obj, js->globalObject(), name ); +} + +void KJSEmbedPart::virtual_hook( int /*id*/, void * /*data*/ ) +{ + +} + +static KJS::Object scopeWalker( KJS::ExecState *exec, const KJS::Object &root, const QString &objectString ) +{ + KJS::Object returnObject = root; + QStringList objects = QStringList::split(".", objectString); + for( uint idx = 0; idx < objects.count(); ++idx) + { + KJS::Identifier id = KJS::Identifier( KJS::UString( objects[idx] )); + KJS::Value newObject = returnObject.get(exec, id ); + if( newObject.isValid() ) + returnObject = newObject.toObject(exec); + } + return returnObject; +} + +KJS::Value KJSEmbedPart::callMethod( const QString & methodName, const KJS::List & args ) const +{ + KJS::ExecState *exec = js->globalExec(); + KJS::Identifier id = KJS::Identifier( KJS::UString(methodName.latin1() )); + KJS::Object obj = js->globalObject(); + KJS::Object fun = obj.get(exec, id ).toObject( exec ); + KJS::Value retValue; + if ( !fun.implementsCall() ) + { + // We need to create an exception here... + } + else + retValue = fun.call(exec, obj, args); + kdDebug( 80001 ) << "Returned type is: " << retValue.type() << endl; + if( exec->hadException() ) + { + kdWarning( 80001 ) << "Got error: " << exec->exception().toString(exec).qstring() << endl; + return exec->exception(); + } + else + { + if( retValue.type() == 1 && retValue.type() == 0) + { + kdDebug( 80001 ) << "Got void return type. " << endl; + return KJS::Null(); + } + } + return retValue; +} + +KJS::Value KJSEmbedPart::getValue( const QString & valueName ) const +{ + KJS::ExecState *exec = js->globalExec(); + KJS::Identifier id = KJS::Identifier( KJS::UString(valueName.latin1() )); + KJS::Object obj = js->globalObject(); + return obj.get(exec, id ); +} + +void KJSEmbedPart::putValue( const QString & valueName, const KJS::Value & value ) +{ + KJS::ExecState *exec = js->globalExec(); + KJS::Identifier id = KJS::Identifier( KJS::UString(valueName.latin1() )); + KJS::Object obj = js->globalObject(); + obj.put(exec, id, value); +} + +void KJSEmbedPart::putVariant( const QString & valueName, const QVariant & value ) +{ + KJS::Value val = convertToValue( js->globalExec(), value); + putValue( valueName, val ); +} + +QVariant KJSEmbedPart::getVariant( const QString & valueName ) const +{ + return convertToVariant( js->globalExec(), getValue( valueName ) ); +} + +bool KJSEmbedPart::hasMethod( const QString & methodName ) +{ + KJS::ExecState *exec = js->globalExec(); + KJS::Identifier id = KJS::Identifier( KJS::UString(methodName.latin1() )); + KJS::Object obj = js->globalObject(); + KJS::Object fun = obj.get(exec, id ).toObject( exec ); + return fun.implementsCall(); +} + +}// namespace KJSEmbed + +// Local Variables: +// c-basic-offset: 4 +// End: |