From 52560ce650f6d3a17fcb9dd78abbee1ea8fa7151 Mon Sep 17 00:00:00 2001 From: Kacper Donat Date: Sun, 5 May 2024 16:55:55 +0200 Subject: [PATCH] Gui: Reuse QActions for workbench activation This fixes segfault that can occour due to keeping reference to QAction that is supposed to change workbench. --- src/Gui/Action.cpp | 30 +++++++++++++++++++++++------- src/Gui/Action.h | 10 ++++++++-- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/Gui/Action.cpp b/src/Gui/Action.cpp index 3806703c8f..ddac2f35bd 100644 --- a/src/Gui/Action.cpp +++ b/src/Gui/Action.cpp @@ -627,6 +627,14 @@ WorkbenchGroup::WorkbenchGroup ( Command* pcCmd, QObject * parent ) this, &WorkbenchGroup::onWorkbenchActivated); } +QAction* WorkbenchGroup::getOrCreateAction(const QString& wbName) { + if (!actionByWorkbenchName.contains(wbName)) { + actionByWorkbenchName[wbName] = new QAction; + } + + return actionByWorkbenchName[wbName]; +} + void WorkbenchGroup::addTo(QWidget *widget) { if (widget->inherits("QToolBar")) { @@ -657,13 +665,13 @@ void WorkbenchGroup::addTo(QWidget *widget) void WorkbenchGroup::refreshWorkbenchList() { - QStringList enabled_wbs_list = DlgSettingsWorkbenchesImp::getEnabledWorkbenches(); + QStringList enabledWbNames = DlgSettingsWorkbenchesImp::getEnabledWorkbenches(); // Clear the actions. for (QAction* action : actions()) { groupAction()->removeAction(action); - delete action; } + enabledWbsActions.clear(); disabledWbsActions.clear(); @@ -671,12 +679,16 @@ void WorkbenchGroup::refreshWorkbenchList() // Create action list of enabled wb int index = 0; - for (const auto& wbName : enabled_wbs_list) { + for (const auto& wbName : enabledWbNames) { QString name = Application::Instance->workbenchMenuText(wbName); QPixmap px = Application::Instance->workbenchIcon(wbName); QString tip = Application::Instance->workbenchToolTip(wbName); - QAction* action = groupAction()->addAction(name); + QAction* action = getOrCreateAction(wbName); + + groupAction()->addAction(action); + + action->setText(name); action->setCheckable(true); action->setData(QVariant(index)); // set the index action->setObjectName(wbName); @@ -694,13 +706,17 @@ void WorkbenchGroup::refreshWorkbenchList() } // Also create action list of disabled wbs - QStringList disabled_wbs_list = DlgSettingsWorkbenchesImp::getDisabledWorkbenches(); - for (const auto& wbName : disabled_wbs_list) { + QStringList disabledWbNames = DlgSettingsWorkbenchesImp::getDisabledWorkbenches(); + for (const auto& wbName : disabledWbNames) { QString name = Application::Instance->workbenchMenuText(wbName); QPixmap px = Application::Instance->workbenchIcon(wbName); QString tip = Application::Instance->workbenchToolTip(wbName); - QAction* action = groupAction()->addAction(name); + QAction* action = getOrCreateAction(wbName); + + groupAction()->addAction(action); + + action->setText(name); action->setCheckable(true); action->setData(QVariant(index)); // set the index action->setObjectName(wbName); diff --git a/src/Gui/Action.h b/src/Gui/Action.h index 54f83c4acd..1ae1062a15 100644 --- a/src/Gui/Action.h +++ b/src/Gui/Action.h @@ -28,6 +28,7 @@ #include #include #include +#include #include namespace Gui @@ -188,13 +189,16 @@ class GuiExport WorkbenchGroup : public ActionGroup { Q_OBJECT + QAction* getOrCreateAction(const QString& wbName); + public: /** * Creates an action for the command \a pcCmd to load the workbench \a name * when it gets activated. */ - WorkbenchGroup (Command* pcCmd, QObject * parent); - void addTo (QWidget * widget) override; + WorkbenchGroup(Command* pcCmd, QObject* parent); + + void addTo(QWidget * widget) override; void refreshWorkbenchList(); void slotActivateWorkbench(const char*); @@ -212,6 +216,8 @@ private: QList enabledWbsActions; QList disabledWbsActions; + QMap actionByWorkbenchName; + Q_DISABLE_COPY(WorkbenchGroup) };