diff --git a/src/libs/qmljsdebugclient/qdeclarativeenginedebug.h b/src/libs/qmljsdebugclient/qdeclarativeenginedebug.h index b7eb6655251ca3041205f960d746c686e40a47ce..822c55ed22159200878d94b322a5f8eb90d09b70 100644 --- a/src/libs/qmljsdebugclient/qdeclarativeenginedebug.h +++ b/src/libs/qmljsdebugclient/qdeclarativeenginedebug.h @@ -170,7 +170,7 @@ public: bool isWaiting() const; Q_SIGNALS: - void stateChanged(QDeclarativeDebugQuery::State); + void stateChanged(QmlJsDebugClient::QDeclarativeDebugQuery::State); protected: QDeclarativeDebugQuery(QObject *); diff --git a/src/plugins/debugger/debugger_dependencies.pri b/src/plugins/debugger/debugger_dependencies.pri index 7a5d3f09e04f12f7d13ec1124dcab08d96588094..699f3d3ece871de7cd9a1e4de010ac93b8c13d77 100644 --- a/src/plugins/debugger/debugger_dependencies.pri +++ b/src/plugins/debugger/debugger_dependencies.pri @@ -6,3 +6,4 @@ include(../../plugins/texteditor/texteditor.pri) include(../../libs/cplusplus/cplusplus.pri) include(../../libs/utils/utils.pri) include(../../libs/symbianutils/symbianutils.pri) +include(../../libs/qmljs/qmljs.pri) diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 7066e906423615056a86eaaf44737b462298b344..85f13a04d3332ed4d8c61dd54b9f85c57a2fb9f7 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -112,7 +112,7 @@ #include #include -#include +#include #include #include @@ -785,7 +785,7 @@ public slots: void aboutToSaveSession(); void executeDebuggerCommand(const QString &command); - void scriptExpressionEntered(const QString &expression); + void evaluateExpression(const QString &expression); void coreShutdown(); public slots: @@ -1079,7 +1079,7 @@ public: QAbstractItemView *m_stackWindow; QAbstractItemView *m_threadsWindow; LogWindow *m_logWindow; - ScriptConsole *m_scriptConsoleWindow; + QmlJSScriptConsoleWidget *m_scriptConsoleWindow; bool m_busy; QString m_lastPermanentStatusMessage; @@ -1972,6 +1972,16 @@ void DebuggerPluginPrivate::connectEngine(DebuggerEngine *engine) //m_threadBox->setModel(engine->threadsModel()); //m_threadBox->setModelColumn(ThreadData::ComboNameColumn); m_watchersWindow->setModel(engine->watchersModel()); + + //Initialize QmlJSConsole + QmlEngine *qmlEngine = qobject_cast(engine); + QmlCppEngine *qmlCppEngine = qobject_cast(engine); + if (qmlCppEngine) + qmlEngine = qobject_cast(qmlCppEngine->qmlEngine()); + if (qmlEngine) { + m_scriptConsoleWindow->setQmlAdapter(qmlEngine->adapter()); + } + engine->watchHandler()->rebuildModel(); } @@ -2047,7 +2057,6 @@ void DebuggerPluginPrivate::setBusyCursor(bool busy) m_threadsWindow->setCursor(cursor); m_watchersWindow->setCursor(cursor); m_snapshotWindow->setCursor(cursor); - m_scriptConsoleWindow->setCursor(cursor); } void DebuggerPluginPrivate::setInitialState() @@ -2239,8 +2248,11 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine) if (qmlCppEngine) qmlEngine = qobject_cast(qmlCppEngine->qmlEngine()); - if (qmlEngine) { - m_scriptConsoleWindow->setEnabled(stopped); + if (qmlEngine && (state == InferiorRunOk || state == InferiorStopOk)) { + m_scriptConsoleWindow->setEnabled(true); + m_scriptConsoleWindow->setInferiorStopped(state == InferiorStopOk); + } else { + m_scriptConsoleWindow->setEnabled(false); } } @@ -2387,7 +2399,7 @@ void DebuggerPluginPrivate::showStatusMessage(const QString &msg0, int timeout) m_statusLabel->showStatusMessage(msg, timeout); } -void DebuggerPluginPrivate::scriptExpressionEntered(const QString &expression) +void DebuggerPluginPrivate::evaluateExpression(const QString &expression) { currentEngine()->executeDebuggerCommand(expression); } @@ -2757,11 +2769,11 @@ void DebuggerPluginPrivate::extensionsInitialized() m_localsWindow->setObjectName(QLatin1String("CppDebugLocals")); m_watchersWindow = new WatchWindow(WatchWindow::WatchersType); m_watchersWindow->setObjectName(QLatin1String("CppDebugWatchers")); - m_scriptConsoleWindow = new ScriptConsole; + m_scriptConsoleWindow = new QmlJSScriptConsoleWidget; m_scriptConsoleWindow->setWindowTitle(tr("QML Script Console")); m_scriptConsoleWindow->setObjectName(DOCKWIDGET_QML_SCRIPTCONSOLE); - connect(m_scriptConsoleWindow, SIGNAL(expressionEntered(QString)), - SLOT(scriptExpressionEntered(QString))); + connect(m_scriptConsoleWindow, SIGNAL(evaluateExpression(QString)), + SLOT(evaluateExpression(QString))); // Snapshot m_snapshotHandler = new SnapshotHandler; diff --git a/src/plugins/debugger/qml/interactiveinterpreter.cpp b/src/plugins/debugger/qml/interactiveinterpreter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2f43649ad0601ae73fb3c2d976af370e972cf8ea --- /dev/null +++ b/src/plugins/debugger/qml/interactiveinterpreter.cpp @@ -0,0 +1,90 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.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 info@qt.nokia.com. +** +**************************************************************************/ + +#include "interactiveinterpreter.h" + +namespace Debugger { +namespace Internal { + +bool InteractiveInterpreter::canEvaluate() +{ + int yyaction = 0; + int yytoken = -1; + int yytos = -1; + + setCode(m_code, 1); + m_tokens.append(T_FEED_JS_PROGRAM); + + do { + if (++yytos == m_stateStack.size()) + m_stateStack.resize(m_stateStack.size() * 2); + + m_stateStack[yytos] = yyaction; + +again: + if (yytoken == -1 && action_index[yyaction] != -TERMINAL_COUNT) { + if (m_tokens.isEmpty()) + yytoken = lex(); + else + yytoken = m_tokens.takeFirst(); + } + + yyaction = t_action(yyaction, yytoken); + if (yyaction > 0) { + if (yyaction == ACCEPT_STATE) { + --yytos; + return true; + } + yytoken = -1; + } else if (yyaction < 0) { + const int ruleno = -yyaction - 1; + yytos -= rhs[ruleno]; + yyaction = nt_action(m_stateStack[yytos], lhs[ruleno] - TERMINAL_COUNT); + } + } while (yyaction); + + const int errorState = m_stateStack[yytos]; + if (t_action(errorState, T_AUTOMATIC_SEMICOLON) && canInsertAutomaticSemicolon(yytoken)) { + yyaction = errorState; + m_tokens.prepend(yytoken); + yytoken = T_SEMICOLON; + goto again; + } + + if (yytoken != EOF_SYMBOL) + return true; + + return false; +} + +} +} diff --git a/src/plugins/debugger/qml/scriptconsole.h b/src/plugins/debugger/qml/interactiveinterpreter.h similarity index 60% rename from src/plugins/debugger/qml/scriptconsole.h rename to src/plugins/debugger/qml/interactiveinterpreter.h index ae2cf2c3ef5983d6226a64c4a7a0a8cd6a8325ed..57962ab62a95f88ccce15fbfedac508a3d154ddb 100644 --- a/src/plugins/debugger/qml/scriptconsole.h +++ b/src/plugins/debugger/qml/interactiveinterpreter.h @@ -30,57 +30,42 @@ ** **************************************************************************/ -#ifndef QMLJSSCRIPTCONSOLE_H -#define QMLJSSCRIPTCONSOLE_H +#ifndef INTERACTIVEINTERPRETER_H +#define INTERACTIVEINTERPRETER_H -#include -#include -#include +#include +#include -#include - -namespace QmlJSEditor { -class Highlighter; -} +#include +#include +#include namespace Debugger { namespace Internal { -class ScriptConsole : public QWidget +class InteractiveInterpreter: QmlJS::Lexer { - Q_OBJECT public: - ScriptConsole(QWidget *parent = 0); - -public slots: - void appendResult(const QString &result); -signals: - void expressionEntered(const QString &expr); - -protected slots: - void clearTextEditor(); - void executeExpression(); + InteractiveInterpreter() + : Lexer(&m_engine), + m_stateStack(128) + { -protected: - bool eventFilter(QObject *obj, QEvent *event); - void setFontSettings(); - void clear(); + } -// QToolButton *m_clearButton; - QPlainTextEdit *m_textEdit; - Utils::FancyLineEdit *m_lineEdit; - QString m_prompt; - QString m_expr; - QString m_lastExpr; + void clearText() { m_code.clear(); } + void appendText(const QString &text) { m_code += text; } - QString m_title; - QmlJSEditor::Highlighter *m_highlighter; + QString code() const { return m_code; } + bool canEvaluate(); +private: + QmlJS::Engine m_engine; + QVector m_stateStack; + QList m_tokens; + QString m_code; }; - } -} //end namespaces - - -#endif +} +#endif // INTERACTIVEINTERPRETER_H diff --git a/src/plugins/debugger/qml/qml.pri b/src/plugins/debugger/qml/qml.pri index 396f247a9b657795da27e88f57b111e559d601b0..3533187ffbdd7a439731374f35f81ec3d021e89a 100644 --- a/src/plugins/debugger/qml/qml.pri +++ b/src/plugins/debugger/qml/qml.pri @@ -1,4 +1,5 @@ include($$PWD/../../../libs/qmljsdebugclient/qmljsdebugclient.pri) +include($$PWD/../../../libs/qmljs/parser/parser.pri) include($$PWD/../../../shared/json/json.pri) DEFINES += JSON_INCLUDE_PRI @@ -8,15 +9,18 @@ HEADERS += \ $$PWD/qmldebuggerclient.h \ $$PWD/qmljsprivateapi.h \ $$PWD/qmlcppengine.h \ - $$PWD/scriptconsole.h \ + $$PWD/qmljsscriptconsole.h \ $$PWD/qscriptdebuggerclient.h \ - $$PWD/qmlv8debuggerclient.h + $$PWD/qmlv8debuggerclient.h \ + $$PWD/interactiveinterpreter.h SOURCES += \ $$PWD/qmlengine.cpp \ $$PWD/qmladapter.cpp \ $$PWD/qmldebuggerclient.cpp \ $$PWD/qmlcppengine.cpp \ - $$PWD/scriptconsole.cpp \ + $$PWD/qmljsscriptconsole.cpp \ $$PWD/qscriptdebuggerclient.cpp \ - $$PWD/qmlv8debuggerclient.cpp + $$PWD/qmlv8debuggerclient.cpp \ + $$PWD/interactiveinterpreter.cpp + diff --git a/src/plugins/debugger/qml/qmladapter.cpp b/src/plugins/debugger/qml/qmladapter.cpp index 81df4fa4feb592e6e4101e5db768b8d1a5b63013..3da270dfdc7cc60cc94d6186569b133b6aed86e4 100644 --- a/src/plugins/debugger/qml/qmladapter.cpp +++ b/src/plugins/debugger/qml/qmladapter.cpp @@ -54,7 +54,9 @@ public: explicit QmlAdapterPrivate(DebuggerEngine *engine) : m_engine(engine) , m_qmlClient(0) + , m_engineDebugClient(0) , m_conn(0) + , m_currentSelectedDebugId(-1) { m_connectionTimer.setInterval(4000); m_connectionTimer.setSingleShot(true); @@ -62,9 +64,12 @@ public: QWeakPointer m_engine; QmlDebuggerClient *m_qmlClient; + QmlJsDebugClient::QDeclarativeEngineDebug *m_engineDebugClient; QTimer m_connectionTimer; QDeclarativeDebugConnection *m_conn; QHash debugClients; + int m_currentSelectedDebugId; + QString m_currentSelectedDebugName; }; } // namespace Internal @@ -272,6 +277,34 @@ QHash QmlAdapter::debuggerClients() { return d->debugClients; } + +QmlJsDebugClient::QDeclarativeEngineDebug *QmlAdapter::engineDebugClient() const +{ + return d->m_engineDebugClient; +} + +void QmlAdapter::setEngineDebugClient(QmlJsDebugClient::QDeclarativeEngineDebug *client) +{ + d->m_engineDebugClient = client; +} + +int QmlAdapter::currentSelectedDebugId() const +{ + return d->m_currentSelectedDebugId; +} + +QString QmlAdapter::currentSelectedDisplayName() const +{ + return d->m_currentSelectedDebugName; +} + +void QmlAdapter::setCurrentSelectedDebugInfo(int currentDebugId, const QString &displayName) +{ + d->m_currentSelectedDebugId = currentDebugId; + d->m_currentSelectedDebugName = displayName; + emit selectionChanged(); +} + void QmlAdapter::logServiceStatusChange(const QString &service, QDeclarativeDebugClient::Status newStatus) { diff --git a/src/plugins/debugger/qml/qmladapter.h b/src/plugins/debugger/qml/qmladapter.h index fe5b5cdf65fad918772ebebbbdeddc528baf7ba0..eb7bae40cc80ce557b52133cd6158bd58a9339e7 100644 --- a/src/plugins/debugger/qml/qmladapter.h +++ b/src/plugins/debugger/qml/qmladapter.h @@ -73,6 +73,13 @@ public: Internal::QmlDebuggerClient *activeDebuggerClient(); QHash debuggerClients(); + QmlJsDebugClient::QDeclarativeEngineDebug *engineDebugClient() const; + void setEngineDebugClient(QmlJsDebugClient::QDeclarativeEngineDebug *client); + + int currentSelectedDebugId() const; + QString currentSelectedDisplayName() const; + void setCurrentSelectedDebugInfo(int debugId, const QString &displayName = QString()); + public slots: void logServiceStatusChange(const QString &service, QDeclarativeDebugClient::Status newStatus); void logServiceActivity(const QString &service, const QString &logMessage); @@ -83,6 +90,7 @@ signals: void connectionStartupFailed(); void connectionError(QAbstractSocket::SocketError socketError); void serviceConnectionError(const QString serviceName); + void selectionChanged(); private slots: void connectionErrorOccurred(QAbstractSocket::SocketError socketError); diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index a3d32ae3bbdaa0224ece195d391b528dc1d3c487..2f031ce3f3c608acbdc6a9ac53b54c6e0ce7a51b 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -676,7 +676,7 @@ void QmlEngine::requestModuleSymbols(const QString &moduleName) bool QmlEngine::setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, const DebuggerToolTipContext &ctx) { - // This is processed by QML inspector, which has dependencies to + // This is processed by QML inspector, which has dependencies to // the qml js editor. Makes life easier. emit tooltipRequested(mousePos, editor, ctx.position); return true; @@ -811,6 +811,11 @@ void QmlEngine::logMessage(LogDirection direction, const QString &message) showMessage(msg, LogDebug); } +QmlAdapter *QmlEngine::adapter() const +{ + return &d->m_adapter; +} + QmlEngine *createQmlEngine(const DebuggerStartParameters &sp, DebuggerEngine *masterEngine) { diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h index 25b9996b45dbb0f266455341b99cc5d92435b1f5..758087b69e253619b565907be6915c0390e4bb75 100644 --- a/src/plugins/debugger/qml/qmlengine.h +++ b/src/plugins/debugger/qml/qmlengine.h @@ -40,6 +40,9 @@ #include namespace Debugger { + +class QmlAdapter; + namespace Internal { class QmlEnginePrivate; @@ -71,6 +74,8 @@ public: void logMessage(LogDirection direction, const QString &str); + QmlAdapter *adapter() const; + public slots: void disconnected(); diff --git a/src/plugins/debugger/qml/qmljsscriptconsole.cpp b/src/plugins/debugger/qml/qmljsscriptconsole.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e81f10601551043358aaf659e58095f2f6d616c8 --- /dev/null +++ b/src/plugins/debugger/qml/qmljsscriptconsole.cpp @@ -0,0 +1,552 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.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 info@qt.nokia.com. +** +**************************************************************************/ + +#include "qmljsscriptconsole.h" +#include "interactiveinterpreter.h" +#include "qmladapter.h" +#include "debuggerstringutils.h" + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace Debugger { +namespace Internal { + +class QmlJSScriptConsolePrivate +{ +public: + QmlJSScriptConsolePrivate() + : prompt(QLatin1String("> ")), + startOfEditableArea(-1), + lastKnownPosition(0), + inferiorStopped(false) + { + resetCache(); + } + + void resetCache(); + void appendToHistory(const QString &script); + bool canEvaluateScript(const QString &script); + + QWeakPointer adapter; + + QString prompt; + int startOfEditableArea; + int lastKnownPosition; + + QStringList scriptHistory; + int scriptHistoryIndex; + + InteractiveInterpreter interpreter; + + bool inferiorStopped; + QList selections; +}; + +void QmlJSScriptConsolePrivate::resetCache() +{ + scriptHistory.clear(); + scriptHistory.append(QLatin1String("")); + scriptHistoryIndex = scriptHistory.count(); + + selections.clear(); +} + +void QmlJSScriptConsolePrivate::appendToHistory(const QString &script) +{ + scriptHistoryIndex = scriptHistory.count(); + scriptHistory.replace(scriptHistoryIndex - 1,script); + scriptHistory.append(QLatin1String("")); + scriptHistoryIndex = scriptHistory.count(); +} + +bool QmlJSScriptConsolePrivate::canEvaluateScript(const QString &script) +{ + interpreter.clearText(); + interpreter.appendText(script); + return interpreter.canEvaluate(); +} + +/////////////////////////////////////////////////////////////////////// +// +// QmlJSScriptConsoleWidget +// +/////////////////////////////////////////////////////////////////////// + +QmlJSScriptConsoleWidget::QmlJSScriptConsoleWidget(QWidget *parent) + : QWidget(parent) +{ + QVBoxLayout *vbox = new QVBoxLayout(this); + vbox->setMargin(0); + vbox->setSpacing(0); + + QWidget *statusbarContainer = new QWidget; + + QHBoxLayout *hbox = new QHBoxLayout(statusbarContainer); + hbox->setMargin(0); + hbox->setSpacing(0); + + //Clear Button + QToolButton *clearButton = new QToolButton; + QAction *clearAction = new QAction(tr("Clear Console"), this); + clearAction->setIcon(QIcon(_(Core::Constants::ICON_CLEAN_PANE))); + + clearButton->setDefaultAction(clearAction); + + //Status Label + m_statusLabel = new Utils::StatusLabel; + + hbox->addWidget(m_statusLabel, 20, Qt::AlignLeft); + hbox->addWidget(clearButton, 0, Qt::AlignRight); + + m_console = new QmlJSScriptConsole; + connect(m_console, SIGNAL(evaluateExpression(QString)), this, + SIGNAL(evaluateExpression(QString))); + connect(m_console, SIGNAL(updateStatusMessage(const QString &, int)), m_statusLabel, + SLOT(showStatusMessage(const QString &, int))); + connect(clearAction, SIGNAL(triggered()), m_console, SLOT(clear())); + vbox->addWidget(statusbarContainer); + vbox->addWidget(m_console); + +} + +void QmlJSScriptConsoleWidget::setQmlAdapter(QmlAdapter *adapter) +{ + m_console->setQmlAdapter(adapter); +} + +void QmlJSScriptConsoleWidget::setInferiorStopped(bool inferiorStopped) +{ + m_console->setInferiorStopped(inferiorStopped); +} + +void QmlJSScriptConsoleWidget::appendResult(const QString &result) +{ + m_console->appendResult(result); +} + +/////////////////////////////////////////////////////////////////////// +// +// QmlJSScriptConsole +// +/////////////////////////////////////////////////////////////////////// + +QmlJSScriptConsole::QmlJSScriptConsole(QWidget *parent) + : QPlainTextEdit(parent), + d(new QmlJSScriptConsolePrivate()) +{ + connect(this, SIGNAL(cursorPositionChanged()), SLOT(onCursorPositionChanged())); + + setFrameStyle(QFrame::NoFrame); + setUndoRedoEnabled(false); + setBackgroundVisible(false); + const TextEditor::FontSettings &fs = TextEditor::TextEditorSettings::instance()->fontSettings(); + setFont(fs.font()); + + displayPrompt(); +} + +QmlJSScriptConsole::~QmlJSScriptConsole() +{ + delete d; +} + +void QmlJSScriptConsole::setPrompt(const QString &prompt) +{ + d->prompt = prompt; +} + +QString QmlJSScriptConsole::prompt() const +{ + return d->prompt; +} + +void QmlJSScriptConsole::setInferiorStopped(bool inferiorStopped) +{ + d->inferiorStopped = inferiorStopped; + onSelectionChanged(); +} + +void QmlJSScriptConsole::setQmlAdapter(QmlAdapter *adapter) +{ + d->adapter = adapter; + clear(); +} + +void QmlJSScriptConsole::appendResult(const QString &result) +{ + QString currentScript = getCurrentScript(); + d->appendToHistory(currentScript); + + QTextCursor cur = textCursor(); + cur.movePosition(QTextCursor::EndOfLine); + cur.insertText(QLatin1String("\n")); + cur.insertText(result); + cur.movePosition(QTextCursor::EndOfLine); + cur.insertText(QLatin1String("\n")); + setTextCursor(cur); + displayPrompt(); + + QTextEdit::ExtraSelection sel; + + QTextCharFormat resultFormat; + resultFormat.setForeground(QBrush(QColor(Qt::darkGray))); + + QTextCursor c(document()->findBlockByNumber(cur.blockNumber()-1)); + c.movePosition(QTextCursor::StartOfBlock); + c.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor); + + sel.format = resultFormat; + sel.cursor = c; + + d->selections.append(sel); + + setExtraSelections(d->selections); +} + +void QmlJSScriptConsole::clear() +{ + d->resetCache(); + + QPlainTextEdit::clear(); + displayPrompt(); +} + +void QmlJSScriptConsole::onStateChanged(QmlJsDebugClient::QDeclarativeDebugQuery::State state) +{ + QDeclarativeDebugExpressionQuery *query = qobject_cast(sender()); + bool gotResult = false; + if (query && state != QDeclarativeDebugQuery::Error) { + QString result(query->result().toString()); + if (result != QLatin1String("")) { + appendResult(result); + gotResult = true; + } + } + + if (!gotResult) { + QString currentScript = getCurrentScript(); + if (d->canEvaluateScript(currentScript)) { + emit evaluateExpression(currentScript); + } else { + QPlainTextEdit::appendPlainText(QLatin1String("")); + moveCursor(QTextCursor::EndOfLine); + } + } + delete query; +} + +void QmlJSScriptConsole::onSelectionChanged() +{ + if (!d->adapter.isNull()) { + QString status; + if (!d->inferiorStopped) { + status.append(tr("Current Selected Object: ")); + status.append(d->adapter.data()->currentSelectedDisplayName()); + } + emit updateStatusMessage(status, 0); + } +} + +void QmlJSScriptConsole::keyPressEvent(QKeyEvent *e) +{ + bool keyConsumed = false; + switch (e->key()) { + + case Qt::Key_Return: + case Qt::Key_Enter: + if (isEditableArea()) { + handleReturnKey(); + keyConsumed = true; + } + break; + + case Qt::Key_Backspace: { + QTextCursor cursor = textCursor(); + bool hasSelection = cursor.hasSelection(); + int selectionStart = cursor.selectionStart(); + if ((hasSelection && selectionStart < d->startOfEditableArea) + || (!hasSelection && selectionStart == d->startOfEditableArea)) { + keyConsumed = true; + } + break; + } + + case Qt::Key_Delete: + if (textCursor().selectionStart() < d->startOfEditableArea) { + keyConsumed = true; + } + break; + + case Qt::Key_Tab: + case Qt::Key_Backtab: + keyConsumed = true; + break; + + case Qt::Key_Left: + if (textCursor().position() == d->startOfEditableArea) { + keyConsumed = true; + } else if (e->modifiers() & Qt::ControlModifier && isEditableArea()) { + handleHomeKey(); + keyConsumed = true; + } + break; + + case Qt::Key_Up: + if (isEditableArea()) { + handleUpKey(); + keyConsumed = true; + } + break; + + case Qt::Key_Down: + if (isEditableArea()) { + handleDownKey(); + keyConsumed = true; + } + break; + + case Qt::Key_Home: + if (isEditableArea()) { + handleHomeKey(); + keyConsumed = true; + } + break; + + case Qt::Key_C: + case Qt::Key_Insert: { + //Fair to assume that for any selection beyond startOfEditableArea + //only copy function is allowed. + QTextCursor cursor = textCursor(); + bool hasSelection = cursor.hasSelection(); + int selectionStart = cursor.selectionStart(); + if (hasSelection && selectionStart < d->startOfEditableArea) { + if (!(e->modifiers() & Qt::ControlModifier)) + keyConsumed = true; + } + break; + } + + default: { + QTextCursor cursor = textCursor(); + bool hasSelection = cursor.hasSelection(); + int selectionStart = cursor.selectionStart(); + if (hasSelection && selectionStart < d->startOfEditableArea) { + keyConsumed = true; + } + break; + } + } + + if (!keyConsumed) + QPlainTextEdit::keyPressEvent(e); +} + +void QmlJSScriptConsole::contextMenuEvent(QContextMenuEvent *event) +{ + QTextCursor cursor = textCursor(); + Qt::TextInteractionFlags flags = textInteractionFlags(); + bool hasSelection = cursor.hasSelection(); + int selectionStart = cursor.selectionStart(); + bool canBeEdited = true; + if (hasSelection && selectionStart < d->startOfEditableArea) { + canBeEdited = false; + } + + QMenu *menu = new QMenu(); + QAction *a; + + if ((flags & Qt::TextEditable) && canBeEdited) { + a = menu->addAction(tr("Cut"), this, SLOT(cut())); + a->setEnabled(cursor.hasSelection()); + } + + a = menu->addAction(tr("Copy"), this, SLOT(copy())); + a->setEnabled(cursor.hasSelection()); + + if ((flags & Qt::TextEditable) && canBeEdited) { + a = menu->addAction(tr("Paste"), this, SLOT(paste())); + a->setEnabled(canPaste()); + } + + menu->addSeparator(); + a = menu->addAction(tr("Select All"), this, SLOT(selectAll())); + a->setEnabled(!document()->isEmpty()); + + menu->addSeparator(); + menu->addAction(tr("Clear"), this, SLOT(clear())); + + menu->exec(event->globalPos()); + + delete menu; +} + +void QmlJSScriptConsole::mouseReleaseEvent(QMouseEvent *e) +{ + QPlainTextEdit::mouseReleaseEvent(e); + QTextCursor cursor = textCursor(); + if (e->button() == Qt::LeftButton && !cursor.hasSelection() && !isEditableArea()) { + cursor.setPosition(d->lastKnownPosition); + setTextCursor(cursor); + } +} + +void QmlJSScriptConsole::onCursorPositionChanged() +{ + if (!isEditableArea()) { + setTextInteractionFlags(Qt::TextSelectableByMouse); + } else { + d->lastKnownPosition = textCursor().position(); + setTextInteractionFlags(Qt::TextEditorInteraction); + } +} + +void QmlJSScriptConsole::displayPrompt() +{ + d->startOfEditableArea = textCursor().position() + d->prompt.length(); + QTextCursor cur = textCursor(); + cur.insertText(d->prompt); + cur.movePosition(QTextCursor::EndOfWord); + setTextCursor(cur); +} + +void QmlJSScriptConsole::handleReturnKey() +{ + QString currentScript = getCurrentScript(); + bool evaluateScript = false; + + //Check if string is only white spaces + if (currentScript.trimmed().isEmpty()) { + QTextCursor cur = textCursor(); + cur.movePosition(QTextCursor::EndOfLine); + cur.insertText(QLatin1String("\n")); + setTextCursor(cur); + displayPrompt(); + evaluateScript = true; + } + + if (!evaluateScript && !d->inferiorStopped) { + if (!d->adapter.isNull()) { + QDeclarativeEngineDebug *engineDebug = d->adapter.data()->engineDebugClient(); + int id = d->adapter.data()->currentSelectedDebugId(); + if (engineDebug && id != -1) { + QDeclarativeDebugExpressionQuery *query = + engineDebug->queryExpressionResult(id, currentScript, this); + connect(query, SIGNAL(stateChanged(QmlJsDebugClient::QDeclarativeDebugQuery::State)), + this, SLOT(onStateChanged(QmlJsDebugClient::QDeclarativeDebugQuery::State))); + evaluateScript = true; + } + } + } + + if (!evaluateScript) { + if (d->canEvaluateScript(currentScript)) { + emit evaluateExpression(currentScript); + } else { + QPlainTextEdit::appendPlainText(QLatin1String("")); + moveCursor(QTextCursor::EndOfLine); + } + } +} + +void QmlJSScriptConsole::handleUpKey() +{ + //get the current script and update in script history + QString currentScript = getCurrentScript(); + d->scriptHistory.replace(d->scriptHistoryIndex - 1,currentScript); + + if (d->scriptHistoryIndex > 1) + d->scriptHistoryIndex--; + + replaceCurrentScript(d->scriptHistory.at(d->scriptHistoryIndex - 1)); +} + +void QmlJSScriptConsole::handleDownKey() +{ + //get the current script and update in script history + QString currentScript = getCurrentScript(); + d->scriptHistory.replace(d->scriptHistoryIndex - 1,currentScript); + + if (d->scriptHistoryIndex < d->scriptHistory.count()) + d->scriptHistoryIndex++; + + replaceCurrentScript(d->scriptHistory.at(d->scriptHistoryIndex - 1)); +} + +void QmlJSScriptConsole::handleHomeKey() +{ + QTextCursor cursor = textCursor(); + cursor.setPosition(d->startOfEditableArea); + setTextCursor(cursor); +} + +QString QmlJSScriptConsole::getCurrentScript() const +{ + QTextCursor cursor = textCursor(); + cursor.setPosition(d->startOfEditableArea); + while (cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor)) ; + QString script = cursor.selectedText(); + cursor.clearSelection(); + //remove trailing white space + int end = script.size() - 1; + while (end > 0 && script[end].isSpace()) + end--; + return script.left(end + 1); +} + +void QmlJSScriptConsole::replaceCurrentScript(const QString &script) +{ + QTextCursor cursor = textCursor(); + cursor.setPosition(d->startOfEditableArea); + while (cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor)) ; + cursor.deleteChar(); + cursor.insertText(script); + setTextCursor(cursor); +} + +bool QmlJSScriptConsole::isEditableArea() const +{ + return textCursor().position() >= d->startOfEditableArea; +} + +} //Internal +} //Debugger diff --git a/src/plugins/debugger/qml/qmljsscriptconsole.h b/src/plugins/debugger/qml/qmljsscriptconsole.h new file mode 100644 index 0000000000000000000000000000000000000000..52401123094f08413bd70aab5ee5d3e7b4aea933 --- /dev/null +++ b/src/plugins/debugger/qml/qmljsscriptconsole.h @@ -0,0 +1,130 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.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 info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef QMLJSSCRIPTCONSOLE_H +#define QMLJSSCRIPTCONSOLE_H + +#include +#include + +namespace Utils { +class StatusLabel; +} + +namespace Debugger { + +class QmlAdapter; + +namespace Internal { + +class QmlJSScriptConsolePrivate; +class QmlJSScriptConsole; + +class QmlJSScriptConsoleWidget : public QWidget +{ + Q_OBJECT +public: + QmlJSScriptConsoleWidget(QWidget *parent = 0); + + void setQmlAdapter(QmlAdapter *adapter); + void setInferiorStopped(bool inferiorStopped); + +public slots: + void appendResult(const QString &result); + +signals: + void evaluateExpression(const QString &expr); + +private: + QmlJSScriptConsole *m_console; + Utils::StatusLabel *m_statusLabel; + +}; + +class QmlJSScriptConsole : public QPlainTextEdit +{ + Q_OBJECT + +public: + explicit QmlJSScriptConsole(QWidget *parent = 0); + ~QmlJSScriptConsole(); + + inline void setTitle(const QString &title) + { setDocumentTitle(title); } + + inline QString title() const + { return documentTitle(); } + + void setPrompt(const QString &prompt); + QString prompt() const; + + void setInferiorStopped(bool inferiorStopped); + + void setQmlAdapter(QmlAdapter *adapter); + + void appendResult(const QString &result); + +public slots: + void clear(); + void onStateChanged(QmlJsDebugClient::QDeclarativeDebugQuery::State); + void onSelectionChanged(); + +protected: + void keyPressEvent(QKeyEvent *e); + void contextMenuEvent(QContextMenuEvent *event); + void mouseReleaseEvent(QMouseEvent *e); + +signals: + void evaluateExpression(const QString &expr); + void updateStatusMessage(const QString &message, int timeoutMS); + +private slots: + void onCursorPositionChanged(); + +private: + void displayPrompt(); + void handleReturnKey(); + void handleUpKey(); + void handleDownKey(); + void handleHomeKey(); + QString getCurrentScript() const; + void replaceCurrentScript(const QString &script); + bool isEditableArea() const; + +private: + QmlJSScriptConsolePrivate *d; +}; + +} //Internal +} //Debugger + +#endif diff --git a/src/plugins/debugger/qml/scriptconsole.cpp b/src/plugins/debugger/qml/scriptconsole.cpp deleted file mode 100644 index f406effa34c7b5ff2b103ef35999ddfdb04ab590..0000000000000000000000000000000000000000 --- a/src/plugins/debugger/qml/scriptconsole.cpp +++ /dev/null @@ -1,241 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (info@qt.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 info@qt.nokia.com. -** -**************************************************************************/ - -#include "scriptconsole.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Debugger { -namespace Internal { - -ScriptConsole::ScriptConsole(QWidget *parent) - : QWidget(parent), - m_textEdit(new QPlainTextEdit), - m_lineEdit(0) -{ - -// m_prompt = QLatin1String(">"); - - QVBoxLayout *layout = new QVBoxLayout(this); - layout->setMargin(0); - layout->setSpacing(0); - layout->addWidget(m_textEdit); - m_textEdit->setFrameStyle(QFrame::NoFrame); - - //updateTitle(); - - /*m_highlighter = new QmlJSEditor::Highlighter(m_textEdit->document()); - m_highlighter->setParent(m_textEdit->document());*/ - - Utils::StyledBar *bar = new Utils::StyledBar; - m_lineEdit = new Utils::FilterLineEdit; - - m_lineEdit->setPlaceholderText(tr("")); - m_lineEdit->setToolTip(tr("Write and evaluate QtScript expressions.")); - - /*m_clearButton = new QToolButton(); - m_clearButton->setToolTip(tr("Clear Output")); - m_clearButton->setIcon(QIcon(Core::Constants::ICON_CLEAN_PANE)); - connect(m_clearButton, SIGNAL(clicked()), this, SLOT(clearTextEditor()));*/ - //connect(m_lineEdit, SIGNAL(textChanged(QString)), SLOT(changeContextHelpId(QString))); - - connect(m_lineEdit, SIGNAL(returnPressed()), SLOT(executeExpression())); - QHBoxLayout *hbox = new QHBoxLayout(bar); - hbox->setMargin(1); - hbox->setSpacing(1); - hbox->addWidget(m_lineEdit); - //hbox->addWidget(m_clearButton); - layout->addWidget(bar); - - m_textEdit->setReadOnly(true); - m_lineEdit->installEventFilter(this); - - setFontSettings(); -} - - -void ScriptConsole::setFontSettings() -{ - const TextEditor::FontSettings &fs = TextEditor::TextEditorSettings::instance()->fontSettings(); - static QVector categories; - if (categories.isEmpty()) { - categories << QLatin1String(TextEditor::Constants::C_NUMBER) - << QLatin1String(TextEditor::Constants::C_STRING) - << QLatin1String(TextEditor::Constants::C_TYPE) - << QLatin1String(TextEditor::Constants::C_KEYWORD) - << QLatin1String(TextEditor::Constants::C_LABEL) - << QLatin1String(TextEditor::Constants::C_COMMENT) - << QLatin1String(TextEditor::Constants::C_VISUAL_WHITESPACE); - } - - const QVector formats = fs.toTextCharFormats(categories); -/* m_highlighter->setFormats(formats); - m_highlighter->rehighlight();*/ - m_textEdit->setFont(fs.font()); - m_lineEdit->setFont(fs.font()); -} - - -void ScriptConsole::clear() -{ - clearTextEditor(); - - if (m_lineEdit) - m_lineEdit->clear(); -// appendPrompt(); -} - -void ScriptConsole::clearTextEditor() -{ - m_textEdit->clear(); - m_textEdit->appendPlainText(tr("Script Console\n")); -} - - -/*void ExpressionQueryWidget::updateTitle() -{ - if (m_currObject.debugId() < 0) { - m_title = tr("Expression queries"); - } else { - QString desc = QLatin1String("<") - + m_currObject.className() + QLatin1String(": ") - + (m_currObject.name().isEmpty() ? QLatin1String("") : m_currObject.name()) - + QLatin1String(">"); - m_title = tr("Expression queries (using context for %1)" , "Selected object").arg(desc); - } -}*/ -/* -void ExpressionQueryWidget::appendPrompt() -{ - m_textEdit->moveCursor(QTextCursor::End); - - if (m_mode == SeparateEntryMode) { - m_textEdit->insertPlainText("\n"); - } else { - m_textEdit->appendPlainText(m_prompt); - } -} -*/ - - - -bool ScriptConsole::eventFilter(QObject* obj, QEvent* event) -{ - if (obj == m_textEdit) { - switch (event->type()) { - case QEvent::KeyPress: - { - QKeyEvent *keyEvent = static_cast(event); - int key = keyEvent->key(); - if (key == Qt::Key_Return || key == Qt::Key_Enter) { - executeExpression(); - return true; - } else if (key == Qt::Key_Backspace) { - // ensure m_expr doesn't contain backspace characters - QTextCursor cursor = m_textEdit->textCursor(); - bool atLastLine = !(cursor.block().next().isValid()); - if (!atLastLine) - return true; - if (cursor.positionInBlock() <= m_prompt.count()) - return true; - cursor.deletePreviousChar(); - m_expr = cursor.block().text().mid(m_prompt.count()); - return true; - } else { - m_textEdit->moveCursor(QTextCursor::End); - m_expr += keyEvent->text(); - } - break; - } - case QEvent::FocusIn: - //checkCurrentContext(); - m_textEdit->moveCursor(QTextCursor::End); - break; - default: - break; - } - } else if (obj == m_lineEdit) { - switch (event->type()) { - case QEvent::KeyPress: - { - QKeyEvent *keyEvent = static_cast(event); - int key = keyEvent->key(); - if (key == Qt::Key_Up && m_lineEdit->text() != m_lastExpr) { - m_expr = m_lineEdit->text(); - if (!m_lastExpr.isEmpty()) - m_lineEdit->setText(m_lastExpr); - } else if (key == Qt::Key_Down) { - m_lineEdit->setText(m_expr); - } - break; - } - case QEvent::FocusIn: - // checkCurrentContext(); - break; - default: - break; - } - } - return QWidget::eventFilter(obj, event); -} - -void ScriptConsole::executeExpression() -{ - m_expr = m_lineEdit->text().trimmed(); - m_expr = m_expr.trimmed(); - if (!m_expr.isEmpty()) { - emit expressionEntered(m_expr); - m_lastExpr = m_expr; - if (m_lineEdit) - m_lineEdit->clear(); - } -} - -void ScriptConsole::appendResult(const QString& result) -{ - m_textEdit->moveCursor(QTextCursor::End); - m_textEdit->insertPlainText(m_expr + " : "); - m_textEdit->insertPlainText(result); - m_textEdit->insertPlainText("\n"); - m_expr.clear(); -} - -} -} diff --git a/src/plugins/qmljsinspector/qmljsclientproxy.cpp b/src/plugins/qmljsinspector/qmljsclientproxy.cpp index 4cddca45df61a020c5e38f4c321b293fa34922d9..529219c35e3590f8c6f5d9e16e69fc3c85d46a00 100644 --- a/src/plugins/qmljsinspector/qmljsclientproxy.cpp +++ b/src/plugins/qmljsinspector/qmljsclientproxy.cpp @@ -63,6 +63,12 @@ ClientProxy::ClientProxy(Debugger::QmlAdapter *adapter, QObject *parent) connectToServer(); } +ClientProxy::~ClientProxy() +{ + m_adapter.data()->setEngineDebugClient(0); + m_adapter.data()->setCurrentSelectedDebugInfo(-1); +} + void ClientProxy::connectToServer() { m_engineClient = new QDeclarativeEngineDebug(m_adapter.data()->connection(), this); @@ -70,6 +76,8 @@ void ClientProxy::connectToServer() connect(m_engineClient, SIGNAL(newObjects()), this, SLOT(newObjects())); connect(m_engineClient, SIGNAL(statusChanged(QDeclarativeDebugClient::Status)), this, SLOT(clientStatusChanged(QDeclarativeDebugClient::Status))); + connect(m_engineClient, SIGNAL(statusChanged(QDeclarativeDebugClient::Status)), + this, SLOT(engineClientStatusChanged(QDeclarativeDebugClient::Status))); m_inspectorClient = new QmlJSInspectorClient(m_adapter.data()->connection(), this); @@ -116,6 +124,13 @@ void ClientProxy::clientStatusChanged(QDeclarativeDebugClient::Status status) updateConnected(); } +void ClientProxy::engineClientStatusChanged(QDeclarativeDebugClient::Status status) +{ + if (status == QDeclarativeDebugClient::Enabled) { + m_adapter.data()->setEngineDebugClient(qobject_cast(sender())); + } +} + void ClientProxy::refreshObjectTree() { if (!m_contextQuery) { @@ -434,7 +449,7 @@ void ClientProxy::queryEngineContext(int id) if (!m_contextQuery->isWaiting()) contextChanged(); else - connect(m_contextQuery, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)), + connect(m_contextQuery, SIGNAL(stateChanged(QmlJsDebugClient::QDeclarativeDebugQuery::State)), this, SLOT(contextChanged())); } @@ -471,8 +486,8 @@ void ClientProxy::fetchContextObjectRecursive(const QDeclarativeDebugContextRefe } else { m_objectTreeQuery << query; connect(query, - SIGNAL(stateChanged(QDeclarativeDebugQuery::State)), - SLOT(objectTreeFetched(QDeclarativeDebugQuery::State))); + SIGNAL(stateChanged(QmlJsDebugClient::QDeclarativeDebugQuery::State)), + SLOT(objectTreeFetched(QmlJsDebugClient::QDeclarativeDebugQuery::State))); } } foreach (const QDeclarativeDebugContextReference& child, context.contexts()) { @@ -481,7 +496,7 @@ void ClientProxy::fetchContextObjectRecursive(const QDeclarativeDebugContextRefe } -void ClientProxy::objectTreeFetched(QDeclarativeDebugQuery::State state) +void ClientProxy::objectTreeFetched(QmlJsDebugClient::QDeclarativeDebugQuery::State state) { QDeclarativeDebugObjectQuery *query = qobject_cast(sender()); if (!query || state == QDeclarativeDebugQuery::Error) { @@ -646,7 +661,7 @@ void ClientProxy::reloadEngines() if (!m_engineQuery->isWaiting()) { updateEngineList(); } else { - connect(m_engineQuery, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)), + connect(m_engineQuery, SIGNAL(stateChanged(QmlJsDebugClient::QDeclarativeDebugQuery::State)), this, SLOT(updateEngineList())); } } diff --git a/src/plugins/qmljsinspector/qmljsclientproxy.h b/src/plugins/qmljsinspector/qmljsclientproxy.h index b971fa220c7d344c4aab5211f89d10f37b110984..f38e8d54b0fcf91b8a34bbfd5d65efa7bb7082e0 100644 --- a/src/plugins/qmljsinspector/qmljsclientproxy.h +++ b/src/plugins/qmljsinspector/qmljsclientproxy.h @@ -58,6 +58,7 @@ class ClientProxy : public QObject public: explicit ClientProxy(Debugger::QmlAdapter *adapter, QObject *parent = 0); + ~ClientProxy(); bool setBindingForObject(int objectDebugId, const QString &propertyName, @@ -137,12 +138,13 @@ public slots: private slots: void connectToServer(); void clientStatusChanged(QDeclarativeDebugClient::Status status); + void engineClientStatusChanged(QDeclarativeDebugClient::Status status); void contextChanged(); void onCurrentObjectsChanged(const QList &debugIds, bool requestIfNeeded = true); void updateEngineList(); - void objectTreeFetched(QDeclarativeDebugQuery::State state = QDeclarativeDebugQuery::Completed); + void objectTreeFetched(QmlJsDebugClient::QDeclarativeDebugQuery::State state = QmlJsDebugClient::QDeclarativeDebugQuery::Completed); void fetchContextObjectRecursive(const QmlJsDebugClient::QDeclarativeDebugContextReference& context); void newObjects(); void objectWatchTriggered(const QByteArray &propertyName, const QVariant &propertyValue); diff --git a/src/plugins/qmljsinspector/qmljsinspector.cpp b/src/plugins/qmljsinspector/qmljsinspector.cpp index 2fd9f2c24cf375b0e64b72f8e4ce642f6794dd7e..559cfc29d3e14a3e0ee03126a3215808aeea1d8c 100644 --- a/src/plugins/qmljsinspector/qmljsinspector.cpp +++ b/src/plugins/qmljsinspector/qmljsinspector.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -272,13 +273,13 @@ void InspectorUi::showDebuggerTooltip(const QPoint &mousePos, TextEditor::ITextE if (!query.isEmpty()) { m_debugQuery = m_clientProxy->queryExpressionResult(ref.debugId(), query); - connect(m_debugQuery, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)), - this, SLOT(debugQueryUpdated(QDeclarativeDebugQuery::State))); + connect(m_debugQuery, SIGNAL(stateChanged(QmlJsDebugClient::QDeclarativeDebugQuery::State)), + this, SLOT(debugQueryUpdated(QmlJsDebugClient::QDeclarativeDebugQuery::State))); } } } -void InspectorUi::debugQueryUpdated(QDeclarativeDebugQuery::State newState) +void InspectorUi::debugQueryUpdated(QmlJsDebugClient::QDeclarativeDebugQuery::State newState) { if (newState != QDeclarativeDebugExpressionQuery::Completed) return; @@ -289,8 +290,8 @@ void InspectorUi::debugQueryUpdated(QDeclarativeDebugQuery::State newState) if (!text.isEmpty()) QToolTip::showText(QCursor::pos(), text); - disconnect(m_debugQuery, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)), - this, SLOT(debugQueryUpdated(QDeclarativeDebugQuery::State))); + disconnect(m_debugQuery, SIGNAL(stateChanged(QmlJsDebugClient::QDeclarativeDebugQuery::State)), + this, SLOT(debugQueryUpdated(QmlJsDebugClient::QDeclarativeDebugQuery::State))); } bool InspectorUi::isConnected() const @@ -525,24 +526,6 @@ inline QDeclarativeDebugObjectReference findParentRecursive( int goalDebugId, return QDeclarativeDebugObjectReference(); } -void InspectorUi::selectItems(const QList &objectReferences) -{ - foreach (const QDeclarativeDebugObjectReference &objref, objectReferences) { - if (objref.debugId() != -1) { - // select only the first valid element of the list - - m_clientProxy->removeAllObjectWatches(); - m_clientProxy->addObjectWatch(objref.debugId()); - QList selectionList; - selectionList << objref; - m_propertyInspector->setCurrentObjects(selectionList); - populateCrumblePath(objref); - gotoObjectReferenceDefinition(objref); - return; - } - } -} - inline QString displayName(const QDeclarativeDebugObjectReference &obj) { // special! state names @@ -566,6 +549,26 @@ inline QString displayName(const QDeclarativeDebugObjectReference &obj) return QString("<%1>").arg(objTypeName); } +void InspectorUi::selectItems(const QList &objectReferences) +{ + foreach (const QDeclarativeDebugObjectReference &objref, objectReferences) { + int debugId = objref.debugId(); + if (debugId != -1) { + // select only the first valid element of the list + + m_clientProxy->removeAllObjectWatches(); + m_clientProxy->addObjectWatch(debugId); + QList selectionList; + selectionList << objref; + m_propertyInspector->setCurrentObjects(selectionList); + populateCrumblePath(objref); + gotoObjectReferenceDefinition(objref); + m_clientProxy->qmlAdapter()->setCurrentSelectedDebugInfo(debugId, displayName(objref)); + break; + } + } +} + bool InspectorUi::isRoot(const QDeclarativeDebugObjectReference &obj) const { foreach (const QDeclarativeDebugObjectReference &rootObj, m_clientProxy->rootObjectReference()) diff --git a/src/plugins/qmljsinspector/qmljsinspector.h b/src/plugins/qmljsinspector/qmljsinspector.h index b38515e4ef7199bb05a51919eb35bcec679d1691..f760cfdc9b3348c9c785e2866f9a757d53138cf1 100644 --- a/src/plugins/qmljsinspector/qmljsinspector.h +++ b/src/plugins/qmljsinspector/qmljsinspector.h @@ -133,7 +133,7 @@ private slots: void updatePendingPreviewDocuments(QmlJS::Document::Ptr doc); void showDebuggerTooltip(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos); - void debugQueryUpdated(QDeclarativeDebugQuery::State); + void debugQueryUpdated(QmlJsDebugClient::QDeclarativeDebugQuery::State); private: bool addQuotesForData(const QVariant &value) const;