]> cloud.milkyroute.net Git - dolphin.git/blob - src/panels/information/kmetadatawidget.cpp
The number of fixed meta-info items may vary dependent on whether Nepomuk is enabled...
[dolphin.git] / src / panels / information / kmetadatawidget.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 library is free software; you can redistribute it and/or *
6 * modify it under the terms of the GNU Library General Public *
7 * License version 2 as published by the Free Software Foundation. *
8 * *
9 * This library is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Library General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU Library General Public License *
15 * along with this library; see the file COPYING.LIB. If not, write to *
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301, USA. *
18 *****************************************************************************/
19
20 #include "kmetadatawidget.h"
21
22 #include <kconfig.h>
23 #include <kconfiggroup.h>
24 #include <kfileitem.h>
25 #include <kglobalsettings.h>
26 #include <kglobal.h>
27 #include <klocale.h>
28
29 #include <QEvent>
30 #include <QFontMetrics>
31 #include <QGridLayout>
32 #include <QLabel>
33 #include <QList>
34 #include <QString>
35
36 #include <config-nepomuk.h>
37 #ifdef HAVE_NEPOMUK
38 #define DISABLE_NEPOMUK_LEGACY
39
40 #include "kcommentwidget_p.h"
41 #include "kloadmetadatathread_p.h"
42 #include "ktaggingwidget_p.h"
43
44 #include <nepomuk/kratingwidget.h>
45 #include <nepomuk/resource.h>
46 #include <nepomuk/resourcemanager.h>
47 #include <nepomuk/property.h>
48 #include <nepomuk/tag.h>
49 #include <nepomuk/variant.h>
50 #include "nepomukmassupdatejob_p.h"
51
52 #include <QMutex>
53 #include <QSpacerItem>
54 #include <QThread>
55 #else
56 namespace Nepomuk
57 {
58 typedef int Tag;
59 }
60 #endif
61
62 class KMetaDataWidget::Private
63 {
64 public:
65 struct Row
66 {
67 QLabel* label;
68 QWidget* infoWidget;
69 };
70
71 Private(KMetaDataWidget* parent);
72 ~Private();
73
74 void addRow(QLabel* label, QWidget* infoWidget);
75 void removeMetaInfoRows();
76 void setRowVisible(QWidget* infoWidget, bool visible);
77
78 /**
79 * Initializes the configuration file "kmetainformationrc"
80 * with proper default settings for the first start in
81 * an uninitialized environment.
82 */
83 void initMetaInfoSettings();
84
85 /**
86 * Parses the configuration file "kmetainformationrc" and
87 * updates the visibility of all rows.
88 */
89 void updateRowsVisibility();
90
91 void slotLoadingFinished();
92
93 void slotRatingChanged(unsigned int rating);
94 void slotTagsChanged(const QList<Nepomuk::Tag>& tags);
95 void slotCommentChanged(const QString& comment);
96
97 void slotMetaDataUpdateDone();
98 void slotLinkActivated(const QString& link);
99
100 void slotTagActivated(const Nepomuk::Tag& tag);
101
102 #ifdef HAVE_NEPOMUK
103 /**
104 * Disables the metadata widget and starts the job that
105 * changes the meta data asynchronously. After the job
106 * has been finished, the metadata widget gets enabled again.
107 */
108 void startChangeDataJob(KJob* job);
109
110 /**
111 * Merges items like 'width' and 'height' as one item.
112 */
113 QList<KLoadMetaDataThread::Item> mergedItems(const QList<KLoadMetaDataThread::Item>& items);
114 #endif
115
116 bool m_sizeVisible;
117 bool m_readOnly;
118 bool m_nepomukActivated;
119 int m_fixedRowCount;
120 MetaDataTypes m_visibleDataTypes;
121 QList<KFileItem> m_fileItems;
122 QList<Row> m_rows;
123
124 QGridLayout* m_gridLayout;
125
126 QLabel* m_typeInfo;
127 QLabel* m_sizeLabel;
128 QLabel* m_sizeInfo;
129 QLabel* m_modifiedInfo;
130 QLabel* m_ownerInfo;
131 QLabel* m_permissionsInfo;
132
133 #ifdef HAVE_NEPOMUK
134 KRatingWidget* m_ratingWidget;
135 KTaggingWidget* m_taggingWidget;
136 KCommentWidget* m_commentWidget;
137
138 QMap<KUrl, Nepomuk::Resource> m_files;
139
140 KLoadMetaDataThread* m_loadMetaDataThread;
141 #endif
142
143 private:
144 KMetaDataWidget* const q;
145 };
146
147 KMetaDataWidget::Private::Private(KMetaDataWidget* parent) :
148 m_sizeVisible(true),
149 m_readOnly(false),
150 m_nepomukActivated(false),
151 m_fixedRowCount(0),
152 m_visibleDataTypes(TypeData | SizeData | ModifiedData | OwnerData |
153 PermissionsData | RatingData | TagsData | CommentData),
154 m_fileItems(),
155 m_rows(),
156 m_gridLayout(0),
157 m_typeInfo(0),
158 m_sizeLabel(0),
159 m_sizeInfo(0),
160 m_modifiedInfo(0),
161 m_ownerInfo(0),
162 m_permissionsInfo(0),
163 #ifdef HAVE_NEPOMUK
164 m_ratingWidget(0),
165 m_taggingWidget(0),
166 m_commentWidget(0),
167 m_files(),
168 m_loadMetaDataThread(0),
169 #endif
170 q(parent)
171 {
172 const QFontMetrics fontMetrics(KGlobalSettings::smallestReadableFont());
173
174 m_gridLayout = new QGridLayout(parent);
175 m_gridLayout->setMargin(0);
176 m_gridLayout->setSpacing(fontMetrics.height() / 4);
177
178 m_typeInfo = new QLabel(parent);
179 m_sizeLabel = new QLabel(parent);
180 m_sizeInfo = new QLabel(parent);
181 m_modifiedInfo = new QLabel(parent);
182 m_ownerInfo = new QLabel(parent);
183 m_permissionsInfo = new QLabel(parent);
184
185 #ifdef HAVE_NEPOMUK
186 m_nepomukActivated = (Nepomuk::ResourceManager::instance()->init() == 0);
187 if (m_nepomukActivated) {
188 m_ratingWidget = new KRatingWidget(parent);
189 m_ratingWidget->setFixedHeight(fontMetrics.height());
190 const Qt::Alignment align = (parent->layoutDirection() == Qt::LeftToRight) ?
191 Qt::AlignLeft : Qt::AlignRight;
192 m_ratingWidget->setAlignment(align);
193 connect(m_ratingWidget, SIGNAL(ratingChanged(unsigned int)),
194 q, SLOT(slotRatingChanged(unsigned int)));
195
196 m_taggingWidget = new KTaggingWidget(parent);
197 connect(m_taggingWidget, SIGNAL(tagsChanged(const QList<Nepomuk::Tag>&)),
198 q, SLOT(slotTagsChanged(const QList<Nepomuk::Tag>&)));
199 connect(m_taggingWidget, SIGNAL(tagActivated(const Nepomuk::Tag&)),
200 q, SLOT(slotTagActivated(const Nepomuk::Tag&)));
201
202 m_commentWidget = new KCommentWidget(parent);
203 connect(m_commentWidget, SIGNAL(commentChanged(const QString&)),
204 q, SLOT(slotCommentChanged(const QString&)));
205 }
206 #endif
207
208 initMetaInfoSettings();
209 }
210
211 KMetaDataWidget::Private::~Private()
212 {
213 #ifdef HAVE_NEPOMUK
214 if (m_loadMetaDataThread != 0) {
215 disconnect(m_loadMetaDataThread, SIGNAL(finished()), q, SLOT(slotLoadingFinished()));
216 m_loadMetaDataThread->cancelAndDelete();
217 m_loadMetaDataThread = 0;
218 }
219 #endif
220 }
221
222 void KMetaDataWidget::Private::addRow(QLabel* label, QWidget* infoWidget)
223 {
224 Row row;
225 row.label = label;
226 row.infoWidget = infoWidget;
227 m_rows.append(row);
228
229 const QFont smallFont = KGlobalSettings::smallestReadableFont();
230 // use a brighter color for the label and a small font size
231 QPalette palette = label->palette();
232 const QPalette::ColorRole role = q->foregroundRole();
233 QColor textColor = palette.color(role);
234 textColor.setAlpha(128);
235 palette.setColor(role, textColor);
236 label->setPalette(palette);
237 label->setForegroundRole(role);
238 label->setFont(smallFont);
239 label->setWordWrap(true);
240 label->setAlignment(Qt::AlignTop | Qt::AlignRight);
241
242 infoWidget->setForegroundRole(role);
243 QLabel* infoLabel = qobject_cast<QLabel*>(infoWidget);
244 if (infoLabel != 0) {
245 infoLabel->setFont(smallFont);
246 infoLabel->setWordWrap(true);
247 infoLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
248 }
249
250 // add the row to grid layout
251 const int rowIndex = m_rows.count();
252 m_gridLayout->addWidget(label, rowIndex, 0, Qt::AlignRight);
253 const int spacerWidth = QFontMetrics(smallFont).size(Qt::TextSingleLine, " ").width();
254 m_gridLayout->addItem(new QSpacerItem(spacerWidth, 1), rowIndex, 1);
255 m_gridLayout->addWidget(infoWidget, rowIndex, 2, Qt::AlignLeft);
256 }
257
258 void KMetaDataWidget::Private::setRowVisible(QWidget* infoWidget, bool visible)
259 {
260 foreach (const Row& row, m_rows) {
261 if (row.infoWidget == infoWidget) {
262 row.label->setVisible(visible);
263 row.infoWidget->setVisible(visible);
264 return;
265 }
266 }
267 }
268
269
270 void KMetaDataWidget::Private::initMetaInfoSettings()
271 {
272 const int currentVersion = 2; // increase version, if the blacklist of disabled
273 // properties should be updated
274
275 KConfig config("kmetainformationrc", KConfig::NoGlobals);
276 if (config.group("Misc").readEntry("version", 0) < currentVersion) {
277 // The resource file is read the first time. Assure
278 // that some meta information is disabled per default.
279
280 // clear old info
281 config.deleteGroup( "Show" );
282 KConfigGroup settings = config.group("Show");
283
284 // trueg: KDE 4.5: use a blacklist of actual rdf properties
285
286 static const char* const disabledProperties[] = {
287 "asText", "contentSize", "created", "depth", "description", "fileExtension",
288 "fileName", "fileSize", "hasTag", "lastModified", "mimeType", "name",
289 "numericRating", "parentUrl", "permissions", "plainTextContent", "owner",
290 "sourceModified", "url",
291 0 // mandatory last entry
292 };
293
294 for (int i = 0; disabledProperties[i] != 0; ++i) {
295 settings.writeEntry(disabledProperties[i], false);
296 }
297
298 // mark the group as initialized
299 config.group("Misc").writeEntry("version", currentVersion);
300 }
301 }
302
303 void KMetaDataWidget::Private::updateRowsVisibility()
304 {
305 KConfig config("kmetainformationrc", KConfig::NoGlobals);
306 KConfigGroup settings = config.group("Show");
307
308 setRowVisible(m_typeInfo,
309 (m_visibleDataTypes & KMetaDataWidget::TypeData) &&
310 settings.readEntry("type", true));
311
312 // Cache in m_sizeVisible whether the size should be shown. This
313 // is necessary as the size is temporary hidden when the target
314 // file item is a directory.
315 m_sizeVisible = (m_visibleDataTypes & KMetaDataWidget::SizeData) &&
316 settings.readEntry("size", true);
317 bool visible = m_sizeVisible;
318 if (visible && (m_fileItems.count() == 1)) {
319 // don't show the size information, if one directory is shown
320 const KFileItem item = m_fileItems.first();
321 visible = !item.isNull() && !item.isDir();
322 }
323 setRowVisible(m_sizeInfo, visible);
324
325 setRowVisible(m_modifiedInfo,
326 (m_visibleDataTypes & KMetaDataWidget::ModifiedData) &&
327 settings.readEntry("modified", true));
328
329 setRowVisible(m_ownerInfo,
330 (m_visibleDataTypes & KMetaDataWidget::OwnerData) &&
331 settings.readEntry("owner", true));
332
333 setRowVisible(m_permissionsInfo,
334 (m_visibleDataTypes & KMetaDataWidget::PermissionsData) &&
335 settings.readEntry("permissions", true));
336
337 #ifdef HAVE_NEPOMUK
338 if (m_nepomukActivated) {
339 setRowVisible(m_ratingWidget,
340 (m_visibleDataTypes & KMetaDataWidget::RatingData) &&
341 settings.readEntry("rating", true));
342
343 setRowVisible(m_taggingWidget,
344 (m_visibleDataTypes & KMetaDataWidget::TagsData) &&
345 settings.readEntry("tags", true));
346
347 setRowVisible(m_commentWidget,
348 (m_visibleDataTypes & KMetaDataWidget::CommentData) &&
349 settings.readEntry("comment", true));
350 }
351 #endif
352 }
353
354 void KMetaDataWidget::Private::slotLoadingFinished()
355 {
356 #ifdef HAVE_NEPOMUK
357 if (m_loadMetaDataThread == 0) {
358 // The signal finished() has been emitted, but the thread has been marked
359 // as invalid in the meantime. Just ignore the signal in this case.
360 return;
361 }
362
363 if (m_nepomukActivated) {
364 Q_ASSERT(m_ratingWidget != 0);
365 Q_ASSERT(m_commentWidget != 0);
366 Q_ASSERT(m_taggingWidget != 0);
367 m_ratingWidget->setRating(m_loadMetaDataThread->rating());
368 m_commentWidget->setText(m_loadMetaDataThread->comment());
369 m_taggingWidget->setTags(m_loadMetaDataThread->tags());
370 }
371
372 // Show the remaining meta information as text. The number
373 // of required rows may very. Existing rows are reused to
374 // prevent flickering.
375 int rowIndex = m_fixedRowCount;
376 const QList<KLoadMetaDataThread::Item> items = mergedItems(m_loadMetaDataThread->items());
377 foreach (const KLoadMetaDataThread::Item& item, items) {
378 const QString itemLabel = item.label;
379 QString itemValue = item.value;
380 if (item.value.startsWith("<a href=")) {
381 // use the text color for the value-links, to create a visual difference
382 // to the semantically different links like "Change..."
383 const QColor linkColor = q->palette().text().color();
384 QString decoration;
385 if (m_readOnly) {
386 decoration = QString::fromLatin1("text-decoration:none;");
387 }
388 const QString styleText = QString::fromLatin1("style=\"color:%1;%2\" ")
389 .arg(linkColor.name())
390 .arg(decoration);
391 itemValue.insert(3 /* after "<a "*/, styleText);
392 }
393 if (rowIndex < m_rows.count()) {
394 // adjust texts of the current row
395 m_rows[rowIndex].label->setText(itemLabel);
396 QLabel* infoValueLabel = qobject_cast<QLabel*>(m_rows[rowIndex].infoWidget);
397 Q_ASSERT(infoValueLabel != 0);
398 infoValueLabel->setText(itemValue);
399 } else {
400 // create new row
401 QLabel* infoLabel = new QLabel(itemLabel, q);
402 QLabel* infoValue = new QLabel(itemValue, q);
403 connect(infoValue, SIGNAL(linkActivated(QString)),
404 q, SLOT(slotLinkActivated(QString)));
405 addRow(infoLabel, infoValue);
406 }
407 ++rowIndex;
408 }
409
410 // remove rows that are not needed anymore
411 for (int i = m_rows.count() - 1; i >= rowIndex; --i) {
412 delete m_rows[i].label;
413 delete m_rows[i].infoWidget;
414 m_rows.pop_back();
415 }
416
417 m_files = m_loadMetaDataThread->files();
418
419 m_loadMetaDataThread->deleteLater();
420 m_loadMetaDataThread = 0;
421 #endif
422
423 q->updateGeometry();
424 }
425
426 void KMetaDataWidget::Private::slotRatingChanged(unsigned int rating)
427 {
428 #ifdef HAVE_NEPOMUK
429 Nepomuk::MassUpdateJob* job =
430 Nepomuk::MassUpdateJob::rateResources(m_files.values(), rating);
431 startChangeDataJob(job);
432 #else
433 Q_UNUSED(rating);
434 #endif
435 }
436
437 void KMetaDataWidget::Private::slotTagsChanged(const QList<Nepomuk::Tag>& tags)
438 {
439 #ifdef HAVE_NEPOMUK
440 m_taggingWidget->setTags(tags);
441
442 Nepomuk::MassUpdateJob* job =
443 Nepomuk::MassUpdateJob::tagResources(m_files.values(), tags);
444 startChangeDataJob(job);
445 #else
446 Q_UNUSED(tags);
447 #endif
448 }
449
450 void KMetaDataWidget::Private::slotCommentChanged(const QString& comment)
451 {
452 #ifdef HAVE_NEPOMUK
453 Nepomuk::MassUpdateJob* job =
454 Nepomuk::MassUpdateJob::commentResources(m_files.values(), comment);
455 startChangeDataJob(job);
456 #else
457 Q_UNUSED(comment);
458 #endif
459 }
460
461 void KMetaDataWidget::Private::slotTagActivated(const Nepomuk::Tag& tag)
462 {
463 #ifdef HAVE_NEPOMUK
464 emit q->urlActivated(tag.resourceUri());
465 #else
466 Q_UNUSED(tag);
467 #endif
468 }
469
470 void KMetaDataWidget::Private::slotMetaDataUpdateDone()
471 {
472 #ifdef HAVE_NEPOMUK
473 q->setEnabled(true);
474 #endif
475 }
476
477 void KMetaDataWidget::Private::slotLinkActivated(const QString& link)
478 {
479 emit q->urlActivated(KUrl(link));
480 }
481
482 #ifdef HAVE_NEPOMUK
483 void KMetaDataWidget::Private::startChangeDataJob(KJob* job)
484 {
485 connect(job, SIGNAL(result(KJob*)),
486 q, SLOT(slotMetaDataUpdateDone()));
487 q->setEnabled(false); // no updates during execution
488 job->start();
489 }
490
491 QList<KLoadMetaDataThread::Item>
492 KMetaDataWidget::Private::mergedItems(const QList<KLoadMetaDataThread::Item>& items)
493 {
494 // TODO: Currently only "width" and "height" are merged as "width x height". If
495 // other kind of merges should be done too, a more general approach is required.
496 QList<KLoadMetaDataThread::Item> mergedItems;
497
498 KLoadMetaDataThread::Item width;
499 KLoadMetaDataThread::Item height;
500
501 foreach (const KLoadMetaDataThread::Item& item, items) {
502 if (item.name == "width") {
503 width = item;
504 } else if (item.name == "height") {
505 height = item;
506 } else {
507 // insert the item sorted by the label
508 int pos = 0;
509 while ( mergedItems.count() > pos &&
510 mergedItems[pos].label < item.label ) {
511 ++pos;
512 }
513 mergedItems.insert( pos, item );
514 }
515 }
516
517 const bool foundWidth = !width.name.isEmpty();
518 const bool foundHeight = !height.name.isEmpty();
519 if (foundWidth && !foundHeight) {
520 mergedItems.insert(0, width);
521 } else if (foundHeight && !foundWidth) {
522 mergedItems.insert(0, height);
523 } else if (foundWidth && foundHeight) {
524 KLoadMetaDataThread::Item size;
525 size.label = i18nc("@label", "Width x Height:");
526 size.value = width.value + " x " + height.value;
527 mergedItems.insert(0, size);
528 }
529
530 return mergedItems;
531 }
532 #endif
533
534 KMetaDataWidget::KMetaDataWidget(QWidget* parent) :
535 QWidget(parent),
536 d(new Private(this))
537 {
538 }
539
540 KMetaDataWidget::~KMetaDataWidget()
541 {
542 delete d;
543 }
544
545 void KMetaDataWidget::setItem(const KFileItem& item)
546 {
547 // update values for "type", "size", "modified",
548 // "owner" and "permissions" synchronously
549 d->m_sizeLabel->setText(i18nc("@label", "Size:"));
550 if (item.isDir()) {
551 d->m_typeInfo->setText(i18nc("@label", "Folder"));
552 d->setRowVisible(d->m_sizeInfo, false);
553 } else {
554 d->m_typeInfo->setText(item.mimeComment());
555 d->m_sizeInfo->setText(KIO::convertSize(item.size()));
556 d->setRowVisible(d->m_sizeInfo, d->m_sizeVisible);
557 }
558 d->m_modifiedInfo->setText(KGlobal::locale()->formatDateTime(item.time(KFileItem::ModificationTime), KLocale::FancyLongDate));
559 d->m_ownerInfo->setText(item.user());
560 d->m_permissionsInfo->setText(item.permissionsString());
561
562 setItems(KFileItemList() << item);
563 }
564
565 void KMetaDataWidget::setItems(const KFileItemList& items)
566 {
567 d->m_fileItems = items;
568
569 if (items.count() > 1) {
570 // calculate the size of all items and show this
571 // information to the user
572 d->m_sizeLabel->setText(i18nc("@label", "Total Size:"));
573 d->setRowVisible(d->m_sizeInfo, d->m_sizeVisible);
574
575 quint64 totalSize = 0;
576 foreach (const KFileItem& item, items) {
577 if (!item.isDir() && !item.isLink()) {
578 totalSize += item.size();
579 }
580 }
581 d->m_sizeInfo->setText(KIO::convertSize(totalSize));
582 }
583
584 #ifdef HAVE_NEPOMUK
585 QList<KUrl> urls;
586 foreach (const KFileItem& item, items) {
587 const KUrl url = item.nepomukUri();
588 if (url.isValid()) {
589 urls.append(url);
590 }
591 }
592
593 if (d->m_loadMetaDataThread != 0) {
594 disconnect(d->m_loadMetaDataThread, SIGNAL(finished()), this, SLOT(slotLoadingFinished()));
595 d->m_loadMetaDataThread->cancelAndDelete();
596 }
597
598 d->m_loadMetaDataThread = new KLoadMetaDataThread();
599 connect(d->m_loadMetaDataThread, SIGNAL(finished()), this, SLOT(slotLoadingFinished()));
600 d->m_loadMetaDataThread->load(urls);
601 #endif
602 }
603
604 void KMetaDataWidget::setItem(const KUrl& url)
605 {
606 KFileItem item(KFileItem::Unknown, KFileItem::Unknown, url);
607 item.refresh();
608 setItem(item);
609 }
610
611 void KMetaDataWidget::setItems(const QList<KUrl>& urls)
612 {
613 KFileItemList items;
614 foreach (const KUrl& url, urls) {
615 KFileItem item(KFileItem::Unknown, KFileItem::Unknown, url);
616 item.refresh();
617 items.append(item);
618 }
619 setItems(items);
620 }
621
622 KFileItemList KMetaDataWidget::items() const
623 {
624 return d->m_fileItems;
625 }
626
627 void KMetaDataWidget::setReadOnly(bool readOnly)
628 {
629 d->m_readOnly = readOnly;
630 #ifdef HAVE_NEPOMUK
631 // TODO: encapsulate this code as part of a metadata-model for KDE 4.5
632 if (d->m_taggingWidget)
633 d->m_taggingWidget->setReadOnly(readOnly);
634 if (d->m_commentWidget)
635 d->m_commentWidget->setReadOnly(readOnly);
636 #endif
637 }
638
639 bool KMetaDataWidget::isReadOnly() const
640 {
641 return d->m_readOnly;
642 }
643
644 void KMetaDataWidget::setVisibleDataTypes(MetaDataTypes data)
645 {
646 d->m_visibleDataTypes = data;
647 d->updateRowsVisibility();
648 }
649
650 KMetaDataWidget::MetaDataTypes KMetaDataWidget::visibleDataTypes() const
651 {
652 return d->m_visibleDataTypes;
653 }
654
655 QSize KMetaDataWidget::sizeHint() const
656 {
657 const int fixedWidth = 200;
658
659 int height = d->m_gridLayout->margin() * 2 +
660 d->m_gridLayout->spacing() * (d->m_rows.count() - 1);
661
662 foreach (const Private::Row& row, d->m_rows) {
663 if (row.infoWidget != 0) {
664 int rowHeight = row.infoWidget->heightForWidth(fixedWidth / 2);
665 if (rowHeight <= 0) {
666 rowHeight = row.infoWidget->sizeHint().height();
667 }
668 height += rowHeight;
669 }
670 }
671
672 return QSize(fixedWidth, height);
673 }
674
675 bool KMetaDataWidget::event(QEvent* event)
676 {
677 if (event->type() == QEvent::Polish) {
678 // The adding of rows is not done in the constructor. This allows the
679 // client of KMetaDataWidget to set a proper foreground role which
680 // will be respected by the rows.
681
682 d->addRow(new QLabel(i18nc("@label", "Type:"), this), d->m_typeInfo);
683 d->addRow(d->m_sizeLabel, d->m_sizeInfo);
684 d->addRow(new QLabel(i18nc("@label", "Modified:"), this), d->m_modifiedInfo);
685 d->addRow(new QLabel(i18nc("@label", "Owner:"), this), d->m_ownerInfo);
686 d->addRow(new QLabel(i18nc("@label", "Permissions:"), this), d->m_permissionsInfo);
687
688 #ifdef HAVE_NEPOMUK
689 if (d->m_nepomukActivated) {
690 d->addRow(new QLabel(i18nc("@label", "Rating:"), this), d->m_ratingWidget);
691 d->addRow(new QLabel(i18nc("@label", "Tags:"), this), d->m_taggingWidget);
692 d->addRow(new QLabel(i18nc("@label", "Comment:"), this), d->m_commentWidget);
693 }
694 #endif
695
696 // The current number of rows represents meta data, that will be shown for
697 // all files. Dynamic meta data will be appended after those rows (see
698 // slotLoadingFinished()).
699 d->m_fixedRowCount = d->m_rows.count();
700
701 d->updateRowsVisibility();
702 }
703
704 return QWidget::event(event);
705 }
706
707 #include "kmetadatawidget.moc"