Salome HOME
test integration for 0019050: EDF 521 GEOM SMESH : Improve selection process in the...
[modules/geom.git] / src / TransformationGUI / TransformationGUI_RotationDlg.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   : TransformationGUI_RotationDlg.cxx
23 // Author : Lucien PIGNOLONI, Open CASCADE S.A.S.
24 //
25
26 #include "TransformationGUI_RotationDlg.h"
27
28 #include <DlgRef.h>
29 #include <GeometryGUI.h>
30 #include <GEOMBase.h>
31
32 #include <SUIT_ResourceMgr.h>
33 #include <SUIT_Session.h>
34 #include <SalomeApp_Application.h>
35 #include <LightApp_SelectionMgr.h>
36
37 #include <TopoDS_Shape.hxx>
38 #include <TopoDS_Edge.hxx>
39 #include <TopoDS.hxx>
40 #include <TopExp.hxx>
41 #include <TColStd_IndexedMapOfInteger.hxx>
42 #include <TopTools_IndexedMapOfShape.hxx>
43
44 #include <GEOMImpl_Types.hxx>
45
46 //=================================================================================
47 // class    : TransformationGUI_RotationDlg()
48 // purpose  : Constructs a TransformationGUI_RotationDlg which is a child of 'parent', with the 
49 //            name 'name' and widget flags set to 'f'.
50 //            The dialog will by default be modeless, unless you set 'modal' to
51 //            TRUE to construct a modal dialog.
52 //=================================================================================
53 TransformationGUI_RotationDlg::TransformationGUI_RotationDlg
54 ( GeometryGUI* theGeometryGUI, QWidget* parent, bool modal, Qt::WindowFlags fl )
55   : GEOMBase_Skeleton( theGeometryGUI, parent, modal, fl )
56 {
57   SUIT_ResourceMgr* aResMgr = myGeomGUI->getApp()->resourceMgr();
58   QPixmap image0( aResMgr->loadPixmap( "GEOM", tr( "ICON_DLG_ROTATION" ) ) );
59   QPixmap image1( aResMgr->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) );
60   QPixmap image2( aResMgr->loadPixmap( "GEOM", tr( "ICON_DLG_ROTATION_THREE_POINTS" ) ) );
61
62   setWindowTitle( tr( "GEOM_ROTATION_TITLE" ) );
63
64   /***************************************************************/
65   mainFrame()->GroupConstructors->setTitle( tr( "GEOM_ROTATION" ) );
66   mainFrame()->RadioButton1->setIcon( image0 );
67   mainFrame()->RadioButton2->setIcon( image2 );
68   mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
69   mainFrame()->RadioButton3->close();
70
71   GroupPoints = new DlgRef_4Sel1Spin2Check( centralWidget() );
72   GroupPoints->GroupBox1->setTitle( tr( "GEOM_ARGUMENTS" ) );
73   GroupPoints->TextLabel1->setText( tr( "GEOM_OBJECTS" ) );
74   GroupPoints->TextLabel2->setText( tr( "GEOM_AXIS" ) );
75   GroupPoints->TextLabel3->setText( tr( "GEOM_ANGLE" ) );
76   GroupPoints->TextLabel4->setText( tr( "GEOM_POINT_I" ).arg( 1 ) );
77   GroupPoints->TextLabel5->setText( tr( "GEOM_POINT_I" ).arg( 2 ) );
78
79   GroupPoints->LineEdit1->setReadOnly( true );
80   GroupPoints->LineEdit2->setReadOnly( true );
81   GroupPoints->LineEdit4->setReadOnly( true );
82   GroupPoints->LineEdit5->setReadOnly( true );
83   GroupPoints->PushButton1->setIcon( image1 );
84   GroupPoints->PushButton2->setIcon( image1 );
85   GroupPoints->PushButton4->setIcon( image1 );
86   GroupPoints->PushButton5->setIcon( image1 );
87   GroupPoints->CheckButton1->setText( tr( "GEOM_CREATE_COPY" ) );
88   GroupPoints->CheckButton2->setText( tr( "GEOM_REVERSE" ) );
89
90   QVBoxLayout* layout = new QVBoxLayout( centralWidget() );
91   layout->setMargin( 0 ); layout->setSpacing( 6 );
92   layout->addWidget( GroupPoints );
93
94   /***************************************************************/
95   double anAngle = 0;
96   double SpecificStep = 5;
97   /* min, max, step and decimals for spin boxes & initial values */
98   initSpinBox( GroupPoints->SpinBox_DX, COORD_MIN, COORD_MAX, SpecificStep, 3 ); // VSR: TODO: DBL_DIGITS_DISPLAY
99   GroupPoints->SpinBox_DX->setValue( anAngle );
100
101   // Activate Create a Copy mode
102   GroupPoints->CheckButton1->setChecked( true );
103   CreateCopyModeChanged( true );
104   
105   mainFrame()->GroupBoxPublish->show();
106
107   /* signals and slots connections */
108   connect( buttonOk(),    SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
109   connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
110
111   connect( this, SIGNAL( constructorsClicked( int ) ), this, SLOT( ConstructorsClicked( int ) ) );
112
113   connect( GroupPoints->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
114   connect( GroupPoints->PushButton2, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
115   connect( GroupPoints->PushButton4, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
116   connect( GroupPoints->PushButton5, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
117  
118   connect( GroupPoints->LineEdit1, SIGNAL( returnPressed() ), this, SLOT( LineEditReturnPressed() ) );
119   connect( GroupPoints->LineEdit2, SIGNAL( returnPressed() ), this, SLOT( LineEditReturnPressed() ) );
120
121   connect( GroupPoints->SpinBox_DX,   SIGNAL( valueChanged( double ) ), this, SLOT( ValueChangedInSpinBox() ) );
122   connect( GroupPoints->CheckButton1, SIGNAL( toggled( bool ) ),        this, SLOT( CreateCopyModeChanged( bool ) ) );
123   connect( GroupPoints->CheckButton2, SIGNAL( toggled( bool ) ),        this, SLOT( onReverse() ) );
124   
125   connect( myGeomGUI->getApp()->selectionMgr(),
126            SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
127
128   setHelpFileName( "rotation_operation_page.html" );
129
130   Init();
131 }
132
133
134 //=================================================================================
135 // function : ~TransformationGUI_RotationDlg()
136 // purpose  : Destroys the object and frees any allocated resources
137 //=================================================================================
138 TransformationGUI_RotationDlg::~TransformationGUI_RotationDlg()
139 {
140   // no need to delete child widgets, Qt does it all for us
141 }
142
143
144 //=================================================================================
145 // function : Init()
146 // purpose  :
147 //=================================================================================
148 void TransformationGUI_RotationDlg::Init()
149 {
150   /* init variables */
151   myEditCurrentArgument = GroupPoints->LineEdit1;
152   GroupPoints->LineEdit2->clear();
153   
154   myAxis = myCentPoint = myPoint1 = myPoint2 = GEOM::GEOM_Object::_nil();
155   
156   initName( tr( "GEOM_ROTATION" ) );
157   ConstructorsClicked( 0 );
158 }
159
160 //=================================================================================
161 // function : ConstructorsClicked()
162 // purpose  : Radio button management
163 //=================================================================================
164 void TransformationGUI_RotationDlg::ConstructorsClicked( int constructorId )
165 {
166   disconnect( myGeomGUI->getApp()->selectionMgr(), 0, this, 0 );
167   
168   myEditCurrentArgument = GroupPoints->LineEdit1;
169   globalSelection();
170
171   switch ( constructorId ) {
172   case 0: /* rotation an object angle and axis */
173     GroupPoints->ShowRows( 2, 3, false );
174     GroupPoints->TextLabel2->setText( tr( "GEOM_AXIS" ) );
175     GroupPoints->LineEdit2->clear();
176     GroupPoints->ShowRows( 4, 4, true );
177     myAxis = GEOM::GEOM_Object::_nil();
178     break;
179   case 1: /* rotation an object by 3 points */
180     GroupPoints->ShowRows( 4, 4, false );
181     GroupPoints->ShowRows( 2, 3, true );
182     GroupPoints->TextLabel2->setText( tr( "GEOM_CENTRAL_POINT" ) );
183     GroupPoints->TextLabel4->setText( tr( "GEOM_POINT_I" ).arg( 1 ) );
184     GroupPoints->TextLabel5->setText( tr( "GEOM_POINT_I" ).arg( 2 ) );
185     GroupPoints->LineEdit2->clear();
186     GroupPoints->LineEdit4->clear();
187     GroupPoints->LineEdit5->clear();
188     myCentPoint = myPoint1 = myPoint2 = GEOM::GEOM_Object::_nil();
189     break;
190   } 
191   
192   qApp->processEvents();
193   updateGeometry();
194   resize( minimumSize() );
195
196   myEditCurrentArgument->setFocus();
197   connect( myGeomGUI->getApp()->selectionMgr(), 
198            SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
199 }
200
201 //=================================================================================
202 // function : ClickOnOk()
203 // purpose  :
204 //=================================================================================
205 void TransformationGUI_RotationDlg::ClickOnOk()
206 {
207   if ( ClickOnApply() )
208     ClickOnCancel();
209 }
210
211
212 //=================================================================================
213 // function : ClickOnApply()
214 // purpose  :
215 //=================================================================================
216 bool TransformationGUI_RotationDlg::ClickOnApply()
217 {
218   if ( !onAccept( GroupPoints->CheckButton1->isChecked() ) )
219     return false;
220   
221   initName();
222   ConstructorsClicked( getConstructorId() );
223   return true;
224 }
225
226
227 //=================================================================================
228 // function : SelectionIntoArgument()
229 // purpose  : Called when selection as changed or other case
230 //=================================================================================
231 void TransformationGUI_RotationDlg::SelectionIntoArgument()
232 {
233   myEditCurrentArgument->setText( "" );
234   QString aName;
235   
236   if ( myEditCurrentArgument == GroupPoints->LineEdit1 ) {
237     int aNbSel = GEOMBase::GetNameOfSelectedIObjects( selectedIO(), aName );
238     if ( aNbSel < 1) {
239       myObjects.length( 0 );
240       return;
241     }
242     GEOMBase::ConvertListOfIOInListOfGO( selectedIO(), myObjects );
243     if ( !myObjects.length() )
244       return;
245   }
246   else {
247     if ( IObjectCount() != 1 ) {
248       if ( myEditCurrentArgument == GroupPoints->LineEdit2 && getConstructorId() == 0 )
249         myAxis = GEOM::GEOM_Object::_nil();
250       else if ( myEditCurrentArgument == GroupPoints->LineEdit2 && getConstructorId() == 1 )
251         myCentPoint  = GEOM::GEOM_Object::_nil();
252       else if ( myEditCurrentArgument == GroupPoints->LineEdit4 )
253         myPoint1 = GEOM::GEOM_Object::_nil();
254       else if ( myEditCurrentArgument == GroupPoints->LineEdit5 )
255         myPoint2 = GEOM::GEOM_Object::_nil();
256       return;
257     }
258
259     Standard_Boolean testResult = Standard_False;
260     GEOM::GEOM_Object_var aSelectedObject = GEOMBase::ConvertIOinGEOMObject( firstIObject(), testResult );
261     if ( !testResult || CORBA::is_nil( aSelectedObject ) )
262       return;
263     
264     aName = GEOMBase::GetName( aSelectedObject );
265     TopoDS_Shape aShape;
266     if ( GEOMBase::GetShape( aSelectedObject, aShape, TopAbs_SHAPE ) && !aShape.IsNull() ) {
267       TopAbs_ShapeEnum aNeedType = TopAbs_VERTEX;
268       if ( myEditCurrentArgument == GroupPoints->LineEdit2 && getConstructorId() == 0 )
269         aNeedType = TopAbs_EDGE;
270       
271       LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
272       TColStd_IndexedMapOfInteger aMap;
273       aSelMgr->GetIndexes( firstIObject(), aMap );
274       if ( aMap.Extent() == 1 ) {
275         int anIndex = aMap( 1 );
276         if ( aNeedType == TopAbs_EDGE )
277           aName += QString( ":edge_%1" ).arg( anIndex );
278         else
279           aName += QString( ":vertex_%1" ).arg( anIndex );
280         
281         //Find SubShape Object in Father
282         GEOM::GEOM_Object_var aFindedObject = findObjectInFather( aSelectedObject, aName );
283         
284         if ( aFindedObject == GEOM::GEOM_Object::_nil() ) { // Object not found in study
285           GEOM::GEOM_IShapesOperations_var aShapesOp =
286             getGeomEngine()->GetIShapesOperations( getStudyId() );
287           aSelectedObject = aShapesOp->GetSubShape( aSelectedObject, anIndex );
288         }
289         else {
290           aSelectedObject = aFindedObject; // get Object from study
291         }
292       }
293       else {
294         if ( aShape.ShapeType() != aNeedType ) {
295           aSelectedObject = GEOM::GEOM_Object::_nil();
296           aName = "";
297         }
298       }
299     }
300     
301     if ( myEditCurrentArgument == GroupPoints->LineEdit2 && getConstructorId() == 0 )
302       myAxis = aSelectedObject;
303     else if ( myEditCurrentArgument == GroupPoints->LineEdit2 && getConstructorId() == 1 )
304       myCentPoint = aSelectedObject;
305     else if ( myEditCurrentArgument == GroupPoints->LineEdit4 )
306       myPoint1 = aSelectedObject;
307     else if ( myEditCurrentArgument == GroupPoints->LineEdit5 )
308       myPoint2 = aSelectedObject;
309   }
310   myEditCurrentArgument->setText( aName );
311   
312   displayPreview();
313 }
314
315
316 //=================================================================================
317 // function : SetEditCurrentArgument()
318 // purpose  :
319 //=================================================================================
320 void TransformationGUI_RotationDlg::SetEditCurrentArgument()
321 {
322   QPushButton* send = (QPushButton*)sender();
323   globalSelection();
324   
325   if ( send == GroupPoints->PushButton1 ) {
326     myEditCurrentArgument = GroupPoints->LineEdit1;
327   }
328   else if ( send == GroupPoints->PushButton2 ) {
329     myEditCurrentArgument = GroupPoints->LineEdit2;
330     if ( getConstructorId() == 0 )
331       localSelection( GEOM::GEOM_Object::_nil(), TopAbs_EDGE );
332     else
333       localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX );
334   }
335   else if ( send == GroupPoints->PushButton4 ) {
336     myEditCurrentArgument = GroupPoints->LineEdit4;
337     localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX );
338   }
339   else if ( send == GroupPoints->PushButton5 ) {
340     myEditCurrentArgument = GroupPoints->LineEdit5;
341     localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX );
342   }
343
344   myEditCurrentArgument->setFocus();
345   SelectionIntoArgument();
346 }
347
348
349 //=================================================================================
350 // function : LineEditReturnPressed()
351 // purpose  :
352 //=================================================================================
353 void TransformationGUI_RotationDlg::LineEditReturnPressed()
354 {  
355   QLineEdit* send = (QLineEdit*)sender();
356   if ( send == GroupPoints->LineEdit1 ||
357        send == GroupPoints->LineEdit2 ) {
358     myEditCurrentArgument = send;
359     GEOMBase_Skeleton::LineEditReturnPressed();
360   }
361 }
362
363
364 //=================================================================================
365 // function : ActivateThisDialog()
366 // purpose  :
367 //=================================================================================
368 void TransformationGUI_RotationDlg::ActivateThisDialog()
369 {
370   GEOMBase_Skeleton::ActivateThisDialog();
371   connect( myGeomGUI->getApp()->selectionMgr(), 
372            SIGNAL( currentSelectionChanged() ) , this, SLOT( SelectionIntoArgument() ) );
373
374   ConstructorsClicked( getConstructorId() );
375 }
376
377
378 //=================================================================================
379 // function : enterEvent()
380 // purpose  :
381 //=================================================================================
382 void TransformationGUI_RotationDlg::enterEvent( QEvent* )
383 {
384   if ( !mainFrame()->GroupConstructors->isEnabled() )
385     ActivateThisDialog();
386 }
387
388
389 //=================================================================================
390 // function : ValueChangedInSpinBox()
391 // purpose  :
392 //=================================================================================
393 void TransformationGUI_RotationDlg::ValueChangedInSpinBox()
394 {
395   displayPreview();
396 }
397
398
399 //=================================================================================
400 // function : createOperation
401 // purpose  :
402 //=================================================================================
403 GEOM::GEOM_IOperations_ptr TransformationGUI_RotationDlg::createOperation()
404 {
405   return getGeomEngine()->GetITransformOperations( getStudyId() );
406 }
407
408
409 //=================================================================================
410 // function : isValid
411 // purpose  :
412 //=================================================================================
413 bool TransformationGUI_RotationDlg::isValid( QString& /*msg*/ )
414 {
415   switch ( getConstructorId() ) {
416   case 0: 
417     return !( myObjects.length() == 0 || myAxis->_is_nil() );
418     break;
419   case 1: 
420     return !( myObjects.length() == 0 || myCentPoint->_is_nil() || myPoint1->_is_nil() || myPoint2->_is_nil() );
421     break;
422   default: 
423     return false;
424   }
425 }
426
427
428 //=================================================================================
429 // function : execute
430 // purpose  :
431 //=================================================================================
432 bool TransformationGUI_RotationDlg::execute( ObjectList& objects )
433 {
434   bool res = false;
435   bool toCreateCopy = IsPreview() || GroupPoints->CheckButton1->isChecked();
436
437   GEOM::GEOM_Object_var anObj;
438   
439   switch ( getConstructorId() ) {
440   case 0 :
441     {
442       if ( toCreateCopy ) {
443         for ( int i = 0; i < myObjects.length(); i++ ) {
444           myCurrObject = myObjects[i];
445           anObj = GEOM::GEOM_ITransformOperations::_narrow( getOperation() )->RotateCopy( myObjects[i], myAxis, GetAngle() * PI180 );
446           if ( !anObj->_is_nil() )
447             objects.push_back( anObj._retn() );
448         }
449       }
450       else {
451         for ( int i = 0; i < myObjects.length(); i++ ) {
452           myCurrObject = myObjects[i];
453           anObj = GEOM::GEOM_ITransformOperations::_narrow( getOperation() )->Rotate( myObjects[i], myAxis, GetAngle() * PI180 );
454           if ( !anObj->_is_nil() )
455             objects.push_back( anObj._retn() );
456         }
457       }
458       res = true;
459       break;
460     }
461   case 1 :
462     {
463       if ( toCreateCopy ) {
464         for ( int i = 0; i < myObjects.length(); i++ ) {
465           myCurrObject = myObjects[i];
466           anObj = GEOM::GEOM_ITransformOperations::_narrow( getOperation() )->RotateThreePointsCopy( myObjects[i], myCentPoint, myPoint1, myPoint2 );
467           if ( !anObj->_is_nil() )
468             objects.push_back( anObj._retn() );
469         }
470       }
471       else {
472         for ( int i = 0; i < myObjects.length(); i++ ) {
473           myCurrObject = myObjects[i];
474           anObj = GEOM::GEOM_ITransformOperations::_narrow( getOperation() )->RotateThreePoints( myObjects[i], myCentPoint, myPoint1, myPoint2 );       
475           if ( !anObj->_is_nil() )
476             objects.push_back( anObj._retn() );
477         }
478       }
479       res = true;
480       break;
481     }
482   }
483   
484   return res;
485 }
486
487 //=================================================================================
488 // function : restoreSubShapes
489 // purpose  :
490 //=================================================================================
491 void TransformationGUI_RotationDlg::restoreSubShapes( SALOMEDS::Study_ptr   theStudy,
492                                                       SALOMEDS::SObject_ptr theSObject )
493 {
494   if ( mainFrame()->CheckBoxRestoreSS->isChecked() ) {
495     // we pass here the first operation argument (object) through the list of arguments
496     // because the rotation operation place its arguments in the data structure in another order,
497     // and we need to point the first argument directly
498     GEOM::ListOfGO_var anArgs = new GEOM::ListOfGO;
499     anArgs->length(1);
500     anArgs[0] = myCurrObject;
501     getGeomEngine()->RestoreSubShapesSO( theStudy, theSObject, anArgs,
502                                          /*theFindMethod=*/GEOM::FSM_Transformed,
503                                          /*theInheritFirstArg=*/true );
504   }
505 }
506
507 //=================================================================================
508 // function : GetAngle()
509 // purpose  :
510 //=================================================================================
511 double TransformationGUI_RotationDlg::GetAngle() const
512 {
513   return GroupPoints->SpinBox_DX->value();
514 }
515
516 //=================================================================================
517 // function :  CreateCopyModeChanged()
518 // purpose  :
519 //=================================================================================
520 void TransformationGUI_RotationDlg::CreateCopyModeChanged( bool isCreateCopy )
521 {
522   mainFrame()->GroupBoxName->setEnabled( isCreateCopy );
523 }
524
525 //=================================================================================
526 // function :  onReverse()
527 // purpose  :
528 //=================================================================================
529 void TransformationGUI_RotationDlg::onReverse()
530 {
531   double anOldValue = GroupPoints->SpinBox_DX->value();
532   GroupPoints->SpinBox_DX->setValue( -anOldValue );
533 }
534
535 //=================================================================================
536 // function : addSubshapeToStudy
537 // purpose  : virtual method to add new SubObjects if local selection
538 //=================================================================================
539 void TransformationGUI_RotationDlg::addSubshapesToStudy()
540 {
541   bool toCreateCopy = IsPreview() || GroupPoints->CheckButton1->isChecked();
542   if ( toCreateCopy ) {
543     QMap<QString, GEOM::GEOM_Object_var> objMap;
544     switch ( getConstructorId() ) {
545     case 0:
546       objMap[GroupPoints->LineEdit2->text()] = myAxis;
547       break;
548     case 1:
549       objMap[GroupPoints->LineEdit2->text()] = myCentPoint;
550       objMap[GroupPoints->LineEdit4->text()] = myPoint1;
551       objMap[GroupPoints->LineEdit5->text()] = myPoint2;
552       break;
553     }
554     addSubshapesToFather( objMap );
555   }
556 }