From ebe1c889b79c7e6abd93adc8fe2f9c155d82c9fa Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 7 Sep 2023 14:49:44 +0200 Subject: [PATCH] QmlDesigner: Integrate component generation It is only activated if the project storage is activated Task-number: QDS-10578 Change-Id: Id93673eba470aa37a249072b3ef9e0231499095a Reviewed-by: Qt CI Patch Build Bot Reviewed-by: Tim Jenssen --- src/plugins/qmldesigner/CMakeLists.txt | 3 + .../propertycomponentgenerator.cpp | 82 ++++++++++--- .../propertycomponentgenerator.h | 15 +++ .../propertyeditorcomponentgenerator.cpp | 14 +-- .../propertyeditorcomponentgenerator.h | 6 +- .../propertyeditor/propertyeditorview.cpp | 108 ++++++++++++++---- .../propertyeditor/propertyeditorview.h | 5 + .../designercore/include/abstractview.h | 2 +- .../qmldesigner/designercore/include/model.h | 1 + .../designercore/model/abstractview.cpp | 2 +- .../qmldesigner/designercore/model/model.cpp | 23 +++- .../qmldesigner/designercore/model/model_p.h | 5 +- .../projectstorage/projectstorage.h | 14 +-- .../projectstorage/projectstorageinterface.h | 4 +- .../projectstorage/sourcepathcache.h | 2 + tests/unit/tests/mocks/abstractviewmock.h | 2 +- tests/unit/tests/mocks/projectstoragemock.cpp | 70 ++++++++++-- tests/unit/tests/mocks/projectstoragemock.h | 19 ++- .../propertycomponentgenerator-test.cpp | 52 +++++++++ .../propertyeditorcomponentgenerator-test.cpp | 56 ++++----- .../unit/tests/unittests/model/model-test.cpp | 8 +- .../projectstorage/projectstorage-test.cpp | 4 +- 22 files changed, 387 insertions(+), 110 deletions(-) diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 6df5a632472..80273e863b8 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -575,6 +575,9 @@ extend_qtc_plugin(QmlDesigner modelnodeoperations.cpp modelnodeoperations.h formatoperation.cpp formatoperation.h navigation2d.cpp navigation2d.h + propertyeditorcomponentgenerator.cpp propertyeditorcomponentgenerator.h + propertycomponentgenerator.cpp propertycomponentgenerator.h + propertycomponentgeneratorinterface.h qmldesignericonprovider.cpp qmldesignericonprovider.h qmleditormenu.cpp qmleditormenu.h selectioncontext.cpp selectioncontext.h diff --git a/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp b/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp index 7e5487909a8..8cc84058d20 100644 --- a/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp +++ b/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp @@ -5,6 +5,7 @@ #include #include +#include #include @@ -205,10 +206,10 @@ std::optional createEntry(QmlJS::SimpleReader needsTypeArg}; } -PropertyComponentGenerator::Entries createEntries(QmlJS::SimpleReaderNode::Ptr templateConfiguration, - Model *model, - const QString &templatesPath) +std::tuple createEntries( + QmlJS::SimpleReaderNode::Ptr templateConfiguration, Model *model, const QString &templatesPath) { + bool hasInvalidTemplates = false; PropertyComponentGenerator::Entries entries; entries.reserve(32); @@ -216,12 +217,14 @@ PropertyComponentGenerator::Entries createEntries(QmlJS::SimpleReaderNode::Ptr t for (const QmlJS::SimpleReaderNode::Ptr &node : nodes) { if (auto entry = createEntry(node.get(), model, templatesPath)) entries.push_back(*entry); + else + hasInvalidTemplates = true; } - return entries; + return {entries, hasInvalidTemplates}; } -QStringList createImports(QmlJS::SimpleReaderNode::Ptr templateConfiguration) +QStringList createImports(QmlJS::SimpleReaderNode *templateConfiguration) { auto property = templateConfiguration->property("imports"); return Utils::transform(property.value.toList(), @@ -232,17 +235,11 @@ QStringList createImports(QmlJS::SimpleReaderNode::Ptr templateConfiguration) PropertyComponentGenerator::PropertyComponentGenerator(const QString &propertyEditorResourcesPath, Model *model) - : m_entries(createEntries(createTemplateConfiguration(propertyEditorResourcesPath), - model, - propertyEditorResourcesPath + "/PropertyTemplates/")) + : m_templateConfiguration{createTemplateConfiguration(propertyEditorResourcesPath)} + , m_propertyTemplatesPath{propertyEditorResourcesPath + "/PropertyTemplates/"} { - auto templateConfiguration = createTemplateConfiguration(propertyEditorResourcesPath); - - m_entries = createEntries(templateConfiguration, - model, - propertyEditorResourcesPath + "/PropertyTemplates/"); - - m_imports = createImports(templateConfiguration); + setModel(model); + m_imports = createImports(m_templateConfiguration.get()); } PropertyComponentGenerator::Property PropertyComponentGenerator::create(const PropertyMetaInfo &property) const @@ -257,6 +254,61 @@ PropertyComponentGenerator::Property PropertyComponentGenerator::create(const Pr return generateComplexComponent(property, propertyType); } +void PropertyComponentGenerator::setModel(Model *model) +{ + if (model && m_model && m_model->projectStorage() == model->projectStorage()) { + m_model = model; + return; + } + + if (model) { + setEntries(m_templateConfiguration, model, m_propertyTemplatesPath); + } else { + m_entries.clear(); + m_entryTypeIds.clear(); + } + m_model = model; +} + +namespace { + +bool insect(const TypeIds &first, const TypeIds &second) +{ + bool intersecting = false; + + std::set_intersection(first.begin(), + first.end(), + second.begin(), + second.end(), + Utils::make_iterator([&](const auto &) { intersecting = true; })); + + return intersecting; +} + +} // namespace + +void PropertyComponentGenerator::setEntries(QmlJS::SimpleReaderNode::Ptr templateConfiguration, + Model *model, + const QString &propertyTemplatesPath) +{ + auto [entries, hasInvalidTemplates] = createEntries(templateConfiguration, + model, + propertyTemplatesPath); + m_entries = std::move(entries); + m_hasInvalidTemplates = hasInvalidTemplates; + m_entryTypeIds = Utils::transform(m_entries, + [](const auto &entry) { return entry.type.id(); }); + std::sort(m_entryTypeIds.begin(), m_entryTypeIds.end()); +} + +void PropertyComponentGenerator::refreshMetaInfos(const TypeIds &deletedTypeIds) +{ + if (!insect(deletedTypeIds, m_entryTypeIds) && !m_hasInvalidTemplates) + return; + + setEntries(m_templateConfiguration, m_model, m_propertyTemplatesPath); +} + const PropertyComponentGenerator::Entry *PropertyComponentGenerator::findEntry(const NodeMetaInfo &type) const { auto found = std::find_if(m_entries.begin(), m_entries.end(), [&](const auto &entry) { diff --git a/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.h b/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.h index 67239c16a70..dfa5f30db2d 100644 --- a/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.h +++ b/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.h @@ -10,6 +10,8 @@ #include +#include + #include #include #include @@ -36,6 +38,10 @@ public: QStringList imports() const override { return m_imports; } + void setModel(Model *model); + + void refreshMetaInfos(const TypeIds &deletedTypeIds); + private: const Entry *findEntry(const NodeMetaInfo &type) const; QString generateSubComponentText(Utils::SmallStringView propertyBaseName, @@ -45,9 +51,18 @@ private: Property generateComplexComponent(const PropertyMetaInfo &property, const NodeMetaInfo &propertyType) const; + void setEntries(QmlJS::SimpleReaderNode::Ptr templateConfiguration, + Model *model, + const QString &propertyTemplatesPath); + private: Entries m_entries; + TypeIds m_entryTypeIds; QStringList m_imports; + QPointer m_model; + QmlJS::SimpleReaderNode::Ptr m_templateConfiguration; + QString m_propertyTemplatesPath; + bool m_hasInvalidTemplates = false; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/componentcore/propertyeditorcomponentgenerator.cpp b/src/plugins/qmldesigner/components/componentcore/propertyeditorcomponentgenerator.cpp index 272130b8f33..9b066d5fec0 100644 --- a/src/plugins/qmldesigner/components/componentcore/propertyeditorcomponentgenerator.cpp +++ b/src/plugins/qmldesigner/components/componentcore/propertyeditorcomponentgenerator.cpp @@ -75,13 +75,11 @@ Utils::SmallStringView propertyName(const GeneratorProperty &property) property); } -PropertyMetaInfos getUnmangedProperties(const NodeMetaInfo &nodeInfo) +PropertyMetaInfos getUnmangedProperties(const NodeMetaInfos &prototypes) { PropertyMetaInfos properties; properties.reserve(128); - auto prototypes = nodeInfo.selfAndPrototypes(); - for (const auto &prototype : prototypes) { if (prototype.propertyEditorPathId()) break; @@ -117,12 +115,12 @@ GeneratorProperties createSortedGeneratorProperties( } QString createPropertySections(const PropertyComponentGeneratorType &propertyGenerator, - const NodeMetaInfo &nodeInfo) + const NodeMetaInfos &prototypeChain) { QString propertyComponents; propertyComponents.reserve(100000); - auto generatorProperties = createSortedGeneratorProperties(getUnmangedProperties(nodeInfo), + auto generatorProperties = createSortedGeneratorProperties(getUnmangedProperties(prototypeChain), propertyGenerator); const auto begin = generatorProperties.begin(); @@ -143,12 +141,12 @@ QString createPropertySections(const PropertyComponentGeneratorType &propertyGen } // namespace -PropertyEditorTemplateGenerator::PropertyEditorTemplateGenerator( +PropertyEditorComponentGenerator::PropertyEditorComponentGenerator( const PropertyComponentGeneratorType &propertyGenerator) : m_propertyGenerator{propertyGenerator} {} -QString PropertyEditorTemplateGenerator::create(const NodeMetaInfo &nodeInfo, bool isComponent) +QString PropertyEditorComponentGenerator::create(const NodeMetaInfos &prototypeChain, bool isComponent) { return QString{R"xy( %1 @@ -171,7 +169,7 @@ QString PropertyEditorTemplateGenerator::create(const NodeMetaInfo &nodeInfo, bo .arg(createImports(m_propertyGenerator.imports()), componentButton(isComponent), QObject::tr("Exposed Custom Properties"), - createPropertySections(m_propertyGenerator, nodeInfo)); + createPropertySections(m_propertyGenerator, prototypeChain)); } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/componentcore/propertyeditorcomponentgenerator.h b/src/plugins/qmldesigner/components/componentcore/propertyeditorcomponentgenerator.h index 37dd824d43f..56fa5ef78dc 100644 --- a/src/plugins/qmldesigner/components/componentcore/propertyeditorcomponentgenerator.h +++ b/src/plugins/qmldesigner/components/componentcore/propertyeditorcomponentgenerator.h @@ -14,13 +14,13 @@ using PropertyComponentGeneratorType = PropertyComponentGeneratorInterface; #else using PropertyComponentGeneratorType = PropertyComponentGenerator; #endif -class PropertyEditorTemplateGenerator +class PropertyEditorComponentGenerator { public: - PropertyEditorTemplateGenerator(const PropertyComponentGeneratorType &propertyGenerator); + PropertyEditorComponentGenerator(const PropertyComponentGeneratorType &propertyGenerator); - QString create(const NodeMetaInfo &nodeInfo, bool isComponent); + [[nodiscard]] QString create(const NodeMetaInfos &prototypeChain, bool isComponent); private: const PropertyComponentGeneratorType &m_propertyGenerator; diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp index bf35e2512eb..1fba74f2178 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp @@ -20,6 +20,7 @@ #include #include +#include #include @@ -65,6 +66,8 @@ PropertyEditorView::PropertyEditorView(AsynchronousImageCache &imageCache, , m_timerId(0) , m_stackedWidget(new PropertyEditorWidget()) , m_qmlBackEndForCurrentType(nullptr) + , m_propertyComponentGenerator{QmlDesigner::PropertyEditorQmlBackend::propertyEditorResourcesPath(), + model()} , m_locked(false) , m_setupCompleted(false) , m_singleShotTimer(new QTimer(this)) @@ -373,6 +376,11 @@ void PropertyEditorView::currentTimelineChanged(const ModelNode &) m_qmlBackEndForCurrentType->contextObject()->setHasActiveTimeline(QmlTimeline::hasActiveTimeline(this)); } +void PropertyEditorView::refreshMetaInfos(const TypeIds &deletedTypeIds) +{ + m_propertyComponentGenerator.refreshMetaInfos(deletedTypeIds); +} + void PropertyEditorView::updateSize() { if (!m_qmlBackEndForCurrentType) @@ -439,8 +447,8 @@ void PropertyEditorView::resetView() namespace { -std::tuple diffType(const NodeMetaInfo &commonAncestor, - const NodeMetaInfo &specificsClassMetaInfo) +[[maybe_unused]] std::tuple diffType(const NodeMetaInfo &commonAncestor, + const NodeMetaInfo &specificsClassMetaInfo) { NodeMetaInfo diffClassMetaInfo; QUrl qmlSpecificsFile; @@ -463,9 +471,9 @@ std::tuple diffType(const NodeMetaInfo &commonAncestor, return {diffClassMetaInfo, qmlSpecificsFile}; } -QString getSpecificQmlData(const NodeMetaInfo &commonAncestor, - const ModelNode &selectedNode, - const NodeMetaInfo &diffClassMetaInfo) +[[maybe_unused]] QString getSpecificQmlData(const NodeMetaInfo &commonAncestor, + const ModelNode &selectedNode, + const NodeMetaInfo &diffClassMetaInfo) { if (commonAncestor.isValid() && diffClassMetaInfo != selectedNode.metaInfo()) return PropertyEditorQmlBackend::templateGeneration(commonAncestor, @@ -534,33 +542,90 @@ void setupWidget(PropertyEditorQmlBackend *currentQmlBackend, stackedWidget->setCurrentWidget(currentQmlBackend->widget()); currentQmlBackend->contextObject()->triggerSelectionChanged(); } + +[[maybe_unused]] auto findPaneAndSpecificsPath(const NodeMetaInfos &prototypes, + const SourcePathCacheInterface &pathCache) +{ + Utils::PathString panePath; + Utils::PathString specificsPath; + + for (const NodeMetaInfo &prototype : prototypes) { + auto sourceId = prototype.propertyEditorPathId(); + if (sourceId) { + auto path = pathCache.sourcePath(sourceId); + if (path.endsWith("Pane.qml")) { + panePath = path; + if (panePath.size() && specificsPath.size()) + return std::make_tuple(panePath, specificsPath); + } else if (path.endsWith("Specifics.qml")) { + specificsPath = path; + if (panePath.size() && specificsPath.size()) + return std::make_tuple(panePath, specificsPath); + } + } + } + + return std::make_tuple(panePath, specificsPath); +} } // namespace void PropertyEditorView::setupQmlBackend() { - const NodeMetaInfo commonAncestor = PropertyEditorQmlBackend::findCommonAncestor(m_selectedNode); + if constexpr (useProjectStorage()) { + auto selfAndPrototypes = m_selectedNode.metaInfo().selfAndPrototypes(); + auto specificQmlData = m_propertyEditorComponentGenerator.create(selfAndPrototypes, + m_selectedNode.isComponent()); + auto [panePath, specificsPath] = findPaneAndSpecificsPath(selfAndPrototypes, + model()->pathCache()); + PropertyEditorQmlBackend *currentQmlBackend = getQmlBackend(m_qmlBackendHash, + QUrl::fromLocalFile( + QString{panePath}), + m_imageCache, + m_stackedWidget, + this); - const auto [qmlFileUrl, specificsClassMetaInfo] = PropertyEditorQmlBackend::getQmlUrlForMetaInfo( - commonAncestor); + setupCurrentQmlBackend(currentQmlBackend, + m_selectedNode, + QUrl::fromLocalFile(QString{specificsPath}), + currentState(), + this, + specificQmlData); - auto [diffClassMetaInfo, qmlSpecificsFile] = diffType(commonAncestor, specificsClassMetaInfo); + setupWidget(currentQmlBackend, this, m_stackedWidget); - QString specificQmlData = getSpecificQmlData(commonAncestor, m_selectedNode, diffClassMetaInfo); + m_qmlBackEndForCurrentType = currentQmlBackend; - PropertyEditorQmlBackend *currentQmlBackend = getQmlBackend(m_qmlBackendHash, - qmlFileUrl, - m_imageCache, - m_stackedWidget, - this); + setupInsight(rootModelNode(), currentQmlBackend); + } else { + const NodeMetaInfo commonAncestor = PropertyEditorQmlBackend::findCommonAncestor( + m_selectedNode); - setupCurrentQmlBackend( - currentQmlBackend, m_selectedNode, qmlSpecificsFile, currentState(), this, specificQmlData); + const auto [qmlFileUrl, specificsClassMetaInfo] = PropertyEditorQmlBackend::getQmlUrlForMetaInfo( + commonAncestor); - setupWidget(currentQmlBackend, this, m_stackedWidget); + auto [diffClassMetaInfo, qmlSpecificsFile] = diffType(commonAncestor, specificsClassMetaInfo); - m_qmlBackEndForCurrentType = currentQmlBackend; + QString specificQmlData = getSpecificQmlData(commonAncestor, m_selectedNode, diffClassMetaInfo); - setupInsight(rootModelNode(), currentQmlBackend); + PropertyEditorQmlBackend *currentQmlBackend = getQmlBackend(m_qmlBackendHash, + qmlFileUrl, + m_imageCache, + m_stackedWidget, + this); + + setupCurrentQmlBackend(currentQmlBackend, + m_selectedNode, + qmlSpecificsFile, + currentState(), + this, + specificQmlData); + + setupWidget(currentQmlBackend, this, m_stackedWidget); + + m_qmlBackEndForCurrentType = currentQmlBackend; + + setupInsight(rootModelNode(), currentQmlBackend); + } } void PropertyEditorView::commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value) @@ -646,6 +711,9 @@ void PropertyEditorView::modelAttached(Model *model) { AbstractView::modelAttached(model); + if constexpr (useProjectStorage()) + m_propertyComponentGenerator.setModel(model); + if (debug) qDebug() << Q_FUNC_INFO; diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h index bb2f9dc360c..cc9b5228392 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h @@ -9,6 +9,7 @@ #include #include +#include QT_BEGIN_NAMESPACE class QEvent; @@ -81,6 +82,8 @@ public: void currentTimelineChanged(const ModelNode &node) override; + void refreshMetaInfos(const TypeIds &deletedTypeIds) override; + protected: void timerEvent(QTimerEvent *event) override; void setupPane(const TypeName &typeName); @@ -113,6 +116,8 @@ private: //variables QString m_qmlDir; QHash m_qmlBackendHash; PropertyEditorQmlBackend *m_qmlBackEndForCurrentType; + PropertyComponentGenerator m_propertyComponentGenerator; + PropertyEditorComponentGenerator m_propertyEditorComponentGenerator{m_propertyComponentGenerator}; bool m_locked; bool m_setupCompleted; QTimer *m_singleShotTimer; diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index 7ca01c687eb..0a3350b693b 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -148,7 +148,7 @@ public: virtual void modelAttached(Model *model); virtual void modelAboutToBeDetached(Model *model); - virtual void refreshMetaInfos(); + virtual void refreshMetaInfos(const TypeIds &deletedTypeIds); virtual void nodeCreated(const ModelNode &createdNode); virtual void nodeAboutToBeRemoved(const ModelNode &removedNode); diff --git a/src/plugins/qmldesigner/designercore/include/model.h b/src/plugins/qmldesigner/designercore/include/model.h index ac8182c0760..cc3b4aadf9c 100644 --- a/src/plugins/qmldesigner/designercore/include/model.h +++ b/src/plugins/qmldesigner/designercore/include/model.h @@ -136,6 +136,7 @@ public: void setMetaInfo(const MetaInfo &metaInfo); NodeMetaInfo boolMetaInfo() const; + NodeMetaInfo doubleMetaInfo() const; NodeMetaInfo flowViewFlowActionAreaMetaInfo() const; NodeMetaInfo flowViewFlowDecisionMetaInfo() const; NodeMetaInfo flowViewFlowItemMetaInfo() const; diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index 2fe422487c9..a982d8dc5e5 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -164,7 +164,7 @@ void AbstractView::modelAboutToBeDetached(Model *) removeModel(); } -void AbstractView::refreshMetaInfos() {} +void AbstractView::refreshMetaInfos(const TypeIds &) {} /*! \enum QmlDesigner::AbstractView::PropertyChangeFlag diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 5bc081833ab..7b5868d6cf5 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -83,7 +83,8 @@ ModelPrivate::ModelPrivate(Model *model, m_currentStateNode = m_rootInternalNode; m_currentTimelineNode = m_rootInternalNode; - projectStorage->addRefreshCallback(&m_metaInfoRefreshCallback); + if constexpr (useProjectStorage()) + projectStorage->addRefreshCallback(&m_metaInfoRefreshCallback); } ModelPrivate::ModelPrivate(Model *model, @@ -106,7 +107,8 @@ ModelPrivate::ModelPrivate(Model *model, m_currentStateNode = m_rootInternalNode; m_currentTimelineNode = m_rootInternalNode; - projectStorage->addRefreshCallback(&m_metaInfoRefreshCallback); + if constexpr (useProjectStorage()) + projectStorage->addRefreshCallback(&m_metaInfoRefreshCallback); } ModelPrivate::ModelPrivate(Model *model, @@ -129,7 +131,8 @@ ModelPrivate::ModelPrivate(Model *model, ModelPrivate::~ModelPrivate() { - projectStorage->removeRefreshCallback(&m_metaInfoRefreshCallback); + if constexpr (useProjectStorage()) + projectStorage->removeRefreshCallback(&m_metaInfoRefreshCallback); }; void ModelPrivate::detachAllViews() @@ -391,9 +394,9 @@ void ModelPrivate::setTypeId(InternalNode *node, Utils::SmallStringView typeName } } -void ModelPrivate::emitRefreshMetaInfos() +void ModelPrivate::emitRefreshMetaInfos(const TypeIds &deletedTypeIds) { - notifyNodeInstanceViewLast([&](AbstractView *view) { view->refreshMetaInfos(); }); + notifyNodeInstanceViewLast([&](AbstractView *view) { view->refreshMetaInfos(deletedTypeIds); }); } void ModelPrivate::handleResourceSet(const ModelResourceSet &resourceSet) @@ -2086,6 +2089,16 @@ NodeMetaInfo Model::boolMetaInfo() const } } +NodeMetaInfo Model::doubleMetaInfo() const +{ + if constexpr (useProjectStorage()) { + using namespace Storage::Info; + return createNodeMetaInfo(); + } else { + return metaInfo("QML.double"); + } +} + template NodeMetaInfo Model::createNodeMetaInfo() const { diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/designercore/model/model_p.h index 1df16d24bb5..d09e4054ca2 100644 --- a/src/plugins/qmldesigner/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/designercore/model/model_p.h @@ -317,7 +317,7 @@ private: EnabledViewRange enabledViews() const; ImportedTypeNameId importedTypeNameId(Utils::SmallStringView typeName); void setTypeId(InternalNode *node, Utils::SmallStringView typeName); - void emitRefreshMetaInfos(); + void emitRefreshMetaInfos(const TypeIds &deletedTypeIds); public: NotNullPointer projectStorage = nullptr; @@ -326,7 +326,8 @@ public: private: Model *m_model = nullptr; MetaInfo m_metaInfo; - std::function m_metaInfoRefreshCallback{[&] { emitRefreshMetaInfos(); }}; + std::function m_metaInfoRefreshCallback{ + [&](const TypeIds &deletedTypeIds) { emitRefreshMetaInfos(deletedTypeIds); }}; Imports m_imports; Imports m_possibleImportList; Imports m_usedImportList; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h index 464d0f3b443..3f47eb3f018 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h @@ -53,6 +53,7 @@ public: void synchronize(Storage::Synchronization::SynchronizationPackage package) override { + TypeIds deletedTypeIds; Sqlite::withImmediateTransaction(database, [&] { AliasPropertyDeclarations insertedAliasPropertyDeclarations; AliasPropertyDeclarations updatedAliasPropertyDeclarations; @@ -61,7 +62,6 @@ public: PropertyDeclarations relinkablePropertyDeclarations; Prototypes relinkablePrototypes; Prototypes relinkableExtensions; - TypeIds deletedTypeIds; TypeIds updatedTypeIds; updatedTypeIds.reserve(package.types.size()); @@ -111,7 +111,7 @@ public: commonTypeCache_.resetTypeIds(); }); - callRefreshMetaInfoCallback(); + callRefreshMetaInfoCallback(deletedTypeIds); } void synchronizeDocumentImports(Storage::Imports imports, SourceId sourceId) override @@ -123,12 +123,12 @@ public: }); } - void addRefreshCallback(std::function *callback) override + void addRefreshCallback(std::function *callback) override { m_refreshCallbacks.push_back(callback); } - void removeRefreshCallback(std::function *callback) override + void removeRefreshCallback(std::function *callback) override { m_refreshCallbacks.erase( std::find(m_refreshCallbacks.begin(), m_refreshCallbacks.end(), callback)); @@ -616,10 +616,10 @@ private: return selectAllModulesStatement.template valuesWithTransaction(); } - void callRefreshMetaInfoCallback() + void callRefreshMetaInfoCallback(const TypeIds &deletedTypeIds) { for (auto *callback : m_refreshCallbacks) - (*callback)(); + (*callback)(deletedTypeIds); } class AliasPropertyDeclaration @@ -2787,7 +2787,7 @@ public: Initializer initializer; mutable ModuleCache moduleCache{ModuleStorageAdapter{*this}}; Storage::Info::CommonTypeCache commonTypeCache_{*this}; - std::vector *> m_refreshCallbacks; + std::vector *> m_refreshCallbacks; ReadWriteStatement<1, 3> upsertTypeStatement{ "INSERT INTO types(sourceId, name, traits) VALUES(?1, ?2, ?3) ON CONFLICT DO " "UPDATE SET traits=excluded.traits WHERE traits IS NOT " diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h index daf4225ffab..e6962602b38 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h @@ -27,8 +27,8 @@ public: virtual void synchronize(Storage::Synchronization::SynchronizationPackage package) = 0; virtual void synchronizeDocumentImports(const Storage::Imports imports, SourceId sourceId) = 0; - virtual void addRefreshCallback(std::function *callback) = 0; - virtual void removeRefreshCallback(std::function *callback) = 0; + virtual void addRefreshCallback(std::function *callback) = 0; + virtual void removeRefreshCallback(std::function *callback) = 0; virtual ModuleId moduleId(::Utils::SmallStringView name) const = 0; virtual std::optional diff --git a/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcache.h b/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcache.h index 68327ee7cb8..424638a64d9 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcache.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcache.h @@ -3,6 +3,7 @@ #pragma once +#include "projectstorage.h" #include "projectstorageexceptions.h" #include "projectstorageids.h" #include "sourcepath.h" @@ -15,6 +16,7 @@ #include #include +#include namespace QmlDesigner { diff --git a/tests/unit/tests/mocks/abstractviewmock.h b/tests/unit/tests/mocks/abstractviewmock.h index f01c9f5f64b..d7eab46acce 100644 --- a/tests/unit/tests/mocks/abstractviewmock.h +++ b/tests/unit/tests/mocks/abstractviewmock.h @@ -56,5 +56,5 @@ public: AbstractView::PropertyChangeFlags propertyChange), (override)); MOCK_METHOD(void, nodeAboutToBeRemoved, (const QmlDesigner::ModelNode &removedNode), (override)); - MOCK_METHOD(void, refreshMetaInfos, (), (override)); + MOCK_METHOD(void, refreshMetaInfos, (const QmlDesigner::TypeIds &), (override)); }; diff --git a/tests/unit/tests/mocks/projectstoragemock.cpp b/tests/unit/tests/mocks/projectstoragemock.cpp index b2445cd82ac..ac829d21a3f 100644 --- a/tests/unit/tests/mocks/projectstoragemock.cpp +++ b/tests/unit/tests/mocks/projectstoragemock.cpp @@ -122,6 +122,16 @@ void ProjectStorageMock::addExportedTypeName(QmlDesigner::TypeId typeId, exportedTypeName[typeId].emplace_back(moduleId, typeName); } +void ProjectStorageMock::removeExportedTypeName(QmlDesigner::TypeId typeId, + QmlDesigner::ModuleId moduleId, + Utils::SmallStringView typeName) +{ + ON_CALL(*this, typeId(Eq(moduleId), Eq(typeName), _)).WillByDefault(Return(TypeId{})); + ON_CALL(*this, fetchTypeIdByModuleIdAndExportedName(Eq(moduleId), Eq(typeName))) + .WillByDefault(Return(TypeId{})); + exportedTypeName.erase(typeId); +} + PropertyDeclarationId ProjectStorageMock::createProperty(TypeId typeId, Utils::SmallString name, PropertyDeclarationTraits traits, @@ -149,6 +159,24 @@ PropertyDeclarationId ProjectStorageMock::createProperty(TypeId typeId, return propertyId; } +void ProjectStorageMock::removeProperty(QmlDesigner::TypeId typeId, Utils::SmallString name) +{ + auto propertyId = propertyDeclarationId(typeId, name); + + ON_CALL(*this, propertyDeclarationId(Eq(typeId), Eq(name))) + .WillByDefault(Return(PropertyDeclarationId{})); + ON_CALL(*this, propertyName(Eq(propertyId))) + .WillByDefault(Return(std::optional{})); + + ON_CALL(*this, propertyDeclaration(Eq(propertyId))) + .WillByDefault(Return(std::optional{})); + + ON_CALL(*this, propertyDeclarationIds(Eq(typeId))) + .WillByDefault(Return(QVarLengthArray{})); + ON_CALL(*this, localPropertyDeclarationIds(Eq(typeId))) + .WillByDefault(Return(QVarLengthArray{})); +} + QmlDesigner::PropertyDeclarationId ProjectStorageMock::createProperty( QmlDesigner::TypeId typeId, Utils::SmallString name, QmlDesigner::TypeId propertyTypeId) { @@ -187,6 +215,14 @@ void addBaseProperties(TypeId typeId, TypeIds baseTypeIds, ProjectStorageMock &s } } } + +void setType(TypeId typeId, ModuleId moduleId, Utils::SmallStringView typeName, ProjectStorageMock &storage) +{ + ON_CALL(storage, typeId(Eq(moduleId), Eq(typeName), _)).WillByDefault(Return(typeId)); + ON_CALL(storage, fetchTypeIdByModuleIdAndExportedName(Eq(moduleId), Eq(typeName))) + .WillByDefault(Return(typeId)); +} + } // namespace TypeId ProjectStorageMock::createType(ModuleId moduleId, @@ -205,13 +241,12 @@ TypeId ProjectStorageMock::createType(ModuleId moduleId, static TypeId typeId; incrementBasicId(typeId); - ON_CALL(*this, typeId(Eq(moduleId), Eq(typeName), _)).WillByDefault(Return(typeId)); - ON_CALL(*this, fetchTypeIdByModuleIdAndExportedName(Eq(moduleId), Eq(typeName))) - .WillByDefault(Return(typeId)); + setType(typeId, moduleId, typeName, *this); + + addBaseProperties(typeId, baseTypeIds, *this); + addExportedTypeName(typeId, moduleId, typeName); - ON_CALL(*this, exportedTypeNames(Eq(typeId))).WillByDefault([&](TypeId id) { - return exportedTypeName[id]; - }); + PropertyDeclarationId defaultPropertyDeclarationId; if (defaultPropertyName.size()) { if (!defaultPropertyTypeId) { @@ -225,8 +260,7 @@ TypeId ProjectStorageMock::createType(ModuleId moduleId, } ON_CALL(*this, type(Eq(typeId))) - .WillByDefault( - Return(Storage::Info::Type{defaultPropertyDeclarationId, sourceId, typeTraits})); + .WillByDefault(Return(Storage::Info::Type{defaultPropertyDeclarationId, sourceId, typeTraits})); ON_CALL(*this, isBasedOn(Eq(typeId), Eq(typeId))).WillByDefault(Return(true)); @@ -240,11 +274,20 @@ TypeId ProjectStorageMock::createType(ModuleId moduleId, ON_CALL(*this, prototypeAndSelfIds(Eq(typeId))).WillByDefault(Return(selfAndPrototypes)); ON_CALL(*this, prototypeIds(Eq(typeId))).WillByDefault(Return(baseTypeIds)); - addBaseProperties(typeId, baseTypeIds, *this); - return typeId; } +void ProjectStorageMock::removeType(QmlDesigner::ModuleId moduleId, Utils::SmallStringView typeName) +{ + auto oldTypeId = typeId(moduleId, typeName); + + setType(TypeId{}, moduleId, typeName, *this); + + removeExportedTypeName(oldTypeId, moduleId, typeName); + + ON_CALL(*this, type(Eq(oldTypeId))).WillByDefault(Return(std::optional{})); +} + QmlDesigner::TypeId ProjectStorageMock::createType(QmlDesigner::ModuleId moduleId, Utils::SmallStringView typeName, QmlDesigner::Storage::TypeTraits typeTraits, @@ -286,6 +329,13 @@ QmlDesigner::TypeId ProjectStorageMock::createValue(QmlDesigner::ModuleId module return createType(moduleId, typeName, Storage::TypeTraits::Value, baseTypeIds); } +ProjectStorageMock::ProjectStorageMock() +{ + ON_CALL(*this, exportedTypeNames(_)).WillByDefault([&](TypeId id) { + return exportedTypeName[id]; + }); +} + void ProjectStorageMock::setupQtQuick() { setupIsBasedOn(*this); diff --git a/tests/unit/tests/mocks/projectstoragemock.h b/tests/unit/tests/mocks/projectstoragemock.h index 5c189af519f..e55841f4786 100644 --- a/tests/unit/tests/mocks/projectstoragemock.h +++ b/tests/unit/tests/mocks/projectstoragemock.h @@ -16,6 +16,7 @@ class ProjectStorageMock : public QmlDesigner::ProjectStorageInterface { public: + ProjectStorageMock(); virtual ~ProjectStorageMock() = default; void setupQtQuick(); @@ -45,6 +46,10 @@ public: QmlDesigner::ModuleId moduleId, Utils::SmallStringView typeName); + void removeExportedTypeName(QmlDesigner::TypeId typeId, + QmlDesigner::ModuleId moduleId, + Utils::SmallStringView typeName); + QmlDesigner::TypeId createType(QmlDesigner::ModuleId moduleId, Utils::SmallStringView typeName, Utils::SmallStringView defaultPropertyName, @@ -54,6 +59,8 @@ public: QmlDesigner::TypeIds baseTypeIds = {}, QmlDesigner::SourceId sourceId = QmlDesigner::SourceId{}); + void removeType(QmlDesigner::ModuleId moduleId, Utils::SmallStringView typeName); + QmlDesigner::TypeId createType(QmlDesigner::ModuleId moduleId, Utils::SmallStringView typeName, QmlDesigner::Storage::TypeTraits typeTraits, @@ -87,6 +94,8 @@ public: Utils::SmallString name, QmlDesigner::TypeId propertyTypeId); + void removeProperty(QmlDesigner::TypeId typeId, Utils::SmallString name); + void createSignal(QmlDesigner::TypeId typeId, Utils::SmallString name); void createFunction(QmlDesigner::TypeId typeId, Utils::SmallString name); void setPropertyEditorPathId(QmlDesigner::TypeId typeId, QmlDesigner::SourceId sourceId); @@ -100,8 +109,14 @@ public: (const QmlDesigner::Storage::Imports imports, QmlDesigner::SourceId sourceId), (override)); - MOCK_METHOD(void, addRefreshCallback, (std::function * callback), (override)); - MOCK_METHOD(void, removeRefreshCallback, (std::function * callback), (override)); + MOCK_METHOD(void, + addRefreshCallback, + (std::function * callback), + (override)); + MOCK_METHOD(void, + removeRefreshCallback, + (std::function * callback), + (override)); MOCK_METHOD(QmlDesigner::ModuleId, moduleId, (::Utils::SmallStringView), (const, override)); diff --git a/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp b/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp index 353efb91f64..10e4cc32525 100644 --- a/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp +++ b/tests/unit/tests/unittests/componentcore/propertycomponentgenerator-test.cpp @@ -319,4 +319,56 @@ TEST_F(PropertyComponentGenerator, get_imports) Eq("import StudioTheme 1.0 as StudioTheme"))); } +TEST_F(PropertyComponentGenerator, set_model_to_null_removes_creates_only_monostates) +{ + QString expected = getExpectedContent("real", "x", "x"); + auto xProperty = itemMetaInfo.property("x"); + + generator.setModel(nullptr); + + ASSERT_THAT(generator.create(xProperty), VariantWith(std::monostate{})); +} + +TEST_F(PropertyComponentGenerator, set_model_fromn_null_updates_internal_state) +{ + generator.setModel(nullptr); + QString expected = getExpectedContent("real", "x", "x"); + auto xProperty = itemMetaInfo.property("x"); + + generator.setModel(&model); + + ASSERT_THAT(generator.create(xProperty), IsBasicProperty(StrippedStringEq(expected))); +} + +TEST_F(PropertyComponentGenerator, after_refresh_meta_infos_type_was_deleted) +{ + auto xProperty = itemMetaInfo.property("x"); + auto doubleMetaInfo = model.doubleMetaInfo(); + projectStorageMock.removeExportedTypeName(doubleMetaInfo.id(), + projectStorageMock.createModule("QML"), + "real"); + + generator.refreshMetaInfos({doubleMetaInfo.id()}); + + ASSERT_THAT(generator.create(xProperty), VariantWith(std::monostate{})); +} + +TEST_F(PropertyComponentGenerator, after_refresh_meta_infos_type_was_added) +{ + QString expected = getExpectedContent("real", "x", "x"); + auto xProperty = itemMetaInfo.property("x"); + auto doubleMetaInfo = model.doubleMetaInfo(); + projectStorageMock.removeExportedTypeName(doubleMetaInfo.id(), + projectStorageMock.createModule("QML"), + "real"); + generator.refreshMetaInfos({doubleMetaInfo.id()}); + projectStorageMock.addExportedTypeName(doubleMetaInfo.id(), + projectStorageMock.createModule("QML"), + "real"); + + generator.refreshMetaInfos({}); + + ASSERT_THAT(generator.create(xProperty), IsBasicProperty(StrippedStringEq(expected))); +} + } // namespace diff --git a/tests/unit/tests/unittests/componentcore/propertyeditorcomponentgenerator-test.cpp b/tests/unit/tests/unittests/componentcore/propertyeditorcomponentgenerator-test.cpp index d02b2b12cbc..3b9a8bbfe25 100644 --- a/tests/unit/tests/unittests/componentcore/propertyeditorcomponentgenerator-test.cpp +++ b/tests/unit/tests/unittests/componentcore/propertyeditorcomponentgenerator-test.cpp @@ -14,7 +14,7 @@ using BasicProperty = QmlDesigner::PropertyComponentGenerator::BasicProperty; using ComplexProperty = QmlDesigner::PropertyComponentGenerator::ComplexProperty; using QmlDesigner::PropertyMetaInfo; -class PropertyEditorTemplateGenerator : public ::testing::Test +class PropertyEditorComponentGenerator : public ::testing::Test { protected: QmlDesigner::NodeMetaInfo createType(Utils::SmallStringView name, @@ -85,13 +85,13 @@ protected: QmlDesigner::SourceId sourceId = QmlDesigner::SourceId::create(10); NiceMock projectStorageMock{sourceId}; NiceMock propertyGeneratorMock; - QmlDesigner::PropertyEditorTemplateGenerator generator{propertyGeneratorMock}; + QmlDesigner::PropertyEditorComponentGenerator generator{propertyGeneratorMock}; QmlDesigner::ModuleId qtQuickModuleId = projectStorageMock.createModule("QtQuick"); QmlDesigner::NodeMetaInfo fooTypeInfo = createType("Foo"); QmlDesigner::TypeId dummyTypeId = projectStorageMock.commonTypeCache().builtinTypeId(); }; -TEST_F(PropertyEditorTemplateGenerator, no_properties_and_no_imports) +TEST_F(PropertyEditorComponentGenerator, no_properties_and_no_imports) { QString expectedText{ R"xy( @@ -110,12 +110,12 @@ TEST_F(PropertyEditorTemplateGenerator, no_properties_and_no_imports) } })xy"}; - auto text = generator.create(fooTypeInfo, false); + auto text = generator.create(fooTypeInfo.selfAndPrototypes(), false); ASSERT_THAT(text, StrippedStringEq(expectedText)); } -TEST_F(PropertyEditorTemplateGenerator, properties_without_component_are_not_shows) +TEST_F(PropertyEditorComponentGenerator, properties_without_component_are_not_shows) { QString expectedText{ R"xy( @@ -135,12 +135,12 @@ TEST_F(PropertyEditorTemplateGenerator, properties_without_component_are_not_sho })xy"}; createProperty(fooTypeInfo.id(), "x", {}, dummyTypeId); - auto text = generator.create(fooTypeInfo, false); + auto text = generator.create(fooTypeInfo.selfAndPrototypes(), false); ASSERT_THAT(text, StrippedStringEq(expectedText)); } -TEST_F(PropertyEditorTemplateGenerator, show_component_button_for_a_component_node) +TEST_F(PropertyEditorComponentGenerator, show_component_button_for_a_component_node) { QString expectedText{ R"xy( @@ -160,12 +160,12 @@ TEST_F(PropertyEditorTemplateGenerator, show_component_button_for_a_component_no } })xy"}; - auto text = generator.create(fooTypeInfo, true); + auto text = generator.create(fooTypeInfo.selfAndPrototypes(), true); ASSERT_THAT(text, StrippedStringEq(expectedText)); } -TEST_F(PropertyEditorTemplateGenerator, imports) +TEST_F(PropertyEditorComponentGenerator, imports) { QString expectedText{ R"xy( @@ -187,12 +187,12 @@ TEST_F(PropertyEditorTemplateGenerator, imports) })xy"}; setImports({"import QtQtuick", "import Studio 2.1"}); - auto text = generator.create(fooTypeInfo, false); + auto text = generator.create(fooTypeInfo.selfAndPrototypes(), false); ASSERT_THAT(text, StrippedStringEq(expectedText)); } -TEST_F(PropertyEditorTemplateGenerator, basic_property) +TEST_F(PropertyEditorComponentGenerator, basic_property) { QString expectedText{ R"xy( @@ -220,12 +220,12 @@ TEST_F(PropertyEditorTemplateGenerator, basic_property) })xy"}; createBasicProperty(fooTypeInfo.id(), "value", {}, dummyTypeId, "Double{}"); - auto text = generator.create(fooTypeInfo, false); + auto text = generator.create(fooTypeInfo.selfAndPrototypes(), false); ASSERT_THAT(text, StrippedStringEq(expectedText)); } -TEST_F(PropertyEditorTemplateGenerator, basic_properties_with_base_type) +TEST_F(PropertyEditorComponentGenerator, basic_properties_with_base_type) { QString expectedText{ R"xy( @@ -256,12 +256,12 @@ TEST_F(PropertyEditorTemplateGenerator, basic_properties_with_base_type) auto superFooInfo = createType("SuperFoo", {fooTypeInfo.id()}); createBasicProperty(superFooInfo.id(), "value", {}, dummyTypeId, "SuperDouble{}"); - auto text = generator.create(superFooInfo, false); + auto text = generator.create(superFooInfo.selfAndPrototypes(), false); ASSERT_THAT(text, StrippedStringEq(expectedText)); } -TEST_F(PropertyEditorTemplateGenerator, +TEST_F(PropertyEditorComponentGenerator, only_handle_basic_properties_for_types_without_specifics_or_panes) { QString expectedText{ @@ -293,12 +293,12 @@ TEST_F(PropertyEditorTemplateGenerator, createBasicProperty(superFooInfo.id(), "value", {}, dummyTypeId, "SuperDouble{}"); projectStorageMock.setPropertyEditorPathId(fooTypeInfo.id(), sourceId); - auto text = generator.create(superFooInfo, false); + auto text = generator.create(superFooInfo.selfAndPrototypes(), false); ASSERT_THAT(text, StrippedStringEq(expectedText)); } -TEST_F(PropertyEditorTemplateGenerator, order_basic_property) +TEST_F(PropertyEditorComponentGenerator, order_basic_property) { QString expectedText{ R"xy( @@ -330,12 +330,12 @@ TEST_F(PropertyEditorTemplateGenerator, order_basic_property) createBasicProperty(fooTypeInfo.id(), "x", {}, dummyTypeId, "AnotherX{}"); createBasicProperty(fooTypeInfo.id(), "y", {}, dummyTypeId, "AndY{}"); - auto text = generator.create(fooTypeInfo, false); + auto text = generator.create(fooTypeInfo.selfAndPrototypes(), false); ASSERT_THAT(text, StrippedStringEq(expectedText)); } -TEST_F(PropertyEditorTemplateGenerator, complex_property) +TEST_F(PropertyEditorComponentGenerator, complex_property) { QString expectedText{ R"xy( @@ -356,12 +356,12 @@ TEST_F(PropertyEditorTemplateGenerator, complex_property) })xy"}; createComplexProperty(fooTypeInfo.id(), "value", {}, dummyTypeId, "Complex{}"); - auto text = generator.create(fooTypeInfo, false); + auto text = generator.create(fooTypeInfo.selfAndPrototypes(), false); ASSERT_THAT(text, StrippedStringEq(expectedText)); } -TEST_F(PropertyEditorTemplateGenerator, complex_properties_with_base_type) +TEST_F(PropertyEditorComponentGenerator, complex_properties_with_base_type) { QString expectedText{ R"xy( @@ -385,12 +385,12 @@ TEST_F(PropertyEditorTemplateGenerator, complex_properties_with_base_type) auto superFooInfo = createType("SuperFoo", {fooTypeInfo.id()}); createComplexProperty(superFooInfo.id(), "value", {}, dummyTypeId, "SuperComplex{}"); - auto text = generator.create(superFooInfo, false); + auto text = generator.create(superFooInfo.selfAndPrototypes(), false); ASSERT_THAT(text, StrippedStringEq(expectedText)); } -TEST_F(PropertyEditorTemplateGenerator, +TEST_F(PropertyEditorComponentGenerator, only_handle_complex_properties_for_types_without_specifics_or_panes) { QString expectedText{ @@ -415,12 +415,12 @@ TEST_F(PropertyEditorTemplateGenerator, createComplexProperty(superFooInfo.id(), "value", {}, dummyTypeId, "SuperComplex{}"); projectStorageMock.setPropertyEditorPathId(fooTypeInfo.id(), sourceId); - auto text = generator.create(superFooInfo, false); + auto text = generator.create(superFooInfo.selfAndPrototypes(), false); ASSERT_THAT(text, StrippedStringEq(expectedText)); } -TEST_F(PropertyEditorTemplateGenerator, ordered_complex_property) +TEST_F(PropertyEditorComponentGenerator, ordered_complex_property) { QString expectedText{ R"xy( @@ -445,12 +445,12 @@ TEST_F(PropertyEditorTemplateGenerator, ordered_complex_property) createComplexProperty(fooTypeInfo.id(), "font", {}, dummyTypeId, "ComplexFont{}"); createComplexProperty(fooTypeInfo.id(), "anchors", {}, dummyTypeId, "Anchors{}"); - auto text = generator.create(fooTypeInfo, false); + auto text = generator.create(fooTypeInfo.selfAndPrototypes(), false); ASSERT_THAT(text, StrippedStringEq(expectedText)); } -TEST_F(PropertyEditorTemplateGenerator, basic_is_placed_before_complex_components) +TEST_F(PropertyEditorComponentGenerator, basic_is_placed_before_complex_components) { QString expectedText{ R"xy( @@ -480,7 +480,7 @@ TEST_F(PropertyEditorTemplateGenerator, basic_is_placed_before_complex_component createBasicProperty(fooTypeInfo.id(), "x", {}, dummyTypeId, "Double{}"); createComplexProperty(fooTypeInfo.id(), "font", {}, dummyTypeId, "Font{}"); - auto text = generator.create(fooTypeInfo, false); + auto text = generator.create(fooTypeInfo.selfAndPrototypes(), false); ASSERT_THAT(text, StrippedStringEq(expectedText)); } diff --git a/tests/unit/tests/unittests/model/model-test.cpp b/tests/unit/tests/unittests/model/model-test.cpp index b705c15ffad..71f6462c7cc 100644 --- a/tests/unit/tests/unittests/model/model-test.cpp +++ b/tests/unit/tests/unittests/model/model-test.cpp @@ -928,14 +928,16 @@ TEST_F(Model, remove_refresh_callback_from_project_storage) TEST_F(Model, refresh_callback_is_calling_abstract_view) { - std::function *callback = nullptr; + const QmlDesigner::TypeIds typeIds = {QmlDesigner::TypeId::create(3), + QmlDesigner::TypeId::create(1)}; + std::function *callback = nullptr; ON_CALL(projectStorageMock, addRefreshCallback(_)).WillByDefault([&](auto *c) { callback = c; }); QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, "Item", -1, -1, nullptr, {}}; model.attachView(&viewMock); - EXPECT_CALL(viewMock, refreshMetaInfos()); + EXPECT_CALL(viewMock, refreshMetaInfos(typeIds)); - (*callback)(); + (*callback)(typeIds); } } // namespace diff --git a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp index 059c49e1397..14974f71232 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp @@ -7195,11 +7195,11 @@ TEST_F(ProjectStorage, synchronize_property_editor_with_non_existing_type_name) TEST_F(ProjectStorage, call_refresh_callback_after_synchronization) { auto package{createSimpleSynchronizationPackage()}; - MockFunction callbackMock; + MockFunction callbackMock; auto callback = callbackMock.AsStdFunction(); storage.addRefreshCallback(&callback); - EXPECT_CALL(callbackMock, Call()); + EXPECT_CALL(callbackMock, Call(_)); storage.synchronize(package); }