Salome HOME
Porting to Qt4.
[modules/geom.git] / src / GEOMGUI / GEOMGUI_OCCSelector.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 #include "GEOMGUI_OCCSelector.h"
21
22 #include <LightApp_DataSubOwner.h>
23
24 #include <OCCViewer_ViewModel.h>
25
26 #include <AIS_ListOfInteractive.hxx>
27 #include <AIS_ListIteratorOfListOfInteractive.hxx>
28 #include <SelectMgr_EntityOwner.hxx>
29 #include <AIS_Shape.hxx>
30 #include <TopTools_IndexedMapOfShape.hxx>
31 #include <TopExp.hxx>
32 #include <SelectMgr_IndexedMapOfOwner.hxx>
33 #include <TColStd_ListIteratorOfListOfInteger.hxx>
34 #include <SelectMgr_Selection.hxx>
35 #include <SelectBasics_SensitiveEntity.hxx>
36 #include <StdSelect_BRepOwner.hxx>
37 #include <TColStd_IndexedMapOfInteger.hxx>
38 #include <NCollection_DataMap.hxx>
39
40 #include <SUIT_Session.h>
41 #include <SalomeApp_Study.h>
42
43
44 //================================================================
45 // Function : GEOMGUI_OCCSelector
46 // Purpose  : 
47 //================================================================
48 GEOMGUI_OCCSelector::GEOMGUI_OCCSelector( OCCViewer_Viewer* viewer, SUIT_SelectionMgr* mgr )
49 : LightApp_OCCSelector( viewer, mgr )
50 {
51 }
52
53 //================================================================
54 // Function : ~GEOMGUI_OCCSelector
55 // Purpose  : 
56 //================================================================
57 GEOMGUI_OCCSelector::~GEOMGUI_OCCSelector()
58 {
59 }
60
61 //================================================================
62 // Function : getSelection
63 // Purpose  : 
64 //================================================================
65 void GEOMGUI_OCCSelector::getSelection( SUIT_DataOwnerPtrList& aList ) const
66 {
67   OCCViewer_Viewer* vw = viewer();
68   if ( !vw )
69     return;
70
71   Handle(AIS_InteractiveContext) ic = vw->getAISContext();
72   
73   if ( ic->HasOpenedContext() )
74     {
75       for ( ic->InitSelected(); ic->MoreSelected(); ic->NextSelected() )
76         {
77           Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(ic->SelectedOwner());
78           if ( anOwner.IsNull() )
79             continue;
80           
81           Handle(AIS_InteractiveObject) io = Handle(AIS_InteractiveObject)::DownCast( anOwner->Selectable() );
82           
83           QString entryStr = entry( io );
84           int index = -1; 
85           
86           if ( anOwner->ComesFromDecomposition() ) // == Local Selection
87             {
88               TopoDS_Shape subShape = anOwner->Shape();
89               Handle(AIS_Shape) aisShape = Handle(AIS_Shape)::DownCast( io );
90               if ( !aisShape.IsNull() )
91                 {
92                   TopoDS_Shape bigShape = aisShape->Shape();
93                   
94                   TopTools_IndexedMapOfShape subShapes;
95                   TopExp::MapShapes( bigShape, subShapes );
96                   index = subShapes.FindIndex( subShape );
97                 }
98             }
99           
100           if ( !entryStr.isEmpty() )
101             {
102               LightApp_DataOwner* owner;
103               if ( index > -1 ) // Local Selection
104                 owner = new LightApp_DataSubOwner( entryStr, index );
105               else // Global Selection
106                 owner = new LightApp_DataOwner( entryStr );
107
108               aList.append( SUIT_DataOwnerPtr( owner ) );
109             }
110         }
111     }
112   else
113     {
114       for ( ic->InitCurrent(); ic->MoreCurrent(); ic->NextCurrent() )
115         {
116           Handle(AIS_InteractiveObject) io = ic->Current();
117           
118           QString entryStr = entry( io );
119           
120           if ( !entryStr.isEmpty() )
121             {
122               LightApp_DataOwner* owner = new LightApp_DataOwner( entryStr );
123               aList.append( SUIT_DataOwnerPtr( owner ) );
124             }
125         }
126     }
127   // add externally selected objects
128   SUIT_DataOwnerPtrList::const_iterator anExtIter;
129   for(anExtIter = mySelectedExternals.begin(); anExtIter != mySelectedExternals.end(); anExtIter++) {
130     aList.append(*anExtIter);
131   }
132   
133 }
134
135 //================================================================
136 // Function : getEntityOwners
137 // Purpose  : 
138 //================================================================
139 static void getEntityOwners( const Handle(AIS_InteractiveObject)& theObj,
140                              const Handle(AIS_InteractiveContext)& theIC,
141                              SelectMgr_IndexedMapOfOwner& theMap )
142 {
143   if ( theObj.IsNull() || theIC.IsNull() )
144     return;
145
146   TColStd_ListOfInteger modes;
147   theIC->ActivatedModes( theObj, modes );
148
149   TColStd_ListIteratorOfListOfInteger itr( modes );
150   for (; itr.More(); itr.Next() ) {
151     int m = itr.Value();
152     if ( !theObj->HasSelection( m ) )
153       continue;
154
155     Handle(SelectMgr_Selection) sel = theObj->Selection( m );
156
157     for ( sel->Init(); sel->More(); sel->Next() ) {
158       Handle(SelectBasics_SensitiveEntity) entity = sel->Sensitive();
159       if ( entity.IsNull() )
160         continue;
161
162       Handle(SelectMgr_EntityOwner) owner =
163         Handle(SelectMgr_EntityOwner)::DownCast(entity->OwnerId());
164       if ( !owner.IsNull() )
165         theMap.Add( owner );
166     }
167   }
168 }
169
170 //================================================================
171 // Function : setSelection
172 // Purpose  : 
173 //================================================================
174 void GEOMGUI_OCCSelector::setSelection( const SUIT_DataOwnerPtrList& aList )
175 {
176   OCCViewer_Viewer* vw = viewer();
177   if ( !vw )
178     return;
179
180   Handle(AIS_InteractiveContext) ic = vw->getAISContext();
181
182   NCollection_DataMap<TCollection_AsciiString, TColStd_IndexedMapOfInteger> indexesMap; // "entry - list_of_int" map for LOCAL selection
183   QMap<QString,int> globalSelMap; // only Key=entry from this map is used.  value(int) is NOT used at all.
184   SelectMgr_IndexedMapOfOwner ownersmap; // map of owners to be selected
185   
186   AIS_ListOfInteractive aDispList;
187   ic->DisplayedObjects( aDispList );
188
189   // build a map of data owner indexes to be selected.
190   // "entry - to - list_of_ids" map
191   for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr )
192   {
193     const LightApp_DataSubOwner* subOwner = dynamic_cast<const LightApp_DataSubOwner*>( (*itr).operator->() );
194     if ( subOwner )
195     {
196       QString entry = subOwner->entry();
197 #ifndef WNT
198       if ( indexesMap.IsBound( TCollection_AsciiString(entry.toLatin1().data())))
199 #else
200           if ( indexesMap.IsBound( (char*)entry.toLatin1()))
201 #endif
202       {
203         TColStd_IndexedMapOfInteger& subIndexes = indexesMap.ChangeFind(entry.toLatin1().data());
204         subIndexes.Add( subOwner->index() );
205         //indexesMap.replace( entry, subIndexes );
206       }
207       else
208       {
209         TColStd_IndexedMapOfInteger subIndexes;
210         subIndexes.Add( subOwner->index() );
211         indexesMap.Bind(entry.toLatin1().data(), subIndexes);
212       }
213     } 
214     else // the owner is NOT a sub owner, maybe it is a DataOwner == GLOBAL selection
215     {
216       const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>( (*itr).operator->() );
217       if ( owner )
218       {
219         SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
220         QString anEntry = appStudy->referencedToEntry( owner->entry() );
221         
222         globalSelMap[anEntry] = 1;
223       }
224     }
225   }
226
227   // get all owners.  Fill "entry - list_of_owners" map.
228   for ( AIS_ListIteratorOfListOfInteractive it( aDispList ); it.More(); it.Next() )
229   {
230     Handle(AIS_InteractiveObject) io = it.Value();
231     QString entryStr = entry( io );
232     if ( !entryStr.isEmpty() )
233     {
234       //EntryToListOfOwnerMap entryOwnersMap; // "entry - list_of_owners" map.  temporary use.
235       SelectMgr_IndexedMapOfOwner owners;
236       getEntityOwners( io, ic, owners ); // get all owners
237
238       for  ( int i = 1, n = owners.Extent(); i <= n; i++ ) 
239       {
240
241         Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(owners( i ));
242
243         if ( anOwner.IsNull() || !anOwner->HasShape() )
244           continue;
245
246         // GLOBAL selection
247         if ( !anOwner->ComesFromDecomposition() && globalSelMap.contains( entryStr ) ) 
248         {
249           ownersmap.Add( anOwner );
250           globalSelMap[entryStr]++;
251         }
252         // LOCAL selection
253         else
254         {
255           Handle(AIS_Shape) aisShape = Handle(AIS_Shape)::DownCast( io );
256
257           if ( !aisShape.IsNull() && indexesMap.IsBound( entryStr.toLatin1().data() ) )
258           {
259             TopoDS_Shape shape = aisShape->Shape();
260             TopTools_IndexedMapOfShape aMapOfShapes;
261             TopExp::MapShapes( shape, aMapOfShapes );
262             const TColStd_IndexedMapOfInteger& subIndexes = indexesMap.ChangeFind(entryStr.toLatin1().data());
263
264             const TopoDS_Shape& aSubShape = anOwner->Shape();
265             int  aSubShapeId = aMapOfShapes.FindIndex( aSubShape );
266
267             // check if the "sub_shape_index" is found in the "map of indexes for this entry",
268             // which was passes in the parameter
269             if ( subIndexes.Contains( aSubShapeId ) )
270             {
271               ownersmap.Add( anOwner );
272             }
273           }
274         } // end of local selection
275       } // end of for(owners)
276     }// end of if(entry)
277   }// end of for(AIS_all_ios)
278
279   vw->unHighlightAll( false );
280
281   // DO the selection
282   for  ( int i = 1, n = ownersmap.Extent(); i <= n; i++ ) 
283   {
284     Handle(SelectMgr_EntityOwner) owner = ownersmap( i );
285     if ( owner->State() )
286       continue;
287
288     if ( ic->HasOpenedContext() )
289       ic->AddOrRemoveSelected( owner, false );
290     else
291       ic->AddOrRemoveSelected( Handle(AIS_InteractiveObject)::DownCast(owner->Selectable()), false );
292   }
293
294   vw->update();
295   
296   // fill extra selected
297   mySelectedExternals.clear();
298   for ( SUIT_DataOwnerPtrList::const_iterator itr2 = aList.begin(); itr2 != aList.end(); ++itr2 ) {
299     const LightApp_DataSubOwner* subOwner = dynamic_cast<const LightApp_DataSubOwner*>( (*itr2).operator->() );
300     if ( !subOwner )
301     {
302       const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>( (*itr2).operator->() );
303       if ( owner )
304       {
305         SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
306         QString anEntry = appStudy->referencedToEntry( owner->entry() );
307         if (globalSelMap[anEntry] == 1) mySelectedExternals.append(*itr2);
308       }
309     }
310   }
311 }