Commit a0598727 authored by dt's avatar dt
Browse files

Fix QtOutputFormatter to work with chunked application output

Reviewed-By: Erik Verbruggen
parent 7b7d9ea7
......@@ -83,6 +83,14 @@ void OutputFormatter::append(const QString &text, const QTextCharFormat &format)
cursor.insertText(text, format);
}
void OutputFormatter::clearLastLine()
{
QTextCursor cursor(m_plainTextEdit->document());
cursor.movePosition(QTextCursor::End);
cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor);
cursor.removeSelectedText();
}
static QColor mix_colors(QColor a, QColor b)
{
return QColor((a.red() + 2 * b.red()) / 3, (a.green() + 2 * b.green()) / 3,
......
......@@ -70,6 +70,7 @@ protected:
void initFormats();
void append(const QString &text, Format format);
void append(const QString &text, const QTextCharFormat &format);
void clearLastLine();
private:
QPlainTextEdit *m_plainTextEdit;
......
......@@ -48,39 +48,102 @@ QtOutputFormatter::QtOutputFormatter(Qt4Project *project)
}
void QtOutputFormatter::appendApplicationOutput(const QString &text, bool onStdErr)
LinkResult QtOutputFormatter::matchLine(const QString &line) const
{
QTextCharFormat linkFormat;
linkFormat.setForeground(plainTextEdit()->palette().link().color());
linkFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
linkFormat.setAnchor(true);
// Create links from QML errors (anything of the form "file:///...:[line]:[column]:")
if (m_qmlError.indexIn(text) != -1) {
const int matchPos = m_qmlError.pos(1);
const QString leader = text.left(matchPos);
append(leader, onStdErr ? StdErrFormat : StdOutFormat);
const QString matched = m_qmlError.cap(1);
linkFormat.setAnchorHref(matched);
append(matched, linkFormat);
int index = matchPos + m_qmlError.matchedLength() - 1;
append(text.mid(index), onStdErr ? StdErrFormat : StdOutFormat);
} else if (m_qtError.indexIn(text) != -1) {
const int matchPos = m_qtError.pos(1);
const QString leader = text.left(matchPos);
append(leader, onStdErr ? StdErrFormat : StdOutFormat);
const QString matched = m_qtError.cap(1);
linkFormat.setAnchorHref(m_qtError.cap(1));
append(matched, linkFormat);
int index = matchPos + m_qtError.matchedLength() - 1;
append(text.mid(index), onStdErr ? StdErrFormat : StdOutFormat);
} else {
append(text, onStdErr ? StdErrFormat : StdOutFormat);
LinkResult lr;
lr.start = -1;
lr.end = -1;
if (m_qmlError.indexIn(line) != -1) {
lr.href = m_qmlError.cap(1);
lr.start = m_qmlError.pos(1);
lr.end = lr.start + lr.href.length();
} else if (m_qtError.indexIn(line) != -1) {
lr.href = m_qtError.cap(1);
lr.start = m_qtError.pos(1);
lr.end = lr.start + lr.href.length();
}
return lr;
}
void QtOutputFormatter::appendApplicationOutput(const QString &txt, bool onStdErr)
{
// Do the initialization lazily, as we don't have a plaintext edit
// in the ctor
if (!m_linkFormat.isValid()) {
m_linkFormat.setForeground(plainTextEdit()->palette().link().color());
m_linkFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
m_linkFormat.setAnchor(true);
}
QString text = txt;
text.remove(QLatin1Char('\r'));
int start = 0;
int pos = txt.indexOf(QLatin1Char('\n'));
while (pos != -1) {
// Line identified
if (!m_lastLine.isEmpty()) {
// Line continuation
const QString newPart = txt.mid(start, pos - start + 1);
const QString line = m_lastLine + newPart;
LinkResult lr = matchLine(line);
if (!lr.href.isEmpty()) {
// Found something && line continuation
clearLastLine();
appendLine(lr, line, onStdErr);
} else {
// Found nothing, just emit the new part
append(newPart, onStdErr ? StdErrFormat : StdOutFormat);
}
// Handled line continuation
m_lastLine.clear();
} else {
const QString line = txt.mid(start, pos - start + 1);
LinkResult lr = matchLine(line);
if (!lr.href.isEmpty()) {
appendLine(lr, line, onStdErr);
} else {
append(line, onStdErr ? StdErrFormat : StdOutFormat);
}
}
start = pos + 1;
pos = txt.indexOf(QLatin1Char('\n'), start);
}
// Handle left over stuff
if (start < txt.length()) {
if (!m_lastLine.isEmpty()) {
// Line continuation
const QString newPart = txt.mid(start);
m_lastLine.append(newPart);
LinkResult lr = matchLine(m_lastLine);
if (!lr.href.isEmpty()) {
// Found something && line continuation
clearLastLine();
appendLine(lr, m_lastLine, onStdErr);
} else {
// Found nothing, just emit the new part
append(newPart, onStdErr ? StdErrFormat : StdOutFormat);
}
} else {
m_lastLine = txt.mid(start);
LinkResult lr = matchLine(m_lastLine);
if (!lr.href.isEmpty()) {
appendLine(lr, m_lastLine, onStdErr);
} else {
append(m_lastLine, onStdErr ? StdErrFormat : StdOutFormat);
}
}
}
}
void QtOutputFormatter::appendLine(LinkResult lr, const QString &line, bool onStdErr)
{
append(line.left(lr.start), onStdErr ? StdErrFormat : StdOutFormat);
m_linkFormat.setAnchorHref(lr.href);
append(line.mid(lr.start, lr.end - lr.start), m_linkFormat);
append(line.mid(lr.end), onStdErr ? StdErrFormat : StdOutFormat);
}
void QtOutputFormatter::handleLink(const QString &href)
......
......@@ -32,12 +32,20 @@
#include <projectexplorer/outputformatter.h>
#include <QtCore/QRegExp>
#include <QSharedPointer>
#include <QtCore/QSharedPointer>
#include <QtGui/QTextCharFormat>
namespace Qt4ProjectManager
{
class Qt4Project;
struct LinkResult
{
int start;
int end;
QString href;
};
class QtOutputFormatter: public ProjectExplorer::OutputFormatter
{
public:
......@@ -48,9 +56,14 @@ public:
virtual void handleLink(const QString &href);
private:
LinkResult matchLine(const QString &line) const;
void appendLine(LinkResult lr, const QString &line, bool onStdError);
QRegExp m_qmlError;
QRegExp m_qtError;
QWeakPointer<Qt4Project> m_project;
QTextCharFormat m_linkFormat;
QString m_lastLine;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment