Move some code from OutputWindow to OutputFormatter

That's where it belongs: The logic there is applicable to all output
formatters, not just those used via an output window.

Change-Id: Idf4ca8d22631ca96feb97553f28724c0275e0bf8
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2020-03-13 17:17:05 +01:00
parent f88789081d
commit 0ff5bf75e1
9 changed files with 98 additions and 95 deletions

View File

@@ -25,6 +25,7 @@
#include "ansiescapecodehandler.h" #include "ansiescapecodehandler.h"
#include "outputformatter.h" #include "outputformatter.h"
#include "synchronousprocess.h"
#include "theme/theme.h" #include "theme/theme.h"
#include <QPlainTextEdit> #include <QPlainTextEdit>
@@ -42,6 +43,8 @@ public:
QTextCursor cursor; QTextCursor cursor;
AnsiEscapeCodeHandler escapeCodeHandler; AnsiEscapeCodeHandler escapeCodeHandler;
bool boldFontEnabled = true; bool boldFontEnabled = true;
bool enforceNewline = false;
bool prependCarriageReturn = false;
}; };
} // namespace Internal } // namespace Internal
@@ -69,14 +72,14 @@ void OutputFormatter::setPlainTextEdit(QPlainTextEdit *plainText)
initFormats(); initFormats();
} }
void OutputFormatter::appendMessage(const QString &text, OutputFormat format) void OutputFormatter::doAppendMessage(const QString &text, OutputFormat format)
{ {
if (!d->cursor.atEnd() && text.startsWith('\n')) if (!d->cursor.atEnd() && text.startsWith('\n'))
d->cursor.movePosition(QTextCursor::End); d->cursor.movePosition(QTextCursor::End);
appendMessage(text, d->formats[format]); doAppendMessage(text, d->formats[format]);
} }
void OutputFormatter::appendMessage(const QString &text, const QTextCharFormat &format) void OutputFormatter::doAppendMessage(const QString &text, const QTextCharFormat &format)
{ {
const QList<FormattedText> formattedTextList = parseAnsi(text, format); const QList<FormattedText> formattedTextList = parseAnsi(text, format);
for (const FormattedText &output : formattedTextList) for (const FormattedText &output : formattedTextList)
@@ -169,6 +172,12 @@ void OutputFormatter::handleLink(const QString &href)
Q_UNUSED(href) Q_UNUSED(href)
} }
void OutputFormatter::clear()
{
d->enforceNewline = false;
d->prependCarriageReturn = false;
}
void OutputFormatter::setBoldFontEnabled(bool enabled) void OutputFormatter::setBoldFontEnabled(bool enabled)
{ {
d->boldFontEnabled = enabled; d->boldFontEnabled = enabled;
@@ -182,4 +191,66 @@ void OutputFormatter::flush()
d->escapeCodeHandler.endFormatScope(); d->escapeCodeHandler.endFormatScope();
} }
void OutputFormatter::appendMessage(const QString &text, OutputFormat format)
{
QString out = text;
if (d->prependCarriageReturn) {
d->prependCarriageReturn = false;
out.prepend('\r');
}
out = SynchronousProcess::normalizeNewlines(out);
if (out.endsWith('\r')) {
d->prependCarriageReturn = true;
out.chop(1);
}
if (format == ErrorMessageFormat || format == NormalMessageFormat) {
doAppendMessage(doNewlineEnforcement(out), format);
} else {
const bool sameLine = format == StdOutFormatSameLine || format == StdErrFormatSameLine;
if (sameLine) {
bool enforceNewline = d->enforceNewline;
d->enforceNewline = false;
if (enforceNewline) {
out.prepend('\n');
} else {
const int newline = out.indexOf('\n');
plainTextEdit()->moveCursor(QTextCursor::End);
if (newline != -1) {
doAppendMessage(out.left(newline), format);// doesn't enforce new paragraph like appendPlainText
out = out.mid(newline);
}
}
if (out.isEmpty()) {
d->enforceNewline = true;
} else {
if (out.endsWith('\n')) {
d->enforceNewline = true;
out.chop(1);
}
doAppendMessage(out, format);
}
} else {
doAppendMessage(doNewlineEnforcement(out), format);
}
}
}
QString OutputFormatter::doNewlineEnforcement(const QString &out)
{
QString s = out;
if (d->enforceNewline) {
s.prepend('\n');
d->enforceNewline = false;
}
if (s.endsWith('\n')) {
d->enforceNewline = true; // make appendOutputInline put in a newline next time
s.chop(1);
}
return s;
}
} // namespace Utils } // namespace Utils

View File

@@ -54,10 +54,11 @@ public:
void flush(); void flush();
virtual void appendMessage(const QString &text, OutputFormat format); void appendMessage(const QString &text, OutputFormat format);
virtual void handleLink(const QString &href); virtual void handleLink(const QString &href);
virtual QList<QWidget *> toolbarWidgets() const { return {}; } virtual QList<QWidget *> toolbarWidgets() const { return {}; }
virtual void clear() {} virtual void clear();
void setBoldFontEnabled(bool enabled); void setBoldFontEnabled(bool enabled);
static QTextCharFormat linkFormat(const QTextCharFormat &inputFormat, const QString &href); static QTextCharFormat linkFormat(const QTextCharFormat &inputFormat, const QString &href);
@@ -66,11 +67,14 @@ protected:
virtual void clearLastLine(); virtual void clearLastLine();
QTextCharFormat charFormat(OutputFormat format) const; QTextCharFormat charFormat(OutputFormat format) const;
QList<FormattedText> parseAnsi(const QString &text, const QTextCharFormat &format); QList<FormattedText> parseAnsi(const QString &text, const QTextCharFormat &format);
virtual void doAppendMessage(const QString &text, OutputFormat format);
void append(const QString &text, const QTextCharFormat &format); void append(const QString &text, const QTextCharFormat &format);
QTextCursor &cursor() const; QTextCursor &cursor() const;
private: private:
virtual void appendMessage(const QString &text, const QTextCharFormat &format); QString doNewlineEnforcement(const QString &out);
virtual void doAppendMessage(const QString &text, const QTextCharFormat &format);
Internal::OutputFormatterPrivate *d; Internal::OutputFormatterPrivate *d;
}; };

View File

@@ -30,7 +30,6 @@
#include "icore.h" #include "icore.h"
#include <utils/outputformatter.h> #include <utils/outputformatter.h>
#include <utils/synchronousprocess.h>
#include <QAction> #include <QAction>
#include <QCursor> #include <QCursor>
@@ -65,8 +64,6 @@ public:
QString settingsKey; QString settingsKey;
OutputFormatter defaultFormatter; OutputFormatter defaultFormatter;
bool enforceNewline = false;
bool prependCarriageReturn = false;
bool scrollToBottom = true; bool scrollToBottom = true;
bool linksActive = true; bool linksActive = true;
bool zoomEnabled = false; bool zoomEnabled = false;
@@ -362,23 +359,6 @@ void OutputWindow::filterNewContent()
scrollToBottom(); scrollToBottom();
} }
QString OutputWindow::doNewlineEnforcement(const QString &out)
{
d->scrollToBottom = true;
QString s = out;
if (d->enforceNewline) {
s.prepend('\n');
d->enforceNewline = false;
}
if (s.endsWith('\n')) {
d->enforceNewline = true; // make appendOutputInline put in a newline next time
s.chop(1);
}
return s;
}
void OutputWindow::setMaxCharCount(int count) void OutputWindow::setMaxCharCount(int count)
{ {
d->maxCharCount = count; d->maxCharCount = count;
@@ -393,16 +373,6 @@ int OutputWindow::maxCharCount() const
void OutputWindow::appendMessage(const QString &output, OutputFormat format) void OutputWindow::appendMessage(const QString &output, OutputFormat format)
{ {
QString out = output; QString out = output;
if (d->prependCarriageReturn) {
d->prependCarriageReturn = false;
out.prepend('\r');
}
out = SynchronousProcess::normalizeNewlines(out);
if (out.endsWith('\r')) {
d->prependCarriageReturn = true;
out.chop(1);
}
if (out.size() > d->maxCharCount) { if (out.size() > d->maxCharCount) {
// Current line alone exceeds limit, we need to cut it. // Current line alone exceeds limit, we need to cut it.
out.truncate(d->maxCharCount); out.truncate(d->maxCharCount);
@@ -425,44 +395,8 @@ void OutputWindow::appendMessage(const QString &output, OutputFormat format)
} }
const bool atBottom = isScrollbarAtBottom() || m_scrollTimer.isActive(); const bool atBottom = isScrollbarAtBottom() || m_scrollTimer.isActive();
d->scrollToBottom = true;
if (format == ErrorMessageFormat || format == NormalMessageFormat) { d->formatter->appendMessage(out, format);
d->formatter->appendMessage(doNewlineEnforcement(out), format);
} else {
bool sameLine = format == StdOutFormatSameLine
|| format == StdErrFormatSameLine;
if (sameLine) {
d->scrollToBottom = true;
bool enforceNewline = d->enforceNewline;
d->enforceNewline = false;
if (enforceNewline) {
out.prepend('\n');
} else {
const int newline = out.indexOf('\n');
moveCursor(QTextCursor::End);
if (newline != -1) {
d->formatter->appendMessage(out.left(newline), format);// doesn't enforce new paragraph like appendPlainText
out = out.mid(newline);
}
}
if (out.isEmpty()) {
d->enforceNewline = true;
} else {
if (out.endsWith('\n')) {
d->enforceNewline = true;
out.chop(1);
}
d->formatter->appendMessage(out, format);
}
} else {
d->formatter->appendMessage(doNewlineEnforcement(out), format);
}
}
if (atBottom) { if (atBottom) {
if (m_lastMessage.elapsed() < 5) { if (m_lastMessage.elapsed() < 5) {
@@ -511,8 +445,6 @@ QMimeData *OutputWindow::createMimeDataFromSelection() const
void OutputWindow::clear() void OutputWindow::clear()
{ {
d->enforceNewline = false;
d->prependCarriageReturn = false;
QPlainTextEdit::clear(); QPlainTextEdit::clear();
d->formatter->clear(); d->formatter->clear();
} }

View File

@@ -103,7 +103,6 @@ private:
QTimer m_scrollTimer; QTimer m_scrollTimer;
QElapsedTimer m_lastMessage; QElapsedTimer m_lastMessage;
void enableUndoRedo(); void enableUndoRedo();
QString doNewlineEnforcement(const QString &out);
void filterNewContent(); void filterNewContent();
Internal::OutputWindowPrivate *d = nullptr; Internal::OutputWindowPrivate *d = nullptr;

View File

@@ -71,7 +71,7 @@ public:
} }
private: private:
void appendMessage(const QString &text, OutputFormat format) final void doAppendMessage(const QString &text, OutputFormat format) final
{ {
const bool isTrace = (format == StdErrFormat const bool isTrace = (format == StdErrFormat
|| format == StdErrFormatSameLine) || format == StdErrFormatSameLine)
@@ -79,7 +79,7 @@ private:
|| text.startsWith("\nTraceback (most recent call last):")); || text.startsWith("\nTraceback (most recent call last):"));
if (!isTrace) { if (!isTrace) {
OutputFormatter::appendMessage(text, format); OutputFormatter::doAppendMessage(text, format);
return; return;
} }
@@ -110,7 +110,7 @@ private:
task.description += ' '; task.description += ' ';
task.description += line.trimmed(); task.description += line.trimmed();
} }
OutputFormatter::appendMessage('\n' + line, format); OutputFormatter::doAppendMessage('\n' + line, format);
} }
} }
if (!tasks.isEmpty()) { if (!tasks.isEmpty()) {

View File

@@ -92,7 +92,7 @@ public:
explicit QtOutputFormatter(Target *target); explicit QtOutputFormatter(Target *target);
~QtOutputFormatter() override; ~QtOutputFormatter() override;
void appendMessage(const QString &text, Utils::OutputFormat format) override; void doAppendMessage(const QString &text, Utils::OutputFormat format) override;
void handleLink(const QString &href) override; void handleLink(const QString &href) override;
protected: protected:
@@ -105,7 +105,7 @@ private:
void appendMessagePart(const QString &txt, const QTextCharFormat &fmt); void appendMessagePart(const QString &txt, const QTextCharFormat &fmt);
void appendLine(const LinkResult &lr, const QString &line, Utils::OutputFormat format); void appendLine(const LinkResult &lr, const QString &line, Utils::OutputFormat format);
void appendLine(const LinkResult &lr, const QString &line, const QTextCharFormat &format); void appendLine(const LinkResult &lr, const QString &line, const QTextCharFormat &format);
void appendMessage(const QString &text, const QTextCharFormat &format) override; void doAppendMessage(const QString &text, const QTextCharFormat &format) override;
QtOutputFormatterPrivate *d; QtOutputFormatterPrivate *d;
friend class QtSupportPlugin; // for testing friend class QtSupportPlugin; // for testing
@@ -163,9 +163,9 @@ LinkResult QtOutputFormatter::matchLine(const QString &line) const
return lr; return lr;
} }
void QtOutputFormatter::appendMessage(const QString &txt, OutputFormat format) void QtOutputFormatter::doAppendMessage(const QString &txt, OutputFormat format)
{ {
appendMessage(txt, charFormat(format)); doAppendMessage(txt, charFormat(format));
} }
void QtOutputFormatter::appendMessagePart(const QString &txt, const QTextCharFormat &fmt) void QtOutputFormatter::appendMessagePart(const QString &txt, const QTextCharFormat &fmt)
@@ -209,7 +209,7 @@ void QtOutputFormatter::appendMessagePart(const QString &txt, const QTextCharFor
cursor().insertText(deferredText, fmt); cursor().insertText(deferredText, fmt);
} }
void QtOutputFormatter::appendMessage(const QString &txt, const QTextCharFormat &format) void QtOutputFormatter::doAppendMessage(const QString &txt, const QTextCharFormat &format)
{ {
if (!cursor().atEnd()) if (!cursor().atEnd())
cursor().movePosition(QTextCursor::End); cursor().movePosition(QTextCursor::End);
@@ -558,7 +558,7 @@ void QtSupportPlugin::testQtOutputFormatter_appendMessage()
QFETCH(QTextCharFormat, inputFormat); QFETCH(QTextCharFormat, inputFormat);
QFETCH(QTextCharFormat, outputFormat); QFETCH(QTextCharFormat, outputFormat);
formatter.appendMessage(inputText, inputFormat); formatter.doAppendMessage(inputText, inputFormat);
QCOMPARE(edit.toPlainText(), outputText); QCOMPARE(edit.toPlainText(), outputText);
QCOMPARE(edit.currentCharFormat(), outputFormat); QCOMPARE(edit.currentCharFormat(), outputFormat);
@@ -579,7 +579,7 @@ void QtSupportPlugin::testQtOutputFormatter_appendMixedAssertAndAnsi()
"file://test.cpp:123 " "file://test.cpp:123 "
"Blue\n"; "Blue\n";
formatter.appendMessage(inputText, QTextCharFormat()); formatter.doAppendMessage(inputText, QTextCharFormat());
QCOMPARE(edit.toPlainText(), outputText); QCOMPARE(edit.toPlainText(), outputText);

View File

@@ -42,14 +42,14 @@ VcsOutputFormatter::VcsOutputFormatter() :
{ {
} }
void VcsOutputFormatter::appendMessage(const QString &text, Utils::OutputFormat format) void VcsOutputFormatter::doAppendMessage(const QString &text, Utils::OutputFormat format)
{ {
QRegularExpressionMatchIterator it = m_regexp.globalMatch(text); QRegularExpressionMatchIterator it = m_regexp.globalMatch(text);
int begin = 0; int begin = 0;
while (it.hasNext()) { while (it.hasNext()) {
const QRegularExpressionMatch match = it.next(); const QRegularExpressionMatch match = it.next();
const QTextCharFormat normalFormat = charFormat(format); const QTextCharFormat normalFormat = charFormat(format);
OutputFormatter::appendMessage(text.mid(begin, match.capturedStart() - begin), format); OutputFormatter::doAppendMessage(text.mid(begin, match.capturedStart() - begin), format);
QTextCursor tc = plainTextEdit()->textCursor(); QTextCursor tc = plainTextEdit()->textCursor();
QStringView url = match.capturedView(); QStringView url = match.capturedView();
begin = match.capturedEnd(); begin = match.capturedEnd();
@@ -61,7 +61,7 @@ void VcsOutputFormatter::appendMessage(const QString &text, Utils::OutputFormat
tc.insertText(url.toString(), linkFormat(normalFormat, url.toString())); tc.insertText(url.toString(), linkFormat(normalFormat, url.toString()));
tc.movePosition(QTextCursor::End); tc.movePosition(QTextCursor::End);
} }
OutputFormatter::appendMessage(text.mid(begin), format); OutputFormatter::doAppendMessage(text.mid(begin), format);
} }
void VcsOutputFormatter::handleLink(const QString &href) void VcsOutputFormatter::handleLink(const QString &href)

View File

@@ -37,7 +37,7 @@ class VcsOutputFormatter : public Utils::OutputFormatter
public: public:
VcsOutputFormatter(); VcsOutputFormatter();
~VcsOutputFormatter() override = default; ~VcsOutputFormatter() override = default;
void appendMessage(const QString &text, Utils::OutputFormat format) override; void doAppendMessage(const QString &text, Utils::OutputFormat format) override;
void handleLink(const QString &href) override; void handleLink(const QString &href) override;
void fillLinkContextMenu(QMenu *menu, const QString &workingDirectory, const QString &href); void fillLinkContextMenu(QMenu *menu, const QString &workingDirectory, const QString &href);

View File

@@ -228,10 +228,7 @@ void OutputWindowPlainTextEdit::appendLines(const QString &s, const QString &rep
const int previousLineCount = document()->lineCount(); const int previousLineCount = document()->lineCount();
const QChar newLine('\n'); m_formatter->appendMessage(s, m_format);
const QChar lastChar = s.at(s.size() - 1);
const bool appendNewline = (lastChar != '\r' && lastChar != newLine);
m_formatter->appendMessage(appendNewline ? s + newLine : s, m_format);
// Scroll down // Scroll down
moveCursor(QTextCursor::End); moveCursor(QTextCursor::End);