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