- const int textRowsCount = (m_layout == CompactLayout) ? visibleRoles().count() : 1;
- const qreal requiredTextHeight = textRowsCount * option.fontMetrics.height();
- scaledIconSize = (requiredTextHeight < maxIconHeight) ?
- widgetSize.height() - 2 * padding : maxIconHeight;
- }
-
- const int maxScaledIconWidth = iconOnTop ? widgetSize.width() - 2 * padding : scaledIconSize;
- const int maxScaledIconHeight = scaledIconSize;
-
- m_scaledPixmapSize = m_pixmap.size();
- m_scaledPixmapSize.scale(maxScaledIconWidth, maxScaledIconHeight, Qt::KeepAspectRatio);
-
- if (iconOnTop) {
- // Center horizontally and align on bottom within the icon-area
- m_pixmapPos.setX((widgetSize.width() - m_scaledPixmapSize.width()) / 2);
- m_pixmapPos.setY(padding + scaledIconSize - m_scaledPixmapSize.height());
- } else {
- // Center horizontally and vertically within the icon-area
- const TextInfo* textInfo = m_textInfo.value("name");
- m_pixmapPos.setX(textInfo->pos.x() - 2 * padding
- - (scaledIconSize + m_scaledPixmapSize.width()) / 2);
- m_pixmapPos.setY(padding
- + (scaledIconSize - m_scaledPixmapSize.height()) / 2);
- }
-
- m_iconRect = QRectF(m_pixmapPos, QSizeF(m_scaledPixmapSize));
-
- // Prepare the pixmap that is used when the item gets hovered
- if (isHovered()) {
- m_hoverPixmap = m_pixmap;
- KIconEffect* effect = KIconLoader::global()->iconEffect();
- // In the KIconLoader terminology, active = hover.
- if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState)) {
- m_hoverPixmap = effect->apply(m_pixmap, KIconLoader::Desktop, KIconLoader::ActiveState);
- } else {
- m_hoverPixmap = m_pixmap;
- }
- } else if (hoverOpacity() <= 0.0) {
- // No hover animation is ongoing. Clear m_hoverPixmap to save memory.
- m_hoverPixmap = QPixmap();
- }
-}
-
-void KFileItemListWidget::updateTextsCache()
-{
- QTextOption textOption;
- switch (m_layout) {
- case IconsLayout:
- textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
- textOption.setAlignment(Qt::AlignHCenter);
- break;
- case CompactLayout:
- case DetailsLayout:
- textOption.setAlignment(Qt::AlignLeft);
- textOption.setWrapMode(QTextOption::NoWrap);
- break;
- default:
- Q_ASSERT(false);
- break;
- }
-
- qDeleteAll(m_textInfo);
- m_textInfo.clear();
- for (int i = 0; i < m_sortedVisibleRoles.count(); ++i) {
- TextInfo* textInfo = new TextInfo();
- textInfo->staticText.setTextFormat(Qt::PlainText);
- textInfo->staticText.setPerformanceHint(QStaticText::AggressiveCaching);
- textInfo->staticText.setTextOption(textOption);
- m_textInfo.insert(m_sortedVisibleRoles[i], textInfo);
- }
-
- switch (m_layout) {
- case IconsLayout: updateIconsLayoutTextCache(); break;
- case CompactLayout: updateCompactLayoutTextCache(); break;
- case DetailsLayout: updateDetailsLayoutTextCache(); break;
- default: Q_ASSERT(false); break;
- }
-}
-
-void KFileItemListWidget::updateIconsLayoutTextCache()
-{
- // +------+
- // | Icon |
- // +------+
- //
- // Name role that
- // might get wrapped above
- // several lines.
- // Additional role 1
- // Additional role 2
-
- const QHash<QByteArray, QVariant> values = data();
-
- const KItemListStyleOption& option = styleOption();
- const qreal padding = option.padding;
- const qreal maxWidth = size().width() - 2 * padding;
- const qreal widgetHeight = size().height();
- const qreal lineSpacing = option.fontMetrics.lineSpacing();
-
- // Initialize properties for the "name" role. It will be used as anchor
- // for initializing the position of the other roles.
- TextInfo* nameTextInfo = m_textInfo.value("name");
- nameTextInfo->staticText.setText(KStringHandler::preProcessWrap(values["name"].toString()));
-
- // Calculate the number of lines required for the name and the required width
- qreal nameWidth = 0;
- qreal nameHeight = 0;
- QTextLine line;
-
- QTextLayout layout(nameTextInfo->staticText.text(), option.font);
- layout.setTextOption(nameTextInfo->staticText.textOption());
- layout.beginLayout();
- while ((line = layout.createLine()).isValid()) {
- line.setLineWidth(maxWidth);
- nameWidth = qMax(nameWidth, line.naturalTextWidth());
- nameHeight += line.height();
- }
- 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 -
- additionalRolesCount * lineSpacing -
- padding);
- m_textRect = QRectF(padding + (maxWidth - nameWidth) / 2,
- nameTextInfo->pos.y(),
- nameWidth,
- nameHeight);
-
- // Calculate the position for each additional information
- qreal y = nameTextInfo->pos.y() + nameHeight;
- foreach (const QByteArray& role, m_sortedVisibleRoles) {
- if (role == "name") {
- continue;
- }
-
- const QString text = roleText(role, values);
- TextInfo* textInfo = m_textInfo.value(role);
- textInfo->staticText.setText(text);
-
- qreal requiredWidth = 0;
-
- QTextLayout layout(text, option.font);
- layout.setTextOption(textInfo->staticText.textOption());
- layout.beginLayout();
- QTextLine textLine = layout.createLine();
- if (textLine.isValid()) {
- textLine.setLineWidth(maxWidth);
- requiredWidth = textLine.naturalTextWidth();
- if (textLine.textLength() < text.length()) {
- // TODO: QFontMetrics::elidedText() works different regarding the given width
- // in comparison to QTextLine::setLineWidth(). It might happen that the text does
- // not get elided although it does not fit into the given width. As workaround
- // the padding is substracted.
- const QString elidedText = option.fontMetrics.elidedText(text, Qt::ElideRight, maxWidth - padding);
- textInfo->staticText.setText(elidedText);
- }
- }
- layout.endLayout();
-
- textInfo->pos = QPointF(padding, y);
- textInfo->staticText.setTextWidth(maxWidth);
-
- const QRectF textRect(padding + (maxWidth - requiredWidth) / 2, y, requiredWidth, lineSpacing);
- m_textRect |= textRect;
-
- y += lineSpacing;
- }
-
- // Add a padding to the text rectangle
- m_textRect.adjust(-padding, -padding, padding, padding);
-}
-
-void KFileItemListWidget::updateCompactLayoutTextCache()
-{
- // +------+ Name role
- // | Icon | Additional role 1
- // +------+ Additional role 2
-
- const QHash<QByteArray, QVariant> values = data();
-
- const KItemListStyleOption& option = styleOption();
- const qreal widgetHeight = size().height();
- const qreal lineSpacing = option.fontMetrics.lineSpacing();
- const qreal textLinesHeight = qMax(visibleRoles().count(), 1) * lineSpacing;
- const int scaledIconSize = (textLinesHeight < option.iconSize) ? widgetHeight - 2 * option.padding : option.iconSize;
-
- qreal maximumRequiredTextWidth = 0;
- 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) {
- const QString text = roleText(role, values);
- TextInfo* textInfo = m_textInfo.value(role);
- textInfo->staticText.setText(text);
-
- qreal requiredWidth = option.fontMetrics.width(text);
- if (requiredWidth > maxWidth) {
- requiredWidth = maxWidth;
- const QString elidedText = option.fontMetrics.elidedText(text, Qt::ElideRight, maxWidth);
- textInfo->staticText.setText(elidedText);
- }
-
- textInfo->pos = QPointF(x, y);
- textInfo->staticText.setTextWidth(maxWidth);
-
- maximumRequiredTextWidth = qMax(maximumRequiredTextWidth, requiredWidth);
-
- y += lineSpacing;