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