QML Debugger refactoring

Now, QmlEngine creates the connection to the inferior (debuggee), and
notifies QmlInspector when a connection is established. Before,
inspector created the debugger engin, which was wrong.

QmlEngine's responsibilities are connecting to the debuggee and basic
QML/JS debugging features like locals & watchers, breakpoints etc.
QmlInspector takes care of Live Preview and other fancy inspection
features.

Reviewed-by: hjk
This commit is contained in:
Lasse Holmstedt
2010-08-13 14:18:10 +02:00
parent 5de57ddad3
commit b71c3c62ba
24 changed files with 821 additions and 643 deletions

View File

@@ -112,7 +112,12 @@ include(cdb/cdb.pri)
include(gdb/gdb.pri) include(gdb/gdb.pri)
include(script/script.pri) include(script/script.pri)
include(pdb/pdb.pri) include(pdb/pdb.pri)
contains(QT_CONFIG, declarative) {
QT += declarative
include(qml/qml.pri) include(qml/qml.pri)
}
include(tcf/tcf.pri) include(tcf/tcf.pri)
include(shared/shared.pri) include(shared/shared.pri)

View File

@@ -76,6 +76,10 @@ public:
bool breakAtMain; bool breakAtMain;
QString crashParameter; // for AttachCrashedExternal QString crashParameter; // for AttachCrashedExternal
// for qml debugging
QString qmlServerAddress;
quint16 qmlServerPort;
// for remote debugging // for remote debugging
QString remoteChannel; QString remoteChannel;
QString remoteArchitecture; QString remoteArchitecture;

View File

@@ -331,7 +331,7 @@ void DebuggerRunControl::createEngine(const DebuggerStartParameters &sp)
QString errorMessage; QString errorMessage;
QString settingsIdHint; QString settingsIdHint;
if (sp.executable.endsWith(_("qmlviewer"))) if (sp.executable.endsWith(_("qmlviewer")) || sp.executable.endsWith(_("qmlobserver")))
engineType = QmlEngineType; engineType = QmlEngineType;
else if (sp.executable.endsWith(_(".js"))) else if (sp.executable.endsWith(_(".js")))
engineType = ScriptEngineType; engineType = ScriptEngineType;

View File

@@ -1,4 +1,12 @@
include($$PWD/../../../libs/qmljsdebugclient/qmljsdebugclient-lib.pri)
HEADERS += $$PWD/qmlengine.h HEADERS += \
SOURCES += $$PWD/qmlengine.cpp $$PWD/qmlengine.h \
$$PWD/qmladapter.h \
$$PWD/qmldebuggerclient.h \
$$PWD/qmljsprivateapi.h
SOURCES += \
$$PWD/qmlengine.cpp \
$$PWD/qmladapter.cpp \
$$PWD/qmldebuggerclient.cpp

View File

@@ -0,0 +1,204 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "qmladapter.h"
#include "qmldebuggerclient.h"
#include "qmljsprivateapi.h"
#include "debuggerengine.h"
#include <QAbstractSocket>
#include <QTimer>
#include <QDebug>
namespace Debugger {
namespace Internal {
QmlAdapter::QmlAdapter(DebuggerEngine *engine, QObject *parent)
: QObject(parent)
, m_engine(engine)
, m_qmlClient(0)
, m_mainClient(0)
, m_connectionTimer(new QTimer(this))
, m_connectionAttempts(0)
, m_conn(0)
{
connect(m_connectionTimer, SIGNAL(timeout()), SLOT(pollInferior()));
}
void QmlAdapter::beginConnection()
{
m_connectionTimer->start();
}
void QmlAdapter::pollInferior()
{
++m_connectionAttempts;
if (connectToViewer()) {
m_connectionTimer->stop();
m_connectionAttempts = 0;
} else if (m_connectionAttempts == m_maxConnectionAttempts) {
emit connectionStartupFailed();
m_connectionTimer->stop();
m_connectionAttempts = 0;
}
}
bool QmlAdapter::connectToViewer()
{
if (m_engine.isNull() || (m_conn && m_conn->state() != QAbstractSocket::UnconnectedState))
return false;
m_conn = new QDeclarativeDebugConnection(this);
connect(m_conn, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
SLOT(connectionStateChanged()));
connect(m_conn, SIGNAL(error(QAbstractSocket::SocketError)),
SLOT(connectionErrorOccurred()));
QString address = m_engine.data()->startParameters().qmlServerAddress;
QString port = QString::number(m_engine.data()->startParameters().qmlServerPort);
showConnectionStatusMessage(tr("Connect to debug server %1:%2").arg(address).arg(port));
m_conn->connectToHost(m_engine.data()->startParameters().qmlServerAddress,
m_engine.data()->startParameters().qmlServerPort);
// blocks until connected; if no connection is available, will fail immediately
if (!m_conn->waitForConnected())
return false;
return true;
}
void QmlAdapter::connectionErrorOccurred()
{
showConnectionErrorMessage(tr("Error: (%1) %2", "%1=error code, %2=error message")
.arg(m_conn->error()).arg(m_conn->errorString()));
// this is only an error if we are already connected and something goes wrong.
if (isConnected())
emit connectionError();
}
void QmlAdapter::connectionStateChanged()
{
switch (m_conn->state()) {
case QAbstractSocket::UnconnectedState:
{
showConnectionStatusMessage(tr("disconnected.\n\n"));
emit disconnected();
break;
}
case QAbstractSocket::HostLookupState:
showConnectionStatusMessage(tr("resolving host..."));
break;
case QAbstractSocket::ConnectingState:
showConnectionStatusMessage(tr("connecting to debug server..."));
break;
case QAbstractSocket::ConnectedState:
{
showConnectionStatusMessage(tr("connected.\n"));
if (!m_mainClient) {
m_mainClient = new QDeclarativeEngineDebug(m_conn, this);
}
createDebuggerClient();
//reloadEngines();
emit connected();
break;
}
case QAbstractSocket::ClosingState:
showConnectionStatusMessage(tr("closing..."));
break;
case QAbstractSocket::BoundState:
case QAbstractSocket::ListeningState:
break;
}
}
void QmlAdapter::createDebuggerClient()
{
m_qmlClient = new QmlDebuggerClient(m_conn);
connect(m_engine.data(), SIGNAL(sendMessage(QByteArray)),
m_qmlClient, SLOT(slotSendMessage(QByteArray)));
connect(m_qmlClient, SIGNAL(messageWasReceived(QByteArray)),
m_engine.data(), SLOT(messageReceived(QByteArray)));
//engine->startSuccessful(); // FIXME: AAA: port to new debugger states
}
bool QmlAdapter::isConnected() const
{
return m_conn && m_qmlClient && m_conn->state() == QAbstractSocket::ConnectedState;
}
bool QmlAdapter::isUnconnected() const
{
return !m_conn || m_conn->state() == QAbstractSocket::UnconnectedState;
}
QDeclarativeEngineDebug *QmlAdapter::client() const
{
return m_mainClient;
}
QDeclarativeDebugConnection *QmlAdapter::connection() const
{
if (!isConnected())
return 0;
return m_conn;
}
void QmlAdapter::showConnectionStatusMessage(const QString &message)
{
if (!m_engine.isNull())
m_engine.data()->showMessage(QLatin1String("QmlJSDebugger: ") + message, LogStatus);
}
void QmlAdapter::showConnectionErrorMessage(const QString &message)
{
if (!m_engine.isNull())
m_engine.data()->showMessage(QLatin1String("QmlJSDebugger: ") + message, LogError);
}
void QmlAdapter::setMaxConnectionAttempts(int maxAttempts)
{
m_maxConnectionAttempts = maxAttempts;
}
void QmlAdapter::setConnectionAttemptInterval(int interval)
{
m_connectionAttemptInterval = interval;
}
} // namespace Internal
} // namespace Debugger

View File

@@ -0,0 +1,98 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef QMLADAPTER_H
#define QMLADAPTER_H
#include <QObject>
#include <QWeakPointer>
#include "qmljsprivateapi.h"
#include "debugger_global.h"
QT_FORWARD_DECLARE_CLASS(QTimer)
namespace Debugger {
namespace Internal {
class DebuggerEngine;
class QmlDebuggerClient;
class DEBUGGER_EXPORT QmlAdapter : public QObject
{
Q_OBJECT
public:
explicit QmlAdapter(DebuggerEngine *engine, QObject *parent = 0);
void beginConnection();
bool isConnected() const;
bool isUnconnected() const;
QDeclarativeEngineDebug *client() const;
QDeclarativeDebugConnection *connection() const;
// TODO move to private API b/w engine and adapter
void setMaxConnectionAttempts(int maxAttempts);
void setConnectionAttemptInterval(int interval);
signals:
void aboutToDisconnect();
void connected();
void disconnected();
void connectionStartupFailed();
void connectionError();
private slots:
void connectionErrorOccurred();
void connectionStateChanged();
void pollInferior();
private:
bool connectToViewer();
void createDebuggerClient();
void showConnectionStatusMessage(const QString &message);
void showConnectionErrorMessage(const QString &message);
private:
QWeakPointer<DebuggerEngine> m_engine;
QmlDebuggerClient *m_qmlClient;
QDeclarativeEngineDebug *m_mainClient;
QTimer *m_connectionTimer;
int m_connectionAttempts;
int m_maxConnectionAttempts;
int m_connectionAttemptInterval;
QDeclarativeDebugConnection *m_conn;
};
} // namespace Internal
} // namespace Debugger
#endif // QMLADAPTER_H

View File

@@ -26,29 +26,33 @@
** contact the sales department at http://qt.nokia.com/contact. ** contact the sales department at http://qt.nokia.com/contact.
** **
**************************************************************************/ **************************************************************************/
#include "qmljsdebuggerclient.h" #include "qmldebuggerclient.h"
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
using namespace QmlJSInspector::Internal; namespace Debugger {
namespace Internal {
DebuggerClient::DebuggerClient(QDeclarativeDebugConnection* client) QmlDebuggerClient::QmlDebuggerClient(QmlJsDebugClient::QDeclarativeDebugConnection* client)
: QDeclarativeDebugClient(QLatin1String("JSDebugger"), client) : QDeclarativeDebugClient(QLatin1String("JSDebugger"), client)
{ {
setEnabled(true); setEnabled(true);
} }
DebuggerClient::~DebuggerClient() QmlDebuggerClient::~QmlDebuggerClient()
{ {
} }
void DebuggerClient::messageReceived(const QByteArray &data) void QmlDebuggerClient::messageReceived(const QByteArray &data)
{ {
emit messageWasReceived(data); emit messageWasReceived(data);
} }
void DebuggerClient::slotSendMessage(const QByteArray &message) void QmlDebuggerClient::slotSendMessage(const QByteArray &message)
{ {
QDeclarativeDebugClient::sendMessage(message); QDeclarativeDebugClient::sendMessage(message);
} }
} // Internal
} // Debugger

View File

@@ -32,16 +32,16 @@
#include "qmljsprivateapi.h" #include "qmljsprivateapi.h"
namespace QmlJSInspector { namespace Debugger {
namespace Internal { namespace Internal {
class DebuggerClient : public QDeclarativeDebugClient class QmlDebuggerClient : public QDeclarativeDebugClient
{ {
Q_OBJECT Q_OBJECT
public: public:
DebuggerClient(QDeclarativeDebugConnection *client); QmlDebuggerClient(QmlJsDebugClient::QDeclarativeDebugConnection *client);
virtual ~DebuggerClient(); virtual ~QmlDebuggerClient();
signals: signals:
void messageWasReceived(const QByteArray &data); void messageWasReceived(const QByteArray &data);

View File

@@ -28,6 +28,7 @@
**************************************************************************/ **************************************************************************/
#include "qmlengine.h" #include "qmlengine.h"
#include "qmladapter.h"
#include "debuggerconstants.h" #include "debuggerconstants.h"
#include "debuggerplugin.h" #include "debuggerplugin.h"
@@ -42,6 +43,7 @@
#include "watchhandler.h" #include "watchhandler.h"
#include "watchutils.h" #include "watchutils.h"
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/environment.h> #include <projectexplorer/environment.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -70,7 +72,10 @@
#endif #endif
# define XSDEBUG(s) qDebug() << s # define XSDEBUG(s) qDebug() << s
enum {
MaxConnectionAttempts = 50,
ConnectionAttemptDefaultInterval = 75
};
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
@@ -96,8 +101,12 @@ QDataStream& operator>>(QDataStream& s, WatchData &data)
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
QmlEngine::QmlEngine(const DebuggerStartParameters &startParameters) QmlEngine::QmlEngine(const DebuggerStartParameters &startParameters)
: DebuggerEngine(startParameters), m_ping(0) : DebuggerEngine(startParameters)
, m_ping(0)
, m_adapter(new QmlAdapter(this))
, m_addedAdapterToObjectPool(false)
{ {
} }
QmlEngine::~QmlEngine() QmlEngine::~QmlEngine()
@@ -107,32 +116,91 @@ QmlEngine::~QmlEngine()
void QmlEngine::setupInferior() void QmlEngine::setupInferior()
{ {
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
attemptBreakpointSynchronization();
connect(&m_applicationLauncher, SIGNAL(processExited(int)), SLOT(disconnected()));
m_applicationLauncher.setEnvironment(startParameters().environment);
m_applicationLauncher.setWorkingDirectory(startParameters().workingDirectory);
notifyInferiorSetupOk(); notifyInferiorSetupOk();
} }
void QmlEngine::connectionEstablished()
{
attemptBreakpointSynchronization();
ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance();
pluginManager->addObject(m_adapter);
m_addedAdapterToObjectPool = true;
plugin()->showMessage(tr("QML Debugger connected."), StatusBar);
notifyEngineRunAndInferiorRunOk();
}
void QmlEngine::connectionStartupFailed()
{
QMessageBox::critical(0,
tr("Failed to connect to debugger"),
tr("Could not connect to debugger server.") );
notifyEngineRunFailed();
}
void QmlEngine::connectionError()
{
// do nothing for now - only exit the debugger when inferior exits.
}
void QmlEngine::runEngine() void QmlEngine::runEngine()
{ {
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
notifyEngineRunAndInferiorRunOk();
// ### TODO for non-qmlproject apps, start in a different way
m_applicationLauncher.start(ProjectExplorer::ApplicationLauncher::Gui,
startParameters().executable,
startParameters().processArgs);
m_adapter->beginConnection();
plugin()->showMessage(tr("QML Debugger connecting..."), StatusBar);
} }
void QmlEngine::shutdownInferior() void QmlEngine::shutdownInferior()
{ {
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state()); QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
if (!m_applicationLauncher.isRunning()) {
showMessage(tr("Trying to stop while process is no longer running."), LogError);
} else {
disconnect(&m_applicationLauncher, SIGNAL(processExited(int)), this, SLOT(disconnected()));
m_applicationLauncher.stop();
}
notifyInferiorShutdownOk(); notifyInferiorShutdownOk();
} }
void QmlEngine::shutdownEngine() void QmlEngine::shutdownEngine()
{ {
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
if (m_addedAdapterToObjectPool) {
ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance();
pluginManager->removeObject(m_adapter);
}
if (m_applicationLauncher.isRunning()) {
// should only happen if engine is ill
disconnect(&m_applicationLauncher, SIGNAL(processExited(int)), this, SLOT(disconnected()));
m_applicationLauncher.stop();
}
notifyEngineShutdownOk(); notifyEngineShutdownOk();
} }
const int serverPort = 3768;
void QmlEngine::setupEngine() void QmlEngine::setupEngine()
{ {
m_adapter->setMaxConnectionAttempts(MaxConnectionAttempts);
m_adapter->setConnectionAttemptInterval(ConnectionAttemptDefaultInterval);
connect(m_adapter, SIGNAL(connectionError()), SLOT(connectionError()));
connect(m_adapter, SIGNAL(connected()), SLOT(connectionEstablished()));
connect(m_adapter, SIGNAL(connectionStartupFailed()), SLOT(connectionStartupFailed()));
notifyEngineSetupOk(); notifyEngineSetupOk();
} }
@@ -368,8 +436,6 @@ void QmlEngine::sendPing()
sendMessage(reply); sendMessage(reply);
} }
DebuggerEngine *createQmlEngine(const DebuggerStartParameters &sp) DebuggerEngine *createQmlEngine(const DebuggerStartParameters &sp)
{ {
return new QmlEngine(sp); return new QmlEngine(sp);
@@ -520,6 +586,7 @@ void QmlEngine::messageReceived(const QByteArray &message)
void QmlEngine::disconnected() void QmlEngine::disconnected()
{ {
plugin()->showMessage(tr("QML Debugger disconnected."), StatusBar);
notifyInferiorExited(); notifyInferiorExited();
} }

View File

@@ -44,12 +44,14 @@
#include <QtNetwork/QAbstractSocket> #include <QtNetwork/QAbstractSocket>
#include <QtNetwork/QTcpSocket> #include <QtNetwork/QTcpSocket>
#include <projectexplorer/applicationlauncher.h>
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
class ScriptAgent; class ScriptAgent;
class WatchData; class WatchData;
class QmlAdapter;
class QmlResponse; class QmlResponse;
class QmlDebuggerClient; class QmlDebuggerClient;
@@ -57,7 +59,6 @@ class DEBUGGER_EXPORT QmlEngine : public DebuggerEngine
{ {
Q_OBJECT Q_OBJECT
int m_ping;
public: public:
explicit QmlEngine(const DebuggerStartParameters &startParameters); explicit QmlEngine(const DebuggerStartParameters &startParameters);
~QmlEngine(); ~QmlEngine();
@@ -112,9 +113,21 @@ private:
signals: signals:
void sendMessage(const QByteArray &msg); void sendMessage(const QByteArray &msg);
private slots:
void connectionEstablished();
void connectionStartupFailed();
void connectionError();
private: private:
void expandObject(const QByteArray &iname, quint64 objectId); void expandObject(const QByteArray &iname, quint64 objectId);
void sendPing(); void sendPing();
private:
int m_ping;
QmlAdapter *m_adapter;
ProjectExplorer::ApplicationLauncher m_applicationLauncher;
bool m_addedAdapterToObjectPool;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -26,51 +26,12 @@
** contact the sales department at http://qt.nokia.com/contact. ** contact the sales department at http://qt.nokia.com/contact.
** **
**************************************************************************/ **************************************************************************/
#ifndef QMLJSPRIVATEAPI_H
#define QMLJSPRIVATEAPI_H
#ifndef QMLJSINSPECTORCONTEXT_H #include <qmljsdebugclient/qdeclarativedebug_p.h>
#define QMLJSINSPECTORCONTEXT_H #include <qmljsdebugclient/qdeclarativedebugclient_p.h>
#include <coreplugin/icontext.h> using namespace QmlJsDebugClient;
#include <QList>
QT_BEGIN_NAMESPACE
class QWidget;
QT_END_NAMESPACE
namespace QmlJSInspector {
namespace Internal {
class ObjectPropertiesView;
class ObjectTree;
class DesignModeWidget;
class InspectorContext : public Core::IContext
{
Q_OBJECT
public:
InspectorContext(QWidget *widget);
virtual ~InspectorContext();
// Core::IContext interface
virtual Core::Context context() const;
virtual QWidget *widget();
virtual QString contextHelpId() const;
static QString contextHelpIdForProperty(const QString &itemName, const QString &propName);
static QString contextHelpIdForItem(const QString &itemName);
public slots:
void setContextHelpId(const QString &helpId);
private:
QWidget *m_widget;
Core::Context m_context;
QString m_contextHelpId;
};
} // Internal
} // QmlInspector
#endif
#endif // QMLJSPRIVATEAPI_H

View File

@@ -35,12 +35,13 @@ SUBDIRS = plugin_coreplugin \
plugin_qmljseditor \ plugin_qmljseditor \
plugin_mercurial \ plugin_mercurial \
plugin_classview \ plugin_classview \
plugin_qmljsinspector \
debugger/dumper.pro debugger/dumper.pro
contains(QT_CONFIG, declarative) { contains(QT_CONFIG, declarative) {
SUBDIRS += plugin_qmlprojectmanager SUBDIRS += \
plugin_qmlprojectmanager \
plugin_qmljsinspector
include(../private_headers.pri) include(../private_headers.pri)
exists($${QT_PRIVATE_HEADERS}/QtDeclarative/private/qdeclarativecontext_p.h) { exists($${QT_PRIVATE_HEADERS}/QtDeclarative/private/qdeclarativecontext_p.h) {

View File

@@ -28,13 +28,13 @@
**************************************************************************/ **************************************************************************/
#include "qmljsclientproxy.h" #include "qmljsclientproxy.h"
#include "qmljsdebuggerclient.h"
#include "qmljsprivateapi.h" #include "qmljsprivateapi.h"
#include "qmljsdesigndebugclient.h" #include "qmljsdesigndebugclient.h"
#include <debugger/debuggerplugin.h> #include <debugger/debuggerplugin.h>
#include <debugger/debuggerrunner.h> #include <debugger/debuggerrunner.h>
#include <debugger/qml/qmlengine.h> #include <debugger/qml/qmlengine.h>
#include <debugger/qml/qmladapter.h>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -44,33 +44,54 @@
using namespace QmlJSInspector::Internal; using namespace QmlJSInspector::Internal;
ClientProxy *ClientProxy::m_instance = 0; ClientProxy::ClientProxy(Debugger::Internal::QmlAdapter *adapter, QObject *parent)
: QObject(parent)
ClientProxy::ClientProxy(QObject *parent) : , m_adapter(adapter)
QObject(parent), , m_client(m_adapter->client())
m_conn(0), , m_designClient(0)
m_client(0), , m_engineQuery(0)
m_designClient(0), , m_contextQuery(0)
m_engineQuery(0), , m_objectTreeQuery(0)
m_contextQuery(0),
m_objectTreeQuery(0)
{ {
Q_ASSERT(! m_instance);
m_instance = this; connect(m_adapter, SIGNAL(aboutToDisconnect()), SLOT(disconnectFromServer()));
connectToServer();
} }
ClientProxy *ClientProxy::instance() void ClientProxy::connectToServer()
{ {
return m_instance; m_designClient = new QmlJSDesignDebugClient(m_adapter->connection(), this);
emit connected();
connect(m_designClient, SIGNAL(currentObjectsChanged(QList<int>)),
SLOT(onCurrentObjectsChanged(QList<int>)));
connect(m_designClient, SIGNAL(colorPickerActivated()),
SIGNAL(colorPickerActivated()));
connect(m_designClient, SIGNAL(zoomToolActivated()),
SIGNAL(zoomToolActivated()));
connect(m_designClient, SIGNAL(selectToolActivated()),
SIGNAL(selectToolActivated()));
connect(m_designClient, SIGNAL(selectMarqueeToolActivated()),
SIGNAL(selectMarqueeToolActivated()));
connect(m_designClient, SIGNAL(animationSpeedChanged(qreal)),
SIGNAL(animationSpeedChanged(qreal)));
connect(m_designClient, SIGNAL(designModeBehaviorChanged(bool)),
SIGNAL(designModeBehaviorChanged(bool)));
connect(m_designClient, SIGNAL(reloaded()), this,
SIGNAL(serverReloaded()));
connect(m_designClient, SIGNAL(selectedColorChanged(QColor)),
SIGNAL(selectedColorChanged(QColor)));
connect(m_designClient, SIGNAL(contextPathUpdated(QStringList)),
SIGNAL(contextPathUpdated(QStringList)));
connect(m_designClient, SIGNAL(treeRefreshRequested()),
SLOT(refreshObjectTree()));
reloadEngines();
} }
bool ClientProxy::connectToViewer(const QString &host, quint16 port) void ClientProxy::disconnectFromServer()
{ {
if (m_conn && m_conn->state() != QAbstractSocket::UnconnectedState)
return false;
if (m_designClient) { if (m_designClient) {
disconnect(m_designClient, SIGNAL(currentObjectsChanged(QList<int>)), disconnect(m_designClient, SIGNAL(currentObjectsChanged(QList<int>)),
this, SLOT(onCurrentObjectsChanged(QList<int>))); this, SLOT(onCurrentObjectsChanged(QList<int>)));
disconnect(m_designClient, SIGNAL(colorPickerActivated()), disconnect(m_designClient, SIGNAL(colorPickerActivated()),
@@ -92,36 +113,22 @@ bool ClientProxy::connectToViewer(const QString &host, quint16 port)
disconnect(m_designClient, SIGNAL(treeRefreshRequested()), disconnect(m_designClient, SIGNAL(treeRefreshRequested()),
this, SLOT(refreshObjectTree())); this, SLOT(refreshObjectTree()));
emit aboutToDisconnect();
delete m_client;
m_client = 0;
delete m_designClient; delete m_designClient;
m_designClient = 0; m_designClient = 0;
} }
if (m_conn) { if (m_engineQuery)
m_conn->disconnectFromHost(); delete m_engineQuery;
delete m_conn; m_engineQuery = 0;
m_conn = 0;
if (m_contextQuery)
delete m_contextQuery;
m_contextQuery = 0;
if (m_objectTreeQuery) {
delete m_objectTreeQuery;
m_objectTreeQuery = 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;
return true;
} }
void ClientProxy::refreshObjectTree() void ClientProxy::refreshObjectTree()
@@ -173,134 +180,6 @@ void ClientProxy::onCurrentObjectsChanged(const QList<int> &debugIds)
} }
} }
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) {
m_client = new QDeclarativeEngineDebug(m_conn, this);
m_designClient = new QmlJSDesignDebugClient(m_conn, this);
emit connected(m_client);
connect(m_designClient, SIGNAL(currentObjectsChanged(QList<int>)),
SLOT(onCurrentObjectsChanged(QList<int>)));
connect(m_designClient, SIGNAL(colorPickerActivated()),
SIGNAL(colorPickerActivated()));
connect(m_designClient, SIGNAL(zoomToolActivated()),
SIGNAL(zoomToolActivated()));
connect(m_designClient, SIGNAL(selectToolActivated()),
SIGNAL(selectToolActivated()));
connect(m_designClient, SIGNAL(selectMarqueeToolActivated()),
SIGNAL(selectMarqueeToolActivated()));
connect(m_designClient, SIGNAL(animationSpeedChanged(qreal)),
SIGNAL(animationSpeedChanged(qreal)));
connect(m_designClient, SIGNAL(designModeBehaviorChanged(bool)),
SIGNAL(designModeBehaviorChanged(bool)));
connect(m_designClient, SIGNAL(reloaded()), this,
SIGNAL(serverReloaded()));
connect(m_designClient, SIGNAL(selectedColorChanged(QColor)),
SIGNAL(selectedColorChanged(QColor)));
connect(m_designClient, SIGNAL(contextPathUpdated(QStringList)),
SIGNAL(contextPathUpdated(QStringList)));
connect(m_designClient, SIGNAL(treeRefreshRequested()),
SLOT(refreshObjectTree()));
}
createDebuggerClient();
reloadEngines();
break;
}
case QAbstractSocket::ClosingState:
emit connectionStatusMessage(tr("[Inspector] closing..."));
break;
case QAbstractSocket::BoundState:
case QAbstractSocket::ListeningState:
break;
}
}
void ClientProxy::createDebuggerClient()
{
DebuggerClient *debuggerClient = new DebuggerClient(m_conn);
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
const QList<Debugger::DebuggerRunControlFactory *> factories =
pm->getObjects<Debugger::DebuggerRunControlFactory>();
ProjectExplorer::RunControl *runControl = 0;
Debugger::DebuggerStartParameters sp;
sp.startMode = Debugger::StartExternal;
sp.executable = "qmlviewer"; //FIXME
runControl = factories.first()->create(sp);
Debugger::DebuggerRunControl* debuggerRunControl =
qobject_cast<Debugger::DebuggerRunControl *>(runControl);
QTC_ASSERT(debuggerRunControl, return);
Debugger::Internal::QmlEngine *engine =
qobject_cast<Debugger::Internal::QmlEngine *>(debuggerRunControl->engine());
QTC_ASSERT(engine, return);
engine->Debugger::Internal::DebuggerEngine::startDebugger(debuggerRunControl);
connect(engine, SIGNAL(sendMessage(QByteArray)),
debuggerClient, SLOT(slotSendMessage(QByteArray)));
connect(debuggerClient, SIGNAL(messageWasReceived(QByteArray)),
engine, SLOT(messageReceived(QByteArray)));
connect(m_conn, SIGNAL(disconnected()),
engine, SLOT(disconnected()));
//engine->startSuccessful(); // FIXME: AAA: port to new debugger states
}
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::setSelectedItemsByObjectId(const QList<QDeclarativeDebugObjectReference> &objectRefs) void ClientProxy::setSelectedItemsByObjectId(const QList<QDeclarativeDebugObjectReference> &objectRefs)
{ {
if (isConnected() && m_designClient) if (isConnected() && m_designClient)
@@ -317,7 +196,6 @@ QDeclarativeDebugObjectReference QmlJSInspector::Internal::ClientProxy::rootObje
return m_rootObject; return m_rootObject;
} }
QDeclarativeDebugObjectReference ClientProxy::objectReferenceForId(int debugId, QDeclarativeDebugObjectReference ClientProxy::objectReferenceForId(int debugId,
const QDeclarativeDebugObjectReference &objectRef) const const QDeclarativeDebugObjectReference &objectRef) const
{ {
@@ -527,7 +405,7 @@ void ClientProxy::setContextPathIndex(int contextIndex)
bool ClientProxy::isDesignClientConnected() const bool ClientProxy::isDesignClientConnected() const
{ {
return (m_designClient && m_conn->isConnected()); return (m_designClient && m_adapter->isConnected());
} }
void ClientProxy::reloadEngines() void ClientProxy::reloadEngines()
@@ -560,3 +438,13 @@ void ClientProxy::updateEngineList()
emit enginesChanged(); emit enginesChanged();
} }
Debugger::Internal::QmlAdapter *ClientProxy::qmlAdapter() const
{
return m_adapter;
}
bool ClientProxy::isConnected() const
{
return m_adapter->isConnected();
}

View File

@@ -35,6 +35,12 @@
QT_FORWARD_DECLARE_CLASS(QUrl) QT_FORWARD_DECLARE_CLASS(QUrl)
namespace Debugger {
namespace Internal {
class QmlAdapter;
}
}
namespace QmlJSInspector { namespace QmlJSInspector {
namespace Internal { namespace Internal {
@@ -46,7 +52,7 @@ class ClientProxy : public QObject
Q_OBJECT Q_OBJECT
public: public:
static ClientProxy *instance(); explicit ClientProxy(Debugger::Internal::QmlAdapter *adapter, QObject *parent = 0);
bool setBindingForObject(int objectDebugId, bool setBindingForObject(int objectDebugId,
const QString &propertyName, const QString &propertyName,
@@ -63,15 +69,13 @@ public:
QDeclarativeDebugObjectReference rootObjectReference() const; QDeclarativeDebugObjectReference rootObjectReference() const;
bool isConnected() const; bool isConnected() const;
bool isUnconnected() const;
void setSelectedItemsByObjectId(const QList<QDeclarativeDebugObjectReference> &objectRefs); void setSelectedItemsByObjectId(const QList<QDeclarativeDebugObjectReference> &objectRefs);
bool connectToViewer(const QString &host, quint16 port);
void disconnectFromViewer();
QList<QDeclarativeDebugEngineReference> engines() const; QList<QDeclarativeDebugEngineReference> engines() const;
Debugger::Internal::QmlAdapter *qmlAdapter() const;
signals: signals:
void objectTreeUpdated(const QDeclarativeDebugObjectReference &rootObject); void objectTreeUpdated(const QDeclarativeDebugObjectReference &rootObject);
void connectionStatusMessage(const QString &text); void connectionStatusMessage(const QString &text);
@@ -81,7 +85,7 @@ signals:
void selectedItemsChanged(const QList<QDeclarativeDebugObjectReference> &selectedItems); void selectedItemsChanged(const QList<QDeclarativeDebugObjectReference> &selectedItems);
void connected(QDeclarativeEngineDebug *client); void connected();
void aboutToDisconnect(); void aboutToDisconnect();
void disconnected(); void disconnected();
@@ -112,9 +116,10 @@ public slots:
void setContextPathIndex(int contextIndex); void setContextPathIndex(int contextIndex);
private slots: private slots:
void disconnectFromServer();
void connectToServer();
void contextChanged(); void contextChanged();
void connectionStateChanged();
void connectionError();
void onCurrentObjectsChanged(const QList<int> &debugIds); void onCurrentObjectsChanged(const QList<int> &debugIds);
void updateEngineList(); void updateEngineList();
@@ -123,17 +128,14 @@ private slots:
private: private:
bool isDesignClientConnected() const; bool isDesignClientConnected() const;
void reloadEngines(); void reloadEngines();
void createDebuggerClient();
QList<QDeclarativeDebugObjectReference> objectReferences(const QUrl &url, const QDeclarativeDebugObjectReference &objectRef) const; QList<QDeclarativeDebugObjectReference> objectReferences(const QUrl &url, const QDeclarativeDebugObjectReference &objectRef) const;
QDeclarativeDebugObjectReference objectReferenceForId(int debugId, const QDeclarativeDebugObjectReference &ref) const; QDeclarativeDebugObjectReference objectReferenceForId(int debugId, const QDeclarativeDebugObjectReference &ref) const;
private: private:
explicit ClientProxy(QObject *parent = 0);
Q_DISABLE_COPY(ClientProxy); Q_DISABLE_COPY(ClientProxy);
static ClientProxy *m_instance; Debugger::Internal::QmlAdapter *m_adapter;
QDeclarativeDebugConnection *m_conn;
QDeclarativeEngineDebug *m_client; QDeclarativeEngineDebug *m_client;
QmlJSDesignDebugClient *m_designClient; QmlJSDesignDebugClient *m_designClient;
@@ -143,8 +145,6 @@ private:
QDeclarativeDebugObjectReference m_rootObject; QDeclarativeDebugObjectReference m_rootObject;
QList<QDeclarativeDebugEngineReference> m_engines; QList<QDeclarativeDebugEngineReference> m_engines;
friend class QmlJSInspector::Internal::InspectorPlugin;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -28,8 +28,8 @@
**************************************************************************/ **************************************************************************/
#include "qmljsinspectorconstants.h" #include "qmljsinspectorconstants.h"
#include "qmljsinspector.h" #include "qmljsinspector.h"
#include "qmlinspectortoolbar.h"
#include "qmljsclientproxy.h" #include "qmljsclientproxy.h"
#include "qmljsinspectorcontext.h"
#include "qmljslivetextpreview.h" #include "qmljslivetextpreview.h"
#include "qmljsprivateapi.h" #include "qmljsprivateapi.h"
#include "qmljscontextcrumblepath.h" #include "qmljscontextcrumblepath.h"
@@ -113,58 +113,98 @@ enum {
ConnectionAttemptSimultaneousInterval = 500 ConnectionAttemptSimultaneousInterval = 500
}; };
Inspector *Inspector::m_instance = 0; InspectorUi *InspectorUi::m_instance = 0;
Inspector::Inspector(QObject *parent) QmlJS::ModelManagerInterface *modelManager()
: QObject(parent), {
m_connectionTimer(new QTimer(this)), return ExtensionSystem::PluginManager::instance()->getObject<QmlJS::ModelManagerInterface>();
m_connectionAttempts(0), }
m_listeningToEditorManager(false),
m_settings(new InspectorSettings(this)), InspectorUi::InspectorUi(QObject *parent)
m_debugProject(0) : QObject(parent)
, m_listeningToEditorManager(false)
, m_settings(new InspectorSettings(this))
, m_clientProxy(0)
, m_debugProject(0)
{ {
m_clientProxy = ClientProxy::instance();
m_instance = this; m_instance = this;
//#warning set up the context widget m_toolbar = new QmlInspectorToolbar(this);
QWidget *contextWidget = 0;
m_context = new InspectorContext(contextWidget);
connect(m_clientProxy, SIGNAL(selectedItemsChanged(QList<QDeclarativeDebugObjectReference>)),
SLOT(setSelectedItemsByObjectReference(QList<QDeclarativeDebugObjectReference>)));
connect(m_clientProxy, SIGNAL(connectionStatusMessage(QString)), SIGNAL(statusMessage(QString)));
connect(m_clientProxy, SIGNAL(connected(QDeclarativeEngineDebug*)), SLOT(connected(QDeclarativeEngineDebug*)));
connect(m_clientProxy, SIGNAL(disconnected()), SLOT(disconnected()));
connect(m_clientProxy, SIGNAL(enginesChanged()), SLOT(updateEngineList()));
connect(m_clientProxy, SIGNAL(serverReloaded()), this, SLOT(serverReloaded()));
connect(m_connectionTimer, SIGNAL(timeout()), SLOT(pollInspector()));
} }
InspectorUi::~InspectorUi()
Inspector::~Inspector()
{ {
} }
void Inspector::saveSettings() const void InspectorUi::setupUi()
{
setupDockWidgets();
m_toolbar->createActions(Core::Context(Constants::C_INSPECTOR));
restoreSettings();
}
void InspectorUi::saveSettings() const
{ {
m_settings->saveSettings(Core::ICore::instance()->settings()); m_settings->saveSettings(Core::ICore::instance()->settings());
} }
void Inspector::restoreSettings() void InspectorUi::restoreSettings()
{ {
m_settings->restoreSettings(Core::ICore::instance()->settings()); m_settings->restoreSettings(Core::ICore::instance()->settings());
} }
void Inspector::disconnected() void InspectorUi::connected(ClientProxy *clientProxy)
{ {
m_debugProject = 0; m_clientProxy = clientProxy;
connect(m_clientProxy, SIGNAL(selectedItemsChanged(QList<QDeclarativeDebugObjectReference>)),
SLOT(setSelectedItemsByObjectReference(QList<QDeclarativeDebugObjectReference>)));
connect(m_clientProxy, SIGNAL(enginesChanged()), SLOT(updateEngineList()));
connect(m_clientProxy, SIGNAL(serverReloaded()), this, SLOT(serverReloaded()));
connect(m_clientProxy, SIGNAL(contextPathUpdated(QStringList)),
m_crumblePath, SLOT(updateContextPath(QStringList)));
m_debugProject = ProjectExplorer::ProjectExplorerPlugin::instance()->startupProject();
connect(m_debugProject, SIGNAL(destroyed()), SLOT(currentDebugProjectRemoved()));
setupToolbar(true);
resetViews(); resetViews();
applyChangesToQmlObserverHelper(false);
initializeDocuments();
QHashIterator<QString, QmlJSLiveTextPreview *> iter(m_textPreviews);
while(iter.hasNext()) {
iter.next();
iter.value()->setClientProxy(m_clientProxy);
}
} }
void Inspector::updateEngineList() void InspectorUi::disconnected()
{
disconnect(m_clientProxy, SIGNAL(selectedItemsChanged(QList<QDeclarativeDebugObjectReference>)),
this, SLOT(setSelectedItemsByObjectReference(QList<QDeclarativeDebugObjectReference>)));
disconnect(m_clientProxy, SIGNAL(enginesChanged()), this, SLOT(updateEngineList()));
disconnect(m_clientProxy, SIGNAL(serverReloaded()), this, SLOT(serverReloaded()));
disconnect(m_clientProxy, SIGNAL(contextPathUpdated(QStringList)),
m_crumblePath, SLOT(updateContextPath(QStringList)));
m_debugProject = 0;
resetViews();
setupToolbar(false);
applyChangesToQmlObserverHelper(false);
QHashIterator<QString, QmlJSLiveTextPreview *> iter(m_textPreviews);
while(iter.hasNext()) {
iter.next();
iter.value()->setClientProxy(0);
}
m_clientProxy = 0;
}
void InspectorUi::updateEngineList()
{ {
const QList<QDeclarativeDebugEngineReference> engines = m_clientProxy->engines(); const QList<QDeclarativeDebugEngineReference> engines = m_clientProxy->engines();
@@ -178,40 +218,14 @@ void Inspector::updateEngineList()
} }
} }
void Inspector::changeSelectedItems(const QList<QDeclarativeDebugObjectReference> &objects) void InspectorUi::changeSelectedItems(const QList<QDeclarativeDebugObjectReference> &objects)
{ {
m_clientProxy->setSelectedItemsByObjectId(objects); m_clientProxy->setSelectedItemsByObjectId(objects);
} }
void Inspector::pollInspector() void InspectorUi::initializeDocuments()
{ {
++m_connectionAttempts; if (!modelManager() || !m_clientProxy)
const QString host = m_runConfigurationDebugData.serverAddress;
const quint16 port = quint16(m_runConfigurationDebugData.serverPort);
if (m_clientProxy->connectToViewer(host, port)) {
initializeDocuments();
m_connectionTimer->stop();
m_connectionAttempts = 0;
} else if (m_connectionAttempts == MaxConnectionAttempts) {
m_connectionTimer->stop();
m_connectionAttempts = 0;
QMessageBox::critical(0,
tr("Failed to connect to debugger"),
tr("Could not connect to debugger server.") );
}
}
QmlJS::ModelManagerInterface *Inspector::modelManager()
{
return ExtensionSystem::PluginManager::instance()->getObject<QmlJS::ModelManagerInterface>();
}
void Inspector::initializeDocuments()
{
if (!modelManager())
return; return;
Core::EditorManager *em = Core::EditorManager::instance(); Core::EditorManager *em = Core::EditorManager::instance();
@@ -231,7 +245,7 @@ void Inspector::initializeDocuments()
applyChangesToQmlObserverHelper(true); applyChangesToQmlObserverHelper(true);
} }
void Inspector::serverReloaded() void InspectorUi::serverReloaded()
{ {
QmlJS::Snapshot snapshot = modelManager()->snapshot(); QmlJS::Snapshot snapshot = modelManager()->snapshot();
m_loadedSnapshot = snapshot; m_loadedSnapshot = snapshot;
@@ -240,22 +254,24 @@ void Inspector::serverReloaded()
Document::Ptr doc = snapshot.document(it.key()); Document::Ptr doc = snapshot.document(it.key());
it.value()->resetInitialDoc(doc); it.value()->resetInitialDoc(doc);
} }
ClientProxy::instance()->queryEngineContext(0); m_clientProxy->queryEngineContext(0);
//ClientProxy::instance()->refreshObjectTree();
} }
void Inspector::removePreviewForEditor(Core::IEditor *oldEditor) void InspectorUi::removePreviewForEditor(Core::IEditor *oldEditor)
{ {
if (QmlJSLiveTextPreview *preview = m_textPreviews.value(oldEditor->file()->fileName())) { if (QmlJSLiveTextPreview *preview = m_textPreviews.value(oldEditor->file()->fileName())) {
preview->unassociateEditor(oldEditor); preview->unassociateEditor(oldEditor);
} }
} }
void Inspector::createPreviewForEditor(Core::IEditor *newEditor) void InspectorUi::createPreviewForEditor(Core::IEditor *newEditor)
{ {
if (newEditor && newEditor->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID if (m_clientProxy
&& m_clientProxy->isConnected()) && m_clientProxy->isConnected()
&& newEditor
&& newEditor->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID
)
{ {
QString filename = newEditor->file()->fileName(); QString filename = newEditor->file()->fileName();
QmlJS::Document::Ptr doc = modelManager()->snapshot().document(filename); QmlJS::Document::Ptr doc = modelManager()->snapshot().document(filename);
@@ -268,7 +284,7 @@ void Inspector::createPreviewForEditor(Core::IEditor *newEditor)
if (m_textPreviews.contains(filename)) { if (m_textPreviews.contains(filename)) {
m_textPreviews.value(filename)->associateEditor(newEditor); m_textPreviews.value(filename)->associateEditor(newEditor);
} else { } else {
QmlJSLiveTextPreview *preview = new QmlJSLiveTextPreview(doc, initdoc, this); QmlJSLiveTextPreview *preview = new QmlJSLiveTextPreview(doc, initdoc, m_clientProxy, this);
connect(preview, connect(preview,
SIGNAL(selectedItemsChanged(QList<QDeclarativeDebugObjectReference>)), SIGNAL(selectedItemsChanged(QList<QDeclarativeDebugObjectReference>)),
SLOT(changeSelectedItems(QList<QDeclarativeDebugObjectReference>))); SLOT(changeSelectedItems(QList<QDeclarativeDebugObjectReference>)));
@@ -282,55 +298,23 @@ void Inspector::createPreviewForEditor(Core::IEditor *newEditor)
} }
} }
bool Inspector::setDebugConfigurationDataFromProject(ProjectExplorer::Project *projectToDebug) void InspectorUi::currentDebugProjectRemoved()
{
if (!projectToDebug) {
emit statusMessage(tr("Invalid project, debugging canceled."));
return false;
}
QmlProjectManager::QmlProjectRunConfiguration* config =
qobject_cast<QmlProjectManager::QmlProjectRunConfiguration*>(projectToDebug->activeTarget()->activeRunConfiguration());
if (!config) {
emit statusMessage(tr("Cannot find project run configuration, debugging canceled."));
return false;
}
m_runConfigurationDebugData.serverAddress = config->debugServerAddress();
m_runConfigurationDebugData.serverPort = config->debugServerPort();
m_connectionTimer->setInterval(ConnectionAttemptDefaultInterval);
return true;
}
void Inspector::startQmlProjectDebugger()
{
m_connectionTimer->start();
}
void Inspector::currentDebugProjectRemoved()
{ {
m_debugProject = 0; m_debugProject = 0;
} }
void Inspector::resetViews() void InspectorUi::resetViews()
{ {
m_crumblePath->updateContextPath(QStringList()); m_crumblePath->updateContextPath(QStringList());
} }
void Inspector::connected(QDeclarativeEngineDebug *client) void InspectorUi::reloadQmlViewer()
{
m_debugProject = ProjectExplorer::ProjectExplorerPlugin::instance()->startupProject();
connect(m_debugProject, SIGNAL(destroyed()), SLOT(currentDebugProjectRemoved()));
m_client = client;
resetViews();
}
void Inspector::reloadQmlViewer()
{ {
if (m_clientProxy)
m_clientProxy->reloadQmlViewer(); m_clientProxy->reloadQmlViewer();
} }
void Inspector::setSimpleDockWidgetArrangement() void InspectorUi::setSimpleDockWidgetArrangement()
{ {
Utils::FancyMainWindow *mainWindow = Debugger::DebuggerUISwitcher::instance()->mainWindow(); Utils::FancyMainWindow *mainWindow = Debugger::DebuggerUISwitcher::instance()->mainWindow();
@@ -342,13 +326,13 @@ void Inspector::setSimpleDockWidgetArrangement()
mainWindow->setTrackingEnabled(true); mainWindow->setTrackingEnabled(true);
} }
void Inspector::setSelectedItemsByObjectReference(QList<QDeclarativeDebugObjectReference> objectReferences) void InspectorUi::setSelectedItemsByObjectReference(QList<QDeclarativeDebugObjectReference> objectReferences)
{ {
if (objectReferences.length()) if (objectReferences.length())
gotoObjectReferenceDefinition(objectReferences.first()); gotoObjectReferenceDefinition(objectReferences.first());
} }
void Inspector::gotoObjectReferenceDefinition(const QDeclarativeDebugObjectReference &obj) void InspectorUi::gotoObjectReferenceDefinition(const QDeclarativeDebugObjectReference &obj)
{ {
Q_UNUSED(obj); Q_UNUSED(obj);
@@ -369,22 +353,7 @@ void Inspector::gotoObjectReferenceDefinition(const QDeclarativeDebugObjectRefer
} }
} }
QDeclarativeDebugExpressionQuery *Inspector::executeExpression(int objectDebugId, const QString &objectId, bool InspectorUi::addQuotesForData(const QVariant &value) const
const QString &propertyName, const QVariant &value)
{
if (objectId.length()) {
QString quoteWrappedValue = value.toString();
if (addQuotesForData(value))
quoteWrappedValue = QString("'%1'").arg(quoteWrappedValue); // ### FIXME this code is wrong!
QString constructedExpression = objectId + "." + propertyName + "=" + quoteWrappedValue;
return m_client.data()->queryExpressionResult(objectDebugId, constructedExpression, this);
}
return 0;
}
bool Inspector::addQuotesForData(const QVariant &value) const
{ {
switch (value.type()) { switch (value.type()) {
case QVariant::String: case QVariant::String:
@@ -398,7 +367,7 @@ bool Inspector::addQuotesForData(const QVariant &value) const
return false; return false;
} }
void Inspector::createDockWidgets() void InspectorUi::setupDockWidgets()
{ {
m_crumblePath = new ContextCrumblePath; m_crumblePath = new ContextCrumblePath;
m_crumblePath->setObjectName("QmlContextPath"); m_crumblePath->setObjectName("QmlContextPath");
@@ -409,43 +378,42 @@ void Inspector::createDockWidgets()
m_crumblePath, Qt::BottomDockWidgetArea); m_crumblePath, Qt::BottomDockWidgetArea);
m_crumblePathDock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea); m_crumblePathDock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
m_crumblePathDock->setTitleBarWidget(new QWidget(m_crumblePathDock)); m_crumblePathDock->setTitleBarWidget(new QWidget(m_crumblePathDock));
connect(m_clientProxy, SIGNAL(contextPathUpdated(QStringList)), m_crumblePath, SLOT(updateContextPath(QStringList)));
} }
void Inspector::crumblePathElementClicked(int pathIndex) void InspectorUi::crumblePathElementClicked(int pathIndex)
{ {
if (m_clientProxy->isConnected() && !m_crumblePath->isEmpty()) { if (m_clientProxy && m_clientProxy->isConnected() && !m_crumblePath->isEmpty()) {
m_clientProxy->setContextPathIndex(pathIndex); m_clientProxy->setContextPathIndex(pathIndex);
} }
} }
bool Inspector::showExperimentalWarning() bool InspectorUi::showExperimentalWarning()
{ {
return m_settings->showLivePreviewWarning(); return m_settings->showLivePreviewWarning();
} }
void Inspector::setShowExperimentalWarning(bool value) void InspectorUi::setShowExperimentalWarning(bool value)
{ {
m_settings->setShowLivePreviewWarning(value); m_settings->setShowLivePreviewWarning(value);
} }
Inspector *Inspector::instance() InspectorUi *InspectorUi::instance()
{ {
return m_instance; return m_instance;
} }
ProjectExplorer::Project *Inspector::debugProject() const ProjectExplorer::Project *InspectorUi::debugProject() const
{ {
return m_debugProject; return m_debugProject;
} }
void Inspector::setApplyChangesToQmlObserver(bool applyChanges) void InspectorUi::setApplyChangesToQmlObserver(bool applyChanges)
{ {
emit livePreviewActivated(applyChanges); emit livePreviewActivated(applyChanges);
applyChangesToQmlObserverHelper(applyChanges); applyChangesToQmlObserverHelper(applyChanges);
} }
void Inspector::applyChangesToQmlObserverHelper(bool applyChanges) void InspectorUi::applyChangesToQmlObserverHelper(bool applyChanges)
{ {
QHashIterator<QString, QmlJSLiveTextPreview *> iter(m_textPreviews); QHashIterator<QString, QmlJSLiveTextPreview *> iter(m_textPreviews);
while(iter.hasNext()) { while(iter.hasNext()) {
@@ -454,7 +422,58 @@ void Inspector::applyChangesToQmlObserverHelper(bool applyChanges)
} }
} }
void Inspector::disableLivePreview() void InspectorUi::disableLivePreview()
{ {
setApplyChangesToQmlObserver(false); setApplyChangesToQmlObserver(false);
} }
void InspectorUi::setupToolbar(bool doConnect)
{
if (doConnect) {
connect(m_clientProxy, SIGNAL(connected()), m_toolbar, SLOT(enable()));
connect(m_clientProxy, SIGNAL(disconnected()), m_toolbar, SLOT(disable()));
connect(m_toolbar, SIGNAL(designModeSelected(bool)), m_clientProxy, SLOT(setDesignModeBehavior(bool)));
connect(m_toolbar, SIGNAL(reloadSelected()), m_clientProxy, SLOT(reloadQmlViewer()));
connect(m_toolbar, SIGNAL(animationSpeedChanged(qreal)), m_clientProxy, SLOT(setAnimationSpeed(qreal)));
connect(m_toolbar, SIGNAL(colorPickerSelected()), m_clientProxy, SLOT(changeToColorPickerTool()));
connect(m_toolbar, SIGNAL(zoomToolSelected()), m_clientProxy, SLOT(changeToZoomTool()));
connect(m_toolbar, SIGNAL(selectToolSelected()), m_clientProxy, SLOT(changeToSelectTool()));
connect(m_toolbar, SIGNAL(marqueeSelectToolSelected()), m_clientProxy, SLOT(changeToSelectMarqueeTool()));
connect(m_toolbar, SIGNAL(applyChangesFromQmlFileTriggered(bool)), this, SLOT(setApplyChangesToQmlObserver(bool)));
connect(this, SIGNAL(livePreviewActivated(bool)), m_toolbar, SLOT(setLivePreviewChecked(bool)));
connect(m_clientProxy, SIGNAL(colorPickerActivated()), m_toolbar, SLOT(activateColorPicker()));
connect(m_clientProxy, SIGNAL(selectToolActivated()), m_toolbar, SLOT(activateSelectTool()));
connect(m_clientProxy, SIGNAL(selectMarqueeToolActivated()), m_toolbar, SLOT(activateMarqueeSelectTool()));
connect(m_clientProxy, SIGNAL(zoomToolActivated()), m_toolbar, SLOT(activateZoomTool()));
connect(m_clientProxy, SIGNAL(designModeBehaviorChanged(bool)), m_toolbar, SLOT(setDesignModeBehavior(bool)));
connect(m_clientProxy, SIGNAL(selectedColorChanged(QColor)), m_toolbar, SLOT(setSelectedColor(QColor)));
connect(m_clientProxy, SIGNAL(animationSpeedChanged(qreal)), m_toolbar, SLOT(changeAnimationSpeed(qreal)));
m_toolbar->enable();
} else {
disconnect(m_clientProxy, SIGNAL(connected()), m_toolbar, SLOT(enable()));
disconnect(m_clientProxy, SIGNAL(disconnected()), m_toolbar, SLOT(disable()));
disconnect(m_toolbar, SIGNAL(designModeSelected(bool)), m_clientProxy, SLOT(setDesignModeBehavior(bool)));
disconnect(m_toolbar, SIGNAL(reloadSelected()), m_clientProxy, SLOT(reloadQmlViewer()));
disconnect(m_toolbar, SIGNAL(animationSpeedChanged(qreal)), m_clientProxy, SLOT(setAnimationSpeed(qreal)));
disconnect(m_toolbar, SIGNAL(colorPickerSelected()), m_clientProxy, SLOT(changeToColorPickerTool()));
disconnect(m_toolbar, SIGNAL(zoomToolSelected()), m_clientProxy, SLOT(changeToZoomTool()));
disconnect(m_toolbar, SIGNAL(selectToolSelected()), m_clientProxy, SLOT(changeToSelectTool()));
disconnect(m_toolbar, SIGNAL(marqueeSelectToolSelected()), m_clientProxy, SLOT(changeToSelectMarqueeTool()));
disconnect(m_toolbar, SIGNAL(applyChangesFromQmlFileTriggered(bool)), this, SLOT(setApplyChangesToQmlObserver(bool)));
disconnect(this, SIGNAL(livePreviewActivated(bool)), m_toolbar, SLOT(setLivePreviewChecked(bool)));
disconnect(m_clientProxy, SIGNAL(colorPickerActivated()), m_toolbar, SLOT(activateColorPicker()));
disconnect(m_clientProxy, SIGNAL(selectToolActivated()), m_toolbar, SLOT(activateSelectTool()));
disconnect(m_clientProxy, SIGNAL(selectMarqueeToolActivated()), m_toolbar, SLOT(activateMarqueeSelectTool()));
disconnect(m_clientProxy, SIGNAL(zoomToolActivated()), m_toolbar, SLOT(activateZoomTool()));
disconnect(m_clientProxy, SIGNAL(designModeBehaviorChanged(bool)), m_toolbar, SLOT(setDesignModeBehavior(bool)));
disconnect(m_clientProxy, SIGNAL(selectedColorChanged(QColor)), m_toolbar, SLOT(setSelectedColor(QColor)));
disconnect(m_clientProxy, SIGNAL(animationSpeedChanged(qreal)), m_toolbar, SLOT(changeAnimationSpeed(qreal)));
m_toolbar->disable();
}
}

View File

@@ -59,13 +59,13 @@ QT_FORWARD_DECLARE_CLASS(QDockWidget)
namespace QmlJSInspector { namespace QmlJSInspector {
namespace Internal { namespace Internal {
class QmlInspectorToolbar;
class ClientProxy; class ClientProxy;
class InspectorContext;
class InspectorSettings; class InspectorSettings;
class ContextCrumblePath; class ContextCrumblePath;
class QmlJSLiveTextPreview; class QmlJSLiveTextPreview;
class Inspector : public QObject class InspectorUi : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -76,33 +76,23 @@ public:
QmlProjectWithCppPlugins QmlProjectWithCppPlugins
}; };
public: public:
Inspector(QObject *parent = 0); InspectorUi(QObject *parent = 0);
virtual ~Inspector(); virtual ~InspectorUi();
bool connectToViewer(); // using host, port from widgets
// returns false if project is not debuggable.
bool setDebugConfigurationDataFromProject(ProjectExplorer::Project *projectToDebug);
void startQmlProjectDebugger();
QDeclarativeDebugExpressionQuery *executeExpression(int objectDebugId, const QString &objectId,
const QString &propertyName, const QVariant &value);
QDeclarativeDebugExpressionQuery *setBindingForObject(int objectDebugId, const QString &objectId,
const QString &propertyName, const QVariant &value,
bool isLiteralValue);
void saveSettings() const; void saveSettings() const;
void restoreSettings(); void restoreSettings();
bool showExperimentalWarning(); bool showExperimentalWarning();
void setShowExperimentalWarning(bool value); void setShowExperimentalWarning(bool value);
static Inspector *instance(); static InspectorUi *instance();
// returns the project being currently debugged, or 0 if not debugging anything // returns the project being currently debugged, or 0 if not debugging anything
ProjectExplorer::Project *debugProject() const; ProjectExplorer::Project *debugProject() const;
void createDockWidgets();
void setupUi();
void connected(ClientProxy *clientProxy);
void disconnected();
signals: signals:
void statusMessage(const QString &text); void statusMessage(const QString &text);
@@ -117,15 +107,11 @@ public slots:
private slots: private slots:
void gotoObjectReferenceDefinition(const QDeclarativeDebugObjectReference &obj); void gotoObjectReferenceDefinition(const QDeclarativeDebugObjectReference &obj);
void pollInspector();
void setSelectedItemsByObjectReference(QList<QDeclarativeDebugObjectReference> objectReferences); void setSelectedItemsByObjectReference(QList<QDeclarativeDebugObjectReference> objectReferences);
void changeSelectedItems(const QList<QDeclarativeDebugObjectReference> &objects); void changeSelectedItems(const QList<QDeclarativeDebugObjectReference> &objects);
void connected(QDeclarativeEngineDebug *client);
void updateEngineList(); void updateEngineList();
void disconnected();
void removePreviewForEditor(Core::IEditor *newEditor); void removePreviewForEditor(Core::IEditor *newEditor);
void createPreviewForEditor(Core::IEditor *newEditor); void createPreviewForEditor(Core::IEditor *newEditor);
@@ -139,32 +125,29 @@ private:
bool addQuotesForData(const QVariant &value) const; bool addQuotesForData(const QVariant &value) const;
void resetViews(); void resetViews();
QmlJS::ModelManagerInterface *modelManager();
void initializeDocuments(); void initializeDocuments();
void applyChangesToQmlObserverHelper(bool applyChanges); void applyChangesToQmlObserverHelper(bool applyChanges);
void setupToolbar(bool doConnect);
void setupDockWidgets();
private: private:
QWeakPointer<QDeclarativeEngineDebug> m_client; QWeakPointer<QDeclarativeEngineDebug> m_client;
QmlProjectManager::QmlProjectRunConfigurationDebugData m_runConfigurationDebugData;
InspectorContext *m_context;
QTimer *m_connectionTimer;
int m_connectionAttempts;
ClientProxy *m_clientProxy;
bool m_listeningToEditorManager; bool m_listeningToEditorManager;
QmlInspectorToolbar *m_toolbar;
ContextCrumblePath *m_crumblePath; ContextCrumblePath *m_crumblePath;
QDockWidget *m_crumblePathDock; QDockWidget *m_crumblePathDock;
InspectorSettings *m_settings; InspectorSettings *m_settings;
ClientProxy *m_clientProxy;
// Qml/JS integration // Qml/JS integration
QHash<QString, QmlJSLiveTextPreview *> m_textPreviews; QHash<QString, QmlJSLiveTextPreview *> m_textPreviews;
QmlJS::Snapshot m_loadedSnapshot; //the snapshot loaded by the viewer QmlJS::Snapshot m_loadedSnapshot; //the snapshot loaded by the viewer
ProjectExplorer::Project *m_debugProject; ProjectExplorer::Project *m_debugProject;
static Inspector *m_instance; static InspectorUi *m_instance;
}; };
} // Internal } // Internal

View File

@@ -8,10 +8,8 @@ DEFINES += QMLJSINSPECTOR_LIBRARY
HEADERS += \ HEADERS += \
qmljsprivateapi.h \ qmljsprivateapi.h \
qmljsdebuggerclient.h \
qmljsinspector_global.h \ qmljsinspector_global.h \
qmljsinspectorconstants.h \ qmljsinspectorconstants.h \
qmljsinspectorcontext.h \
qmljsinspectorplugin.h \ qmljsinspectorplugin.h \
qmljsclientproxy.h \ qmljsclientproxy.h \
qmljsinspector.h \ qmljsinspector.h \
@@ -23,8 +21,6 @@ qmljscontextcrumblepath.h \
qmljsinspectorsettings.h qmljsinspectorsettings.h
SOURCES += \ SOURCES += \
qmljsdebuggerclient.cpp \
qmljsinspectorcontext.cpp \
qmljsinspectorplugin.cpp \ qmljsinspectorplugin.cpp \
qmljsclientproxy.cpp \ qmljsclientproxy.cpp \
qmljsinspector.cpp \ qmljsinspector.cpp \

View File

@@ -1,82 +0,0 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "qmljsinspectorcontext.h"
#include "qmljsinspectorconstants.h"
#include <coreplugin/icore.h>
#include <QtGui/QWidget>
#include <QtCore/QDebug>
using namespace QmlJSInspector::Internal;
using namespace QmlJSInspector::Constants;
InspectorContext::InspectorContext(QWidget *widget)
: IContext(widget),
m_widget(widget),
m_context(C_INSPECTOR)
{
}
InspectorContext::~InspectorContext()
{
}
Core::Context InspectorContext::context() const
{
return m_context;
}
QWidget *InspectorContext::widget()
{
return m_widget;
}
void InspectorContext::setContextHelpId(const QString &helpId)
{
m_contextHelpId = helpId;
}
QString InspectorContext::contextHelpId() const
{
return m_contextHelpId;
}
QString InspectorContext::contextHelpIdForProperty(const QString &itemName, const QString &propName)
{
// TODO this functionality is not supported yet as we don't have help id's for
// properties.
return QString("QML.").append(itemName).append(".").append(propName);
}
QString InspectorContext::contextHelpIdForItem(const QString &itemName)
{
return QString("QML.").append(itemName);
}

View File

@@ -35,25 +35,16 @@
#include <debugger/debuggeruiswitcher.h> #include <debugger/debuggeruiswitcher.h>
#include <debugger/debuggerconstants.h> #include <debugger/debuggerconstants.h>
#include <debugger/qml/qmladapter.h>
#include <qmlprojectmanager/qmlproject.h> #include <qmlprojectmanager/qmlproject.h>
#include <qmljseditor/qmljseditorconstants.h> #include <qmljseditor/qmljseditorconstants.h>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/runconfiguration.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/project.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/imode.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/icontext.h> #include <coreplugin/icontext.h>
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <QtCore/QStringList> #include <QtCore/QStringList>
#include <QtCore/QtPlugin> #include <QtCore/QtPlugin>
@@ -71,23 +62,16 @@ namespace {
InspectorPlugin *g_instance = 0; // the global QML/JS inspector instance InspectorPlugin *g_instance = 0; // the global QML/JS inspector instance
QToolButton *createToolButton(QAction *action)
{
QToolButton *button = new QToolButton;
button->setDefaultAction(action);
return button;
}
} // end of anonymous namespace } // end of anonymous namespace
InspectorPlugin::InspectorPlugin() InspectorPlugin::InspectorPlugin()
: IPlugin()
, m_clientProxy(0)
{ {
Q_ASSERT(! g_instance); Q_ASSERT(! g_instance);
g_instance = this; g_instance = this;
m_clientProxy = new ClientProxy(this); m_inspectorUi = new InspectorUi(this);
m_inspector = new Inspector(this);
m_toolbar = new QmlInspectorToolbar(this);
} }
InspectorPlugin::~InspectorPlugin() InspectorPlugin::~InspectorPlugin()
@@ -99,24 +83,19 @@ QmlJS::ModelManagerInterface *InspectorPlugin::modelManager() const
return ExtensionSystem::PluginManager::instance()->getObject<QmlJS::ModelManagerInterface>(); return ExtensionSystem::PluginManager::instance()->getObject<QmlJS::ModelManagerInterface>();
} }
ClientProxy *InspectorPlugin::clientProxy() const
{
return m_clientProxy;
}
InspectorPlugin *InspectorPlugin::instance() InspectorPlugin *InspectorPlugin::instance()
{ {
return g_instance; return g_instance;
} }
Inspector *InspectorPlugin::inspector() const InspectorUi *InspectorPlugin::inspector() const
{ {
return m_inspector; return m_inspectorUi;
} }
ExtensionSystem::IPlugin::ShutdownFlag InspectorPlugin::aboutToShutdown() ExtensionSystem::IPlugin::ShutdownFlag InspectorPlugin::aboutToShutdown()
{ {
m_inspector->saveSettings(); m_inspectorUi->saveSettings();
return SynchronousShutdown; return SynchronousShutdown;
} }
@@ -125,95 +104,51 @@ bool InspectorPlugin::initialize(const QStringList &arguments, QString *errorStr
Q_UNUSED(arguments); Q_UNUSED(arguments);
Q_UNUSED(errorString); Q_UNUSED(errorString);
connect(Core::ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)),
SLOT(prepareDebugger(Core::IMode*)));
ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance();
Debugger::DebuggerUISwitcher *uiSwitcher = pluginManager->getObject<Debugger::DebuggerUISwitcher>(); Debugger::DebuggerUISwitcher *uiSwitcher = pluginManager->getObject<Debugger::DebuggerUISwitcher>();
uiSwitcher->addLanguage(LANG_QML, Core::Context(C_INSPECTOR)); uiSwitcher->addLanguage(LANG_QML, Core::Context(C_INSPECTOR));
m_inspector->createDockWidgets();
return true; return true;
} }
void InspectorPlugin::extensionsInitialized() void InspectorPlugin::extensionsInitialized()
{ {
ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance();
Debugger::DebuggerUISwitcher *uiSwitcher = pluginManager->getObject<Debugger::DebuggerUISwitcher>();
Debugger::DebuggerUISwitcher *uiSwitcher = pluginManager->getObject<Debugger::DebuggerUISwitcher>();
connect(uiSwitcher, SIGNAL(dockArranged(QString)), SLOT(setDockWidgetArrangement(QString))); connect(uiSwitcher, SIGNAL(dockArranged(QString)), SLOT(setDockWidgetArrangement(QString)));
if (ProjectExplorer::ProjectExplorerPlugin *pex = ProjectExplorer::ProjectExplorerPlugin::instance()) { connect(pluginManager, SIGNAL(objectAdded(QObject*)), SLOT(objectAdded(QObject*)));
connect(pex, SIGNAL(aboutToExecuteProject(ProjectExplorer::Project*, QString)), connect(pluginManager, SIGNAL(aboutToRemoveObject(QObject*)), SLOT(aboutToRemoveObject(QObject*)));
SLOT(activateDebuggerForProject(ProjectExplorer::Project*, QString)));
}
m_toolbar->createActions(Core::Context(C_INSPECTOR));
connect(m_clientProxy, SIGNAL(connected(QDeclarativeEngineDebug*)), m_toolbar, SLOT(enable())); m_inspectorUi->setupUi();
connect(m_clientProxy, SIGNAL(disconnected()), m_toolbar, SLOT(disable()));
connect(m_toolbar, SIGNAL(designModeSelected(bool)), m_clientProxy, SLOT(setDesignModeBehavior(bool)));
connect(m_toolbar, SIGNAL(reloadSelected()), m_clientProxy, SLOT(reloadQmlViewer()));
connect(m_toolbar, SIGNAL(animationSpeedChanged(qreal)), m_clientProxy, SLOT(setAnimationSpeed(qreal)));
connect(m_toolbar, SIGNAL(colorPickerSelected()), m_clientProxy, SLOT(changeToColorPickerTool()));
connect(m_toolbar, SIGNAL(zoomToolSelected()), m_clientProxy, SLOT(changeToZoomTool()));
connect(m_toolbar, SIGNAL(selectToolSelected()), m_clientProxy, SLOT(changeToSelectTool()));
connect(m_toolbar, SIGNAL(marqueeSelectToolSelected()), m_clientProxy, SLOT(changeToSelectMarqueeTool()));
connect(m_toolbar, SIGNAL(applyChangesFromQmlFileTriggered(bool)), m_inspector, SLOT(setApplyChangesToQmlObserver(bool)));
connect(m_inspector, SIGNAL(livePreviewActivated(bool)), m_toolbar, SLOT(setLivePreviewChecked(bool)));
connect(m_clientProxy, SIGNAL(colorPickerActivated()), m_toolbar, SLOT(activateColorPicker()));
connect(m_clientProxy, SIGNAL(selectToolActivated()), m_toolbar, SLOT(activateSelectTool()));
connect(m_clientProxy, SIGNAL(selectMarqueeToolActivated()), m_toolbar, SLOT(activateMarqueeSelectTool()));
connect(m_clientProxy, SIGNAL(zoomToolActivated()), m_toolbar, SLOT(activateZoomTool()));
connect(m_clientProxy, SIGNAL(designModeBehaviorChanged(bool)), m_toolbar, SLOT(setDesignModeBehavior(bool)));
connect(m_clientProxy, SIGNAL(selectedColorChanged(QColor)), m_toolbar, SLOT(setSelectedColor(QColor)));
connect(m_clientProxy, SIGNAL(animationSpeedChanged(qreal)), m_toolbar, SLOT(changeAnimationSpeed(qreal)));
m_inspector->restoreSettings();
}
void InspectorPlugin::activateDebuggerForProject(ProjectExplorer::Project *project, const QString &runMode)
{
Q_UNUSED(project);
Q_UNUSED(runMode);
if (runMode == QLatin1String(ProjectExplorer::Constants::DEBUGMODE)) {
#ifdef __GNUC__
# warning start a QML/JS debugging session using the information stored in the current project
#endif
// FIXME we probably want to activate the debugger for other projects than QmlProjects,
// if they contain Qml files. Some kind of options should exist for this behavior.
if (QmlProjectManager::QmlProject *qmlproj = qobject_cast<QmlProjectManager::QmlProject*>(project)) {
if (m_inspector->setDebugConfigurationDataFromProject(qmlproj))
m_inspector->startQmlProjectDebugger();
}
}
}
void InspectorPlugin::prepareDebugger(Core::IMode *mode)
{
if (mode->id() != QLatin1String(Debugger::Constants::MODE_DEBUG))
return;
ProjectExplorer::ProjectExplorerPlugin *pex = ProjectExplorer::ProjectExplorerPlugin::instance();
if (pex->startupProject() && pex->startupProject()->id() == QLatin1String("QmlProjectManager.QmlProject")) {
ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance();
Debugger::DebuggerUISwitcher *uiSwitcher = pluginManager->getObject<Debugger::DebuggerUISwitcher>();
uiSwitcher->setActiveLanguage(LANG_QML);
}
} }
void InspectorPlugin::setDockWidgetArrangement(const QString &activeLanguage) void InspectorPlugin::setDockWidgetArrangement(const QString &activeLanguage)
{ {
if (activeLanguage == QmlJSInspector::Constants::LANG_QML || activeLanguage.isEmpty()) if (activeLanguage == QmlJSInspector::Constants::LANG_QML || activeLanguage.isEmpty())
m_inspector->setSimpleDockWidgetArrangement(); m_inspectorUi->setSimpleDockWidgetArrangement();
} }
// The adapter object is only added to the pool with a succesful connection,
// so we can immediately init our stuff.
void InspectorPlugin::objectAdded(QObject *object)
{
Debugger::Internal::QmlAdapter *adapter = qobject_cast<Debugger::Internal::QmlAdapter *>(object);
if (adapter) {
m_clientProxy = new ClientProxy(adapter);
m_inspectorUi->connected(m_clientProxy);
}
}
void InspectorPlugin::aboutToRemoveObject(QObject *obj)
{
if (m_clientProxy && m_clientProxy->qmlAdapter() == obj) {
m_inspectorUi->disconnected();
delete m_clientProxy;
m_clientProxy = 0;
}
}
Q_EXPORT_PLUGIN(InspectorPlugin) Q_EXPORT_PLUGIN(InspectorPlugin)

View File

@@ -49,9 +49,8 @@ namespace ProjectExplorer {
namespace QmlJSInspector { namespace QmlJSInspector {
namespace Internal { namespace Internal {
class QmlInspectorToolbar;
class ClientProxy; class ClientProxy;
class Inspector; class InspectorUi;
class InspectorPlugin : public ExtensionSystem::IPlugin class InspectorPlugin : public ExtensionSystem::IPlugin
{ {
@@ -64,8 +63,7 @@ public:
static InspectorPlugin *instance(); static InspectorPlugin *instance();
QmlJS::ModelManagerInterface *modelManager() const; QmlJS::ModelManagerInterface *modelManager() const;
ClientProxy *clientProxy() const; InspectorUi *inspector() const;
Inspector *inspector() const;
// ExtensionSystem::IPlugin interface // ExtensionSystem::IPlugin interface
virtual bool initialize(const QStringList &arguments, QString *errorString); virtual bool initialize(const QStringList &arguments, QString *errorString);
@@ -73,19 +71,19 @@ public:
virtual ExtensionSystem::IPlugin::ShutdownFlag aboutToShutdown(); virtual ExtensionSystem::IPlugin::ShutdownFlag aboutToShutdown();
public slots: public slots:
void activateDebuggerForProject(ProjectExplorer::Project *project, const QString &runMode);
void setDockWidgetArrangement(const QString &activeLanguage); void setDockWidgetArrangement(const QString &activeLanguage);
private slots: private slots:
void prepareDebugger(Core::IMode *mode); void prepareDebugger(Core::IMode *mode);
void objectAdded(QObject *object);
void aboutToRemoveObject(QObject *obj);
private: private:
void createActions(); void createActions();
private: private:
ClientProxy *m_clientProxy; ClientProxy *m_clientProxy;
Inspector *m_inspector; InspectorUi *m_inspectorUi;
QmlInspectorToolbar *m_toolbar;
}; };
} // end of namespace Internal } // end of namespace Internal

View File

@@ -167,20 +167,28 @@ void QmlJSLiveTextPreview::unassociateEditor(Core::IEditor *oldEditor)
} }
} }
QmlJSLiveTextPreview::QmlJSLiveTextPreview(const QmlJS::Document::Ptr &doc, const QmlJS::Document::Ptr &initDoc, QObject* parent) : QmlJSLiveTextPreview::QmlJSLiveTextPreview(const QmlJS::Document::Ptr &doc,
QObject(parent), m_previousDoc(doc), m_initialDoc(initDoc), m_applyChangesToQmlObserver(true) const QmlJS::Document::Ptr &initDoc,
ClientProxy *clientProxy,
QObject* parent)
: QObject(parent)
, m_previousDoc(doc)
, m_initialDoc(initDoc)
, m_applyChangesToQmlObserver(true)
, m_clientProxy(clientProxy)
{ {
Q_ASSERT(doc->fileName() == initDoc->fileName()); Q_ASSERT(doc->fileName() == initDoc->fileName());
ClientProxy *clientProxy = ClientProxy::instance();
m_filename = doc->fileName(); m_filename = doc->fileName();
connect(modelManager(), SIGNAL(documentChangedOnDisk(QmlJS::Document::Ptr)), connect(modelManager(), SIGNAL(documentChangedOnDisk(QmlJS::Document::Ptr)),
SLOT(documentChanged(QmlJS::Document::Ptr))); SLOT(documentChanged(QmlJS::Document::Ptr)));
connect(clientProxy, if (m_clientProxy.data()) {
connect(m_clientProxy.data(),
SIGNAL(objectTreeUpdated(QDeclarativeDebugObjectReference)), SIGNAL(objectTreeUpdated(QDeclarativeDebugObjectReference)),
SLOT(updateDebugIds(QDeclarativeDebugObjectReference))); SLOT(updateDebugIds(QDeclarativeDebugObjectReference)));
} }
}
void QmlJSLiveTextPreview::resetInitialDoc(const QmlJS::Document::Ptr &doc) void QmlJSLiveTextPreview::resetInitialDoc(const QmlJS::Document::Ptr &doc)
{ {
@@ -209,14 +217,12 @@ QList<int> QmlJSLiveTextPreview::objectReferencesForOffset(quint32 offset) const
void QmlJSLiveTextPreview::changeSelectedElements(QList<int> offsets, const QString &wordAtCursor) void QmlJSLiveTextPreview::changeSelectedElements(QList<int> offsets, const QString &wordAtCursor)
{ {
if (m_editors.isEmpty() || !m_previousDoc) if (m_editors.isEmpty() || !m_previousDoc || !m_clientProxy)
return; return;
ClientProxy *clientProxy = ClientProxy::instance();
QDeclarativeDebugObjectReference objectRefUnderCursor; QDeclarativeDebugObjectReference objectRefUnderCursor;
if (!wordAtCursor.isEmpty() && wordAtCursor[0].isUpper()) { if (!wordAtCursor.isEmpty() && wordAtCursor[0].isUpper()) {
QList<QDeclarativeDebugObjectReference> refs = clientProxy->objectReferences(); QList<QDeclarativeDebugObjectReference> refs = m_clientProxy.data()->objectReferences();
foreach (const QDeclarativeDebugObjectReference &ref, refs) { foreach (const QDeclarativeDebugObjectReference &ref, refs) {
if (ref.idString() == wordAtCursor) { if (ref.idString() == wordAtCursor) {
objectRefUnderCursor = ref; objectRefUnderCursor = ref;
@@ -431,7 +437,7 @@ protected:
Q_UNUSED(scriptBinding); Q_UNUSED(scriptBinding);
checkUnsyncronizableElementChanges(parentDefinition); checkUnsyncronizableElementChanges(parentDefinition);
appliedChangesToViewer = true; appliedChangesToViewer = true;
ClientProxy::instance()->setMethodBodyForObject(debugId, methodName, methodBody); m_clientProxy->setMethodBodyForObject(debugId, methodName, methodBody);
} }
virtual void updateScriptBinding(DebugId debugId, virtual void updateScriptBinding(DebugId debugId,
@@ -453,19 +459,19 @@ protected:
if (isLiteral) if (isLiteral)
expr = castToLiteral(scriptCode, scriptBinding); expr = castToLiteral(scriptCode, scriptBinding);
appliedChangesToViewer = true; appliedChangesToViewer = true;
ClientProxy::instance()->setBindingForObject(debugId, propertyName, expr, isLiteral); m_clientProxy->setBindingForObject(debugId, propertyName, expr, isLiteral);
} }
virtual void resetBindingForObject(int debugId, const QString &propertyName) virtual void resetBindingForObject(int debugId, const QString &propertyName)
{ {
appliedChangesToViewer = true; appliedChangesToViewer = true;
ClientProxy::instance()->resetBindingForObject(debugId, propertyName); m_clientProxy->resetBindingForObject(debugId, propertyName);
} }
virtual void removeObject(int debugId) virtual void removeObject(int debugId)
{ {
appliedChangesToViewer = true; appliedChangesToViewer = true;
ClientProxy::instance()->destroyQmlObject(debugId); m_clientProxy->destroyQmlObject(debugId);
} }
virtual void createObject(const QString& qmlText, DebugId ref, virtual void createObject(const QString& qmlText, DebugId ref,
@@ -473,7 +479,7 @@ protected:
{ {
appliedChangesToViewer = true; appliedChangesToViewer = true;
referenceRefreshRequired = true; referenceRefreshRequired = true;
ClientProxy::instance()->createQmlObject(qmlText, ref, importList, filename); m_clientProxy->createQmlObject(qmlText, ref, importList, filename);
} }
void checkUnsyncronizableElementChanges(UiObjectDefinition *parentDefinition) void checkUnsyncronizableElementChanges(UiObjectDefinition *parentDefinition)
@@ -513,19 +519,27 @@ protected:
} }
public: public:
UpdateObserver() : appliedChangesToViewer(false), referenceRefreshRequired(false), unsyncronizableChanges(QmlJSLiveTextPreview::NoUnsyncronizableChanges) {} UpdateObserver(ClientProxy *clientProxy)
: appliedChangesToViewer(false)
, referenceRefreshRequired(false)
, unsyncronizableChanges(QmlJSLiveTextPreview::NoUnsyncronizableChanges)
, m_clientProxy(clientProxy)
{
}
bool appliedChangesToViewer; bool appliedChangesToViewer;
bool referenceRefreshRequired; bool referenceRefreshRequired;
QString unsyncronizableElementName; QString unsyncronizableElementName;
QmlJSLiveTextPreview::UnsyncronizableChangeType unsyncronizableChanges; QmlJSLiveTextPreview::UnsyncronizableChangeType unsyncronizableChanges;
unsigned unsyncronizableChangeLine; unsigned unsyncronizableChangeLine;
unsigned unsyncronizableChangeColumn; unsigned unsyncronizableChangeColumn;
ClientProxy *m_clientProxy;
}; };
void QmlJSLiveTextPreview::documentChanged(QmlJS::Document::Ptr doc) void QmlJSLiveTextPreview::documentChanged(QmlJS::Document::Ptr doc)
{ {
if (doc->fileName() != m_previousDoc->fileName()) if (doc->fileName() != m_previousDoc->fileName() || !m_clientProxy)
return; return;
Core::ICore *core = Core::ICore::instance(); Core::ICore *core = Core::ICore::instance();
@@ -534,7 +548,7 @@ void QmlJSLiveTextPreview::documentChanged(QmlJS::Document::Ptr doc)
if (!core->hasContext(dbgcontext)) if (!core->hasContext(dbgcontext))
return; return;
if (ProjectExplorer::Project *debugProject = Inspector::instance()->debugProject()) { if (ProjectExplorer::Project *debugProject = InspectorUi::instance()->debugProject()) {
QStringList files = debugProject->files(ProjectExplorer::Project::ExcludeGeneratedFiles); QStringList files = debugProject->files(ProjectExplorer::Project::ExcludeGeneratedFiles);
if (!files.contains(doc->fileName())) if (!files.contains(doc->fileName()))
return; return;
@@ -548,16 +562,16 @@ void QmlJSLiveTextPreview::documentChanged(QmlJS::Document::Ptr doc)
if (doc && m_previousDoc && doc->fileName() == m_previousDoc->fileName() if (doc && m_previousDoc && doc->fileName() == m_previousDoc->fileName()
&& doc->qmlProgram() && m_previousDoc->qmlProgram()) && doc->qmlProgram() && m_previousDoc->qmlProgram())
{ {
UpdateObserver delta; UpdateObserver delta(m_clientProxy.data());
m_debugIds = delta(m_previousDoc, doc, m_debugIds); m_debugIds = delta(m_previousDoc, doc, m_debugIds);
if (delta.referenceRefreshRequired) if (delta.referenceRefreshRequired)
ClientProxy::instance()->refreshObjectTree(); m_clientProxy.data()->refreshObjectTree();
if (Inspector::instance()->showExperimentalWarning() && delta.appliedChangesToViewer) { if (InspectorUi::instance()->showExperimentalWarning() && delta.appliedChangesToViewer) {
showExperimentalWarning(); showExperimentalWarning();
experimentalWarningShown = true; experimentalWarningShown = true;
Inspector::instance()->setShowExperimentalWarning(false); InspectorUi::instance()->setShowExperimentalWarning(false);
} }
if (delta.unsyncronizableChanges != NoUnsyncronizableChanges && !experimentalWarningShown) if (delta.unsyncronizableChanges != NoUnsyncronizableChanges && !experimentalWarningShown)
@@ -568,7 +582,7 @@ void QmlJSLiveTextPreview::documentChanged(QmlJS::Document::Ptr doc)
if (!delta.newObjects.isEmpty()) if (!delta.newObjects.isEmpty())
m_createdObjects[doc] += delta.newObjects; m_createdObjects[doc] += delta.newObjects;
ClientProxy::instance()->clearComponentCache(); m_clientProxy.data()->clearComponentCache();
} }
} else { } else {
m_docWithUnappliedChanges = doc; m_docWithUnappliedChanges = doc;
@@ -634,5 +648,23 @@ void QmlJSLiveTextPreview::setApplyChangesToQmlObserver(bool applyChanges)
m_applyChangesToQmlObserver = applyChanges; m_applyChangesToQmlObserver = applyChanges;
} }
void QmlJSLiveTextPreview::setClientProxy(ClientProxy *clientProxy)
{
if (m_clientProxy.data()) {
disconnect(m_clientProxy.data(),
SIGNAL(objectTreeUpdated(QDeclarativeDebugObjectReference)),
this,
SLOT(updateDebugIds(QDeclarativeDebugObjectReference)));
}
m_clientProxy = clientProxy;
if (m_clientProxy.data()) {
connect(m_clientProxy.data(),
SIGNAL(objectTreeUpdated(QDeclarativeDebugObjectReference)),
SLOT(updateDebugIds(QDeclarativeDebugObjectReference)));
}
}
} // namespace Internal } // namespace Internal
} // namespace QmlJSInspector } // namespace QmlJSInspector

View File

@@ -56,12 +56,17 @@ namespace Internal {
namespace QmlJSInspector { namespace QmlJSInspector {
namespace Internal { namespace Internal {
class ClientProxy;
class QmlJSLiveTextPreview : public QObject class QmlJSLiveTextPreview : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit QmlJSLiveTextPreview(const QmlJS::Document::Ptr &doc, const QmlJS::Document::Ptr &initDoc, QObject *parent = 0); explicit QmlJSLiveTextPreview(const QmlJS::Document::Ptr &doc,
const QmlJS::Document::Ptr &initDoc,
ClientProxy *clientProxy,
QObject *parent = 0);
//void updateDocuments(); //void updateDocuments();
void associateEditor(Core::IEditor *editor); void associateEditor(Core::IEditor *editor);
@@ -70,6 +75,8 @@ public:
void mapObjectToQml(const QDeclarativeDebugObjectReference &object); void mapObjectToQml(const QDeclarativeDebugObjectReference &object);
void resetInitialDoc(const QmlJS::Document::Ptr &doc); void resetInitialDoc(const QmlJS::Document::Ptr &doc);
void setClientProxy(ClientProxy *clientProxy);
enum UnsyncronizableChangeType { enum UnsyncronizableChangeType {
NoUnsyncronizableChanges, NoUnsyncronizableChanges,
AttributeChangeWarning, AttributeChangeWarning,
@@ -111,6 +118,7 @@ private:
bool m_applyChangesToQmlObserver; bool m_applyChangesToQmlObserver;
QmlJS::Document::Ptr m_docWithUnappliedChanges; QmlJS::Document::Ptr m_docWithUnappliedChanges;
QWeakPointer<ClientProxy> m_clientProxy;
}; };

View File

@@ -37,8 +37,11 @@
#include <projectexplorer/applicationlauncher.h> #include <projectexplorer/applicationlauncher.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <debugger/debuggerrunner.h>
#include <debugger/debuggerplugin.h>
#include <debugger/debuggerconstants.h> #include <debugger/debuggerconstants.h>
#include <debugger/debuggeruiswitcher.h> #include <debugger/debuggeruiswitcher.h>
#include <debugger/debuggerengine.h>
#include <qmljsinspector/qmljsinspectorconstants.h> #include <qmljsinspector/qmljsinspectorconstants.h>
#include <QDir> #include <QDir>
@@ -143,16 +146,27 @@ bool QmlRunControlFactory::canRun(RunConfiguration *runConfiguration,
QmlProjectRunConfiguration *config = qobject_cast<QmlProjectRunConfiguration*>(runConfiguration); QmlProjectRunConfiguration *config = qobject_cast<QmlProjectRunConfiguration*>(runConfiguration);
if (mode == ProjectExplorer::Constants::RUNMODE) { if (mode == ProjectExplorer::Constants::RUNMODE) {
return config != 0; return config != 0;
} else { } else if (mode == ProjectExplorer::Constants::DEBUGMODE) {
return (config != 0) && Debugger::DebuggerUISwitcher::instance()->supportedLanguages().contains(QmlProjectManager::Constants::LANG_QML); bool qmlDebugSupportInstalled = Debugger::DebuggerUISwitcher::instance()->supportedLanguages().contains(QmlProjectManager::Constants::LANG_QML);
return (config != 0) && qmlDebugSupportInstalled;
} }
return false;
} }
RunControl *QmlRunControlFactory::create(RunConfiguration *runConfiguration, RunControl *QmlRunControlFactory::create(RunConfiguration *runConfiguration,
const QString &mode) const QString &mode)
{ {
QTC_ASSERT(canRun(runConfiguration, mode), return 0); QTC_ASSERT(canRun(runConfiguration, mode), return 0);
return new QmlRunControl(qobject_cast<QmlProjectRunConfiguration *>(runConfiguration), mode);
QmlProjectRunConfiguration *config = qobject_cast<QmlProjectRunConfiguration *>(runConfiguration);
RunControl *runControl = 0;
if (mode == ProjectExplorer::Constants::RUNMODE) {
runControl = new QmlRunControl(config, mode);
} else {
runControl = createDebugRunControl(config);
}
return runControl;
} }
QString QmlRunControlFactory::displayName() const QString QmlRunControlFactory::displayName() const
@@ -166,6 +180,25 @@ QWidget *QmlRunControlFactory::createConfigurationWidget(RunConfiguration *runCo
return new QLabel("TODO add Configuration widget"); return new QLabel("TODO add Configuration widget");
} }
ProjectExplorer::RunControl *QmlRunControlFactory::createDebugRunControl(QmlProjectRunConfiguration *runConfig)
{
ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment();
environment.set(QmlProjectManager::Constants::E_QML_DEBUG_SERVER_PORT, QString::number(runConfig->debugServerPort()));
Debugger::DebuggerStartParameters params;
params.startMode = Debugger::StartInternal;
params.executable = runConfig->viewerPath();
params.qmlServerAddress = runConfig->debugServerAddress();
params.qmlServerPort = runConfig->debugServerPort();
params.processArgs = runConfig->viewerArguments();
params.workingDirectory = runConfig->workingDirectory();
params.environment = environment.toStringList();
params.displayName = runConfig->displayName();
Debugger::DebuggerRunControl *debuggerRunControl = Debugger::DebuggerPlugin::createDebugger(params, runConfig);
return debuggerRunControl;
}
} // namespace Internal } // namespace Internal
} // namespace QmlProjectManager } // namespace QmlProjectManager

View File

@@ -75,6 +75,9 @@ public:
virtual ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, const QString &mode); virtual ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration, const QString &mode);
virtual QString displayName() const; virtual QString displayName() const;
virtual QWidget *createConfigurationWidget(ProjectExplorer::RunConfiguration *runConfiguration); virtual QWidget *createConfigurationWidget(ProjectExplorer::RunConfiguration *runConfiguration);
private:
ProjectExplorer::RunControl *createDebugRunControl(QmlProjectRunConfiguration *runConfig);
}; };
} // namespace Internal } // namespace Internal