1 // Copyright (C) 2014-2020 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include <XGUI_MenuMgr.h>
21 #include <XGUI_Workshop.h>
22 #include <XGUI_ActionsMgr.h>
23 #include <XGUI_OperationMgr.h>
24 #include <XGUI_MenuWorkbench.h>
25 #include <XGUI_MenuGroup.h>
27 #include <Events_Loop.h>
28 #include <Config_FeatureMessage.h>
29 #include <Config_Keywords.h>
32 #include <AppElements_Workbench.h>
33 #include <AppElements_Command.h>
34 #include <AppElements_MainMenu.h>
35 #include <AppElements_MainWindow.h>
36 #include <AppElements_MenuGroupPanel.h>
37 #include <AppElements_Button.h>
39 #include <XGUI_SalomeConnector.h>
42 #include <ModuleBase_IModule.h>
43 #include <ModuleBase_Tools.h>
49 XGUI_MenuMgr::XGUI_MenuMgr(XGUI_Workshop* theWorkshop)
50 : myWorkshop(theWorkshop)
52 Events_Loop* aLoop = Events_Loop::loop();
54 aLoop->registerListener(this, Events_Loop::eventByName(Config_FeatureMessage::GUI_EVENT()));
57 void XGUI_MenuMgr::processEvent(const std::shared_ptr<Events_Message>& theMessage)
59 //A message to start feature creation received.
60 if (theMessage->eventID() ==
61 Events_Loop::loop()->eventByName(Config_FeatureMessage::GUI_EVENT())) {
62 std::shared_ptr<Config_FeatureMessage> aFeatureMsg =
63 std::dynamic_pointer_cast<Config_FeatureMessage>(theMessage);
64 if (!aFeatureMsg->isInternal()) {
65 addFeature(aFeatureMsg);
70 void XGUI_MenuMgr::addFeature(const std::shared_ptr<Config_FeatureMessage>& theMessage)
74 qDebug() << "XGUI_WorkshopListener::addFeature: NULL message.";
78 QString aWchName = ModuleBase_Tools::translate("workshop", theMessage->workbenchId());
79 theMessage->setToolBarId(ModuleBase_Tools::translate("workshop",
80 theMessage->workbenchId()).toStdString());
82 std::string aWchNameString = aWchName.toStdString();
83 std::shared_ptr<XGUI_MenuWorkbench> aWorkbench = findWorkbench(aWchNameString);
84 std::shared_ptr<XGUI_MenuGroup> aGroup = aWorkbench->findGroup(theMessage->groupId());
85 aGroup->setFeatureInfo(theMessage);
87 ActionInfo aFeatureInfo;
88 aFeatureInfo.initFrom(theMessage);
90 QStringList aNestedFeatures =
91 QString::fromStdString(theMessage->nestedFeatures()).split(" ", QString::SkipEmptyParts);
92 QList<QAction*> aNestedActList;
93 bool isColumnButton = !aNestedFeatures.isEmpty();
95 QString aNestedActions = QString::fromStdString(theMessage->actionsWhenNested());
96 XGUI_OperationMgr* anOperationMgr = myWorkshop->operationMgr();
97 XGUI_ActionsMgr* anActionsMgr = myWorkshop->actionsMgr();
98 if (aNestedActions.contains(FEATURE_WHEN_NESTED_ACCEPT)) {
99 QAction* anAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll);
100 QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(commitAllOperations()));
101 aNestedActList << anAction;
103 if (aNestedActions.contains(FEATURE_WHEN_NESTED_ABORT)) {
104 QAction* anAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AbortAll);
105 QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(onAbortAllOperation()));
106 aNestedActList << anAction;
110 //Find or create Workbench
111 AppElements_MainMenu* aMenuBar = myWorkshop->mainWindow()->menuObject();
112 AppElements_Workbench* aPage = aMenuBar->findWorkbench(aWchName);
114 aPage = myWorkshop->addWorkbench(aWchName);
116 //Find or create Group
117 QString aGroupName = QString::fromStdString(theMessage->groupId());
118 AppElements_MenuGroupPanel* aGroup = aPage->findGroup(aGroupName);
120 aGroup = aPage->addGroup(aGroupName);
122 // Check if hotkey sequence is already defined:
123 XGUI_ActionsMgr* anActionsMgr = myWorkshop->actionsMgr();
124 QKeySequence aHotKey = anActionsMgr->registerShortcut(aFeatureInfo.shortcut);
125 if(aHotKey != aFeatureInfo.shortcut) {
126 aFeatureInfo.shortcut = aHotKey;
128 AppElements_Command* aCommand = aGroup->addFeature(theMessage);
129 // Enrich created button with accept/abort buttons if necessary
130 AppElements_Button* aButton = aCommand->button();
131 if (aButton->isColumnButton()) {
132 aButton->setAdditionalButtons(aNestedActList);
134 myWorkshop->actionsMgr()->addCommand(aCommand);
135 myWorkshop->module()->actionCreated(aCommand);
139 std::shared_ptr<XGUI_MenuWorkbench> XGUI_MenuMgr::findWorkbench(const std::string& theWorkbenchName)
141 std::list< std::shared_ptr<XGUI_MenuWorkbench> >::const_iterator anIt = myWorkbenches.begin(),
142 aLast = myWorkbenches.end();
143 std::shared_ptr<XGUI_MenuWorkbench> aResultWorkbench;
144 for (; anIt != aLast && !aResultWorkbench; anIt++) {
145 std::shared_ptr<XGUI_MenuWorkbench> aWorkbench = *anIt;
146 if (aWorkbench->getName() == theWorkbenchName)
147 aResultWorkbench = aWorkbench;
149 if (!aResultWorkbench) {
151 std::shared_ptr<XGUI_MenuWorkbench>(new XGUI_MenuWorkbench(theWorkbenchName));
152 myWorkbenches.push_back(aResultWorkbench);
154 return aResultWorkbench;
157 void XGUI_MenuMgr::createFeatureActions()
160 std::list< std::shared_ptr<XGUI_MenuWorkbench> >::const_iterator anIt = myWorkbenches.begin(),
161 aLast = myWorkbenches.end();
162 XGUI_SalomeConnector* aSalomeConnector = myWorkshop->salomeConnector();
163 for (; anIt != aLast; anIt++) {
164 std::shared_ptr<XGUI_MenuWorkbench> aWorkbench = *anIt;
165 std::string aWchName = aWorkbench->getName();
166 const std::list<std::shared_ptr<XGUI_MenuGroup> >& aGroups = aWorkbench->groups();
167 std::list<std::shared_ptr<XGUI_MenuGroup> >::const_iterator aGIt = aGroups.begin(),
168 aGLast = aGroups.end();
169 for (; aGIt != aGLast; aGIt++) {
170 const std::shared_ptr<XGUI_MenuGroup> aGroup = *aGIt;
171 std::string aGName = aGroup->getName();
172 const std::list<std::shared_ptr<Config_FeatureMessage> >& aFeaturesInfo =
173 aGroup->featuresInfo();
174 std::list<std::shared_ptr<Config_FeatureMessage> >::const_iterator aFIt =
175 aFeaturesInfo.begin(), aFLast = aFeaturesInfo.end();
176 size_t aFSize = aFeaturesInfo.size();
177 for(size_t i = 0; aFIt != aFLast; aFIt++, i++) {
178 std::shared_ptr<Config_FeatureMessage> aMessage = *aFIt;
179 bool aUseSeparator = i == aFSize-1;
180 QAction* aAction = buildAction(aMessage, aWchName, aUseSeparator);
182 aSalomeConnector->setFeatureInfo(QString::fromStdString(aMessage->id()), aMessage);
183 myWorkshop->actionsMgr()->addCommand(aAction);
184 myWorkshop->module()->actionCreated(aAction);
191 QAction* XGUI_MenuMgr::buildAction(const std::shared_ptr<Config_FeatureMessage>& theMessage,
192 const std::string& theWchName, const bool aUseSeparator) const
194 QAction* anAction = 0;
197 XGUI_SalomeConnector* aSalomeConnector = myWorkshop->salomeConnector();
199 ActionInfo aFeatureInfo;
200 aFeatureInfo.initFrom(theMessage);
201 QStringList aNestedFeatures =
202 QString::fromStdString(theMessage->nestedFeatures()).split(" ", QString::SkipEmptyParts);
203 QList<QAction*> aNestedActList;
204 if (!aNestedFeatures.isEmpty()) {
205 QString aNestedActions = QString::fromStdString(theMessage->actionsWhenNested());
206 XGUI_OperationMgr* anOperationMgr = myWorkshop->operationMgr();
207 XGUI_ActionsMgr* anActionsMgr = myWorkshop->actionsMgr();
208 if (aNestedActions.contains(FEATURE_WHEN_NESTED_ACCEPT)) {
209 QAction* anAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll);
210 QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(commitAllOperations()));
211 aNestedActList << anAction;
213 if (aNestedActions.contains(FEATURE_WHEN_NESTED_ABORT)) {
214 QAction* anAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AbortAll);
215 QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(onAbortAllOperation()));
216 aNestedActList << anAction;
218 anAction = aSalomeConnector->addFeatureOfNested(theWchName.c_str(), aFeatureInfo,
222 anAction = aSalomeConnector->addFeature(theWchName.c_str(), aFeatureInfo, aUseSeparator);