diff --git a/src/SMESHGUI/SMESHGUI_SelectionOp.cxx b/src/SMESHGUI/SMESHGUI_SelectionOp.cxx new file mode 100644 index 000000000..1bc466c6a --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_SelectionOp.cxx @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include CORBA_SERVER_HEADER(GEOM_Gen) +#include + +/* + 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( study() ); + if( !_study ) + return -1; + + _PTR( Study ) st = _study->studyDS(); + + int res = -1; + if( objtype == Object ) + { + SalomeApp_Study* _study = dynamic_cast( 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( 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( sobj.get() )->GetObject() ); + SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( + dynamic_cast( 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( (*anIt).operator->() ); + SalomeApp_SVTKDataOwner* vtkowner = dynamic_cast( (*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 and 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 index 000000000..5dde0a059 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_SelectionOp.h @@ -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 +#include +#include +#include + +#include +#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 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 and 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 Filters; + +private: + Filters myFilters; + Selection_Mode myDefSelectionMode, myOldSelectionMode; +}; + +#endif