/* This file is part of the KFileMetaData project SPDX-FileCopyrightText: 2014 Vishesh Handa SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL */ #include "propertyinfo.h" #include #include #include "formatstrings_p.h" #include "icnamematch_p.h" #include #include using namespace KFileMetaData; class KFileMetaData::PropertyInfoData { using FormatFunction = QString (&)(const QVariant&); public: const Property::Property prop; const bool shouldBeIndexed = false; const QString name; const KLazyLocalizedString displayName; const QMetaType::Type valueType = QMetaType::UnknownType; const FormatFunction formatAsString = FormatStrings::toStringFunction; static constexpr auto fromId(Property::Property property) -> const PropertyInfoData*; static auto fromName(const QString& name) -> const PropertyInfoData*; static const PropertyInfoData s_Empty; static const std::array s_allProperties; static const QHash s_propertyHash; }; const PropertyInfoData PropertyInfoData::s_Empty{ Property::Empty, false, QStringLiteral("empty"), kli18nc("@label", "Empty") }; const std::array PropertyInfoData::s_allProperties { PropertyInfoData{ Property::Album, true, QStringLiteral("album"), kli18nc("@label music album", "Album"), QMetaType::QString }, PropertyInfoData{ Property::AlbumArtist, true, QStringLiteral("albumArtist"), kli18nc("@label", "Album Artist"), QMetaType::QString }, PropertyInfoData{ Property::Artist, true, QStringLiteral("artist"), kli18nc("@label", "Artist"), QMetaType::QString }, PropertyInfoData{ Property::AspectRatio, false, QStringLiteral("aspectRatio"), kli18nc("@label", "Aspect Ratio"), QMetaType::Double, FormatStrings::formatAspectRatio }, PropertyInfoData{ Property::Author, true, QStringLiteral("author"), kli18nc("@label", "Author"), QMetaType::QString }, PropertyInfoData{ Property::BitRate, false, QStringLiteral("bitRate"), kli18nc("@label", "Bitrate"), QMetaType::Int, FormatStrings::formatBitRate }, PropertyInfoData{ Property::Channels, false, QStringLiteral("channels"), kli18nc("@label", "Channels"), QMetaType::Int }, PropertyInfoData{ Property::Comment, false, QStringLiteral("comment"), kli18nc("@label", "Comment"), QMetaType::QString }, PropertyInfoData{ Property::Description, false, QStringLiteral("description"), kli18nc("@label", "Description"), QMetaType::QString }, PropertyInfoData{ Property::Composer, true, QStringLiteral("composer"), kli18nc("@label", "Composer"), QMetaType::QString }, PropertyInfoData{ Property::Copyright, false, QStringLiteral("copyright"), kli18nc("@label", "Copyright"), QMetaType::QString }, PropertyInfoData{ Property::CreationDate, false, QStringLiteral("creationDate"), kli18nc("@label", "Creation Date"), QMetaType::QDateTime, FormatStrings::formatDate }, PropertyInfoData{ Property::Duration, false, QStringLiteral("duration"), kli18nc("@label", "Duration"), QMetaType::Int, FormatStrings::formatDuration }, PropertyInfoData{ Property::FrameRate, false, QStringLiteral("frameRate"), kli18nc("@label", "Frame Rate"), QMetaType::Double, FormatStrings::formatAsFrameRate }, PropertyInfoData{ Property::Generator, false, QStringLiteral("generator"), kli18nc("@label", "Document Generated By"), QMetaType::QString }, PropertyInfoData{ Property::Genre, true, QStringLiteral("genre"), kli18nc("@label music genre", "Genre"), QMetaType::QString }, PropertyInfoData{ Property::Height, false, QStringLiteral("height"), kli18nc("@label", "Height"), QMetaType::Int }, PropertyInfoData{ Property::ImageDateTime, false, QStringLiteral("imageDateTime"), kli18nc("@label EXIF", "Image Date Time"), QMetaType::QDateTime, FormatStrings::formatDate }, PropertyInfoData{ Property::Manufacturer, false, QStringLiteral("manufacturer"), kli18nc("@label EXIF", "Manufacturer"), QMetaType::QString }, PropertyInfoData{ Property::Model, false, QStringLiteral("model"), kli18nc("@label EXIF", "Model"), QMetaType::QString }, PropertyInfoData{ Property::ImageOrientation, false, QStringLiteral("imageOrientation"), kli18nc("@label EXIF", "Image Orientation"), QMetaType::Int, FormatStrings::formatOrientationValue }, PropertyInfoData{ Property::Keywords, false, QStringLiteral("keywords"), kli18nc("@label", "Keywords"), QMetaType::QString }, PropertyInfoData{ Property::Language, false, QStringLiteral("language"), kli18nc("@label", "Language"), QMetaType::QString }, PropertyInfoData{ Property::LineCount, false, QStringLiteral("lineCount"), kli18nc("@label number of lines", "Line Count"), QMetaType::Int }, PropertyInfoData{ Property::Lyricist, true, QStringLiteral("lyricist"), kli18nc("@label", "Lyricist"), QMetaType::QString }, PropertyInfoData{ Property::PageCount, false, QStringLiteral("pageCount"), kli18nc("@label", "Page Count"), QMetaType::Int }, PropertyInfoData{ Property::PhotoApertureValue, false, QStringLiteral("photoApertureValue"), kli18nc("@label EXIF", "Aperture Value"), QMetaType::Double, FormatStrings::formatAsFNumber }, PropertyInfoData{ Property::PhotoDateTimeOriginal, false, QStringLiteral("photoDateTimeOriginal"), kli18nc("@label EXIF", "Original Date Time"), QMetaType::QDateTime, FormatStrings::formatDate }, PropertyInfoData{ Property::PhotoExposureBiasValue, false, QStringLiteral("photoExposureBiasValue"), kli18nc("@label EXIF", "Exposure Bias"), QMetaType::Double, FormatStrings::formatPhotoExposureBias }, PropertyInfoData{ Property::PhotoExposureTime, false, QStringLiteral("photoExposureTime"), kli18nc("@label EXIF", "Exposure Time"), QMetaType::Double, FormatStrings::formatPhotoTime }, PropertyInfoData{ Property::PhotoFlash, false, QStringLiteral("photoFlash"), kli18nc("@label EXIF", "Flash"), QMetaType::Int, FormatStrings::formatPhotoFlashValue }, PropertyInfoData{ Property::PhotoFNumber, false, QStringLiteral("photoFNumber"), kli18nc("@label EXIF", "F Number"), QMetaType::Double, FormatStrings::formatAsFNumber }, PropertyInfoData{ Property::PhotoFocalLength, false, QStringLiteral("photoFocalLength"), kli18nc("@label EXIF", "Focal Length"), QMetaType::Double, FormatStrings::formatAsMilliMeter }, PropertyInfoData{ Property::PhotoFocalLengthIn35mmFilm, false, QStringLiteral("photoFocalLengthIn35mmFilm"), kli18nc("@label EXIF", "Focal Length 35mm"), QMetaType::Double, FormatStrings::formatAsMilliMeter }, PropertyInfoData{ Property::PhotoGpsLatitude, false, QStringLiteral("photoGpsLatitude"), kli18nc("@label EXIF", "GPS Latitude"), QMetaType::Double, FormatStrings::formatAsDegree }, PropertyInfoData{ Property::PhotoGpsLongitude, false, QStringLiteral("photoGpsLongitude"), kli18nc("@label EXIF", "GPS Longitude"), QMetaType::Double, FormatStrings::formatAsDegree }, PropertyInfoData{ Property::PhotoGpsAltitude, false, QStringLiteral("photoGpsAltitude"), kli18nc("@label EXIF", "GPS Altitude"), QMetaType::Double, FormatStrings::formatAsMeter }, PropertyInfoData{ Property::PhotoISOSpeedRatings, false, QStringLiteral("photoISOSpeedRatings"), kli18nc("@label EXIF", "ISO Speed Rating"), QMetaType::Int }, PropertyInfoData{ Property::PhotoMeteringMode, false, QStringLiteral("photoMeteringMode"), kli18nc("@label EXIF", "Metering Mode"), QMetaType::Int }, PropertyInfoData{ Property::PhotoPixelXDimension, false, QStringLiteral("photoPixelXDimension"), kli18nc("@label EXIF", "X Dimension"), QMetaType::Int }, PropertyInfoData{ Property::PhotoPixelYDimension, false, QStringLiteral("photoPixelYDimension"), kli18nc("@label EXIF", "Y Dimension"), QMetaType::Int }, PropertyInfoData{ Property::PhotoSaturation, false, QStringLiteral("photoSaturation"), kli18nc("@label EXIF", "Saturation"), QMetaType::Int }, PropertyInfoData{ Property::PhotoSharpness, false, QStringLiteral("photoSharpness"), kli18nc("@label EXIF", "Sharpness"), QMetaType::Int }, PropertyInfoData{ Property::PhotoWhiteBalance, false, QStringLiteral("photoWhiteBalance"), kli18nc("@label EXIF", "White Balance"), QMetaType::Int }, PropertyInfoData{ Property::Publisher, true, QStringLiteral("publisher"), kli18nc("@label", "Publisher"), QMetaType::QString }, PropertyInfoData{ Property::Label, true, QStringLiteral("label"), kli18nc("@label", "Label"), QMetaType::QString }, PropertyInfoData{ Property::ReleaseYear, false, QStringLiteral("releaseYear"), kli18nc("@label", "Release Year"), QMetaType::Int }, PropertyInfoData{ Property::SampleRate, false, QStringLiteral("sampleRate"), kli18nc("@label", "Sample Rate"), QMetaType::Int, FormatStrings::formatSampleRate }, PropertyInfoData{ Property::Subject, false, QStringLiteral("subject"), kli18nc("@label", "Subject"), QMetaType::QString }, PropertyInfoData{ Property::Title, true, QStringLiteral("title"), kli18nc("@label", "Title"), QMetaType::QString }, PropertyInfoData{ Property::TrackNumber, false, QStringLiteral("trackNumber"), kli18nc("@label music track number", "Track Number"), QMetaType::Int }, PropertyInfoData{ Property::DiscNumber, false, QStringLiteral("discNumber"), kli18nc("@label music disc number", "Disc Number"), QMetaType::Int }, PropertyInfoData{ Property::Location, true, QStringLiteral("location"), kli18nc("@label", "Location"), QMetaType::QString }, PropertyInfoData{ Property::Performer, true, QStringLiteral("performer"), kli18nc("@label", "Performer"), QMetaType::QString }, PropertyInfoData{ Property::Ensemble, true, QStringLiteral("ensemble"), kli18nc("@label", "Ensemble"), QMetaType::QString }, PropertyInfoData{ Property::Arranger, true, QStringLiteral("arranger"), kli18nc("@label", "Arranger"), QMetaType::QString }, PropertyInfoData{ Property::Conductor, true, QStringLiteral("conductor"), kli18nc("@label", "Conductor"), QMetaType::QString }, PropertyInfoData{ Property::Compilation, true, QStringLiteral("compilation"), kli18nc("@label", "Compilation"), QMetaType::QString }, PropertyInfoData{ Property::License, true, QStringLiteral("license"), kli18nc("@label", "License"), QMetaType::QString }, PropertyInfoData{ Property::Lyrics, true, QStringLiteral("lyrics"), kli18nc("@label", "Lyrics"), QMetaType::QString }, PropertyInfoData{ Property::Opus, false, QStringLiteral("opus"), kli18nc("@label", "Opus"), QMetaType::Int }, PropertyInfoData{ Property::Rating, false, QStringLiteral("embeddedRating"), kli18nc("@label", "Rating"), QMetaType::Int }, PropertyInfoData{ Property::ReplayGainAlbumPeak, false, QStringLiteral("replayGainAlbumPeak"), kli18nc("@label ReplayGain is the name of a standard", "ReplayGain Album Peak"), QMetaType::Double, FormatStrings::formatDouble }, PropertyInfoData{ Property::ReplayGainAlbumGain, false, QStringLiteral("replayGainAlbumGain"), kli18nc("@label ReplayGain is the name of a standard", "ReplayGain Album Gain"), QMetaType::Double, FormatStrings::formatDouble }, PropertyInfoData{ Property::ReplayGainTrackPeak, false, QStringLiteral("replayGainTrackPeak"), kli18nc("@label ReplayGain is the name of a standard", "ReplayGain Track Peak"), QMetaType::Double, FormatStrings::formatDouble }, PropertyInfoData{ Property::ReplayGainTrackGain, false, QStringLiteral("replayGainTrackGain"), kli18nc("@label ReplayGain is the name of a standard", "ReplayGain Track Gain"), QMetaType::Double, FormatStrings::formatDouble }, PropertyInfoData{ Property::Width, false, QStringLiteral("width"), kli18nc("@label", "Width"), QMetaType::Int }, PropertyInfoData{ Property::WordCount, false, QStringLiteral("wordCount"), kli18nc("@label number of words", "Word Count"), QMetaType::Int }, PropertyInfoData{ Property::TranslationUnitsTotal, false, QStringLiteral("translationUnitsTotal"), kli18nc("@label number of translatable strings", "Translatable Units"), QMetaType::Int }, PropertyInfoData{ Property::TranslationUnitsWithTranslation, false, QStringLiteral("translationUnitsWithTranslation"), kli18nc("@label number of translated strings", "Translations"), QMetaType::Int }, PropertyInfoData{ Property::TranslationUnitsWithDraftTranslation, false, QStringLiteral("translationUnitsWithDraftTranslation"), kli18nc("@label number of fuzzy translated strings", "Draft Translations"), QMetaType::Int }, PropertyInfoData{ Property::TranslationLastAuthor, false, QStringLiteral("translationLastAuthor"), kli18nc("@label translation author", "Author"), QMetaType::QString }, PropertyInfoData{ Property::TranslationLastUpDate, false, QStringLiteral("translationLastUpDate"), kli18nc("@label translations last update", "Last Update"), QMetaType::QString, FormatStrings::formatDate }, PropertyInfoData{ Property::TranslationTemplateDate, false, QStringLiteral("translationTemplateDate"), kli18nc("@label date of template creation8", "Template Creation"), QMetaType::QString, FormatStrings::formatDate }, PropertyInfoData{ Property::OriginUrl, false, QStringLiteral("originUrl"), kli18nc("@label the URL a file was originally downloaded from", "Downloaded From"), QMetaType::QUrl }, PropertyInfoData{ Property::OriginEmailSubject, false, QStringLiteral("originEmailSubject"), kli18nc("@label the subject of an email this file was attached to", "E-Mail Attachment Subject"), QMetaType::QString }, PropertyInfoData{ Property::OriginEmailSender, false, QStringLiteral("originEmailSender"), kli18nc("@label the sender of an email this file was attached to", "E-Mail Attachment Sender"), QMetaType::QString }, PropertyInfoData{ Property::OriginEmailMessageId, false, QStringLiteral("originEmailMessageId"), kli18nc("@label the message ID of an email this file was attached to", "E-Mail Attachment Message ID"), QMetaType::QString } }; const QHash PropertyInfoData::s_propertyHash = []() { QHash infoHash; infoHash.reserve(s_allProperties.size()); for (const auto& info: s_allProperties) { infoHash[QStringView(info.name)] = &info; } return infoHash; }(); constexpr auto PropertyInfoData::fromId(Property::Property property) -> const PropertyInfoData* { for (const auto& p : s_allProperties) { if (p.prop == property) return &p; } return &s_Empty; } auto PropertyInfoData::fromName(const QString& name) -> const PropertyInfoData* { return s_propertyHash.value(LcIdentifierName(name), &s_Empty); } PropertyInfo::PropertyInfo(Property::Property property) : d(PropertyInfoData::fromId(property)) {}; PropertyInfo::PropertyInfo() : d(&PropertyInfoData::s_Empty) {}; PropertyInfo::PropertyInfo(const PropertyInfo& pi) : d(pi.d) { } PropertyInfo::~PropertyInfo() = default; PropertyInfo& PropertyInfo::operator=(const PropertyInfo& rhs) { d = rhs.d; return *this; } bool PropertyInfo::operator==(const PropertyInfo& rhs) const { return d == rhs.d; } QString PropertyInfo::displayName() const { return d->displayName.toString(); } QString PropertyInfo::name() const { return d->name; } Property::Property PropertyInfo::property() const { return d->prop; } QMetaType::Type PropertyInfo::valueType() const { return d->valueType; } bool PropertyInfo::shouldBeIndexed() const { return d->shouldBeIndexed; } QString PropertyInfo::formatAsDisplayString(const QVariant &value) const { if (value.userType() == QMetaType::QVariantList || value.userType() == QMetaType::QStringList) { if (d->valueType == QMetaType::QString) { return QLocale().createSeparatedList(value.toStringList()); } else { QStringList displayList; const auto valueList = value.toList(); for (const auto& entry : valueList) { displayList << d->formatAsString(entry); } return QLocale().createSeparatedList(displayList); } } else { return d->formatAsString(value); } } PropertyInfo PropertyInfo::fromName(const QString& name) { PropertyInfo pi; pi.d = PropertyInfoData::fromName(name); return pi; } QStringList PropertyInfo::allNames() { static QStringList sNames = []() { QStringList names; names.reserve(PropertyInfoData::s_allProperties.size()); for (auto info: PropertyInfoData::s_allProperties) { names.append(info.name); } return names; }(); return sNames; }