Salome HOME
Restore Delete menu
[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
12 #include <AppElements_MainWindow.h>
13
14 //#include "PartSetPlugin_Part.h"
15
16 #include <ModelAPI_Data.h>
17 #include <ModelAPI_AttributeDocRef.h>
18 #include <ModelAPI_Object.h>
19 #include <ModelAPI_Session.h>
20 #include <ModelAPI_ResultGroup.h>
21 #include <ModelAPI_ResultParameter.h>
22 #include <ModelAPI_ResultConstruction.h>
23 #include <ModelAPI_ResultBody.h>
24
25 #include <ModuleBase_IModule.h>
26 #include <ModuleBase_Tools.h>
27
28 #include <QAction>
29 #include <QContextMenuEvent>
30 #include <QMenu>
31 #include <QMdiArea>
32
33
34 XGUI_ContextMenuMgr::XGUI_ContextMenuMgr(XGUI_Workshop* theParent)
35     : QObject(theParent),
36       myWorkshop(theParent),
37       mySeparator(0)
38 {
39 }
40
41 XGUI_ContextMenuMgr::~XGUI_ContextMenuMgr()
42 {
43 }
44
45 void XGUI_ContextMenuMgr::createActions()
46 {
47   QAction* aAction = new QAction(QIcon(":pictures/delete.png"), tr("Delete"), this);
48   QMainWindow* aDesktop = myWorkshop->mainWindow();
49   if (!aDesktop)
50     aDesktop = myWorkshop->salomeConnector()->desktop();
51   aDesktop->addAction(aAction);
52
53   addAction("DELETE_CMD", aAction);
54   aAction->setShortcut(Qt::Key_Delete);
55   aAction->setShortcutContext(Qt::ApplicationShortcut);
56
57   aAction = new QAction(QIcon(":pictures/color.png"), tr("Color..."), this);
58   addAction("COLOR_CMD", aAction);
59
60   aAction = new QAction(QIcon(":pictures/eye_pencil.png"), tr("Show"), this);
61   addAction("SHOW_CMD", aAction);
62
63   aAction = new QAction(QIcon(":pictures/eye_pencil.png"), tr("Show only"), this);
64   addAction("SHOW_ONLY_CMD", aAction);
65
66   aAction = new QAction(QIcon(":pictures/eye_pencil_closed.png"), tr("Hide"), this);
67   addAction("HIDE_CMD", aAction);
68
69   aAction = new QAction(QIcon(":pictures/eye_pencil_closed.png"), tr("Hide all"), this);
70   addAction("HIDEALL_CMD", aAction);
71
72   aAction = new QAction(QIcon(":pictures/shading.png"), tr("Shading"), this);
73   addAction("SHADING_CMD", aAction);
74
75   aAction = new QAction(QIcon(":pictures/wireframe.png"), tr("Wireframe"), this);
76   addAction("WIREFRAME_CMD", aAction);
77
78   mySeparator = new QAction(this);
79   mySeparator->setSeparator(true);
80
81
82   buildObjBrowserMenu();
83   buildViewerMenu();
84 }
85
86 void XGUI_ContextMenuMgr::addAction(const QString& theId, QAction* theAction)
87 {
88   if (myActions.contains(theId))
89     qCritical("A command with Id = '%s' already defined!", qPrintable(theId));
90   theAction->setData(theId);
91   connect(theAction, SIGNAL(triggered(bool)), this, SLOT(onAction(bool)));
92   myActions[theId] = theAction;
93 }
94
95 QAction* XGUI_ContextMenuMgr::action(const QString& theId) const
96 {
97   if (myActions.contains(theId))
98     return myActions[theId];
99   return 0;
100 }
101
102 QAction* XGUI_ContextMenuMgr::actionByName(const QString& theName) const
103 {
104   foreach(QAction* eachAction, myActions) {
105     if (eachAction->text() == theName) {
106       return eachAction;
107     }
108   }
109   return NULL;
110 }
111
112 QStringList XGUI_ContextMenuMgr::actionIds() const
113 {
114   return myActions.keys();
115 }
116
117 void XGUI_ContextMenuMgr::onAction(bool isChecked)
118 {
119   QAction* aAction = static_cast<QAction*>(sender());
120   emit actionTriggered(aAction->data().toString(), isChecked);
121 }
122
123 void XGUI_ContextMenuMgr::updateCommandsStatus()
124 {
125 }
126
127 void XGUI_ContextMenuMgr::onContextMenuRequest(QContextMenuEvent* theEvent)
128 {
129   QMenu* aMenu = 0;
130   if (sender() == myWorkshop->objectBrowser()) {
131     updateObjectBrowserMenu();
132     aMenu = objBrowserMenu();
133   } else if (sender() == myWorkshop->viewer()) {
134     updateViewerMenu();
135     aMenu = viewerMenu();
136   }
137
138   if (aMenu && (aMenu->actions().size() > 0)) {
139     // it is possible that some objects should do something before and after the popup menu exec
140     // e.g. a sketch manager changes an internal flag on this signals in order to do not hide
141     // a created entity
142     emit beforeContextMenu();
143     aMenu->exec(theEvent->globalPos());
144     emit afterContextMenu();
145     delete aMenu;
146   }
147 }
148
149 void XGUI_ContextMenuMgr::updateObjectBrowserMenu() 
150 {
151   foreach(QAction* aAction, myActions)
152     aAction->setEnabled(false);
153
154   XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
155   QObjectPtrList aObjects = aSelMgr->selection()->selectedObjects();
156   int aSelected = aObjects.size();
157   if (aSelected > 0) {
158     SessionPtr aMgr = ModelAPI_Session::get();
159     XGUI_Displayer* aDisplayer = myWorkshop->displayer();
160     bool hasResult = false;
161     bool hasFeature = false;
162     bool hasParameter = false;
163     ModuleBase_Tools::checkObjects(aObjects, hasResult, hasFeature, hasParameter);
164
165     //Process Feature
166     if (aSelected == 1) {
167       ObjectPtr aObject = aObjects.first();
168       if (aObject) {
169         if (!hasFeature) {
170           if (aObject->isDisplayed()) {
171             if (aDisplayer->canBeShaded(aObject)) {
172               action("WIREFRAME_CMD")->setEnabled(true);
173               action("SHADING_CMD")->setEnabled(true);
174             }
175             action("HIDE_CMD")->setEnabled(true);
176           } else if (hasResult && (!hasParameter)) {
177             action("SHOW_CMD")->setEnabled(true);
178           }
179
180           ResultPartPtr aPartRes = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObject);
181           if (aPartRes) {
182             action("SHOW_CMD")->setEnabled(true);
183           }
184
185           if (!(hasParameter || hasFeature))
186             action("SHOW_ONLY_CMD")->setEnabled(true);
187         }
188       } 
189     } else {
190       if (hasResult && (!hasParameter)) {
191         action("SHOW_CMD")->setEnabled(true);
192         action("HIDE_CMD")->setEnabled(true);
193         action("SHOW_ONLY_CMD")->setEnabled(true);
194         action("SHADING_CMD")->setEnabled(true);
195         action("WIREFRAME_CMD")->setEnabled(true);
196       }
197     }
198     if (hasFeature || hasParameter)
199       action("DELETE_CMD")->setEnabled(true);
200   }
201   if (myWorkshop->canChangeColor())
202     action("COLOR_CMD")->setEnabled(true);
203 }
204
205 void XGUI_ContextMenuMgr::updateViewerMenu()
206 {
207   foreach(QAction* aAction, myActions)
208     aAction->setEnabled(false);
209
210   XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
211   QObjectPtrList aObjects = aSelMgr->selection()->selectedObjects();
212   if (aObjects.size() > 0) {
213     bool isVisible = false;
214     bool isShading = false;
215     bool canBeShaded = false;
216     foreach(ObjectPtr aObject, aObjects)
217     {
218       ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObject);
219       if (aRes && aRes->isDisplayed()) {
220         isVisible = true;
221         canBeShaded = myWorkshop->displayer()->canBeShaded(aObject);
222         isShading = (myWorkshop->displayer()->displayMode(aObject) == XGUI_Displayer::Shading);      
223         break;
224       }
225     }
226     if (isVisible) {
227       if (canBeShaded) {
228         action("WIREFRAME_CMD")->setEnabled(true);
229         action("SHADING_CMD")->setEnabled(true);
230       }
231       action("SHOW_ONLY_CMD")->setEnabled(true);
232       action("HIDE_CMD")->setEnabled(true);
233     } else
234       action("SHOW_CMD")->setEnabled(true);
235   }
236   if (myWorkshop->displayer()->objectsCount() > 0)
237     action("HIDEALL_CMD")->setEnabled(true);
238   if (myWorkshop->canChangeColor())
239     action("COLOR_CMD")->setEnabled(true);
240 }
241
242 void XGUI_ContextMenuMgr::connectObjectBrowser()
243 {
244   connect(myWorkshop->objectBrowser(), SIGNAL(contextMenuRequested(QContextMenuEvent*)), this,
245           SLOT(onContextMenuRequest(QContextMenuEvent*)));
246 }
247
248 void XGUI_ContextMenuMgr::connectViewer()
249 {
250   connect(myWorkshop->viewer(), SIGNAL(contextMenuRequested(QContextMenuEvent*)), this,
251           SLOT(onContextMenuRequest(QContextMenuEvent*)));
252 }
253
254
255 void XGUI_ContextMenuMgr::buildObjBrowserMenu()
256 {
257   QAction* aSeparator = new QAction(this);
258   aSeparator->setSeparator(true);
259
260   QActionsList aList;
261   
262   // Result construction menu
263   aList.append(action("SHOW_CMD"));
264   aList.append(action("HIDE_CMD"));
265   aList.append(action("SHOW_ONLY_CMD"));
266   aList.append(action("COLOR_CMD"));
267   myObjBrowserMenus[ModelAPI_ResultConstruction::group()] = aList;
268   // Result part menu
269   myObjBrowserMenus[ModelAPI_ResultPart::group()] = aList;
270   //-------------------------------------
271   // Result body menu
272   aList.clear();
273   aList.append(action("WIREFRAME_CMD"));
274   aList.append(action("SHADING_CMD"));
275   aList.append(action("COLOR_CMD"));
276   aList.append(mySeparator);
277   aList.append(action("SHOW_CMD"));
278   aList.append(action("HIDE_CMD"));
279   aList.append(action("SHOW_ONLY_CMD"));
280   myObjBrowserMenus[ModelAPI_ResultBody::group()] = aList;
281   // Group menu
282   myObjBrowserMenus[ModelAPI_ResultGroup::group()] = aList;
283   //-------------------------------------
284   // Feature menu
285   aList.clear();
286   aList.append(action("DELETE_CMD"));
287   myObjBrowserMenus[ModelAPI_Feature::group()] = aList;
288   myObjBrowserMenus[ModelAPI_ResultParameter::group()] = aList;
289   //-------------------------------------
290 }
291
292 void XGUI_ContextMenuMgr::buildViewerMenu()
293 {
294   QActionsList aList;
295   // Result construction menu
296   aList.append(action("HIDE_CMD"));
297   aList.append(action("SHOW_ONLY_CMD"));
298   aList.append(action("HIDEALL_CMD"));
299   aList.append(action("COLOR_CMD"));
300   myViewerMenu[ModelAPI_ResultConstruction::group()] = aList;
301   // Result part menu
302   myViewerMenu[ModelAPI_ResultPart::group()] = aList;
303   //-------------------------------------
304   // Result body menu
305   aList.clear();
306   aList.append(action("WIREFRAME_CMD"));
307   aList.append(action("SHADING_CMD"));
308   aList.append(action("COLOR_CMD"));
309   aList.append(mySeparator);
310   aList.append(action("HIDE_CMD"));
311   aList.append(action("SHOW_ONLY_CMD"));
312   aList.append(action("HIDEALL_CMD"));
313   myViewerMenu[ModelAPI_ResultBody::group()] = aList;
314   // Group menu
315   myViewerMenu[ModelAPI_ResultGroup::group()] = aList;
316   //-------------------------------------
317
318 }
319
320
321 QMenu* XGUI_ContextMenuMgr::objBrowserMenu() const
322 {
323   QMenu* aMenu = new QMenu();
324   XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
325   QObjectPtrList aObjects = aSelMgr->selection()->selectedObjects();
326   int aSelected = aObjects.size();
327   QActionsList aActions;
328   if (aSelected == 1) {
329     ObjectPtr aObject = aObjects.first();
330     std::string aName = aObject->groupName();
331     if (myObjBrowserMenus.contains(aName))
332       aActions = myObjBrowserMenus[aName];
333   } else if (aSelected > 1) {
334       aActions.append(action("HIDE_CMD"));
335       aActions.append(action("SHOW_ONLY_CMD"));
336       aActions.append(mySeparator);
337       aActions.append(action("SHADING_CMD"));
338       aActions.append(action("WIREFRAME_CMD"));
339   }
340   aMenu->addActions(aActions);
341
342   ModuleBase_IModule* aModule = myWorkshop->module();
343   if (aModule) {
344     aMenu->addSeparator();
345     aModule->addObjectBrowserMenu(aMenu);
346   }
347   aMenu->addSeparator();
348   aMenu->addActions(myWorkshop->objectBrowser()->actions());
349
350   return aMenu;
351 }
352
353 QMenu* XGUI_ContextMenuMgr::viewerMenu() const
354 {
355   QMenu* aMenu = new QMenu();
356   ModuleBase_IModule* aModule = myWorkshop->module();
357   if (aModule) 
358     aModule->addViewerMenu(aMenu, myActions);
359
360   XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
361   QObjectPtrList aObjects = aSelMgr->selection()->selectedObjects();
362   int aSelected = aObjects.size();
363   QActionsList aActions;
364   if (aSelected == 1) {
365     ObjectPtr aObject = aObjects.first();
366     std::string aName = aObject->groupName();
367     if (myViewerMenu.contains(aName))
368       aActions = myViewerMenu[aName];
369   } else if (aSelected > 1) {
370     aActions.append(action("HIDE_CMD"));
371   }
372   aMenu->addActions(aActions);
373
374   if (!myWorkshop->isSalomeMode()) {
375     aMenu->addSeparator();
376     QMdiArea* aMDI = myWorkshop->mainWindow()->mdiArea();
377     if (aMDI->actions().size() > 0) {
378       QMenu* aSubMenu = aMenu->addMenu(tr("Windows"));
379       aSubMenu->addActions(aMDI->actions());
380     }
381   }
382   return aMenu;
383 }