1 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : SMESHGUI_SelectionOp.cxx
21 // Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
25 #include "SMESHGUI_SelectionOp.h"
28 #include "SMESHGUI_VTKUtils.h"
29 #include "SMESHGUI_MeshUtils.h"
30 #include "SMESHGUI_Selection.h"
32 #include <SMESH_Actor.h>
33 #include <SMDS_Mesh.hxx>
34 #include <SMDS_MeshNode.hxx>
36 // SALOME GUI includes
37 #include <SUIT_SelectionFilter.h>
38 #include <LightApp_SelectionMgr.h>
39 #include <SalomeApp_Study.h>
40 #include <SVTK_ViewWindow.h>
41 #include <SVTK_ViewModel.h>
43 #include <SALOME_ListIO.hxx>
44 #include <SALOME_ListIteratorOfListIO.hxx>
46 // SALOME KERNEL includes
47 #include <SALOMEDS_SObject.hxx>
50 Class : SMESHGUI_SelectionOp
51 Description : Base operation for all operations using object selection in viewer or objectbrowser
52 through common widgets created by LightApp_Dialog::createObject
55 //=================================================================================
56 // name : SMESHGUI_SelectionOp
58 //=================================================================================
59 SMESHGUI_SelectionOp::SMESHGUI_SelectionOp( const Selection_Mode mode )
60 : SMESHGUI_Operation(),
61 myDefSelectionMode( mode )
65 //=================================================================================
66 // name : ~SMESHGUI_SelectionOp
68 //=================================================================================
69 SMESHGUI_SelectionOp::~SMESHGUI_SelectionOp()
71 removeCustomFilters();
74 //=================================================================================
75 // name : startOperation
77 //=================================================================================
78 void SMESHGUI_SelectionOp::startOperation()
80 myOldSelectionMode = selectionMode();
81 setSelectionMode( myDefSelectionMode );
83 SMESHGUI_Operation::startOperation();
86 disconnect( dlg(), SIGNAL( objectActivated( int ) ), this, SLOT( onActivateObject( int ) ) );
87 disconnect( dlg(), SIGNAL( objectDeactivated( int ) ), this, SLOT( onDeactivateObject( int ) ) );
88 disconnect( dlg(), SIGNAL( selectionChanged( int ) ), this, SLOT( onSelectionChanged( int ) ) );
89 connect( dlg(), SIGNAL( objectActivated( int ) ), this, SLOT( onActivateObject( int ) ) );
90 connect( dlg(), SIGNAL( objectDeactivated( int ) ), this, SLOT( onDeactivateObject( int ) ) );
91 connect( dlg(), SIGNAL( selectionChanged( int ) ), this, SLOT( onSelectionChanged( int ) ) );
95 //=================================================================================
96 // name : removeCustomFilters
98 //=================================================================================
99 void SMESHGUI_SelectionOp::removeCustomFilters()
101 if (myFilters.count() > 0) {
102 LightApp_SelectionMgr* mgr = selectionMgr();
103 Filters::const_iterator anIt = myFilters.begin(),
104 aLast = myFilters.end();
105 for ( ; anIt != aLast; anIt++) {
107 if (mgr) mgr->removeFilter(anIt.value());
116 //=================================================================================
117 // name : commitOperation
119 //=================================================================================
120 void SMESHGUI_SelectionOp::commitOperation()
122 SMESHGUI_Operation::commitOperation();
123 removeCustomFilters();
124 setSelectionMode( myOldSelectionMode );
127 //=================================================================================
128 // name : abortOperation
130 //=================================================================================
131 void SMESHGUI_SelectionOp::abortOperation()
133 SMESHGUI_Operation::abortOperation();
134 removeCustomFilters();
135 setSelectionMode( myOldSelectionMode );
138 //=================================================================================
139 // name : selectionDone
141 //=================================================================================
142 void SMESHGUI_SelectionOp::selectionDone()
147 if( selectionMode()!=ActorSelection )
150 selectionMgr()->selectedObjects( aList, SVTK_Viewer::Type() );
152 if( aList.Extent() != 1 ) //we can select nodes or elements only within one mesh
154 dlg()->clearSelection();
159 QStringList names, ids;
160 LightApp_Dialog::TypesList types;
161 selected( names, types, ids );
162 dlg()->selectObject( names, types, ids );
165 //=================================================================================
166 // name : createFilter
168 //=================================================================================
169 SUIT_SelectionFilter* SMESHGUI_SelectionOp::createFilter( const int ) const
174 //=================================================================================
175 // name : onActivateObject
177 //=================================================================================
178 void SMESHGUI_SelectionOp::onActivateObject( int id )
180 LightApp_SelectionMgr* mgr = selectionMgr();
184 if( !myFilters.contains( id ) )
185 myFilters[ id ] = createFilter( id );
187 if( myFilters[ id ] )
188 mgr->installFilter( myFilters[ id ] );
193 //=================================================================================
194 // name : onDeactivateObject
196 //=================================================================================
197 void SMESHGUI_SelectionOp::onDeactivateObject( int id )
199 removeCustomFilters();
202 //=================================================================================
205 //=================================================================================
206 void SMESHGUI_SelectionOp::initDialog()
210 dlg()->clearSelection();
211 dlg()->deactivateAll();
215 //=================================================================================
218 //=================================================================================
219 void SMESHGUI_SelectionOp::onSelectionChanged( int )
223 //=======================================================================
224 // name : selectionMode
225 // Purpose : Returns selection mode
226 //=======================================================================
227 Selection_Mode SMESHGUI_SelectionOp::selectionMode() const
229 SVTK_ViewWindow* wnd = viewWindow();
231 return wnd->SelectionMode();
233 return ActorSelection;
236 //=======================================================================
237 // name : setSelectionMode
238 // Purpose : Set selection mode
239 //=======================================================================
240 void SMESHGUI_SelectionOp::setSelectionMode( const Selection_Mode mode )
242 SVTK_ViewWindow* wnd = viewWindow();
244 wnd->SetSelectionMode( mode );
247 //=======================================================================
249 // Purpose : Highlight object in 3d viewer
250 //=======================================================================
251 void SMESHGUI_SelectionOp::highlight( const Handle( SALOME_InteractiveObject )& obj,
252 const bool hilight, const bool immediately )
254 SVTK_ViewWindow* wnd = viewWindow();
256 wnd->highlight( obj, hilight, immediately );
259 //=======================================================================
260 // name : addOrRemoveIndex
261 // Purpose : Select/deselect cells of mesh
262 //=======================================================================
263 void SMESHGUI_SelectionOp::addOrRemoveIndex( const Handle( SALOME_InteractiveObject )& obj,
264 const TColStd_MapOfInteger& indices,
265 const bool isModeShift )
267 SVTK_Selector* sel = selector();
269 sel->AddOrRemoveIndex( obj, indices, isModeShift );
272 //=======================================================================
274 // Purpose : Get active view window
275 //=======================================================================
276 SVTK_ViewWindow* SMESHGUI_SelectionOp::viewWindow() const
278 return SMESH::GetViewWindow( getSMESHGUI() );
281 //=======================================================================
283 // Purpose : Get selector
284 //=======================================================================
285 SVTK_Selector* SMESHGUI_SelectionOp::selector() const
287 SVTK_ViewWindow* wnd = viewWindow();
288 return wnd ? wnd->GetSelector() : 0;
291 //=======================================================================
293 // Purpose : Find type by id
294 //=======================================================================
295 int SMESHGUI_SelectionOp::typeById( const QString& str, const EntityType objtype ) const
297 SalomeApp_Study* _study = dynamic_cast<SalomeApp_Study*>( study() );
301 _PTR( Study ) st = _study->studyDS();
304 if( objtype == Object )
306 SalomeApp_Study* _study = dynamic_cast<SalomeApp_Study*>( study() );
309 int t = SMESHGUI_Selection::type( str, _study->studyDS() );
312 //try to get GEOM type
313 _PTR( SObject ) sobj = st->FindObjectID( str.toLatin1().data() );
316 GEOM::GEOM_Object_var obj = GEOM::GEOM_Object::_narrow(
317 dynamic_cast<SALOMEDS_SObject*>( sobj.get() )->GetObject() );
318 if( !CORBA::is_nil( obj ) )
319 res = SMESHGUI_Dialog::prefix( "GEOM" ) + obj->GetType();
323 res = SMESHGUI_Dialog::prefix( "SMESH" ) + t;
328 int pos = str.indexOf( idChar() );
329 QString entry = str.left( pos ),
330 _id = str.mid( pos+1 );
332 int id = _id.toInt( &ok );
335 _PTR( SObject ) sobj = st->FindObjectID( entry.toLatin1().data() );
336 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow(
337 dynamic_cast<SALOMEDS_SObject*>( sobj.get() )->GetObject() );
338 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow(
339 dynamic_cast<SALOMEDS_SObject*>( sobj.get() )->GetObject() );
340 if( !CORBA::is_nil( mesh ) )
341 res = SMESHGUI_Dialog::prefix( "SMESH element" ) +
342 mesh->GetElementType( id, objtype==MeshElement );
344 else if( !CORBA::is_nil( submesh ) )
345 res = SMESHGUI_Dialog::prefix( "SMESH element" ) +
346 submesh->GetElementType( id, objtype==MeshElement );
353 //=======================================================================
355 // Purpose : Get names, types and ids of selected objects
356 //=======================================================================
357 void SMESHGUI_SelectionOp::selected( QStringList& names,
358 LightApp_Dialog::TypesList& types,
359 QStringList& ids ) const
361 /* SUIT_DataOwnerPtrList list; selectionMgr()->selected( list );
362 SUIT_DataOwnerPtrList::const_iterator anIt = list.begin(),
364 for( ; anIt!=aLast; anIt++ )
366 LightApp_DataOwner* owner = dynamic_cast<LightApp_DataOwner*>( (*anIt).operator->() );
367 LightApp_SVTKDataOwner* vtkowner = dynamic_cast<LightApp_SVTKDataOwner*>( (*anIt).operator->() );
371 QString id_str = QString( "%1%2%3" ).arg( vtkowner->entry() ).arg( idChar() ), current_id_str;
372 Selection_Mode mode = vtkowner->GetMode();
373 EntityType objtype = mode == NodeSelection ? MeshNode : MeshElement;
374 const TColStd_IndexedMapOfInteger& ownerids = vtkowner->GetIds();
376 for( int i=1, n=ownerids.Extent(); i<=n; i++ )
378 int curid = ownerids( i );
379 current_id_str = id_str.arg( curid );
380 ids.append( current_id_str );
381 types.append( typeById( current_id_str, objtype ) );
382 names.append( QString( "%1" ).arg( curid ) );
388 QString id = owner->entry();
390 types.append( typeById( id, Object ) );
391 names.append( owner->IO()->getName() );
395 SALOME_ListIO selObjs;
396 TColStd_IndexedMapOfInteger selIndices;
397 selectionMgr()->selectedObjects( selObjs );
398 Selection_Mode mode = selectionMode();
399 EntityType objtype = mode == NodeSelection ? MeshNode : MeshElement;
401 for( SALOME_ListIteratorOfListIO anIt( selObjs ); anIt.More(); anIt.Next() )
404 selectionMgr()->GetIndexes( anIt.Value(), selIndices );
405 if( selIndices.Extent() > 0 )
407 QString id_str = QString( "%1%2%3" ).arg( anIt.Value()->getEntry() ).arg( idChar() ), current_id_str;
408 for( int i=1, n=selIndices.Extent(); i<=n; i++ )
410 int curid = selIndices( i );
411 current_id_str = id_str.arg( curid );
412 ids.append( current_id_str );
413 types.append( typeById( current_id_str, objtype ) );
414 names.append( QString( "%1" ).arg( curid ) );
419 QString id = anIt.Value()->getEntry();
421 types.append( typeById( id, Object ) );
422 SalomeApp_Study* _study = dynamic_cast<SalomeApp_Study*>( study() );
425 _PTR(SObject) obj = _study->studyDS()->FindObjectID( anIt.Value()->getEntry() );
427 names.append( obj->GetName().c_str() );
433 //=======================================================================
435 // Purpose : Char using to divide <entry> and <id> in string id representation. By default, '#'
436 //=======================================================================
437 QChar SMESHGUI_SelectionOp::idChar() const
442 //=================================================================================
445 //=================================================================================
446 SMESH::SMESH_Mesh_var SMESHGUI_SelectionOp::mesh() const
448 if( selectionMode()==ActorSelection )
449 return SMESH::SMESH_Mesh::_nil();
451 SALOME_ListIO sel; selectionMgr()->selectedObjects( sel, SVTK_Viewer::Type() );
452 if( sel.Extent()==1 )
453 return SMESH::GetMeshByIO( sel.First() );
455 return SMESH::SMESH_Mesh::_nil();
458 //=================================================================================
461 //=================================================================================
462 SMESH_Actor* SMESHGUI_SelectionOp::actor() const
464 SMESH::SMESH_Mesh_var m = mesh();
466 return SMESH::FindActorByObject( m.in() );
471 //=================================================================================
472 // name : onTextChanged
474 //=================================================================================
475 void SMESHGUI_SelectionOp::onTextChanged( int, const QStringList& list )
480 TColStd_MapOfInteger newIndices;
482 SALOME_ListIO sel; selectionMgr()->selectedObjects( sel );
483 SMESH_Actor* anActor = actor();
484 if( sel.Extent()==0 || !anActor )
487 SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
489 IdList ids; extractIds( list, ids, '\0' );
490 IdList::const_iterator anIt = ids.begin(),
492 for( ; anIt!=aLast; anIt++ )
493 if( const SMDS_MeshNode * n = aMesh->FindNode( *anIt ) )
494 newIndices.Add( n->GetID() );
496 selector()->AddOrRemoveIndex( sel.First(), newIndices, false );
497 highlight( sel.First(), true, true );
499 QStringList names, _ids; LightApp_Dialog::TypesList types;
500 selected( names, types, _ids );
501 dlg()->selectObject( names, types, _ids, false );
504 //=================================================================================
505 // name : selectedIds
507 //=================================================================================
508 void SMESHGUI_SelectionOp::selectedIds( const int id, IdList& list ) const
513 QStringList ids; dlg()->selectedObject( id, ids );
514 extractIds( ids, list );
517 //=================================================================================
520 //=================================================================================
521 void SMESHGUI_SelectionOp::extractIds( const QStringList& ids, IdList& list, const QChar idchar )
523 QStringList::const_iterator anIt = ids.begin(),
526 for( ; anIt!=aLast; anIt++ )
529 int pos = idchar=='\0' ? -1 : id_str.indexOf( idchar );
531 if( idchar=='\0' || pos>=0 )
533 id = id_str.mid( pos+1 ).toInt();
539 //=================================================================================
542 //=================================================================================
543 void SMESHGUI_SelectionOp::extractIds( const QStringList& ids, IdList& list ) const
545 extractIds( ids, list, idChar() );