QmlDesigner: Automatically determine if CreateTexture needs import

Avoid having to pass to CreateTexture whether the asset needs importing
or not. Instead check if the asset is already inside the porject or
not. Also small relevant tweaks.

Change-Id: I6a449d76a6b70ab34fe81762fc9e3eacf9b64d04
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
Mahmoud Badri
2023-03-09 18:13:43 +02:00
parent dc254b9a36
commit 27e2823591
7 changed files with 42 additions and 61 deletions

View File

@@ -47,7 +47,7 @@ public:
AssetsLibraryView::AssetsLibraryView(ExternalDependenciesInterface &externalDependencies) AssetsLibraryView::AssetsLibraryView(ExternalDependenciesInterface &externalDependencies)
: AbstractView{externalDependencies} : AbstractView{externalDependencies}
, m_createTextures{this, false} , m_createTextures{this}
{} {}
AssetsLibraryView::~AssetsLibraryView() AssetsLibraryView::~AssetsLibraryView()

View File

@@ -30,7 +30,7 @@ namespace QmlDesigner {
ContentLibraryView::ContentLibraryView(ExternalDependenciesInterface &externalDependencies) ContentLibraryView::ContentLibraryView(ExternalDependenciesInterface &externalDependencies)
: AbstractView(externalDependencies) : AbstractView(externalDependencies)
, m_createTexture(this, true) , m_createTexture(this)
{} {}
ContentLibraryView::~ContentLibraryView() ContentLibraryView::~ContentLibraryView()

View File

@@ -6,6 +6,7 @@
#include "abstractview.h" #include "abstractview.h"
#include "asset.h" #include "asset.h"
#include "documentmanager.h" #include "documentmanager.h"
#include "modelnode.h"
#include "modelnodeoperations.h" #include "modelnodeoperations.h"
#include "nodelistproperty.h" #include "nodelistproperty.h"
#include "nodemetainfo.h" #include "nodemetainfo.h"
@@ -18,18 +19,27 @@
namespace QmlDesigner { namespace QmlDesigner {
CreateTexture::CreateTexture(AbstractView *view, bool importFile) CreateTexture::CreateTexture(AbstractView *view)
: m_view{view} : m_view{view}
, m_importFile{importFile}
{} {}
ModelNode CreateTexture::execute(const QString &filePath, AddTextureMode mode, int sceneId) ModelNode CreateTexture::execute(const QString &filePath, AddTextureMode mode, int sceneId)
{ {
Asset asset(filePath); Asset asset(filePath);
if (!asset.isValidTextureSource() || (m_importFile && !addFileToProject(filePath))) if (!asset.isValidTextureSource())
return {}; return {};
ModelNode texture = createTextureFromImage(filePath, mode); Utils::FilePath assetPath = Utils::FilePath::fromString(filePath);
if (!assetPath.isChildOf(DocumentManager::currentResourcePath())) {
if (!addFileToProject(filePath))
return {};
// after importing change assetPath to path in project
QString assetName = assetPath.fileName();
assetPath = ModelNodeOperations::getImagesDefaultDirectory().pathAppended(assetName);
}
ModelNode texture = createTextureFromImage(assetPath, mode);
if (!texture.isValid()) if (!texture.isValid())
return {}; return {};
@@ -58,7 +68,7 @@ bool CreateTexture::addFileToProject(const QString &filePath)
return true; return true;
} }
ModelNode CreateTexture::createTextureFromImage(const QString &assetPath, AddTextureMode mode) ModelNode CreateTexture::createTextureFromImage(const Utils::FilePath &assetPath, AddTextureMode mode)
{ {
if (mode != AddTextureMode::Texture && mode != AddTextureMode::LightProbe) if (mode != AddTextureMode::Texture && mode != AddTextureMode::LightProbe)
return {}; return {};
@@ -69,18 +79,7 @@ ModelNode CreateTexture::createTextureFromImage(const QString &assetPath, AddTex
NodeMetaInfo metaInfo = m_view->model()->qtQuick3DTextureMetaInfo(); NodeMetaInfo metaInfo = m_view->model()->qtQuick3DTextureMetaInfo();
Utils::FilePath currentDocumentPath = QmlDesigner::DocumentManager::currentFilePath(); QString textureSource = assetPath.relativePathFrom(DocumentManager::currentFilePath()).toString();
Utils::FilePath imageTargetPath;
if (m_importFile) {
QString assetName = Utils::FilePath::fromString(assetPath).fileName();
// if the asset had to be imported from somewhere else, then assetPath is the source where
// the asset was taken from, and we have to compute where it was placed in the project.
imageTargetPath = ModelNodeOperations::getImagesDefaultDirectory().pathAppended(assetName);
} else {
imageTargetPath = Utils::FilePath::fromString(assetPath);
}
QString textureSource = imageTargetPath.relativePathFrom(currentDocumentPath).toString();
ModelNode newTexNode = m_view->getTextureDefaultInstance(textureSource); ModelNode newTexNode = m_view->getTextureDefaultInstance(textureSource);
if (!newTexNode.isValid()) { if (!newTexNode.isValid()) {
@@ -88,7 +87,7 @@ ModelNode CreateTexture::createTextureFromImage(const QString &assetPath, AddTex
metaInfo.majorVersion(), metaInfo.majorVersion(),
metaInfo.minorVersion()); metaInfo.minorVersion());
newTexNode.setIdWithoutRefactoring(m_view->model()->generateNewId(QFileInfo(assetPath).baseName())); newTexNode.setIdWithoutRefactoring(m_view->model()->generateNewId(assetPath.baseName()));
VariantProperty sourceProp = newTexNode.variantProperty("source"); VariantProperty sourceProp = newTexNode.variantProperty("source");
sourceProp.setValue(textureSource); sourceProp.setValue(textureSource);
@@ -136,4 +135,10 @@ ModelNode CreateTexture::resolveSceneEnv(int sceneId)
return activeSceneEnv; return activeSceneEnv;
} }
void CreateTextures::execute(const QStringList &filePaths, AddTextureMode mode, int sceneId)
{
for (const QString &path : filePaths)
CreateTexture::execute(path, mode, sceneId);
}
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -3,13 +3,16 @@
#pragma once #pragma once
#include <modelnode.h>
#include <QObject> #include <QObject>
namespace Utils {
class FilePath;
}
namespace QmlDesigner { namespace QmlDesigner {
class AbstractView; class AbstractView;
class ModelNode;
enum class AddTextureMode { Image, Texture, LightProbe }; enum class AddTextureMode { Image, Texture, LightProbe };
@@ -18,29 +21,24 @@ class CreateTexture : public QObject
Q_OBJECT Q_OBJECT
public: public:
CreateTexture(AbstractView *view, bool importFiles = false); CreateTexture(AbstractView *view);
ModelNode execute(const QString &filePath, AddTextureMode mode = AddTextureMode::Texture, int sceneId = -1); ModelNode execute(const QString &filePath, AddTextureMode mode = AddTextureMode::Texture, int sceneId = -1);
ModelNode resolveSceneEnv(int sceneId); ModelNode resolveSceneEnv(int sceneId);
void assignTextureAsLightProbe(const ModelNode &texture, int sceneId); void assignTextureAsLightProbe(const ModelNode &texture, int sceneId);
private: private:
bool addFileToProject(const QString &filePath); bool addFileToProject(const QString &filePath);
ModelNode createTextureFromImage(const QString &assetPath, AddTextureMode mode); ModelNode createTextureFromImage(const Utils::FilePath &assetPath, AddTextureMode mode);
private:
AbstractView *m_view = nullptr; AbstractView *m_view = nullptr;
bool m_importFile = false;
}; };
class CreateTextures : public CreateTexture class CreateTextures : public CreateTexture
{ {
public: public:
using CreateTexture::CreateTexture; using CreateTexture::CreateTexture;
void execute(const QStringList &filePaths, AddTextureMode mode, int sceneId = -1) void execute(const QStringList &filePaths, AddTextureMode mode, int sceneId = -1);
{
for (const QString &path : filePaths)
CreateTexture::execute(path, mode, sceneId);
}
}; };
} } // namespace QmlDesigner

View File

@@ -5,25 +5,20 @@
#include "bindingproperty.h" #include "bindingproperty.h"
#include "createtexture.h" #include "createtexture.h"
#include "designmodecontext.h"
#include "materialbrowsermodel.h" #include "materialbrowsermodel.h"
#include "materialbrowsertexturesmodel.h" #include "materialbrowsertexturesmodel.h"
#include "materialbrowserwidget.h" #include "materialbrowserwidget.h"
#include "nodeabstractproperty.h" #include "nodeabstractproperty.h"
#include "nodeinstanceview.h"
#include "nodemetainfo.h" #include "nodemetainfo.h"
#include "qmldesignerconstants.h"
#include "qmlobjectnode.h" #include "qmlobjectnode.h"
#include "variantproperty.h" #include "variantproperty.h"
#include <designmodecontext.h>
#include <nodeinstanceview.h>
#include <nodelistproperty.h>
#include <qmldesignerconstants.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/messagebox.h> #include <coreplugin/messagebox.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projecttree.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -31,7 +26,6 @@
#include <QQmlEngine> #include <QQmlEngine>
#include <QQuickItem> #include <QQuickItem>
#include <QQuickView> #include <QQuickView>
#include <QRegularExpression>
#include <QTimer> #include <QTimer>
namespace QmlDesigner { namespace QmlDesigner {
@@ -648,16 +642,7 @@ void MaterialBrowserView::applyTextureToProperty(const QString &matId, const QSt
{ {
executeInTransaction(__FUNCTION__, [&] { executeInTransaction(__FUNCTION__, [&] {
if (m_appliedTextureId.isEmpty() && !m_appliedTexturePath.isEmpty()) { if (m_appliedTextureId.isEmpty() && !m_appliedTexturePath.isEmpty()) {
bool import = true; auto texCreator = new CreateTexture(this);
using namespace ProjectExplorer;
if (Project *proj = ProjectTree::currentProject()) {
Utils::FilePath projDir = proj->projectFilePath().parentDir().pathAppended("content");
if (m_appliedTexturePath.startsWith(projDir.toString()))
import = false;
}
auto texCreator = new CreateTexture(this, import);
ModelNode tex = texCreator->execute(m_appliedTexturePath, AddTextureMode::Texture); ModelNode tex = texCreator->execute(m_appliedTexturePath, AddTextureMode::Texture);
m_appliedTextureId = tex.id(); m_appliedTextureId = tex.id();
m_appliedTexturePath.clear(); m_appliedTexturePath.clear();

View File

@@ -286,7 +286,7 @@ void MaterialBrowserWidget::acceptBundleTextureDropOnMaterial(int matIndex, cons
ModelNode mat = m_materialBrowserModel->materialAt(matIndex); ModelNode mat = m_materialBrowserModel->materialAt(matIndex);
QTC_ASSERT(mat.isValid(), return); QTC_ASSERT(mat.isValid(), return);
auto *creator = new CreateTexture(m_materialBrowserView, true); auto *creator = new CreateTexture(m_materialBrowserView);
m_materialBrowserView->executeInTransaction(__FUNCTION__, [&] { m_materialBrowserView->executeInTransaction(__FUNCTION__, [&] {
ModelNode tex = creator->execute(bundleTexPath.toLocalFile()); ModelNode tex = creator->execute(bundleTexPath.toLocalFile());

View File

@@ -7,14 +7,10 @@
#include "bindingproperty.h" #include "bindingproperty.h"
#include "createtexture.h" #include "createtexture.h"
#include "designermcumanager.h" #include "designermcumanager.h"
#include "documentmanager.h"
#include "modelnodeoperations.h"
#include "nodelistproperty.h"
#include "nodemetainfo.h" #include "nodemetainfo.h"
#include "nodeproperty.h" #include "nodeproperty.h"
#include "qmlitemnode.h" #include "qmlitemnode.h"
#include "qmlobjectnode.h" #include "qmlobjectnode.h"
#include "variantproperty.h"
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -506,11 +502,8 @@ void PropertyEditorValue::commitDrop(const QString &dropData)
m_modelNode.view()->executeInTransaction(__FUNCTION__, [&] { m_modelNode.view()->executeInTransaction(__FUNCTION__, [&] {
QmlDesigner::ModelNode texture = m_modelNode.view()->modelNodeForInternalId(dropData.toInt()); QmlDesigner::ModelNode texture = m_modelNode.view()->modelNodeForInternalId(dropData.toInt());
if (!texture || !texture.metaInfo().isQtQuick3DTexture()) { if (!texture || !texture.metaInfo().isQtQuick3DTexture()) {
Utils::FilePath imagePath = Utils::FilePath::fromString(dropData); auto texCreator = new QmlDesigner::CreateTexture(m_modelNode.view());
texture = texCreator->execute(dropData, QmlDesigner::AddTextureMode::Texture);
bool needsImport = !imagePath.isChildOf(QmlDesigner::DocumentManager::currentResourcePath());
auto texCreator = new QmlDesigner::CreateTexture(m_modelNode.view(), needsImport);
texture = texCreator->execute(imagePath.toString(), QmlDesigner::AddTextureMode::Texture);
texCreator->deleteLater(); texCreator->deleteLater();
} }