From aa3d61da93269db35024be73b433f75ccdf03c33 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 9 Apr 2025 12:45:04 +0200 Subject: [PATCH] QmlDesigner: Fix DesignSystemView for project storage The projectStorageDependencies are only available if actually a project is opened. DSStore is part of a library and also used in the importer. Instead of changing DSStore, we create the DSStore in the first attach after a project was opened. DesignSystemInterface is the interface to the QML UI. We guard access in case no DSStore is created, yet. TODO: We should only load the DesignSystem on demand if the view is actually active. Task-number: QDS-15070 Change-Id: I6f52375d029e575582dc8f16abc50c157666f287 Reviewed-by: Marco Bubke --- .../designsysteminterface.cpp | 21 +++++++++++++-- .../designsystemview/designsysteminterface.h | 4 ++- .../designsystemview/designsystemview.cpp | 26 +++++++++++++++---- .../designsystemview/designsystemview.h | 8 ++++-- src/plugins/qmldesigner/qmldesignerplugin.cpp | 4 +-- 5 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.cpp b/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.cpp index 820ec51e5ad..7b27bbb52d8 100644 --- a/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.cpp +++ b/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.cpp @@ -11,8 +11,7 @@ #include namespace QmlDesigner { -DesignSystemInterface::DesignSystemInterface(DSStore *store) - : m_store(store) +DesignSystemInterface::DesignSystemInterface() { qmlRegisterUncreatableMetaObject( QmlDesigner::staticMetaObject, "QmlDesigner.DesignSystem", 1, 0, "GroupType", ""); @@ -23,6 +22,8 @@ DesignSystemInterface::~DesignSystemInterface() {} void DesignSystemInterface::loadDesignSystem() { + QTC_ASSERT(m_store, return); + m_models.clear(); if (auto err = m_store->load()) @@ -33,6 +34,8 @@ void DesignSystemInterface::loadDesignSystem() CollectionModel *DesignSystemInterface::model(const QString &typeName) { + QTC_ASSERT(m_store, return nullptr); + if (auto collection = m_store->collection(typeName)) return createModel(typeName, collection); @@ -41,17 +44,22 @@ CollectionModel *DesignSystemInterface::model(const QString &typeName) QString DesignSystemInterface::generateCollectionName(const QString &hint) const { + QTC_ASSERT(m_store, return {}); return m_store->uniqueCollectionName(hint); } void DesignSystemInterface::addCollection(const QString &name) { + QTC_ASSERT(m_store, return); + if (m_store->addCollection(name)) emit collectionsChanged(); } void DesignSystemInterface::removeCollection(const QString &name) { + QTC_ASSERT(m_store, return); + if (m_store->collection(name)) { m_models.erase(name); m_store->removeCollection(name); @@ -61,6 +69,8 @@ void DesignSystemInterface::removeCollection(const QString &name) void DesignSystemInterface::renameCollection(const QString &oldName, const QString &newName) { + QTC_ASSERT(m_store, return); + if (m_store->renameCollection(oldName, newName)) emit collectionsChanged(); } @@ -74,9 +84,16 @@ ThemeProperty DesignSystemInterface::createThemeProperty(const QString &name, QStringList DesignSystemInterface::collections() const { + QTC_ASSERT(m_store, return {}); + return m_store->collectionNames(); } +void DesignSystemInterface::setDSStore(DSStore *store) +{ + m_store = store; +} + CollectionModel *DesignSystemInterface::createModel(const QString &typeName, DSThemeManager *collection) { auto [iterator, inserted] = m_models.try_emplace(typeName, collection, m_store); diff --git a/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.h b/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.h index 6aaa7e92023..6f4f8c1e0a5 100644 --- a/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.h +++ b/src/plugins/qmldesigner/components/designsystemview/designsysteminterface.h @@ -18,7 +18,7 @@ class DesignSystemInterface : public QObject Q_PROPERTY(QStringList collections READ collections NOTIFY collectionsChanged FINAL) public: - DesignSystemInterface(DSStore *store); + DesignSystemInterface(); ~DesignSystemInterface(); Q_INVOKABLE void loadDesignSystem(); @@ -35,6 +35,8 @@ public: QStringList collections() const; + void setDSStore(DSStore *store); + signals: void collectionsChanged(); diff --git a/src/plugins/qmldesigner/components/designsystemview/designsystemview.cpp b/src/plugins/qmldesigner/components/designsystemview/designsystemview.cpp index 29e8cf49f49..a7f9ef33a52 100644 --- a/src/plugins/qmldesigner/components/designsystemview/designsystemview.cpp +++ b/src/plugins/qmldesigner/components/designsystemview/designsystemview.cpp @@ -21,17 +21,14 @@ namespace QmlDesigner { -DesignSystemView::DesignSystemView(ExternalDependenciesInterface &externalDependencies, - ProjectStorageDependencies projectStorageDependencies) +DesignSystemView::DesignSystemView(ExternalDependenciesInterface &externalDependencies) : AbstractView(externalDependencies) , m_externalDependencies(externalDependencies) - , m_dsStore(std::make_unique(m_externalDependencies, projectStorageDependencies)) - , m_dsInterface(m_dsStore.get()) { connect(ProjectExplorer::ProjectManager::instance(), &ProjectExplorer::ProjectManager::startupProjectChanged, this, - [this](ProjectExplorer::Project *) { loadDesignSystem(); }); + [this](ProjectExplorer::Project *) { resetDesignSystem(); }); connect(Core::EditorManager::instance(), &Core::EditorManager::saved, @@ -63,12 +60,31 @@ bool DesignSystemView::hasWidget() const return true; } +void DesignSystemView::modelAttached(Model *model) +{ + AbstractView::modelAttached(model); + /* Only load on first attach */ + if (!m_dsStore) + loadDesignSystem(); +} + void DesignSystemView::loadDesignSystem() { /*This is only used to load internally - when saving we have to take care of reflection. * Saving should not trigger a load again. */ + + m_dsStore = std::make_unique(m_externalDependencies, + model()->projectStorageDependencies()); + m_dsInterface.setDSStore(m_dsStore.get()); + m_dsInterface.loadDesignSystem(); } +void DesignSystemView::resetDesignSystem() +{ + m_dsStore.reset(); + m_dsInterface.setDSStore(nullptr); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/designsystemview/designsystemview.h b/src/plugins/qmldesigner/components/designsystemview/designsystemview.h index b3c44cfb873..42332c13819 100644 --- a/src/plugins/qmldesigner/components/designsystemview/designsystemview.h +++ b/src/plugins/qmldesigner/components/designsystemview/designsystemview.h @@ -4,6 +4,7 @@ #pragma once #include "designsysteminterface.h" +#include "qmldesignerprojectmanager.h" #include #include @@ -13,21 +14,24 @@ namespace QmlDesigner { class DSStore; class ExternalDependenciesInterface; class DesignSystemWidget; +class QmlDesignerProjectManager; class DesignSystemView : public AbstractView { Q_OBJECT public: - explicit DesignSystemView(ExternalDependenciesInterface &externalDependencies, - ProjectStorageDependencies projectStorageDependencies); + explicit DesignSystemView(ExternalDependenciesInterface &externalDependencies); ~DesignSystemView() override; WidgetInfo widgetInfo() override; bool hasWidget() const override; + void modelAttached(Model *model) override; + private: void loadDesignSystem(); + void resetDesignSystem(); QWidget *createViewWidget(); private: diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index fdf8b9e94d9..55be25b7c2a 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -677,9 +677,7 @@ void QmlDesignerPlugin::enforceDelayedInitialize() transitionEditorView->registerActions(); if (QmlDesignerBasePlugin::experimentalFeaturesEnabled()) - d->viewManager.registerView( - std::make_unique(d->externalDependencies, - d->projectManager.projectStorageDependencies())); + d->viewManager.registerView(std::make_unique(d->externalDependencies)); d->viewManager.registerFormEditorTool(std::make_unique()); d->viewManager.registerFormEditorTool(std::make_unique());