• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

kjsembed

slotproxy.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 "slotproxy.h"
00023 
00024 #include <QtCore/QMetaEnum>
00025 #include <QtCore/QMetaType>
00026 #include <QtCore/QDebug>
00027 #include <QtGui/QWidget>
00028 
00029 #include <kjs/interpreter.h>
00030 
00031 #include "variant_binding.h"
00032 #include "qobject_binding.h"
00033 
00034 //#define DEBUG_SLOTPROXY 1
00035 
00036 using namespace KJSEmbed;
00037 
00038 SlotProxy::SlotProxy(KJS::JSObject *obj, KJS::Interpreter *interpreter, QObject *parent, const QByteArray &signature)
00039     : QObject(parent), m_interpreter(interpreter), m_object(obj)
00040 {
00041     m_signature = QMetaObject::normalizedSignature( signature );
00042     uint signatureSize = m_signature.size() + 1;
00043 
00044     // content:
00045     m_data[0] = 1;  // revision
00046     m_data[1] = 0;  // classname
00047     m_data[2] = 0;  // classinfo
00048     m_data[3] = 0;  // classinfo
00049     m_data[4] = 1;  // methods
00050     m_data[5] = 10; // methods
00051     m_data[6] = 0;  // properties
00052     m_data[7] = 0;  // properties
00053     m_data[8] = 0;  // enums/sets
00054     m_data[9] = 0;  // enums/sets
00055     // slots:
00056     m_data[10] = 10;  //signature start
00057     m_data[11] = 10 + signatureSize;  //parameters start
00058     m_data[12] = 10 + signatureSize;  //type start
00059     m_data[13] = 10 + signatureSize;  //tag start
00060     m_data[14] = 0x0a;//flags
00061     m_data[15] = 0;    // eod
00062 
00063     m_stringData = QByteArray("SlotProxy\0", 10);
00064     m_stringData += m_signature;
00065     m_stringData += QByteArray("\0\0", 2);
00066 
00067     staticMetaObject.d.superdata = &QObject::staticMetaObject;
00068     staticMetaObject.d.stringdata = m_stringData.data();
00069     staticMetaObject.d.data = m_data;
00070     staticMetaObject.d.extradata = 0;
00071 #ifdef DEBUG_SLOTPROXY
00072         qDebug() << "SlotProxy() obj=" << this <<  " m_signature=" << m_signature;
00073 #endif
00074 }
00075 
00076 SlotProxy::~SlotProxy()
00077 {
00078 #ifdef DEBUG_SLOTPROXY
00079     qDebug() << "??????SlotProxy::~SlotProxy() obj=" << this <<" m_signature=" << m_signature;
00080 #endif
00081 }
00082 
00083 const QMetaObject *SlotProxy::metaObject() const
00084 {
00085     return &staticMetaObject;
00086 }
00087 
00088 void *SlotProxy::qt_metacast(const char *_clname)
00089 {
00090     if (!_clname) return 0;
00091     if (!strcmp(_clname, m_stringData))
00092         return static_cast<void*>(const_cast<SlotProxy*>(this));
00093     return QObject::qt_metacast(_clname);
00094 }
00095 
00096 KJS::JSValue *SlotProxy::callMethod( const QByteArray & methodName, void **_a )
00097 {
00098 #ifdef DEBUG_SLOTPROXY
00099     qDebug() << "SlotProxy::callMethod(" << methodName << ",_a) obj=" << this;
00100 #endif
00101     KJS::ExecState *exec = m_interpreter->globalExec();
00102     exec->clearException();
00103 
00104     // Crash
00105     // KJS::Interpreter::globalExec()->context().thisValue()
00106     KJS::List args = convertArguments(exec, _a);
00107     KJS::Identifier id = KJS::Identifier( KJS::UString(methodName.data()));
00108     KJS::JSObject *fun = m_object->get(exec, id )->toObject( exec );
00109     KJS::JSValue *retValue;
00110     if ( !fun->implementsCall() )
00111     {
00112 #ifdef DEBUG_SLOTPROXY
00113         qDebug() << "SlotProxy::callMethod got bad handler";
00114 #endif
00115         QString msg = i18n( "Bad slot handler: Object %1 Identifier %2 Method %3 Signature: %4.",
00116                             m_object->className().ascii(),
00117                             id.ascii(),
00118                             methodName.data(),
00119                             QString(m_signature));
00120 
00121         retValue = throwError(exec, KJS::TypeError, msg);
00122     }
00123     else
00124         retValue = fun->call(exec, m_object, args);
00125 
00126     if( exec->hadException() )
00127     {
00128 #ifdef DEBUG_SLOTPROXY
00129         qDebug() << "SlotProxy::callMethod had exception";
00130 #endif
00131         if (m_interpreter->shouldPrintExceptions())
00132         {
00133             KJS::JSLock lock;
00134             KJS::JSObject* exceptObj = exec->exception()->toObject(exec);//retValue->toObject(exec);
00135             QString message = toQString(exceptObj->toString(exec));
00136             QString sourceURL = toQString(exceptObj->get(exec, "sourceURL")->toString(exec));
00137             int sourceId = exceptObj->get(exec, "sourceId")->toUInt32(exec);
00138             // would include the line number, but it's always last line of file
00139             int line = exceptObj->get(exec, "line")->toUInt32(exec);
00140             (*KJSEmbed::conerr()) << i18n("Exception calling '%1' slot from %2:%3:%4", QString(methodName), !sourceURL.isEmpty() ? sourceURL : QString::number(sourceId), line, message) << endl;
00141         }
00142 
00143         // clear it so it doesn't stop other things
00144         exec->clearException();
00145 
00146         return KJS::jsNull();
00147     }
00148     else
00149     {
00150         if( retValue->type() == 1 || retValue->type() == 0)
00151         {
00152             return KJS::jsNull();
00153         }
00154     }
00155     return retValue;
00156 }
00157 
00158 KJS::List SlotProxy::convertArguments(KJS::ExecState *exec, void **_a )
00159 {
00160     KJS::List args;
00161     int offset = metaObject()->indexOfMethod(m_signature);
00162     QMetaMethod method = metaObject()->method(offset);
00163     QList<QByteArray> params = method.parameterTypes();
00164     int idx = 1;
00165 #ifdef DEBUG_SLOTPROXY
00166     qDebug() << "SlotProxy::convertArguments(): obj=" << this << " m_signature=" << m_signature << " offset=" << offset << " params=" << params ;
00167 #endif
00168     foreach( const QByteArray &param, params )
00169     {
00170 #ifdef DEBUG_SLOTPROXY
00171         int type = QMetaType::type( param.constData() );
00172         qDebug("\tGot a %d - %s - _a[%d] = %p", type, param.data(), idx, _a[idx]);
00173         qDebug("\t QMetaType::type()=%d", QMetaType::type(QByteArray("Pinya::") + param.constData()));
00174 #endif
00175         int tp = QVariant::nameToType(param.constData());
00176         switch(tp)
00177         {
00178         case QVariant::Int:
00179             args.append(KJS::jsNumber(*(int*)_a[idx]));
00180             break;
00181         case QVariant::UInt:
00182             args.append(KJS::jsNumber(*(uint*)_a[idx]));
00183             break;
00184         case QVariant::LongLong:
00185             args.append(KJS::jsNumber(*(qlonglong*)_a[idx]));
00186             break;
00187         case QVariant::ULongLong:
00188             args.append(KJS::jsNumber(*(qulonglong*)_a[idx]));
00189             break;
00190         case QVariant::Double:
00191             args.append(KJS::jsNumber(*(double*)_a[idx]));
00192             break;
00193         case QVariant::Bool:
00194             args.append(KJS::jsBoolean(*(bool*)_a[idx]));
00195             break;
00196         case QVariant::String:
00197             args.append(KJS::jsString((*reinterpret_cast<QString(*)>(_a[idx]))));
00198             break;
00199         case QVariant::UserType:
00200         {
00201             KJS::JSObject* returnValue;
00202             KJS::JSObject* parent = exec->dynamicInterpreter()->globalObject();
00203             QByteArray typeName = param.constData();
00204             bool isPtr = typeName.contains("*");
00205             if (isPtr)
00206                 typeName.replace("*", ""); //krazy:exclude=doublequote_chars
00207 #ifdef DEBUG_SLOTPROXY
00208             qDebug() << "\tQVariant::UserType: typeName=" << typeName << " param=" << param.constData() << " isPtr" << isPtr;
00209 #endif
00210             if ( parent->hasProperty( exec, KJS::Identifier(toUString(typeName))) )
00211             {
00212                 QObject* qObj;
00213                 if (isPtr &&
00214                     ((qObj = *reinterpret_cast<QObject**>(_a[idx])) != 0))
00215                 {
00216 #ifdef DEBUG_SLOTPROXY
00217                     qDebug() << "qObj=" << qObj;
00218 #endif
00219                     Pointer<QObject> pov(*reinterpret_cast<QObject*(*)>(_a[idx]));
00220                     returnValue = StaticConstructor::bind(exec, typeName, pov);
00221                     if ( returnValue )
00222                     {
00223                         args.append(returnValue);
00224                         break;
00225                     }
00226                     else
00227                     {
00228 #ifdef DEBUG_SLOTPROXY
00229                         qDebug("\t\tNo binding retrieved");
00230 #endif
00231                         returnValue = StaticConstructor::construct( exec, parent, toUString(typeName) );
00232                         if( returnValue )
00233                         {
00234                             if(QObjectBinding *objImp = KJSEmbed::extractBindingImp<QObjectBinding>(exec, returnValue))
00235                             {
00236 #ifdef DEBUG_SLOTPROXY
00237                                 qDebug() << "\t\t\tFound QObjectBinding";
00238 #endif
00239                                 objImp->setOwnership( KJSEmbed::ObjectBinding::JSOwned );
00240                                 objImp->setObject(qObj);
00241                                 if (qObj->parent() != 0)
00242                                     objImp->setOwnership(KJSEmbed::ObjectBinding::QObjOwned);
00243                                 else
00244                                     objImp->setOwnership(KJSEmbed::ObjectBinding::CPPOwned);
00245                                 args.append(returnValue);
00246                                 break;
00247                             }
00248                         }
00249                     }
00250                 }
00251             }
00252             else
00253             {
00254 #ifdef DEBUG_SLOTPROXY
00255                 qDebug("\t\tNo binding registered");
00256 #endif
00257                 KJS::JSObject* returnValue = 0;
00258                 switch( QMetaType::type( param.constData() ) )
00259                 {
00260                     case QMetaType::QObjectStar: {
00261                         QObject* obj = (*reinterpret_cast< QObject*(*)>( _a[idx] ));
00262                         returnValue = KJSEmbed::createQObject(exec, obj, KJSEmbed::ObjectBinding::QObjOwned);
00263                     } break;
00264                     case QMetaType::QWidgetStar: {
00265                         QWidget* obj = (*reinterpret_cast< QWidget*(*)>( _a[idx] ));
00266                         returnValue = KJSEmbed::createQObject(exec, obj, KJSEmbed::ObjectBinding::QObjOwned);
00267                     } break;
00268                     default: {
00269 #ifdef DEBUG_SLOTPROXY
00270                         qDebug("\t\tInvalid type !");
00271 #endif
00272                     } break;
00273                 }
00274                 if( returnValue ) {
00275                     args.append(returnValue);
00276                     break;
00277                 }
00278             }
00279         }
00280         case QVariant::StringList:
00281         case QVariant::List:
00282         case QVariant::Map:
00283         default:
00284             //qDebug("\t\tconverting to variant");
00285             QVariant variant(tp, _a[idx]);
00286             args.append( KJSEmbed::convertToValue(exec,variant) );
00287             break;
00288         }
00289         ++idx;
00290     }
00291 
00292     return args;
00293 }
00294 
00295 int SlotProxy::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
00296 {
00297 #ifdef DEBUG_SLOTPROXY
00298     qDebug("SlotProxy::qt_metacall(_c=%d, _id=%d, _a=%p _a[0]=%p _a[1]=%p) obj=", _c, _id, _a, _a[0], _a[1], this);
00299 #endif
00300     _id = QObject::qt_metacall(_c, _id, _a);
00301     if (_id < 0)
00302             return _id;
00303     if (_c == QMetaObject::InvokeMetaMethod)
00304     {
00305         switch (_id)
00306         {
00307             case 0: {
00308                 // invoke js method here
00309                 QByteArray method = m_signature.left(m_signature.indexOf('('));
00310                 KJS::JSValue *result = callMethod(method, _a);
00311                 m_tmpResult = convertToVariant(m_interpreter->globalExec(), result);
00312 #ifdef DEBUG_SLOTPROXY
00313                 qDebug()<<"SlotProxy::qt_metacall result="<<m_tmpResult.toString();
00314 #endif
00315                 _a[0] = &(m_tmpResult);
00316             } break;
00317         }
00318         _id -= 1;
00319     }
00320     return _id;
00321 }
00322 
00323 //kate: indent-spaces on; indent-width 4; replace-tabs on; indent-mode cstyle;

kjsembed

Skip menu "kjsembed"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal