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 <ci_patchbuild_bot@qt.io>
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2023-09-07 14:49:44 +02:00
parent 95d40394da
commit ebe1c889b7
22 changed files with 387 additions and 110 deletions

View File

@@ -575,6 +575,9 @@ extend_qtc_plugin(QmlDesigner
modelnodeoperations.cpp modelnodeoperations.h modelnodeoperations.cpp modelnodeoperations.h
formatoperation.cpp formatoperation.h formatoperation.cpp formatoperation.h
navigation2d.cpp navigation2d.h navigation2d.cpp navigation2d.h
propertyeditorcomponentgenerator.cpp propertyeditorcomponentgenerator.h
propertycomponentgenerator.cpp propertycomponentgenerator.h
propertycomponentgeneratorinterface.h
qmldesignericonprovider.cpp qmldesignericonprovider.h qmldesignericonprovider.cpp qmldesignericonprovider.h
qmleditormenu.cpp qmleditormenu.h qmleditormenu.cpp qmleditormenu.h
selectioncontext.cpp selectioncontext.h selectioncontext.cpp selectioncontext.h

View File

@@ -5,6 +5,7 @@
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/set_algorithm.h>
#include <model.h> #include <model.h>
@@ -205,10 +206,10 @@ std::optional<PropertyComponentGenerator::Entry> createEntry(QmlJS::SimpleReader
needsTypeArg}; needsTypeArg};
} }
PropertyComponentGenerator::Entries createEntries(QmlJS::SimpleReaderNode::Ptr templateConfiguration, std::tuple<PropertyComponentGenerator::Entries, bool> createEntries(
Model *model, QmlJS::SimpleReaderNode::Ptr templateConfiguration, Model *model, const QString &templatesPath)
const QString &templatesPath)
{ {
bool hasInvalidTemplates = false;
PropertyComponentGenerator::Entries entries; PropertyComponentGenerator::Entries entries;
entries.reserve(32); entries.reserve(32);
@@ -216,12 +217,14 @@ PropertyComponentGenerator::Entries createEntries(QmlJS::SimpleReaderNode::Ptr t
for (const QmlJS::SimpleReaderNode::Ptr &node : nodes) { for (const QmlJS::SimpleReaderNode::Ptr &node : nodes) {
if (auto entry = createEntry(node.get(), model, templatesPath)) if (auto entry = createEntry(node.get(), model, templatesPath))
entries.push_back(*entry); 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"); auto property = templateConfiguration->property("imports");
return Utils::transform<QStringList>(property.value.toList(), return Utils::transform<QStringList>(property.value.toList(),
@@ -232,17 +235,11 @@ QStringList createImports(QmlJS::SimpleReaderNode::Ptr templateConfiguration)
PropertyComponentGenerator::PropertyComponentGenerator(const QString &propertyEditorResourcesPath, PropertyComponentGenerator::PropertyComponentGenerator(const QString &propertyEditorResourcesPath,
Model *model) Model *model)
: m_entries(createEntries(createTemplateConfiguration(propertyEditorResourcesPath), : m_templateConfiguration{createTemplateConfiguration(propertyEditorResourcesPath)}
model, , m_propertyTemplatesPath{propertyEditorResourcesPath + "/PropertyTemplates/"}
propertyEditorResourcesPath + "/PropertyTemplates/"))
{ {
auto templateConfiguration = createTemplateConfiguration(propertyEditorResourcesPath); setModel(model);
m_imports = createImports(m_templateConfiguration.get());
m_entries = createEntries(templateConfiguration,
model,
propertyEditorResourcesPath + "/PropertyTemplates/");
m_imports = createImports(templateConfiguration);
} }
PropertyComponentGenerator::Property PropertyComponentGenerator::create(const PropertyMetaInfo &property) const PropertyComponentGenerator::Property PropertyComponentGenerator::create(const PropertyMetaInfo &property) const
@@ -257,6 +254,61 @@ PropertyComponentGenerator::Property PropertyComponentGenerator::create(const Pr
return generateComplexComponent(property, propertyType); 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<TypeIds>(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 const PropertyComponentGenerator::Entry *PropertyComponentGenerator::findEntry(const NodeMetaInfo &type) const
{ {
auto found = std::find_if(m_entries.begin(), m_entries.end(), [&](const auto &entry) { auto found = std::find_if(m_entries.begin(), m_entries.end(), [&](const auto &entry) {

View File

@@ -10,6 +10,8 @@
#include <qmljs/qmljssimplereader.h> #include <qmljs/qmljssimplereader.h>
#include <QPointer>
#include <optional> #include <optional>
#include <variant> #include <variant>
#include <vector> #include <vector>
@@ -36,6 +38,10 @@ public:
QStringList imports() const override { return m_imports; } QStringList imports() const override { return m_imports; }
void setModel(Model *model);
void refreshMetaInfos(const TypeIds &deletedTypeIds);
private: private:
const Entry *findEntry(const NodeMetaInfo &type) const; const Entry *findEntry(const NodeMetaInfo &type) const;
QString generateSubComponentText(Utils::SmallStringView propertyBaseName, QString generateSubComponentText(Utils::SmallStringView propertyBaseName,
@@ -45,9 +51,18 @@ private:
Property generateComplexComponent(const PropertyMetaInfo &property, Property generateComplexComponent(const PropertyMetaInfo &property,
const NodeMetaInfo &propertyType) const; const NodeMetaInfo &propertyType) const;
void setEntries(QmlJS::SimpleReaderNode::Ptr templateConfiguration,
Model *model,
const QString &propertyTemplatesPath);
private: private:
Entries m_entries; Entries m_entries;
TypeIds m_entryTypeIds;
QStringList m_imports; QStringList m_imports;
QPointer<Model> m_model;
QmlJS::SimpleReaderNode::Ptr m_templateConfiguration;
QString m_propertyTemplatesPath;
bool m_hasInvalidTemplates = false;
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -75,13 +75,11 @@ Utils::SmallStringView propertyName(const GeneratorProperty &property)
property); property);
} }
PropertyMetaInfos getUnmangedProperties(const NodeMetaInfo &nodeInfo) PropertyMetaInfos getUnmangedProperties(const NodeMetaInfos &prototypes)
{ {
PropertyMetaInfos properties; PropertyMetaInfos properties;
properties.reserve(128); properties.reserve(128);
auto prototypes = nodeInfo.selfAndPrototypes();
for (const auto &prototype : prototypes) { for (const auto &prototype : prototypes) {
if (prototype.propertyEditorPathId()) if (prototype.propertyEditorPathId())
break; break;
@@ -117,12 +115,12 @@ GeneratorProperties createSortedGeneratorProperties(
} }
QString createPropertySections(const PropertyComponentGeneratorType &propertyGenerator, QString createPropertySections(const PropertyComponentGeneratorType &propertyGenerator,
const NodeMetaInfo &nodeInfo) const NodeMetaInfos &prototypeChain)
{ {
QString propertyComponents; QString propertyComponents;
propertyComponents.reserve(100000); propertyComponents.reserve(100000);
auto generatorProperties = createSortedGeneratorProperties(getUnmangedProperties(nodeInfo), auto generatorProperties = createSortedGeneratorProperties(getUnmangedProperties(prototypeChain),
propertyGenerator); propertyGenerator);
const auto begin = generatorProperties.begin(); const auto begin = generatorProperties.begin();
@@ -143,12 +141,12 @@ QString createPropertySections(const PropertyComponentGeneratorType &propertyGen
} // namespace } // namespace
PropertyEditorTemplateGenerator::PropertyEditorTemplateGenerator( PropertyEditorComponentGenerator::PropertyEditorComponentGenerator(
const PropertyComponentGeneratorType &propertyGenerator) const PropertyComponentGeneratorType &propertyGenerator)
: m_propertyGenerator{propertyGenerator} : m_propertyGenerator{propertyGenerator}
{} {}
QString PropertyEditorTemplateGenerator::create(const NodeMetaInfo &nodeInfo, bool isComponent) QString PropertyEditorComponentGenerator::create(const NodeMetaInfos &prototypeChain, bool isComponent)
{ {
return QString{R"xy( return QString{R"xy(
%1 %1
@@ -171,7 +169,7 @@ QString PropertyEditorTemplateGenerator::create(const NodeMetaInfo &nodeInfo, bo
.arg(createImports(m_propertyGenerator.imports()), .arg(createImports(m_propertyGenerator.imports()),
componentButton(isComponent), componentButton(isComponent),
QObject::tr("Exposed Custom Properties"), QObject::tr("Exposed Custom Properties"),
createPropertySections(m_propertyGenerator, nodeInfo)); createPropertySections(m_propertyGenerator, prototypeChain));
} }
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -14,13 +14,13 @@ using PropertyComponentGeneratorType = PropertyComponentGeneratorInterface;
#else #else
using PropertyComponentGeneratorType = PropertyComponentGenerator; using PropertyComponentGeneratorType = PropertyComponentGenerator;
#endif #endif
class PropertyEditorTemplateGenerator class PropertyEditorComponentGenerator
{ {
public: 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: private:
const PropertyComponentGeneratorType &m_propertyGenerator; const PropertyComponentGeneratorType &m_propertyGenerator;

View File

@@ -20,6 +20,7 @@
#include <bindingproperty.h> #include <bindingproperty.h>
#include <nodeabstractproperty.h> #include <nodeabstractproperty.h>
#include <projectstorage/sourcepathcache.h>
#include <theme.h> #include <theme.h>
@@ -65,6 +66,8 @@ PropertyEditorView::PropertyEditorView(AsynchronousImageCache &imageCache,
, m_timerId(0) , m_timerId(0)
, m_stackedWidget(new PropertyEditorWidget()) , m_stackedWidget(new PropertyEditorWidget())
, m_qmlBackEndForCurrentType(nullptr) , m_qmlBackEndForCurrentType(nullptr)
, m_propertyComponentGenerator{QmlDesigner::PropertyEditorQmlBackend::propertyEditorResourcesPath(),
model()}
, m_locked(false) , m_locked(false)
, m_setupCompleted(false) , m_setupCompleted(false)
, m_singleShotTimer(new QTimer(this)) , m_singleShotTimer(new QTimer(this))
@@ -373,6 +376,11 @@ void PropertyEditorView::currentTimelineChanged(const ModelNode &)
m_qmlBackEndForCurrentType->contextObject()->setHasActiveTimeline(QmlTimeline::hasActiveTimeline(this)); m_qmlBackEndForCurrentType->contextObject()->setHasActiveTimeline(QmlTimeline::hasActiveTimeline(this));
} }
void PropertyEditorView::refreshMetaInfos(const TypeIds &deletedTypeIds)
{
m_propertyComponentGenerator.refreshMetaInfos(deletedTypeIds);
}
void PropertyEditorView::updateSize() void PropertyEditorView::updateSize()
{ {
if (!m_qmlBackEndForCurrentType) if (!m_qmlBackEndForCurrentType)
@@ -439,8 +447,8 @@ void PropertyEditorView::resetView()
namespace { namespace {
std::tuple<NodeMetaInfo, QUrl> diffType(const NodeMetaInfo &commonAncestor, [[maybe_unused]] std::tuple<NodeMetaInfo, QUrl> diffType(const NodeMetaInfo &commonAncestor,
const NodeMetaInfo &specificsClassMetaInfo) const NodeMetaInfo &specificsClassMetaInfo)
{ {
NodeMetaInfo diffClassMetaInfo; NodeMetaInfo diffClassMetaInfo;
QUrl qmlSpecificsFile; QUrl qmlSpecificsFile;
@@ -463,9 +471,9 @@ std::tuple<NodeMetaInfo, QUrl> diffType(const NodeMetaInfo &commonAncestor,
return {diffClassMetaInfo, qmlSpecificsFile}; return {diffClassMetaInfo, qmlSpecificsFile};
} }
QString getSpecificQmlData(const NodeMetaInfo &commonAncestor, [[maybe_unused]] QString getSpecificQmlData(const NodeMetaInfo &commonAncestor,
const ModelNode &selectedNode, const ModelNode &selectedNode,
const NodeMetaInfo &diffClassMetaInfo) const NodeMetaInfo &diffClassMetaInfo)
{ {
if (commonAncestor.isValid() && diffClassMetaInfo != selectedNode.metaInfo()) if (commonAncestor.isValid() && diffClassMetaInfo != selectedNode.metaInfo())
return PropertyEditorQmlBackend::templateGeneration(commonAncestor, return PropertyEditorQmlBackend::templateGeneration(commonAncestor,
@@ -534,33 +542,90 @@ void setupWidget(PropertyEditorQmlBackend *currentQmlBackend,
stackedWidget->setCurrentWidget(currentQmlBackend->widget()); stackedWidget->setCurrentWidget(currentQmlBackend->widget());
currentQmlBackend->contextObject()->triggerSelectionChanged(); 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 } // namespace
void PropertyEditorView::setupQmlBackend() 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( setupCurrentQmlBackend(currentQmlBackend,
commonAncestor); 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, setupInsight(rootModelNode(), currentQmlBackend);
qmlFileUrl, } else {
m_imageCache, const NodeMetaInfo commonAncestor = PropertyEditorQmlBackend::findCommonAncestor(
m_stackedWidget, m_selectedNode);
this);
setupCurrentQmlBackend( const auto [qmlFileUrl, specificsClassMetaInfo] = PropertyEditorQmlBackend::getQmlUrlForMetaInfo(
currentQmlBackend, m_selectedNode, qmlSpecificsFile, currentState(), this, specificQmlData); 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) void PropertyEditorView::commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value)
@@ -646,6 +711,9 @@ void PropertyEditorView::modelAttached(Model *model)
{ {
AbstractView::modelAttached(model); AbstractView::modelAttached(model);
if constexpr (useProjectStorage())
m_propertyComponentGenerator.setModel(model);
if (debug) if (debug)
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;

View File

@@ -9,6 +9,7 @@
#include <QObject> #include <QObject>
#include <QTimer> #include <QTimer>
#include <propertyeditorcomponentgenerator.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QEvent; class QEvent;
@@ -81,6 +82,8 @@ public:
void currentTimelineChanged(const ModelNode &node) override; void currentTimelineChanged(const ModelNode &node) override;
void refreshMetaInfos(const TypeIds &deletedTypeIds) override;
protected: protected:
void timerEvent(QTimerEvent *event) override; void timerEvent(QTimerEvent *event) override;
void setupPane(const TypeName &typeName); void setupPane(const TypeName &typeName);
@@ -113,6 +116,8 @@ private: //variables
QString m_qmlDir; QString m_qmlDir;
QHash<QString, PropertyEditorQmlBackend *> m_qmlBackendHash; QHash<QString, PropertyEditorQmlBackend *> m_qmlBackendHash;
PropertyEditorQmlBackend *m_qmlBackEndForCurrentType; PropertyEditorQmlBackend *m_qmlBackEndForCurrentType;
PropertyComponentGenerator m_propertyComponentGenerator;
PropertyEditorComponentGenerator m_propertyEditorComponentGenerator{m_propertyComponentGenerator};
bool m_locked; bool m_locked;
bool m_setupCompleted; bool m_setupCompleted;
QTimer *m_singleShotTimer; QTimer *m_singleShotTimer;

View File

@@ -148,7 +148,7 @@ public:
virtual void modelAttached(Model *model); virtual void modelAttached(Model *model);
virtual void modelAboutToBeDetached(Model *model); virtual void modelAboutToBeDetached(Model *model);
virtual void refreshMetaInfos(); virtual void refreshMetaInfos(const TypeIds &deletedTypeIds);
virtual void nodeCreated(const ModelNode &createdNode); virtual void nodeCreated(const ModelNode &createdNode);
virtual void nodeAboutToBeRemoved(const ModelNode &removedNode); virtual void nodeAboutToBeRemoved(const ModelNode &removedNode);

View File

@@ -136,6 +136,7 @@ public:
void setMetaInfo(const MetaInfo &metaInfo); void setMetaInfo(const MetaInfo &metaInfo);
NodeMetaInfo boolMetaInfo() const; NodeMetaInfo boolMetaInfo() const;
NodeMetaInfo doubleMetaInfo() const;
NodeMetaInfo flowViewFlowActionAreaMetaInfo() const; NodeMetaInfo flowViewFlowActionAreaMetaInfo() const;
NodeMetaInfo flowViewFlowDecisionMetaInfo() const; NodeMetaInfo flowViewFlowDecisionMetaInfo() const;
NodeMetaInfo flowViewFlowItemMetaInfo() const; NodeMetaInfo flowViewFlowItemMetaInfo() const;

View File

@@ -164,7 +164,7 @@ void AbstractView::modelAboutToBeDetached(Model *)
removeModel(); removeModel();
} }
void AbstractView::refreshMetaInfos() {} void AbstractView::refreshMetaInfos(const TypeIds &) {}
/*! /*!
\enum QmlDesigner::AbstractView::PropertyChangeFlag \enum QmlDesigner::AbstractView::PropertyChangeFlag

View File

@@ -83,7 +83,8 @@ ModelPrivate::ModelPrivate(Model *model,
m_currentStateNode = m_rootInternalNode; m_currentStateNode = m_rootInternalNode;
m_currentTimelineNode = m_rootInternalNode; m_currentTimelineNode = m_rootInternalNode;
projectStorage->addRefreshCallback(&m_metaInfoRefreshCallback); if constexpr (useProjectStorage())
projectStorage->addRefreshCallback(&m_metaInfoRefreshCallback);
} }
ModelPrivate::ModelPrivate(Model *model, ModelPrivate::ModelPrivate(Model *model,
@@ -106,7 +107,8 @@ ModelPrivate::ModelPrivate(Model *model,
m_currentStateNode = m_rootInternalNode; m_currentStateNode = m_rootInternalNode;
m_currentTimelineNode = m_rootInternalNode; m_currentTimelineNode = m_rootInternalNode;
projectStorage->addRefreshCallback(&m_metaInfoRefreshCallback); if constexpr (useProjectStorage())
projectStorage->addRefreshCallback(&m_metaInfoRefreshCallback);
} }
ModelPrivate::ModelPrivate(Model *model, ModelPrivate::ModelPrivate(Model *model,
@@ -129,7 +131,8 @@ ModelPrivate::ModelPrivate(Model *model,
ModelPrivate::~ModelPrivate() ModelPrivate::~ModelPrivate()
{ {
projectStorage->removeRefreshCallback(&m_metaInfoRefreshCallback); if constexpr (useProjectStorage())
projectStorage->removeRefreshCallback(&m_metaInfoRefreshCallback);
}; };
void ModelPrivate::detachAllViews() 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) 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<QML, DoubleType>();
} else {
return metaInfo("QML.double");
}
}
template<const auto &moduleName, const auto &typeName> template<const auto &moduleName, const auto &typeName>
NodeMetaInfo Model::createNodeMetaInfo() const NodeMetaInfo Model::createNodeMetaInfo() const
{ {

View File

@@ -317,7 +317,7 @@ private:
EnabledViewRange enabledViews() const; EnabledViewRange enabledViews() const;
ImportedTypeNameId importedTypeNameId(Utils::SmallStringView typeName); ImportedTypeNameId importedTypeNameId(Utils::SmallStringView typeName);
void setTypeId(InternalNode *node, Utils::SmallStringView typeName); void setTypeId(InternalNode *node, Utils::SmallStringView typeName);
void emitRefreshMetaInfos(); void emitRefreshMetaInfos(const TypeIds &deletedTypeIds);
public: public:
NotNullPointer<ProjectStorageType> projectStorage = nullptr; NotNullPointer<ProjectStorageType> projectStorage = nullptr;
@@ -326,7 +326,8 @@ public:
private: private:
Model *m_model = nullptr; Model *m_model = nullptr;
MetaInfo m_metaInfo; MetaInfo m_metaInfo;
std::function<void()> m_metaInfoRefreshCallback{[&] { emitRefreshMetaInfos(); }}; std::function<void(const TypeIds &deletedTypeIds)> m_metaInfoRefreshCallback{
[&](const TypeIds &deletedTypeIds) { emitRefreshMetaInfos(deletedTypeIds); }};
Imports m_imports; Imports m_imports;
Imports m_possibleImportList; Imports m_possibleImportList;
Imports m_usedImportList; Imports m_usedImportList;

View File

@@ -53,6 +53,7 @@ public:
void synchronize(Storage::Synchronization::SynchronizationPackage package) override void synchronize(Storage::Synchronization::SynchronizationPackage package) override
{ {
TypeIds deletedTypeIds;
Sqlite::withImmediateTransaction(database, [&] { Sqlite::withImmediateTransaction(database, [&] {
AliasPropertyDeclarations insertedAliasPropertyDeclarations; AliasPropertyDeclarations insertedAliasPropertyDeclarations;
AliasPropertyDeclarations updatedAliasPropertyDeclarations; AliasPropertyDeclarations updatedAliasPropertyDeclarations;
@@ -61,7 +62,6 @@ public:
PropertyDeclarations relinkablePropertyDeclarations; PropertyDeclarations relinkablePropertyDeclarations;
Prototypes relinkablePrototypes; Prototypes relinkablePrototypes;
Prototypes relinkableExtensions; Prototypes relinkableExtensions;
TypeIds deletedTypeIds;
TypeIds updatedTypeIds; TypeIds updatedTypeIds;
updatedTypeIds.reserve(package.types.size()); updatedTypeIds.reserve(package.types.size());
@@ -111,7 +111,7 @@ public:
commonTypeCache_.resetTypeIds(); commonTypeCache_.resetTypeIds();
}); });
callRefreshMetaInfoCallback(); callRefreshMetaInfoCallback(deletedTypeIds);
} }
void synchronizeDocumentImports(Storage::Imports imports, SourceId sourceId) override void synchronizeDocumentImports(Storage::Imports imports, SourceId sourceId) override
@@ -123,12 +123,12 @@ public:
}); });
} }
void addRefreshCallback(std::function<void()> *callback) override void addRefreshCallback(std::function<void(const TypeIds &deletedTypeIds)> *callback) override
{ {
m_refreshCallbacks.push_back(callback); m_refreshCallbacks.push_back(callback);
} }
void removeRefreshCallback(std::function<void()> *callback) override void removeRefreshCallback(std::function<void(const TypeIds &deletedTypeIds)> *callback) override
{ {
m_refreshCallbacks.erase( m_refreshCallbacks.erase(
std::find(m_refreshCallbacks.begin(), m_refreshCallbacks.end(), callback)); std::find(m_refreshCallbacks.begin(), m_refreshCallbacks.end(), callback));
@@ -616,10 +616,10 @@ private:
return selectAllModulesStatement.template valuesWithTransaction<Module, 128>(); return selectAllModulesStatement.template valuesWithTransaction<Module, 128>();
} }
void callRefreshMetaInfoCallback() void callRefreshMetaInfoCallback(const TypeIds &deletedTypeIds)
{ {
for (auto *callback : m_refreshCallbacks) for (auto *callback : m_refreshCallbacks)
(*callback)(); (*callback)(deletedTypeIds);
} }
class AliasPropertyDeclaration class AliasPropertyDeclaration
@@ -2787,7 +2787,7 @@ public:
Initializer initializer; Initializer initializer;
mutable ModuleCache moduleCache{ModuleStorageAdapter{*this}}; mutable ModuleCache moduleCache{ModuleStorageAdapter{*this}};
Storage::Info::CommonTypeCache<ProjectStorageInterface> commonTypeCache_{*this}; Storage::Info::CommonTypeCache<ProjectStorageInterface> commonTypeCache_{*this};
std::vector<std::function<void()> *> m_refreshCallbacks; std::vector<std::function<void(const TypeIds &deletedTypeIds)> *> m_refreshCallbacks;
ReadWriteStatement<1, 3> upsertTypeStatement{ ReadWriteStatement<1, 3> upsertTypeStatement{
"INSERT INTO types(sourceId, name, traits) VALUES(?1, ?2, ?3) ON CONFLICT DO " "INSERT INTO types(sourceId, name, traits) VALUES(?1, ?2, ?3) ON CONFLICT DO "
"UPDATE SET traits=excluded.traits WHERE traits IS NOT " "UPDATE SET traits=excluded.traits WHERE traits IS NOT "

View File

@@ -27,8 +27,8 @@ public:
virtual void synchronize(Storage::Synchronization::SynchronizationPackage package) = 0; virtual void synchronize(Storage::Synchronization::SynchronizationPackage package) = 0;
virtual void synchronizeDocumentImports(const Storage::Imports imports, SourceId sourceId) = 0; virtual void synchronizeDocumentImports(const Storage::Imports imports, SourceId sourceId) = 0;
virtual void addRefreshCallback(std::function<void()> *callback) = 0; virtual void addRefreshCallback(std::function<void(const TypeIds &deletedTypeIds)> *callback) = 0;
virtual void removeRefreshCallback(std::function<void()> *callback) = 0; virtual void removeRefreshCallback(std::function<void(const TypeIds &deletedTypeIds)> *callback) = 0;
virtual ModuleId moduleId(::Utils::SmallStringView name) const = 0; virtual ModuleId moduleId(::Utils::SmallStringView name) const = 0;
virtual std::optional<Storage::Info::PropertyDeclaration> virtual std::optional<Storage::Info::PropertyDeclaration>

View File

@@ -3,6 +3,7 @@
#pragma once #pragma once
#include "projectstorage.h"
#include "projectstorageexceptions.h" #include "projectstorageexceptions.h"
#include "projectstorageids.h" #include "projectstorageids.h"
#include "sourcepath.h" #include "sourcepath.h"
@@ -15,6 +16,7 @@
#include <sqlitetransaction.h> #include <sqlitetransaction.h>
#include <algorithm> #include <algorithm>
#include <utility>
namespace QmlDesigner { namespace QmlDesigner {

View File

@@ -56,5 +56,5 @@ public:
AbstractView::PropertyChangeFlags propertyChange), AbstractView::PropertyChangeFlags propertyChange),
(override)); (override));
MOCK_METHOD(void, nodeAboutToBeRemoved, (const QmlDesigner::ModelNode &removedNode), (override)); MOCK_METHOD(void, nodeAboutToBeRemoved, (const QmlDesigner::ModelNode &removedNode), (override));
MOCK_METHOD(void, refreshMetaInfos, (), (override)); MOCK_METHOD(void, refreshMetaInfos, (const QmlDesigner::TypeIds &), (override));
}; };

View File

@@ -122,6 +122,16 @@ void ProjectStorageMock::addExportedTypeName(QmlDesigner::TypeId typeId,
exportedTypeName[typeId].emplace_back(moduleId, typeName); 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, PropertyDeclarationId ProjectStorageMock::createProperty(TypeId typeId,
Utils::SmallString name, Utils::SmallString name,
PropertyDeclarationTraits traits, PropertyDeclarationTraits traits,
@@ -149,6 +159,24 @@ PropertyDeclarationId ProjectStorageMock::createProperty(TypeId typeId,
return propertyId; 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<Utils::SmallString>{}));
ON_CALL(*this, propertyDeclaration(Eq(propertyId)))
.WillByDefault(Return(std::optional<QmlDesigner::Storage::Info::PropertyDeclaration>{}));
ON_CALL(*this, propertyDeclarationIds(Eq(typeId)))
.WillByDefault(Return(QVarLengthArray<PropertyDeclarationId, 128>{}));
ON_CALL(*this, localPropertyDeclarationIds(Eq(typeId)))
.WillByDefault(Return(QVarLengthArray<PropertyDeclarationId, 128>{}));
}
QmlDesigner::PropertyDeclarationId ProjectStorageMock::createProperty( QmlDesigner::PropertyDeclarationId ProjectStorageMock::createProperty(
QmlDesigner::TypeId typeId, Utils::SmallString name, QmlDesigner::TypeId propertyTypeId) 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 } // namespace
TypeId ProjectStorageMock::createType(ModuleId moduleId, TypeId ProjectStorageMock::createType(ModuleId moduleId,
@@ -205,13 +241,12 @@ TypeId ProjectStorageMock::createType(ModuleId moduleId,
static TypeId typeId; static TypeId typeId;
incrementBasicId(typeId); incrementBasicId(typeId);
ON_CALL(*this, typeId(Eq(moduleId), Eq(typeName), _)).WillByDefault(Return(typeId)); setType(typeId, moduleId, typeName, *this);
ON_CALL(*this, fetchTypeIdByModuleIdAndExportedName(Eq(moduleId), Eq(typeName)))
.WillByDefault(Return(typeId)); addBaseProperties(typeId, baseTypeIds, *this);
addExportedTypeName(typeId, moduleId, typeName); addExportedTypeName(typeId, moduleId, typeName);
ON_CALL(*this, exportedTypeNames(Eq(typeId))).WillByDefault([&](TypeId id) {
return exportedTypeName[id];
});
PropertyDeclarationId defaultPropertyDeclarationId; PropertyDeclarationId defaultPropertyDeclarationId;
if (defaultPropertyName.size()) { if (defaultPropertyName.size()) {
if (!defaultPropertyTypeId) { if (!defaultPropertyTypeId) {
@@ -225,8 +260,7 @@ TypeId ProjectStorageMock::createType(ModuleId moduleId,
} }
ON_CALL(*this, type(Eq(typeId))) ON_CALL(*this, type(Eq(typeId)))
.WillByDefault( .WillByDefault(Return(Storage::Info::Type{defaultPropertyDeclarationId, sourceId, typeTraits}));
Return(Storage::Info::Type{defaultPropertyDeclarationId, sourceId, typeTraits}));
ON_CALL(*this, isBasedOn(Eq(typeId), Eq(typeId))).WillByDefault(Return(true)); 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, prototypeAndSelfIds(Eq(typeId))).WillByDefault(Return(selfAndPrototypes));
ON_CALL(*this, prototypeIds(Eq(typeId))).WillByDefault(Return(baseTypeIds)); ON_CALL(*this, prototypeIds(Eq(typeId))).WillByDefault(Return(baseTypeIds));
addBaseProperties(typeId, baseTypeIds, *this);
return typeId; 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<Storage::Info::Type>{}));
}
QmlDesigner::TypeId ProjectStorageMock::createType(QmlDesigner::ModuleId moduleId, QmlDesigner::TypeId ProjectStorageMock::createType(QmlDesigner::ModuleId moduleId,
Utils::SmallStringView typeName, Utils::SmallStringView typeName,
QmlDesigner::Storage::TypeTraits typeTraits, QmlDesigner::Storage::TypeTraits typeTraits,
@@ -286,6 +329,13 @@ QmlDesigner::TypeId ProjectStorageMock::createValue(QmlDesigner::ModuleId module
return createType(moduleId, typeName, Storage::TypeTraits::Value, baseTypeIds); return createType(moduleId, typeName, Storage::TypeTraits::Value, baseTypeIds);
} }
ProjectStorageMock::ProjectStorageMock()
{
ON_CALL(*this, exportedTypeNames(_)).WillByDefault([&](TypeId id) {
return exportedTypeName[id];
});
}
void ProjectStorageMock::setupQtQuick() void ProjectStorageMock::setupQtQuick()
{ {
setupIsBasedOn(*this); setupIsBasedOn(*this);

View File

@@ -16,6 +16,7 @@
class ProjectStorageMock : public QmlDesigner::ProjectStorageInterface class ProjectStorageMock : public QmlDesigner::ProjectStorageInterface
{ {
public: public:
ProjectStorageMock();
virtual ~ProjectStorageMock() = default; virtual ~ProjectStorageMock() = default;
void setupQtQuick(); void setupQtQuick();
@@ -45,6 +46,10 @@ public:
QmlDesigner::ModuleId moduleId, QmlDesigner::ModuleId moduleId,
Utils::SmallStringView typeName); Utils::SmallStringView typeName);
void removeExportedTypeName(QmlDesigner::TypeId typeId,
QmlDesigner::ModuleId moduleId,
Utils::SmallStringView typeName);
QmlDesigner::TypeId createType(QmlDesigner::ModuleId moduleId, QmlDesigner::TypeId createType(QmlDesigner::ModuleId moduleId,
Utils::SmallStringView typeName, Utils::SmallStringView typeName,
Utils::SmallStringView defaultPropertyName, Utils::SmallStringView defaultPropertyName,
@@ -54,6 +59,8 @@ public:
QmlDesigner::TypeIds baseTypeIds = {}, QmlDesigner::TypeIds baseTypeIds = {},
QmlDesigner::SourceId sourceId = QmlDesigner::SourceId{}); QmlDesigner::SourceId sourceId = QmlDesigner::SourceId{});
void removeType(QmlDesigner::ModuleId moduleId, Utils::SmallStringView typeName);
QmlDesigner::TypeId createType(QmlDesigner::ModuleId moduleId, QmlDesigner::TypeId createType(QmlDesigner::ModuleId moduleId,
Utils::SmallStringView typeName, Utils::SmallStringView typeName,
QmlDesigner::Storage::TypeTraits typeTraits, QmlDesigner::Storage::TypeTraits typeTraits,
@@ -87,6 +94,8 @@ public:
Utils::SmallString name, Utils::SmallString name,
QmlDesigner::TypeId propertyTypeId); QmlDesigner::TypeId propertyTypeId);
void removeProperty(QmlDesigner::TypeId typeId, Utils::SmallString name);
void createSignal(QmlDesigner::TypeId typeId, Utils::SmallString name); void createSignal(QmlDesigner::TypeId typeId, Utils::SmallString name);
void createFunction(QmlDesigner::TypeId typeId, Utils::SmallString name); void createFunction(QmlDesigner::TypeId typeId, Utils::SmallString name);
void setPropertyEditorPathId(QmlDesigner::TypeId typeId, QmlDesigner::SourceId sourceId); void setPropertyEditorPathId(QmlDesigner::TypeId typeId, QmlDesigner::SourceId sourceId);
@@ -100,8 +109,14 @@ public:
(const QmlDesigner::Storage::Imports imports, QmlDesigner::SourceId sourceId), (const QmlDesigner::Storage::Imports imports, QmlDesigner::SourceId sourceId),
(override)); (override));
MOCK_METHOD(void, addRefreshCallback, (std::function<void()> * callback), (override)); MOCK_METHOD(void,
MOCK_METHOD(void, removeRefreshCallback, (std::function<void()> * callback), (override)); addRefreshCallback,
(std::function<void(const QmlDesigner::TypeIds &)> * callback),
(override));
MOCK_METHOD(void,
removeRefreshCallback,
(std::function<void(const QmlDesigner::TypeIds &)> * callback),
(override));
MOCK_METHOD(QmlDesigner::ModuleId, moduleId, (::Utils::SmallStringView), (const, override)); MOCK_METHOD(QmlDesigner::ModuleId, moduleId, (::Utils::SmallStringView), (const, override));

View File

@@ -319,4 +319,56 @@ TEST_F(PropertyComponentGenerator, get_imports)
Eq("import StudioTheme 1.0 as StudioTheme"))); 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>(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>(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 } // namespace

View File

@@ -14,7 +14,7 @@ using BasicProperty = QmlDesigner::PropertyComponentGenerator::BasicProperty;
using ComplexProperty = QmlDesigner::PropertyComponentGenerator::ComplexProperty; using ComplexProperty = QmlDesigner::PropertyComponentGenerator::ComplexProperty;
using QmlDesigner::PropertyMetaInfo; using QmlDesigner::PropertyMetaInfo;
class PropertyEditorTemplateGenerator : public ::testing::Test class PropertyEditorComponentGenerator : public ::testing::Test
{ {
protected: protected:
QmlDesigner::NodeMetaInfo createType(Utils::SmallStringView name, QmlDesigner::NodeMetaInfo createType(Utils::SmallStringView name,
@@ -85,13 +85,13 @@ protected:
QmlDesigner::SourceId sourceId = QmlDesigner::SourceId::create(10); QmlDesigner::SourceId sourceId = QmlDesigner::SourceId::create(10);
NiceMock<ProjectStorageMockWithQtQtuick> projectStorageMock{sourceId}; NiceMock<ProjectStorageMockWithQtQtuick> projectStorageMock{sourceId};
NiceMock<PropertyComponentGeneratorMock> propertyGeneratorMock; NiceMock<PropertyComponentGeneratorMock> propertyGeneratorMock;
QmlDesigner::PropertyEditorTemplateGenerator generator{propertyGeneratorMock}; QmlDesigner::PropertyEditorComponentGenerator generator{propertyGeneratorMock};
QmlDesigner::ModuleId qtQuickModuleId = projectStorageMock.createModule("QtQuick"); QmlDesigner::ModuleId qtQuickModuleId = projectStorageMock.createModule("QtQuick");
QmlDesigner::NodeMetaInfo fooTypeInfo = createType("Foo"); QmlDesigner::NodeMetaInfo fooTypeInfo = createType("Foo");
QmlDesigner::TypeId dummyTypeId = projectStorageMock.commonTypeCache().builtinTypeId<double>(); QmlDesigner::TypeId dummyTypeId = projectStorageMock.commonTypeCache().builtinTypeId<double>();
}; };
TEST_F(PropertyEditorTemplateGenerator, no_properties_and_no_imports) TEST_F(PropertyEditorComponentGenerator, no_properties_and_no_imports)
{ {
QString expectedText{ QString expectedText{
R"xy( R"xy(
@@ -110,12 +110,12 @@ TEST_F(PropertyEditorTemplateGenerator, no_properties_and_no_imports)
} }
})xy"}; })xy"};
auto text = generator.create(fooTypeInfo, false); auto text = generator.create(fooTypeInfo.selfAndPrototypes(), false);
ASSERT_THAT(text, StrippedStringEq(expectedText)); 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{ QString expectedText{
R"xy( R"xy(
@@ -135,12 +135,12 @@ TEST_F(PropertyEditorTemplateGenerator, properties_without_component_are_not_sho
})xy"}; })xy"};
createProperty(fooTypeInfo.id(), "x", {}, dummyTypeId); createProperty(fooTypeInfo.id(), "x", {}, dummyTypeId);
auto text = generator.create(fooTypeInfo, false); auto text = generator.create(fooTypeInfo.selfAndPrototypes(), false);
ASSERT_THAT(text, StrippedStringEq(expectedText)); 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{ QString expectedText{
R"xy( R"xy(
@@ -160,12 +160,12 @@ TEST_F(PropertyEditorTemplateGenerator, show_component_button_for_a_component_no
} }
})xy"}; })xy"};
auto text = generator.create(fooTypeInfo, true); auto text = generator.create(fooTypeInfo.selfAndPrototypes(), true);
ASSERT_THAT(text, StrippedStringEq(expectedText)); ASSERT_THAT(text, StrippedStringEq(expectedText));
} }
TEST_F(PropertyEditorTemplateGenerator, imports) TEST_F(PropertyEditorComponentGenerator, imports)
{ {
QString expectedText{ QString expectedText{
R"xy( R"xy(
@@ -187,12 +187,12 @@ TEST_F(PropertyEditorTemplateGenerator, imports)
})xy"}; })xy"};
setImports({"import QtQtuick", "import Studio 2.1"}); 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)); ASSERT_THAT(text, StrippedStringEq(expectedText));
} }
TEST_F(PropertyEditorTemplateGenerator, basic_property) TEST_F(PropertyEditorComponentGenerator, basic_property)
{ {
QString expectedText{ QString expectedText{
R"xy( R"xy(
@@ -220,12 +220,12 @@ TEST_F(PropertyEditorTemplateGenerator, basic_property)
})xy"}; })xy"};
createBasicProperty(fooTypeInfo.id(), "value", {}, dummyTypeId, "Double{}"); createBasicProperty(fooTypeInfo.id(), "value", {}, dummyTypeId, "Double{}");
auto text = generator.create(fooTypeInfo, false); auto text = generator.create(fooTypeInfo.selfAndPrototypes(), false);
ASSERT_THAT(text, StrippedStringEq(expectedText)); ASSERT_THAT(text, StrippedStringEq(expectedText));
} }
TEST_F(PropertyEditorTemplateGenerator, basic_properties_with_base_type) TEST_F(PropertyEditorComponentGenerator, basic_properties_with_base_type)
{ {
QString expectedText{ QString expectedText{
R"xy( R"xy(
@@ -256,12 +256,12 @@ TEST_F(PropertyEditorTemplateGenerator, basic_properties_with_base_type)
auto superFooInfo = createType("SuperFoo", {fooTypeInfo.id()}); auto superFooInfo = createType("SuperFoo", {fooTypeInfo.id()});
createBasicProperty(superFooInfo.id(), "value", {}, dummyTypeId, "SuperDouble{}"); createBasicProperty(superFooInfo.id(), "value", {}, dummyTypeId, "SuperDouble{}");
auto text = generator.create(superFooInfo, false); auto text = generator.create(superFooInfo.selfAndPrototypes(), false);
ASSERT_THAT(text, StrippedStringEq(expectedText)); ASSERT_THAT(text, StrippedStringEq(expectedText));
} }
TEST_F(PropertyEditorTemplateGenerator, TEST_F(PropertyEditorComponentGenerator,
only_handle_basic_properties_for_types_without_specifics_or_panes) only_handle_basic_properties_for_types_without_specifics_or_panes)
{ {
QString expectedText{ QString expectedText{
@@ -293,12 +293,12 @@ TEST_F(PropertyEditorTemplateGenerator,
createBasicProperty(superFooInfo.id(), "value", {}, dummyTypeId, "SuperDouble{}"); createBasicProperty(superFooInfo.id(), "value", {}, dummyTypeId, "SuperDouble{}");
projectStorageMock.setPropertyEditorPathId(fooTypeInfo.id(), sourceId); projectStorageMock.setPropertyEditorPathId(fooTypeInfo.id(), sourceId);
auto text = generator.create(superFooInfo, false); auto text = generator.create(superFooInfo.selfAndPrototypes(), false);
ASSERT_THAT(text, StrippedStringEq(expectedText)); ASSERT_THAT(text, StrippedStringEq(expectedText));
} }
TEST_F(PropertyEditorTemplateGenerator, order_basic_property) TEST_F(PropertyEditorComponentGenerator, order_basic_property)
{ {
QString expectedText{ QString expectedText{
R"xy( R"xy(
@@ -330,12 +330,12 @@ TEST_F(PropertyEditorTemplateGenerator, order_basic_property)
createBasicProperty(fooTypeInfo.id(), "x", {}, dummyTypeId, "AnotherX{}"); createBasicProperty(fooTypeInfo.id(), "x", {}, dummyTypeId, "AnotherX{}");
createBasicProperty(fooTypeInfo.id(), "y", {}, dummyTypeId, "AndY{}"); createBasicProperty(fooTypeInfo.id(), "y", {}, dummyTypeId, "AndY{}");
auto text = generator.create(fooTypeInfo, false); auto text = generator.create(fooTypeInfo.selfAndPrototypes(), false);
ASSERT_THAT(text, StrippedStringEq(expectedText)); ASSERT_THAT(text, StrippedStringEq(expectedText));
} }
TEST_F(PropertyEditorTemplateGenerator, complex_property) TEST_F(PropertyEditorComponentGenerator, complex_property)
{ {
QString expectedText{ QString expectedText{
R"xy( R"xy(
@@ -356,12 +356,12 @@ TEST_F(PropertyEditorTemplateGenerator, complex_property)
})xy"}; })xy"};
createComplexProperty(fooTypeInfo.id(), "value", {}, dummyTypeId, "Complex{}"); createComplexProperty(fooTypeInfo.id(), "value", {}, dummyTypeId, "Complex{}");
auto text = generator.create(fooTypeInfo, false); auto text = generator.create(fooTypeInfo.selfAndPrototypes(), false);
ASSERT_THAT(text, StrippedStringEq(expectedText)); ASSERT_THAT(text, StrippedStringEq(expectedText));
} }
TEST_F(PropertyEditorTemplateGenerator, complex_properties_with_base_type) TEST_F(PropertyEditorComponentGenerator, complex_properties_with_base_type)
{ {
QString expectedText{ QString expectedText{
R"xy( R"xy(
@@ -385,12 +385,12 @@ TEST_F(PropertyEditorTemplateGenerator, complex_properties_with_base_type)
auto superFooInfo = createType("SuperFoo", {fooTypeInfo.id()}); auto superFooInfo = createType("SuperFoo", {fooTypeInfo.id()});
createComplexProperty(superFooInfo.id(), "value", {}, dummyTypeId, "SuperComplex{}"); createComplexProperty(superFooInfo.id(), "value", {}, dummyTypeId, "SuperComplex{}");
auto text = generator.create(superFooInfo, false); auto text = generator.create(superFooInfo.selfAndPrototypes(), false);
ASSERT_THAT(text, StrippedStringEq(expectedText)); ASSERT_THAT(text, StrippedStringEq(expectedText));
} }
TEST_F(PropertyEditorTemplateGenerator, TEST_F(PropertyEditorComponentGenerator,
only_handle_complex_properties_for_types_without_specifics_or_panes) only_handle_complex_properties_for_types_without_specifics_or_panes)
{ {
QString expectedText{ QString expectedText{
@@ -415,12 +415,12 @@ TEST_F(PropertyEditorTemplateGenerator,
createComplexProperty(superFooInfo.id(), "value", {}, dummyTypeId, "SuperComplex{}"); createComplexProperty(superFooInfo.id(), "value", {}, dummyTypeId, "SuperComplex{}");
projectStorageMock.setPropertyEditorPathId(fooTypeInfo.id(), sourceId); projectStorageMock.setPropertyEditorPathId(fooTypeInfo.id(), sourceId);
auto text = generator.create(superFooInfo, false); auto text = generator.create(superFooInfo.selfAndPrototypes(), false);
ASSERT_THAT(text, StrippedStringEq(expectedText)); ASSERT_THAT(text, StrippedStringEq(expectedText));
} }
TEST_F(PropertyEditorTemplateGenerator, ordered_complex_property) TEST_F(PropertyEditorComponentGenerator, ordered_complex_property)
{ {
QString expectedText{ QString expectedText{
R"xy( R"xy(
@@ -445,12 +445,12 @@ TEST_F(PropertyEditorTemplateGenerator, ordered_complex_property)
createComplexProperty(fooTypeInfo.id(), "font", {}, dummyTypeId, "ComplexFont{}"); createComplexProperty(fooTypeInfo.id(), "font", {}, dummyTypeId, "ComplexFont{}");
createComplexProperty(fooTypeInfo.id(), "anchors", {}, dummyTypeId, "Anchors{}"); createComplexProperty(fooTypeInfo.id(), "anchors", {}, dummyTypeId, "Anchors{}");
auto text = generator.create(fooTypeInfo, false); auto text = generator.create(fooTypeInfo.selfAndPrototypes(), false);
ASSERT_THAT(text, StrippedStringEq(expectedText)); 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{ QString expectedText{
R"xy( R"xy(
@@ -480,7 +480,7 @@ TEST_F(PropertyEditorTemplateGenerator, basic_is_placed_before_complex_component
createBasicProperty(fooTypeInfo.id(), "x", {}, dummyTypeId, "Double{}"); createBasicProperty(fooTypeInfo.id(), "x", {}, dummyTypeId, "Double{}");
createComplexProperty(fooTypeInfo.id(), "font", {}, dummyTypeId, "Font{}"); createComplexProperty(fooTypeInfo.id(), "font", {}, dummyTypeId, "Font{}");
auto text = generator.create(fooTypeInfo, false); auto text = generator.create(fooTypeInfo.selfAndPrototypes(), false);
ASSERT_THAT(text, StrippedStringEq(expectedText)); ASSERT_THAT(text, StrippedStringEq(expectedText));
} }

View File

@@ -928,14 +928,16 @@ TEST_F(Model, remove_refresh_callback_from_project_storage)
TEST_F(Model, refresh_callback_is_calling_abstract_view) TEST_F(Model, refresh_callback_is_calling_abstract_view)
{ {
std::function<void()> *callback = nullptr; const QmlDesigner::TypeIds typeIds = {QmlDesigner::TypeId::create(3),
QmlDesigner::TypeId::create(1)};
std::function<void(const QmlDesigner::TypeIds &)> *callback = nullptr;
ON_CALL(projectStorageMock, addRefreshCallback(_)).WillByDefault([&](auto *c) { callback = c; }); ON_CALL(projectStorageMock, addRefreshCallback(_)).WillByDefault([&](auto *c) { callback = c; });
QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, "Item", -1, -1, nullptr, {}}; QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, "Item", -1, -1, nullptr, {}};
model.attachView(&viewMock); model.attachView(&viewMock);
EXPECT_CALL(viewMock, refreshMetaInfos()); EXPECT_CALL(viewMock, refreshMetaInfos(typeIds));
(*callback)(); (*callback)(typeIds);
} }
} // namespace } // namespace

View File

@@ -7195,11 +7195,11 @@ TEST_F(ProjectStorage, synchronize_property_editor_with_non_existing_type_name)
TEST_F(ProjectStorage, call_refresh_callback_after_synchronization) TEST_F(ProjectStorage, call_refresh_callback_after_synchronization)
{ {
auto package{createSimpleSynchronizationPackage()}; auto package{createSimpleSynchronizationPackage()};
MockFunction<void()> callbackMock; MockFunction<void(const QmlDesigner::TypeIds &)> callbackMock;
auto callback = callbackMock.AsStdFunction(); auto callback = callbackMock.AsStdFunction();
storage.addRefreshCallback(&callback); storage.addRefreshCallback(&callback);
EXPECT_CALL(callbackMock, Call()); EXPECT_CALL(callbackMock, Call(_));
storage.synchronize(package); storage.synchronize(package);
} }