forked from qt-creator/qt-creator
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:
@@ -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");
|
||||
|
||||
|
@@ -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")
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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 {
|
||||
|
Reference in New Issue
Block a user