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;
|
||||
}
|
||||
|
||||
ToolChainConfigWidget *AndroidToolChain::configurationWidget()
|
||||
std::unique_ptr<ToolChainConfigWidget> AndroidToolChain::createConfigurationWidget()
|
||||
{
|
||||
return new AndroidToolChainConfigWidget(this);
|
||||
return std::make_unique<AndroidToolChainConfigWidget>(this);
|
||||
}
|
||||
|
||||
FileName AndroidToolChain::suggestedDebugger() const
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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 {
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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; }
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -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))
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user