]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kfileitemlistview.cpp
Revert the 2.0 decision to always use KB for file-sizes
[dolphin.git] / src / kitemviews / kfileitemlistview.cpp
index 89fec9d0f8b28e1afbbb1193784df100951671da..11760fed1cc9f285d1652f9493f817ee9c9df664 100644 (file)
@@ -46,8 +46,7 @@ KFileItemListView::KFileItemListView(QGraphicsWidget* parent) :
     m_itemLayout(IconsLayout),
     m_modelRolesUpdater(0),
     m_updateVisibleIndexRangeTimer(0),
-    m_updateIconSizeTimer(0),
-    m_minimumRolesWidths()
+    m_updateIconSizeTimer(0)
 {
     setAcceptDrops(true);
 
@@ -66,8 +65,6 @@ KFileItemListView::KFileItemListView(QGraphicsWidget* parent) :
     connect(m_updateIconSizeTimer, SIGNAL(timeout()), this, SLOT(updateIconSize()));
 
     setVisibleRoles(QList<QByteArray>() << "name");
-
-    updateMinimumRolesWidths();
 }
 
 KFileItemListView::~KFileItemListView()
@@ -85,19 +82,38 @@ KFileItemListView::~KFileItemListView()
 void KFileItemListView::setPreviewsShown(bool show)
 {
     if (m_modelRolesUpdater) {
-        m_modelRolesUpdater->setPreviewShown(show);
+        m_modelRolesUpdater->setPreviewsShown(show);
     }
 }
 
 bool KFileItemListView::previewsShown() const
 {
-    return m_modelRolesUpdater->isPreviewShown();
+    return m_modelRolesUpdater ? m_modelRolesUpdater->previewsShown() : false;
+}
+
+void KFileItemListView::setEnlargeSmallPreviews(bool enlarge)
+{
+    if (m_modelRolesUpdater) {
+        m_modelRolesUpdater->setEnlargeSmallPreviews(enlarge);
+    }
+}
+
+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();
     }
 }
@@ -119,126 +135,6 @@ QStringList KFileItemListView::enabledPlugins() const
     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.margin;
-        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.margin * 4;
-        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.margin * 4 + option.iconSize + maximumRequiredWidth;
-        const qreal height = option.margin * 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.margin * 2 + qMax(option.iconSize, option.fontMetrics.height());
-        return QSizeF(-1, height);
-    }
-
-    default:
-        Q_ASSERT(false);
-        break;
-    }
-
-    return QSize();
-}
-
-QHash<QByteArray, QSizeF> KFileItemListView::visibleRolesSizes(const KItemRangeList& itemRanges) const
-{
-    QElapsedTimer timer;
-    timer.start();
-
-    QHash<QByteArray, QSizeF> sizes;
-
-    int calculatedItemCount = 0;
-    bool maxTimeExceeded = false;
-    foreach (const KItemRange& itemRange, itemRanges) {
-        const int startIndex = itemRange.index;
-        const int endIndex = startIndex + itemRange.count - 1;
-
-        for (int i = startIndex; i <= endIndex; ++i) {
-            foreach (const QByteArray& visibleRole, visibleRoles()) {
-                QSizeF maxSize = sizes.value(visibleRole, QSizeF(0, 0));
-                const QSizeF itemSize = visibleRoleSizeHint(i, visibleRole);
-                maxSize = maxSize.expandedTo(itemSize);
-                sizes.insert(visibleRole, maxSize);
-            }
-
-            if (calculatedItemCount > 100 && timer.elapsed() > 200) {
-                // When having several thousands of items calculating the sizes can get
-                // very expensive. We accept a possibly too small role-size in favour
-                // of having no blocking user interface.
-                #ifdef KFILEITEMLISTVIEW_DEBUG
-                    kDebug() << "Timer exceeded, stopped after" << calculatedItemCount << "items";
-                #endif
-                maxTimeExceeded = true;
-                break;
-            }
-            ++calculatedItemCount;
-        }
-        if (maxTimeExceeded) {
-            break;
-        }
-    }
-
-#ifdef KFILEITEMLISTVIEW_DEBUG
-    int rangesItemCount = 0;
-    foreach (const KItemRange& itemRange, itemRanges) {
-        rangesItemCount += itemRange.count;
-    }
-    kDebug() << "[TIME] Calculated dynamic item size for " << rangesItemCount << "items:" << timer.elapsed();
-#endif
-    return sizes;
-}
-
-bool KFileItemListView::supportsItemExpanding() const
-{
-    return m_itemLayout == DetailsLayout;
-}
-
 QPixmap KFileItemListView::createDragPixmap(const QSet<int>& indexes) const
 {
     if (!model()) {
@@ -321,8 +217,7 @@ void KFileItemListView::initializeItemListWidget(KItemListWidget* item)
     default:            Q_ASSERT(false); break;
     }
 
-    fileItemListWidget->setAlternatingBackgroundColors(m_itemLayout == DetailsLayout &&
-                                                       visibleRoles().count() > 1);
+    fileItemListWidget->setSupportsItemExpanding(supportsItemExpanding());
 }
 
 bool KFileItemListView::itemSizeHintUpdateRequired(const QSet<QByteArray>& changedRoles) const
@@ -347,8 +242,7 @@ void KFileItemListView::onModelChanged(KItemModelBase* current, KItemModelBase*
 
     delete m_modelRolesUpdater;
     m_modelRolesUpdater = new KFileItemModelRolesUpdater(static_cast<KFileItemModel*>(current), this);
-    const int size = styleOption().iconSize;
-    m_modelRolesUpdater->setIconSize(QSize(size, size));
+    m_modelRolesUpdater->setIconSize(availableIconSize());
 
     applyRolesToModel();
 }
@@ -379,19 +273,6 @@ void KFileItemListView::onVisibleRolesChanged(const QList<QByteArray>& current,
     Q_UNUSED(current);
     Q_UNUSED(previous);
     applyRolesToModel();
-
-    if (m_itemLayout == DetailsLayout) {
-        // Only enable the alternating background colors if more than one role
-        // is visible
-        const int previousCount = previous.count();
-        const int currentCount = current.count();
-        if ((previousCount <= 1 && currentCount > 1) || (previousCount > 1 && currentCount <= 1)) {
-            const bool enabled = (currentCount > 1);
-            foreach (KItemListWidget* widget, visibleItemListWidgets()) {
-                widget->setAlternatingBackgroundColors(enabled);
-            }
-        }
-    }
 }
 
 void KFileItemListView::onStyleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous)
@@ -401,6 +282,13 @@ void KFileItemListView::onStyleOptionChanged(const KItemListStyleOption& current
     triggerIconSizeUpdate();
 }
 
+void KFileItemListView::onSupportsItemExpandingChanged(bool supportsExpanding)
+{
+    Q_UNUSED(supportsExpanding);
+    applyRolesToModel();
+    updateLayoutOfVisibleItems();
+}
+
 void KFileItemListView::onTransactionBegin()
 {
     m_modelRolesUpdater->setPaused(true);
@@ -464,8 +352,7 @@ void KFileItemListView::updateVisibleIndexRange()
         // of the icon-size before unpausing m_modelRolesUpdater. This prevents
         // an unnecessary expensive recreation of all previews afterwards.
         m_updateIconSizeTimer->stop();
-        const KItemListStyleOption& option = styleOption();
-        m_modelRolesUpdater->setIconSize(QSize(option.iconSize, option.iconSize));
+        m_modelRolesUpdater->setIconSize(availableIconSize());
     }
 
     m_modelRolesUpdater->setPaused(isTransactionActive());
@@ -487,8 +374,7 @@ void KFileItemListView::updateIconSize()
         return;
     }
 
-    const KItemListStyleOption& option = styleOption();
-    m_modelRolesUpdater->setIconSize(QSize(option.iconSize, option.iconSize));
+    m_modelRolesUpdater->setIconSize(availableIconSize());
 
     if (m_updateVisibleIndexRangeTimer->isActive()) {
         // If the visibility-index-range update is pending do an immediate update
@@ -504,32 +390,6 @@ void KFileItemListView::updateIconSize()
     updateTimersInterval();
 }
 
-QSizeF KFileItemListView::visibleRoleSizeHint(int index, const QByteArray& role) const
-{
-    const KItemListStyleOption& option = styleOption();
-
-    qreal width = m_minimumRolesWidths.value(role, 0);
-    const qreal height = option.margin * 2 + option.fontMetrics.height();
-
-    const QHash<QByteArray, QVariant> values = model()->data(index);
-    const QString text = KFileItemListWidget::roleText(role, values);
-    if (!text.isEmpty()) {
-        const qreal columnMargin = option.margin * 3;
-        width = qMax(width, qreal(2 * columnMargin + option.fontMetrics.width(text)));
-    }
-
-    if (role == "name") {
-        // 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);
-}
-
 void KFileItemListView::updateLayoutOfVisibleItems()
 {
     if (!model()) {
@@ -559,15 +419,6 @@ void KFileItemListView::updateTimersInterval()
     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()) {
@@ -584,9 +435,10 @@ void KFileItemListView::applyRolesToModel()
     roles.insert("iconName");
     roles.insert("name");
     roles.insert("isDir");
-    if (m_itemLayout == DetailsLayout) {
+    if (supportsItemExpanding()) {
         roles.insert("isExpanded");
-        roles.insert("expansionLevel");
+        roles.insert("isExpandable");
+        roles.insert("expandedParentsCount");
     }
 
     // Assure that the role that is used for sorting will be determined
@@ -596,4 +448,16 @@ void KFileItemListView::applyRolesToModel()
     m_modelRolesUpdater->setRoles(roles);
 }
 
+QSize KFileItemListView::availableIconSize() const
+{
+    const KItemListStyleOption& option = styleOption();
+    const int iconSize = option.iconSize;
+    if (m_itemLayout == IconsLayout) {
+        const int maxIconWidth = itemSize().width() - 2 * option.padding;
+        return QSize(maxIconWidth, iconSize);
+    }
+
+    return QSize(iconSize, iconSize);
+}
+
 #include "kfileitemlistview.moc"