diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2020-03-19 16:00:37 +0100 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2020-03-20 13:48:15 +0000 |
commit | 04a99c1de16e1d04bcc1908fec7464d15b421702 (patch) | |
tree | 1f298306aae0ae288bac75b0691c8968e6c72e6b /src/libs/utils/outputformatter.cpp | |
parent | 7158e676121767f43ac542cc3c958d8ed1279436 (diff) |
Remove the limitation that output formatters have to be exclusive
Introduce an aggregating output formatter that forwards its input to a
sub-formatter that feels responsible for it, or otherwise lets the base
class handle it.
Our output panes now use such an aggregating formatter.
In particular, this means that in the future, we won't have to stuff all
run control output formatting into the Qt output formatter anymore.
Change-Id: I5498f200a61db10ccff3ec8974c6825da7f7072d
Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'src/libs/utils/outputformatter.cpp')
-rw-r--r-- | src/libs/utils/outputformatter.cpp | 86 |
1 files changed, 82 insertions, 4 deletions
diff --git a/src/libs/utils/outputformatter.cpp b/src/libs/utils/outputformatter.cpp index ea40ddadee..a1a98a1fbe 100644 --- a/src/libs/utils/outputformatter.cpp +++ b/src/libs/utils/outputformatter.cpp @@ -25,8 +25,10 @@ #include "ansiescapecodehandler.h" #include "outputformatter.h" +#include "qtcassert.h" #include "synchronousprocess.h" #include "theme/theme.h" +#include "utils/optional.h" #include <QPair> #include <QPlainTextEdit> @@ -44,6 +46,7 @@ public: QTextCursor cursor; AnsiEscapeCodeHandler escapeCodeHandler; QPair<QString, OutputFormat> incompleteLine; + optional<QTextCharFormat> formatOverride; bool boldFontEnabled = true; bool prependCarriageReturn = false; }; @@ -75,9 +78,15 @@ void OutputFormatter::setPlainTextEdit(QPlainTextEdit *plainText) void OutputFormatter::doAppendMessage(const QString &text, OutputFormat format) { - if (!d->cursor.atEnd() && text.startsWith('\n')) - d->cursor.movePosition(QTextCursor::End); - doAppendMessage(text, d->formats[format]); + if (handleMessage(text, format) == Status::NotHandled) + appendMessageDefault(text, format); +} + +OutputFormatter::Status OutputFormatter::handleMessage(const QString &text, OutputFormat format) +{ + Q_UNUSED(text); + Q_UNUSED(format); + return Status::NotHandled; } void OutputFormatter::doAppendMessage(const QString &text, const QTextCharFormat &format) @@ -118,6 +127,16 @@ QTextCharFormat OutputFormatter::linkFormat(const QTextCharFormat &inputFormat, return result; } +void OutputFormatter::overrideTextCharFormat(const QTextCharFormat &fmt) +{ + d->formatOverride = fmt; +} + +void OutputFormatter::appendMessageDefault(const QString &text, OutputFormat format) +{ + doAppendMessage(text, d->formatOverride ? d->formatOverride.value() : d->formats[format]); +} + void OutputFormatter::clearLastLine() { // Note that this approach will fail if the text edit is not read-only and users @@ -158,9 +177,10 @@ void OutputFormatter::dumpIncompleteLine(const QString &line, OutputFormat forma d->incompleteLine.second = format; } -void OutputFormatter::handleLink(const QString &href) +bool OutputFormatter::handleLink(const QString &href) { Q_UNUSED(href) + return false; } void OutputFormatter::clear() @@ -236,4 +256,62 @@ void OutputFormatter::appendMessage(const QString &text, OutputFormat format) } } +class AggregatingOutputFormatter::Private +{ +public: + QList<OutputFormatter *> formatters; + OutputFormatter *nextFormatter = nullptr; +}; + +AggregatingOutputFormatter::AggregatingOutputFormatter() : d(new Private) {} +AggregatingOutputFormatter::~AggregatingOutputFormatter() { delete d; } + +void AggregatingOutputFormatter::setFormatters(const QList<OutputFormatter *> &formatters) +{ + for (OutputFormatter * const f : formatters) + f->setPlainTextEdit(plainTextEdit()); + d->formatters = formatters; + d->nextFormatter = nullptr; +} + +OutputFormatter::Status AggregatingOutputFormatter::handleMessage(const QString &text, + OutputFormat format) +{ + if (d->nextFormatter) { + switch (d->nextFormatter->handleMessage(text, format)) { + case Status::Done: + d->nextFormatter = nullptr; + return Status::Done; + case Status::InProgress: + return Status::InProgress; + case Status::NotHandled: + QTC_CHECK(false); + d->nextFormatter = nullptr; + return Status::NotHandled; + } + } + QTC_CHECK(!d->nextFormatter); + for (OutputFormatter * const formatter : qAsConst(d->formatters)) { + switch (formatter->handleMessage(text, format)) { + case Status::Done: + return Status::Done; + case Status::InProgress: + d->nextFormatter = formatter; + return Status::InProgress; + case Status::NotHandled: + break; + } + } + return Status::NotHandled; +} + +bool AggregatingOutputFormatter::handleLink(const QString &href) +{ + for (OutputFormatter * const f : qAsConst(d->formatters)) { + if (f->handleLink(href)) + return true; + } + return false; +} + } // namespace Utils |