1 // Copyright (C) 2007-2014 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>
46 #include <SALOME_ListIteratorOfListIO.hxx>
48 // SALOME KERNEL includes
49 #include <SALOMEDS_SObject.hxx>
52 Class : SMESHGUI_SelectionOp
53 Description : Base operation for all operations using object selection in viewer or objectbrowser
54 through common widgets created by LightApp_Dialog::createObject
57 //=================================================================================
58 // name : SMESHGUI_SelectionOp
60 //=================================================================================
61 SMESHGUI_SelectionOp::SMESHGUI_SelectionOp( const Selection_Mode mode )
62 : SMESHGUI_Operation(),
63 myDefSelectionMode( mode )
67 //=================================================================================
68 // name : ~SMESHGUI_SelectionOp
70 //=================================================================================
71 SMESHGUI_SelectionOp::~SMESHGUI_SelectionOp()
73 removeCustomFilters();
76 //=================================================================================
77 // name : startOperation
79 //=================================================================================
80 void SMESHGUI_SelectionOp::startOperation()
82 myOldSelectionMode = selectionMode();
83 setSelectionMode( myDefSelectionMode );
85 SMESHGUI_Operation::startOperation();
88 disconnect( dlg(), SIGNAL( objectActivated( int ) ), this, SLOT( onActivateObject( int ) ) );
89 disconnect( dlg(), SIGNAL( objectDeactivated( int ) ), this, SLOT( onDeactivateObject( int ) ) );
90 disconnect( dlg(), SIGNAL( selectionChanged( int ) ), this, SLOT( onSelectionChanged( int ) ) );
91 connect( dlg(), SIGNAL( objectActivated( int ) ), this, SLOT( onActivateObject( int ) ) );
92 connect( dlg(), SIGNAL( objectDeactivated( int ) ), this, SLOT( onDeactivateObject( int ) ) );
93 connect( dlg(), SIGNAL( selectionChanged( int ) ), this, SLOT( onSelectionChanged( int ) ) );
97 //=================================================================================
98 // name : removeCustomFilters
100 //=================================================================================
101 void SMESHGUI_SelectionOp::removeCustomFilters()
103 if (myFilters.count() > 0) {
104 LightApp_SelectionMgr* mgr = selectionMgr();
105 Filters::const_iterator anIt = myFilters.begin(),
106 aLast = myFilters.end();
107 for ( ; anIt != aLast; anIt++) {
109 if (mgr) mgr->removeFilter(anIt.value());
118 //=================================================================================
119 // name : commitOperation
121 //=================================================================================
122 void SMESHGUI_SelectionOp::commitOperation()
124 SMESHGUI_Operation::commitOperation();
125 removeCustomFilters();
126 setSelectionMode( myOldSelectionMode );
129 //=================================================================================
130 // name : abortOperation
132 //=================================================================================
133 void SMESHGUI_SelectionOp::abortOperation()
135 SMESHGUI_Operation::abortOperation();
136 removeCustomFilters();
137 setSelectionMode( myOldSelectionMode );
140 //=================================================================================
141 // name : selectionDone
143 //=================================================================================
144 void SMESHGUI_SelectionOp::selectionDone()
149 if( selectionMode()!=ActorSelection )
152 selectionMgr()->selectedObjects( aList, SVTK_Viewer::Type() );
154 if( aList.Extent() != 1 ) //we can select nodes or elements only within one mesh
156 dlg()->clearSelection();
161 QStringList names, ids;
162 LightApp_Dialog::TypesList types;
163 selected( names, types, ids );
164 dlg()->selectObject( names, types, ids );
167 //=================================================================================
168 // name : createFilter
170 //=================================================================================
171 SUIT_SelectionFilter* SMESHGUI_SelectionOp::createFilter( const int ) const
176 //=================================================================================
177 // name : onActivateObject
179 //=================================================================================
180 void SMESHGUI_SelectionOp::onActivateObject( int id )
182 LightApp_SelectionMgr* mgr = selectionMgr();
186 if( !myFilters.contains( id ) )
187 myFilters[ id ] = createFilter( id );
189 if( myFilters[ id ] )
190 mgr->installFilter( myFilters[ id ] );
195 //=================================================================================
196 // name : onDeactivateObject
198 //=================================================================================
199 void SMESHGUI_SelectionOp::onDeactivateObject( int id )
201 removeCustomFilters();
204 //=================================================================================
207 //=================================================================================
208 void SMESHGUI_SelectionOp::initDialog()
212 dlg()->clearSelection();
213 dlg()->deactivateAll();
217 //=================================================================================
220 //=================================================================================
221 void SMESHGUI_SelectionOp::onSelectionChanged( int )
225 //=======================================================================
226 // name : selectionMode
227 // Purpose : Returns selection mode
228 //=======================================================================
229 Selection_Mode SMESHGUI_SelectionOp::selectionMode() const
231 SVTK_ViewWindow* wnd = viewWindow();
233 return wnd->SelectionMode();
235 return ActorSelection;
238 //=======================================================================
239 // name : setSelectionMode
240 // Purpose : Set selection mode
241 //=======================================================================
242 void SMESHGUI_SelectionOp::setSelectionMode( const Selection_Mode mode )
244 SVTK_ViewWindow* wnd = viewWindow();
246 wnd->SetSelectionMode( mode );
249 //=======================================================================
251 // Purpose : Highlight object in 3d viewer
252 //=======================================================================
253 void SMESHGUI_SelectionOp::highlight( const Handle( SALOME_InteractiveObject )& obj,
254 const bool hilight, const bool immediately )
256 SVTK_ViewWindow* wnd = viewWindow();
258 wnd->highlight( obj, hilight, immediately );
261 //=======================================================================
262 // name : addOrRemoveIndex
263 // Purpose : Select/deselect cells of mesh
264 //=======================================================================
265 void SMESHGUI_SelectionOp::addOrRemoveIndex( const Handle( SALOME_InteractiveObject )& obj,
266 const TColStd_MapOfInteger& indices,
267 const bool isModeShift )
269 SVTK_Selector* sel = selector();
271 sel->AddOrRemoveIndex( obj, indices, isModeShift );
274 //=======================================================================
276 // Purpose : Get active view window
277 //=======================================================================
278 SVTK_ViewWindow* SMESHGUI_SelectionOp::viewWindow() const
280 return SMESH::GetViewWindow( getSMESHGUI() );
283 //=======================================================================
285 // Purpose : Get selector
286 //=======================================================================
287 SVTK_Selector* SMESHGUI_SelectionOp::selector() const
289 SVTK_ViewWindow* wnd = viewWindow();
290 return wnd ? wnd->GetSelector() : 0;
293 //=======================================================================
295 // Purpose : Find type by id
296 //=======================================================================
297 int SMESHGUI_SelectionOp::typeById( const QString& str, const EntityType objtype ) const
299 SalomeApp_Study* _study = dynamic_cast<SalomeApp_Study*>( study() );
303 _PTR( Study ) st = _study->studyDS();
306 if( objtype == Object )
308 SalomeApp_Study* _study = dynamic_cast<SalomeApp_Study*>( study() );
311 int t = SMESHGUI_Selection::type( str, _study->studyDS() );
314 //try to get GEOM type
315 _PTR( SObject ) sobj = st->FindObjectID( str.toLatin1().data() );
318 GEOM::GEOM_Object_var obj = GEOM::GEOM_Object::_narrow(
319 dynamic_cast<SALOMEDS_SObject*>( sobj.get() )->GetObject() );
320 if( !CORBA::is_nil( obj ) )
321 // as decoding of type id is not realized in LightApp_Dialog,
322 //make all GEOM objects have same type id
323 res = SMESHGUI_Dialog::prefix( "GEOM" );// + obj->GetType();
327 res = SMESHGUI_Dialog::prefix( "SMESH" ) + t;
332 int pos = str.indexOf( idChar() );
333 QString entry = str.left( pos ),
334 _id = str.mid( pos+1 );
336 int id = _id.toInt( &ok );
339 _PTR( SObject ) sobj = st->FindObjectID( entry.toLatin1().data() );
340 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow(
341 dynamic_cast<SALOMEDS_SObject*>( sobj.get() )->GetObject() );
342 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow(
343 dynamic_cast<SALOMEDS_SObject*>( sobj.get() )->GetObject() );
344 if( !CORBA::is_nil( mesh ) )
345 res = SMESHGUI_Dialog::prefix( "SMESH element" ) +
346 mesh->GetElementType( id, objtype==MeshElement );
348 else if( !CORBA::is_nil( submesh ) )
349 res = SMESHGUI_Dialog::prefix( "SMESH element" ) +
350 submesh->GetElementType( id, objtype==MeshElement );
357 //=======================================================================
359 // Purpose : Get names, types and ids of selected objects
360 //=======================================================================
361 void SMESHGUI_SelectionOp::selected( QStringList& names,
362 LightApp_Dialog::TypesList& types,
363 QStringList& ids ) const
365 /* SUIT_DataOwnerPtrList list; selectionMgr()->selected( list );
366 SUIT_DataOwnerPtrList::const_iterator anIt = list.begin(),
368 for( ; anIt!=aLast; anIt++ )
370 LightApp_DataOwner* owner = dynamic_cast<LightApp_DataOwner*>( (*anIt).operator->() );
371 LightApp_SVTKDataOwner* vtkowner = dynamic_cast<LightApp_SVTKDataOwner*>( (*anIt).operator->() );
375 QString id_str = QString( "%1%2%3" ).arg( vtkowner->entry() ).arg( idChar() ), current_id_str;
376 Selection_Mode mode = vtkowner->GetMode();
377 EntityType objtype = mode == NodeSelection ? MeshNode : MeshElement;
378 const TColStd_IndexedMapOfInteger& ownerids = vtkowner->GetIds();
380 for( int i=1, n=ownerids.Extent(); i<=n; i++ )
382 int curid = ownerids( i );
383 current_id_str = id_str.arg( curid );
384 ids.append( current_id_str );
385 types.append( typeById( current_id_str, objtype ) );
386 names.append( QString( "%1" ).arg( curid ) );
392 QString id = owner->entry();
394 types.append( typeById( id, Object ) );
395 names.append( owner->IO()->getName() );
399 SALOME_ListIO selObjs;
400 TColStd_IndexedMapOfInteger selIndices;
401 selectionMgr()->selectedObjects( selObjs );
402 Selection_Mode mode = selectionMode();
403 EntityType objtype = mode == NodeSelection ? MeshNode : MeshElement;
405 for( SALOME_ListIteratorOfListIO anIt( selObjs ); anIt.More(); anIt.Next() )
408 selectionMgr()->GetIndexes( anIt.Value(), selIndices );
409 if( selIndices.Extent() > 0 )
411 QString id_str = QString( "%1%2%3" ).arg( anIt.Value()->getEntry() ).arg( idChar() ), current_id_str;
412 for( int i=1, n=selIndices.Extent(); i<=n; i++ )
414 int curid = selIndices( i );
415 current_id_str = id_str.arg( curid );
416 ids.append( current_id_str );
417 types.append( typeById( current_id_str, objtype ) );
418 names.append( QString( "%1" ).arg( curid ) );
423 QString id = anIt.Value()->getEntry();
425 types.append( typeById( id, Object ) );
426 SalomeApp_Study* _study = dynamic_cast<SalomeApp_Study*>( study() );
429 _PTR(SObject) obj = _study->studyDS()->FindObjectID( anIt.Value()->getEntry() );
431 names.append( obj->GetName().c_str() );
437 //=======================================================================
439 // Purpose : Char using to divide <entry> and <id> in string id representation. By default, '#'
440 //=======================================================================
441 QChar SMESHGUI_SelectionOp::idChar() const
446 //=================================================================================
449 //=================================================================================
450 SMESH::SMESH_Mesh_var SMESHGUI_SelectionOp::mesh() const
452 if( selectionMode()==ActorSelection )
453 return SMESH::SMESH_Mesh::_nil();
455 SALOME_ListIO sel; selectionMgr()->selectedObjects( sel, SVTK_Viewer::Type() );
456 if( sel.Extent()==1 )
457 return SMESH::GetMeshByIO( sel.First() );
459 return SMESH::SMESH_Mesh::_nil();
462 //=================================================================================
465 //=================================================================================
466 SMESH_Actor* SMESHGUI_SelectionOp::actor() const
468 SMESH::SMESH_Mesh_var m = mesh();
470 return SMESH::FindActorByObject( m.in() );
475 //=================================================================================
476 // name : onTextChanged
478 //=================================================================================
479 void SMESHGUI_SelectionOp::onTextChanged( int, const QStringList& list )
484 TColStd_MapOfInteger newIndices;
486 SALOME_ListIO sel; selectionMgr()->selectedObjects( sel );
487 SMESH_Actor* anActor = actor();
488 if( sel.Extent()==0 || !anActor )
491 SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
493 IdList ids; extractIds( list, ids, '\0' );
494 IdList::const_iterator anIt = ids.begin(),
496 if ( selectionMode() == NodeSelection )
497 for( ; anIt!=aLast; anIt++ ) {
498 if( const SMDS_MeshNode * n = aMesh->FindNode( *anIt ) )
499 newIndices.Add( n->GetID() );
502 for( ; anIt!=aLast; anIt++ ) {
503 if( const SMDS_MeshElement* e = aMesh->FindElement( *anIt ) )
504 newIndices.Add( e->GetID() );
507 selector()->AddOrRemoveIndex( sel.First(), newIndices, false );
508 highlight( sel.First(), true, true );
510 QStringList names, _ids; LightApp_Dialog::TypesList types;
511 selected( names, types, _ids );
512 dlg()->selectObject( names, types, _ids, false );
515 //=================================================================================
516 // name : selectedIds
518 //=================================================================================
519 void SMESHGUI_SelectionOp::selectedIds( const int id, IdList& list ) const
524 QStringList ids; dlg()->selectedObject( id, ids );
525 extractIds( ids, list );
528 //=================================================================================
531 //=================================================================================
532 void SMESHGUI_SelectionOp::extractIds( const QStringList& ids, IdList& list, const QChar idchar )
534 QStringList::const_iterator anIt = ids.begin(),
537 for( ; anIt!=aLast; anIt++ )
540 int pos = idchar=='\0' ? -1 : id_str.indexOf( idchar );
542 if( idchar=='\0' || pos>=0 )
544 id = id_str.mid( pos+1 ).toInt();
550 //=================================================================================
553 //=================================================================================
554 void SMESHGUI_SelectionOp::extractIds( const QStringList& ids, IdList& list ) const
556 extractIds( ids, list, idChar() );