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