X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/5413025f0b26e9b195d1117bb483fbfe42e8c8c8..5360bc3ab328c8b1161b0c5df9c5785829a3e880:/src/kitemviews/kstandarditemlistwidget.cpp diff --git a/src/kitemviews/kstandarditemlistwidget.cpp b/src/kitemviews/kstandarditemlistwidget.cpp index bc3bb29de..3939fd237 100644 --- a/src/kitemviews/kstandarditemlistwidget.cpp +++ b/src/kitemviews/kstandarditemlistwidget.cpp @@ -1,21 +1,8 @@ -/*************************************************************************** - * 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" @@ -88,7 +75,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()) { @@ -113,8 +100,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; } @@ -214,12 +201,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) { const QString& text = roleText(role, values); - const qreal requiredWidth = fontMetrics.width(text); + const qreal requiredWidth = fontMetrics.horizontalAdvance(text); maximumRequiredWidth = qMax(maximumRequiredWidth, requiredWidth); } } @@ -478,7 +465,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; @@ -600,7 +587,7 @@ void KStandardItemListWidget::refreshCache() bool KStandardItemListWidget::isRoleRightAligned(const QByteArray& role) const { - Q_UNUSED(role); + Q_UNUSED(role) return false; } @@ -665,7 +652,7 @@ QString KStandardItemListWidget::roleText(const QByteArray& role, void KStandardItemListWidget::dataChanged(const QHash& current, const QSet& roles) { - Q_UNUSED(current); + Q_UNUSED(current) m_dirtyContent = true; @@ -697,7 +684,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; } @@ -706,38 +693,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; } @@ -748,7 +735,7 @@ 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") { @@ -966,7 +953,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 @@ -1011,7 +998,8 @@ 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 @@ -1112,6 +1100,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.right(extensionLength)); + return ret; + } + } + return m_customizedFontMetrics.elidedText(text,Qt::ElideRight, + elidingWidth); +} + void KStandardItemListWidget::updateIconsLayoutTextCache() { // +------+ @@ -1163,13 +1171,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 @@ -1220,11 +1226,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(); } } @@ -1266,10 +1272,10 @@ void KStandardItemListWidget::updateCompactLayoutTextCache() 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); } @@ -1281,7 +1287,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() @@ -1316,7 +1322,7 @@ void KStandardItemListWidget::updateDetailsLayoutTextCache() 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; @@ -1326,8 +1332,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); @@ -1339,8 +1345,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 @@ -1461,34 +1467,23 @@ 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 = 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)); } @@ -1499,9 +1494,25 @@ QPixmap KStandardItemListWidget::pixmapForIcon(const QString& name, const QStrin // setup time. foreach (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; } }