Salome HOME
Introduce a SALOME_IntaractiveObject attribute
[modules/gui.git] / src / SVTK / SVTK_Selector.cxx
1 //  SALOME SALOMEGUI : implementation of desktop and GUI kernel
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SALOME_Selection.cxx
25 //  Author : Nicolas REJNERI
26 //  Module : SALOME
27 //  $Header$
28
29
30 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
31 #include <TColStd_IndexedMapOfInteger.hxx>
32
33
34 #include "SALOME_Actor.h"
35 #include "SVTK_ViewModel.h"
36 #include "SVTK_ViewWindow.h"
37 #include "SALOME_ListIteratorOfListIO.hxx"
38
39 #include "SVTK_Selector.h"
40 #include "utilities.h"
41
42 SVTK_Selector
43 ::SVTK_Selector()
44 {
45 }
46
47 SVTK_Selector
48 ::~SVTK_Selector()
49 {
50 }
51
52 void 
53 SVTK_Selector
54 ::SetSelectionMode(Selection_Mode theMode)
55 {
56   mySelectionMode = theMode;
57 }
58
59 void 
60 SVTK_Selector
61 ::ClearIObjects() 
62 {
63   myIO2Actors.Clear();
64   myIObjects.Clear();
65   myMapIOSubIndex.Clear();
66 }
67
68 //----------------------------------------------------------------------------
69 bool
70 SVTK_Selector
71 ::IsSelected(const Handle(SALOME_InteractiveObject)& theObject) const
72 {
73   SALOME_ListIteratorOfListIO anIter(myIObjects);
74   for(; anIter.More(); anIter.Next()){
75     if(theObject->isSame(anIter.Value())){
76       return true;
77     }
78   }
79   return false;
80 }
81
82 bool
83 SVTK_Selector
84 ::IsSelected(SALOME_Actor* theActor) const
85 {
86   const Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
87   return IsSelected(anIO) && myIO2Actors.IsBound(anIO);
88 }
89
90 SALOME_Actor*
91 SVTK_Selector
92 ::GetActor(const Handle(SALOME_InteractiveObject)& theIO) const
93 {
94   if(myIO2Actors.IsBound(theIO))
95     return myIO2Actors.Find(theIO).GetPointer();
96   return NULL;
97 }
98
99 //----------------------------------------------------------------------------
100 bool 
101 SVTK_Selector
102 ::AddIObject(const Handle(SALOME_InteractiveObject)& theIO) 
103 {
104   if(!IsSelected(theIO)){
105     myIObjects.Append(theIO);
106     return true;
107   }
108   return false;
109 }
110
111 bool 
112 SVTK_Selector
113 ::AddIObject(SALOME_Actor* theActor) 
114 {
115   const Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
116
117   bool anIsIOBound = IsSelected(anIO);
118   if(!anIsIOBound)
119     myIObjects.Append(anIO);
120
121   bool anIsActorBound = myIO2Actors.IsBound(anIO);
122   if(!anIsActorBound)
123     myIO2Actors.Bind(anIO,theActor);
124   
125   return !anIsIOBound || !anIsActorBound;
126 }
127
128 //----------------------------------------------------------------------------
129 bool 
130 SVTK_Selector
131 ::RemoveIObject(const Handle(SALOME_InteractiveObject)& theIO) 
132 {
133   bool anIsIOBound = false;
134   for(SALOME_ListIteratorOfListIO anIter(myIObjects); anIter.More(); anIter.Next()){
135     if(theIO->isSame(anIter.Value())){
136       if(myMapIOSubIndex.IsBound(theIO))
137         myMapIOSubIndex.UnBind(theIO);
138       myIObjects.Remove(anIter);
139       anIsIOBound = true; 
140     }
141   }
142
143   bool anIsActorBound = myIO2Actors.IsBound(theIO);
144   if(anIsActorBound)
145     myIO2Actors.UnBind(theIO);
146
147   return anIsIOBound || anIsActorBound;
148 }
149
150 bool 
151 SVTK_Selector
152 ::RemoveIObject(SALOME_Actor* theActor) 
153 {
154   const Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
155
156   bool anIsActorBound = myIO2Actors.IsBound(anIO);
157   if(anIsActorBound)
158     myIO2Actors.UnBind(anIO);
159
160   bool anIsIOBound = false;
161   for(SALOME_ListIteratorOfListIO anIter(myIObjects); anIter.More(); anIter.Next()){
162     if(anIO->isSame(anIter.Value())){
163       if(myMapIOSubIndex.IsBound(anIO))
164         myMapIOSubIndex.UnBind(anIO);
165       myIObjects.Remove(anIter);
166       anIsIOBound = true; 
167     }
168   }
169
170   return anIsIOBound || anIsActorBound;
171 }
172
173 //----------------------------------------------------------------------------
174 const SALOME_ListIO& 
175 SVTK_Selector
176 ::StoredIObjects() const
177 {
178   return myIObjects;
179 }
180
181 int
182 SVTK_Selector
183 ::IObjectCount() const
184 {
185   return myIObjects.Extent();
186 }
187
188 bool 
189 SVTK_Selector
190 ::HasIndex( const Handle(SALOME_InteractiveObject)& theIO) const
191 {
192   return myMapIOSubIndex.IsBound(theIO);
193 }
194
195 void 
196 SVTK_Selector
197 ::GetIndex( const Handle(SALOME_InteractiveObject)& theIO, 
198             TColStd_IndexedMapOfInteger& theIndex)
199 {
200   if(myMapIOSubIndex.IsBound(theIO))
201     theIndex = myMapIOSubIndex.Find(theIO);
202   else
203     theIndex.Clear();
204 }
205
206 bool
207 SVTK_Selector
208 ::IsIndexSelected(const Handle(SALOME_InteractiveObject)& theIO, 
209                   int theIndex) const
210 {
211   if( !myMapIOSubIndex.IsBound(theIO))
212     return false;
213
214   const TColStd_IndexedMapOfInteger& aMapIndex = myMapIOSubIndex.Find(theIO);
215   return aMapIndex.Contains(theIndex);
216 }
217
218 static 
219 bool
220 removeIndex(TColStd_IndexedMapOfInteger& theMapIndex,
221             const int theIndex)
222 {
223   int anId = theMapIndex.FindIndex(theIndex); // i==0 if Index is not in the MapIndex
224   if(anId){
225     // only the last key can be removed
226     int aLastId = theMapIndex.FindKey(theMapIndex.Extent());
227     if(aLastId == anId)
228       theMapIndex.RemoveLast();
229     else{
230       TColStd_IndexedMapOfInteger aNewMap;
231       aNewMap.ReSize(theMapIndex.Extent()-1);
232       for(int j = 1; j <= theMapIndex.Extent(); j++){
233         int anIndex = theMapIndex(j);
234         if ( anIndex != theIndex )
235           aNewMap.Add( anIndex );
236       }
237       theMapIndex = aNewMap;
238     }
239   }
240   return anId;
241 }
242
243
244 bool
245 SVTK_Selector
246 ::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& theIO, 
247                     const TColStd_IndexedMapOfInteger& theIndices, 
248                     bool theIsModeShift)
249 {
250   TColStd_IndexedMapOfInteger empty;
251   if(!myMapIOSubIndex.IsBound(theIO))
252     myMapIOSubIndex.Bind(theIO, empty);
253
254   TColStd_IndexedMapOfInteger& aMapIndex = myMapIOSubIndex.ChangeFind(theIO);
255   aMapIndex = theIndices;
256
257   if(!theIsModeShift)
258     aMapIndex.Clear();
259   
260   if(aMapIndex.IsEmpty()){
261     myMapIOSubIndex.UnBind(theIO);
262     RemoveIObject(theIO);
263   }
264
265   return !aMapIndex.IsEmpty();
266 }
267
268
269 bool
270 SVTK_Selector
271 ::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& theIO, 
272                     const TColStd_MapOfInteger& theIndices, 
273                     bool theIsModeShift)
274 {
275   TColStd_IndexedMapOfInteger empty;    
276   if(!myMapIOSubIndex.IsBound(theIO))
277     myMapIOSubIndex.Bind(theIO, empty);
278
279   TColStd_IndexedMapOfInteger& aMapIndex = myMapIOSubIndex.ChangeFind(theIO);
280
281   if(!theIsModeShift)
282     aMapIndex.Clear();
283   
284   for(TColStd_MapIteratorOfMapOfInteger anIter(theIndices); anIter.More(); anIter.Next())
285     aMapIndex.Add(anIter.Key());
286   
287   if(aMapIndex.IsEmpty()){
288     myMapIOSubIndex.UnBind(theIO);
289     RemoveIObject(theIO);
290   }
291
292   return !aMapIndex.IsEmpty();
293 }
294
295
296 bool 
297 SVTK_Selector
298 ::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& theIO, 
299                     int theIndex, 
300                     bool theIsModeShift)
301 {
302   TColStd_IndexedMapOfInteger empty;            
303   if(!myMapIOSubIndex.IsBound(theIO))
304     myMapIOSubIndex.Bind(theIO, empty);
305   
306   TColStd_IndexedMapOfInteger& aMapIndex = myMapIOSubIndex.ChangeFind(theIO);
307
308   bool anIsConatains = aMapIndex.Contains( theIndex );
309
310   if (anIsConatains)
311     removeIndex( aMapIndex, theIndex );
312   
313   if (!theIsModeShift)
314     aMapIndex.Clear();
315   
316   if(!anIsConatains)
317     aMapIndex.Add( theIndex );
318
319   if ( aMapIndex.IsEmpty() ) {
320     myMapIOSubIndex.UnBind(theIO);
321     RemoveIObject(theIO);
322   }
323
324   return false;
325 }
326
327
328 void
329 SVTK_Selector
330 ::RemoveIndex( const Handle(SALOME_InteractiveObject)& theIO, 
331                int theIndex)
332 {
333   if ( myMapIOSubIndex.IsBound( theIO ) ) {
334     TColStd_IndexedMapOfInteger& aMapIndex = myMapIOSubIndex.ChangeFind( theIO );
335     removeIndex( aMapIndex, theIndex );
336   }
337 }
338
339 void 
340 SVTK_Selector
341 ::ClearIndex()
342 {
343   myMapIOSubIndex.Clear();  
344 }