diff options
author | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-07-11 08:25:07 +0200 |
---|---|---|
committer | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-08-21 08:25:51 +0000 |
commit | 2c0554c187adb4ef886affd193b8149afa199d13 (patch) | |
tree | 8c484fc209db1c06e5eec942d1af9e1d0b566140 | |
parent | 263cf4c6088d579a2cda05b3d5b795840e3e79fc (diff) |
ProjectExplorer: Fix memory leaks in tree models
Fix widgets being leaked by the ToolChainOptionsPage.
This page created widgets and stored them in the tree node
and never deleted them.
The fix is to put all the widgets into one QStackedWidget, so
that this will clean up once the page is destroyed.
Change-Id: Ic02824a4c52771d8962dc594176077c2e139fb84
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
-rw-r--r-- | src/plugins/android/androidtoolchain.cpp | 4 | ||||
-rw-r--r-- | src/plugins/android/androidtoolchain.h | 2 | ||||
-rw-r--r-- | src/plugins/nim/project/nimtoolchain.cpp | 4 | ||||
-rw-r--r-- | src/plugins/nim/project/nimtoolchain.h | 2 | ||||
-rw-r--r-- | src/plugins/projectexplorer/customtoolchain.cpp | 4 | ||||
-rw-r--r-- | src/plugins/projectexplorer/customtoolchain.h | 2 | ||||
-rw-r--r-- | src/plugins/projectexplorer/gcctoolchain.cpp | 4 | ||||
-rw-r--r-- | src/plugins/projectexplorer/gcctoolchain.h | 2 | ||||
-rw-r--r-- | src/plugins/projectexplorer/msvctoolchain.cpp | 8 | ||||
-rw-r--r-- | src/plugins/projectexplorer/msvctoolchain.h | 4 | ||||
-rw-r--r-- | src/plugins/projectexplorer/toolchain.h | 2 | ||||
-rw-r--r-- | src/plugins/projectexplorer/toolchainoptionspage.cpp | 24 | ||||
-rw-r--r-- | src/plugins/projectexplorer/toolchainsettingsaccessor.cpp | 3 | ||||
-rw-r--r-- | src/plugins/qnx/qnxtoolchain.cpp | 4 | ||||
-rw-r--r-- | src/plugins/qnx/qnxtoolchain.h | 2 |
15 files changed, 38 insertions, 33 deletions
diff --git a/src/plugins/android/androidtoolchain.cpp b/src/plugins/android/androidtoolchain.cpp index f8d0535c7e..6fb7e67bbf 100644 --- a/src/plugins/android/androidtoolchain.cpp +++ b/src/plugins/android/androidtoolchain.cpp @@ -181,9 +181,9 @@ bool AndroidToolChain::operator ==(const ToolChain &tc) const return m_ndkToolChainVersion == static_cast<const AndroidToolChain &>(tc).m_ndkToolChainVersion; } -ToolChainConfigWidget *AndroidToolChain::configurationWidget() +std::unique_ptr<ToolChainConfigWidget> AndroidToolChain::createConfigurationWidget() { - return new AndroidToolChainConfigWidget(this); + return std::make_unique<AndroidToolChainConfigWidget>(this); } FileName AndroidToolChain::suggestedDebugger() const diff --git a/src/plugins/android/androidtoolchain.h b/src/plugins/android/androidtoolchain.h index 4d37e4ae07..0352bfe94e 100644 --- a/src/plugins/android/androidtoolchain.h +++ b/src/plugins/android/androidtoolchain.h @@ -44,7 +44,7 @@ public: bool operator ==(const ProjectExplorer::ToolChain &) const override; - ProjectExplorer::ToolChainConfigWidget *configurationWidget() override; + std::unique_ptr<ProjectExplorer::ToolChainConfigWidget> createConfigurationWidget() override; Utils::FileName suggestedDebugger() const override; Utils::FileName suggestedGdbServer() const; diff --git a/src/plugins/nim/project/nimtoolchain.cpp b/src/plugins/nim/project/nimtoolchain.cpp index cd41c17869..56f6f3f9a9 100644 --- a/src/plugins/nim/project/nimtoolchain.cpp +++ b/src/plugins/nim/project/nimtoolchain.cpp @@ -136,9 +136,9 @@ IOutputParser *NimToolChain::outputParser() const return nullptr; } -ToolChainConfigWidget *NimToolChain::configurationWidget() +std::unique_ptr<ProjectExplorer::ToolChainConfigWidget> NimToolChain::createConfigurationWidget() { - return new NimToolChainConfigWidget(this); + return std::make_unique<NimToolChainConfigWidget>(this); } ToolChain *NimToolChain::clone() const diff --git a/src/plugins/nim/project/nimtoolchain.h b/src/plugins/nim/project/nimtoolchain.h index 2da07dd2e2..4e6ee118c1 100644 --- a/src/plugins/nim/project/nimtoolchain.h +++ b/src/plugins/nim/project/nimtoolchain.h @@ -54,7 +54,7 @@ public: QString compilerVersion() const; void setCompilerCommand(const Utils::FileName &compilerCommand); ProjectExplorer::IOutputParser *outputParser() const final; - ProjectExplorer::ToolChainConfigWidget *configurationWidget() final; + std::unique_ptr<ProjectExplorer::ToolChainConfigWidget> createConfigurationWidget() final; ProjectExplorer::ToolChain *clone() const final; QVariantMap toMap() const final; diff --git a/src/plugins/projectexplorer/customtoolchain.cpp b/src/plugins/projectexplorer/customtoolchain.cpp index 68c663bbc9..1bdf90db23 100644 --- a/src/plugins/projectexplorer/customtoolchain.cpp +++ b/src/plugins/projectexplorer/customtoolchain.cpp @@ -412,9 +412,9 @@ QList<CustomToolChain::Parser> CustomToolChain::parsers() return result; } -ToolChainConfigWidget *CustomToolChain::configurationWidget() +std::unique_ptr<ToolChainConfigWidget> CustomToolChain::createConfigurationWidget() { - return new Internal::CustomToolChainConfigWidget(this); + return std::make_unique<Internal::CustomToolChainConfigWidget>(this); } namespace Internal { diff --git a/src/plugins/projectexplorer/customtoolchain.h b/src/plugins/projectexplorer/customtoolchain.h index 75ba190c66..b0554f0d06 100644 --- a/src/plugins/projectexplorer/customtoolchain.h +++ b/src/plugins/projectexplorer/customtoolchain.h @@ -90,7 +90,7 @@ public: QVariantMap toMap() const override; bool fromMap(const QVariantMap &data) override; - ToolChainConfigWidget *configurationWidget() override; + std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override; bool operator ==(const ToolChain &) const override; diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 27413c22ea..101594befe 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -861,9 +861,9 @@ bool GccToolChain::operator ==(const ToolChain &other) const && m_platformLinkerFlags == gccTc->m_platformLinkerFlags; } -ToolChainConfigWidget *GccToolChain::configurationWidget() +std::unique_ptr<ToolChainConfigWidget> GccToolChain::createConfigurationWidget() { - return new GccToolChainConfigWidget(this); + return std::make_unique<GccToolChainConfigWidget>(this); } void GccToolChain::updateSupportedAbis() const diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h index 2a0ca0e17d..7cc6d60e6f 100644 --- a/src/plugins/projectexplorer/gcctoolchain.h +++ b/src/plugins/projectexplorer/gcctoolchain.h @@ -158,7 +158,7 @@ public: QVariantMap toMap() const override; bool fromMap(const QVariantMap &data) override; - ToolChainConfigWidget *configurationWidget() override; + std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override; bool operator ==(const ToolChain &) const override; diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index 9a68a59689..220d8509dc 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -764,9 +764,9 @@ bool MsvcToolChain::fromMap(const QVariantMap &data) } -ToolChainConfigWidget *MsvcToolChain::configurationWidget() +std::unique_ptr<ToolChainConfigWidget> MsvcToolChain::createConfigurationWidget() { - return new MsvcToolChainConfigWidget(this); + return std::make_unique<MsvcToolChainConfigWidget>(this); } ToolChain *MsvcToolChain::clone() const @@ -1048,9 +1048,9 @@ bool ClangClToolChain::fromMap(const QVariantMap &data) return true; } -ToolChainConfigWidget *ClangClToolChain::configurationWidget() +std::unique_ptr<ToolChainConfigWidget> ClangClToolChain::createConfigurationWidget() { - return new ClangClToolChainConfigWidget(this); + return std::make_unique<ClangClToolChainConfigWidget>(this); } void ClangClToolChain::resetMsvcToolChain(const MsvcToolChain *base) diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h index 8510cece09..88ba1523cd 100644 --- a/src/plugins/projectexplorer/msvctoolchain.h +++ b/src/plugins/projectexplorer/msvctoolchain.h @@ -73,7 +73,7 @@ public: QVariantMap toMap() const override; bool fromMap(const QVariantMap &data) override; - ToolChainConfigWidget *configurationWidget() override; + std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override; ToolChain *clone() const override; @@ -127,7 +127,7 @@ public: ToolChain *clone() const override; QVariantMap toMap() const override; bool fromMap(const QVariantMap &data) override; - ToolChainConfigWidget *configurationWidget() override; + std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override; const QList<MsvcToolChain *> &msvcToolchains() const; QString clangPath() const { return m_clangPath; } diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h index 0f463bf801..7b41968d06 100644 --- a/src/plugins/projectexplorer/toolchain.h +++ b/src/plugins/projectexplorer/toolchain.h @@ -146,7 +146,7 @@ public: virtual bool operator ==(const ToolChain &) const; - virtual ToolChainConfigWidget *configurationWidget() = 0; + virtual std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() = 0; virtual bool canClone() const; virtual ToolChain *clone() const = 0; diff --git a/src/plugins/projectexplorer/toolchainoptionspage.cpp b/src/plugins/projectexplorer/toolchainoptionspage.cpp index 562c7c6d62..eff7f3a408 100644 --- a/src/plugins/projectexplorer/toolchainoptionspage.cpp +++ b/src/plugins/projectexplorer/toolchainoptionspage.cpp @@ -48,6 +48,7 @@ #include <QMessageBox> #include <QPushButton> #include <QSpacerItem> +#include <QStackedWidget> #include <QTextStream> #include <QTreeView> #include <QVBoxLayout> @@ -60,11 +61,12 @@ namespace Internal { class ToolChainTreeItem : public TreeItem { public: - ToolChainTreeItem(ToolChain *tc, bool c) : + ToolChainTreeItem(QStackedWidget *parentWidget, ToolChain *tc, bool c) : toolChain(tc), changed(c) { - widget = tc->configurationWidget(); + widget = tc->createConfigurationWidget().release(); if (widget) { + parentWidget->addWidget(widget); if (tc->isAutoDetected()) widget->makeReadOnly(); QObject::connect(widget, &ToolChainConfigWidget::dirty, @@ -132,9 +134,6 @@ public: m_model.rootItem()->appendChild(autoRoot); m_model.rootItem()->appendChild(manualRoot); - foreach (ToolChain *tc, ToolChainManager::toolChains()) - insertToolChain(tc); - m_toolChainView = new QTreeView(this); m_toolChainView->setUniformRowHeights(true); m_toolChainView->setSelectionMode(QAbstractItemView::SingleSelection); @@ -174,6 +173,12 @@ public: m_container->setState(DetailsWidget::NoSummary); m_container->setVisible(false); + m_widgetStack = new QStackedWidget; + m_container->setWidget(m_widgetStack); + + foreach (ToolChain *tc, ToolChainManager::toolChains()) + insertToolChain(tc); + auto buttonLayout = new QVBoxLayout; buttonLayout->setSpacing(6); buttonLayout->setContentsMargins(0, 0, 0, 0); @@ -234,6 +239,7 @@ public: QList<ToolChainFactory *> m_factories; QTreeView *m_toolChainView; DetailsWidget *m_container; + QStackedWidget *m_widgetStack; QPushButton *m_addButton; QPushButton *m_cloneButton; QPushButton *m_delButton; @@ -260,8 +266,9 @@ void ToolChainOptionsWidget::markForRemoval(ToolChainTreeItem *item) ToolChainTreeItem *ToolChainOptionsWidget::insertToolChain(ToolChain *tc, bool changed) { StaticTreeItem *parent = parentForToolChain(tc); - auto item = new ToolChainTreeItem(tc, changed); + auto item = new ToolChainTreeItem(m_widgetStack, tc, changed); parent->appendChild(item); + return item; } @@ -308,13 +315,10 @@ StaticTreeItem *ToolChainOptionsWidget::parentForToolChain(ToolChain *tc) void ToolChainOptionsWidget::toolChainSelectionChanged() { ToolChainTreeItem *item = currentTreeItem(); - QWidget *oldWidget = m_container->takeWidget(); // Prevent deletion. - if (oldWidget) - oldWidget->setVisible(false); QWidget *currentTcWidget = item ? item->widget : nullptr; - m_container->setWidget(currentTcWidget); + m_widgetStack->setCurrentWidget(currentTcWidget); m_container->setVisible(currentTcWidget); updateState(); } diff --git a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp index 39b465bea4..3d4329ffb4 100644 --- a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp +++ b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp @@ -281,6 +281,7 @@ QList<ToolChain *> ToolChainSettingsAccessor::toolChains(const QVariantMap &data #include "headerpath.h" #include "abi.h" +#include "toolchainconfigwidget.h" #include <QSet> #include <QTest> @@ -318,7 +319,7 @@ public: QString makeCommand(const Environment &env) const override { Q_UNUSED(env); return QString("make"); } FileName compilerCommand() const override { return Utils::FileName::fromString("/tmp/test/gcc"); } IOutputParser *outputParser() const override { return nullptr; } - ToolChainConfigWidget *configurationWidget() override { return nullptr; } + std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override { return nullptr; } TTC *clone() const override { return new TTC(*this); } bool operator ==(const ToolChain &other) const override { if (!ToolChain::operator==(other)) diff --git a/src/plugins/qnx/qnxtoolchain.cpp b/src/plugins/qnx/qnxtoolchain.cpp index 219c089e67..63c9c3dc56 100644 --- a/src/plugins/qnx/qnxtoolchain.cpp +++ b/src/plugins/qnx/qnxtoolchain.cpp @@ -118,9 +118,9 @@ QString QnxToolChain::typeDisplayName() const return QnxToolChainFactory::tr("QCC"); } -ToolChainConfigWidget *QnxToolChain::configurationWidget() +std::unique_ptr<ToolChainConfigWidget> QnxToolChain::createConfigurationWidget() { - return new QnxToolChainConfigWidget(this); + return std::make_unique<QnxToolChainConfigWidget>(this); } void QnxToolChain::addToEnvironment(Environment &env) const diff --git a/src/plugins/qnx/qnxtoolchain.h b/src/plugins/qnx/qnxtoolchain.h index 1d930a80d3..8fe11673fd 100644 --- a/src/plugins/qnx/qnxtoolchain.h +++ b/src/plugins/qnx/qnxtoolchain.h @@ -39,7 +39,7 @@ public: QString typeDisplayName() const override; - ProjectExplorer::ToolChainConfigWidget *configurationWidget() override; + std::unique_ptr<ProjectExplorer::ToolChainConfigWidget> createConfigurationWidget() override; void addToEnvironment(Utils::Environment &env) const override; Utils::FileNameList suggestedMkspecList() const override; |