1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
31 **************************************************************************/
33 #include "s60deployconfiguration.h"
34 #include "s60deployconfigurationwidget.h"
35 #include "s60manager.h"
36 #include "qt4project.h"
37 #include "qt4target.h"
38 #include "qt4projectmanagerconstants.h"
39 #include "qt4buildconfiguration.h"
40 #include "qt4symbiantarget.h"
41 #include "s60createpackagestep.h"
42 #include "s60deploystep.h"
44 #include <utils/qtcassert.h>
45 #include <symbianutils/symbiandevicemanager.h>
47 #include <projectexplorer/buildconfiguration.h>
48 #include <projectexplorer/buildsteplist.h>
49 #include <projectexplorer/project.h>
50 #include <projectexplorer/toolchain.h>
52 #include <QtCore/QFileInfo>
54 using namespace ProjectExplorer;
55 using namespace Qt4ProjectManager;
56 using namespace Qt4ProjectManager::Internal;
59 const char * const S60_DC_ID("Qt4ProjectManager.S60DeployConfiguration");
60 const char * const S60_DC_PREFIX("Qt4ProjectManager.S60DeployConfiguration.");
62 const char * const SERIAL_PORT_NAME_KEY("Qt4ProjectManager.S60DeployConfiguration.SerialPortName");
63 const char * const INSTALLATION_DRIVE_LETTER_KEY("Qt4ProjectManager.S60DeployConfiguration.InstallationDriveLetter");
64 const char * const SILENT_INSTALL_KEY("Qt4ProjectManager.S60DeployConfiguration.SilentInstall");
65 const char * const DEVICE_ADDRESS_KEY("Qt4ProjectManager.S60DeployConfiguration.DeviceAddress");
66 const char * const DEVICE_PORT_KEY("Qt4ProjectManager.S60DeployConfiguration.DevicePort");
67 const char * const COMMUNICATION_CHANNEL_KEY("Qt4ProjectManager.S60DeployConfiguration.CommunicationChannel");
69 const char * const DEFAULT_TCF_TRK_TCP_PORT("65029");
71 QString pathFromId(const QString &id)
73 if (!id.startsWith(QLatin1String(S60_DC_PREFIX)))
75 return id.mid(QString::fromLatin1(S60_DC_PREFIX).size());
78 QString pathToId(const QString &path)
80 return QString::fromLatin1(S60_DC_PREFIX) + path;
84 // ======== S60DeployConfiguration
86 S60DeployConfiguration::S60DeployConfiguration(Target *parent) :
87 DeployConfiguration(parent, QLatin1String(S60_DC_ID)),
88 m_activeBuildConfiguration(0),
90 m_serialPortName(QLatin1String("COM5")),
92 m_serialPortName(QLatin1String(SymbianUtils::SymbianDeviceManager::linuxBlueToothDeviceRootC) + QLatin1Char('0')),
94 m_installationDrive('C'),
95 m_silentInstall(true),
96 m_devicePort(QLatin1String(DEFAULT_TCF_TRK_TCP_PORT)),
97 m_communicationChannel(CommunicationTrkSerialConnection)
102 S60DeployConfiguration::S60DeployConfiguration(Target *target, S60DeployConfiguration *source) :
103 DeployConfiguration(target, source),
104 m_activeBuildConfiguration(0),
105 m_serialPortName(source->m_serialPortName),
106 m_installationDrive(source->m_installationDrive),
107 m_silentInstall(source->m_silentInstall),
108 m_deviceAddress(source->m_deviceAddress),
109 m_devicePort(source->m_devicePort),
110 m_communicationChannel(source->m_communicationChannel)
115 void S60DeployConfiguration::ctor()
117 setDefaultDisplayName(defaultDisplayName());
118 // TODO disable S60 Deploy Configuration while parsing
119 // requires keeping track of the parsing state of the project
120 // connect(qt4Target()->qt4Project(), SIGNAL(proFileInvalidated(Qt4ProjectManager::Internal::Qt4ProFileNode*)),
121 // this, SLOT(targetInformationInvalidated()));
122 connect(qt4Target()->qt4Project(), SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode*,bool)),
123 this, SIGNAL(targetInformationChanged()));
124 connect(qt4Target(), SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
125 this, SLOT(updateActiveBuildConfiguration(ProjectExplorer::BuildConfiguration*)));
126 connect(qt4Target(), SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
127 this, SLOT(updateActiveRunConfiguration(ProjectExplorer::RunConfiguration*)));
128 updateActiveBuildConfiguration(qt4Target()->activeBuildConfiguration());
131 S60DeployConfiguration::~S60DeployConfiguration()
135 ProjectExplorer::DeployConfigurationWidget *S60DeployConfiguration::configurationWidget() const
137 return new S60DeployConfigurationWidget();
140 bool S60DeployConfiguration::isStaticLibrary(const Qt4ProFileNode &projectNode) const
142 if (projectNode.projectType() == LibraryTemplate) {
143 const QStringList &config(projectNode.variableValue(ConfigVar));
144 if (config.contains(QLatin1String("static")) || config.contains(QLatin1String("staticlib")))
150 bool S60DeployConfiguration::isApplication(const Qt4ProFileNode &projectNode) const
152 return projectNode.projectType() == ApplicationTemplate;
155 bool S60DeployConfiguration::isDeployable(const Qt4ProFileNode &projectNode) const
157 const QStringList &deployment(projectNode.variableValue(Deployment));
158 // default_*deployment are default for DEPLOYMENT
159 const char * defaultDeploymentStart = "default_";
160 const char * defaultDeploymentEnd = "deployment";
162 //we need to filter out the default_*deployment
163 for (int i = deployment.count() - 1; i >= 0; --i) {
164 const QString var = deployment.at(i);
165 if (!var.startsWith(QLatin1String(defaultDeploymentStart))
166 || !var.endsWith(QLatin1String(defaultDeploymentEnd)))
172 bool S60DeployConfiguration::hasSisPackage(const Qt4ProFileNode &projectNode) const
174 return isDeployable(projectNode) || isApplication(projectNode);
177 QStringList S60DeployConfiguration::signedPackages() const
179 QList<Qt4ProFileNode *> list = qt4Target()->qt4Project()->allProFiles();
181 foreach (Qt4ProFileNode *node, list) {
182 if (!hasSisPackage(*node))
184 TargetInformation ti = node->targetInformation();
186 result << ti.buildDir + QLatin1Char('/') + createPackageName(ti.target);
191 QString S60DeployConfiguration::createPackageName(const QString &baseName) const
193 QString name(baseName);
194 name += isSigned() ? QLatin1String("") : QLatin1String("_unsigned");
195 name += runSmartInstaller() ? QLatin1String("_installer") : QLatin1String("");
196 name += QLatin1String(".sis");
200 QStringList S60DeployConfiguration::packageFileNamesWithTargetInfo() const
202 QList<Qt4ProFileNode *> leafs = qt4Target()->qt4Project()->allProFiles();
204 foreach (Qt4ProFileNode *qt4ProFileNode, leafs) {
205 if (!hasSisPackage(*qt4ProFileNode))
207 TargetInformation ti = qt4ProFileNode->targetInformation();
210 QString baseFileName = ti.buildDir + QLatin1Char('/') + ti.target;
211 baseFileName += QLatin1Char('_')
212 + (isDebug() ? QLatin1String("debug") : QLatin1String("release"))
213 + QLatin1Char('-') + S60Manager::platform(qt4Target()->activeBuildConfiguration()->toolChain()) + QLatin1String(".sis");
214 result << baseFileName;
219 QStringList S60DeployConfiguration::packageTemplateFileNames() const
221 QList<Qt4ProFileNode *> list = qt4Target()->qt4Project()->allProFiles();
223 foreach (Qt4ProFileNode *node, list) {
224 if (!hasSisPackage(*node))
226 TargetInformation ti = node->targetInformation();
228 result << ti.buildDir + QLatin1Char('/') + ti.target + QLatin1String("_template.pkg");
233 QStringList S60DeployConfiguration::appPackageTemplateFileNames() const
235 QList<Qt4ProFileNode *> list = qt4Target()->qt4Project()->allProFiles();
237 foreach (Qt4ProFileNode *node, list) {
238 if (!hasSisPackage(*node))
240 TargetInformation ti = node->targetInformation();
242 result << ti.buildDir + QLatin1Char('/') + ti.target + QLatin1String("_template.pkg");
247 bool S60DeployConfiguration::runSmartInstaller() const
249 DeployConfiguration *dc = target()->activeDeployConfiguration();
250 QTC_ASSERT(dc, return false);
251 BuildStepList *bsl = dc->stepList();
252 QTC_ASSERT(bsl, return false);
253 QList<BuildStep *> steps = bsl->steps();
254 foreach (const BuildStep *step, steps) {
255 if (const S60CreatePackageStep *packageStep = qobject_cast<const S60CreatePackageStep *>(step)) {
256 return packageStep->createsSmartInstaller();
262 bool S60DeployConfiguration::isSigned() const
264 DeployConfiguration *dc = target()->activeDeployConfiguration();
265 QTC_ASSERT(dc, return false);
266 BuildStepList *bsl = dc->stepList();
267 QTC_ASSERT(bsl, return false);
268 QList<BuildStep *> steps = bsl->steps();
269 foreach (const BuildStep *step, steps) {
270 if (const S60CreatePackageStep *packageStep = qobject_cast<const S60CreatePackageStep *>(step)) {
271 return packageStep->signingMode() != S60CreatePackageStep::NotSigned;
277 ProjectExplorer::ToolChain *S60DeployConfiguration::toolChain() const
279 if (Qt4BuildConfiguration *bc = qobject_cast<Qt4BuildConfiguration *>(target()->activeBuildConfiguration()))
280 return bc->toolChain();
284 bool S60DeployConfiguration::isDebug() const
286 const Qt4BuildConfiguration *qt4bc = qt4Target()->activeBuildConfiguration();
287 return (qt4bc->qmakeBuildConfiguration() & QtVersion::DebugBuild);
290 QString S60DeployConfiguration::symbianTarget() const
292 return isDebug() ? QLatin1String("udeb") : QLatin1String("urel");
295 const QtVersion *S60DeployConfiguration::qtVersion() const
297 if (const Qt4BuildConfiguration *qt4bc = qt4Target()->activeBuildConfiguration())
298 return qt4bc->qtVersion();
302 void S60DeployConfiguration::updateActiveBuildConfiguration(ProjectExplorer::BuildConfiguration *buildConfiguration)
304 if (m_activeBuildConfiguration)
305 disconnect(m_activeBuildConfiguration, SIGNAL(s60CreatesSmartInstallerChanged()),
306 this, SIGNAL(targetInformationChanged()));
307 m_activeBuildConfiguration = buildConfiguration;
308 if (m_activeBuildConfiguration)
309 connect(m_activeBuildConfiguration, SIGNAL(s60CreatesSmartInstallerChanged()),
310 this, SIGNAL(targetInformationChanged()));
313 void S60DeployConfiguration::updateActiveRunConfiguration(ProjectExplorer::RunConfiguration *runConfiguration)
315 Q_UNUSED(runConfiguration);
316 setDefaultDisplayName(defaultDisplayName());
319 QVariantMap S60DeployConfiguration::toMap() const
321 QVariantMap map(ProjectExplorer::DeployConfiguration::toMap());
322 map.insert(QLatin1String(SERIAL_PORT_NAME_KEY), m_serialPortName);
323 map.insert(QLatin1String(INSTALLATION_DRIVE_LETTER_KEY), QChar(m_installationDrive));
324 map.insert(QLatin1String(SILENT_INSTALL_KEY), QVariant(m_silentInstall));
325 map.insert(QLatin1String(DEVICE_ADDRESS_KEY), QVariant(m_deviceAddress));
326 map.insert(QLatin1String(DEVICE_PORT_KEY), m_devicePort);
327 map.insert(QLatin1String(COMMUNICATION_CHANNEL_KEY), QVariant(m_communicationChannel));
332 QString S60DeployConfiguration::defaultDisplayName() const
334 QList<Qt4ProFileNode *> list = qt4Target()->qt4Project()->allProFiles();
335 foreach (Qt4ProFileNode *node, list) {
336 TargetInformation ti = node->targetInformation();
337 if (ti.valid && !ti.buildDir.isEmpty())
338 return tr("Deploy %1 to Symbian device").arg(QFileInfo(ti.buildDir).completeBaseName());
340 return tr("Deploy to Symbian device");
343 bool S60DeployConfiguration::fromMap(const QVariantMap &map)
345 if (!DeployConfiguration::fromMap(map))
347 m_serialPortName = map.value(QLatin1String(SERIAL_PORT_NAME_KEY)).toString().trimmed();
348 m_installationDrive = map.value(QLatin1String(INSTALLATION_DRIVE_LETTER_KEY), QChar('C'))
350 m_silentInstall = map.value(QLatin1String(SILENT_INSTALL_KEY), QVariant(true)).toBool();
351 m_deviceAddress = map.value(QLatin1String(DEVICE_ADDRESS_KEY)).toString();
352 m_devicePort = map.value(QLatin1String(DEVICE_PORT_KEY), QString(QLatin1String(DEFAULT_TCF_TRK_TCP_PORT))).toString();
353 m_communicationChannel = static_cast<CommunicationChannel>(map.value(QLatin1String(COMMUNICATION_CHANNEL_KEY),
354 QVariant(CommunicationTrkSerialConnection)).toInt());
356 setDefaultDisplayName(defaultDisplayName());
360 Qt4SymbianTarget *S60DeployConfiguration::qt4Target() const
362 return static_cast<Qt4SymbianTarget *>(target());
365 QString S60DeployConfiguration::serialPortName() const
367 return m_serialPortName;
370 void S60DeployConfiguration::setSerialPortName(const QString &name)
372 const QString &candidate = name.trimmed();
373 if (m_serialPortName == candidate)
375 m_serialPortName = candidate;
376 emit serialPortNameChanged();
379 char S60DeployConfiguration::installationDrive() const
381 return m_installationDrive;
384 void S60DeployConfiguration::setInstallationDrive(char drive)
386 if (m_installationDrive == drive)
388 m_installationDrive = drive;
389 emit installationDriveChanged();
392 bool S60DeployConfiguration::silentInstall() const
394 return m_silentInstall;
397 void S60DeployConfiguration::setSilentInstall(bool silent)
399 m_silentInstall = silent;
402 QString S60DeployConfiguration::deviceAddress() const
404 return m_deviceAddress;
407 void S60DeployConfiguration::setDeviceAddress(const QString &address)
409 if (m_deviceAddress != address) {
410 m_deviceAddress = address;
411 emit deviceAddressChanged();
415 QString S60DeployConfiguration::devicePort() const
420 void S60DeployConfiguration::setDevicePort(const QString &port)
422 if (m_devicePort != port) {
423 if (port.isEmpty()) //setup the default CODA's port
424 m_devicePort = QLatin1String(DEFAULT_TCF_TRK_TCP_PORT);
427 emit devicePortChanged();
431 S60DeployConfiguration::CommunicationChannel S60DeployConfiguration::communicationChannel() const
433 return m_communicationChannel;
436 void S60DeployConfiguration::setCommunicationChannel(CommunicationChannel channel)
438 if (m_communicationChannel != channel) {
439 m_communicationChannel = channel;
440 emit communicationChannelChanged();
444 void S60DeployConfiguration::setAvailableDeviceDrives(QList<DeviceDrive> drives)
446 m_availableDeviceDrives = drives;
447 emit availableDeviceDrivesChanged();
450 const QList<S60DeployConfiguration::DeviceDrive> &S60DeployConfiguration::availableDeviceDrives() const
452 return m_availableDeviceDrives;
455 // ======== S60DeployConfigurationFactory
457 S60DeployConfigurationFactory::S60DeployConfigurationFactory(QObject *parent) :
458 DeployConfigurationFactory(parent)
462 S60DeployConfigurationFactory::~S60DeployConfigurationFactory()
466 QStringList S60DeployConfigurationFactory::availableCreationIds(Target *parent) const
468 Qt4SymbianTarget *target = qobject_cast<Qt4SymbianTarget *>(parent);
470 target->id() != QLatin1String(Constants::S60_DEVICE_TARGET_ID))
471 return QStringList();
473 return target->qt4Project()->applicationProFilePathes(QLatin1String(S60_DC_PREFIX));
476 QString S60DeployConfigurationFactory::displayNameForId(const QString &id) const
478 if (!pathFromId(id).isEmpty())
479 return tr("%1 on Symbian Device").arg(QFileInfo(pathFromId(id)).completeBaseName());
483 DeployConfiguration *S60DeployConfigurationFactory::create(Target *parent, const QString &id)
485 if (!canCreate(parent, id))
488 Qt4SymbianTarget *t = static_cast<Qt4SymbianTarget *>(parent);
489 S60DeployConfiguration *dc = new S60DeployConfiguration(t);
491 dc->setDefaultDisplayName(tr("Deploy to Symbian device"));
492 dc->stepList()->insertStep(0, new S60CreatePackageStep(dc->stepList()));
493 dc->stepList()->insertStep(1, new S60DeployStep(dc->stepList()));
497 bool S60DeployConfigurationFactory::canCreate(Target *parent, const QString& /*id*/) const
499 Qt4SymbianTarget * t = qobject_cast<Qt4SymbianTarget *>(parent);
500 if (!t || t->id() != QLatin1String(Constants::S60_DEVICE_TARGET_ID))
505 bool S60DeployConfigurationFactory::canRestore(Target *parent, const QVariantMap& /*map*/) const
507 Qt4SymbianTarget * t = qobject_cast<Qt4SymbianTarget *>(parent);
508 return t && t->id() == QLatin1String(Constants::S60_DEVICE_TARGET_ID);
511 DeployConfiguration *S60DeployConfigurationFactory::restore(Target *parent, const QVariantMap &map)
513 if (!canRestore(parent, map))
515 Qt4SymbianTarget *t = static_cast<Qt4SymbianTarget *>(parent);
516 S60DeployConfiguration *dc = new S60DeployConfiguration(t);
517 if (dc->fromMap(map))
524 bool S60DeployConfigurationFactory::canClone(Target *parent, DeployConfiguration *source) const
526 if (!qobject_cast<Qt4SymbianTarget *>(parent))
528 return source->id() == QLatin1String(S60_DC_ID);
531 DeployConfiguration *S60DeployConfigurationFactory::clone(Target *parent, DeployConfiguration *source)
533 if (!canClone(parent, source))
535 Qt4SymbianTarget *t = static_cast<Qt4SymbianTarget *>(parent);
536 S60DeployConfiguration * old = static_cast<S60DeployConfiguration *>(source);
537 return new S60DeployConfiguration(t, old);