forked from qt-creator/qt-creator
QmlDesigner: Respect canBeContainer on drag from library to navigator
If the parent node can't be a container for the newly created node, the newly created node is deleted within the same transaction. Change-Id: I4f4771add3aae5b4509b3bb0a8fbabfed2e7c99e Fixes: QDS-2660 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -557,9 +557,10 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
|
||||
bool moveNodesAfter = true;
|
||||
|
||||
if (foundTarget) {
|
||||
if (!NodeHints::fromItemLibraryEntry(itemLibraryEntry).canBeDroppedInNavigator())
|
||||
if (!hints.canBeDroppedInNavigator())
|
||||
return;
|
||||
|
||||
bool validContainer = false;
|
||||
QmlObjectNode newQmlObjectNode;
|
||||
m_view->executeInTransaction("NavigatorTreeModel::handleItemLibraryItemDrop", [&] {
|
||||
newQmlObjectNode = QmlItemNode::createQmlObjectNode(m_view, itemLibraryEntry, QPointF(), targetProperty, false);
|
||||
@@ -587,6 +588,7 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
|
||||
ModelNode targetEnv;
|
||||
if (targetProperty.parentModelNode().isSubclassOf("QtQuick3D.SceneEnvironment")) {
|
||||
targetEnv = targetProperty.parentModelNode();
|
||||
validContainer = true;
|
||||
} else if (targetProperty.parentModelNode().isSubclassOf("QtQuick3D.View3D")) {
|
||||
// see if View3D has environment set to it
|
||||
BindingProperty envNodeProp = targetProperty.parentModelNode().bindingProperty("environment");
|
||||
@@ -595,6 +597,7 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
|
||||
if (envNode.isValid())
|
||||
targetEnv = envNode;
|
||||
}
|
||||
validContainer = true;
|
||||
}
|
||||
insertIntoList("effects", targetEnv);
|
||||
} else if (newModelNode.isSubclassOf("QtQuick3D.Material")) {
|
||||
@@ -603,6 +606,7 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
|
||||
ModelNode targetModel;
|
||||
targetModel = targetProperty.parentModelNode();
|
||||
insertIntoList("materials", targetModel);
|
||||
validContainer = true;
|
||||
}
|
||||
} else {
|
||||
const bool isShader = newModelNode.isSubclassOf("QtQuick3D.Shader");
|
||||
@@ -627,22 +631,30 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
|
||||
// want undo to place the node under invalid parent
|
||||
moveNodesAfter = false;
|
||||
moveNodesInteractive(targetProperty, {newQmlObjectNode}, targetRowNumber, false);
|
||||
validContainer = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!validContainer) {
|
||||
validContainer = NodeHints::fromModelNode(targetProperty.parentModelNode()).canBeContainerFor(newModelNode);
|
||||
if (!validContainer)
|
||||
newQmlObjectNode.destroy();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (moveNodesAfter && newQmlObjectNode.isValid() && targetProperty.isNodeListProperty()) {
|
||||
QList<ModelNode> newModelNodeList;
|
||||
newModelNodeList.append(newQmlObjectNode);
|
||||
if (validContainer) {
|
||||
if (moveNodesAfter && newQmlObjectNode.isValid() && targetProperty.isNodeListProperty()) {
|
||||
QList<ModelNode> newModelNodeList;
|
||||
newModelNodeList.append(newQmlObjectNode);
|
||||
|
||||
moveNodesInteractive(targetProperty, newModelNodeList, targetRowNumber);
|
||||
moveNodesInteractive(targetProperty, newModelNodeList, targetRowNumber);
|
||||
}
|
||||
|
||||
if (newQmlObjectNode.isValid())
|
||||
m_view->setSelectedModelNode(newQmlObjectNode.modelNode());
|
||||
}
|
||||
|
||||
if (newQmlObjectNode.isValid())
|
||||
m_view->setSelectedModelNode(newQmlObjectNode.modelNode());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -717,9 +729,14 @@ void NavigatorTreeModel::handleItemLibraryImageDrop(const QMimeData *mimeData, i
|
||||
// if dropping an image on a texture, set the texture source
|
||||
targetNode.variantProperty("source").setValue(imagePath);
|
||||
} else {
|
||||
|
||||
// create an image
|
||||
newModelNode = QmlItemNode::createQmlItemNodeFromImage(m_view, imageSource , QPointF(), targetProperty);
|
||||
m_view->executeInTransaction("NavigatorTreeModel::handleItemLibraryImageDrop", [&] {
|
||||
// create an image
|
||||
QmlItemNode newItemNode = QmlItemNode::createQmlItemNodeFromImage(m_view, imageSource, QPointF(), targetProperty, false);
|
||||
if (NodeHints::fromModelNode(targetProperty.parentModelNode()).canBeContainerFor(newItemNode.modelNode()))
|
||||
newModelNode = newItemNode.modelNode();
|
||||
else
|
||||
newItemNode.destroy();
|
||||
});
|
||||
}
|
||||
|
||||
if (newModelNode.isValid()) {
|
||||
|
@@ -61,11 +61,13 @@ public:
|
||||
static QmlItemNode createQmlItemNodeFromImage(AbstractView *view,
|
||||
const QString &imageName,
|
||||
const QPointF &position,
|
||||
QmlItemNode parentQmlItemNode);
|
||||
QmlItemNode parentQmlItemNode,
|
||||
bool executeInTransaction = true);
|
||||
static QmlItemNode createQmlItemNodeFromImage(AbstractView *view,
|
||||
const QString &imageName,
|
||||
const QPointF &position,
|
||||
NodeAbstractProperty parentproperty);
|
||||
NodeAbstractProperty parentproperty,
|
||||
bool executeInTransaction = true);
|
||||
|
||||
QList<QmlItemNode> children() const;
|
||||
QList<QmlObjectNode> resources() const;
|
||||
|
@@ -73,47 +73,50 @@ QmlItemNode QmlItemNode::createQmlItemNode(AbstractView *view,
|
||||
return QmlItemNode(createQmlObjectNode(view, itemLibraryEntry, position, parentQmlItemNode));
|
||||
}
|
||||
|
||||
QmlItemNode QmlItemNode::createQmlItemNodeFromImage(AbstractView *view, const QString &imageName, const QPointF &position, QmlItemNode parentQmlItemNode)
|
||||
QmlItemNode QmlItemNode::createQmlItemNodeFromImage(AbstractView *view, const QString &imageName, const QPointF &position, QmlItemNode parentQmlItemNode, bool executeInTransaction)
|
||||
{
|
||||
if (!parentQmlItemNode.isValid())
|
||||
parentQmlItemNode = QmlItemNode(view->rootModelNode());
|
||||
|
||||
NodeAbstractProperty parentProperty = parentQmlItemNode.defaultNodeAbstractProperty();
|
||||
|
||||
return QmlItemNode::createQmlItemNodeFromImage(view, imageName, position, parentProperty);
|
||||
return QmlItemNode::createQmlItemNodeFromImage(view, imageName, position, parentProperty, executeInTransaction);
|
||||
}
|
||||
|
||||
QmlItemNode QmlItemNode::createQmlItemNodeFromImage(AbstractView *view, const QString &imageName, const QPointF &position, NodeAbstractProperty parentproperty)
|
||||
QmlItemNode QmlItemNode::createQmlItemNodeFromImage(AbstractView *view, const QString &imageName, const QPointF &position, NodeAbstractProperty parentproperty, bool executeInTransaction)
|
||||
{
|
||||
QmlItemNode newQmlItemNode;
|
||||
|
||||
if (parentproperty.isValid() && view->model()->hasNodeMetaInfo("QtQuick.Image")) {
|
||||
view->executeInTransaction("QmlItemNode::createQmlItemNodeFromImage", [=, &newQmlItemNode, &parentproperty](){
|
||||
NodeMetaInfo metaInfo = view->model()->metaInfo("QtQuick.Image");
|
||||
QList<QPair<PropertyName, QVariant> > propertyPairList;
|
||||
propertyPairList.append({PropertyName("x"), QVariant(qRound(position.x()))});
|
||||
propertyPairList.append({PropertyName("y"), QVariant(qRound(position.y()))});
|
||||
auto doCreateQmlItemNodeFromImage = [=, &newQmlItemNode, &parentproperty]() {
|
||||
NodeMetaInfo metaInfo = view->model()->metaInfo("QtQuick.Image");
|
||||
QList<QPair<PropertyName, QVariant> > propertyPairList;
|
||||
propertyPairList.append({PropertyName("x"), QVariant(qRound(position.x()))});
|
||||
propertyPairList.append({PropertyName("y"), QVariant(qRound(position.y()))});
|
||||
|
||||
QString relativeImageName = imageName;
|
||||
QString relativeImageName = imageName;
|
||||
|
||||
//use relative path
|
||||
if (QFileInfo::exists(view->model()->fileUrl().toLocalFile())) {
|
||||
QDir fileDir(QFileInfo(view->model()->fileUrl().toLocalFile()).absolutePath());
|
||||
relativeImageName = fileDir.relativeFilePath(imageName);
|
||||
propertyPairList.append({PropertyName("source"), QVariant(relativeImageName)});
|
||||
}
|
||||
//use relative path
|
||||
if (QFileInfo::exists(view->model()->fileUrl().toLocalFile())) {
|
||||
QDir fileDir(QFileInfo(view->model()->fileUrl().toLocalFile()).absolutePath());
|
||||
relativeImageName = fileDir.relativeFilePath(imageName);
|
||||
propertyPairList.append({PropertyName("source"), QVariant(relativeImageName)});
|
||||
}
|
||||
|
||||
newQmlItemNode = QmlItemNode(view->createModelNode("QtQuick.Image", metaInfo.majorVersion(), metaInfo.minorVersion(), propertyPairList));
|
||||
parentproperty.reparentHere(newQmlItemNode);
|
||||
newQmlItemNode = QmlItemNode(view->createModelNode("QtQuick.Image", metaInfo.majorVersion(), metaInfo.minorVersion(), propertyPairList));
|
||||
parentproperty.reparentHere(newQmlItemNode);
|
||||
|
||||
QFileInfo fi(relativeImageName);
|
||||
newQmlItemNode.setId(view->generateNewId(fi.baseName(), "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");
|
||||
|
||||
Q_ASSERT(newQmlItemNode.isValid());
|
||||
});
|
||||
}
|
||||
Q_ASSERT(newQmlItemNode.isValid());
|
||||
};
|
||||
|
||||
if (executeInTransaction)
|
||||
view->executeInTransaction("QmlItemNode::createQmlItemNodeFromImage", doCreateQmlItemNodeFromImage);
|
||||
else
|
||||
doCreateQmlItemNodeFromImage();
|
||||
|
||||
return newQmlItemNode;
|
||||
}
|
||||
|
Reference in New Issue
Block a user