diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml index 0bca2d9a935..fdf6cd74ac8 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml @@ -34,6 +34,9 @@ Item { var complexSuffixes = rootView.supportedAssetSuffixes(true) for (const u of drag.urls) { var url = u.toString() + if (assetsModel.urlPathExistsInModel(url)) + continue; + var ext = '*.' + url.slice(url.lastIndexOf('.') + 1).toLowerCase() if (simpleSuffixes.includes(ext)) root.dropSimpleExtFiles.push(url) diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml index daeaab44dad..7e29bf1508e 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml @@ -716,6 +716,8 @@ Item { onDropEnter: (drag) => { drag.accepted = drag.formats[0] === "application/vnd.qtdesignstudio.bundletexture" + || drag.formats[0] === "application/vnd.qtdesignstudio.assets" + highlight = drag.accepted } @@ -726,7 +728,10 @@ Item { onDrop: (drag) => { drag.accept() highlight = false - rootView.acceptBundleTextureDrop() + if (drag.formats[0] === "application/vnd.qtdesignstudio.bundletexture") + rootView.acceptBundleTextureDrop() + else if (drag.formats[0] === "application/vnd.qtdesignstudio.assets") + rootView.acceptAssetsDrop(drag.urls) } onExpandedChanged: { diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp index e7142aa6f70..4818ca3ed3e 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp @@ -150,6 +150,12 @@ bool AssetsLibraryModel::addNewFolder(const QString &folderPath) return dir.mkpath(iterPath); } +bool AssetsLibraryModel::urlPathExistsInModel(const QUrl &url) const +{ + QModelIndex index = indexForPath(url.toLocalFile()); + return index.isValid(); +} + bool AssetsLibraryModel::deleteFolderRecursively(const QModelIndex &folderIndex) { auto idx = mapToSource(folderIndex); diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h index 625216af8a6..5ac2cf7bfc9 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h @@ -39,6 +39,7 @@ public: Q_INVOKABLE QList parentIndices(const QModelIndex &index) const; Q_INVOKABLE bool indexIsValid(const QModelIndex &index) const; + Q_INVOKABLE bool urlPathExistsInModel(const QUrl &url) const; Q_INVOKABLE QString currentProjectDirPath() const; Q_INVOKABLE QString contentDirPath() const; Q_INVOKABLE bool requestDeleteFiles(const QStringList &filePaths); diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp index 33abbbc5dd8..54d766c2cb1 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp @@ -72,8 +72,16 @@ bool AssetsLibraryWidget::eventFilter(QObject *obj, QEvent *event) if ((me->globalPos() - m_dragStartPoint).manhattanLength() > 10) { QMimeData *mimeData = new QMimeData; mimeData->setData(Constants::MIME_TYPE_ASSETS, m_assetsToDrag.join(',').toUtf8()); - m_model->startDrag(mimeData, - m_assetsIconProvider->requestPixmap(m_assetsToDrag[0], nullptr, {128, 128})); + + QList urlsToDrag = Utils::transform(m_assetsToDrag, [](const QString &path) { + return QUrl::fromLocalFile(path); + }); + + mimeData->setUrls(urlsToDrag); + + m_model->startDrag(mimeData, m_assetsIconProvider->requestPixmap(m_assetsToDrag[0], + nullptr, {128, 128})); + m_assetsToDrag.clear(); } } diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index 0651185382a..8a691cd6223 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -235,7 +235,7 @@ ModelNodePreviewImageOperation DesignerActionManager::modelNodePreviewOperation( bool DesignerActionManager::externalDragHasSupportedAssets(const QMimeData *mimeData) const { - if (!mimeData->hasUrls()) + if (!mimeData->hasUrls() || mimeData->hasFormat(Constants::MIME_TYPE_ASSETS)) return false; QSet filtersSet; diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index fc1db47fd40..5066d8aefe2 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -216,6 +216,17 @@ WidgetInfo MaterialBrowserView::widgetInfo() tr("Material Browser view")); } +void MaterialBrowserView::createTextures(const QStringList &assetPaths) +{ + auto *create = new CreateTextures(this, false); + + executeInTransaction("MaterialBrowserView::createTextures", [&]() { + create->execute(assetPaths, AddTextureMode::Texture, m_sceneId); + }); + + create->deleteLater(); +} + void MaterialBrowserView::modelAttached(Model *model) { AbstractView::modelAttached(model); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h index 398269a95fe..da064d4446f 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h @@ -55,6 +55,7 @@ public: void applyTextureToModel3D(const QmlObjectNode &model3D, const ModelNode &texture = {}); void applyTextureToMaterial(const QList &materials, const ModelNode &texture); + void createTextures(const QStringList &assetPaths); Q_INVOKABLE void updatePropsModel(const QString &matId); Q_INVOKABLE void applyTextureToProperty(const QString &matId, const QString &propName); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp index 2f48fc1b73a..8973dc47ae6 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp @@ -278,6 +278,12 @@ void MaterialBrowserWidget::acceptBundleTextureDrop() m_materialBrowserView->model()->endDrag(); } +void MaterialBrowserWidget::acceptAssetsDrop(const QList &urls) +{ + QStringList assetPaths = Utils::transform(urls, [](const QUrl &url) { return url.toLocalFile(); }); + m_materialBrowserView->createTextures(assetPaths); +} + void MaterialBrowserWidget::acceptTextureDropOnMaterial(int matIndex, const QString &texId) { ModelNode mat = m_materialBrowserModel->materialAt(matIndex); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h index 8fe0ceb434c..e607f022546 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h @@ -59,6 +59,7 @@ public: Q_INVOKABLE void startDragTexture(int index, const QPointF &mousePos); Q_INVOKABLE void acceptBundleMaterialDrop(); Q_INVOKABLE void acceptBundleTextureDrop(); + Q_INVOKABLE void acceptAssetsDrop(const QList &urls); Q_INVOKABLE void acceptTextureDropOnMaterial(int matIndex, const QString &texId); Q_INVOKABLE void focusMaterialSection(bool focusMatSec);