Salome HOME
updated copyright message
[modules/geom.git] / src / TransformationGUI / TransformationGUI_MirrorDlg.cxx
1 // Copyright (C) 2007-2023  CEA, EDF, 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, or (at your option) any later version.
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
23 // GEOM GEOMGUI : GUI for Geometry component
24 // File   : TransformationGUI_MirrorDlg.cxx
25 // Author : Lucien PIGNOLONI, Open CASCADE S.A.S.
26 //
27 #include "TransformationGUI_MirrorDlg.h"
28
29 #include <DlgRef.h>
30 #include <GeometryGUI.h>
31 #include <GEOMBase.h>
32
33 #include <SUIT_Session.h>
34 #include <SUIT_ResourceMgr.h>
35 #include <SalomeApp_Application.h>
36 #include <LightApp_SelectionMgr.h>
37
38 // OCCT Includes
39 #include <TopoDS_Shape.hxx>
40 #include <TopoDS_Edge.hxx>
41 #include <TopoDS.hxx>
42 #include <TopExp.hxx>
43 #include <TColStd_IndexedMapOfInteger.hxx>
44 #include <TopTools_IndexedMapOfShape.hxx>
45
46 #include <GEOMImpl_Types.hxx>
47
48 //=================================================================================
49 // class    : TransformationGUI_MirrorDlg()
50 // purpose  : Constructs a TransformationGUI_MirrorDlg which is a child of 'parent', with the
51 //            name 'name' and widget flags set to 'f'.
52 //            The dialog will by default be modeless, unless you set 'modal' to
53 //            TRUE to construct a modal dialog.
54 //=================================================================================
55 TransformationGUI_MirrorDlg::TransformationGUI_MirrorDlg (GeometryGUI* theGeometryGUI, QWidget* parent,
56                                                           bool modal, Qt::WindowFlags fl)
57   : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl),
58     myInitial(true)
59 {
60   SUIT_ResourceMgr* aResMgr = myGeomGUI->getApp()->resourceMgr();
61   QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_MIRROR_POINT")));
62   QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_MIRROR_AXE")));
63   QPixmap image2 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_MIRROR_PLANE")));
64   QPixmap image3 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
65
66   setWindowTitle(tr("GEOM_MIRROR_TITLE"));
67
68   /***************************************************************/
69   mainFrame()->GroupConstructors->setTitle(tr("GEOM_MIRROR"));
70   mainFrame()->RadioButton1->setIcon(image0);
71   mainFrame()->RadioButton2->setIcon(image1);
72   mainFrame()->RadioButton3->setIcon(image2);
73
74   GroupPoints = new DlgRef_2Sel1Spin2Check(centralWidget());
75   GroupPoints->SpinBox_DX->hide();
76   GroupPoints->TextLabel3->hide();
77   GroupPoints->CheckButton2->hide();
78   GroupPoints->GroupBox1->setTitle(tr("GEOM_ARGUMENTS"));
79   GroupPoints->TextLabel1->setText(tr("GEOM_OBJECTS"));
80   GroupPoints->TextLabel2->setText(tr("GEOM_POINT_MIRROR"));
81   GroupPoints->TextLabel2->setFixedWidth(74);
82   GroupPoints->PushButton1->setIcon(image3);
83   GroupPoints->PushButton2->setIcon(image3);
84   GroupPoints->CheckButton1->setText(tr("GEOM_CREATE_COPY"));
85
86   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
87   layout->setMargin(0); layout->setSpacing(6);
88   layout->addWidget(GroupPoints);
89   /***************************************************************/
90
91   setHelpFileName("mirror_operation_page.html");
92
93   // Activate Create a Copy mode
94   GroupPoints->CheckButton1->setChecked(true);
95   CreateCopyModeChanged();
96
97   Init();
98 }
99
100 //=================================================================================
101 // function : ~TransformationGUI_MirrorDlg()
102 // purpose  : Destroys the object and frees any allocated resources
103 //=================================================================================
104 TransformationGUI_MirrorDlg::~TransformationGUI_MirrorDlg()
105 {
106   // no need to delete child widgets, Qt does it all for us
107 }
108
109 //=================================================================================
110 // function : Init()
111 // purpose  :
112 //=================================================================================
113 void TransformationGUI_MirrorDlg::Init()
114 {
115   // init variables
116   GroupPoints->LineEdit1->setReadOnly(true);
117   GroupPoints->LineEdit2->setReadOnly(true);
118
119   GroupPoints->LineEdit1->setText("");
120   GroupPoints->LineEdit2->setText("");
121
122   myObjects.clear();
123   myArgument.nullify();
124
125   mainFrame()->GroupBoxPublish->show();
126
127   // signals and slots connections
128   connect(buttonOk(),    SIGNAL(clicked()), this, SLOT(ClickOnOk()));
129   connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
130
131   connect(this, SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int)));
132
133   connect(GroupPoints->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
134   connect(GroupPoints->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
135
136   connect(GroupPoints->CheckButton1, SIGNAL(toggled(bool)), this, SLOT(CreateCopyModeChanged()));
137
138   initName(tr("GEOM_MIRROR"));
139
140   ConstructorsClicked(0);
141   resize(minimumSizeHint());
142 }
143
144 //=================================================================================
145 // function : ConstructorsClicked()
146 // purpose  : Radio button management
147 //=================================================================================
148 void TransformationGUI_MirrorDlg::ConstructorsClicked (int constructorId)
149 {
150   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
151
152   GroupPoints->LineEdit2->clear();
153   myArgument.nullify();
154
155   switch (constructorId) {
156   case 0: // mirror an object by point
157     GroupPoints->TextLabel2->setText(tr("GEOM_POINT_MIRROR"));
158     break;
159   case 1: // mirror an object by axe
160     GroupPoints->TextLabel2->setText(tr("GEOM_AXE_MIRROR"));
161     break;
162   case 2: // mirror an object by plane
163     GroupPoints->TextLabel2->setText(tr("GEOM_PLANE_MIRROR"));
164     break;
165   }
166
167   GroupPoints->PushButton1->click();
168
169   if (myInitial) {
170     myInitial = false;
171     SelectionIntoArgument();
172   }
173   else {
174     processPreview();
175   }
176 }
177
178 //=================================================================================
179 // function : ClickOnOk()
180 // purpose  :
181 //=================================================================================
182 void TransformationGUI_MirrorDlg::ClickOnOk()
183 {
184   setIsApplyAndClose( true );
185   if (ClickOnApply())
186     ClickOnCancel();
187 }
188
189 //=================================================================================
190 // function : ClickOnApply()
191 // purpose  :
192 //=================================================================================
193 bool TransformationGUI_MirrorDlg::ClickOnApply()
194 {
195   if (!onAccept(GroupPoints->CheckButton1->isChecked()))
196     return false;
197
198   initName();
199
200   // activate selection and connect selection manager
201   ConstructorsClicked(getConstructorId());
202   SelectionIntoArgument();
203
204   return true;
205 }
206
207 //=================================================================================
208 // function : SelectionIntoArgument()
209 // purpose  : Called when selection is changed or on dialog initialization or activation
210 //=================================================================================
211 void TransformationGUI_MirrorDlg::SelectionIntoArgument()
212 {
213   erasePreview();
214
215   if ( myEditCurrentArgument == GroupPoints->LineEdit1 ) {
216     myObjects = getSelected( TopAbs_SHAPE, -1 );
217     if ( !myObjects.isEmpty() ) {
218       QString aName = myObjects.count() > 1 ? QString( "%1_objects").arg( myObjects.count() ) : GEOMBase::GetName( myObjects[0].get() );
219       myEditCurrentArgument->setText( aName );
220     }
221     else {
222       myEditCurrentArgument->setText("");
223     }
224   }
225   else {
226     TopAbs_ShapeEnum aNeedType = ( getConstructorId() == 1 ) ? 
227       TopAbs_EDGE : ( ( getConstructorId() == 2 ) ? TopAbs_FACE : TopAbs_VERTEX );
228     GEOM::GeomObjPtr aSelectedObject = getSelected( aNeedType );
229     TopoDS_Shape aShape;
230     if ( aSelectedObject && GEOMBase::GetShape( aSelectedObject.get(), aShape ) && !aShape.IsNull() ) {
231       QString aName = GEOMBase::GetName( aSelectedObject.get() );
232       myEditCurrentArgument->setText( aName );
233       myArgument = aSelectedObject;
234       if ( myObjects.isEmpty() )
235         GroupPoints->PushButton1->click();
236     }
237     else {
238       if ( myEditCurrentArgument == GroupPoints->LineEdit2 )
239         myArgument.nullify();
240       myEditCurrentArgument->setText("");
241     }
242   }
243
244   processPreview();
245 }
246
247 //=================================================================================
248 // function : SetEditCurrentArgument()
249 // purpose  :
250 //=================================================================================
251 void TransformationGUI_MirrorDlg::SetEditCurrentArgument()
252 {
253   QPushButton* send = (QPushButton*)sender();
254
255   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
256   globalSelection();
257
258   if (send == GroupPoints->PushButton1) {
259     myEditCurrentArgument = GroupPoints->LineEdit1;
260
261     GroupPoints->PushButton2->setDown(false);
262     GroupPoints->LineEdit2->setEnabled(false);
263   }
264   else if (send == GroupPoints->PushButton2) {
265     myEditCurrentArgument = GroupPoints->LineEdit2;
266
267     switch (getConstructorId()) {
268     case 0:
269       localSelection(TopAbs_VERTEX);
270       break;
271     case 1:
272       localSelection(TopAbs_EDGE);
273       break;
274     case 2:
275       globalSelection(GEOM_PLANE);
276       localSelection(TopAbs_FACE);
277       break;
278     }
279
280     GroupPoints->PushButton1->setDown(false);
281     GroupPoints->LineEdit1->setEnabled(false);
282   }
283   connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
284           this, SLOT(SelectionIntoArgument()));
285
286   // enable line edit
287   myEditCurrentArgument->setEnabled(true);
288   myEditCurrentArgument->setFocus();
289   // after setFocus(), because it will be setDown(false) when loses focus
290   send->setDown(true);
291
292   // seems we need it only to avoid preview disappearing, caused by selection mode change
293   processPreview();
294 }
295
296 //=================================================================================
297 // function : ActivateThisDialog()
298 // purpose  :
299 //=================================================================================
300 void TransformationGUI_MirrorDlg::ActivateThisDialog()
301 {
302   GEOMBase_Skeleton::ActivateThisDialog();
303   connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),
304            this, SLOT( SelectionIntoArgument() ) );
305
306   ConstructorsClicked( getConstructorId() );
307 }
308
309 //=================================================================================
310 // function : enterEvent()
311 // purpose  : when mouse enter onto the QWidget
312 //=================================================================================
313 void TransformationGUI_MirrorDlg::enterEvent (QEvent*)
314 {
315   if (!mainFrame()->GroupConstructors->isEnabled())
316     ActivateThisDialog();
317 }
318
319 //=================================================================================
320 // function : createOperation
321 // purpose  :
322 //=================================================================================
323 GEOM::GEOM_IOperations_ptr  TransformationGUI_MirrorDlg::createOperation()
324 {
325   return getGeomEngine()->GetITransformOperations();
326 }
327
328 //=================================================================================
329 // function : isValid
330 // purpose  :
331 //=================================================================================
332 bool TransformationGUI_MirrorDlg::isValid (QString& /*msg*/)
333 {
334   return !myObjects.isEmpty() && myArgument;
335 }
336
337 //=================================================================================
338 // function : execute
339 // purpose  :
340 //=================================================================================
341 bool  TransformationGUI_MirrorDlg::execute (ObjectList& objects)
342 {
343   bool res = false;
344   bool toCreateCopy = IsPreview() || GroupPoints->CheckButton1->isChecked();
345
346   GEOM::GEOM_Object_var anObj;
347
348   GEOM::GEOM_ITransformOperations_var anOper = GEOM::GEOM_ITransformOperations::_narrow(getOperation());
349
350   switch (getConstructorId()) {
351   case 0:
352     {
353       if (toCreateCopy) {
354         for (int i = 0; i < myObjects.count(); i++) {
355           anObj = anOper->MirrorPointCopy(myObjects[i].get(), myArgument.get());
356           if (!anObj->_is_nil())
357             objects.push_back(anObj._retn());
358         }
359       }
360       else {
361         for (int i = 0; i < myObjects.count(); i++) {
362           anObj = anOper->MirrorPoint(myObjects[i].get(), myArgument.get());
363           if (!anObj->_is_nil())
364             objects.push_back(anObj._retn());
365         }
366       }
367       res = true;
368       break;
369     }
370   case 1:
371     {
372       if (toCreateCopy) {
373         for (int i = 0; i < myObjects.count(); i++) {
374           anObj = anOper->MirrorAxisCopy(myObjects[i].get(), myArgument.get());
375           if (!anObj->_is_nil())
376             objects.push_back(anObj._retn());
377         }
378       }
379       else {
380         for (int i = 0; i < myObjects.count(); i++) {
381           anObj = anOper->MirrorAxis(myObjects[i].get(), myArgument.get());
382           if (!anObj->_is_nil())
383             objects.push_back(anObj._retn());
384         }
385       }
386       res = true;
387       break;
388     }
389   case 2:
390     {
391       if (toCreateCopy) {
392         for (int i = 0; i < myObjects.count(); i++) {
393             anObj = anOper->MirrorPlaneCopy(myObjects[i].get(), myArgument.get());
394             if (!anObj->_is_nil())
395               objects.push_back(anObj._retn());
396         }
397       }
398       else {
399         for (int i = 0; i < myObjects.count(); i++) {
400           anObj = anOper->MirrorPlane(myObjects[i].get(), myArgument.get());
401           if (!anObj->_is_nil())
402             objects.push_back(anObj._retn());
403         }
404       }
405       res = true;
406       break;
407     }
408   }
409
410   return res;
411 }
412
413 //=================================================================================
414 // function : restoreSubShapes
415 // purpose  :
416 //=================================================================================
417 void TransformationGUI_MirrorDlg::restoreSubShapes (SALOMEDS::SObject_ptr theSObject)
418 {
419   if (mainFrame()->CheckBoxRestoreSS->isChecked()) {
420     // empty list of arguments means that all arguments should be restored
421     getGeomEngine()->RestoreSubShapesSO(theSObject, GEOM::ListOfGO(),
422                                         /*theFindMethod=*/GEOM::FSM_Transformed,
423                                         /*theInheritFirstArg=*/true,
424                                         mainFrame()->CheckBoxAddPrefix->isChecked());
425   }
426 }
427
428 //=================================================================================
429 // function :  CreateCopyModeChanged()
430 // purpose  :
431 //=================================================================================
432 void TransformationGUI_MirrorDlg::CreateCopyModeChanged()
433 {
434   mainFrame()->GroupBoxName->setEnabled(GroupPoints->CheckButton1->isChecked());
435 }
436
437 //=================================================================================
438 // function : addSubshapeToStudy
439 // purpose  : virtual method to add new SubObjects if local selection
440 //=================================================================================
441 void TransformationGUI_MirrorDlg::addSubshapesToStudy()
442 {
443   bool toCreateCopy = IsPreview() || GroupPoints->CheckButton1->isChecked();
444   if (toCreateCopy) {
445     switch (getConstructorId()) {
446     case 0:
447     case 1:
448     case 2:
449       GEOMBase::PublishSubObject( myArgument.get() );
450       break;
451     default:
452       break;
453     }
454   }
455 }
456
457 //=================================================================================
458 // function : getSourceObjects
459 // purpose  : virtual method to get source objects
460 //=================================================================================
461 QList<GEOM::GeomObjPtr> TransformationGUI_MirrorDlg::getSourceObjects()
462 {
463   QList<GEOM::GeomObjPtr> res;
464   if ( GroupPoints->CheckButton1->isChecked() ) {
465     res.append(myObjects);
466     res << myArgument;
467   }
468   return res;
469 }