Salome HOME
8e2470f053e401c33d2929730698a88c5f00e446
[modules/geom.git] / src / BuildGUI / BuildGUI_EdgeDlg.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   : BuildGUI_EdgeDlg.cxx
25 // Author : Lucien PIGNOLONI, Open CASCADE S.A.S.
26
27 #include "BuildGUI_EdgeDlg.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 #include <GEOMImpl_Types.hxx>
39 #include <TColStd_IndexedMapOfInteger.hxx>
40
41 //=================================================================================
42 // class    : BuildGUI_EdgeDlg()
43 // purpose  : Constructs a BuildGUI_EdgeDlg which is a child of 'parent', with the
44 //            name 'name' and widget flags set to 'f'.
45 //            The dialog will by default be modeless, unless you set 'modal' to
46 //            TRUE to construct a modal dialog.
47 //=================================================================================
48 BuildGUI_EdgeDlg::BuildGUI_EdgeDlg (GeometryGUI* theGeometryGUI, QWidget* parent)
49   : GEOMBase_Skeleton(theGeometryGUI, parent)
50 {
51   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
52   QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
53   QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_BUILD_EDGE")));
54   QPixmap image2 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_BUILD_EDGE_WIRE")));
55   QPixmap image3 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_BUILD_EDGE_CURVE")));
56
57   setWindowTitle(tr("GEOM_EDGE_TITLE"));
58
59   /***************************************************************/
60   mainFrame()->GroupConstructors->setTitle(tr("GEOM_EDGE"));
61   mainFrame()->RadioButton1->setIcon(image1);
62   mainFrame()->RadioButton2->setIcon(image2);
63   mainFrame()->RadioButton3->setIcon(image3);
64
65   // two points
66
67   GroupPoints = new DlgRef_2Sel(centralWidget());
68   GroupPoints->GroupBox1->setTitle(tr("GEOM_POINTS"));
69   GroupPoints->TextLabel1->setText(tr("GEOM_POINT_I").arg(1));
70   GroupPoints->TextLabel2->setText(tr("GEOM_POINT_I").arg(2));
71   GroupPoints->PushButton1->setIcon(image0);
72   GroupPoints->PushButton2->setIcon(image0);
73   GroupPoints->LineEdit1->setReadOnly(true);
74   GroupPoints->LineEdit2->setReadOnly(true);
75
76   // wire
77
78   GroupWire = new DlgRef_1Sel2Spin(centralWidget());
79   GroupWire->GroupBox1->setTitle(tr("GEOM_WIRE"));
80   GroupWire->TextLabel1->setText(tr("GEOM_WIRE"));
81   GroupWire->PushButton1->setIcon(image0);
82   GroupWire->LineEdit1->setReadOnly(true);
83   GroupWire->TextLabel2->setText(tr("GEOM_LINEAR_TOLERANCE"));
84   GroupWire->TextLabel3->setText(tr("GEOM_ANGULAR_TOLERANCE"));
85   double SpecificStep = 0.0001;
86   double prec1 = Precision::Confusion();
87   double prec2 = Precision::Angular();
88   initSpinBox(GroupWire->SpinBox_DX, prec1, MAX_NUMBER, SpecificStep, "len_tol_precision");
89   initSpinBox(GroupWire->SpinBox_DY, prec2, MAX_NUMBER, SpecificStep, "ang_tol_precision");
90   GroupWire->SpinBox_DX->setValue(prec1);
91   GroupWire->SpinBox_DY->setValue(prec2);
92
93   // on curve
94
95   GroupOnCurve = new DlgRef_2Sel1Spin(centralWidget());
96   GroupOnCurve->GroupBox1->setTitle(tr("GEOM_ARGUMENTS"));
97   GroupOnCurve->TextLabel1->setText(tr("GEOM_EDGE"));
98   GroupOnCurve->PushButton1->setIcon(image0);
99   GroupOnCurve->LineEdit1->setReadOnly(true);
100   GroupOnCurve->TextLabel2->setText(tr("GEOM_START_POINT"));
101   GroupOnCurve->PushButton2->setIcon(image0);
102   GroupOnCurve->LineEdit2->setReadOnly(true);
103   GroupOnCurve->TextLabel3->setText(tr("GEOM_LENGTH"));
104   double step = aResMgr->doubleValue("Geometry", "SettingsGeomStep", 100.0);
105   initSpinBox(GroupOnCurve->SpinBox_DX, COORD_MIN, COORD_MAX, step, "length_precision");
106   GroupOnCurve->SpinBox_DX->setValue(step);
107
108   // layout
109
110   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
111   layout->setMargin(0); layout->setSpacing(6);
112   layout->addWidget(GroupPoints);
113   layout->addWidget(GroupWire);
114   layout->addWidget(GroupOnCurve);
115   /***************************************************************/
116
117   setHelpFileName("create_edge_page.html");
118
119   // initialisation
120   Init();
121 }
122
123 //=================================================================================
124 // function : ~BuildGUI_EdgeDlg()
125 // purpose  : Destroys the object and frees any allocated resources
126 //=================================================================================
127 BuildGUI_EdgeDlg::~BuildGUI_EdgeDlg()
128 {
129   // no need to delete child widgets, Qt does it all for us
130 }
131
132 //=================================================================================
133 // function : Init()
134 // purpose  :
135 //=================================================================================
136 void BuildGUI_EdgeDlg::Init()
137 {
138   // init variables
139   myPoint1.nullify();
140   myPoint2.nullify();
141   myWire.nullify();
142   myCurve.nullify();
143   myStartPoint.nullify();
144
145   myEditCurrentArgument = GroupPoints->LineEdit1;
146   GroupPoints->PushButton1->setDown(true);
147   globalSelection(); // close local contexts, if any
148   localSelection(TopAbs_VERTEX);
149
150   // signals and slots connections
151   connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
152   connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()),        this, SLOT(ClickOnCancel()));
153
154   connect(this,      SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int)));
155
156   connect(buttonOk(),    SIGNAL(clicked()), this, SLOT(ClickOnOk()));
157   connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
158
159   connect(GroupPoints->PushButton1,  SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
160   connect(GroupPoints->PushButton2,  SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
161   connect(GroupWire->PushButton1,    SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
162   connect(GroupOnCurve->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
163   connect(GroupOnCurve->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
164
165   connect(GroupOnCurve->SpinBox_DX, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
166
167   connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
168            this, SLOT(SelectionIntoArgument()));
169
170   initName(tr("GEOM_EDGE"));
171
172   ConstructorsClicked(0);
173 }
174
175 //=================================================================================
176 // function : ClickOnOk()
177 // purpose  :
178 //=================================================================================
179 void BuildGUI_EdgeDlg::ClickOnOk()
180 {
181   setIsApplyAndClose( true );
182   if (ClickOnApply())
183     ClickOnCancel();
184 }
185
186 //=================================================================================
187 // function : ClickOnApply()
188 // purpose  :
189 //=================================================================================
190 bool BuildGUI_EdgeDlg::ClickOnApply()
191 {
192   if (!onAccept())
193     return false;
194
195   initName();
196
197   myEditCurrentArgument->setText("");
198   ConstructorsClicked(getConstructorId());
199
200   return true;
201 }
202
203 //=================================================================================
204 // function : ConstructorsClicked()
205 // purpose  : Radio button management
206 //=================================================================================
207 void BuildGUI_EdgeDlg::ConstructorsClicked(int constructorId)
208 {
209   switch (constructorId) {
210   case 0:
211     {
212       globalSelection(); // close local contexts, if any
213       localSelection(TopAbs_VERTEX);
214
215       myEditCurrentArgument = GroupPoints->LineEdit1;
216       GroupPoints->LineEdit1->setText("");
217       GroupPoints->LineEdit2->setText("");
218       myPoint1.nullify();
219       myPoint2.nullify();
220       GroupPoints->PushButton1->setDown(true);
221       GroupPoints->PushButton2->setDown(false);
222       GroupPoints->LineEdit1->setEnabled(true);
223       GroupPoints->LineEdit2->setEnabled(false);
224       GroupPoints->show();
225       GroupWire->hide();
226       GroupOnCurve->hide();
227       break;
228     }
229   case 1:
230     {
231       globalSelection(); // close local contexts, if any
232       localSelection(TopAbs_WIRE);
233
234       myEditCurrentArgument = GroupWire->LineEdit1;
235       GroupWire->LineEdit1->setText("");
236       myWire.nullify();
237       GroupWire->PushButton1->setDown(true);
238       GroupWire->LineEdit1->setEnabled(true);
239       GroupPoints->hide();
240       GroupOnCurve->hide();
241       GroupWire->show();
242       break;
243     }
244   case 2:
245     {
246       globalSelection(); // close local contexts, if any
247       localSelection(TopAbs_EDGE);
248
249       myEditCurrentArgument = GroupOnCurve->LineEdit1;
250       GroupOnCurve->LineEdit1->setText("");
251       GroupOnCurve->LineEdit2->setText("");
252       myCurve.nullify();
253       myStartPoint.nullify();
254       GroupOnCurve->PushButton1->setDown(true);
255       GroupOnCurve->PushButton2->setDown(false);
256       GroupOnCurve->LineEdit1->setEnabled(true);
257       GroupOnCurve->LineEdit2->setEnabled(false);
258       GroupPoints->hide();
259       GroupWire->hide();
260       GroupOnCurve->show();
261       break;
262     }
263   }
264
265   qApp->processEvents();
266   updateGeometry();
267   resize(minimumSizeHint());
268   SelectionIntoArgument();
269 }
270
271 //=================================================================================
272 // function : SelectionIntoArgument()
273 // purpose  : Called when selection is changed or on dialog initialization or activation
274 //=================================================================================
275 void BuildGUI_EdgeDlg::SelectionIntoArgument()
276 {
277   erasePreview();
278   myEditCurrentArgument->setText("");
279
280   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
281   SALOME_ListIO aSelList;
282   aSelMgr->selectedObjects(aSelList);
283
284   if (aSelList.Extent() != 1) {
285     if      (myEditCurrentArgument == GroupPoints->LineEdit1)  myPoint1.nullify();
286     else if (myEditCurrentArgument == GroupPoints->LineEdit2)  myPoint2.nullify();
287     else if (myEditCurrentArgument == GroupWire->LineEdit1)    myWire.nullify();
288     else if (myEditCurrentArgument == GroupOnCurve->LineEdit1) myCurve.nullify();
289     else if (myEditCurrentArgument == GroupOnCurve->LineEdit2) myStartPoint.nullify();
290     displayPreview(true);
291     return;
292   }
293
294   TopAbs_ShapeEnum aNeedType = TopAbs_VERTEX;
295   if (myEditCurrentArgument == GroupWire->LineEdit1) aNeedType = TopAbs_WIRE;
296   else if (myEditCurrentArgument == GroupOnCurve->LineEdit1) aNeedType = TopAbs_EDGE;
297   GEOM::GeomObjPtr aSelectedObject = getSelected(aNeedType);
298
299   TopoDS_Shape aShape;
300   if (aSelectedObject && GEOMBase::GetShape(aSelectedObject.get(), aShape) && !aShape.IsNull()) {
301     QString aName = GEOMBase::GetName(aSelectedObject.get());
302     myEditCurrentArgument->setText(aName);
303
304     globalSelection();
305     localSelection(aNeedType);
306
307     if (myEditCurrentArgument == GroupPoints->LineEdit1) {
308       myPoint1 = aSelectedObject;
309       if (myPoint1 && !myPoint2)
310         GroupPoints->PushButton2->click();
311     }
312     else if (myEditCurrentArgument == GroupPoints->LineEdit2) {
313       myPoint2 = aSelectedObject;
314       if (myPoint2 && !myPoint1)
315         GroupPoints->PushButton1->click();
316     }
317     else if (myEditCurrentArgument == GroupWire->LineEdit1) {
318       myWire = aSelectedObject;
319     }
320     else if (myEditCurrentArgument == GroupOnCurve->LineEdit1) {
321       myCurve = aSelectedObject;
322       if (myCurve && !myStartPoint)
323         GroupOnCurve->PushButton2->click();
324     }
325     else if (myEditCurrentArgument == GroupOnCurve->LineEdit2) {
326       myStartPoint = aSelectedObject;
327       if (myStartPoint && !myCurve)
328         GroupOnCurve->PushButton1->click();
329     }
330   }
331
332   displayPreview(true);
333 }
334
335 //=================================================================================
336 // function : SetEditCurrentArgument()
337 // purpose  :
338 //=================================================================================
339 void BuildGUI_EdgeDlg::SetEditCurrentArgument()
340 {
341   QPushButton* send = (QPushButton*)sender();
342
343   if (send == GroupPoints->PushButton1) {
344     myEditCurrentArgument = GroupPoints->LineEdit1;
345     GroupPoints->PushButton2->setDown(false);
346     GroupPoints->LineEdit2->setEnabled(false);
347   }
348   else if (send == GroupPoints->PushButton2) {
349     myEditCurrentArgument = GroupPoints->LineEdit2;
350     GroupPoints->PushButton1->setDown(false);
351     GroupPoints->LineEdit1->setEnabled(false);
352   }
353   else if (send == GroupWire->PushButton1) {
354     myEditCurrentArgument = GroupWire->LineEdit1;
355   }
356   else if (send == GroupOnCurve->PushButton1) {
357     myEditCurrentArgument = GroupOnCurve->LineEdit1;
358     GroupOnCurve->PushButton2->setDown(false);
359     GroupOnCurve->LineEdit2->setEnabled(false);
360
361     globalSelection(); // close local contexts, if any
362     localSelection(TopAbs_EDGE);
363   }
364   else if (send == GroupOnCurve->PushButton2) {
365     myEditCurrentArgument = GroupOnCurve->LineEdit2;
366     GroupOnCurve->PushButton1->setDown(false);
367     GroupOnCurve->LineEdit1->setEnabled(false);
368
369     globalSelection(); // close local contexts, if any
370     localSelection(TopAbs_VERTEX);
371   }
372
373   // enable line edit
374   myEditCurrentArgument->setEnabled(true);
375   myEditCurrentArgument->setFocus();
376   send->setDown(true);
377   displayPreview(true);
378 }
379
380 //=================================================================================
381 // function : ActivateThisDialog()
382 // purpose  :
383 //=================================================================================
384 void BuildGUI_EdgeDlg::ActivateThisDialog()
385 {
386   GEOMBase_Skeleton::ActivateThisDialog();
387
388   connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
389           this, SLOT(SelectionIntoArgument()));
390
391   ConstructorsClicked(getConstructorId());
392 }
393
394 //=================================================================================
395 // function : enterEvent()
396 // purpose  :
397 //=================================================================================
398 void BuildGUI_EdgeDlg::enterEvent (QEvent*)
399 {
400   if (!mainFrame()->GroupConstructors->isEnabled())
401     ActivateThisDialog();
402 }
403
404 //=================================================================================
405 // function : ValueChangedInSpinBox()
406 // purpose  :
407 //=================================================================================
408 void BuildGUI_EdgeDlg::ValueChangedInSpinBox(double /*newValue*/)
409 {
410   displayPreview(true);
411 }
412
413 //=================================================================================
414 // function : createOperation
415 // purpose  :
416 //=================================================================================
417 GEOM::GEOM_IOperations_ptr BuildGUI_EdgeDlg::createOperation()
418 {
419   return getGeomEngine()->GetIShapesOperations();
420 }
421
422 //=================================================================================
423 // function : isValid
424 // purpose  :
425 //=================================================================================
426 bool BuildGUI_EdgeDlg::isValid (QString& msg)
427 {
428   bool ok = false;
429   switch (getConstructorId()) {
430   case 0:
431     ok = myPoint1 && myPoint2;
432     break;
433   case 1:
434     ok = GroupWire->SpinBox_DX->isValid(msg, !IsPreview()) &&
435          GroupWire->SpinBox_DY->isValid(msg, !IsPreview()) &&
436          myWire;
437     break;
438   case 2:
439     ok = GroupOnCurve->SpinBox_DX->isValid(msg, !IsPreview()) &&
440          myCurve;
441     break;
442   default:
443     break;
444   }
445   return ok;
446 }
447
448 //=================================================================================
449 // function : execute
450 // purpose  :
451 //=================================================================================
452 bool BuildGUI_EdgeDlg::execute (ObjectList& objects)
453 {
454   bool res = false;
455   GEOM::GEOM_Object_var anObj;
456
457   GEOM::GEOM_IShapesOperations_var anOper = GEOM::GEOM_IShapesOperations::_narrow(getOperation());
458
459   switch (getConstructorId()) {
460   case 0:
461     {
462       anObj = anOper->MakeEdge(myPoint1.get(), myPoint2.get());
463       res = true;
464       break;
465     }
466   case 1:
467     {
468       double aLinearTolerance   = GroupWire->SpinBox_DX->value();
469       double anAngularTolerance = GroupWire->SpinBox_DY->value();
470
471       QStringList aParameters;
472       aParameters << GroupWire->SpinBox_DX->text();
473       aParameters << GroupWire->SpinBox_DY->text();
474
475       anObj = anOper->MakeEdgeWire(myWire.get(), aLinearTolerance, anAngularTolerance);
476
477       if (!anObj->_is_nil() && !IsPreview())
478         anObj->SetParameters(aParameters.join(":").toUtf8().constData());
479
480       res = true;
481       break;
482     }
483   case 2:
484     {
485       double aLength = GroupOnCurve->SpinBox_DX->value();
486
487       anObj = anOper->MakeEdgeOnCurveByLength(myCurve.get(), aLength, myStartPoint.get());
488
489       if (!anObj->_is_nil() && !IsPreview())
490         anObj->SetParameters(GroupOnCurve->SpinBox_DX->text().toUtf8().constData());
491
492       res = true;
493       break;
494     }
495   }
496
497   if (!anObj->_is_nil()) objects.push_back(anObj._retn());
498
499   return res;
500 }
501
502 //=================================================================================
503 // function : addSubshapeToStudy
504 // purpose  : virtual method to add new SubObjects if local selection
505 //=================================================================================
506 void BuildGUI_EdgeDlg::addSubshapesToStudy()
507 {
508   switch (getConstructorId()) {
509   case 0:
510     GEOMBase::PublishSubObject(myPoint1.get());
511     GEOMBase::PublishSubObject(myPoint2.get());
512     break;
513   case 1:
514     GEOMBase::PublishSubObject(myWire.get());
515     break;
516   case 2:
517     GEOMBase::PublishSubObject(myCurve.get());
518     GEOMBase::PublishSubObject(myStartPoint.get());
519     break;
520   default:
521     break;
522   }
523 }
524
525 //=================================================================================
526 // function : getSourceObjects
527 // purpose  : virtual method to get source objects
528 //=================================================================================
529 QList<GEOM::GeomObjPtr> BuildGUI_EdgeDlg::getSourceObjects()
530 {
531   QList<GEOM::GeomObjPtr> res;
532   res << myPoint1 << myPoint2 << myWire << myCurve << myStartPoint;
533   return res;
534 }