PageRenderTime 78ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 1ms

/src/plugins/projectexplorer/settingsaccessor.cpp

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