diff options
author | Eike Ziller <eike.ziller@qt.io> | 2021-06-04 10:50:51 +0200 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2021-06-04 13:27:29 +0000 |
commit | 637837edf1b93654e15b74521327f6b1d507f940 (patch) | |
tree | 908ab85bc67a32acd16f1903081539d2b1dae9a0 | |
parent | 3282aa92f891b4eab1075eccdfe0df6eb4f7f1c1 (diff) | |
download | qt-creator-637837edf1b93654e15b74521327f6b1d507f940.tar.gz |
Mode bar: Fix splitting configuration name into two lines
Amends 0795d5f42d6ead3ce2bce1203bb527413c6373f4
- QRegularExpression::match does not support negative offsets, so that
part was wrong when porting to QRegularExpression
- QString::lastIndexOf with QRegularExpression and negative index is
broken in Qt > 5.15.2, which leads to endless recursion
Use good ol' loops instead, which also saves the overhead of throwing a
regular expression on this.
Task-number: QTBUG-94215
Change-Id: Ia9747c32fc775f2a735af97a6b73f9a5021882ab
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
-rw-r--r-- | src/plugins/coreplugin/fancyactionbar.cpp | 52 |
1 files changed, 37 insertions, 15 deletions
diff --git a/src/plugins/coreplugin/fancyactionbar.cpp b/src/plugins/coreplugin/fancyactionbar.cpp index ed4d5ddb27..d0b757a586 100644 --- a/src/plugins/coreplugin/fancyactionbar.cpp +++ b/src/plugins/coreplugin/fancyactionbar.cpp @@ -86,6 +86,42 @@ bool FancyToolButton::event(QEvent *e) return QToolButton::event(e); } +static int findSplitPos(const QString &text, const QFontMetrics &fontMetrics, qreal availableWidth) +{ + if (text.length() == 0) + return -1; + int splitPos = -1; + int lastWhiteSpace; + int firstWhiteSpace = text.length(); + do { + // search backwards for ranges of whitespaces + // search first whitespace (backwards) + lastWhiteSpace = firstWhiteSpace - 1; // start before last blob (or at end of text) + while (lastWhiteSpace >= 0) { + if (text.at(lastWhiteSpace).isSpace()) + break; + --lastWhiteSpace; + } + // search last whitespace (backwards) + firstWhiteSpace = lastWhiteSpace; + while (firstWhiteSpace > 0) { + if (!text.at(firstWhiteSpace - 1).isSpace()) + break; + --firstWhiteSpace; + } + // if the text after the whitespace range fits into the available width, that's a great + // position for splitting, but look if we can fit more + if (firstWhiteSpace != -1) { + if (fontMetrics.horizontalAdvance(text.mid(lastWhiteSpace + 1)) <= availableWidth) + splitPos = lastWhiteSpace + 1; + else + break; + } + } while (firstWhiteSpace > 0 + && fontMetrics.horizontalAdvance(text.left(firstWhiteSpace)) > availableWidth); + return splitPos; +} + static QVector<QString> splitInTwoLines(const QString &text, const QFontMetrics &fontMetrics, qreal availableWidth) @@ -95,21 +131,7 @@ static QVector<QString> splitInTwoLines(const QString &text, // to put them in the second line. First line is drawn with ellipsis, // second line gets ellipsis if it couldn't split off full words. QVector<QString> splitLines(2); - const QRegularExpression rx(QLatin1String("\\s+")); - int splitPos = -1; - int nextSplitPos = text.length(); - do { - int offset = nextSplitPos - text.length() - 1; - nextSplitPos = text.lastIndexOf(rx, offset); - if (nextSplitPos != -1) { - const QRegularExpressionMatch match = rx.match(text, offset); - int splitCandidate = nextSplitPos + match.capturedLength(); - if (fontMetrics.horizontalAdvance(text.mid(splitCandidate)) <= availableWidth) - splitPos = splitCandidate; - else - break; - } - } while (nextSplitPos > 0 && fontMetrics.horizontalAdvance(text.left(nextSplitPos)) > availableWidth); + const int splitPos = findSplitPos(text, fontMetrics, availableWidth); // check if we could split at white space at all if (splitPos < 0) { splitLines[0] = fontMetrics.elidedText(text, Qt::ElideRight, int(availableWidth)); |