]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_ContextMenuMgr.cpp
Salome HOME
Issue #807: disable the show/hide actions if the part set document is not active
[modules/shaper.git] / src / XGUI / XGUI_ContextMenuMgr.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 #include "XGUI_ContextMenuMgr.h"
4 #include "XGUI_Workshop.h"
5 #include "XGUI_ObjectsBrowser.h"
6 #include "XGUI_SelectionMgr.h"
7 #include "XGUI_Displayer.h"
8 #include "XGUI_ViewerProxy.h"
9 #include "XGUI_Selection.h"
10 #include "XGUI_SalomeConnector.h"
11
12 #include <AppElements_MainWindow.h>
13
14 //#include "PartSetPlugin_Part.h"
15
16 #include <ModelAPI_Data.h>
17 #include <ModelAPI_AttributeDocRef.h>
18 #include <ModelAPI_Object.h>
19 #include <ModelAPI_Session.h>
20 #include <ModelAPI_ResultGroup.h>
21 #include <ModelAPI_ResultParameter.h>
22 #include <ModelAPI_ResultConstruction.h>
23 #include <ModelAPI_ResultBody.h>
24 #include <ModelAPI_Tools.h>
25
26 #include <ModuleBase_IModule.h>
27 #include <ModuleBase_Tools.h>
28
29 #include <QAction>
30 #include <QContextMenuEvent>
31 #include <QMenu>
32 #include <QMdiArea>
33
34
35 XGUI_ContextMenuMgr::XGUI_ContextMenuMgr(XGUI_Workshop* theParent)
36     : QObject(theParent),
37       myWorkshop(theParent),
38       mySeparator(0)
39 {
40 }
41
42 XGUI_ContextMenuMgr::~XGUI_ContextMenuMgr()
43 {
44 }
45
46 void XGUI_ContextMenuMgr::createActions()
47 {
48   QAction* aAction = new QAction(QIcon(":pictures/delete.png"), tr("Delete"), this);
49   QMainWindow* aDesktop = myWorkshop->mainWindow();
50   if (!aDesktop)
51     aDesktop = myWorkshop->salomeConnector()->desktop();
52   aDesktop->addAction(aAction);
53
54   addAction("DELETE_CMD", aAction);
55   aAction->setShortcut(Qt::Key_Delete);
56   aAction->setShortcutContext(Qt::ApplicationShortcut);
57
58   aAction = new QAction(QIcon(":pictures/rename_edit.png"), tr("Rename"), this);
59   addAction("RENAME_CMD", aAction);
60   connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onRename()));
61
62   aAction = new QAction(QIcon(":pictures/move.png"), tr("Move..."), this);
63   addAction("MOVE_CMD", aAction);
64
65   aAction = new QAction(QIcon(":pictures/color.png"), tr("Color..."), this);
66   addAction("COLOR_CMD", aAction);
67
68   aAction = new QAction(QIcon(":pictures/eye_pencil.png"), tr("Show"), this);
69   addAction("SHOW_CMD", aAction);
70
71   aAction = new QAction(QIcon(":pictures/eye_pencil.png"), tr("Show only"), this);
72   addAction("SHOW_ONLY_CMD", aAction);
73
74   aAction = new QAction(QIcon(":pictures/eye_pencil_closed.png"), tr("Hide"), this);
75   addAction("HIDE_CMD", aAction);
76
77   aAction = new QAction(QIcon(":pictures/eye_pencil_closed.png"), tr("Hide all"), this);
78   addAction("HIDEALL_CMD", aAction);
79
80   aAction = new QAction(QIcon(":pictures/shading.png"), tr("Shading"), this);
81   addAction("SHADING_CMD", aAction);
82
83   aAction = new QAction(QIcon(":pictures/wireframe.png"), tr("Wireframe"), this);
84   addAction("WIREFRAME_CMD", aAction);
85
86   mySeparator = new QAction(this);
87   mySeparator->setSeparator(true);
88
89
90   buildObjBrowserMenu();
91   buildViewerMenu();
92 }
93
94 void XGUI_ContextMenuMgr::addAction(const QString& theId, QAction* theAction)
95 {
96   if (myActions.contains(theId))
97     qCritical("A command with Id = '%s' already defined!", qPrintable(theId));
98   theAction->setData(theId);
99   connect(theAction, SIGNAL(triggered(bool)), this, SLOT(onAction(bool)));
100   myActions[theId] = theAction;
101 }
102
103 QAction* XGUI_ContextMenuMgr::action(const QString& theId) const
104 {
105   if (myActions.contains(theId))
106     return myActions[theId];
107   return 0;
108 }
109
110 QAction* XGUI_ContextMenuMgr::actionByName(const QString& theName) const
111 {
112   foreach(QAction* eachAction, myActions) {
113     if (eachAction->text() == theName) {
114       return eachAction;
115     }
116   }
117   return NULL;
118 }
119
120 QStringList XGUI_ContextMenuMgr::actionIds() const
121 {
122   return myActions.keys();
123 }
124
125 void XGUI_ContextMenuMgr::onAction(bool isChecked)
126 {
127   QAction* aAction = static_cast<QAction*>(sender());
128   emit actionTriggered(aAction->data().toString(), isChecked);
129 }
130
131 void XGUI_ContextMenuMgr::updateCommandsStatus()
132 {
133 }
134
135 void XGUI_ContextMenuMgr::onContextMenuRequest(QContextMenuEvent* theEvent)
136 {
137   QMenu* aMenu = new QMenu();
138   if (sender() == myWorkshop->objectBrowser()) {
139     updateObjectBrowserMenu();
140     addObjBrowserMenu(aMenu);
141   } else if (sender() == myWorkshop->viewer()) {
142     updateViewerMenu();
143     addViewerMenu(aMenu);
144   }
145
146   if (aMenu && (aMenu->actions().size() > 0)) {
147     // it is possible that some objects should do something before and after the popup menu exec
148     // e.g. a sketch manager changes an internal flag on this signals in order to do not hide
149     // a created entity
150     emit beforeContextMenu();
151     aMenu->exec(theEvent->globalPos());
152     emit afterContextMenu();
153     delete aMenu;
154   }
155 }
156
157 void XGUI_ContextMenuMgr::updateObjectBrowserMenu() 
158 {
159   foreach(QAction* aAction, myActions)
160     aAction->setEnabled(false);
161
162   XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
163   QObjectPtrList aObjects = aSelMgr->selection()->selectedObjects();
164   int aSelected = aObjects.size();
165   if (aSelected > 0) {
166     SessionPtr aMgr = ModelAPI_Session::get();
167     XGUI_Displayer* aDisplayer = myWorkshop->displayer();
168     bool hasResult = false;
169     bool hasFeature = false;
170     bool hasParameter = false;
171     bool hasSubFeature = false;
172     ModuleBase_Tools::checkObjects(aObjects, hasResult, hasFeature, hasParameter, hasSubFeature);
173
174     //Process Feature
175     if (aSelected == 1) {
176       ObjectPtr aObject = aObjects.first();
177       if (aObject) {
178         if (hasResult && myWorkshop->canBeShaded(aObject)) {
179           action("WIREFRAME_CMD")->setEnabled(true);
180           action("SHADING_CMD")->setEnabled(true);
181         }
182         if (!hasFeature) {
183           bool aHasSubResults = ModelAPI_Tools::hasSubResults(
184                                             std::dynamic_pointer_cast<ModelAPI_Result>(aObject));
185           if (aHasSubResults) {
186             action("HIDE_CMD")->setEnabled(true);
187             action("SHOW_CMD")->setEnabled(true);
188           }
189           else {
190             if (aObject->isDisplayed()) {
191               action("HIDE_CMD")->setEnabled(true);
192             } else if (hasResult && (!hasParameter)) {
193               action("SHOW_CMD")->setEnabled(true);
194             }
195           }
196           if (!(hasParameter || hasFeature))
197             action("SHOW_ONLY_CMD")->setEnabled(true);
198         }
199         else if (hasFeature && myWorkshop->canMoveFeature())
200           action("MOVE_CMD")->setEnabled(true);
201
202         if( aMgr->activeDocument() == aObject->document() )
203         {
204           action("RENAME_CMD")->setEnabled(true);
205           action("DELETE_CMD")->setEnabled(true);
206         }
207       }
208     } else {
209       // parameter is commented because the actions are not in the list of result parameter actions
210       if (hasResult /*&& (!hasParameter)*/) {
211         action("SHOW_CMD")->setEnabled(true);
212         action("HIDE_CMD")->setEnabled(true);
213         action("SHOW_ONLY_CMD")->setEnabled(true);
214         action("SHADING_CMD")->setEnabled(true);
215         action("WIREFRAME_CMD")->setEnabled(true);
216       }
217     }
218     bool allActive = true;
219     foreach( ObjectPtr aObject, aObjects )
220       if( aMgr->activeDocument() != aObject->document() )
221       {
222         allActive = false;
223         break;
224       }
225     if (!hasSubFeature && allActive ) {
226       if (hasFeature || hasParameter)
227         action("DELETE_CMD")->setEnabled(true);
228     }
229   }
230
231   bool isPartSetDocActive = 
232     ModelAPI_Session::get()->activeDocument()==ModelAPI_Session::get()->moduleDocument();
233   if( !isPartSetDocActive )
234   {
235     action("SHOW_CMD")->setEnabled(false);
236     action("HIDE_CMD")->setEnabled(false);
237     action("SHOW_ONLY_CMD")->setEnabled(false);
238   }
239
240   if (myWorkshop->canChangeColor())
241     action("COLOR_CMD")->setEnabled(true);
242
243   ModuleBase_IModule* aModule = myWorkshop->module();
244   if (aModule)
245     aModule->updateObjectBrowserMenu(myActions);
246 }
247
248 void XGUI_ContextMenuMgr::updateViewerMenu()
249 {
250   foreach(QAction* aAction, myActions)
251     aAction->setEnabled(false);
252
253   XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
254   QList<ModuleBase_ViewerPrs> aPrsList = aSelMgr->selection()->getSelected(ModuleBase_ISelection::Viewer);
255   if (aPrsList.size() > 0) {
256     bool isVisible = false;
257     bool isShading = false;
258     bool canBeShaded = false;
259     ObjectPtr aObject;
260     foreach(ModuleBase_ViewerPrs aPrs, aPrsList) {
261       aObject = aPrs.object();
262       ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObject);
263       if (aRes && aRes->isDisplayed()) {
264         isVisible = true;
265         canBeShaded = myWorkshop->displayer()->canBeShaded(aObject);
266         isShading = (myWorkshop->displayer()->displayMode(aObject) == XGUI_Displayer::Shading);      
267         break;
268       }
269     }
270     if (isVisible) {
271       if (canBeShaded) {
272         action("WIREFRAME_CMD")->setEnabled(true);
273         action("SHADING_CMD")->setEnabled(true);
274       }
275       action("SHOW_ONLY_CMD")->setEnabled(true);
276       action("HIDE_CMD")->setEnabled(true);
277     } else
278       action("SHOW_CMD")->setEnabled(true);
279   }
280   if (myWorkshop->displayer()->objectsCount() > 0)
281     action("HIDEALL_CMD")->setEnabled(true);
282   if (myWorkshop->canChangeColor())
283     action("COLOR_CMD")->setEnabled(true);
284
285   action("DELETE_CMD")->setEnabled(true);
286
287   ModuleBase_IModule* aModule = myWorkshop->module();
288   if (aModule)
289     aModule->updateViewerMenu(myActions);
290 }
291
292 void XGUI_ContextMenuMgr::connectObjectBrowser()
293 {
294   connect(myWorkshop->objectBrowser(), SIGNAL(contextMenuRequested(QContextMenuEvent*)), this,
295           SLOT(onContextMenuRequest(QContextMenuEvent*)));
296 }
297
298 void XGUI_ContextMenuMgr::connectViewer()
299 {
300   connect(myWorkshop->viewer(), SIGNAL(contextMenuRequested(QContextMenuEvent*)), this,
301           SLOT(onContextMenuRequest(QContextMenuEvent*)));
302 }
303
304
305 void XGUI_ContextMenuMgr::buildObjBrowserMenu()
306 {
307   QAction* aSeparator = new QAction(this);
308   aSeparator->setSeparator(true);
309
310   QActionsList aList;
311   
312   // Result construction menu
313   aList.append(action("SHOW_CMD"));
314   aList.append(action("HIDE_CMD"));
315   aList.append(action("SHOW_ONLY_CMD"));
316   aList.append(action("COLOR_CMD"));
317   aList.append(mySeparator);
318   aList.append(action("RENAME_CMD"));
319   myObjBrowserMenus[ModelAPI_ResultConstruction::group()] = aList;
320   //-------------------------------------
321   // Result body menu
322   aList.clear();
323   aList.append(action("WIREFRAME_CMD"));
324   aList.append(action("SHADING_CMD"));
325   aList.append(action("COLOR_CMD"));
326   aList.append(mySeparator);
327   aList.append(action("SHOW_CMD"));
328   aList.append(action("HIDE_CMD"));
329   aList.append(action("SHOW_ONLY_CMD"));
330   aList.append(mySeparator);
331   aList.append(action("RENAME_CMD"));
332   myObjBrowserMenus[ModelAPI_ResultBody::group()] = aList;
333   // Group menu
334   myObjBrowserMenus[ModelAPI_ResultGroup::group()] = aList;
335   // Result part menu
336   myObjBrowserMenus[ModelAPI_ResultPart::group()] = aList;
337   //-------------------------------------
338   // Feature menu
339   aList.clear();
340   aList.append(action("DELETE_CMD"));
341   aList.append(action("MOVE_CMD"));
342   aList.append(mySeparator);
343   aList.append(action("RENAME_CMD"));
344   myObjBrowserMenus[ModelAPI_Feature::group()] = aList;
345
346   aList.clear();
347   aList.append(action("DELETE_CMD"));
348   aList.append(mySeparator);
349   aList.append(action("RENAME_CMD"));
350   myObjBrowserMenus[ModelAPI_ResultParameter::group()] = aList;
351   //-------------------------------------
352 }
353
354 void XGUI_ContextMenuMgr::buildViewerMenu()
355 {
356   QActionsList aList;
357   // Result construction menu
358   aList.append(action("HIDE_CMD"));
359   aList.append(action("SHOW_ONLY_CMD"));
360   aList.append(action("HIDEALL_CMD"));
361   aList.append(action("COLOR_CMD"));
362   myViewerMenu[ModelAPI_ResultConstruction::group()] = aList;
363   // Result part menu
364   myViewerMenu[ModelAPI_ResultPart::group()] = aList;
365   //-------------------------------------
366   // Result body menu
367   aList.clear();
368   aList.append(action("WIREFRAME_CMD"));
369   aList.append(action("SHADING_CMD"));
370   aList.append(action("COLOR_CMD"));
371   aList.append(mySeparator);
372   aList.append(action("HIDE_CMD"));
373   aList.append(action("SHOW_ONLY_CMD"));
374   aList.append(action("HIDEALL_CMD"));
375   myViewerMenu[ModelAPI_ResultBody::group()] = aList;
376   // Group menu
377   myViewerMenu[ModelAPI_ResultGroup::group()] = aList;
378   //-------------------------------------
379
380 }
381
382
383 void XGUI_ContextMenuMgr::addObjBrowserMenu(QMenu* theMenu) const
384 {
385   XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
386   QObjectPtrList aObjects = aSelMgr->selection()->selectedObjects();
387   int aSelected = aObjects.size();
388   QActionsList aActions;
389   if (aSelected == 1) {
390     ObjectPtr aObject = aObjects.first();
391     std::string aName = aObject->groupName();
392     if (myObjBrowserMenus.contains(aName))
393       aActions = myObjBrowserMenus[aName];
394   } else if (aSelected > 1) {
395       aActions.append(action("SHADING_CMD"));
396       aActions.append(action("WIREFRAME_CMD"));
397       aActions.append(mySeparator);
398       aActions.append(action("SHOW_CMD"));
399       aActions.append(action("HIDE_CMD"));
400       aActions.append(action("SHOW_ONLY_CMD"));
401       aActions.append(mySeparator);
402       aActions.append(action("DELETE_CMD"));
403       //aActions.append(action("MOVE_CMD"));
404   }
405   theMenu->addActions(aActions);
406
407   ModuleBase_IModule* aModule = myWorkshop->module();
408   if (aModule) {
409     theMenu->addSeparator();
410     aModule->addObjectBrowserMenu(theMenu);
411   }
412   theMenu->addSeparator();
413   theMenu->addActions(myWorkshop->objectBrowser()->actions());
414 }
415
416 void XGUI_ContextMenuMgr::addViewerMenu(QMenu* theMenu) const
417 {
418   ModuleBase_IModule* aModule = myWorkshop->module();
419   if (aModule) {
420     if (aModule->addViewerMenu(theMenu, myActions))
421       theMenu->addSeparator();
422   }
423   XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
424   QList<ModuleBase_ViewerPrs> aPrsList = aSelMgr->selection()->getSelected(ModuleBase_ISelection::Viewer);
425   int aSelected = aPrsList.size();
426   QActionsList aActions;
427   if (aSelected == 1) {
428     ObjectPtr aObject = aPrsList.first().object();
429     std::string aName = aObject->groupName();
430     if (myViewerMenu.contains(aName))
431       aActions = myViewerMenu[aName];
432   } else if (aSelected > 1) {
433     aActions.append(action("HIDE_CMD"));
434   }
435   theMenu->addActions(aActions);
436
437   if (!myWorkshop->isSalomeMode()) {
438     theMenu->addSeparator();
439     QMdiArea* aMDI = myWorkshop->mainWindow()->mdiArea();
440     if (aMDI->actions().size() > 0) {
441       QMenu* aSubMenu = theMenu->addMenu(tr("Windows"));
442       aSubMenu->addActions(aMDI->actions());
443     }
444   }
445 }
446
447 QStringList XGUI_ContextMenuMgr::actionObjectGroups(const QString& theName)
448 {
449   QStringList aGroups;
450
451   QMap<std::string, QActionsList>::const_iterator anIt = myObjBrowserMenus.begin(),
452                                                   aLast = myObjBrowserMenus.end();
453   for (; anIt != aLast; anIt++) {
454     QString aGroupName(anIt.key().c_str());
455     if (aGroups.contains(aGroupName))
456       continue;
457     QActionsList anActions = anIt.value();
458     QActionsList::const_iterator anAIt = anActions.begin(), anALast = anActions.end();
459     bool aFound = false;
460     for (; anAIt != anALast && !aFound; anAIt++)
461       aFound = (*anAIt)->data().toString() == theName;
462     if (aFound)
463       aGroups.append(aGroupName);
464   }
465   return aGroups;
466 }
467
468 void XGUI_ContextMenuMgr::onRename()
469 {
470   myWorkshop->objectBrowser()->onEditItem();
471 }