aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/utils/outputformatter.cpp86
-rw-r--r--src/libs/utils/outputformatter.h39
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