diff --git a/app/mainwindow.cpp b/app/mainwindow.cpp --- a/app/mainwindow.cpp +++ b/app/mainwindow.cpp @@ -306,6 +306,9 @@ qCDebug(ARK) << "CreateDialog returned mime:" << dialog.data()->currentMimeType().name(); m_openArgs.metaData()[QStringLiteral("createNewArchive")] = QStringLiteral("true"); + if (dialog.data()->compressionLevel() > -1) { + m_openArgs.metaData()[QStringLiteral("compressionLevel")] = QString::number(dialog.data()->compressionLevel()); + } m_openArgs.metaData()[QStringLiteral("encryptionPassword")] = password; if (dialog.data()->isHeaderEncryptionEnabled()) { @@ -316,6 +319,7 @@ m_openArgs.metaData().remove(QStringLiteral("showExtractDialog")); m_openArgs.metaData().remove(QStringLiteral("createNewArchive")); + m_openArgs.metaData().remove(QStringLiteral("compressionLevel")); m_openArgs.metaData().remove(QStringLiteral("encryptionPassword")); m_openArgs.metaData().remove(QStringLiteral("encryptHeader")); } diff --git a/kerfuffle/archiveformat.h b/kerfuffle/archiveformat.h --- a/kerfuffle/archiveformat.h +++ b/kerfuffle/archiveformat.h @@ -37,7 +37,11 @@ { public: explicit ArchiveFormat(); - explicit ArchiveFormat(const QMimeType& mimeType, Kerfuffle::Archive::EncryptionType encryptionType); + explicit ArchiveFormat(const QMimeType& mimeType, + Kerfuffle::Archive::EncryptionType encryptionType, + int compLevelMin, + int compLevelMax, + int compLevelDefault); /** * @return The archive format of the given @p mimeType, according to the given @p metadata. @@ -54,11 +58,18 @@ */ Kerfuffle::Archive::EncryptionType encryptionType() const; + int compressionLevelMin() const; + int compressionLevelMax() const; + int compressionLevelDefault() const; + private: QMimeType m_mimeType; Kerfuffle::Archive::EncryptionType m_encryptionType; + int m_compressionLevelMin; + int m_compressionLevelMax; + int m_compressionLevelDefault; }; } -#endif // ARCHIVEFORMAT_H \ No newline at end of file +#endif // ARCHIVEFORMAT_H diff --git a/kerfuffle/archiveformat.cpp b/kerfuffle/archiveformat.cpp --- a/kerfuffle/archiveformat.cpp +++ b/kerfuffle/archiveformat.cpp @@ -33,9 +33,16 @@ { } -ArchiveFormat::ArchiveFormat(const QMimeType& mimeType, Archive::EncryptionType encryptionType) : +ArchiveFormat::ArchiveFormat(const QMimeType& mimeType, + Archive::EncryptionType encryptionType, + int compLevelMin, + int compLevelMax, + int compLevelDefault) : m_mimeType(mimeType), - m_encryptionType(encryptionType) + m_encryptionType(encryptionType), + m_compressionLevelMin(compLevelMin), + m_compressionLevelMax(compLevelMax), + m_compressionLevelDefault(compLevelDefault) { } @@ -48,17 +55,19 @@ } const QJsonObject formatProps = json[mime].toObject(); - if (formatProps.isEmpty()) { - return ArchiveFormat(mimeType, Archive::Unencrypted); - } + int compLevelMin = formatProps[QStringLiteral("CompressionLevelMin")].toInt(); + int compLevelMax = formatProps[QStringLiteral("CompressionLevelMax")].toInt(); + int compLevelDefault = formatProps[QStringLiteral("CompressionLevelDefault")].toInt(); + + Archive::EncryptionType encType = Archive::Unencrypted; if (formatProps[QStringLiteral("HeaderEncryption")].toBool()) { - return ArchiveFormat(mimeType, Archive::HeaderEncrypted); + encType = Archive::HeaderEncrypted; + } else if (formatProps[QStringLiteral("Encryption")].toBool()) { + encType = Archive::Encrypted; } - if (formatProps[QStringLiteral("Encryption")].toBool()) { - return ArchiveFormat(mimeType, Archive::Encrypted); - } + return ArchiveFormat(mimeType, encType, compLevelMin, compLevelMax, compLevelDefault); } return ArchiveFormat(); @@ -74,4 +83,19 @@ return m_encryptionType; } +int ArchiveFormat::compressionLevelMin() const +{ + return m_compressionLevelMin; +} + +int ArchiveFormat::compressionLevelMax() const +{ + return m_compressionLevelMax; +} + +int ArchiveFormat::compressionLevelDefault() const +{ + return m_compressionLevelDefault; +} + } diff --git a/kerfuffle/cliinterface.cpp b/kerfuffle/cliinterface.cpp --- a/kerfuffle/cliinterface.cpp +++ b/kerfuffle/cliinterface.cpp @@ -252,12 +252,14 @@ QDir::setCurrent(globalWorkDir); } + int compLevel = options.value(QStringLiteral("CompressionLevel"), -1).toInt(); + const auto args = substituteAddVariables(m_param.value(AddArgs).toStringList(), files, workDir, password(), isHeaderEncryptionEnabled(), - options.value(QStringLiteral("CompressionLevel")).toInt()); + compLevel); if (!runProcess(m_param.value(AddProgram).toStringList(), args)) { failOperation(); @@ -718,6 +720,10 @@ QString CliInterface::compressionLevelSwitch(int level) const { + if (level == -1) { + return QString(); + } + Q_ASSERT(m_param.contains(CompressionLevelSwitch)); QString compLevelSwitch = m_param.value(CompressionLevelSwitch).toString(); diff --git a/kerfuffle/createdialog.h b/kerfuffle/createdialog.h --- a/kerfuffle/createdialog.h +++ b/kerfuffle/createdialog.h @@ -57,6 +57,7 @@ QString password() const; QMimeType currentMimeType() const; bool setMimeType(const QString &mimeTypeName); + int compressionLevel() const; /** * @return Whether the user can encrypt the new archive. diff --git a/kerfuffle/createdialog.cpp b/kerfuffle/createdialog.cpp --- a/kerfuffle/createdialog.cpp +++ b/kerfuffle/createdialog.cpp @@ -133,6 +133,16 @@ m_ui->collapsibleEncryption->setToolTip(i18n("Protection of the archive with password is not possible with the %1 format.", mimeType.comment())); } + + if (archiveFormat.compressionLevelMax() == 0) { + m_ui->collapsibleCompression->setEnabled(false); + } else { + m_ui->collapsibleCompression->setEnabled(true); + m_ui->compLevelSlider->setMinimum(archiveFormat.compressionLevelMin()); + m_ui->compLevelSlider->setMaximum(archiveFormat.compressionLevelMax()); + m_ui->compLevelSlider->setValue(archiveFormat.compressionLevelDefault()); + } + slotEncryptionToggled(); } @@ -164,6 +174,14 @@ return QUrl::fromLocalFile(dir + fileName); } +int CreateDialog::compressionLevel() const +{ + if (m_ui->compLevelSlider->isEnabled()) { + return m_ui->compLevelSlider->value(); + } + return -1; +} + QString CreateDialog::password() const { return m_ui->pwdWidget->password(); diff --git a/kerfuffle/createdialog.ui b/kerfuffle/createdialog.ui --- a/kerfuffle/createdialog.ui +++ b/kerfuffle/createdialog.ui @@ -7,7 +7,7 @@ 0 0 502 - 228 + 369 @@ -70,6 +70,13 @@ + + + + Extension: + + + @@ -80,13 +87,6 @@ - - - - Extension: - - - @@ -134,6 +134,73 @@ + + + false + + + Compression + + + false + + + + + + Min + + + + + + + Max + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 1 + 0 + + + + Level: + + + + + + + + 3 + 0 + + + + 9 + + + Qt::Horizontal + + + QSlider::TicksBothSides + + + 1 + + + + + + + Qt::Horizontal diff --git a/part/part.cpp b/part/part.cpp --- a/part/part.cpp +++ b/part/part.cpp @@ -1105,6 +1105,10 @@ CompressionOptions options; options[QStringLiteral("GlobalWorkDir")] = globalWorkDir; + if (arguments().metaData().contains(QStringLiteral("compressionLevel"))) { + options[QStringLiteral("CompressionLevel")] = arguments().metaData()[QStringLiteral("compressionLevel")]; + } + AddJob *job = m_model->addFiles(cleanFilesToAdd, options); if (!job) { return; diff --git a/plugins/cli7zplugin/kerfuffle_cli7z.json b/plugins/cli7zplugin/kerfuffle_cli7z.json --- a/plugins/cli7zplugin/kerfuffle_cli7z.json +++ b/plugins/cli7zplugin/kerfuffle_cli7z.json @@ -56,9 +56,15 @@ ], "X-KDE-Priority": 180, "application/x-7z-compressed": { - "HeaderEncryption": true + "HeaderEncryption": true, + "CompressionLevelMin": 0, + "CompressionLevelMax": 9, + "CompressionLevelDefault": 5 }, "application/zip": { - "Encryption": true + "Encryption": true, + "CompressionLevelMin": 0, + "CompressionLevelMax": 9, + "CompressionLevelDefault": 5 } -} \ No newline at end of file +} diff --git a/plugins/clirarplugin/kerfuffle_clirar.json b/plugins/clirarplugin/kerfuffle_clirar.json --- a/plugins/clirarplugin/kerfuffle_clirar.json +++ b/plugins/clirarplugin/kerfuffle_clirar.json @@ -58,6 +58,9 @@ ], "X-KDE-Priority": 120, "application/x-rar": { - "HeaderEncryption": true + "HeaderEncryption": true, + "CompressionLevelMin": 0, + "CompressionLevelMax": 5, + "CompressionLevelDefault": 3 } -} \ No newline at end of file +} diff --git a/plugins/clizipplugin/kerfuffle_clizip.json b/plugins/clizipplugin/kerfuffle_clizip.json --- a/plugins/clizipplugin/kerfuffle_clizip.json +++ b/plugins/clizipplugin/kerfuffle_clizip.json @@ -55,9 +55,15 @@ ], "X-KDE-Priority": 160, "application/x-java-archive": { - "Encryption": true + "Encryption": true, + "CompressionLevelMin": 0, + "CompressionLevelMax": 9, + "CompressionLevelDefault": 6 }, "application/zip": { - "Encryption": true + "Encryption": true, + "CompressionLevelMin": 0, + "CompressionLevelMax": 9, + "CompressionLevelDefault": 6 } -} \ No newline at end of file +} diff --git a/plugins/libarchive/kerfuffle_libarchive.json b/plugins/libarchive/kerfuffle_libarchive.json --- a/plugins/libarchive/kerfuffle_libarchive.json +++ b/plugins/libarchive/kerfuffle_libarchive.json @@ -55,5 +55,40 @@ }, "X-KDE-Kerfuffle-APIRevision": 1, "X-KDE-Kerfuffle-ReadWrite": true, - "X-KDE-Priority": 100 -} \ No newline at end of file + "X-KDE-Priority": 100, + "application/x-compressed-tar": { + "CompressionLevelMin": 1, + "CompressionLevelMax": 9, + "CompressionLevelDefault": 6 + }, + "application/x-bzip-compressed-tar": { + "CompressionLevelMin": 1, + "CompressionLevelMax": 9, + "CompressionLevelDefault": 9 + }, + "application/x-xz-compressed-tar": { + "CompressionLevelMin": 0, + "CompressionLevelMax": 9, + "CompressionLevelDefault": 6 + }, + "application/x-lzma-compressed-tar": { + "CompressionLevelMin": 0, + "CompressionLevelMax": 9, + "CompressionLevelDefault": 6 + }, + "application/x-lzip-compressed-tar": { + "CompressionLevelMin": 0, + "CompressionLevelMax": 9, + "CompressionLevelDefault": 6 + }, + "application/x-tzo": { + "CompressionLevelMin": 1, + "CompressionLevelMax": 9, + "CompressionLevelDefault": 5 + }, + "application/x-lrzip-compressed-tar": { + "CompressionLevelMin": 1, + "CompressionLevelMax": 9, + "CompressionLevelDefault": 1 + } +} diff --git a/plugins/libarchive/readwritelibarchiveplugin.cpp b/plugins/libarchive/readwritelibarchiveplugin.cpp --- a/plugins/libarchive/readwritelibarchiveplugin.cpp +++ b/plugins/libarchive/readwritelibarchiveplugin.cpp @@ -144,6 +144,19 @@ QLatin1String(archive_error_string(arch_writer.data())))); return false; } + + // Set compression level if passed in CompressionOptions. + if (options.contains(QStringLiteral("CompressionLevel"))) { + qCDebug(ARK) << "Using compression level:" << options.value(QStringLiteral("CompressionLevel")).toString(); + ret = archive_write_set_filter_option(arch_writer.data(), NULL, "compression-level", options.value(QStringLiteral("CompressionLevel")).toString().toUtf8()); + if (ret != ARCHIVE_OK) { + qCWarning(ARK) << "Failed to set compression level"; + emit error(xi18nc("@info", "Setting the compression level failed with the following error:%1", + QLatin1String(archive_error_string(arch_writer.data())))); + return false; + } + } + } else { switch (archive_filter_code(arch_reader.data(), 0)) { case ARCHIVE_FILTER_GZIP: @@ -184,18 +197,6 @@ QLatin1String(archive_error_string(arch_writer.data())))); return false; } - - // Set compression level if passed in CompressionOptions. - if (options.contains(QStringLiteral("CompressionLevel"))) { - qCDebug(ARK) << "Using compression level:" << options.value(QStringLiteral("CompressionLevel")).toString(); - ret = archive_write_set_filter_option(arch_writer.data(), NULL, "compression-level", options.value(QStringLiteral("CompressionLevel")).toString().toUtf8()); - if (ret != ARCHIVE_OK) { - qCWarning(ARK) << "Failed to set compression level"; - emit error(xi18nc("@info", "Setting the compression level failed with the following error:%1", - QLatin1String(archive_error_string(arch_writer.data())))); - return false; - } - } } ret = archive_write_open_fd(arch_writer.data(), tempFile.handle());