]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kstandarditemlistwidget.cpp
Update the "is cut" state of items if necessary
[dolphin.git] / src / kitemviews / kstandarditemlistwidget.cpp
index b429211b88c18244786819c73925c26e418578c9..54546b440716c811fa23f976988553ffa8f10df8 100644 (file)
@@ -57,13 +57,12 @@ 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 QString text = KStringHandler::preProcessWrap(itemText(index, view));
 
         const qreal itemWidth = view->itemSize().width();
         const qreal maxWidth = itemWidth - 2 * option.padding;
@@ -100,10 +99,18 @@ QSizeF KStandardItemListWidgetInformant::itemSizeHint(int index, const KItemList
         // 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);
+        const QList<QByteArray>& visibleRoles = view->visibleRoles();
+        const bool showOnlyTextRole = (visibleRoles.count() == 1) && (visibleRoles.first() == "text");
+
+        if (showOnlyTextRole) {
+            maximumRequiredWidth = option.fontMetrics.width(itemText(index, view));
+        } else {
+            const QHash<QByteArray, QVariant> values = view->model()->data(index);
+            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;
@@ -159,6 +166,11 @@ qreal KStandardItemListWidgetInformant::preferredRoleColumnWidth(const QByteArra
     return width;
 }
 
+QString KStandardItemListWidgetInformant::itemText(int index, const KItemListView* view) const
+{
+    return view->model()->data(index).value("text").toString();
+}
+
 QString KStandardItemListWidgetInformant::roleText(const QByteArray& role,
                                                    const QHash<QByteArray, QVariant>& values) const
 {
@@ -204,8 +216,13 @@ KStandardItemListWidget::~KStandardItemListWidget()
     qDeleteAll(m_textInfo);
     m_textInfo.clear();
 
-    delete m_roleEditor;
-    delete m_oldRoleEditor;
+    if (m_roleEditor) {
+        m_roleEditor->deleteLater();
+    }
+
+    if (m_oldRoleEditor) {
+        m_oldRoleEditor->deleteLater();
+    }
 }
 
 void KStandardItemListWidget::setLayout(Layout layout)
@@ -572,6 +589,12 @@ void KStandardItemListWidget::dataChanged(const QHash<QByteArray, QVariant>& cur
         dirtyRoles = roles;
     }
 
+    // The URL might have changed (i.e., if the sort order of the items has
+    // been changed). Therefore, the "is cut" state must be updated.
+    KFileItemClipboard* clipboard = KFileItemClipboard::instance();
+    const KUrl itemUrl = data().value("url").value<KUrl>();
+    m_isCut = clipboard->isCut(itemUrl);
+
     // The icon-state might depend from other roles and hence is
     // marked as dirty whenever a role has been changed
     dirtyRoles.insert("iconPixmap");
@@ -649,16 +672,15 @@ void KStandardItemListWidget::editedRoleChanged(const QByteArray& current, const
                        this, SLOT(slotRoleEditingCanceled(QByteArray,QVariant)));
             disconnect(m_roleEditor, SIGNAL(roleEditingFinished(QByteArray,QVariant)),
                        this, SLOT(slotRoleEditingFinished(QByteArray,QVariant)));
+
+            if (m_oldRoleEditor) {
+                m_oldRoleEditor->deleteLater();
+            }
             m_oldRoleEditor = m_roleEditor;
             m_roleEditor->hide();
             m_roleEditor = 0;
         }
         return;
-    } else if (m_oldRoleEditor) {
-        // Delete the old editor before constructing the new one to
-        // prevent a memory leak.
-        m_oldRoleEditor->deleteLater();
-        m_oldRoleEditor = 0;
     }
 
     Q_ASSERT(!m_roleEditor);
@@ -791,14 +813,14 @@ 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 KItemListStyleOption& option = styleOption();
             const qreal widgetHeight = size().height();
-            const qreal inc = (widgetHeight - KIconLoader::SizeSmall) / 2;
+            const qreal inc = (widgetHeight - option.iconSize) / 2;
             const qreal x = expandedParentsCount * widgetHeight + inc;
             const qreal y = inc;
-            m_expansionArea = QRectF(x, y, KIconLoader::SizeSmall, KIconLoader::SizeSmall);
+            m_expansionArea = QRectF(x, y, option.iconSize, option.iconSize);
             return;
         }
     }
@@ -839,29 +861,14 @@ void KStandardItemListWidget::updatePixmapCache()
                 // use a generic icon as fallback
                 iconName = QLatin1String("unknown");
             }
-            m_pixmap = pixmapForIcon(iconName, maxIconHeight);
+            const QStringList overlays = values["iconOverlays"].toStringList();
+            m_pixmap = pixmapForIcon(iconName, overlays, 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) {
             KIconEffect* effect = KIconLoader::global()->iconEffect();
             m_pixmap = effect->apply(m_pixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
@@ -1042,12 +1049,15 @@ void KStandardItemListWidget::updateIconsLayoutTextCache()
             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());
+                QString lastTextLine = nameText.mid(line.textStart());
                 lastTextLine = m_customizedFontMetrics.elidedText(lastTextLine,
                                                                   Qt::ElideRight,
-                                                                  line.naturalTextWidth() - 1);
+                                                                  maxWidth);
                 const QString elidedText = nameText.left(line.textStart()) + lastTextLine;
                 nameTextInfo->staticText.setText(elidedText);
+
+                const qreal lastLineWidth = m_customizedFontMetrics.boundingRect(lastTextLine).width();
+                nameWidth = qMax(nameWidth, lastLineWidth);
             }
             break;
         }
@@ -1318,14 +1328,17 @@ void KStandardItemListWidget::closeRoleEditor()
         scene()->views()[0]->parentWidget()->setFocus();
     }
 
+    if (m_oldRoleEditor) {
+        m_oldRoleEditor->deleteLater();
+    }
     m_oldRoleEditor = m_roleEditor;
     m_roleEditor->hide();
     m_roleEditor = 0;
 }
 
-QPixmap KStandardItemListWidget::pixmapForIcon(const QString& name, int size)
+QPixmap KStandardItemListWidget::pixmapForIcon(const QString& name, const QStringList& overlays, int size)
 {
-    const QString key = "KStandardItemListWidget:" % name  % ":" % QString::number(size);
+    const QString key = "KStandardItemListWidget:" % name % ":" % overlays.join(":") % ":" % QString::number(size);
     QPixmap pixmap;
 
     if (!QPixmapCache::find(key, pixmap)) {
@@ -1355,6 +1368,20 @@ QPixmap KStandardItemListWidget::pixmapForIcon(const QString& name, int size)
             KPixmapModifier::scale(pixmap, QSize(size, size));
         }
 
+        // 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, pixmap, KIconLoader::Desktop);
+                break;
+            }
+        }
+
         QPixmapCache::insert(key, pixmap);
     }