Salome HOME
Base class for all smesh operations that are working with selection
authorsln <sln@opencascade.com>
Tue, 23 Aug 2005 08:55:09 +0000 (08:55 +0000)
committersln <sln@opencascade.com>
Tue, 23 Aug 2005 08:55:09 +0000 (08:55 +0000)
src/SMESHGUI/SMESHGUI_SelectionOp.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_SelectionOp.h [new file with mode: 0644]

diff --git a/src/SMESHGUI/SMESHGUI_SelectionOp.cxx b/src/SMESHGUI/SMESHGUI_SelectionOp.cxx
new file mode 100644 (file)
index 0000000..1bc466c
--- /dev/null
@@ -0,0 +1,508 @@
+//  Copyright (C) 2003  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 
+//  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 
+//  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 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESHGUI_SelectionOp.cxx
+//  Author : Alexander SOLOVYOV
+//  Module : SMESH
+
+#include <SMESHGUI_SelectionOp.h>
+#include <SMESHGUI_VTKUtils.h>
+#include <SMESHGUI_MeshUtils.h>
+#include <SMESHGUI_Selection.h>
+#include <SMESHGUI.h>
+#include <SUIT_SelectionFilter.h>
+#include <SalomeApp_SelectionMgr.h>
+#include <SalomeApp_Study.h>
+#include <SalomeApp_VTKSelector.h>
+#include <SVTK_ViewWindow.h>
+#include <SVTK_ViewModel.h>
+#include <SVTK_Selector.h>
+#include <SMESH_Actor.h>
+
+#include <SMDS_Mesh.hxx>
+#include <SMDS_MeshNode.hxx>
+
+#include CORBA_SERVER_HEADER(GEOM_Gen)
+#include <SALOMEDS_SObject.hxx>
+
+/*
+  Class       : SMESHGUI_SelectionOp
+  Description : Base operation for all operations using object selection in viewer or objectbrowser
+                through common widgets created by SalomeApp_Dialog::createObject
+*/
+
+//=================================================================================
+// name     : SMESHGUI_SelectionOp
+// purpose  : 
+//=================================================================================
+SMESHGUI_SelectionOp::SMESHGUI_SelectionOp( const Selection_Mode mode )
+: SMESHGUI_Operation(),
+  myDefSelectionMode( mode )
+{
+}
+
+//=================================================================================
+// name     : ~SMESHGUI_SelectionOp
+// purpose  :
+//=================================================================================
+SMESHGUI_SelectionOp::~SMESHGUI_SelectionOp()
+{
+  Filters::const_iterator anIt = myFilters.begin(),
+                          aLast = myFilters.end();
+  for( ; anIt!=aLast; anIt++ )
+    if( anIt.data() )
+      delete anIt.data();
+}
+
+//=================================================================================
+// name     : startOperation
+// purpose  :
+//=================================================================================
+void SMESHGUI_SelectionOp::startOperation()
+{
+  SMESHGUI_Operation::startOperation();
+  if( dlg() )
+  {
+    disconnect( dlg(), SIGNAL( objectActivated( int ) ), this, SLOT( onActivateObject( int ) ) );
+    disconnect( dlg(), SIGNAL( objectDeactivated( int ) ), this, SLOT( onDeactivateObject( int ) ) );
+    disconnect( dlg(), SIGNAL( selectionChanged( int ) ), this, SLOT( onSelectionChanged( int ) ) );
+    connect( dlg(), SIGNAL( objectActivated( int ) ), this, SLOT( onActivateObject( int ) ) );
+    connect( dlg(), SIGNAL( objectDeactivated( int ) ), this, SLOT( onDeactivateObject( int ) ) );
+    connect( dlg(), SIGNAL( selectionChanged( int ) ), this, SLOT( onSelectionChanged( int ) ) );
+  }
+
+  myOldSelectionMode = selectionMode();
+  setSelectionMode( myDefSelectionMode );
+}
+
+//=================================================================================
+// name     : removeCustomFilters
+// purpose  :
+//=================================================================================
+void SMESHGUI_SelectionOp::removeCustomFilters() const
+{
+  SalomeApp_SelectionMgr* mgr = selectionMgr();
+  if( !mgr )
+    return;
+    
+  Filters::const_iterator anIt = myFilters.begin(),
+                          aLast = myFilters.end();
+  for( ; anIt!=aLast; anIt++ )
+    if( anIt.data() )
+      mgr->removeFilter( anIt.data() );
+}
+
+//=================================================================================
+// name     : commitOperation
+// purpose  :
+//=================================================================================
+void SMESHGUI_SelectionOp::commitOperation()
+{
+  removeCustomFilters();
+  setSelectionMode( myOldSelectionMode );
+  SMESHGUI_Operation::commitOperation();  
+}
+
+//=================================================================================
+// name     : abortOperation
+// purpose  :
+//=================================================================================
+void SMESHGUI_SelectionOp::abortOperation()
+{
+  removeCustomFilters();
+  setSelectionMode( myOldSelectionMode );  
+  SMESHGUI_Operation::abortOperation();
+}
+
+//=================================================================================
+// name     : selectionDone
+// purpose  :
+//=================================================================================
+void SMESHGUI_SelectionOp::selectionDone()
+{
+  if( !dlg() )
+    return;
+
+  if( selectionMode()!=ActorSelection )
+  {
+    SALOME_ListIO aList;
+    selectionMgr()->selectedObjects( aList, SVTK_Viewer::Type() );
+
+    if( aList.Extent() != 1 ) //we can select nodes or elements only within one mesh
+    {
+      dlg()->clearSelection();
+      return;
+    }    
+  }
+    
+  QStringList names, ids;
+  SalomeApp_Dialog::TypesList types;
+  selected( names, types, ids );
+  dlg()->selectObject( names, types, ids );
+}
+
+//=================================================================================
+// name     : createFilter
+// purpose  :
+//=================================================================================
+SUIT_SelectionFilter* SMESHGUI_SelectionOp::createFilter( const int ) const
+{
+  return 0;
+}
+
+//=================================================================================
+// name     : onActivateObject
+// purpose  :
+//=================================================================================
+void SMESHGUI_SelectionOp::onActivateObject( int id )
+{
+  SalomeApp_SelectionMgr* mgr = selectionMgr();
+  if( !mgr )
+    return;
+    
+  if( !myFilters.contains( id ) )
+    myFilters[ id ] = createFilter( id );
+
+  if( myFilters[ id ] )
+    mgr->installFilter( myFilters[ id ] );
+
+  selectionDone();
+}
+
+//=================================================================================
+// name     : onDeactivateObject
+// purpose  :
+//=================================================================================
+void SMESHGUI_SelectionOp::onDeactivateObject( int id )
+{
+  SalomeApp_SelectionMgr* mgr = selectionMgr();
+  if( mgr && myFilters.contains( id ) && myFilters[ id ] )
+    mgr->removeFilter( myFilters[ id ] );
+}
+
+//=================================================================================
+// name     : initDialog
+// purpose  :
+//=================================================================================
+void SMESHGUI_SelectionOp::initDialog()
+{
+  if( dlg() )
+  {
+    dlg()->clearSelection();
+    dlg()->deactivateAll();
+  }
+}
+
+//=================================================================================
+// name     : initDialog
+// purpose  :
+//=================================================================================
+void SMESHGUI_SelectionOp::onSelectionChanged( int )
+{
+}
+
+//=======================================================================
+// name    : selectionMode
+// Purpose : Returns selection mode
+//=======================================================================
+Selection_Mode SMESHGUI_SelectionOp::selectionMode() const
+{
+  SVTK_ViewWindow* wnd = viewWindow();
+  if( wnd )
+    return wnd->SelectionMode();
+  else
+    return ActorSelection;
+}
+
+//=======================================================================
+// name    : setSelectionMode
+// Purpose : Set selection mode
+//=======================================================================
+void SMESHGUI_SelectionOp::setSelectionMode( const Selection_Mode mode )
+{
+  SVTK_ViewWindow* wnd = viewWindow();
+  if( wnd )
+    wnd->SetSelectionMode( mode );
+}
+
+//=======================================================================
+// name    : highlight
+// Purpose : Highlight object in 3d viewer
+//=======================================================================
+void SMESHGUI_SelectionOp::highlight( const Handle( SALOME_InteractiveObject )& obj,
+                                      const bool hilight, const bool immediately )
+{
+  SVTK_ViewWindow* wnd = viewWindow();
+  if( wnd )
+    wnd->highlight( obj, hilight, immediately );
+}
+
+//=======================================================================
+// name    : addOrRemoveIndex
+// Purpose : Select/deselect cells of mesh
+//=======================================================================
+void SMESHGUI_SelectionOp::addOrRemoveIndex( const Handle( SALOME_InteractiveObject )& obj,
+                                             const TColStd_MapOfInteger& indices,
+                                             const bool isModeShift )
+{
+  SVTK_Selector* sel = selector();
+  if( sel )
+    sel->AddOrRemoveIndex( obj, indices, isModeShift );
+}
+
+//=======================================================================
+// name    : viewWindow
+// Purpose : Get active view window
+//=======================================================================
+SVTK_ViewWindow* SMESHGUI_SelectionOp::viewWindow() const
+{
+  return SMESH::GetViewWindow( getSMESHGUI() );
+}
+
+//=======================================================================
+// name    : selector
+// Purpose : Get selector
+//=======================================================================
+SVTK_Selector* SMESHGUI_SelectionOp::selector() const
+{
+  SVTK_ViewWindow* wnd = viewWindow();
+  return wnd ? wnd->GetSelector() : 0;
+}
+
+//=======================================================================
+// name    : typeById
+// Purpose : Find type by id
+//=======================================================================
+int SMESHGUI_SelectionOp::typeById( const QString& str, const EntityType objtype ) const
+{
+  SalomeApp_Study* _study = dynamic_cast<SalomeApp_Study*>( study() );
+  if( !_study )
+    return -1;
+
+  _PTR( Study ) st = _study->studyDS();
+
+  int res = -1;
+  if( objtype == Object )
+  {
+    SalomeApp_Study* _study = dynamic_cast<SalomeApp_Study*>( study() );
+    if( _study )
+    {
+      int t = SMESHGUI_Selection::type( str, _study->studyDS() );
+      if( t<0 )
+      {
+        //try to get GEOM type
+        _PTR( SObject ) sobj = st->FindObjectID( str.latin1() );
+        if( sobj )
+        {
+          GEOM::GEOM_Object_var obj = GEOM::GEOM_Object::_narrow(
+            dynamic_cast<SALOMEDS_SObject*>( sobj.get() )->GetObject() );
+          if( !CORBA::is_nil( obj ) )
+            res = SMESHGUI_Dialog::prefix( "GEOM" ) + obj->GetType();
+        }
+      }
+      else
+        res = SMESHGUI_Dialog::prefix( "SMESH" ) + t;
+    }
+  }
+  else
+  {
+    int pos = str.find( idChar() );
+    QString entry = str.left( pos ),
+            _id = str.mid( pos+1 );
+    bool ok;
+    int id = _id.toInt( &ok );
+    if( ok )
+    {
+      _PTR( SObject ) sobj = st->FindObjectID( entry.latin1() );
+      SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( 
+        dynamic_cast<SALOMEDS_SObject*>( sobj.get() )->GetObject() );
+      SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( 
+        dynamic_cast<SALOMEDS_SObject*>( sobj.get() )->GetObject() );
+      if( !CORBA::is_nil( mesh ) )
+        res = SMESHGUI_Dialog::prefix( "SMESH element" ) + 
+          mesh->GetElementType( id, objtype==MeshElement );
+
+      else if( !CORBA::is_nil( submesh ) )
+        res = SMESHGUI_Dialog::prefix( "SMESH element" ) + 
+          submesh->GetElementType( id, objtype==MeshElement );
+    }
+  }
+
+  return res;
+}
+
+//=======================================================================
+// name    : selected
+// Purpose : Get names, types and ids of selected objects
+//=======================================================================
+void SMESHGUI_SelectionOp::selected( QStringList& names,
+                                     SalomeApp_Dialog::TypesList& types,
+                                     QStringList& ids ) const
+{
+  SUIT_DataOwnerPtrList list; selectionMgr()->selected( list );
+  SUIT_DataOwnerPtrList::const_iterator anIt = list.begin(),
+                                        aLast = list.end();
+  for( ; anIt!=aLast; anIt++ )
+  {
+    SalomeApp_DataOwner* owner = dynamic_cast<SalomeApp_DataOwner*>( (*anIt).operator->() );
+    SalomeApp_SVTKDataOwner* vtkowner = dynamic_cast<SalomeApp_SVTKDataOwner*>( (*anIt).operator->() );
+
+    if( vtkowner )
+    {
+      QString id_str = QString( "%1%2%3" ).arg( vtkowner->entry() ).arg( idChar() ), current_id_str;
+      Selection_Mode mode = vtkowner->GetMode();
+      EntityType objtype = mode == NodeSelection ? MeshNode : MeshElement;
+      const TColStd_IndexedMapOfInteger& ownerids = vtkowner->GetIds();
+
+      for( int i=1, n=ownerids.Extent(); i<=n; i++ )
+      {
+        int curid = ownerids( i );
+        current_id_str = id_str.arg( curid );
+        ids.append( current_id_str );
+        types.append( typeById( current_id_str, objtype ) );
+        names.append( QString( "%1" ).arg( curid ) );
+      }
+    }
+
+    else if( owner )
+    {
+      QString id = owner->entry();
+      ids.append( id );
+      types.append( typeById( id, Object ) );
+      names.append( owner->IO()->getName() );
+    }
+  }
+}
+
+//=======================================================================
+// name    : idChar
+// Purpose : Char using to divide <entry> and <id> in string id representation. By default, '#'
+//=======================================================================
+QChar SMESHGUI_SelectionOp::idChar() const
+{
+  return '#';
+}
+
+//=================================================================================
+// name     : mesh
+// purpose  :
+//=================================================================================
+SMESH::SMESH_Mesh_var SMESHGUI_SelectionOp::mesh() const
+{
+  if( selectionMode()==ActorSelection )
+    return SMESH::SMESH_Mesh::_nil();
+    
+  SALOME_ListIO sel; selectionMgr()->selectedObjects( sel, SVTK_Viewer::Type() );
+  if( sel.Extent()==1 )
+    return SMESH::GetMeshByIO( sel.First() );
+  else
+    return SMESH::SMESH_Mesh::_nil();
+}
+
+//=================================================================================
+// name     : actor
+// purpose  :
+//=================================================================================
+SMESH_Actor* SMESHGUI_SelectionOp::actor() const
+{
+  SMESH::SMESH_Mesh_var m = mesh();
+  if( !m->_is_nil() )
+    return SMESH::FindActorByObject( m.in() );
+  else
+    return 0;
+}
+
+//=================================================================================
+// name     : onTextChanged
+// purpose  :
+//=================================================================================
+void SMESHGUI_SelectionOp::onTextChanged( int, const QStringList& list )
+{
+    if( !dlg() )
+      return;
+
+    TColStd_MapOfInteger newIndices;
+
+    SALOME_ListIO sel; selectionMgr()->selectedObjects( sel );
+    SMESH_Actor* anActor = actor();
+    if( sel.Extent()==0 || !anActor )
+      return;
+
+    SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
+
+    IdList ids; extractIds( list, ids, '\0' );
+    IdList::const_iterator anIt = ids.begin(),
+                           aLast = ids.end();
+    for( ; anIt!=aLast; anIt++ )
+      if( const SMDS_MeshNode * n = aMesh->FindNode( *anIt ) )
+        newIndices.Add( n->GetID() );
+
+    selector()->AddOrRemoveIndex( sel.First(), newIndices, false );
+    highlight( sel.First(), true, true );
+
+    QStringList names, _ids; SalomeApp_Dialog::TypesList types;
+    selected( names, types, _ids );
+    dlg()->selectObject( names, types, _ids, false );
+}
+
+//=================================================================================
+// name     : selectedIds
+// purpose  :
+//=================================================================================
+void SMESHGUI_SelectionOp::selectedIds( const int id, IdList& list ) const
+{
+  if( !dlg() )
+    return;
+
+  QStringList ids; dlg()->selectedObject( id, ids );
+  extractIds( ids, list );
+}
+
+//=================================================================================
+// name     : extractIds
+// purpose  :
+//=================================================================================
+void SMESHGUI_SelectionOp::extractIds( const QStringList& ids, IdList& list, const QChar idchar )
+{
+  QStringList::const_iterator anIt = ids.begin(),
+                              aLast = ids.end();
+  QString id_str;
+  for( ; anIt!=aLast; anIt++ )
+  {
+    id_str = *anIt;
+    int pos = idchar=='\0' ? -1 : id_str.find( idchar );
+    int id = -1;
+    if( idchar=='\0' || pos>=0 )
+    {
+      id = id_str.mid( pos+1 ).toInt();
+      list.append( id );
+    }
+  }
+}
+
+//=================================================================================
+// name     : extractIds
+// purpose  :
+//=================================================================================
+void SMESHGUI_SelectionOp::extractIds( const QStringList& ids, IdList& list ) const
+{
+  extractIds( ids, list, idChar() );
+}
diff --git a/src/SMESHGUI/SMESHGUI_SelectionOp.h b/src/SMESHGUI/SMESHGUI_SelectionOp.h
new file mode 100644 (file)
index 0000000..5dde0a0
--- /dev/null
@@ -0,0 +1,163 @@
+//  Copyright (C) 2003  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 
+//  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 
+//  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 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESHGUI_SelectionOp.h
+//  Author : Alexander SOLOVYOV
+//  Module : SMESH
+
+
+#ifndef SMESHGUI_SelectionOp_H
+#define SMESHGUI_SelectionOp_H
+
+#include <SMESHGUI_Operation.h>
+#include <SMESHGUI_Dialog.h>
+#include <SVTK_Selection.h>
+#include <SALOME_InteractiveObject.hxx>
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Gen)
+
+
+class SUIT_SelectionFilter;
+class TColStd_MapOfInteger;
+class SVTK_ViewWindow;
+class SVTK_Selector;
+class SMESH_Actor;
+
+/*
+  Class       : SMESHGUI_SelectionOp
+  Description : Base operation for all operations using object selection in viewer or objectbrowser
+                through common widgets created by SalomeApp_Dialog::createObject
+*/
+class SMESHGUI_SelectionOp : public SMESHGUI_Operation
+{ 
+  Q_OBJECT
+
+public:
+  typedef QValueList<int> IdList; //! List of node or element ids
+  
+public:
+  SMESHGUI_SelectionOp( const Selection_Mode = ActorSelection );
+  virtual ~SMESHGUI_SelectionOp();
+
+  static void  extractIds( const QStringList&, IdList&, const QChar );  
+
+protected:
+  typedef enum
+  {
+    Object,
+    MeshNode,
+    MeshElement
+
+  } EntityType;
+  /*!
+      This enumeration is used in typeById method to distinguish objects, mesh nodes and mesh elements,
+      because node end element ids may overlap
+  */
+  
+protected:
+  virtual void                  startOperation();
+  virtual void                  commitOperation();
+  virtual void                  abortOperation();
+  virtual void                  selectionDone();
+
+  //! sets the dialog widgets to state just after operation start
+  virtual void                  initDialog();
+
+  /*!
+   *  Creates filter being used when certain object selection widget is active
+   *  If no filter must be used, then function must return 0
+   *  if id is negative, then function must return filter for common using independently of active widget
+   */
+  virtual SUIT_SelectionFilter* createFilter( const int ) const;
+
+  //! Remove only filters set by this operation (they are in map myFilters )
+  void removeCustomFilters() const;
+
+  //! Return what selection mode is set in VTK viewer
+  Selection_Mode    selectionMode() const;
+
+  //! Set selection mode in VTK viewer
+  void              setSelectionMode( const Selection_Mode );
+
+  //! Hilight object in VTK viewer
+  void              highlight( const Handle( SALOME_InteractiveObject )&,
+                               const bool, const bool = true );
+                               
+  //! Select some nodes or elements in VTK
+  void              addOrRemoveIndex( const Handle( SALOME_InteractiveObject )&,
+                                      const TColStd_MapOfInteger&, const bool );
+
+  SVTK_ViewWindow*  viewWindow() const;
+  SVTK_Selector*    selector() const;
+
+  //! Get names, types and ids of selected objects
+  virtual void      selected( QStringList&, SMESHGUI_Dialog::TypesList&, QStringList& ) const;
+
+  //! Find type by id
+  virtual int       typeById( const QString&, const EntityType ) const;
+
+  //! Char using to divide <entry> and <id> in string id representation. By default, '#'
+  virtual QChar     idChar() const;
+
+  //! Try to find in certain object selection widget selected node or element ids and return it
+  void                   selectedIds( const int, IdList& ) const;
+
+  //! Find in QStringList correct node or element ids representation and append integer(id) to IdList
+  void                   extractIds( const QStringList&, IdList& ) const;
+
+  //! Return selected mesh if selection mode isn't ActorSelection and only one object is selected
+  SMESH::SMESH_Mesh_var  mesh() const;
+
+  //! Return actor according to selected mesh if selection mode isn't ActorSelection
+  SMESH_Actor*           actor() const;
+  
+protected slots:
+  //! Installs filter corresponding to certain object selection widget
+  virtual void onActivateObject( int );
+
+  //! Removes filter corresponding to certain object selection widget
+  virtual void onDeactivateObject( int );
+
+  /*!
+    *  Empty default implementation. In successors it may be used for more advanced selection checking.
+    *  This slot is connected to signal when the selection changed in some object selection widget
+  */
+  virtual void onSelectionChanged( int );
+
+  /*! Default implementation allowing user to edit selected ids "by hands".
+      In order to run default mechanism, you must set for some
+      object selection widget the "name indication" to "ListOfNames",
+      "read only" state to false and connect the dialog's signal "objectChanged"
+      to this slot
+      Warning: this mechanism can process only integer ids, NOT MESH OR GROUP NAMES!!!
+  */
+  virtual void  onTextChanged( int, const QStringList& );
+  
+private:
+  typedef QMap<int, SUIT_SelectionFilter*> Filters;
+  
+private:
+  Filters         myFilters;
+  Selection_Mode  myDefSelectionMode, myOldSelectionMode;
+};
+
+#endif