QmlDesigner: Allow adding imported 3D components to content library

Fixes: QDS-12784
Change-Id: I87edf8f6c14fabb066c85e8536c91b58e439e5d0
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
Reviewed-by: Ali Kianian <ali.kianian@qt.io>
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
Mahmoud Badri
2024-05-23 11:33:45 +03:00
parent 8bfe805645
commit 2eb396b83d
6 changed files with 89 additions and 14 deletions

View File

@@ -312,8 +312,7 @@ QPair<QString, QString> ContentLibraryUserModel::getUniqueLibItemNames(const QSt
itemIcons.append(QFileInfo(obj.value("icon").toString()).baseName());
}
QString baseQml = defaultName.trimmed();
baseQml.remove(' ');
QString baseQml = UniqueName::generateId(defaultName);
baseQml[0] = baseQml.at(0).toUpper();
baseQml.prepend("My");

View File

@@ -23,8 +23,9 @@
#include <qmldesignerconstants.h>
#include <qmldesignerplugin.h>
#include <qmlobjectnode.h>
#include <variantproperty.h>
#include <uniquename.h>
#include <utils3d.h>
#include <variantproperty.h>
#include <utils/algorithm.h>
@@ -367,6 +368,9 @@ void ContentLibraryView::customNotification(const AbstractView *view,
} else if (identifier == "add_assets_to_content_lib") {
addLibAssets(data.first().toStringList());
} else if (identifier == "add_3d_to_content_lib") {
if (nodeList.first().isComponent())
addLib3DComponent(nodeList.first());
else
addLib3DItem(nodeList.first());
}
}
@@ -663,6 +667,67 @@ void ContentLibraryView::addLibAssets(const QStringList &paths)
m_widget->userModel()->addTextures(pathsInBundle);
}
void ContentLibraryView::addLib3DComponent(const ModelNode &node)
{
auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils();
// TODO: check component with existing name and show a confirmation dialog
QString compBaseName = node.simplifiedTypeName();
QString compFileName = compBaseName + ".qml";
Utils::FilePath compDir = DocumentManager::currentProjectDirPath()
.pathAppended(compUtils.import3dTypePath() + '/' + compBaseName);
auto bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/3d/");
// generate and save icon
UniqueName::generateId(compBaseName);
QString iconPath = QLatin1String("icons/%1").arg(UniqueName::generateId(compBaseName) + ".png");
QString fullIconPath = bundlePath.pathAppended(iconPath).toString();
genAndSaveIcon(compDir.pathAppended(compFileName).path(), fullIconPath);
const Utils::FilePaths sourceFiles = compDir.dirEntries({{}, QDir::Files, QDirIterator::Subdirectories});
const QStringList ignoreList {"_importdata.json", "qmldir", compBaseName + ".hints"};
QStringList filesList; // 3D component's assets (dependencies)
for (const Utils::FilePath &sourcePath : sourceFiles) {
Utils::FilePath relativePath = sourcePath.relativePathFrom(compDir);
if (ignoreList.contains(sourcePath.fileName()) || relativePath.startsWith("source scene"))
continue;
Utils::FilePath targetPath = bundlePath.pathAppended(relativePath.path());
targetPath.parentDir().ensureWritableDir();
// copy item from project to user bundle
auto result = sourcePath.copyFile(targetPath);
if (!result)
qWarning() << __FUNCTION__ << result.error();
if (sourcePath.fileName() != compFileName) // skip component file (only collect dependencies)
filesList.append(relativePath.path());
}
// add the item to the bundle json
QJsonObject &jsonRef = m_widget->userModel()->bundleJson3DObjectRef();
QJsonArray itemsArr = jsonRef.value("items").toArray();
itemsArr.append(QJsonObject {
{"name", node.simplifiedTypeName()},
{"qml", compFileName},
{"icon", iconPath},
{"files", QJsonArray::fromStringList(filesList)}
});
jsonRef["items"] = itemsArr;
auto result = bundlePath.pathAppended("user_3d_bundle.json")
.writeFileContents(QJsonDocument(jsonRef).toJson());
if (!result)
qWarning() << __FUNCTION__ << result.error();
m_widget->userModel()->add3DItem(compBaseName, compFileName, QUrl::fromLocalFile(fullIconPath),
filesList);
}
void ContentLibraryView::addLib3DItem(const ModelNode &node)
{
auto bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/3d/");
@@ -682,16 +747,13 @@ void ContentLibraryView::addLib3DItem(const ModelNode &node)
// add the item to the bundle json
QJsonObject &jsonRef = m_widget->userModel()->bundleJson3DObjectRef();
QJsonArray itemsArr = jsonRef.value("items").toArray();
QJsonObject itemObj;
itemObj.insert("name", name);
itemObj.insert("qml", qml);
itemObj.insert("icon", iconPath);
QJsonArray filesArr;
for (const QString &assetPath : depAssets)
filesArr.append(assetPath);
itemObj.insert("files", filesArr);
itemsArr.append(QJsonObject {
{"name", name},
{"qml", qml},
{"icon", iconPath},
{"files", QJsonArray::fromStringList(depAssets)}
});
itemsArr.append(itemObj);
jsonRef["items"] = itemsArr;
auto result = bundlePath.pathAppended("user_3d_bundle.json")

View File

@@ -57,6 +57,7 @@ private:
void updateBundlesQuick3DVersion();
void addLibMaterial(const ModelNode &node, const QPixmap &iconPixmap);
void addLibAssets(const QStringList &paths);
void addLib3DComponent(const ModelNode &node);
void addLib3DItem(const ModelNode &node);
void genAndSaveIcon(const QString &qmlPath, const QString &iconPath);
QStringList writeLibItemQml(const ModelNode &node, const QString &qml);

View File

@@ -156,6 +156,9 @@ QString generateId(const QString &id, std::function<bool(const QString &)> predi
if (newId.at(0).isDigit() || std::binary_search(std::begin(keywords), std::end(keywords), newId))
newId.prepend('_');
if (!predicate)
return newId;
return UniqueName::generate(newId, predicate);
}

View File

@@ -11,6 +11,7 @@ namespace QmlDesigner::UniqueName {
QString generate(const QString &name, std::function<bool(const QString &)> predicate);
QString generatePath(const QString &path);
QMLDESIGNERCORE_EXPORT QString generateId(const QString &id, std::function<bool(const QString &)> predicate);
QMLDESIGNERCORE_EXPORT QString generateId(const QString &id,
std::function<bool(const QString &)> predicate = {});
} // namespace QmlDesigner::UniqueName

View File

@@ -21,6 +21,15 @@ TEST(UniqueName, generate_returns_same_input_if_predicate_returns_false)
ASSERT_THAT(uniqueName, "abc");
}
TEST(UniqueName, generateId_returns_properly_formatted_id_when_predicate_is_not_provided)
{
QString id = " A bc d _";
QString uniqueId = UniqueName::generateId(id);
ASSERT_THAT(uniqueId, "aBcD_");
}
TEST(UniqueName, generateId_returns_properly_formatted_id)
{
auto pred = [] (const QString &id) -> bool {