QtSupport: Pimpl QtOutputFormatter

Change-Id: Ib2748f1cdd5de4bf11f0eab03bd4c6a683580a9e
Reviewed-by: Tobias Hunger <tobias.hunger@theqtcompany.com>
This commit is contained in:
Orgad Shaneh
2015-02-24 23:30:52 +02:00
committed by Orgad Shaneh
parent 51011aed80
commit 16cfcfe136
2 changed files with 87 additions and 58 deletions

View File

@@ -33,73 +33,106 @@
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <utils/ansiescapecodehandler.h> #include <utils/ansiescapecodehandler.h>
#include <utils/fileinprojectfinder.h>
#include <utils/theme/theme.h> #include <utils/theme/theme.h>
#include <QPlainTextEdit> #include <QPlainTextEdit>
#include <QPointer>
#include <QRegExp>
#include <QTextCursor> #include <QTextCursor>
#include <QUrl> #include <QUrl>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace QtSupport;
using namespace Utils; using namespace Utils;
namespace QtSupport {
// "file" or "qrc", colon, optional '//', '/' and further characters // "file" or "qrc", colon, optional '//', '/' and further characters
#define QML_URL_REGEXP \ #define QML_URL_REGEXP \
"(?:file|qrc):(?://)?/.+" "(?:file|qrc):(?://)?/.+"
namespace Internal {
QtOutputFormatter::QtOutputFormatter(ProjectExplorer::Project *project) class QtOutputFormatterPrivate
: OutputFormatter() {
, m_qmlError(QLatin1String("^(" QML_URL_REGEXP // url public:
QtOutputFormatterPrivate(Project *proj)
: qmlError(QLatin1String("^(" QML_URL_REGEXP // url
":\\d+" // colon, line ":\\d+" // colon, line
"(?::\\d+)?)" // colon, column (optional) "(?::\\d+)?)" // colon, column (optional)
"[: \t]")) // colon, space or tab "[: \t]")) // colon, space or tab
, m_qtError(QLatin1String("Object::.*in (.*:\\d+)")) , qtError(QLatin1String("Object::.*in (.*:\\d+)"))
, m_qtAssert(QLatin1String("ASSERT: .* in file (.+, line \\d+)")) , qtAssert(QLatin1String("ASSERT: .* in file (.+, line \\d+)"))
, m_qtAssertX(QLatin1String("ASSERT failure in .*: \".*\", file (.+, line \\d+)")) , qtAssertX(QLatin1String("ASSERT failure in .*: \".*\", file (.+, line \\d+)"))
, m_qtTestFail(QLatin1String("^ Loc: \\[(.*)\\]")) , qtTestFail(QLatin1String("^ Loc: \\[(.*)\\]"))
, m_project(project) , project(proj)
{
}
~QtOutputFormatterPrivate()
{
}
QRegExp qmlError;
QRegExp qtError;
QRegExp qtAssert;
QRegExp qtAssertX;
QRegExp qtTestFail;
QPointer<Project> project;
QString lastLine;
FileInProjectFinder projectFinder;
};
} // namespace Internal
QtOutputFormatter::QtOutputFormatter(Project *project)
: d(new Internal::QtOutputFormatterPrivate(project))
{ {
if (project) { if (project) {
m_projectFinder.setProjectFiles(project->files(Project::ExcludeGeneratedFiles)); d->projectFinder.setProjectFiles(project->files(Project::ExcludeGeneratedFiles));
m_projectFinder.setProjectDirectory(project->projectDirectory().toString()); d->projectFinder.setProjectDirectory(project->projectDirectory().toString());
connect(project, SIGNAL(fileListChanged()), connect(project, SIGNAL(fileListChanged()),
this, SLOT(updateProjectFileList())); this, SLOT(updateProjectFileList()));
} }
} }
QtOutputFormatter::~QtOutputFormatter()
{
delete d;
}
LinkResult QtOutputFormatter::matchLine(const QString &line) const LinkResult QtOutputFormatter::matchLine(const QString &line) const
{ {
LinkResult lr; LinkResult lr;
lr.start = -1; lr.start = -1;
lr.end = -1; lr.end = -1;
if (m_qmlError.indexIn(line) != -1) { if (d->qmlError.indexIn(line) != -1) {
lr.href = m_qmlError.cap(1); lr.href = d->qmlError.cap(1);
lr.start = m_qmlError.pos(1); lr.start = d->qmlError.pos(1);
lr.end = lr.start + lr.href.length(); lr.end = lr.start + lr.href.length();
} else if (m_qtError.indexIn(line) != -1) { } else if (d->qtError.indexIn(line) != -1) {
lr.href = m_qtError.cap(1); lr.href = d->qtError.cap(1);
lr.start = m_qtError.pos(1); lr.start = d->qtError.pos(1);
lr.end = lr.start + lr.href.length(); lr.end = lr.start + lr.href.length();
} else if (m_qtAssert.indexIn(line) != -1) { } else if (d->qtAssert.indexIn(line) != -1) {
lr.href = m_qtAssert.cap(1); lr.href = d->qtAssert.cap(1);
lr.start = m_qtAssert.pos(1); lr.start = d->qtAssert.pos(1);
lr.end = lr.start + lr.href.length(); lr.end = lr.start + lr.href.length();
} else if (m_qtAssertX.indexIn(line) != -1) { } else if (d->qtAssertX.indexIn(line) != -1) {
lr.href = m_qtAssertX.cap(1); lr.href = d->qtAssertX.cap(1);
lr.start = m_qtAssertX.pos(1); lr.start = d->qtAssertX.pos(1);
lr.end = lr.start + lr.href.length(); lr.end = lr.start + lr.href.length();
} else if (m_qtTestFail.indexIn(line) != -1) { } else if (d->qtTestFail.indexIn(line) != -1) {
lr.href = m_qtTestFail.cap(1); lr.href = d->qtTestFail.cap(1);
lr.start = m_qtTestFail.pos(1); lr.start = d->qtTestFail.pos(1);
lr.end = lr.start + lr.href.length(); lr.end = lr.start + lr.href.length();
} }
return lr; return lr;
} }
void QtOutputFormatter::appendMessage(const QString &txt, Utils::OutputFormat format) void QtOutputFormatter::appendMessage(const QString &txt, OutputFormat format)
{ {
appendMessage(txt, charFormat(format)); appendMessage(txt, charFormat(format));
} }
@@ -113,14 +146,14 @@ void QtOutputFormatter::appendMessagePart(QTextCursor &cursor, const QString &tx
for (int start = 0, pos = -1; start < length; start = pos + 1) { for (int start = 0, pos = -1; start < length; start = pos + 1) {
pos = txt.indexOf(QLatin1Char('\n'), start); pos = txt.indexOf(QLatin1Char('\n'), start);
const QString newPart = txt.mid(start, (pos == -1) ? -1 : pos - start + 1); const QString newPart = txt.mid(start, (pos == -1) ? -1 : pos - start + 1);
const QString line = m_lastLine + newPart; const QString line = d->lastLine + newPart;
LinkResult lr = matchLine(line); LinkResult lr = matchLine(line);
if (!lr.href.isEmpty()) { if (!lr.href.isEmpty()) {
// Found something && line continuation // Found something && line continuation
cursor.insertText(deferredText, format); cursor.insertText(deferredText, format);
deferredText.clear(); deferredText.clear();
if (!m_lastLine.isEmpty()) if (!d->lastLine.isEmpty())
clearLastLine(); clearLastLine();
appendLine(cursor, lr, line, format); appendLine(cursor, lr, line, format);
} else { } else {
@@ -129,10 +162,10 @@ void QtOutputFormatter::appendMessagePart(QTextCursor &cursor, const QString &tx
} }
if (pos == -1) { if (pos == -1) {
m_lastLine = line; d->lastLine = line;
break; break;
} }
m_lastLine.clear(); // Handled line continuation d->lastLine.clear(); // Handled line continuation
} }
cursor.insertText(deferredText, format); cursor.insertText(deferredText, format);
} }
@@ -150,7 +183,7 @@ void QtOutputFormatter::appendMessage(const QString &txt, const QTextCharFormat
} }
void QtOutputFormatter::appendLine(QTextCursor &cursor, const LinkResult &lr, void QtOutputFormatter::appendLine(QTextCursor &cursor, const LinkResult &lr,
const QString &line, Utils::OutputFormat format) const QString &line, OutputFormat format)
{ {
appendLine(cursor, lr, line, charFormat(format)); appendLine(cursor, lr, line, charFormat(format));
} }
@@ -186,7 +219,7 @@ void QtOutputFormatter::handleLink(const QString &href)
const int line = qmlLineColumnLink.cap(2).toInt(); const int line = qmlLineColumnLink.cap(2).toInt();
const int column = qmlLineColumnLink.cap(3).toInt(); const int column = qmlLineColumnLink.cap(3).toInt();
openEditor(m_projectFinder.findFile(fileUrl), line, column - 1); openEditor(d->projectFinder.findFile(fileUrl), line, column - 1);
return; return;
} }
@@ -197,7 +230,7 @@ void QtOutputFormatter::handleLink(const QString &href)
if (qmlLineLink.indexIn(href) != -1) { if (qmlLineLink.indexIn(href) != -1) {
const QUrl fileUrl = QUrl(qmlLineLink.cap(1)); const QUrl fileUrl = QUrl(qmlLineLink.cap(1));
const int line = qmlLineLink.cap(2).toInt(); const int line = qmlLineLink.cap(2).toInt();
openEditor(m_projectFinder.findFile(m_projectFinder.findFile(fileUrl)), line); openEditor(d->projectFinder.findFile(d->projectFinder.findFile(fileUrl)), line);
return; return;
} }
@@ -223,7 +256,7 @@ void QtOutputFormatter::handleLink(const QString &href)
} }
if (!fileName.isEmpty()) { if (!fileName.isEmpty()) {
fileName = m_projectFinder.findFile(QUrl::fromLocalFile(fileName)); fileName = d->projectFinder.findFile(QUrl::fromLocalFile(fileName));
openEditor(fileName, line); openEditor(fileName, line);
return; return;
} }
@@ -233,7 +266,7 @@ void QtOutputFormatter::handleLink(const QString &href)
void QtOutputFormatter::clearLastLine() void QtOutputFormatter::clearLastLine()
{ {
OutputFormatter::clearLastLine(); OutputFormatter::clearLastLine();
m_lastLine.clear(); d->lastLine.clear();
} }
void QtOutputFormatter::openEditor(const QString &fileName, int line, int column) void QtOutputFormatter::openEditor(const QString &fileName, int line, int column)
@@ -243,10 +276,12 @@ void QtOutputFormatter::openEditor(const QString &fileName, int line, int column
void QtOutputFormatter::updateProjectFileList() void QtOutputFormatter::updateProjectFileList()
{ {
if (m_project) if (d->project)
m_projectFinder.setProjectFiles(m_project.data()->files(Project::ExcludeGeneratedFiles)); d->projectFinder.setProjectFiles(d->project.data()->files(Project::ExcludeGeneratedFiles));
} }
} // namespace QtSupport
// Unit tests: // Unit tests:
#ifdef WITH_TESTS #ifdef WITH_TESTS
@@ -255,9 +290,11 @@ void QtOutputFormatter::updateProjectFileList()
# include "qtsupportplugin.h" # include "qtsupportplugin.h"
using namespace QtSupport::Internal; Q_DECLARE_METATYPE(QTextCharFormat)
Q_DECLARE_METATYPE(QTextCharFormat); namespace QtSupport {
using namespace QtSupport::Internal;
class TestQtOutputFormatter : public QtOutputFormatter class TestQtOutputFormatter : public QtOutputFormatter
{ {
@@ -427,4 +464,6 @@ void QtSupportPlugin::testQtOutputFormatter_appendMixedAssertAndAnsi()
QCOMPARE(edit.currentCharFormat(), blueFormat()); QCOMPARE(edit.currentCharFormat(), blueFormat());
} }
} // namespace QtSupport
#endif // WITH_TESTS #endif // WITH_TESTS

View File

@@ -34,10 +34,6 @@
#include "qtsupport_global.h" #include "qtsupport_global.h"
#include <utils/outputformatter.h> #include <utils/outputformatter.h>
#include <utils/fileinprojectfinder.h>
#include <QRegExp>
#include <QPointer>
QT_FORWARD_DECLARE_CLASS(QTextCursor) QT_FORWARD_DECLARE_CLASS(QTextCursor)
@@ -53,15 +49,16 @@ struct LinkResult
}; };
namespace Internal { namespace Internal {
class QtOutputFormatterPrivate;
class QtSupportPlugin; class QtSupportPlugin;
} }
class QTSUPPORT_EXPORT QtOutputFormatter class QTSUPPORT_EXPORT QtOutputFormatter : public Utils::OutputFormatter
: public Utils::OutputFormatter
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit QtOutputFormatter(ProjectExplorer::Project *project); explicit QtOutputFormatter(ProjectExplorer::Project *project);
~QtOutputFormatter();
void appendMessage(const QString &text, Utils::OutputFormat format); void appendMessage(const QString &text, Utils::OutputFormat format);
void appendMessage(const QString &text, const QTextCharFormat &format); void appendMessage(const QString &text, const QTextCharFormat &format);
@@ -82,14 +79,7 @@ private:
void appendLine(QTextCursor &cursor, const LinkResult &lr, const QString &line, void appendLine(QTextCursor &cursor, const LinkResult &lr, const QString &line,
const QTextCharFormat &format); const QTextCharFormat &format);
mutable QRegExp m_qmlError; Internal::QtOutputFormatterPrivate *d;
mutable QRegExp m_qtError;
mutable QRegExp m_qtAssert;
mutable QRegExp m_qtAssertX;
mutable QRegExp m_qtTestFail;
QPointer<ProjectExplorer::Project> m_project;
QString m_lastLine;
Utils::FileInProjectFinder m_projectFinder;
// for testing // for testing
friend class Internal::QtSupportPlugin; friend class Internal::QtSupportPlugin;