Salome HOME
Provide editing of parameters
[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_ResultPart.h>
20 #include <ModelAPI_Session.h>
21 #include <ModelAPI_ResultGroup.h>
22 #include <ModelAPI_ResultParameter.h>
23
24 #include <ModuleBase_IModule.h>
25
26 #include <QAction>
27 #include <QContextMenuEvent>
28 #include <QMenu>
29 #include <QMdiArea>
30
31 XGUI_ContextMenuMgr::XGUI_ContextMenuMgr(XGUI_Workshop* theParent)
32     : QObject(theParent),
33       myWorkshop(theParent)
34 {
35 }
36
37 XGUI_ContextMenuMgr::~XGUI_ContextMenuMgr()
38 {
39 }
40
41 void XGUI_ContextMenuMgr::createActions()
42 {
43   QAction* aAction = new QAction(QIcon(":pictures/edit.png"), tr("Edit..."), this);
44   addAction("EDIT_CMD", aAction);
45
46   aAction = new QAction(QIcon(":pictures/activate.png"), tr("Activate"), this);
47   addAction("ACTIVATE_PART_CMD", aAction);
48
49   aAction = new QAction(QIcon(":pictures/assembly.png"), tr("Deactivate"), this);
50   addAction("DEACTIVATE_PART_CMD", aAction);
51
52   aAction = new QAction(QIcon(":pictures/delete.png"), tr("Delete"), this);
53   QMainWindow* aDesktop = myWorkshop->mainWindow();
54   if (!aDesktop)
55     aDesktop = myWorkshop->salomeConnector()->desktop();
56   aDesktop->addAction(aAction);
57
58   addAction("DELETE_CMD", aAction);
59   aAction->setShortcut(Qt::Key_Delete);
60   aAction->setShortcutContext(Qt::ApplicationShortcut);
61
62   aAction = new QAction(QIcon(":pictures/color.png"), tr("Color"), this);
63   addAction("COLOR_CMD", aAction);
64
65   aAction = new QAction(QIcon(":pictures/eye_pencil.png"), tr("Show"), this);
66   addAction("SHOW_CMD", aAction);
67
68   aAction = new QAction(QIcon(":pictures/eye_pencil.png"), tr("Show only"), this);
69   addAction("SHOW_ONLY_CMD", aAction);
70
71   aAction = new QAction(QIcon(":pictures/eye_pencil_closed.png"), tr("Hide"), this);
72   addAction("HIDE_CMD", aAction);
73
74   aAction = new QAction(QIcon(":pictures/eye_pencil_closed.png"), tr("Hide all"), this);
75   addAction("HIDEALL_CMD", aAction);
76
77   aAction = new QAction(QIcon(":pictures/shading.png"), tr("Shading"), this);
78   addAction("SHADING_CMD", aAction);
79
80   aAction = new QAction(QIcon(":pictures/wireframe.png"), tr("Wireframe"), this);
81   addAction("WIREFRAME_CMD", aAction);
82 }
83
84 void XGUI_ContextMenuMgr::addAction(const QString& theId, QAction* theAction)
85 {
86   if (myActions.contains(theId))
87     qCritical("A command with Id = '%s' already defined!", qPrintable(theId));
88   theAction->setData(theId);
89   connect(theAction, SIGNAL(triggered(bool)), this, SLOT(onAction(bool)));
90   myActions[theId] = theAction;
91 }
92
93 QAction* XGUI_ContextMenuMgr::action(const QString& theId) const
94 {
95   if (myActions.contains(theId))
96     return myActions[theId];
97   return 0;
98 }
99
100 QStringList XGUI_ContextMenuMgr::actionIds() const
101 {
102   return myActions.keys();
103 }
104
105 void XGUI_ContextMenuMgr::onAction(bool isChecked)
106 {
107   QAction* aAction = static_cast<QAction*>(sender());
108   emit actionTriggered(aAction->data().toString(), isChecked);
109 }
110
111 void XGUI_ContextMenuMgr::updateCommandsStatus()
112 {
113 }
114
115 void XGUI_ContextMenuMgr::onContextMenuRequest(QContextMenuEvent* theEvent)
116 {
117   QMenu* aMenu = 0;
118   if (sender() == myWorkshop->objectBrowser())
119     aMenu = objectBrowserMenu();
120   else if (sender() == myWorkshop->viewer()) {
121     aMenu = viewerMenu();
122   }
123
124   if (aMenu && (aMenu->actions().size() > 0)) {
125     // it is possible that some objects should do something before and after the popup menu exec
126     // e.g. a sketch manager changes an internal flag on this signals in order to do not hide
127     // a created entity
128     emit beforeContextMenu();
129     aMenu->exec(theEvent->globalPos());
130     emit afterContextMenu();
131     delete aMenu;
132   }
133 }
134
135 QMenu* XGUI_ContextMenuMgr::objectBrowserMenu() const
136 {
137   QMenu* aMenu = new QMenu();
138   XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
139   QObjectPtrList aObjects = aSelMgr->selection()->selectedObjects();
140   int aSelected = aObjects.size();
141   if (aSelected > 0) {
142     SessionPtr aMgr = ModelAPI_Session::get();
143     XGUI_Displayer* aDisplayer = myWorkshop->displayer();
144     bool hasResult = false;
145     bool hasFeature = false;
146     bool hasParameter = false;
147     foreach(ObjectPtr aObj, aObjects)
148     {
149       FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
150       ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
151       ResultParameterPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aResult);
152
153       hasResult = (aResult.get() != NULL);
154       hasFeature = (aFeature.get() != NULL);
155       hasParameter = (aConstruction.get() != NULL);
156       if (hasFeature && hasResult  && hasParameter)
157         break;
158     }
159     //Process Feature
160     if (aSelected == 1) {
161       ObjectPtr aObject = aObjects.first();
162       if (aObject) {
163         ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObject);
164         if (aPart) {
165           if (aMgr->activeDocument() == aPart->partDoc())
166             aMenu->addAction(action("DEACTIVATE_PART_CMD"));
167           else
168             aMenu->addAction(action("ACTIVATE_PART_CMD"));
169         } else if (hasFeature && aObject->document() == aMgr->activeDocument()) {
170           aMenu->addAction(action("EDIT_CMD"));
171         } else {
172           if (aDisplayer->isVisible(aObject)) {
173             if (aDisplayer->canBeShaded(aObject)) {
174               if (aDisplayer->displayMode(aObject) == XGUI_Displayer::Shading)
175                 aMenu->addAction(action("WIREFRAME_CMD"));
176               else
177                 aMenu->addAction(action("SHADING_CMD"));
178             }
179             aMenu->addSeparator();
180             aMenu->addAction(action("HIDE_CMD"));
181           } else if (!hasParameter) {
182             aMenu->addAction(action("SHOW_CMD"));
183           }
184           if (hasParameter)
185             aMenu->addAction(action("EDIT_CMD"));
186           else
187             aMenu->addAction(action("SHOW_ONLY_CMD"));
188         }
189       } else {  // If feature is 0 the it means that selected root object (document)
190         if (aMgr->activeDocument() != aMgr->moduleDocument())
191           aMenu->addAction(action("ACTIVATE_PART_CMD"));
192       }
193     } else {
194       if (hasResult && (!hasParameter)) {
195         aMenu->addAction(action("SHOW_CMD"));
196         aMenu->addAction(action("HIDE_CMD"));
197         aMenu->addAction(action("SHOW_ONLY_CMD"));
198         aMenu->addSeparator();
199         aMenu->addAction(action("SHADING_CMD"));
200         aMenu->addAction(action("WIREFRAME_CMD"));
201       }
202     }
203     if (hasFeature || hasParameter)
204       aMenu->addAction(action("DELETE_CMD"));
205   }
206   if (myWorkshop->canChangeColor())
207     aMenu->addAction(action("COLOR_CMD"));
208
209   aMenu->addSeparator();
210   aMenu->addActions(myWorkshop->objectBrowser()->actions());
211
212   ModuleBase_IModule* aModule = myWorkshop->module();
213   if (aModule)
214     aModule->addObjectBrowserItems(aMenu);
215
216   if (aMenu->actions().size() > 0) {
217     return aMenu;
218   }
219   delete aMenu;
220   return 0;
221 }
222
223 QMenu* XGUI_ContextMenuMgr::viewerMenu() const
224 {
225   QMenu* aMenu = new QMenu();
226   addViewerItems(aMenu);
227   if (aMenu->actions().size() > 0) {
228     return aMenu;
229   }
230   delete aMenu;
231   return 0;
232 }
233
234 void XGUI_ContextMenuMgr::addViewerItems(QMenu* theMenu) const
235 {
236   bool aIsDone = false;
237   ModuleBase_IModule* aModule = myWorkshop->module();
238   if (aModule) 
239     aIsDone = aModule->addViewerItems(theMenu, myActions);
240
241   if (!aIsDone) {
242     XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
243     QObjectPtrList aObjects = aSelMgr->selection()->selectedObjects();
244     if (aObjects.size() > 0) {
245       //if (aObjects.size() == 1)
246       //  theMenu->addAction(action("EDIT_CMD"));
247       bool isVisible = false;
248       bool isShading = false;
249       bool canBeShaded = false;
250       foreach(ObjectPtr aObject, aObjects)
251       {
252         ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObject);
253         if (aRes && myWorkshop->displayer()->isVisible(aRes)) {
254           isVisible = true;
255           canBeShaded = myWorkshop->displayer()->canBeShaded(aObject);
256           isShading = (myWorkshop->displayer()->displayMode(aObject) == XGUI_Displayer::Shading);      
257           break;
258         }
259       }
260       if (isVisible) {
261         if (canBeShaded) {
262           if (isShading)
263             theMenu->addAction(action("WIREFRAME_CMD"));
264           else
265             theMenu->addAction(action("SHADING_CMD"));
266         }
267         theMenu->addSeparator();
268         theMenu->addAction(action("SHOW_ONLY_CMD"));
269         theMenu->addAction(action("HIDE_CMD"));
270       } else
271         theMenu->addAction(action("SHOW_CMD"));
272       //theMenu->addAction(action("DELETE_CMD"));
273     }
274     if (myWorkshop->displayer()->objectsCount() > 0)
275       theMenu->addAction(action("HIDEALL_CMD"));
276     if (myWorkshop->canChangeColor())
277       theMenu->addAction(action("COLOR_CMD"));
278   }
279   if (!myWorkshop->isSalomeMode()) {
280     theMenu->addSeparator();
281     QMdiArea* aMDI = myWorkshop->mainWindow()->mdiArea();
282     if (aMDI->actions().size() > 0) {
283       QMenu* aSubMenu = theMenu->addMenu(tr("Windows"));
284       aSubMenu->addActions(aMDI->actions());
285     }
286   }
287
288 }
289
290 void XGUI_ContextMenuMgr::connectObjectBrowser() const
291 {
292   connect(myWorkshop->objectBrowser(), SIGNAL(contextMenuRequested(QContextMenuEvent*)), this,
293           SLOT(onContextMenuRequest(QContextMenuEvent*)));
294 }
295
296 void XGUI_ContextMenuMgr::connectViewer() const
297 {
298   connect(myWorkshop->viewer(), SIGNAL(contextMenuRequested(QContextMenuEvent*)), this,
299           SLOT(onContextMenuRequest(QContextMenuEvent*)));
300 }
301