From 8b3463fdeb3d03fd0c87873089a6f84321eecc49 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 17 Feb 2019 21:02:11 +0100 Subject: QAbstractItemView: make v-aligned items texts more user-friendly Commit 25133a1b77c059e32760f3d288c985183d86da4a fixed the item view text layouting correctly in a technical way. For a vertically aligned text which does not fit into the given rect it is not user-friendly to show some parts of the text. It is better to display the start of it and show an elide marker in the last visible line. Fixes: QTBUG-73721 Change-Id: Ia7453133ea0a229b24196467168c8371585c4d8f Reviewed-by: Eirik Aavitsland Reviewed-by: Richard Moe Gustavsen --- src/widgets/styles/qcommonstyle.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'src/widgets/styles') diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 79e338a6e7..c739ddc6e2 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -843,11 +843,14 @@ static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbut } #endif // QT_CONFIG(toolbutton) -static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth) +static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth, int maxHeight = -1, int *lastVisibleLine = nullptr) { + if (lastVisibleLine) + *lastVisibleLine = -1; qreal height = 0; qreal widthUsed = 0; textLayout.beginLayout(); + int i = 0; while (true) { QTextLine line = textLayout.createLine(); if (!line.isValid()) @@ -856,6 +859,13 @@ static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth) line.setPosition(QPointF(0, height)); height += line.height(); widthUsed = qMax(widthUsed, line.naturalTextWidth()); + // we assume that the height of the next line is the same as the current one + if (maxHeight > 0 && lastVisibleLine && height + line.height() > maxHeight) { + const QTextLine nextLine = textLayout.createLine(); + *lastVisibleLine = nextLine.isValid() ? i : -1; + break; + } + ++i; } textLayout.endLayout(); return QSizeF(widthUsed, height); @@ -869,7 +879,13 @@ QString QCommonStylePrivate::calculateElidedText(const QString &text, const QTex QTextLayout textLayout(text, font); textLayout.setTextOption(textOption); - viewItemTextLayout(textLayout, textRect.width()); + // In AlignVCenter mode when more than one line is displayed and the height only allows + // some of the lines it makes no sense to display those. From a users perspective it makes + // more sense to see the start of the text instead something inbetween. + const bool vAlignmentOptimization = paintStartPosition && valign.testFlag(Qt::AlignVCenter); + + int lastVisibleLine = -1; + viewItemTextLayout(textLayout, textRect.width(), vAlignmentOptimization ? textRect.height() : -1, &lastVisibleLine); const QRectF boundingRect = textLayout.boundingRect(); // don't care about LTR/RTL here, only need the height @@ -896,7 +912,7 @@ QString QCommonStylePrivate::calculateElidedText(const QString &text, const QTex const int start = line.textStart(); const int length = line.textLength(); const bool drawElided = line.naturalTextWidth() > textRect.width(); - bool elideLastVisibleLine = false; + bool elideLastVisibleLine = lastVisibleLine == i; if (!drawElided && i + 1 < lineCount && lastVisibleLineShouldBeElided) { const QTextLine nextLine = textLayout.lineAt(i + 1); const int nextHeight = height + nextLine.height() / 2; @@ -927,7 +943,8 @@ QString QCommonStylePrivate::calculateElidedText(const QString &text, const QTex } // below visible text, can stop - if (height + layoutRect.top() >= textRect.bottom()) + if ((height + layoutRect.top() >= textRect.bottom()) || + (lastVisibleLine >= 0 && lastVisibleLine == i)) break; } return ret; -- cgit v1.2.3