QAbstractItemView: make v-aligned items texts more user-friendly
Commit 25133a1b77
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 <eirik.aavitsland@qt.io>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
parent
3702622dde
commit
8b3463fdeb
@ -843,11 +843,14 @@ static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbut
|
|||||||
}
|
}
|
||||||
#endif // QT_CONFIG(toolbutton)
|
#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 height = 0;
|
||||||
qreal widthUsed = 0;
|
qreal widthUsed = 0;
|
||||||
textLayout.beginLayout();
|
textLayout.beginLayout();
|
||||||
|
int i = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
QTextLine line = textLayout.createLine();
|
QTextLine line = textLayout.createLine();
|
||||||
if (!line.isValid())
|
if (!line.isValid())
|
||||||
@ -856,6 +859,13 @@ static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth)
|
|||||||
line.setPosition(QPointF(0, height));
|
line.setPosition(QPointF(0, height));
|
||||||
height += line.height();
|
height += line.height();
|
||||||
widthUsed = qMax(widthUsed, line.naturalTextWidth());
|
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();
|
textLayout.endLayout();
|
||||||
return QSizeF(widthUsed, height);
|
return QSizeF(widthUsed, height);
|
||||||
@ -869,7 +879,13 @@ QString QCommonStylePrivate::calculateElidedText(const QString &text, const QTex
|
|||||||
QTextLayout textLayout(text, font);
|
QTextLayout textLayout(text, font);
|
||||||
textLayout.setTextOption(textOption);
|
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();
|
const QRectF boundingRect = textLayout.boundingRect();
|
||||||
// don't care about LTR/RTL here, only need the height
|
// 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 start = line.textStart();
|
||||||
const int length = line.textLength();
|
const int length = line.textLength();
|
||||||
const bool drawElided = line.naturalTextWidth() > textRect.width();
|
const bool drawElided = line.naturalTextWidth() > textRect.width();
|
||||||
bool elideLastVisibleLine = false;
|
bool elideLastVisibleLine = lastVisibleLine == i;
|
||||||
if (!drawElided && i + 1 < lineCount && lastVisibleLineShouldBeElided) {
|
if (!drawElided && i + 1 < lineCount && lastVisibleLineShouldBeElided) {
|
||||||
const QTextLine nextLine = textLayout.lineAt(i + 1);
|
const QTextLine nextLine = textLayout.lineAt(i + 1);
|
||||||
const int nextHeight = height + nextLine.height() / 2;
|
const int nextHeight = height + nextLine.height() / 2;
|
||||||
@ -927,7 +943,8 @@ QString QCommonStylePrivate::calculateElidedText(const QString &text, const QTex
|
|||||||
}
|
}
|
||||||
|
|
||||||
// below visible text, can stop
|
// below visible text, can stop
|
||||||
if (height + layoutRect.top() >= textRect.bottom())
|
if ((height + layoutRect.top() >= textRect.bottom()) ||
|
||||||
|
(lastVisibleLine >= 0 && lastVisibleLine == i))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user