diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,11 @@ URL "https://download.kde.org/stable/frameworks/" TYPE OPTIONAL PURPOSE "Archive is needed to build ODF and OOXML 2007 extractors") +find_package(KF5 ${KF5_DEP_VERSION} COMPONENTS CoreAddons) +set_package_properties(KF5CoreAddons PROPERTIES DESCRIPTION "KDE Frameworks 5: Core Addons Framework" + URL "https://download.kde.org/stable/frameworks/" TYPE OPTIONAL + PURPOSE "Needed for the formatting of properties for display purposes") + find_package(KF5 ${KF5_DEP_VERSION} REQUIRED COMPONENTS I18n) find_package(Poppler 0.12.1 COMPONENTS Qt5) diff --git a/autotests/propertyinfotest.h b/autotests/propertyinfotest.h --- a/autotests/propertyinfotest.h +++ b/autotests/propertyinfotest.h @@ -30,6 +30,7 @@ Q_OBJECT private Q_SLOTS: void testNameIdMapping(); + void testFormatAsDisplayString(); }; } diff --git a/autotests/propertyinfotest.cpp b/autotests/propertyinfotest.cpp --- a/autotests/propertyinfotest.cpp +++ b/autotests/propertyinfotest.cpp @@ -45,4 +45,26 @@ } } +void PropertyInfoTest::testFormatAsDisplayString() +{ + auto emptyProperty = PropertyInfo::fromName(QStringLiteral("no valid property name")); + QCOMPARE(emptyProperty.formatAsDisplayString(QVariant("empty")), QStringLiteral("empty")); + PropertyInfo year(Property::DiscNumber); + QCOMPARE(year.formatAsDisplayString(QVariant(2018)), QStringLiteral("2018")); + QStringList artistList = {"Artist1", "Artist2"}; + PropertyInfo artist(Property::Artist); + QCOMPARE(artist.formatAsDisplayString(QVariant(artistList)), QStringLiteral("Artist1, Artist2")); + QStringList authorList = {"Author1"}; + PropertyInfo author(Property::Author); + QCOMPARE(artist.formatAsDisplayString(QVariant(authorList)), QStringLiteral("Author1")); + PropertyInfo duration(Property::Duration); + QCOMPARE(duration.formatAsDisplayString(QVariant(1800)), QStringLiteral("0:30:00")); + PropertyInfo sampleRate(Property::SampleRate); + QCOMPARE(sampleRate.formatAsDisplayString(QVariant(44100)), QStringLiteral("44,1 kHz")); + PropertyInfo bitRate(Property::BitRate); + QCOMPARE(bitRate.formatAsDisplayString(QVariant(128000)), QStringLiteral("128 kB/s")); + PropertyInfo orientation(Property::ImageOrientation); + QCOMPARE(orientation.formatAsDisplayString(QVariant(5)), QStringLiteral("Transposed")); +} + QTEST_GUILESS_MAIN(PropertyInfoTest) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,6 +13,7 @@ writerplugin.cpp writercollection.cpp externalwriter.cpp + formatstrings.cpp ) ecm_qt_declare_logging_category(KF5FileMetaData_SRCS HEADER kfilemetadata_debug.h IDENTIFIER KFILEMETADATA_LOG CATEGORY_NAME kf5.kfilemetadata) @@ -34,6 +35,7 @@ Qt5::Core PRIVATE KF5::I18n + KF5::CoreAddons ) if(TAGLIB_FOUND) diff --git a/autotests/propertyinfotest.h b/src/formatstrings.h copy from autotests/propertyinfotest.h copy to src/formatstrings.h --- a/autotests/propertyinfotest.h +++ b/src/formatstrings.h @@ -1,6 +1,5 @@ /* - * This file is part of the KDE KFileMetaData project - * Copyright (C) 2014 Vishesh Handa + * Copyright (C) 2018 Alexander Stippich * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,20 +17,36 @@ * */ -#ifndef PROPERTYINFOTEST_H -#define PROPERTYINFOTEST_H +#ifndef KFILEMETADATA_FORMATSTRINGS_H +#define KFILEMETADATA_FORMATSTRINGS_H -#include +#include +#include +#include namespace KFileMetaData { -class PropertyInfoTest : public QObject +class Q_DECL_HIDDEN FormatStrings { - Q_OBJECT -private Q_SLOTS: - void testNameIdMapping(); +public: + static const KFormat form; + + static QString toStringFunction(const QVariant& value); + + static QString joinStringListFunction(const QVariant& value); + + static QString formatDate(const QVariant& value); + + static QString formatDuration(const QVariant& value); + + static QString formatBitRate(const QVariant& value); + + static QString formatSampleRate(const QVariant& value); + + static QString formatOrientationValue(const QVariant& value); + }; } -#endif // PROPERTYINFOTEST_H +#endif diff --git a/src/formatstrings.cpp b/src/formatstrings.cpp new file mode 100644 --- /dev/null +++ b/src/formatstrings.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2018 Alexander Stippich + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "formatstrings.h" + +#include +#include + +using namespace KFileMetaData; + +const KFormat FormatStrings::form; + +QString FormatStrings::toStringFunction(const QVariant& value) +{ + return value.toString(); +} + +QString FormatStrings::joinStringListFunction(const QVariant& value) +{ + return value.toStringList().join(i18nc("Separation between multiple entries", ", ")); +} + +QString FormatStrings::formatDate(const QVariant& value) +{ + + QDateTime dt; + if (value.type() == QVariant::DateTime) { + dt = value.toDateTime(); + } else { + dt = QDateTime::fromString(value.toString(), Qt::ISODate); + } + if (dt.isValid()) { + QTime time = dt.time(); + if (!time.hour() && !time.minute() && !time.second()){ + return FormatStrings::form.formatRelativeDate(dt.date(), QLocale::LongFormat); + } else { + return FormatStrings::form.formatRelativeDateTime(dt, QLocale::LongFormat); + } + } + return QString(); +} + +QString FormatStrings::formatDuration(const QVariant& value) +{ + return FormatStrings::form.formatDuration(value.toInt() * 1000); +} + +QString FormatStrings::formatBitRate(const QVariant& value) +{ + return i18nc("@label bitrate (per second)", "%1/s", FormatStrings::form.formatByteSize(value.toInt(), 0, KFormat::MetricBinaryDialect)); +} + +QString FormatStrings::formatSampleRate(const QVariant& value) +{ + return i18nc("@label samplerate in kilohertz", "%1 kHz", QLocale().toString(value.toDouble() / 1000)); +} + +QString FormatStrings::formatOrientationValue(const QVariant& value) +{ + QString string; + switch (value.toInt()) { + case 1: string = i18nc("@item:intable Image orientation", "Unchanged"); break; + case 2: string = i18nc("@item:intable Image orientation", "Horizontally flipped"); break; + case 3: string = i18nc("@item:intable image orientation", "180° rotated"); break; + case 4: string = i18nc("@item:intable image orientation", "Vertically flipped"); break; + case 5: string = i18nc("@item:intable image orientation", "Transposed"); break; + case 6: string = i18nc("@item:intable image orientation", "90° rotated"); break; + case 7: string = i18nc("@item:intable image orientation", "Transversed"); break; + case 8: string = i18nc("@item:intable image orientation", "270° rotated"); break; + default: + break; + } + return string; +} + diff --git a/src/propertyinfo.h b/src/propertyinfo.h --- a/src/propertyinfo.h +++ b/src/propertyinfo.h @@ -85,6 +85,13 @@ */ static PropertyInfo fromName(const QString& name); + /** + * Returns the value of the property as a QString with added formatting, + * added units if needed, and translated enums. + * @since 5.54 + */ + QString formatAsDisplayString(const QVariant& value) const; + private: class Private; Private* d; diff --git a/src/propertyinfo.cpp b/src/propertyinfo.cpp --- a/src/propertyinfo.cpp +++ b/src/propertyinfo.cpp @@ -24,6 +24,8 @@ #include +#include "formatstrings.h" + using namespace KFileMetaData; class Q_DECL_HIDDEN PropertyInfo::Private @@ -34,6 +36,7 @@ QString displayName; QVariant::Type valueType; bool shouldBeIndexed; + QString (*formatAsString)(const QVariant& value) = nullptr; }; PropertyInfo::PropertyInfo(Property::Property property) @@ -77,6 +80,7 @@ d->name = QStringLiteral("bitRate"); d->displayName = i18nc("@label", "Bitrate"); d->valueType = QVariant::Int; + d->formatAsString = &FormatStrings::formatBitRate; break; case Property::Channels: @@ -117,12 +121,14 @@ d->name = QStringLiteral("creationDate"); d->displayName = i18nc("@label", "Creation Date"); d->valueType = QVariant::String; + d->formatAsString = &FormatStrings::formatDate; break; case Property::Duration: d->name = QStringLiteral("duration"); d->displayName = i18nc("@label", "Duration"); d->valueType = QVariant::Int; + d->formatAsString = &FormatStrings::formatDuration; break; case Property::Empty: @@ -160,6 +166,7 @@ d->name = QStringLiteral("imageDateTime"); d->displayName = i18nc("@label EXIF", "Image Date Time"); d->valueType = QVariant::DateTime; + d->formatAsString = &FormatStrings::formatDate; break; case Property::ImageMake: @@ -180,6 +187,7 @@ d->name = QStringLiteral("imageOrientation"); d->displayName = i18nc("@label EXIF", "Image Orientation"); d->valueType = QVariant::Int; + d->formatAsString = &FormatStrings::formatOrientationValue; break; case Property::Keywords: @@ -225,6 +233,7 @@ d->name = QStringLiteral("photoDateTimeOriginal"); d->displayName = i18nc("@label EXIF", "Photo Original Date Time"); d->valueType = QVariant::DateTime; + d->formatAsString = &FormatStrings::formatDate; break; case Property::PhotoExposureBiasValue: @@ -345,6 +354,7 @@ d->name = QStringLiteral("sampleRate"); d->displayName = i18nc("@label", "Sample Rate"); d->valueType = QVariant::Int; + d->formatAsString = &FormatStrings::formatSampleRate; break; case Property::Subject: @@ -503,13 +513,15 @@ d->displayName = i18nc("@label translations last update", "Last Update"); d->valueType = QVariant::String; d->shouldBeIndexed = false; + d->formatAsString = &FormatStrings::formatDate; break; case Property::TranslationTemplateDate: d->name = QStringLiteral("translationTemplateDate"); d->displayName = i18nc("@label date of template creation8", "Template Creation"); d->valueType = QVariant::String; d->shouldBeIndexed = false; + d->formatAsString = &FormatStrings::formatDate; break; case Property::OriginUrl: @@ -551,6 +563,14 @@ { d->shouldBeIndexed = false; } + + if (d->formatAsString == nullptr) { + if (d->valueType == QVariant::StringList) { + d->formatAsString = &FormatStrings::joinStringListFunction; + } else { + d->formatAsString = &FormatStrings::toStringFunction; + } + } } PropertyInfo::PropertyInfo(const PropertyInfo& pi) @@ -600,6 +620,11 @@ return d->shouldBeIndexed; } +QString PropertyInfo::formatAsDisplayString(const QVariant &value) const +{ + return (d->formatAsString)(value); +} + PropertyInfo PropertyInfo::fromName(const QString& name) { static QHash propertyHash = {