forked from qt-creator/qt-creator
ProjectExplorer: Generalize issues -> output pane linking
This feature was specific to the compile output pane, but we want to have it in other panes too. Change-Id: I110b27af7d0aa23acbc5623d1c0405816250df19 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -324,7 +324,7 @@ void OutputFormatter::doAppendMessage(const QString &text, OutputFormat format)
|
|||||||
if (d->postPrintAction)
|
if (d->postPrintAction)
|
||||||
d->postPrintAction(p);
|
d->postPrintAction(p);
|
||||||
else
|
else
|
||||||
p->runPostPrintActions();
|
p->runPostPrintActions(plainTextEdit());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -591,7 +591,7 @@ void OutputFormatter::flush()
|
|||||||
for (OutputLineParser * const p : qAsConst(d->lineParsers))
|
for (OutputLineParser * const p : qAsConst(d->lineParsers))
|
||||||
p->flush();
|
p->flush();
|
||||||
if (d->nextParser)
|
if (d->nextParser)
|
||||||
d->nextParser->runPostPrintActions();
|
d->nextParser->runPostPrintActions(plainTextEdit());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OutputFormatter::hasFatalErrors() const
|
bool OutputFormatter::hasFatalErrors() const
|
||||||
|
@@ -91,7 +91,7 @@ public:
|
|||||||
virtual bool handleLink(const QString &href) { Q_UNUSED(href); return false; }
|
virtual bool handleLink(const QString &href) { Q_UNUSED(href); return false; }
|
||||||
virtual bool hasFatalErrors() const { return false; }
|
virtual bool hasFatalErrors() const { return false; }
|
||||||
virtual void flush() {}
|
virtual void flush() {}
|
||||||
virtual void runPostPrintActions() {}
|
virtual void runPostPrintActions(QPlainTextEdit *) {}
|
||||||
|
|
||||||
void setRedirectionDetector(const OutputLineParser *detector);
|
void setRedirectionDetector(const OutputLineParser *detector);
|
||||||
bool needsRedirection() const;
|
bool needsRedirection() const;
|
||||||
|
@@ -42,6 +42,7 @@ QT_END_NAMESPACE
|
|||||||
namespace Core {
|
namespace Core {
|
||||||
class CommandButton;
|
class CommandButton;
|
||||||
class IContext;
|
class IContext;
|
||||||
|
class OutputWindow;
|
||||||
|
|
||||||
class CORE_EXPORT IOutputPane : public QObject
|
class CORE_EXPORT IOutputPane : public QObject
|
||||||
{
|
{
|
||||||
@@ -54,6 +55,7 @@ public:
|
|||||||
virtual QWidget *outputWidget(QWidget *parent) = 0;
|
virtual QWidget *outputWidget(QWidget *parent) = 0;
|
||||||
virtual QList<QWidget *> toolBarWidgets() const;
|
virtual QList<QWidget *> toolBarWidgets() const;
|
||||||
virtual QString displayName() const = 0;
|
virtual QString displayName() const = 0;
|
||||||
|
virtual const QList<OutputWindow *> outputWindows() const { return {}; }
|
||||||
|
|
||||||
virtual int priorityInStatusBar() const = 0;
|
virtual int priorityInStatusBar() const = 0;
|
||||||
|
|
||||||
|
@@ -39,7 +39,9 @@
|
|||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QCursor>
|
#include <QCursor>
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
|
#include <QHash>
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
|
#include <QPair>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
@@ -88,6 +90,7 @@ public:
|
|||||||
OutputWindow::FilterModeFlags filterMode = OutputWindow::FilterModeFlag::Default;
|
OutputWindow::FilterModeFlags filterMode = OutputWindow::FilterModeFlag::Default;
|
||||||
QTimer scrollTimer;
|
QTimer scrollTimer;
|
||||||
QElapsedTimer lastMessage;
|
QElapsedTimer lastMessage;
|
||||||
|
QHash<unsigned int, QPair<int, int>> taskPositions;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
@@ -491,6 +494,42 @@ void OutputWindow::appendMessage(const QString &output, OutputFormat format)
|
|||||||
d->queueTimer.start();
|
d->queueTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OutputWindow::registerPositionOf(unsigned taskId, int linkedOutputLines, int skipLines,
|
||||||
|
int offset)
|
||||||
|
{
|
||||||
|
if (linkedOutputLines <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const int blocknumber = document()->blockCount() - offset;
|
||||||
|
const int firstLine = blocknumber - linkedOutputLines - skipLines;
|
||||||
|
const int lastLine = firstLine + linkedOutputLines - 1;
|
||||||
|
|
||||||
|
d->taskPositions.insert(taskId, qMakePair(firstLine, lastLine));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OutputWindow::knowsPositionOf(unsigned taskId) const
|
||||||
|
{
|
||||||
|
return d->taskPositions.contains(taskId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutputWindow::showPositionOf(unsigned taskId)
|
||||||
|
{
|
||||||
|
QPair<int, int> position = d->taskPositions.value(taskId);
|
||||||
|
QTextCursor newCursor(document()->findBlockByNumber(position.second));
|
||||||
|
|
||||||
|
// Move cursor to end of last line of interest:
|
||||||
|
newCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::MoveAnchor);
|
||||||
|
setTextCursor(newCursor);
|
||||||
|
|
||||||
|
// Move cursor and select lines:
|
||||||
|
newCursor.setPosition(document()->findBlockByNumber(position.first).position(),
|
||||||
|
QTextCursor::KeepAnchor);
|
||||||
|
setTextCursor(newCursor);
|
||||||
|
|
||||||
|
// Center cursor now:
|
||||||
|
centerCursor();
|
||||||
|
}
|
||||||
|
|
||||||
QMimeData *OutputWindow::createMimeDataFromSelection() const
|
QMimeData *OutputWindow::createMimeDataFromSelection() const
|
||||||
{
|
{
|
||||||
const auto mimeData = new QMimeData;
|
const auto mimeData = new QMimeData;
|
||||||
@@ -522,6 +561,7 @@ void OutputWindow::clear()
|
|||||||
{
|
{
|
||||||
d->formatter.clear();
|
d->formatter.clear();
|
||||||
d->scrollToBottom = true;
|
d->scrollToBottom = true;
|
||||||
|
d->taskPositions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutputWindow::flush()
|
void OutputWindow::flush()
|
||||||
|
@@ -62,6 +62,10 @@ public:
|
|||||||
|
|
||||||
void appendMessage(const QString &out, Utils::OutputFormat format);
|
void appendMessage(const QString &out, Utils::OutputFormat format);
|
||||||
|
|
||||||
|
void registerPositionOf(unsigned taskId, int linkedOutputLines, int skipLines, int offset = 0);
|
||||||
|
bool knowsPositionOf(unsigned taskId) const;
|
||||||
|
void showPositionOf(unsigned taskId);
|
||||||
|
|
||||||
void grayOutOldContent();
|
void grayOutOldContent();
|
||||||
void clear();
|
void clear();
|
||||||
void flush();
|
void flush();
|
||||||
|
@@ -81,17 +81,6 @@ CompileOutputWindow::CompileOutputWindow(QAction *cancelBuildAction) :
|
|||||||
m_outputWindow->setUndoRedoEnabled(false);
|
m_outputWindow->setUndoRedoEnabled(false);
|
||||||
m_outputWindow->setMaxCharCount(Core::Constants::DEFAULT_MAX_CHAR_COUNT);
|
m_outputWindow->setMaxCharCount(Core::Constants::DEFAULT_MAX_CHAR_COUNT);
|
||||||
|
|
||||||
outputFormatter()->overridePostPrintAction([this](Utils::OutputLineParser *parser) {
|
|
||||||
if (const auto taskParser = qobject_cast<OutputTaskParser *>(parser)) {
|
|
||||||
int offset = 0;
|
|
||||||
Utils::reverseForeach(taskParser->taskInfo(), [this, &offset](const OutputTaskParser::TaskInfo &ti) {
|
|
||||||
registerPositionOf(ti.task, ti.linkedLines, ti.skippedLines, offset);
|
|
||||||
offset += ti.linkedLines;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
parser->runPostPrintActions();
|
|
||||||
});
|
|
||||||
|
|
||||||
Utils::ProxyAction *cancelBuildProxyButton =
|
Utils::ProxyAction *cancelBuildProxyButton =
|
||||||
Utils::ProxyAction::proxyActionWithIcon(cancelBuildAction,
|
Utils::ProxyAction::proxyActionWithIcon(cancelBuildAction,
|
||||||
Utils::Icons::STOP_SMALL_TOOLBAR.icon());
|
Utils::Icons::STOP_SMALL_TOOLBAR.icon());
|
||||||
@@ -198,7 +187,6 @@ void CompileOutputWindow::appendText(const QString &text, BuildStep::OutputForma
|
|||||||
void CompileOutputWindow::clearContents()
|
void CompileOutputWindow::clearContents()
|
||||||
{
|
{
|
||||||
m_outputWindow->clear();
|
m_outputWindow->clear();
|
||||||
m_taskPositions.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CompileOutputWindow::priorityInStatusBar() const
|
int CompileOutputWindow::priorityInStatusBar() const
|
||||||
@@ -230,37 +218,7 @@ bool CompileOutputWindow::canNavigate() const
|
|||||||
void CompileOutputWindow::registerPositionOf(const Task &task, int linkedOutputLines, int skipLines,
|
void CompileOutputWindow::registerPositionOf(const Task &task, int linkedOutputLines, int skipLines,
|
||||||
int offset)
|
int offset)
|
||||||
{
|
{
|
||||||
if (linkedOutputLines <= 0)
|
m_outputWindow->registerPositionOf(task.taskId, linkedOutputLines, skipLines, offset);
|
||||||
return;
|
|
||||||
|
|
||||||
const int blocknumber = m_outputWindow->document()->blockCount() - offset;
|
|
||||||
const int firstLine = blocknumber - linkedOutputLines - skipLines;
|
|
||||||
const int lastLine = firstLine + linkedOutputLines - 1;
|
|
||||||
|
|
||||||
m_taskPositions.insert(task.taskId, qMakePair(firstLine, lastLine));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CompileOutputWindow::knowsPositionOf(const Task &task)
|
|
||||||
{
|
|
||||||
return (m_taskPositions.contains(task.taskId));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CompileOutputWindow::showPositionOf(const Task &task)
|
|
||||||
{
|
|
||||||
QPair<int, int> position = m_taskPositions.value(task.taskId);
|
|
||||||
QTextCursor newCursor(m_outputWindow->document()->findBlockByNumber(position.second));
|
|
||||||
|
|
||||||
// Move cursor to end of last line of interest:
|
|
||||||
newCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::MoveAnchor);
|
|
||||||
m_outputWindow->setTextCursor(newCursor);
|
|
||||||
|
|
||||||
// Move cursor and select lines:
|
|
||||||
newCursor.setPosition(m_outputWindow->document()->findBlockByNumber(position.first).position(),
|
|
||||||
QTextCursor::KeepAnchor);
|
|
||||||
m_outputWindow->setTextCursor(newCursor);
|
|
||||||
|
|
||||||
// Center cursor now:
|
|
||||||
m_outputWindow->centerCursor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompileOutputWindow::flush()
|
void CompileOutputWindow::flush()
|
||||||
|
@@ -30,8 +30,6 @@
|
|||||||
#include <coreplugin/dialogs/ioptionspage.h>
|
#include <coreplugin/dialogs/ioptionspage.h>
|
||||||
#include <coreplugin/ioutputpane.h>
|
#include <coreplugin/ioutputpane.h>
|
||||||
|
|
||||||
#include <QHash>
|
|
||||||
#include <QPair>
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QToolButton;
|
class QToolButton;
|
||||||
@@ -73,8 +71,6 @@ public:
|
|||||||
void appendText(const QString &text, BuildStep::OutputFormat format);
|
void appendText(const QString &text, BuildStep::OutputFormat format);
|
||||||
|
|
||||||
void registerPositionOf(const Task &task, int linkedOutputLines, int skipLines, int offset = 0);
|
void registerPositionOf(const Task &task, int linkedOutputLines, int skipLines, int offset = 0);
|
||||||
bool knowsPositionOf(const Task &task);
|
|
||||||
void showPositionOf(const Task &task);
|
|
||||||
|
|
||||||
void flush();
|
void flush();
|
||||||
void reset();
|
void reset();
|
||||||
@@ -86,13 +82,13 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void updateFilter() override;
|
void updateFilter() override;
|
||||||
|
const QList<Core::OutputWindow *> outputWindows() const override { return {m_outputWindow}; }
|
||||||
|
|
||||||
void loadSettings();
|
void loadSettings();
|
||||||
void storeSettings() const;
|
void storeSettings() const;
|
||||||
void updateFromSettings();
|
void updateFromSettings();
|
||||||
|
|
||||||
Core::OutputWindow *m_outputWindow;
|
Core::OutputWindow *m_outputWindow;
|
||||||
QHash<unsigned int, QPair<int, int>> m_taskPositions;
|
|
||||||
ShowOutputTaskHandler *m_handler;
|
ShowOutputTaskHandler *m_handler;
|
||||||
QToolButton *m_cancelBuildButton;
|
QToolButton *m_cancelBuildButton;
|
||||||
QToolButton * const m_settingsButton;
|
QToolButton * const m_settingsButton;
|
||||||
|
@@ -28,10 +28,14 @@
|
|||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "taskhub.h"
|
#include "taskhub.h"
|
||||||
|
|
||||||
|
#include <coreplugin/outputwindow.h>
|
||||||
#include <texteditor/fontsettings.h>
|
#include <texteditor/fontsettings.h>
|
||||||
#include <texteditor/texteditorsettings.h>
|
#include <texteditor/texteditorsettings.h>
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/ansiescapecodehandler.h>
|
#include <utils/ansiescapecodehandler.h>
|
||||||
|
|
||||||
|
#include <QPlainTextEdit>
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class ProjectExplorer::OutputTaskParser
|
\class ProjectExplorer::OutputTaskParser
|
||||||
@@ -113,8 +117,16 @@ void OutputTaskParser::setDetailsFormat(Task &task, const LinkSpecs &linkSpecs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutputTaskParser::runPostPrintActions()
|
void OutputTaskParser::runPostPrintActions(QPlainTextEdit *edit)
|
||||||
{
|
{
|
||||||
|
int offset = 0;
|
||||||
|
if (const auto ow = qobject_cast<Core::OutputWindow *>(edit)) {
|
||||||
|
Utils::reverseForeach(taskInfo(), [this, ow, &offset](const TaskInfo &ti) {
|
||||||
|
ow->registerPositionOf(ti.task.taskId, ti.linkedLines, ti.skippedLines, offset);
|
||||||
|
offset += ti.linkedLines;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
for (const TaskInfo &t : qAsConst(d->scheduledTasks))
|
for (const TaskInfo &t : qAsConst(d->scheduledTasks))
|
||||||
TaskHub::addTask(t.task);
|
TaskHub::addTask(t.task);
|
||||||
d->scheduledTasks.clear();
|
d->scheduledTasks.clear();
|
||||||
|
@@ -57,7 +57,7 @@ protected:
|
|||||||
void setDetailsFormat(Task &task, const LinkSpecs &linkSpecs = {});
|
void setDetailsFormat(Task &task, const LinkSpecs &linkSpecs = {});
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void runPostPrintActions() override;
|
void runPostPrintActions(QPlainTextEdit *edit) override;
|
||||||
|
|
||||||
class Private;
|
class Private;
|
||||||
Private * const d;
|
Private * const d;
|
||||||
|
@@ -27,22 +27,25 @@
|
|||||||
|
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
#include "compileoutputwindow.h"
|
#include <coreplugin/ioutputpane.h>
|
||||||
|
#include <coreplugin/outputwindow.h>
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
ShowOutputTaskHandler::ShowOutputTaskHandler(CompileOutputWindow *window) :
|
ShowOutputTaskHandler::ShowOutputTaskHandler(Core::IOutputPane *window) : m_window(window)
|
||||||
m_window(window)
|
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_window);
|
Q_ASSERT(m_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShowOutputTaskHandler::canHandle(const Task &task) const
|
bool ShowOutputTaskHandler::canHandle(const Task &task) const
|
||||||
{
|
{
|
||||||
return m_window->knowsPositionOf(task);
|
return Utils::anyOf(m_window->outputWindows(), [task](const Core::OutputWindow *ow) {
|
||||||
|
return ow->knowsPositionOf(task.taskId);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowOutputTaskHandler::handle(const Task &task)
|
void ShowOutputTaskHandler::handle(const Task &task)
|
||||||
@@ -50,7 +53,12 @@ void ShowOutputTaskHandler::handle(const Task &task)
|
|||||||
Q_ASSERT(canHandle(task));
|
Q_ASSERT(canHandle(task));
|
||||||
// popup first as this does move the visible area!
|
// popup first as this does move the visible area!
|
||||||
m_window->popup(Core::IOutputPane::Flags(Core::IOutputPane::ModeSwitch | Core::IOutputPane::WithFocus));
|
m_window->popup(Core::IOutputPane::Flags(Core::IOutputPane::ModeSwitch | Core::IOutputPane::WithFocus));
|
||||||
m_window->showPositionOf(task);
|
for (Core::OutputWindow * const ow : m_window->outputWindows()) {
|
||||||
|
if (ow->knowsPositionOf(task.taskId)) {
|
||||||
|
ow->showPositionOf(task.taskId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QAction *ShowOutputTaskHandler::createAction(QObject *parent) const
|
QAction *ShowOutputTaskHandler::createAction(QObject *parent) const
|
||||||
|
@@ -27,24 +27,24 @@
|
|||||||
|
|
||||||
#include "itaskhandler.h"
|
#include "itaskhandler.h"
|
||||||
|
|
||||||
|
namespace Core { class IOutputPane; }
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class CompileOutputWindow;
|
|
||||||
|
|
||||||
class ShowOutputTaskHandler : public ITaskHandler
|
class ShowOutputTaskHandler : public ITaskHandler
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ShowOutputTaskHandler(CompileOutputWindow *window);
|
explicit ShowOutputTaskHandler(Core::IOutputPane *window);
|
||||||
|
|
||||||
bool canHandle(const Task &) const override;
|
bool canHandle(const Task &) const override;
|
||||||
void handle(const Task &task) override;
|
void handle(const Task &task) override;
|
||||||
QAction *createAction(QObject *parent) const override;
|
QAction *createAction(QObject *parent) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CompileOutputWindow *m_window;
|
Core::IOutputPane * const m_window;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
Reference in New Issue
Block a user