]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Allow resizing of columns by the user
authorPeter Penz <peter.penz19@gmail.com>
Fri, 23 Sep 2011 17:09:01 +0000 (19:09 +0200)
committerPeter Penz <peter.penz19@gmail.com>
Fri, 23 Sep 2011 17:11:05 +0000 (19:11 +0200)
Still open:
- Column content is not clipped correctly
- First column is not automatically increased to the available
  width like in Dolphin 1.7

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

index c1d98c810fa31181d98fdadaa8dce443ea1130ca..6ff83b79331998406d616e1446571a152d3f1426 100644 (file)
@@ -396,7 +396,20 @@ QSizeF KFileItemListView::visibleRoleSizeHint(int index, const QByteArray& role)
     const QVariant value = model()->data(index).value(role);
     const QString text = value.toString();
     if (!text.isEmpty()) {
-        width = qMax(width, qreal(option.margin * 2 + option.fontMetrics.width(text)));
+        const qreal columnMargin = option.margin * 3;
+        width = qMax(width, qreal(2 * columnMargin + option.fontMetrics.width(text)));
+    }
+
+    if (role == "name") {
+        const QHash<QByteArray, QVariant> values = model()->data(index);
+        Q_ASSERT(values.contains("expansionLevel"));
+
+        // Increase the width by the expansion-toggle and the current expansion level
+        const int expansionLevel = values.value("expansionLevel", 0).toInt();
+        width += option.margin + expansionLevel * itemSize().height() + KIconLoader::SizeSmall;
+
+        // Increase the width by the required space for the icon
+        width += option.margin * 2 + option.iconSize;
     }
 
     return QSizeF(width, height);
index a9193fbc75a4b729381bcc67ca982a65902f2216..49c5db5fdaf9655e37c25588a7da51da3c74d016 100644 (file)
@@ -578,7 +578,9 @@ void KFileItemListWidget::updateDetailsLayoutTextCache()
     const int scaledIconSize = widgetHeight - 2 * option.margin;
     const int fontHeight = option.fontMetrics.height();
 
-    qreal x = m_expansionArea.right() + option.margin * 3 + scaledIconSize;
+    const qreal columnMargin = option.margin * 3;
+    const qreal firstColumnInc = m_expansionArea.right() + option.margin * 2 + scaledIconSize;
+    qreal x = firstColumnInc;
     const qreal y = qMax(qreal(option.margin), (widgetHeight - fontHeight) / 2);
 
     foreach (const QByteArray& role, m_sortedVisibleRoles) {
@@ -588,7 +590,7 @@ void KFileItemListWidget::updateDetailsLayoutTextCache()
         m_text[textId].setText(text);
 
         const qreal requiredWidth = option.fontMetrics.width(text);
-        m_textPos[textId] = QPointF(x, y);
+        m_textPos[textId] = QPointF(x + columnMargin, y);
 
         const qreal columnWidth = visibleRolesSizes().value(role, QSizeF(0, 0)).width();
         x += columnWidth;
@@ -596,16 +598,16 @@ void KFileItemListWidget::updateDetailsLayoutTextCache()
         switch (textId) {
         case Name: {
             m_textBoundingRect = QRectF(m_textPos[textId].x() - option.margin, 0,
-                                         requiredWidth + 2 * option.margin, size().height());
+                                        requiredWidth + 2 * option.margin, 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 -= m_expansionArea.right();
+            x -= firstColumnInc;
             break;
         }
         case Size:
             // The values for the size should be right aligned
-            m_textPos[textId].rx() += columnWidth - requiredWidth - 2 * option.margin;
+            m_textPos[textId].rx() += columnWidth - requiredWidth - 2 * columnMargin;
             break;
 
         default:
index c0b48c1a06fca681ef9fca53107d5de1e5ad1845..09b9bf08fbff8b7e832ce809857c3db7a98effdb 100644 (file)
@@ -186,12 +186,15 @@ void KItemListHeader::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
     if (m_roleOperation == ResizeRoleOperation) {
         const QByteArray pressedRole = m_visibleRoles.at(m_pressedRoleIndex);
 
-        qreal roleWidth = m_visibleRolesWidths.value(pressedRole);
-        roleWidth += event->pos().x() - event->lastPos().x();
-        roleWidth = qMax(minimumRoleWidth(), roleWidth);
+        qreal previousWidth = m_visibleRolesWidths.value(pressedRole);
+        qreal currentWidth = previousWidth;
+        currentWidth += event->pos().x() - event->lastPos().x();
+        currentWidth = qMax(minimumRoleWidth(), currentWidth);
 
-        m_visibleRolesWidths.insert(pressedRole, roleWidth);
+        m_visibleRolesWidths.insert(pressedRole, currentWidth);
         update();
+
+        emit visibleRoleWidthChanged(pressedRole, currentWidth, previousWidth);
     } else if ((event->pos() - m_pressedMousePos).manhattanLength() >= QApplication::startDragDistance()) {
         kDebug() << "Moving of role not supported yet";
         m_roleOperation = MoveRoleOperation;
index 79b988464163dea4dedfd93a81d1c0ed23171e66..43b7db59a909f5bccfdc186a161dab0a2bd52d00 100644 (file)
@@ -49,6 +49,15 @@ public:
 
     virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0);
 
+signals:
+    /**
+     * Is emitted if the width of a visible role has been adjusted by the user with the mouse
+     * (no signal is emitted if KItemListHeader::setVisibleRoles() is invoked).
+     */
+    void visibleRoleWidthChanged(const QByteArray& role,
+                                 qreal currentWidth,
+                                 qreal previousWidth);
+
 protected:
     virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
     virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);
index dd2915b8ea961b6d280570fb5ad708e026456090..ef429e544e82ce689523c32e01f7f3115cf923db 100644 (file)
@@ -76,7 +76,8 @@ KItemListView::KItemListView(QGraphicsWidget* parent) :
     m_mousePos(),
     m_autoScrollIncrement(0),
     m_autoScrollTimer(0),
-    m_header(0)
+    m_header(0),
+    m_useHeaderWidths(false)
 {
     setAcceptHoverEvents(true);
 
@@ -239,11 +240,18 @@ void KItemListView::setHeaderShown(bool show)
         m_header->setVisibleRoles(m_visibleRoles);
         m_header->setVisibleRolesWidths(headerRolesWidths());
         m_header->setZValue(1);
+
+        m_useHeaderWidths = false;
         updateHeaderWidth();
+
+        connect(m_header, SIGNAL(visibleRoleWidthChanged(QByteArray,qreal,qreal)),
+                this, SLOT(slotVisibleRoleWidthChanged(QByteArray,qreal,qreal)));
+
         m_layouter->setHeaderHeight(m_header->size().height());
     } else if (!show && m_header) {
         delete m_header;
         m_header = 0;
+        m_useHeaderWidths = false;
         m_layouter->setHeaderHeight(0);
     }
 }
@@ -572,7 +580,9 @@ void KItemListView::resizeEvent(QGraphicsSceneResizeEvent* event)
 
 void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges)
 {
-    markVisibleRolesSizesAsDirty();
+    if (!m_useHeaderWidths) {
+        markVisibleRolesSizesAsDirty();
+    }
 
     const bool hasMultipleRanges = (itemRanges.count() > 1);
     if (hasMultipleRanges) {
@@ -645,7 +655,9 @@ void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges)
 
 void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges)
 {
-    markVisibleRolesSizesAsDirty();
+    if (!m_useHeaderWidths) {
+        markVisibleRolesSizesAsDirty();
+    }
 
     const bool hasMultipleRanges = (itemRanges.count() > 1);
     if (hasMultipleRanges) {
@@ -867,6 +879,25 @@ void KItemListView::slotRubberBandActivationChanged(bool active)
     update();
 }
 
+void KItemListView::slotVisibleRoleWidthChanged(const QByteArray& role,
+                                                qreal currentWidth,
+                                                qreal previousWidth)
+{
+    Q_UNUSED(previousWidth);
+    Q_ASSERT(m_header);
+
+    m_useHeaderWidths = true;
+
+    if (m_visibleRolesSizes.contains(role)) {
+        QSizeF roleSize = m_visibleRolesSizes.value(role);
+        roleSize.setWidth(currentWidth);
+        m_visibleRolesSizes.insert(role, roleSize);
+    }
+
+    m_layouter->setItemSize(QSizeF()); // Forces an update in applyDynamicItemSize()
+    updateLayout();
+}
+
 void KItemListView::triggerAutoScrolling()
 {
     if (!m_autoScrollTimer) {
@@ -1267,6 +1298,7 @@ bool KItemListView::markVisibleRolesSizesAsDirty()
     if (dirty) {
         m_visibleRolesSizes.clear();
         m_layouter->setItemSize(QSizeF());
+        m_useHeaderWidths = false;
     }
     return dirty;
 }
@@ -1279,16 +1311,14 @@ void KItemListView::applyDynamicItemSize()
 
     if (m_visibleRolesSizes.isEmpty()) {
         m_visibleRolesSizes = visibleRoleSizes();
-        foreach (KItemListWidget* widget, visibleItemListWidgets()) {
-            widget->setVisibleRolesSizes(m_visibleRolesSizes);
-        }
-
         if (m_header) {
             m_header->setVisibleRolesWidths(headerRolesWidths());
         }
     }
 
     if (m_layouter->itemSize().isEmpty()) {
+        // Calculate the maximum size of an item by considering the
+        // visible role sizes and apply them to the layouter.
         qreal requiredWidth = 0;
         qreal requiredHeight = 0;
 
@@ -1309,6 +1339,11 @@ void KItemListView::applyDynamicItemSize()
         }
 
         m_layouter->setItemSize(dynamicItemSize);
+
+        // Update the role sizes for all visible widgets
+        foreach (KItemListWidget* widget, visibleItemListWidgets()) {
+            widget->setVisibleRolesSizes(m_visibleRolesSizes);
+        }
     }
 }
 
index da02e0bc232c7b5c5e50e6777e6423d0f3857d37..b088ea4873ca0f2271a5e053c24c37a103c774b7 100644 (file)
@@ -147,6 +147,12 @@ public:
     int lastVisibleIndex() const;
 
     virtual QSizeF itemSizeHint(int index) const;
+
+    /**
+     * @return The size of each visible role in case if KItemListView::itemSize()
+     *         is empty. This allows to have dynamic but equal role sizes between
+     *         all items. Per default an empty hash is returned.
+     */
     virtual QHash<QByteArray, QSizeF> visibleRoleSizes() const;
 
     /**
@@ -228,6 +234,16 @@ private slots:
     void slotRubberBandPosChanged();
     void slotRubberBandActivationChanged(bool active);
 
+    /**
+     * Is invoked if the visible role-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.
+     */
+    void slotVisibleRoleWidthChanged(const QByteArray& role,
+                                     qreal currentWidth,
+                                     qreal previousWidth);
+
     /**
      * Triggers the autoscrolling if autoScroll() is enabled by checking the
      * current mouse position. If the mouse position is within the autoscroll
@@ -354,6 +370,7 @@ private:
     QTimer* m_autoScrollTimer;
 
     KItemListHeader* m_header;
+    bool m_useHeaderWidths;
 
     friend class KItemListController;
 };