summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAurindam Jana <aurindam.jana@nokia.com>2012-02-08 15:54:59 +0100
committerAurindam Jana <aurindam.jana@nokia.com>2012-02-16 14:13:21 +0100
commitba412ee505cc357d32bcee26e3562329b727807b (patch)
treea529da42ba4f25b46ce6a83ececf34dfe16e425d /src
parentbb4f25b74871384eeab86ff42a3d6e230deb52b8 (diff)
downloadqt-creator-ba412ee505cc357d32bcee26e3562329b727807b.tar.gz
ScriptConsole: Use QTreeView
Use QTreeView instead of modified QPlainTextEdit to show the console. Using a QTreeView gives more control over output display as well as separates out the model from the view. Change-Id: I436b13ed042c00d09d6de627b442bfd8d10d2236 Reviewed-by: Kai Koehne <kai.koehne@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/debugger/debugger.qrc6
-rw-r--r--src/plugins/debugger/images/collapse.pngbin0 -> 986 bytes
-rw-r--r--src/plugins/debugger/images/error.pngbin0 -> 1344 bytes
-rw-r--r--src/plugins/debugger/images/expand.pngbin0 -> 997 bytes
-rw-r--r--src/plugins/debugger/images/log.pngbin0 -> 1354 bytes
-rw-r--r--src/plugins/debugger/images/prompt.pngbin0 -> 1049 bytes
-rw-r--r--src/plugins/debugger/images/warning.pngbin0 -> 1454 bytes
-rw-r--r--src/plugins/debugger/qml/consolebackend.cpp179
-rw-r--r--src/plugins/debugger/qml/consolebackend.h100
-rw-r--r--src/plugins/debugger/qml/consoleeditor.cpp278
-rw-r--r--src/plugins/debugger/qml/consoleeditor.h81
-rw-r--r--src/plugins/debugger/qml/consoleitemdelegate.cpp321
-rw-r--r--src/plugins/debugger/qml/consoleitemdelegate.h174
-rw-r--r--src/plugins/debugger/qml/consoleitemmodel.cpp348
-rw-r--r--src/plugins/debugger/qml/consoleitemmodel.h94
-rw-r--r--src/plugins/debugger/qml/consoletreeview.cpp157
-rw-r--r--src/plugins/debugger/qml/consoletreeview.h59
-rw-r--r--src/plugins/debugger/qml/qml.pri14
-rw-r--r--src/plugins/debugger/qml/qmljsscriptconsole.cpp704
-rw-r--r--src/plugins/debugger/qml/qmljsscriptconsole.h101
20 files changed, 2004 insertions, 612 deletions
diff --git a/src/plugins/debugger/debugger.qrc b/src/plugins/debugger/debugger.qrc
index 0f7ebee1ab..e1bf571107 100644
--- a/src/plugins/debugger/debugger.qrc
+++ b/src/plugins/debugger/debugger.qrc
@@ -30,5 +30,11 @@
<file>images/location_16.png</file>
<file>images/location_24.png</file>
<file>images/pin.xpm</file>
+ <file>images/collapse.png</file>
+ <file>images/error.png</file>
+ <file>images/expand.png</file>
+ <file>images/log.png</file>
+ <file>images/prompt.png</file>
+ <file>images/warning.png</file>
</qresource>
</RCC>
diff --git a/src/plugins/debugger/images/collapse.png b/src/plugins/debugger/images/collapse.png
new file mode 100644
index 0000000000..64ae3720c1
--- /dev/null
+++ b/src/plugins/debugger/images/collapse.png
Binary files differ
diff --git a/src/plugins/debugger/images/error.png b/src/plugins/debugger/images/error.png
new file mode 100644
index 0000000000..39768b9f39
--- /dev/null
+++ b/src/plugins/debugger/images/error.png
Binary files differ
diff --git a/src/plugins/debugger/images/expand.png b/src/plugins/debugger/images/expand.png
new file mode 100644
index 0000000000..7959bfc97e
--- /dev/null
+++ b/src/plugins/debugger/images/expand.png
Binary files differ
diff --git a/src/plugins/debugger/images/log.png b/src/plugins/debugger/images/log.png
new file mode 100644
index 0000000000..e4766f228b
--- /dev/null
+++ b/src/plugins/debugger/images/log.png
Binary files differ
diff --git a/src/plugins/debugger/images/prompt.png b/src/plugins/debugger/images/prompt.png
new file mode 100644
index 0000000000..a333a87198
--- /dev/null
+++ b/src/plugins/debugger/images/prompt.png
Binary files differ
diff --git a/src/plugins/debugger/images/warning.png b/src/plugins/debugger/images/warning.png
new file mode 100644
index 0000000000..3200efc4fd
--- /dev/null
+++ b/src/plugins/debugger/images/warning.png
Binary files differ
diff --git a/src/plugins/debugger/qml/consolebackend.cpp b/src/plugins/debugger/qml/consolebackend.cpp
new file mode 100644
index 0000000000..0ffca2ad05
--- /dev/null
+++ b/src/plugins/debugger/qml/consolebackend.cpp
@@ -0,0 +1,179 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@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 qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "consolebackend.h"
+#include "qmlengine.h"
+#include "qmladapter.h"
+
+#include "debuggerstringutils.h"
+
+#include <utils/qtcassert.h>
+
+namespace Debugger {
+namespace Internal {
+
+///////////////////////////////////////////////////////////////////////
+//
+// ConsoleBackend
+//
+///////////////////////////////////////////////////////////////////////
+
+ConsoleBackend::ConsoleBackend(QObject *parent) :
+ QObject(parent)
+{
+}
+
+///////////////////////////////////////////////////////////////////////
+//
+// QmlJSConsoleBackend
+//
+///////////////////////////////////////////////////////////////////////
+
+QmlJSConsoleBackend::QmlJSConsoleBackend(QObject *parent) :
+ ConsoleBackend(parent),
+ m_engine(0),
+ m_inferiorStopped(false),
+ m_isValidContext(false),
+ m_Error(false)
+{
+}
+
+void QmlJSConsoleBackend::setInferiorStopped(bool isInferiorStopped)
+{
+ m_inferiorStopped = isInferiorStopped;
+}
+
+bool QmlJSConsoleBackend::inferiorStopped() const
+{
+ return m_inferiorStopped;
+}
+
+void QmlJSConsoleBackend::setEngine(QmlEngine *engine)
+{
+ m_engine = engine;
+}
+
+QmlEngine *QmlJSConsoleBackend::engine() const
+{
+ return m_engine;
+}
+
+void QmlJSConsoleBackend::setIsValidContext(bool isValidContext)
+{
+ m_isValidContext = isValidContext;
+}
+
+bool QmlJSConsoleBackend::isValidContext() const
+{
+ return m_isValidContext;
+}
+
+void QmlJSConsoleBackend::onDebugQueryStateChanged(
+ QmlJsDebugClient::QDeclarativeDebugQuery::State state)
+{
+ QmlJsDebugClient::QDeclarativeDebugExpressionQuery *query =
+ qobject_cast<QmlJsDebugClient::QDeclarativeDebugExpressionQuery *>(
+ sender());
+ if (query && state != QmlJsDebugClient::QDeclarativeDebugQuery::Error)
+ emit message(ConsoleItemModel::UndefinedType,
+ query->result().toString());
+ else
+ emit message(ConsoleItemModel::ErrorType,
+ _("Error evaluating expression."));
+ delete query;
+}
+
+void QmlJSConsoleBackend::evaluate(const QString &script,
+ bool *returnKeyConsumed)
+{
+ *returnKeyConsumed = true;
+ m_Error = false;
+ //Check if string is only white spaces
+ if (!script.trimmed().isEmpty()) {
+ //Check for a valid context
+ if (m_isValidContext) {
+ //check if it can be evaluated
+ if (canEvaluateScript(script)) {
+ //Evaluate expression based on engine state
+ //When engine->state() == InferiorStopOk, the expression
+ //is sent to V8DebugService. In all other cases, the
+ //expression is evaluated by QDeclarativeEngine.
+ if (!m_inferiorStopped) {
+ QmlAdapter *adapter = m_engine->adapter();
+ QTC_ASSERT(adapter, return);
+ QDeclarativeEngineDebug *engineDebug =
+ adapter->engineDebugClient();
+
+ int id = adapter->currentSelectedDebugId();
+ if (engineDebug && id != -1) {
+ QDeclarativeDebugExpressionQuery *query =
+ engineDebug->queryExpressionResult(id, script);
+ connect(query,
+ SIGNAL(stateChanged(
+ QmlJsDebugClient::QDeclarativeDebugQuery
+ ::State)),
+ this,
+ SLOT(onDebugQueryStateChanged(
+ QmlJsDebugClient::QDeclarativeDebugQuery
+ ::State)));
+ }
+ } else {
+ emit evaluateExpression(script);
+ }
+ } else {
+ *returnKeyConsumed = false;
+ }
+ } else {
+ //Incase of invalid context, append the expression to history
+ //and show Error message
+ m_Error = true;
+ }
+ }
+}
+
+void QmlJSConsoleBackend::emitErrorMessage()
+{
+ if (m_Error)
+ emit message(
+ ConsoleItemModel::ErrorType,
+ _("Cannot evaluate without a valid QML/JS Context"));
+}
+
+bool QmlJSConsoleBackend::canEvaluateScript(const QString &script)
+{
+ m_interpreter.clearText();
+ m_interpreter.appendText(script);
+ return m_interpreter.canEvaluate();
+}
+
+}
+}
diff --git a/src/plugins/debugger/qml/consolebackend.h b/src/plugins/debugger/qml/consolebackend.h
new file mode 100644
index 0000000000..dd24b427df
--- /dev/null
+++ b/src/plugins/debugger/qml/consolebackend.h
@@ -0,0 +1,100 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@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 qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef CONSOLEBACKEND_H
+#define CONSOLEBACKEND_H
+
+#include "consoleitemmodel.h"
+#include "interactiveinterpreter.h"
+
+#include <qmljsdebugclient/qdeclarativeenginedebug.h>
+
+#include <QtCore/QObject>
+
+namespace Debugger {
+namespace Internal {
+
+class ConsoleBackend : public QObject
+{
+ Q_OBJECT
+public:
+ explicit ConsoleBackend(QObject *parent = 0);
+
+ virtual void emitErrorMessage() = 0;
+
+ virtual void evaluate(const QString &, bool *returnKeyConsumed) = 0;
+
+signals:
+ void message(ConsoleItemModel::ItemType itemType, const QString &msg);
+};
+
+class QmlEngine;
+class QmlJSConsoleBackend : public ConsoleBackend
+{
+ Q_OBJECT
+public:
+ explicit QmlJSConsoleBackend(QObject *parent = 0);
+
+ void setInferiorStopped(bool inferiorStopped);
+ bool inferiorStopped() const;
+
+ void setEngine(QmlEngine *engine);
+ QmlEngine *engine() const;
+
+ void setIsValidContext(bool isValidContext);
+ bool isValidContext() const;
+
+ virtual void evaluate(const QString &, bool *returnKeyConsumed);
+ void emitErrorMessage();
+
+private slots:
+ void onDebugQueryStateChanged(
+ QmlJsDebugClient::QDeclarativeDebugQuery::State state);
+
+signals:
+ void evaluateExpression(const QString &);
+
+private:
+ bool canEvaluateScript(const QString &script);
+
+private:
+ QmlEngine *m_engine;
+ InteractiveInterpreter m_interpreter;
+ bool m_inferiorStopped;
+ bool m_isValidContext;
+ bool m_Error;
+};
+
+} //Internal
+} //Debugger
+
+#endif // CONSOLEBACKEND_H
diff --git a/src/plugins/debugger/qml/consoleeditor.cpp b/src/plugins/debugger/qml/consoleeditor.cpp
new file mode 100644
index 0000000000..cd655b621e
--- /dev/null
+++ b/src/plugins/debugger/qml/consoleeditor.cpp
@@ -0,0 +1,278 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@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 qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "consoleeditor.h"
+#include "consoleitemmodel.h"
+#include "consoleitemdelegate.h"
+#include "consolebackend.h"
+
+#include "debuggerstringutils.h"
+
+#include <utils/qtcassert.h>
+
+#include <QtGui/QMenu>
+#include <QtGui/QKeyEvent>
+
+namespace Debugger {
+namespace Internal {
+
+///////////////////////////////////////////////////////////////////////
+//
+// ConsoleEditor
+//
+///////////////////////////////////////////////////////////////////////
+
+ConsoleEditor::ConsoleEditor(const QModelIndex &index,
+ ConsoleBackend *backend,
+ QWidget *parent) :
+ QTextEdit(parent),
+ m_consoleBackend(backend),
+ m_historyIndex(index),
+ m_prompt(QLatin1String(":/debugger/images/prompt.png")),
+ m_startOfEditableArea(0)
+{
+ setFrameStyle(QFrame::NoFrame);
+ setUndoRedoEnabled(false);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ document()->addResource(QTextDocument::ImageResource,
+ QUrl(QLatin1String("prompt")), m_prompt);
+ QTextImageFormat format;
+ format.setName(QLatin1String("prompt"));
+ format.setHeight(9);
+ format.setWidth(9);
+ textCursor().insertImage(format);
+ textCursor().insertText(QLatin1String(" "));
+ m_startOfEditableArea = textCursor().position();
+
+ ensureCursorVisible();
+ setTextInteractionFlags(Qt::TextEditorInteraction);
+}
+
+void ConsoleEditor::keyPressEvent(QKeyEvent *e)
+{
+ bool keyConsumed = false;
+
+ switch (e->key()) {
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ if (m_consoleBackend) {
+ m_consoleBackend->evaluate(getCurrentScript(), &keyConsumed);
+ if (keyConsumed) {
+ emit editingFinished();
+ emit appendEditableRow();
+ //emit error message if there is an error
+ m_consoleBackend->emitErrorMessage();
+ }
+ } else {
+ emit editingFinished();
+ emit appendEditableRow();
+ keyConsumed = true;
+ }
+ break;
+
+ case Qt::Key_Backspace:
+ if (textCursor().selectionStart() <= m_startOfEditableArea)
+ keyConsumed = true;
+ break;
+
+ case Qt::Key_Delete:
+ if (textCursor().selectionStart() < m_startOfEditableArea)
+ keyConsumed = true;
+ break;
+
+ case Qt::Key_Home:
+ {
+ QTextCursor c(textCursor());
+ c.setPosition(m_startOfEditableArea);
+ setTextCursor(c);
+ keyConsumed = true;
+ }
+ break;
+
+ case Qt::Key_Up:
+ handleUpKey();
+ keyConsumed = true;
+ break;
+
+ case Qt::Key_Down:
+ handleDownKey();
+ keyConsumed = true;
+ break;
+
+ // Ctrl+Left: Moves the cursor one word to the left.
+ // Left: Moves the cursor one character to the left.
+ case Qt::Key_Left:
+ if (textCursor().position() <= m_startOfEditableArea
+ || e->modifiers() & Qt::ControlModifier) {
+ QTextCursor c(textCursor());
+ c.setPosition(m_startOfEditableArea);
+ setTextCursor(c);
+ keyConsumed = true;
+ }
+ break;
+
+ // Ctrl+Right: Moves the cursor one word to the right.
+ // Right: Moves the cursor one character to the right.
+ case Qt::Key_Right:
+ if ( !(e->modifiers() & Qt::ControlModifier)
+ && textCursor().position() <= m_startOfEditableArea) {
+ QTextCursor c(textCursor());
+ c.setPosition(m_startOfEditableArea);
+ setTextCursor(c);
+ keyConsumed = true;
+ }
+ break;
+
+ // Ctrl+C, Ctrl+Insert: Allow to Copy the selected text to the clipboard.
+ case Qt::Key_C:
+ case Qt::Key_Insert:
+ if (textCursor().selectionStart() < m_startOfEditableArea &&
+ !(e->modifiers() & Qt::ControlModifier))
+ keyConsumed = true;
+ break;
+
+ default:
+ // Disallow any other keys in the prompt area
+ if (textCursor().selectionStart() < m_startOfEditableArea)
+ keyConsumed = true;
+ break;
+ }
+
+ if (!keyConsumed)
+ QTextEdit::keyPressEvent(e);
+}
+
+void ConsoleEditor::contextMenuEvent(QContextMenuEvent *event)
+{
+ QTextCursor cursor = textCursor();
+ bool editable = cursor.position() > m_startOfEditableArea;
+ QMenu *menu = new QMenu();
+ QAction *a;
+
+ a = menu->addAction(tr("Cu&t"), this, SLOT(cut()));
+ a->setEnabled(cursor.hasSelection() && editable);
+
+ a = menu->addAction(tr("&Copy"), this, SLOT(copy()));
+ a->setEnabled(cursor.hasSelection());
+
+ a = menu->addAction(tr("&Paste"), this, SLOT(paste()));
+ a->setEnabled(canPaste() && editable);
+
+ menu->addSeparator();
+ a = menu->addAction(tr("Select &All"), this, SLOT(selectAll()));
+ a->setEnabled(!document()->isEmpty());
+
+ menu->addSeparator();
+ menu->addAction(tr("C&lear"), this, SLOT(clear()));
+
+ menu->exec(event->globalPos());
+
+ delete menu;
+}
+
+void ConsoleEditor::focusOutEvent(QFocusEvent * /*e*/)
+{
+ emit editingFinished();
+}
+
+void ConsoleEditor::handleUpKey()
+{
+ QTC_ASSERT(m_historyIndex.isValid(), return);
+ int currentRow = m_historyIndex.row();
+ const QAbstractItemModel *model = m_historyIndex.model();
+ if (currentRow == model->rowCount() - 1)
+ m_cachedScript = getCurrentScript();
+
+ while (currentRow) {
+ currentRow--;
+ if (model->hasIndex(currentRow, 0)) {
+ QModelIndex index = model->index(currentRow, 0);
+ if (ConsoleItemModel::InputType ==
+ (ConsoleItemModel::ItemType)model->data(
+ index, ConsoleItemModel::TypeRole).toInt()) {
+ m_historyIndex = index;
+ replaceCurrentScript(model->data(
+ index, Qt::DisplayRole).
+ toString());
+ break;
+ }
+ }
+ }
+}
+
+void ConsoleEditor::handleDownKey()
+{
+ QTC_ASSERT(m_historyIndex.isValid(), return);
+ int currentRow = m_historyIndex.row();
+ const QAbstractItemModel *model = m_historyIndex.model();
+ while (currentRow < model->rowCount() - 1) {
+ currentRow++;
+ if (model->hasIndex(currentRow, 0)) {
+ QModelIndex index = model->index(currentRow, 0);
+ if (ConsoleItemModel::InputType ==
+ (ConsoleItemModel::ItemType)model->data(
+ index, ConsoleItemModel::TypeRole).toInt()) {
+ m_historyIndex = index;
+ if (currentRow == model->rowCount() - 1)
+ replaceCurrentScript(m_cachedScript);
+ else
+ replaceCurrentScript(model->data(
+ index, Qt::DisplayRole).
+ toString());
+ break;
+ }
+ }
+ }
+}
+
+QString ConsoleEditor::getCurrentScript() const
+{
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(m_startOfEditableArea);
+ cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
+ QString script = cursor.selectedText();
+ //remove WS
+ return script.trimmed();
+}
+
+void ConsoleEditor::replaceCurrentScript(const QString &script)
+{
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(m_startOfEditableArea);
+ cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
+ cursor.removeSelectedText();
+ cursor.insertText(script);
+ setTextCursor(cursor);
+}
+
+} //Internal
+} //Debugger
diff --git a/src/plugins/debugger/qml/consoleeditor.h b/src/plugins/debugger/qml/consoleeditor.h
new file mode 100644
index 0000000000..6cdad218ec
--- /dev/null
+++ b/src/plugins/debugger/qml/consoleeditor.h
@@ -0,0 +1,81 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@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 qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef CONSOLEEDITOR_H
+#define CONSOLEEDITOR_H
+
+#include "consoleitemmodel.h"
+
+#include <QtGui/QTextEdit>
+#include <QtCore/QModelIndex>
+
+namespace Debugger {
+namespace Internal {
+
+class ConsoleBackend;
+class ConsoleEditor : public QTextEdit
+{
+ Q_OBJECT
+public:
+ explicit ConsoleEditor(const QModelIndex &index,
+ ConsoleBackend *backend = 0,
+ QWidget *parent = 0);
+
+ QString getCurrentScript() const;
+
+protected:
+ void keyPressEvent(QKeyEvent *e);
+ void contextMenuEvent(QContextMenuEvent *event);
+ void focusOutEvent(QFocusEvent *e);
+
+signals:
+ void editingFinished();
+ void appendEditableRow();
+
+protected:
+ void handleUpKey();
+ void handleDownKey();
+
+ void replaceCurrentScript(const QString &script);
+
+private:
+ ConsoleBackend *m_consoleBackend;
+ QModelIndex m_historyIndex;
+ QString m_cachedScript;
+ QImage m_prompt;
+ int m_startOfEditableArea;
+};
+
+} //Internal
+} //Debugger
+
+#endif // CONSOLEEDITOR_H
diff --git a/src/plugins/debugger/qml/consoleitemdelegate.cpp b/src/plugins/debugger/qml/consoleitemdelegate.cpp
new file mode 100644
index 0000000000..c6a0fe3fa4
--- /dev/null
+++ b/src/plugins/debugger/qml/consoleitemdelegate.cpp
@@ -0,0 +1,321 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@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 qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "consoleitemdelegate.h"
+#include "consoleeditor.h"
+#include "qmlengine.h"
+
+#include <QtGui/QPainter>
+#include <QtGui/QTreeView>
+
+const char CONSOLE_LOG_BACKGROUND_COLOR[] = "#2378B7";
+const char CONSOLE_WARNING_BACKGROUND_COLOR[] = "#E6CD49";
+const char CONSOLE_ERROR_BACKGROUND_COLOR[] = "#ED471A";
+const char CONSOLE_EDITOR_BACKGROUND_COLOR[] = "#F7F7F7";
+
+const char CONSOLE_LOG_TEXT_COLOR[] = "#333333";
+const char CONSOLE_WARNING_TEXT_COLOR[] = "#666666";
+const char CONSOLE_ERROR_TEXT_COLOR[] = "#1D5B93";
+const char CONSOLE_EDITOR_TEXT_COLOR[] = "#000000";
+
+const char CONSOLE_BORDER_COLOR[] = "#DEDEDE";
+const float CONSOLE_ALPHA = 0.7f;
+
+namespace Debugger {
+namespace Internal {
+
+///////////////////////////////////////////////////////////////////////
+//
+// ConsoleItemDelegate
+//
+///////////////////////////////////////////////////////////////////////
+
+ConsoleItemDelegate::ConsoleItemDelegate(QObject *parent) :
+ QStyledItemDelegate(parent),
+ m_logIcon(QLatin1String(":/debugger/images/log.png")),
+ m_warningIcon(QLatin1String(":/debugger/images/warning.png")),
+ m_errorIcon(QLatin1String(":/debugger/images/error.png")),
+ m_expandIcon(QLatin1String(":/debugger/images/expand.png")),
+ m_collapseIcon(QLatin1String(":/debugger/images/collapse.png")),
+ m_prompt(QLatin1String(":/debugger/images/prompt.png")),
+ m_consoleBackend(0)
+{
+}
+
+void ConsoleItemDelegate::emitSizeHintChanged(const QModelIndex &index)
+{
+ emit sizeHintChanged(index);
+}
+
+void ConsoleItemDelegate::setConsoleBackend(ConsoleBackend *consoleBackend)
+{
+ m_consoleBackend = consoleBackend;
+}
+
+void ConsoleItemDelegate::drawBackground(QPainter *painter, const QRect &rect,
+ ConsoleItemModel::ItemType itemType,
+ bool selected) const
+{
+ QColor backgroundColor;
+ switch (itemType) {
+ case ConsoleItemModel::LogType:
+ backgroundColor = QColor(CONSOLE_LOG_BACKGROUND_COLOR);
+ break;
+ case ConsoleItemModel::WarningType:
+ backgroundColor = QColor(CONSOLE_WARNING_BACKGROUND_COLOR);
+ break;
+ case ConsoleItemModel::ErrorType:
+ backgroundColor = QColor(CONSOLE_ERROR_BACKGROUND_COLOR);
+ break;
+ case ConsoleItemModel::InputType:
+ backgroundColor = QColor(CONSOLE_EDITOR_BACKGROUND_COLOR);
+ break;
+ default:
+ backgroundColor = QColor(CONSOLE_EDITOR_BACKGROUND_COLOR);
+ break;
+ }
+ if (selected)
+ backgroundColor.setAlphaF(0.5f);
+ else
+ backgroundColor.setAlphaF(1 - CONSOLE_ALPHA);
+
+ painter->setBrush(backgroundColor);
+
+ painter->setPen(Qt::NoPen);
+ painter->drawRect(rect);
+}
+
+void ConsoleItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ QStyleOptionViewItemV4 opt = option;
+ initStyleOption(&opt, index);
+ painter->save();
+
+ //Set Colors
+ QColor textColor;
+ QIcon taskIcon;
+ ConsoleItemModel::ItemType type =
+ (ConsoleItemModel::ItemType)index.data(
+ ConsoleItemModel::TypeRole).toInt();
+ switch (type) {
+ case ConsoleItemModel::LogType:
+ textColor = QColor(CONSOLE_LOG_TEXT_COLOR);
+ taskIcon = m_logIcon;
+ break;
+ case ConsoleItemModel::WarningType:
+ textColor = QColor(CONSOLE_WARNING_TEXT_COLOR);
+ taskIcon = m_warningIcon;
+ break;
+ case ConsoleItemModel::ErrorType:
+ textColor = QColor(CONSOLE_ERROR_TEXT_COLOR);
+ taskIcon = m_errorIcon;
+ break;
+ case ConsoleItemModel::InputType:
+ textColor = QColor(CONSOLE_EDITOR_TEXT_COLOR);
+ taskIcon = m_prompt;
+ break;
+ default:
+ textColor = QColor(CONSOLE_EDITOR_TEXT_COLOR);
+ break;
+ }
+
+ //Paint background
+ drawBackground(painter, opt.rect, type,
+ bool(opt.state & QStyle::State_Selected));
+
+ //Calculate positions
+ const QTreeView *view = qobject_cast<const QTreeView *>(opt.widget);
+ int level = 0;
+ QModelIndex idx(index);
+ while (idx.parent() != QModelIndex()) {
+ idx = idx.parent();
+ level++;
+ }
+ int width = view->width() - level * view->indentation();
+ bool showTypeIcon = index.parent() == QModelIndex();
+ bool showExpandableIcon = type != ConsoleItemModel::InputType &&
+ type != ConsoleItemModel::UndefinedType;
+
+ QRect rect(opt.rect.x(), opt.rect.top(), width, opt.rect.height());
+ ConsoleItemPositions positions(rect, opt.font, showTypeIcon,
+ showExpandableIcon);
+
+ // Paint TaskIconArea:
+ if (showTypeIcon)
+ painter->drawPixmap(positions.adjustedLeft(), positions.adjustedTop(),
+ taskIcon.pixmap(positions.typeIconWidth(),
+ positions.typeIconHeight()));
+
+ // Set Text Color
+ painter->setPen(textColor);
+ // Paint TextArea:
+ // Layout the description
+ QTextLayout tl(index.data(Qt::DisplayRole).toString(), opt.font);
+ layoutText(tl, positions.textAreaWidth());
+ tl.draw(painter, QPoint(positions.textAreaLeft(), positions.adjustedTop()));
+
+ //skip if area is editable
+ if (showExpandableIcon) {
+ // Paint ExpandableIconArea:
+ QIcon expandCollapseIcon;
+ if (index.model()->rowCount(index)) {
+ if (view->isExpanded(index))
+ expandCollapseIcon = m_collapseIcon;
+ else
+ expandCollapseIcon = m_expandIcon;
+ }
+ painter->drawPixmap(positions.expandCollapseIconLeft(),
+ positions.adjustedTop(),
+ expandCollapseIcon.pixmap(
+ positions.expandCollapseIconWidth(),
+ positions.expandCollapseIconHeight()));
+ }
+
+ // Separator lines
+ painter->setPen(QColor(CONSOLE_BORDER_COLOR));
+ if (!index.flags() & Qt::ItemIsEditable)
+ painter->drawLine(0, opt.rect.bottom(), opt.rect.right(),
+ opt.rect.bottom());
+ painter->restore();
+}
+
+QSize ConsoleItemDelegate::sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ QStyleOptionViewItemV4 opt = option;
+ initStyleOption(&opt, index);
+
+ const QTreeView *view = qobject_cast<const QTreeView *>(opt.widget);
+ int level = 0;
+ QModelIndex idx(index);
+ while (idx.parent() != QModelIndex()) {
+ idx = idx.parent();
+ level++;
+ }
+ int width = view->width() - level * view->indentation();
+ if (index.flags() & Qt::ItemIsEditable)
+ return QSize(width, view->height() * 1/2);
+
+ ConsoleItemModel::ItemType type =
+ (ConsoleItemModel::ItemType)index.data(
+ ConsoleItemModel::TypeRole).toInt();
+ bool showTypeIcon = index.parent() == QModelIndex();
+ bool showExpandableIcon = type != ConsoleItemModel::InputType &&
+ type != ConsoleItemModel::UndefinedType;
+
+ QRect rect(level * view->indentation(), 0, width, 0);
+ ConsoleItemPositions positions(rect, opt.font,
+ showTypeIcon,
+ showExpandableIcon);
+
+ QTextLayout tl(index.data(Qt::DisplayRole).toString(), option.font);
+ qreal height = layoutText(tl, positions.textAreaWidth());
+ height += 2 * ConsoleItemPositions::ITEM_PADDING;
+ if (height < positions.minimumHeight())
+ height = positions.minimumHeight();
+
+ return QSize(width, height);
+}
+
+QWidget *ConsoleItemDelegate::createEditor(QWidget *parent,
+ const QStyleOptionViewItem &/*option*/,
+ const QModelIndex &index) const
+
+{
+ ConsoleEditor *editor = new ConsoleEditor(index, m_consoleBackend, parent);
+ connect(editor, SIGNAL(appendEditableRow()),
+ this, SIGNAL(appendEditableRow()));
+ connect(editor, SIGNAL(editingFinished()),
+ this, SLOT(commitAndCloseEditor()));
+ return editor;
+}
+
+void ConsoleItemDelegate::setEditorData(QWidget *editor,
+ const QModelIndex &index) const
+{
+ ConsoleEditor *edtr = qobject_cast<ConsoleEditor *>(editor);
+ edtr->insertPlainText(index.data(Qt::DisplayRole).toString());
+}
+
+void ConsoleItemDelegate::setModelData(QWidget *editor,
+ QAbstractItemModel *model,
+ const QModelIndex &index) const
+{
+ ConsoleEditor *edtr = qobject_cast<ConsoleEditor *>(editor);
+ model->setData(index, edtr->getCurrentScript(), Qt::DisplayRole);
+ model->setData(index, edtr->getCurrentScript(), ConsoleItemModel::TypeRole);
+}
+
+void ConsoleItemDelegate::updateEditorGeometry(QWidget *editor,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &/*index*/) const
+{
+ QStyleOptionViewItemV4 opt = option;
+ editor->setGeometry(QRect(opt.rect.x(), opt.rect.top(),
+ opt.rect.width(), opt.rect.bottom()));
+}
+
+void ConsoleItemDelegate::currentChanged(const QModelIndex &current,
+ const QModelIndex &previous)
+{
+ emit sizeHintChanged(current);
+ emit sizeHintChanged(previous);
+}
+
+void ConsoleItemDelegate::commitAndCloseEditor()
+{
+ ConsoleEditor *editor = qobject_cast<ConsoleEditor *>(sender());
+ emit commitData(editor);
+ emit closeEditor(editor);
+}
+
+qreal ConsoleItemDelegate::layoutText(QTextLayout &tl, int width) const
+{
+ qreal height = 0;
+ tl.beginLayout();
+ while (true) {
+ QTextLine line = tl.createLine();
+
+ if (!line.isValid())
+ break;
+ line.setLeadingIncluded(true);
+ line.setLineWidth(width);
+ line.setPosition(QPoint(0, height));
+ height += line.height();
+ }
+ tl.endLayout();
+ return height;
+}
+
+} //Internal
+} //Debugger
diff --git a/src/plugins/debugger/qml/consoleitemdelegate.h b/src/plugins/debugger/qml/consoleitemdelegate.h
new file mode 100644
index 0000000000..a7b79f9018
--- /dev/null
+++ b/src/plugins/debugger/qml/consoleitemdelegate.h
@@ -0,0 +1,174 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@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 qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef CONSOLEITEMDELEGATE_H
+#define CONSOLEITEMDELEGATE_H
+
+#include "consoleitemmodel.h"
+
+#include <QTextLayout>
+#include <QStyledItemDelegate>
+
+namespace Debugger {
+namespace Internal {
+
+class ConsoleBackend;
+class ConsoleItemDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+public:
+ explicit ConsoleItemDelegate(QObject *parent = 0);
+ void emitSizeHintChanged(const QModelIndex &index);
+ void setConsoleBackend(ConsoleBackend *consoleBackend);
+
+ void drawBackground(QPainter *painter, const QRect &rect,
+ ConsoleItemModel::ItemType itemType, bool selected) const;
+
+public slots:
+ void currentChanged(const QModelIndex &current, const QModelIndex &previous);
+
+protected:
+ void paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+ QSize sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+ void setEditorData(QWidget *editor, const QModelIndex &index) const;
+ void setModelData(QWidget *editor, QAbstractItemModel *model,
+ const QModelIndex &index) const;
+
+ void updateEditorGeometry(QWidget *editor,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+signals:
+ void appendEditableRow();
+
+private slots:
+ void commitAndCloseEditor();
+
+private:
+ qreal layoutText(QTextLayout &tl, int width) const;
+
+private:
+ const QIcon m_logIcon;
+ const QIcon m_warningIcon;
+ const QIcon m_errorIcon;
+ const QIcon m_expandIcon;
+ const QIcon m_collapseIcon;
+ const QIcon m_prompt;
+ ConsoleBackend *m_consoleBackend;
+};
+
+/*
+ +----------------------------------------------------------------------------+
+ | TYPEICONAREA EXPANDABLEICONAREA TEXTAREA |
+ +----------------------------------------------------------------------------+
+
+ */
+/*
+ +----------------------------------------------------------------------------+
+ | PROMPTAREA EDITABLEAREA |
+ +----------------------------------------------------------------------------+
+
+ */
+class ConsoleItemPositions
+{
+public:
+ ConsoleItemPositions(const QRect &rect,
+ const QFont &font = QFont(),
+ bool showTaskIconArea = true,
+ bool showExpandableIconArea = true)
+ : m_x(rect.x()),
+ m_width(rect.width()),
+ m_top(rect.top()),
+ m_bottom(rect.bottom()),
+ m_showTaskIconArea(showTaskIconArea),
+ m_showExpandableIconArea(showExpandableIconArea)
+ {
+ m_fontHeight = QFontMetrics(font).height();
+ }
+
+ int adjustedTop() const { return m_top + ITEM_PADDING; }
+ int adjustedLeft() const { return m_x + ITEM_PADDING; }
+ int adjustedRight() const { return m_width - ITEM_PADDING; }
+ int adjustedBottom() const { return m_bottom; }
+ int lineHeight() const { return m_fontHeight + 1; }
+ int minimumHeight() const { return typeIconHeight() + 2 * ITEM_PADDING; }
+
+ //PROMPTAREA is same as TYPEICONAREA
+ int typeIconLeft() const { return adjustedLeft(); }
+ int typeIconWidth() const { return TASK_ICON_SIZE; }
+ int typeIconHeight() const { return TASK_ICON_SIZE; }
+ int typeIconRight() const { return m_showTaskIconArea ?
+ typeIconLeft() + typeIconWidth() : adjustedLeft(); }
+ QRect typeIcon() const { return
+ QRect(typeIconLeft(), adjustedTop(),
+ typeIconWidth(), typeIconHeight()); }
+
+ int expandCollapseIconLeft() const { return typeIconRight() +
+ ITEM_SPACING; }
+ int expandCollapseIconWidth() const { return TASK_ICON_SIZE; }
+ int expandCollapseIconHeight() const { return TASK_ICON_SIZE; }
+ int expandCollapseIconRight() const { return m_showExpandableIconArea ?
+ expandCollapseIconLeft() + expandCollapseIconWidth() :
+ typeIconRight(); }
+ QRect expandCollapseIcon() const { return
+ QRect(expandCollapseIconLeft(), adjustedTop(),
+ expandCollapseIconWidth(), expandCollapseIconHeight()); }
+
+ int textAreaLeft() const { return expandCollapseIconRight() + ITEM_SPACING; }
+ int textAreaWidth() const { return textAreaRight() - textAreaLeft(); }
+ int textAreaRight() const { return adjustedRight() - ITEM_SPACING; }
+ QRect textArea() const { return
+ QRect(textAreaLeft(), adjustedTop(), textAreaWidth(), lineHeight()); }
+
+private:
+ int m_x;
+ int m_width;
+ int m_top;
+ int m_bottom;
+ int m_fontHeight;
+ bool m_showTaskIconArea;
+ bool m_showExpandableIconArea;
+
+public:
+ static const int TASK_ICON_SIZE = 16;
+ static const int ITEM_PADDING = 2;
+ static const int ITEM_SPACING = 2 * ITEM_PADDING;
+
+};
+} //Internal
+} //Debugger
+
+#endif // CONSOLEITEMDELEGATE_H
diff --git a/src/plugins/debugger/qml/consoleitemmodel.cpp b/src/plugins/debugger/qml/consoleitemmodel.cpp
new file mode 100644
index 0000000000..aaad6df3c8
--- /dev/null
+++ b/src/plugins/debugger/qml/consoleitemmodel.cpp
@@ -0,0 +1,348 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@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 qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "consoleitemmodel.h"
+
+namespace Debugger {
+namespace Internal {
+
+class ConsoleItem
+ {
+ public:
+ ConsoleItem(const QString &data = QString(),
+ ConsoleItemModel::ItemType type = ConsoleItemModel::UndefinedType,
+ ConsoleItem *parent = 0);
+ ~ConsoleItem();
+
+ ConsoleItem *child(int number);
+ int childCount() const;
+ QString text() const;
+ ConsoleItemModel::ItemType itemType() const;
+ bool insertChildren(int position, int count);
+ ConsoleItem *parent();
+ bool removeChildren(int position, int count);
+ bool removeColumns(int position, int columns);
+ int childNumber() const;
+ bool setData(const QString &text, ConsoleItemModel::ItemType itemType);
+ bool setText(const QString &text);
+ bool setItemType(ConsoleItemModel::ItemType itemType);
+
+ private:
+ QList<ConsoleItem *> m_childItems;
+ QString m_text;
+ ConsoleItemModel::ItemType m_itemType;
+ ConsoleItem *m_parentItem;
+ };
+
+///////////////////////////////////////////////////////////////////////
+//
+// ConsoleItem
+//
+///////////////////////////////////////////////////////////////////////
+
+ConsoleItem::ConsoleItem(const QString &text,
+ ConsoleItemModel::ItemType itemType,
+ ConsoleItem *parent)
+ : m_text(text),
+ m_itemType(itemType),
+ m_parentItem(parent)
+
+{
+}
+
+ConsoleItem::~ConsoleItem()
+{
+ qDeleteAll(m_childItems);
+}
+
+ConsoleItem *ConsoleItem::child(int number)
+{
+ return m_childItems.value(number);
+}
+
+int ConsoleItem::childCount() const
+{
+ return m_childItems.count();
+}
+
+int ConsoleItem::childNumber() const
+{
+ if (m_parentItem)
+ return m_parentItem->m_childItems.indexOf(const_cast<ConsoleItem *>(this));
+
+ return 0;
+}
+
+QString ConsoleItem::text() const
+{
+ return m_text;
+}
+
+ConsoleItemModel::ItemType ConsoleItem::itemType() const
+{
+ return m_itemType;
+}
+\
+bool ConsoleItem::insertChildren(int position, int count)
+{
+ if (position < 0 || position > m_childItems.size())
+ return false;
+
+ for (int row = 0; row < count; ++row) {
+ ConsoleItem *item = new ConsoleItem(QString(),
+ ConsoleItemModel::UndefinedType, this);
+ m_childItems.insert(position, item);
+ }
+
+ return true;
+}
+
+ConsoleItem *ConsoleItem::parent()
+{
+ return m_parentItem;
+}
+
+bool ConsoleItem::removeChildren(int position, int count)
+{
+ if (position < 0 || position + count > m_childItems.size())
+ return false;
+
+ for (int row = 0; row < count; ++row)
+ delete m_childItems.takeAt(position);
+
+ return true;
+}
+
+bool ConsoleItem::removeColumns(int /*position*/, int /*columns*/)
+{
+ return false;
+}
+
+bool ConsoleItem::setData(const QString &text,
+ ConsoleItemModel::ItemType itemType)
+{
+ m_text = text;
+ m_itemType = itemType;
+ return true;
+}
+
+bool ConsoleItem::setText(const QString &text)
+{
+ m_text = text;
+ return true;
+}
+
+bool ConsoleItem::setItemType(ConsoleItemModel::ItemType itemType)
+{
+ m_itemType = itemType;
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////
+//
+// ConsoleItemModel
+//
+///////////////////////////////////////////////////////////////////////
+
+ConsoleItemModel::ConsoleItemModel(QObject *parent) :
+ QAbstractItemModel(parent)
+{
+ m_rootItem = new ConsoleItem();
+}
+
+ConsoleItemModel::~ConsoleItemModel()
+{
+ delete m_rootItem;
+}
+
+void ConsoleItemModel::clear()
+{
+ beginResetModel();
+ reset();
+ delete m_rootItem;
+ m_rootItem = new ConsoleItem();
+ endResetModel();
+
+ //Insert an empty row
+ appendEditableRow();
+}
+
+void ConsoleItemModel::appendItem(ItemType itemType, QString message)
+{
+ int position = m_rootItem->childCount() - 1;
+ insertRow(position);
+ QModelIndex idx = index(position, 0);
+ if (getItem(idx)->setData(message, itemType))
+ emit dataChanged(idx, idx);
+}
+
+void ConsoleItemModel::appendEditableRow()
+{
+ int position = m_rootItem->childCount();
+ insertRow(position);
+ QModelIndex idx = index(position, 0);
+ if (getItem(idx)->setData(QString(), ConsoleItemModel::InputType)) {
+ QModelIndex idx = index(position, 0);
+ emit dataChanged(idx, idx);
+ emit editableRowAppended(idx, QItemSelectionModel::ClearAndSelect);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+//
+// ConsoleEditor
+//
+///////////////////////////////////////////////////////////////////////
+
+QVariant ConsoleItemModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+
+ ConsoleItem *item = getItem(index);
+
+ if (role == Qt::DisplayRole )
+ return item->text();
+ else if (role == ConsoleItemModel::TypeRole)
+ return int(item->itemType());
+ else
+ return QVariant();
+}
+
+QModelIndex ConsoleItemModel::index(int row, int column,
+ const QModelIndex &parent) const
+{
+ if (parent.isValid() && parent.column() != 0)
+ return QModelIndex();
+
+ if (column > 0)
+ return QModelIndex();
+
+ ConsoleItem *parentItem = getItem(parent);
+
+ ConsoleItem *childItem = parentItem->child(row);
+ if (childItem)
+ return createIndex(row, column, childItem);
+ else
+ return QModelIndex();
+}
+
+QModelIndex ConsoleItemModel::parent(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return QModelIndex();
+
+ ConsoleItem *childItem = getItem(index);
+ ConsoleItem *parentItem = childItem->parent();
+
+ if (parentItem == m_rootItem)
+ return QModelIndex();
+
+ return createIndex(parentItem->childNumber(), 0, parentItem);
+}
+
+int ConsoleItemModel::rowCount(const QModelIndex &parent) const
+{
+ ConsoleItem *parentItem = getItem(parent);
+
+ return parentItem->childCount();
+}
+
+int ConsoleItemModel::columnCount(const QModelIndex & /* parent */) const
+{
+ return 1;
+}
+
+Qt::ItemFlags ConsoleItemModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return 0;
+
+ ConsoleItem *item = getItem(index);
+ if (item->parent() == m_rootItem && index.row() == m_rootItem->childCount() - 1)
+ return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+}
+
+bool ConsoleItemModel::setData(const QModelIndex &index, const QVariant &value,
+ int role)
+{
+ ConsoleItem *item = getItem(index);
+ bool result = false;
+ if (role == Qt::DisplayRole )
+ result = item->setText(value.toString());
+ else if (role == ConsoleItemModel::TypeRole)
+ result = item->setItemType((ItemType)value.toInt());
+ else if (value.canConvert(QVariant::String))
+ result = item->setText(value.toString());
+
+ if (result)
+ emit dataChanged(index, index);
+
+ return result;
+}
+
+bool ConsoleItemModel::insertRows(int position, int rows, const QModelIndex &parent)
+{
+ ConsoleItem *parentItem = getItem(parent);
+ bool success;
+
+ beginInsertRows(parent, position, position + rows - 1);
+ success = parentItem->insertChildren(position, rows);
+ endInsertRows();
+
+ return success;
+}
+
+bool ConsoleItemModel::removeRows(int position, int rows, const QModelIndex &parent)
+{
+ ConsoleItem *parentItem = getItem(parent);
+ bool success = true;
+
+ beginRemoveRows(parent, position, position + rows - 1);
+ success = parentItem->removeChildren(position, rows);
+ endRemoveRows();
+
+ return success;
+}
+
+ConsoleItem *ConsoleItemModel::getItem(const QModelIndex &index) const
+{
+ if (index.isValid()) {
+ ConsoleItem *item = static_cast<ConsoleItem*>(index.internalPointer());
+ if (item) return item;
+ }
+ return m_rootItem;
+}
+
+} //Internal
+} //Debugger
diff --git a/src/plugins/debugger/qml/consoleitemmodel.h b/src/plugins/debugger/qml/consoleitemmodel.h
new file mode 100644
index 0000000000..994d34d6e0
--- /dev/null
+++ b/src/plugins/debugger/qml/consoleitemmodel.h
@@ -0,0 +1,94 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@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 qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef CONSOLEITEMMODEL_H
+#define CONSOLEITEMMODEL_H
+
+#include <QAbstractItemModel>
+#include <QtGui/QItemSelectionModel>
+
+namespace Debugger {
+namespace Internal {
+
+class ConsoleItem;
+class ConsoleItemModel : public QAbstractItemModel
+{
+ Q_OBJECT
+
+public:
+ enum ItemType { InputType, LogType, WarningType, ErrorType,
+ UndefinedType //Can be used for unknown and for Return values
+ };
+ enum Roles { TypeRole = Qt::UserRole };
+
+ explicit ConsoleItemModel(QObject *parent = 0);
+ ~ConsoleItemModel();
+
+ void appendItem(ItemType,QString);
+
+public slots:
+ void clear();
+ void appendEditableRow();
+
+signals:
+ void editableRowAppended(const QModelIndex &index,
+ QItemSelectionModel::SelectionFlags flags);
+
+protected:
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+
+ QModelIndex index(int row, int column,
+ const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex &index) const;
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ bool setData(const QModelIndex &index, const QVariant &value,
+ int role = Qt::EditRole);
+
+ bool insertRows(int position, int rows,
+ const QModelIndex &parent = QModelIndex());
+ bool removeRows(int position, int rows,
+ const QModelIndex &parent = QModelIndex());
+
+ ConsoleItem *getItem(const QModelIndex &index) const;
+
+private:
+ ConsoleItem *m_rootItem;
+};
+
+} //Internal
+} //Debugger
+
+#endif // CONSOLEITEMMODEL_H
diff --git a/src/plugins/debugger/qml/consoletreeview.cpp b/src/plugins/debugger/qml/consoletreeview.cpp
new file mode 100644
index 0000000000..3fed6e3f50
--- /dev/null
+++ b/src/plugins/debugger/qml/consoletreeview.cpp
@@ -0,0 +1,157 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@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 qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "consoletreeview.h"
+#include "consoleitemdelegate.h"
+#include "consoleitemmodel.h"
+#include "debuggerinternalconstants.h"
+
+#include <QtGui/QMouseEvent>
+#include <QtGui/QProxyStyle>
+#include <QtGui/QPainter>
+
+namespace Debugger {
+namespace Internal {
+
+class ConsoleTreeViewStyle : public QProxyStyle
+{
+public:
+ void drawPrimitive(PrimitiveElement element,
+ const QStyleOption *option,
+ QPainter *painter,
+ const QWidget *widget = 0) const
+ {
+ if (element != QStyle::PE_PanelItemViewRow)
+ QProxyStyle::drawPrimitive(element, option, painter, widget);
+ }
+
+ int styleHint(StyleHint hint, const QStyleOption *option = 0,
+ const QWidget *widget = 0,
+ QStyleHintReturn *returnData = 0) const {
+ if (hint == SH_ItemView_ShowDecorationSelected)
+ return 0;
+ else
+ return QProxyStyle::styleHint(hint, option, widget, returnData);
+ }
+};
+
+///////////////////////////////////////////////////////////////////////
+//
+// ConsoleTreeView
+//
+///////////////////////////////////////////////////////////////////////
+
+ConsoleTreeView::ConsoleTreeView(QWidget *parent) :
+ QTreeView(parent)
+{
+ setFrameStyle(QFrame::NoFrame);
+ setHeaderHidden(true);
+ setRootIsDecorated(false);
+ setEditTriggers(QAbstractItemView::AllEditTriggers);
+ setStyleSheet(QLatin1String("QTreeView::branch:has-siblings:!adjoins-item {"
+ "border-image: none;"
+ "image: none; }"
+ "QTreeView::branch:has-siblings:adjoins-item {"
+ "border-image: none;"
+ "image: none; }"
+ "QTreeView::branch:!has-children:!has-siblings:adjoins-item {"
+ "border-image: none;"
+ "image: none; }"
+ "QTreeView::branch:has-children:!has-siblings:closed,"
+ "QTreeView::branch:closed:has-children:has-siblings {"
+ "border-image: none;"
+ "image: none; }"
+ "QTreeView::branch:open:has-children:!has-siblings,"
+ "QTreeView::branch:open:has-children:has-siblings {"
+ "border-image: none;"
+ "image: none; }"));
+ ConsoleTreeViewStyle *style = new ConsoleTreeViewStyle;
+ setStyle(style);
+ style->setParent(this);
+}
+
+void ConsoleTreeView::setItemDelegate(QAbstractItemDelegate *delegate)
+{
+ connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ delegate, SLOT(currentChanged(QModelIndex,QModelIndex)));
+ QTreeView::setItemDelegate(delegate);
+}
+
+void ConsoleTreeView::mousePressEvent(QMouseEvent *event)
+{
+ QPoint pos = event->pos();
+ QModelIndex index = indexAt(pos);
+ if (index.isValid()) {
+ ConsoleItemModel::ItemType type =
+ (ConsoleItemModel::ItemType)index.data(
+ ConsoleItemModel::TypeRole).toInt();
+ bool showTypeIcon = index.parent() == QModelIndex();
+ bool showExpandableIcon = type != ConsoleItemModel::InputType &&
+ type != ConsoleItemModel::UndefinedType;
+ ConsoleItemPositions positions(visualRect(index), viewOptions().font,
+ showTypeIcon, showExpandableIcon);
+
+ if (positions.expandCollapseIcon().contains(pos)) {
+ if (isExpanded(index))
+ setExpanded(index, false);
+ else
+ setExpanded(index, true);
+ } else {
+ QTreeView::mousePressEvent(event);
+ }
+ } else {
+ selectionModel()->setCurrentIndex(model()->index(
+ model()->rowCount() - 1, 0),
+ QItemSelectionModel::ClearAndSelect);
+ }
+}
+
+void ConsoleTreeView::resizeEvent(QResizeEvent *e)
+{
+ static_cast<ConsoleItemDelegate *>(itemDelegate())->emitSizeHintChanged(
+ selectionModel()->currentIndex());
+ QTreeView::resizeEvent(e);
+}
+
+void ConsoleTreeView::drawBranches(QPainter *painter, const QRect &rect,
+ const QModelIndex &index) const
+{
+ ConsoleItemModel::ItemType type =
+ (ConsoleItemModel::ItemType)index.data(
+ ConsoleItemModel::TypeRole).toInt();
+ static_cast<ConsoleItemDelegate *>(itemDelegate())->drawBackground(
+ painter, rect, type, true);
+ QTreeView::drawBranches(painter, rect, index);
+}
+
+} //Internal
+} //Debugger
diff --git a/src/plugins/debugger/qml/consoletreeview.h b/src/plugins/debugger/qml/consoletreeview.h
new file mode 100644
index 0000000000..5790fbde6a
--- /dev/null
+++ b/src/plugins/debugger/qml/consoletreeview.h
@@ -0,0 +1,59 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@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 qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef CONSOLETREEVIEW_H
+#define CONSOLETREEVIEW_H
+
+#include <QtGui/QTreeView>
+
+namespace Debugger {
+namespace Internal {
+
+class ConsoleTreeView : public QTreeView
+{
+ Q_OBJECT
+public:
+ explicit ConsoleTreeView(QWidget *parent = 0);
+
+ void setItemDelegate(QAbstractItemDelegate *delegate);
+
+protected:
+ void mousePressEvent(QMouseEvent *event);
+ void resizeEvent(QResizeEvent *e);
+ void drawBranches(QPainter *painter, const QRect &rect,
+ const QModelIndex &index) const;
+};
+
+} //Internal
+} //Debugger
+
+#endif // CONSOLETREEVIEW_H
diff --git a/src/plugins/debugger/qml/qml.pri b/src/plugins/debugger/qml/qml.pri
index a34c120add..74a8d2c3e8 100644
--- a/src/plugins/debugger/qml/qml.pri
+++ b/src/plugins/debugger/qml/qml.pri
@@ -10,7 +10,12 @@ HEADERS += \
$$PWD/qscriptdebuggerclient.h \
$$PWD/qmlv8debuggerclient.h \
$$PWD/interactiveinterpreter.h \
- $$PWD/qmlv8debuggerclientconstants.h
+ $$PWD/qmlv8debuggerclientconstants.h \
+ $$PWD/consoletreeview.h \
+ $$PWD/consoleitemmodel.h \
+ $$PWD/consoleitemdelegate.h \
+ $$PWD/consoleeditor.h \
+ $$PWD/consolebackend.h
SOURCES += \
$$PWD/qmlengine.cpp \
@@ -20,5 +25,10 @@ SOURCES += \
$$PWD/qmljsscriptconsole.cpp \
$$PWD/qscriptdebuggerclient.cpp \
$$PWD/qmlv8debuggerclient.cpp \
- $$PWD/interactiveinterpreter.cpp
+ $$PWD/interactiveinterpreter.cpp \
+ $$PWD/consoletreeview.cpp \
+ $$PWD/consoleitemmodel.cpp \
+ $$PWD/consoleitemdelegate.cpp \
+ $$PWD/consoleeditor.cpp \
+ $$PWD/consolebackend.cpp
diff --git a/src/plugins/debugger/qml/qmljsscriptconsole.cpp b/src/plugins/debugger/qml/qmljsscriptconsole.cpp
index 1579875bd2..086ae12c75 100644
--- a/src/plugins/debugger/qml/qmljsscriptconsole.cpp
+++ b/src/plugins/debugger/qml/qmljsscriptconsole.cpp
@@ -31,20 +31,21 @@
**************************************************************************/
#include "qmljsscriptconsole.h"
-#include "interactiveinterpreter.h"
#include "qmladapter.h"
#include "debuggerstringutils.h"
-
-#include <texteditor/fontsettings.h>
-#include <texteditor/texteditorsettings.h>
+#include "consoletreeview.h"
+#include "consoleitemmodel.h"
+#include "consoleitemdelegate.h"
+#include "consolebackend.h"
+#include "debuggerstringutils.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/coreconstants.h>
#include <utils/statuslabel.h>
#include <utils/styledbar.h>
+#include <utils/savedaction.h>
#include <coreplugin/icore.h>
-#include <utils/qtcassert.h>
#include <qmljsdebugclient/qdebugmessageclient.h>
#include <debugger/qml/qmlcppengine.h>
@@ -67,56 +68,6 @@ static const char SHOW_ERROR[] = "showError";
namespace Debugger {
namespace Internal {
-class QmlJSScriptConsolePrivate
-{
-public:
- QmlJSScriptConsolePrivate()
- : adapter(0),
- prompt(_("> ")),
- startOfEditableArea(-1),
- lastKnownPosition(0),
- inferiorStopped(false),
- hasContext(false)
- {
- scriptHistory.append(QString());
- scriptHistoryIndex = scriptHistory.count();
- }
-
- void appendToHistory(const QString &script);
- bool canEvaluateScript(const QString &script);
-
- QmlAdapter *adapter;
-
- QString prompt;
- int startOfEditableArea;
- int lastKnownPosition;
-
- QStringList scriptHistory;
- int scriptHistoryIndex;
-
- InteractiveInterpreter interpreter;
-
- bool inferiorStopped;
- bool hasContext;
-
- QFlags<QmlJSScriptConsole::DebugLevelFlag> debugLevel;
-};
-
-void QmlJSScriptConsolePrivate::appendToHistory(const QString &script)
-{
- scriptHistoryIndex = scriptHistory.count();
- scriptHistory.replace(scriptHistoryIndex - 1,script);
- scriptHistory.append(QString());
- scriptHistoryIndex = scriptHistory.count();
-}
-
-bool QmlJSScriptConsolePrivate::canEvaluateScript(const QString &script)
-{
- interpreter.clearText();
- interpreter.appendText(script);
- return interpreter.canEvaluate();
-}
-
///////////////////////////////////////////////////////////////////////
//
// QmlJSScriptConsoleWidget
@@ -126,74 +77,151 @@ bool QmlJSScriptConsolePrivate::canEvaluateScript(const QString &script)
QmlJSScriptConsoleWidget::QmlJSScriptConsoleWidget(QWidget *parent)
: QWidget(parent)
{
+ const int statusBarHeight = 25;
+ const int spacing = 7;
+ const int buttonWidth = 25;
+
QVBoxLayout *vbox = new QVBoxLayout(this);
vbox->setMargin(0);
vbox->setSpacing(0);
QWidget *statusbarContainer = new QWidget;
-
+ statusbarContainer->setFixedHeight(statusBarHeight);
QHBoxLayout *hbox = new QHBoxLayout(statusbarContainer);
hbox->setMargin(0);
hbox->setSpacing(0);
+ //Status Label
+ m_statusLabel = new Utils::StatusLabel;
+ hbox->addSpacing(spacing);
+ hbox->addWidget(m_statusLabel);
+ hbox->addWidget(new Utils::StyledSeparator);
+
+ //Filters
+ hbox->addSpacing(spacing);
+ m_showLog = new QToolButton(this);
+ m_showLog->setAutoRaise(true);
+ m_showLog->setFixedWidth(buttonWidth);
+ m_showLogAction = new Utils::SavedAction(this);
+ m_showLogAction->setDefaultValue(true);
+ m_showLogAction->setSettingsKey(_(SCRIPT_CONSOLE), _(SHOW_LOG));
+ m_showLogAction->setText(tr("Log"));
+ m_showLogAction->setCheckable(true);
+ m_showLogAction->setIcon(QIcon(_(":/debugger/images/log.png")));
+// connect(m_showLogAction, SIGNAL(toggled(bool)), this, SLOT(setDebugLevel()));
+ m_showLog->setDefaultAction(m_showLogAction);
+
+ m_showWarning = new QToolButton(this);
+ m_showWarning->setAutoRaise(true);
+ m_showWarning->setFixedWidth(buttonWidth);
+ m_showWarningAction = new Utils::SavedAction(this);
+ m_showWarningAction->setDefaultValue(true);
+ m_showWarningAction->setSettingsKey(_(SCRIPT_CONSOLE), _(SHOW_WARNING));
+ m_showWarningAction->setText(tr("Warning"));
+ m_showWarningAction->setCheckable(true);
+ m_showWarningAction->setIcon(QIcon(_(":/debugger/images/warning.png")));
+// connect(m_showWarningAction, SIGNAL(toggled(bool)), this, SLOT(setDebugLevel()));
+ m_showWarning->setDefaultAction(m_showWarningAction);
+
+ m_showError = new QToolButton(this);
+ m_showError->setAutoRaise(true);
+ m_showError->setFixedWidth(buttonWidth);
+ m_showErrorAction = new Utils::SavedAction(this);
+ m_showErrorAction->setDefaultValue(true);
+ m_showErrorAction->setSettingsKey(_(SCRIPT_CONSOLE), _(SHOW_ERROR));
+ m_showErrorAction->setText(tr("Error"));
+ m_showErrorAction->setCheckable(true);
+ m_showErrorAction->setIcon(QIcon(_(":/debugger/images/error.png")));
+// connect(m_showErrorAction, SIGNAL(toggled(bool)), this, SLOT(setDebugLevel()));
+ m_showError->setDefaultAction(m_showErrorAction);
+
+ hbox->addWidget(m_showLog);
+ hbox->addSpacing(spacing);
+ hbox->addWidget(m_showWarning);
+ hbox->addSpacing(spacing);
+ hbox->addWidget(m_showError);
+
//Clear Button
QToolButton *clearButton = new QToolButton;
+ clearButton->setAutoRaise(true);
+ clearButton->setFixedWidth(buttonWidth);
QAction *clearAction = new QAction(tr("Clear Console"), this);
clearAction->setIcon(QIcon(_(Core::Constants::ICON_CLEAN_PANE)));
-
clearButton->setDefaultAction(clearAction);
- //Status Label
- m_statusLabel = new Utils::StatusLabel;
+ hbox->addSpacing(spacing);
+ hbox->addWidget(clearButton);
+ hbox->addSpacing(spacing);
+
+ m_consoleView = new ConsoleTreeView(this);
+
+ m_model = new ConsoleItemModel(this);
+ m_model->clear();
+ connect(clearAction, SIGNAL(triggered()), m_model, SLOT(clear()));
+ m_consoleView->setModel(m_model);
+ connect(m_model,
+ SIGNAL(editableRowAppended(QModelIndex,QItemSelectionModel::SelectionFlags)),
+ m_consoleView->selectionModel(),
+ SLOT(setCurrentIndex(QModelIndex,QItemSelectionModel::SelectionFlags)));
+
+ m_consoleBackend = new QmlJSConsoleBackend(this);
+ connect(m_consoleBackend, SIGNAL(evaluateExpression(QString)),
+ this, SIGNAL(evaluateExpression(QString)));
+ connect(m_consoleBackend, SIGNAL(message(ConsoleItemModel::ItemType,QString)),
+ this, SLOT(appendOutput(ConsoleItemModel::ItemType,QString)));
+
+ m_itemDelegate = new ConsoleItemDelegate(this);
+ connect(m_itemDelegate, SIGNAL(appendEditableRow()),
+ m_model, SLOT(appendEditableRow()));
+ m_itemDelegate->setConsoleBackend(m_consoleBackend);
+ m_consoleView->setItemDelegate(m_itemDelegate);
- hbox->addWidget(m_statusLabel, 20, Qt::AlignLeft);
- hbox->addWidget(new Utils::StyledSeparator);
- m_showLog = new QCheckBox(tr("Log"), this);
- m_showWarning = new QCheckBox(tr("Warning"), this);
- m_showError = new QCheckBox(tr("Error"), this);
- connect(m_showLog, SIGNAL(stateChanged(int)), this, SLOT(setDebugLevel()));
- connect(m_showWarning, SIGNAL(stateChanged(int)), this, SLOT(setDebugLevel()));
- connect(m_showError, SIGNAL(stateChanged(int)), this, SLOT(setDebugLevel()));
- hbox->addWidget(m_showLog);
- hbox->addWidget(m_showWarning);
- hbox->addWidget(m_showError);
- hbox->addWidget(new Utils::StyledSeparator);
- hbox->addWidget(clearButton, 0, Qt::AlignRight);
-
- m_console = new QmlJSScriptConsole(this);
- connect(m_console, SIGNAL(evaluateExpression(QString)), this,
- SIGNAL(evaluateExpression(QString)));
- connect(m_console, SIGNAL(updateStatusMessage(const QString &, int)), m_statusLabel,
- SLOT(showStatusMessage(const QString &, int)));
- connect(clearAction, SIGNAL(triggered()), m_console, SLOT(clear()));
vbox->addWidget(statusbarContainer);
- vbox->addWidget(m_console);
+ vbox->addWidget(m_consoleView);
- QSettings *settings = Core::ICore::settings();
- settings->beginGroup(_(SCRIPT_CONSOLE));
- m_showLog->setChecked(settings->value(_(SHOW_LOG), true).toBool());
- m_showWarning->setChecked(settings->value(_(SHOW_WARNING), true).toBool());
- m_showError->setChecked(settings->value(_(SHOW_ERROR), true).toBool());
- settings->endGroup();
+ readSettings();
+ connect(Core::ICore::instance(),
+ SIGNAL(saveSettingsRequested()), SLOT(writeSettings()));
}
QmlJSScriptConsoleWidget::~QmlJSScriptConsoleWidget()
{
+ writeSettings();
+}
+
+void QmlJSScriptConsoleWidget::readSettings()
+{
+ QSettings *settings = Core::ICore::settings();
+ m_showLogAction->readSettings(settings);
+ m_showWarningAction->readSettings(settings);
+ m_showErrorAction->readSettings(settings);
+}
+
+void QmlJSScriptConsoleWidget::writeSettings() const
+{
QSettings *settings = Core::ICore::settings();
- settings->beginGroup(_(SCRIPT_CONSOLE));
- settings->setValue(_(SHOW_LOG), QVariant(m_showLog->isChecked()));
- settings->setValue(_(SHOW_WARNING), QVariant(m_showWarning->isChecked()));
- settings->setValue(_(SHOW_ERROR), QVariant(m_showError->isChecked()));
- settings->endGroup();
+ m_showLogAction->writeSettings(settings);
+ m_showWarningAction->writeSettings(settings);
+ m_showErrorAction->writeSettings(settings);
}
void QmlJSScriptConsoleWidget::setEngine(DebuggerEngine *engine)
{
- if (m_console->engine())
- disconnect(m_console->engine(), SIGNAL(stateChanged(Debugger::DebuggerState)),
+ QmlEngine *qmlEngine = m_consoleBackend->engine();
+ if (qmlEngine) {
+ disconnect(qmlEngine, SIGNAL(stateChanged(Debugger::DebuggerState)),
this, SLOT(onEngineStateChanged(Debugger::DebuggerState)));
+ disconnect(qmlEngine->stackHandler(), SIGNAL(currentIndexChanged()),
+ this, SLOT(onSelectionChanged()));
+ disconnect(qmlEngine->adapter(), SIGNAL(selectionChanged()),
+ this, SLOT(onSelectionChanged()));
+ disconnect(qmlEngine->adapter()->messageClient(),
+ SIGNAL(message(QtMsgType,QString)),
+ this, SLOT(appendMessage(QtMsgType,QString)));
+ qmlEngine = 0;
+ }
- QmlEngine *qmlEngine = qobject_cast<QmlEngine *>(engine);
+ qmlEngine = qobject_cast<QmlEngine *>(engine);
QmlCppEngine *qmlCppEngine = qobject_cast<QmlCppEngine *>(engine);
if (qmlCppEngine)
qmlEngine = qobject_cast<QmlEngine *>(qmlCppEngine->qmlEngine());
@@ -202,483 +230,97 @@ void QmlJSScriptConsoleWidget::setEngine(DebuggerEngine *engine)
if (qmlEngine) {
connect(qmlEngine, SIGNAL(stateChanged(Debugger::DebuggerState)),
this, SLOT(onEngineStateChanged(Debugger::DebuggerState)));
-
+ connect(qmlEngine->stackHandler(), SIGNAL(currentIndexChanged()),
+ this, SLOT(onSelectionChanged()));
+ connect(qmlEngine->adapter(), SIGNAL(selectionChanged()),
+ this, SLOT(onSelectionChanged()));
+ connect(qmlEngine->adapter()->messageClient(),
+ SIGNAL(message(QtMsgType,QString)),
+ this, SLOT(appendMessage(QtMsgType,QString)));
onEngineStateChanged(qmlEngine->state());
}
-
- m_console->setEngine(qmlEngine);
+ m_consoleBackend->setEngine(qmlEngine);
}
void QmlJSScriptConsoleWidget::appendResult(const QString &result)
{
- m_console->appendResult(result);
-}
-
-void QmlJSScriptConsoleWidget::setDebugLevel()
-{
- QFlags<QmlJSScriptConsole::DebugLevelFlag> level;
-
- if (m_showLog->isChecked())
- level |= QmlJSScriptConsole::Log;
-
- if (m_showWarning->isChecked())
- level |= QmlJSScriptConsole::Warning;
-
- if (m_showError->isChecked())
- level |= QmlJSScriptConsole::Error;
-
- m_console->setDebugLevel(level);
+ m_model->appendItem(ConsoleItemModel::UndefinedType, result);
}
void QmlJSScriptConsoleWidget::onEngineStateChanged(Debugger::DebuggerState state)
{
if (state == InferiorRunOk || state == InferiorStopOk) {
setEnabled(true);
- m_console->setInferiorStopped(state == InferiorStopOk);
+ m_consoleBackend->setInferiorStopped(state == InferiorStopOk);
} else {
setEnabled(false);
}
}
-///////////////////////////////////////////////////////////////////////
-//
-// QmlJSScriptConsole
-//
-///////////////////////////////////////////////////////////////////////
-
-QmlJSScriptConsole::QmlJSScriptConsole(QWidget *parent)
- : QPlainTextEdit(parent),
- d(new QmlJSScriptConsolePrivate())
-{
- connect(this, SIGNAL(cursorPositionChanged()), SLOT(onCursorPositionChanged()));
-
- setFrameStyle(QFrame::NoFrame);
- setUndoRedoEnabled(false);
- setBackgroundVisible(false);
- const TextEditor::FontSettings &fs = TextEditor::TextEditorSettings::instance()->fontSettings();
- setFont(fs.font());
-
- displayPrompt();
-}
-
-QmlJSScriptConsole::~QmlJSScriptConsole()
-{
- delete d;
-}
-
-void QmlJSScriptConsole::setPrompt(const QString &prompt)
-{
- d->prompt = prompt;
-}
-
-QString QmlJSScriptConsole::prompt() const
-{
- return d->prompt;
-}
-
-void QmlJSScriptConsole::setInferiorStopped(bool inferiorStopped)
-{
- d->inferiorStopped = inferiorStopped;
- onSelectionChanged();
-}
-
-void QmlJSScriptConsole::setEngine(QmlEngine *eng)
-{
- if (d->adapter) {
- disconnect(engine()->stackHandler(), SIGNAL(currentIndexChanged()), this, SLOT(onSelectionChanged()));
- disconnect(d->adapter, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
- disconnect(d->adapter->messageClient(), SIGNAL(message(QtMsgType,QString)),
- this, SLOT(insertDebugOutput(QtMsgType,QString)));
- d->adapter = 0;
- }
-
- if (eng) {
- d->adapter = eng->adapter();
- connect(eng->stackHandler(), SIGNAL(currentIndexChanged()), this, SLOT(onSelectionChanged()));
- connect(d->adapter, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
- connect(d->adapter->messageClient(), SIGNAL(message(QtMsgType,QString)),
- this, SLOT(insertDebugOutput(QtMsgType,QString)));
- }
-
- clear();
-}
-
-DebuggerEngine *QmlJSScriptConsole::engine() const
-{
- if (d->adapter)
- return d->adapter->debuggerEngine();
- return 0;
-}
-
-void QmlJSScriptConsole::appendResult(const QString &message, const QColor &color)
-{
- QTextCharFormat resultFormat;
- resultFormat.setForeground(color);
- QTextCursor cur = textCursor();
-
- cur.setPosition(d->startOfEditableArea - d->prompt.length());
- cur.insertText(message, resultFormat);
- cur.insertText(_("\n"));
-
- QList<QTextEdit::ExtraSelection> selections = extraSelections();
- QTextEdit::ExtraSelection sel;
- sel.format = resultFormat;
- sel.cursor = cur;
- selections.append(sel);
-
- setExtraSelections(selections);
-
- d->startOfEditableArea += message.length() + 1; //1 for new line character
-}
-
-void QmlJSScriptConsole::setDebugLevel(QFlags<DebugLevelFlag> level)
+void QmlJSScriptConsoleWidget::onSelectionChanged()
{
- d->debugLevel = level;
-}
-
-void QmlJSScriptConsole::clear()
-{
- QPlainTextEdit::clear();
- displayPrompt();
-}
+ QmlEngine *qmlEngine = m_consoleBackend->engine();
+ if (qmlEngine && qmlEngine->adapter()) {
+ const QString context = m_consoleBackend->inferiorStopped() ?
+ qmlEngine->stackHandler()->currentFrame().function :
+ qmlEngine->adapter()->currentSelectedDisplayName();
-void QmlJSScriptConsole::onStateChanged(QmlJsDebugClient::QDeclarativeDebugQuery::State state)
-{
- QDeclarativeDebugExpressionQuery *query = qobject_cast<QDeclarativeDebugExpressionQuery *>(sender());
-
- if (query && state != QDeclarativeDebugQuery::Error) {
- QString result(query->result().toString());
- if (result == _("<undefined>") && d->inferiorStopped) {
- //don't give up. check if we can still evaluate using javascript engine
- emit evaluateExpression(getCurrentScript());
- } else {
- appendResult(result);
- }
- } else {
- QPlainTextEdit::appendPlainText(QString());
- moveCursor(QTextCursor::EndOfLine);
+ m_consoleBackend->setIsValidContext(!context.isEmpty());
+ m_statusLabel->showStatusMessage(tr("Context: ").append(context), 0);
}
- delete query;
}
-void QmlJSScriptConsole::onSelectionChanged()
+void QmlJSScriptConsoleWidget::appendOutput(ConsoleItemModel::ItemType itemType,
+ const QString &message)
{
- if (d->adapter) {
- const QString context = d->inferiorStopped ?
- d->adapter->debuggerEngine()->stackHandler()->currentFrame().function :
- d->adapter->currentSelectedDisplayName();
+ if (itemType == ConsoleItemModel::UndefinedType)
+ return m_model->appendItem(itemType, message);
- d->hasContext = !context.isEmpty();
- emit updateStatusMessage(tr("Context: ").append(context), 0);
+ QtMsgType type;
+ switch (itemType) {
+ case ConsoleItemModel::LogType:
+ type = QtDebugMsg;
+ break;
+ case ConsoleItemModel::WarningType:
+ type = QtWarningMsg;
+ break;
+ case ConsoleItemModel::ErrorType:
+ type = QtCriticalMsg;
+ break;
+ default:
+ type = QtDebugMsg;
+ break;
}
+ appendMessage(type, message);
}
-void QmlJSScriptConsole::insertDebugOutput(QtMsgType type, const QString &debugMsg)
+void QmlJSScriptConsoleWidget::appendMessage(QtMsgType type, const QString &message)
{
- QColor color;
+ ConsoleItemModel::ItemType itemType;
switch (type) {
case QtDebugMsg:
- if (!(d->debugLevel & Log))
+ if (!m_showLogAction->isChecked())
return;
- color = QColor(Qt::darkBlue);
+ itemType = ConsoleItemModel::LogType;
break;
case QtWarningMsg:
- if (!(d->debugLevel & Warning))
+ if (!m_showWarningAction->isChecked())
return;
- color = QColor(Qt::darkYellow);
+ itemType = ConsoleItemModel::WarningType;
break;
case QtCriticalMsg:
- if (!(d->debugLevel & Error))
+ case QtFatalMsg:
+ if (!m_showErrorAction->isChecked())
return;
- color = QColor(Qt::darkRed);
+ itemType = ConsoleItemModel::ErrorType;
break;
default:
- color = QColor(Qt::black);
- }
- appendResult(debugMsg, color);
-}
-
-void QmlJSScriptConsole::keyPressEvent(QKeyEvent *e)
-{
- bool keyConsumed = false;
- switch (e->key()) {
-
- case Qt::Key_Return:
- case Qt::Key_Enter:
- if (isEditableArea()) {
- handleReturnKey();
- keyConsumed = true;
- }
- break;
-
- case Qt::Key_Backspace: {
- QTextCursor cursor = textCursor();
- bool hasSelection = cursor.hasSelection();
- int selectionStart = cursor.selectionStart();
- if ((hasSelection && selectionStart < d->startOfEditableArea)
- || (!hasSelection && selectionStart == d->startOfEditableArea)) {
- keyConsumed = true;
- }
- break;
- }
-
- case Qt::Key_Delete:
- if (textCursor().selectionStart() < d->startOfEditableArea) {
- keyConsumed = true;
- }
- break;
-
- case Qt::Key_Tab:
- case Qt::Key_Backtab:
- keyConsumed = true;
- break;
-
- case Qt::Key_Left:
- if (textCursor().position() == d->startOfEditableArea) {
- keyConsumed = true;
- } else if (e->modifiers() & Qt::ControlModifier && isEditableArea()) {
- handleHomeKey();
- keyConsumed = true;
- }
- break;
-
- case Qt::Key_Up:
- if (isEditableArea()) {
- handleUpKey();
- keyConsumed = true;
- }
- break;
-
- case Qt::Key_Down:
- if (isEditableArea()) {
- handleDownKey();
- keyConsumed = true;
- }
- break;
-
- case Qt::Key_Home:
- if (isEditableArea()) {
- handleHomeKey();
- keyConsumed = true;
- }
- break;
-
- case Qt::Key_C:
- case Qt::Key_Insert: {
- //Fair to assume that for any selection beyond startOfEditableArea
- //only copy function is allowed.
- QTextCursor cursor = textCursor();
- bool hasSelection = cursor.hasSelection();
- int selectionStart = cursor.selectionStart();
- if (hasSelection && selectionStart < d->startOfEditableArea) {
- if (!(e->modifiers() & Qt::ControlModifier))
- keyConsumed = true;
- }
- break;
- }
-
- default: {
- QTextCursor cursor = textCursor();
- bool hasSelection = cursor.hasSelection();
- int selectionStart = cursor.selectionStart();
- if (hasSelection && selectionStart < d->startOfEditableArea) {
- keyConsumed = true;
- }
- break;
+ //this cannot happen as type has to
+ //be one of the above
+ //return since itemType is not known
+ return;
}
- }
-
- if (!keyConsumed)
- QPlainTextEdit::keyPressEvent(e);
-}
-
-void QmlJSScriptConsole::contextMenuEvent(QContextMenuEvent *event)
-{
- QTextCursor cursor = textCursor();
- Qt::TextInteractionFlags flags = textInteractionFlags();
- bool hasSelection = cursor.hasSelection();
- int selectionStart = cursor.selectionStart();
- bool canBeEdited = true;
- if (hasSelection && selectionStart < d->startOfEditableArea) {
- canBeEdited = false;
- }
-
- QMenu *menu = new QMenu();
- QAction *a;
-
- if ((flags & Qt::TextEditable) && canBeEdited) {
- a = menu->addAction(tr("Cut"), this, SLOT(cut()));
- a->setEnabled(cursor.hasSelection());
- }
-
-
- a = menu->addAction(tr("Copy"), this, SLOT(copy()));
- a->setEnabled(cursor.hasSelection());
-
- if ((flags & Qt::TextEditable) && canBeEdited) {
- a = menu->addAction(tr("Paste"), this, SLOT(paste()));
- a->setEnabled(canPaste());
- }
-
- menu->addSeparator();
- a = menu->addAction(tr("Select All"), this, SLOT(selectAll()));
- a->setEnabled(!document()->isEmpty());
-
- menu->addSeparator();
- menu->addAction(tr("Clear"), this, SLOT(clear()));
-
- menu->exec(event->globalPos());
-
-
- delete menu;
-}
-
-void QmlJSScriptConsole::mouseReleaseEvent(QMouseEvent *e)
-{
- QPlainTextEdit::mouseReleaseEvent(e);
- QTextCursor cursor = textCursor();
- if (e->button() == Qt::LeftButton && !cursor.hasSelection() && !isEditableArea()) {
- cursor.setPosition(d->lastKnownPosition);
- setTextCursor(cursor);
- }
-}
-
-void QmlJSScriptConsole::onCursorPositionChanged()
-{
- if (!isEditableArea()) {
- setTextInteractionFlags(Qt::TextSelectableByMouse);
- } else {
- d->lastKnownPosition = textCursor().position();
- setTextInteractionFlags(Qt::TextEditorInteraction);
- }
-}
-
-void QmlJSScriptConsole::displayPrompt()
-{
- d->startOfEditableArea = textCursor().position() + d->prompt.length();
- QTextCursor cur = textCursor();
- cur.insertText(d->prompt);
- cur.movePosition(QTextCursor::EndOfWord);
- setTextCursor(cur);
-}
-
-void QmlJSScriptConsole::handleReturnKey()
-{
- QString currentScript = getCurrentScript();
- bool showPrompt = true;
- bool showInvalidContextError = false;
-
- //Check if string is only white spaces
- if (!currentScript.trimmed().isEmpty()) {
- //Check for a valid context
- if (d->hasContext) {
- //check if it can be evaluated
- if (d->canEvaluateScript(currentScript)) {
- //Evaluate expression based on engine state
- //When engine->state() == InferiorStopOk, the expression
- //is sent to V8DebugService. In all other cases, the
- //expression is evaluated by QDeclarativeEngine.
- if (!d->inferiorStopped) {
- QTC_ASSERT(d->adapter, return);
- QDeclarativeEngineDebug *engineDebug = d->adapter->engineDebugClient();
- int id = d->adapter->currentSelectedDebugId();
- if (engineDebug && id != -1) {
- QDeclarativeDebugExpressionQuery *query =
- engineDebug->queryExpressionResult(id, currentScript, this);
- connect(query, SIGNAL(stateChanged(QmlJsDebugClient::QDeclarativeDebugQuery::State)),
- this, SLOT(onStateChanged(QmlJsDebugClient::QDeclarativeDebugQuery::State)));
- }
- } else {
- emit evaluateExpression(currentScript);
- }
-
- d->appendToHistory(currentScript);
- } else {
- //The expression is not complete, wait for more input
- //Move to next line and do not show prompt
- QPlainTextEdit::appendPlainText(QString());
- moveCursor(QTextCursor::EndOfLine);
- showPrompt = false;
- }
- } else {
- //Incase of invalid context, append the expression to history
- //and show Error message
- d->appendToHistory(currentScript);
- showInvalidContextError = true;
- }
- }
-
- if (showPrompt) {
- QTextCursor cur = textCursor();
- cur.movePosition(QTextCursor::End);
- cur.insertText(_("\n"));
- setTextCursor(cur);
- displayPrompt();
- }
-
- //Show an error message
- if (showInvalidContextError)
- appendResult(QLatin1String("Cannot evaluate without a valid QML/JS Context"));
-}
-
-void QmlJSScriptConsole::handleUpKey()
-{
- //get the current script and update in script history
- QString currentScript = getCurrentScript();
- d->scriptHistory.replace(d->scriptHistoryIndex - 1,currentScript);
-
- if (d->scriptHistoryIndex > 1)
- d->scriptHistoryIndex--;
-
- replaceCurrentScript(d->scriptHistory.at(d->scriptHistoryIndex - 1));
-}
-
-void QmlJSScriptConsole::handleDownKey()
-{
- //get the current script and update in script history
- QString currentScript = getCurrentScript();
- d->scriptHistory.replace(d->scriptHistoryIndex - 1,currentScript);
-
- if (d->scriptHistoryIndex < d->scriptHistory.count())
- d->scriptHistoryIndex++;
-
- replaceCurrentScript(d->scriptHistory.at(d->scriptHistoryIndex - 1));
-}
-
-void QmlJSScriptConsole::handleHomeKey()
-{
- QTextCursor cursor = textCursor();
- cursor.setPosition(d->startOfEditableArea);
- setTextCursor(cursor);
-}
-
-QString QmlJSScriptConsole::getCurrentScript() const
-{
- QTextCursor cursor = textCursor();
- cursor.setPosition(d->startOfEditableArea);
- while (cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor)) ;
- QString script = cursor.selectedText();
- cursor.clearSelection();
- //remove trailing white space
- int end = script.size() - 1;
- while (end > 0 && script[end].isSpace())
- end--;
- return script.left(end + 1);
-}
-
-void QmlJSScriptConsole::replaceCurrentScript(const QString &script)
-{
- QTextCursor cursor = textCursor();
- cursor.setPosition(d->startOfEditableArea);
- while (cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor)) ;
- cursor.deleteChar();
- cursor.insertText(script);
- setTextCursor(cursor);
-}
-
-bool QmlJSScriptConsole::isEditableArea() const
-{
- return textCursor().position() >= d->startOfEditableArea;
+ m_model->appendItem(itemType, message);
}
} //Internal
diff --git a/src/plugins/debugger/qml/qmljsscriptconsole.h b/src/plugins/debugger/qml/qmljsscriptconsole.h
index aef7b72401..27997aebfa 100644
--- a/src/plugins/debugger/qml/qmljsscriptconsole.h
+++ b/src/plugins/debugger/qml/qmljsscriptconsole.h
@@ -33,16 +33,17 @@
#ifndef QMLJSSCRIPTCONSOLE_H
#define QMLJSSCRIPTCONSOLE_H
-#include <qmljsdebugclient/qdeclarativeenginedebug.h>
+#include "consoleitemmodel.h"
#include <debugger/debuggerconstants.h>
-#include <QPlainTextEdit>
+#include <QtGui/QWidget>
QT_BEGIN_NAMESPACE
-class QCheckBox;
+class QToolButton;
QT_END_NAMESPACE
namespace Utils {
class StatusLabel;
+class SavedAction;
}
namespace Debugger {
@@ -51,10 +52,9 @@ class DebuggerEngine;
namespace Internal {
-class QmlJSScriptConsolePrivate;
-class QmlJSScriptConsole;
-class QmlEngine;
-
+class ConsoleTreeView;
+class ConsoleItemDelegate;
+class QmlJSConsoleBackend;
class QmlJSScriptConsoleWidget : public QWidget
{
Q_OBJECT
@@ -63,90 +63,33 @@ public:
~QmlJSScriptConsoleWidget();
void setEngine(DebuggerEngine *engine);
+ void readSettings();
public slots:
+ void writeSettings() const;
void appendResult(const QString &result);
+ void appendOutput(ConsoleItemModel::ItemType, const QString &message);
+ void appendMessage(QtMsgType type, const QString &message);
signals:
void evaluateExpression(const QString &expr);
private slots:
- void setDebugLevel();
void onEngineStateChanged(Debugger::DebuggerState state);
-
-private:
- QmlJSScriptConsole *m_console;
- Utils::StatusLabel *m_statusLabel;
- QCheckBox *m_showLog;
- QCheckBox *m_showWarning;
- QCheckBox *m_showError;
-
-};
-
-class QmlJSScriptConsole : public QPlainTextEdit
-{
- Q_OBJECT
-
-public:
- enum DebugLevelFlag {
- None = 0,
- Log = 1,
- Warning = 2,
- Error = 4
- };
-
- explicit QmlJSScriptConsole(QWidget *parent = 0);
- ~QmlJSScriptConsole();
-
- inline void setTitle(const QString &title)
- { setDocumentTitle(title); }
-
- inline QString title() const
- { return documentTitle(); }
-
- void setPrompt(const QString &prompt);
- QString prompt() const;
-
- void setInferiorStopped(bool inferiorStopped);
-
- void setEngine(QmlEngine *engine);
- DebuggerEngine *engine() const;
-
- void appendResult(const QString &message, const QColor &color = QColor(Qt::darkGray));
-
- void setDebugLevel(QFlags<DebugLevelFlag> level);
-
-public slots:
- void clear();
- void onStateChanged(QmlJsDebugClient::QDeclarativeDebugQuery::State);
- void insertDebugOutput(QtMsgType type, const QString &debugMsg);
-
-protected:
- void keyPressEvent(QKeyEvent *e);
- void contextMenuEvent(QContextMenuEvent *event);
- void mouseReleaseEvent(QMouseEvent *e);
-
-signals:
- void evaluateExpression(const QString &expr);
- void updateStatusMessage(const QString &message, int timeoutMS);
-
-private slots:
void onSelectionChanged();
- void onCursorPositionChanged();
private:
- void displayPrompt();
- void handleReturnKey();
- void handleUpKey();
- void handleDownKey();
- void handleHomeKey();
- QString getCurrentScript() const;
- void replaceCurrentScript(const QString &script);
- bool isEditableArea() const;
-
-private:
- QmlJSScriptConsolePrivate *d;
- friend class QmlJSScriptConsolePrivate;
+ ConsoleTreeView *m_consoleView;
+ ConsoleItemModel *m_model;
+ ConsoleItemDelegate *m_itemDelegate;
+ QmlJSConsoleBackend *m_consoleBackend;
+ Utils::StatusLabel *m_statusLabel;
+ QToolButton *m_showLog;
+ QToolButton *m_showWarning;
+ QToolButton *m_showError;
+ Utils::SavedAction *m_showLogAction;
+ Utils::SavedAction *m_showWarningAction;
+ Utils::SavedAction *m_showErrorAction;
};
} //Internal