ProjectExplorer: Prevent offering build configs with the same build dir

... in the target setup page. Instead, if a build config candidate is
added that has the same build directory (which should only happen for
imported builds), replace the existing one.

Fixes: QTCREATORBUG-31567
Change-Id: I72b4efb20b5b083c80b87d42c78a9a8193c06c97
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Christian Kandeler
2025-01-14 13:25:42 +01:00
parent dc32603c1f
commit 8fe7e92be8
2 changed files with 30 additions and 10 deletions

View File

@@ -122,18 +122,24 @@ void TargetSetupWidget::addBuildInfo(const BuildInfo &info, bool isImport)
m_haveImported = true; m_haveImported = true;
} }
const auto pos = static_cast<int>(m_infoStore.size());
BuildInfoStore store; BuildInfoStore store;
store.buildInfo = info; store.buildInfo = info;
store.isEnabled = info.enabledByDefault; store.isEnabled = info.enabledByDefault;
store.hasIssues = false;
const auto it
= std::find_if(m_infoStore.begin(), m_infoStore.end(), [&info](const BuildInfoStore &bsi) {
return bsi.buildInfo.buildDirectory == info.buildDirectory;
});
const bool replace = it != m_infoStore.end();
const int pos = replace ? std::distance(m_infoStore.begin(), it) : int(m_infoStore.size());
if (!replace || (isImport && m_selected == 0))
++m_selected; ++m_selected;
store.checkbox = new QCheckBox; store.checkbox = new QCheckBox;
store.checkbox->setText(info.displayName); store.checkbox->setText(info.displayName);
store.checkbox->setChecked(store.isEnabled); store.checkbox->setChecked(store.isEnabled);
store.checkbox->setAttribute(Qt::WA_LayoutUsesWidgetRect); store.checkbox->setAttribute(Qt::WA_LayoutUsesWidgetRect);
m_newBuildsLayout->addWidget(store.checkbox, pos * 2, 0);
store.pathChooser = new PathChooser(); store.pathChooser = new PathChooser();
store.pathChooser->setExpectedKind(PathChooser::Directory); store.pathChooser->setExpectedKind(PathChooser::Directory);
@@ -142,11 +148,9 @@ void TargetSetupWidget::addBuildInfo(const BuildInfo &info, bool isImport)
store.pathChooser->setVisible(false); store.pathChooser->setVisible(false);
store.pathChooser->setHistoryCompleter("TargetSetup.BuildDir.History"); store.pathChooser->setHistoryCompleter("TargetSetup.BuildDir.History");
store.pathChooser->setReadOnly(isImport); store.pathChooser->setReadOnly(isImport);
m_newBuildsLayout->addWidget(store.pathChooser, pos * 2, 1);
store.issuesLabel = new QLabel; store.issuesLabel = new QLabel;
store.issuesLabel->setIndent(32); store.issuesLabel->setIndent(32);
m_newBuildsLayout->addWidget(store.issuesLabel, pos * 2 + 1, 0, 1, 2);
store.issuesLabel->setVisible(false); store.issuesLabel->setVisible(false);
connect(store.checkbox, &QAbstractButton::toggled, this, connect(store.checkbox, &QAbstractButton::toggled, this,
@@ -154,11 +158,20 @@ void TargetSetupWidget::addBuildInfo(const BuildInfo &info, bool isImport)
connect(store.pathChooser, &PathChooser::rawPathChanged, this, connect(store.pathChooser, &PathChooser::rawPathChanged, this,
[this, pathChooser = store.pathChooser] { pathChanged(pathChooser); }); [this, pathChooser = store.pathChooser] { pathChanged(pathChooser); });
store.hasIssues = false; if (replace) {
QTC_CHECK(isImport);
m_newBuildsLayout->replaceWidget(it->checkbox, store.checkbox);
m_newBuildsLayout->replaceWidget(it->pathChooser, store.pathChooser);
m_newBuildsLayout->replaceWidget(it->issuesLabel, store.issuesLabel);
*it = std::move(store);
} else {
m_newBuildsLayout->addWidget(store.checkbox, pos * 2, 0);
m_newBuildsLayout->addWidget(store.pathChooser, pos * 2, 1);
m_newBuildsLayout->addWidget(store.issuesLabel, pos * 2 + 1, 0, 1, 2);
m_infoStore.emplace_back(std::move(store)); m_infoStore.emplace_back(std::move(store));
}
reportIssues(pos); reportIssues(pos);
emit selectedToggled(); emit selectedToggled();
} }
@@ -381,6 +394,12 @@ TargetSetupWidget::BuildInfoStore::~BuildInfoStore()
} }
TargetSetupWidget::BuildInfoStore::BuildInfoStore(TargetSetupWidget::BuildInfoStore &&other) TargetSetupWidget::BuildInfoStore::BuildInfoStore(TargetSetupWidget::BuildInfoStore &&other)
{
*this = std::move(other);
}
TargetSetupWidget::BuildInfoStore &TargetSetupWidget::BuildInfoStore::operator=(
BuildInfoStore &&other)
{ {
std::swap(other.buildInfo, buildInfo); std::swap(other.buildInfo, buildInfo);
std::swap(other.checkbox, checkbox); std::swap(other.checkbox, checkbox);
@@ -389,6 +408,7 @@ TargetSetupWidget::BuildInfoStore::BuildInfoStore(TargetSetupWidget::BuildInfoSt
std::swap(other.pathChooser, pathChooser); std::swap(other.pathChooser, pathChooser);
std::swap(other.isEnabled, isEnabled); std::swap(other.isEnabled, isEnabled);
std::swap(other.hasIssues, hasIssues); std::swap(other.hasIssues, hasIssues);
return *this;
} }
} // namespace Internal } // namespace Internal

View File

@@ -86,7 +86,7 @@ private:
BuildInfoStore(const BuildInfoStore &other) = delete; BuildInfoStore(const BuildInfoStore &other) = delete;
BuildInfoStore(BuildInfoStore &&other); BuildInfoStore(BuildInfoStore &&other);
BuildInfoStore &operator=(const BuildInfoStore &other) = delete; BuildInfoStore &operator=(const BuildInfoStore &other) = delete;
BuildInfoStore &operator=(BuildInfoStore &&other) = delete; BuildInfoStore &operator=(BuildInfoStore &&other);
BuildInfo buildInfo; BuildInfo buildInfo;
QCheckBox *checkbox = nullptr; QCheckBox *checkbox = nullptr;