Salome HOME
69a5fa91737bd814f0b1e96eecceb755d2babc8b
[modules/geom.git] / src / PrimitiveGUI / PrimitiveGUI_DiskDlg.cxx
1 // Copyright (C) 2007-2023  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // GEOM GEOMGUI : GUI for Geometry component
21 // File   : PrimitiveGUI_DiskDlg.cxx
22 // Author : Lucien PIGNOLONI, Open CASCADE S.A.S.
23 //
24 #include "PrimitiveGUI_DiskDlg.h"
25
26 #include <DlgRef.h>
27 #include <GeometryGUI.h>
28 #include <GEOMBase.h>
29
30 #include <SUIT_Session.h>
31 #include <SUIT_ResourceMgr.h>
32 #include <SalomeApp_Application.h>
33 #include <LightApp_SelectionMgr.h>
34
35 // OCCT Includes
36 #include <TopoDS_Shape.hxx>
37 #include <TopoDS_Edge.hxx>
38 #include <TopoDS.hxx>
39 #include <TopExp.hxx>
40 #include <TColStd_IndexedMapOfInteger.hxx>
41 #include <TopTools_IndexedMapOfShape.hxx>
42
43 //=================================================================================
44 // class    : PrimitiveGUI_DiskDlg()
45 // purpose  : Constructs a PrimitiveGUI_DiskDlg which is a child of 'parent', with the
46 //            name 'name' and widget flags set to 'f'.
47 //            The dialog will by default be modeless, unless you set 'modal' to
48 //            TRUE to construct a modal dialog.
49 //=================================================================================
50 PrimitiveGUI_DiskDlg::PrimitiveGUI_DiskDlg (GeometryGUI* theGeometryGUI, QWidget* parent,
51                                             bool modal, Qt::WindowFlags fl)
52   : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl)
53 {
54   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
55   QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_DISK_PNT_VEC_R")));
56   QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
57   QPixmap image2 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_DISK_THREE_POINTS")));
58   QPixmap image3 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_DISK_R")));
59
60   setWindowTitle(tr("GEOM_DISK_TITLE"));
61
62   /***************************************************************/
63   mainFrame()->GroupConstructors->setTitle(tr("GEOM_DISK"));
64   mainFrame()->RadioButton1->setIcon(image3);
65   mainFrame()->RadioButton2->setIcon(image0);
66   mainFrame()->RadioButton3->setIcon(image2);
67
68   GroupPntVecR = new DlgRef_2Sel1Spin(centralWidget());
69   GroupPntVecR->GroupBox1->setTitle(tr("GEOM_ARGUMENTS"));
70   GroupPntVecR->TextLabel1->setText(tr("GEOM_CENTER_POINT"));
71   GroupPntVecR->TextLabel2->setText(tr("GEOM_VECTOR"));
72   GroupPntVecR->TextLabel3->setText(tr("GEOM_RADIUS"));
73   GroupPntVecR->PushButton1->setIcon(image1);
74   GroupPntVecR->PushButton2->setIcon(image1);
75   GroupPntVecR->LineEdit1->setReadOnly(true);
76   GroupPntVecR->LineEdit2->setReadOnly(true);
77
78   Group3Pnts = new DlgRef_3Sel(centralWidget());
79   Group3Pnts->GroupBox1->setTitle(tr("GEOM_ARGUMENTS"));
80   Group3Pnts->TextLabel1->setText(tr("GEOM_POINT1"));
81   Group3Pnts->TextLabel2->setText(tr("GEOM_POINT2"));
82   Group3Pnts->TextLabel3->setText(tr("GEOM_POINT3"));
83   Group3Pnts->PushButton1->setIcon(image1);
84   Group3Pnts->PushButton2->setIcon(image1);
85   Group3Pnts->PushButton3->setIcon(image1);
86   Group3Pnts->LineEdit1->setReadOnly(true);
87   Group3Pnts->LineEdit2->setReadOnly(true);
88   Group3Pnts->LineEdit3->setReadOnly(true);
89
90   GroupDimensions = new DlgRef_1Spin(centralWidget());
91   GroupDimensions->GroupBox1->setTitle(tr("GEOM_ARGUMENTS"));
92   GroupDimensions->TextLabel1->setText(tr("GEOM_RADIUS"));
93
94   GroupOrientation = new DlgRef_3Radio(centralWidget());
95   GroupOrientation->GroupBox1->setTitle(tr("GEOM_ORIENTATION"));
96   GroupOrientation->RadioButton1->setText(tr("GEOM_WPLANE_OXY"));
97   GroupOrientation->RadioButton2->setText(tr("GEOM_WPLANE_OYZ"));
98   GroupOrientation->RadioButton3->setText(tr("GEOM_WPLANE_OZX"));
99
100   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
101   layout->setMargin(0); layout->setSpacing(6);
102   layout->addWidget(GroupPntVecR);
103   layout->addWidget(Group3Pnts);
104   layout->addWidget(GroupDimensions);
105   layout->addWidget(GroupOrientation);
106   /***************************************************************/
107
108   setHelpFileName("create_disk_page.html");
109
110   Init();
111 }
112
113 //=================================================================================
114 // function : ~PrimitiveGUI_DiskDlg()
115 // purpose  : Destroys the object and frees any allocated resources
116 //=================================================================================
117 PrimitiveGUI_DiskDlg::~PrimitiveGUI_DiskDlg()
118 {
119 }
120
121 //=================================================================================
122 // function : Init()
123 // purpose  :
124 //=================================================================================
125 void PrimitiveGUI_DiskDlg::Init()
126 {
127   // Get setting of step value from file configuration
128   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
129   double aStep = resMgr->doubleValue("Geometry", "SettingsGeomStep", 100);
130
131   // min, max, step and decimals for spin boxes & initial values
132   initSpinBox(GroupPntVecR->SpinBox_DX, 0.00001, COORD_MAX, aStep, "length_precision" );
133   initSpinBox(GroupDimensions->SpinBox_DX, 0.00001, COORD_MAX, aStep, "length_precision" );
134
135   // init variables
136   myEditCurrentArgument = GroupPntVecR->LineEdit1;
137   myOrientationType = 1;
138   GroupOrientation->RadioButton1->setChecked(true);
139
140   GroupPntVecR->LineEdit1->setText("");
141   GroupPntVecR->LineEdit2->setText("");
142   Group3Pnts->LineEdit1->setText("");
143   Group3Pnts->LineEdit2->setText("");
144   Group3Pnts->LineEdit3->setText("");
145   myPoint.nullify();
146   myDir.nullify();
147   myPoint1.nullify();
148   myPoint2.nullify();
149   myPoint3.nullify();
150
151   GroupPntVecR->SpinBox_DX->setValue(100);
152   GroupDimensions->SpinBox_DX->setValue(100);
153
154   // signals and slots connections
155   connect(buttonOk(),    SIGNAL(clicked()), this, SLOT(ClickOnOk()));
156   connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
157
158   connect(this,          SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int)));
159
160   connect(GroupPntVecR->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
161   connect(GroupPntVecR->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
162
163   connect(Group3Pnts->PushButton1,   SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
164   connect(Group3Pnts->PushButton2,   SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
165   connect(Group3Pnts->PushButton3,   SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
166
167   connect(GroupPntVecR->SpinBox_DX,    SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox()));
168   connect(GroupDimensions->SpinBox_DX, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox()));
169
170   connect(GroupOrientation->RadioButton1, SIGNAL(clicked()), this, SLOT(RadioButtonClicked()));
171   connect(GroupOrientation->RadioButton2, SIGNAL(clicked()), this, SLOT(RadioButtonClicked()));
172   connect(GroupOrientation->RadioButton3, SIGNAL(clicked()), this, SLOT(RadioButtonClicked()));
173
174   connect(myGeomGUI, SIGNAL(SignalDefaultStepValueChanged(double)), this, SLOT(SetDoubleSpinBoxStep(double)));
175   connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()),               this, SLOT(ClickOnCancel()));
176
177   initName(tr("GEOM_DISK"));
178
179   ConstructorsClicked(0);
180 }
181
182 //=================================================================================
183 // function : SetDoubleSpinBoxStep()
184 // purpose  : Double spin box management
185 //=================================================================================
186 void PrimitiveGUI_DiskDlg::SetDoubleSpinBoxStep (double step)
187 {
188   GroupDimensions->SpinBox_DX->setSingleStep(step);
189   GroupPntVecR->SpinBox_DX->setSingleStep(step);
190 }
191
192 //=================================================================================
193 // function : RadioBittonClicked()
194 // purpose  : Radio button management
195 //=================================================================================
196 void PrimitiveGUI_DiskDlg::RadioButtonClicked()
197 {
198   if (GroupOrientation->RadioButton1->isChecked())
199     myOrientationType = 1;
200   else if (GroupOrientation->RadioButton2->isChecked())
201     myOrientationType = 2;
202   else if (GroupOrientation->RadioButton3->isChecked())
203     myOrientationType = 3;
204   displayPreview(true);
205 }
206
207 //=================================================================================
208 // function : ConstructorsClicked()
209 // purpose  : Radio button management
210 //=================================================================================
211 void PrimitiveGUI_DiskDlg::ConstructorsClicked (int constructorId)
212 {
213   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
214
215   switch (constructorId) {
216   case 0:
217     {
218       GroupPntVecR->hide();
219       Group3Pnts->hide();
220       GroupDimensions->show();
221       GroupOrientation->show();
222
223       disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
224       globalSelection(); // close local contexts, if any
225       break;
226     }
227   case 1:
228     {
229       GroupDimensions->hide();
230       GroupOrientation->hide();
231       GroupPntVecR->show();
232       Group3Pnts->hide();
233
234       GroupPntVecR->PushButton1->click();
235       break;
236     }
237   case 2:
238     {
239       GroupDimensions->hide();
240       GroupOrientation->hide();
241       GroupPntVecR->hide();
242       Group3Pnts->show();
243
244       Group3Pnts->PushButton1->click();
245       break;
246     }
247   }
248
249   qApp->processEvents();
250   updateGeometry();
251   resize(minimumSizeHint());
252   SelectionIntoArgument();
253
254   displayPreview(true);
255 }
256
257 //=================================================================================
258 // function : ClickOnOk()
259 // purpose  :
260 //=================================================================================
261 void PrimitiveGUI_DiskDlg::ClickOnOk()
262 {
263   setIsApplyAndClose( true );
264   if (ClickOnApply())
265     ClickOnCancel();
266 }
267
268 //=================================================================================
269 // function : ClickOnApply()
270 // purpose  :
271 //=================================================================================
272 bool PrimitiveGUI_DiskDlg::ClickOnApply()
273 {
274   if (!onAccept())
275     return false;
276
277   initName();
278   // activate selection and connect selection manager
279   ConstructorsClicked(getConstructorId());
280   return true;
281 }
282
283 //=================================================================================
284 // function : SelectionIntoArgument()
285 // purpose  : Called when selection is changed or on dialog initialization or activation
286 //=================================================================================
287 void PrimitiveGUI_DiskDlg::SelectionIntoArgument()
288 {
289   if (getConstructorId() == 0)
290     return;
291
292   erasePreview();
293   myEditCurrentArgument->setText("");
294
295   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
296   SALOME_ListIO aSelList;
297   aSelMgr->selectedObjects(aSelList);
298
299   if (aSelList.Extent() != 1) {
300     if      (myEditCurrentArgument == GroupPntVecR->LineEdit1) myPoint.nullify();
301     else if (myEditCurrentArgument == GroupPntVecR->LineEdit2) myDir.nullify();
302     else if (myEditCurrentArgument == Group3Pnts->LineEdit1)   myPoint1.nullify();
303     else if (myEditCurrentArgument == Group3Pnts->LineEdit2)   myPoint2.nullify();
304     else if (myEditCurrentArgument == Group3Pnts->LineEdit3)   myPoint3.nullify();
305     return;
306   }
307
308   TopAbs_ShapeEnum aNeedType = myEditCurrentArgument == GroupPntVecR->LineEdit2 ? TopAbs_EDGE : TopAbs_VERTEX;
309   GEOM::GeomObjPtr aSelectedObject = getSelected( aNeedType );
310   TopoDS_Shape aShape;
311   if ( aSelectedObject && GEOMBase::GetShape( aSelectedObject.get(), aShape ) && !aShape.IsNull() ) {
312     QString aName = GEOMBase::GetName( aSelectedObject.get() );
313
314     myEditCurrentArgument->setText(aName);
315     
316     // clear selection
317     disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
318     myGeomGUI->getApp()->selectionMgr()->clearSelected();
319     connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
320             this, SLOT(SelectionIntoArgument()));
321     
322     if (myEditCurrentArgument == GroupPntVecR->LineEdit1) {
323       myPoint = aSelectedObject;
324       if (myPoint && !myDir)
325         GroupPntVecR->PushButton2->click();
326     }
327     else if (myEditCurrentArgument == GroupPntVecR->LineEdit2) {
328       myDir = aSelectedObject;
329       if (myDir && !myPoint)
330         GroupPntVecR->PushButton1->click();
331     }
332     else if (myEditCurrentArgument == Group3Pnts->LineEdit1) {
333       myPoint1 = aSelectedObject;
334       if (myPoint1 && !myPoint2)
335         Group3Pnts->PushButton2->click();
336     }
337     else if (myEditCurrentArgument == Group3Pnts->LineEdit2) {
338       myPoint2 = aSelectedObject;
339       if (myPoint2 && !myPoint3)
340         Group3Pnts->PushButton3->click();
341     }
342     else if (myEditCurrentArgument == Group3Pnts->LineEdit3) {
343       myPoint3 = aSelectedObject;
344       if (myPoint3 && !myPoint1)
345         Group3Pnts->PushButton1->click();
346     }
347   }
348
349   displayPreview(true);
350 }
351
352 //=================================================================================
353 // function : SetEditCurrentArgument()
354 // purpose  :
355 //=================================================================================
356 void PrimitiveGUI_DiskDlg::SetEditCurrentArgument()
357 {
358   QPushButton* send = (QPushButton*)sender();
359
360   if (send == GroupPntVecR->PushButton1) {
361     myEditCurrentArgument = GroupPntVecR->LineEdit1;
362
363     GroupPntVecR->PushButton2->setDown(false);
364     GroupPntVecR->LineEdit2->setEnabled(false);
365   }
366   else if (send == GroupPntVecR->PushButton2) {
367     myEditCurrentArgument = GroupPntVecR->LineEdit2;
368
369     GroupPntVecR->PushButton1->setDown(false);
370     GroupPntVecR->LineEdit1->setEnabled(false);
371   }
372   else if (send == Group3Pnts->PushButton1) {
373     myEditCurrentArgument = Group3Pnts->LineEdit1;
374
375     Group3Pnts->PushButton2->setDown(false);
376     Group3Pnts->PushButton3->setDown(false);
377     Group3Pnts->LineEdit2->setEnabled(false);
378     Group3Pnts->LineEdit3->setEnabled(false);
379   }
380   else if (send == Group3Pnts->PushButton2) {
381     myEditCurrentArgument = Group3Pnts->LineEdit2;
382
383     Group3Pnts->PushButton1->setDown(false);
384     Group3Pnts->PushButton3->setDown(false);
385     Group3Pnts->LineEdit1->setEnabled(false);
386     Group3Pnts->LineEdit3->setEnabled(false);
387   }
388   else if (send == Group3Pnts->PushButton3) {
389     myEditCurrentArgument = Group3Pnts->LineEdit3;
390
391     Group3Pnts->PushButton1->setDown(false);
392     Group3Pnts->PushButton2->setDown(false);
393     Group3Pnts->LineEdit1->setEnabled(false);
394     Group3Pnts->LineEdit2->setEnabled(false);
395   }
396
397   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
398   if (myEditCurrentArgument == GroupPntVecR->LineEdit2) {
399     globalSelection(); // close local contexts, if any
400     localSelection(TopAbs_EDGE);
401   }
402   else {
403     globalSelection(); // close local contexts, if any
404     localSelection(TopAbs_VERTEX);
405   }
406   connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
407           this, SLOT(SelectionIntoArgument()));
408
409   // enable line edit
410   myEditCurrentArgument->setEnabled(true);
411   myEditCurrentArgument->setFocus();
412   // after setFocus(), because it will be setDown(false) when loses focus
413   send->setDown(true);
414
415   // seems we need it only to avoid preview disappearing, caused by selection mode change
416   displayPreview(true);
417 }
418
419 //=================================================================================
420 // function : ActivateThisDialog()
421 // purpose  :
422 //=================================================================================
423 void PrimitiveGUI_DiskDlg::ActivateThisDialog()
424 {
425   GEOMBase_Skeleton::ActivateThisDialog();
426   connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),
427            this, SLOT( SelectionIntoArgument() ) );
428
429   ConstructorsClicked( getConstructorId() );
430 }
431
432 //=================================================================================
433 // function : enterEvent()
434 // purpose  :
435 //=================================================================================
436 void PrimitiveGUI_DiskDlg::enterEvent (QEvent*)
437 {
438   if (!mainFrame()->GroupConstructors->isEnabled())
439     ActivateThisDialog();
440 }
441
442 //=================================================================================
443 // function : ValueChangedInSpinBox()
444 // purpose  :
445 //=================================================================================
446 void PrimitiveGUI_DiskDlg::ValueChangedInSpinBox()
447 {
448   displayPreview(true);
449 }
450
451 //=================================================================================
452 // function : createOperation
453 // purpose  :
454 //=================================================================================
455 GEOM::GEOM_IOperations_ptr PrimitiveGUI_DiskDlg::createOperation()
456 {
457   return getGeomEngine()->GetI3DPrimOperations();
458 }
459
460 // //=================================================================================
461 // // function : isEqual
462 // // purpose  : it may also be needed to check for min distance between gp_Pnt-s...
463 // //=================================================================================
464 // static bool isEqual (const GEOM::GEOM_Object_var& thePnt1, const GEOM::GEOM_Object_var& thePnt2)
465 // {
466 //   return thePnt1->_is_equivalent(thePnt2);
467 // }
468
469 //=================================================================================
470 // function : isValid
471 // purpose  :
472 //=================================================================================
473 bool PrimitiveGUI_DiskDlg::isValid (QString& msg)
474 {
475   bool ok = false;
476   if ( getConstructorId() == 0 )
477     ok = GroupDimensions->SpinBox_DX->isValid( msg, !IsPreview() ) && getRadius() > 0;
478   else if ( getConstructorId() == 1 )
479     ok = GroupPntVecR->SpinBox_DX->isValid( msg, !IsPreview() ) && myPoint && myDir && getRadius() > 0;
480   else if ( getConstructorId() == 2 )
481     ok = myPoint1 && myPoint2 && myPoint3 && myPoint1 != myPoint2 && myPoint1 != myPoint3 && myPoint2 != myPoint3;
482   return ok;
483 }
484
485 //=================================================================================
486 // function : execute
487 // purpose  :
488 //=================================================================================
489 bool PrimitiveGUI_DiskDlg::execute (ObjectList& objects)
490 {
491   bool res = false;
492   QStringList aParameters;
493
494   GEOM::GEOM_Object_var anObj;
495
496   GEOM::GEOM_I3DPrimOperations_var anOper = GEOM::GEOM_I3DPrimOperations::_narrow(getOperation());
497
498   switch (getConstructorId()) {
499   case 0:
500     anObj = anOper->MakeDiskR(getRadius(), myOrientationType);
501     if (!anObj->_is_nil() && !IsPreview())
502     {
503       aParameters << GroupDimensions->SpinBox_DX->text();
504       anObj->SetParameters(aParameters.join(":").toUtf8().constData());
505     }
506     res = true;
507     break;
508   case 1:
509     anObj = anOper->MakeDiskPntVecR(myPoint.get(), myDir.get(), getRadius());
510     if (!anObj->_is_nil() && !IsPreview())
511     {
512       aParameters << GroupPntVecR->SpinBox_DX->text();
513       anObj->SetParameters(aParameters.join(":").toUtf8().constData());
514     }
515     res = true;
516     break;
517   case 2:
518     anObj = anOper->MakeDiskThreePnt(myPoint1.get(), myPoint2.get(), myPoint3.get());
519     res = true;
520     break;
521   }
522
523   if (!anObj->_is_nil())
524     objects.push_back(anObj._retn());
525
526   return res;
527 }
528
529 //=================================================================================
530 // function : getRadius()
531 // purpose  :
532 //=================================================================================
533 double PrimitiveGUI_DiskDlg::getRadius() const
534 {
535   double r = 0.;
536   switch (getConstructorId()) {
537   case 0:
538     r = GroupDimensions->SpinBox_DX->value(); break;
539   case 1:
540     r = GroupPntVecR->SpinBox_DX->value(); break;
541   }
542   return r;
543 }
544
545 //=================================================================================
546 // function : addSubshapeToStudy
547 // purpose  : virtual method to add new SubObjects if local selection
548 //=================================================================================
549 void PrimitiveGUI_DiskDlg::addSubshapesToStudy()
550 {
551   switch (getConstructorId()) {
552   case 1:
553     GEOMBase::PublishSubObject( myPoint.get() );
554     GEOMBase::PublishSubObject( myDir.get() );
555     break;
556   case 2:
557     GEOMBase::PublishSubObject( myPoint1.get() );
558     GEOMBase::PublishSubObject( myPoint2.get() );
559     GEOMBase::PublishSubObject( myPoint3.get() );
560     break;
561   default:
562     break;
563   }
564 }
565
566 //=================================================================================
567 // function : getSourceObjects
568 // purpose  : virtual method to get source objects
569 //=================================================================================
570 QList<GEOM::GeomObjPtr> PrimitiveGUI_DiskDlg::getSourceObjects()
571 {
572   QList<GEOM::GeomObjPtr> res;
573   res << myPoint << myDir << myPoint1 << myPoint2 << myPoint3;
574   return res;
575 }