diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 25be663941686751106a744c85692e0ea86d26a8..284c56a7e6bbf033a91e0bb83d59e753e3cae687 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -573,16 +573,14 @@ QStringList NavigatorTreeModel::visibleProperties(const ModelNode &node) const { QStringList propertyList; - foreach (PropertyMetaInfo propertyMetaInfo, node.metaInfo().properties().values()) { - if (!m_hiddenProperties.contains(propertyMetaInfo.name()) && - propertyMetaInfo.name() != node.metaInfo().defaultProperty() && - propertyMetaInfo.isReadable() && - propertyMetaInfo.isWriteable()) { + foreach (const QString &propertyName, node.metaInfo().propertyNamesOnlyContainer()) { + if (!m_hiddenProperties.contains(propertyName) && + propertyName != node.metaInfo().defaultProperty()) { // TODO: ask the node instances - QString qmlType = qmlTypeInQtContainer(propertyMetaInfo.type()); + QString qmlType = qmlTypeInQtContainer(node.metaInfo().propertyType(propertyName)); if (node.metaInfo().metaInfo().hasNodeMetaInfo(qmlType) && - node.metaInfo().metaInfo().nodeMetaInfo(qmlType).isSubclassOf("QGraphicsObject", -1, -1)) { - propertyList << propertyMetaInfo.name(); + node.metaInfo().metaInfo().nodeMetaInfo(qmlType).isSubclassOf("Qt/QtObject", 4, 7)) { + propertyList.append(propertyName); } } } diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp index 2122d25c964b8b5b970506e554e88499ecb93db3..b9b4369e2f5fe4b5b74b6ddb53e066721e45101f 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp @@ -175,7 +175,7 @@ void PropertyEditor::NodeType::setup(const QmlObjectNode &fxObjectNode, const QS QDeclarativeContext *ctxt = m_view->rootContext(); if (fxObjectNode.isValid()) { - foreach (const QString &propertyName, fxObjectNode.modelNode().metaInfo().properties(true).keys()) + foreach (const QString &propertyName, fxObjectNode.modelNode().metaInfo().propertyNames()) createPropertyEditorValue(fxObjectNode, propertyName, fxObjectNode.instanceValue(propertyName), &m_backendValuesPropertyMap, propertyEditor); // className @@ -227,8 +227,8 @@ void PropertyEditor::NodeType::initialSetup(const QString &typeName, const QUrl NodeMetaInfo metaInfo = propertyEditor->model()->metaInfo().nodeMetaInfo(typeName, 4, 7); - foreach (const QString &propertyName, metaInfo.properties(true).keys()) - setupPropertyEditorValue(propertyName, &m_backendValuesPropertyMap, propertyEditor, metaInfo.property(propertyName, true).type()); + foreach (const QString &propertyName, metaInfo.propertyNames()) + setupPropertyEditorValue(propertyName, &m_backendValuesPropertyMap, propertyEditor, metaInfo.propertyType(propertyName)); PropertyEditorValue *valueObject = qobject_cast<PropertyEditorValue*>(QDeclarativeMetaType::toQObject(m_backendValuesPropertyMap.value("className"))); if (!valueObject) @@ -386,8 +386,8 @@ void PropertyEditor::changeValue(const QString &propertyName) QVariant castedValue; - if (fxObjectNode.modelNode().metaInfo().isValid() && fxObjectNode.modelNode().metaInfo().property(propertyName, true).isValid()) { - castedValue = fxObjectNode.modelNode().metaInfo().property(propertyName, true).castedValue(value->value()); + if (fxObjectNode.modelNode().metaInfo().isValid() && fxObjectNode.modelNode().metaInfo().hasProperty(propertyName)) { + castedValue = fxObjectNode.modelNode().metaInfo().nativePropertyValue(propertyName, value->value()); } else { qWarning() << "PropertyEditor:" <<propertyName << "cannot be casted (metainfo)"; return ; @@ -398,8 +398,8 @@ void PropertyEditor::changeValue(const QString &propertyName) return ; } - if (fxObjectNode.modelNode().metaInfo().isValid() && fxObjectNode.modelNode().metaInfo().property(propertyName).isValid()) - if (fxObjectNode.modelNode().metaInfo().property(propertyName).type() == QLatin1String("QUrl")) { //turn absolute local file paths into relative paths + if (fxObjectNode.modelNode().metaInfo().isValid() && fxObjectNode.modelNode().metaInfo().hasProperty(propertyName)) + if (fxObjectNode.modelNode().metaInfo().propertyType(propertyName) == QLatin1String("QUrl")) { //turn absolute local file paths into relative paths QString filePath = castedValue.toUrl().toString(); if (QFileInfo(filePath).exists() && QFileInfo(filePath).isAbsolute()) { QDir fileDir(QFileInfo(model()->fileUrl().toLocalFile()).absolutePath()); @@ -446,13 +446,13 @@ void PropertyEditor::changeExpression(const QString &name) QmlObjectNode fxObjectNode(m_selectedNode); PropertyEditorValue *value = qobject_cast<PropertyEditorValue*>(QDeclarativeMetaType::toQObject(m_currentType->m_backendValuesPropertyMap.value(underscoreName))); - if (fxObjectNode.modelNode().metaInfo().isValid() && fxObjectNode.modelNode().metaInfo().property(name).isValid()) { - if (fxObjectNode.modelNode().metaInfo().property(name).type() == QLatin1String("QColor")) { + if (fxObjectNode.modelNode().metaInfo().isValid() && fxObjectNode.modelNode().metaInfo().hasProperty(name)) { + if (fxObjectNode.modelNode().metaInfo().propertyType(name) == QLatin1String("QColor")) { if (QColor(value->expression().remove('"')).isValid()) { fxObjectNode.setVariantProperty(name, QColor(value->expression().remove('"'))); return; } - } else if (fxObjectNode.modelNode().metaInfo().property(name).type() == QLatin1String("bool")) { + } else if (fxObjectNode.modelNode().metaInfo().propertyType(name) == QLatin1String("bool")) { if (value->expression().compare("false", Qt::CaseInsensitive) == 0 || value->expression().compare("true", Qt::CaseInsensitive) == 0) { if (value->expression().compare("true", Qt::CaseInsensitive) == 0) fxObjectNode.setVariantProperty(name, true); @@ -460,14 +460,14 @@ void PropertyEditor::changeExpression(const QString &name) fxObjectNode.setVariantProperty(name, false); return; } - } else if (fxObjectNode.modelNode().metaInfo().property(name).type() == QLatin1String("int")) { + } else if (fxObjectNode.modelNode().metaInfo().propertyType(name) == QLatin1String("int")) { bool ok; int intValue = value->expression().toInt(&ok); if (ok) { fxObjectNode.setVariantProperty(name, intValue); return; } - } else if (fxObjectNode.modelNode().metaInfo().property(name).type() == QLatin1String("qreal")) { + } else if (fxObjectNode.modelNode().metaInfo().propertyType(name) == QLatin1String("qreal")) { bool ok; qreal realValue = value->expression().toFloat(&ok); if (ok) { @@ -561,20 +561,19 @@ QString templateGeneration(NodeMetaInfo type, NodeMetaInfo superType, const QmlO qmlTemplate += QLatin1String("layout: VerticalLayout {\n"); QList<QString> orderedList; - orderedList = type.properties(true).keys(); + orderedList = type.propertyNames(); qSort(orderedList); foreach (const QString &name, orderedList) { - const PropertyMetaInfo propertyMetaInfo(type.property(name, true)); QString properName = name; properName.replace(".", "_"); - QString typeName = propertyMetaInfo.type(); + QString typeName = type.propertyType(name); //alias resolution only possible with instance if (typeName == QLatin1String("alias") && objectNode.isValid()) typeName = objectNode.instanceType(name); - if (!superType.hasProperty(name, true)) { + if (!superType.hasProperty(name)) { if (typeName == "int") { qmlTemplate += QString(QLatin1String( "IntEditor { backendValue: backendValues.%2\n caption: \"%1\"\nbaseStateFlag: isBaseState\nslider: false\n}" diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp index bad02129c2dd9b67d789ac270e1fa29d790320ba..776f2aa2c4c0a42588f4307cee0f428b7f7471fc 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp @@ -53,8 +53,8 @@ PropertyEditorValue::PropertyEditorValue(QObject *parent) QVariant PropertyEditorValue::value() const { QVariant returnValue = m_value; - if (modelNode().isValid() && modelNode().metaInfo().isValid() && modelNode().metaInfo().property(name()).isValid()) - if (modelNode().metaInfo().property(name()).type() == QLatin1String("QUrl")) { + if (modelNode().isValid() && modelNode().metaInfo().isValid() && modelNode().metaInfo().hasProperty(name())) + if (modelNode().metaInfo().propertyType(name()) == QLatin1String("QUrl")) { returnValue = returnValue.toUrl().toString(); } return returnValue; @@ -97,8 +97,8 @@ void PropertyEditorValue::setValueWithEmit(const QVariant &value) { if (m_value != value) { QVariant newValue = value; - if (modelNode().isValid() && modelNode().metaInfo().isValid() && modelNode().metaInfo().property(name()).isValid()) - if (modelNode().metaInfo().property(name()).type() == QLatin1String("QUrl")) { + if (modelNode().isValid() && modelNode().metaInfo().isValid() && modelNode().metaInfo().hasProperty(name())) + if (modelNode().metaInfo().propertyType(name()) == QLatin1String("QUrl")) { newValue = QUrl(newValue.toString()); } @@ -272,7 +272,7 @@ void PropertyEditorNodeWrapper::add(const QString &type) if ((m_editorValue && m_editorValue->modelNode().isValid())) { if (propertyType.isEmpty()) - propertyType = m_editorValue->modelNode().metaInfo().property(m_editorValue->name()).type(); + propertyType = m_editorValue->modelNode().metaInfo().propertyType(m_editorValue->name()); while (propertyType.contains('*')) //strip star propertyType.chop(1); m_modelNode = m_editorValue->modelNode().view()->createModelNode(propertyType, 4, 7); @@ -332,7 +332,7 @@ void PropertyEditorNodeWrapper::setup() foreach (QObject *object, m_valuesPropertyMap.children()) delete object; - foreach (const QString &propertyName, m_modelNode.metaInfo().properties().keys()) { + foreach (const QString &propertyName, m_modelNode.metaInfo().propertyNames()) { if (fxObjectNode.isValid()) { PropertyEditorValue *valueObject = new PropertyEditorValue(&m_valuesPropertyMap); valueObject->setName(propertyName); diff --git a/src/plugins/qmldesigner/designercore/include/nodemetainfo.h b/src/plugins/qmldesigner/designercore/include/nodemetainfo.h index 999a31fdec571ddecd39a3ed2bcd5f97073eaf1e..774a860630a345f6dc87f069c966ba7ced5ede8c 100644 --- a/src/plugins/qmldesigner/designercore/include/nodemetainfo.h +++ b/src/plugins/qmldesigner/designercore/include/nodemetainfo.h @@ -77,11 +77,14 @@ public: bool isValid() const; MetaInfo metaInfo() const; - PropertyMetaInfo property(const QString &propertyName, bool resolveDotSyntax = false) const; - QList<NodeMetaInfo> superClasses() const; NodeMetaInfo directSuperClass() const; - QHash<QString,PropertyMetaInfo> properties(bool resolveDotSyntax = false) const; + + + QStringList propertyNames() const; + QStringList propertyNamesOnlyContainer() const; + QString propertyType(const QString &propertyName) const; + QVariant nativePropertyValue(const QString &propertyName, const QVariant &value) const; QString typeName() const; int majorVersion() const; @@ -92,7 +95,7 @@ public: bool hasDefaultProperty() const; QString defaultProperty() const; - bool hasProperty(const QString &propertyName, bool resolveDotSyntax = false) const; + bool hasProperty(const QString &propertyName) const; bool isContainer() const; bool isComponent() const; bool isSubclassOf(const QString& type, int majorVersion, int minorVersio) const; @@ -113,8 +116,11 @@ private: void setDefaultProperty(const QString &defaultProperty); void setSuperClass(const QString &typeName, int majorVersion = -1, int minorVersion = -1); - bool hasLocalProperty(const QString &propertyName, bool resolveDotSyntax = false) const; + bool hasLocalProperty(const QString &propertyName, bool resolveDotSyntax = true) const; QHash<QString,PropertyMetaInfo> dotProperties() const; + QHash<QString,PropertyMetaInfo> properties(bool resolveDotSyntax = true) const; + PropertyMetaInfo property(const QString &propertyName, bool resolveDotSyntax = true) const; + private: QExplicitlySharedDataPointer<Internal::NodeMetaInfoData> m_data; diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index b6ac2227448bede862d3bca0e99cad16d6b6f028..e679f27d70ff3dcd1e17002b875e825def02fc22 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -255,9 +255,9 @@ QHash<QString,PropertyMetaInfo> NodeMetaInfo::dotProperties() const QHash<QString,PropertyMetaInfo> propertiesInfo; - foreach (const QString &propertyName, properties().keys()) { + foreach (const QString &propertyName, properties(false).keys()) { if (property(propertyName).hasDotSubProperties()) { - QString propertyType = property(propertyName).type(); + QString propertyType = property(propertyName, false).type(); if (propertyType.right(1) == "*") propertyType = propertyType.left(propertyType.size() - 1).trimmed(); @@ -377,17 +377,17 @@ bool NodeMetaInfo::hasLocalProperty(const QString &propertyName, bool resolveDot \throws InvalidMetaInfoException if the object is not valid */ -bool NodeMetaInfo::hasProperty(const QString &propertyName, bool resolveDotSyntax) const +bool NodeMetaInfo::hasProperty(const QString &propertyName) const { if (!isValid()) { qWarning() << "NodeMetaInfo is invalid"; return false; } - if (hasLocalProperty(propertyName, resolveDotSyntax)) + if (hasLocalProperty(propertyName, true)) return true; - if (directSuperClass().isValid() && directSuperClass().hasProperty(propertyName, resolveDotSyntax)) + if (directSuperClass().isValid() && directSuperClass().hasProperty(propertyName)) return true; return false; @@ -610,6 +610,38 @@ bool NodeMetaInfo::isSubclassOf(const QString &type, int majorVersion, int minor return false; } +QStringList NodeMetaInfo::propertyNames() const +{ + return properties(true).keys(); +} + +QStringList NodeMetaInfo::propertyNamesOnlyContainer() const +{ + QStringList nameList; + foreach(const PropertyMetaInfo &propertyMetaInfo, properties(true).values()) { + if (propertyMetaInfo.isReadable() && propertyMetaInfo.isWriteable()) + nameList.append(propertyMetaInfo.name()); + } + + return nameList; +} + +QString NodeMetaInfo::propertyType(const QString &propertyName) const +{ + if (!hasProperty(propertyName)) + return QString(); + + return property(propertyName).type(); +} + +QVariant NodeMetaInfo::nativePropertyValue(const QString &propertyName, const QVariant &value) const +{ + if (!hasProperty(propertyName)) + return value; + + return property(propertyName).castedValue(value); +} + void NodeMetaInfo::setQmlFile(const QString &filePath) { if (!isValid()) {