]> cloud.milkyroute.net Git - dolphin.git/commitdiff
KItemListView interface and implementation simplification
authorPeter Penz <peter.penz19@gmail.com>
Mon, 26 Mar 2012 22:44:39 +0000 (00:44 +0200)
committerPeter Penz <peter.penz19@gmail.com>
Mon, 26 Mar 2012 22:48:34 +0000 (00:48 +0200)
- Remove KItemListView::preferredRoleColumnWidth() and allow implementing
  this as part of derived classes from KItemListWidget. Those derived
  classes are aware about the layout and hence also can provide the
  preferred role width.

- Make KItemListView::itemSizeHint() non-virtual and also allow
  implementing the size hint as part of derived classes from KItemListWidget.

src/kitemviews/kfileitemlistview.cpp
src/kitemviews/kfileitemlistview.h
src/kitemviews/kfileitemlistwidget.cpp
src/kitemviews/kfileitemlistwidget.h
src/kitemviews/kitemlistview.cpp
src/kitemviews/kitemlistview.h

index ab111b9129266c7eb5b272934a13b1a823db2205..8f7c9c899c5e045e24cff5b129d108de9a7272bf 100644 (file)
@@ -46,8 +46,7 @@ KFileItemListView::KFileItemListView(QGraphicsWidget* parent) :
     m_itemLayout(IconsLayout),
     m_modelRolesUpdater(0),
     m_updateVisibleIndexRangeTimer(0),
     m_itemLayout(IconsLayout),
     m_modelRolesUpdater(0),
     m_updateVisibleIndexRangeTimer(0),
-    m_updateIconSizeTimer(0),
-    m_minimumRolesWidths()
+    m_updateIconSizeTimer(0)
 {
     setAcceptDrops(true);
 
 {
     setAcceptDrops(true);
 
@@ -66,8 +65,6 @@ KFileItemListView::KFileItemListView(QGraphicsWidget* parent) :
     connect(m_updateIconSizeTimer, SIGNAL(timeout()), this, SLOT(updateIconSize()));
 
     setVisibleRoles(QList<QByteArray>() << "name");
     connect(m_updateIconSizeTimer, SIGNAL(timeout()), this, SLOT(updateIconSize()));
 
     setVisibleRoles(QList<QByteArray>() << "name");
-
-    updateMinimumRolesWidths();
 }
 
 KFileItemListView::~KFileItemListView()
 }
 
 KFileItemListView::~KFileItemListView()
@@ -126,98 +123,6 @@ QStringList KFileItemListView::enabledPlugins() const
     return m_modelRolesUpdater ? m_modelRolesUpdater->enabledPlugins() : QStringList();
 }
 
     return m_modelRolesUpdater ? m_modelRolesUpdater->enabledPlugins() : QStringList();
 }
 
-QSizeF KFileItemListView::itemSizeHint(int index) const
-{
-    const QHash<QByteArray, QVariant> values = model()->data(index);
-    const KItemListStyleOption& option = styleOption();
-    const int additionalRolesCount = qMax(visibleRoles().count() - 1, 0);
-
-    switch (m_itemLayout) {
-    case IconsLayout: {
-        const QString text = KStringHandler::preProcessWrap(values["name"].toString());
-
-        const qreal maxWidth = itemSize().width() - 2 * option.padding;
-        int textLinesCount = 0;
-        QTextLine line;
-
-        // Calculate the number of lines required for wrapping the name
-        QTextOption textOption(Qt::AlignHCenter);
-        textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
-
-        QTextLayout layout(text, option.font);
-        layout.setTextOption(textOption);
-        layout.beginLayout();
-        while ((line = layout.createLine()).isValid()) {
-            line.setLineWidth(maxWidth);
-            line.naturalTextWidth();
-            ++textLinesCount;
-        }
-        layout.endLayout();
-
-        // Add one line for each additional information
-        textLinesCount += additionalRolesCount;
-
-        const qreal height = textLinesCount * option.fontMetrics.height() +
-                             option.iconSize +
-                             option.padding * 3;
-        return QSizeF(itemSize().width(), height);
-    }
-
-    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, visibleRoles()) {
-            const QString text = KFileItemListWidget::roleText(role, values);
-            const qreal requiredWidth = option.fontMetrics.width(text);
-            maximumRequiredWidth = qMax(maximumRequiredWidth, requiredWidth);
-        }
-
-        const qreal width = option.padding * 4 + option.iconSize + maximumRequiredWidth;
-        const qreal height = option.padding * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * option.fontMetrics.height());
-        return QSizeF(width, height);
-    }
-
-    case DetailsLayout: {
-        // The width will be determined dynamically by KFileItemListView::visibleRoleSizes()
-        const qreal height = option.padding * 2 + qMax(option.iconSize, option.fontMetrics.height());
-        return QSizeF(-1, height);
-    }
-
-    default:
-        Q_ASSERT(false);
-        break;
-    }
-
-    return QSize();
-}
-
-qreal KFileItemListView::preferredRoleColumnWidth(const QByteArray& role, int index) const
-{
-    const KItemListStyleOption& option = styleOption();
-
-    qreal width = m_minimumRolesWidths.value(role, 0);
-
-    const QHash<QByteArray, QVariant> values = model()->data(index);
-    const QString text = KFileItemListWidget::roleText(role, values);
-    if (!text.isEmpty()) {
-        const qreal columnPadding = option.padding * 3;
-        width = qMax(width, qreal(2 * columnPadding + 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) * itemSize().height() + KIconLoader::SizeSmall;
-
-        // Increase the width by the required space for the icon
-        width += option.padding * 2 + option.iconSize;
-    }
-
-    return width;
-}
-
 QPixmap KFileItemListView::createDragPixmap(const QSet<int>& indexes) const
 {
     if (!model()) {
 QPixmap KFileItemListView::createDragPixmap(const QSet<int>& indexes) const
 {
     if (!model()) {
@@ -502,15 +407,6 @@ void KFileItemListView::updateTimersInterval()
     m_updateIconSizeTimer->setInterval(interval);
 }
 
     m_updateIconSizeTimer->setInterval(interval);
 }
 
-void KFileItemListView::updateMinimumRolesWidths()
-{
-    m_minimumRolesWidths.clear();
-
-    const KItemListStyleOption& option = styleOption();
-    const QString sizeText = QLatin1String("888888") + i18nc("@item:intable", "items");
-    m_minimumRolesWidths.insert("size", option.fontMetrics.width(sizeText));
-}
-
 void KFileItemListView::applyRolesToModel()
 {
     if (!model()) {
 void KFileItemListView::applyRolesToModel()
 {
     if (!model()) {
index a94e2b6f5d67a982a60137cf2845852aa2bbbc74..40808c4de9e4ad038b594e82abe890e1c3ca6170 100644 (file)
@@ -74,12 +74,6 @@ public:
      */
     QStringList enabledPlugins() const;
 
      */
     QStringList enabledPlugins() const;
 
-    /** @reimp */
-    virtual QSizeF itemSizeHint(int index) const;
-
-    /** @reimp */
-    virtual qreal preferredRoleColumnWidth(const QByteArray& role, int index) const;
-
     /** @reimp */
     virtual QPixmap createDragPixmap(const QSet<int>& indexes) const;
 
     /** @reimp */
     virtual QPixmap createDragPixmap(const QSet<int>& indexes) const;
 
@@ -111,7 +105,6 @@ private slots:
 private:
     void updateLayoutOfVisibleItems();
     void updateTimersInterval();
 private:
     void updateLayoutOfVisibleItems();
     void updateTimersInterval();
-    void updateMinimumRolesWidths();
 
     /**
      * Applies the roles defined by KItemListView::visibleRoles() to the
 
     /**
      * Applies the roles defined by KItemListView::visibleRoles() to the
@@ -135,9 +128,6 @@ private:
     QTimer* m_updateVisibleIndexRangeTimer;
     QTimer* m_updateIconSizeTimer;
 
     QTimer* m_updateVisibleIndexRangeTimer;
     QTimer* m_updateIconSizeTimer;
 
-    // Cache for calculating visibleRoleSizes() in a fast way
-    QHash<QByteArray, int> m_minimumRolesWidths;
-
     friend class KFileItemListViewTest; // For unit testing
 };
 
     friend class KFileItemListViewTest; // For unit testing
 };
 
index 5c865d1ca3a0f7872b6eaa92a6631f5417c9d380..022f3b472f66050556c2d5fbed085231fa07926b 100644 (file)
@@ -20,8 +20,8 @@
 #include "kfileitemlistwidget.h"
 
 #include "kfileitemclipboard_p.h"
 #include "kfileitemlistwidget.h"
 
 #include "kfileitemclipboard_p.h"
+#include "kfileitemlistview.h"
 #include "kfileitemmodel.h"
 #include "kfileitemmodel.h"
-#include "kitemlistview.h"
 #include "kpixmapmodifier_p.h"
 
 #include <KIcon>
 #include "kpixmapmodifier_p.h"
 
 #include <KIcon>
@@ -222,48 +222,62 @@ QRectF KFileItemListWidget::selectionToggleRect() const
     return QRectF(pos, QSizeF(toggleSize, toggleSize));
 }
 
     return QRectF(pos, QSizeF(toggleSize, toggleSize));
 }
 
-QString KFileItemListWidget::roleText(const QByteArray& role, const QHash<QByteArray, QVariant>& values)
+QSizeF KFileItemListWidget::itemSizeHint(int index, const KItemListView* view)
 {
 {
-    QString text;
-    const QVariant roleValue = values.value(role);
+    const QHash<QByteArray, QVariant> values = view->model()->data(index);
+    const KItemListStyleOption& option = view->styleOption();
+    const int additionalRolesCount = qMax(view->visibleRoles().count() - 1, 0);
 
 
-    switch (roleTextId(role)) {
-    case Name:
-    case Permissions:
-    case Owner:
-    case Group:
-    case Type:
-    case Destination:
-    case Path:
-        text = roleValue.toString();
-        break;
+    switch (static_cast<const KFileItemListView*>(view)->itemLayout()) {
+    case IconsLayout: {
+        const QString text = KStringHandler::preProcessWrap(values["name"].toString());
 
 
-    case 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.
-            if (!roleValue.isNull()) {
-                const int count = roleValue.toInt();
-                if (count < 0) {
-                    text = i18nc("@item:intable", "Unknown");
-                } else {
-                    text = i18ncp("@item:intable", "%1 item", "%1 items", count);
-                }
-            }
-        } else {
-            // Show the size in kilobytes (always round up)
-            const KLocale* locale = KGlobal::locale();
-            const int roundInc = (locale->binaryUnitDialect() == KLocale::MetricBinaryDialect) ? 499 : 511;
-            const KIO::filesize_t size = roleValue.value<KIO::filesize_t>() + roundInc;
-            text = locale->formatByteSize(size, 0, KLocale::DefaultBinaryDialect, KLocale::UnitKiloByte);
+        const qreal maxWidth = view->itemSize().width() - 2 * option.padding;
+        int textLinesCount = 0;
+        QTextLine line;
+
+        // Calculate the number of lines required for wrapping the name
+        QTextOption textOption(Qt::AlignHCenter);
+        textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
+
+        QTextLayout layout(text, option.font);
+        layout.setTextOption(textOption);
+        layout.beginLayout();
+        while ((line = layout.createLine()).isValid()) {
+            line.setLineWidth(maxWidth);
+            line.naturalTextWidth();
+            ++textLinesCount;
         }
         }
-        break;
+        layout.endLayout();
+
+        // Add one line for each additional information
+        textLinesCount += additionalRolesCount;
+
+        const qreal height = textLinesCount * option.fontMetrics.height() +
+                             option.iconSize +
+                             option.padding * 3;
+        return QSizeF(view->itemSize().width(), height);
     }
 
     }
 
-    case Date: {
-        const QDateTime dateTime = roleValue.toDateTime();
-        text = KGlobal::locale()->formatDateTime(dateTime);
-        break;
+    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);
+        }
+
+        const qreal width = option.padding * 4 + option.iconSize + maximumRequiredWidth;
+        const qreal height = option.padding * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * option.fontMetrics.height());
+        return QSizeF(width, height);
+    }
+
+    case DetailsLayout: {
+        const qreal height = option.padding * 2 + qMax(option.iconSize, option.fontMetrics.height());
+        return QSizeF(-1, height);
     }
 
     default:
     }
 
     default:
@@ -271,7 +285,34 @@ QString KFileItemListWidget::roleText(const QByteArray& role, const QHash<QByteA
         break;
     }
 
         break;
     }
 
-    return text;
+    return QSize();
+}
+
+qreal KFileItemListWidget::preferredRoleColumnWidth(const QByteArray& role,
+                                                    int index,
+                                                    const KItemListView* view)
+{
+    qreal width = 0;
+
+    const QHash<QByteArray, QVariant> values = view->model()->data(index);
+    const KItemListStyleOption& option = view->styleOption();
+
+    const QString text = KFileItemListWidget::roleText(role, values);
+    if (!text.isEmpty()) {
+        const qreal columnPadding = option.padding * 3;
+        width = qMax(width, qreal(2 * columnPadding + 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()
 }
 
 void KFileItemListWidget::invalidateCache()
@@ -924,6 +965,17 @@ QPixmap KFileItemListWidget::pixmapForIcon(const QString& name, int size)
     return pixmap;
 }
 
     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)
+{
+    KIconEffect::semiTransparent(pixmap);
+}
+
 KFileItemListWidget::TextId KFileItemListWidget::roleTextId(const QByteArray& role)
 {
     static QHash<QByteArray, TextId> rolesHash;
 KFileItemListWidget::TextId KFileItemListWidget::roleTextId(const QByteArray& role)
 {
     static QHash<QByteArray, TextId> rolesHash;
@@ -942,15 +994,55 @@ KFileItemListWidget::TextId KFileItemListWidget::roleTextId(const QByteArray& ro
     return rolesHash.value(role);
 }
 
     return rolesHash.value(role);
 }
 
-void KFileItemListWidget::applyCutEffect(QPixmap& pixmap)
+QString KFileItemListWidget::roleText(const QByteArray& role, const QHash<QByteArray, QVariant>& values)
 {
 {
-    KIconEffect* effect = KIconLoader::global()->iconEffect();
-    pixmap = effect->apply(pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
-}
+    QString text;
+    const QVariant roleValue = values.value(role);
 
 
-void KFileItemListWidget::applyHiddenEffect(QPixmap& pixmap)
-{
-    KIconEffect::semiTransparent(pixmap);
-}
+    switch (roleTextId(role)) {
+    case Name:
+    case Permissions:
+    case Owner:
+    case Group:
+    case Type:
+    case Destination:
+    case Path:
+        text = roleValue.toString();
+        break;
+
+    case 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.
+            if (!roleValue.isNull()) {
+                const int count = roleValue.toInt();
+                if (count < 0) {
+                    text = i18nc("@item:intable", "Unknown");
+                } else {
+                    text = i18ncp("@item:intable", "%1 item", "%1 items", count);
+                }
+            }
+        } else {
+            // Show the size in kilobytes (always round up)
+            const KLocale* locale = KGlobal::locale();
+            const int roundInc = (locale->binaryUnitDialect() == KLocale::MetricBinaryDialect) ? 499 : 511;
+            const KIO::filesize_t size = roleValue.value<KIO::filesize_t>() + roundInc;
+            text = locale->formatByteSize(size, 0, KLocale::DefaultBinaryDialect, KLocale::UnitKiloByte);
+        }
+        break;
+    }
+
+    case Date: {
+        const QDateTime dateTime = roleValue.toDateTime();
+        text = KGlobal::locale()->formatDateTime(dateTime);
+        break;
+    }
+
+    default:
+        Q_ASSERT(false);
+        break;
+    }
 
 
+    return text;
+}
 #include "kfileitemlistwidget.moc"
 #include "kfileitemlistwidget.moc"
index 3e6cf8d2ab0f9f1cda8fce3ed20b55bb2afeb9fd..76d090040870a5f2e3779e48ac81812fff810ba1 100644 (file)
@@ -28,6 +28,9 @@
 #include <QPointF>
 #include <QStaticText>
 
 #include <QPointF>
 #include <QStaticText>
 
+class KItemListView;
+class KItemListStyleOption;
+
 class LIBDOLPHINPRIVATE_EXPORT KFileItemListWidget : public KItemListWidget
 {
     Q_OBJECT
 class LIBDOLPHINPRIVATE_EXPORT KFileItemListWidget : public KItemListWidget
 {
     Q_OBJECT
@@ -57,12 +60,20 @@ public:
     virtual QRectF selectionToggleRect() const;
 
     /**
     virtual QRectF selectionToggleRect() const;
 
     /**
-     * @return Shown string for the role \p role of the item with the values \p values.
+     * Implementation of KItemListWidgetCreatorBase::itemSizeHint() when
+     * using the KItemListWidgetCreator-template.
+     *
+     * @see KItemListView
      */
      */
-    // TODO: Move this method to a helper class shared by KFileItemListWidget and
-    // KFileItemListView to share information that is required to calculate the size hints
-    // in KFileItemListView and to represent the actual data in KFileItemListWidget.
-    static QString roleText(const QByteArray& role, const QHash<QByteArray, QVariant>& values);
+    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);
 
 protected:
     /**
 
 protected:
     /**
@@ -126,9 +137,14 @@ private:
     void drawSiblingsInformation(QPainter* painter);
 
     static QPixmap pixmapForIcon(const QString& name, int size);
     void drawSiblingsInformation(QPainter* painter);
 
     static QPixmap pixmapForIcon(const QString& name, int size);
-    static TextId roleTextId(const QByteArray& role);
     static void applyCutEffect(QPixmap& pixmap);
     static void applyHiddenEffect(QPixmap& pixmap);
     static void applyCutEffect(QPixmap& pixmap);
     static void applyHiddenEffect(QPixmap& pixmap);
+    static TextId roleTextId(const QByteArray& role);
+
+    /**
+     * @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;
 
 private:
     bool m_isCut;
index 7d1cd6e71707425817af076968b67e254d8a9810..8a18991a09fd800f984e38bee757e274269e78b6 100644 (file)
@@ -510,15 +510,7 @@ int KItemListView::lastVisibleIndex() const
 
 QSizeF KItemListView::itemSizeHint(int index) const
 {
 
 QSizeF KItemListView::itemSizeHint(int index) const
 {
-    Q_UNUSED(index);
-    return itemSize();
-}
-
-qreal KItemListView::preferredRoleColumnWidth(const QByteArray& role, int index) const
-{
-    Q_UNUSED(role);
-    Q_UNUSED(index);
-    return 100;
+    return m_widgetCreator->itemSizeHint(index, this);
 }
 
 void KItemListView::setSupportsItemExpanding(bool supportsExpanding)
 }
 
 void KItemListView::setSupportsItemExpanding(bool supportsExpanding)
@@ -1915,7 +1907,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);
         for (int i = startIndex; i <= endIndex; ++i) {
             foreach (const QByteArray& visibleRole, visibleRoles()) {
                 qreal maxWidth = widths.value(visibleRole, 0);
-                const qreal width = preferredRoleColumnWidth(visibleRole, i);
+                const qreal width = m_widgetCreator->preferredRoleColumnWidth(visibleRole, i, this);
                 maxWidth = qMax(width, maxWidth);
                 widths.insert(visibleRole, maxWidth);
             }
                 maxWidth = qMax(width, maxWidth);
                 widths.insert(visibleRole, maxWidth);
             }
index 9c42a6f3eb571d483a28f1c2dbe03ea72bdec03b..d65ece8e29ed3817c272482e01d7e51e1902604d 100644 (file)
@@ -186,17 +186,11 @@ public:
 
     /**
      * @return Required size for the item with the index \p index.
 
     /**
      * @return Required size for the item with the index \p index.
-     *         Per default KItemListView::itemSize() is returned.
-     *         When reimplementing this method it is recommended to
-     *         also reimplement KItemListView::itemSizeHintUpdateRequired().
+     *         The returned value might be larger than KItemListView::itemSize().
+     *         In this case the layout grid will be stretched to assure an
+     *         unclipped item.
      */
      */
-    virtual QSizeF itemSizeHint(int index) const;
-
-    /**
-     * @return The preferred column-width of the given \a role for the item
-     *         with the index \a index.
-     */
-    virtual qreal preferredRoleColumnWidth(const QByteArray& role, int index) const;
+    QSizeF itemSizeHint(int index) const;
 
     /**
      * If set to true, items having child-items can be expanded to show the child-items as
 
     /**
      * If set to true, items having child-items can be expanded to show the child-items as
@@ -714,24 +708,50 @@ private:
  * @brief Base class for creating KItemListWidgets.
  *
  * It is recommended that applications simply use the KItemListWidgetCreator-template class.
  * @brief Base class for creating KItemListWidgets.
  *
  * It is recommended that applications simply use the KItemListWidgetCreator-template class.
- * For a custom implementation the methods create() and recyle() must be reimplemented.
- * The intention of the widget creator is to prevent repetitive and expensive instantiations and
- * deletions of KItemListWidgets by recycling existing widget instances.
+ * For a custom implementation the methods create(), itemSizeHint() and preferredColumnWith()
+ * must be reimplemented. The intention of the widget creator is to prevent repetitive and
+ * expensive instantiations and deletions of KItemListWidgets by recycling existing widget
+ * instances.
  */
 class LIBDOLPHINPRIVATE_EXPORT KItemListWidgetCreatorBase : public KItemListCreatorBase
 {
 public:
     virtual ~KItemListWidgetCreatorBase();
  */
 class LIBDOLPHINPRIVATE_EXPORT KItemListWidgetCreatorBase : public KItemListCreatorBase
 {
 public:
     virtual ~KItemListWidgetCreatorBase();
+
     virtual KItemListWidget* create(KItemListView* view) = 0;
     virtual KItemListWidget* create(KItemListView* view) = 0;
+
     virtual void recycle(KItemListWidget* widget);
     virtual void recycle(KItemListWidget* widget);
+
+    virtual QSizeF itemSizeHint(int index, const KItemListView* view) const = 0;
+
+    virtual qreal preferredRoleColumnWidth(const QByteArray& role,
+                                           int index,
+                                           const KItemListView* view) const = 0;
 };
 
 };
 
+/**
+ * @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:
     virtual ~KItemListWidgetCreator();
 template <class T>
 class KItemListWidgetCreator : public KItemListWidgetCreatorBase
 {
 public:
     virtual ~KItemListWidgetCreator();
+
     virtual KItemListWidget* create(KItemListView* view);
     virtual KItemListWidget* create(KItemListView* view);
+
+    virtual QSizeF itemSizeHint(int index, const KItemListView* view) const;
+
+    virtual qreal preferredRoleColumnWidth(const QByteArray& role,
+                                           int index,
+                                           const KItemListView* view) const;
 };
 
 template <class T>
 };
 
 template <class T>
@@ -750,6 +770,20 @@ KItemListWidget* KItemListWidgetCreator<T>::create(KItemListView* view)
     return widget;
 }
 
     return widget;
 }
 
+template<class T>
+QSizeF KItemListWidgetCreator<T>::itemSizeHint(int index, const KItemListView* view) const
+{
+    return T::itemSizeHint(index, view);
+}
+
+template<class T>
+qreal KItemListWidgetCreator<T>::preferredRoleColumnWidth(const QByteArray& role,
+                                                          int index,
+                                                          const KItemListView* view) const
+{
+    return T::preferredRoleColumnWidth(role, index, view);
+}
+
 /**
  * @brief Base class for creating KItemListGroupHeaders.
  *
 /**
  * @brief Base class for creating KItemListGroupHeaders.
  *