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