forked from qt-creator/qt-creator
Moved "Application Output" formatting to a specialized formatter.
By introducing the OutputFormatter, RunControls can influence the formatting depening on the application started. A nice (and intended) side-effect is that the QML runtime specific formatting will not interfere anymore with anything else.
This commit is contained in:
72
src/plugins/projectexplorer/outputformatter.cpp
Normal file
72
src/plugins/projectexplorer/outputformatter.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, 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.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "outputformatter.h"
|
||||
|
||||
#include <QtGui/QPlainTextEdit>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
OutputFormatter::OutputFormatter(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QPlainTextEdit *OutputFormatter::plainTextEdit() const
|
||||
{
|
||||
return m_plainTextEdit;
|
||||
}
|
||||
|
||||
void OutputFormatter::setPlainTextEdit(QPlainTextEdit *plainText)
|
||||
{
|
||||
m_plainTextEdit = plainText;
|
||||
setParent(m_plainTextEdit);
|
||||
}
|
||||
|
||||
void OutputFormatter::appendOutput(const QString &text)
|
||||
{
|
||||
QTextCharFormat format;
|
||||
format.setForeground(plainTextEdit()->palette().text().color());
|
||||
plainTextEdit()->setCurrentCharFormat(format);
|
||||
plainTextEdit()->insertPlainText(text);
|
||||
}
|
||||
|
||||
void OutputFormatter::appendError(const QString &text)
|
||||
{
|
||||
appendOutput(text);
|
||||
}
|
||||
|
||||
void OutputFormatter::mousePressEvent(QMouseEvent * /*e*/)
|
||||
{}
|
||||
|
||||
void OutputFormatter::mouseReleaseEvent(QMouseEvent * /*e*/)
|
||||
{}
|
||||
|
||||
void OutputFormatter::mouseMoveEvent(QMouseEvent * /*e*/)
|
||||
{}
|
||||
66
src/plugins/projectexplorer/outputformatter.h
Normal file
66
src/plugins/projectexplorer/outputformatter.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, 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.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef OUTPUTFORMATTER_H
|
||||
#define OUTPUTFORMATTER_H
|
||||
|
||||
#include "projectexplorer_export.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QString>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QPlainTextEdit);
|
||||
QT_FORWARD_DECLARE_CLASS(QMouseEvent);
|
||||
|
||||
namespace ProjectExplorer {
|
||||
|
||||
class PROJECTEXPLORER_EXPORT OutputFormatter: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
OutputFormatter(QObject *parent = 0);
|
||||
|
||||
QPlainTextEdit *plainTextEdit() const;
|
||||
void setPlainTextEdit(QPlainTextEdit *plainText);
|
||||
|
||||
virtual void appendOutput(const QString &text);
|
||||
virtual void appendError(const QString &text);
|
||||
|
||||
virtual void mousePressEvent(QMouseEvent *e);
|
||||
virtual void mouseReleaseEvent(QMouseEvent *e);
|
||||
virtual void mouseMoveEvent(QMouseEvent *e);
|
||||
|
||||
private:
|
||||
QPlainTextEdit *m_plainTextEdit;
|
||||
};
|
||||
|
||||
} // namespace ProjectExplorer
|
||||
|
||||
#endif // OUTPUTFORMATTER_H
|
||||
@@ -42,7 +42,6 @@
|
||||
#include <coreplugin/icontext.h>
|
||||
#include <find/basetextfind.h>
|
||||
#include <aggregation/aggregate.h>
|
||||
#include <texteditor/basetexteditor.h>
|
||||
|
||||
#include <QtGui/QIcon>
|
||||
#include <QtGui/QScrollBar>
|
||||
@@ -176,11 +175,6 @@ void OutputPane::setFocus()
|
||||
m_tabWidget->currentWidget()->setFocus();
|
||||
}
|
||||
|
||||
void OutputPane::appendOutput(const QString &/*out*/)
|
||||
{
|
||||
// This function is in the interface, since we can't do anything sensible here, we don't do anything here.
|
||||
}
|
||||
|
||||
void OutputPane::createNewOutputWindow(RunControl *rc)
|
||||
{
|
||||
connect(rc, SIGNAL(started()),
|
||||
@@ -199,6 +193,7 @@ void OutputPane::createNewOutputWindow(RunControl *rc)
|
||||
OutputWindow *ow = static_cast<OutputWindow *>(m_tabWidget->widget(i));
|
||||
ow->grayOutOldContent();
|
||||
ow->verticalScrollBar()->setValue(ow->verticalScrollBar()->maximum());
|
||||
ow->setFormatter(rc->createOutputFormatter(ow));
|
||||
m_outputWindows.insert(rc, ow);
|
||||
found = true;
|
||||
break;
|
||||
@@ -206,6 +201,7 @@ void OutputPane::createNewOutputWindow(RunControl *rc)
|
||||
}
|
||||
if (!found) {
|
||||
OutputWindow *ow = new OutputWindow(m_tabWidget);
|
||||
ow->setFormatter(rc->createOutputFormatter(ow));
|
||||
Aggregation::Aggregate *agg = new Aggregation::Aggregate;
|
||||
agg->add(ow);
|
||||
agg->add(new Find::BaseTextFind(ow));
|
||||
@@ -226,6 +222,12 @@ void OutputPane::appendOutputInline(RunControl *rc, const QString &out)
|
||||
ow->appendOutputInline(out);
|
||||
}
|
||||
|
||||
void OutputPane::appendError(RunControl *rc, const QString &out)
|
||||
{
|
||||
OutputWindow *ow = m_outputWindows.value(rc);
|
||||
ow->appendError(out);
|
||||
}
|
||||
|
||||
void OutputPane::showTabFor(RunControl *rc)
|
||||
{
|
||||
OutputWindow *ow = m_outputWindows.value(rc);
|
||||
@@ -346,11 +348,8 @@ bool OutputPane::canNavigate()
|
||||
|
||||
OutputWindow::OutputWindow(QWidget *parent)
|
||||
: QPlainTextEdit(parent)
|
||||
, m_qmlError(QLatin1String("(file:///[^:]+:\\d+:\\d+):"))
|
||||
, m_enforceNewline(false)
|
||||
, m_scrollToBottom(false)
|
||||
, m_linksActive(true)
|
||||
, m_mousePressed(false)
|
||||
{
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
//setCenterOnScroll(false);
|
||||
@@ -405,6 +404,17 @@ OutputWindow::~OutputWindow()
|
||||
delete m_outputWindowContext;
|
||||
}
|
||||
|
||||
OutputFormatter *OutputWindow::formatter() const
|
||||
{
|
||||
return m_formatter;
|
||||
}
|
||||
|
||||
void OutputWindow::setFormatter(OutputFormatter *formatter)
|
||||
{
|
||||
m_formatter = formatter;
|
||||
m_formatter->setPlainTextEdit(this);
|
||||
}
|
||||
|
||||
void OutputWindow::showEvent(QShowEvent *e)
|
||||
{
|
||||
QPlainTextEdit::showEvent(e);
|
||||
@@ -414,20 +424,28 @@ void OutputWindow::showEvent(QShowEvent *e)
|
||||
m_scrollToBottom = false;
|
||||
}
|
||||
|
||||
void OutputWindow::appendOutput(const QString &out)
|
||||
QString OutputWindow::doNewlineMagic(const QString &out)
|
||||
{
|
||||
m_scrollToBottom = true;
|
||||
QString s = out;
|
||||
m_enforceNewline = true; // make appendOutputInline put in a newline next time
|
||||
if (s.endsWith(QLatin1Char('\n'))) {
|
||||
s.chop(1);
|
||||
}
|
||||
setMaximumBlockCount(MaxBlockCount);
|
||||
if (m_enforceNewline)
|
||||
s.prepend(QLatin1Char('\n'));
|
||||
|
||||
QTextCharFormat format;
|
||||
format.setForeground(palette().text().color());
|
||||
setCurrentCharFormat(format);
|
||||
appendPlainText(out);
|
||||
m_enforceNewline = true; // make appendOutputInline put in a newline next time
|
||||
|
||||
if (s.endsWith(QLatin1Char('\n')))
|
||||
s.chop(1);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void OutputWindow::appendOutput(const QString &out)
|
||||
{
|
||||
setMaximumBlockCount(MaxBlockCount);
|
||||
const bool atBottom = isScrollbarAtBottom();
|
||||
m_formatter->appendOutput(doNewlineMagic(out));
|
||||
if (atBottom)
|
||||
scrollToBottom();
|
||||
enableUndoRedo();
|
||||
}
|
||||
|
||||
@@ -439,15 +457,12 @@ void OutputWindow::appendOutputInline(const QString &out)
|
||||
int newline = -1;
|
||||
bool enforceNewline = m_enforceNewline;
|
||||
m_enforceNewline = false;
|
||||
const bool atBottom = isScrollbarAtBottom();
|
||||
|
||||
if (!enforceNewline) {
|
||||
newline = out.indexOf(QLatin1Char('\n'));
|
||||
moveCursor(QTextCursor::End);
|
||||
bool atBottom = (blockBoundingRect(document()->lastBlock()).bottom() + contentOffset().y()
|
||||
<= viewport()->rect().bottom());
|
||||
insertPlainText(newline < 0 ? out : out.left(newline)); // doesn't enforce new paragraph like appendPlainText
|
||||
if (atBottom)
|
||||
verticalScrollBar()->setValue(verticalScrollBar()->maximum());
|
||||
m_formatter->appendOutput(newline < 0 ? out : out.left(newline)); // doesn't enforce new paragraph like appendPlainText
|
||||
}
|
||||
|
||||
QString s = out.mid(newline+1);
|
||||
@@ -458,28 +473,32 @@ void OutputWindow::appendOutputInline(const QString &out)
|
||||
m_enforceNewline = true;
|
||||
s.chop(1);
|
||||
}
|
||||
QTextCharFormat format;
|
||||
format.setForeground(palette().text().color());
|
||||
setCurrentCharFormat(format);
|
||||
|
||||
// (This feature depends on the availability of QPlainTextEdit::anchorAt)
|
||||
// Convert to HTML, preserving newlines and whitespace
|
||||
s = Qt::convertFromPlainText(s);
|
||||
|
||||
// Create links from QML errors (anything of the form "file:///...:[line]:[column]:")
|
||||
int index = 0;
|
||||
while ((index = m_qmlError.indexIn(s, index)) != -1) {
|
||||
const QString captured = m_qmlError.cap(1);
|
||||
const QString link = QString(QLatin1String("<a href=\"%1\">%2</a>")).arg(captured, captured);
|
||||
s.replace(index, captured.length(), link);
|
||||
index += link.length();
|
||||
}
|
||||
appendHtml(s);
|
||||
m_formatter->appendOutput(QLatin1Char('\n') + s);
|
||||
}
|
||||
|
||||
if (atBottom)
|
||||
scrollToBottom();
|
||||
enableUndoRedo();
|
||||
}
|
||||
|
||||
void OutputWindow::appendError(const QString &out)
|
||||
{
|
||||
setMaximumBlockCount(MaxBlockCount);
|
||||
m_formatter->appendError(doNewlineMagic(out));
|
||||
enableUndoRedo();
|
||||
}
|
||||
|
||||
bool OutputWindow::isScrollbarAtBottom() const
|
||||
{
|
||||
return blockBoundingRect(document()->lastBlock()).bottom() + contentOffset().y()
|
||||
<= viewport()->rect().bottom();
|
||||
}
|
||||
|
||||
void OutputWindow::scrollToBottom()
|
||||
{
|
||||
verticalScrollBar()->setValue(verticalScrollBar()->maximum());
|
||||
}
|
||||
|
||||
void OutputWindow::grayOutOldContent()
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
@@ -512,43 +531,17 @@ void OutputWindow::enableUndoRedo()
|
||||
void OutputWindow::mousePressEvent(QMouseEvent *e)
|
||||
{
|
||||
QPlainTextEdit::mousePressEvent(e);
|
||||
m_mousePressed = true;
|
||||
m_formatter->mousePressEvent(e);
|
||||
}
|
||||
|
||||
void OutputWindow::mouseReleaseEvent(QMouseEvent *e)
|
||||
{
|
||||
QPlainTextEdit::mouseReleaseEvent(e);
|
||||
m_mousePressed = false;
|
||||
|
||||
if (!m_linksActive) {
|
||||
// Mouse was released, activate links again
|
||||
m_linksActive = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const QString href = anchorAt(e->pos());
|
||||
if (!href.isEmpty()) {
|
||||
QRegExp qmlErrorLink(QLatin1String("^file://(/[^:]+):(\\d+):(\\d+)"));
|
||||
|
||||
if (qmlErrorLink.indexIn(href) != -1) {
|
||||
const QString fileName = qmlErrorLink.cap(1);
|
||||
const int line = qmlErrorLink.cap(2).toInt();
|
||||
const int column = qmlErrorLink.cap(3).toInt();
|
||||
TextEditor::BaseTextEditor::openEditorAt(fileName, line, column - 1);
|
||||
}
|
||||
}
|
||||
m_formatter->mouseReleaseEvent(e);
|
||||
}
|
||||
|
||||
void OutputWindow::mouseMoveEvent(QMouseEvent *e)
|
||||
{
|
||||
QPlainTextEdit::mouseMoveEvent(e);
|
||||
|
||||
// Cursor was dragged to make a selection, deactivate links
|
||||
if (m_mousePressed && textCursor().hasSelection())
|
||||
m_linksActive = false;
|
||||
|
||||
if (!m_linksActive || anchorAt(e->pos()).isEmpty())
|
||||
viewport()->setCursor(Qt::IBeamCursor);
|
||||
else
|
||||
viewport()->setCursor(Qt::PointingHandCursor);
|
||||
m_formatter->mouseMoveEvent(e);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#define OUTPUTWINDOW_H
|
||||
|
||||
#include <coreplugin/ioutputpane.h>
|
||||
#include <projectexplorer/outputformatter.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QHash>
|
||||
@@ -83,18 +84,18 @@ public:
|
||||
void goToPrev();
|
||||
bool canNavigate();
|
||||
|
||||
void appendOutput(const QString &out);
|
||||
|
||||
// ApplicationOutputspecifics
|
||||
void createNewOutputWindow(RunControl *rc);
|
||||
void appendOutput(RunControl *rc, const QString &out);
|
||||
void appendOutputInline(RunControl *rc, const QString &out);
|
||||
void showTabFor(RunControl *rc);
|
||||
|
||||
public slots:
|
||||
// ApplicationOutputspecifics
|
||||
void createNewOutputWindow(RunControl *rc);
|
||||
void projectRemoved();
|
||||
void coreAboutToClose();
|
||||
|
||||
void appendOutput(RunControl *rc, const QString &out);
|
||||
void appendOutputInline(RunControl *rc, const QString &out);
|
||||
void appendError(RunControl *rc, const QString &out);
|
||||
|
||||
private slots:
|
||||
void reRunRunControl();
|
||||
void stopRunControl();
|
||||
@@ -123,8 +124,13 @@ public:
|
||||
OutputWindow(QWidget *parent = 0);
|
||||
~OutputWindow();
|
||||
|
||||
OutputFormatter* formatter() const;
|
||||
void setFormatter(OutputFormatter *formatter);
|
||||
|
||||
void appendOutput(const QString &out);
|
||||
void appendOutputInline(const QString &out);
|
||||
void appendError(const QString &out);
|
||||
|
||||
void grayOutOldContent();
|
||||
|
||||
void showEvent(QShowEvent *);
|
||||
@@ -134,15 +140,19 @@ protected:
|
||||
void mouseReleaseEvent(QMouseEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
|
||||
bool isScrollbarAtBottom() const;
|
||||
void scrollToBottom();
|
||||
|
||||
private:
|
||||
void enableUndoRedo();
|
||||
QString doNewlineMagic(const QString &out);
|
||||
|
||||
private:
|
||||
Core::BaseContext *m_outputWindowContext;
|
||||
void enableUndoRedo();
|
||||
OutputFormatter *m_formatter;
|
||||
|
||||
QRegExp m_qmlError;
|
||||
bool m_enforceNewline;
|
||||
bool m_scrollToBottom;
|
||||
bool m_linksActive;
|
||||
bool m_mousePressed;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -1274,11 +1274,12 @@ void ProjectExplorerPlugin::startRunControl(RunControl *runControl, const QStrin
|
||||
d->m_outputPane->clearContents();
|
||||
|
||||
connect(runControl, SIGNAL(addToOutputWindow(RunControl *, const QString &)),
|
||||
this, SLOT(addToApplicationOutputWindow(RunControl *, const QString &)));
|
||||
d->m_outputPane, SLOT(appendOutput(RunControl*,const QString &)));
|
||||
connect(runControl, SIGNAL(addToOutputWindowInline(RunControl *, const QString &)),
|
||||
this, SLOT(addToApplicationOutputWindowInline(RunControl *, const QString &)));
|
||||
d->m_outputPane, SLOT(appendOutputInline(RunControl*,const QString &)));
|
||||
connect(runControl, SIGNAL(error(RunControl *, const QString &)),
|
||||
this, SLOT(addErrorToApplicationOutputWindow(RunControl *, const QString &)));
|
||||
d->m_outputPane, SLOT(appendError(RunControl *, const QString &)));
|
||||
|
||||
connect(runControl, SIGNAL(finished()),
|
||||
this, SLOT(runControlFinished()));
|
||||
|
||||
@@ -1711,21 +1712,6 @@ bool ProjectExplorerPlugin::showBuildConfigDialog()
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectExplorerPlugin::addToApplicationOutputWindow(RunControl *rc, const QString &line)
|
||||
{
|
||||
d->m_outputPane->appendOutput(rc, line);
|
||||
}
|
||||
|
||||
void ProjectExplorerPlugin::addToApplicationOutputWindowInline(RunControl *rc, const QString &line)
|
||||
{
|
||||
d->m_outputPane->appendOutputInline(rc, line);
|
||||
}
|
||||
|
||||
void ProjectExplorerPlugin::addErrorToApplicationOutputWindow(RunControl *rc, const QString &error)
|
||||
{
|
||||
d->m_outputPane->appendOutput(rc, error);
|
||||
}
|
||||
|
||||
void ProjectExplorerPlugin::runControlFinished()
|
||||
{
|
||||
if (sender() == d->m_debuggingRunControl)
|
||||
|
||||
@@ -182,10 +182,6 @@ private slots:
|
||||
void startupProjectChanged(); // Calls updateRunAction
|
||||
void updateRunActions();
|
||||
|
||||
void addToApplicationOutputWindow(RunControl *, const QString &line);
|
||||
void addToApplicationOutputWindowInline(RunControl *, const QString &line);
|
||||
void addErrorToApplicationOutputWindow(RunControl *, const QString &error);
|
||||
|
||||
void loadProject(const QString &project) { openProject(project); }
|
||||
void currentModeChanged(Core::IMode *mode, Core::IMode *oldMode);
|
||||
void updateActions();
|
||||
|
||||
@@ -79,7 +79,8 @@ HEADERS += projectexplorer.h \
|
||||
buildenvironmentwidget.h \
|
||||
buildconfigdialog.h \
|
||||
ldparser.h \
|
||||
linuxiccparser.h
|
||||
linuxiccparser.h \
|
||||
outputformatter.h
|
||||
SOURCES += projectexplorer.cpp \
|
||||
projectwindow.cpp \
|
||||
buildmanager.cpp \
|
||||
@@ -145,7 +146,8 @@ SOURCES += projectexplorer.cpp \
|
||||
buildenvironmentwidget.cpp \
|
||||
buildconfigdialog.cpp \
|
||||
ldparser.cpp \
|
||||
linuxiccparser.cpp
|
||||
linuxiccparser.cpp \
|
||||
outputformatter.cpp
|
||||
FORMS += processstep.ui \
|
||||
editorsettingspropertiespage.ui \
|
||||
runsettingspropertiespage.ui \
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "runconfiguration.h"
|
||||
|
||||
#include "outputformatter.h"
|
||||
#include "project.h"
|
||||
#include "target.h"
|
||||
#include "buildconfiguration.h"
|
||||
@@ -236,6 +237,11 @@ bool RunControl::sameRunConfiguration(RunControl *other)
|
||||
return other->m_runConfiguration.data() == m_runConfiguration.data();
|
||||
}
|
||||
|
||||
OutputFormatter *RunControl::createOutputFormatter(QObject *parent)
|
||||
{
|
||||
return new OutputFormatter(parent);
|
||||
}
|
||||
|
||||
void RunControl::bringApplicationToForeground(qint64 pid)
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
|
||||
@@ -47,6 +47,7 @@ class Target;
|
||||
|
||||
class RunControl;
|
||||
class BuildConfiguration;
|
||||
class OutputFormatter;
|
||||
|
||||
/**
|
||||
* Base class for a run configuration. A run configuration specifies how a
|
||||
@@ -168,6 +169,8 @@ public:
|
||||
|
||||
bool sameRunConfiguration(RunControl *other);
|
||||
|
||||
virtual OutputFormatter *createOutputFormatter(QObject *parent = 0);
|
||||
|
||||
signals:
|
||||
void addToOutputWindow(RunControl *, const QString &line);
|
||||
void addToOutputWindowInline(RunControl *, const QString &line);
|
||||
|
||||
118
src/plugins/qmlprojectmanager/qmloutputformatter.cpp
Normal file
118
src/plugins/qmlprojectmanager/qmloutputformatter.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, 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.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "qmloutputformatter.h"
|
||||
|
||||
#include <texteditor/basetexteditor.h>
|
||||
|
||||
#include <QtGui/QPlainTextEdit>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace QmlProjectManager::Internal;
|
||||
|
||||
QmlOutputFormatter::QmlOutputFormatter(QObject *parent)
|
||||
: OutputFormatter(parent)
|
||||
, m_qmlError(QLatin1String("(file:///[^:]+:\\d+:\\d+):"))
|
||||
, m_linksActive(true)
|
||||
, m_mousePressed(false)
|
||||
{
|
||||
}
|
||||
|
||||
void QmlOutputFormatter::appendOutput(const QString &text)
|
||||
{
|
||||
QTextCharFormat normalFormat, linkFormat;
|
||||
normalFormat.setForeground(plainTextEdit()->palette().text().color());
|
||||
linkFormat.setForeground(plainTextEdit()->palette().link().color());
|
||||
linkFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline);
|
||||
linkFormat.setAnchor(true);
|
||||
|
||||
plainTextEdit()->setCurrentCharFormat(normalFormat);
|
||||
|
||||
// Create links from QML errors (anything of the form "file:///...:[line]:[column]:")
|
||||
int index = 0;
|
||||
while (m_qmlError.indexIn(text, index) != -1) {
|
||||
const int matchPos = m_qmlError.pos(1);
|
||||
const QString leader = text.mid(index, matchPos - index);
|
||||
plainTextEdit()->insertPlainText(leader);
|
||||
|
||||
const QString matched = m_qmlError.cap(1);
|
||||
linkFormat.setAnchorHref(matched);
|
||||
plainTextEdit()->setCurrentCharFormat(linkFormat);
|
||||
plainTextEdit()->insertPlainText(matched);
|
||||
plainTextEdit()->setCurrentCharFormat(normalFormat);
|
||||
|
||||
index = matchPos + m_qmlError.matchedLength() - 1;
|
||||
}
|
||||
plainTextEdit()->insertPlainText(text.mid(index));
|
||||
}
|
||||
|
||||
void QmlOutputFormatter::appendError(const QString &text)
|
||||
{
|
||||
appendOutput(text);
|
||||
}
|
||||
|
||||
void QmlOutputFormatter::mousePressEvent(QMouseEvent * /*e*/)
|
||||
{
|
||||
m_mousePressed = true;
|
||||
}
|
||||
|
||||
void QmlOutputFormatter::mouseReleaseEvent(QMouseEvent *e)
|
||||
{
|
||||
m_mousePressed = false;
|
||||
|
||||
if (!m_linksActive) {
|
||||
// Mouse was released, activate links again
|
||||
m_linksActive = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const QString href = plainTextEdit()->anchorAt(e->pos());
|
||||
if (!href.isEmpty()) {
|
||||
QRegExp qmlErrorLink(QLatin1String("^file://(/[^:]+):(\\d+):(\\d+)"));
|
||||
|
||||
if (qmlErrorLink.indexIn(href) != -1) {
|
||||
const QString fileName = qmlErrorLink.cap(1);
|
||||
const int line = qmlErrorLink.cap(2).toInt();
|
||||
const int column = qmlErrorLink.cap(3).toInt();
|
||||
TextEditor::BaseTextEditor::openEditorAt(fileName, line, column - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QmlOutputFormatter::mouseMoveEvent(QMouseEvent *e)
|
||||
{
|
||||
// Cursor was dragged to make a selection, deactivate links
|
||||
if (m_mousePressed && plainTextEdit()->textCursor().hasSelection())
|
||||
m_linksActive = false;
|
||||
|
||||
if (!m_linksActive || plainTextEdit()->anchorAt(e->pos()).isEmpty())
|
||||
plainTextEdit()->viewport()->setCursor(Qt::IBeamCursor);
|
||||
else
|
||||
plainTextEdit()->viewport()->setCursor(Qt::PointingHandCursor);
|
||||
}
|
||||
61
src/plugins/qmlprojectmanager/qmloutputformatter.h
Normal file
61
src/plugins/qmlprojectmanager/qmloutputformatter.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, 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.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef QMLOUTPUTFORMATTER_H
|
||||
#define QMLOUTPUTFORMATTER_H
|
||||
|
||||
#include <projectexplorer/outputformatter.h>
|
||||
|
||||
#include <QtCore/QRegExp>
|
||||
|
||||
namespace QmlProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
class QmlOutputFormatter: public ProjectExplorer::OutputFormatter
|
||||
{
|
||||
public:
|
||||
QmlOutputFormatter(QObject *parent = 0);
|
||||
|
||||
virtual void appendOutput(const QString &text);
|
||||
virtual void appendError(const QString &text);
|
||||
|
||||
virtual void mousePressEvent(QMouseEvent *e);
|
||||
virtual void mouseReleaseEvent(QMouseEvent *e);
|
||||
virtual void mouseMoveEvent(QMouseEvent *e);
|
||||
|
||||
private:
|
||||
QRegExp m_qmlError;
|
||||
bool m_linksActive;
|
||||
bool m_mousePressed;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace QmlProjectManager
|
||||
|
||||
#endif // QMLOUTPUTFORMATTER_H
|
||||
@@ -22,7 +22,8 @@ HEADERS += qmlproject.h \
|
||||
qmltaskmanager.h \
|
||||
qmlprojectmanager_global.h \
|
||||
qmlprojectmanagerconstants.h \
|
||||
qmlprojecttarget.h
|
||||
qmlprojecttarget.h \
|
||||
qmloutputformatter.h
|
||||
SOURCES += qmlproject.cpp \
|
||||
qmlprojectplugin.cpp \
|
||||
qmlprojectmanager.cpp \
|
||||
@@ -34,7 +35,8 @@ SOURCES += qmlproject.cpp \
|
||||
qmlprojectrunconfigurationfactory.cpp \
|
||||
qmlprojectapplicationwizard.cpp \
|
||||
qmltaskmanager.cpp \
|
||||
qmlprojecttarget.cpp
|
||||
qmlprojecttarget.cpp \
|
||||
qmloutputformatter.cpp
|
||||
RESOURCES += qmlproject.qrc
|
||||
|
||||
OTHER_FILES += QmlProjectManager.pluginspec \
|
||||
|
||||
@@ -70,9 +70,9 @@ QmlProjectRunConfiguration::QmlProjectRunConfiguration(Internal::QmlProjectTarge
|
||||
|
||||
QmlProjectRunConfiguration::QmlProjectRunConfiguration(Internal::QmlProjectTarget *parent, QmlProjectRunConfiguration *source) :
|
||||
ProjectExplorer::RunConfiguration(parent, source),
|
||||
m_fileListModel(new QStringListModel(this)),
|
||||
m_qmlViewerCustomPath(source->m_qmlViewerCustomPath),
|
||||
m_qmlViewerArgs(source->m_qmlViewerArgs),
|
||||
m_fileListModel(new QStringListModel(this)),
|
||||
m_projectTarget(parent)
|
||||
{
|
||||
setMainScript(source->m_scriptFile);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "qmloutputformatter.h"
|
||||
#include "qmlprojectruncontrol.h"
|
||||
#include "qmlprojectrunconfiguration.h"
|
||||
#include "qmlprojectconstants.h"
|
||||
@@ -102,6 +103,11 @@ bool QmlRunControl::isRunning() const
|
||||
return m_applicationLauncher.isRunning();
|
||||
}
|
||||
|
||||
ProjectExplorer::OutputFormatter *QmlRunControl::createOutputFormatter(QObject *parent)
|
||||
{
|
||||
return new QmlOutputFormatter(parent);
|
||||
}
|
||||
|
||||
void QmlRunControl::slotBringApplicationToForeground(qint64 pid)
|
||||
{
|
||||
bringApplicationToForeground(pid);
|
||||
|
||||
@@ -50,6 +50,8 @@ public:
|
||||
virtual void stop();
|
||||
virtual bool isRunning() const;
|
||||
|
||||
virtual ProjectExplorer::OutputFormatter *createOutputFormatter(QObject *parent = 0);
|
||||
|
||||
private slots:
|
||||
void processExited(int exitCode);
|
||||
void slotBringApplicationToForeground(qint64 pid);
|
||||
|
||||
Reference in New Issue
Block a user