From 35a773b2dcf3746817d169a1cd34b12d61f043ad Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 23 Aug 2022 16:43:44 +0200 Subject: [PATCH] QmlDesigner: Use ProjectStorage Task-number: QDS-7379 Change-Id: I50c8a4a527daa7268a723094b6ceec37d10dfaa6 Reviewed-by: Qt CI Bot Reviewed-by: Thomas Hartmann Reviewed-by: Tim Jenssen Reviewed-by: --- src/plugins/qmldesigner/CMakeLists.txt | 15 +- .../components/bindingeditor/actioneditor.cpp | 18 +- .../bindingeditor/bindingeditor.cpp | 9 +- .../components/bindingeditor/signallist.cpp | 2 +- .../connectioneditor/bindingmodel.cpp | 24 +- .../connectioneditor/connectionmodel.cpp | 3 +- .../connectioneditor/connectionviewwidget.cpp | 8 +- .../components/connectioneditor/delegates.cpp | 20 +- .../dynamicpropertiesmodel.cpp | 6 +- .../curveeditor/curveeditormodel.cpp | 11 +- .../components/integration/designdocument.cpp | 5 +- .../components/integration/designdocument.h | 14 +- .../materialeditor/materialeditorview.cpp | 9 +- .../choosefrompropertylistdialog.cpp | 6 +- .../navigator/choosefrompropertylistdialog.h | 2 +- .../navigator/navigatortreemodel.cpp | 29 +- .../propertyeditorqmlbackend.cpp | 31 +- .../propertyeditor/propertyeditorqmlbackend.h | 2 +- .../propertyeditor/propertyeditorvalue.cpp | 17 +- .../propertyeditor/propertyeditorview.cpp | 16 +- .../components/sourcetool/sourcetool.cpp | 2 +- .../timelineeditor/timelinecontrols.cpp | 6 +- .../timelineeditor/timelinecontrols.h | 2 +- .../timelineeditor/timelinepropertyitem.cpp | 10 +- .../transitioneditor/transitioneditorview.cpp | 10 +- .../qmldesigner/designercore/include/model.h | 15 +- .../designercore/include/nodemetainfo.h | 54 ++- .../designercore/include/projectstorageids.h | 2 +- .../designercore/include/propertymetainfo.h | 42 +-- .../include/qmldesignercorelib_global.h | 8 + .../include/qmltimelinekeyframegroup.h | 2 +- .../designercore/metainfo/nodemetainfo.cpp | 348 ++++++++++++++---- .../designercore/model/abstractview.cpp | 2 +- .../designercore/model/internalnode_p.h | 6 +- .../qmldesigner/designercore/model/model.cpp | 52 ++- .../qmldesigner/designercore/model/model_p.h | 4 +- .../designercore/model/modelnode.cpp | 27 +- .../designercore/model/qmlobjectnode.cpp | 2 +- .../model/qmltimelinekeyframegroup.cpp | 11 +- .../designercore/model/texttomodelmerger.cpp | 3 +- .../projectstorage/projectstorage.h | 2 +- .../projectstorage/projectstoragefwd.h | 38 ++ .../projectstorage/projectstorageinfotypes.h | 121 ++++++ .../projectstorage/projectstoragetypes.h | 83 +---- .../projectstorage/qmldocumentparser.h | 7 +- .../qmldesigner/qmldesignerprojectmanager.h | 9 +- tests/auto/qml/qmldesigner/CMakeLists.txt | 2 +- .../qml/qmldesigner/coretests/CMakeLists.txt | 1 + .../designercore/include/nodemetainfo.h | 11 +- .../unit/unittest/gtest-creator-printing.cpp | 7 +- 50 files changed, 741 insertions(+), 395 deletions(-) create mode 100644 src/plugins/qmldesigner/designercore/projectstorage/projectstoragefwd.h create mode 100644 src/plugins/qmldesigner/designercore/projectstorage/projectstorageinfotypes.h diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 517d0594f4d..3ef5dbcce1c 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -3,6 +3,15 @@ if (APPLE) set(QmlDesignerPluginInstallPrefix "${IDE_PLUGIN_PATH}/QmlDesigner") endif() + +env_with_default("QDS_USE_PROJECTSTORAGE" ENV_QDS_USE_PROJECTSTORAGE OFF) +option(USE_PROJECTSTORAGE "Build uses ProjectStorage" ${ENV_QDS_USE_PROJECTSTORAGE}) +add_feature_info("Build uses ProjectStorage" ${USE_PROJECTSTORAGE} "") + +env_with_default("QDS_WITH_QMLDOM" ENV_QDS_WITH_QMLDOM OFF) +option(WITH_QMLDOM "Build with QmlDom" ${ENV_QDS_WITH_QMLDOM}) +add_feature_info("Build with QmlDom" ${WITH_QMLDOM} "") + add_qtc_plugin(QmlDesigner CONDITION Qt5_VERSION VERSION_GREATER_EQUAL 6.2.0 AND TARGET Qt5::QuickWidgets AND TARGET Qt5::Svg DEPENDS @@ -11,6 +20,7 @@ add_qtc_plugin(QmlDesigner DEFINES IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\" SHARE_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../../../share/qtcreator/qmldesigner" + $<$:QDS_USE_PROJECTSTORAGE> PUBLIC_INCLUDES "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_CURRENT_LIST_DIR}/designercore/include" @@ -50,10 +60,6 @@ add_qtc_plugin(QmlDesigner include(qmldesignercore.cmake) extend_with_qmldesigner_core(QmlDesigner) -env_with_default("QDS_WITH_QMLDOM" ENV_QDS_WITH_QMLDOM OFF) -option(WITH_QMLDOM "Build with QmlDom" ${ENV_QDS_WITH_QMLDOM}) -add_feature_info("Build with QmlDom" ${WITH_QMLDOM} "") - function(get_and_add_as_subdirectory name repository git_tag build_dir source_dir source_subdir) # make the configuration in the build dir file(MAKE_DIRECTORY ${build_dir}/${name}) @@ -458,6 +464,7 @@ extend_qtc_plugin(QmlDesigner nonlockingmutex.h projectstorageinterface.h projectstorage.cpp projectstorage.h + projectstoragefwd.h projectstoragepathwatcher.h projectstoragepathwatcherinterface.h projectstoragepathwatchernotifierinterface.h diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp index 8f0d063424c..7275ffbeed7 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp @@ -195,6 +195,10 @@ void ActionEditor::prepareConnections() constexpr auto typeWhiteList = std::make_tuple( "string", "real", "int", "double", "bool", "QColor", "color", "QtQuick.Item", "QQuickItem"); + auto isSkippedType = [](auto &&type) { + return !(type.isString() || type.isInteger() || type.isBool() || type.isColor() + || type.isFloat() || type.isQmlItem()); + }; static QList methodBlackList({"toString", "destroy"}); QList connections; @@ -210,12 +214,12 @@ void ActionEditor::prepareConnections() ActionEditorDialog::ConnectionOption connection(modelNode.id()); for (const auto &property : modelNode.metaInfo().properties()) { - if (!property.hasPropertyTypeName(typeWhiteList)) + if (isSkippedType(property.propertyType())) continue; connection.properties.append( ActionEditorDialog::PropertyOption(QString::fromUtf8(property.name()), - skipCpp(std::move(property.propertyTypeName())), + skipCpp(property.propertyType().typeName()), property.isWritable())); } @@ -270,13 +274,13 @@ void ActionEditor::prepareConnections() if (metaInfo.isValid()) { ActionEditorDialog::SingletonOption singelton; for (const auto &property : metaInfo.properties()) { - if (!property.hasPropertyTypeName(typeWhiteList)) + if (isSkippedType(property.propertyType())) continue; - singelton.properties.append( - ActionEditorDialog::PropertyOption(QString::fromUtf8(property.name()), - skipCpp(property.propertyTypeName()), - property.isWritable())); + singelton.properties.append(ActionEditorDialog::PropertyOption( + QString::fromUtf8(property.name()), + skipCpp(property.propertyType().typeName()), + property.isWritable())); } if (!singelton.properties.isEmpty()) { diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp index 27e8a41cb3c..a8a232f9c5d 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp @@ -113,7 +113,10 @@ void BindingEditor::setBackendValue(const QVariant &backendValue) const ModelNode node = propertyEditorValue->modelNode(); if (node.isValid()) { - m_backendValueTypeName = node.metaInfo().property(propertyEditorValue->name()).propertyTypeName(); + m_backendValueTypeName = node.metaInfo() + .property(propertyEditorValue->name()) + .propertyType() + .typeName(); QString nodeId = node.id(); if (nodeId.isEmpty()) @@ -206,7 +209,7 @@ void BindingEditor::prepareBindings() for (const auto &objnode : allNodes) { BindingEditorDialog::BindingOption binding; for (const auto &property : objnode.metaInfo().properties()) { - const TypeName &propertyTypeName = property.propertyTypeName(); + const TypeName &propertyTypeName = property.propertyType().typeName(); if (skipTypeFiltering || (m_backendValueTypeName == propertyTypeName) @@ -260,7 +263,7 @@ void BindingEditor::prepareBindings() BindingEditorDialog::BindingOption binding; for (const auto &property : metaInfo.properties()) { - TypeName propertyTypeName = property.propertyTypeName(); + TypeName propertyTypeName = property.propertyType().typeName(); if (skipTypeFiltering || (m_backendValueTypeName == propertyTypeName) diff --git a/src/plugins/qmldesigner/components/bindingeditor/signallist.cpp b/src/plugins/qmldesigner/components/bindingeditor/signallist.cpp index 603f2004fd4..6ce77793afa 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/signallist.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/signallist.cpp @@ -169,7 +169,7 @@ void SignalList::prepareSignals() // Gather valid properties and aliases from components for (const auto &property : node.metaInfo().properties()) { - const NodeMetaInfo info = m_modelNode.model()->metaInfo(property.propertyTypeName()); + const NodeMetaInfo info = property.propertyType(); callOnlyMouseSignalNames(info.signalNames(), QmlFlowViewNode::mouseSignals(), diff --git a/src/plugins/qmldesigner/components/connectioneditor/bindingmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/bindingmodel.cpp index 9a6327f3cd1..d72d938f3be 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/bindingmodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/bindingmodel.cpp @@ -157,10 +157,10 @@ QStringList BindingModel::possibleSourceProperties(const BindingProperty &bindin const QStringList stringlist = expression.split(QLatin1String(".")); QStringList possibleProperties; - TypeName typeName; + NodeMetaInfo type; if (auto metaInfo = bindingProperty.parentModelNode().metaInfo(); metaInfo.isValid()) - typeName = metaInfo.property(bindingProperty.name()).propertyTypeName(); + type = metaInfo.property(bindingProperty.name()).propertyType(); else qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for target node"; @@ -172,18 +172,16 @@ QStringList BindingModel::possibleSourceProperties(const BindingProperty &bindin //if it's not a valid model node, maybe it's a singleton if (RewriterView* rv = connectionView()->rewriterView()) { for (const QmlTypeData &data : rv->getQMLTypes()) { - if (!data.typeName.isEmpty()) { - if (data.typeName == id) { - NodeMetaInfo metaInfo = connectionView()->model()->metaInfo(data.typeName.toUtf8()); + if (!data.typeName.isEmpty() && data.typeName == id) { + NodeMetaInfo metaInfo = connectionView()->model()->metaInfo(data.typeName.toUtf8()); - if (metaInfo.isValid()) { - for (const auto &property : metaInfo.properties()) { - //without check for now - possibleProperties.push_back(QString::fromUtf8(property.name())); - } - - return possibleProperties; + if (metaInfo.isValid()) { + for (const auto &property : metaInfo.properties()) { + //without check for now + possibleProperties.push_back(QString::fromUtf8(property.name())); } + + return possibleProperties; } } } @@ -207,7 +205,7 @@ QStringList BindingModel::possibleSourceProperties(const BindingProperty &bindin if (metaInfo.isValid()) { for (const auto &property : metaInfo.properties()) { - if (property.propertyTypeName() == typeName) //### todo proper check + if (property.propertyType() == type) //### todo proper check possibleProperties.push_back(QString::fromUtf8(property.name())); } } else { diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp index bf5d24ddd0d..7eb6842deab 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp @@ -474,8 +474,7 @@ QStringList ConnectionModel::getPossibleSignalsForConnection(const ModelNode &co auto getAliasMetaSignals = [&](QString aliasPart, NodeMetaInfo metaInfo) { if (metaInfo.isValid() && metaInfo.hasProperty(aliasPart.toUtf8())) { - NodeMetaInfo propertyMetaInfo = connectionView()->model()->metaInfo( - metaInfo.property(aliasPart.toUtf8()).propertyTypeName()); + NodeMetaInfo propertyMetaInfo = metaInfo.property(aliasPart.toUtf8()).propertyType(); if (propertyMetaInfo.isValid()) { return propertyNameListToStringList(propertyMetaInfo.signalNames()); } diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp index 178f5657b19..050c5e86015 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp @@ -216,9 +216,11 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event) return; const ModelNode node = property.parentModelNode(); - const TypeName typeName = property.isDynamic() - ? property.dynamicTypeName() - : node.metaInfo().property(property.name()).propertyTypeName(); + const TypeName typeName = property.isDynamic() ? property.dynamicTypeName() + : node.metaInfo() + .property(property.name()) + .propertyType() + .typeName(); const QString targetName = node.displayName() + "." + property.name(); diff --git a/src/plugins/qmldesigner/components/connectioneditor/delegates.cpp b/src/plugins/qmldesigner/components/connectioneditor/delegates.cpp index df8ba039910..4c15448a2c9 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/delegates.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/delegates.cpp @@ -299,20 +299,12 @@ QWidget *ConnectionDelegate::createEditor(QWidget *parent, const QStyleOptionVie auto addMetaInfoProperties = [&](const NodeMetaInfo& itemMetaInfo, QString itemName){ if (itemMetaInfo.isValid()) { for (const auto &property : itemMetaInfo.properties()) { - TypeName propertyType = property.propertyTypeName(); - if (!propertyType.isEmpty()) { - //first letter is a reliable item indicator - QChar firstLetter = QString::fromUtf8(propertyType).at(0); - if (firstLetter.isLetter() && firstLetter.isUpper()) { - if (!property.isEnumType() && !property.isPrivate() - && !property.isListProperty() && !property.isPointer()) { - NodeMetaInfo propertyMetaInfo = - connectionModel->connectionView()->model()->metaInfo(propertyType); - if (propertyMetaInfo.isValid()) { - if (propertyMetaInfo.isQmlItem()) { - connectionComboBox->addItem(itemName + "." + property.name()); - } - } + NodeMetaInfo propertyType = property.propertyType(); + if (propertyType.isValid() && propertyType.isFileComponent()) { + if (!property.isEnumType() && !property.isPrivate() + && !property.isListProperty() && !property.isPointer()) { + if (propertyType.isQmlItem()) { + connectionComboBox->addItem(itemName + "." + property.name()); } } } diff --git a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp index 0ebb2864be2..24cc50f4024 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp @@ -383,10 +383,10 @@ QStringList DynamicPropertiesModel::possibleSourceProperties(const BindingProper const QString expression = bindingProperty.expression(); const QStringList stringlist = expression.split(QLatin1String(".")); - PropertyName typeName; + NodeMetaInfo type; if (auto metaInfo = bindingProperty.parentModelNode().metaInfo(); metaInfo.isValid()) { - typeName = metaInfo.property(bindingProperty.name()).propertyTypeName(); + type = metaInfo.property(bindingProperty.name()).propertyType(); } else { qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for target node"; } @@ -405,7 +405,7 @@ QStringList DynamicPropertiesModel::possibleSourceProperties(const BindingProper if (metaInfo.isValid()) { QStringList possibleProperties; for (const auto &property : metaInfo.properties()) { - if (property.propertyTypeName() == typeName) //### todo proper check + if (property.propertyType() == type) //### todo proper check possibleProperties.push_back(QString::fromUtf8(property.name())); } return possibleProperties; diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp index 13d43ecbd13..1b96854d9fd 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditormodel.cpp @@ -36,6 +36,7 @@ #include #include +#include #include #include @@ -218,17 +219,13 @@ void CurveEditorModel::reset(const std::vector &items) PropertyTreeItem::ValueType typeFrom(const QmlDesigner::QmlTimelineKeyframeGroup &group) { - if (group.valueType() == QmlDesigner::TypeName("double") - || group.valueType() == QmlDesigner::TypeName("real") - || group.valueType() == QmlDesigner::TypeName("float")) + if (group.valueType().isFloat()) return PropertyTreeItem::ValueType::Double; - if (group.valueType() == QmlDesigner::TypeName("boolean") - || group.valueType() == QmlDesigner::TypeName("bool")) + if (group.valueType().isBool()) return PropertyTreeItem::ValueType::Bool; - if (group.valueType() == QmlDesigner::TypeName("integer") - || group.valueType() == QmlDesigner::TypeName("int")) + if (group.valueType().isInteger()) return PropertyTreeItem::ValueType::Integer; // Ignoring: QColor / HAlignment / VAlignment diff --git a/src/plugins/qmldesigner/components/integration/designdocument.cpp b/src/plugins/qmldesigner/components/integration/designdocument.cpp index 87a8af19fa4..be3c9819e04 100644 --- a/src/plugins/qmldesigner/components/integration/designdocument.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocument.cpp @@ -617,12 +617,13 @@ void DesignDocument::paste() const double scatterRange = 20.; int offset = QRandomGenerator::global()->generateDouble() * scatterRange - scatterRange / 2; + const auto defaultPropertyName = targetNode.metaInfo().defaultPropertyName(); + auto parentProperty = targetNode.nodeListProperty(defaultPropertyName); for (const ModelNode &node : qAsConst(selectedNodes)) { - PropertyName defaultProperty(targetNode.metaInfo().defaultPropertyName()); ModelNode pastedNode(view.insertModel(node)); pastedNodeList.append(pastedNode); scatterItem(pastedNode, targetNode, offset); - targetNode.nodeListProperty(defaultProperty).reparentHere(pastedNode); + parentProperty.reparentHere(pastedNode); } view.setSelectedModelNodes(pastedNodeList); diff --git a/src/plugins/qmldesigner/components/integration/designdocument.h b/src/plugins/qmldesigner/components/integration/designdocument.h index ce5f43a997b..baed2ea0a4e 100644 --- a/src/plugins/qmldesigner/components/integration/designdocument.h +++ b/src/plugins/qmldesigner/components/integration/designdocument.h @@ -25,13 +25,13 @@ #pragma once -#include -#include #include #include -#include - #include +#include +#include +#include +#include #include #include @@ -46,10 +46,6 @@ namespace ProjectExplorer { class Target; } -namespace Sqlite { -class Database; -} - namespace QmlDesigner { class ModelNode; @@ -58,8 +54,6 @@ class QmlObjectNode; class CrumbleBarInfo; class ViewManager; class AbstractView; -template -class ProjectStorage; class QMLDESIGNERCORE_EXPORT DesignDocument: public QObject { diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index 55129a17b66..564776574d4 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -145,7 +145,7 @@ void MaterialEditorView::changeValue(const QString &name) bool propertyTypeUrl = false; if (metaInfo.isValid() && metaInfo.hasProperty(propertyName)) { - if (metaInfo.property(propertyName).propertyTypeNameIsUrl()) { + if (metaInfo.property(propertyName).propertyType().isUrl()) { // turn absolute local file paths into relative paths propertyTypeUrl = true; QString filePath = castedValue.toUrl().toString(); @@ -209,7 +209,7 @@ void MaterialEditorView::changeExpression(const QString &propertyName) if (auto metaInfo = m_selectedMaterial.metaInfo(); metaInfo.isValid() && metaInfo.hasProperty(name)) { - auto propertyTypeName = metaInfo.property(name).propertyTypeName(); + auto propertyTypeName = metaInfo.property(name).propertyType().typeName(); if (propertyTypeName == "QColor") { if (QColor(value->expression().remove('"')).isValid()) { qmlObjectNode.setVariantProperty(name, QColor(value->expression().remove('"'))); @@ -542,8 +542,7 @@ void MaterialEditorView::setupQmlBackend() NodeMetaInfo metaInfo = m_selectedMaterial.metaInfo(); if (metaInfo.isValid()) { diffClassName = metaInfo.typeName(); - const QList hierarchy = metaInfo.classHierarchy(); - for (const NodeMetaInfo &metaInfo : hierarchy) { + for (const NodeMetaInfo &metaInfo : metaInfo.classHierarchy()) { if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsUrl)) break; qmlSpecificsUrl = PropertyEditorQmlBackend::getQmlFileUrl(metaInfo.typeName() @@ -1022,7 +1021,7 @@ void QmlDesigner::MaterialEditorView::highlightSupportedProperties(bool highligh QTC_ASSERT(metaInfo.isValid(), return); for (const QString &propName : propNames) { - if (metaInfo.property(propName.toUtf8()).hasPropertyTypeName("QtQuick3D.Texture")) { + if (metaInfo.property(propName.toUtf8()).propertyType().isQtQuick3DTexture()) { QObject *propEditorValObj = propMap.value(propName).value(); PropertyEditorValue *propEditorVal = qobject_cast(propEditorValObj); propEditorVal->setHasActiveDrag(highlight); diff --git a/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp b/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp index f8da77025c8..b49cb8762a1 100644 --- a/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp +++ b/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp @@ -66,7 +66,7 @@ ChooseFromPropertyListFilter::ChooseFromPropertyListFilter(const NodeMetaInfo &i || parentInfo.isSubclassOf("QtQuick3D.PrincipledMaterial")) { // All texture properties are valid targets for (const auto &property : parentInfo.properties()) { - const TypeName &propType = property.propertyTypeName(); + const TypeName &propType = property.propertyType().typeName(); if (propType == textureType || propType == textureTypeCpp) { propertyList.append(QString::fromUtf8(property.name())); if (breakOnFirst) @@ -167,12 +167,12 @@ ChooseFromPropertyListDialog *ChooseFromPropertyListDialog::createIfNeeded( // Create dialog for selecting writable properties of exact property type ChooseFromPropertyListDialog *ChooseFromPropertyListDialog::createIfNeeded( - const ModelNode &targetNode, TypeName propertyType, QWidget *parent) + const ModelNode &targetNode, const NodeMetaInfo &propertyType, QWidget *parent) { const NodeMetaInfo metaInfo = targetNode.metaInfo(); QStringList matchingNames; for (const auto &property : metaInfo.properties()) { - if (property.hasPropertyTypeName(propertyType) && property.isWritable()) + if (property.propertyType() == propertyType && property.isWritable()) matchingNames.append(QString::fromUtf8(property.name())); } diff --git a/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.h b/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.h index fc9e494ce31..f8e1c0d5092 100644 --- a/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.h +++ b/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.h @@ -58,7 +58,7 @@ public: const ModelNode &newNode, QWidget *parent = 0); static ChooseFromPropertyListDialog *createIfNeeded(const ModelNode &targetNode, - TypeName type, + const NodeMetaInfo &propertyType, QWidget *parent = 0); private: diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 015b8cf9d6c..bfa15edc4ac 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -1040,7 +1040,9 @@ bool NavigatorTreeModel::dropAsImage3dTexture(const ModelNode &targetNode, || targetNode.isSubclassOf("QtQuick3D.PrincipledMaterial")) { // if dropping an image on a material, create a texture instead of image // Show texture property selection dialog - auto dialog = ChooseFromPropertyListDialog::createIfNeeded(targetNode, "QtQuick3D.Texture", + auto dialog = ChooseFromPropertyListDialog::createIfNeeded(targetNode, + m_view->model()->metaInfo( + "QtQuick3D.Texture"), Core::ICore::dialogParent()); if (!dialog) return false; @@ -1103,10 +1105,12 @@ ModelNode NavigatorTreeModel::createTextureNode(const NodeAbstractProperty &targ return {}; } -TypeName propertyType(const NodeAbstractProperty &property) +namespace { +NodeMetaInfo propertyType(const NodeAbstractProperty &property) { - return property.parentModelNode().metaInfo().property(property.name()).propertyTypeName(); + return property.parentModelNode().metaInfo().property(property.name()).propertyType(); } +} // namespace void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProperty, const QList &modelNodes, @@ -1115,18 +1119,17 @@ void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProper { QTC_ASSERT(m_view, return); - auto doMoveNodesInteractive = [&parentProperty, modelNodes, targetIndex](){ - const TypeName propertyQmlType = propertyType(parentProperty); + auto doMoveNodesInteractive = [&parentProperty, modelNodes, targetIndex]() { + const auto propertyQmlType = propertyType(parentProperty); int idx = targetIndex; for (const ModelNode &modelNode : modelNodes) { - if (modelNode.isValid() - && modelNode != parentProperty.parentModelNode() - && !modelNode.isAncestorOf(parentProperty.parentModelNode()) - && (modelNode.metaInfo().isSubclassOf(propertyQmlType) - || propertyQmlType == "alias" - || parentProperty.name() == "data" - || (parentProperty.parentModelNode().metaInfo().defaultPropertyName() == parentProperty.name() - && propertyQmlType == ".QQmlComponent"))) { + if (modelNode.isValid() && modelNode != parentProperty.parentModelNode() + && !modelNode.isAncestorOf(parentProperty.parentModelNode()) + && (modelNode.metaInfo().isSubclassOf(propertyQmlType) || propertyQmlType.isAlias() + || parentProperty.name() == "data" + || (parentProperty.parentModelNode().metaInfo().defaultPropertyName() + == parentProperty.name() + && propertyQmlType.isQmlComponent()))) { //### todo: allowing alias is just a heuristic //once the MetaInfo is part of instances we can do this right diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp index 2e43c1107e4..5bedc2f7e91 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp @@ -515,7 +515,7 @@ void PropertyEditorQmlBackend::initialSetup(const TypeName &typeName, const QUrl for (const auto &property : metaInfo.properties()) { setupPropertyEditorValue(property.name(), propertyEditor, - QString::fromUtf8(property.propertyTypeName())); + QString::fromUtf8(property.propertyType().typeName())); } auto valueObject = qobject_cast(variantToQObject( @@ -579,18 +579,16 @@ inline bool dotPropertyHeuristic(const QmlObjectNode &node, const NodeMetaInfo & const PropertyName parentProperty = list.first(); const PropertyName itemProperty = list.last(); - TypeName typeName = type.property(parentProperty).propertyTypeName(); + NodeMetaInfo propertyType = type.property(parentProperty).propertyType(); NodeMetaInfo itemInfo = node.view()->model()->metaInfo("QtQuick.Item"); NodeMetaInfo textInfo = node.view()->model()->metaInfo("QtQuick.Text"); NodeMetaInfo rectangleInfo = node.view()->model()->metaInfo("QtQuick.Rectangle"); NodeMetaInfo imageInfo = node.view()->model()->metaInfo("QtQuick.Image"); - if (typeName == "font" - || itemInfo.hasProperty(itemProperty) - || textInfo.isSubclassOf(typeName) - || rectangleInfo.isSubclassOf(typeName) - || imageInfo.isSubclassOf(typeName)) + if (propertyType.isFont() || itemInfo.hasProperty(itemProperty) + || textInfo.isSubclassOf(propertyType) || rectangleInfo.isSubclassOf(propertyType) + || imageInfo.isSubclassOf(propertyType)) return false; return true; @@ -630,10 +628,10 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &metaTyp if (!superType.hasProperty(propertyName) // TODO add property.isLocalProperty() && property.isWritable() && dotPropertyHeuristic(node, metaType, propertyName)) { - QString typeName = QString::fromUtf8(property.propertyTypeName()); + QString typeName = QString::fromUtf8(property.propertyType().typeName()); if (typeName == "alias" && node.isValid()) - typeName = QString::fromLatin1(node.instanceType(propertyName)); + typeName = QString::fromUtf8(node.instanceType(propertyName)); // Check if a template for the type exists if (allTypes.contains(typeName)) { @@ -674,9 +672,9 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &metaTyp PropertyName underscoreProperty = propertyName; underscoreProperty.replace('.', '_'); - TypeName typeName = property.propertyTypeName(); + TypeName typeName = property.propertyType().typeName(); // alias resolution only possible with instance - if (typeName == "alias" && node.isValid()) + if (!useProjectStorage() && typeName == "alias" && node.isValid()) typeName = node.instanceType(propertyName); QString filledTemplate; @@ -743,9 +741,9 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &metaTyp emptyTemplate = false; for (auto &[property, properties] : propertyMap) { // for (auto it = propertyMap.cbegin(); it != propertyMap.cend(); ++it) { - TypeName parentTypeName = property.propertyTypeName(); + TypeName parentTypeName = property.propertyType().typeName(); // alias resolution only possible with instance - if (parentTypeName == "alias" && node.isValid()) + if (!useProjectStorage() && parentTypeName == "alias" && node.isValid()) parentTypeName = node.instanceType(property.name()); qmlInnerTemplate += "Section {\n"; @@ -817,9 +815,10 @@ static NodeMetaInfo findCommonSuperClass(const NodeMetaInfo &first, const NodeMe NodeMetaInfo PropertyEditorQmlBackend::findCommonAncestor(const ModelNode &node) { if (!node.isValid()) - return {}; + return node.metaInfo(); - QTC_ASSERT(node.metaInfo().isValid(), return {}); + if (auto metaInfo = node.metaInfo(); metaInfo.isValid()) + return metaInfo; AbstractView *view = node.view(); @@ -910,7 +909,7 @@ void PropertyEditorQmlBackend::setValueforAuxiliaryProperties(const QmlObjectNod QUrl PropertyEditorQmlBackend::getQmlUrlForMetaInfo(const NodeMetaInfo &metaInfo, TypeName &className) { if (metaInfo.isValid()) { - const QList hierarchy = metaInfo.classHierarchy(); + const NodeMetaInfos hierarchy = metaInfo.classHierarchy(); for (const NodeMetaInfo &info : hierarchy) { QUrl fileUrl = fileToUrl(locateQmlFile(info, QString::fromUtf8(qmlFileName(info)))); if (fileUrl.isValid()) { diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h index e71382ecebd..4185a9ce58e 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h @@ -71,7 +71,7 @@ public: static QString propertyEditorResourcesPath(); static QString templateGeneration(const NodeMetaInfo &type, const NodeMetaInfo &superType, const QmlObjectNode &node); - static QUrl getQmlFileUrl(const TypeName &relativeTypeName, const NodeMetaInfo &info = NodeMetaInfo()); + static QUrl getQmlFileUrl(const TypeName &relativeTypeName, const NodeMetaInfo &info); static QUrl getQmlUrlForMetaInfo(const NodeMetaInfo &modelNode, TypeName &className); static bool checkIfUrlExists(const QUrl &url); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp index 59e8af563d4..b97121af142 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp @@ -63,7 +63,7 @@ QVariant PropertyEditorValue::value() const if (modelNode().isValid()) { if (auto metaInfo = modelNode().metaInfo(); metaInfo.isValid() && metaInfo.hasProperty(name()) - && metaInfo.property(name()).propertyTypeNameIsUrl()) { + && metaInfo.property(name()).propertyType().isUrl()) { returnValue = returnValue.toUrl().toString(); } } @@ -106,7 +106,7 @@ static void fixAmbigousColorNames(const QmlDesigner::ModelNode &modelNode, { if (modelNode.isValid()) { if (auto metaInfo = modelNode.metaInfo(); - metaInfo.isValid() && metaInfo.property(name).propertyTypeNameIsColor()) { + metaInfo.isValid() && metaInfo.property(name).propertyType().isColor()) { if ((value->type() == QVariant::Color)) { QColor color = value->value(); int alpha = color.alpha(); @@ -124,7 +124,7 @@ static void fixUrl(const QmlDesigner::ModelNode &modelNode, const QmlDesigner::P { if (modelNode.isValid()) { if (auto metaInfo = modelNode.metaInfo(); - metaInfo.isValid() && metaInfo.property(name).propertyTypeNameIsUrl()) + metaInfo.isValid() && metaInfo.property(name).propertyType().isUrl()) if (!value->isValid()) *value = QStringLiteral(""); @@ -149,7 +149,7 @@ void PropertyEditorValue::setValueWithEmit(const QVariant &value) if (modelNode().isValid()) { if (auto metaInfo = modelNode().metaInfo(); metaInfo.isValid() && metaInfo.hasProperty(name()) - && metaInfo.property(name()).propertyTypeNameIsUrl()) { + && metaInfo.property(name()).propertyType().isUrl()) { newValue = QUrl(newValue.toString()); } } @@ -268,7 +268,7 @@ bool PropertyEditorValue::isTranslated() const if (modelNode().isValid()) { if (auto metaInfo = modelNode().metaInfo(); metaInfo.isValid() && metaInfo.hasProperty(name()) - && metaInfo.property(name()).propertyTypeNameIsString()) { + && metaInfo.property(name()).propertyType().isString()) { const QmlDesigner::QmlObjectNode objectNode(modelNode()); if (objectNode.isValid() && objectNode.hasBindingProperty(name())) { const QRegularExpression rx( @@ -438,7 +438,7 @@ QString PropertyEditorValue::getTranslationContext() const if (modelNode().isValid()) { if (auto metaInfo = modelNode().metaInfo(); metaInfo.isValid() && metaInfo.hasProperty(name()) - && metaInfo.property(name()).propertyTypeNameIsString()) { + && metaInfo.property(name()).propertyType().isString()) { const QmlDesigner::QmlObjectNode objectNode(modelNode()); if (objectNode.isValid() && objectNode.hasBindingProperty(name())) { const QRegularExpression rx(QRegularExpression::anchoredPattern( @@ -532,7 +532,7 @@ bool PropertyEditorValue::idListReplace(int idx, const QString &value) void PropertyEditorValue::commitDrop(const QString &path) { if (m_modelNode.isSubclassOf("QtQuick3D.Material") - && m_modelNode.metaInfo().property(m_name).hasPropertyTypeName("QtQuick3D.Texture")) { + && m_modelNode.metaInfo().property(m_name).propertyType().isQtQuick3DTexture()) { // create a texture node QmlDesigner::NodeMetaInfo metaInfo = m_modelNode.view()->model()->metaInfo("QtQuick3D.Texture"); QmlDesigner::ModelNode texture = m_modelNode.view()->createModelNode("QtQuick3D.Texture", @@ -635,7 +635,8 @@ void PropertyEditorNodeWrapper::add(const QString &type) propertyType = m_editorValue->modelNode() .metaInfo() .property(m_editorValue->name()) - .propertyTypeName(); + .propertyType() + .typeName(); } while (propertyType.contains('*')) //strip star propertyType.chop(1); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp index c9183c467c0..1c05aa87aea 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp @@ -201,7 +201,7 @@ void PropertyEditorView::changeValue(const QString &name) bool propertyTypeUrl = false; if (metaInfo.isValid() && metaInfo.hasProperty(propertyName) - && metaInfo.property(propertyName).propertyTypeNameIsUrl()) { + && metaInfo.property(propertyName).propertyType().isUrl()) { // turn absolute local file paths into relative paths propertyTypeUrl = true; QString filePath = castedValue.toUrl().toString(); @@ -272,13 +272,13 @@ void PropertyEditorView::changeExpression(const QString &propertyName) if (auto metaInfo = qmlObjectNode->modelNode().metaInfo(); metaInfo.isValid() && metaInfo.hasProperty(name)) { - const auto &propertTypeName = metaInfo.property(name).propertyTypeName(); - if (propertTypeName == "QColor") { + const auto &propertType = metaInfo.property(name).propertyType(); + if (propertType.isColor()) { if (QColor(value->expression().remove('"')).isValid()) { qmlObjectNode->setVariantProperty(name, QColor(value->expression().remove('"'))); return; } - } else if (propertTypeName == "bool") { + } else if (propertType.isBool()) { if (isTrueFalseLiteral(value->expression())) { if (value->expression().compare("true", Qt::CaseInsensitive) == 0) qmlObjectNode->setVariantProperty(name, true); @@ -286,21 +286,21 @@ void PropertyEditorView::changeExpression(const QString &propertyName) qmlObjectNode->setVariantProperty(name, false); return; } - } else if (propertTypeName == "int") { + } else if (propertType.isInteger()) { bool ok; int intValue = value->expression().toInt(&ok); if (ok) { qmlObjectNode->setVariantProperty(name, intValue); return; } - } else if (propertTypeName == "qreal") { + } else if (propertType.isFloat()) { bool ok; qreal realValue = value->expression().toDouble(&ok); if (ok) { qmlObjectNode->setVariantProperty(name, realValue); return; } - } else if (propertTypeName == "QVariant") { + } else if (propertType.isVariant()) { bool ok; qreal realValue = value->expression().toDouble(&ok); if (ok) { @@ -464,7 +464,7 @@ void PropertyEditorView::setupQmlBackend() TypeName diffClassName; if (commonAncestor.isValid()) { diffClassName = commonAncestor.typeName(); - const QList hierarchy = commonAncestor.classHierarchy(); + const NodeMetaInfos hierarchy = commonAncestor.classHierarchy(); for (const NodeMetaInfo &metaInfo : hierarchy) { if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsFile)) break; diff --git a/src/plugins/qmldesigner/components/sourcetool/sourcetool.cpp b/src/plugins/qmldesigner/components/sourcetool/sourcetool.cpp index 6ce5c488511..e816f418c1c 100644 --- a/src/plugins/qmldesigner/components/sourcetool/sourcetool.cpp +++ b/src/plugins/qmldesigner/components/sourcetool/sourcetool.cpp @@ -54,7 +54,7 @@ bool modelNodeHasUrlSource(const QmlDesigner::ModelNode &modelNode) { QmlDesigner::NodeMetaInfo metaInfo = modelNode.metaInfo(); return metaInfo.isValid() && metaInfo.hasProperty("source") - && metaInfo.property("source").propertyTypeNameIsUrl(); + && metaInfo.property("source").propertyType().isUrl(); } } //namespace diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinecontrols.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinecontrols.cpp index f417d5dad06..e75bb192e4e 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinecontrols.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinecontrols.cpp @@ -40,11 +40,11 @@ namespace QmlDesigner { -TimelineControl *createTimelineControl(const TypeName &name) +TimelineControl *createTimelineControl(const NodeMetaInfo &metaInfo) { - if (name == "real" || name == "double" || name == "float") + if (metaInfo.isFloat()) return new FloatControl; - if (name == "QColor" || name == "color") + if (metaInfo.isColor()) return new ColorControl; return nullptr; diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinecontrols.h b/src/plugins/qmldesigner/components/timelineeditor/timelinecontrols.h index 4c30357be9e..7ee0660a550 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinecontrols.h +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinecontrols.h @@ -51,7 +51,7 @@ public: virtual void setSize(int width, int height) = 0; }; -TimelineControl *createTimelineControl(const TypeName &name); +TimelineControl *createTimelineControl(const NodeMetaInfo &metaInfo); class FloatControl : public QDoubleSpinBox, public TimelineControl { diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.cpp index 62c94f386f8..bce17583bf1 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.cpp @@ -235,11 +235,11 @@ TimelinePropertyItem *TimelinePropertyItem::create(const QmlTimelineKeyframeGrou if (!objectNode.isValid()) return item; - auto nameOfType = objectNode.modelNode() - .metaInfo() - .property(item->m_frames.propertyName()) - .propertyTypeName(); - item->m_control = createTimelineControl(nameOfType); + auto propertyType = objectNode.modelNode() + .metaInfo() + .property(item->m_frames.propertyName()) + .propertyType(); + item->m_control = createTimelineControl(propertyType); if (item->m_control) { item->m_control->setSize((TimelineConstants::sectionWidth / 2.6) - 10, item->size().height() - 2 + 1); diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorview.cpp b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorview.cpp index 30bb635eafb..46467ff5ef9 100644 --- a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorview.cpp +++ b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorview.cpp @@ -218,8 +218,6 @@ ModelNode TransitionEditorView::addNewTransition() QHash idPropertyList; - const QVector validProperties = {"int", "real", "double", "qreal", "color", "QColor", "float"}; - for (const QmlModelState &state : qAsConst(states)) { for (const QmlPropertyChanges & change : state.propertyChanges()) { QStringList locList; @@ -227,11 +225,9 @@ ModelNode TransitionEditorView::addNewTransition() if (target.isValid() && target.hasMetaInfo()) { const QString targetId = target.id(); for (const VariantProperty &property : change.modelNode().variantProperties()) { - TypeName typeName = target.metaInfo().property(property.name()).propertyTypeName(); - if (typeName.startsWith(".")) - typeName.remove(0, 6); + auto type = target.metaInfo().property(property.name()).propertyType(); - if (validProperties.contains(typeName)) + if (type.isInteger() || type.isColor() || type.isFloat()) locList.append(QString::fromUtf8(property.name())); } if (idPropertyList.contains(targetId)) { @@ -303,6 +299,8 @@ ModelNode TransitionEditorView::addNewTransition() }); } else { QString properties; + const QVector validProperties = { + "int", "real", "double", "qreal", "color", "QColor", "float"}; for (const PropertyName &property : validProperties) properties.append(QString::fromUtf8(property) + ", "); if (!properties.isEmpty()) diff --git a/src/plugins/qmldesigner/designercore/include/model.h b/src/plugins/qmldesigner/designercore/include/model.h index f6a82a96226..fe7c58a7c08 100644 --- a/src/plugins/qmldesigner/designercore/include/model.h +++ b/src/plugins/qmldesigner/designercore/include/model.h @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -40,10 +41,6 @@ class QPixmap; class QUrl; QT_END_NAMESPACE -namespace Sqlite { -class Database; -} - namespace QmlDesigner { namespace Internal { @@ -64,8 +61,6 @@ class AbstractProperty; class RewriterView; class NodeInstanceView; class TextModifier; -template -class ProjectStorage; using PropertyListType = QList >; @@ -106,8 +101,8 @@ public: const MetaInfo metaInfo() const; MetaInfo metaInfo(); - NodeMetaInfo metaInfo(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1); - bool hasNodeMetaInfo(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1); + NodeMetaInfo metaInfo(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1) const; + bool hasNodeMetaInfo(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1) const; void setMetaInfo(const MetaInfo &metaInfo); void attachView(AbstractView *view); @@ -134,7 +129,7 @@ public: NodeInstanceView *nodeInstanceView() const; void setNodeInstanceView(NodeInstanceView *nodeInstanceView); - Model *metaInfoProxyModel(); + Model *metaInfoProxyModel() const; TextModifier *textModifier() const; void setTextModifier(TextModifier *textModifier); @@ -154,6 +149,8 @@ public: void startDrag(QMimeData *mimeData, const QPixmap &icon); void endDrag(); + NotNullPointer> projectStorage() const; + private: std::unique_ptr d; }; diff --git a/src/plugins/qmldesigner/designercore/include/nodemetainfo.h b/src/plugins/qmldesigner/designercore/include/nodemetainfo.h index 695f7dbfe6e..d9ac20ded5f 100644 --- a/src/plugins/qmldesigner/designercore/include/nodemetainfo.h +++ b/src/plugins/qmldesigner/designercore/include/nodemetainfo.h @@ -29,6 +29,12 @@ #include "propertymetainfo.h" #include "qmldesignercorelib_global.h" +#include +#include +#include + +#include + #include #include #include @@ -48,17 +54,20 @@ class AbstractProperty; class QMLDESIGNERCORE_EXPORT NodeMetaInfo { public: - NodeMetaInfo(); - NodeMetaInfo(Model *model, const TypeName &type, int maj, int min); - + NodeMetaInfo() = default; + NodeMetaInfo(Model *model, const TypeName &typeName, int majorVersion, int minorVersion); + NodeMetaInfo(TypeId typeId, NotNullPointer> projectStorage) + : m_typeId{typeId} + , m_projectStorage{projectStorage} + {} + NodeMetaInfo(NotNullPointer> projectStorage) + : m_projectStorage{projectStorage} + {} ~NodeMetaInfo(); - NodeMetaInfo(const NodeMetaInfo &other); - NodeMetaInfo &operator=(const NodeMetaInfo &other); - bool isValid() const; bool isFileComponent() const; - bool hasProperty(const PropertyName &propertyName) const; + bool hasProperty(Utils::SmallStringView propertyName) const; PropertyMetaInfos properties() const; PropertyMetaInfos localProperties() const; PropertyMetaInfo property(const PropertyName &propertyName) const; @@ -67,8 +76,8 @@ public: PropertyName defaultPropertyName() const; bool hasDefaultProperty() const; - QList classHierarchy() const; - QList superClasses() const; + std::vector classHierarchy() const; + std::vector superClasses() const; NodeMetaInfo directSuperClass() const; bool defaultPropertyIsComponent() const; @@ -82,16 +91,43 @@ public: bool availableInVersion(int majorVersion, int minorVersion) const; bool isSubclassOf(const TypeName &type, int majorVersion = -1, int minorVersion = -1) const; + bool isSubclassOf(const NodeMetaInfo &metaInfo) const; bool isGraphicalItem() const; bool isQmlItem() const; bool isLayoutable() const; bool isView() const; bool isTabView() const; + bool isAlias() const; + bool isQmlComponent() const; + bool isFont() const; + bool isColor() const; + bool isBool() const; + bool isInteger() const; + bool isFloat() const; + bool isVariant() const; + bool isString() const; + bool isUrl() const; + bool isQtQuick3DTexture() const; + bool isEnumeration() const; QString importDirectoryPath() const; + friend bool operator==(const NodeMetaInfo &first, const NodeMetaInfo &second) + { + if constexpr (useProjectStorage()) + return first.m_typeId == second.m_typeId; + else + return first.m_privateData == second.m_privateData; + } + private: + const Storage::Info::Type &typeData() const; + +private: + TypeId m_typeId; + NotNullPointer> m_projectStorage = {}; + mutable Utils::optional m_typeData; QSharedPointer m_privateData; }; diff --git a/src/plugins/qmldesigner/designercore/include/projectstorageids.h b/src/plugins/qmldesigner/designercore/include/projectstorageids.h index b81f13f9c12..e735d916d0c 100644 --- a/src/plugins/qmldesigner/designercore/include/projectstorageids.h +++ b/src/plugins/qmldesigner/designercore/include/projectstorageids.h @@ -25,7 +25,7 @@ #pragma once -#include +#include namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/designercore/include/propertymetainfo.h b/src/plugins/qmldesigner/designercore/include/propertymetainfo.h index 6463157a9e6..c3ccb0c384d 100644 --- a/src/plugins/qmldesigner/designercore/include/propertymetainfo.h +++ b/src/plugins/qmldesigner/designercore/include/propertymetainfo.h @@ -27,6 +27,12 @@ #include +#include +#include +#include + +#include + #include #include @@ -34,45 +40,39 @@ namespace QmlDesigner { +class NodeMetaInfo; + class QMLDESIGNERCORE_EXPORT PropertyMetaInfo { public: PropertyMetaInfo(QSharedPointer nodeMetaInfoPrivateData, const PropertyName &propertyName); + PropertyMetaInfo(PropertyDeclarationId id, + NotNullPointer> projectStorage) + : m_id{id} + , m_projectStorage{projectStorage} + {} ~PropertyMetaInfo(); - const TypeName &propertyTypeName() const; - class NodeMetaInfo propertyNodeMetaInfo() const; - + PropertyName name() const; + NodeMetaInfo propertyType() const; bool isWritable() const; bool isListProperty() const; bool isEnumType() const; bool isPrivate() const; bool isPointer() const; QVariant castedValue(const QVariant &value) const; - const PropertyName &name() const & { return m_propertyName; } - template - bool hasPropertyTypeName(const TypeName &...typeName) const - { - auto propertyTypeName_ = propertyTypeName(); - return ((propertyTypeName_ == typeName) || ...); - } - - template - bool hasPropertyTypeName(const std::tuple &typeNames) const - { - return std::apply([&](auto... typeName) { return hasPropertyTypeName(typeName...); }, - typeNames); - } - - bool propertyTypeNameIsColor() const { return hasPropertyTypeName("QColor", "color"); } - bool propertyTypeNameIsString() const { return hasPropertyTypeName("QString", "string"); } - bool propertyTypeNameIsUrl() const { return hasPropertyTypeName("QUrl", "url"); } +private: + const Storage::Info::PropertyDeclaration &propertyData() const; + TypeName propertyTypeName() const; private: QSharedPointer m_nodeMetaInfoPrivateData; PropertyName m_propertyName; + PropertyDeclarationId m_id; + NotNullPointer> m_projectStorage; + mutable Utils::optional m_propertyData; }; using PropertyMetaInfos = std::vector; diff --git a/src/plugins/qmldesigner/designercore/include/qmldesignercorelib_global.h b/src/plugins/qmldesigner/designercore/include/qmldesignercorelib_global.h index 9f1c743d472..4d008889b05 100644 --- a/src/plugins/qmldesigner/designercore/include/qmldesignercorelib_global.h +++ b/src/plugins/qmldesigner/designercore/include/qmldesignercorelib_global.h @@ -67,4 +67,12 @@ enum AnchorLineType { AnchorLineAllMask = AnchorLineVerticalMask | AnchorLineHorizontalMask }; +constexpr bool useProjectStorage() +{ +#ifdef QDS_USE_PROJECTSTORAGE + return true; +#else + return false; +#endif +} } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/qmltimelinekeyframegroup.h b/src/plugins/qmldesigner/designercore/include/qmltimelinekeyframegroup.h index 6aee5ea0d58..7bcb0179578 100644 --- a/src/plugins/qmldesigner/designercore/include/qmltimelinekeyframegroup.h +++ b/src/plugins/qmldesigner/designercore/include/qmltimelinekeyframegroup.h @@ -54,7 +54,7 @@ public: void setValue(const QVariant &value, qreal frame); QVariant value(qreal frame) const; - TypeName valueType() const; + NodeMetaInfo valueType() const; qreal currentFrame() const; diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index 8d53d410b09..160528c9ab2 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -29,8 +29,9 @@ #include "metainfo.h" #include -#include +#include #include +#include #include #include @@ -315,7 +316,7 @@ public: m_context->viewerContext(), *m_context->snapshot().importDependencies()).toUtf8(); m_properties.append({propertyName, qualifiedTypeName}); } else { - TypeId typeId; + QmlJS::TypeId typeId; TypeName typeName = typeId(value).toUtf8(); if (typeName == "Function") @@ -1394,120 +1395,166 @@ void NodeMetaInfoPrivate::initialiseProperties() m_slots = getSlots(m_objectValue, context()); } -NodeMetaInfo::NodeMetaInfo() - : m_privateData(QSharedPointer::create()) -{ - -} - NodeMetaInfo::NodeMetaInfo(Model *model, const TypeName &type, int maj, int min) : m_privateData(NodeMetaInfoPrivate::create(model, type, maj, min)) { - } NodeMetaInfo::~NodeMetaInfo() = default; -NodeMetaInfo::NodeMetaInfo(const NodeMetaInfo &other) = default; - -NodeMetaInfo &NodeMetaInfo::operator=(const NodeMetaInfo &other) -{ - if (this != &other) - this->m_privateData = other.m_privateData; - - return *this; -} - bool NodeMetaInfo::isValid() const { - return m_privateData->isValid(); + if constexpr (useProjectStorage()) + return bool(m_typeId); + else + return m_privateData && m_privateData->isValid(); } bool NodeMetaInfo::isFileComponent() const { - return m_privateData->isFileComponent(); + if constexpr (useProjectStorage()) + return bool(typeData().traits & Storage::TypeTraits::IsFileComponent); + else + return m_privateData->isFileComponent(); } -bool NodeMetaInfo::hasProperty(const PropertyName &propertyName) const +bool NodeMetaInfo::hasProperty(Utils::SmallStringView propertyName) const { - return m_privateData->properties().contains(propertyName); + if constexpr (useProjectStorage()) + return bool(m_projectStorage->propertyDeclarationId(m_typeId, propertyName)); + else + return m_privateData->properties().contains(propertyName); } PropertyMetaInfos NodeMetaInfo::properties() const { - const auto &properties = m_privateData->properties(); + if constexpr (useProjectStorage()) { + return Utils::transform( + m_projectStorage->propertyDeclarationIds(m_typeId), [&](auto id) { + return PropertyMetaInfo{id, m_projectStorage}; + }); - PropertyMetaInfos propertyMetaInfos; - propertyMetaInfos.reserve(static_cast(properties.size())); + } else { + const auto &properties = m_privateData->properties(); - for (const auto &name : properties) - propertyMetaInfos.emplace_back(m_privateData, name); + PropertyMetaInfos propertyMetaInfos; + propertyMetaInfos.reserve(static_cast(properties.size())); - return propertyMetaInfos; + for (const auto &name : properties) + propertyMetaInfos.emplace_back(m_privateData, name); + + return propertyMetaInfos; + } } PropertyMetaInfos NodeMetaInfo::localProperties() const { - const auto &properties = m_privateData->localProperties(); + if constexpr (useProjectStorage()) { + return Utils::transform( + m_projectStorage->localPropertyDeclarationIds(m_typeId), [&](auto id) { + return PropertyMetaInfo{id, m_projectStorage}; + }); + } else { + const auto &properties = m_privateData->localProperties(); - PropertyMetaInfos propertyMetaInfos; - propertyMetaInfos.reserve(static_cast(properties.size())); + PropertyMetaInfos propertyMetaInfos; + propertyMetaInfos.reserve(static_cast(properties.size())); - for (const auto &name : properties) - propertyMetaInfos.emplace_back(m_privateData, name); + for (const auto &name : properties) + propertyMetaInfos.emplace_back(m_privateData, name); - return propertyMetaInfos; + return propertyMetaInfos; + } } PropertyMetaInfo NodeMetaInfo::property(const PropertyName &propertyName) const { - return PropertyMetaInfo{m_privateData, propertyName}; + if constexpr (useProjectStorage()) { + return {m_projectStorage->propertyDeclarationId(m_typeId, propertyName), m_projectStorage}; + } else { + return PropertyMetaInfo{m_privateData, propertyName}; + } } PropertyNameList NodeMetaInfo::signalNames() const { - return m_privateData->signalNames(); + if constexpr (useProjectStorage()) { + return Utils::transform(m_projectStorage->signalDeclarationNames(m_typeId), + [&](const auto &name) { + return name.toQByteArray(); + }); + } else { + return m_privateData->signalNames(); + } } PropertyNameList NodeMetaInfo::slotNames() const { - return m_privateData->slotNames(); + if constexpr (useProjectStorage()) { + return Utils::transform(m_projectStorage->functionDeclarationNames(m_typeId), + [&](const auto &name) { + return name.toQByteArray(); + }); + } else { + return m_privateData->slotNames(); + } } PropertyName NodeMetaInfo::defaultPropertyName() const { - return m_privateData->defaultPropertyName(); + if constexpr (useProjectStorage()) { + if (auto name = m_projectStorage->propertyName(typeData().defaultPropertyId)) + return name->toQByteArray(); + return {}; + } else { + return m_privateData->defaultPropertyName(); + } } - bool NodeMetaInfo::hasDefaultProperty() const { - return !defaultPropertyName().isEmpty(); + if constexpr (useProjectStorage()) + return bool(typeData().defaultPropertyId); + else + return !defaultPropertyName().isEmpty(); } -QList NodeMetaInfo::classHierarchy() const +NodeMetaInfos NodeMetaInfo::classHierarchy() const { - QList hierarchy = {*this}; - hierarchy.append(superClasses()); + NodeMetaInfos hierarchy = {*this}; + Model *model = m_privateData->model(); + for (const TypeDescription &type : m_privateData->prototypes()) + hierarchy.emplace_back(model, type.className.toUtf8(), type.majorVersion, type.minorVersion); + return hierarchy; } -QList NodeMetaInfo::superClasses() const +NodeMetaInfos NodeMetaInfo::superClasses() const { + NodeMetaInfos hierarchy; Model *model = m_privateData->model(); - return Utils::transform(m_privateData->prototypes(), [model](const TypeDescription &type) { - return NodeMetaInfo(model, type.className.toUtf8(), type.majorVersion, type.minorVersion); - }); + for (const TypeDescription &type : m_privateData->prototypes()) + hierarchy.emplace_back(model, type.className.toUtf8(), type.majorVersion, type.minorVersion); + + return hierarchy; } -NodeMetaInfo NodeMetaInfo::directSuperClass() const +NodeMetaInfo NodeMetaInfo::directSuperClass() const // actually this can be too because their arre extensions { - return superClasses().value(1, NodeMetaInfo()); + const auto &protoTypes = m_privateData->prototypes(); + Model *model = m_privateData->model(); + + if (protoTypes.empty()) + return NodeMetaInfo{m_projectStorage}; + + const auto &type = m_privateData->prototypes().front(); + + return NodeMetaInfo{model, type.className.toUtf8(), type.majorVersion, type.minorVersion}; } bool NodeMetaInfo::defaultPropertyIsComponent() const { if (hasDefaultProperty()) - return property(defaultPropertyName()).hasPropertyTypeName("Component"); + return property(defaultPropertyName()).propertyType().isQmlComponent(); return false; } @@ -1542,13 +1589,24 @@ QString NodeMetaInfo::importDirectoryPath() const return m_privateData->importDirectoryPath(); } +#ifdef QDS_USE_PROJECTSTORAGE +const Storage::Info::Type &NodeMetaInfo::typeData() const +{ + if (!m_typeData) + m_typeData = m_projectStorage->type(m_typeId); + + return *m_typeData; +} +#endif + bool NodeMetaInfo::availableInVersion(int majorVersion, int minorVersion) const { if (majorVersion == -1 && minorVersion == -1) return true; return (m_privateData->majorVersion() >= majorVersion) - || (majorVersion == m_privateData->majorVersion() && m_privateData->minorVersion() >= minorVersion); + || (majorVersion == m_privateData->majorVersion() + && m_privateData->minorVersion() >= minorVersion); } bool NodeMetaInfo::isSubclassOf(const TypeName &type, int majorVersion, int minorVersion) const @@ -1572,10 +1630,10 @@ bool NodeMetaInfo::isSubclassOf(const TypeName &type, int majorVersion, int mino stringIdentifier(type, majorVersion, minorVersion))) return false; //take a shortcut - optimization - const QList superClassList = superClasses(); + const NodeMetaInfos superClassList = superClasses(); for (const NodeMetaInfo &superClass : superClassList) { if (superClass.m_privateData->cleverCheckType(type) - && superClass.availableInVersion(majorVersion, minorVersion)) { + && superClass.availableInVersion(majorVersion, minorVersion)) { m_privateData->prototypeCachePositives().insert( stringIdentifier(type, majorVersion, minorVersion)); return true; @@ -1585,18 +1643,20 @@ bool NodeMetaInfo::isSubclassOf(const TypeName &type, int majorVersion, int mino return false; } +bool NodeMetaInfo::isSubclassOf(const NodeMetaInfo &metaInfo) const +{ + return isSubclassOf(metaInfo.typeName(), metaInfo.majorVersion(), metaInfo.minorVersion()); +} + bool NodeMetaInfo::isGraphicalItem() const { - return isSubclassOf("QtQuick.Item") - || isSubclassOf("QtQuick.Window.Window") - || isSubclassOf("QtQuick.Dialogs.Dialog") - || isSubclassOf("QtQuick.Controls.Popup"); + return isSubclassOf("QtQuick.Item") || isSubclassOf("QtQuick.Window.Window") + || isSubclassOf("QtQuick.Dialogs.Dialog") || isSubclassOf("QtQuick.Controls.Popup"); } bool NodeMetaInfo::isQmlItem() const { - return isSubclassOf("QtQuick.QtObject") - || isSubclassOf("QtQml.QtObject"); + return isSubclassOf("QtQuick.QtObject") || isSubclassOf("QtQml.QtObject"); } bool NodeMetaInfo::isLayoutable() const @@ -1604,17 +1664,15 @@ bool NodeMetaInfo::isLayoutable() const if (isSubclassOf(".QDeclarativeBasePositioner")) return true; //QtQuick 1 - return isSubclassOf("QtQuick.Positioner") - || isSubclassOf("QtQuick.Layouts.Layout") - || isSubclassOf("QtQuick.Controls.SplitView"); + return isSubclassOf("QtQuick.Positioner") || isSubclassOf("QtQuick.Layouts.Layout") + || isSubclassOf("QtQuick.Controls.SplitView"); } bool NodeMetaInfo::isView() const { - return isValid() && - (isSubclassOf("QtQuick.ListView") || - isSubclassOf("QtQuick.GridView") || - isSubclassOf("QtQuick.PathView")); + return isValid() + && (isSubclassOf("QtQuick.ListView") || isSubclassOf("QtQuick.GridView") + || isSubclassOf("QtQuick.PathView")); } bool NodeMetaInfo::isTabView() const @@ -1622,48 +1680,171 @@ bool NodeMetaInfo::isTabView() const return isSubclassOf("QtQuick.Controls.TabView"); } +bool NodeMetaInfo::isAlias() const +{ + return m_privateData && m_privateData->qualfiedTypeName() == "alias"; +} + +bool NodeMetaInfo::isQmlComponent() const +{ + auto type = m_privateData->qualfiedTypeName(); + + return type == "Component" || type == "Qt.Component" || type == "QtQuick.Component" + || type == "QtQml.Component" || type == ".QQmlComponent" || type == "QQmlComponent"; +} + +bool NodeMetaInfo::isFont() const +{ + return m_privateData && m_privateData->qualfiedTypeName() == "font"; +} + +bool NodeMetaInfo::isColor() const +{ + if (!m_privateData) + return false; + + auto type = m_privateData->qualfiedTypeName(); + + return type == "QColor" || type == "color"; +} + +bool NodeMetaInfo::isBool() const +{ + if (!m_privateData) + return false; + + auto type = m_privateData->qualfiedTypeName(); + + return type == "bool" || type == "boolean"; +} + +bool NodeMetaInfo::isInteger() const +{ + if (!m_privateData) + return false; + + auto type = m_privateData->qualfiedTypeName(); + + return type == "int" || type == "integer"; +} + +bool NodeMetaInfo::isFloat() const +{ + if (!m_privateData) + return false; + + auto type = m_privateData->qualfiedTypeName(); + + return type == "qreal" || type == "double" || type == "float"; + ; +} + +bool NodeMetaInfo::isVariant() const +{ + return m_privateData && m_privateData->qualfiedTypeName() == "QVariant"; +} + +bool NodeMetaInfo::isString() const +{ + if (!m_privateData) + return false; + + auto type = m_privateData->qualfiedTypeName(); + + return type == "string" || type == "QString"; +} + +bool NodeMetaInfo::isUrl() const +{ + if (!m_privateData) + return false; + + auto type = m_privateData->qualfiedTypeName(); + + return type == "url" || type == "QUrl"; +} + +bool NodeMetaInfo::isQtQuick3DTexture() const +{ + return m_privateData && m_privateData->qualfiedTypeName() == "QtQuick3D.Texture"; +} + +bool NodeMetaInfo::isEnumeration() const +{ + if constexpr (useProjectStorage()) + return bool(typeData().traits & Storage::TypeTraits::IsEnum); + + return false; +} + PropertyMetaInfo::PropertyMetaInfo(QSharedPointer nodeMetaInfoPrivateData, const PropertyName &propertyName) : m_nodeMetaInfoPrivateData{nodeMetaInfoPrivateData} , m_propertyName{propertyName} + , m_projectStorage{nullptr} {} -PropertyMetaInfo::~PropertyMetaInfo() {} +PropertyMetaInfo::~PropertyMetaInfo() = default; -const TypeName &PropertyMetaInfo::propertyTypeName() const +NodeMetaInfo PropertyMetaInfo::propertyType() const { - return m_nodeMetaInfoPrivateData->propertyType(m_propertyName); + if constexpr (useProjectStorage()) { + return {propertyData().typeId, m_projectStorage}; + } else { + return NodeMetaInfo{m_nodeMetaInfoPrivateData->model(), + m_nodeMetaInfoPrivateData->propertyType(m_propertyName), + -1, + -1}; + } } -NodeMetaInfo PropertyMetaInfo::propertyNodeMetaInfo() const +PropertyName PropertyMetaInfo::name() const { - return m_nodeMetaInfoPrivateData->model()->metaInfo(propertyTypeName()); + if constexpr (useProjectStorage()) + return PropertyName(Utils::SmallStringView(propertyData().name)); + else + return m_propertyName; } bool PropertyMetaInfo::isWritable() const { - return m_nodeMetaInfoPrivateData->isPropertyWritable(m_propertyName); + if constexpr (useProjectStorage()) + return !(propertyData().traits & Storage::PropertyDeclarationTraits::IsReadOnly); + else + return m_nodeMetaInfoPrivateData->isPropertyWritable(m_propertyName); } bool PropertyMetaInfo::isListProperty() const { - return m_nodeMetaInfoPrivateData->isPropertyList(m_propertyName); + if constexpr (useProjectStorage()) + return propertyData().traits & Storage::PropertyDeclarationTraits::IsList; + else + return m_nodeMetaInfoPrivateData->isPropertyList(m_propertyName); } bool PropertyMetaInfo::isEnumType() const { - return m_nodeMetaInfoPrivateData->isPropertyEnum(m_propertyName); + if constexpr (useProjectStorage()) + return propertyType().isEnumeration(); + else + return m_nodeMetaInfoPrivateData->isPropertyEnum(m_propertyName); } bool PropertyMetaInfo::isPrivate() const { - return m_propertyName.startsWith("__"); + if constexpr (useProjectStorage()) + return propertyData().name.startsWith("__"); + else + return m_propertyName.startsWith("__"); } bool PropertyMetaInfo::isPointer() const { - return m_nodeMetaInfoPrivateData->isPropertyPointer(m_propertyName); + if constexpr (useProjectStorage()) + return propertyData().traits & Storage::PropertyDeclarationTraits::IsPointer; + else + return m_nodeMetaInfoPrivateData->isPropertyPointer(m_propertyName); } QVariant PropertyMetaInfo::castedValue(const QVariant &value) const @@ -1708,4 +1889,17 @@ QVariant PropertyMetaInfo::castedValue(const QVariant &value) const return Internal::PropertyParser::variantFromString(variant.toString()); } +const Storage::Info::PropertyDeclaration &PropertyMetaInfo::propertyData() const +{ + if (!m_propertyData) + m_propertyData = m_projectStorage->propertyDeclaration(m_id); + + return *m_propertyData; +} + +TypeName PropertyMetaInfo::propertyTypeName() const +{ + return propertyType().typeName(); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index f55f2580860..6cdb8e937f6 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -998,7 +998,7 @@ static int getMajorVersionFromNode(const ModelNode &modelNode) static int getMinorVersionFromNode(const ModelNode &modelNode) { if (modelNode.metaInfo().isValid()) { - const QList infos = modelNode.metaInfo().classHierarchy(); + const NodeMetaInfos infos = modelNode.metaInfo().classHierarchy(); for (const NodeMetaInfo &info : infos) { if (info.typeName() == "QtQuick.QtObject" || info.typeName() == "QtQuick.Item") return info.minorVersion(); diff --git a/src/plugins/qmldesigner/designercore/model/internalnode_p.h b/src/plugins/qmldesigner/designercore/model/internalnode_p.h index 19f039c406f..1a87068d0dd 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnode_p.h +++ b/src/plugins/qmldesigner/designercore/model/internalnode_p.h @@ -34,8 +34,9 @@ #include "internalvariantproperty.h" #include - #include +#include +#include #include #include @@ -149,6 +150,9 @@ public: int nodeSourceType = 0; QString behaviorPropertyName; QStringList scriptFunctions; + ModuleId moduleId; // is invalid if type is implicit + Utils::SmallString documentTypeName; // how the type is written in den Document + TypeId typeId; private: AuxiliaryDatas m_auxiliaryDatas; diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index d01ba0d82b0..1ed1ebf198a 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -30,11 +30,7 @@ #include "model_p.h" #include -#include -#include -#include -#include #include "abstractview.h" #include "internalnodeabstractproperty.h" @@ -57,6 +53,8 @@ #include "textmodifier.h" #include "variantproperty.h" +#include + #ifndef QMLDESIGNER_TEST #include #include @@ -68,6 +66,9 @@ #include #include +#include +#include +#include #include /*! @@ -95,8 +96,8 @@ ModelPrivate::ModelPrivate(Model *model, int major, int minor, Model *metaInfoProxyModel) - : m_model{model} - , m_projectStorage{&projectStorage} + : projectStorage{&projectStorage} + , m_model{model} { m_metaInfoProxyModel = metaInfoProxyModel; @@ -1578,6 +1579,11 @@ void Model::endDrag() d->notifyDragEnded(); } +NotNullPointer> Model::projectStorage() const +{ + return d->projectStorage; +} + QString Model::generateNewId(const QString &prefixName) const { return generateNewId(prefixName, QStringLiteral("element")); @@ -1666,12 +1672,12 @@ void Model::setNodeInstanceView(NodeInstanceView *nodeInstanceView) \brief Returns the model that is used for metainfo \return Returns itself if other metaInfoProxyModel does not exist */ -Model *Model::metaInfoProxyModel() +Model *Model::metaInfoProxyModel() const { if (d->m_metaInfoProxyModel) return d->m_metaInfoProxyModel->metaInfoProxyModel(); - return this; + return const_cast(this); } TextModifier *Model::textModifier() const @@ -1740,7 +1746,7 @@ const MetaInfo Model::metaInfo() const return d->metaInfo(); } -bool Model::hasNodeMetaInfo(const TypeName &typeName, int majorVersion, int minorVersion) +bool Model::hasNodeMetaInfo(const TypeName &typeName, int majorVersion, int minorVersion) const { return metaInfo(typeName, majorVersion, minorVersion).isValid(); } @@ -1750,9 +1756,33 @@ void Model::setMetaInfo(const MetaInfo &metaInfo) d->setMetaInfo(metaInfo); } -NodeMetaInfo Model::metaInfo(const TypeName &typeName, int majorVersion, int minorVersion) +namespace { +[[maybe_unused]] std::pair moduleTypeName( + const TypeName &typeName) { - return NodeMetaInfo(metaInfoProxyModel(), typeName, majorVersion, minorVersion); + auto foundDot = std::find(typeName.begin(), typeName.end(), '.'); + + if (foundDot == typeName.end()) + return {"", typeName}; + + return {{typeName.begin(), foundDot}, {std::next(foundDot), typeName.end()}}; +} +} // namespace + +NodeMetaInfo Model::metaInfo(const TypeName &typeName, int majorVersion, int minorVersion) const +{ + if constexpr (useProjectStorage()) { + auto [module, componentName] = moduleTypeName(typeName); + + ModuleId moduleId = d->projectStorage->moduleId(module); + TypeId typeId = d->projectStorage->typeId(moduleId, + componentName, + Storage::Synchronization::Version{majorVersion, + minorVersion}); + return NodeMetaInfo(typeId, d->projectStorage); + } else { + return NodeMetaInfo(metaInfoProxyModel(), typeName, majorVersion, minorVersion); + } } /*! diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/designercore/model/model_p.h index af980a99a68..122c65c1c3f 100644 --- a/src/plugins/qmldesigner/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/designercore/model/model_p.h @@ -268,6 +268,9 @@ public: void updateEnabledViews(); +public: + NotNullPointer> projectStorage = nullptr; + private: void removePropertyWithoutNotification(const InternalPropertyPointer &property); void removeAllSubNodes(const InternalNodePointer &node); @@ -298,7 +301,6 @@ private: QPointer m_textModifier; QPointer m_metaInfoProxyModel; QHash> m_nodeMetaInfoCache; - ProjectStorage *m_projectStorage = nullptr; bool m_writeLock = false; qint32 m_internalIdCounter = 1; }; diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/designercore/model/modelnode.cpp index 9e1ab497eb3..c7d2ce66542 100644 --- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelnode.cpp @@ -870,7 +870,17 @@ NodeMetaInfo ModelNode::metaInfo() const throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); } - return NodeMetaInfo(model()->metaInfoProxyModel(), type(), majorVersion(), minorVersion()); + if (!m_internalNode->typeId) + throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__); + + if constexpr (useProjectStorage()) { + return NodeMetaInfo(m_internalNode->typeId, m_model->projectStorage()); + } else { + return NodeMetaInfo(m_model->metaInfoProxyModel(), + m_internalNode->typeName, + m_internalNode->majorVersion, + m_internalNode->minorVersion); + } } bool ModelNode::hasMetaInfo() const @@ -948,20 +958,23 @@ bool ModelNode::hasNodeAbstractProperty(const PropertyName &name) const bool ModelNode::hasDefaultNodeAbstractProperty() const { - return hasProperty(metaInfo().defaultPropertyName()) - && m_internalNode->property(metaInfo().defaultPropertyName())->isNodeAbstractProperty(); + auto defaultPropertyName = metaInfo().defaultPropertyName(); + return hasProperty(defaultPropertyName) + && m_internalNode->property(defaultPropertyName)->isNodeAbstractProperty(); } bool ModelNode::hasDefaultNodeListProperty() const { - return hasProperty(metaInfo().defaultPropertyName()) - && m_internalNode->property(metaInfo().defaultPropertyName())->isNodeListProperty(); + auto defaultPropertyName = metaInfo().defaultPropertyName(); + return hasProperty(defaultPropertyName) + && m_internalNode->property(defaultPropertyName)->isNodeListProperty(); } bool ModelNode::hasDefaultNodeProperty() const { - return hasProperty(metaInfo().defaultPropertyName()) - && m_internalNode->property(metaInfo().defaultPropertyName())->isNodeProperty(); + auto defaultPropertyName = metaInfo().defaultPropertyName(); + return hasProperty(defaultPropertyName) + && m_internalNode->property(defaultPropertyName)->isNodeProperty(); } bool ModelNode::hasNodeProperty(const PropertyName &name) const diff --git a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp index c5736eec7b7..53040400842 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp @@ -252,7 +252,7 @@ QVariant QmlObjectNode::modelValue(const PropertyName &name) const bool QmlObjectNode::isTranslatableText(const PropertyName &name) const { if (modelNode().metaInfo().isValid() && modelNode().metaInfo().hasProperty(name) - && modelNode().metaInfo().property(name).propertyTypeNameIsString()) { + && modelNode().metaInfo().property(name).propertyType().isString()) { if (modelNode().hasBindingProperty(name)) { static QRegularExpression regularExpressionPattern( QLatin1String("^qsTr(|Id|anslate)\\(\".*\"\\)$")); diff --git a/src/plugins/qmldesigner/designercore/model/qmltimelinekeyframegroup.cpp b/src/plugins/qmldesigner/designercore/model/qmltimelinekeyframegroup.cpp index eca0013ec49..7e08415582a 100644 --- a/src/plugins/qmldesigner/designercore/model/qmltimelinekeyframegroup.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmltimelinekeyframegroup.cpp @@ -206,21 +206,16 @@ QVariant QmlTimelineKeyframeGroup::value(qreal frame) const return QVariant(); } -TypeName QmlTimelineKeyframeGroup::valueType() const +NodeMetaInfo QmlTimelineKeyframeGroup::valueType() const { QTC_ASSERT(isValid(), return {}); const ModelNode targetNode = target(); - TypeName typeName; - if (targetNode.isValid() && targetNode.hasMetaInfo()) - typeName = targetNode.metaInfo().property(propertyName()).propertyTypeName(); + return targetNode.metaInfo().property(propertyName()).propertyType(); - if (typeName.startsWith(".")) - typeName.remove(0, 6); - - return typeName; + return {}; } bool QmlTimelineKeyframeGroup::hasKeyframe(qreal frame) diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 012697f52ac..c77ff95064c 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -339,8 +339,7 @@ bool propertyIsComponentType(const QmlDesigner::NodeAbstractProperty &property, return false; //If the type is already a subclass of Component keep it return property.parentModelNode().isValid() - && isComponentType( - property.parentModelNode().metaInfo().property(property.name()).propertyTypeName()); + && property.parentModelNode().metaInfo().property(property.name()).propertyType().isQmlComponent(); } QString extractComponentFromQml(const QString &source) diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h index 21a0e7e8839..f0d9a3b6a96 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h @@ -184,7 +184,7 @@ public: propertyDeclarationId); } - Utils::optional type(TypeId typeId) + Utils::optional type(TypeId typeId) const { return selectInfoTypeByTypeIdStatement.template optionalValueWithTransaction( typeId); diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragefwd.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragefwd.h new file mode 100644 index 00000000000..07ccd636f3d --- /dev/null +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragefwd.h @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +namespace Sqlite { +class Database; +}; + +namespace QmlDesigner { +template +class ProjectStorage; + +template +using NotNullPointer = Type *; +} diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinfotypes.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinfotypes.h new file mode 100644 index 00000000000..f9b8dfd8a50 --- /dev/null +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinfotypes.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "projectstorageids.h" + +#include + +#include +#include +#include + +namespace QmlDesigner { + +template +constexpr std::underlying_type_t to_underlying(Enumeration enumeration) noexcept +{ + static_assert(std::is_enum_v, "to_underlying expect an enumeration"); + return static_cast>(enumeration); +} + +} // namespace QmlDesigner + +namespace QmlDesigner::Storage { +enum class PropertyDeclarationTraits : int { + None = 0, + IsReadOnly = 1 << 0, + IsPointer = 1 << 1, + IsList = 1 << 2 +}; +constexpr PropertyDeclarationTraits operator|(PropertyDeclarationTraits first, + PropertyDeclarationTraits second) +{ + return static_cast(static_cast(first) | static_cast(second)); +} + +constexpr bool operator&(PropertyDeclarationTraits first, PropertyDeclarationTraits second) +{ + return static_cast(first) & static_cast(second); +} + +enum class TypeTraits : int { + None, + Reference, + Value, + Sequence, + IsEnum = 1 << 8, + IsFileComponent = 1 << 9 +}; + +constexpr TypeTraits operator|(TypeTraits first, TypeTraits second) +{ + return static_cast(static_cast(first) | static_cast(second)); +} + +constexpr TypeTraits operator&(TypeTraits first, TypeTraits second) +{ + return static_cast(static_cast(first) & static_cast(second)); +} + +using TypeNameString = Utils::BasicSmallString<63>; + +} // namespace QmlDesigner::Storage + +namespace QmlDesigner::Storage::Info { + +class PropertyDeclaration +{ +public: + PropertyDeclaration(TypeId typeId, + Utils::SmallStringView name, + PropertyDeclarationTraits traits, + TypeId propertyTypeId) + : typeId{typeId} + , name{name} + , traits{traits} + , propertyTypeId{propertyTypeId} + {} + + TypeId typeId; + Utils::SmallString name; + PropertyDeclarationTraits traits; + TypeId propertyTypeId; +}; + +class Type +{ +public: + Type(PropertyDeclarationId defaultPropertyId, TypeTraits traits) + : defaultPropertyId{defaultPropertyId} + , traits{traits} + {} + + PropertyDeclarationId defaultPropertyId; + TypeTraits traits; +}; + +} // namespace QmlDesigner::Storage::Info diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h index c4781d41ad6..18066cfafd3 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h @@ -27,6 +27,7 @@ #include "filestatus.h" #include "projectstorageids.h" +#include "projectstorageinfotypes.h" #include @@ -34,54 +35,6 @@ #include #include -namespace QmlDesigner { - -template -constexpr std::underlying_type_t to_underlying(Enumeration enumeration) noexcept -{ - static_assert(std::is_enum_v, "to_underlying expect an enumeration"); - return static_cast>(enumeration); -} - - -} // namespace QmlDesigner - -namespace QmlDesigner::Storage { -enum class PropertyDeclarationTraits : int { - None = 0, - IsReadOnly = 1 << 0, - IsPointer = 1 << 1, - IsList = 1 << 2 -}; -constexpr PropertyDeclarationTraits operator|(PropertyDeclarationTraits first, - PropertyDeclarationTraits second) -{ - return static_cast(static_cast(first) | static_cast(second)); -} - -constexpr bool operator&(PropertyDeclarationTraits first, PropertyDeclarationTraits second) -{ - return static_cast(first) & static_cast(second); -} - -enum class TypeTraits : int { - None, - Reference, - Value, - Sequence, - IsEnum = 1 << 8, - IsFileComponent = 1 << 9 -}; - -constexpr TypeTraits operator|(TypeTraits first, TypeTraits second) -{ - return static_cast(static_cast(first) | static_cast(second)); -} - -using TypeNameString = Utils::BasicSmallString<63>; - -} // namespace QmlDesigner::Storage - namespace QmlDesigner::Storage::Synchronization { enum class TypeNameKind { Exported = 1, QualifiedExported = 2 }; @@ -912,37 +865,3 @@ public: } // namespace QmlDesigner::Storage::Synchronization -namespace QmlDesigner::Storage::Info { - -class PropertyDeclaration -{ -public: - PropertyDeclaration(TypeId typeId, - Utils::SmallStringView name, - PropertyDeclarationTraits traits, - TypeId propertyTypeId) - : typeId{typeId} - , name{name} - , traits{traits} - , propertyTypeId{propertyTypeId} - {} - - TypeId typeId; - Utils::SmallString name; - PropertyDeclarationTraits traits; - TypeId propertyTypeId; -}; - -class Type -{ -public: - Type(PropertyDeclarationId defaultPropertyId, TypeTraits traits) - : defaultPropertyId{defaultPropertyId} - , traits{traits} - {} - - PropertyDeclarationId defaultPropertyId; - TypeTraits traits; -}; - -} // namespace QmlDesigner::Storage::Info diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h index 785ab669bd4..416674fc9cb 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h @@ -28,15 +28,10 @@ #include "nonlockingmutex.h" #include "qmldocumentparserinterface.h" -namespace Sqlite { -class Database; -} +#include namespace QmlDesigner { -template -class ProjectStorage; - template class SourcePathCache; diff --git a/src/plugins/qmldesigner/qmldesignerprojectmanager.h b/src/plugins/qmldesigner/qmldesignerprojectmanager.h index adb5217e2fe..3204ecf10ac 100644 --- a/src/plugins/qmldesigner/qmldesignerprojectmanager.h +++ b/src/plugins/qmldesigner/qmldesignerprojectmanager.h @@ -25,6 +25,8 @@ #pragma once +#include + #include #include @@ -42,15 +44,8 @@ class Project; class Target; } // namespace ProjectExplorer -namespace Sqlite { -class Database; -} - namespace QmlDesigner { -template -class ProjectStorage; - class QmlDesignerProjectManager : public QObject { Q_OBJECT diff --git a/tests/auto/qml/qmldesigner/CMakeLists.txt b/tests/auto/qml/qmldesigner/CMakeLists.txt index 5792c8bd261..2e501ed3e97 100644 --- a/tests/auto/qml/qmldesigner/CMakeLists.txt +++ b/tests/auto/qml/qmldesigner/CMakeLists.txt @@ -1,4 +1,4 @@ if (${Qt5_VERSION} VERSION_GREATER_EQUAL "6.2.0") - add_subdirectory(coretests) +# add_subdirectory(coretests) add_subdirectory(wizard) endif() diff --git a/tests/auto/qml/qmldesigner/coretests/CMakeLists.txt b/tests/auto/qml/qmldesigner/coretests/CMakeLists.txt index 572570915c8..5ce2cffa82a 100644 --- a/tests/auto/qml/qmldesigner/coretests/CMakeLists.txt +++ b/tests/auto/qml/qmldesigner/coretests/CMakeLists.txt @@ -1,6 +1,7 @@ add_qtc_test(tst_qml_testcore EXCLUDE_FROM_PRECHECK CONDITION TARGET QmlProjectManager AND Qt5_VERSION VERSION_GREATER_EQUAL 6.2.0 + DEPENDS Sqlite DEFINES QT_CREATOR QMLDESIGNER_TEST diff --git a/tests/unit/mockup/qmldesigner/designercore/include/nodemetainfo.h b/tests/unit/mockup/qmldesigner/designercore/include/nodemetainfo.h index 095e634672b..5d4a4b22740 100644 --- a/tests/unit/mockup/qmldesigner/designercore/include/nodemetainfo.h +++ b/tests/unit/mockup/qmldesigner/designercore/include/nodemetainfo.h @@ -27,6 +27,9 @@ #include "propertymetainfo.h" +#include +#include + #include #include #include @@ -49,6 +52,8 @@ class NodeMetaInfo public: NodeMetaInfo() {} NodeMetaInfo(Model *, const TypeName &, int, int) {} + NodeMetaInfo(TypeId, NotNullPointer>) {} + NodeMetaInfo(NotNullPointer>) {} bool isValid() const { return {}; } bool isFileComponent() const { return {}; } @@ -62,8 +67,8 @@ public: PropertyName defaultPropertyName() const { return "data"; } bool hasDefaultProperty() const { return {}; } - QList classHierarchy() const { return {}; } - QList superClasses() const { return {}; } + std::vector classHierarchy() const { return {}; } + std::vector superClasses() const { return {}; } NodeMetaInfo directSuperClass() const { return {}; } bool defaultPropertyIsComponent() const { return {}; } @@ -91,4 +96,6 @@ public: static void clearCache() {} }; +using NodeMetaInfos = std::vector; + } // namespace QmlDesigner diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp index 2c6046740a1..ca1bf5fc245 100644 --- a/tests/unit/unittest/gtest-creator-printing.cpp +++ b/tests/unit/unittest/gtest-creator-printing.cpp @@ -562,14 +562,9 @@ const char *typeTraitsToString(TypeTraits traits) return ""; } -bool operator&(TypeTraits first, TypeTraits second) -{ - return static_cast(first) & static_cast(second); -} - const char *typeTraitsFlagsToString(TypeTraits traits) { - if (traits & TypeTraits::IsEnum) + if (bool(traits & TypeTraits::IsEnum)) return "(IsEnum)"; return "";