• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

kjsembed

  • kjsembed
  • kjsembed
slotproxy.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2 Copyright (C) 2005, 2006 Ian Reinhart Geiser <geiseri@kde.org>
3 Copyright (C) 2005, 2006 Matt Broadstone <mbroadst@gmail.com>
4 Copyright (C) 2005, 2006 Richard J. Moore <rich@kde.org>
5 Copyright (C) 2005, 2006 Erik L. Bunce <kde@bunce.us>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21*/
22#include "slotproxy.h"
23
24#include <QtCore/QMetaEnum>
25#include <QtCore/QMetaType>
26#include <QtCore/QDebug>
27#include <QtGui/QWidget>
28
29#include <kjs/interpreter.h>
30
31#include "variant_binding.h"
32#include "qobject_binding.h"
33
34//#define DEBUG_SLOTPROXY 1
35
36using namespace KJSEmbed;
37
38SlotProxy::SlotProxy(KJS::JSObject *obj, KJS::Interpreter *interpreter, QObject *parent, const QByteArray &signature)
39 : QObject(parent), m_interpreter(interpreter), m_object(obj)
40{
41 m_signature = QMetaObject::normalizedSignature( signature );
42 uint signatureSize = m_signature.size() + 1;
43
44 // content:
45 m_data[0] = 1; // revision
46 m_data[1] = 0; // classname
47 m_data[2] = 0; // classinfo
48 m_data[3] = 0; // classinfo
49 m_data[4] = 1; // methods
50 m_data[5] = 10; // methods
51 m_data[6] = 0; // properties
52 m_data[7] = 0; // properties
53 m_data[8] = 0; // enums/sets
54 m_data[9] = 0; // enums/sets
55 // slots:
56 m_data[10] = 10; //signature start
57 m_data[11] = 10 + signatureSize; //parameters start
58 m_data[12] = 10 + signatureSize; //type start
59 m_data[13] = 10 + signatureSize; //tag start
60 m_data[14] = 0x0a;//flags
61 m_data[15] = 0; // eod
62
63 m_stringData = QByteArray("SlotProxy\0", 10);
64 m_stringData += m_signature;
65 m_stringData += QByteArray("\0\0", 2);
66
67 staticMetaObject.d.superdata = &QObject::staticMetaObject;
68 staticMetaObject.d.stringdata = m_stringData.data();
69 staticMetaObject.d.data = m_data;
70 staticMetaObject.d.extradata = 0;
71#ifdef DEBUG_SLOTPROXY
72 qDebug() << "SlotProxy() obj=" << this << " m_signature=" << m_signature;
73#endif
74}
75
76SlotProxy::~SlotProxy()
77{
78#ifdef DEBUG_SLOTPROXY
79 qDebug() << "??????SlotProxy::~SlotProxy() obj=" << this <<" m_signature=" << m_signature;
80#endif
81}
82
83const QMetaObject *SlotProxy::metaObject() const
84{
85 return &staticMetaObject;
86}
87
88void *SlotProxy::qt_metacast(const char *_clname)
89{
90 if (!_clname) return 0;
91 if (!strcmp(_clname, m_stringData))
92 return static_cast<void*>(const_cast<SlotProxy*>(this));
93 return QObject::qt_metacast(_clname);
94}
95
96KJS::JSValue *SlotProxy::callMethod( const QByteArray & methodName, void **_a )
97{
98#ifdef DEBUG_SLOTPROXY
99 qDebug() << "SlotProxy::callMethod(" << methodName << ",_a) obj=" << this;
100#endif
101 KJS::ExecState *exec = m_interpreter->globalExec();
102 exec->clearException();
103
104 // Crash
105 // KJS::Interpreter::globalExec()->context().thisValue()
106 KJS::List args = convertArguments(exec, _a);
107 KJS::Identifier id = KJS::Identifier( KJS::UString(methodName.data()));
108 KJS::JSObject *fun = m_object->get(exec, id )->toObject( exec );
109 KJS::JSValue *retValue;
110 if ( !fun->implementsCall() )
111 {
112#ifdef DEBUG_SLOTPROXY
113 qDebug() << "SlotProxy::callMethod got bad handler";
114#endif
115 QString msg = i18n( "Bad slot handler: Object %1 Identifier %2 Method %3 Signature: %4.",
116 m_object->className().ascii(),
117 id.ascii(),
118 methodName.data(),
119 QString(m_signature));
120
121 retValue = throwError(exec, KJS::TypeError, msg);
122 }
123 else
124 retValue = fun->call(exec, m_object, args);
125
126 if( exec->hadException() )
127 {
128#ifdef DEBUG_SLOTPROXY
129 qDebug() << "SlotProxy::callMethod had exception";
130#endif
131 if (m_interpreter->shouldPrintExceptions())
132 {
133 KJS::JSLock lock;
134 KJS::JSObject* exceptObj = exec->exception()->toObject(exec);//retValue->toObject(exec);
135 QString message = toQString(exceptObj->toString(exec));
136 QString sourceURL = toQString(exceptObj->get(exec, "sourceURL")->toString(exec));
137 int sourceId = exceptObj->get(exec, "sourceId")->toUInt32(exec);
138 // would include the line number, but it's always last line of file
139 int line = exceptObj->get(exec, "line")->toUInt32(exec);
140 (*KJSEmbed::conerr()) << i18n("Exception calling '%1' slot from %2:%3:%4", QString(methodName), !sourceURL.isEmpty() ? sourceURL : QString::number(sourceId), line, message) << endl;
141 }
142
143 // clear it so it doesn't stop other things
144 exec->clearException();
145
146 return KJS::jsNull();
147 }
148 else
149 {
150 if( retValue->type() == 1 || retValue->type() == 0)
151 {
152 return KJS::jsNull();
153 }
154 }
155 return retValue;
156}
157
158KJS::List SlotProxy::convertArguments(KJS::ExecState *exec, void **_a )
159{
160 KJS::List args;
161 int offset = metaObject()->indexOfMethod(m_signature);
162 QMetaMethod method = metaObject()->method(offset);
163 QList<QByteArray> params = method.parameterTypes();
164 int idx = 1;
165#ifdef DEBUG_SLOTPROXY
166 qDebug() << "SlotProxy::convertArguments(): obj=" << this << " m_signature=" << m_signature << " offset=" << offset << " params=" << params ;
167#endif
168 foreach( const QByteArray &param, params )
169 {
170#ifdef DEBUG_SLOTPROXY
171 int type = QMetaType::type( param.constData() );
172 qDebug("\tGot a %d - %s - _a[%d] = %p", type, param.data(), idx, _a[idx]);
173 qDebug("\t QMetaType::type()=%d", QMetaType::type(QByteArray("Pinya::") + param.constData()));
174#endif
175 int tp = QVariant::nameToType(param.constData());
176 switch(tp)
177 {
178 case QVariant::Int:
179 args.append(KJS::jsNumber(*(int*)_a[idx]));
180 break;
181 case QVariant::UInt:
182 args.append(KJS::jsNumber(*(uint*)_a[idx]));
183 break;
184 case QVariant::LongLong:
185 args.append(KJS::jsNumber(*(qlonglong*)_a[idx]));
186 break;
187 case QVariant::ULongLong:
188 args.append(KJS::jsNumber(*(qulonglong*)_a[idx]));
189 break;
190 case QVariant::Double:
191 args.append(KJS::jsNumber(*(double*)_a[idx]));
192 break;
193 case QVariant::Bool:
194 args.append(KJS::jsBoolean(*(bool*)_a[idx]));
195 break;
196 case QVariant::String:
197 args.append(KJS::jsString((*reinterpret_cast<QString(*)>(_a[idx]))));
198 break;
199 case QVariant::UserType:
200 {
201 KJS::JSObject* returnValue;
202 KJS::JSObject* parent = exec->dynamicInterpreter()->globalObject();
203 QByteArray typeName = param.constData();
204 bool isPtr = typeName.contains("*");
205 if (isPtr)
206 typeName.replace("*", ""); //krazy:exclude=doublequote_chars
207#ifdef DEBUG_SLOTPROXY
208 qDebug() << "\tQVariant::UserType: typeName=" << typeName << " param=" << param.constData() << " isPtr" << isPtr;
209#endif
210 if ( parent->hasProperty( exec, KJS::Identifier(toUString(typeName))) )
211 {
212 QObject* qObj;
213 if (isPtr &&
214 ((qObj = *reinterpret_cast<QObject**>(_a[idx])) != 0))
215 {
216#ifdef DEBUG_SLOTPROXY
217 qDebug() << "qObj=" << qObj;
218#endif
219 Pointer<QObject> pov(*reinterpret_cast<QObject*(*)>(_a[idx]));
220 returnValue = StaticConstructor::bind(exec, typeName, pov);
221 if ( returnValue )
222 {
223 args.append(returnValue);
224 break;
225 }
226 else
227 {
228#ifdef DEBUG_SLOTPROXY
229 qDebug("\t\tNo binding retrieved");
230#endif
231 returnValue = StaticConstructor::construct( exec, parent, toUString(typeName) );
232 if( returnValue )
233 {
234 if(QObjectBinding *objImp = KJSEmbed::extractBindingImp<QObjectBinding>(exec, returnValue))
235 {
236#ifdef DEBUG_SLOTPROXY
237 qDebug() << "\t\t\tFound QObjectBinding";
238#endif
239 objImp->setOwnership( KJSEmbed::ObjectBinding::JSOwned );
240 objImp->setObject(qObj);
241 if (qObj->parent() != 0)
242 objImp->setOwnership(KJSEmbed::ObjectBinding::QObjOwned);
243 else
244 objImp->setOwnership(KJSEmbed::ObjectBinding::CPPOwned);
245 args.append(returnValue);
246 break;
247 }
248 }
249 }
250 }
251 }
252 else
253 {
254#ifdef DEBUG_SLOTPROXY
255 qDebug("\t\tNo binding registered");
256#endif
257 KJS::JSObject* returnValue = 0;
258 switch( QMetaType::type( param.constData() ) )
259 {
260 case QMetaType::QObjectStar: {
261 QObject* obj = (*reinterpret_cast< QObject*(*)>( _a[idx] ));
262 returnValue = KJSEmbed::createQObject(exec, obj, KJSEmbed::ObjectBinding::QObjOwned);
263 } break;
264 case QMetaType::QWidgetStar: {
265 QWidget* obj = (*reinterpret_cast< QWidget*(*)>( _a[idx] ));
266 returnValue = KJSEmbed::createQObject(exec, obj, KJSEmbed::ObjectBinding::QObjOwned);
267 } break;
268 default: {
269#ifdef DEBUG_SLOTPROXY
270 qDebug("\t\tInvalid type !");
271#endif
272 } break;
273 }
274 if( returnValue ) {
275 args.append(returnValue);
276 break;
277 }
278 }
279 }
280 case QVariant::StringList:
281 case QVariant::List:
282 case QVariant::Map:
283 default:
284 //qDebug("\t\tconverting to variant");
285 QVariant variant(tp, _a[idx]);
286 args.append( KJSEmbed::convertToValue(exec,variant) );
287 break;
288 }
289 ++idx;
290 }
291
292 return args;
293}
294
295int SlotProxy::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
296{
297#ifdef DEBUG_SLOTPROXY
298 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);
299#endif
300 _id = QObject::qt_metacall(_c, _id, _a);
301 if (_id < 0)
302 return _id;
303 if (_c == QMetaObject::InvokeMetaMethod)
304 {
305 switch (_id)
306 {
307 case 0: {
308 // invoke js method here
309 QByteArray method = m_signature.left(m_signature.indexOf('('));
310 KJS::JSValue *result = callMethod(method, _a);
311 m_tmpResult = convertToVariant(m_interpreter->globalExec(), result);
312#ifdef DEBUG_SLOTPROXY
313 qDebug()<<"SlotProxy::qt_metacall result="<<m_tmpResult.toString();
314#endif
315 _a[0] = &(m_tmpResult);
316 } break;
317 }
318 _id -= 1;
319 }
320 return _id;
321}
322
323//kate: indent-spaces on; indent-width 4; replace-tabs on; indent-mode cstyle;
KJSEmbed::ObjectBinding::QObjOwned
@ QObjOwned
Definition: object_binding.h:91
KJSEmbed::ObjectBinding::CPPOwned
@ CPPOwned
Definition: object_binding.h:91
KJSEmbed::ObjectBinding::JSOwned
@ JSOwned
Definition: object_binding.h:91
KJSEmbed::QObjectBinding
Definition: qobject_binding.h:80
KJSEmbed::SlotProxy
Definition: slotproxy.h:42
KJSEmbed::SlotProxy::qt_metacall
int qt_metacall(QMetaObject::Call _c, int _id, void **_a)
Definition: slotproxy.cpp:295
KJSEmbed::SlotProxy::SlotProxy
SlotProxy(KJS::JSObject *obj, KJS::Interpreter *interpreter, QObject *parent, const QByteArray &signature)
Definition: slotproxy.cpp:38
KJSEmbed::SlotProxy::staticMetaObject
QMetaObject staticMetaObject
Definition: slotproxy.h:47
KJSEmbed::SlotProxy::metaObject
const QMetaObject * metaObject() const
Definition: slotproxy.cpp:83
KJSEmbed::SlotProxy::qt_metacast
void * qt_metacast(const char *_clname)
Definition: slotproxy.cpp:88
KJSEmbed::SlotProxy::~SlotProxy
~SlotProxy()
Definition: slotproxy.cpp:76
KJSEmbed::StaticConstructor::construct
KJS::JSObject * construct(KJS::ExecState *exec, const KJS::List &args)
Calls the callback that will in turn create a new instance of this object with the arguments passed i...
Definition: static_binding.cpp:79
KJSEmbed::StaticConstructor::bind
static KJS::JSObject * bind(KJS::ExecState *exec, const QString &className, PointerBase &objPtr)
Definition: static_binding.cpp:130
QObject
QWidget
result
END_VARIANT_METHOD result
Definition: color.cpp:85
KJSEmbed
Definition: application.h:33
KJSEmbed::convertToVariant
QVariant KJSEMBED_EXPORT convertToVariant(KJS::ExecState *exec, KJS::JSValue *value)
Convert a KJS::JSValue into a QVariant object.
Definition: variant_binding.cpp:253
KJSEmbed::toQString
QString toQString(const KJS::UString &u)
Definition: kjseglobal.h:58
KJSEmbed::convertToValue
KJSEMBED_EXPORT KJS::JSValue * convertToValue(KJS::ExecState *exec, const QVariant &value)
Convert a QVariant to a KJS::JSValue.
Definition: variant_binding.cpp:298
KJSEmbed::conerr
KJSEMBED_EXPORT QTextStream * conerr()
Definition: kjseglobal.cpp:143
KJSEmbed::createQObject
KJSEMBED_EXPORT KJS::JSObject * createQObject(KJS::ExecState *exec, QObject *value, KJSEmbed::ObjectBinding::Ownership owner=KJSEmbed::ObjectBinding::JSOwned)
Returns a binding object for the specified QObject.
Definition: qobject_binding.cpp:735
KJSEmbed::toUString
KJS::UString toUString(const QString &qs)
Definition: kjseglobal.h:66
KJSEmbed::callMethod
KJS::JSValue *(* callMethod)(KJS::ExecState *, KJS::JSObject *, const KJS::List &)
Method callback signature.
Definition: binding_support.h:289
KJS::jsString
KJS::JSCell * jsString(const QString &s)
Definition: kjseglobal.h:73
NodeListNS::idx
END_VALUE_METHOD int idx
Definition: dom.cpp:691
parent
QObject * parent
Definition: qaction_binding.cpp:48
qobject_binding.h
slotproxy.h
Pointer
Definition: pointer.h:43
variant_binding.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kjsembed

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

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal