diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h index 56831c7854b..f5c80c12b67 100644 --- a/src/plugins/projectexplorer/toolchain.h +++ b/src/plugins/projectexplorer/toolchain.h @@ -81,7 +81,8 @@ public: enum Detection { ManualDetection, AutoDetection, - AutoDetectionFromSettings + AutoDetectionFromSettings, + AutoDetectionFromSdk, }; using Predicate = std::function; diff --git a/src/plugins/projectexplorer/toolchainoptionspage.cpp b/src/plugins/projectexplorer/toolchainoptionspage.cpp index 278c0064f4e..7289ca9bbf1 100644 --- a/src/plugins/projectexplorer/toolchainoptionspage.cpp +++ b/src/plugins/projectexplorer/toolchainoptionspage.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -210,6 +211,10 @@ public: m_delButton = new QPushButton(ToolChainOptionsPage::tr("Remove"), this); + m_redetectButton = new QPushButton(ToolChainOptionsPage::tr("Re-detect"), this); + connect(m_redetectButton, &QAbstractButton::clicked, + this, &ToolChainOptionsWidget::redetectToolchains); + m_detectionSettingsButton = new QPushButton( ToolChainOptionsPage::tr("Auto-detection Settings..."), this); connect(m_detectionSettingsButton, &QAbstractButton::clicked, this, @@ -235,6 +240,7 @@ public: buttonLayout->addWidget(m_addButton); buttonLayout->addWidget(m_cloneButton); buttonLayout->addWidget(m_delButton); + buttonLayout->addWidget(m_redetectButton); buttonLayout->addWidget(m_detectionSettingsButton); buttonLayout->addItem(new QSpacerItem(10, 40, QSizePolicy::Minimum, QSizePolicy::Expanding)); @@ -283,6 +289,8 @@ public: return action; } + void redetectToolchains(); + void apply(); private: @@ -294,6 +302,7 @@ public: QPushButton *m_addButton; QPushButton *m_cloneButton; QPushButton *m_delButton; + QPushButton *m_redetectButton; QPushButton *m_detectionSettingsButton; QHash> m_languageMap; @@ -366,6 +375,50 @@ StaticTreeItem *ToolChainOptionsWidget::parentForToolChain(ToolChain *tc) return tc->isAutoDetected() ? nodes.first : nodes.second; } +void ToolChainOptionsWidget::redetectToolchains() +{ + QList itemsToRemove; + QList knownTcs; + m_model.forAllItems([&itemsToRemove, &knownTcs](TreeItem *item) { + if (item->level() != 3) + return; + const auto tcItem = static_cast(item); + if (tcItem->toolChain->isAutoDetected() + && tcItem->toolChain->detection() != ToolChain::AutoDetectionFromSdk) { + itemsToRemove << tcItem; + } else { + knownTcs << tcItem->toolChain; + } + }); + QList toAdd; + QSet toDelete; + for (ToolChainFactory *f : ToolChainFactory::allToolChainFactories()) { + for (ToolChain * const tc : f->autoDetect(knownTcs)) { + if (knownTcs.contains(tc) || toDelete.contains(tc)) + continue; + const auto matchItem = [tc](const ToolChainTreeItem *item) { + return item->toolChain->compilerCommand() == tc->compilerCommand() + && item->toolChain->typeId() == tc->typeId() + && item->toolChain->language() == tc->language() + && item->toolChain->targetAbi() == tc->targetAbi(); + }; + ToolChainTreeItem * const item = findOrDefault(itemsToRemove, matchItem); + if (item) { + itemsToRemove.removeOne(item); + toDelete << tc; + continue; + } + knownTcs << tc; + toAdd << tc; + } + } + for (ToolChainTreeItem * const tcItem : qAsConst(itemsToRemove)) + markForRemoval(tcItem); + for (ToolChain * const newTc : qAsConst(toAdd)) + m_toAddList.append(insertToolChain(newTc, true)); + qDeleteAll(toDelete); +} + void ToolChainOptionsWidget::toolChainSelectionChanged() { ToolChainTreeItem *item = currentTreeItem(); @@ -388,14 +441,16 @@ void ToolChainOptionsWidget::apply() // Update tool chains: foreach (const Core::Id &l, m_languageMap.keys()) { - StaticTreeItem *parent = m_languageMap.value(l).second; - for (TreeItem *item : *parent) { - auto tcItem = static_cast(item); - Q_ASSERT(tcItem->toolChain); - if (tcItem->widget) - tcItem->widget->apply(); - tcItem->changed = false; - tcItem->update(); + const QPair autoAndManual = m_languageMap.value(l); + for (StaticTreeItem *parent : {autoAndManual.first, autoAndManual.second}) { + for (TreeItem *item : *parent) { + auto tcItem = static_cast(item); + Q_ASSERT(tcItem->toolChain); + if (tcItem->widget) + tcItem->widget->apply(); + tcItem->changed = false; + tcItem->update(); + } } } diff --git a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp index e66dbee0185..1148780345d 100644 --- a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp +++ b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp @@ -195,6 +195,8 @@ QList ToolChainSettingsAccessor::restoreToolChains(QWidget *parent) const QList systemFileTcs = toolChains(restoreSettings(FileName::fromString(Core::ICore::installerResourcePath() + TOOLCHAIN_FILENAME), parent)); + for (ToolChain * const systemTc : systemFileTcs) + systemTc->setDetection(ToolChain::AutoDetectionFromSdk); // read all tool chains from user file. const QList userFileTcs = toolChains(restoreSettings(parent));