1 // Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : SMESHGUI_SelectionOp.cxx
24 // Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
27 #include "SMESHGUI_SelectionOp.h"
30 #include "SMESHGUI_VTKUtils.h"
31 #include "SMESHGUI_MeshUtils.h"
32 #include "SMESHGUI_Selection.h"
34 #include <SMESH_Actor.h>
35 #include <SMDS_Mesh.hxx>
36 #include <SMDS_MeshNode.hxx>
38 // SALOME GUI includes
39 #include <SUIT_SelectionFilter.h>
40 #include <LightApp_SelectionMgr.h>
41 #include <SalomeApp_Study.h>
42 #include <SVTK_ViewWindow.h>
43 #include <SVTK_ViewModel.h>
45 #include <SALOME_ListIO.hxx>
47 // SALOME KERNEL includes
48 #include <SALOMEDS_SObject.hxx>
51 Class : SMESHGUI_SelectionOp
52 Description : Base operation for all operations using object selection in viewer or objectbrowser
53 through common widgets created by LightApp_Dialog::createObject
56 //=================================================================================
57 // name : SMESHGUI_SelectionOp
59 //=================================================================================
60 SMESHGUI_SelectionOp::SMESHGUI_SelectionOp( const Selection_Mode mode )
61 : SMESHGUI_Operation(),
62 myDefSelectionMode( mode )
66 //=================================================================================
67 // name : ~SMESHGUI_SelectionOp
69 //=================================================================================
70 SMESHGUI_SelectionOp::~SMESHGUI_SelectionOp()
72 removeCustomFilters();
75 //=================================================================================
76 // name : startOperation
78 //=================================================================================
79 void SMESHGUI_SelectionOp::startOperation()
81 myOldSelectionMode = selectionMode();
82 setSelectionMode( myDefSelectionMode );
84 SMESHGUI_Operation::startOperation();
87 disconnect( dlg(), SIGNAL( objectActivated( int ) ), this, SLOT( onActivateObject( int ) ) );
88 disconnect( dlg(), SIGNAL( objectDeactivated( int ) ), this, SLOT( onDeactivateObject( int ) ) );
89 disconnect( dlg(), SIGNAL( selectionChanged( int ) ), this, SLOT( onSelectionChanged( int ) ) );
90 connect( dlg(), SIGNAL( objectActivated( int ) ), this, SLOT( onActivateObject( int ) ) );
91 connect( dlg(), SIGNAL( objectDeactivated( int ) ), this, SLOT( onDeactivateObject( int ) ) );
92 connect( dlg(), SIGNAL( selectionChanged( int ) ), this, SLOT( onSelectionChanged( int ) ) );
96 //=================================================================================
97 // name : removeCustomFilters
99 //=================================================================================
100 void SMESHGUI_SelectionOp::removeCustomFilters()
102 if (myFilters.count() > 0) {
103 LightApp_SelectionMgr* mgr = selectionMgr();
104 Filters::const_iterator anIt = myFilters.begin(),
105 aLast = myFilters.end();
106 for ( ; anIt != aLast; anIt++) {
108 if (mgr) mgr->removeFilter(anIt.value());
117 //=================================================================================
118 // name : commitOperation
120 //=================================================================================
121 void SMESHGUI_SelectionOp::commitOperation()
123 SMESHGUI_Operation::commitOperation();
124 removeCustomFilters();
125 setSelectionMode( myOldSelectionMode );
128 //=================================================================================
129 // name : abortOperation
131 //=================================================================================
132 void SMESHGUI_SelectionOp::abortOperation()
134 SMESHGUI_Operation::abortOperation();
135 removeCustomFilters();
136 setSelectionMode( myOldSelectionMode );
139 //=================================================================================
140 // name : selectionDone
142 //=================================================================================
143 void SMESHGUI_SelectionOp::selectionDone()
148 if( selectionMode()!=ActorSelection )
151 selectionMgr()->selectedObjects( aList, SVTK_Viewer::Type() );
153 if( aList.Extent() != 1 ) //we can select nodes or elements only within one mesh
155 dlg()->clearSelection();
160 QStringList names, ids;
161 LightApp_Dialog::TypesList types;
162 selected( names, types, ids );
163 dlg()->selectObject( names, types, ids );
166 //=================================================================================
167 // name : createFilter
169 //=================================================================================
170 SUIT_SelectionFilter* SMESHGUI_SelectionOp::createFilter( const int ) const
175 //=================================================================================
176 // name : onActivateObject
178 //=================================================================================
179 void SMESHGUI_SelectionOp::onActivateObject( int id )
181 LightApp_SelectionMgr* mgr = selectionMgr();
185 if( !myFilters.contains( id ) )
186 myFilters[ id ] = createFilter( id );
188 if( myFilters[ id ] )
189 mgr->installFilter( myFilters[ id ] );
194 //=================================================================================
195 // name : onDeactivateObject
197 //=================================================================================
198 void SMESHGUI_SelectionOp::onDeactivateObject( int /*id*/ )
200 removeCustomFilters();
203 //=================================================================================
206 //=================================================================================
207 void SMESHGUI_SelectionOp::initDialog()
211 dlg()->clearSelection();
212 dlg()->deactivateAll();
216 //=================================================================================
219 //=================================================================================
220 void SMESHGUI_SelectionOp::onSelectionChanged( int )
224 //=======================================================================
225 // name : selectionMode
226 // Purpose : Returns selection mode
227 //=======================================================================
228 Selection_Mode SMESHGUI_SelectionOp::selectionMode() const
230 SVTK_ViewWindow* wnd = viewWindow();
232 return wnd->SelectionMode();
234 return ActorSelection;
237 //=======================================================================
238 // name : setSelectionMode
239 // Purpose : Set selection mode
240 //=======================================================================
241 void SMESHGUI_SelectionOp::setSelectionMode( const Selection_Mode mode )
243 SVTK_ViewWindow* wnd = viewWindow();
245 wnd->SetSelectionMode( mode );
248 //=======================================================================
250 // Purpose : Highlight object in 3d viewer
251 //=======================================================================
252 void SMESHGUI_SelectionOp::highlight( const Handle( SALOME_InteractiveObject )& obj,
253 const bool highlight, const bool immediately )
255 SVTK_ViewWindow* wnd = viewWindow();
257 wnd->highlight( obj, highlight, immediately );
260 //=======================================================================
261 // name : addOrRemoveIndex
262 // Purpose : Select/deselect cells of mesh
263 //=======================================================================
264 void SMESHGUI_SelectionOp::addOrRemoveIndex( const Handle( SALOME_InteractiveObject )& obj,
265 const SVTK_TVtkIDsMap& indices,
266 const bool isModeShift )
268 SVTK_Selector* sel = selector();
270 sel->AddOrRemoveIndex( obj, indices, isModeShift );
273 //=======================================================================
275 // Purpose : Get active view window
276 //=======================================================================
277 SVTK_ViewWindow* SMESHGUI_SelectionOp::viewWindow() const
279 return SMESH::GetViewWindow( getSMESHGUI() );
282 //=======================================================================
284 // Purpose : Get selector
285 //=======================================================================
286 SVTK_Selector* SMESHGUI_SelectionOp::selector() const
288 SVTK_ViewWindow* wnd = viewWindow();
289 return wnd ? wnd->GetSelector() : 0;
292 //=======================================================================
294 // Purpose : Find type by id
295 //=======================================================================
296 int SMESHGUI_SelectionOp::typeById( const QString& str, const EntityType objtype ) const
298 _PTR(Study) aStudy = SMESH::getStudy();
301 if( objtype == Object )
303 int t = SMESHGUI_Selection::type( str );
306 //try to get GEOM type
307 _PTR( SObject ) sobj = aStudy->FindObjectID( str.toUtf8().data() );
310 GEOM::GEOM_Object_var obj = GEOM::GEOM_Object::_narrow(
311 dynamic_cast<SALOMEDS_SObject*>( sobj.get() )->GetObject() );
312 if( !CORBA::is_nil( obj ) )
313 // as decoding of type id is not realized in LightApp_Dialog,
314 //make all GEOM objects have same type id
315 res = SMESHGUI_Dialog::prefix( "GEOM" );// + obj->GetType();
319 res = SMESHGUI_Dialog::prefix( "SMESH" ) + t;
323 int pos = str.indexOf( idChar() );
324 QString entry = str.left( pos ),
325 _id = str.mid( pos+1 );
327 int id = _id.toInt( &ok );
330 _PTR( SObject ) sobj = aStudy->FindObjectID( entry.toUtf8().data() );
331 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow(
332 dynamic_cast<SALOMEDS_SObject*>( sobj.get() )->GetObject() );
333 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow(
334 dynamic_cast<SALOMEDS_SObject*>( sobj.get() )->GetObject() );
335 if( !CORBA::is_nil( mesh ) )
336 res = SMESHGUI_Dialog::prefix( "SMESH element" ) +
337 mesh->GetElementType( id, objtype==MeshElement );
339 else if( !CORBA::is_nil( submesh ) )
340 res = SMESHGUI_Dialog::prefix( "SMESH element" ) +
341 submesh->GetElementType( id, objtype==MeshElement );
348 //=======================================================================
350 // Purpose : Get names, types and ids of selected objects
351 //=======================================================================
352 void SMESHGUI_SelectionOp::selected( QStringList& names,
353 LightApp_Dialog::TypesList& types,
354 QStringList& ids ) const
356 /* SUIT_DataOwnerPtrList list; selectionMgr()->selected( list );
357 SUIT_DataOwnerPtrList::const_iterator anIt = list.begin(),
359 for( ; anIt!=aLast; anIt++ )
361 LightApp_DataOwner* owner = dynamic_cast<LightApp_DataOwner*>( (*anIt).operator->() );
362 LightApp_SVTKDataOwner* vtkowner = dynamic_cast<LightApp_SVTKDataOwner*>( (*anIt).operator->() );
366 QString id_str = QString( "%1%2%3" ).arg( vtkowner->entry() ).arg( idChar() ), current_id_str;
367 Selection_Mode mode = vtkowner->GetMode();
368 EntityType objtype = mode == NodeSelection ? MeshNode : MeshElement;
369 const TColStd_IndexedMapOfInteger& ownerids = vtkowner->GetIds();
371 for( int i=1, n=ownerids.Extent(); i<=n; i++ )
373 int curid = ownerids( i );
374 current_id_str = id_str.arg( curid );
375 ids.append( current_id_str );
376 types.append( typeById( current_id_str, objtype ) );
377 names.append( QString( "%1" ).arg( curid ) );
383 QString id = owner->entry();
385 types.append( typeById( id, Object ) );
386 names.append( owner->IO()->getName() );
390 SALOME_ListIO selObjs;
391 TColStd_IndexedMapOfInteger selIndices;
392 selectionMgr()->selectedObjects( selObjs );
393 Selection_Mode mode = selectionMode();
394 EntityType objtype = mode == NodeSelection ? MeshNode : MeshElement;
396 for( SALOME_ListIteratorOfListIO anIt( selObjs ); anIt.More(); anIt.Next() )
399 selectionMgr()->GetIndexes( anIt.Value(), selIndices );
400 if( selIndices.Extent() > 0 )
402 QString id_str = QString( "%1%2%3" ).arg( anIt.Value()->getEntry() ).arg( idChar() ), current_id_str;
403 for( int i=1, n=selIndices.Extent(); i<=n; i++ )
405 int curid = selIndices( i );
406 current_id_str = id_str.arg( curid );
407 ids.append( current_id_str );
408 types.append( typeById( current_id_str, objtype ) );
409 names.append( QString( "%1" ).arg( curid ) );
414 QString id = anIt.Value()->getEntry();
416 types.append( typeById( id, Object ) );
417 _PTR(SObject) obj = SMESH::getStudy()->FindObjectID( anIt.Value()->getEntry() );
419 names.append( QString( obj->GetName().c_str() ).trimmed() );
424 //=======================================================================
426 // Purpose : Char using to divide <entry> and <id> in string id representation. By default, '#'
427 //=======================================================================
428 QChar SMESHGUI_SelectionOp::idChar() const
433 //=================================================================================
436 //=================================================================================
437 SMESH::SMESH_Mesh_var SMESHGUI_SelectionOp::mesh() const
439 if( selectionMode()==ActorSelection )
440 return SMESH::SMESH_Mesh::_nil();
442 SALOME_ListIO sel; selectionMgr()->selectedObjects( sel, SVTK_Viewer::Type() );
443 if( sel.Extent()==1 )
444 return SMESH::GetMeshByIO( sel.First() );
446 return SMESH::SMESH_Mesh::_nil();
449 //=================================================================================
452 //=================================================================================
453 SMESH_Actor* SMESHGUI_SelectionOp::actor() const
455 SMESH::SMESH_Mesh_var m = mesh();
457 return SMESH::FindActorByObject( m.in() );
462 //=================================================================================
463 // name : onTextChanged
465 //=================================================================================
466 void SMESHGUI_SelectionOp::onTextChanged( int, const QStringList& list )
471 SVTK_TVtkIDsMap newIndices;
473 SALOME_ListIO sel; selectionMgr()->selectedObjects( sel );
474 SMESH_Actor* anActor = actor();
475 if( sel.Extent()==0 || !anActor )
478 SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
480 IdList ids; extractIds( list, ids, '\0' );
481 IdList::const_iterator anIt = ids.begin(),
483 if ( selectionMode() == NodeSelection )
484 for( ; anIt!=aLast; anIt++ ) {
485 if( const SMDS_MeshNode * n = aMesh->FindNode( *anIt ) )
486 newIndices.Add( n->GetID() );
489 for( ; anIt!=aLast; anIt++ ) {
490 if( const SMDS_MeshElement* e = aMesh->FindElement( *anIt ) )
491 newIndices.Add( e->GetID() );
494 selector()->AddOrRemoveIndex( sel.First(), newIndices, false );
495 highlight( sel.First(), true, true );
497 QStringList names, _ids; LightApp_Dialog::TypesList types;
498 selected( names, types, _ids );
499 dlg()->selectObject( names, types, _ids, false );
502 //=================================================================================
503 // name : selectedIds
505 //=================================================================================
506 void SMESHGUI_SelectionOp::selectedIds( const int id, IdList& list ) const
511 QStringList ids; dlg()->selectedObject( id, ids );
512 extractIds( ids, list );
515 //=================================================================================
518 //=================================================================================
519 void SMESHGUI_SelectionOp::extractIds( const QStringList& ids, IdList& list, const QChar idchar )
521 QStringList::const_iterator anIt = ids.begin(),
524 for( ; anIt!=aLast; anIt++ )
527 int pos = idchar=='\0' ? -1 : id_str.indexOf( idchar );
529 if( idchar=='\0' || pos>=0 )
531 id = id_str.mid( pos+1 ).toInt();
537 //=================================================================================
540 //=================================================================================
541 void SMESHGUI_SelectionOp::extractIds( const QStringList& ids, IdList& list ) const
543 extractIds( ids, list, idChar() );