From 032f743fbf7248855556b4b3507f5eb37d707882 Mon Sep 17 00:00:00 2001 From: 0penBrain <48731257+0penBrain@users.noreply.github.com> Date: Sun, 9 May 2021 09:58:11 +0200 Subject: [PATCH 1/6] [Gui] Introducing user edit mode --- src/Gui/Application.cpp | 44 +++++++++++++++++++++++++++++++++++++++ src/Gui/Application.h | 26 +++++++++++++++++++++++ src/Gui/ApplicationPy.cpp | 38 +++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index d59831672b..a0f2d10742 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -1244,6 +1244,50 @@ void Application::tryClose(QCloseEvent * e) } } +int Application::getUserEditMode(const std::string &mode) const +{ + if (mode.empty()) { + return userEditMode; + } + for (auto const &uem : userEditModes) { + if (uem.second == mode) { + return uem.first; + } + } + return -1; +} + +std::string Application::getUserEditModeName(int mode) const +{ + if (mode == -1) { + return userEditModes.at(userEditMode); + } + if (userEditModes.find(mode) != userEditModes.end()) { + return userEditModes.at(mode); + } + return ""; +} + +bool Application::setUserEditMode(int mode) +{ + if (userEditModes.find(mode) != userEditModes.end() && userEditMode != mode) { + userEditMode = mode; + this->signalUserEditModeChanged(userEditMode); + return true; + } + return false; +} + +bool Application::setUserEditMode(const std::string &mode) +{ + for (auto const &uem : userEditModes) { + if (uem.second == mode) { + return setUserEditMode(uem.first); + } + } + return false; +} + /** * Activate the matching workbench to the registered workbench handler with name \a name. * The handler must be an instance of a class written in Python. diff --git a/src/Gui/Application.h b/src/Gui/Application.h index 0f596d3276..bab862f4f0 100644 --- a/src/Gui/Application.h +++ b/src/Gui/Application.h @@ -27,6 +27,7 @@ #include #include #include +#include #define putpix() @@ -133,6 +134,8 @@ public: boost::signals2::signal signalInEdit; /// signal on leaving edit mode boost::signals2::signal signalResetEdit; + /// signal on changing user edit mode + boost::signals2::signal signalUserEditModeChanged; //@} /** @name methods for Document handling */ @@ -227,6 +230,25 @@ public: static void runApplication(void); void tryClose( QCloseEvent * e ); //@} + + /** @name User edit mode */ + //@{ +protected: + const std::map userEditModes { + {0, "Default"}, + {1, "Transform"}, + {2, "Cutting"}, + {3, "Color"} + }; + int userEditMode = userEditModes.begin()->first; + +public: + std::map listUserEditModes() const { return userEditModes; } + int getUserEditMode(const std::string &mode = "") const; + std::string getUserEditModeName(int mode = -1) const; + bool setUserEditMode(int mode); + bool setUserEditMode(const std::string &mode); + //@} public: //--------------------------------------------------------------------- @@ -293,6 +315,10 @@ public: static PyObject* sAddDocObserver (PyObject *self,PyObject *args); static PyObject* sRemoveDocObserver (PyObject *self,PyObject *args); + + static PyObject* sListUserEditModes (PyObject *self,PyObject *args); + static PyObject* sGetUserEditMode (PyObject *self,PyObject *args); + static PyObject* sSetUserEditMode (PyObject *self,PyObject *args); static PyMethodDef Methods[]; diff --git a/src/Gui/ApplicationPy.cpp b/src/Gui/ApplicationPy.cpp index 13016c977f..61d636a63b 100644 --- a/src/Gui/ApplicationPy.cpp +++ b/src/Gui/ApplicationPy.cpp @@ -205,6 +205,18 @@ PyMethodDef Application::Methods[] = { {"removeDocumentObserver", (PyCFunction) Application::sRemoveDocObserver, METH_VARARGS, "removeDocumentObserver() -> None\n\n" "Remove an added document observer."}, + + {"listUserEditModes", (PyCFunction) Application::sListUserEditModes, METH_VARARGS, + "listUserEditModes() -> list\n\n" + "List available user edit modes"}, + + {"getUserEditMode", (PyCFunction) Application::sGetUserEditMode, METH_VARARGS, + "getUserEditMode() -> string\n\n" + "Get current user edit mode"}, + + {"setUserEditMode", (PyCFunction) Application::sSetUserEditMode, METH_VARARGS, + "setUserEditMode(string=mode) -> Bool\n\n" + "Set user edit mode to 'mode', returns True if exists, false otherwise"}, {"reload", (PyCFunction) Application::sReload, METH_VARARGS, "reload(name) -> doc\n\n" @@ -1485,3 +1497,29 @@ PyObject* Application::sCoinRemoveAllChildren(PyObject * /*self*/, PyObject *arg }PY_CATCH; } +PyObject* Application::sListUserEditModes(PyObject * /*self*/, PyObject *args) +{ + Py::List ret; + if (!PyArg_ParseTuple(args, "")) + return NULL; + for (auto const &uem : Instance->listUserEditModes()) { + ret.append(Py::String(uem.second)); + } + return Py::new_reference_to(ret); +} + +PyObject* Application::sGetUserEditMode(PyObject * /*self*/, PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return NULL; + return Py::new_reference_to(Py::String(Instance->getUserEditModeName())); +} + +PyObject* Application::sSetUserEditMode(PyObject * /*self*/, PyObject *args) +{ + char *mode = ""; + if (!PyArg_ParseTuple(args, "s", &mode)) + return NULL; + bool ok = Instance->setUserEditMode(std::string(mode)); + return Py::new_reference_to(Py::Boolean(ok)); +} From a8e7992a7d48325941a5b06666814b5102105f6e Mon Sep 17 00:00:00 2001 From: 0penBrain <48731257+0penBrain@users.noreply.github.com> Date: Thu, 13 May 2021 08:36:37 +0200 Subject: [PATCH 2/6] [Gui] UserEditMode : take into account in edit command + Mark strings for translation --- src/Gui/Application.h | 8 ++++---- src/Gui/Command.h | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Gui/Application.h b/src/Gui/Application.h index bab862f4f0..edc46d52ed 100644 --- a/src/Gui/Application.h +++ b/src/Gui/Application.h @@ -235,10 +235,10 @@ public: //@{ protected: const std::map userEditModes { - {0, "Default"}, - {1, "Transform"}, - {2, "Cutting"}, - {3, "Color"} + {0, QT_TRANSLATE_NOOP("EditMode", "Default")}, + {1, QT_TRANSLATE_NOOP("EditMode", "Transform")}, + {2, QT_TRANSLATE_NOOP("EditMode", "Cutting")}, + {3, QT_TRANSLATE_NOOP("EditMode", "Color")} }; int userEditMode = userEditModes.begin()->first; diff --git a/src/Gui/Command.h b/src/Gui/Command.h index c3f7a2c982..1660f54079 100644 --- a/src/Gui/Command.h +++ b/src/Gui/Command.h @@ -31,6 +31,7 @@ #include #include +#include /** @defgroup CommandMacros Helper macros for running commands through Python interpreter */ //@{ @@ -179,8 +180,8 @@ auto __obj = _obj;\ if(__obj && __obj->getNameInDocument()) {\ Gui::Command::doCommand(Gui::Command::Gui,\ - "Gui.ActiveDocument.setEdit(App.getDocument('%s').getObject('%s'))",\ - __obj->getDocument()->getName(), __obj->getNameInDocument());\ + "Gui.ActiveDocument.setEdit(App.getDocument('%s').getObject('%s'), %i)",\ + __obj->getDocument()->getName(), __obj->getNameInDocument(), Gui::Application::Instance->getUserEditMode());\ }\ }while(0) From b84bb1a16a76a5185dd6581e714a0b474d604a63 Mon Sep 17 00:00:00 2001 From: 0penBrain <48731257+0penBrain@users.noreply.github.com> Date: Thu, 13 May 2021 11:16:48 +0200 Subject: [PATCH 3/6] [Gui] UserEditMode : add menu and toolbar management --- src/Gui/CommandStd.cpp | 95 ++++++ src/Gui/Icons/EditModeColor.svg | 243 ++++++++++++++ src/Gui/Icons/EditModeCutting.svg | 496 ++++++++++++++++++++++++++++ src/Gui/Icons/EditModeDefault.svg | 396 ++++++++++++++++++++++ src/Gui/Icons/EditModeTransform.svg | 231 +++++++++++++ src/Gui/Icons/resource.qrc | 4 + src/Gui/Workbench.cpp | 4 +- 7 files changed, 1467 insertions(+), 2 deletions(-) create mode 100644 src/Gui/Icons/EditModeColor.svg create mode 100644 src/Gui/Icons/EditModeCutting.svg create mode 100644 src/Gui/Icons/EditModeDefault.svg create mode 100644 src/Gui/Icons/EditModeTransform.svg diff --git a/src/Gui/CommandStd.cpp b/src/Gui/CommandStd.cpp index e62df2d7e8..7ca792d1e9 100644 --- a/src/Gui/CommandStd.cpp +++ b/src/Gui/CommandStd.cpp @@ -29,6 +29,7 @@ # include # include # include +# include #endif #include @@ -63,6 +64,7 @@ using Base::Console; using Base::Sequencer; using namespace Gui; +namespace bp = boost::placeholders; //=========================================================================== @@ -813,6 +815,98 @@ void StdCmdUnitsCalculator::activated(int iMsg) dlg->show(); } +//=========================================================================== +// StdCmdUserEditMode +//=========================================================================== +class StdCmdUserEditMode : public Gui::Command +{ +public: + StdCmdUserEditMode(); + virtual ~StdCmdUserEditMode(){} + virtual void languageChange(); + virtual const char* className() const {return "StdCmdUserEditMode";} + void updateIcon(int mode); +protected: + virtual void activated(int iMsg); + virtual bool isActive(void); + virtual Gui::Action * createAction(void); +}; + +StdCmdUserEditMode::StdCmdUserEditMode() + : Command("Std_UserEditMode") +{ + sGroup = QT_TR_NOOP("Edit mode"); + sMenuText = QT_TR_NOOP("Edit mode"); + sToolTipText = QT_TR_NOOP("Defines behavior when editing an object from tree"); + sStatusTip = QT_TR_NOOP("Defines behavior when editing an object from tree"); + sWhatsThis = "Std_UserEditMode"; + sPixmap = "EditModeDefault"; + eType = ForEdit; + + this->getGuiApplication()->signalUserEditModeChanged.connect(boost::bind(&StdCmdUserEditMode::updateIcon, this, bp::_1)); +} + +Gui::Action * StdCmdUserEditMode::createAction(void) +{ + Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow()); + pcAction->setDropDownMenu(true); + applyCommandData(this->className(), pcAction); + + for (auto const &uem : Gui::Application::Instance->listUserEditModes()) { + QAction* act = pcAction->addAction(QString()); + act->setCheckable(true); + act->setIcon(BitmapFactory().iconFromTheme(qPrintable(QString::fromLatin1("EditMode")+QString::fromStdString(uem.second)))); + act->setObjectName(QString::fromLatin1("Std_EditMode")+QString::fromStdString(uem.second)); + act->setWhatsThis(QString::fromLatin1(getWhatsThis())); + + if (uem.first == 0) { + pcAction->setIcon(act->icon()); + act->setChecked(true); + } + } + + _pcAction = pcAction; + languageChange(); + return pcAction; +} + +void StdCmdUserEditMode::languageChange() +{ + Command::languageChange(); + + if (!_pcAction) + return; + Gui::ActionGroup* pcAction = qobject_cast(_pcAction); + QList a = pcAction->actions(); + + for (int i = 0 ; i < a.count() ; i++) { + auto modeName = Gui::Application::Instance->getUserEditModeName(i); + a[i]->setText(QCoreApplication::translate( + "EditMode", qPrintable(QString::fromStdString(modeName)))); + a[i]->setToolTip(QCoreApplication::translate( + "EditMode", qPrintable(QString::fromStdString(modeName)+QString::fromLatin1(" mode")))); + } +} + +void StdCmdUserEditMode::updateIcon(int mode) +{ + Gui::ActionGroup *actionGroup = dynamic_cast(_pcAction); + if (!actionGroup) + return; + + actionGroup->setCheckedAction(mode); +} + +void StdCmdUserEditMode::activated(int iMsg) +{ + Gui::Application::Instance->setUserEditMode(iMsg); +} + +bool StdCmdUserEditMode::isActive(void) +{ + return true; +} + namespace Gui { void CreateStdCommands(void) @@ -842,6 +936,7 @@ void CreateStdCommands(void) rcCmdMgr.addCommand(new StdCmdPythonWebsite()); rcCmdMgr.addCommand(new StdCmdTextDocument()); rcCmdMgr.addCommand(new StdCmdUnitsCalculator()); + rcCmdMgr.addCommand(new StdCmdUserEditMode()); //rcCmdMgr.addCommand(new StdCmdMeasurementSimple()); //rcCmdMgr.addCommand(new StdCmdDownloadOnlineHelp()); //rcCmdMgr.addCommand(new StdCmdDescription()); diff --git a/src/Gui/Icons/EditModeColor.svg b/src/Gui/Icons/EditModeColor.svg new file mode 100644 index 0000000000..07d832dc28 --- /dev/null +++ b/src/Gui/Icons/EditModeColor.svg @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/src/Gui/Icons/EditModeCutting.svg b/src/Gui/Icons/EditModeCutting.svg new file mode 100644 index 0000000000..fb051257b8 --- /dev/null +++ b/src/Gui/Icons/EditModeCutting.svg @@ -0,0 +1,496 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Edit Cut + + + Garrett Le Sage + + + + + edit + cut + clipboard + + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Gui/Icons/EditModeDefault.svg b/src/Gui/Icons/EditModeDefault.svg new file mode 100644 index 0000000000..a6183e8b0a --- /dev/null +++ b/src/Gui/Icons/EditModeDefault.svg @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Preferences System + + + preferences + settings + control panel + tweaks + system + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Gui/Icons/EditModeTransform.svg b/src/Gui/Icons/EditModeTransform.svg new file mode 100644 index 0000000000..135ac9736e --- /dev/null +++ b/src/Gui/Icons/EditModeTransform.svg @@ -0,0 +1,231 @@ + + + Std_AxisCross + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Std_AxisCross + + + [bitacovir] + + + + + FreeCAD LGPL2+ + + + + + FreeCAD + + + 2020/12/20 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Gui/Icons/resource.qrc b/src/Gui/Icons/resource.qrc index 9de6436fbb..0f0e132595 100644 --- a/src/Gui/Icons/resource.qrc +++ b/src/Gui/Icons/resource.qrc @@ -240,6 +240,10 @@ document-package.svg Std_Alignment.svg Std_DuplicateSelection.svg + EditModeDefault.svg + EditModeTransform.svg + EditModeCutting.svg + EditModeColor.svg diff --git a/src/Gui/Workbench.cpp b/src/Gui/Workbench.cpp index 715d2623c8..bda11719ef 100644 --- a/src/Gui/Workbench.cpp +++ b/src/Gui/Workbench.cpp @@ -587,7 +587,7 @@ MenuItem* StdWorkbench::setupMenuBar() const << "Std_Refresh" << "Std_BoxSelection" << "Std_BoxElementSelection" << "Std_SelectAll" << "Std_Delete" << "Std_SendToPythonConsole" << "Separator" << "Std_Placement" << "Std_TransformManip" << "Std_Alignment" - << "Std_Edit" << "Separator" << "Std_DlgPreferences"; + << "Std_Edit" << "Separator" << "Std_UserEditMode" << "Separator" << "Std_DlgPreferences"; MenuItem* axoviews = new MenuItem; axoviews->setCommand("Axonometric"); @@ -712,7 +712,7 @@ ToolBarItem* StdWorkbench::setupToolBars() const file->setCommand("File"); *file << "Std_New" << "Std_Open" << "Std_Save" << "Std_Print" << "Separator" << "Std_Cut" << "Std_Copy" << "Std_Paste" << "Separator" << "Std_Undo" << "Std_Redo" << "Separator" - << "Std_Refresh" << "Separator" << "Std_WhatsThis"; + << "Std_UserEditMode" << "Separator" << "Std_Refresh" << "Separator" << "Std_WhatsThis"; // Workbench switcher ToolBarItem* wb = new ToolBarItem( root ); From 1e3b9fb166d5ac3400df5f58d7bf6a4358762a9c Mon Sep 17 00:00:00 2001 From: 0penBrain <48731257+0penBrain@users.noreply.github.com> Date: Thu, 13 May 2021 11:30:21 +0200 Subject: [PATCH 4/6] [Gui] UserEditMode : add cross comments in case a new edit mode has to be added --- src/Gui/Application.h | 3 +++ src/Gui/ViewProvider.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/Gui/Application.h b/src/Gui/Application.h index edc46d52ed..6c436f97d9 100644 --- a/src/Gui/Application.h +++ b/src/Gui/Application.h @@ -234,6 +234,9 @@ public: /** @name User edit mode */ //@{ protected: + // the below std::map is a translation of 'EditMode' enum in ViewProvider.h + // to add a new edit mode, it should first be added there + // this is only used for GUI user interaction (menu, toolbar, Python API) const std::map userEditModes { {0, QT_TRANSLATE_NOOP("EditMode", "Default")}, {1, QT_TRANSLATE_NOOP("EditMode", "Transform")}, diff --git a/src/Gui/ViewProvider.h b/src/Gui/ViewProvider.h index 257f5a6167..1d5761a87e 100644 --- a/src/Gui/ViewProvider.h +++ b/src/Gui/ViewProvider.h @@ -420,6 +420,9 @@ public: * you can handle most of the events in the viewer by yourself */ //@{ + // the below enum is reflected in 'userEditModes' std::map in Application.h + // so it is possible for the user to choose a default one through GUI + // if you add a mode here, consider to make it accessible there too enum EditMode {Default = 0, Transform, Cutting, From 688cc987ebdf32677c0f594ad0f2c48530bd7b78 Mon Sep 17 00:00:00 2001 From: 0penBrain <48731257+0penBrain@users.noreply.github.com> Date: Sat, 15 May 2021 10:12:10 +0200 Subject: [PATCH 5/6] [Gui] UserEditMode : minor improvements --- src/Gui/CommandStd.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Gui/CommandStd.cpp b/src/Gui/CommandStd.cpp index 7ca792d1e9..2ee06da8cb 100644 --- a/src/Gui/CommandStd.cpp +++ b/src/Gui/CommandStd.cpp @@ -854,9 +854,10 @@ Gui::Action * StdCmdUserEditMode::createAction(void) for (auto const &uem : Gui::Application::Instance->listUserEditModes()) { QAction* act = pcAction->addAction(QString()); + auto modeName = QString::fromStdString(uem.second); act->setCheckable(true); - act->setIcon(BitmapFactory().iconFromTheme(qPrintable(QString::fromLatin1("EditMode")+QString::fromStdString(uem.second)))); - act->setObjectName(QString::fromLatin1("Std_EditMode")+QString::fromStdString(uem.second)); + act->setIcon(BitmapFactory().iconFromTheme(qPrintable(QString::fromLatin1("EditMode")+modeName))); + act->setObjectName(QString::fromLatin1("Std_EditMode")+modeName); act->setWhatsThis(QString::fromLatin1(getWhatsThis())); if (uem.first == 0) { @@ -880,11 +881,11 @@ void StdCmdUserEditMode::languageChange() QList a = pcAction->actions(); for (int i = 0 ; i < a.count() ; i++) { - auto modeName = Gui::Application::Instance->getUserEditModeName(i); + auto modeName = QString::fromStdString(Gui::Application::Instance->getUserEditModeName(i)); a[i]->setText(QCoreApplication::translate( - "EditMode", qPrintable(QString::fromStdString(modeName)))); + "EditMode", qPrintable(modeName))); a[i]->setToolTip(QCoreApplication::translate( - "EditMode", qPrintable(QString::fromStdString(modeName)+QString::fromLatin1(" mode")))); + "EditMode", qPrintable(modeName+QString::fromLatin1(" mode")))); } } From c87c492ada478ced8f06fb003d21f0e0a3c9f707 Mon Sep 17 00:00:00 2001 From: 0penBrain <48731257+0penBrain@users.noreply.github.com> Date: Sat, 15 May 2021 11:26:20 +0200 Subject: [PATCH 6/6] [Gui] ActionGroup can declared being a "Mode" action This will essentially not update the tooltip when an action is checked as it isn't suitable As example, view DrawStyle command where the group tooltip is better than the selected action tooltip Only UserEditMode is implemented in this commit, should be pushed to DrawStyle and maybe other after merge --- src/Gui/Action.cpp | 6 +++--- src/Gui/Action.h | 2 ++ src/Gui/CommandStd.cpp | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Gui/Action.cpp b/src/Gui/Action.cpp index 9fea44fa97..a8fa8503c3 100644 --- a/src/Gui/Action.cpp +++ b/src/Gui/Action.cpp @@ -227,7 +227,7 @@ void Action::setMenuRole(QAction::MenuRole menuRole) * to the command object. */ ActionGroup::ActionGroup ( Command* pcCmd,QObject * parent) - : Action(pcCmd, parent), _group(0), _dropDown(false),_external(false),_toggle(false) + : Action(pcCmd, parent), _group(0), _dropDown(false),_external(false),_toggle(false),_isMode(false) { _group = new QActionGroup(this); connect(_group, SIGNAL(triggered(QAction*)), this, SLOT(onActivated (QAction*))); @@ -336,7 +336,7 @@ void ActionGroup::setCheckedAction(int i) QAction* a = _group->actions()[i]; a->setChecked(true); this->setIcon(a->icon()); - this->setToolTip(a->toolTip()); + if (!this->_isMode) this->setToolTip(a->toolTip()); this->setProperty("defaultAction", QVariant(i)); } @@ -378,7 +378,7 @@ void ActionGroup::onActivated (QAction* a) } #endif this->setIcon(a->icon()); - this->setToolTip(a->toolTip()); + if (!this->_isMode) this->setToolTip(a->toolTip()); this->setProperty("defaultAction", QVariant(index)); _pcCmd->invoke(index, Command::TriggerChildAction); } diff --git a/src/Gui/Action.h b/src/Gui/Action.h index 5aa6f2c313..d50deb8cb0 100644 --- a/src/Gui/Action.h +++ b/src/Gui/Action.h @@ -107,6 +107,7 @@ public: void setExclusive (bool); bool isExclusive() const; void setVisible (bool); + void setIsMode(bool b) { _isMode = b; } void setDropDownMenu(bool b) { _dropDown = b; } QAction* addAction(QAction*); @@ -126,6 +127,7 @@ protected: bool _dropDown; bool _external; bool _toggle; + bool _isMode; }; // -------------------------------------------------------------------- diff --git a/src/Gui/CommandStd.cpp b/src/Gui/CommandStd.cpp index 2ee06da8cb..a0ae9fdea4 100644 --- a/src/Gui/CommandStd.cpp +++ b/src/Gui/CommandStd.cpp @@ -850,6 +850,7 @@ Gui::Action * StdCmdUserEditMode::createAction(void) { Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow()); pcAction->setDropDownMenu(true); + pcAction->setIsMode(true); applyCommandData(this->className(), pcAction); for (auto const &uem : Gui::Application::Instance->listUserEditModes()) {