]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Cleanup and minor fixes for column-handling
authorPeter Penz <peter.penz19@gmail.com>
Sat, 24 Mar 2012 22:46:44 +0000 (23:46 +0100)
committerPeter Penz <peter.penz19@gmail.com>
Sat, 24 Mar 2012 22:47:42 +0000 (23:47 +0100)
src/kitemviews/kfileitemlistview.cpp
src/kitemviews/kfileitemlistview.h
src/kitemviews/kitemlistheader.cpp
src/kitemviews/kitemlistheader.h
src/kitemviews/kitemlistheaderwidget.cpp
src/kitemviews/kitemlistheaderwidget_p.h
src/kitemviews/kitemlistview.cpp
src/kitemviews/kitemlistview.h
src/views/dolphinview.cpp

index 483dabb8366f13b6d3de8a8df021f1141f876bf1..a0650b665660a6ccd3a37a67ef45dd2c5ade086b 100644 (file)
@@ -193,7 +193,7 @@ QSizeF KFileItemListView::itemSizeHint(int index) const
     return QSize();
 }
 
-QHash<QByteArray, qreal> KFileItemListView::columnWidths(const KItemRangeList& itemRanges) const
+QHash<QByteArray, qreal> KFileItemListView::preferredColumnWidths(const KItemRangeList& itemRanges) const
 {
     QElapsedTimer timer;
     timer.start();
index 23a84d4b96547cdc75a713c90c19f78826901268..db8566934af41bf77020ec327aab38a4d4aa999c 100644 (file)
@@ -78,7 +78,7 @@ public:
     virtual QSizeF itemSizeHint(int index) const;
 
     /** @reimp */
-    virtual QHash<QByteArray, qreal> columnWidths(const KItemRangeList& itemRanges) const;
+    virtual QHash<QByteArray, qreal> preferredColumnWidths(const KItemRangeList& itemRanges) const;
 
     /** @reimp */
     virtual QPixmap createDragPixmap(const QSet<int>& indexes) const;
index f1050538d3290f79b39d33282f6e7dd4a40089df..9c617840aa84e72acc2875aa0d9a52480dc846c0 100644 (file)
@@ -30,7 +30,7 @@ void KItemListHeader::setAutomaticColumnResizing(bool automatic)
     if (m_headerWidget->automaticColumnResizing() != automatic) {
         m_headerWidget->setAutomaticColumnResizing(automatic);
         if (automatic) {
-            m_view->updateColumnWidthsForHeader();
+            m_view->resizeColumnWidths();
         }
     }
 }
@@ -65,6 +65,11 @@ void KItemListHeader::setColumnWidths(const QHash<QByteArray, qreal>& columnWidt
     }
 }
 
+qreal KItemListHeader::preferredColumnWidth(const QByteArray& role) const
+{
+    return m_headerWidget->preferredColumnWidth(role);
+}
+
 KItemListHeader::KItemListHeader(KItemListView* listView) :
     QObject(listView->parent()),
     m_view(listView)
index d0aae7fc1e81f16710c8d212de94771e447281f8..fe2d0ac1052d590157b8780aae7c3e591a208269 100644 (file)
@@ -65,6 +65,11 @@ public:
      */
     void setColumnWidths(const QHash<QByteArray, qreal>& columnWidths);
 
+    /**
+     * @return The column width that is required to show the role unclipped.
+     */
+    qreal preferredColumnWidth(const QByteArray& role) const;
+
 signals:
     /**
      * Is emitted if the width of a column has been adjusted by the user with the mouse
index 2f3058ac730cdd9934744692966840039d6b6507..18b37c246dfc1d888743b0f5ffc604aea4c8a24c 100644 (file)
 
 KItemListHeaderWidget::KItemListHeaderWidget(QGraphicsWidget* parent) :
     QGraphicsWidget(parent),
-    m_automaticColumnResizing(false),
+    m_automaticColumnResizing(true),
     m_model(0),
     m_columns(),
-    m_columnsWidths(),
+    m_columnWidths(),
+    m_preferredColumnWidths(),
     m_hoveredRoleIndex(-1),
     m_pressedRoleIndex(-1),
     m_roleOperation(NoRoleOperation),
@@ -98,6 +99,8 @@ bool KItemListHeaderWidget::automaticColumnResizing() const
 void KItemListHeaderWidget::setColumns(const QList<QByteArray>& roles)
 {
     m_columns = roles;
+    m_columnWidths.clear();
+    m_preferredColumnWidths.clear();
     update();
 }
 
@@ -113,15 +116,25 @@ void KItemListHeaderWidget::setColumnWidth(const QByteArray& role, qreal width)
         width = minWidth;
     }
 
-    if (m_columnsWidths.value(role) != width) {
-        m_columnsWidths.insert(role, width);
+    if (m_columnWidths.value(role) != width) {
+        m_columnWidths.insert(role, width);
         update();
     }
 }
 
 qreal KItemListHeaderWidget::columnWidth(const QByteArray& role) const
 {
-    return m_columnsWidths.value(role);
+    return m_columnWidths.value(role);
+}
+
+void KItemListHeaderWidget::setPreferredColumnWidth(const QByteArray& role, qreal width)
+{
+    m_preferredColumnWidths.insert(role, width);
+}
+
+qreal KItemListHeaderWidget::preferredColumnWidth(const QByteArray& role) const
+{
+    return m_preferredColumnWidths.value(role);
 }
 
 qreal KItemListHeaderWidget::minimumColumnWidth() const
@@ -146,7 +159,7 @@ void KItemListHeaderWidget::paint(QPainter* painter, const QStyleOptionGraphicsI
     qreal x = 0;
     int orderIndex = 0;
     foreach (const QByteArray& role, m_columns) {
-        const qreal roleWidth = m_columnsWidths.value(role);
+        const qreal roleWidth = m_columnWidths.value(role);
         const QRectF rect(x, 0, roleWidth, size().height());
         paintRole(painter, role, rect, orderIndex, widget);
         x += roleWidth;
@@ -250,7 +263,7 @@ void KItemListHeaderWidget::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
                 qreal roleX = 0;
                 for (int i = 0; i < roleIndex; ++i) {
                     const QByteArray role = m_columns[i];
-                    roleX += m_columnsWidths.value(role);
+                    roleX += m_columnWidths.value(role);
                 }
 
                 m_movingRole.xDec = event->pos().x() - roleX;
@@ -263,12 +276,12 @@ void KItemListHeaderWidget::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
     case ResizeRoleOperation: {
         const QByteArray pressedRole = m_columns[m_pressedRoleIndex];
 
-        qreal previousWidth = m_columnsWidths.value(pressedRole);
+        qreal previousWidth = m_columnWidths.value(pressedRole);
         qreal currentWidth = previousWidth;
         currentWidth += event->pos().x() - event->lastPos().x();
         currentWidth = qMax(minimumColumnWidth(), currentWidth);
 
-        m_columnsWidths.insert(pressedRole, currentWidth);
+        m_columnWidths.insert(pressedRole, currentWidth);
         update();
 
         emit columnWidthChanged(pressedRole, currentWidth, previousWidth);
@@ -344,10 +357,10 @@ void KItemListHeaderWidget::slotSortOrderChanged(Qt::SortOrder current, Qt::Sort
 }
 
 void KItemListHeaderWidget::paintRole(QPainter* painter,
-                                const QByteArray& role,
-                                const QRectF& rect,
-                                int orderIndex,
-                                QWidget* widget) const
+                                      const QByteArray& role,
+                                      const QRectF& rect,
+                                      int orderIndex,
+                                      QWidget* widget) const
 {
     // The following code is based on the code from QHeaderView::paintSection().
     // Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
@@ -414,7 +427,7 @@ int KItemListHeaderWidget::roleIndexAt(const QPointF& pos) const
     qreal x = 0;
     foreach (const QByteArray& role, m_columns) {
         ++index;
-        x += m_columnsWidths.value(role);
+        x += m_columnWidths.value(role);
         if (pos.x() <= x) {
             break;
         }
@@ -428,7 +441,7 @@ bool KItemListHeaderWidget::isAboveRoleGrip(const QPointF& pos, int roleIndex) c
     qreal x = 0;
     for (int i = 0; i <= roleIndex; ++i) {
         const QByteArray role = m_columns[i];
-        x += m_columnsWidths.value(role);
+        x += m_columnWidths.value(role);
     }
 
     const int grip = style()->pixelMetric(QStyle::PM_HeaderGripMargin);
@@ -438,7 +451,7 @@ bool KItemListHeaderWidget::isAboveRoleGrip(const QPointF& pos, int roleIndex) c
 QPixmap KItemListHeaderWidget::createRolePixmap(int roleIndex) const
 {
     const QByteArray role = m_columns[roleIndex];
-    const qreal roleWidth = m_columnsWidths.value(role);
+    const qreal roleWidth = m_columnWidths.value(role);
     const QRect rect(0, 0, roleWidth, size().height());
 
     QImage image(rect.size(), QImage::Format_ARGB32_Premultiplied);
@@ -469,7 +482,7 @@ int KItemListHeaderWidget::targetOfMovingRole() const
     qreal targetLeft = 0;
     while (targetIndex < m_columns.count()) {
         const QByteArray role = m_columns[targetIndex];
-        const qreal targetWidth = m_columnsWidths.value(role);
+        const qreal targetWidth = m_columnWidths.value(role);
         const qreal targetRight = targetLeft + targetWidth - 1;
 
         const bool isInTarget = (targetWidth >= movingWidth &&
@@ -498,7 +511,7 @@ qreal KItemListHeaderWidget::roleXPosition(const QByteArray& role) const
             return x;
         }
 
-        x += m_columnsWidths.value(visibleRole);
+        x += m_columnWidths.value(visibleRole);
     }
 
     return -1;
index ea8bb1ef9c43eb685966658e229d437d41abf63e..e271060660f521ba1652e1daaf556e08a360a9da 100644 (file)
@@ -53,6 +53,12 @@ public:
     void setColumnWidth(const QByteArray& role, qreal width);
     qreal columnWidth(const QByteArray& role) const;
 
+    /**
+     * Sets the column-width that is required to show the role unclipped.
+     */
+    void setPreferredColumnWidth(const QByteArray& role, qreal width);
+    qreal preferredColumnWidth(const QByteArray& role) const;
+
     qreal minimumColumnWidth() const;
 
     virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0);
@@ -139,7 +145,8 @@ private:
     bool m_automaticColumnResizing;
     KItemModelBase* m_model;
     QList<QByteArray> m_columns;
-    QHash<QByteArray, qreal> m_columnsWidths;
+    QHash<QByteArray, qreal> m_columnWidths;
+    QHash<QByteArray, qreal> m_preferredColumnWidths;
 
     int m_hoveredRoleIndex;
     int m_pressedRoleIndex;
index ff1cbc39ae12a92bba3964dfcfcf054c7c3b6f3e..d8dd3e16f4dd69a631979e86a3bcdb52066706cb 100644 (file)
@@ -67,7 +67,6 @@ KItemListView::KItemListView(QGraphicsWidget* parent) :
     m_styleOption(),
     m_visibleItems(),
     m_visibleGroups(),
-    m_columnWidthsCache(),
     m_visibleCells(),
     m_sizeHintResolver(0),
     m_layouter(0),
@@ -177,7 +176,7 @@ void KItemListView::setItemSize(const QSizeF& itemSize)
 
     if (itemSize.isEmpty()) {
         if (m_headerWidget->automaticColumnResizing()) {
-            updateColumnWidthsCache();
+            updatePreferredColumnWidths();
         } else {
             // Only apply the changed height and respect the header widths
             // set by the user
@@ -282,10 +281,15 @@ void KItemListView::setVisibleRoles(const QList<QByteArray>& roles)
 
     if (m_headerWidget->isVisible()) {
         m_headerWidget->setColumns(roles);
-        m_headerWidget->setAutomaticColumnResizing(true);
     }
 
-    updateColumnWidthsCache();
+    if (m_itemSize.isEmpty()) {
+        updatePreferredColumnWidths();
+        if (!m_headerWidget->automaticColumnResizing()) {
+            applyColumnWidthsFromHeader();
+        }
+    }
+
     doLayout(NoAnimation);
 
     onVisibleRolesChanged(roles, previousRoles);
@@ -410,31 +414,20 @@ void KItemListView::setGeometry(const QRectF& rect)
 
     const QSizeF newSize = rect.size();
     if (m_itemSize.isEmpty()) {
-        // The item size is dynamic:
-        // Changing the geometry does not require to do an expensive
-        // update of the visible-roles sizes, only the stretched sizes
-        // need to be adjusted to the new size.
-        updateColumnWidthsForHeader();
-
-        if (!m_headerWidget->automaticColumnResizing()) {
-            QSizeF dynamicItemSize = m_layouter->itemSize();
-
-            if (m_itemSize.width() < 0) {
-                const qreal requiredWidth = columnWidthsSum();
-                if (newSize.width() > requiredWidth) {
-                    dynamicItemSize.setWidth(newSize.width());
-                }
-                const qreal headerWidth = qMax(newSize.width(), requiredWidth);
-                m_headerWidget->resize(headerWidth, m_headerWidget->size().height());
-            }
-
+        if (m_headerWidget->automaticColumnResizing()) {
+            resizeColumnWidths();
+        } else {
+            const qreal requiredWidth = columnWidthsSum();
+            const QSizeF dynamicItemSize(qMax(newSize.width(), requiredWidth),
+                                         m_itemSize.height());
             m_layouter->setItemSize(dynamicItemSize);
+            m_headerWidget->resize(dynamicItemSize.width(), m_headerWidget->size().height());
         }
 
         // Triggering a synchronous layout is fine from a performance point of view,
         // as with dynamic item sizes no moving animation must be done.
         m_layouter->setSize(newSize);
-        doLayout(Animation);
+        doLayout(NoAnimation);
     } else {
         const bool animate = !changesItemGridLayout(newSize,
                                                     m_layouter->itemSize(),
@@ -517,7 +510,7 @@ QSizeF KItemListView::itemSizeHint(int index) const
     return itemSize();
 }
 
-QHash<QByteArray, qreal> KItemListView::columnWidths(const KItemRangeList& itemRanges) const
+QHash<QByteArray, qreal> KItemListView::preferredColumnWidths(const KItemRangeList& itemRanges) const
 {
     Q_UNUSED(itemRanges);
     return QHash<QByteArray, qreal>();
@@ -616,7 +609,6 @@ bool KItemListView::isTransactionActive() const
 
 void KItemListView::setHeaderVisible(bool visible)
 {
-
     if (visible && !m_headerWidget->isVisible()) {
         m_headerWidget->setPos(0, 0);
         m_headerWidget->setModel(m_model);
@@ -632,8 +624,6 @@ void KItemListView::setHeaderVisible(bool visible)
         connect(m_headerWidget, SIGNAL(sortRoleChanged(QByteArray,QByteArray)),
                 this, SIGNAL(sortRoleChanged(QByteArray,QByteArray)));
 
-        m_headerWidget->setAutomaticColumnResizing(true);
-
         m_layouter->setHeaderHeight(m_headerWidget->size().height());
         m_headerWidget->setVisible(true);
     } else if (!visible && m_headerWidget->isVisible()) {
@@ -647,7 +637,6 @@ void KItemListView::setHeaderVisible(bool visible)
                    this, SIGNAL(sortRoleChanged(QByteArray,QByteArray)));
 
         m_layouter->setHeaderHeight(0);
-        m_headerWidget->setAutomaticColumnResizing(true);
         m_headerWidget->setVisible(false);
     }
 }
@@ -819,7 +808,9 @@ QList<KItemListWidget*> KItemListView::visibleItemListWidgets() const
 
 void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges)
 {
-    updateColumnWidthsCache(itemRanges);
+    if (m_itemSize.isEmpty()) {
+        updatePreferredColumnWidths(itemRanges);
+    }
 
     const bool hasMultipleRanges = (itemRanges.count() > 1);
     if (hasMultipleRanges) {
@@ -918,7 +909,9 @@ void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges)
 
 void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges)
 {
-    updateColumnWidthsCache();
+    if (m_itemSize.isEmpty()) {
+        updatePreferredColumnWidths();
+    }
 
     const bool hasMultipleRanges = (itemRanges.count() > 1);
     if (hasMultipleRanges) {
@@ -1049,8 +1042,8 @@ void KItemListView::slotItemsChanged(const KItemRangeList& itemRanges,
                                      const QSet<QByteArray>& roles)
 {
     const bool updateSizeHints = itemSizeHintUpdateRequired(roles);
-    if (updateSizeHints) {
-        updateColumnWidthsCache(itemRanges);
+    if (updateSizeHints && m_itemSize.isEmpty()) {
+        updatePreferredColumnWidths(itemRanges);
     }
 
     foreach (const KItemRange& itemRange, itemRanges) {
@@ -1226,27 +1219,12 @@ void KItemListView::slotHeaderColumnWidthChanged(const QByteArray& role,
                                                  qreal currentWidth,
                                                  qreal previousWidth)
 {
+    Q_UNUSED(role);
+    Q_UNUSED(currentWidth);
     Q_UNUSED(previousWidth);
 
     m_headerWidget->setAutomaticColumnResizing(false);
-
-    if (m_columnWidthsCache.contains(role)) {
-        m_columnWidthsCache.insert(role, currentWidth);
-
-        // Apply the new size to the layouter
-        const qreal requiredWidth = columnWidthsSum();
-        const QSizeF dynamicItemSize(qMax(size().width(), requiredWidth),
-                                     m_itemSize.height());
-        m_layouter->setItemSize(dynamicItemSize);
-
-        // Update the role sizes for all visible widgets
-        QHashIterator<int, KItemListWidget*> it(m_visibleItems);
-        while (it.hasNext()) {
-            it.next();
-            updateWidgetColumnWidths(it.value());
-        }
-        doLayout(NoAnimation);
-    }
+    applyColumnWidthsFromHeader();
 }
 
 void KItemListView::slotHeaderColumnMoved(const QByteArray& role,
@@ -1915,17 +1893,12 @@ bool KItemListView::useAlternateBackgrounds() const
 
 void KItemListView::applyColumnWidthsFromHeader()
 {
-    qreal roleWidthSum = 0;
-    foreach (const QByteArray& role, m_visibleRoles) {
-        const qreal width = m_headerWidget->columnWidth(role);
-        m_columnWidthsCache.insert(role, width);
-        roleWidthSum += width;
-    }
-
     // Apply the new size to the layouter
-    const QSizeF dynamicItemSize(qMax(size().width(), roleWidthSum),
+    const qreal requiredWidth = columnWidthsSum();
+    const QSizeF dynamicItemSize(qMax(size().width(), requiredWidth),
                                  m_itemSize.height());
     m_layouter->setItemSize(dynamicItemSize);
+    m_headerWidget->resize(dynamicItemSize.width(), m_headerWidget->size().height());
 
     // Update the role sizes for all visible widgets
     QHashIterator<int, KItemListWidget*> it(m_visibleItems);
@@ -1933,7 +1906,6 @@ void KItemListView::applyColumnWidthsFromHeader()
         it.next();
         updateWidgetColumnWidths(it.value());
     }
-    doLayout(NoAnimation);
 }
 
 void KItemListView::updateWidgetColumnWidths(KItemListWidget* widget)
@@ -1943,11 +1915,9 @@ void KItemListView::updateWidgetColumnWidths(KItemListWidget* widget)
     }
 }
 
-void KItemListView::updateColumnWidthsCache(const KItemRangeList& itemRanges)
+void KItemListView::updatePreferredColumnWidths(const KItemRangeList& itemRanges)
 {
-    if (!m_itemSize.isEmpty() || !m_headerWidget->automaticColumnResizing()) {
-        return;
-    }
+    Q_ASSERT(m_itemSize.isEmpty());
 
     const int itemCount = m_model->count();
     int rangesItemCount = 0;
@@ -1956,18 +1926,9 @@ void KItemListView::updateColumnWidthsCache(const KItemRangeList& itemRanges)
     }
 
     if (itemCount == rangesItemCount) {
-        m_columnWidthsCache = columnWidths(itemRanges);
-        if (m_headerWidget->isVisible()) {
-            // Assure the the sizes are not smaller than the minimum defined by the header
-            const qreal minHeaderRoleWidth = m_headerWidget->minimumColumnWidth();
-            QMutableHashIterator<QByteArray, qreal> it (m_columnWidthsCache);
-            while (it.hasNext()) {
-                it.next();
-                const qreal width = it.value();
-                if (width < minHeaderRoleWidth) {
-                    m_columnWidthsCache.insert(it.key(), minHeaderRoleWidth);
-                }
-            }
+        const QHash<QByteArray, qreal> preferredWidths = preferredColumnWidths(itemRanges);
+        foreach (const QByteArray& role, m_visibleRoles) {
+            m_headerWidget->setPreferredColumnWidth(role, preferredWidths.value(role));
         }
     } else {
         // Only a sub range of the roles need to be determined.
@@ -1976,15 +1937,15 @@ void KItemListView::updateColumnWidthsCache(const KItemRangeList& itemRanges)
         // expensive update might be required.
         bool updateRequired = false;
 
-        const QHash<QByteArray, qreal> updatedWidths = columnWidths(itemRanges);
+        const QHash<QByteArray, qreal> updatedWidths = preferredColumnWidths(itemRanges);
         QHashIterator<QByteArray, qreal> it(updatedWidths);
         while (it.hasNext()) {
             it.next();
             const QByteArray& role = it.key();
             const qreal updatedWidth = it.value();
-            const qreal currentWidth = m_columnWidthsCache.value(role);
+            const qreal currentWidth = m_headerWidget->preferredColumnWidth(role);
             if (updatedWidth > currentWidth) {
-                m_columnWidthsCache.insert(role, updatedWidth);
+                m_headerWidget->setPreferredColumnWidth(role, updatedWidth);
                 updateRequired = true;
             }
         }
@@ -1996,10 +1957,12 @@ void KItemListView::updateColumnWidthsCache(const KItemRangeList& itemRanges)
         }
     }
 
-    updateColumnWidthsForHeader();
+    if (m_header->automaticColumnResizing()) {
+        resizeColumnWidths();
+    }
 }
 
-void KItemListView::updateColumnWidthsCache()
+void KItemListView::updatePreferredColumnWidths()
 {
     if (!m_model) {
         return;
@@ -2007,15 +1970,14 @@ void KItemListView::updateColumnWidthsCache()
 
     const int itemCount = m_model->count();
     if (itemCount > 0) {
-        updateColumnWidthsCache(KItemRangeList() << KItemRange(0, itemCount));
+        updatePreferredColumnWidths(KItemRangeList() << KItemRange(0, itemCount));
     }
 }
 
-void KItemListView::updateColumnWidthsForHeader()
+void KItemListView::resizeColumnWidths()
 {
-    if (!m_itemSize.isEmpty() || !m_headerWidget->automaticColumnResizing() || m_visibleRoles.isEmpty()) {
-        return;
-    }
+    Q_ASSERT(m_itemSize.isEmpty());
+    Q_ASSERT(m_headerWidget->automaticColumnResizing());
 
     // Calculate the maximum size of an item by considering the
     // visible role sizes and apply them to the layouter. If the
@@ -2023,39 +1985,41 @@ void KItemListView::updateColumnWidthsForHeader()
     // first role will get stretched.
 
     foreach (const QByteArray& role, m_visibleRoles) {
-        m_headerWidget->setColumnWidth(role, m_columnWidthsCache.value(role));
+        const qreal preferredWidth = m_headerWidget->preferredColumnWidth(role);
+        m_headerWidget->setColumnWidth(role, preferredWidth);
     }
 
-    const QByteArray role = m_visibleRoles.first();
-    qreal firstColumnWidth = m_columnWidthsCache.value(role);
-
+    const QByteArray firstRole = m_visibleRoles.first();
+    qreal firstColumnWidth = m_headerWidget->columnWidth(firstRole);
     QSizeF dynamicItemSize = m_itemSize;
 
-    if (dynamicItemSize.width() <= 0) {
-        const qreal requiredWidth = columnWidthsSum();
-        const qreal availableWidth = size().width();
-        if (requiredWidth != availableWidth) {
-            // Stretch the first role to use the whole remaining width
-            firstColumnWidth += availableWidth - requiredWidth;
-
-            // TODO: A proper calculation of the minimum width depends on the implementation
-            // of KItemListWidget. Probably a kind of minimum size-hint should be introduced
-            // later.
-            const qreal minWidth = m_styleOption.iconSize * 2 + 200;
-            if (firstColumnWidth < minWidth) {
-                firstColumnWidth = minWidth;
-            }
-
-            m_headerWidget->setColumnWidth(role, firstColumnWidth);
+    qreal requiredWidth = columnWidthsSum();
+    const qreal availableWidth = size().width();
+    if (requiredWidth < availableWidth) {
+        // Stretch the first column to use the whole remaining width
+        firstColumnWidth += availableWidth - requiredWidth;
+        m_headerWidget->setColumnWidth(firstRole, firstColumnWidth);
+    } else if (requiredWidth > availableWidth) {
+        // Shrink the first column to be able to show as much other
+        // columns as possible
+        qreal shrinkedFirstColumnWidth = firstColumnWidth - requiredWidth + availableWidth;
+
+        // TODO: A proper calculation of the minimum width depends on the implementation
+        // of KItemListWidget. Probably a kind of minimum size-hint should be introduced
+        // later.
+        const qreal minWidth = m_styleOption.iconSize * 2 + 200;
+        if (shrinkedFirstColumnWidth < minWidth) {
+            shrinkedFirstColumnWidth = minWidth;
         }
-        dynamicItemSize.rwidth() = qMax(requiredWidth, availableWidth);
+
+        m_headerWidget->setColumnWidth(firstRole, shrinkedFirstColumnWidth);
+        requiredWidth -= firstColumnWidth - shrinkedFirstColumnWidth;
     }
 
-    m_layouter->setItemSize(dynamicItemSize);
+    dynamicItemSize.rwidth() = qMax(requiredWidth, availableWidth);
 
-    if (m_headerWidget->isVisible()) {
-        m_headerWidget->resize(dynamicItemSize.width(), m_headerWidget->size().height());
-    }
+    m_layouter->setItemSize(dynamicItemSize);
+    m_headerWidget->resize(dynamicItemSize.width(), m_headerWidget->size().height());
 
     // Update the role sizes for all visible widgets
     QHashIterator<int, KItemListWidget*> it(m_visibleItems);
@@ -2067,13 +2031,11 @@ void KItemListView::updateColumnWidthsForHeader()
 
 qreal KItemListView::columnWidthsSum() const
 {
-    qreal widthSum = 0;
-    QHashIterator<QByteArray, qreal> it(m_columnWidthsCache);
-    while (it.hasNext()) {
-        it.next();
-        widthSum += it.value();
+    qreal widthsSum = 0;
+    foreach (const QByteArray& role, m_visibleRoles) {
+        widthsSum += m_headerWidget->columnWidth(role);
     }
-    return widthSum;
+    return widthsSum;
 }
 
 QRectF KItemListView::headerBoundaries() const
index 70ba03061a6e49357dfb0d4deffcf8177fcddac6..e1433f684a2147526d58cc72d6308b1ecf33ff2b 100644 (file)
@@ -194,12 +194,12 @@ public:
 
     /**
      * @param itemRanges Items that must be checked for getting the widths of columns.
-     * @return           The width of the column of each visible role. The width will
+     * @return           The preferred width of the column of each visible role. The width will
      *                   be respected if the width of the item size is <= 0 (see
      *                   KItemListView::setItemSize()). Per default an empty hash
      *                   is returned.
      */
-    virtual QHash<QByteArray, qreal> columnWidths(const KItemRangeList& itemRanges) const;
+    virtual QHash<QByteArray, qreal> preferredColumnWidths(const KItemRangeList& itemRanges) const;
 
     /**
      * If set to true, items having child-items can be expanded to show the child-items as
@@ -372,9 +372,9 @@ private slots:
 
     /**
      * Is invoked if the column-width of one role in the header has
-     * been changed by the user. It is remembered that the user has modified
-     * the role-width, so that it won't be changed anymore automatically to
-     * calculate an optimized width.
+     * been changed by the user. The automatic resizing of columns
+     * will be turned off as soon as this method has been called at
+     * least once.
      */
     void slotHeaderColumnWidthChanged(const QByteArray& role,
                                       qreal currentWidth,
@@ -487,7 +487,7 @@ private:
     void updateGroupHeaderLayout(KItemListWidget* widget);
 
     /**
-     * Recycles the group-header from the widget.
+     * Recycles the group-header for the widget.
      */
     void recycleGroupHeaderForWidget(KItemListWidget* widget);
 
@@ -524,32 +524,34 @@ private:
      */
     bool useAlternateBackgrounds() const;
 
+    /**
+     * Applies the column-widths from m_headerWidget to the layout
+     * of the view.
+     */
     void applyColumnWidthsFromHeader();
 
     /**
-     * Applies the roles-sizes from m_stretchedVisibleRolesSizes
-     * to \a widget.
+     * Applies the column-widths from m_headerWidget to \a widget.
      */
     void updateWidgetColumnWidths(KItemListWidget* widget);
 
     /**
-     * Updates m_visibleRolesSizes by calling KItemListView::visibleRolesSizes().
-     * Nothing will be done if m_itemRect is not empty or custom header-widths
-     * are used (see m_useHeaderWidths). Also m_strechedVisibleRolesSizes will be adjusted
-     * to respect the available view-size.
+     * Updates the preferred column-widths of m_groupHeaderWidget by
+     * invoking KItemListView::columnWidths().
      */
-    void updateColumnWidthsCache(const KItemRangeList& itemRanges);
+    void updatePreferredColumnWidths(const KItemRangeList& itemRanges);
 
     /**
-     * Convenience method for updateVisibleRoleSizes(KItemRangeList() << KItemRange(0, m_model->count()).
+     * Convenience method for
+     * updateColumnWidthsCache(KItemRangeList() << KItemRange(0, m_model->count()).
      */
-    void updateColumnWidthsCache();
+    void updatePreferredColumnWidths();
 
     /**
-     * Updates the column widhts of the header based on m_columnWidthsCache and the available
-     * view-size.
+     * Resizes the column-widths of m_headerWidget based on the preferred widths
+     * and the vailable view-size.
      */
-    void updateColumnWidthsForHeader();
+    void resizeColumnWidths();
 
     /**
      * @return Sum of the widths of all columns.
@@ -645,8 +647,6 @@ private:
     QHash<int, KItemListWidget*> m_visibleItems;
     QHash<KItemListWidget*, KItemListGroupHeader*> m_visibleGroups;
 
-    QHash<QByteArray, qreal> m_columnWidthsCache; // Cache for columnWidths() result
-
     struct Cell
     {
         Cell() : column(-1), row(-1) {}
index 241f24fd41da236bb8b9a6c054be9587b4feec2f..8672b531bf356223af3b4f916440b132ea77c6f4 100644 (file)
@@ -830,18 +830,16 @@ void DolphinView::slotHeaderContextMenuRequested(const QPointF& pos)
 
     QAction* action = menu->exec(pos.toPoint());
     if (menu && action) {
+        KItemListHeader* header = view->header();
+
         if (action == autoAdjustWidthsAction) {
             // Clear the column-widths from the viewproperties and turn on
             // the automatic resizing of the columns
             props.setHeaderColumnWidths(QList<int>());
-            KItemListHeader* header = m_container->controller()->view()->header();
             header->setAutomaticColumnResizing(true);
         } else if (action == customWidthsAction) {
             // Apply the current column-widths as custom column-widths and turn
             // off the automatic resizing of the columns
-            const KItemListView* view = m_container->controller()->view();
-            KItemListHeader* header = view->header();
-
             QList<int> columnWidths;
             foreach (const QByteArray& role, view->visibleRoles()) {
                 columnWidths.append(header->columnWidth(role));
@@ -862,6 +860,11 @@ void DolphinView::slotHeaderContextMenuRequested(const QPointF& pos)
 
             view->setVisibleRoles(visibleRoles);
             props.setVisibleRoles(visibleRoles);
+
+            // Reset the stored column-widths, so that automatic resizing is
+            // used again.
+            props.setHeaderColumnWidths(QList<int>());
+            header->setAutomaticColumnResizing(true);
         }
     }