From 147396d764aff1b5ca5cf2a50b43efb37e02291c Mon Sep 17 00:00:00 2001 From: Aurindam Jana <aurindam.jana@nokia.com> Date: Wed, 15 Feb 2012 12:35:43 +0100 Subject: [PATCH] ScriptConsole: Refactor to QtMessageLogWindow Move QML/JS independent classes to common Debugger code. A Debugger Engine needs to override evaluateScriptExpression() to provide engine specific script evaluation. Change-Id: I02b23b380a3eb1b12003b30ded0b7d075e44dfed Reviewed-by: hjk <qthjk@ovi.com> --- src/plugins/debugger/consolewindow.cpp | 326 ---------------- src/plugins/debugger/debugger.pro | 18 +- src/plugins/debugger/debuggerconstants.h | 3 +- src/plugins/debugger/debuggercore.h | 1 + src/plugins/debugger/debuggerengine.cpp | 24 ++ src/plugins/debugger/debuggerengine.h | 4 + src/plugins/debugger/debuggermainwindow.cpp | 10 +- src/plugins/debugger/debuggerplugin.cpp | 39 +- src/plugins/debugger/qml/consolebackend.cpp | 179 --------- src/plugins/debugger/qml/consolebackend.h | 100 ----- src/plugins/debugger/qml/consoleitemmodel.cpp | 348 ----------------- src/plugins/debugger/qml/qml.pri | 17 +- src/plugins/debugger/qml/qmlcppengine.cpp | 11 + src/plugins/debugger/qml/qmlcppengine.h | 3 + src/plugins/debugger/qml/qmlengine.cpp | 121 +++++- src/plugins/debugger/qml/qmlengine.h | 8 +- .../debugger/qml/qmljsscriptconsole.cpp | 327 ---------------- .../debugger/qml/qmlv8debuggerclient.cpp | 13 +- .../debugger/qml/qscriptdebuggerclient.cpp | 2 +- ...nsoleeditor.cpp => qtmessagelogeditor.cpp} | 65 ++-- .../consoleeditor.h => qtmessagelogeditor.h} | 18 +- src/plugins/debugger/qtmessageloghandler.cpp | 352 ++++++++++++++++++ ...nsoleitemmodel.h => qtmessageloghandler.h} | 80 +++- ...egate.cpp => qtmessagelogitemdelegate.cpp} | 131 +++---- ...mdelegate.h => qtmessagelogitemdelegate.h} | 26 +- .../debugger/qtmessagelogproxymodel.cpp | 92 +++++ ...riptconsole.h => qtmessagelogproxymodel.h} | 69 ++-- ...nsoletreeview.cpp => qtmessagelogview.cpp} | 48 +-- .../consoletreeview.h => qtmessagelogview.h} | 12 +- src/plugins/debugger/qtmessagelogwindow.cpp | 223 +++++++++++ .../{consolewindow.h => qtmessagelogwindow.h} | 50 +-- 31 files changed, 1123 insertions(+), 1597 deletions(-) delete mode 100644 src/plugins/debugger/consolewindow.cpp delete mode 100644 src/plugins/debugger/qml/consolebackend.cpp delete mode 100644 src/plugins/debugger/qml/consolebackend.h delete mode 100644 src/plugins/debugger/qml/consoleitemmodel.cpp delete mode 100644 src/plugins/debugger/qml/qmljsscriptconsole.cpp rename src/plugins/debugger/{qml/consoleeditor.cpp => qtmessagelogeditor.cpp} (81%) rename src/plugins/debugger/{qml/consoleeditor.h => qtmessagelogeditor.h} (84%) create mode 100644 src/plugins/debugger/qtmessageloghandler.cpp rename src/plugins/debugger/{qml/consoleitemmodel.h => qtmessageloghandler.h} (54%) rename src/plugins/debugger/{qml/consoleitemdelegate.cpp => qtmessagelogitemdelegate.cpp} (67%) rename src/plugins/debugger/{qml/consoleitemdelegate.h => qtmessagelogitemdelegate.h} (91%) create mode 100644 src/plugins/debugger/qtmessagelogproxymodel.cpp rename src/plugins/debugger/{qml/qmljsscriptconsole.h => qtmessagelogproxymodel.h} (50%) rename src/plugins/debugger/{qml/consoletreeview.cpp => qtmessagelogview.cpp} (75%) rename src/plugins/debugger/{qml/consoletreeview.h => qtmessagelogview.h} (87%) create mode 100644 src/plugins/debugger/qtmessagelogwindow.cpp rename src/plugins/debugger/{consolewindow.h => qtmessagelogwindow.h} (65%) diff --git a/src/plugins/debugger/consolewindow.cpp b/src/plugins/debugger/consolewindow.cpp deleted file mode 100644 index 3d33f2557a9..00000000000 --- a/src/plugins/debugger/consolewindow.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/************************************************************************** -** -** 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 "consolewindow.h" -#include "logwindow.h" - -#include "debuggeractions.h" -#include "debuggercore.h" - -#include <QDebug> - -#include <QHBoxLayout> -#include <QVBoxLayout> -#include <QKeyEvent> -#include <QMenu> -#include <QSyntaxHighlighter> -#include <QPlainTextEdit> - -#include <aggregation/aggregate.h> -#include <coreplugin/findplaceholder.h> -#include <find/basetextfind.h> - -#include <utils/savedaction.h> - -namespace Debugger { -namespace Internal { - -///////////////////////////////////////////////////////////////////// -// -// ConsoleHighlighter -// -///////////////////////////////////////////////////////////////////// - -class ConsoleHighlighter : public QSyntaxHighlighter -{ -public: - ConsoleHighlighter(QPlainTextEdit *parent) - : QSyntaxHighlighter(parent->document()), m_parent(parent) - {} - -private: - void highlightBlock(const QString &text) - { - QTextCharFormat format; - switch (LogWindow::channelForChar(text.isEmpty() ? QChar() : text.at(0))) { - case LogInput: - format.setForeground(Qt::blue); - setFormat(1, text.size(), format); - break; - case LogStatus: - format.setForeground(Qt::darkGreen); - setFormat(1, text.size(), format); - break; - case LogWarning: - format.setForeground(Qt::darkYellow); - setFormat(1, text.size(), format); - break; - case LogError: - format.setForeground(Qt::red); - setFormat(1, text.size(), format); - break; - case LogTime: - format.setForeground(Qt::darkRed); - setFormat(1, text.size(), format); - break; - default: - break; - } - QColor base = m_parent->palette().color(QPalette::Base); - format.setForeground(base); - format.setFontPointSize(1); - setFormat(0, 1, format); -/* - if (text.size() > 3 && text.at(2) == QLatin1Char(':')) { - QTextCharFormat format; - format.setForeground(Qt::darkRed); - setFormat(1, text.size(), format); - } -*/ - } - - QPlainTextEdit *m_parent; -}; - -///////////////////////////////////////////////////////////////////// -// -// DebbuggerPane base class -// -///////////////////////////////////////////////////////////////////// - -// FIXME: Code duplication with FakeVim -class History -{ -public: - History() : m_index(0) {} - void append(const QString &item) { - m_items.removeAll(item); - m_items.append(item); m_index = m_items.size() - 1; - } - void down() { m_index = qMin(m_index + 1, m_items.size()); } - void up() { m_index = qMax(m_index - 1, 0); } - //void clear() { m_items.clear(); m_index = 0; } - void restart() { m_index = m_items.size(); } - QString current() const { return m_items.value(m_index, QString()); } - QStringList items() const { return m_items; } -private: - QStringList m_items; - int m_index; -}; - -class Console : public QPlainTextEdit -{ - Q_OBJECT - -public: - Console(QWidget *parent) - : QPlainTextEdit(parent) - { - setMaximumBlockCount(100000); - setFrameStyle(QFrame::NoFrame); - m_clearContentsAction = new QAction(this); - m_clearContentsAction->setText(tr("Clear Contents")); - m_clearContentsAction->setEnabled(true); - connect(m_clearContentsAction, SIGNAL(triggered(bool)), - parent, SLOT(clearContents())); - - m_saveContentsAction = new QAction(this); - m_saveContentsAction->setText(tr("Save Contents")); - m_saveContentsAction->setEnabled(true); - connect(m_saveContentsAction, SIGNAL(triggered()), this, SLOT(saveContents())); - } - - void contextMenuEvent(QContextMenuEvent *ev) - { - debuggerCore()->executeDebuggerCommand(textCursor().block().text()); - QMenu *menu = createStandardContextMenu(); - menu->addAction(m_clearContentsAction); - menu->addAction(m_saveContentsAction); // X11 clipboard is unreliable for long texts - menu->addAction(debuggerCore()->action(LogTimeStamps)); - menu->addAction(debuggerCore()->action(VerboseLog)); - menu->addSeparator(); - menu->addAction(debuggerCore()->action(SettingsDialog)); - menu->exec(ev->globalPos()); - delete menu; - } - - void keyPressEvent(QKeyEvent *ev) - { - if (ev->key() == Qt::Key_Return) { - if (ev->modifiers() == 0) { - QString cmd = textCursor().block().text(); - if (cmd.isEmpty()) - cmd = m_history.current(); - QString cleanCmd; - foreach (QChar c, cmd) - if (c.unicode() >= 32 && c.unicode() < 128) - cleanCmd.append(c); - if (!cleanCmd.isEmpty()) { - debuggerCore()->executeDebuggerCommand(cleanCmd); - m_history.append(cleanCmd); - } - } - QPlainTextEdit::keyPressEvent(ev); - } else if (ev->key() == Qt::Key_Up) { - m_history.up(); - } else if (ev->key() == Qt::Key_Down) { - m_history.down(); - } else { - QPlainTextEdit::keyPressEvent(ev); - } - } - - void mouseDoubleClickEvent(QMouseEvent *ev) - { - QString line = cursorForPosition(ev->pos()).block().text(); - int n = 0; - - // cut time string - if (line.size() > 18 && line.at(0) == QLatin1Char('[')) - line = line.mid(18); - //qDebug() << line; - - for (int i = 0; i != line.size(); ++i) { - QChar c = line.at(i); - if (!c.isDigit()) - break; - n = 10 * n + c.unicode() - '0'; - } - //emit commandSelected(n); - } - - -private slots: - void saveContents(); - -private: - QAction *m_clearContentsAction; - QAction *m_saveContentsAction; - History m_history; -}; - -void Console::saveContents() -{ - LogWindow::writeLogContents(this, this); -} - -///////////////////////////////////////////////////////////////////// -// -// ConsoleWindow -// -///////////////////////////////////////////////////////////////////// - -ConsoleWindow::ConsoleWindow(QWidget *parent) - : QWidget(parent) -{ - setWindowTitle(tr("Console")); - setObjectName(QLatin1String("Console")); - - m_console = new Console(this); - m_console->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - - QVBoxLayout *layout = new QVBoxLayout(this); - layout->setMargin(0); - layout->setSpacing(0); - layout->addWidget(m_console); - layout->addWidget(new Core::FindToolBarPlaceHolder(this)); - setLayout(layout); - - Aggregation::Aggregate *aggregate = new Aggregation::Aggregate; - aggregate->add(m_console); - aggregate->add(new Find::BaseTextFind(m_console)); - - //connect(m_console, SIGNAL(statusMessageRequested(QString,int)), - // this, SIGNAL(statusMessageRequested(QString,int))); -} - -void ConsoleWindow::showOutput(int channel, const QString &output) -{ - if (output.isEmpty()) - return; - //QTextCursor oldCursor = m_console->textCursor(); - //QTextCursor cursor = oldCursor; - //cursor.movePosition(QTextCursor::End); - //bool atEnd = oldCursor.position() == cursor.position(); - - foreach (QString line, output.split(QLatin1Char('\n'))) { - // FIXME: QTextEdit asserts on really long lines... - const int n = 30000; - if (line.size() > n) { - line.truncate(n); - line += QLatin1String(" [...] <cut off>"); - } - m_console->appendPlainText(LogWindow::charForChannel(channel) + line + QLatin1Char('\n')); - } - QTextCursor cursor = m_console->textCursor(); - cursor.movePosition(QTextCursor::End); - //if (atEnd) { - m_console->setTextCursor(cursor); - m_console->ensureCursorVisible(); - //} -} - -void ConsoleWindow::showInput(int channel, const QString &input) -{ - Q_UNUSED(channel) - m_console->appendPlainText(input); - QTextCursor cursor = m_console->textCursor(); - cursor.movePosition(QTextCursor::End); - m_console->setTextCursor(cursor); - m_console->ensureCursorVisible(); -} - -void ConsoleWindow::clearContents() -{ - m_console->clear(); -} - -void ConsoleWindow::setCursor(const QCursor &cursor) -{ - m_console->viewport()->setCursor(cursor); - QWidget::setCursor(cursor); -} - -QString ConsoleWindow::combinedContents() const -{ - return m_console->toPlainText(); -} - -QString ConsoleWindow::inputContents() const -{ - return m_console->toPlainText(); -} - -} // namespace Internal -} // namespace Debugger - -#include "consolewindow.moc" diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro index 40df0c389d6..733253a984b 100644 --- a/src/plugins/debugger/debugger.pro +++ b/src/plugins/debugger/debugger.pro @@ -23,7 +23,6 @@ HEADERS += \ breakpointmarker.h \ breakwindow.h \ commonoptionspage.h \ - consolewindow.h \ debugger_global.h \ debuggeractions.h \ debuggercore.h \ @@ -67,7 +66,13 @@ HEADERS += \ debuggertooltipmanager.h \ debuggertoolchaincombobox.h \ debuggersourcepathmappingwidget.h \ - memoryview.h + memoryview.h \ + qtmessagelogwindow.h \ + qtmessagelogeditor.h \ + qtmessagelogview.h \ + qtmessagelogproxymodel.h \ + qtmessagelogitemdelegate.h \ + qtmessageloghandler.h SOURCES += \ basewindow.cpp \ @@ -76,7 +81,6 @@ SOURCES += \ breakpointmarker.cpp \ breakwindow.cpp \ commonoptionspage.cpp \ - consolewindow.cpp \ debuggeractions.cpp \ debuggerdialogs.cpp \ debuggerengine.cpp \ @@ -113,7 +117,13 @@ SOURCES += \ debuggertooltipmanager.cpp \ debuggertoolchaincombobox.cpp \ debuggersourcepathmappingwidget.cpp \ - memoryview.cpp + memoryview.cpp \ + qtmessagelogwindow.cpp \ + qtmessagelogproxymodel.cpp \ + qtmessagelogview.cpp \ + qtmessagelogitemdelegate.cpp \ + qtmessageloghandler.cpp \ + qtmessagelogeditor.cpp FORMS += attachexternaldialog.ui \ attachcoredialog.ui \ diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h index db6616f209e..1367cbeb5bd 100644 --- a/src/plugins/debugger/debuggerconstants.h +++ b/src/plugins/debugger/debuggerconstants.h @@ -178,7 +178,8 @@ enum LogChannel AppError, // stderr AppStuff, // (possibly) windows debug channel StatusBar, // LogStatus and also put to the status bar - ScriptConsoleOutput + QtMessageLogOutput, + QtMessageLogStatus }; enum DebuggerEngineType diff --git a/src/plugins/debugger/debuggercore.h b/src/plugins/debugger/debuggercore.h index d050f52e054..d54b2cf4208 100644 --- a/src/plugins/debugger/debuggercore.h +++ b/src/plugins/debugger/debuggercore.h @@ -119,6 +119,7 @@ public: virtual void openMemoryEditor() = 0; virtual void languagesChanged() = 0; virtual void executeDebuggerCommand(const QString &command) = 0; + virtual bool evaluateScriptExpression(const QString &expression) = 0; virtual Utils::SavedAction *action(int code) const = 0; virtual bool boolSetting(int code) const = 0; diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 743e0c1350f..80efc3261e1 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -50,6 +50,7 @@ #include "stackhandler.h" #include "threadshandler.h" #include "watchhandler.h" +#include "qtmessageloghandler.h" #include <coreplugin/icore.h> #include <coreplugin/idocument.h> @@ -301,6 +302,7 @@ public: StackHandler m_stackHandler; ThreadsHandler m_threadsHandler; WatchHandler m_watchHandler; + QtMessageLogHandler m_qtMessageHandler; QFutureInterface<void> m_progress; DisassemblerAgent m_disassemblerAgent; @@ -434,6 +436,11 @@ WatchHandler *DebuggerEngine::watchHandler() const : &d->m_watchHandler; } +QtMessageLogHandler *DebuggerEngine::qtMessageLogHandler() const +{ + return &d->m_qtMessageHandler; +} + SourceFilesHandler *DebuggerEngine::sourceFilesHandler() const { return d->m_masterEngine @@ -513,6 +520,14 @@ QAbstractItemModel *DebuggerEngine::sourceFilesModel() const return model; } +QAbstractItemModel *DebuggerEngine::qtMessageLogModel() const +{ + QAbstractItemModel *model = qtMessageLogHandler()->model(); + if (model->objectName().isEmpty()) // Make debugging easier. + model->setObjectName(objectName() + QLatin1String("QtMessageLogModel")); + return model; +} + void DebuggerEngine::fetchMemory(MemoryAgent *, QObject *, quint64 addr, quint64 length) { @@ -541,6 +556,9 @@ void DebuggerEngine::showMessage(const QString &msg, int channel, int timeout) c } //if (msg.size() && msg.at(0).isUpper() && msg.at(1).isUpper()) // qDebug() << qPrintable(msg) << "IN STATE" << state(); + if (channel == QtMessageLogOutput) + qtMessageLogHandler()->appendMessage(QtMessageLogHandler::UndefinedType, msg); + debuggerCore()->showMessage(msg, channel, timeout); if (d->m_runControl) { d->m_runControl->showMessage(msg, channel); @@ -1617,6 +1635,12 @@ void DebuggerEngine::executeDebuggerCommand(const QString &) showStatusMessage(tr("This debugger cannot handle user input.")); } +bool DebuggerEngine::evaluateScriptExpression(const QString &) +{ + showStatusMessage(tr("This debugger cannot handle user input.")); + return false; +} + BreakHandler *DebuggerEngine::breakHandler() const { return debuggerCore()->breakHandler(); diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 312cb30e644..5c5eeedb58f 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -82,6 +82,7 @@ class BreakpointParameters; class QmlCppEngine; class DebuggerToolTipContext; class MemoryMarkup; +class QtMessageLogHandler; struct WatchUpdateFlags { @@ -224,6 +225,7 @@ public: virtual Internal::WatchHandler *watchHandler() const; virtual Internal::SourceFilesHandler *sourceFilesHandler() const; virtual Internal::BreakHandler *breakHandler() const; + virtual Internal::QtMessageLogHandler *qtMessageLogHandler() const; virtual QAbstractItemModel *modulesModel() const; virtual QAbstractItemModel *registerModel() const; @@ -234,6 +236,7 @@ public: virtual QAbstractItemModel *returnModel() const; virtual QAbstractItemModel *toolTipsModel() const; virtual QAbstractItemModel *sourceFilesModel() const; + virtual QAbstractItemModel *qtMessageLogModel() const; void progressPing(); void handleFinished(); @@ -361,6 +364,7 @@ protected: virtual void executeRunToFunction(const QString &functionName); virtual void executeJumpToLine(const Internal::ContextData &data); virtual void executeDebuggerCommand(const QString &command); + virtual bool evaluateScriptExpression(const QString &expression); virtual void frameUp(); virtual void frameDown(); diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp index c4486a624c8..db615a2c8ec 100644 --- a/src/plugins/debugger/debuggermainwindow.cpp +++ b/src/plugins/debugger/debuggermainwindow.cpp @@ -660,7 +660,7 @@ void DebuggerMainWindowPrivate::setSimpleDockWidgetArrangement() QDockWidget *threadsDock = q->dockWidget(QLatin1String(DOCKWIDGET_THREADS)); QDockWidget *outputDock = q->dockWidget(QLatin1String(DOCKWIDGET_OUTPUT)); QDockWidget *qmlInspectorDock = q->dockWidget(QLatin1String(DOCKWIDGET_QML_INSPECTOR)); - QDockWidget *scriptConsoleDock = q->dockWidget(QLatin1String(DOCKWIDGET_QML_SCRIPTCONSOLE)); + QDockWidget *consoleDock = q->dockWidget(QLatin1String(DOCKWIDGET_QML_SCRIPTCONSOLE)); QDockWidget *modulesDock = q->dockWidget(QLatin1String(DOCKWIDGET_MODULES)); QDockWidget *registerDock = q->dockWidget(QLatin1String(DOCKWIDGET_REGISTER)); QDockWidget *sourceFilesDock = q->dockWidget(QLatin1String(DOCKWIDGET_SOURCE_FILES)); @@ -671,7 +671,7 @@ void DebuggerMainWindowPrivate::setSimpleDockWidgetArrangement() QTC_ASSERT(snapshotsDock, return); QTC_ASSERT(threadsDock, return); QTC_ASSERT(outputDock, return); - QTC_ASSERT(scriptConsoleDock, return); + QTC_ASSERT(consoleDock, return); QTC_ASSERT(modulesDock, return); QTC_ASSERT(registerDock, return); QTC_ASSERT(sourceFilesDock, return); @@ -697,13 +697,13 @@ void DebuggerMainWindowPrivate::setSimpleDockWidgetArrangement() q->tabifyDockWidget(breakDock, threadsDock); q->tabifyDockWidget(breakDock, sourceFilesDock); q->tabifyDockWidget(breakDock, snapshotsDock); - q->tabifyDockWidget(breakDock, scriptConsoleDock); + q->tabifyDockWidget(breakDock, consoleDock); if (m_activeDebugLanguages.testFlag(Debugger::QmlLanguage)) { if (qmlInspectorDock) qmlInspectorDock->show(); - if (scriptConsoleDock) - scriptConsoleDock->show(); + if (consoleDock) + consoleDock->show(); } else { // CPP only threadsDock->show(); diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 60e9cbb8baf..b6a0cf6e75c 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -47,7 +47,7 @@ #include "breakpoint.h" #include "breakhandler.h" #include "breakwindow.h" -#include "consolewindow.h" +#include "qtmessagelogwindow.h" #include "disassemblerlines.h" #include "logwindow.h" #include "moduleswindow.h" @@ -114,8 +114,6 @@ #include <utils/statuslabel.h> #include <utils/fileutils.h> -#include <qml/qmljsscriptconsole.h> - #include <QTimer> #include <QtPlugin> #include <QComboBox> @@ -849,7 +847,7 @@ public slots: void aboutToSaveSession(); void executeDebuggerCommand(const QString &command); - void evaluateExpression(const QString &expression); + bool evaluateScriptExpression(const QString &expression); void coreShutdown(); #ifdef WITH_TESTS @@ -1172,7 +1170,7 @@ public: BreakWindow *m_breakWindow; BreakHandler *m_breakHandler; - //ConsoleWindow *m_consoleWindow; + QtMessageLogWindow *m_qtMessageLogWindow; QTreeView *m_returnWindow; QTreeView *m_localsWindow; QTreeView *m_watchersWindow; @@ -1183,7 +1181,6 @@ public: QAbstractItemView *m_stackWindow; QAbstractItemView *m_threadsWindow; LogWindow *m_logWindow; - QmlJSScriptConsoleWidget *m_scriptConsoleWindow; bool m_busy; QString m_lastPermanentStatusMessage; @@ -1237,7 +1234,7 @@ DebuggerPluginPrivate::DebuggerPluginPrivate(DebuggerPlugin *plugin) : m_stackWindow = 0; m_threadsWindow = 0; m_logWindow = 0; - m_scriptConsoleWindow = 0; + m_qtMessageLogWindow = 0; m_mainWindow = 0; m_snapshotHandler = 0; @@ -2096,8 +2093,7 @@ void DebuggerPluginPrivate::connectEngine(DebuggerEngine *engine) //m_threadBox->setModel(engine->threadsModel()); //m_threadBox->setModelColumn(ThreadData::ComboNameColumn); m_watchersWindow->setModel(engine->watchersModel()); - - m_scriptConsoleWindow->setEngine(engine); + m_qtMessageLogWindow->setModel(engine->qtMessageLogModel()); engine->watchHandler()->rebuildModel(); @@ -2219,7 +2215,7 @@ void DebuggerPluginPrivate::setInitialState() action(AutoDerefPointers)->setEnabled(true); action(ExpandStack)->setEnabled(false); - m_scriptConsoleWindow->setEnabled(false); + m_qtMessageLogWindow->setEnabled(true); } void DebuggerPluginPrivate::updateWatchersWindow() @@ -2519,9 +2515,9 @@ void DebuggerPluginPrivate::showStatusMessage(const QString &msg0, int timeout) m_statusLabel->showStatusMessage(msg, timeout); } -void DebuggerPluginPrivate::evaluateExpression(const QString &expression) +bool DebuggerPluginPrivate::evaluateScriptExpression(const QString &expression) { - currentEngine()->executeDebuggerCommand(expression); + return currentEngine()->evaluateScriptExpression(expression); } void DebuggerPluginPrivate::openMemoryEditor() @@ -2595,9 +2591,6 @@ void DebuggerPluginPrivate::showMessage(const QString &msg, int channel, int tim m_logWindow->showInput(LogInput, msg); m_logWindow->showOutput(LogInput, msg); break; - case ScriptConsoleOutput: - m_scriptConsoleWindow->appendResult(msg); - break; case LogError: { m_logWindow->showOutput(channel, msg); QAction *action = m_mainWindow->dockWidget(_(DOCKWIDGET_OUTPUT)) @@ -2606,6 +2599,10 @@ void DebuggerPluginPrivate::showMessage(const QString &msg, int channel, int tim action->trigger(); break; } + case QtMessageLogStatus: + QTC_ASSERT(m_qtMessageLogWindow, return); + m_qtMessageLogWindow->showStatus(msg, timeout); + break; default: m_logWindow->showOutput(channel, msg); break; @@ -2874,8 +2871,8 @@ void DebuggerPluginPrivate::extensionsInitialized() m_breakWindow->setObjectName(QLatin1String(DOCKWIDGET_BREAK)); m_breakWindow->setModel(m_breakHandler->model()); - //m_consoleWindow = new ConsoleWindow; - //m_consoleWindow->setObjectName(QLatin1String("CppDebugConsole")); + m_qtMessageLogWindow = new QtMessageLogWindow(); + m_qtMessageLogWindow->setObjectName(QLatin1String(DOCKWIDGET_QML_SCRIPTCONSOLE)); m_modulesWindow = new ModulesWindow; m_modulesWindow->setObjectName(QLatin1String(DOCKWIDGET_MODULES)); m_logWindow = new LogWindow; @@ -2894,11 +2891,6 @@ void DebuggerPluginPrivate::extensionsInitialized() m_localsWindow->setObjectName(QLatin1String("CppDebugLocals")); m_watchersWindow = new WatchWindow(WatchWindow::WatchersType); m_watchersWindow->setObjectName(QLatin1String("CppDebugWatchers")); - m_scriptConsoleWindow = new QmlJSScriptConsoleWidget; - m_scriptConsoleWindow->setWindowTitle(tr("QML Script Console")); - m_scriptConsoleWindow->setObjectName(QLatin1String(DOCKWIDGET_QML_SCRIPTCONSOLE)); - connect(m_scriptConsoleWindow, SIGNAL(evaluateExpression(QString)), - SLOT(evaluateExpression(QString))); // Snapshot m_snapshotHandler = new SnapshotHandler; @@ -3011,11 +3003,10 @@ void DebuggerPluginPrivate::extensionsInitialized() dock->setProperty(DOCKWIDGET_DEFAULT_AREA, Qt::TopDockWidgetArea); m_mainWindow->createDockWidget(CppLanguage, m_breakWindow); - //m_mainWindow->createDockWidget(CppLanguage, m_consoleWindow); + m_mainWindow->createDockWidget(QmlLanguage, m_qtMessageLogWindow); m_mainWindow->createDockWidget(CppLanguage, m_snapshotWindow); m_mainWindow->createDockWidget(CppLanguage, m_stackWindow); m_mainWindow->createDockWidget(CppLanguage, m_threadsWindow); - m_mainWindow->createDockWidget(QmlLanguage, m_scriptConsoleWindow); QSplitter *localsAndWatchers = new MiniSplitter(Qt::Vertical); localsAndWatchers->setObjectName(QLatin1String(DOCKWIDGET_WATCHERS)); diff --git a/src/plugins/debugger/qml/consolebackend.cpp b/src/plugins/debugger/qml/consolebackend.cpp deleted file mode 100644 index 0ffca2ad053..00000000000 --- a/src/plugins/debugger/qml/consolebackend.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/************************************************************************** -** -** 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 deleted file mode 100644 index dd24b427df6..00000000000 --- a/src/plugins/debugger/qml/consolebackend.h +++ /dev/null @@ -1,100 +0,0 @@ -/************************************************************************** -** -** 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/consoleitemmodel.cpp b/src/plugins/debugger/qml/consoleitemmodel.cpp deleted file mode 100644 index aaad6df3c8a..00000000000 --- a/src/plugins/debugger/qml/consoleitemmodel.cpp +++ /dev/null @@ -1,348 +0,0 @@ -/************************************************************************** -** -** 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/qml.pri b/src/plugins/debugger/qml/qml.pri index 74a8d2c3e89..5f458b085cc 100644 --- a/src/plugins/debugger/qml/qml.pri +++ b/src/plugins/debugger/qml/qml.pri @@ -6,29 +6,16 @@ HEADERS += \ $$PWD/qmldebuggerclient.h \ $$PWD/qmljsprivateapi.h \ $$PWD/qmlcppengine.h \ - $$PWD/qmljsscriptconsole.h \ $$PWD/qscriptdebuggerclient.h \ $$PWD/qmlv8debuggerclient.h \ $$PWD/interactiveinterpreter.h \ - $$PWD/qmlv8debuggerclientconstants.h \ - $$PWD/consoletreeview.h \ - $$PWD/consoleitemmodel.h \ - $$PWD/consoleitemdelegate.h \ - $$PWD/consoleeditor.h \ - $$PWD/consolebackend.h + $$PWD/qmlv8debuggerclientconstants.h SOURCES += \ $$PWD/qmlengine.cpp \ $$PWD/qmladapter.cpp \ $$PWD/qmldebuggerclient.cpp \ $$PWD/qmlcppengine.cpp \ - $$PWD/qmljsscriptconsole.cpp \ $$PWD/qscriptdebuggerclient.cpp \ $$PWD/qmlv8debuggerclient.cpp \ - $$PWD/interactiveinterpreter.cpp \ - $$PWD/consoletreeview.cpp \ - $$PWD/consoleitemmodel.cpp \ - $$PWD/consoleitemdelegate.cpp \ - $$PWD/consoleeditor.cpp \ - $$PWD/consolebackend.cpp - + $$PWD/interactiveinterpreter.cpp diff --git a/src/plugins/debugger/qml/qmlcppengine.cpp b/src/plugins/debugger/qml/qmlcppengine.cpp index a326ee3b5fb..17a820b0bd7 100644 --- a/src/plugins/debugger/qml/qmlcppengine.cpp +++ b/src/plugins/debugger/qml/qmlcppengine.cpp @@ -36,6 +36,7 @@ #include "debuggerstartparameters.h" #include "stackhandler.h" #include "qmlengine.h" +#include "qtmessageloghandler.h" #include <coreplugin/icore.h> #include <utils/qtcassert.h> @@ -426,6 +427,11 @@ void QmlCppEngine::executeDebuggerCommand(const QString &command) } } +bool QmlCppEngine::evaluateScriptExpression(const QString &expression) +{ + return d->m_qmlEngine->evaluateScriptExpression(expression); +} + ///////////////////////////////////////////////////////// void QmlCppEngine::setupEngine() @@ -811,6 +817,11 @@ void QmlCppEngine::resetLocation() DebuggerEngine::resetLocation(); } +Internal::QtMessageLogHandler *QmlCppEngine::qtMessageLogHandler() const +{ + return d->m_qmlEngine->qtMessageLogHandler(); +} + DebuggerEngine *QmlCppEngine::cppEngine() const { return d->m_cppEngine; diff --git a/src/plugins/debugger/qml/qmlcppengine.h b/src/plugins/debugger/qml/qmlcppengine.h index 8104eda4dd7..fb3b5c66e74 100644 --- a/src/plugins/debugger/qml/qmlcppengine.h +++ b/src/plugins/debugger/qml/qmlcppengine.h @@ -96,6 +96,8 @@ public: int timeout = -1) const; void resetLocation(); + Internal::QtMessageLogHandler *qtMessageLogHandler() const; + protected: void detachDebugger(); void executeStep(); @@ -112,6 +114,7 @@ protected: void executeRunToFunction(const QString &functionName); void executeJumpToLine(const ContextData &data); void executeDebuggerCommand(const QString &command); + bool evaluateScriptExpression(const QString &expression); void setupEngine(); void setupInferior(); diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index 7a7b72c128d..8c24aa0313d 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -32,6 +32,7 @@ #include "qmlengine.h" #include "qmladapter.h" +#include "interactiveinterpreter.h" #include "debuggerstartparameters.h" #include "debuggeractions.h" @@ -51,11 +52,13 @@ #include "watchhandler.h" #include "sourcefileshandler.h" #include "watchutils.h" +#include "qtmessageloghandler.h" #include <extensionsystem/pluginmanager.h> #include <projectexplorer/applicationlauncher.h> #include <qmljsdebugclient/qdeclarativeoutputparser.h> #include <qmljseditor/qmljseditorconstants.h> +#include <qmljsdebugclient/qdebugmessageclient.h> #include <utils/environment.h> #include <utils/qtcassert.h> @@ -112,10 +115,13 @@ private: QmlJsDebugClient::QDeclarativeOutputParser m_outputParser; QHash<QString, QTextDocument*> m_sourceDocuments; QHash<QString, QWeakPointer<TextEditor::ITextEditor> > m_sourceEditors; + InteractiveInterpreter m_interpreter; + bool m_validContext; }; QmlEnginePrivate::QmlEnginePrivate(QmlEngine *q) - : m_adapter(q) + : m_adapter(q), + m_validContext(false) {} @@ -145,6 +151,15 @@ QmlEngine::QmlEngine(const DebuggerStartParameters &startParameters, connect(&d->m_adapter, SIGNAL(connectionStartupFailed()), SLOT(connectionStartupFailed())); + connect(this, SIGNAL(stateChanged(Debugger::DebuggerState)), + SLOT(updateCurrentContext())); + connect(this->stackHandler(), SIGNAL(currentIndexChanged()), + SLOT(updateCurrentContext())); + connect(&d->m_adapter, SIGNAL(selectionChanged()), + SLOT(updateCurrentContext())); + connect(d->m_adapter.messageClient(), SIGNAL(message(QtMsgType,QString)), + SLOT(appendDebugOutput(QtMsgType,QString))); + connect(&d->m_applicationLauncher, SIGNAL(processExited(int)), SLOT(disconnected())); @@ -169,6 +184,8 @@ QmlEngine::QmlEngine(const DebuggerStartParameters &startParameters, d->m_noDebugOutputTimer.setSingleShot(true); d->m_noDebugOutputTimer.setInterval(8000); connect(&d->m_noDebugOutputTimer, SIGNAL(timeout()), this, SLOT(beginConnection())); + + qtMessageLogHandler()->setHasEditableRow(true); } QmlEngine::~QmlEngine() @@ -781,6 +798,23 @@ void QmlEngine::synchronizeWatchers() } } +void QmlEngine::onDebugQueryStateChanged( + QmlJsDebugClient::QDeclarativeDebugQuery::State state) +{ + QmlJsDebugClient::QDeclarativeDebugExpressionQuery *query = + qobject_cast<QmlJsDebugClient::QDeclarativeDebugExpressionQuery *>( + sender()); + if (query && state != QmlJsDebugClient::QDeclarativeDebugQuery::Error) + qtMessageLogHandler()-> + appendItem(new QtMessageLogItem(QtMessageLogHandler::UndefinedType, + query->result().toString())); + else + qtMessageLogHandler()-> + appendItem(new QtMessageLogItem(QtMessageLogHandler::ErrorType, + _("Error evaluating expression."))); + delete query; +} + bool QmlEngine::hasCapability(unsigned cap) const { return cap & (AddWatcherCapability @@ -828,6 +862,36 @@ void QmlEngine::wrongSetupMessageBoxFinished(int result) } } +void QmlEngine::updateCurrentContext() +{ + const QString context = state() == InferiorStopOk ? + stackHandler()->currentFrame().function : + d->m_adapter.currentSelectedDisplayName(); + d->m_validContext = !context.isEmpty(); + showMessage(tr("Context: ").append(context), QtMessageLogStatus); +} + +void QmlEngine::appendDebugOutput(QtMsgType type, const QString &message) +{ + QtMessageLogHandler::ItemType itemType; + switch (type) { + case QtDebugMsg: + itemType = QtMessageLogHandler::DebugType; + break; + case QtWarningMsg: + itemType = QtMessageLogHandler::WarningType; + break; + case QtCriticalMsg: + case QtFatalMsg: + itemType = QtMessageLogHandler::ErrorType; + break; + default: + //This case is not possible + return; + } + qtMessageLogHandler()->appendItem(new QtMessageLogItem(itemType, message)); +} + void QmlEngine::executeDebuggerCommand(const QString& command) { if (d->m_adapter.activeDebuggerClient()) { @@ -835,6 +899,54 @@ void QmlEngine::executeDebuggerCommand(const QString& command) } } +bool QmlEngine::evaluateScriptExpression(const QString& expression) +{ + bool didEvaluate = true; + //Check if string is only white spaces + if (!expression.trimmed().isEmpty()) { + //Check for a valid context + if (d->m_validContext) { + //check if it can be evaluated + if (canEvaluateScript(expression)) { + //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 (state() != InferiorStopOk) { + QDeclarativeEngineDebug *engineDebug = + d->m_adapter.engineDebugClient(); + + int id = d->m_adapter.currentSelectedDebugId(); + if (engineDebug && id != -1) { + QDeclarativeDebugExpressionQuery *query = + engineDebug->queryExpressionResult(id, expression); + connect(query, + SIGNAL(stateChanged( + QmlJsDebugClient::QDeclarativeDebugQuery + ::State)), + this, + SLOT(onDebugQueryStateChanged( + QmlJsDebugClient::QDeclarativeDebugQuery + ::State))); + } + } else { + executeDebuggerCommand(expression); + } + } else { + didEvaluate = false; + } + } else { + //Incase of invalid context, show Error message + qtMessageLogHandler()-> + appendItem(new QtMessageLogItem( + QtMessageLogHandler::ErrorType, + _("Cannot evaluate without" + "a valid QML/JS Context.")), + qtMessageLogHandler()->rowCount()); + } + } + return didEvaluate; +} QString QmlEngine::qmlImportPath() const { @@ -931,6 +1043,13 @@ void QmlEngine::updateEditor(Core::IEditor *editor, const QTextDocument *documen plainTextEdit->setReadOnly(true); } +bool QmlEngine::canEvaluateScript(const QString &script) +{ + d->m_interpreter.clearText(); + d->m_interpreter.appendText(script); + return d->m_interpreter.canEvaluate(); +} + QmlAdapter *QmlEngine::adapter() const { return &d->m_adapter; diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h index 69e0de76ba3..e3df9e9b9c1 100644 --- a/src/plugins/debugger/qml/qmlengine.h +++ b/src/plugins/debugger/qml/qmlengine.h @@ -34,7 +34,7 @@ #define DEBUGGER_QMLENGINE_H #include "debuggerengine.h" - +#include <qmljsdebugclient/qdeclarativeenginedebug.h> #include <utils/outputformat.h> #include <QAbstractSocket> @@ -96,6 +96,8 @@ private slots: void retryMessageBoxFinished(int result); void wrongSetupMessageBox(const QString &errorMessage); void wrongSetupMessageBoxFinished(int result); + void updateCurrentContext(); + void appendDebugOutput(QtMsgType type, const QString &message); private: // DebuggerEngine implementation. @@ -147,6 +149,7 @@ private: void updateWatchData(const WatchData &data, const WatchUpdateFlags &flags); void executeDebuggerCommand(const QString &command); + bool evaluateScriptExpression(const QString &expression); bool hasCapability(unsigned) const; @@ -163,6 +166,8 @@ private slots: void appendMessage(const QString &msg, Utils::OutputFormat); void synchronizeWatchers(); + void onDebugQueryStateChanged( + QmlJsDebugClient::QDeclarativeDebugQuery::State state); private: void closeConnection(); @@ -176,6 +181,7 @@ private: QString qmlImportPath() const; void updateEditor(Core::IEditor *editor, const QTextDocument *document); + bool canEvaluateScript(const QString &script); private: friend class QmlCppEngine; diff --git a/src/plugins/debugger/qml/qmljsscriptconsole.cpp b/src/plugins/debugger/qml/qmljsscriptconsole.cpp deleted file mode 100644 index 086ae12c751..00000000000 --- a/src/plugins/debugger/qml/qmljsscriptconsole.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/************************************************************************** -** -** 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 "qmljsscriptconsole.h" -#include "qmladapter.h" -#include "debuggerstringutils.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 <qmljsdebugclient/qdebugmessageclient.h> -#include <debugger/qml/qmlcppengine.h> -#include <debugger/qml/qmlengine.h> -#include <debugger/stackhandler.h> -#include <debugger/stackframe.h> - -#include <QMenu> -#include <QTextBlock> -#include <QHBoxLayout> -#include <QVBoxLayout> -#include <QToolButton> -#include <QCheckBox> - -static const char SCRIPT_CONSOLE[] = "ScriptConsole"; -static const char SHOW_LOG[] = "showLog"; -static const char SHOW_WARNING[] = "showWarning"; -static const char SHOW_ERROR[] = "showError"; - -namespace Debugger { -namespace Internal { - -/////////////////////////////////////////////////////////////////////// -// -// QmlJSScriptConsoleWidget -// -/////////////////////////////////////////////////////////////////////// - -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); - - 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); - - vbox->addWidget(statusbarContainer); - vbox->addWidget(m_consoleView); - - 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(); - m_showLogAction->writeSettings(settings); - m_showWarningAction->writeSettings(settings); - m_showErrorAction->writeSettings(settings); -} - -void QmlJSScriptConsoleWidget::setEngine(DebuggerEngine *engine) -{ - 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 = qobject_cast<QmlEngine *>(engine); - QmlCppEngine *qmlCppEngine = qobject_cast<QmlCppEngine *>(engine); - if (qmlCppEngine) - qmlEngine = qobject_cast<QmlEngine *>(qmlCppEngine->qmlEngine()); - - //Supports only QML 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_consoleBackend->setEngine(qmlEngine); -} - -void QmlJSScriptConsoleWidget::appendResult(const QString &result) -{ - m_model->appendItem(ConsoleItemModel::UndefinedType, result); -} - -void QmlJSScriptConsoleWidget::onEngineStateChanged(Debugger::DebuggerState state) -{ - if (state == InferiorRunOk || state == InferiorStopOk) { - setEnabled(true); - m_consoleBackend->setInferiorStopped(state == InferiorStopOk); - } else { - setEnabled(false); - } -} - -void QmlJSScriptConsoleWidget::onSelectionChanged() -{ - QmlEngine *qmlEngine = m_consoleBackend->engine(); - if (qmlEngine && qmlEngine->adapter()) { - const QString context = m_consoleBackend->inferiorStopped() ? - qmlEngine->stackHandler()->currentFrame().function : - qmlEngine->adapter()->currentSelectedDisplayName(); - - m_consoleBackend->setIsValidContext(!context.isEmpty()); - m_statusLabel->showStatusMessage(tr("Context: ").append(context), 0); - } -} - -void QmlJSScriptConsoleWidget::appendOutput(ConsoleItemModel::ItemType itemType, - const QString &message) -{ - if (itemType == ConsoleItemModel::UndefinedType) - return m_model->appendItem(itemType, message); - - 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 QmlJSScriptConsoleWidget::appendMessage(QtMsgType type, const QString &message) -{ - ConsoleItemModel::ItemType itemType; - switch (type) { - case QtDebugMsg: - if (!m_showLogAction->isChecked()) - return; - itemType = ConsoleItemModel::LogType; - break; - case QtWarningMsg: - if (!m_showWarningAction->isChecked()) - return; - itemType = ConsoleItemModel::WarningType; - break; - case QtCriticalMsg: - case QtFatalMsg: - if (!m_showErrorAction->isChecked()) - return; - itemType = ConsoleItemModel::ErrorType; - break; - default: - //this cannot happen as type has to - //be one of the above - //return since itemType is not known - return; - } - m_model->appendItem(itemType, message); -} - -} //Internal -} //Debugger diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp index 3cd5e08f408..0a30be2164c 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp @@ -1146,7 +1146,9 @@ void QmlV8DebuggerClient::assignValueInDebugger(const QByteArray /*expr*/, const if (stackHandler->isContentsValid() && stackHandler->currentFrame().isUsable()) { d->evaluate(expression, false, false, stackHandler->currentIndex()); } else { - d->engine->showMessage(QString(_("Cannot evaluate %1 in current stack frame")).arg(expression), ScriptConsoleOutput); + d->engine->showMessage(QString(_("Cannot evaluate" + "%1 in current stack frame")). + arg(expression), QtMessageLogOutput); } } @@ -1163,8 +1165,9 @@ void QmlV8DebuggerClient::executeDebuggerCommand(const QString &command) d->evaluatingExpression.insert(d->sequence, command); } else { //Currently cannot evaluate if not in a javascript break - d->engine->showMessage(QString(_("Cannot evaluate %1 in current stack frame")).arg(command), ScriptConsoleOutput); - // d->evaluate(command); + d->engine->showMessage(QString(_("Cannot evaluate %1" + "in current stack frame")). + arg(command), QtMessageLogOutput); } } @@ -1825,7 +1828,7 @@ void QmlV8DebuggerClient::updateEvaluationResult(int sequence, bool success, con d->engine->watchHandler()->endCycle(); } else { - d->engine->showMessage(body.value.toString(), ScriptConsoleOutput); + d->engine->showMessage(body.value.toString(), QtMessageLogOutput); //Update the locals foreach (int index, d->currentFrameScopes) d->scope(index); @@ -2014,7 +2017,7 @@ void QmlV8DebuggerClient::highlightExceptionCode(int lineNumber, QString message = QString(_("%1: %2: %3")).arg(filePath).arg(lineNumber) .arg(errorMessage); - d->engine->showMessage(message, ScriptConsoleOutput); + d->engine->showMessage(message, QtMessageLogOutput); } } } diff --git a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp index 8469d20af6f..c62c976844d 100644 --- a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp +++ b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp @@ -519,7 +519,7 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data) if (iname.startsWith("watch.")) { d->engine->watchHandler()->insertData(data); } else if (iname == "console") { - d->engine->showMessage(data.value, ScriptConsoleOutput); + d->engine->showMessage(data.value, QtMessageLogOutput); } else { qWarning() << "QmlEngine: Unexcpected result: " << iname << data.value; } diff --git a/src/plugins/debugger/qml/consoleeditor.cpp b/src/plugins/debugger/qtmessagelogeditor.cpp similarity index 81% rename from src/plugins/debugger/qml/consoleeditor.cpp rename to src/plugins/debugger/qtmessagelogeditor.cpp index 65b03e71a8c..2d95d4caf1f 100644 --- a/src/plugins/debugger/qml/consoleeditor.cpp +++ b/src/plugins/debugger/qtmessagelogeditor.cpp @@ -30,15 +30,15 @@ ** **************************************************************************/ -#include "consoleeditor.h" -#include "consoleitemmodel.h" -#include "consoleitemdelegate.h" -#include "consolebackend.h" - +#include "qtmessagelogeditor.h" +#include "qtmessageloghandler.h" #include "debuggerstringutils.h" +#include "debuggercore.h" +#include "debuggerengine.h" #include <utils/qtcassert.h> +#include <QUrl> #include <QMenu> #include <QKeyEvent> @@ -47,56 +47,47 @@ namespace Internal { /////////////////////////////////////////////////////////////////////// // -// ConsoleEditor +// QtMessageLogEditor // /////////////////////////////////////////////////////////////////////// -ConsoleEditor::ConsoleEditor(const QModelIndex &index, - ConsoleBackend *backend, +QtMessageLogEditor::QtMessageLogEditor(const QModelIndex &index, QWidget *parent) : QTextEdit(parent), - m_consoleBackend(backend), m_historyIndex(index), - m_prompt(QLatin1String(":/debugger/images/prompt.png")), + m_prompt(_(":/debugger/images/prompt.png")), m_startOfEditableArea(0) { setFrameStyle(QFrame::NoFrame); setUndoRedoEnabled(false); setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); document()->addResource(QTextDocument::ImageResource, - QUrl(QLatin1String("prompt")), m_prompt); + QUrl(_("prompt")), m_prompt); QTextImageFormat format; - format.setName(QLatin1String("prompt")); + format.setName(_("prompt")); format.setHeight(9); format.setWidth(9); textCursor().insertImage(format); - textCursor().insertText(QLatin1String(" ")); + textCursor().insertText(_(" ")); m_startOfEditableArea = textCursor().position(); ensureCursorVisible(); setTextInteractionFlags(Qt::TextEditorInteraction); } -void ConsoleEditor::keyPressEvent(QKeyEvent *e) +void QtMessageLogEditor::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 { + case Qt::Key_Enter: { + keyConsumed = debuggerCore()->evaluateScriptExpression(getCurrentScript()); + if (keyConsumed) { emit editingFinished(); - emit appendEditableRow(); - keyConsumed = true; + debuggerCore()->currentEngine()->qtMessageLogHandler()->appendEditableRow(); } + } break; case Qt::Key_Backspace: @@ -171,7 +162,7 @@ void ConsoleEditor::keyPressEvent(QKeyEvent *e) QTextEdit::keyPressEvent(e); } -void ConsoleEditor::contextMenuEvent(QContextMenuEvent *event) +void QtMessageLogEditor::contextMenuEvent(QContextMenuEvent *event) { QTextCursor cursor = textCursor(); bool editable = cursor.position() > m_startOfEditableArea; @@ -199,12 +190,12 @@ void ConsoleEditor::contextMenuEvent(QContextMenuEvent *event) delete menu; } -void ConsoleEditor::focusOutEvent(QFocusEvent * /*e*/) +void QtMessageLogEditor::focusOutEvent(QFocusEvent * /*e*/) { emit editingFinished(); } -void ConsoleEditor::handleUpKey() +void QtMessageLogEditor::handleUpKey() { QTC_ASSERT(m_historyIndex.isValid(), return); int currentRow = m_historyIndex.row(); @@ -216,9 +207,8 @@ void ConsoleEditor::handleUpKey() currentRow--; if (model->hasIndex(currentRow, 0)) { QModelIndex index = model->index(currentRow, 0); - if (ConsoleItemModel::InputType == - (ConsoleItemModel::ItemType)model->data( - index, ConsoleItemModel::TypeRole).toInt()) { + if (QtMessageLogHandler::InputType == (QtMessageLogHandler::ItemType)model->data( + index, QtMessageLogHandler::TypeRole).toInt()) { m_historyIndex = index; replaceCurrentScript(model->data( index, Qt::DisplayRole). @@ -229,7 +219,7 @@ void ConsoleEditor::handleUpKey() } } -void ConsoleEditor::handleDownKey() +void QtMessageLogEditor::handleDownKey() { QTC_ASSERT(m_historyIndex.isValid(), return); int currentRow = m_historyIndex.row(); @@ -238,9 +228,8 @@ void ConsoleEditor::handleDownKey() currentRow++; if (model->hasIndex(currentRow, 0)) { QModelIndex index = model->index(currentRow, 0); - if (ConsoleItemModel::InputType == - (ConsoleItemModel::ItemType)model->data( - index, ConsoleItemModel::TypeRole).toInt()) { + if (QtMessageLogHandler::InputType == (QtMessageLogHandler::ItemType)model->data( + index, QtMessageLogHandler::TypeRole).toInt()) { m_historyIndex = index; if (currentRow == model->rowCount() - 1) replaceCurrentScript(m_cachedScript); @@ -254,7 +243,7 @@ void ConsoleEditor::handleDownKey() } } -QString ConsoleEditor::getCurrentScript() const +QString QtMessageLogEditor::getCurrentScript() const { QTextCursor cursor = textCursor(); cursor.setPosition(m_startOfEditableArea); @@ -264,7 +253,7 @@ QString ConsoleEditor::getCurrentScript() const return script.trimmed(); } -void ConsoleEditor::replaceCurrentScript(const QString &script) +void QtMessageLogEditor::replaceCurrentScript(const QString &script) { QTextCursor cursor = textCursor(); cursor.setPosition(m_startOfEditableArea); diff --git a/src/plugins/debugger/qml/consoleeditor.h b/src/plugins/debugger/qtmessagelogeditor.h similarity index 84% rename from src/plugins/debugger/qml/consoleeditor.h rename to src/plugins/debugger/qtmessagelogeditor.h index b9745496d59..4a1121c941b 100644 --- a/src/plugins/debugger/qml/consoleeditor.h +++ b/src/plugins/debugger/qtmessagelogeditor.h @@ -30,24 +30,20 @@ ** **************************************************************************/ -#ifndef CONSOLEEDITOR_H -#define CONSOLEEDITOR_H +#ifndef QTMESSAGELOGEDITOR_H +#define QTMESSAGELOGEDITOR_H -#include "consoleitemmodel.h" - -#include <QTextEdit> #include <QModelIndex> +#include <QTextEdit> namespace Debugger { namespace Internal { -class ConsoleBackend; -class ConsoleEditor : public QTextEdit +class QtMessageLogEditor : public QTextEdit { Q_OBJECT public: - explicit ConsoleEditor(const QModelIndex &index, - ConsoleBackend *backend = 0, + explicit QtMessageLogEditor(const QModelIndex &index, QWidget *parent = 0); QString getCurrentScript() const; @@ -59,7 +55,6 @@ protected: signals: void editingFinished(); - void appendEditableRow(); protected: void handleUpKey(); @@ -68,7 +63,6 @@ protected: void replaceCurrentScript(const QString &script); private: - ConsoleBackend *m_consoleBackend; QModelIndex m_historyIndex; QString m_cachedScript; QImage m_prompt; @@ -78,4 +72,4 @@ private: } //Internal } //Debugger -#endif // CONSOLEEDITOR_H +#endif // QTMESSAGELOGEDITOR_H diff --git a/src/plugins/debugger/qtmessageloghandler.cpp b/src/plugins/debugger/qtmessageloghandler.cpp new file mode 100644 index 00000000000..a9bf672ea69 --- /dev/null +++ b/src/plugins/debugger/qtmessageloghandler.cpp @@ -0,0 +1,352 @@ +/************************************************************************** +** +** 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 "qtmessageloghandler.h" + +namespace Debugger { +namespace Internal { + +/////////////////////////////////////////////////////////////////////// +// +// QtMessageLogItem +// +/////////////////////////////////////////////////////////////////////// + +QtMessageLogItem::QtMessageLogItem(QtMessageLogHandler::ItemType itemType, + const QString &text, QtMessageLogItem *parent) + : m_text(text), + m_itemType(itemType), + m_parentItem(parent) + +{ +} + +QtMessageLogItem::~QtMessageLogItem() +{ + qDeleteAll(m_childItems); +} + +QtMessageLogItem *QtMessageLogItem::child(int number) +{ + return m_childItems.value(number); +} + +int QtMessageLogItem::childCount() const +{ + return m_childItems.count(); +} + +int QtMessageLogItem::childNumber() const +{ + if (m_parentItem) + return m_parentItem->m_childItems.indexOf(const_cast<QtMessageLogItem *>(this)); + + return 0; +} + +QString QtMessageLogItem::text() const +{ + return m_text; +} + +QtMessageLogHandler::ItemType QtMessageLogItem::itemType() const +{ + return m_itemType; +} +\ +bool QtMessageLogItem::insertChildren(int position, int count) +{ + if (position < 0 || position > m_childItems.size()) + return false; + + for (int row = 0; row < count; ++row) { + QtMessageLogItem *item = new QtMessageLogItem(QtMessageLogHandler::UndefinedType, QString(), this); + m_childItems.insert(position, item); + } + + return true; +} + +bool QtMessageLogItem::insertChild(int position, QtMessageLogItem *item) +{ + if (position < 0 || position > m_childItems.size()) + return false; + + if (item->parent()) + item->parent()->detachChild(item->childNumber()); + + item->m_parentItem = this; + m_childItems.insert(position, item); + + return true; +} + +QtMessageLogItem *QtMessageLogItem::parent() +{ + return m_parentItem; +} + +bool QtMessageLogItem::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 QtMessageLogItem::detachChild(int position) +{ + if (position < 0 || position > m_childItems.size()) + return false; + + m_childItems.removeAt(position); + + return true; +} + +bool QtMessageLogItem::setText(const QString &text) +{ + m_text = text; + return true; +} + +bool QtMessageLogItem::setItemType(QtMessageLogHandler::ItemType itemType) +{ + m_itemType = itemType; + return true; +} + +/////////////////////////////////////////////////////////////////////// +// +// QtMessageLogHandler +// +/////////////////////////////////////////////////////////////////////// + +QtMessageLogHandler::QtMessageLogHandler(QObject *parent) : + QAbstractItemModel(parent), + m_hasEditableRow(false), + m_rootItem(new QtMessageLogItem()) +{ +} + +QtMessageLogHandler::~QtMessageLogHandler() +{ + delete m_rootItem; +} + +void QtMessageLogHandler::clear() +{ + beginResetModel(); + reset(); + delete m_rootItem; + m_rootItem = new QtMessageLogItem(); + endResetModel(); + + if (m_hasEditableRow) + appendEditableRow(); +} + +bool QtMessageLogHandler::appendItem(QtMessageLogItem *item, int position) +{ + if (position < 0) + position = m_rootItem->childCount() - 1; + + beginInsertRows(QModelIndex(), position, position); + bool success = m_rootItem->insertChild(position, item); + endInsertRows(); + + return success; +} + +bool QtMessageLogHandler::appendMessage(QtMessageLogHandler::ItemType itemType, + const QString &message, int position) +{ + return appendItem(new QtMessageLogItem(itemType, message), position); +} + +void QtMessageLogHandler::setHasEditableRow(bool hasEditableRow) +{ + if (m_hasEditableRow && !hasEditableRow) + removeEditableRow(); + + if (!m_hasEditableRow && hasEditableRow) + appendEditableRow(); + + m_hasEditableRow = hasEditableRow; +} + +bool QtMessageLogHandler::hasEditableRow() const +{ + return m_hasEditableRow; +} + +void QtMessageLogHandler::appendEditableRow() +{ + int position = m_rootItem->childCount(); + if (appendItem(new QtMessageLogItem(QtMessageLogHandler::InputType), position)) + emit selectEditableRow(index(position, 0), + QItemSelectionModel::ClearAndSelect); +} + +void QtMessageLogHandler::removeEditableRow() +{ + if (m_rootItem->child(m_rootItem->childCount() - 1)->itemType() == QtMessageLogHandler::InputType) + removeRow(m_rootItem->childCount() - 1); +} + +QVariant QtMessageLogHandler::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + QtMessageLogItem *item = getItem(index); + + if (role == Qt::DisplayRole ) + return item->text(); + else if (role == QtMessageLogHandler::TypeRole) + return int(item->itemType()); + else + return QVariant(); +} + +QModelIndex QtMessageLogHandler::index(int row, int column, + const QModelIndex &parent) const +{ + if (parent.isValid() && parent.column() != 0) + return QModelIndex(); + + if (column > 0) + return QModelIndex(); + + QtMessageLogItem *parentItem = getItem(parent); + + QtMessageLogItem *childItem = parentItem->child(row); + if (childItem) + return createIndex(row, column, childItem); + else + return QModelIndex(); +} + +QModelIndex QtMessageLogHandler::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + QtMessageLogItem *childItem = getItem(index); + QtMessageLogItem *parentItem = childItem->parent(); + + if (parentItem == m_rootItem) + return QModelIndex(); + + return createIndex(parentItem->childNumber(), 0, parentItem); +} + +int QtMessageLogHandler::rowCount(const QModelIndex &parent) const +{ + QtMessageLogItem *parentItem = getItem(parent); + + return parentItem->childCount(); +} + +int QtMessageLogHandler::columnCount(const QModelIndex & /* parent */) const +{ + return 1; +} + +Qt::ItemFlags QtMessageLogHandler::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return 0; + + QtMessageLogItem *item = getItem(index); + if (m_hasEditableRow && item->parent() == m_rootItem + && index.row() == m_rootItem->childCount() - 1) + return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +bool QtMessageLogHandler::setData(const QModelIndex &index, const QVariant &value, + int role) +{ + QtMessageLogItem *item = getItem(index); + bool result = false; + if (role == Qt::DisplayRole ) + result = item->setText(value.toString()); + else if (role == QtMessageLogHandler::TypeRole) + result = item->setItemType((QtMessageLogHandler::ItemType)value.toInt()); + else if (value.canConvert(QVariant::String)) + result = item->setText(value.toString()); + + if (result) + emit dataChanged(index, index); + + return result; +} + +bool QtMessageLogHandler::insertRows(int position, int rows, const QModelIndex &parent) +{ + QtMessageLogItem *parentItem = getItem(parent); + bool success; + + beginInsertRows(parent, position, position + rows - 1); + success = parentItem->insertChildren(position, rows); + endInsertRows(); + + return success; +} + +bool QtMessageLogHandler::removeRows(int position, int rows, const QModelIndex &parent) +{ + QtMessageLogItem *parentItem = getItem(parent); + bool success = true; + + beginRemoveRows(parent, position, position + rows - 1); + success = parentItem->removeChildren(position, rows); + endRemoveRows(); + + return success; +} + +QtMessageLogItem *QtMessageLogHandler::getItem(const QModelIndex &index) const +{ + if (index.isValid()) { + QtMessageLogItem *item = static_cast<QtMessageLogItem*>(index.internalPointer()); + if (item) return item; + } + return m_rootItem; +} + +} //Internal +} //Debugger diff --git a/src/plugins/debugger/qml/consoleitemmodel.h b/src/plugins/debugger/qtmessageloghandler.h similarity index 54% rename from src/plugins/debugger/qml/consoleitemmodel.h rename to src/plugins/debugger/qtmessageloghandler.h index 7f0ce194c61..f83ea3d2c92 100644 --- a/src/plugins/debugger/qml/consoleitemmodel.h +++ b/src/plugins/debugger/qtmessageloghandler.h @@ -30,8 +30,8 @@ ** **************************************************************************/ -#ifndef CONSOLEITEMMODEL_H -#define CONSOLEITEMMODEL_H +#ifndef QTMESSAGELOGHANDLER_H +#define QTMESSAGELOGHANDLER_H #include <QAbstractItemModel> #include <QItemSelectionModel> @@ -39,29 +39,48 @@ namespace Debugger { namespace Internal { -class ConsoleItem; -class ConsoleItemModel : public QAbstractItemModel +class QtMessageLogItem; +class QtMessageLogHandler : public QAbstractItemModel { Q_OBJECT public: - enum ItemType { InputType, LogType, WarningType, ErrorType, - UndefinedType //Can be used for unknown and for Return values - }; + enum ItemType + { + InputType = 0x01, + DebugType = 0x02, + WarningType = 0x04, + ErrorType = 0x08, + UndefinedType = 0x10, //Can be used for unknown and for Return values + DefaultTypes = InputType | UndefinedType + }; + Q_DECLARE_FLAGS(ItemTypes, ItemType) + enum Roles { TypeRole = Qt::UserRole }; - explicit ConsoleItemModel(QObject *parent = 0); - ~ConsoleItemModel(); + explicit QtMessageLogHandler(QObject *parent = 0); + ~QtMessageLogHandler(); + + void setHasEditableRow(bool hasEditableRow); + bool hasEditableRow() const; + void appendEditableRow(); + void removeEditableRow(); + + bool appendItem(QtMessageLogItem *item, int position = -1); + bool appendMessage(QtMessageLogHandler::ItemType itemType, + const QString &message, int position = -1); + + QAbstractItemModel *model() { return this; } - void appendItem(ItemType,QString); + int rowCount(const QModelIndex &parent = QModelIndex()) const; public slots: void clear(); - void appendEditableRow(); signals: - void editableRowAppended(const QModelIndex &index, + void selectEditableRow(const QModelIndex &index, QItemSelectionModel::SelectionFlags flags); + void rowInserted(const QModelIndex &index); protected: QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; @@ -70,7 +89,7 @@ protected: 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; @@ -82,13 +101,42 @@ protected: bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); - ConsoleItem *getItem(const QModelIndex &index) const; + QtMessageLogItem *getItem(const QModelIndex &index) const; private: - ConsoleItem *m_rootItem; + bool m_hasEditableRow; + QtMessageLogItem *m_rootItem; }; +class QtMessageLogItem + { + public: + QtMessageLogItem(QtMessageLogHandler::ItemType type = QtMessageLogHandler::UndefinedType, + const QString &data = QString(), + QtMessageLogItem *parent = 0); + ~QtMessageLogItem(); + + QtMessageLogItem *child(int number); + int childCount() const; + QString text() const; + QtMessageLogHandler::ItemType itemType() const; + bool insertChildren(int position, int count); + bool insertChild(int position, QtMessageLogItem *item); + QtMessageLogItem *parent(); + bool removeChildren(int position, int count); + bool detachChild(int position); + int childNumber() const; + bool setText(const QString &text); + bool setItemType(QtMessageLogHandler::ItemType itemType); + + private: + QList<QtMessageLogItem *> m_childItems; + QString m_text; + QtMessageLogHandler::ItemType m_itemType; + QtMessageLogItem *m_parentItem; + }; + } //Internal } //Debugger -#endif // CONSOLEITEMMODEL_H +#endif // QTMESSAGELOGHANDLER_H diff --git a/src/plugins/debugger/qml/consoleitemdelegate.cpp b/src/plugins/debugger/qtmessagelogitemdelegate.cpp similarity index 67% rename from src/plugins/debugger/qml/consoleitemdelegate.cpp rename to src/plugins/debugger/qtmessagelogitemdelegate.cpp index 1971f8b3a5a..b08ab5e45ce 100644 --- a/src/plugins/debugger/qml/consoleitemdelegate.cpp +++ b/src/plugins/debugger/qtmessagelogitemdelegate.cpp @@ -30,91 +30,90 @@ ** **************************************************************************/ -#include "consoleitemdelegate.h" -#include "consoleeditor.h" -#include "qmlengine.h" +#include "qtmessagelogitemdelegate.h" +#include "qtmessagelogeditor.h" +#include "qtmessageloghandler.h" #include <QPainter> #include <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_LOG_BACKGROUND_COLOR[] = "#E8EEF2"; +const char CONSOLE_WARNING_BACKGROUND_COLOR[] = "#F6F4EB"; +const char CONSOLE_ERROR_BACKGROUND_COLOR[] = "#F6EBE7"; const char CONSOLE_EDITOR_BACKGROUND_COLOR[] = "#F7F7F7"; +const char CONSOLE_LOG_BACKGROUND_SELECTED_COLOR[] = "#CDDEEA"; +const char CONSOLE_WARNING_BACKGROUND_SELECTED_COLOR[] = "#F3EED1"; +const char CONSOLE_ERROR_BACKGROUND_SELECTED_COLOR[] = "#F5D4CB"; +const char CONSOLE_EDITOR_BACKGROUND_SELECTED_COLOR[] = "#DEDEDE"; + 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; +const char CONSOLE_BORDER_COLOR[] = "#C9C9C9"; namespace Debugger { namespace Internal { /////////////////////////////////////////////////////////////////////// // -// ConsoleItemDelegate +// QtMessageLogItemDelegate // /////////////////////////////////////////////////////////////////////// -ConsoleItemDelegate::ConsoleItemDelegate(QObject *parent) : +QtMessageLogItemDelegate::QtMessageLogItemDelegate(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) + m_prompt(QLatin1String(":/debugger/images/prompt.png")) { } -void ConsoleItemDelegate::emitSizeHintChanged(const QModelIndex &index) +void QtMessageLogItemDelegate::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, +void QtMessageLogItemDelegate::drawBackground(QPainter *painter, const QRect &rect, + const QModelIndex &index, bool selected) const { + painter->save(); + QtMessageLogHandler::ItemType itemType = (QtMessageLogHandler::ItemType)index.data( + QtMessageLogHandler::TypeRole).toInt(); QColor backgroundColor; switch (itemType) { - case ConsoleItemModel::LogType: - backgroundColor = QColor(CONSOLE_LOG_BACKGROUND_COLOR); + case QtMessageLogHandler::DebugType: + backgroundColor = selected ? QColor(CONSOLE_LOG_BACKGROUND_SELECTED_COLOR) : + QColor(CONSOLE_LOG_BACKGROUND_COLOR); break; - case ConsoleItemModel::WarningType: - backgroundColor = QColor(CONSOLE_WARNING_BACKGROUND_COLOR); + case QtMessageLogHandler::WarningType: + backgroundColor = selected ? QColor(CONSOLE_WARNING_BACKGROUND_SELECTED_COLOR) : + 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); + case QtMessageLogHandler::ErrorType: + backgroundColor = selected ? QColor(CONSOLE_ERROR_BACKGROUND_SELECTED_COLOR) : + QColor(CONSOLE_ERROR_BACKGROUND_COLOR); break; + case QtMessageLogHandler::InputType: default: - backgroundColor = QColor(CONSOLE_EDITOR_BACKGROUND_COLOR); + backgroundColor = selected ? QColor(CONSOLE_EDITOR_BACKGROUND_SELECTED_COLOR) : + QColor(CONSOLE_EDITOR_BACKGROUND_COLOR); break; } - if (selected) - backgroundColor.setAlphaF(0.5f); - else - backgroundColor.setAlphaF(1 - CONSOLE_ALPHA); - - painter->setBrush(backgroundColor); - + if (!(index.flags() & Qt::ItemIsEditable)) + painter->setBrush(backgroundColor); painter->setPen(Qt::NoPen); painter->drawRect(rect); + painter->restore(); } -void ConsoleItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, +void QtMessageLogItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItemV4 opt = option; @@ -124,23 +123,22 @@ void ConsoleItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o //Set Colors QColor textColor; QIcon taskIcon; - ConsoleItemModel::ItemType type = - (ConsoleItemModel::ItemType)index.data( - ConsoleItemModel::TypeRole).toInt(); + QtMessageLogHandler::ItemType type = (QtMessageLogHandler::ItemType)index.data( + QtMessageLogHandler::TypeRole).toInt(); switch (type) { - case ConsoleItemModel::LogType: + case QtMessageLogHandler::DebugType: textColor = QColor(CONSOLE_LOG_TEXT_COLOR); taskIcon = m_logIcon; break; - case ConsoleItemModel::WarningType: + case QtMessageLogHandler::WarningType: textColor = QColor(CONSOLE_WARNING_TEXT_COLOR); taskIcon = m_warningIcon; break; - case ConsoleItemModel::ErrorType: + case QtMessageLogHandler::ErrorType: textColor = QColor(CONSOLE_ERROR_TEXT_COLOR); taskIcon = m_errorIcon; break; - case ConsoleItemModel::InputType: + case QtMessageLogHandler::InputType: textColor = QColor(CONSOLE_EDITOR_TEXT_COLOR); taskIcon = m_prompt; break; @@ -150,7 +148,7 @@ void ConsoleItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o } //Paint background - drawBackground(painter, opt.rect, type, + drawBackground(painter, opt.rect, index, bool(opt.state & QStyle::State_Selected)); //Calculate positions @@ -163,8 +161,7 @@ void ConsoleItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o } int width = view->width() - level * view->indentation(); bool showTypeIcon = index.parent() == QModelIndex(); - bool showExpandableIcon = type != ConsoleItemModel::InputType && - type != ConsoleItemModel::UndefinedType; + bool showExpandableIcon = type == QtMessageLogHandler::UndefinedType; QRect rect(opt.rect.x(), opt.rect.top(), width, opt.rect.height()); ConsoleItemPositions positions(rect, opt.font, showTypeIcon, @@ -203,13 +200,13 @@ void ConsoleItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o // Separator lines painter->setPen(QColor(CONSOLE_BORDER_COLOR)); - if (!index.flags() & Qt::ItemIsEditable) + 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, +QSize QtMessageLogItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItemV4 opt = option; @@ -226,12 +223,10 @@ QSize ConsoleItemDelegate::sizeHint(const QStyleOptionViewItem &option, if (index.flags() & Qt::ItemIsEditable) return QSize(width, view->height() * 1/2); - ConsoleItemModel::ItemType type = - (ConsoleItemModel::ItemType)index.data( - ConsoleItemModel::TypeRole).toInt(); + QtMessageLogHandler::ItemType type = (QtMessageLogHandler::ItemType)index.data( + QtMessageLogHandler::TypeRole).toInt(); bool showTypeIcon = index.parent() == QModelIndex(); - bool showExpandableIcon = type != ConsoleItemModel::InputType && - type != ConsoleItemModel::UndefinedType; + bool showExpandableIcon = type == QtMessageLogHandler::UndefinedType; QRect rect(level * view->indentation(), 0, width, 0); ConsoleItemPositions positions(rect, opt.font, @@ -247,36 +242,34 @@ QSize ConsoleItemDelegate::sizeHint(const QStyleOptionViewItem &option, return QSize(width, height); } -QWidget *ConsoleItemDelegate::createEditor(QWidget *parent, +QWidget *QtMessageLogItemDelegate::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())); + QtMessageLogEditor *editor = new QtMessageLogEditor(index, parent); connect(editor, SIGNAL(editingFinished()), this, SLOT(commitAndCloseEditor())); return editor; } -void ConsoleItemDelegate::setEditorData(QWidget *editor, +void QtMessageLogItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { - ConsoleEditor *edtr = qobject_cast<ConsoleEditor *>(editor); + QtMessageLogEditor *edtr = qobject_cast<QtMessageLogEditor *>(editor); edtr->insertPlainText(index.data(Qt::DisplayRole).toString()); } -void ConsoleItemDelegate::setModelData(QWidget *editor, +void QtMessageLogItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { - ConsoleEditor *edtr = qobject_cast<ConsoleEditor *>(editor); + QtMessageLogEditor *edtr = qobject_cast<QtMessageLogEditor *>(editor); model->setData(index, edtr->getCurrentScript(), Qt::DisplayRole); - model->setData(index, edtr->getCurrentScript(), ConsoleItemModel::TypeRole); + model->setData(index, QtMessageLogHandler::InputType, QtMessageLogHandler::TypeRole); } -void ConsoleItemDelegate::updateEditorGeometry(QWidget *editor, +void QtMessageLogItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/*index*/) const { @@ -285,21 +278,21 @@ void ConsoleItemDelegate::updateEditorGeometry(QWidget *editor, opt.rect.width(), opt.rect.bottom())); } -void ConsoleItemDelegate::currentChanged(const QModelIndex ¤t, +void QtMessageLogItemDelegate::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { emit sizeHintChanged(current); emit sizeHintChanged(previous); } -void ConsoleItemDelegate::commitAndCloseEditor() +void QtMessageLogItemDelegate::commitAndCloseEditor() { - ConsoleEditor *editor = qobject_cast<ConsoleEditor *>(sender()); + QtMessageLogEditor *editor = qobject_cast<QtMessageLogEditor *>(sender()); emit commitData(editor); emit closeEditor(editor); } -qreal ConsoleItemDelegate::layoutText(QTextLayout &tl, int width) const +qreal QtMessageLogItemDelegate::layoutText(QTextLayout &tl, int width) const { qreal height = 0; tl.beginLayout(); diff --git a/src/plugins/debugger/qml/consoleitemdelegate.h b/src/plugins/debugger/qtmessagelogitemdelegate.h similarity index 91% rename from src/plugins/debugger/qml/consoleitemdelegate.h rename to src/plugins/debugger/qtmessagelogitemdelegate.h index a7b79f90182..7bce80fb4df 100644 --- a/src/plugins/debugger/qml/consoleitemdelegate.h +++ b/src/plugins/debugger/qtmessagelogitemdelegate.h @@ -30,10 +30,8 @@ ** **************************************************************************/ -#ifndef CONSOLEITEMDELEGATE_H -#define CONSOLEITEMDELEGATE_H - -#include "consoleitemmodel.h" +#ifndef QTMESSAGELOGITEMDELEGATE_H +#define QTMESSAGELOGITEMDELEGATE_H #include <QTextLayout> #include <QStyledItemDelegate> @@ -41,17 +39,15 @@ namespace Debugger { namespace Internal { -class ConsoleBackend; -class ConsoleItemDelegate : public QStyledItemDelegate +class QtMessageLogItemDelegate : public QStyledItemDelegate { Q_OBJECT public: - explicit ConsoleItemDelegate(QObject *parent = 0); + explicit QtMessageLogItemDelegate(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; + const QModelIndex &index, + bool selected) const; public slots: void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); @@ -71,9 +67,6 @@ protected: const QStyleOptionViewItem &option, const QModelIndex &index) const; -signals: - void appendEditableRow(); - private slots: void commitAndCloseEditor(); @@ -87,7 +80,6 @@ private: const QIcon m_expandIcon; const QIcon m_collapseIcon; const QIcon m_prompt; - ConsoleBackend *m_consoleBackend; }; /* @@ -164,11 +156,11 @@ private: public: static const int TASK_ICON_SIZE = 16; - static const int ITEM_PADDING = 2; - static const int ITEM_SPACING = 2 * ITEM_PADDING; + static const int ITEM_PADDING = 7; + static const int ITEM_SPACING = 4; }; } //Internal } //Debugger -#endif // CONSOLEITEMDELEGATE_H +#endif // QTMESSAGELOGITEMDELEGATE_H diff --git a/src/plugins/debugger/qtmessagelogproxymodel.cpp b/src/plugins/debugger/qtmessagelogproxymodel.cpp new file mode 100644 index 00000000000..3d861007c30 --- /dev/null +++ b/src/plugins/debugger/qtmessagelogproxymodel.cpp @@ -0,0 +1,92 @@ +/************************************************************************** +** +** 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 "qtmessagelogproxymodel.h" + +namespace Debugger { +namespace Internal { + +QtMessageLogProxyModel::QtMessageLogProxyModel(QObject *parent) : + QSortFilterProxyModel(parent), + m_filter(QtMessageLogHandler::DefaultTypes) +{ +} + +void QtMessageLogProxyModel::setShowLogs(bool show) +{ + m_filter = show ? m_filter | QtMessageLogHandler::DebugType : + m_filter & ~QtMessageLogHandler::DebugType; + setFilterRegExp(QString()); +} + +void QtMessageLogProxyModel::setShowWarnings(bool show) +{ + m_filter = show ? m_filter | QtMessageLogHandler::WarningType : + m_filter & ~QtMessageLogHandler::WarningType; + setFilterRegExp(QString()); +} + +void QtMessageLogProxyModel::setShowErrors(bool show) +{ + m_filter = show ? m_filter | QtMessageLogHandler::ErrorType : + m_filter & ~QtMessageLogHandler::ErrorType; + setFilterRegExp(QString()); +} + +void QtMessageLogProxyModel::selectEditableRow(const QModelIndex &index, + QItemSelectionModel::SelectionFlags command) +{ + emit setCurrentIndex(mapFromSource(index), command); +} + +bool QtMessageLogProxyModel::filterAcceptsRow(int sourceRow, + const QModelIndex &sourceParent) const + { + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + return m_filter.testFlag((QtMessageLogHandler::ItemType) + sourceModel()->data( + index, QtMessageLogHandler::TypeRole).toInt()); + } + +void QtMessageLogProxyModel::onRowsInserted(const QModelIndex &index, int start, int end) +{ + int rowIndex = end; + do { + if (filterAcceptsRow(rowIndex, index)) { + emit scrollToBottom(); + break; + } + } while (--rowIndex >= start); +} + +} // namespace Internal +} // namespace Debugger diff --git a/src/plugins/debugger/qml/qmljsscriptconsole.h b/src/plugins/debugger/qtmessagelogproxymodel.h similarity index 50% rename from src/plugins/debugger/qml/qmljsscriptconsole.h rename to src/plugins/debugger/qtmessagelogproxymodel.h index 3a45cb981df..ad8993bb7c8 100644 --- a/src/plugins/debugger/qml/qmljsscriptconsole.h +++ b/src/plugins/debugger/qtmessagelogproxymodel.h @@ -30,69 +30,44 @@ ** **************************************************************************/ -#ifndef QMLJSSCRIPTCONSOLE_H -#define QMLJSSCRIPTCONSOLE_H +#ifndef QTMESSAGELOGPROXYMODEL_H +#define QTMESSAGELOGPROXYMODEL_H -#include "consoleitemmodel.h" -#include <debugger/debuggerconstants.h> -#include <QWidget> +#include "qtmessageloghandler.h" -QT_BEGIN_NAMESPACE -class QToolButton; -QT_END_NAMESPACE - -namespace Utils { -class StatusLabel; -class SavedAction; -} +#include <QSortFilterProxyModel> +#include <QItemSelectionModel> namespace Debugger { - -class DebuggerEngine; - namespace Internal { -class ConsoleTreeView; -class ConsoleItemDelegate; -class QmlJSConsoleBackend; -class QmlJSScriptConsoleWidget : public QWidget +class QtMessageLogProxyModel : public QSortFilterProxyModel { Q_OBJECT public: - QmlJSScriptConsoleWidget(QWidget *parent = 0); - ~QmlJSScriptConsoleWidget(); - - void setEngine(DebuggerEngine *engine); - void readSettings(); + explicit QtMessageLogProxyModel(QObject *parent = 0); public slots: - void writeSettings() const; - void appendResult(const QString &result); - void appendOutput(ConsoleItemModel::ItemType, const QString &message); - void appendMessage(QtMsgType type, const QString &message); + void setShowLogs(bool show); + void setShowWarnings(bool show); + void setShowErrors(bool show); + void selectEditableRow(const QModelIndex &index, + QItemSelectionModel::SelectionFlags command); + void onRowsInserted(const QModelIndex &index, int start, int end); signals: - void evaluateExpression(const QString &expr); + void scrollToBottom(); + void setCurrentIndex(const QModelIndex &index, + QItemSelectionModel::SelectionFlags command); -private slots: - void onEngineStateChanged(Debugger::DebuggerState state); - void onSelectionChanged(); +protected: + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; private: - 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; + QFlags<QtMessageLogHandler::ItemType> m_filter; }; -} //Internal -} //Debugger +} // namespace Internal +} // namespace Debugger -#endif +#endif // QTMESSAGELOGPROXYMODEL_H diff --git a/src/plugins/debugger/qml/consoletreeview.cpp b/src/plugins/debugger/qtmessagelogview.cpp similarity index 75% rename from src/plugins/debugger/qml/consoletreeview.cpp rename to src/plugins/debugger/qtmessagelogview.cpp index 146bea4d5f2..34f7ba96e22 100644 --- a/src/plugins/debugger/qml/consoletreeview.cpp +++ b/src/plugins/debugger/qtmessagelogview.cpp @@ -30,10 +30,9 @@ ** **************************************************************************/ -#include "consoletreeview.h" -#include "consoleitemdelegate.h" -#include "consoleitemmodel.h" -#include "debuggerinternalconstants.h" +#include "qtmessagelogview.h" +#include "qtmessagelogitemdelegate.h" +#include "qtmessageloghandler.h" #include <QMouseEvent> #include <QProxyStyle> @@ -42,7 +41,7 @@ namespace Debugger { namespace Internal { -class ConsoleTreeViewStyle : public QProxyStyle +class QtMessageLogViewViewStyle : public QProxyStyle { public: void drawPrimitive(PrimitiveElement element, @@ -54,7 +53,8 @@ public: QProxyStyle::drawPrimitive(element, option, painter, widget); } - int styleHint(StyleHint hint, const QStyleOption *option = 0, + int styleHint(StyleHint hint, + const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const { if (hint == SH_ItemView_ShowDecorationSelected) @@ -66,11 +66,11 @@ public: /////////////////////////////////////////////////////////////////////// // -// ConsoleTreeView +// QtMessageLogView // /////////////////////////////////////////////////////////////////////// -ConsoleTreeView::ConsoleTreeView(QWidget *parent) : +QtMessageLogView::QtMessageLogView(QWidget *parent) : QTreeView(parent) { setFrameStyle(QFrame::NoFrame); @@ -94,29 +94,20 @@ ConsoleTreeView::ConsoleTreeView(QWidget *parent) : "QTreeView::branch:open:has-children:has-siblings {" "border-image: none;" "image: none; }")); - ConsoleTreeViewStyle *style = new ConsoleTreeViewStyle; + QtMessageLogViewViewStyle *style = new QtMessageLogViewViewStyle; 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) +void QtMessageLogView::mousePressEvent(QMouseEvent *event) { QPoint pos = event->pos(); QModelIndex index = indexAt(pos); if (index.isValid()) { - ConsoleItemModel::ItemType type = - (ConsoleItemModel::ItemType)index.data( - ConsoleItemModel::TypeRole).toInt(); + QtMessageLogHandler::ItemType type = (QtMessageLogHandler::ItemType)index.data( + QtMessageLogHandler::TypeRole).toInt(); bool showTypeIcon = index.parent() == QModelIndex(); - bool showExpandableIcon = type != ConsoleItemModel::InputType && - type != ConsoleItemModel::UndefinedType; + bool showExpandableIcon = type == QtMessageLogHandler::UndefinedType; ConsoleItemPositions positions(visualRect(index), viewOptions().font, showTypeIcon, showExpandableIcon); @@ -135,21 +126,18 @@ void ConsoleTreeView::mousePressEvent(QMouseEvent *event) } } -void ConsoleTreeView::resizeEvent(QResizeEvent *e) +void QtMessageLogView::resizeEvent(QResizeEvent *e) { - static_cast<ConsoleItemDelegate *>(itemDelegate())->emitSizeHintChanged( + static_cast<QtMessageLogItemDelegate *>(itemDelegate())->emitSizeHintChanged( selectionModel()->currentIndex()); QTreeView::resizeEvent(e); } -void ConsoleTreeView::drawBranches(QPainter *painter, const QRect &rect, +void QtMessageLogView::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); + static_cast<QtMessageLogItemDelegate *>(itemDelegate())->drawBackground( + painter, rect, index, false); QTreeView::drawBranches(painter, rect, index); } diff --git a/src/plugins/debugger/qml/consoletreeview.h b/src/plugins/debugger/qtmessagelogview.h similarity index 87% rename from src/plugins/debugger/qml/consoletreeview.h rename to src/plugins/debugger/qtmessagelogview.h index 87f9aef6e9f..4a6a301d268 100644 --- a/src/plugins/debugger/qml/consoletreeview.h +++ b/src/plugins/debugger/qtmessagelogview.h @@ -30,21 +30,19 @@ ** **************************************************************************/ -#ifndef CONSOLETREEVIEW_H -#define CONSOLETREEVIEW_H +#ifndef QTMESSAGELOGVIEW_H +#define QTMESSAGELOGVIEW_H #include <QTreeView> namespace Debugger { namespace Internal { -class ConsoleTreeView : public QTreeView +class QtMessageLogView : public QTreeView { Q_OBJECT public: - explicit ConsoleTreeView(QWidget *parent = 0); - - void setItemDelegate(QAbstractItemDelegate *delegate); + explicit QtMessageLogView(QWidget *parent = 0); protected: void mousePressEvent(QMouseEvent *event); @@ -56,4 +54,4 @@ protected: } //Internal } //Debugger -#endif // CONSOLETREEVIEW_H +#endif // QTMESSAGELOGVIEW_H diff --git a/src/plugins/debugger/qtmessagelogwindow.cpp b/src/plugins/debugger/qtmessagelogwindow.cpp new file mode 100644 index 00000000000..c3a8e52638b --- /dev/null +++ b/src/plugins/debugger/qtmessagelogwindow.cpp @@ -0,0 +1,223 @@ +/************************************************************************** +** +** 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 "qtmessagelogwindow.h" +#include "qtmessagelogview.h" +#include "qtmessageloghandler.h" +#include "qtmessagelogitemdelegate.h" +#include "debuggerstringutils.h" +#include "qtmessagelogproxymodel.h" + +#include <utils/statuslabel.h> +#include <utils/styledbar.h> +#include <utils/savedaction.h> + +#include <coreplugin/icore.h> +#include <coreplugin/coreconstants.h> + +#include <QSettings> +#include <QHBoxLayout> +#include <QVBoxLayout> +#include <QToolButton> + +static const char CONSOLE[] = "Console"; +static const char SHOW_LOG[] = "showLog"; +static const char SHOW_WARNING[] = "showWarning"; +static const char SHOW_ERROR[] = "showError"; + +namespace Debugger { +namespace Internal { + +///////////////////////////////////////////////////////////////////// +// +// QtMessageLogWindow +// +///////////////////////////////////////////////////////////////////// + +QtMessageLogWindow::QtMessageLogWindow(QWidget *parent) + : QWidget(parent) +{ + setWindowTitle(tr(CONSOLE)); + setObjectName(_(CONSOLE)); + + const int statusBarHeight = 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); + + const int spacing = 7; + //Status Label + m_statusLabel = new Utils::StatusLabel; + hbox->addSpacing(spacing); + hbox->addWidget(m_statusLabel); + hbox->addWidget(new Utils::StyledSeparator); + hbox->addSpacing(spacing); + + const int buttonWidth = 25; + //Filters + QToolButton *button = new QToolButton(this); + button->setAutoRaise(true); + button->setFixedWidth(buttonWidth); + m_showLogAction = new Utils::SavedAction(this); + m_showLogAction->setDefaultValue(true); + m_showLogAction->setSettingsKey(_(CONSOLE), _(SHOW_LOG)); + m_showLogAction->setText(tr("Log")); + m_showLogAction->setCheckable(true); + m_showLogAction->setIcon(QIcon(_(":/debugger/images/log.png"))); + button->setDefaultAction(m_showLogAction); + hbox->addWidget(button); + hbox->addSpacing(spacing); + + button = new QToolButton(this); + button->setAutoRaise(true); + button->setFixedWidth(buttonWidth); + m_showWarningAction = new Utils::SavedAction(this); + m_showWarningAction->setDefaultValue(true); + m_showWarningAction->setSettingsKey(_(CONSOLE), _(SHOW_WARNING)); + m_showWarningAction->setText(tr("Warning")); + m_showWarningAction->setCheckable(true); + m_showWarningAction->setIcon(QIcon(_(":/debugger/images/warning.png"))); + button->setDefaultAction(m_showWarningAction); + hbox->addWidget(button); + hbox->addSpacing(spacing); + + button = new QToolButton(this); + button->setAutoRaise(true); + button->setFixedWidth(buttonWidth); + m_showErrorAction = new Utils::SavedAction(this); + m_showErrorAction->setDefaultValue(true); + m_showErrorAction->setSettingsKey(_(CONSOLE), _(SHOW_ERROR)); + m_showErrorAction->setText(tr("Error")); + m_showErrorAction->setCheckable(true); + m_showErrorAction->setIcon(QIcon(_(":/debugger/images/error.png"))); + button->setDefaultAction(m_showErrorAction); + hbox->addWidget(button); + hbox->addSpacing(spacing); + + //Clear Button + button = new QToolButton; + button->setAutoRaise(true); + button->setFixedWidth(buttonWidth); + m_clearAction = new QAction(tr("Clear Console"), this); + m_clearAction->setIcon(QIcon(_(Core::Constants::ICON_CLEAN_PANE))); + button->setDefaultAction(m_clearAction); + hbox->addWidget(button); + hbox->addSpacing(spacing); + + m_treeView = new QtMessageLogView(this); + m_treeView->setSizePolicy(QSizePolicy::MinimumExpanding, + QSizePolicy::MinimumExpanding); + + m_proxyModel = new QtMessageLogProxyModel(this); + connect(m_showLogAction, SIGNAL(toggled(bool)), + m_proxyModel, SLOT(setShowLogs(bool))); + connect(m_showWarningAction, SIGNAL(toggled(bool)), + m_proxyModel, SLOT(setShowWarnings(bool))); + connect(m_showErrorAction, SIGNAL(toggled(bool)), + m_proxyModel, SLOT(setShowErrors(bool))); + + m_treeView->setModel(m_proxyModel); + connect(m_proxyModel, + SIGNAL(setCurrentIndex(QModelIndex,QItemSelectionModel::SelectionFlags)), + m_treeView->selectionModel(), + SLOT(setCurrentIndex(QModelIndex,QItemSelectionModel::SelectionFlags))); + connect(m_proxyModel, + SIGNAL(scrollToBottom()), + m_treeView, + SLOT(scrollToBottom())); + + QtMessageLogItemDelegate *itemDelegate = new QtMessageLogItemDelegate(this); + connect(m_treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), + itemDelegate, SLOT(currentChanged(QModelIndex,QModelIndex))); + m_treeView->setItemDelegate(itemDelegate); + + vbox->addWidget(statusbarContainer); + vbox->addWidget(m_treeView); + + readSettings(); + connect(Core::ICore::instance(), + SIGNAL(saveSettingsRequested()), SLOT(writeSettings())); +} + +QtMessageLogWindow::~QtMessageLogWindow() +{ + writeSettings(); +} + +void QtMessageLogWindow::readSettings() +{ + QSettings *settings = Core::ICore::settings(); + m_showLogAction->readSettings(settings); + m_showWarningAction->readSettings(settings); + m_showErrorAction->readSettings(settings); +} + +void QtMessageLogWindow::showStatus(const QString &context, int timeout) +{ + m_statusLabel->showStatusMessage(context, timeout); +} + +void QtMessageLogWindow::writeSettings() const +{ + QSettings *settings = Core::ICore::settings(); + m_showLogAction->writeSettings(settings); + m_showWarningAction->writeSettings(settings); + m_showErrorAction->writeSettings(settings); +} + +void QtMessageLogWindow::setModel(QAbstractItemModel *model) +{ + m_proxyModel->setSourceModel(model); + QtMessageLogHandler *handler = qobject_cast<QtMessageLogHandler *>(model); + connect(m_clearAction, SIGNAL(triggered()), handler, SLOT(clear())); + connect(handler, + SIGNAL(selectEditableRow(QModelIndex,QItemSelectionModel::SelectionFlags)), + m_proxyModel, + SLOT(selectEditableRow(QModelIndex,QItemSelectionModel::SelectionFlags))); + + //Scroll to bottom when rows matching current filter settings are inserted + //Not connecting rowsRemoved as the only way to remove rows is to clear the + //model which will automatically reset the view. + connect(handler, + SIGNAL(rowsInserted(QModelIndex,int,int)), + m_proxyModel, + SLOT(onRowsInserted(QModelIndex,int,int))); +} + +} // namespace Internal +} // namespace Debugger diff --git a/src/plugins/debugger/consolewindow.h b/src/plugins/debugger/qtmessagelogwindow.h similarity index 65% rename from src/plugins/debugger/consolewindow.h rename to src/plugins/debugger/qtmessagelogwindow.h index a4fcab01764..25caa0140a7 100644 --- a/src/plugins/debugger/consolewindow.h +++ b/src/plugins/debugger/qtmessagelogwindow.h @@ -30,50 +30,52 @@ ** **************************************************************************/ -#ifndef DEBUGGER_CONSOLEWINDOW_H -#define DEBUGGER_CONSOLEWINDOW_H +#ifndef QTMESSAGELOGWINDOW_H +#define QTMESSAGELOGWINDOW_H #include <QWidget> QT_BEGIN_NAMESPACE -class QCursor; +class QAbstractItemModel; +class QAction; QT_END_NAMESPACE +namespace Utils { +class StatusLabel; +class SavedAction; +} + namespace Debugger { namespace Internal { -class Console; - -class ConsoleWindow : public QWidget +class QtMessageLogView; +class QtMessageLogProxyModel; +class QtMessageLogWindow : public QWidget { Q_OBJECT - public: - explicit ConsoleWindow(QWidget *parent = 0); - - void setCursor(const QCursor &cursor); + QtMessageLogWindow(QWidget *parent = 0); + ~QtMessageLogWindow(); - QString combinedContents() const; - QString inputContents() const; - - static QString logTimeStamp(); + void setModel(QAbstractItemModel *model); + void readSettings(); + void showStatus(const QString &context, int timeout); public slots: - void clearContents(); - void showOutput(int channel, const QString &output); - void showInput(int channel, const QString &input); - -signals: - void showPage(); - void statusMessageRequested(const QString &msg, int); + void writeSettings() const; private: - Console *m_console; // combined input/output + Utils::StatusLabel *m_statusLabel; + Utils::SavedAction *m_showLogAction; + Utils::SavedAction *m_showWarningAction; + Utils::SavedAction *m_showErrorAction; + QAction *m_clearAction; + QtMessageLogView *m_treeView; + QtMessageLogProxyModel *m_proxyModel; }; - } // namespace Internal } // namespace Debugger -#endif // DEBUGGER_CONSOLEWINDOW_H +#endif // QTMESSAGELOGWINDOW_H -- GitLab