From b250c073b587694d732313ee1a1d0a16ae69dec9 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Tue, 17 Jan 2017 17:43:44 +0100 Subject: [PATCH] Core: Fix memory leak in InfoBarEntry Use like InfoBarEntry info(id, text); info.setShowDefaultCancelButton(false); leaked the infoWidgetCloseButton. Fix the memory leak and improve the API to avoid inconsistent state. Change-Id: If2e06a8a5239e4f902a883da82122c3a27df48a6 Reviewed-by: David Schulz --- src/plugins/coreplugin/infobar.cpp | 31 ++++++++++++------- src/plugins/coreplugin/infobar.h | 4 +-- .../cppeditor/cppminimizableinfobars.cpp | 2 +- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/plugins/coreplugin/infobar.cpp b/src/plugins/coreplugin/infobar.cpp index 7c301af8a30..5738789b792 100644 --- a/src/plugins/coreplugin/infobar.cpp +++ b/src/plugins/coreplugin/infobar.cpp @@ -59,18 +59,22 @@ void InfoBarEntry::setCustomButtonInfo(const QString &_buttonText, CallBack call void InfoBarEntry::setCancelButtonInfo(CallBack callBack) { + m_useCancelButton = true; m_cancelButtonCallBack = callBack; } void InfoBarEntry::setCancelButtonInfo(const QString &_cancelButtonText, CallBack callBack) { + m_useCancelButton = true; cancelButtonText = _cancelButtonText; m_cancelButtonCallBack = callBack; } -void InfoBarEntry::setShowDefaultCancelButton(bool yesno) +void InfoBarEntry::removeCancelButton() { - m_showDefaultCancelButton = yesno; + m_useCancelButton = false; + cancelButtonText.clear(); + m_cancelButtonCallBack = nullptr; } void InfoBarEntry::setDetailsWidgetCreator(const InfoBarEntry::DetailsWidgetCreator &creator) @@ -283,17 +287,20 @@ void InfoBarDisplay::update() }); } - QToolButton *infoWidgetCloseButton = new QToolButton; - // need to connect to cancelObjectbefore connecting to cancelButtonClicked, - // because the latter removes the button and with it any connect - if (info.m_cancelButtonCallBack) - connect(infoWidgetCloseButton, &QAbstractButton::clicked, info.m_cancelButtonCallBack); - connect(infoWidgetCloseButton, &QAbstractButton::clicked, this, [this, id] { - m_infoBar->suppressInfo(id); - }); + QToolButton *infoWidgetCloseButton = nullptr; + if (info.m_useCancelButton) { + infoWidgetCloseButton = new QToolButton; + // need to connect to cancelObjectbefore connecting to cancelButtonClicked, + // because the latter removes the button and with it any connect + if (info.m_cancelButtonCallBack) + connect(infoWidgetCloseButton, &QAbstractButton::clicked, info.m_cancelButtonCallBack); + connect(infoWidgetCloseButton, &QAbstractButton::clicked, this, [this, id] { + m_infoBar->suppressInfo(id); + }); + } if (info.cancelButtonText.isEmpty()) { - if (info.m_showDefaultCancelButton) { + if (infoWidgetCloseButton) { infoWidgetCloseButton->setAutoRaise(true); infoWidgetCloseButton->setIcon(Utils::Icons::CLOSE_FOREGROUND.icon()); infoWidgetCloseButton->setToolTip(tr("Close")); @@ -302,7 +309,7 @@ void InfoBarDisplay::update() if (infoWidgetSuppressButton) hbox->addWidget(infoWidgetSuppressButton); - if (info.m_showDefaultCancelButton) + if (infoWidgetCloseButton) hbox->addWidget(infoWidgetCloseButton); } else { infoWidgetCloseButton->setText(info.cancelButtonText); diff --git a/src/plugins/coreplugin/infobar.h b/src/plugins/coreplugin/infobar.h index c5d1120fc33..a11c1e0d3a4 100644 --- a/src/plugins/coreplugin/infobar.h +++ b/src/plugins/coreplugin/infobar.h @@ -58,7 +58,7 @@ public: void setCustomButtonInfo(const QString &_buttonText, CallBack callBack); void setCancelButtonInfo(CallBack callBack); void setCancelButtonInfo(const QString &_cancelButtonText, CallBack callBack); - void setShowDefaultCancelButton(bool yesno); + void removeCancelButton(); using DetailsWidgetCreator = std::function; void setDetailsWidgetCreator(const DetailsWidgetCreator &creator); @@ -72,7 +72,7 @@ private: CallBack m_cancelButtonCallBack; GlobalSuppressionMode globalSuppression; DetailsWidgetCreator m_detailsWidgetCreator; - bool m_showDefaultCancelButton = true; + bool m_useCancelButton = true; friend class InfoBar; friend class InfoBarDisplay; }; diff --git a/src/plugins/cppeditor/cppminimizableinfobars.cpp b/src/plugins/cppeditor/cppminimizableinfobars.cpp index 949e49f2800..0e4fcaabd20 100644 --- a/src/plugins/cppeditor/cppminimizableinfobars.cpp +++ b/src/plugins/cppeditor/cppminimizableinfobars.cpp @@ -140,7 +140,7 @@ static InfoBarEntry createMinimizableInfo(const Id &id, QTC_CHECK(minimizer); InfoBarEntry info(id, text); - info.setShowDefaultCancelButton(false); + info.removeCancelButton(); // The minimizer() might delete the "Minimize" button immediately and as // result invalid reads will happen in QToolButton::mouseReleaseEvent(). // Avoid this by running the minimizer in the next event loop iteration.