diff --git a/src/libs/utils/infobar.cpp b/src/libs/utils/infobar.cpp index cb416715725..831ba27e6f2 100644 --- a/src/libs/utils/infobar.cpp +++ b/src/libs/utils/infobar.cpp @@ -85,6 +85,16 @@ InfoBarEntry::InfoBarEntry(Id _id, const QString &_infoText, GlobalSuppression _ { } +Id InfoBarEntry::id() const +{ + return m_id; +} + +QString InfoBarEntry::text() const +{ + return m_infoText; +} + void InfoBarEntry::addCustomButton(const QString &buttonText, CallBack callBack, const QString &tooltip) diff --git a/src/libs/utils/infobar.h b/src/libs/utils/infobar.h index d6562b8b59f..df015c96883 100644 --- a/src/libs/utils/infobar.h +++ b/src/libs/utils/infobar.h @@ -54,8 +54,12 @@ public: Enabled }; + InfoBarEntry() = default; InfoBarEntry(Id _id, const QString &_infoText, GlobalSuppression _globalSuppression = GlobalSuppression::Disabled); + Id id() const; + QString text() const; + using CallBack = std::function; void addCustomButton(const QString &_buttonText, CallBack callBack, const QString &tooltip = {}); void setCancelButtonInfo(CallBack callBack); diff --git a/src/plugins/cppeditor/cppeditordocument.cpp b/src/plugins/cppeditor/cppeditordocument.cpp index b14c2dae469..442fd8036d6 100644 --- a/src/plugins/cppeditor/cppeditordocument.cpp +++ b/src/plugins/cppeditor/cppeditordocument.cpp @@ -55,6 +55,8 @@ #include +const char NO_PROJECT_CONFIGURATION[] = "NoProject"; + namespace { CppEditor::CppModelManager *mm() @@ -129,6 +131,10 @@ CppEditorDocument::CppEditorDocument() this, &CppEditorDocument::reparseWithPreferredParseContext); m_minimizableInfoBars.setSettingsGroup(Constants::CPPEDITOR_SETTINGSGROUP); + m_minimizableInfoBars.setPossibleInfoBarEntries( + {{NO_PROJECT_CONFIGURATION, + tr("Warning: This file is not part of any project. " + "The code model might have issues parsing this file properly.")}}); // See also onFilePathChanged() for more initialization } @@ -420,7 +426,7 @@ BaseEditorDocumentProcessor *CppEditorDocument::processor() [this] (const ProjectPartInfo &info) { const bool hasProjectPart = !(info.hints & ProjectPartInfo::IsFallbackMatch); - m_minimizableInfoBars.processHasProjectPart(hasProjectPart); + m_minimizableInfoBars.setInfoVisible(NO_PROJECT_CONFIGURATION, !hasProjectPart); m_parseContextModel.update(info); const bool isAmbiguous = info.hints & ProjectPartInfo::IsAmbiguousMatch; const bool isProjectFile = info.hints & ProjectPartInfo::IsFromProjectMatch; diff --git a/src/plugins/cppeditor/cppminimizableinfobars.cpp b/src/plugins/cppeditor/cppminimizableinfobars.cpp index 25c24c3d60b..daef096f208 100644 --- a/src/plugins/cppeditor/cppminimizableinfobars.cpp +++ b/src/plugins/cppeditor/cppminimizableinfobars.cpp @@ -32,7 +32,6 @@ #include #include -const char NO_PROJECT_CONFIGURATION[] = "NoProject"; const char SETTINGS_PREFIX[] = "ShowInfoBarFor"; const bool kShowInInfoBarDefault = true; @@ -45,6 +44,17 @@ namespace Internal { MinimizableInfoBars::MinimizableInfoBars(InfoBar &infoBar) : m_infoBar(infoBar) { +} + +void MinimizableInfoBars::setPossibleInfoBarEntries(const QList &entries) +{ + QTC_CHECK(m_actions.isEmpty()); + m_infoEntries.clear(); + m_isInfoVisible.clear(); + for (const Utils::InfoBarEntry &entry : entries) { + m_infoEntries.insert(entry.id(), entry); + m_isInfoVisible.insert(entry.id(), false); + } createActions(); } @@ -55,15 +65,19 @@ void MinimizableInfoBars::setSettingsGroup(const QString &settingsGroup) void MinimizableInfoBars::createActions() { - auto action = new QAction(this); - action->setToolTip(tr("File is not part of any project.")); - action->setIcon(Icons::WARNING_TOOLBAR.pixmap()); - connect(action, &QAction::triggered, this, [this]() { - setShowInInfoBar(NO_PROJECT_CONFIGURATION, true); - updateNoProjectConfiguration(); - }); - action->setVisible(!showInInfoBar(NO_PROJECT_CONFIGURATION)); - m_actions.insert(NO_PROJECT_CONFIGURATION, action); + QTC_CHECK(m_actions.isEmpty()); + for (const Utils::InfoBarEntry &entry : qAsConst(m_infoEntries)) { + const Id id = entry.id(); + auto action = new QAction(this); + action->setToolTip(entry.text()); + action->setIcon(Icons::WARNING_TOOLBAR.pixmap()); + connect(action, &QAction::triggered, this, [this, id]() { + setShowInInfoBar(id, true); + updateInfo(id); + }); + action->setVisible(!showInInfoBar(id)); + m_actions.insert(id, action); + } } QString MinimizableInfoBars::settingsKey(const Id &id) const @@ -87,21 +101,21 @@ void MinimizableInfoBars::createShowInfoBarActions(const ActionCreator &actionCr } } -void MinimizableInfoBars::processHasProjectPart(bool hasProjectPart) +void MinimizableInfoBars::setInfoVisible(const Id &id, bool visible) { - m_hasProjectPart = hasProjectPart; - updateNoProjectConfiguration(); + QTC_CHECK(m_isInfoVisible.contains(id)); + m_isInfoVisible.insert(id, visible); + updateInfo(id); } -void MinimizableInfoBars::updateNoProjectConfiguration() +void MinimizableInfoBars::updateInfo(const Id &id) { - const Id id(NO_PROJECT_CONFIGURATION); m_infoBar.removeInfo(id); bool show = false; - if (!m_hasProjectPart) { + if (m_isInfoVisible.value(id)) { if (showInInfoBar(id)) - addNoProjectConfigurationEntry(id); + showInfoBar(id); else show = true; } @@ -111,35 +125,24 @@ void MinimizableInfoBars::updateNoProjectConfiguration() action->setVisible(show); } -static InfoBarEntry createMinimizableInfo(const Id &id, - const QString &text, - QObject *guard, - std::function minimizer) +void MinimizableInfoBars::showInfoBar(const Id &id) { - QTC_CHECK(minimizer); - - InfoBarEntry info(id, text); + const InfoBarEntry entry = m_infoEntries.value(id); + InfoBarEntry info(entry); 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. - info.addCustomButton(MinimizableInfoBars::tr("Minimize"), [guard, minimizer] { + info.addCustomButton(MinimizableInfoBars::tr("Minimize"), [this, id] { QMetaObject::invokeMethod( - guard, [minimizer] { minimizer(); }, Qt::QueuedConnection); + this, + [id, this] { + setShowInInfoBar(id, false); + updateInfo(id); + }, + Qt::QueuedConnection); }); - - return info; -} - -void MinimizableInfoBars::addNoProjectConfigurationEntry(const Id &id) -{ - const QString text = tr("Warning: This file is not part of any project. " - "The code model might have issues parsing this file properly."); - - m_infoBar.addInfo(createMinimizableInfo(id, text, this, [this, id]() { - setShowInInfoBar(id, false); - updateNoProjectConfiguration(); - })); + m_infoBar.addInfo(info); } bool MinimizableInfoBars::showInInfoBar(const Id &id) const diff --git a/src/plugins/cppeditor/cppminimizableinfobars.h b/src/plugins/cppeditor/cppminimizableinfobars.h index 8eb9ab9802d..2bd6a28a49d 100644 --- a/src/plugins/cppeditor/cppminimizableinfobars.h +++ b/src/plugins/cppeditor/cppminimizableinfobars.h @@ -26,6 +26,7 @@ #pragma once #include +#include #include #include @@ -33,10 +34,6 @@ #include -namespace Utils { -class InfoBar; -} - namespace CppEditor { namespace Internal { @@ -51,9 +48,11 @@ public: explicit MinimizableInfoBars(Utils::InfoBar &infoBar); void setSettingsGroup(const QString &settingsGroup); + void setPossibleInfoBarEntries(const QList &entries); + void createShowInfoBarActions(const ActionCreator &actionCreator) const; - void processHasProjectPart(bool hasProjectPart); + void setInfoVisible(const Utils::Id &id, bool visible); private: void createActions(); @@ -62,16 +61,16 @@ private: bool showInInfoBar(const Utils::Id &id) const; void setShowInInfoBar(const Utils::Id &id, bool show); - void updateNoProjectConfiguration(); + void updateInfo(const Utils::Id &id); - void addNoProjectConfigurationEntry(const Utils::Id &id); + void showInfoBar(const Utils::Id &id); private: Utils::InfoBar &m_infoBar; QString m_settingsGroup; QHash m_actions; - - bool m_hasProjectPart = true; + QHash m_isInfoVisible; + QHash m_infoEntries; }; } // namespace Internal