Salome HOME
PAL9951 - selection with SHIFT key works incorrectly
[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
38 #include "SVTK_SelectorDef.h"
39 #include "utilities.h"
40
41 SVTK_SelectorDef
42 ::SVTK_SelectorDef()
43 {
44 }
45
46 SVTK_SelectorDef
47 ::~SVTK_SelectorDef()
48 {
49 }
50
51 void 
52 SVTK_SelectorDef
53 ::SetSelectionMode(Selection_Mode theMode)
54 {
55   mySelectionMode = theMode;
56 }
57
58 void 
59 SVTK_SelectorDef
60 ::ClearIObjects() 
61 {
62   myIO2Actors.clear();
63   myIObjects.clear();
64   myMapIOSubIndex.clear();
65 }
66
67 //----------------------------------------------------------------------------
68 bool
69 SVTK_SelectorDef
70 ::IsSelected(const Handle(SALOME_InteractiveObject)& theIO) const
71 {
72   return myIObjects.find(theIO) != myIObjects.end();
73 }
74
75 bool
76 SVTK_SelectorDef
77 ::IsSelected(SALOME_Actor* theActor) const
78 {
79   const Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
80   return IsSelected(anIO) && myIO2Actors.find(anIO) != myIO2Actors.end();
81 }
82
83 SALOME_Actor*
84 SVTK_SelectorDef
85 ::GetActor(const Handle(SALOME_InteractiveObject)& theIO) const
86 {
87   TIO2Actors::const_iterator anIter = myIO2Actors.find(theIO);
88   if(anIter != myIO2Actors.end())
89     return anIter->second.GetPointer();
90   return NULL;
91 }
92
93 //----------------------------------------------------------------------------
94 bool 
95 SVTK_SelectorDef
96 ::AddIObject(const Handle(SALOME_InteractiveObject)& theIO) 
97 {
98   if(!IsSelected(theIO)){
99     myIObjects.insert(theIO);
100     return true;
101   }
102   return false;
103 }
104
105 bool 
106 SVTK_SelectorDef
107 ::AddIObject(SALOME_Actor* theActor) 
108 {
109   const Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
110
111   bool anIsIOBound = IsSelected(anIO);
112   if(!anIsIOBound)
113     myIObjects.insert(anIO);
114
115   bool anIsActorBound = myIO2Actors.find(anIO) != myIO2Actors.end();
116   if(!anIsActorBound)
117     myIO2Actors[anIO] = theActor;
118   
119   return !anIsIOBound || !anIsActorBound;
120 }
121
122 //----------------------------------------------------------------------------
123 bool 
124 SVTK_SelectorDef
125 ::RemoveIObject(const Handle(SALOME_InteractiveObject)& theIO) 
126 {
127   bool anIsIOBound = myIObjects.find(theIO) != myIObjects.end();
128
129   myIObjects.erase(theIO);
130   myIO2Actors.erase(theIO);
131   myMapIOSubIndex.erase(theIO);
132
133   return anIsIOBound;
134 }
135
136 bool 
137 SVTK_SelectorDef
138 ::RemoveIObject(SALOME_Actor* theActor) 
139 {
140   const Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
141
142   bool anIsActorBound = myIO2Actors.find(anIO) != myIO2Actors.end();
143   if(anIsActorBound)
144     myIO2Actors.erase(anIO);
145
146   return RemoveIObject(anIO) || anIsActorBound;
147 }
148
149 //----------------------------------------------------------------------------
150 const SALOME_ListIO& 
151 SVTK_SelectorDef
152 ::StoredIObjects() const
153 {
154   myIObjectList.Clear();
155   TIObjects::const_iterator anIter = myIObjects.begin();
156   TIObjects::const_iterator anIterEnd = myIObjects.end();
157   for(; anIter != anIterEnd; anIter++)
158     myIObjectList.Append(*anIter);
159
160   return myIObjectList;
161 }
162
163 int
164 SVTK_SelectorDef
165 ::IObjectCount() const
166 {
167   return myIObjects.size();
168 }
169
170 bool 
171 SVTK_SelectorDef
172 ::HasIndex( const Handle(SALOME_InteractiveObject)& theIO) const
173 {
174   return myMapIOSubIndex.find(theIO) != myMapIOSubIndex.end();
175 }
176
177 void 
178 SVTK_SelectorDef
179 ::GetIndex( const Handle(SALOME_InteractiveObject)& theIO, 
180             TColStd_IndexedMapOfInteger& theIndex)
181 {
182   TMapIOSubIndex::const_iterator anIter = myMapIOSubIndex.find(theIO);
183   if(anIter != myMapIOSubIndex.end())
184     theIndex = anIter->second.myMap;
185   else
186     theIndex.Clear();
187 }
188
189 bool
190 SVTK_SelectorDef
191 ::IsIndexSelected(const Handle(SALOME_InteractiveObject)& theIO, 
192                   int theIndex) const
193 {
194   TMapIOSubIndex::const_iterator anIter = myMapIOSubIndex.find(theIO);
195   if(anIter != myMapIOSubIndex.end()){
196     const TColStd_IndexedMapOfInteger& aMapIndex = anIter->second.myMap;
197     return aMapIndex.Contains(theIndex);
198   }
199
200   return false;
201 }
202
203 static 
204 bool
205 removeIndex(TColStd_IndexedMapOfInteger& theMapIndex,
206             const int theIndex)
207 {
208   int anId = theMapIndex.FindIndex(theIndex); // i==0 if Index is not in the MapIndex
209   if(anId){
210     // only the last key can be removed
211     int aLastId = theMapIndex.FindKey(theMapIndex.Extent());
212     if(aLastId == anId)
213       theMapIndex.RemoveLast();
214     else{
215       TColStd_IndexedMapOfInteger aNewMap;
216       aNewMap.ReSize(theMapIndex.Extent()-1);
217       for(int j = 1; j <= theMapIndex.Extent(); j++){
218         int anIndex = theMapIndex(j);
219         if ( anIndex != theIndex )
220           aNewMap.Add( anIndex );
221       }
222       theMapIndex = aNewMap;
223     }
224   }
225   return anId;
226 }
227
228
229 bool
230 SVTK_SelectorDef
231 ::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& theIO, 
232                     const TColStd_IndexedMapOfInteger& theIndices, 
233                     bool theIsModeShift)
234 {
235   TMapIOSubIndex::iterator aMapIter = myMapIOSubIndex.find(theIO);
236   if(aMapIter == myMapIOSubIndex.end()){
237     TIndexedMapOfInteger anEmpty;
238     aMapIter = myMapIOSubIndex.
239       insert(TMapIOSubIndex::value_type(theIO,anEmpty)).first;
240   }
241   TColStd_IndexedMapOfInteger& aMapIndex = aMapIter->second.myMap;
242
243   if(!theIsModeShift)
244     aMapIndex.Clear();
245   
246   for(int i = 1, iEnd = theIndices.Extent(); i <= iEnd; i++)
247     aMapIndex.Add(theIndices(i));
248   
249   if(aMapIndex.IsEmpty())
250     myMapIOSubIndex.erase(theIO);
251
252   return !aMapIndex.IsEmpty();
253 }
254
255
256 bool
257 SVTK_SelectorDef
258 ::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& theIO, 
259                     const TColStd_MapOfInteger& theIndices, 
260                     bool theIsModeShift)
261 {
262   TMapIOSubIndex::iterator aMapIter = myMapIOSubIndex.find(theIO);
263   if(aMapIter == myMapIOSubIndex.end()){
264     TIndexedMapOfInteger anEmpty;
265     aMapIter = myMapIOSubIndex.
266       insert(TMapIOSubIndex::value_type(theIO,anEmpty)).first;
267   }
268   TColStd_IndexedMapOfInteger& aMapIndex = aMapIter->second.myMap;
269
270   if(!theIsModeShift)
271     aMapIndex.Clear();
272   
273   TColStd_MapIteratorOfMapOfInteger anIter(theIndices);
274   for(; anIter.More(); anIter.Next())
275     aMapIndex.Add(anIter.Key());
276   
277   if(aMapIndex.IsEmpty())
278     myMapIOSubIndex.erase(theIO);
279
280   return !aMapIndex.IsEmpty();
281 }
282
283
284 bool 
285 SVTK_SelectorDef
286 ::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& theIO, 
287                     int theIndex, 
288                     bool theIsModeShift)
289 {
290   TMapIOSubIndex::iterator anIter = myMapIOSubIndex.find(theIO);
291   if(anIter == myMapIOSubIndex.end()){
292     TIndexedMapOfInteger anEmpty;
293     anIter = myMapIOSubIndex.
294       insert(TMapIOSubIndex::value_type(theIO,anEmpty)).first;
295   }
296   TColStd_IndexedMapOfInteger& aMapIndex = anIter->second.myMap;
297
298   bool anIsConatains = aMapIndex.Contains(theIndex);
299   if(anIsConatains)
300     removeIndex(aMapIndex,theIndex);
301   
302   if(!theIsModeShift)
303     aMapIndex.Clear();
304   
305   if(!anIsConatains)
306     aMapIndex.Add( theIndex );
307
308   if( aMapIndex.IsEmpty())
309     myMapIOSubIndex.erase(theIO);
310
311   return false;
312 }
313
314
315 void
316 SVTK_SelectorDef
317 ::RemoveIndex( const Handle(SALOME_InteractiveObject)& theIO, 
318                int theIndex)
319 {
320   if(IsIndexSelected(theIO,theIndex)){
321     TMapIOSubIndex::iterator anIter = myMapIOSubIndex.find(theIO);
322     TColStd_IndexedMapOfInteger& aMapIndex = anIter->second.myMap;
323     removeIndex(aMapIndex,theIndex);
324   }
325 }
326
327 void 
328 SVTK_SelectorDef
329 ::ClearIndex()
330 {
331   myMapIOSubIndex.clear();  
332 }