Salome HOME
9bb99a77b0fab6fbac52a8e359fd5900d6381f42
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_SelectionOp.cxx
1 // Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
3 //
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. 
8 //
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. 
13 //
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 
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 // File   : SMESHGUI_SelectionOp.cxx
21 // Author : Alexander SOLOVYOV, Open CASCADE S.A.S.
22 //
23
24 // SMESH includes
25 #include "SMESHGUI_SelectionOp.h"
26
27 #include "SMESHGUI.h"
28 #include "SMESHGUI_VTKUtils.h"
29 #include "SMESHGUI_MeshUtils.h"
30 #include "SMESHGUI_Selection.h"
31
32 #include <SMESH_Actor.h>
33 #include <SMDS_Mesh.hxx>
34 #include <SMDS_MeshNode.hxx>
35
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>
42
43 #include <SALOME_ListIO.hxx>
44 #include <SALOME_ListIteratorOfListIO.hxx>
45
46 // SALOME KERNEL includes 
47 #include <SALOMEDS_SObject.hxx>
48
49 /*
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
53 */
54
55 //=================================================================================
56 // name     : SMESHGUI_SelectionOp
57 // purpose  : 
58 //=================================================================================
59 SMESHGUI_SelectionOp::SMESHGUI_SelectionOp( const Selection_Mode mode )
60 : SMESHGUI_Operation(),
61   myDefSelectionMode( mode )
62 {
63 }
64
65 //=================================================================================
66 // name     : ~SMESHGUI_SelectionOp
67 // purpose  :
68 //=================================================================================
69 SMESHGUI_SelectionOp::~SMESHGUI_SelectionOp()
70 {
71   removeCustomFilters();
72 }
73
74 //=================================================================================
75 // name     : startOperation
76 // purpose  :
77 //=================================================================================
78 void SMESHGUI_SelectionOp::startOperation()
79 {
80   myOldSelectionMode = selectionMode();
81   setSelectionMode( myDefSelectionMode );
82
83   SMESHGUI_Operation::startOperation();
84   if( dlg() )
85   {
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 ) ) );
92   }
93 }
94
95 //=================================================================================
96 // name     : removeCustomFilters
97 // purpose  :
98 //=================================================================================
99 void SMESHGUI_SelectionOp::removeCustomFilters()
100 {
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++) {
106       if (anIt.value()) {
107         if (mgr) mgr->removeFilter(anIt.value());
108         delete anIt.value();
109       }
110     }
111
112     myFilters.clear();
113   }
114 }
115
116 //=================================================================================
117 // name     : commitOperation
118 // purpose  :
119 //=================================================================================
120 void SMESHGUI_SelectionOp::commitOperation()
121 {
122   SMESHGUI_Operation::commitOperation();  
123   removeCustomFilters();
124   setSelectionMode( myOldSelectionMode );
125 }
126
127 //=================================================================================
128 // name     : abortOperation
129 // purpose  :
130 //=================================================================================
131 void SMESHGUI_SelectionOp::abortOperation()
132 {
133   SMESHGUI_Operation::abortOperation();
134   removeCustomFilters();
135   setSelectionMode( myOldSelectionMode );  
136 }
137
138 //=================================================================================
139 // name     : selectionDone
140 // purpose  :
141 //=================================================================================
142 void SMESHGUI_SelectionOp::selectionDone()
143 {
144   if( !dlg() )
145     return;
146
147   if( selectionMode()!=ActorSelection )
148   {
149     SALOME_ListIO aList;
150     selectionMgr()->selectedObjects( aList, SVTK_Viewer::Type() );
151
152     if( aList.Extent() != 1 ) //we can select nodes or elements only within one mesh
153     {
154       dlg()->clearSelection();
155       return;
156     }    
157   }
158     
159   QStringList names, ids;
160   LightApp_Dialog::TypesList types;
161   selected( names, types, ids );
162   dlg()->selectObject( names, types, ids );
163 }
164
165 //=================================================================================
166 // name     : createFilter
167 // purpose  :
168 //=================================================================================
169 SUIT_SelectionFilter* SMESHGUI_SelectionOp::createFilter( const int ) const
170 {
171   return 0;
172 }
173
174 //=================================================================================
175 // name     : onActivateObject
176 // purpose  :
177 //=================================================================================
178 void SMESHGUI_SelectionOp::onActivateObject( int id )
179 {
180   LightApp_SelectionMgr* mgr = selectionMgr();
181   if( !mgr )
182     return;
183     
184   if( !myFilters.contains( id ) )
185     myFilters[ id ] = createFilter( id );
186
187   if( myFilters[ id ] )
188     mgr->installFilter( myFilters[ id ] );
189
190   selectionDone();
191 }
192
193 //=================================================================================
194 // name     : onDeactivateObject
195 // purpose  :
196 //=================================================================================
197 void SMESHGUI_SelectionOp::onDeactivateObject( int id )
198 {
199   removeCustomFilters();
200 }
201
202 //=================================================================================
203 // name     : initDialog
204 // purpose  :
205 //=================================================================================
206 void SMESHGUI_SelectionOp::initDialog()
207 {
208   if( dlg() )
209   {
210     dlg()->clearSelection();
211     dlg()->deactivateAll();
212   }
213 }
214
215 //=================================================================================
216 // name     : initDialog
217 // purpose  :
218 //=================================================================================
219 void SMESHGUI_SelectionOp::onSelectionChanged( int )
220 {
221 }
222
223 //=======================================================================
224 // name    : selectionMode
225 // Purpose : Returns selection mode
226 //=======================================================================
227 Selection_Mode SMESHGUI_SelectionOp::selectionMode() const
228 {
229   SVTK_ViewWindow* wnd = viewWindow();
230   if( wnd )
231     return wnd->SelectionMode();
232   else
233     return ActorSelection;
234 }
235
236 //=======================================================================
237 // name    : setSelectionMode
238 // Purpose : Set selection mode
239 //=======================================================================
240 void SMESHGUI_SelectionOp::setSelectionMode( const Selection_Mode mode )
241 {
242   SVTK_ViewWindow* wnd = viewWindow();
243   if( wnd )
244     wnd->SetSelectionMode( mode );
245 }
246
247 //=======================================================================
248 // name    : highlight
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 )
253 {
254   SVTK_ViewWindow* wnd = viewWindow();
255   if( wnd )
256     wnd->highlight( obj, hilight, immediately );
257 }
258
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 )
266 {
267   SVTK_Selector* sel = selector();
268   if( sel )
269     sel->AddOrRemoveIndex( obj, indices, isModeShift );
270 }
271
272 //=======================================================================
273 // name    : viewWindow
274 // Purpose : Get active view window
275 //=======================================================================
276 SVTK_ViewWindow* SMESHGUI_SelectionOp::viewWindow() const
277 {
278   return SMESH::GetViewWindow( getSMESHGUI() );
279 }
280
281 //=======================================================================
282 // name    : selector
283 // Purpose : Get selector
284 //=======================================================================
285 SVTK_Selector* SMESHGUI_SelectionOp::selector() const
286 {
287   SVTK_ViewWindow* wnd = viewWindow();
288   return wnd ? wnd->GetSelector() : 0;
289 }
290
291 //=======================================================================
292 // name    : typeById
293 // Purpose : Find type by id
294 //=======================================================================
295 int SMESHGUI_SelectionOp::typeById( const QString& str, const EntityType objtype ) const
296 {
297   SalomeApp_Study* _study = dynamic_cast<SalomeApp_Study*>( study() );
298   if( !_study )
299     return -1;
300
301   _PTR( Study ) st = _study->studyDS();
302
303   int res = -1;
304   if( objtype == Object )
305   {
306     SalomeApp_Study* _study = dynamic_cast<SalomeApp_Study*>( study() );
307     if( _study )
308     {
309       int t = SMESHGUI_Selection::type( str, _study->studyDS() );
310       if( t<0 )
311       {
312         //try to get GEOM type
313         _PTR( SObject ) sobj = st->FindObjectID( str.toLatin1().data() );
314         if( sobj )
315         {
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();
320         }
321       }
322       else
323         res = SMESHGUI_Dialog::prefix( "SMESH" ) + t;
324     }
325   }
326   else
327   {
328     int pos = str.indexOf( idChar() );
329     QString entry = str.left( pos ),
330             _id = str.mid( pos+1 );
331     bool ok;
332     int id = _id.toInt( &ok );
333     if( ok )
334     {
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 );
343
344       else if( !CORBA::is_nil( submesh ) )
345         res = SMESHGUI_Dialog::prefix( "SMESH element" ) + 
346           submesh->GetElementType( id, objtype==MeshElement );
347     }
348   }
349
350   return res;
351 }
352
353 //=======================================================================
354 // name    : selected
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
360 {
361 /*  SUIT_DataOwnerPtrList list; selectionMgr()->selected( list );
362   SUIT_DataOwnerPtrList::const_iterator anIt = list.begin(),
363                                         aLast = list.end();
364   for( ; anIt!=aLast; anIt++ )
365   {
366     LightApp_DataOwner* owner = dynamic_cast<LightApp_DataOwner*>( (*anIt).operator->() );
367     LightApp_SVTKDataOwner* vtkowner = dynamic_cast<LightApp_SVTKDataOwner*>( (*anIt).operator->() );
368
369     if( vtkowner )
370     {
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();
375
376       for( int i=1, n=ownerids.Extent(); i<=n; i++ )
377       {
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 ) );
383       }
384     }
385
386     else if( owner )
387     {
388       QString id = owner->entry();
389       ids.append( id );
390       types.append( typeById( id, Object ) );
391       names.append( owner->IO()->getName() );
392     }
393   }*/
394
395   SALOME_ListIO selObjs;
396   TColStd_IndexedMapOfInteger selIndices;
397   selectionMgr()->selectedObjects( selObjs );
398   Selection_Mode mode = selectionMode();
399   EntityType objtype = mode == NodeSelection ? MeshNode : MeshElement;
400
401   for( SALOME_ListIteratorOfListIO anIt( selObjs ); anIt.More(); anIt.Next() )
402   {
403     selIndices.Clear();
404     selectionMgr()->GetIndexes( anIt.Value(), selIndices );
405     if( selIndices.Extent() > 0 )
406     {
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++ )
409       {
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 ) );
415       }
416     }
417     else
418     {
419       QString id = anIt.Value()->getEntry();
420       ids.append( id );
421       types.append( typeById( id, Object ) );
422       SalomeApp_Study* _study = dynamic_cast<SalomeApp_Study*>( study() );
423       if( _study )
424       {
425         _PTR(SObject) obj = _study->studyDS()->FindObjectID( anIt.Value()->getEntry() );
426         if( obj )
427           names.append( obj->GetName().c_str() );
428       }
429     }
430   }
431 }
432
433 //=======================================================================
434 // name    : idChar
435 // Purpose : Char using to divide <entry> and <id> in string id representation. By default, '#'
436 //=======================================================================
437 QChar SMESHGUI_SelectionOp::idChar() const
438 {
439   return '#';
440 }
441
442 //=================================================================================
443 // name     : mesh
444 // purpose  :
445 //=================================================================================
446 SMESH::SMESH_Mesh_var SMESHGUI_SelectionOp::mesh() const
447 {
448   if( selectionMode()==ActorSelection )
449     return SMESH::SMESH_Mesh::_nil();
450     
451   SALOME_ListIO sel; selectionMgr()->selectedObjects( sel, SVTK_Viewer::Type() );
452   if( sel.Extent()==1 )
453     return SMESH::GetMeshByIO( sel.First() );
454   else
455     return SMESH::SMESH_Mesh::_nil();
456 }
457
458 //=================================================================================
459 // name     : actor
460 // purpose  :
461 //=================================================================================
462 SMESH_Actor* SMESHGUI_SelectionOp::actor() const
463 {
464   SMESH::SMESH_Mesh_var m = mesh();
465   if( !m->_is_nil() )
466     return SMESH::FindActorByObject( m.in() );
467   else
468     return 0;
469 }
470
471 //=================================================================================
472 // name     : onTextChanged
473 // purpose  :
474 //=================================================================================
475 void SMESHGUI_SelectionOp::onTextChanged( int, const QStringList& list )
476 {
477     if( !dlg() )
478       return;
479
480     TColStd_MapOfInteger newIndices;
481
482     SALOME_ListIO sel; selectionMgr()->selectedObjects( sel );
483     SMESH_Actor* anActor = actor();
484     if( sel.Extent()==0 || !anActor )
485       return;
486
487     SMDS_Mesh* aMesh = anActor->GetObject()->GetMesh();
488
489     IdList ids; extractIds( list, ids, '\0' );
490     IdList::const_iterator anIt = ids.begin(),
491                            aLast = ids.end();
492     for( ; anIt!=aLast; anIt++ )
493       if( const SMDS_MeshNode * n = aMesh->FindNode( *anIt ) )
494         newIndices.Add( n->GetID() );
495
496     selector()->AddOrRemoveIndex( sel.First(), newIndices, false );
497     highlight( sel.First(), true, true );
498
499     QStringList names, _ids; LightApp_Dialog::TypesList types;
500     selected( names, types, _ids );
501     dlg()->selectObject( names, types, _ids, false );
502 }
503
504 //=================================================================================
505 // name     : selectedIds
506 // purpose  :
507 //=================================================================================
508 void SMESHGUI_SelectionOp::selectedIds( const int id, IdList& list ) const
509 {
510   if( !dlg() )
511     return;
512
513   QStringList ids; dlg()->selectedObject( id, ids );
514   extractIds( ids, list );
515 }
516
517 //=================================================================================
518 // name     : extractIds
519 // purpose  :
520 //=================================================================================
521 void SMESHGUI_SelectionOp::extractIds( const QStringList& ids, IdList& list, const QChar idchar )
522 {
523   QStringList::const_iterator anIt = ids.begin(),
524                               aLast = ids.end();
525   QString id_str;
526   for( ; anIt!=aLast; anIt++ )
527   {
528     id_str = *anIt;
529     int pos = idchar=='\0' ? -1 : id_str.indexOf( idchar );
530     int id = -1;
531     if( idchar=='\0' || pos>=0 )
532     {
533       id = id_str.mid( pos+1 ).toInt();
534       list.append( id );
535     }
536   }
537 }
538
539 //=================================================================================
540 // name     : extractIds
541 // purpose  :
542 //=================================================================================
543 void SMESHGUI_SelectionOp::extractIds( const QStringList& ids, IdList& list ) const
544 {
545   extractIds( ids, list, idChar() );
546 }