Skip to content
Snippets Groups Projects
Commit b3e1a13b authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Readded the QmlJS client proxy.

parent a88a635e
No related branches found
No related tags found
No related merge requests found
#include "qmljsclientproxy.h"
#include "qmljsdebuggerclient.h"
#include <utils/qtcassert.h>
#include <private/qdeclarativedebug_p.h>
#include <private/qdeclarativedebugclient_p.h>
#include <QUrl>
#include <QAbstractSocket>
#include <QDebug>
using namespace QmlJSInspector::Internal;
ClientProxy *ClientProxy::m_instance = 0;
ClientProxy::ClientProxy(QObject *parent) :
QObject(parent),
m_conn(0),
m_client(0),
m_engineQuery(0),
m_contextQuery(0),
m_objectTreeQuery(0),
m_debuggerRunControl(0)
{
m_instance = this;
}
ClientProxy *ClientProxy::instance()
{
return m_instance;
}
bool ClientProxy::connectToViewer(const QString &host, quint16 port)
{
if (m_conn && m_conn->state() != QAbstractSocket::UnconnectedState)
return false;
qDebug() << Q_FUNC_INFO;
if (m_client) {
disconnect(m_client, SIGNAL(propertyDumpReceived(QDeclarativeDebugPropertyDump)),
this, SIGNAL(propertyDumpReceived(QDeclarativeDebugPropertyDump)));
disconnect(m_client, SIGNAL(selectedItemsChanged(QList<QDeclarativeDebugObjectReference>)),
this, SIGNAL(selectedItemsChanged(QList<QDeclarativeDebugObjectReference>)));
emit aboutToDisconnect();
delete m_client; m_client = 0;
}
if (m_conn) {
m_conn->disconnectFromHost();
delete m_conn;
m_conn = 0;
}
m_conn = new QDeclarativeDebugConnection(this);
connect(m_conn, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
SLOT(connectionStateChanged()));
connect(m_conn, SIGNAL(error(QAbstractSocket::SocketError)),
SLOT(connectionError()));
emit connectionStatusMessage(tr("[Inspector] set to connect to debug server %1:%2").arg(host).arg(port));
m_conn->connectToHost(host, port);
// blocks until connected; if no connection is available, will fail immediately
if (!m_conn->waitForConnected())
return false;
// ### commented out as the code resulted in asserts
// QTC_ASSERT(m_debuggerRunControl, return false);
// Debugger::Internal::QmlEngine *engine = qobject_cast<Debugger::Internal::QmlEngine *>(m_debuggerRunControl->engine());
// QTC_ASSERT(engine, return false);
// (void) new DebuggerClient(m_conn, engine);
return true;
}
void ClientProxy::disconnectFromViewer()
{
m_conn->disconnectFromHost();
emit disconnected();
}
void ClientProxy::connectionError()
{
emit connectionStatusMessage(tr("[Inspector] error: (%1) %2", "%1=error code, %2=error message")
.arg(m_conn->error()).arg(m_conn->errorString()));
}
void ClientProxy::connectionStateChanged()
{
switch (m_conn->state()) {
case QAbstractSocket::UnconnectedState:
{
emit connectionStatusMessage(tr("[Inspector] disconnected.\n\n"));
delete m_engineQuery;
m_engineQuery = 0;
delete m_contextQuery;
m_contextQuery = 0;
if (m_objectTreeQuery) {
delete m_objectTreeQuery;
m_objectTreeQuery = 0;
}
emit disconnected();
break;
}
case QAbstractSocket::HostLookupState:
emit connectionStatusMessage(tr("[Inspector] resolving host..."));
break;
case QAbstractSocket::ConnectingState:
emit connectionStatusMessage(tr("[Inspector] connecting to debug server..."));
break;
case QAbstractSocket::ConnectedState:
{
emit connectionStatusMessage(tr("[Inspector] connected.\n"));
if (!m_client) {
qDebug() << "CREATING ENGINE";
m_client = new QDeclarativeEngineDebug(m_conn, this);
emit connected(m_client);
connect(m_client,
SIGNAL(propertyDumpReceived(QDeclarativeDebugPropertyDump)),
SIGNAL(propertyDumpReceived(QDeclarativeDebugPropertyDump)));
connect(m_client,
SIGNAL(selectedItemsChanged(QList<QDeclarativeDebugObjectReference>)),
SIGNAL(selectedItemsChanged(QList<QDeclarativeDebugObjectReference>)));
}
reloadEngines();
break;
}
case QAbstractSocket::ClosingState:
emit connectionStatusMessage(tr("[Inspector] closing..."));
break;
case QAbstractSocket::BoundState:
case QAbstractSocket::ListeningState:
break;
}
}
bool ClientProxy::isConnected() const
{
return (m_conn && m_client && m_conn->state() == QAbstractSocket::ConnectedState);
}
bool ClientProxy::isUnconnected() const
{
return (!m_conn || m_conn->state() == QAbstractSocket::UnconnectedState);
}
void ClientProxy::setSelectedItemByObjectId(int engineId, const QDeclarativeDebugObjectReference &objectRef)
{
qDebug() << "TODO:" << Q_FUNC_INFO;
#if 0
if (isConnected())
m_client->setSelectedItemByObjectId(engineId, objectRef);
#endif
}
QList<QDeclarativeDebugObjectReference> ClientProxy::objectReferences(const QUrl &url) const
{
return objectReferences(url, m_rootObject);
}
QList<QDeclarativeDebugObjectReference> ClientProxy::objectReferences(const QUrl &url,
const QDeclarativeDebugObjectReference &objectRef) const
{
QList<QDeclarativeDebugObjectReference> result;
if (objectRef.source().url() == url)
result.append(objectRef);
foreach(const QDeclarativeDebugObjectReference &child, objectRef.children()) {
result.append(objectReferences(url, child));
}
return result;
}
QDeclarativeDebugExpressionQuery *ClientProxy::setBindingForObject(int objectDebugId,
const QString &propertyName,
const QVariant &value,
bool isLiteralValue)
{
qDebug() << "TODO:" << Q_FUNC_INFO;
#if 0
if (propertyName == QLatin1String("id") || objectDebugId == -1)
return 0;
qDebug() << "executeBinding():" << objectDebugId << propertyName << value << "isLiteral:" << isLiteralValue;
return m_client->setBindingForObject(objectDebugId, propertyName, value.toString(), isLiteralValue, 0);
#else
return 0;
#endif
}
void ClientProxy::queryEngineContext(int id)
{
if (id < 0)
return;
if (m_contextQuery) {
delete m_contextQuery;
m_contextQuery = 0;
}
m_contextQuery = m_client->queryRootContexts(QDeclarativeDebugEngineReference(id), this);
if (!m_contextQuery->isWaiting())
contextChanged();
else
QObject::connect(m_contextQuery, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)),
this, SLOT(contextChanged()));
}
void ClientProxy::contextChanged()
{
if (m_contextQuery) {
if (m_contextQuery->rootContext().objects().isEmpty()) {
m_rootObject = QDeclarativeDebugObjectReference();
emit objectTreeUpdated(m_rootObject);
} else {
m_rootObject = m_contextQuery->rootContext().objects().first();
}
delete m_contextQuery; m_contextQuery = 0;
m_objectTreeQuery = m_client->queryObjectRecursive(m_rootObject, this);
if (!m_objectTreeQuery->isWaiting()) {
objectTreeFetched();
} else {
connect(m_objectTreeQuery,
SIGNAL(stateChanged(QDeclarativeDebugQuery::State)),
SLOT(objectTreeFetched(QDeclarativeDebugQuery::State)));
}
}
}
void ClientProxy::objectTreeFetched(QDeclarativeDebugQuery::State state)
{
if (state != QDeclarativeDebugQuery::Completed) {
m_rootObject = QDeclarativeDebugObjectReference();
return;
}
m_rootObject = m_objectTreeQuery->object();
delete m_objectTreeQuery;
m_objectTreeQuery = 0;
emit objectTreeUpdated(m_rootObject);
}
void ClientProxy::reloadQmlViewer(int engineId)
{
qDebug() << "TODO:" << Q_FUNC_INFO;
#if 0
if (m_client && m_conn->isConnected()) {
m_client->reloadQmlViewer(engineId);
}
#endif
}
void ClientProxy::reloadEngines()
{
if (m_engineQuery) {
emit connectionStatusMessage("[Inspector] Waiting for response to previous engine query");
return;
}
emit aboutToReloadEngines();
m_engineQuery = m_client->queryAvailableEngines(this);
if (!m_engineQuery->isWaiting())
updateEngineList();
else
QObject::connect(m_engineQuery, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)),
this, SLOT(updateEngineList()));
}
QList<QDeclarativeDebugEngineReference> ClientProxy::engines() const
{
return m_engines;
}
void ClientProxy::updateEngineList()
{
m_engines = m_engineQuery->engines();
delete m_engineQuery; m_engineQuery = 0;
emit enginesChanged();
}
#ifndef QMLJSCLIENTPROXY_H
#define QMLJSCLIENTPROXY_H
#include "qmljsinspectorplugin.h"
#include <private/qdeclarativedebug_p.h>
#include <QObject>
QT_FORWARD_DECLARE_CLASS(QUrl)
QT_FORWARD_DECLARE_CLASS(QDeclarativeEngineDebug)
QT_FORWARD_DECLARE_CLASS(QDeclarativeDebugConnection)
QT_FORWARD_DECLARE_CLASS(QDeclarativeDebugExpressionQuery)
QT_FORWARD_DECLARE_CLASS(QDeclarativeDebugPropertyDump)
namespace Debugger {
class DebuggerRunControl;
}
namespace QmlJSInspector {
namespace Internal {
class QmlInspectorPlugin;
class ClientProxy : public QObject
{
Q_OBJECT
public:
static ClientProxy *instance();
QDeclarativeDebugExpressionQuery *setBindingForObject(int objectDebugId,
const QString &propertyName,
const QVariant &value,
bool isLiteralValue);
// returns the object references for the given url.
QList<QDeclarativeDebugObjectReference> objectReferences(const QUrl &url) const;
bool isConnected() const;
bool isUnconnected() const;
void setSelectedItemByObjectId(int engineId, const QDeclarativeDebugObjectReference &objectRef);
bool connectToViewer(const QString &host, quint16 port);
void disconnectFromViewer();
QList<QDeclarativeDebugEngineReference> engines() const;
signals:
void objectTreeUpdated(const QDeclarativeDebugObjectReference &rootObject);
void connectionStatusMessage(const QString &text);
void aboutToReloadEngines();
void enginesChanged();
void propertyDumpReceived(const QDeclarativeDebugPropertyDump &propertyDump);
void selectedItemsChanged(const QList<QDeclarativeDebugObjectReference> &selectedItems);
void connected(QDeclarativeEngineDebug *client);
void aboutToDisconnect();
void disconnected();
public slots:
void queryEngineContext(int id);
void reloadQmlViewer(int engineId);
private slots:
void contextChanged();
void connectionStateChanged();
void connectionError();
void updateEngineList();
void objectTreeFetched(QDeclarativeDebugQuery::State state = QDeclarativeDebugQuery::Completed);
private:
void reloadEngines();
QList<QDeclarativeDebugObjectReference> objectReferences(const QUrl &url, const QDeclarativeDebugObjectReference &objectRef) const;
private:
explicit ClientProxy(QObject *parent = 0);
Q_DISABLE_COPY(ClientProxy);
static ClientProxy *m_instance;
QDeclarativeDebugConnection *m_conn;
QDeclarativeEngineDebug *m_client;
QDeclarativeDebugEnginesQuery *m_engineQuery;
QDeclarativeDebugRootContextQuery *m_contextQuery;
QDeclarativeDebugObjectQuery *m_objectTreeQuery;
QDeclarativeDebugObjectReference m_rootObject;
QList<QDeclarativeDebugEngineReference> m_engines;
Debugger::DebuggerRunControl *m_debuggerRunControl;
friend class QmlJSInspector::Internal::QmlInspectorPlugin;
};
} // namespace Internal
} // namespace QmlJSInspector
#endif // QMLJSCLIENTPROXY_H
......@@ -2,7 +2,7 @@ TEMPLATE = lib
TARGET = QmlJSInspector
INCLUDEPATH += .
DEPENDPATH += .
QT += declarative
QT += declarative network
include(../../private_headers.pri)
......@@ -13,12 +13,14 @@ qmljsdebuggerclient.h \
qmljsinspector_global.h \
qmljsinspectorconstants.h \
qmljsinspectorcontext.h \
qmljsinspectorplugin.h
qmljsinspectorplugin.h \
qmljsclientproxy.h
SOURCES += \
qmljsdebuggerclient.cpp \
qmljsinspectorcontext.cpp \
qmljsinspectorplugin.cpp
qmljsinspectorplugin.cpp \
qmljsclientproxy.cpp
OTHER_FILES += QmlJSInspector.pluginspec
RESOURCES += qmljsinspector.qrc
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment