#include "kfileitemlistview.h"
#include "kfileitemmodel.h"
-#include <KIcon>
+#include <QIcon>
#include <KIconEffect>
#include <KIconLoader>
-#include <KLocale>
-#include <kratingpainter.h>
+#include <KRatingPainter>
#include <KStringHandler>
-#include <KDebug>
#include "private/kfileitemclipboard.h"
#include "private/kitemlistroleeditor.h"
#include "private/kpixmapmodifier.h"
-#include <QFontMetricsF>
#include <QGraphicsScene>
#include <QGraphicsSceneResizeEvent>
#include <QGraphicsView>
#include <QTextLayout>
#include <QTextLine>
#include <QPixmapCache>
+#include <QGuiApplication>
// #define KSTANDARDITEMLISTWIDGET_DEBUG
{
}
-QSizeF KStandardItemListWidgetInformant::itemSizeHint(int index, const KItemListView* view) const
+void KStandardItemListWidgetInformant::calculateItemSizeHints(QVector<qreal>& logicalHeightHints, qreal& logicalWidthHint, 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 qreal itemWidth = view->itemSize().width();
- const qreal maxWidth = itemWidth - 2 * option.padding;
- QTextLine line;
-
- // Calculate the number of lines required for wrapping the name
- QTextOption textOption(Qt::AlignHCenter);
- textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
-
- qreal textHeight = 0;
- QTextLayout layout(text, option.font);
- layout.setTextOption(textOption);
- layout.beginLayout();
- while ((line = layout.createLine()).isValid()) {
- line.setLineWidth(maxWidth);
- line.naturalTextWidth();
- textHeight += line.height();
- }
- layout.endLayout();
-
- // Add one line for each additional information
- textHeight += additionalRolesCount * option.fontMetrics.lineSpacing();
-
- const qreal maxTextHeight = option.maxTextSize.height();
- if (maxTextHeight > 0 && textHeight > maxTextHeight) {
- textHeight = maxTextHeight;
- }
-
- return QSizeF(itemWidth, textHeight + option.iconSize + option.padding * 3);
- }
-
- case KStandardItemListWidget::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, view->visibleRoles()) {
- const QString text = roleText(role, values);
- const qreal requiredWidth = option.fontMetrics.width(text);
- maximumRequiredWidth = qMax(maximumRequiredWidth, requiredWidth);
- }
+ case KStandardItemListWidget::IconsLayout:
+ calculateIconsLayoutItemSizeHints(logicalHeightHints, logicalWidthHint, view);
+ break;
- qreal width = option.padding * 4 + option.iconSize + maximumRequiredWidth;
- const qreal maxWidth = option.maxTextSize.width();
- if (maxWidth > 0 && width > maxWidth) {
- width = maxWidth;
- }
- const qreal height = option.padding * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * option.fontMetrics.lineSpacing());
- return QSizeF(width, height);
- }
+ case KStandardItemListWidget::CompactLayout:
+ calculateCompactLayoutItemSizeHints(logicalHeightHints, logicalWidthHint, view);
+ break;
- case KStandardItemListWidget::DetailsLayout: {
- const qreal height = option.padding * 2 + qMax(option.iconSize, option.fontMetrics.height());
- return QSizeF(-1, height);
- }
+ case KStandardItemListWidget::DetailsLayout:
+ calculateDetailsLayoutItemSizeHints(logicalHeightHints, logicalWidthHint, view);
+ break;
default:
Q_ASSERT(false);
break;
}
-
- return QSize();
}
qreal KStandardItemListWidgetInformant::preferredRoleColumnWidth(const QByteArray& role,
const QString text = roleText(role, values);
qreal width = KStandardItemListWidget::columnPadding(option);
+ const QFontMetrics& normalFontMetrics = option.fontMetrics;
+ const QFontMetrics linkFontMetrics(customizedFontForLinks(option.font));
+
if (role == "rating") {
width += KStandardItemListWidget::preferredRatingSize(option).width();
} else {
- width += option.fontMetrics.width(text);
+ // 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);
if (role == "text") {
if (view->supportsItemExpanding()) {
// Increase the width by the expansion-toggle and the current expansion level
const int expandedParentsCount = values.value("expandedParentsCount", 0).toInt();
- const qreal height = option.padding * 2 + qMax(option.iconSize, option.fontMetrics.height());
+ const qreal height = option.padding * 2 + qMax(option.iconSize, fontMetrics.height());
width += (expandedParentsCount + 1) * height;
}
return width;
}
+QString KStandardItemListWidgetInformant::itemText(int index, const KItemListView* view) const
+{
+ return view->model()->data(index).value("text").toString();
+}
+
+bool KStandardItemListWidgetInformant::itemIsLink(int index, const KItemListView* view) const
+{
+ Q_UNUSED(index);
+ Q_UNUSED(view);
+ return false;
+}
+
QString KStandardItemListWidgetInformant::roleText(const QByteArray& role,
const QHash<QByteArray, QVariant>& values) const
{
return values.value(role).toString();
}
+QFont KStandardItemListWidgetInformant::customizedFontForLinks(const QFont& baseFont) const
+{
+ return baseFont;
+}
+
+void KStandardItemListWidgetInformant::calculateIconsLayoutItemSizeHints(QVector<qreal>& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const
+{
+ const KItemListStyleOption& option = view->styleOption();
+ const QFont& normalFont = option.font;
+ const int additionalRolesCount = qMax(view->visibleRoles().count() - 1, 0);
+
+ const qreal itemWidth = view->itemSize().width();
+ const qreal maxWidth = itemWidth - 2 * option.padding;
+ const qreal additionalRolesSpacing = additionalRolesCount * option.fontMetrics.lineSpacing();
+ const qreal spacingAndIconHeight = option.iconSize + option.padding * 3;
+
+ const QFont linkFont = customizedFontForLinks(normalFont);
+
+ QTextOption textOption(Qt::AlignHCenter);
+ textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
+
+ for (int index = 0; index < logicalHeightHints.count(); ++index) {
+ if (logicalHeightHints.at(index) > 0.0) {
+ continue;
+ }
+
+ // If the current item is a link, we use the customized link font instead of the normal font.
+ 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);
+ layout.setTextOption(textOption);
+ layout.beginLayout();
+ QTextLine line;
+ int lineCount = 0;
+ while ((line = layout.createLine()).isValid()) {
+ line.setLineWidth(maxWidth);
+ line.naturalTextWidth();
+ textHeight += line.height();
+
+ ++lineCount;
+ if (lineCount == option.maxTextLines) {
+ break;
+ }
+ }
+ layout.endLayout();
+
+ // Add one line for each additional information
+ textHeight += additionalRolesSpacing;
+
+ logicalHeightHints[index] = textHeight + spacingAndIconHeight;
+ }
+
+ logicalWidthHint = itemWidth;
+}
+
+void KStandardItemListWidgetInformant::calculateCompactLayoutItemSizeHints(QVector<qreal>& logicalHeightHints, qreal& logicalWidthHint, const KItemListView* view) const
+{
+ const KItemListStyleOption& option = view->styleOption();
+ const QFontMetrics& normalFontMetrics = option.fontMetrics;
+ const int additionalRolesCount = qMax(view->visibleRoles().count() - 1, 0);
+
+ const QList<QByteArray>& visibleRoles = view->visibleRoles();
+ const bool showOnlyTextRole = (visibleRoles.count() == 1) && (visibleRoles.first() == "text");
+ const qreal maxWidth = option.maxTextWidth;
+ const qreal paddingAndIconWidth = option.padding * 4 + option.iconSize;
+ const qreal height = option.padding * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * normalFontMetrics.lineSpacing());
+
+ const QFontMetrics linkFontMetrics(customizedFontForLinks(option.font));
+
+ for (int index = 0; index < logicalHeightHints.count(); ++index) {
+ if (logicalHeightHints.at(index) > 0.0) {
+ continue;
+ }
+
+ // If the 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;
+
+ // 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;
+
+ if (showOnlyTextRole) {
+ maximumRequiredWidth = fontMetrics.width(itemText(index, view));
+ } else {
+ const QHash<QByteArray, QVariant>& values = view->model()->data(index);
+ foreach (const QByteArray& role, visibleRoles) {
+ const QString& text = roleText(role, values);
+ const qreal requiredWidth = fontMetrics.width(text);
+ maximumRequiredWidth = qMax(maximumRequiredWidth, requiredWidth);
+ }
+ }
+
+ qreal width = paddingAndIconWidth + maximumRequiredWidth;
+ if (maxWidth > 0 && width > maxWidth) {
+ width = maxWidth;
+ }
+
+ logicalHeightHints[index] = width;
+ }
+
+ logicalWidthHint = height;
+}
+
+void KStandardItemListWidgetInformant::calculateDetailsLayoutItemSizeHints(QVector<qreal>& 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);
+ logicalWidthHint = -1.0;
+}
+
KStandardItemListWidget::KStandardItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent) :
KItemListWidget(informant, parent),
m_isCut(false),
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)
*/
// Paint pixmap1 so that pixmap1 = m_pixmap * (1.0 - hoverOpacity())
QPixmap pixmap1(m_pixmap.size());
+ pixmap1.setDevicePixelRatio(m_pixmap.devicePixelRatio());
pixmap1.fill(Qt::transparent);
{
QPainter p(&pixmap1);
// Paint pixmap2 so that pixmap2 = m_hoverPixmap * hoverOpacity()
QPixmap pixmap2(pixmap1.size());
+ pixmap2.setDevicePixelRatio(pixmap1.devicePixelRatio());
pixmap2.fill(Qt::transparent);
{
QPainter p(&pixmap2);
}
painter->setFont(m_customizedFont);
- painter->setPen(m_isHidden ? m_additionalInfoTextColor : textColor());
+ painter->setPen(textColor());
const TextInfo* textInfo = m_textInfo.value("text");
if (!textInfo) {
painter->setPen(Qt::green);
painter->drawRect(m_iconRect);
+ painter->setPen(Qt::blue);
+ painter->drawRect(m_textRect);
+
painter->setPen(Qt::red);
painter->drawText(QPointF(0, m_customizedFontMetrics.height()), QString::number(index()));
painter->drawRect(rect());
return m_textRect;
}
+QRectF KStandardItemListWidget::selectionRect() const
+{
+ const_cast<KStandardItemListWidget*>(this)->triggerCacheRefreshing();
+
+ switch (m_layout) {
+ case IconsLayout:
+ return m_textRect;
+
+ case CompactLayout:
+ case DetailsLayout: {
+ const int padding = styleOption().padding;
+ QRectF adjustedIconRect = iconRect().adjusted(-padding, -padding, padding, padding);
+ return adjustedIconRect | m_textRect;
+ }
+
+ default:
+ Q_ASSERT(false);
+ break;
+ }
+
+ return m_textRect;
+}
+
QRectF KStandardItemListWidget::expansionToggleRect() const
{
const_cast<KStandardItemListWidget*>(this)->triggerCacheRefreshing();
QColor KStandardItemListWidget::textColor() const
{
- if (m_customTextColor.isValid() && !isSelected()) {
- return m_customTextColor;
+ if (!isSelected()) {
+ if (m_isHidden) {
+ return m_additionalInfoTextColor;
+ } else if (m_customTextColor.isValid()) {
+ return m_customTextColor;
+ }
}
const QPalette::ColorGroup group = isActiveWindow() ? QPalette::Active : QPalette::Inactive;
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 QUrl itemUrl = data().value("url").toUrl();
+ 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");
if (m_roleEditor) {
emit roleEditingCanceled(index(), current, data().value(current));
- disconnect(m_roleEditor, SIGNAL(roleEditingCanceled(int,QByteArray,QVariant)),
- this, SLOT(slotRoleEditingCanceled(int,QByteArray,QVariant)));
- disconnect(m_roleEditor, SIGNAL(roleEditingFinished(int,QByteArray,QVariant)),
- this, SLOT(slotRoleEditingFinished(int,QByteArray,QVariant)));
+ disconnect(m_roleEditor, &KItemListRoleEditor::roleEditingCanceled,
+ this, &KStandardItemListWidget::slotRoleEditingCanceled);
+ disconnect(m_roleEditor, &KItemListRoleEditor::roleEditingFinished,
+ this, &KStandardItemListWidget::slotRoleEditingFinished);
+
+ 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);
const TextInfo* textInfo = m_textInfo.value("text");
m_roleEditor = new KItemListRoleEditor(parent);
- m_roleEditor->setIndex(index());
m_roleEditor->setRole(current);
m_roleEditor->setFont(styleOption().font);
m_roleEditor->setTextCursor(cursor);
}
- connect(m_roleEditor, SIGNAL(roleEditingCanceled(int,QByteArray,QVariant)),
- this, SLOT(slotRoleEditingCanceled(int,QByteArray,QVariant)));
- connect(m_roleEditor, SIGNAL(roleEditingFinished(int,QByteArray,QVariant)),
- this, SLOT(slotRoleEditingFinished(int,QByteArray,QVariant)));
+ connect(m_roleEditor, &KItemListRoleEditor::roleEditingCanceled,
+ this, &KStandardItemListWidget::slotRoleEditingCanceled);
+ connect(m_roleEditor, &KItemListRoleEditor::roleEditingFinished,
+ this, &KStandardItemListWidget::slotRoleEditingFinished);
// Adjust the geometry of the editor
QRectF rect = roleEditingRect(current);
// Listen to changes of the clipboard to mark the item as cut/uncut
KFileItemClipboard* clipboard = KFileItemClipboard::instance();
- const KUrl itemUrl = data().value("url").value<KUrl>();
+ const QUrl itemUrl = data().value("url").toUrl();
m_isCut = clipboard->isCut(itemUrl);
- connect(clipboard, SIGNAL(cutItemsChanged()),
- this, SLOT(slotCutItemsChanged()));
+ connect(clipboard, &KFileItemClipboard::cutItemsChanged,
+ this, &KStandardItemListWidget::slotCutItemsChanged);
}
void KStandardItemListWidget::hideEvent(QHideEvent* event)
{
- disconnect(KFileItemClipboard::instance(), SIGNAL(cutItemsChanged()),
- this, SLOT(slotCutItemsChanged()));
+ disconnect(KFileItemClipboard::instance(), &KFileItemClipboard::cutItemsChanged,
+ this, &KStandardItemListWidget::slotCutItemsChanged);
KItemListWidget::hideEvent(event);
}
+bool KStandardItemListWidget::event(QEvent *event)
+{
+ if (event->type() == QEvent::WindowDeactivate || event->type() == QEvent::WindowActivate
+ || event->type() == QEvent::PaletteChange) {
+ m_dirtyContent = true;
+ }
+
+ return KItemListWidget::event(event);
+}
+
void KStandardItemListWidget::slotCutItemsChanged()
{
- const KUrl itemUrl = data().value("url").value<KUrl>();
+ const QUrl itemUrl = data().value("url").toUrl();
const bool isCut = KFileItemClipboard::instance()->isCut(itemUrl);
if (m_isCut != isCut) {
m_isCut = isCut;
}
}
-void KStandardItemListWidget::slotRoleEditingCanceled(int index,
- const QByteArray& role,
+void KStandardItemListWidget::slotRoleEditingCanceled(const QByteArray& role,
const QVariant& value)
{
closeRoleEditor();
- emit roleEditingCanceled(index, role, value);
+ emit roleEditingCanceled(index(), role, value);
setEditedRole(QByteArray());
}
-void KStandardItemListWidget::slotRoleEditingFinished(int index,
- const QByteArray& role,
+void KStandardItemListWidget::slotRoleEditingFinished(const QByteArray& role,
const QVariant& value)
{
closeRoleEditor();
- emit roleEditingFinished(index, role, value);
+ emit roleEditingFinished(index(), role, value);
setEditedRole(QByteArray());
}
{
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;
}
}
if (iconName.isEmpty()) {
// The icon-name has not been not resolved by KFileItemModelRolesUpdater,
// use a generic icon as fallback
- iconName = QLatin1String("unknown");
+ iconName = QStringLiteral("unknown");
}
- m_pixmap = pixmapForIcon(iconName, maxIconHeight);
- } else if (m_pixmap.width() != maxIconWidth || m_pixmap.height() != maxIconHeight) {
+ const QStringList overlays = values["iconOverlays"].toStringList();
+ m_pixmap = pixmapForIcon(iconName, overlays, maxIconHeight, isSelected() && isActiveWindow() ? 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
// 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;
- }
+ KPixmapModifier::scale(m_pixmap, QSize(maxIconWidth, maxIconHeight) * qApp->devicePixelRatio());
}
if (m_isCut) {
KIconEffect::semiTransparent(m_pixmap);
}
- if (isSelected()) {
+ if (m_layout == IconsLayout && isSelected()) {
const QColor color = palette().brush(QPalette::Normal, QPalette::Highlight).color();
QImage image = m_pixmap.toImage();
KIconEffect::colorize(image, color, 0.8f);
qreal nameHeight = 0;
QTextLine line;
- const int additionalRolesCount = qMax(visibleRoles().count() - 1, 0);
- const int maxNameLines = (option.maxTextSize.height() / int(lineSpacing)) - additionalRolesCount;
-
QTextLayout layout(nameTextInfo->staticText.text(), m_customizedFont);
layout.setTextOption(nameTextInfo->staticText.textOption());
layout.beginLayout();
nameHeight += line.height();
++nameLineIndex;
- if (nameLineIndex == maxNameLines) {
+ if (nameLineIndex == option.maxTextLines) {
// The maximum number of textlines has been reached. If this is
// the case provide an elided text if necessary.
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());
- lastTextLine = m_customizedFontMetrics.elidedText(lastTextLine,
- Qt::ElideRight,
- line.naturalTextWidth() - 1);
- const QString elidedText = nameText.left(line.textStart()) + lastTextLine;
- nameTextInfo->staticText.setText(elidedText);
+ qreal elidingWidth = maxWidth;
+ qreal lastLineWidth;
+ do {
+ QString lastTextLine = nameText.mid(line.textStart());
+ lastTextLine = m_customizedFontMetrics.elidedText(lastTextLine,
+ Qt::ElideRight,
+ elidingWidth);
+ const QString elidedText = nameText.left(line.textStart()) + lastTextLine;
+ nameTextInfo->staticText.setText(elidedText);
+
+ lastLineWidth = m_customizedFontMetrics.boundingRect(lastTextLine).width();
+
+ // We do the text eliding in a loop with decreasing width (1 px / iteration)
+ // to avoid problems related to different width calculation code paths
+ // within Qt. (see bug 337104)
+ elidingWidth -= 1.0;
+ } while (lastLineWidth > maxWidth);
+
+ nameWidth = qMax(nameWidth, lastLineWidth);
}
break;
}
layout.endLayout();
// Use one line for each additional information
+ const int additionalRolesCount = qMax(visibleRoles().count() - 1, 0);
nameTextInfo->staticText.setTextWidth(maxWidth);
nameTextInfo->pos = QPointF(padding, widgetHeight -
nameHeight -
y += lineSpacing;
}
- m_textRect = QRectF(x - option.padding, 0, maximumRequiredTextWidth + 2 * option.padding, widgetHeight);
+ m_textRect = QRectF(x - 2 * option.padding, 0, maximumRequiredTextWidth + 3 * option.padding, widgetHeight);
}
void KStandardItemListWidget::updateDetailsLayoutTextCache()
const qreal textWidth = option.extendedSelectionRegion
? size().width() - textInfo->pos.x()
: requiredWidth + 2 * option.padding;
- m_textRect = QRectF(textInfo->pos.x() - option.padding, 0,
- textWidth, size().height());
+ m_textRect = QRectF(textInfo->pos.x() - 2 * option.padding, 0,
+ textWidth + option.padding, 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
void KStandardItemListWidget::drawPixmap(QPainter* painter, const QPixmap& pixmap)
{
- if (m_scaledPixmapSize != pixmap.size()) {
+ if (m_scaledPixmapSize != pixmap.size() / pixmap.devicePixelRatio()) {
QPixmap scaledPixmap = pixmap;
- KPixmapModifier::scale(scaledPixmap, m_scaledPixmapSize);
+ KPixmapModifier::scale(scaledPixmap, m_scaledPixmapSize * qApp->devicePixelRatio());
+ scaledPixmap.setDevicePixelRatio(qApp->devicePixelRatio());
painter->drawPixmap(m_pixmapPos, scaledPixmap);
#ifdef KSTANDARDITEMLISTWIDGET_DEBUG
if (m_isExpandable) {
option.state |= QStyle::State_Children;
}
- if (data()["isExpanded"].toBool()) {
+ if (data().value("isExpanded").toBool()) {
option.state |= QStyle::State_Open;
}
isItemSibling = false;
void KStandardItemListWidget::closeRoleEditor()
{
- disconnect(m_roleEditor, SIGNAL(roleEditingCanceled(int,QByteArray,QVariant)),
- this, SLOT(slotRoleEditingCanceled(int,QByteArray,QVariant)));
- disconnect(m_roleEditor, SIGNAL(roleEditingFinished(int,QByteArray,QVariant)),
- this, SLOT(slotRoleEditingFinished(int,QByteArray,QVariant)));
+ disconnect(m_roleEditor, &KItemListRoleEditor::roleEditingCanceled,
+ this, &KStandardItemListWidget::slotRoleEditingCanceled);
+ disconnect(m_roleEditor, &KItemListRoleEditor::roleEditingFinished,
+ this, &KStandardItemListWidget::slotRoleEditingFinished);
if (m_roleEditor->hasFocus()) {
// If the editing was not ended by a FocusOut event, we have
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, QIcon::Mode mode)
{
- const QString key = "KStandardItemListWidget:" % name % ":" % QString::number(size);
+ 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);
QPixmap pixmap;
if (!QPixmapCache::find(key, pixmap)) {
- const KIcon icon(name);
+ const QIcon icon = QIcon::fromTheme(name, fallbackIcon);
int requestedSize;
if (size <= KIconLoader::SizeSmall) {
requestedSize = size;
}
- pixmap = icon.pixmap(requestedSize, requestedSize);
+ pixmap = icon.pixmap(requestedSize / qApp->devicePixelRatio(), requestedSize / qApp->devicePixelRatio(), mode);
if (requestedSize != 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);
}
+ pixmap.setDevicePixelRatio(qApp->devicePixelRatio());
return pixmap;
}
return option.padding * 6;
}
-#include "kstandarditemlistwidget.moc"