summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2010-04-20 01:25:02 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2010-04-20 01:25:02 (GMT)
commitc734d6eecbdb594346b3008bd5a843605d761af8 (patch)
treeff2341a64a38824b97816bd222c2c0cd18e13585 /src
parent1b80a6bc28cb49b9f6e1a2132d929819924aa604 (diff)
downloadQt-c734d6eecbdb594346b3008bd5a843605d761af8.zip
Qt-c734d6eecbdb594346b3008bd5a843605d761af8.tar.gz
Qt-c734d6eecbdb594346b3008bd5a843605d761af8.tar.bz2
Handle overrides correctly in extension objects
QTBUG-7817
Diffstat (limited to 'src')
-rw-r--r--src/declarative/qml/qdeclarativemetatype.cpp75
1 files changed, 73 insertions, 2 deletions
diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp
index d41bd43..96bf4e5 100644
--- a/src/declarative/qml/qdeclarativemetatype.cpp
+++ b/src/declarative/qml/qdeclarativemetatype.cpp
@@ -221,6 +221,76 @@ bool QDeclarativeType::availableInVersion(int vmajor, int vminor) const
return vmajor > d->m_version_maj || (vmajor == d->m_version_maj && vminor >= d->m_version_min);
}
+static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
+ const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd)
+{
+ // Clone Q_CLASSINFO
+ for (int ii = mo->classInfoOffset(); ii < mo->classInfoCount(); ++ii) {
+ QMetaClassInfo info = mo->classInfo(ii);
+
+ int otherIndex = ignoreEnd->indexOfClassInfo(info.name());
+ if (otherIndex >= ignoreStart->classInfoOffset() + ignoreStart->classInfoCount()) {
+ // Skip
+ } else {
+ builder.addClassInfo(info.name(), info.value());
+ }
+ }
+
+ // Clone Q_PROPERTY
+ for (int ii = mo->propertyOffset(); ii < mo->propertyCount(); ++ii) {
+ QMetaProperty property = mo->property(ii);
+
+ int otherIndex = ignoreEnd->indexOfProperty(property.name());
+ if (otherIndex >= ignoreStart->classInfoOffset() + ignoreStart->classInfoCount()) {
+ builder.addProperty(QByteArray("__qml_ignore__") + property.name(), QByteArray("void"));
+ // Skip
+ } else {
+ builder.addProperty(property);
+ }
+ }
+
+ // Clone Q_METHODS
+ for (int ii = mo->methodOffset(); ii < mo->methodCount(); ++ii) {
+ QMetaMethod method = mo->method(ii);
+
+ // More complex - need to search name
+ QByteArray name = method.signature();
+ int parenIdx = name.indexOf('(');
+ if (parenIdx != -1) name = name.left(parenIdx);
+
+
+ bool found = false;
+
+ for (int ii = ignoreStart->methodOffset() + ignoreStart->methodCount();
+ !found && ii < ignoreEnd->methodOffset() + ignoreEnd->methodCount();
+ ++ii) {
+
+ QMetaMethod other = ignoreEnd->method(ii);
+ QByteArray othername = other.signature();
+ int parenIdx = othername.indexOf('(');
+ if (parenIdx != -1) othername = othername.left(parenIdx);
+
+ found = name == othername;
+ }
+
+ QMetaMethodBuilder m = builder.addMethod(method);
+ if (found) // SKIP
+ m.setAccess(QMetaMethod::Private);
+ }
+
+ // Clone Q_ENUMS
+ for (int ii = mo->enumeratorOffset(); ii < mo->enumeratorCount(); ++ii) {
+ QMetaEnum enumerator = mo->enumerator(ii);
+
+ int otherIndex = ignoreEnd->indexOfEnumerator(enumerator.name());
+ if (otherIndex >= ignoreStart->enumeratorOffset() + ignoreStart->enumeratorCount()) {
+ // Skip
+ } else {
+ builder.addEnumerator(enumerator);
+ }
+ }
+}
+
void QDeclarativeTypePrivate::init() const
{
if (m_isSetup) return;
@@ -245,8 +315,9 @@ void QDeclarativeTypePrivate::init() const
QDeclarativeType *t = metaTypeData()->metaObjectToType.value(mo);
if (t) {
if (t->d->m_extFunc) {
- QMetaObject *mmo = new QMetaObject;
- *mmo = *t->d->m_extMetaObject;
+ QMetaObjectBuilder builder;
+ clone(builder, t->d->m_extMetaObject, t->d->m_baseMetaObject, m_baseMetaObject);
+ QMetaObject *mmo = builder.toMetaObject();
mmo->d.superdata = m_baseMetaObject;
if (!m_metaObjects.isEmpty())
m_metaObjects.last().metaObject->d.superdata = mmo;