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