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