aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qtsupport/qtoutputformatter.cpp
diff options
context:
space:
mode:
authordt <qtc-committer@nokia.com>2011-05-20 21:40:53 +0200
committerDaniel Teske <daniel.teske@nokia.com>2011-05-24 18:35:11 +0200
commit754be1bcfcd22e41f591ae78642605f639b075b1 (patch)
treea0f0d1f36165bacede673a13ed26904dc04f3970 /src/plugins/qtsupport/qtoutputformatter.cpp
parentdcd34febabccdcb96fc7963172cba270e20aa483 (diff)
Move a lot of qmake independent classes to a new plugin qtsupport
Also adjust qmldumptool to remove the dependency on qt4project/qmlproject, by passing in the qtversion instead of figuring it out in qmldumptool. Change-Id: Ie6ac582d36bfef290313c0716b33b62fcf42630c Reviewed-on: http://codereview.qt.nokia.com/70 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Daniel Teske <daniel.teske@nokia.com>
Diffstat (limited to 'src/plugins/qtsupport/qtoutputformatter.cpp')
-rw-r--r--src/plugins/qtsupport/qtoutputformatter.cpp268
1 files changed, 268 insertions, 0 deletions
diff --git a/src/plugins/qtsupport/qtoutputformatter.cpp b/src/plugins/qtsupport/qtoutputformatter.cpp
new file mode 100644
index 00000000000..036521ac529
--- /dev/null
+++ b/src/plugins/qtsupport/qtoutputformatter.cpp
@@ -0,0 +1,268 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#include "qtoutputformatter.h"
+
+#include <texteditor/basetexteditor.h>
+#include <qt4projectmanager/qt4project.h>
+#include <utils/qtcassert.h>
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QUrl>
+#include <QtGui/QPlainTextEdit>
+#include <QtGui/QTextCursor>
+
+using namespace ProjectExplorer;
+using namespace QtSupport;
+
+QtOutputFormatter::QtOutputFormatter(ProjectExplorer::Project *project)
+ : OutputFormatter()
+ , m_qmlError(QLatin1String("^(?:\\[Qt Message\\] )?" // '[Qt Message] ' prefix (optional, on Symbian)
+ "(file:///.+" // file url
+ ":\\d+" // colon, line
+ "(?::\\d+)?)" // colon, column (optional)
+ ":")) // colon
+ , m_qtError(QLatin1String("Object::.*in (.*:\\d+)"))
+ , m_qtAssert(QLatin1String("ASSERT: .* in file (.+, line \\d+)"))
+ , m_qtTestFail(QLatin1String("^ Loc: \\[(.*)\\]"))
+ , m_project(project)
+{
+ if(project) {
+ m_projectFinder.setProjectFiles(project->files(Project::ExcludeGeneratedFiles));
+ m_projectFinder.setProjectDirectory(project->projectDirectory());
+
+ connect(project, SIGNAL(fileListChanged()),
+ this, SLOT(updateProjectFileList()));
+ }
+}
+
+LinkResult QtOutputFormatter::matchLine(const QString &line) const
+{
+ 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();
+ } else if (m_qtAssert.indexIn(line) != -1) {
+ lr.href = m_qtAssert.cap(1);
+ lr.start = m_qtAssert.pos(1);
+ lr.end = lr.start + lr.href.length();
+ } else if (m_qtTestFail.indexIn(line) != -1) {
+ lr.href = m_qtTestFail.cap(1);
+ lr.start = m_qtTestFail.pos(1);
+ lr.end = lr.start + lr.href.length();
+ }
+ return lr;
+}
+
+void QtOutputFormatter::appendMessage(const QString &txt, Utils::OutputFormat format)
+{
+ QTextCursor cursor(plainTextEdit()->document());
+ cursor.movePosition(QTextCursor::End);
+ cursor.beginEditBlock();
+
+ QString text = txt;
+ text.remove(QLatin1Char('\r'));
+
+ QString deferedText;
+
+ 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
+ cursor.insertText(deferedText, charFormat(format));
+ deferedText.clear();
+ clearLastLine();
+ appendLine(cursor, lr, line, format);
+ } else {
+ // Found nothing, just emit the new part
+ deferedText += newPart;
+ }
+ // Handled line continuation
+ m_lastLine.clear();
+ } else {
+ const QString line = txt.mid(start, pos - start + 1);
+ LinkResult lr = matchLine(line);
+ if (!lr.href.isEmpty()) {
+ cursor.insertText(deferedText, charFormat(format));
+ deferedText.clear();
+ appendLine(cursor, lr, line, format);
+ } else {
+ deferedText += line;
+ }
+ }
+ 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
+ cursor.insertText(deferedText, charFormat(format));
+ deferedText.clear();
+ clearLastLine();
+ appendLine(cursor, lr, m_lastLine, format);
+ } else {
+ // Found nothing, just emit the new part
+ deferedText += newPart;
+ }
+ } else {
+ m_lastLine = txt.mid(start);
+ LinkResult lr = matchLine(m_lastLine);
+ if (!lr.href.isEmpty()) {
+ cursor.insertText(deferedText, charFormat(format));
+ deferedText.clear();
+ appendLine(cursor, lr, m_lastLine, format);
+ } else {
+ deferedText += m_lastLine;
+ }
+ }
+ }
+ cursor.insertText(deferedText, charFormat(format));
+ // deferedText.clear();
+ cursor.endEditBlock();
+}
+
+void QtOutputFormatter::appendLine(QTextCursor &cursor, LinkResult lr,
+ const QString &line, Utils::OutputFormat format)
+{
+ const QTextCharFormat normalFormat = charFormat(format);
+ cursor.insertText(line.left(lr.start), normalFormat);
+
+ QTextCharFormat linkFormat = normalFormat;
+ const QColor textColor = plainTextEdit()->palette().color(QPalette::Text);
+ linkFormat.setForeground(mixColors(textColor, QColor(Qt::blue)));
+ linkFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ linkFormat.setAnchor(true);
+ linkFormat.setAnchorHref(lr.href);
+ cursor.insertText(line.mid(lr.start, lr.end - lr.start), linkFormat);
+ cursor.insertText(line.mid(lr.end), normalFormat);
+}
+
+void QtOutputFormatter::handleLink(const QString &href)
+{
+ if (!href.isEmpty()) {
+ const QRegExp qmlLineColumnLink(QLatin1String("^(file:///.+)" // file url
+ ":(\\d+)" // line
+ ":(\\d+)$")); // column
+
+ if (qmlLineColumnLink.indexIn(href) != -1) {
+ const QString fileName = QUrl(qmlLineColumnLink.cap(1)).toLocalFile();
+ const int line = qmlLineColumnLink.cap(2).toInt();
+ const int column = qmlLineColumnLink.cap(3).toInt();
+
+ TextEditor::BaseTextEditorWidget::openEditorAt(m_projectFinder.findFile(fileName), line, column - 1);
+
+ return;
+ }
+
+ const QRegExp qmlLineLink(QLatin1String("^(file:///.+)" // file url
+ ":(\\d+)$")); // line
+
+ if (qmlLineLink.indexIn(href) != -1) {
+ const QString fileName = QUrl(qmlLineLink.cap(1)).toLocalFile();
+ const int line = qmlLineLink.cap(2).toInt();
+ TextEditor::BaseTextEditorWidget::openEditorAt(m_projectFinder.findFile(fileName), line);
+ return;
+ }
+
+ QString fileName;
+ int line = -1;
+
+ QRegExp qtErrorLink(QLatin1String("^(.*):(\\d+)$"));
+ if (qtErrorLink.indexIn(href) != -1) {
+ fileName = qtErrorLink.cap(1);
+ line = qtErrorLink.cap(2).toInt();
+ }
+
+ QRegExp qtAssertLink(QLatin1String("^(.+), line (\\d+)$"));
+ if (qtAssertLink.indexIn(href) != -1) {
+ fileName = qtAssertLink.cap(1);
+ line = qtAssertLink.cap(2).toInt();
+ }
+
+ QRegExp qtTestFailLink(QLatin1String("^(.*)\\((\\d+)\\)$"));
+ if (qtTestFailLink.indexIn(href) != -1) {
+ fileName = qtTestFailLink.cap(1);
+ line = qtTestFailLink.cap(2).toInt();
+ }
+
+ if (!fileName.isEmpty()) {
+ QFileInfo fi(fileName);
+ if (fi.isRelative()) {
+ // Yeah fileName is relative, no surprise
+ ProjectExplorer::Project *pro = m_project.data();
+ if (pro) {
+ QString baseName = fi.fileName();
+ foreach (const QString &file, pro->files(Project::AllFiles)) {
+ if (file.endsWith(baseName)) {
+ // pick the first one...
+ fileName = file;
+ break;
+ }
+ }
+ }
+ } else if (!fi.exists()) {
+ // map possible on-device path to source path
+ fileName = m_projectFinder.findFile(fileName);
+ }
+ TextEditor::BaseTextEditorWidget::openEditorAt(fileName, line, 0);
+ return;
+ }
+ }
+}
+
+void QtOutputFormatter::updateProjectFileList()
+{
+ if (m_project)
+ m_projectFinder.setProjectFiles(m_project.data()->files(Project::ExcludeGeneratedFiles));
+}