Salome HOME
PR: mergefrom_BSEC_br1_14Mar04
[modules/kernel.git] / src / SALOMEGUI / SALOME_Selection.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   \class SALOME_Selection SALOME_Selection.h
31   \brief Selection Mechanism of Interactive Object.
32 */
33
34 #include "SALOME_Selection.h"
35 #include "SALOME_Filter.hxx"
36 #include "SALOME_InteractiveObject.hxx"
37 #include "SALOME_ListIteratorOfListIO.hxx"
38 #include "SALOME_ListIteratorOfListOfFilter.hxx"
39
40 #include "QAD_Desktop.h"
41 #include "utilities.h"
42 using namespace std;
43
44 static QList<SALOME_Selection>&  SALOME_Sel_GetSelections()
45 {
46   static QList<SALOME_Selection> Selections;
47   return Selections;
48 }
49
50 //=======================================================================
51 //                       SELECTIONS MANAGEMENT
52 //=======================================================================
53
54 /*!
55   Constructor
56 */
57 SALOME_Selection::SALOME_Selection(const QString& aName) :
58   myName(aName)
59 {
60   myFilters.Clear();
61   myIObjects.Clear();
62   mySelectionMode = 4; /*Actor*/
63   mySelActiveCompOnly = false;
64   
65   QAD_Desktop* aDesktop = QAD_Application::getDesktop();
66   if (aDesktop) {
67     QAD_Application *anActiveApplication = aDesktop->getActiveApp();
68     if (anActiveApplication) QAD_ASSERT(connect(this, SIGNAL(currentSelectionChanged()),anActiveApplication, SLOT(updateActions())));
69   }
70 }
71
72 /*!
73   Destructor
74 */
75 SALOME_Selection::~SALOME_Selection()
76 {
77 }
78
79 /*!
80   Create a Selection with name \a aName
81   \return TRUE if the Selection is created. Returns FALSE otherwise. 
82 */
83 bool SALOME_Selection::CreateSelection(const QString& aName)
84
85   SALOME_Selection* S = NULL;
86   if ( SALOME_Selection::FindSelection( aName ) )
87     S = SALOME_Selection::Selection( aName );
88   else {
89     S = new SALOME_Selection(aName);
90     SALOME_Sel_GetSelections().prepend(S);
91   }
92   return true;
93 }
94
95
96 /*!
97   Sets the current Selection with \a aName
98 */
99 SALOME_Selection* SALOME_Selection::Selection(const QString& aName) 
100 {
101   SALOME_Selection* Sel = NULL;
102   if(SALOME_Sel_GetSelections().isEmpty()) return Sel;
103
104   for( Sel=SALOME_Sel_GetSelections().first(); Sel!=0; Sel=SALOME_Sel_GetSelections().next() ){
105     if( Sel->myName.compare(aName) == 0 ) 
106       return Sel;
107   }
108   
109   return Sel;
110 }
111
112 /*!
113   Finds Selection with \a aName
114   \return TRUE if the Selection is found. Returns FALSE otherwise. 
115 */
116 bool SALOME_Selection::FindSelection(const QString& aName) 
117 {
118   SALOME_Selection* Sel;
119   for( Sel=SALOME_Sel_GetSelections().first(); Sel!=0; Sel=SALOME_Sel_GetSelections().next() ){
120     if( Sel->myName.compare(aName) == 0 )
121       return true;
122   }
123
124   return false;
125 }
126
127 /*!
128   Removes Selection with \a aName
129   \return TRUE if the Selection is removed. Returns FALSE otherwise. 
130 */
131 bool SALOME_Selection::RemoveSelection(const QString& aName) 
132 {
133   SALOME_Selection* Sel;
134   for( Sel=SALOME_Sel_GetSelections().first(); Sel!=0; Sel=SALOME_Sel_GetSelections().next() ){
135     if( Sel->myName.compare(aName) == 0 )
136        return SALOME_Sel_GetSelections().remove(Sel);
137   }
138   return false;
139 }
140
141
142
143 //=======================================================================
144 //                                FILTERS MANAGEMENT
145 //=======================================================================
146
147 /*!
148   Adds Filter
149 */
150 void SALOME_Selection::AddFilter(const Handle(SALOME_Filter)& aFilter,
151                                  bool updateSelection) 
152 {
153   if ( !FindFilter(aFilter) ) {
154     myFilters.Append( aFilter );
155
156     SALOME_ListIO removedIObjects;
157
158     if ( updateSelection ) {
159       SALOME_ListIteratorOfListIO It(myIObjects);
160       for(;It.More();It.Next()){
161         Handle(SALOME_InteractiveObject) Object = It.Value();
162         if( !IsOk(Object) ) {
163           removedIObjects.Append( Object );
164           //      RemoveIObject( Object );
165         }
166       }
167       
168       SALOME_ListIteratorOfListIO It1(removedIObjects);
169       for(;It1.More();It1.Next()){
170         Handle(SALOME_InteractiveObject) Object = It1.Value();
171         RemoveIObject( Object );
172       }
173     }
174   }
175 }
176
177 /*!
178   Removes Filter
179 */
180 bool SALOME_Selection::RemoveFilter(const Handle(SALOME_Filter)& aFilter) 
181 {
182   SALOME_ListIteratorOfListOfFilter It(myFilters);
183   for(;It.More();It.Next()){
184     if (aFilter==It.Value()){ 
185       myFilters.Remove(It);
186       return true;
187     }
188   }
189   return false;
190 }
191
192 //! Clears All Filters
193 void SALOME_Selection::ClearFilters()
194 {
195   myFilters.Clear();
196 }
197
198 //! Finds aFilter 
199 bool SALOME_Selection::FindFilter(const Handle(SALOME_Filter)& aFilter) 
200 {
201   SALOME_ListIteratorOfListOfFilter It(myFilters);
202   for(;It.More();It.Next())
203     if (aFilter==It.Value()) 
204       return true;
205   return false;
206 }
207
208 //! Returns the list of stored Filters
209 const SALOME_ListOfFilter& SALOME_Selection::StoredFilters()
210 {
211   return myFilters;
212 }
213
214
215
216 //=======================================================================
217 //                     INTERACTIVE OBJECTS MANAGEMENT
218 //=======================================================================
219
220 void SALOME_Selection::Clear() 
221 {
222   myIObjects.Clear();
223 }
224
225 //! Clears all Interactive Objects
226 void SALOME_Selection::ClearIObjects() 
227 {
228   myIObjects.Clear();
229
230   QAD_Desktop*   myDesktop = (QAD_Desktop*) QAD_Application::getDesktop();
231   QAD_Study* myActiveStudy = myDesktop->getActiveStudy();
232   myActiveStudy->unHighlightAll();
233
234   myMapIOSubIndex.Clear();
235
236   emit currentSelectionChanged();
237 }
238
239 //! Add an InteractiveObject
240 int SALOME_Selection::AddIObject(const Handle(SALOME_InteractiveObject)& anObject, bool update) 
241 {
242   QAD_Desktop*   myDesktop = (QAD_Desktop*) QAD_Application::getDesktop();
243   QAD_Study* myActiveStudy = myDesktop->getActiveStudy();
244
245   if ( !IsOk(anObject) ) {
246     MESSAGE ( "The Object not authorized by Filters" )
247     myActiveStudy->highlight(anObject,false, update);
248     return -1;
249   }
250
251   bool Found = false;
252   SALOME_ListIteratorOfListIO It(myIObjects);
253   for(;It.More();It.Next()) {
254     if (anObject->isSame(It.Value())) {
255       Found = true;
256       break;
257     }
258   }
259
260   // Il n'est pas dedans, on le rajoute....
261   if(Found==false) {
262     myIObjects.Append( anObject );
263     myActiveStudy->highlight(anObject, true, update);
264     emit currentSelectionChanged();
265     return 1;
266   }
267   return 0;
268 }
269
270 //! Removes an InteractiveObject
271 int SALOME_Selection::RemoveIObject(const Handle(SALOME_InteractiveObject)& anObject, bool update) 
272 {
273   SALOME_ListIteratorOfListIO It(myIObjects);
274   for(;It.More();It.Next()) {
275     if (anObject->isSame(It.Value())) {
276       QAD_Desktop*   myDesktop = (QAD_Desktop*) QAD_Application::getDesktop();
277       QAD_Study* myActiveStudy = myDesktop->getActiveStudy();
278       myActiveStudy->highlight(anObject, false, update);
279
280       if ( myMapIOSubIndex.IsBound( anObject ) ) {
281         myMapIOSubIndex.UnBind( anObject );
282       }
283       
284       myIObjects.Remove(It);
285
286       emit currentSelectionChanged();
287       return 1; 
288     }
289   }
290   return 0;
291 }
292
293 //! Returns the list of InteractiveObjects
294 const SALOME_ListIO& SALOME_Selection::StoredIObjects()
295 {
296   return myIObjects;
297 }
298
299 //! Returns the number of InteractiveObjects in the selection. 
300 int SALOME_Selection::IObjectCount()
301 {
302   return myIObjects.Extent();
303 }
304
305 //!  Returns the first InteractiveObject in the selection.
306 Handle(SALOME_InteractiveObject) SALOME_Selection::firstIObject()
307 {
308   return myIObjects.First();
309 }
310
311 //! Returns the last InteractiveObject in the selection.
312 Handle(SALOME_InteractiveObject) SALOME_Selection::lastIObject()
313 {
314   return myIObjects.Last();
315 }
316
317 /*!
318   Returns TRUE if the InteractiveObject is authorized by Filters. Returns FALSE otherwise.
319 */
320 bool SALOME_Selection::IsOk(const Handle(SALOME_InteractiveObject)& anObj)
321 {
322   SALOME_ListIteratorOfListOfFilter It(myFilters);
323   for(;It.More();It.Next()){
324     Handle(SALOME_Filter) theFilter = It.Value();
325     if ( !theFilter->IsOk(anObj) ) 
326       return false;
327   }
328   return true;
329 }
330
331 void SALOME_Selection::SetSelectionMode(int mode, bool activeCompOnly)
332 {
333   mySelectionMode = mode;
334   mySelActiveCompOnly = activeCompOnly;
335 }
336
337 int SALOME_Selection::SelectionMode()
338 {
339   return mySelectionMode;
340 }
341
342 bool SALOME_Selection::IsSelectActiveCompOnly() const
343 {
344   return mySelActiveCompOnly;
345 }
346
347 bool SALOME_Selection::HasIndex( const Handle(SALOME_InteractiveObject)& IObject )
348 {
349   return myMapIOSubIndex.IsBound(IObject);
350 }
351
352 void SALOME_Selection::GetIndex( const Handle(SALOME_InteractiveObject)& IObject, TColStd_MapOfInteger& theIndex )
353 {
354   if ( myMapIOSubIndex.IsBound(IObject) ) {
355     theIndex = myMapIOSubIndex.Find(IObject);
356   }
357   else {
358     theIndex.Clear();
359   }
360 }
361
362
363
364 bool SALOME_Selection::IsIndexSelected(const Handle(SALOME_InteractiveObject)& IObject, int index)
365 {
366   if ( !myMapIOSubIndex.IsBound( IObject ) ) {
367     return false;
368   }
369   TColStd_MapOfInteger& MapIndex = myMapIOSubIndex.ChangeFind( IObject );
370   return MapIndex.Contains( index );
371 }
372
373
374
375
376 bool SALOME_Selection::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& IObject, 
377                                          int index, 
378                                          bool modeShift,
379                                          bool update)
380 {
381   MESSAGE ( " SALOME_Selection::AddOrRemoveIndex " << index << " - " << modeShift )
382   QAD_Desktop*   myDesktop = (QAD_Desktop*) QAD_Application::getDesktop();
383   QAD_Study* myActiveStudy = myDesktop->getActiveStudy();
384
385   if ( !myMapIOSubIndex.IsBound( IObject ) ) {
386     TColStd_MapOfInteger Empty;
387     myMapIOSubIndex.Bind( IObject, Empty );
388   }
389   TColStd_MapOfInteger& MapIndex = myMapIOSubIndex.ChangeFind( IObject );
390
391   if ( MapIndex.Contains( index )) {
392     if ( modeShift ) {
393       MapIndex.Remove( index );
394       myActiveStudy->highlight( IObject, true, update );
395     }
396   } else {
397     if ( !modeShift )
398       MapIndex.Clear();
399
400     MapIndex.Add( index );
401     myActiveStudy->highlight( IObject, true, update );
402     emit currentSelectionChanged();
403     return true;
404   }
405
406   if ( MapIndex.IsEmpty() ) {
407     myMapIOSubIndex.UnBind( IObject );
408     RemoveIObject( IObject, update );
409   }
410
411   emit currentSelectionChanged();
412   return false;
413 }
414
415 void SALOME_Selection::RemoveIndex( const Handle(SALOME_InteractiveObject)& IObject, int index )
416 {
417   if ( myMapIOSubIndex.IsBound( IObject ) ) {
418     TColStd_MapOfInteger& MapIndex = myMapIOSubIndex.ChangeFind( IObject );
419     if ( MapIndex.Contains( index ) )
420       MapIndex.Remove( index );
421   }
422 }
423