From 4bedfd6609c6efe5dc327d305feac8985d4658e3 Mon Sep 17 00:00:00 2001
From: Alexander Stippich <a.stippich@gmx.net>
Date: Sat, 9 Feb 2019 17:41:46 +0100
Subject: Add string formatting function to property info
Summary:
Adds the ability to format the metadata value
for displaying purposes individually for each
property. Currently, users of KFileMetaData
must implement their own custom formatting
functions.
All custom formatting functions from
Baloo-Widgets and Dolphin are copied into
KFileMetaData. This can be extended later.
This adds a dependency on KCoreAddons to
KFileMetaData.
FEATURE: 398581
Test Plan: tests pass
Reviewers: broulik, bruns, mgallien, #frameworks
Reviewed By: bruns
Subscribers: ngraham, kde-frameworks-devel, #baloo
Tags: #frameworks, #baloo
Differential Revision: https://phabricator.kde.org/D17245
---
CMakeLists.txt | 5 +++
autotests/propertyinfotest.cpp | 29 ++++++++++++++
autotests/propertyinfotest.h | 1 +
src/CMakeLists.txt | 2 +
src/formatstrings.cpp | 86 ++++++++++++++++++++++++++++++++++++++++++
src/formatstrings_p.h | 50 ++++++++++++++++++++++++
src/propertyinfo.cpp | 27 +++++++++++++
src/propertyinfo.h | 7 ++++
8 files changed, 207 insertions(+)
create mode 100644 src/formatstrings.cpp
create mode 100644 src/formatstrings_p.h
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fa481a9..7ef0a40 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -40,6 +40,11 @@ set_package_properties(KF5Archive PROPERTIES DESCRIPTION "KDE Frameworks 5: Arch
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 REQUIRED
+ 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.cpp b/autotests/propertyinfotest.cpp
index ae8b1b8..e203dcd 100644
--- a/autotests/propertyinfotest.cpp
+++ b/autotests/propertyinfotest.cpp
@@ -45,4 +45,33 @@ void PropertyInfoTest::testNameIdMapping()
}
}
+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)), QString(QLocale().toString(44.1) + QStringLiteral(" 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/autotests/propertyinfotest.h b/autotests/propertyinfotest.h
index 677ade1..15e6a10 100644
--- a/autotests/propertyinfotest.h
+++ b/autotests/propertyinfotest.h
@@ -30,6 +30,7 @@ class PropertyInfoTest : public QObject
Q_OBJECT
private Q_SLOTS:
void testNameIdMapping();
+ void testFormatAsDisplayString();
};
}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 52fa8e5..c3cbe8c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -13,6 +13,7 @@ set(KF5FileMetaData_SRCS
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 @@ target_link_libraries(KF5FileMetaData
Qt5::Core
PRIVATE
KF5::I18n
+ KF5::CoreAddons
)
if(TAGLIB_FOUND)
diff --git a/src/formatstrings.cpp b/src/formatstrings.cpp
new file mode 100644
index 0000000..b0bfdf8
--- /dev/null
+++ b/src/formatstrings.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2018 Alexander Stippich <a.stippich@gmx.net>
+ *
+ * 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_p.h"
+
+#include <QDateTime>
+#include <KLocalizedString>
+
+using namespace KFileMetaData;
+
+QString FormatStrings::toStringFunction(const QVariant& value)
+{
+ return value.toString();
+}
+
+QString FormatStrings::joinStringListFunction(const QVariant& value)
+{
+ return value.toStringList().join(i18nc("Separation between multiple entries in a list", ", "));
+}
+
+QString FormatStrings::formatDate(const QVariant& value)
+{
+ KFormat form;
+ QDateTime dt;
+ if (value.type() == QVariant::DateTime) {
+ dt = value.toDateTime();
+ } else {
+ dt = QDateTime::fromString(value.toString(), Qt::ISODate);
+ }
+ if (dt.isValid()) {
+ return form.formatRelativeDateTime(dt, QLocale::LongFormat);
+ }
+ return QString();
+}
+
+QString FormatStrings::formatDuration(const QVariant& value)
+{
+ KFormat form;
+ return form.formatDuration(value.toInt() * 1000);
+}
+
+QString FormatStrings::formatBitRate(const QVariant& value)
+{
+ KFormat form;
+ return i18nc("@label bitrate (per second)", "%1/s", 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("Description of image orientation", "Unchanged"); break;
+ case 2: string = i18nc("Description of image orientation", "Horizontally flipped"); break;
+ case 3: string = i18nc("Description of image orientation", "180° rotated"); break;
+ case 4: string = i18nc("Description of image orientation", "Vertically flipped"); break;
+ case 5: string = i18nc("Description of image orientation", "Transposed"); break;
+ case 6: string = i18nc("Description of image orientation, counter clock-wise rotated", "90° rotated CCW "); break;
+ case 7: string = i18nc("Description of image orientation", "Transversed"); break;
+ case 8: string = i18nc("Description of image orientation, counter clock-wise rotated", "270° rotated CCW"); break;
+ default:
+ break;
+ }
+ return string;
+}
+
diff --git a/src/formatstrings_p.h b/src/formatstrings_p.h
new file mode 100644
index 0000000..125c31e
--- /dev/null
+++ b/src/formatstrings_p.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2018 Alexander Stippich <a.stippich@gmx.net>
+ *
+ * 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
+ *
+ */
+
+#ifndef KFILEMETADATA_FORMATSTRINGS_P_H
+#define KFILEMETADATA_FORMATSTRINGS_P_H
+
+#include <QString>
+#include <QVariant>
+#include <KFormat>
+
+namespace KFileMetaData {
+
+class Q_DECL_HIDDEN FormatStrings
+{
+public:
+ 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
diff --git a/src/propertyinfo.cpp b/src/propertyinfo.cpp
index 5439a58..56fc596 100644
--- a/src/propertyinfo.cpp
+++ b/src/propertyinfo.cpp
@@ -24,6 +24,8 @@
#include <KLocalizedString>
+#include "formatstrings_p.h"
+
using namespace KFileMetaData;
class Q_DECL_HIDDEN PropertyInfo::Private
@@ -34,6 +36,7 @@ public:
QString displayName;
QVariant::Type valueType;
bool shouldBeIndexed;
+ QString (*formatAsString)(const QVariant& value) = nullptr;
};
PropertyInfo::PropertyInfo(Property::Property property)
@@ -41,6 +44,7 @@ PropertyInfo::PropertyInfo(Property::Property property)
{
d->prop = property;
d->shouldBeIndexed = true;
+ d->formatAsString = &FormatStrings::toStringFunction;
switch (property) {
case Property::Album:
@@ -53,12 +57,14 @@ PropertyInfo::PropertyInfo(Property::Property property)
d->name = QStringLiteral("albumArtist");
d->displayName = i18nc("@label", "Album Artist");
d->valueType = QVariant::StringList;
+ d->formatAsString = &FormatStrings::joinStringListFunction;
break;
case Property::Artist:
d->name = QStringLiteral("artist");
d->displayName = i18nc("@label", "Artist");
d->valueType = QVariant::StringList;
+ d->formatAsString = &FormatStrings::joinStringListFunction;
break;
case Property::AspectRatio:
@@ -71,12 +77,14 @@ PropertyInfo::PropertyInfo(Property::Property property)
d->name = QStringLiteral("author");
d->displayName = i18nc("@label", "Author");
d->valueType = QVariant::StringList;
+ d->formatAsString = &FormatStrings::joinStringListFunction;
break;
case Property::BitRate:
d->name = QStringLiteral("bitRate");
d->displayName = i18nc("@label", "Bitrate");
d->valueType = QVariant::Int;
+ d->formatAsString = &FormatStrings::formatBitRate;
break;
case Property::Channels:
@@ -117,12 +125,14 @@ PropertyInfo::PropertyInfo(Property::Property property)
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:
@@ -147,6 +157,7 @@ PropertyInfo::PropertyInfo(Property::Property property)
d->name = QStringLiteral("genre");
d->displayName = i18nc("@label music genre", "Genre");
d->valueType = QVariant::StringList;
+ d->formatAsString = &FormatStrings::joinStringListFunction;
d->shouldBeIndexed = false;
break;
@@ -160,6 +171,7 @@ PropertyInfo::PropertyInfo(Property::Property property)
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,12 +192,14 @@ PropertyInfo::PropertyInfo(Property::Property property)
d->name = QStringLiteral("imageOrientation");
d->displayName = i18nc("@label EXIF", "Image Orientation");
d->valueType = QVariant::Int;
+ d->formatAsString = &FormatStrings::formatOrientationValue;
break;
case Property::Keywords:
d->name = QStringLiteral("keywords");
d->displayName = i18nc("@label", "Keywords");
d->valueType = QVariant::StringList;
+ d->formatAsString = &FormatStrings::joinStringListFunction;
d->shouldBeIndexed = false;
break;
@@ -206,6 +220,7 @@ PropertyInfo::PropertyInfo(Property::Property property)
d->name = QStringLiteral("lyricist");
d->displayName = i18nc("@label", "Lyricist");
d->valueType = QVariant::StringList;
+ d->formatAsString = &FormatStrings::joinStringListFunction;
d->shouldBeIndexed = false;
break;
@@ -225,6 +240,7 @@ PropertyInfo::PropertyInfo(Property::Property property)
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 +361,7 @@ PropertyInfo::PropertyInfo(Property::Property property)
d->name = QStringLiteral("sampleRate");
d->displayName = i18nc("@label", "Sample Rate");
d->valueType = QVariant::Int;
+ d->formatAsString = &FormatStrings::formatSampleRate;
break;
case Property::Subject:
@@ -382,6 +399,7 @@ PropertyInfo::PropertyInfo(Property::Property property)
d->name = QStringLiteral("performer");
d->displayName = i18nc("@label", "Performer");
d->valueType = QVariant::StringList;
+ d->formatAsString = &FormatStrings::joinStringListFunction;
break;
case Property::Ensemble:
@@ -394,12 +412,14 @@ PropertyInfo::PropertyInfo(Property::Property property)
d->name = QStringLiteral("arranger");
d->displayName = i18nc("@label", "Arranger");
d->valueType = QVariant::StringList;
+ d->formatAsString = &FormatStrings::joinStringListFunction;
break;
case Property::Conductor:
d->name = QStringLiteral("conductor");
d->displayName = i18nc("@label", "Conductor");
d->valueType = QVariant::StringList;
+ d->formatAsString = &FormatStrings::joinStringListFunction;
break;
case Property::Compilation:
@@ -503,6 +523,7 @@ PropertyInfo::PropertyInfo(Property::Property property)
d->displayName = i18nc("@label translations last update", "Last Update");
d->valueType = QVariant::String;
d->shouldBeIndexed = false;
+ d->formatAsString = &FormatStrings::formatDate;
break;
case Property::TranslationTemplateDate:
@@ -510,6 +531,7 @@ PropertyInfo::PropertyInfo(Property::Property property)
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:
@@ -600,6 +622,11 @@ bool PropertyInfo::shouldBeIndexed() const
return d->shouldBeIndexed;
}
+QString PropertyInfo::formatAsDisplayString(const QVariant &value) const
+{
+ return (d->formatAsString)(value);
+}
+
PropertyInfo PropertyInfo::fromName(const QString& name)
{
static QHash<QString, Property::Property> propertyHash = {
diff --git a/src/propertyinfo.h b/src/propertyinfo.h
index c1767c4..3c426e8 100644
--- a/src/propertyinfo.h
+++ b/src/propertyinfo.h
@@ -85,6 +85,13 @@ public:
*/
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.56
+ */
+ QString formatAsDisplayString(const QVariant& value) const;
+
private:
class Private;
Private* d;
--
cgit v1.1