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