Back to index

salome-geom  6.5.0
TransformationGUI_ScaleDlg.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 // GEOM GEOMGUI : GUI for Geometry component
00024 // File   : TransformationGUI_ScaleDlg.cxx
00025 // Author : Lucien PIGNOLONI, Open CASCADE S.A.S.
00026 //
00027 #include "TransformationGUI_ScaleDlg.h"
00028 
00029 #include <DlgRef.h>
00030 #include <GeometryGUI.h>
00031 #include <GEOMBase.h>
00032 
00033 #include <SalomeApp_DoubleSpinBox.h>
00034 #include <SUIT_Session.h>
00035 #include <SUIT_ResourceMgr.h>
00036 #include <SalomeApp_Application.h>
00037 #include <LightApp_SelectionMgr.h>
00038 
00039 // OCCT Includes
00040 #include <TopoDS_Shape.hxx>
00041 #include <TopoDS.hxx>
00042 #include <TopExp.hxx>
00043 #include <TColStd_IndexedMapOfInteger.hxx>
00044 #include <TopTools_IndexedMapOfShape.hxx>
00045 
00046 #include <GEOMImpl_Types.hxx>
00047 
00048 //=================================================================================
00049 // class    : TransformationGUI_ScaleDlg()
00050 // purpose  : Constructs a TransformationGUI_ScaleDlg which is a child of 'parent', with the
00051 //            name 'name' and widget flags set to 'f'.
00052 //            The dialog will by default be modeless, unless you set 'modal' to
00053 //            TRUE to construct a modal dialog.
00054 //=================================================================================
00055 TransformationGUI_ScaleDlg::TransformationGUI_ScaleDlg (GeometryGUI* theGeometryGUI, QWidget* parent,
00056                                                         bool modal, Qt::WindowFlags fl)
00057   : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl),
00058     myInitial(true)
00059 {
00060   SUIT_ResourceMgr* aResMgr = myGeomGUI->getApp()->resourceMgr();
00061   QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_SCALE")));
00062   QPixmap image2 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_SCALE_ALONG_AXES")));
00063   QPixmap image3 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
00064 
00065   setWindowTitle(tr("GEOM_SCALE_TITLE"));
00066 
00067   // Constructors
00068   mainFrame()->GroupConstructors->setTitle(tr("GEOM_SCALE"));
00069   mainFrame()->RadioButton1->setIcon(image1);
00070   mainFrame()->RadioButton2->setIcon(image2);
00071   mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose);
00072   mainFrame()->RadioButton3->close();
00073 
00074   // Own widgets
00075   GroupBox1 = new QGroupBox(tr("GEOM_ARGUMENTS"), this);
00076   QGridLayout* OwnLayout = new QGridLayout(GroupBox1);
00077   OwnLayout->setSpacing(6);
00078   OwnLayout->setMargin(11);
00079 
00080   TextLabel1 = new QLabel(tr("GEOM_OBJECTS"), GroupBox1);
00081   PushButton1 = new QPushButton(GroupBox1);
00082   PushButton1->setIcon(image3);
00083   PushButton1->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
00084   LineEdit1 = new QLineEdit(GroupBox1);
00085   LineEdit1->setReadOnly(true);
00086   LineEdit1->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
00087 
00088   TextLabel2 = new QLabel(tr("GEOM_CENTRAL_POINT"), GroupBox1);
00089   PushButton2 = new QPushButton(GroupBox1);
00090   PushButton2->setIcon(image3);
00091   PushButton2->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
00092   LineEdit2 = new QLineEdit(GroupBox1);
00093   LineEdit2->setReadOnly(true);
00094   LineEdit2->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
00095 
00096   TextLabel3 = new QLabel(tr("GEOM_SCALE_FACTOR"), GroupBox1);
00097   SpinBox_FX = new SalomeApp_DoubleSpinBox(GroupBox1);
00098 
00099   TextLabel4 = new QLabel(tr("GEOM_SCALE_FACTOR_Y"), GroupBox1);
00100   SpinBox_FY = new SalomeApp_DoubleSpinBox(GroupBox1);
00101 
00102   TextLabel5 = new QLabel(tr("GEOM_SCALE_FACTOR_Z"), GroupBox1);
00103   SpinBox_FZ = new SalomeApp_DoubleSpinBox(GroupBox1);
00104 
00105   CheckBoxCopy = new QCheckBox(tr("GEOM_CREATE_COPY"), GroupBox1);
00106   CheckBoxCopy->setChecked(true);
00107 
00108   // Layouting
00109   OwnLayout->addWidget(TextLabel1,   0, 0);
00110   OwnLayout->addWidget(PushButton1,  0, 1);
00111   OwnLayout->addWidget(LineEdit1,    0, 2, 1, 2);
00112   OwnLayout->addWidget(TextLabel2,   1, 0);
00113   OwnLayout->addWidget(PushButton2,  1, 1);
00114   OwnLayout->addWidget(LineEdit2,    1, 2, 1, 2);
00115   OwnLayout->addWidget(TextLabel3,   2, 0);
00116   OwnLayout->addWidget(SpinBox_FX,   2, 2);
00117   OwnLayout->addWidget(TextLabel4,   3, 0);
00118   OwnLayout->addWidget(SpinBox_FY,   3, 2);
00119   OwnLayout->addWidget(TextLabel5,   4, 0);
00120   OwnLayout->addWidget(SpinBox_FZ,   4, 2);
00121   OwnLayout->addWidget(CheckBoxCopy, 5, 0, 1, 4);
00122 
00123   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
00124   layout->setMargin(0); layout->setSpacing(6);
00125   layout->addWidget(GroupBox1);
00126 
00127   setHelpFileName("scale_operation_page.html");
00128 
00129   // Modification of an existing object by offset is not allowed
00130   CheckBoxCopy->hide();
00131 
00132   // Activate Create a Copy mode
00133   CreateCopyModeChanged();
00134 
00135   // Allowed inheritance of children and visual properties by the scaling result
00136   mainFrame()->GroupBoxPublish->show();
00137 
00138   Init();
00139 }
00140 
00141 //=================================================================================
00142 // function : ~TransformationGUI_ScaleDlg()
00143 // purpose  : Destroys the object and frees any allocated resources
00144 //=================================================================================
00145 TransformationGUI_ScaleDlg::~TransformationGUI_ScaleDlg()
00146 {
00147 }
00148 
00149 //=================================================================================
00150 // function : Init()
00151 // purpose  :
00152 //=================================================================================
00153 void TransformationGUI_ScaleDlg::Init()
00154 {
00155   // Min, max, step and decimals for spin boxes & initial values
00156   double aFactor = 2.0;
00157   double SpecificStep = 0.5;
00158 
00159   initSpinBox(SpinBox_FX, COORD_MIN, COORD_MAX, SpecificStep, "parametric_precision" );
00160   initSpinBox(SpinBox_FY, COORD_MIN, COORD_MAX, SpecificStep, "parametric_precision" );
00161   initSpinBox(SpinBox_FZ, COORD_MIN, COORD_MAX, SpecificStep, "parametric_precision" );
00162   SpinBox_FX->setValue(aFactor);
00163   SpinBox_FY->setValue(aFactor);
00164   SpinBox_FZ->setValue(aFactor);
00165 
00166   // init variables
00167   LineEdit1->setText("");
00168   LineEdit2->setText("");
00169 
00170   myObjects.clear();
00171   myPoint.nullify();
00172 
00173   // Signals and slots connections
00174   connect(buttonOk(),        SIGNAL(clicked()), this, SLOT(ClickOnOk()));
00175   connect(buttonApply(),     SIGNAL(clicked()), this, SLOT(ClickOnApply()));
00176   connect(this, SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int)));
00177 
00178   connect(PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
00179   connect(PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
00180 
00181   connect(SpinBox_FX, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox()));
00182   connect(SpinBox_FY, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox()));
00183   connect(SpinBox_FZ, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox()));
00184   
00185   // san : Commented so as not to override specific step settings
00186   //connect(myGeomGUI, SIGNAL(SignalDefaultStepValueChanged(double)), this, SLOT(SetDoubleSpinBoxStep(double)));
00187 
00188   connect(CheckBoxCopy, SIGNAL(toggled(bool)), this, SLOT(CreateCopyModeChanged()));
00189 
00190   initName(tr("GEOM_SCALE"));
00191 
00192   ConstructorsClicked(0);
00193 }
00194 
00195 //=================================================================================
00196 // function : ConstructorsClicked()
00197 // purpose  : Radio button management
00198 //=================================================================================
00199 void TransformationGUI_ScaleDlg::ConstructorsClicked (int constructorId)
00200 {
00201   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
00202 
00203   myPoint.nullify();
00204   LineEdit2->clear();
00205   
00206   switch (constructorId) {
00207   case 0: // translation an object by dx, dy, dz
00208     TextLabel3->setText(tr("GEOM_SCALE_FACTOR"));
00209     TextLabel4->hide();
00210     TextLabel5->hide();
00211     SpinBox_FY->hide();
00212     SpinBox_FZ->hide();
00213 
00214     PushButton1->click();
00215     break;
00216   case 1: // translation an object by 2 points
00217     TextLabel3->setText(tr("GEOM_SCALE_FACTOR_X"));
00218     TextLabel4->show();
00219     TextLabel5->show();
00220     SpinBox_FY->show();
00221     SpinBox_FZ->show();
00222 
00223     PushButton1->click();
00224     break;
00225   default:
00226     break;
00227   }
00228 
00229   qApp->processEvents();
00230   updateGeometry();
00231   resize(minimumSizeHint());
00232 
00233   if (myInitial) {
00234     myInitial = false;
00235     SelectionIntoArgument();
00236   }
00237   else {
00238     processPreview();
00239   }
00240 }
00241 
00242 //=================================================================================
00243 // function : ClickOnOk()
00244 // purpose  :
00245 //=================================================================================
00246 void TransformationGUI_ScaleDlg::ClickOnOk()
00247 {
00248   setIsApplyAndClose( true );
00249   if (ClickOnApply())
00250     ClickOnCancel();
00251 }
00252 
00253 //=================================================================================
00254 // function : ClickOnApply()
00255 // purpose  :
00256 //=================================================================================
00257 bool TransformationGUI_ScaleDlg::ClickOnApply()
00258 {
00259   if (!onAccept(CheckBoxCopy->isChecked()))
00260     return false;
00261 
00262   initName(tr("GEOM_SCALE"));
00263 
00264   // activate selection and connect selection manager
00265   ConstructorsClicked(getConstructorId());
00266   SelectionIntoArgument();
00267 
00268   return true;
00269 }
00270 
00271 //=================================================================================
00272 // function : SelectionIntoArgument()
00273 // purpose  : Called when selection is changed or on dialog initialization or activation
00274 //=================================================================================
00275 void TransformationGUI_ScaleDlg::SelectionIntoArgument()
00276 {
00277   erasePreview();
00278 
00279   if ( myEditCurrentArgument == LineEdit1 ) {
00280     myObjects = getSelected( TopAbs_SHAPE, -1 );
00281     if ( !myObjects.isEmpty() ) {
00282       QString aName = myObjects.count() > 1 ? QString( "%1_objects").arg( myObjects.count() ) : GEOMBase::GetName( myObjects[0].get() );
00283       myEditCurrentArgument->setText( aName );
00284     }
00285     else {
00286       myEditCurrentArgument->setText("");
00287     }
00288   }
00289   else {
00290     GEOM::GeomObjPtr aSelectedObject = getSelected( TopAbs_VERTEX );
00291     TopoDS_Shape aShape;
00292     if ( aSelectedObject && GEOMBase::GetShape( aSelectedObject.get(), aShape ) && !aShape.IsNull() ) {
00293       QString aName = GEOMBase::GetName( aSelectedObject.get() );
00294       myEditCurrentArgument->setText( aName );
00295       myPoint = aSelectedObject;
00296       if ( myObjects.isEmpty() )
00297        PushButton1->click();
00298     }
00299     else {
00300       myPoint.nullify();
00301       myEditCurrentArgument->setText("");
00302     }
00303   }
00304 
00305   processPreview();
00306 }
00307 
00308 //=================================================================================
00309 // function : SetEditCurrentArgument()
00310 // purpose  :
00311 //=================================================================================
00312 void TransformationGUI_ScaleDlg::SetEditCurrentArgument()
00313 {
00314   QPushButton* send = (QPushButton*)sender();
00315 
00316   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
00317   globalSelection();
00318 
00319   if (send == PushButton1) {
00320     myEditCurrentArgument = LineEdit1;
00321 
00322     PushButton2->setDown(false);
00323     LineEdit2->setEnabled(false);
00324   }
00325   else if (send == PushButton2) {
00326     myEditCurrentArgument = LineEdit2;
00327 
00328     localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX);
00329 
00330     PushButton1->setDown(false);
00331     LineEdit1->setEnabled(false);
00332   }
00333   connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
00334           this, SLOT(SelectionIntoArgument()));
00335 
00336   // enable line edit
00337   myEditCurrentArgument->setEnabled(true);
00338   myEditCurrentArgument->setFocus();
00339   // after setFocus(), because it will be setDown(false) when loses focus
00340   send->setDown(true);
00341 
00342   // seems we need it only to avoid preview disappearing, caused by selection mode change
00343   processPreview();
00344 }
00345 
00346 //=================================================================================
00347 // function : ActivateThisDialog()
00348 // purpose  :
00349 //=================================================================================
00350 void TransformationGUI_ScaleDlg::ActivateThisDialog()
00351 {
00352   GEOMBase_Skeleton::ActivateThisDialog();
00353   connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),
00354            this, SLOT( SelectionIntoArgument() ) );
00355 
00356   ConstructorsClicked( getConstructorId() );
00357 }
00358 
00359 //=================================================================================
00360 // function : enterEvent()
00361 // purpose  :
00362 //=================================================================================
00363 void TransformationGUI_ScaleDlg::enterEvent (QEvent*)
00364 {
00365   if (!mainFrame()->GroupConstructors->isEnabled())
00366     ActivateThisDialog();
00367 }
00368 
00369 //=================================================================================
00370 // function : ValueChangedInSpinBox()
00371 // purpose  :
00372 //=================================================================================
00373 void TransformationGUI_ScaleDlg::ValueChangedInSpinBox()
00374 {
00375   processPreview();
00376 }
00377 
00378 //=================================================================================
00379 // function : SetDoubleSpinBoxStep()
00380 // purpose  : Double spin box management
00381 //=================================================================================
00382 void TransformationGUI_ScaleDlg::SetDoubleSpinBoxStep(double step)
00383 {
00384   SpinBox_FX->setSingleStep(step);
00385   SpinBox_FY->setSingleStep(step);
00386   SpinBox_FZ->setSingleStep(step);
00387 }
00388 
00389 //=================================================================================
00390 // function : createOperation
00391 // purpose  :
00392 //=================================================================================
00393 GEOM::GEOM_IOperations_ptr TransformationGUI_ScaleDlg::createOperation()
00394 {
00395   return getGeomEngine()->GetITransformOperations(getStudyId());
00396 }
00397 
00398 //=================================================================================
00399 // function : isValid
00400 // purpose  :
00401 //=================================================================================
00402 bool TransformationGUI_ScaleDlg::isValid (QString& msg)
00403 {
00404   bool ok = false;
00405   if ( getConstructorId() == 0 ) {
00406     ok = SpinBox_FX->isValid( msg, !IsPreview() ) &&
00407          !myObjects.isEmpty() &&
00408          qAbs( SpinBox_FX->value() ) > 0.00001;
00409   }
00410   else {
00411     ok = SpinBox_FX->isValid( msg, !IsPreview() ) &&
00412          SpinBox_FY->isValid( msg, !IsPreview() ) &&
00413          SpinBox_FZ->isValid( msg, !IsPreview() ) &&
00414          !myObjects.isEmpty() &&
00415          qAbs( SpinBox_FX->value() ) > 0.00001 &&
00416          qAbs( SpinBox_FY->value() ) > 0.00001 &&
00417          qAbs( SpinBox_FZ->value() ) > 0.00001;
00418   }
00419   return ok;
00420 }
00421 
00422 //=================================================================================
00423 // function : execute
00424 // purpose  :
00425 //=================================================================================
00426 bool TransformationGUI_ScaleDlg::execute (ObjectList& objects)
00427 {
00428   bool toCreateCopy = IsPreview() || CheckBoxCopy->isChecked();
00429 
00430   GEOM::GEOM_Object_var anObj;
00431 
00432   GEOM::GEOM_ITransformOperations_var anOper = GEOM::GEOM_ITransformOperations::_narrow(getOperation());
00433 
00434   switch (getConstructorId())
00435   {
00436   case 0:
00437     {
00438       if (toCreateCopy)
00439       {
00440         for (int i = 0; i < myObjects.count(); i++)
00441         {
00442           anObj = anOper->ScaleShapeCopy(myObjects[i].get(), myPoint.get(), SpinBox_FX->value());
00443           if (!anObj->_is_nil()) {
00444             if(!IsPreview()) 
00445               anObj->SetParameters(SpinBox_FX->text().toLatin1().constData());
00446             objects.push_back(anObj._retn());
00447           }
00448         }
00449       }
00450       else
00451       {
00452         for (int i = 0; i < myObjects.count(); i++)
00453         {
00454           anObj = anOper->ScaleShape(myObjects[i].get(), myPoint.get(), SpinBox_FX->value());
00455           if (!anObj->_is_nil())
00456             objects.push_back(anObj._retn());
00457         }
00458       }
00459     }
00460     break;
00461   case 1:
00462     {
00463       if (toCreateCopy)
00464       {
00465         for (int i = 0; i < myObjects.count(); i++)
00466         {
00467           anObj = anOper->ScaleShapeAlongAxesCopy(myObjects[i].get(), myPoint.get(), SpinBox_FX->value(),
00468                                                   SpinBox_FY->value(), SpinBox_FZ->value());
00469           if (!anObj->_is_nil())
00470             if(!IsPreview()) {
00471               QStringList aParameters;
00472               aParameters<<SpinBox_FX->text();
00473               aParameters<<SpinBox_FY->text();
00474               aParameters<<SpinBox_FZ->text();
00475               anObj->SetParameters(aParameters.join(":").toLatin1().constData());
00476             }
00477             objects.push_back(anObj._retn());
00478         }
00479       }
00480       else
00481       {
00482         for (int i = 0; i < myObjects.count(); i++)
00483         {
00484           anObj = anOper->ScaleShapeAlongAxes(myObjects[i].get(), myPoint.get(), SpinBox_FX->value(),
00485                                               SpinBox_FY->value(), SpinBox_FZ->value());
00486           if (!anObj->_is_nil())
00487             objects.push_back(anObj._retn());
00488         }
00489       }
00490     }
00491     break;
00492   default:
00493     break;
00494   }
00495 
00496   return true;
00497 }
00498 
00499 //=================================================================================
00500 // function : restoreSubShapes
00501 // purpose  :
00502 //=================================================================================
00503 void TransformationGUI_ScaleDlg::restoreSubShapes (SALOMEDS::Study_ptr   theStudy,
00504                                                    SALOMEDS::SObject_ptr theSObject)
00505 {
00506   if (mainFrame()->CheckBoxRestoreSS->isChecked()) {
00507     // empty list of arguments means that all arguments should be restored
00508     getGeomEngine()->RestoreSubShapesSO(theStudy, theSObject, GEOM::ListOfGO(),
00509                                         /*theFindMethod=*/GEOM::FSM_Transformed,
00510                                         /*theInheritFirstArg=*/true,
00511                                         mainFrame()->CheckBoxAddPrefix->isChecked());
00512   }
00513 }
00514 
00515 //=================================================================================
00516 // function :  CreateCopyModeChanged()
00517 // purpose  :
00518 //=================================================================================
00519 void TransformationGUI_ScaleDlg::CreateCopyModeChanged()
00520 {
00521   mainFrame()->GroupBoxName->setEnabled(CheckBoxCopy->isChecked());
00522 }
00523 
00524 //=================================================================================
00525 // function : addSubshapesToStudy
00526 // purpose  : virtual method to add new SubObjects if local selection
00527 //=================================================================================
00528 void TransformationGUI_ScaleDlg::addSubshapesToStudy()
00529 {
00530   bool toCreateCopy = IsPreview() || CheckBoxCopy->isChecked();
00531   if (toCreateCopy)
00532   {
00533     GEOMBase::PublishSubObject( myPoint.get() );
00534   }
00535 }