00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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 "bind_qlcdnumber.h"
00054 #include "bind_qtimer.h"
00055 #include "application.h"
00056
00057 #include "builtins.h"
00058
00059 #include <kjs/interpreter.h>
00060 #include <kjs/completion.h>
00061
00062 #include <QtCore/QFile>
00063 #include <QtCore/QTextStream>
00064 #include <QtCore/QObject>
00065
00066 #include <QtCore/QDebug>
00067
00068
00075 namespace KJS {
00076 #ifndef QTONLY_WEBKIT
00077 UString::UString( const QString &d )
00078 {
00079 uint len = d.length();
00080 UChar *dat = static_cast<UChar*>(fastMalloc(sizeof(UChar)*len));
00081 memcpy( dat, d.unicode(), len * sizeof(UChar) );
00082 m_rep = UString::Rep::create(dat, len);
00083 }
00084
00085 QString UString::qstring() const
00086 {
00087 return QString((QChar*) data(), size());
00088 }
00089
00090 QString Identifier::qstring() const
00091 {
00092 return QString((QChar*) data(), size());
00093 }
00094 #endif
00095 }
00096
00097 namespace KJSEmbed {
00098
00099 class EnginePrivate {
00100 public:
00101 EnginePrivate ( )
00102 {
00103 m_interpreter = new KJS::Interpreter( );
00104 m_interpreter->initGlobalObject();
00105 m_interpreter->ref();
00106 }
00107 ~EnginePrivate()
00108 {
00109 m_interpreter->deref();
00110 }
00111 KJS::Interpreter *m_interpreter;
00112 KJS::Completion m_currentResult;
00113 bool m_bindingsEnabled;
00114 };
00115
00116 void setup( KJS::ExecState *exec, KJS::JSObject *parent )
00117 {
00118 StaticBinding::publish( exec, parent, IoFactory::methods() );
00119 StaticBinding::publish( exec, parent, FileDialog::methods() );
00120 StaticBinding::publish( exec, parent, BuiltinsFactory::methods() );
00121 StaticConstructor::add( exec, parent, Timer::constructor() );
00122 StaticConstructor::add( exec, parent, FileIO::constructor() );
00123 StaticConstructor::add( exec, parent, DomNode::constructor() );
00124 StaticConstructor::add( exec, parent, DomDocument::constructor() );
00125 StaticConstructor::add( exec, parent, DomElement::constructor() );
00126 StaticConstructor::add( exec, parent, DomAttr::constructor() );
00127 StaticConstructor::add( exec, parent, DomDocumentType::constructor() );
00128 StaticConstructor::add( exec, parent, DomNodeList::constructor() );
00129 StaticConstructor::add( exec, parent, DomNamedNodeMap::constructor() );
00130 StaticConstructor::add( exec, parent, DomText::constructor() );
00131 StaticConstructor::add( exec, parent, Url::constructor() );
00132 StaticConstructor::add( exec, parent, SettingsBinding::constructor() );
00133 StaticConstructor::add( exec, parent, CoreApplicationBinding::constructor() );
00134 StaticConstructor::add( exec, parent, Point::constructor() );
00135 StaticConstructor::add( exec, parent, Size::constructor() );
00136 StaticConstructor::add( exec, parent, Rect::constructor() );
00137
00138
00139 QApplication* app =
00140 ::qobject_cast<QApplication*>(QCoreApplication::instance());
00141 if (app && (app->type() != QApplication::Tty))
00142 {
00143
00144
00145 #ifdef KJSEMBED_FORMBUILDER_BINDING
00146 StaticConstructor::add( exec, parent, FormBuilder::constructor() );
00147 #endif
00148 StaticConstructor::add( exec, parent, UiLoaderBinding::constructor() );
00149 StaticConstructor::add( exec, parent, QWidgetBinding::constructor() );
00150 StaticConstructor::add( exec, parent, Layout::constructor() );
00151 StaticConstructor::add( exec, parent, Action::constructor() );
00152 StaticConstructor::add( exec, parent, ActionGroup::constructor() );
00153 StaticConstructor::add( exec, parent, Font::constructor() );
00154 StaticConstructor::add( exec, parent, Pen::constructor() );
00155 StaticConstructor::add( exec, parent, Brush::constructor() );
00156 StaticConstructor::add( exec, parent, Image::constructor() );
00157 StaticConstructor::add( exec, parent, Pixmap::constructor() );
00158 StaticConstructor::add( exec, parent, Color::constructor() );
00159 StaticConstructor::add( exec, parent, Painter::constructor() );
00160 StaticConstructor::add( exec, parent, SvgRenderer::constructor() );
00161 StaticConstructor::add( exec, parent, SvgWidget::constructor() );
00162 StaticConstructor::add( exec, parent, LCDNumber::constructor() );
00163 StaticConstructor::add( exec, parent, ApplicationBinding::constructor() );
00164 }
00165 }
00166
00167 Engine::Engine( bool enableBindings )
00168 {
00169 dptr = new EnginePrivate( );
00170 if ( enableBindings )
00171 setup( dptr->m_interpreter->globalExec(), dptr->m_interpreter->globalObject() );
00172 dptr->m_bindingsEnabled = enableBindings;
00173 }
00174
00175 Engine::~Engine()
00176 {
00177 delete dptr;
00178 }
00179
00180 bool Engine::isBindingsEnabled() const
00181 {
00182 return dptr->m_bindingsEnabled;
00183 }
00184
00185 KJS::JSObject *Engine::addObject( QObject *obj, KJS::JSObject *parent, const KJS::UString &name ) const
00186 {
00187 KJS::ExecState *exec = dptr->m_interpreter->globalExec();
00188 KJS::JSObject *returnObject = KJSEmbed::createQObject(exec , obj, KJSEmbed::ObjectBinding::CPPOwned );
00189 KJS::Identifier jsName( !name.isEmpty() ? name : toUString(obj->objectName()) );
00190
00191 parent->putDirect(jsName, returnObject, KJS::DontDelete|KJS::ReadOnly );
00192 return returnObject;
00193 }
00194
00195 KJS::JSObject *Engine::addObject( QObject *obj, const KJS::UString &name ) const
00196 {
00197 return addObject( obj, dptr->m_interpreter->globalObject(), name );
00198 }
00199
00200 KJS::Completion Engine::completion() const
00201 {
00202 return dptr->m_currentResult;
00203 }
00204
00205 KJS::Interpreter *Engine::interpreter() const
00206 {
00207 return dptr->m_interpreter;
00208 }
00209
00210 KJS::Completion Engine::runFile( KJS::Interpreter *interpreter, const KJS::UString &fileName )
00211 {
00212
00213 KJS::UString code;
00214 QFile file( toQString(fileName) );
00215 if( file.open( QFile::ReadOnly ) )
00216 {
00217 QTextStream ts( &file );
00218
00219 QString line;
00220 while( !ts.atEnd() )
00221 {
00222 line = ts.readLine();
00223 if( line[0] != '#' ) code += toUString(line + '\n');
00224 }
00225 file.close();
00226 }
00227 else
00228 {
00229 code = "println('Could not open file.');";
00230 qWarning() << "Could not open file " << toQString(fileName);
00231 }
00232
00233
00234
00235 return interpreter->evaluate( fileName, 0, code, 0 );
00236 }
00237
00238 Engine::ExitStatus Engine::runFile( const KJS::UString &fileName )
00239 {
00240 dptr->m_currentResult = runFile( dptr->m_interpreter, fileName );
00241
00242 if( dptr->m_currentResult.complType() == KJS::Normal )
00243 return Engine::Success;
00244 else if ( dptr->m_currentResult.complType() == KJS::ReturnValue)
00245 return Engine::Success;
00246 else
00247 return Engine::Failure;
00248 }
00249
00250 Engine::ExitStatus Engine::execute( const KJS::UString &code )
00251 {
00252 dptr->m_currentResult = dptr->m_interpreter->evaluate(KJS::UString(""), 0, code, 0);
00253 if( dptr->m_currentResult.complType() == KJS::Normal )
00254 return Engine::Success;
00255 else if ( dptr->m_currentResult.complType() == KJS::ReturnValue)
00256 return Engine::Success;
00257 else
00258 return Engine::Failure;
00259 }
00260
00261 KJS::JSObject *Engine::construct( const KJS::UString &className, const KJS::List &args ) const
00262 {
00263 KJS::JSObject *global = dptr->m_interpreter->globalObject();
00264 KJS::ExecState *exec = dptr->m_interpreter->globalExec();
00265 return StaticConstructor::construct( exec, global, className, args );
00266 }
00267
00268 KJS::JSValue *Engine::callMethod( const KJS::UString &methodName, const KJS::List &args )
00269 {
00270 KJS::JSObject *global = dptr->m_interpreter->globalObject();
00271 KJS::ExecState *exec = dptr->m_interpreter->globalExec();
00272
00273 KJS::Identifier id = KJS::Identifier( KJS::UString( methodName ) );
00274 KJS::JSObject *fun = global->get( exec, id )->toObject( exec );
00275 KJS::JSValue *retValue;
00276
00277 if ( !fun->implementsCall() ) {
00278 QString msg = i18n( "%1 is not a function and cannot be called.", toQString(methodName) );
00279 return throwError( exec, KJS::TypeError, msg );
00280 }
00281
00282 retValue = fun->call( exec, global, args );
00283
00284 if( exec->hadException() )
00285 return exec->exception();
00286
00287 return retValue;
00288 }
00289
00290 KJS::JSValue *Engine::callMethod( KJS::JSObject *parent,
00291 const KJS::UString &methodName, const KJS::List &args )
00292 {
00293 KJS::ExecState *exec = dptr->m_interpreter->globalExec();
00294
00295 KJS::Identifier id = KJS::Identifier( methodName);
00296 KJS::JSObject *fun = parent->get( exec, id )->toObject( exec );
00297 KJS::JSValue *retValue;
00298
00299 if ( !fun->implementsCall() ) {
00300 QString msg = i18n( "%1 is not a function and cannot be called.", toQString(methodName) );
00301 return throwError( exec, KJS::TypeError, msg );
00302 }
00303
00304 retValue = fun->call( exec, parent, args );
00305
00306 if( exec->hadException() )
00307 return exec->exception();
00308
00309 return retValue;
00310 }
00311
00312
00313 }
00314
00315