Commit 7168dd48 authored by Tobias Hunger's avatar Tobias Hunger
Browse files

AnsiEscapeHandler: Use a dedicated struct in favor of a qPair



Change-Id: I800d4868caf0cd58f83507ae2d0849d50f86a01f
Reviewed-by: default avatarDaniel Teske <daniel.teske@digia.com>
parent c96fd741
...@@ -70,8 +70,7 @@ static QColor ansiColor(uint code) ...@@ -70,8 +70,7 @@ static QColor ansiColor(uint code)
return QColor(red, green, blue); return QColor(red, green, blue);
} }
QList<StringFormatPair> AnsiEscapeCodeHandler::parseText(const QString &text, QList<FormattedText> AnsiEscapeCodeHandler::parseText(const FormattedText &input)
const QTextCharFormat &defaultFormat)
{ {
enum AnsiEscapeCodes { enum AnsiEscapeCodes {
ResetFormat = 0, ResetFormat = 0,
...@@ -86,22 +85,22 @@ QList<StringFormatPair> AnsiEscapeCodeHandler::parseText(const QString &text, ...@@ -86,22 +85,22 @@ QList<StringFormatPair> AnsiEscapeCodeHandler::parseText(const QString &text,
DefaultBackgroundColor = 49 DefaultBackgroundColor = 49
}; };
QList<StringFormatPair> outputData; QList<FormattedText> outputData;
QTextCharFormat charFormat = m_previousFormatClosed ? defaultFormat : m_previousFormat; QTextCharFormat charFormat = m_previousFormatClosed ? input.format : m_previousFormat;
const QString escape = QLatin1String("\x1b["); const QString escape = QLatin1String("\x1b[");
if (!text.contains(escape)) { if (!input.text.contains(escape)) {
outputData << StringFormatPair(text, charFormat); outputData << FormattedText(input.text, charFormat);
return outputData; return outputData;
} else if (!text.startsWith(escape)) { } else if (!input.text.startsWith(escape)) {
outputData << StringFormatPair(text.left(text.indexOf(escape)), charFormat); outputData << FormattedText(input.text.left(input.text.indexOf(escape)), charFormat);
} }
const QChar semicolon = QLatin1Char(';'); const QChar semicolon = QLatin1Char(';');
const QChar colorTerminator = QLatin1Char('m'); const QChar colorTerminator = QLatin1Char('m');
// strippedText always starts with "\e[" // strippedText always starts with "\e["
QString strippedText = text.mid(text.indexOf(escape)); QString strippedText = input.text.mid(input.text.indexOf(escape));
while (!strippedText.isEmpty()) { while (!strippedText.isEmpty()) {
while (strippedText.startsWith(escape)) { while (strippedText.startsWith(escape)) {
strippedText.remove(0, 2); strippedText.remove(0, 2);
...@@ -129,7 +128,7 @@ QList<StringFormatPair> AnsiEscapeCodeHandler::parseText(const QString &text, ...@@ -129,7 +128,7 @@ QList<StringFormatPair> AnsiEscapeCodeHandler::parseText(const QString &text,
strippedText.remove(0, 1); strippedText.remove(0, 1);
if (numbers.isEmpty()) { if (numbers.isEmpty()) {
charFormat = defaultFormat; charFormat = input.format;
endFormatScope(); endFormatScope();
} }
...@@ -145,7 +144,7 @@ QList<StringFormatPair> AnsiEscapeCodeHandler::parseText(const QString &text, ...@@ -145,7 +144,7 @@ QList<StringFormatPair> AnsiEscapeCodeHandler::parseText(const QString &text,
} else { } else {
switch (code) { switch (code) {
case ResetFormat: case ResetFormat:
charFormat = defaultFormat; charFormat = input.format;
endFormatScope(); endFormatScope();
break; break;
case BoldText: case BoldText:
...@@ -153,11 +152,11 @@ QList<StringFormatPair> AnsiEscapeCodeHandler::parseText(const QString &text, ...@@ -153,11 +152,11 @@ QList<StringFormatPair> AnsiEscapeCodeHandler::parseText(const QString &text,
setFormatScope(charFormat); setFormatScope(charFormat);
break; break;
case DefaultTextColor: case DefaultTextColor:
charFormat.setForeground(defaultFormat.foreground()); charFormat.setForeground(input.format.foreground());
setFormatScope(charFormat); setFormatScope(charFormat);
break; break;
case DefaultBackgroundColor: case DefaultBackgroundColor:
charFormat.setBackground(defaultFormat.background()); charFormat.setBackground(input.format.background());
setFormatScope(charFormat); setFormatScope(charFormat);
break; break;
case RgbTextColor: case RgbTextColor:
...@@ -194,10 +193,10 @@ QList<StringFormatPair> AnsiEscapeCodeHandler::parseText(const QString &text, ...@@ -194,10 +193,10 @@ QList<StringFormatPair> AnsiEscapeCodeHandler::parseText(const QString &text,
break; break;
int index = strippedText.indexOf(escape); int index = strippedText.indexOf(escape);
if (index > 0) { if (index > 0) {
outputData << StringFormatPair(strippedText.left(index), charFormat); outputData << FormattedText(strippedText.left(index), charFormat);
strippedText.remove(0, index); strippedText.remove(0, index);
} else if (index == -1) { } else if (index == -1) {
outputData << StringFormatPair(strippedText, charFormat); outputData << FormattedText(strippedText, charFormat);
break; break;
} }
} }
......
...@@ -37,13 +37,23 @@ ...@@ -37,13 +37,23 @@
namespace Utils { namespace Utils {
typedef QPair<QString, QTextCharFormat> StringFormatPair; class QTCREATOR_UTILS_EXPORT FormattedText {
public:
FormattedText() { }
FormattedText(const FormattedText &other) : text(other.text), format(other.format) { }
FormattedText(const QString &txt, const QTextCharFormat &fmt = QTextCharFormat()) :
text(txt), format(fmt)
{ }
QString text;
QTextCharFormat format;
};
class QTCREATOR_UTILS_EXPORT AnsiEscapeCodeHandler class QTCREATOR_UTILS_EXPORT AnsiEscapeCodeHandler
{ {
public: public:
AnsiEscapeCodeHandler(); AnsiEscapeCodeHandler();
QList<StringFormatPair> parseText(const QString &text, const QTextCharFormat &defaultFormat); QList<FormattedText> parseText(const FormattedText &input);
void endFormatScope(); void endFormatScope();
private: private:
......
...@@ -65,8 +65,10 @@ void OutputFormatter::appendMessage(const QString &text, OutputFormat format) ...@@ -65,8 +65,10 @@ void OutputFormatter::appendMessage(const QString &text, OutputFormat format)
QTextCursor cursor(m_plainTextEdit->document()); QTextCursor cursor(m_plainTextEdit->document());
cursor.movePosition(QTextCursor::End); cursor.movePosition(QTextCursor::End);
foreach (const StringFormatPair &pair, m_escapeCodeHandler->parseText(text, m_formats[format])) foreach (const FormattedText &output,
cursor.insertText(pair.first, pair.second); m_escapeCodeHandler->parseText(FormattedText(text, m_formats[format]))) {
cursor.insertText(output.text, output.format);
}
} }
QTextCharFormat OutputFormatter::charFormat(OutputFormat format) const QTextCharFormat OutputFormatter::charFormat(OutputFormat format) const
......
...@@ -205,8 +205,9 @@ void CompileOutputWindow::appendText(const QString &text, ProjectExplorer::Build ...@@ -205,8 +205,9 @@ void CompileOutputWindow::appendText(const QString &text, ProjectExplorer::Build
} }
foreach (const Utils::StringFormatPair &pair, m_escapeCodeHandler->parseText(text, textFormat)) foreach (const Utils::FormattedText &output,
m_outputWindow->appendText(pair.first, pair.second); m_escapeCodeHandler->parseText(Utils::FormattedText(text, textFormat)))
m_outputWindow->appendText(output.text, output.format);
} }
void CompileOutputWindow::clearContents() void CompileOutputWindow::clearContents()
......
...@@ -34,11 +34,11 @@ ...@@ -34,11 +34,11 @@
using namespace Utils; using namespace Utils;
typedef QList<StringFormatPair> ResultList; typedef QList<FormattedText> FormattedTextList;
Q_DECLARE_METATYPE(QTextCharFormat); Q_DECLARE_METATYPE(QTextCharFormat);
Q_DECLARE_METATYPE(StringFormatPair); Q_DECLARE_METATYPE(FormattedText);
Q_DECLARE_METATYPE(ResultList); Q_DECLARE_METATYPE(FormattedTextList);
static QString ansiEscape(const QByteArray &sequence) static QString ansiEscape(const QByteArray &sequence)
{ {
...@@ -76,16 +76,16 @@ void tst_AnsiEscapeCodeHandler::testSimpleFormat() ...@@ -76,16 +76,16 @@ void tst_AnsiEscapeCodeHandler::testSimpleFormat()
{ {
QFETCH(QString, text); QFETCH(QString, text);
QFETCH(QTextCharFormat, format); QFETCH(QTextCharFormat, format);
QFETCH(ResultList, expected); QFETCH(FormattedTextList, expected);
AnsiEscapeCodeHandler handler; AnsiEscapeCodeHandler handler;
ResultList result = handler.parseText(text, format); FormattedTextList result = handler.parseText(FormattedText(text, format));
handler.endFormatScope(); handler.endFormatScope();
QCOMPARE(result.size(), expected.size()); QCOMPARE(result.size(), expected.size());
for (int i = 0; i < result.size(); ++i) { for (int i = 0; i < result.size(); ++i) {
QCOMPARE(result[i].first, expected[i].first); QCOMPARE(result[i].text, expected[i].text);
QCOMPARE(result[i].second, expected[i].second); QCOMPARE(result[i].format, expected[i].format);
} }
} }
...@@ -93,40 +93,40 @@ void tst_AnsiEscapeCodeHandler::testSimpleFormat_data() ...@@ -93,40 +93,40 @@ void tst_AnsiEscapeCodeHandler::testSimpleFormat_data()
{ {
QTest::addColumn<QString>("text"); QTest::addColumn<QString>("text");
QTest::addColumn<QTextCharFormat>("format"); QTest::addColumn<QTextCharFormat>("format");
QTest::addColumn<ResultList>("expected"); QTest::addColumn<FormattedTextList>("expected");
// Test pass-through // Test pass-through
QTextCharFormat defaultFormat; QTextCharFormat defaultFormat;
QTest::newRow("Pass-through") << "Hello World" << defaultFormat QTest::newRow("Pass-through") << "Hello World" << defaultFormat
<< (ResultList() << StringFormatPair("Hello World", defaultFormat)); << (FormattedTextList() << FormattedText("Hello World", defaultFormat));
// Test text-color change // Test text-color change
QTextCharFormat redFormat; QTextCharFormat redFormat;
redFormat.setForeground(QColor(170, 0, 0)); redFormat.setForeground(QColor(170, 0, 0));
const QString text2 = "This is " + red + "red" + normal + " text"; const QString text2 = "This is " + red + "red" + normal + " text";
QTest::newRow("Text-color change") << text2 << QTextCharFormat() QTest::newRow("Text-color change") << text2 << QTextCharFormat()
<< (ResultList() << (FormattedTextList()
<< StringFormatPair("This is ", defaultFormat) << FormattedText("This is ", defaultFormat)
<< StringFormatPair("red", redFormat) << FormattedText("red", redFormat)
<< StringFormatPair(" text", defaultFormat)); << FormattedText(" text", defaultFormat));
// Test text format change to bold // Test text format change to bold
QTextCharFormat boldFormat; QTextCharFormat boldFormat;
boldFormat.setFontWeight(QFont::Bold); boldFormat.setFontWeight(QFont::Bold);
const QString text3 = "A line of " + bold + "bold" + normal + " text"; const QString text3 = "A line of " + bold + "bold" + normal + " text";
QTest::newRow("Text-format change") << text3 << QTextCharFormat() QTest::newRow("Text-format change") << text3 << QTextCharFormat()
<< (ResultList() << (FormattedTextList()
<< StringFormatPair("A line of ", defaultFormat) << FormattedText("A line of ", defaultFormat)
<< StringFormatPair("bold", boldFormat) << FormattedText("bold", boldFormat)
<< StringFormatPair(" text", defaultFormat)); << FormattedText(" text", defaultFormat));
// Test resetting format to normal with other reset pattern // Test resetting format to normal with other reset pattern
const QString text4 = "A line of " + bold + "bold" + normal1 + " text"; const QString text4 = "A line of " + bold + "bold" + normal1 + " text";
QTest::newRow("Alternative reset pattern (QTCREATORBUG-10132)") << text4 << QTextCharFormat() QTest::newRow("Alternative reset pattern (QTCREATORBUG-10132)") << text4 << QTextCharFormat()
<< (ResultList() << (FormattedTextList()
<< StringFormatPair("A line of ", defaultFormat) << FormattedText("A line of ", defaultFormat)
<< StringFormatPair("bold", boldFormat) << FormattedText("bold", boldFormat)
<< StringFormatPair(" text", defaultFormat)); << FormattedText(" text", defaultFormat));
} }
void tst_AnsiEscapeCodeHandler::testLineOverlappingFormat() void tst_AnsiEscapeCodeHandler::testLineOverlappingFormat()
...@@ -138,22 +138,22 @@ void tst_AnsiEscapeCodeHandler::testLineOverlappingFormat() ...@@ -138,22 +138,22 @@ void tst_AnsiEscapeCodeHandler::testLineOverlappingFormat()
QTextCharFormat defaultFormat; QTextCharFormat defaultFormat;
AnsiEscapeCodeHandler handler; AnsiEscapeCodeHandler handler;
ResultList result; FormattedTextList result;
result.append(handler.parseText(line1, defaultFormat)); result.append(handler.parseText(FormattedText(line1, defaultFormat)));
result.append(handler.parseText(line2, defaultFormat)); result.append(handler.parseText(FormattedText(line2, defaultFormat)));
QTextCharFormat boldFormat; QTextCharFormat boldFormat;
boldFormat.setFontWeight(QFont::Bold); boldFormat.setFontWeight(QFont::Bold);
QCOMPARE(result.size(), 4); QCOMPARE(result.size(), 4);
QCOMPARE(result[0].first, QLatin1String("A line of ")); QCOMPARE(result[0].text, QLatin1String("A line of "));
QCOMPARE(result[0].second, defaultFormat); QCOMPARE(result[0].format, defaultFormat);
QCOMPARE(result[1].first, QLatin1String("bold text")); QCOMPARE(result[1].text, QLatin1String("bold text"));
QCOMPARE(result[1].second, boldFormat); QCOMPARE(result[1].format, boldFormat);
QCOMPARE(result[2].first, QLatin1String("A line of ")); QCOMPARE(result[2].text, QLatin1String("A line of "));
QCOMPARE(result[2].second, boldFormat); QCOMPARE(result[2].format, boldFormat);
QCOMPARE(result[3].first, QLatin1String("normal text")); QCOMPARE(result[3].text, QLatin1String("normal text"));
QCOMPARE(result[3].second, defaultFormat); QCOMPARE(result[3].format, defaultFormat);
} }
QTEST_APPLESS_MAIN(tst_AnsiEscapeCodeHandler) QTEST_APPLESS_MAIN(tst_AnsiEscapeCodeHandler)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment