Improve QJSValueIterator implementation.
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativemetatype.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <QtDeclarative/qdeclarativeprivate.h>
43 #include "private/qdeclarativemetatype_p.h"
44
45 #include "private/qdeclarativeproxymetaobject_p.h"
46 #include "private/qdeclarativecustomparser_p.h"
47 #include "private/qdeclarativeguard_p.h"
48
49 #include <QtCore/qdebug.h>
50 #include <QtCore/qstringlist.h>
51 #include <QtCore/qmetaobject.h>
52 #include <QtCore/qbitarray.h>
53 #include <QtCore/qreadwritelock.h>
54 #include <qmetatype.h>
55 #include <qobjectdefs.h>
56 #include <qdatetime.h>
57 #include <qbytearray.h>
58 #include <qreadwritelock.h>
59 #include <qstring.h>
60 #include <qstringlist.h>
61 #include <qvector.h>
62 #include <qlocale.h>
63 #include <QtCore/qcryptographichash.h>
64 #include <QtDeclarative/qjsvalue.h>
65
66 #include <ctype.h>
67
68 #ifdef QT_BOOTSTRAPPED
69 # ifndef QT_NO_GEOM_VARIANT
70 #  define QT_NO_GEOM_VARIANT
71 # endif
72 #else
73 #  include <qbitarray.h>
74 #  include <qurl.h>
75 #  include <qvariant.h>
76 #endif
77
78 #ifndef QT_NO_GEOM_VARIANT
79 # include <qsize.h>
80 # include <qpoint.h>
81 # include <qrect.h>
82 # include <qline.h>
83 # include <qvector3d.h>
84 #endif
85 #define NS(x) QT_PREPEND_NAMESPACE(x)
86
87 QT_BEGIN_NAMESPACE
88
89 struct QDeclarativeMetaTypeData
90 {
91     QDeclarativeMetaTypeData();
92     ~QDeclarativeMetaTypeData();
93     QList<QDeclarativeType *> types;
94     typedef QHash<int, QDeclarativeType *> Ids;
95     Ids idToType;
96     typedef QHash<QByteArray, QDeclarativeType *> Names;
97     Names nameToType;
98     typedef QHash<const QMetaObject *, QDeclarativeType *> MetaObjects;
99     MetaObjects metaObjectToType;
100     typedef QHash<int, QDeclarativeMetaType::StringConverter> StringConverters;
101     StringConverters stringConverters;
102     struct ModuleApiList {
103         ModuleApiList() : sorted(true) {}
104         QList<QDeclarativeMetaType::ModuleApi> moduleApis;
105         bool sorted;
106     };
107     typedef QHash<QByteArray, ModuleApiList> ModuleApis;
108     ModuleApis moduleApis;
109     int moduleApiCount;
110
111     struct ModuleInfo {
112         ModuleInfo(int major, int minor)
113             : vmajor(major), vminor_min(minor), vminor_max(minor) {}
114         ModuleInfo(int major, int minor_min, int minor_max)
115             : vmajor(major), vminor_min(minor_min), vminor_max(minor_max) {}
116         int vmajor;
117         int vminor_min, vminor_max;
118     };
119     typedef QHash<QPair<QByteArray,int>, ModuleInfo> ModuleInfoHash;
120     ModuleInfoHash modules;
121
122     QBitArray objects;
123     QBitArray interfaces;
124     QBitArray lists;
125
126     QList<QDeclarativePrivate::AutoParentFunction> parentFunctions;
127 };
128 Q_GLOBAL_STATIC(QDeclarativeMetaTypeData, metaTypeData)
129 Q_GLOBAL_STATIC(QReadWriteLock, metaTypeDataLock)
130
131 QDeclarativeMetaTypeData::QDeclarativeMetaTypeData()
132 : moduleApiCount(0)
133 {
134 }
135
136 QDeclarativeMetaTypeData::~QDeclarativeMetaTypeData()
137 {
138     for (int i = 0; i < types.count(); ++i)
139         delete types.at(i);
140 }
141
142 class QDeclarativeTypePrivate
143 {
144 public:
145     QDeclarativeTypePrivate();
146
147     void init() const;
148
149     bool m_isInterface : 1;
150     const char *m_iid;
151     QByteArray m_module;
152     QByteArray m_name;
153     int m_version_maj;
154     int m_version_min;
155     int m_typeId; int m_listId; 
156     int m_revision;
157     mutable bool m_containsRevisionedAttributes;
158     mutable QDeclarativeType *m_superType;
159
160     int m_allocationSize;
161     void (*m_newFunc)(void *);
162     QString m_noCreationReason;
163
164     const QMetaObject *m_baseMetaObject;
165     QDeclarativeAttachedPropertiesFunc m_attachedPropertiesFunc;
166     const QMetaObject *m_attachedPropertiesType;
167     int m_attachedPropertiesId;
168     int m_parserStatusCast;
169     int m_propertyValueSourceCast;
170     int m_propertyValueInterceptorCast;
171     QObject *(*m_extFunc)(QObject *);
172     const QMetaObject *m_extMetaObject;
173     int m_index;
174     QDeclarativeCustomParser *m_customParser;
175     mutable volatile bool m_isSetup:1;
176     mutable bool m_haveSuperType : 1;
177     mutable QList<QDeclarativeProxyMetaObject::ProxyData> m_metaObjects;
178
179     static QHash<const QMetaObject *, int> m_attachedPropertyIds;
180 };
181
182 QHash<const QMetaObject *, int> QDeclarativeTypePrivate::m_attachedPropertyIds;
183
184 QDeclarativeTypePrivate::QDeclarativeTypePrivate()
185 : m_isInterface(false), m_iid(0), m_typeId(0), m_listId(0), m_revision(0), m_containsRevisionedAttributes(false),
186   m_superType(0), m_allocationSize(0), m_newFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0), 
187   m_attachedPropertiesType(0), m_parserStatusCast(-1), m_propertyValueSourceCast(-1), 
188   m_propertyValueInterceptorCast(-1), m_extFunc(0), m_extMetaObject(0), m_index(-1), m_customParser(0), 
189   m_isSetup(false), m_haveSuperType(false)
190 {
191 }
192
193
194 QDeclarativeType::QDeclarativeType(int index, const QDeclarativePrivate::RegisterInterface &interface)
195 : d(new QDeclarativeTypePrivate)
196 {
197     d->m_isInterface = true;
198     d->m_iid = interface.iid;
199     d->m_typeId = interface.typeId;
200     d->m_listId = interface.listId;
201     d->m_newFunc = 0;
202     d->m_index = index;
203     d->m_isSetup = true;
204     d->m_version_maj = 0;
205     d->m_version_min = 0;
206 }
207
208 QDeclarativeType::QDeclarativeType(int index, const QDeclarativePrivate::RegisterType &type)
209 : d(new QDeclarativeTypePrivate)
210 {
211     QByteArray name = type.uri;
212     if (type.uri) name += '/';
213     name += type.elementName;
214
215     d->m_module = type.uri;
216     d->m_name = name;
217     d->m_version_maj = type.versionMajor;
218     d->m_version_min = type.versionMinor;
219     if (type.version >= 1) // revisions added in version 1
220         d->m_revision = type.revision;
221     d->m_typeId = type.typeId;
222     d->m_listId = type.listId;
223     d->m_allocationSize = type.objectSize;
224     d->m_newFunc = type.create;
225     d->m_noCreationReason = type.noCreationReason;
226     d->m_baseMetaObject = type.metaObject;
227     d->m_attachedPropertiesFunc = type.attachedPropertiesFunction;
228     d->m_attachedPropertiesType = type.attachedPropertiesMetaObject;
229     if (d->m_attachedPropertiesType) {
230         QHash<const QMetaObject *, int>::Iterator iter = d->m_attachedPropertyIds.find(d->m_baseMetaObject);
231         if (iter == d->m_attachedPropertyIds.end())
232             iter = d->m_attachedPropertyIds.insert(d->m_baseMetaObject, index);
233         d->m_attachedPropertiesId = *iter;
234     } else {
235         d->m_attachedPropertiesId = -1;
236     }
237     d->m_parserStatusCast = type.parserStatusCast;
238     d->m_propertyValueSourceCast = type.valueSourceCast;
239     d->m_propertyValueInterceptorCast = type.valueInterceptorCast;
240     d->m_extFunc = type.extensionObjectCreate;
241     d->m_index = index;
242     d->m_customParser = type.customParser;
243
244     if (type.extensionMetaObject)
245         d->m_extMetaObject = type.extensionMetaObject;
246 }
247
248 QDeclarativeType::~QDeclarativeType()
249 {
250     delete d->m_customParser;
251     delete d;
252 }
253
254 QByteArray QDeclarativeType::module() const
255 {
256     return d->m_module;
257 }
258
259 int QDeclarativeType::majorVersion() const
260 {
261     return d->m_version_maj;
262 }
263
264 int QDeclarativeType::minorVersion() const
265 {
266     return d->m_version_min;
267 }
268
269 bool QDeclarativeType::availableInVersion(int vmajor, int vminor) const
270 {
271     return vmajor == d->m_version_maj && vminor >= d->m_version_min;
272 }
273
274 bool QDeclarativeType::availableInVersion(const QByteArray &module, int vmajor, int vminor) const
275 {
276     return module == d->m_module && vmajor == d->m_version_maj && vminor >= d->m_version_min;
277 }
278
279 // returns the nearest _registered_ super class
280 QDeclarativeType *QDeclarativeType::superType() const
281 {
282     if (!d->m_haveSuperType) {
283         const QMetaObject *mo = d->m_baseMetaObject->superClass();
284         while (mo && !d->m_superType) {
285             d->m_superType = QDeclarativeMetaType::qmlType(mo, d->m_module, d->m_version_maj, d->m_version_min);
286             mo = mo->superClass();
287         }
288         d->m_haveSuperType = true;
289     }
290
291     return d->m_superType;
292 }
293
294 static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo, 
295                   const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd)
296 {
297     // Set classname
298     builder.setClassName(ignoreEnd->className());
299
300     // Clone Q_CLASSINFO
301     for (int ii = mo->classInfoOffset(); ii < mo->classInfoCount(); ++ii) {
302         QMetaClassInfo info = mo->classInfo(ii);
303
304         int otherIndex = ignoreEnd->indexOfClassInfo(info.name());
305         if (otherIndex >= ignoreStart->classInfoOffset() + ignoreStart->classInfoCount()) {
306             // Skip 
307         } else {
308             builder.addClassInfo(info.name(), info.value());
309         }
310     }
311
312     // Clone Q_PROPERTY
313     for (int ii = mo->propertyOffset(); ii < mo->propertyCount(); ++ii) {
314         QMetaProperty property = mo->property(ii);
315
316         int otherIndex = ignoreEnd->indexOfProperty(property.name());
317         if (otherIndex >= ignoreStart->propertyOffset() + ignoreStart->propertyCount()) {
318             builder.addProperty(QByteArray("__qml_ignore__") + property.name(), QByteArray("void"));
319             // Skip 
320         } else {
321             builder.addProperty(property);
322         }
323     }
324
325     // Clone Q_METHODS
326     for (int ii = mo->methodOffset(); ii < mo->methodCount(); ++ii) {
327         QMetaMethod method = mo->method(ii);
328
329         // More complex - need to search name
330         QByteArray name = method.signature();
331         int parenIdx = name.indexOf('(');
332         if (parenIdx != -1) name = name.left(parenIdx);
333
334
335         bool found = false;
336
337         for (int ii = ignoreStart->methodOffset() + ignoreStart->methodCount(); 
338              !found && ii < ignoreEnd->methodOffset() + ignoreEnd->methodCount();
339              ++ii) {
340
341             QMetaMethod other = ignoreEnd->method(ii);
342             QByteArray othername = other.signature();
343             int parenIdx = othername.indexOf('(');
344             if (parenIdx != -1) othername = othername.left(parenIdx);
345
346             found = name == othername;
347         }
348
349         QMetaMethodBuilder m = builder.addMethod(method);
350         if (found) // SKIP
351             m.setAccess(QMetaMethod::Private);
352     }
353
354     // Clone Q_ENUMS
355     for (int ii = mo->enumeratorOffset(); ii < mo->enumeratorCount(); ++ii) {
356         QMetaEnum enumerator = mo->enumerator(ii);
357
358         int otherIndex = ignoreEnd->indexOfEnumerator(enumerator.name());
359         if (otherIndex >= ignoreStart->enumeratorOffset() + ignoreStart->enumeratorCount()) {
360             // Skip 
361         } else {
362             builder.addEnumerator(enumerator);
363         }
364     }
365 }
366
367 void QDeclarativeTypePrivate::init() const
368 {
369     if (m_isSetup) return;
370
371     QWriteLocker lock(metaTypeDataLock());
372     if (m_isSetup)
373         return;
374
375     // Setup extended meta object
376     // XXX - very inefficient
377     const QMetaObject *mo = m_baseMetaObject;
378     if (m_extFunc) {
379         QMetaObject *mmo = new QMetaObject;
380         *mmo = *m_extMetaObject;
381         mmo->d.superdata = mo;
382         QDeclarativeProxyMetaObject::ProxyData data = { mmo, m_extFunc, 0, 0 };
383         m_metaObjects << data;
384     }
385
386     mo = mo->d.superdata;
387     while(mo) {
388         QDeclarativeType *t = metaTypeData()->metaObjectToType.value(mo);
389         if (t) {
390             if (t->d->m_extFunc) {
391                 QMetaObjectBuilder builder;
392                 clone(builder, t->d->m_extMetaObject, t->d->m_baseMetaObject, m_baseMetaObject);
393                 QMetaObject *mmo = builder.toMetaObject();
394                 mmo->d.superdata = m_baseMetaObject;
395                 if (!m_metaObjects.isEmpty())
396                     m_metaObjects.last().metaObject->d.superdata = mmo;
397                 QDeclarativeProxyMetaObject::ProxyData data = { mmo, t->d->m_extFunc, 0, 0 };
398                 m_metaObjects << data;
399             }
400         }
401         mo = mo->d.superdata;
402     }
403
404     for (int ii = 0; ii < m_metaObjects.count(); ++ii) {
405         m_metaObjects[ii].propertyOffset =
406             m_metaObjects.at(ii).metaObject->propertyOffset();
407         m_metaObjects[ii].methodOffset =
408             m_metaObjects.at(ii).metaObject->methodOffset();
409     }
410     
411     // Check for revisioned details
412     {
413         const QMetaObject *mo = 0;
414         if (m_metaObjects.isEmpty())
415             mo = m_baseMetaObject;
416         else
417             mo = m_metaObjects.first().metaObject;
418
419         for (int ii = 0; !m_containsRevisionedAttributes && ii < mo->propertyCount(); ++ii) {
420             if (mo->property(ii).revision() != 0)
421                 m_containsRevisionedAttributes = true;
422         }
423
424         for (int ii = 0; !m_containsRevisionedAttributes && ii < mo->methodCount(); ++ii) {
425             if (mo->method(ii).revision() != 0)
426                 m_containsRevisionedAttributes = true;
427         }
428     }
429
430     m_isSetup = true;
431     lock.unlock();
432 }
433
434 QByteArray QDeclarativeType::typeName() const
435 {
436     if (d->m_baseMetaObject)
437         return d->m_baseMetaObject->className();
438     else
439         return QByteArray();
440 }
441
442 QByteArray QDeclarativeType::qmlTypeName() const
443 {
444     return d->m_name;
445 }
446
447 QObject *QDeclarativeType::create() const
448 {
449     d->init();
450
451     QObject *rv = (QObject *)operator new(d->m_allocationSize);
452     d->m_newFunc(rv);
453
454     if (rv && !d->m_metaObjects.isEmpty())
455         (void *)new QDeclarativeProxyMetaObject(rv, &d->m_metaObjects);
456
457     return rv;
458 }
459
460 void QDeclarativeType::create(QObject **out, void **memory, size_t additionalMemory) const
461 {
462     d->init();
463
464     QObject *rv = (QObject *)operator new(d->m_allocationSize + additionalMemory);
465     d->m_newFunc(rv);
466
467     if (rv && !d->m_metaObjects.isEmpty())
468         (void *)new QDeclarativeProxyMetaObject(rv, &d->m_metaObjects);
469
470     *out = rv;
471     *memory = ((char *)rv) + d->m_allocationSize;
472 }
473
474 QDeclarativeCustomParser *QDeclarativeType::customParser() const
475 {
476     return d->m_customParser;
477 }
478
479 QDeclarativeType::CreateFunc QDeclarativeType::createFunction() const
480 {
481     return d->m_newFunc;
482 }
483
484 QString QDeclarativeType::noCreationReason() const
485 {
486     return d->m_noCreationReason;
487 }
488
489 int QDeclarativeType::createSize() const
490 {
491     return d->m_allocationSize;
492 }
493
494 bool QDeclarativeType::isCreatable() const
495 {
496     return d->m_newFunc != 0;
497 }
498
499 bool QDeclarativeType::isExtendedType() const
500 {
501     d->init();
502
503     return !d->m_metaObjects.isEmpty();
504 }
505
506 bool QDeclarativeType::isInterface() const
507 {
508     return d->m_isInterface;
509 }
510
511 int QDeclarativeType::typeId() const
512 {
513     return d->m_typeId;
514 }
515
516 int QDeclarativeType::qListTypeId() const
517 {
518     return d->m_listId;
519 }
520
521 const QMetaObject *QDeclarativeType::metaObject() const
522 {
523     d->init();
524
525     if (d->m_metaObjects.isEmpty())
526         return d->m_baseMetaObject;
527     else
528         return d->m_metaObjects.first().metaObject;
529
530 }
531
532 const QMetaObject *QDeclarativeType::baseMetaObject() const
533 {
534     return d->m_baseMetaObject;
535 }
536
537 bool QDeclarativeType::containsRevisionedAttributes() const
538 {
539     d->init();
540
541     return d->m_containsRevisionedAttributes;
542 }
543
544 int QDeclarativeType::metaObjectRevision() const
545 {
546     return d->m_revision;
547 }
548
549 QDeclarativeAttachedPropertiesFunc QDeclarativeType::attachedPropertiesFunction() const
550 {
551     return d->m_attachedPropertiesFunc;
552 }
553
554 const QMetaObject *QDeclarativeType::attachedPropertiesType() const
555 {
556     return d->m_attachedPropertiesType;
557 }
558
559 /*
560 This is the id passed to qmlAttachedPropertiesById().  This is different from the index
561 for the case that a single class is registered under two or more names (eg. Item in 
562 Qt 4.7 and QtQuick 1.0).
563 */
564 int QDeclarativeType::attachedPropertiesId() const
565 {
566     return d->m_attachedPropertiesId;
567 }
568
569 int QDeclarativeType::parserStatusCast() const
570 {
571     return d->m_parserStatusCast;
572 }
573
574 int QDeclarativeType::propertyValueSourceCast() const
575 {
576     return d->m_propertyValueSourceCast;
577 }
578
579 int QDeclarativeType::propertyValueInterceptorCast() const
580 {
581     return d->m_propertyValueInterceptorCast;
582 }
583
584 const char *QDeclarativeType::interfaceIId() const
585 {
586     return d->m_iid;
587 }
588
589 int QDeclarativeType::index() const
590 {
591     return d->m_index;
592 }
593
594 int registerAutoParentFunction(QDeclarativePrivate::RegisterAutoParent &autoparent)
595 {
596     QWriteLocker lock(metaTypeDataLock());
597     QDeclarativeMetaTypeData *data = metaTypeData();
598
599     data->parentFunctions.append(autoparent.function);
600
601     return data->parentFunctions.count() - 1;
602 }
603
604 int registerInterface(const QDeclarativePrivate::RegisterInterface &interface)
605 {
606     if (interface.version > 0) 
607         qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
608
609     QWriteLocker lock(metaTypeDataLock());
610     QDeclarativeMetaTypeData *data = metaTypeData();
611
612     int index = data->types.count();
613
614     QDeclarativeType *type = new QDeclarativeType(index, interface);
615
616     data->types.append(type);
617     data->idToType.insert(type->typeId(), type);
618     data->idToType.insert(type->qListTypeId(), type);
619     // XXX No insertMulti, so no multi-version interfaces?
620     if (!type->qmlTypeName().isEmpty())
621         data->nameToType.insert(type->qmlTypeName(), type);
622
623     if (data->interfaces.size() <= interface.typeId)
624         data->interfaces.resize(interface.typeId + 16);
625     if (data->lists.size() <= interface.listId)
626         data->lists.resize(interface.listId + 16);
627     data->interfaces.setBit(interface.typeId, true);
628     data->lists.setBit(interface.listId, true);
629
630     return index;
631 }
632
633 int registerType(const QDeclarativePrivate::RegisterType &type)
634 {
635     if (type.elementName) {
636         for (int ii = 0; type.elementName[ii]; ++ii) {
637             if (!isalnum(type.elementName[ii])) {
638                 qWarning("qmlRegisterType(): Invalid QML element name \"%s\"", type.elementName);
639                 return -1;
640             }
641         }
642     }
643
644     QWriteLocker lock(metaTypeDataLock());
645     QDeclarativeMetaTypeData *data = metaTypeData();
646     int index = data->types.count();
647
648     QDeclarativeType *dtype = new QDeclarativeType(index, type);
649
650     data->types.append(dtype);
651     data->idToType.insert(dtype->typeId(), dtype);
652     if (dtype->qListTypeId()) data->idToType.insert(dtype->qListTypeId(), dtype);
653
654     if (!dtype->qmlTypeName().isEmpty())
655         data->nameToType.insertMulti(dtype->qmlTypeName(), dtype);
656
657     data->metaObjectToType.insertMulti(dtype->baseMetaObject(), dtype);
658
659     if (data->objects.size() <= type.typeId)
660         data->objects.resize(type.typeId + 16);
661     if (data->lists.size() <= type.listId)
662         data->lists.resize(type.listId + 16);
663     data->objects.setBit(type.typeId, true);
664     if (type.listId) data->lists.setBit(type.listId, true);
665
666     if (type.uri) {
667         QByteArray mod(type.uri);
668         QPair<QByteArray,int> key(mod,type.versionMajor);
669         QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.find(key);
670         if (it == data->modules.end()) {
671             // New module
672             data->modules.insert(key, QDeclarativeMetaTypeData::ModuleInfo(type.versionMajor,type.versionMinor));
673         } else {
674             if ((*it).vminor_max < type.versionMinor) {
675                 // Newer module
676                 data->modules.insert(key, QDeclarativeMetaTypeData::ModuleInfo((*it).vmajor, (*it).vminor_min, type.versionMinor));
677             } else if ((*it).vminor_min > type.versionMinor) {
678                 // Older module
679                 data->modules.insert(key, QDeclarativeMetaTypeData::ModuleInfo((*it).vmajor, type.versionMinor, (*it).vminor_min));
680             }
681         }
682     }
683
684     return index;
685 }
686
687 int registerModuleApi(const QDeclarativePrivate::RegisterModuleApi &api)
688 {
689     QWriteLocker lock(metaTypeDataLock());
690
691     QDeclarativeMetaTypeData *data = metaTypeData();
692     QByteArray uri(api.uri);
693     QDeclarativeMetaType::ModuleApi import;
694     import.major = api.versionMajor;
695     import.minor = api.versionMinor;
696     import.script = api.scriptApi;
697     import.qobject = api.qobjectApi;
698
699     int index = data->moduleApiCount++;
700
701     QDeclarativeMetaTypeData::ModuleApis::Iterator iter = data->moduleApis.find(uri);
702     if (iter == data->moduleApis.end()) {
703         QDeclarativeMetaTypeData::ModuleApiList apis;
704         apis.moduleApis << import;
705         data->moduleApis.insert(uri, apis);
706     } else {
707         iter->moduleApis << import;
708         iter->sorted = false;
709     }
710
711     return index;
712 }
713
714
715 /*
716 This method is "over generalized" to allow us to (potentially) register more types of things in
717 the future without adding exported symbols.
718 */
719 int QDeclarativePrivate::qmlregister(RegistrationType type, void *data)
720 {
721     if (type == TypeRegistration) {
722         return registerType(*reinterpret_cast<RegisterType *>(data));
723     } else if (type == InterfaceRegistration) {
724         return registerInterface(*reinterpret_cast<RegisterInterface *>(data));
725     } else if (type == AutoParentRegistration) {
726         return registerAutoParentFunction(*reinterpret_cast<RegisterAutoParent *>(data));
727     } else if (type == ModuleApiRegistration) {
728         return registerModuleApi(*reinterpret_cast<RegisterModuleApi *>(data));
729     }
730     return -1;
731 }
732
733 bool QDeclarativeMetaType::isAnyModule(const QByteArray &module)
734 {
735     QDeclarativeMetaTypeData *data = metaTypeData();
736
737     QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.begin();
738     while (it != data->modules.end()) {
739         if (it.key().first == module)
740             return true;
741         ++it;
742     }
743
744     return false;
745 }
746
747 /*
748     Returns true if any type or API has been registered for the given \a module with at least
749     versionMajor.versionMinor, or if types have been registered for \a module with at most
750     versionMajor.versionMinor.
751
752     So if only 4.7 and 4.9 have been registered, 4.7,4.8, and 4.9 are valid, but not 4.6 nor 4.10.
753 */
754 bool QDeclarativeMetaType::isModule(const QByteArray &module, int versionMajor, int versionMinor)
755 {
756     QDeclarativeMetaTypeData *data = metaTypeData();
757
758     // first, check Types
759     QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.find(QPair<QByteArray,int>(module,versionMajor));
760     if (it != data->modules.end()) {
761         if (((*it).vminor_max >= versionMinor && (*it).vminor_min <= versionMinor))
762             return true;
763     }
764
765     // then, check ModuleApis
766     foreach (const QDeclarativeMetaType::ModuleApi &mApi, data->moduleApis.value(module).moduleApis) {
767         if (mApi.major == versionMajor && mApi.minor == versionMinor) {
768             return true;
769         }
770     }
771
772     return false;
773 }
774
775 QList<QDeclarativePrivate::AutoParentFunction> QDeclarativeMetaType::parentFunctions()
776 {
777     QReadLocker lock(metaTypeDataLock());
778     QDeclarativeMetaTypeData *data = metaTypeData();
779     return data->parentFunctions;
780 }
781
782 static bool operator<(const QDeclarativeMetaType::ModuleApi &lhs, const QDeclarativeMetaType::ModuleApi &rhs)
783 {
784     return lhs.major < rhs.major || (lhs.major == rhs.major && lhs.minor < rhs.minor);
785 }
786
787 QDeclarativeMetaType::ModuleApi
788 QDeclarativeMetaType::moduleApi(const QByteArray &uri, int versionMajor, int versionMinor)
789 {
790     QReadLocker lock(metaTypeDataLock());
791     QDeclarativeMetaTypeData *data = metaTypeData();
792
793     QDeclarativeMetaTypeData::ModuleApis::Iterator iter = data->moduleApis.find(uri);
794     if (iter == data->moduleApis.end())
795         return ModuleApi();
796
797     if (iter->sorted == false) {
798         qSort(iter->moduleApis.begin(), iter->moduleApis.end());
799         iter->sorted = true;
800     }
801
802     for (int ii = iter->moduleApis.count() - 1; ii >= 0; --ii) {
803         const ModuleApi &import = iter->moduleApis.at(ii);
804         if (import.major == versionMajor && import.minor <= versionMinor)
805             return import;
806     }
807
808     return ModuleApi();
809 }
810
811 QObject *QDeclarativeMetaType::toQObject(const QVariant &v, bool *ok)
812 {
813     if (!isQObject(v.userType())) {
814         if (ok) *ok = false;
815         return 0;
816     }
817
818     if (ok) *ok = true;
819
820     return *(QObject **)v.constData();
821 }
822
823 bool QDeclarativeMetaType::isQObject(int userType)
824 {
825     if (userType == QMetaType::QObjectStar)
826         return true;
827
828     QReadLocker lock(metaTypeDataLock());
829     QDeclarativeMetaTypeData *data = metaTypeData();
830     return userType >= 0 && userType < data->objects.size() && data->objects.testBit(userType);
831 }
832
833 /*
834     Returns the item type for a list of type \a id.
835  */
836 int QDeclarativeMetaType::listType(int id)
837 {
838     QReadLocker lock(metaTypeDataLock());
839     QDeclarativeMetaTypeData *data = metaTypeData();
840     QDeclarativeType *type = data->idToType.value(id);
841     if (type && type->qListTypeId() == id)
842         return type->typeId();
843     else
844         return 0;
845 }
846
847 int QDeclarativeMetaType::attachedPropertiesFuncId(const QMetaObject *mo)
848 {
849     QReadLocker lock(metaTypeDataLock());
850     QDeclarativeMetaTypeData *data = metaTypeData();
851
852     QDeclarativeType *type = data->metaObjectToType.value(mo);
853     if (type && type->attachedPropertiesFunction())
854         return type->attachedPropertiesId();
855     else
856         return -1;
857 }
858
859 QDeclarativeAttachedPropertiesFunc QDeclarativeMetaType::attachedPropertiesFuncById(int id)
860 {
861     if (id < 0)
862         return 0;
863     QReadLocker lock(metaTypeDataLock());
864     QDeclarativeMetaTypeData *data = metaTypeData();
865     return data->types.at(id)->attachedPropertiesFunction();
866 }
867
868 QMetaProperty QDeclarativeMetaType::defaultProperty(const QMetaObject *metaObject)
869 {
870     int idx = metaObject->indexOfClassInfo("DefaultProperty");
871     if (-1 == idx)
872         return QMetaProperty();
873
874     QMetaClassInfo info = metaObject->classInfo(idx);
875     if (!info.value())
876         return QMetaProperty();
877
878     idx = metaObject->indexOfProperty(info.value());
879     if (-1 == idx)
880         return QMetaProperty();
881
882     return metaObject->property(idx);
883 }
884
885 QMetaProperty QDeclarativeMetaType::defaultProperty(QObject *obj)
886 {
887     if (!obj)
888         return QMetaProperty();
889
890     const QMetaObject *metaObject = obj->metaObject();
891     return defaultProperty(metaObject);
892 }
893
894 QMetaMethod QDeclarativeMetaType::defaultMethod(const QMetaObject *metaObject)
895 {
896     int idx = metaObject->indexOfClassInfo("DefaultMethod");
897     if (-1 == idx)
898         return QMetaMethod();
899
900     QMetaClassInfo info = metaObject->classInfo(idx);
901     if (!info.value())
902         return QMetaMethod();
903
904     idx = metaObject->indexOfMethod(info.value());
905     if (-1 == idx)
906         return QMetaMethod();
907
908     return metaObject->method(idx);
909 }
910
911 QMetaMethod QDeclarativeMetaType::defaultMethod(QObject *obj)
912 {
913     if (!obj)
914         return QMetaMethod();
915
916     const QMetaObject *metaObject = obj->metaObject();
917     return defaultMethod(metaObject);
918 }
919
920 QDeclarativeMetaType::TypeCategory QDeclarativeMetaType::typeCategory(int userType)
921 {
922     if (userType < 0)
923         return Unknown;
924     if (userType == QMetaType::QObjectStar)
925         return Object;
926
927     QReadLocker lock(metaTypeDataLock());
928     QDeclarativeMetaTypeData *data = metaTypeData();
929     if (userType < data->objects.size() && data->objects.testBit(userType))
930         return Object;
931     else if (userType < data->lists.size() && data->lists.testBit(userType))
932         return List;
933     else
934         return Unknown;
935 }
936
937 bool QDeclarativeMetaType::isInterface(int userType)
938 {
939     QReadLocker lock(metaTypeDataLock());
940     QDeclarativeMetaTypeData *data = metaTypeData();
941     return userType >= 0 && userType < data->interfaces.size() && data->interfaces.testBit(userType);
942 }
943
944 const char *QDeclarativeMetaType::interfaceIId(int userType)
945 {
946     QReadLocker lock(metaTypeDataLock());
947     QDeclarativeMetaTypeData *data = metaTypeData();
948     QDeclarativeType *type = data->idToType.value(userType);
949     lock.unlock();
950     if (type && type->isInterface() && type->typeId() == userType)
951         return type->interfaceIId();
952     else
953         return 0;
954 }
955
956 bool QDeclarativeMetaType::isList(int userType)
957 {
958     QReadLocker lock(metaTypeDataLock());
959     QDeclarativeMetaTypeData *data = metaTypeData();
960     return userType >= 0 && userType < data->lists.size() && data->lists.testBit(userType);
961 }
962
963 /*!
964     A custom string convertor allows you to specify a function pointer that
965     returns a variant of \a type. For example, if you have written your own icon
966     class that you want to support as an object property assignable in QML:
967
968     \code
969     int type = qRegisterMetaType<SuperIcon>("SuperIcon");
970     QML::addCustomStringConvertor(type, &SuperIcon::pixmapFromString);
971     \endcode
972
973     The function pointer must be of the form:
974     \code
975     QVariant (*StringConverter)(const QString &);
976     \endcode
977  */
978 void QDeclarativeMetaType::registerCustomStringConverter(int type, StringConverter converter)
979 {
980     QWriteLocker lock(metaTypeDataLock());
981
982     QDeclarativeMetaTypeData *data = metaTypeData();
983     if (data->stringConverters.contains(type))
984         return;
985     data->stringConverters.insert(type, converter);
986 }
987
988 /*!
989     Return the custom string converter for \a type, previously installed through
990     registerCustomStringConverter()
991  */
992 QDeclarativeMetaType::StringConverter QDeclarativeMetaType::customStringConverter(int type)
993 {
994     QReadLocker lock(metaTypeDataLock());
995
996     QDeclarativeMetaTypeData *data = metaTypeData();
997     return data->stringConverters.value(type);
998 }
999
1000 /*!
1001     Returns the type (if any) of URI-qualified named \a name in version specified
1002     by \a version_major and \a version_minor.
1003 */
1004 QDeclarativeType *QDeclarativeMetaType::qmlType(const QByteArray &name, int version_major, int version_minor)
1005 {
1006     QReadLocker lock(metaTypeDataLock());
1007     QDeclarativeMetaTypeData *data = metaTypeData();
1008
1009     QList<QDeclarativeType*> types = data->nameToType.values(name);
1010     foreach (QDeclarativeType *t, types) {
1011         // XXX version_major<0 just a kludge for QDeclarativePropertyPrivate::initProperty
1012         if (version_major<0 || t->availableInVersion(version_major,version_minor))
1013             return t;
1014     }
1015     return 0;
1016 }
1017
1018 /*!
1019     Returns the type (if any) that corresponds to the \a metaObject.  Returns null if no
1020     type is registered.
1021 */
1022 QDeclarativeType *QDeclarativeMetaType::qmlType(const QMetaObject *metaObject)
1023 {
1024     QReadLocker lock(metaTypeDataLock());
1025     QDeclarativeMetaTypeData *data = metaTypeData();
1026
1027     return data->metaObjectToType.value(metaObject);
1028 }
1029
1030 /*!
1031     Returns the type (if any) that corresponds to the \a metaObject in version specified
1032     by \a version_major and \a version_minor in module specified by \a uri.  Returns null if no
1033     type is registered.
1034 */
1035 QDeclarativeType *QDeclarativeMetaType::qmlType(const QMetaObject *metaObject, const QByteArray &module, int version_major, int version_minor)
1036 {
1037     QReadLocker lock(metaTypeDataLock());
1038     QDeclarativeMetaTypeData *data = metaTypeData();
1039
1040     QDeclarativeMetaTypeData::MetaObjects::const_iterator it = data->metaObjectToType.find(metaObject);
1041     while (it != data->metaObjectToType.end() && it.key() == metaObject) {
1042         QDeclarativeType *t = *it;
1043         if (version_major < 0 || t->availableInVersion(module, version_major,version_minor))
1044             return t;
1045         ++it;
1046     }
1047
1048     return 0;
1049 }
1050
1051 /*!
1052     Returns the type (if any) that corresponds to the QVariant::Type \a userType.  
1053     Returns null if no type is registered.
1054 */
1055 QDeclarativeType *QDeclarativeMetaType::qmlType(int userType)
1056 {
1057     QReadLocker lock(metaTypeDataLock());
1058     QDeclarativeMetaTypeData *data = metaTypeData();
1059
1060     QDeclarativeType *type = data->idToType.value(userType);
1061     if (type && type->typeId() == userType)
1062         return type;
1063     else
1064         return 0;
1065 }
1066
1067 /*!
1068     Returns the list of registered QML type names.
1069 */
1070 QList<QByteArray> QDeclarativeMetaType::qmlTypeNames()
1071 {
1072     QReadLocker lock(metaTypeDataLock());
1073     QDeclarativeMetaTypeData *data = metaTypeData();
1074
1075     return data->nameToType.keys();
1076 }
1077
1078 /*!
1079     Returns the list of registered QML types.
1080 */
1081 QList<QDeclarativeType*> QDeclarativeMetaType::qmlTypes()
1082 {
1083     QReadLocker lock(metaTypeDataLock());
1084     QDeclarativeMetaTypeData *data = metaTypeData();
1085
1086     return data->nameToType.values();
1087 }
1088
1089 QT_END_NAMESPACE
1090
1091 #include <QtGui/qfont.h>
1092 #include <QtGui/qpixmap.h>
1093 #include <QtGui/qbrush.h>
1094 #include <QtGui/qcolor.h>
1095 #include <QtGui/qpalette.h>
1096 #include <QtGui/qicon.h>
1097 #include <QtGui/qimage.h>
1098 #include <QtGui/qpolygon.h>
1099 #include <QtGui/qregion.h>
1100 #include <QtGui/qbitmap.h>
1101 #include <QtGui/qcursor.h>
1102 #include <QtGui/qsizepolicy.h>
1103 #include <QtGui/qkeysequence.h>
1104 #include <QtGui/qpen.h>
1105
1106 //#include <QtGui/qtextlength.h>
1107 #include <QtGui/qtextformat.h>
1108 #include <QtGui/qmatrix.h>
1109 #include <QtGui/qtransform.h>
1110 #include <QtGui/qmatrix4x4.h>
1111 #include <QtGui/qvector2d.h>
1112 #include <QtGui/qvector3d.h>
1113 #include <QtGui/qvector4d.h>
1114 #include <QtGui/qquaternion.h>
1115 #include <private/qv8engine_p.h>
1116
1117 Q_DECLARE_METATYPE(QJSValue);
1118 Q_DECLARE_METATYPE(QDeclarativeV8Handle);
1119
1120 QT_BEGIN_NAMESPACE
1121
1122 bool QDeclarativeMetaType::canCopy(int type)
1123 {
1124     switch(type) {
1125     case QMetaType::VoidStar:
1126     case QMetaType::QObjectStar:
1127     case QMetaType::QWidgetStar:
1128     case QMetaType::Long:
1129     case QMetaType::Int:
1130     case QMetaType::Short:
1131     case QMetaType::Char:
1132     case QMetaType::ULong:
1133     case QMetaType::UInt:
1134     case QMetaType::LongLong:
1135     case QMetaType::ULongLong:
1136     case QMetaType::UShort:
1137     case QMetaType::UChar:
1138     case QMetaType::Bool:
1139     case QMetaType::Float:
1140     case QMetaType::Double:
1141     case QMetaType::QChar:
1142     case QMetaType::QVariantMap:
1143     case QMetaType::QVariantHash:
1144     case QMetaType::QVariantList:
1145     case QMetaType::QByteArray:
1146     case QMetaType::QString:
1147     case QMetaType::QStringList:
1148     case QMetaType::QBitArray:
1149     case QMetaType::QDate:
1150     case QMetaType::QTime:
1151     case QMetaType::QDateTime:
1152     case QMetaType::QUrl:
1153     case QMetaType::QLocale:
1154     case QMetaType::QRect:
1155     case QMetaType::QRectF:
1156     case QMetaType::QSize:
1157     case QMetaType::QSizeF:
1158     case QMetaType::QLine:
1159     case QMetaType::QLineF:
1160     case QMetaType::QPoint:
1161     case QMetaType::QPointF:
1162     case QMetaType::QVector3D:
1163 #ifndef QT_NO_REGEXP
1164     case QMetaType::QRegExp:
1165 #endif
1166     case QMetaType::Void:
1167 #ifdef QT3_SUPPORT
1168     case QMetaType::QColorGroup:
1169 #endif
1170     case QMetaType::QFont:
1171     case QMetaType::QPixmap:
1172     case QMetaType::QBrush:
1173     case QMetaType::QColor:
1174     case QMetaType::QPalette:
1175     case QMetaType::QIcon:
1176     case QMetaType::QImage:
1177     case QMetaType::QPolygon:
1178     case QMetaType::QRegion:
1179     case QMetaType::QBitmap:
1180 #ifndef QT_NO_CURSOR
1181     case QMetaType::QCursor:
1182 #endif
1183     case QMetaType::QSizePolicy:
1184     case QMetaType::QKeySequence:
1185     case QMetaType::QPen:
1186     case QMetaType::QTextLength:
1187     case QMetaType::QTextFormat:
1188     case QMetaType::QMatrix:
1189     case QMetaType::QTransform:
1190     case QMetaType::QMatrix4x4:
1191     case QMetaType::QVector2D:
1192     case QMetaType::QVector4D:
1193     case QMetaType::QQuaternion:
1194         return true;
1195
1196     default:
1197         if (type == qMetaTypeId<QVariant>() ||
1198             type == qMetaTypeId<QJSValue>() ||
1199             type == qMetaTypeId<QDeclarativeV8Handle>() ||
1200             typeCategory(type) != Unknown) {
1201             return true;
1202         }
1203         break;
1204     }
1205
1206     return false;
1207 }
1208
1209 /*!
1210     Copies \a copy into \a data, assuming they both are of type \a type.  If
1211     \a copy is zero, a default type is copied.  Returns true if the copy was
1212     successful and false if not.
1213
1214     \note This should move into QMetaType once complete
1215
1216 */
1217 bool QDeclarativeMetaType::copy(int type, void *data, const void *copy)
1218 {
1219     if (copy) {
1220         switch(type) {
1221         case QMetaType::VoidStar:
1222         case QMetaType::QObjectStar:
1223         case QMetaType::QWidgetStar:
1224             *static_cast<void **>(data) = *static_cast<void* const *>(copy);
1225             return true;
1226         case QMetaType::Long:
1227             *static_cast<long *>(data) = *static_cast<const long*>(copy);
1228             return true;
1229         case QMetaType::Int:
1230             *static_cast<int *>(data) = *static_cast<const int*>(copy);
1231             return true;
1232         case QMetaType::Short:
1233             *static_cast<short *>(data) = *static_cast<const short*>(copy);
1234             return true;
1235         case QMetaType::Char:
1236             *static_cast<char *>(data) = *static_cast<const char*>(copy);
1237             return true;
1238         case QMetaType::ULong:
1239             *static_cast<ulong *>(data) = *static_cast<const ulong*>(copy);
1240             return true;
1241         case QMetaType::UInt:
1242             *static_cast<uint *>(data) = *static_cast<const uint*>(copy);
1243             return true;
1244         case QMetaType::LongLong:
1245             *static_cast<qlonglong *>(data) = *static_cast<const qlonglong*>(copy);
1246             return true;
1247         case QMetaType::ULongLong:
1248             *static_cast<qulonglong *>(data) = *static_cast<const qulonglong*>(copy);
1249             return true;
1250         case QMetaType::UShort:
1251             *static_cast<ushort *>(data) = *static_cast<const ushort*>(copy);
1252             return true;
1253         case QMetaType::UChar:
1254             *static_cast<uchar *>(data) = *static_cast<const uchar*>(copy);
1255             return true;
1256         case QMetaType::Bool:
1257             *static_cast<bool *>(data) = *static_cast<const bool*>(copy);
1258             return true;
1259         case QMetaType::Float:
1260             *static_cast<float *>(data) = *static_cast<const float*>(copy);
1261             return true;
1262         case QMetaType::Double:
1263             *static_cast<double *>(data) = *static_cast<const double*>(copy);
1264             return true;
1265         case QMetaType::QChar:
1266             *static_cast<NS(QChar) *>(data) = *static_cast<const NS(QChar)*>(copy);
1267             return true;
1268         case QMetaType::QVariantMap:
1269             *static_cast<NS(QVariantMap) *>(data) = *static_cast<const NS(QVariantMap)*>(copy);
1270             return true;
1271         case QMetaType::QVariantHash:
1272             *static_cast<NS(QVariantHash) *>(data) = *static_cast<const NS(QVariantHash)*>(copy);
1273             return true;
1274         case QMetaType::QVariantList:
1275             *static_cast<NS(QVariantList) *>(data) = *static_cast<const NS(QVariantList)*>(copy);
1276             return true;
1277         case QMetaType::QByteArray:
1278             *static_cast<NS(QByteArray) *>(data) = *static_cast<const NS(QByteArray)*>(copy);
1279             return true;
1280         case QMetaType::QString:
1281             *static_cast<NS(QString) *>(data) = *static_cast<const NS(QString)*>(copy);
1282             return true;
1283         case QMetaType::QStringList:
1284             *static_cast<NS(QStringList) *>(data) = *static_cast<const NS(QStringList)*>(copy);
1285             return true;
1286         case QMetaType::QBitArray:
1287             *static_cast<NS(QBitArray) *>(data) = *static_cast<const NS(QBitArray)*>(copy);
1288             return true;
1289         case QMetaType::QDate:
1290             *static_cast<NS(QDate) *>(data) = *static_cast<const NS(QDate)*>(copy);
1291             return true;
1292         case QMetaType::QTime:
1293             *static_cast<NS(QTime) *>(data) = *static_cast<const NS(QTime)*>(copy);
1294             return true;
1295         case QMetaType::QDateTime:
1296             *static_cast<NS(QDateTime) *>(data) = *static_cast<const NS(QDateTime)*>(copy);
1297             return true;
1298         case QMetaType::QUrl:
1299             *static_cast<NS(QUrl) *>(data) = *static_cast<const NS(QUrl)*>(copy);
1300             return true;
1301         case QMetaType::QLocale:
1302             *static_cast<NS(QLocale) *>(data) = *static_cast<const NS(QLocale)*>(copy);
1303             return true;
1304         case QMetaType::QRect:
1305             *static_cast<NS(QRect) *>(data) = *static_cast<const NS(QRect)*>(copy);
1306             return true;
1307         case QMetaType::QRectF:
1308             *static_cast<NS(QRectF) *>(data) = *static_cast<const NS(QRectF)*>(copy);
1309             return true;
1310         case QMetaType::QSize:
1311             *static_cast<NS(QSize) *>(data) = *static_cast<const NS(QSize)*>(copy);
1312             return true;
1313         case QMetaType::QSizeF:
1314             *static_cast<NS(QSizeF) *>(data) = *static_cast<const NS(QSizeF)*>(copy);
1315             return true;
1316         case QMetaType::QLine:
1317             *static_cast<NS(QLine) *>(data) = *static_cast<const NS(QLine)*>(copy);
1318             return true;
1319         case QMetaType::QLineF:
1320             *static_cast<NS(QLineF) *>(data) = *static_cast<const NS(QLineF)*>(copy);
1321             return true;
1322         case QMetaType::QPoint:
1323             *static_cast<NS(QPoint) *>(data) = *static_cast<const NS(QPoint)*>(copy);
1324             return true;
1325         case QMetaType::QPointF:
1326             *static_cast<NS(QPointF) *>(data) = *static_cast<const NS(QPointF)*>(copy);
1327             return true;
1328         case QMetaType::QVector3D:
1329             *static_cast<NS(QVector3D) *>(data) = *static_cast<const NS(QVector3D)*>(copy);
1330             return true;
1331 #ifndef QT_NO_REGEXP
1332         case QMetaType::QRegExp:
1333             *static_cast<NS(QRegExp) *>(data) = *static_cast<const NS(QRegExp)*>(copy);
1334             return true;
1335 #endif
1336         case QMetaType::Void:
1337             return true;
1338
1339
1340 #ifdef QT3_SUPPORT
1341         case QMetaType::QColorGroup:
1342             *static_cast<NS(QColorGroup) *>(data) = *static_cast<const NS(QColorGroup)*>(copy);
1343             return true;
1344 #endif
1345
1346         case QMetaType::QFont:
1347             *static_cast<NS(QFont) *>(data) = *static_cast<const NS(QFont)*>(copy);
1348             return true;
1349         case QMetaType::QPixmap:
1350             *static_cast<NS(QPixmap) *>(data) = *static_cast<const NS(QPixmap)*>(copy);
1351             return true;
1352         case QMetaType::QBrush:
1353             *static_cast<NS(QBrush) *>(data) = *static_cast<const NS(QBrush)*>(copy);
1354             return true;
1355         case QMetaType::QColor:
1356             *static_cast<NS(QColor) *>(data) = *static_cast<const NS(QColor)*>(copy);
1357             return true;
1358         case QMetaType::QPalette:
1359             *static_cast<NS(QPalette) *>(data) = *static_cast<const NS(QPalette)*>(copy);
1360             return true;
1361         case QMetaType::QIcon:
1362             *static_cast<NS(QIcon) *>(data) = *static_cast<const NS(QIcon)*>(copy);
1363             return true;
1364         case QMetaType::QImage:
1365             *static_cast<NS(QImage) *>(data) = *static_cast<const NS(QImage)*>(copy);
1366             return true;
1367         case QMetaType::QPolygon:
1368             *static_cast<NS(QPolygon) *>(data) = *static_cast<const NS(QPolygon)*>(copy);
1369             return true;
1370         case QMetaType::QRegion:
1371             *static_cast<NS(QRegion) *>(data) = *static_cast<const NS(QRegion)*>(copy);
1372             return true;
1373         case QMetaType::QBitmap:
1374             *static_cast<NS(QBitmap) *>(data) = *static_cast<const NS(QBitmap)*>(copy);
1375             return true;
1376 #ifndef QT_NO_CURSOR
1377         case QMetaType::QCursor:
1378             *static_cast<NS(QCursor) *>(data) = *static_cast<const NS(QCursor)*>(copy);
1379             return true;
1380 #endif
1381         case QMetaType::QSizePolicy:
1382             *static_cast<NS(QSizePolicy) *>(data) = *static_cast<const NS(QSizePolicy)*>(copy);
1383             return true;
1384         case QMetaType::QKeySequence:
1385             *static_cast<NS(QKeySequence) *>(data) = *static_cast<const NS(QKeySequence)*>(copy);
1386             return true;
1387         case QMetaType::QPen:
1388             *static_cast<NS(QPen) *>(data) = *static_cast<const NS(QPen)*>(copy);
1389             return true;
1390         case QMetaType::QTextLength:
1391             *static_cast<NS(QTextLength) *>(data) = *static_cast<const NS(QTextLength)*>(copy);
1392             return true;
1393         case QMetaType::QTextFormat:
1394             *static_cast<NS(QTextFormat) *>(data) = *static_cast<const NS(QTextFormat)*>(copy);
1395             return true;
1396         case QMetaType::QMatrix:
1397             *static_cast<NS(QMatrix) *>(data) = *static_cast<const NS(QMatrix)*>(copy);
1398             return true;
1399         case QMetaType::QTransform:
1400             *static_cast<NS(QTransform) *>(data) = *static_cast<const NS(QTransform)*>(copy);
1401             return true;
1402         case QMetaType::QMatrix4x4:
1403             *static_cast<NS(QMatrix4x4) *>(data) = *static_cast<const NS(QMatrix4x4)*>(copy);
1404             return true;
1405         case QMetaType::QVector2D:
1406             *static_cast<NS(QVector2D) *>(data) = *static_cast<const NS(QVector2D)*>(copy);
1407             return true;
1408         case QMetaType::QVector4D:
1409             *static_cast<NS(QVector4D) *>(data) = *static_cast<const NS(QVector4D)*>(copy);
1410             return true;
1411         case QMetaType::QQuaternion:
1412             *static_cast<NS(QQuaternion) *>(data) = *static_cast<const NS(QQuaternion)*>(copy);
1413             return true;
1414
1415         default:
1416             if (type == qMetaTypeId<QVariant>()) {
1417                 *static_cast<NS(QVariant) *>(data) = *static_cast<const NS(QVariant)*>(copy);
1418                 return true;
1419             } else if (type == qMetaTypeId<QJSValue>()) {
1420                 *static_cast<NS(QJSValue) *>(data) = *static_cast<const NS(QJSValue)*>(copy);
1421                 return true;
1422             } else if (type == qMetaTypeId<QDeclarativeV8Handle>()) {
1423                 *static_cast<NS(QDeclarativeV8Handle) *>(data) = *static_cast<const NS(QDeclarativeV8Handle)*>(copy);
1424                 return true;
1425             } else if (typeCategory(type) != Unknown) {
1426                 *static_cast<void **>(data) = *static_cast<void* const *>(copy);
1427                 return true;
1428             }
1429             break;
1430         }
1431     } else {
1432         switch(type) {
1433         case QMetaType::VoidStar:
1434         case QMetaType::QObjectStar:
1435         case QMetaType::QWidgetStar:
1436             *static_cast<void **>(data) = 0;
1437             return true;
1438         case QMetaType::Long:
1439             *static_cast<long *>(data) = long(0);
1440             return true;
1441         case QMetaType::Int:
1442             *static_cast<int *>(data) = int(0);
1443             return true;
1444         case QMetaType::Short:
1445             *static_cast<short *>(data) = short(0);
1446             return true;
1447         case QMetaType::Char:
1448             *static_cast<char *>(data) = char(0);
1449             return true;
1450         case QMetaType::ULong:
1451             *static_cast<ulong *>(data) = ulong(0);
1452             return true;
1453         case QMetaType::UInt:
1454             *static_cast<uint *>(data) = uint(0);
1455             return true;
1456         case QMetaType::LongLong:
1457             *static_cast<qlonglong *>(data) = qlonglong(0);
1458             return true;
1459         case QMetaType::ULongLong:
1460             *static_cast<qulonglong *>(data) = qulonglong(0);
1461             return true;
1462         case QMetaType::UShort:
1463             *static_cast<ushort *>(data) = ushort(0);
1464             return true;
1465         case QMetaType::UChar:
1466             *static_cast<uchar *>(data) = uchar(0);
1467             return true;
1468         case QMetaType::Bool:
1469             *static_cast<bool *>(data) = bool(false);
1470             return true;
1471         case QMetaType::Float:
1472             *static_cast<float *>(data) = float(0);
1473             return true;
1474         case QMetaType::Double:
1475             *static_cast<double *>(data) = double(0);
1476             return true;
1477         case QMetaType::QChar:
1478             *static_cast<NS(QChar) *>(data) = NS(QChar)();
1479             return true;
1480         case QMetaType::QVariantMap:
1481             *static_cast<NS(QVariantMap) *>(data) = NS(QVariantMap)();
1482             return true;
1483         case QMetaType::QVariantHash:
1484             *static_cast<NS(QVariantHash) *>(data) = NS(QVariantHash)();
1485             return true;
1486         case QMetaType::QVariantList:
1487             *static_cast<NS(QVariantList) *>(data) = NS(QVariantList)();
1488             return true;
1489         case QMetaType::QByteArray:
1490             *static_cast<NS(QByteArray) *>(data) = NS(QByteArray)();
1491             return true;
1492         case QMetaType::QString:
1493             *static_cast<NS(QString) *>(data) = NS(QString)();
1494             return true;
1495         case QMetaType::QStringList:
1496             *static_cast<NS(QStringList) *>(data) = NS(QStringList)();
1497             return true;
1498         case QMetaType::QBitArray:
1499             *static_cast<NS(QBitArray) *>(data) = NS(QBitArray)();
1500             return true;
1501         case QMetaType::QDate:
1502             *static_cast<NS(QDate) *>(data) = NS(QDate)();
1503             return true;
1504         case QMetaType::QTime:
1505             *static_cast<NS(QTime) *>(data) = NS(QTime)();
1506             return true;
1507         case QMetaType::QDateTime:
1508             *static_cast<NS(QDateTime) *>(data) = NS(QDateTime)();
1509             return true;
1510         case QMetaType::QUrl:
1511             *static_cast<NS(QUrl) *>(data) = NS(QUrl)();
1512             return true;
1513         case QMetaType::QLocale:
1514             *static_cast<NS(QLocale) *>(data) = NS(QLocale)();
1515             return true;
1516         case QMetaType::QRect:
1517             *static_cast<NS(QRect) *>(data) = NS(QRect)();
1518             return true;
1519         case QMetaType::QRectF:
1520             *static_cast<NS(QRectF) *>(data) = NS(QRectF)();
1521             return true;
1522         case QMetaType::QSize:
1523             *static_cast<NS(QSize) *>(data) = NS(QSize)();
1524             return true;
1525         case QMetaType::QSizeF:
1526             *static_cast<NS(QSizeF) *>(data) = NS(QSizeF)();
1527             return true;
1528         case QMetaType::QLine:
1529             *static_cast<NS(QLine) *>(data) = NS(QLine)();
1530             return true;
1531         case QMetaType::QLineF:
1532             *static_cast<NS(QLineF) *>(data) = NS(QLineF)();
1533             return true;
1534         case QMetaType::QPoint:
1535             *static_cast<NS(QPoint) *>(data) = NS(QPoint)();
1536             return true;
1537         case QMetaType::QPointF:
1538             *static_cast<NS(QPointF) *>(data) = NS(QPointF)();
1539             return true;
1540         case QMetaType::QVector3D:
1541             *static_cast<NS(QVector3D) *>(data) = NS(QVector3D)();
1542             return true;
1543 #ifndef QT_NO_REGEXP
1544         case QMetaType::QRegExp:
1545             *static_cast<NS(QRegExp) *>(data) = NS(QRegExp)();
1546             return true;
1547 #endif
1548         case QMetaType::Void:
1549             return true;
1550
1551 #ifdef QT3_SUPPORT
1552         case QMetaType::QColorGroup:
1553             *static_cast<NS(QColorGroup) *>(data) = NS(QColorGroup)();
1554             return true;
1555 #endif
1556
1557         case QMetaType::QFont:
1558             *static_cast<NS(QFont) *>(data) = NS(QFont)();
1559             return true;
1560         case QMetaType::QPixmap:
1561             *static_cast<NS(QPixmap) *>(data) = NS(QPixmap)();
1562             return true;
1563         case QMetaType::QBrush:
1564             *static_cast<NS(QBrush) *>(data) = NS(QBrush)();
1565             return true;
1566         case QMetaType::QColor:
1567             *static_cast<NS(QColor) *>(data) = NS(QColor)();
1568             return true;
1569         case QMetaType::QPalette:
1570             *static_cast<NS(QPalette) *>(data) = NS(QPalette)();
1571             return true;
1572         case QMetaType::QIcon:
1573             *static_cast<NS(QIcon) *>(data) = NS(QIcon)();
1574             return true;
1575         case QMetaType::QImage:
1576             *static_cast<NS(QImage) *>(data) = NS(QImage)();
1577             return true;
1578         case QMetaType::QPolygon:
1579             *static_cast<NS(QPolygon) *>(data) = NS(QPolygon)();
1580             return true;
1581         case QMetaType::QRegion:
1582             *static_cast<NS(QRegion) *>(data) = NS(QRegion)();
1583             return true;
1584         case QMetaType::QBitmap:
1585             *static_cast<NS(QBitmap) *>(data) = NS(QBitmap)();
1586             return true;
1587 #ifndef QT_NO_CURSOR
1588         case QMetaType::QCursor:
1589             *static_cast<NS(QCursor) *>(data) = NS(QCursor)();
1590             return true;
1591 #endif
1592         case QMetaType::QSizePolicy:
1593             *static_cast<NS(QSizePolicy) *>(data) = NS(QSizePolicy)();
1594             return true;
1595         case QMetaType::QKeySequence:
1596             *static_cast<NS(QKeySequence) *>(data) = NS(QKeySequence)();
1597             return true;
1598         case QMetaType::QPen:
1599             *static_cast<NS(QPen) *>(data) = NS(QPen)();
1600             return true;
1601         case QMetaType::QTextLength:
1602             *static_cast<NS(QTextLength) *>(data) = NS(QTextLength)();
1603             return true;
1604         case QMetaType::QTextFormat:
1605             *static_cast<NS(QTextFormat) *>(data) = NS(QTextFormat)();
1606             return true;
1607         case QMetaType::QMatrix:
1608             *static_cast<NS(QMatrix) *>(data) = NS(QMatrix)();
1609             return true;
1610         case QMetaType::QTransform:
1611             *static_cast<NS(QTransform) *>(data) = NS(QTransform)();
1612             return true;
1613         case QMetaType::QMatrix4x4:
1614             *static_cast<NS(QMatrix4x4) *>(data) = NS(QMatrix4x4)();
1615             return true;
1616         case QMetaType::QVector2D:
1617             *static_cast<NS(QVector2D) *>(data) = NS(QVector2D)();
1618             return true;
1619         case QMetaType::QVector4D:
1620             *static_cast<NS(QVector4D) *>(data) = NS(QVector4D)();
1621             return true;
1622         case QMetaType::QQuaternion:
1623             *static_cast<NS(QQuaternion) *>(data) = NS(QQuaternion)();
1624             return true;
1625         default:
1626             if (type == qMetaTypeId<QVariant>()) {
1627                 *static_cast<NS(QVariant) *>(data) = NS(QVariant)();
1628                 return true;
1629             } else if (type == qMetaTypeId<QJSValue>()) {
1630                 *static_cast<NS(QJSValue) *>(data) = NS(QJSValue)();
1631                 return true;
1632             } else if (type == qMetaTypeId<QDeclarativeV8Handle>()) {
1633                 *static_cast<NS(QDeclarativeV8Handle) *>(data) = NS(QDeclarativeV8Handle)();
1634                 return true;
1635             } else if (typeCategory(type) != Unknown) {
1636                 *static_cast<void **>(data) = 0;
1637                 return true;
1638             }
1639             break;
1640         }
1641     }
1642
1643     return false;
1644 }
1645
1646 QT_END_NAMESPACE