From 7022918f2c370f3b553797d1d59da2990e0b9ab0 Mon Sep 17 00:00:00 2001 From: Josh Handley Date: Fri, 2 May 2014 17:00:55 -0400 Subject: [PATCH] Handle elide of multi-line text in QStyledItemDeletegate QCommonStylePrivate::viewItemDrawText did not correctly handle elide in multi-line text strings. It would cut off the string after the first line that required elision. This works with the older QItemDelegate. This fix elides each line of the text separately before rendering each line. [ChangeLog][QtWidgets][QCommonStylePrivate] Elide of multi-line text Task-number: QTBUG-14949 Change-Id: I94fb50172c92ac12de17de4e9a967cd82375533d --- src/widgets/styles/qcommonstyle.cpp | 60 ++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 4a98521..da99b3a 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -878,38 +878,37 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt QTextLayout textLayout(option->text, option->font); textLayout.setTextOption(textOption); - viewItemTextLayout(textLayout, textRect.width()); + QSizeF textLayoutSize = viewItemTextLayout(textLayout, textRect.width()); + + if (textLayoutSize.width() >= textRect.width() || textLayoutSize.height() >= textRect.height()) { + + QString elided; + int start = 0; + int end = textLayout.text().indexOf(QChar::LineSeparator); + if (end == -1) { + const QStackTextEngine engine(textLayout.text(), option->font); + elided = engine.elidedText(option->textElideMode, textRect.width()); + } else { + while (end != -1) { + const QStackTextEngine engine(textLayout.text().mid(start, end - start), option->font); + elided += engine.elidedText(option->textElideMode, textRect.width()); + elided += QChar::LineSeparator; + start = end + 1; + end = textLayout.text().indexOf(QChar::LineSeparator, start); + } + const QStackTextEngine engine(textLayout.text().mid(start), option->font); + elided += engine.elidedText(option->textElideMode, textRect.width()); + } + // redo the layout now that we have ellided text + textLayout.setText(elided); + viewItemTextLayout(textLayout, textRect.width()); + } - QString elidedText; qreal height = 0; qreal width = 0; - int elidedIndex = -1; const int lineCount = textLayout.lineCount(); for (int j = 0; j < lineCount; ++j) { const QTextLine line = textLayout.lineAt(j); - if (j + 1 <= lineCount - 1) { - const QTextLine nextLine = textLayout.lineAt(j + 1); - if ((nextLine.y() + nextLine.height()) > textRect.height()) { - int start = line.textStart(); - int length = line.textLength() + nextLine.textLength(); - const QStackTextEngine engine(textLayout.text().mid(start, length), option->font); - elidedText = engine.elidedText(option->textElideMode, textRect.width()); - height += line.height(); - width = textRect.width(); - elidedIndex = j; - break; - } - } - if (line.naturalTextWidth() > textRect.width()) { - int start = line.textStart(); - int length = line.textLength(); - const QStackTextEngine engine(textLayout.text().mid(start, length), option->font); - elidedText = engine.elidedText(option->textElideMode, textRect.width()); - height += line.height(); - width = textRect.width(); - elidedIndex = j; - break; - } width = qMax(width, line.width()); height += line.height(); } @@ -919,15 +918,6 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt const QPointF position = layoutRect.topLeft(); for (int i = 0; i < lineCount; ++i) { const QTextLine line = textLayout.lineAt(i); - if (i == elidedIndex) { - qreal x = position.x() + line.x(); - qreal y = position.y() + line.y() + line.ascent(); - p->save(); - p->setFont(option->font); - p->drawText(QPointF(x, y), elidedText); - p->restore(); - break; - } line.draw(p, position); } } -- 1.8.1.2