Newer
Older
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 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"
#include "qt4project.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 <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/persistentsettings.h>
#include <debugger/debuggermanager.h>
#include <QtGui/QMessageBox>
#include <QtGui/QMainWindow>
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 SIGNING_MODE_KEY("Qt4ProjectManager.S60DeviceRunConfiguration.SigningMode");
const char * const CUSTOM_SIGNATURE_PATH_KEY("Qt4ProjectManager.S60DeviceRunConfiguration.CustomSignaturePath");
const char * const CUSTOM_KEY_PATH_KEY("Qt4ProjectManager.S60DeviceRunConfiguration.CustomKeyPath");
const char * const SERIAL_PORT_NAME_KEY("Qt4ProjectManager.S60DeviceRunConfiguration.SerialPortName");
const char * const COMMUNICATION_TYPE_KEY("Qt4ProjectManager.S60DeviceRunConfiguration.CommunicationType");
const char * const COMMAND_LINE_ARGUMENTS_KEY("Qt4ProjectManager.S60DeviceRunConfiguration.CommandLineArguments");
const int PROGRESS_PACKAGECREATED = 100;
const int PROGRESS_PACKAGESIGNED = 200;
const int PROGRESS_DEPLOYBASE = 200;
const int PROGRESS_PACKAGEDEPLOYED = 300;
const int PROGRESS_PACKAGEINSTALLED = 400;
const int PROGRESS_MAX = 400;
// Format information about a file
QString lsFile(const QString &f)
{
QString rc;
const QFileInfo fi(f);
QTextStream str(&rc);
str << fi.size() << ' ' << fi.lastModified().toString(Qt::ISODate) << ' ' << QDir::toNativeSeparators(fi.absoluteFilePath());
return rc;
}
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(Project *project, const QString &proFilePath) :
RunConfiguration(project, QLatin1String(S60_DEVICE_RC_ID)),
#ifdef Q_OS_WIN
m_serialPortName(QLatin1String("COM5")),

Friedemann Kleint
committed
m_communicationType(SymbianUtils::SerialPortCommunication),

Friedemann Kleint
committed
m_serialPortName(QLatin1String(SymbianUtils::SymbianDeviceManager::linuxBlueToothDeviceRootC) + QLatin1Char('0')),
m_communicationType(SymbianUtils::BlueToothCommunication),
{
ctor();
}
S60DeviceRunConfiguration::S60DeviceRunConfiguration(Project *project, S60DeviceRunConfiguration *source) :
RunConfiguration(project, source),
m_proFilePath(source->m_proFilePath),
m_cachedTargetInformationValid(false),
m_serialPortName(source->m_serialPortName),
m_communicationType(source->m_communicationType),
m_signingMode(source->m_signingMode),
m_customSignaturePath(source->m_customSignaturePath),
m_customKeyPath(source->m_customKeyPath)
{
ctor();
}
void S60DeviceRunConfiguration::proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
{
if (m_proFilePath == pro->path())
invalidateCachedTargetInformation();
}
void S60DeviceRunConfiguration::ctor()
setDisplayName(tr("%1 on Symbian Device").arg(QFileInfo(m_proFilePath).completeBaseName()));
setDisplayName(tr("QtS60DeviceRunConfiguration"));
connect(qt4Project(), SIGNAL(targetInformationChanged()),
this, SLOT(invalidateCachedTargetInformation()));
connect(qt4Project(), SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
this, SLOT(proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode*)));
S60DeviceRunConfiguration::~S60DeviceRunConfiguration()
{
}
Qt4Project *S60DeviceRunConfiguration::qt4Project() const
{
return static_cast<Qt4Project *>(project());
}
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 *>(project()->activeBuildConfiguration()))
return bc->toolChainType();
return ProjectExplorer::ToolChain::INVALID;
bool S60DeviceRunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *configuration) const
Qt4BuildConfiguration *qt4bc = static_cast<Qt4BuildConfiguration *>(configuration);
const ToolChain::ToolChainType type = qt4bc->toolChainType();
return type == ToolChain::GCCE || type == ToolChain::RVCT_ARMV5 || type == ToolChain::RVCT_ARMV6;
}
QWidget *S60DeviceRunConfiguration::configurationWidget()
{
return new S60DeviceRunConfigurationWidget(this);
}
QVariantMap S60DeviceRunConfiguration::toMap() const
QVariantMap map(ProjectExplorer::RunConfiguration::toMap());
const QDir projectDir = QFileInfo(project()->file()->fileName()).absoluteDir();
map.insert(QLatin1String(PRO_FILE_KEY), projectDir.relativeFilePath(m_proFilePath));
map.insert(QLatin1String(SIGNING_MODE_KEY), (int)m_signingMode);
map.insert(QLatin1String(CUSTOM_SIGNATURE_PATH_KEY), m_customSignaturePath);
map.insert(QLatin1String(CUSTOM_KEY_PATH_KEY), m_customKeyPath);
map.insert(QLatin1String(SERIAL_PORT_NAME_KEY), m_serialPortName);
map.insert(QLatin1String(COMMUNICATION_TYPE_KEY), m_communicationType);
map.insert(QLatin1String(COMMAND_LINE_ARGUMENTS_KEY), m_commandLineArguments);
return map;
bool S60DeviceRunConfiguration::fromMap(const QVariantMap &map)
const QDir projectDir = QFileInfo(qt4Project()->file()->fileName()).absoluteDir();
m_proFilePath = projectDir.filePath(map.value(QLatin1String(PRO_FILE_KEY)).toString());
m_signingMode = static_cast<SigningMode>(map.value(QLatin1String(SIGNING_MODE_KEY)).toInt());
m_customSignaturePath = map.value(QLatin1String(CUSTOM_SIGNATURE_PATH_KEY)).toString();
m_customKeyPath = map.value(QLatin1String(CUSTOM_KEY_PATH_KEY)).toString();
m_serialPortName = map.value(QLatin1String(SERIAL_PORT_NAME_KEY)).toString().trimmed();
m_communicationType = map.value(QLatin1String(COMMUNICATION_TYPE_KEY)).toInt();
m_commandLineArguments = map.value(QLatin1String(COMMAND_LINE_ARGUMENTS_KEY)).toStringList();
return RunConfiguration::fromMap(map);
}
QString S60DeviceRunConfiguration::serialPortName() const
{
return m_serialPortName;
}
void S60DeviceRunConfiguration::setSerialPortName(const QString &name)
{
m_serialPortName = name.trimmed();
int S60DeviceRunConfiguration::communicationType() const
{
return m_communicationType;
}
void S60DeviceRunConfiguration::setCommunicationType(int t)
{
m_communicationType = t;
}
QString S60DeviceRunConfiguration::targetName() const
{
const_cast<S60DeviceRunConfiguration *>(this)->updateTarget();
return m_targetName;
}
QString S60DeviceRunConfiguration::basePackageFilePath() const
{
const_cast<S60DeviceRunConfiguration *>(this)->updateTarget();
QString S60DeviceRunConfiguration::symbianPlatform() const
{
const_cast<S60DeviceRunConfiguration *>(this)->updateTarget();
return m_platform;
}
QString S60DeviceRunConfiguration::symbianTarget() const
{
const_cast<S60DeviceRunConfiguration *>(this)->updateTarget();
return m_target;
}
QString S60DeviceRunConfiguration::packageTemplateFileName() const
{
const_cast<S60DeviceRunConfiguration *>(this)->updateTarget();
return m_packageTemplateFileName;
}
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
S60DeviceRunConfiguration::SigningMode S60DeviceRunConfiguration::signingMode() const
{
return m_signingMode;
}
void S60DeviceRunConfiguration::setSigningMode(SigningMode mode)
{
m_signingMode = mode;
}
QString S60DeviceRunConfiguration::customSignaturePath() const
{
return m_customSignaturePath;
}
void S60DeviceRunConfiguration::setCustomSignaturePath(const QString &path)
{
m_customSignaturePath = path;
}
QString S60DeviceRunConfiguration::customKeyPath() const
{
return m_customKeyPath;
}
void S60DeviceRunConfiguration::setCustomKeyPath(const QString &path)
{
m_customKeyPath = path;
}
QString S60DeviceRunConfiguration::packageFileName() const
{
QString rc = basePackageFilePath();
if (!rc.isEmpty())
rc += QLatin1String(".pkg");
return rc;
}
QString S60DeviceRunConfiguration::localExecutableFileName() const
Qt4BuildConfiguration *qt4bc = qobject_cast<Qt4BuildConfiguration *>(project()->activeBuildConfiguration());
S60Devices::Device device = S60Manager::instance()->deviceForQtVersion(qt4bc->qtVersion());
QString localExecutable = device.epocRoot;
localExecutable += QString::fromLatin1("/epoc32/release/%1/%2/%3.exe")
.arg(symbianPlatform()).arg(symbianTarget()).arg(targetName());
qDebug() << localExecutable;
return QDir::toNativeSeparators(localExecutable);
QStringList S60DeviceRunConfiguration::commandLineArguments() const
{
return m_commandLineArguments;
}
void S60DeviceRunConfiguration::setCommandLineArguments(const QStringList &args)
{
m_commandLineArguments = args;
}
void S60DeviceRunConfiguration::updateTarget()
{
if (m_cachedTargetInformationValid)
return;
Qt4TargetInformation info = qt4Project()->targetInformation(qt4Project()->activeQt4BuildConfiguration(),
m_proFilePath);
if (info.error != Qt4TargetInformation::NoError) {
if (info.error == Qt4TargetInformation::ProParserError) {
Core::ICore::instance()->messageManager()->printToOutputPane(
tr("Could not parse %1. The QtS60 Device run configuration %2 can not be started.")
.arg(m_proFilePath).arg(displayName()));
m_targetName.clear();
m_baseFileName.clear();
m_packageTemplateFileName.clear();
m_platform.clear();
m_cachedTargetInformationValid = true;
emit targetInformationChanged();
return;
}
m_targetName = info.target;
m_baseFileName = info.workingDir + QLatin1Char('/') + m_targetName;
m_packageTemplateFileName = m_baseFileName + QLatin1String("_template.pkg");
Qt4BuildConfiguration *qt4bc = qt4Project()->activeQt4BuildConfiguration();
switch (qt4bc->toolChainType()) {
case ToolChain::GCCE:
case ToolChain::GCCE_GNUPOC:
m_platform = QLatin1String("gcce");
break;
case ToolChain::RVCT_ARMV5:
m_platform = QLatin1String("armv5");
break;
default: // including ToolChain::RVCT_ARMV6_GNUPOC:
m_platform = QLatin1String("armv6");
if (qt4bc->qmakeBuildConfiguration() & QtVersion::DebugBuild)
m_target = QLatin1String("udeb");
m_target = QLatin1String("urel");
m_baseFileName += QLatin1Char('_') + m_platform + QLatin1Char('_') + m_target;
m_cachedTargetInformationValid = true;
emit targetInformationChanged();
}
void S60DeviceRunConfiguration::invalidateCachedTargetInformation()
{
m_cachedTargetInformationValid = false;
emit targetInformationChanged();
}
// ======== S60DeviceRunConfigurationFactory
S60DeviceRunConfigurationFactory::S60DeviceRunConfigurationFactory(QObject *parent) :
IRunConfigurationFactory(parent)
{
}
S60DeviceRunConfigurationFactory::~S60DeviceRunConfigurationFactory()
{
}
QStringList S60DeviceRunConfigurationFactory::availableCreationIds(Project *parent) const
Qt4Project *qt4project = qobject_cast<Qt4Project *>(parent);
if (!qt4project)
return QStringList();
return 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(Project *parent, const QString &id) const
Qt4Project * project(qobject_cast<Qt4Project *>(parent));
if (!project)
return false;
return project->hasApplicationProFile(pathFromId(id));
RunConfiguration *S60DeviceRunConfigurationFactory::create(Project *parent, const QString &id)
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
if (!canCreate(parent, id))
return 0;
Qt4Project *project(static_cast<Qt4Project *>(parent));
return new S60DeviceRunConfiguration(project, pathFromId(id));
}
bool S60DeviceRunConfigurationFactory::canRestore(ProjectExplorer::Project *parent, const QVariantMap &map) const
{
if (!qobject_cast<Qt4Project *>(parent))
return false;
QString id(ProjectExplorer::idFromMap(map));
return id == QLatin1String(S60_DEVICE_RC_ID);
}
RunConfiguration *S60DeviceRunConfigurationFactory::restore(ProjectExplorer::Project *parent, const QVariantMap &map)
{
if (!canRestore(parent, map))
return 0;
Qt4Project *project(static_cast<Qt4Project *>(parent));
S60DeviceRunConfiguration *rc(new S60DeviceRunConfiguration(project, QString()));
if (rc->fromMap(map))
return rc;
delete rc;
return 0;
}
bool S60DeviceRunConfigurationFactory::canClone(ProjectExplorer::Project *parent, ProjectExplorer::RunConfiguration *source) const
{
if (!qobject_cast<Qt4Project *>(parent))
return false;
return source->id() == QLatin1String(S60_DEVICE_RC_ID);
}
RunConfiguration *S60DeviceRunConfigurationFactory::clone(ProjectExplorer::Project *parent, ProjectExplorer::RunConfiguration *source)
{
if (!canClone(parent, source))
return 0;
Qt4Project *project = static_cast<Qt4Project *>(parent);
S60DeviceRunConfiguration * old(static_cast<S60DeviceRunConfiguration *>(source));
return new S60DeviceRunConfiguration(project, old);
S60DeviceRunControlBase::S60DeviceRunControlBase(RunConfiguration *runConfiguration) :
m_toolChain(ProjectExplorer::ToolChain::INVALID),
{
// connect for automatically reporting the "finished deploy" state to the progress manager
connect(this, SIGNAL(finished()), this, SLOT(reportDeployFinished()));
connect(m_makesis, SIGNAL(readyReadStandardError()),
this, SLOT(readStandardError()));
connect(m_makesis, SIGNAL(readyReadStandardOutput()),
this, SLOT(readStandardOutput()));
connect(m_makesis, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(makesisProcessFailed()));
connect(m_makesis, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(makesisProcessFinished()));
S60DeviceRunConfiguration *s60runConfig = qobject_cast<S60DeviceRunConfiguration *>(runConfiguration);
Qt4BuildConfiguration *activeBuildConf = s60runConfig->qt4Project()->activeQt4BuildConfiguration();
QTC_ASSERT(s60runConfig, return);
m_toolChain = s60runConfig->toolChainType();
m_serialPortName = s60runConfig->serialPortName();

Friedemann Kleint
committed
m_serialPortFriendlyName = SymbianUtils::SymbianDeviceManager::instance()->friendlyNameForPort(m_serialPortName);
m_communicationType = s60runConfig->communicationType();
m_targetName = s60runConfig->targetName();
m_baseFileName = s60runConfig->basePackageFilePath();
m_commandLineArguments = s60runConfig->commandLineArguments();
m_symbianPlatform = s60runConfig->symbianPlatform();
m_symbianTarget = s60runConfig->symbianTarget();
m_packageTemplateFile = s60runConfig->packageTemplateFileName();
m_workingDirectory = QFileInfo(m_baseFileName).absolutePath();
m_qtDir = activeBuildConf->qtVersion()->versionInfo().value("QT_INSTALL_DATA");
m_useCustomSignature = (s60runConfig->signingMode() == S60DeviceRunConfiguration::SignCustom);
m_customSignaturePath = s60runConfig->customSignaturePath();
m_customKeyPath = s60runConfig->customKeyPath();
const S60Devices::Device device = S60Manager::instance()->deviceForQtVersion(activeBuildConf->qtVersion());
switch (m_toolChain) {
case ProjectExplorer::ToolChain::GCCE_GNUPOC:
case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC: {
// 'sis' is a make target here. Set up with correct environment
ProjectExplorer::ToolChain *toolchain = activeBuildConf->toolChain();
m_makesisTool = toolchain->makeCommand();
m_toolsDirectory = device.epocRoot + QLatin1String("/epoc32/tools");
ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
toolchain->addToEnvironment(env);
m_makesis->setEnvironment(env.toStringList());
}
break;
default:
m_toolsDirectory = device.toolsRoot + QLatin1String("/epoc32/tools");
m_makesisTool = m_toolsDirectory + "/makesis.exe";
// Set up signing packages
m_signsis = new QProcess(this);
connect(m_signsis, SIGNAL(readyReadStandardError()),
this, SLOT(readStandardError()));
connect(m_signsis, SIGNAL(readyReadStandardOutput()),
this, SLOT(readStandardOutput()));
connect(m_signsis, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(signsisProcessFailed()));
connect(m_signsis, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(signsisProcessFinished()));
break;
}
m_executableFileName = s60runConfig->localExecutableFileName();
m_packageFilePath = s60runConfig->packageFileName();
m_packageFile = QFileInfo(m_packageFilePath).fileName();
if (debug)
qDebug() << "S60DeviceRunControlBase" << m_targetName << ProjectExplorer::ToolChain::toolChainName(m_toolChain)
<< m_serialPortName << m_communicationType << m_workingDirectory;
S60DeviceRunControlBase::~S60DeviceRunControlBase()
{
if (m_launcher) {
m_launcher->deleteLater();
m_launcher = 0;
}
}
m_deployProgress = new QFutureInterface<void>;
Core::ICore::instance()->progressManager()->addTask(m_deployProgress->future(),
tr("Deploying"),
QLatin1String("Symbian.Deploy"));
m_deployProgress->setProgressRange(0, PROGRESS_MAX);
m_deployProgress->setProgressValue(0);
m_deployProgress->reportStarted();
if (m_serialPortName.isEmpty()) {
error(this, tr("There is no device plugged in."));
emit finished();
return;
}
emit addToOutputWindow(this, tr("Creating %1.sisx ...").arg(QDir::toNativeSeparators(m_baseFileName)));
emit addToOutputWindow(this, tr("Executable file: %1").arg(lsFile(m_executableFileName)));
QString errorMessage;
QString settingsCategory;
QString settingsPage;
if (!checkConfiguration(&errorMessage, &settingsCategory, &settingsPage)) {
error(this, errorMessage);
emit finished();
Core::ICore::instance()->showWarningWithOptions(tr("Debugger for Symbian Platform"),
errorMessage, QString(),
settingsCategory, settingsPage);
return;
}
QStringList makeSisArgs;
switch (m_toolChain) {
case ProjectExplorer::ToolChain::GCCE_GNUPOC:
case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC:
makeSisArgs.push_back(QLatin1String("sis"));
break;
default:
makeSisArgs.push_back(m_packageFile);
if (!createPackageFileFromTemplate(&errorMessage)) {
error(this, errorMessage);
emit finished();
return;
}
break;
m_makesis->setWorkingDirectory(m_workingDirectory);
emit addToOutputWindow(this, tr("%1 %2").arg(QDir::toNativeSeparators(m_makesisTool), m_packageFile));
if (debug)
qDebug() << m_makesisTool << makeSisArgs << m_workingDirectory;
m_makesis->start(m_makesisTool, makeSisArgs, QIODevice::ReadOnly);
static inline void stopProcess(QProcess *p)
{
const int timeOutMS = 200;
if (p->state() != QProcess::Running)
return;
p->terminate();
if (p->waitForFinished(timeOutMS))
return;
p->kill();
}
if (m_makesis)
stopProcess(m_makesis);
if (m_signsis)
stopProcess(m_signsis);
if (m_launcher)
m_launcher->terminate();
bool S60DeviceRunControlBase::isRunning() const
return m_makesis->state() != QProcess::NotRunning;
void S60DeviceRunControlBase::readStandardError()
QProcess *process = static_cast<QProcess *>(sender());
QByteArray data = process->readAllStandardError();
emit addToOutputWindowInline(this, QString::fromLocal8Bit(data.constData(), data.length()));
void S60DeviceRunControlBase::readStandardOutput()
QProcess *process = static_cast<QProcess *>(sender());
QByteArray data = process->readAllStandardOutput();
emit addToOutputWindowInline(this, QString::fromLocal8Bit(data.constData(), data.length()));
}
bool S60DeviceRunControlBase::createPackageFileFromTemplate(QString *errorMessage)
{
QFile packageTemplate(m_packageTemplateFile);
if (!packageTemplate.open(QIODevice::ReadOnly)) {
*errorMessage = tr("Could not read template package file '%1'").arg(QDir::toNativeSeparators(m_packageTemplateFile));
return false;
}
QString contents = packageTemplate.readAll();
packageTemplate.close();
contents.replace(QLatin1String("$(PLATFORM)"), m_symbianPlatform);
contents.replace(QLatin1String("$(TARGET)"), m_symbianTarget);
QFile packageFile(m_packageFilePath);
if (!packageFile.open(QIODevice::WriteOnly)) {
*errorMessage = tr("Could not write package file '%1'").arg(QDir::toNativeSeparators(m_packageFilePath));
return false;
}
packageFile.write(contents.toLocal8Bit());
packageFile.close();
return true;
}
void S60DeviceRunControlBase::makesisProcessFailed()
processFailed(m_makesisTool, m_makesis->error());
void S60DeviceRunControlBase::makesisProcessFinished()
if (m_makesis->exitCode() != 0) {
error(this, tr("An error occurred while creating the package."));
m_deployProgress->setProgressValue(PROGRESS_PACKAGECREATED);
switch (m_toolChain) {
case ProjectExplorer::ToolChain::GCCE_GNUPOC:
case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC:
startDeployment();
break;
default:
startSigning();
break;
}
}
void S60DeviceRunControlBase::startSigning()
{
QString signsisTool = m_toolsDirectory + QLatin1String("/signsis.exe");
QString sisFile = QFileInfo(m_baseFileName + QLatin1String(".sis")).fileName();
QString sisxFile = QFileInfo(m_baseFileName + QLatin1String(".sisx")).fileName();
QString signature = (m_useCustomSignature ? m_customSignaturePath
: m_qtDir + QLatin1String("/src/s60installs/selfsigned.cer"));
: m_qtDir + QLatin1String("/src/s60installs/selfsigned.key"));
<< sisxFile << QDir::toNativeSeparators(signature)
<< QDir::toNativeSeparators(key);
m_signsis->setWorkingDirectory(m_workingDirectory);
emit addToOutputWindow(this, tr("%1 %2").arg(QDir::toNativeSeparators(signsisTool), arguments.join(QString(QLatin1Char(' ')))));
m_signsis->start(signsisTool, arguments, QIODevice::ReadOnly);
}
void S60DeviceRunControlBase::signsisProcessFailed()
{
processFailed("signsis.exe", m_signsis->error());
}
void S60DeviceRunControlBase::signsisProcessFinished()
if (m_signsis->exitCode() != 0) {
error(this, tr("An error occurred while creating the package."));
m_deployProgress->setProgressValue(PROGRESS_PACKAGESIGNED);
}
void S60DeviceRunControlBase::startDeployment()
{
m_launcher = new trk::Launcher();
connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished()));
connect(m_launcher, SIGNAL(canNotConnect(QString)), this, SLOT(printConnectFailed(QString)));
connect(m_launcher, SIGNAL(copyingStarted()), this, SLOT(printCopyingNotice()));
connect(m_launcher, SIGNAL(canNotCreateFile(QString,QString)), this, SLOT(printCreateFileFailed(QString,QString)));
connect(m_launcher, SIGNAL(canNotWriteFile(QString,QString)), this, SLOT(printWriteFileFailed(QString,QString)));
connect(m_launcher, SIGNAL(canNotCloseFile(QString,QString)), this, SLOT(printCloseFileFailed(QString,QString)));
connect(m_launcher, SIGNAL(installingStarted()), this, SLOT(printInstallingNotice()));
connect(m_launcher, SIGNAL(canNotInstall(QString,QString)), this, SLOT(printInstallFailed(QString,QString)));
connect(m_launcher, SIGNAL(installingFinished()), this, SLOT(printInstallingFinished()));
connect(m_launcher, SIGNAL(copyProgress(int)), this, SLOT(printCopyProgress(int)));
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)));
m_launcher->setTrkServerName(m_serialPortName);

Friedemann Kleint
committed
m_launcher->setSerialFrame(m_communicationType == SymbianUtils::SerialPortCommunication);
if (!m_commandLineArguments.isEmpty())
m_launcher->setCommandLineArgs(m_commandLineArguments);
const QString copySrc(m_baseFileName + ".sisx");
const QString copyDst = QString("C:\\Data\\%1.sisx").arg(QFileInfo(m_baseFileName).fileName());
const QString runFileName = QString("C:\\sys\\bin\\%1.exe").arg(m_targetName);
m_launcher->setCopyFileName(copySrc, copyDst);
m_launcher->setInstallFileName(copyDst);
initLauncher(runFileName, m_launcher);
emit addToOutputWindow(this, tr("Package: %1\nDeploying application to '%2'...").arg(lsFile(copySrc), m_serialPortFriendlyName));
QString errorMessage;
// Prompt the user to start up the Blue tooth connection
const trk::PromptStartCommunicationResult src =
S60RunConfigBluetoothStarter::startCommunication(m_launcher->trkDevice(),
m_communicationType, 0,
&errorMessage);
switch (src) {
case trk::PromptStartCommunicationConnected:
break;
case trk::PromptStartCommunicationCanceled:
case trk::PromptStartCommunicationError:
error(this, errorMessage);
emit finished();
return;
};
if (!m_launcher->startServer(&errorMessage)) {
error(this, 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));
void S60DeviceRunControlBase::printCreateFileFailed(const QString &filename, const QString &errorMessage)
emit addToOutputWindow(this, tr("Could not create file %1 on device: %2").arg(filename, errorMessage));
void S60DeviceRunControlBase::printWriteFileFailed(const QString &filename, const QString &errorMessage)
{
emit addToOutputWindow(this, tr("Could not write to file %1 on device: %2").arg(filename, errorMessage));
}
void S60DeviceRunControlBase::printCloseFileFailed(const QString &filename, const QString &errorMessage)
{
const QString msg = tr("Could not close file %1 on device: %2. It will be closed when App TRK is closed.");
emit addToOutputWindow(this, msg.arg(filename, errorMessage));
}
void S60DeviceRunControlBase::printConnectFailed(const QString &errorMessage)
{
emit addToOutputWindow(this, tr("Could not connect to App TRK on device: %1. Restarting App TRK might help.").arg(errorMessage));
}
void S60DeviceRunControlBase::printCopyingNotice()
emit addToOutputWindow(this, tr("Copying install file..."));
void S60DeviceRunControlBase::printCopyProgress(int progress)
m_deployProgress->setProgressValue(PROGRESS_DEPLOYBASE + progress);
void S60DeviceRunControlBase::printInstallingNotice()
m_deployProgress->setProgressValue(PROGRESS_PACKAGEDEPLOYED);
emit addToOutputWindow(this, tr("Installing application..."));
}
void S60DeviceRunControlBase::printInstallingFinished()
{
m_deployProgress->setProgressValue(PROGRESS_PACKAGEINSTALLED);
m_deployProgress->reportFinished();
delete m_deployProgress;
m_deployProgress = 0;
}
void S60DeviceRunControlBase::printInstallFailed(const QString &filename, const QString &errorMessage)
{
emit addToOutputWindow(this, tr("Could not install from package %1 on device: %2").arg(filename, errorMessage));
}
void S60DeviceRunControlBase::launcherFinished()
{
m_launcher->deleteLater();
m_launcher = 0;
handleLauncherFinished();
}
void S60DeviceRunControlBase::reportDeployFinished()
{
if (m_deployProgress) {
m_deployProgress->reportFinished();
delete m_deployProgress;
m_deployProgress = 0;
}
}
void S60DeviceRunControlBase::processStopped(uint pc, uint pid, uint tid, const QString& reason)
{
emit addToOutputWindow(this, trk::Launcher::msgStopped(pid, tid, pc, reason));
m_launcher->terminate();
}
QMessageBox *S60DeviceRunControlBase::createTrkWaitingMessageBox(const QString &port, QWidget *parent)
{
const QString title = QCoreApplication::translate("Qt4ProjectManager::Internal::S60DeviceRunControlBase",
const QString text = QCoreApplication::translate("Qt4ProjectManager::Internal::S60DeviceRunControlBase",
QMessageBox *rc = new QMessageBox(QMessageBox::Information, title, text,
QMessageBox::Cancel, parent);
return rc;
}
void S60DeviceRunControlBase::slotLauncherStateChanged(int s)
{
if (s == trk::Launcher::WaitingForTrk) {
QMessageBox *mb = S60DeviceRunControlBase::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();
}
}
void S60DeviceRunControlBase::slotWaitingForTrkClosed()
{
if (m_launcher && m_launcher->state() == trk::Launcher::WaitingForTrk) {
stop();
emit finished();
}
}
void S60DeviceRunControlBase::processFailed(const QString &program, QProcess::ProcessError errorCode)
{
QString errorString;
switch (errorCode) {
case QProcess::FailedToStart:
errorString = tr("Failed to start %1.");
break;
case QProcess::Crashed:
errorString = tr("%1 has unexpectedly finished.");
break;
default:
errorString = tr("An error has occurred while running %1.");
}
error(this, errorString.arg(program));
void S60DeviceRunControlBase::printApplicationOutput(const QString &output)
{
emit addToOutputWindowInline(this, output);
}
bool S60DeviceRunControlBase::checkConfiguration(QString * /* errorMessage */,
QString * /* settingsCategory */,
QString * /* settingsPage */) const
{
return true;
}
// =============== S60DeviceRunControl
S60DeviceRunControl::S60DeviceRunControl(ProjectExplorer::RunConfiguration *runConfiguration) :
S60DeviceRunControlBase(runConfiguration)
{
}
void S60DeviceRunControl::initLauncher(const QString &executable, trk::Launcher *launcher)
{
connect(launcher, SIGNAL(startingApplication()), this, SLOT(printStartingNotice()));
connect(launcher, SIGNAL(applicationRunning(uint)), this, SLOT(printRunNotice(uint)));
connect(launcher, SIGNAL(canNotRun(QString)), this, SLOT(printRunFailNotice(QString)));
connect(launcher, SIGNAL(applicationOutputReceived(QString)), this, SLOT(printApplicationOutput(QString)));
launcher->addStartupActions(trk::Launcher::ActionCopyInstallRun);
launcher->setFileName(executable);
}
void S60DeviceRunControl::handleLauncherFinished()
{
emit finished();
emit addToOutputWindow(this, tr("Finished."));
}
void S60DeviceRunControl::printStartingNotice()
{
emit addToOutputWindow(this, tr("Starting application..."));
}
void S60DeviceRunControl::printRunNotice(uint pid)
{
emit addToOutputWindow(this, tr("Application running with pid %1.").arg(pid));
void S60DeviceRunControl::printRunFailNotice(const QString &errorMessage) {
emit addToOutputWindow(this, tr("Could not start application: %1").arg(errorMessage));
}
// ======== S60DeviceDebugRunControl
S60DeviceDebugRunControl::S60DeviceDebugRunControl(S60DeviceRunConfiguration *runConfiguration) :
S60DeviceRunControlBase(runConfiguration),
m_startParams(new Debugger::DebuggerStartParameters)
Debugger::DebuggerManager *dm = Debugger::DebuggerManager::instance();
S60DeviceRunConfiguration *rc = qobject_cast<S60DeviceRunConfiguration *>(runConfiguration);
QTC_ASSERT(dm && rc, return);
connect(dm, SIGNAL(debuggingFinished()),
this, SLOT(debuggingFinished()), Qt::QueuedConnection);
connect(dm, SIGNAL(applicationOutputAvailable(QString)),
Qt::QueuedConnection);
m_startParams->remoteChannel = rc->serialPortName();
m_startParams->processArgs = rc->commandLineArguments();
m_startParams->remoteChannelType = rc->communicationType();
m_startParams->startMode = Debugger::StartInternal;
m_startParams->toolChainType = rc->toolChainType();
m_localExecutableFileName = rc->localExecutableFileName();
const int lastDotPos = m_localExecutableFileName.lastIndexOf(QLatin1Char('.'));
if (lastDotPos != -1) {
m_startParams->symbolFileName = m_localExecutableFileName.mid(0, lastDotPos) + QLatin1String(".sym");
}
S60DeviceRunControlBase::stop();
Debugger::DebuggerManager *dm = Debugger::DebuggerManager::instance();
QTC_ASSERT(dm, return)
if (dm->state() == Debugger::DebuggerNotReady)
dm->exitDebugger();
}
S60DeviceDebugRunControl::~S60DeviceDebugRunControl()
{
}
void S60DeviceDebugRunControl::initLauncher(const QString &executable, trk::Launcher *launcher)