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

kjsembed

  • kjsembed
  • kjsembed
variant_binding.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 Copyright (C) 2007, 2008 Sebastian Sauer <mail@dipe.org>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA.
22*/
23
24#include "variant_binding.h"
25
26#include <stdlib.h>
27
28#include <kjs/PropertyNameArray.h>
29#include <kjs/array_instance.h>
30
31#include <QtCore/QBitRef>
32#include <QtCore/QByteRef>
33#include <QtCore/QDebug>
34#include <QtCore/QObject>
35#include <QtGui/QWidget>
36
37#include "kjseglobal.h"
38#include "static_binding.h"
39#include "qobject_binding.h"
40
41//#define KJSEMBED_VARIANT_DEBUG
42
43using namespace KJSEmbed;
44
45const KJS::ClassInfo VariantBinding::info = { "VariantBinding", 0, 0, 0 };
46
47VariantBinding::VariantBinding( KJS::ExecState *exec, const QVariant &value )
48 : ProxyBinding(exec), m_value(value)
49{
50 StaticBinding::publish( exec, this, VariantFactory::methods() );
51}
52
53void *VariantBinding::pointer()
54{
55 return m_value.data();
56}
57
58KJS::UString VariantBinding::toString(KJS::ExecState *) const
59{
60 return toUString(m_value.toString());
61}
62
63KJS::UString VariantBinding::className() const
64{
65 return m_value.typeName();
66}
67
68QVariant VariantBinding::variant() const
69{
70 return m_value;
71}
72
73void VariantBinding::setValue( const QVariant &val )
74{
75 m_value = val;
76}
77
78QGenericArgument VariantBinding::arg(const char *type) const
79{
80 const void *p = m_value.constData();
81 //qDebug("Ptr %0x", p );
82 //qDebug() << p;
83 return QGenericArgument( type, p );
84}
85
86KJS::JSValue *callName( KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args )
87{
88 Q_UNUSED( args );
89 KJSEmbed::VariantBinding *imp = KJSEmbed::extractBindingImp<KJSEmbed::VariantBinding>(exec, self);
90 return imp ? KJS::jsString( imp->variant().typeName() ) : KJS::jsNull();
91}
92
93KJS::JSValue *callCast( KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args )
94{
95 KJSEmbed::VariantBinding *imp = KJSEmbed::extractBindingImp<KJSEmbed::VariantBinding>(exec, self );
96 if( imp )
97 {
98 QVariant val = imp->variant();
99 QVariant::Type type = QVariant::nameToType( args[0]->toString(exec).ascii() );
100 KJS::JSValue *returnValue = KJS::jsBoolean(val.convert(type));
101 imp->setValue(val);
102 return returnValue;
103 }
104 return KJS::jsNull();
105}
106
107KJS::JSValue *callToString( KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args )
108{
109 Q_UNUSED( args );
110 KJSEmbed::VariantBinding *imp = KJSEmbed::extractBindingImp<KJSEmbed::VariantBinding>(exec, self );
111 if( imp )
112 {
113 //qDebug("Call value to string");
114 QVariant val = imp->variant();
115 QString stringVal = val.toString();
116 if( !stringVal.isEmpty() )
117 return KJS::jsString( val.toString() );
118 return KJS::jsString( val.typeName() );
119 }
120 return KJS::jsNull();
121}
122
123const Method VariantFactory::VariantMethods[] =
124{
125 {"cast", 1, KJS::DontDelete|KJS::ReadOnly|KJS::DontEnum, &callCast },
126 {"toString", 0, KJS::DontDelete|KJS::ReadOnly|KJS::DontEnum, &callToString },
127 {0, 0, 0, 0 }
128};
129
130enum JavaScriptArrayType { None, List, Map };
131
132JavaScriptArrayType checkArray( KJS::ExecState *exec, KJS::JSValue *val )
133{
134 KJS::JSObject *obj = val->toObject( exec );
135 if ( toQString(obj->className()) == "Array" )
136 {
137 if( !obj->hasProperty(exec, KJS::Identifier("length")) )
138 return Map;
139 KJS::JSValue *jslen = obj->get(exec, KJS::Identifier("length"));
140 const int len = jslen->toNumber(exec);
141 if ( len > 0 ) {
142 QByteArray buff;
143 buff.setNum(len-1);
144 if( !obj->hasProperty(exec, KJS::Identifier( buff.data() ) ) )
145 return Map;
146 }
147 return List;
148 }
149 else
150 return None;
151}
152
153QMap<QString, QVariant> KJSEmbed::convertArrayToMap( KJS::ExecState *exec, KJS::JSValue *value )
154{
155 QMap<QString, QVariant> returnMap;
156 KJS::JSObject *obj = value->toObject(exec);
157 KJS::PropertyNameArray lst;
158 obj->getPropertyNames(exec, lst);
159 KJS::PropertyNameArrayIterator idx = lst.begin();
160 for( ; idx != lst.end(); idx++ )
161 {
162 KJS::Identifier id = *idx;
163 KJS::JSValue *val = obj->get(exec, id);
164 returnMap[toQString(id)] = convertToVariant(exec,val);
165 }
166 return returnMap;
167}
168
169QList<QVariant> KJSEmbed::convertArrayToList( KJS::ExecState *exec, KJS::JSValue *value )
170{
171 QList<QVariant> returnList;
172 /*
173 KJS::JSObject *obj = value->toObject( exec );
174 if ( toQString(obj->className() == "Array" )
175 {
176 int length = int(obj->get( exec, KJS::Identifier( "length" ) )->toInteger( exec ) );
177 for ( int index = 0; index < length; ++index )
178 {
179 QByteArray buff;
180 buff.setNum(index);
181 KJS::JSValue *val = obj->get(exec, KJS::Identifier( buff.data() ) );
182 if( val )
183 returnList += convertToVariant(exec, val );
184 else
185 returnList += QVariant();
186 }
187 }
188 */
189 KJS::ArrayInstance* arrayImp = extractBindingImp<KJS::ArrayInstance>(exec, value);
190 if(arrayImp)
191 {
192 const unsigned numItems = arrayImp->getLength();
193 for ( unsigned i = 0; i < numItems; ++i )
194 returnList.append( convertToVariant(exec, arrayImp->getItem(i)) );
195 }
196 return returnList;
197}
198
199QStringList KJSEmbed::convertArrayToStringList( KJS::ExecState *exec, KJS::JSValue *value )
200{
201 QStringList returnList;
202 /*
203 KJS::JSObject *obj = value->toObject( exec );
204 if ( toQString(obj->className()) == "Array" )
205 {
206 int length = int( obj->get( exec, KJS::Identifier( "length" ) )->toInteger( exec ) );
207 for ( int index = 0; index < length; ++index )
208 {
209 QByteArray buff;
210 buff.setNum(index);
211 KJS::JSValue *val = obj->get(exec, KJS::Identifier( buff.data() ) );
212 if( val )
213 returnList += convertToVariant(exec, val ).value<QString>();
214 else
215 returnList += QString();
216 }
217 }
218 */
219 KJS::ArrayInstance* arrayImp = extractBindingImp<KJS::ArrayInstance>(exec, value);
220 if(arrayImp)
221 {
222 const unsigned numItems = arrayImp->getLength();
223 for ( unsigned i = 0; i < numItems; ++i )
224 returnList.append( convertToVariant(exec, arrayImp->getItem(i)).toString() );
225 }
226 return returnList;
227}
228
229QDateTime convertDateToDateTime( KJS::ExecState *exec, KJS::JSValue *value )
230{
231 KJS::List args;
232 QDateTime returnDateTime;
233 KJS::JSObject *obj = value->toObject( exec );
234 if ( toQString(obj->className()) == "Date" )
235 {
236 int seconds = int( obj->get( exec, KJS::Identifier( "getSeconds" ) )->toObject( exec )->call( exec, obj, args )->toInteger( exec ) );
237 int minutes = int( obj->get( exec, KJS::Identifier( "getMinutes" ) )->toObject( exec )->call( exec, obj, args )->toInteger( exec ) );
238 int hours = int( obj->get( exec, KJS::Identifier( "getHours" ) )->toObject( exec )->call( exec, obj, args )->toInteger( exec ) );
239 int month = int( obj->get( exec, KJS::Identifier( "getMonth" ) )->toObject( exec )->call( exec, obj, args )->toInteger( exec ) );
240 int day = int( obj->get( exec, KJS::Identifier( "getDate" ) )->toObject( exec )->call( exec, obj, args )->toInteger( exec ) );
241 int year = int( obj->get( exec, KJS::Identifier( "getFullYear" ) )->toObject( exec )->call( exec, obj, args )->toInteger( exec ) );
242 returnDateTime.setDate( QDate( year, month + 1, day ) );
243 returnDateTime.setTime( QTime( hours, minutes, seconds ) );
244 }
245 else
246 {
247 // Throw error
248 }
249
250 return returnDateTime;
251}
252
253QVariant KJSEmbed::convertToVariant( KJS::ExecState *exec, KJS::JSValue *value )
254{
255#ifdef KJSEMBED_VARIANT_DEBUG
256 qDebug()<<"KJSEmbed::convertToVariant";
257#endif
258
259 QVariant returnValue;
260 switch( value->type() )
261 {
262 case KJS::UndefinedType:
263 case KJS::NullType:
264 break;
265 case KJS::StringType:
266 returnValue = toQString(value->toString(exec));
267 break;
268 case KJS::NumberType:
269 returnValue = value->toNumber(exec);
270 break;
271 case KJS::BooleanType:
272 returnValue = value->toBoolean(exec);
273 break;
274 case KJS::ObjectType:
275 {
276 KJS::JSObject *obj = value->toObject(exec);
277 //qDebug() << "Object type: " << toQString(obj->className());
278 if ( toQString(obj->className()) == "Array" ) {
279 if (checkArray(exec, value) == List)
280 returnValue = convertArrayToList(exec, value);
281 else
282 returnValue = convertArrayToMap(exec, value);
283 }
284 else if ( toQString(obj->className()) == "Date" )
285 returnValue = convertDateToDateTime( exec, value );
286 else
287 returnValue = extractVariant(exec,value);
288 //if( returnValue.isNull() ) returnValue = toQString(value->toString(exec));
289 } break;
290 default:
291 returnValue = extractVariant(exec,value);
292 //if( returnValue.isNull() ) returnValue = toQString(value->toString(exec));
293 break;
294 }
295 return returnValue;
296}
297
298KJS::JSValue *KJSEmbed::convertToValue( KJS::ExecState *exec, const QVariant &value )
299{
300#ifdef KJSEMBED_VARIANT_DEBUG
301 qDebug()<<"KJSEmbed::convertToValue typeid="<<value.type()<<"typename="<<value.typeName()<<"toString="<<value.toString();
302#endif
303
304 KJS::JSValue *returnValue;
305 switch( value.type() )
306 {
307 case QVariant::Invalid:
308 returnValue = KJS::jsNull();
309 break;
310 case QVariant::Int:
311 returnValue = KJS::jsNumber( value.value<int>() );
312 break;
313 case QVariant::UInt:
314 returnValue = KJS::jsNumber( value.value<unsigned int>() );
315 break;
316 case QVariant::LongLong:
317 returnValue = KJS::jsNumber( value.value<qlonglong>() );
318 break;
319 case QVariant::ULongLong:
320 returnValue = KJS::jsNumber( value.value<qulonglong>() );
321 break;
322 case QVariant::Double:
323 returnValue = KJS::jsNumber( value.value<double>() );
324 break;
325 case QVariant::Bool:
326 returnValue = KJS::jsBoolean( value.value<bool>() );
327 break;
328 case QVariant::ByteArray:
329 returnValue = KJS::jsString( QString(value.value<QByteArray>()) );
330 break;
331 case QVariant::String:
332 returnValue = KJS::jsString( value.value<QString>() );
333 break;
334 case QVariant::StringList:
335 {
336 KJS::List items;
337 QStringList lst = value.value<QStringList>();
338 QStringList::Iterator idx = lst.begin();
339 for ( ; idx != lst.end(); ++idx )
340 items.append( KJS::jsString( ( *idx ) ) );
341 returnValue = exec->lexicalInterpreter()->builtinArray()->construct( exec, items );
342 break;
343 }
344 case QVariant::Date: // fall through
345 case QVariant::DateTime: // fall through
346 case QVariant::Time:
347 {
348 QDateTime dt = QDateTime::currentDateTime();
349 if ( value.type() == QVariant::Date )
350 dt.setDate( value.toDate() );
351 else if ( value.type() == QVariant::Time )
352 dt.setTime( value.toTime() );
353 else
354 dt = value.toDateTime();
355
356 KJS::List items;
357 items.append( KJS::jsNumber( dt.date().year() ) );
358 items.append( KJS::jsNumber( dt.date().month() - 1 ) );
359 items.append( KJS::jsNumber( dt.date().day() ) );
360 items.append( KJS::jsNumber( dt.time().hour() ) );
361 items.append( KJS::jsNumber( dt.time().minute() ) );
362 items.append( KJS::jsNumber( dt.time().second() ) );
363 items.append( KJS::jsNumber( dt.time().msec() ) );
364 returnValue = exec->lexicalInterpreter()->builtinDate()->construct( exec, items );
365 break;
366 }
367 case QVariant::List:
368 {
369 KJS::List items;
370 QList<QVariant> lst = value.toList();
371 foreach( const QVariant &item, lst)
372 items.append( convertToValue( exec, item ) );
373 returnValue = exec->lexicalInterpreter()->builtinArray()->construct( exec, items );
374 break;
375 }
376 case QVariant::Map:
377 {
378 QMap<QString,QVariant> map = value.toMap();
379 QMap<QString,QVariant>::Iterator idx = map.begin();
380 KJS::JSObject *obj = exec->lexicalInterpreter()->builtinObject()->construct( exec, KJS::List() );
381 for ( ; idx != map.end(); ++idx )
382 obj->put(exec, KJS::Identifier( toUString(idx.key()) ), convertToValue( exec, idx.value() ) );
383 returnValue = obj;
384 break;
385 }
386 default:
387 {
388 if( qVariantCanConvert< QWidget* >(value) ) {
389 QWidget* widget = qvariant_cast< QWidget* >(value);
390 returnValue = widget ? createQObject(exec, widget, KJSEmbed::ObjectBinding::CPPOwned) : KJS::jsNull();
391 }
392 else if( qVariantCanConvert< QObject* >(value) ) {
393 QObject* object = qvariant_cast< QObject* >(value);
394 returnValue = object ? createQObject(exec, object, KJSEmbed::ObjectBinding::CPPOwned) : KJS::jsNull();
395 }
396 else {
397 returnValue = createVariant(exec, value.typeName(), value );
398 if( returnValue->isNull() )
399 returnValue = KJS::jsString( value.value<QString>() );
400 }
401 break;
402 }
403 }
404 return returnValue;
405}
406
407QVariant KJSEmbed::extractVariant( KJS::ExecState *exec, KJS::JSValue *value )
408{
409#ifdef KJSEMBED_VARIANT_DEBUG
410 qDebug()<<"KJSEmbed::extractVariant";
411#endif
412
413 KJSEmbed::VariantBinding *imp = KJSEmbed::extractBindingImp<KJSEmbed::VariantBinding>(exec, value );
414 if( imp )
415 return imp->variant();
416 if( value->type() == KJS::StringType)
417 return QVariant(toQString(value->toString(exec)));
418 if( value->type() == KJS::NumberType)
419 return QVariant(value->toNumber(exec));
420 if( value->type() == KJS::BooleanType)
421 return QVariant(value->toBoolean(exec));
422
423 KJS::JSObject *obj = value->toObject( exec );
424 if ( obj ) {
425 if(QObjectBinding *objImp = KJSEmbed::extractBindingImp<QObjectBinding>(exec, value)) {
426 QVariant v;
427 if( QObject* qobj = objImp->qobject<QObject>() )
428 v.setValue(qobj);
429 return v;
430 }
431 if( toQString(obj->className()) == "Array" )
432 return convertArrayToList( exec, value );
433 }
434 return QVariant();
435}
436
437//kate: indent-spaces on; indent-width 4; replace-tabs on; indent-mode cstyle;
KJSEmbed::ObjectBinding::CPPOwned
@ CPPOwned
Definition: object_binding.h:91
KJSEmbed::ProxyBinding
Definition: binding_support.h:248
KJSEmbed::QObjectBinding
Definition: qobject_binding.h:80
KJSEmbed::StaticBinding::publish
static void publish(KJS::ExecState *exec, KJS::JSObject *object, const Method *methods)
Publishes an array of Methods to an object.
Definition: static_binding.cpp:60
KJSEmbed::VariantBinding
QVariant based binding.
Definition: variant_binding.h:89
KJSEmbed::VariantBinding::setValue
void setValue(const QVariant &val)
Set the internal value of the QVariant.
Definition: variant_binding.cpp:73
KJSEmbed::VariantBinding::pointer
void * pointer()
Definition: variant_binding.cpp:53
KJSEmbed::VariantBinding::className
KJS::UString className() const
Definition: variant_binding.cpp:63
KJSEmbed::VariantBinding::variant
QVariant variant() const
Return the wrapped QVariant.
Definition: variant_binding.cpp:68
KJSEmbed::VariantBinding::VariantBinding
VariantBinding(KJS::ExecState *exec, const QVariant &value)
Create a new binding implementation with a QVariant to wrap.
Definition: variant_binding.cpp:47
KJSEmbed::VariantBinding::toString
KJS::UString toString(KJS::ExecState *) const
Definition: variant_binding.cpp:58
KJSEmbed::VariantBinding::info
static const KJS::ClassInfo info
Definition: variant_binding.h:123
KJSEmbed::VariantBinding::arg
QGenericArgument arg(const char *type) const
Constructs a QGenericArgument that is used with QMetaObject::invokeMember.
Definition: variant_binding.cpp:78
KJSEmbed::VariantFactory::methods
static const Method * methods()
Definition: variant_binding.h:251
KJSEmbed::VariantFactory::VariantMethods
static const Method VariantMethods[]
Definition: variant_binding.h:250
QObject
QWidget
kjseglobal.h
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::convertArrayToStringList
QStringList KJSEMBED_EXPORT convertArrayToStringList(KJS::ExecState *exec, KJS::JSValue *value)
Convert a KJS::JSValue inot a QStringList.
Definition: variant_binding.cpp:199
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::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::extractVariant
QVariant KJSEMBED_EXPORT extractVariant(KJS::ExecState *exec, KJS::JSValue *value)
Extracts a QVariant from a KJS::JSValue if the conversion fails a QVariant::Null is returned.
Definition: variant_binding.cpp:407
KJSEmbed::toUString
KJS::UString toUString(const QString &qs)
Definition: kjseglobal.h:66
KJSEmbed::convertArrayToList
QList< QVariant > KJSEMBED_EXPORT convertArrayToList(KJS::ExecState *exec, KJS::JSValue *value)
Convert a KJS::JSValue into a QList.
Definition: variant_binding.cpp:169
KJSEmbed::createVariant
KJS::JSValue * createVariant(KJS::ExecState *exec, const KJS::UString &className, const T &value)
Can create any known KJSEmbed::VariantBinding object and set the value.
Definition: variant_binding.h:185
KJSEmbed::convertArrayToMap
QMap< QString, QVariant > KJSEMBED_EXPORT convertArrayToMap(KJS::ExecState *exec, KJS::JSValue *value)
Convert a KJS::JSValue that contains an associative array into a QMap.
Definition: variant_binding.cpp:153
KJS::jsString
KJS::JSCell * jsString(const QString &s)
Definition: kjseglobal.h:73
qobject_binding.h
value
QVariant value
Definition: settings.cpp:35
static_binding.h
KJSEmbed::Method
Method structure.
Definition: binding_support.h:295
widget
END_METHOD_LUT QSvgWidget * widget
Definition: svg_binding.cpp:106
JavaScriptArrayType
JavaScriptArrayType
Definition: variant_binding.cpp:130
Map
@ Map
Definition: variant_binding.cpp:130
List
@ List
Definition: variant_binding.cpp:130
None
@ None
Definition: variant_binding.cpp:130
callToString
KJS::JSValue * callToString(KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args)
Definition: variant_binding.cpp:107
checkArray
JavaScriptArrayType checkArray(KJS::ExecState *exec, KJS::JSValue *val)
Definition: variant_binding.cpp:132
convertDateToDateTime
QDateTime convertDateToDateTime(KJS::ExecState *exec, KJS::JSValue *value)
Definition: variant_binding.cpp:229
callName
KJS::JSValue * callName(KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args)
Definition: variant_binding.cpp:86
callCast
KJS::JSValue * callCast(KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args)
Definition: variant_binding.cpp:93
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