diff --git a/kerfuffle/archive_kerfuffle.h b/kerfuffle/archive_kerfuffle.h --- a/kerfuffle/archive_kerfuffle.h +++ b/kerfuffle/archive_kerfuffle.h @@ -93,6 +93,7 @@ Q_PROPERTY(qulonglong packedSize READ packedSize) Q_PROPERTY(QString subfolderName MEMBER m_subfolderName READ subfolderName) Q_PROPERTY(QString password READ password) + Q_PROPERTY(QStringList compressionMethods MEMBER m_compressionMethods) public: @@ -221,6 +222,7 @@ void onAddFinished(KJob*); void onUserQuery(Kerfuffle::Query*); void onNewEntry(const Archive::Entry *entry); + void onCompressionMethodFound(const QStringList &methods); private: Archive(ReadOnlyArchiveInterface *archiveInterface, bool isReadOnly, QObject *parent = 0); @@ -235,7 +237,6 @@ * @return A valid archive if the plugin could be loaded, an invalid one otherwise (with the FailedPlugin error set). */ static Archive *create(const QString &fileName, Plugin *plugin, QObject *parent = Q_NULLPTR); - ReadOnlyArchiveInterface *m_iface; bool m_isReadOnly; bool m_isSingleFolder; @@ -249,6 +250,7 @@ qulonglong m_numberOfFolders; CompressionOptions m_compOptions; QMimeType m_mimeType; + QStringList m_compressionMethods; }; } // namespace Kerfuffle diff --git a/kerfuffle/archive_kerfuffle.cpp b/kerfuffle/archive_kerfuffle.cpp --- a/kerfuffle/archive_kerfuffle.cpp +++ b/kerfuffle/archive_kerfuffle.cpp @@ -172,8 +172,19 @@ m_iface->setParent(this); connect(m_iface, &ReadOnlyArchiveInterface::entry, this, &Archive::onNewEntry); + connect(m_iface, &ReadOnlyArchiveInterface::compressionMethodFound, this, &Archive::onCompressionMethodFound); } +void Archive::onCompressionMethodFound(const QStringList &methods) +{ + // If other methods are found, we dont report "Store" method. + QStringList processedMethods = methods; + if (processedMethods.size() > 1 && + processedMethods.contains(QStringLiteral("Store"))) { + processedMethods.removeOne(QStringLiteral("Store")); + } + setProperty("compressionMethods", processedMethods); +} Archive::~Archive() { diff --git a/kerfuffle/archiveinterface.h b/kerfuffle/archiveinterface.h --- a/kerfuffle/archiveinterface.h +++ b/kerfuffle/archiveinterface.h @@ -167,6 +167,7 @@ void finished(bool result); void userQuery(Query *query); void testSuccess(); + void compressionMethodFound(const QStringList); protected: diff --git a/kerfuffle/propertiesdialog.cpp b/kerfuffle/propertiesdialog.cpp --- a/kerfuffle/propertiesdialog.cpp +++ b/kerfuffle/propertiesdialog.cpp @@ -63,6 +63,7 @@ m_ui->lblArchiveName->setText(archive->fileName()); m_ui->lblArchiveType->setText(archive->mimeType().comment()); m_ui->lblMimetype->setText(archive->mimeType().name()); + m_ui->lblCompressionMethods->setText(archive->property("compressionMethods").toStringList().join(QStringLiteral(", "))); m_ui->lblReadOnly->setText(archive->isReadOnly() ? i18n("yes") : i18n("no")); m_ui->lblMultiVolume->setText(archive->isMultiVolume() ? i18n("yes (%1 volumes)", archive->numberOfVolumes()) : i18n("no")); m_ui->lblHasComment->setText(archive->hasComment() ? i18n("yes") : i18n("no")); diff --git a/kerfuffle/propertiesdialog.ui b/kerfuffle/propertiesdialog.ui --- a/kerfuffle/propertiesdialog.ui +++ b/kerfuffle/propertiesdialog.ui @@ -7,7 +7,7 @@ 0 0 730 - 412 + 436 @@ -73,126 +73,126 @@ - + Opened read-only: - + - + Password-protected: - + - + Has comment: - + - + Number of entries: - + - + Unpacked size: - + - + Packed size: - + - + Compression ratio: - + - + Last modified: - + - + MD5 hash: - + @@ -205,14 +205,14 @@ - + SHA-1 hash: - + @@ -222,14 +222,14 @@ - + SHA-256 hash: - + nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn @@ -239,20 +239,34 @@ - + Multi-volume: - + + + + + Compression method(s): + + + + + + + + + + diff --git a/plugins/cli7zplugin/cliplugin.h b/plugins/cli7zplugin/cliplugin.h --- a/plugins/cli7zplugin/cliplugin.h +++ b/plugins/cli7zplugin/cliplugin.h @@ -67,6 +67,7 @@ int m_linesComment; Kerfuffle::Archive::Entry *m_currentArchiveEntry; bool m_isFirstInformationEntry; + QStringList m_compressionMethods; }; #endif // CLIPLUGIN_H diff --git a/plugins/cli7zplugin/cliplugin.cpp b/plugins/cli7zplugin/cliplugin.cpp --- a/plugins/cli7zplugin/cliplugin.cpp +++ b/plugins/cli7zplugin/cliplugin.cpp @@ -180,6 +180,23 @@ } } else if (line.startsWith(QStringLiteral("Volumes = "))) { m_numberOfVolumes = line.section(QLatin1Char('='), 1).trimmed().toInt(); + + } else if (line.startsWith(QStringLiteral("Method = "))) { + QStringList methods = line.section(QLatin1Char('='), 1).trimmed().split(QLatin1Char(' '), QString::SkipEmptyParts); + // LZMA methods are output with some trailing numbers by 7z representing dictionary/block sizes. + // We are not interested in these, so remove them. + QMutableListIterator i(methods); + while (i.hasNext()) { + QString m = i.next(); + if (m.startsWith(QLatin1String("LZMA2"))) { + m = m.left(5); + } else if (m.startsWith(QLatin1String("LZMA"))) { + m = m.left(4); + } + i.setValue(m); + } + emit compressionMethodFound(methods); + } else if (rxComment.match(line).hasMatch()) { m_parseState = ParseStateComment; m_comment.append(line.section(QLatin1Char('='), 1) + QLatin1Char('\n')); @@ -241,6 +258,19 @@ m_currentArchiveEntry->setProperty("CRC", line.mid(6).trimmed()); } else if (line.startsWith(QStringLiteral("Method = "))) { m_currentArchiveEntry->setProperty("method", line.mid(9).trimmed()); + + // For zip archives we need to check method for each entry. + if (m_archiveType == ArchiveTypeZip) { + QString method = line.mid(9).trimmed(); + if (method == QLatin1String("xz")) { + method = QStringLiteral("XZ"); + } + if (!m_compressionMethods.contains(method)) { + m_compressionMethods.append(method); + emit compressionMethodFound(m_compressionMethods); + } + } + } else if (line.startsWith(QStringLiteral("Encrypted = ")) && line.size() >= 13) { m_currentArchiveEntry->setProperty("isPasswordProtected", line.at(12) == QLatin1Char('+')); diff --git a/plugins/clirarplugin/cliplugin.cpp b/plugins/clirarplugin/cliplugin.cpp --- a/plugins/clirarplugin/cliplugin.cpp +++ b/plugins/clirarplugin/cliplugin.cpp @@ -217,6 +217,11 @@ m_isSolid = true; qCDebug(ARK) << "Solid archive detected"; } + if (line.contains(QLatin1String("RAR 4"))) { + emit compressionMethodFound(QStringList{QStringLiteral("RAR4")}); + } else if (line.contains(QLatin1String("RAR 5"))) { + emit compressionMethodFound(QStringList{QStringLiteral("RAR5")}); + } } return true; } diff --git a/plugins/cliunarchiverplugin/cliplugin.cpp b/plugins/cliunarchiverplugin/cliplugin.cpp --- a/plugins/cliunarchiverplugin/cliplugin.cpp +++ b/plugins/cliunarchiverplugin/cliplugin.cpp @@ -240,6 +240,12 @@ setMultiVolume(true); } + QString formatName = json.value(QStringLiteral("lsarFormatName")).toString(); + if (formatName == QLatin1String("RAR")) { + emit compressionMethodFound(QStringList{QStringLiteral("RAR4")}); + } else if (formatName == QLatin1String("RAR 5")) { + emit compressionMethodFound(QStringList{QStringLiteral("RAR5")}); + } const QJsonArray entries = json.value(QStringLiteral("lsarContents")).toArray(); foreach (const QJsonValue& value, entries) { diff --git a/plugins/clizipplugin/cliplugin.h b/plugins/clizipplugin/cliplugin.h --- a/plugins/clizipplugin/cliplugin.h +++ b/plugins/clizipplugin/cliplugin.h @@ -50,6 +50,7 @@ private: bool setMovingAddedFiles(); void finishMoving(bool result); + QString convertCompressionMethod(const QString &method); enum ParseState { ParseStateHeader = 0, @@ -59,6 +60,7 @@ int m_linesComment; QString m_tempComment; + QStringList m_compressionMethods; }; #endif // CLIPLUGIN_H diff --git a/plugins/clizipplugin/cliplugin.cpp b/plugins/clizipplugin/cliplugin.cpp --- a/plugins/clizipplugin/cliplugin.cpp +++ b/plugins/clizipplugin/cliplugin.cpp @@ -179,6 +179,12 @@ e->setProperty("compressedSize", rxMatch.captured(6).toInt()); e->setProperty("method", rxMatch.captured(7)); + QString method = convertCompressionMethod(rxMatch.captured(7)); + if (!m_compressionMethods.contains(method)) { + m_compressionMethods.append(method); + emit compressionMethodFound(m_compressionMethods); + } + const QDateTime ts(QDate::fromString(rxMatch.captured(8), QStringLiteral("yyyyMMdd")), QTime::fromString(rxMatch.captured(9), QStringLiteral("hhmmss"))); e->setProperty("timestamp", ts); @@ -284,4 +290,16 @@ cleanUp(); } +QString CliPlugin::convertCompressionMethod(const QString &method) +{ + if (method == QLatin1String("stor")) { + return QStringLiteral("Store"); + } else if (method.startsWith(QLatin1String("def"))) { + return QStringLiteral("Deflate"); + } else if (method == QLatin1String("bzp2")) { + return QStringLiteral("BZip2"); + } + return method; +} + #include "cliplugin.moc" diff --git a/plugins/libarchive/libarchiveplugin.h b/plugins/libarchive/libarchiveplugin.h --- a/plugins/libarchive/libarchiveplugin.h +++ b/plugins/libarchive/libarchiveplugin.h @@ -90,6 +90,7 @@ private: int extractionFlags() const; + QString convertCompressionName(const QString &method); int m_cachedArchiveEntryCount; qlonglong m_currentExtractedFilesSize; diff --git a/plugins/libarchive/libarchiveplugin.cpp b/plugins/libarchive/libarchiveplugin.cpp --- a/plugins/libarchive/libarchiveplugin.cpp +++ b/plugins/libarchive/libarchiveplugin.cpp @@ -58,6 +58,10 @@ } qDebug(ARK) << "Detected compression filter:" << archive_filter_name(m_archiveReader.data(), 0); + QString compMethod = convertCompressionName(QString::fromUtf8(archive_filter_name(m_archiveReader.data(), 0))); + if (!compMethod.isEmpty()) { + emit compressionMethodFound(QStringList{compMethod}); + } m_cachedArchiveEntryCount = 0; m_extractedFilesSize = 0; @@ -531,4 +535,28 @@ } } +QString LibarchivePlugin::convertCompressionName(const QString &method) +{ + if (method == QLatin1String("gzip")) { + return QStringLiteral("GZip"); + } else if (method == QLatin1String("bzip2")) { + return QStringLiteral("BZip2"); + } else if (method == QLatin1String("xz")) { + return QStringLiteral("XZ"); + } else if (method == QLatin1String("compress (.Z)")) { + return QStringLiteral("Compress"); + } else if (method == QLatin1String("lrzip")) { + return QStringLiteral("LRZip"); + } else if (method == QLatin1String("lzip")) { + return QStringLiteral("LZip"); + } else if (method == QLatin1String("lz4")) { + return QStringLiteral("LZ4"); + } else if (method == QLatin1String("lzop")) { + return QStringLiteral("lzop"); + } else if (method == QLatin1String("lzma")) { + return QStringLiteral("LZMA"); + } + return QString(); +} + #include "libarchiveplugin.moc"