forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -181,9 +181,9 @@ bool AndroidToolChain::operator ==(const ToolChain &tc) const
|
|||||||
return m_ndkToolChainVersion == static_cast<const AndroidToolChain &>(tc).m_ndkToolChainVersion;
|
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
|
FileName AndroidToolChain::suggestedDebugger() const
|
||||||
|
@@ -44,7 +44,7 @@ public:
|
|||||||
|
|
||||||
bool operator ==(const ProjectExplorer::ToolChain &) const override;
|
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 suggestedDebugger() const override;
|
||||||
Utils::FileName suggestedGdbServer() const;
|
Utils::FileName suggestedGdbServer() const;
|
||||||
|
|
||||||
|
@@ -136,9 +136,9 @@ IOutputParser *NimToolChain::outputParser() const
|
|||||||
return nullptr;
|
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
|
ToolChain *NimToolChain::clone() const
|
||||||
|
@@ -54,7 +54,7 @@ public:
|
|||||||
QString compilerVersion() const;
|
QString compilerVersion() const;
|
||||||
void setCompilerCommand(const Utils::FileName &compilerCommand);
|
void setCompilerCommand(const Utils::FileName &compilerCommand);
|
||||||
ProjectExplorer::IOutputParser *outputParser() const final;
|
ProjectExplorer::IOutputParser *outputParser() const final;
|
||||||
ProjectExplorer::ToolChainConfigWidget *configurationWidget() final;
|
std::unique_ptr<ProjectExplorer::ToolChainConfigWidget> createConfigurationWidget() final;
|
||||||
ProjectExplorer::ToolChain *clone() const final;
|
ProjectExplorer::ToolChain *clone() const final;
|
||||||
|
|
||||||
QVariantMap toMap() const final;
|
QVariantMap toMap() const final;
|
||||||
|
@@ -412,9 +412,9 @@ QList<CustomToolChain::Parser> CustomToolChain::parsers()
|
|||||||
return result;
|
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 {
|
namespace Internal {
|
||||||
|
@@ -90,7 +90,7 @@ public:
|
|||||||
QVariantMap toMap() const override;
|
QVariantMap toMap() const override;
|
||||||
bool fromMap(const QVariantMap &data) override;
|
bool fromMap(const QVariantMap &data) override;
|
||||||
|
|
||||||
ToolChainConfigWidget *configurationWidget() override;
|
std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override;
|
||||||
|
|
||||||
bool operator ==(const ToolChain &) const override;
|
bool operator ==(const ToolChain &) const override;
|
||||||
|
|
||||||
|
@@ -861,9 +861,9 @@ bool GccToolChain::operator ==(const ToolChain &other) const
|
|||||||
&& m_platformLinkerFlags == gccTc->m_platformLinkerFlags;
|
&& 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
|
void GccToolChain::updateSupportedAbis() const
|
||||||
|
@@ -158,7 +158,7 @@ public:
|
|||||||
QVariantMap toMap() const override;
|
QVariantMap toMap() const override;
|
||||||
bool fromMap(const QVariantMap &data) override;
|
bool fromMap(const QVariantMap &data) override;
|
||||||
|
|
||||||
ToolChainConfigWidget *configurationWidget() override;
|
std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override;
|
||||||
|
|
||||||
bool operator ==(const ToolChain &) const override;
|
bool operator ==(const ToolChain &) const override;
|
||||||
|
|
||||||
|
@@ -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
|
ToolChain *MsvcToolChain::clone() const
|
||||||
@@ -1048,9 +1048,9 @@ bool ClangClToolChain::fromMap(const QVariantMap &data)
|
|||||||
return true;
|
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)
|
void ClangClToolChain::resetMsvcToolChain(const MsvcToolChain *base)
|
||||||
|
@@ -73,7 +73,7 @@ public:
|
|||||||
QVariantMap toMap() const override;
|
QVariantMap toMap() const override;
|
||||||
bool fromMap(const QVariantMap &data) override;
|
bool fromMap(const QVariantMap &data) override;
|
||||||
|
|
||||||
ToolChainConfigWidget *configurationWidget() override;
|
std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override;
|
||||||
|
|
||||||
ToolChain *clone() const override;
|
ToolChain *clone() const override;
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ public:
|
|||||||
ToolChain *clone() const override;
|
ToolChain *clone() const override;
|
||||||
QVariantMap toMap() const override;
|
QVariantMap toMap() const override;
|
||||||
bool fromMap(const QVariantMap &data) override;
|
bool fromMap(const QVariantMap &data) override;
|
||||||
ToolChainConfigWidget *configurationWidget() override;
|
std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() override;
|
||||||
|
|
||||||
const QList<MsvcToolChain *> &msvcToolchains() const;
|
const QList<MsvcToolChain *> &msvcToolchains() const;
|
||||||
QString clangPath() const { return m_clangPath; }
|
QString clangPath() const { return m_clangPath; }
|
||||||
|
@@ -146,7 +146,7 @@ public:
|
|||||||
|
|
||||||
virtual bool operator ==(const ToolChain &) const;
|
virtual bool operator ==(const ToolChain &) const;
|
||||||
|
|
||||||
virtual ToolChainConfigWidget *configurationWidget() = 0;
|
virtual std::unique_ptr<ToolChainConfigWidget> createConfigurationWidget() = 0;
|
||||||
virtual bool canClone() const;
|
virtual bool canClone() const;
|
||||||
virtual ToolChain *clone() const = 0;
|
virtual ToolChain *clone() const = 0;
|
||||||
|
|
||||||
|
@@ -48,6 +48,7 @@
|
|||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QSpacerItem>
|
#include <QSpacerItem>
|
||||||
|
#include <QStackedWidget>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QTreeView>
|
#include <QTreeView>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
@@ -60,11 +61,12 @@ namespace Internal {
|
|||||||
class ToolChainTreeItem : public TreeItem
|
class ToolChainTreeItem : public TreeItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ToolChainTreeItem(ToolChain *tc, bool c) :
|
ToolChainTreeItem(QStackedWidget *parentWidget, ToolChain *tc, bool c) :
|
||||||
toolChain(tc), changed(c)
|
toolChain(tc), changed(c)
|
||||||
{
|
{
|
||||||
widget = tc->configurationWidget();
|
widget = tc->createConfigurationWidget().release();
|
||||||
if (widget) {
|
if (widget) {
|
||||||
|
parentWidget->addWidget(widget);
|
||||||
if (tc->isAutoDetected())
|
if (tc->isAutoDetected())
|
||||||
widget->makeReadOnly();
|
widget->makeReadOnly();
|
||||||
QObject::connect(widget, &ToolChainConfigWidget::dirty,
|
QObject::connect(widget, &ToolChainConfigWidget::dirty,
|
||||||
@@ -132,9 +134,6 @@ public:
|
|||||||
m_model.rootItem()->appendChild(autoRoot);
|
m_model.rootItem()->appendChild(autoRoot);
|
||||||
m_model.rootItem()->appendChild(manualRoot);
|
m_model.rootItem()->appendChild(manualRoot);
|
||||||
|
|
||||||
foreach (ToolChain *tc, ToolChainManager::toolChains())
|
|
||||||
insertToolChain(tc);
|
|
||||||
|
|
||||||
m_toolChainView = new QTreeView(this);
|
m_toolChainView = new QTreeView(this);
|
||||||
m_toolChainView->setUniformRowHeights(true);
|
m_toolChainView->setUniformRowHeights(true);
|
||||||
m_toolChainView->setSelectionMode(QAbstractItemView::SingleSelection);
|
m_toolChainView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
@@ -174,6 +173,12 @@ public:
|
|||||||
m_container->setState(DetailsWidget::NoSummary);
|
m_container->setState(DetailsWidget::NoSummary);
|
||||||
m_container->setVisible(false);
|
m_container->setVisible(false);
|
||||||
|
|
||||||
|
m_widgetStack = new QStackedWidget;
|
||||||
|
m_container->setWidget(m_widgetStack);
|
||||||
|
|
||||||
|
foreach (ToolChain *tc, ToolChainManager::toolChains())
|
||||||
|
insertToolChain(tc);
|
||||||
|
|
||||||
auto buttonLayout = new QVBoxLayout;
|
auto buttonLayout = new QVBoxLayout;
|
||||||
buttonLayout->setSpacing(6);
|
buttonLayout->setSpacing(6);
|
||||||
buttonLayout->setContentsMargins(0, 0, 0, 0);
|
buttonLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
@@ -234,6 +239,7 @@ public:
|
|||||||
QList<ToolChainFactory *> m_factories;
|
QList<ToolChainFactory *> m_factories;
|
||||||
QTreeView *m_toolChainView;
|
QTreeView *m_toolChainView;
|
||||||
DetailsWidget *m_container;
|
DetailsWidget *m_container;
|
||||||
|
QStackedWidget *m_widgetStack;
|
||||||
QPushButton *m_addButton;
|
QPushButton *m_addButton;
|
||||||
QPushButton *m_cloneButton;
|
QPushButton *m_cloneButton;
|
||||||
QPushButton *m_delButton;
|
QPushButton *m_delButton;
|
||||||
@@ -260,8 +266,9 @@ void ToolChainOptionsWidget::markForRemoval(ToolChainTreeItem *item)
|
|||||||
ToolChainTreeItem *ToolChainOptionsWidget::insertToolChain(ToolChain *tc, bool changed)
|
ToolChainTreeItem *ToolChainOptionsWidget::insertToolChain(ToolChain *tc, bool changed)
|
||||||
{
|
{
|
||||||
StaticTreeItem *parent = parentForToolChain(tc);
|
StaticTreeItem *parent = parentForToolChain(tc);
|
||||||
auto item = new ToolChainTreeItem(tc, changed);
|
auto item = new ToolChainTreeItem(m_widgetStack, tc, changed);
|
||||||
parent->appendChild(item);
|
parent->appendChild(item);
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,13 +315,10 @@ StaticTreeItem *ToolChainOptionsWidget::parentForToolChain(ToolChain *tc)
|
|||||||
void ToolChainOptionsWidget::toolChainSelectionChanged()
|
void ToolChainOptionsWidget::toolChainSelectionChanged()
|
||||||
{
|
{
|
||||||
ToolChainTreeItem *item = currentTreeItem();
|
ToolChainTreeItem *item = currentTreeItem();
|
||||||
QWidget *oldWidget = m_container->takeWidget(); // Prevent deletion.
|
|
||||||
if (oldWidget)
|
|
||||||
oldWidget->setVisible(false);
|
|
||||||
|
|
||||||
QWidget *currentTcWidget = item ? item->widget : nullptr;
|
QWidget *currentTcWidget = item ? item->widget : nullptr;
|
||||||
|
|
||||||
m_container->setWidget(currentTcWidget);
|
m_widgetStack->setCurrentWidget(currentTcWidget);
|
||||||
m_container->setVisible(currentTcWidget);
|
m_container->setVisible(currentTcWidget);
|
||||||
updateState();
|
updateState();
|
||||||
}
|
}
|
||||||
|
@@ -281,6 +281,7 @@ QList<ToolChain *> ToolChainSettingsAccessor::toolChains(const QVariantMap &data
|
|||||||
#include "headerpath.h"
|
#include "headerpath.h"
|
||||||
|
|
||||||
#include "abi.h"
|
#include "abi.h"
|
||||||
|
#include "toolchainconfigwidget.h"
|
||||||
|
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
@@ -318,7 +319,7 @@ public:
|
|||||||
QString makeCommand(const Environment &env) const override { Q_UNUSED(env); return QString("make"); }
|
QString makeCommand(const Environment &env) const override { Q_UNUSED(env); return QString("make"); }
|
||||||
FileName compilerCommand() const override { return Utils::FileName::fromString("/tmp/test/gcc"); }
|
FileName compilerCommand() const override { return Utils::FileName::fromString("/tmp/test/gcc"); }
|
||||||
IOutputParser *outputParser() const override { return nullptr; }
|
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); }
|
TTC *clone() const override { return new TTC(*this); }
|
||||||
bool operator ==(const ToolChain &other) const override {
|
bool operator ==(const ToolChain &other) const override {
|
||||||
if (!ToolChain::operator==(other))
|
if (!ToolChain::operator==(other))
|
||||||
|
@@ -118,9 +118,9 @@ QString QnxToolChain::typeDisplayName() const
|
|||||||
return QnxToolChainFactory::tr("QCC");
|
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
|
void QnxToolChain::addToEnvironment(Environment &env) const
|
||||||
|
@@ -39,7 +39,7 @@ public:
|
|||||||
|
|
||||||
QString typeDisplayName() const override;
|
QString typeDisplayName() const override;
|
||||||
|
|
||||||
ProjectExplorer::ToolChainConfigWidget *configurationWidget() override;
|
std::unique_ptr<ProjectExplorer::ToolChainConfigWidget> createConfigurationWidget() override;
|
||||||
|
|
||||||
void addToEnvironment(Utils::Environment &env) const override;
|
void addToEnvironment(Utils::Environment &env) const override;
|
||||||
Utils::FileNameList suggestedMkspecList() const override;
|
Utils::FileNameList suggestedMkspecList() const override;
|
||||||
|
Reference in New Issue
Block a user