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 Wed May 2 2012 18:21:10 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed May 2 2012 18:21:10 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.