Salome HOME
Add copyright header according to request of CEA from 06.06.2017
[modules/shaper.git] / src / XGUI / XGUI_MenuMgr.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
18 //
19
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>
26
27 #include <Events_Loop.h>
28 #include <Config_FeatureMessage.h>
29 #include <Config_Keywords.h>
30
31 #ifndef HAVE_SALOME
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>
38 #else
39 #include <XGUI_SalomeConnector.h>
40 #endif
41
42 #include <ModuleBase_IModule.h>
43
44 #include <QObject>
45 #include <QAction>
46 #include <QDebug>
47
48 XGUI_MenuMgr::XGUI_MenuMgr(XGUI_Workshop* theWorkshop)
49 : myWorkshop(theWorkshop)
50 {
51   Events_Loop* aLoop = Events_Loop::loop();
52
53   aLoop->registerListener(this, Events_Loop::eventByName(Config_FeatureMessage::GUI_EVENT()));
54 }
55
56 void XGUI_MenuMgr::processEvent(const std::shared_ptr<Events_Message>& theMessage)
57 {
58   //A message to start feature creation received.
59   if (theMessage->eventID() ==
60       Events_Loop::loop()->eventByName(Config_FeatureMessage::GUI_EVENT())) {
61     std::shared_ptr<Config_FeatureMessage> aFeatureMsg =
62        std::dynamic_pointer_cast<Config_FeatureMessage>(theMessage);
63     if (!aFeatureMsg->isInternal()) {
64       addFeature(aFeatureMsg);
65     }
66   }
67 }
68
69 void XGUI_MenuMgr::addFeature(const std::shared_ptr<Config_FeatureMessage>& theMessage)
70 {
71   if (!theMessage) {
72 #ifdef _DEBUG
73     qDebug() << "XGUI_WorkshopListener::addFeature: NULL message.";
74 #endif
75     return;
76   }
77 #ifdef HAVE_SALOME
78   std::shared_ptr<XGUI_MenuWorkbench> aWorkbench = findWorkbench(theMessage->workbenchId());
79   std::shared_ptr<XGUI_MenuGroup> aGroup = aWorkbench->findGroup(theMessage->groupId());
80   aGroup->setFeatureInfo(theMessage);
81 #else
82   ActionInfo aFeatureInfo;
83   aFeatureInfo.initFrom(theMessage);
84
85   QString aWchName = QString::fromStdString(theMessage->workbenchId());
86   QStringList aNestedFeatures =
87       QString::fromStdString(theMessage->nestedFeatures()).split(" ", QString::SkipEmptyParts);
88   QList<QAction*> aNestedActList;
89   bool isColumnButton = !aNestedFeatures.isEmpty();
90   if (isColumnButton) {
91     QString aNestedActions = QString::fromStdString(theMessage->actionsWhenNested());
92     XGUI_OperationMgr* anOperationMgr = myWorkshop->operationMgr();
93     XGUI_ActionsMgr* anActionsMgr = myWorkshop->actionsMgr();
94     if (aNestedActions.contains(FEATURE_WHEN_NESTED_ACCEPT)) {
95       QAction* anAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll);
96       QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(commitAllOperations()));
97       aNestedActList << anAction;
98     }
99     if (aNestedActions.contains(FEATURE_WHEN_NESTED_ABORT)) {
100       QAction* anAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AbortAll);
101       QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(abortAllOperations()));
102       aNestedActList << anAction;
103     }
104   }
105
106   //Find or create Workbench
107   AppElements_MainMenu* aMenuBar = myWorkshop->mainWindow()->menuObject();
108   AppElements_Workbench* aPage = aMenuBar->findWorkbench(aWchName);
109   if (!aPage) {
110     aPage = myWorkshop->addWorkbench(aWchName);
111   }
112   //Find or create Group
113   QString aGroupName = QString::fromStdString(theMessage->groupId());
114   AppElements_MenuGroupPanel* aGroup = aPage->findGroup(aGroupName);
115   if (!aGroup) {
116     aGroup = aPage->addGroup(aGroupName);
117   }
118   // Check if hotkey sequence is already defined:
119   XGUI_ActionsMgr* anActionsMgr = myWorkshop->actionsMgr();
120   QKeySequence aHotKey = anActionsMgr->registerShortcut(aFeatureInfo.shortcut);
121   if(aHotKey != aFeatureInfo.shortcut) {
122     aFeatureInfo.shortcut = aHotKey;
123   }
124   AppElements_Command* aCommand = aGroup->addFeature(theMessage);
125   // Enrich created button with accept/abort buttons if necessary
126   AppElements_Button* aButton = aCommand->button();
127   if (aButton->isColumnButton()) {
128     aButton->setAdditionalButtons(aNestedActList);
129   }
130   myWorkshop->actionsMgr()->addCommand(aCommand);
131   myWorkshop->module()->actionCreated(aCommand);
132 #endif
133 }
134
135 std::shared_ptr<XGUI_MenuWorkbench> XGUI_MenuMgr::findWorkbench(const std::string& theWorkbenchName)
136 {
137   std::list< std::shared_ptr<XGUI_MenuWorkbench> >::const_iterator anIt = myWorkbenches.begin(),
138                                                                    aLast = myWorkbenches.end();
139   std::shared_ptr<XGUI_MenuWorkbench> aResultWorkbench;
140   for (; anIt != aLast && !aResultWorkbench; anIt++) {
141     std::shared_ptr<XGUI_MenuWorkbench> aWorkbench = *anIt;
142     if (aWorkbench->getName() == theWorkbenchName)
143       aResultWorkbench = aWorkbench;
144   }
145   if (!aResultWorkbench) {
146     aResultWorkbench =
147       std::shared_ptr<XGUI_MenuWorkbench>(new XGUI_MenuWorkbench(theWorkbenchName));
148     myWorkbenches.push_back(aResultWorkbench);
149   }
150   return aResultWorkbench;
151 }
152
153 void XGUI_MenuMgr::createFeatureActions()
154 {
155 #ifdef HAVE_SALOME
156   std::list< std::shared_ptr<XGUI_MenuWorkbench> >::const_iterator anIt = myWorkbenches.begin(),
157                                                                    aLast = myWorkbenches.end();
158   XGUI_SalomeConnector* aSalomeConnector = myWorkshop->salomeConnector();
159   for (; anIt != aLast; anIt++) {
160     std::shared_ptr<XGUI_MenuWorkbench> aWorkbench = *anIt;
161     std::string aWchName = aWorkbench->getName();
162     const std::list<std::shared_ptr<XGUI_MenuGroup> >& aGroups = aWorkbench->groups();
163     std::list<std::shared_ptr<XGUI_MenuGroup> >::const_iterator aGIt = aGroups.begin(),
164                                                                 aGLast = aGroups.end();
165     for (; aGIt != aGLast; aGIt++) {
166       const std::shared_ptr<XGUI_MenuGroup> aGroup = *aGIt;
167       std::string aGName = aGroup->getName();
168       const std::list<std::shared_ptr<Config_FeatureMessage> >& aFeaturesInfo =
169         aGroup->featuresInfo();
170       std::list<std::shared_ptr<Config_FeatureMessage> >::const_iterator aFIt =
171         aFeaturesInfo.begin(), aFLast = aFeaturesInfo.end();
172       int aFSize = aFeaturesInfo.size();
173       for(int i = 0; aFIt != aFLast; aFIt++, i++) {
174         std::shared_ptr<Config_FeatureMessage> aMessage = *aFIt;
175         bool aUseSeparator = i == aFSize-1;
176         QAction* aAction = buildAction(aMessage, aWchName, aUseSeparator);
177
178         aSalomeConnector->setFeatureInfo(QString::fromStdString(aMessage->id()), aMessage);
179         myWorkshop->actionsMgr()->addCommand(aAction);
180         myWorkshop->module()->actionCreated(aAction);
181       }
182     }
183   }
184 #endif
185 }
186
187 QAction* XGUI_MenuMgr::buildAction(const std::shared_ptr<Config_FeatureMessage>& theMessage,
188                                    const std::string& theWchName, const bool aUseSeparator) const
189 {
190   QAction* anAction = 0;
191
192 #ifdef HAVE_SALOME
193   XGUI_SalomeConnector* aSalomeConnector = myWorkshop->salomeConnector();
194
195   ActionInfo aFeatureInfo;
196   aFeatureInfo.initFrom(theMessage);
197   QStringList aNestedFeatures =
198       QString::fromStdString(theMessage->nestedFeatures()).split(" ", QString::SkipEmptyParts);
199   QList<QAction*> aNestedActList;
200   if (!aNestedFeatures.isEmpty()) {
201     QString aNestedActions = QString::fromStdString(theMessage->actionsWhenNested());
202     XGUI_OperationMgr* anOperationMgr = myWorkshop->operationMgr();
203     XGUI_ActionsMgr* anActionsMgr = myWorkshop->actionsMgr();
204     if (aNestedActions.contains(FEATURE_WHEN_NESTED_ACCEPT)) {
205       QAction* anAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll);
206       QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(commitAllOperations()));
207       aNestedActList << anAction;
208     }
209     if (aNestedActions.contains(FEATURE_WHEN_NESTED_ABORT)) {
210       QAction* anAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AbortAll);
211       QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(abortAllOperations()));
212       aNestedActList << anAction;
213     }
214     anAction = aSalomeConnector->addFeatureOfNested(theWchName.c_str(), aFeatureInfo,
215                                                     aNestedActList);
216   }
217   else {
218     anAction = aSalomeConnector->addFeature(theWchName.c_str(), aFeatureInfo, aUseSeparator);
219   }
220 #endif
221   return anAction;
222 }