diff options
Diffstat (limited to 'src/libs/utils/outputformatter.h')
-rw-r--r-- | src/libs/utils/outputformatter.h | 152 |
1 files changed, 134 insertions, 18 deletions
diff --git a/src/libs/utils/outputformatter.h b/src/libs/utils/outputformatter.h index 5b7acb0337..6c8539d3ed 100644 --- a/src/libs/utils/outputformatter.h +++ b/src/libs/utils/outputformatter.h @@ -26,56 +26,172 @@ #pragma once #include "utils_global.h" +#include "fileutils.h" +#include "optional.h" #include "outputformat.h" #include <QObject> -#include <QFont> + +#include <functional> QT_BEGIN_NAMESPACE class QPlainTextEdit; +class QRegularExpressionMatch; class QTextCharFormat; class QTextCursor; QT_END_NAMESPACE namespace Utils { - +class FileInProjectFinder; class FormattedText; -namespace Internal { class OutputFormatterPrivate; } +class QTCREATOR_UTILS_EXPORT OutputLineParser : public QObject +{ + Q_OBJECT +public: + OutputLineParser(); + ~OutputLineParser() override; + + enum class Status { Done, InProgress, NotHandled }; + class LinkSpec { + public: + LinkSpec() = default; + LinkSpec(int sp, int l, const QString &t) : startPos(sp), length(l), target(t) {} + int startPos = -1; + int length = -1; + QString target; + }; + using LinkSpecs = QList<LinkSpec>; + class Result { + public: + Result(Status s, const LinkSpecs &l = {}, const optional<QString> &c = {}) + : status(s), linkSpecs(l), newContent(c) {} + Status status; + LinkSpecs linkSpecs; + optional<QString> newContent; // Hard content override. Only to be used in extreme cases. + }; + + static bool isLinkTarget(const QString &target); + static void parseLinkTarget(const QString &target, FilePath &filePath, int &line, int &column); + + void addSearchDir(const Utils::FilePath &dir); + void dropSearchDir(const Utils::FilePath &dir); + const FilePaths searchDirectories() const; + + void setFileFinder(Utils::FileInProjectFinder *finder); + + void setDemoteErrorsToWarnings(bool demote); + bool demoteErrorsToWarnings() const; + + // line 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 parsing purposes. + virtual Result handleLine(const QString &line, OutputFormat format) = 0; + + virtual bool handleLink(const QString &href) { Q_UNUSED(href); return false; } + virtual bool hasFatalErrors() const { return false; } + virtual void flush() {} + virtual void runPostPrintActions() {} + + void setRedirectionDetector(const OutputLineParser *detector); + bool needsRedirection() const; + virtual bool hasDetectedRedirection() const { return false; } + +#ifdef WITH_TESTS + void skipFileExistsCheck(); +#endif + +protected: + static QString rightTrimmed(const QString &in); + Utils::FilePath absoluteFilePath(const Utils::FilePath &filePath); + static QString createLinkTarget(const FilePath &filePath, int line, int column); + void addLinkSpecForAbsoluteFilePath(LinkSpecs &linkSpecs, const FilePath &filePath, + int lineNo, int pos, int len); + void addLinkSpecForAbsoluteFilePath(LinkSpecs &linkSpecs, const FilePath &filePath, + int lineNo, const QRegularExpressionMatch &match, + int capIndex); + void addLinkSpecForAbsoluteFilePath(LinkSpecs &linkSpecs, const FilePath &filePath, + int lineNo, const QRegularExpressionMatch &match, + const QString &capName); + +signals: + void newSearchDir(const Utils::FilePath &dir); + void searchDirExpired(const Utils::FilePath &dir); + +private: + class Private; + Private * const d; +}; class QTCREATOR_UTILS_EXPORT OutputFormatter : public QObject { Q_OBJECT - public: OutputFormatter(); ~OutputFormatter() override; QPlainTextEdit *plainTextEdit() const; - virtual void setPlainTextEdit(QPlainTextEdit *plainText); + void setPlainTextEdit(QPlainTextEdit *plainText); + + // Forwards to line parsers. Add those before. + void addSearchDir(const FilePath &dir); + void dropSearchDir(const FilePath &dir); + + void setLineParsers(const QList<OutputLineParser *> &parsers); // Takes ownership + void addLineParsers(const QList<OutputLineParser *> &parsers); + void addLineParser(OutputLineParser *parser); + + void setFileFinder(const FileInProjectFinder &finder); + void setDemoteErrorsToWarnings(bool demote); - void flush(); + using PostPrintAction = std::function<void(OutputLineParser *)>; + void overridePostPrintAction(const PostPrintAction &postPrintAction); - virtual void appendMessage(const QString &text, OutputFormat format); - virtual void handleLink(const QString &href); - virtual QList<QWidget *> toolbarWidgets() const { return {}; } - virtual void clear() {} + void appendMessage(const QString &text, OutputFormat format); + void flush(); // Flushes in-flight data. + void clear(); // Clears the text edit, if there is one. + void reset(); // Wipes everything except the text edit. + + bool handleFileLink(const QString &href); + void handleLink(const QString &href); void setBoldFontEnabled(bool enabled); + + bool hasFatalErrors() const; + + static const QList<Utils::FormattedText> linkifiedText(const QList<FormattedText> &text, + const OutputLineParser::LinkSpecs &linkSpecs); + +#ifdef WITH_TESTS + void overrideTextCharFormat(const QTextCharFormat &fmt); + QList<OutputLineParser *> lineParsers() const; +#endif + +#ifndef WITH_TESTS +private: +#endif + QTextCharFormat charFormat(OutputFormat format) const; static QTextCharFormat linkFormat(const QTextCharFormat &inputFormat, const QString &href); signals: - void contentChanged(); + void openInEditorRequested(const FilePath &filePath, int line, int column); -protected: +private: + void doAppendMessage(const QString &text, OutputFormat format); + + OutputLineParser::Result handleMessage(const QString &text, OutputFormat format, + QList<OutputLineParser *> &involvedParsers); + + void append(const QString &text, const QTextCharFormat &format); void initFormats(); - virtual void clearLastLine(); - QTextCharFormat charFormat(OutputFormat format) const; + void flushIncompleteLine(); + void dumpIncompleteLine(const QString &line, OutputFormat format); + void clearLastLine(); QList<FormattedText> parseAnsi(const QString &text, const QTextCharFormat &format); - void append(const QString &text, const QTextCharFormat &format); + OutputFormat outputTypeForParser(const OutputLineParser *parser, OutputFormat type) const; + void setupLineParser(OutputLineParser *parser); -private: - virtual void appendMessage(const QString &text, const QTextCharFormat &format); - Internal::OutputFormatterPrivate *d; + class Private; + Private * const d; }; + } // namespace Utils |