]> cloud.milkyroute.net Git - dolphin.git/blob - src/panels/information/metadatawidget.cpp
Fixes double inserting of terms, interestingly this problem did not existed before...
[dolphin.git] / src / panels / information / metadatawidget.cpp
1 /***************************************************************************
2 * Copyright (C) 2008 by Sebastian Trueg <trueg@kde.org> *
3 * Copyright (C) 2009 by Peter Penz <peter.penz@gmx.at> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program 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 *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
19 ***************************************************************************/
20
21 #include "metadatawidget.h"
22
23 #include <kconfig.h>
24 #include <kconfiggroup.h>
25 #include <kfileitem.h>
26 #include <kglobalsettings.h>
27 #include <klocale.h>
28
29 #include <QFontMetrics>
30 #include <QGridLayout>
31 #include <QLabel>
32 #include <QList>
33 #include <QString>
34
35 #include <config-nepomuk.h>
36 #ifdef HAVE_NEPOMUK
37 #define DISABLE_NEPOMUK_LEGACY
38
39 #include "commentwidget_p.h"
40 #include "nepomukmassupdatejob_p.h"
41 #include "taggingwidget_p.h"
42
43 #include <Nepomuk/KRatingWidget>
44 #include <Nepomuk/Resource>
45 #include <Nepomuk/ResourceManager>
46 #include <Nepomuk/Types/Property>
47 #include <Nepomuk/Variant>
48
49 #include <QMutex>
50 #include <QSpacerItem>
51 #include <QThread>
52 #endif
53
54 #include <kdebug.h>
55
56 class MetaDataWidget::Private
57 {
58 public:
59 struct Row
60 {
61 QLabel* label;
62 QWidget* infoWidget;
63 };
64
65 Private(MetaDataWidget* parent);
66 ~Private();
67
68 void addRow(QLabel* label, QWidget* infoWidget);
69 void removeMetaInfoRows();
70 void setRowVisible(QWidget* infoWidget, bool visible);
71
72 /**
73 * Initializes the configuration file "kmetainformationrc"
74 * with proper default settings for the first start in
75 * an uninitialized environment.
76 */
77 void initMetaInfoSettings();
78
79 /**
80 * Parses the configuration file "kmetainformationrc" and
81 * updates the visibility of all rows.
82 */
83 void updateRowsVisibility();
84
85 void slotLoadingFinished();
86 void slotRatingChanged(unsigned int rating);
87 void slotTagsChanged(const QList<Nepomuk::Tag>& tags);
88 void slotCommentChanged(const QString& comment);
89 void slotMetaDataUpdateDone();
90
91 /**
92 * Disables the metadata widget and starts the job that
93 * changes the meta data asynchronously. After the job
94 * has been finished, the metadata widget gets enabled again.
95 */
96 void startChangeDataJob(KJob* job);
97
98 bool m_isSizeVisible;
99 MetaDataTypes m_hiddenData;
100 QList<KFileItem> m_fileItems;
101 QList<Row> m_rows;
102
103 QGridLayout* m_gridLayout;
104
105 QLabel* m_typeInfo;
106 QLabel* m_sizeLabel;
107 QLabel* m_sizeInfo;
108 QLabel* m_modifiedInfo;
109 QLabel* m_ownerInfo;
110 QLabel* m_permissionsInfo;
111
112 #ifdef HAVE_NEPOMUK
113 KRatingWidget* m_ratingWidget;
114 TaggingWidget* m_taggingWidget;
115 CommentWidget* m_commentWidget;
116
117 // shared data between the GUI-thread and
118 // the loader-thread (see LoadFilesThread):
119 QMutex m_mutex;
120 struct SharedData
121 {
122 int rating;
123 QString comment;
124 QList<Nepomuk::Tag> tags;
125 QList<QString> metaInfoLabels;
126 QList<QString> metaInfoValues;
127 QMap<KUrl, Nepomuk::Resource> files;
128 } m_sharedData;
129
130 /**
131 * Loads the meta data of files and writes
132 * the result into a shared data pool that
133 * can be used by the widgets in the GUI thread.
134 */
135 class LoadFilesThread : public QThread
136 {
137 public:
138 LoadFilesThread(SharedData* m_sharedData, QMutex* m_mutex);
139 virtual ~LoadFilesThread();
140 void loadFiles(const KUrl::List& urls);
141 virtual void run();
142
143 private:
144 /**
145 * Assures that the settings for the meta information
146 * are initialized with proper default values.
147 */
148 void initMetaInfoSettings(KConfigGroup& group);
149
150 /**
151 * Temporary helper method for KDE 4.3 as we currently don't get
152 * translated labels for Nepmok literals: Replaces camelcase labels
153 * like "fileLocation" by "File Location:".
154 */
155 QString tunedLabel(const QString& label) const;
156
157 private:
158 SharedData* m_sharedData;
159 QMutex* m_mutex;
160 KUrl::List m_urls;
161 bool m_canceled;
162 };
163
164 LoadFilesThread* m_loadFilesThread;
165 #endif
166
167 private:
168 MetaDataWidget* const q;
169 };
170
171 MetaDataWidget::Private::Private(MetaDataWidget* parent) :
172 m_isSizeVisible(true),
173 m_hiddenData(None),
174 m_fileItems(),
175 m_rows(),
176 m_gridLayout(0),
177 m_typeInfo(0),
178 m_sizeLabel(0),
179 m_sizeInfo(0),
180 m_modifiedInfo(0),
181 m_ownerInfo(0),
182 m_permissionsInfo(0),
183 #ifdef HAVE_NEPOMUK
184 m_ratingWidget(0),
185 m_taggingWidget(0),
186 m_commentWidget(0),
187 m_loadFilesThread(0),
188 #endif
189 q(parent)
190 {
191 m_gridLayout = new QGridLayout(parent);
192 m_gridLayout->setMargin(0);
193
194 m_typeInfo = new QLabel(parent);
195 m_sizeLabel = new QLabel(parent);
196 m_sizeInfo = new QLabel(parent);
197 m_modifiedInfo = new QLabel(parent);
198 m_ownerInfo = new QLabel(parent);
199 m_permissionsInfo = new QLabel(parent);
200
201 addRow(new QLabel(i18nc("@label", "Type:"), parent), m_typeInfo);
202 addRow(m_sizeLabel, m_sizeInfo);
203 addRow(new QLabel(i18nc("@label", "Modified:"), parent), m_modifiedInfo);
204 addRow(new QLabel(i18nc("@label", "Owner:"), parent), m_ownerInfo);
205 addRow(new QLabel(i18nc("@label", "Permissions:"), parent), m_permissionsInfo);
206
207 #ifdef HAVE_NEPOMUK
208 if (Nepomuk::ResourceManager::instance()->init() == 0) {
209 const QFontMetrics fontMetrics(KGlobalSettings::smallestReadableFont());
210 m_ratingWidget = new KRatingWidget(parent);
211 m_ratingWidget->setFixedHeight(fontMetrics.height());
212 connect(m_ratingWidget, SIGNAL(ratingChanged(unsigned int)),
213 q, SLOT(slotRatingChanged(unsigned int)));
214
215 m_taggingWidget = new TaggingWidget(parent);
216 connect(m_taggingWidget, SIGNAL(tagsChanged(const QList<Nepomuk::Tag>&)),
217 q, SLOT(slotTagsChanged(const QList<Nepomuk::Tag>&)));
218
219 m_commentWidget = new CommentWidget(parent);
220 connect(m_commentWidget, SIGNAL(commentChanged(const QString&)),
221 q, SLOT(slotCommentChanged(const QString&)));
222
223 addRow(new QLabel(i18nc("@label", "Rating:"), parent), m_ratingWidget);
224 addRow(new QLabel(i18nc("@label", "Tags:"), parent), m_taggingWidget);
225 addRow(new QLabel(i18nc("@label", "Comment:"), parent), m_commentWidget);
226
227 m_loadFilesThread = new LoadFilesThread(&m_sharedData, &m_mutex);
228 connect(m_loadFilesThread, SIGNAL(finished()), q, SLOT(slotLoadingFinished()));
229 }
230
231 m_sharedData.rating = 0;
232 #endif
233
234 initMetaInfoSettings();
235 updateRowsVisibility();
236 }
237
238 MetaDataWidget::Private::~Private()
239 {
240 #ifdef HAVE_NEPOMUK
241 delete m_loadFilesThread;
242 #endif
243 }
244
245 void MetaDataWidget::Private::addRow(QLabel* label, QWidget* infoWidget)
246 {
247 Row row;
248 row.label = label;
249 row.infoWidget = infoWidget;
250 m_rows.append(row);
251
252 const QFont smallFont = KGlobalSettings::smallestReadableFont();
253 // use a brighter color for the label and a small font size
254 QPalette palette = label->palette();
255 QColor textColor = palette.color(QPalette::Text);
256 textColor.setAlpha(128);
257 palette.setColor(QPalette::WindowText, textColor);
258 label->setPalette(palette);
259 label->setFont(smallFont);
260 label->setWordWrap(true);
261 label->setAlignment(Qt::AlignTop | Qt::AlignRight);
262
263 QLabel* infoLabel = qobject_cast<QLabel*>(infoWidget);
264 if (infoLabel != 0) {
265 infoLabel->setFont(smallFont);
266 infoLabel->setWordWrap(true);
267 infoLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
268 }
269
270 // add the row to grid layout
271 const int rowIndex = m_rows.count();
272 m_gridLayout->addWidget(label, rowIndex, 0, Qt::AlignRight);
273 const int spacerWidth = QFontMetrics(smallFont).size(Qt::TextSingleLine, " ").width();
274 m_gridLayout->addItem(new QSpacerItem(spacerWidth, 1), rowIndex, 1);
275 m_gridLayout->addWidget(infoWidget, rowIndex, 2, Qt::AlignLeft);
276 }
277
278 void MetaDataWidget::Private::setRowVisible(QWidget* infoWidget, bool visible)
279 {
280 foreach (const Row& row, m_rows) {
281 if (row.infoWidget == infoWidget) {
282 row.label->setVisible(visible);
283 row.infoWidget->setVisible(visible);
284 return;
285 }
286 }
287 }
288
289
290 void MetaDataWidget::Private::initMetaInfoSettings()
291 {
292 KConfig config("kmetainformationrc", KConfig::NoGlobals);
293 KConfigGroup settings = config.group("Show");
294 if (!settings.readEntry("initialized", false)) {
295 // The resource file is read the first time. Assure
296 // that some meta information is disabled per default.
297
298 static const char* disabledProperties[] = {
299 "asText", "contentSize", "created", "depth", "description", "fileExtension",
300 "fileName", "fileSize", "hasTag", "isPartOf", "lastModified", "mimeType", "name",
301 "numericRating", "parentUrl", "permissions", "plainTextContent", "owner",
302 "sourceModified", "url",
303 0 // mandatory last entry
304 };
305
306 int i = 0;
307 while (disabledProperties[i] != 0) {
308 settings.writeEntry(disabledProperties[i], false);
309 ++i;
310 }
311
312 // mark the group as initialized
313 settings.writeEntry("initialized", true);
314 }
315 }
316
317 void MetaDataWidget::Private::updateRowsVisibility()
318 {
319 KConfig config("kmetainformationrc", KConfig::NoGlobals);
320 KConfigGroup settings = config.group("Show");
321
322 setRowVisible(m_typeInfo,
323 !(m_hiddenData & MetaDataWidget::TypeData) &&
324 settings.readEntry("type", true));
325
326 // Cache in m_isSizeVisible whether the size should be shown. This
327 // is necessary as the size is temporary hidden when the target
328 // file item is a directory.
329 m_isSizeVisible = !(m_hiddenData & MetaDataWidget::SizeData) &&
330 settings.readEntry("size", true);
331 setRowVisible(m_sizeInfo, m_isSizeVisible);
332
333 setRowVisible(m_modifiedInfo,
334 !(m_hiddenData & MetaDataWidget::ModifiedData) &&
335 settings.readEntry("modified", true));
336
337 setRowVisible(m_ownerInfo,
338 !(m_hiddenData & MetaDataWidget::OwnerData) &&
339 settings.readEntry("owner", true));
340
341 setRowVisible(m_permissionsInfo,
342 !(m_hiddenData & MetaDataWidget::PermissionsData) &&
343 settings.readEntry("permissions", true));
344
345 #ifdef HAVE_NEPOMUK
346 if (Nepomuk::ResourceManager::instance()->init() == 0) {
347 setRowVisible(m_ratingWidget,
348 !(m_hiddenData & MetaDataWidget::RatingData) &&
349 settings.readEntry("rating", true));
350
351 setRowVisible(m_taggingWidget,
352 !(m_hiddenData & MetaDataWidget::TagsData) &&
353 settings.readEntry("tags", true));
354
355 setRowVisible(m_commentWidget,
356 !(m_hiddenData & MetaDataWidget::CommentData) &&
357 settings.readEntry("comment", true));
358 }
359 #endif
360 }
361
362 void MetaDataWidget::Private::slotLoadingFinished()
363 {
364 #ifdef HAVE_NEPOMUK
365 QMutexLocker locker(&m_mutex);
366 m_ratingWidget->setRating(m_sharedData.rating);
367 m_commentWidget->setText(m_sharedData.comment);
368 m_taggingWidget->setTags(m_sharedData.tags);
369
370 // Show the remaining meta information as text. The number
371 // of required rows may very. Existing rows are reused to
372 // prevent flickering.
373 int index = 8; // TODO: don't hardcode this value here
374 const int rowCount = m_rows.count();
375 Q_ASSERT(rowCount >= index);
376
377 Q_ASSERT(m_sharedData.metaInfoLabels.count() == m_sharedData.metaInfoValues.count());
378 const int metaInfoCount = m_sharedData.metaInfoLabels.count();
379 for (int i = 0; i < metaInfoCount; ++i) {
380 if (index < rowCount) {
381 // adjust texts of the current row
382 m_rows[index].label->setText(m_sharedData.metaInfoLabels[i]);
383 QLabel* infoValueLabel = qobject_cast<QLabel*>(m_rows[index].infoWidget);
384 Q_ASSERT(infoValueLabel != 0);
385 infoValueLabel->setText(m_sharedData.metaInfoValues[i]);
386 } else {
387 // create new row
388 QLabel* infoLabel = new QLabel(m_sharedData.metaInfoLabels[i], q);
389 QLabel* infoValue = new QLabel(m_sharedData.metaInfoValues[i], q);
390 addRow(infoLabel, infoValue);
391 }
392 ++index;
393 }
394 if (metaInfoCount > 0) {
395 --index;
396 }
397
398 // remove rows that are not needed anymore
399 for (int i = rowCount - 1; i > index; --i) {
400 delete m_rows[i].label;
401 delete m_rows[i].infoWidget;
402 m_rows.pop_back();
403 }
404
405 emit q->loadingFinished();
406 #endif
407 }
408
409 void MetaDataWidget::Private::slotRatingChanged(unsigned int rating)
410 {
411 #ifdef HAVE_NEPOMUK
412 QMutexLocker locker(&m_mutex);
413 Nepomuk::MassUpdateJob* job =
414 Nepomuk::MassUpdateJob::rateResources(m_sharedData.files.values(), rating);
415 locker.unlock();
416 startChangeDataJob(job);
417 #endif
418 emit q->ratingChanged(rating);
419 }
420
421 void MetaDataWidget::Private::slotTagsChanged(const QList<Nepomuk::Tag>& tags)
422 {
423 #ifdef HAVE_NEPOMUK
424 m_taggingWidget->setTags(tags);
425
426 QMutexLocker locker(&m_mutex);
427 Nepomuk::MassUpdateJob* job =
428 Nepomuk::MassUpdateJob::tagResources(m_sharedData.files.values(), tags);
429 locker.unlock();
430 startChangeDataJob(job);
431 #endif
432 emit q->tagsChanged(tags);
433 }
434
435 void MetaDataWidget::Private::slotCommentChanged(const QString& comment)
436 {
437 #ifdef HAVE_NEPOMUK
438 QMutexLocker locker(&m_mutex);
439 Nepomuk::MassUpdateJob* job =
440 Nepomuk::MassUpdateJob::commentResources(m_sharedData.files.values(), comment);
441 locker.unlock();
442 startChangeDataJob(job);
443 #endif
444 emit q->commentChanged(comment);
445 }
446
447 void MetaDataWidget::Private::slotMetaDataUpdateDone()
448 {
449 q->setEnabled(true);
450 }
451
452 void MetaDataWidget::Private::startChangeDataJob(KJob* job)
453 {
454 connect(job, SIGNAL(result(KJob*)),
455 q, SLOT(slotMetaDataUpdateDone()));
456 q->setEnabled(false); // no updates during execution
457 job->start();
458 }
459
460 #ifdef HAVE_NEPOMUK
461 MetaDataWidget::Private::LoadFilesThread::LoadFilesThread(
462 MetaDataWidget::Private::SharedData* m_sharedData,
463 QMutex* m_mutex) :
464 m_sharedData(m_sharedData),
465 m_mutex(m_mutex),
466 m_urls(),
467 m_canceled(false)
468 {
469 }
470
471 MetaDataWidget::Private::LoadFilesThread::~LoadFilesThread()
472 {
473 // This thread may very well be deleted during execution. We need
474 // to protect it from crashes here.
475 m_canceled = true;
476 wait();
477 }
478
479 void MetaDataWidget::Private::LoadFilesThread::loadFiles(const KUrl::List& urls)
480 {
481 QMutexLocker locker(m_mutex);
482 m_urls = urls;
483 m_canceled = false;
484 start();
485 }
486
487 void MetaDataWidget::Private::LoadFilesThread::run()
488 {
489 QMutexLocker locker(m_mutex);
490 const KUrl::List urls = m_urls;
491 locker.unlock();
492
493 KConfig config("kmetainformationrc", KConfig::NoGlobals);
494 KConfigGroup settings = config.group("Show");
495
496 bool first = true;
497 unsigned int rating = 0;
498 QString comment;
499 QList<Nepomuk::Tag> tags;
500 QList<QString> metaInfoLabels;
501 QList<QString> metaInfoValues;
502 QMap<KUrl, Nepomuk::Resource> files;
503 foreach (const KUrl& url, urls) {
504 if (m_canceled) {
505 return;
506 }
507
508 Nepomuk::Resource file(url);
509 files.insert(url, file);
510
511 if (!first && (rating != file.rating())) {
512 rating = 0; // reset rating
513 } else if (first) {
514 rating = file.rating();
515 }
516
517 if (!first && (comment != file.description())) {
518 comment.clear(); // reset comment
519 } else if (first) {
520 comment = file.description();
521 }
522
523 if (!first && (tags != file.tags())) {
524 tags.clear(); // reset tags
525 } else if (first) {
526 tags = file.tags();
527 }
528
529 if (first && (urls.count() == 1)) {
530 // TODO: show shared meta information instead
531 // of not showing anything on multiple selections
532 QHash<QUrl, Nepomuk::Variant> properties = file.properties();
533 QHash<QUrl, Nepomuk::Variant>::const_iterator it = properties.constBegin();
534 while (it != properties.constEnd()) {
535 Nepomuk::Types::Property prop(it.key());
536 if (settings.readEntry(prop.name(), true)) {
537 // TODO #1: use Nepomuk::formatValue(res, prop) if available
538 // instead of it.value().toString()
539 // TODO #2: using tunedLabel() is a workaround for KDE 4.3 (4.4?) until
540 // we get translated labels
541 metaInfoLabels.append(tunedLabel(prop.label()));
542 metaInfoValues.append(it.value().toString());
543 }
544 ++it;
545 }
546 }
547
548 first = false;
549 }
550
551 locker.relock();
552 m_sharedData->rating = rating;
553 m_sharedData->comment = comment;
554 m_sharedData->tags = tags;
555 m_sharedData->metaInfoLabels = metaInfoLabels;
556 m_sharedData->metaInfoValues = metaInfoValues;
557 m_sharedData->files = files;
558 }
559
560 QString MetaDataWidget::Private::LoadFilesThread::tunedLabel(const QString& label) const
561 {
562 QString tunedLabel;
563 const int labelLength = label.length();
564 if (labelLength > 0) {
565 tunedLabel.reserve(labelLength);
566 tunedLabel = label[0].toUpper();
567 for (int i = 1; i < labelLength; ++i) {
568 if (label[i].isUpper() && !label[i - 1].isSpace() && !label[i - 1].isUpper()) {
569 tunedLabel += ' ';
570 tunedLabel += label[i].toLower();
571 } else {
572 tunedLabel += label[i];
573 }
574 }
575 }
576 return tunedLabel + ':';
577 }
578
579 #endif // HAVE_NEPOMUK
580
581 MetaDataWidget::MetaDataWidget(QWidget* parent) :
582 QWidget(parent),
583 d(new Private(this))
584 {
585 }
586
587 MetaDataWidget::~MetaDataWidget()
588 {
589 delete d;
590 }
591
592 void MetaDataWidget::setItem(const KFileItem& item)
593 {
594 // update values for "type", "size", "modified",
595 // "owner" and "permissions" synchronously
596 d->m_sizeLabel->setText(i18nc("@label", "Size:"));
597 if (item.isDir()) {
598 d->m_typeInfo->setText(i18nc("@label", "Folder"));
599 d->setRowVisible(d->m_sizeInfo, false);
600 } else {
601 d->m_typeInfo->setText(item.mimeComment());
602 d->m_sizeInfo->setText(KIO::convertSize(item.size()));
603 d->setRowVisible(d->m_sizeInfo, d->m_isSizeVisible);
604 }
605 d->m_modifiedInfo->setText(item.timeString());
606 d->m_ownerInfo->setText(item.user());
607 d->m_permissionsInfo->setText(item.permissionsString());
608
609 setItems(KFileItemList() << item);
610 }
611
612 void MetaDataWidget::setItems(const KFileItemList& items)
613 {
614 d->m_fileItems = items;
615
616 if (items.count() > 1) {
617 // calculate the size of all items and show this
618 // information to the user
619 d->m_sizeLabel->setText(i18nc("@label", "Total Size:"));
620 d->setRowVisible(d->m_sizeInfo, d->m_isSizeVisible);
621
622 quint64 totalSize = 0;
623 foreach (const KFileItem& item, items) {
624 if (!item.isDir() && !item.isLink()) {
625 totalSize += item.size();
626 }
627 }
628 d->m_sizeInfo->setText(KIO::convertSize(totalSize));
629 }
630
631 #ifdef HAVE_NEPOMUK
632 if (Nepomuk::ResourceManager::instance()->init() == 0) {
633 QList<KUrl> urls;
634 foreach (const KFileItem& item, items) {
635 const KUrl url = item.nepomukUri();
636 if (url.isValid()) {
637 urls.append(url);
638 }
639 }
640 d->m_loadFilesThread->loadFiles(urls);
641 }
642 #endif
643 }
644
645 void MetaDataWidget::setItem(const KUrl& url)
646 {
647 KFileItem item(KFileItem::Unknown, KFileItem::Unknown, url);
648 item.refresh();
649 setItem(item);
650 }
651
652 void MetaDataWidget::setItems(const QList<KUrl>& urls)
653 {
654 KFileItemList items;
655 foreach (const KUrl& url, urls) {
656 KFileItem item(KFileItem::Unknown, KFileItem::Unknown, url);
657 item.refresh();
658 items.append(item);
659 }
660 setItems(items);
661 }
662
663 KFileItemList MetaDataWidget::items() const
664 {
665 return d->m_fileItems;
666 }
667
668 void MetaDataWidget::setHiddenData(MetaDataTypes data)
669 {
670 d->m_hiddenData = data;
671 d->updateRowsVisibility();
672 }
673
674 MetaDataWidget::MetaDataTypes MetaDataWidget::hiddenData() const
675 {
676 return d->m_hiddenData;
677 }
678
679 unsigned int MetaDataWidget::rating() const
680 {
681 #ifdef HAVE_NEPOMUK
682 QMutexLocker locker(&d->m_mutex);
683 return d->m_sharedData.rating;
684 #else
685 return 0;
686 #endif
687 }
688
689 QList<Nepomuk::Tag> MetaDataWidget::tags() const
690 {
691 #ifdef HAVE_NEPOMUK
692 QMutexLocker locker(&d->m_mutex);
693 return d->m_sharedData.tags;
694 #else
695 return QList<Nepomuk::Tag>();
696 #endif
697 }
698
699 QString MetaDataWidget::comment() const
700 {
701 #ifdef HAVE_NEPOMUK
702 QMutexLocker locker(&d->m_mutex);
703 return d->m_sharedData.comment;
704 #else
705 return QString();
706 #endif
707 }
708
709 #include "metadatawidget.moc"