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