X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/97415005de040885cb63ea01fdb879e20226a2f2..cebcf8db:/src/kitemviews/private/kbaloorolesprovider.cpp diff --git a/src/kitemviews/private/kbaloorolesprovider.cpp b/src/kitemviews/private/kbaloorolesprovider.cpp index 9f151df92..d0632e2c5 100644 --- a/src/kitemviews/private/kbaloorolesprovider.cpp +++ b/src/kitemviews/private/kbaloorolesprovider.cpp @@ -1,43 +1,72 @@ -/*************************************************************************** - * Copyright (C) 2012 by Peter Penz * - * Copyright (C) 2013 by Vishesh Handa * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program 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 General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ +/* + * SPDX-FileCopyrightText: 2012 Peter Penz + * SPDX-FileCopyrightText: 2013 Vishesh Handa + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ #include "kbaloorolesprovider.h" -#include -#include - #include #include #include -#include -#include +#include +#include -struct KBalooRolesProviderSingleton +namespace +{ +QString tagsFromValues(const QStringList &values) { + if (values.size() == 1) { + return values.at(0); + } + + QStringList alphabeticalOrderTags = values; + QCollator coll; + coll.setNumericMode(true); + std::sort(alphabeticalOrderTags.begin(), alphabeticalOrderTags.end(), [&](const QString &s1, const QString &s2) { + return coll.compare(s1, s2) < 0; + }); + return alphabeticalOrderTags.join(QLatin1String(", ")); +} + + using Property = KFileMetaData::Property::Property; + // Mapping from the KFM::Property to the KFileItemModel roles. + const QHash propertyRoleMap() { + static const auto map = QHash { + { Property::Rating, QByteArrayLiteral("rating") }, + { Property::Comment, QByteArrayLiteral("comment") }, + { Property::Title, QByteArrayLiteral("title") }, + { Property::Author, QByteArrayLiteral("author") }, + { Property::Publisher, QByteArrayLiteral("publisher") }, + { Property::PageCount, QByteArrayLiteral("pageCount") }, + { Property::WordCount, QByteArrayLiteral("wordCount") }, + { Property::LineCount, QByteArrayLiteral("lineCount") }, + { Property::Width, QByteArrayLiteral("width") }, + { Property::Height, QByteArrayLiteral("height") }, + { Property::ImageDateTime, QByteArrayLiteral("imageDateTime") }, + { Property::ImageOrientation, QByteArrayLiteral("orientation") }, + { Property::Artist, QByteArrayLiteral("artist") }, + { Property::Genre, QByteArrayLiteral("genre") }, + { Property::Album, QByteArrayLiteral("album") }, + { Property::Duration, QByteArrayLiteral("duration") }, + { Property::BitRate, QByteArrayLiteral("bitrate") }, + { Property::AspectRatio, QByteArrayLiteral("aspectRatio") }, + { Property::FrameRate, QByteArrayLiteral("frameRate") }, + { Property::ReleaseYear, QByteArrayLiteral("releaseYear") }, + { Property::TrackNumber, QByteArrayLiteral("track") } + }; + return map; + } +} + +struct KBalooRolesProviderSingleton { KBalooRolesProvider instance; }; Q_GLOBAL_STATIC(KBalooRolesProviderSingleton, s_balooRolesProvider) - -KBalooRolesProvider& KBalooRolesProvider::instance() +KBalooRolesProvider &KBalooRolesProvider::instance() { return s_balooRolesProvider->instance; } @@ -51,139 +80,108 @@ QSet KBalooRolesProvider::roles() const return m_roles; } -QHash KBalooRolesProvider::roleValues(const Baloo::File& file, - const QSet& roles) const +QHash KBalooRolesProvider::roleValues(const Baloo::File &file, const QSet &roles) const { QHash values; - int width = -1; - int height = -1; + using entry = std::pair; + + const auto &propMap = file.properties(); + auto rangeBegin = propMap.constKeyValueBegin(); + + while (rangeBegin != propMap.constKeyValueEnd()) { + auto key = (*rangeBegin).first; - QMapIterator it(file.properties()); - while (it.hasNext()) { - it.next(); + auto rangeEnd = std::find_if(rangeBegin, propMap.constKeyValueEnd(), [key](const entry &e) { + return e.first != key; + }); - const KFileMetaData::PropertyInfo pi(it.key()); - const QString property = pi.name(); - const QByteArray role = roleForProperty(property); + const QByteArray role = propertyRoleMap().value(key); if (role.isEmpty() || !roles.contains(role)) { + rangeBegin = rangeEnd; continue; } - const QVariant value = it.value(); - - if (role == "imageSize") { - // Merge the two properties for width and height - // as one string into the "imageSize" role - if (property == QLatin1String("width")) { - width = value.toInt(); - } - else if (property == QLatin1String("height")) { - height = value.toInt(); + const KFileMetaData::PropertyInfo propertyInfo(key); + auto distance = std::distance(rangeBegin, rangeEnd); + if (distance > 1) { + QVariantList list; + list.reserve(static_cast(distance)); + std::for_each(rangeBegin, rangeEnd, [&list](const entry &s) { + list.append(s.second); + }); + values.insert(role, propertyInfo.formatAsDisplayString(list)); + } else { + if (propertyInfo.valueType() == QMetaType::Type::QDateTime) { + // Let dolphin format later Dates + values.insert(role, (*rangeBegin).second); + } else { + values.insert(role, propertyInfo.formatAsDisplayString((*rangeBegin).second)); } + } + rangeBegin = rangeEnd; + } - if (width >= 0 && height >= 0) { - QString widthAndHeight = QString::number(width); - widthAndHeight += QLatin1String(" x "); - widthAndHeight += QString::number(height); - values.insert(role, widthAndHeight); - } - } else if (role == "orientation") { - const QString orientation = orientationFromValue(value.toInt()); - values.insert(role, orientation); - } else if (role == "duration") { - const QString duration = durationFromValue(value.toInt()); - values.insert(role, duration); - } else { - values.insert(role, value.toString()); + if (roles.contains("dimensions")) { + bool widthOk = false; + bool heightOk = false; + + const int width = propMap.value(KFileMetaData::Property::Width).toInt(&widthOk); + const int height = propMap.value(KFileMetaData::Property::Height).toInt(&heightOk); + + if (widthOk && heightOk && width >= 0 && height >= 0) { + values.insert("dimensions", QSize(width, height)); } } - KFileMetaData::UserMetaData md(file.path()); + KFileMetaData::UserMetaData::Attributes attributes; if (roles.contains("tags")) { - values.insert("tags", tagsFromValues(md.tags())); + attributes |= KFileMetaData::UserMetaData::Tags; } if (roles.contains("rating")) { - values.insert("rating", QString::number(md.rating())); + attributes |= KFileMetaData::UserMetaData::Rating; } if (roles.contains("comment")) { - values.insert("comment", md.userComment()); + attributes |= KFileMetaData::UserMetaData::Comment; } if (roles.contains("originUrl")) { - values.insert("originUrl", md.originUrl()); + attributes |= KFileMetaData::UserMetaData::OriginUrl; } - return values; -} + if (attributes == KFileMetaData::UserMetaData::None) { + return values; + } -QByteArray KBalooRolesProvider::roleForProperty(const QString& property) const -{ - return m_roleForProperty.value(property); -} + KFileMetaData::UserMetaData md(file.path()); + attributes = md.queryAttributes(attributes); -KBalooRolesProvider::KBalooRolesProvider() : - m_roles(), - m_roleForProperty() -{ - struct PropertyInfo - { - const char* const property; - const char* const role; - }; - - // Mapping from the URIs to the KFileItemModel roles. Note that this must not be - // a 1:1 mapping: One role may contain several URI-values (e.g. the URIs for height and - // width of an image are mapped to the role "imageSize") - static const PropertyInfo propertyInfoList[] = { - { "rating", "rating" }, - { "tag", "tags" }, - { "comment", "comment" }, - { "title", "title" }, - { "wordCount", "wordCount" }, - { "lineCount", "lineCount" }, - { "width", "imageSize" }, - { "height", "imageSize" }, - { "nexif.orientation", "orientation", }, - { "artist", "artist" }, - { "album", "album" }, - { "duration", "duration" }, - { "trackNumber", "track" }, - { "originUrl", "originUrl" } - }; - - for (unsigned int i = 0; i < sizeof(propertyInfoList) / sizeof(PropertyInfo); ++i) { - m_roleForProperty.insert(propertyInfoList[i].property, propertyInfoList[i].role); - m_roles.insert(propertyInfoList[i].role); + if (attributes & KFileMetaData::UserMetaData::Tags) { + values.insert("tags", tagsFromValues(md.tags())); + } + if (attributes & KFileMetaData::UserMetaData::Rating) { + values.insert("rating", QString::number(md.rating())); + } + if (attributes & KFileMetaData::UserMetaData::Comment) { + values.insert("comment", md.userComment()); + } + if (attributes & KFileMetaData::UserMetaData::OriginUrl) { + values.insert("originUrl", md.originUrl()); } -} -QString KBalooRolesProvider::tagsFromValues(const QStringList& values) const -{ - return values.join(QStringLiteral(", ")); + return values; } -QString KBalooRolesProvider::orientationFromValue(int value) const +KBalooRolesProvider::KBalooRolesProvider() { - QString string; - switch (value) { - 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; + // Display roles filled from Baloo property cache + for (const auto &role : propertyRoleMap()) { + m_roles.insert(role); } - return string; -} + m_roles.insert("dimensions"); -QString KBalooRolesProvider::durationFromValue(int value) const -{ - QTime duration; - duration = duration.addSecs(value); - return duration.toString(QStringLiteral("hh:mm:ss")); + // Display roles provided by UserMetaData + m_roles.insert(QByteArrayLiteral("tags")); + m_roles.insert(QByteArrayLiteral("rating")); + m_roles.insert(QByteArrayLiteral("comment")); + m_roles.insert(QByteArrayLiteral("originUrl")); } -