Core: Pimpl OutputWindow

Change-Id: Id19f3d0ffcc1b3c939d57c9cb2c5b0fa7be7203c
Reviewed-by: Nikita Baryshnikov <nib952051@gmail.com>
Reviewed-by: hjk <hjk@theqtcompany.com>
This commit is contained in:
Orgad Shaneh
2015-02-24 22:39:14 +02:00
committed by hjk
parent eeee955061
commit 169fe15940
3 changed files with 87 additions and 57 deletions

View File

@@ -34,6 +34,7 @@
#include "coreconstants.h" #include "coreconstants.h"
#include "icore.h" #include "icore.h"
#include <utils/outputformatter.h>
#include <utils/synchronousprocess.h> #include <utils/synchronousprocess.h>
#include <QAction> #include <QAction>
@@ -43,16 +44,45 @@ using namespace Utils;
namespace Core { namespace Core {
namespace Internal {
class OutputWindowPrivate
{
public:
OutputWindowPrivate()
: outputWindowContext(0)
, formatter(0)
, enforceNewline(false)
, scrollToBottom(false)
, linksActive(true)
, mousePressed(false)
, maxLineCount(100000)
{
}
~OutputWindowPrivate()
{
ICore::removeContextObject(outputWindowContext);
delete outputWindowContext;
}
IContext *outputWindowContext;
Utils::OutputFormatter *formatter;
bool enforceNewline;
bool scrollToBottom;
bool linksActive;
bool mousePressed;
int maxLineCount;
};
} // namespace Internal
/*******************/ /*******************/
OutputWindow::OutputWindow(Context context, QWidget *parent) OutputWindow::OutputWindow(Context context, QWidget *parent)
: QPlainTextEdit(parent) : QPlainTextEdit(parent)
, m_formatter(0) , d(new Internal::OutputWindowPrivate)
, m_enforceNewline(false)
, m_scrollToBottom(false)
, m_linksActive(true)
, m_mousePressed(false)
, m_maxLineCount(100000)
{ {
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
//setCenterOnScroll(false); //setCenterOnScroll(false);
@@ -60,10 +90,10 @@ OutputWindow::OutputWindow(Context context, QWidget *parent)
setMouseTracking(true); setMouseTracking(true);
setUndoRedoEnabled(false); setUndoRedoEnabled(false);
m_outputWindowContext = new IContext; d->outputWindowContext = new IContext;
m_outputWindowContext->setContext(context); d->outputWindowContext->setContext(context);
m_outputWindowContext->setWidget(this); d->outputWindowContext->setWidget(this);
ICore::addContextObject(m_outputWindowContext); ICore::addContextObject(d->outputWindowContext);
QAction *undoAction = new QAction(this); QAction *undoAction = new QAction(this);
QAction *redoAction = new QAction(this); QAction *redoAction = new QAction(this);
@@ -99,28 +129,27 @@ OutputWindow::OutputWindow(Context context, QWidget *parent)
OutputWindow::~OutputWindow() OutputWindow::~OutputWindow()
{ {
ICore::removeContextObject(m_outputWindowContext); delete d;
delete m_outputWindowContext;
} }
void OutputWindow::mousePressEvent(QMouseEvent * e) void OutputWindow::mousePressEvent(QMouseEvent * e)
{ {
m_mousePressed = true; d->mousePressed = true;
QPlainTextEdit::mousePressEvent(e); QPlainTextEdit::mousePressEvent(e);
} }
void OutputWindow::mouseReleaseEvent(QMouseEvent *e) void OutputWindow::mouseReleaseEvent(QMouseEvent *e)
{ {
m_mousePressed = false; d->mousePressed = false;
if (m_linksActive) { if (d->linksActive) {
const QString href = anchorAt(e->pos()); const QString href = anchorAt(e->pos());
if (m_formatter) if (d->formatter)
m_formatter->handleLink(href); d->formatter->handleLink(href);
} }
// Mouse was released, activate links again // Mouse was released, activate links again
m_linksActive = true; d->linksActive = true;
QPlainTextEdit::mouseReleaseEvent(e); QPlainTextEdit::mouseReleaseEvent(e);
} }
@@ -128,10 +157,10 @@ void OutputWindow::mouseReleaseEvent(QMouseEvent *e)
void OutputWindow::mouseMoveEvent(QMouseEvent *e) void OutputWindow::mouseMoveEvent(QMouseEvent *e)
{ {
// Cursor was dragged to make a selection, deactivate links // Cursor was dragged to make a selection, deactivate links
if (m_mousePressed && textCursor().hasSelection()) if (d->mousePressed && textCursor().hasSelection())
m_linksActive = false; d->linksActive = false;
if (!m_linksActive || anchorAt(e->pos()).isEmpty()) if (!d->linksActive || anchorAt(e->pos()).isEmpty())
viewport()->setCursor(Qt::IBeamCursor); viewport()->setCursor(Qt::IBeamCursor);
else else
viewport()->setCursor(Qt::PointingHandCursor); viewport()->setCursor(Qt::PointingHandCursor);
@@ -161,34 +190,34 @@ void OutputWindow::keyPressEvent(QKeyEvent *ev)
OutputFormatter *OutputWindow::formatter() const OutputFormatter *OutputWindow::formatter() const
{ {
return m_formatter; return d->formatter;
} }
void OutputWindow::setFormatter(OutputFormatter *formatter) void OutputWindow::setFormatter(OutputFormatter *formatter)
{ {
m_formatter = formatter; d->formatter = formatter;
m_formatter->setPlainTextEdit(this); d->formatter->setPlainTextEdit(this);
} }
void OutputWindow::showEvent(QShowEvent *e) void OutputWindow::showEvent(QShowEvent *e)
{ {
QPlainTextEdit::showEvent(e); QPlainTextEdit::showEvent(e);
if (m_scrollToBottom) if (d->scrollToBottom)
verticalScrollBar()->setValue(verticalScrollBar()->maximum()); verticalScrollBar()->setValue(verticalScrollBar()->maximum());
m_scrollToBottom = false; d->scrollToBottom = false;
} }
QString OutputWindow::doNewlineEnforcement(const QString &out) QString OutputWindow::doNewlineEnforcement(const QString &out)
{ {
m_scrollToBottom = true; d->scrollToBottom = true;
QString s = out; QString s = out;
if (m_enforceNewline) { if (d->enforceNewline) {
s.prepend(QLatin1Char('\n')); s.prepend(QLatin1Char('\n'));
m_enforceNewline = false; d->enforceNewline = false;
} }
if (s.endsWith(QLatin1Char('\n'))) { if (s.endsWith(QLatin1Char('\n'))) {
m_enforceNewline = true; // make appendOutputInline put in a newline next time d->enforceNewline = true; // make appendOutputInline put in a newline next time
s.chop(1); s.chop(1);
} }
@@ -197,19 +226,24 @@ QString OutputWindow::doNewlineEnforcement(const QString &out)
void OutputWindow::setMaxLineCount(int count) void OutputWindow::setMaxLineCount(int count)
{ {
m_maxLineCount = count; d->maxLineCount = count;
setMaximumBlockCount(m_maxLineCount); setMaximumBlockCount(d->maxLineCount);
}
int OutputWindow::maxLineCount() const
{
return d->maxLineCount;
} }
void OutputWindow::appendMessage(const QString &output, OutputFormat format) void OutputWindow::appendMessage(const QString &output, OutputFormat format)
{ {
const QString out = SynchronousProcess::normalizeNewlines(output); const QString out = SynchronousProcess::normalizeNewlines(output);
setMaximumBlockCount(m_maxLineCount); setMaximumBlockCount(d->maxLineCount);
const bool atBottom = isScrollbarAtBottom(); const bool atBottom = isScrollbarAtBottom();
if (format == ErrorMessageFormat || format == NormalMessageFormat) { if (format == ErrorMessageFormat || format == NormalMessageFormat) {
m_formatter->appendMessage(doNewlineEnforcement(out), format); d->formatter->appendMessage(doNewlineEnforcement(out), format);
} else { } else {
@@ -217,31 +251,31 @@ void OutputWindow::appendMessage(const QString &output, OutputFormat format)
|| format == StdErrFormatSameLine; || format == StdErrFormatSameLine;
if (sameLine) { if (sameLine) {
m_scrollToBottom = true; d->scrollToBottom = true;
int newline = -1; int newline = -1;
bool enforceNewline = m_enforceNewline; bool enforceNewline = d->enforceNewline;
m_enforceNewline = false; d->enforceNewline = false;
if (!enforceNewline) { if (!enforceNewline) {
newline = out.indexOf(QLatin1Char('\n')); newline = out.indexOf(QLatin1Char('\n'));
moveCursor(QTextCursor::End); moveCursor(QTextCursor::End);
if (newline != -1) if (newline != -1)
m_formatter->appendMessage(out.left(newline), format);// doesn't enforce new paragraph like appendPlainText d->formatter->appendMessage(out.left(newline), format);// doesn't enforce new paragraph like appendPlainText
} }
QString s = out.mid(newline+1); QString s = out.mid(newline+1);
if (s.isEmpty()) { if (s.isEmpty()) {
m_enforceNewline = true; d->enforceNewline = true;
} else { } else {
if (s.endsWith(QLatin1Char('\n'))) { if (s.endsWith(QLatin1Char('\n'))) {
m_enforceNewline = true; d->enforceNewline = true;
s.chop(1); s.chop(1);
} }
m_formatter->appendMessage(QLatin1Char('\n') + s, format); d->formatter->appendMessage(QLatin1Char('\n') + s, format);
} }
} else { } else {
m_formatter->appendMessage(doNewlineEnforcement(out), format); d->formatter->appendMessage(doNewlineEnforcement(out), format);
} }
} }
@@ -254,7 +288,7 @@ void OutputWindow::appendMessage(const QString &output, OutputFormat format)
void OutputWindow::appendText(const QString &textIn, const QTextCharFormat &format) void OutputWindow::appendText(const QString &textIn, const QTextCharFormat &format)
{ {
const QString text = SynchronousProcess::normalizeNewlines(textIn); const QString text = SynchronousProcess::normalizeNewlines(textIn);
if (m_maxLineCount > 0 && document()->blockCount() >= m_maxLineCount) if (d->maxLineCount > 0 && document()->blockCount() >= d->maxLineCount)
return; return;
const bool atBottom = isScrollbarAtBottom(); const bool atBottom = isScrollbarAtBottom();
QTextCursor cursor = QTextCursor(document()); QTextCursor cursor = QTextCursor(document());
@@ -262,7 +296,7 @@ void OutputWindow::appendText(const QString &textIn, const QTextCharFormat &form
cursor.beginEditBlock(); cursor.beginEditBlock();
cursor.insertText(doNewlineEnforcement(text), format); cursor.insertText(doNewlineEnforcement(text), format);
if (m_maxLineCount > 0 && document()->blockCount() >= m_maxLineCount) { if (d->maxLineCount > 0 && document()->blockCount() >= d->maxLineCount) {
QTextCharFormat tmp; QTextCharFormat tmp;
tmp.setFontWeight(QFont::Bold); tmp.setFontWeight(QFont::Bold);
cursor.insertText(doNewlineEnforcement(tr("Additional output omitted") + QLatin1Char('\n')), tmp); cursor.insertText(doNewlineEnforcement(tr("Additional output omitted") + QLatin1Char('\n')), tmp);
@@ -280,7 +314,7 @@ bool OutputWindow::isScrollbarAtBottom() const
void OutputWindow::clear() void OutputWindow::clear()
{ {
m_enforceNewline = false; d->enforceNewline = false;
QPlainTextEdit::clear(); QPlainTextEdit::clear();
} }

View File

@@ -34,13 +34,15 @@
#include "core_global.h" #include "core_global.h"
#include "icontext.h" #include "icontext.h"
#include <utils/outputformatter.h> #include <utils/outputformat.h>
#include <QPlainTextEdit> #include <QPlainTextEdit>
namespace Utils { class OutputFormatter; }
namespace Core { namespace Core {
class IContext; namespace Internal { class OutputWindowPrivate; }
class CORE_EXPORT OutputWindow : public QPlainTextEdit class CORE_EXPORT OutputWindow : public QPlainTextEdit
{ {
@@ -65,7 +67,7 @@ public:
void scrollToBottom(); void scrollToBottom();
void setMaxLineCount(int count); void setMaxLineCount(int count);
int maxLineCount() const { return m_maxLineCount; } int maxLineCount() const;
public slots: public slots:
void setWordWrapEnabled(bool wrap); void setWordWrapEnabled(bool wrap);
@@ -83,14 +85,7 @@ private:
void enableUndoRedo(); void enableUndoRedo();
QString doNewlineEnforcement(const QString &out); QString doNewlineEnforcement(const QString &out);
IContext *m_outputWindowContext; Internal::OutputWindowPrivate *d;
Utils::OutputFormatter *m_formatter;
bool m_enforceNewline;
bool m_scrollToBottom;
bool m_linksActive;
bool m_mousePressed;
int m_maxLineCount;
}; };
} // namespace Core } // namespace Core

View File

@@ -44,8 +44,9 @@
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <extensionsystem/invoker.h> #include <extensionsystem/invoker.h>
#include <utils/qtcassert.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/outputformatter.h>
#include <utils/qtcassert.h>
#include <QAction> #include <QAction>
#include <QVBoxLayout> #include <QVBoxLayout>