]> cloud.milkyroute.net Git - dolphin.git/blob - src/kitemviews/private/kbaloorolesprovider.cpp
dd6df0aa77dbfc466426b4374ef97923298604f6
[dolphin.git] / src / kitemviews / private / kbaloorolesprovider.cpp
1 /*
2 * SPDX-FileCopyrightText: 2012 Peter Penz <peter.penz19@gmail.com>
3 * SPDX-FileCopyrightText: 2013 Vishesh Handa <me@vhanda.in>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8 #include "kbaloorolesprovider.h"
9
10 #include <Baloo/File>
11 #include <KFileMetaData/PropertyInfo>
12 #include <KFileMetaData/UserMetaData>
13
14 #include <QCollator>
15 #include <QSize>
16
17 namespace {
18 QString tagsFromValues(const QStringList& values)
19 {
20 if (values.size() == 1) {
21 return values.at(0);
22 }
23
24 QStringList alphabeticalOrderTags = values;
25 QCollator coll;
26 coll.setNumericMode(true);
27 std::sort(alphabeticalOrderTags.begin(), alphabeticalOrderTags.end(), [&](const QString& s1, const QString& s2){ return coll.compare(s1, s2) < 0; });
28 return alphabeticalOrderTags.join(QLatin1String(", "));
29 }
30
31 using Property = KFileMetaData::Property::Property;
32 // Mapping from the KFM::Property to the KFileItemModel roles.
33 const QHash<Property, QByteArray> propertyRoleMap() {
34 static const auto map = QHash<Property, QByteArray> {
35 { Property::Rating, QByteArrayLiteral("rating") },
36 { Property::Comment, QByteArrayLiteral("comment") },
37 { Property::Title, QByteArrayLiteral("title") },
38 { Property::Author, QByteArrayLiteral("author") },
39 { Property::WordCount, QByteArrayLiteral("wordCount") },
40 { Property::LineCount, QByteArrayLiteral("lineCount") },
41 { Property::Width, QByteArrayLiteral("width") },
42 { Property::Height, QByteArrayLiteral("height") },
43 { Property::ImageDateTime, QByteArrayLiteral("imageDateTime") },
44 { Property::ImageOrientation, QByteArrayLiteral("orientation") },
45 { Property::Artist, QByteArrayLiteral("artist") },
46 { Property::Genre, QByteArrayLiteral("genre") },
47 { Property::Album, QByteArrayLiteral("album") },
48 { Property::Duration, QByteArrayLiteral("duration") },
49 { Property::BitRate, QByteArrayLiteral("bitrate") },
50 { Property::AspectRatio, QByteArrayLiteral("aspectRatio") },
51 { Property::FrameRate, QByteArrayLiteral("frameRate") },
52 { Property::ReleaseYear, QByteArrayLiteral("releaseYear") },
53 { Property::TrackNumber, QByteArrayLiteral("track") }
54 };
55 return map;
56 }
57 }
58
59 struct KBalooRolesProviderSingleton
60 {
61 KBalooRolesProvider instance;
62 };
63 Q_GLOBAL_STATIC(KBalooRolesProviderSingleton, s_balooRolesProvider)
64
65
66 KBalooRolesProvider& KBalooRolesProvider::instance()
67 {
68 return s_balooRolesProvider->instance;
69 }
70
71 KBalooRolesProvider::~KBalooRolesProvider()
72 {
73 }
74
75 QSet<QByteArray> KBalooRolesProvider::roles() const
76 {
77 return m_roles;
78 }
79
80 QHash<QByteArray, QVariant> KBalooRolesProvider::roleValues(const Baloo::File& file,
81 const QSet<QByteArray>& roles) const
82 {
83 QHash<QByteArray, QVariant> values;
84
85 using entry = std::pair<const KFileMetaData::Property::Property&, const QVariant&>;
86
87 const auto& propMap = file.properties();
88 auto rangeBegin = propMap.constKeyValueBegin();
89
90 while (rangeBegin != propMap.constKeyValueEnd()) {
91 auto key = (*rangeBegin).first;
92
93 auto rangeEnd = std::find_if(rangeBegin, propMap.constKeyValueEnd(),
94 [key](const entry& e) { return e.first != key; });
95
96 const QByteArray role = propertyRoleMap().value(key);
97 if (role.isEmpty() || !roles.contains(role)) {
98 rangeBegin = rangeEnd;
99 continue;
100 }
101
102 const KFileMetaData::PropertyInfo propertyInfo(key);
103 auto distance = std::distance(rangeBegin, rangeEnd);
104 if (distance > 1) {
105 QVariantList list;
106 list.reserve(static_cast<int>(distance));
107 std::for_each(rangeBegin, rangeEnd, [&list](const entry& s) { list.append(s.second); });
108 values.insert(role, propertyInfo.formatAsDisplayString(list));
109 } else {
110 if (propertyInfo.valueType() == QVariant::DateTime) {
111 // Let dolphin format later Dates
112 values.insert(role, (*rangeBegin).second);
113 } else {
114 values.insert(role, propertyInfo.formatAsDisplayString((*rangeBegin).second));
115 }
116 }
117 rangeBegin = rangeEnd;
118 }
119
120 if (roles.contains("dimensions")) {
121 bool widthOk = false;
122 bool heightOk = false;
123
124 const int width = propMap.value(KFileMetaData::Property::Width).toInt(&widthOk);
125 const int height = propMap.value(KFileMetaData::Property::Height).toInt(&heightOk);
126
127 if (widthOk && heightOk && width >= 0 && height >= 0) {
128 values.insert("dimensions", QSize(width, height));
129 }
130 }
131
132 KFileMetaData::UserMetaData::Attributes attributes;
133 if (roles.contains("tags")) {
134 attributes |= KFileMetaData::UserMetaData::Tags;
135 }
136 if (roles.contains("rating")) {
137 attributes |= KFileMetaData::UserMetaData::Rating;
138 }
139 if (roles.contains("comment")) {
140 attributes |= KFileMetaData::UserMetaData::Comment;
141 }
142 if (roles.contains("originUrl")) {
143 attributes |= KFileMetaData::UserMetaData::OriginUrl;
144 }
145
146 if (attributes == KFileMetaData::UserMetaData::None) {
147 return values;
148 }
149
150 KFileMetaData::UserMetaData md(file.path());
151 attributes = md.queryAttributes(attributes);
152
153 if (attributes & KFileMetaData::UserMetaData::Tags) {
154 values.insert("tags", tagsFromValues(md.tags()));
155 }
156 if (attributes & KFileMetaData::UserMetaData::Rating) {
157 values.insert("rating", QString::number(md.rating()));
158 }
159 if (attributes & KFileMetaData::UserMetaData::Comment) {
160 values.insert("comment", md.userComment());
161 }
162 if (attributes & KFileMetaData::UserMetaData::OriginUrl) {
163 values.insert("originUrl", md.originUrl());
164 }
165
166 return values;
167 }
168
169 KBalooRolesProvider::KBalooRolesProvider()
170 {
171 // Display roles filled from Baloo property cache
172 for (const auto& role : propertyRoleMap()) {
173 m_roles.insert(role);
174 }
175 m_roles.insert("dimensions");
176
177 // Display roles provided by UserMetaData
178 m_roles.insert(QByteArrayLiteral("tags"));
179 m_roles.insert(QByteArrayLiteral("rating"));
180 m_roles.insert(QByteArrayLiteral("comment"));
181 m_roles.insert(QByteArrayLiteral("originUrl"));
182 }
183