forked from qt-creator/qt-creator
QmlDesigner: Add assets to navigator in 1 transaction
...so only 1 undo step is created when dragging multiple assets to navigator. Change-Id: Ifa812eada5ce56a51e164d80864c3826f9875caf Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -535,7 +535,7 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
|
|||||||
if (mimeData->hasFormat("application/vnd.bauhaus.itemlibraryinfo")) {
|
if (mimeData->hasFormat("application/vnd.bauhaus.itemlibraryinfo")) {
|
||||||
handleItemLibraryItemDrop(mimeData, rowNumber, dropModelIndex);
|
handleItemLibraryItemDrop(mimeData, rowNumber, dropModelIndex);
|
||||||
} else if (mimeData->hasFormat("application/vnd.bauhaus.libraryresource")) {
|
} else if (mimeData->hasFormat("application/vnd.bauhaus.libraryresource")) {
|
||||||
QStringList assetsPaths = QString::fromUtf8(mimeData->data("application/vnd.bauhaus.libraryresource")).split(",");
|
const QStringList assetsPaths = QString::fromUtf8(mimeData->data("application/vnd.bauhaus.libraryresource")).split(",");
|
||||||
NodeAbstractProperty targetProperty;
|
NodeAbstractProperty targetProperty;
|
||||||
|
|
||||||
const QModelIndex rowModelIndex = dropModelIndex.sibling(dropModelIndex.row(), 0);
|
const QModelIndex rowModelIndex = dropModelIndex.sibling(dropModelIndex.row(), 0);
|
||||||
@@ -544,7 +544,24 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
|
|||||||
if (foundTarget) {
|
if (foundTarget) {
|
||||||
QList<ModelNode> addedNodes;
|
QList<ModelNode> addedNodes;
|
||||||
ModelNode currNode;
|
ModelNode currNode;
|
||||||
for (const QString &assetPath : std::as_const(assetsPaths)) {
|
|
||||||
|
QSet<QString> neededImports;
|
||||||
|
for (const QString &assetPath : assetsPaths) {
|
||||||
|
QString assetType = ItemLibraryWidget::getAssetTypeAndData(assetPath).first;
|
||||||
|
if (assetType == "application/vnd.bauhaus.libraryresource.shader")
|
||||||
|
neededImports.insert("QtQuick3D");
|
||||||
|
else if (assetType == "application/vnd.bauhaus.libraryresource.sound")
|
||||||
|
neededImports.insert("QtMultimedia");
|
||||||
|
|
||||||
|
if (neededImports.size() == 2)
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const QString &import : std::as_const(neededImports))
|
||||||
|
addImport(import);
|
||||||
|
|
||||||
|
m_view->executeInTransaction("NavigatorTreeModel::dropMimeData", [&] {
|
||||||
|
for (const QString &assetPath : assetsPaths) {
|
||||||
auto assetTypeAndData = ItemLibraryWidget::getAssetTypeAndData(assetPath);
|
auto assetTypeAndData = ItemLibraryWidget::getAssetTypeAndData(assetPath);
|
||||||
QString assetType = assetTypeAndData.first;
|
QString assetType = assetTypeAndData.first;
|
||||||
QString assetData = QString::fromUtf8(assetTypeAndData.second);
|
QString assetData = QString::fromUtf8(assetTypeAndData.second);
|
||||||
@@ -562,6 +579,8 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
|
|||||||
if (currNode.isValid())
|
if (currNode.isValid())
|
||||||
addedNodes.append(currNode);
|
addedNodes.append(currNode);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (!addedNodes.isEmpty()) {
|
if (!addedNodes.isEmpty()) {
|
||||||
moveNodesInteractive(targetProperty, addedNodes, rowNumber);
|
moveNodesInteractive(targetProperty, addedNodes, rowNumber);
|
||||||
m_view->setSelectedModelNodes(addedNodes);
|
m_view->setSelectedModelNodes(addedNodes);
|
||||||
@@ -757,14 +776,12 @@ ModelNode NavigatorTreeModel::handleItemLibraryImageDrop(const QString &imagePat
|
|||||||
// if dropping an image on an existing image, set the source
|
// if dropping an image on an existing image, set the source
|
||||||
targetNode.variantProperty("source").setValue(imagePathRelative);
|
targetNode.variantProperty("source").setValue(imagePathRelative);
|
||||||
} else {
|
} else {
|
||||||
m_view->executeInTransaction("NavigatorTreeModel::handleItemLibraryImageDrop", [&] {
|
|
||||||
// create an image
|
// create an image
|
||||||
QmlItemNode newItemNode = QmlItemNode::createQmlItemNodeFromImage(m_view, imagePath, QPointF(), targetProperty, false);
|
QmlItemNode newItemNode = QmlItemNode::createQmlItemNodeFromImage(m_view, imagePath, QPointF(), targetProperty, false);
|
||||||
if (NodeHints::fromModelNode(targetProperty.parentModelNode()).canBeContainerFor(newItemNode.modelNode()))
|
if (NodeHints::fromModelNode(targetProperty.parentModelNode()).canBeContainerFor(newItemNode.modelNode()))
|
||||||
newModelNode = newItemNode.modelNode();
|
newModelNode = newItemNode.modelNode();
|
||||||
else
|
else
|
||||||
newItemNode.destroy();
|
newItemNode.destroy();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -781,7 +798,6 @@ ModelNode NavigatorTreeModel::handleItemLibraryFontDrop(const QString &fontFamil
|
|||||||
|
|
||||||
ModelNode newModelNode;
|
ModelNode newModelNode;
|
||||||
|
|
||||||
m_view->executeInTransaction("NavigatorTreeModel::handleItemLibraryFontDrop", [&] {
|
|
||||||
if (targetNode.isSubclassOf("QtQuick.Text")) {
|
if (targetNode.isSubclassOf("QtQuick.Text")) {
|
||||||
// if dropping into an existing Text, update font
|
// if dropping into an existing Text, update font
|
||||||
targetNode.variantProperty("font.family").setValue(fontFamily);
|
targetNode.variantProperty("font.family").setValue(fontFamily);
|
||||||
@@ -794,37 +810,37 @@ ModelNode NavigatorTreeModel::handleItemLibraryFontDrop(const QString &fontFamil
|
|||||||
else
|
else
|
||||||
newItemNode.destroy();
|
newItemNode.destroy();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
return newModelNode;
|
return newModelNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavigatorTreeModel::addImport(const QString &importName)
|
||||||
|
{
|
||||||
|
Import import = Import::createLibraryImport(importName);
|
||||||
|
if (!m_view->model()->hasImport(import, true, true)) {
|
||||||
|
const QList<Import> possImports = m_view->model()->possibleImports();
|
||||||
|
for (const auto &possImport : possImports) {
|
||||||
|
if (possImport.url() == import.url()) {
|
||||||
|
import = possImport;
|
||||||
|
m_view->model()->changeImports({import}, {});
|
||||||
|
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManagerImport(import);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ModelNode NavigatorTreeModel::handleItemLibraryShaderDrop(const QString &shaderPath, bool isFragShader,
|
ModelNode NavigatorTreeModel::handleItemLibraryShaderDrop(const QString &shaderPath, bool isFragShader,
|
||||||
NodeAbstractProperty targetProperty,
|
NodeAbstractProperty targetProperty,
|
||||||
const QModelIndex &rowModelIndex)
|
const QModelIndex &rowModelIndex)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_view, return {});
|
QTC_ASSERT(m_view, return {});
|
||||||
|
|
||||||
Import import = Import::createLibraryImport(QStringLiteral("QtQuick3D"));
|
|
||||||
bool addImport = false;
|
|
||||||
if (!m_view->model()->hasImport(import, true, true)) {
|
|
||||||
const QList<Import> possImports = m_view->model()->possibleImports();
|
|
||||||
for (const auto &possImport : possImports) {
|
|
||||||
if (possImport.url() == import.url()) {
|
|
||||||
import = possImport;
|
|
||||||
addImport = true;
|
|
||||||
m_view->model()->changeImports({import}, {});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ModelNode targetNode(modelNodeForIndex(rowModelIndex));
|
ModelNode targetNode(modelNodeForIndex(rowModelIndex));
|
||||||
ModelNode newModelNode;
|
ModelNode newModelNode;
|
||||||
|
|
||||||
const QString relPath = DocumentManager::currentFilePath().toFileInfo().dir().relativeFilePath(shaderPath);
|
const QString relPath = DocumentManager::currentFilePath().toFileInfo().dir().relativeFilePath(shaderPath);
|
||||||
|
|
||||||
m_view->executeInTransaction("NavigatorTreeModel::handleItemLibraryShaderDrop", [&] {
|
|
||||||
if (targetNode.isSubclassOf("QtQuick3D.Shader")) {
|
if (targetNode.isSubclassOf("QtQuick3D.Shader")) {
|
||||||
// if dropping into an existing Shader, update
|
// if dropping into an existing Shader, update
|
||||||
targetNode.variantProperty("stage").setEnumeration(isFragShader ? "Shader.Fragment"
|
targetNode.variantProperty("stage").setEnumeration(isFragShader ? "Shader.Fragment"
|
||||||
@@ -855,10 +871,6 @@ ModelNode NavigatorTreeModel::handleItemLibraryShaderDrop(const QString &shaderP
|
|||||||
newModelNode.setIdWithoutRefactoring(m_view->generateNewId(fi.baseName(),
|
newModelNode.setIdWithoutRefactoring(m_view->generateNewId(fi.baseName(),
|
||||||
"shader"));
|
"shader"));
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if (addImport)
|
|
||||||
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
|
|
||||||
|
|
||||||
return newModelNode;
|
return newModelNode;
|
||||||
}
|
}
|
||||||
@@ -869,26 +881,11 @@ ModelNode NavigatorTreeModel::handleItemLibrarySoundDrop(const QString &soundPat
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(m_view, return {});
|
QTC_ASSERT(m_view, return {});
|
||||||
|
|
||||||
Import import = Import::createLibraryImport(QStringLiteral("QtMultimedia"));
|
|
||||||
bool addImport = false;
|
|
||||||
if (!m_view->model()->hasImport(import, true, true)) {
|
|
||||||
const QList<Import> possImports = m_view->model()->possibleImports();
|
|
||||||
for (const auto &possImport : possImports) {
|
|
||||||
if (possImport.url() == import.url()) {
|
|
||||||
import = possImport;
|
|
||||||
addImport = true;
|
|
||||||
m_view->model()->changeImports({import}, {});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ModelNode targetNode(modelNodeForIndex(rowModelIndex));
|
ModelNode targetNode(modelNodeForIndex(rowModelIndex));
|
||||||
ModelNode newModelNode;
|
ModelNode newModelNode;
|
||||||
|
|
||||||
const QString relPath = DocumentManager::currentFilePath().toFileInfo().dir().relativeFilePath(soundPath);
|
const QString relPath = DocumentManager::currentFilePath().toFileInfo().dir().relativeFilePath(soundPath);
|
||||||
|
|
||||||
m_view->executeInTransaction("NavigatorTreeModel::handleItemLibrarySoundDrop", [&] {
|
|
||||||
if (targetNode.isSubclassOf("QtMultimedia.SoundEffect")) {
|
if (targetNode.isSubclassOf("QtMultimedia.SoundEffect")) {
|
||||||
// if dropping into on an existing SoundEffect, update
|
// if dropping into on an existing SoundEffect, update
|
||||||
targetNode.variantProperty("source").setValue(relPath);
|
targetNode.variantProperty("source").setValue(relPath);
|
||||||
@@ -913,10 +910,6 @@ ModelNode NavigatorTreeModel::handleItemLibrarySoundDrop(const QString &soundPat
|
|||||||
newModelNode.setIdWithoutRefactoring(m_view->generateNewId(fi.baseName(),
|
newModelNode.setIdWithoutRefactoring(m_view->generateNewId(fi.baseName(),
|
||||||
"soundEffect"));
|
"soundEffect"));
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if (addImport)
|
|
||||||
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
|
|
||||||
|
|
||||||
return newModelNode;
|
return newModelNode;
|
||||||
}
|
}
|
||||||
|
@@ -128,6 +128,7 @@ private:
|
|||||||
const QString &imagePath, ModelNode &newNode);
|
const QString &imagePath, ModelNode &newNode);
|
||||||
ModelNode createTextureNode(const NodeAbstractProperty &targetProp, const QString &imagePath);
|
ModelNode createTextureNode(const NodeAbstractProperty &targetProp, const QString &imagePath);
|
||||||
QList<QPersistentModelIndex> nodesToPersistentIndex(const QList<ModelNode> &modelNodes);
|
QList<QPersistentModelIndex> nodesToPersistentIndex(const QList<ModelNode> &modelNodes);
|
||||||
|
void addImport(const QString &importName);
|
||||||
|
|
||||||
QPointer<NavigatorView> m_view;
|
QPointer<NavigatorView> m_view;
|
||||||
mutable QHash<ModelNode, QModelIndex> m_nodeIndexHash;
|
mutable QHash<ModelNode, QModelIndex> m_nodeIndexHash;
|
||||||
|
Reference in New Issue
Block a user