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>
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);

View File

@@ -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();

View File

@@ -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<DSStore>(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<DSStore>(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

View File

@@ -4,6 +4,7 @@
#pragma once
#include "designsysteminterface.h"
#include "qmldesignerprojectmanager.h"
#include <abstractview.h>
#include <memory>
@@ -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:

View File

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