]> SALOME platform Git repositories - modules/geom.git/blob - src/TransformationGUI/TransformationGUI_ScaleDlg.cxx
Salome HOME
Remove some methods of GEOMBase_Helper (IObjectCount(), firstIObject(), lastIObject...
[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   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
262   SALOME_ListIO aSelList;
263   aSelMgr->selectedObjects(aSelList);
264
265   if (myEditCurrentArgument == LineEdit1)
266   {
267     int aNbSel = GEOMBase::GetNameOfSelectedIObjects(aSelList, aName);
268     if (aNbSel < 1)
269     {
270       myObjects.length(0);
271       return;
272     }
273     GEOMBase::ConvertListOfIOInListOfGO(aSelList, myObjects);
274     if (!myObjects.length())
275       return;
276   }
277   else if (myEditCurrentArgument == LineEdit2)
278   {
279     GEOM::GEOM_Object_var aSelectedObject = GEOM::GEOM_Object::_nil();
280     if (aSelList.Extent() == 1)
281     {
282       Standard_Boolean testResult = Standard_False;
283       aSelectedObject = GEOMBase::ConvertIOinGEOMObject(aSelList.First(), testResult);
284       if (testResult)
285       {
286         aName = GEOMBase::GetName(aSelectedObject);
287
288         TopoDS_Shape aShape;
289         if (GEOMBase::GetShape(aSelectedObject, aShape, TopAbs_SHAPE) && !aShape.IsNull())
290         {
291           TColStd_IndexedMapOfInteger aMap;
292           aSelMgr->GetIndexes(aSelList.First(), aMap);
293           if (aMap.Extent() == 1)
294           {
295             int anIndex = aMap( 1 );
296             aName += QString( ":vertex_%1" ).arg( anIndex );
297
298             //Find SubShape Object in Father
299             GEOM::GEOM_Object_var aFindedObject = findObjectInFather( aSelectedObject, aName );
300
301             if ( aFindedObject == GEOM::GEOM_Object::_nil() ) { // Object not found in study
302               GEOM::GEOM_IShapesOperations_var aShapesOp =
303                 getGeomEngine()->GetIShapesOperations( getStudyId() );
304               aSelectedObject = aShapesOp->GetSubShape( aSelectedObject, anIndex );
305               aSelMgr->clearSelected();
306             }
307             else
308               aSelectedObject = aFindedObject; // get Object from study
309           }
310           else
311           {
312             if ( aShape.ShapeType() != TopAbs_VERTEX ) {
313               aSelectedObject = GEOM::GEOM_Object::_nil();
314               aName = "";
315             }
316           }
317         }
318       }
319     }
320
321     myPoint = aSelectedObject;
322   }
323
324   myEditCurrentArgument->setText(aName);
325   displayPreview();
326 }
327
328 //=================================================================================
329 // function : LineEditReturnPressed()
330 // purpose  :
331 //=================================================================================
332 void TransformationGUI_ScaleDlg::LineEditReturnPressed()
333 {
334   QLineEdit* send = (QLineEdit*)sender();
335   if ( send == LineEdit1 || send == LineEdit2 )
336   {
337     myEditCurrentArgument = send;
338     GEOMBase_Skeleton::LineEditReturnPressed();
339   }
340 }
341
342 //=================================================================================
343 // function : SetEditCurrentArgument()
344 // purpose  :
345 //=================================================================================
346 void TransformationGUI_ScaleDlg::SetEditCurrentArgument()
347 {
348   QPushButton* send = (QPushButton*)sender();
349   globalSelection();
350   
351   if ( send == PushButton1 ) {
352     myEditCurrentArgument = LineEdit1;
353   }
354   else if ( send == PushButton2 ) {
355     myEditCurrentArgument = LineEdit2;
356     localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX);
357   }
358   
359   myEditCurrentArgument->setFocus();
360   SelectionIntoArgument();
361 }
362
363 //=================================================================================
364 // function : ActivateThisDialog()
365 // purpose  :
366 //=================================================================================
367 void TransformationGUI_ScaleDlg::ActivateThisDialog()
368 {
369   GEOMBase_Skeleton::ActivateThisDialog();
370   connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),
371            this, SLOT( SelectionIntoArgument() ) );
372   globalSelection();
373   myEditCurrentArgument->setFocus();
374   if ( myEditCurrentArgument == LineEdit2 ) {
375     localSelection( GEOM::GEOM_Object::_nil(), TopAbs_VERTEX );
376   }
377 }
378
379 //=================================================================================
380 // function : enterEvent()
381 // purpose  :
382 //=================================================================================
383 void TransformationGUI_ScaleDlg::enterEvent( QEvent* )
384 {
385   if ( !mainFrame()->GroupConstructors->isEnabled() )
386     ActivateThisDialog();
387 }
388
389 //=================================================================================
390 // function : ValueChangedInSpinBox()
391 // purpose  :
392 //=================================================================================
393 void TransformationGUI_ScaleDlg::ValueChangedInSpinBox()
394 {
395   displayPreview();
396 }
397
398 //=================================================================================
399 // function : SetDoubleSpinBoxStep()
400 // purpose  : Double spin box management
401 //=================================================================================
402 void TransformationGUI_ScaleDlg::SetDoubleSpinBoxStep( double step )
403 {
404   SpinBox_FX->setSingleStep( step );
405   SpinBox_FY->setSingleStep( step );
406   SpinBox_FZ->setSingleStep( step );
407 }
408
409 //=================================================================================
410 // function : createOperation
411 // purpose  :
412 //=================================================================================
413 GEOM::GEOM_IOperations_ptr TransformationGUI_ScaleDlg::createOperation()
414 {
415   return myGeomGUI->GetGeomGen()->GetITransformOperations( getStudyId() );
416 }
417
418 //=================================================================================
419 // function : isValid
420 // purpose  :
421 //=================================================================================
422 bool TransformationGUI_ScaleDlg::isValid( QString& /*msg*/)
423 {
424   if ( myObjects.length() > 0 && fabs( SpinBox_FX->value() ) > 0.00001 )
425   {
426     // && !myPoint->_is_nil()
427     if ( getConstructorId() == 0 )
428       return true;
429     if ( fabs( SpinBox_FY->value() ) > 0.00001 &&
430          fabs( SpinBox_FZ->value() ) > 0.00001 )
431       return true;
432   }
433   return false;
434 }
435
436 //=================================================================================
437 // function : execute
438 // purpose  :
439 //=================================================================================
440 bool TransformationGUI_ScaleDlg::execute( ObjectList& objects )
441 {
442   bool toCreateCopy = IsPreview() || CheckBoxCopy->isChecked();
443
444   GEOM::GEOM_Object_var anObj;
445
446   switch ( getConstructorId() )
447   {
448   case 0:
449     {
450       if ( toCreateCopy )
451       {
452         for ( int i = 0; i < myObjects.length(); i++ )
453         {
454           anObj = GEOM::GEOM_ITransformOperations::_narrow( getOperation() )->
455             ScaleShapeCopy( myObjects[i], myPoint, SpinBox_FX->value() );
456           if ( !anObj->_is_nil() )
457             objects.push_back( anObj._retn() );
458         }
459       }
460       else
461       {
462         for ( int i = 0; i < myObjects.length(); i++ )
463         {
464           anObj = GEOM::GEOM_ITransformOperations::_narrow( getOperation() )->
465             ScaleShape( myObjects[i], myPoint, SpinBox_FX->value() );
466           if ( !anObj->_is_nil() )
467             objects.push_back( anObj._retn() );
468         }
469       }
470     }
471     break;
472   case 1:
473     {
474       if ( toCreateCopy )
475       {
476         for ( int i = 0; i < myObjects.length(); i++ )
477         {
478           anObj = GEOM::GEOM_ITransformOperations::_narrow( getOperation() )->
479             ScaleShapeAlongAxesCopy( myObjects[i], myPoint, SpinBox_FX->value(),
480                                      SpinBox_FY->value(), SpinBox_FZ->value() );
481           if ( !anObj->_is_nil() )
482             objects.push_back( anObj._retn() );
483         }
484       }
485       else
486       {
487         for ( int i = 0; i < myObjects.length(); i++ )
488         {
489           anObj = GEOM::GEOM_ITransformOperations::_narrow( getOperation() )->
490             ScaleShapeAlongAxes( myObjects[i], myPoint, SpinBox_FX->value(),
491                                  SpinBox_FY->value(), SpinBox_FZ->value() );
492           if ( !anObj->_is_nil() )
493             objects.push_back( anObj._retn() );
494         }
495       }
496     }
497     break;
498   default:
499     break;
500   }
501
502   return true;
503 }
504
505 //=================================================================================
506 // function : restoreSubShapes
507 // purpose  :
508 //=================================================================================
509 void TransformationGUI_ScaleDlg::restoreSubShapes( SALOMEDS::Study_ptr   theStudy,
510                                                    SALOMEDS::SObject_ptr theSObject )
511 {
512   if ( mainFrame()->CheckBoxRestoreSS->isChecked() ) {
513     // empty list of arguments means that all arguments should be restored
514     getGeomEngine()->RestoreSubShapesSO( theStudy, theSObject, GEOM::ListOfGO(),
515                                          /*theFindMethod=*/GEOM::FSM_Transformed,
516                                          /*theInheritFirstArg=*/true );
517   }
518 }
519
520 //=================================================================================
521 // function :  CreateCopyModeChanged()
522 // purpose  :
523 //=================================================================================
524 void TransformationGUI_ScaleDlg::CreateCopyModeChanged( bool isCreateCopy )
525 {
526   mainFrame()->GroupBoxName->setEnabled( isCreateCopy );
527 }
528
529 //=================================================================================
530 // function : addSubshapesToStudy
531 // purpose  : virtual method to add new SubObjects if local selection
532 //=================================================================================
533 void TransformationGUI_ScaleDlg::addSubshapesToStudy()
534 {
535   bool toCreateCopy = IsPreview() || CheckBoxCopy->isChecked();
536   if ( toCreateCopy )
537   {
538     if ( !myPoint->_is_nil() )
539     {
540       QMap<QString, GEOM::GEOM_Object_var> objMap;
541       objMap[LineEdit2->text()] = myPoint;
542       addSubshapesToFather( objMap );
543     }
544   }
545 }