forked from qt-creator/qt-creator
QmlDesigner: Add generated components when adding to content lib
Also few relevant fixes and tweaks. Fixes: QDS-13746 Change-Id: I2a22d535591d6908ca3960145cb01682844aee38 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Ali Kianian <ali.kianian@qt.io>
This commit is contained in:
@@ -38,6 +38,11 @@ Utils::FilePath AssetPath::absFilPath() const
|
||||
return basePath.pathAppended(relativePath);
|
||||
}
|
||||
|
||||
QByteArray AssetPath::fileContent() const
|
||||
{
|
||||
return absFilPath().fileContents().value_or("");
|
||||
}
|
||||
|
||||
BundleHelper::BundleHelper(AbstractView *view, QWidget *widget)
|
||||
: m_view(view)
|
||||
, m_widget(widget)
|
||||
@@ -186,7 +191,7 @@ void BundleHelper::importBundleToProject()
|
||||
}
|
||||
|
||||
QString typePrefix = compUtils.userBundleType(bundleId);
|
||||
TypeName type = QLatin1String("%1.%2").arg(typePrefix, qml.chopped(4)).toLatin1();
|
||||
TypeName type = QLatin1String("%1.%2").arg(typePrefix, qml.section('.', 0, 0)).toLatin1();
|
||||
|
||||
QString err = m_importer->importComponent(bundlePath.toFSPathString(), type, qml, files);
|
||||
|
||||
@@ -211,12 +216,6 @@ void BundleHelper::exportComponent(const ModelNode &node)
|
||||
if (exportPath.isEmpty())
|
||||
return;
|
||||
|
||||
// targetPath is a temp path for collecting and zipping assets, actual export target is where
|
||||
// the user chose to export (i.e. exportPath)
|
||||
QTemporaryDir tempDir;
|
||||
QTC_ASSERT(tempDir.isValid(), return);
|
||||
auto targetPath = Utils::FilePath::fromString(tempDir.path());
|
||||
|
||||
m_zipWriter = std::make_unique<ZipWriter>(exportPath);
|
||||
|
||||
Utils::FilePath compFilePath = Utils::FilePath::fromString(ModelUtils::componentFilePath(node));
|
||||
@@ -224,14 +223,14 @@ void BundleHelper::exportComponent(const ModelNode &node)
|
||||
QString compBaseName = compFilePath.completeBaseName();
|
||||
QString compFileName = compFilePath.fileName();
|
||||
|
||||
QString iconPath = QLatin1String("icons/%1").arg(UniqueName::generateId(compBaseName) + ".png");
|
||||
m_iconPath = QLatin1String("icons/%1").arg(UniqueName::generateId(compBaseName) + ".png");
|
||||
|
||||
const QSet<AssetPath> compDependencies = getComponentDependencies(compFilePath, compDir);
|
||||
|
||||
QStringList filesList;
|
||||
for (const AssetPath &asset : compDependencies) {
|
||||
Utils::FilePath assetAbsPath = asset.absFilPath();
|
||||
QByteArray assetContent = assetAbsPath.fileContents().value_or("");
|
||||
QByteArray assetContent = asset.fileContent();
|
||||
|
||||
// remove imports of sub components
|
||||
for (const QString &import : std::as_const(asset.importsToRemove)) {
|
||||
@@ -252,7 +251,7 @@ void BundleHelper::exportComponent(const ModelNode &node)
|
||||
itemsArr.append(QJsonObject {
|
||||
{"name", node.simplifiedTypeName()},
|
||||
{"qml", compFileName},
|
||||
{"icon", iconPath},
|
||||
{"icon", m_iconPath},
|
||||
{"files", QJsonArray::fromStringList(filesList)}
|
||||
});
|
||||
|
||||
@@ -262,12 +261,9 @@ void BundleHelper::exportComponent(const ModelNode &node)
|
||||
jsonObj["id"] = compUtils.user3DBundleId();
|
||||
jsonObj["version"] = BUNDLE_VERSION;
|
||||
|
||||
Utils::FilePath jsonFilePath = targetPath.pathAppended(Constants::BUNDLE_JSON_FILENAME);
|
||||
m_zipWriter->addFile(jsonFilePath.fileName(), QJsonDocument(jsonObj).toJson());
|
||||
m_zipWriter->addFile(Constants::BUNDLE_JSON_FILENAME, QJsonDocument(jsonObj).toJson());
|
||||
|
||||
// add icon
|
||||
m_iconSavePath = targetPath.pathAppended(iconPath);
|
||||
m_iconSavePath.parentDir().ensureWritableDir();
|
||||
getImageFromCache(compFilePath.path(), [&](const QImage &image) {
|
||||
addIconAndCloseZip(image);
|
||||
});
|
||||
@@ -293,6 +289,7 @@ void BundleHelper::exportNode(const ModelNode &node, const QPixmap &iconPixmap)
|
||||
|
||||
QString qml = nodeNameToComponentFileName(name);
|
||||
QString iconBaseName = UniqueName::generateId(name);
|
||||
m_iconPath = QLatin1String("icons/%1.png").arg(iconBaseName);
|
||||
|
||||
// generate and save Qml file
|
||||
auto [qmlString, depAssets] = modelNodeToQmlString(node);
|
||||
@@ -307,15 +304,13 @@ void BundleHelper::exportNode(const ModelNode &node, const QPixmap &iconPixmap)
|
||||
QTC_ASSERT_EXPECTED(result, return);
|
||||
m_zipWriter->addFile(qmlFilePath.fileName(), qmlString.toUtf8());
|
||||
|
||||
QString iconPath = QLatin1String("icons/%1.png").arg(iconBaseName);
|
||||
|
||||
// add the item to the bundle json
|
||||
QJsonObject jsonObj;
|
||||
QJsonArray itemsArr;
|
||||
itemsArr.append(QJsonObject {
|
||||
{"name", name},
|
||||
{"qml", qml},
|
||||
{"icon", iconPath},
|
||||
{"icon", m_iconPath},
|
||||
{"files", QJsonArray::fromStringList(depAssetsRelativePaths)}
|
||||
});
|
||||
|
||||
@@ -331,7 +326,7 @@ void BundleHelper::exportNode(const ModelNode &node, const QPixmap &iconPixmap)
|
||||
|
||||
// add item's dependency assets to the bundle zip and target path (for icon generation)
|
||||
for (const AssetPath &assetPath : depAssetsList) {
|
||||
auto assetContent = assetPath.absFilPath().fileContents().value_or("");
|
||||
QByteArray assetContent = assetPath.fileContent();
|
||||
m_zipWriter->addFile(assetPath.relativePath, assetContent);
|
||||
|
||||
Utils::FilePath assetTargetPath = targetPath.pathAppended(assetPath.relativePath);
|
||||
@@ -352,7 +347,6 @@ void BundleHelper::exportNode(const ModelNode &node, const QPixmap &iconPixmap)
|
||||
iconPixmapToSave = iconPixmap;
|
||||
}
|
||||
|
||||
m_iconSavePath = targetPath.pathAppended(iconPath);
|
||||
if (iconPixmapToSave.isNull()) {
|
||||
getImageFromCache(qmlFilePath.toFSPathString(), [&](const QImage &image) {
|
||||
addIconAndCloseZip(image);
|
||||
@@ -556,7 +550,7 @@ void BundleHelper::addIconAndCloseZip(const auto &image) { // auto: QImage or QP
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
image.save(&buffer, "PNG");
|
||||
|
||||
m_zipWriter->addFile("icons/" + m_iconSavePath.fileName(), iconByteArray);
|
||||
m_zipWriter->addFile(m_iconPath, iconByteArray);
|
||||
m_zipWriter->close();
|
||||
};
|
||||
|
||||
@@ -664,7 +658,7 @@ Utils::FilePath getComponentFilePath(const QString &nodeType, const Utils::FileP
|
||||
} // namespace
|
||||
|
||||
QSet<AssetPath> BundleHelper::getComponentDependencies(const Utils::FilePath &filePath,
|
||||
const Utils::FilePath &mainCompDir)
|
||||
const Utils::FilePath &mainCompDir) const
|
||||
{
|
||||
QSet<AssetPath> depList;
|
||||
AssetPath compAssetPath = {mainCompDir, filePath.relativePathFrom(mainCompDir).toFSPathString()};
|
||||
|
@@ -32,6 +32,7 @@ public:
|
||||
{}
|
||||
|
||||
Utils::FilePath absFilPath() const;
|
||||
QByteArray fileContent() const;
|
||||
|
||||
bool operator==(const AssetPath &other) const
|
||||
{
|
||||
@@ -62,6 +63,8 @@ public:
|
||||
QString nodeNameToComponentFileName(const QString &name) const;
|
||||
QPair<QString, QSet<AssetPath>> modelNodeToQmlString(const ModelNode &node, int depth = 0);
|
||||
QString getImportPath() const;
|
||||
QSet<AssetPath> getComponentDependencies(const Utils::FilePath &filePath,
|
||||
const Utils::FilePath &mainCompDir) const;
|
||||
|
||||
private:
|
||||
void createImporter();
|
||||
@@ -71,8 +74,6 @@ private:
|
||||
void addIconAndCloseZip(const auto &image);
|
||||
Utils::FilePath componentPath(const NodeMetaInfo &metaInfo) const;
|
||||
QSet<AssetPath> getBundleComponentDependencies(const ModelNode &node) const;
|
||||
QSet<AssetPath> getComponentDependencies(const Utils::FilePath &filePath,
|
||||
const Utils::FilePath &mainCompDir);
|
||||
void exportComponent(const ModelNode &node);
|
||||
void exportNode(const ModelNode &node, const QPixmap &iconPixmap = QPixmap());
|
||||
|
||||
@@ -81,7 +82,7 @@ private:
|
||||
Utils::UniqueObjectPtr<BundleImporter> m_importer;
|
||||
std::unique_ptr<ZipWriter> m_zipWriter;
|
||||
std::unique_ptr<QTemporaryDir> m_tempDir;
|
||||
Utils::FilePath m_iconSavePath;
|
||||
QString m_iconPath;
|
||||
|
||||
static constexpr char BUNDLE_VERSION[] = "1.0";
|
||||
};
|
||||
|
@@ -84,7 +84,7 @@ void ContentLibraryUserModel::addItem(const QString &bundleId, const QString &na
|
||||
auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils();
|
||||
|
||||
QString typePrefix = compUtils.userBundleType(bundleId);
|
||||
TypeName type = QLatin1String("%1.%2").arg(typePrefix, qml.chopped(4)).toLatin1();
|
||||
TypeName type = QLatin1String("%1.%2").arg(typePrefix, qml.section('.', 0, 0)).toLatin1();
|
||||
|
||||
SectionIndex sectionIndex = bundleIdToSectionIndex(bundleId);
|
||||
|
||||
@@ -308,7 +308,7 @@ void ContentLibraryUserModel::updateImportedState(const QStringList &importedIte
|
||||
bool changed = false;
|
||||
for (QObject *item : items) {
|
||||
ContentLibraryItem *castedItem = qobject_cast<ContentLibraryItem *>(item);
|
||||
changed |= castedItem->setImported(importedItems.contains(castedItem->qml().chopped(4)));
|
||||
changed |= castedItem->setImported(importedItems.contains(castedItem->qml().section('.', 0, 0)));
|
||||
}
|
||||
|
||||
if (changed)
|
||||
|
@@ -570,17 +570,18 @@ void ContentLibraryView::addLibAssets(const QStringList &paths)
|
||||
m_widget->userModel()->addTextures(targetPathsToAdd);
|
||||
}
|
||||
|
||||
// TODO: combine this method with BundleHelper::exportComponent()
|
||||
void ContentLibraryView::addLib3DComponent(const ModelNode &node)
|
||||
{
|
||||
auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils();
|
||||
auto bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/3d/");
|
||||
|
||||
m_bundleId = compUtils.user3DBundleId();
|
||||
|
||||
QString compBaseName = node.simplifiedTypeName();
|
||||
QString compFileName = compBaseName + ".qml";
|
||||
|
||||
auto compDir = Utils::FilePath::fromString(ModelUtils::componentFilePath(node)).parentDir();
|
||||
auto bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/3d/");
|
||||
Utils::FilePath compFilePath = Utils::FilePath::fromString(ModelUtils::componentFilePath(node));
|
||||
Utils::FilePath compDir = compFilePath.parentDir();
|
||||
QString compBaseName = compFilePath.completeBaseName();
|
||||
QString compFileName = compFilePath.fileName();
|
||||
|
||||
// confirm overwrite if an item with same name exists
|
||||
if (bundlePath.pathAppended(compFileName).exists()) {
|
||||
@@ -599,24 +600,28 @@ void ContentLibraryView::addLib3DComponent(const ModelNode &node)
|
||||
m_iconSavePath = bundlePath.pathAppended(iconPath);
|
||||
m_iconSavePath.parentDir().ensureWritableDir();
|
||||
|
||||
const Utils::FilePaths sourceFiles = compDir.dirEntries({{}, QDir::Files, QDirIterator::Subdirectories});
|
||||
const QStringList ignoreList {"_importdata.json", "qmldir", compBaseName + ".hints"};
|
||||
const QSet<AssetPath> compDependencies = m_bundleHelper->getComponentDependencies(compFilePath, compDir);
|
||||
|
||||
QStringList filesList; // 3D component's assets (dependencies)
|
||||
for (const AssetPath &asset : compDependencies) {
|
||||
Utils::FilePath assetAbsPath = asset.absFilPath();
|
||||
QByteArray assetContent = asset.fileContent();
|
||||
|
||||
for (const Utils::FilePath &sourcePath : sourceFiles) {
|
||||
Utils::FilePath relativePath = sourcePath.relativePathFrom(compDir);
|
||||
if (ignoreList.contains(sourcePath.fileName()) || relativePath.startsWith("source scene"))
|
||||
continue;
|
||||
// remove imports of sub components
|
||||
for (const QString &import : std::as_const(asset.importsToRemove)) {
|
||||
int removeIdx = assetContent.indexOf(QByteArray("import " + import.toLatin1()));
|
||||
int removeLen = assetContent.indexOf('\n', removeIdx) - removeIdx;
|
||||
assetContent.remove(removeIdx, removeLen);
|
||||
}
|
||||
|
||||
Utils::FilePath targetPath = bundlePath.pathAppended(relativePath.path());
|
||||
Utils::FilePath targetPath = bundlePath.pathAppended(asset.relativePath);
|
||||
targetPath.parentDir().ensureWritableDir();
|
||||
|
||||
// copy item from project to user bundle
|
||||
auto result = sourcePath.copyFile(targetPath);
|
||||
auto result = targetPath.writeFileContents(assetContent);
|
||||
QTC_ASSERT_EXPECTED(result,);
|
||||
|
||||
if (sourcePath.fileName() != compFileName) // skip component file (only collect dependencies)
|
||||
filesList.append(relativePath.path());
|
||||
if (assetAbsPath.fileName() != compFileName) // skip component file (only collect dependencies)
|
||||
filesList.append(asset.relativePath);
|
||||
}
|
||||
|
||||
// add the item to the bundle json
|
||||
|
@@ -78,7 +78,7 @@ void UserItemCategory::loadBundle(bool force)
|
||||
|
||||
QString name = itemObj.value("name").toString();
|
||||
QString qml = itemObj.value("qml").toString();
|
||||
TypeName type = QLatin1String("%1.%2").arg(typePrefix, qml.chopped(4)).toLatin1();
|
||||
TypeName type = QLatin1String("%1.%2").arg(typePrefix, qml.section('.', 0, 0)).toLatin1();
|
||||
QUrl icon = m_bundlePath.pathAppended(itemObj.value("icon").toString()).toUrl();
|
||||
QStringList files = itemObj.value("files").toVariant().toStringList();
|
||||
|
||||
|
Reference in New Issue
Block a user