diff --git a/app/batchextract.cpp b/app/batchextract.cpp --- a/app/batchextract.cpp +++ b/app/batchextract.cpp @@ -67,7 +67,7 @@ { QString destination = destinationFolder(); const bool isSingleFolderRPM = (archive->isSingleFolderArchive() && - (Kerfuffle::Archive::determineMimeType(archive->fileName()) == QStringLiteral("application/x-rpm"))); + (archive->mimeType().name() == QLatin1String("application/x-rpm"))); if ((autoSubfolder()) && (!archive->isSingleFolderArchive() || isSingleFolderRPM)) { const QDir d(destination); diff --git a/autotests/kerfuffle/mimetypetest.cpp b/autotests/kerfuffle/mimetypetest.cpp --- a/autotests/kerfuffle/mimetypetest.cpp +++ b/autotests/kerfuffle/mimetypetest.cpp @@ -35,59 +35,42 @@ private Q_SLOTS: - void testEmptyFilename(); - void testTarDetection(); - void testWrongZipExtension(); - void testSpecialCharsTarExtension(); - void testIsoDetection(); - void testFallbackOnExtensionMimetype(); + void testMimeTypeDetection_data(); + void testMimeTypeDetection(); }; QTEST_GUILESS_MAIN(MimeTypeTest) -void MimeTypeTest::testEmptyFilename() +void MimeTypeTest::testMimeTypeDetection_data() { - QCOMPARE(Archive::determineMimeType(QString()), QStringLiteral("application/octet-stream")); -} + QTest::addColumn("archiveName"); + QTest::addColumn("expectedMimeType"); -void MimeTypeTest::testTarDetection() -{ - const QString testFile = QFINDTESTDATA("data/simplearchive.tar.gz"); - QCOMPARE(Archive::determineMimeType(testFile), QStringLiteral("application/x-compressed-tar")); -} + const QString compressedTarMime = QStringLiteral("application/x-compressed-tar"); + const QString isoMimeType = QStringLiteral("application/x-cd-image"); -void MimeTypeTest::testWrongZipExtension() -{ - const QString testFile = QFINDTESTDATA("data/zip_with_wrong_extension.rar"); - QCOMPARE(Archive::determineMimeType(testFile), QStringLiteral("application/zip")); -} + QTest::newRow("empty name") << QString() << QStringLiteral("application/octet-stream"); + QTest::newRow("tar.gz") << QFINDTESTDATA("data/simplearchive.tar.gz") << compressedTarMime; + QTest::newRow("zip with wrong extension") << QFINDTESTDATA("data/zip_with_wrong_extension.rar") << QStringLiteral("application/zip"); + QTest::newRow("tar with special char in the extension") << QStringLiteral("foo.tar~1.gz") << compressedTarMime; + QTest::newRow("another tar with special char in the extension") << QStringLiteral("foo.ta4r.gz") << compressedTarMime; -void MimeTypeTest::testSpecialCharsTarExtension() -{ - const QString tarMimeType = QStringLiteral("application/x-compressed-tar"); - QCOMPARE(Archive::determineMimeType(QStringLiteral("foo.tar~1.gz")), tarMimeType); - QCOMPARE(Archive::determineMimeType(QStringLiteral("foo.ta4r.gz")), tarMimeType); -} + // This ISO file may be detected-by-content as text/plain. See https://bugs.freedesktop.org/show_bug.cgi?id=80877 + QTest::newRow("archlinux truncated ISO") << QFINDTESTDATA("data/archlinux-2015.09.01-dual_truncated.iso") << isoMimeType; -void MimeTypeTest::testIsoDetection() -{ - const QString isoMimeType = QStringLiteral("application/x-cd-image"); + // This ISO may not bet detected-by-content. See https://bugs.freedesktop.org/show_bug.cgi?id=80877 + QTest::newRow("kubuntu truncated ISO") << QFINDTESTDATA("data/kubuntu-14.04.1-desktop-amd64_truncated.iso") << isoMimeType; - // Test workaround for https://bugs.freedesktop.org/show_bug.cgi?id=80877 - // 1. This ISO file may be detected-by-content as text/plain. - const QString archIso = QFINDTESTDATA("data/archlinux-2015.09.01-dual_truncated.iso"); - QCOMPARE(Archive::determineMimeType(archIso), isoMimeType); - // 2. This ISO may not bet detected-by-content. - const QString kubuntuIso = QFINDTESTDATA("data/kubuntu-14.04.1-desktop-amd64_truncated.iso"); - QCOMPARE(Archive::determineMimeType(kubuntuIso), isoMimeType); + // Some mimetypes (e.g. tar-v7 archives, see #355955) cannot be detected by content (as of shared-mime-info 1.5). + QTest::newRow("tar-v7") << QFINDTESTDATA("data/tar-v7.tar") << QStringLiteral("application/x-tar"); } -// Some mimetypes (e.g. tar-v7 archives, see #355955) cannot be detected by content (as of shared-mime-info 1.5). -// In this case we fallback to the mimetype detected from the extension. -void MimeTypeTest::testFallbackOnExtensionMimetype() +void MimeTypeTest::testMimeTypeDetection() { - const QString testFile = QFINDTESTDATA("data/tar-v7.tar"); - QCOMPARE(Archive::determineMimeType(testFile), QStringLiteral("application/x-tar")); + QFETCH(QString, archiveName); + QFETCH(QString, expectedMimeType); + + QCOMPARE(Archive::determineMimeType(archiveName).name(), expectedMimeType); } #include "mimetypetest.moc" diff --git a/kerfuffle/archive_kerfuffle.h b/kerfuffle/archive_kerfuffle.h --- a/kerfuffle/archive_kerfuffle.h +++ b/kerfuffle/archive_kerfuffle.h @@ -30,11 +30,11 @@ #include "kerfuffle_export.h" -#include #include +#include #include #include -#include + #include @@ -136,7 +136,7 @@ { Q_OBJECT Q_PROPERTY(QString fileName READ fileName) - Q_PROPERTY(QString mimeType READ mimeType) + Q_PROPERTY(QMimeType mimeType READ mimeType) Q_PROPERTY(bool isReadOnly READ isReadOnly) Q_PROPERTY(bool isPasswordProtected READ isPasswordProtected) Q_PROPERTY(bool hasComment READ hasComment) @@ -146,16 +146,16 @@ public: QString fileName() const; - QString mimeType() const; + QMimeType mimeType() const; qulonglong numberOfFiles() const; bool isReadOnly() const; bool isPasswordProtected(); bool hasComment() const; qulonglong unpackedSize() const; qulonglong packedSize() const; static bool comparePlugins(const KPluginMetaData &p1, const KPluginMetaData &p2); - static QString determineMimeType(const QString& filename); + static QMimeType determineMimeType(const QString& filename); static QVector findPluginOffers(const QString& filename, const QString& fixedMimeType); static Archive *create(const QString &fileName, QObject *parent = 0); diff --git a/kerfuffle/archive_kerfuffle.cpp b/kerfuffle/archive_kerfuffle.cpp --- a/kerfuffle/archive_kerfuffle.cpp +++ b/kerfuffle/archive_kerfuffle.cpp @@ -49,7 +49,7 @@ return (p1.rawData()[QStringLiteral("X-KDE-Priority")].toVariant().toInt()) > (p2.rawData()[QStringLiteral("X-KDE-Priority")].toVariant().toInt()); } -QString Archive::determineMimeType(const QString& filename) +QMimeType Archive::determineMimeType(const QString& filename) { QMimeDatabase db; @@ -70,7 +70,7 @@ // mimeFromContent will be "application/octet-stream" when file is // unreadable, so use extension. if (!fileinfo.isReadable()) { - return mimeFromExtension.name(); + return mimeFromExtension; } // Compressed tar-archives are detected as single compressed files when @@ -82,35 +82,35 @@ mimeFromContent == db.mimeTypeForName(QStringLiteral("application/x-bzip"))) || (mimeFromExtension == db.mimeTypeForName(QStringLiteral("application/x-xz-compressed-tar")) && mimeFromContent == db.mimeTypeForName(QStringLiteral("application/x-xz")))) { - return mimeFromExtension.name(); + return mimeFromExtension; } if (mimeFromExtension != mimeFromContent) { if (mimeFromContent.isDefault()) { qCWarning(ARK) << "Could not detect mimetype from content." << "Using extension-based mimetype:" << mimeFromExtension.name(); - return mimeFromExtension.name(); + return mimeFromExtension; } // #354344: ISO files are currently wrongly detected-by-content. if (mimeFromExtension.inherits(QStringLiteral("application/x-cd-image"))) { - return mimeFromExtension.name(); + return mimeFromExtension; } qCWarning(ARK) << "Mimetype for filename extension (" << mimeFromExtension.name() << ") did not match mimetype for content (" << mimeFromContent.name() << "). Using content-based mimetype."; } - return mimeFromContent.name(); + return mimeFromContent; } QVector Archive::findPluginOffers(const QString& filename, const QString& fixedMimeType) { qCDebug(ARK) << "Find plugin offers for" << filename << "with mime" << fixedMimeType; - const QString mimeType = fixedMimeType.isEmpty() ? determineMimeType(filename) : fixedMimeType; + const QString mimeType = fixedMimeType.isEmpty() ? determineMimeType(filename).name() : fixedMimeType; qCDebug(ARK) << "Detected mime" << mimeType; @@ -230,7 +230,7 @@ return m_iface->filename(); } -QString Archive::mimeType() const +QMimeType Archive::mimeType() const { return determineMimeType(fileName()); } diff --git a/kerfuffle/propertiesdialog.cpp b/kerfuffle/propertiesdialog.cpp --- a/kerfuffle/propertiesdialog.cpp +++ b/kerfuffle/propertiesdialog.cpp @@ -31,7 +31,6 @@ #include #include -#include #include #include @@ -59,7 +58,7 @@ m_ui = new PropertiesDialogUI(this); m_ui->lblArchiveName->setText(archive->fileName()); - m_ui->lblArchiveType->setText(archive->mimeType()); + m_ui->lblArchiveType->setText(QStringLiteral("%1 (%2)").arg(archive->mimeType().comment(), archive->mimeType().name())); m_ui->lblReadOnly->setText(archive->isReadOnly() ? i18n("yes") : i18n("no")); m_ui->lblPasswordProtected->setText(archive->isPasswordProtected() ? i18n("yes") : i18n("no")); m_ui->lblHasComment->setText(archive->hasComment() ? i18n("yes") : i18n("no")); @@ -70,9 +69,7 @@ m_ui->lblLastModified->setText(fi.lastModified().toString(QStringLiteral("yyyy-MM-dd HH:mm"))); // Show an icon representing the mimetype of the archive. - QMimeDatabase db; - QIcon icon; - icon = QIcon::fromTheme(db.mimeTypeForName(archive->mimeType()).iconName()); + QIcon icon = QIcon::fromTheme(archive->mimeType().iconName()); m_ui->lblIcon->setPixmap(icon.pixmap(IconSize(KIconLoader::Desktop), IconSize(KIconLoader::Desktop))); connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); diff --git a/part/part.cpp b/part/part.cpp --- a/part/part.cpp +++ b/part/part.cpp @@ -677,8 +677,7 @@ qCWarning(ARK) << "No entry listed by the plugin"; displayMsgWidget(KMessageWidget::Warning, xi18nc("@info", "The archive is empty or Ark could not open its content.")); } else if (m_model->rowCount() == 1) { - QMimeType mime = QMimeDatabase().mimeTypeForName(Archive::determineMimeType(m_model->archive()->fileName())); - if (mime.inherits(QStringLiteral("application/x-cd-image")) && + if (m_model->archive()->mimeType().inherits(QStringLiteral("application/x-cd-image")) && m_model->entryForIndex(m_model->index(0, 0))[FileName].toString() == QLatin1String("README.TXT")) { qCWarning(ARK) << "Detected ISO image with UDF filesystem"; displayMsgWidget(KMessageWidget::Warning, xi18nc("@info", "Ark does not currently support ISO files with UDF filesystem."));