summaryrefslogtreecommitdiffstats
path: root/src/widgets/styles/qcommonstyle.cpp
diff options
context:
space:
mode:
authorChristian Ehrlicher <ch.ehrlicher@gmx.de>2019-02-17 21:02:11 +0100
committerChristian Ehrlicher <ch.ehrlicher@gmx.de>2019-03-08 12:04:46 +0000
commit8b3463fdeb3d03fd0c87873089a6f84321eecc49 (patch)
tree20a820f7615724f36d99925cf2a602e4a6973b57 /src/widgets/styles/qcommonstyle.cpp
parent3702622dde060442534019bd99cbbf140391547b (diff)
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 <eirik.aavitsland@qt.io> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Diffstat (limited to 'src/widgets/styles/qcommonstyle.cpp')
-rw-r--r--src/widgets/styles/qcommonstyle.cpp25
1 files changed, 21 insertions, 4 deletions
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;