X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FLightApp%2FLightApp_SelectionMgr.cxx;h=4e8eb3e8604e9a177079553b9d512b1941ba8b3f;hb=8d973f87a441c75acab8b1cf0d3f54434735008e;hp=a46e906c0736a25ca8c83f7ca47839fef6a692a1;hpb=101fd10f1e736daa5d7f0f0ee5499b951460832a;p=modules%2Fgui.git diff --git a/src/LightApp/LightApp_SelectionMgr.cxx b/src/LightApp/LightApp_SelectionMgr.cxx index a46e906c0..4e8eb3e86 100644 --- a/src/LightApp/LightApp_SelectionMgr.cxx +++ b/src/LightApp/LightApp_SelectionMgr.cxx @@ -1,21 +1,25 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D -// +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either +// License as published by the Free Software Foundation; either // version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + #include "LightApp_SelectionMgr.h" #include "LightApp_Study.h" @@ -24,6 +28,7 @@ #include "LightApp_Application.h" #include +#include #ifndef DISABLE_SALOMEOBJECT #include @@ -33,14 +38,19 @@ #include #include #include + #include #endif +#include + /*! Constructor. */ LightApp_SelectionMgr::LightApp_SelectionMgr( LightApp_Application* app, const bool fb ) : SUIT_SelectionMgr( fb ), -myApp( app ) + myApp( app ), + myTimeStamp( QTime::currentTime() ), + myCacheState( false ) { } @@ -59,6 +69,13 @@ LightApp_Application* LightApp_SelectionMgr::application() const return myApp; } +void LightApp_SelectionMgr::setSelected( const SUIT_DataOwnerPtrList& lst, const bool append ) +{ + SUIT_SelectionMgr::setSelected( lst, append ); + + myTimeStamp = QTime::currentTime(); +} + #ifndef DISABLE_SALOMEOBJECT /*! Get all selected objects from selection manager @@ -66,42 +83,78 @@ LightApp_Application* LightApp_SelectionMgr::application() const void LightApp_SelectionMgr::selectedObjects( SALOME_ListIO& theList, const QString& theType, const bool convertReferences ) const { + LightApp_Study* study = dynamic_cast( application()->activeStudy() ); + if ( !study ) + return; + theList.Clear(); - SUIT_DataOwnerPtrList aList; - selected( aList, theType ); + QList selList; - QMap entryMap; + if ( isActualSelectionCache( theType ) ) { + selList = selectionCache( theType ); + } + else { + QStringList types; + if ( !theType.isEmpty() ) + types.append( theType ); + else + types = selectorTypes(); + + QSet aSet; + for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) { + SUIT_DataOwnerPtrList aList; + selected( aList, *it ); + + QList typeSelList; + + for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) { + const LightApp_DataOwner* owner = dynamic_cast( (*itr).operator->() ); + if ( !owner ) + continue; + + if ( !aSet.contains( owner->entry() ) ) { + selList.append( owner->IO() ); + aSet.insert( owner->entry() ); + } - QString entry; - for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) - { - const LightApp_DataOwner* owner = dynamic_cast( (*itr).operator->() ); - if( !owner ) - continue; + typeSelList.append( owner->IO() ); + } - LightApp_Study* study = dynamic_cast( application()->activeStudy() ); - if ( !study ) - return; + if ( isSelectionCacheEnabled() ) { + LightApp_SelectionMgr* that = (LightApp_SelectionMgr*)this; + that->myCacheSelection.insert( *it, typeSelList ); + that->myCacheTimes.insert( *it, QTime::currentTime() ); + } + } + } - entry = owner->entry(); + QSet entrySet; + for ( QList::const_iterator itr = selList.begin(); itr != selList.end(); ++itr ) + { + Handle(SALOME_InteractiveObject) io = *itr; + QString entry( io->getEntry() ); + // Entry to check object uniqueness. + // It is selected owner entry in the case, when we do not convert references, + // and entry of a real object, when we convert references. if ( convertReferences ) { QString refEntry = study->referencedToEntry( entry ); - if( !entryMap.contains( entry ) ) { + if ( !entrySet.contains( refEntry ) ) { if ( refEntry != entry ) { - QString component = study->componentDataType( refEntry ); - theList.Append( new SALOME_InteractiveObject( refEntry, component, ""/*refobj->Name().c_str()*/ ) ); + entry = refEntry; + QString component = study->componentDataType( entry ); + theList.Append( new SALOME_InteractiveObject( (const char*)entry.toLatin1(), + (const char*)component.toLatin1(), + ""/*refobj->Name().c_str()*/ ) ); } - else - theList.Append( owner->IO() ); + else if ( !io.IsNull() ) + theList.Append( io ); } } - else { - if( !entryMap.contains( entry ) ) - theList.Append( owner->IO() ); - } + else if ( !entrySet.contains( entry ) && !io.IsNull() ) + theList.Append( io ); - entryMap.insert(owner->entry(), 1); + entrySet.insert( entry ); } } @@ -127,26 +180,52 @@ void LightApp_SelectionMgr::setSelectedObjects( const SALOME_ListIO& lst, const void LightApp_SelectionMgr::selectedObjects( QStringList& theList, const QString& theType, const bool convertReferences ) const { + LightApp_Study* study = dynamic_cast( application()->activeStudy() ); + if ( !study ) + return; + theList.clear(); - SUIT_DataOwnerPtrList aList; - selected( aList, theType ); + QStringList selList; - QString entry; - for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) - { - const LightApp_DataOwner* owner = dynamic_cast( (*itr).operator->() ); - if( !owner ) - continue; + if ( isActualSelectionCache( theType ) ) + selList = selectionCache( theType ); + else { + QStringList types; + if ( !theType.isEmpty() ) + types.append( theType ); + else + types = selectorTypes(); + + QSet aSet; + for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) { + SUIT_DataOwnerPtrList aList; + selected( aList, *it ); - LightApp_Study* study = dynamic_cast( application()->activeStudy() ); - if ( !study ) - return; + QStringList typeSelList; - entry = owner->entry(); - if( !theList.contains( entry ) ) - theList.append( entry ); + for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) { + const LightApp_DataOwner* owner = dynamic_cast( (*itr).operator->() ); + if ( !owner ) + continue; + + if ( !aSet.contains( owner->entry() ) ) { + selList.append( owner->entry() ); + aSet.insert( owner->entry() ); + } + + typeSelList.append( owner->entry() ); + } + + if ( isSelectionCacheEnabled() ) { + LightApp_SelectionMgr* that = (LightApp_SelectionMgr*)this; + that->myCacheSelection.insert( *it, typeSelList ); + that->myCacheTimes.insert( *it, QTime::currentTime() ); + } + } } + + theList = selList; } #endif @@ -158,6 +237,8 @@ void LightApp_SelectionMgr::selectionChanged( SUIT_Selector* theSel ) { SUIT_SelectionMgr::selectionChanged( theSel ); + myTimeStamp = QTime::currentTime(); + emit currentSelectionChanged(); } @@ -166,7 +247,7 @@ void LightApp_SelectionMgr::selectionChanged( SUIT_Selector* theSel ) /*! get map of indexes for the given SALOME_InteractiveObject */ -void LightApp_SelectionMgr::GetIndexes( const Handle(SALOME_InteractiveObject)& IObject, +void LightApp_SelectionMgr::GetIndexes( const Handle(SALOME_InteractiveObject)& IObject, TColStd_IndexedMapOfInteger& theIndex) { theIndex.Clear(); @@ -176,12 +257,10 @@ void LightApp_SelectionMgr::GetIndexes( const Handle(SALOME_InteractiveObject)& for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) { - const LightApp_DataSubOwner* subOwner = dynamic_cast( (*itr).operator->() ); - if ( subOwner ) - if ( subOwner->entry() == QString(IObject->getEntry()) ) - theIndex.Add( subOwner->index() ); + LightApp_DataSubOwner* subOwner = dynamic_cast( (*itr).operator->() ); + if ( subOwner && subOwner->entry() == QString(IObject->getEntry()) ) + theIndex.Add( subOwner->index() ); } - } /*! @@ -199,7 +278,7 @@ void LightApp_SelectionMgr::GetIndexes( const QString& theEntry, TColStd_Indexed const LightApp_DataSubOwner* subOwner = dynamic_cast( (*itr).operator->() ); if ( subOwner ) if ( subOwner->entry() == theEntry ) - theIndex.Add( subOwner->index() ); + theIndex.Add( subOwner->index() ); } } @@ -207,29 +286,32 @@ void LightApp_SelectionMgr::GetIndexes( const QString& theEntry, TColStd_Indexed /*! Add or remove interactive objects from selection manager. */ -bool LightApp_SelectionMgr::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& IObject, - const TColStd_MapOfInteger& theIndexes, - bool modeShift) +//bool LightApp_SelectionMgr::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& IObject, +void LightApp_SelectionMgr::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& IObject, + const TColStd_MapOfInteger& theIndexes, + bool modeShift) { SUIT_DataOwnerPtrList remainsOwners; - + SUIT_DataOwnerPtrList aList; selected( aList ); + QString ioEntry (IObject->getEntry()); + if ( !modeShift ) { for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) { const LightApp_DataOwner* owner = dynamic_cast( (*itr).operator->() ); - if ( owner ) + if ( owner ) { - if ( owner->entry() != QString(IObject->getEntry()) ) - { - const LightApp_DataSubOwner* subOwner = dynamic_cast( owner ); - if ( subOwner ) - remainsOwners.append( new LightApp_DataSubOwner( subOwner->entry(), subOwner->index() ) ); - else - remainsOwners.append( new LightApp_DataOwner( owner->entry() ) ); - } + if ( owner->entry() != ioEntry ) + { + const LightApp_DataSubOwner* subOwner = dynamic_cast( owner ); + if ( subOwner ) + remainsOwners.append( new LightApp_DataSubOwner( subOwner->entry(), subOwner->index() ) ); + else + remainsOwners.append( new LightApp_DataOwner( owner->entry() ) ); + } } } } @@ -239,24 +321,24 @@ bool LightApp_SelectionMgr::AddOrRemoveIndex( const Handle(SALOME_InteractiveObj TColStd_MapIteratorOfMapOfInteger It; It.Initialize(theIndexes); for(;It.More();It.Next()) - remainsOwners.append( new LightApp_DataSubOwner( QString(IObject->getEntry()), It.Key() ) ); - + remainsOwners.append( new LightApp_DataSubOwner( ioEntry, It.Key() ) ); + bool append = false; setSelected( remainsOwners, append ); emit currentSelectionChanged(); - TColStd_IndexedMapOfInteger anIndexes; - GetIndexes( IObject, anIndexes ); - return !anIndexes.IsEmpty(); - + // Bug 17269: To avoid calling of selected(aList) + //TColStd_IndexedMapOfInteger anIndexes; + //GetIndexes( IObject, anIndexes ); + //return !anIndexes.IsEmpty(); } /*! select 'subobjects' with given indexes */ -void LightApp_SelectionMgr::selectObjects( const Handle(SALOME_InteractiveObject)& IObject, - TColStd_IndexedMapOfInteger theIndex, bool append ) +void LightApp_SelectionMgr::selectObjects( const Handle(SALOME_InteractiveObject)& IObject, + TColStd_IndexedMapOfInteger theIndex, bool append ) { SUIT_DataOwnerPtrList aList; @@ -266,11 +348,10 @@ void LightApp_SelectionMgr::selectObjects( const Handle(SALOME_InteractiveObject { int i; for ( i = 1; i <= theIndex.Extent(); i++ ) - aList.append( new LightApp_DataSubOwner( QString(IObject->getEntry()), theIndex( i ) ) ); + aList.append( new LightApp_DataSubOwner( QString(IObject->getEntry()), theIndex( i ) ) ); } setSelected( aList, append ); - } /*! @@ -280,21 +361,20 @@ void LightApp_SelectionMgr::selectObjects( MapIOOfMapOfInteger theMapIO, bool ap { SUIT_DataOwnerPtrList aList; - MapIOOfMapOfInteger::Iterator it; - for ( it = theMapIO.begin(); it != theMapIO.end(); ++it ) + MapIOOfMapOfInteger::Iterator it(theMapIO); + for ( ; it.More(); it.Next() ) { - if ( it.data().IsEmpty() ) - aList.append( new LightApp_DataOwner( QString(it.key()->getEntry()) ) ); + if ( it.Value().IsEmpty() ) + aList.append( new LightApp_DataOwner( QString(it.Key()->getEntry()) ) ); else - { - int i; - for ( i = 1; i <= it.data().Extent(); i++ ) - aList.append( new LightApp_DataSubOwner( QString(it.key()->getEntry()), it.data()( i ) ) ); - } + { + int i; + for ( i = 1; i <= it.Value().Extent(); i++ ) + aList.append( new LightApp_DataSubOwner( QString(it.Key()->getEntry()), it.Value()( i ) ) ); + } } - - setSelected( aList, append ); + setSelected( aList, append ); } /*! @@ -302,7 +382,7 @@ void LightApp_SelectionMgr::selectObjects( MapIOOfMapOfInteger theMapIO, bool ap */ void LightApp_SelectionMgr::selectedSubOwners( MapEntryOfMapOfInteger& theMap ) { - theMap.clear(); + theMap.Clear(); TColStd_IndexedMapOfInteger anIndexes; @@ -311,17 +391,138 @@ void LightApp_SelectionMgr::selectedSubOwners( MapEntryOfMapOfInteger& theMap ) for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) { - const LightApp_DataSubOwner* subOwner = dynamic_cast( (*itr).operator->() ); - if ( subOwner ) + const LightApp_DataSubOwner* subOwner = + dynamic_cast( (*itr).operator->() ); + if ( subOwner ) { - if ( !theMap.contains( subOwner->entry() ) ) +//#ifndef WNT + if ( !theMap.IsBound( TCollection_AsciiString(subOwner->entry().toLatin1().data()) ) ) +//#else +// if ( !theMap.IsBound( subOwner->entry().toLatin1().data() ) ) +//#endif { - anIndexes.Clear(); - GetIndexes( subOwner->entry(), anIndexes ); - theMap.insert( subOwner->entry(), anIndexes ); + anIndexes.Clear(); + //Bug 17269: GetIndexes( subOwner->entry(), anIndexes ); + //Bug 17269: To avoid multiple calling of selected(aList) + for ( SUIT_DataOwnerPtrList::const_iterator itr2 = itr; itr2 != aList.end(); ++itr2 ) + { + const LightApp_DataSubOwner* subOwner2 = + dynamic_cast( (*itr2).operator->() ); + if ( subOwner2 ) + if ( subOwner2->entry() == subOwner->entry() ) + anIndexes.Add( subOwner2->index() ); + } + // + theMap.Bind( subOwner->entry().toLatin1().data(), anIndexes ); } } } } #endif + +void LightApp_SelectionMgr::clearSelectionCache() +{ + myCacheTimes.clear(); + myCacheSelection.clear(); +} + +bool LightApp_SelectionMgr::isSelectionCacheEnabled() const +{ + return myCacheState; +} + +void LightApp_SelectionMgr::setSelectionCacheEnabled( bool on ) +{ + if ( myCacheState == on ) + return; + + myCacheState = on; + + if ( !myCacheState ) + clearSelectionCache(); +} + +#ifndef DISABLE_SALOMEOBJECT + +QList LightApp_SelectionMgr::selectionCache( const QString& type ) const +{ + QList res; + + QStringList types; + if ( !type.isEmpty() ) + types.append( type ); + else + types = selectorTypes(); + + QSet set; + for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) { + if ( myCacheSelection.contains( *it ) ) { + const SelList& lst = myCacheSelection[*it]; + for ( SelList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) { + if ( !(*itr).IsNull() && !set.contains( (*itr)->getEntry() ) ) { + res.append( *itr ); + set.insert( (*itr)->getEntry() ); + } + } + } + } + return res; +} + +#else + +QStringList LightApp_SelectionMgr::selectionCache( const QString& type ) const +{ + QStringList res; + + QStringList types; + if ( !type.isEmpty() ) + types.append( type ); + else + types = selectorTypes(); + + QSet set; + for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) { + if ( myCacheSelection.contains( *it ) ) { + const SelList& lst = myCacheSelection[*it]; + for ( SelList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) { + if ( !set.contains( *itr ) ) { + res.append( *itr ); + set.insert( *itr ); + } + } + } + } + return res; +} + +#endif + +bool LightApp_SelectionMgr::isActualSelectionCache( const QString& type ) const +{ + bool ok = true; + + QStringList types; + if ( !type.isEmpty() ) + types.append( type ); + else + types = selectorTypes(); + + for ( QStringList::iterator it = types.begin(); it != types.end() && ok; ++it ) + ok = myCacheTimes.contains( *it ) && myCacheTimes[*it].isValid() && myCacheTimes[*it] >= myTimeStamp; + + return ok; +} + +QStringList LightApp_SelectionMgr::selectorTypes() const +{ + QStringList types; + QList selectorList; + selectors( selectorList ); + for ( QList::const_iterator it = selectorList.begin(); it != selectorList.end(); ++it ) { + if ( (*it)->isEnabled() ) + types.append( (*it)->type() ); + } + return types; +}