kjsembed
kjsembed.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2005, 2006 Ian Reinhart Geiser <geiseri@kde.org> 00003 Copyright (C) 2005, 2006 Matt Broadstone <mbroadst@gmail.com> 00004 Copyright (C) 2005, 2006 Richard J. Moore <rich@kde.org> 00005 Copyright (C) 2005, 2006 Erik L. Bunce <kde@bunce.us> 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License as published by the Free Software Foundation; either 00010 version 2 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Library General Public License for more details. 00016 00017 You should have received a copy of the GNU Library General Public License 00018 along with this library; see the file COPYING.LIB. If not, write to 00019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00020 Boston, MA 02110-1301, USA. 00021 */ 00022 #include "kjsembed.h" 00023 #include "binding_support.h" 00024 00025 #include "qobject_binding.h" 00026 #include "variant_binding.h" 00027 #include "static_binding.h" 00028 00029 #include "iosupport.h" 00030 #include "quiloader_binding.h" 00031 #ifdef KJSEMBED_FORMBUILDER_BINDING 00032 #include "qformbuilder_binding.h" 00033 #endif 00034 #include "qpainter_binding.h" 00035 #include "qwidget_binding.h" 00036 #include "qaction_binding.h" 00037 #include "qlayout_binding.h" 00038 #include "svg_binding.h" 00039 #include "filedialog_binding.h" 00040 #include "settings.h" 00041 #include "fileio.h" 00042 #include "color.h" 00043 #include "rect.h" 00044 #include "size.h" 00045 #include "point.h" 00046 #include "image.h" 00047 #include "pixmap.h" 00048 #include "brush.h" 00049 #include "pen.h" 00050 #include "font.h" 00051 #include "dom.h" 00052 #include "url.h" 00053 #include "application.h" 00054 00055 #include "builtins.h" 00056 00057 #include <kjs/interpreter.h> 00058 #include <kjs/completion.h> 00059 00060 #include <QtCore/QFile> 00061 #include <QtCore/QTextStream> 00062 #include <QtCore/QObject> 00063 00064 #include <QtCore/QDebug> 00065 00066 00073 namespace KJS { 00074 #ifndef QTONLY_WEBKIT 00075 UString::UString( const QString &d ) 00076 { 00077 uint len = d.length(); 00078 UChar *dat = static_cast<UChar*>(fastMalloc(sizeof(UChar)*len)); 00079 memcpy( dat, d.unicode(), len * sizeof(UChar) ); 00080 m_rep = UString::Rep::create(dat, len); 00081 } 00082 00083 QString UString::qstring() const 00084 { 00085 return QString((QChar*) data(), size()); 00086 } 00087 00088 QString Identifier::qstring() const 00089 { 00090 return QString((QChar*) data(), size()); 00091 } 00092 #endif 00093 } 00094 00095 namespace KJSEmbed { 00096 00097 class EnginePrivate { 00098 public: 00099 EnginePrivate ( ) 00100 { 00101 m_interpreter = new KJS::Interpreter( ); 00102 m_interpreter->initGlobalObject(); 00103 m_interpreter->ref(); 00104 } 00105 ~EnginePrivate() 00106 { 00107 m_interpreter->deref(); 00108 } 00109 KJS::Interpreter *m_interpreter; 00110 KJS::Completion m_currentResult; 00111 bool m_bindingsEnabled; 00112 }; 00113 00114 void setup( KJS::ExecState *exec, KJS::JSObject *parent ) 00115 { 00116 StaticBinding::publish( exec, parent, IoFactory::methods() ); // Global methods 00117 StaticBinding::publish( exec, parent, FileDialog::methods() ); // Global methods 00118 StaticBinding::publish( exec, parent, BuiltinsFactory::methods() ); // Global methods 00119 StaticConstructor::add( exec, parent, FileIO::constructor() ); // Ctor 00120 StaticConstructor::add( exec, parent, DomNode::constructor() ); // Ctor 00121 StaticConstructor::add( exec, parent, DomDocument::constructor() ); // Ctor 00122 StaticConstructor::add( exec, parent, DomElement::constructor() ); // Ctor 00123 StaticConstructor::add( exec, parent, DomAttr::constructor() ); // Ctor 00124 StaticConstructor::add( exec, parent, DomDocumentType::constructor() ); // Ctor 00125 StaticConstructor::add( exec, parent, DomNodeList::constructor() ); // Ctor 00126 StaticConstructor::add( exec, parent, DomNamedNodeMap::constructor() ); // Ctor 00127 StaticConstructor::add( exec, parent, DomText::constructor() ); // Ctor 00128 StaticConstructor::add( exec, parent, Url::constructor() ); // Ctor 00129 StaticConstructor::add( exec, parent, SettingsBinding::constructor() ); // Ctor 00130 StaticConstructor::add( exec, parent, CoreApplicationBinding::constructor() ); 00131 StaticConstructor::add( exec, parent, Point::constructor() ); // Ctor 00132 StaticConstructor::add( exec, parent, Size::constructor() ); // Ctor 00133 StaticConstructor::add( exec, parent, Rect::constructor() ); // Ctor 00134 StaticConstructor::add( exec, parent, Color::constructor() ); // Ctor 00135 00136 // check if this is a GUI application 00137 QApplication* app = ::qobject_cast<QApplication*>(QCoreApplication::instance()); 00138 if (app && (app->type() != QApplication::Tty)) 00139 { 00140 //qDebug("Loading GUI Bindings"); 00141 00142 #ifdef KJSEMBED_FORMBUILDER_BINDING 00143 StaticConstructor::add( exec, parent, FormBuilder::constructor() ); // Ctor 00144 #endif 00145 StaticConstructor::add( exec, parent, UiLoaderBinding::constructor() ); // Ctor 00146 StaticConstructor::add( exec, parent, QWidgetBinding::constructor() ); // Ctor 00147 StaticConstructor::add( exec, parent, Layout::constructor() ); // Ctor 00148 StaticConstructor::add( exec, parent, Action::constructor() ); // Ctor 00149 StaticConstructor::add( exec, parent, ActionGroup::constructor() ); // Ctor 00150 StaticConstructor::add( exec, parent, Font::constructor() ); // Ctor 00151 StaticConstructor::add( exec, parent, Pen::constructor() ); // Ctor 00152 StaticConstructor::add( exec, parent, Brush::constructor() ); // Ctor 00153 StaticConstructor::add( exec, parent, Image::constructor() ); // Ctor 00154 StaticConstructor::add( exec, parent, Pixmap::constructor() ); // Ctor 00155 StaticConstructor::add( exec, parent, Painter::constructor() ); // Ctor 00156 StaticConstructor::add( exec, parent, SvgRenderer::constructor() ); // Ctor 00157 StaticConstructor::add( exec, parent, SvgWidget::constructor() ); // Ctor 00158 StaticConstructor::add( exec, parent, ApplicationBinding::constructor() ); 00159 } 00160 } 00161 00162 Engine::Engine( bool enableBindings ) 00163 { 00164 dptr = new EnginePrivate( ); 00165 if ( enableBindings ) 00166 setup( dptr->m_interpreter->globalExec(), dptr->m_interpreter->globalObject() ); 00167 dptr->m_bindingsEnabled = enableBindings; 00168 } 00169 00170 Engine::~Engine() 00171 { 00172 delete dptr; 00173 } 00174 00175 bool Engine::isBindingsEnabled() const 00176 { 00177 return dptr->m_bindingsEnabled; 00178 } 00179 00180 KJS::JSObject *Engine::addObject( QObject *obj, KJS::JSObject *parent, const KJS::UString &name ) const 00181 { 00182 KJS::ExecState *exec = dptr->m_interpreter->globalExec(); 00183 KJS::JSObject *returnObject = KJSEmbed::createQObject(exec , obj, KJSEmbed::ObjectBinding::CPPOwned ); 00184 KJS::Identifier jsName( !name.isEmpty() ? name : toUString(obj->objectName()) ); 00185 00186 parent->putDirect(jsName, returnObject, KJS::DontDelete|KJS::ReadOnly ); 00187 return returnObject; 00188 } 00189 00190 KJS::JSObject *Engine::addObject( QObject *obj, const KJS::UString &name ) const 00191 { 00192 return addObject( obj, dptr->m_interpreter->globalObject(), name ); 00193 } 00194 00195 KJS::Completion Engine::completion() const 00196 { 00197 return dptr->m_currentResult; 00198 } 00199 00200 KJS::Interpreter *Engine::interpreter() const 00201 { 00202 return dptr->m_interpreter; 00203 } 00204 00205 KJS::Completion Engine::runFile( KJS::Interpreter *interpreter, const KJS::UString &fileName ) 00206 { 00207 // qDebug() << "runFile: " << toQString(fileName); 00208 KJS::UString code; 00209 QFile file( toQString(fileName) ); 00210 if( file.open( QFile::ReadOnly ) ) 00211 { 00212 QTextStream ts( &file ); 00213 00214 QString line; 00215 while( !ts.atEnd() ) 00216 { 00217 line = ts.readLine(); 00218 if( line[0] != '#' ) code += toUString(line + '\n'); 00219 } 00220 file.close(); 00221 } 00222 else 00223 { 00224 code = "println('Could not open file.');"; 00225 qWarning() << "Could not open file " << toQString(fileName); 00226 } 00227 00228 // qDebug() << "Loaded code: " << toQString(code); 00229 00230 return interpreter->evaluate( fileName, 0, code, 0 ); 00231 } 00232 00233 Engine::ExitStatus Engine::runFile( const KJS::UString &fileName ) 00234 { 00235 dptr->m_currentResult = runFile( dptr->m_interpreter, fileName ); 00236 00237 if( dptr->m_currentResult.complType() == KJS::Normal ) 00238 return Engine::Success; 00239 else if ( dptr->m_currentResult.complType() == KJS::ReturnValue) 00240 return Engine::Success; 00241 else 00242 return Engine::Failure; 00243 } 00244 00245 Engine::ExitStatus Engine::execute( const KJS::UString &code ) 00246 { 00247 dptr->m_currentResult = dptr->m_interpreter->evaluate(KJS::UString(""), 0, code, 0); 00248 if( dptr->m_currentResult.complType() == KJS::Normal ) 00249 return Engine::Success; 00250 else if ( dptr->m_currentResult.complType() == KJS::ReturnValue) 00251 return Engine::Success; 00252 else 00253 return Engine::Failure; 00254 } 00255 00256 KJS::JSObject *Engine::construct( const KJS::UString &className, const KJS::List &args ) const 00257 { 00258 KJS::JSObject *global = dptr->m_interpreter->globalObject(); 00259 KJS::ExecState *exec = dptr->m_interpreter->globalExec(); 00260 return StaticConstructor::construct( exec, global, className, args ); 00261 } 00262 00263 KJS::JSValue *Engine::callMethod( const KJS::UString &methodName, const KJS::List &args ) 00264 { 00265 KJS::JSObject *global = dptr->m_interpreter->globalObject(); 00266 KJS::ExecState *exec = dptr->m_interpreter->globalExec(); 00267 00268 KJS::Identifier id = KJS::Identifier( KJS::UString( methodName ) ); 00269 KJS::JSObject *fun = global->get( exec, id )->toObject( exec ); 00270 KJS::JSValue *retValue; 00271 00272 if ( !fun->implementsCall() ) { 00273 QString msg = i18n( "%1 is not a function and cannot be called.", toQString(methodName) ); 00274 return throwError( exec, KJS::TypeError, msg ); 00275 } 00276 00277 retValue = fun->call( exec, global, args ); 00278 00279 if( exec->hadException() ) 00280 return exec->exception(); 00281 00282 return retValue; 00283 } 00284 00285 KJS::JSValue *Engine::callMethod( KJS::JSObject *parent, 00286 const KJS::UString &methodName, const KJS::List &args ) 00287 { 00288 KJS::ExecState *exec = dptr->m_interpreter->globalExec(); 00289 00290 KJS::Identifier id = KJS::Identifier( methodName); 00291 KJS::JSObject *fun = parent->get( exec, id )->toObject( exec ); 00292 KJS::JSValue *retValue; 00293 00294 if ( !fun->implementsCall() ) { 00295 QString msg = i18n( "%1 is not a function and cannot be called.", toQString(methodName) ); 00296 return throwError( exec, KJS::TypeError, msg ); 00297 } 00298 00299 retValue = fun->call( exec, parent, args ); 00300 00301 if( exec->hadException() ) 00302 return exec->exception(); 00303 00304 return retValue; 00305 } 00306 00307 00308 } // namespace KJS 00309 00310 //kate: indent-spaces on; indent-width 4; replace-tabs on; indent-mode cstyle;
KDE 4.6 API Reference