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