- QPainter painter(&squarePixmap);
- int x, y;
- if (iconOnTop) {
- x = (iconHeight - m_pixmap.width()) / 2; // Center horizontally
- y = iconHeight - m_pixmap.height(); // Align on bottom
- painter.drawPixmap(x, y, m_pixmap);
- } else {
- x = iconHeight - m_pixmap.width(); // Align right
- y = (iconHeight - m_pixmap.height()) / 2; // Center vertically
- painter.drawPixmap(x, y, m_pixmap);
- }
-
- m_pixmap = squarePixmap;
- } else {
- m_hoverPixmapRect.setSize(m_pixmap.size());
- }
-
- if (m_isCut) {
- applyCutEffect(m_pixmap);
- }
-
- if (m_isHidden) {
- applyHiddenEffect(m_pixmap);
- }
-
- Q_ASSERT(m_pixmap.height() == iconHeight);
- }
- if (!m_overlay.isNull()) {
- QPainter painter(&m_pixmap);
- painter.drawPixmap(0, m_pixmap.height() - m_overlay.height(), m_overlay);
- }
-
- m_scaledPixmapSize = QSize(scaledIconHeight, scaledIconHeight);
-
- if (iconOnTop) {
- m_pixmapPos.setX((widgetSize.width() - m_scaledPixmapSize.width()) / 2);
- } else {
- m_pixmapPos.setX(m_textPos[Name].x() - 2 * option.margin - scaledIconHeight);
- }
- m_pixmapPos.setY(option.margin);
-
- // Center the hover rectangle horizontally and align it on bottom
- const qreal x = m_pixmapPos.x() + (m_scaledPixmapSize.width() - m_hoverPixmapRect.width()) / 2.0;
- const qreal y = m_pixmapPos.y() + m_scaledPixmapSize.height() - m_hoverPixmapRect.height();
- m_hoverPixmapRect.moveTopLeft(QPointF(x, y));
-
- // 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;
- }
-
- for (int i = 0; i < TextIdCount; ++i) {
- m_text[i].setText(QString());
- m_text[i].setTextOption(textOption);
- }
-
- 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 maxWidth = size().width() - 2 * option.margin;
- const qreal widgetHeight = size().height();
- const qreal fontHeight = option.fontMetrics.height();
-
- // Initialize properties for the "name" role. It will be used as anchor
- // for initializing the position of the other roles.
- m_text[Name].setText(KStringHandler::preProcessWrap(values["name"].toString()));
-
- // Calculate the number of lines required for the name and the required width
- int textLinesCountForName = 0;
- qreal requiredWidthForName = 0;
- QTextLine line;
-
- QTextLayout layout(m_text[Name].text(), option.font);
- layout.setTextOption(m_text[Name].textOption());
- layout.beginLayout();
- while ((line = layout.createLine()).isValid()) {
- line.setLineWidth(maxWidth);
- requiredWidthForName = qMax(requiredWidthForName, line.naturalTextWidth());
- ++textLinesCountForName;
- }
- layout.endLayout();
-
- // Use one line for each additional information
- int textLinesCount = textLinesCountForName;
- const int additionalRolesCount = qMax(visibleRoles().count() - 1, 0);
- textLinesCount += additionalRolesCount;
-
- m_text[Name].setTextWidth(maxWidth);
- m_textPos[Name] = QPointF(option.margin, widgetHeight - textLinesCount * fontHeight - option.margin);
- m_textRect = QRectF(option.margin + (maxWidth - requiredWidthForName) / 2,
- m_textPos[Name].y(),
- requiredWidthForName,
- m_text[Name].size().height());
-
- // Calculate the position for each additional information
- qreal y = m_textPos[Name].y() + textLinesCountForName * fontHeight;
- foreach (const QByteArray& role, m_sortedVisibleRoles) {
- const TextId textId = roleTextId(role);
- if (textId == Name) {
- continue;
- }
-
- const QString text = roleText(role, values);
- m_text[textId].setText(text);
-
- qreal requiredWidth = 0;
-
- QTextLayout layout(text, option.font);
- layout.setTextOption(m_text[textId].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 margin is substracted.
- const QString elidedText = option.fontMetrics.elidedText(text, Qt::ElideRight, maxWidth - option.margin);
- m_text[textId].setText(elidedText);
- }
- }
- layout.endLayout();
-
- m_textPos[textId] = QPointF(option.margin, y);
- m_text[textId].setTextWidth(maxWidth);
-
- const QRectF textRect(option.margin + (maxWidth - requiredWidth) / 2, y, requiredWidth, fontHeight);
- m_textRect |= textRect;
-
- y += fontHeight;
- }
-
- // Add a margin to the text rectangle
- const qreal margin = option.margin;
- m_textRect.adjust(-margin, -margin, margin, margin);
-}
-
-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 fontHeight = option.fontMetrics.height();
- const qreal textLinesHeight = qMax(visibleRoles().count(), 1) * fontHeight;
- const int scaledIconSize = (textLinesHeight < option.iconSize) ? widgetHeight - 2 * option.margin : option.iconSize;
-
- qreal maximumRequiredTextWidth = 0;
- const qreal x = option.margin * 3 + scaledIconSize;
- qreal y = (widgetHeight - textLinesHeight) / 2;
- const qreal maxWidth = size().width() - x - option.margin;
- foreach (const QByteArray& role, m_sortedVisibleRoles) {
- const TextId textId = roleTextId(role);
-
- const QString text = roleText(role, values);
- m_text[textId].setText(text);
-
- qreal requiredWidth = option.fontMetrics.width(text);
- if (requiredWidth > maxWidth) {
- requiredWidth = maxWidth;
- const QString elidedText = option.fontMetrics.elidedText(text, Qt::ElideRight, maxWidth);
- m_text[textId].setText(elidedText);
- }
-
- m_textPos[textId] = QPointF(x, y);
- m_text[textId].setTextWidth(maxWidth);
-
- maximumRequiredTextWidth = qMax(maximumRequiredTextWidth, requiredWidth);
-
- y += fontHeight;
- }
-
- m_textRect = QRectF(x - option.margin, 0, maximumRequiredTextWidth + 2 * option.margin, widgetHeight);
-}
-
-void KFileItemListWidget::updateDetailsLayoutTextCache()
-{
- // Precondition: Requires already updated m_expansionArea
- // to determine the left position.
-
- // +------+
- // | Icon | Name role Additional role 1 Additional role 2
- // +------+
- m_textRect = QRectF();
-
- const KItemListStyleOption& option = styleOption();
- const QHash<QByteArray, QVariant> values = data();
-
- const qreal widgetHeight = size().height();
- const int scaledIconSize = widgetHeight - 2 * option.margin;
- const int fontHeight = option.fontMetrics.height();
-
- const qreal columnMargin = option.margin * 3;
- const qreal firstColumnInc = m_expansionArea.right() + option.margin * 2 + scaledIconSize;
- qreal x = firstColumnInc;
- const qreal y = qMax(qreal(option.margin), (widgetHeight - fontHeight) / 2);
-
- foreach (const QByteArray& role, m_sortedVisibleRoles) {
- const TextId textId = roleTextId(role);
-
- QString text = roleText(role, values);
-
- // Elide the text in case it does not fit into the available column-width
- qreal requiredWidth = option.fontMetrics.width(text);
- const qreal columnWidth = visibleRolesSizes().value(role, QSizeF(0, 0)).width();
- qreal availableTextWidth = columnWidth - 2 * columnMargin;
- if (textId == Name) {
- availableTextWidth -= firstColumnInc;
- }
-
- if (requiredWidth > availableTextWidth) {
- text = option.fontMetrics.elidedText(text, Qt::ElideRight, availableTextWidth);
- requiredWidth = option.fontMetrics.width(text);