[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [kde-baseapps] dolphin/src: Allow showing Nepomuk metadata inside views
From:       Peter Penz <peter.penz19 () gmail ! com>
Date:       2012-04-01 14:47:15
Message-ID: 20120401144715.0ED9BA60A9 () git ! kde ! org
[Download RAW message or body]

Git commit 270e0c3e489218ae5543c72e5ec643ba2ee9de3a by Peter Penz.
Committed on 01/04/2012 at 16:42.
Pushed by ppenz into branch 'master'.

Allow showing Nepomuk metadata inside views

Metadata like image-size, rating, comments, tags, ... can be shown
now in the view (e.g. as column in the Details mode).

Still open: The rating-information needs to be shown as stars.

In the context of this feature also the following bugs have been
fixed:
- Fix visual glitches in the header of the Details mode
- Improve the minimum column width calculation to respect also
  the headling and not only the content

BUG: 296782
FIXED-IN: 4.9.0

M  +11   -9    dolphin/src/CMakeLists.txt
M  +60   -63   dolphin/src/kitemviews/kfileitemlistwidget.cpp
M  +10   -11   dolphin/src/kitemviews/kfileitemlistwidget.h
M  +35   -35   dolphin/src/kitemviews/kfileitemmodel.cpp
M  +10   -0    dolphin/src/kitemviews/kfileitemmodel.h
M  +36   -0    dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
M  +8    -0    dolphin/src/kitemviews/kfileitemmodelrolesupdater.h
M  +20   -10   dolphin/src/kitemviews/kitemlistheaderwidget.cpp
M  +4    -0    dolphin/src/kitemviews/kitemlistheaderwidget_p.h
M  +27   -13   dolphin/src/kitemviews/kitemlistview.cpp
A  +153  -0    dolphin/src/kitemviews/knepomukrolesprovider.cpp     [License: GPL \
(v2+)] A  +66   -0    dolphin/src/kitemviews/knepomukrolesprovider_p.h     [License: \
GPL (v2+)] M  +24   -0    dolphin/src/settings/additionalinfodialog.cpp
M  +1    -0    dolphin/src/views/dolphinitemlistcontainer.cpp
M  +25   -2    dolphin/src/views/dolphinview.cpp
M  +21   -0    dolphin/src/views/dolphinviewactionhandler.cpp

http://commits.kde.org/kde-baseapps/270e0c3e489218ae5543c72e5ec643ba2ee9de3a

diff --git a/dolphin/src/CMakeLists.txt b/dolphin/src/CMakeLists.txt
index 2ab5e9c..45d7c49 100644
--- a/dolphin/src/CMakeLists.txt
+++ b/dolphin/src/CMakeLists.txt
@@ -67,6 +67,13 @@ set(dolphinprivate_LIB_SRCS
     views/zoomlevelinfo.cpp
 )
 
+if (Nepomuk_FOUND)
+    set(dolphinprivate_LIB_SRCS
+        ${dolphinprivate_LIB_SRCS}
+        kitemviews/knepomukrolesprovider.cpp
+    )
+endif (Nepomuk_FOUND)
+
 kde4_add_kcfg_files(dolphinprivate_LIB_SRCS
     settings/dolphin_compactmodesettings.kcfgc
     settings/dolphin_directoryviewpropertysettings.kcfgc
@@ -80,18 +87,16 @@ kde4_add_library(dolphinprivate SHARED \
${dolphinprivate_LIB_SRCS})  
 target_link_libraries(dolphinprivate ${KDE4_KFILE_LIBS} konq \
${KDE4_KNEWSTUFF3_LIBS})  if (Nepomuk_FOUND)
-  target_link_libraries(dolphinprivate ${NEPOMUK_LIBRARIES} \
${NEPOMUK_QUERY_LIBRARIES} nepomukutils ${SOPRANO_LIBRARIES}) +    \
target_link_libraries(dolphinprivate ${NEPOMUK_LIBRARIES} ${NEPOMUK_QUERY_LIBRARIES} \
nepomukutils ${SOPRANO_LIBRARIES})  endif (Nepomuk_FOUND)
+
 if(X11_Xrender_FOUND)
-  target_link_libraries(dolphinprivate ${X11_Xrender_LIB} )
+    target_link_libraries(dolphinprivate ${X11_Xrender_LIB} )
 endif(X11_Xrender_FOUND)
 
-
-
 set_target_properties(dolphinprivate PROPERTIES VERSION ${GENERIC_LIB_VERSION} \
SOVERSION ${GENERIC_LIB_SOVERSION} )  install(TARGETS dolphinprivate  \
${INSTALL_TARGETS_DEFAULT_ARGS})  
-
 ##########################################
 
 set(dolphinpart_SRCS
@@ -165,10 +170,7 @@ kde4_add_kcfg_files(dolphin_SRCS
 )
 
 if(Nepomuk_FOUND)
-    set(dolphin_SRCS
-        ${dolphin_SRCS}
-        panels/search/searchpanel.cpp
-    )
+    set(dolphin_SRCS ${dolphin_SRCS} panels/search/searchpanel.cpp)
 endif(Nepomuk_FOUND)
 
 if(NOT WIN32)
diff --git a/dolphin/src/kitemviews/kfileitemlistwidget.cpp \
b/dolphin/src/kitemviews/kfileitemlistwidget.cpp index 022f3b4..4511b3b 100644
--- a/dolphin/src/kitemviews/kfileitemlistwidget.cpp
+++ b/dolphin/src/kitemviews/kfileitemlistwidget.cpp
@@ -55,8 +55,7 @@ KFileItemListWidget::KFileItemListWidget(QGraphicsItem* parent) :
     m_scaledPixmapSize(),
     m_iconRect(),
     m_hoverPixmap(),
-    m_textPos(),
-    m_text(),
+    m_textInfo(),
     m_textRect(),
     m_sortedVisibleRoles(),
     m_expansionArea(),
@@ -64,14 +63,12 @@ KFileItemListWidget::KFileItemListWidget(QGraphicsItem* parent) :
     m_additionalInfoTextColor(),
     m_overlay()
 {
-    for (int i = 0; i < TextIdCount; ++i) {
-        m_text[i].setTextFormat(Qt::PlainText);
-        m_text[i].setPerformanceHint(QStaticText::AggressiveCaching);
-    }
 }
 
 KFileItemListWidget::~KFileItemListWidget()
 {
+    qDeleteAll(m_textInfo);
+    m_textInfo.clear();
 }
 
 void KFileItemListWidget::setLayout(Layout layout)
@@ -131,7 +128,8 @@ void KFileItemListWidget::paint(QPainter* painter, const \
QStyleOptionGraphicsIte  
     painter->setFont(itemListStyleOption.font);
     painter->setPen(textColor());
-    painter->drawStaticText(m_textPos[Name], m_text[Name]);
+    const TextInfo* textInfo = m_textInfo.value("name");
+    painter->drawStaticText(textInfo->pos, textInfo->staticText);
 
     bool clipAdditionalInfoBounds = false;
     if (m_supportsItemExpanding) {
@@ -139,7 +137,7 @@ void KFileItemListWidget::paint(QPainter* painter, const \
                QStyleOptionGraphicsIte
         // with the icon. This can happen if the user has minimized the width
         // of the name-column to a very small value.
         const qreal minX = m_pixmapPos.x() + m_pixmap.width() + 4 * \
                itemListStyleOption.padding;
-        if (m_textPos[Name].x() + columnWidth("name") > minX) {
+        if (textInfo->pos.x() + columnWidth("name") > minX) {
             clipAdditionalInfoBounds = true;
             painter->save();
             painter->setClipRect(minX, 0, size().width() - minX, size().height(), \
Qt::IntersectClip); @@ -148,8 +146,10 @@ void KFileItemListWidget::paint(QPainter* \
painter, const QStyleOptionGraphicsIte  
     painter->setPen(m_additionalInfoTextColor);
     painter->setFont(itemListStyleOption.font);
-    for (int i = Name + 1; i < TextIdCount; ++i) {
-        painter->drawStaticText(m_textPos[i], m_text[i]);
+
+    for (int i = 1; i < m_sortedVisibleRoles.count(); ++i) {
+        const TextInfo* textInfo = m_textInfo.value(m_sortedVisibleRoles[i]);
+        painter->drawStaticText(textInfo->pos, textInfo->staticText);
     }
 
     if (clipAdditionalInfoBounds) {
@@ -579,7 +579,8 @@ void KFileItemListWidget::updatePixmapCache()
 
     int scaledIconSize = 0;
     if (iconOnTop) {
-        scaledIconSize = static_cast<int>(m_textPos[Name].y() - 2 * padding);
+        const TextInfo* textInfo = m_textInfo.value("name");
+        scaledIconSize = static_cast<int>(textInfo->pos.y() - 2 * padding);
     } else {
         const int textRowsCount = (m_layout == CompactLayout) ? \
                visibleRoles().count() : 1;
         const qreal requiredTextHeight = textRowsCount * \
option.fontMetrics.height(); @@ -599,7 +600,8 @@ void \
                KFileItemListWidget::updatePixmapCache()
         m_pixmapPos.setY(padding + scaledIconSize - m_scaledPixmapSize.height());
     } else {
         // Center horizontally and vertically within the icon-area
-        m_pixmapPos.setX(m_textPos[Name].x() - 2 * padding
+        const TextInfo* textInfo = m_textInfo.value("name");
+        m_pixmapPos.setX(textInfo->pos.x() - 2 * padding
                          - (scaledIconSize + m_scaledPixmapSize.width()) / 2);
         m_pixmapPos.setY(padding
                          + (scaledIconSize - m_scaledPixmapSize.height()) / 2);
@@ -641,9 +643,14 @@ void KFileItemListWidget::updateTextsCache()
         break;
     }
 
-    for (int i = 0; i < TextIdCount; ++i) {
-        m_text[i].setText(QString());
-        m_text[i].setTextOption(textOption);
+    qDeleteAll(m_textInfo);
+    m_textInfo.clear();
+    for (int i = 0; i < m_sortedVisibleRoles.count(); ++i) {
+        TextInfo* textInfo = new TextInfo();
+        textInfo->staticText.setTextFormat(Qt::PlainText);
+        textInfo->staticText.setPerformanceHint(QStaticText::AggressiveCaching);
+        textInfo->staticText.setTextOption(textOption);
+        m_textInfo.insert(m_sortedVisibleRoles[i], textInfo);
     }
 
     switch (m_layout) {
@@ -676,15 +683,16 @@ void KFileItemListWidget::updateIconsLayoutTextCache()
 
     // Initialize properties for the "name" role. It will be used as anchor
     // for initializing the position of the other roles.
-    m_text[Name].setText(KStringHandler::preProcessWrap(values["name"].toString()));
+    TextInfo* nameTextInfo = m_textInfo.value("name");
+    nameTextInfo->staticText.setText(KStringHandler::preProcessWrap(values["name"].toString()));
  
     // Calculate the number of lines required for the name and the required width
     int textLinesCountForName = 0;
     qreal requiredWidthForName = 0;
     QTextLine line;
 
-    QTextLayout layout(m_text[Name].text(), option.font);
-    layout.setTextOption(m_text[Name].textOption());
+    QTextLayout layout(nameTextInfo->staticText.text(), option.font);
+    layout.setTextOption(nameTextInfo->staticText.textOption());
     layout.beginLayout();
     while ((line = layout.createLine()).isValid()) {
         line.setLineWidth(maxWidth);
@@ -698,28 +706,28 @@ void KFileItemListWidget::updateIconsLayoutTextCache()
     const int additionalRolesCount = qMax(visibleRoles().count() - 1, 0);
     textLinesCount += additionalRolesCount;
 
-    m_text[Name].setTextWidth(maxWidth);
-    m_textPos[Name] = QPointF(padding, widgetHeight - textLinesCount * fontHeight - \
padding); +    nameTextInfo->staticText.setTextWidth(maxWidth);
+    nameTextInfo->pos = QPointF(padding, widgetHeight - textLinesCount * fontHeight \
- padding);  m_textRect = QRectF(padding + (maxWidth - requiredWidthForName) / 2,
-                        m_textPos[Name].y(),
+                        nameTextInfo->pos.y(),
                         requiredWidthForName,
                         textLinesCountForName * fontHeight);
 
     // Calculate the position for each additional information
-    qreal y = m_textPos[Name].y() + textLinesCountForName * fontHeight;
+    qreal y = nameTextInfo->pos.y() + textLinesCountForName * fontHeight;
     foreach (const QByteArray& role, m_sortedVisibleRoles) {
-        const TextId textId = roleTextId(role);
-        if (textId == Name) {
+        if (role == "name") {
             continue;
         }
 
         const QString text = roleText(role, values);
-        m_text[textId].setText(text);
+        TextInfo* textInfo = m_textInfo.value(role);
+        textInfo->staticText.setText(text);
 
         qreal requiredWidth = 0;
 
         QTextLayout layout(text, option.font);
-        layout.setTextOption(m_text[textId].textOption());
+        layout.setTextOption(textInfo->staticText.textOption());
         layout.beginLayout();
         QTextLine textLine = layout.createLine();
         if (textLine.isValid()) {
@@ -731,13 +739,13 @@ void KFileItemListWidget::updateIconsLayoutTextCache()
                 // not get elided although it does not fit into the given width. As \
workaround  // the padding is substracted.
                 const QString elidedText = option.fontMetrics.elidedText(text, \
                Qt::ElideRight, maxWidth - padding);
-                m_text[textId].setText(elidedText);
+                textInfo->staticText.setText(elidedText);
             }
         }
         layout.endLayout();
 
-        m_textPos[textId] = QPointF(padding, y);
-        m_text[textId].setTextWidth(maxWidth);
+        textInfo->pos = QPointF(padding, y);
+        textInfo->staticText.setTextWidth(maxWidth);
 
         const QRectF textRect(padding + (maxWidth - requiredWidth) / 2, y, \
requiredWidth, fontHeight);  m_textRect |= textRect;
@@ -768,20 +776,19 @@ void KFileItemListWidget::updateCompactLayoutTextCache()
     qreal y = (widgetHeight - textLinesHeight) / 2;
     const qreal maxWidth = size().width() - x - option.padding;
     foreach (const QByteArray& role, m_sortedVisibleRoles) {
-        const TextId textId = roleTextId(role);
-
         const QString text = roleText(role, values);
-        m_text[textId].setText(text);
+        TextInfo* textInfo = m_textInfo.value(role);
+        textInfo->staticText.setText(text);
 
         qreal requiredWidth = option.fontMetrics.width(text);
         if (requiredWidth > maxWidth) {
             requiredWidth = maxWidth;
             const QString elidedText = option.fontMetrics.elidedText(text, \
                Qt::ElideRight, maxWidth);
-            m_text[textId].setText(elidedText);
+            textInfo->staticText.setText(elidedText);
         }
 
-        m_textPos[textId] = QPointF(x, y);
-        m_text[textId].setTextWidth(maxWidth);
+        textInfo->pos = QPointF(x, y);
+        textInfo->staticText.setTextWidth(maxWidth);
 
         maximumRequiredTextWidth = qMax(maximumRequiredTextWidth, requiredWidth);
 
@@ -820,7 +827,7 @@ void KFileItemListWidget::updateDetailsLayoutTextCache()
     const qreal y = qMax(qreal(option.padding), (widgetHeight - fontHeight) / 2);
 
     foreach (const QByteArray& role, m_sortedVisibleRoles) {
-        const TextId textId = roleTextId(role);
+        const RoleType type = roleType(role);
 
         QString text = roleText(role, values);
 
@@ -828,7 +835,7 @@ void KFileItemListWidget::updateDetailsLayoutTextCache()
         qreal requiredWidth = option.fontMetrics.width(text);
         const qreal roleWidth = columnWidth(role);
         qreal availableTextWidth = roleWidth - 2 * columnPadding;
-        if (textId == Name) {
+        if (type == Name) {
             availableTextWidth -= firstColumnInc;
         }
 
@@ -837,16 +844,17 @@ void KFileItemListWidget::updateDetailsLayoutTextCache()
             requiredWidth = option.fontMetrics.width(text);
         }
 
-        m_text[textId].setText(text);
-        m_textPos[textId] = QPointF(x + columnPadding, y);
+        TextInfo* textInfo = m_textInfo.value(role);
+        textInfo->staticText.setText(text);
+        textInfo->pos = QPointF(x + columnPadding, y);
         x += roleWidth;
 
-        switch (textId) {
+        switch (type) {
         case Name: {
             const qreal textWidth = option.extendedSelectionRegion
-                                    ? size().width() - m_textPos[textId].x()
+                                    ? size().width() - textInfo->pos.x()
                                     : requiredWidth + 2 * option.padding;
-            m_textRect = QRectF(m_textPos[textId].x() - option.padding, 0,
+            m_textRect = QRectF(textInfo->pos.x() - option.padding, 0,
                                 textWidth, size().height());
 
             // The column after the name should always be aligned on the same \
x-position independent @@ -856,7 +864,7 @@ void \
KFileItemListWidget::updateDetailsLayoutTextCache()  }
         case Size:
             // The values for the size should be right aligned
-            m_textPos[textId].rx() += roleWidth - requiredWidth - 2 * columnPadding;
+            textInfo->pos.rx() += roleWidth - requiredWidth - 2 * columnPadding;
             break;
 
         default:
@@ -976,22 +984,16 @@ void KFileItemListWidget::applyHiddenEffect(QPixmap& pixmap)
     KIconEffect::semiTransparent(pixmap);
 }
 
-KFileItemListWidget::TextId KFileItemListWidget::roleTextId(const QByteArray& role)
+KFileItemListWidget::RoleType KFileItemListWidget::roleType(const QByteArray& role)
 {
-    static QHash<QByteArray, TextId> rolesHash;
+    static QHash<QByteArray, RoleType> rolesHash;
     if (rolesHash.isEmpty()) {
         rolesHash.insert("name", Name);
         rolesHash.insert("size", Size);
         rolesHash.insert("date", Date);
-        rolesHash.insert("permissions", Permissions);
-        rolesHash.insert("owner", Owner);
-        rolesHash.insert("group", Group);
-        rolesHash.insert("type", Type);
-        rolesHash.insert("destination", Destination);
-        rolesHash.insert("path", Path);
     }
 
-    return rolesHash.value(role);
+    return rolesHash.value(role, Generic);
 }
 
 QString KFileItemListWidget::roleText(const QByteArray& role, const \
QHash<QByteArray, QVariant>& values) @@ -999,17 +1001,7 @@ QString \
KFileItemListWidget::roleText(const QByteArray& role, const QHash<QByteA  QString \
text;  const QVariant roleValue = values.value(role);
 
-    switch (roleTextId(role)) {
-    case Name:
-    case Permissions:
-    case Owner:
-    case Group:
-    case Type:
-    case Destination:
-    case Path:
-        text = roleValue.toString();
-        break;
-
+    switch (roleType(role)) {
     case Size: {
         if (values.value("isDir").toBool()) {
             // The item represents a directory. Show the number of sub directories
@@ -1038,6 +1030,11 @@ QString KFileItemListWidget::roleText(const QByteArray& role, \
const QHash<QByteA  break;
     }
 
+    case Name:
+    case Generic:
+        text = roleValue.toString();
+        break;
+
     default:
         Q_ASSERT(false);
         break;
diff --git a/dolphin/src/kitemviews/kfileitemlistwidget.h \
b/dolphin/src/kitemviews/kfileitemlistwidget.h index 76d0900..d68a224 100644
--- a/dolphin/src/kitemviews/kfileitemlistwidget.h
+++ b/dolphin/src/kitemviews/kfileitemlistwidget.h
@@ -109,17 +109,11 @@ private slots:
     void slotCutItemsChanged();
 
 private:
-    enum TextId {
+    enum RoleType {
         Name,
         Size,
         Date,
-        Permissions,
-        Owner,
-        Group,
-        Type,
-        Destination,
-        Path,
-        TextIdCount // Mandatory last entry
+        Generic  // Mandatory last entry
     };
 
     void triggerCacheRefreshing();
@@ -139,7 +133,7 @@ private:
     static QPixmap pixmapForIcon(const QString& name, int size);
     static void applyCutEffect(QPixmap& pixmap);
     static void applyHiddenEffect(QPixmap& pixmap);
-    static TextId roleTextId(const QByteArray& role);
+    static RoleType roleType(const QByteArray& role);
 
     /**
      * @return Shown string for the role \p role of the item with the values \p \
values. @@ -164,8 +158,13 @@ private:
     QRectF m_iconRect;          // Cache for KItemListWidget::iconRect()
     QPixmap m_hoverPixmap;      // Cache for modified m_pixmap when hovering the \
item  
-    QPointF m_textPos[TextIdCount];
-    QStaticText m_text[TextIdCount];
+    struct TextInfo
+    {
+        QPointF pos;
+        QStaticText staticText;
+    };
+    QHash<QByteArray, TextInfo*> m_textInfo;
+
     QRectF m_textRect;
 
     QList<QByteArray> m_sortedVisibleRoles;
diff --git a/dolphin/src/kitemviews/kfileitemmodel.cpp \
b/dolphin/src/kitemviews/kfileitemmodel.cpp index efc7b32..1d7366c 100644
--- a/dolphin/src/kitemviews/kfileitemmodel.cpp
+++ b/dolphin/src/kitemviews/kfileitemmodel.cpp
@@ -274,19 +274,8 @@ QList<QPair<int, QVariant> > KFileItemModel::groups() const
         case SizeRole:        m_groups = sizeRoleGroups(); break;
         case DateRole:        m_groups = dateRoleGroups(); break;
         case PermissionsRole: m_groups = permissionRoleGroups(); break;
-        case OwnerRole:       m_groups = genericStringRoleGroups("owner"); break;
-        case GroupRole:       m_groups = genericStringRoleGroups("group"); break;
-        case TypeRole:        m_groups = genericStringRoleGroups("type"); break;
-        case DestinationRole: m_groups = genericStringRoleGroups("destination"); \
                break;
-        case PathRole:        m_groups = genericStringRoleGroups("path"); break;
-        case CommentRole:     m_groups = genericStringRoleGroups("comment"); break;
-        case TagsRole:        m_groups = genericStringRoleGroups("tags"); break;
         case RatingRole:      m_groups = ratingRoleGroups(); break;
-        case NoRole:          break;
-        case IsDirRole:       break;
-        case IsExpandedRole:  break;
-        case ExpandedParentsCountRole: break;
-        default:                 Q_ASSERT(false); break;
+        default:              m_groups = genericStringRoleGroups(sortRole()); break;
         }
 
 #ifdef KFILEITEMMODEL_DEBUG
@@ -558,6 +547,8 @@ QList<KFileItemModel::RoleInfo> \
KFileItemModel::rolesInformation()  info.role = map[i].role;
                 info.translation = map[i].roleTranslation;
                 info.group = map[i].groupTranslation;
+                info.requiresNepomuk = map[i].requiresNepomuk;
+                info.requiresIndexer = map[i].requiresIndexer;
                 rolesInfo.append(info);
             }
         }
@@ -1344,6 +1335,15 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const \
ItemData* b) const  break;
     }
 
+    case ImageSizeRole: {
+        // Alway use a natural comparing to interpret the numbers of a string like
+        // "1600 x 1200" for having a correct sorting.
+        result = KStringHandler::naturalCompare(a->values.value("imageSize").toString(),
 +                                                \
b->values.value("imageSize").toString(), +                                            \
Qt::CaseSensitive); +        break;
+    }
+
     case PermissionsRole:
     case OwnerRole:
     case GroupRole:
@@ -1953,29 +1953,29 @@ KFileItemList KFileItemModel::childItems(const KFileItem& \
item) const  const KFileItemModel::RoleInfoMap* KFileItemModel::rolesInfoMap(int& \
count)  {
     static const RoleInfoMap rolesInfoMap[] = {
-    //    role           roleType         role translation                           \
                group translation
-        { 0,             NoRole,          0, 0,                                      \
                0, 0 },
-        { "name",        NameRole,        I18N_NOOP2_NOSTRIP("@label", "Name"),      \
                0, 0 },
-        { "size",        SizeRole,        I18N_NOOP2_NOSTRIP("@label", "Size"),      \
                0, 0 },
-        { "date",        DateRole,        I18N_NOOP2_NOSTRIP("@label", "Date"),      \
                0, 0 },
-        { "type",        TypeRole,        I18N_NOOP2_NOSTRIP("@label", "Type"),      \
                0, 0 },
-        { "rating",      RatingRole,      I18N_NOOP2_NOSTRIP("@label", "Rating"),    \
                0, 0 },
-        { "tags",        TagsRole,        I18N_NOOP2_NOSTRIP("@label", "Tags"),      \
                0, 0 },
-        { "comment",     CommentRole,     I18N_NOOP2_NOSTRIP("@label", "Comment"),   \
                0, 0 },
-        { "wordCount",   WordCountRole,   I18N_NOOP2_NOSTRIP("@label", "Word \
                Count"),       I18N_NOOP2_NOSTRIP("@label", "Document") },
-        { "lineCount",   LineCountRole,   I18N_NOOP2_NOSTRIP("@label", "Line \
                Count"),       I18N_NOOP2_NOSTRIP("@label", "Document") },
-        { "imageSize",   ImageSizeRole,   I18N_NOOP2_NOSTRIP("@label", "Image \
                Size"),       I18N_NOOP2_NOSTRIP("@label", "Image") },
-        { "orientation", OrientationRole, I18N_NOOP2_NOSTRIP("@label", \
                "Orientation"),      I18N_NOOP2_NOSTRIP("@label", "Image") },
-        { "artist",      ArtistRole,      I18N_NOOP2_NOSTRIP("@label", "Artist"),    \
                I18N_NOOP2_NOSTRIP("@label", "Music") },
-        { "album",       AlbumRole,       I18N_NOOP2_NOSTRIP("@label", "Album"),     \
                I18N_NOOP2_NOSTRIP("@label", "Music") },
-        { "duration",    DurationRole,    I18N_NOOP2_NOSTRIP("@label", "Duration"),  \
                I18N_NOOP2_NOSTRIP("@label", "Music") },
-        { "track",       TrackRole,       I18N_NOOP2_NOSTRIP("@label", "Track"),     \
                I18N_NOOP2_NOSTRIP("@label", "Music") },
-        { "path",        PathRole,        I18N_NOOP2_NOSTRIP("@label", "Path"),      \
                I18N_NOOP2_NOSTRIP("@label", "Other") },
-        { "destination", DestinationRole, I18N_NOOP2_NOSTRIP("@label", "Link \
                Destination"), I18N_NOOP2_NOSTRIP("@label", "Other") },
-        { "copiedFrom",  CopiedFromRole,  I18N_NOOP2_NOSTRIP("@label", "Copied \
                From"),      I18N_NOOP2_NOSTRIP("@label", "Other") },
-        { "permissions", PermissionsRole, I18N_NOOP2_NOSTRIP("@label", \
                "Permissions"),      I18N_NOOP2_NOSTRIP("@label", "Other") },
-        { "owner",       OwnerRole,       I18N_NOOP2_NOSTRIP("@label", "Owner"),     \
                I18N_NOOP2_NOSTRIP("@label", "Other") },
-        { "group",       GroupRole,       I18N_NOOP2_NOSTRIP("@label", "Group"),     \
I18N_NOOP2_NOSTRIP("@label", "Other") }, +    //  | role         | roleType       | \
role translation                                | group translation           | \
requires Nepomuk | requires indexer +        { 0,             NoRole,          0, 0,  \
0, 0,                                     false, false }, +        { "name",        \
NameRole,        I18N_NOOP2_NOSTRIP("@label", "Name"),             0, 0,              \
false, false }, +        { "size",        SizeRole,        \
I18N_NOOP2_NOSTRIP("@label", "Size"),             0, 0,                               \
false, false }, +        { "date",        DateRole,        \
I18N_NOOP2_NOSTRIP("@label", "Date"),             0, 0,                               \
false, false }, +        { "type",        TypeRole,        \
I18N_NOOP2_NOSTRIP("@label", "Type"),             0, 0,                               \
false, false }, +        { "rating",      RatingRole,      \
I18N_NOOP2_NOSTRIP("@label", "Rating"),           0, 0,                               \
true,  false }, +        { "tags",        TagsRole,        \
I18N_NOOP2_NOSTRIP("@label", "Tags"),             0, 0,                               \
true,  false }, +        { "comment",     CommentRole,     \
I18N_NOOP2_NOSTRIP("@label", "Comment"),          0, 0,                               \
true,  false }, +        { "wordCount",   WordCountRole,   \
I18N_NOOP2_NOSTRIP("@label", "Word Count"),       I18N_NOOP2_NOSTRIP("@label", \
"Document"), true,  true  }, +        { "lineCount",   LineCountRole,   \
I18N_NOOP2_NOSTRIP("@label", "Line Count"),       I18N_NOOP2_NOSTRIP("@label", \
"Document"), true,  true  }, +        { "imageSize",   ImageSizeRole,   \
I18N_NOOP2_NOSTRIP("@label", "Image Size"),       I18N_NOOP2_NOSTRIP("@label", \
"Image"),    true,  true  }, +        { "orientation", OrientationRole, \
I18N_NOOP2_NOSTRIP("@label", "Orientation"),      I18N_NOOP2_NOSTRIP("@label", \
"Image"),    true,  true  }, +        { "artist",      ArtistRole,      \
I18N_NOOP2_NOSTRIP("@label", "Artist"),           I18N_NOOP2_NOSTRIP("@label", \
"Music"),    true,  true  }, +        { "album",       AlbumRole,       \
I18N_NOOP2_NOSTRIP("@label", "Album"),            I18N_NOOP2_NOSTRIP("@label", \
"Music"),    true,  true  }, +        { "duration",    DurationRole,    \
I18N_NOOP2_NOSTRIP("@label", "Duration"),         I18N_NOOP2_NOSTRIP("@label", \
"Music"),    true,  true  }, +        { "track",       TrackRole,       \
I18N_NOOP2_NOSTRIP("@label", "Track"),            I18N_NOOP2_NOSTRIP("@label", \
"Music"),    true,  true  }, +        { "path",        PathRole,        \
I18N_NOOP2_NOSTRIP("@label", "Path"),             I18N_NOOP2_NOSTRIP("@label", \
"Other"),    false, false }, +        { "destination", DestinationRole, \
I18N_NOOP2_NOSTRIP("@label", "Link Destination"), I18N_NOOP2_NOSTRIP("@label", \
"Other"),    false, false }, +        { "copiedFrom",  CopiedFromRole,  \
I18N_NOOP2_NOSTRIP("@label", "Copied From"),      I18N_NOOP2_NOSTRIP("@label", \
"Other"),    true,  false }, +        { "permissions", PermissionsRole, \
I18N_NOOP2_NOSTRIP("@label", "Permissions"),      I18N_NOOP2_NOSTRIP("@label", \
"Other"),    false, false }, +        { "owner",       OwnerRole,       \
I18N_NOOP2_NOSTRIP("@label", "Owner"),            I18N_NOOP2_NOSTRIP("@label", \
"Other"),    false, false }, +        { "group",       GroupRole,       \
I18N_NOOP2_NOSTRIP("@label", "User Group"),       I18N_NOOP2_NOSTRIP("@label", \
"Other"),    false, false },  };
 
     count = sizeof(rolesInfoMap) / sizeof(RoleInfoMap);
diff --git a/dolphin/src/kitemviews/kfileitemmodel.h \
b/dolphin/src/kitemviews/kfileitemmodel.h index 0b1885a..4824dec 100644
--- a/dolphin/src/kitemviews/kfileitemmodel.h
+++ b/dolphin/src/kitemviews/kfileitemmodel.h
@@ -162,8 +162,16 @@ public:
     {   QByteArray role;
         QString translation;
         QString group;
+        bool requiresNepomuk;
+        bool requiresIndexer;
     };
 
+    /**
+     * @return Provides static information for all available roles that
+     *         are supported by KFileItemModel. Some roles can only be
+     *         determined if Nepomuk is enabled and/or the Nepomuk
+     *         indexing is enabled.
+     */
     static QList<RoleInfo> rolesInformation();
 
 signals:
@@ -344,6 +352,8 @@ private:
         const char* const roleTranslation;
         const char* const groupTranslationContext;
         const char* const groupTranslation;
+        const bool requiresNepomuk;
+        const bool requiresIndexer;
     };
 
     /**
diff --git a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp \
b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp index 7b0d75d..efcf6b4 100644
--- a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
+++ b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp
@@ -33,6 +33,10 @@
 #include <QElapsedTimer>
 #include <QTimer>
 
+#ifdef HAVE_NEPOMUK
+    #include "knepomukrolesprovider_p.h"
+#endif
+
 // Required includes for subItemsCount():
 #ifdef Q_WS_WIN
     #include <QDir>
@@ -74,6 +78,10 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* \
model, QO  m_previewJobs(),
     m_changedItemsTimer(0),
     m_changedItems()
+  #ifdef HAVE_NEPOMUK
+  , m_resolveNepomukRoles(false)
+  #endif
+
 {
     Q_ASSERT(model);
 
@@ -219,6 +227,23 @@ void KFileItemModelRolesUpdater::setRoles(const \
QSet<QByteArray>& roles)  if (m_roles != roles) {
         m_roles = roles;
 
+#ifdef HAVE_NEPOMUK
+        // Check whether there is at least one role that must be resolved
+        // with the help of Nepomuk. If this is the case, m_resolveNepomukRoles
+        // will be set to true and the (quite expensive) resolving will be done
+        // in KFileItemModelRolesUpdater::rolesData().
+        const KNepomukRolesProvider& rolesProvider = \
KNepomukRolesProvider::instance(); +        m_resolveNepomukRoles = false;
+        QSetIterator<QByteArray> it(roles);
+        while (it.hasNext()) {
+            const QByteArray& role = it.next();
+            if (rolesProvider.isNepomukRole(role)) {
+                m_resolveNepomukRoles = true;
+                break;
+            }
+        }
+#endif
+
         if (m_paused) {
             m_rolesChangedDuringPausing = true;
         } else {
@@ -754,6 +779,17 @@ QHash<QByteArray, QVariant> \
KFileItemModelRolesUpdater::rolesData(const KFileIte  
     data.insert("iconOverlays", item.overlays());
 
+#ifdef HAVE_NEPOMUK
+    if (m_resolveNepomukRoles) {
+        const KNepomukRolesProvider& rolesProvider = \
KNepomukRolesProvider::instance(); +        QHashIterator<QByteArray, QVariant> \
it(rolesProvider.roleValues(item.url(), m_roles)); +        while (it.hasNext()) {
+            it.next();
+            data.insert(it.key(), it.value());
+        }
+    }
+#endif
+
     return data;
 }
 
diff --git a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h \
b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h index 4db2dde..47255b0 100644
--- a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h
+++ b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h
@@ -20,6 +20,7 @@
 #ifndef KFILEITEMMODELROLESUPDATER_H
 #define KFILEITEMMODELROLESUPDATER_H
 
+#include <config-nepomuk.h>
 #include <libdolphin_export.h>
 
 #include <KFileItem>
@@ -204,6 +205,13 @@ private:
     // of time.
     QTimer* m_changedItemsTimer;
     QSet<KFileItem> m_changedItems;
+
+#ifdef HAVE_NEPOMUK
+    // True if roles must be resolved with the help of Nepomuk inside
+    // KFileItemModelRolesUpdater::rolesData().
+    bool m_resolveNepomukRoles;
+#endif
+
 };
 
 #endif
diff --git a/dolphin/src/kitemviews/kitemlistheaderwidget.cpp \
b/dolphin/src/kitemviews/kitemlistheaderwidget.cpp index d3a8f00..2105b67 100644
--- a/dolphin/src/kitemviews/kitemlistheaderwidget.cpp
+++ b/dolphin/src/kitemviews/kitemlistheaderwidget.cpp
@@ -34,6 +34,7 @@ KItemListHeaderWidget::KItemListHeaderWidget(QGraphicsWidget* \
parent) :  QGraphicsWidget(parent),
     m_automaticColumnResizing(true),
     m_model(0),
+    m_offset(0),
     m_columns(),
     m_columnWidths(),
     m_preferredColumnWidths(),
@@ -48,10 +49,6 @@ KItemListHeaderWidget::KItemListHeaderWidget(QGraphicsWidget* \
parent) :  m_movingRole.index = -1;
 
     setAcceptHoverEvents(true);
-
-    QStyleOptionHeader option;
-    const QSize headerSize = style()->sizeFromContents(QStyle::CT_HeaderSection, \
                &option, QSize());
-    resize(0, headerSize.height());
 }
 
 KItemListHeaderWidget::~KItemListHeaderWidget()
@@ -142,6 +139,19 @@ qreal KItemListHeaderWidget::preferredColumnWidth(const \
QByteArray& role) const  return m_preferredColumnWidths.value(role);
 }
 
+void KItemListHeaderWidget::setOffset(qreal offset)
+{
+    if (m_offset != offset) {
+        m_offset = offset;
+        update();
+    }
+}
+
+qreal KItemListHeaderWidget::offset() const
+{
+    return m_offset;
+}
+
 qreal KItemListHeaderWidget::minimumColumnWidth() const
 {
     QFontMetricsF fontMetrics(font());
@@ -161,7 +171,7 @@ void KItemListHeaderWidget::paint(QPainter* painter, const \
QStyleOptionGraphicsI  painter->setFont(font());
     painter->setPen(palette().text().color());
 
-    qreal x = 0;
+    qreal x = -m_offset;
     int orderIndex = 0;
     foreach (const QByteArray& role, m_columns) {
         const qreal roleWidth = m_columnWidths.value(role);
@@ -265,7 +275,7 @@ void \
KItemListHeaderWidget::mouseMoveEvent(QGraphicsSceneMouseEvent* event)  } else {
                 m_movingRole.pixmap = createRolePixmap(roleIndex);
 
-                qreal roleX = 0;
+                qreal roleX = -m_offset;
                 for (int i = 0; i < roleIndex; ++i) {
                     const QByteArray role = m_columns[i];
                     roleX += m_columnWidths.value(role);
@@ -429,7 +439,7 @@ int KItemListHeaderWidget::roleIndexAt(const QPointF& pos) const
 {
     int index = -1;
 
-    qreal x = 0;
+    qreal x = -m_offset;
     foreach (const QByteArray& role, m_columns) {
         ++index;
         x += m_columnWidths.value(role);
@@ -443,7 +453,7 @@ int KItemListHeaderWidget::roleIndexAt(const QPointF& pos) const
 
 bool KItemListHeaderWidget::isAboveRoleGrip(const QPointF& pos, int roleIndex) const
 {
-    qreal x = 0;
+    qreal x = -m_offset;
     for (int i = 0; i <= roleIndex; ++i) {
         const QByteArray role = m_columns[i];
         x += m_columnWidths.value(role);
@@ -484,7 +494,7 @@ int KItemListHeaderWidget::targetOfMovingRole() const
     const int movingRight = movingLeft + movingWidth - 1;
 
     int targetIndex = 0;
-    qreal targetLeft = 0;
+    qreal targetLeft = -m_offset;
     while (targetIndex < m_columns.count()) {
         const QByteArray role = m_columns[targetIndex];
         const qreal targetWidth = m_columnWidths.value(role);
@@ -510,7 +520,7 @@ int KItemListHeaderWidget::targetOfMovingRole() const
 
 qreal KItemListHeaderWidget::roleXPosition(const QByteArray& role) const
 {
-    qreal x = 0;
+    qreal x = -m_offset;
     foreach (const QByteArray& visibleRole, m_columns) {
         if (visibleRole == role) {
             return x;
diff --git a/dolphin/src/kitemviews/kitemlistheaderwidget_p.h \
b/dolphin/src/kitemviews/kitemlistheaderwidget_p.h index e271060..f8bba97 100644
--- a/dolphin/src/kitemviews/kitemlistheaderwidget_p.h
+++ b/dolphin/src/kitemviews/kitemlistheaderwidget_p.h
@@ -59,6 +59,9 @@ public:
     void setPreferredColumnWidth(const QByteArray& role, qreal width);
     qreal preferredColumnWidth(const QByteArray& role) const;
 
+    void setOffset(qreal offset);
+    qreal offset() const;
+
     qreal minimumColumnWidth() const;
 
     virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, \
QWidget* widget = 0); @@ -144,6 +147,7 @@ private:
 
     bool m_automaticColumnResizing;
     KItemModelBase* m_model;
+    qreal m_offset;
     QList<QByteArray> m_columns;
     QHash<QByteArray, qreal> m_columnWidths;
     QHash<QByteArray, qreal> m_preferredColumnWidths;
diff --git a/dolphin/src/kitemviews/kitemlistview.cpp \
b/dolphin/src/kitemviews/kitemlistview.cpp index 8a18991..ddc65c3 100644
--- a/dolphin/src/kitemviews/kitemlistview.cpp
+++ b/dolphin/src/kitemviews/kitemlistview.cpp
@@ -237,7 +237,7 @@ void KItemListView::setItemOffset(qreal offset)
 
     m_layouter->setItemOffset(offset);
     if (m_headerWidget->isVisible()) {
-        m_headerWidget->setPos(-offset, 0);
+        m_headerWidget->setOffset(offset);
     }
 
     // Don't check whether the m_layoutTimer is active: Changing the
@@ -418,6 +418,7 @@ void KItemListView::setGeometry(const QRectF& rect)
 
     const QSizeF newSize = rect.size();
     if (m_itemSize.isEmpty()) {
+        m_headerWidget->resize(rect.width(), m_headerWidget->size().height());
         if (m_headerWidget->automaticColumnResizing()) {
             applyAutomaticColumnWidths();
         } else {
@@ -425,7 +426,6 @@ void KItemListView::setGeometry(const QRectF& rect)
             const QSizeF dynamicItemSize(qMax(newSize.width(), requiredWidth),
                                          m_itemSize.height());
             m_layouter->setItemSize(dynamicItemSize);
-            m_headerWidget->resize(dynamicItemSize.width(), \
m_headerWidget->size().height());  }
 
         // Triggering a synchronous layout is fine from a performance point of view,
@@ -604,10 +604,18 @@ bool KItemListView::isTransactionActive() const
     return m_activeTransactions > 0;
 }
 
+// TODO:
+#include <QGraphicsScene>
+#include <QGraphicsView>
 void KItemListView::setHeaderVisible(bool visible)
 {
     if (visible && !m_headerWidget->isVisible()) {
-        m_headerWidget->setPos(0, 0);
+        QStyleOptionHeader option;
+        const QSize headerSize = style()->sizeFromContents(QStyle::CT_HeaderSection,
+                                                           &option, QSize());
+
+        m_headerWidget->setPos(0, 0);        
+        m_headerWidget->resize(size().width(), headerSize.height());
         m_headerWidget->setModel(m_model);
         m_headerWidget->setColumns(m_visibleRoles);
         m_headerWidget->setZValue(1);
@@ -621,7 +629,7 @@ void KItemListView::setHeaderVisible(bool visible)
         connect(m_headerWidget, SIGNAL(sortRoleChanged(QByteArray,QByteArray)),
                 this, SIGNAL(sortRoleChanged(QByteArray,QByteArray)));
 
-        m_layouter->setHeaderHeight(m_headerWidget->size().height());
+        m_layouter->setHeaderHeight(headerSize.height());
         m_headerWidget->setVisible(true);
     } else if (!visible && m_headerWidget->isVisible()) {
         disconnect(m_headerWidget, \
SIGNAL(columnWidthChanged(QByteArray,qreal,qreal)), @@ -1898,6 +1906,19 @@ \
QHash<QByteArray, qreal> KItemListView::preferredColumnWidths(const KItemRangeLi  
     QHash<QByteArray, qreal> widths;
 
+    // Calculate the minimum width for each column that is required
+    // to show the headline unclipped.
+    const QFontMetricsF fontMetrics(m_headerWidget->font());
+    const int gripMargin   = \
m_headerWidget->style()->pixelMetric(QStyle::PM_HeaderGripMargin); +    const int \
headerMargin = m_headerWidget->style()->pixelMetric(QStyle::PM_HeaderMargin); +    \
foreach (const QByteArray& visibleRole, visibleRoles()) { +        const QString \
headerText = m_model->roleDescription(visibleRole); +        const qreal headerWidth \
= fontMetrics.width(headerText) + gripMargin + headerMargin * 2; +        \
widths.insert(visibleRole, headerWidth); +    }
+
+    // Calculate the preferred column withs for each item and ignore values
+    // smaller than the width for showing the headline unclipped.
     int calculatedItemCount = 0;
     bool maxTimeExceeded = false;
     foreach (const KItemRange& itemRange, itemRanges) {
@@ -1936,7 +1957,6 @@ void KItemListView::applyColumnWidthsFromHeader()
     const QSizeF dynamicItemSize(qMax(size().width(), requiredWidth),
                                  m_itemSize.height());
     m_layouter->setItemSize(dynamicItemSize);
-    m_headerWidget->resize(dynamicItemSize.width(), \
m_headerWidget->size().height());  
     // Update the role sizes for all visible widgets
     QHashIterator<int, KItemListWidget*> it(m_visibleItems);
@@ -2001,13 +2021,8 @@ void KItemListView::updatePreferredColumnWidths(const \
KItemRangeList& itemRanges  
 void KItemListView::updatePreferredColumnWidths()
 {
-    if (!m_model) {
-        return;
-    }
-
-    const int itemCount = m_model->count();
-    if (itemCount > 0) {
-        updatePreferredColumnWidths(KItemRangeList() << KItemRange(0, itemCount));
+    if (m_model) {
+        updatePreferredColumnWidths(KItemRangeList() << KItemRange(0, \
m_model->count()));  }
 }
 
@@ -2056,7 +2071,6 @@ void KItemListView::applyAutomaticColumnWidths()
     dynamicItemSize.rwidth() = qMax(requiredWidth, availableWidth);
 
     m_layouter->setItemSize(dynamicItemSize);
-    m_headerWidget->resize(dynamicItemSize.width(), \
m_headerWidget->size().height());  
     // Update the role sizes for all visible widgets
     QHashIterator<int, KItemListWidget*> it(m_visibleItems);
diff --git a/dolphin/src/kitemviews/knepomukrolesprovider.cpp \
b/dolphin/src/kitemviews/knepomukrolesprovider.cpp new file mode 100644
index 0000000..1612d57
--- /dev/null
+++ b/dolphin/src/kitemviews/knepomukrolesprovider.cpp
@@ -0,0 +1,153 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Peter Penz <peter.penz19@gmail.com>             *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#include "knepomukrolesprovider_p.h"
+
+#include <KDebug>
+#include <KGlobal>
+
+#include <Nepomuk/Resource>
+#include <Nepomuk/Tag>
+#include <Nepomuk/Types/Property>
+#include <Nepomuk/Variant>
+
+struct KNepomukRolesProviderSingleton
+{
+    KNepomukRolesProvider instance;
+};
+K_GLOBAL_STATIC(KNepomukRolesProviderSingleton, s_nepomukRolesProvider)
+
+
+KNepomukRolesProvider& KNepomukRolesProvider::instance()
+{
+    return s_nepomukRolesProvider->instance;
+}
+
+KNepomukRolesProvider::~KNepomukRolesProvider()
+{
+}
+
+bool KNepomukRolesProvider::isNepomukRole(const QByteArray& role) const
+{
+    return m_roles.contains(role);
+}
+
+QHash<QByteArray, QVariant> KNepomukRolesProvider::roleValues(const QUrl& url,
+                                                              const \
QSet<QByteArray>& roles) const +{
+    const Nepomuk::Resource resource(url);
+    if (!resource.isValid()) {
+        return QHash<QByteArray, QVariant>();
+    }
+
+    QHash<QByteArray, QVariant> values;
+
+    int width = -1;
+    int height = -1;
+
+    QHashIterator<QUrl, Nepomuk::Variant> it(resource.properties());
+    while (it.hasNext()) {
+        it.next();
+
+        const Nepomuk::Types::Property property = it.key();
+        const QByteArray role = m_roleForUri.value(property.uri());
+        if (role.isEmpty() || !roles.contains(role)) {
+            continue;
+        }
+
+        const Nepomuk::Variant value = it.value();
+
+        if (role == "imageSize") {
+            // Merge the two Nepomuk properties for width and height
+            // as one string into the "imageSize" role
+            const QString uri = property.uri().toString();
+            if (uri.endsWith("#width")) {
+                width = value.toInt();
+            } else if (uri.endsWith("#height")) {
+                height = value.toInt();
+            }
+
+            if (width >= 0 && height >= 0) {
+                const QString widthAndHeight = QString::number(width) +
+                                               QLatin1String(" x ") +
+                                               QString::number(height);
+                values.insert(role, widthAndHeight);
+            }
+        } else if (role == "tags") {
+            const QString tags = tagsFromValues(value.toStringList());
+            values.insert(role, tags);
+        } else {
+            values.insert(role, value.toString());
+        }
+    }
+
+    return values;
+}
+
+KNepomukRolesProvider::KNepomukRolesProvider() :
+    m_roles(),
+    m_roleForUri()
+{
+    struct UriInfo
+    {
+        const char* const uri;
+        const char* const role;
+    };
+
+    // Mapping from the URIs to the KFileItemModel roles. Note that this must not be
+    // a 1:1 mapping: One role may contain several URI-values (e.g. the URIs for \
height and +    // width of an image are mapped to the role "imageSize")
+    static const UriInfo uriInfoList[] = {
+        { "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#numericRating", \
"rating" }, +        { \
"http://www.semanticdesktop.org/ontologies/2007/08/15/nao#hasTag",        "tags" }, + \
{ "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#description",   "comment" \
}, +        { "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#wordCount",   \
"wordCount" }, +        { \
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#lineCount",     "lineCount" \
}, +        { "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width",       \
"imageSize" }, +        { \
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height",        "imageSize" \
}, +        { "http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#orientation", \
"orientation", }, +        { \
"http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#performer",     "artist" }, \
+        { "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#musicAlbum",    \
"album" }, +        { \
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#duration",      "duration" \
}, +        { "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#trackNumber", \
"track" }, +        { \
"http://www.semanticdesktop.org/ontologies/2010/04/30/ndo#copiedFrom",    \
"copiedFrom" } +    };
+
+    for (unsigned int i = 0; i < sizeof(uriInfoList) / sizeof(UriInfo); ++i) {
+        m_roleForUri.insert(QUrl(uriInfoList[i].uri), uriInfoList[i].role);
+        m_roles.insert(uriInfoList[i].role);
+    }
+}
+
+QString KNepomukRolesProvider::tagsFromValues(const QStringList& values) const
+{
+    QString tags;
+
+    for (int i = 0; i < values.count(); ++i) {
+        if (i > 0) {
+            tags.append(QLatin1String(", "));
+        }
+
+        const Nepomuk::Tag tag(values[i]);
+        tags += tag.genericLabel();
+    }
+
+    return tags;
+}
+
diff --git a/dolphin/src/kitemviews/knepomukrolesprovider_p.h \
b/dolphin/src/kitemviews/knepomukrolesprovider_p.h new file mode 100644
index 0000000..7955093
--- /dev/null
+++ b/dolphin/src/kitemviews/knepomukrolesprovider_p.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Peter Penz <peter.penz19@gmail.com>             *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
+ ***************************************************************************/
+
+#ifndef KNEPOMUKROLESPROVIDER_H
+#define KNEPOMUKROLESPROVIDER_H
+
+#include <QHash>
+#include <QSet>
+#include <QUrl>
+
+class QUrl;
+
+/**
+ * @brief Allows accessing metadata of a file by providing KFileItemModel roles.
+ *
+ * Is a helper class for KFileItemModelRolesUpdater to retrieve roles that
+ * are only accessible with Nepomuk.
+ */
+class KNepomukRolesProvider
+{
+public:
+    static KNepomukRolesProvider& instance();
+    virtual ~KNepomukRolesProvider();
+
+    /**
+     * @return True if the values of the role can be determined by Nepomuk.
+     */
+    bool isNepomukRole(const QByteArray& role) const;
+
+    /**
+     * @return Values for the roles \a roles that can be determined from the file
+     *         with the URL \a url.
+     */
+    QHash<QByteArray, QVariant> roleValues(const QUrl& url, const QSet<QByteArray>& \
roles) const; +
+protected:
+    KNepomukRolesProvider();
+
+private:
+    QString tagsFromValues(const QStringList& values) const;
+
+private:
+    QSet<QByteArray> m_roles;
+    QHash<QUrl, QByteArray> m_roleForUri;
+
+    friend class KNepomukRolesProviderSingleton;
+};
+
+#endif
+
diff --git a/dolphin/src/settings/additionalinfodialog.cpp \
b/dolphin/src/settings/additionalinfodialog.cpp index 9e5f170..3cac35b 100644
--- a/dolphin/src/settings/additionalinfodialog.cpp
+++ b/dolphin/src/settings/additionalinfodialog.cpp
@@ -19,12 +19,18 @@
 
 #include "additionalinfodialog.h"
 
+#include <config-nepomuk.h>
+
 #include <KLocale>
 #include "kitemviews/kfileitemmodel.h"
 #include <QCheckBox>
 #include <QLabel>
 #include <QVBoxLayout>
 
+#ifdef HAVE_NEPOMUK
+    #include <Nepomuk/ResourceManager>
+#endif
+
 AdditionalInfoDialog::AdditionalInfoDialog(QWidget* parent,
                                            const QList<QByteArray>& visibleRoles) :
     KDialog(parent),
@@ -44,12 +50,30 @@ AdditionalInfoDialog::AdditionalInfoDialog(QWidget* parent,
     header->setWordWrap(true);
 
     // Add checkboxes
+    bool nepomukRunning = false;
+    bool indexingEnabled = false;
+#ifdef HAVE_NEPOMUK
+    nepomukRunning = (Nepomuk::ResourceManager::instance()->init() == 0);
+    if (nepomukRunning) {
+        KConfig config("nepomukserverrc");
+        indexingEnabled = \
config.group("Service-nepomukfileindexer").readEntry("autostart", false); +    }
+#endif
+
     m_listWidget = new QListWidget(mainWidget);
     m_listWidget->setSelectionMode(QAbstractItemView::NoSelection);
     const QList<KFileItemModel::RoleInfo> rolesInfo = \
KFileItemModel::rolesInformation();  foreach (const KFileItemModel::RoleInfo& info, \
                rolesInfo) {
         QListWidgetItem* item = new QListWidgetItem(info.translation, m_listWidget);
         item->setCheckState(visibleRoles.contains(info.role) ? Qt::Checked : \
Qt::Unchecked); +
+        const bool enable = (!info.requiresNepomuk && !info.requiresIndexer) ||
+                            (info.requiresNepomuk && nepomukRunning) ||
+                            (info.requiresIndexer && indexingEnabled);
+
+        if (!enable) {
+            item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
+        }
     }
 
     QVBoxLayout* layout = new QVBoxLayout(mainWidget);
diff --git a/dolphin/src/views/dolphinitemlistcontainer.cpp \
b/dolphin/src/views/dolphinitemlistcontainer.cpp index 8224399..391dc64 100644
--- a/dolphin/src/views/dolphinitemlistcontainer.cpp
+++ b/dolphin/src/views/dolphinitemlistcontainer.cpp
@@ -140,6 +140,7 @@ void \
DolphinItemListContainer::setItemLayout(KFileItemListView::Layout layout)  \
m_fileItemListView->setScrollOrientation(Qt::Vertical);  \
                m_fileItemListView->setHeaderVisible(true);
         m_fileItemListView->setSupportsItemExpanding(DetailsModeSettings::expandableFolders());
 +
         break;
     case KFileItemListView::CompactLayout:
         m_fileItemListView->setScrollOrientation(Qt::Horizontal);
diff --git a/dolphin/src/views/dolphinview.cpp b/dolphin/src/views/dolphinview.cpp
index ab81316..78fd56d 100644
--- a/dolphin/src/views/dolphinview.cpp
+++ b/dolphin/src/views/dolphinview.cpp
@@ -20,6 +20,8 @@
 
 #include "dolphinview.h"
 
+#include <config-nepomuk.h>
+
 #include <QAbstractItemView>
 #include <QApplication>
 #include <QBoxLayout>
@@ -70,6 +72,10 @@
 #include "views/tooltips/tooltipmanager.h"
 #include "zoomlevelinfo.h"
 
+#ifdef HAVE_NEPOMUK
+    #include <Nepomuk/ResourceManager>
+#endif
+
 namespace {
     const int MaxModeEnum = DolphinView::CompactView;
 };
@@ -784,6 +790,16 @@ void DolphinView::slotHeaderContextMenuRequested(const QPointF& \
pos)  KItemListView* view = m_container->controller()->view();
     const QSet<QByteArray> visibleRolesSet = view->visibleRoles().toSet();
 
+    bool nepomukRunning = false;
+    bool indexingEnabled = false;
+#ifdef HAVE_NEPOMUK
+    nepomukRunning = (Nepomuk::ResourceManager::instance()->init() == 0);
+    if (nepomukRunning) {
+        KConfig config("nepomukserverrc");
+        indexingEnabled = \
config.group("Service-nepomukfileindexer").readEntry("autostart", false); +    }
+#endif
+
     QString groupName;
     QMenu* groupMenu = 0;
 
@@ -811,6 +827,11 @@ void DolphinView::slotHeaderContextMenuRequested(const QPointF& \
pos)  action->setCheckable(true);
         action->setChecked(visibleRolesSet.contains(info.role));
         action->setData(info.role);
+
+        const bool enable = (!info.requiresNepomuk && !info.requiresIndexer) ||
+                            (info.requiresNepomuk && nepomukRunning) ||
+                            (info.requiresIndexer && indexingEnabled);
+        action->setEnabled(enable);
     }
 
     menu->addSeparator();
@@ -861,8 +882,10 @@ void DolphinView::slotHeaderContextMenuRequested(const QPointF& \
pos)  props.setVisibleRoles(visibleRoles);
 
             QList<int> columnWidths;
-            foreach (const QByteArray& role, view->visibleRoles()) {
-                columnWidths.append(header->columnWidth(role));
+            if (!header->automaticColumnResizing()) {
+                foreach (const QByteArray& role, view->visibleRoles()) {
+                    columnWidths.append(header->columnWidth(role));
+                }
             }
             props.setHeaderColumnWidths(columnWidths);
         }
diff --git a/dolphin/src/views/dolphinviewactionhandler.cpp \
b/dolphin/src/views/dolphinviewactionhandler.cpp index aead11d..eb127e2 100644
--- a/dolphin/src/views/dolphinviewactionhandler.cpp
+++ b/dolphin/src/views/dolphinviewactionhandler.cpp
@@ -20,6 +20,8 @@
 
 #include "dolphinviewactionhandler.h"
 
+#include <config-nepomuk.h>
+
 #include "settings/viewpropertiesdialog.h"
 #include "views/dolphinview.h"
 #include "views/zoomlevelinfo.h"
@@ -37,6 +39,10 @@
 #include <KRun>
 #include <KPropertiesDialog>
 
+#ifdef HAVE_NEPOMUK
+    #include <Nepomuk/ResourceManager>
+#endif
+
 #include <KDebug>
 
 DolphinViewActionHandler::DolphinViewActionHandler(KActionCollection* collection, \
QObject* parent) : @@ -228,6 +234,16 @@ QActionGroup* \
DolphinViewActionHandler::createFileItemRolesActionGroup(const QSt  KActionMenu* \
groupMenu = 0;  QActionGroup* groupMenuGroup = 0;
 
+    bool nepomukRunning = false;
+    bool indexingEnabled = false;
+#ifdef HAVE_NEPOMUK
+    nepomukRunning = (Nepomuk::ResourceManager::instance()->init() == 0);
+    if (nepomukRunning) {
+        KConfig config("nepomukserverrc");
+        indexingEnabled = \
config.group("Service-nepomukfileindexer").readEntry("autostart", false); +    }
+#endif
+
     const QList<KFileItemModel::RoleInfo> rolesInfo = \
KFileItemModel::rolesInformation();  foreach (const KFileItemModel::RoleInfo& info, \
rolesInfo) {  if (!isSortGroup && info.role == "name") {
@@ -265,6 +281,11 @@ QActionGroup* \
DolphinViewActionHandler::createFileItemRolesActionGroup(const QSt  \
action->setText(info.translation);  action->setData(info.role);
 
+        const bool enable = (!info.requiresNepomuk && !info.requiresIndexer) ||
+                            (info.requiresNepomuk && nepomukRunning) ||
+                            (info.requiresIndexer && indexingEnabled);
+        action->setEnabled(enable);
+
         if (isSortGroup) {
             m_sortByActions.insert(info.role, action);
         } else {


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic