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