]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Prepare view-engine for non-KFileItem usecase
authorPeter Penz <peter.penz19@gmail.com>
Sat, 21 Apr 2012 19:28:16 +0000 (21:28 +0200)
committerPeter Penz <peter.penz19@gmail.com>
Sat, 21 Apr 2012 19:32:42 +0000 (21:32 +0200)
Up to now the view-engine only provided a model-implementation that
supports file-items. The view-engine always had been designed to be able
to work with any kind of model, so now a KStandardItemModel is available.
The plan is to convert the places panel to the new view-engine. It should
be no problem to fix this until the feature freeze - in the worst case
the places-panel code could be reverted while still keeping the
KStandardItemModel changes.

41 files changed:
src/CMakeLists.txt
src/dolphinmainwindow.cpp
src/kitemviews/kfileitemlistview.cpp
src/kitemviews/kfileitemlistview.h
src/kitemviews/kfileitemlistwidget.cpp
src/kitemviews/kfileitemlistwidget.h
src/kitemviews/kfileitemmodel.cpp
src/kitemviews/kfileitemmodel.h
src/kitemviews/kitemlistcontainer.cpp
src/kitemviews/kitemlistcontainer.h
src/kitemviews/kitemlistcontroller.cpp
src/kitemviews/kitemlistcontroller.h
src/kitemviews/kitemliststyleoption.cpp
src/kitemviews/kitemlistview.cpp
src/kitemviews/kitemlistview.h
src/kitemviews/kitemlistwidget.cpp
src/kitemviews/kitemlistwidget.h
src/kitemviews/kstandarditem.cpp [new file with mode: 0644]
src/kitemviews/kstandarditem.h [new file with mode: 0644]
src/kitemviews/kstandarditemlistview.cpp [new file with mode: 0644]
src/kitemviews/kstandarditemlistview.h [new file with mode: 0644]
src/kitemviews/kstandarditemlistwidget.cpp [new file with mode: 0644]
src/kitemviews/kstandarditemlistwidget.h [new file with mode: 0644]
src/kitemviews/kstandarditemmodel.cpp [new file with mode: 0644]
src/kitemviews/kstandarditemmodel.h [new file with mode: 0644]
src/panels/folders/folderspanel.cpp
src/panels/folders/folderspanel.h
src/panels/places/placespanel.cpp
src/panels/places/placespanel.h
src/settings/viewpropertiesdialog.cpp
src/tests/kfileitemmodeltest.cpp
src/tests/kitemlistcontrollertest.cpp
src/views/dolphinfileitemlistwidget.cpp
src/views/dolphinfileitemlistwidget.h
src/views/dolphinitemlistview.cpp [moved from src/views/dolphinitemlistcontainer.cpp with 57% similarity]
src/views/dolphinitemlistview.h [moved from src/views/dolphinitemlistcontainer.h with 59% similarity]
src/views/dolphinview.cpp
src/views/dolphinview.h
src/views/dolphinviewactionhandler.cpp
src/views/viewproperties.cpp
src/views/viewproperties.h

index 97a307b5da6a3be5c006e726629c451913ef02cc..868ff6c602c809a3d23d2b61646ceadce174f5ea 100644 (file)
@@ -32,6 +32,10 @@ set(dolphinprivate_LIB_SRCS
     kitemviews/kitemlistview.cpp
     kitemviews/kitemlistwidget.cpp
     kitemviews/kitemmodelbase.cpp
+    kitemviews/kstandarditem.cpp
+    kitemviews/kstandarditemlistview.cpp
+    kitemviews/kstandarditemlistwidget.cpp
+    kitemviews/kstandarditemmodel.cpp
     kitemviews/private/kfileitemclipboard.cpp
     kitemviews/private/kfileitemmodeldirlister.cpp
     kitemviews/private/kfileitemmodelsortalgorithm.cpp
@@ -52,7 +56,7 @@ set(dolphinprivate_LIB_SRCS
     settings/viewpropertiesdialog.cpp
     settings/viewpropsprogressinfo.cpp
     views/dolphinfileitemlistwidget.cpp
-    views/dolphinitemlistcontainer.cpp
+    views/dolphinitemlistview.cpp
     views/dolphinnewfilemenuobserver.cpp
     views/dolphinplacesmodel.cpp
     views/dolphinremoteencoding.cpp
index 6800daefbefc5d60ab5eee6fc6bd4572c012f31d..a990e2a1768610aa1b38d73ae88933009fa6ae0a 100644 (file)
@@ -1847,17 +1847,17 @@ void DolphinMainWindow::setupDockWidgets()
     QList<QAction*> placesActions;
     placesActions.append(separator);
     placesActions.append(lockLayoutAction);
-    placesPanel->addActions(placesActions);
-    placesPanel->setModel(DolphinPlacesModel::instance());
-    placesPanel->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    //placesPanel->addActions(placesActions);
+    //placesPanel->setModel(DolphinPlacesModel::instance());
+    //placesPanel->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
     placesDock->setWidget(placesPanel);
 
     QAction* placesAction = placesDock->toggleViewAction();
     createPanelAction(KIcon("bookmarks"), Qt::Key_F9, placesAction, "show_places_panel");
 
     addDockWidget(Qt::LeftDockWidgetArea, placesDock);
-    connect(placesPanel, SIGNAL(urlChanged(KUrl,Qt::MouseButtons)),
-            this, SLOT(handlePlacesClick(KUrl,Qt::MouseButtons)));
+    //connect(placesPanel, SIGNAL(urlChanged(KUrl,Qt::MouseButtons)),
+    //        this, SLOT(handlePlacesClick(KUrl,Qt::MouseButtons)));
     connect(this, SIGNAL(urlChanged(KUrl)),
             placesPanel, SLOT(setUrl(KUrl)));
     connect(placesDock, SIGNAL(visibilityChanged(bool)),
index c5c4448750f55c4fdd4cefd3134b51d302539035..7bcc781faea5ef78527717e16dd83b45c1152441 100644 (file)
@@ -43,8 +43,7 @@ namespace {
 }
 
 KFileItemListView::KFileItemListView(QGraphicsWidget* parent) :
-    KItemListView(parent),
-    m_itemLayout(IconsLayout),
+    KStandardItemListView(parent),
     m_modelRolesUpdater(0),
     m_updateVisibleIndexRangeTimer(0),
     m_updateIconSizeTimer(0)
@@ -52,8 +51,6 @@ KFileItemListView::KFileItemListView(QGraphicsWidget* parent) :
     setAcceptDrops(true);
 
     setScrollOrientation(Qt::Vertical);
-    setWidgetCreator(new KItemListWidgetCreator<KFileItemListWidget>());
-    setGroupHeaderCreator(new KItemListGroupHeaderCreator<KFileItemListGroupHeader>());
 
     m_updateVisibleIndexRangeTimer = new QTimer(this);
     m_updateVisibleIndexRangeTimer->setSingleShot(true);
@@ -65,25 +62,26 @@ KFileItemListView::KFileItemListView(QGraphicsWidget* parent) :
     m_updateIconSizeTimer->setInterval(ShortInterval);
     connect(m_updateIconSizeTimer, SIGNAL(timeout()), this, SLOT(updateIconSize()));
 
-    setVisibleRoles(QList<QByteArray>() << "name");
+    setVisibleRoles(QList<QByteArray>() << "text");
 }
 
 KFileItemListView::~KFileItemListView()
 {
-    // The group headers are children of the widgets created by
-    // widgetCreator(). So it is mandatory to delete the group headers
-    // first.
-    delete groupHeaderCreator();
-    delete widgetCreator();
-
     delete m_modelRolesUpdater;
     m_modelRolesUpdater = 0;
 }
 
 void KFileItemListView::setPreviewsShown(bool show)
 {
-    if (m_modelRolesUpdater) {
+    if (!m_modelRolesUpdater) {
+        return;
+    }
+
+    if (m_modelRolesUpdater->previewsShown() != show) {
+        beginTransaction();
         m_modelRolesUpdater->setPreviewsShown(show);
+        onPreviewsShownChanged(show);
+        endTransaction();
     }
 }
 
@@ -104,26 +102,6 @@ bool KFileItemListView::enlargeSmallPreviews() const
     return m_modelRolesUpdater ? m_modelRolesUpdater->enlargeSmallPreviews() : false;
 }
 
-void KFileItemListView::setItemLayout(Layout layout)
-{
-    if (m_itemLayout != layout) {
-        const bool updateRoles = (m_itemLayout == DetailsLayout || layout == DetailsLayout);
-        m_itemLayout = layout;
-        if (updateRoles) {
-            // The details-layout requires some invisible roles that
-            // must be added to the model if the new layout is "details".
-            // If the old layout was "details" the roles will get removed.
-            applyRolesToModel();
-        }
-        updateLayoutOfVisibleItems();
-    }
-}
-
-KFileItemListView::Layout KFileItemListView::itemLayout() const
-{
-    return m_itemLayout;
-}
-
 void KFileItemListView::setEnabledPlugins(const QStringList& list)
 {
     if (m_modelRolesUpdater) {
@@ -207,52 +185,53 @@ QPixmap KFileItemListView::createDragPixmap(const QSet<int>& indexes) const
     return dragPixmap;
 }
 
-void KFileItemListView::initializeItemListWidget(KItemListWidget* item)
+KItemListWidgetCreatorBase* KFileItemListView::defaultWidgetCreator() const
 {
-    KFileItemListWidget* fileItemListWidget = static_cast<KFileItemListWidget*>(item);
-
-    switch (m_itemLayout) {
-    case IconsLayout:   fileItemListWidget->setLayout(KFileItemListWidget::IconsLayout); break;
-    case CompactLayout: fileItemListWidget->setLayout(KFileItemListWidget::CompactLayout); break;
-    case DetailsLayout: fileItemListWidget->setLayout(KFileItemListWidget::DetailsLayout); break;
-    default:            Q_ASSERT(false); break;
-    }
+    return new KItemListWidgetCreator<KFileItemListWidget>();
+}
 
-    fileItemListWidget->setSupportsItemExpanding(supportsItemExpanding());
+KItemListGroupHeaderCreatorBase* KFileItemListView::defaultGroupHeaderCreator() const
+{
+    return new KItemListGroupHeaderCreator<KFileItemListGroupHeader>();
 }
 
-bool KFileItemListView::itemSizeHintUpdateRequired(const QSet<QByteArray>& changedRoles) const
+void KFileItemListView::onPreviewsShownChanged(bool shown)
 {
-    // Even if the icons have a different size they are always aligned within
-    // the area defined by KItemStyleOption.iconSize and hence result in no
-    // change of the item-size.
-    const bool containsIconName = changedRoles.contains("iconName");
-    const bool containsIconPixmap = changedRoles.contains("iconPixmap");
-    const int count = changedRoles.count();
+    Q_UNUSED(shown);
+}
 
-    const bool iconChanged = (containsIconName && containsIconPixmap && count == 2) ||
-                             (containsIconName && count == 1) ||
-                             (containsIconPixmap && count == 1);
-    return !iconChanged;
+void KFileItemListView::onItemLayoutChanged(ItemLayout current, ItemLayout previous)
+{
+    if (previous == DetailsLayout || current == DetailsLayout) {
+        // The details-layout requires some invisible roles that
+        // must be added to the model if the new layout is "details".
+        // If the old layout was "details" the roles will get removed.
+        applyRolesToModel();
+    }
+    KStandardItemListView::onItemLayoutChanged(current, previous);
+    triggerVisibleIndexRangeUpdate();
 }
 
 void KFileItemListView::onModelChanged(KItemModelBase* current, KItemModelBase* previous)
 {
-    Q_UNUSED(previous);
     Q_ASSERT(qobject_cast<KFileItemModel*>(current));
+    KStandardItemListView::onModelChanged(current, previous);
 
     delete m_modelRolesUpdater;
-    m_modelRolesUpdater = new KFileItemModelRolesUpdater(static_cast<KFileItemModel*>(current), this);
-    m_modelRolesUpdater->setIconSize(availableIconSize());
+    m_modelRolesUpdater = 0;
 
-    applyRolesToModel();
+    if (current) {
+        m_modelRolesUpdater = new KFileItemModelRolesUpdater(static_cast<KFileItemModel*>(current), this);
+        m_modelRolesUpdater->setIconSize(availableIconSize());
+
+        applyRolesToModel();
+    }
 }
 
 void KFileItemListView::onScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous)
 {
-    Q_UNUSED(current);
-    Q_UNUSED(previous);
-    updateLayoutOfVisibleItems();
+    KStandardItemListView::onScrollOrientationChanged(current, previous);
+    triggerVisibleIndexRangeUpdate();
 }
 
 void KFileItemListView::onItemSizeChanged(const QSizeF& current, const QSizeF& previous)
@@ -264,39 +243,42 @@ void KFileItemListView::onItemSizeChanged(const QSizeF& current, const QSizeF& p
 
 void KFileItemListView::onScrollOffsetChanged(qreal current, qreal previous)
 {
-    Q_UNUSED(current);
-    Q_UNUSED(previous);
+    KStandardItemListView::onScrollOffsetChanged(current, previous);
     triggerVisibleIndexRangeUpdate();
 }
 
 void KFileItemListView::onVisibleRolesChanged(const QList<QByteArray>& current, const QList<QByteArray>& previous)
 {
-    Q_UNUSED(current);
-    Q_UNUSED(previous);
+    KStandardItemListView::onVisibleRolesChanged(current, previous);
     applyRolesToModel();
 }
 
 void KFileItemListView::onStyleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous)
 {
-    Q_UNUSED(current);
-    Q_UNUSED(previous);
+    KStandardItemListView::onStyleOptionChanged(current, previous);
     triggerIconSizeUpdate();
 }
 
 void KFileItemListView::onSupportsItemExpandingChanged(bool supportsExpanding)
 {
-    Q_UNUSED(supportsExpanding);
     applyRolesToModel();
-    updateLayoutOfVisibleItems();
+    KStandardItemListView::onSupportsItemExpandingChanged(supportsExpanding);
+    triggerVisibleIndexRangeUpdate();
 }
 
 void KFileItemListView::onTransactionBegin()
 {
-    m_modelRolesUpdater->setPaused(true);
+    if (m_modelRolesUpdater) {
+        m_modelRolesUpdater->setPaused(true);
+    }
 }
 
 void KFileItemListView::onTransactionEnd()
 {
+    if (!m_modelRolesUpdater) {
+        return;
+    }
+
     // Only unpause the model-roles-updater if no timer is active. If one
     // timer is still active the model-roles-updater will be unpaused later as
     // soon as the timer has been exceeded.
@@ -309,13 +291,13 @@ void KFileItemListView::onTransactionEnd()
 
 void KFileItemListView::resizeEvent(QGraphicsSceneResizeEvent* event)
 {
-    KItemListView::resizeEvent(event);
+    KStandardItemListView::resizeEvent(event);
     triggerVisibleIndexRangeUpdate();
 }
 
 void KFileItemListView::slotItemsRemoved(const KItemRangeList& itemRanges)
 {
-    KItemListView::slotItemsRemoved(itemRanges);
+    KStandardItemListView::slotItemsRemoved(itemRanges);
     updateTimersInterval();
 }
 
@@ -326,7 +308,7 @@ void KFileItemListView::slotSortRoleChanged(const QByteArray& current, const QBy
         applyRolesToModel();
     }
 
-    KItemListView::slotSortRoleChanged(current, previous);
+    KStandardItemListView::slotSortRoleChanged(current, previous);
 }
 
 void KFileItemListView::triggerVisibleIndexRangeUpdate()
@@ -391,18 +373,6 @@ void KFileItemListView::updateIconSize()
     updateTimersInterval();
 }
 
-void KFileItemListView::updateLayoutOfVisibleItems()
-{
-    if (!model()) {
-        return;
-    }
-
-    foreach (KItemListWidget* widget, visibleItemListWidgets()) {
-        initializeItemListWidget(widget);
-    }
-    triggerVisibleIndexRangeUpdate();
-}
-
 void KFileItemListView::updateTimersInterval()
 {
     if (!model()) {
@@ -434,7 +404,7 @@ void KFileItemListView::applyRolesToModel()
     QSet<QByteArray> roles = visibleRoles().toSet();
     roles.insert("iconPixmap");
     roles.insert("iconName");
-    roles.insert("name");
+    roles.insert("text");
     roles.insert("isDir");
     if (supportsItemExpanding()) {
         roles.insert("isExpanded");
@@ -453,7 +423,7 @@ QSize KFileItemListView::availableIconSize() const
 {
     const KItemListStyleOption& option = styleOption();
     const int iconSize = option.iconSize;
-    if (m_itemLayout == IconsLayout) {
+    if (itemLayout() == IconsLayout) {
         const int maxIconWidth = itemSize().width() - 2 * option.padding;
         return QSize(maxIconWidth, iconSize);
     }
index 8f7ca9063c1c617385cb921be0f119c43f9e930c..c8a3385fdf128dee8dca2beb57dc0738108548a2 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <libdolphin_export.h>
 
-#include <kitemviews/kitemlistview.h>
+#include <kitemviews/kstandarditemlistview.h>
 
 class KFileItemModelRolesUpdater;
 class QTimer;
@@ -36,18 +36,11 @@ class QTimer;
  * KItemListView::setWidgetCreator() and KItemListView::setGroupHeaderCreator()
  * to apply customized generators.
  */
-class LIBDOLPHINPRIVATE_EXPORT KFileItemListView : public KItemListView
+class LIBDOLPHINPRIVATE_EXPORT KFileItemListView : public KStandardItemListView
 {
     Q_OBJECT
 
 public:
-    enum Layout
-    {
-        IconsLayout,
-        CompactLayout,
-        DetailsLayout
-    };
-
     KFileItemListView(QGraphicsWidget* parent = 0);
     virtual ~KFileItemListView();
 
@@ -62,9 +55,6 @@ public:
     void setEnlargeSmallPreviews(bool enlarge);
     bool enlargeSmallPreviews() const;
 
-    void setItemLayout(Layout layout);
-    Layout itemLayout() const;
-
     /**
      * Sets the list of enabled thumbnail plugins that are used for previews.
      * Per default all plugins enabled in the KConfigGroup "PreviewSettings"
@@ -86,8 +76,10 @@ public:
     virtual QPixmap createDragPixmap(const QSet<int>& indexes) const;
 
 protected:
-    virtual void initializeItemListWidget(KItemListWidget* item);
-    virtual bool itemSizeHintUpdateRequired(const QSet<QByteArray>& changedRoles) const;
+    virtual KItemListWidgetCreatorBase* defaultWidgetCreator() const;
+    virtual KItemListGroupHeaderCreatorBase* defaultGroupHeaderCreator() const;
+    virtual void onPreviewsShownChanged(bool shown);
+    virtual void onItemLayoutChanged(ItemLayout current, ItemLayout previous);
     virtual void onModelChanged(KItemModelBase* current, KItemModelBase* previous);
     virtual void onScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous);
     virtual void onItemSizeChanged(const QSizeF& current, const QSizeF& previous);
@@ -111,7 +103,6 @@ private slots:
     void updateIconSize();
 
 private:
-    void updateLayoutOfVisibleItems();
     void updateTimersInterval();
 
     /**
@@ -130,8 +121,6 @@ private:
     QSize availableIconSize() const;
 
 private:
-    Layout m_itemLayout;
-
     KFileItemModelRolesUpdater* m_modelRolesUpdater;
     QTimer* m_updateVisibleIndexRangeTimer;
     QTimer* m_updateIconSizeTimer;
index 83df9da702e1a75a2abe42dc5a123d987ebe4477..a5a4f9c0b02bf717997b3cf18d726a5939450bbb 100644 (file)
 
 #include "kfileitemlistwidget.h"
 
-#include "kfileitemlistview.h"
-#include "kfileitemmodel.h"
-
-#include <KIcon>
-#include <KIconEffect>
-#include <KIconLoader>
-#include <KLocale>
-#include <kratingpainter.h>
-#include <KStringHandler>
 #include <KDebug>
+#include <KGlobal>
+#include <KLocale>
+#include <KIO/MetaData>
+#include <QDateTime>
 
-#include "private/kfileitemclipboard.h"
-#include "private/kitemlistroleeditor.h"
-#include "private/kpixmapmodifier.h"
-
-#include <QFontMetricsF>
-#include <QGraphicsScene>
-#include <QGraphicsSceneResizeEvent>
-#include <QGraphicsView>
-#include <QPainter>
-#include <QStyleOption>
-#include <QTextLayout>
-#include <QTextLine>
-
-// #define KFILEITEMLISTWIDGET_DEBUG
-
-KFileItemListWidget::KFileItemListWidget(QGraphicsItem* parent) :
-    KItemListWidget(parent),
-    m_isCut(false),
-    m_isHidden(false),
-    m_isExpandable(false),
-    m_supportsItemExpanding(false),
-    m_dirtyLayout(true),
-    m_dirtyContent(true),
-    m_dirtyContentRoles(),
-    m_layout(IconsLayout),
-    m_pixmapPos(),
-    m_pixmap(),
-    m_scaledPixmapSize(),
-    m_iconRect(),
-    m_hoverPixmap(),
-    m_textInfo(),
-    m_textRect(),
-    m_sortedVisibleRoles(),
-    m_expansionArea(),
-    m_customTextColor(),
-    m_additionalInfoTextColor(),
-    m_overlay(),
-    m_rating(),
-    m_roleEditor(0)
-{
-}
-
-KFileItemListWidget::~KFileItemListWidget()
-{
-    qDeleteAll(m_textInfo);
-    m_textInfo.clear();
-
-    delete m_roleEditor;
-}
-
-void KFileItemListWidget::setLayout(Layout layout)
-{
-    if (m_layout != layout) {
-        m_layout = layout;
-        m_dirtyLayout = true;
-        updateAdditionalInfoTextColor();
-        update();
-    }
-}
-
-KFileItemListWidget::Layout KFileItemListWidget::layout() const
-{
-    return m_layout;
-}
-
-void KFileItemListWidget::setSupportsItemExpanding(bool supportsItemExpanding)
-{
-    if (m_supportsItemExpanding != supportsItemExpanding) {
-        m_supportsItemExpanding = supportsItemExpanding;
-        m_dirtyLayout = true;
-        update();
-    }
-}
-
-bool KFileItemListWidget::supportsItemExpanding() const
-{
-    return m_supportsItemExpanding;
-}
-
-void KFileItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
-{
-    const_cast<KFileItemListWidget*>(this)->triggerCacheRefreshing();
-
-    KItemListWidget::paint(painter, option, widget);
-
-    if (!m_expansionArea.isEmpty()) {
-        drawSiblingsInformation(painter);
-    }
-
-    const KItemListStyleOption& itemListStyleOption = styleOption();
-    if (isHovered()) {
-        // Blend the unhovered and hovered pixmap if the hovering
-        // animation is ongoing
-        if (hoverOpacity() < 1.0) {
-            drawPixmap(painter, m_pixmap);
-        }
-
-        const qreal opacity = painter->opacity();
-        painter->setOpacity(hoverOpacity() * opacity);
-        drawPixmap(painter, m_hoverPixmap);
-        painter->setOpacity(opacity);
-    } else {
-        drawPixmap(painter, m_pixmap);
-    }
-
-    painter->setFont(itemListStyleOption.font);
-    painter->setPen(textColor());
-    const TextInfo* textInfo = m_textInfo.value("name");
-    painter->drawStaticText(textInfo->pos, textInfo->staticText);
-
-    bool clipAdditionalInfoBounds = false;
-    if (m_supportsItemExpanding) {
-        // Prevent a possible overlapping of the additional-information texts
-        // 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 (textInfo->pos.x() + columnWidth("name") > minX) {
-            clipAdditionalInfoBounds = true;
-            painter->save();
-            painter->setClipRect(minX, 0, size().width() - minX, size().height(), Qt::IntersectClip);
-        }
-    }
-
-    painter->setPen(m_additionalInfoTextColor);
-    painter->setFont(itemListStyleOption.font);
-
-    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 (!m_rating.isNull()) {
-        const TextInfo* ratingTextInfo = m_textInfo.value("rating");
-        QPointF pos = ratingTextInfo->pos;
-        const Qt::Alignment align = ratingTextInfo->staticText.textOption().alignment();
-        if (align & Qt::AlignHCenter) {
-            pos.rx() += (size().width() - m_rating.width()) / 2;
-        }
-        painter->drawPixmap(pos, m_rating);
-    }
-
-    if (clipAdditionalInfoBounds) {
-        painter->restore();
-    }
-
-#ifdef KFILEITEMLISTWIDGET_DEBUG
-    painter->setBrush(Qt::NoBrush);
-    painter->setPen(Qt::green);
-    painter->drawRect(m_iconRect);
-
-    painter->setPen(Qt::red);
-    painter->drawText(QPointF(0, itemListStyleOption.fontMetrics.height()), QString::number(index()));
-    painter->drawRect(rect());
-#endif
-}
-
-QRectF KFileItemListWidget::iconRect() const
-{
-    const_cast<KFileItemListWidget*>(this)->triggerCacheRefreshing();
-    return m_iconRect;
-}
-
-QRectF KFileItemListWidget::textRect() const
-{
-    const_cast<KFileItemListWidget*>(this)->triggerCacheRefreshing();
-    return m_textRect;
-}
-
-QRectF KFileItemListWidget::textFocusRect() const
-{
-    // In the compact- and details-layout a larger textRect() is returned to be aligned
-    // with the iconRect(). This is useful to have a larger selection/hover-area
-    // when having a quite large icon size but only one line of text. Still the
-    // focus rectangle should be shown as narrow as possible around the text.
-
-    const_cast<KFileItemListWidget*>(this)->triggerCacheRefreshing();
-
-    switch (m_layout) {
-    case CompactLayout: {
-        QRectF rect = m_textRect;
-        const TextInfo* topText    = m_textInfo.value(m_sortedVisibleRoles.first());
-        const TextInfo* bottomText = m_textInfo.value(m_sortedVisibleRoles.last());
-        rect.setTop(topText->pos.y());
-        rect.setBottom(bottomText->pos.y() + bottomText->staticText.size().height());
-        return rect;
-    }
-
-    case DetailsLayout: {
-        QRectF rect = m_textRect;
-        const TextInfo* textInfo    = m_textInfo.value(m_sortedVisibleRoles.first());
-        rect.setTop(textInfo->pos.y());
-        rect.setBottom(textInfo->pos.y() + textInfo->staticText.size().height());
-        return rect;
-    }
-
-    default:
-        break;
-    }
-
-    return m_textRect;
-}
-
-QRectF KFileItemListWidget::expansionToggleRect() const
-{
-    const_cast<KFileItemListWidget*>(this)->triggerCacheRefreshing();
-    return m_isExpandable ? m_expansionArea : QRectF();
-}
-
-QRectF KFileItemListWidget::selectionToggleRect() const
-{
-    const_cast<KFileItemListWidget*>(this)->triggerCacheRefreshing();
-
-    const int iconHeight = styleOption().iconSize;
-
-    int toggleSize = KIconLoader::SizeSmall;
-    if (iconHeight >= KIconLoader::SizeEnormous) {
-        toggleSize = KIconLoader::SizeMedium;
-    } else if (iconHeight >= KIconLoader::SizeLarge) {
-        toggleSize = KIconLoader::SizeSmallMedium;
-    }
-
-    QPointF pos = iconRect().topLeft();
-
-    // If the selection toggle has a very small distance to the
-    // widget borders, the size of the selection toggle will get
-    // increased to prevent an accidental clicking of the item
-    // when trying to hit the toggle.
-    const int widgetHeight = size().height();
-    const int widgetWidth = size().width();
-    const int minMargin = 2;
-
-    if (toggleSize + minMargin * 2 >= widgetHeight) {
-        pos.rx() -= (widgetHeight - toggleSize) / 2;
-        toggleSize = widgetHeight;
-        pos.setY(0);
-    }
-    if (toggleSize + minMargin * 2 >= widgetWidth) {
-        pos.ry() -= (widgetWidth - toggleSize) / 2;
-        toggleSize = widgetWidth;
-        pos.setX(0);
-    }
-
-    return QRectF(pos, QSizeF(toggleSize, toggleSize));
-}
-
-QSizeF KFileItemListWidget::itemSizeHint(int index, const KItemListView* view)
-{
-    const QHash<QByteArray, QVariant> values = view->model()->data(index);
-    const KItemListStyleOption& option = view->styleOption();
-    const int additionalRolesCount = qMax(view->visibleRoles().count() - 1, 0);
-
-    switch (static_cast<const KFileItemListView*>(view)->itemLayout()) {
-    case IconsLayout: {
-        const QString text = KStringHandler::preProcessWrap(values["name"].toString());
-
-        const qreal itemWidth = view->itemSize().width();
-        const qreal maxWidth = itemWidth - 2 * option.padding;
-        QTextLine line;
-
-        // Calculate the number of lines required for wrapping the name
-        QTextOption textOption(Qt::AlignHCenter);
-        textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
-
-        qreal textHeight = 0;
-        QTextLayout layout(text, option.font);
-        layout.setTextOption(textOption);
-        layout.beginLayout();
-        while ((line = layout.createLine()).isValid()) {
-            line.setLineWidth(maxWidth);
-            line.naturalTextWidth();
-            textHeight += line.height();
-        }
-        layout.endLayout();
-
-        // Add one line for each additional information
-        textHeight += additionalRolesCount * option.fontMetrics.lineSpacing();
-
-        const qreal maxTextHeight = option.maxTextSize.height();
-        if (maxTextHeight > 0 && textHeight > maxTextHeight) {
-            textHeight = maxTextHeight;
-        }
-
-        return QSizeF(itemWidth, textHeight + option.iconSize + option.padding * 3);
-    }
-
-    case CompactLayout: {
-        // For each row exactly one role is shown. Calculate the maximum required width that is necessary
-        // to show all roles without horizontal clipping.
-        qreal maximumRequiredWidth = 0.0;
-
-        foreach (const QByteArray& role, view->visibleRoles()) {
-            const QString text = KFileItemListWidget::roleText(role, values);
-            const qreal requiredWidth = option.fontMetrics.width(text);
-            maximumRequiredWidth = qMax(maximumRequiredWidth, requiredWidth);
-        }
-
-        qreal width = option.padding * 4 + option.iconSize + maximumRequiredWidth;
-        const qreal maxWidth = option.maxTextSize.width();
-        if (maxWidth > 0 && width > maxWidth) {
-            width = maxWidth;
-        }
-        const qreal height = option.padding * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * option.fontMetrics.lineSpacing());
-        return QSizeF(width, height);
-    }
-
-    case DetailsLayout: {
-        const qreal height = option.padding * 2 + qMax(option.iconSize, option.fontMetrics.height());
-        return QSizeF(-1, height);
-    }
-
-    default:
-        Q_ASSERT(false);
-        break;
-    }
-
-    return QSize();
-}
-
-qreal KFileItemListWidget::preferredRoleColumnWidth(const QByteArray& role,
-                                                    int index,
-                                                    const KItemListView* view)
-{
-
-    const QHash<QByteArray, QVariant> values = view->model()->data(index);
-    const KItemListStyleOption& option = view->styleOption();
-
-    const QString text = KFileItemListWidget::roleText(role, values);
-    qreal width = columnPadding(option);
-
-    if (role == "rating") {
-        width += preferredRatingSize(option).width();
-    } else {
-        width += option.fontMetrics.width(text);
-
-        if (role == "name") {
-            // Increase the width by the expansion-toggle and the current expansion level
-            const int expandedParentsCount = values.value("expandedParentsCount", 0).toInt();
-            width += option.padding + (expandedParentsCount + 1) * view->itemSize().height() + KIconLoader::SizeSmall;
-
-            // Increase the width by the required space for the icon
-            width += option.padding * 2 + option.iconSize;
-        }
-    }
-
-    return width;
-}
-
-void KFileItemListWidget::invalidateCache()
-{
-    m_dirtyLayout = true;
-    m_dirtyContent = true;
-}
-
-void KFileItemListWidget::refreshCache()
-{
-}
-
-void KFileItemListWidget::setTextColor(const QColor& color)
-{
-    if (color != m_customTextColor) {
-        m_customTextColor = color;
-        updateAdditionalInfoTextColor();
-        update();
-    }
-}
-
-QColor KFileItemListWidget::textColor() const
-{
-    if (m_customTextColor.isValid() && !isSelected()) {
-        return m_customTextColor;
-    }
-
-    const QPalette::ColorGroup group = isActiveWindow() ? QPalette::Active : QPalette::Inactive;
-    const QPalette::ColorRole role = isSelected() ? QPalette::HighlightedText : QPalette::Text;
-    return styleOption().palette.brush(group, role).color();
-}
-
-void KFileItemListWidget::setOverlay(const QPixmap& overlay)
-{
-    m_overlay = overlay;
-    m_dirtyContent = true;
-    update();
-}
-
-QPixmap KFileItemListWidget::overlay() const
-{
-    return m_overlay;
-}
-
-void KFileItemListWidget::dataChanged(const QHash<QByteArray, QVariant>& current,
-                                      const QSet<QByteArray>& roles)
-{
-    Q_UNUSED(current);
-
-    m_dirtyContent = true;
-
-    QSet<QByteArray> dirtyRoles;
-    if (roles.isEmpty()) {
-        dirtyRoles = visibleRoles().toSet();
-        dirtyRoles.insert("iconPixmap");
-        dirtyRoles.insert("iconName");
-    } else {
-        dirtyRoles = roles;
-    }
-
-    QSetIterator<QByteArray> it(dirtyRoles);
-    while (it.hasNext()) {
-        const QByteArray& role = it.next();
-        m_dirtyContentRoles.insert(role);
-    }
-}
-
-void KFileItemListWidget::visibleRolesChanged(const QList<QByteArray>& current,
-                                              const QList<QByteArray>& previous)
-{
-    Q_UNUSED(previous);
-    m_sortedVisibleRoles = current;
-    m_dirtyLayout = true;
-}
-
-void KFileItemListWidget::columnWidthChanged(const QByteArray& role,
-                                             qreal current,
-                                             qreal previous)
-{
-    Q_UNUSED(role);
-    Q_UNUSED(current);
-    Q_UNUSED(previous);
-    m_dirtyLayout = true;
-}
-
-void KFileItemListWidget::styleOptionChanged(const KItemListStyleOption& current,
-                                             const KItemListStyleOption& previous)
-{
-    Q_UNUSED(current);
-    Q_UNUSED(previous);
-    updateAdditionalInfoTextColor();
-    m_dirtyLayout = true;
-}
-
-void KFileItemListWidget::hoveredChanged(bool hovered)
-{
-    Q_UNUSED(hovered);
-    m_dirtyLayout = true;
-}
-
-void KFileItemListWidget::selectedChanged(bool selected)
-{
-    Q_UNUSED(selected);
-    updateAdditionalInfoTextColor();
-}
-
-void KFileItemListWidget::siblingsInformationChanged(const QBitArray& current, const QBitArray& previous)
-{
-    Q_UNUSED(current);
-    Q_UNUSED(previous);
-    m_dirtyLayout = true;
-}
-
-void KFileItemListWidget::editedRoleChanged(const QByteArray& current, const QByteArray& previous)
-{
-    Q_UNUSED(previous);
-
-   QGraphicsView* parent = scene()->views()[0];
-   if (current.isEmpty() || !parent || current != "name") {
-        if (m_roleEditor) {
-            emit roleEditingCanceled(index(), current, data().value(current));
-            m_roleEditor->deleteLater();
-            m_roleEditor = 0;
-        }
-        return;
-    }
-
-    Q_ASSERT(!m_roleEditor);
-
-    const TextInfo* textInfo = m_textInfo.value("name");
-
-    m_roleEditor = new KItemListRoleEditor(parent);
-    m_roleEditor->setIndex(index());
-    m_roleEditor->setRole(current);
-
-    const QString text = data().value(current).toString();
-    m_roleEditor->setPlainText(text);
-
-    QTextOption textOption = textInfo->staticText.textOption();
-    m_roleEditor->document()->setDefaultTextOption(textOption);
-
-    // Select the text without MIME-type extension
-    int selectionLength = text.length();
-
-    const QString extension = KMimeType::extractKnownExtension(text);
-    if (!extension.isEmpty()) {
-        selectionLength -= extension.length() + 1;
-    }
-
-    if (selectionLength > 0) {
-        QTextCursor cursor = m_roleEditor->textCursor();
-        cursor.movePosition(QTextCursor::StartOfBlock);
-        cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, selectionLength);
-        m_roleEditor->setTextCursor(cursor);
-    }
-
-    connect(m_roleEditor, SIGNAL(roleEditingCanceled(int,QByteArray,QVariant)),
-            this, SLOT(slotRoleEditingCanceled(int,QByteArray,QVariant)));
-    connect(m_roleEditor, SIGNAL(roleEditingFinished(int,QByteArray,QVariant)),
-            this, SLOT(slotRoleEditingFinished(int,QByteArray,QVariant)));
-
-    // Adjust the geometry of the editor
-    QRectF rect = roleEditingRect(current);
-    const int frameWidth = m_roleEditor->frameWidth();
-    rect.adjust(-frameWidth, -frameWidth, frameWidth, frameWidth);
-    rect.translate(pos());
-    if (rect.right() > parent->width()) {
-        rect.setWidth(parent->width() - rect.left());
-    }
-    if (rect.bottom() > parent->height()) {
-        rect.setHeight(parent->height() - rect.top());
-    }
-    m_roleEditor->setGeometry(rect.toRect());
-    m_roleEditor->show();
-    m_roleEditor->setFocus();
-}
-
-void KFileItemListWidget::resizeEvent(QGraphicsSceneResizeEvent* event)
-{
-    if (m_roleEditor) {
-        setEditedRole(QByteArray());
-        Q_ASSERT(!m_roleEditor);
-    }
-
-    KItemListWidget::resizeEvent(event);
-
-    m_dirtyLayout = true;
-}
-
-void KFileItemListWidget::showEvent(QShowEvent* event)
-{
-    KItemListWidget::showEvent(event);
-
-    // Listen to changes of the clipboard to mark the item as cut/uncut
-    KFileItemClipboard* clipboard = KFileItemClipboard::instance();
-
-    const KUrl itemUrl = data().value("url").value<KUrl>();
-    m_isCut = clipboard->isCut(itemUrl);
-
-    connect(clipboard, SIGNAL(cutItemsChanged()),
-            this, SLOT(slotCutItemsChanged()));
-}
-
-void KFileItemListWidget::hideEvent(QHideEvent* event)
-{
-    disconnect(KFileItemClipboard::instance(), SIGNAL(cutItemsChanged()),
-               this, SLOT(slotCutItemsChanged()));
-
-    KItemListWidget::hideEvent(event);
-}
-
-void KFileItemListWidget::slotCutItemsChanged()
-{
-    const KUrl itemUrl = data().value("url").value<KUrl>();
-    const bool isCut = KFileItemClipboard::instance()->isCut(itemUrl);
-    if (m_isCut != isCut) {
-        m_isCut = isCut;
-        m_pixmap = QPixmap();
-        m_dirtyContent = true;
-        update();
-    }
-}
-
-void KFileItemListWidget::slotRoleEditingCanceled(int index,
-                                                  const QByteArray& role,
-                                                  const QVariant& value)
-{
-    m_roleEditor->deleteLater();
-    m_roleEditor = 0;
-    emit roleEditingCanceled(index, role, value);
-    setEditedRole(QByteArray());
-}
-
-void KFileItemListWidget::slotRoleEditingFinished(int index,
-                                                  const QByteArray& role,
-                                                  const QVariant& value)
-{
-    m_roleEditor->deleteLater();
-    m_roleEditor = 0;
-    emit roleEditingFinished(index, role, value);
-    setEditedRole(QByteArray());
-}
-
-void KFileItemListWidget::triggerCacheRefreshing()
-{
-    if ((!m_dirtyContent && !m_dirtyLayout) || index() < 0) {
-        return;
-    }
-
-    refreshCache();
-
-    const QHash<QByteArray, QVariant> values = data();
-    m_isExpandable = m_supportsItemExpanding && values["isExpandable"].toBool();
-    m_isHidden = values["name"].toString().startsWith(QLatin1Char('.'));
-
-    updateExpansionArea();
-    updateTextsCache();
-    updatePixmapCache();
-
-    m_dirtyLayout = false;
-    m_dirtyContent = false;
-    m_dirtyContentRoles.clear();
-}
-
-void KFileItemListWidget::updateExpansionArea()
-{
-    if (m_supportsItemExpanding) {
-        const QHash<QByteArray, QVariant> values = data();
-        Q_ASSERT(values.contains("expandedParentsCount"));
-        const int expandedParentsCount = values.value("expandedParentsCount", 0).toInt();
-        if (expandedParentsCount >= 0) {
-            const qreal widgetHeight = size().height();
-            const qreal inc = (widgetHeight - KIconLoader::SizeSmall) / 2;
-            const qreal x = expandedParentsCount * widgetHeight + inc;
-            const qreal y = inc;
-            m_expansionArea = QRectF(x, y, KIconLoader::SizeSmall, KIconLoader::SizeSmall);
-            return;
-        }
-    }
-
-    m_expansionArea = QRectF();
-}
-
-void KFileItemListWidget::updatePixmapCache()
-{
-    // Precondition: Requires already updated m_textPos values to calculate
-    // the remaining height when the alignment is vertical.
-
-    const QSizeF widgetSize = size();
-    const bool iconOnTop = (m_layout == IconsLayout);
-    const KItemListStyleOption& option = styleOption();
-    const qreal padding = option.padding;
-
-    const int maxIconWidth = iconOnTop ? widgetSize.width() - 2 * padding : option.iconSize;
-    const int maxIconHeight = option.iconSize;
-
-    const QHash<QByteArray, QVariant> values = data();
-
-    bool updatePixmap = (m_pixmap.width() != maxIconWidth || m_pixmap.height() != maxIconHeight);
-    if (!updatePixmap && m_dirtyContent) {
-        updatePixmap = m_dirtyContentRoles.isEmpty()
-                       || m_dirtyContentRoles.contains("iconPixmap")
-                       || m_dirtyContentRoles.contains("iconName")
-                       || m_dirtyContentRoles.contains("iconOverlays");
-    }
-
-    if (updatePixmap) {
-        m_pixmap = values["iconPixmap"].value<QPixmap>();
-        if (m_pixmap.isNull()) {
-            // Use the icon that fits to the MIME-type
-            QString iconName = values["iconName"].toString();
-            if (iconName.isEmpty()) {
-                // The icon-name has not been not resolved by KFileItemModelRolesUpdater,
-                // use a generic icon as fallback
-                iconName = QLatin1String("unknown");
-            }
-            m_pixmap = pixmapForIcon(iconName, maxIconHeight);
-        } else if (m_pixmap.width() != maxIconWidth || m_pixmap.height() != maxIconHeight) {
-            // A custom pixmap has been applied. Assure that the pixmap
-            // is scaled to the maximum available size.
-            KPixmapModifier::scale(m_pixmap, QSize(maxIconWidth, maxIconHeight));
-        }
-
-        const QStringList overlays = values["iconOverlays"].toStringList();
-
-        // Strangely KFileItem::overlays() returns empty string-values, so
-        // we need to check first whether an overlay must be drawn at all.
-        // It is more efficient to do it here, as KIconLoader::drawOverlays()
-        // assumes that an overlay will be drawn and has some additional
-        // setup time.
-        foreach (const QString& overlay, overlays) {
-            if (!overlay.isEmpty()) {
-                // There is at least one overlay, draw all overlays above m_pixmap
-                // and cancel the check
-                KIconLoader::global()->drawOverlays(overlays, m_pixmap, KIconLoader::Desktop);
-                break;
-            }
-        }
-
-        if (m_isCut) {
-            applyCutEffect(m_pixmap);
-        }
-
-        if (m_isHidden) {
-            applyHiddenEffect(m_pixmap);
-        }
-    }
-
-    if (!m_overlay.isNull()) {
-        QPainter painter(&m_pixmap);
-        painter.drawPixmap(0, m_pixmap.height() - m_overlay.height(), m_overlay);
-    }
-
-    int scaledIconSize = 0;
-    if (iconOnTop) {
-        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();
-        scaledIconSize = (requiredTextHeight < maxIconHeight) ?
-                           widgetSize.height() - 2 * padding : maxIconHeight;
-    }
-
-    const int maxScaledIconWidth = iconOnTop ? widgetSize.width() - 2 * padding : scaledIconSize;
-    const int maxScaledIconHeight = scaledIconSize;
-
-    m_scaledPixmapSize = m_pixmap.size();
-    m_scaledPixmapSize.scale(maxScaledIconWidth, maxScaledIconHeight, Qt::KeepAspectRatio);
-
-    if (iconOnTop) {
-        // Center horizontally and align on bottom within the icon-area
-        m_pixmapPos.setX((widgetSize.width() - m_scaledPixmapSize.width()) / 2);
-        m_pixmapPos.setY(padding + scaledIconSize - m_scaledPixmapSize.height());
-    } else {
-        // Center horizontally and vertically within the icon-area
-        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);
-    }
-
-    m_iconRect = QRectF(m_pixmapPos, QSizeF(m_scaledPixmapSize));
-
-    // Prepare the pixmap that is used when the item gets hovered
-    if (isHovered()) {
-        m_hoverPixmap = m_pixmap;
-        KIconEffect* effect = KIconLoader::global()->iconEffect();
-        // In the KIconLoader terminology, active = hover.
-        if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState)) {
-            m_hoverPixmap = effect->apply(m_pixmap, KIconLoader::Desktop, KIconLoader::ActiveState);
-        } else {
-            m_hoverPixmap = m_pixmap;
-        }
-    } else if (hoverOpacity() <= 0.0) {
-        // No hover animation is ongoing. Clear m_hoverPixmap to save memory.
-        m_hoverPixmap = QPixmap();
-    }
-}
-
-void KFileItemListWidget::updateTextsCache()
-{
-    QTextOption textOption;
-    switch (m_layout) {
-    case IconsLayout:
-        textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
-        textOption.setAlignment(Qt::AlignHCenter);
-        break;
-    case CompactLayout:
-    case DetailsLayout:
-        textOption.setAlignment(Qt::AlignLeft);
-        textOption.setWrapMode(QTextOption::NoWrap);
-        break;
-    default:
-        Q_ASSERT(false);
-        break;
-    }
-
-    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) {
-    case IconsLayout:   updateIconsLayoutTextCache(); break;
-    case CompactLayout: updateCompactLayoutTextCache(); break;
-    case DetailsLayout: updateDetailsLayoutTextCache(); break;
-    default: Q_ASSERT(false); break;
-    }
-
-    const TextInfo* ratingTextInfo = m_textInfo.value("rating");
-    if (ratingTextInfo) {
-        // The text of the rating-role has been set to empty to get
-        // replaced by a rating-image showing the rating as stars.
-        const KItemListStyleOption& option = styleOption();
-        QSizeF ratingSize = preferredRatingSize(option);
-
-        const qreal availableWidth = (m_layout == DetailsLayout)
-                                     ? columnWidth("rating") - columnPadding(option)
-                                     : m_textRect.width();
-        if (ratingSize.width() > availableWidth) {
-            ratingSize.rwidth() = availableWidth;
-        }
-        m_rating = QPixmap(ratingSize.toSize());
-        m_rating.fill(Qt::transparent);
-
-        QPainter painter(&m_rating);
-        const QRect rect(0, 0, m_rating.width(), m_rating.height());
-        const int rating = data().value("rating").toInt();
-        KRatingPainter::paintRating(&painter, rect, Qt::AlignJustify | Qt::AlignVCenter, rating);
-    } else if (!m_rating.isNull()) {
-        m_rating = QPixmap();
-    }
-}
-
-void KFileItemListWidget::updateIconsLayoutTextCache()
-{
-    //      +------+
-    //      | Icon |
-    //      +------+
-    //
-    //    Name role that
-    // might get wrapped above
-    //    several lines.
-    //  Additional role 1
-    //  Additional role 2
-
-    const QHash<QByteArray, QVariant> values = data();
-
-    const KItemListStyleOption& option = styleOption();
-    const qreal padding = option.padding;
-    const qreal maxWidth = size().width() - 2 * padding;
-    const qreal widgetHeight = size().height();
-    const qreal lineSpacing = option.fontMetrics.lineSpacing();
-
-    // Initialize properties for the "name" role. It will be used as anchor
-    // for initializing the position of the other roles.
-    TextInfo* nameTextInfo = m_textInfo.value("name");
-    const QString nameText = KStringHandler::preProcessWrap(values["name"].toString());
-    nameTextInfo->staticText.setText(nameText);
-
-    // Calculate the number of lines required for the name and the required width
-    qreal nameWidth = 0;
-    qreal nameHeight = 0;
-    QTextLine line;
-
-    const int additionalRolesCount = qMax(visibleRoles().count() - 1, 0);
-    const int maxNameLines = (option.maxTextSize.height() / int(lineSpacing)) - additionalRolesCount;
-
-    QTextLayout layout(nameTextInfo->staticText.text(), option.font);
-    layout.setTextOption(nameTextInfo->staticText.textOption());
-    layout.beginLayout();
-    int nameLineIndex = 0;
-    while ((line = layout.createLine()).isValid()) {
-        line.setLineWidth(maxWidth);
-        nameWidth = qMax(nameWidth, line.naturalTextWidth());
-        nameHeight += line.height();
-
-        ++nameLineIndex;
-        if (nameLineIndex == maxNameLines) {
-            // The maximum number of textlines has been reached. If this is
-            // the case provide an elided text if necessary.
-            const int textLength = line.textStart() + line.textLength();
-            if (textLength < nameText.length()) {
-                // Elide the last line of the text
-                QString lastTextLine = nameText.mid(line.textStart(), line.textLength());
-                lastTextLine = option.fontMetrics.elidedText(lastTextLine,
-                                                             Qt::ElideRight,
-                                                             line.naturalTextWidth() - 1);
-                const QString elidedText = nameText.left(line.textStart()) + lastTextLine;
-                nameTextInfo->staticText.setText(elidedText);
-            }
-            break;
-        }
-    }
-    layout.endLayout();
-
-    // Use one line for each additional information
-    nameTextInfo->staticText.setTextWidth(maxWidth);
-    nameTextInfo->pos = QPointF(padding, widgetHeight -
-                                         nameHeight -
-                                         additionalRolesCount * lineSpacing -
-                                         padding);
-    m_textRect = QRectF(padding + (maxWidth - nameWidth) / 2,
-                        nameTextInfo->pos.y(),
-                        nameWidth,
-                        nameHeight);
-
-    // Calculate the position for each additional information
-    qreal y = nameTextInfo->pos.y() + nameHeight;
-    foreach (const QByteArray& role, m_sortedVisibleRoles) {
-        if (role == "name") {
-            continue;
-        }
-
-        const QString text = roleText(role, values);
-        TextInfo* textInfo = m_textInfo.value(role);
-        textInfo->staticText.setText(text);
-
-        qreal requiredWidth = 0;
-
-        QTextLayout layout(text, option.font);
-        QTextOption textOption;
-        textOption.setWrapMode(QTextOption::NoWrap);
-        layout.setTextOption(textOption);
-
-        layout.beginLayout();
-        QTextLine textLine = layout.createLine();
-        if (textLine.isValid()) {
-            textLine.setLineWidth(maxWidth);
-            requiredWidth = textLine.naturalTextWidth();
-            if (requiredWidth > maxWidth) {
-                const QString elidedText = option.fontMetrics.elidedText(text, Qt::ElideRight, maxWidth);
-                textInfo->staticText.setText(elidedText);
-                requiredWidth = option.fontMetrics.width(elidedText);
-            }
-        }
-        layout.endLayout();
-
-        textInfo->pos = QPointF(padding, y);
-        textInfo->staticText.setTextWidth(maxWidth);
-
-        const QRectF textRect(padding + (maxWidth - requiredWidth) / 2, y, requiredWidth, lineSpacing);
-        m_textRect |= textRect;
-
-        y += lineSpacing;
-    }
-
-    // Add a padding to the text rectangle
-    m_textRect.adjust(-padding, -padding, padding, padding);
-}
-
-void KFileItemListWidget::updateCompactLayoutTextCache()
-{
-    // +------+  Name role
-    // | Icon |  Additional role 1
-    // +------+  Additional role 2
-
-    const QHash<QByteArray, QVariant> values = data();
-
-    const KItemListStyleOption& option = styleOption();
-    const qreal widgetHeight = size().height();
-    const qreal lineSpacing = option.fontMetrics.lineSpacing();
-    const qreal textLinesHeight = qMax(visibleRoles().count(), 1) * lineSpacing;
-    const int scaledIconSize = (textLinesHeight < option.iconSize) ? widgetHeight - 2 * option.padding : option.iconSize;
-
-    qreal maximumRequiredTextWidth = 0;
-    const qreal x = option.padding * 3 + scaledIconSize;
-    qreal y = qRound((widgetHeight - textLinesHeight) / 2);
-    const qreal maxWidth = size().width() - x - option.padding;
-    foreach (const QByteArray& role, m_sortedVisibleRoles) {
-        const QString text = roleText(role, values);
-        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);
-            textInfo->staticText.setText(elidedText);
-        }
-
-        textInfo->pos = QPointF(x, y);
-        textInfo->staticText.setTextWidth(maxWidth);
-
-        maximumRequiredTextWidth = qMax(maximumRequiredTextWidth, requiredWidth);
-
-        y += lineSpacing;
-    }
-
-    m_textRect = QRectF(x - option.padding, 0, maximumRequiredTextWidth + 2 * option.padding, widgetHeight);
-}
-
-void KFileItemListWidget::updateDetailsLayoutTextCache()
-{
-    // Precondition: Requires already updated m_expansionArea
-    // to determine the left position.
-
-    // +------+
-    // | Icon |  Name role   Additional role 1   Additional role 2
-    // +------+
-    m_textRect = QRectF();
-
-    const KItemListStyleOption& option = styleOption();
-    const QHash<QByteArray, QVariant> values = data();
-
-    const qreal widgetHeight = size().height();
-    const int scaledIconSize = widgetHeight - 2 * option.padding;
-    const int fontHeight = option.fontMetrics.height();
-
-    const qreal columnWidthInc = columnPadding(option);
-    qreal firstColumnInc = scaledIconSize;
-    if (m_supportsItemExpanding) {
-        firstColumnInc += (m_expansionArea.left() + m_expansionArea.right() + widgetHeight) / 2;
-    } else {
-        firstColumnInc += option.padding;
-    }
-
-    qreal x = firstColumnInc;
-    const qreal y = qMax(qreal(option.padding), (widgetHeight - fontHeight) / 2);
-
-    foreach (const QByteArray& role, m_sortedVisibleRoles) {
-        const RoleType type = roleType(role);
-
-        QString text = roleText(role, values);
-
-        // Elide the text in case it does not fit into the available column-width
-        qreal requiredWidth = option.fontMetrics.width(text);
-        const qreal roleWidth = columnWidth(role);
-        qreal availableTextWidth = roleWidth - columnWidthInc;
-        if (type == Name) {
-            availableTextWidth -= firstColumnInc;
-        }
-
-        if (requiredWidth > availableTextWidth) {
-            text = option.fontMetrics.elidedText(text, Qt::ElideRight, availableTextWidth);
-            requiredWidth = option.fontMetrics.width(text);
-        }
-
-        TextInfo* textInfo = m_textInfo.value(role);
-        textInfo->staticText.setText(text);
-        textInfo->pos = QPointF(x + columnWidthInc / 2, y);
-        x += roleWidth;
-
-        switch (type) {
-        case Name: {
-            const qreal textWidth = option.extendedSelectionRegion
-                                    ? size().width() - textInfo->pos.x()
-                                    : requiredWidth + 2 * option.padding;
-            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
-            // from the expansion-level shown in the name column
-            x -= firstColumnInc;
-            break;
-        }
-        case Size:
-            // The values for the size should be right aligned
-            textInfo->pos.rx() += roleWidth - requiredWidth - columnWidthInc;
-            break;
-
-        default:
-            break;
-        }
-    }
-}
-
-void KFileItemListWidget::updateAdditionalInfoTextColor()
-{
-    QColor c1;
-    if (m_customTextColor.isValid()) {
-        c1 = m_customTextColor;
-    } else if (isSelected() && m_layout != DetailsLayout) {
-        c1 = styleOption().palette.highlightedText().color();
-    } else {
-        c1 = styleOption().palette.text().color();
-    }
-
-    // For the color of the additional info the inactive text color
-    // is not used as this might lead to unreadable text for some color schemes. Instead
-    // the text color c1 is slightly mixed with the background color.
-    const QColor c2 = styleOption().palette.base().color();
-    const int p1 = 70;
-    const int p2 = 100 - p1;
-    m_additionalInfoTextColor = QColor((c1.red()   * p1 + c2.red()   * p2) / 100,
-                                       (c1.green() * p1 + c2.green() * p2) / 100,
-                                       (c1.blue()  * p1 + c2.blue()  * p2) / 100);
-}
-
-void KFileItemListWidget::drawPixmap(QPainter* painter, const QPixmap& pixmap)
-{
-    if (m_scaledPixmapSize != pixmap.size()) {
-        QPixmap scaledPixmap = pixmap;
-        KPixmapModifier::scale(scaledPixmap, m_scaledPixmapSize);
-        painter->drawPixmap(m_pixmapPos, scaledPixmap);
-
-#ifdef KFILEITEMLISTWIDGET_DEBUG
-        painter->setPen(Qt::blue);
-        painter->drawRect(QRectF(m_pixmapPos, QSizeF(m_scaledPixmapSize)));
-#endif
-    } else {
-        painter->drawPixmap(m_pixmapPos, pixmap);
-    }
-}
-
-void KFileItemListWidget::drawSiblingsInformation(QPainter* painter)
-{
-    const int siblingSize = size().height();
-    const int x = (m_expansionArea.left() + m_expansionArea.right() - siblingSize) / 2;
-    QRect siblingRect(x, 0, siblingSize, siblingSize);
-
-    QStyleOption option;
-    bool isItemSibling = true;
-
-    const QBitArray siblings = siblingsInformation();
-    for (int i = siblings.count() - 1; i >= 0; --i) {
-        option.rect = siblingRect;
-        option.state = siblings.at(i) ? QStyle::State_Sibling : QStyle::State_None;
-
-        if (isItemSibling) {
-            option.state |= QStyle::State_Item;
-            if (m_isExpandable) {
-                option.state |= QStyle::State_Children;
-            }
-            if (data()["isExpanded"].toBool()) {
-                option.state |= QStyle::State_Open;
-            }
-            isItemSibling = false;
-        }
-
-        style()->drawPrimitive(QStyle::PE_IndicatorBranch, &option, painter);
-
-        siblingRect.translate(-siblingRect.width(), 0);
-    }
-}
-
-QRectF KFileItemListWidget::roleEditingRect(const QByteArray& role) const
-{
-    const TextInfo* textInfo = m_textInfo.value(role);
-    if (!textInfo) {
-        return QRectF();
-    }
-
-    QRectF rect(textInfo->pos, textInfo->staticText.size());
-    if (m_layout == DetailsLayout) {
-        rect.setWidth(columnWidth(role) - rect.x());
-    }
-
-    return rect;
-}
-
-QPixmap KFileItemListWidget::pixmapForIcon(const QString& name, int size)
-{
-    const KIcon icon(name);
-
-    int requestedSize;
-    if (size <= KIconLoader::SizeSmall) {
-        requestedSize = KIconLoader::SizeSmall;
-    } else if (size <= KIconLoader::SizeSmallMedium) {
-        requestedSize = KIconLoader::SizeSmallMedium;
-    } else if (size <= KIconLoader::SizeMedium) {
-        requestedSize = KIconLoader::SizeMedium;
-    } else if (size <= KIconLoader::SizeLarge) {
-        requestedSize = KIconLoader::SizeLarge;
-    } else if (size <= KIconLoader::SizeHuge) {
-        requestedSize = KIconLoader::SizeHuge;
-    } else if (size <= KIconLoader::SizeEnormous) {
-        requestedSize = KIconLoader::SizeEnormous;
-    } else if (size <= KIconLoader::SizeEnormous * 2) {
-        requestedSize = KIconLoader::SizeEnormous * 2;
-    } else {
-        requestedSize = size;
-    }
-
-    QPixmap pixmap = icon.pixmap(requestedSize, requestedSize);
-    if (requestedSize != size) {
-        KPixmapModifier::scale(pixmap, QSize(size, size));
-    }
-
-    return pixmap;
-}
-
-void KFileItemListWidget::applyCutEffect(QPixmap& pixmap)
-{
-    KIconEffect* effect = KIconLoader::global()->iconEffect();
-    pixmap = effect->apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
-}
-
-void KFileItemListWidget::applyHiddenEffect(QPixmap& pixmap)
+KFileItemListWidgetInformant::KFileItemListWidgetInformant() :
+    KStandardItemListWidgetInformant()
 {
-    KIconEffect::semiTransparent(pixmap);
 }
 
-KFileItemListWidget::RoleType KFileItemListWidget::roleType(const QByteArray& role)
+KFileItemListWidgetInformant::~KFileItemListWidgetInformant()
 {
-    static QHash<QByteArray, RoleType> rolesHash;
-    if (rolesHash.isEmpty()) {
-        rolesHash.insert("name", Name);
-        rolesHash.insert("size", Size);
-        rolesHash.insert("date", Date);
-        rolesHash.insert("rating", Rating);
-    }
-
-    return rolesHash.value(role, Generic);
 }
 
-QString KFileItemListWidget::roleText(const QByteArray& role, const QHash<QByteArray, QVariant>& values)
+QString KFileItemListWidgetInformant::roleText(const QByteArray& role,
+                                               const QHash<QByteArray, QVariant>& values) const
 {
     QString text;
     const QVariant roleValue = values.value(role);
 
-    switch (roleType(role)) {
-    case Size: {
+    // Implementation note: In case if more roles require a custom handling
+    // use a hash + switch for a linear runtime.
+
+    if (role == "size") {
         if (values.value("isDir").toBool()) {
             // The item represents a directory. Show the number of sub directories
             // instead of the file size of the directory.
@@ -1230,41 +59,33 @@ QString KFileItemListWidget::roleText(const QByteArray& role, const QHash<QByteA
             const KIO::filesize_t size = roleValue.value<KIO::filesize_t>();
             text = KGlobal::locale()->formatByteSize(size);
         }
-        break;
-    }
-
-    case Date: {
+    } else if (role == "date") {
         const QDateTime dateTime = roleValue.toDateTime();
         text = KGlobal::locale()->formatDateTime(dateTime);
-        break;
+    } else {
+        text = KStandardItemListWidgetInformant::roleText(role, values);
     }
 
-    case Rating:
-        // Always use an empty text, as the rating is shown by the image m_rating.
-        break;
-
-    case Name:
-    case Generic:
-        text = roleValue.toString();
-        break;
+    return text;
+}
 
-    default:
-        Q_ASSERT(false);
-        break;
-    }
+KFileItemListWidget::KFileItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) :
+    KStandardItemListWidget(informant, parent)
+{
+}
 
-    return text;
+KFileItemListWidget::~KFileItemListWidget()
+{
 }
 
-QSizeF KFileItemListWidget::preferredRatingSize(const KItemListStyleOption& option)
+KItemListWidgetInformant* KFileItemListWidget::createInformant()
 {
-    const qreal height = option.fontMetrics.ascent();
-    return QSizeF(height * 5, height);
+    return new KFileItemListWidgetInformant();
 }
 
-qreal KFileItemListWidget::columnPadding(const KItemListStyleOption& option)
+bool KFileItemListWidget::isRoleRightAligned(const QByteArray& role) const
 {
-    return option.padding * 6;
+    return role == "size";
 }
 
 #include "kfileitemlistwidget.moc"
index 33d348babf3211e11c18fea951771843f4bdd890..4bd37548165e5ef96200647739e70260f9d5b535 100644 (file)
 
 #include <libdolphin_export.h>
 
-#include <kitemviews/kitemlistwidget.h>
+#include <kitemviews/kstandarditemlistwidget.h>
 
-#include <QPixmap>
-#include <QPointF>
-#include <QStaticText>
+class LIBDOLPHINPRIVATE_EXPORT KFileItemListWidgetInformant : public KStandardItemListWidgetInformant
+{
+public:
+    KFileItemListWidgetInformant();
+    virtual ~KFileItemListWidgetInformant();
 
-class KItemListRoleEditor;
-class KItemListStyleOption;
-class KItemListView;
+protected:
+    virtual QString roleText(const QByteArray& role, const QHash<QByteArray, QVariant>& values) const;
+};
 
-class LIBDOLPHINPRIVATE_EXPORT KFileItemListWidget : public KItemListWidget
+class LIBDOLPHINPRIVATE_EXPORT KFileItemListWidget : public KStandardItemListWidget
 {
     Q_OBJECT
 
 public:
-    enum Layout
-    {
-        IconsLayout,
-        CompactLayout,
-        DetailsLayout
-    };
-
-    KFileItemListWidget(QGraphicsItem* parent);
+    KFileItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent);
     virtual ~KFileItemListWidget();
 
-    void setLayout(Layout layout);
-    Layout layout() const;
-
-    void setSupportsItemExpanding(bool supportsItemExpanding);
-    bool supportsItemExpanding() const;
-
-    virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0);
-
-    virtual QRectF iconRect() const;
-    virtual QRectF textRect() const;
-    virtual QRectF textFocusRect() const;
-    virtual QRectF expansionToggleRect() const;
-    virtual QRectF selectionToggleRect() const;
-
-    /**
-     * Implementation of KItemListWidgetCreatorBase::itemSizeHint() when
-     * using the KItemListWidgetCreator-template.
-     *
-     * @see KItemListView
-     */
-    static QSizeF itemSizeHint(int index, const KItemListView* view);
-
-    /**
-     * Implementation of KItemListWidgetCreatorBase::preferredRoleColumnWidth() when
-     * using the KItemListWidgetCreator-template.
-     *
-     * @see KItemListView
-     */
-    static qreal preferredRoleColumnWidth(const QByteArray& role, int index, const KItemListView* view);
+    static KItemListWidgetInformant* createInformant();
 
 protected:
-    /**
-     * Invalidates the cache which results in calling KFileItemListWidget::refreshCache() as
-     * soon as the item need to gets repainted.
-     */
-    void invalidateCache();
-
-    /**
-     * Is called if the cache got invalidated by KFileItemListWidget::invalidateCache().
-     * The default implementation is empty.
-     */
-    virtual void refreshCache();
-
-    void setTextColor(const QColor& color);
-    QColor textColor() const;
-
-    void setOverlay(const QPixmap& overlay);
-    QPixmap overlay() const;
-
-    virtual void dataChanged(const QHash<QByteArray, QVariant>& current, const QSet<QByteArray>& roles = QSet<QByteArray>());
-    virtual void visibleRolesChanged(const QList<QByteArray>& current, const QList<QByteArray>& previous);
-    virtual void columnWidthChanged(const QByteArray& role, qreal current, qreal previous);
-    virtual void styleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous);
-    virtual void hoveredChanged(bool hovered);
-    virtual void selectedChanged(bool selected);
-    virtual void siblingsInformationChanged(const QBitArray& current, const QBitArray& previous);
-    virtual void editedRoleChanged(const QByteArray& current, const QByteArray& previous);
-    virtual void resizeEvent(QGraphicsSceneResizeEvent* event);
-    virtual void showEvent(QShowEvent* event);
-    virtual void hideEvent(QHideEvent* event);
-
-private slots:
-    void slotCutItemsChanged();
-    void slotRoleEditingCanceled(int index, const QByteArray& role, const QVariant& value);
-    void slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value);
-
-private:
-    /**
-     * Typedefinitions for roles that require a special handling
-     * and must be accessible in a fast way. The mapping of a
-     * QByteArray role to the type is done by KFileItemListWidget::roleType().
-     */
-    enum RoleType {
-        Name,
-        Size,
-        Date,
-        Rating,
-        Generic  // Mandatory last entry
-    };
-
-    void triggerCacheRefreshing();
-    void updateExpansionArea();
-    void updatePixmapCache();
-
-    void updateTextsCache();
-    void updateIconsLayoutTextCache();
-    void updateCompactLayoutTextCache();
-    void updateDetailsLayoutTextCache();
-
-    void updateAdditionalInfoTextColor();
-
-    void drawPixmap(QPainter* painter, const QPixmap& pixmap);
-    void drawSiblingsInformation(QPainter* painter);
-
-    QRectF roleEditingRect(const QByteArray &role) const;
-
-    static QPixmap pixmapForIcon(const QString& name, int size);
-    static void applyCutEffect(QPixmap& pixmap);
-    static void applyHiddenEffect(QPixmap& pixmap);
-    static RoleType roleType(const QByteArray& role);
-
-    /**
-     * @return Preferred size of the rating-image based on the given
-     *         style-option. The height of the font is taken as
-     *         reference.
-     */
-    static QSizeF preferredRatingSize(const KItemListStyleOption& option);
-
-    /**
-     * @return Horizontal padding in pixels that is added to the required width of
-     *         a column to display the content.
-     */
-    static qreal columnPadding(const KItemListStyleOption& option);
-
-    /**
-     * @return Shown string for the role \p role of the item with the values \p values.
-     */
-    static QString roleText(const QByteArray& role, const QHash<QByteArray, QVariant>& values);
-
-private:
-    bool m_isCut;
-    bool m_isHidden;
-    bool m_isExpandable;
-    bool m_supportsItemExpanding;
-
-    bool m_dirtyLayout;
-    bool m_dirtyContent;
-    QSet<QByteArray> m_dirtyContentRoles;
-
-    Layout m_layout;
-    QPointF m_pixmapPos;
-    QPixmap m_pixmap;
-    QSize m_scaledPixmapSize;
-
-    QRectF m_iconRect;          // Cache for KItemListWidget::iconRect()
-    QPixmap m_hoverPixmap;      // Cache for modified m_pixmap when hovering the item
-
-    struct TextInfo
-    {
-        QPointF pos;
-        QStaticText staticText;
-    };
-    QHash<QByteArray, TextInfo*> m_textInfo;
-
-    QRectF m_textRect;
-
-    QList<QByteArray> m_sortedVisibleRoles;
-
-    QRectF m_expansionArea;
-
-    QColor m_customTextColor;
-    QColor m_additionalInfoTextColor;
-
-    QPixmap m_overlay;
-    QPixmap m_rating;
-
-    KItemListRoleEditor* m_roleEditor;
+    virtual bool isRoleRightAligned(const QByteArray& role) const;
 };
 
 #endif
index 8710f4440980a0258b790e955db7a90640bbb4be..ac8fc3bef4553f7ca449527ae6324eac2a6ddf25 100644 (file)
@@ -35,7 +35,7 @@
 // #define KFILEITEMMODEL_DEBUG
 
 KFileItemModel::KFileItemModel(QObject* parent) :
-    KItemModelBase("name", parent),
+    KItemModelBase("text", parent),
     m_dirLister(0),
     m_naturalSorting(KGlobalSettings::naturalSorting()),
     m_sortDirsFirst(true),
@@ -77,7 +77,7 @@ KFileItemModel::KFileItemModel(QObject* parent) :
     resetRoles();
     m_requestRole[NameRole] = true;
     m_requestRole[IsDirRole] = true;
-    m_roles.insert("name");
+    m_roles.insert("text");
     m_roles.insert("isDir");
 
     // For slow KIO-slaves like used for searching it makes sense to show results periodically even
@@ -253,12 +253,12 @@ int KFileItemModel::indexForKeyboardSearch(const QString& text, int startFromInd
 {
     startFromIndex = qMax(0, startFromIndex);
     for (int i = startFromIndex; i < count(); ++i) {
-        if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
+        if (data(i)["text"].toString().startsWith(text, Qt::CaseInsensitive)) {
             return i;
         }
     }
     for (int i = 0; i < startFromIndex; ++i) {
-        if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
+        if (data(i)["text"].toString().startsWith(text, Qt::CaseInsensitive)) {
             return i;
         }
     }
@@ -1165,7 +1165,7 @@ QHash<QByteArray, QVariant> KFileItemModel::retrieveData(const KFileItem& item)
     }
 
     if (m_requestRole[NameRole]) {
-        data.insert("name", item.text());
+        data.insert("text", item.text());
     }
 
     if (m_requestRole[SizeRole]) {
@@ -1523,7 +1523,7 @@ QList<QPair<int, QVariant> > KFileItemModel::nameRoleGroups() const
             continue;
         }
 
-        const QString name = m_itemData.at(i)->values.value("name").toString();
+        const QString name = m_itemData.at(i)->values.value("text").toString();
 
         // Use the first character of the name as group indication
         QChar newFirstChar = name.at(0).toUpper();
@@ -1873,7 +1873,7 @@ const KFileItemModel::RoleInfoMap* KFileItemModel::rolesInfoMap(int& count)
     static const RoleInfoMap rolesInfoMap[] = {
     //  | 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 },
+        { "text",        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 },
index b29c76c9201be76a711bf5f49f88923d12d72e5f..2683336e1e221d88c93233f5c577ceca58a459c8 100644 (file)
@@ -108,7 +108,7 @@ public:
     virtual bool supportsDropping(int index) const;
 
     /** @reimp */
-    virtual QString roleDescription(const QByteArray& typeForRole) const;
+    virtual QString roleDescription(const QByteArray& role) const;
 
     /** @reimp */
     virtual QList<QPair<int, QVariant> > groups() const;
index 5a485b62c3338c89fa1934a42cb7eee6a1a610ec..5500851c8c92c564bf3130c66198cea9b61eb8c7 100644 (file)
@@ -67,8 +67,6 @@ void KItemListContainerViewport::wheelEvent(QWheelEvent* event)
     event->ignore();
 }
 
-
-
 KItemListContainer::KItemListContainer(KItemListController* controller, QWidget* parent) :
     QAbstractScrollArea(parent),
     m_controller(controller),
@@ -77,20 +75,32 @@ KItemListContainer::KItemListContainer(KItemListController* controller, QWidget*
 {
     Q_ASSERT(controller);
     controller->setParent(this);
-    initialize();
-}
 
-KItemListContainer::KItemListContainer(QWidget* parent) :
-    QAbstractScrollArea(parent),
-    m_controller(0),
-    m_horizontalSmoothScroller(0),
-    m_verticalSmoothScroller(0)
-{
-    initialize();
+    QGraphicsView* graphicsView = new KItemListContainerViewport(new QGraphicsScene(this), this);
+    setViewport(graphicsView);
+
+    m_horizontalSmoothScroller = new KItemListSmoothScroller(horizontalScrollBar(), this);
+    m_verticalSmoothScroller = new KItemListSmoothScroller(verticalScrollBar(), this);
+
+    if (controller->model()) {
+        slotModelChanged(controller->model(), 0);
+    }
+    if (controller->view()) {
+        slotViewChanged(controller->view(), 0);
+    }
+
+    connect(controller, SIGNAL(modelChanged(KItemModelBase*,KItemModelBase*)),
+            this, SLOT(slotModelChanged(KItemModelBase*,KItemModelBase*)));
+    connect(controller, SIGNAL(viewChanged(KItemListView*,KItemListView*)),
+            this, SLOT(slotViewChanged(KItemListView*,KItemListView*)));
 }
 
 KItemListContainer::~KItemListContainer()
 {
+    // Don't rely on the QObject-order to delete the controller, otherwise
+    // the QGraphicsScene might get deleted before the view.
+    delete m_controller;
+    m_controller = 0;
 }
 
 KItemListController* KItemListContainer::controller() const
@@ -98,6 +108,33 @@ KItemListController* KItemListContainer::controller() const
     return m_controller;
 }
 
+void KItemListContainer::setEnabledFrame(bool enable)
+{
+    QGraphicsView* graphicsView = qobject_cast<QGraphicsView*>(viewport());
+    if (enable) {
+        setFrameShape(QFrame::StyledPanel);
+        graphicsView->setPalette(palette());
+        graphicsView->viewport()->setAutoFillBackground(true);
+    } else {
+        setFrameShape(QFrame::NoFrame);
+        // Make the background of the container transparent and apply the window-text color
+        // to the text color, so that enough contrast is given for all color
+        // schemes
+        QPalette p = graphicsView->palette();
+        p.setColor(QPalette::Active,   QPalette::Text, p.color(QPalette::Active,   QPalette::WindowText));
+        p.setColor(QPalette::Inactive, QPalette::Text, p.color(QPalette::Inactive, QPalette::WindowText));
+        p.setColor(QPalette::Disabled, QPalette::Text, p.color(QPalette::Disabled, QPalette::WindowText));
+        graphicsView->setPalette(p);
+        graphicsView->viewport()->setAutoFillBackground(false);
+    }
+}
+
+bool KItemListContainer::enabledFrame() const
+{
+    const QGraphicsView* graphicsView = qobject_cast<QGraphicsView*>(viewport());
+    return graphicsView->autoFillBackground();
+}
+
 void KItemListContainer::keyPressEvent(QKeyEvent* event)
 {
     // TODO: We should find a better way to handle the key press events in the view.
@@ -355,29 +392,4 @@ void KItemListContainer::updateScrollOffsetScrollBarPolicy()
     }
 }
 
-void KItemListContainer::initialize()
-{
-    if (m_controller) {
-        if (m_controller->model()) {
-            slotModelChanged(m_controller->model(), 0);
-        }
-        if (m_controller->view()) {
-            slotViewChanged(m_controller->view(), 0);
-        }
-    } else {
-        m_controller = new KItemListController(this);
-    }
-
-    connect(m_controller, SIGNAL(modelChanged(KItemModelBase*,KItemModelBase*)),
-            this, SLOT(slotModelChanged(KItemModelBase*,KItemModelBase*)));
-    connect(m_controller, SIGNAL(viewChanged(KItemListView*,KItemListView*)),
-            this, SLOT(slotViewChanged(KItemListView*,KItemListView*)));
-
-    QGraphicsView* graphicsView = new KItemListContainerViewport(new QGraphicsScene(this), this);
-    setViewport(graphicsView);
-
-    m_horizontalSmoothScroller = new KItemListSmoothScroller(horizontalScrollBar(), this);
-    m_verticalSmoothScroller = new KItemListSmoothScroller(verticalScrollBar(), this);
-}
-
 #include "kitemlistcontainer.moc"
index b41f48a7f189d556e0203e55a90de6d24e6578a0..474a9ecc03d3528c4208ff73bf2eff564970e3c7 100644 (file)
@@ -37,6 +37,8 @@ class QPropertyAnimation;
 /**
  * @brief Provides a QWidget based scrolling view for a KItemListController.
  *
+ * The model and view are maintained by the KItemListController.
+ *
  * @see KItemListController
  */
 class LIBDOLPHINPRIVATE_EXPORT KItemListContainer : public QAbstractScrollArea
@@ -44,12 +46,19 @@ class LIBDOLPHINPRIVATE_EXPORT KItemListContainer : public QAbstractScrollArea
     Q_OBJECT
 
 public:
+    /**
+     * @param controller Controller that maintains the model and the view.
+     *                   The KItemListContainer takes ownership of the controller
+     *                   (the parent will be set to the KItemListContainer).
+     * @param parent     Optional parent widget.
+     */
     explicit KItemListContainer(KItemListController* controller, QWidget* parent = 0);
-    KItemListContainer(QWidget* parent = 0);
     virtual ~KItemListContainer();
-
     KItemListController* controller() const;
 
+    void setEnabledFrame(bool enable);
+    bool enabledFrame() const;
+
 protected:
     virtual void keyPressEvent(QKeyEvent* event);
     virtual void showEvent(QShowEvent* event);
@@ -66,7 +75,6 @@ private slots:
     void updateItemOffsetScrollBar();
 
 private:
-    void initialize();
     void updateGeometries();
     void updateSmoothScrollers(Qt::Orientation orientation);
 
index c0f565b4dd94ec34a703f8b926b563dd77a9c4b6..011a3b57dd97e2c6b1573347d95305952e6ba14d 100644 (file)
@@ -41,7 +41,7 @@
 #include <QMimeData>
 #include <QTimer>
 
-KItemListController::KItemListController(QObject* parent) :
+KItemListController::KItemListController(KItemModelBase* model, KItemListView* view, QObject* parent) :
     QObject(parent),
     m_singleClickActivation(KGlobalSettings::singleClick()),
     m_selectionTogglePressed(false),
@@ -65,10 +65,20 @@ KItemListController::KItemListController(QObject* parent) :
     m_autoActivationTimer->setSingleShot(true);
     m_autoActivationTimer->setInterval(-1);
     connect(m_autoActivationTimer, SIGNAL(timeout()), this, SLOT(slotAutoActivationTimeout()));
+
+    setModel(model);
+    setView(view);
 }
 
 KItemListController::~KItemListController()
 {
+    setView(0);
+    delete m_view;
+    m_view = 0;
+
+    setModel(0);
+    delete m_model;
+    m_model = 0;
 }
 
 void KItemListController::setModel(KItemModelBase* model)
@@ -79,6 +89,9 @@ void KItemListController::setModel(KItemModelBase* model)
 
     KItemModelBase* oldModel = m_model;
     m_model = model;
+    if (m_model) {
+        m_model->setParent(this);
+    }
 
     if (m_view) {
         m_view->setModel(m_model);
@@ -116,6 +129,7 @@ void KItemListController::setView(KItemListView* view)
         m_view->setController(this);
         m_view->setModel(m_model);
         connect(m_view, SIGNAL(scrollOffsetChanged(qreal,qreal)), this, SLOT(slotViewScrollOffsetChanged(qreal,qreal)));
+        updateExtendedSelectionRegion();
     }
 
     emit viewChanged(m_view, oldView);
@@ -129,6 +143,7 @@ KItemListView* KItemListController::view() const
 void KItemListController::setSelectionBehavior(SelectionBehavior behavior)
 {
     m_selectionBehavior = behavior;
+    updateExtendedSelectionRegion();
 }
 
 KItemListController::SelectionBehavior KItemListController::selectionBehavior() const
@@ -1159,4 +1174,16 @@ qreal KItemListController::keyboardAnchorPos(int index) const
     return 0;
 }
 
+void KItemListController::updateExtendedSelectionRegion()
+{
+    if (m_view) {
+        const bool extend = (m_selectionBehavior != MultiSelection);
+        KItemListStyleOption option = m_view->styleOption();
+        if (option.extendedSelectionRegion != extend) {
+            option.extendedSelectionRegion = extend;
+            m_view->setStyleOption(option);
+        }
+    }
+}
+
 #include "kitemlistcontroller.moc"
index b44fcca3c8447056cc451f86f5266b1fbd5274c0..db31d50c3d4387f517ff5a1036fe0bd5ebfaeeca 100644 (file)
@@ -72,7 +72,12 @@ public:
         MultiSelection
     };
 
-    KItemListController(QObject* parent = 0);
+    /**
+     * @param model  Model of the controller. The ownership is passed to the controller.
+     * @param view   View of the controller. The ownership is passed to the controller.
+     * @param parent Optional parent object.
+     */
+    KItemListController(KItemModelBase* model, KItemListView* view, QObject* parent = 0);
     virtual ~KItemListController();
 
     void setModel(KItemModelBase* model);
@@ -261,6 +266,13 @@ private:
      */
     qreal keyboardAnchorPos(int index) const;
 
+    /**
+     * Dependent on the selection-behavior the extendedSelectionRegion-property
+     * of the KItemListStyleOption from the view should be adjusted: If no
+     * rubberband selection is used the property should be enabled.
+     */
+    void updateExtendedSelectionRegion();
+
 private:
     bool m_singleClickActivation;
     bool m_selectionTogglePressed;
index 36cfeb088c58e8b103990b2bfc6307a2669b3e07..ac2587962e847791788e55cdbdf78439022abf25 100644 (file)
@@ -26,10 +26,10 @@ KItemListStyleOption::KItemListStyleOption() :
     font(),
     fontMetrics(QFont()),
     palette(),
-    padding(0),
-    horizontalMargin(0),
-    verticalMargin(0),
-    iconSize(KIconLoader::SizeMedium),
+    padding(-1),
+    horizontalMargin(-1),
+    verticalMargin(-1),
+    iconSize(-1),
     extendedSelectionRegion(false),
     maxTextSize()
 {
index d53c245890826ae5da6b7092edde8b9a029354f4..934edf050661ce0c58704e9cd5f685f5dede3d73 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "kitemlistview.h"
 
+#include <KDebug>
 #include "kitemlistcontroller.h"
 #include "kitemlistheader.h"
 #include "kitemlistselectionmanager.h"
@@ -33,8 +34,6 @@
 #include "private/kitemlistviewlayouter.h"
 #include "private/kitemlistviewanimation.h"
 
-#include <KDebug>
-
 #include <QCursor>
 #include <QGraphicsSceneMouseEvent>
 #include <QPainter>
@@ -113,91 +112,17 @@ KItemListView::KItemListView(QGraphicsWidget* parent) :
 
 KItemListView::~KItemListView()
 {
-    delete m_sizeHintResolver;
-    m_sizeHintResolver = 0;
-}
-
-void KItemListView::setScrollOrientation(Qt::Orientation orientation)
-{
-    const Qt::Orientation previousOrientation = m_layouter->scrollOrientation();
-    if (orientation == previousOrientation) {
-        return;
-    }
-
-    m_layouter->setScrollOrientation(orientation);
-    m_animation->setScrollOrientation(orientation);
-    m_sizeHintResolver->clearCache();
-
-    if (m_grouped) {
-        QMutableHashIterator<KItemListWidget*, KItemListGroupHeader*> it (m_visibleGroups);
-        while (it.hasNext()) {
-            it.next();
-            it.value()->setScrollOrientation(orientation);
-        }
-        updateGroupHeaderHeight();
-
-    }
-
-    doLayout(NoAnimation);
-
-    onScrollOrientationChanged(orientation, previousOrientation);
-    emit scrollOrientationChanged(orientation, previousOrientation);
-}
-
-Qt::Orientation KItemListView::scrollOrientation() const
-{
-    return m_layouter->scrollOrientation();
-}
+    // The group headers are children of the widgets created by
+    // widgetCreator(). So it is mandatory to delete the group headers
+    // first.
+    delete m_groupHeaderCreator;
+    m_groupHeaderCreator = 0;
 
-void KItemListView::setItemSize(const QSizeF& size)
-{
-    const QSizeF previousSize = m_itemSize;
-    if (size == previousSize) {
-        return;
-    }
+    delete m_widgetCreator;
+    m_widgetCreator = 0;
 
-    // Skip animations when the number of rows or columns
-    // are changed in the grid layout. Although the animation
-    // engine can handle this usecase, it looks obtrusive.
-    const bool animate = !changesItemGridLayout(m_layouter->size(),
-                                                size,
-                                                m_layouter->itemMargin());
-
-    const bool alternateBackgroundsChanged = (m_visibleRoles.count() > 1) &&
-                                             (( m_itemSize.isEmpty() && !size.isEmpty()) ||
-                                              (!m_itemSize.isEmpty() && size.isEmpty()));
-
-    m_itemSize = size;
-
-    if (alternateBackgroundsChanged) {
-        // For an empty item size alternate backgrounds are drawn if more than
-        // one role is shown. Assure that the backgrounds for visible items are
-        // updated when changing the size in this context.
-        updateAlternateBackgrounds();
-    }
-
-    if (size.isEmpty()) {
-        if (m_headerWidget->automaticColumnResizing()) {
-            updatePreferredColumnWidths();
-        } else {
-            // Only apply the changed height and respect the header widths
-            // set by the user
-            const qreal currentWidth = m_layouter->itemSize().width();
-            const QSizeF newSize(currentWidth, size.height());
-            m_layouter->setItemSize(newSize);
-        }
-    } else {
-        m_layouter->setItemSize(size);
-    }
-
-    m_sizeHintResolver->clearCache();
-    doLayout(animate ? Animation : NoAnimation);
-    onItemSizeChanged(size, previousSize);
-}
-
-QSizeF KItemListView::itemSize() const
-{
-    return m_itemSize;
+    delete m_sizeHintResolver;
+    m_sizeHintResolver = 0;
 }
 
 void KItemListView::setScrollOffset(qreal offset)
@@ -354,62 +279,39 @@ KItemModelBase* KItemListView::model() const
 
 void KItemListView::setWidgetCreator(KItemListWidgetCreatorBase* widgetCreator)
 {
+    if (m_widgetCreator) {
+        delete m_widgetCreator;
+    }
     m_widgetCreator = widgetCreator;
 }
 
 KItemListWidgetCreatorBase* KItemListView::widgetCreator() const
 {
+    if (!m_widgetCreator) {
+        m_widgetCreator = defaultWidgetCreator();
+    }
     return m_widgetCreator;
 }
 
 void KItemListView::setGroupHeaderCreator(KItemListGroupHeaderCreatorBase* groupHeaderCreator)
 {
+    if (m_groupHeaderCreator) {
+        delete m_groupHeaderCreator;
+    }
     m_groupHeaderCreator = groupHeaderCreator;
 }
 
 KItemListGroupHeaderCreatorBase* KItemListView::groupHeaderCreator() const
 {
+    if (!m_groupHeaderCreator) {
+        m_groupHeaderCreator = defaultGroupHeaderCreator();
+    }
     return m_groupHeaderCreator;
 }
 
-void KItemListView::setStyleOption(const KItemListStyleOption& option)
+QSizeF KItemListView::itemSize() const
 {
-    const KItemListStyleOption previousOption = m_styleOption;
-    m_styleOption = option;
-
-    bool animate = true;
-    const QSizeF margin(option.horizontalMargin, option.verticalMargin);
-    if (margin != m_layouter->itemMargin()) {
-        // Skip animations when the number of rows or columns
-        // are changed in the grid layout. Although the animation
-        // engine can handle this usecase, it looks obtrusive.
-        animate = !changesItemGridLayout(m_layouter->size(),
-                                         m_layouter->itemSize(),
-                                         margin);
-        m_layouter->setItemMargin(margin);
-    }
-
-    if (m_grouped) {
-        updateGroupHeaderHeight();
-    }
-
-    if (animate && previousOption.maxTextSize != option.maxTextSize) {
-        // Animating a change of the maximum text size just results in expensive
-        // temporary eliding and clipping operations and does not look good visually.
-        animate = false;
-    }
-
-    QHashIterator<int, KItemListWidget*> it(m_visibleItems);
-    while (it.hasNext()) {
-        it.next();
-        it.value()->setStyleOption(option);
-    }
-
-    m_sizeHintResolver->clearCache();
-    m_layouter->markAsDirty();
-    doLayout(animate ? Animation : NoAnimation);
-
-    onStyleOptionChanged(option, previousOption);
+    return m_itemSize;
 }
 
 const KItemListStyleOption& KItemListView::styleOption() const
@@ -519,7 +421,7 @@ int KItemListView::lastVisibleIndex() const
 
 QSizeF KItemListView::itemSizeHint(int index) const
 {
-    return m_widgetCreator->itemSizeHint(index, this);
+    return widgetCreator()->itemSizeHint(index, this);
 }
 
 void KItemListView::setSupportsItemExpanding(bool supportsExpanding)
@@ -709,6 +611,134 @@ void KItemListView::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt
     }
 }
 
+void KItemListView::setItemSize(const QSizeF& size)
+{
+    const QSizeF previousSize = m_itemSize;
+    if (size == previousSize) {
+        return;
+    }
+
+    // Skip animations when the number of rows or columns
+    // are changed in the grid layout. Although the animation
+    // engine can handle this usecase, it looks obtrusive.
+    const bool animate = !changesItemGridLayout(m_layouter->size(),
+                                                size,
+                                                m_layouter->itemMargin());
+
+    const bool alternateBackgroundsChanged = (m_visibleRoles.count() > 1) &&
+                                             (( m_itemSize.isEmpty() && !size.isEmpty()) ||
+                                              (!m_itemSize.isEmpty() && size.isEmpty()));
+
+    m_itemSize = size;
+
+    if (alternateBackgroundsChanged) {
+        // For an empty item size alternate backgrounds are drawn if more than
+        // one role is shown. Assure that the backgrounds for visible items are
+        // updated when changing the size in this context.
+        updateAlternateBackgrounds();
+    }
+
+    if (size.isEmpty()) {
+        if (m_headerWidget->automaticColumnResizing()) {
+            updatePreferredColumnWidths();
+        } else {
+            // Only apply the changed height and respect the header widths
+            // set by the user
+            const qreal currentWidth = m_layouter->itemSize().width();
+            const QSizeF newSize(currentWidth, size.height());
+            m_layouter->setItemSize(newSize);
+        }
+    } else {
+        m_layouter->setItemSize(size);
+    }
+
+    m_sizeHintResolver->clearCache();
+    doLayout(animate ? Animation : NoAnimation);
+    onItemSizeChanged(size, previousSize);
+}
+
+void KItemListView::setStyleOption(const KItemListStyleOption& option)
+{
+    const KItemListStyleOption previousOption = m_styleOption;
+    m_styleOption = option;
+
+    bool animate = true;
+    const QSizeF margin(option.horizontalMargin, option.verticalMargin);
+    if (margin != m_layouter->itemMargin()) {
+        // Skip animations when the number of rows or columns
+        // are changed in the grid layout. Although the animation
+        // engine can handle this usecase, it looks obtrusive.
+        animate = !changesItemGridLayout(m_layouter->size(),
+                                         m_layouter->itemSize(),
+                                         margin);
+        m_layouter->setItemMargin(margin);
+    }
+
+    if (m_grouped) {
+        updateGroupHeaderHeight();
+    }
+
+    if (animate && previousOption.maxTextSize != option.maxTextSize) {
+        // Animating a change of the maximum text size just results in expensive
+        // temporary eliding and clipping operations and does not look good visually.
+        animate = false;
+    }
+
+    QHashIterator<int, KItemListWidget*> it(m_visibleItems);
+    while (it.hasNext()) {
+        it.next();
+        it.value()->setStyleOption(option);
+    }
+
+    m_sizeHintResolver->clearCache();
+    m_layouter->markAsDirty();
+    doLayout(animate ? Animation : NoAnimation);
+
+    onStyleOptionChanged(option, previousOption);
+}
+
+void KItemListView::setScrollOrientation(Qt::Orientation orientation)
+{
+    const Qt::Orientation previousOrientation = m_layouter->scrollOrientation();
+    if (orientation == previousOrientation) {
+        return;
+    }
+
+    m_layouter->setScrollOrientation(orientation);
+    m_animation->setScrollOrientation(orientation);
+    m_sizeHintResolver->clearCache();
+
+    if (m_grouped) {
+        QMutableHashIterator<KItemListWidget*, KItemListGroupHeader*> it (m_visibleGroups);
+        while (it.hasNext()) {
+            it.next();
+            it.value()->setScrollOrientation(orientation);
+        }
+        updateGroupHeaderHeight();
+
+    }
+
+    doLayout(NoAnimation);
+
+    onScrollOrientationChanged(orientation, previousOrientation);
+    emit scrollOrientationChanged(orientation, previousOrientation);
+}
+
+Qt::Orientation KItemListView::scrollOrientation() const
+{
+    return m_layouter->scrollOrientation();
+}
+
+KItemListWidgetCreatorBase* KItemListView::defaultWidgetCreator() const
+{
+    return 0;
+}
+
+KItemListGroupHeaderCreatorBase* KItemListView::defaultGroupHeaderCreator() const
+{
+    return 0;
+}
+
 void KItemListView::initializeItemListWidget(KItemListWidget* item)
 {
     Q_UNUSED(item);
@@ -728,8 +758,13 @@ void KItemListView::onControllerChanged(KItemListController* current, KItemListC
 
 void KItemListView::onModelChanged(KItemModelBase* current, KItemModelBase* previous)
 {
-    Q_UNUSED(current);
     Q_UNUSED(previous);
+
+    m_sizeHintResolver->clearCache();
+    const int itemCount = current->count();
+    if (itemCount > 0) {
+        m_sizeHintResolver->itemsInserted(0, itemCount);
+    }
 }
 
 void KItemListView::onScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous)
@@ -1205,7 +1240,7 @@ void KItemListView::slotAnimationFinished(QGraphicsWidget* widget,
         // by m_visibleWidgets and must be deleted manually after the animation has
         // been finished.
         recycleGroupHeaderForWidget(itemListWidget);
-        m_widgetCreator->recycle(itemListWidget);
+        widgetCreator()->recycle(itemListWidget);
         break;
     }
 
@@ -1713,7 +1748,7 @@ void KItemListView::emitOffsetChanges()
 
 KItemListWidget* KItemListView::createWidget(int index)
 {
-    KItemListWidget* widget = m_widgetCreator->create(this);
+    KItemListWidget* widget = widgetCreator()->create(this);
     widget->setFlag(QGraphicsItem::ItemStacksBehindParent);
 
     m_visibleItems.insert(index, widget);
@@ -1733,7 +1768,7 @@ void KItemListView::recycleWidget(KItemListWidget* widget)
     m_visibleItems.remove(index);
     m_visibleCells.remove(index);
 
-    m_widgetCreator->recycle(widget);
+    widgetCreator()->recycle(widget);
 }
 
 void KItemListView::setWidgetIndex(KItemListWidget* widget, int index)
@@ -1813,7 +1848,7 @@ void KItemListView::updateGroupHeaderForWidget(KItemListWidget* widget)
 
     KItemListGroupHeader* groupHeader = m_visibleGroups.value(widget);
     if (!groupHeader) {
-        groupHeader = m_groupHeaderCreator->create(this);
+        groupHeader = groupHeaderCreator()->create(this);
         groupHeader->setParentItem(widget);
         m_visibleGroups.insert(widget, groupHeader);
         connect(widget, SIGNAL(geometryChanged()), this, SLOT(slotGeometryOfGroupHeaderParentChanged()));
@@ -1859,7 +1894,7 @@ void KItemListView::recycleGroupHeaderForWidget(KItemListWidget* widget)
     KItemListGroupHeader* header = m_visibleGroups.value(widget);
     if (header) {
         header->setParentItem(0);
-        m_groupHeaderCreator->recycle(header);
+        groupHeaderCreator()->recycle(header);
         m_visibleGroups.remove(widget);
         disconnect(widget, SIGNAL(geometryChanged()), this, SLOT(slotGeometryOfGroupHeaderParentChanged()));
     }
@@ -1960,6 +1995,7 @@ QHash<QByteArray, qreal> KItemListView::preferredColumnWidths(const KItemRangeLi
 
     // Calculate the preferred column withs for each item and ignore values
     // smaller than the width for showing the headline unclipped.
+    const KItemListWidgetCreatorBase* creator = widgetCreator();
     int calculatedItemCount = 0;
     bool maxTimeExceeded = false;
     foreach (const KItemRange& itemRange, itemRanges) {
@@ -1969,7 +2005,7 @@ QHash<QByteArray, qreal> KItemListView::preferredColumnWidths(const KItemRangeLi
         for (int i = startIndex; i <= endIndex; ++i) {
             foreach (const QByteArray& visibleRole, visibleRoles()) {
                 qreal maxWidth = widths.value(visibleRole, 0);
-                const qreal width = m_widgetCreator->preferredRoleColumnWidth(visibleRole, i, this);
+                const qreal width = creator->preferredRoleColumnWidth(visibleRole, i, this);
                 maxWidth = qMax(width, maxWidth);
                 widths.insert(visibleRole, maxWidth);
             }
@@ -2071,6 +2107,9 @@ void KItemListView::applyAutomaticColumnWidths()
 {
     Q_ASSERT(m_itemSize.isEmpty());
     Q_ASSERT(m_headerWidget->automaticColumnResizing());
+    if (m_visibleRoles.isEmpty()) {
+        return;
+    }
 
     // Calculate the maximum size of an item by considering the
     // visible role sizes and apply them to the layouter. If the
index 13f62f89b2d5f48edf2c2993c0c9157838c55c03..3c47e95c66c1e9b78736b3d3ab00315e9891542f 100644 (file)
@@ -42,6 +42,7 @@ class KItemListRubberBand;
 class KItemListViewAnimation;
 class KItemListViewLayouter;
 class KItemListWidget;
+class KItemListWidgetInformant;
 class KItemListWidgetCreatorBase;
 class KItemListViewCreatorBase;
 class QTimer;
@@ -53,11 +54,8 @@ class QTimer;
  * a GraphicsItem. Each visible item is represented by a KItemListWidget.
  *
  * The created view must be applied to the KItemListController with
- * KItemListController::setView(). For showing a custom model it is not
- * mandatory to derive from KItemListView, all that is necessary is
- * to set a widget-creator that is capable to create KItemListWidgets
- * showing the model items. A widget-creator can be set with
- * KItemListView::setWidgetCreator().
+ * KItemListController::setView() or with the constructor of
+ * KItemListController.
  *
  * @see KItemListWidget
  * @see KItemModelBase
@@ -73,17 +71,6 @@ public:
     KItemListView(QGraphicsWidget* parent = 0);
     virtual ~KItemListView();
 
-    /**
-     * If the scroll-orientation is vertical, the items are ordered
-     * from top to bottom (= default setting). If the scroll-orientation
-     * is horizontal, the items are ordered from left to right.
-     */
-    void setScrollOrientation(Qt::Orientation orientation);
-    Qt::Orientation scrollOrientation() const;
-
-    void setItemSize(const QSizeF& size);
-    QSizeF itemSize() const;
-
     /**
      * Offset of the scrollbar that represents the scroll-orientation
      * (see setScrollOrientation()).
@@ -145,17 +132,27 @@ public:
      * <code>
      * itemListView->setWidgetCreator(new KItemListWidgetCreator<X>());
      * </code>
-     * Note that the ownership of the widget creator is not transferred to
-     * the item-list view: One instance of a widget creator might get shared
-     * by several item-list view instances.
+     * The ownership of the widget creator is transferred to
+     * the item-list view.
      **/
     void setWidgetCreator(KItemListWidgetCreatorBase* widgetCreator);
     KItemListWidgetCreatorBase* widgetCreator() const;
 
+    /**
+     * Sets the creator that creates a group header. Usually it is sufficient
+     * to implement a custom header widget X derived from KItemListGroupHeader and
+     * set the creator by:
+     * <code>
+     * itemListView->setGroupHeaderCreator(new KItemListGroupHeaderCreator<X>());
+     * </code>
+     * The ownership of the gropup header creator is transferred to
+     * the item-list view.
+     **/
     void setGroupHeaderCreator(KItemListGroupHeaderCreatorBase* groupHeaderCreator);
     KItemListGroupHeaderCreatorBase* groupHeaderCreator() const;
 
-    void setStyleOption(const KItemListStyleOption& option);
+    QSizeF itemSize() const;
+
     const KItemListStyleOption& styleOption() const;
 
     /** @reimp */
@@ -313,6 +310,33 @@ signals:
     void roleEditingFinished(int index, const QByteArray& role, const QVariant& value);
 
 protected:
+    void setItemSize(const QSizeF& size);
+    void setStyleOption(const KItemListStyleOption& option);
+
+    /**
+     * If the scroll-orientation is vertical, the items are ordered
+     * from top to bottom (= default setting). If the scroll-orientation
+     * is horizontal, the items are ordered from left to right.
+     */
+    void setScrollOrientation(Qt::Orientation orientation);
+    Qt::Orientation scrollOrientation() const;
+
+    /**
+     * Factory method for creating a default widget-creator. The method will be used
+     * in case if setWidgetCreator() has not been set by the application.
+     * @return New instance of the widget-creator that should be used per
+     *         default.
+     */
+    virtual KItemListWidgetCreatorBase* defaultWidgetCreator() const;
+
+    /**
+     * Factory method for creating a default group-header-creator. The method will be used
+     * in case if setGroupHeaderCreator() has not been set by the application.
+     * @return New instance of the group-header-creator that should be used per
+     *         default.
+     */
+    virtual KItemListGroupHeaderCreatorBase* defaultGroupHeaderCreator() const;
+
     /**
      * Is called when creating a new KItemListWidget instance and allows derived
      * classes to do a custom initialization.
@@ -656,8 +680,8 @@ private:
     KItemListController* m_controller;
     KItemModelBase* m_model;
     QList<QByteArray> m_visibleRoles;
-    KItemListWidgetCreatorBase* m_widgetCreator;
-    KItemListGroupHeaderCreatorBase* m_groupHeaderCreator;
+    mutable KItemListWidgetCreatorBase* m_widgetCreator;
+    mutable KItemListGroupHeaderCreatorBase* m_groupHeaderCreator;
     KItemListStyleOption m_styleOption;
 
     QHash<int, KItemListWidget*> m_visibleItems;
@@ -747,18 +771,12 @@ public:
 
 /**
  * @brief Template class for creating KItemListWidgets.
- *
- * The template class must provide the following two static methods:
- * - QSizeF itemSizeHint(int index, const KItemListView* view)
- * - preferredRoleColumnWidth(const QByteArray& role, int index, const KItemListView* view)
- * Those static methods are used as implementation for
- * KItemListWidgetCreatorBase::itemSizeHint() and
- * KItemListWidgetCreatorBase::preferedRoleColumnWidth().
  */
 template <class T>
 class KItemListWidgetCreator : public KItemListWidgetCreatorBase
 {
 public:
+    KItemListWidgetCreator();
     virtual ~KItemListWidgetCreator();
 
     virtual KItemListWidget* create(KItemListView* view);
@@ -768,11 +786,20 @@ public:
     virtual qreal preferredRoleColumnWidth(const QByteArray& role,
                                            int index,
                                            const KItemListView* view) const;
+private:
+    KItemListWidgetInformant* m_informant;
 };
 
+template <class T>
+KItemListWidgetCreator<T>::KItemListWidgetCreator() :
+    m_informant(T::createInformant())
+{
+}
+
 template <class T>
 KItemListWidgetCreator<T>::~KItemListWidgetCreator()
 {
+    delete m_informant;
 }
 
 template <class T>
@@ -780,7 +807,7 @@ KItemListWidget* KItemListWidgetCreator<T>::create(KItemListView* view)
 {
     KItemListWidget* widget = static_cast<KItemListWidget*>(popRecycleableWidget());
     if (!widget) {
-        widget = new T(view);
+        widget = new T(m_informant, view);
         addCreatedWidget(widget);
     }
     return widget;
@@ -789,7 +816,7 @@ KItemListWidget* KItemListWidgetCreator<T>::create(KItemListView* view)
 template<class T>
 QSizeF KItemListWidgetCreator<T>::itemSizeHint(int index, const KItemListView* view) const
 {
-    return T::itemSizeHint(index, view);
+    return m_informant->itemSizeHint(index, view);
 }
 
 template<class T>
@@ -797,7 +824,7 @@ qreal KItemListWidgetCreator<T>::preferredRoleColumnWidth(const QByteArray& role
                                                           int index,
                                                           const KItemListView* view) const
 {
-    return T::preferredRoleColumnWidth(role, index, view);
+    return m_informant->preferredRoleColumnWidth(role, index, view);
 }
 
 /**
index 542b781f1bce82d32595a6912890d8add84faa73..f304aa41ddfbb6e994f4a997515a452ce9f3d09a 100644 (file)
 #include <QPropertyAnimation>
 #include <QStyleOption>
 
-KItemListWidget::KItemListWidget(QGraphicsItem* parent) :
+KItemListWidgetInformant::KItemListWidgetInformant()
+{
+}
+
+KItemListWidgetInformant::~KItemListWidgetInformant()
+{
+}
+
+KItemListWidget::KItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) :
     QGraphicsWidget(parent, 0),
+    m_informant(informant),
     m_index(-1),
     m_selected(false),
     m_current(false),
index 8a28913b663e6a0345d63a78cafa1add07ee2b78..fdb07d62e6ddb2d90a6f7bbf950954e8612f42ac 100644 (file)
 #include <QStyle>
 
 class KItemListSelectionToggle;
+class KItemListView;
 class QPropertyAnimation;
 
+/**
+ * @brief Provides information for creating an instance of KItemListWidget.
+ *
+ * KItemListView only creates KItemListWidget instances for the visible
+ * area. For calculating the required size of all items the expected
+ * size for the invisible items must be accessible. KItemListWidgetInformant
+ * provides this information.
+ */
+class LIBDOLPHINPRIVATE_EXPORT KItemListWidgetInformant
+{
+public:
+    KItemListWidgetInformant();
+    virtual ~KItemListWidgetInformant();
+
+    virtual QSizeF itemSizeHint(int index, const KItemListView* view) const = 0;
+
+    virtual qreal preferredRoleColumnWidth(const QByteArray& role,
+                                           int index,
+                                           const KItemListView* view) const = 0;
+};
+
 /**
  * @brief Widget that shows a visible item from the model.
  *
@@ -46,7 +68,7 @@ class LIBDOLPHINPRIVATE_EXPORT KItemListWidget : public QGraphicsWidget
     Q_OBJECT
 
 public:
-    KItemListWidget(QGraphicsItem* parent);
+    KItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent);
     virtual ~KItemListWidget();
 
     void setIndex(int index);
@@ -176,6 +198,8 @@ protected:
      */
     qreal hoverOpacity() const;
 
+    const KItemListWidgetInformant* informant() const;
+
 private slots:
     void slotHoverAnimationFinished();
 
@@ -188,6 +212,7 @@ private:
 private:
     Q_PROPERTY(qreal hoverOpacity READ hoverOpacity WRITE setHoverOpacity)
 
+    KItemListWidgetInformant* m_informant;
     int m_index;
     bool m_selected;
     bool m_current;
@@ -208,6 +233,12 @@ private:
 
     QByteArray m_editedRole;
 };
+
+inline const KItemListWidgetInformant* KItemListWidget::informant() const
+{
+    return m_informant;
+}
+
 #endif
 
 
diff --git a/src/kitemviews/kstandarditem.cpp b/src/kitemviews/kstandarditem.cpp
new file mode 100644 (file)
index 0000000..090746d
--- /dev/null
@@ -0,0 +1,100 @@
+/***************************************************************************
+ *   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 "kstandarditem.h"
+
+KStandardItem::KStandardItem(KStandardItem* parent) :
+    m_text(),
+    m_icon(),
+    m_group(),
+    m_parent(parent),
+    m_children(),
+    m_model(0)
+{
+}
+
+KStandardItem::KStandardItem(const QString& text, KStandardItem* parent) :
+    m_text(text),
+    m_icon(),
+    m_group(),
+    m_parent(parent),
+    m_children(),
+    m_model(0)
+{
+}
+
+KStandardItem::KStandardItem(const QIcon& icon, const QString& text, KStandardItem* parent) :
+    m_text(text),
+    m_icon(icon),
+    m_group(),
+    m_parent(parent),
+    m_children(),
+    m_model(0)
+{
+}
+
+KStandardItem::~KStandardItem()
+{
+}
+
+void KStandardItem::setText(const QString& text)
+{
+    m_text = text;
+}
+
+QString KStandardItem::text() const
+{
+    return m_text;
+}
+
+void KStandardItem::setIcon(const QIcon& icon)
+{
+    m_icon = icon;
+}
+
+QIcon KStandardItem::icon() const
+{
+    return m_icon;
+}
+
+void KStandardItem::setGroup(const QString& group)
+{
+    m_group = group;
+}
+
+QString KStandardItem::group() const
+{
+    return m_group;
+}
+
+void KStandardItem::setParent(KStandardItem* parent)
+{
+    // TODO: not implemented yet
+    m_parent = parent;
+}
+
+KStandardItem* KStandardItem::parent() const
+{
+    return m_parent;
+}
+
+QList<KStandardItem*> KStandardItem::children() const
+{
+    return m_children;
+}
diff --git a/src/kitemviews/kstandarditem.h b/src/kitemviews/kstandarditem.h
new file mode 100644 (file)
index 0000000..0315f4b
--- /dev/null
@@ -0,0 +1,72 @@
+/***************************************************************************
+ *   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 KSTANDARDITEM_H
+#define KSTANDARDITEM_H
+
+#include <libdolphin_export.h>
+
+#include <QIcon>
+#include <QList>
+
+class KStandardItemModel;
+
+/**
+ * @brief Represents and item of KStandardItemModel.
+ *
+ * Provides setter- and getter-methods for most commonly
+ * used properties.
+ */
+class LIBDOLPHINPRIVATE_EXPORT KStandardItem
+{
+
+public:
+    explicit KStandardItem(KStandardItem* parent = 0);
+    explicit KStandardItem(const QString& text, KStandardItem* parent = 0);
+    KStandardItem(const QIcon& icon, const QString& text, KStandardItem* parent = 0);
+    virtual ~KStandardItem();
+
+    void setText(const QString& text);
+    QString text() const;
+
+    void setIcon(const QIcon& icon);
+    QIcon icon() const;
+
+    void setGroup(const QString& group);
+    QString group() const;
+
+    void setParent(KStandardItem* parent);
+    KStandardItem* parent() const;
+
+    QList<KStandardItem*> children() const;
+
+private:
+    QString m_text;
+    QIcon m_icon;
+    QString m_group;
+    KStandardItem* m_parent;
+    QList<KStandardItem*> m_children;
+    KStandardItemModel* m_model;
+
+    friend class KStandardItemModel;
+};
+
+#endif
+
+
diff --git a/src/kitemviews/kstandarditemlistview.cpp b/src/kitemviews/kstandarditemlistview.cpp
new file mode 100644 (file)
index 0000000..bd5da9e
--- /dev/null
@@ -0,0 +1,191 @@
+/***************************************************************************
+ *   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 "kstandarditemlistview.h"
+
+#include <KDebug>
+#include <KIconLoader>
+#include "kstandarditemlistwidget.h"
+
+KStandardItemListView::KStandardItemListView(QGraphicsWidget* parent) :
+    KItemListView(parent),
+    m_itemLayout(DetailsLayout)
+{
+    setAcceptDrops(true);
+    setScrollOrientation(Qt::Vertical);
+    setVisibleRoles(QList<QByteArray>() << "text");
+}
+
+KStandardItemListView::~KStandardItemListView()
+{
+}
+
+void KStandardItemListView::setItemLayout(ItemLayout layout)
+{
+    if (m_itemLayout == layout) {
+        return;
+    }
+
+    beginTransaction();
+
+    const ItemLayout previous = m_itemLayout;
+    m_itemLayout = layout;
+
+    switch (layout) {
+    case IconsLayout:
+        setScrollOrientation(Qt::Vertical);
+        setSupportsItemExpanding(false);
+        break;
+    case DetailsLayout:
+        setScrollOrientation(Qt::Vertical);
+        setSupportsItemExpanding(true);
+        break;
+    case CompactLayout:
+        setScrollOrientation(Qt::Horizontal);
+        setSupportsItemExpanding(false);
+        break;
+    default:
+        Q_ASSERT(false);
+        break;
+    }
+
+    onItemLayoutChanged(layout, previous);
+
+    endTransaction();
+}
+
+KStandardItemListView::ItemLayout KStandardItemListView::itemLayout() const
+{
+    return m_itemLayout;
+}
+
+KItemListWidgetCreatorBase* KStandardItemListView::defaultWidgetCreator() const
+{
+    return new KItemListWidgetCreator<KStandardItemListWidget>();
+}
+
+KItemListGroupHeaderCreatorBase* KStandardItemListView::defaultGroupHeaderCreator() const
+{
+    return 0; // TODO: new KItemListGroupHeaderCreator<KStandardItemListGroupHeader>()
+}
+
+void KStandardItemListView::initializeItemListWidget(KItemListWidget* item)
+{
+    KStandardItemListWidget* standardItemListWidget = qobject_cast<KStandardItemListWidget*>(item);
+    Q_ASSERT(standardItemListWidget);
+
+    switch (itemLayout()) {
+    case IconsLayout:   standardItemListWidget->setLayout(KStandardItemListWidget::IconsLayout); break;
+    case CompactLayout: standardItemListWidget->setLayout(KStandardItemListWidget::CompactLayout); break;
+    case DetailsLayout: standardItemListWidget->setLayout(KStandardItemListWidget::DetailsLayout); break;
+    default:            Q_ASSERT(false); break;
+    }
+
+    standardItemListWidget->setSupportsItemExpanding(supportsItemExpanding());
+}
+
+
+bool KStandardItemListView::itemSizeHintUpdateRequired(const QSet<QByteArray>& changedRoles) const
+{
+    // Even if the icons have a different size they are always aligned within
+    // the area defined by KItemStyleOption.iconSize and hence result in no
+    // change of the item-size.
+    const bool containsIconName = changedRoles.contains("iconName");
+    const bool containsIconPixmap = changedRoles.contains("iconPixmap");
+    const int count = changedRoles.count();
+
+    const bool iconChanged = (containsIconName && containsIconPixmap && count == 2) ||
+                             (containsIconName && count == 1) ||
+                             (containsIconPixmap && count == 1);
+    return !iconChanged;
+}
+
+void KStandardItemListView::onItemLayoutChanged(ItemLayout current, ItemLayout previous)
+{
+    Q_UNUSED(current);
+    Q_UNUSED(previous);
+    updateLayoutOfVisibleItems();
+}
+
+void KStandardItemListView::onScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous)
+{
+    Q_UNUSED(current);
+    Q_UNUSED(previous);
+    updateLayoutOfVisibleItems();
+}
+
+void KStandardItemListView::onSupportsItemExpandingChanged(bool supportsExpanding)
+{
+    Q_UNUSED(supportsExpanding);
+    updateLayoutOfVisibleItems();
+}
+
+
+void KStandardItemListView::polishEvent()
+{
+    switch (m_itemLayout) {
+    case IconsLayout:   applyDefaultStyleOption(KIconLoader::SizeMedium, 2, 4, 8); break;
+    case CompactLayout: applyDefaultStyleOption(KIconLoader::SizeSmall,  2, 8, 0); break;
+    case DetailsLayout: applyDefaultStyleOption(KIconLoader::SizeSmall,  2, 0, 0); break;
+    default:            Q_ASSERT(false); break;
+    }
+
+    QGraphicsWidget::polishEvent();
+}
+
+void KStandardItemListView::applyDefaultStyleOption(int iconSize,
+                                                    int padding,
+                                                    int horizontalMargin,
+                                                    int verticalMargin)
+{
+    KItemListStyleOption option = styleOption();
+
+    bool changed = false;
+    if (option.iconSize < 0) {
+        option.iconSize = iconSize;
+        changed = true;
+    }
+    if (option.padding < 0) {
+        option.padding = padding;
+        changed = true;
+    }
+    if (option.horizontalMargin < 0) {
+        option.horizontalMargin = horizontalMargin;
+        changed = true;
+    }
+    if (option.verticalMargin < 0) {
+        option.verticalMargin = verticalMargin;
+        changed = true;
+    }
+
+    if (changed) {
+        setStyleOption(option);
+    }
+}
+
+void KStandardItemListView::updateLayoutOfVisibleItems()
+{
+    if (model()) {
+        foreach (KItemListWidget* widget, visibleItemListWidgets()) {
+            initializeItemListWidget(widget);
+        }
+    }
+}
+
+#include "kstandarditemlistview.moc"
diff --git a/src/kitemviews/kstandarditemlistview.h b/src/kitemviews/kstandarditemlistview.h
new file mode 100644 (file)
index 0000000..fd4fa86
--- /dev/null
@@ -0,0 +1,81 @@
+/***************************************************************************
+ *   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 KSTANDARDITEMLISTVIEW_H
+#define KSTANDARDITEMLISTVIEW_H
+
+#include <libdolphin_export.h>
+
+#include <kitemviews/kitemlistview.h>
+
+/**
+ * @brief Provides layouts for icons-, compact- and details-view.
+ *
+ * Together with the KStandardItemModel lists for standard usecases
+ * can be created in a straight forward way.
+ *
+ * Example code:
+ * <code>
+ * KStandardItemListView* view = new KStandardItemListView();
+ * KStandardItemModel* model = new KStandardItemModel();
+ * model->appendItem(new KStandardItem("Item 1"));
+ * model->appendItem(new KStandardItem("Item 2"));
+ * KItemListController* controller = new KItemListController(model, view);
+ * KItemListContainer* container = new KItemListContainer(controller, parentWidget);
+ * </code>
+ */
+class LIBDOLPHINPRIVATE_EXPORT KStandardItemListView : public KItemListView
+{
+    Q_OBJECT
+
+public:
+    enum ItemLayout
+    {
+        IconsLayout,
+        CompactLayout,
+        DetailsLayout
+    };
+
+    KStandardItemListView(QGraphicsWidget* parent = 0);
+    virtual ~KStandardItemListView();
+
+    void setItemLayout(ItemLayout layout);
+    ItemLayout itemLayout() const;
+
+protected:
+    virtual KItemListWidgetCreatorBase* defaultWidgetCreator() const;
+    virtual KItemListGroupHeaderCreatorBase* defaultGroupHeaderCreator() const;
+    virtual void initializeItemListWidget(KItemListWidget* item);
+    virtual bool itemSizeHintUpdateRequired(const QSet<QByteArray>& changedRoles) const;
+    virtual void onItemLayoutChanged(ItemLayout current, ItemLayout previous);
+    virtual void onScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous);
+    virtual void onSupportsItemExpandingChanged(bool supportsExpanding);
+    virtual void polishEvent();
+
+private:
+    void applyDefaultStyleOption(int iconSize, int padding, int horizontalMargin, int verticalMargin);
+    void updateLayoutOfVisibleItems();
+
+private:
+    ItemLayout m_itemLayout;
+};
+
+#endif
+
+
diff --git a/src/kitemviews/kstandarditemlistwidget.cpp b/src/kitemviews/kstandarditemlistwidget.cpp
new file mode 100644 (file)
index 0000000..c9d9b42
--- /dev/null
@@ -0,0 +1,1234 @@
+/***************************************************************************
+ *   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 "kstandarditemlistwidget.h"
+
+#include "kfileitemlistview.h"
+#include "kfileitemmodel.h"
+
+#include <KIcon>
+#include <KIconEffect>
+#include <KIconLoader>
+#include <KLocale>
+#include <kratingpainter.h>
+#include <KStringHandler>
+#include <KDebug>
+
+#include "private/kfileitemclipboard.h"
+#include "private/kitemlistroleeditor.h"
+#include "private/kpixmapmodifier.h"
+
+#include <QFontMetricsF>
+#include <QGraphicsScene>
+#include <QGraphicsSceneResizeEvent>
+#include <QGraphicsView>
+#include <QPainter>
+#include <QStyleOption>
+#include <QTextLayout>
+#include <QTextLine>
+
+// #define KFILEITEMLISTWIDGET_DEBUG
+
+KStandardItemListWidgetInformant::KStandardItemListWidgetInformant() :
+    KItemListWidgetInformant()
+{
+}
+
+KStandardItemListWidgetInformant::~KStandardItemListWidgetInformant()
+{
+}
+
+QSizeF KStandardItemListWidgetInformant::itemSizeHint(int index, const KItemListView* view) const
+{
+    const QHash<QByteArray, QVariant> values = view->model()->data(index);
+    const KItemListStyleOption& option = view->styleOption();
+    const int additionalRolesCount = qMax(view->visibleRoles().count() - 1, 0);
+
+    switch (static_cast<const KStandardItemListView*>(view)->itemLayout()) {
+    case KStandardItemListWidget::IconsLayout: {
+        const QString text = KStringHandler::preProcessWrap(values["text"].toString());
+
+        const qreal itemWidth = view->itemSize().width();
+        const qreal maxWidth = itemWidth - 2 * option.padding;
+        QTextLine line;
+
+        // Calculate the number of lines required for wrapping the name
+        QTextOption textOption(Qt::AlignHCenter);
+        textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
+
+        qreal textHeight = 0;
+        QTextLayout layout(text, option.font);
+        layout.setTextOption(textOption);
+        layout.beginLayout();
+        while ((line = layout.createLine()).isValid()) {
+            line.setLineWidth(maxWidth);
+            line.naturalTextWidth();
+            textHeight += line.height();
+        }
+        layout.endLayout();
+
+        // Add one line for each additional information
+        textHeight += additionalRolesCount * option.fontMetrics.lineSpacing();
+
+        const qreal maxTextHeight = option.maxTextSize.height();
+        if (maxTextHeight > 0 && textHeight > maxTextHeight) {
+            textHeight = maxTextHeight;
+        }
+
+        return QSizeF(itemWidth, textHeight + option.iconSize + option.padding * 3);
+    }
+
+    case KStandardItemListWidget::CompactLayout: {
+        // For each row exactly one role is shown. Calculate the maximum required width that is necessary
+        // to show all roles without horizontal clipping.
+        qreal maximumRequiredWidth = 0.0;
+
+        foreach (const QByteArray& role, view->visibleRoles()) {
+            const QString text = roleText(role, values);
+            const qreal requiredWidth = option.fontMetrics.width(text);
+            maximumRequiredWidth = qMax(maximumRequiredWidth, requiredWidth);
+        }
+
+        qreal width = option.padding * 4 + option.iconSize + maximumRequiredWidth;
+        const qreal maxWidth = option.maxTextSize.width();
+        if (maxWidth > 0 && width > maxWidth) {
+            width = maxWidth;
+        }
+        const qreal height = option.padding * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * option.fontMetrics.lineSpacing());
+        return QSizeF(width, height);
+    }
+
+    case KStandardItemListWidget::DetailsLayout: {
+        const qreal height = option.padding * 2 + qMax(option.iconSize, option.fontMetrics.height());
+        return QSizeF(-1, height);
+    }
+
+    default:
+        Q_ASSERT(false);
+        break;
+    }
+
+    return QSize();
+}
+
+qreal KStandardItemListWidgetInformant::preferredRoleColumnWidth(const QByteArray& role,
+                                                                 int index,
+                                                                 const KItemListView* view) const
+{
+    const QHash<QByteArray, QVariant> values = view->model()->data(index);
+    const KItemListStyleOption& option = view->styleOption();
+
+    const QString text = roleText(role, values);
+    qreal width = KStandardItemListWidget::columnPadding(option);
+
+    if (role == "rating") {
+        width += KStandardItemListWidget::preferredRatingSize(option).width();
+    } else {
+        width += option.fontMetrics.width(text);
+
+        if (role == "text") {
+            // Increase the width by the expansion-toggle and the current expansion level
+            const int expandedParentsCount = values.value("expandedParentsCount", 0).toInt();
+            width += option.padding + (expandedParentsCount + 1) * view->itemSize().height() + KIconLoader::SizeSmall;
+
+            // Increase the width by the required space for the icon
+            width += option.padding * 2 + option.iconSize;
+        }
+    }
+
+    return width;
+}
+
+QString KStandardItemListWidgetInformant::roleText(const QByteArray& role,
+                                                   const QHash<QByteArray, QVariant>& values) const
+{
+    if (role == "rating") {
+        // Always use an empty text, as the rating is shown by the image m_rating.
+        return QString();
+    }
+    return values.value(role).toString();
+}
+
+KStandardItemListWidget::KStandardItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) :
+    KItemListWidget(informant, parent),
+    m_isCut(false),
+    m_isHidden(false),
+    m_isExpandable(false),
+    m_supportsItemExpanding(false),
+    m_dirtyLayout(true),
+    m_dirtyContent(true),
+    m_dirtyContentRoles(),
+    m_layout(IconsLayout),
+    m_pixmapPos(),
+    m_pixmap(),
+    m_scaledPixmapSize(),
+    m_iconRect(),
+    m_hoverPixmap(),
+    m_textInfo(),
+    m_textRect(),
+    m_sortedVisibleRoles(),
+    m_expansionArea(),
+    m_customTextColor(),
+    m_additionalInfoTextColor(),
+    m_overlay(),
+    m_rating(),
+    m_roleEditor(0)
+{
+}
+
+KStandardItemListWidget::~KStandardItemListWidget()
+{
+    qDeleteAll(m_textInfo);
+    m_textInfo.clear();
+
+    delete m_roleEditor;
+}
+
+void KStandardItemListWidget::setLayout(Layout layout)
+{
+    if (m_layout != layout) {
+        m_layout = layout;
+        m_dirtyLayout = true;
+        updateAdditionalInfoTextColor();
+        update();
+    }
+}
+
+KStandardItemListWidget::Layout KStandardItemListWidget::layout() const
+{
+    return m_layout;
+}
+
+void KStandardItemListWidget::setSupportsItemExpanding(bool supportsItemExpanding)
+{
+    if (m_supportsItemExpanding != supportsItemExpanding) {
+        m_supportsItemExpanding = supportsItemExpanding;
+        m_dirtyLayout = true;
+        update();
+    }
+}
+
+bool KStandardItemListWidget::supportsItemExpanding() const
+{
+    return m_supportsItemExpanding;
+}
+
+void KStandardItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
+{
+    const_cast<KStandardItemListWidget*>(this)->triggerCacheRefreshing();
+
+    KItemListWidget::paint(painter, option, widget);
+
+    if (!m_expansionArea.isEmpty()) {
+        drawSiblingsInformation(painter);
+    }
+
+    const KItemListStyleOption& itemListStyleOption = styleOption();
+    if (isHovered()) {
+        // Blend the unhovered and hovered pixmap if the hovering
+        // animation is ongoing
+        if (hoverOpacity() < 1.0) {
+            drawPixmap(painter, m_pixmap);
+        }
+
+        const qreal opacity = painter->opacity();
+        painter->setOpacity(hoverOpacity() * opacity);
+        drawPixmap(painter, m_hoverPixmap);
+        painter->setOpacity(opacity);
+    } else {
+        drawPixmap(painter, m_pixmap);
+    }
+
+    painter->setFont(itemListStyleOption.font);
+    painter->setPen(textColor());
+    const TextInfo* textInfo = m_textInfo.value("text");
+    painter->drawStaticText(textInfo->pos, textInfo->staticText);
+
+    bool clipAdditionalInfoBounds = false;
+    if (m_supportsItemExpanding) {
+        // Prevent a possible overlapping of the additional-information texts
+        // 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 (textInfo->pos.x() + columnWidth("text") > minX) {
+            clipAdditionalInfoBounds = true;
+            painter->save();
+            painter->setClipRect(minX, 0, size().width() - minX, size().height(), Qt::IntersectClip);
+        }
+    }
+
+    painter->setPen(m_additionalInfoTextColor);
+    painter->setFont(itemListStyleOption.font);
+
+    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 (!m_rating.isNull()) {
+        const TextInfo* ratingTextInfo = m_textInfo.value("rating");
+        QPointF pos = ratingTextInfo->pos;
+        const Qt::Alignment align = ratingTextInfo->staticText.textOption().alignment();
+        if (align & Qt::AlignHCenter) {
+            pos.rx() += (size().width() - m_rating.width()) / 2;
+        }
+        painter->drawPixmap(pos, m_rating);
+    }
+
+    if (clipAdditionalInfoBounds) {
+        painter->restore();
+    }
+
+#ifdef KFILEITEMLISTWIDGET_DEBUG
+    painter->setBrush(Qt::NoBrush);
+    painter->setPen(Qt::green);
+    painter->drawRect(m_iconRect);
+
+    painter->setPen(Qt::red);
+    painter->drawText(QPointF(0, itemListStyleOption.fontMetrics.height()), QString::number(index()));
+    painter->drawRect(rect());
+#endif
+}
+
+QRectF KStandardItemListWidget::iconRect() const
+{
+    const_cast<KStandardItemListWidget*>(this)->triggerCacheRefreshing();
+    return m_iconRect;
+}
+
+QRectF KStandardItemListWidget::textRect() const
+{
+    const_cast<KStandardItemListWidget*>(this)->triggerCacheRefreshing();
+    return m_textRect;
+}
+
+QRectF KStandardItemListWidget::textFocusRect() const
+{
+    // In the compact- and details-layout a larger textRect() is returned to be aligned
+    // with the iconRect(). This is useful to have a larger selection/hover-area
+    // when having a quite large icon size but only one line of text. Still the
+    // focus rectangle should be shown as narrow as possible around the text.
+
+    const_cast<KStandardItemListWidget*>(this)->triggerCacheRefreshing();
+
+    switch (m_layout) {
+    case CompactLayout: {
+        QRectF rect = m_textRect;
+        const TextInfo* topText    = m_textInfo.value(m_sortedVisibleRoles.first());
+        const TextInfo* bottomText = m_textInfo.value(m_sortedVisibleRoles.last());
+        rect.setTop(topText->pos.y());
+        rect.setBottom(bottomText->pos.y() + bottomText->staticText.size().height());
+        return rect;
+    }
+
+    case DetailsLayout: {
+        QRectF rect = m_textRect;
+        const TextInfo* textInfo    = m_textInfo.value(m_sortedVisibleRoles.first());
+        rect.setTop(textInfo->pos.y());
+        rect.setBottom(textInfo->pos.y() + textInfo->staticText.size().height());
+        return rect;
+    }
+
+    default:
+        break;
+    }
+
+    return m_textRect;
+}
+
+QRectF KStandardItemListWidget::expansionToggleRect() const
+{
+    const_cast<KStandardItemListWidget*>(this)->triggerCacheRefreshing();
+    return m_isExpandable ? m_expansionArea : QRectF();
+}
+
+QRectF KStandardItemListWidget::selectionToggleRect() const
+{
+    const_cast<KStandardItemListWidget*>(this)->triggerCacheRefreshing();
+
+    const int iconHeight = styleOption().iconSize;
+
+    int toggleSize = KIconLoader::SizeSmall;
+    if (iconHeight >= KIconLoader::SizeEnormous) {
+        toggleSize = KIconLoader::SizeMedium;
+    } else if (iconHeight >= KIconLoader::SizeLarge) {
+        toggleSize = KIconLoader::SizeSmallMedium;
+    }
+
+    QPointF pos = iconRect().topLeft();
+
+    // If the selection toggle has a very small distance to the
+    // widget borders, the size of the selection toggle will get
+    // increased to prevent an accidental clicking of the item
+    // when trying to hit the toggle.
+    const int widgetHeight = size().height();
+    const int widgetWidth = size().width();
+    const int minMargin = 2;
+
+    if (toggleSize + minMargin * 2 >= widgetHeight) {
+        pos.rx() -= (widgetHeight - toggleSize) / 2;
+        toggleSize = widgetHeight;
+        pos.setY(0);
+    }
+    if (toggleSize + minMargin * 2 >= widgetWidth) {
+        pos.ry() -= (widgetWidth - toggleSize) / 2;
+        toggleSize = widgetWidth;
+        pos.setX(0);
+    }
+
+    return QRectF(pos, QSizeF(toggleSize, toggleSize));
+}
+
+KItemListWidgetInformant* KStandardItemListWidget::createInformant()
+{
+    return new KStandardItemListWidgetInformant();
+}
+
+void KStandardItemListWidget::invalidateCache()
+{
+    m_dirtyLayout = true;
+    m_dirtyContent = true;
+}
+
+void KStandardItemListWidget::refreshCache()
+{
+}
+
+bool KStandardItemListWidget::isRoleRightAligned(const QByteArray& role) const
+{
+    Q_UNUSED(role);
+    return false;
+}
+
+void KStandardItemListWidget::setTextColor(const QColor& color)
+{
+    if (color != m_customTextColor) {
+        m_customTextColor = color;
+        updateAdditionalInfoTextColor();
+        update();
+    }
+}
+
+QColor KStandardItemListWidget::textColor() const
+{
+    if (m_customTextColor.isValid() && !isSelected()) {
+        return m_customTextColor;
+    }
+
+    const QPalette::ColorGroup group = isActiveWindow() ? QPalette::Active : QPalette::Inactive;
+    const QPalette::ColorRole role = isSelected() ? QPalette::HighlightedText : QPalette::Text;
+    return styleOption().palette.brush(group, role).color();
+}
+
+void KStandardItemListWidget::setOverlay(const QPixmap& overlay)
+{
+    m_overlay = overlay;
+    m_dirtyContent = true;
+    update();
+}
+
+QPixmap KStandardItemListWidget::overlay() const
+{
+    return m_overlay;
+}
+
+
+QString KStandardItemListWidget::roleText(const QByteArray& role,
+                                          const QHash<QByteArray, QVariant>& values) const
+{
+    return static_cast<const KStandardItemListWidgetInformant*>(informant())->roleText(role, values);
+}
+
+void KStandardItemListWidget::dataChanged(const QHash<QByteArray, QVariant>& current,
+                                          const QSet<QByteArray>& roles)
+{
+    Q_UNUSED(current);
+
+    m_dirtyContent = true;
+
+    QSet<QByteArray> dirtyRoles;
+    if (roles.isEmpty()) {
+        dirtyRoles = visibleRoles().toSet();
+        dirtyRoles.insert("iconPixmap");
+        dirtyRoles.insert("iconName");
+    } else {
+        dirtyRoles = roles;
+    }
+
+    QSetIterator<QByteArray> it(dirtyRoles);
+    while (it.hasNext()) {
+        const QByteArray& role = it.next();
+        m_dirtyContentRoles.insert(role);
+    }
+}
+
+void KStandardItemListWidget::visibleRolesChanged(const QList<QByteArray>& current,
+                                              const QList<QByteArray>& previous)
+{
+    Q_UNUSED(previous);
+    m_sortedVisibleRoles = current;
+    m_dirtyLayout = true;
+}
+
+void KStandardItemListWidget::columnWidthChanged(const QByteArray& role,
+                                             qreal current,
+                                             qreal previous)
+{
+    Q_UNUSED(role);
+    Q_UNUSED(current);
+    Q_UNUSED(previous);
+    m_dirtyLayout = true;
+}
+
+void KStandardItemListWidget::styleOptionChanged(const KItemListStyleOption& current,
+                                             const KItemListStyleOption& previous)
+{
+    Q_UNUSED(current);
+    Q_UNUSED(previous);
+    updateAdditionalInfoTextColor();
+    m_dirtyLayout = true;
+}
+
+void KStandardItemListWidget::hoveredChanged(bool hovered)
+{
+    Q_UNUSED(hovered);
+    m_dirtyLayout = true;
+}
+
+void KStandardItemListWidget::selectedChanged(bool selected)
+{
+    Q_UNUSED(selected);
+    updateAdditionalInfoTextColor();
+}
+
+void KStandardItemListWidget::siblingsInformationChanged(const QBitArray& current, const QBitArray& previous)
+{
+    Q_UNUSED(current);
+    Q_UNUSED(previous);
+    m_dirtyLayout = true;
+}
+
+void KStandardItemListWidget::editedRoleChanged(const QByteArray& current, const QByteArray& previous)
+{
+    Q_UNUSED(previous);
+
+   QGraphicsView* parent = scene()->views()[0];
+   if (current.isEmpty() || !parent || current != "text") {
+        if (m_roleEditor) {
+            emit roleEditingCanceled(index(), current, data().value(current));
+            m_roleEditor->deleteLater();
+            m_roleEditor = 0;
+        }
+        return;
+    }
+
+    Q_ASSERT(!m_roleEditor);
+
+    const TextInfo* textInfo = m_textInfo.value("text");
+
+    m_roleEditor = new KItemListRoleEditor(parent);
+    m_roleEditor->setIndex(index());
+    m_roleEditor->setRole(current);
+
+    const QString text = data().value(current).toString();
+    m_roleEditor->setPlainText(text);
+
+    QTextOption textOption = textInfo->staticText.textOption();
+    m_roleEditor->document()->setDefaultTextOption(textOption);
+
+    // Select the text without MIME-type extension
+    int selectionLength = text.length();
+
+    const QString extension = KMimeType::extractKnownExtension(text);
+    if (!extension.isEmpty()) {
+        selectionLength -= extension.length() + 1;
+    }
+
+    if (selectionLength > 0) {
+        QTextCursor cursor = m_roleEditor->textCursor();
+        cursor.movePosition(QTextCursor::StartOfBlock);
+        cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, selectionLength);
+        m_roleEditor->setTextCursor(cursor);
+    }
+
+    connect(m_roleEditor, SIGNAL(roleEditingCanceled(int,QByteArray,QVariant)),
+            this, SLOT(slotRoleEditingCanceled(int,QByteArray,QVariant)));
+    connect(m_roleEditor, SIGNAL(roleEditingFinished(int,QByteArray,QVariant)),
+            this, SLOT(slotRoleEditingFinished(int,QByteArray,QVariant)));
+
+    // Adjust the geometry of the editor
+    QRectF rect = roleEditingRect(current);
+    const int frameWidth = m_roleEditor->frameWidth();
+    rect.adjust(-frameWidth, -frameWidth, frameWidth, frameWidth);
+    rect.translate(pos());
+    if (rect.right() > parent->width()) {
+        rect.setWidth(parent->width() - rect.left());
+    }
+    m_roleEditor->setGeometry(rect.toRect());
+    m_roleEditor->show();
+    m_roleEditor->setFocus();
+}
+
+void KStandardItemListWidget::resizeEvent(QGraphicsSceneResizeEvent* event)
+{
+    if (m_roleEditor) {
+        setEditedRole(QByteArray());
+        Q_ASSERT(!m_roleEditor);
+    }
+
+    KItemListWidget::resizeEvent(event);
+
+    m_dirtyLayout = true;
+}
+
+void KStandardItemListWidget::showEvent(QShowEvent* event)
+{
+    KItemListWidget::showEvent(event);
+
+    // Listen to changes of the clipboard to mark the item as cut/uncut
+    KFileItemClipboard* clipboard = KFileItemClipboard::instance();
+
+    const KUrl itemUrl = data().value("url").value<KUrl>();
+    m_isCut = clipboard->isCut(itemUrl);
+
+    connect(clipboard, SIGNAL(cutItemsChanged()),
+            this, SLOT(slotCutItemsChanged()));
+}
+
+void KStandardItemListWidget::hideEvent(QHideEvent* event)
+{
+    disconnect(KFileItemClipboard::instance(), SIGNAL(cutItemsChanged()),
+               this, SLOT(slotCutItemsChanged()));
+
+    KItemListWidget::hideEvent(event);
+}
+
+void KStandardItemListWidget::slotCutItemsChanged()
+{
+    const KUrl itemUrl = data().value("url").value<KUrl>();
+    const bool isCut = KFileItemClipboard::instance()->isCut(itemUrl);
+    if (m_isCut != isCut) {
+        m_isCut = isCut;
+        m_pixmap = QPixmap();
+        m_dirtyContent = true;
+        update();
+    }
+}
+
+void KStandardItemListWidget::slotRoleEditingCanceled(int index,
+                                                  const QByteArray& role,
+                                                  const QVariant& value)
+{
+    m_roleEditor->deleteLater();
+    m_roleEditor = 0;
+    emit roleEditingCanceled(index, role, value);
+    setEditedRole(QByteArray());
+}
+
+void KStandardItemListWidget::slotRoleEditingFinished(int index,
+                                                  const QByteArray& role,
+                                                  const QVariant& value)
+{
+    m_roleEditor->deleteLater();
+    m_roleEditor = 0;
+    emit roleEditingFinished(index, role, value);
+    setEditedRole(QByteArray());
+}
+
+void KStandardItemListWidget::triggerCacheRefreshing()
+{
+    if ((!m_dirtyContent && !m_dirtyLayout) || index() < 0) {
+        return;
+    }
+
+    refreshCache();
+
+    const QHash<QByteArray, QVariant> values = data();
+    m_isExpandable = m_supportsItemExpanding && values["isExpandable"].toBool();
+    m_isHidden = values["text"].toString().startsWith(QLatin1Char('.'));
+
+    updateExpansionArea();
+    updateTextsCache();
+    updatePixmapCache();
+
+    m_dirtyLayout = false;
+    m_dirtyContent = false;
+    m_dirtyContentRoles.clear();
+}
+
+void KStandardItemListWidget::updateExpansionArea()
+{
+    if (m_supportsItemExpanding) {
+        const QHash<QByteArray, QVariant> values = data();
+        Q_ASSERT(values.contains("expandedParentsCount"));
+        const int expandedParentsCount = values.value("expandedParentsCount", 0).toInt();
+        if (expandedParentsCount >= 0) {
+            const qreal widgetHeight = size().height();
+            const qreal inc = (widgetHeight - KIconLoader::SizeSmall) / 2;
+            const qreal x = expandedParentsCount * widgetHeight + inc;
+            const qreal y = inc;
+            m_expansionArea = QRectF(x, y, KIconLoader::SizeSmall, KIconLoader::SizeSmall);
+            return;
+        }
+    }
+
+    m_expansionArea = QRectF();
+}
+
+void KStandardItemListWidget::updatePixmapCache()
+{
+    // Precondition: Requires already updated m_textPos values to calculate
+    // the remaining height when the alignment is vertical.
+
+    const QSizeF widgetSize = size();
+    const bool iconOnTop = (m_layout == IconsLayout);
+    const KItemListStyleOption& option = styleOption();
+    const qreal padding = option.padding;
+
+    const int maxIconWidth = iconOnTop ? widgetSize.width() - 2 * padding : option.iconSize;
+    const int maxIconHeight = option.iconSize;
+
+    const QHash<QByteArray, QVariant> values = data();
+
+    bool updatePixmap = (m_pixmap.width() != maxIconWidth || m_pixmap.height() != maxIconHeight);
+    if (!updatePixmap && m_dirtyContent) {
+        updatePixmap = m_dirtyContentRoles.isEmpty()
+                       || m_dirtyContentRoles.contains("iconPixmap")
+                       || m_dirtyContentRoles.contains("iconName")
+                       || m_dirtyContentRoles.contains("iconOverlays");
+    }
+
+    if (updatePixmap) {
+        m_pixmap = values["iconPixmap"].value<QPixmap>();
+        if (m_pixmap.isNull()) {
+            // Use the icon that fits to the MIME-type
+            QString iconName = values["iconName"].toString();
+            if (iconName.isEmpty()) {
+                // The icon-name has not been not resolved by KFileItemModelRolesUpdater,
+                // use a generic icon as fallback
+                iconName = QLatin1String("unknown");
+            }
+            m_pixmap = pixmapForIcon(iconName, maxIconHeight);
+        } else if (m_pixmap.width() != maxIconWidth || m_pixmap.height() != maxIconHeight) {
+            // A custom pixmap has been applied. Assure that the pixmap
+            // is scaled to the maximum available size.
+            KPixmapModifier::scale(m_pixmap, QSize(maxIconWidth, maxIconHeight));
+        }
+
+        const QStringList overlays = values["iconOverlays"].toStringList();
+
+        // Strangely KFileItem::overlays() returns empty string-values, so
+        // we need to check first whether an overlay must be drawn at all.
+        // It is more efficient to do it here, as KIconLoader::drawOverlays()
+        // assumes that an overlay will be drawn and has some additional
+        // setup time.
+        foreach (const QString& overlay, overlays) {
+            if (!overlay.isEmpty()) {
+                // There is at least one overlay, draw all overlays above m_pixmap
+                // and cancel the check
+                KIconLoader::global()->drawOverlays(overlays, m_pixmap, KIconLoader::Desktop);
+                break;
+            }
+        }
+
+        if (m_isCut) {
+            applyCutEffect(m_pixmap);
+        }
+
+        if (m_isHidden) {
+            applyHiddenEffect(m_pixmap);
+        }
+    }
+
+    if (!m_overlay.isNull()) {
+        QPainter painter(&m_pixmap);
+        painter.drawPixmap(0, m_pixmap.height() - m_overlay.height(), m_overlay);
+    }
+
+    int scaledIconSize = 0;
+    if (iconOnTop) {
+        const TextInfo* textInfo = m_textInfo.value("text");
+        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();
+        scaledIconSize = (requiredTextHeight < maxIconHeight) ?
+                           widgetSize.height() - 2 * padding : maxIconHeight;
+    }
+
+    const int maxScaledIconWidth = iconOnTop ? widgetSize.width() - 2 * padding : scaledIconSize;
+    const int maxScaledIconHeight = scaledIconSize;
+
+    m_scaledPixmapSize = m_pixmap.size();
+    m_scaledPixmapSize.scale(maxScaledIconWidth, maxScaledIconHeight, Qt::KeepAspectRatio);
+
+    if (iconOnTop) {
+        // Center horizontally and align on bottom within the icon-area
+        m_pixmapPos.setX((widgetSize.width() - m_scaledPixmapSize.width()) / 2);
+        m_pixmapPos.setY(padding + scaledIconSize - m_scaledPixmapSize.height());
+    } else {
+        // Center horizontally and vertically within the icon-area
+        const TextInfo* textInfo = m_textInfo.value("text");
+        m_pixmapPos.setX(textInfo->pos.x() - 2 * padding
+                         - (scaledIconSize + m_scaledPixmapSize.width()) / 2);
+        m_pixmapPos.setY(padding
+                         + (scaledIconSize - m_scaledPixmapSize.height()) / 2);
+    }
+
+    m_iconRect = QRectF(m_pixmapPos, QSizeF(m_scaledPixmapSize));
+
+    // Prepare the pixmap that is used when the item gets hovered
+    if (isHovered()) {
+        m_hoverPixmap = m_pixmap;
+        KIconEffect* effect = KIconLoader::global()->iconEffect();
+        // In the KIconLoader terminology, active = hover.
+        if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState)) {
+            m_hoverPixmap = effect->apply(m_pixmap, KIconLoader::Desktop, KIconLoader::ActiveState);
+        } else {
+            m_hoverPixmap = m_pixmap;
+        }
+    } else if (hoverOpacity() <= 0.0) {
+        // No hover animation is ongoing. Clear m_hoverPixmap to save memory.
+        m_hoverPixmap = QPixmap();
+    }
+}
+
+void KStandardItemListWidget::updateTextsCache()
+{
+    QTextOption textOption;
+    switch (m_layout) {
+    case IconsLayout:
+        textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
+        textOption.setAlignment(Qt::AlignHCenter);
+        break;
+    case CompactLayout:
+    case DetailsLayout:
+        textOption.setAlignment(Qt::AlignLeft);
+        textOption.setWrapMode(QTextOption::NoWrap);
+        break;
+    default:
+        Q_ASSERT(false);
+        break;
+    }
+
+    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) {
+    case IconsLayout:   updateIconsLayoutTextCache(); break;
+    case CompactLayout: updateCompactLayoutTextCache(); break;
+    case DetailsLayout: updateDetailsLayoutTextCache(); break;
+    default: Q_ASSERT(false); break;
+    }
+
+    const TextInfo* ratingTextInfo = m_textInfo.value("rating");
+    if (ratingTextInfo) {
+        // The text of the rating-role has been set to empty to get
+        // replaced by a rating-image showing the rating as stars.
+        const KItemListStyleOption& option = styleOption();
+        QSizeF ratingSize = preferredRatingSize(option);
+
+        const qreal availableWidth = (m_layout == DetailsLayout)
+                                     ? columnWidth("rating") - columnPadding(option)
+                                     : m_textRect.width();
+        if (ratingSize.width() > availableWidth) {
+            ratingSize.rwidth() = availableWidth;
+        }
+        m_rating = QPixmap(ratingSize.toSize());
+        m_rating.fill(Qt::transparent);
+
+        QPainter painter(&m_rating);
+        const QRect rect(0, 0, m_rating.width(), m_rating.height());
+        const int rating = data().value("rating").toInt();
+        KRatingPainter::paintRating(&painter, rect, Qt::AlignJustify | Qt::AlignVCenter, rating);
+    } else if (!m_rating.isNull()) {
+        m_rating = QPixmap();
+    }
+}
+
+void KStandardItemListWidget::updateIconsLayoutTextCache()
+{
+    //      +------+
+    //      | Icon |
+    //      +------+
+    //
+    //    Name role that
+    // might get wrapped above
+    //    several lines.
+    //  Additional role 1
+    //  Additional role 2
+
+    const QHash<QByteArray, QVariant> values = data();
+
+    const KItemListStyleOption& option = styleOption();
+    const qreal padding = option.padding;
+    const qreal maxWidth = size().width() - 2 * padding;
+    const qreal widgetHeight = size().height();
+    const qreal lineSpacing = option.fontMetrics.lineSpacing();
+
+    // Initialize properties for the "text" role. It will be used as anchor
+    // for initializing the position of the other roles.
+    TextInfo* nameTextInfo = m_textInfo.value("text");
+    const QString nameText = KStringHandler::preProcessWrap(values["text"].toString());
+    nameTextInfo->staticText.setText(nameText);
+
+    // Calculate the number of lines required for the name and the required width
+    qreal nameWidth = 0;
+    qreal nameHeight = 0;
+    QTextLine line;
+
+    const int additionalRolesCount = qMax(visibleRoles().count() - 1, 0);
+    const int maxNameLines = (option.maxTextSize.height() / int(lineSpacing)) - additionalRolesCount;
+
+    QTextLayout layout(nameTextInfo->staticText.text(), option.font);
+    layout.setTextOption(nameTextInfo->staticText.textOption());
+    layout.beginLayout();
+    int nameLineIndex = 0;
+    while ((line = layout.createLine()).isValid()) {
+        line.setLineWidth(maxWidth);
+        nameWidth = qMax(nameWidth, line.naturalTextWidth());
+        nameHeight += line.height();
+
+        ++nameLineIndex;
+        if (nameLineIndex == maxNameLines) {
+            // The maximum number of textlines has been reached. If this is
+            // the case provide an elided text if necessary.
+            const int textLength = line.textStart() + line.textLength();
+            if (textLength < nameText.length()) {
+                // Elide the last line of the text
+                QString lastTextLine = nameText.mid(line.textStart(), line.textLength());
+                lastTextLine = option.fontMetrics.elidedText(lastTextLine,
+                                                             Qt::ElideRight,
+                                                             line.naturalTextWidth() - 1);
+                const QString elidedText = nameText.left(line.textStart()) + lastTextLine;
+                nameTextInfo->staticText.setText(elidedText);
+            }
+            break;
+        }
+    }
+    layout.endLayout();
+
+    // Use one line for each additional information
+    nameTextInfo->staticText.setTextWidth(maxWidth);
+    nameTextInfo->pos = QPointF(padding, widgetHeight -
+                                         nameHeight -
+                                         additionalRolesCount * lineSpacing -
+                                         padding);
+    m_textRect = QRectF(padding + (maxWidth - nameWidth) / 2,
+                        nameTextInfo->pos.y(),
+                        nameWidth,
+                        nameHeight);
+
+    // Calculate the position for each additional information
+    qreal y = nameTextInfo->pos.y() + nameHeight;
+    foreach (const QByteArray& role, m_sortedVisibleRoles) {
+        if (role == "text") {
+            continue;
+        }
+
+        const QString text = roleText(role, values);
+        TextInfo* textInfo = m_textInfo.value(role);
+        textInfo->staticText.setText(text);
+
+        qreal requiredWidth = 0;
+
+        QTextLayout layout(text, option.font);
+        QTextOption textOption;
+        textOption.setWrapMode(QTextOption::NoWrap);
+        layout.setTextOption(textOption);
+
+        layout.beginLayout();
+        QTextLine textLine = layout.createLine();
+        if (textLine.isValid()) {
+            textLine.setLineWidth(maxWidth);
+            requiredWidth = textLine.naturalTextWidth();
+            if (requiredWidth > maxWidth) {
+                const QString elidedText = option.fontMetrics.elidedText(text, Qt::ElideRight, maxWidth);
+                textInfo->staticText.setText(elidedText);
+                requiredWidth = option.fontMetrics.width(elidedText);
+            }
+        }
+        layout.endLayout();
+
+        textInfo->pos = QPointF(padding, y);
+        textInfo->staticText.setTextWidth(maxWidth);
+
+        const QRectF textRect(padding + (maxWidth - requiredWidth) / 2, y, requiredWidth, lineSpacing);
+        m_textRect |= textRect;
+
+        y += lineSpacing;
+    }
+
+    // Add a padding to the text rectangle
+    m_textRect.adjust(-padding, -padding, padding, padding);
+}
+
+void KStandardItemListWidget::updateCompactLayoutTextCache()
+{
+    // +------+  Name role
+    // | Icon |  Additional role 1
+    // +------+  Additional role 2
+
+    const QHash<QByteArray, QVariant> values = data();
+
+    const KItemListStyleOption& option = styleOption();
+    const qreal widgetHeight = size().height();
+    const qreal lineSpacing = option.fontMetrics.lineSpacing();
+    const qreal textLinesHeight = qMax(visibleRoles().count(), 1) * lineSpacing;
+    const int scaledIconSize = (textLinesHeight < option.iconSize) ? widgetHeight - 2 * option.padding : option.iconSize;
+
+    qreal maximumRequiredTextWidth = 0;
+    const qreal x = option.padding * 3 + scaledIconSize;
+    qreal y = qRound((widgetHeight - textLinesHeight) / 2);
+    const qreal maxWidth = size().width() - x - option.padding;
+    foreach (const QByteArray& role, m_sortedVisibleRoles) {
+        const QString text = roleText(role, values);
+        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);
+            textInfo->staticText.setText(elidedText);
+        }
+
+        textInfo->pos = QPointF(x, y);
+        textInfo->staticText.setTextWidth(maxWidth);
+
+        maximumRequiredTextWidth = qMax(maximumRequiredTextWidth, requiredWidth);
+
+        y += lineSpacing;
+    }
+
+    m_textRect = QRectF(x - option.padding, 0, maximumRequiredTextWidth + 2 * option.padding, widgetHeight);
+}
+
+void KStandardItemListWidget::updateDetailsLayoutTextCache()
+{
+    // Precondition: Requires already updated m_expansionArea
+    // to determine the left position.
+
+    // +------+
+    // | Icon |  Name role   Additional role 1   Additional role 2
+    // +------+
+    m_textRect = QRectF();
+
+    const KItemListStyleOption& option = styleOption();
+    const QHash<QByteArray, QVariant> values = data();
+
+    const qreal widgetHeight = size().height();
+    const int scaledIconSize = widgetHeight - 2 * option.padding;
+    const int fontHeight = option.fontMetrics.height();
+
+    const qreal columnWidthInc = columnPadding(option);
+    qreal firstColumnInc = scaledIconSize;
+    if (m_supportsItemExpanding) {
+        firstColumnInc += (m_expansionArea.left() + m_expansionArea.right() + widgetHeight) / 2;
+    } else {
+        firstColumnInc += option.padding;
+    }
+
+    qreal x = firstColumnInc;
+    const qreal y = qMax(qreal(option.padding), (widgetHeight - fontHeight) / 2);
+
+    foreach (const QByteArray& role, m_sortedVisibleRoles) {
+        QString text = roleText(role, values);
+
+        // Elide the text in case it does not fit into the available column-width
+        qreal requiredWidth = option.fontMetrics.width(text);
+        const qreal roleWidth = columnWidth(role);
+        qreal availableTextWidth = roleWidth - columnWidthInc;
+
+        const bool isTextRole = (role == "text");
+        if (isTextRole) {
+            availableTextWidth -= firstColumnInc;
+        }
+
+        if (requiredWidth > availableTextWidth) {
+            text = option.fontMetrics.elidedText(text, Qt::ElideRight, availableTextWidth);
+            requiredWidth = option.fontMetrics.width(text);
+        }
+
+        TextInfo* textInfo = m_textInfo.value(role);
+        textInfo->staticText.setText(text);
+        textInfo->pos = QPointF(x + columnWidthInc / 2, y);
+        x += roleWidth;
+
+        if (isTextRole) {
+            const qreal textWidth = option.extendedSelectionRegion
+                                    ? size().width() - textInfo->pos.x()
+                                    : requiredWidth + 2 * option.padding;
+            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
+            // from the expansion-level shown in the name column
+            x -= firstColumnInc;
+        } else if (isRoleRightAligned(role)) {
+            textInfo->pos.rx() += roleWidth - requiredWidth - columnWidthInc;
+        }
+    }
+}
+
+void KStandardItemListWidget::updateAdditionalInfoTextColor()
+{
+    QColor c1;
+    if (m_customTextColor.isValid()) {
+        c1 = m_customTextColor;
+    } else if (isSelected() && m_layout != DetailsLayout) {
+        c1 = styleOption().palette.highlightedText().color();
+    } else {
+        c1 = styleOption().palette.text().color();
+    }
+
+    // For the color of the additional info the inactive text color
+    // is not used as this might lead to unreadable text for some color schemes. Instead
+    // the text color c1 is slightly mixed with the background color.
+    const QColor c2 = styleOption().palette.base().color();
+    const int p1 = 70;
+    const int p2 = 100 - p1;
+    m_additionalInfoTextColor = QColor((c1.red()   * p1 + c2.red()   * p2) / 100,
+                                       (c1.green() * p1 + c2.green() * p2) / 100,
+                                       (c1.blue()  * p1 + c2.blue()  * p2) / 100);
+}
+
+void KStandardItemListWidget::drawPixmap(QPainter* painter, const QPixmap& pixmap)
+{
+    if (m_scaledPixmapSize != pixmap.size()) {
+        QPixmap scaledPixmap = pixmap;
+        KPixmapModifier::scale(scaledPixmap, m_scaledPixmapSize);
+        painter->drawPixmap(m_pixmapPos, scaledPixmap);
+
+#ifdef KFILEITEMLISTWIDGET_DEBUG
+        painter->setPen(Qt::blue);
+        painter->drawRect(QRectF(m_pixmapPos, QSizeF(m_scaledPixmapSize)));
+#endif
+    } else {
+        painter->drawPixmap(m_pixmapPos, pixmap);
+    }
+}
+
+void KStandardItemListWidget::drawSiblingsInformation(QPainter* painter)
+{
+    const int siblingSize = size().height();
+    const int x = (m_expansionArea.left() + m_expansionArea.right() - siblingSize) / 2;
+    QRect siblingRect(x, 0, siblingSize, siblingSize);
+
+    QStyleOption option;
+    bool isItemSibling = true;
+
+    const QBitArray siblings = siblingsInformation();
+    for (int i = siblings.count() - 1; i >= 0; --i) {
+        option.rect = siblingRect;
+        option.state = siblings.at(i) ? QStyle::State_Sibling : QStyle::State_None;
+
+        if (isItemSibling) {
+            option.state |= QStyle::State_Item;
+            if (m_isExpandable) {
+                option.state |= QStyle::State_Children;
+            }
+            if (data()["isExpanded"].toBool()) {
+                option.state |= QStyle::State_Open;
+            }
+            isItemSibling = false;
+        }
+
+        style()->drawPrimitive(QStyle::PE_IndicatorBranch, &option, painter);
+
+        siblingRect.translate(-siblingRect.width(), 0);
+    }
+}
+
+QRectF KStandardItemListWidget::roleEditingRect(const QByteArray& role) const
+{
+    const TextInfo* textInfo = m_textInfo.value(role);
+    if (!textInfo) {
+        return QRectF();
+    }
+
+    QRectF rect(textInfo->pos, textInfo->staticText.size());
+    if (m_layout == DetailsLayout) {
+        rect.setWidth(columnWidth(role) - rect.x());
+    }
+
+    return rect;
+}
+
+QPixmap KStandardItemListWidget::pixmapForIcon(const QString& name, int size)
+{
+    const KIcon icon(name);
+
+    int requestedSize;
+    if (size <= KIconLoader::SizeSmall) {
+        requestedSize = KIconLoader::SizeSmall;
+    } else if (size <= KIconLoader::SizeSmallMedium) {
+        requestedSize = KIconLoader::SizeSmallMedium;
+    } else if (size <= KIconLoader::SizeMedium) {
+        requestedSize = KIconLoader::SizeMedium;
+    } else if (size <= KIconLoader::SizeLarge) {
+        requestedSize = KIconLoader::SizeLarge;
+    } else if (size <= KIconLoader::SizeHuge) {
+        requestedSize = KIconLoader::SizeHuge;
+    } else if (size <= KIconLoader::SizeEnormous) {
+        requestedSize = KIconLoader::SizeEnormous;
+    } else if (size <= KIconLoader::SizeEnormous * 2) {
+        requestedSize = KIconLoader::SizeEnormous * 2;
+    } else {
+        requestedSize = size;
+    }
+
+    QPixmap pixmap = icon.pixmap(requestedSize, requestedSize);
+    if (requestedSize != size) {
+        KPixmapModifier::scale(pixmap, QSize(size, size));
+    }
+
+    return pixmap;
+}
+
+void KStandardItemListWidget::applyCutEffect(QPixmap& pixmap)
+{
+    KIconEffect* effect = KIconLoader::global()->iconEffect();
+    pixmap = effect->apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
+}
+
+void KStandardItemListWidget::applyHiddenEffect(QPixmap& pixmap)
+{
+    KIconEffect::semiTransparent(pixmap);
+}
+
+QSizeF KStandardItemListWidget::preferredRatingSize(const KItemListStyleOption& option)
+{
+    const qreal height = option.fontMetrics.ascent();
+    return QSizeF(height * 5, height);
+}
+
+qreal KStandardItemListWidget::columnPadding(const KItemListStyleOption& option)
+{
+    return option.padding * 6;
+}
+
+#include "kstandarditemlistwidget.moc"
diff --git a/src/kitemviews/kstandarditemlistwidget.h b/src/kitemviews/kstandarditemlistwidget.h
new file mode 100644 (file)
index 0000000..1bd44e2
--- /dev/null
@@ -0,0 +1,218 @@
+/***************************************************************************
+ *   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 KSTANDARDITEMLISTWIDGET_H
+#define KSTANDARDITEMLISTWIDGET_H
+
+#include <libdolphin_export.h>
+
+#include <kitemviews/kitemlistwidget.h>
+
+#include <QPixmap>
+#include <QPointF>
+#include <QStaticText>
+
+class KItemListRoleEditor;
+class KItemListStyleOption;
+class KItemListView;
+
+class LIBDOLPHINPRIVATE_EXPORT KStandardItemListWidgetInformant : public KItemListWidgetInformant
+{
+public:
+    KStandardItemListWidgetInformant();
+    virtual ~KStandardItemListWidgetInformant();
+
+    virtual QSizeF itemSizeHint(int index, const KItemListView* view) const;
+
+    virtual qreal preferredRoleColumnWidth(const QByteArray& role,
+                                           int index,
+                                           const KItemListView* view) const;
+protected:
+    /**
+     * @return String representation of the role \a role. The representation of
+     *         a role might depend on other roles, so the values of all roles
+     *         are passed as parameter.
+     */
+    virtual QString roleText(const QByteArray& role,
+                             const QHash<QByteArray, QVariant>& values) const;
+
+    friend class KStandardItemListWidget; // Accesses roleText()
+};
+
+/**
+ * @brief Itemlist widget implementation for KStandardItemView and KStandardItemModel.
+ */
+class LIBDOLPHINPRIVATE_EXPORT KStandardItemListWidget : public KItemListWidget
+{
+    Q_OBJECT
+
+public:
+    enum Layout
+    {
+        IconsLayout,
+        CompactLayout,
+        DetailsLayout
+    };
+
+    KStandardItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent);
+    virtual ~KStandardItemListWidget();
+
+    void setLayout(Layout layout);
+    Layout layout() const;
+
+    void setSupportsItemExpanding(bool supportsItemExpanding);
+    bool supportsItemExpanding() const;
+
+    virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0);
+
+    virtual QRectF iconRect() const;
+    virtual QRectF textRect() const;
+    virtual QRectF textFocusRect() const;
+    virtual QRectF expansionToggleRect() const;
+    virtual QRectF selectionToggleRect() const;
+
+    static KItemListWidgetInformant* createInformant();
+
+protected:
+    /**
+     * Invalidates the cache which results in calling KStandardItemListWidget::refreshCache() as
+     * soon as the item need to gets repainted.
+     */
+    void invalidateCache();
+
+    /**
+     * Is called if the cache got invalidated by KStandardItemListWidget::invalidateCache().
+     * The default implementation is empty.
+     */
+    virtual void refreshCache();
+
+    /**
+     * @return True if the give role should be right aligned when showing it inside a column.
+     *         Per default false is returned.
+     */
+    virtual bool isRoleRightAligned(const QByteArray& role) const;
+
+    void setTextColor(const QColor& color);
+    QColor textColor() const;
+
+    void setOverlay(const QPixmap& overlay);
+    QPixmap overlay() const;
+
+    /**
+     * @see KStandardItemListWidgetInformant::roleText().
+     */
+    QString roleText(const QByteArray& role, const QHash<QByteArray, QVariant>& values) const;
+
+    virtual void dataChanged(const QHash<QByteArray, QVariant>& current, const QSet<QByteArray>& roles = QSet<QByteArray>());
+    virtual void visibleRolesChanged(const QList<QByteArray>& current, const QList<QByteArray>& previous);
+    virtual void columnWidthChanged(const QByteArray& role, qreal current, qreal previous);
+    virtual void styleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous);
+    virtual void hoveredChanged(bool hovered);
+    virtual void selectedChanged(bool selected);
+    virtual void siblingsInformationChanged(const QBitArray& current, const QBitArray& previous);
+    virtual void editedRoleChanged(const QByteArray& current, const QByteArray& previous);
+    virtual void resizeEvent(QGraphicsSceneResizeEvent* event);
+    virtual void showEvent(QShowEvent* event);
+    virtual void hideEvent(QHideEvent* event);
+
+private slots:
+    void slotCutItemsChanged();
+    void slotRoleEditingCanceled(int index, const QByteArray& role, const QVariant& value);
+    void slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value);
+
+private:
+    void triggerCacheRefreshing();
+    void updateExpansionArea();
+    void updatePixmapCache();
+
+    void updateTextsCache();
+    void updateIconsLayoutTextCache();
+    void updateCompactLayoutTextCache();
+    void updateDetailsLayoutTextCache();
+
+    void updateAdditionalInfoTextColor();
+
+    void drawPixmap(QPainter* painter, const QPixmap& pixmap);
+    void drawSiblingsInformation(QPainter* painter);
+
+    QRectF roleEditingRect(const QByteArray &role) const;
+
+    static QPixmap pixmapForIcon(const QString& name, int size);
+    static void applyCutEffect(QPixmap& pixmap);
+    static void applyHiddenEffect(QPixmap& pixmap);
+
+    /**
+     * @return Preferred size of the rating-image based on the given
+     *         style-option. The height of the font is taken as
+     *         reference.
+     */
+    static QSizeF preferredRatingSize(const KItemListStyleOption& option);
+
+    /**
+     * @return Horizontal padding in pixels that is added to the required width of
+     *         a column to display the content.
+     */
+    static qreal columnPadding(const KItemListStyleOption& option);
+
+private:
+    bool m_isCut;
+    bool m_isHidden;
+    bool m_isExpandable;
+    bool m_supportsItemExpanding;
+
+    bool m_dirtyLayout;
+    bool m_dirtyContent;
+    QSet<QByteArray> m_dirtyContentRoles;
+
+    Layout m_layout;
+    QPointF m_pixmapPos;
+    QPixmap m_pixmap;
+    QSize m_scaledPixmapSize;
+
+    QRectF m_iconRect;          // Cache for KItemListWidget::iconRect()
+    QPixmap m_hoverPixmap;      // Cache for modified m_pixmap when hovering the item
+
+    struct TextInfo
+    {
+        QPointF pos;
+        QStaticText staticText;
+    };
+    QHash<QByteArray, TextInfo*> m_textInfo;
+
+    QRectF m_textRect;
+
+    QList<QByteArray> m_sortedVisibleRoles;
+
+    QRectF m_expansionArea;
+
+    QColor m_customTextColor;
+    QColor m_additionalInfoTextColor;
+
+    QPixmap m_overlay;
+    QPixmap m_rating;
+
+    KItemListRoleEditor* m_roleEditor;
+
+    friend class KStandardItemListWidgetInformant; // Accesses private static methods to be able to
+                                                   // share a common layout calculation
+};
+
+#endif
+
+
diff --git a/src/kitemviews/kstandarditemmodel.cpp b/src/kitemviews/kstandarditemmodel.cpp
new file mode 100644 (file)
index 0000000..76b2ad0
--- /dev/null
@@ -0,0 +1,128 @@
+/***************************************************************************
+ *   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 "kstandarditemmodel.h"
+#include "kstandarditem.h"
+
+KStandardItemModel::KStandardItemModel(QObject* parent) :
+    KItemModelBase(parent),
+    m_items(),
+    m_indexesForItems()
+{
+}
+
+KStandardItemModel::~KStandardItemModel()
+{
+}
+
+void KStandardItemModel::insertItem(int index, KStandardItem* item)
+{
+    if (!m_indexesForItems.contains(item) && !item->m_model) {
+        m_items.insert(index, item);
+        m_indexesForItems.insert(item, index);
+        item->m_model = this;
+        // TODO: no hierarchical items are handled yet
+    }
+}
+
+void KStandardItemModel::appendItem(KStandardItem *item)
+{
+    insertItem(m_items.count(), item);
+}
+
+void KStandardItemModel::removeItem(KStandardItem* item)
+{
+    const int index = m_indexesForItems.value(item, -1);
+    if (index >= 0) {
+        m_items.removeAt(index);
+        m_indexesForItems.remove(item);
+        delete item;
+        // TODO: no hierarchical items are handled yet
+    }
+}
+
+KStandardItem* KStandardItemModel::item(int index) const
+{
+    if (index < 0 || index >= m_items.count()) {
+        return 0;
+    }
+    return m_items[index];
+}
+
+int KStandardItemModel::index(const KStandardItem* item) const
+{
+    return m_indexesForItems.value(item, -1);
+}
+
+int KStandardItemModel::count() const
+{
+    return m_items.count();
+}
+
+QHash<QByteArray, QVariant> KStandardItemModel::data(int index) const
+{
+    // TODO: Ugly hack
+    QHash<QByteArray, QVariant> values;
+    const KStandardItem* item = m_items[index];
+    values.insert("text", item->text());
+    values.insert("iconName", item->icon().name());
+    return values;
+}
+
+bool KStandardItemModel::setData(int index, const QHash<QByteArray, QVariant>& values)
+{
+    Q_UNUSED(values);
+    if (index < 0 || index >= count()) {
+        return false;
+    }
+
+    return true;
+}
+
+QMimeData* KStandardItemModel::createMimeData(const QSet<int>& indexes) const
+{
+    Q_UNUSED(indexes);
+    return 0;
+}
+
+int KStandardItemModel::indexForKeyboardSearch(const QString& text, int startFromIndex) const
+{
+    Q_UNUSED(text);
+    Q_UNUSED(startFromIndex);
+    return -1;
+}
+
+bool KStandardItemModel::supportsDropping(int index) const
+{
+    Q_UNUSED(index);
+    return false;
+}
+
+QString KStandardItemModel::roleDescription(const QByteArray& role) const
+{
+    Q_UNUSED(role);
+    return QString();
+}
+
+QList<QPair<int, QVariant> > KStandardItemModel::groups() const
+{
+    return QList<QPair<int, QVariant> >();
+}
+
+#include "kstandarditemmodel.moc"
diff --git a/src/kitemviews/kstandarditemmodel.h b/src/kitemviews/kstandarditemmodel.h
new file mode 100644 (file)
index 0000000..01d2d4d
--- /dev/null
@@ -0,0 +1,68 @@
+/***************************************************************************
+ *   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 KSTANDARDITEMMODEL_H
+#define KSTANDARDITEMMODEL_H
+
+#include <libdolphin_export.h>
+#include <kitemviews/kitemmodelbase.h>
+#include <QHash>
+#include <QList>
+
+class KStandardItem;
+
+/**
+ * @brief Model counterpart for KStandardItemView.
+ *
+ * Allows to add items to the model in an easy way by the
+ * class KStandardItem.
+ *
+ * @see KStandardItem
+ */
+class LIBDOLPHINPRIVATE_EXPORT KStandardItemModel : public KItemModelBase
+{
+    Q_OBJECT
+
+public:
+    explicit KStandardItemModel(QObject* parent = 0);
+    virtual ~KStandardItemModel();
+
+    void insertItem(int index, KStandardItem* item);
+    void appendItem(KStandardItem* item);
+    void removeItem(KStandardItem* item);
+    KStandardItem* item(int index) const;
+    int index(const KStandardItem* item) const;
+
+    virtual int count() const;
+    virtual QHash<QByteArray, QVariant> data(int index) const;
+    virtual bool setData(int index, const QHash<QByteArray, QVariant>& values);
+    virtual QMimeData* createMimeData(const QSet<int>& indexes) const;
+    virtual int indexForKeyboardSearch(const QString& text, int startFromIndex = 0) const;
+    virtual bool supportsDropping(int index) const;
+    virtual QString roleDescription(const QByteArray& role) const;
+    virtual QList<QPair<int, QVariant> > groups() const;
+
+private:
+    QList<KStandardItem*> m_items;
+    QHash<const KStandardItem*, int> m_indexesForItems;
+};
+
+#endif
+
+
index 40e5eca8d118a8a1fc607deedcd1051f977c2ec5..5e8286cdcdea25d242781895cdb3c3fa7a5a9c1a 100644 (file)
@@ -48,7 +48,8 @@
 FoldersPanel::FoldersPanel(QWidget* parent) :
     Panel(parent),
     m_updateCurrentItem(false),
-    m_controller(0)
+    m_controller(0),
+    m_model(0)
 {
     setLayoutDirection(Qt::LeftToRight);
 }
@@ -67,7 +68,7 @@ FoldersPanel::~FoldersPanel()
 void FoldersPanel::setShowHiddenFiles(bool show)
 {
     FoldersPanelSettings::setHiddenFilesShown(show);
-    fileItemModel()->setShowHiddenFiles(show);
+    m_model->setShowHiddenFiles(show);
 }
 
 bool FoldersPanel::showHiddenFiles() const
@@ -88,8 +89,8 @@ bool FoldersPanel::autoScrolling() const
 
 void FoldersPanel::rename(const KFileItem& item)
 {
-    const int index = fileItemModel()->index(item);
-    m_controller->view()->editRole(index, "name");
+    const int index = m_model->index(item);
+    m_controller->view()->editRole(index, "text");
 }
 
 bool FoldersPanel::urlChanged()
@@ -115,21 +116,10 @@ void FoldersPanel::showEvent(QShowEvent* event)
     }
 
     if (!m_controller) {
-        // Postpone the creating of the dir lister to the first show event.
-        // This assures that no performance and memory overhead is given when the TreeView is not
-        // used at all (see FoldersPanel::setUrl()).
+        // Postpone the creating of the controller to the first show event.
+        // This assures that no performance and memory overhead is given when the folders panel is not
+        // used at all and stays invisible.
         KFileItemListView* view  = new KFileItemListView();
-        view->setWidgetCreator(new KItemListWidgetCreator<KFileItemListWidget>());
-
-        KItemListStyleOption styleOption = view->styleOption();
-        styleOption.padding = 2;
-        styleOption.iconSize = KIconLoader::SizeSmall;
-        styleOption.extendedSelectionRegion = true;
-        view->setStyleOption(styleOption);
-
-        const qreal itemHeight = qMax(int(KIconLoader::SizeSmall), styleOption.fontMetrics.height());
-        view->setItemSize(QSizeF(-1, itemHeight + 2 * styleOption.padding));
-        view->setItemLayout(KFileItemListView::DetailsLayout);
         view->setSupportsItemExpanding(true);
         // Set the opacity to 0 initially. The opacity will be increased after the loading of the initial tree
         // has been finished in slotLoadingCompleted(). This prevents an unnecessary animation-mess when
@@ -139,17 +129,14 @@ void FoldersPanel::showEvent(QShowEvent* event)
         connect(view, SIGNAL(roleEditingFinished(int,QByteArray,QVariant)),
                 this, SLOT(slotRoleEditingFinished(int,QByteArray,QVariant)));
 
-        KFileItemModel* model = new KFileItemModel(this);
-        model->setShowDirectoriesOnly(true);
-        model->setShowHiddenFiles(FoldersPanelSettings::hiddenFilesShown());
+        m_model = new KFileItemModel(this);
+        m_model->setShowDirectoriesOnly(true);
+        m_model->setShowHiddenFiles(FoldersPanelSettings::hiddenFilesShown());
         // Use a QueuedConnection to give the view the possibility to react first on the
         // finished loading.
-        connect(model, SIGNAL(directoryLoadingCompleted()), this, SLOT(slotLoadingCompleted()), Qt::QueuedConnection);
+        connect(m_model, SIGNAL(directoryLoadingCompleted()), this, SLOT(slotLoadingCompleted()), Qt::QueuedConnection);
 
-        KItemListContainer* container = new KItemListContainer(this);
-        m_controller = container->controller();
-        m_controller->setView(view);
-        m_controller->setModel(model);
+        m_controller = new KItemListController(m_model, view, this);
         m_controller->setSelectionBehavior(KItemListController::SingleSelection);
         m_controller->setAutoActivationDelay(750);
         m_controller->setSingleClickActivation(true);
@@ -160,21 +147,8 @@ void FoldersPanel::showEvent(QShowEvent* event)
         connect(m_controller, SIGNAL(viewContextMenuRequested(QPointF)), this, SLOT(slotViewContextMenuRequested(QPointF)));
         connect(m_controller, SIGNAL(itemDropEvent(int,QGraphicsSceneDragDropEvent*)), this, SLOT(slotItemDropEvent(int,QGraphicsSceneDragDropEvent*)));
 
-        // TODO: Check whether it makes sense to make an explicit API for KItemListContainer
-        // to make the background transparent.
-        container->setFrameShape(QFrame::NoFrame);
-        QGraphicsView* graphicsView = qobject_cast<QGraphicsView*>(container->viewport());
-        if (graphicsView) {
-            // Make the background of the container transparent and apply the window-text color
-            // to the text color, so that enough contrast is given for all color
-            // schemes
-            QPalette p = graphicsView->palette();
-            p.setColor(QPalette::Active,   QPalette::Text, p.color(QPalette::Active,   QPalette::WindowText));
-            p.setColor(QPalette::Inactive, QPalette::Text, p.color(QPalette::Inactive, QPalette::WindowText));
-            p.setColor(QPalette::Disabled, QPalette::Text, p.color(QPalette::Disabled, QPalette::WindowText));
-            graphicsView->setPalette(p);
-            graphicsView->viewport()->setAutoFillBackground(false);
-        }
+        KItemListContainer* container = new KItemListContainer(m_controller, this);
+        container->setEnabledFrame(false);
 
         QVBoxLayout* layout = new QVBoxLayout(this);
         layout->setMargin(0);
@@ -197,7 +171,7 @@ void FoldersPanel::keyPressEvent(QKeyEvent* event)
 
 void FoldersPanel::slotItemActivated(int index)
 {
-    const KFileItem item = fileItemModel()->fileItem(index);
+    const KFileItem item = m_model->fileItem(index);
     if (!item.isNull()) {
         emit changeUrl(item.url(), Qt::LeftButton);
     }
@@ -205,7 +179,7 @@ void FoldersPanel::slotItemActivated(int index)
 
 void FoldersPanel::slotItemMiddleClicked(int index)
 {
-    const KFileItem item = fileItemModel()->fileItem(index);
+    const KFileItem item = m_model->fileItem(index);
     if (!item.isNull()) {
         emit changeUrl(item.url(), Qt::MiddleButton);
     }
@@ -215,7 +189,7 @@ void FoldersPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
 {
     Q_UNUSED(pos);
 
-    const KFileItem fileItem = fileItemModel()->fileItem(index);
+    const KFileItem fileItem = m_model->fileItem(index);
 
     QWeakPointer<TreeViewContextMenu> contextMenu = new TreeViewContextMenu(this, fileItem);
     contextMenu.data()->open();
@@ -238,7 +212,7 @@ void FoldersPanel::slotViewContextMenuRequested(const QPointF& pos)
 void FoldersPanel::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* event)
 {
     if (index >= 0) {
-        KFileItem destItem = fileItemModel()->fileItem(index);
+        KFileItem destItem = m_model->fileItem(index);
         if (destItem.isNull()) {
             return;
         }
@@ -255,8 +229,8 @@ void FoldersPanel::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* eve
 
 void FoldersPanel::slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value)
 {
-    if (role == "name") {
-        const KFileItem item = fileItemModel()->fileItem(index);
+    if (role == "text") {
+        const KFileItem item = m_model->fileItem(index);
         const QString newName = value.toString();
         if (!newName.isEmpty() && newName != item.text() && newName != QLatin1String(".") && newName != QLatin1String("..")) {
             KonqOperations::rename(this, item.url(), newName);
@@ -280,7 +254,7 @@ void FoldersPanel::slotLoadingCompleted()
         return;
     }
 
-    const int index = fileItemModel()->index(url());
+    const int index = m_model->index(url());
     updateCurrentItem(index);
     m_updateCurrentItem = false;
 }
@@ -311,18 +285,17 @@ void FoldersPanel::loadTree(const KUrl& url)
         baseUrl.setPath(QString('/'));
     }
 
-    KFileItemModel* model = fileItemModel();
-    if (model->directory() != baseUrl) {
+    if (m_model->directory() != baseUrl) {
         m_updateCurrentItem = true;
-        model->refreshDirectory(baseUrl);
+        m_model->refreshDirectory(baseUrl);
     }
 
-    const int index = model->index(url);
+    const int index = m_model->index(url);
     if (index >= 0) {
         updateCurrentItem(index);
     } else {
         m_updateCurrentItem = true;
-        model->expandParentDirectories(url);
+        m_model->expandParentDirectories(url);
         // slotLoadingCompleted() will be invoked after the model has
         // expanded the url
     }
@@ -338,9 +311,4 @@ void FoldersPanel::updateCurrentItem(int index)
     m_controller->view()->scrollToItem(index);
 }
 
-KFileItemModel* FoldersPanel::fileItemModel() const
-{
-    return static_cast<KFileItemModel*>(m_controller->model());
-}
-
 #include "folderspanel.moc"
index 10a30d1f7cb8f1ebff8999d7de086cc5d840e638..b21ecabad3db7ca08f7c1bc9b87606d2a516ebf1 100644 (file)
@@ -96,11 +96,10 @@ private:
      */
     void updateCurrentItem(int index);
 
-    KFileItemModel* fileItemModel() const;
-
 private:
     bool m_updateCurrentItem;
     KItemListController* m_controller;
+    KFileItemModel* m_model;
 };
 
 #endif // FOLDERSPANEL_H
index 902c436cf62e82b05434f431228703453d67c8dc..4ac82276005cbb7fda9aecb1cdbc01916fbfaf10 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Peter Penz <peter.penz19@gmail.com>             *
+ *   Copyright (C) 2008-2012 by Peter Penz <peter.penz19@gmail.com>        *
  *   Copyright (C) 2010 by Christian Muehlhaeuser <muesli@gmail.com>       *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
 
 #include "placespanel.h"
 
-#include <KFileItem>
-#include <konq_operations.h>
+#include <KIcon>
+#include <kitemviews/kitemlistcontainer.h>
+#include <kitemviews/kitemlistcontroller.h>
+#include <kitemviews/kstandarditem.h>
+#include <kitemviews/kstandarditemlistview.h>
+#include <kitemviews/kstandarditemmodel.h>
 #include <views/draganddrophelper.h>
+#include <QVBoxLayout>
+#include <QShowEvent>
 
 PlacesPanel::PlacesPanel(QWidget* parent) :
-    KFilePlacesView(parent),
-    m_mouseButtons(Qt::NoButton)
+    Panel(parent),
+    m_controller(0),
+    m_model(0)
 {
-    setDropOnPlaceEnabled(true);
-    connect(this, SIGNAL(urlsDropped(KUrl,QDropEvent*,QWidget*)),
-            this, SLOT(slotUrlsDropped(KUrl,QDropEvent*,QWidget*)));
-    connect(this, SIGNAL(urlChanged(KUrl)),
-            this, SLOT(emitExtendedUrlChangedSignal(KUrl)));
 }
 
 PlacesPanel::~PlacesPanel()
 {
 }
 
-void PlacesPanel::mousePressEvent(QMouseEvent* event)
+bool PlacesPanel::urlChanged()
 {
-    m_mouseButtons = event->buttons();
-    KFilePlacesView::mousePressEvent(event);
+    return true;
 }
 
-void PlacesPanel::slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget* parent)
+void PlacesPanel::showEvent(QShowEvent* event)
 {
-    Q_UNUSED(parent);
-    DragAndDropHelper::dropUrls(KFileItem(), dest, event);
+    if (event->spontaneous()) {
+        Panel::showEvent(event);
+        return;
+    }
+
+    if (!m_controller) {
+        // Postpone the creating of the controller to the first show event.
+        // This assures that no performance and memory overhead is given when the folders panel is not
+        // used at all and stays invisible.
+        KStandardItemListView* view = new KStandardItemListView();
+        m_model = new KStandardItemModel(this);
+        m_model->appendItem(new KStandardItem("Temporary"));
+        m_model->appendItem(new KStandardItem("out of"));
+        m_model->appendItem(new KStandardItem("order. Press"));
+        m_model->appendItem(new KStandardItem("F9 and use"));
+        m_model->appendItem(new KStandardItem("the left icon"));
+        m_model->appendItem(new KStandardItem("of the location"));
+        m_model->appendItem(new KStandardItem("bar instead."));
+
+        m_controller = new KItemListController(m_model, view, this);
+
+        KItemListContainer* container = new KItemListContainer(m_controller, this);
+        container->setEnabledFrame(false);
+
+        QVBoxLayout* layout = new QVBoxLayout(this);
+        layout->setMargin(0);
+        layout->addWidget(container);
+    }
+
+    Panel::showEvent(event);
 }
 
-void PlacesPanel::emitExtendedUrlChangedSignal(const KUrl& url)
+void PlacesPanel::slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget* parent)
 {
-    emit urlChanged(url, m_mouseButtons);
+    Q_UNUSED(parent);
+    DragAndDropHelper::dropUrls(KFileItem(), dest, event);
 }
 
 #include "placespanel.moc"
index 903f2cadbad1871843b81d490c9697f7d1d7c1b3..1c46cd57de238c84b87b36cbae7d6a27f18b89cc 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2008 by Peter Penz <peter.penz19@gmail.com>             *
+ *   Copyright (C) 2008-2012 by Peter Penz <peter.penz19@gmail.com>        *
  *   Copyright (C) 2010 by Christian Muehlhaeuser <muesli@gmail.com>       *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
 #ifndef PLACESPANEL_H
 #define PLACESPANEL_H
 
-#include <kfileplacesview.h>
+#include <panels/panel.h>
+
+class KItemListController;
+class KStandardItemModel;
 
 /**
  * @brief Combines bookmarks and mounted devices as list.
  */
-class PlacesPanel : public KFilePlacesView
+class PlacesPanel : public Panel
 {
     Q_OBJECT
 
@@ -34,18 +37,16 @@ public:
     PlacesPanel(QWidget* parent);
     virtual ~PlacesPanel();
 
-signals:
-    void urlChanged(const KUrl& url, Qt::MouseButtons buttons);
-
 protected:
-    virtual void mousePressEvent(QMouseEvent* event);
+    virtual bool urlChanged();
+    virtual void showEvent(QShowEvent* event);
 
 private slots:
     void slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget* parent);
-    void emitExtendedUrlChangedSignal(const KUrl& url);
 
 private:
-    Qt::MouseButtons m_mouseButtons;
+    KItemListController* m_controller;
+    KStandardItemModel* m_model;
 };
 
 #endif // PLACESPANEL_H
index 20461a394eef5a17c07f5c6ea4e141de23bf6135..a3af275ea2cdb8360675c96da3ad2bb1eda86048 100644 (file)
@@ -297,7 +297,7 @@ void ViewPropertiesDialog::configureAdditionalInfo()
         // makes no sense and leads to a usability problem as no viewport area is available
         // anymore. Hence as fallback provide at least a size and date column.
         visibleRoles.clear();
-        visibleRoles.append("name");
+        visibleRoles.append("text");
         visibleRoles.append("size");
         visibleRoles.append("date");
         m_viewProps->setVisibleRoles(visibleRoles);
index 9eee50d44197801ce85e1d3e18829e152416479f..7b56957d41e860ef228041318c56fa465bb1ed43 100644 (file)
@@ -114,13 +114,13 @@ void KFileItemModelTest::testDefaultRoles()
 {
     const QSet<QByteArray> roles = m_model->roles();
     QCOMPARE(roles.count(), 2);
-    QVERIFY(roles.contains("name"));
+    QVERIFY(roles.contains("text"));
     QVERIFY(roles.contains("isDir"));
 }
 
 void KFileItemModelTest::testDefaultSortRole()
 {
-    QCOMPARE(m_model->sortRole(), QByteArray("name"));
+    QCOMPARE(m_model->sortRole(), QByteArray("text"));
 
     QStringList files;
     files << "c.txt" << "a.txt" << "b.txt";
@@ -131,9 +131,9 @@ void KFileItemModelTest::testDefaultSortRole()
     QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
 
     QCOMPARE(m_model->count(), 3);
-    QCOMPARE(m_model->data(0)["name"].toString(), QString("a.txt"));
-    QCOMPARE(m_model->data(1)["name"].toString(), QString("b.txt"));
-    QCOMPARE(m_model->data(2)["name"].toString(), QString("c.txt"));
+    QCOMPARE(m_model->data(0)["text"].toString(), QString("a.txt"));
+    QCOMPARE(m_model->data(1)["text"].toString(), QString("b.txt"));
+    QCOMPARE(m_model->data(2)["text"].toString(), QString("c.txt"));
 }
 
 void KFileItemModelTest::testDefaultGroupedSorting()
@@ -269,7 +269,7 @@ void KFileItemModelTest::testSetDataWithModifiedSortRole()
 
     // Changing the value of a sort-role must result in
     // a reordering of the items.
-    QCOMPARE(m_model->sortRole(), QByteArray("name"));
+    QCOMPARE(m_model->sortRole(), QByteArray("text"));
 
     QStringList files;
     files << "a.txt" << "b.txt" << "c.txt";
@@ -572,7 +572,7 @@ void KFileItemModelTest::testSorting()
     QDateTime now = QDateTime::currentDateTime();
 
     QSet<QByteArray> roles;
-    roles.insert("name");
+    roles.insert("text");
     roles.insert("isExpanded");
     roles.insert("isExpandable");
     roles.insert("expandedParentsCount");
@@ -601,7 +601,7 @@ void KFileItemModelTest::testSorting()
     QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
 
     // Default: Sort by Name, ascending
-    QCOMPARE(m_model->sortRole(), QByteArray("name"));
+    QCOMPARE(m_model->sortRole(), QByteArray("text"));
     QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder);
     QVERIFY(m_model->sortDirectoriesFirst());
     QVERIFY(!m_model->showHiddenFiles());
@@ -611,7 +611,7 @@ void KFileItemModelTest::testSorting()
 
     // Sort by Name, ascending, 'Sort Folders First' disabled
     m_model->setSortDirectoriesFirst(false);
-    QCOMPARE(m_model->sortRole(), QByteArray("name"));
+    QCOMPARE(m_model->sortRole(), QByteArray("text"));
     QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder);
     QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "c" << "c-1" << "c-2" << "c-3" << "d" << "e");
     QCOMPARE(spyItemsMoved.count(), 1);
@@ -620,7 +620,7 @@ void KFileItemModelTest::testSorting()
     // Sort by Name, descending
     m_model->setSortDirectoriesFirst(true);
     m_model->setSortOrder(Qt::DescendingOrder);
-    QCOMPARE(m_model->sortRole(), QByteArray("name"));
+    QCOMPARE(m_model->sortRole(), QByteArray("text"));
     QCOMPARE(m_model->sortOrder(), Qt::DescendingOrder);
     QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "e" << "d" << "b" << "a");
     QCOMPARE(spyItemsMoved.count(), 2);
@@ -654,7 +654,7 @@ void KFileItemModelTest::testSorting()
     QCOMPARE(spyItemsMoved.takeFirst().at(1).value<QList<int> >(), QList<int>() << 2 << 4 << 5 << 3 << 0 << 1 << 6 << 7);
 
     // Sort by Name, ascending, 'Sort Folders First' disabled
-    m_model->setSortRole("name");
+    m_model->setSortRole("text");
     QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder);
     QVERIFY(!m_model->sortDirectoriesFirst());
     QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "c" << "c-1" << "c-2" << "c-3" << "d" << "e");
@@ -800,7 +800,7 @@ QStringList KFileItemModelTest::itemsInModel() const
 {
     QStringList items;
     for (int i = 0; i < m_model->count(); i++) {
-        items << m_model->data(i).value("name").toString();
+        items << m_model->data(i).value("text").toString();
     }
     return items;
 }
index 3b67e7b50fd8dad5e76dcc78d3a5fe65d873957e..47b2b8b7593a344cfb63345a5e358b982ab697b8 100644 (file)
@@ -33,7 +33,7 @@ namespace {
     const int DefaultTimeout = 2000;
 };
 
-Q_DECLARE_METATYPE(KFileItemListView::Layout);
+Q_DECLARE_METATYPE(KFileItemListView::ItemLayout);
 Q_DECLARE_METATYPE(Qt::Orientation);
 Q_DECLARE_METATYPE(KItemListController::SelectionBehavior);
 Q_DECLARE_METATYPE(QSet<int>);
@@ -79,15 +79,13 @@ void KItemListControllerTest::initTestCase()
 
     m_testDir = new TestDir();
     m_model = new KFileItemModel();
-    m_container = new KItemListContainer();
+    m_view = new KFileItemListView();
+    m_controller = new KItemListController(m_model, m_view, this);
+    m_container = new KItemListContainer(m_controller);
     m_controller = m_container->controller();
     m_controller->setSelectionBehavior(KItemListController::MultiSelection);
     m_selectionManager = m_controller->selectionManager();
 
-    m_view = new KFileItemListView();
-    m_controller->setView(m_view);
-    m_controller->setModel(m_model);
-
     QStringList files;
     files
         << "a1" << "a2" << "a3"
@@ -106,15 +104,8 @@ void KItemListControllerTest::initTestCase()
 
 void KItemListControllerTest::cleanupTestCase()
 {
-    delete m_view;
-    m_view = 0;
-
     delete m_container;
     m_container = 0;
-    m_controller = 0;
-
-    delete m_model;
-    m_model = 0;
 
     delete m_testDir;
     m_testDir = 0;
@@ -187,15 +178,15 @@ Q_DECLARE_METATYPE(QList<keyPressViewStatePair>);
  */
 void KItemListControllerTest::testKeyboardNavigation_data()
 {
-    QTest::addColumn<KFileItemListView::Layout>("layout");
+    QTest::addColumn<KFileItemListView::ItemLayout>("layout");
     QTest::addColumn<Qt::Orientation>("scrollOrientation");
     QTest::addColumn<int>("columnCount");
     QTest::addColumn<KItemListController::SelectionBehavior>("selectionBehavior");
     QTest::addColumn<bool>("groupingEnabled");
     QTest::addColumn<QList<QPair<KeyPress, ViewState> > >("testList");
 
-    QList<KFileItemListView::Layout> layoutList;
-    QHash<KFileItemListView::Layout, QString> layoutNames;
+    QList<KFileItemListView::ItemLayout> layoutList;
+    QHash<KFileItemListView::ItemLayout, QString> layoutNames;
     layoutList.append(KFileItemListView::IconsLayout);
     layoutNames[KFileItemListView::IconsLayout] = "Icons";
     layoutList.append(KFileItemListView::CompactLayout);
@@ -219,7 +210,7 @@ void KItemListControllerTest::testKeyboardNavigation_data()
     groupingEnabledList.append(true);
     groupingEnabledNames[true] = "grouping enabled";
 
-    foreach (KFileItemListView::Layout layout, layoutList) {
+    foreach (KFileItemListView::ItemLayout layout, layoutList) {
         // The following settings depend on the layout.
         // Note that 'columns' are actually 'rows' in
         // Compact layout.
@@ -443,7 +434,7 @@ void KItemListControllerTest::testKeyboardNavigation_data()
  */
 void KItemListControllerTest::testKeyboardNavigation()
 {
-    QFETCH(KFileItemListView::Layout, layout);
+    QFETCH(KFileItemListView::ItemLayout, layout);
     QFETCH(Qt::Orientation, scrollOrientation);
     QFETCH(int, columnCount);
     QFETCH(KItemListController::SelectionBehavior, selectionBehavior);
index e730c47b85f636552134699a6eb9f8232d289506..43030c63405d29ae644ec6e66653bded34d79132 100644 (file)
@@ -26,8 +26,9 @@
 
 #include <KDebug>
 
-DolphinFileItemListWidget::DolphinFileItemListWidget(QGraphicsItem* parent) :
-    KFileItemListWidget(parent)
+DolphinFileItemListWidget::DolphinFileItemListWidget(KItemListWidgetInformant* informant,
+                                                     QGraphicsItem* parent) :
+    KFileItemListWidget(informant, parent)
 {
 }
 
index 87ed0333bccde23aa2b8d7edd0b1342a800877da..b9de6fb194e45dab5e440edad41fc922172f45b5 100644 (file)
@@ -36,7 +36,7 @@ class LIBDOLPHINPRIVATE_EXPORT DolphinFileItemListWidget : public KFileItemListW
     Q_OBJECT
 
 public:
-    DolphinFileItemListWidget(QGraphicsItem* parent);
+    DolphinFileItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent);
     virtual ~DolphinFileItemListWidget();
 
 protected:
similarity index 57%
rename from src/views/dolphinitemlistcontainer.cpp
rename to src/views/dolphinitemlistview.cpp
index 88e10d8a3a9b2d9bc4861ce7adce8dbbd0aab322..156ca204f2edcc56ee7d5786666cd14cf2486367 100644 (file)
  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
  ***************************************************************************/
 
-#include "dolphinitemlistcontainer.h"
+#include "dolphinitemlistview.h"
 
 #include "dolphin_generalsettings.h"
 #include "dolphin_iconsmodesettings.h"
 #include "dolphin_detailsmodesettings.h"
 #include "dolphin_compactmodesettings.h"
-
 #include "dolphinfileitemlistwidget.h"
 
 #include <kitemviews/kfileitemlistview.h>
 #include "zoomlevelinfo.h"
 
 
-DolphinItemListContainer::DolphinItemListContainer(QWidget* parent) :
-    KItemListContainer(parent),
-    m_zoomLevel(0),
-    m_fileItemListView(0)
+DolphinItemListView::DolphinItemListView(QGraphicsWidget* parent) :
+    KFileItemListView(parent),
+    m_zoomLevel(0)
 {
-    controller()->setModel(new KFileItemModel(this));
-
-    m_fileItemListView = new KFileItemListView();
-    controller()->setView(m_fileItemListView);
-
-    m_fileItemListView->setWidgetCreator(new KItemListWidgetCreator<DolphinFileItemListWidget>());
-    m_fileItemListView->setEnabledSelectionToggles(GeneralSettings::showSelectionToggle());
-    m_fileItemListView->setEnlargeSmallPreviews(GeneralSettings::enlargeSmallPreviews());
-
-    updateAutoActivationDelay();
     updateFont();
     updateGridSize();
 }
 
-DolphinItemListContainer::~DolphinItemListContainer()
+DolphinItemListView::~DolphinItemListView()
 {
     writeSettings();
-
-    controller()->setView(0);
-    delete m_fileItemListView;
-    m_fileItemListView = 0;
-}
-
-void DolphinItemListContainer::setPreviewsShown(bool show)
-{
-    beginTransaction();
-    m_fileItemListView->setPreviewsShown(show);
-    updateGridSize();
-    endTransaction();
-}
-
-bool DolphinItemListContainer::previewsShown() const
-{
-    return m_fileItemListView->previewsShown();
-}
-
-void DolphinItemListContainer::setVisibleRoles(const QList<QByteArray>& roles)
-{
-    m_fileItemListView->setVisibleRoles(roles);
-    updateGridSize();
-}
-
-QList<QByteArray> DolphinItemListContainer::visibleRoles() const
-{
-    return m_fileItemListView->visibleRoles();
 }
 
-void DolphinItemListContainer::setZoomLevel(int level)
+void DolphinItemListView::setZoomLevel(int level)
 {
     if (level < ZoomLevelInfo::minimumLevel()) {
         level = ZoomLevelInfo::minimumLevel();
@@ -116,76 +76,24 @@ void DolphinItemListContainer::setZoomLevel(int level)
     updateGridSize();
 }
 
-int DolphinItemListContainer::zoomLevel() const
+int DolphinItemListView::zoomLevel() const
 {
     return m_zoomLevel;
 }
 
-void DolphinItemListContainer::setItemLayout(KFileItemListView::Layout layout)
-{
-    if (layout == itemLayout()) {
-        return;
-    }
-
-    beginTransaction();
-    m_fileItemListView->setItemLayout(layout);
-
-    switch (layout) {
-    case KFileItemListView::IconsLayout:
-        m_fileItemListView->setScrollOrientation(Qt::Vertical);
-        m_fileItemListView->setHeaderVisible(false);
-        m_fileItemListView->setSupportsItemExpanding(false);
-        break;
-    case KFileItemListView::DetailsLayout:
-        m_fileItemListView->setScrollOrientation(Qt::Vertical);
-        m_fileItemListView->setHeaderVisible(true);
-        m_fileItemListView->setSupportsItemExpanding(DetailsModeSettings::expandableFolders());
-
-        break;
-    case KFileItemListView::CompactLayout:
-        m_fileItemListView->setScrollOrientation(Qt::Horizontal);
-        m_fileItemListView->setHeaderVisible(false);
-        m_fileItemListView->setSupportsItemExpanding(false);
-        break;
-    default:
-        Q_ASSERT(false);
-        break;
-    }
-
-    updateFont();
-    updateGridSize();
-    endTransaction();
-}
-
-KFileItemListView::Layout DolphinItemListContainer::itemLayout() const
-{
-    return m_fileItemListView->itemLayout();
-}
-
-void DolphinItemListContainer::beginTransaction()
-{
-    m_fileItemListView->beginTransaction();
-}
-
-void DolphinItemListContainer::endTransaction()
-{
-    m_fileItemListView->endTransaction();
-}
-
-void DolphinItemListContainer::readSettings()
+void DolphinItemListView::readSettings()
 {
     ViewModeSettings settings(viewMode());
     settings.readConfig();
 
     beginTransaction();
 
-    m_fileItemListView->setEnabledSelectionToggles(GeneralSettings::showSelectionToggle());
+    setEnabledSelectionToggles(GeneralSettings::showSelectionToggle());
 
     const bool expandableFolders = (itemLayout() && KFileItemListView::DetailsLayout) &&
                                    DetailsModeSettings::expandableFolders();
-    m_fileItemListView->setSupportsItemExpanding(expandableFolders);
+    setSupportsItemExpanding(expandableFolders);
 
-    updateAutoActivationDelay();
     updateFont();
     updateGridSize();
 
@@ -194,26 +102,59 @@ void DolphinItemListContainer::readSettings()
                                                        << "directorythumbnail"
                                                        << "imagethumbnail"
                                                        << "jpegthumbnail");
-    m_fileItemListView->setEnabledPlugins(plugins);
+    setEnabledPlugins(plugins);
 
     endTransaction();
 }
 
-void DolphinItemListContainer::writeSettings()
+void DolphinItemListView::writeSettings()
 {
     IconsModeSettings::self()->writeConfig();
     CompactModeSettings::self()->writeConfig();
     DetailsModeSettings::self()->writeConfig();
 }
 
-void DolphinItemListContainer::updateGridSize()
+KItemListWidgetCreatorBase* DolphinItemListView::defaultWidgetCreator() const
+{
+    return new KItemListWidgetCreator<DolphinFileItemListWidget>();
+}
+
+void DolphinItemListView::onItemLayoutChanged(ItemLayout current, ItemLayout previous)
+{
+    Q_UNUSED(previous);
+
+    if (current == DetailsLayout) {
+        setSupportsItemExpanding(DetailsModeSettings::expandableFolders());
+        setHeaderVisible(true);
+    } else {
+        setHeaderVisible(false);
+    }
+
+    updateFont();
+    updateGridSize();
+}
+
+void DolphinItemListView::onPreviewsShownChanged(bool shown)
+{
+    Q_UNUSED(shown);
+    updateGridSize();
+}
+
+void DolphinItemListView::onVisibleRolesChanged(const QList<QByteArray>& current,
+                                                const QList<QByteArray>& previous)
+{
+    KFileItemListView::onVisibleRolesChanged(current, previous);
+    updateGridSize();
+}
+
+void DolphinItemListView::updateGridSize()
 {
     const ViewModeSettings settings(viewMode());
 
     // Calculate the size of the icon
     const int iconSize = previewsShown() ? settings.previewSize() : settings.iconSize();
     m_zoomLevel = ZoomLevelInfo::zoomLevelForIconSize(QSize(iconSize, iconSize));
-    KItemListStyleOption styleOption = m_fileItemListView->styleOption();
+    KItemListStyleOption option = styleOption();
 
     const int padding = 2;
     int horizontalMargin = 0;
@@ -241,13 +182,13 @@ void DolphinItemListContainer::updateGridSize()
             itemWidth = iconSize + padding * 2;
         }
 
-        itemHeight = padding * 3 + iconSize + styleOption.fontMetrics.lineSpacing();
+        itemHeight = padding * 3 + iconSize + option.fontMetrics.lineSpacing();
         if (IconsModeSettings::maximumTextLines() > 0) {
             // A restriction is given for the maximum number of textlines (0 means
             // having no restriction)
-            const int additionalInfoCount = m_fileItemListView->visibleRoles().count() - 1;
+            const int additionalInfoCount = visibleRoles().count() - 1;
             const int maxAdditionalLines = additionalInfoCount + IconsModeSettings::maximumTextLines();
-            maxTextSize.rheight() = styleOption.fontMetrics.lineSpacing() * maxAdditionalLines;
+            maxTextSize.rheight() = option.fontMetrics.lineSpacing() * maxAdditionalLines;
         }
 
         horizontalMargin = 4;
@@ -255,14 +196,14 @@ void DolphinItemListContainer::updateGridSize()
         break;
     }
     case KFileItemListView::CompactLayout: {
-        itemWidth = padding * 4 + iconSize + styleOption.fontMetrics.height() * 5;
-        const int textLinesCount = m_fileItemListView->visibleRoles().count();
-        itemHeight = padding * 2 + qMax(iconSize, textLinesCount * styleOption.fontMetrics.lineSpacing());
+        itemWidth = padding * 4 + iconSize + option.fontMetrics.height() * 5;
+        const int textLinesCount = visibleRoles().count();
+        itemHeight = padding * 2 + qMax(iconSize, textLinesCount * option.fontMetrics.lineSpacing());
 
         if (CompactModeSettings::maximumTextWidthIndex() > 0) {
             // A restriction is given for the maximum width of the text (0 means
             // having no restriction)
-            maxTextSize.rwidth() = styleOption.fontMetrics.height() * 10 *
+            maxTextSize.rwidth() = option.fontMetrics.height() * 10 *
                                    CompactModeSettings::maximumTextWidthIndex();
         }
 
@@ -271,7 +212,7 @@ void DolphinItemListContainer::updateGridSize()
     }
     case KFileItemListView::DetailsLayout: {
         itemWidth = -1;
-        itemHeight = padding * 2 + qMax(iconSize, styleOption.fontMetrics.lineSpacing());
+        itemHeight = padding * 2 + qMax(iconSize, option.fontMetrics.lineSpacing());
         break;
     }
     default:
@@ -282,20 +223,20 @@ void DolphinItemListContainer::updateGridSize()
     }
 
     // Apply the calculated values
-    styleOption.padding = padding;
-    styleOption.horizontalMargin = horizontalMargin;
-    styleOption.verticalMargin = verticalMargin;
-    styleOption.iconSize = iconSize;
-    styleOption.maxTextSize = maxTextSize;
-    m_fileItemListView->beginTransaction();
-    m_fileItemListView->setStyleOption(styleOption);
-    m_fileItemListView->setItemSize(QSizeF(itemWidth, itemHeight));
-    m_fileItemListView->endTransaction();
+    option.padding = padding;
+    option.horizontalMargin = horizontalMargin;
+    option.verticalMargin = verticalMargin;
+    option.iconSize = iconSize;
+    option.maxTextSize = maxTextSize;
+    beginTransaction();
+    setStyleOption(option);
+    setItemSize(QSizeF(itemWidth, itemHeight));
+    endTransaction();
 }
 
-void DolphinItemListContainer::updateFont()
+void DolphinItemListView::updateFont()
 {
-    KItemListStyleOption styleOption = m_fileItemListView->styleOption();
+    KItemListStyleOption option = styleOption();
 
     const ViewModeSettings settings(viewMode());
 
@@ -304,19 +245,13 @@ void DolphinItemListContainer::updateFont()
     font.setWeight(settings.fontWeight());
     font.setPointSizeF(settings.fontSize());
 
-    styleOption.font = font;
-    styleOption.fontMetrics = QFontMetrics(font);
-
-    m_fileItemListView->setStyleOption(styleOption);
-}
+    option.font = font;
+    option.fontMetrics = QFontMetrics(font);
 
-void DolphinItemListContainer::updateAutoActivationDelay()
-{
-    const int delay = GeneralSettings::autoExpandFolders() ? 750 : -1;
-    controller()->setAutoActivationDelay(delay);
+    setStyleOption(option);
 }
 
-ViewModeSettings::ViewMode DolphinItemListContainer::viewMode() const
+ViewModeSettings::ViewMode DolphinItemListView::viewMode() const
 {
     ViewModeSettings::ViewMode mode;
 
@@ -332,4 +267,4 @@ ViewModeSettings::ViewMode DolphinItemListContainer::viewMode() const
     return mode;
 }
 
-#include "dolphinitemlistcontainer.moc"
+#include "dolphinitemlistview.moc"
similarity index 59%
rename from src/views/dolphinitemlistcontainer.h
rename to src/views/dolphinitemlistview.h
index f3505b663687e5fc21e148054c1fa596a669da44..c2d86cc5e21efc0344b6662465e00e8fc65cda42 100644 (file)
  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
  ***************************************************************************/
 
-#ifndef DOLPHINITEMLISTCONTAINER_H
-#define DOLPHINITEMLISTCONTAINER_H
+#ifndef DOLPHINITEMLISTVIEW_H
+#define DOLPHINITEMLISTVIEW_H
 
 #include <kitemviews/kfileitemlistview.h>
-#include <kitemviews/kitemlistcontainer.h>
 #include <settings/viewmodes/viewmodesettings.h>
 
 #include <libdolphin_export.h>
 class KFileItemListView;
 
 /**
- * @brief Extends KItemListContainer by Dolphin specific properties.
+ * @brief Dolphin specific view-implementation.
  *
- * The view and model for KFileItems are created automatically when
- * instantating KItemListContainer.
- *
- * The Dolphin settings of the icons-, compact- and details-view are
- * converted internally to properties that can be used to configure e.g.
- * the item-size and visible roles of the KItemListView.
+ * Offers zoom-level support and takes care for translating
+ * the view-properties into the corresponding KItemListView
+ * properties.
  */
-class LIBDOLPHINPRIVATE_EXPORT DolphinItemListContainer : public KItemListContainer
+class LIBDOLPHINPRIVATE_EXPORT DolphinItemListView : public KFileItemListView
 {
     Q_OBJECT
 
 public:
-    explicit DolphinItemListContainer(QWidget* parent = 0);
-
-    virtual ~DolphinItemListContainer();
-
-    void setPreviewsShown(bool show);
-    bool previewsShown() const;
-
-    void setVisibleRoles(const QList<QByteArray>& roles);
-    QList<QByteArray> visibleRoles() const;
+    explicit DolphinItemListView(QGraphicsWidget* parent = 0);
+    virtual ~DolphinItemListView();
 
     void setZoomLevel(int level);
     int zoomLevel() const;
 
-    void setItemLayout(KFileItemListView::Layout layout);
-    KFileItemListView::Layout itemLayout() const;
-
-    void beginTransaction();
-    void endTransaction();
-
     void readSettings();
     void writeSettings();
 
+protected:
+    virtual KItemListWidgetCreatorBase* defaultWidgetCreator() const;
+    virtual void onItemLayoutChanged(ItemLayout current, ItemLayout previous);
+    virtual void onPreviewsShownChanged(bool shown);
+    virtual void onVisibleRolesChanged(const QList<QByteArray>& current,
+                                       const QList<QByteArray>& previous);
+
 private:
     void updateGridSize();
     void updateFont();
 
-    /**
-     * Updates the auto activation delay of the itemlist controller
-     * dependent on the 'autoExpand' setting from the general settings.
-     */
-    void updateAutoActivationDelay();
-
     ViewModeSettings::ViewMode viewMode() const;
 
 private:
     int m_zoomLevel;
-    KFileItemListView* m_fileItemListView;
 };
 
 #endif
index 7494ac5e6ecb02ed922bc5224196e1f0850ece78..12932c7099d886c0ee110f4fd2a6c823cbbbe65c 100644 (file)
@@ -42,6 +42,7 @@
 #include <KLocale>
 #include <kitemviews/kfileitemmodel.h>
 #include <kitemviews/kfileitemlistview.h>
+#include <kitemviews/kitemlistcontainer.h>
 #include <kitemviews/kitemlistheader.h>
 #include <kitemviews/kitemlistselectionmanager.h>
 #include <kitemviews/kitemlistview.h>
@@ -62,7 +63,7 @@
 #include "dolphinnewfilemenuobserver.h"
 #include "dolphin_detailsmodesettings.h"
 #include "dolphin_generalsettings.h"
-#include "dolphinitemlistcontainer.h"
+#include "dolphinitemlistview.h"
 #include "draganddrophelper.h"
 #include "renamedialog.h"
 #include "versioncontrol/versioncontrolobserver.h"
@@ -90,6 +91,8 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
     m_mode(DolphinView::IconsView),
     m_visibleRoles(),
     m_topLayout(0),
+    m_model(0),
+    m_view(0),
     m_container(0),
     m_toolTipManager(0),
     m_selectionChangedTimer(0),
@@ -115,14 +118,23 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
     connect(m_selectionChangedTimer, SIGNAL(timeout()),
             this, SLOT(emitSelectionChangedSignal()));
 
-    m_container = new DolphinItemListContainer(this);
-    m_container->setVisibleRoles(QList<QByteArray>() << "name");
+    m_model = new KFileItemModel(this);
+    m_view = new DolphinItemListView();
+    m_view->setEnabledSelectionToggles(GeneralSettings::showSelectionToggle());
+    m_view->setEnlargeSmallPreviews(GeneralSettings::enlargeSmallPreviews());
+    m_view->setVisibleRoles(QList<QByteArray>() << "text");
+    applyModeToView();
+
+    KItemListController* controller = new KItemListController(m_model, m_view, this);
+    const int delay = GeneralSettings::autoExpandFolders() ? 750 : -1;
+    controller->setAutoActivationDelay(delay);
+
+    m_container = new KItemListContainer(controller, this);
     m_container->installEventFilter(this);
     setFocusProxy(m_container);
     connect(m_container->horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hideToolTip()));
     connect(m_container->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hideToolTip()));
 
-    KItemListController* controller = m_container->controller();
     controller->setSelectionBehavior(KItemListController::MultiSelection);
     connect(controller, SIGNAL(itemActivated(int)), this, SLOT(slotItemActivated(int)));
     connect(controller, SIGNAL(itemsActivated(QSet<int>)), this, SLOT(slotItemsActivated(QSet<int>)));
@@ -136,30 +148,28 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
     connect(controller, SIGNAL(itemDropEvent(int,QGraphicsSceneDragDropEvent*)), this, SLOT(slotItemDropEvent(int,QGraphicsSceneDragDropEvent*)));
     connect(controller, SIGNAL(modelChanged(KItemModelBase*,KItemModelBase*)), this, SLOT(slotModelChanged(KItemModelBase*,KItemModelBase*)));
 
-    KFileItemModel* model = fileItemModel();
-    connect(model, SIGNAL(directoryLoadingStarted()),       this, SLOT(slotDirectoryLoadingStarted()));
-    connect(model, SIGNAL(directoryLoadingCompleted()),     this, SLOT(slotDirectoryLoadingCompleted()));
-    connect(model, SIGNAL(directoryLoadingProgress(int)),   this, SIGNAL(directoryLoadingProgress(int)));
-    connect(model, SIGNAL(directorySortingProgress(int)),   this, SIGNAL(directorySortingProgress(int)));
-    connect(model, SIGNAL(itemsChanged(KItemRangeList,QSet<QByteArray>)),
+    connect(m_model, SIGNAL(directoryLoadingStarted()),       this, SLOT(slotDirectoryLoadingStarted()));
+    connect(m_model, SIGNAL(directoryLoadingCompleted()),     this, SLOT(slotDirectoryLoadingCompleted()));
+    connect(m_model, SIGNAL(directoryLoadingProgress(int)),   this, SIGNAL(directoryLoadingProgress(int)));
+    connect(m_model, SIGNAL(directorySortingProgress(int)),   this, SIGNAL(directorySortingProgress(int)));
+    connect(m_model, SIGNAL(itemsChanged(KItemRangeList,QSet<QByteArray>)),
             this, SLOT(slotItemsChanged()));
-    connect(model, SIGNAL(itemsRemoved(KItemRangeList)),    this, SIGNAL(itemCountChanged()));
-    connect(model, SIGNAL(itemsInserted(KItemRangeList)),   this, SIGNAL(itemCountChanged()));
-    connect(model, SIGNAL(infoMessage(QString)),            this, SIGNAL(infoMessage(QString)));
-    connect(model, SIGNAL(errorMessage(QString)),           this, SIGNAL(errorMessage(QString)));
-    connect(model, SIGNAL(directoryRedirection(KUrl,KUrl)), this, SLOT(slotDirectoryRedirection(KUrl,KUrl)));
-
-    KItemListView* view = controller->view();
-    view->installEventFilter(this);
-    connect(view, SIGNAL(sortOrderChanged(Qt::SortOrder,Qt::SortOrder)),
+    connect(m_model, SIGNAL(itemsRemoved(KItemRangeList)),    this, SIGNAL(itemCountChanged()));
+    connect(m_model, SIGNAL(itemsInserted(KItemRangeList)),   this, SIGNAL(itemCountChanged()));
+    connect(m_model, SIGNAL(infoMessage(QString)),            this, SIGNAL(infoMessage(QString)));
+    connect(m_model, SIGNAL(errorMessage(QString)),           this, SIGNAL(errorMessage(QString)));
+    connect(m_model, SIGNAL(directoryRedirection(KUrl,KUrl)), this, SLOT(slotDirectoryRedirection(KUrl,KUrl)));
+
+    m_view->installEventFilter(this);
+    connect(m_view, SIGNAL(sortOrderChanged(Qt::SortOrder,Qt::SortOrder)),
             this, SLOT(slotSortOrderChangedByHeader(Qt::SortOrder,Qt::SortOrder)));
-    connect(view, SIGNAL(sortRoleChanged(QByteArray,QByteArray)),
+    connect(m_view, SIGNAL(sortRoleChanged(QByteArray,QByteArray)),
             this, SLOT(slotSortRoleChangedByHeader(QByteArray,QByteArray)));
-    connect(view, SIGNAL(visibleRolesChanged(QList<QByteArray>,QList<QByteArray>)),
+    connect(m_view, SIGNAL(visibleRolesChanged(QList<QByteArray>,QList<QByteArray>)),
             this, SLOT(slotVisibleRolesChangedByHeader(QList<QByteArray>,QList<QByteArray>)));
-    connect(view, SIGNAL(roleEditingFinished(int,QByteArray,QVariant)),
+    connect(m_view, SIGNAL(roleEditingFinished(int,QByteArray,QVariant)),
             this, SLOT(slotRoleEditingFinished(int,QByteArray,QVariant)));
-    connect(view->header(), SIGNAL(columnWidthChanged(QByteArray,qreal,qreal)),
+    connect(m_view->header(), SIGNAL(columnWidthChanged(QByteArray,qreal,qreal)),
             this, SLOT(slotHeaderColumnWidthChanged(QByteArray,qreal,qreal)));
 
     KItemListSelectionManager* selectionManager = controller->selectionManager();
@@ -169,7 +179,7 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
     m_toolTipManager = new ToolTipManager(this);
 
     m_versionControlObserver = new VersionControlObserver(this);
-    m_versionControlObserver->setModel(model);
+    m_versionControlObserver->setModel(m_model);
     connect(m_versionControlObserver, SIGNAL(infoMessage(QString)), this, SIGNAL(infoMessage(QString)));
     connect(m_versionControlObserver, SIGNAL(errorMessage(QString)), this, SIGNAL(errorMessage(QString)));
     connect(m_versionControlObserver, SIGNAL(operationCompletedMessage(QString)), this, SIGNAL(operationCompletedMessage(QString)));
@@ -248,19 +258,18 @@ void DolphinView::setPreviewsShown(bool show)
     ViewProperties props(url());
     props.setPreviewsShown(show);
 
-    m_container->setPreviewsShown(show);
+    m_view->setPreviewsShown(show);
     emit previewsShownChanged(show);
 }
 
 bool DolphinView::previewsShown() const
 {
-    return m_container->previewsShown();
+    return m_view->previewsShown();
 }
 
 void DolphinView::setHiddenFilesShown(bool show)
 {
-    KFileItemModel* model = fileItemModel();
-    if (model->showHiddenFiles() == show) {
+    if (m_model->showHiddenFiles() == show) {
         return;
     }
 
@@ -271,13 +280,13 @@ void DolphinView::setHiddenFilesShown(bool show)
     ViewProperties props(url());
     props.setHiddenFilesShown(show);
 
-    model->setShowHiddenFiles(show);
+    m_model->setShowHiddenFiles(show);
     emit hiddenFilesShownChanged(show);
 }
 
 bool DolphinView::hiddenFilesShown() const
 {
-    return fileItemModel()->showHiddenFiles();
+    return m_model->showHiddenFiles();
 }
 
 void DolphinView::setGroupedSorting(bool grouped)
@@ -297,18 +306,17 @@ void DolphinView::setGroupedSorting(bool grouped)
 
 bool DolphinView::groupedSorting() const
 {
-    return fileItemModel()->groupedSorting();
+    return m_model->groupedSorting();
 }
 
 KFileItemList DolphinView::items() const
 {
     KFileItemList list;
-    const KFileItemModel* model = fileItemModel();
-    const int itemCount = model->count();
+    const int itemCount = m_model->count();
     list.reserve(itemCount);
 
     for (int i = 0; i < itemCount; ++i) {
-        list.append(model->fileItem(i));
+        list.append(m_model->fileItem(i));
     }
 
     return list;
@@ -316,12 +324,11 @@ KFileItemList DolphinView::items() const
 
 int DolphinView::itemsCount() const
 {
-    return fileItemModel()->count();
+    return m_model->count();
 }
 
 KFileItemList DolphinView::selectedItems() const
 {
-    const KFileItemModel* model = fileItemModel();
     const KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
     const QSet<int> selectedIndexes = selectionManager->selectedItems();
 
@@ -329,7 +336,7 @@ KFileItemList DolphinView::selectedItems() const
     QSetIterator<int> it(selectedIndexes);
     while (it.hasNext()) {
         const int index = it.next();
-        selectedItems.append(model->fileItem(index));
+        selectedItems.append(m_model->fileItem(index));
     }
     return selectedItems;
 }
@@ -355,11 +362,10 @@ void DolphinView::selectItems(const QRegExp& pattern, bool enabled)
     const KItemListSelectionManager::SelectionMode mode = enabled
                                                         ? KItemListSelectionManager::Select
                                                         : KItemListSelectionManager::Deselect;
-    const KFileItemModel* model = fileItemModel();
     KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
 
-    for (int index = 0; index < model->count(); index++) {
-        const KFileItem item = model->fileItem(index);
+    for (int index = 0; index < m_model->count(); index++) {
+        const KFileItem item = m_model->fileItem(index);
         if (pattern.exactMatch(item.text())) {
             // An alternative approach would be to store the matching items in a QSet<int> and
             // select them in one go after the loop, but we'd need a new function
@@ -373,7 +379,7 @@ void DolphinView::selectItems(const QRegExp& pattern, bool enabled)
 void DolphinView::setZoomLevel(int level)
 {
     const int oldZoomLevel = zoomLevel();
-    m_container->setZoomLevel(level);
+    m_view->setZoomLevel(level);
     if (zoomLevel() != oldZoomLevel) {
         emit zoomLevelChanged(zoomLevel(), oldZoomLevel);
     }
@@ -381,7 +387,7 @@ void DolphinView::setZoomLevel(int level)
 
 int DolphinView::zoomLevel() const
 {
-    return m_container->zoomLevel();
+    return m_view->zoomLevel();
 }
 
 void DolphinView::setSortRole(const QByteArray& role)
@@ -406,8 +412,7 @@ void DolphinView::setSortOrder(Qt::SortOrder order)
 
 Qt::SortOrder DolphinView::sortOrder() const
 {
-    KItemModelBase* model = fileItemModel();
-    return model->sortOrder();
+    return m_model->sortOrder();
 }
 
 void DolphinView::setSortFoldersFirst(bool foldersFirst)
@@ -419,8 +424,7 @@ void DolphinView::setSortFoldersFirst(bool foldersFirst)
 
 bool DolphinView::sortFoldersFirst() const
 {
-    KFileItemModel* model = fileItemModel();
-    return model->sortDirectoriesFirst();
+    return m_model->sortDirectoriesFirst();
 }
 
 void DolphinView::setVisibleRoles(const QList<QByteArray>& roles)
@@ -431,7 +435,7 @@ void DolphinView::setVisibleRoles(const QList<QByteArray>& roles)
     props.setVisibleRoles(roles);
 
     m_visibleRoles = roles;
-    m_container->setVisibleRoles(roles);
+    m_view->setVisibleRoles(roles);
 
     emit visibleRolesChanged(m_visibleRoles, previousRoles);
 }
@@ -460,18 +464,21 @@ void DolphinView::reload()
 
 void DolphinView::stopLoading()
 {
-    fileItemModel()->cancelDirectoryLoading();
+    m_model->cancelDirectoryLoading();
 }
 
 void DolphinView::readSettings()
 {
-    const int oldZoomLevel = m_container->zoomLevel();
+    const int oldZoomLevel = m_view->zoomLevel();
 
     GeneralSettings::self()->readConfig();
-    m_container->readSettings();
+    m_view->readSettings();
     applyViewProperties();
 
-    const int newZoomLevel = m_container->zoomLevel();
+    const int delay = GeneralSettings::autoExpandFolders() ? 750 : -1;
+    m_container->controller()->setAutoActivationDelay(delay);
+
+    const int newZoomLevel = m_view->zoomLevel();
     if (newZoomLevel != oldZoomLevel) {
         emit zoomLevelChanged(newZoomLevel, oldZoomLevel);
     }
@@ -480,17 +487,17 @@ void DolphinView::readSettings()
 void DolphinView::writeSettings()
 {
     GeneralSettings::self()->writeConfig();
-    m_container->writeSettings();
+    m_view->writeSettings();
 }
 
 void DolphinView::setNameFilter(const QString& nameFilter)
 {
-    fileItemModel()->setNameFilter(nameFilter);
+    m_model->setNameFilter(nameFilter);
 }
 
 QString DolphinView::nameFilter() const
 {
-    return fileItemModel()->nameFilter();
+    return m_model->nameFilter();
 }
 
 QString DolphinView::statusBarText() const
@@ -551,7 +558,7 @@ QList<QAction*> DolphinView::versionControlActions(const KFileItemList& items) c
     QList<QAction*> actions;
 
     if (items.isEmpty()) {
-        const KFileItem item = fileItemModel()->rootItem();
+        const KFileItem item = m_model->rootItem();
         actions = m_versionControlObserver->actions(KFileItemList() << item);
     } else {
         actions = m_versionControlObserver->actions(items);
@@ -575,7 +582,7 @@ void DolphinView::setUrl(const KUrl& url)
     // applying the view properties, otherwise expensive operations
     // might be done on the existing items although they get cleared
     // anyhow afterwards by loadDirectory().
-    fileItemModel()->clear();
+    m_model->clear();
     applyViewProperties();
     loadDirectory(url);
 
@@ -585,13 +592,13 @@ void DolphinView::setUrl(const KUrl& url)
 void DolphinView::selectAll()
 {
     KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
-    selectionManager->setSelected(0, fileItemModel()->count());
+    selectionManager->setSelected(0, m_model->count());
 }
 
 void DolphinView::invertSelection()
 {
     KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
-    selectionManager->setSelected(0, fileItemModel()->count(), KItemListSelectionManager::Toggle);
+    selectionManager->setSelected(0, m_model->count(), KItemListSelectionManager::Toggle);
 }
 
 void DolphinView::clearSelection()
@@ -607,8 +614,8 @@ void DolphinView::renameSelectedItems()
      }
 
      if (items.count() == 1) {
-         const int index = fileItemModel()->index(items.first());
-         m_container->controller()->view()->editRole(index, "name");
+         const int index = m_model->index(items.first());
+         m_container->controller()->view()->editRole(index, "text");
      } else {
          RenameDialog* dialog = new RenameDialog(this, items);
          dialog->setAttribute(Qt::WA_DeleteOnClose);
@@ -683,19 +690,19 @@ bool DolphinView::eventFilter(QObject* watched, QEvent* event)
         break;
 
     case QEvent::GraphicsSceneDragEnter:
-        if (watched == m_container->controller()->view()) {
+        if (watched == m_view) {
             m_dragging = true;
         }
         break;
 
     case QEvent::GraphicsSceneDragLeave:
-        if (watched == m_container->controller()->view()) {
+        if (watched == m_view) {
             m_dragging = false;
         }
         break;
 
     case QEvent::GraphicsSceneDrop:
-        if (watched == m_container->controller()->view()) {
+        if (watched == m_view) {
             m_dragging = false;
         }
     default:
@@ -731,7 +738,7 @@ void DolphinView::activate()
 
 void DolphinView::slotItemActivated(int index)
 {
-    const KFileItem item = fileItemModel()->fileItem(index);
+    const KFileItem item = m_model->fileItem(index);
     if (!item.isNull()) {
         emit itemActivated(item);
     }
@@ -743,11 +750,10 @@ void DolphinView::slotItemsActivated(const QSet<int>& indexes)
 
     KFileItemList items;
 
-    KFileItemModel* model = fileItemModel();
     QSetIterator<int> it(indexes);
     while (it.hasNext()) {
         const int index = it.next();
-        items.append(model->fileItem(index));
+        items.append(m_model->fileItem(index));
     }
 
     foreach (const KFileItem& item, items) {
@@ -761,7 +767,7 @@ void DolphinView::slotItemsActivated(const QSet<int>& indexes)
 
 void DolphinView::slotItemMiddleClicked(int index)
 {
-    const KFileItem item = fileItemModel()->fileItem(index);
+    const KFileItem item = m_model->fileItem(index);
     if (item.isDir() || isTabsForFilesEnabled()) {
         emit tabRequested(item.url());
     }
@@ -769,7 +775,7 @@ void DolphinView::slotItemMiddleClicked(int index)
 
 void DolphinView::slotItemContextMenuRequested(int index, const QPointF& pos)
 {
-    const KFileItem item = fileItemModel()->fileItem(index);
+    const KFileItem item = m_model->fileItem(index);
     emit requestContextMenu(pos.toPoint(), item, url(), QList<QAction*>());
 }
 
@@ -803,12 +809,12 @@ void DolphinView::slotHeaderContextMenuRequested(const QPointF& pos)
     // Add all roles to the menu that can be shown or hidden by the user
     const QList<KFileItemModel::RoleInfo> rolesInfo = KFileItemModel::rolesInformation();
     foreach (const KFileItemModel::RoleInfo& info, rolesInfo) {
-        if (info.role == "name") {
-            // It should not be possible to hide the "name" role
+        if (info.role == "text") {
+            // It should not be possible to hide the "text" role
             continue;
         }
 
-        const QString text = fileItemModel()->roleDescription(info.role);
+        const QString text = m_model->roleDescription(info.role);
         QAction* action = 0;
         if (info.group.isEmpty()) {
             action = menu->addAction(text);
@@ -895,14 +901,14 @@ void DolphinView::slotHeaderColumnWidthChanged(const QByteArray& role, qreal cur
 {
     Q_UNUSED(previous);
 
-    const QList<QByteArray> visibleRoles = m_container->visibleRoles();
+    const QList<QByteArray> visibleRoles = m_view->visibleRoles();
 
     ViewProperties props(url());
     QList<int> columnWidths = props.headerColumnWidths();
     if (columnWidths.count() != visibleRoles.count()) {
         columnWidths.clear();
         columnWidths.reserve(visibleRoles.count());
-        const KItemListHeader* header = m_container->controller()->view()->header();
+        const KItemListHeader* header = m_view->header();
         foreach (const QByteArray& role, visibleRoles) {
             const int width = header->columnWidth(role);
             columnWidths.append(width);
@@ -918,7 +924,7 @@ void DolphinView::slotHeaderColumnWidthChanged(const QByteArray& role, qreal cur
 
 void DolphinView::slotItemHovered(int index)
 {
-    const KFileItem item = fileItemModel()->fileItem(index);
+    const KFileItem item = m_model->fileItem(index);
 
     if (GeneralSettings::showToolTips() && !m_dragging) {
         QRectF itemRect = m_container->controller()->view()->itemContextRect(index);
@@ -941,11 +947,11 @@ void DolphinView::slotItemUnhovered(int index)
 void DolphinView::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* event)
 {
     KUrl destUrl;
-    KFileItem destItem = fileItemModel()->fileItem(index);
+    KFileItem destItem = m_model->fileItem(index);
     if (destItem.isNull() || (!destItem.isDir() && !destItem.isDesktopFile())) {
         // Use the URL of the view as drop target if the item is no directory
         // or desktop-file
-        destItem = fileItemModel()->rootItem();
+        destItem = m_model->rootItem();
         destUrl = url();
     } else {
         // The item represents a directory or desktop-file
@@ -973,13 +979,16 @@ void DolphinView::slotModelChanged(KItemModelBase* current, KItemModelBase* prev
 {
     if (previous != 0) {
         disconnect(previous, SIGNAL(directoryLoadingCompleted()), this, SLOT(slotDirectoryLoadingCompleted()));
+        m_versionControlObserver->setModel(0);
     }
 
-    Q_ASSERT(qobject_cast<KFileItemModel*>(current));
-    connect(current, SIGNAL(loadingCompleted()), this, SLOT(slotDirectoryLoadingCompleted()));
+    if (current) {
+        Q_ASSERT(qobject_cast<KFileItemModel*>(current));
+        connect(current, SIGNAL(loadingCompleted()), this, SLOT(slotDirectoryLoadingCompleted()));
 
-    KFileItemModel* fileItemModel = static_cast<KFileItemModel*>(current);
-    m_versionControlObserver->setModel(fileItemModel);
+        KFileItemModel* fileItemModel = static_cast<KFileItemModel*>(current);
+        m_versionControlObserver->setModel(fileItemModel);
+    }
 }
 
 void DolphinView::slotMouseButtonPressed(int itemIndex, Qt::MouseButtons buttons)
@@ -1034,8 +1043,7 @@ void DolphinView::updateSortOrder(Qt::SortOrder order)
     ViewProperties props(url());
     props.setSortOrder(order);
 
-    KItemModelBase* model = fileItemModel();
-    model->setSortOrder(order);
+    m_model->setSortOrder(order);
 
     emit sortOrderChanged(order);
 }
@@ -1045,8 +1053,7 @@ void DolphinView::updateSortFoldersFirst(bool foldersFirst)
     ViewProperties props(url());
     props.setSortFoldersFirst(foldersFirst);
 
-    KFileItemModel* model = fileItemModel();
-    model->setSortDirectoriesFirst(foldersFirst);
+    m_model->setSortDirectoriesFirst(foldersFirst);
 
     emit sortFoldersFirstChanged(foldersFirst);
 }
@@ -1082,7 +1089,7 @@ void DolphinView::restoreState(QDataStream& stream)
     // Restore expanded folders (only relevant for the details view - will be ignored by the view in other view modes)
     QSet<KUrl> urls;
     stream >> urls;
-    fileItemModel()->restoreExpandedDirectories(urls);
+    m_model->restoreExpandedDirectories(urls);
 }
 
 void DolphinView::saveState(QDataStream& stream)
@@ -1090,7 +1097,7 @@ void DolphinView::saveState(QDataStream& stream)
     // Save the current item that has the keyboard focus
     const int currentIndex = m_container->controller()->selectionManager()->currentItem();
     if (currentIndex != -1) {
-        KFileItem item = fileItemModel()->fileItem(currentIndex);
+        KFileItem item = m_model->fileItem(currentIndex);
         Q_ASSERT(!item.isNull()); // If the current index is valid a item must exist
         KUrl currentItemUrl = item.url();
         stream << currentItemUrl;
@@ -1104,12 +1111,12 @@ void DolphinView::saveState(QDataStream& stream)
     stream << QPoint(x, y);
 
     // Save expanded folders (only relevant for the details view - the set will be empty in other view modes)
-    stream << fileItemModel()->expandedDirectories();
+    stream << m_model->expandedDirectories();
 }
 
 KFileItem DolphinView::rootItem() const
 {
-    return fileItemModel()->rootItem();
+    return m_model->rootItem();
 }
 
 void DolphinView::observeCreatedItem(const KUrl& url)
@@ -1147,7 +1154,7 @@ void DolphinView::updateViewState()
 {
     if (m_currentItemUrl != KUrl()) {
         KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
-        const int currentIndex = fileItemModel()->index(m_currentItemUrl);
+        const int currentIndex = m_model->index(m_currentItemUrl);
         if (currentIndex != -1) {
             selectionManager->setCurrentItem(currentIndex);
         } else {
@@ -1170,10 +1177,9 @@ void DolphinView::updateViewState()
 
         KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
         QSet<int> selectedItems = selectionManager->selectedItems();
-        const KFileItemModel* model = fileItemModel();
 
         foreach (const KUrl& url, m_selectedUrls) {
-            const int index = model->index(url);
+            const int index = m_model->index(url);
             if (index >= 0) {
                 selectedItems.insert(index);
             }
@@ -1195,10 +1201,9 @@ void DolphinView::calculateItemCount(int& fileCount,
                                      int& folderCount,
                                      KIO::filesize_t& totalFileSize) const
 {
-    const KFileItemModel* model = fileItemModel();
-    const int itemCount = model->count();
+    const int itemCount = m_model->count();
     for (int i = 0; i < itemCount; ++i) {
-        const KFileItem item = model->fileItem(i);
+        const KFileItem item = m_model->fileItem(i);
         if (item.isDir()) {
             ++folderCount;
         } else {
@@ -1258,7 +1263,7 @@ void DolphinView::slotItemsChanged()
 void DolphinView::slotSortOrderChangedByHeader(Qt::SortOrder current, Qt::SortOrder previous)
 {
     Q_UNUSED(previous);
-    Q_ASSERT(fileItemModel()->sortOrder() == current);
+    Q_ASSERT(m_model->sortOrder() == current);
 
     ViewProperties props(url());
     props.setSortOrder(current);
@@ -1269,7 +1274,7 @@ void DolphinView::slotSortOrderChangedByHeader(Qt::SortOrder current, Qt::SortOr
 void DolphinView::slotSortRoleChangedByHeader(const QByteArray& current, const QByteArray& previous)
 {
     Q_UNUSED(previous);
-    Q_ASSERT(fileItemModel()->sortRole() == current);
+    Q_ASSERT(m_model->sortRole() == current);
 
     ViewProperties props(url());
     props.setSortRole(current);
@@ -1295,8 +1300,8 @@ void DolphinView::slotVisibleRolesChangedByHeader(const QList<QByteArray>& curre
 
 void DolphinView::slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value)
 {
-    if (role == "name") {
-        const KFileItem item = fileItemModel()->fileItem(index);
+    if (role == "text") {
+        const KFileItem item = m_model->fileItem(index);
         const QString newName = value.toString();
         if (!newName.isEmpty() && newName != item.text() && newName != QLatin1String(".") && newName != QLatin1String("..")) {
             KonqOperations::rename(this, item.url(), newName);
@@ -1304,11 +1309,6 @@ void DolphinView::slotRoleEditingFinished(int index, const QByteArray& role, con
     }
 }
 
-KFileItemModel* DolphinView::fileItemModel() const
-{
-    return static_cast<KFileItemModel*>(m_container->controller()->model());
-}
-
 void DolphinView::loadDirectory(const KUrl& url, bool reload)
 {
     if (!url.isValid()) {
@@ -1321,20 +1321,18 @@ void DolphinView::loadDirectory(const KUrl& url, bool reload)
         return;
     }
 
-    KFileItemModel* model = fileItemModel();
     if (reload) {
-        model->refreshDirectory(url);
+        m_model->refreshDirectory(url);
     } else {
-        model->loadDirectory(url);
+        m_model->loadDirectory(url);
     }
 }
 
 void DolphinView::applyViewProperties()
 {
-    m_container->beginTransaction();
+    m_view->beginTransaction();
 
     const ViewProperties props(url());
-    KFileItemModel* model = fileItemModel();
 
     const Mode mode = props.viewMode();
     if (m_mode != mode) {
@@ -1344,49 +1342,43 @@ void DolphinView::applyViewProperties()
         // Changing the mode might result in changing
         // the zoom level. Remember the old zoom level so
         // that zoomLevelChanged() can get emitted.
-        const int oldZoomLevel = m_container->zoomLevel();
-
-        switch (m_mode) {
-        case IconsView:   m_container->setItemLayout(KFileItemListView::IconsLayout); break;
-        case CompactView: m_container->setItemLayout(KFileItemListView::CompactLayout); break;
-        case DetailsView: m_container->setItemLayout(KFileItemListView::DetailsLayout); break;
-        default: Q_ASSERT(false); break;
-        }
+        const int oldZoomLevel = m_view->zoomLevel();
+        applyModeToView();
 
         emit modeChanged(m_mode, previousMode);
 
-        if (m_container->zoomLevel() != oldZoomLevel) {
-            emit zoomLevelChanged(m_container->zoomLevel(), oldZoomLevel);
+        if (m_view->zoomLevel() != oldZoomLevel) {
+            emit zoomLevelChanged(m_view->zoomLevel(), oldZoomLevel);
         }
     }
 
     const bool hiddenFilesShown = props.hiddenFilesShown();
-    if (hiddenFilesShown != model->showHiddenFiles()) {
-        model->setShowHiddenFiles(hiddenFilesShown);
+    if (hiddenFilesShown != m_model->showHiddenFiles()) {
+        m_model->setShowHiddenFiles(hiddenFilesShown);
         emit hiddenFilesShownChanged(hiddenFilesShown);
     }
 
     const bool groupedSorting = props.groupedSorting();
-    if (groupedSorting != model->groupedSorting()) {
-        model->setGroupedSorting(groupedSorting);
+    if (groupedSorting != m_model->groupedSorting()) {
+        m_model->setGroupedSorting(groupedSorting);
         emit groupedSortingChanged(groupedSorting);
     }
 
     const QByteArray sortRole = props.sortRole();
-    if (sortRole != model->sortRole()) {
-        model->setSortRole(sortRole);
+    if (sortRole != m_model->sortRole()) {
+        m_model->setSortRole(sortRole);
         emit sortRoleChanged(sortRole);
     }
 
     const Qt::SortOrder sortOrder = props.sortOrder();
-    if (sortOrder != model->sortOrder()) {
-        model->setSortOrder(sortOrder);
+    if (sortOrder != m_model->sortOrder()) {
+        m_model->setSortOrder(sortOrder);
         emit sortOrderChanged(sortOrder);
     }
 
     const bool sortFoldersFirst = props.sortFoldersFirst();
-    if (sortFoldersFirst != model->sortDirectoriesFirst()) {
-        model->setSortDirectoriesFirst(sortFoldersFirst);
+    if (sortFoldersFirst != m_model->sortDirectoriesFirst()) {
+        m_model->setSortDirectoriesFirst(sortFoldersFirst);
         emit sortFoldersFirstChanged(sortFoldersFirst);
     }
 
@@ -1394,15 +1386,15 @@ void DolphinView::applyViewProperties()
     if (visibleRoles != m_visibleRoles) {
         const QList<QByteArray> previousVisibleRoles = m_visibleRoles;
         m_visibleRoles = visibleRoles;
-        m_container->setVisibleRoles(visibleRoles);
+        m_view->setVisibleRoles(visibleRoles);
         emit visibleRolesChanged(m_visibleRoles, previousVisibleRoles);
     }
 
     const bool previewsShown = props.previewsShown();
-    if (previewsShown != m_container->previewsShown()) {
+    if (previewsShown != m_view->previewsShown()) {
         const int oldZoomLevel = zoomLevel();
 
-        m_container->setPreviewsShown(previewsShown);
+        m_view->setPreviewsShown(previewsShown);
         emit previewsShownChanged(previewsShown);
 
         // Changing the preview-state might result in a changed zoom-level
@@ -1429,7 +1421,17 @@ void DolphinView::applyViewProperties()
         }
     }
 
-    m_container->endTransaction();
+    m_view->endTransaction();
+}
+
+void DolphinView::applyModeToView()
+{
+    switch (m_mode) {
+    case IconsView:   m_view->setItemLayout(KFileItemListView::IconsLayout); break;
+    case CompactView: m_view->setItemLayout(KFileItemListView::CompactLayout); break;
+    case DetailsView: m_view->setItemLayout(KFileItemListView::DetailsLayout); break;
+    default: Q_ASSERT(false); break;
+    }
 }
 
 void DolphinView::pasteToUrl(const KUrl& url)
@@ -1457,11 +1459,10 @@ KUrl::List DolphinView::simplifiedSelectedUrls() const
 
 QMimeData* DolphinView::selectionMimeData() const
 {
-    const KFileItemModel* model = fileItemModel();
     const KItemListSelectionManager* selectionManager = m_container->controller()->selectionManager();
     const QSet<int> selectedIndexes = selectionManager->selectedItems();
 
-    return model->createMimeData(selectedIndexes);
+    return m_model->createMimeData(selectedIndexes);
 }
 
 void DolphinView::markPastedUrlsAsSelected(const QMimeData* mimeData)
@@ -1480,7 +1481,7 @@ void DolphinView::updateWritableState()
     const bool wasFolderWritable = m_isFolderWritable;
     m_isFolderWritable = true;
 
-    const KFileItem item = fileItemModel()->rootItem();
+    const KFileItem item = m_model->rootItem();
     if (!item.isNull()) {
         KFileItemListProperties capabilities(KFileItemList() << item);
         m_isFolderWritable = capabilities.supportsWriting();
index a9cf0ade40efd160fd80940c2d15ff4637b6440a..bfac885025eca30e737dfd38e5f8444ed920afba 100644 (file)
 
 typedef KIO::FileUndoManager::CommandType CommandType;
 
-class DolphinItemListContainer;
+class DolphinItemListView;
 class KAction;
 class KActionCollection;
 class KFileItemModel;
+class KItemListContainer;
 class KItemModelBase;
 class KUrl;
 class ToolTipManager;
@@ -659,8 +660,6 @@ private slots:
     void calculateItemCount(int& fileCount, int& folderCount, KIO::filesize_t& totalFileSize) const;
 
 private:
-    KFileItemModel* fileItemModel() const;
-
     void loadDirectory(const KUrl& url, bool reload = false);
 
     /**
@@ -669,6 +668,12 @@ private:
      */
     void applyViewProperties();
 
+    /**
+     * Applies the m_mode property to the corresponding
+     * itemlayout-property of the KItemListView.
+     */
+    void applyModeToView();
+
     /**
      * Helper method for DolphinView::paste() and DolphinView::pasteIntoFolder().
      * Pastes the clipboard data into the URL \a url.
@@ -716,7 +721,9 @@ private:
 
     QVBoxLayout* m_topLayout;
 
-    DolphinItemListContainer* m_container;
+    KFileItemModel* m_model;
+    DolphinItemListView* m_view;
+    KItemListContainer* m_container;
 
     ToolTipManager* m_toolTipManager;
 
index e2293674096f066bf546f8087d822e4c5c8bccc4..6f69a642010872ce95ae0080c59a484f4d5f9ee7 100644 (file)
@@ -246,8 +246,8 @@ QActionGroup* DolphinViewActionHandler::createFileItemRolesActionGroup(const QSt
 
     const QList<KFileItemModel::RoleInfo> rolesInfo = KFileItemModel::rolesInformation();
     foreach (const KFileItemModel::RoleInfo& info, rolesInfo) {
-        if (!isSortGroup && info.role == "name") {
-            // It should not be possible to hide the "name" role
+        if (!isSortGroup && info.role == "text") {
+            // It should not be possible to hide the "text" role
             continue;
         }
 
index 83958ad001550dfd955933760dad5cbb2303b40a..d19b3bfdac3b6d3e3a36eb76ab0a1d544edb0c23 100644 (file)
@@ -33,8 +33,9 @@
 #include <QFileInfo>
 
 namespace {
-    const int CurrentViewPropertiesVersion = 2;
     const int AdditionalInfoViewPropertiesVersion = 1;
+    const int NameRolePropertiesVersion = 2;
+    const int CurrentViewPropertiesVersion = 3;
 
     // String representation to mark the additional properties of
     // the details view as customized by the user. See
@@ -256,7 +257,7 @@ QList<QByteArray> ViewProperties::visibleRoles() const
     // is accepted.
 
     QList<QByteArray> roles;
-    roles.append("name");
+    roles.append("text");
 
     // Iterate through all stored keys and append all roles that match to
     // the curren view mode.
@@ -264,16 +265,19 @@ QList<QByteArray> ViewProperties::visibleRoles() const
     const int prefixLength = prefix.length();
 
     QStringList visibleRoles = m_node->visibleRoles();
-    if (visibleRoles.isEmpty() && m_node->version() <= AdditionalInfoViewPropertiesVersion) {
+    const int version = m_node->version();
+    if (visibleRoles.isEmpty() && version <= AdditionalInfoViewPropertiesVersion) {
         // Convert the obsolete additionalInfo-property from older versions into the
         // visibleRoles-property
         visibleRoles = const_cast<ViewProperties*>(this)->convertAdditionalInfo();
+    } else if (version <= NameRolePropertiesVersion) {
+        visibleRoles = const_cast<ViewProperties*>(this)->convertNameRole();
     }
 
     foreach (const QString& visibleRole, visibleRoles) {
         if (visibleRole.startsWith(prefix)) {
             const QByteArray role = visibleRole.right(visibleRole.length() - prefixLength).toLatin1();
-            if (role != "name") {
+            if (role != "text") {
                 roles.append(role);
             }
         }
@@ -281,7 +285,7 @@ QList<QByteArray> ViewProperties::visibleRoles() const
 
     // For the details view the size and date should be shown per default
     // until the additional information has been explicitly changed by the user
-    const bool useDefaultValues = roles.count() == 1 // "name"
+    const bool useDefaultValues = roles.count() == 1 // "text"
                                   && (m_node->viewMode() == DolphinView::DetailsView)
                                   && !visibleRoles.contains(CustomizedDetailsString);
     if (useDefaultValues) {
@@ -403,6 +407,23 @@ QStringList ViewProperties::convertAdditionalInfo()
     return visibleRoles;
 }
 
+QStringList ViewProperties::convertNameRole()
+{
+    QStringList visibleRoles = m_node->visibleRoles();
+    for (int i = 0; i < visibleRoles.count(); ++i) {
+        if (visibleRoles[i].endsWith("_name")) {
+            const int leftLength = visibleRoles[i].length() - 5;
+            visibleRoles[i] = visibleRoles[i].left(leftLength) + "_text";
+        }
+    }
+
+    m_node->setVisibleRoles(visibleRoles);
+    update();
+
+    return visibleRoles;
+}
+
+
 bool ViewProperties::isPartOfHome(const QString& filePath)
 {
     // For performance reasons cache the path in a static QString
index 303c042271c879f5f166fb5627458318170dbb29..29f7c282cc7144296c3bb03f6cae8db97717a053 100644 (file)
@@ -142,11 +142,18 @@ private:
 
     /**
      * Provides backward compatibility with .directory files created with
-     * Dolphin < 2.1: Converts the old additionalInfo-property into
+     * Dolphin < 2.0: Converts the old additionalInfo-property into
      * the visibleRoles-property and clears the additionalInfo-property.
      */
     QStringList convertAdditionalInfo();
 
+    /**
+     * Provides backward compatibility with .directory files created with
+     * Dolphin < 2.1: Converts the old name-role "name" to the generic
+     * role "text".
+     */
+    QStringList convertNameRole();
+
     /**
      * Returns true, if \a filePath is part of the home-path (see QDir::homePath()).
      */