diff options
Diffstat (limited to 'src/plugins/debugger/qml/qmlengine.cpp')
-rw-r--r-- | src/plugins/debugger/qml/qmlengine.cpp | 264 |
1 files changed, 147 insertions, 117 deletions
diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index e142e7bddc..c2274c5e68 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -41,6 +41,8 @@ #include "debuggerrunner.h" #include "debuggerstringutils.h" #include "debuggertooltipmanager.h" +#include "localsandexpressionswindow.h" +#include "watchwindow.h" #include "breakhandler.h" #include "moduleshandler.h" @@ -49,13 +51,13 @@ #include "watchhandler.h" #include "sourcefileshandler.h" #include "watchutils.h" -#include "qtmessageloghandler.h" -#include <extensionsystem/pluginmanager.h> #include <qmldebug/baseenginedebugclient.h> #include <qmljseditor/qmljseditorconstants.h> #include <qmljs/parser/qmljsast_p.h> #include <qmljs/qmljsmodelmanagerinterface.h> +#include <qmljs/consolemanagerinterface.h> +#include <qmljs/consoleitem.h> #include <utils/environment.h> #include <utils/qtcassert.h> @@ -82,6 +84,8 @@ #include <QTcpSocket> #include <QHostAddress> +#include <QDockWidget> + #define DEBUG_QML 1 #if DEBUG_QML # define SDEBUG(s) qDebug() << s @@ -259,6 +263,11 @@ public: quint32 *column; }; +QmlJS::ConsoleManagerInterface *qmlConsoleManager() +{ + return QmlJS::ConsoleManagerInterface::instance(); +} + /////////////////////////////////////////////////////////////////////// // // QmlEngine @@ -274,8 +283,6 @@ QmlEngine::QmlEngine(const DebuggerStartParameters &startParameters) { setObjectName(QLatin1String("QmlEngine")); - ExtensionSystem::PluginManager::addObject(this); - connect(&m_adapter, SIGNAL(connectionError(QAbstractSocket::SocketError)), SLOT(connectionError(QAbstractSocket::SocketError))); connect(&m_adapter, SIGNAL(serviceConnectionError(QString)), @@ -289,7 +296,7 @@ QmlEngine::QmlEngine(const DebuggerStartParameters &startParameters) SLOT(updateCurrentContext())); connect(this->stackHandler(), SIGNAL(currentIndexChanged()), SLOT(updateCurrentContext())); - connect(&m_inspectorAdapter, SIGNAL(selectionChanged()), + connect(inspectorTreeView(), SIGNAL(currentIndexChanged(QModelIndex)), SLOT(updateCurrentContext())); connect(m_inspectorAdapter.agent(), SIGNAL( expressionResult(quint32,QVariant)), @@ -329,27 +336,23 @@ QmlEngine::QmlEngine(const DebuggerStartParameters &startParameters) m_noDebugOutputTimer.setInterval(8000); connect(&m_noDebugOutputTimer, SIGNAL(timeout()), this, SLOT(tryToConnect())); - qtMessageLogHandler()->setHasEditableRow(true); - - connect(ModelManagerInterface::instance(), - SIGNAL(documentUpdated(QmlJS::Document::Ptr)), - this, - SLOT(documentUpdated(QmlJS::Document::Ptr))); - + ModelManagerInterface *mmIface = ModelManagerInterface::instance(); + if (mmIface) { + connect(ModelManagerInterface::instance(), SIGNAL(documentUpdated(QmlJS::Document::Ptr)), + this, SLOT(documentUpdated(QmlJS::Document::Ptr))); + } // we won't get any debug output if (startParameters.useTerminal) { m_noDebugOutputTimer.setInterval(0); m_retryOnConnectFail = true; m_automaticConnect = true; } + if (qmlConsoleManager()) + qmlConsoleManager()->setScriptEvaluator(this); } QmlEngine::~QmlEngine() { - if (ExtensionSystem::PluginManager::allObjects().contains(this)) { - ExtensionSystem::PluginManager::removeObject(this); - } - QList<Core::IEditor *> editorsToClose; QHash<QString, QWeakPointer<TextEditor::ITextEditor> >::iterator iter; @@ -653,6 +656,8 @@ void QmlEngine::shutdownInferior() void QmlEngine::shutdownEngine() { + if (qmlConsoleManager()) + qmlConsoleManager()->setScriptEvaluator(0); m_noDebugOutputTimer.stop(); // double check (ill engine?): @@ -781,9 +786,9 @@ void QmlEngine::activateFrame(int index) gotoLocation(stackHandler()->frames().value(index)); } -void QmlEngine::selectThread(int index) +void QmlEngine::selectThread(ThreadId threadId) { - Q_UNUSED(index) + Q_UNUSED(threadId) } void QmlEngine::insertBreakpoint(BreakpointModelId id) @@ -1033,14 +1038,61 @@ void QmlEngine::synchronizeWatchers() } } +QmlJS::ConsoleItem *constructLogItemTree(QmlJS::ConsoleItem *parent, + const QVariant &result, + const QString &key = QString()) +{ + using namespace QmlJS; + bool sorted = debuggerCore()->boolSetting(SortStructMembers); + if (!result.isValid()) + return 0; + + ConsoleItem *item = new ConsoleItem(parent); + if (result.type() == QVariant::Map) { + if (key.isEmpty()) + item->setText(_("Object")); + else + item->setText(key + _(" : Object")); + + QMapIterator<QString, QVariant> i(result.toMap()); + while (i.hasNext()) { + i.next(); + ConsoleItem *child = constructLogItemTree(item, i.value(), i.key()); + if (child) + item->insertChild(child, sorted); + } + } else if (result.type() == QVariant::List) { + if (key.isEmpty()) + item->setText(_("List")); + else + item->setText(QString(_("[%1] : List")).arg(key)); + QVariantList resultList = result.toList(); + for (int i = 0; i < resultList.count(); i++) { + ConsoleItem *child = constructLogItemTree(item, resultList.at(i), + QString::number(i)); + if (child) + item->insertChild(child, sorted); + } + } else if (result.canConvert(QVariant::String)) { + item->setText(result.toString()); + } else { + item->setText(_("Unknown Value")); + } + + return item; +} + void QmlEngine::expressionEvaluated(quint32 queryId, const QVariant &result) { if (queryIds.contains(queryId)) { queryIds.removeOne(queryId); - QtMessageLogItem *item = constructLogItemTree(qtMessageLogHandler()->root(), - result); - if (item) - qtMessageLogHandler()->appendItem(item); + using namespace QmlJS; + ConsoleManagerInterface *consoleManager = qmlConsoleManager(); + if (consoleManager) { + ConsoleItem *item = constructLogItemTree(consoleManager->rootItem(), result); + if (item) + consoleManager->printToConsolePane(item); + } } } @@ -1093,36 +1145,55 @@ void QmlEngine::documentUpdated(QmlJS::Document::Ptr doc) void QmlEngine::updateCurrentContext() { - const QString context = state() == InferiorStopOk ? - stackHandler()->currentFrame().function : - m_inspectorAdapter.currentSelectedDisplayName(); - showMessage(tr("Context: ").append(context), QtMessageLogStatus); + QString context; + if (state() == InferiorStopOk) { + context = stackHandler()->currentFrame().function; + } else { + QModelIndex currentIndex = inspectorTreeView()->currentIndex(); + const WatchData *currentData = watchHandler()->watchData(currentIndex); + const WatchData *parentData = watchHandler()->watchData(currentIndex.parent()); + const WatchData *grandParentData = watchHandler()->watchData( + currentIndex.parent().parent()); + if (currentData->id != parentData->id) + context = currentData->name; + else if (parentData->id != grandParentData->id) + context = parentData->name; + else + context = grandParentData->name; + } + + QmlJS::ConsoleManagerInterface *consoleManager = qmlConsoleManager(); + if (consoleManager) + consoleManager->setContext(tr("Context: ").append(context)); } void QmlEngine::appendDebugOutput(QtMsgType type, const QString &message, const QmlDebug::QDebugContextInfo &info) { - QtMessageLogHandler::ItemType itemType; + using namespace QmlJS; + ConsoleItem::ItemType itemType; switch (type) { case QtDebugMsg: - itemType = QtMessageLogHandler::DebugType; + itemType = ConsoleItem::DebugType; break; case QtWarningMsg: - itemType = QtMessageLogHandler::WarningType; + itemType = ConsoleItem::WarningType; break; case QtCriticalMsg: case QtFatalMsg: - itemType = QtMessageLogHandler::ErrorType; + itemType = ConsoleItem::ErrorType; break; default: //This case is not possible return; } - QtMessageLogItem *item = new QtMessageLogItem(qtMessageLogHandler()->root(), - itemType, message); - item->file = info.file; - item->line = info.line; - qtMessageLogHandler()->appendItem(item); + ConsoleManagerInterface *consoleManager = qmlConsoleManager(); + if (consoleManager) { + ConsoleItem *item = new ConsoleItem(consoleManager->rootItem(), itemType, message); + item->file = info.file; + item->line = info.line; + consoleManager->printToConsolePane(item); + } } void QmlEngine::executeDebuggerCommand(const QString &command, DebuggerLanguages languages) @@ -1132,40 +1203,29 @@ void QmlEngine::executeDebuggerCommand(const QString &command, DebuggerLanguages } } -bool QmlEngine::evaluateScriptExpression(const QString &expression) +bool QmlEngine::evaluateScript(const QString &expression) { bool didEvaluate = true; - //Check if string is only white spaces - if (!expression.trimmed().isEmpty()) { - //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) { - QmlInspectorAgent *agent = m_inspectorAdapter.agent(); - quint32 queryId - = agent->queryExpressionResult( - m_inspectorAdapter.currentSelectedDebugId(), - expression); - if (queryId) { - queryIds << queryId; - } else { - didEvaluate = false; - qtMessageLogHandler()-> - appendItem( - new QtMessageLogItem( - qtMessageLogHandler()->root(), - QtMessageLogHandler::ErrorType, - _("Error evaluating expression."))); - } - } else { - executeDebuggerCommand(expression, QmlLanguage); - } + // Evaluate expression based on engine state + // When engine->state() == InferiorStopOk, the expression is sent to debuggerClient. + if (state() != InferiorStopOk) { + QModelIndex currentIndex = inspectorTreeView()->currentIndex(); + QmlInspectorAgent *agent = m_inspectorAdapter.agent(); + quint32 queryId = agent->queryExpressionResult(watchHandler()->watchData(currentIndex)->id, + expression); + if (queryId) { + queryIds << queryId; } else { didEvaluate = false; + using namespace QmlJS; + ConsoleManagerInterface *consoleManager = qmlConsoleManager(); + if (consoleManager) { + consoleManager->printToConsolePane(ConsoleItem::ErrorType, + _("Error evaluating expression.")); + } } + } else { + executeDebuggerCommand(expression, QmlLanguage); } return didEvaluate; } @@ -1272,69 +1332,39 @@ bool QmlEngine::canEvaluateScript(const QString &script) return m_interpreter.canEvaluate(); } -QtMessageLogItem *QmlEngine::constructLogItemTree( - QtMessageLogItem *parent, const QVariant &result, const QString &key) -{ - if (!result.isValid()) - return 0; - - QtMessageLogItem *item = new QtMessageLogItem(parent); - if (result.type() == QVariant::Map) { - if (key.isEmpty()) - item->setText(_("Object")); - else - item->setText(key + _(" : Object")); - - QMapIterator<QString, QVariant> i(result.toMap()); - while (i.hasNext()) { - i.next(); - QtMessageLogItem *child = constructLogItemTree(item, - i.value(), i.key()); - if (child) - item->insertChild(child); - } - } else if (result.type() == QVariant::List) { - if (key.isEmpty()) - item->setText(_("List")); - else - item->setText(QString(_("[%1] : List")).arg(key)); - QVariantList resultList = result.toList(); - for (int i = 0; i < resultList.count(); i++) { - QtMessageLogItem *child = constructLogItemTree(item, resultList.at(i), - QString::number(i)); - if (child) - item->insertChild(child); - } - } else if (result.canConvert(QVariant::String)) { - item->setText(result.toString()); - } else { - item->setText(_("Unknown Value")); - } - - return item; -} - bool QmlEngine::adjustBreakpointLineAndColumn( const QString &filePath, quint32 *line, quint32 *column, bool *valid) { - bool success = true; + bool success = false; //check if file is in the latest snapshot //ignoring documentChangedOnDisk //TODO:: update breakpoints if document is changed. - Document::Ptr doc = ModelManagerInterface::instance()->newestSnapshot(). - document(filePath); - if (doc.isNull()) { - ModelManagerInterface::instance()->updateSourceFiles( - QStringList() << filePath, false); - success = false; - } else { - ASTWalker walker; - walker(doc->ast(), line, column); - *valid = walker.done; + ModelManagerInterface *mmIface = ModelManagerInterface::instance(); + if (mmIface) { + Document::Ptr doc = mmIface->newestSnapshot(). + document(filePath); + if (doc.isNull()) { + ModelManagerInterface::instance()->updateSourceFiles( + QStringList() << filePath, false); + } else { + ASTWalker walker; + walker(doc->ast(), line, column); + *valid = walker.done; + success = true; + } } return success; } +WatchTreeView *QmlEngine::inspectorTreeView() const +{ + DebuggerMainWindow *dw = qobject_cast<DebuggerMainWindow *>(debuggerCore()->mainWindow()); + LocalsAndExpressionsWindow *leW = qobject_cast<LocalsAndExpressionsWindow *>( + dw->dockWidget(QLatin1String(Constants::DOCKWIDGET_WATCHERS))->widget()); + WatchWindow *inspectorWindow = qobject_cast<WatchWindow *>(leW->inspectorWidget()); + return qobject_cast<WatchTreeView *>(inspectorWindow->treeView()); +} + DebuggerEngine *createQmlEngine(const DebuggerStartParameters &sp) { return new QmlEngine(sp); |