diff options
Diffstat (limited to 'src/libs/utils')
-rw-r--r-- | src/libs/utils/outputformatter.cpp | 86 | ||||
-rw-r--r-- | src/libs/utils/outputformatter.h | 39 |
2 files changed, 114 insertions, 11 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 diff --git a/src/libs/utils/outputformatter.h b/src/libs/utils/outputformatter.h index a5d9c4b331..0aaf880714 100644 --- a/src/libs/utils/outputformatter.h +++ b/src/libs/utils/outputformatter.h @@ -42,8 +42,11 @@ class FormattedText; namespace Internal { class OutputFormatterPrivate; } +class QTCREATOR_UTILS_EXPORT AggregatingOutputFormatter; + class QTCREATOR_UTILS_EXPORT OutputFormatter : public QObject { + friend class AggregatingOutputFormatter; public: OutputFormatter(); ~OutputFormatter() override; @@ -55,26 +58,32 @@ public: void appendMessage(const QString &text, OutputFormat format); - virtual void handleLink(const QString &href); + virtual bool handleLink(const QString &href); void clear(); void setBoldFontEnabled(bool enabled); static QTextCharFormat linkFormat(const QTextCharFormat &inputFormat, const QString &href); -protected: - // text contains at most one line feed character, and if it does occur, it's the last character. - // Either way, the input is to be considered "complete" for formatting purposes. - virtual void doAppendMessage(const QString &text, OutputFormat format); + // For unit testing only + void overrideTextCharFormat(const QTextCharFormat &fmt); - virtual void clearLastLine(); +protected: + enum class Status { Done, InProgress, NotHandled }; + void appendMessageDefault(const QString &text, OutputFormat format); + void clearLastLine(); QTextCharFormat charFormat(OutputFormat format) const; QList<FormattedText> parseAnsi(const QString &text, const QTextCharFormat &format); QTextCursor &cursor() const; private: - void doAppendMessage(const QString &text, const QTextCharFormat &format); + // text contains at most one line feed character, and if it does occur, it's the last character. + // Either way, the input is to be considered "complete" for formatting purposes. + void doAppendMessage(const QString &text, OutputFormat format); + + virtual Status handleMessage(const QString &text, OutputFormat format); virtual void reset() {} + void doAppendMessage(const QString &text, const QTextCharFormat &format); void append(const QString &text, const QTextCharFormat &format); void initFormats(); void flushIncompleteLine(); @@ -83,4 +92,20 @@ private: Internal::OutputFormatterPrivate *d; }; +class QTCREATOR_UTILS_EXPORT AggregatingOutputFormatter : public OutputFormatter +{ +public: + AggregatingOutputFormatter(); + ~AggregatingOutputFormatter(); + + void setFormatters(const QList<OutputFormatter *> &formatters); + bool handleLink(const QString &href) override; + +private: + Status handleMessage(const QString &text, OutputFormat format) override; + + class Private; + Private * const d; +}; + } // namespace Utils |