OSDN Git Service

Update license.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / qt4projectmanager / qt-s60 / s60deployconfiguration.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
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.
18 **
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.
22 **
23 ** Other Usage
24 **
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.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **************************************************************************/
32
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"
43
44 #include <utils/qtcassert.h>
45 #include <symbianutils/symbiandevicemanager.h>
46
47 #include <projectexplorer/buildconfiguration.h>
48 #include <projectexplorer/buildsteplist.h>
49 #include <projectexplorer/project.h>
50 #include <projectexplorer/toolchain.h>
51
52 #include <QtCore/QFileInfo>
53
54 using namespace ProjectExplorer;
55 using namespace Qt4ProjectManager;
56 using namespace Qt4ProjectManager::Internal;
57
58 namespace {
59 const char * const S60_DC_ID("Qt4ProjectManager.S60DeployConfiguration");
60 const char * const S60_DC_PREFIX("Qt4ProjectManager.S60DeployConfiguration.");
61
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");
68
69 const char * const DEFAULT_TCF_TRK_TCP_PORT("65029");
70
71 QString pathFromId(const QString &id)
72 {
73     if (!id.startsWith(QLatin1String(S60_DC_PREFIX)))
74         return QString();
75     return id.mid(QString::fromLatin1(S60_DC_PREFIX).size());
76 }
77
78 QString pathToId(const QString &path)
79 {
80     return QString::fromLatin1(S60_DC_PREFIX) + path;
81 }
82 }
83
84 // ======== S60DeployConfiguration
85
86 S60DeployConfiguration::S60DeployConfiguration(Target *parent) :
87     DeployConfiguration(parent,  QLatin1String(S60_DC_ID)),
88     m_activeBuildConfiguration(0),
89 #ifdef Q_OS_WIN
90     m_serialPortName(QLatin1String("COM5")),
91 #else
92     m_serialPortName(QLatin1String(SymbianUtils::SymbianDeviceManager::linuxBlueToothDeviceRootC) + QLatin1Char('0')),
93 #endif
94     m_installationDrive('C'),
95     m_silentInstall(true),
96     m_devicePort(QLatin1String(DEFAULT_TCF_TRK_TCP_PORT)),
97     m_communicationChannel(CommunicationTrkSerialConnection)
98 {
99     ctor();
100 }
101
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)
111 {
112     ctor();
113 }
114
115 void S60DeployConfiguration::ctor()
116 {
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());
129 }
130
131 S60DeployConfiguration::~S60DeployConfiguration()
132 {
133 }
134
135 ProjectExplorer::DeployConfigurationWidget *S60DeployConfiguration::configurationWidget() const
136 {
137     return new S60DeployConfigurationWidget();
138 }
139
140 bool S60DeployConfiguration::isStaticLibrary(const Qt4ProFileNode &projectNode) const
141 {
142     if (projectNode.projectType() == LibraryTemplate) {
143         const QStringList &config(projectNode.variableValue(ConfigVar));
144         if (config.contains(QLatin1String("static")) || config.contains(QLatin1String("staticlib")))
145             return true;
146     }
147     return false;
148 }
149
150 bool S60DeployConfiguration::isApplication(const Qt4ProFileNode &projectNode) const
151 {
152     return projectNode.projectType() == ApplicationTemplate;
153 }
154
155 bool S60DeployConfiguration::isDeployable(const Qt4ProFileNode &projectNode) const
156 {
157     const QStringList &deployment(projectNode.variableValue(Deployment));
158     // default_*deployment are default for DEPLOYMENT
159     const char * defaultDeploymentStart = "default_";
160     const char * defaultDeploymentEnd = "deployment";
161
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)))
167             return true;
168     }
169     return false;
170 }
171
172 bool S60DeployConfiguration::hasSisPackage(const Qt4ProFileNode &projectNode) const
173 {
174     return isDeployable(projectNode) || isApplication(projectNode);
175 }
176
177 QStringList S60DeployConfiguration::signedPackages() const
178 {
179     QList<Qt4ProFileNode *> list = qt4Target()->qt4Project()->allProFiles();
180     QStringList result;
181     foreach (Qt4ProFileNode *node, list) {
182         if (!hasSisPackage(*node))
183             continue;
184         TargetInformation ti = node->targetInformation();
185         if (ti.valid)
186             result << ti.buildDir + QLatin1Char('/') + createPackageName(ti.target);
187     }
188     return result;
189 }
190
191 QString S60DeployConfiguration::createPackageName(const QString &baseName) const
192 {
193     QString name(baseName);
194     name += isSigned() ? QLatin1String("") : QLatin1String("_unsigned");
195     name += runSmartInstaller() ? QLatin1String("_installer") : QLatin1String("");
196     name += QLatin1String(".sis");
197     return name;
198 }
199
200 QStringList S60DeployConfiguration::packageFileNamesWithTargetInfo() const
201 {
202     QList<Qt4ProFileNode *> leafs = qt4Target()->qt4Project()->allProFiles();
203     QStringList result;
204     foreach (Qt4ProFileNode *qt4ProFileNode, leafs) {
205         if (!hasSisPackage(*qt4ProFileNode))
206             continue;
207         TargetInformation ti = qt4ProFileNode->targetInformation();
208         if (!ti.valid)
209             continue;
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;
215     }
216     return result;
217 }
218
219 QStringList S60DeployConfiguration::packageTemplateFileNames() const
220 {
221     QList<Qt4ProFileNode *> list = qt4Target()->qt4Project()->allProFiles();
222     QStringList result;
223     foreach (Qt4ProFileNode *node, list) {
224         if (!hasSisPackage(*node))
225             continue;
226         TargetInformation ti = node->targetInformation();
227         if (ti.valid)
228             result << ti.buildDir + QLatin1Char('/') + ti.target + QLatin1String("_template.pkg");
229     }
230     return result;
231 }
232
233 QStringList S60DeployConfiguration::appPackageTemplateFileNames() const
234 {
235     QList<Qt4ProFileNode *> list = qt4Target()->qt4Project()->allProFiles();
236     QStringList result;
237     foreach (Qt4ProFileNode *node, list) {
238         if (!hasSisPackage(*node))
239             continue;
240         TargetInformation ti = node->targetInformation();
241         if (ti.valid)
242             result << ti.buildDir + QLatin1Char('/') + ti.target + QLatin1String("_template.pkg");
243     }
244     return result;
245 }
246
247 bool S60DeployConfiguration::runSmartInstaller() const
248 {
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();
257         }
258     }
259     return false;
260 }
261
262 bool S60DeployConfiguration::isSigned() const
263 {
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;
272         }
273     }
274     return false;
275 }
276
277 ProjectExplorer::ToolChain *S60DeployConfiguration::toolChain() const
278 {
279     if (Qt4BuildConfiguration *bc = qobject_cast<Qt4BuildConfiguration *>(target()->activeBuildConfiguration()))
280         return bc->toolChain();
281     return 0;
282 }
283
284 bool S60DeployConfiguration::isDebug() const
285 {
286     const Qt4BuildConfiguration *qt4bc = qt4Target()->activeBuildConfiguration();
287     return (qt4bc->qmakeBuildConfiguration() & QtVersion::DebugBuild);
288 }
289
290 QString S60DeployConfiguration::symbianTarget() const
291 {
292     return isDebug() ? QLatin1String("udeb") : QLatin1String("urel");
293 }
294
295 const QtVersion *S60DeployConfiguration::qtVersion() const
296 {
297     if (const Qt4BuildConfiguration *qt4bc = qt4Target()->activeBuildConfiguration())
298         return qt4bc->qtVersion();
299     return 0;
300 }
301
302 void S60DeployConfiguration::updateActiveBuildConfiguration(ProjectExplorer::BuildConfiguration *buildConfiguration)
303 {
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()));
311 }
312
313 void S60DeployConfiguration::updateActiveRunConfiguration(ProjectExplorer::RunConfiguration *runConfiguration)
314 {
315     Q_UNUSED(runConfiguration);
316     setDefaultDisplayName(defaultDisplayName());
317 }
318
319 QVariantMap S60DeployConfiguration::toMap() const
320 {
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));
328
329     return map;
330 }
331
332 QString S60DeployConfiguration::defaultDisplayName() const
333 {
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());
339     }
340     return tr("Deploy to Symbian device");
341 }
342
343 bool S60DeployConfiguration::fromMap(const QVariantMap &map)
344 {
345     if (!DeployConfiguration::fromMap(map))
346         return false;
347     m_serialPortName = map.value(QLatin1String(SERIAL_PORT_NAME_KEY)).toString().trimmed();
348     m_installationDrive = map.value(QLatin1String(INSTALLATION_DRIVE_LETTER_KEY), QChar('C'))
349                           .toChar().toAscii();
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());
355
356     setDefaultDisplayName(defaultDisplayName());
357     return true;
358 }
359
360 Qt4SymbianTarget *S60DeployConfiguration::qt4Target() const
361 {
362     return static_cast<Qt4SymbianTarget *>(target());
363 }
364
365 QString S60DeployConfiguration::serialPortName() const
366 {
367     return m_serialPortName;
368 }
369
370 void S60DeployConfiguration::setSerialPortName(const QString &name)
371 {
372     const QString &candidate = name.trimmed();
373     if (m_serialPortName == candidate)
374         return;
375     m_serialPortName = candidate;
376     emit serialPortNameChanged();
377 }
378
379 char S60DeployConfiguration::installationDrive() const
380 {
381     return m_installationDrive;
382 }
383
384 void S60DeployConfiguration::setInstallationDrive(char drive)
385 {
386     if (m_installationDrive == drive)
387         return;
388     m_installationDrive = drive;
389     emit installationDriveChanged();
390 }
391
392 bool S60DeployConfiguration::silentInstall() const
393 {
394     return m_silentInstall;
395 }
396
397 void S60DeployConfiguration::setSilentInstall(bool silent)
398 {
399     m_silentInstall = silent;
400 }
401
402 QString S60DeployConfiguration::deviceAddress() const
403 {
404     return m_deviceAddress;
405 }
406
407 void S60DeployConfiguration::setDeviceAddress(const QString &address)
408 {
409     if (m_deviceAddress != address) {
410         m_deviceAddress = address;
411         emit deviceAddressChanged();
412     }
413 }
414
415 QString S60DeployConfiguration::devicePort() const
416 {
417     return m_devicePort;
418 }
419
420 void S60DeployConfiguration::setDevicePort(const QString &port)
421 {
422     if (m_devicePort != port) {
423         if (port.isEmpty()) //setup the default CODA's port
424             m_devicePort = QLatin1String(DEFAULT_TCF_TRK_TCP_PORT);
425         else
426             m_devicePort = port;
427         emit devicePortChanged();
428     }
429 }
430
431 S60DeployConfiguration::CommunicationChannel S60DeployConfiguration::communicationChannel() const
432 {
433     return m_communicationChannel;
434 }
435
436 void S60DeployConfiguration::setCommunicationChannel(CommunicationChannel channel)
437 {
438     if (m_communicationChannel != channel) {
439         m_communicationChannel = channel;
440         emit communicationChannelChanged();
441     }
442 }
443
444 void S60DeployConfiguration::setAvailableDeviceDrives(QList<DeviceDrive> drives)
445 {
446     m_availableDeviceDrives = drives;
447     emit availableDeviceDrivesChanged();
448 }
449
450 const QList<S60DeployConfiguration::DeviceDrive> &S60DeployConfiguration::availableDeviceDrives() const
451 {
452     return m_availableDeviceDrives;
453 }
454
455 // ======== S60DeployConfigurationFactory
456
457 S60DeployConfigurationFactory::S60DeployConfigurationFactory(QObject *parent) :
458     DeployConfigurationFactory(parent)
459 {
460 }
461
462 S60DeployConfigurationFactory::~S60DeployConfigurationFactory()
463 {
464 }
465
466 QStringList S60DeployConfigurationFactory::availableCreationIds(Target *parent) const
467 {
468     Qt4SymbianTarget *target = qobject_cast<Qt4SymbianTarget *>(parent);
469     if (!target ||
470         target->id() != QLatin1String(Constants::S60_DEVICE_TARGET_ID))
471         return QStringList();
472
473     return target->qt4Project()->applicationProFilePathes(QLatin1String(S60_DC_PREFIX));
474 }
475
476 QString S60DeployConfigurationFactory::displayNameForId(const QString &id) const
477 {
478     if (!pathFromId(id).isEmpty())
479         return tr("%1 on Symbian Device").arg(QFileInfo(pathFromId(id)).completeBaseName());
480     return QString();
481 }
482
483 DeployConfiguration *S60DeployConfigurationFactory::create(Target *parent, const QString &id)
484 {
485     if (!canCreate(parent, id))
486         return 0;
487
488     Qt4SymbianTarget *t = static_cast<Qt4SymbianTarget *>(parent);
489     S60DeployConfiguration *dc = new S60DeployConfiguration(t);
490
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()));
494     return dc;
495 }
496
497 bool S60DeployConfigurationFactory::canCreate(Target *parent, const QString& /*id*/) const
498 {
499     Qt4SymbianTarget * t = qobject_cast<Qt4SymbianTarget *>(parent);
500     if (!t || t->id() != QLatin1String(Constants::S60_DEVICE_TARGET_ID))
501         return false;
502     return true;
503 }
504
505 bool S60DeployConfigurationFactory::canRestore(Target *parent, const QVariantMap& /*map*/) const
506 {
507     Qt4SymbianTarget * t = qobject_cast<Qt4SymbianTarget *>(parent);
508     return t && t->id() == QLatin1String(Constants::S60_DEVICE_TARGET_ID);
509 }
510
511 DeployConfiguration *S60DeployConfigurationFactory::restore(Target *parent, const QVariantMap &map)
512 {
513     if (!canRestore(parent, map))
514         return 0;
515     Qt4SymbianTarget *t = static_cast<Qt4SymbianTarget *>(parent);
516     S60DeployConfiguration *dc = new S60DeployConfiguration(t);
517     if (dc->fromMap(map))
518         return dc;
519
520     delete dc;
521     return 0;
522 }
523
524 bool S60DeployConfigurationFactory::canClone(Target *parent, DeployConfiguration *source) const
525 {
526     if (!qobject_cast<Qt4SymbianTarget *>(parent))
527         return false;
528     return source->id() == QLatin1String(S60_DC_ID);
529 }
530
531 DeployConfiguration *S60DeployConfigurationFactory::clone(Target *parent, DeployConfiguration *source)
532 {
533     if (!canClone(parent, source))
534         return 0;
535     Qt4SymbianTarget *t = static_cast<Qt4SymbianTarget *>(parent);
536     S60DeployConfiguration * old = static_cast<S60DeployConfiguration *>(source);
537     return new S60DeployConfiguration(t, old);
538 }