Salome HOME
Merge remote-tracking branch 'remotes/origin/master' into BR_coding_rules
[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 #include "XGUI_OperationMgr.h"
13 #include "XGUI_Tools.h"
14 #include "XGUI_ActionsMgr.h"
15
16 #ifndef HAVE_SALOME
17 #include <AppElements_MainWindow.h>
18 #endif
19
20 //#include "PartSetPlugin_Part.h"
21
22 #include <ModelAPI_Data.h>
23 #include <ModelAPI_AttributeDocRef.h>
24 #include <ModelAPI_Object.h>
25 #include <ModelAPI_Session.h>
26 #include <ModelAPI_ResultGroup.h>
27 #include <ModelAPI_ResultParameter.h>
28 #include <ModelAPI_ResultConstruction.h>
29 #include <ModelAPI_ResultBody.h>
30 #include <ModelAPI_Tools.h>
31 #include <ModelAPI_ResultField.h>
32
33 #include <Config_DataModelReader.h>
34
35 #include <ModuleBase_IModule.h>
36 #include <ModuleBase_Tools.h>
37 #include <ModuleBase_OperationAction.h>
38 #include <ModuleBase_ViewerPrs.h>
39
40 #include <QAction>
41 #include <QActionGroup>
42 #include <QContextMenuEvent>
43 #include <QMenu>
44 #include <QMdiArea>
45 #include <QMainWindow>
46 #include <QModelIndex>
47
48
49 XGUI_ContextMenuMgr::XGUI_ContextMenuMgr(XGUI_Workshop* theParent)
50     : QObject(theParent),
51       myWorkshop(theParent),
52       mySeparator(0)
53 {
54 }
55
56 XGUI_ContextMenuMgr::~XGUI_ContextMenuMgr()
57 {
58 }
59
60 void XGUI_ContextMenuMgr::createActions()
61 {
62 #ifdef HAVE_SALOME
63   QMainWindow* aDesktop = myWorkshop->salomeConnector()->desktop();
64 #else
65   QMainWindow* aDesktop = myWorkshop->mainWindow();
66 #endif
67
68   QAction* aAction = ModuleBase_Tools::createAction(QIcon(":pictures/delete.png"), tr("Delete"),
69                                                     aDesktop);
70   aDesktop->addAction(aAction);
71
72   addAction("DELETE_CMD", aAction);
73   aAction->setShortcutContext(Qt::ApplicationShortcut);
74
75   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/rename_edit.png"), tr("Rename"),
76                                            aDesktop, this, SLOT(onRename()));
77   addAction("RENAME_CMD", aAction);
78
79   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/move.png"),
80                                            XGUI_Workshop::MOVE_TO_END_COMMAND, this);
81   addAction("MOVE_CMD", aAction);
82
83   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/clean_history.png"),
84                                            tr("Clean history"), aDesktop);
85   addAction("CLEAN_HISTORY_CMD", aAction);
86
87   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/color.png"), tr("Color..."), aDesktop);
88   addAction("COLOR_CMD", aAction);
89
90   aAction = ModuleBase_Tools::createAction(QIcon(""), tr("Deflection..."), aDesktop);
91   addAction("DEFLECTION_CMD", aAction);
92
93   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/eye_pencil.png"), tr("Show"), aDesktop);
94   addAction("SHOW_CMD", aAction);
95
96   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/eye_pencil.png"), tr("Show only"),
97                                            aDesktop);
98   addAction("SHOW_ONLY_CMD", aAction);
99
100   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/eye_pencil_closed.png"), tr("Hide"),
101                                            aDesktop);
102   addAction("HIDE_CMD", aAction);
103
104   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/eye_pencil_closed.png"), tr("Hide all"),
105                                            aDesktop);
106   addAction("HIDEALL_CMD", aAction);
107
108   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/shading.png"), tr("Shading"), aDesktop);
109   addAction("SHADING_CMD", aAction);
110
111   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/wireframe.png"), tr("Wireframe"),
112                                            aDesktop);
113   addAction("WIREFRAME_CMD", aAction);
114
115   mySeparator = ModuleBase_Tools::createAction(QIcon(), "", aDesktop);
116   mySeparator->setSeparator(true);
117
118   //mySelectActions = new QActionGroup(this);
119   //mySelectActions->setExclusive(true);
120
121   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/vertex.png"), tr("Vertices"), aDesktop,
122                                            this, SLOT(onShapeSelection(bool)));
123   aAction->setCheckable(true);
124   addAction("SELECT_VERTEX_CMD", aAction);
125   //mySelectActions->addAction(aAction);
126
127   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/edge.png"), tr("Edges"), aDesktop,
128                                            this, SLOT(onShapeSelection(bool)));
129   aAction->setCheckable(true);
130   addAction("SELECT_EDGE_CMD", aAction);
131   //mySelectActions->addAction(aAction);
132
133   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/face.png"), tr("Faces"), aDesktop,
134                                            this, SLOT(onShapeSelection(bool)));
135   aAction->setCheckable(true);
136   addAction("SELECT_FACE_CMD", aAction);
137   //mySelectActions->addAction(aAction);
138
139   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/result.png"), tr("Results"), aDesktop,
140                                            this, SLOT(onResultSelection(bool)));
141   aAction->setCheckable(true);
142   addAction("SELECT_RESULT_CMD", aAction);
143   //mySelectActions->addAction(aAction);
144
145   aAction->setChecked(true);
146
147   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/find_result.png"),
148                                            tr("Select results"), aDesktop);
149   addAction("SHOW_RESULTS_CMD", aAction);
150
151   aAction = ModuleBase_Tools::createAction(QIcon(":pictures/find_result.png"),
152                                            tr("Select parent feature"), aDesktop);
153   addAction("SHOW_FEATURE_CMD", aAction);
154
155   buildObjBrowserMenu();
156   buildViewerMenu();
157 }
158
159 void XGUI_ContextMenuMgr::addAction(const QString& theId, QAction* theAction)
160 {
161   if (myActions.contains(theId))
162     qCritical("A command with Id = '%s' already defined!", qPrintable(theId));
163   theAction->setData(theId);
164   connect(theAction, SIGNAL(triggered(bool)), this, SLOT(onAction(bool)));
165   myActions[theId] = theAction;
166 }
167
168 QAction* XGUI_ContextMenuMgr::action(const QString& theId) const
169 {
170   if (myActions.contains(theId))
171     return myActions[theId];
172   return 0;
173 }
174
175 QAction* XGUI_ContextMenuMgr::actionByName(const QString& theName) const
176 {
177   foreach(QAction* eachAction, myActions) {
178     if (eachAction->text() == theName) {
179       return eachAction;
180     }
181   }
182   return NULL;
183 }
184
185 QStringList XGUI_ContextMenuMgr::actionIds() const
186 {
187   return myActions.keys();
188 }
189
190 void XGUI_ContextMenuMgr::onAction(bool isChecked)
191 {
192   QAction* aAction = static_cast<QAction*>(sender());
193   emit actionTriggered(aAction->data().toString(), isChecked);
194 }
195
196 void XGUI_ContextMenuMgr::updateCommandsStatus()
197 {
198 }
199
200 void XGUI_ContextMenuMgr::onContextMenuRequest(QContextMenuEvent* theEvent)
201 {
202   QMenu* aMenu = new QMenu();
203   if (sender() == myWorkshop->objectBrowser()) {
204     updateObjectBrowserMenu();
205     addObjBrowserMenu(aMenu);
206   } else if (sender() == myWorkshop->viewer()) {
207     updateViewerMenu();
208     addViewerMenu(aMenu);
209   }
210
211   if (aMenu && (aMenu->actions().size() > 0)) {
212     // it is possible that some objects should do something before and after the popup menu exec
213     // e.g. a sketch manager changes an internal flag on this signals in order to do not hide
214     // a created entity
215     emit beforeContextMenu();
216     aMenu->exec(theEvent->globalPos());
217     emit afterContextMenu();
218     delete aMenu;
219   }
220 }
221
222 void XGUI_ContextMenuMgr::updateObjectBrowserMenu()
223 {
224   foreach(QAction* aAction, myActions)
225     aAction->setEnabled(false);
226
227   XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
228   QObjectPtrList aObjects = aSelMgr->selection()->selectedObjects();
229   int aSelected = aObjects.size();
230   if (aSelected > 0) {
231     SessionPtr aMgr = ModelAPI_Session::get();
232     XGUI_Displayer* aDisplayer = myWorkshop->displayer();
233     bool hasResult = false;
234     bool hasFeature = false;
235     bool hasParameter = false;
236     bool hasCompositeOwner = false;
237     ModuleBase_Tools::checkObjects(aObjects, hasResult, hasFeature, hasParameter,
238                                    hasCompositeOwner);
239     //Process Feature
240     if (aSelected == 1) {
241       ObjectPtr aObject = aObjects.first();
242       if (aObject) {
243         if (hasResult && myWorkshop->canBeShaded(aObject)) {
244           XGUI_Displayer::DisplayMode aMode = aDisplayer->displayMode(aObject);
245           if (aMode != XGUI_Displayer::NoMode) {
246             action("WIREFRAME_CMD")->setEnabled(aMode == XGUI_Displayer::Shading);
247             action("SHADING_CMD")->setEnabled(aMode == XGUI_Displayer::Wireframe);
248           } else {
249             action("WIREFRAME_CMD")->setEnabled(true);
250             action("SHADING_CMD")->setEnabled(true);
251           }
252         }
253         if (!hasFeature) {
254           bool aHasSubResults = ModelAPI_Tools::hasSubResults(
255                                             std::dynamic_pointer_cast<ModelAPI_Result>(aObject));
256           if (aHasSubResults) {
257             action("HIDE_CMD")->setEnabled(true);
258             action("SHOW_CMD")->setEnabled(true);
259           }
260           else {
261             if (aObject->isDisplayed()) {
262               action("HIDE_CMD")->setEnabled(true);
263             } else if (hasResult && (!hasParameter)) {
264               action("SHOW_CMD")->setEnabled(true);
265             }
266           }
267           if (!(hasParameter || hasFeature))
268             action("SHOW_ONLY_CMD")->setEnabled(true);
269         }
270         else if (hasFeature && myWorkshop->canMoveFeature())
271           action("MOVE_CMD")->setEnabled(true);
272
273         if( aMgr->activeDocument() == aObject->document() )
274         {
275           action("RENAME_CMD")->setEnabled(true);
276           action("DELETE_CMD")->setEnabled(!hasCompositeOwner);
277           action("CLEAN_HISTORY_CMD")->setEnabled(!hasCompositeOwner &&
278                                                   (hasFeature || hasParameter));
279         }
280       }
281     } else {
282       // parameter is commented because the actions are not in the list of result parameter actions
283       if (hasResult /*&& (!hasParameter)*/) {
284         action("SHOW_CMD")->setEnabled(true);
285         action("HIDE_CMD")->setEnabled(true);
286         action("SHOW_ONLY_CMD")->setEnabled(true);
287         action("SHADING_CMD")->setEnabled(true);
288         action("WIREFRAME_CMD")->setEnabled(true);
289       }
290     }
291     bool allActive = true;
292     foreach( ObjectPtr aObject, aObjects )
293       if( aMgr->activeDocument() != aObject->document() )  {
294         allActive = false;
295         break;
296       }
297     if (!hasCompositeOwner && allActive ) {
298       if (hasFeature || hasParameter)
299         action("DELETE_CMD")->setEnabled(true);
300     }
301     if (!hasCompositeOwner && allActive && (hasFeature|| hasParameter))
302       action("CLEAN_HISTORY_CMD")->setEnabled(true);
303
304     action("SHOW_RESULTS_CMD")->setEnabled(hasFeature);
305     action("SHOW_FEATURE_CMD")->setEnabled(hasResult);
306   }
307
308   // Show/Hide command has to be disabled for objects from non active document
309   bool aDeactivate = false;
310   foreach (ObjectPtr aObj, aObjects) {
311     if (!aObj->document()->isActive()) {
312       if ((aObj->document() != ModelAPI_Session::get()->moduleDocument()) ||
313            aObj->groupName() == ModelAPI_ResultPart::group()) {
314         aDeactivate = true;
315         break;
316       }
317     }
318   }
319   if (aDeactivate) {
320     // If at leas a one objec can not be edited then Show/Hide has to be disabled
321     action("SHOW_CMD")->setEnabled(false);
322     action("HIDE_CMD")->setEnabled(false);
323     action("SHOW_ONLY_CMD")->setEnabled(false);
324   }
325
326   if (myWorkshop->canChangeColor())
327     action("COLOR_CMD")->setEnabled(true);
328
329   if (myWorkshop->canChangeDeflection())
330     action("DEFLECTION_CMD")->setEnabled(true);
331
332   ModuleBase_IModule* aModule = myWorkshop->module();
333   if (aModule)
334     aModule->updateObjectBrowserMenu(myActions);
335 }
336
337 void XGUI_ContextMenuMgr::updateViewerMenu()
338 {
339   foreach(QAction* aAction, myActions)
340     aAction->setEnabled(false);
341
342   XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
343   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
344   QList<ModuleBase_ViewerPrsPtr> aPrsList =
345     aSelMgr->selection()->getSelected(ModuleBase_ISelection::Viewer);
346   if (aPrsList.size() > 0) {
347     bool isVisible = false;
348     bool isShading = false;
349     bool canBeShaded = false;
350     ObjectPtr aObject;
351     foreach(ModuleBase_ViewerPrsPtr aPrs, aPrsList) {
352       aObject = aPrs->object();
353       ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObject);
354       if (aRes && aRes->isDisplayed()) {
355         isVisible = true;
356         canBeShaded = myWorkshop->displayer()->canBeShaded(aObject);
357         isShading =
358           (myWorkshop->displayer()->displayMode(aObject) == XGUI_Displayer::Shading);
359         break;
360       }
361     }
362     if (isVisible) {
363       if (canBeShaded) {
364         XGUI_Displayer::DisplayMode aMode = aDisplayer->displayMode(aObject);
365         if (aMode != XGUI_Displayer::NoMode) {
366           action("WIREFRAME_CMD")->setEnabled(aMode == XGUI_Displayer::Shading);
367           action("SHADING_CMD")->setEnabled(aMode == XGUI_Displayer::Wireframe);
368         } else {
369           action("WIREFRAME_CMD")->setEnabled(true);
370           action("SHADING_CMD")->setEnabled(true);
371         }
372       }
373       action("SHOW_ONLY_CMD")->setEnabled(true);
374       action("HIDE_CMD")->setEnabled(true);
375     } else
376       action("SHOW_CMD")->setEnabled(true);
377   }
378   if (myWorkshop->displayer()->objectsCount() > 0)
379     action("HIDEALL_CMD")->setEnabled(true);
380
381   // Update selection menu
382   QIntList aModes = aDisplayer->activeSelectionModes();
383   action("SELECT_VERTEX_CMD")->setEnabled(true);
384   action("SELECT_EDGE_CMD")->setEnabled(true);
385   action("SELECT_FACE_CMD")->setEnabled(true);
386   action("SELECT_RESULT_CMD")->setEnabled(true);
387
388   action("SELECT_RESULT_CMD")->setChecked(false);
389   action("SELECT_VERTEX_CMD")->setChecked(false);
390   action("SELECT_EDGE_CMD")->setChecked(false);
391   action("SELECT_FACE_CMD")->setChecked(false);
392   action("SELECT_RESULT_CMD")->setChecked(false);
393   if (aModes.count() == 0) {
394     action("SELECT_RESULT_CMD")->setChecked(true);
395   } else {
396     foreach(int aMode, aModes) {
397       switch (aMode) {
398       case TopAbs_VERTEX:
399         action("SELECT_VERTEX_CMD")->setChecked(true);
400         break;
401       case TopAbs_EDGE:
402         action("SELECT_EDGE_CMD")->setChecked(true);
403         break;
404       case TopAbs_FACE:
405         action("SELECT_FACE_CMD")->setChecked(true);
406         break;
407       default:
408         action("SELECT_RESULT_CMD")->setChecked(true);
409       }
410     }
411   }
412
413   ModuleBase_IModule* aModule = myWorkshop->module();
414   if (aModule)
415     aModule->updateViewerMenu(myActions);
416
417   if (myWorkshop->canChangeColor())
418     action("COLOR_CMD")->setEnabled(true);
419
420   if (myWorkshop->canChangeDeflection())
421     action("DEFLECTION_CMD")->setEnabled(true);
422
423   action("DELETE_CMD")->setEnabled(true);
424 }
425
426 void XGUI_ContextMenuMgr::connectObjectBrowser()
427 {
428   connect(myWorkshop->objectBrowser(), SIGNAL(contextMenuRequested(QContextMenuEvent*)), this,
429           SLOT(onContextMenuRequest(QContextMenuEvent*)));
430 }
431
432 void XGUI_ContextMenuMgr::connectViewer()
433 {
434   connect(myWorkshop->viewer(), SIGNAL(contextMenuRequested(QContextMenuEvent*)), this,
435           SLOT(onContextMenuRequest(QContextMenuEvent*)));
436 }
437
438
439 void XGUI_ContextMenuMgr::buildObjBrowserMenu()
440 {
441   QAction* aSeparator = ModuleBase_Tools::createAction(QIcon(), "", myWorkshop->desktop());
442   aSeparator->setSeparator(true);
443
444   QActionsList aList;
445
446   // Result construction menu
447   aList.append(action("SHOW_CMD"));
448   aList.append(action("HIDE_CMD"));
449   aList.append(action("SHOW_ONLY_CMD"));
450   aList.append(mySeparator);
451   aList.append(action("RENAME_CMD"));
452   aList.append(action("COLOR_CMD"));
453   aList.append(action("DEFLECTION_CMD"));
454   aList.append(action("SHOW_FEATURE_CMD"));
455   myObjBrowserMenus[ModelAPI_ResultConstruction::group()] = aList;
456
457   //-------------------------------------
458   // Result body menu
459   aList.clear();
460   aList.append(action("WIREFRAME_CMD"));
461   aList.append(action("SHADING_CMD"));
462   aList.append(mySeparator); // this separator is not shown as this action is added after show only
463   // qt list container contains only one instance of the same action
464   aList.append(action("SHOW_CMD"));
465   aList.append(action("HIDE_CMD"));
466   aList.append(action("SHOW_ONLY_CMD"));
467   aList.append(mySeparator);
468   aList.append(action("RENAME_CMD"));
469   aList.append(action("COLOR_CMD"));
470   aList.append(action("DEFLECTION_CMD"));
471   aList.append(action("SHOW_FEATURE_CMD"));
472   myObjBrowserMenus[ModelAPI_ResultBody::group()] = aList;
473   // Group menu
474   myObjBrowserMenus[ModelAPI_ResultGroup::group()] = aList;
475   myObjBrowserMenus[ModelAPI_ResultField::group()] = aList;
476   // Result part menu
477   myObjBrowserMenus[ModelAPI_ResultPart::group()] = aList;
478   //-------------------------------------
479   // Feature menu
480   aList.clear();
481   aList.append(action("RENAME_CMD"));
482   aList.append(action("SHOW_RESULTS_CMD"));
483   aList.append(action("MOVE_CMD"));
484   aList.append(mySeparator);
485   aList.append(action("CLEAN_HISTORY_CMD"));
486   aList.append(action("DELETE_CMD"));
487   myObjBrowserMenus[ModelAPI_Feature::group()] = aList;
488
489   aList.clear();
490   aList.append(action("RENAME_CMD"));
491   aList.append(mySeparator);
492   aList.append(action("CLEAN_HISTORY_CMD"));
493   aList.append(action("DELETE_CMD"));
494   myObjBrowserMenus[ModelAPI_ResultParameter::group()] = aList;
495   //-------------------------------------
496 }
497
498 void XGUI_ContextMenuMgr::buildViewerMenu()
499 {
500   QActionsList aList;
501   // Result construction menu
502   aList.append(action("HIDE_CMD"));
503   aList.append(action("SHOW_ONLY_CMD"));
504   aList.append(mySeparator);
505   aList.append(action("COLOR_CMD"));
506   aList.append(action("DEFLECTION_CMD"));
507   myViewerMenu[ModelAPI_ResultConstruction::group()] = aList;
508   // Result part menu
509   myViewerMenu[ModelAPI_ResultPart::group()] = aList;
510   //-------------------------------------
511   // Result body menu
512   aList.clear();
513   aList.append(action("WIREFRAME_CMD"));
514   aList.append(action("SHADING_CMD"));
515   aList.append(mySeparator);
516   aList.append(action("HIDE_CMD"));
517   aList.append(action("SHOW_ONLY_CMD"));
518   aList.append(mySeparator);
519   aList.append(action("COLOR_CMD"));
520   aList.append(action("DEFLECTION_CMD"));
521   myViewerMenu[ModelAPI_ResultBody::group()] = aList;
522   // Group menu
523   myViewerMenu[ModelAPI_ResultGroup::group()] = aList;
524   myViewerMenu[ModelAPI_ResultField::group()] = aList;
525   //-------------------------------------
526 }
527
528
529 void XGUI_ContextMenuMgr::addObjBrowserMenu(QMenu* theMenu) const
530 {
531   ModuleBase_IModule* aModule = myWorkshop->module();
532   if (aModule) {
533     theMenu->addSeparator();
534     aModule->addObjectBrowserMenu(theMenu);
535   }
536
537   XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
538   QObjectPtrList aObjects = aSelMgr->selection()->selectedObjects();
539   int aSelected = aObjects.size();
540   QActionsList aActions;
541   if (aSelected == 1) {
542     ObjectPtr aObject = aObjects.first();
543     std::string aName = aObject->groupName();
544     if (myObjBrowserMenus.contains(aName))
545       aActions = myObjBrowserMenus[aName];
546   } else if (aSelected > 1) {
547       aActions.append(action("WIREFRAME_CMD"));
548       aActions.append(action("SHADING_CMD"));
549       aActions.append(mySeparator);
550       aActions.append(action("SHOW_CMD"));
551       aActions.append(action("HIDE_CMD"));
552       aActions.append(action("SHOW_ONLY_CMD"));
553       aActions.append(mySeparator);
554       //aActions.append(action("MOVE_CMD"));
555       aActions.append(action("COLOR_CMD"));
556       aActions.append(action("DEFLECTION_CMD"));
557
558       aActions.append(action("CLEAN_HISTORY_CMD"));
559       aActions.append(action("DELETE_CMD"));
560   }
561   theMenu->addActions(aActions);
562   addFeatures(theMenu);
563
564   // It is commented out because Object Browser does not have actions
565   //theMenu->addSeparator();
566   //theMenu->addActions(myWorkshop->objectBrowser()->actions());
567 }
568
569 void XGUI_ContextMenuMgr::addViewerMenu(QMenu* theMenu) const
570 {
571   XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
572   QList<ModuleBase_ViewerPrsPtr> aPrsList =
573     aSelMgr->selection()->getSelected(ModuleBase_ISelection::Viewer);
574   int aSelected = aPrsList.size();
575   QActionsList aActions;
576
577   // Create selection menu
578   XGUI_OperationMgr* aOpMgr = myWorkshop->operationMgr();
579   QIntList aModes;
580   myWorkshop->module()->activeSelectionModes(aModes);
581   if ((!aOpMgr->hasOperation()) && aModes.isEmpty()) {
582     QMenu* aSelMenu = new QMenu(tr("Selection mode"), theMenu);
583     aSelMenu->addAction(action("SELECT_VERTEX_CMD"));
584     aSelMenu->addAction(action("SELECT_EDGE_CMD"));
585     aSelMenu->addAction(action("SELECT_FACE_CMD"));
586     //IMP: an attempt to use result selection with other selection modes
587     //aSelMenu->addSeparator();
588     aSelMenu->addAction(action("SELECT_RESULT_CMD"));
589     theMenu->addMenu(aSelMenu);
590     theMenu->addSeparator();
591   }
592   if (aSelected == 1) {
593     ObjectPtr aObject = aPrsList.first()->object();
594     if (aObject.get() != NULL) {
595       std::string aName = aObject->groupName();
596       if (myViewerMenu.contains(aName))
597         aActions = myViewerMenu[aName];
598     }
599   } else if (aSelected > 1) {
600     aActions.append(action("HIDE_CMD"));
601   }
602   // hide all is shown always even if selection in the viewer is empty
603   aActions.append(action("HIDEALL_CMD"));
604   aActions.append(action("COLOR_CMD"));
605   aActions.append(action("DEFLECTION_CMD"));
606
607   theMenu->addActions(aActions);
608
609   QMap<int, QAction*> aMenuActions;
610   ModuleBase_IModule* aModule = myWorkshop->module();
611   if (aModule) {
612     if (aModule->addViewerMenu(myActions, theMenu, aMenuActions))
613       theMenu->addSeparator();
614   }
615
616   // insert the module menu items on specific positions in the popup menu: some actions should be
617   // in the begin of the list, Delete action should be the last by #1343 issue
618   QList<QAction*> anActions = theMenu->actions();
619   int anActionsSize = anActions.size();
620   QAction* aFirstAction = anActions[0];
621   QMap<int, QAction*>::const_iterator anIt = aMenuActions.begin(), aLast = aMenuActions.end();
622   for (; anIt != aLast; anIt++) {
623     if (anIt.key() > anActionsSize)
624       theMenu->addAction(anIt.value());
625     else
626       theMenu->insertAction(aFirstAction, *anIt);
627   }
628
629 #ifndef HAVE_SALOME
630   theMenu->addSeparator();
631   QMdiArea* aMDI = myWorkshop->mainWindow()->mdiArea();
632   if (aMDI->actions().size() > 0) {
633     QMenu* aSubMenu = theMenu->addMenu(tr("Windows"));
634     aSubMenu->addActions(aMDI->actions());
635   }
636 #endif
637 }
638
639 QStringList XGUI_ContextMenuMgr::actionObjectGroups(const QString& theName)
640 {
641   QStringList aGroups;
642
643   QMap<std::string, QActionsList>::const_iterator anIt = myObjBrowserMenus.begin(),
644                                                   aLast = myObjBrowserMenus.end();
645   for (; anIt != aLast; anIt++) {
646     QString aGroupName(anIt.key().c_str());
647     if (aGroups.contains(aGroupName))
648       continue;
649     QActionsList anActions = anIt.value();
650     QActionsList::const_iterator anAIt = anActions.begin(), anALast = anActions.end();
651     bool aFound = false;
652     for (; anAIt != anALast && !aFound; anAIt++)
653       aFound = (*anAIt)->data().toString() == theName;
654     if (aFound)
655       aGroups.append(aGroupName);
656   }
657   return aGroups;
658 }
659
660 void XGUI_ContextMenuMgr::onRename()
661 {
662   QObjectPtrList anObjects = myWorkshop->selector()->selection()->selectedObjects();
663   if (!myWorkshop->abortAllOperations())
664     return;
665   // restore selection in case if dialog box was shown
666   myWorkshop->objectBrowser()->setObjectsSelected(anObjects);
667   myWorkshop->objectBrowser()->onEditItem();
668 }
669
670 void XGUI_ContextMenuMgr::addFeatures(QMenu* theMenu) const
671 {
672   SessionPtr aMgr = ModelAPI_Session::get();
673   DocumentPtr aActiveDoc = aMgr->activeDocument();
674
675   XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
676   XGUI_ActionsMgr* aActionMgr = myWorkshop->actionsMgr();
677   const Config_DataModelReader* aDataModelXML = myWorkshop->dataModelXMLReader();
678   QModelIndexList aSelectedIndexes = aSelMgr->selection()->selectedIndexes();
679
680   QString aName;
681   int aLen = 0;
682   bool aIsRoot = false;
683   foreach(QModelIndex aIdx, aSelectedIndexes) {
684     // Process only first column
685     if (aIdx.column() == 0) {
686       aIsRoot = !aIdx.parent().isValid();
687       // Exit if the selected index belongs to non active document
688       if (aIsRoot && (aActiveDoc != aMgr->moduleDocument()))
689         return;
690       if ((!aIsRoot) && (aIdx.internalPointer() != aActiveDoc.get()))
691         return;
692
693       // Get name of the selected index
694       aName = aIdx.data().toString();
695       aLen = aName.indexOf('(');
696       if (aLen != -1) {
697         aName = aName.left(--aLen);
698       }
699       std::string aFeaturesStr = aIsRoot?
700         aDataModelXML->rootFolderFeatures(aName.toStdString()) :
701         aDataModelXML->subFolderFeatures(aName.toStdString());
702         if (aFeaturesStr.length() > 0) {
703           QStringList aFeturesList =
704             QString(aFeaturesStr.c_str()).split(",", QString::SkipEmptyParts);
705           foreach(QString aFea, aFeturesList) {
706             QAction* aAction = aActionMgr->action(aFea);
707             if (aAction)
708               theMenu->addAction(aAction);
709           }
710         }
711     }
712   }
713 }
714
715 #define UNCHECK_ACTION(NAME) \
716 { QAction* aAction = action(NAME); \
717 bool isBlock = aAction->signalsBlocked(); \
718 aAction->blockSignals(true); \
719 aAction->setChecked(false); \
720   aAction->blockSignals(isBlock); }
721
722
723 void XGUI_ContextMenuMgr::onResultSelection(bool theChecked)
724 {
725   UNCHECK_ACTION("SELECT_VERTEX_CMD");
726   UNCHECK_ACTION("SELECT_EDGE_CMD");
727   UNCHECK_ACTION("SELECT_FACE_CMD");
728 }
729
730 void XGUI_ContextMenuMgr::onShapeSelection(bool theChecked)
731 {
732   UNCHECK_ACTION("SHOW_RESULTS_CMD");
733 }