QmlDesigner: Allow adding multiple 3D nodes to the content lib

Fixes: QDS-13201
Change-Id: I5812e7fb90f9d98d3ffa15eaa049a402181b1265
Reviewed-by: Shrief Gabr <shrief.gabr@qt.io>
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
Mahmoud Badri
2025-03-07 13:38:27 +02:00
parent 3f0f5e0ae4
commit ba8303b86b
4 changed files with 50 additions and 31 deletions

View File

@@ -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<ModelNode> 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)

View File

@@ -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<ModelNode> 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<AssetPath> 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<const NodeInstanceView *>(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)

View File

@@ -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<ModelNode, QString> m_nodeIconHash;
int m_remainingIconsToSave = 0;
static constexpr char BUNDLE_VERSION[] = "1.0";
static constexpr char ADD_ITEM_REQ_ID[] = "AddItemReqId";

View File

@@ -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(