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