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

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • 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.3
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