From bec41a7a557f4e3ed1eafe6a3c59e305836e23a5 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 10 Mar 2022 10:36:08 +0100 Subject: [PATCH] QmlDesigner: Remove dependency of ModelNode on AbstractView * Moved AbstractView::hasId() and AbstractView::generateNewId to Model. I kept a convenience function AbstractView::hasId(), so we do not have to change too much code. * hasId() and generateNewId() do not mutate the model and therefore belong to the model. * This also allows to remove the dependency on AbstractView in ModelNode * Adjusting the usage of generateNewId() throughout the code base. Change-Id: I0b8bab995c48fd52760b509cbe53f0854230b4c8 Reviewed-by: Reviewed-by: Mahmoud Badri Reviewed-by: Miikka Heikkinen --- .../componentcore/layoutingridlayout.cpp | 2 +- .../connectioneditor/backendmodel.cpp | 2 +- .../components/eventlist/nodelistview.cpp | 2 +- .../navigator/navigatortreemodel.cpp | 13 ++--- .../componentsplugin/addtabdesigneraction.cpp | 2 +- .../designercore/include/abstractview.h | 2 - .../qmldesigner/designercore/include/model.h | 5 ++ .../designercore/model/abstractview.cpp | 48 +---------------- .../qmldesigner/designercore/model/model.cpp | 53 +++++++++++++++++++ .../designercore/model/modelnode.cpp | 6 +-- .../designercore/model/qmlitemnode.cpp | 4 +- .../designercore/model/qmlvisualnode.cpp | 2 +- 12 files changed, 76 insertions(+), 65 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/layoutingridlayout.cpp b/src/plugins/qmldesigner/components/componentcore/layoutingridlayout.cpp index f55f4807d91..439faec59d1 100644 --- a/src/plugins/qmldesigner/components/componentcore/layoutingridlayout.cpp +++ b/src/plugins/qmldesigner/components/componentcore/layoutingridlayout.cpp @@ -419,7 +419,7 @@ void LayoutInGridLayout::fillEmptyCells() newItemNode.setVariantProperty("y", yPos); newItemNode.setVariantProperty("width", 14); newItemNode.setVariantProperty("height", 14); - newItemNode.setId(m_selectionContext.view()->generateNewId("spacer")); + newItemNode.setId(m_selectionContext.view()->model()->generateNewId("spacer")); } m_layoutedNodes.append(m_spacerNodes); } diff --git a/src/plugins/qmldesigner/components/connectioneditor/backendmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/backendmodel.cpp index 36d30713032..402023b8289 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/backendmodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/backendmodel.cpp @@ -241,7 +241,7 @@ void BackendModel::addNewBackend() if (!model->hasImport(import)) model->changeImports({import}, {}); - QString propertyName = m_connectionView->generateNewId(typeName); + QString propertyName = m_connectionView->model()->generateNewId(typeName); NodeMetaInfo metaInfo = model->metaInfo(typeName.toUtf8()); diff --git a/src/plugins/qmldesigner/components/eventlist/nodelistview.cpp b/src/plugins/qmldesigner/components/eventlist/nodelistview.cpp index a322d56ebc9..8569477bb5f 100644 --- a/src/plugins/qmldesigner/components/eventlist/nodelistview.cpp +++ b/src/plugins/qmldesigner/components/eventlist/nodelistview.cpp @@ -141,7 +141,7 @@ QString NodeListView::setNodeId(int internalId, const QString &id) { ModelNode node = modelNodeForInternalId(internalId); if (node.isValid()) { - QString newId = generateNewId(id); + QString newId = model()->generateNewId(id); node.setIdWithRefactoring(newId); return newId; } diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 654a18dfc9e..735df196afb 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -910,8 +910,8 @@ ModelNode NavigatorTreeModel::handleItemLibraryShaderDrop(const QString &shaderP // Rename the node based on shader source QFileInfo fi(relPath); - newModelNode.setIdWithoutRefactoring(m_view->generateNewId(fi.baseName(), - "shader")); + newModelNode.setIdWithoutRefactoring( + m_view->model()->generateNewId(fi.baseName(), "shader")); // Passes can't have children, so move shader node under parent if (targetProperty.parentModelNode().isSubclassOf("QtQuick3D.Pass")) { BindingProperty listProp = targetNode.bindingProperty("shaders"); @@ -956,9 +956,9 @@ ModelNode NavigatorTreeModel::handleItemLibrarySoundDrop(const QString &soundPat // Rename the node based on source QFileInfo fi(relPath); - newModelNode.setIdWithoutRefactoring(m_view->generateNewId(fi.baseName(), - "soundEffect")); - } + newModelNode.setIdWithoutRefactoring( + m_view->model()->generateNewId(fi.baseName(), "soundEffect")); + } return newModelNode; } @@ -1073,7 +1073,8 @@ ModelNode NavigatorTreeModel::createTextureNode(const NodeAbstractProperty &targ // Rename the node based on source image QFileInfo fi(imagePath); - newModelNode.setIdWithoutRefactoring(m_view->generateNewId(fi.baseName(), "textureImage")); + newModelNode.setIdWithoutRefactoring( + m_view->model()->generateNewId(fi.baseName(), "textureImage")); return newModelNode; } return {}; diff --git a/src/plugins/qmldesigner/componentsplugin/addtabdesigneraction.cpp b/src/plugins/qmldesigner/componentsplugin/addtabdesigneraction.cpp index 4f08a6eb830..12ba1d433a0 100644 --- a/src/plugins/qmldesigner/componentsplugin/addtabdesigneraction.cpp +++ b/src/plugins/qmldesigner/componentsplugin/addtabdesigneraction.cpp @@ -131,7 +131,7 @@ void AddTabDesignerAction::addNewTab() tabViewModelNode.majorVersion(), tabViewModelNode.minorVersion(), propertyList); - newTabModelNode.setIdWithRefactoring(newTabModelNode.view()->generateNewId(tabName)); + newTabModelNode.setIdWithRefactoring(newTabModelNode.model()->generateNewId(tabName)); tabViewModelNode.defaultNodeAbstractProperty().reparentHere(newTabModelNode); } } diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index 3908844dea4..b303a4fdef7 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -161,8 +161,6 @@ public: ModelNode modelNodeForId(const QString &id); bool hasId(const QString &id) const; - QString generateNewId(const QString &prefixName) const; - QString generateNewId(const QString &prefixName, const QString &fallbackPrefix) const; ModelNode modelNodeForInternalId(qint32 internalId) const; bool hasModelNodeForInternalId(qint32 internalId) const; diff --git a/src/plugins/qmldesigner/designercore/include/model.h b/src/plugins/qmldesigner/designercore/include/model.h index cb453a57566..48700376b9d 100644 --- a/src/plugins/qmldesigner/designercore/include/model.h +++ b/src/plugins/qmldesigner/designercore/include/model.h @@ -124,6 +124,11 @@ public: void clearMetaInfoCache(); + bool hasId(const QString &id) const; + + QString generateNewId(const QString &prefixName) const; + QString generateNewId(const QString &prefixName, const QString &fallbackPrefix) const; + protected: Model(); diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index 78014142e3b..790b6ad5a53 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -42,7 +42,6 @@ #include #include -#include #include #include @@ -519,52 +518,7 @@ ModelNode AbstractView::modelNodeForId(const QString &id) bool AbstractView::hasId(const QString &id) const { - return model()->d->hasId(id); -} - -QString firstCharToLower(const QString &string) -{ - QString resultString = string; - - if (!resultString.isEmpty()) - resultString[0] = resultString.at(0).toLower(); - - return resultString; -} - -QString AbstractView::generateNewId(const QString &prefixName, const QString &fallbackPrefix) const -{ - // First try just the prefixName without number as postfix, then continue with 2 and further - // as postfix until id does not already exist. - // Properties of the root node are not allowed for ids, because they are available in the - // complete context without qualification. - - int counter = 0; - - QString newBaseId = QString(QStringLiteral("%1")).arg(firstCharToLower(prefixName)); - newBaseId.remove(QRegularExpression(QStringLiteral("[^a-zA-Z0-9_]"))); - - if (!newBaseId.isEmpty()) { - QChar firstChar = newBaseId.at(0); - if (firstChar.isDigit()) - newBaseId.prepend('_'); - } else { - newBaseId = fallbackPrefix; - } - - QString newId = newBaseId; - - while (!ModelNode::isValidId(newId) || hasId(newId) || rootModelNode().hasProperty(newId.toUtf8())) { - ++counter; - newId = QString(QStringLiteral("%1%2")).arg(firstCharToLower(newBaseId)).arg(counter); - } - - return newId; -} - -QString AbstractView::generateNewId(const QString &prefixName) const -{ - return generateNewId(prefixName, QStringLiteral("element")); + return model()->hasId(id); } ModelNode AbstractView::modelNodeForInternalId(qint32 internalId) const diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 39b24186232..64a45e0a894 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -67,6 +67,8 @@ #include +#include + /*! \defgroup CoreModel */ @@ -1444,6 +1446,57 @@ bool Model::hasImport(const Import &import, bool ignoreAlias, bool allowHigherVe return false; } +bool Model::hasId(const QString &id) const +{ + return d->hasId(id); +} + +static QString firstCharToLower(const QString &string) +{ + QString resultString = string; + + if (!resultString.isEmpty()) + resultString[0] = resultString.at(0).toLower(); + + return resultString; +} + +QString Model::generateNewId(const QString &prefixName, const QString &fallbackPrefix) const +{ + // First try just the prefixName without number as postfix, then continue with 2 and further + // as postfix until id does not already exist. + // Properties of the root node are not allowed for ids, because they are available in the + // complete context without qualification. + + int counter = 0; + + QString newBaseId = QString(QStringLiteral("%1")).arg(firstCharToLower(prefixName)); + newBaseId.remove(QRegularExpression(QStringLiteral("[^a-zA-Z0-9_]"))); + + if (!newBaseId.isEmpty()) { + QChar firstChar = newBaseId.at(0); + if (firstChar.isDigit()) + newBaseId.prepend('_'); + } else { + newBaseId = fallbackPrefix; + } + + QString newId = newBaseId; + + while (!ModelNode::isValidId(newId) || hasId(newId) + || d->rootNode()->hasProperty(newId.toUtf8())) { + ++counter; + newId = QString(QStringLiteral("%1%2")).arg(firstCharToLower(newBaseId)).arg(counter); + } + + return newId; +} + +QString Model::generateNewId(const QString &prefixName) const +{ + return generateNewId(prefixName, QStringLiteral("element")); +} + bool Model::isImportPossible(const Import &import, bool ignoreAlias, bool allowHigherVersion) const { if (imports().contains(import)) diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/designercore/model/modelnode.cpp index 288d9dadc4f..c6851548759 100644 --- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelnode.cpp @@ -25,7 +25,6 @@ #include "modelnode.h" #include -#include #include #include #include "internalnode_p.h" @@ -144,7 +143,7 @@ QString ModelNode::id() const QString ModelNode::validId() { if (id().isEmpty()) - setIdWithRefactoring(view()->generateNewId(simplifiedTypeName())); + setIdWithRefactoring(model()->generateNewId(simplifiedTypeName())); return id(); } @@ -270,7 +269,8 @@ void ModelNode::setIdWithoutRefactoring(const QString &id) if (id == m_internalNode->id()) return; - if (view()->hasId(id)) + + if (model()->hasId(id)) throw InvalidIdException(__LINE__, __FUNCTION__, __FILE__, id.toUtf8(), InvalidIdException::DuplicateId); m_model.data()->d->changeNodeId(internalNode(), id); diff --git a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp index bc5089f5305..844240f0b92 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp @@ -117,7 +117,7 @@ QmlItemNode QmlItemNode::createQmlItemNodeFromImage(AbstractView *view, const QS parentproperty.reparentHere(newQmlItemNode); QFileInfo fi(relativeImageName); - newQmlItemNode.setId(view->generateNewId(fi.baseName(), "image")); + newQmlItemNode.setId(view->model()->generateNewId(fi.baseName(), "image")); newQmlItemNode.modelNode().variantProperty("fillMode").setEnumeration("Image.PreserveAspectFit"); @@ -168,7 +168,7 @@ QmlItemNode QmlItemNode::createQmlItemNodeFromFont(AbstractView *view, metaInfo.minorVersion(), propertyPairList)); parentproperty.reparentHere(newQmlItemNode); - newQmlItemNode.setId(view->generateNewId("text", "text")); + newQmlItemNode.setId(view->model()->generateNewId("text", "text")); Q_ASSERT(newQmlItemNode.isValid()); }; diff --git a/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp index 6a78e11cdba..d6f417407c1 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp @@ -335,7 +335,7 @@ QmlObjectNode QmlVisualNode::createQmlObjectNode(AbstractView *view, if (!newQmlObjectNode.isValid()) return; - newQmlObjectNode.setId(view->generateNewId(itemLibraryEntry.name())); + newQmlObjectNode.setId(view->model()->generateNewId(itemLibraryEntry.name())); for (const auto &propertyBindingEntry : propertyBindingList) newQmlObjectNode.modelNode().bindingProperty(propertyBindingEntry.first).setExpression(propertyBindingEntry.second);