Salome HOME
PR: merge from branch BR_UnitTests tag mergeto_trunk_17oct05
[modules/kernel.git] / src / SALOMEGUI / SALOME_Selection.cxx
index 3e79a6c6d99060ac9b45703810c97e832cbac06a..74a60fb5e09f3bdf6cad78cfaffb718d4ec30917 100644 (file)
@@ -26,7 +26,6 @@
 //  Module : SALOME
 //  $Header$
 
-using namespace std;
 /*!
   \class SALOME_Selection SALOME_Selection.h
   \brief Selection Mechanism of Interactive Object.
@@ -41,6 +40,17 @@ using namespace std;
 #include "QAD_Desktop.h"
 #include "utilities.h"
 
+#include <TColStd_MapIteratorOfMapOfInteger.hxx>
+#include <TColStd_IndexedMapOfInteger.hxx>
+
+#ifdef _DEBUG_
+static int MYDEBUG = 0;
+#else
+static int MYDEBUG = 0;
+#endif
+
+using namespace std;
+
 static QList<SALOME_Selection>&  SALOME_Sel_GetSelections()
 {
   static QList<SALOME_Selection> Selections;
@@ -59,7 +69,7 @@ SALOME_Selection::SALOME_Selection(const QString& aName) :
 {
   myFilters.Clear();
   myIObjects.Clear();
-  mySelectionMode = 4; /*Actor*/
+  mySelectionMode = ActorSelection; /*4*/
   mySelActiveCompOnly = false;
   
   QAD_Desktop* aDesktop = QAD_Application::getDesktop();
@@ -243,7 +253,7 @@ int SALOME_Selection::AddIObject(const Handle(SALOME_InteractiveObject)& anObjec
   QAD_Study* myActiveStudy = myDesktop->getActiveStudy();
 
   if ( !IsOk(anObject) ) {
-    MESSAGE ( "The Object not authorized by Filters" )
+    if(MYDEBUG) INFOS ( "The Object not authorized by Filters" )
     myActiveStudy->highlight(anObject,false, update);
     return -1;
   }
@@ -305,13 +315,13 @@ int SALOME_Selection::IObjectCount()
 //!  Returns the first InteractiveObject in the selection.
 Handle(SALOME_InteractiveObject) SALOME_Selection::firstIObject()
 {
-  return myIObjects.First();
+  return myIObjects.Extent() > 0 ? myIObjects.First() : Handle(SALOME_InteractiveObject)();
 }
 
 //! Returns the last InteractiveObject in the selection.
 Handle(SALOME_InteractiveObject) SALOME_Selection::lastIObject()
 {
-  return myIObjects.Last();
+  return myIObjects.Extent() > 0 ? myIObjects.Last() : Handle(SALOME_InteractiveObject)();
 }
 
 /*!
@@ -328,13 +338,13 @@ bool SALOME_Selection::IsOk(const Handle(SALOME_InteractiveObject)& anObj)
   return true;
 }
 
-void SALOME_Selection::SetSelectionMode(int mode, bool activeCompOnly)
+void SALOME_Selection::SetSelectionMode(Selection_Mode mode, bool activeCompOnly)
 {
   mySelectionMode = mode;
   mySelActiveCompOnly = activeCompOnly;
 }
 
-int SALOME_Selection::SelectionMode()
+Selection_Mode SALOME_Selection::SelectionMode()
 {
   return mySelectionMode;
 }
@@ -349,7 +359,7 @@ bool SALOME_Selection::HasIndex( const Handle(SALOME_InteractiveObject)& IObject
   return myMapIOSubIndex.IsBound(IObject);
 }
 
-void SALOME_Selection::GetIndex( const Handle(SALOME_InteractiveObject)& IObject, TColStd_MapOfInteger& theIndex )
+void SALOME_Selection::GetIndex( const Handle(SALOME_InteractiveObject)& IObject, TColStd_IndexedMapOfInteger& theIndex )
 {
   if ( myMapIOSubIndex.IsBound(IObject) ) {
     theIndex = myMapIOSubIndex.Find(IObject);
@@ -366,11 +376,32 @@ bool SALOME_Selection::IsIndexSelected(const Handle(SALOME_InteractiveObject)& I
   if ( !myMapIOSubIndex.IsBound( IObject ) ) {
     return false;
   }
-  TColStd_MapOfInteger& MapIndex = myMapIOSubIndex.ChangeFind( IObject );
+  TColStd_IndexedMapOfInteger& MapIndex = myMapIOSubIndex.ChangeFind( IObject );
   return MapIndex.Contains( index );
 }
 
-
+static bool removeIndex( TColStd_IndexedMapOfInteger& MapIndex,
+                        const int                     Index)
+{
+  int i = MapIndex.FindIndex( Index ); // i==0 if Index is not in the MapIndex
+  if ( i ) {
+    // only the last key can be removed
+    int indexLast = MapIndex.FindKey( MapIndex.Extent() );
+    if ( indexLast == Index )
+      MapIndex.RemoveLast();
+    else {
+      TColStd_IndexedMapOfInteger aNewMap;
+      aNewMap.ReSize( MapIndex.Extent() - 1 );
+      for ( int j = 1; j <= MapIndex.Extent(); j++ ) {
+        int ind = MapIndex( j );
+        if ( ind != Index )
+          aNewMap.Add( ind );
+      }
+      MapIndex = aNewMap;
+    }
+  }
+  return i;
+}
 
 
 bool SALOME_Selection::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& IObject, 
@@ -378,46 +409,138 @@ bool SALOME_Selection::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)&
                                         bool modeShift,
                                         bool update)
 {
-  MESSAGE ( " SALOME_Selection::AddOrRemoveIndex " << index << " - " << modeShift )
+  if(MYDEBUG) INFOS( " SALOME_Selection::AddOrRemoveIndex " << index << " - " << modeShift );
   QAD_Desktop*   myDesktop = (QAD_Desktop*) QAD_Application::getDesktop();
   QAD_Study* myActiveStudy = myDesktop->getActiveStudy();
 
   if ( !myMapIOSubIndex.IsBound( IObject ) ) {
-    TColStd_MapOfInteger Empty;
+    TColStd_IndexedMapOfInteger Empty;
     myMapIOSubIndex.Bind( IObject, Empty );
   }
-  TColStd_MapOfInteger& MapIndex = myMapIOSubIndex.ChangeFind( IObject );
+  TColStd_IndexedMapOfInteger& MapIndex = myMapIOSubIndex.ChangeFind( IObject );
 
-  if ( MapIndex.Contains( index )) {
-    if ( modeShift ) {
-      MapIndex.Remove( index );
-      myActiveStudy->highlight( IObject, true, update );
-    }
-  } else {
-    if ( !modeShift )
-      MapIndex.Clear();
+  bool anIsConatains = MapIndex.Contains( index );
 
+  if (anIsConatains)
+    removeIndex( MapIndex, index );
+  
+  if (!modeShift)
+    MapIndex.Clear();
+  
+  if(!anIsConatains)
     MapIndex.Add( index );
-    myActiveStudy->highlight( IObject, true, update );
-    emit currentSelectionChanged();
-    return true;
-  }
 
   if ( MapIndex.IsEmpty() ) {
     myMapIOSubIndex.UnBind( IObject );
     RemoveIObject( IObject, update );
   }
 
+  myActiveStudy->highlight( IObject, true, update );   
+
   emit currentSelectionChanged();
   return false;
 }
 
+bool SALOME_Selection::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& IObject, 
+                                        const TColStd_MapOfInteger& theIndices, 
+                                        bool modeShift,
+                                        bool update)
+{
+  QAD_Desktop*   myDesktop = (QAD_Desktop*) QAD_Application::getDesktop();
+  QAD_Study* myActiveStudy = myDesktop->getActiveStudy();
+  
+  if ( !myMapIOSubIndex.IsBound( IObject ) ) {
+    TColStd_IndexedMapOfInteger Empty;
+    myMapIOSubIndex.Bind( IObject, Empty );
+  }
+  TColStd_IndexedMapOfInteger& MapIndex = myMapIOSubIndex.ChangeFind( IObject );
+  TColStd_MapIteratorOfMapOfInteger It;
+  It.Initialize(theIndices);
+  
+  if (!modeShift)
+    MapIndex.Clear();
+  
+  for(;It.More();It.Next())
+    MapIndex.Add(It.Key());
+  
+  if ( MapIndex.IsEmpty() ) {
+    myMapIOSubIndex.UnBind( IObject );
+    RemoveIObject( IObject, update );
+  }
+
+  myActiveStudy->highlight( IObject, true, update );   
+
+  emit currentSelectionChanged();
+  
+  return !MapIndex.IsEmpty();
+}
+
+bool SALOME_Selection::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& IObject, 
+                                        const TContainerOfId& theIndices, 
+                                        bool modeShift,
+                                        bool update)
+{
+  QAD_Desktop*   myDesktop = (QAD_Desktop*) QAD_Application::getDesktop();
+  QAD_Study* myActiveStudy = myDesktop->getActiveStudy();
+  
+  if ( !myMapIOSubIndex.IsBound( IObject ) ) {
+    TColStd_IndexedMapOfInteger Empty;
+    myMapIOSubIndex.Bind( IObject, Empty );
+  }
+  TColStd_IndexedMapOfInteger& MapIndex = myMapIOSubIndex.ChangeFind( IObject );
+      
+  if (!modeShift)
+    MapIndex.Clear();
+  
+  TContainerOfId::const_iterator anIter = theIndices.begin();
+  TContainerOfId::const_iterator anIterEnd = theIndices.end();
+  for(; anIter != anIterEnd; anIter++)
+    MapIndex.Add(*anIter); 
+
+  if ( MapIndex.IsEmpty() ) {
+    myMapIOSubIndex.UnBind( IObject );
+    RemoveIObject( IObject, update );
+  }
+
+  myActiveStudy->highlight( IObject, true, update );   
+
+  emit currentSelectionChanged();
+  
+  return !MapIndex.IsEmpty();
+}
+
 void SALOME_Selection::RemoveIndex( const Handle(SALOME_InteractiveObject)& IObject, int index )
 {
   if ( myMapIOSubIndex.IsBound( IObject ) ) {
-    TColStd_MapOfInteger& MapIndex = myMapIOSubIndex.ChangeFind( IObject );
-    if ( MapIndex.Contains( index ) )
-      MapIndex.Remove( index );
+    TColStd_IndexedMapOfInteger& MapIndex = myMapIOSubIndex.ChangeFind( IObject );
+    removeIndex( MapIndex, index );
   }
 }
 
+void SALOME_Selection::ClearIndex()
+{
+  myMapIOSubIndex.Clear();  
+}
+
+
+//================================================================
+// Function : GEOMBase_Helper
+// Purpose  : Block signal currentSelectionChanged. Use this method to
+//            deactivate signal before big modification of selection.
+//            After this modification this signal must be activated and
+//            method SelectionChanged must be called to notify other oblects
+//            ( dialogs for example )
+//================================================================
+void SALOME_Selection::BlockSignals( const bool theState )
+{
+  blockSignals( theState );
+}
+
+//================================================================
+// Function : SelectionChanged
+// Purpose  : Enit signal currentSelectionChanged()
+//================================================================
+void SALOME_Selection::SelectionChanged()
+{
+  emit currentSelectionChanged();
+}