Commit 270e0c3e authored by Peter Penz's avatar Peter Penz
Browse files

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
parent d275ebf6
......@@ -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)
......
......@@ -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;
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
};
/**
......
......@@ -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;
}
......
......@@ -20,6 +20,7 @@
#ifndef KFILEITEMMODELROLESUPDATER_H
#define KFILEITEMMODELROLESUPDATER_H