• Skip to content
  • Skip to link menu
KDE 4.7 API Reference
  • KDE API Reference
  • kdelibs
  • 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->setForegroundRole(q->foregroundRole());
00234         label->setFont(q->font());
00235         label->setWordWrap(true);
00236         label->setAlignment(Qt::AlignTop | Qt::AlignRight);
00237 
00238         // Create value-widget
00239         QWidget* valueWidget = m_provider->createValueWidget(key, value, q);
00240 
00241         // Add the label and value-widget to grid layout
00242         m_gridLayout->addWidget(label, rowIndex, 0, Qt::AlignRight);
00243         const int spacerWidth = QFontMetrics(q->font()).size(Qt::TextSingleLine, " ").width();
00244         m_gridLayout->addItem(new QSpacerItem(spacerWidth, 1), rowIndex, 1);
00245         m_gridLayout->addWidget(valueWidget, rowIndex, 2, Qt::AlignLeft);
00246 
00247         // Remember the label and value-widget as row
00248         Row row;
00249         row.label = label;
00250         row.value = valueWidget;
00251         m_rows.append(row);
00252 
00253         ++rowIndex;
00254     }
00255 #endif
00256 
00257     q->updateGeometry();
00258 #ifndef KIO_NO_NEPOMUK
00259     emit q->metaDataRequestFinished(m_provider->items());
00260 #endif
00261 }
00262 
00263 void KFileMetaDataWidget::Private::slotLinkActivated(const QString& link)
00264 {
00265     const KUrl url(link);
00266     if (url.isValid()) {
00267         emit q->urlActivated(url);
00268     }
00269 }
00270 
00271 void KFileMetaDataWidget::Private::slotDataChangeStarted()
00272 {
00273     q->setEnabled(false);
00274 }
00275 
00276 void KFileMetaDataWidget::Private::slotDataChangeFinished()
00277 {
00278     q->setEnabled(true);
00279 }
00280 
00281 #ifndef KIO_NO_NEPOMUK
00282 QList<KUrl> KFileMetaDataWidget::Private::sortedKeys(const QHash<KUrl, Nepomuk::Variant>& data) const
00283 {
00284     // Create a map, where the translated label prefixed with the
00285     // sort priority acts as key. The data of each entry is the URI
00286     // of the data. By this the all URIs are sorted by the sort priority
00287     // and sub sorted by the translated labels.
00288     QMap<QString, KUrl> map;
00289     QHash<KUrl, Nepomuk::Variant>::const_iterator hashIt = data.constBegin();
00290     while (hashIt != data.constEnd()) {
00291         const KUrl uri = hashIt.key();
00292 
00293         QString key = m_provider->group(uri);
00294         key += m_provider->label(uri);
00295 
00296         map.insert(key, uri);
00297         ++hashIt;
00298     }
00299 
00300     // Apply the URIs from the map to the list that will get returned.
00301     // The list will then be alphabetically ordered by the translated labels of the URIs.
00302     QList<KUrl> list;
00303     QMap<QString, KUrl>::const_iterator mapIt = map.constBegin();
00304     while (mapIt != map.constEnd()) {
00305         list.append(mapIt.value());
00306         ++mapIt;
00307     }
00308 
00309     return list;
00310 }
00311 
00312 bool KFileMetaDataWidget::Private::hasNepomukUris() const
00313 {
00314     foreach (const KFileItem& fileItem, m_provider->items()) {
00315         if (fileItem.nepomukUri().isValid()) {
00316             return true;
00317         }
00318     }
00319     return false;
00320 }
00321 #endif
00322 
00323 KFileMetaDataWidget::KFileMetaDataWidget(QWidget* parent) :
00324     QWidget(parent),
00325     d(new Private(this))
00326 {
00327 }
00328 
00329 KFileMetaDataWidget::~KFileMetaDataWidget()
00330 {
00331     delete d;
00332 }
00333 
00334 void KFileMetaDataWidget::setItems(const KFileItemList& items)
00335 {
00336 #ifndef KIO_NO_NEPOMUK
00337     d->m_provider->setItems(items);
00338 #endif
00339 }
00340 
00341 KFileItemList KFileMetaDataWidget::items() const
00342 {
00343 #ifndef KIO_NO_NEPOMUK
00344     return d->m_provider->items();
00345 #else
00346     return KFileItemList();
00347 #endif
00348 }
00349 
00350 void KFileMetaDataWidget::setReadOnly(bool readOnly)
00351 {
00352 #ifndef KIO_NO_NEPOMUK
00353     d->m_provider->setReadOnly(readOnly);
00354 #endif
00355 }
00356 
00357 bool KFileMetaDataWidget::isReadOnly() const
00358 {
00359 #ifndef KIO_NO_NEPOMUK
00360     return d->m_provider->isReadOnly();
00361 #else
00362     return true;
00363 #endif
00364 }
00365 
00366 QSize KFileMetaDataWidget::sizeHint() const
00367 {
00368     if (d->m_gridLayout == 0) {
00369         return QWidget::sizeHint();
00370     }
00371 
00372     // Calculate the required width for the labels and values
00373     int leftWidthMax = 0;
00374     int rightWidthMax = 0;
00375     int rightWidthAverage = 0;
00376     foreach (const Private::Row& row, d->m_rows) {
00377         const QWidget* valueWidget = row.value;
00378         const int rightWidth = valueWidget->sizeHint().width();
00379         rightWidthAverage += rightWidth;
00380         if (rightWidth > rightWidthMax) {
00381             rightWidthMax = rightWidth;
00382         }
00383 
00384         const int leftWidth = row.label->sizeHint().width();
00385         if (leftWidth > leftWidthMax) {
00386             leftWidthMax = leftWidth;
00387         }
00388     }
00389 
00390     // Some value widgets might return a very huge width for the size hint.
00391     // Limit the maximum width to the double width of the overall average
00392     // to assure a less messed layout.
00393     if (d->m_rows.count() > 1) {
00394         rightWidthAverage /= d->m_rows.count();
00395         if (rightWidthMax > rightWidthAverage * 2) {
00396             rightWidthMax = rightWidthAverage * 2;
00397         }
00398     }
00399 
00400     // Based on the available width calculate the required height
00401     int height = d->m_gridLayout->margin() * 2 + d->m_gridLayout->spacing() * (d->m_rows.count() - 1);
00402     foreach (const Private::Row& row, d->m_rows) {
00403         const QWidget* valueWidget = row.value;
00404         const int rowHeight = qMax(row.label->heightForWidth(leftWidthMax),
00405                                    valueWidget->heightForWidth(rightWidthMax));
00406         height += rowHeight;
00407     }
00408 
00409     const int width = d->m_gridLayout->margin() * 2 + leftWidthMax +
00410                       d->m_gridLayout->spacing() + rightWidthMax;
00411 
00412     return QSize(width, height);
00413 }
00414 
00415 bool KFileMetaDataWidget::event(QEvent* event)
00416 {
00417     return QWidget::event(event);
00418 }
00419 
00420 #include "kfilemetadatawidget.moc"

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

Skip menu "kdelibs"
  • 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
Generated for kdelibs by doxygen 1.7.5
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal