diff --git a/CMakeLists.txt b/CMakeLists.txt index fa481a9..7ef0a40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,137 +1,142 @@ cmake_minimum_required(VERSION 3.5) set(KF5_VERSION "5.56.0") # handled by release scripts set(KF5_DEP_VERSION "5.55.0") # handled by release scripts project(KFileMetaData VERSION ${KF5_VERSION}) include(FeatureSummary) find_package(ECM 5.55.0 NO_MODULE) set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://projects.kde.org/projects/kdesupport/extra-cmake-modules") feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${ECM_MODULE_PATH}) include(KDEInstallDirs) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(KDECMakeSettings) include(ECMAddTests) include(GenerateExportHeader) include(ECMSetupVersion) include(ECMGenerateHeaders) include(ECMAddQch) include(ECMQtDeclareLoggingCategory) include(CheckStructHasMember) option(BUILD_QCH "Build API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)" OFF) add_feature_info(QCH ${BUILD_QCH} "API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)") ecm_setup_version(PROJECT VARIABLE_PREFIX KFILEMETADATA PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5FileMetaDataConfigVersion.cmake" SOVERSION 3) # Dependencies set(REQUIRED_QT_VERSION 5.10.0) find_package(Qt5 ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE COMPONENTS Xml) find_package(KF5 ${KF5_DEP_VERSION} COMPONENTS Archive) set_package_properties(KF5Archive PROPERTIES DESCRIPTION "KDE Frameworks 5: Archive Framework" 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) set_package_properties(Poppler PROPERTIES DESCRIPTION "A PDF rendering library" URL "https://poppler.freedesktop.org/" TYPE OPTIONAL PURPOSE "Support for PDF files") find_package(Taglib 1.11.1) set_package_properties(Taglib PROPERTIES DESCRIPTION "Id3 tag reader" URL "https://taglib.org/" TYPE OPTIONAL PURPOSE "Support for music metadata") find_package(LibExiv2 0.21) set_package_properties(LibExiv2 PROPERTIES TYPE OPTIONAL PURPOSE "Support for image metadata") find_package(FFmpeg 57.48 COMPONENTS AVCODEC) find_package(FFmpeg 57.40 COMPONENTS AVFORMAT) find_package(FFmpeg 55.27 COMPONENTS AVUTIL) set_package_properties(FFmpeg PROPERTIES DESCRIPTION "Video Tag reader" URL "https://ffmpeg.org/" TYPE OPTIONAL PURPOSE "Support for video metadata") if (FFmpeg_AVFORMAT_FOUND) set(CMAKE_REQUIRED_INCLUDES ${AVCODEC_INCLUDE_DIRS}) CHECK_STRUCT_HAS_MEMBER(AVStream codecpar "stdint.h;libavformat/avformat.h" HAVE_AVSTREAM_CODECPAR LANGUAGE CXX) endif() find_package(EPub) set_package_properties(EPub PROPERTIES DESCRIPTION "Ebook epub reader" URL "https://sourceforge.net/projects/ebook-tools/" TYPE OPTIONAL PURPOSE "Support for epub metadata") find_package(CatDoc) set_package_properties(CatDoc PROPERTIES DESCRIPTION "catdoc executable" URL "https://www.wagner.pp.ru/~vitus/software/catdoc/" TYPE RUNTIME PURPOSE "Extract text from office 98 files - RUNTIME dependency") if ( CMAKE_SYSTEM_NAME MATCHES "Linux" ) find_package(Xattr) set_package_properties(Xattr PROPERTIES DESCRIPTION "library libattr " URL "https://savannah.nongnu.org/projects/attr" TYPE REQUIRED PURPOSE "Extended attribute shared library") endif() #find_package(QMobipocket) #set_package_properties(QMobipocket PROPERTIES DESCRIPTION "Mobipocket epub reader" # URL "https://projects.kde.org/projects/kde/kdegraphics/kdegraphics-mobipocket" # TYPE OPTIONAL PURPOSE "Support for mobi metadata") add_definitions(-DTRANSLATION_DOMAIN=\"kfilemetadata5\") add_subdirectory(src) if (BUILD_TESTING) add_subdirectory(autotests) add_subdirectory(tests) endif() # Config files set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/KF5FileMetaData") if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po") ki18n_install(po) endif() if (BUILD_QCH) ecm_install_qch_export( TARGETS KF5FileMetaData_QCH FILE KF5FileMetaDataQchTargets.cmake DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT Devel ) set(PACKAGE_INCLUDE_QCHTARGETS "include(\"\${CMAKE_CURRENT_LIST_DIR}/KF5FileMetaDataQchTargets.cmake\")") endif() include(CMakePackageConfigHelpers) configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/KF5FileMetaDataConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/KF5FileMetaDataConfig.cmake" INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/KF5FileMetaDataConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/KF5FileMetaDataConfigVersion.cmake" DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT devel ) # contains list of debug categories, for kdebugsettings install(FILES kfilemetadata.categories DESTINATION ${KDE_INSTALL_CONFDIR}) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/autotests/propertyinfotest.cpp b/autotests/propertyinfotest.cpp index ae8b1b8..e203dcd 100644 --- a/autotests/propertyinfotest.cpp +++ b/autotests/propertyinfotest.cpp @@ -1,48 +1,77 @@ /* * This file is part of the KDE KFileMetaData project * Copyright (C) 2014 Vishesh Handa * * 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 "propertyinfotest.h" #include "propertyinfo.h" #include using namespace KFileMetaData; void PropertyInfoTest::testNameIdMapping() { // The +1 is to avoid the Empty Property int i = static_cast(Property::FirstProperty) + 1; int e = static_cast(Property::LastProperty); for (; i <= e; i++) { Property::Property p = static_cast(i); PropertyInfo pi(p); // qDebug() << pi.name(); QCOMPARE(pi.property(), p); QVERIFY(!pi.name().isEmpty()); QVERIFY(!pi.displayName().isEmpty()); PropertyInfo pi2 = PropertyInfo::fromName(pi.name()); QCOMPARE(pi2.property(), p); } } +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 @@ -1,37 +1,38 @@ /* * This file is part of the KDE KFileMetaData project * Copyright (C) 2014 Vishesh Handa * * 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 PROPERTYINFOTEST_H #define PROPERTYINFOTEST_H #include namespace KFileMetaData { class PropertyInfoTest : public QObject { Q_OBJECT private Q_SLOTS: void testNameIdMapping(); + void testFormatAsDisplayString(); }; } #endif // PROPERTYINFOTEST_H diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 52fa8e5..c3cbe8c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,135 +1,137 @@ set(KF5FileMetaData_SRCS extractionresult.cpp simpleextractionresult.cpp extractor.cpp extractorplugin.cpp extractorcollection.cpp externalextractor.cpp propertyinfo.cpp typeinfo.cpp usermetadata.cpp writedata.cpp writer.cpp 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) if(TAGLIB_FOUND) set(KF5FileMetaData_SRCS ${KF5FileMetaData_SRCS} embeddedimagedata.cpp ) endif() add_library(KF5FileMetaData ${KF5FileMetaData_SRCS} ) add_library(KF5::FileMetaData ALIAS KF5FileMetaData) target_link_libraries(KF5FileMetaData PUBLIC Qt5::Core PRIVATE KF5::I18n + KF5::CoreAddons ) if(TAGLIB_FOUND) target_include_directories(KF5FileMetaData SYSTEM PRIVATE ${TAGLIB_INCLUDES}) target_link_libraries(KF5FileMetaData PRIVATE ${TAGLIB_LIBRARIES} ) endif() generate_export_header(KF5FileMetaData BASE_NAME KFileMetaData EXPORT_FILE_NAME kfilemetadata_export.h) set_target_properties(KF5FileMetaData PROPERTIES VERSION ${KFILEMETADATA_VERSION_STRING} SOVERSION ${KFILEMETADATA_SOVERSION} EXPORT_NAME FileMetaData ) target_include_directories(KF5FileMetaData INTERFACE "$") ecm_generate_headers(KF5FileMetaData_CamelCase_HEADERS HEADER_NAMES ExtractionResult SimpleExtractionResult Extractor ExtractorPlugin ExtractorCollection Properties PropertyInfo Types TypeInfo UserMetaData WriteData Writer WriterPlugin WriterCollection EmbeddedImageData PREFIX kfilemetadata REQUIRED_HEADERS KF5FileMetaData_HEADERS ) install(TARGETS KF5FileMetaData EXPORT KF5FileMetaDataTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS}) install(EXPORT KF5FileMetaDataTargets NAMESPACE KF5:: DESTINATION ${LIB_INSTALL_DIR}/cmake/KF5FileMetaData FILE KF5FileMetaDataTargets.cmake) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/kfilemetadata_export.h ${KF5FileMetaData_HEADERS} DESTINATION ${KF5_INCLUDE_INSTALL_DIR}/KFileMetaData/kfilemetadata COMPONENT Devel ) install(FILES ${KF5FileMetaData_CamelCase_HEADERS} DESTINATION ${KF5_INCLUDE_INSTALL_DIR}/KFileMetaData/KFileMetaData COMPONENT Devel ) configure_file(config-kfilemetadata.h.in ${CMAKE_CURRENT_BINARY_DIR}/config-kfilemetadata.h) if(BUILD_QCH) ecm_add_qch( KF5FileMetaData_QCH NAME KFileMetaData BASE_NAME KF5FileMetaData VERSION ${KF5_VERSION} ORG_DOMAIN org.kde SOURCES # using only public headers, to cover only public API ${KF5FileMetaData_HEADERS} MD_MAINPAGE "${CMAKE_SOURCE_DIR}/README.md" LINK_QCHS Qt5Core_QCH BLANK_MACROS KFILEMETADATA_EXPORT KFILEMETADATA_DEPRECATED KFILEMETADATA_DEPRECATED_EXPORT TAGFILE_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR} QCH_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR} COMPONENT Devel ) endif() include(ECMGeneratePriFile) ecm_generate_pri_file( BASE_NAME KFileMetaData LIB_NAME KF5FileMetaData DEPS "core" FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR ${KF5_INCLUDE_INSTALL_DIR}/KFileMetaData ) install(FILES ${PRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR}) add_subdirectory(extractors) add_subdirectory(writers) 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 + * + * 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 +#include + +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/autotests/propertyinfotest.h b/src/formatstrings_p.h similarity index 53% copy from autotests/propertyinfotest.h copy to src/formatstrings_p.h index 677ade1..125c31e 100644 --- a/autotests/propertyinfotest.h +++ b/src/formatstrings_p.h @@ -1,37 +1,50 @@ /* - * 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 * 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 PROPERTYINFOTEST_H -#define PROPERTYINFOTEST_H +#ifndef KFILEMETADATA_FORMATSTRINGS_P_H +#define KFILEMETADATA_FORMATSTRINGS_P_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 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/propertyinfo.cpp b/src/propertyinfo.cpp index 5439a58..56fc596 100644 --- a/src/propertyinfo.cpp +++ b/src/propertyinfo.cpp @@ -1,687 +1,714 @@ /* * This file is part of the KFileMetaData project * Copyright (C) 2014 Vishesh Handa * * 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) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * 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, see . * */ #include "propertyinfo.h" #include +#include "formatstrings_p.h" + using namespace KFileMetaData; class Q_DECL_HIDDEN PropertyInfo::Private { public: Property::Property prop; QString name; QString displayName; QVariant::Type valueType; bool shouldBeIndexed; + QString (*formatAsString)(const QVariant& value) = nullptr; }; PropertyInfo::PropertyInfo(Property::Property property) : d(new Private) { d->prop = property; d->shouldBeIndexed = true; + d->formatAsString = &FormatStrings::toStringFunction; switch (property) { case Property::Album: d->name = QStringLiteral("album"); d->displayName = i18nc("@label music album", "Album"); d->valueType = QVariant::String; break; case Property::AlbumArtist: 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: d->name = QStringLiteral("aspectRatio"); d->displayName = i18nc("@label", "Aspect Ratio"); d->valueType = QVariant::Int; break; case Property::Author: 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: d->name = QStringLiteral("channels"); d->displayName = i18nc("@label", "Channels"); d->valueType = QVariant::Int; break; case Property::Comment: d->name = QStringLiteral("comment"); d->displayName = i18nc("@label", "Comment"); d->valueType = QVariant::String; d->shouldBeIndexed = false; break; case Property::Description: d->name = QStringLiteral("description"); d->displayName = i18nc("@label", "Description"); d->valueType = QVariant::String; d->shouldBeIndexed = false; break; case Property::Composer: d->name = QStringLiteral("composer"); d->displayName = i18nc("@label", "Composer"); d->valueType = QVariant::String; d->shouldBeIndexed = false; break; case Property::Copyright: d->name = QStringLiteral("copyright"); d->displayName = i18nc("@label", "Copyright"); d->valueType = QVariant::String; d->shouldBeIndexed = false; break; case Property::CreationDate: 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: d->name = QStringLiteral("empty"); d->valueType = QVariant::Invalid; break; case Property::FrameRate: d->name = QStringLiteral("frameRate"); d->displayName = i18nc("@label", "Frame Rate"); d->valueType = QVariant::Int; break; case Property::Generator: d->name = QStringLiteral("generator"); d->displayName = i18nc("@label", "Document Generated By"); d->valueType = QVariant::String; d->shouldBeIndexed = false; break; case Property::Genre: d->name = QStringLiteral("genre"); d->displayName = i18nc("@label music genre", "Genre"); d->valueType = QVariant::StringList; + d->formatAsString = &FormatStrings::joinStringListFunction; d->shouldBeIndexed = false; break; case Property::Height: d->name = QStringLiteral("height"); d->displayName = i18nc("@label", "Height"); d->valueType = QVariant::Int; break; case Property::ImageDateTime: d->name = QStringLiteral("imageDateTime"); d->displayName = i18nc("@label EXIF", "Image Date Time"); d->valueType = QVariant::DateTime; + d->formatAsString = &FormatStrings::formatDate; break; case Property::ImageMake: d->name = QStringLiteral("imageMake"); d->displayName = i18nc("@label EXIF", "Image Make"); d->valueType = QVariant::String; d->shouldBeIndexed = false; break; case Property::ImageModel: d->name = QStringLiteral("imageModel"); d->displayName = i18nc("@label EXIF", "Image Model"); d->valueType = QVariant::String; d->shouldBeIndexed = false; break; case Property::ImageOrientation: 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; case Property::Language: d->name = QStringLiteral("language"); d->displayName = i18nc("@label", "Language"); d->valueType = QVariant::String; d->shouldBeIndexed = false; break; case Property::LineCount: d->name = QStringLiteral("lineCount"); d->displayName = i18nc("@label number of lines", "Line Count"); d->valueType = QVariant::Int; break; case Property::Lyricist: d->name = QStringLiteral("lyricist"); d->displayName = i18nc("@label", "Lyricist"); d->valueType = QVariant::StringList; + d->formatAsString = &FormatStrings::joinStringListFunction; d->shouldBeIndexed = false; break; case Property::PageCount: d->name = QStringLiteral("pageCount"); d->displayName = i18nc("@label", "Page Count"); d->valueType = QVariant::Int; break; case Property::PhotoApertureValue: d->name = QStringLiteral("photoApertureValue"); d->displayName = i18nc("@label EXIF", "Photo Aperture Value"); d->valueType = QVariant::Double; break; case Property::PhotoDateTimeOriginal: 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: d->name = QStringLiteral("photoExposureBiasValue"); d->displayName = i18nc("@label EXIF", "Photo Exposure Bias"); d->valueType = QVariant::Double; break; case Property::PhotoExposureTime: d->name = QStringLiteral("photoExposureTime"); d->displayName = i18nc("@label EXIF", "Photo Exposure Time"); d->valueType = QVariant::Double; break; case Property::PhotoFlash: d->name = QStringLiteral("photoFlash"); d->displayName = i18nc("@label EXIF", "Photo Flash"); d->valueType = QVariant::Int; break; case Property::PhotoFNumber: d->name = QStringLiteral("photoFNumber"); d->displayName = i18nc("@label EXIF", "Photo F Number"); d->valueType = QVariant::Int; break; case Property::PhotoFocalLength: d->name = QStringLiteral("photoFocalLength"); d->displayName = i18nc("@label EXIF", "Photo Focal Length"); d->valueType = QVariant::Double; break; case Property::PhotoFocalLengthIn35mmFilm: d->name = QStringLiteral("photoFocalLengthIn35mmFilm"); d->displayName = i18nc("@label EXIF", "Photo Focal Length 35mm"); d->valueType = QVariant::Double; break; case Property::PhotoGpsLatitude: d->name = QStringLiteral("photoGpsLatitude"); d->displayName = i18nc("@label EXIF", "Photo GPS Latitude"); d->valueType = QVariant::Double; break; case Property::PhotoGpsLongitude: d->name = QStringLiteral("photoGpsLongitude"); d->displayName = i18nc("@label EXIF", "Photo GPS Longitude"); d->valueType = QVariant::Double; break; case Property::PhotoGpsAltitude: d->name = QStringLiteral("photoGpsAltitude"); d->displayName = i18nc("@label EXIF", "Photo GPS Altitude"); d->valueType = QVariant::Double; break; case Property::PhotoISOSpeedRatings: d->name = QStringLiteral("photoISOSpeedRatings"); d->displayName = i18nc("@label EXIF", "Photo ISO Speed Rating"); d->valueType = QVariant::Int; break; case Property::PhotoMeteringMode: d->name = QStringLiteral("photoMeteringMode"); d->displayName = i18nc("@label EXIF", "Photo Metering Mode"); d->valueType = QVariant::Int; break; case Property::PhotoPixelXDimension: d->name = QStringLiteral("photoPixelXDimension"); d->displayName = i18nc("@label EXIF", "Photo X Dimension"); d->valueType = QVariant::Int; break; case Property::PhotoPixelYDimension: d->name = QStringLiteral("photoPixelYDimension"); d->displayName = i18nc("@label EXIF", "Photo Y Dimension"); d->valueType = QVariant::Int; break; case Property::PhotoSaturation: d->name = QStringLiteral("photoSaturation"); d->displayName = i18nc("@label EXIF", "Photo Saturation"); d->valueType = QVariant::Int; break; case Property::PhotoSharpness: d->name = QStringLiteral("photoSharpness"); d->displayName = i18nc("@label EXIF", "Photo Sharpness"); d->valueType = QVariant::Int; break; case Property::PhotoWhiteBalance: d->name = QStringLiteral("photoWhiteBalance"); d->displayName = i18nc("@label EXIF", "Photo White Balance"); d->valueType = QVariant::Int; break; case Property::Publisher: d->name = QStringLiteral("publisher"); d->displayName = i18nc("@label", "Publisher"); d->valueType = QVariant::String; break; case Property::Label: d->name = QStringLiteral("label"); d->displayName = i18nc("@label", "Label"); d->valueType = QVariant::String; break; case Property::ReleaseYear: d->name = QStringLiteral("releaseYear"); d->displayName = i18nc("@label", "Release Year"); d->valueType = QVariant::Int; break; case Property::SampleRate: d->name = QStringLiteral("sampleRate"); d->displayName = i18nc("@label", "Sample Rate"); d->valueType = QVariant::Int; + d->formatAsString = &FormatStrings::formatSampleRate; break; case Property::Subject: d->name = QStringLiteral("subject"); d->displayName = i18nc("@label", "Subject"); d->valueType = QVariant::String; d->shouldBeIndexed = false; break; case Property::Title: d->name = QStringLiteral("title"); d->displayName = i18nc("@label", "Title"); d->valueType = QVariant::String; break; case Property::TrackNumber: d->name = QStringLiteral("trackNumber"); d->displayName = i18nc("@label music track number", "Track Number"); d->valueType = QVariant::Int; break; case Property::DiscNumber: d->name = QStringLiteral("discNumber"); d->displayName = i18nc("@label music disc number", "Disc Number"); d->valueType = QVariant::Int; break; case Property::Location: d->name = QStringLiteral("location"); d->displayName = i18nc("@label", "Location"); d->valueType = QVariant::String; break; case Property::Performer: d->name = QStringLiteral("performer"); d->displayName = i18nc("@label", "Performer"); d->valueType = QVariant::StringList; + d->formatAsString = &FormatStrings::joinStringListFunction; break; case Property::Ensemble: d->name = QStringLiteral("ensemble"); d->displayName = i18nc("@label", "Ensemble"); d->valueType = QVariant::String; break; case Property::Arranger: 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: d->name = QStringLiteral("compilation"); d->displayName = i18nc("@label", "Compilation"); d->valueType = QVariant::String; break; case Property::License: d->name = QStringLiteral("license"); d->displayName = i18nc("@label", "License"); d->valueType = QVariant::String; break; case Property::Lyrics: d->name = QStringLiteral("lyrics"); d->displayName = i18nc("@label", "Lyrics"); d->valueType = QVariant::String; break; case Property::Opus: d->name = QStringLiteral("opus"); d->displayName = i18nc("@label", "Opus"); d->valueType = QVariant::Int; break; case Property::Rating: d->name = QStringLiteral("embeddedRating"); d->displayName = i18nc("@label", "Rating"); d->valueType = QVariant::Int; break; case Property::ReplayGainAlbumPeak: d->name = QStringLiteral("replayGainAlbumPeak"); d->displayName = i18nc("@label", "Replay Gain Album Peak"); d->valueType = QVariant::Double; break; case Property::ReplayGainAlbumGain: d->name = QStringLiteral("replayGainAlbumGain"); d->displayName = i18nc("@label", "Replay Gain Album Gain"); d->valueType = QVariant::Double; break; case Property::ReplayGainTrackPeak: d->name = QStringLiteral("replayGainTrackPeak"); d->displayName = i18nc("@label", "Replay Gain Track Peak"); d->valueType = QVariant::Double; break; case Property::ReplayGainTrackGain: d->name = QStringLiteral("replayGainTrackGain"); d->displayName = i18nc("@label", "Replay Gain Track Gain"); d->valueType = QVariant::Double; break; case Property::Width: d->name = QStringLiteral("width"); d->displayName = i18nc("@label", "Width"); d->valueType = QVariant::Int; break; case Property::WordCount: d->name = QStringLiteral("wordCount"); d->displayName = i18nc("@label number of words", "Word Count"); d->valueType = QVariant::Int; break; case Property::TranslationUnitsTotal: d->name = QStringLiteral("translationUnitsTotal"); d->displayName = i18nc("@label number of translatable strings", "Translatable Units"); d->valueType = QVariant::Int; d->shouldBeIndexed = false; break; case Property::TranslationUnitsWithTranslation: d->name = QStringLiteral("translationUnitsWithTranslation"); d->displayName = i18nc("@label number of translated strings", "Translations"); d->valueType = QVariant::Int; d->shouldBeIndexed = false; break; case Property::TranslationUnitsWithDraftTranslation: d->name = QStringLiteral("translationUnitsWithDraftTranslation"); d->displayName = i18nc("@label number of fuzzy translated strings", "Draft Translations"); d->valueType = QVariant::Int; d->shouldBeIndexed = false; break; case Property::TranslationLastAuthor: d->name = QStringLiteral("translationLastAuthor"); d->displayName = i18nc("@label translation author", "Author"); d->valueType = QVariant::String; d->shouldBeIndexed = false; break; case Property::TranslationLastUpDate: d->name = QStringLiteral("translationLastUpDate"); 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: d->name = QStringLiteral("originUrl"); d->displayName = i18nc("@label the URL a file was originally downloaded from", "Downloaded From"); d->valueType = QVariant::Url; d->shouldBeIndexed = false; break; case Property::OriginEmailSubject: d->name = QStringLiteral("originEmailSubject"); d->displayName = i18nc("@label the subject of an email this file was attached to", "E-Mail Attachment Subject"); d->valueType = QVariant::String; d->shouldBeIndexed = false; break; case Property::OriginEmailSender: d->name = QStringLiteral("originEmailSender"); d->displayName = i18nc("@label the sender of an email this file was attached to", "E-Mail Attachment Sender"); d->valueType = QVariant::String; d->shouldBeIndexed = false; break; case Property::OriginEmailMessageId: d->name = QStringLiteral("originEmailMessageId"); d->displayName = i18nc("@label the message ID of an email this file was attached to", "E-Mail Attachment Message ID"); d->valueType = QVariant::String; d->shouldBeIndexed = false; break; case Property::PropertyCount: // To silence the compiler. break; // NOTE: new properties must also be added to ::fromName() } if (d->valueType == QVariant::Int || d->valueType == QVariant::DateTime || d->valueType == QVariant::Double) { d->shouldBeIndexed = false; } } PropertyInfo::PropertyInfo(const PropertyInfo& pi) : d(new Private(*pi.d)) { } PropertyInfo::~PropertyInfo() { delete d; } PropertyInfo& PropertyInfo::operator=(const PropertyInfo& rhs) { *d = *rhs.d; return *this; } bool PropertyInfo::operator==(const PropertyInfo& rhs) const { return d->name == rhs.d->name && d->displayName == rhs.d->displayName && d->prop == rhs.d->prop && d->shouldBeIndexed == rhs.d->shouldBeIndexed; } QString PropertyInfo::displayName() const { return d->displayName; } QString PropertyInfo::name() const { return d->name; } Property::Property PropertyInfo::property() const { return d->prop; } QVariant::Type PropertyInfo::valueType() const { return d->valueType; } 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 propertyHash = { { QStringLiteral("bitrate"), Property::BitRate }, { QStringLiteral("channels"), Property::Channels }, { QStringLiteral("duration"), Property::Duration }, { QStringLiteral("genre"), Property::Genre }, { QStringLiteral("samplerate"), Property::SampleRate }, { QStringLiteral("tracknumber"), Property::TrackNumber }, { QStringLiteral("discnumber"), Property::DiscNumber }, { QStringLiteral("releaseyear"), Property::ReleaseYear }, { QStringLiteral("comment"), Property::Comment }, { QStringLiteral("description"), Property::Description }, { QStringLiteral("artist"), Property::Artist }, { QStringLiteral("album"), Property::Album }, { QStringLiteral("albumartist"), Property::AlbumArtist }, { QStringLiteral("composer"), Property::Composer }, { QStringLiteral("lyricist"), Property::Lyricist }, { QStringLiteral("location"), Property::Location }, { QStringLiteral("performer"), Property::Performer }, { QStringLiteral("ensemble"), Property::Ensemble }, { QStringLiteral("arranger"), Property::Arranger }, { QStringLiteral("conductor"), Property::Conductor }, { QStringLiteral("opus"), Property::Opus }, { QStringLiteral("embeddedrating"), Property::Rating }, { QStringLiteral("author"), Property::Author }, { QStringLiteral("title"), Property::Title }, { QStringLiteral("subject"), Property::Subject }, { QStringLiteral("generator"), Property::Generator }, { QStringLiteral("pagecount"), Property::PageCount }, { QStringLiteral("wordcount"), Property::WordCount }, { QStringLiteral("linecount"), Property::LineCount }, { QStringLiteral("language"), Property::Language }, { QStringLiteral("copyright"), Property::Copyright }, { QStringLiteral("publisher"), Property::Publisher }, { QStringLiteral("label"), Property::Label }, { QStringLiteral("compilation"), Property::Compilation }, { QStringLiteral("license"), Property::License }, { QStringLiteral("lyrics"), Property::Lyrics }, { QStringLiteral("replaygainalbumpeak"), Property::ReplayGainAlbumPeak }, { QStringLiteral("replaygainalbumgain"), Property::ReplayGainAlbumGain }, { QStringLiteral("replaygaintrackpeak"), Property::ReplayGainTrackPeak }, { QStringLiteral("replaygaintrackgain"), Property::ReplayGainTrackGain }, { QStringLiteral("creationdate"), Property::CreationDate }, { QStringLiteral("keywords"), Property::Keywords }, { QStringLiteral("width"), Property::Width }, { QStringLiteral("height"), Property::Height }, { QStringLiteral("aspectratio"), Property::AspectRatio }, { QStringLiteral("framerate"), Property::FrameRate }, { QStringLiteral("imagemake"), Property::ImageMake }, { QStringLiteral("imagemodel"), Property::ImageModel }, { QStringLiteral("imagedatetime"), Property::ImageDateTime }, { QStringLiteral("imageorientation"), Property::ImageOrientation }, { QStringLiteral("photoflash"), Property::PhotoFlash }, { QStringLiteral("photopixelxdimension"), Property::PhotoPixelXDimension }, { QStringLiteral("photopixelydimension"), Property::PhotoPixelYDimension }, { QStringLiteral("photodatetimeoriginal"), Property::PhotoDateTimeOriginal }, { QStringLiteral("photofocallength"), Property::PhotoFocalLength }, { QStringLiteral("photofocallengthin35mmfilm"), Property::PhotoFocalLengthIn35mmFilm }, { QStringLiteral("photoexposuretime"), Property::PhotoExposureTime }, { QStringLiteral("photofnumber"), Property::PhotoFNumber }, { QStringLiteral("photoaperturevalue"), Property::PhotoApertureValue }, { QStringLiteral("photoexposurebiasvalue"), Property::PhotoExposureBiasValue }, { QStringLiteral("photowhitebalance"), Property::PhotoWhiteBalance }, { QStringLiteral("photometeringmode"), Property::PhotoMeteringMode }, { QStringLiteral("photoisospeedratings"), Property::PhotoISOSpeedRatings }, { QStringLiteral("photosaturation"), Property::PhotoSaturation }, { QStringLiteral("photosharpness"), Property::PhotoSharpness }, { QStringLiteral("photogpslatitude"), Property::PhotoGpsLatitude }, { QStringLiteral("photogpslongitude"), Property::PhotoGpsLongitude }, { QStringLiteral("photogpsaltitude"), Property::PhotoGpsAltitude }, { QStringLiteral("translationunitstotal"), Property::TranslationUnitsTotal }, { QStringLiteral("translationunitswithtranslation"), Property::TranslationUnitsWithTranslation }, { QStringLiteral("translationunitswithdrafttranslation"), Property::TranslationUnitsWithDraftTranslation }, { QStringLiteral("translationlastauthor"), Property::TranslationLastAuthor }, { QStringLiteral("translationlastupdate"), Property::TranslationLastUpDate }, { QStringLiteral("translationtemplatedate"), Property::TranslationTemplateDate }, { QStringLiteral("originurl"), Property::OriginUrl }, { QStringLiteral("originemailsubject"), Property::OriginEmailSubject }, { QStringLiteral("originemailsender"), Property::OriginEmailSender }, { QStringLiteral("originemailmessageid"), Property::OriginEmailMessageId } }; return PropertyInfo(propertyHash.value(name.toLower())); } diff --git a/src/propertyinfo.h b/src/propertyinfo.h index c1767c4..3c426e8 100644 --- a/src/propertyinfo.h +++ b/src/propertyinfo.h @@ -1,94 +1,101 @@ /* * This file is part of the KFileMetaData project * Copyright (C) 2014 Vishesh Handa * * 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) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * 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, see . * */ #ifndef _KFILEMETADATA_PROPERTYINFO_H #define _KFILEMETADATA_PROPERTYINFO_H #include #include #include "properties.h" #include "kfilemetadata_export.h" namespace KFileMetaData { /** * \class PropertyInfo propertyinfo.h * * The PropertyInfo class can be used to obtain extra information * about any property. It is commonly used be indexers in order * to obtain a translatable name of the property along with * additional information such as if the property should be indexed. */ class KFILEMETADATA_EXPORT PropertyInfo { public: PropertyInfo(Property::Property property); PropertyInfo(const PropertyInfo& pi); ~PropertyInfo(); PropertyInfo& operator=(const PropertyInfo& rhs); bool operator==(const PropertyInfo& rhs) const; /** * The enumeration which represents this property */ Property::Property property() const; /** * The internal unique name used to refer to the property */ QString name() const; /** * A user visible name of the property */ QString displayName() const; /** * The type the value of this property should be. * Eg - Property::Height should be an integer */ QVariant::Type valueType() const; /** * Indicates if this property requires indexing or should just be stored. * Eg - Property::Height does not need to be part of the global index. * When a user searches for 600, they should not get images with * that height * * This is just a recommendation. */ bool shouldBeIndexed() const; /** * Construct a PropertyInfo from the internal property name. * The internal property name is case insensitive */ 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; }; } #endif // _KFILEMETADATA_PROPERTYINFO_H