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