Salome HOME
Merge branch 'Dev_GroupsRevision'
[modules/shaper.git] / src / XGUI / XGUI_SelectionMgr.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_SelectionMgr.h"
22
23 #include "XGUI_Workshop.h"
24 #include "XGUI_ObjectsBrowser.h"
25 #include "XGUI_SalomeConnector.h"
26 #include "XGUI_ViewerProxy.h"
27 #include "XGUI_Displayer.h"
28 #include "XGUI_Selection.h"
29 #include "XGUI_OperationMgr.h"
30
31 #ifndef HAVE_SALOME
32 #include <AppElements_MainWindow.h>
33 #endif
34
35 #include <ModelAPI_Feature.h>
36 #include <ModelAPI_Session.h>
37 #include <ModelAPI_AttributeDocRef.h>
38 #include <ModelAPI_Data.h>
39 #include <ModelAPI_Result.h>
40 #include <ModelAPI_Object.h>
41 #include <ModelAPI_ResultCompSolid.h>
42
43 #include <ModuleBase_ViewerPrs.h>
44 #include <ModuleBase_Tools.h>
45
46 #include <SelectMgr_ListIteratorOfListOfFilter.hxx>
47
48 #ifdef TINSPECTOR
49 #include <inspector/VInspectorAPI_CallBack.hxx>
50 #endif
51
52 XGUI_SelectionMgr::XGUI_SelectionMgr(XGUI_Workshop* theParent)
53     : QObject(theParent),
54       myWorkshop(theParent)
55 {
56   mySelection = new XGUI_Selection(myWorkshop);
57 }
58
59 XGUI_SelectionMgr::~XGUI_SelectionMgr()
60 {
61   delete mySelection;
62 }
63
64 //**************************************************************
65 void XGUI_SelectionMgr::connectViewers()
66 {
67   connect(myWorkshop->objectBrowser(), SIGNAL(selectionChanged()), this,
68           SLOT(onObjectBrowserSelection()));
69
70   //Connect to other viewers
71   connect(myWorkshop->viewer(), SIGNAL(selectionChanged()), this, SLOT(onViewerSelection()));
72 }
73
74 //**************************************************************
75 void XGUI_SelectionMgr::setSelectedOwners(const SelectMgr_IndexedMapOfOwner& theSelectedOwners,
76                                           bool isUpdateViewer)
77 {
78   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
79   if (!aContext.IsNull()) {
80     /// previous selection should be cleared, else there will be decomposition of selections:
81     /// as AddOrRemoveSelected inverts current selection
82     aContext->ClearSelected(false);
83
84     for  (Standard_Integer i = 1, n = theSelectedOwners.Extent(); i <= n; i++)  {
85       Handle(SelectMgr_EntityOwner) anOwner = theSelectedOwners(i);
86
87       aContext->AddOrRemoveSelected(anOwner, isUpdateViewer);
88       #ifdef TINSPECTOR
89       if (myWorkshop->displayer()->getCallBack())
90         myWorkshop->displayer()->getCallBack()->AddOrRemoveSelected(anOwner);
91       #endif
92     }
93   }
94 }
95
96 //**************************************************************
97 void XGUI_SelectionMgr::onObjectBrowserSelection()
98 {
99   QList<ModuleBase_ViewerPrsPtr> aSelectedPrs =
100              myWorkshop->selector()->selection()->getSelected(ModuleBase_ISelection::Browser);
101
102   QList<ModuleBase_ViewerPrsPtr> aTmpList = aSelectedPrs;
103   ObjectPtr aObject;
104   FeaturePtr aFeature;
105   foreach(ModuleBase_ViewerPrsPtr aPrs, aTmpList) {
106     aObject = aPrs->object();
107     if (aObject.get()) {
108       aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObject);
109       if (aFeature.get()) {
110         const std::list<std::shared_ptr<ModelAPI_Result>> aResList = aFeature->results();
111         ResultPtr aResult;
112         ResultCompSolidPtr aCompSolid;
113         std::list<ResultPtr>::const_iterator aIt;
114         for (aIt = aResList.cbegin(); aIt != aResList.cend(); ++aIt) {
115           aResult = (*aIt);
116           aSelectedPrs.append(std::shared_ptr<ModuleBase_ViewerPrs>(
117             new ModuleBase_ViewerPrs(aResult, GeomShapePtr(), NULL)));
118           aCompSolid = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aResult);
119           if (aCompSolid.get()) {
120             for (int i = 0; i < aCompSolid->numberOfSubs(); i++) {
121               ResultBodyPtr aResult = aCompSolid->subResult(i);
122               aSelectedPrs.append(std::shared_ptr<ModuleBase_ViewerPrs>(
123                 new ModuleBase_ViewerPrs(aResult, aResult->shape(), NULL)));
124             }
125           }
126         }
127       }
128     }
129   }
130   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
131   aDisplayer->setSelected(aSelectedPrs);
132   emit selectionChanged();
133 }
134
135 //**************************************************************
136 void XGUI_SelectionMgr::onViewerSelection()
137 {
138   QList<ModuleBase_ViewerPrsPtr> aValues;
139   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
140   if (!aContext.IsNull())
141     aValues = selection()->getSelected(ModuleBase_ISelection::Viewer);
142
143   QObjectPtrList anObjects;
144   convertToObjectBrowserSelection(aValues, anObjects);
145
146   bool aBlocked = myWorkshop->objectBrowser()->blockSignals(true);
147   myWorkshop->objectBrowser()->setObjectsSelected(anObjects);
148   myWorkshop->objectBrowser()->blockSignals(aBlocked);
149
150   emit selectionChanged();
151 }
152
153 //**************************************************************
154 void XGUI_SelectionMgr::deselectPresentation(const Handle(AIS_InteractiveObject) theObject)
155 {
156   NCollection_List<Handle(SelectBasics_EntityOwner)> aResultOwners;
157
158   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
159   for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected()) {
160     Handle(SelectMgr_EntityOwner) anOwner = aContext->SelectedOwner();
161     if (anOwner.IsNull()) // TODO: check why it is possible
162       continue;
163     if (anOwner->Selectable() == theObject && anOwner->IsSelected())
164       aResultOwners.Append(anOwner);
165   }
166   NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (aResultOwners);
167   Handle(SelectMgr_EntityOwner) anOwner;
168   for (; anOwnersIt.More(); anOwnersIt.Next()) {
169     anOwner = Handle(SelectMgr_EntityOwner)::DownCast(anOwnersIt.Value());
170     if (!anOwner.IsNull())
171       aContext->AddOrRemoveSelected(anOwner, false);
172   }
173 }
174
175 //**************************************************************
176 void XGUI_SelectionMgr::updateSelectionBy(const ModuleBase_ISelection::SelectionPlace& thePlace)
177 {
178   QList<ModuleBase_ViewerPrsPtr> aSelectedPrs =
179                myWorkshop->selector()->selection()->getSelected(thePlace);
180   if (thePlace == ModuleBase_ISelection::Browser) {
181     XGUI_Displayer* aDisplayer = myWorkshop->displayer();
182     aDisplayer->setSelected(aSelectedPrs);
183   }
184
185 }
186 //**************************************************************
187 void XGUI_SelectionMgr::clearSelection()
188 {
189   QObjectPtrList aFeatures;
190   bool aBlocked = myWorkshop->objectBrowser()->blockSignals(true);
191   myWorkshop->objectBrowser()->setObjectsSelected(aFeatures);
192   myWorkshop->objectBrowser()->blockSignals(aBlocked);
193
194   QList<ModuleBase_ViewerPrsPtr> aSelectedPrs =
195              myWorkshop->selector()->selection()->getSelected(ModuleBase_ISelection::Browser);
196
197   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
198   aDisplayer->setSelected(aSelectedPrs);
199
200   emit selectionChanged();
201 }
202 //**************************************************************
203 void XGUI_SelectionMgr::setSelected(const QList<ModuleBase_ViewerPrsPtr>& theValues)
204 {
205   // update selection in Viewer
206   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
207   aDisplayer->setSelected(theValues);
208
209   // update selection in Object Browser
210   bool aBlocked = myWorkshop->objectBrowser()->blockSignals(true);
211   QObjectPtrList anObjects;
212   convertToObjectBrowserSelection(theValues, anObjects);
213
214   myWorkshop->objectBrowser()->setObjectsSelected(anObjects);
215   myWorkshop->objectBrowser()->blockSignals(aBlocked);
216 }
217 //**************************************************************
218 void XGUI_SelectionMgr::convertToObjectBrowserSelection(
219                                    const QList<ModuleBase_ViewerPrsPtr>& theValues,
220                                    QObjectPtrList& theObjects)
221 {
222   theObjects.clear();
223
224   ResultPtr aResult;
225   FeaturePtr aFeature;
226   bool aHasOperation = (myWorkshop->operationMgr()->currentOperation() != 0);
227   SessionPtr aMgr = ModelAPI_Session::get();
228   DocumentPtr anActiveDocument = aMgr->activeDocument();
229
230   foreach(ModuleBase_ViewerPrsPtr aPrs, theValues) {
231     if (aPrs->object().get()) {
232       if (!theObjects.contains(aPrs->object()))
233         theObjects.append(aPrs->object());
234       if (aPrs->shape().get() && (!aHasOperation)) {
235         aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aPrs->object());
236         if (aResult.get()) {
237           aFeature = anActiveDocument->producedByFeature(aResult, aPrs->shape());
238           if (aFeature.get() && (!theObjects.contains(aFeature)))
239             theObjects.append(aFeature);
240         }
241       }
242     }
243   }
244 }
245
246 std::list<FeaturePtr> XGUI_SelectionMgr::getSelectedFeatures()
247 {
248   std::list<FeaturePtr> aFeatures;
249   QObjectPtrList aObjects = selection()->selectedObjects();
250   if (aObjects.isEmpty())
251     return aFeatures;
252
253   bool isPart = false;
254   foreach(ObjectPtr aObj, aObjects) {
255     FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
256     if (aFeature.get()) {
257       ResultPtr aRes = aFeature->firstResult();
258       isPart = (aRes.get() && (aRes->groupName() == ModelAPI_ResultPart::group()));
259       if (!isPart)
260         aFeatures.push_back(aFeature);
261     }
262   }
263   return aFeatures;
264 }