1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "LightApp_SelectionMgr.h"
25 #include "LightApp_Study.h"
26 #include "LightApp_DataOwner.h"
27 #include "LightApp_DataSubOwner.h"
28 #include "LightApp_Application.h"
30 #include <SUIT_Session.h>
31 #include <SUIT_Selector.h>
33 #ifndef DISABLE_SALOMEOBJECT
34 #include <SALOME_ListIO.hxx>
36 // Open CASCADE Include
37 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
38 #include <TCollection_AsciiString.hxx>
41 #include <QtCore/QSet>
46 LightApp_SelectionMgr::LightApp_SelectionMgr( LightApp_Application* app, const bool fb )
47 : SUIT_SelectionMgr( fb ),
49 myTimeStamp( QTime::currentTime() ),
57 LightApp_SelectionMgr::~LightApp_SelectionMgr()
64 LightApp_Application* LightApp_SelectionMgr::application() const
69 void LightApp_SelectionMgr::setSelected( const SUIT_DataOwnerPtrList& lst, const bool append )
71 SUIT_SelectionMgr::setSelected( lst, append );
73 myTimeStamp = QTime::currentTime();
76 #ifndef DISABLE_SALOMEOBJECT
78 Get a sole selected objects from selection manager. If more than one object selected, return NULL.
79 Useful to optimize performance in case of large number of objects (IPAL0054049)
81 Handle(SALOME_InteractiveObject)
82 LightApp_SelectionMgr::soleSelectedObject( const QString& theType,
83 const bool convertReferences ) const
86 selectedObjects( list, theType, convertReferences, true );
87 return list.Extent() == 1 ? list.First() : Handle(SALOME_InteractiveObject)();
91 Get all selected objects from selection manager
93 void LightApp_SelectionMgr::selectedObjects( SALOME_ListIO& theList,
94 const QString& theType,
95 const bool convertReferences,
96 const bool sole) const
98 LightApp_Study* study = dynamic_cast<LightApp_Study*>( application()->activeStudy() );
104 QList<Handle(SALOME_InteractiveObject)> selList;
106 if ( !sole && isActualSelectionCache( theType )) {
107 selList = selectionCache( theType );
111 if ( !theType.isEmpty() )
112 types.append( theType );
114 types = selectorTypes();
117 for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) {
118 SUIT_DataOwnerPtrList aList;
119 selected( aList, *it, sole );
121 QList<Handle(SALOME_InteractiveObject)> typeSelList;
123 for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) {
124 const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>( (*itr).operator->() );
128 if ( !aSet.contains( owner->entry() ) && !owner->IO().IsNull() ) {
129 selList.append( owner->IO() );
130 aSet.insert( owner->entry() );
133 typeSelList.append( owner->IO() );
136 if ( !sole && isSelectionCacheEnabled() ) {
137 LightApp_SelectionMgr* that = (LightApp_SelectionMgr*)this;
138 that->myCacheSelection.insert( *it, typeSelList );
139 that->myCacheTimes.insert( *it, QTime::currentTime() );
144 QSet<QString> entrySet;
145 for ( QList<Handle(SALOME_InteractiveObject)>::const_iterator itr = selList.begin(); itr != selList.end(); ++itr )
147 Handle(SALOME_InteractiveObject) io = *itr;
148 QString entry( io->getEntry() );
149 // Entry to check object uniqueness.
150 // It is selected owner entry in the case, when we do not convert references,
151 // and entry of a real object, when we convert references.
152 if ( convertReferences ) {
153 QString refEntry = study->referencedToEntry( entry );
154 if ( !entrySet.contains( refEntry ) ) {
155 if ( refEntry != entry ) {
157 QString component = study->componentDataType( entry );
158 theList.Append( new SALOME_InteractiveObject( (const char*)entry.toUtf8(),
159 (const char*)component.toLatin1(),
160 ""/*refobj->Name().c_str()*/ ) );
162 else if ( !io.IsNull() )
163 theList.Append( io );
166 else if ( !entrySet.contains( entry ) && !io.IsNull() )
167 theList.Append( io );
169 entrySet.insert( entry );
172 if ( sole && theList.Extent() > 1 )
177 Append selected objects.
179 void LightApp_SelectionMgr::setSelectedObjects( const SALOME_ListIO& lst, const bool append )
181 SUIT_DataOwnerPtrList owners;
182 for ( SALOME_ListIteratorOfListIO it( lst ); it.More(); it.Next() )
184 if ( it.Value()->hasEntry() )
185 owners.append( new LightApp_DataOwner( it.Value() ) );
188 setSelected( owners, append );
193 Get all selected objects from selection manager
195 void LightApp_SelectionMgr::selectedObjects( QStringList& theList, const QString& theType,
196 const bool convertReferences ) const
198 LightApp_Study* study = dynamic_cast<LightApp_Study*>( application()->activeStudy() );
206 if ( isActualSelectionCache( theType ) )
207 selList = selectionCache( theType );
210 if ( !theType.isEmpty() )
211 types.append( theType );
213 types = selectorTypes();
216 for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) {
217 SUIT_DataOwnerPtrList aList;
218 selected( aList, *it );
220 QStringList typeSelList;
222 for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) {
223 const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>( (*itr).operator->() );
227 if ( !aSet.contains( owner->entry() ) ) {
228 selList.append( owner->entry() );
229 aSet.insert( owner->entry() );
232 typeSelList.append( owner->entry() );
235 if ( isSelectionCacheEnabled() ) {
236 LightApp_SelectionMgr* that = (LightApp_SelectionMgr*)this;
237 that->myCacheSelection.insert( *it, typeSelList );
238 that->myCacheTimes.insert( *it, QTime::currentTime() );
247 Append selected objects.
249 void LightApp_SelectionMgr::setSelectedObjects( const QStringList& lst, const bool append )
251 SUIT_DataOwnerPtrList owners;
252 foreach( const QString& aValue, lst ) {
253 if ( !aValue.isNull() )
254 owners.append( new LightApp_DataOwner( aValue ) );
257 setSelected( owners, append );
263 Emit current selection changed.
265 void LightApp_SelectionMgr::selectionChanged( SUIT_Selector* theSel )
267 SUIT_SelectionMgr::selectionChanged( theSel );
269 myTimeStamp = QTime::currentTime();
271 emit currentSelectionChanged();
274 #ifndef DISABLE_SALOMEOBJECT
277 get map of indexes for the given SALOME_InteractiveObject
279 void LightApp_SelectionMgr::GetIndexes( const Handle(SALOME_InteractiveObject)& IObject,
280 TColStd_IndexedMapOfInteger& theIndex)
284 SUIT_DataOwnerPtrList aList;
287 for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr )
289 LightApp_DataSubOwner* subOwner = dynamic_cast<LightApp_DataSubOwner*>( (*itr).operator->() );
290 if ( subOwner && subOwner->entry() == QString(IObject->getEntry()) )
291 theIndex.Add( subOwner->index() );
296 get map of indexes for the given entry of SALOME_InteractiveObject
298 void LightApp_SelectionMgr::GetIndexes( const QString& theEntry, TColStd_IndexedMapOfInteger& theIndex )
302 SUIT_DataOwnerPtrList aList;
305 for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr )
307 const LightApp_DataSubOwner* subOwner = dynamic_cast<const LightApp_DataSubOwner*>( (*itr).operator->() );
309 if ( subOwner->entry() == theEntry )
310 theIndex.Add( subOwner->index() );
316 Add or remove interactive objects from selection manager.
318 //bool LightApp_SelectionMgr::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& IObject,
319 void LightApp_SelectionMgr::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& IObject,
320 const TColStd_MapOfInteger& theIndexes,
323 SUIT_DataOwnerPtrList remainsOwners;
325 SUIT_DataOwnerPtrList aList;
328 QString ioEntry (IObject->getEntry());
331 for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr )
333 const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>( (*itr).operator->() );
336 if ( owner->entry() != ioEntry )
338 const LightApp_DataSubOwner* subOwner = dynamic_cast<const LightApp_DataSubOwner*>( owner );
340 remainsOwners.append( new LightApp_DataSubOwner( subOwner->entry(), subOwner->index() ) );
342 remainsOwners.append( new LightApp_DataOwner( owner->entry() ) );
348 remainsOwners = aList;
350 TColStd_MapIteratorOfMapOfInteger It;
351 It.Initialize(theIndexes);
352 for(;It.More();It.Next())
353 remainsOwners.append( new LightApp_DataSubOwner( ioEntry, It.Key() ) );
356 setSelected( remainsOwners, append );
358 emit currentSelectionChanged();
360 // Bug 17269: To avoid calling of selected(aList)
361 //TColStd_IndexedMapOfInteger anIndexes;
362 //GetIndexes( IObject, anIndexes );
363 //return !anIndexes.IsEmpty();
367 select 'subobjects' with given indexes
369 void LightApp_SelectionMgr::selectObjects( const Handle(SALOME_InteractiveObject)& IObject,
370 TColStd_IndexedMapOfInteger theIndex, bool append )
372 SUIT_DataOwnerPtrList aList;
374 if ( theIndex.IsEmpty() )
375 aList.append( new LightApp_DataOwner( QString(IObject->getEntry()) ) );
379 for ( i = 1; i <= theIndex.Extent(); i++ )
380 aList.append( new LightApp_DataSubOwner( QString(IObject->getEntry()), theIndex( i ) ) );
383 setSelected( aList, append );
387 select 'subobjects' with given indexes
389 void LightApp_SelectionMgr::selectObjects( MapIOOfMapOfInteger theMapIO, bool append )
391 SUIT_DataOwnerPtrList aList;
393 MapIOOfMapOfInteger::Iterator it(theMapIO);
394 for ( ; it.More(); it.Next() )
396 if ( it.Value().IsEmpty() )
397 aList.append( new LightApp_DataOwner( QString(it.Key()->getEntry()) ) );
401 for ( i = 1; i <= it.Value().Extent(); i++ )
402 aList.append( new LightApp_DataSubOwner( QString(it.Key()->getEntry()), it.Value()( i ) ) );
406 setSelected( aList, append );
410 get map of selected subowners : object's entry <-> map of indexes
412 void LightApp_SelectionMgr::selectedSubOwners( MapEntryOfMapOfInteger& theMap )
416 TColStd_IndexedMapOfInteger anIndexes;
418 SUIT_DataOwnerPtrList aList;
421 for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr )
423 const LightApp_DataSubOwner* subOwner =
424 dynamic_cast<const LightApp_DataSubOwner*>( (*itr).operator->() );
428 if ( !theMap.IsBound( TCollection_AsciiString(subOwner->entry().toUtf8().data()) ) )
430 // if ( !theMap.IsBound( subOwner->entry().toLatin1().data() ) )
434 //Bug 17269: GetIndexes( subOwner->entry(), anIndexes );
435 //Bug 17269: To avoid multiple calling of selected(aList)
436 for ( SUIT_DataOwnerPtrList::const_iterator itr2 = itr; itr2 != aList.end(); ++itr2 )
438 const LightApp_DataSubOwner* subOwner2 =
439 dynamic_cast<const LightApp_DataSubOwner*>( (*itr2).operator->() );
441 if ( subOwner2->entry() == subOwner->entry() )
442 anIndexes.Add( subOwner2->index() );
445 theMap.Bind( subOwner->entry().toUtf8().data(), anIndexes );
453 void LightApp_SelectionMgr::clearSelectionCache()
455 myCacheTimes.clear();
456 myCacheSelection.clear();
459 bool LightApp_SelectionMgr::isSelectionCacheEnabled() const
464 void LightApp_SelectionMgr::setSelectionCacheEnabled( bool on )
466 if ( myCacheState == on )
472 clearSelectionCache();
475 #ifndef DISABLE_SALOMEOBJECT
477 QList<Handle(SALOME_InteractiveObject)> LightApp_SelectionMgr::selectionCache( const QString& type ) const
479 QList<Handle(SALOME_InteractiveObject)> res;
482 if ( !type.isEmpty() )
483 types.append( type );
485 types = selectorTypes();
488 for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) {
489 if ( myCacheSelection.contains( *it ) ) {
490 const SelList& lst = myCacheSelection[*it];
491 for ( SelList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) {
492 if ( !(*itr).IsNull() && !set.contains( (*itr)->getEntry() ) ) {
494 set.insert( (*itr)->getEntry() );
504 QStringList LightApp_SelectionMgr::selectionCache( const QString& type ) const
509 if ( !type.isEmpty() )
510 types.append( type );
512 types = selectorTypes();
515 for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) {
516 if ( myCacheSelection.contains( *it ) ) {
517 const SelList& lst = myCacheSelection[*it];
518 for ( SelList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) {
519 if ( !set.contains( *itr ) ) {
531 bool LightApp_SelectionMgr::isActualSelectionCache( const QString& type ) const
536 if ( !type.isEmpty() )
537 types.append( type );
539 types = selectorTypes();
541 for ( QStringList::iterator it = types.begin(); it != types.end() && ok; ++it )
542 ok = myCacheTimes.contains( *it ) && myCacheTimes[*it].isValid() && myCacheTimes[*it] >= myTimeStamp;
547 QStringList LightApp_SelectionMgr::selectorTypes() const
550 QList<SUIT_Selector*> selectorList;
551 selectors( selectorList );
552 for ( QList<SUIT_Selector*>::const_iterator it = selectorList.begin(); it != selectorList.end(); ++it ) {
553 if ( (*it)->isEnabled() )
554 types.append( (*it)->type() );