diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-04-20 01:25:02 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-04-20 01:25:02 (GMT) |
commit | c734d6eecbdb594346b3008bd5a843605d761af8 (patch) | |
tree | ff2341a64a38824b97816bd222c2c0cd18e13585 /src | |
parent | 1b80a6bc28cb49b9f6e1a2132d929819924aa604 (diff) | |
download | Qt-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.cpp | 75 |
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; |