diff --git a/src/plugins/qmldesigner/designercore/metainfo/metainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/metainfo.cpp index 7bf49440265a65fcdd3743f8893c8282b4522691..9bc25d65c82d731e8c6c69d681cc0704d76aa11f 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/metainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/metainfo.cpp @@ -72,11 +72,12 @@ public: void parseQmlTypes(); void parseNonQmlTypes(); void parseValueTypes(); - void parseNonQmlClassRecursively(const QMetaObject *qMetaObject, int majorVersion, int minorVersion); + void parseNonQmlClassRecursively(const QMetaObject *qMetaObject); void parseProperties(NodeMetaInfo &nodeMetaInfo, const QMetaObject *qMetaObject) const; void parseClassInfo(NodeMetaInfo &nodeMetaInfo, const QMetaObject *qMetaObject) const; - QString typeName(const QMetaObject *qMetaObject) const; + QList<QDeclarativeType*> qmlTypes(); + void typeInfo(const QMetaObject *qMetaObject, QString *typeName, int *majorVersion = 0, int *minorVersion = 0) const; void parseXmlFiles(); @@ -125,7 +126,7 @@ void MetaInfoPrivate::initialize() void MetaInfoPrivate::loadPlugins(QDeclarativeEngine *engine) { // hack to load plugins - QDeclarativeComponent pluginComponent(engine); + QDeclarativeComponent pluginComponent(engine, 0); QStringList pluginList; pluginList += "import Qt 4.7"; @@ -139,6 +140,7 @@ void MetaInfoPrivate::loadPlugins(QDeclarativeEngine *engine) QString componentString = QString("%1\n Item {}\n").arg(pluginList.join("\n")); + pluginComponent.setData(componentString.toLatin1(), QUrl()); } @@ -206,48 +208,83 @@ void MetaInfoPrivate::parseClassInfo(NodeMetaInfo &nodeMetaInfo, const QMetaObje } } -void MetaInfoPrivate::parseNonQmlClassRecursively(const QMetaObject *qMetaObject, int majorVersion, int minorVersion) +void MetaInfoPrivate::parseNonQmlClassRecursively(const QMetaObject *qMetaObject) { Q_ASSERT_X(qMetaObject, Q_FUNC_INFO, "invalid QMetaObject"); - const QString className = qMetaObject->className(); - if (className.isEmpty()) { + QString typeName; + int majorVersion = -1; + int minorVersion = -1; + typeInfo(qMetaObject, &typeName, &majorVersion, &minorVersion); + + if (typeName.isEmpty()) { qWarning() << "Meta type system: Registered class has no name."; return; } - if (!m_q->hasNodeMetaInfo(typeName(qMetaObject), majorVersion, minorVersion)) { - NodeMetaInfo nodeMetaInfo(*m_q); - nodeMetaInfo.setType(typeName(qMetaObject), majorVersion, minorVersion); - parseProperties(nodeMetaInfo, qMetaObject); - parseClassInfo(nodeMetaInfo, qMetaObject); + NodeMetaInfo existingInfo = m_q->nodeMetaInfo(typeName, majorVersion, minorVersion); + if (existingInfo.isValid() + && existingInfo.majorVersion() == majorVersion + && existingInfo.minorVersion() == minorVersion) { + return; + } - if (debug) - qDebug() << "adding non qml type" << nodeMetaInfo.typeName() << nodeMetaInfo.majorVersion() << nodeMetaInfo.minorVersion() << ", parent type" << typeName(qMetaObject->superClass()); - if (qMetaObject->superClass()) - nodeMetaInfo.setSuperClass(typeName(qMetaObject->superClass())); + NodeMetaInfo nodeMetaInfo(*m_q); + nodeMetaInfo.setType(typeName, majorVersion, minorVersion); + parseProperties(nodeMetaInfo, qMetaObject); + parseClassInfo(nodeMetaInfo, qMetaObject); - m_q->addNodeInfo(nodeMetaInfo); - } + QString superTypeName; + int superTypeMajorVersion = -1; + int superTypeMinorVersion = -1; - if (const QMetaObject *superClass = qMetaObject->superClass()) { - parseNonQmlClassRecursively(superClass, majorVersion, minorVersion); + if (qMetaObject->superClass()) { + typeInfo(qMetaObject->superClass(), &superTypeName, &superTypeMajorVersion, &superTypeMinorVersion); + nodeMetaInfo.setSuperClass(superTypeName, superTypeMajorVersion, superTypeMinorVersion); } + if (debug) + qDebug() << "adding non qml type" << nodeMetaInfo.typeName() << nodeMetaInfo.majorVersion() << nodeMetaInfo.minorVersion() + << ", parent type" << superTypeName << superTypeMajorVersion << superTypeMinorVersion; + + m_q->addNodeInfo(nodeMetaInfo); + + if (const QMetaObject *superClass = qMetaObject->superClass()) + parseNonQmlClassRecursively(superClass); } +QList<QDeclarativeType*> MetaInfoPrivate::qmlTypes() +{ + QList<QDeclarativeType*> list; + foreach (QDeclarativeType *type, QDeclarativeMetaType::qmlTypes()) { + if (!type->qmlTypeName().startsWith("Bauhaus/") + && !type->qmlTypeName().startsWith("QmlProject/")) + list += type; + } + return list; +} -QString MetaInfoPrivate::typeName(const QMetaObject *qMetaObject) const +void MetaInfoPrivate::typeInfo(const QMetaObject *qMetaObject, QString *typeName, int *majorVersion, int *minorVersion) const { + Q_ASSERT(typeName); + if (!qMetaObject) - return QString(); - QString className = qMetaObject->className(); - if (QDeclarativeType *qmlType = QDeclarativeMetaType::qmlType(qMetaObject)) { - QString qmlClassName(qmlType->qmlTypeName()); - if (!qmlClassName.isEmpty()) - className = qmlType->qmlTypeName(); // Ensure that we always use the qml name, - // if available. + return; + + *typeName = qMetaObject->className(); + int majVersion = -1; + int minVersion = -1; + QDeclarativeType *qmlType = QDeclarativeMetaType::qmlType(qMetaObject); + if (qmlType) { + if (!qmlType->qmlTypeName().isEmpty()) { + *typeName = qmlType->qmlTypeName(); + majVersion = qmlType->majorVersion(); + minVersion = qmlType->minorVersion(); + } } - return className; + if (majorVersion) + *majorVersion = majVersion; + if (minorVersion) + *minorVersion = minVersion; } void MetaInfoPrivate::parseValueTypes() @@ -303,12 +340,12 @@ void MetaInfoPrivate::parseValueTypes() void MetaInfoPrivate::parseQmlTypes() { - foreach (QDeclarativeType *qmlType, QDeclarativeMetaType::qmlTypes()) { + foreach (QDeclarativeType *qmlType, qmlTypes()) { const QString qtTypeName(qmlType->typeName()); const QString qmlTypeName(qmlType->qmlTypeName()); m_QtTypesToQmlTypes.insert(qtTypeName, qmlTypeName); } - foreach (QDeclarativeType *qmlType, QDeclarativeMetaType::qmlTypes()) { + foreach (QDeclarativeType *qmlType, qmlTypes()) { const QMetaObject *qMetaObject = qmlType->metaObject(); // parseQmlTypes is called iteratively e.g. when plugins are loaded @@ -319,32 +356,42 @@ void MetaInfoPrivate::parseQmlTypes() nodeMetaInfo.setType(qmlType->qmlTypeName(), qmlType->majorVersion(), qmlType->minorVersion()); parseProperties(nodeMetaInfo, qMetaObject); - parseClassInfo(nodeMetaInfo, qMetaObject); - - QString superTypeName = typeName(qMetaObject->superClass()); if (qmlType->baseMetaObject() != qMetaObject) { // type is declared with Q_DECLARE_EXTENDED_TYPE - // also parse properties of original type parseProperties(nodeMetaInfo, qmlType->baseMetaObject()); - superTypeName = typeName(qmlType->baseMetaObject()->superClass()); } - nodeMetaInfo.setSuperClass(superTypeName); + parseClassInfo(nodeMetaInfo, qMetaObject); + + QString superTypeName; + int superTypeMajorVersion = -1; + int superTypeMinorVersion = -1; + if (const QMetaObject *superClassObject = qmlType->baseMetaObject()->superClass()) + typeInfo(superClassObject, &superTypeName, &superTypeMajorVersion, &superTypeMinorVersion); + + if (!superTypeName.isEmpty()) + nodeMetaInfo.setSuperClass(superTypeName, superTypeMajorVersion, superTypeMinorVersion); + + if (debug) { + qDebug() << "adding qml type" << nodeMetaInfo.typeName() << nodeMetaInfo.majorVersion() << nodeMetaInfo.minorVersion() + << ", super class" << superTypeName << superTypeMajorVersion << superTypeMinorVersion; + } - if (debug) - qDebug() << "adding qml type" << nodeMetaInfo.typeName() << nodeMetaInfo.majorVersion() << nodeMetaInfo.minorVersion() << "super class" << superTypeName; m_q->addNodeInfo(nodeMetaInfo); } } void MetaInfoPrivate::parseNonQmlTypes() { - foreach (QDeclarativeType *qmlType, QDeclarativeMetaType::qmlTypes()) { - if (!qmlType->qmlTypeName().contains("Bauhaus")) - parseNonQmlClassRecursively(qmlType->metaObject(), qmlType->majorVersion(), qmlType->minorVersion()); + foreach (QDeclarativeType *qmlType, qmlTypes()) { + if (qmlType->qmlTypeName().startsWith("Bauhaus/") + || qmlType->qmlTypeName().startsWith("QmlProject/")) + continue; + if (qmlType->metaObject()->superClass()) + parseNonQmlClassRecursively(qmlType->metaObject()->superClass()); } - parseNonQmlClassRecursively(&QDeclarativeAnchors::staticMetaObject, -1, -1); + parseNonQmlClassRecursively(&QDeclarativeAnchors::staticMetaObject); } @@ -429,12 +476,14 @@ MetaInfo& MetaInfo::operator=(const MetaInfo &other) bool MetaInfo::hasNodeMetaInfo(const QString &typeName, int majorVersion, int minorVersion) const { foreach (const NodeMetaInfo &info, m_p->m_nodeMetaInfoHash.values(typeName)) { - if (info.availableInVersion(majorVersion, minorVersion)) { + if (info.availableInVersion(majorVersion, minorVersion)) { { return true; } + } } if (!isGlobal()) return global().hasNodeMetaInfo(typeName); + return false; } @@ -443,16 +492,21 @@ bool MetaInfo::hasNodeMetaInfo(const QString &typeName, int majorVersion, int mi */ NodeMetaInfo MetaInfo::nodeMetaInfo(const QString &typeName, int majorVersion, int minorVersion) const { + NodeMetaInfo returnInfo; foreach (const NodeMetaInfo &info, m_p->m_nodeMetaInfoHash.values(typeName)) { - // todo: The order for different types for different versions is random here. if (info.availableInVersion(majorVersion, minorVersion)) { - return info; + if (!returnInfo.isValid() + || returnInfo.majorVersion() < info.majorVersion() + || (returnInfo.majorVersion() == info.minorVersion() + && returnInfo.minorVersion() < info.minorVersion())) + returnInfo = info; } } - if (!isGlobal()) + if (!returnInfo.isValid() + && !isGlobal()) return global().nodeMetaInfo(typeName); - return NodeMetaInfo(); + return returnInfo; } QString MetaInfo::fromQtTypes(const QString &type) const diff --git a/tests/auto/qml/qmldesigner/coretests/testcore.cpp b/tests/auto/qml/qmldesigner/coretests/testcore.cpp index a702214dd4538ccfe6ebf671b0a0219c30faac26..ac255d3dcf2f6660faf33e74f496e8e2aa6d6f7d 100644 --- a/tests/auto/qml/qmldesigner/coretests/testcore.cpp +++ b/tests/auto/qml/qmldesigner/coretests/testcore.cpp @@ -3610,8 +3610,12 @@ void TestCore::testMetaInfo() // test whether default type is registered QVERIFY(model->metaInfo().hasNodeMetaInfo("Qt/Item", 4, 7)); - // test whether types from plugins are loaded + // test whether types from plugins are registered QVERIFY(model->metaInfo().hasNodeMetaInfo("org.webkit/WebView", 1, 0)); + + // test whether non-qml type is registered + QVERIFY(model->metaInfo().hasNodeMetaInfo("QGraphicsObject", 4, 7)); // Qt 4.7 namespace + QVERIFY(model->metaInfo().hasNodeMetaInfo("QGraphicsObject", 1, 0)); // webkit 1.0 namespace } void TestCore::testMetaInfoSimpleType() @@ -3625,11 +3629,11 @@ void TestCore::testMetaInfoSimpleType() QScopedPointer<Model> model(Model::create("Qt/Item")); QVERIFY(model.data()); - QVERIFY(model->metaInfo().hasNodeMetaInfo("Qt/Item")); + QVERIFY(model->metaInfo().hasNodeMetaInfo("Qt/Item", 4, 7)); QVERIFY(model->metaInfo().hasNodeMetaInfo("Qt/Item", 4, 7)); NodeMetaInfo itemMetaInfo = model->metaInfo().nodeMetaInfo("Qt/Item", 4, 7); - NodeMetaInfo itemMetaInfo2 = model->metaInfo().nodeMetaInfo("Qt/Item"); + NodeMetaInfo itemMetaInfo2 = model->metaInfo().nodeMetaInfo("Qt/Item", 4, 7); QCOMPARE(itemMetaInfo, itemMetaInfo2); QVERIFY(itemMetaInfo.isValid()); @@ -3641,12 +3645,12 @@ void TestCore::testMetaInfoSimpleType() NodeMetaInfo graphicsObjectInfo = itemMetaInfo.directSuperClass(); QVERIFY(graphicsObjectInfo.isValid()); QCOMPARE(graphicsObjectInfo.typeName(), QLatin1String("QGraphicsObject")); - QCOMPARE(graphicsObjectInfo.majorVersion(), 4); - QCOMPARE(graphicsObjectInfo.minorVersion(), 7); + QCOMPARE(graphicsObjectInfo.majorVersion(), -1); + QCOMPARE(graphicsObjectInfo.minorVersion(), -1); QCOMPARE(itemMetaInfo.superClasses().size(), 2); // QGraphicsObject, Qt/QtObject QVERIFY(itemMetaInfo.isSubclassOf("QGraphicsObject", 4, 7)); - QVERIFY(itemMetaInfo.isSubclassOf("Qt/QtObject", -1, -1)); + QVERIFY(itemMetaInfo.isSubclassOf("Qt/QtObject", 4, 7)); // availableInVersion QVERIFY(itemMetaInfo.availableInVersion(4, 7)); @@ -3704,8 +3708,8 @@ void TestCore::testMetaInfoExtendedType() NodeMetaInfo graphicsObjectTypeInfo = graphicsWidgetTypeInfo.directSuperClass(); QVERIFY(graphicsObjectTypeInfo.isValid()); QCOMPARE(graphicsObjectTypeInfo.typeName(), QLatin1String("QGraphicsObject")); - QCOMPARE(graphicsObjectTypeInfo.majorVersion(), 4); - QCOMPARE(graphicsObjectTypeInfo.minorVersion(), 7); + QCOMPARE(graphicsObjectTypeInfo.majorVersion(), -1); + QCOMPARE(graphicsObjectTypeInfo.minorVersion(), -1); QCOMPARE(graphicsWidgetTypeInfo.superClasses().size(), 2); } @@ -3736,8 +3740,8 @@ void TestCore::testMetaInfoCustomType() NodeMetaInfo stateOperationInfo = propertyChangesInfo.directSuperClass(); QVERIFY(stateOperationInfo.isValid()); QCOMPARE(stateOperationInfo.typeName(), QLatin1String("QDeclarativeStateOperation")); - QCOMPARE(stateOperationInfo.majorVersion(), 4); - QCOMPARE(stateOperationInfo.minorVersion(), 7); + QCOMPARE(stateOperationInfo.majorVersion(), -1); + QCOMPARE(stateOperationInfo.minorVersion(), -1); QCOMPARE(propertyChangesInfo.superClasses().size(), 2); // DeclarativePropertyChanges just has 3 properties