X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/5f57256a2f293622c7a10844adae29190907b9eb..8bc7f72a731904f4cc0669333e5db39613246e9e:/src/kitemviews/kstandarditemlistwidget.cpp diff --git a/src/kitemviews/kstandarditemlistwidget.cpp b/src/kitemviews/kstandarditemlistwidget.cpp index aa12f884c..3106b47b4 100644 --- a/src/kitemviews/kstandarditemlistwidget.cpp +++ b/src/kitemviews/kstandarditemlistwidget.cpp @@ -1,46 +1,29 @@ -/*************************************************************************** - * Copyright (C) 2012 by Peter Penz * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ +/* + * SPDX-FileCopyrightText: 2012 Peter Penz + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ #include "kstandarditemlistwidget.h" #include "kfileitemlistview.h" #include "kfileitemmodel.h" +#include "private/kfileitemclipboard.h" +#include "private/kitemlistroleeditor.h" +#include "private/kpixmapmodifier.h" -#include #include #include #include #include -#include "private/kfileitemclipboard.h" -#include "private/kitemlistroleeditor.h" -#include "private/kpixmapmodifier.h" - +#include #include #include #include -#include -#include -#include -#include -#include #include +#include +#include // #define KSTANDARDITEMLISTWIDGET_DEBUG @@ -53,18 +36,18 @@ KStandardItemListWidgetInformant::~KStandardItemListWidgetInformant() { } -void KStandardItemListWidgetInformant::calculateItemSizeHints(QVector& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const +void KStandardItemListWidgetInformant::calculateItemSizeHints(QVector>& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const { switch (static_cast(view)->itemLayout()) { - case KStandardItemListWidget::IconsLayout: + case KStandardItemListView::IconsLayout: calculateIconsLayoutItemSizeHints(logicalHeightHints, logicalWidthHint, view); break; - case KStandardItemListWidget::CompactLayout: + case KStandardItemListView::CompactLayout: calculateCompactLayoutItemSizeHints(logicalHeightHints, logicalWidthHint, view); break; - case KStandardItemListWidget::DetailsLayout: + case KStandardItemListView::DetailsLayout: calculateDetailsLayoutItemSizeHints(logicalHeightHints, logicalWidthHint, view); break; @@ -93,7 +76,7 @@ qreal KStandardItemListWidgetInformant::preferredRoleColumnWidth(const QByteArra // If current item is a link, we use the customized link font metrics instead of the normal font metrics. const QFontMetrics& fontMetrics = itemIsLink(index, view) ? linkFontMetrics : normalFontMetrics; - width += fontMetrics.width(text); + width += fontMetrics.horizontalAdvance(text); if (role == "text") { if (view->supportsItemExpanding()) { @@ -118,8 +101,8 @@ QString KStandardItemListWidgetInformant::itemText(int index, const KItemListVie bool KStandardItemListWidgetInformant::itemIsLink(int index, const KItemListView* view) const { - Q_UNUSED(index); - Q_UNUSED(view); + Q_UNUSED(index) + Q_UNUSED(view) return false; } @@ -138,7 +121,7 @@ QFont KStandardItemListWidgetInformant::customizedFontForLinks(const QFont& base return baseFont; } -void KStandardItemListWidgetInformant::calculateIconsLayoutItemSizeHints(QVector& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const +void KStandardItemListWidgetInformant::calculateIconsLayoutItemSizeHints(QVector>& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const { const KItemListStyleOption& option = view->styleOption(); const QFont& normalFont = option.font; @@ -155,7 +138,7 @@ void KStandardItemListWidgetInformant::calculateIconsLayoutItemSizeHints(QVector textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); for (int index = 0; index < logicalHeightHints.count(); ++index) { - if (logicalHeightHints.at(index) > 0.0) { + if (logicalHeightHints.at(index).first > 0.0) { continue; } @@ -163,7 +146,7 @@ void KStandardItemListWidgetInformant::calculateIconsLayoutItemSizeHints(QVector const QFont& font = itemIsLink(index, view) ? linkFont : normalFont; const QString& text = KStringHandler::preProcessWrap(itemText(index, view)); - + // Calculate the number of lines required for wrapping the name qreal textHeight = 0; QTextLayout layout(text, font); @@ -171,6 +154,7 @@ void KStandardItemListWidgetInformant::calculateIconsLayoutItemSizeHints(QVector layout.beginLayout(); QTextLine line; int lineCount = 0; + bool isElided = false; while ((line = layout.createLine()).isValid()) { line.setLineWidth(maxWidth); line.naturalTextWidth(); @@ -178,6 +162,7 @@ void KStandardItemListWidgetInformant::calculateIconsLayoutItemSizeHints(QVector ++lineCount; if (lineCount == option.maxTextLines) { + isElided = layout.createLine().isValid(); break; } } @@ -186,13 +171,14 @@ void KStandardItemListWidgetInformant::calculateIconsLayoutItemSizeHints(QVector // Add one line for each additional information textHeight += additionalRolesSpacing; - logicalHeightHints[index] = textHeight + spacingAndIconHeight; + logicalHeightHints[index].first = textHeight + spacingAndIconHeight; + logicalHeightHints[index].second = isElided; } logicalWidthHint = itemWidth; } -void KStandardItemListWidgetInformant::calculateCompactLayoutItemSizeHints(QVector& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const +void KStandardItemListWidgetInformant::calculateCompactLayoutItemSizeHints(QVector>& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const { const KItemListStyleOption& option = view->styleOption(); const QFontMetrics& normalFontMetrics = option.fontMetrics; @@ -207,7 +193,7 @@ void KStandardItemListWidgetInformant::calculateCompactLayoutItemSizeHints(QVect const QFontMetrics linkFontMetrics(customizedFontForLinks(option.font)); for (int index = 0; index < logicalHeightHints.count(); ++index) { - if (logicalHeightHints.at(index) > 0.0) { + if (logicalHeightHints.at(index).first > 0.0) { continue; } @@ -219,12 +205,12 @@ void KStandardItemListWidgetInformant::calculateCompactLayoutItemSizeHints(QVect qreal maximumRequiredWidth = 0.0; if (showOnlyTextRole) { - maximumRequiredWidth = fontMetrics.width(itemText(index, view)); + maximumRequiredWidth = fontMetrics.horizontalAdvance(itemText(index, view)); } else { const QHash& values = view->model()->data(index); - foreach (const QByteArray& role, visibleRoles) { + for (const QByteArray& role : visibleRoles) { const QString& text = roleText(role, values); - const qreal requiredWidth = fontMetrics.width(text); + const qreal requiredWidth = fontMetrics.horizontalAdvance(text); maximumRequiredWidth = qMax(maximumRequiredWidth, requiredWidth); } } @@ -234,22 +220,37 @@ void KStandardItemListWidgetInformant::calculateCompactLayoutItemSizeHints(QVect width = maxWidth; } - logicalHeightHints[index] = width; + logicalHeightHints[index].first = width; } logicalWidthHint = height; } -void KStandardItemListWidgetInformant::calculateDetailsLayoutItemSizeHints(QVector& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const +void KStandardItemListWidgetInformant::calculateDetailsLayoutItemSizeHints(QVector>& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const { const KItemListStyleOption& option = view->styleOption(); - const qreal height = option.padding * 2 + qMax(option.iconSize, option.fontMetrics.height()); - logicalHeightHints.fill(height); + + float zoomLevel = 1; + if (option.iconSize >= KIconLoader::SizeEnormous) { + zoomLevel = 2; + } else if (option.iconSize >= KIconLoader::SizeHuge) { + zoomLevel = 1.8; + } else if (option.iconSize >= KIconLoader::SizeLarge) { + zoomLevel = 1.6; + } else if (option.iconSize >= KIconLoader::SizeMedium) { + zoomLevel = 1.4; + } else if (option.iconSize >= KIconLoader::SizeSmallMedium) { + zoomLevel = 1.2; + } + + const qreal contentHeight = qMax(option.iconSize, zoomLevel * option.fontMetrics.height()); + logicalHeightHints.fill(std::make_pair(contentHeight + 2 * option.padding, false)); logicalWidthHint = -1.0; } KStandardItemListWidget::KStandardItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) : KItemListWidget(informant, parent), + m_textInfo(), m_isCut(false), m_isHidden(false), m_customizedFont(), @@ -265,7 +266,6 @@ KStandardItemListWidget::KStandardItemListWidget(KItemListWidgetInformant* infor m_scaledPixmapSize(), m_iconRect(), m_hoverPixmap(), - m_textInfo(), m_textRect(), m_sortedVisibleRoles(), m_expansionArea(), @@ -332,7 +332,7 @@ void KStandardItemListWidget::paint(QPainter* painter, const QStyleOptionGraphic } const KItemListStyleOption& itemListStyleOption = styleOption(); - if (isHovered()) { + if (isHovered() && !m_pixmap.isNull()) { if (hoverOpacity() < 1.0) { /* * Linear interpolation between m_pixmap and m_hoverPixmap. @@ -375,7 +375,7 @@ void KStandardItemListWidget::paint(QPainter* painter, const QStyleOptionGraphic } else { drawPixmap(painter, m_hoverPixmap); } - } else { + } else if (!m_pixmap.isNull()) { drawPixmap(painter, m_pixmap); } @@ -483,7 +483,7 @@ QRectF KStandardItemListWidget::textFocusRect() const const KItemListStyleOption& option = styleOption(); if (option.extendedSelectionRegion) { const QString text = textInfo->staticText.text(); - rect.setWidth(m_customizedFontMetrics.width(text) + 2 * option.padding); + rect.setWidth(m_customizedFontMetrics.horizontalAdvance(text) + 2 * option.padding); } return rect; @@ -599,13 +599,20 @@ void KStandardItemListWidget::invalidateCache() m_dirtyContent = true; } +void KStandardItemListWidget::invalidateIconCache() +{ + m_dirtyContent = true; + m_dirtyContentRoles.insert("iconPixmap"); + m_dirtyContentRoles.insert("iconOverlays"); +} + void KStandardItemListWidget::refreshCache() { } bool KStandardItemListWidget::isRoleRightAligned(const QByteArray& role) const { - Q_UNUSED(role); + Q_UNUSED(role) return false; } @@ -670,13 +677,14 @@ QString KStandardItemListWidget::roleText(const QByteArray& role, void KStandardItemListWidget::dataChanged(const QHash& current, const QSet& roles) { - Q_UNUSED(current); + Q_UNUSED(current) m_dirtyContent = true; QSet dirtyRoles; if (roles.isEmpty()) { - dirtyRoles = visibleRoles().toSet(); + const auto visibleRoles = this->visibleRoles(); + dirtyRoles = QSet(visibleRoles.constBegin(), visibleRoles.constEnd()); } else { dirtyRoles = roles; } @@ -702,7 +710,7 @@ void KStandardItemListWidget::dataChanged(const QHash& cur void KStandardItemListWidget::visibleRolesChanged(const QList& current, const QList& previous) { - Q_UNUSED(previous); + Q_UNUSED(previous) m_sortedVisibleRoles = current; m_dirtyLayout = true; } @@ -711,38 +719,38 @@ void KStandardItemListWidget::columnWidthChanged(const QByteArray& role, qreal current, qreal previous) { - Q_UNUSED(role); - Q_UNUSED(current); - Q_UNUSED(previous); + Q_UNUSED(role) + Q_UNUSED(current) + Q_UNUSED(previous) m_dirtyLayout = true; } void KStandardItemListWidget::styleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous) { - Q_UNUSED(current); - Q_UNUSED(previous); + Q_UNUSED(current) + Q_UNUSED(previous) updateAdditionalInfoTextColor(); m_dirtyLayout = true; } void KStandardItemListWidget::hoveredChanged(bool hovered) { - Q_UNUSED(hovered); + Q_UNUSED(hovered) m_dirtyLayout = true; } void KStandardItemListWidget::selectedChanged(bool selected) { - Q_UNUSED(selected); + Q_UNUSED(selected) updateAdditionalInfoTextColor(); m_dirtyContent = true; } void KStandardItemListWidget::siblingsInformationChanged(const QBitArray& current, const QBitArray& previous) { - Q_UNUSED(current); - Q_UNUSED(previous); + Q_UNUSED(current) + Q_UNUSED(previous) m_dirtyLayout = true; } @@ -753,12 +761,12 @@ int KStandardItemListWidget::selectionLength(const QString& text) const void KStandardItemListWidget::editedRoleChanged(const QByteArray& current, const QByteArray& previous) { - Q_UNUSED(previous); + Q_UNUSED(previous) QGraphicsView* parent = scene()->views()[0]; if (current.isEmpty() || !parent || current != "text") { if (m_roleEditor) { - emit roleEditingCanceled(index(), current, data().value(current)); + Q_EMIT roleEditingCanceled(index(), current, data().value(current)); disconnect(m_roleEditor, &KItemListRoleEditor::roleEditingCanceled, this, &KStandardItemListWidget::slotRoleEditingCanceled); @@ -781,6 +789,7 @@ void KStandardItemListWidget::editedRoleChanged(const QByteArray& current, const m_roleEditor = new KItemListRoleEditor(parent); m_roleEditor->setRole(current); + m_roleEditor->setAllowUpDownKeyChainEdit(m_layout != IconsLayout); m_roleEditor->setFont(styleOption().font); const QString text = data().value(current).toString(); @@ -883,7 +892,7 @@ void KStandardItemListWidget::slotRoleEditingCanceled(const QByteArray& role, const QVariant& value) { closeRoleEditor(); - emit roleEditingCanceled(index(), role, value); + Q_EMIT roleEditingCanceled(index(), role, value); setEditedRole(QByteArray()); } @@ -891,7 +900,7 @@ void KStandardItemListWidget::slotRoleEditingFinished(const QByteArray& role, const QVariant& value) { closeRoleEditor(); - emit roleEditingFinished(index(), role, value); + Q_EMIT roleEditingFinished(index(), role, value); setEditedRole(QByteArray()); } @@ -961,7 +970,34 @@ void KStandardItemListWidget::updatePixmapCache() } if (updatePixmap) { - m_pixmap = values["iconPixmap"].value(); + m_pixmap = QPixmap(); + + int sequenceIndex = hoverSequenceIndex(); + + if (values.contains("hoverSequencePixmaps")) { + // Use one of the hover sequence pixmaps instead of the default + // icon pixmap. + + const QVector pixmaps = values["hoverSequencePixmaps"].value>(); + + if (values.contains("hoverSequenceWraparoundPoint")) { + const float wap = values["hoverSequenceWraparoundPoint"].toFloat(); + if (wap >= 1.0f) { + sequenceIndex %= static_cast(wap); + } + } + + const int loadedIndex = qMax(qMin(sequenceIndex, pixmaps.size()-1), 0); + + if (loadedIndex != 0) { + m_pixmap = pixmaps[loadedIndex]; + } + } + + if (m_pixmap.isNull()) { + m_pixmap = values["iconPixmap"].value(); + } + if (m_pixmap.isNull()) { // Use the icon that fits to the MIME-type QString iconName = values["iconName"].toString(); @@ -971,7 +1007,7 @@ void KStandardItemListWidget::updatePixmapCache() iconName = QStringLiteral("unknown"); } const QStringList overlays = values["iconOverlays"].toStringList(); - m_pixmap = pixmapForIcon(iconName, overlays, maxIconHeight, isSelected() && isActiveWindow() ? QIcon::Selected : QIcon::Normal); + m_pixmap = pixmapForIcon(iconName, overlays, maxIconHeight, m_layout != IconsLayout && isActiveWindow() && isSelected() ? QIcon::Selected : QIcon::Normal); } else if (m_pixmap.width() / m_pixmap.devicePixelRatio() != maxIconWidth || m_pixmap.height() / m_pixmap.devicePixelRatio() != maxIconHeight) { // A custom pixmap has been applied. Assure that the pixmap @@ -979,6 +1015,11 @@ void KStandardItemListWidget::updatePixmapCache() KPixmapModifier::scale(m_pixmap, QSize(maxIconWidth, maxIconHeight) * qApp->devicePixelRatio()); } + if (m_pixmap.isNull()) { + m_hoverPixmap = QPixmap(); + return; + } + if (m_isCut) { KIconEffect* effect = KIconLoader::global()->iconEffect(); m_pixmap = effect->apply(m_pixmap, KIconLoader::Desktop, KIconLoader::DisabledState); @@ -991,6 +1032,10 @@ void KStandardItemListWidget::updatePixmapCache() if (m_layout == IconsLayout && isSelected()) { const QColor color = palette().brush(QPalette::Normal, QPalette::Highlight).color(); QImage image = m_pixmap.toImage(); + if (image.isNull()) { + m_hoverPixmap = QPixmap(); + return; + } KIconEffect::colorize(image, color, 0.8f); m_pixmap = QPixmap::fromImage(image); } @@ -1016,19 +1061,26 @@ void KStandardItemListWidget::updatePixmapCache() const int maxScaledIconHeight = scaledIconSize; m_scaledPixmapSize = m_pixmap.size(); - m_scaledPixmapSize.scale(maxScaledIconWidth, maxScaledIconHeight, Qt::KeepAspectRatio); + m_scaledPixmapSize.scale(maxScaledIconWidth * qApp->devicePixelRatio(), maxScaledIconHeight * qApp->devicePixelRatio(), Qt::KeepAspectRatio); + m_scaledPixmapSize = m_scaledPixmapSize / qApp->devicePixelRatio(); if (iconOnTop) { // Center horizontally and align on bottom within the icon-area - m_pixmapPos.setX((widgetSize.width() - m_scaledPixmapSize.width()) / 2); + m_pixmapPos.setX((widgetSize.width() - m_scaledPixmapSize.width()) / 2.0); m_pixmapPos.setY(padding + scaledIconSize - m_scaledPixmapSize.height()); } else { // Center horizontally and vertically within the icon-area const TextInfo* textInfo = m_textInfo.value("text"); - m_pixmapPos.setX(textInfo->pos.x() - 2 * padding - - (scaledIconSize + m_scaledPixmapSize.width()) / 2); - m_pixmapPos.setY(padding - + (scaledIconSize - m_scaledPixmapSize.height()) / 2); + m_pixmapPos.setX(textInfo->pos.x() - 2.0 * padding + - (scaledIconSize + m_scaledPixmapSize.width()) / 2.0); + + // Derive icon's vertical center from the center of the text frame, including + // any necessary adjustment if the font's midline is offset from the frame center + const qreal midlineShift = m_customizedFontMetrics.height() / 2.0 + - m_customizedFontMetrics.descent() + - m_customizedFontMetrics.capHeight() / 2.0; + m_pixmapPos.setY(m_textRect.center().y() + midlineShift - m_scaledPixmapSize.height() / 2.0); + } m_iconRect = QRectF(m_pixmapPos, QSizeF(m_scaledPixmapSize)); @@ -1111,6 +1163,26 @@ void KStandardItemListWidget::updateTextsCache() } } +QString KStandardItemListWidget::elideRightKeepExtension(const QString &text, int elidingWidth) const +{ + const auto extensionIndex = text.lastIndexOf('.'); + if (extensionIndex != -1) { + // has file extension + const auto extensionLength = text.length() - extensionIndex; + const auto extensionWidth = m_customizedFontMetrics.horizontalAdvance(text.right(extensionLength)); + if (elidingWidth > extensionWidth && extensionLength < 6 && (float(extensionWidth) / float(elidingWidth)) < 0.3) { + // if we have room to display the file extension and the extension is not too long + QString ret = m_customizedFontMetrics.elidedText(text.chopped(extensionLength), + Qt::ElideRight, + elidingWidth - extensionWidth); + ret.append(text.rightRef(extensionLength)); + return ret; + } + } + return m_customizedFontMetrics.elidedText(text,Qt::ElideRight, + elidingWidth); +} + void KStandardItemListWidget::updateIconsLayoutTextCache() { // +------+ @@ -1162,13 +1234,11 @@ void KStandardItemListWidget::updateIconsLayoutTextCache() qreal lastLineWidth; do { QString lastTextLine = nameText.mid(line.textStart()); - lastTextLine = m_customizedFontMetrics.elidedText(lastTextLine, - Qt::ElideRight, - elidingWidth); + lastTextLine = elideRightKeepExtension(lastTextLine, elidingWidth); const QString elidedText = nameText.left(line.textStart()) + lastTextLine; nameTextInfo->staticText.setText(elidedText); - lastLineWidth = m_customizedFontMetrics.boundingRect(lastTextLine).width(); + lastLineWidth = m_customizedFontMetrics.horizontalAdvance(lastTextLine); // We do the text eliding in a loop with decreasing width (1 px / iteration) // to avoid problems related to different width calculation code paths @@ -1197,7 +1267,7 @@ void KStandardItemListWidget::updateIconsLayoutTextCache() // Calculate the position for each additional information qreal y = nameTextInfo->pos.y() + nameHeight; - foreach (const QByteArray& role, m_sortedVisibleRoles) { + for (const QByteArray& role : qAsConst(m_sortedVisibleRoles)) { if (role == "text") { continue; } @@ -1219,11 +1289,11 @@ void KStandardItemListWidget::updateIconsLayoutTextCache() textLine.setLineWidth(maxWidth); requiredWidth = textLine.naturalTextWidth(); if (requiredWidth > maxWidth) { - const QString elidedText = m_customizedFontMetrics.elidedText(text, Qt::ElideRight, maxWidth); + const QString elidedText = elideRightKeepExtension(text, maxWidth); textInfo->staticText.setText(elidedText); - requiredWidth = m_customizedFontMetrics.width(elidedText); + requiredWidth = m_customizedFontMetrics.horizontalAdvance(elidedText); } else if (role == "rating") { - // Use the width of the rating pixmap, because the rating text is empty. + // Use the width of the rating pixmap, because the rating text is empty. requiredWidth = m_rating.width(); } } @@ -1260,15 +1330,15 @@ void KStandardItemListWidget::updateCompactLayoutTextCache() const qreal x = option.padding * 3 + scaledIconSize; qreal y = qRound((widgetHeight - textLinesHeight) / 2); const qreal maxWidth = size().width() - x - option.padding; - foreach (const QByteArray& role, m_sortedVisibleRoles) { + for (const QByteArray& role : qAsConst(m_sortedVisibleRoles)) { const QString text = roleText(role, values); TextInfo* textInfo = m_textInfo.value(role); textInfo->staticText.setText(text); - qreal requiredWidth = m_customizedFontMetrics.width(text); + qreal requiredWidth = m_customizedFontMetrics.horizontalAdvance(text); if (requiredWidth > maxWidth) { requiredWidth = maxWidth; - const QString elidedText = m_customizedFontMetrics.elidedText(text, Qt::ElideRight, maxWidth); + const QString elidedText = elideRightKeepExtension(text, maxWidth); textInfo->staticText.setText(elidedText); } @@ -1280,7 +1350,7 @@ void KStandardItemListWidget::updateCompactLayoutTextCache() y += lineSpacing; } - m_textRect = QRectF(x - 2 * option.padding, 0, maximumRequiredTextWidth + 3 * option.padding, widgetHeight); + m_textRect = QRectF(x - option.padding, 0, maximumRequiredTextWidth + 2 * option.padding, widgetHeight); } void KStandardItemListWidget::updateDetailsLayoutTextCache() @@ -1311,11 +1381,11 @@ void KStandardItemListWidget::updateDetailsLayoutTextCache() qreal x = firstColumnInc; const qreal y = qMax(qreal(option.padding), (widgetHeight - fontHeight) / 2); - foreach (const QByteArray& role, m_sortedVisibleRoles) { + for (const QByteArray& role : qAsConst(m_sortedVisibleRoles)) { QString text = roleText(role, values); // Elide the text in case it does not fit into the available column-width - qreal requiredWidth = m_customizedFontMetrics.width(text); + qreal requiredWidth = m_customizedFontMetrics.horizontalAdvance(text); const qreal roleWidth = columnWidth(role); qreal availableTextWidth = roleWidth - columnWidthInc; @@ -1325,8 +1395,8 @@ void KStandardItemListWidget::updateDetailsLayoutTextCache() } if (requiredWidth > availableTextWidth) { - text = m_customizedFontMetrics.elidedText(text, Qt::ElideRight, availableTextWidth); - requiredWidth = m_customizedFontMetrics.width(text); + text = elideRightKeepExtension(text, availableTextWidth); + requiredWidth = m_customizedFontMetrics.horizontalAdvance(text); } TextInfo* textInfo = m_textInfo.value(role); @@ -1338,8 +1408,8 @@ void KStandardItemListWidget::updateDetailsLayoutTextCache() const qreal textWidth = option.extendedSelectionRegion ? size().width() - textInfo->pos.x() : requiredWidth + 2 * option.padding; - m_textRect = QRectF(textInfo->pos.x() - 2 * option.padding, 0, - textWidth + option.padding, size().height()); + m_textRect = QRectF(textInfo->pos.x() - option.padding, 0, + textWidth, 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 @@ -1460,34 +1530,24 @@ void KStandardItemListWidget::closeRoleEditor() QPixmap KStandardItemListWidget::pixmapForIcon(const QString& name, const QStringList& overlays, int size, QIcon::Mode mode) { static const QIcon fallbackIcon = QIcon::fromTheme(QStringLiteral("unknown")); + size *= qApp->devicePixelRatio(); - const QString key = "KStandardItemListWidget:" % name % ":" % overlays.join(QStringLiteral(":")) % ":" % QString::number(size) % ":" % QString::number(mode); + + const QString key = "KStandardItemListWidget:" % name % ":" % overlays.join(QLatin1Char(':')) % ":" % QString::number(size) % ":" % QString::number(mode); QPixmap pixmap; - if (!QPixmapCache::find(key, pixmap)) { - const QIcon icon = QIcon::fromTheme(name, fallbackIcon); - - int requestedSize; - if (size <= KIconLoader::SizeSmall) { - requestedSize = KIconLoader::SizeSmall; - } else if (size <= KIconLoader::SizeSmallMedium) { - requestedSize = KIconLoader::SizeSmallMedium; - } else if (size <= KIconLoader::SizeMedium) { - requestedSize = KIconLoader::SizeMedium; - } else if (size <= KIconLoader::SizeLarge) { - requestedSize = KIconLoader::SizeLarge; - } else if (size <= KIconLoader::SizeHuge) { - requestedSize = KIconLoader::SizeHuge; - } else if (size <= KIconLoader::SizeEnormous) { - requestedSize = KIconLoader::SizeEnormous; - } else if (size <= KIconLoader::SizeEnormous * 2) { - requestedSize = KIconLoader::SizeEnormous * 2; - } else { - requestedSize = size; + if (!QPixmapCache::find(key, &pixmap)) { + QIcon icon = QIcon::fromTheme(name); + if (icon.isNull()) { + icon = QIcon(name); + } + if (icon.isNull() + || icon.pixmap(size / qApp->devicePixelRatio(), size / qApp->devicePixelRatio(), mode).isNull()) { + icon = fallbackIcon; } - pixmap = icon.pixmap(requestedSize / qApp->devicePixelRatio(), requestedSize / qApp->devicePixelRatio(), mode); - if (requestedSize != size) { + pixmap = icon.pixmap(size / qApp->devicePixelRatio(), size / qApp->devicePixelRatio(), mode); + if (pixmap.width() != size || pixmap.height() != size) { KPixmapModifier::scale(pixmap, QSize(size, size)); } @@ -1496,11 +1556,27 @@ QPixmap KStandardItemListWidget::pixmapForIcon(const QString& name, const QStrin // 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) { + for (const QString& overlay : overlays) { if (!overlay.isEmpty()) { + int state = KIconLoader::DefaultState; + + switch (mode) { + case QIcon::Normal: + break; + case QIcon::Active: + state = KIconLoader::ActiveState; + break; + case QIcon::Disabled: + state = KIconLoader::DisabledState; + break; + case QIcon::Selected: + state = KIconLoader::SelectedState; + break; + } + // There is at least one overlay, draw all overlays above m_pixmap // and cancel the check - KIconLoader::global()->drawOverlays(overlays, pixmap, KIconLoader::Desktop); + KIconLoader::global()->drawOverlays(overlays, pixmap, KIconLoader::Desktop, state); break; } }