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