QmlDesigner: More test for NodeMetaInfo

Task-number: QDS-10055
Change-Id: I23a9d7ea87dff9f3e07f5beeb734cea7d01d2e94
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Marco Bubke
2023-07-05 14:04:26 +02:00
parent 8ab4968278
commit 98cff9e097
39 changed files with 2340 additions and 261 deletions

View File

@@ -19,8 +19,6 @@ public:
constexpr explicit BasicId() = default;
constexpr BasicId(const char *) = delete;
static constexpr BasicId create(InternalIntegerType idNumber)
{
BasicId id;

View File

@@ -4,12 +4,13 @@
#include "componentexporter.h"
#include "exportnotification.h"
#include "designdocument.h"
#include "nodemetainfo.h"
#include "qmldesignerplugin.h"
#include "rewriterview.h"
#include "qmlitemnode.h"
#include "qmlobjectnode.h"
#include <designdocument.h>
#include <model/modelutils.h>
#include <nodemetainfo.h>
#include <qmldesignerplugin.h>
#include <qmlitemnode.h>
#include <qmlobjectnode.h>
#include <rewriterview.h>
#include <coreplugin/editormanager/editormanager.h>
#include <projectexplorer/project.h>
@@ -340,12 +341,11 @@ QString AssetExporter::componentUuid(const ModelNode &instance) const
// Returns the UUID of the component's root node
// Empty string is returned if the node is not an instance of a component within
// the project.
NodeMetaInfo metaInfo = instance.metaInfo();
if (!metaInfo.isValid())
return {};
const QString path = metaInfo.componentFileName();
if (m_componentUuidCache.contains(path))
return m_componentUuidCache[path];
if (instance) {
const QString path = ModelUtils::componentFilePath(instance);
return m_componentUuidCache.value(path);
}
return {};
}

View File

@@ -28,7 +28,7 @@ static QByteArrayList populateLineage(const QmlDesigner::ModelNode &node)
if (!node.isValid() || node.type().isEmpty())
return {};
for (auto &info : node.metaInfo().superClasses())
for (auto &info : node.metaInfo().prototypes())
lineage.append(info.typeName());
return lineage;

View File

@@ -3,13 +3,14 @@
#include "modelnodecontextmenu_helper.h"
#include <nodemetainfo.h>
#include <modelnode.h>
#include <qmlitemnode.h>
#include <bindingproperty.h>
#include <model/modelutils.h>
#include <modelnode.h>
#include <nodemetainfo.h>
#include <nodeproperty.h>
#include <qmldesignerplugin.h>
#include <qmldesignerconstants.h>
#include <qmldesignerplugin.h>
#include <qmlitemnode.h>
#include <QFile>
@@ -76,10 +77,11 @@ bool selectionHasSameParent(const SelectionContext &selectionState)
bool fileComponentExists(const ModelNode &modelNode)
{
if (!modelNode.metaInfo().isFileComponent())
if (!modelNode.metaInfo().isFileComponent()) {
return true;
}
const QString fileName = modelNode.metaInfo().componentFileName();
const QString fileName = ModelUtils::componentFilePath(modelNode);
if (fileName.contains("qml/QtQuick"))
return false;
@@ -97,7 +99,8 @@ bool selectionIsImported3DAsset(const SelectionContext &selectionState)
{
ModelNode node = selectionState.currentSingleSelectedNode();
if (selectionState.view() && node.hasMetaInfo()) {
QString fileName = node.metaInfo().componentFileName(); // absolute path
QString fileName = ModelUtils::componentFilePath(node);
if (fileName.isEmpty()) {
// Node is not a file component, so we have to check if the current doc itself is
fileName = node.model()->fileUrl().toLocalFile();

View File

@@ -205,7 +205,7 @@ void ContentLibraryBundleImporter::handleImportTimer()
for (const QString &pendingType : pendingTypes) {
NodeMetaInfo metaInfo = model->metaInfo(pendingType.toUtf8());
const bool isImport = m_pendingTypes[pendingType];
const bool typeComplete = metaInfo.isValid() && !metaInfo.superClasses().empty();
const bool typeComplete = metaInfo.isValid() && !metaInfo.prototypes().empty();
if (isImport == typeComplete) {
m_pendingTypes.remove(pendingType);
if (isImport)

View File

@@ -7,6 +7,7 @@
#include <qmldesignerplugin.h>
#include <bindingproperty.h>
#include <model/modelutils.h>
#include <nodeabstractproperty.h>
#include <nodelistproperty.h>
#include <nodemetainfo.h>
@@ -93,9 +94,9 @@ void DebugView::nodeCreated(const ModelNode &createdNode)
message << createdNode.majorVersion() << "." << createdNode.minorVersion();
message << createdNode.nodeSource();
message << "MetaInfo " << createdNode.metaInfo().isValid() << " ";
if (createdNode.metaInfo().isValid()) {
message << createdNode.metaInfo().majorVersion() << "." << createdNode.metaInfo().minorVersion();
message << createdNode.metaInfo().componentFileName();
if (auto metaInfo = createdNode.metaInfo()) {
message << metaInfo.majorVersion() << "." << metaInfo.minorVersion();
message << ModelUtils::componentFilePath(createdNode);
}
log("::nodeCreated:", message.readAll());
}
@@ -282,9 +283,10 @@ void DebugView::selectedNodesChanged(const QList<ModelNode> &selectedNodes /*sel
message << lineBreak;
if (selectedNode.metaInfo().isValid()) {
for (const NodeMetaInfo &metaInfo : selectedNode.metaInfo().classHierarchy())
for (const NodeMetaInfo &metaInfo : selectedNode.metaInfo().selfAndPrototypes()) {
message << metaInfo.typeName() << " " << metaInfo.majorVersion() << "."
<< metaInfo.minorVersion() << lineBreak;
}
message << lineBreak;
message << selectedNode.metaInfo().typeName();

View File

@@ -3,19 +3,20 @@
#include "bakelights.h"
#include "abstractview.h"
#include "auxiliarydataproperties.h"
#include "bakelightsdatamodel.h"
#include "bakelightsconnectionmanager.h"
#include "bindingproperty.h"
#include "documentmanager.h"
#include "modelnode.h"
#include "nodeabstractproperty.h"
#include "nodeinstanceview.h"
#include "nodemetainfo.h"
#include "plaintexteditmodifier.h"
#include "rewriterview.h"
#include "variantproperty.h"
#include <abstractview.h>
#include <auxiliarydataproperties.h>
#include <bakelightsconnectionmanager.h>
#include <bakelightsdatamodel.h>
#include <bindingproperty.h>
#include <documentmanager.h>
#include <model/modelutils.h>
#include <modelnode.h>
#include <nodeabstractproperty.h>
#include <nodeinstanceview.h>
#include <nodemetainfo.h>
#include <plaintexteditmodifier.h>
#include <rewriterview.h>
#include <variantproperty.h>
#include <coreplugin/icore.h>
@@ -240,18 +241,21 @@ void BakeLights::rebake()
void BakeLights::exposeModelsAndLights(const QString &nodeId)
{
ModelNode compNode = m_view->modelNodeForId(nodeId);
if (!compNode.isValid() || !compNode.isComponent()
|| compNode.metaInfo().componentFileName().isEmpty()) {
if (!compNode.isValid() || !compNode.isComponent()) {
return;
}
auto componentFilePath = ModelUtils::componentFilePath(compNode);
if (componentFilePath.isEmpty()) {
return;
}
RewriterView rewriter{m_view->externalDependencies(), RewriterView::Amend};
ModelPointer compModel = QmlDesigner::Model::create("QtQuick/Item", 2, 1);
const QString compFile = compNode.metaInfo().componentFileName();
const Utils::FilePath compFilePath = Utils::FilePath::fromString(compFile);
const Utils::FilePath compFilePath = Utils::FilePath::fromString(componentFilePath);
QByteArray src = compFilePath.fileContents().value();
compModel->setFileUrl(QUrl::fromLocalFile(compFile));
compModel->setFileUrl(QUrl::fromLocalFile(componentFilePath));
auto textDocument = std::make_unique<QTextDocument>(QString::fromUtf8(src));
auto modifier = std::make_unique<IndentingTextEditModifier>(
@@ -295,12 +299,12 @@ void BakeLights::exposeModelsAndLights(const QString &nodeId)
QString newText = modifier->text();
if (newText != originalText) {
QSaveFile saveFile(compFile);
QSaveFile saveFile(componentFilePath);
if (saveFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
saveFile.write(newText.toUtf8());
saveFile.commit();
} else {
qWarning() << __FUNCTION__ << "Failed to save changes to:" << compFile;
qWarning() << __FUNCTION__ << "Failed to save changes to:" << componentFilePath;
}
}

View File

@@ -4,14 +4,15 @@
#include "itemlibraryassetimportdialog.h"
#include "ui_itemlibraryassetimportdialog.h"
#include "qmldesignerplugin.h"
#include "qmldesignerconstants.h"
#include "model.h"
#include "nodemetainfo.h"
#include "variantproperty.h"
#include <model.h>
#include <model/modelutils.h>
#include <nodemetainfo.h>
#include <qmldesignerconstants.h>
#include <qmldesignerplugin.h>
#include <variantproperty.h>
#include "utils/outputformatter.h"
#include "theme.h"
#include <theme.h>
#include <utils/outputformatter.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectmanager.h>
@@ -283,7 +284,7 @@ void ItemLibraryAssetImportDialog::updateImport(const ModelNode &updateNode,
QString errorMsg;
const ModelNode &node = updateNode;
if (node.hasMetaInfo()) {
QString compFileName = node.metaInfo().componentFileName(); // absolute path
QString compFileName = ModelUtils::componentFilePath(node); // absolute path
bool preselectNodeSource = false;
if (compFileName.isEmpty()) {
// Node is not a file component, so we have to check if the current doc itself is

View File

@@ -548,7 +548,7 @@ void MaterialEditorView::setupQmlBackend()
TypeName diffClassName;
if (NodeMetaInfo metaInfo = m_selectedMaterial.metaInfo()) {
diffClassName = metaInfo.typeName();
for (const NodeMetaInfo &metaInfo : metaInfo.classHierarchy()) {
for (const NodeMetaInfo &metaInfo : metaInfo.selfAndPrototypes()) {
if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsUrl))
break;
qmlSpecificsUrl = PropertyEditorQmlBackend::getQmlFileUrl(metaInfo.typeName()

View File

@@ -90,7 +90,7 @@ ChooseFromPropertyListFilter::ChooseFromPropertyListFilter(const NodeMetaInfo &i
} else if (insertInfo.isQtQuick3DParticles3DParticle3D()) {
if (parentInfo.isQtQuick3DParticles3DParticleEmitter3D())
propertyList.append("particle");
} else if (insertInfo.isQtQuick3DParticleAbstractShape()) {
} else if (insertInfo.isQtQuick3DParticlesAbstractShape()) {
if (parentInfo.isQtQuick3DParticles3DParticleEmitter3D()
|| parentInfo.isQtQuick3DParticles3DAttractor3D())
propertyList.append("shape");

View File

@@ -2,28 +2,29 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "navigatorview.h"
#include "iconcheckboxitemdelegate.h"
#include "nameitemdelegate.h"
#include "navigatortreemodel.h"
#include "navigatorwidget.h"
#include "qmldesignerconstants.h"
#include "qmldesignericons.h"
#include "qmldesignerplugin.h"
#include "assetslibrarywidget.h"
#include "commontypecache.h"
#include "nameitemdelegate.h"
#include "iconcheckboxitemdelegate.h"
#include <assetslibrarywidget.h>
#include <bindingproperty.h>
#include <designmodecontext.h>
#include <commontypecache.h>
#include <designersettings.h>
#include <designmodecontext.h>
#include <itemlibraryinfo.h>
#include <nodeproperty.h>
#include <model/modelutils.h>
#include <nodeinstanceview.h>
#include <nodelistproperty.h>
#include <variantproperty.h>
#include <nodeproperty.h>
#include <qmldesignerconstants.h>
#include <qmldesignericons.h>
#include <qmldesignerplugin.h>
#include <qmlitemnode.h>
#include <rewritingexception.h>
#include <nodeinstanceview.h>
#include <theme.h>
#include <variantproperty.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h>
@@ -450,7 +451,7 @@ void NavigatorView::changeToComponent(const QModelIndex &index)
const ModelNode doubleClickNode = modelNodeForIndex(index);
if (doubleClickNode.metaInfo().isFileComponent())
Core::EditorManager::openEditor(Utils::FilePath::fromString(
doubleClickNode.metaInfo().componentFileName()),
ModelUtils::componentFilePath(doubleClickNode)),
Utils::Id(),
Core::EditorManager::DoNotMakeVisible);
}
@@ -468,7 +469,7 @@ QAbstractItemModel *NavigatorView::currentModel() const
const ProjectExplorer::FileNode *NavigatorView::fileNodeForModelNode(const ModelNode &node) const
{
QString filename = node.metaInfo().componentFileName();
QString filename = ModelUtils::componentFilePath(node);
Utils::FilePath filePath = Utils::FilePath::fromString(filename);
ProjectExplorer::Project *currentProject = ProjectExplorer::ProjectManager::projectForFile(
filePath);

View File

@@ -958,7 +958,7 @@ void PropertyEditorQmlBackend::setValueforAuxiliaryProperties(const QmlObjectNod
QUrl PropertyEditorQmlBackend::getQmlUrlForMetaInfo(const NodeMetaInfo &metaInfo, TypeName &className)
{
if (metaInfo.isValid()) {
const NodeMetaInfos hierarchy = metaInfo.classHierarchy();
const NodeMetaInfos hierarchy = metaInfo.selfAndPrototypes();
for (const NodeMetaInfo &info : hierarchy) {
QUrl fileUrl = fileToUrl(locateQmlFile(info, QString::fromUtf8(qmlFileName(info))));
if (fileUrl.isValid()) {

View File

@@ -450,7 +450,7 @@ void PropertyEditorView::setupQmlBackend()
TypeName diffClassName;
if (commonAncestor.isValid()) {
diffClassName = commonAncestor.typeName();
const NodeMetaInfos hierarchy = commonAncestor.classHierarchy();
const NodeMetaInfos hierarchy = commonAncestor.selfAndPrototypes();
for (const NodeMetaInfo &metaInfo : hierarchy) {
if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsFile))
break;

View File

@@ -416,7 +416,7 @@ void TextureEditorView::setupQmlBackend()
TypeName diffClassName;
if (NodeMetaInfo metaInfo = m_selectedTexture.metaInfo()) {
diffClassName = metaInfo.typeName();
for (const NodeMetaInfo &metaInfo : metaInfo.classHierarchy()) {
for (const NodeMetaInfo &metaInfo : metaInfo.selfAndPrototypes()) {
if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsUrl))
break;
qmlSpecificsUrl = PropertyEditorQmlBackend::getQmlFileUrl(metaInfo.typeName()

View File

@@ -128,6 +128,7 @@ public:
NodeMetaInfo fontMetaInfo() const;
NodeMetaInfo qmlQtObjectMetaInfo() const;
NodeMetaInfo qtQmlModelsListModelMetaInfo() const;
NodeMetaInfo qtQmlModelsListElementMetaInfo() const;
NodeMetaInfo qtQuick3DBakedLightmapMetaInfo() const;
NodeMetaInfo qtQuick3DDefaultMaterialMetaInfo() const;
NodeMetaInfo qtQuick3DMaterialMetaInfo() const;
@@ -214,6 +215,8 @@ public:
void endDrag();
NotNullPointer<const ProjectStorageType> projectStorage() const;
const PathCacheType &pathCache() const;
PathCacheType &pathCache();
private:
template<const auto &moduleName, const auto &typeName>

View File

@@ -65,8 +65,8 @@ public:
PropertyMetaInfo defaultProperty() const;
bool hasDefaultProperty() const;
std::vector<NodeMetaInfo> classHierarchy() const;
std::vector<NodeMetaInfo> superClasses() const;
std::vector<NodeMetaInfo> selfAndPrototypes() const;
std::vector<NodeMetaInfo> prototypes() const;
NodeMetaInfo commonBase(const NodeMetaInfo &metaInfo) const;
bool defaultPropertyIsComponent() const;
@@ -76,6 +76,7 @@ public:
int majorVersion() const;
int minorVersion() const;
SourceId sourceId() const;
QString componentFileName() const;
bool isBasedOn(const NodeMetaInfo &metaInfo) const;
@@ -126,7 +127,6 @@ public:
bool isQmlComponent() const;
bool isQtMultimediaSoundEffect() const;
bool isQtObject() const;
bool isQtQuick3D() const;
bool isQtQuick3DBakedLightmap() const;
bool isQtQuick3DBuffer() const;
bool isQtQuick3DCamera() const;
@@ -139,7 +139,7 @@ public:
bool isQtQuick3DMaterial() const;
bool isQtQuick3DModel() const;
bool isQtQuick3DNode() const;
bool isQtQuick3DParticleAbstractShape() const;
bool isQtQuick3DParticlesAbstractShape() const;
bool isQtQuick3DParticles3DAffector3D() const;
bool isQtQuick3DParticles3DAttractor3D() const;
bool isQtQuick3DParticles3DParticle3D() const;

View File

@@ -3,66 +3,67 @@
#include "nodeinstanceview.h"
#include "abstractproperty.h"
#include "bindingproperty.h"
#include "captureddatacommand.h"
#include "changeauxiliarycommand.h"
#include "changebindingscommand.h"
#include "changefileurlcommand.h"
#include "changeidscommand.h"
#include "changelanguagecommand.h"
#include "changenodesourcecommand.h"
#include "changepreviewimagesizecommand.h"
#include "changeselectioncommand.h"
#include "changestatecommand.h"
#include "changevaluescommand.h"
#include "childrenchangedcommand.h"
#include "clearscenecommand.h"
#include "completecomponentcommand.h"
#include "componentcompletedcommand.h"
#include "connectionmanagerinterface.h"
#include "createinstancescommand.h"
#include "createscenecommand.h"
#include "debugoutputcommand.h"
#include "informationchangedcommand.h"
#include "imageutils.h"
#include "inputeventcommand.h"
#include "nodeabstractproperty.h"
#include "nodeinstanceserverproxy.h"
#include "nodelistproperty.h"
#include "pixmapchangedcommand.h"
#include "puppettocreatorcommand.h"
#include "qml3dnode.h"
#include "qmlchangeset.h"
#include "qmldesignerconstants.h"
#include "qmlstate.h"
#include "qmltimeline.h"
#include "qmltimelinekeyframegroup.h"
#include "qmlvisualnode.h"
#include "removeinstancescommand.h"
#include "removepropertiescommand.h"
#include "removesharedmemorycommand.h"
#include "reparentinstancescommand.h"
#include "scenecreatedcommand.h"
#include "statepreviewimagechangedcommand.h"
#include "tokencommand.h"
#include "update3dviewstatecommand.h"
#include "valueschangedcommand.h"
#include "variantproperty.h"
#include "view3dactioncommand.h"
#include "requestmodelnodepreviewimagecommand.h"
#include "nanotracecommand.h"
#include "nanotrace/nanotrace.h"
#include <abstractproperty.h>
#include <bindingproperty.h>
#include <captureddatacommand.h>
#include <changeauxiliarycommand.h>
#include <changebindingscommand.h>
#include <changefileurlcommand.h>
#include <changeidscommand.h>
#include <changelanguagecommand.h>
#include <changenodesourcecommand.h>
#include <changepreviewimagesizecommand.h>
#include <changeselectioncommand.h>
#include <changestatecommand.h>
#include <changevaluescommand.h>
#include <childrenchangedcommand.h>
#include <clearscenecommand.h>
#include <completecomponentcommand.h>
#include <componentcompletedcommand.h>
#include <connectionmanagerinterface.h>
#include <createinstancescommand.h>
#include <createscenecommand.h>
#include <debugoutputcommand.h>
#include <imageutils.h>
#include <informationchangedcommand.h>
#include <inputeventcommand.h>
#include <nanotrace/nanotrace.h>
#include <nanotracecommand.h>
#include <nodeabstractproperty.h>
#include <nodeinstanceserverproxy.h>
#include <nodelistproperty.h>
#include <pixmapchangedcommand.h>
#include <puppettocreatorcommand.h>
#include <qml3dnode.h>
#include <qmlchangeset.h>
#include <qmldesignerconstants.h>
#include <qmlstate.h>
#include <qmltimeline.h>
#include <qmltimelinekeyframegroup.h>
#include <qmlvisualnode.h>
#include <removeinstancescommand.h>
#include <removepropertiescommand.h>
#include <removesharedmemorycommand.h>
#include <reparentinstancescommand.h>
#include <requestmodelnodepreviewimagecommand.h>
#include <scenecreatedcommand.h>
#include <statepreviewimagechangedcommand.h>
#include <tokencommand.h>
#include <update3dviewstatecommand.h>
#include <valueschangedcommand.h>
#include <variantproperty.h>
#include <view3dactioncommand.h>
#include <auxiliarydataproperties.h>
#include <designersettings.h>
#include <externaldependenciesinterface.h>
#include <metainfo.h>
#include <model.h>
#include <model/modelutils.h>
#include <modelnode.h>
#include <nodehints.h>
#include <rewriterview.h>
#include <qmlitemnode.h>
#include <rewriterview.h>
#include <utils/hdrimage.h>
@@ -1077,18 +1078,20 @@ CreateSceneCommand NodeInstanceView::createCreateSceneCommand()
if (parentTakesOverRendering(instance.modelNode()))
nodeFlags |= InstanceContainer::ParentTakesOverRendering;
const auto modelNode = instance.modelNode();
InstanceContainer container(instance.instanceId(),
instance.modelNode().type(),
instance.modelNode().majorVersion(),
instance.modelNode().minorVersion(),
instance.modelNode().metaInfo().componentFileName(),
instance.modelNode().nodeSource(),
modelNode.type(),
modelNode.majorVersion(),
modelNode.minorVersion(),
ModelUtils::componentFilePath(modelNode),
modelNode.nodeSource(),
nodeSourceType,
nodeMetaType,
nodeFlags);
if (!parentIsBehavior(instance.modelNode()))
if (!parentIsBehavior(modelNode)) {
instanceContainerList.append(container);
}
}
QVector<ReparentContainer> reparentContainerList;
@@ -1243,12 +1246,13 @@ CreateInstancesCommand NodeInstanceView::createCreateInstancesCommand(const QLis
if (parentTakesOverRendering(instance.modelNode()))
nodeFlags |= InstanceContainer::ParentTakesOverRendering;
const auto modelNode = instance.modelNode();
InstanceContainer container(instance.instanceId(),
instance.modelNode().type(),
instance.modelNode().majorVersion(),
instance.modelNode().minorVersion(),
instance.modelNode().metaInfo().componentFileName(),
instance.modelNode().nodeSource(),
modelNode.type(),
modelNode.majorVersion(),
modelNode.minorVersion(),
ModelUtils::componentFilePath(modelNode),
modelNode.nodeSource(),
nodeSourceType,
nodeMetaType,
nodeFlags);
@@ -1783,9 +1787,9 @@ void NodeInstanceView::requestModelNodePreviewImage(const ModelNode &node,
if (renderInstance.isValid())
renderItemId = renderInstance.instanceId();
if (renderNode.isComponent())
componentPath = renderNode.metaInfo().componentFileName();
componentPath = ModelUtils::componentFilePath(renderNode);
} else if (node.isComponent()) {
componentPath = node.metaInfo().componentFileName();
componentPath = ModelUtils::componentFilePath(node);
}
const double ratio = m_externalDependencies.formEditorDevicePixelRatio();
const int dim = Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * ratio;

View File

@@ -80,7 +80,7 @@ QmlDesigner::NodeHints::NodeHints(const ModelNode &node) : m_modelNode(node)
if (!itemLibraryEntryList.isEmpty())
m_hints = itemLibraryEntryList.constFirst().hints();
} else { /* If we have meta information we run the complete type hierarchy and check for hints */
const auto classHierarchy = m_modelNode.metaInfo().classHierarchy();
const auto classHierarchy = m_modelNode.metaInfo().selfAndPrototypes();
for (const NodeMetaInfo &metaInfo : classHierarchy) {
QList <ItemLibraryEntry> itemLibraryEntryList = libraryInfo->entriesForType(
metaInfo.typeName(), metaInfo.majorVersion(), metaInfo.minorVersion());

View File

@@ -1591,26 +1591,25 @@ bool NodeMetaInfo::hasDefaultProperty() const
return !defaultPropertyName().isEmpty();
}
NodeMetaInfos NodeMetaInfo::classHierarchy() const
std::vector<NodeMetaInfo> NodeMetaInfo::selfAndPrototypes() const
{
if constexpr (useProjectStorage()) {
NodeMetaInfos hierarchy;
const auto typeIds = m_projectStorage->prototypeAndSelfIds(m_typeId);
hierarchy.reserve(typeIds.size());
for (TypeId typeId : typeIds)
hierarchy.emplace_back(typeId, m_projectStorage);
return hierarchy;
if (isValid()) {
return Utils::transform<NodeMetaInfos>(
m_projectStorage->prototypeAndSelfIds(m_typeId), [&](TypeId typeId) {
return NodeMetaInfo{typeId, m_projectStorage};
});
}
} else {
if (isValid()) {
NodeMetaInfos hierarchy = {*this};
Model *model = m_privateData->model();
for (const TypeDescription &type : m_privateData->prototypes())
for (const TypeDescription &type : m_privateData->prototypes()) {
hierarchy.emplace_back(model,
type.className.toUtf8(),
type.majorVersion,
type.minorVersion);
}
return hierarchy;
}
@@ -1619,17 +1618,15 @@ NodeMetaInfos NodeMetaInfo::classHierarchy() const
return {};
}
NodeMetaInfos NodeMetaInfo::superClasses() const
NodeMetaInfos NodeMetaInfo::prototypes() const
{
if constexpr (useProjectStorage()) {
NodeMetaInfos hierarchy;
const auto typeIds = m_projectStorage->prototypeIds(m_typeId);
hierarchy.reserve(typeIds.size());
for (TypeId typeId : typeIds)
hierarchy.emplace_back(typeId, m_projectStorage);
return hierarchy;
if (isValid()) {
return Utils::transform<NodeMetaInfos>(
m_projectStorage->prototypeIds(m_typeId), [&](TypeId typeId) {
return NodeMetaInfo{typeId, m_projectStorage};
});
}
} else {
if (isValid()) {
NodeMetaInfos hierarchy;
@@ -1691,10 +1688,28 @@ int NodeMetaInfo::minorVersion() const
return -1;
}
SourceId NodeMetaInfo::sourceId() const
{
if constexpr (useProjectStorage()) {
if (isValid()) {
return typeData().sourceId;
}
}
return SourceId{};
}
QString NodeMetaInfo::componentFileName() const
{
if (isValid())
return m_privateData->componentFileName();
if constexpr (!useProjectStorage()) {
if (isValid()) {
return m_privateData->componentFileName();
}
} else {
if (isValid()) {
return m_privateData->componentFileName();
}
}
return {};
}
@@ -1736,7 +1751,7 @@ bool NodeMetaInfo::isSubclassOf(const TypeName &type, int majorVersion, int mino
stringIdentifier(type, majorVersion, minorVersion)))
return false; //take a shortcut - optimization
const NodeMetaInfos superClassList = superClasses();
const NodeMetaInfos superClassList = prototypes();
for (const NodeMetaInfo &superClass : superClassList) {
if (superClass.m_privateData->cleverCheckType(type)) {
m_privateData->prototypeCachePositives().insert(
@@ -1750,8 +1765,27 @@ bool NodeMetaInfo::isSubclassOf(const TypeName &type, int majorVersion, int mino
bool NodeMetaInfo::isSuitableForMouseAreaFill() const
{
return isSubclassOf("QtQuick.Item") && !isSubclassOf("QtQuick.MouseArea")
&& !isSubclassOf("QtQuick.Controls.Control") && !isSubclassOf("QtQuick.Templates.Control");
if constexpr (useProjectStorage()) {
if (!isValid()) {
return false;
}
using namespace Storage::Info;
auto itemId = m_projectStorage->commonTypeId<QtQuick, Item>();
auto mouseAreaId = m_projectStorage->commonTypeId<QtQuick, MouseArea>();
auto controlsControlId = m_projectStorage->commonTypeId<QtQuick_Controls, Control>();
auto templatesControlId = m_projectStorage->commonTypeId<QtQuick_Templates, Control>();
return m_projectStorage->isBasedOn(m_typeId,
itemId,
mouseAreaId,
controlsControlId,
templatesControlId);
} else {
return isSubclassOf("QtQuick.Item") && !isSubclassOf("QtQuick.MouseArea")
&& !isSubclassOf("QtQuick.Controls.Control")
&& !isSubclassOf("QtQuick.Templates.Control");
}
}
bool NodeMetaInfo::isBasedOn(const NodeMetaInfo &metaInfo) const
@@ -1944,6 +1978,10 @@ namespace {
template<const char *moduleName, const char *typeName>
bool isBasedOnCommonType(NotNullPointer<const ProjectStorageType> projectStorage, TypeId typeId)
{
if (!typeId) {
return false;
}
auto base = projectStorage->commonTypeId<moduleName, typeName>();
return projectStorage->isBasedOn(typeId, base);
@@ -1953,6 +1991,10 @@ bool isBasedOnCommonType(NotNullPointer<const ProjectStorageType> projectStorage
bool NodeMetaInfo::isGraphicalItem() const
{
if constexpr (useProjectStorage()) {
if (!isValid()) {
return false;
}
using namespace Storage::Info;
auto itemId = m_projectStorage->commonTypeId<QtQuick, Item>();
auto windowId = m_projectStorage->commonTypeId<QtQuick_Window, Window>();
@@ -1981,6 +2023,10 @@ bool NodeMetaInfo::isQtObject() const
bool NodeMetaInfo::isLayoutable() const
{
if constexpr (useProjectStorage()) {
if (!isValid()) {
return false;
}
using namespace Storage::Info;
auto positionerId = m_projectStorage->commonTypeId<QtQuick, Positioner>();
auto layoutId = m_projectStorage->commonTypeId<QtQuick_Layouts, Layout>();
@@ -2008,6 +2054,10 @@ bool NodeMetaInfo::isQtQuickLayoutsLayout() const
bool NodeMetaInfo::isView() const
{
if constexpr (useProjectStorage()) {
if (!isValid()) {
return false;
}
using namespace Storage::Info;
auto listViewId = m_projectStorage->commonTypeId<QtQuick, ListView>();
auto gridViewId = m_projectStorage->commonTypeId<QtQuick, GridView>();
@@ -2036,7 +2086,7 @@ bool NodeMetaInfo::isVector2D() const
{
if constexpr (useProjectStorage()) {
using namespace Storage::Info;
return isTypeId(m_typeId, m_projectStorage->commonTypeId<QtQuick, vector2d>());
return isValid() && isTypeId(m_typeId, m_projectStorage->commonTypeId<QtQuick, vector2d>());
} else {
if (!m_privateData)
return false;
@@ -2051,7 +2101,7 @@ bool NodeMetaInfo::isVector3D() const
{
if constexpr (useProjectStorage()) {
using namespace Storage::Info;
return isTypeId(m_typeId, m_projectStorage->commonTypeId<QtQuick, vector3d>());
return isValid() && isTypeId(m_typeId, m_projectStorage->commonTypeId<QtQuick, vector3d>());
} else {
if (!m_privateData)
return false;
@@ -2066,7 +2116,7 @@ bool NodeMetaInfo::isVector4D() const
{
if constexpr (useProjectStorage()) {
using namespace Storage::Info;
return isTypeId(m_typeId, m_projectStorage->commonTypeId<QtQuick, vector4d>());
return isValid() && isTypeId(m_typeId, m_projectStorage->commonTypeId<QtQuick, vector4d>());
} else {
if (!m_privateData)
return false;
@@ -2152,6 +2202,10 @@ bool NodeMetaInfo::isQtQuickTimelineKeyframeGroup() const
bool NodeMetaInfo::isListOrGridView() const
{
if constexpr (useProjectStorage()) {
if (!isValid()) {
return false;
}
using namespace Storage::Info;
auto listViewId = m_projectStorage->commonTypeId<QtQuick, ListView>();
auto gridViewId = m_projectStorage->commonTypeId<QtQuick, GridView>();
@@ -2195,7 +2249,11 @@ bool NodeMetaInfo::isQtQuickBorderImage() const
bool NodeMetaInfo::isAlias() const
{
return isValid() && m_privateData->qualfiedTypeName() == "alias";
if constexpr (useProjectStorage()) {
return false; // there is no type alias
} else {
return isValid() && m_privateData->qualfiedTypeName() == "alias";
}
}
bool NodeMetaInfo::isQtQuickPositioner() const
@@ -2340,7 +2398,7 @@ bool NodeMetaInfo::isQtQuick3DParticles3DAttractor3D() const
}
}
bool NodeMetaInfo::isQtQuick3DParticleAbstractShape() const
bool NodeMetaInfo::isQtQuick3DParticlesAbstractShape() const
{
if constexpr (useProjectStorage()) {
using namespace Storage::Info;
@@ -2455,6 +2513,10 @@ bool NodeMetaInfo::isQtMultimediaSoundEffect() const
bool NodeMetaInfo::isFlowViewItem() const
{
if constexpr (useProjectStorage()) {
if (!isValid()) {
return false;
}
using namespace Storage::Info;
auto flowItemId = m_projectStorage->commonTypeId<FlowView, FlowItem>();
auto flowWildcardId = m_projectStorage->commonTypeId<FlowView, FlowWildcard>();
@@ -2558,7 +2620,7 @@ bool NodeMetaInfo::isFont() const
{
if constexpr (useProjectStorage()) {
using namespace Storage::Info;
return isTypeId(m_typeId, m_projectStorage->commonTypeId<QtQuick, font>());
return isValid() && isTypeId(m_typeId, m_projectStorage->commonTypeId<QtQuick, font>());
} else {
return isValid() && m_privateData->qualfiedTypeName() == "font";
}
@@ -2568,7 +2630,7 @@ bool NodeMetaInfo::isColor() const
{
if constexpr (useProjectStorage()) {
using namespace Storage::Info;
return isTypeId(m_typeId, m_projectStorage->builtinTypeId<QColor>());
return isValid() && isTypeId(m_typeId, m_projectStorage->builtinTypeId<QColor>());
} else {
if (!isValid())
return false;
@@ -2583,14 +2645,18 @@ bool NodeMetaInfo::isEffectMaker() const
{
// We use arbitrary type name because at this time we don't have effect maker
// specific type
return typeName() == QString::fromUtf8(Storage::Info::EffectMaker);
if constexpr (useProjectStorage()) {
return false;
} else {
return typeName() == QString::fromUtf8(Storage::Info::EffectMaker);
}
}
bool NodeMetaInfo::isBool() const
{
if constexpr (useProjectStorage()) {
using namespace Storage::Info;
return isTypeId(m_typeId, m_projectStorage->builtinTypeId<bool>());
return isValid() && isTypeId(m_typeId, m_projectStorage->builtinTypeId<bool>());
} else {
if (!isValid())
return false;
@@ -2605,7 +2671,7 @@ bool NodeMetaInfo::isInteger() const
{
if constexpr (useProjectStorage()) {
using namespace Storage::Info;
return isTypeId(m_typeId, m_projectStorage->builtinTypeId<int>());
return isValid() && isTypeId(m_typeId, m_projectStorage->builtinTypeId<int>());
} else {
if (!isValid())
return false;
@@ -2619,6 +2685,10 @@ bool NodeMetaInfo::isInteger() const
bool NodeMetaInfo::isFloat() const
{
if constexpr (useProjectStorage()) {
if (!isValid()) {
return false;
}
using namespace Storage::Info;
auto floatId = m_projectStorage->builtinTypeId<float>();
auto doubleId = m_projectStorage->builtinTypeId<double>();
@@ -2638,7 +2708,7 @@ bool NodeMetaInfo::isVariant() const
{
if constexpr (useProjectStorage()) {
using namespace Storage::Info;
return isTypeId(m_typeId, m_projectStorage->builtinTypeId<QVariant>());
return isValid() && isTypeId(m_typeId, m_projectStorage->builtinTypeId<QVariant>());
} else {
return isValid() && simplifiedTypeName() == "QVariant";
}
@@ -2648,7 +2718,7 @@ bool NodeMetaInfo::isString() const
{
if constexpr (useProjectStorage()) {
using namespace Storage::Info;
return isTypeId(m_typeId, m_projectStorage->builtinTypeId<QString>());
return isValid() && isTypeId(m_typeId, m_projectStorage->builtinTypeId<QString>());
} else {
if (!isValid())
return false;
@@ -2663,7 +2733,7 @@ bool NodeMetaInfo::isUrl() const
{
if constexpr (useProjectStorage()) {
using namespace Storage::Info;
return isTypeId(m_typeId, m_projectStorage->builtinTypeId<QUrl>());
return isValid() && isTypeId(m_typeId, m_projectStorage->builtinTypeId<QUrl>());
} else {
if (!isValid())
return false;
@@ -2823,7 +2893,8 @@ bool NodeMetaInfo::isQtQuick3DCubeMapTexture() const
return isBasedOnCommonType<QtQuick3D, CubeMapTexture>(m_projectStorage, m_typeId);
} else {
return isValid()
&& (isSubclassOf("QtQuick3D.CubeMapTexture") || isSubclassOf("<cpp>.QQuick3DCubeMapTexture"));
&& (isSubclassOf("QtQuick3D.CubeMapTexture")
|| isSubclassOf("<cpp>.QQuick3DCubeMapTexture"));
}
}
@@ -2850,7 +2921,7 @@ bool NodeMetaInfo::isQtQuick3DEffect() const
bool NodeMetaInfo::isEnumeration() const
{
if constexpr (useProjectStorage())
return bool(typeData().traits & Storage::TypeTraits::IsEnum);
return isValid() && bool(typeData().traits & Storage::TypeTraits::IsEnum);
return false;
}
@@ -3064,9 +3135,26 @@ const PropertyName &PropertyMetaInfo::propertyName() const
NodeMetaInfo NodeMetaInfo::commonBase(const NodeMetaInfo &metaInfo) const
{
for (const NodeMetaInfo &info : metaInfo.superClasses()) {
if (isBasedOn(info))
return info;
if constexpr (useProjectStorage()) {
if (isValid() && metaInfo) {
const auto firstTypeIds = m_projectStorage->prototypeAndSelfIds(m_typeId);
const auto secondTypeIds = m_projectStorage->prototypeAndSelfIds(metaInfo.m_typeId);
auto found
= std::find_if(firstTypeIds.begin(), firstTypeIds.end(), [&](TypeId firstTypeId) {
return std::find(secondTypeIds.begin(), secondTypeIds.end(), firstTypeId)
!= secondTypeIds.end();
});
if (found != firstTypeIds.end()) {
return NodeMetaInfo{*found, m_projectStorage};
}
}
} else {
for (const NodeMetaInfo &info : metaInfo.selfAndPrototypes()) {
if (isBasedOn(info)) {
return info;
}
}
}
return {};

View File

@@ -927,10 +927,9 @@ static int getMajorVersionFromImport(const Model *model)
static int getMajorVersionFromNode(const ModelNode &modelNode)
{
if (modelNode.metaInfo().isValid()) {
for (const NodeMetaInfo &info : modelNode.metaInfo().classHierarchy()) {
if (info.typeName() == "QtQml.QtObject"
|| info.typeName() == "QtQuick.QtObject"
|| info.typeName() == "QtQuick.Item") {
for (const NodeMetaInfo &info : modelNode.metaInfo().selfAndPrototypes()) {
if (info.typeName() == "QtQml.QtObject" || info.typeName() == "QtQuick.QtObject"
|| info.typeName() == "QtQuick.Item") {
return info.majorVersion();
}
}
@@ -942,7 +941,7 @@ static int getMajorVersionFromNode(const ModelNode &modelNode)
static int getMinorVersionFromNode(const ModelNode &modelNode)
{
if (modelNode.metaInfo().isValid()) {
const NodeMetaInfos infos = modelNode.metaInfo().classHierarchy();
const NodeMetaInfos infos = modelNode.metaInfo().selfAndPrototypes();
for (const NodeMetaInfo &info : infos) {
if (info.typeName() == "QtQuick.QtObject" || info.typeName() == "QtQuick.Item")
return info.minorVersion();

View File

@@ -347,7 +347,7 @@ std::pair<Utils::SmallStringView, Utils::SmallStringView> decomposeTypePath(Util
QT_WARNING_POP
} // namespace
void ModelPrivate::setTypeId(InternalNode *node, Utils::SmallStringView typeName)
ImportedTypeNameId ModelPrivate::importedTypeNameId(Utils::SmallStringView typeName)
{
if constexpr (useProjectStorage()) {
auto [moduleName, shortTypeName] = decomposeTypePath(typeName);
@@ -361,15 +361,21 @@ void ModelPrivate::setTypeId(InternalNode *node, Utils::SmallStringView typeName
ModuleId moduleId = projectStorage->moduleId(Utils::PathString{found->url()});
ImportId importId = projectStorage->importId(
Storage::Import{moduleId, found->majorVersion(), found->minorVersion(), m_sourceId});
ImportedTypeNameId typeNameId = projectStorage->importedTypeNameId(importId,
shortTypeName);
node->typeId = projectStorage->typeId(typeNameId);
return;
return projectStorage->importedTypeNameId(importId, shortTypeName);
}
}
ImportedTypeNameId typeNameId = projectStorage->importedTypeNameId(m_sourceId, shortTypeName);
node->typeId = projectStorage->typeId(typeNameId);
return projectStorage->importedTypeNameId(m_sourceId, shortTypeName);
}
return ImportedTypeNameId{};
}
void ModelPrivate::setTypeId(InternalNode *node, Utils::SmallStringView typeName)
{
if constexpr (useProjectStorage()) {
node->importedTypeNameId = importedTypeNameId(typeName);
node->typeId = projectStorage->typeId(node->importedTypeNameId);
}
}
@@ -1824,6 +1830,16 @@ NotNullPointer<const ProjectStorageType> Model::projectStorage() const
return d->projectStorage;
}
const PathCacheType &Model::pathCache() const
{
return *d->pathCache;
}
PathCacheType &Model::pathCache()
{
return *d->pathCache;
}
void ModelDeleter::operator()(class Model *model)
{
model->detachAllViews();
@@ -2011,6 +2027,16 @@ NodeMetaInfo Model::qtQmlModelsListModelMetaInfo() const
}
}
NodeMetaInfo Model::qtQmlModelsListElementMetaInfo() const
{
if constexpr (useProjectStorage()) {
using namespace Storage::Info;
return createNodeMetaInfo<QtQml_Models, ListElement>();
} else {
return metaInfo("QtQml.Models.ListElement");
}
}
NodeMetaInfo Model::qmlQtObjectMetaInfo() const
{
if constexpr (useProjectStorage()) {
@@ -2317,13 +2343,8 @@ 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::Version{majorVersion, minorVersion});
return NodeMetaInfo(typeId, d->projectStorage);
return NodeMetaInfo(d->projectStorage->typeId(d->importedTypeNameId(typeName)),
d->projectStorage);
} else {
return NodeMetaInfo(metaInfoProxyModel(), typeName, majorVersion, minorVersion);
}

View File

@@ -311,6 +311,7 @@ private:
static QList<std::tuple<InternalBindingPropertyPointer, QString>> toInternalBindingProperties(
const ModelResourceSet::SetExpressions &setExpressions);
EnabledViewRange enabledViews() const;
ImportedTypeNameId importedTypeNameId(Utils::SmallStringView typeName);
void setTypeId(InternalNode *node, Utils::SmallStringView typeName);
public:

View File

@@ -4,6 +4,7 @@
#include "modelutils.h"
#include <nodemetainfo.h>
#include <projectstorage/sourcepathcache.h>
#include <utils/expected.h>
@@ -102,4 +103,29 @@ PropertyMetaInfo metainfo(const ModelNode &node, const PropertyName &propertyNam
return node.metaInfo().property(propertyName);
}
QString componentFilePath(const PathCacheType &pathCache, const NodeMetaInfo &metaInfo)
{
if constexpr (useProjectStorage()) {
auto typeSourceId = metaInfo.sourceId();
if (typeSourceId && metaInfo.isFileComponent()) {
return pathCache.sourcePath(typeSourceId).toQString();
}
} else {
return metaInfo.componentFileName();
}
return {};
}
QString componentFilePath(const ModelNode &node)
{
if (node) {
const auto &pathCache = node.model()->pathCache();
return ModelUtils::componentFilePath(pathCache, node.metaInfo());
}
return {};
}
} // namespace QmlDesigner::ModelUtils

View File

@@ -29,4 +29,8 @@ QMLDESIGNERCORE_EXPORT PropertyMetaInfo metainfo(const AbstractProperty &propert
QMLDESIGNERCORE_EXPORT PropertyMetaInfo metainfo(const ModelNode &node,
const PropertyName &propertyName);
QMLDESIGNERCORE_EXPORT QString componentFilePath(const PathCacheType &pathCache,
const NodeMetaInfo &metaInfo);
QMLDESIGNERCORE_EXPORT QString componentFilePath(const ModelNode &node);
} // namespace QmlDesigner::ModelUtils

View File

@@ -31,6 +31,7 @@ inline constexpr char Camera[] = "Camera";
inline constexpr char Command[] = "Command";
inline constexpr char Component[] = "Component";
inline constexpr char Connections[] = "Connections";
inline constexpr char Control[] = "Control";
inline constexpr char CubeMapTexture[] = "CubeMapTexture";
inline constexpr char DefaultMaterial[] = "DefaultMaterial";
inline constexpr char Dialog[] = "Dialog";
@@ -55,11 +56,13 @@ inline constexpr char Item[] = "Item";
inline constexpr char KeyframeGroup[] = "KeyframeGroup";
inline constexpr char Keyframe[] = "Keyframe";
inline constexpr char Layout[] = "Layout";
inline constexpr char ListElement[] = "ListElement";
inline constexpr char ListModel[] = "ListModel";
inline constexpr char ListView[] = "ListView";
inline constexpr char Loader[] = "Loader";
inline constexpr char Material[] = "Material";
inline constexpr char Model[] = "Model";
inline constexpr char MouseArea[] = "MouseArea";
inline constexpr char Node[] = "Node";
inline constexpr char Particle3D[] = "Particle3D";
inline constexpr char ParticleEmitter3D[] = "ParticleEmitter3D";
@@ -92,6 +95,7 @@ inline constexpr char QtQuick_Dialogs[] = "QtQuick.Dialogs";
inline constexpr char QtQuick_Extras[] = "QtQuick.Extras";
inline constexpr char QtQuick_Layouts[] = "QtQuick.Layouts";
inline constexpr char QtQuick_Studio_Components[] = "QtQuick.Studio.Components";
inline constexpr char QtQuick_Templates[] = "QtQuick.Templates";
inline constexpr char QtQuick_Timeline[] = "QtQuick.Timeline";
inline constexpr char QtQuick_Window[] = "QtQuick.Window";
inline constexpr char Qt_SafeRenderer[] = "Qt.SafeRenderer";
@@ -160,6 +164,7 @@ class CommonTypeCache
CacheType<QML, var>,
CacheType<QML_cppnative, FloatType>,
CacheType<QtMultimedia, SoundEffect>,
CacheType<QtQml_Models, ListElement>,
CacheType<QtQml_Models, ListModel>,
CacheType<QtQuick, BorderImage>,
CacheType<QtQuick, Connections>,
@@ -168,6 +173,7 @@ class CommonTypeCache
CacheType<QtQuick, Item>,
CacheType<QtQuick, ListView>,
CacheType<QtQuick, Loader>,
CacheType<QtQuick, MouseArea>,
CacheType<QtQuick, Path>,
CacheType<QtQuick, PathView>,
CacheType<QtQuick, PauseAnimation>,
@@ -214,6 +220,7 @@ class CommonTypeCache
CacheType<QtQuick3D_Particles3D, ParticleEmitter3D>,
CacheType<QtQuick3D_Particles3D, SpriteParticle3D>,
CacheType<QtQuick3D_Particles3D_cppnative, QQuick3DParticleAbstractShape>,
CacheType<QtQuick_Controls, Control>,
CacheType<QtQuick_Controls, Popup>,
CacheType<QtQuick_Controls, SplitView>,
CacheType<QtQuick_Controls, SwipeView>,
@@ -223,6 +230,7 @@ class CommonTypeCache
CacheType<QtQuick_Extras, Picture>,
CacheType<QtQuick_Layouts, Layout>,
CacheType<QtQuick_Studio_Components, GroupItem>,
CacheType<QtQuick_Templates, Control>,
CacheType<QtQuick_Timeline, Keyframe>,
CacheType<QtQuick_Timeline, KeyframeGroup>,
CacheType<QtQuick_Timeline, Timeline>,

View File

@@ -3268,8 +3268,8 @@ public:
"UPDATE types SET defaultPropertyId=?2 WHERE typeId=?1", database};
WriteStatement<1> updateDefaultPropertyIdToNullStatement{
"UPDATE types SET defaultPropertyId=NULL WHERE defaultPropertyId=?1", database};
mutable ReadStatement<2, 1> selectInfoTypeByTypeIdStatement{
"SELECT defaultPropertyId, traits FROM types WHERE typeId=?", database};
mutable ReadStatement<3, 1> selectInfoTypeByTypeIdStatement{
"SELECT defaultPropertyId, sourceId, traits FROM types WHERE typeId=?", database};
mutable ReadStatement<1, 1> selectPrototypeIdsForTypeIdInOrderStatement{
"WITH RECURSIVE "
" all_prototype_and_extension(typeId, prototypeId) AS ("

View File

@@ -89,12 +89,14 @@ public:
class Type
{
public:
Type(PropertyDeclarationId defaultPropertyId, TypeTraits traits)
Type(PropertyDeclarationId defaultPropertyId, SourceId sourceId, TypeTraits traits)
: defaultPropertyId{defaultPropertyId}
, sourceId{sourceId}
, traits{traits}
{}
PropertyDeclarationId defaultPropertyId;
SourceId sourceId;
TypeTraits traits;
};

View File

@@ -5,13 +5,14 @@
#include "qmldesignerplugin.h"
#include <bindingproperty.h>
#include <model/modelutils.h>
#include <modelnode.h>
#include <nodelistproperty.h>
#include <nodemetainfo.h>
#include <nodeproperty.h>
#include <variantproperty.h>
#include <qmldesignerprojectmanager.h>
#include <qmlitemnode.h>
#include <variantproperty.h>
#include <utils/qtcassert.h>
#include <utils/textfileformat.h>
@@ -100,7 +101,7 @@ static void openFileComponentForFile(const QString &fileName)
static void openFileComponent(const ModelNode &modelNode)
{
openFileComponentForFile(modelNode.metaInfo().componentFileName());
openFileComponentForFile(ModelUtils::componentFilePath(modelNode));
}
static void openFileComponentForDelegate(const ModelNode &modelNode)

View File

@@ -4829,11 +4829,11 @@ void tst_TestCore::testMetaInfoSimpleType()
QCOMPARE(itemMetaInfo.minorVersion(), 1);
// super classes
NodeMetaInfo qobject = itemMetaInfo.superClasses()[1];
NodeMetaInfo qobject = itemMetaInfo.prototypes()[1];
QVERIFY(qobject.isValid());
QVERIFY(qobject.isQtObject());
QCOMPARE(itemMetaInfo.superClasses().size(), 2); // Item, QtQuick.QtObject
QCOMPARE(itemMetaInfo.prototypes().size(), 2); // Item, QtQuick.QtObject
QVERIFY(itemMetaInfo.isQtQuickItem());
QVERIFY(itemMetaInfo.isQtObject());
}
@@ -4852,11 +4852,11 @@ void tst_TestCore::testMetaInfoUncreatableType()
QCOMPARE(animationTypeInfo.majorVersion(), 2);
QCOMPARE(animationTypeInfo.minorVersion(), 1);
NodeMetaInfo qObjectTypeInfo = animationTypeInfo.superClasses()[1];
NodeMetaInfo qObjectTypeInfo = animationTypeInfo.prototypes()[1];
QVERIFY(qObjectTypeInfo.isValid());
QCOMPARE(qObjectTypeInfo.simplifiedTypeName(), QmlDesigner::TypeName("QtObject"));
QCOMPARE(animationTypeInfo.superClasses().size(), 2);
QCOMPARE(animationTypeInfo.prototypes().size(), 2);
}
void tst_TestCore::testMetaInfoExtendedType()
@@ -4870,7 +4870,7 @@ void tst_TestCore::testMetaInfoExtendedType()
QVERIFY(typeInfo.hasProperty("font")); // from QGraphicsWidget
QVERIFY(typeInfo.hasProperty("enabled")); // from QGraphicsItem
NodeMetaInfo graphicsObjectTypeInfo = typeInfo.superClasses()[1];
NodeMetaInfo graphicsObjectTypeInfo = typeInfo.prototypes()[1];
QVERIFY(graphicsObjectTypeInfo.isValid());
}
@@ -4892,12 +4892,12 @@ void tst_TestCore::testMetaInfoCustomType()
QVERIFY(propertyChangesInfo.hasProperty("restoreEntryValues"));
QVERIFY(propertyChangesInfo.hasProperty("explicit"));
NodeMetaInfo stateOperationInfo = propertyChangesInfo.superClasses()[1];
NodeMetaInfo stateOperationInfo = propertyChangesInfo.prototypes()[1];
QVERIFY(stateOperationInfo.isValid());
QCOMPARE(stateOperationInfo.typeName(), QmlDesigner::TypeName("QtQuick.QQuickStateOperation"));
QCOMPARE(stateOperationInfo.majorVersion(), -1);
QCOMPARE(stateOperationInfo.minorVersion(), -1);
QCOMPARE(propertyChangesInfo.superClasses().size(), 3);
QCOMPARE(propertyChangesInfo.prototypes().size(), 3);
// DeclarativePropertyChanges just has 3 properties
QCOMPARE(propertyChangesInfo.properties().size() - stateOperationInfo.properties().size(), 3);

View File

@@ -43,6 +43,10 @@ void setupIsBasedOn(ProjectStorageMock &mock)
ModuleId ProjectStorageMock::createModule(Utils::SmallStringView moduleName)
{
if (auto id = moduleId(moduleName)) {
return id;
}
static ModuleId moduleId;
incrementBasicId(moduleId);
@@ -54,6 +58,10 @@ ModuleId ProjectStorageMock::createModule(Utils::SmallStringView moduleName)
QmlDesigner::ImportedTypeNameId ProjectStorageMock::createImportedTypeNameId(
SourceId sourceId, Utils::SmallStringView typeName, TypeId typeId)
{
if (auto id = importedTypeNameId(sourceId, typeName)) {
return id;
}
static ImportedTypeNameId importedTypeNameId;
incrementBasicId(importedTypeNameId);
@@ -76,6 +84,10 @@ QmlDesigner::ImportedTypeNameId ProjectStorageMock::createImportedTypeNameId(
QmlDesigner::ImportedTypeNameId ProjectStorageMock::createImportedTypeNameId(
QmlDesigner::ImportId importId, Utils::SmallStringView typeName, QmlDesigner::TypeId typeId)
{
if (auto id = importedTypeNameId(importId, typeName)) {
return id;
}
static ImportedTypeNameId importedTypeNameId;
incrementBasicId(importedTypeNameId);
@@ -104,6 +116,10 @@ PropertyDeclarationId ProjectStorageMock::createProperty(TypeId typeId,
PropertyDeclarationTraits traits,
TypeId propertyTypeId)
{
if (auto id = propertyDeclarationId(typeId, name)) {
return id;
}
static PropertyDeclarationId propertyId;
incrementBasicId(propertyId);
@@ -148,8 +164,13 @@ TypeId ProjectStorageMock::createType(ModuleId moduleId,
PropertyDeclarationTraits defaultPropertyTraits,
TypeId defaultPropertyTypeId,
Storage::TypeTraits typeTraits,
TypeIds baseTypeIds)
TypeIds baseTypeIds,
SourceId sourceId)
{
if (auto id = typeId(moduleId, typeName)) {
return id;
}
static TypeId typeId;
incrementBasicId(typeId);
@@ -167,22 +188,31 @@ TypeId ProjectStorageMock::createType(ModuleId moduleId,
}
ON_CALL(*this, type(Eq(typeId)))
.WillByDefault(Return(Storage::Info::Type{defaultPropertyDeclarationId, typeTraits}));
.WillByDefault(
Return(Storage::Info::Type{defaultPropertyDeclarationId, sourceId, typeTraits}));
ON_CALL(*this, isBasedOn(Eq(typeId), Eq(typeId))).WillByDefault(Return(true));
for (TypeId baseTypeId : baseTypeIds)
ON_CALL(*this, isBasedOn(Eq(typeId), Eq(baseTypeId))).WillByDefault(Return(true));
TypeIds selfAndPrototypes;
selfAndPrototypes.reserve(baseTypeIds.size() + 1);
selfAndPrototypes.push_back(typeId);
selfAndPrototypes.insert(selfAndPrototypes.end(), baseTypeIds.begin(), baseTypeIds.end());
ON_CALL(*this, prototypeAndSelfIds(Eq(typeId))).WillByDefault(Return(selfAndPrototypes));
ON_CALL(*this, prototypeIds(Eq(typeId))).WillByDefault(Return(baseTypeIds));
return typeId;
}
QmlDesigner::TypeId ProjectStorageMock::createType(QmlDesigner::ModuleId moduleId,
Utils::SmallStringView typeName,
QmlDesigner::Storage::TypeTraits typeTraits,
QmlDesigner::TypeIds baseTypeIds)
QmlDesigner::TypeIds baseTypeIds,
SourceId sourceId)
{
return createType(moduleId, typeName, {}, {}, TypeId{}, typeTraits, baseTypeIds);
return createType(moduleId, typeName, {}, {}, TypeId{}, typeTraits, baseTypeIds, sourceId);
}
TypeId ProjectStorageMock::createObject(ModuleId moduleId,
@@ -190,7 +220,8 @@ TypeId ProjectStorageMock::createObject(ModuleId moduleId,
Utils::SmallStringView defaultPropertyName,
PropertyDeclarationTraits defaultPropertyTraits,
QmlDesigner::TypeId defaultPropertyTypeId,
TypeIds baseTypeIds)
TypeIds baseTypeIds,
QmlDesigner::SourceId sourceId)
{
return createType(moduleId,
typeName,
@@ -198,7 +229,8 @@ TypeId ProjectStorageMock::createObject(ModuleId moduleId,
defaultPropertyTraits,
defaultPropertyTypeId,
Storage::TypeTraits::Reference,
baseTypeIds);
baseTypeIds,
sourceId);
}
TypeId ProjectStorageMock::createObject(ModuleId moduleId,
@@ -213,11 +245,13 @@ void ProjectStorageMock::setupQtQuick()
setupIsBasedOn(*this);
auto qmlModuleId = createModule("QML");
auto qmlNativeModuleId = createModule("QML-cppnative");
auto qtQmlModelsModuleId = createModule("QtQml.Models");
auto qtQuickModuleId = createModule("QtQuick");
auto qtQuickNativeModuleId = createModule("QtQuick-cppnative");
createType(qmlModuleId, "int", Storage::TypeTraits::Value);
createType(qmlNativeModuleId, "float", Storage::TypeTraits::Value);
auto qtObjectId = createObject(qmlModuleId,
"QtObject",
@@ -275,7 +309,7 @@ void ProjectStorageMock::setupQtQuick()
"data",
PropertyDeclarationTraits::IsList,
qtObjectId,
{qtObjectId, itemId});
{itemId, qtObjectId});
createObject(flowViewModuleId,
"FlowWildcard",
"data",

View File

@@ -47,12 +47,14 @@ public:
QmlDesigner::Storage::PropertyDeclarationTraits defaultPropertyTraits,
QmlDesigner::TypeId defaultPropertyTypeId,
QmlDesigner::Storage::TypeTraits typeTraits,
QmlDesigner::TypeIds baseTypeIds = {});
QmlDesigner::TypeIds baseTypeIds = {},
QmlDesigner::SourceId sourceId = QmlDesigner::SourceId{});
QmlDesigner::TypeId createType(QmlDesigner::ModuleId moduleId,
Utils::SmallStringView typeName,
QmlDesigner::Storage::TypeTraits typeTraits,
QmlDesigner::TypeIds baseTypeIds = {});
QmlDesigner::TypeIds baseTypeIds = {},
QmlDesigner::SourceId sourceId = QmlDesigner::SourceId{});
QmlDesigner::TypeId createObject(
QmlDesigner::ModuleId moduleId,
@@ -60,7 +62,8 @@ public:
Utils::SmallStringView defaultPropertyName,
QmlDesigner::Storage::PropertyDeclarationTraits defaultPropertyTraits,
QmlDesigner::TypeId defaultPropertyTypeId,
QmlDesigner::TypeIds baseTypeIds = {});
QmlDesigner::TypeIds baseTypeIds = {},
QmlDesigner::SourceId sourceId = QmlDesigner::SourceId{});
QmlDesigner::TypeId createObject(QmlDesigner::ModuleId moduleId,
Utils::SmallStringView typeName,
@@ -99,7 +102,11 @@ public:
typeId,
(QmlDesigner::ImportedTypeNameId typeNameId),
(const, override));
QmlDesigner::TypeId typeId(QmlDesigner::ModuleId moduleId,
::Utils::SmallStringView exportedTypeName) const
{
return typeId(moduleId, exportedTypeName, QmlDesigner::Storage::Version{});
}
MOCK_METHOD(QmlDesigner::TypeId,
typeId,
(QmlDesigner::ModuleId moduleId,

View File

@@ -54,7 +54,6 @@ add_qtc_library(TestDesignerCore OBJECT
imagecache/synchronousimagecache.cpp
imagecache/timestampproviderinterface.h
include/abstractproperty.h
include/abstractview.h
include/asynchronousexplicitimagecache.h
include/asynchronousimagecache.h
include/asynchronousimagecacheinterface.h
@@ -64,7 +63,6 @@ add_qtc_library(TestDesignerCore OBJECT
include/itemlibraryinfo.h
include/metainfo.h
include/metainforeader.h
include/model.h
include/modelnode.h
include/nodeabstractproperty.h
include/nodelistproperty.h
@@ -108,6 +106,7 @@ add_qtc_library(TestDesignerCore OBJECT
model/modelnode.cpp
model/modelresourcemanagementinterface.h
model/modelresourcemanagement.cpp model/modelresourcemanagement.h
model/modelutils.cpp model/modelutils.h
model/propertycontainer.cpp
model/propertyparser.cpp
model/nodeabstractproperty.cpp

View File

@@ -3,7 +3,7 @@ file(RELATIVE_PATH TEST_RELATIVE_LIBEXEC_PATH "/${RELATIVE_TEST_PATH}" "/${IDE_L
add_qtc_test(unittest GTEST
PROPERTIES COMPILE_WARNING_AS_ERROR OFF
SKIP_AUTOMOC ON
SKIP_AUTOGEN ON
DEPENDS
Qt::Core Qt::Network Qt::Widgets
Qt::Xml Qt::Concurrent Qt::QmlPrivate Qt::Gui

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,8 @@ extend_qtc_test(unittest
import-test.cpp
model-test.cpp
modelnode-test.cpp
nodelistproperty-test.cpp
modelresourcemanagement-test.cpp
modelutils-test.cpp
nodelistproperty-test.cpp
)

View File

@@ -855,4 +855,18 @@ TEST_F(Model, change_root_node_type_changes_meta_info)
ASSERT_THAT(rootNode.metaInfo(), model.qmlQtObjectMetaInfo());
}
TEST_F(Model, meta_info)
{
auto meta_info = model.metaInfo("QtObject");
ASSERT_THAT(meta_info, model.qmlQtObjectMetaInfo());
}
TEST_F(Model, meta_info_of_not_existing_type_is_invalid)
{
auto meta_info = model.metaInfo("Foo");
ASSERT_THAT(meta_info, IsFalse());
}
} // namespace

View File

@@ -0,0 +1,109 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <googletest.h>
#include <mocks/projectstoragemock.h>
#include <mocks/sourcepathcachemock.h>
#include <model/modelutils.h>
#include <nodemetainfo.h>
namespace {
class ModelUtils : public ::testing::Test
{
protected:
NiceMock<SourcePathCacheMockWithPaths> pathCacheMock{"/path/model.qml"};
QmlDesigner::SourceId sourceId = pathCacheMock.createSourceId("/path/foo.qml");
NiceMock<ProjectStorageMockWithQtQtuick> projectStorageMock{pathCacheMock.sourceId};
QmlDesigner::ModuleId moduleId = projectStorageMock.moduleId("QtQuick");
QmlDesigner::Model model{{projectStorageMock, pathCacheMock},
"Item",
{QmlDesigner::Import::createLibraryImport("QML"),
QmlDesigner::Import::createLibraryImport("QtQuick"),
QmlDesigner::Import::createLibraryImport("QtQml.Models")},
QUrl::fromLocalFile(pathCacheMock.path.toQString())};
};
TEST_F(ModelUtils, component_file_path)
{
auto typeId = projectStorageMock.createType(moduleId,
"Foo",
QmlDesigner::Storage::TypeTraits::IsFileComponent,
{},
sourceId);
QmlDesigner::NodeMetaInfo metaInfo{typeId, &projectStorageMock};
auto path = QmlDesigner::ModelUtils::componentFilePath(pathCacheMock, metaInfo);
ASSERT_THAT(path, "/path/foo.qml");
}
TEST_F(ModelUtils, empty_component_file_path_for_non_file_component)
{
auto typeId = projectStorageMock.createType(moduleId, "Foo", {}, {}, sourceId);
QmlDesigner::NodeMetaInfo metaInfo{typeId, &projectStorageMock};
auto path = QmlDesigner::ModelUtils::componentFilePath(pathCacheMock, metaInfo);
ASSERT_THAT(path, IsEmpty());
}
TEST_F(ModelUtils, empty_component_file_path_for_invalid_meta_info)
{
QmlDesigner::NodeMetaInfo metaInfo;
auto path = QmlDesigner::ModelUtils::componentFilePath(pathCacheMock, metaInfo);
ASSERT_THAT(path, IsEmpty());
}
TEST_F(ModelUtils, component_file_path_for_node)
{
auto typeId = projectStorageMock.createType(moduleId,
"Foo",
QmlDesigner::Storage::TypeTraits::IsFileComponent,
{},
sourceId);
projectStorageMock.createImportedTypeNameId(pathCacheMock.sourceId, "Foo", typeId);
auto node = model.createModelNode("Foo");
auto path = QmlDesigner::ModelUtils::componentFilePath(node);
ASSERT_THAT(path, "/path/foo.qml");
}
TEST_F(ModelUtils, component_file_path_for_invalid_node_is_empty)
{
auto path = QmlDesigner::ModelUtils::componentFilePath(QmlDesigner::ModelNode{});
ASSERT_THAT(path, IsEmpty());
}
TEST_F(ModelUtils, component_file_path_for_node_without_metainfo_is_empty)
{
auto typeId = projectStorageMock.createType(moduleId,
"Foo",
QmlDesigner::Storage::TypeTraits::IsFileComponent,
{},
sourceId);
auto node = model.createModelNode("Foo");
auto path = QmlDesigner::ModelUtils::componentFilePath(node);
ASSERT_THAT(path, IsEmpty());
}
TEST_F(ModelUtils, component_file_path_for_non_file_component_node_is_empty)
{
auto typeId = projectStorageMock.createType(moduleId, "Foo", {}, {}, sourceId);
projectStorageMock.createImportedTypeNameId(pathCacheMock.sourceId, "Foo", typeId);
auto node = model.createModelNode("Foo");
auto path = QmlDesigner::ModelUtils::componentFilePath(node);
ASSERT_THAT(path, IsEmpty());
}
} // namespace

View File

@@ -62,7 +62,7 @@ protected:
ON_CALL(projectStorageMock, typeId(Eq(moduleId), Eq(typeName), _)).WillByDefault(Return(typeId));
ON_CALL(projectStorageMock, type(Eq(typeId)))
.WillByDefault(Return(Info::Type{defaultPropertyId, {}}));
.WillByDefault(Return(Info::Type{defaultPropertyId, QmlDesigner::SourceId{}, {}}));
ON_CALL(projectStorageMock, propertyName(Eq(defaultPropertyId)))
.WillByDefault(Return(defaultPeopertyName));
}

View File

@@ -242,15 +242,17 @@ MATCHER(StringsAreSorted, std::string(negation ? "isn't sorted" : "is sorted"))
});
}
MATCHER_P2(IsInfoType,
MATCHER_P3(IsInfoType,
defaultPropertyId,
sourceId,
traits,
std::string(negation ? "isn't " : "is ")
+ PrintToString(Storage::Info::Type{defaultPropertyId, traits}))
+ PrintToString(Storage::Info::Type{defaultPropertyId, sourceId, traits}))
{
const Storage::Info::Type &type = arg;
return type.defaultPropertyId == defaultPropertyId && type.traits == traits;
return type.defaultPropertyId == defaultPropertyId && type.sourceId == sourceId
&& type.traits == traits;
}
class ProjectStorage : public testing::Test
@@ -6520,7 +6522,7 @@ TEST_F(ProjectStorage, get_type)
auto type = storage.type(typeId);
ASSERT_THAT(type, Optional(IsInfoType(defaultPropertyId, TypeTraits::Reference)));
ASSERT_THAT(type, Optional(IsInfoType(defaultPropertyId, sourceId1, TypeTraits::Reference)));
}
TEST_F(ProjectStorage, dont_get_type_for_invalid_id)