• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KIO

  • kio
  • kfile
kfilemetadatawidget.cpp
Go to the documentation of this file.
1/*****************************************************************************
2 * Copyright (C) 2008-2010 by Sebastian Trueg <trueg@kde.org> *
3 * Copyright (C) 2009-2010 by Peter Penz <peter.penz@gmx.at> *
4 * *
5 * This library is free software; you can redistribute it and/or *
6 * modify it under the terms of the GNU Library General Public *
7 * License as published by the Free Software Foundation; either *
8 * version 2 of the License, or (at your option) any later version. *
9 * *
10 * This library is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
13 * Library General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU Library General Public License *
16 * along with this library; see the file COPYING.LIB. If not, write to *
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
18 * Boston, MA 02110-1301, USA. *
19 *****************************************************************************/
20
21#include "kfilemetadatawidget.h"
22
23#include <kconfig.h>
24#include <kconfiggroup.h>
25#include <kfileitem.h>
26#include <klocale.h>
27
28#include <QGridLayout>
29#include <QLabel>
30#include <QList>
31#include <QSet>
32#include <QString>
33#include <QTimer>
34
35#include <config-kio.h>
36#ifndef KIO_NO_NEPOMUK
37 #define DISABLE_NEPOMUK_LEGACY
38
39 #include <property.h>
40 #include <tag.h>
41
42 #include <QSpacerItem>
43
44 #include "kfilemetadataprovider_p.h"
45#endif
46
47class KFileMetaDataWidget::Private
48{
49public:
50 struct Row
51 {
52 QLabel* label;
53 QWidget* value;
54 };
55
56 Private(KFileMetaDataWidget* parent);
57 ~Private();
58
64 void initMetaInfoSettings();
65
71 void updateFileItemRowsVisibility();
72
73 void deleteRows();
74
75 void slotLoadingFinished();
76 void slotLinkActivated(const QString& link);
77 void slotDataChangeStarted();
78 void slotDataChangeFinished();
79
80#ifndef KIO_NO_NEPOMUK
81 QList<KUrl> sortedKeys(const QHash<KUrl, Nepomuk::Variant>& data) const;
82
87 bool hasNepomukUris() const;
88#endif
89
90 QList<Row> m_rows;
91#ifndef KIO_NO_NEPOMUK
92 KFileMetaDataProvider* m_provider;
93#endif
94 QGridLayout* m_gridLayout;
95
96private:
97 KFileMetaDataWidget* const q;
98};
99
100KFileMetaDataWidget::Private::Private(KFileMetaDataWidget* parent) :
101 m_rows(),
102#ifndef KIO_NO_NEPOMUK
103 m_provider(0),
104#endif
105 m_gridLayout(0),
106 q(parent)
107{
108 initMetaInfoSettings();
109
110#ifndef KIO_NO_NEPOMUK
111 // TODO: If KFileMetaDataProvider might get a public class in future KDE releases,
112 // the following code should be moved into KFileMetaDataWidget::setModel():
113 m_provider = new KFileMetaDataProvider(q);
114 connect(m_provider, SIGNAL(loadingFinished()), q, SLOT(slotLoadingFinished()));
115 connect(m_provider, SIGNAL(urlActivated(KUrl)), q, SIGNAL(urlActivated(KUrl)));
116#endif
117}
118
119KFileMetaDataWidget::Private::~Private()
120{
121}
122
123void KFileMetaDataWidget::Private::initMetaInfoSettings()
124{
125 const int currentVersion = 3; // increase version, if the blacklist of disabled
126 // properties should be updated
127
128 KConfig config("kmetainformationrc", KConfig::NoGlobals);
129 if (config.group("Misc").readEntry("version", 0) < currentVersion) {
130 // The resource file is read the first time. Assure
131 // that some meta information is disabled per default.
132
133 // clear old info
134 config.deleteGroup("Show");
135 KConfigGroup settings = config.group("Show");
136
137 static const char* const disabledProperties[] = {
138 "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#comment",
139 "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentSize",
140 "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#depends",
141 "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#isPartOf",
142 "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#lastModified",
143 "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#mimeType",
144 "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#plainTextContent",
145 "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#url",
146 "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#averageBitrate",
147 "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#channels",
148 "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#fileName",
149 "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#apertureValue",
150 "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#exposureBiasValue",
151 "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#exposureTime",
152 "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#flash",
153 "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#focalLength",
154 "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#focalLengthIn35mmFilm",
155 "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#isoSpeedRatings",
156 "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#make",
157 "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#meteringMode",
158 "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#model",
159 "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#orientation",
160 "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#whiteBalance",
161 "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#description",
162 "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#hasTag",
163 "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#lastModified",
164 "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#numericRating",
165 "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
166 "kfileitem#owner",
167 "kfileitem#permissions",
168 0 // mandatory last entry
169 };
170
171 for (int i = 0; disabledProperties[i] != 0; ++i) {
172 settings.writeEntry(disabledProperties[i], false);
173 }
174
175 // mark the group as initialized
176 config.group("Misc").writeEntry("version", currentVersion);
177 }
178}
179
180void KFileMetaDataWidget::Private::deleteRows()
181{
182 foreach (const Row& row, m_rows) {
183 delete row.label;
184 delete row.value;
185 }
186 m_rows.clear();
187}
188
189void KFileMetaDataWidget::Private::slotLoadingFinished()
190{
191#ifndef KIO_NO_NEPOMUK
192 deleteRows();
193
194 if (!hasNepomukUris()) {
195 q->updateGeometry();
196 emit q->metaDataRequestFinished(m_provider->items());
197 return;
198 }
199
200 if (m_gridLayout == 0) {
201 m_gridLayout = new QGridLayout(q);
202 m_gridLayout->setMargin(0);
203 m_gridLayout->setSpacing(q->fontMetrics().height() / 4);
204 }
205
206 QHash<KUrl, Nepomuk::Variant> data = m_provider->data();
207
208 // Remove all items, that are marked as hidden in kmetainformationrc
209 KConfig config("kmetainformationrc", KConfig::NoGlobals);
210 KConfigGroup settings = config.group("Show");
211 QHash<KUrl, Nepomuk::Variant>::iterator it = data.begin();
212 while (it != data.end()) {
213 const QString uriString = it.key().url();
214 if (!settings.readEntry(uriString, true) ||
215 !Nepomuk::Types::Property(it.key()).userVisible()) {
216 it = data.erase(it);
217 } else {
218 ++it;
219 }
220 }
221
222 // Iterate through all remaining items embed the label
223 // and the value as new row in the widget
224 int rowIndex = 0;
225 const QList<KUrl> keys = sortedKeys(data);
226 foreach (const KUrl& key, keys) {
227 const Nepomuk::Variant value = data[key];
228 QString itemLabel = m_provider->label(key);
229 itemLabel.append(QLatin1Char(':'));
230
231 // Create label
232 QLabel* label = new QLabel(itemLabel, q);
233 label->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
234 label->setForegroundRole(q->foregroundRole());
235 label->setFont(q->font());
236 label->setWordWrap(true);
237 label->setAlignment(Qt::AlignTop | Qt::AlignRight);
238
239 // Create value-widget
240 QWidget* valueWidget = m_provider->createValueWidget(key, value, q);
241
242 // Add the label and value-widget to grid layout
243 m_gridLayout->addWidget(label, rowIndex, 0, Qt::AlignRight);
244 const int spacerWidth = QFontMetrics(q->font()).size(Qt::TextSingleLine, " ").width();
245 m_gridLayout->addItem(new QSpacerItem(spacerWidth, 1), rowIndex, 1);
246 m_gridLayout->addWidget(valueWidget, rowIndex, 2, Qt::AlignLeft);
247
248 // Remember the label and value-widget as row
249 Row row;
250 row.label = label;
251 row.value = valueWidget;
252 m_rows.append(row);
253
254 ++rowIndex;
255 }
256#endif
257
258 q->updateGeometry();
259#ifndef KIO_NO_NEPOMUK
260 emit q->metaDataRequestFinished(m_provider->items());
261#endif
262}
263
264void KFileMetaDataWidget::Private::slotLinkActivated(const QString& link)
265{
266 const KUrl url(link);
267 if (url.isValid()) {
268 emit q->urlActivated(url);
269 }
270}
271
272void KFileMetaDataWidget::Private::slotDataChangeStarted()
273{
274 q->setEnabled(false);
275}
276
277void KFileMetaDataWidget::Private::slotDataChangeFinished()
278{
279 q->setEnabled(true);
280}
281
282#ifndef KIO_NO_NEPOMUK
283QList<KUrl> KFileMetaDataWidget::Private::sortedKeys(const QHash<KUrl, Nepomuk::Variant>& data) const
284{
285 // Create a map, where the translated label prefixed with the
286 // sort priority acts as key. The data of each entry is the URI
287 // of the data. By this the all URIs are sorted by the sort priority
288 // and sub sorted by the translated labels.
289 QMap<QString, KUrl> map;
290 QHash<KUrl, Nepomuk::Variant>::const_iterator hashIt = data.constBegin();
291 while (hashIt != data.constEnd()) {
292 const KUrl uri = hashIt.key();
293
294 QString key = m_provider->group(uri);
295 key += m_provider->label(uri);
296
297 map.insert(key, uri);
298 ++hashIt;
299 }
300
301 // Apply the URIs from the map to the list that will get returned.
302 // The list will then be alphabetically ordered by the translated labels of the URIs.
303 QList<KUrl> list;
304 QMap<QString, KUrl>::const_iterator mapIt = map.constBegin();
305 while (mapIt != map.constEnd()) {
306 list.append(mapIt.value());
307 ++mapIt;
308 }
309
310 return list;
311}
312
313bool KFileMetaDataWidget::Private::hasNepomukUris() const
314{
315 foreach (const KFileItem& fileItem, m_provider->items()) {
316 if (fileItem.nepomukUri().isValid()) {
317 return true;
318 }
319 }
320 return false;
321}
322#endif
323
324KFileMetaDataWidget::KFileMetaDataWidget(QWidget* parent) :
325 QWidget(parent),
326 d(new Private(this))
327{
328}
329
330KFileMetaDataWidget::~KFileMetaDataWidget()
331{
332 delete d;
333}
334
335void KFileMetaDataWidget::setItems(const KFileItemList& items)
336{
337#ifndef KIO_NO_NEPOMUK
338 d->m_provider->setItems(items);
339#endif
340}
341
342KFileItemList KFileMetaDataWidget::items() const
343{
344#ifndef KIO_NO_NEPOMUK
345 return d->m_provider->items();
346#else
347 return KFileItemList();
348#endif
349}
350
351void KFileMetaDataWidget::setReadOnly(bool readOnly)
352{
353#ifndef KIO_NO_NEPOMUK
354 d->m_provider->setReadOnly(readOnly);
355#endif
356}
357
358bool KFileMetaDataWidget::isReadOnly() const
359{
360#ifndef KIO_NO_NEPOMUK
361 return d->m_provider->isReadOnly();
362#else
363 return true;
364#endif
365}
366
367QSize KFileMetaDataWidget::sizeHint() const
368{
369 if (d->m_gridLayout == 0) {
370 return QWidget::sizeHint();
371 }
372
373 // Calculate the required width for the labels and values
374 int leftWidthMax = 0;
375 int rightWidthMax = 0;
376 int rightWidthAverage = 0;
377 foreach (const Private::Row& row, d->m_rows) {
378 const QWidget* valueWidget = row.value;
379 const int rightWidth = valueWidget->sizeHint().width();
380 rightWidthAverage += rightWidth;
381 if (rightWidth > rightWidthMax) {
382 rightWidthMax = rightWidth;
383 }
384
385 const int leftWidth = row.label->sizeHint().width();
386 if (leftWidth > leftWidthMax) {
387 leftWidthMax = leftWidth;
388 }
389 }
390
391 // Some value widgets might return a very huge width for the size hint.
392 // Limit the maximum width to the double width of the overall average
393 // to assure a less messed layout.
394 if (d->m_rows.count() > 1) {
395 rightWidthAverage /= d->m_rows.count();
396 if (rightWidthMax > rightWidthAverage * 2) {
397 rightWidthMax = rightWidthAverage * 2;
398 }
399 }
400
401 // Based on the available width calculate the required height
402 int height = d->m_gridLayout->margin() * 2 + d->m_gridLayout->spacing() * (d->m_rows.count() - 1);
403 foreach (const Private::Row& row, d->m_rows) {
404 const QWidget* valueWidget = row.value;
405 const int rowHeight = qMax(row.label->heightForWidth(leftWidthMax),
406 valueWidget->heightForWidth(rightWidthMax));
407 height += rowHeight;
408 }
409
410 const int width = d->m_gridLayout->margin() * 2 + leftWidthMax +
411 d->m_gridLayout->spacing() + rightWidthMax;
412
413 return QSize(width, height);
414}
415
416bool KFileMetaDataWidget::event(QEvent* event)
417{
418 return QWidget::event(event);
419}
420
421#include "kfilemetadatawidget.moc"
KConfigGroup
KConfigGroup::writeEntry
void writeEntry(const char *key, const char *value, WriteConfigFlags pFlags=Normal)
KConfigGroup::readEntry
QString readEntry(const char *key, const char *aDefault=0) const
KConfig
KConfig::NoGlobals
NoGlobals
KFileItemList
List of KFileItems, which adds a few helper methods to QList<KFileItem>.
Definition: kfileitem.h:675
KFileItem
A KFileItem is a generic class to handle a file, local or remote.
Definition: kfileitem.h:46
KFileItem::nepomukUri
KUrl nepomukUri() const
Returns the resource URI to be used for Nepomuk annotations.
Definition: kfileitem.cpp:1616
KFileMetaDataProvider
Provides the data for the KMetaDataWidget.
Definition: kfilemetadataprovider_p.h:51
KFileMetaDataWidget
Shows the meta data of one or more file items.
Definition: kfilemetadatawidget.h:47
KFileMetaDataWidget::isReadOnly
bool isReadOnly() const
Definition: kfilemetadatawidget.cpp:358
KFileMetaDataWidget::setItems
void setItems(const KFileItemList &items)
Sets the items for which the meta data should be shown.
Definition: kfilemetadatawidget.cpp:335
KFileMetaDataWidget::items
KFileItemList items() const
Definition: kfilemetadatawidget.cpp:342
KFileMetaDataWidget::~KFileMetaDataWidget
virtual ~KFileMetaDataWidget()
Definition: kfilemetadatawidget.cpp:330
KFileMetaDataWidget::sizeHint
virtual QSize sizeHint() const
Definition: kfilemetadatawidget.cpp:367
KFileMetaDataWidget::KFileMetaDataWidget
KFileMetaDataWidget(QWidget *parent=0)
Definition: kfilemetadatawidget.cpp:324
KFileMetaDataWidget::setReadOnly
void setReadOnly(bool readOnly)
If set to true, data such as the comment, tag or rating cannot be changed by the user.
Definition: kfilemetadatawidget.cpp:351
KFileMetaDataWidget::event
virtual bool event(QEvent *event)
Definition: kfilemetadatawidget.cpp:416
KUrl
QHash
QLabel
QList
QMap
QWidget
kconfig.h
kconfiggroup.h
kfileitem.h
kfilemetadataprovider_p.h
kfilemetadatawidget.h
klocale.h
config
KSharedConfigPtr config()
KRecentDirs::list
QStringList list(const QString &fileClass)
Returns a list of directories associated with this file-class.
Definition: krecentdirs.cpp:60
label
QString label(StandardShortcut id)
Row
Row
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal