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