Commit 7f09d0b7 authored by Kai Koehne's avatar Kai Koehne

Merge QML inspector into debugger plugin

Merge QmlJSInspector plugin into the debugger. Also merge the
extra Inspector window with the Locals & Watchers: It now shows
the QML object tree in the running state.

Change-Id: I59ae0c1b970a48ba10ecda92ed3ba765d94b1d9c
Reviewed-by: default avatarAurindam Jana <aurindam.jana@nokia.com>
parent d201c681
......@@ -55,7 +55,6 @@ Project {
"src/plugins/projectexplorer/projectexplorer.qbs",
"src/plugins/qmldesigner/qmldesigner.qbs",
"src/plugins/qmljseditor/qmljseditor.qbs",
"src/plugins/qmljsinspector/qmljsinspector.qbs",
"src/plugins/qmljstools/qmljstools.qbs",
"src/plugins/qmlprofiler/qmlprofiler.qbs",
"src/plugins/qmlprojectmanager/qmlprojectmanager.qbs",
......
......@@ -348,14 +348,16 @@ quint32 BaseEngineDebugClient::queryObjectRecursive(const QmlDebugObjectReferenc
}
quint32 BaseEngineDebugClient::queryExpressionResult(int objectDebugId,
const QString &expr)
const QString &expr,
int engineId)
{
quint32 id = 0;
if (status() == QmlDebugClient::Enabled && objectDebugId != -1) {
id = getId();
QByteArray message;
QDataStream ds(&message, QIODevice::WriteOnly);
ds << QByteArray("EVAL_EXPRESSION") << id << objectDebugId << expr;
ds << QByteArray("EVAL_EXPRESSION") << id << objectDebugId << expr
<< engineId;
sendMessage(message);
}
return id;
......
......@@ -66,7 +66,7 @@ public:
quint32 queryObject(const QmlDebugObjectReference &object);
quint32 queryObjectRecursive(const QmlDebugObjectReference &object);
quint32 queryExpressionResult(int objectDebugId,
const QString &expr);
const QString &expr, int engineId = -1);
virtual quint32 setBindingForObject(int objectDebugId, const QString &propertyName,
const QVariant &bindingExpression,
bool isLiteralValue,
......@@ -116,7 +116,7 @@ class QmlDebugEngineReference
{
public:
QmlDebugEngineReference() : m_debugId(-1) {}
QmlDebugEngineReference(int id) : m_debugId(id) {}
explicit QmlDebugEngineReference(int id) : m_debugId(id) {}
int debugId() const { return m_debugId; }
QString name() const { return m_name; }
......@@ -133,7 +133,7 @@ class QmlDebugObjectReference
{
public:
QmlDebugObjectReference() : m_debugId(-1), m_parentId(-1), m_contextDebugId(-1), m_needsMoreData(false) {}
QmlDebugObjectReference(int id) : m_debugId(id), m_parentId(-1), m_contextDebugId(-1), m_needsMoreData(false) {}
explicit QmlDebugObjectReference(int id) : m_debugId(id), m_parentId(-1), m_contextDebugId(-1), m_needsMoreData(false) {}
int debugId() const { return m_debugId; }
int parentId() const { return m_parentId; }
......@@ -148,18 +148,18 @@ public:
QList<QmlDebugPropertyReference> properties() const { return m_properties; }
QList<QmlDebugObjectReference> children() const { return m_children; }
bool insertObjectInTree(const QmlDebugObjectReference &obj)
int insertObjectInTree(const QmlDebugObjectReference &obj)
{
for (int i = 0; i < m_children.count(); i++) {
if (m_children[i].debugId() == obj.debugId()) {
m_children.replace(i, obj);
return true;
return debugId();
} else {
if (m_children[i].insertObjectInTree(obj))
return true;
return debugId();
}
}
return false;
return -1;
}
bool operator ==(const QmlDebugObjectReference &obj)
......@@ -229,4 +229,20 @@ Q_DECLARE_METATYPE(QmlDebug::QmlDebugEngineReference)
Q_DECLARE_METATYPE(QmlDebug::QmlDebugEngineReferenceList)
Q_DECLARE_METATYPE(QmlDebug::QmlDebugContextReference)
inline QDebug operator<<(QDebug dbg, const QmlDebug::QmlDebugEngineReference &ref) {
dbg.nospace() << "(Engine " << ref.debugId() << "/" << ref.name() << ")";
return dbg.space();
}
inline QDebug operator<<(QDebug dbg, const QmlDebug::QmlDebugContextReference &ref) {
dbg.nospace() << "(Context " << ref.debugId() << "/" << ref.name() << ")";
return dbg.space();
}
inline QDebug operator<<(QDebug dbg, const QmlDebug::QmlDebugObjectReference &ref) {
dbg.nospace() << "(Object " << ref.debugId() << "/"
<< (ref.idString().isEmpty() ? ref.idString() : ref.className()) << ")";
return dbg.space();
}
#endif // BASEENGINEDEBUGCLIENT_H
......@@ -31,10 +31,9 @@
#include "basetoolsclient.h"
namespace QmlJSInspector {
namespace Internal {
namespace QmlDebug {
BaseToolsClient::BaseToolsClient(QmlDebug::QmlDebugConnection* client, QLatin1String clientName)
BaseToolsClient::BaseToolsClient(QmlDebugConnection* client, QLatin1String clientName)
: QmlDebugClient(clientName, client)
{
setObjectName(clientName);
......@@ -45,14 +44,13 @@ void BaseToolsClient::statusChanged(Status status)
emit connectedStatusChanged(status);
}
void BaseToolsClient::recurseObjectIdList(const QmlDebug::QmlDebugObjectReference &ref,
void BaseToolsClient::recurseObjectIdList(const QmlDebugObjectReference &ref,
QList<int> &debugIds, QList<QString> &objectIds)
{
debugIds << ref.debugId();
objectIds << ref.idString();
foreach (const QmlDebug::QmlDebugObjectReference &child, ref.children())
foreach (const QmlDebugObjectReference &child, ref.children())
recurseObjectIdList(child, debugIds, objectIds);
}
} // namespace Internal
} // namespace QmlJSInspector
} // namespace QmlDebug
......@@ -32,17 +32,16 @@
#ifndef BASETOOLSCLIENT_H
#define BASETOOLSCLIENT_H
#include <qmldebug/qmldebugclient.h>
#include <qmldebug/baseenginedebugclient.h>
#include "qmldebugclient.h"
#include "baseenginedebugclient.h"
namespace QmlJSInspector {
namespace Internal {
namespace QmlDebug {
class BaseToolsClient : public QmlDebug::QmlDebugClient
class QMLDEBUG_EXPORT BaseToolsClient : public QmlDebugClient
{
Q_OBJECT
public:
BaseToolsClient(QmlDebug::QmlDebugConnection* client, QLatin1String clientName);
BaseToolsClient(QmlDebugConnection *client, QLatin1String clientName);
virtual void setCurrentObjects(const QList<int> &debugIds) = 0;
virtual void reloadViewer() = 0;
......@@ -67,7 +66,7 @@ public:
// ### Qt 4.8: remove if we can have access to qdeclarativecontextdata or id's
virtual void setObjectIdList(
const QList<QmlDebug::QmlDebugObjectReference> &objectRoots) = 0;
const QList<QmlDebugObjectReference> &objectRoots) = 0;
virtual void clearComponentCache() = 0;
......@@ -89,7 +88,7 @@ signals:
protected:
void statusChanged(Status);
void recurseObjectIdList(const QmlDebug::QmlDebugObjectReference &ref,
void recurseObjectIdList(const QmlDebugObjectReference &ref,
QList<int> &debugIds, QList<QString> &objectIds);
protected:
enum LogDirection {
......@@ -98,7 +97,6 @@ protected:
};
};
} // namespace Internal
} // namespace QmlJSInspector
} // namespace QmlDebug
#endif // BASETOOLSCLIENT_H
......@@ -30,16 +30,114 @@
**************************************************************************/
#include "declarativetoolsclient.h"
#include "qmljsclientproxy.h"
#include "qmljsinspectorconstants.h"
#include <QMetaEnum>
#include <QStringList>
using namespace QmlJSDebugger;
namespace QmlJSInspector {
namespace QmlDebug {
namespace Internal {
namespace Constants {
enum DesignTool {
NoTool = 0,
SelectionToolMode = 1,
MarqueeSelectionToolMode = 2,
MoveToolMode = 3,
ResizeToolMode = 4,
ZoomMode = 6
};
}
class InspectorProtocol : public QObject
{
Q_OBJECT
Q_ENUMS(Message Tool)
public:
enum Message {
AnimationSpeedChanged = 0,
AnimationPausedChanged = 19, // highest value
ChangeTool = 1,
ClearComponentCache = 2,
ColorChanged = 3,
CreateObject = 5,
CurrentObjectsChanged = 6,
DestroyObject = 7,
MoveObject = 8,
ObjectIdList = 9,
Reload = 10,
Reloaded = 11,
SetAnimationSpeed = 12,
SetAnimationPaused = 18,
SetCurrentObjects = 14,
SetDesignMode = 15,
ShowAppOnTop = 16,
ToolChanged = 17
};
enum Tool {
ColorPickerTool,
SelectMarqueeTool,
SelectTool,
ZoomTool
};
static inline QString toString(Message message)
{
return staticMetaObject.enumerator(0).valueToKey(message);
}
static inline QString toString(Tool tool)
{
return staticMetaObject.enumerator(1).valueToKey(tool);
}
};
inline QDataStream & operator<< (QDataStream &stream, InspectorProtocol::Message message)
{
return stream << static_cast<quint32>(message);
}
inline QDataStream & operator>> (QDataStream &stream, InspectorProtocol::Message &message)
{
quint32 i;
stream >> i;
message = static_cast<InspectorProtocol::Message>(i);
return stream;
}
inline QDebug operator<< (QDebug dbg, InspectorProtocol::Message message)
{
dbg << InspectorProtocol::toString(message);
return dbg;
}
inline QDataStream & operator<< (QDataStream &stream, InspectorProtocol::Tool tool)
{
return stream << static_cast<quint32>(tool);
}
inline QDataStream & operator>> (QDataStream &stream, InspectorProtocol::Tool &tool)
{
quint32 i;
stream >> i;
tool = static_cast<InspectorProtocol::Tool>(i);
return stream;
}
inline QDebug operator<< (QDebug dbg, InspectorProtocol::Tool tool)
{
dbg << InspectorProtocol::toString(tool);
return dbg;
}
} // internal
using namespace Internal;
DeclarativeToolsClient::DeclarativeToolsClient(QmlDebugConnection *client)
: BaseToolsClient(client,QLatin1String(Constants::QDECLARATIVE_OBSERVER_MODE)),
: BaseToolsClient(client,QLatin1String("QDeclarativeObserverMode")),
m_connection(client)
{
setObjectName(name());
......@@ -165,7 +263,7 @@ void DeclarativeToolsClient::setCurrentObjects(const QList<int> &debugIds)
}
void DeclarativeToolsClient::setObjectIdList(
const QList<QmlDebug::QmlDebugObjectReference> &objectRoots)
const QList<QmlDebugObjectReference> &objectRoots)
{
QByteArray message;
QDataStream ds(&message, QIODevice::WriteOnly);
......@@ -173,7 +271,7 @@ void DeclarativeToolsClient::setObjectIdList(
QList<int> debugIds;
QList<QString> objectIds;
foreach (const QmlDebug::QmlDebugObjectReference &ref, objectRoots)
foreach (const QmlDebugObjectReference &ref, objectRoots)
recurseObjectIdList(ref, debugIds, objectIds);
InspectorProtocol::Message cmd = InspectorProtocol::ObjectIdList;
......@@ -182,7 +280,7 @@ void DeclarativeToolsClient::setObjectIdList(
Q_ASSERT(debugIds.length() == objectIds.length());
for(int i = 0; i < debugIds.length(); ++i) {
for (int i = 0; i < debugIds.length(); ++i) {
ds << debugIds[i] << objectIds[i];
}
......@@ -423,7 +521,7 @@ void DeclarativeToolsClient::applyChangesFromQmlFile()
}
void DeclarativeToolsClient::log(LogDirection direction,
InspectorProtocol::Message message,
int message,
const QString &extra)
{
QString msg;
......@@ -432,11 +530,14 @@ void DeclarativeToolsClient::log(LogDirection direction,
else
msg += QLatin1String(" receiving ");
msg += InspectorProtocol::toString(message);
InspectorProtocol::Message msgType
= static_cast<InspectorProtocol::Message>(message);
msg += InspectorProtocol::toString(msgType);
msg += QLatin1Char(' ');
msg += extra;
emit logActivity(name(), msg);
}
} // namespace Internal
} // namespace QmlJSInspector
} // namespace QmlDebug
#include "declarativetoolsclient.moc"
......@@ -34,16 +34,13 @@
#include "basetoolsclient.h"
#include <inspectorprotocol.h>
namespace QmlDebug {
namespace QmlJSInspector {
namespace Internal {
class DeclarativeToolsClient : public BaseToolsClient
class QMLDEBUG_EXPORT DeclarativeToolsClient : public BaseToolsClient
{
Q_OBJECT
public:
DeclarativeToolsClient(QmlDebug::QmlDebugConnection *client);
DeclarativeToolsClient(QmlDebugConnection *client);
void setCurrentObjects(const QList<int> &debugIds);
void reloadViewer();
......@@ -67,7 +64,7 @@ public:
QList<int> currentObjects() const;
// ### Qt 4.8: remove if we can have access to qdeclarativecontextdata or id's
void setObjectIdList(const QList<QmlDebug::QmlDebugObjectReference> &objectRoots);
void setObjectIdList(const QList<QmlDebugObjectReference> &objectRoots);
void clearComponentCache();
......@@ -76,15 +73,14 @@ protected:
private:
void log(LogDirection direction,
QmlJSDebugger::InspectorProtocol::Message message,
int message,
const QString &extra = QString());
private:
QList<int> m_currentDebugIds;
QmlDebug::QmlDebugConnection *m_connection;
QmlDebugConnection *m_connection;
};
} // namespace Internal
} // namespace QmlJSInspector
} // namespace QmlDebug
#endif // DECLARATIVETOOLSCLIENT_H
......@@ -19,7 +19,10 @@ HEADERS += \
$$PWD/qv8profilerclient.h \
$$PWD/qmldebugconstants.h \
$$PWD/qdebugmessageclient.h \
$$PWD/qmlenginedebugclient.h
$$PWD/qmlenginedebugclient.h \
$$PWD/basetoolsclient.h \
$$PWD/declarativetoolsclient.h \
$$PWD/qmltoolsclient.h
SOURCES += \
$$PWD/qmldebugclient.cpp \
......@@ -29,5 +32,8 @@ SOURCES += \
$$PWD/qpacketprotocol.cpp \
$$PWD/qv8profilerclient.cpp \
$$PWD/qdebugmessageclient.cpp \
$$PWD/qmlenginedebugclient.cpp
$$PWD/qmlenginedebugclient.cpp \
$$PWD/basetoolsclient.cpp \
$$PWD/declarativetoolsclient.cpp \
$$PWD/qmltoolsclient.cpp
......@@ -20,6 +20,11 @@ QtcLibrary {
files: [
"baseenginedebugclient.cpp",
"baseenginedebugclient.h",
"basetoolsclient.cpp",
"basetoolsclient.h",
"declarativeenginedebugclient.h",
"declarativetoolsclient.cpp",
"declarativetoolsclient.h",
"qdebugmessageclient.cpp",
"qdebugmessageclient.h",
"qmldebugclient.cpp",
......@@ -34,7 +39,6 @@ QtcLibrary {
"qmlprofilertraceclient.h",
"qpacketprotocol.cpp",
"qpacketprotocol.h",
"declarativeenginedebugclient.h",
"qmlenginedebugclient.cpp",
"qmlenginedebugclient.h",
"qv8profilerclient.cpp",
......
......@@ -30,8 +30,7 @@
**************************************************************************/
#include "qmltoolsclient.h"
#include "qmljsclientproxy.h"
#include "qmljsinspectorconstants.h"
#include <QStringList>
//INSPECTOR SERVICE PROTOCOL
// <HEADER><COMMAND><DATA>
......@@ -61,11 +60,10 @@ const char DESTROY_OBJECT[] = "destroyObject";
const char MOVE_OBJECT[] = "moveObject";
const char CLEAR_CACHE[] = "clearCache";
namespace QmlJSInspector {
namespace Internal {
namespace QmlDebug {
QmlToolsClient::QmlToolsClient(QmlDebugConnection *client)
: BaseToolsClient(client, QLatin1String(Constants::QML_INSPECTOR)),
: BaseToolsClient(client, QLatin1String("QmlInspector")),
m_connection(client),
m_requestId(0),
m_slowDownFactor(1)
......@@ -328,5 +326,4 @@ void QmlToolsClient::log(LogDirection direction,
emit logActivity(name(), msg);
}
} // namespace Internal
} // namespace QmlJSInspector
} // namespace QmlDebug
......@@ -33,14 +33,14 @@
#define QMLTOOLSCLIENT_H
#include "basetoolsclient.h"
namespace QmlJSInspector {
namespace Internal {
class QmlToolsClient : public BaseToolsClient
namespace QmlDebug {
class QMLDEBUG_EXPORT QmlToolsClient : public BaseToolsClient
{
Q_OBJECT
public:
explicit QmlToolsClient(QmlDebug::QmlDebugConnection *client);
explicit QmlToolsClient(QmlDebugConnection *client);
void setCurrentObjects(const QList<int> &debugIds);
void reloadViewer();
......@@ -64,7 +64,7 @@ public:
QList<int> currentObjects() const;
// ### Qt 4.8: remove if we can have access to qdeclarativecontextdata or id's
void setObjectIdList(const QList<QmlDebug::QmlDebugObjectReference> &objectRoots);
void setObjectIdList(const QList<QmlDebugObjectReference> &objectRoots);
void clearComponentCache();
......@@ -78,12 +78,11 @@ private:
private:
QList<int> m_currentDebugIds;
QmlDebug::QmlDebugConnection *m_connection;
QmlDebugConnection *m_connection;
int m_requestId;
qreal m_slowDownFactor;
};
} // namespace Internal
} // namespace QmlJSInspector
} // namespace QmlDebug
#endif // QMLTOOLSCLIENT_H
......@@ -18,6 +18,7 @@ Alternatively, this plugin may be used under the terms of the GNU Lesser General
<dependency name=\"Core\" version=\"$$QTCREATOR_VERSION\"/>
<dependency name=\"Find\" version=\"$$QTCREATOR_VERSION\"/>
<dependency name=\"CppTools\" version=\"$$QTCREATOR_VERSION\"/>
<dependency name=\"QmlJSTools\" version=\"$$QTCREATOR_VERSION\"/>
<!-- Debugger plugin adds items to the editor\'s context menu -->
<dependency name=\"CppEditor\" version=\"$$QTCREATOR_VERSION\" type=\"optional\"/>
</dependencyList>
......
......@@ -74,6 +74,8 @@ CommonOptionsPageWidget::CommonOptionsPageWidget
m_ui.checkBoxSwitchModeOnExit);
m_group->insert(dc->action(RaiseOnInterrupt),
m_ui.checkBoxBringToForegroundOnInterrrupt);
m_group->insert(dc->action(ShowQmlObjectTree),
m_ui.checkBoxShowQmlObjectTree);
m_group->insert(dc->action(FontSizeFollowsEditor),
m_ui.checkBoxFontSizeFollowsEditor);
m_group->insert(dc->action(AutoDerefPointers), 0);
......@@ -123,6 +125,7 @@ QString CommonOptionsPageWidget::searchKeyWords() const
<< sep << m_ui.checkBoxSwitchModeOnExit->text()
<< sep << m_ui.labelMaximalStackDepth->text()
<< sep << m_ui.checkBoxBringToForegroundOnInterrrupt->text()
<< sep << m_ui.checkBoxShowQmlObjectTree->text()
;
rc.remove(QLatin1Char('&'));
return rc;
......
......@@ -120,7 +120,14 @@
</item>
</layout>
</item>
<item row="3" column="1">
<item row="3" column="0">
<widget class="QCheckBox" name="checkBoxBringToForegroundOnInterrrupt">
<property name="text">
<string>Bring Qt Creator to foreground when application interrupts</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="checkBoxRegisterForPostMortem">
<property name="toolTip">
<string>Register Qt Creator for debugging crashed applications.</string>
......@@ -130,10 +137,13 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="checkBoxBringToForegroundOnInterrrupt">
<item row="3" column="1">
<widget class="QCheckBox" name="checkBoxShowQmlObjectTree">
<property name="toolTip">
<string>Show QML object tree in Locals &amp; Expressions when connected and not stepping.</string>
</property>
<property name="text">
<string>Bring Qt Creator to foreground when application interrupts</string>
<string>Show QML object tree</string>
</property>
</widget>
</item>
......
......@@ -72,7 +72,8 @@ HEADERS += \
qtmessagelogview.h \
qtmessagelogproxymodel.h \
qtmessagelogitemdelegate.h \
qtmessageloghandler.h
qtmessageloghandler.h \
localsandwatcherswindow.h
SOURCES += \
basewindow.cpp \
......@@ -123,7 +124,8 @@ SOURCES += \
qtmessagelogview.cpp \
qtmessagelogitemdelegate.cpp \
qtmessageloghandler.cpp \
qtmessagelogeditor.cpp
qtmessagelogeditor.cpp \
localsandwatcherswindow.cpp
FORMS += attachexternaldialog.ui \
attachcoredialog.ui \
......
......@@ -8,6 +8,7 @@ QtcPlugin {
Depends { name: "qt"; submodules: ['widgets', 'network', 'script'] }
Depends { name: "Core" }
Depends { name: "CppTools" }
Depends { name: "QmlJSTools" }
Depends { name: "Find" }
Depends { name: "ProjectExplorer" }
Depends { name: "TextEditor" }
......@@ -75,6 +76,8 @@ QtcPlugin {
"disassemblerlines.cpp",
"disassemblerlines.h",
"dumperoptionpage.ui",
"localsandwatcherswindow.cpp",
"localsandwatcherswindow.h",
"logwindow.cpp",
"logwindow.h",