Salome HOME
Mantis issue 0021200: Problem of performance when doing a partition. A fix by PKV.
[modules/geom.git] / src / TransformationGUI / TransformationGUI_MultiRotationDlg.cxx
1 //  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  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 //  GEOM GEOMGUI : GUI for Geometry component
23 //  File   : TransformationGUI_MultiRotationDlg.cxx
24 //  Author : Damien COQUERET, Open CASCADE S.A.S.
25
26 #include "TransformationGUI_MultiRotationDlg.h"
27
28 #include <DlgRef.h>
29 #include <GeometryGUI.h>
30 #include <GEOMBase.h>
31
32 #include <SUIT_Session.h>
33 #include <SUIT_ResourceMgr.h>
34 #include <SalomeApp_Application.h>
35 #include <LightApp_SelectionMgr.h>
36
37 // OCCT Includes
38 #include <TopoDS_Shape.hxx>
39 #include <TopoDS_Edge.hxx>
40 #include <TopoDS.hxx>
41 #include <TopExp.hxx>
42 #include <TColStd_IndexedMapOfInteger.hxx>
43 #include <TopTools_IndexedMapOfShape.hxx>
44
45 #include <GEOMImpl_Types.hxx>
46
47 //=================================================================================
48 // class    : TransformationGUI_MultiRotationDlg()
49 // purpose  : Constructs a TransformationGUI_MultiRotationDlg which is a child of 'parent', with the
50 //            name 'name' and widget flags set to 'f'.
51 //            The dialog will by default be modeless, unless you set 'modal' to
52 //            TRUE to construct a modal dialog.
53 //=================================================================================
54 TransformationGUI_MultiRotationDlg::TransformationGUI_MultiRotationDlg
55 (GeometryGUI* theGeometryGUI, QWidget* parent, bool modal, Qt::WindowFlags fl)
56   : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl),
57     myInitial(true)
58 {
59   SUIT_ResourceMgr* aResMgr = myGeomGUI->getApp()->resourceMgr();
60   QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_MULTIROTATION_SIMPLE")));
61   QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_MULTIROTATION_DOUBLE")));
62   QPixmap image2 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
63
64   setWindowTitle(tr("GEOM_MULTIROTATION_TITLE"));
65
66   /***************************************************************/
67   mainFrame()->GroupConstructors->setTitle(tr("GEOM_MULTIROTATION"));
68   mainFrame()->RadioButton1->setIcon(image0);
69   mainFrame()->RadioButton2->setIcon(image1);
70   mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose);
71   mainFrame()->RadioButton3->close();
72
73   GroupPoints = new DlgRef_2Sel1SpinInt(centralWidget());
74   GroupPoints->GroupBox1->setTitle(tr("GEOM_MULTIROTATION_SIMPLE"));
75   GroupPoints->TextLabel1->setText(tr("GEOM_MAIN_OBJECT"));
76   GroupPoints->TextLabel2->setText(tr("GEOM_VECTOR"));
77   GroupPoints->TextLabel3->setText(tr("GEOM_NB_TIMES"));
78   GroupPoints->PushButton1->setIcon(image2);
79   GroupPoints->PushButton2->setIcon(image2);
80   GroupPoints->LineEdit1->setReadOnly(true);
81   GroupPoints->LineEdit2->setReadOnly(true);
82
83   GroupDimensions = new DlgRef_2Sel4Spin1Check(centralWidget());
84   GroupDimensions->GroupBox1->setTitle(tr("GEOM_MULTIROTATION_DOUBLE"));
85   GroupDimensions->TextLabel1->setText(tr("GEOM_MAIN_OBJECT"));
86   GroupDimensions->TextLabel2->setText(tr("GEOM_VECTOR"));
87   GroupDimensions->TextLabel3->setText(tr("GEOM_ANGLE"));
88   GroupDimensions->TextLabel4->setText(tr("GEOM_NB_TIMES"));
89   GroupDimensions->TextLabel5->setText(tr("GEOM_STEP"));
90   GroupDimensions->TextLabel6->setText(tr("GEOM_NB_TIMES"));
91   GroupDimensions->CheckButton1->setText(tr("GEOM_REVERSE"));
92   GroupDimensions->PushButton1->setIcon(image2);
93   GroupDimensions->PushButton2->setIcon(image2);
94   GroupDimensions->LineEdit1->setReadOnly(true);
95   GroupDimensions->LineEdit2->setReadOnly(true);
96
97   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
98   layout->setMargin(0); layout->setSpacing(6);
99   layout->addWidget(GroupPoints);
100   layout->addWidget(GroupDimensions);
101   /***************************************************************/
102
103   setHelpFileName("multi_rotation_operation_page.html");
104
105   Init();
106 }
107
108 //=================================================================================
109 // function : ~TransformationGUI_MultiRotationDlg()
110 // purpose  : Destroys the object and frees any allocated resources
111 //=================================================================================
112 TransformationGUI_MultiRotationDlg::~TransformationGUI_MultiRotationDlg()
113 {
114   // no need to delete child widgets, Qt does it all for us
115 }
116
117 //=================================================================================
118 // function : Init()
119 // purpose  :
120 //=================================================================================
121 void TransformationGUI_MultiRotationDlg::Init()
122 {
123   // Get setting of step value from file configuration
124   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
125   double step = resMgr->doubleValue("Geometry", "SettingsGeomStep", 100);
126
127   int SpecificStep1 = 5;
128   int SpecificStep2 = 1;
129   // init variables
130   myAng = 45.0;
131   myStep = 50.0;
132   myNbTimes1 = myNbTimes2 = 2;
133
134   // min, max, step and decimals for spin boxes & initial values
135   initSpinBox(GroupPoints->SpinBox_DX, 1, 999, SpecificStep2);
136   GroupPoints->SpinBox_DX->setValue(myNbTimes1);
137
138   initSpinBox(GroupDimensions->SpinBox_DX1, COORD_MIN, COORD_MAX, SpecificStep1, "angle_precision" );
139   initSpinBox(GroupDimensions->SpinBox_DY1, 1, 999, SpecificStep2);
140   initSpinBox(GroupDimensions->SpinBox_DX2, COORD_MIN, COORD_MAX, step,"length_precision" );
141   initSpinBox(GroupDimensions->SpinBox_DY2, 1, 999, SpecificStep2);
142   GroupDimensions->SpinBox_DX1->setValue(myAng);
143   GroupDimensions->SpinBox_DY1->setValue(myNbTimes1);
144   GroupDimensions->SpinBox_DX2->setValue(myStep);
145   GroupDimensions->SpinBox_DY2->setValue(myNbTimes2);
146
147   GroupPoints->LineEdit1->setText("");
148   GroupPoints->LineEdit2->setText("");
149
150   GroupDimensions->LineEdit1->setText("");
151   GroupDimensions->LineEdit2->setText("");
152
153   myBase.nullify();
154   myVector.nullify();
155
156   mainFrame()->GroupBoxPublish->show();
157
158   // signals and slots connections
159   connect(buttonOk(),    SIGNAL(clicked()), this, SLOT(ClickOnOk()));
160   connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
161
162   connect(this,          SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int)));
163
164   connect(GroupPoints->PushButton1,     SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
165   connect(GroupPoints->PushButton2,     SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
166   connect(GroupDimensions->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
167   connect(GroupDimensions->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
168
169   connect(GroupPoints->SpinBox_DX,      SIGNAL(valueChanged(int)),    this, SLOT(ValueChangedInSpinBox(int)));
170   connect(GroupDimensions->SpinBox_DX1, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
171   connect(GroupDimensions->SpinBox_DY1, SIGNAL(valueChanged(int)),    this, SLOT(ValueChangedInSpinBox(int)));
172   connect(GroupDimensions->SpinBox_DX2, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
173   connect(GroupDimensions->SpinBox_DY2, SIGNAL(valueChanged(int)),    this, SLOT(ValueChangedInSpinBox(int)));
174
175   connect(GroupDimensions->SpinBox_DX1,SIGNAL(textChanged( const QString& )),
176           this, SLOT(TextValueChangedInSpinBox( const QString& )));
177
178   connect(myGeomGUI, SIGNAL(SignalDefaultStepValueChanged(double)), this, SLOT(SetDoubleSpinBoxStep(double)));
179
180   connect(GroupDimensions->CheckButton1, SIGNAL(toggled(bool)), this, SLOT(ReverseAngle()));
181
182   initName(tr("GEOM_MULTIROTATION"));
183
184   ConstructorsClicked(0);
185 }
186
187 //=================================================================================
188 // function : SetDoubleSpinBoxStep()
189 // purpose  : Double spin box management
190 //=================================================================================
191 void TransformationGUI_MultiRotationDlg::SetDoubleSpinBoxStep (double step)
192 {
193   GroupDimensions->SpinBox_DX2->setSingleStep(step);
194
195   // san: Commented so as not to override specific step settings
196   //GroupPoints->SpinBox_DX->setSingleStep((int)step);
197   //GroupDimensions->SpinBox_DX1->setSingleStep(step);
198   //GroupDimensions->SpinBox_DY1->setSingleStep((int)step);
199   //GroupDimensions->SpinBox_DY2->setSingleStep((int)step);
200 }
201
202 //=================================================================================
203 // function : ConstructorsClicked()
204 // purpose  : Radio button management
205 //=================================================================================
206 void TransformationGUI_MultiRotationDlg::ConstructorsClicked (int constructorId)
207 {
208   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
209
210   switch (constructorId) {
211   case 0: // Rotate simple
212     {
213       GroupDimensions->hide();
214       GroupPoints->show();
215
216       GroupPoints->LineEdit1->setText("");
217       GroupPoints->LineEdit2->setText("");
218       myBase.nullify();
219       myVector.nullify();
220
221       GroupPoints->SpinBox_DX->setValue(myNbTimes1);
222
223       GroupPoints->PushButton1->click();
224     }
225     break;
226   case 1: // Rotate double
227     {
228       GroupPoints->hide();
229       GroupDimensions->show();
230
231       GroupDimensions->LineEdit1->setText("");
232       GroupDimensions->LineEdit2->setText("");
233       myBase.nullify();
234       myVector.nullify();
235
236       GroupDimensions->SpinBox_DX1->setValue(myAng);
237       GroupDimensions->SpinBox_DY1->setValue(myNbTimes1);
238       GroupDimensions->SpinBox_DX2->setValue(myStep);
239       GroupDimensions->SpinBox_DY2->setValue(myNbTimes2);
240
241       GroupDimensions->PushButton1->click();
242     }
243     break;
244   }
245
246   qApp->processEvents();
247   updateGeometry();
248   resize(minimumSizeHint());
249
250   if (myInitial) {
251     myInitial = false;
252     SelectionIntoArgument();
253   }
254   else {
255     displayPreview();
256   }
257 }
258
259 //=================================================================================
260 // function : ClickOnOk()
261 // purpose  :
262 //=================================================================================
263 void TransformationGUI_MultiRotationDlg::ClickOnOk()
264 {
265   if (ClickOnApply())
266     ClickOnCancel();
267 }
268
269 //=================================================================================
270 // function : ClickOnApply()
271 // purpose  :
272 //=================================================================================
273 bool TransformationGUI_MultiRotationDlg::ClickOnApply()
274 {
275   if (!onAccept())
276     return false;
277
278   initName();
279   // activate selection and connect selection manager
280   ConstructorsClicked(getConstructorId());
281   return true;
282 }
283
284 //=================================================================================
285 // function : SelectionIntoArgument()
286 // purpose  : Called when selection is changed or on dialog initialization or activation
287 //=================================================================================
288 void TransformationGUI_MultiRotationDlg::SelectionIntoArgument()
289 {
290   erasePreview();
291
292   TopAbs_ShapeEnum aNeedType = ( myEditCurrentArgument == GroupPoints->LineEdit2 ||
293                                  myEditCurrentArgument == GroupDimensions->LineEdit2 ) ?
294     TopAbs_EDGE : TopAbs_SHAPE;
295   GEOM::GeomObjPtr aSelectedObject = getSelected( aNeedType );
296   TopoDS_Shape aShape;
297   if ( aSelectedObject && GEOMBase::GetShape( aSelectedObject.get(), aShape ) && !aShape.IsNull() ) {
298     QString aName = GEOMBase::GetName( aSelectedObject.get() );
299     myEditCurrentArgument->setText( aName );
300     if ( myEditCurrentArgument == GroupPoints->LineEdit1 ) {
301       myBase = aSelectedObject;
302       if ( !myVector )
303         GroupPoints->PushButton2->click();
304     }
305     else if ( myEditCurrentArgument == GroupPoints->LineEdit2)  {
306       myVector = aSelectedObject;
307       if ( !myBase )
308         GroupPoints->PushButton1->click();
309     }
310     else if ( myEditCurrentArgument == GroupDimensions->LineEdit1 ) {
311       myBase = aSelectedObject;
312       if ( !myVector )
313         GroupDimensions->PushButton2->click();
314     }
315     else if ( myEditCurrentArgument == GroupDimensions->LineEdit2 ) {
316       myVector = aSelectedObject;
317       if ( !myBase )
318         GroupDimensions->PushButton1->click();
319     }
320     
321     // clear selection
322     disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
323     myGeomGUI->getApp()->selectionMgr()->clearSelected();
324     connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
325             this, SLOT(SelectionIntoArgument()));
326   }
327   else {
328     if ( myEditCurrentArgument == GroupPoints->LineEdit1 ||
329          myEditCurrentArgument == GroupDimensions->LineEdit1 )
330       myBase.nullify();
331     else if ( myEditCurrentArgument == GroupPoints->LineEdit2 ||
332               myEditCurrentArgument == GroupDimensions->LineEdit2 )
333       myVector.nullify();
334     myEditCurrentArgument->setText("");
335   }
336
337   displayPreview();
338 }
339
340 //=================================================================================
341 // function : SetEditCurrentArgument()
342 // purpose  :
343 //=================================================================================
344 void TransformationGUI_MultiRotationDlg::SetEditCurrentArgument()
345 {
346   QPushButton* send = (QPushButton*)sender();
347
348   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
349   globalSelection(GEOM_ALLSHAPES);
350
351   if (send == GroupPoints->PushButton1) {
352     myEditCurrentArgument = GroupPoints->LineEdit1;
353
354     GroupPoints->PushButton2->setDown(false);
355     GroupPoints->LineEdit2->setEnabled(false);
356   }
357   else if (send == GroupPoints->PushButton2) {
358     myEditCurrentArgument = GroupPoints->LineEdit2;
359
360     localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE);
361
362     GroupPoints->PushButton1->setDown(false);
363     GroupPoints->LineEdit1->setEnabled(false);
364   }
365   else if (send == GroupDimensions->PushButton1) {
366     myEditCurrentArgument = GroupDimensions->LineEdit1;
367
368     GroupDimensions->PushButton2->setDown(false);
369     GroupDimensions->LineEdit2->setEnabled(false);
370   }
371   else if (send == GroupDimensions->PushButton2) {
372     myEditCurrentArgument = GroupDimensions->LineEdit2;
373
374     localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE);
375
376     GroupDimensions->PushButton1->setDown(false);
377     GroupDimensions->LineEdit1->setEnabled(false);
378   }
379   connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
380           this, SLOT(SelectionIntoArgument()));
381
382   // enable line edit
383   myEditCurrentArgument->setEnabled(true);
384   myEditCurrentArgument->setFocus();
385   // after setFocus(), because it will be setDown(false) when loses focus
386   send->setDown(true);
387
388   // seems we need it only to avoid preview disappearing, caused by selection mode change
389   displayPreview();
390 }
391
392 //=================================================================================
393 // function : ActivateThisDialog()
394 // purpose  :
395 //=================================================================================
396 void TransformationGUI_MultiRotationDlg::ActivateThisDialog()
397 {
398   GEOMBase_Skeleton::ActivateThisDialog();
399   connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),
400            this, SLOT( SelectionIntoArgument() ) );
401
402   ConstructorsClicked( getConstructorId() );
403 }
404
405 //=================================================================================
406 // function : enterEvent()
407 // purpose  :
408 //=================================================================================
409 void TransformationGUI_MultiRotationDlg::enterEvent (QEvent*)
410 {
411   if (!mainFrame()->GroupConstructors->isEnabled())
412     ActivateThisDialog();
413 }
414
415 //=================================================================================
416 // function : TextValueChangedInSpinBox()
417 // purpose  :
418 //=================================================================================
419 void TransformationGUI_MultiRotationDlg::TextValueChangedInSpinBox(const QString& s){
420   bool isDigit;
421   s.toDouble(&isDigit);
422   if(!isDigit)
423     GroupDimensions->CheckButton1->setChecked(false);
424   GroupDimensions->CheckButton1->setEnabled(isDigit);
425 }
426
427 //=================================================================================
428 // function : ValueChangedInSpinBox()
429 // purpose  :
430 //=================================================================================
431 void TransformationGUI_MultiRotationDlg::ValueChangedInSpinBox (double newValue)
432 {
433   QObject* send = (QObject*)sender();
434
435   if (send == GroupDimensions->SpinBox_DX1)
436     myAng = newValue;
437   else if (send == GroupDimensions->SpinBox_DX2)
438     myStep = newValue;
439
440   displayPreview();
441 }
442
443 //=================================================================================
444 // function : ValueChangedInSpinBox()
445 // purpose  :
446 //=================================================================================
447 void TransformationGUI_MultiRotationDlg::ValueChangedInSpinBox (int newValue)
448 {
449   QObject* send = (QObject*)sender();
450
451   if (send == GroupPoints->SpinBox_DX || send == GroupDimensions->SpinBox_DY1)
452     myNbTimes1 = newValue;
453   else if (send == GroupDimensions->SpinBox_DY2)
454     myNbTimes2 = newValue;
455
456   displayPreview();
457 }
458
459 //=================================================================================
460 // function : ReverseAngle()
461 // purpose  : 'state' not used here
462 //=================================================================================
463 void TransformationGUI_MultiRotationDlg::ReverseAngle()
464 {
465   myAng = -myAng;
466
467   int aConstructorId = getConstructorId();
468
469   if (aConstructorId == 1)
470     GroupDimensions->SpinBox_DX1->setValue(myAng);
471
472   displayPreview();
473 }
474
475 //=================================================================================
476 // function : createOperation
477 // purpose  :
478 //=================================================================================
479 GEOM::GEOM_IOperations_ptr TransformationGUI_MultiRotationDlg::createOperation()
480 {
481   return getGeomEngine()->GetITransformOperations(getStudyId());
482 }
483
484 //=================================================================================
485 // function : isValid
486 // purpose  :
487 //=================================================================================
488 bool TransformationGUI_MultiRotationDlg::isValid (QString& msg)
489 {
490   bool ok = false;
491   switch(getConstructorId()){
492   case 0:
493     ok = GroupPoints->SpinBox_DX->isValid( msg, !IsPreview() ) &&  myBase && myVector;
494     break;
495   case 1:
496     ok = GroupDimensions->SpinBox_DX1->isValid( msg, !IsPreview() ) &&
497          GroupDimensions->SpinBox_DY1->isValid( msg, !IsPreview() ) &&
498          GroupDimensions->SpinBox_DX2->isValid( msg, !IsPreview() ) &&
499          GroupDimensions->SpinBox_DY2->isValid( msg, !IsPreview() ) &&
500          myBase && myVector;
501     break;
502   default:
503     break;
504   }
505   return ok;
506 }
507
508 //=================================================================================
509 // function : execute
510 // purpose  :
511 //=================================================================================
512 bool TransformationGUI_MultiRotationDlg::execute (ObjectList& objects)
513 {
514   bool res = false;
515
516   GEOM::GEOM_Object_var anObj;
517   QStringList aParameters;
518
519   GEOM::GEOM_ITransformOperations_var anOper = GEOM::GEOM_ITransformOperations::_narrow(getOperation());
520
521   switch (getConstructorId()) {
522   case 0:
523     if ( myBase && myVector ) {
524       anObj = anOper->MultiRotate1D(myBase.get(), myVector.get(), myNbTimes1);
525       if(!IsPreview())
526         aParameters<<GroupPoints->SpinBox_DX->text();
527       res = true;
528     }
529     break;
530   case 1:
531     if ( myBase && myVector ) {
532       anObj = anOper->MultiRotate2D(myBase.get(), myVector.get(), myAng, myNbTimes1, myStep, myNbTimes2);
533       if(!IsPreview()) {
534         aParameters<<GroupDimensions->SpinBox_DX1->text();
535         aParameters<<GroupDimensions->SpinBox_DY1->text();
536         aParameters<<GroupDimensions->SpinBox_DX2->text();
537         aParameters<<GroupDimensions->SpinBox_DY2->text();
538       }
539       res = true;
540     }
541     break;
542   }
543
544   if (!anObj->_is_nil()) {
545     if(!IsPreview())
546       anObj->SetParameters(aParameters.join(":").toLatin1().constData());
547     objects.push_back(anObj._retn());
548   }
549
550   return res;
551 }
552
553 //=================================================================================
554 // function : addSubshapeToStudy
555 // purpose  : virtual method to add new SubObjects if local selection
556 //=================================================================================
557 void TransformationGUI_MultiRotationDlg::addSubshapesToStudy()
558 {
559   switch (getConstructorId()) {
560   case 0:
561   case 1:
562     GEOMBase::PublishSubObject( myVector.get() );
563     break;
564   default:
565     break;
566   }
567 }
568
569 //=================================================================================
570 // function : restoreSubShapes
571 // purpose  :
572 //=================================================================================
573 void TransformationGUI_MultiRotationDlg::restoreSubShapes (SALOMEDS::Study_ptr   theStudy,
574                                                            SALOMEDS::SObject_ptr theSObject)
575 {
576   if (mainFrame()->CheckBoxRestoreSS->isChecked()) {
577     // we pass here the first operation argument (object) through the list of arguments
578     // because the rotation operation place its arguments in the data structure in another order,
579     // and we need to point the first argument directly
580     GEOM::ListOfGO_var anArgs = new GEOM::ListOfGO;
581     anArgs->length(1);
582     anArgs[0] = myBase.copy();
583     getGeomEngine()->RestoreSubShapesSO(theStudy, theSObject, anArgs,
584                                         /*theFindMethod=*/GEOM::FSM_MultiTransformed,
585                                         /*theInheritFirstArg=*/true,
586                                         mainFrame()->CheckBoxAddPrefix->isChecked());
587   }
588 }