QmlDesigner: Close bundle zip properly

In some cases icons are added synchronously, in which case the final
json addition would reopen the zip file without closing.

Fixes: QDS-14856
Change-Id: Ie6401e274c50901c7e871e6d8bed53eaf3c3c356
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
Miikka Heikkinen
2025-03-04 15:16:15 +02:00
parent 9726fffd3d
commit 1cba6bf5af
2 changed files with 16 additions and 10 deletions

View File

@@ -236,7 +236,7 @@ void BundleHelper::exportBundle(const QList<ModelNode> &nodes, const QPixmap &ic
nodesToExport.append(node); nodesToExport.append(node);
} }
m_remainingIcons = nodesToExport.size(); m_remainingFiles = nodesToExport.size() + 1;
for (const ModelNode &node : std::as_const(nodesToExport)) { for (const ModelNode &node : std::as_const(nodesToExport)) {
if (node.isComponent()) if (node.isComponent())
@@ -247,6 +247,7 @@ void BundleHelper::exportBundle(const QList<ModelNode> &nodes, const QPixmap &ic
jsonObj["items"] = itemsArr; jsonObj["items"] = itemsArr;
m_zipWriter->addFile(Constants::BUNDLE_JSON_FILENAME, QJsonDocument(jsonObj).toJson()); m_zipWriter->addFile(Constants::BUNDLE_JSON_FILENAME, QJsonDocument(jsonObj).toJson());
maybeCloseZip();
} }
QJsonObject BundleHelper::exportComponent(const ModelNode &node) QJsonObject BundleHelper::exportComponent(const ModelNode &node)
@@ -281,7 +282,7 @@ QJsonObject BundleHelper::exportComponent(const ModelNode &node)
// add icon // add icon
QString filePath = compFilePath.path(); QString filePath = compFilePath.path();
getImageFromCache(filePath, [this, iconPath](const QImage &image) { getImageFromCache(filePath, [this, iconPath](const QImage &image) {
addIconAndCloseZip(iconPath, image); addIconToZip(iconPath, image);
}); });
return { return {
@@ -344,10 +345,10 @@ QJsonObject BundleHelper::exportNode(const ModelNode &node, const QPixmap &iconP
if (iconPixmapToSave.isNull()) { if (iconPixmapToSave.isNull()) {
getImageFromCache(qmlFilePath.toFSPathString(), [this, iconPath](const QImage &image) { getImageFromCache(qmlFilePath.toFSPathString(), [this, iconPath](const QImage &image) {
addIconAndCloseZip(iconPath, image); addIconToZip(iconPath, image);
}); });
} else { } else {
addIconAndCloseZip(iconPath, iconPixmapToSave); addIconToZip(iconPath, iconPixmapToSave);
} }
return { return {
@@ -358,6 +359,12 @@ QJsonObject BundleHelper::exportNode(const ModelNode &node, const QPixmap &iconP
}; };
} }
void BundleHelper::maybeCloseZip()
{
if (--m_remainingFiles <= 0)
m_zipWriter->close();
}
QPair<QString, QSet<AssetPath>> BundleHelper::modelNodeToQmlString(const ModelNode &node, int depth) QPair<QString, QSet<AssetPath>> BundleHelper::modelNodeToQmlString(const ModelNode &node, int depth)
{ {
static QStringList depListIds; static QStringList depListIds;
@@ -541,16 +548,14 @@ void BundleHelper::getImageFromCache(const QString &qmlPath,
}); });
} }
void BundleHelper::addIconAndCloseZip(const QString &iconPath, const auto &image) { // auto: QImage or QPixmap void BundleHelper::addIconToZip(const QString &iconPath, const auto &image) { // auto: QImage or QPixmap
QByteArray iconByteArray; QByteArray iconByteArray;
QBuffer buffer(&iconByteArray); QBuffer buffer(&iconByteArray);
buffer.open(QIODevice::WriteOnly); buffer.open(QIODevice::WriteOnly);
image.save(&buffer, "PNG"); image.save(&buffer, "PNG");
m_zipWriter->addFile(iconPath, iconByteArray); m_zipWriter->addFile(iconPath, iconByteArray);
maybeCloseZip();
if (--m_remainingIcons <= 0)
m_zipWriter->close();
}; };
QString BundleHelper::getImportPath() const QString BundleHelper::getImportPath() const

View File

@@ -71,18 +71,19 @@ private:
QString getExportPath(const ModelNode &node) const; QString getExportPath(const ModelNode &node) const;
bool isMaterialBundle(const QString &bundleId) const; bool isMaterialBundle(const QString &bundleId) const;
bool isItemBundle(const QString &bundleId) const; bool isItemBundle(const QString &bundleId) const;
void addIconAndCloseZip(const QString &iconPath, const auto &image); void addIconToZip(const QString &iconPath, const auto &image);
Utils::FilePath componentPath(const ModelNode &node) const; Utils::FilePath componentPath(const ModelNode &node) const;
QSet<AssetPath> getBundleComponentDependencies(const ModelNode &node) const; QSet<AssetPath> getBundleComponentDependencies(const ModelNode &node) const;
QJsonObject exportComponent(const ModelNode &node); QJsonObject exportComponent(const ModelNode &node);
QJsonObject exportNode(const ModelNode &node, const QPixmap &iconPixmap = QPixmap()); QJsonObject exportNode(const ModelNode &node, const QPixmap &iconPixmap = QPixmap());
void maybeCloseZip();
QPointer<AbstractView> m_view; QPointer<AbstractView> m_view;
QPointer<QWidget> m_widget; QPointer<QWidget> m_widget;
Utils::UniqueObjectPtr<BundleImporter> m_importer; Utils::UniqueObjectPtr<BundleImporter> m_importer;
std::unique_ptr<ZipWriter> m_zipWriter; std::unique_ptr<ZipWriter> m_zipWriter;
std::unique_ptr<QTemporaryDir> m_tempDir; std::unique_ptr<QTemporaryDir> m_tempDir;
int m_remainingIcons = 0; int m_remainingFiles = 0;
static constexpr char BUNDLE_VERSION[] = "1.0"; static constexpr char BUNDLE_VERSION[] = "1.0";
}; };