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