Merge output formatters and output parsers

Now only one piece of code needs to be written to both linkify output in
an output pane and create tasks for it in the issues pane.
The calling sites are also simplified. For instance, until now, build
steps had to feed their output parsers manually and then push the
created tasks up the signal stack in parallel with the actual output,
which the build manager relied upon for cross-linking the output pane
content. Afterwards, the output would get forwarded to the formatter
(and parsed for ANSI escape codes a second time). In contrast, a build
step now just forwards the process output, and task parsing as well as
output formatting is done centrally further up the stack.
Concrete user-visible improvements so far:
    - File paths in compiler/linker messages are clickable links now.
    - QtTest applications now create clickable links also when run
      as part of a build step, not just in the app output pane.

Task-number: QTCREATORBUG-22665
Change-Id: Ic9fb95b2d97f2520ab3ec653315e9219466ec08d
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Christian Kandeler
2020-04-16 13:53:05 +02:00
parent b7851eeb55
commit 1c6e4fbd32
115 changed files with 1124 additions and 1179 deletions

View File

@@ -24,12 +24,14 @@
****************************************************************************/
#include "compileoutputwindow.h"
#include "buildmanager.h"
#include "showoutputtaskhandler.h"
#include "task.h"
#include "ioutputparser.h"
#include "projectexplorer.h"
#include "projectexplorericons.h"
#include "projectexplorersettings.h"
#include "showoutputtaskhandler.h"
#include "task.h"
#include "taskhub.h"
#include <coreplugin/outputwindow.h>
@@ -40,7 +42,8 @@
#include <texteditor/texteditorsettings.h>
#include <texteditor/fontsettings.h>
#include <texteditor/behaviorsettings.h>
#include <utils/outputformat.h>
#include <utils/algorithm.h>
#include <utils/outputformatter.h>
#include <utils/proxyaction.h>
#include <utils/theme/theme.h>
#include <utils/utilsicons.h>
@@ -67,74 +70,29 @@ const char WRAP_OUTPUT_KEY[] = "ProjectExplorer/Settings/WrapBuildOutput";
const char MAX_LINES_KEY[] = "ProjectExplorer/Settings/MaxBuildOutputLines";
const char OPTIONS_PAGE_ID[] = "C.ProjectExplorer.CompileOutputOptions";
class CompileOutputTextEdit : public Core::OutputWindow
{
Q_OBJECT
public:
CompileOutputTextEdit(const Core::Context &context) : Core::OutputWindow(context, SETTINGS_KEY)
{
setMouseTracking(true);
}
void addTask(const Task &task, int blocknumber)
{
m_taskids.insert(blocknumber, task.taskId);
}
void clearTasks()
{
m_taskids.clear();
}
protected:
void mouseMoveEvent(QMouseEvent *ev) override
{
const int line = cursorForPosition(ev->pos()).block().blockNumber();
if (m_taskids.contains(line) && m_mousePressButton == Qt::NoButton)
viewport()->setCursor(Qt::PointingHandCursor);
else
viewport()->setCursor(Qt::IBeamCursor);
QPlainTextEdit::mouseMoveEvent(ev);
}
void mousePressEvent(QMouseEvent *ev) override
{
m_mousePressPosition = ev->pos();
m_mousePressButton = ev->button();
QPlainTextEdit::mousePressEvent(ev);
}
void mouseReleaseEvent(QMouseEvent *ev) override
{
if ((m_mousePressPosition - ev->pos()).manhattanLength() < 4
&& m_mousePressButton == Qt::LeftButton) {
int line = cursorForPosition(ev->pos()).block().blockNumber();
if (unsigned taskid = m_taskids.value(line, 0))
TaskHub::showTaskInEditor(taskid);
}
m_mousePressButton = Qt::NoButton;
QPlainTextEdit::mouseReleaseEvent(ev);
}
private:
QHash<int, unsigned int> m_taskids; //Map blocknumber to taskId
QPoint m_mousePressPosition;
Qt::MouseButton m_mousePressButton = Qt::NoButton;
};
CompileOutputWindow::CompileOutputWindow(QAction *cancelBuildAction) :
m_cancelBuildButton(new QToolButton),
m_settingsButton(new QToolButton)
{
Core::Context context(C_COMPILE_OUTPUT);
m_outputWindow = new CompileOutputTextEdit(context);
m_outputWindow = new Core::OutputWindow(context, SETTINGS_KEY);
m_outputWindow->setWindowTitle(displayName());
m_outputWindow->setWindowIcon(Icons::WINDOW.icon());
m_outputWindow->setReadOnly(true);
m_outputWindow->setUndoRedoEnabled(false);
m_outputWindow->setMaxCharCount(Core::Constants::DEFAULT_MAX_CHAR_COUNT);
outputFormatter()->overridePostPrintAction([this](Utils::OutputLineParser *parser) {
if (const auto taskParser = qobject_cast<OutputTaskParser *>(parser)) {
int offset = 0;
Utils::reverseForeach(taskParser->taskInfo(), [this, &offset](const OutputTaskParser::TaskInfo &ti) {
registerPositionOf(ti.task, ti.linkedLines, ti.skippedLines, offset);
offset += ti.linkedLines;
});
}
parser->runPostPrintActions();
});
// Let selected text be colored as if the text edit was editable,
// otherwise the highlight for searching is too light
QPalette p = m_outputWindow->palette();
@@ -254,7 +212,6 @@ void CompileOutputWindow::appendText(const QString &text, BuildStep::OutputForma
void CompileOutputWindow::clearContents()
{
m_outputWindow->clear();
m_outputWindow->clearTasks();
m_taskPositions.clear();
}
@@ -287,22 +244,17 @@ bool CompileOutputWindow::canNavigate() const
return false;
}
void CompileOutputWindow::registerPositionOf(const Task &task, int linkedOutputLines, int skipLines)
void CompileOutputWindow::registerPositionOf(const Task &task, int linkedOutputLines, int skipLines,
int offset)
{
if (linkedOutputLines <= 0)
return;
const int charNumber = m_outputWindow->document()->characterCount();
if (charNumber > m_outputWindow->maxCharCount())
return;
const int blocknumber = m_outputWindow->document()->blockCount();
const int startLine = blocknumber - linkedOutputLines + 1 - skipLines;
const int endLine = blocknumber - skipLines;
const int blocknumber = m_outputWindow->document()->blockCount() - offset - 1;
const int firstLine = blocknumber - linkedOutputLines - skipLines;
const int lastLine = firstLine + linkedOutputLines - 1;
m_taskPositions.insert(task.taskId, qMakePair(startLine, endLine));
for (int i = startLine; i <= endLine; ++i)
m_outputWindow->addTask(task, i);
m_taskPositions.insert(task.taskId, qMakePair(firstLine, lastLine));
}
bool CompileOutputWindow::knowsPositionOf(const Task &task)
@@ -340,6 +292,11 @@ void CompileOutputWindow::setSettings(const CompileOutputSettings &settings)
updateFromSettings();
}
Utils::OutputFormatter *CompileOutputWindow::outputFormatter() const
{
return m_outputWindow->outputFormatter();
}
void CompileOutputWindow::updateFilter()
{
m_outputWindow->updateFilterProperties(filterText(), filterCaseSensitivity(),
@@ -415,5 +372,3 @@ CompileOutputSettingsPage::CompileOutputSettingsPage()
} // Internal
} // ProjectExplorer
#include "compileoutputwindow.moc"