ProjectExplorer: Give the Task class an explicit summary

We'd like to create more useful tasks from compiler output, that is, try
harder to identify consecutive lines that refer to the same issue and
create one task for them, rather than one for each line. In such
"aggregate" tasks, the first line will not necessarily carry the main
information. Therefore, we make it explicit what this main information
is by introducing a dedicated summary member.
Also streamline the font handling for compile tasks.

Change-Id: I933f2643a13c710dab1ab548c56669b129026eb5
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2020-05-12 16:26:34 +02:00
parent e35f945758
commit b02f6b5d30
29 changed files with 89 additions and 157 deletions

View File

@@ -28,9 +28,6 @@
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/task.h> #include <projectexplorer/task.h>
#include <texteditor/fontsettings.h>
#include <texteditor/texteditorsettings.h>
#include <QRegularExpression> #include <QRegularExpression>
using namespace ProjectExplorer; using namespace ProjectExplorer;
@@ -69,28 +66,6 @@ void IarParser::newTask(const Task &task)
m_lines = 1; m_lines = 1;
} }
void IarParser::amendDescription()
{
while (!m_descriptionParts.isEmpty())
m_lastTask.description.append(m_descriptionParts.takeFirst());
while (!m_snippets.isEmpty()) {
const QString snippet = m_snippets.takeFirst();
const int start = m_lastTask.description.count() + 1;
m_lastTask.description.append('\n');
m_lastTask.description.append(snippet);
QTextLayout::FormatRange fr;
fr.start = start;
fr.length = m_lastTask.description.count() + 1;
fr.format.setFont(TextEditor::TextEditorSettings::fontSettings().font());
fr.format.setFontStyleHint(QFont::Monospace);
m_lastTask.formats.append(fr);
++m_lines;
}
}
void IarParser::amendFilePath() void IarParser::amendFilePath()
{ {
if (m_filePathParts.isEmpty()) if (m_filePathParts.isEmpty())
@@ -251,7 +226,12 @@ void IarParser::flush()
if (m_lastTask.isNull()) if (m_lastTask.isNull())
return; return;
amendDescription(); while (!m_descriptionParts.isEmpty())
m_lastTask.summary.append(m_descriptionParts.takeFirst());
m_lastTask.details = m_snippets;
m_snippets.clear();
m_lines += m_lastTask.details.count();
setMonospacedDetailsFormat(m_lastTask);
amendFilePath(); amendFilePath();
m_expectSnippet = true; m_expectSnippet = true;

View File

@@ -28,9 +28,6 @@
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/task.h> #include <projectexplorer/task.h>
#include <texteditor/fontsettings.h>
#include <texteditor/texteditorsettings.h>
#include <QRegularExpression> #include <QRegularExpression>
using namespace ProjectExplorer; using namespace ProjectExplorer;
@@ -71,26 +68,6 @@ void KeilParser::newTask(const Task &task)
m_lines = 1; m_lines = 1;
} }
void KeilParser::amendDescription()
{
while (!m_snippets.isEmpty()) {
const QString snippet = m_snippets.takeFirst();
const int start = m_lastTask.description.count() + 1;
m_lastTask.description.append('\n');
m_lastTask.description.append(snippet);
QTextLayout::FormatRange fr;
fr.start = start;
fr.length = m_lastTask.description.count() + 1;
fr.format.setFont(TextEditor::TextEditorSettings::fontSettings().font());
fr.format.setFontStyleHint(QFont::Monospace);
m_lastTask.formats.append(fr);
++m_lines;
}
}
// ARM compiler specific parsers. // ARM compiler specific parsers.
OutputLineParser::Result KeilParser::parseArmWarningOrErrorDetailsMessage(const QString &lne) OutputLineParser::Result KeilParser::parseArmWarningOrErrorDetailsMessage(const QString &lne)
@@ -278,8 +255,10 @@ void KeilParser::flush()
if (m_lastTask.isNull()) if (m_lastTask.isNull())
return; return;
amendDescription(); m_lastTask.details = m_snippets;
m_snippets.clear();
m_lines += m_lastTask.details.count();
setMonospacedDetailsFormat(m_lastTask);
Task t = m_lastTask; Task t = m_lastTask;
m_lastTask.clear(); m_lastTask.clear();
scheduleTask(t, m_lines, 1); scheduleTask(t, m_lines, 1);

View File

@@ -43,7 +43,6 @@ public:
private: private:
void newTask(const ProjectExplorer::Task &task); void newTask(const ProjectExplorer::Task &task);
void amendDescription();
// ARM compiler specific parsers. // ARM compiler specific parsers.
Result parseArmWarningOrErrorDetailsMessage(const QString &lne); Result parseArmWarningOrErrorDetailsMessage(const QString &lne);

View File

@@ -28,9 +28,6 @@
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/task.h> #include <projectexplorer/task.h>
#include <texteditor/fontsettings.h>
#include <texteditor/texteditorsettings.h>
#include <QRegularExpression> #include <QRegularExpression>
using namespace ProjectExplorer; using namespace ProjectExplorer;
@@ -73,17 +70,7 @@ void SdccParser::newTask(const Task &task)
void SdccParser::amendDescription(const QString &desc) void SdccParser::amendDescription(const QString &desc)
{ {
const int start = m_lastTask.description.count() + 1; m_lastTask.details.append(desc);
m_lastTask.description.append('\n');
m_lastTask.description.append(desc);
QTextLayout::FormatRange fr;
fr.start = start;
fr.length = m_lastTask.description.count() + 1;
fr.format.setFont(TextEditor::TextEditorSettings::fontSettings().font());
fr.format.setFontStyleHint(QFont::Monospace);
m_lastTask.formats.append(fr);
++m_lines; ++m_lines;
} }
@@ -165,6 +152,7 @@ void SdccParser::flush()
if (m_lastTask.isNull()) if (m_lastTask.isNull())
return; return;
setMonospacedDetailsFormat(m_lastTask);
Task t = m_lastTask; Task t = m_lastTask;
m_lastTask.clear(); m_lastTask.clear();
scheduleTask(t, m_lines, 1); scheduleTask(t, m_lines, 1);

View File

@@ -101,9 +101,9 @@ OutputLineParser::Result CMakeParser::handleLine(const QString &line, OutputForm
m_lines = 1; m_lines = 1;
return {Status::InProgress, linkSpecs}; return {Status::InProgress, linkSpecs};
} else if (trimmedLine.startsWith(QLatin1String(" ")) && !m_lastTask.isNull()) { } else if (trimmedLine.startsWith(QLatin1String(" ")) && !m_lastTask.isNull()) {
if (!m_lastTask.description.isEmpty()) if (!m_lastTask.summary.isEmpty())
m_lastTask.description.append(QLatin1Char(' ')); m_lastTask.summary.append(' ');
m_lastTask.description.append(trimmedLine.trimmed()); m_lastTask.summary.append(trimmedLine.trimmed());
++m_lines; ++m_lines;
return Status::InProgress; return Status::InProgress;
} else if (trimmedLine.endsWith(QLatin1String("in cmake code at"))) { } else if (trimmedLine.endsWith(QLatin1String("in cmake code at"))) {
@@ -136,7 +136,7 @@ OutputLineParser::Result CMakeParser::handleLine(const QString &line, OutputForm
return {Status::InProgress, linkSpecs}; return {Status::InProgress, linkSpecs};
} }
case LINE_DESCRIPTION: case LINE_DESCRIPTION:
m_lastTask.description = trimmedLine; m_lastTask.summary = trimmedLine;
if (trimmedLine.endsWith(QLatin1Char('\"'))) if (trimmedLine.endsWith(QLatin1Char('\"')))
m_expectTripleLineErrorData = LINE_DESCRIPTION2; m_expectTripleLineErrorData = LINE_DESCRIPTION2;
else { else {
@@ -146,8 +146,7 @@ OutputLineParser::Result CMakeParser::handleLine(const QString &line, OutputForm
} }
return Status::InProgress; return Status::InProgress;
case LINE_DESCRIPTION2: case LINE_DESCRIPTION2:
m_lastTask.description.append(QLatin1Char('\n')); m_lastTask.details.append(trimmedLine);
m_lastTask.description.append(trimmedLine);
m_expectTripleLineErrorData = NONE; m_expectTripleLineErrorData = NONE;
flush(); flush();
return Status::Done; return Status::Done;

View File

@@ -977,7 +977,7 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm
const Tasks tasks = DebuggerKitAspect::validateDebugger(kit); const Tasks tasks = DebuggerKitAspect::validateDebugger(kit);
for (const Task &t : tasks) { for (const Task &t : tasks) {
if (t.type != Task::Warning) if (t.type != Task::Warning)
m_runParameters.validationErrors.append(t.description); m_runParameters.validationErrors.append(t.description());
} }
RunConfiguration *runConfig = runControl->runConfiguration(); RunConfiguration *runConfig = runControl->runConfiguration();

View File

@@ -36,15 +36,12 @@ using namespace Help::Internal;
bool SearchTaskHandler::canHandle(const ProjectExplorer::Task &task) const bool SearchTaskHandler::canHandle(const ProjectExplorer::Task &task) const
{ {
return !task.description.isEmpty() return !task.summary.isEmpty();
&& !task.description.startsWith(QLatin1Char('\n'));
} }
void SearchTaskHandler::handle(const ProjectExplorer::Task &task) void SearchTaskHandler::handle(const ProjectExplorer::Task &task)
{ {
const int eol = task.description.indexOf(QLatin1Char('\n')); emit search(QUrl("https://www.google.com/search?q=" + task.summary));
const QUrl url(QLatin1String("https://www.google.com/search?q=") + task.description.left(eol));
emit search(url);
} }
QAction *SearchTaskHandler::createAction(QObject *parent) const QAction *SearchTaskHandler::createAction(QObject *parent) const

View File

@@ -112,7 +112,7 @@ OutputLineParser::Result ClangParser::handleLine(const QString &line, OutputForm
} }
if (m_expectSnippet) { if (m_expectSnippet) {
amendDescription(lne, true); amendDescription(lne);
return Status::InProgress; return Status::InProgress;
} }

View File

@@ -44,7 +44,7 @@ ConfigTaskHandler::ConfigTaskHandler(const Task &pattern, Core::Id page) :
bool ConfigTaskHandler::canHandle(const Task &task) const bool ConfigTaskHandler::canHandle(const Task &task) const
{ {
return task.description == m_pattern.description return task.description() == m_pattern.description()
&& task.category == m_pattern.category; && task.category == m_pattern.category;
} }

View File

@@ -54,7 +54,7 @@ void CopyTaskHandler::handle(const Task &task)
QApplication::clipboard()->setText(task.file.toUserOutput() + QLatin1Char(':') + QApplication::clipboard()->setText(task.file.toUserOutput() + QLatin1Char(':') +
QString::number(task.line) + QLatin1String(": ") QString::number(task.line) + QLatin1String(": ")
+ type + task.description); + type + task.description());
} }
Core::Id CopyTaskHandler::actionManagerId() const Core::Id CopyTaskHandler::actionManagerId() const

View File

@@ -292,7 +292,7 @@ void ExtraCompilerPrivate::updateIssues()
const auto fontSettings = TextEditor::TextEditorSettings::instance()->fontSettings(); const auto fontSettings = TextEditor::TextEditorSettings::instance()->fontSettings();
selection.format = fontSettings.toTextCharFormat(issue.type == Task::Warning ? selection.format = fontSettings.toTextCharFormat(issue.type == Task::Warning ?
TextEditor::C_WARNING : TextEditor::C_ERROR); TextEditor::C_WARNING : TextEditor::C_ERROR);
selection.format.setToolTip(issue.description); selection.format.setToolTip(issue.description());
selections.append(selection); selections.append(selection);
} }

View File

@@ -30,8 +30,6 @@
#include "projectexplorerconstants.h" #include "projectexplorerconstants.h"
#include "buildmanager.h" #include "buildmanager.h"
#include <texteditor/fontsettings.h>
#include <texteditor/texteditorsettings.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
using namespace ProjectExplorer; using namespace ProjectExplorer;
@@ -82,27 +80,19 @@ void GccParser::flush()
{ {
if (m_currentTask.isNull()) if (m_currentTask.isNull())
return; return;
setMonospacedDetailsFormat(m_currentTask);
Task t = m_currentTask; Task t = m_currentTask;
m_currentTask.clear(); m_currentTask.clear();
scheduleTask(t, m_lines, 1); scheduleTask(t, m_lines, 1);
m_lines = 0; m_lines = 0;
} }
void GccParser::amendDescription(const QString &desc, bool monospaced) void GccParser::amendDescription(const QString &desc)
{ {
if (m_currentTask.isNull()) if (m_currentTask.isNull())
return; return;
int start = m_currentTask.description.count() + 1; m_currentTask.details.append(desc);
m_currentTask.description.append(QLatin1Char('\n'));
m_currentTask.description.append(desc);
if (monospaced) {
QTextLayout::FormatRange fr;
fr.start = start;
fr.length = desc.count() + 1;
fr.format.setFont(TextEditor::TextEditorSettings::fontSettings().font());
fr.format.setFontStyleHint(QFont::Monospace);
m_currentTask.formats.append(fr);
}
++m_lines; ++m_lines;
return; return;
} }
@@ -174,7 +164,7 @@ OutputLineParser::Result GccParser::handleLine(const QString &line, OutputFormat
newTask(CompileTask(Task::Unknown, lne.trimmed() /* description */, filePath, lineNo)); newTask(CompileTask(Task::Unknown, lne.trimmed() /* description */, filePath, lineNo));
return {Status::InProgress, linkSpecs}; return {Status::InProgress, linkSpecs};
} else if (lne.startsWith(' ') && !m_currentTask.isNull()) { } else if (lne.startsWith(' ') && !m_currentTask.isNull()) {
amendDescription(lne, true); amendDescription(lne);
return Status::InProgress; return Status::InProgress;
} }

View File

@@ -48,7 +48,7 @@ protected:
void newTask(const Task &task); void newTask(const Task &task);
void flush() override; void flush() override;
void amendDescription(const QString &desc, bool monospaced); void amendDescription(const QString &desc);
private: private:
Result handleLine(const QString &line, Utils::OutputFormat type) override; Result handleLine(const QString &line, Utils::OutputFormat type) override;

View File

@@ -28,6 +28,9 @@
#include "task.h" #include "task.h"
#include "taskhub.h" #include "taskhub.h"
#include <texteditor/fontsettings.h>
#include <texteditor/texteditorsettings.h>
/*! /*!
\class ProjectExplorer::OutputTaskParser \class ProjectExplorer::OutputTaskParser
@@ -91,6 +94,18 @@ void OutputTaskParser::scheduleTask(const Task &task, int outputLines, int skipp
QTC_CHECK(d->scheduledTasks.size() <= 2); QTC_CHECK(d->scheduledTasks.size() <= 2);
} }
void OutputTaskParser::setMonospacedDetailsFormat(Task &task)
{
if (task.details.isEmpty())
return;
QTextLayout::FormatRange fr;
fr.start = task.summary.length() + 1;
fr.length = task.details.join('\n').length();
fr.format.setFont(TextEditor::TextEditorSettings::fontSettings().font());
fr.format.setFontStyleHint(QFont::Monospace);
task.formats = {fr};
}
void OutputTaskParser::runPostPrintActions() void OutputTaskParser::runPostPrintActions()
{ {
for (const TaskInfo &t : qAsConst(d->scheduledTasks)) for (const TaskInfo &t : qAsConst(d->scheduledTasks))

View File

@@ -54,6 +54,7 @@ public:
protected: protected:
void scheduleTask(const Task &task, int outputLines, int skippedLines = 0); void scheduleTask(const Task &task, int outputLines, int skippedLines = 0);
void setMonospacedDetailsFormat(Task &task);
private: private:
void runPostPrintActions() override; void runPostPrintActions() override;

View File

@@ -77,7 +77,7 @@ Utils::OutputLineParser::Result LdParser::handleLine(const QString &line, Utils:
return Status::InProgress; return Status::InProgress;
} }
if (!m_incompleteTask.isNull() && lne.startsWith(" ")) { if (!m_incompleteTask.isNull() && lne.startsWith(" ")) {
m_incompleteTask.description.append('\n').append(lne); m_incompleteTask.details.append(lne);
static const QRegularExpression locRegExp(" (?<symbol>\\S+) in (?<file>\\S+)"); static const QRegularExpression locRegExp(" (?<symbol>\\S+) in (?<file>\\S+)");
const QRegularExpressionMatch match = locRegExp.match(lne); const QRegularExpressionMatch match = locRegExp.match(lne);
LinkSpecs linkSpecs; LinkSpecs linkSpecs;

View File

@@ -92,18 +92,7 @@ OutputLineParser::Result LinuxIccParser::handleLine(const QString &line, OutputF
return Status::InProgress; return Status::InProgress;
} }
if (!m_expectFirstLine && m_caretLine.indexIn(line) != -1) { if (!m_expectFirstLine && m_caretLine.indexIn(line) != -1) {
// Format the last line as code // FIXME: m_temporary.details.append(line);
QTextLayout::FormatRange fr;
fr.start = m_temporary.description.lastIndexOf(QLatin1Char('\n')) + 1;
fr.length = m_temporary.description.length() - fr.start;
fr.format.setFontItalic(true);
m_temporary.formats.append(fr);
QTextLayout::FormatRange fr2;
fr2.start = fr.start + line.indexOf(QLatin1Char('^')) - m_indent;
fr2.length = 1;
fr2.format.setFontWeight(QFont::Bold);
m_temporary.formats.append(fr2);
return Status::InProgress; return Status::InProgress;
} }
if (!m_expectFirstLine && line.trimmed().isEmpty()) { // last Line if (!m_expectFirstLine && line.trimmed().isEmpty()) { // last Line
@@ -113,11 +102,7 @@ OutputLineParser::Result LinuxIccParser::handleLine(const QString &line, OutputF
return Status::Done; return Status::Done;
} }
if (!m_expectFirstLine && m_continuationLines.indexIn(line) != -1) { if (!m_expectFirstLine && m_continuationLines.indexIn(line) != -1) {
m_temporary.description.append(QLatin1Char('\n')); m_temporary.details.append(m_continuationLines.cap(1).trimmed());
m_indent = 0;
while (m_indent < line.length() && line.at(m_indent).isSpace())
m_indent++;
m_temporary.description.append(m_continuationLines.cap(1).trimmed());
++m_lines; ++m_lines;
return Status::InProgress; return Status::InProgress;
} }
@@ -139,6 +124,8 @@ void LinuxIccParser::flush()
{ {
if (m_temporary.isNull()) if (m_temporary.isNull())
return; return;
setMonospacedDetailsFormat(m_temporary);
Task t = m_temporary; Task t = m_temporary;
m_temporary.clear(); m_temporary.clear();
scheduleTask(t, m_lines, 1); scheduleTask(t, m_lines, 1);

View File

@@ -53,7 +53,6 @@ private:
QRegExp m_pchInfoLine; QRegExp m_pchInfoLine;
bool m_expectFirstLine = true; bool m_expectFirstLine = true;
int m_indent = 0;
Task m_temporary; Task m_temporary;
int m_lines = 0; int m_lines = 0;
}; };

View File

@@ -113,26 +113,7 @@ OutputLineParser::Result MsvcParser::handleLine(const QString &line, OutputForma
if (m_lastTask.isNull()) if (m_lastTask.isNull())
return Status::NotHandled; return Status::NotHandled;
m_lastTask.description.append('\n'); m_lastTask.details.append(rightTrimmed(line.mid(8)));
m_lastTask.description.append(line.mid(8));
// trim trailing spaces:
int i = 0;
for (i = m_lastTask.description.length() - 1; i >= 0; --i) {
if (!m_lastTask.description.at(i).isSpace())
break;
}
m_lastTask.description.truncate(i + 1);
if (m_lastTask.formats.isEmpty()) {
QTextLayout::FormatRange fr;
fr.start = m_lastTask.description.indexOf('\n') + 1;
fr.length = m_lastTask.description.length() - fr.start;
fr.format.setFontItalic(true);
m_lastTask.formats.append(fr);
} else {
m_lastTask.formats[0].length = m_lastTask.description.length()
- m_lastTask.formats[0].start;
}
++m_lines; ++m_lines;
return Status::InProgress; return Status::InProgress;
} }
@@ -195,6 +176,7 @@ void MsvcParser::flush()
if (m_lastTask.isNull()) if (m_lastTask.isNull())
return; return;
setMonospacedDetailsFormat(m_lastTask);
Task t = m_lastTask; Task t = m_lastTask;
m_lastTask.clear(); m_lastTask.clear();
scheduleTask(t, m_lines, 1); scheduleTask(t, m_lines, 1);
@@ -275,8 +257,7 @@ OutputLineParser::Result ClangClParser::handleLine(const QString &line, OutputFo
flush(); flush();
return Status::Done; return Status::Done;
} }
m_lastTask.description.append('\n'); m_lastTask.details.append(trimmed);
m_lastTask.description.append(trimmed);
++m_linkedLines; ++m_linkedLines;
return Status::InProgress; return Status::InProgress;
} }

View File

@@ -83,7 +83,7 @@ void OutputParserTester::testParsing(const QString &lines,
if (m_receivedTasks.size() == tasks.size()) { if (m_receivedTasks.size() == tasks.size()) {
for (int i = 0; i < tasks.size(); ++i) { for (int i = 0; i < tasks.size(); ++i) {
QCOMPARE(m_receivedTasks.at(i).category, tasks.at(i).category); QCOMPARE(m_receivedTasks.at(i).category, tasks.at(i).category);
QCOMPARE(m_receivedTasks.at(i).description, tasks.at(i).description); QCOMPARE(m_receivedTasks.at(i).description(), tasks.at(i).description());
QVERIFY2(m_receivedTasks.at(i).file == tasks.at(i).file, QVERIFY2(m_receivedTasks.at(i).file == tasks.at(i).file,
msgFileComparisonFail(m_receivedTasks.at(i).file, tasks.at(i).file)); msgFileComparisonFail(m_receivedTasks.at(i).file, tasks.at(i).file));
QCOMPARE(m_receivedTasks.at(i).line, tasks.at(i).line); QCOMPARE(m_receivedTasks.at(i).line, tasks.at(i).line);

View File

@@ -388,7 +388,7 @@ QPair<Task::TaskType, QString> TargetSetupWidget::findIssues(const BuildInfo &in
highestType = Task::Warning; highestType = Task::Warning;
severity = tr("<b>Warning:</b> ", "Severity is Task::Warning"); severity = tr("<b>Warning:</b> ", "Severity is Task::Warning");
} }
text.append(severity + t.description); text.append(severity + t.description());
} }
if (!text.isEmpty()) if (!text.isEmpty())
text = QLatin1String("<nobr>") + text; text = QLatin1String("<nobr>") + text;

View File

@@ -62,15 +62,20 @@ unsigned int Task::s_nextId = 1;
\sa ProjectExplorer::TaskHub \sa ProjectExplorer::TaskHub
*/ */
Task::Task(TaskType type_, const QString &description_, Task::Task(TaskType type_, const QString &description,
const Utils::FilePath &file_, int line_, Core::Id category_, const Utils::FilePath &file_, int line_, Core::Id category_,
const QIcon &icon, Options options) : const QIcon &icon, Options options) :
taskId(s_nextId), type(type_), options(options), description(description_), taskId(s_nextId), type(type_), options(options), summary(description),
line(line_), movedLine(line_), category(category_), line(line_), movedLine(line_), category(category_),
icon(icon.isNull() ? taskTypeIcon(type_) : icon) icon(icon.isNull() ? taskTypeIcon(type_) : icon)
{ {
++s_nextId; ++s_nextId;
setFile(file_); setFile(file_);
QStringList desc = description.split('\n');
if (desc.length() > 1) {
summary = desc.first();
details = desc.mid(1);
}
} }
Task Task::compilerMissingTask() Task Task::compilerMissingTask()
@@ -97,7 +102,8 @@ void Task::clear()
{ {
taskId = 0; taskId = 0;
type = Task::Unknown; type = Task::Unknown;
description.clear(); summary.clear();
details.clear();
file = Utils::FilePath(); file = Utils::FilePath();
line = -1; line = -1;
movedLine = -1; movedLine = -1;
@@ -119,6 +125,14 @@ void Task::setFile(const Utils::FilePath &file_)
} }
} }
QString Task::description() const
{
QString desc = summary;
if (!details.isEmpty())
desc.append('\n').append(details.join('\n'));
return desc;
}
// //
// functions // functions
// //
@@ -173,7 +187,7 @@ QString toHtml(const Tasks &issues)
default: default:
break; break;
} }
str << "</b>" << t.description << "<br>"; str << "</b>" << t.description() << "<br>";
} }
return result; return result;
} }

View File

@@ -32,6 +32,7 @@
#include <QIcon> #include <QIcon>
#include <QMetaType> #include <QMetaType>
#include <QStringList>
#include <QTextLayout> #include <QTextLayout>
namespace TextEditor { namespace TextEditor {
@@ -72,11 +73,13 @@ public:
bool isNull() const; bool isNull() const;
void clear(); void clear();
void setFile(const Utils::FilePath &file); void setFile(const Utils::FilePath &file);
QString description() const;
unsigned int taskId = 0; unsigned int taskId = 0;
TaskType type = Unknown; TaskType type = Unknown;
Options options = AddTextMark | FlashWorthy; Options options = AddTextMark | FlashWorthy;
QString description; QString summary;
QStringList details;
Utils::FilePath file; Utils::FilePath file;
Utils::FilePaths fileCandidates; Utils::FilePaths fileCandidates;
int line = -1; int line = -1;

View File

@@ -74,9 +74,9 @@ public:
if (task.category == Constants::TASK_CATEGORY_COMPILE) { if (task.category == Constants::TASK_CATEGORY_COMPILE) {
setToolTip("<html><body><b>" + QApplication::translate("TaskHub", "Build Issue") setToolTip("<html><body><b>" + QApplication::translate("TaskHub", "Build Issue")
+ "</b><br/><code style=\"white-space:pre;font-family:monospace\">" + "</b><br/><code style=\"white-space:pre;font-family:monospace\">"
+ task.description.toHtmlEscaped() + "</code></body></html>"); + task.description().toHtmlEscaped() + "</code></body></html>");
} else { } else {
setToolTip(task.description); setToolTip(task.description());
} }
setIcon(task.icon); setIcon(task.icon);
setVisible(!task.icon.isNull()); setVisible(!task.icon.isNull());
@@ -152,7 +152,7 @@ void TaskHub::addTask(Task::TaskType type, const QString &description, Core::Id
void TaskHub::addTask(Task task) void TaskHub::addTask(Task task)
{ {
QTC_ASSERT(m_registeredCategories.contains(task.category), return); QTC_ASSERT(m_registeredCategories.contains(task.category), return);
QTC_ASSERT(!task.description.isEmpty(), return); QTC_ASSERT(!task.description().isEmpty(), return);
QTC_ASSERT(!task.isNull(), return); QTC_ASSERT(!task.isNull(), return);
QTC_ASSERT(task.m_mark.isNull(), return); QTC_ASSERT(task.m_mark.isNull(), return);

View File

@@ -247,7 +247,7 @@ QVariant TaskModel::data(const QModelIndex &index, int role) const
else if (role == TaskModel::MovedLine) else if (role == TaskModel::MovedLine)
return m_tasks.at(index.row()).movedLine; return m_tasks.at(index.row()).movedLine;
else if (role == TaskModel::Description) else if (role == TaskModel::Description)
return m_tasks.at(index.row()).description; return m_tasks.at(index.row()).description();
else if (role == TaskModel::FileNotFound) else if (role == TaskModel::FileNotFound)
return m_fileNotFound.value(m_tasks.at(index.row()).file.toString()); return m_fileNotFound.value(m_tasks.at(index.row()).file.toString());
else if (role == TaskModel::Type) else if (role == TaskModel::Type)
@@ -405,7 +405,7 @@ bool TaskFilterModel::filterAcceptsTask(const Task &task) const
return m_filterStringIsRegexp ? m_filterRegexp.isValid() && s.contains(m_filterRegexp) return m_filterStringIsRegexp ? m_filterRegexp.isValid() && s.contains(m_filterRegexp)
: s.contains(m_filterText, m_filterCaseSensitivity); : s.contains(m_filterText, m_filterCaseSensitivity);
}; };
if ((accepts(task.file.toString()) || accepts(task.description)) == m_filterIsInverted) if ((accepts(task.file.toString()) || accepts(task.description())) == m_filterIsInverted)
accept = false; accept = false;
} }

View File

@@ -99,9 +99,9 @@ private:
m_tasks.append({Task::Warning, text.trimmed(), {}, -1, category}); m_tasks.append({Task::Warning, text.trimmed(), {}, -1, category});
} else { } else {
Task &task = m_tasks.back(); Task &task = m_tasks.back();
if (!task.description.isEmpty()) if (!task.summary.isEmpty())
task.description += ' '; task.summary += ' ';
task.description += text.trimmed(); task.summary += text.trimmed();
} }
} else { } else {
// The actual exception. This ends the traceback. // The actual exception. This ends the traceback.

View File

@@ -313,7 +313,7 @@ void QmakeBuildConfiguration::updateProblemLabel()
} }
if (!text.endsWith(QLatin1String("br>"))) if (!text.endsWith(QLatin1String("br>")))
text.append(QLatin1String("<br>")); text.append(QLatin1String("<br>"));
text.append(type + task.description); text.append(type + task.description());
} }
buildDirectoryAspect()->setProblem(text); buildDirectoryAspect()->setProblem(text);
return; return;

View File

@@ -78,7 +78,7 @@ OutputLineParser::Result QtTestParser::handleLine(const QString &line, OutputFor
emitCurrentTask(); emitCurrentTask();
return {Status::Done, linkSpecs}; return {Status::Done, linkSpecs};
} }
m_currentTask.description.append('\n').append(theLine); m_currentTask.details.append(theLine);
return Status::InProgress; return Status::InProgress;
} }

View File

@@ -90,5 +90,5 @@ void CompilerOutputProcessor::handleTask(const ProjectExplorer::Task &task)
*m_ostream << ':' << task.line; *m_ostream << ':' << task.line;
*m_ostream << ": "; *m_ostream << ": ";
} }
*m_ostream << task.description << '\n'; *m_ostream << task.description() << '\n';
} }