Merge branch 'master' of git://scm.dev.nokia.troll.no/qt/qtdeclarative
[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 <QtScript/qscriptvalue.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_min(major), vminor_min(minor), vmajor_max(major), vminor_max(minor) {}
114         ModuleInfo(int major_min, int minor_min, int major_max, int minor_max)
115             : vmajor_min(major_min), vminor_min(minor_min), vmajor_max(major_max), vminor_max(minor_max) {}
116         int vmajor_min, vminor_min;
117         int vmajor_max, vminor_max;
118     };
119     typedef QHash<QByteArray, 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 || (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 || (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     // Clone Q_CLASSINFO
298     for (int ii = mo->classInfoOffset(); ii < mo->classInfoCount(); ++ii) {
299         QMetaClassInfo info = mo->classInfo(ii);
300
301         int otherIndex = ignoreEnd->indexOfClassInfo(info.name());
302         if (otherIndex >= ignoreStart->classInfoOffset() + ignoreStart->classInfoCount()) {
303             // Skip 
304         } else {
305             builder.addClassInfo(info.name(), info.value());
306         }
307     }
308
309     // Clone Q_PROPERTY
310     for (int ii = mo->propertyOffset(); ii < mo->propertyCount(); ++ii) {
311         QMetaProperty property = mo->property(ii);
312
313         int otherIndex = ignoreEnd->indexOfProperty(property.name());
314         if (otherIndex >= ignoreStart->propertyOffset() + ignoreStart->propertyCount()) {
315             builder.addProperty(QByteArray("__qml_ignore__") + property.name(), QByteArray("void"));
316             // Skip 
317         } else {
318             builder.addProperty(property);
319         }
320     }
321
322     // Clone Q_METHODS
323     for (int ii = mo->methodOffset(); ii < mo->methodCount(); ++ii) {
324         QMetaMethod method = mo->method(ii);
325
326         // More complex - need to search name
327         QByteArray name = method.signature();
328         int parenIdx = name.indexOf('(');
329         if (parenIdx != -1) name = name.left(parenIdx);
330
331
332         bool found = false;
333
334         for (int ii = ignoreStart->methodOffset() + ignoreStart->methodCount(); 
335              !found && ii < ignoreEnd->methodOffset() + ignoreEnd->methodCount();
336              ++ii) {
337
338             QMetaMethod other = ignoreEnd->method(ii);
339             QByteArray othername = other.signature();
340             int parenIdx = othername.indexOf('(');
341             if (parenIdx != -1) othername = othername.left(parenIdx);
342
343             found = name == othername;
344         }
345
346         QMetaMethodBuilder m = builder.addMethod(method);
347         if (found) // SKIP
348             m.setAccess(QMetaMethod::Private);
349     }
350
351     // Clone Q_ENUMS
352     for (int ii = mo->enumeratorOffset(); ii < mo->enumeratorCount(); ++ii) {
353         QMetaEnum enumerator = mo->enumerator(ii);
354
355         int otherIndex = ignoreEnd->indexOfEnumerator(enumerator.name());
356         if (otherIndex >= ignoreStart->enumeratorOffset() + ignoreStart->enumeratorCount()) {
357             // Skip 
358         } else {
359             builder.addEnumerator(enumerator);
360         }
361     }
362 }
363
364 void QDeclarativeTypePrivate::init() const
365 {
366     if (m_isSetup) return;
367
368     QWriteLocker lock(metaTypeDataLock());
369     if (m_isSetup)
370         return;
371
372     // Setup extended meta object
373     // XXX - very inefficient
374     const QMetaObject *mo = m_baseMetaObject;
375     if (m_extFunc) {
376         QMetaObject *mmo = new QMetaObject;
377         *mmo = *m_extMetaObject;
378         mmo->d.superdata = mo;
379         QDeclarativeProxyMetaObject::ProxyData data = { mmo, m_extFunc, 0, 0 };
380         m_metaObjects << data;
381     }
382
383     mo = mo->d.superdata;
384     while(mo) {
385         QDeclarativeType *t = metaTypeData()->metaObjectToType.value(mo);
386         if (t) {
387             if (t->d->m_extFunc) {
388                 QMetaObjectBuilder builder;
389                 clone(builder, t->d->m_extMetaObject, t->d->m_baseMetaObject, m_baseMetaObject);
390                 QMetaObject *mmo = builder.toMetaObject();
391                 mmo->d.superdata = m_baseMetaObject;
392                 if (!m_metaObjects.isEmpty())
393                     m_metaObjects.last().metaObject->d.superdata = mmo;
394                 QDeclarativeProxyMetaObject::ProxyData data = { mmo, t->d->m_extFunc, 0, 0 };
395                 m_metaObjects << data;
396             }
397         }
398         mo = mo->d.superdata;
399     }
400
401     for (int ii = 0; ii < m_metaObjects.count(); ++ii) {
402         m_metaObjects[ii].propertyOffset =
403             m_metaObjects.at(ii).metaObject->propertyOffset();
404         m_metaObjects[ii].methodOffset =
405             m_metaObjects.at(ii).metaObject->methodOffset();
406     }
407     
408     // Check for revisioned details
409     {
410         const QMetaObject *mo = 0;
411         if (m_metaObjects.isEmpty())
412             mo = m_baseMetaObject;
413         else
414             mo = m_metaObjects.first().metaObject;
415
416         for (int ii = 0; !m_containsRevisionedAttributes && ii < mo->propertyCount(); ++ii) {
417             if (mo->property(ii).revision() != 0)
418                 m_containsRevisionedAttributes = true;
419         }
420
421         for (int ii = 0; !m_containsRevisionedAttributes && ii < mo->methodCount(); ++ii) {
422             if (mo->method(ii).revision() != 0)
423                 m_containsRevisionedAttributes = true;
424         }
425     }
426
427     m_isSetup = true;
428     lock.unlock();
429 }
430
431 QByteArray QDeclarativeType::typeName() const
432 {
433     if (d->m_baseMetaObject)
434         return d->m_baseMetaObject->className();
435     else
436         return QByteArray();
437 }
438
439 QByteArray QDeclarativeType::qmlTypeName() const
440 {
441     return d->m_name;
442 }
443
444 QObject *QDeclarativeType::create() const
445 {
446     d->init();
447
448     QObject *rv = (QObject *)operator new(d->m_allocationSize);
449     d->m_newFunc(rv);
450
451     if (rv && !d->m_metaObjects.isEmpty())
452         (void *)new QDeclarativeProxyMetaObject(rv, &d->m_metaObjects);
453
454     return rv;
455 }
456
457 void QDeclarativeType::create(QObject **out, void **memory, size_t additionalMemory) const
458 {
459     d->init();
460
461     QObject *rv = (QObject *)operator new(d->m_allocationSize + additionalMemory);
462     d->m_newFunc(rv);
463
464     if (rv && !d->m_metaObjects.isEmpty())
465         (void *)new QDeclarativeProxyMetaObject(rv, &d->m_metaObjects);
466
467     *out = rv;
468     *memory = ((char *)rv) + d->m_allocationSize;
469 }
470
471 QDeclarativeCustomParser *QDeclarativeType::customParser() const
472 {
473     return d->m_customParser;
474 }
475
476 QDeclarativeType::CreateFunc QDeclarativeType::createFunction() const
477 {
478     return d->m_newFunc;
479 }
480
481 QString QDeclarativeType::noCreationReason() const
482 {
483     return d->m_noCreationReason;
484 }
485
486 int QDeclarativeType::createSize() const
487 {
488     return d->m_allocationSize;
489 }
490
491 bool QDeclarativeType::isCreatable() const
492 {
493     return d->m_newFunc != 0;
494 }
495
496 bool QDeclarativeType::isExtendedType() const
497 {
498     d->init();
499
500     return !d->m_metaObjects.isEmpty();
501 }
502
503 bool QDeclarativeType::isInterface() const
504 {
505     return d->m_isInterface;
506 }
507
508 int QDeclarativeType::typeId() const
509 {
510     return d->m_typeId;
511 }
512
513 int QDeclarativeType::qListTypeId() const
514 {
515     return d->m_listId;
516 }
517
518 const QMetaObject *QDeclarativeType::metaObject() const
519 {
520     d->init();
521
522     if (d->m_metaObjects.isEmpty())
523         return d->m_baseMetaObject;
524     else
525         return d->m_metaObjects.first().metaObject;
526
527 }
528
529 const QMetaObject *QDeclarativeType::baseMetaObject() const
530 {
531     return d->m_baseMetaObject;
532 }
533
534 bool QDeclarativeType::containsRevisionedAttributes() const
535 {
536     d->init();
537
538     return d->m_containsRevisionedAttributes;
539 }
540
541 int QDeclarativeType::metaObjectRevision() const
542 {
543     return d->m_revision;
544 }
545
546 QDeclarativeAttachedPropertiesFunc QDeclarativeType::attachedPropertiesFunction() const
547 {
548     return d->m_attachedPropertiesFunc;
549 }
550
551 const QMetaObject *QDeclarativeType::attachedPropertiesType() const
552 {
553     return d->m_attachedPropertiesType;
554 }
555
556 /*
557 This is the id passed to qmlAttachedPropertiesById().  This is different from the index
558 for the case that a single class is registered under two or more names (eg. Item in 
559 Qt 4.7 and QtQuick 1.0).
560 */
561 int QDeclarativeType::attachedPropertiesId() const
562 {
563     return d->m_attachedPropertiesId;
564 }
565
566 int QDeclarativeType::parserStatusCast() const
567 {
568     return d->m_parserStatusCast;
569 }
570
571 int QDeclarativeType::propertyValueSourceCast() const
572 {
573     return d->m_propertyValueSourceCast;
574 }
575
576 int QDeclarativeType::propertyValueInterceptorCast() const
577 {
578     return d->m_propertyValueInterceptorCast;
579 }
580
581 const char *QDeclarativeType::interfaceIId() const
582 {
583     return d->m_iid;
584 }
585
586 int QDeclarativeType::index() const
587 {
588     return d->m_index;
589 }
590
591 int registerAutoParentFunction(QDeclarativePrivate::RegisterAutoParent &autoparent)
592 {
593     QWriteLocker lock(metaTypeDataLock());
594     QDeclarativeMetaTypeData *data = metaTypeData();
595
596     data->parentFunctions.append(autoparent.function);
597
598     return data->parentFunctions.count() - 1;
599 }
600
601 int registerInterface(const QDeclarativePrivate::RegisterInterface &interface)
602 {
603     if (interface.version > 0) 
604         qFatal("qmlRegisterType(): Cannot mix incompatible QML versions.");
605
606     QWriteLocker lock(metaTypeDataLock());
607     QDeclarativeMetaTypeData *data = metaTypeData();
608
609     int index = data->types.count();
610
611     QDeclarativeType *type = new QDeclarativeType(index, interface);
612
613     data->types.append(type);
614     data->idToType.insert(type->typeId(), type);
615     data->idToType.insert(type->qListTypeId(), type);
616     // XXX No insertMulti, so no multi-version interfaces?
617     if (!type->qmlTypeName().isEmpty())
618         data->nameToType.insert(type->qmlTypeName(), type);
619
620     if (data->interfaces.size() <= interface.typeId)
621         data->interfaces.resize(interface.typeId + 16);
622     if (data->lists.size() <= interface.listId)
623         data->lists.resize(interface.listId + 16);
624     data->interfaces.setBit(interface.typeId, true);
625     data->lists.setBit(interface.listId, true);
626
627     return index;
628 }
629
630 int registerType(const QDeclarativePrivate::RegisterType &type)
631 {
632     if (type.elementName) {
633         for (int ii = 0; type.elementName[ii]; ++ii) {
634             if (!isalnum(type.elementName[ii])) {
635                 qWarning("qmlRegisterType(): Invalid QML element name \"%s\"", type.elementName);
636                 return -1;
637             }
638         }
639     }
640
641     QWriteLocker lock(metaTypeDataLock());
642     QDeclarativeMetaTypeData *data = metaTypeData();
643     int index = data->types.count();
644
645     QDeclarativeType *dtype = new QDeclarativeType(index, type);
646
647     data->types.append(dtype);
648     data->idToType.insert(dtype->typeId(), dtype);
649     if (dtype->qListTypeId()) data->idToType.insert(dtype->qListTypeId(), dtype);
650
651     if (!dtype->qmlTypeName().isEmpty())
652         data->nameToType.insertMulti(dtype->qmlTypeName(), dtype);
653
654     data->metaObjectToType.insertMulti(dtype->baseMetaObject(), dtype);
655
656     if (data->objects.size() <= type.typeId)
657         data->objects.resize(type.typeId + 16);
658     if (data->lists.size() <= type.listId)
659         data->lists.resize(type.listId + 16);
660     data->objects.setBit(type.typeId, true);
661     if (type.listId) data->lists.setBit(type.listId, true);
662
663     if (type.uri) {
664         QByteArray mod(type.uri);
665         QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.find(mod);
666         if (it == data->modules.end()) {
667             // New module
668             data->modules.insert(mod, QDeclarativeMetaTypeData::ModuleInfo(type.versionMajor,type.versionMinor));
669         } else if ((*it).vmajor_max < type.versionMajor || ((*it).vmajor_max == type.versionMajor && (*it).vminor_max < type.versionMinor)) {
670             // Newer module
671             data->modules.insert(mod, QDeclarativeMetaTypeData::ModuleInfo((*it).vmajor_min, (*it).vminor_min, type.versionMajor, type.versionMinor));
672         } else if ((*it).vmajor_min > type.versionMajor || ((*it).vmajor_min == type.versionMajor && (*it).vminor_min > type.versionMinor)) {
673             // Older module
674             data->modules.insert(mod, QDeclarativeMetaTypeData::ModuleInfo(type.versionMajor, type.versionMinor, (*it).vmajor_min, (*it).vminor_min));
675         }
676     }
677
678     return index;
679 }
680
681 int registerModuleApi(const QDeclarativePrivate::RegisterModuleApi &api)
682 {
683     QWriteLocker lock(metaTypeDataLock());
684
685     QDeclarativeMetaTypeData *data = metaTypeData();
686     QByteArray uri(api.uri);
687     QDeclarativeMetaType::ModuleApi import;
688     import.major = api.versionMajor;
689     import.minor = api.versionMinor;
690     import.script = api.scriptApi;
691     import.qobject = api.qobjectApi;
692
693     int index = data->moduleApiCount++;
694
695     QDeclarativeMetaTypeData::ModuleApis::Iterator iter = data->moduleApis.find(uri);
696     if (iter == data->moduleApis.end()) {
697         QDeclarativeMetaTypeData::ModuleApiList apis;
698         apis.moduleApis << import;
699         data->moduleApis.insert(uri, apis);
700     } else {
701         iter->moduleApis << import;
702         iter->sorted = false;
703     }
704
705     return index;
706 }
707
708
709 /*
710 This method is "over generalized" to allow us to (potentially) register more types of things in
711 the future without adding exported symbols.
712 */
713 int QDeclarativePrivate::qmlregister(RegistrationType type, void *data)
714 {
715     if (type == TypeRegistration) {
716         return registerType(*reinterpret_cast<RegisterType *>(data));
717     } else if (type == InterfaceRegistration) {
718         return registerInterface(*reinterpret_cast<RegisterInterface *>(data));
719     } else if (type == AutoParentRegistration) {
720         return registerAutoParentFunction(*reinterpret_cast<RegisterAutoParent *>(data));
721     } else if (type == ModuleApiRegistration) {
722         return registerModuleApi(*reinterpret_cast<RegisterModuleApi *>(data));
723     }
724     return -1;
725 }
726
727 /*
728     Returns true if any type or API has been registered for the given \a module with at least
729     versionMajor.versionMinor, or if types have been registered for \a module with at most
730     versionMajor.versionMinor.
731
732     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.
733
734     Passing -1 for both \a versionMajor \a versionMinor will return true if any version is installed.
735 */
736 bool QDeclarativeMetaType::isModule(const QByteArray &module, int versionMajor, int versionMinor)
737 {
738     QDeclarativeMetaTypeData *data = metaTypeData();
739
740     // first, check Types
741     QDeclarativeMetaTypeData::ModuleInfoHash::Iterator it = data->modules.find(module);
742     if (it != data->modules.end()
743         && ((versionMajor<0 && versionMinor<0) ||
744                 (((*it).vmajor_max > versionMajor ||
745                     ((*it).vmajor_max == versionMajor && (*it).vminor_max >= versionMinor))
746                 && ((*it).vmajor_min < versionMajor ||
747                     ((*it).vmajor_min == versionMajor && (*it).vminor_min <= versionMinor))))) {
748         return true;
749     }
750
751     // then, check ModuleApis
752     foreach (const QDeclarativeMetaType::ModuleApi &mApi, data->moduleApis.value(module).moduleApis) {
753         if ((versionMajor<0 && versionMinor<0)
754                 || (mApi.major == versionMajor && mApi.minor == versionMinor)) {
755             return true;
756         }
757     }
758
759     return false;
760 }
761
762 QList<QDeclarativePrivate::AutoParentFunction> QDeclarativeMetaType::parentFunctions()
763 {
764     QReadLocker lock(metaTypeDataLock());
765     QDeclarativeMetaTypeData *data = metaTypeData();
766     return data->parentFunctions;
767 }
768
769 static bool operator<(const QDeclarativeMetaType::ModuleApi &lhs, const QDeclarativeMetaType::ModuleApi &rhs)
770 {
771     return lhs.major < rhs.major || (lhs.major == rhs.major && lhs.minor < rhs.minor);
772 }
773
774 QDeclarativeMetaType::ModuleApi
775 QDeclarativeMetaType::moduleApi(const QByteArray &uri, int versionMajor, int versionMinor)
776 {
777     QReadLocker lock(metaTypeDataLock());
778     QDeclarativeMetaTypeData *data = metaTypeData();
779
780     QDeclarativeMetaTypeData::ModuleApis::Iterator iter = data->moduleApis.find(uri);
781     if (iter == data->moduleApis.end())
782         return ModuleApi();
783
784     if (iter->sorted == false) {
785         qSort(iter->moduleApis.begin(), iter->moduleApis.end());
786         iter->sorted = true;
787     }
788
789     for (int ii = iter->moduleApis.count() - 1; ii >= 0; --ii) {
790         const ModuleApi &import = iter->moduleApis.at(ii);
791         if (import.major == versionMajor && import.minor <= versionMinor)
792             return import;
793     }
794
795     return ModuleApi();
796 }
797
798 QObject *QDeclarativeMetaType::toQObject(const QVariant &v, bool *ok)
799 {
800     if (!isQObject(v.userType())) {
801         if (ok) *ok = false;
802         return 0;
803     }
804
805     if (ok) *ok = true;
806
807     return *(QObject **)v.constData();
808 }
809
810 bool QDeclarativeMetaType::isQObject(int userType)
811 {
812     if (userType == QMetaType::QObjectStar)
813         return true;
814
815     QReadLocker lock(metaTypeDataLock());
816     QDeclarativeMetaTypeData *data = metaTypeData();
817     return userType >= 0 && userType < data->objects.size() && data->objects.testBit(userType);
818 }
819
820 /*
821     Returns the item type for a list of type \a id.
822  */
823 int QDeclarativeMetaType::listType(int id)
824 {
825     QReadLocker lock(metaTypeDataLock());
826     QDeclarativeMetaTypeData *data = metaTypeData();
827     QDeclarativeType *type = data->idToType.value(id);
828     if (type && type->qListTypeId() == id)
829         return type->typeId();
830     else
831         return 0;
832 }
833
834 int QDeclarativeMetaType::attachedPropertiesFuncId(const QMetaObject *mo)
835 {
836     QReadLocker lock(metaTypeDataLock());
837     QDeclarativeMetaTypeData *data = metaTypeData();
838
839     QDeclarativeType *type = data->metaObjectToType.value(mo);
840     if (type && type->attachedPropertiesFunction())
841         return type->attachedPropertiesId();
842     else
843         return -1;
844 }
845
846 QDeclarativeAttachedPropertiesFunc QDeclarativeMetaType::attachedPropertiesFuncById(int id)
847 {
848     if (id < 0)
849         return 0;
850     QReadLocker lock(metaTypeDataLock());
851     QDeclarativeMetaTypeData *data = metaTypeData();
852     return data->types.at(id)->attachedPropertiesFunction();
853 }
854
855 QMetaProperty QDeclarativeMetaType::defaultProperty(const QMetaObject *metaObject)
856 {
857     int idx = metaObject->indexOfClassInfo("DefaultProperty");
858     if (-1 == idx)
859         return QMetaProperty();
860
861     QMetaClassInfo info = metaObject->classInfo(idx);
862     if (!info.value())
863         return QMetaProperty();
864
865     idx = metaObject->indexOfProperty(info.value());
866     if (-1 == idx)
867         return QMetaProperty();
868
869     return metaObject->property(idx);
870 }
871
872 QMetaProperty QDeclarativeMetaType::defaultProperty(QObject *obj)
873 {
874     if (!obj)
875         return QMetaProperty();
876
877     const QMetaObject *metaObject = obj->metaObject();
878     return defaultProperty(metaObject);
879 }
880
881 QMetaMethod QDeclarativeMetaType::defaultMethod(const QMetaObject *metaObject)
882 {
883     int idx = metaObject->indexOfClassInfo("DefaultMethod");
884     if (-1 == idx)
885         return QMetaMethod();
886
887     QMetaClassInfo info = metaObject->classInfo(idx);
888     if (!info.value())
889         return QMetaMethod();
890
891     idx = metaObject->indexOfMethod(info.value());
892     if (-1 == idx)
893         return QMetaMethod();
894
895     return metaObject->method(idx);
896 }
897
898 QMetaMethod QDeclarativeMetaType::defaultMethod(QObject *obj)
899 {
900     if (!obj)
901         return QMetaMethod();
902
903     const QMetaObject *metaObject = obj->metaObject();
904     return defaultMethod(metaObject);
905 }
906
907 QDeclarativeMetaType::TypeCategory QDeclarativeMetaType::typeCategory(int userType)
908 {
909     if (userType < 0)
910         return Unknown;
911     if (userType == QMetaType::QObjectStar)
912         return Object;
913
914     QReadLocker lock(metaTypeDataLock());
915     QDeclarativeMetaTypeData *data = metaTypeData();
916     if (userType < data->objects.size() && data->objects.testBit(userType))
917         return Object;
918     else if (userType < data->lists.size() && data->lists.testBit(userType))
919         return List;
920     else
921         return Unknown;
922 }
923
924 bool QDeclarativeMetaType::isInterface(int userType)
925 {
926     QReadLocker lock(metaTypeDataLock());
927     QDeclarativeMetaTypeData *data = metaTypeData();
928     return userType >= 0 && userType < data->interfaces.size() && data->interfaces.testBit(userType);
929 }
930
931 const char *QDeclarativeMetaType::interfaceIId(int userType)
932 {
933     QReadLocker lock(metaTypeDataLock());
934     QDeclarativeMetaTypeData *data = metaTypeData();
935     QDeclarativeType *type = data->idToType.value(userType);
936     lock.unlock();
937     if (type && type->isInterface() && type->typeId() == userType)
938         return type->interfaceIId();
939     else
940         return 0;
941 }
942
943 bool QDeclarativeMetaType::isList(int userType)
944 {
945     QReadLocker lock(metaTypeDataLock());
946     QDeclarativeMetaTypeData *data = metaTypeData();
947     return userType >= 0 && userType < data->lists.size() && data->lists.testBit(userType);
948 }
949
950 /*!
951     A custom string convertor allows you to specify a function pointer that
952     returns a variant of \a type. For example, if you have written your own icon
953     class that you want to support as an object property assignable in QML:
954
955     \code
956     int type = qRegisterMetaType<SuperIcon>("SuperIcon");
957     QML::addCustomStringConvertor(type, &SuperIcon::pixmapFromString);
958     \endcode
959
960     The function pointer must be of the form:
961     \code
962     QVariant (*StringConverter)(const QString &);
963     \endcode
964  */
965 void QDeclarativeMetaType::registerCustomStringConverter(int type, StringConverter converter)
966 {
967     QWriteLocker lock(metaTypeDataLock());
968
969     QDeclarativeMetaTypeData *data = metaTypeData();
970     if (data->stringConverters.contains(type))
971         return;
972     data->stringConverters.insert(type, converter);
973 }
974
975 /*!
976     Return the custom string converter for \a type, previously installed through
977     registerCustomStringConverter()
978  */
979 QDeclarativeMetaType::StringConverter QDeclarativeMetaType::customStringConverter(int type)
980 {
981     QReadLocker lock(metaTypeDataLock());
982
983     QDeclarativeMetaTypeData *data = metaTypeData();
984     return data->stringConverters.value(type);
985 }
986
987 /*!
988     Returns the type (if any) of URI-qualified named \a name in version specified
989     by \a version_major and \a version_minor.
990 */
991 QDeclarativeType *QDeclarativeMetaType::qmlType(const QByteArray &name, int version_major, int version_minor)
992 {
993     QReadLocker lock(metaTypeDataLock());
994     QDeclarativeMetaTypeData *data = metaTypeData();
995
996     QList<QDeclarativeType*> types = data->nameToType.values(name);
997     foreach (QDeclarativeType *t, types) {
998         // XXX version_major<0 just a kludge for QDeclarativePropertyPrivate::initProperty
999         if (version_major<0 || t->availableInVersion(version_major,version_minor))
1000             return t;
1001     }
1002     return 0;
1003 }
1004
1005 /*!
1006     Returns the type (if any) that corresponds to the \a metaObject.  Returns null if no
1007     type is registered.
1008 */
1009 QDeclarativeType *QDeclarativeMetaType::qmlType(const QMetaObject *metaObject)
1010 {
1011     QReadLocker lock(metaTypeDataLock());
1012     QDeclarativeMetaTypeData *data = metaTypeData();
1013
1014     return data->metaObjectToType.value(metaObject);
1015 }
1016
1017 /*!
1018     Returns the type (if any) that corresponds to the \a metaObject in version specified
1019     by \a version_major and \a version_minor in module specified by \a uri.  Returns null if no
1020     type is registered.
1021 */
1022 QDeclarativeType *QDeclarativeMetaType::qmlType(const QMetaObject *metaObject, const QByteArray &module, int version_major, int version_minor)
1023 {
1024     QReadLocker lock(metaTypeDataLock());
1025     QDeclarativeMetaTypeData *data = metaTypeData();
1026
1027     QDeclarativeMetaTypeData::MetaObjects::const_iterator it = data->metaObjectToType.find(metaObject);
1028     while (it != data->metaObjectToType.end() && it.key() == metaObject) {
1029         QDeclarativeType *t = *it;
1030         if (version_major < 0 || t->availableInVersion(module, version_major,version_minor))
1031             return t;
1032         ++it;
1033     }
1034
1035     return 0;
1036 }
1037
1038 /*!
1039     Returns the type (if any) that corresponds to the QVariant::Type \a userType.  
1040     Returns null if no type is registered.
1041 */
1042 QDeclarativeType *QDeclarativeMetaType::qmlType(int userType)
1043 {
1044     QReadLocker lock(metaTypeDataLock());
1045     QDeclarativeMetaTypeData *data = metaTypeData();
1046
1047     QDeclarativeType *type = data->idToType.value(userType);
1048     if (type && type->typeId() == userType)
1049         return type;
1050     else
1051         return 0;
1052 }
1053
1054 /*!
1055     Returns the list of registered QML type names.
1056 */
1057 QList<QByteArray> QDeclarativeMetaType::qmlTypeNames()
1058 {
1059     QReadLocker lock(metaTypeDataLock());
1060     QDeclarativeMetaTypeData *data = metaTypeData();
1061
1062     return data->nameToType.keys();
1063 }
1064
1065 /*!
1066     Returns the list of registered QML types.
1067 */
1068 QList<QDeclarativeType*> QDeclarativeMetaType::qmlTypes()
1069 {
1070     QReadLocker lock(metaTypeDataLock());
1071     QDeclarativeMetaTypeData *data = metaTypeData();
1072
1073     return data->nameToType.values();
1074 }
1075
1076 QT_END_NAMESPACE
1077
1078 #include <QtGui/qfont.h>
1079 #include <QtGui/qpixmap.h>
1080 #include <QtGui/qbrush.h>
1081 #include <QtGui/qcolor.h>
1082 #include <QtGui/qpalette.h>
1083 #include <QtGui/qicon.h>
1084 #include <QtGui/qimage.h>
1085 #include <QtGui/qpolygon.h>
1086 #include <QtGui/qregion.h>
1087 #include <QtGui/qbitmap.h>
1088 #include <QtGui/qcursor.h>
1089 #include <QtGui/qsizepolicy.h>
1090 #include <QtGui/qkeysequence.h>
1091 #include <QtGui/qpen.h>
1092
1093 //#include <QtGui/qtextlength.h>
1094 #include <QtGui/qtextformat.h>
1095 #include <QtGui/qmatrix.h>
1096 #include <QtGui/qtransform.h>
1097 #include <QtGui/qmatrix4x4.h>
1098 #include <QtGui/qvector2d.h>
1099 #include <QtGui/qvector3d.h>
1100 #include <QtGui/qvector4d.h>
1101 #include <QtGui/qquaternion.h>
1102
1103 Q_DECLARE_METATYPE(QScriptValue);
1104
1105 QT_BEGIN_NAMESPACE
1106
1107 bool QDeclarativeMetaType::canCopy(int type)
1108 {
1109     switch(type) {
1110     case QMetaType::VoidStar:
1111     case QMetaType::QObjectStar:
1112     case QMetaType::QWidgetStar:
1113     case QMetaType::Long:
1114     case QMetaType::Int:
1115     case QMetaType::Short:
1116     case QMetaType::Char:
1117     case QMetaType::ULong:
1118     case QMetaType::UInt:
1119     case QMetaType::LongLong:
1120     case QMetaType::ULongLong:
1121     case QMetaType::UShort:
1122     case QMetaType::UChar:
1123     case QMetaType::Bool:
1124     case QMetaType::Float:
1125     case QMetaType::Double:
1126     case QMetaType::QChar:
1127     case QMetaType::QVariantMap:
1128     case QMetaType::QVariantHash:
1129     case QMetaType::QVariantList:
1130     case QMetaType::QByteArray:
1131     case QMetaType::QString:
1132     case QMetaType::QStringList:
1133     case QMetaType::QBitArray:
1134     case QMetaType::QDate:
1135     case QMetaType::QTime:
1136     case QMetaType::QDateTime:
1137     case QMetaType::QUrl:
1138     case QMetaType::QLocale:
1139     case QMetaType::QRect:
1140     case QMetaType::QRectF:
1141     case QMetaType::QSize:
1142     case QMetaType::QSizeF:
1143     case QMetaType::QLine:
1144     case QMetaType::QLineF:
1145     case QMetaType::QPoint:
1146     case QMetaType::QPointF:
1147     case QMetaType::QVector3D:
1148 #ifndef QT_NO_REGEXP
1149     case QMetaType::QRegExp:
1150 #endif
1151     case QMetaType::Void:
1152 #ifdef QT3_SUPPORT
1153     case QMetaType::QColorGroup:
1154 #endif
1155     case QMetaType::QFont:
1156     case QMetaType::QPixmap:
1157     case QMetaType::QBrush:
1158     case QMetaType::QColor:
1159     case QMetaType::QPalette:
1160     case QMetaType::QIcon:
1161     case QMetaType::QImage:
1162     case QMetaType::QPolygon:
1163     case QMetaType::QRegion:
1164     case QMetaType::QBitmap:
1165 #ifndef QT_NO_CURSOR
1166     case QMetaType::QCursor:
1167 #endif
1168     case QMetaType::QSizePolicy:
1169     case QMetaType::QKeySequence:
1170     case QMetaType::QPen:
1171     case QMetaType::QTextLength:
1172     case QMetaType::QTextFormat:
1173     case QMetaType::QMatrix:
1174     case QMetaType::QTransform:
1175     case QMetaType::QMatrix4x4:
1176     case QMetaType::QVector2D:
1177     case QMetaType::QVector4D:
1178     case QMetaType::QQuaternion:
1179         return true;
1180
1181     default:
1182         if (type == qMetaTypeId<QVariant>() ||
1183             type == qMetaTypeId<QScriptValue>() ||
1184             typeCategory(type) != Unknown) {
1185             return true;
1186         }
1187         break;
1188     }
1189
1190     return false;
1191 }
1192
1193 /*!
1194     Copies \a copy into \a data, assuming they both are of type \a type.  If
1195     \a copy is zero, a default type is copied.  Returns true if the copy was
1196     successful and false if not.
1197
1198     \note This should move into QMetaType once complete
1199
1200 */
1201 bool QDeclarativeMetaType::copy(int type, void *data, const void *copy)
1202 {
1203     if (copy) {
1204         switch(type) {
1205         case QMetaType::VoidStar:
1206         case QMetaType::QObjectStar:
1207         case QMetaType::QWidgetStar:
1208             *static_cast<void **>(data) = *static_cast<void* const *>(copy);
1209             return true;
1210         case QMetaType::Long:
1211             *static_cast<long *>(data) = *static_cast<const long*>(copy);
1212             return true;
1213         case QMetaType::Int:
1214             *static_cast<int *>(data) = *static_cast<const int*>(copy);
1215             return true;
1216         case QMetaType::Short:
1217             *static_cast<short *>(data) = *static_cast<const short*>(copy);
1218             return true;
1219         case QMetaType::Char:
1220             *static_cast<char *>(data) = *static_cast<const char*>(copy);
1221             return true;
1222         case QMetaType::ULong:
1223             *static_cast<ulong *>(data) = *static_cast<const ulong*>(copy);
1224             return true;
1225         case QMetaType::UInt:
1226             *static_cast<uint *>(data) = *static_cast<const uint*>(copy);
1227             return true;
1228         case QMetaType::LongLong:
1229             *static_cast<qlonglong *>(data) = *static_cast<const qlonglong*>(copy);
1230             return true;
1231         case QMetaType::ULongLong:
1232             *static_cast<qulonglong *>(data) = *static_cast<const qulonglong*>(copy);
1233             return true;
1234         case QMetaType::UShort:
1235             *static_cast<ushort *>(data) = *static_cast<const ushort*>(copy);
1236             return true;
1237         case QMetaType::UChar:
1238             *static_cast<uchar *>(data) = *static_cast<const uchar*>(copy);
1239             return true;
1240         case QMetaType::Bool:
1241             *static_cast<bool *>(data) = *static_cast<const bool*>(copy);
1242             return true;
1243         case QMetaType::Float:
1244             *static_cast<float *>(data) = *static_cast<const float*>(copy);
1245             return true;
1246         case QMetaType::Double:
1247             *static_cast<double *>(data) = *static_cast<const double*>(copy);
1248             return true;
1249         case QMetaType::QChar:
1250             *static_cast<NS(QChar) *>(data) = *static_cast<const NS(QChar)*>(copy);
1251             return true;
1252         case QMetaType::QVariantMap:
1253             *static_cast<NS(QVariantMap) *>(data) = *static_cast<const NS(QVariantMap)*>(copy);
1254             return true;
1255         case QMetaType::QVariantHash:
1256             *static_cast<NS(QVariantHash) *>(data) = *static_cast<const NS(QVariantHash)*>(copy);
1257             return true;
1258         case QMetaType::QVariantList:
1259             *static_cast<NS(QVariantList) *>(data) = *static_cast<const NS(QVariantList)*>(copy);
1260             return true;
1261         case QMetaType::QByteArray:
1262             *static_cast<NS(QByteArray) *>(data) = *static_cast<const NS(QByteArray)*>(copy);
1263             return true;
1264         case QMetaType::QString:
1265             *static_cast<NS(QString) *>(data) = *static_cast<const NS(QString)*>(copy);
1266             return true;
1267         case QMetaType::QStringList:
1268             *static_cast<NS(QStringList) *>(data) = *static_cast<const NS(QStringList)*>(copy);
1269             return true;
1270         case QMetaType::QBitArray:
1271             *static_cast<NS(QBitArray) *>(data) = *static_cast<const NS(QBitArray)*>(copy);
1272             return true;
1273         case QMetaType::QDate:
1274             *static_cast<NS(QDate) *>(data) = *static_cast<const NS(QDate)*>(copy);
1275             return true;
1276         case QMetaType::QTime:
1277             *static_cast<NS(QTime) *>(data) = *static_cast<const NS(QTime)*>(copy);
1278             return true;
1279         case QMetaType::QDateTime:
1280             *static_cast<NS(QDateTime) *>(data) = *static_cast<const NS(QDateTime)*>(copy);
1281             return true;
1282         case QMetaType::QUrl:
1283             *static_cast<NS(QUrl) *>(data) = *static_cast<const NS(QUrl)*>(copy);
1284             return true;
1285         case QMetaType::QLocale:
1286             *static_cast<NS(QLocale) *>(data) = *static_cast<const NS(QLocale)*>(copy);
1287             return true;
1288         case QMetaType::QRect:
1289             *static_cast<NS(QRect) *>(data) = *static_cast<const NS(QRect)*>(copy);
1290             return true;
1291         case QMetaType::QRectF:
1292             *static_cast<NS(QRectF) *>(data) = *static_cast<const NS(QRectF)*>(copy);
1293             return true;
1294         case QMetaType::QSize:
1295             *static_cast<NS(QSize) *>(data) = *static_cast<const NS(QSize)*>(copy);
1296             return true;
1297         case QMetaType::QSizeF:
1298             *static_cast<NS(QSizeF) *>(data) = *static_cast<const NS(QSizeF)*>(copy);
1299             return true;
1300         case QMetaType::QLine:
1301             *static_cast<NS(QLine) *>(data) = *static_cast<const NS(QLine)*>(copy);
1302             return true;
1303         case QMetaType::QLineF:
1304             *static_cast<NS(QLineF) *>(data) = *static_cast<const NS(QLineF)*>(copy);
1305             return true;
1306         case QMetaType::QPoint:
1307             *static_cast<NS(QPoint) *>(data) = *static_cast<const NS(QPoint)*>(copy);
1308             return true;
1309         case QMetaType::QPointF:
1310             *static_cast<NS(QPointF) *>(data) = *static_cast<const NS(QPointF)*>(copy);
1311             return true;
1312         case QMetaType::QVector3D:
1313             *static_cast<NS(QVector3D) *>(data) = *static_cast<const NS(QVector3D)*>(copy);
1314             return true;
1315 #ifndef QT_NO_REGEXP
1316         case QMetaType::QRegExp:
1317             *static_cast<NS(QRegExp) *>(data) = *static_cast<const NS(QRegExp)*>(copy);
1318             return true;
1319 #endif
1320         case QMetaType::Void:
1321             return true;
1322
1323
1324 #ifdef QT3_SUPPORT
1325         case QMetaType::QColorGroup:
1326             *static_cast<NS(QColorGroup) *>(data) = *static_cast<const NS(QColorGroup)*>(copy);
1327             return true;
1328 #endif
1329
1330         case QMetaType::QFont:
1331             *static_cast<NS(QFont) *>(data) = *static_cast<const NS(QFont)*>(copy);
1332             return true;
1333         case QMetaType::QPixmap:
1334             *static_cast<NS(QPixmap) *>(data) = *static_cast<const NS(QPixmap)*>(copy);
1335             return true;
1336         case QMetaType::QBrush:
1337             *static_cast<NS(QBrush) *>(data) = *static_cast<const NS(QBrush)*>(copy);
1338             return true;
1339         case QMetaType::QColor:
1340             *static_cast<NS(QColor) *>(data) = *static_cast<const NS(QColor)*>(copy);
1341             return true;
1342         case QMetaType::QPalette:
1343             *static_cast<NS(QPalette) *>(data) = *static_cast<const NS(QPalette)*>(copy);
1344             return true;
1345         case QMetaType::QIcon:
1346             *static_cast<NS(QIcon) *>(data) = *static_cast<const NS(QIcon)*>(copy);
1347             return true;
1348         case QMetaType::QImage:
1349             *static_cast<NS(QImage) *>(data) = *static_cast<const NS(QImage)*>(copy);
1350             return true;
1351         case QMetaType::QPolygon:
1352             *static_cast<NS(QPolygon) *>(data) = *static_cast<const NS(QPolygon)*>(copy);
1353             return true;
1354         case QMetaType::QRegion:
1355             *static_cast<NS(QRegion) *>(data) = *static_cast<const NS(QRegion)*>(copy);
1356             return true;
1357         case QMetaType::QBitmap:
1358             *static_cast<NS(QBitmap) *>(data) = *static_cast<const NS(QBitmap)*>(copy);
1359             return true;
1360 #ifndef QT_NO_CURSOR
1361         case QMetaType::QCursor:
1362             *static_cast<NS(QCursor) *>(data) = *static_cast<const NS(QCursor)*>(copy);
1363             return true;
1364 #endif
1365         case QMetaType::QSizePolicy:
1366             *static_cast<NS(QSizePolicy) *>(data) = *static_cast<const NS(QSizePolicy)*>(copy);
1367             return true;
1368         case QMetaType::QKeySequence:
1369             *static_cast<NS(QKeySequence) *>(data) = *static_cast<const NS(QKeySequence)*>(copy);
1370             return true;
1371         case QMetaType::QPen:
1372             *static_cast<NS(QPen) *>(data) = *static_cast<const NS(QPen)*>(copy);
1373             return true;
1374         case QMetaType::QTextLength:
1375             *static_cast<NS(QTextLength) *>(data) = *static_cast<const NS(QTextLength)*>(copy);
1376             return true;
1377         case QMetaType::QTextFormat:
1378             *static_cast<NS(QTextFormat) *>(data) = *static_cast<const NS(QTextFormat)*>(copy);
1379             return true;
1380         case QMetaType::QMatrix:
1381             *static_cast<NS(QMatrix) *>(data) = *static_cast<const NS(QMatrix)*>(copy);
1382             return true;
1383         case QMetaType::QTransform:
1384             *static_cast<NS(QTransform) *>(data) = *static_cast<const NS(QTransform)*>(copy);
1385             return true;
1386         case QMetaType::QMatrix4x4:
1387             *static_cast<NS(QMatrix4x4) *>(data) = *static_cast<const NS(QMatrix4x4)*>(copy);
1388             return true;
1389         case QMetaType::QVector2D:
1390             *static_cast<NS(QVector2D) *>(data) = *static_cast<const NS(QVector2D)*>(copy);
1391             return true;
1392         case QMetaType::QVector4D:
1393             *static_cast<NS(QVector4D) *>(data) = *static_cast<const NS(QVector4D)*>(copy);
1394             return true;
1395         case QMetaType::QQuaternion:
1396             *static_cast<NS(QQuaternion) *>(data) = *static_cast<const NS(QQuaternion)*>(copy);
1397             return true;
1398
1399         default:
1400             if (type == qMetaTypeId<QVariant>()) {
1401                 *static_cast<NS(QVariant) *>(data) = *static_cast<const NS(QVariant)*>(copy);
1402                 return true;
1403             } else if (type == qMetaTypeId<QScriptValue>()) {
1404                 *static_cast<NS(QScriptValue) *>(data) = *static_cast<const NS(QScriptValue)*>(copy);
1405                 return true;
1406             } else if (typeCategory(type) != Unknown) {
1407                 *static_cast<void **>(data) = *static_cast<void* const *>(copy);
1408                 return true;
1409             }
1410             break;
1411         }
1412     } else {
1413         switch(type) {
1414         case QMetaType::VoidStar:
1415         case QMetaType::QObjectStar:
1416         case QMetaType::QWidgetStar:
1417             *static_cast<void **>(data) = 0;
1418             return true;
1419         case QMetaType::Long:
1420             *static_cast<long *>(data) = long(0);
1421             return true;
1422         case QMetaType::Int:
1423             *static_cast<int *>(data) = int(0);
1424             return true;
1425         case QMetaType::Short:
1426             *static_cast<short *>(data) = short(0);
1427             return true;
1428         case QMetaType::Char:
1429             *static_cast<char *>(data) = char(0);
1430             return true;
1431         case QMetaType::ULong:
1432             *static_cast<ulong *>(data) = ulong(0);
1433             return true;
1434         case QMetaType::UInt:
1435             *static_cast<uint *>(data) = uint(0);
1436             return true;
1437         case QMetaType::LongLong:
1438             *static_cast<qlonglong *>(data) = qlonglong(0);
1439             return true;
1440         case QMetaType::ULongLong:
1441             *static_cast<qulonglong *>(data) = qulonglong(0);
1442             return true;
1443         case QMetaType::UShort:
1444             *static_cast<ushort *>(data) = ushort(0);
1445             return true;
1446         case QMetaType::UChar:
1447             *static_cast<uchar *>(data) = uchar(0);
1448             return true;
1449         case QMetaType::Bool:
1450             *static_cast<bool *>(data) = bool(false);
1451             return true;
1452         case QMetaType::Float:
1453             *static_cast<float *>(data) = float(0);
1454             return true;
1455         case QMetaType::Double:
1456             *static_cast<double *>(data) = double(0);
1457             return true;
1458         case QMetaType::QChar:
1459             *static_cast<NS(QChar) *>(data) = NS(QChar)();
1460             return true;
1461         case QMetaType::QVariantMap:
1462             *static_cast<NS(QVariantMap) *>(data) = NS(QVariantMap)();
1463             return true;
1464         case QMetaType::QVariantHash:
1465             *static_cast<NS(QVariantHash) *>(data) = NS(QVariantHash)();
1466             return true;
1467         case QMetaType::QVariantList:
1468             *static_cast<NS(QVariantList) *>(data) = NS(QVariantList)();
1469             return true;
1470         case QMetaType::QByteArray:
1471             *static_cast<NS(QByteArray) *>(data) = NS(QByteArray)();
1472             return true;
1473         case QMetaType::QString:
1474             *static_cast<NS(QString) *>(data) = NS(QString)();
1475             return true;
1476         case QMetaType::QStringList:
1477             *static_cast<NS(QStringList) *>(data) = NS(QStringList)();
1478             return true;
1479         case QMetaType::QBitArray:
1480             *static_cast<NS(QBitArray) *>(data) = NS(QBitArray)();
1481             return true;
1482         case QMetaType::QDate:
1483             *static_cast<NS(QDate) *>(data) = NS(QDate)();
1484             return true;
1485         case QMetaType::QTime:
1486             *static_cast<NS(QTime) *>(data) = NS(QTime)();
1487             return true;
1488         case QMetaType::QDateTime:
1489             *static_cast<NS(QDateTime) *>(data) = NS(QDateTime)();
1490             return true;
1491         case QMetaType::QUrl:
1492             *static_cast<NS(QUrl) *>(data) = NS(QUrl)();
1493             return true;
1494         case QMetaType::QLocale:
1495             *static_cast<NS(QLocale) *>(data) = NS(QLocale)();
1496             return true;
1497         case QMetaType::QRect:
1498             *static_cast<NS(QRect) *>(data) = NS(QRect)();
1499             return true;
1500         case QMetaType::QRectF:
1501             *static_cast<NS(QRectF) *>(data) = NS(QRectF)();
1502             return true;
1503         case QMetaType::QSize:
1504             *static_cast<NS(QSize) *>(data) = NS(QSize)();
1505             return true;
1506         case QMetaType::QSizeF:
1507             *static_cast<NS(QSizeF) *>(data) = NS(QSizeF)();
1508             return true;
1509         case QMetaType::QLine:
1510             *static_cast<NS(QLine) *>(data) = NS(QLine)();
1511             return true;
1512         case QMetaType::QLineF:
1513             *static_cast<NS(QLineF) *>(data) = NS(QLineF)();
1514             return true;
1515         case QMetaType::QPoint:
1516             *static_cast<NS(QPoint) *>(data) = NS(QPoint)();
1517             return true;
1518         case QMetaType::QPointF:
1519             *static_cast<NS(QPointF) *>(data) = NS(QPointF)();
1520             return true;
1521         case QMetaType::QVector3D:
1522             *static_cast<NS(QVector3D) *>(data) = NS(QVector3D)();
1523             return true;
1524 #ifndef QT_NO_REGEXP
1525         case QMetaType::QRegExp:
1526             *static_cast<NS(QRegExp) *>(data) = NS(QRegExp)();
1527             return true;
1528 #endif
1529         case QMetaType::Void:
1530             return true;
1531
1532 #ifdef QT3_SUPPORT
1533         case QMetaType::QColorGroup:
1534             *static_cast<NS(QColorGroup) *>(data) = NS(QColorGroup)();
1535             return true;
1536 #endif
1537
1538         case QMetaType::QFont:
1539             *static_cast<NS(QFont) *>(data) = NS(QFont)();
1540             return true;
1541         case QMetaType::QPixmap:
1542             *static_cast<NS(QPixmap) *>(data) = NS(QPixmap)();
1543             return true;
1544         case QMetaType::QBrush:
1545             *static_cast<NS(QBrush) *>(data) = NS(QBrush)();
1546             return true;
1547         case QMetaType::QColor:
1548             *static_cast<NS(QColor) *>(data) = NS(QColor)();
1549             return true;
1550         case QMetaType::QPalette:
1551             *static_cast<NS(QPalette) *>(data) = NS(QPalette)();
1552             return true;
1553         case QMetaType::QIcon:
1554             *static_cast<NS(QIcon) *>(data) = NS(QIcon)();
1555             return true;
1556         case QMetaType::QImage:
1557             *static_cast<NS(QImage) *>(data) = NS(QImage)();
1558             return true;
1559         case QMetaType::QPolygon:
1560             *static_cast<NS(QPolygon) *>(data) = NS(QPolygon)();
1561             return true;
1562         case QMetaType::QRegion:
1563             *static_cast<NS(QRegion) *>(data) = NS(QRegion)();
1564             return true;
1565         case QMetaType::QBitmap:
1566             *static_cast<NS(QBitmap) *>(data) = NS(QBitmap)();
1567             return true;
1568 #ifndef QT_NO_CURSOR
1569         case QMetaType::QCursor:
1570             *static_cast<NS(QCursor) *>(data) = NS(QCursor)();
1571             return true;
1572 #endif
1573         case QMetaType::QSizePolicy:
1574             *static_cast<NS(QSizePolicy) *>(data) = NS(QSizePolicy)();
1575             return true;
1576         case QMetaType::QKeySequence:
1577             *static_cast<NS(QKeySequence) *>(data) = NS(QKeySequence)();
1578             return true;
1579         case QMetaType::QPen:
1580             *static_cast<NS(QPen) *>(data) = NS(QPen)();
1581             return true;
1582         case QMetaType::QTextLength:
1583             *static_cast<NS(QTextLength) *>(data) = NS(QTextLength)();
1584             return true;
1585         case QMetaType::QTextFormat:
1586             *static_cast<NS(QTextFormat) *>(data) = NS(QTextFormat)();
1587             return true;
1588         case QMetaType::QMatrix:
1589             *static_cast<NS(QMatrix) *>(data) = NS(QMatrix)();
1590             return true;
1591         case QMetaType::QTransform:
1592             *static_cast<NS(QTransform) *>(data) = NS(QTransform)();
1593             return true;
1594         case QMetaType::QMatrix4x4:
1595             *static_cast<NS(QMatrix4x4) *>(data) = NS(QMatrix4x4)();
1596             return true;
1597         case QMetaType::QVector2D:
1598             *static_cast<NS(QVector2D) *>(data) = NS(QVector2D)();
1599             return true;
1600         case QMetaType::QVector4D:
1601             *static_cast<NS(QVector4D) *>(data) = NS(QVector4D)();
1602             return true;
1603         case QMetaType::QQuaternion:
1604             *static_cast<NS(QQuaternion) *>(data) = NS(QQuaternion)();
1605             return true;
1606         default:
1607             if (type == qMetaTypeId<QVariant>()) {
1608                 *static_cast<NS(QVariant) *>(data) = NS(QVariant)();
1609                 return true;
1610             } else if (type == qMetaTypeId<QScriptValue>()) {
1611                 *static_cast<NS(QScriptValue) *>(data) = NS(QScriptValue)();
1612                 return true;
1613             } else if (typeCategory(type) != Unknown) {
1614                 *static_cast<void **>(data) = 0;
1615                 return true;
1616             }
1617             break;
1618         }
1619     }
1620
1621     return false;
1622 }
1623
1624 QT_END_NAMESPACE