Commit caf05473 authored by Tom Sutcliffe's avatar Tom Sutcliffe Committed by Kai Koehne
Browse files

Added support for running QML debugger without C++ debugger on Symbian

Reviewed-by: kkoehne
Reviewed-by: Pawel Polanski
parent 2caf050d
......@@ -305,6 +305,7 @@ void QmlEngine::filterApplicationMessage(const QString &msg, int /*channel*/)
static QString waitingForConnection = QLatin1String("Waiting for connection ");
static QString unableToListen = QLatin1String("Unable to listen ");
static QString debuggingNotEnabled = QLatin1String("Ignoring \"-qmljsdebugger=");
static QString debuggingNotEnabled2 = QLatin1String("Ignoring\"-qmljsdebugger="); // There is (was?) a bug in one of the error strings - safest to handle both
static QString connectionEstablished = QLatin1String("Connection established");
QString errorMessage;
......@@ -313,7 +314,7 @@ void QmlEngine::filterApplicationMessage(const QString &msg, int /*channel*/)
} else if (status.startsWith(unableToListen)) {
//: Error message shown after 'Could not connect ... debugger:"
errorMessage = tr("The port seems to be in use.");
} else if (status.startsWith(debuggingNotEnabled)) {
} else if (status.startsWith(debuggingNotEnabled) || status.startsWith(debuggingNotEnabled2)) {
//: Error message shown after 'Could not connect ... debugger:"
errorMessage = tr("The application is not set up for QML/JS debugging.");
} else if (status.startsWith(connectionEstablished)) {
......@@ -380,7 +381,7 @@ void QmlEngine::runEngine()
{
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
if (!isSlaveEngine())
if (!isSlaveEngine() && startParameters().startMode != AttachToRemote)
startApplicationLauncher();
}
......
......@@ -70,7 +70,8 @@ enum { debug = 0 };
CodaRunControl::CodaRunControl(RunConfiguration *runConfiguration, const QString &mode) :
S60RunControlBase(runConfiguration, mode),
m_port(0),
m_state(StateUninit)
m_state(StateUninit),
m_stopAfterConnect(false)
{
const S60DeviceRunConfiguration *s60runConfig = qobject_cast<S60DeviceRunConfiguration *>(runConfiguration);
QTC_ASSERT(s60runConfig, return);
......@@ -239,6 +240,8 @@ void CodaRunControl::handleConnected()
m_state = StateConnected;
appendMessage(tr("Connected.\n"), NormalMessageFormat);
setProgress(maxProgress()*0.80);
emit connected();
if (!m_stopAfterConnect)
initCommunication();
}
......@@ -392,3 +395,14 @@ void CodaRunControl::deviceRemoved(const SymbianUtils::SymbianDevice &device)
finishRunControl();
}
}
void CodaRunControl::connect()
{
m_stopAfterConnect = true;
start();
}
void CodaRunControl::run()
{
initCommunication();
}
......@@ -66,11 +66,18 @@ public:
static QMessageBox *createCodaWaitingMessageBox(QWidget *parent = 0);
using QObject::connect;
void connect(); // Like start() but doesn't actually launch the program; just hooks up coda.
void run();
protected:
virtual bool doStart();
virtual void doStop();
virtual bool setupLauncher();
signals:
void connected();
protected slots:
void finishRunControl();
void checkForTimeout();
......@@ -114,6 +121,7 @@ private:
QString m_runningProcessId;
State m_state;
bool m_stopAfterConnect;
};
} // namespace Internal
......
......@@ -40,6 +40,7 @@
#include "qt4projectmanagerconstants.h"
#include "qtoutputformatter.h"
#include "qt4symbiantarget.h"
#include "codaruncontrol.h"
#include <utils/qtcassert.h>
......@@ -306,6 +307,22 @@ void S60DeviceRunConfiguration::setCommandLineArguments(const QString &args)
m_commandLineArguments = args;
}
QString S60DeviceRunConfiguration::qmlCommandLineArguments() const
{
QString args;
if (useQmlDebugger()) {
const S60DeployConfiguration *activeDeployConf =
qobject_cast<S60DeployConfiguration *>(qt4Target()->activeDeployConfiguration());
QTC_ASSERT(activeDeployConf, return args);
if (activeDeployConf->communicationChannel() == S60DeployConfiguration::CommunicationCodaTcpConnection)
args = QString("-qmljsdebugger=port:%1").arg(qmlDebugServerPort());
else
args = QString("-qmljsdebugger=ost");
}
return args;
}
QString S60DeviceRunConfiguration::proFilePath() const
{
return m_proFilePath;
......@@ -429,7 +446,11 @@ static Debugger::DebuggerStartParameters s60DebuggerStartParams(const S60DeviceR
sp.remoteChannel = activeDeployConf->serialPortName();
sp.processArgs = rc->commandLineArguments();
if (rc->useQmlDebugger() && !rc->useCppDebugger())
sp.startMode = Debugger::AttachToRemote;
else
sp.startMode = Debugger::StartInternal;
sp.toolChainAbi = rc->abi();
sp.executable = debugFileName;
sp.executableUid = rc->executableUid();
......@@ -437,14 +458,11 @@ static Debugger::DebuggerStartParameters s60DebuggerStartParams(const S60DeviceR
sp.serverPort = activeDeployConf->devicePort().toInt();
sp.displayName = rc->displayName();
sp.qmlServerPort = rc->qmlDebugServerPort();
// TODO - is this the correct place to put this?
if (rc->useQmlDebugger()) {
QString qmlArgs = rc->qmlCommandLineArguments();
if (sp.processArgs.length())
sp.processArgs.prepend(" ");
if (activeDeployConf->communicationChannel() == S60DeployConfiguration::CommunicationCodaTcpConnection)
sp.processArgs.prepend(QString("-qmljsdebugger=port:%1").arg(sp.qmlServerPort));
else
sp.processArgs.prepend(QString("-qmljsdebugger=ost"));
sp.processArgs.prepend(qmlArgs);
}
sp.communicationChannel = activeDeployConf->communicationChannel() == S60DeployConfiguration::CommunicationCodaTcpConnection?
......@@ -466,13 +484,19 @@ static Debugger::DebuggerStartParameters s60DebuggerStartParams(const S60DeviceR
S60DeviceDebugRunControl::S60DeviceDebugRunControl(S60DeviceRunConfiguration *rc,
const Debugger::DebuggerStartParameters &sp,
const QPair<Debugger::DebuggerEngineType, Debugger::DebuggerEngineType> &masterSlaveEngineTypes) :
Debugger::DebuggerRunControl(rc, sp, masterSlaveEngineTypes)
Debugger::DebuggerRunControl(rc, sp, masterSlaveEngineTypes),
m_codaRunControl(NULL),
m_codaState(ENotUsingCodaRunControl)
{
if (startParameters().symbolFileName.isEmpty()) {
const QString msg = tr("Warning: Cannot locate the symbol file belonging to %1.\n").
arg(rc->localExecutableFileName());
appendMessage(msg, ErrorMessageFormat);
}
if (masterSlaveEngineTypes.first == Debugger::QmlEngineType) {
connect(engine(), SIGNAL(requestRemoteSetup()), this, SLOT(remoteSetupRequested()));
connect(engine(), SIGNAL(stateChanged(Debugger::DebuggerState)), this, SLOT(qmlEngineStateChanged(Debugger::DebuggerState)));
}
}
void S60DeviceDebugRunControl::start()
......@@ -487,6 +511,63 @@ bool S60DeviceDebugRunControl::promptToStop(bool *) const
return Debugger::DebuggerRunControl::promptToStop(0);
}
void S60DeviceDebugRunControl::remoteSetupRequested()
{
// This is called from Engine->setupInferior(), ie InferiorSetupRequested state
QTC_ASSERT(runConfiguration()->useQmlDebugger() && !runConfiguration()->useCppDebugger(), return);
m_codaRunControl = new CodaRunControl(runConfiguration(), Debugger::Constants::DEBUGMODE);
connect(m_codaRunControl, SIGNAL(connected()), this, SLOT(codaConnected()));
connect(m_codaRunControl, SIGNAL(finished()), this, SLOT(codaFinished()));
connect(m_codaRunControl, SIGNAL(appendMessage(ProjectExplorer::RunControl*,QString,ProjectExplorer::OutputFormat)), this, SLOT(handleMessageFromCoda(ProjectExplorer::RunControl*,QString,ProjectExplorer::OutputFormat)));
connect(this, SIGNAL(finished()), this, SLOT(handleDebuggingFinished()));
m_codaState = EWaitingForCodaConnection;
m_codaRunControl->connect();
}
void S60DeviceDebugRunControl::codaFinished()
{
if (m_codaRunControl) {
m_codaRunControl->deleteLater();
m_codaRunControl = NULL;
}
if (m_codaState == EWaitingForCodaConnection) {
engine()->handleRemoteSetupFailed(QLatin1String("CODA failed to initialise")); // TODO sort out this error string? Unlikely we'll ever hit this state anyway.
} else {
debuggingFinished();
}
m_codaState = ENotUsingCodaRunControl;
}
void S60DeviceDebugRunControl::codaConnected()
{
QTC_ASSERT(m_codaState == EWaitingForCodaConnection, return);
m_codaState = ECodaConnected;
engine()->handleRemoteSetupDone(-1, 0); // calls notifyInferiorSetupOk()
}
void S60DeviceDebugRunControl::qmlEngineStateChanged(const Debugger::DebuggerState &state)
{
if (state == Debugger::EngineRunRequested)
m_codaRunControl->run();
}
void S60DeviceDebugRunControl::handleDebuggingFinished()
{
if (m_codaRunControl) {
m_codaRunControl->stop(); // We'll get a callback to our codaFinished() slot when it's done
}
}
void S60DeviceDebugRunControl::handleMessageFromCoda(ProjectExplorer::RunControl *aCodaRunControl, const QString &msg, ProjectExplorer::OutputFormat format)
{
// This only gets used when QmlEngine is the master debug engine. If GDB is running, messages are handled via the gdb adapter
Q_UNUSED(aCodaRunControl)
Q_UNUSED(format)
engine()->showMessage(msg, Debugger::AppOutput);
}
//
S60DeviceDebugRunControlFactory::S60DeviceDebugRunControlFactory(QObject *parent) :
IRunControlFactory(parent)
{
......
......@@ -53,6 +53,7 @@ namespace Internal {
class Qt4SymbianTarget;
class Qt4ProFileNode;
class S60DeviceRunConfigurationFactory;
class CodaRunControl;
class S60DeviceRunConfiguration : public ProjectExplorer::RunConfiguration
{
......@@ -74,6 +75,7 @@ public:
QString commandLineArguments() const;
void setCommandLineArguments(const QString &args);
QString qmlCommandLineArguments() const;
QString projectFilePath() const;
......@@ -139,6 +141,22 @@ public:
const QPair<Debugger::DebuggerEngineType, Debugger::DebuggerEngineType> &masterSlaveEngineTypes);
virtual void start();
virtual bool promptToStop(bool *optionalPrompt = 0) const;
private slots:
void remoteSetupRequested();
void codaConnected();
void qmlEngineStateChanged(const Debugger::DebuggerState &state);
void codaFinished();
void handleDebuggingFinished();
void handleMessageFromCoda(ProjectExplorer::RunControl *aCodaRunControl, const QString &msg, ProjectExplorer::OutputFormat format);
private:
CodaRunControl *m_codaRunControl;
enum {
ENotUsingCodaRunControl = 0,
EWaitingForCodaConnection,
ECodaConnected,
} m_codaState;
};
class S60DeviceDebugRunControlFactory : public ProjectExplorer::IRunControlFactory
......
......@@ -88,6 +88,11 @@ S60RunControlBase::S60RunControlBase(RunConfiguration *runConfiguration, const Q
m_executableUid = s60runConfig->executableUid();
m_targetName = s60runConfig->targetName();
m_commandLineArguments = s60runConfig->commandLineArguments();
QString qmlArgs = s60runConfig->qmlCommandLineArguments();
if (mode == Debugger::Constants::DEBUGMODE && qmlArgs.length()) {
m_commandLineArguments.prepend(' ');
m_commandLineArguments.prepend(qmlArgs);
}
m_qtDir = activeBuildConf->qtVersion()->versionInfo().value("QT_INSTALL_DATA");
m_installationDrive = activeDeployConf->installationDrive();
if (const QtVersion *qtv = activeDeployConf->qtVersion())
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment