From 71e27450b6da9f4cedfdb09caa23b8f035f9d6cf Mon Sep 17 00:00:00 2001 From: Daniel Teske <daniel.teske@nokia.com> Date: Fri, 24 Feb 2012 17:17:49 +0100 Subject: [PATCH] React to qt versions changes on the project setup page. Since the project setup now hapens in the projects mode, we need to consider the user using the qt options dialog. The TargetSetupPage owns the temporary qt versions created for importing. The individual Qt4TargetSetupWidgets hold pointers to those temporary qt version. Thus the TargetSetupPage needs to inform the widgets when a pointer becomes invalid or a already existing id needs to be replaced by a temporary qt version. The interface of Qt4TargetSetupWidget is now pretty bad and doesn't really work. Task-Number: QTCREATORBUG-7020 Change-Id: I08799e482cb8f7f7b86c1bc14a0aabd444eee5d8 Reviewed-by: Tobias Hunger <tobias.hunger@nokia.com> --- src/plugins/madde/qt4maemotargetfactory.cpp | 6 +- .../buildconfigurationinfo.h | 27 +- .../qt-desktop/qt4desktoptargetfactory.cpp | 6 +- .../qt-desktop/qt4simulatortargetfactory.cpp | 6 +- .../qt-s60/qt4symbiantargetfactory.cpp | 10 +- src/plugins/qt4projectmanager/qt4target.cpp | 247 +++++++++++++----- src/plugins/qt4projectmanager/qt4target.h | 19 +- .../qt4projectmanager/qt4targetsetupwidget.h | 12 +- .../wizards/targetsetuppage.cpp | 138 +++++++++- .../wizards/targetsetuppage.h | 7 +- .../embeddedlinuxtargetfactory.cpp | 6 +- 11 files changed, 375 insertions(+), 109 deletions(-) diff --git a/src/plugins/madde/qt4maemotargetfactory.cpp b/src/plugins/madde/qt4maemotargetfactory.cpp index 4879165803f..f2ab143512a 100644 --- a/src/plugins/madde/qt4maemotargetfactory.cpp +++ b/src/plugins/madde/qt4maemotargetfactory.cpp @@ -179,8 +179,8 @@ ProjectExplorer::Target *Qt4MaemoTargetFactory::create(ProjectExplorer::Project QtSupport::BaseQtVersion::QmakeBuildConfigs config = qtVersion->defaultBuildConfig(); QList<BuildConfigurationInfo> infos; - infos.append(BuildConfigurationInfo(qtVersion, config, QString(), QString())); - infos.append(BuildConfigurationInfo(qtVersion, config ^ QtSupport::BaseQtVersion::DebugBuild, QString(), QString())); + infos.append(BuildConfigurationInfo(qtVersion->uniqueId(), config, QString(), QString())); + infos.append(BuildConfigurationInfo(qtVersion->uniqueId(), config ^ QtSupport::BaseQtVersion::DebugBuild, QString(), QString())); return create(parent, id, infos); } @@ -208,7 +208,7 @@ ProjectExplorer::Target *Qt4MaemoTargetFactory::create(ProjectExplorer::Project foreach (const BuildConfigurationInfo &info, infos) target->addQt4BuildConfiguration(msgBuildConfigurationName(info), QString(), - info.version, info.buildConfig, + info.version(), info.buildConfig, info.additionalArguments, info.directory, info.importing); foreach (const QString &deployConfigId, deployConfigIds) { diff --git a/src/plugins/qt4projectmanager/buildconfigurationinfo.h b/src/plugins/qt4projectmanager/buildconfigurationinfo.h index c37e5c1a8ec..bc0f3a2859a 100644 --- a/src/plugins/qt4projectmanager/buildconfigurationinfo.h +++ b/src/plugins/qt4projectmanager/buildconfigurationinfo.h @@ -40,35 +40,44 @@ namespace Qt4ProjectManager { struct QT4PROJECTMANAGER_EXPORT BuildConfigurationInfo { explicit BuildConfigurationInfo() - : version(0), buildConfig(QtSupport::BaseQtVersion::QmakeBuildConfig(0)), importing(false), temporaryQtVersion(false) + : qtVersionId(-1), buildConfig(QtSupport::BaseQtVersion::QmakeBuildConfig(0)), importing(false), temporaryQtVersion(0) {} - explicit BuildConfigurationInfo(QtSupport::BaseQtVersion *v, QtSupport::BaseQtVersion::QmakeBuildConfigs bc, - const QString &aa, const QString &d, bool importing_ = false, bool temporaryQtVersion_ = false) : - version(v), buildConfig(bc), additionalArguments(aa), directory(d), importing(importing_), temporaryQtVersion(temporaryQtVersion_) + explicit BuildConfigurationInfo(int v, QtSupport::BaseQtVersion::QmakeBuildConfigs bc, + const QString &aa, const QString &d, + bool importing_ = false, + QtSupport::BaseQtVersion *temporaryQtVersion_ = 0, + const QString &makefile_ = QString()) + : qtVersionId(v), buildConfig(bc), + additionalArguments(aa), directory(d), + importing(importing_), temporaryQtVersion(temporaryQtVersion_), + makefile(makefile_) { } bool isValid() const { - return version != 0; + return version() != 0; } bool operator ==(const BuildConfigurationInfo &other) const { - return version == other.version + return qtVersionId == other.qtVersionId && buildConfig == other.buildConfig && additionalArguments == other.additionalArguments && directory == other.directory && importing == other.importing - && temporaryQtVersion == other.temporaryQtVersion; + && temporaryQtVersion == other.temporaryQtVersion + && makefile == other.makefile; } + QtSupport::BaseQtVersion *version() const; - QtSupport::BaseQtVersion *version; + int qtVersionId; QtSupport::BaseQtVersion::QmakeBuildConfigs buildConfig; QString additionalArguments; QString directory; bool importing; - bool temporaryQtVersion; + QtSupport::BaseQtVersion *temporaryQtVersion; + QString makefile; static QList<BuildConfigurationInfo> importBuildConfigurations(const QString &proFilePath); static QList<BuildConfigurationInfo> checkForBuild(const QString &directory, const QString &proFilePath); diff --git a/src/plugins/qt4projectmanager/qt-desktop/qt4desktoptargetfactory.cpp b/src/plugins/qt4projectmanager/qt-desktop/qt4desktoptargetfactory.cpp index 06df7004a09..7e49cce9396 100644 --- a/src/plugins/qt4projectmanager/qt-desktop/qt4desktoptargetfactory.cpp +++ b/src/plugins/qt4projectmanager/qt-desktop/qt4desktoptargetfactory.cpp @@ -158,8 +158,8 @@ ProjectExplorer::Target *Qt4DesktopTargetFactory::create(ProjectExplorer::Projec QtSupport::BaseQtVersion::QmakeBuildConfigs config = qtVersion->defaultBuildConfig(); QList<BuildConfigurationInfo> infos; - infos.append(BuildConfigurationInfo(qtVersion, config, QString(), QString())); - infos.append(BuildConfigurationInfo(qtVersion, config ^ QtSupport::BaseQtVersion::DebugBuild, QString(), QString())); + infos.append(BuildConfigurationInfo(qtVersion->uniqueId(), config, QString(), QString())); + infos.append(BuildConfigurationInfo(qtVersion->uniqueId(), config ^ QtSupport::BaseQtVersion::DebugBuild, QString(), QString())); return create(parent, id, infos); } @@ -183,7 +183,7 @@ ProjectExplorer::Target *Qt4DesktopTargetFactory::create(ProjectExplorer::Projec foreach (const BuildConfigurationInfo &info, infos) t->addQt4BuildConfiguration(msgBuildConfigurationName(info), QString(), - info.version, info.buildConfig, + info.version(), info.buildConfig, info.additionalArguments, info.directory, info.importing); t->addDeployConfiguration(t->createDeployConfiguration(QLatin1String(ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID))); diff --git a/src/plugins/qt4projectmanager/qt-desktop/qt4simulatortargetfactory.cpp b/src/plugins/qt4projectmanager/qt-desktop/qt4simulatortargetfactory.cpp index 71ecce00e4a..0f70c0aa38b 100644 --- a/src/plugins/qt4projectmanager/qt-desktop/qt4simulatortargetfactory.cpp +++ b/src/plugins/qt4projectmanager/qt-desktop/qt4simulatortargetfactory.cpp @@ -144,8 +144,8 @@ ProjectExplorer::Target *Qt4SimulatorTargetFactory::create(ProjectExplorer::Proj QtSupport::BaseQtVersion *qtVersion = knownVersions.first(); QtSupport::BaseQtVersion::QmakeBuildConfigs config = qtVersion->defaultBuildConfig(); QList<BuildConfigurationInfo> infos; - infos.append(BuildConfigurationInfo(qtVersion, config, QString(), QString())); - infos.append(BuildConfigurationInfo(qtVersion, config ^ QtSupport::BaseQtVersion::DebugBuild, QString(), QString())); + infos.append(BuildConfigurationInfo(qtVersion->uniqueId(), config, QString(), QString())); + infos.append(BuildConfigurationInfo(qtVersion->uniqueId(), config ^ QtSupport::BaseQtVersion::DebugBuild, QString(), QString())); return create(parent, id, infos); } @@ -159,7 +159,7 @@ ProjectExplorer::Target *Qt4SimulatorTargetFactory::create(ProjectExplorer::Proj Qt4SimulatorTarget *t = new Qt4SimulatorTarget(static_cast<Qt4Project *>(parent), id); foreach (const BuildConfigurationInfo &info, infos) - t->addQt4BuildConfiguration(msgBuildConfigurationName(info), QString(), info.version, info.buildConfig, + t->addQt4BuildConfiguration(msgBuildConfigurationName(info), QString(), info.version(), info.buildConfig, info.additionalArguments, info.directory, info.importing); t->addDeployConfiguration(t->createDeployConfiguration(QLatin1String(ProjectExplorer::Constants::DEFAULT_DEPLOYCONFIGURATION_ID))); diff --git a/src/plugins/qt4projectmanager/qt-s60/qt4symbiantargetfactory.cpp b/src/plugins/qt4projectmanager/qt-s60/qt4symbiantargetfactory.cpp index 228dc0a501c..6b7febfb4ef 100644 --- a/src/plugins/qt4projectmanager/qt-s60/qt4symbiantargetfactory.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/qt4symbiantargetfactory.cpp @@ -203,13 +203,13 @@ ProjectExplorer::Target *Qt4SymbianTargetFactory::create(ProjectExplorer::Projec QList<BuildConfigurationInfo> infos; if (id != QLatin1String(Constants::S60_EMULATOR_TARGET_ID)) { - infos.append(BuildConfigurationInfo(qtVersion, config, QString(), QString())); - infos.append(BuildConfigurationInfo(qtVersion, config ^ QtSupport::BaseQtVersion::DebugBuild, QString(), QString())); + infos.append(BuildConfigurationInfo(qtVersion->uniqueId(), config, QString(), QString())); + infos.append(BuildConfigurationInfo(qtVersion->uniqueId(), config ^ QtSupport::BaseQtVersion::DebugBuild, QString(), QString())); } else { if (config & QtSupport::BaseQtVersion::DebugBuild) - infos.append(BuildConfigurationInfo(qtVersion, config, QString(), QString())); + infos.append(BuildConfigurationInfo(qtVersion->uniqueId(), config, QString(), QString())); else - infos.append(BuildConfigurationInfo(qtVersion, config ^ QtSupport::BaseQtVersion::DebugBuild, QString(), QString())); + infos.append(BuildConfigurationInfo(qtVersion->uniqueId(), config ^ QtSupport::BaseQtVersion::DebugBuild, QString(), QString())); } return create(parent, id, infos); @@ -222,7 +222,7 @@ ProjectExplorer::Target *Qt4SymbianTargetFactory::create(ProjectExplorer::Projec Qt4SymbianTarget *t = new Qt4SymbianTarget(static_cast<Qt4Project *>(parent), id); foreach (const BuildConfigurationInfo &info, infos) t->addQt4BuildConfiguration(msgBuildConfigurationName(info), QString(), - info.version, info.buildConfig, + info.version(), info.buildConfig, info.additionalArguments, info.directory, info.importing); t->addDeployConfiguration(t->createDeployConfiguration(QLatin1String(S60_DEPLOYCONFIGURATION_ID))); diff --git a/src/plugins/qt4projectmanager/qt4target.cpp b/src/plugins/qt4projectmanager/qt4target.cpp index c8b6e484ba8..bd2f7297d35 100644 --- a/src/plugins/qt4projectmanager/qt4target.cpp +++ b/src/plugins/qt4projectmanager/qt4target.cpp @@ -139,7 +139,7 @@ QList<BuildConfigurationInfo> Qt4BaseTargetFactory::availableBuildConfigurations if (!version->isValid() || !version->toolChainAvailable(id)) continue; QtSupport::BaseQtVersion::QmakeBuildConfigs config = version->defaultBuildConfig(); - BuildConfigurationInfo info = BuildConfigurationInfo(version, config, QString(), QString(), false, false); + BuildConfigurationInfo info = BuildConfigurationInfo(version->uniqueId(), config, QString(), QString(), false); info.directory = shadowBuildDirectory(proFilePath, id, msgBuildConfigurationName(info)); infoList.append(info); @@ -220,7 +220,7 @@ QList<Qt4BaseTargetFactory *> Qt4BaseTargetFactory::qt4BaseTargetFactoriesForIds // Return name of a build configuration. QString Qt4BaseTargetFactory::msgBuildConfigurationName(const BuildConfigurationInfo &info) { - const QString qtVersionName = info.version->displayName(); + const QString qtVersionName = info.version()->displayName(); return (info.buildConfig & QtSupport::BaseQtVersion::DebugBuild) ? //: Name of a debug build configuration to created by a project wizard, %1 being the Qt version name. We recommend not translating it. tr("%1 Debug").arg(qtVersionName) : @@ -640,13 +640,13 @@ Qt4DefaultTargetSetupWidget::Qt4DefaultTargetSetupWidget(Qt4BaseTargetFactory *f setupImportWidgets(); - setBuildConfigurationInfos(infos); + setBuildConfigurationInfos(infos, false); int qtVersionId = s->value(QLatin1String("Qt4ProjectManager.TargetSetupPage.QtVersionId"), -1).toInt(); int index = m_versionComboBox->findData(qtVersionId); if (index != -1) m_versionComboBox->setCurrentIndex(index); - qtVersionChanged(); + updateOneQtVisible(); if (!m_importInfos.isEmpty()) m_detailsWidget->setState(Utils::DetailsWidget::Expanded); @@ -661,7 +661,7 @@ Qt4DefaultTargetSetupWidget::Qt4DefaultTargetSetupWidget(Qt4BaseTargetFactory *f connect(m_buildConfigurationComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(buildConfigurationComboBoxChanged())); connect(m_versionComboBox, SIGNAL(currentIndexChanged(int)), - this, SLOT(qtVersionChanged())); + this, SLOT(updateOneQtVisible())); } Qt4DefaultTargetSetupWidget::~Qt4DefaultTargetSetupWidget() @@ -691,6 +691,11 @@ void Qt4DefaultTargetSetupWidget::setTargetSelected(bool b) m_detailsWidget->setState(Utils::DetailsWidget::Expanded); } +void Qt4DefaultTargetSetupWidget::updateBuildConfigurationInfos(const QList<BuildConfigurationInfo> &infos) +{ + setBuildConfigurationInfos(infos, false); +} + void Qt4DefaultTargetSetupWidget::targetCheckBoxToggled(bool b) { if (m_ignoreChange) @@ -718,7 +723,7 @@ QString Qt4DefaultTargetSetupWidget::displayNameFrom(const BuildConfigurationInf //: release build buildType = tr("release"); } - return info.version->displayName() + QLatin1Char(' ') + buildType; + return info.version()->displayName() + QLatin1Char(' ') + buildType; } void Qt4DefaultTargetSetupWidget::setProFilePath(const QString &proFilePath) @@ -730,7 +735,7 @@ void Qt4DefaultTargetSetupWidget::setProFilePath(const QString &proFilePath) m_minimumQtVersion, m_maximumQtVersion, m_requiredFeatures), - false); + true); } void Qt4DefaultTargetSetupWidget::setBuildConfiguraionComboBoxVisible(bool b) @@ -798,7 +803,7 @@ QList<BuildConfigurationInfo> Qt4DefaultTargetSetupWidget::buildConfigurationInf QString sourceDir = QFileInfo(m_proFilePath).absolutePath(); int size = m_infos.size(); for (int i=0; i < size; ++i) { - if (state == PERQT || (m_enabled.at(i) && (state == MANUALLY || (state == ONEQT && m_infos.at(i).version->uniqueId() == qtVersionId)))) { + if (state == PERQT || (m_enabled.at(i) && (state == MANUALLY || (state == ONEQT && m_infos.at(i).version()->uniqueId() == qtVersionId)))) { BuildConfigurationInfo info = m_infos.at(i); if (!m_shadowBuildEnabled->isChecked()) info.directory = sourceDir; @@ -830,7 +835,7 @@ void Qt4DefaultTargetSetupWidget::addImportClicked() QList<BuildConfigurationInfo> filterdInfos; bool filtered = false; foreach (const BuildConfigurationInfo &info, infos) { - if (info.version->supportsTargetId(m_id)) + if (info.version()->supportsTargetId(m_id)) filterdInfos << info; else filtered = true; @@ -884,70 +889,173 @@ void Qt4DefaultTargetSetupWidget::addImportClicked() emit selectedToggled(); } -QList<BuildConfigurationInfo> Qt4DefaultTargetSetupWidget::usedImportInfos() +QList<QtSupport::BaseQtVersion *> Qt4DefaultTargetSetupWidget::usedTemporaryQtVersions() { - QList<BuildConfigurationInfo> infos; + QList<QtSupport::BaseQtVersion *> versions; for (int i = 0; i < m_importInfos.size(); ++i) { - if (m_importEnabled.at(i)) - infos << m_importInfos.at(i); + if (m_importEnabled.at(i) && m_importInfos.at(i).temporaryQtVersion) + versions << m_importInfos.at(i).temporaryQtVersion; } - return infos; + return versions; } -void Qt4DefaultTargetSetupWidget::setBuildConfigurationInfos(const QList<BuildConfigurationInfo> &infos, bool resetEnabled) +void Qt4DefaultTargetSetupWidget::replaceQtVersionWithQtVersion(int oldId, int newId) { - m_infos = infos; - if (resetEnabled || m_infos.size() != m_enabled.size()) { - m_enabled.clear(); - m_selected = 0; - QStringList existingBuilds; - for (int i = 0; i < m_importInfos.size(); ++i) { - const BuildConfigurationInfo &info = m_importInfos.at(i); - existingBuilds << info.directory; - if (m_importEnabled.at(i)) - ++m_selected; + QList<BuildConfigurationInfo>::iterator it, end; + it = m_importInfos.begin(); + end = m_importInfos.end(); + for ( ; it != end; ++it) { + BuildConfigurationInfo &info = *it; + if (info.qtVersionId == oldId) { + info.qtVersionId = newId; + } + } +} + +void Qt4DefaultTargetSetupWidget::replaceTemporaryQtVersionWithQtVersion(QtSupport::BaseQtVersion *version, int id) +{ + QList<BuildConfigurationInfo>::iterator it, end; + it = m_importInfos.begin(); + end = m_importInfos.end(); + for ( ; it != end; ++it) { + BuildConfigurationInfo &info = *it; + if (info.temporaryQtVersion == version) { + info.temporaryQtVersion = 0; + info.qtVersionId = id; } + } +} + +void Qt4DefaultTargetSetupWidget::replaceQtVersionWithTemporaryQtVersion(int id, QtSupport::BaseQtVersion *version) +{ + QList<BuildConfigurationInfo>::iterator it, end; + it = m_importInfos.begin(); + end = m_importInfos.end(); + for ( ; it != end; ++it) { + BuildConfigurationInfo &info = *it; + if (info.qtVersionId == id) { + info.temporaryQtVersion = version; + info.qtVersionId = -1; + } + } +} + +namespace { +bool equal(const BuildConfigurationInfo &a, const BuildConfigurationInfo &b) +{ + return a.qtVersionId == b.qtVersionId + && a.buildConfig == b.buildConfig + && a.additionalArguments == b.additionalArguments; +} + +bool less(const BuildConfigurationInfo &a, const BuildConfigurationInfo &b) +{ + if (a.qtVersionId < b.qtVersionId) + return true; + if (a.qtVersionId > b.qtVersionId) + return false; + if (a.buildConfig < b.buildConfig) + return true; + if (a.buildConfig > b.buildConfig) + return false; + if (a.additionalArguments < b.additionalArguments) + return true; + if (a.additionalArguments > b.additionalArguments) + return false; + // Other cases can't happen! + qDebug() << "could not order buildconfiguration infos"; + return false; +} +} + +void Qt4DefaultTargetSetupWidget::setBuildConfigurationInfos(QList<BuildConfigurationInfo> infos, bool resetDirectories) +{ + // This is somewhat ugly in that we used to sort the buildconfigurations in the order + // that the default for that qt version is first + qSort(infos.begin(), infos.end(), less); - // Default to importing existing builds and disable - // builds that would overwrite imports - for (int i=0; i < m_infos.size(); ++i) { - if (existingBuilds.contains(m_infos.at(i).directory) || m_hasInSourceBuild) { - m_enabled << false; + // Existing builds, to figure out which newly added + // buildconfigurations should be en/disabled + QStringList existingBuilds; + for (int i = 0; i < m_importInfos.size(); ++i) { + const BuildConfigurationInfo &info = m_importInfos.at(i); + existingBuilds << info.directory; + } + + // Iterate over old/new infos to get the correct + // m_selected and m_enabled state + QList<BuildConfigurationInfo>::const_iterator oldit, oend; + oldit = m_infos.constBegin(); + oend = m_infos.constEnd(); + + QList<BuildConfigurationInfo>::iterator newit, nend; + newit = infos.begin(); + nend = infos.end(); + + QList<bool>::const_iterator enabledIt = m_enabled.constBegin(); + QList<bool> enabled; + while (oldit != oend && newit != nend) { + if (equal(*oldit, *newit)) { + if (!resetDirectories) + newit->directory = oldit->directory; + enabled << *enabledIt; + + ++oldit; + ++enabledIt; + ++newit; + } else if (less(*oldit, *newit)) { + // Deleted qt version + if (*enabledIt) + --m_selected; + ++oldit; + ++enabledIt; + } else { + // new info, check if we have a import build for that directory already + // then disable this build + if (existingBuilds.contains(newit->directory) || m_hasInSourceBuild) { + enabled << false; } else { - m_enabled << true; + enabled << true; ++m_selected; } + + ++newit; } + } - clearWidgets(); - setupWidgets(); - } else { - bool foundIssues = false; - m_ignoreChange = true; - QString sourceDir = QFileInfo(m_proFilePath).absolutePath(); - for (int i=0; i < m_checkboxes.size(); ++i) { - const BuildConfigurationInfo &info = m_infos.at(i); - - m_checkboxes[i]->setText(displayNameFrom(info)); - if (m_shadowBuildEnabled->isChecked()) - m_pathChoosers[i]->setPath(info.directory); - else - m_pathChoosers[i]->setPath(sourceDir); - foundIssues |= reportIssues(i); + while (oldit != oend) { + if (*enabledIt) + --m_selected; + ++oldit; + ++enabledIt; + } + + while (newit != nend) { + if (existingBuilds.contains(newit->directory) || m_hasInSourceBuild) { + enabled << false; + } else { + enabled << true; + ++m_selected; } - m_ignoreChange = false; - if (foundIssues && isTargetSelected()) - m_detailsWidget->setState(Utils::DetailsWidget::Expanded); + + ++newit; } + m_infos = infos; + m_enabled = enabled; + + // Recreate widgets + clearWidgets(); + setupWidgets(); + // update version combobox int oldQtVersionId = -1; if (m_versionComboBox->currentIndex() != -1) oldQtVersionId = m_versionComboBox->itemData(m_versionComboBox->currentIndex()).toInt(); QList<QtSupport::BaseQtVersion *> list; foreach (const BuildConfigurationInfo &info, m_infos) { - if (!list.contains(info.version)) - list << info.version; + if (!list.contains(info.version())) + list << info.version(); } m_ignoreChange = true; m_versionComboBox->clear(); @@ -958,6 +1066,8 @@ void Qt4DefaultTargetSetupWidget::setBuildConfigurationInfos(const QList<BuildCo } m_ignoreChange = false; updateWidgetVisibility(); + + emit selectedToggled(); } void Qt4DefaultTargetSetupWidget::setupImportWidgets() @@ -971,8 +1081,8 @@ void Qt4DefaultTargetSetupWidget::createImportWidget(const BuildConfigurationInf QCheckBox *checkBox = new QCheckBox; checkBox->setText(tr("Import build from %1").arg(QDir::toNativeSeparators(info.directory))); checkBox->setChecked(m_importEnabled.at(pos)); - if (info.version) - checkBox->setToolTip(info.version->toHtml(false)); + if (info.version()) + checkBox->setToolTip(info.version()->toHtml(false)); m_importLayout->addWidget(checkBox, pos, 0, 1, 2); connect(checkBox, SIGNAL(toggled(bool)), @@ -992,8 +1102,8 @@ void Qt4DefaultTargetSetupWidget::setupWidgets() checkbox->setText(displayNameFrom(info)); checkbox->setChecked(m_enabled.at(i)); checkbox->setAttribute(Qt::WA_LayoutUsesWidgetRect); - if (info.version) - checkbox->setToolTip(info.version->toHtml(false)); + if (info.version()) + checkbox->setToolTip(info.version()->toHtml(false)); m_newBuildsLayout->addWidget(checkbox, i * 2, 0); Utils::PathChooser *pathChooser = new Utils::PathChooser(); @@ -1133,13 +1243,13 @@ void Qt4DefaultTargetSetupWidget::updateWidgetVisibility() } else if (state == ONEQT) { m_versionLabel->setVisible(true); m_versionComboBox->setVisible(true); - qtVersionChanged(); + updateOneQtVisible(); } m_shadowBuildEnabled->setVisible(m_shadowBuildCheckBoxVisible && (state != NONE)); emit selectedToggled(); } -void Qt4DefaultTargetSetupWidget::qtVersionChanged() +void Qt4DefaultTargetSetupWidget::updateOneQtVisible() { if (m_ignoreChange) return; @@ -1149,7 +1259,7 @@ void Qt4DefaultTargetSetupWidget::qtVersionChanged() if (buildConfigurationTemplate() != ONEQT) return; for (int i = 0; i < m_infos.size(); ++i) { - bool visible = m_infos.at(i).version->uniqueId() == id; + bool visible = m_infos.at(i).version()->uniqueId() == id; m_checkboxes.at(i)->setVisible(visible); m_pathChoosers.at(i)->setVisible(visible); m_reportIssuesLabels.at(i)->setVisible(m_issues.at(i)); @@ -1175,7 +1285,7 @@ QPair<ProjectExplorer::Task::TaskType, QString> Qt4DefaultTargetSetupWidget::fin QString buildDir = info.directory; if (!m_shadowBuildEnabled->isChecked()) buildDir = QFileInfo(m_proFilePath).absolutePath(); - QtSupport::BaseQtVersion *version = info.version; + QtSupport::BaseQtVersion *version = info.version(); QList<ProjectExplorer::Task> issues = version->reportIssues(m_proFilePath, buildDir); @@ -1209,7 +1319,7 @@ QList<BuildConfigurationInfo> BuildConfigurationInfo::filterBuildConfigurationIn { QList<BuildConfigurationInfo> result; foreach (const BuildConfigurationInfo &info, infos) - if (info.version->supportsTargetId(id)) + if (info.version()->supportsTargetId(id)) result.append(info); return result; } @@ -1221,7 +1331,7 @@ QList<BuildConfigurationInfo> BuildConfigurationInfo::filterBuildConfigurationIn return infos; QList<BuildConfigurationInfo> result; foreach (const BuildConfigurationInfo &info, infos) - if (info.version->supportsPlatform(platform)) + if (info.version()->supportsPlatform(platform)) result.append(info); return result; } @@ -1230,11 +1340,19 @@ QList<BuildConfigurationInfo> BuildConfigurationInfo::filterBuildConfigurationIn { QList<BuildConfigurationInfo> result; foreach (const BuildConfigurationInfo &info, infos) - if (info.version->availableFeatures().contains(features)) + if (info.version()->availableFeatures().contains(features)) result.append(info); return result; } +QtSupport::BaseQtVersion *BuildConfigurationInfo::version() const +{ + if (temporaryQtVersion) + return temporaryQtVersion; + QtSupport::QtVersionManager *manager = QtSupport::QtVersionManager::instance(); + return manager->version(qtVersionId); +} + QList<BuildConfigurationInfo> BuildConfigurationInfo::importBuildConfigurations(const QString &proFilePath) { QList<BuildConfigurationInfo> result; @@ -1306,12 +1424,13 @@ QList<BuildConfigurationInfo> BuildConfigurationInfo::checkForBuild(const QStrin } Utils::QtcProcess::addArgs(&specArgument, additionalArguments); - BuildConfigurationInfo info = BuildConfigurationInfo(version, + BuildConfigurationInfo info = BuildConfigurationInfo(version->uniqueId(), makefileBuildConfig.first, specArgument, directory, true, - temporaryQtVersion); + temporaryQtVersion ? version : 0, + file); infos.append(info); } return infos; diff --git a/src/plugins/qt4projectmanager/qt4target.h b/src/plugins/qt4projectmanager/qt4target.h index d11e3899074..99a5aced940 100644 --- a/src/plugins/qt4projectmanager/qt4target.h +++ b/src/plugins/qt4projectmanager/qt4target.h @@ -111,6 +111,14 @@ private slots: void emitProFileEvaluateNeeded(); }; +// TODO handle the user deleting/creating qt versions correctly +// Update list of buildconfigurations on adding/removing +// Do advanced magic for importing cases: +// - If the qt version that would be imported was created in the mean time +// delete the temporary qt version and set the versionId to the newly created version +// - If the qt version that a import configuration uses was deleted from the qt versions +// create a new temporary qt version and use that +// For greatness! class Qt4DefaultTargetSetupWidget : public Qt4TargetSetupWidget { Q_OBJECT @@ -129,7 +137,12 @@ public: ~Qt4DefaultTargetSetupWidget(); bool isTargetSelected() const; void setTargetSelected(bool b); - QList<BuildConfigurationInfo> usedImportInfos(); + + void updateBuildConfigurationInfos(const QList<BuildConfigurationInfo> &infos); + QList<QtSupport::BaseQtVersion *> usedTemporaryQtVersions(); + void replaceQtVersionWithQtVersion(int oldId, int newId); + void replaceTemporaryQtVersionWithQtVersion(QtSupport::BaseQtVersion *version, int id); + void replaceQtVersionWithTemporaryQtVersion(int id, QtSupport::BaseQtVersion *version); QList<BuildConfigurationInfo> buildConfigurationInfos() const; void setProFilePath(const QString &proFilePath); @@ -151,12 +164,12 @@ private slots: void pathChanged(); void shadowBuildingToggled(); void buildConfigurationComboBoxChanged(); - void qtVersionChanged(); + void updateOneQtVisible(); void targetCheckBoxToggled(bool b); private: void updateWidgetVisibility(); - void setBuildConfigurationInfos(const QList<BuildConfigurationInfo> &list, bool resetEnabled = true); + void setBuildConfigurationInfos(QList<BuildConfigurationInfo> list, bool resetDirectories); bool reportIssues(int index); QPair<ProjectExplorer::Task::TaskType, QString> findIssues(const BuildConfigurationInfo &info); void createImportWidget(const BuildConfigurationInfo &info, int pos); diff --git a/src/plugins/qt4projectmanager/qt4targetsetupwidget.h b/src/plugins/qt4projectmanager/qt4targetsetupwidget.h index a3f19c830ef..be1679928ed 100644 --- a/src/plugins/qt4projectmanager/qt4targetsetupwidget.h +++ b/src/plugins/qt4projectmanager/qt4targetsetupwidget.h @@ -37,6 +37,10 @@ #include <QWidget> +namespace QtSupport { +class BaseQtVersion; +} + namespace Qt4ProjectManager { struct BuildConfigurationInfo; @@ -49,7 +53,13 @@ public: virtual bool isTargetSelected() const = 0; virtual void setTargetSelected(bool b) = 0; virtual void setProFilePath(const QString &proFilePath) = 0; - virtual QList<BuildConfigurationInfo> usedImportInfos() = 0; + + virtual void updateBuildConfigurationInfos(const QList<BuildConfigurationInfo> &infos) = 0; + + virtual QList<QtSupport::BaseQtVersion *> usedTemporaryQtVersions() = 0; + virtual void replaceQtVersionWithQtVersion(int oldId, int newId) = 0; + virtual void replaceTemporaryQtVersionWithQtVersion(QtSupport::BaseQtVersion *version, int id) = 0; + virtual void replaceQtVersionWithTemporaryQtVersion(int id, QtSupport::BaseQtVersion *version) = 0; signals: void selectedToggled() const; diff --git a/src/plugins/qt4projectmanager/wizards/targetsetuppage.cpp b/src/plugins/qt4projectmanager/wizards/targetsetuppage.cpp index fe37d6b9e38..865ef954735 100644 --- a/src/plugins/qt4projectmanager/wizards/targetsetuppage.cpp +++ b/src/plugins/qt4projectmanager/wizards/targetsetuppage.cpp @@ -60,6 +60,7 @@ TargetSetupPage::TargetSetupPage(QWidget *parent) : m_useScrollArea(true), m_maximumQtVersionNumber(INT_MAX, INT_MAX, INT_MAX), m_spacer(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)), + m_ignoreQtVersionChange(false), m_ui(new Internal::Ui::TargetSetupPage) { m_ui->setupUi(this); @@ -73,6 +74,9 @@ TargetSetupPage::TargetSetupPage(QWidget *parent) : connect(m_ui->descriptionLabel, SIGNAL(linkActivated(QString)), this, SIGNAL(noteTextLinkActivated())); + + connect(QtSupport::QtVersionManager::instance(), SIGNAL(qtVersionsChanged(QList<int>,QList<int>,QList<int>)), + this, SLOT(qtVersionsChanged(QList<int>,QList<int>,QList<int>))); } void TargetSetupPage::initializePage() @@ -260,10 +264,20 @@ void TargetSetupPage::setupImportInfos() void TargetSetupPage::cleanupImportInfos() { + // The same qt version can be twice in the list, for the following case + // A Project with two import build using the same already existing qt version + // If that qt version is deleted, it is replaced by ONE temporary qt version + // So two entries in m_importInfos refer to the same qt version + QSet<QtSupport::BaseQtVersion *> alreadyDeleted; foreach (const BuildConfigurationInfo &info, m_importInfos) { - if (info.temporaryQtVersion) - delete info.version; + if (info.temporaryQtVersion) { + if (!alreadyDeleted.contains(info.temporaryQtVersion)) { + alreadyDeleted << info.temporaryQtVersion; + delete info.temporaryQtVersion; + } + } } + m_importInfos.clear(); } void TargetSetupPage::newImportBuildConfiguration(const BuildConfigurationInfo &info) @@ -271,26 +285,122 @@ void TargetSetupPage::newImportBuildConfiguration(const BuildConfigurationInfo & m_importInfos.append(info); } -bool TargetSetupPage::setupProject(Qt4ProjectManager::Qt4Project *project) +void TargetSetupPage::qtVersionsChanged(const QList<int> &added, const QList<int> &removed, const QList<int> &changed) { - QMap<QString, Qt4TargetSetupWidget *>::const_iterator it, end; - end = m_widgets.constEnd(); - it = m_widgets.constBegin(); + Q_UNUSED(added) + if (m_ignoreQtVersionChange) + return; + QMap<QString, Qt4TargetSetupWidget *>::iterator it, end; + end = m_widgets.end(); + it = m_widgets.begin(); for ( ; it != end; ++it) { Qt4BaseTargetFactory *factory = m_factories.value(it.value()); + it.value()->updateBuildConfigurationInfos(factory->availableBuildConfigurations(it.key(), + m_proFilePath, + m_minimumQtVersionNumber, + m_maximumQtVersionNumber, + m_requiredQtFeatures)); + } - foreach (const BuildConfigurationInfo &info, it.value()->usedImportInfos()) { - QtSupport::BaseQtVersion *version = info.version; - for (int i=0; i < m_importInfos.size(); ++i) { - if (m_importInfos.at(i).version == version) { - if (m_importInfos[i].temporaryQtVersion) { - QtSupport::QtVersionManager::instance()->addVersion(m_importInfos[i].version); - m_importInfos[i].temporaryQtVersion = false; - } + QtSupport::QtVersionManager *mgr = QtSupport::QtVersionManager::instance(); + for (int i = 0; i < m_importInfos.size(); ++i) { + if (QtSupport::BaseQtVersion *tmpVersion = m_importInfos[i].temporaryQtVersion) { + // Check whether we have a qt version now + QtSupport::BaseQtVersion *version = + mgr->qtVersionForQMakeBinary(tmpVersion->qmakeCommand()); + if (version) + replaceTemporaryQtVersion(tmpVersion, version->uniqueId()); + } else { + // Check whether we need to replace the qt version id + int oldId = m_importInfos[i].qtVersionId; + if (removed.contains(oldId) || changed.contains(oldId)) { + QString makefile = m_importInfos[i].directory + QLatin1Char('/') + m_importInfos[i].makefile; + Utils::FileName qmakeBinary = QtSupport::QtVersionManager::findQMakeBinaryFromMakefile(makefile); + QtSupport::BaseQtVersion *version = QtSupport::QtVersionManager::instance()->qtVersionForQMakeBinary(qmakeBinary); + if (version) { + replaceQtVersionWithQtVersion(oldId, version->uniqueId()); + } else { + version = QtSupport::QtVersionFactory::createQtVersionFromQMakePath(qmakeBinary); + replaceQtVersionWithTemporaryQtVersion(oldId, version); } } } + } +} +void TargetSetupPage::replaceQtVersionWithQtVersion(int oldId, int newId) +{ + for (int i = 0; i < m_importInfos.size(); ++i) { + if (m_importInfos[i].qtVersionId == oldId) { + m_importInfos[i].qtVersionId = newId; + } + } + QMap<QString, Qt4TargetSetupWidget *>::const_iterator it, end; + it = m_widgets.constBegin(); + end = m_widgets.constEnd(); + for ( ; it != end; ++it) + (*it)->replaceQtVersionWithQtVersion(oldId, newId); +} + +void TargetSetupPage::replaceQtVersionWithTemporaryQtVersion(int id, QtSupport::BaseQtVersion *version) +{ + for (int i = 0; i < m_importInfos.size(); ++i) { + if (m_importInfos[i].qtVersionId == id) { + m_importInfos[i].temporaryQtVersion = version; + m_importInfos[i].qtVersionId = -1; + } + } + QMap<QString, Qt4TargetSetupWidget *>::const_iterator it, end; + it = m_widgets.constBegin(); + end = m_widgets.constEnd(); + for ( ; it != end; ++it) + (*it)->replaceQtVersionWithTemporaryQtVersion(id, version); +} + +void TargetSetupPage::replaceTemporaryQtVersion(QtSupport::BaseQtVersion *version, int id) +{ + for (int i = 0; i < m_importInfos.size(); ++i) { + if (m_importInfos[i].temporaryQtVersion == version) { + m_importInfos[i].temporaryQtVersion = 0; + m_importInfos[i].qtVersionId = id; + } + } + QMap<QString, Qt4TargetSetupWidget *>::const_iterator it, end; + it = m_widgets.constBegin(); + end = m_widgets.constEnd(); + for ( ; it != end; ++it) + (*it)->replaceTemporaryQtVersionWithQtVersion(version, id); +} + +bool TargetSetupPage::setupProject(Qt4ProjectManager::Qt4Project *project) +{ + m_ignoreQtVersionChange = true; + QtSupport::QtVersionManager *mgr = QtSupport::QtVersionManager::instance(); + QMap<QString, Qt4TargetSetupWidget *>::const_iterator it, end; + end = m_widgets.constEnd(); + it = m_widgets.constBegin(); + + QSet<QtSupport::BaseQtVersion *> temporaryQtVersions; + for ( ; it != end; ++it) + foreach (QtSupport::BaseQtVersion *tempVersion, it.value()->usedTemporaryQtVersions()) + temporaryQtVersions.insert(tempVersion); + + foreach (QtSupport::BaseQtVersion *tempVersion, temporaryQtVersions) { + QtSupport::BaseQtVersion *version = mgr->qtVersionForQMakeBinary(tempVersion->qmakeCommand()); + if (version) { + replaceTemporaryQtVersion(tempVersion, version->uniqueId()); + delete tempVersion; + } else { + mgr->addVersion(tempVersion); + replaceTemporaryQtVersion(tempVersion, tempVersion->uniqueId()); + } + } + + m_ignoreQtVersionChange = false; + + it = m_widgets.constBegin(); + for ( ; it != end; ++it) { + Qt4BaseTargetFactory *factory = m_factories.value(it.value()); if (ProjectExplorer::Target *target = factory->create(project, it.key(), it.value())) project->addTarget(target); } diff --git a/src/plugins/qt4projectmanager/wizards/targetsetuppage.h b/src/plugins/qt4projectmanager/wizards/targetsetuppage.h index 0c32e5ebad1..a37735bdf56 100644 --- a/src/plugins/qt4projectmanager/wizards/targetsetuppage.h +++ b/src/plugins/qt4projectmanager/wizards/targetsetuppage.h @@ -111,10 +111,14 @@ signals: private slots: void newImportBuildConfiguration(const BuildConfigurationInfo &info); + void qtVersionsChanged(const QList<int> &added, const QList<int> &removed, const QList<int> &changed); private: void setupImportInfos(); void cleanupImportInfos(); + void replaceQtVersionWithQtVersion(int oldId, int newId); + void replaceTemporaryQtVersion(QtSupport::BaseQtVersion *version, int id); + void replaceQtVersionWithTemporaryQtVersion(int id, QtSupport::BaseQtVersion *version); void setupWidgets(); void deleteWidgets(); @@ -132,8 +136,9 @@ private: QHash<Qt4TargetSetupWidget *, Qt4BaseTargetFactory *> m_factories; QSpacerItem *m_spacer; + bool m_ignoreQtVersionChange; Internal::Ui::TargetSetupPage *m_ui; - QList<BuildConfigurationInfo> m_importInfos; + QList<BuildConfigurationInfo> m_importInfos; // This owns the temporary qt versions }; } // namespace Qt4ProjectManager diff --git a/src/plugins/remotelinux/embeddedlinuxtargetfactory.cpp b/src/plugins/remotelinux/embeddedlinuxtargetfactory.cpp index 07b1894f2db..7a9b05c92f4 100644 --- a/src/plugins/remotelinux/embeddedlinuxtargetfactory.cpp +++ b/src/plugins/remotelinux/embeddedlinuxtargetfactory.cpp @@ -139,8 +139,8 @@ ProjectExplorer::Target *EmbeddedLinuxTargetFactory::create(ProjectExplorer::Pro QtSupport::BaseQtVersion::QmakeBuildConfigs config = qtVersion->defaultBuildConfig(); QList<Qt4ProjectManager::BuildConfigurationInfo> infos; - infos.append(Qt4ProjectManager::BuildConfigurationInfo(qtVersion, config, QString(), QString())); - infos.append(Qt4ProjectManager::BuildConfigurationInfo(qtVersion, + infos.append(Qt4ProjectManager::BuildConfigurationInfo(qtVersion->uniqueId(), config, QString(), QString())); + infos.append(Qt4ProjectManager::BuildConfigurationInfo(qtVersion->uniqueId(), config ^ QtSupport::BaseQtVersion::DebugBuild, QString(), QString())); @@ -158,7 +158,7 @@ ProjectExplorer::Target *EmbeddedLinuxTargetFactory::create(ProjectExplorer::Pro foreach (const Qt4ProjectManager::BuildConfigurationInfo &info, infos) t->addQt4BuildConfiguration(msgBuildConfigurationName(info), QString(), - info.version, info.buildConfig, + info.version(), info.buildConfig, info.additionalArguments, info.directory, info.importing); t->addDeployConfiguration( -- GitLab