forked from qt-creator/qt-creator
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: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -419,7 +419,7 @@ void LayoutInGridLayout::fillEmptyCells()
|
|||||||
newItemNode.setVariantProperty("y", yPos);
|
newItemNode.setVariantProperty("y", yPos);
|
||||||
newItemNode.setVariantProperty("width", 14);
|
newItemNode.setVariantProperty("width", 14);
|
||||||
newItemNode.setVariantProperty("height", 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);
|
m_layoutedNodes.append(m_spacerNodes);
|
||||||
}
|
}
|
||||||
|
@@ -241,7 +241,7 @@ void BackendModel::addNewBackend()
|
|||||||
if (!model->hasImport(import))
|
if (!model->hasImport(import))
|
||||||
model->changeImports({import}, {});
|
model->changeImports({import}, {});
|
||||||
|
|
||||||
QString propertyName = m_connectionView->generateNewId(typeName);
|
QString propertyName = m_connectionView->model()->generateNewId(typeName);
|
||||||
|
|
||||||
NodeMetaInfo metaInfo = model->metaInfo(typeName.toUtf8());
|
NodeMetaInfo metaInfo = model->metaInfo(typeName.toUtf8());
|
||||||
|
|
||||||
|
@@ -141,7 +141,7 @@ QString NodeListView::setNodeId(int internalId, const QString &id)
|
|||||||
{
|
{
|
||||||
ModelNode node = modelNodeForInternalId(internalId);
|
ModelNode node = modelNodeForInternalId(internalId);
|
||||||
if (node.isValid()) {
|
if (node.isValid()) {
|
||||||
QString newId = generateNewId(id);
|
QString newId = model()->generateNewId(id);
|
||||||
node.setIdWithRefactoring(newId);
|
node.setIdWithRefactoring(newId);
|
||||||
return newId;
|
return newId;
|
||||||
}
|
}
|
||||||
|
@@ -910,8 +910,8 @@ ModelNode NavigatorTreeModel::handleItemLibraryShaderDrop(const QString &shaderP
|
|||||||
|
|
||||||
// Rename the node based on shader source
|
// Rename the node based on shader source
|
||||||
QFileInfo fi(relPath);
|
QFileInfo fi(relPath);
|
||||||
newModelNode.setIdWithoutRefactoring(m_view->generateNewId(fi.baseName(),
|
newModelNode.setIdWithoutRefactoring(
|
||||||
"shader"));
|
m_view->model()->generateNewId(fi.baseName(), "shader"));
|
||||||
// Passes can't have children, so move shader node under parent
|
// Passes can't have children, so move shader node under parent
|
||||||
if (targetProperty.parentModelNode().isSubclassOf("QtQuick3D.Pass")) {
|
if (targetProperty.parentModelNode().isSubclassOf("QtQuick3D.Pass")) {
|
||||||
BindingProperty listProp = targetNode.bindingProperty("shaders");
|
BindingProperty listProp = targetNode.bindingProperty("shaders");
|
||||||
@@ -956,8 +956,8 @@ ModelNode NavigatorTreeModel::handleItemLibrarySoundDrop(const QString &soundPat
|
|||||||
|
|
||||||
// Rename the node based on source
|
// Rename the node based on source
|
||||||
QFileInfo fi(relPath);
|
QFileInfo fi(relPath);
|
||||||
newModelNode.setIdWithoutRefactoring(m_view->generateNewId(fi.baseName(),
|
newModelNode.setIdWithoutRefactoring(
|
||||||
"soundEffect"));
|
m_view->model()->generateNewId(fi.baseName(), "soundEffect"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return newModelNode;
|
return newModelNode;
|
||||||
@@ -1073,7 +1073,8 @@ ModelNode NavigatorTreeModel::createTextureNode(const NodeAbstractProperty &targ
|
|||||||
|
|
||||||
// Rename the node based on source image
|
// Rename the node based on source image
|
||||||
QFileInfo fi(imagePath);
|
QFileInfo fi(imagePath);
|
||||||
newModelNode.setIdWithoutRefactoring(m_view->generateNewId(fi.baseName(), "textureImage"));
|
newModelNode.setIdWithoutRefactoring(
|
||||||
|
m_view->model()->generateNewId(fi.baseName(), "textureImage"));
|
||||||
return newModelNode;
|
return newModelNode;
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
@@ -131,7 +131,7 @@ void AddTabDesignerAction::addNewTab()
|
|||||||
tabViewModelNode.majorVersion(),
|
tabViewModelNode.majorVersion(),
|
||||||
tabViewModelNode.minorVersion(),
|
tabViewModelNode.minorVersion(),
|
||||||
propertyList);
|
propertyList);
|
||||||
newTabModelNode.setIdWithRefactoring(newTabModelNode.view()->generateNewId(tabName));
|
newTabModelNode.setIdWithRefactoring(newTabModelNode.model()->generateNewId(tabName));
|
||||||
tabViewModelNode.defaultNodeAbstractProperty().reparentHere(newTabModelNode);
|
tabViewModelNode.defaultNodeAbstractProperty().reparentHere(newTabModelNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -161,8 +161,6 @@ public:
|
|||||||
|
|
||||||
ModelNode modelNodeForId(const QString &id);
|
ModelNode modelNodeForId(const QString &id);
|
||||||
bool hasId(const QString &id) const;
|
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;
|
ModelNode modelNodeForInternalId(qint32 internalId) const;
|
||||||
bool hasModelNodeForInternalId(qint32 internalId) const;
|
bool hasModelNodeForInternalId(qint32 internalId) const;
|
||||||
|
@@ -124,6 +124,11 @@ public:
|
|||||||
|
|
||||||
void clearMetaInfoCache();
|
void clearMetaInfoCache();
|
||||||
|
|
||||||
|
bool hasId(const QString &id) const;
|
||||||
|
|
||||||
|
QString generateNewId(const QString &prefixName) const;
|
||||||
|
QString generateNewId(const QString &prefixName, const QString &fallbackPrefix) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Model();
|
Model();
|
||||||
|
|
||||||
|
@@ -42,7 +42,6 @@
|
|||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
#include <QRegularExpression>
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QtGui/qimage.h>
|
#include <QtGui/qimage.h>
|
||||||
|
|
||||||
@@ -519,52 +518,7 @@ ModelNode AbstractView::modelNodeForId(const QString &id)
|
|||||||
|
|
||||||
bool AbstractView::hasId(const QString &id) const
|
bool AbstractView::hasId(const QString &id) const
|
||||||
{
|
{
|
||||||
return model()->d->hasId(id);
|
return model()->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"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelNode AbstractView::modelNodeForInternalId(qint32 internalId) const
|
ModelNode AbstractView::modelNodeForInternalId(qint32 internalId) const
|
||||||
|
@@ -67,6 +67,8 @@
|
|||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
|
#include <QRegularExpression>
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\defgroup CoreModel
|
\defgroup CoreModel
|
||||||
*/
|
*/
|
||||||
@@ -1444,6 +1446,57 @@ bool Model::hasImport(const Import &import, bool ignoreAlias, bool allowHigherVe
|
|||||||
return false;
|
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
|
bool Model::isImportPossible(const Import &import, bool ignoreAlias, bool allowHigherVersion) const
|
||||||
{
|
{
|
||||||
if (imports().contains(import))
|
if (imports().contains(import))
|
||||||
|
@@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#include "modelnode.h"
|
#include "modelnode.h"
|
||||||
#include <abstractproperty.h>
|
#include <abstractproperty.h>
|
||||||
#include <abstractview.h>
|
|
||||||
#include <model.h>
|
#include <model.h>
|
||||||
#include <nodemetainfo.h>
|
#include <nodemetainfo.h>
|
||||||
#include "internalnode_p.h"
|
#include "internalnode_p.h"
|
||||||
@@ -144,7 +143,7 @@ QString ModelNode::id() const
|
|||||||
QString ModelNode::validId()
|
QString ModelNode::validId()
|
||||||
{
|
{
|
||||||
if (id().isEmpty())
|
if (id().isEmpty())
|
||||||
setIdWithRefactoring(view()->generateNewId(simplifiedTypeName()));
|
setIdWithRefactoring(model()->generateNewId(simplifiedTypeName()));
|
||||||
|
|
||||||
return id();
|
return id();
|
||||||
}
|
}
|
||||||
@@ -270,7 +269,8 @@ void ModelNode::setIdWithoutRefactoring(const QString &id)
|
|||||||
if (id == m_internalNode->id())
|
if (id == m_internalNode->id())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (view()->hasId(id))
|
|
||||||
|
if (model()->hasId(id))
|
||||||
throw InvalidIdException(__LINE__, __FUNCTION__, __FILE__, id.toUtf8(), InvalidIdException::DuplicateId);
|
throw InvalidIdException(__LINE__, __FUNCTION__, __FILE__, id.toUtf8(), InvalidIdException::DuplicateId);
|
||||||
|
|
||||||
m_model.data()->d->changeNodeId(internalNode(), id);
|
m_model.data()->d->changeNodeId(internalNode(), id);
|
||||||
|
@@ -117,7 +117,7 @@ QmlItemNode QmlItemNode::createQmlItemNodeFromImage(AbstractView *view, const QS
|
|||||||
parentproperty.reparentHere(newQmlItemNode);
|
parentproperty.reparentHere(newQmlItemNode);
|
||||||
|
|
||||||
QFileInfo fi(relativeImageName);
|
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");
|
newQmlItemNode.modelNode().variantProperty("fillMode").setEnumeration("Image.PreserveAspectFit");
|
||||||
|
|
||||||
@@ -168,7 +168,7 @@ QmlItemNode QmlItemNode::createQmlItemNodeFromFont(AbstractView *view,
|
|||||||
metaInfo.minorVersion(), propertyPairList));
|
metaInfo.minorVersion(), propertyPairList));
|
||||||
parentproperty.reparentHere(newQmlItemNode);
|
parentproperty.reparentHere(newQmlItemNode);
|
||||||
|
|
||||||
newQmlItemNode.setId(view->generateNewId("text", "text"));
|
newQmlItemNode.setId(view->model()->generateNewId("text", "text"));
|
||||||
|
|
||||||
Q_ASSERT(newQmlItemNode.isValid());
|
Q_ASSERT(newQmlItemNode.isValid());
|
||||||
};
|
};
|
||||||
|
@@ -335,7 +335,7 @@ QmlObjectNode QmlVisualNode::createQmlObjectNode(AbstractView *view,
|
|||||||
if (!newQmlObjectNode.isValid())
|
if (!newQmlObjectNode.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
newQmlObjectNode.setId(view->generateNewId(itemLibraryEntry.name()));
|
newQmlObjectNode.setId(view->model()->generateNewId(itemLibraryEntry.name()));
|
||||||
|
|
||||||
for (const auto &propertyBindingEntry : propertyBindingList)
|
for (const auto &propertyBindingEntry : propertyBindingList)
|
||||||
newQmlObjectNode.modelNode().bindingProperty(propertyBindingEntry.first).setExpression(propertyBindingEntry.second);
|
newQmlObjectNode.modelNode().bindingProperty(propertyBindingEntry.first).setExpression(propertyBindingEntry.second);
|
||||||
|
Reference in New Issue
Block a user