QmlDesigner: Generate qml id from image file name

When dragging an image file to create a Image or Texture item,
base the id on the file name rather than setting it to generic name
based on type.

This includes cleanup of AbstractView::generateNewId to remove
redundant and unused code as well as an option to provide a fallback
id prefix.

Change-Id: I563f1760ffbace9c5c2145477ec8736836f36c45
Fixes: QDS-2328
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
Miikka Heikkinen
2020-08-28 15:31:05 +03:00
committed by Thomas Hartmann
parent f1bb1bf572
commit e6343c296a
4 changed files with 26 additions and 23 deletions

View File

@@ -51,6 +51,7 @@
#include <QApplication> #include <QApplication>
#include <QPointF> #include <QPointF>
#include <QDir> #include <QDir>
#include <QFileInfo>
#include <coreplugin/messagebox.h> #include <coreplugin/messagebox.h>
@@ -649,6 +650,10 @@ void NavigatorTreeModel::handleItemLibraryImageDrop(const QMimeData *mimeData, i
// create a texture // create a texture
newModelNode = QmlItemNode::createQmlObjectNode(m_view, itemLibraryEntry, {}, targetProp, false); newModelNode = QmlItemNode::createQmlObjectNode(m_view, itemLibraryEntry, {}, targetProp, false);
// Rename the node based on source image
QFileInfo fi(imagePath);
newModelNode.setIdWithoutRefactoring(m_view->generateNewId(fi.baseName(), "textureImage"));
return newModelNode.isValid(); return newModelNode.isValid();
} }
return false; return false;

View File

@@ -160,6 +160,7 @@ 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 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;

View File

@@ -504,40 +504,36 @@ QString firstCharToLower(const QString &string)
return resultString; return resultString;
} }
QString AbstractView::generateNewId(const QString &prefixName) const QString AbstractView::generateNewId(const QString &prefixName, const QString &fallbackPrefix) const
{ {
QString fixedPrefix = firstCharToLower(prefixName); // First try just the prefixName without number as postfix, then continue with 2 and further
fixedPrefix.remove(' '); // as postfix until id does not already exist.
// Properties of the root node are not allowed for ids, because they are available in the
bool forceSuffix = false; // complete context without qualification.
if (!ModelNode::isValidId(fixedPrefix))
forceSuffix = true;
int counter = 0; int counter = 0;
/* First try just the prefixName without number as postfix, then continue with 2 and further as postfix QString newBaseId = QString(QStringLiteral("%1")).arg(firstCharToLower(prefixName));
* until id does not already exist. newBaseId.remove(QRegExp(QStringLiteral("[^a-zA-Z0-9_]")));
* Properties of the root node are not allowed for ids, because they are available in the complete context
* without qualification.
* The id "item" is explicitly not allowed, because it is too likely to clash.
*/
QString newId = QString(QStringLiteral("%1")).arg(firstCharToLower(prefixName)); if (newBaseId.isEmpty())
if (forceSuffix) newBaseId = fallbackPrefix;
QString(QStringLiteral("%1%2")).arg(firstCharToLower(prefixName)).arg(1);
newId.remove(QRegExp(QStringLiteral("[^a-zA-Z0-9_]"))); QString newId = newBaseId;
while (!ModelNode::isValidId(newId) || hasId(newId) || rootModelNode().hasProperty(newId.toUtf8()) || newId == "item") { while (!ModelNode::isValidId(newId) || hasId(newId) || rootModelNode().hasProperty(newId.toUtf8())) {
counter += 1; ++counter;
newId = QString(QStringLiteral("%1%2")).arg(firstCharToLower(prefixName)).arg(counter); newId = QString(QStringLiteral("%1%2")).arg(firstCharToLower(newBaseId)).arg(counter);
newId.remove(QRegExp(QStringLiteral("[^a-zA-Z0-9_]")));
} }
return newId; 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
{ {
return ModelNode(model()->d->nodeForInternalId(internalId), model(), this); return ModelNode(model()->d->nodeForInternalId(internalId), model(), this);

View File

@@ -106,7 +106,8 @@ QmlItemNode QmlItemNode::createQmlItemNodeFromImage(AbstractView *view, const QS
newQmlItemNode = QmlItemNode(view->createModelNode("QtQuick.Image", metaInfo.majorVersion(), metaInfo.minorVersion(), propertyPairList)); newQmlItemNode = QmlItemNode(view->createModelNode("QtQuick.Image", metaInfo.majorVersion(), metaInfo.minorVersion(), propertyPairList));
parentproperty.reparentHere(newQmlItemNode); parentproperty.reparentHere(newQmlItemNode);
newQmlItemNode.setId(view->generateNewId(QLatin1String("image"))); QFileInfo fi(relativeImageName);
newQmlItemNode.setId(view->generateNewId(fi.baseName(), "image"));
newQmlItemNode.modelNode().variantProperty("fillMode").setEnumeration("Image.PreserveAspectFit"); newQmlItemNode.modelNode().variantProperty("fillMode").setEnumeration("Image.PreserveAspectFit");