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

kjsembed

  • sources
  • kde-4.12
  • kdelibs
  • 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 
36 using namespace KJSEmbed;
37 
38 SlotProxy::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 
76 SlotProxy::~SlotProxy()
77 {
78 #ifdef DEBUG_SLOTPROXY
79  qDebug() << "??????SlotProxy::~SlotProxy() obj=" << this <<" m_signature=" << m_signature;
80 #endif
81 }
82 
83 const QMetaObject *SlotProxy::metaObject() const
84 {
85  return &staticMetaObject;
86 }
87 
88 void *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 
96 KJS::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 
158 KJS::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 
295 int 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::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::SlotProxy::qt_metacall
int qt_metacall(QMetaObject::Call _c, int _id, void **_a)
Definition: slotproxy.cpp:295
KJSEmbed::QObjectBinding
Definition: qobject_binding.h:79
KJSEmbed::SlotProxy::SlotProxy
SlotProxy(KJS::JSObject *obj, KJS::Interpreter *interpreter, QObject *parent, const QByteArray &signature)
Definition: slotproxy.cpp:38
Pointer
Definition: pointer.h:42
KJSEmbed::ObjectBinding::JSOwned
Definition: object_binding.h:91
KJSEmbed::SlotProxy::~SlotProxy
~SlotProxy()
Definition: slotproxy.cpp:76
QWidget
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::ObjectBinding::QObjOwned
Definition: object_binding.h:91
QObject
parent
QObject * parent
Definition: qaction_binding.cpp:48
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
DomDocumentNS::message
QString message
Definition: dom.cpp:358
KJSEmbed::ObjectBinding::CPPOwned
Definition: object_binding.h:91
BrushNS::result
result
Definition: brush.cpp:48
KJSEmbed::SlotProxy::qt_metacast
void * qt_metacast(const char *_clname)
Definition: slotproxy.cpp:88
KJSEmbed::SlotProxy::staticMetaObject
QMetaObject staticMetaObject
Definition: slotproxy.h:47
slotproxy.h
NodeListNS::idx
END_VALUE_METHOD int idx
Definition: dom.cpp:691
KJSEmbed::SlotProxy
Definition: slotproxy.h:41
KJSEmbed::StaticConstructor::bind
static KJS::JSObject * bind(KJS::ExecState *exec, const QString &className, PointerBase &objPtr)
Definition: static_binding.cpp:130
KJS::jsString
KJS::JSCell * jsString(const QString &s)
Definition: kjseglobal.h:73
List
Definition: variant_binding.cpp:130
KJSEmbed::toUString
KJS::UString toUString(const QString &qs)
Definition: kjseglobal.h:66
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
Map
Definition: variant_binding.cpp:130
qobject_binding.h
variant_binding.h
KJSEmbed::SlotProxy::metaObject
const QMetaObject * metaObject() const
Definition: slotproxy.cpp:83
KJS::throwError
JSObject * throwError(ExecState *e, ErrorType t, const QString &m)
Definition: binding_support.h:241
KJSEmbed::conerr
KJSEMBED_EXPORT QTextStream * conerr()
Definition: kjseglobal.cpp:143
KJSEmbed::toQString
QString toQString(const KJS::UString &u)
Definition: kjseglobal.h:58
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:47:53 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



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