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

KIO

kfilemetadatawidget.cpp
Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Copyright (C) 2008-2010 by Sebastian Trueg <trueg@kde.org>                *
00003  * Copyright (C) 2009-2010 by Peter Penz <peter.penz@gmx.at>                 *
00004  *                                                                           *
00005  * This library is free software; you can redistribute it and/or             *
00006  * modify it under the terms of the GNU Library General Public               *
00007  * License as published by the Free Software Foundation; either              *
00008  * version 2 of the License, or (at your option) any later version.          *
00009  *                                                                           *
00010  * This library is distributed in the hope that it will be useful,           *
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00013  * Library General Public License for more details.                          *
00014  *                                                                           *
00015  * You should have received a copy of the GNU Library General Public License *
00016  * along with this library; see the file COPYING.LIB.  If not, write to      *
00017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,      *
00018  * Boston, MA 02110-1301, USA.                                               *
00019  *****************************************************************************/
00020 
00021 #include "kfilemetadatawidget.h"
00022 
00023 #include <kconfig.h>
00024 #include <kconfiggroup.h>
00025 #include <kfileitem.h>
00026 #include <klocale.h>
00027 
00028 #include <QGridLayout>
00029 #include <QLabel>
00030 #include <QList>
00031 #include <QSet>
00032 #include <QString>
00033 #include <QTimer>
00034 
00035 #include <config-kio.h>
00036 #ifndef KIO_NO_NEPOMUK
00037     #define DISABLE_NEPOMUK_LEGACY
00038 
00039     #include <property.h>
00040     #include <tag.h>
00041 
00042     #include <QSpacerItem>
00043 
00044     #include "kfilemetadataprovider_p.h"
00045 #endif
00046 
00047 class KFileMetaDataWidget::Private
00048 {
00049 public:
00050     struct Row
00051     {
00052         QLabel* label;
00053         QWidget* value;
00054     };
00055 
00056     Private(KFileMetaDataWidget* parent);
00057     ~Private();
00058 
00064     void initMetaInfoSettings();
00065 
00071     void updateFileItemRowsVisibility();
00072 
00073     void deleteRows();
00074 
00075     void slotLoadingFinished();
00076     void slotLinkActivated(const QString& link);
00077     void slotDataChangeStarted();
00078     void slotDataChangeFinished();
00079 
00080 #ifndef KIO_NO_NEPOMUK
00081     QList<KUrl> sortedKeys(const QHash<KUrl, Nepomuk::Variant>& data) const;
00082 
00087     bool hasNepomukUris() const;
00088 #endif
00089 
00090     QList<Row> m_rows;
00091 #ifndef KIO_NO_NEPOMUK
00092     KFileMetaDataProvider* m_provider;
00093 #endif
00094     QGridLayout* m_gridLayout;
00095 
00096 private:
00097     KFileMetaDataWidget* const q;
00098 };
00099 
00100 KFileMetaDataWidget::Private::Private(KFileMetaDataWidget* parent) :
00101     m_rows(),
00102 #ifndef KIO_NO_NEPOMUK
00103     m_provider(0),
00104 #endif
00105     m_gridLayout(0),
00106     q(parent)
00107 {
00108     initMetaInfoSettings();
00109 
00110 #ifndef KIO_NO_NEPOMUK
00111     // TODO: If KFileMetaDataProvider might get a public class in future KDE releases,
00112     // the following code should be moved into KFileMetaDataWidget::setModel():
00113     m_provider = new KFileMetaDataProvider(q);
00114     connect(m_provider, SIGNAL(loadingFinished()), q, SLOT(slotLoadingFinished()));
00115     connect(m_provider, SIGNAL(urlActivated(KUrl)), q, SIGNAL(urlActivated(KUrl)));
00116 #endif
00117 }
00118 
00119 KFileMetaDataWidget::Private::~Private()
00120 {
00121 }
00122 
00123 void KFileMetaDataWidget::Private::initMetaInfoSettings()
00124 {
00125     const int currentVersion = 3; // increase version, if the blacklist of disabled
00126                                   // properties should be updated
00127 
00128     KConfig config("kmetainformationrc", KConfig::NoGlobals);
00129     if (config.group("Misc").readEntry("version", 0) < currentVersion) {
00130         // The resource file is read the first time. Assure
00131         // that some meta information is disabled per default.
00132 
00133         // clear old info
00134         config.deleteGroup("Show");
00135         KConfigGroup settings = config.group("Show");
00136 
00137         static const char* const disabledProperties[] = {
00138             "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#comment",
00139             "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentSize",
00140             "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#depends",
00141             "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#isPartOf",
00142             "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#lastModified",
00143             "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#mimeType",
00144             "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#plainTextContent",
00145             "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#url",
00146             "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#averageBitrate",
00147             "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#channels",
00148             "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#fileName",
00149             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#apertureValue",
00150             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#exposureBiasValue",
00151             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#exposureTime",
00152             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#flash",
00153             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#focalLength",
00154             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#focalLengthIn35mmFilm",
00155             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#isoSpeedRatings",
00156             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#make",
00157             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#meteringMode",
00158             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#model",
00159             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#orientation",
00160             "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#whiteBalance",
00161             "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#description",
00162             "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#hasTag",
00163             "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#lastModified",
00164             "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#numericRating",
00165             "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
00166             "kfileitem#owner",
00167             "kfileitem#permissions",
00168             0 // mandatory last entry
00169         };
00170 
00171         for (int i = 0; disabledProperties[i] != 0; ++i) {
00172             settings.writeEntry(disabledProperties[i], false);
00173         }
00174 
00175         // mark the group as initialized
00176         config.group("Misc").writeEntry("version", currentVersion);
00177     }
00178 }
00179 
00180 void KFileMetaDataWidget::Private::deleteRows()
00181 {
00182     foreach (const Row& row, m_rows) {
00183         delete row.label;
00184         delete row.value;
00185     }
00186     m_rows.clear();
00187 }
00188 
00189 void KFileMetaDataWidget::Private::slotLoadingFinished()
00190 {
00191 #ifndef KIO_NO_NEPOMUK
00192     deleteRows();
00193 
00194     if (!hasNepomukUris()) {
00195         q->updateGeometry();
00196         emit q->metaDataRequestFinished(m_provider->items());
00197         return;
00198     }
00199 
00200     if (m_gridLayout == 0) {
00201         m_gridLayout = new QGridLayout(q);
00202         m_gridLayout->setMargin(0);
00203         m_gridLayout->setSpacing(q->fontMetrics().height() / 4);
00204     }
00205 
00206     QHash<KUrl, Nepomuk::Variant> data = m_provider->data();
00207 
00208     // Remove all items, that are marked as hidden in kmetainformationrc
00209     KConfig config("kmetainformationrc", KConfig::NoGlobals);
00210     KConfigGroup settings = config.group("Show");
00211     QHash<KUrl, Nepomuk::Variant>::iterator it = data.begin();
00212     while (it != data.end()) {
00213         const QString uriString = it.key().url();
00214         if (!settings.readEntry(uriString, true) ||
00215             !Nepomuk::Types::Property(it.key()).userVisible()) {
00216             it = data.erase(it);
00217         } else {
00218             ++it;
00219         }
00220     }
00221 
00222     // Iterate through all remaining items embed the label
00223     // and the value as new row in the widget
00224     int rowIndex = 0;
00225     const QList<KUrl> keys = sortedKeys(data);
00226     foreach (const KUrl& key, keys) {
00227         const Nepomuk::Variant value = data[key];
00228         QString itemLabel = m_provider->label(key);
00229         itemLabel.append(QLatin1Char(':'));
00230 
00231         // Create label
00232         QLabel* label = new QLabel(itemLabel, q);
00233         label->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
00234         label->setForegroundRole(q->foregroundRole());
00235         label->setFont(q->font());
00236         label->setWordWrap(true);
00237         label->setAlignment(Qt::AlignTop | Qt::AlignRight);
00238 
00239         // Create value-widget
00240         QWidget* valueWidget = m_provider->createValueWidget(key, value, q);
00241 
00242         // Add the label and value-widget to grid layout
00243         m_gridLayout->addWidget(label, rowIndex, 0, Qt::AlignRight);
00244         const int spacerWidth = QFontMetrics(q->font()).size(Qt::TextSingleLine, " ").width();
00245         m_gridLayout->addItem(new QSpacerItem(spacerWidth, 1), rowIndex, 1);
00246         m_gridLayout->addWidget(valueWidget, rowIndex, 2, Qt::AlignLeft);
00247 
00248         // Remember the label and value-widget as row
00249         Row row;
00250         row.label = label;
00251         row.value = valueWidget;
00252         m_rows.append(row);
00253 
00254         ++rowIndex;
00255     }
00256 #endif
00257 
00258     q->updateGeometry();
00259 #ifndef KIO_NO_NEPOMUK
00260     emit q->metaDataRequestFinished(m_provider->items());
00261 #endif
00262 }
00263 
00264 void KFileMetaDataWidget::Private::slotLinkActivated(const QString& link)
00265 {
00266     const KUrl url(link);
00267     if (url.isValid()) {
00268         emit q->urlActivated(url);
00269     }
00270 }
00271 
00272 void KFileMetaDataWidget::Private::slotDataChangeStarted()
00273 {
00274     q->setEnabled(false);
00275 }
00276 
00277 void KFileMetaDataWidget::Private::slotDataChangeFinished()
00278 {
00279     q->setEnabled(true);
00280 }
00281 
00282 #ifndef KIO_NO_NEPOMUK
00283 QList<KUrl> KFileMetaDataWidget::Private::sortedKeys(const QHash<KUrl, Nepomuk::Variant>& data) const
00284 {
00285     // Create a map, where the translated label prefixed with the
00286     // sort priority acts as key. The data of each entry is the URI
00287     // of the data. By this the all URIs are sorted by the sort priority
00288     // and sub sorted by the translated labels.
00289     QMap<QString, KUrl> map;
00290     QHash<KUrl, Nepomuk::Variant>::const_iterator hashIt = data.constBegin();
00291     while (hashIt != data.constEnd()) {
00292         const KUrl uri = hashIt.key();
00293 
00294         QString key = m_provider->group(uri);
00295         key += m_provider->label(uri);
00296 
00297         map.insert(key, uri);
00298         ++hashIt;
00299     }
00300 
00301     // Apply the URIs from the map to the list that will get returned.
00302     // The list will then be alphabetically ordered by the translated labels of the URIs.
00303     QList<KUrl> list;
00304     QMap<QString, KUrl>::const_iterator mapIt = map.constBegin();
00305     while (mapIt != map.constEnd()) {
00306         list.append(mapIt.value());
00307         ++mapIt;
00308     }
00309 
00310     return list;
00311 }
00312 
00313 bool KFileMetaDataWidget::Private::hasNepomukUris() const
00314 {
00315     foreach (const KFileItem& fileItem, m_provider->items()) {
00316         if (fileItem.nepomukUri().isValid()) {
00317             return true;
00318         }
00319     }
00320     return false;
00321 }
00322 #endif
00323 
00324 KFileMetaDataWidget::KFileMetaDataWidget(QWidget* parent) :
00325     QWidget(parent),
00326     d(new Private(this))
00327 {
00328 }
00329 
00330 KFileMetaDataWidget::~KFileMetaDataWidget()
00331 {
00332     delete d;
00333 }
00334 
00335 void KFileMetaDataWidget::setItems(const KFileItemList& items)
00336 {
00337 #ifndef KIO_NO_NEPOMUK
00338     d->m_provider->setItems(items);
00339 #endif
00340 }
00341 
00342 KFileItemList KFileMetaDataWidget::items() const
00343 {
00344 #ifndef KIO_NO_NEPOMUK
00345     return d->m_provider->items();
00346 #else
00347     return KFileItemList();
00348 #endif
00349 }
00350 
00351 void KFileMetaDataWidget::setReadOnly(bool readOnly)
00352 {
00353 #ifndef KIO_NO_NEPOMUK
00354     d->m_provider->setReadOnly(readOnly);
00355 #endif
00356 }
00357 
00358 bool KFileMetaDataWidget::isReadOnly() const
00359 {
00360 #ifndef KIO_NO_NEPOMUK
00361     return d->m_provider->isReadOnly();
00362 #else
00363     return true;
00364 #endif
00365 }
00366 
00367 QSize KFileMetaDataWidget::sizeHint() const
00368 {
00369     if (d->m_gridLayout == 0) {
00370         return QWidget::sizeHint();
00371     }
00372 
00373     // Calculate the required width for the labels and values
00374     int leftWidthMax = 0;
00375     int rightWidthMax = 0;
00376     int rightWidthAverage = 0;
00377     foreach (const Private::Row& row, d->m_rows) {
00378         const QWidget* valueWidget = row.value;
00379         const int rightWidth = valueWidget->sizeHint().width();
00380         rightWidthAverage += rightWidth;
00381         if (rightWidth > rightWidthMax) {
00382             rightWidthMax = rightWidth;
00383         }
00384 
00385         const int leftWidth = row.label->sizeHint().width();
00386         if (leftWidth > leftWidthMax) {
00387             leftWidthMax = leftWidth;
00388         }
00389     }
00390 
00391     // Some value widgets might return a very huge width for the size hint.
00392     // Limit the maximum width to the double width of the overall average
00393     // to assure a less messed layout.
00394     if (d->m_rows.count() > 1) {
00395         rightWidthAverage /= d->m_rows.count();
00396         if (rightWidthMax > rightWidthAverage * 2) {
00397             rightWidthMax = rightWidthAverage * 2;
00398         }
00399     }
00400 
00401     // Based on the available width calculate the required height
00402     int height = d->m_gridLayout->margin() * 2 + d->m_gridLayout->spacing() * (d->m_rows.count() - 1);
00403     foreach (const Private::Row& row, d->m_rows) {
00404         const QWidget* valueWidget = row.value;
00405         const int rowHeight = qMax(row.label->heightForWidth(leftWidthMax),
00406                                    valueWidget->heightForWidth(rightWidthMax));
00407         height += rowHeight;
00408     }
00409 
00410     const int width = d->m_gridLayout->margin() * 2 + leftWidthMax +
00411                       d->m_gridLayout->spacing() + rightWidthMax;
00412 
00413     return QSize(width, height);
00414 }
00415 
00416 bool KFileMetaDataWidget::event(QEvent* event)
00417 {
00418     return QWidget::event(event);
00419 }
00420 
00421 #include "kfilemetadatawidget.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 20:55:21 by doxygen 1.8.0 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.8.3 API Reference

Skip menu "kdelibs-4.8.3 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