PageRenderTime 64ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/src/plugins/projectexplorer/settingsaccessor.cpp

https://bitbucket.org/kpozn/qt-creator-py-reborn
C++ | 2699 lines | 2163 code | 302 blank | 234 comment | 667 complexity | 2a3ed87a9689936f14807bcd35c4bee0 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**************************************************************************
  2. **
  3. ** This file is part of Qt Creator
  4. **
  5. ** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
  6. **
  7. ** Contact: Nokia Corporation (qt-info@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. #include "settingsaccessor.h"
  33. #include "buildconfiguration.h"
  34. #include "devicesupport/devicemanager.h"
  35. #include "project.h"
  36. #include "projectexplorer.h"
  37. #include "projectexplorersettings.h"
  38. #include "projectexplorerconstants.h"
  39. #include "target.h"
  40. #include "profile.h"
  41. #include "profilemanager.h"
  42. #include <coreplugin/icore.h>
  43. #include <coreplugin/idocument.h>
  44. #include <extensionsystem/pluginmanager.h>
  45. #include <utils/qtcassert.h>
  46. #include <utils/qtcprocess.h>
  47. #include <utils/persistentsettings.h>
  48. #include <QApplication>
  49. #include <QDebug>
  50. #include <QFile>
  51. #include <QMainWindow>
  52. #include <QMessageBox>
  53. namespace ProjectExplorer {
  54. namespace Internal {
  55. // -------------------------------------------------------------------------
  56. // UserFileVersionHandler
  57. // -------------------------------------------------------------------------
  58. class UserFileVersionHandler
  59. {
  60. public:
  61. UserFileVersionHandler();
  62. virtual ~UserFileVersionHandler();
  63. // The user file version this handler accepts for input.
  64. virtual int userFileVersion() const = 0;
  65. virtual QString displayUserFileVersion() const = 0;
  66. // Update from userFileVersion() to userFileVersion() + 1
  67. virtual QVariantMap update(Project *project, const QVariantMap &map) = 0;
  68. protected:
  69. typedef QPair<QLatin1String,QLatin1String> Change;
  70. QVariantMap renameKeys(const QList<Change> &changes, QVariantMap map);
  71. };
  72. UserFileVersionHandler::UserFileVersionHandler()
  73. {
  74. }
  75. UserFileVersionHandler::~UserFileVersionHandler()
  76. {
  77. }
  78. /**
  79. * Performs a simple renaming of the listed keys in \a changes recursively on \a map.
  80. */
  81. QVariantMap UserFileVersionHandler::renameKeys(const QList<Change> &changes, QVariantMap map)
  82. {
  83. foreach (const Change &change, changes) {
  84. QVariantMap::iterator oldSetting = map.find(change.first);
  85. if (oldSetting != map.end()) {
  86. map.insert(change.second, oldSetting.value());
  87. map.erase(oldSetting);
  88. }
  89. }
  90. QVariantMap::iterator i = map.begin();
  91. while (i != map.end()) {
  92. QVariant v = i.value();
  93. if (v.type() == QVariant::Map)
  94. i.value() = renameKeys(changes, v.toMap());
  95. ++i;
  96. }
  97. return map;
  98. }
  99. } // Internal
  100. } // ProjectExplorer
  101. using namespace ProjectExplorer;
  102. using namespace Internal;
  103. using Utils::PersistentSettingsReader;
  104. using Utils::PersistentSettingsWriter;
  105. namespace {
  106. const char VERSION_KEY[] = "ProjectExplorer.Project.Updater.FileVersion";
  107. const char ENVIRONMENT_ID_KEY[] = "ProjectExplorer.Project.Updater.EnvironmentId";
  108. const char USER_STICKY_KEYS_KEY[] = "ProjectExplorer.Project.UserStickyKeys";
  109. const char SHARED_SETTINGS[] = "SharedSettings";
  110. // Version 0 is used in Qt Creator 1.3.x and
  111. // (in a slighly different flavour) post 1.3 master.
  112. class Version0Handler : public UserFileVersionHandler
  113. {
  114. public:
  115. int userFileVersion() const
  116. {
  117. return 0;
  118. }
  119. QString displayUserFileVersion() const
  120. {
  121. return QLatin1String("1.3");
  122. }
  123. QVariantMap update(Project *project, const QVariantMap &map);
  124. private:
  125. QVariantMap convertBuildConfigurations(Project *project, const QVariantMap &map);
  126. QVariantMap convertRunConfigurations(Project *project, const QVariantMap &map);
  127. QVariantMap convertBuildSteps(Project *project, const QVariantMap &map);
  128. };
  129. // Version 1 is used in master post Qt Creator 1.3.x.
  130. // It was never used in any official release but is required for the
  131. // transition to later versions (which introduce support for targets).
  132. class Version1Handler : public UserFileVersionHandler
  133. {
  134. public:
  135. int userFileVersion() const
  136. {
  137. return 1;
  138. }
  139. QString displayUserFileVersion() const
  140. {
  141. return QLatin1String("1.3+git");
  142. }
  143. QVariantMap update(Project *project, const QVariantMap &map);
  144. private:
  145. struct TargetDescription
  146. {
  147. TargetDescription(QString tid, QString dn) :
  148. id(tid),
  149. displayName(dn)
  150. {
  151. }
  152. TargetDescription(const TargetDescription &td) :
  153. id(td.id),
  154. displayName(td.displayName)
  155. {
  156. }
  157. QString id;
  158. QString displayName;
  159. };
  160. };
  161. // Version 2 is used in master post Qt Creator 2.0 alpha.
  162. class Version2Handler : public UserFileVersionHandler
  163. {
  164. public:
  165. int userFileVersion() const
  166. {
  167. return 2;
  168. }
  169. QString displayUserFileVersion() const
  170. {
  171. return QLatin1String("2.0-alpha+git");
  172. }
  173. QVariantMap update(Project *project, const QVariantMap &map);
  174. };
  175. // Version 3 reflect the move of symbian signing from run to build step.
  176. class Version3Handler : public UserFileVersionHandler
  177. {
  178. public:
  179. int userFileVersion() const
  180. {
  181. return 3;
  182. }
  183. QString displayUserFileVersion() const
  184. {
  185. return QLatin1String("2.0-alpha2+git");
  186. }
  187. QVariantMap update(Project *project, const QVariantMap &map);
  188. };
  189. // Version 4 reflects the introduction of deploy steps
  190. class Version4Handler : public UserFileVersionHandler
  191. {
  192. public:
  193. int userFileVersion() const
  194. {
  195. return 4;
  196. }
  197. QString displayUserFileVersion() const
  198. {
  199. return QLatin1String("2.1pre1");
  200. }
  201. QVariantMap update(Project *project, const QVariantMap &map);
  202. };
  203. // Version 5 reflects the introduction of new deploy steps for Symbian/Maemo
  204. class Version5Handler : public UserFileVersionHandler
  205. {
  206. public:
  207. int userFileVersion() const
  208. {
  209. return 5;
  210. }
  211. QString displayUserFileVersion() const
  212. {
  213. return QLatin1String("2.1pre2");
  214. }
  215. QVariantMap update(Project *project, const QVariantMap &map);
  216. };
  217. // Version 6 reflects the introduction of new deploy steps for Symbian/Maemo
  218. class Version6Handler : public UserFileVersionHandler
  219. {
  220. public:
  221. int userFileVersion() const
  222. {
  223. return 6;
  224. }
  225. QString displayUserFileVersion() const
  226. {
  227. return QLatin1String("2.1pre3");
  228. }
  229. QVariantMap update(Project *project, const QVariantMap &map);
  230. };
  231. // Version 7 reflects the introduction of new deploy configuration for Symbian
  232. class Version7Handler : public UserFileVersionHandler
  233. {
  234. public:
  235. int userFileVersion() const
  236. {
  237. return 7;
  238. }
  239. QString displayUserFileVersion() const
  240. {
  241. return QLatin1String("2.1pre4");
  242. }
  243. QVariantMap update(Project *project, const QVariantMap &map);
  244. };
  245. // Version 8 reflects the change of environment variable expansion rules,
  246. // turning some env variables into expandos, the change of argument quoting rules,
  247. // and the change of VariableManager's expansion syntax.
  248. class Version8Handler : public UserFileVersionHandler
  249. {
  250. public:
  251. int userFileVersion() const
  252. {
  253. return 8;
  254. }
  255. QString displayUserFileVersion() const
  256. {
  257. // pre5 because we renamed 2.2 to 2.1 later, so people already have 2.2pre4 files
  258. return QLatin1String("2.2pre5");
  259. }
  260. QVariantMap update(Project *project, const QVariantMap &map);
  261. };
  262. // Version 9 reflects the refactoring of the Maemo deploy step.
  263. class Version9Handler : public UserFileVersionHandler
  264. {
  265. public:
  266. int userFileVersion() const
  267. {
  268. return 9;
  269. }
  270. QString displayUserFileVersion() const
  271. {
  272. return QLatin1String("2.3pre1");
  273. }
  274. QVariantMap update(Project *project, const QVariantMap &map);
  275. };
  276. // Version 10 introduces disabling buildsteps, and handles upgrading custom process steps
  277. class Version10Handler : public UserFileVersionHandler
  278. {
  279. public:
  280. int userFileVersion() const
  281. {
  282. return 10;
  283. }
  284. QString displayUserFileVersion() const
  285. {
  286. return QLatin1String("2.5pre1");
  287. }
  288. QVariantMap update(Project *project, const QVariantMap &map);
  289. };
  290. // Version 10 introduces disabling buildsteps, and handles upgrading custom process steps
  291. class Version11Handler : public UserFileVersionHandler
  292. {
  293. public:
  294. Version11Handler();
  295. ~Version11Handler();
  296. int userFileVersion() const
  297. {
  298. return 11;
  299. }
  300. QString displayUserFileVersion() const
  301. {
  302. return QLatin1String("2.6pre1");
  303. }
  304. QVariantMap update(Project *project, const QVariantMap &map);
  305. private:
  306. void addBuildConfiguration(const QString &origTarget, Profile *p,
  307. bool targetActive,
  308. const QVariantMap &bc, bool bcActive);
  309. void addOtherConfiguration(const QString &origTarget,
  310. const QList<QVariantMap> &dcs, int activeDc,
  311. const QList<QVariantMap> &rcs, int activeRc, const QString &projectDir);
  312. void parseQtversionFile();
  313. void parseToolChainFile();
  314. class ToolChainExtraData {
  315. public:
  316. explicit ToolChainExtraData(const QString &mks = QString(), const QString &d = QString()) :
  317. m_mkspec(mks), m_debugger(d)
  318. { }
  319. QString m_mkspec;
  320. QString m_debugger;
  321. };
  322. QHash<QString, ToolChainExtraData> m_toolChainExtras;
  323. QHash<int, QString> m_qtVersionExtras;
  324. QHash<Profile *, QVariantMap> m_targets;
  325. };
  326. } // namespace
  327. //
  328. // Helper functions:
  329. //
  330. QT_BEGIN_NAMESPACE
  331. class HandlerNode
  332. {
  333. public:
  334. QSet<QString> strings;
  335. QHash<QString, HandlerNode> children;
  336. };
  337. Q_DECLARE_TYPEINFO(HandlerNode, Q_MOVABLE_TYPE);
  338. QT_END_NAMESPACE
  339. static HandlerNode buildHandlerNodes(const char * const **keys)
  340. {
  341. HandlerNode ret;
  342. while (const char *rname = *(*keys)++) {
  343. QString name = QLatin1String(rname);
  344. if (name.endsWith(QLatin1Char('.'))) {
  345. HandlerNode sub = buildHandlerNodes(keys);
  346. foreach (const QString &key, name.split(QLatin1Char('|')))
  347. ret.children.insert(key, sub);
  348. } else {
  349. ret.strings.insert(name);
  350. }
  351. }
  352. return ret;
  353. }
  354. static QVariantMap processHandlerNodes(const HandlerNode &node, const QVariantMap &map,
  355. QVariant (*handler)(const QVariant &var))
  356. {
  357. QVariantMap result;
  358. QMapIterator<QString, QVariant> it(map);
  359. while (it.hasNext()) {
  360. it.next();
  361. const QString &key = it.key();
  362. if (node.strings.contains(key)) {
  363. result.insert(key, handler(it.value()));
  364. goto handled;
  365. }
  366. if (it.value().type() == QVariant::Map)
  367. for (QHash<QString, HandlerNode>::ConstIterator subit = node.children.constBegin();
  368. subit != node.children.constEnd(); ++subit)
  369. if (key.startsWith(subit.key())) {
  370. result.insert(key, processHandlerNodes(subit.value(), it.value().toMap(), handler));
  371. goto handled;
  372. }
  373. result.insert(key, it.value());
  374. handled: ;
  375. }
  376. return result;
  377. }
  378. // -------------------------------------------------------------------------
  379. // UserFileAccessor
  380. // -------------------------------------------------------------------------
  381. SettingsAccessor::SettingsAccessor() :
  382. m_firstVersion(-1),
  383. m_lastVersion(-1),
  384. m_userFileAcessor(QByteArray("qtcUserFileName"),
  385. QLatin1String(".user"),
  386. QString::fromLocal8Bit(qgetenv("QTC_EXTENSION")),
  387. true,
  388. true),
  389. m_sharedFileAcessor(QByteArray("qtcSharedFileName"),
  390. QLatin1String(".shared"),
  391. QString::fromLocal8Bit(qgetenv("QTC_SHARED_EXTENSION")),
  392. false,
  393. false)
  394. {
  395. addVersionHandler(new Version0Handler);
  396. addVersionHandler(new Version1Handler);
  397. addVersionHandler(new Version2Handler);
  398. addVersionHandler(new Version3Handler);
  399. addVersionHandler(new Version4Handler);
  400. addVersionHandler(new Version5Handler);
  401. addVersionHandler(new Version6Handler);
  402. addVersionHandler(new Version7Handler);
  403. addVersionHandler(new Version8Handler);
  404. addVersionHandler(new Version9Handler);
  405. addVersionHandler(new Version10Handler);
  406. addVersionHandler(new Version11Handler);
  407. }
  408. SettingsAccessor::~SettingsAccessor()
  409. {
  410. qDeleteAll(m_handlers);
  411. }
  412. SettingsAccessor *SettingsAccessor::instance()
  413. {
  414. static SettingsAccessor acessor;
  415. return &acessor;
  416. }
  417. namespace {
  418. // It's assumed that the shared map has the same structure as the user map.
  419. template <class Operation_T>
  420. void synchronizeSettings(QVariantMap *userMap,
  421. const QVariantMap &sharedMap,
  422. Operation_T *op)
  423. {
  424. QVariantMap::const_iterator it = sharedMap.begin();
  425. QVariantMap::const_iterator eit = sharedMap.end();
  426. for (; it != eit; ++it) {
  427. const QString &key = it.key();
  428. const QVariant &sharedValue = it.value();
  429. const QVariant &userValue = userMap->value(key);
  430. if (sharedValue.type() == QVariant::Map) {
  431. if (userValue.type() != QVariant::Map) {
  432. // This should happen only if the user manually changed the file in such a way.
  433. continue;
  434. }
  435. QVariantMap nestedUserMap = userValue.toMap();
  436. synchronizeSettings(&nestedUserMap,
  437. sharedValue.toMap(),
  438. op);
  439. userMap->insert(key, nestedUserMap);
  440. } else if (userMap->contains(key) && userValue != sharedValue) {
  441. op->apply(userMap, key, sharedValue);
  442. }
  443. }
  444. }
  445. struct MergeSharedSetting
  446. {
  447. MergeSharedSetting(const QSet<QString> &sticky) : m_userSticky(sticky) {}
  448. void apply(QVariantMap *userMap, const QString &key, const QVariant &sharedValue)
  449. {
  450. if (!m_userSticky.contains(key))
  451. userMap->insert(key, sharedValue);
  452. }
  453. QSet<QString> m_userSticky;
  454. };
  455. // When restoring settings...
  456. // We check whether a .shared file exists. If so, we compare the settings in this file with
  457. // corresponding ones in the .user file. Whenever we identify a corresponding setting which
  458. // has a different value and which is not marked as sticky, we merge the .shared value into
  459. // the .user value.
  460. void mergeSharedSettings(QVariantMap *userMap, const QVariantMap &sharedMap)
  461. {
  462. if (sharedMap.isEmpty())
  463. return;
  464. QSet<QString> stickyKeys;
  465. const QVariant stickyList = userMap->take(QLatin1String(USER_STICKY_KEYS_KEY)).toList();
  466. if (stickyList.isValid()) {
  467. if (stickyList.type() != QVariant::List) {
  468. // File is messed up... The user probably changed something.
  469. return;
  470. }
  471. foreach (const QVariant &v, stickyList.toList())
  472. stickyKeys.insert(v.toString());
  473. }
  474. MergeSharedSetting op(stickyKeys);
  475. synchronizeSettings(userMap, sharedMap, &op);
  476. }
  477. struct TrackUserStickySetting
  478. {
  479. void apply(QVariantMap *, const QString &key, const QVariant &)
  480. {
  481. m_userSticky.insert(key);
  482. }
  483. QSet<QString> m_userSticky;
  484. };
  485. // When saving settings...
  486. // If a .shared file was considered in the previous restoring step, we check whether for
  487. // any of the current .shared settings there's a .user one which is different. If so, this
  488. // means the user explicitly changed it and we mark this setting as sticky.
  489. // Note that settings are considered sticky only when they differ from the .shared ones.
  490. // Although this approach is more flexible than permanent/forever sticky settings, it has
  491. // the side-effect that if a particular value unintentionally becomes the same in both
  492. // the .user and .shared files, this setting will "unstick".
  493. void trackUserStickySettings(QVariantMap *userMap, const QVariantMap &sharedMap)
  494. {
  495. if (sharedMap.isEmpty())
  496. return;
  497. TrackUserStickySetting op;
  498. synchronizeSettings(userMap, sharedMap, &op);
  499. userMap->insert(QLatin1String(USER_STICKY_KEYS_KEY), QVariant(op.m_userSticky.toList()));
  500. }
  501. } // Anonymous
  502. QVariantMap SettingsAccessor::restoreSettings(Project *project) const
  503. {
  504. if (m_lastVersion < 0 || !project)
  505. return QVariantMap();
  506. SettingsData settings;
  507. if (!m_userFileAcessor.readFile(project, &settings))
  508. settings.clear(); // No user settings, but there can still be shared ones.
  509. if (settings.isValid()) {
  510. if (settings.m_version > SettingsAccessor::instance()->m_lastVersion + 1) {
  511. QMessageBox::information(
  512. Core::ICore::mainWindow(),
  513. QApplication::translate("ProjectExplorer::SettingsAccessor",
  514. "Using Old Project Settings File"),
  515. QApplication::translate("ProjectExplorer::SettingsAccessor",
  516. "<html><head/><body><p>A versioned backup of the .user "
  517. "settings file will be used, because the non-versioned "
  518. "file was created by an incompatible newer version of "
  519. "Qt Creator.</p><p>Project settings changes made since "
  520. "the last time this version of Qt Creator was used "
  521. "with this project are ignored, and changes made now "
  522. "will <b>not</b> be propagated to the newer version."
  523. "</p></body></html>"),
  524. QMessageBox::Ok);
  525. }
  526. // Verify environment.
  527. if (!verifyEnvironmentId(settings.m_map.value(QLatin1String(ENVIRONMENT_ID_KEY)).toString())) {
  528. // TODO tr, casing check
  529. QMessageBox msgBox(
  530. QMessageBox::Question,
  531. QApplication::translate("ProjectExplorer::SettingsAccessor",
  532. "Project Settings File from a different Environment?"),
  533. QApplication::translate("ProjectExplorer::SettingsAccessor",
  534. "Qt Creator has found a .user settings file which was "
  535. "created for another development setup, maybe "
  536. "originating from another machine.\n\n"
  537. "The .user settings files contain environment specific "
  538. "settings. They should not be copied to a different "
  539. "environment. \n\n"
  540. "Do you still want to load the settings file?"),
  541. QMessageBox::Yes | QMessageBox::No,
  542. Core::ICore::mainWindow());
  543. msgBox.setDefaultButton(QMessageBox::No);
  544. msgBox.setEscapeButton(QMessageBox::No);
  545. if (msgBox.exec() == QMessageBox::No)
  546. return QVariantMap();
  547. }
  548. // Do we need to generate a backup?
  549. if (settings.m_version < m_lastVersion + 1 && !settings.m_usingBackup) {
  550. const QString &backupFileName = settings.m_fileName
  551. + QLatin1Char('.')
  552. + m_handlers.value(settings.m_version)->displayUserFileVersion();
  553. QFile::remove(backupFileName); // Remove because copy doesn't overwrite
  554. QFile::copy(settings.m_fileName, backupFileName);
  555. }
  556. }
  557. // Time to consider shared settings...
  558. SettingsData sharedSettings;
  559. if (m_sharedFileAcessor.readFile(project, &sharedSettings)) {
  560. bool useSharedSettings = true;
  561. if (sharedSettings.m_version != settings.m_version) {
  562. int baseFileVersion;
  563. if (sharedSettings.m_version > m_lastVersion + 1) {
  564. // The shared file version is newer than Creator... If we have valid user
  565. // settings we prompt the user whether we could try an *unsupported* update.
  566. // This makes sense since the merging operation will only replace shared settings
  567. // that perfectly match corresponding user ones. If we don't have valid user
  568. // settings to compare against, there's nothing we can do.
  569. if (!settings.isValid())
  570. return QVariantMap();
  571. QMessageBox msgBox(
  572. QMessageBox::Question,
  573. QApplication::translate("ProjectExplorer::SettingsAccessor",
  574. "Unsupported Shared Settings File"),
  575. QApplication::translate("ProjectExplorer::SettingsAccessor",
  576. "The version of your .shared file is not yet "
  577. "supported by this Qt Creator version. "
  578. "Only settings that are still compatible "
  579. "will be taken into account.\n\n"
  580. "Do you want to continue?\n\n"
  581. "If you choose not to continue Qt Creator will "
  582. "not try to load the .shared file."),
  583. QMessageBox::Yes | QMessageBox::No,
  584. Core::ICore::mainWindow());
  585. msgBox.setDefaultButton(QMessageBox::No);
  586. msgBox.setEscapeButton(QMessageBox::No);
  587. if (msgBox.exec() == QMessageBox::No)
  588. useSharedSettings = false;
  589. else
  590. baseFileVersion = m_lastVersion + 1;
  591. } else {
  592. baseFileVersion = qMax(settings.m_version, sharedSettings.m_version);
  593. }
  594. if (useSharedSettings) {
  595. // We now update the user and shared settings so they are compatible.
  596. for (int i = sharedSettings.m_version; i < baseFileVersion; ++i)
  597. sharedSettings.m_map = m_handlers.value(i)->update(project, sharedSettings.m_map);
  598. if (!settings.isValid()) {
  599. project->setProperty(SHARED_SETTINGS, sharedSettings.m_map);
  600. return sharedSettings.m_map;
  601. }
  602. for (int i = settings.m_version; i < baseFileVersion; ++i)
  603. settings.m_map = m_handlers.value(i)->update(project, settings.m_map);
  604. settings.m_version = baseFileVersion;
  605. }
  606. }
  607. if (useSharedSettings) {
  608. project->setProperty(SHARED_SETTINGS, sharedSettings.m_map);
  609. if (!settings.isValid())
  610. return sharedSettings.m_map;
  611. mergeSharedSettings(&settings.m_map, sharedSettings.m_map);
  612. }
  613. }
  614. if (!settings.isValid())
  615. return QVariantMap();
  616. // Update from the base version to Creator's version.
  617. for (int i = settings.m_version; i <= m_lastVersion; ++i)
  618. settings.m_map = m_handlers.value(i)->update(project, settings.m_map);
  619. return settings.m_map;
  620. }
  621. bool SettingsAccessor::saveSettings(const Project *project, const QVariantMap &map) const
  622. {
  623. if (!project || map.isEmpty())
  624. return false;
  625. SettingsData settings(map);
  626. const QVariant &shared = project->property(SHARED_SETTINGS);
  627. if (shared.isValid())
  628. trackUserStickySettings(&settings.m_map, shared.toMap());
  629. return m_userFileAcessor.writeFile(project, &settings);
  630. }
  631. void SettingsAccessor::addVersionHandler(UserFileVersionHandler *handler)
  632. {
  633. const int version(handler->userFileVersion());
  634. QTC_ASSERT(handler, return);
  635. QTC_ASSERT(version >= 0, return);
  636. QTC_ASSERT(!m_handlers.contains(version), return);
  637. QTC_ASSERT(m_handlers.isEmpty() ||
  638. (version == m_lastVersion + 1 || version == m_firstVersion - 1), return);
  639. if (m_handlers.isEmpty()) {
  640. m_firstVersion = version;
  641. m_lastVersion = version;
  642. } else {
  643. if (version < m_firstVersion)
  644. m_firstVersion = version;
  645. if (version > m_lastVersion)
  646. m_lastVersion = version;
  647. }
  648. m_handlers.insert(version, handler);
  649. // Postconditions:
  650. Q_ASSERT(m_lastVersion >= 0);
  651. Q_ASSERT(m_firstVersion >= 0);
  652. Q_ASSERT(m_lastVersion >= m_firstVersion);
  653. Q_ASSERT(m_handlers.count() == m_lastVersion - m_firstVersion + 1);
  654. for (int i = m_firstVersion; i < m_lastVersion; ++i)
  655. Q_ASSERT(m_handlers.contains(i));
  656. }
  657. bool SettingsAccessor::verifyEnvironmentId(const QString &id)
  658. {
  659. QUuid fileEnvironmentId(id);
  660. if (!fileEnvironmentId.isNull()
  661. && fileEnvironmentId
  662. != ProjectExplorerPlugin::instance()->projectExplorerSettings().environmentId) {
  663. return false;
  664. }
  665. return true;
  666. }
  667. // -------------------------------------------------------------------------
  668. // SettingsData
  669. // -------------------------------------------------------------------------
  670. void SettingsAccessor::SettingsData::clear()
  671. {
  672. m_version = -1;
  673. m_usingBackup = false;
  674. m_map.clear();
  675. m_fileName.clear();
  676. }
  677. bool SettingsAccessor::SettingsData::isValid() const
  678. {
  679. return m_version > -1 && !m_fileName.isEmpty();
  680. }
  681. // -------------------------------------------------------------------------
  682. // FileAcessor
  683. // -------------------------------------------------------------------------
  684. SettingsAccessor::FileAccessor::FileAccessor(const QByteArray &id,
  685. const QString &defaultSuffix,
  686. const QString &environmentSuffix,
  687. bool envSpecific,
  688. bool versionStrict)
  689. : m_id(id)
  690. , m_environmentSpecific(envSpecific)
  691. , m_versionStrict(versionStrict)
  692. {
  693. assignSuffix(defaultSuffix, environmentSuffix);
  694. }
  695. void SettingsAccessor::FileAccessor::assignSuffix(const QString &defaultSuffix,
  696. const QString &environmentSuffix)
  697. {
  698. if (!environmentSuffix.isEmpty()) {
  699. m_suffix = environmentSuffix;
  700. m_suffix.replace(QRegExp(QLatin1String("[^a-zA-Z0-9_.-]")), QString(QLatin1Char('_'))); // replace fishy characters:
  701. m_suffix.prepend(QLatin1Char('.'));
  702. } else {
  703. m_suffix = defaultSuffix;
  704. }
  705. }
  706. QString SettingsAccessor::FileAccessor::assembleFileName(const Project *project) const
  707. {
  708. return project->document()->fileName() + m_suffix;
  709. }
  710. bool SettingsAccessor::FileAccessor::findNewestCompatibleSetting(SettingsData *settings) const
  711. {
  712. const QString baseFileName = settings->m_fileName;
  713. const int baseVersion = settings->m_version;
  714. settings->m_fileName.clear();
  715. settings->m_version = -1;
  716. PersistentSettingsReader reader;
  717. SettingsAccessor *acessor = SettingsAccessor::instance();
  718. QFileInfo fileInfo(baseFileName);
  719. QStringList fileNameFilter(fileInfo.fileName() + QLatin1String(".*"));
  720. const QStringList &entryList = fileInfo.absoluteDir().entryList(fileNameFilter);
  721. QStringList candidates;
  722. // First we try to identify the newest old version with a quick check.
  723. foreach (const QString &file, entryList) {
  724. const QString &suffix = file.mid(fileInfo.fileName().length() + 1);
  725. const QString &candidateFileName = baseFileName + QLatin1String(".") + suffix;
  726. candidates.append(candidateFileName);
  727. for (int candidateVersion = acessor->m_lastVersion;
  728. candidateVersion >= acessor->m_firstVersion;
  729. --candidateVersion) {
  730. if (suffix == acessor->m_handlers.value(candidateVersion)->displayUserFileVersion()) {
  731. if (candidateVersion > settings->m_version) {
  732. settings->m_version = candidateVersion;
  733. settings->m_fileName = candidateFileName;
  734. }
  735. break;
  736. }
  737. }
  738. }
  739. if (settings->m_version != -1) {
  740. if (reader.load(settings->m_fileName)) {
  741. settings->m_map = reader.restoreValues();
  742. return true;
  743. }
  744. qWarning() << "Unable to load file" << settings->m_fileName;
  745. }
  746. // If we haven't identified a valid file or if it for any reason failed to load, we
  747. // try a more expensive check (which is actually needed to identify our own and newer
  748. // versions as we don't know what extensions will be assigned in the future).
  749. foreach (const QString &candidateFileName, candidates) {
  750. if (settings->m_fileName == candidateFileName)
  751. continue; // This one has already failed to load.
  752. if (reader.load(candidateFileName)) {
  753. settings->m_map = reader.restoreValues();
  754. int candidateVersion = settings->m_map.value(QLatin1String(VERSION_KEY), 0).toInt();
  755. if (candidateVersion == acessor->m_lastVersion + 1) {
  756. settings->m_version = candidateVersion;
  757. settings->m_fileName = candidateFileName;
  758. return true;
  759. }
  760. }
  761. }
  762. // Nothing really worked...
  763. qWarning() << "File version" << baseVersion << "too new.";
  764. return false;
  765. }
  766. bool SettingsAccessor::FileAccessor::readFile(Project *project,
  767. SettingsData *settings) const
  768. {
  769. PersistentSettingsReader reader;
  770. settings->m_fileName = assembleFileName(project);
  771. if (!reader.load(settings->m_fileName))
  772. return false;
  773. settings->m_map = reader.restoreValues();
  774. // Get and verify file version
  775. settings->m_version = settings->m_map.value(QLatin1String(VERSION_KEY), 0).toInt();
  776. if (!m_versionStrict)
  777. return true;
  778. if (settings->m_version < SettingsAccessor::instance()->m_firstVersion) {
  779. qWarning() << "Version" << settings->m_version << "in" << m_suffix << "too old.";
  780. return false;
  781. }
  782. if (settings->m_version > SettingsAccessor::instance()->m_lastVersion + 1) {
  783. if (!findNewestCompatibleSetting(settings))
  784. return false;
  785. settings->m_usingBackup = true;
  786. project->setProperty(m_id.constData(), settings->m_fileName);
  787. }
  788. return true;
  789. }
  790. bool SettingsAccessor::FileAccessor::writeFile(const Project *project,
  791. const SettingsData *settings) const
  792. {
  793. PersistentSettingsWriter writer;
  794. for (QVariantMap::const_iterator i = settings->m_map.constBegin();
  795. i != settings->m_map.constEnd();
  796. ++i) {
  797. writer.saveValue(i.key(), i.value());
  798. }
  799. writer.saveValue(QLatin1String(VERSION_KEY), SettingsAccessor::instance()->m_lastVersion + 1);
  800. if (m_environmentSpecific) {
  801. writer.saveValue(QLatin1String(ENVIRONMENT_ID_KEY),
  802. ProjectExplorerPlugin::instance()->projectExplorerSettings().environmentId.toString());
  803. }
  804. const QString &fileName = project->property(m_id).toString();
  805. return writer.save(fileName.isEmpty() ? assembleFileName(project) : fileName,
  806. QLatin1String("QtCreatorProject"),
  807. Core::ICore::mainWindow());
  808. }
  809. // -------------------------------------------------------------------------
  810. // Version0Handler
  811. // -------------------------------------------------------------------------
  812. QVariantMap Version0Handler::convertBuildConfigurations(Project *project, const QVariantMap &map)
  813. {
  814. Q_ASSERT(project);
  815. QVariantMap result;
  816. // Find a valid Id to use:
  817. QString id;
  818. if (project->id() == Core::Id("GenericProjectManager.GenericProject")) {
  819. id = QLatin1String("GenericProjectManager.GenericBuildConfiguration");
  820. } else if (project->id() == Core::Id("CMakeProjectManager.CMakeProject")) {
  821. id = QLatin1String("CMakeProjectManager.CMakeBuildConfiguration");
  822. } else if (project->id() == Core::Id("Qt4ProjectManager.Qt4Project")) {
  823. result.insert(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.NeedsV0Update"), QVariant());
  824. id = QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration");
  825. } else {
  826. return QVariantMap(); // QmlProjects do not(/no longer) have BuildConfigurations,
  827. // or we do not know how to handle this.
  828. }
  829. result.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"), id);
  830. for (QVariantMap::const_iterator i = map.constBegin(); i != map.constEnd(); ++i) {
  831. if (i.key() == QLatin1String("ProjectExplorer.BuildConfiguration.DisplayName")) {
  832. result.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.DisplayName"),
  833. i.value());
  834. continue;
  835. }
  836. if (id == QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration") ||
  837. id.startsWith(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration."))) {
  838. // Qt4BuildConfiguration:
  839. if (i.key() == QLatin1String("QtVersionId")) {
  840. result.insert(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId"),
  841. i.value().toInt());
  842. } else if (i.key() == QLatin1String("ToolChain")) {
  843. result.insert(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.ToolChain"),
  844. i.value());
  845. } else if (i.key() == QLatin1String("buildConfiguration")) {
  846. result.insert(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration"),
  847. i.value());
  848. } else if (i.key() == QLatin1String("userEnvironmentChanges")) {
  849. result.insert(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.UserEnvironmentChanges"),
  850. i.value());
  851. } else if (i.key() == QLatin1String("useShadowBuild")) {
  852. result.insert(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild"),
  853. i.value());
  854. } else if (i.key() == QLatin1String("clearSystemEnvironment")) {
  855. result.insert(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.ClearSystemEnvironment"),
  856. i.value());
  857. } else if (i.key() == QLatin1String("buildDirectory")) {
  858. result.insert(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory"),
  859. i.value());
  860. } else {
  861. qWarning() << "Unknown Qt4BuildConfiguration Key found:" << i.key() << i.value();
  862. }
  863. continue;
  864. } else if (id == QLatin1String("CMakeProjectManager.CMakeBuildConfiguration")) {
  865. if (i.key() == QLatin1String("userEnvironmentChanges")) {
  866. result.insert(QLatin1String("CMakeProjectManager.CMakeBuildConfiguration.UserEnvironmentChanges"),
  867. i.value());
  868. } else if (i.key() == QLatin1String("msvcVersion")) {
  869. result.insert(QLatin1String("CMakeProjectManager.CMakeBuildConfiguration.MsvcVersion"),
  870. i.value());
  871. } else if (i.key() == QLatin1String("buildDirectory")) {
  872. result.insert(QLatin1String("CMakeProjectManager.CMakeBuildConfiguration.BuildDirectory"),
  873. i.value());
  874. } else {
  875. qWarning() << "Unknown CMakeBuildConfiguration Key found:" << i.key() << i.value();
  876. }
  877. continue;
  878. } else if (id == QLatin1String("GenericProjectManager.GenericBuildConfiguration")) {
  879. if (i.key() == QLatin1String("buildDirectory")) {
  880. result.insert(QLatin1String("GenericProjectManager.GenericBuildConfiguration.BuildDirectory"),
  881. i.value());
  882. } else {
  883. qWarning() << "Unknown GenericBuildConfiguration Key found:" << i.key() << i.value();
  884. }
  885. continue;
  886. }
  887. qWarning() << "Unknown BuildConfiguration Key found:" << i.key() << i.value();
  888. qWarning() << "BuildConfiguration Id is:" << id;
  889. }
  890. return result;
  891. }
  892. QVariantMap Version0Handler::convertRunConfigurations(Project *project, const QVariantMap &map)
  893. {
  894. Q_UNUSED(project);
  895. QVariantMap result;
  896. QString id;
  897. // Convert Id:
  898. id = map.value(QLatin1String("Id")).toString();
  899. if (id.isEmpty())
  900. id = map.value(QLatin1String("type")).toString();
  901. if (id.isEmpty())
  902. return QVariantMap();
  903. if (QLatin1String("Qt4ProjectManager.DeviceRunConfiguration") == id)
  904. id = QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration");
  905. if (QLatin1String("Qt4ProjectManager.EmulatorRunConfiguration") == id)
  906. id = QLatin1String("Qt4ProjectManager.S60EmulatorRunConfiguration");
  907. // no need to change the CMakeRunConfiguration, CustomExecutableRunConfiguration,
  908. // MaemoRunConfiguration or Qt4RunConfiguration
  909. result.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"), id);
  910. // Convert everything else:
  911. for (QVariantMap::const_iterator i = map.constBegin(); i != map.constEnd(); ++i) {
  912. if (i.key() == QLatin1String("Id") || i.key() == QLatin1String("type"))
  913. continue;
  914. if (i.key() == QLatin1String("RunConfiguration.name")) {
  915. result.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.DisplayName"),
  916. i.value());
  917. } else if (QLatin1String("CMakeProjectManager.CMakeRunConfiguration") == id) {
  918. if (i.key() == QLatin1String("CMakeRunConfiguration.Target"))
  919. result.insert(QLatin1String("CMakeProjectManager.CMakeRunConfiguration.Target"), i.value());
  920. else if (i.key() == QLatin1String("CMakeRunConfiguration.WorkingDirectory"))
  921. result.insert(QLatin1String("CMakeProjectManager.CMakeRunConfiguration.WorkingDirectory"), i.value());
  922. else if (i.key() == QLatin1String("CMakeRunConfiguration.UserWorkingDirectory"))
  923. result.insert(QLatin1String("CMakeProjectManager.CMakeRunConfiguration.UserWorkingDirectory"), i.value());
  924. else if (i.key() == QLatin1String("CMakeRunConfiguration.UseTerminal"))
  925. result.insert(QLatin1String("CMakeProjectManager.CMakeRunConfiguration.UseTerminal"), i.value());
  926. else if (i.key() == QLatin1String("CMakeRunConfiguation.Title"))
  927. result.insert(QLatin1String("CMakeProjectManager.CMakeRunConfiguation.Title"), i.value());
  928. else if (i.key() == QLatin1String("CMakeRunConfiguration.Arguments"))
  929. result.insert(QLatin1String("CMakeProjectManager.CMakeRunConfiguration.Arguments"), i.value());
  930. else if (i.key() == QLatin1String("CMakeRunConfiguration.UserEnvironmentChanges"))
  931. result.insert(QLatin1String("CMakeProjectManager.CMakeRunConfiguration.UserEnvironmentChanges"), i.value());
  932. else if (i.key() == QLatin1String("BaseEnvironmentBase"))
  933. result.insert(QLatin1String("CMakeProjectManager.BaseEnvironmentBase"), i.value());
  934. else
  935. qWarning() << "Unknown CMakeRunConfiguration key found:" << i.key() << i.value();
  936. } else if (QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration") == id) {
  937. if (i.key() == QLatin1String("ProFile"))
  938. result.insert(QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration.ProFile"), i.value());
  939. else if (i.key() == QLatin1String("SigningMode"))
  940. result.insert(QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration.SigningMode"), i.value());
  941. else if (i.key() == QLatin1String("CustomSignaturePath"))
  942. result.insert(QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration.CustomSignaturePath"), i.value());
  943. else if (i.key() == QLatin1String("CustomKeyPath"))
  944. result.insert(QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration.CustomKeyPath"), i.value());
  945. else if (i.key() == QLatin1String("SerialPortName"))
  946. result.insert(QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration.SerialPortName"), i.value());
  947. else if (i.key() == QLatin1String("CommunicationType"))
  948. result.insert(QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration.CommunicationType"), i.value());
  949. else if (i.key() == QLatin1String("CommandLineArguments"))
  950. result.insert(QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration.CommandLineArguments"), i.value());
  951. else
  952. qWarning() << "Unknown S60DeviceRunConfiguration key found:" << i.key() << i.value();
  953. } else if (QLatin1String("Qt4ProjectManager.S60EmulatorRunConfiguration") == id) {
  954. if (i.key() == QLatin1String("ProFile"))
  955. result.insert(QLatin1String("Qt4ProjectManager.S60EmulatorRunConfiguration.ProFile"), i.value());
  956. else
  957. qWarning() << "Unknown S60EmulatorRunConfiguration key found:" << i.key() << i.value();
  958. } else if (QLatin1String("Qt4ProjectManager.Qt4RunConfiguration") == id) {
  959. if (i.key() == QLatin1String("ProFile"))
  960. result.insert(QLatin1String("Qt4ProjectManager.Qt4RunConfiguration.ProFile"), i.value());
  961. else if (i.key() == QLatin1String("CommandLineArguments"))
  962. result.insert(QLatin1String("Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"), i.value());
  963. else if (i.key() == QLatin1String("UserSetName"))
  964. result.insert(QLatin1String("Qt4ProjectManager.Qt4RunConfiguration.UserSetName"), i.value());
  965. else if (i.key() == QLatin1String("UseTerminal"))
  966. result.insert(QLatin1String("Qt4ProjectManager.Qt4RunConfiguration.UseTerminal"), i.value());
  967. else if (i.key() == QLatin1String("UseDyldImageSuffix"))
  968. result.insert(QLatin1String("Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix"), i.value());
  969. else if (i.key() == QLatin1String("UserEnvironmentChanges"))
  970. result.insert(QLatin1String("Qt4ProjectManager.Qt4RunConfiguration.UserEnvironmentChanges"), i.value());
  971. else if (i.key() == QLatin1String("BaseEnvironmentBase"))
  972. result.insert(QLatin1String("Qt4ProjectManager.Qt4RunConfiguration.BaseEnvironmentBase"), i.value());
  973. else if (i.key() == QLatin1String("UserSetWorkingDirectory"))
  974. result.insert(QLatin1String("Qt4ProjectManager.Qt4RunConfiguration.UserSetWorkingDirectory"), i.value());
  975. else if (i.key() == QLatin1String("UserWorkingDirectory"))
  976. result.insert(QLatin1String("Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"), i.value());
  977. else
  978. qWarning() << "Unknown Qt4RunConfiguration key found:" << i.key() << i.value();
  979. } else if (QLatin1String("Qt4ProjectManager.MaemoRunConfiguration") == id) {
  980. if (i.key() == QLatin1String("ProFile"))
  981. result.insert(QLatin1String("Qt4ProjectManager.MaemoRunConfiguration.ProFile"), i.value());
  982. else if (i.key() == QLatin1String("Arguments"))
  983. result.insert(QLatin1String("Qt4ProjectManager.MaemoRunConfiguration.Arguments"), i.value());
  984. else if (i.key() == QLatin1String("Simulator"))
  985. result.insert(QLatin1String("Qt4ProjectManager.MaemoRunConfiguration.Simulator"), i.value());
  986. else if (i.key() == QLatin1String("DeviceId"))
  987. result.insert(QLatin1String("Qt4ProjectManager.MaemoRunConfiguration.DeviceId"), i.value());
  988. else if (i.key() == QLatin1String("LastDeployed"))
  989. result.insert(QLatin1String("Qt4ProjectManager.MaemoRunConfiguration.LastDeployed"), i.value());
  990. else if (i.key() == QLatin1String("DebuggingHelpersLastDeployed"))
  991. result.insert(QLatin1String("Qt4ProjectManager.MaemoRunConfiguration.DebuggingHelpersLastDeployed"), i.value());
  992. else
  993. qWarning() << "Unknown MaemoRunConfiguration key found:" << i.key() << i.value();
  994. } else if (QLatin1String("ProjectExplorer.CustomExecutableRunConfiguration") == id) {
  995. if (i.key() == QLatin1String("Executable"))
  996. result.insert(QLatin1String("ProjectExplorer.CustomExecutableRunConfiguration.Executable"), i.value());
  997. else if (i.key() == QLatin1String("Arguments"))
  998. result.insert(QLatin1String("ProjectExplorer.CustomExecutableRunConfiguration.Arguments"), i.value());
  999. else if (i.key() == QLatin1String("WorkingDirectory"))
  1000. result.insert(QLatin1String("ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory"), i.value());
  1001. else if (i.key() == QLatin1String("UseTerminal"))
  1002. result.insert(QLatin1String("ProjectExplorer.CustomExecutableRunConfiguration.UseTerminal"), i.value());
  1003. else if (i.key() == QLatin1String("UserSetName"))
  1004. result.insert(QLatin1String("ProjectExplorer.CustomExecutableRunConfiguration.UserSetName"), i.value());
  1005. else if (i.key() == QLatin1String("UserName"))
  1006. result.insert(QLatin1String("ProjectExplorer.CustomExecutableRunConfiguration.UserName"), i.value());
  1007. else if (i.key() == QLatin1String("UserEnvironmentChanges"))
  1008. result.insert(QLatin1String("ProjectExplorer.CustomExecutableRunConfiguration.UserEnvironmentChanges"), i.value());
  1009. else if (i.key() == QLatin1String("BaseEnvironmentBase"))
  1010. result.insert(QLatin1String("ProjectExplorer.CustomExecutableRunConfiguration.BaseEnvironmentBase"), i.value());
  1011. else
  1012. qWarning() << "Unknown CustomExecutableRunConfiguration key found:" << i.key() << i.value();
  1013. } else {
  1014. result.insert(i.key(), i.value());
  1015. }
  1016. }
  1017. return result;
  1018. }
  1019. QVariantMap Version0Handler::convertBuildSteps(Project *project, const QVariantMap &map)
  1020. {
  1021. Q_UNUSED(project);
  1022. QVariantMap result;
  1023. QString id(map.value(QLatin1String("Id")).toString());
  1024. if (QLatin1String("GenericProjectManager.MakeStep") == id)
  1025. id = QLatin1String("GenericProjectManager.GenericMakeStep");
  1026. if (QLatin1String("projectexplorer.processstep") == id)
  1027. id = QLatin1String("ProjectExplorer.ProcessStep");
  1028. if (QLatin1String("trolltech.qt4projectmanager.make") == id)
  1029. id = QLatin1String("Qt4ProjectManager.MakeStep");
  1030. if (QLatin1String("trolltech.qt4projectmanager.qmake") == id)
  1031. id = QLatin1String("QtProjectManager.QMakeBuildStep");
  1032. // No need to change the CMake MakeStep.
  1033. result.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"), id);
  1034. for (QVariantMap::const_iterator i = map.constBegin(); i != map.constEnd(); ++i) {
  1035. if (i.key() == QLatin1String("Id"))
  1036. continue;
  1037. if (i.key() == QLatin1String("ProjectExplorer.BuildConfiguration.DisplayName")) {
  1038. // skip this: Not needed.
  1039. continue;
  1040. }
  1041. if (QLatin1String("GenericProjectManager.GenericMakeStep") == id) {
  1042. if (i.key() == QLatin1String("buildTargets"))
  1043. result.insert(QLatin1String("GenericProjectManager.GenericMakeStep.BuildTargets"), i.value());
  1044. else if (i.key() == QLatin1String("makeArguments"))
  1045. result.insert(QLatin1String("GenericProjectManager.GenericMakeStep.MakeArguments"), i.value());
  1046. else if (i.key() == QLatin1String("makeCommand"))
  1047. result.insert(QLatin1String("GenericProjectManager.GenericMakeStep.MakeCommand"), i.value());
  1048. else
  1049. qWarning() << "Unknown GenericMakeStep value found:" << i.key() << i.value();
  1050. continue;
  1051. } else if (QLatin1String("ProjectExplorer.ProcessStep") == id) {
  1052. if (i.key() == QLatin1String("ProjectExplorer.ProcessStep.DisplayName"))
  1053. result.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.DisplayName"), i.value());
  1054. else if (i.key() == QLatin1String("abstractProcess.command"))
  1055. result.insert(QLatin1String("ProjectExplorer.ProcessStep.Command"), i.value());
  1056. else if ((i.key() == QLatin1String("abstractProcess.workingDirectory") ||
  1057. i.key() == QLatin1String("workingDirectory")) &&
  1058. !i.value().toString().isEmpty())
  1059. result.insert(QLatin1String("ProjectExplorer.ProcessStep.WorkingDirectory"), i.value());
  1060. else if (i.key() == QLatin1String("abstractProcess.arguments"))
  1061. result.insert(QLatin1String("ProjectExplorer.ProcessStep.Arguments"), i.value());
  1062. else if (i.key() == QLatin1String("abstractProcess.enabled"))
  1063. result.insert(QLatin1String("ProjectExplorer.ProcessStep.Enabled"), i.value());
  1064. else
  1065. qWarning() << "Unknown ProcessStep value found:" << i.key() << i.value();
  1066. } else if (QLatin1String("Qt4ProjectManager.MakeStep") == id) {
  1067. if (i.key() == QLatin1String("makeargs"))
  1068. result.insert(QLatin1String("Qt4ProjectManager.MakeStep.MakeArguments"), i.value());
  1069. else if (i.key() == QLatin1String("makeCmd"))
  1070. result.insert(QLatin1String("Qt4ProjectManager.MakeStep.MakeCommand"), i.value());
  1071. else if (i.key() == QLatin1String("clean"))
  1072. result.insert(QLatin1String("Qt4ProjectManager.MakeStep.Clean"), i.value());
  1073. else
  1074. qWarning() << "Unknown Qt4MakeStep value found:" << i.key() << i.value();
  1075. } else if (QLatin1String("QtProjectManager.QMakeBuildStep") == id) {
  1076. if (i.key() == QLatin1String("qmakeArgs"))
  1077. result.insert(QLatin1String("QtProjectManager.QMakeBuildStep.QMakeArguments"), i.value());
  1078. else
  1079. qWarning() << "Unknown Qt4QMakeStep value found:" << i.key() << i.value();
  1080. } else if (QLatin1String("CMakeProjectManager.MakeStep") == id) {
  1081. if (i.key() == QLatin1String("buildTargets"))
  1082. result.insert(QLatin1String("CMakeProjectManager.MakeStep.BuildTargets"), i.value());
  1083. else if (i.key() == QLatin1String("additionalArguments"))
  1084. result.insert(QLatin1String("CMakeProjectManager.MakeStep.AdditionalArguments"), i.value());
  1085. else if (i.key() == QLatin1String("clean"))
  1086. result.insert(QLatin1String("CMakeProjectManager.MakeStep.Clean"), i.value());
  1087. else
  1088. qWarning() << "Unknown CMakeMakeStep value found:" << i.key() << i.value();
  1089. } else {
  1090. result.insert(i.key(), i.value());
  1091. }
  1092. }
  1093. return result;
  1094. }
  1095. QVariantMap Version0Handler::update(Project *project, const QVariantMap &map)
  1096. {
  1097. QVariantMap result;
  1098. // "project": section is unused, just ignore it.
  1099. // "buildconfigurations" and "buildConfiguration-":
  1100. QStringList bcs(map.value(QLatin1String("buildconfigurations")).toStringList());
  1101. QString active(map.value(QLatin1String("activebuildconfiguration")).toString());
  1102. int count(0);
  1103. foreach (const QString &bc, bcs) {
  1104. // convert buildconfiguration:
  1105. QString oldBcKey(QString::fromLatin1("buildConfiguration-") + bc);
  1106. if (bc == active)
  1107. result.insert(QLatin1String("ProjectExplorer.Project.ActiveBuildConfiguration"), count);
  1108. QVariantMap tmp(map.value(oldBcKey).toMap());
  1109. QVariantMap bcMap(convertBuildConfigurations(project, tmp));
  1110. if (bcMap.isEmpty())
  1111. continue;
  1112. // buildsteps
  1113. QStringList buildSteps(map.value(oldBcKey + QLatin1String("-buildsteps")).toStringList());
  1114. if (buildSteps.isEmpty())
  1115. // try lowercase version, too:-(
  1116. buildSteps = map.value(QString::fromLatin1("buildconfiguration-") + bc + QLatin1String("-buildsteps")).toStringList();
  1117. if (buildSteps.isEmpty())
  1118. buildSteps = map.value(QLatin1String("buildsteps")).toStringList();
  1119. int pos(0);
  1120. foreach (const QString &bs, buildSteps) {
  1121. // Watch out: Capitalization differs from oldBcKey!
  1122. const QString localKey(QLatin1String("buildconfiguration-") + bc + QString::fromLatin1("-buildstep") + QString::number(pos));
  1123. const QString globalKey(QString::fromLatin1("buildstep") + QString::number(pos));
  1124. QVariantMap local(map.value(localKey).toMap());
  1125. QVariantMap global(map.value(globalKey).toMap());
  1126. for (QVariantMap::const_iterator i = global.constBegin(); i != global.constEnd(); ++i) {
  1127. if (!local.contains(i.key()))
  1128. local.insert(i.key(), i.value());
  1129. if (i.key() == QLatin1String("ProjectExplorer.BuildConfiguration.DisplayName") &&
  1130. local.value(i.key()).toString().isEmpty())
  1131. local.insert(i.key(), i.value());
  1132. }
  1133. local.insert(QLatin1String("Id"), bs);
  1134. bcMap.insert(QString::fromLatin1("ProjectExplorer.BuildConfiguration.BuildStep.") + QString::number(pos),
  1135. convertBuildSteps(project, local));
  1136. ++pos;
  1137. }
  1138. bcMap.insert(QLatin1String("ProjectExplorer.BuildConfiguration.BuildStepsCount"), pos);
  1139. // cleansteps
  1140. QStringList cleanSteps(map.value(oldBcKey + QLatin1String("-cleansteps")).toStringList());
  1141. if (cleanSteps.isEmpty())
  1142. // try lowercase version, too:-(
  1143. cleanSteps = map.value(QString::fromLatin1("buildconfiguration-") + bc + QLatin1String("-cleansteps")).toStringList();
  1144. if (cleanSteps.isEmpty())
  1145. cleanSteps = map.value(QLatin1String("cleansteps")).toStringList();
  1146. pos = 0;
  1147. foreach (const QString &bs, cleanSteps) {
  1148. // Watch out: Capitalization differs from oldBcKey!
  1149. const QString localKey(QLatin1String("buildconfiguration-") + bc + QString::fromLatin1("-cleanstep") + QString::number(pos));
  1150. const QString globalKey(QString::fromLatin1("cleanstep") + QString::number(pos));
  1151. QVariantMap local(map.value(localKey).toMap());
  1152. QVariantMap global(map.value(globalKey).toMap());
  1153. for (QVariantMap::const_iterator i = global.constBegin(); i != global.constEnd(); ++i) {
  1154. if (!local.contains(i.key()))
  1155. local.insert(i.key(), i.value());
  1156. if (i.key() == QLatin1String("ProjectExplorer.BuildConfiguration.DisplayName") &&
  1157. local.value(i.key()).toString().isEmpty())
  1158. local.insert(i.key(), i.value());
  1159. }
  1160. local.insert(QLatin1String("Id"), bs);
  1161. bcMap.insert(QString::fromLatin1("ProjectExplorer.BuildConfiguration.CleanStep.") + QString::number(pos),
  1162. convertBuildSteps(project, local));
  1163. ++pos;
  1164. }
  1165. bcMap.insert(QLatin1String("ProjectExplorer.BuildConfiguration.CleanStepsCount"), pos);
  1166. // Merge into result set:
  1167. result.insert(QString::fromLatin1("ProjectExplorer.Project.BuildConfiguration.") + QString::number(count), bcMap);
  1168. ++count;
  1169. }
  1170. result.insert(QLatin1String("ProjectExplorer.Project.BuildConfigurationCount"), count);
  1171. // "RunConfiguration*":
  1172. active = map.value(QLatin1String("activeRunConfiguration")).toString();
  1173. count = 0;
  1174. forever {
  1175. QString prefix(QLatin1String("RunConfiguration") + QString::number(count) + QLatin1Char('-'));
  1176. QVariantMap rcMap;
  1177. for (QVariantMap::const_iterator i = map.constBegin(); i != map.constEnd(); ++i) {
  1178. if (!i.key().startsWith(prefix))
  1179. continue;
  1180. QString newKey(i.key().mid(prefix.size()));
  1181. rcMap.insert(newKey, i.value());
  1182. }
  1183. if (rcMap.isEmpty()) {
  1184. result.insert(QLatin1String("ProjectExplorer.Project.RunConfigurationCount"), count);
  1185. break;
  1186. }
  1187. result.insert(QString::fromLatin1("ProjectExplorer.Project.RunConfiguration.") + QString::number(count),
  1188. convertRunConfigurations(project, rcMap));
  1189. ++count;
  1190. }
  1191. // "defaultFileEncoding" (EditorSettings):
  1192. QVariant codecVariant(map.value(QLatin1String("defaultFileEncoding")));
  1193. if (codecVariant.isValid()) {
  1194. QByteArray codec(codecVariant.toByteArray());
  1195. QVariantMap editorSettingsMap;
  1196. editorSettingsMap.insert(QLatin1String("EditorConfiguration.Codec"), codec);
  1197. result.insert(QLatin1String("ProjectExplorer.Project.EditorSettings"),
  1198. editorSettingsMap);
  1199. }
  1200. QVariant toolchain(map.value(QLatin1String("toolChain")));
  1201. if (toolchain.isValid()) {
  1202. bool ok;
  1203. int type(toolchain.toInt(&ok));
  1204. if (!ok) {
  1205. QString toolChainName(toolchain.toString());
  1206. if (toolChainName == QLatin1String("gcc"))
  1207. type = 0;
  1208. else if (toolChainName == QLatin1String("mingw"))
  1209. type = 2;
  1210. else if (toolChainName == QLatin1String("msvc"))
  1211. type = 3;
  1212. else if (toolChainName == QLatin1String("wince"))
  1213. type = 4;
  1214. }
  1215. result.insert(QLatin1String("GenericProjectManager.GenericProject.Toolchain"), type);
  1216. }
  1217. return result;
  1218. }
  1219. // -------------------------------------------------------------------------
  1220. // Version1Handler
  1221. // -------------------------------------------------------------------------
  1222. QVariantMap Version1Handler::update(Project *project, const QVariantMap &map)
  1223. {
  1224. QVariantMap result;
  1225. // The only difference between version 1 and 2 of the user file is that
  1226. // we need to add targets.
  1227. // Generate a list of all possible targets for the project:
  1228. QList<TargetDescription> targets;
  1229. if (project->id() == Core::Id("GenericProjectManager.GenericProject"))
  1230. targets << TargetDescription(QString::fromLatin1("GenericProjectManager.GenericTarget"),
  1231. QCoreApplication::translate("GenericProjectManager::GenericTarget",
  1232. "Desktop",
  1233. "Generic desktop target display name"));
  1234. else if (project->id() == Core::Id("CMakeProjectManager.CMakeProject"))
  1235. targets << TargetDescription(QString::fromLatin1("CMakeProjectManager.DefaultCMakeTarget"),
  1236. QCoreApplication::translate("CMakeProjectManager::Internal::CMakeTarget",
  1237. "Desktop",
  1238. "CMake Default target display name"));
  1239. else if (project->id() == Core::Id("Qt4ProjectManager.Qt4Project"))
  1240. targets << TargetDescription(QString::fromLatin1("Qt4ProjectManager.Target.DesktopTarget"),
  1241. QCoreApplication::translate("Qt4ProjectManager::Internal::Qt4Target",
  1242. "Desktop",
  1243. "Qt4 Desktop target display name"))
  1244. << TargetDescription(QString::fromLatin1("Qt4ProjectManager.Target.S60EmulatorTarget"),
  1245. QCoreApplication::translate("Qt4ProjectManager::Internal::Qt4Target",
  1246. "Symbian Emulator",
  1247. "Qt4 Symbian Emulator target display name"))
  1248. << TargetDescription(QString::fromLatin1("Qt4ProjectManager.Target.S60DeviceTarget"),
  1249. QCoreApplication::translate("Qt4ProjectManager::Internal::Qt4Target",
  1250. "Symbian Device",
  1251. "Qt4 Symbian Device target display name"))
  1252. << TargetDescription(QString::fromLatin1("Qt4ProjectManager.Target.MaemoEmulatorTarget"),
  1253. QCoreApplication::translate("Qt4ProjectManager::Internal::Qt4Target",
  1254. "Maemo Emulator",
  1255. "Qt4 Maemo Emulator target display name"))
  1256. << TargetDescription(QString::fromLatin1("Qt4ProjectManager.Target.MaemoDeviceTarget"),
  1257. QCoreApplication::translate("Qt4ProjectManager::Internal::Qt4Target",
  1258. "Maemo Device",
  1259. "Qt4 Maemo Device target display name"));
  1260. else if (project->id() == Core::Id("QmlProjectManager.QmlProject"))
  1261. targets << TargetDescription(QString::fromLatin1("QmlProjectManager.QmlTarget"),
  1262. QCoreApplication::translate("QmlProjectManager::QmlTarget",
  1263. "QML Viewer",
  1264. "QML Viewer target display name"));
  1265. else
  1266. return QVariantMap(); // We do not know how to handle this.
  1267. result.insert(QLatin1String("ProjectExplorer.Project.ActiveTarget"), 0);
  1268. result.insert(QLatin1String("ProjectExplorer.Project.TargetCount"), targets.count());
  1269. int pos(0);
  1270. foreach (const TargetDescription &td, targets) {
  1271. QVariantMap targetMap;
  1272. // Do not set displayName or icon!
  1273. targetMap.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"), td.id);
  1274. int count = map.value(QLatin1String("ProjectExplorer.Project.BuildConfigurationCount")).toInt();
  1275. targetMap.insert(QLatin1String("ProjectExplorer.Target.BuildConfigurationCount"), count);
  1276. for (int i = 0; i < count; ++i) {
  1277. QString key(QString::fromLatin1("ProjectExplorer.Project.BuildConfiguration.") + QString::number(i));
  1278. if (map.contains(key)) {
  1279. QVariantMap bcMap = map.value(key).toMap();
  1280. if (!bcMap.contains(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild")))
  1281. bcMap.insert(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild"), false);
  1282. targetMap.insert(QString::fromLatin1("ProjectExplorer.Target.BuildConfiguration.") + QString::number(i),
  1283. bcMap);
  1284. }
  1285. }
  1286. count = map.value(QLatin1String("ProjectExplorer.Project.RunConfigurationCount")).toInt();
  1287. for (int i = 0; i < count; ++i) {
  1288. QString key(QString::fromLatin1("ProjectExplorer.Project.RunConfiguration.") + QString::number(i));
  1289. if (map.contains(key))
  1290. targetMap.insert(QString::fromLatin1("ProjectExplorer.Target.RunConfiguration.") + QString::number(i),
  1291. map.value(key));
  1292. }
  1293. if (map.contains(QLatin1String("ProjectExplorer.Project.ActiveBuildConfiguration")))
  1294. targetMap.insert(QLatin1String("ProjectExplorer.Target.ActiveBuildConfiguration"),
  1295. map.value(QLatin1String("ProjectExplorer.Project.ActiveBuildConfiguration")));
  1296. if (map.contains(QLatin1String("ProjectExplorer.Project.ActiveRunConfiguration")))
  1297. targetMap.insert(QLatin1String("ProjectExplorer.Target.ActiveRunConfiguration"),
  1298. map.value(QLatin1String("ProjectExplorer.Project.ActiveRunConfiguration")));
  1299. if (map.contains(QLatin1String("ProjectExplorer.Project.RunConfigurationCount")))
  1300. targetMap.insert(QLatin1String("ProjectExplorer.Target.RunConfigurationCount"),
  1301. map.value(QLatin1String("ProjectExplorer.Project.RunConfigurationCount")));
  1302. result.insert(QString::fromLatin1("ProjectExplorer.Project.Target.") + QString::number(pos), targetMap);
  1303. ++pos;
  1304. }
  1305. // copy everything else:
  1306. for (QVariantMap::const_iterator i = map.constBegin(); i != map.constEnd(); ++i) {
  1307. if (i.key() == QLatin1String("ProjectExplorer.Project.ActiveBuildConfiguration") ||
  1308. i.key() == QLatin1String("ProjectExplorer.Project.BuildConfigurationCount") ||
  1309. i.key() == QLatin1String("ProjectExplorer.Project.ActiveRunConfiguration") ||
  1310. i.key() == QLatin1String("ProjectExplorer.Project.RunConfigurationCount") ||
  1311. i.key().startsWith(QLatin1String("ProjectExplorer.Project.BuildConfiguration.")) ||
  1312. i.key().startsWith(QLatin1String("ProjectExplorer.Project.RunConfiguration.")))
  1313. continue;
  1314. result.insert(i.key(), i.value());
  1315. }
  1316. return result;
  1317. }
  1318. // -------------------------------------------------------------------------
  1319. // Version2Handler
  1320. // -------------------------------------------------------------------------
  1321. QVariantMap Version2Handler::update(Project *, const QVariantMap &map)
  1322. {
  1323. QList<Change> changes;
  1324. changes.append(qMakePair(QLatin1String("CMakeProjectManager.CMakeBuildConfiguration.UserEnvironmentChanges"),
  1325. QLatin1String("ProjectExplorer.BuildConfiguration.UserEnvironmentChanges")));
  1326. changes.append(qMakePair(QLatin1String("CMakeProjectManager.CMakeBuildConfiguration.ClearSystemEnvironment"),
  1327. QLatin1String("ProjectExplorer.BuildConfiguration.ClearSystemEnvironment")));
  1328. changes.append(qMakePair(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.UserEnvironmentChanges"),
  1329. QLatin1String("ProjectExplorer.BuildConfiguration.UserEnvironmentChanges")));
  1330. changes.append(qMakePair(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.ClearSystemEnvironment"),
  1331. QLatin1String("ProjectExplorer.BuildConfiguration.ClearSystemEnvironment")));
  1332. return renameKeys(changes, QVariantMap(map));
  1333. }
  1334. // -------------------------------------------------------------------------
  1335. // Version3Handler
  1336. // -------------------------------------------------------------------------
  1337. // insert the additional build step:
  1338. //<valuemap key="ProjectExplorer.BuildConfiguration.BuildStep.2" type="QVariantMap">
  1339. // <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">Create sis Package</value>
  1340. // <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.S60SignBuildStep</value>
  1341. // <value key="Qt4ProjectManager.MakeStep.Clean" type="bool">false</value>
  1342. // <valuelist key="Qt4ProjectManager.MakeStep.MakeArguments" type="QVariantList"/>
  1343. // <value key="Qt4ProjectManager.MakeStep.MakeCommand" type="QString"></value>
  1344. // <value key="Qt4ProjectManager.S60CreatePackageStep.Certificate" type="QString"></value>
  1345. // <value key="Qt4ProjectManager.S60CreatePackageStep.Keyfile" type="QString"></value>
  1346. // <value key="Qt4ProjectManager.S60CreatePackageStep.SignMode" type="int">0</value>
  1347. //</valuemap>
  1348. // remove the deprecated sign run settings from
  1349. //<valuemap key="ProjectExplorer.Target.RunConfiguration.0" type="QVariantMap">
  1350. // <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">untitled1 on Symbian Device</value>
  1351. // <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.S60DeviceRunConfiguration</value>
  1352. // <valuelist key="Qt4ProjectManager.S60DeviceRunConfiguration.CommandLineArguments" type="QVariantList"/>
  1353. // <value key="Qt4ProjectManager.S60DeviceRunConfiguration.CustomKeyPath" type="QString"></value>
  1354. // <value key="Qt4ProjectManager.S60DeviceRunConfiguration.CustomSignaturePath" type="QString"></value>
  1355. // <value key="Qt4ProjectManager.S60DeviceRunConfiguration.ProFile" type="QString">untitled1.pro</value>
  1356. // <value key="Qt4ProjectManager.S60DeviceRunConfiguration.SerialPortName" type="QString">COM3</value>
  1357. // <value key="Qt4ProjectManager.S60DeviceRunConfiguration.SigningMode" type="int">0</value>
  1358. //</valuemap>
  1359. QVariantMap Version3Handler::update(Project *, const QVariantMap &map)
  1360. {
  1361. QVariantMap result;
  1362. QMapIterator<QString, QVariant> it(map);
  1363. while (it.hasNext()) {
  1364. it.next();
  1365. const QString &targetKey = it.key();
  1366. // check for target info
  1367. if (!targetKey.startsWith(QLatin1String("ProjectExplorer.Project.Target."))) {
  1368. result.insert(targetKey, it.value());
  1369. continue;
  1370. }
  1371. const QVariantMap &originalTarget = it.value().toMap();
  1372. // check for symbian device target
  1373. if (originalTarget.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"))
  1374. != QLatin1String("Qt4ProjectManager.Target.S60DeviceTarget")) {
  1375. result.insert(targetKey, originalTarget);
  1376. continue;
  1377. }
  1378. QVariantMap newTarget;
  1379. // first iteration: search run configurations, get signing info, remove old signing keys
  1380. QString customKeyPath;
  1381. QString customSignaturePath;
  1382. int signingMode = 0; // SelfSign
  1383. QMapIterator<QString, QVariant> targetIt(originalTarget);
  1384. while (targetIt.hasNext()) {
  1385. targetIt.next();
  1386. const QString &key = targetIt.key();
  1387. if (key.startsWith(QLatin1String("ProjectExplorer.Target.BuildConfiguration."))) {
  1388. // build configurations are handled in second iteration
  1389. continue;
  1390. }
  1391. if (!key.startsWith(QLatin1String("ProjectExplorer.Target.RunConfiguration."))) {
  1392. newTarget.insert(key, targetIt.value());
  1393. continue;
  1394. }
  1395. QVariantMap runConfig = targetIt.value().toMap();
  1396. if (runConfig.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"))
  1397. != QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration")) {
  1398. newTarget.insert(key, runConfig);
  1399. continue;
  1400. }
  1401. // get signing info
  1402. customKeyPath = runConfig.value(QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration.CustomKeyPath")).toString();
  1403. customSignaturePath = runConfig.value(QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration.CustomSignaturePath")).toString();
  1404. signingMode = runConfig.value(QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration.SigningMode")).toInt();
  1405. // remove old signing keys
  1406. runConfig.remove(QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration.CustomKeyPath"));
  1407. runConfig.remove(QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration.CustomSignaturePath"));
  1408. runConfig.remove(QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration.SigningMode"));
  1409. newTarget.insert(key, runConfig);
  1410. }
  1411. // second iteration: add new signing build step
  1412. targetIt.toFront();
  1413. while (targetIt.hasNext()) {
  1414. targetIt.next();
  1415. const QString &key = targetIt.key();
  1416. if (!key.startsWith(QLatin1String("ProjectExplorer.Target.BuildConfiguration."))) {
  1417. // everything except build configs already handled
  1418. continue;
  1419. }
  1420. QVariantMap buildConfig = targetIt.value().toMap();
  1421. int stepCount = buildConfig.value(QLatin1String("ProjectExplorer.BuildConfiguration.BuildStepsCount")).toInt();
  1422. QVariantMap signBuildStep;
  1423. signBuildStep.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.DisplayName"), QLatin1String("Create SIS package"));
  1424. signBuildStep.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"), QLatin1String("Qt4ProjectManager.S60SignBuildStep"));
  1425. signBuildStep.insert(QLatin1String("Qt4ProjectManager.MakeStep.Clean"), false);
  1426. signBuildStep.insert(QLatin1String("Qt4ProjectManager.S60CreatePackageStep.Certificate"), customSignaturePath);
  1427. signBuildStep.insert(QLatin1String("Qt4ProjectManager.S60CreatePackageStep.Keyfile"), customKeyPath);
  1428. signBuildStep.insert(QLatin1String("Qt4ProjectManager.S60CreatePackageStep.SignMode"), signingMode);
  1429. buildConfig.insert(QString::fromLatin1("ProjectExplorer.BuildConfiguration.BuildStep.%1").arg(stepCount), signBuildStep);
  1430. buildConfig.insert(QLatin1String("ProjectExplorer.BuildConfiguration.BuildStepsCount"), stepCount + 1);
  1431. newTarget.insert(key, buildConfig);
  1432. }
  1433. result.insert(targetKey, newTarget);
  1434. }
  1435. return result;
  1436. }
  1437. // -------------------------------------------------------------------------
  1438. // Version4Handler
  1439. // -------------------------------------------------------------------------
  1440. // Move packaging steps from build steps into deploy steps
  1441. QVariantMap Version4Handler::update(Project *, const QVariantMap &map)
  1442. {
  1443. QVariantMap result;
  1444. QMapIterator<QString, QVariant> it(map);
  1445. while (it.hasNext()) {
  1446. it.next();
  1447. const QString &globalKey = it.key();
  1448. // check for target info
  1449. if (!globalKey.startsWith(QLatin1String("ProjectExplorer.Project.Target."))) {
  1450. result.insert(globalKey, it.value());
  1451. continue;
  1452. }
  1453. const QVariantMap &originalTarget = it.value().toMap();
  1454. // check for symbian and maemo device target
  1455. if (originalTarget.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"))
  1456. != QLatin1String("Qt4ProjectManager.Target.S60DeviceTarget")
  1457. && originalTarget.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"))
  1458. != QLatin1String("Qt4ProjectManager.Target.MaemoDeviceTarget"))
  1459. {
  1460. result.insert(globalKey, originalTarget);
  1461. continue;
  1462. }
  1463. QVariantMap newTarget;
  1464. QMapIterator<QString, QVariant> targetIt(originalTarget);
  1465. while (targetIt.hasNext()) {
  1466. targetIt.next();
  1467. const QString &targetKey = targetIt.key();
  1468. if (targetKey.startsWith(QLatin1String("ProjectExplorer.Target.RunConfiguration."))) {
  1469. const QVariantMap &runConfigMap = targetIt.value().toMap();
  1470. const QLatin1String maemoRcId("Qt4ProjectManager.MaemoRunConfiguration");
  1471. if (runConfigMap.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id")).toString()
  1472. == maemoRcId) {
  1473. QVariantMap newRunConfigMap;
  1474. for (QVariantMap::ConstIterator rcMapIt = runConfigMap.constBegin();
  1475. rcMapIt != runConfigMap.constEnd(); ++rcMapIt) {
  1476. const QLatin1String oldProFileKey(".ProFile");
  1477. if (rcMapIt.key() == oldProFileKey) {
  1478. newRunConfigMap.insert(maemoRcId + oldProFileKey,
  1479. rcMapIt.value());
  1480. } else {
  1481. newRunConfigMap.insert(rcMapIt.key(),
  1482. rcMapIt.value());
  1483. }
  1484. }
  1485. newTarget.insert(targetKey, newRunConfigMap);
  1486. continue;
  1487. }
  1488. }
  1489. if (!targetKey.startsWith(QLatin1String("ProjectExplorer.Target.BuildConfiguration."))) {
  1490. newTarget.insert(targetKey, targetIt.value());
  1491. continue;
  1492. }
  1493. bool movedBs = false;
  1494. const QVariantMap &originalBc = targetIt.value().toMap();
  1495. QVariantMap newBc;
  1496. QMapIterator<QString, QVariant> bcIt(originalBc);
  1497. while(bcIt.hasNext()) {
  1498. bcIt.next();
  1499. const QString &bcKey = bcIt.key();
  1500. if (!bcKey.startsWith(QLatin1String("ProjectExplorer.BuildConfiguration.BuildStep."))) {
  1501. newBc.insert(bcKey, bcIt.value());
  1502. continue;
  1503. }
  1504. const QVariantMap &buildStep = bcIt.value().toMap();
  1505. if ((buildStep.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id")).toString() ==
  1506. QLatin1String("Qt4ProjectManager.S60SignBuildStep"))
  1507. || (buildStep.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id")).toString() ==
  1508. QLatin1String("Qt4ProjectManager.MaemoPackageCreationStep"))) {
  1509. movedBs = true;
  1510. newBc.insert(QLatin1String("ProjectExplorer.BuildConfiguration.DeployStep.0"), buildStep);
  1511. } else {
  1512. newBc.insert(bcKey, buildStep);
  1513. }
  1514. }
  1515. if (movedBs) {
  1516. // adjust counts:
  1517. newBc.insert(QLatin1String("ProjectExplorer.BuildConfiguration.DeployStepsCount"), 1);
  1518. newBc.insert(QLatin1String("ProjectExplorer.BuildConfiguration.BuildStepsCount"),
  1519. newBc.value(QLatin1String("ProjectExplorer.BuildConfiguration.BuildStepsCount")).toInt() - 1);
  1520. }
  1521. newTarget.insert(targetKey, newBc);
  1522. }
  1523. result.insert(globalKey, newTarget);
  1524. }
  1525. return result;
  1526. }
  1527. // -------------------------------------------------------------------------
  1528. // Version5Handler
  1529. // -------------------------------------------------------------------------
  1530. // Move packaging steps from build steps into deploy steps
  1531. QVariantMap Version5Handler::update(Project *, const QVariantMap &map)
  1532. {
  1533. QVariantMap result;
  1534. QMapIterator<QString, QVariant> it(map);
  1535. while (it.hasNext()) {
  1536. it.next();
  1537. const QString &globalKey = it.key();
  1538. // check for target info
  1539. if (!globalKey.startsWith(QLatin1String("ProjectExplorer.Project.Target."))) {
  1540. result.insert(globalKey, it.value());
  1541. continue;
  1542. }
  1543. const QVariantMap &originalTarget = it.value().toMap();
  1544. // check for symbian and maemo device target
  1545. if (originalTarget.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"))
  1546. != QLatin1String("Qt4ProjectManager.Target.S60DeviceTarget")
  1547. && originalTarget.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"))
  1548. != QLatin1String("Qt4ProjectManager.Target.MaemoDeviceTarget")) {
  1549. result.insert(globalKey, originalTarget);
  1550. continue;
  1551. }
  1552. QVariantMap newTarget;
  1553. QMapIterator<QString, QVariant> targetIt(originalTarget);
  1554. while (targetIt.hasNext()) {
  1555. targetIt.next();
  1556. const QString &targetKey = targetIt.key();
  1557. if (!targetKey.startsWith(QLatin1String("ProjectExplorer.Target.BuildConfiguration."))) {
  1558. newTarget.insert(targetKey, targetIt.value());
  1559. continue;
  1560. }
  1561. const QVariantMap &originalBc = targetIt.value().toMap();
  1562. QVariantMap newBc = originalBc;
  1563. QVariantMap newDeployStep;
  1564. if (originalTarget.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"))
  1565. == QLatin1String("Qt4ProjectManager.Target.S60DeviceTarget")) {
  1566. newDeployStep.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"),
  1567. QLatin1String("Qt4ProjectManager.S60DeployStep"));
  1568. } else {
  1569. newDeployStep.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"),
  1570. QLatin1String("Qt4ProjectManager.MaemoDeployStep"));
  1571. }
  1572. int deployCount = newBc.value(QLatin1String("ProjectExplorer.BuildConfiguration.DeployStepsCount"), 0).toInt();
  1573. newBc.insert(QString::fromLatin1("ProjectExplorer.BuildConfiguration.DeployStep.") + QString::number(deployCount),
  1574. newDeployStep);
  1575. newBc.insert(QLatin1String("ProjectExplorer.BuildConfiguration.DeployStepsCount"), deployCount + 1);
  1576. newTarget.insert(targetKey, newBc);
  1577. }
  1578. result.insert(globalKey, newTarget);
  1579. }
  1580. return result;
  1581. }
  1582. // -------------------------------------------------------------------------
  1583. // Version6Handler
  1584. // -------------------------------------------------------------------------
  1585. // Introduce DeployConfiguration and BuildStepLists
  1586. QVariantMap Version6Handler::update(Project *, const QVariantMap &map)
  1587. {
  1588. QVariantMap result;
  1589. QMapIterator<QString, QVariant> it(map);
  1590. while (it.hasNext()) {
  1591. it.next();
  1592. const QString &globalKey = it.key();
  1593. // check for target info
  1594. if (!globalKey.startsWith(QLatin1String("ProjectExplorer.Project.Target."))) {
  1595. result.insert(globalKey, it.value());
  1596. continue;
  1597. }
  1598. QVariantMap newDc;
  1599. const QVariantMap &originalTarget = it.value().toMap();
  1600. QVariantMap newTarget;
  1601. QVariantMap deploySteps;
  1602. QString deploymentName = QCoreApplication::translate("ProjectExplorer::UserFileHandler", "No deployment");
  1603. QMapIterator<QString, QVariant> targetIt(originalTarget);
  1604. while (targetIt.hasNext()) {
  1605. targetIt.next();
  1606. const QString &targetKey = targetIt.key();
  1607. if (targetKey == QLatin1String("ProjectExplorer.ProjectConfiguration.Id")) {
  1608. if (targetIt.value().toString() == QLatin1String("Qt4ProjectManager.Target.MaemoDeviceTarget"))
  1609. deploymentName = QCoreApplication::translate("ProjectExplorer::UserFileHandler", "Deploy to Maemo device");
  1610. else if (targetIt.value().toString() == QLatin1String("Qt4ProjectManager.Target.S60DeviceTarget"))
  1611. deploymentName = QCoreApplication::translate("ProjectExplorer::UserFileHandler", "Deploy to Symbian device");
  1612. }
  1613. if (!targetKey.startsWith(QLatin1String("ProjectExplorer.Target.BuildConfiguration."))) {
  1614. newTarget.insert(targetKey, targetIt.value());
  1615. continue;
  1616. }
  1617. QVariantMap buildSteps;
  1618. QVariantMap cleanSteps;
  1619. const QVariantMap &originalBc = targetIt.value().toMap();
  1620. QVariantMap newBc;
  1621. QMapIterator<QString, QVariant> bcIt(originalBc);
  1622. while (bcIt.hasNext())
  1623. {
  1624. bcIt.next();
  1625. const QString &bcKey = bcIt.key();
  1626. if (bcKey.startsWith(QLatin1String("ProjectExplorer.BuildConfiguration.BuildStep."))) {
  1627. QString position = bcKey.mid(45);
  1628. buildSteps.insert(QString::fromLatin1("ProjectExplorer.BuildStepList.Step.") + position, bcIt.value());
  1629. continue;
  1630. }
  1631. if (bcKey.startsWith(QLatin1String("ProjectExplorer.BuildConfiguration.BuildStepsCount"))) {
  1632. buildSteps.insert(QLatin1String("ProjectExplorer.BuildStepList.StepsCount"), bcIt.value());
  1633. continue;
  1634. }
  1635. if (bcKey.startsWith(QLatin1String("ProjectExplorer.BuildConfiguration.CleanStep."))) {
  1636. QString position = bcKey.mid(45);
  1637. cleanSteps.insert(QString::fromLatin1("ProjectExplorer.BuildStepList.Step.") + position, bcIt.value());
  1638. continue;
  1639. }
  1640. if (bcKey.startsWith(QLatin1String("ProjectExplorer.BuildConfiguration.CleanStepsCount"))) {
  1641. cleanSteps.insert(QLatin1String("ProjectExplorer.BuildStepList.StepsCount"), bcIt.value());
  1642. continue;
  1643. }
  1644. if (bcKey.startsWith(QLatin1String("ProjectExplorer.BuildConfiguration.DeployStep."))) {
  1645. QString position = bcKey.mid(46);
  1646. deploySteps.insert(QString::fromLatin1("ProjectExplorer.BuildStepList.Step.") + position, bcIt.value());
  1647. continue;
  1648. }
  1649. if (bcKey.startsWith(QLatin1String("ProjectExplorer.BuildConfiguration.DeployStepsCount"))) {
  1650. deploySteps.insert(QLatin1String("ProjectExplorer.BuildStepList.StepsCount"), bcIt.value());
  1651. continue;
  1652. }
  1653. newBc.insert(bcKey, bcIt.value());
  1654. }
  1655. buildSteps.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.DisplayName"), QLatin1String("Build"));
  1656. buildSteps.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"), QLatin1String("ProjectExplorer.BuildSteps.Build"));
  1657. cleanSteps.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.DisplayName"), QLatin1String("Clean"));
  1658. cleanSteps.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"), QLatin1String("ProjectExplorer.BuildSteps.Clean"));
  1659. newBc.insert(QLatin1String("ProjectExplorer.BuildConfiguration.BuildStepList.0"), buildSteps);
  1660. newBc.insert(QLatin1String("ProjectExplorer.BuildConfiguration.BuildStepList.1"), cleanSteps);
  1661. newBc.insert(QLatin1String("ProjectExplorer.BuildConfiguration.BuildStepListCount"), 2);
  1662. newTarget.insert(targetKey, newBc);
  1663. }
  1664. // Only insert one deploy configuration:
  1665. deploySteps.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.DisplayName"), QLatin1String("Deploy"));
  1666. deploySteps.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"), QLatin1String("ProjectExplorer.BuildSteps.Deploy"));
  1667. newDc.insert(QLatin1String("ProjectExplorer.BuildConfiguration.BuildStepList.0"), deploySteps);
  1668. newDc.insert(QLatin1String("ProjectExplorer.BuildConfiguration.BuildStepListCount"), 1);
  1669. newDc.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.DisplayName"), deploymentName);
  1670. newDc.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"), QLatin1String("ProjectExplorer.DefaultDeployConfiguration"));
  1671. newTarget.insert(QLatin1String("ProjectExplorer.Target.DeployConfigurationCount"), 1);
  1672. newTarget.insert(QLatin1String("ProjectExplorer.Target.ActiveDeployConfiguration"), 0);
  1673. newTarget.insert(QLatin1String("ProjectExplorer.Target.DeployConfiguration.0"), newDc);
  1674. result.insert(globalKey, newTarget);
  1675. }
  1676. return result;
  1677. }
  1678. // -------------------------------------------------------------------------
  1679. // Version7Handler
  1680. // -------------------------------------------------------------------------
  1681. // new implementation of DeployConfiguration
  1682. QVariantMap Version7Handler::update(Project *, const QVariantMap &map)
  1683. {
  1684. QVariantMap result;
  1685. QMapIterator<QString, QVariant> it(map);
  1686. while (it.hasNext()) {
  1687. it.next();
  1688. const QString &globalKey = it.key();
  1689. // check for target info
  1690. if (!globalKey.startsWith(QLatin1String("ProjectExplorer.Project.Target."))) {
  1691. result.insert(globalKey, it.value());
  1692. continue;
  1693. }
  1694. const QVariantMap &originalTarget = it.value().toMap();
  1695. // check for symbian device target
  1696. if (originalTarget.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"))
  1697. != QLatin1String("Qt4ProjectManager.Target.S60DeviceTarget") ) {
  1698. result.insert(globalKey, originalTarget);
  1699. continue;
  1700. }
  1701. QVariantMap newTarget;
  1702. QMapIterator<QString, QVariant> targetIt(originalTarget);
  1703. while (targetIt.hasNext()) {
  1704. targetIt.next();
  1705. const QString &targetKey = targetIt.key();
  1706. if (targetKey.startsWith(QLatin1String("ProjectExplorer.Target.RunConfiguration."))) {
  1707. QVariantMap newRunConfiguration;
  1708. const QVariantMap &originalRc = targetIt.value().toMap();
  1709. QMapIterator<QString, QVariant> rcIt(originalRc);
  1710. while (rcIt.hasNext()) {
  1711. rcIt.next();
  1712. const QString &rcKey = rcIt.key();
  1713. // remove installation related data from RunConfiguration
  1714. if (rcKey.startsWith(QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration.InstallationDriveLetter"))) {
  1715. continue;
  1716. }
  1717. if (rcKey.startsWith(QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration.SerialPortName"))) {
  1718. continue;
  1719. }
  1720. if (rcKey.startsWith(QLatin1String("Qt4ProjectManager.S60DeviceRunConfiguration.SilentInstall"))) {
  1721. continue;
  1722. }
  1723. newRunConfiguration.insert(rcKey, rcIt.value());
  1724. }
  1725. newTarget.insert(targetKey, newRunConfiguration);
  1726. } else {
  1727. newTarget.insert(targetKey, targetIt.value());
  1728. continue;
  1729. }
  1730. }
  1731. result.insert(globalKey, newTarget);
  1732. }
  1733. return result;
  1734. }
  1735. // -------------------------------------------------------------------------
  1736. // Version8Handler
  1737. // -------------------------------------------------------------------------
  1738. // Argument list reinterpretation
  1739. static const char * const argListKeys[] = {
  1740. "ProjectExplorer.Project.Target.",
  1741. "ProjectExplorer.Target.BuildConfiguration."
  1742. "|ProjectExplorer.Target.DeployConfiguration.",
  1743. "ProjectExplorer.BuildConfiguration.BuildStepList.",
  1744. "ProjectExplorer.BuildStepList.Step.",
  1745. "GenericProjectManager.GenericMakeStep.MakeArguments",
  1746. "QtProjectManager.QMakeBuildStep.QMakeArguments",
  1747. "Qt4ProjectManager.MakeStep.MakeArguments",
  1748. "CMakeProjectManager.MakeStep.AdditionalArguments",
  1749. 0,
  1750. 0,
  1751. 0,
  1752. "ProjectExplorer.Target.RunConfiguration.",
  1753. "ProjectExplorer.CustomExecutableRunConfiguration.Arguments",
  1754. "Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments",
  1755. "CMakeProjectManager.CMakeRunConfiguration.Arguments",
  1756. 0,
  1757. 0,
  1758. 0
  1759. };
  1760. static const char * const lameArgListKeys[] = {
  1761. "ProjectExplorer.Project.Target.",
  1762. "ProjectExplorer.Target.BuildConfiguration."
  1763. "|ProjectExplorer.Target.DeployConfiguration.",
  1764. "ProjectExplorer.BuildConfiguration.BuildStepList.",
  1765. "ProjectExplorer.BuildStepList.Step.",
  1766. "ProjectExplorer.ProcessStep.Arguments",
  1767. 0,
  1768. 0,
  1769. 0,
  1770. "ProjectExplorer.Target.RunConfiguration.",
  1771. "Qt4ProjectManager.MaemoRunConfiguration.Arguments",
  1772. "Qt4ProjectManager.S60DeviceRunConfiguration.CommandLineArguments",
  1773. "QmlProjectManager.QmlRunConfiguration.QDeclarativeViewerArguments",
  1774. 0,
  1775. 0,
  1776. 0
  1777. };
  1778. #ifdef Q_OS_UNIX
  1779. inline static bool isSpecialChar(ushort c)
  1780. {
  1781. // Chars that should be quoted (TM). This includes:
  1782. static const uchar iqm[] = {
  1783. 0xff, 0xff, 0xff, 0xff, 0xdf, 0x07, 0x00, 0xd8,
  1784. 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x78
  1785. }; // 0-32 \'"$`<>|;&(){}*?#!~[]
  1786. return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)));
  1787. }
  1788. inline static bool hasSpecialChars(const QString &arg)
  1789. {
  1790. for (int x = arg.length() - 1; x >= 0; --x)
  1791. if (isSpecialChar(arg.unicode()[x].unicode()))
  1792. return true;
  1793. return false;
  1794. }
  1795. #endif
  1796. // These were split according to sane (even if a bit arcane) rules
  1797. static QVariant version8ArgNodeHandler(const QVariant &var)
  1798. {
  1799. QString ret;
  1800. foreach (const QVariant &svar, var.toList()) {
  1801. #ifdef Q_OS_UNIX
  1802. // We don't just addArg, so we don't disarm existing env expansions.
  1803. // This is a bit fuzzy logic ...
  1804. QString s = svar.toString();
  1805. s.replace(QLatin1Char('\\'), QLatin1String("\\\\"));
  1806. s.replace(QLatin1Char('"'), QLatin1String("\\\""));
  1807. s.replace(QLatin1Char('`'), QLatin1String("\\`"));
  1808. if (s != svar.toString() || hasSpecialChars(s))
  1809. s.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
  1810. Utils::QtcProcess::addArgs(&ret, s);
  1811. #else
  1812. // Under windows, env expansions cannot be quoted anyway.
  1813. Utils::QtcProcess::addArg(&ret, svar.toString());
  1814. #endif
  1815. }
  1816. return QVariant(ret);
  1817. }
  1818. // These were just split on whitespace
  1819. static QVariant version8LameArgNodeHandler(const QVariant &var)
  1820. {
  1821. QString ret;
  1822. foreach (const QVariant &svar, var.toList())
  1823. Utils::QtcProcess::addArgs(&ret, svar.toString());
  1824. return QVariant(ret);
  1825. }
  1826. // Environment variable reinterpretation
  1827. static const char * const envExpandedKeys[] = {
  1828. "ProjectExplorer.Project.Target.",
  1829. "ProjectExplorer.Target.BuildConfiguration."
  1830. "|ProjectExplorer.Target.DeployConfiguration.",
  1831. "ProjectExplorer.BuildConfiguration.BuildStepList.",
  1832. "ProjectExplorer.BuildStepList.Step.",
  1833. "ProjectExplorer.ProcessStep.WorkingDirectory",
  1834. "ProjectExplorer.ProcessStep.Command",
  1835. "ProjectExplorer.ProcessStep.Arguments",
  1836. "GenericProjectManager.GenericMakeStep.MakeCommand",
  1837. "GenericProjectManager.GenericMakeStep.MakeArguments",
  1838. "GenericProjectManager.GenericMakeStep.BuildTargets",
  1839. "QtProjectManager.QMakeBuildStep.QMakeArguments",
  1840. "Qt4ProjectManager.MakeStep.MakeCommand",
  1841. "Qt4ProjectManager.MakeStep.MakeArguments",
  1842. "CMakeProjectManager.MakeStep.AdditionalArguments",
  1843. "CMakeProjectManager.MakeStep.BuildTargets",
  1844. 0,
  1845. 0,
  1846. "Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory",
  1847. 0,
  1848. "ProjectExplorer.Target.RunConfiguration.",
  1849. "ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory",
  1850. "ProjectExplorer.CustomExecutableRunConfiguration.Executable",
  1851. "ProjectExplorer.CustomExecutableRunConfiguration.Arguments",
  1852. "Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory",
  1853. "Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments",
  1854. "Qt4ProjectManager.MaemoRunConfiguration.Arguments",
  1855. "Qt4ProjectManager.S60DeviceRunConfiguration.CommandLineArguments",
  1856. "CMakeProjectManager.CMakeRunConfiguration.UserWorkingDirectory",
  1857. "CMakeProjectManager.CMakeRunConfiguration.Arguments",
  1858. 0,
  1859. 0,
  1860. 0
  1861. };
  1862. static QString version8NewVar(const QString &old)
  1863. {
  1864. QString ret = old;
  1865. #ifdef Q_OS_UNIX
  1866. ret.prepend(QLatin1String("${"));
  1867. ret.append(QLatin1Char('}'));
  1868. #else
  1869. ret.prepend(QLatin1Char('%'));
  1870. ret.append(QLatin1Char('%'));
  1871. #endif
  1872. return ret;
  1873. }
  1874. // Translate DOS-like env var expansions into Unix-like ones and vice versa.
  1875. // On the way, change {SOURCE,BUILD}DIR env expansions to %{}-expandos
  1876. static QVariant version8EnvNodeTransform(const QVariant &var)
  1877. {
  1878. QString result = var.toString();
  1879. result.replace(QRegExp(QLatin1String("%SOURCEDIR%|\\$(SOURCEDIR\\b|\\{SOURCEDIR\\})")),
  1880. QLatin1String("%{sourceDir}"));
  1881. result.replace(QRegExp(QLatin1String("%BUILDDIR%|\\$(BUILDDIR\\b|\\{BUILDDIR\\})")),
  1882. QLatin1String("%{buildDir}"));
  1883. #ifdef Q_OS_UNIX
  1884. for (int vStart = -1, i = 0; i < result.length(); ) {
  1885. QChar c = result.at(i++);
  1886. if (c == QLatin1Char('%')) {
  1887. if (vStart > 0 && vStart < i - 1) {
  1888. QString nv = version8NewVar(result.mid(vStart, i - 1 - vStart));
  1889. result.replace(vStart - 1, i - vStart + 1, nv);
  1890. i = vStart - 1 + nv.length();
  1891. vStart = -1;
  1892. } else {
  1893. vStart = i;
  1894. }
  1895. } else if (vStart > 0) {
  1896. // Sanity check so we don't catch too much garbage
  1897. if (!c.isLetterOrNumber() && c != QLatin1Char('_'))
  1898. vStart = -1;
  1899. }
  1900. }
  1901. #else
  1902. enum { BASE, OPTIONALVARIABLEBRACE, VARIABLE, BRACEDVARIABLE } state = BASE;
  1903. int vStart = -1;
  1904. for (int i = 0; i < result.length();) {
  1905. QChar c = result.at(i++);
  1906. if (state == BASE) {
  1907. if (c == QLatin1Char('$'))
  1908. state = OPTIONALVARIABLEBRACE;
  1909. } else if (state == OPTIONALVARIABLEBRACE) {
  1910. if (c == QLatin1Char('{')) {
  1911. state = BRACEDVARIABLE;
  1912. vStart = i;
  1913. } else if (c.isLetterOrNumber() || c == QLatin1Char('_')) {
  1914. state = VARIABLE;
  1915. vStart = i - 1;
  1916. } else {
  1917. state = BASE;
  1918. }
  1919. } else if (state == BRACEDVARIABLE) {
  1920. if (c == QLatin1Char('}')) {
  1921. QString nv = version8NewVar(result.mid(vStart, i - 1 - vStart));
  1922. result.replace(vStart - 2, i - vStart + 2, nv);
  1923. i = vStart + nv.length();
  1924. state = BASE;
  1925. }
  1926. } else if (state == VARIABLE) {
  1927. if (!c.isLetterOrNumber() && c != QLatin1Char('_')) {
  1928. QString nv = version8NewVar(result.mid(vStart, i - 1 - vStart));
  1929. result.replace(vStart - 1, i - vStart, nv);
  1930. i = vStart - 1 + nv.length(); // On the same char - could be next expansion.
  1931. state = BASE;
  1932. }
  1933. }
  1934. }
  1935. if (state == VARIABLE) {
  1936. QString nv = version8NewVar(result.mid(vStart));
  1937. result.truncate(vStart - 1);
  1938. result += nv;
  1939. }
  1940. #endif
  1941. return QVariant(result);
  1942. }
  1943. static QVariant version8EnvNodeHandler(const QVariant &var)
  1944. {
  1945. if (var.type() != QVariant::List)
  1946. return version8EnvNodeTransform(var);
  1947. QVariantList vl;
  1948. foreach (const QVariant &svar, var.toList())
  1949. vl << version8EnvNodeTransform(svar);
  1950. return vl;
  1951. }
  1952. // VariableManager expando reinterpretation
  1953. static const char * const varExpandedKeys[] = {
  1954. "ProjectExplorer.Project.Target.",
  1955. "ProjectExplorer.Target.BuildConfiguration."
  1956. "|ProjectExplorer.Target.DeployConfiguration.",
  1957. "ProjectExplorer.BuildConfiguration.BuildStepList.",
  1958. "ProjectExplorer.BuildStepList.Step.",
  1959. "GenericProjectManager.GenericMakeStep.MakeCommand",
  1960. "GenericProjectManager.GenericMakeStep.MakeArguments",
  1961. "GenericProjectManager.GenericMakeStep.BuildTargets",
  1962. 0,
  1963. 0,
  1964. 0,
  1965. 0,
  1966. 0
  1967. };
  1968. // Translate old-style ${} var expansions into new-style %{} ones
  1969. static QVariant version8VarNodeTransform(const QVariant &var)
  1970. {
  1971. static const char * const vars[] = {
  1972. "absoluteFilePath",
  1973. "absolutePath",
  1974. "baseName",
  1975. "canonicalPath",
  1976. "canonicalFilePath",
  1977. "completeBaseName",
  1978. "completeSuffix",
  1979. "fileName",
  1980. "filePath",
  1981. "path",
  1982. "suffix"
  1983. };
  1984. static QSet<QString> map;
  1985. if (map.isEmpty())
  1986. for (unsigned i = 0; i < sizeof(vars)/sizeof(vars[0]); ++i)
  1987. map.insert(QLatin1String("CURRENT_DOCUMENT:") + QLatin1String(vars[i]));
  1988. QString str = var.toString();
  1989. int pos = 0;
  1990. forever {
  1991. int openPos = str.indexOf(QLatin1String("${"), pos);
  1992. if (openPos < 0)
  1993. break;
  1994. int varPos = openPos + 2;
  1995. int closePos = str.indexOf(QLatin1Char('}'), varPos);
  1996. if (closePos < 0)
  1997. break;
  1998. if (map.contains(str.mid(varPos, closePos - varPos)))
  1999. str[openPos] = QLatin1Char('%');
  2000. pos = closePos + 1;
  2001. }
  2002. return QVariant(str);
  2003. }
  2004. static QVariant version8VarNodeHandler(const QVariant &var)
  2005. {
  2006. if (var.type() != QVariant::List)
  2007. return version8VarNodeTransform(var);
  2008. QVariantList vl;
  2009. foreach (const QVariant &svar, var.toList())
  2010. vl << version8VarNodeTransform(svar);
  2011. return vl;
  2012. }
  2013. QVariantMap Version8Handler::update(Project *, const QVariantMap &map)
  2014. {
  2015. const char * const *p1 = argListKeys;
  2016. QVariantMap rmap1 = processHandlerNodes(buildHandlerNodes(&p1), map, version8ArgNodeHandler);
  2017. const char * const *p2 = lameArgListKeys;
  2018. QVariantMap rmap2 = processHandlerNodes(buildHandlerNodes(&p2), rmap1, version8LameArgNodeHandler);
  2019. const char * const *p3 = envExpandedKeys;
  2020. QVariantMap rmap3 = processHandlerNodes(buildHandlerNodes(&p3), rmap2, version8EnvNodeHandler);
  2021. const char * const *p4 = varExpandedKeys;
  2022. return processHandlerNodes(buildHandlerNodes(&p4), rmap3, version8VarNodeHandler);
  2023. }
  2024. QVariantMap Version9Handler::update(Project *project, const QVariantMap &map)
  2025. {
  2026. Q_UNUSED(project);
  2027. QVariantMap result;
  2028. QMapIterator<QString, QVariant> globalIt(map);
  2029. while (globalIt.hasNext()) {
  2030. globalIt.next();
  2031. const QString &globalKey = globalIt.key();
  2032. // check for target info
  2033. if (!globalKey.startsWith(QLatin1String("ProjectExplorer.Project.Target."))) {
  2034. result.insert(globalKey, globalIt.value());
  2035. continue;
  2036. }
  2037. const QVariantMap &origTargetMap = globalIt.value().toMap();
  2038. const QString targetIdKey
  2039. = QLatin1String("ProjectExplorer.ProjectConfiguration.Id");
  2040. // check for maemo device target
  2041. if (origTargetMap.value(targetIdKey)
  2042. != QLatin1String("Qt4ProjectManager.Target.MaemoDeviceTarget")
  2043. && origTargetMap.value(targetIdKey)
  2044. != QLatin1String("Qt4ProjectManager.Target.HarmattanDeviceTarget")
  2045. && origTargetMap.value(targetIdKey)
  2046. != QLatin1String("Qt4ProjectManager.Target.MeegoDeviceTarget"))
  2047. {
  2048. result.insert(globalKey, origTargetMap);
  2049. continue;
  2050. }
  2051. QVariantMap newTargetMap;
  2052. QMapIterator<QString, QVariant> targetIt(origTargetMap);
  2053. while (targetIt.hasNext()) {
  2054. targetIt.next();
  2055. if (!targetIt.key().startsWith(QLatin1String("ProjectExplorer.Target.DeployConfiguration."))) {
  2056. newTargetMap.insert(targetIt.key(), targetIt.value());
  2057. continue;
  2058. }
  2059. QVariantMap deployConfMap = targetIt.value().toMap();
  2060. deployConfMap.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"),
  2061. QLatin1String("2.2MaemoDeployConfig"));
  2062. newTargetMap.insert(targetIt.key(), deployConfMap);
  2063. }
  2064. result.insert(globalKey, newTargetMap);
  2065. }
  2066. return result;
  2067. }
  2068. QVariantMap Version10Handler::update(Project *project, const QVariantMap &map)
  2069. {
  2070. Q_UNUSED(project);
  2071. QList<Change> changes;
  2072. changes.append(qMakePair(QLatin1String("ProjectExplorer.ProcessStep.Enabled"),
  2073. QLatin1String("ProjectExplorer.BuildStep.Enabled")));
  2074. return renameKeys(changes, QVariantMap(map));
  2075. }
  2076. Version11Handler::Version11Handler()
  2077. { }
  2078. Version11Handler::~Version11Handler()
  2079. {
  2080. ProfileManager *pm = ProfileManager::instance();
  2081. if (!pm) // Can happen during teardown!
  2082. return;
  2083. QList<Profile *> knownProfiles = pm->profiles();
  2084. foreach (Profile *p, m_targets.keys()) {
  2085. if (!knownProfiles.contains(p))
  2086. delete p;
  2087. }
  2088. m_targets.clear();
  2089. }
  2090. QVariantMap Version11Handler::update(Project *project, const QVariantMap &map)
  2091. {
  2092. // Read in old data to help with the transition:
  2093. parseQtversionFile();
  2094. parseToolChainFile();
  2095. QVariantMap result;
  2096. ProfileManager *pm = ProfileManager::instance();
  2097. foreach (Profile *p, pm->profiles())
  2098. m_targets.insert(p, QVariantMap());
  2099. QMapIterator<QString, QVariant> globalIt(map);
  2100. int activeTarget = map.value(QLatin1String("ProjectExplorer.Project.ActiveTarget"), 0).toInt();
  2101. while (globalIt.hasNext()) {
  2102. globalIt.next();
  2103. const QString &globalKey = globalIt.key();
  2104. // Keep everything but targets:
  2105. if (!globalKey.startsWith(QLatin1String("ProjectExplorer.Project.Target."))) {
  2106. result.insert(globalKey, globalIt.value());
  2107. continue;
  2108. }
  2109. // Update Targets:
  2110. const QVariantMap &target = globalIt.value().toMap();
  2111. int targetPos = globalKey.mid(globalKey.lastIndexOf(QLatin1Char('.'))).toInt();
  2112. QVariantMap extraTargetData;
  2113. QList<QVariantMap> bcs;
  2114. int activeBc = -1;
  2115. QList<QVariantMap> dcs;
  2116. int activeDc = -1;
  2117. QList<QVariantMap> rcs;
  2118. int activeRc = -1;
  2119. // Read old target:
  2120. QMapIterator<QString, QVariant> targetIt(target);
  2121. while (targetIt.hasNext()) {
  2122. targetIt.next();
  2123. const QString &targetKey = targetIt.key();
  2124. // BuildConfigurations:
  2125. if (targetKey == QLatin1String("ProjectExplorer.Target.ActiveBuildConfiguration"))
  2126. activeBc = targetIt.value().toInt();
  2127. else if (targetKey == QLatin1String("ProjectExplorer.Target.BuildConfigurationCount"))
  2128. continue;
  2129. else if (targetKey.startsWith(QLatin1String("ProjectExplorer.Target.BuildConfiguration.")))
  2130. bcs.append(targetIt.value().toMap());
  2131. else
  2132. // DeployConfigurations:
  2133. if (targetKey == QLatin1String("ProjectExplorer.Target.ActiveDeployConfiguration"))
  2134. activeDc = targetIt.value().toInt();
  2135. else if (targetKey == QLatin1String("ProjectExplorer.Target.DeployConfigurationCount"))
  2136. continue;
  2137. else if (targetKey.startsWith(QLatin1String("ProjectExplorer.Target.DeployConfiguration.")))
  2138. dcs.append(targetIt.value().toMap());
  2139. else
  2140. // RunConfigurations:
  2141. if (targetKey == QLatin1String("ProjectExplorer.Target.ActiveRunConfiguration"))
  2142. activeRc = targetIt.value().toInt();
  2143. else if (targetKey == QLatin1String("ProjectExplorer.Target.RunConfigurationCount"))
  2144. continue;
  2145. else if (targetKey.startsWith(QLatin1String("ProjectExplorer.Target.RunConfiguration.")))
  2146. rcs.append(targetIt.value().toMap());
  2147. // Rest (the target's ProjectConfiguration settings only as there is nothing else):
  2148. else
  2149. extraTargetData.insert(targetKey, targetIt.value());
  2150. }
  2151. const QString targetId = extraTargetData.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id")).toString();
  2152. // Check each BCs/DCs and create profiles as needed
  2153. int bcPos = 0;
  2154. foreach (const QVariantMap &bc, bcs) {
  2155. const QString targetId = extraTargetData.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id")).toString();
  2156. Profile *tmp = new Profile;
  2157. tmp->setDisplayName(extraTargetData.value(QLatin1String("ProjectExplorer.ProjectConfiguration.DisplayName")).toString());
  2158. if (targetId == QLatin1String("Qt4ProjectManager.Target.AndroidDeviceTarget")) {
  2159. tmp->setIconPath(QLatin1String(":/android/images/QtAndroid.png"));
  2160. // use default device type
  2161. } else if (targetId == QLatin1String("RemoteLinux.EmbeddedLinuxTarget")) {
  2162. // use default icon
  2163. tmp->setValue(Core::Id("PE.Profile.DeviceType"), QString::fromLatin1("GenericLinuxOsType"));
  2164. } else if (targetId == QLatin1String("Qt4ProjectManager.Target.HarmattanDeviceTarget")) {
  2165. tmp->setIconPath(QLatin1String(":/projectexplorer/images/MaemoDevice.png"));
  2166. tmp->setValue(Core::Id("PE.Profile.DeviceType"), QString::fromLatin1("HarmattanOsType"));
  2167. } else if (targetId == QLatin1String("Qt4ProjectManager.Target.MaemoDeviceTarget")) {
  2168. tmp->setIconPath(QLatin1String(":/projectexplorer/images/MaemoDevice.png"));
  2169. tmp->setValue(Core::Id("PE.Profile.DeviceType"), QString::fromLatin1("Maemo5OsType"));
  2170. } else if (targetId == QLatin1String("Qt4ProjectManager.Target.MeegoDeviceTarget")) {
  2171. tmp->setIconPath(QLatin1String(":/projectexplorer/images/MaemoDevice.png"));
  2172. tmp->setValue(Core::Id("PE.Profile.DeviceType"), QString::fromLatin1("MeegoOsType"));
  2173. } else if (targetId == QLatin1String("Qt4ProjectManager.Target.S60DeviceTarget")) {
  2174. tmp->setIconPath(QLatin1String(":/projectexplorer/images/SymbianDevice.png"));
  2175. tmp->setValue(Core::Id("PE.Profile.DeviceType"), QString::fromLatin1("Qt4ProjectManager.SymbianDevice"));
  2176. tmp->setValue(Core::Id("PE.Profile.Device"), QString::fromLatin1("Symbian Device"));
  2177. } else if (targetId == QLatin1String("Qt4ProjectManager.Target.QtSimulatorTarget")) {
  2178. tmp->setIconPath(QLatin1String(":/projectexplorer/images/SymbianEmulator.png"));
  2179. // use default device type
  2180. } else {
  2181. // use default desktop icon and device type
  2182. tmp->setValue(Core::Id("PE.Profile.Device"), QString::fromLatin1("Desktop Device"));
  2183. }
  2184. // Tool chain
  2185. QString tcId = bc.value(QLatin1String("CMakeProjectManager.CMakeBuildConfiguration.ToolChain")).toString();
  2186. if (tcId.isEmpty())
  2187. tcId = bc.value(QLatin1String("ProjectExplorer.BuildCOnfiguration.ToolChain")).toString();
  2188. const QString origTcId = tcId;
  2189. tcId.replace(QLatin1String("Qt4ProjectManager.ToolChain.Maemo:"),
  2190. QLatin1String("ProjectExplorer.ToolChain.Gcc:")); // convert Maemo to GCC
  2191. tmp->setValue(Core::Id("PE.Profile.ToolChain"), tcId);
  2192. // QtVersion
  2193. int qtVersionId = bc.value(QLatin1String("Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId"), -1).toInt();
  2194. tmp->setValue(Core::Id("QtSupport.QtInformation"), qtVersionId);
  2195. // Debugger + mkspec
  2196. if (m_toolChainExtras.contains(origTcId)) {
  2197. Utils::Environment env = Utils::Environment::systemEnvironment();
  2198. QString debugger = m_toolChainExtras.value(origTcId).m_debugger;
  2199. if (!debugger.isEmpty() && !QFileInfo(debugger).isAbsolute())
  2200. debugger = env.searchInPath(debugger);
  2201. tmp->setValue(Core::Id("Debugger.Information"), debugger);
  2202. tmp->setValue(Core::Id("QtPM4.mkSpecInformation"), m_toolChainExtras.value(origTcId).m_mkspec);
  2203. }
  2204. // SysRoot
  2205. if (m_qtVersionExtras.contains(qtVersionId))
  2206. tmp->setValue(Core::Id("PE.Profile.SysRoot"), m_qtVersionExtras.value(qtVersionId));
  2207. // Device
  2208. QString devId;
  2209. foreach (const QVariantMap &dc, dcs) {
  2210. devId = dc.value(QLatin1String("Qt4ProjectManager.MaemoRunConfiguration.DeviceId")).toString();
  2211. if (!devId.isEmpty())
  2212. break;
  2213. }
  2214. if (devId.isEmpty()) {
  2215. if (targetId == QLatin1String("Qt4ProjectManager.Target.S60DeviceTarget"))
  2216. devId = QByteArray("Symbian Device");
  2217. else
  2218. devId = QByteArray("Desktop Device");
  2219. }
  2220. if (!devId.isEmpty() && !DeviceManager::instance()->find(Core::Id(devId))) // We do not know that device
  2221. devId.clear();
  2222. tmp->setValue(Core::Id("PE.Profile.Device"), devId);
  2223. addBuildConfiguration(targetId, tmp, activeTarget == targetPos, bc, bcPos == activeBc);
  2224. ++bcPos;
  2225. } // bcs
  2226. addOtherConfiguration(targetId, dcs, activeDc, rcs, activeRc, project->projectDirectory());
  2227. }
  2228. int newPos = 0;
  2229. QList<Profile *> knownProfiles = pm->profiles();
  2230. // Generate new target data:
  2231. foreach (Profile *p, m_targets.keys()) {
  2232. QVariantMap data = m_targets.value(p);
  2233. if (data.isEmpty())
  2234. continue;
  2235. if (!knownProfiles.contains(p))
  2236. pm->registerProfile(p);
  2237. data.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"), p->id().name());
  2238. data.insert(QLatin1String("ProjectExplorer.Target.Profile"), p->id().name());
  2239. data.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.DisplayName"), p->displayName());
  2240. data.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.DefaultDisplayName"), p->displayName());
  2241. result.insert(QString::fromLatin1("ProjectExplorer.Project.Target.") + QString::number(newPos), data);
  2242. if (data.value(QLatin1String("IsActive"), false).toBool())
  2243. result.insert(QLatin1String("ProjectExplorer.Project.ActiveTarget"), newPos);
  2244. ++newPos;
  2245. }
  2246. result.insert(QLatin1String("ProjectExplorer.Project.TargetCount"), newPos);
  2247. return result;
  2248. }
  2249. void Version11Handler::addBuildConfiguration(const QString &origTarget, Profile *p, bool targetActive,
  2250. const QVariantMap &bc, bool bcActive)
  2251. {
  2252. foreach (Profile *i, m_targets.keys()) {
  2253. const QString tc = i->value(Core::Id("PE.Profile.ToolChain")).toString();
  2254. const int qt = i->value(Core::Id("QtSupport.QtInformation")).toInt();
  2255. const QString debugger = i->value(Core::Id("Debugger.Information")).toString();
  2256. const QString mkspec = i->value(Core::Id("QtPM4.mkSpecInformation")).toString();
  2257. if ((i->value(Core::Id("PE.Profile.DeviceType")).toString() == p->value(Core::Id("PE.Profile.DeviceType")).toString())
  2258. && (tc.isEmpty() || (tc == p->value(Core::Id("PE.Profile.ToolChain")).toString()))
  2259. && (qt < 0 || (qt == p->value(Core::Id("QtSupport.QtInformation")).toInt()))
  2260. && (debugger.isEmpty() || (debugger == p->value(Core::Id("Debugger.Information")).toString()))
  2261. && (mkspec.isEmpty() || (mkspec == p->value(Core::Id("QtPM4.mkSpecInformation")).toString()))
  2262. && (i->value(Core::Id("PE.Profile.SysRoot")).toString() == p->value(Core::Id("PE.Profile.SysRoot")).toString())) {
  2263. delete p;
  2264. p = i;
  2265. }
  2266. }
  2267. QVariantMap merged = m_targets.value(p);
  2268. int bcCount = merged.value(QLatin1String("ProjectExplorer.Target.BuildConfigurationCount"), 0).toInt();
  2269. merged.insert(QString::fromLatin1("ProjectExplorer.Target.BuildConfiguration.") + QString::number(bcCount), bc);
  2270. if (bcActive)
  2271. merged.insert(QLatin1String("ProjectExplorer.Target.ActiveBuildConfiguration"), bcCount);
  2272. merged.insert(QLatin1String("ProjectExplorer.Target.BuildConfigurationCount"), bcCount + 1);
  2273. if (targetActive && bcActive)
  2274. merged.insert(QLatin1String("Update.IsActive"), true);
  2275. merged.insert(QLatin1String("Update.OriginalTarget"), origTarget);
  2276. m_targets.insert(p, merged);
  2277. }
  2278. void Version11Handler::addOtherConfiguration(const QString &origTarget,
  2279. const QList<QVariantMap> &dcs, int activeDc,
  2280. const QList<QVariantMap> &rcs, int activeRc,
  2281. const QString &projectDir)
  2282. {
  2283. foreach (Profile *tmp, m_targets.keys()) {
  2284. QVariantMap data = m_targets.value(tmp);
  2285. if (data.isEmpty())
  2286. continue;
  2287. const QString dataTarget = data.value(QLatin1String("Update.OriginalTarget")).toString();
  2288. if (dataTarget != origTarget)
  2289. continue;
  2290. int dcCount = dcs.count();
  2291. data.insert(QLatin1String("ProjectExplorer.Target.DeployConfigurationCount"), dcCount);
  2292. for (int i = 0; i < dcCount; ++i)
  2293. data.insert(QString::fromLatin1("ProjectExplorer.Target.DeployConfiguration.") + QString::number(i), dcs.at(i));
  2294. data.insert(QLatin1String("ProjectExplorer.Target.ActiveDeployConfiguration"), activeDc);
  2295. int rcCount = rcs.count();
  2296. data.insert(QLatin1String("ProjectExplorer.Target.RunConfigurationCount"), rcCount);
  2297. for (int i = 0; i < rcCount; ++i) {
  2298. QVariantMap rcData = rcs.at(i);
  2299. QString proFile = rcData.value(QLatin1String("Qt4ProjectManager.MaemoRunConfiguration.ProFile")).toString();
  2300. if (proFile.isEmpty())
  2301. proFile = rcData.value(QLatin1String("Qt4ProjectManager.Qt4RunConfiguration.ProFile")).toString();
  2302. if (!proFile.isEmpty()) {
  2303. QString newId = rcData.value(QLatin1String("ProjectExplorer.ProjectConfiguration.Id")).toString();
  2304. newId.append(QLatin1Char(':'));
  2305. Utils::FileName fn = Utils::FileName::fromString(projectDir);
  2306. fn.appendPath(proFile);
  2307. newId.append(fn.toString());
  2308. rcData.insert(QLatin1String("ProjectExplorer.ProjectConfiguration.Id"), newId);
  2309. }
  2310. data.insert(QString::fromLatin1("ProjectExplorer.Target.RunConfiguration.") + QString::number(i), rcData);
  2311. }
  2312. data.insert(QLatin1String("ProjectExplorer.Target.ActiveRunConfiguration"), activeRc);
  2313. m_targets.insert(tmp, data);
  2314. }
  2315. }
  2316. static QString targetRoot(const QString &qmakePath)
  2317. {
  2318. #ifdef Q_OS_WIN
  2319. Qt::CaseSensitivity cs = Qt::CaseInsensitive;
  2320. const QString binQmake = "/bin/qmake.exe";
  2321. #else
  2322. Qt::CaseSensitivity cs = Qt::CaseSensitive;
  2323. const QString binQmake = "/bin/qmake";
  2324. #endif
  2325. return QDir::cleanPath(qmakePath).remove(binQmake, cs);
  2326. }
  2327. static QString maddeRoot(const QString &qmakePath)
  2328. {
  2329. QDir dir(targetRoot(qmakePath));
  2330. dir.cdUp(); dir.cdUp();
  2331. return dir.absolutePath();
  2332. }
  2333. void Version11Handler::parseQtversionFile()
  2334. {
  2335. ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
  2336. QFileInfo settingsLocation(pm->settings()->fileName());
  2337. QString fileName = settingsLocation.absolutePath() + QLatin1String("/qtversion.xml");
  2338. Utils::PersistentSettingsReader reader;
  2339. if (!reader.load(fileName)) {
  2340. qWarning("Failed to open legacy qtversions.xml file.");
  2341. return;
  2342. }
  2343. QVariantMap data = reader.restoreValues();
  2344. int count = data.value(QLatin1String("QtVersion.Count"), 0).toInt();
  2345. for (int i = 0; i < count; ++i) {
  2346. const QString key = QString::fromLatin1("QtVersion.") + QString::number(i);
  2347. if (!data.contains(key))
  2348. continue;
  2349. const QVariantMap qtversionMap = data.value(key).toMap();
  2350. QString sysRoot = qtversionMap.value(QLatin1String("SystemRoot")).toString();
  2351. const QString type = qtversionMap.value(QLatin1String("QtVersion.Type")).toString();
  2352. const QString qmake = qtversionMap.value(QLatin1String("QMakePath")).toString();
  2353. if (type == QLatin1String("Qt4ProjectManager.QtVersion.Maemo")) {
  2354. QFile file(QDir::cleanPath(targetRoot(qmake)) + QLatin1String("/information"));
  2355. if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text)) {
  2356. QTextStream stream(&file);
  2357. while (!stream.atEnd()) {
  2358. const QString &line = stream.readLine().trimmed();
  2359. const QStringList &list = line.split(QLatin1Char(' '));
  2360. if (list.count() <= 1)
  2361. continue;
  2362. if (list.at(0) == QLatin1String("sysroot")) {
  2363. sysRoot = maddeRoot(qmake) + QLatin1String("/sysroots/") + list.at(1);
  2364. }
  2365. }
  2366. }
  2367. }
  2368. int id = qtversionMap.value(QLatin1String("Id")).toInt();
  2369. if (id > -1 && !sysRoot.isEmpty())
  2370. m_qtVersionExtras.insert(id, sysRoot);
  2371. }
  2372. }
  2373. void Version11Handler::parseToolChainFile()
  2374. {
  2375. ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
  2376. QFileInfo settingsLocation(pm->settings()->fileName());
  2377. QString fileName = settingsLocation.absolutePath() + QLatin1String("/toolChains.xml");
  2378. Utils::PersistentSettingsReader reader;
  2379. if (!reader.load(fileName)) {
  2380. qWarning("Failed to open legacy toolChains.xml file.");
  2381. return;
  2382. }
  2383. QVariantMap data = reader.restoreValues();
  2384. int count = data.value(QLatin1String("ToolChain.Count"), 0).toInt();
  2385. for (int i = 0; i < count; ++i) {
  2386. const QString key = QString::fromLatin1("ToolChain.") + QString::number(i);
  2387. if (!data.contains(key))
  2388. continue;
  2389. const QVariantMap tcMap = data.value(key).toMap();
  2390. QString id = tcMap.value(QLatin1String("ProjectExplorer.ToolChain.Id")).toString();
  2391. if (id.isEmpty())
  2392. continue;
  2393. QString mkspec = tcMap.value(QLatin1String("ProjectExplorer.ToolChain.MkSpecOverride")).toString();
  2394. QString debugger = tcMap.value(QLatin1String("ProjectExplorer.GccToolChain.Debugger")).toString();
  2395. m_toolChainExtras.insert(id, ToolChainExtraData(mkspec, debugger));
  2396. }
  2397. }