]> SALOME platform Git repositories - modules/gui.git/blob - src/LightApp/LightApp_SelectionMgr.cxx
Salome HOME
Merge branch 'V8_1_BR'
[modules/gui.git] / src / LightApp / LightApp_SelectionMgr.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  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, or (at your option) any later version.
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.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "LightApp_SelectionMgr.h"
24
25 #include "LightApp_Study.h"
26 #include "LightApp_DataOwner.h"
27 #include "LightApp_DataSubOwner.h"
28 #include "LightApp_Application.h"
29
30 #include <SUIT_Session.h>
31 #include <SUIT_Selector.h>
32
33 #ifndef DISABLE_SALOMEOBJECT
34   #include <SALOME_ListIO.hxx>
35
36   // Open CASCADE Include
37   #include <TColStd_MapIteratorOfMapOfInteger.hxx>
38   #include <TCollection_AsciiString.hxx>
39 #endif
40
41 #include <QtCore/QSet>
42
43 /*!
44   Constructor.
45 */
46 LightApp_SelectionMgr::LightApp_SelectionMgr( LightApp_Application* app, const bool fb )
47 : SUIT_SelectionMgr( fb ),
48   myApp( app ),
49   myTimeStamp( QTime::currentTime() ),
50   myCacheState( false )
51 {
52 }
53
54 /*!
55   Destructor.
56 */
57 LightApp_SelectionMgr::~LightApp_SelectionMgr()
58 {
59 }
60
61 /*!
62   Gets application.
63 */
64 LightApp_Application* LightApp_SelectionMgr::application() const
65 {
66   return myApp;
67 }
68
69 void LightApp_SelectionMgr::setSelected( const SUIT_DataOwnerPtrList& lst, const bool append )
70 {
71   SUIT_SelectionMgr::setSelected( lst, append );
72
73   myTimeStamp = QTime::currentTime();
74 }
75
76 #ifndef DISABLE_SALOMEOBJECT
77 /*!
78   Get all selected objects from selection manager
79 */
80 void LightApp_SelectionMgr::selectedObjects( SALOME_ListIO& theList, const QString& theType,
81                                              const bool convertReferences ) const
82 {
83   LightApp_Study* study = dynamic_cast<LightApp_Study*>( application()->activeStudy() );
84   if ( !study )
85     return;
86   
87   theList.Clear();
88
89   QList<Handle(SALOME_InteractiveObject)> selList;
90
91   if ( isActualSelectionCache( theType ) ) {
92     selList = selectionCache( theType );
93   }
94   else {
95     QStringList types;
96     if ( !theType.isEmpty() )
97       types.append( theType );
98     else
99       types = selectorTypes();
100
101     QSet<QString> aSet;
102     for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) {
103       SUIT_DataOwnerPtrList aList;
104       selected( aList, *it );
105
106       QList<Handle(SALOME_InteractiveObject)> typeSelList;
107
108       for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) {
109         const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>( (*itr).operator->() );
110         if ( !owner )
111           continue;
112
113         if ( !aSet.contains( owner->entry() ) && !owner->IO().IsNull() ) {
114           selList.append( owner->IO() );
115           aSet.insert( owner->entry() );
116         }
117
118         typeSelList.append( owner->IO() );
119       }
120
121       if ( isSelectionCacheEnabled() ) {
122         LightApp_SelectionMgr* that = (LightApp_SelectionMgr*)this;
123         that->myCacheSelection.insert( *it, typeSelList );
124         that->myCacheTimes.insert( *it, QTime::currentTime() );
125       }
126     }
127   }
128
129   QSet<QString> entrySet;
130   for ( QList<Handle(SALOME_InteractiveObject)>::const_iterator itr = selList.begin(); itr != selList.end(); ++itr )
131   {
132     Handle(SALOME_InteractiveObject) io = *itr;
133     QString entry( io->getEntry() );
134     // Entry to check object uniqueness.
135     // It is selected owner entry in the case, when we do not convert references,
136     // and entry of a real object, when we convert references.
137     if ( convertReferences ) {
138       QString refEntry = study->referencedToEntry( entry );
139       if ( !entrySet.contains( refEntry ) ) {
140         if ( refEntry != entry ) {
141           entry = refEntry;
142           QString component = study->componentDataType( entry );
143           theList.Append( new SALOME_InteractiveObject( (const char*)entry.toLatin1(),
144                                                         (const char*)component.toLatin1(),
145                                                         ""/*refobj->Name().c_str()*/ ) );
146         }
147         else if ( !io.IsNull() )
148           theList.Append( io );
149       }
150     }
151     else if ( !entrySet.contains( entry ) && !io.IsNull() )
152       theList.Append( io );
153
154     entrySet.insert( entry );
155   }
156 }
157
158 /*!
159   Append selected objects.
160 */
161 void LightApp_SelectionMgr::setSelectedObjects( const SALOME_ListIO& lst, const bool append )
162 {
163   SUIT_DataOwnerPtrList owners;
164   for ( SALOME_ListIteratorOfListIO it( lst ); it.More(); it.Next() )
165   {
166     if ( it.Value()->hasEntry() )
167       owners.append( new LightApp_DataOwner( it.Value() ) );
168   }
169
170   setSelected( owners, append );
171 }
172
173 #else
174 /*!
175   Get all selected objects from selection manager
176 */
177 void LightApp_SelectionMgr::selectedObjects( QStringList& theList, const QString& theType,
178                                              const bool convertReferences ) const
179 {
180   LightApp_Study* study = dynamic_cast<LightApp_Study*>( application()->activeStudy() );
181   if ( !study )
182     return;
183
184   theList.clear();
185
186   QStringList selList;
187
188   if ( isActualSelectionCache( theType ) )
189     selList = selectionCache( theType );
190   else {
191     QStringList types;
192     if ( !theType.isEmpty() )
193       types.append( theType );
194     else
195       types = selectorTypes();
196
197     QSet<QString> aSet;
198     for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) {
199       SUIT_DataOwnerPtrList aList;
200       selected( aList, *it );
201
202       QStringList typeSelList;
203
204       for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) {
205         const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>( (*itr).operator->() );
206         if ( !owner )
207           continue;
208
209         if ( !aSet.contains( owner->entry() ) ) {
210           selList.append( owner->entry() );
211           aSet.insert( owner->entry() );
212         }
213
214         typeSelList.append( owner->entry() );
215       }
216
217       if ( isSelectionCacheEnabled() ) {
218         LightApp_SelectionMgr* that = (LightApp_SelectionMgr*)this;
219         that->myCacheSelection.insert( *it, typeSelList );
220         that->myCacheTimes.insert( *it, QTime::currentTime() );
221       }
222     }
223   }
224
225   theList = selList;
226 }
227
228 /*!
229   Append selected objects.
230 */
231 void LightApp_SelectionMgr::setSelectedObjects( const QStringList& lst, const bool append )
232 {
233   SUIT_DataOwnerPtrList owners;
234   foreach( const QString& aValue, lst ) {
235     if ( !aValue.isNull() )
236       owners.append( new LightApp_DataOwner( aValue ) );
237   }
238
239   setSelected( owners, append );
240 }
241
242 #endif
243
244 /*!
245   Emit current selection changed.
246 */
247 void LightApp_SelectionMgr::selectionChanged( SUIT_Selector* theSel )
248 {
249   SUIT_SelectionMgr::selectionChanged( theSel );
250
251   myTimeStamp = QTime::currentTime();
252
253   emit currentSelectionChanged();
254 }
255
256 #ifndef DISABLE_SALOMEOBJECT
257
258 /*!
259   get map of indexes for the given SALOME_InteractiveObject
260 */
261 void LightApp_SelectionMgr::GetIndexes( const Handle(SALOME_InteractiveObject)& IObject,
262                                         TColStd_IndexedMapOfInteger& theIndex)
263 {
264   theIndex.Clear();
265
266   SUIT_DataOwnerPtrList aList;
267   selected( aList );
268
269   for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr )
270   {
271     LightApp_DataSubOwner* subOwner = dynamic_cast<LightApp_DataSubOwner*>( (*itr).operator->() );
272     if ( subOwner && subOwner->entry() == QString(IObject->getEntry()) )
273       theIndex.Add( subOwner->index() );
274   }
275 }
276
277 /*!
278   get map of indexes for the given entry of SALOME_InteractiveObject
279 */
280 void LightApp_SelectionMgr::GetIndexes( const QString& theEntry, TColStd_IndexedMapOfInteger& theIndex )
281 {
282   theIndex.Clear();
283
284   SUIT_DataOwnerPtrList aList;
285   selected( aList );
286
287   for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr )
288   {
289     const LightApp_DataSubOwner* subOwner = dynamic_cast<const LightApp_DataSubOwner*>( (*itr).operator->() );
290     if ( subOwner )
291       if ( subOwner->entry() == theEntry )
292         theIndex.Add( subOwner->index() );
293   }
294
295 }
296
297 /*!
298   Add or remove interactive objects from selection manager.
299 */
300 //bool LightApp_SelectionMgr::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& IObject,
301 void LightApp_SelectionMgr::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& IObject,
302                                               const TColStd_MapOfInteger& theIndexes,
303                                               bool modeShift)
304 {
305   SUIT_DataOwnerPtrList remainsOwners;
306
307   SUIT_DataOwnerPtrList aList;
308   selected( aList );
309
310   QString ioEntry (IObject->getEntry());
311
312   if ( !modeShift ) {
313     for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr )
314     {
315       const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>( (*itr).operator->() );
316       if ( owner )
317       {
318         if ( owner->entry() != ioEntry )
319         {
320           const LightApp_DataSubOwner* subOwner = dynamic_cast<const LightApp_DataSubOwner*>( owner );
321           if ( subOwner )
322             remainsOwners.append( new LightApp_DataSubOwner( subOwner->entry(), subOwner->index() ) );
323           else
324             remainsOwners.append( new LightApp_DataOwner( owner->entry() ) );
325         }
326       }
327     }
328   }
329   else
330     remainsOwners = aList;
331
332   TColStd_MapIteratorOfMapOfInteger It;
333   It.Initialize(theIndexes);
334   for(;It.More();It.Next())
335     remainsOwners.append( new LightApp_DataSubOwner( ioEntry, It.Key() ) );
336
337   bool append = false;
338   setSelected( remainsOwners, append );
339
340   emit currentSelectionChanged();
341
342   // Bug 17269: To avoid calling of selected(aList)
343   //TColStd_IndexedMapOfInteger anIndexes;
344   //GetIndexes( IObject, anIndexes );
345   //return !anIndexes.IsEmpty();
346 }
347
348 /*!
349   select 'subobjects' with given indexes
350 */
351 void LightApp_SelectionMgr::selectObjects( const Handle(SALOME_InteractiveObject)& IObject,
352                                             TColStd_IndexedMapOfInteger theIndex, bool append )
353 {
354   SUIT_DataOwnerPtrList aList;
355
356   if ( theIndex.IsEmpty() )
357     aList.append( new LightApp_DataOwner( QString(IObject->getEntry()) ) );
358   else
359     {
360       int i;
361       for ( i = 1; i <= theIndex.Extent(); i++ )
362         aList.append( new LightApp_DataSubOwner( QString(IObject->getEntry()), theIndex( i ) ) );
363     }
364
365   setSelected( aList, append );
366 }
367
368 /*!
369   select 'subobjects' with given indexes
370 */
371 void LightApp_SelectionMgr::selectObjects( MapIOOfMapOfInteger theMapIO, bool append )
372 {
373   SUIT_DataOwnerPtrList aList;
374
375   MapIOOfMapOfInteger::Iterator it(theMapIO);
376   for ( ; it.More(); it.Next() )
377     {
378       if ( it.Value().IsEmpty() )
379         aList.append( new LightApp_DataOwner( QString(it.Key()->getEntry()) ) );
380       else
381         {
382           int i;
383           for ( i = 1; i <= it.Value().Extent(); i++ )
384             aList.append( new LightApp_DataSubOwner( QString(it.Key()->getEntry()), it.Value()( i ) ) );
385         }
386     }
387
388   setSelected( aList, append );
389 }
390
391 /*!
392   get map of selected subowners : object's entry <-> map of indexes
393 */
394 void LightApp_SelectionMgr::selectedSubOwners( MapEntryOfMapOfInteger& theMap )
395 {
396   theMap.Clear();
397
398   TColStd_IndexedMapOfInteger anIndexes;
399
400   SUIT_DataOwnerPtrList aList;
401   selected( aList );
402
403   for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr )
404   {
405     const LightApp_DataSubOwner* subOwner =
406       dynamic_cast<const LightApp_DataSubOwner*>( (*itr).operator->() );
407     if ( subOwner )
408     {
409 //#ifndef WIN32
410       if ( !theMap.IsBound( TCollection_AsciiString(subOwner->entry().toLatin1().data()) ) )
411 //#else
412 //      if ( !theMap.IsBound( subOwner->entry().toLatin1().data() ) )
413 //#endif
414       {
415         anIndexes.Clear();
416         //Bug 17269: GetIndexes( subOwner->entry(), anIndexes );
417         //Bug 17269: To avoid multiple calling of selected(aList)
418         for ( SUIT_DataOwnerPtrList::const_iterator itr2 = itr; itr2 != aList.end(); ++itr2 )
419         {
420           const LightApp_DataSubOwner* subOwner2 =
421             dynamic_cast<const LightApp_DataSubOwner*>( (*itr2).operator->() );
422           if ( subOwner2 )
423             if ( subOwner2->entry() == subOwner->entry() )
424               anIndexes.Add( subOwner2->index() );
425         }
426         //
427         theMap.Bind( subOwner->entry().toLatin1().data(), anIndexes );
428       }
429     }
430   }
431 }
432
433 #endif
434
435 void LightApp_SelectionMgr::clearSelectionCache()
436 {
437   myCacheTimes.clear();
438   myCacheSelection.clear();
439 }
440
441 bool LightApp_SelectionMgr::isSelectionCacheEnabled() const
442 {
443   return myCacheState;
444 }
445
446 void LightApp_SelectionMgr::setSelectionCacheEnabled( bool on )
447 {
448   if ( myCacheState == on )
449     return;
450
451   myCacheState = on;
452
453   if ( !myCacheState )
454     clearSelectionCache();
455 }
456
457 #ifndef DISABLE_SALOMEOBJECT
458
459 QList<Handle(SALOME_InteractiveObject)> LightApp_SelectionMgr::selectionCache( const QString& type ) const
460 {
461   QList<Handle(SALOME_InteractiveObject)> res;
462
463   QStringList types;
464   if ( !type.isEmpty() )
465     types.append( type );
466   else
467     types = selectorTypes();
468
469   QSet<QString> set;
470   for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) {
471     if ( myCacheSelection.contains( *it ) ) {
472       const SelList& lst = myCacheSelection[*it];
473       for ( SelList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) {
474         if ( !(*itr).IsNull() && !set.contains( (*itr)->getEntry() ) ) {
475           res.append( *itr );
476           set.insert( (*itr)->getEntry() );
477         }
478       }
479     }
480   }
481   return res;
482 }
483
484 #else
485
486 QStringList LightApp_SelectionMgr::selectionCache( const QString& type ) const
487 {
488   QStringList res;
489
490   QStringList types;
491   if ( !type.isEmpty() )
492     types.append( type );
493   else
494     types = selectorTypes();
495
496   QSet<QString> set;
497   for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) {
498     if ( myCacheSelection.contains( *it ) ) {
499       const SelList& lst = myCacheSelection[*it];
500       for ( SelList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) {
501         if ( !set.contains( *itr ) ) {
502           res.append( *itr );
503           set.insert( *itr );
504         }
505       }
506     }
507   }
508   return res;
509 }
510
511 #endif
512
513 bool LightApp_SelectionMgr::isActualSelectionCache( const QString& type ) const
514 {
515   bool ok = true;
516
517   QStringList types;
518   if ( !type.isEmpty() )
519     types.append( type );
520   else
521     types = selectorTypes();
522
523   for ( QStringList::iterator it = types.begin(); it != types.end() && ok; ++it )
524     ok = myCacheTimes.contains( *it ) && myCacheTimes[*it].isValid() && myCacheTimes[*it] >= myTimeStamp;
525
526   return ok;
527 }
528
529 QStringList LightApp_SelectionMgr::selectorTypes() const
530 {
531   QStringList types;
532   QList<SUIT_Selector*> selectorList;
533   selectors( selectorList );
534   for ( QList<SUIT_Selector*>::const_iterator it = selectorList.begin(); it != selectorList.end(); ++it ) {
535     if ( (*it)->isEnabled() )
536       types.append( (*it)->type() );
537   }
538   return types;
539 }