Salome HOME
*** empty log message ***
[modules/geom.git] / src / EntityGUI / EntityGUI_SubShapeDlg.cxx
1 // GEOM GEOMGUI : GUI for Geometry component
2 //
3 // Copyright (C) 2003  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. 
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 // File   : EntityGUI_SubShapeDlg.cxx
23 // Author : Lucien PIGNOLONI, Open CASCADE S.A.S.
24 //
25
26 #include "EntityGUI_SubShapeDlg.h"
27
28 #include <GEOM_DlgRef.h>
29 #include <GeometryGUI.h>
30 #include <GEOMBase.h>
31
32 #include <SUIT_Desktop.h>
33 #include <SUIT_ResourceMgr.h>
34 #include <SUIT_Session.h>
35 #include <SUIT_ViewManager.h>
36 #include <SUIT_ViewWindow.h>
37 #include <OCCViewer_ViewModel.h>
38 #include <SalomeApp_Application.h>
39 #include <LightApp_SelectionMgr.h>
40
41 #include <TColStd_IndexedMapOfInteger.hxx>
42 #include <TopoDS_Iterator.hxx>
43 #include <TopExp_Explorer.hxx>
44 #include <TopTools_MapOfShape.hxx>
45
46 #include <QMessageBox>
47
48 //=================================================================================
49 // class    : EntityGUI_SubShapeDlg
50 // purpose  : Constructs a EntityGUI_SubShapeDlg which is a child of 'parent', with the
51 //            name 'name' and widget flags set to 'f'.
52 //            The dialog will by default be modeless, unless you set 'modal' to
53 //            TRUE to construct a modal dialog.
54 //=================================================================================
55 EntityGUI_SubShapeDlg::EntityGUI_SubShapeDlg( GeometryGUI* theGeometryGUI, QWidget* parent,
56                                               bool modal, Qt::WindowFlags fl )
57   : GEOMBase_Skeleton( theGeometryGUI, parent, modal, fl )
58 {
59   QPixmap image0( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_SUBSHAPE" ) ) );
60   QPixmap image1( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) );
61
62   setWindowTitle( tr( "GEOM_SUBSHAPE_TITLE" ) );
63
64   /***************************************************************/
65   mainFrame()->GroupConstructors->setTitle( tr( "GEOM_SUB_SHAPE" ) );
66   mainFrame()->RadioButton1->setIcon( image0 );
67   mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose );
68   mainFrame()->RadioButton2->close();
69   mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
70   mainFrame()->RadioButton3->close();
71
72   GroupPoints = new DlgRef_1Sel1Check1List( centralWidget() );
73
74   GroupPoints->GroupBox1->setTitle( tr( "GEOM_ARGUMENTS" ) );
75   GroupPoints->TextLabel1->setText( tr( "GEOM_MAIN_OBJECT" ) );
76   GroupPoints->TextLabel2->setText( tr( "GEOM_SUBSHAPE_TYPE" ) );
77   GroupPoints->CheckButton1->setText( tr( "GEOM_SUBSHAPE_SELECT" ) );
78   GroupPoints->PushButton1->setIcon( image1 );
79   GroupPoints->LineEdit1->setReadOnly( true );
80
81   QVBoxLayout* layout = new QVBoxLayout( centralWidget() );
82   layout->setMargin( 0 ); layout->setSpacing( 6 );
83   layout->addWidget( GroupPoints );
84   /***************************************************************/
85
86   setHelpFileName( "explode.htm" );
87
88   Init();
89 }
90
91
92 //=================================================================================
93 // function : ~EntityGUI_SubShapeDlg()
94 // purpose  : Destroys the object and frees any allocated resources
95 //=================================================================================
96 EntityGUI_SubShapeDlg::~EntityGUI_SubShapeDlg()
97 {
98 }
99
100
101 //=================================================================================
102 // function : Init()
103 // purpose  :
104 //=================================================================================
105 void EntityGUI_SubShapeDlg::Init()
106 {
107   /* init variables */
108   myEditCurrentArgument = GroupPoints->LineEdit1;
109   myObject = GEOM::GEOM_Object::_nil();
110
111   myWithShape = true;
112
113   /* type for sub shape selection */
114   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Compound" );
115   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Compsolid" );
116   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Solid" );
117   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Shell" );
118   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Face" );
119   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Wire" );
120   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Edge" );
121   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Vertex" );
122   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Shape" );
123
124   if ( SUIT_Session::session()->activeApplication()->desktop()->activeWindow()->getViewManager()->getType() 
125        != OCCViewer_Viewer::Type() )
126     GroupPoints->CheckButton1->setEnabled( false );
127
128   /* signals and slots connections */
129   connect( myGeomGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) );
130
131   connect( buttonOk(),    SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
132   connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
133
134   connect( GroupPoints->PushButton1,  SIGNAL( clicked() ),       this, SLOT( SetEditCurrentArgument() ) );
135   connect( GroupPoints->LineEdit1,    SIGNAL( returnPressed() ), this, SLOT( LineEditReturnPressed() ) );
136
137   connect( GroupPoints->ComboBox1,    SIGNAL( activated( int ) ),    this, SLOT( ComboTextChanged() ) );
138   connect( GroupPoints->CheckButton1, SIGNAL( stateChanged( int ) ), this, SLOT( SubShapeToggled() ) );
139
140   connect( ( (SalomeApp_Application*)( SUIT_Session::session()->activeApplication() ) )->selectionMgr(),
141            SIGNAL( currentSelectionChanged( )), this, SLOT( SelectionIntoArgument() ) );
142
143   updateButtonState();
144
145   SelectionIntoArgument();
146 }
147
148
149 //=================================================================================
150 // function : ClickOnOk()
151 // purpose  :
152 //=================================================================================
153 void EntityGUI_SubShapeDlg::ClickOnOk()
154 {
155   if ( ClickOnApply() )
156     ClickOnCancel();
157 }
158
159
160 //=================================================================================
161 // function : ClickOnApply()
162 // purpose  :
163 //=================================================================================
164 bool EntityGUI_SubShapeDlg::ClickOnApply()
165 {
166   SUIT_Session::session()->activeApplication()->putInfo( "" );
167     
168   /* Explode all sub shapes */
169   if ( isAllSubShapes() ) {
170     /* More than 30 subshapes : ask confirmation */
171     unsigned int nb = NumberOfSubShapes( myShape, shapeType() );
172     if ( nb > 30 ) {
173       const QString caption = tr( "GEOM_CONFIRM" );
174       const QString text = tr( "GEOM_CONFIRM_INFO" ).arg( nb );
175       const QString button0 = tr( "GEOM_BUT_EXPLODE" );
176       const QString button1 = tr( "GEOM_BUT_CANCEL" );
177
178       if ( QMessageBox::warning( this, caption, text, button0, button1 ) != 0 )
179         return false;  /* aborted */
180     }
181   }
182
183   return onAccept();
184 }
185
186
187 //=================================================================================
188 // function : SelectionIntoArgument()
189 // purpose  : Called when selection as changed or other case
190 //          : used only by SelectButtonC1A1 (LineEditC1A1)
191 //=================================================================================
192 void EntityGUI_SubShapeDlg::SelectionIntoArgument()
193 {
194   if ( !isAllSubShapes() )
195     return;
196
197   ResetStateOfDialog();
198
199   QString aString = ""; /* name of selection */
200
201   int nbSel = GEOMBase::GetNameOfSelectedIObjects( selectedIO(), aString, true );
202   if( nbSel != 1 )
203     return;
204
205   TopoDS_Shape S;
206   Handle(SALOME_InteractiveObject) IO = firstIObject();
207   if ( !IO->hasEntry() ) {
208     SUIT_Session::session()->activeApplication()->putInfo( tr( "GEOM_PRP_SHAPE_IN_STUDY" ) );
209     updateButtonState();
210     return;
211   }
212
213   if ( !GEOMBase::GetTopoFromSelection( selectedIO(), S ) ||
214        S.IsNull() ||
215        S.ShapeType() == TopAbs_VERTEX ) {
216     updateButtonState();
217     return;
218   }
219
220
221   Standard_Boolean testResult;
222   myObject = GEOMBase::ConvertIOinGEOMObject( IO, testResult );
223   if ( !testResult || myObject->_is_nil() ) {
224     updateButtonState();
225     return;
226   }
227
228   myShape = S;
229   GroupPoints->LineEdit1->setText( aString );
230
231
232   int SelectedShapeType = GroupPoints->ComboBox1->currentIndex();
233   int count = GroupPoints->ComboBox1->count();
234
235   if ( myWithShape )
236     count = count - 1;
237
238   int i = 0;
239   // Solving PAL5590
240   if ( myShape.ShapeType() == TopAbs_COMPOUND ) {
241     unsigned int nb = NumberOfSubShapes(myShape, TopAbs_COMPOUND);
242     if ( nb > 0 )
243       i++;
244   }
245   while ( i <= myShape.ShapeType() ) {
246     GroupPoints->ComboBox1->removeItem( 0 );
247     i++;
248   }
249
250   if ( myShape.ShapeType() == TopAbs_COMPOUND ) {
251     if ( myWithShape == false ) {
252       GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Shape" );
253       myWithShape = true;
254     }
255   }
256   else {
257     if ( myWithShape == true ) {
258       GroupPoints->ComboBox1->removeItem( GroupPoints->ComboBox1->count() - 1 );
259       myWithShape = false;
260     }
261   }
262
263   int count1 = GroupPoints->ComboBox1->count();
264   if ( myWithShape )
265     count1 = count1 - 1;
266
267   if ( SelectedShapeType > myShape.ShapeType() ) {
268     if ( SelectedShapeType == 8 ) {
269       if ( myShape.ShapeType() != TopAbs_COMPOUND ) {
270         GroupPoints->ComboBox1->setCurrentIndex( 0 );
271         ComboTextChanged();
272       }
273     }
274     else
275       GroupPoints->ComboBox1->setCurrentIndex( count1 - count + SelectedShapeType );
276   }
277   else {
278     GroupPoints->ComboBox1->setCurrentIndex( 0 );
279     ComboTextChanged();
280   }
281
282   updateButtonState();
283 }
284
285
286 //=================================================================================
287 // function : SetEditCurrentArgument()
288 // purpose  :
289 //=================================================================================
290 void EntityGUI_SubShapeDlg::SetEditCurrentArgument()
291 {
292   GroupPoints->LineEdit1->setFocus();
293   myEditCurrentArgument = GroupPoints->LineEdit1;
294   
295   GroupPoints->CheckButton1->setChecked( false );
296   SubShapeToggled();
297   SelectionIntoArgument();
298 }
299
300
301 //=================================================================================
302 // function : LineEditReturnPressed()
303 // purpose  :
304 //=================================================================================
305 void EntityGUI_SubShapeDlg::LineEditReturnPressed()
306 {  
307   QLineEdit* send = (QLineEdit*)sender();
308   if ( send == GroupPoints->LineEdit1 )
309     SetEditCurrentArgument();
310   else
311     return;
312
313   GEOMBase_Skeleton::LineEditReturnPressed();
314 }
315
316
317 //=================================================================================
318 // function : DeactivateActiveDialog()
319 // purpose  :
320 //=================================================================================
321 void EntityGUI_SubShapeDlg::DeactivateActiveDialog()
322 {
323   if ( mainFrame()->GroupConstructors->isEnabled() ) {
324     GEOMBase_Skeleton::DeactivateActiveDialog();
325   }
326 }
327
328
329 //=================================================================================
330 // function : ActivateThisDialog()
331 // purpose  :
332 //=================================================================================
333 void EntityGUI_SubShapeDlg::ActivateThisDialog()
334 {
335   GEOMBase_Skeleton::ActivateThisDialog();
336   connect( ( (SalomeApp_Application*)( SUIT_Session::session()->activeApplication( ) ) )->selectionMgr(),
337            SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ) ;
338   SubShapeToggled();
339   updateButtonState();
340 }
341
342
343 //=================================================================================
344 // function : enterEvent()
345 // purpose  :
346 //=================================================================================
347 void EntityGUI_SubShapeDlg::enterEvent( QEvent* )
348 {
349   if ( !mainFrame()->GroupConstructors->isEnabled() )
350     ActivateThisDialog();
351 }
352
353 //=================================================================================
354 // function : ResetStateOfDialog()
355 // purpose  : Completely reset the state of method including local context
356 //=================================================================================
357 void EntityGUI_SubShapeDlg::ResetStateOfDialog()
358 {
359   myObject = GEOM::GEOM_Object::_nil();
360   myShape.Nullify();
361   myEditCurrentArgument->setText( "" );
362
363   int SelectedShapeType = GroupPoints->ComboBox1->currentIndex();
364   int count = GroupPoints->ComboBox1->count();
365   if ( myWithShape )
366     count = count - 1;
367
368   /* type for sub shape selection */
369   GroupPoints->ComboBox1->clear();
370   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Compound" );
371   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Compsolid" );
372   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Solid" );
373   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Shell" );
374   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Face" );
375   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Wire" );
376   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Edge" );
377   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Vertex" );
378   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Shape" );
379   
380   myWithShape = true;
381   
382   GroupPoints->ComboBox1->setCurrentIndex( 8 - count + SelectedShapeType );
383   ComboTextChanged();
384
385   updateButtonState();
386 }
387
388
389 //=================================================================================
390 // function : SubShapeToggled()
391 // purpose  : Allow user selection of all or only selected sub shapes
392 //          : Called when 'CheckButton1' state change
393 //=================================================================================
394 void EntityGUI_SubShapeDlg::SubShapeToggled()
395 {
396   if ( isAllSubShapes() )
397     globalSelection( GEOM_ALLSHAPES );
398   else
399     localSelection( myObject, shapeType() );
400 }
401
402
403 //=================================================================================
404 // function : ComboTextChanged()
405 // purpose  : 
406 //=================================================================================
407 void EntityGUI_SubShapeDlg::ComboTextChanged()
408 {
409   /* Select sub shapes mode not checked */
410   updateButtonState();
411   SubShapeToggled();    
412 }
413
414
415 //=================================================================================
416 // function : NumberOfSubShapes()
417 // purpose  :
418 //=================================================================================
419 unsigned int EntityGUI_SubShapeDlg::NumberOfSubShapes( const TopoDS_Shape& S,
420                                                        const int shapeType ) const
421 {
422   if ( S.IsNull() )
423     return 0;
424
425   unsigned int index = 0;
426   TopTools_MapOfShape M;
427
428   if ( S.ShapeType() == TopAbs_COMPOUND &&
429        ( TopAbs_ShapeEnum(shapeType) == TopAbs_SHAPE ||
430          TopAbs_ShapeEnum(shapeType) == TopAbs_COMPSOLID ||
431          TopAbs_ShapeEnum(shapeType) == TopAbs_COMPOUND ) ) {
432     TopoDS_Iterator It( S, Standard_True, Standard_True );
433     for ( ; It.More(); It.Next() ) {
434       if ( M.Add( It.Value() ) ) {
435         if ( TopAbs_ShapeEnum( shapeType ) == TopAbs_SHAPE ||
436              TopAbs_ShapeEnum( shapeType ) == It.Value().ShapeType() ) {
437           index++;
438         }
439       }
440     }
441   } 
442   else {
443     TopExp_Explorer Exp ( S, TopAbs_ShapeEnum( shapeType ) );
444     for ( ; Exp.More(); Exp.Next() ) {
445       if ( M.Add( Exp.Current() ) ) {
446         index++;
447       }
448     }
449   }
450
451   M.Clear();
452   return index;
453 }
454
455 //=================================================================================
456 // function : updateButtonState
457 // purpose  :
458 //=================================================================================
459 void EntityGUI_SubShapeDlg::updateButtonState()
460 {
461   if ( SUIT_Session::session()->activeApplication()->desktop()->activeWindow()->getViewManager()->getType() != OCCViewer_Viewer::Type() ||
462        myObject->_is_nil() || shapeType() == TopAbs_SHAPE || shapeType() == TopAbs_COMPOUND ) {
463     GroupPoints->CheckButton1->setChecked( false );
464     GroupPoints->CheckButton1->setEnabled( false );
465   }
466   else
467     GroupPoints->CheckButton1->setEnabled( true );
468 }
469
470 //=================================================================================
471 // function : isAllSubShapes
472 // purpose  :
473 //=================================================================================
474 bool EntityGUI_SubShapeDlg::isAllSubShapes() const
475 {
476   return !GroupPoints->CheckButton1->isChecked() || !GroupPoints->CheckButton1->isEnabled();
477 }
478
479 //=================================================================================
480 // function : shapeType
481 // purpose  :
482 //=================================================================================
483 int EntityGUI_SubShapeDlg::shapeType() const
484 {
485   int type = GroupPoints->ComboBox1->currentIndex();
486
487   if ( myObject->_is_nil() )
488     return type;
489
490   // Solving PAL5590
491   type += myShape.ShapeType() + 1;
492   if ( myShape.ShapeType() == TopAbs_COMPOUND &&
493        NumberOfSubShapes( myShape, TopAbs_COMPOUND ) > 0 ) {
494     type--;
495   }
496
497   return type;
498 }
499
500 //=================================================================================
501 // function : createOperation
502 // purpose  :
503 //=================================================================================
504 GEOM::GEOM_IOperations_ptr EntityGUI_SubShapeDlg::createOperation()
505 {
506   return getGeomEngine()->GetIShapesOperations( getStudyId() );
507 }
508
509 //=================================================================================
510 // function : isValid
511 // purpose  :
512 //=================================================================================
513 bool EntityGUI_SubShapeDlg::isValid( QString& msg )
514 {
515   bool isOk = false;
516   if ( !myObject->_is_nil() ) {
517     if ( isAllSubShapes() )
518       isOk = true;
519     else if ( IObjectCount() == 1 ) {
520       Standard_Boolean aResult = Standard_False;
521       GEOM::GEOM_Object_var anObj =
522         GEOMBase::ConvertIOinGEOMObject( firstIObject(), aResult );
523       
524       if ( aResult && !anObj->_is_nil() ) {
525         TColStd_IndexedMapOfInteger aMapIndex;
526         ( (SalomeApp_Application*)( SUIT_Session::session()->activeApplication() ) )->selectionMgr()->GetIndexes( firstIObject(), aMapIndex );
527         isOk = aMapIndex.Extent() > 0;
528         if ( !isOk )
529           msg += tr( "NO_SUBSHAPES_SELECTED" );
530       }
531     }
532   }
533   return isOk;
534 }
535
536 //=================================================================================
537 // function : execute
538 // purpose  :
539 //=================================================================================
540 bool EntityGUI_SubShapeDlg::execute( ObjectList& objects )
541 {
542   GEOM::ListOfGO_var aList = GEOM::GEOM_IShapesOperations::_narrow(
543     getOperation() )->MakeExplode( myObject, shapeType(), true );
544     
545   if ( !aList->length() )
546     return false;
547   
548   // Throw away sub-shapes not selected by user if not in preview mode 
549   // and manual selection is active
550   if ( !isAllSubShapes() ) {
551     if ( IObjectCount() == 1 ) {
552       Standard_Boolean aResult = Standard_False;
553       GEOM::GEOM_Object_var anObj =
554         GEOMBase::ConvertIOinGEOMObject( firstIObject(), aResult );
555
556       if ( aResult && !anObj->_is_nil() ) {
557         TColStd_IndexedMapOfInteger aMapIndex;
558         ( (SalomeApp_Application*)( SUIT_Session::session()->activeApplication() ) )->selectionMgr()->GetIndexes( firstIObject(), aMapIndex );
559
560         GEOM::GEOM_ILocalOperations_var aLocOp = 
561           getGeomEngine()->GetILocalOperations( getStudyId() );
562
563         for ( int i = 0, n = aList->length(); i < n; i++ )
564           if ( aMapIndex.Contains( aLocOp->GetSubShapeIndex( myObject, aList[i] ) ) )
565             objects.push_back( GEOM::GEOM_Object::_duplicate( aList[i] ) );
566       }
567     }
568   }
569   else
570     for ( int i = 0, n = aList->length(); i < n; i++ )
571       objects.push_back( GEOM::GEOM_Object::_duplicate( aList[i] ) );
572   
573   return objects.size();
574 }
575
576 //================================================================
577 // Function : getFather
578 // Purpose  : Get father object for object to be added in study
579 //            ( called with addInStudy method )
580 //================================================================
581 GEOM::GEOM_Object_ptr EntityGUI_SubShapeDlg::getFather( GEOM::GEOM_Object_ptr )
582 {
583   return myObject;
584 }
585
586 const char* EntityGUI_SubShapeDlg::getNewObjectName() const
587 {
588   return "";
589 }