forked from qt-creator/qt-creator
Added support for running QML debugger without C++ debugger on Symbian
Reviewed-by: kkoehne Reviewed-by: Pawel Polanski
This commit is contained in:
committed by
Kai Koehne
parent
2caf050dcd
commit
caf0547319
@@ -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,7 +240,9 @@ void CodaRunControl::handleConnected()
|
||||
m_state = StateConnected;
|
||||
appendMessage(tr("Connected.\n"), NormalMessageFormat);
|
||||
setProgress(maxProgress()*0.80);
|
||||
initCommunication();
|
||||
emit connected();
|
||||
if (!m_stopAfterConnect)
|
||||
initCommunication();
|
||||
}
|
||||
|
||||
void CodaRunControl::handleContextRemoved(const CodaEvent &event)
|
||||
@@ -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();
|
||||
sp.startMode = Debugger::StartInternal;
|
||||
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())
|
||||
|
||||
Reference in New Issue
Block a user