Salome HOME
Copyright update 2021
[modules/geom.git] / src / BlocksGUI / BlocksGUI_QuadFaceDlg.cxx
1 // Copyright (C) 2007-2021  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, 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   : BlocksGUI_QuadFaceDlg.cxx
25 // Author : Julia DOROVSKIKH, Open CASCADE S.A.S. (julia.dorovskikh@opencascade.com)
26 //
27 #include "BlocksGUI_QuadFaceDlg.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 // QT Includes
39 #include <qlabel.h>
40
41 // OCCT Includes
42 #include <TopAbs.hxx>
43 #include <TColStd_IndexedMapOfInteger.hxx>
44
45 #include <GEOMImpl_Types.hxx>
46
47 //=================================================================================
48 // class    : BlocksGUI_QuadFaceDlg()
49 // purpose  : Constructs a BlocksGUI_QuadFaceDlg which is a child of 'parent'.
50 //=================================================================================
51 BlocksGUI_QuadFaceDlg::BlocksGUI_QuadFaceDlg (GeometryGUI* theGeometryGUI, QWidget* parent)
52   : GEOMBase_Skeleton(theGeometryGUI, parent),
53     myInitial(true)
54 {
55   SUIT_ResourceMgr* aResMgr = myGeomGUI->getApp()->resourceMgr();
56   QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_QUAD_FACE_4_VERT")));
57   QPixmap image2 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_QUAD_FACE_2_EDGE")));
58   QPixmap image3 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_QUAD_FACE_4_EDGE")));
59   QPixmap imageS (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
60
61   setWindowTitle(tr("GEOM_QUAD_FACE_TITLE"));
62
63   /***************************************************************/
64   mainFrame()->GroupConstructors->setTitle(tr("GEOM_QUAD_FACE"));
65
66   mainFrame()->RadioButton1->setIcon(image1);
67   mainFrame()->RadioButton2->setIcon(image2);
68   mainFrame()->RadioButton3->setIcon(image3);
69
70   // Create first group
71   myGrp1 = new QGroupBox(tr("GEOM_ARGUMENTS"), centralWidget());
72
73   createSelWg(tr("VERTEX_1"), imageS, myGrp1, Vertex1);
74   createSelWg(tr("VERTEX_2"), imageS, myGrp1, Vertex2);
75   createSelWg(tr("VERTEX_3"), imageS, myGrp1, Vertex3);
76   createSelWg(tr("VERTEX_4"), imageS, myGrp1, Vertex4);
77
78   // Create second group
79   myGrp2 = new QGroupBox(tr("GEOM_ARGUMENTS"), centralWidget());
80
81   createSelWg(tr("EDGE_1"), imageS, myGrp2, Edge12);
82   createSelWg(tr("EDGE_2"), imageS, myGrp2, Edge22);
83
84   // Create third group
85   myGrp3 = new QGroupBox(tr("GEOM_ARGUMENTS"), centralWidget());
86
87   createSelWg(tr("EDGE_1"), imageS, myGrp3, Edge14);
88   createSelWg(tr("EDGE_2"), imageS, myGrp3, Edge24);
89   createSelWg(tr("EDGE_3"), imageS, myGrp3, Edge34);
90   createSelWg(tr("EDGE_4"), imageS, myGrp3, Edge44);
91
92   // Add groups to layout
93   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
94   layout->setMargin(0); layout->setSpacing(6);
95   layout->addWidget(myGrp1);
96   layout->addWidget(myGrp2);
97   layout->addWidget(myGrp3);
98   /***************************************************************/
99
100   setHelpFileName("build_by_blocks_page.html#quad_face_anchor");
101
102   Init();
103 }
104
105 //=================================================================================
106 // function : ~BlocksGUI_QuadFaceDlg()
107 // purpose  : Destroys the object and frees any allocated resources
108 //=================================================================================
109 BlocksGUI_QuadFaceDlg::~BlocksGUI_QuadFaceDlg()
110 {
111   // no need to delete child widgets, Qt does it all for us
112 }
113
114 //=================================================================================
115 // function : Init()
116 // purpose  :
117 //=================================================================================
118 void BlocksGUI_QuadFaceDlg::Init()
119 {
120   // signals and slots connections
121   connect(buttonOk(),    SIGNAL(clicked()), this, SLOT(ClickOnOk()));
122   connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
123
124   connect(this, SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int)));
125
126   QMap<int, QPushButton*>::iterator anIterBtn;
127   for (anIterBtn = mySelBtn.begin(); anIterBtn != mySelBtn.end(); ++anIterBtn)
128     connect(anIterBtn.value(), SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
129
130   // init controls and fields
131   initName(tr("GEOM_QUAD_FACE"));
132
133   myConstructorId = -1;
134   ConstructorsClicked(0);
135 }
136
137 //=================================================================================
138 // function : ConstructorsClicked()
139 // purpose  : Radio button management
140 //=================================================================================
141 void BlocksGUI_QuadFaceDlg::ConstructorsClicked (int constructorId)
142 {
143   if (myConstructorId == constructorId)
144     return;
145
146   myConstructorId = constructorId;
147
148   // init fields
149   myShape1.nullify();
150   myShape2.nullify();
151   myShape3.nullify();
152   myShape4.nullify();
153
154   // clear line edits
155   QMap<int, QLineEdit*>::iterator anIterLE;
156   for (anIterLE = mySelName.begin(); anIterLE != mySelName.end(); ++anIterLE)
157     anIterLE.value()->setText("");
158
159   switch (constructorId) {
160   case 0:
161     myGrp2->hide();
162     myGrp3->hide();
163     myGrp1->show();
164     mySelBtn[Vertex1]->click();
165     break;
166   case 1:
167     myGrp1->hide();
168     myGrp3->hide();
169     myGrp2->show();
170     mySelBtn[Edge12]->click();
171     break;
172   case 2:
173     myGrp1->hide();
174     myGrp2->hide();
175     myGrp3->show();
176     mySelBtn[Edge14]->click();
177     break;
178   default:
179     break;
180   }
181
182   qApp->processEvents();
183   updateGeometry();
184   resize(minimumSizeHint());
185
186   // on dialog initialization we init the first field with a selected object (if any)
187   SelectionIntoArgument();
188 }
189
190 //=================================================================================
191 // function : ClickOnOk()
192 // purpose  :
193 //=================================================================================
194 void BlocksGUI_QuadFaceDlg::ClickOnOk()
195 {
196   setIsApplyAndClose( true );
197   if (ClickOnApply())
198     ClickOnCancel();
199 }
200
201 //=================================================================================
202 // function : ClickOnApply()
203 // purpose  :
204 //=================================================================================
205 bool BlocksGUI_QuadFaceDlg::ClickOnApply()
206 {
207   if (!onAccept())
208     return false;
209
210   initName();
211   return true;
212 }
213
214 //=================================================================================
215 // function : SelectionIntoArgument()
216 // purpose  : Called when selection is changed or on dialog initialization or activation
217 //=================================================================================
218 void BlocksGUI_QuadFaceDlg::SelectionIntoArgument()
219 {
220   erasePreview();
221
222   // Get index of current selection focus
223   int aCurrFocus = -1;
224   QMap<int, QLineEdit*>::iterator anIter;
225   for (anIter = mySelName.begin(); anIter != mySelName.end(); ++anIter) {
226     if (myEditCurrentArgument == anIter.value()) {
227       aCurrFocus = anIter.key();
228       break;
229     }
230   }
231
232   TopAbs_ShapeEnum aType = TopAbs_EDGE;
233   if (aCurrFocus == Vertex1 || aCurrFocus == Vertex2 ||
234       aCurrFocus == Vertex3 || aCurrFocus == Vertex4)
235     aType = TopAbs_VERTEX;
236
237   GEOM::GeomObjPtr aSelectedObject = getSelected( aType );
238   TopoDS_Shape aShape;
239   if ( aSelectedObject && GEOMBase::GetShape( aSelectedObject.get(), aShape ) && !aShape.IsNull() ) {
240     QString aName = GEOMBase::GetName( aSelectedObject.get() );
241     myEditCurrentArgument->setText( aName );
242     switch (aCurrFocus) {
243       // four vertices
244     case Vertex1:
245       myShape1 = aSelectedObject;
246       if      (!myShape2) mySelBtn[Vertex2]->click();
247       else if (!myShape3) mySelBtn[Vertex3]->click();
248       else if (!myShape4) mySelBtn[Vertex4]->click();
249       break;
250     case Vertex2:
251       myShape2 = aSelectedObject;
252       if      (!myShape3) mySelBtn[Vertex3]->click();
253       else if (!myShape4) mySelBtn[Vertex4]->click();
254       else if (!myShape1) mySelBtn[Vertex1]->click();
255       break;
256     case Vertex3:
257       myShape3 = aSelectedObject;
258       if      (!myShape4) mySelBtn[Vertex4]->click();
259       else if (!myShape1) mySelBtn[Vertex1]->click();
260       else if (!myShape2) mySelBtn[Vertex2]->click();
261       break;
262     case Vertex4:
263       myShape4 = aSelectedObject;
264       if      (!myShape1) mySelBtn[Vertex1]->click();
265       else if (!myShape2) mySelBtn[Vertex2]->click();
266       else if (!myShape3) mySelBtn[Vertex3]->click();
267       break;
268       // two edges
269     case Edge12:
270       myShape1 = aSelectedObject;
271       if      (!myShape2) mySelBtn[Edge22]->click();
272       break;
273     case Edge22:
274       myShape2 = aSelectedObject;
275       if      (!myShape1) mySelBtn[Edge12]->click();
276       break;
277       // four edges
278     case Edge14:
279       myShape1 = aSelectedObject;
280       if      (!myShape2) mySelBtn[Edge24]->click();
281       else if (!myShape3) mySelBtn[Edge34]->click();
282       else if (!myShape4) mySelBtn[Edge44]->click();
283       break;
284     case Edge24:
285       myShape2 = aSelectedObject;
286       if      (!myShape3) mySelBtn[Edge34]->click();
287       else if (!myShape4) mySelBtn[Edge44]->click();
288       else if (!myShape1) mySelBtn[Edge14]->click();
289       break;
290     case Edge34:
291       myShape3 = aSelectedObject;
292       if      (!myShape4) mySelBtn[Edge44]->click();
293       else if (!myShape1) mySelBtn[Edge14]->click();
294       else if (!myShape2) mySelBtn[Edge24]->click();
295       break;
296     case Edge44:
297       myShape4 = aSelectedObject;
298       if      (!myShape1) mySelBtn[Edge14]->click();
299       else if (!myShape2) mySelBtn[Edge24]->click();
300       else if (!myShape3) mySelBtn[Edge34]->click();
301       break;
302     default:
303       break;
304     }
305   }
306   else {
307     switch (aCurrFocus) {
308     case Vertex1:
309     case Edge12:
310     case Edge14:
311       myShape1.nullify();
312       break;
313     case Vertex2:
314     case Edge22:
315     case Edge24:
316       myShape2.nullify();
317       break;
318     case Vertex3:
319     case Edge34:
320       myShape3.nullify();
321       break;
322     case Vertex4:
323     case Edge44:
324       myShape4.nullify();
325       break;
326     default:
327       break;
328     }
329     myEditCurrentArgument->setText( "" );
330   }
331
332   displayPreview(true);
333 }
334
335 //=================================================================================
336 // function : SetEditCurrentArgument()
337 // purpose  :
338 //=================================================================================
339 void BlocksGUI_QuadFaceDlg::SetEditCurrentArgument()
340 {
341   QPushButton* aSender = (QPushButton*)sender();
342
343   // clear selection
344   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
345   if (myInitial)
346     myInitial = false;
347   else
348     myGeomGUI->getApp()->selectionMgr()->clearSelected();
349
350   // disable all
351   switch (myConstructorId) {
352   case 0:
353     mySelBtn[Vertex1]->setDown(false);
354     mySelBtn[Vertex2]->setDown(false);
355     mySelBtn[Vertex3]->setDown(false);
356     mySelBtn[Vertex4]->setDown(false);
357
358     mySelName[Vertex1]->setEnabled(false);
359     mySelName[Vertex2]->setEnabled(false);
360     mySelName[Vertex3]->setEnabled(false);
361     mySelName[Vertex4]->setEnabled(false);
362     break;
363   case 1:
364     mySelBtn[Edge12]->setDown(false);
365     mySelBtn[Edge22]->setDown(false);
366
367     mySelName[Edge12]->setEnabled(false);
368     mySelName[Edge22]->setEnabled(false);
369     break;
370   case 2:
371     mySelBtn[Edge14]->setDown(false);
372     mySelBtn[Edge24]->setDown(false);
373     mySelBtn[Edge34]->setDown(false);
374     mySelBtn[Edge44]->setDown(false);
375
376     mySelName[Edge14]->setEnabled(false);
377     mySelName[Edge24]->setEnabled(false);
378     mySelName[Edge34]->setEnabled(false);
379     mySelName[Edge44]->setEnabled(false);
380     break;
381   default:
382     break;
383   }
384
385   // set line edit as current argument
386   QMap<int, QPushButton*>::iterator anIter;
387   for (anIter = mySelBtn.begin(); anIter != mySelBtn.end(); ++anIter) {
388     if (anIter.value() == aSender) {
389       myEditCurrentArgument = mySelName[anIter.key()];
390       break;
391     }
392   }
393
394   // enable line edit
395   myEditCurrentArgument->setEnabled(true);
396   myEditCurrentArgument->setFocus();
397
398   // enable push button
399   // after setFocus(), because it will be setDown(false) when loses focus
400   aSender->setDown(true);
401
402   activateSelection();
403 }
404
405 //=================================================================================
406 // function : ActivateThisDialog()
407 // purpose  :
408 //=================================================================================
409 void BlocksGUI_QuadFaceDlg::ActivateThisDialog()
410 {
411   GEOMBase_Skeleton::ActivateThisDialog();
412   activateSelection();
413
414   // ??
415   displayPreview(true);
416 }
417
418 //=================================================================================
419 // function : enterEvent()
420 // purpose  :
421 //=================================================================================
422 void BlocksGUI_QuadFaceDlg::enterEvent (QEvent*)
423 {
424   if (!mainFrame()->GroupConstructors->isEnabled())
425     ActivateThisDialog();
426 }
427
428 //=================================================================================
429 // function : createSelWg()
430 // purpose  :
431 //=================================================================================
432 void BlocksGUI_QuadFaceDlg::createSelWg (const QString& theLbl,
433                                          QPixmap&       thePix,
434                                          QWidget*       theParent,
435                                          const int      theId)
436 {
437   QLabel* lab = new QLabel(theLbl, theParent);
438   mySelBtn[theId] = new QPushButton(theParent);
439   mySelBtn[theId]->setIcon(thePix);
440   mySelBtn[theId]->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
441   mySelName[theId] = new QLineEdit(theParent);
442   mySelName[theId]->setReadOnly(true);
443   QGridLayout* l = 0;
444   if (!theParent->layout()) {
445     l = new QGridLayout(theParent);
446     l->setMargin(9); l->setSpacing(6);
447   }
448   else {
449     l = qobject_cast<QGridLayout*>(theParent->layout());
450   }
451   int row = l->rowCount();
452   l->addWidget(lab,              row, 0);
453   l->addWidget(mySelBtn[theId],  row, 1);
454   l->addWidget(mySelName[theId], row, 2);
455 }
456
457 //=================================================================================
458 // function : activateSelection
459 // purpose  : Activate selection in accordance with myEditCurrentArgument
460 //=================================================================================
461 void BlocksGUI_QuadFaceDlg::activateSelection()
462 {
463   globalSelection(); // close local contexts, if any
464   if (myEditCurrentArgument == mySelName[Vertex1] ||
465       myEditCurrentArgument == mySelName[Vertex2] ||
466       myEditCurrentArgument == mySelName[Vertex3] ||
467       myEditCurrentArgument == mySelName[Vertex4])
468   {
469     localSelection(TopAbs_VERTEX); //Select Vertices on All Shapes
470   }
471   else
472   {
473     localSelection(TopAbs_EDGE); //Select Edges on All Shapes
474   }
475   connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
476           this, SLOT(SelectionIntoArgument()));
477 }
478
479 //=================================================================================
480 // function : createOperation
481 // purpose  :
482 //=================================================================================
483 GEOM::GEOM_IOperations_ptr BlocksGUI_QuadFaceDlg::createOperation()
484 {
485   return getGeomEngine()->GetIBlocksOperations();
486 }
487
488 //=================================================================================
489 // function : isValid
490 // purpose  : Verify validity of input data
491 //=================================================================================
492 bool BlocksGUI_QuadFaceDlg::isValid (QString&)
493 {
494   bool ok = false;
495   switch (getConstructorId()) {
496   case 0:
497     ok = myShape1 && myShape2 && myShape3 && myShape4;
498     break;
499   case 1:
500     ok = myShape1 && myShape2;
501     break;
502   case 2:
503     ok = myShape1 && myShape2 && myShape3 && myShape4;
504     break;
505   default:
506     break;
507   }
508   return ok;
509 }
510
511 //=================================================================================
512 // function : execute
513 // purpose  :
514 //=================================================================================
515 bool BlocksGUI_QuadFaceDlg::execute (ObjectList& objects)
516 {
517   bool res = false;
518
519   GEOM::GEOM_Object_var anObj;
520
521   GEOM::GEOM_IBlocksOperations_var anOper = GEOM::GEOM_IBlocksOperations::_narrow(getOperation());
522
523   switch (getConstructorId()) {
524   case 0:
525     anObj = anOper->MakeQuad4Vertices(myShape1.get(), myShape2.get(), myShape3.get(), myShape4.get());
526     res = true;
527     break;
528   case 1:
529     anObj = anOper->MakeQuad2Edges(myShape1.get(), myShape2.get());
530     res = true;
531     break;
532   case 2:
533     anObj = anOper->MakeQuad(myShape1.get(), myShape2.get(), myShape3.get(), myShape4.get());
534     res = true;
535     break;
536   default:
537     break;
538   }
539
540   if (!anObj->_is_nil())
541     objects.push_back(anObj._retn());
542
543   return res;
544 }
545
546 //=================================================================================
547 // function : addSubshapeToStudy
548 // purpose  : virtual method to add new SubObjects if local selection
549 //=================================================================================
550 void BlocksGUI_QuadFaceDlg::addSubshapesToStudy()
551 {
552   switch (getConstructorId()) {
553   case 0:
554     GEOMBase::PublishSubObject( myShape1.get() );
555     GEOMBase::PublishSubObject( myShape2.get() );
556     GEOMBase::PublishSubObject( myShape3.get() );
557     GEOMBase::PublishSubObject( myShape4.get() );
558     break;
559   case 1:
560     GEOMBase::PublishSubObject( myShape1.get() );
561     GEOMBase::PublishSubObject( myShape2.get() );
562     break;
563   case 2:
564     GEOMBase::PublishSubObject( myShape1.get() );
565     GEOMBase::PublishSubObject( myShape2.get() );
566     GEOMBase::PublishSubObject( myShape3.get() );
567     GEOMBase::PublishSubObject( myShape4.get() );
568     break;
569   default:
570     break;
571   }
572 }
573
574 //=================================================================================
575 // function : getSourceObjects
576 // purpose  : virtual method to get source objects
577 //=================================================================================
578 QList<GEOM::GeomObjPtr> BlocksGUI_QuadFaceDlg::getSourceObjects()
579 {
580   QList<GEOM::GeomObjPtr> res;
581   res << myShape1 << myShape2 << myShape3 << myShape4;
582   return res;
583 }