Newer
Older
/**************************************************************************
**
** 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
**
**************************************************************************/
#include "s60devicerunconfiguration.h"
#include "s60devicerunconfigurationwidget.h"

Pawel Polanski
committed
#include "s60deployconfiguration.h"
#include "qtversionmanager.h"
#include "profilereader.h"
#include "s60manager.h"
#include "s60devices.h"
#include "s60runconfigbluetoothstarter.h"
#include "bluetoothlistener_gui.h"

Friedemann Kleint
committed
#include "symbiandevicemanager.h"
#include "qt4buildconfiguration.h"
#include "qt4projectmanagerconstants.h"
#include "s60createpackagestep.h"
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <projectexplorer/deployconfiguration.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/project.h>
#include <debugger/debuggerengine.h>
#include <debugger/debuggerplugin.h>
#include <QtGui/QMessageBox>
#include <QtGui/QMainWindow>
#include <QtCore/QCoreApplication>
using namespace Qt4ProjectManager::Internal;
namespace {
const char * const S60_DEVICE_RC_ID("Qt4ProjectManager.S60DeviceRunConfiguration");
const char * const S60_DEVICE_RC_PREFIX("Qt4ProjectManager.S60DeviceRunConfiguration.");
const char * const PRO_FILE_KEY("Qt4ProjectManager.S60DeviceRunConfiguration.ProFile");
const char * const COMMUNICATION_TYPE_KEY("Qt4ProjectManager.S60DeviceRunConfiguration.CommunicationType");
const char * const COMMAND_LINE_ARGUMENTS_KEY("Qt4ProjectManager.S60DeviceRunConfiguration.CommandLineArguments");
const int PROGRESS_MAX = 200;
// Format information about a file
static inline QString msgListFile(const QString &f)
{
QString rc;
const QFileInfo fi(f);
QTextStream str(&rc);
if (fi.exists()) {
str << fi.size() << ' ' << fi.lastModified().toString(Qt::ISODate) << ' ' << QDir::toNativeSeparators(fi.absoluteFilePath());
} else {
str << "<non-existent> " << QDir::toNativeSeparators(fi.absoluteFilePath());
}
QString pathFromId(const QString &id)
{
if (!id.startsWith(QLatin1String(S60_DEVICE_RC_PREFIX)))
return QString();
return id.mid(QString::fromLatin1(S60_DEVICE_RC_PREFIX).size());
}
QString pathToId(const QString &path)
{
return QString::fromLatin1(S60_DEVICE_RC_PREFIX) + path;
}
}
// ======== S60DeviceRunConfiguration
S60DeviceRunConfiguration::S60DeviceRunConfiguration(Target *parent, const QString &proFilePath) :
RunConfiguration(parent, QLatin1String(S60_DEVICE_RC_ID)),

Pawel Polanski
committed
m_proFilePath(proFilePath)
{
ctor();
}
S60DeviceRunConfiguration::S60DeviceRunConfiguration(Target *target, S60DeviceRunConfiguration *source) :
RunConfiguration(target, source),
m_proFilePath(source->m_proFilePath),

Pawel Polanski
committed
m_commandLineArguments(source->m_commandLineArguments)
{
ctor();
}
void S60DeviceRunConfiguration::ctor()
//: S60 device runconfiguration default display name, %1 is base pro-File name
setDefaultDisplayName(tr("%1 on Symbian Device").arg(QFileInfo(m_proFilePath).completeBaseName()));
//: S60 device runconfiguration default display name (no profile set)
setDefaultDisplayName(tr("Run on Symbian device"));
}
void S60DeviceRunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
{
if (m_proFilePath == pro->path())
emit targetInformationChanged();
}
S60DeviceRunConfiguration::~S60DeviceRunConfiguration()
{
}
Qt4Target *S60DeviceRunConfiguration::qt4Target() const
ProjectExplorer::ToolChain::ToolChainType S60DeviceRunConfiguration::toolChainType(
ProjectExplorer::BuildConfiguration *configuration) const
{
if (Qt4BuildConfiguration *bc = qobject_cast<Qt4BuildConfiguration *>(configuration))
return bc->toolChainType();
return ProjectExplorer::ToolChain::INVALID;
}
ProjectExplorer::ToolChain::ToolChainType S60DeviceRunConfiguration::toolChainType() const
{
if (Qt4BuildConfiguration *bc = qobject_cast<Qt4BuildConfiguration *>(target()->activeBuildConfiguration()))
return ProjectExplorer::ToolChain::INVALID;
bool S60DeviceRunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *configuration) const
const Qt4BuildConfiguration *qt4bc = static_cast<const Qt4BuildConfiguration *>(configuration);
switch (qt4bc->toolChainType()) {
case ToolChain::GCCE:
case ToolChain::RVCT_ARMV5:
case ToolChain::RVCT_ARMV6:
case ToolChain::GCCE_GNUPOC:
case ToolChain::RVCT_ARMV5_GNUPOC:
return true;
default:
break;
}
return false;
QWidget *S60DeviceRunConfiguration::createConfigurationWidget()
{
return new S60DeviceRunConfigurationWidget(this);
}
ProjectExplorer::OutputFormatter *S60DeviceRunConfiguration::createOutputFormatter() const
{
return new QtOutputFormatter(qt4Target()->qt4Project());
}
QVariantMap S60DeviceRunConfiguration::toMap() const
QVariantMap map(ProjectExplorer::RunConfiguration::toMap());
const QDir projectDir = QDir(target()->project()->projectDirectory());
map.insert(QLatin1String(PRO_FILE_KEY), projectDir.relativeFilePath(m_proFilePath));
map.insert(QLatin1String(COMMAND_LINE_ARGUMENTS_KEY), m_commandLineArguments);
return map;
bool S60DeviceRunConfiguration::fromMap(const QVariantMap &map)
const QDir projectDir = QDir(target()->project()->projectDirectory());
m_proFilePath = projectDir.filePath(map.value(QLatin1String(PRO_FILE_KEY)).toString());
m_commandLineArguments = map.value(QLatin1String(COMMAND_LINE_ARGUMENTS_KEY)).toStringList();
if (m_proFilePath.isEmpty())
return false;
if (!QFileInfo(m_proFilePath).exists())
return false;
setDefaultDisplayName(tr("%1 on Symbian Device").arg(QFileInfo(m_proFilePath).completeBaseName()));
return RunConfiguration::fromMap(map);
static inline QString fixBaseNameTarget(const QString &in)
{
if (in == QLatin1String("udeb"))
return QLatin1String("debug");
if (in == QLatin1String("urel"))
return QLatin1String("release");
return in;
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
QString S60DeviceRunConfiguration::targetName() const
{
TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(projectFilePath());
if (!ti.valid)
return QString();
return ti.target;
}
const QtVersion *S60DeviceRunConfiguration::qtVersion() const
{
if (const BuildConfiguration *bc = target()->activeBuildConfiguration())
if (const Qt4BuildConfiguration *qt4bc = qobject_cast<const Qt4BuildConfiguration *>(bc))
return qt4bc->qtVersion();
return 0;
}
bool S60DeviceRunConfiguration::isDebug() const
{
const Qt4BuildConfiguration *qt4bc = qt4Target()->activeBuildConfiguration();
return (qt4bc->qmakeBuildConfiguration() & QtVersion::DebugBuild);
}
QString S60DeviceRunConfiguration::symbianTarget() const
{
return isDebug() ? QLatin1String("udeb") : QLatin1String("urel");
}
QString S60DeviceRunConfiguration::symbianPlatform() const
{
const Qt4BuildConfiguration *qt4bc = qt4Target()->activeBuildConfiguration();
switch (qt4bc->toolChainType()) {
case ToolChain::GCCE:
case ToolChain::GCCE_GNUPOC:
return QLatin1String("gcce");
case ToolChain::RVCT_ARMV5:
return QLatin1String("armv5");
default: // including ToolChain::RVCT_ARMV6_GNUPOC:
return QLatin1String("armv6");
}
}
/* Grep a package file for the '.exe' file. Curently for use on Linux only
* as the '.pkg'-files on Windows do not contain drive letters, which is not
* handled here. \code
; Executable and default resource files
"./foo.exe" - "!:\sys\bin\foo.exe"
\endcode */
static inline QString executableFromPackageUnix(const QString &packageFileName)
{
QFile packageFile(packageFileName);
if (!packageFile.open(QIODevice::ReadOnly|QIODevice::Text))
return QString();
QRegExp pattern(QLatin1String("^\"(.*.exe)\" *- \"!:.*.exe\"$"));
QTC_ASSERT(pattern.isValid(), return QString());
foreach(const QString &line, QString::fromLocal8Bit(packageFile.readAll()).split(QLatin1Char('\n')))
if (pattern.exactMatch(line)) {
// Expand relative paths by package file paths
QString rc = pattern.cap(1);
if (rc.startsWith(QLatin1String("./")))
rc.remove(0, 2);
const QFileInfo fi(rc);
if (fi.isAbsolute())
return rc;
return QFileInfo(packageFileName).absolutePath() + QLatin1Char('/') + rc;
}
return QString();
}
QString S60DeviceRunConfiguration::localExecutableFileName() const
{
QString localExecutable;
switch (toolChainType()) {
case ToolChain::GCCE_GNUPOC:
case ToolChain::RVCT_ARMV5_GNUPOC: {
TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(projectFilePath());
if (!ti.valid)
return QString();
localExecutable = executableFromPackageUnix(ti.buildDir + QLatin1Char('/') + ti.target + QLatin1String("_template.pkg"));
}
break;
default: {
const QtVersion *qtv = qtVersion();
QTC_ASSERT(qtv, return QString());
const S60Devices::Device device = S60Manager::instance()->deviceForQtVersion(qtv);
QTextStream(&localExecutable) << device.epocRoot << "/epoc32/release/"
<< symbianPlatform() << '/' << symbianTarget() << '/' << targetName()
<< ".exe";
}
break;
}
return QDir::toNativeSeparators(localExecutable);
}
quint32 S60DeviceRunConfiguration::executableUid() const
{
quint32 uid = 0;
QString executablePath(localExecutableFileName());
if (!executablePath.isEmpty()) {
QFile file(executablePath);
if (file.open(QIODevice::ReadOnly)) {
// executable's UID is 4 bytes starting at 8.
const QByteArray data = file.read(12);
if (data.size() == 12) {
const unsigned char *d = reinterpret_cast<const unsigned char*>(data.data() + 8);
uid = *d++;
uid += *d++ << 8;
uid += *d++ << 16;
uid += *d++ << 24;
}
}
}
return uid;
}

Pawel Polanski
committed
QString S60DeviceRunConfiguration::projectFilePath() const

Pawel Polanski
committed
return m_proFilePath;
QStringList S60DeviceRunConfiguration::commandLineArguments() const
{
return m_commandLineArguments;
}
void S60DeviceRunConfiguration::setCommandLineArguments(const QStringList &args)
{
m_commandLineArguments = args;
}
// ======== S60DeviceRunConfigurationFactory
S60DeviceRunConfigurationFactory::S60DeviceRunConfigurationFactory(QObject *parent) :
IRunConfigurationFactory(parent)
{
}
S60DeviceRunConfigurationFactory::~S60DeviceRunConfigurationFactory()
{
}
QStringList S60DeviceRunConfigurationFactory::availableCreationIds(Target *parent) const
Qt4Target *target = qobject_cast<Qt4Target *>(parent);
if (!target ||
target->id() != QLatin1String(Constants::S60_DEVICE_TARGET_ID))
return QStringList();
return target->qt4Project()->applicationProFilePathes(QLatin1String(S60_DEVICE_RC_PREFIX));
QString S60DeviceRunConfigurationFactory::displayNameForId(const QString &id) const
if (!pathFromId(id).isEmpty())
return tr("%1 on Symbian Device").arg(QFileInfo(pathFromId(id)).completeBaseName());
return QString();
bool S60DeviceRunConfigurationFactory::canCreate(Target *parent, const QString &id) const
Qt4Target * t(qobject_cast<Qt4Target *>(parent));
if (!t ||
t->id() != QLatin1String(Constants::S60_DEVICE_TARGET_ID))
return t->qt4Project()->hasApplicationProFile(pathFromId(id));
RunConfiguration *S60DeviceRunConfigurationFactory::create(Target *parent, const QString &id)
if (!canCreate(parent, id))
return 0;
Qt4Target *t(static_cast<Qt4Target *>(parent));
return new S60DeviceRunConfiguration(t, pathFromId(id));
bool S60DeviceRunConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
Qt4Target * t(qobject_cast<Qt4Target *>(parent));
if (!t ||
t->id() != QLatin1String(Constants::S60_DEVICE_TARGET_ID))
return false;
QString id(ProjectExplorer::idFromMap(map));
return id == QLatin1String(S60_DEVICE_RC_ID);
}
RunConfiguration *S60DeviceRunConfigurationFactory::restore(Target *parent, const QVariantMap &map)
{
if (!canRestore(parent, map))
return 0;
Qt4Target *t(static_cast<Qt4Target *>(parent));
S60DeviceRunConfiguration *rc(new S60DeviceRunConfiguration(t, QString()));
if (rc->fromMap(map))
return rc;
delete rc;
return 0;
}
bool S60DeviceRunConfigurationFactory::canClone(Target *parent, RunConfiguration *source) const
return false;
return source->id() == QLatin1String(S60_DEVICE_RC_ID);
}
RunConfiguration *S60DeviceRunConfigurationFactory::clone(Target *parent, RunConfiguration *source)
{
if (!canClone(parent, source))
return 0;
Qt4Target *t = static_cast<Qt4Target *>(parent);
S60DeviceRunConfiguration * old(static_cast<S60DeviceRunConfiguration *>(source));

Pawel Polanski
committed
S60DeviceRunControl::S60DeviceRunControl(RunConfiguration *runConfiguration, QString mode) :
m_toolChain(ProjectExplorer::ToolChain::INVALID),
m_handleDeviceRemoval(true),
{
// connect for automatically reporting the "finished deploy" state to the progress manager
connect(this, SIGNAL(finished()), this, SLOT(reportDeployFinished()));
S60DeviceRunConfiguration *s60runConfig = qobject_cast<S60DeviceRunConfiguration *>(runConfiguration);
const Qt4BuildConfiguration *activeBuildConf = s60runConfig->qt4Target()->activeBuildConfiguration();

Pawel Polanski
committed
S60DeployConfiguration *activeDeployConf = qobject_cast<S60DeployConfiguration *>(s60runConfig->qt4Target()->activeDeployConfiguration());
QTC_ASSERT(s60runConfig, return);
m_toolChain = s60runConfig->toolChainType();

Pawel Polanski
committed
m_serialPortName = activeDeployConf->serialPortName();

Friedemann Kleint
committed
m_serialPortFriendlyName = SymbianUtils::SymbianDeviceManager::instance()->friendlyNameForPort(m_serialPortName);
m_targetName = s60runConfig->targetName();
m_commandLineArguments = s60runConfig->commandLineArguments();
m_qtDir = activeBuildConf->qtVersion()->versionInfo().value("QT_INSTALL_DATA");

Pawel Polanski
committed
m_installationDrive = activeDeployConf->installationDrive();
if (const QtVersion *qtv = activeDeployConf->qtVersion())
m_qtBinPath = qtv->versionInfo().value(QLatin1String("QT_INSTALL_BINS"));
QTC_ASSERT(!m_qtBinPath.isEmpty(), return);
m_executableFileName = s60runConfig->localExecutableFileName();

Pawel Polanski
committed
qDebug() << "S60DeviceRunControl::CT" << m_targetName << ProjectExplorer::ToolChain::toolChainName(m_toolChain)

Pawel Polanski
committed
S60DeviceRunControl::~S60DeviceRunControl()
{
if (m_launcher) {
m_launcher->deleteLater();
m_launcher = 0;
}
}

Pawel Polanski
committed
void S60DeviceRunControl::start()

Pawel Polanski
committed
m_launchProgress = new QFutureInterface<void>;
Core::ICore::instance()->progressManager()->addTask(m_launchProgress->future(),
tr("Launching"),
QLatin1String("Symbian.Launch"));

Pawel Polanski
committed
m_launchProgress->setProgressRange(0, PROGRESS_MAX);
m_launchProgress->setProgressValue(0);
m_launchProgress->reportStarted();
if (m_serialPortName.isEmpty()) {

Pawel Polanski
committed
m_launchProgress->reportCanceled();
appendMessage(this, tr("There is no device plugged in."), true);
emit finished();
return;
}
emit appendMessage(this, tr("Executable file: %1").arg(msgListFile(m_executableFileName)), false);
QString errorMessage;
QString settingsCategory;
QString settingsPage;
if (!checkConfiguration(&errorMessage, &settingsCategory, &settingsPage)) {

Pawel Polanski
committed
m_launchProgress->reportCanceled();
appendMessage(this, errorMessage, true);
emit finished();
Core::ICore::instance()->showWarningWithOptions(tr("Debugger for Symbian Platform"),
errorMessage, QString(),
settingsCategory, settingsPage);
return;
}
RunControl::StopResult S60DeviceRunControl::stop()
{
if (m_launcher)
m_launcher->terminate();
return AsynchronousStop;

Pawel Polanski
committed
bool S60DeviceRunControl::isRunning() const

Pawel Polanski
committed
return m_launcher && (m_launcher->state() == trk::Launcher::Connecting
|| m_launcher->state() == trk::Launcher::Connected
|| m_launcher->state() == trk::Launcher::WaitingForTrk);

Pawel Polanski
committed
void S60DeviceRunControl::startLaunching()

Pawel Polanski
committed
if (setupLauncher(errorMessage)) {

Pawel Polanski
committed
if (m_launchProgress)
m_launchProgress->setProgressValue(PROGRESS_MAX/2);

Pawel Polanski
committed
} else {
if (!errorMessage.isEmpty())
appendMessage(this, errorMessage, true);

Pawel Polanski
committed
bool S60DeviceRunControl::setupLauncher(QString &errorMessage)

Pawel Polanski
committed
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
{
connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(deviceRemoved(const SymbianUtils::SymbianDevice)),
this, SLOT(deviceRemoved(SymbianUtils::SymbianDevice)));
m_launcher = trk::Launcher::acquireFromDeviceManager(m_serialPortName, 0, &errorMessage);
if (!m_launcher)
return false;
connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished()));
connect(m_launcher, SIGNAL(canNotConnect(QString)), this, SLOT(printConnectFailed(QString)));
connect(m_launcher, SIGNAL(stateChanged(int)), this, SLOT(slotLauncherStateChanged(int)));
connect(m_launcher, SIGNAL(processStopped(uint,uint,uint,QString)),
this, SLOT(processStopped(uint,uint,uint,QString)));
if (!m_commandLineArguments.isEmpty())
m_launcher->setCommandLineArgs(m_commandLineArguments);
const QString runFileName = QString::fromLatin1("%1:\\sys\\bin\\%2.exe").arg(m_installationDrive).arg(m_targetName);
initLauncher(runFileName, m_launcher);
const trk::PromptStartCommunicationResult src =
S60RunConfigBluetoothStarter::startCommunication(m_launcher->trkDevice(),
0, &errorMessage);
if (src != trk::PromptStartCommunicationConnected)
return false;
if (!m_launcher->startServer(&errorMessage)) {
errorMessage = tr("Could not connect to phone on port '%1': %2\n"
"Check if the phone is connected and App TRK is running.").arg(m_serialPortName, errorMessage);
return false;
}
return true;
}

Pawel Polanski
committed
void S60DeviceRunControl::printConnectFailed(const QString &errorMessage)
emit appendMessage(this, tr("Could not connect to App TRK on device: %1. Restarting App TRK might help.").arg(errorMessage), true);

Pawel Polanski
committed
void S60DeviceRunControl::launcherFinished()

Pawel Polanski
committed
m_handleDeviceRemoval = false;
trk::Launcher::releaseToDeviceManager(m_launcher);
m_launcher->deleteLater();
m_launcher = 0;
handleLauncherFinished();
}

Pawel Polanski
committed
void S60DeviceRunControl::reportDeployFinished()

Pawel Polanski
committed
if (m_launchProgress) {
m_launchProgress->reportFinished();
delete m_launchProgress;
m_launchProgress = 0;

Pawel Polanski
committed
void S60DeviceRunControl::processStopped(uint pc, uint pid, uint tid, const QString& reason)
emit addToOutputWindow(this, trk::Launcher::msgStopped(pid, tid, pc, reason), false);
m_launcher->terminate();
}

Pawel Polanski
committed
QMessageBox *S60DeviceRunControl::createTrkWaitingMessageBox(const QString &port, QWidget *parent)
const QString title = tr("Waiting for App TRK");
const QString text = tr("Qt Creator is waiting for the TRK application to connect.<br>"
"Please make sure the application is running on "
"your mobile phone and the right port is "
"configured in the project settings.").arg(port);
QMessageBox *rc = new QMessageBox(QMessageBox::Information, title, text,
QMessageBox::Cancel, parent);
return rc;
}

Pawel Polanski
committed
void S60DeviceRunControl::slotLauncherStateChanged(int s)
{
if (s == trk::Launcher::WaitingForTrk) {

Pawel Polanski
committed
QMessageBox *mb = S60DeviceRunControl::createTrkWaitingMessageBox(m_launcher->trkServerName(),
Core::ICore::instance()->mainWindow());
connect(m_launcher, SIGNAL(stateChanged(int)), mb, SLOT(close()));
connect(mb, SIGNAL(finished(int)), this, SLOT(slotWaitingForTrkClosed()));
mb->open();
}
}

Pawel Polanski
committed
void S60DeviceRunControl::slotWaitingForTrkClosed()
{
if (m_launcher && m_launcher->state() == trk::Launcher::WaitingForTrk) {
stop();
appendMessage(this, tr("Canceled."), true);
emit finished();
}
}

Pawel Polanski
committed
void S60DeviceRunControl::printApplicationOutput(const QString &output)
{
printApplicationOutput(output, false);
}

Pawel Polanski
committed
void S60DeviceRunControl::printApplicationOutput(const QString &output, bool onStdErr)
emit addToOutputWindowInline(this, output, onStdErr);

Pawel Polanski
committed
void S60DeviceRunControl::deviceRemoved(const SymbianUtils::SymbianDevice &d)
{
if (m_handleDeviceRemoval && d.portName() == m_serialPortName) {
appendMessage(this, tr("The device '%1' has been disconnected").arg(d.friendlyName()), true);
emit finished();
}
}

Pawel Polanski
committed
bool S60DeviceRunControl::checkConfiguration(QString * /* errorMessage */,
QString * /* settingsCategory */,
QString * /* settingsPage */) const
{
return true;
}
void S60DeviceRunControl::initLauncher(const QString &executable, trk::Launcher *launcher)
{
connect(launcher, SIGNAL(startingApplication()), this, SLOT(printStartingNotice()));

Pawel Polanski
committed
connect(launcher, SIGNAL(applicationRunning(uint)), this, SLOT(applicationRunNotice(uint)));
connect(launcher, SIGNAL(canNotRun(QString)), this, SLOT(applicationRunFailedNotice(QString)));
connect(launcher, SIGNAL(applicationOutputReceived(QString)), this, SLOT(printApplicationOutput(QString)));
launcher->addStartupActions(trk::Launcher::ActionRun);
launcher->setFileName(executable);
}
void S60DeviceRunControl::handleLauncherFinished()
{
emit finished();
emit appendMessage(this, tr("Finished."), false);
void S60DeviceRunControl::printStartingNotice()
{
emit appendMessage(this, tr("Starting application..."), false);

Pawel Polanski
committed
void S60DeviceRunControl::applicationRunNotice(uint pid)
emit appendMessage(this, tr("Application running with pid %1.").arg(pid), false);

Pawel Polanski
committed
if (m_launchProgress)
m_launchProgress->setProgressValue(PROGRESS_MAX);

Pawel Polanski
committed
void S60DeviceRunControl::applicationRunFailedNotice(const QString &errorMessage)
{
emit appendMessage(this, tr("Could not start application: %1").arg(errorMessage), true);
// ======== S60DeviceDebugRunControl
static inline QString localExecutable(const S60DeviceRunConfiguration *rc)
if (const S60DeviceRunConfiguration *s60runConfig = qobject_cast<const S60DeviceRunConfiguration *>(rc))
return s60runConfig->localExecutableFileName();
return QString();
}
// Create start parameters from run configuration
Debugger::DebuggerStartParameters S60DeviceDebugRunControl::s60DebuggerStartParams(const S60DeviceRunConfiguration *rc)
{
Debugger::DebuggerStartParameters sp;
QTC_ASSERT(rc, return sp);
const S60DeployConfiguration *activeDeployConf = qobject_cast<S60DeployConfiguration *>(rc->qt4Target()->activeDeployConfiguration());

Pawel Polanski
committed

Pawel Polanski
committed
const QString debugFileName = QString::fromLatin1("%1:\\sys\\bin\\%2.exe")
.arg(activeDeployConf->installationDrive()).arg(rc->targetName());

Pawel Polanski
committed
sp.remoteChannel = activeDeployConf->serialPortName();
sp.processArgs = rc->commandLineArguments();
sp.startMode = Debugger::StartInternal;
sp.toolChainType = rc->toolChainType();
sp.executable = debugFileName;
sp.executableUid = rc->executableUid();

Pawel Polanski
committed
QTC_ASSERT(sp.executableUid, return sp);

Pawel Polanski
committed
// Prefer the '*.sym' file over the '.exe', which should exist at the same
// location in debug builds
const QString localExecutableFileName = localExecutable(rc);
const int lastDotPos = localExecutableFileName.lastIndexOf(QLatin1Char('.'));
if (lastDotPos != -1) {
const QString symbolFileName = localExecutableFileName.mid(0, lastDotPos) + QLatin1String(".sym");
if (QFileInfo(symbolFileName).isFile())
sp.symbolFileName = symbolFileName;

Pawel Polanski
committed
}
return sp;
}
S60DeviceDebugRunControl::S60DeviceDebugRunControl(S60DeviceRunConfiguration *rc,
const QString &) :
Debugger::DebuggerRunControl(rc, Debugger::GdbEngineType,
S60DeviceDebugRunControl::s60DebuggerStartParams(rc))
{
if (startParameters().symbolFileName.isEmpty()) {
const QString msg = tr("Warning: Cannot locate the symbol file belonging to %1.").
arg(localExecutable(rc));
emit appendMessage(this, msg, true);
connect(this, SIGNAL(finished()), this, SLOT(slotFinished()));

Pawel Polanski
committed
void S60DeviceDebugRunControl::start()

Pawel Polanski
committed
QString errorMessage;
QString settingsCategory;
QString settingsPage;
if (!Debugger::DebuggerRunControl::checkDebugConfiguration(startParameters().toolChainType,
&errorMessage, &settingsCategory, &settingsPage)) {

Pawel Polanski
committed
m_debugProgress->reportCanceled();
appendMessage(this, errorMessage, true);
emit finished();
Core::ICore::instance()->showWarningWithOptions(tr("Debugger for Symbian Platform"),
errorMessage, QString(),
settingsCategory, settingsPage);
return;
m_debugProgress.reset(new QFutureInterface<void>);
Core::ICore::instance()->progressManager()->addTask(m_debugProgress->future(),
tr("Debugging"),
QLatin1String("Symbian.Debug"));
m_debugProgress->setProgressRange(0, PROGRESS_MAX);
m_debugProgress->setProgressValue(0);
m_debugProgress->reportStarted();
emit appendMessage(this, tr("Launching debugger..."), false);
Debugger::DebuggerRunControl::start();

Pawel Polanski
committed
S60DeviceDebugRunControl::~S60DeviceDebugRunControl()
{
}
RunControl::StopResult S60DeviceDebugRunControl::stop()
{
if (!m_debugProgress.isNull()) {

Pawel Polanski
committed
m_debugProgress->reportCanceled();
m_debugProgress.reset();
}
return Debugger::DebuggerRunControl::stop();

Pawel Polanski
committed
}
void S60DeviceDebugRunControl::slotFinished()
if (!m_debugProgress.isNull()) {

Pawel Polanski
committed
m_debugProgress->setProgressValue(PROGRESS_MAX);
m_debugProgress->reportFinished();
m_debugProgress.reset();

Pawel Polanski
committed
}