diff --git a/depends/util/src/pathutils.cpp b/depends/util/src/pathutils.cpp index 63f1b9a5..a193212c 100644 --- a/depends/util/src/pathutils.cpp +++ b/depends/util/src/pathutils.cpp @@ -22,6 +22,10 @@ QString PathCombine(QString path1, QString path2) { + if(!path1.size()) + return path2; + if(!path2.size()) + return path1; return QDir::cleanPath(path1 + QDir::separator() + path2); } diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index eebb8a70..059f6d3b 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -1458,13 +1458,101 @@ void MainWindow::on_actionDeleteInstance_triggered() } } +#include + +bool compressSubDir(QuaZip* zip, QString dir, QString origDir, QString prefix) +{ + if (!zip) return false; + if (zip->getMode()!=QuaZip::mdCreate && zip->getMode()!=QuaZip::mdAppend && zip->getMode()!=QuaZip::mdAdd) + { + return false; + } + + QDir directory(dir); + if (!directory.exists()) return false; + + QDir origDirectory(origDir); + if (dir != origDir) + { + QuaZipFile dirZipFile(zip); + auto dirPrefix = PathCombine(prefix, origDirectory.relativeFilePath(dir)) + "/"; + if (!dirZipFile.open(QIODevice::WriteOnly, QuaZipNewInfo(dirPrefix, dir), 0, 0, 0)) + { + return false; + } + dirZipFile.close(); + } + + QFileInfoList files = directory.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Hidden); + for (auto file: files) + { + if(!compressSubDir(zip,file.absoluteFilePath(),origDir, prefix)) + { + return false; + } + } + + files = directory.entryInfoList(QDir::Files); + for (auto file: files) + { + if(!file.isFile()) + { + continue; + } + + if(file.absoluteFilePath()==zip->getZipName()) + { + continue; + } + + QString filename = origDirectory.relativeFilePath(file.absoluteFilePath()); + if(prefix.size()) + { + filename = PathCombine(prefix, filename); + } + if (!JlCompress::compressFile(zip,file.absoluteFilePath(),filename)) + { + return false; + } + } + + return true; +} + +bool compressDir(QString zipFile, QString dir, QString prefix = QString()) +{ + QuaZip zip(zipFile); + QDir().mkpath(QFileInfo(zipFile).absolutePath()); + if(!zip.open(QuaZip::mdCreate)) + { + QFile::remove(zipFile); + return false; + } + + QSet added; + if (!compressSubDir(&zip,dir,dir,prefix)) + { + QFile::remove(zipFile); + return false; + } + zip.close(); + if(zip.getZipError()!=0) + { + QFile::remove(zipFile); + return false; + } + return true; +} + void MainWindow::on_actionExportInstance_triggered() { if (m_selectedInstance) { + auto name = RemoveInvalidFilenameChars(m_selectedInstance->name()); + const QString output = QFileDialog::getSaveFileName(this, tr("Export %1") .arg(m_selectedInstance->name()), - QDir::homePath(), "Zip (*.zip)"); + PathCombine(QDir::homePath(), name + ".zip") , "Zip (*.zip)"); if (output.isNull()) { return; @@ -1478,7 +1566,8 @@ void MainWindow::on_actionExportInstance_triggered() return; } } - if (!JlCompress::compressDir(output, m_selectedInstance->instanceRoot())) + + if (!compressDir(output, m_selectedInstance->instanceRoot(), name)) { QMessageBox::warning(this, tr("Error"), tr("Unable to export instance")); }