diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h index 222943024fa..f61c7a2ce9f 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h @@ -87,12 +87,17 @@ inline bool isModelOrMaterial(const SelectionContext &selectionState) inline bool enableAddToContentLib(const SelectionContext &selectionState) { - ModelNode modelNode = selectionState.currentSingleSelectedNode(); - auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); - bool isInBundle = modelNode.type().startsWith(compUtils.componentBundlesTypePrefix().toLatin1()); - bool isNode3D = modelNode.metaInfo().isQtQuick3DNode(); + const QList nodes = selectionState.selectedModelNodes(); + if (nodes.isEmpty()) + return false; - return isNode3D && !isInBundle; + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + + return std::all_of(nodes.cbegin(), nodes.cend(), [&](const ModelNode &node) { + bool isInBundle = node.type().startsWith(compUtils.componentBundlesTypePrefix().toLatin1()); + bool isNode3D = node.metaInfo().isQtQuick3DNode(); + return isNode3D && !isInBundle; + }); } inline bool are3DNodes(const SelectionContext &selectionState) diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index 7ec0ff221bd..710bd866628 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -461,10 +461,18 @@ void ContentLibraryView::customNotification(const AbstractView *view, addLibAssets(data.first().toStringList()); m_widget->showTab(ContentLibraryWidget::TabIndex::UserAssetsTab); } else if (identifier == "add_3d_to_content_lib") { - if (nodeList.first().isComponent()) - addLib3DComponent(nodeList.first()); - else - addLibItem(nodeList.first()); + const QList selected3DNodes = Utils::filtered(selectedModelNodes(), + [](const ModelNode &node) { + return node.metaInfo().isQtQuick3DNode(); + }); + QTC_ASSERT(!selected3DNodes.isEmpty(), return); + m_remainingIconsToSave = selected3DNodes.size(); + for (const ModelNode &node : selected3DNodes) { + if (node.isComponent()) + addLib3DComponent(node); + else + addLibItem(node); + } m_widget->showTab(ContentLibraryWidget::TabIndex::UserAssetsTab); } } @@ -492,12 +500,14 @@ void ContentLibraryView::auxiliaryDataChanged(const ModelNode &, active3DSceneChanged(data.toInt()); } -void ContentLibraryView::modelNodePreviewPixmapChanged(const ModelNode &, +void ContentLibraryView::modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap, const QByteArray &requestId) { - if (requestId == ADD_ITEM_REQ_ID) - saveIconToBundle(pixmap); + if (requestId == ADD_ITEM_REQ_ID) { + saveIconToBundle(pixmap, m_nodeIconHash.value(node)); + m_nodeIconHash.remove(node); + } } #ifdef QDS_USE_PROJECTSTORAGE @@ -640,8 +650,8 @@ void ContentLibraryView::addLib3DComponent(const ModelNode &node) } QString iconPath = QLatin1String("icons/%1").arg(UniqueName::generateId(compBaseName) + ".png"); - m_iconSavePath = bundlePath.pathAppended(iconPath); - m_iconSavePath.parentDir().ensureWritableDir(); + Utils::FilePath iconSavePath = bundlePath.pathAppended(iconPath); + iconSavePath.parentDir().ensureWritableDir(); const QSet compDependencies = m_bundleHelper->getComponentDependencies(compFilePath, compDir); @@ -683,12 +693,13 @@ void ContentLibraryView::addLib3DComponent(const ModelNode &node) .writeFileContents(QJsonDocument(jsonRef).toJson()); QTC_ASSERT_EXPECTED(result,); - m_widget->userModel()->addItem(m_bundleId, compBaseName, compFileName, m_iconSavePath.toUrl(), + m_widget->userModel()->addItem(m_bundleId, compBaseName, compFileName, iconSavePath.toUrl(), filesList); // generate and save icon - m_bundleHelper->getImageFromCache(compDir.pathAppended(compFileName).path(), [&](const QImage &image) { - saveIconToBundle(image); + m_bundleHelper->getImageFromCache(compDir.pathAppended(compFileName).path(), + [&, iconSavePath](const QImage &image) { + saveIconToBundle(image, iconSavePath.toFSPathString()); }); } @@ -781,10 +792,10 @@ void ContentLibraryView::addLibItem(const ModelNode &node, const QPixmap &iconPi QTC_ASSERT_EXPECTED(result,); } - m_iconSavePath = bundlePath.pathAppended(iconPath); - m_iconSavePath.parentDir().ensureWritableDir(); + Utils::FilePath iconSavePath = bundlePath.pathAppended(iconPath); + iconSavePath.parentDir().ensureWritableDir(); - m_widget->userModel()->addItem(m_bundleId, name, qml, m_iconSavePath.toUrl(), depAssetsRelativePaths); + m_widget->userModel()->addItem(m_bundleId, name, qml, iconSavePath.toUrl(), depAssetsRelativePaths); // generate and save icon QPixmap iconPixmapToSave; @@ -796,21 +807,23 @@ void ContentLibraryView::addLibItem(const ModelNode &node, const QPixmap &iconPi iconPixmapToSave = iconPixmap; if (iconPixmapToSave.isNull()) { + m_nodeIconHash.insert(node, iconSavePath.toFSPathString()); static_cast(model()->nodeInstanceView()) ->previewImageDataForGenericNode(node, {}, {}, ADD_ITEM_REQ_ID); } else { - saveIconToBundle(iconPixmapToSave); + saveIconToBundle(iconPixmapToSave, iconSavePath.toFSPathString()); } } -void ContentLibraryView::saveIconToBundle(const auto &image) { // auto: QImage or QPixmap - bool iconSaved = image.save(m_iconSavePath.toFSPathString()); - if (iconSaved) - m_widget->userModel()->refreshSection(m_bundleId); - else +void ContentLibraryView::saveIconToBundle(const auto &image, const QString &iconPath) { // auto: QImage or QPixmap + --m_remainingIconsToSave; + bool iconSaved = image.save(iconPath); + if (iconSaved) { + if (m_remainingIconsToSave <= 0) + m_widget->userModel()->refreshSection(m_bundleId); + } else { qWarning() << __FUNCTION__ << ": icon save failed"; - - m_iconSavePath.clear(); + } } void ContentLibraryView::decodeAndAddToContentLib(const QByteArray &data) diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h index de9886bff32..e8cc641c32c 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h @@ -67,7 +67,7 @@ private: void addLib3DComponent(const ModelNode &node); void addLibItem(const ModelNode &node, const QPixmap &iconPixmap = {}); void importBundleToContentLib(); - void saveIconToBundle(const auto &image); + void saveIconToBundle(const auto &image, const QString &iconPath); void decodeAndAddToContentLib(const QByteArray &encodedInternalIds); #ifdef QDS_USE_PROJECTSTORAGE @@ -91,9 +91,10 @@ private: bool m_bundleMaterialAddToSelected = false; bool m_hasQuick3DImport = false; qint32 m_sceneId = -1; - Utils::FilePath m_iconSavePath; QString m_generatedFolderName; QString m_bundleId; + QHash m_nodeIconHash; + int m_remainingIconsToSave = 0; static constexpr char BUNDLE_VERSION[] = "1.0"; static constexpr char ADD_ITEM_REQ_ID[] = "AddItemReqId"; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index 124a6ab252d..12e7588c093 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -373,7 +373,7 @@ void Edit3DWidget::createContextMenu() contextIcon(DesignerIcons::CreateIcon), // TODO: placeholder icon tr("Add to Content Library"), [&] { QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); - view()->emitCustomNotification("add_3d_to_content_lib", {m_contextMenuTarget}); // To ContentLibrary + view()->emitCustomNotification("add_3d_to_content_lib", {}); // To ContentLibrary }); m_importBundleAction = m_contextMenu->addAction(