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 <marco.bubke@qt.io>
This commit is contained in:
Thomas Hartmann
2025-04-09 12:45:04 +02:00
committed by Thomas Hartmann
parent 5982ab8074
commit aa3d61da93
5 changed files with 50 additions and 13 deletions

View File

@@ -11,8 +11,7 @@
#include <QQmlEngine> #include <QQmlEngine>
namespace QmlDesigner { namespace QmlDesigner {
DesignSystemInterface::DesignSystemInterface(DSStore *store) DesignSystemInterface::DesignSystemInterface()
: m_store(store)
{ {
qmlRegisterUncreatableMetaObject( qmlRegisterUncreatableMetaObject(
QmlDesigner::staticMetaObject, "QmlDesigner.DesignSystem", 1, 0, "GroupType", ""); QmlDesigner::staticMetaObject, "QmlDesigner.DesignSystem", 1, 0, "GroupType", "");
@@ -23,6 +22,8 @@ DesignSystemInterface::~DesignSystemInterface() {}
void DesignSystemInterface::loadDesignSystem() void DesignSystemInterface::loadDesignSystem()
{ {
QTC_ASSERT(m_store, return);
m_models.clear(); m_models.clear();
if (auto err = m_store->load()) if (auto err = m_store->load())
@@ -33,6 +34,8 @@ void DesignSystemInterface::loadDesignSystem()
CollectionModel *DesignSystemInterface::model(const QString &typeName) CollectionModel *DesignSystemInterface::model(const QString &typeName)
{ {
QTC_ASSERT(m_store, return nullptr);
if (auto collection = m_store->collection(typeName)) if (auto collection = m_store->collection(typeName))
return createModel(typeName, collection); return createModel(typeName, collection);
@@ -41,17 +44,22 @@ CollectionModel *DesignSystemInterface::model(const QString &typeName)
QString DesignSystemInterface::generateCollectionName(const QString &hint) const QString DesignSystemInterface::generateCollectionName(const QString &hint) const
{ {
QTC_ASSERT(m_store, return {});
return m_store->uniqueCollectionName(hint); return m_store->uniqueCollectionName(hint);
} }
void DesignSystemInterface::addCollection(const QString &name) void DesignSystemInterface::addCollection(const QString &name)
{ {
QTC_ASSERT(m_store, return);
if (m_store->addCollection(name)) if (m_store->addCollection(name))
emit collectionsChanged(); emit collectionsChanged();
} }
void DesignSystemInterface::removeCollection(const QString &name) void DesignSystemInterface::removeCollection(const QString &name)
{ {
QTC_ASSERT(m_store, return);
if (m_store->collection(name)) { if (m_store->collection(name)) {
m_models.erase(name); m_models.erase(name);
m_store->removeCollection(name); m_store->removeCollection(name);
@@ -61,6 +69,8 @@ void DesignSystemInterface::removeCollection(const QString &name)
void DesignSystemInterface::renameCollection(const QString &oldName, const QString &newName) void DesignSystemInterface::renameCollection(const QString &oldName, const QString &newName)
{ {
QTC_ASSERT(m_store, return);
if (m_store->renameCollection(oldName, newName)) if (m_store->renameCollection(oldName, newName))
emit collectionsChanged(); emit collectionsChanged();
} }
@@ -74,9 +84,16 @@ ThemeProperty DesignSystemInterface::createThemeProperty(const QString &name,
QStringList DesignSystemInterface::collections() const QStringList DesignSystemInterface::collections() const
{ {
QTC_ASSERT(m_store, return {});
return m_store->collectionNames(); return m_store->collectionNames();
} }
void DesignSystemInterface::setDSStore(DSStore *store)
{
m_store = store;
}
CollectionModel *DesignSystemInterface::createModel(const QString &typeName, DSThemeManager *collection) CollectionModel *DesignSystemInterface::createModel(const QString &typeName, DSThemeManager *collection)
{ {
auto [iterator, inserted] = m_models.try_emplace(typeName, collection, m_store); auto [iterator, inserted] = m_models.try_emplace(typeName, collection, m_store);

View File

@@ -18,7 +18,7 @@ class DesignSystemInterface : public QObject
Q_PROPERTY(QStringList collections READ collections NOTIFY collectionsChanged FINAL) Q_PROPERTY(QStringList collections READ collections NOTIFY collectionsChanged FINAL)
public: public:
DesignSystemInterface(DSStore *store); DesignSystemInterface();
~DesignSystemInterface(); ~DesignSystemInterface();
Q_INVOKABLE void loadDesignSystem(); Q_INVOKABLE void loadDesignSystem();
@@ -35,6 +35,8 @@ public:
QStringList collections() const; QStringList collections() const;
void setDSStore(DSStore *store);
signals: signals:
void collectionsChanged(); void collectionsChanged();

View File

@@ -21,17 +21,14 @@
namespace QmlDesigner { namespace QmlDesigner {
DesignSystemView::DesignSystemView(ExternalDependenciesInterface &externalDependencies, DesignSystemView::DesignSystemView(ExternalDependenciesInterface &externalDependencies)
ProjectStorageDependencies projectStorageDependencies)
: AbstractView(externalDependencies) : AbstractView(externalDependencies)
, m_externalDependencies(externalDependencies) , m_externalDependencies(externalDependencies)
, m_dsStore(std::make_unique<DSStore>(m_externalDependencies, projectStorageDependencies))
, m_dsInterface(m_dsStore.get())
{ {
connect(ProjectExplorer::ProjectManager::instance(), connect(ProjectExplorer::ProjectManager::instance(),
&ProjectExplorer::ProjectManager::startupProjectChanged, &ProjectExplorer::ProjectManager::startupProjectChanged,
this, this,
[this](ProjectExplorer::Project *) { loadDesignSystem(); }); [this](ProjectExplorer::Project *) { resetDesignSystem(); });
connect(Core::EditorManager::instance(), connect(Core::EditorManager::instance(),
&Core::EditorManager::saved, &Core::EditorManager::saved,
@@ -63,12 +60,31 @@ bool DesignSystemView::hasWidget() const
return true; return true;
} }
void DesignSystemView::modelAttached(Model *model)
{
AbstractView::modelAttached(model);
/* Only load on first attach */
if (!m_dsStore)
loadDesignSystem();
}
void DesignSystemView::loadDesignSystem() void DesignSystemView::loadDesignSystem()
{ {
/*This is only used to load internally - when saving we have to take care of reflection. /*This is only used to load internally - when saving we have to take care of reflection.
* Saving should not trigger a load again. * Saving should not trigger a load again.
*/ */
m_dsStore = std::make_unique<DSStore>(m_externalDependencies,
model()->projectStorageDependencies());
m_dsInterface.setDSStore(m_dsStore.get());
m_dsInterface.loadDesignSystem(); m_dsInterface.loadDesignSystem();
} }
void DesignSystemView::resetDesignSystem()
{
m_dsStore.reset();
m_dsInterface.setDSStore(nullptr);
}
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -4,6 +4,7 @@
#pragma once #pragma once
#include "designsysteminterface.h" #include "designsysteminterface.h"
#include "qmldesignerprojectmanager.h"
#include <abstractview.h> #include <abstractview.h>
#include <memory> #include <memory>
@@ -13,21 +14,24 @@ namespace QmlDesigner {
class DSStore; class DSStore;
class ExternalDependenciesInterface; class ExternalDependenciesInterface;
class DesignSystemWidget; class DesignSystemWidget;
class QmlDesignerProjectManager;
class DesignSystemView : public AbstractView class DesignSystemView : public AbstractView
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit DesignSystemView(ExternalDependenciesInterface &externalDependencies, explicit DesignSystemView(ExternalDependenciesInterface &externalDependencies);
ProjectStorageDependencies projectStorageDependencies);
~DesignSystemView() override; ~DesignSystemView() override;
WidgetInfo widgetInfo() override; WidgetInfo widgetInfo() override;
bool hasWidget() const override; bool hasWidget() const override;
void modelAttached(Model *model) override;
private: private:
void loadDesignSystem(); void loadDesignSystem();
void resetDesignSystem();
QWidget *createViewWidget(); QWidget *createViewWidget();
private: private:

View File

@@ -677,9 +677,7 @@ void QmlDesignerPlugin::enforceDelayedInitialize()
transitionEditorView->registerActions(); transitionEditorView->registerActions();
if (QmlDesignerBasePlugin::experimentalFeaturesEnabled()) if (QmlDesignerBasePlugin::experimentalFeaturesEnabled())
d->viewManager.registerView( d->viewManager.registerView(std::make_unique<DesignSystemView>(d->externalDependencies));
std::make_unique<DesignSystemView>(d->externalDependencies,
d->projectManager.projectStorageDependencies()));
d->viewManager.registerFormEditorTool(std::make_unique<SourceTool>()); d->viewManager.registerFormEditorTool(std::make_unique<SourceTool>());
d->viewManager.registerFormEditorTool(std::make_unique<ColorTool>()); d->viewManager.registerFormEditorTool(std::make_unique<ColorTool>());