Back to index

salome-gui  6.5.0
LightApp_SelectionMgr.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #include "LightApp_SelectionMgr.h"
00024 
00025 #include "LightApp_Study.h"
00026 #include "LightApp_DataOwner.h"
00027 #include "LightApp_DataSubOwner.h"
00028 #include "LightApp_Application.h"
00029 
00030 #include <SUIT_Session.h>
00031 #include <SUIT_Selector.h>
00032 
00033 #ifndef DISABLE_SALOMEOBJECT
00034   #include <SALOME_ListIO.hxx>
00035   #include <SALOME_ListIteratorOfListIO.hxx>
00036 
00037   // Open CASCADE Include
00038   #include <TColStd_MapOfInteger.hxx>
00039   #include <TColStd_MapIteratorOfMapOfInteger.hxx>
00040   #include <TColStd_IndexedMapOfInteger.hxx>
00041   #include <TCollection_AsciiString.hxx>
00042 #endif
00043 
00044 #include <QtCore/QSet>
00045 
00049 LightApp_SelectionMgr::LightApp_SelectionMgr( LightApp_Application* app, const bool fb )
00050 : SUIT_SelectionMgr( fb ),
00051   myApp( app ),
00052   myTimeStamp( QTime::currentTime() ),
00053   myCacheState( false )
00054 {
00055 }
00056 
00060 LightApp_SelectionMgr::~LightApp_SelectionMgr()
00061 {
00062 }
00063 
00067 LightApp_Application* LightApp_SelectionMgr::application() const
00068 {
00069   return myApp;
00070 }
00071 
00072 void LightApp_SelectionMgr::setSelected( const SUIT_DataOwnerPtrList& lst, const bool append )
00073 {
00074   SUIT_SelectionMgr::setSelected( lst, append );
00075 
00076   myTimeStamp = QTime::currentTime();
00077 }
00078 
00079 #ifndef DISABLE_SALOMEOBJECT
00080 
00083 void LightApp_SelectionMgr::selectedObjects( SALOME_ListIO& theList, const QString& theType,
00084                                              const bool convertReferences ) const
00085 {
00086   LightApp_Study* study = dynamic_cast<LightApp_Study*>( application()->activeStudy() );
00087   if ( !study )
00088     return;
00089   
00090   theList.Clear();
00091 
00092   QList<Handle(SALOME_InteractiveObject)> selList;
00093 
00094   if ( isActualSelectionCache( theType ) ) {
00095     selList = selectionCache( theType );
00096   }
00097   else {
00098     QStringList types;
00099     if ( !theType.isEmpty() )
00100       types.append( theType );
00101     else
00102       types = selectorTypes();
00103 
00104     QSet<QString> aSet;
00105     for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) {
00106       SUIT_DataOwnerPtrList aList;
00107       selected( aList, *it );
00108 
00109       QList<Handle(SALOME_InteractiveObject)> typeSelList;
00110 
00111       for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) {
00112        const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>( (*itr).operator->() );
00113        if ( !owner )
00114          continue;
00115 
00116        if ( !aSet.contains( owner->entry() ) ) {
00117          selList.append( owner->IO() );
00118          aSet.insert( owner->entry() );
00119        }
00120 
00121        typeSelList.append( owner->IO() );
00122       }
00123 
00124       if ( isSelectionCacheEnabled() ) {
00125        LightApp_SelectionMgr* that = (LightApp_SelectionMgr*)this;
00126        that->myCacheSelection.insert( *it, typeSelList );
00127        that->myCacheTimes.insert( *it, QTime::currentTime() );
00128       }
00129     }
00130   }
00131 
00132   QSet<QString> entrySet;
00133   for ( QList<Handle(SALOME_InteractiveObject)>::const_iterator itr = selList.begin(); itr != selList.end(); ++itr )
00134   {
00135     Handle(SALOME_InteractiveObject) io = *itr;
00136     QString entry( io->getEntry() );
00137     // Entry to check object uniqueness.
00138     // It is selected owner entry in the case, when we do not convert references,
00139     // and entry of a real object, when we convert references.
00140     if ( convertReferences ) {
00141       QString refEntry = study->referencedToEntry( entry );
00142       if ( !entrySet.contains( refEntry ) ) {
00143         if ( refEntry != entry ) {
00144          entry = refEntry;
00145           QString component = study->componentDataType( entry );
00146           theList.Append( new SALOME_InteractiveObject( (const char*)entry.toLatin1(),
00147                                                  (const char*)component.toLatin1(),
00148                                                  ""/*refobj->Name().c_str()*/ ) );
00149         }
00150         else if ( !io.IsNull() )
00151           theList.Append( io );
00152       }
00153     }
00154     else if ( !entrySet.contains( entry ) && !io.IsNull() )
00155       theList.Append( io );
00156 
00157     entrySet.insert( entry );
00158   }
00159 }
00160 
00164 void LightApp_SelectionMgr::setSelectedObjects( const SALOME_ListIO& lst, const bool append )
00165 {
00166   SUIT_DataOwnerPtrList owners;
00167   for ( SALOME_ListIteratorOfListIO it( lst ); it.More(); it.Next() )
00168   {
00169     if ( it.Value()->hasEntry() )
00170       owners.append( new LightApp_DataOwner( it.Value() ) );
00171   }
00172 
00173   setSelected( owners, append );
00174 }
00175 
00176 #else
00177 
00180 void LightApp_SelectionMgr::selectedObjects( QStringList& theList, const QString& theType,
00181                                              const bool convertReferences ) const
00182 {
00183   LightApp_Study* study = dynamic_cast<LightApp_Study*>( application()->activeStudy() );
00184   if ( !study )
00185     return;
00186 
00187   theList.clear();
00188 
00189   QStringList selList;
00190 
00191   if ( isActualSelectionCache( theType ) )
00192     selList = selectionCache( theType );
00193   else {
00194     QStringList types;
00195     if ( !theType.isEmpty() )
00196       types.append( theType );
00197     else
00198       types = selectorTypes();
00199 
00200     QSet<QString> aSet;
00201     for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) {
00202       SUIT_DataOwnerPtrList aList;
00203       selected( aList, *it );
00204 
00205       QStringList typeSelList;
00206 
00207       for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) {
00208        const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>( (*itr).operator->() );
00209        if ( !owner )
00210          continue;
00211 
00212        if ( !aSet.contains( owner->entry() ) ) {
00213          selList.append( owner->entry() );
00214          aSet.insert( owner->entry() );
00215        }
00216 
00217        typeSelList.append( owner->entry() );
00218       }
00219 
00220       if ( isSelectionCacheEnabled() ) {
00221        LightApp_SelectionMgr* that = (LightApp_SelectionMgr*)this;
00222        that->myCacheSelection.insert( *it, typeSelList );
00223        that->myCacheTimes.insert( *it, QTime::currentTime() );
00224       }
00225     }
00226   }
00227 
00228   theList = selList;
00229 }
00230 
00231 #endif
00232 
00236 void LightApp_SelectionMgr::selectionChanged( SUIT_Selector* theSel )
00237 {
00238   SUIT_SelectionMgr::selectionChanged( theSel );
00239 
00240   myTimeStamp = QTime::currentTime();
00241 
00242   emit currentSelectionChanged();
00243 }
00244 
00245 #ifndef DISABLE_SALOMEOBJECT
00246 
00250 void LightApp_SelectionMgr::GetIndexes( const Handle(SALOME_InteractiveObject)& IObject,
00251                                         TColStd_IndexedMapOfInteger& theIndex)
00252 {
00253   theIndex.Clear();
00254 
00255   SUIT_DataOwnerPtrList aList;
00256   selected( aList );
00257 
00258   for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr )
00259   {
00260     LightApp_DataSubOwner* subOwner = dynamic_cast<LightApp_DataSubOwner*>( (*itr).operator->() );
00261     if ( subOwner && subOwner->entry() == QString(IObject->getEntry()) )
00262       theIndex.Add( subOwner->index() );
00263   }
00264 }
00265 
00269 void LightApp_SelectionMgr::GetIndexes( const QString& theEntry, TColStd_IndexedMapOfInteger& theIndex )
00270 {
00271   theIndex.Clear();
00272 
00273   SUIT_DataOwnerPtrList aList;
00274   selected( aList );
00275 
00276   for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr )
00277   {
00278     const LightApp_DataSubOwner* subOwner = dynamic_cast<const LightApp_DataSubOwner*>( (*itr).operator->() );
00279     if ( subOwner )
00280       if ( subOwner->entry() == theEntry )
00281         theIndex.Add( subOwner->index() );
00282   }
00283 
00284 }
00285 
00289 //bool LightApp_SelectionMgr::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& IObject,
00290 void LightApp_SelectionMgr::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& IObject,
00291                                               const TColStd_MapOfInteger& theIndexes,
00292                                               bool modeShift)
00293 {
00294   SUIT_DataOwnerPtrList remainsOwners;
00295 
00296   SUIT_DataOwnerPtrList aList;
00297   selected( aList );
00298 
00299   QString ioEntry (IObject->getEntry());
00300 
00301   if ( !modeShift ) {
00302     for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr )
00303     {
00304       const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>( (*itr).operator->() );
00305       if ( owner )
00306       {
00307         if ( owner->entry() != ioEntry )
00308         {
00309           const LightApp_DataSubOwner* subOwner = dynamic_cast<const LightApp_DataSubOwner*>( owner );
00310           if ( subOwner )
00311             remainsOwners.append( new LightApp_DataSubOwner( subOwner->entry(), subOwner->index() ) );
00312           else
00313             remainsOwners.append( new LightApp_DataOwner( owner->entry() ) );
00314         }
00315       }
00316     }
00317   }
00318   else
00319     remainsOwners = aList;
00320 
00321   TColStd_MapIteratorOfMapOfInteger It;
00322   It.Initialize(theIndexes);
00323   for(;It.More();It.Next())
00324     remainsOwners.append( new LightApp_DataSubOwner( ioEntry, It.Key() ) );
00325 
00326   bool append = false;
00327   setSelected( remainsOwners, append );
00328 
00329   emit currentSelectionChanged();
00330 
00331   // Bug 17269: To avoid calling of selected(aList)
00332   //TColStd_IndexedMapOfInteger anIndexes;
00333   //GetIndexes( IObject, anIndexes );
00334   //return !anIndexes.IsEmpty();
00335 }
00336 
00340 void LightApp_SelectionMgr::selectObjects( const Handle(SALOME_InteractiveObject)& IObject,
00341                                             TColStd_IndexedMapOfInteger theIndex, bool append )
00342 {
00343   SUIT_DataOwnerPtrList aList;
00344 
00345   if ( theIndex.IsEmpty() )
00346     aList.append( new LightApp_DataOwner( QString(IObject->getEntry()) ) );
00347   else
00348     {
00349       int i;
00350       for ( i = 1; i <= theIndex.Extent(); i++ )
00351         aList.append( new LightApp_DataSubOwner( QString(IObject->getEntry()), theIndex( i ) ) );
00352     }
00353 
00354   setSelected( aList, append );
00355 }
00356 
00360 void LightApp_SelectionMgr::selectObjects( MapIOOfMapOfInteger theMapIO, bool append )
00361 {
00362   SUIT_DataOwnerPtrList aList;
00363 
00364   MapIOOfMapOfInteger::Iterator it(theMapIO);
00365   for ( ; it.More(); it.Next() )
00366     {
00367       if ( it.Value().IsEmpty() )
00368         aList.append( new LightApp_DataOwner( QString(it.Key()->getEntry()) ) );
00369       else
00370         {
00371           int i;
00372           for ( i = 1; i <= it.Value().Extent(); i++ )
00373             aList.append( new LightApp_DataSubOwner( QString(it.Key()->getEntry()), it.Value()( i ) ) );
00374         }
00375     }
00376 
00377   setSelected( aList, append );
00378 }
00379 
00383 void LightApp_SelectionMgr::selectedSubOwners( MapEntryOfMapOfInteger& theMap )
00384 {
00385   theMap.Clear();
00386 
00387   TColStd_IndexedMapOfInteger anIndexes;
00388 
00389   SUIT_DataOwnerPtrList aList;
00390   selected( aList );
00391 
00392   for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr )
00393   {
00394     const LightApp_DataSubOwner* subOwner =
00395       dynamic_cast<const LightApp_DataSubOwner*>( (*itr).operator->() );
00396     if ( subOwner )
00397     {
00398 //#ifndef WNT
00399       if ( !theMap.IsBound( TCollection_AsciiString(subOwner->entry().toLatin1().data()) ) )
00400 //#else
00401 //      if ( !theMap.IsBound( subOwner->entry().toLatin1().data() ) )
00402 //#endif
00403       {
00404         anIndexes.Clear();
00405         //Bug 17269: GetIndexes( subOwner->entry(), anIndexes );
00406         //Bug 17269: To avoid multiple calling of selected(aList)
00407         for ( SUIT_DataOwnerPtrList::const_iterator itr2 = itr; itr2 != aList.end(); ++itr2 )
00408         {
00409           const LightApp_DataSubOwner* subOwner2 =
00410             dynamic_cast<const LightApp_DataSubOwner*>( (*itr2).operator->() );
00411           if ( subOwner2 )
00412             if ( subOwner2->entry() == subOwner->entry() )
00413               anIndexes.Add( subOwner2->index() );
00414         }
00415         //
00416         theMap.Bind( subOwner->entry().toLatin1().data(), anIndexes );
00417       }
00418     }
00419   }
00420 }
00421 
00422 #endif
00423 
00424 void LightApp_SelectionMgr::clearSelectionCache()
00425 {
00426   myCacheTimes.clear();
00427   myCacheSelection.clear();
00428 }
00429 
00430 bool LightApp_SelectionMgr::isSelectionCacheEnabled() const
00431 {
00432   return myCacheState;
00433 }
00434 
00435 void LightApp_SelectionMgr::setSelectionCacheEnabled( bool on )
00436 {
00437   if ( myCacheState == on )
00438     return;
00439 
00440   myCacheState = on;
00441 
00442   if ( !myCacheState )
00443     clearSelectionCache();
00444 }
00445 
00446 #ifndef DISABLE_SALOMEOBJECT
00447 
00448 QList<Handle_SALOME_InteractiveObject> LightApp_SelectionMgr::selectionCache( const QString& type ) const
00449 {
00450   QList<Handle_SALOME_InteractiveObject> res;
00451 
00452   QStringList types;
00453   if ( !type.isEmpty() )
00454     types.append( type );
00455   else
00456     types = selectorTypes();
00457 
00458   QSet<QString> set;
00459   for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) {
00460     if ( myCacheSelection.contains( *it ) ) {
00461       const SelList& lst = myCacheSelection[*it];
00462       for ( SelList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) {
00463        if ( !(*itr).IsNull() && !set.contains( (*itr)->getEntry() ) ) {
00464          res.append( *itr );
00465          set.insert( (*itr)->getEntry() );
00466        }
00467       }
00468     }
00469   }
00470   return res;
00471 }
00472 
00473 #else
00474 
00475 QStringList LightApp_SelectionMgr::selectionCache( const QString& type ) const
00476 {
00477   QStringList res;
00478 
00479   QStringList types;
00480   if ( !type.isEmpty() )
00481     types.append( type );
00482   else
00483     types = selectorTypes();
00484 
00485   QSet<QString> set;
00486   for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) {
00487     if ( myCacheSelection.contains( *it ) ) {
00488       const SelList& lst = myCacheSelection[*it];
00489       for ( SelList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) {
00490        if ( !set.contains( *itr ) ) {
00491          res.append( *itr );
00492          set.insert( *itr );
00493        }
00494       }
00495     }
00496   }
00497   return res;
00498 }
00499 
00500 #endif
00501 
00502 bool LightApp_SelectionMgr::isActualSelectionCache( const QString& type ) const
00503 {
00504   bool ok = true;
00505 
00506   QStringList types;
00507   if ( !type.isEmpty() )
00508     types.append( type );
00509   else
00510     types = selectorTypes();
00511 
00512   for ( QStringList::iterator it = types.begin(); it != types.end() && ok; ++it )
00513     ok = myCacheTimes.contains( *it ) && myCacheTimes[*it].isValid() && myCacheTimes[*it] >= myTimeStamp;
00514 
00515   return ok;
00516 }
00517 
00518 QStringList LightApp_SelectionMgr::selectorTypes() const
00519 {
00520   QStringList types;
00521   QList<SUIT_Selector*> selectorList;
00522   selectors( selectorList );
00523   for ( QList<SUIT_Selector*>::const_iterator it = selectorList.begin(); it != selectorList.end(); ++it ) {
00524     if ( (*it)->isEnabled() )
00525       types.append( (*it)->type() );
00526   }
00527   return types;
00528 }