aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmldesigner/components/collectioneditor/datastoremodelnode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/qmldesigner/components/collectioneditor/datastoremodelnode.cpp')
-rw-r--r--src/plugins/qmldesigner/components/collectioneditor/datastoremodelnode.cpp214
1 files changed, 214 insertions, 0 deletions
diff --git a/src/plugins/qmldesigner/components/collectioneditor/datastoremodelnode.cpp b/src/plugins/qmldesigner/components/collectioneditor/datastoremodelnode.cpp
new file mode 100644
index 0000000000..4b2ab6edbe
--- /dev/null
+++ b/src/plugins/qmldesigner/components/collectioneditor/datastoremodelnode.cpp
@@ -0,0 +1,214 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "datastoremodelnode.h"
+
+#include "collectioneditorconstants.h"
+#include "model/qmltextgenerator.h"
+
+#include <model.h>
+#include <nodemetainfo.h>
+#include <nodeproperty.h>
+#include <variantproperty.h>
+
+#include <qmljstools/qmljscodestylepreferences.h>
+#include <qmljstools/qmljstoolssettings.h>
+
+#include <projectexplorer/project.h>
+#include <projectexplorer/projectexplorer.h>
+#include <projectexplorer/projectmanager.h>
+
+#include <utils/fileutils.h>
+#include <utils/qtcassert.h>
+
+namespace {
+
+Utils::FilePath findFile(const Utils::FilePath &path, const QString &fileName)
+{
+ QDirIterator it(path.toString(), QDirIterator::Subdirectories);
+
+ while (it.hasNext()) {
+ QFileInfo file(it.next());
+ if (file.isDir())
+ continue;
+
+ if (file.fileName() == fileName)
+ return Utils::FilePath::fromFileInfo(file);
+ }
+ return {};
+}
+
+QmlDesigner::PropertyNameList createNameList(const QmlDesigner::ModelNode &node)
+{
+ using QmlDesigner::AbstractProperty;
+ using QmlDesigner::PropertyName;
+ using QmlDesigner::PropertyNameList;
+ static PropertyNameList defaultsNodeProps = {"id",
+ QmlDesigner::CollectionEditor::SOURCEFILE_PROPERTY,
+ QmlDesigner::CollectionEditor::JSONCHILDMODELNAME_PROPERTY,
+ "backend"};
+ PropertyNameList dynamicPropertyNames = Utils::transform(
+ node.dynamicProperties(),
+ [](const AbstractProperty &property) -> PropertyName { return property.name(); });
+
+ Utils::sort(dynamicPropertyNames);
+
+ return defaultsNodeProps + dynamicPropertyNames;
+}
+
+} // namespace
+
+namespace QmlDesigner {
+
+DataStoreModelNode::DataStoreModelNode()
+{
+ reloadModel();
+}
+
+void DataStoreModelNode::reloadModel()
+{
+ using Utils::FilePath;
+ if (!ProjectExplorer::ProjectManager::startupProject()) {
+ reset();
+ return;
+ }
+ bool forceUpdate = false;
+
+ const FilePath projectFilePath = ProjectExplorer::ProjectManager::startupProject()->projectDirectory();
+ const FilePath importsPath = FilePath::fromString(projectFilePath.path() + "/imports");
+ FilePath dataStoreQmlPath = findFile(importsPath, "DataStore.qml");
+ FilePath dataStoreJsonPath = findFile(importsPath, "DataStore.json");
+ QUrl dataStoreQmlUrl = dataStoreQmlPath.toUrl();
+
+ if (dataStoreQmlPath.exists() && dataStoreJsonPath.exists()) {
+ if (!m_model.get() || m_model->fileUrl() != dataStoreQmlUrl) {
+ m_model = Model::create(CollectionEditor::JSONCOLLECTIONMODEL_TYPENAME, 1, 1);
+ forceUpdate = true;
+ Import import = Import::createLibraryImport(CollectionEditor::COLLECTIONMODEL_IMPORT);
+ try {
+ if (!m_model->hasImport(import, true, true))
+ m_model->changeImports({import}, {});
+ } catch (const Exception &) {
+ QTC_ASSERT(false, return);
+ }
+ }
+ } else {
+ reset();
+ }
+
+ QTC_ASSERT(m_model.get(), return);
+ m_model->setFileUrl(dataStoreQmlUrl);
+
+ m_dataRelativePath = dataStoreJsonPath.relativePathFrom(dataStoreQmlPath).toFSPathString();
+
+ if (forceUpdate) {
+ updateDataStoreProperties();
+ updateSingletonFile();
+ }
+}
+
+QStringList DataStoreModelNode::collectionNames() const
+{
+ return m_collectionNames;
+}
+
+Model *DataStoreModelNode::model() const
+{
+ return m_model.get();
+}
+
+ModelNode DataStoreModelNode::modelNode() const
+{
+ QTC_ASSERT(m_model.get(), return {});
+ return m_model->rootModelNode();
+}
+
+QString DataStoreModelNode::getModelQmlText()
+{
+ ModelNode node = modelNode();
+ QTC_ASSERT(node, return {});
+
+ Internal::QmlTextGenerator textGen(createNameList(node),
+ QmlJSTools::QmlJSToolsSettings::globalCodeStyle()->tabSettings());
+
+ QString genText = textGen(node);
+ return genText;
+}
+
+void DataStoreModelNode::reset()
+{
+ if (m_model)
+ m_model.reset();
+
+ m_dataRelativePath.clear();
+ setCollectionNames({});
+}
+
+void DataStoreModelNode::updateDataStoreProperties()
+{
+ QTC_ASSERT(model(), return);
+
+ ModelNode rootNode = modelNode();
+ QTC_ASSERT(rootNode.isValid(), return);
+
+ static TypeName childNodeTypename = "ChildListModel";
+
+ const QList<AbstractProperty> formerPropertyNames = rootNode.dynamicProperties();
+ for (const AbstractProperty &property : formerPropertyNames)
+ rootNode.removeProperty(property.name());
+
+ rootNode.setIdWithoutRefactoring("models");
+
+ for (const QString &collectionName : std::as_const(m_collectionNames)) {
+ PropertyName newName = collectionName.toLatin1();
+
+ ModelNode collectionNode = model()->createModelNode(childNodeTypename);
+
+ VariantProperty modelNameProperty = collectionNode.variantProperty(
+ CollectionEditor::JSONCHILDMODELNAME_PROPERTY);
+ modelNameProperty.setValue(newName);
+
+ NodeProperty nodeProp = rootNode.nodeProperty(newName);
+ nodeProp.setDynamicTypeNameAndsetModelNode(childNodeTypename, collectionNode);
+ }
+
+ // Backend Property
+ ModelNode backendNode = model()->createModelNode(CollectionEditor::JSONBACKEND_TYPENAME);
+ NodeProperty backendProperty = rootNode.nodeProperty("backend");
+ backendProperty.setDynamicTypeNameAndsetModelNode(CollectionEditor::JSONBACKEND_TYPENAME,
+ backendNode);
+ // Source Property
+ VariantProperty sourceProp = rootNode.variantProperty(CollectionEditor::SOURCEFILE_PROPERTY);
+ sourceProp.setValue(m_dataRelativePath);
+}
+
+void DataStoreModelNode::updateSingletonFile()
+{
+ using Utils::FilePath;
+ using Utils::FileSaver;
+ QTC_ASSERT(m_model.get(), return);
+
+ const QString pragmaSingleTone = "pragma Singleton\n";
+ QString imports;
+
+ for (const Import &import : m_model->imports())
+ imports += QStringLiteral("import %1\n").arg(import.toString(true));
+
+ QString content = pragmaSingleTone + imports + getModelQmlText();
+ QUrl modelUrl = m_model->fileUrl();
+ FileSaver file(FilePath::fromUserInput(modelUrl.isLocalFile() ? modelUrl.toLocalFile()
+ : modelUrl.toString()));
+ file.write(content.toLatin1());
+ file.finalize();
+}
+
+void DataStoreModelNode::setCollectionNames(const QStringList &newCollectionNames)
+{
+ if (m_collectionNames != newCollectionNames) {
+ m_collectionNames = newCollectionNames;
+ updateDataStoreProperties();
+ updateSingletonFile();
+ }
+}
+
+} // namespace QmlDesigner