Salome HOME
Merge from V5_1_4_BR 07/05/2010
[modules/geom.git] / src / BlocksGUI / BlocksGUI_QuadFaceDlg.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
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 fird 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 = myShape2 = GEOM::GEOM_Object::_nil();
150   myShape3 = myShape4 = myShape1;
151
152   // clear line edits
153   QMap<int, QLineEdit*>::iterator anIterLE;
154   for (anIterLE = mySelName.begin(); anIterLE != mySelName.end(); ++anIterLE)
155     anIterLE.value()->setText("");
156
157   switch (constructorId) {
158   case 0:
159     myGrp2->hide();
160     myGrp3->hide();
161     myGrp1->show();
162     mySelBtn[Vertex1]->click();
163     break;
164   case 1:
165     myGrp1->hide();
166     myGrp3->hide();
167     myGrp2->show();
168     mySelBtn[Edge12]->click();
169     break;
170   case 2:
171     myGrp1->hide();
172     myGrp2->hide();
173     myGrp3->show();
174     mySelBtn[Edge14]->click();
175     break;
176   default:
177     break;
178   }
179
180   qApp->processEvents();
181   updateGeometry();
182   resize(minimumSizeHint());
183
184   // on dialog initialization we init the first field with a selected object (if any)
185   SelectionIntoArgument();
186 }
187
188 //=================================================================================
189 // function : ClickOnOk()
190 // purpose  :
191 //=================================================================================
192 void BlocksGUI_QuadFaceDlg::ClickOnOk()
193 {
194   if (ClickOnApply())
195     ClickOnCancel();
196 }
197
198 //=================================================================================
199 // function : ClickOnApply()
200 // purpose  :
201 //=================================================================================
202 bool BlocksGUI_QuadFaceDlg::ClickOnApply()
203 {
204   if (!onAccept())
205     return false;
206
207   initName();
208   return true;
209 }
210
211 //=================================================================================
212 // function : SelectionIntoArgument()
213 // purpose  : Called when selection is changed or on dialog initialization or activation
214 //=================================================================================
215 void BlocksGUI_QuadFaceDlg::SelectionIntoArgument()
216 {
217   erasePreview();
218
219   // Get index of current selection focus
220   int aCurrFocus = -1;
221   QMap<int, QLineEdit*>::iterator anIter;
222   for (anIter = mySelName.begin(); anIter != mySelName.end(); ++anIter) {
223     if (myEditCurrentArgument == anIter.value()) {
224       aCurrFocus = anIter.key();
225       break;
226     }
227   }
228
229   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
230   SALOME_ListIO aSelList;
231   aSelMgr->selectedObjects(aSelList);
232
233   TopAbs_ShapeEnum aType = TopAbs_EDGE;
234   if (aCurrFocus == Vertex1 || aCurrFocus == Vertex2 ||
235       aCurrFocus == Vertex3 || aCurrFocus == Vertex4)
236     aType = TopAbs_VERTEX;
237
238   QString aName;
239   GEOM::GEOM_Object_var anObj = GEOM::GEOM_Object::_nil();
240
241   if (aSelList.Extent() == 1) {
242     Standard_Boolean aResult = Standard_False;
243     anObj = GEOMBase::ConvertIOinGEOMObject(aSelList.First(), aResult);
244     if (aResult && !anObj->_is_nil()) {
245       aName = GEOMBase::GetName(anObj);
246
247       // Get Selected object if selected subshape
248       TopoDS_Shape aShape;
249       if (GEOMBase::GetShape(anObj, aShape, TopAbs_SHAPE) && !aShape.IsNull())
250       {
251         TColStd_IndexedMapOfInteger aMap;
252         aSelMgr->GetIndexes(aSelList.First(), aMap);
253         if (aMap.Extent() == 1) // Local Selection
254         {
255           int anIndex = aMap(1);
256           if (aType == TopAbs_VERTEX)
257             aName += QString(":vertex_%1").arg(anIndex);
258           else
259             aName += QString(":edge_%1").arg(anIndex);
260
261           //Find SubShape Object in Father
262           GEOM::GEOM_Object_var aFindedObject = GEOMBase_Helper::findObjectInFather(anObj, aName);
263
264           if (aFindedObject == GEOM::GEOM_Object::_nil()) { // Object not found in study
265             GEOM::GEOM_IShapesOperations_var aShapesOp = getGeomEngine()->GetIShapesOperations(getStudyId());
266             anObj = aShapesOp->GetSubShape(anObj, anIndex);
267           }
268           else
269             anObj = aFindedObject; // get Object from study
270         }
271         else // Global Selection
272         {
273           if (aShape.ShapeType() != aType) {
274             anObj = GEOM::GEOM_Object::_nil();
275             aName = "";
276           }
277         }
278       }
279     }
280   }
281
282   myEditCurrentArgument->setText(aName);
283
284   switch (aCurrFocus) {
285     // four vertices
286   case Vertex1:
287     myShape1 = anObj;
288     if (!myShape1->_is_nil() && myShape2->_is_nil())
289       mySelBtn[Vertex2]->click();
290     break;
291   case Vertex2:
292     myShape2 = anObj;
293     if (!myShape2->_is_nil() && myShape3->_is_nil())
294       mySelBtn[Vertex3]->click();
295     break;
296   case Vertex3:
297     myShape3 = anObj;
298     if (!myShape3->_is_nil() && myShape4->_is_nil())
299       mySelBtn[Vertex4]->click();
300     break;
301   case Vertex4:
302     myShape4 = anObj;
303     if (!myShape4->_is_nil() && myShape1->_is_nil())
304       mySelBtn[Vertex1]->click();
305     break;
306
307     // two edges
308   case Edge12:
309     myShape1 = anObj;
310     if (!myShape1->_is_nil() && myShape2->_is_nil())
311       mySelBtn[Edge22]->click();
312     break;
313   case Edge22:
314     myShape2 = anObj;
315     if (!myShape2->_is_nil() && myShape1->_is_nil())
316       mySelBtn[Edge12]->click();
317     break;
318
319     // four edges
320   case Edge14:
321     myShape1 = anObj;
322     if (!myShape1->_is_nil() && myShape2->_is_nil())
323       mySelBtn[Edge24]->click();
324     break;
325   case Edge24:
326     myShape2 = anObj;
327     if (!myShape2->_is_nil() && myShape3->_is_nil())
328       mySelBtn[Edge34]->click();
329     break;
330   case Edge34:
331     myShape3 = anObj;
332     if (!myShape3->_is_nil() && myShape4->_is_nil())
333       mySelBtn[Edge44]->click();
334     break;
335   case Edge44:
336     myShape4 = anObj;
337     if (!myShape4->_is_nil() && myShape1->_is_nil())
338       mySelBtn[Edge14]->click();
339     break;
340
341   default:
342     break;
343   }
344
345   displayPreview();
346 }
347
348 //=================================================================================
349 // function : SetEditCurrentArgument()
350 // purpose  :
351 //=================================================================================
352 void BlocksGUI_QuadFaceDlg::SetEditCurrentArgument()
353 {
354   QPushButton* aSender = (QPushButton*)sender();
355
356   // clear selection
357   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
358   if (myInitial)
359     myInitial = false;
360   else
361     myGeomGUI->getApp()->selectionMgr()->clearSelected();
362
363   // disable all
364   switch (myConstructorId) {
365   case 0:
366     mySelBtn[Vertex1]->setDown(false);
367     mySelBtn[Vertex2]->setDown(false);
368     mySelBtn[Vertex3]->setDown(false);
369     mySelBtn[Vertex4]->setDown(false);
370
371     mySelName[Vertex1]->setEnabled(false);
372     mySelName[Vertex2]->setEnabled(false);
373     mySelName[Vertex3]->setEnabled(false);
374     mySelName[Vertex4]->setEnabled(false);
375     break;
376   case 1:
377     mySelBtn[Edge12]->setDown(false);
378     mySelBtn[Edge22]->setDown(false);
379
380     mySelName[Edge12]->setEnabled(false);
381     mySelName[Edge22]->setEnabled(false);
382     break;
383   case 2:
384     mySelBtn[Edge14]->setDown(false);
385     mySelBtn[Edge24]->setDown(false);
386     mySelBtn[Edge34]->setDown(false);
387     mySelBtn[Edge44]->setDown(false);
388
389     mySelName[Edge14]->setEnabled(false);
390     mySelName[Edge24]->setEnabled(false);
391     mySelName[Edge34]->setEnabled(false);
392     mySelName[Edge44]->setEnabled(false);
393     break;
394   default:
395     break;
396   }
397
398   // set line edit as current argument
399   QMap<int, QPushButton*>::iterator anIter;
400   for (anIter = mySelBtn.begin(); anIter != mySelBtn.end(); ++anIter) {
401     if (anIter.value() == aSender) {
402       myEditCurrentArgument = mySelName[anIter.key()];
403       break;
404     }
405   }
406
407   // enable line edit
408   myEditCurrentArgument->setEnabled(true);
409   myEditCurrentArgument->setFocus();
410
411   // enable push button
412   // after setFocus(), because it will be setDown(false) when loses focus
413   aSender->setDown(true);
414
415   activateSelection();
416 }
417
418 //=================================================================================
419 // function : ActivateThisDialog()
420 // purpose  :
421 //=================================================================================
422 void BlocksGUI_QuadFaceDlg::ActivateThisDialog()
423 {
424   GEOMBase_Skeleton::ActivateThisDialog();
425   activateSelection();
426
427   // ??
428   displayPreview();
429 }
430
431 //=================================================================================
432 // function : enterEvent()
433 // purpose  :
434 //=================================================================================
435 void BlocksGUI_QuadFaceDlg::enterEvent (QEvent*)
436 {
437   if (!mainFrame()->GroupConstructors->isEnabled())
438     ActivateThisDialog();
439 }
440
441 //=================================================================================
442 // function : createSelWg()
443 // purpose  :
444 //=================================================================================
445 void BlocksGUI_QuadFaceDlg::createSelWg (const QString& theLbl,
446                                          QPixmap&       thePix,
447                                          QWidget*       theParent,
448                                          const int      theId)
449 {
450   QLabel* lab = new QLabel(theLbl, theParent);
451   mySelBtn[theId] = new QPushButton(theParent);
452   mySelBtn[theId]->setIcon(thePix);
453   mySelBtn[theId]->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
454   mySelName[theId] = new QLineEdit(theParent);
455   mySelName[theId]->setReadOnly(true);
456   QGridLayout* l = 0;
457   if (!theParent->layout()) {
458     l = new QGridLayout(theParent);
459     l->setMargin(9); l->setSpacing(6);
460   }
461   else {
462     l = qobject_cast<QGridLayout*>(theParent->layout());
463   }
464   int row = l->rowCount();
465   l->addWidget(lab,              row, 0);
466   l->addWidget(mySelBtn[theId],  row, 1);
467   l->addWidget(mySelName[theId], row, 2);
468 }
469
470 //=================================================================================
471 // function : activateSelection
472 // purpose  : Activate selection in accordance with myEditCurrentArgument
473 //=================================================================================
474 void BlocksGUI_QuadFaceDlg::activateSelection()
475 {
476   globalSelection(); // close local contexts, if any
477   if (myEditCurrentArgument == mySelName[Vertex1] ||
478       myEditCurrentArgument == mySelName[Vertex2] ||
479       myEditCurrentArgument == mySelName[Vertex3] ||
480       myEditCurrentArgument == mySelName[Vertex4])
481   {
482     localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); //Select Vertices on All Shapes
483   }
484   else
485   {
486     localSelection(GEOM::GEOM_Object::_nil(), TopAbs_EDGE); //Select Edges on All Shapes
487   }
488   connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
489           this, SLOT(SelectionIntoArgument()));
490 }
491
492 //=================================================================================
493 // function : createOperation
494 // purpose  :
495 //=================================================================================
496 GEOM::GEOM_IOperations_ptr BlocksGUI_QuadFaceDlg::createOperation()
497 {
498   return getGeomEngine()->GetIBlocksOperations(getStudyId());
499 }
500
501 //=================================================================================
502 // function : isValid
503 // purpose  : Verify validity of input data
504 //=================================================================================
505 bool BlocksGUI_QuadFaceDlg::isValid (QString&)
506 {
507   bool ok = false;
508   switch (getConstructorId()) {
509   case 0:
510     ok = (!myShape1->_is_nil() && !myShape2->_is_nil() &&
511           !myShape3->_is_nil() && !myShape4->_is_nil());
512     break;
513   case 1:
514     ok = (!myShape1->_is_nil() && !myShape2->_is_nil());
515     break;
516   case 2:
517     ok = (!myShape1->_is_nil() && !myShape2->_is_nil() &&
518           !myShape3->_is_nil() && !myShape4->_is_nil());
519     break;
520   default:
521     break;
522   }
523   return ok;
524 }
525
526 //=================================================================================
527 // function : execute
528 // purpose  :
529 //=================================================================================
530 bool BlocksGUI_QuadFaceDlg::execute (ObjectList& objects)
531 {
532   bool res = false;
533
534   GEOM::GEOM_Object_var anObj;
535
536   GEOM::GEOM_IBlocksOperations_var anOper = GEOM::GEOM_IBlocksOperations::_narrow(getOperation());
537
538   switch (getConstructorId()) {
539   case 0:
540     anObj = anOper->MakeQuad4Vertices(myShape1, myShape2, myShape3, myShape4);
541     res = true;
542     break;
543   case 1:
544     anObj = anOper->MakeQuad2Edges(myShape1, myShape2);
545     res = true;
546     break;
547   case 2:
548     anObj = anOper->MakeQuad(myShape1, myShape2, myShape3, myShape4);
549     res = true;
550     break;
551   default:
552     break;
553   }
554
555   if (!anObj->_is_nil())
556     objects.push_back(anObj._retn());
557
558   return res;
559 }
560
561 //=================================================================================
562 // function : addSubshapeToStudy
563 // purpose  : virtual method to add new SubObjects if local selection
564 //=================================================================================
565 void BlocksGUI_QuadFaceDlg::addSubshapesToStudy()
566 {
567   QMap<QString, GEOM::GEOM_Object_var> objMap;
568
569   switch (getConstructorId()) {
570   case 0:
571     objMap[mySelName[Vertex1]->text()] = myShape1;
572     objMap[mySelName[Vertex2]->text()] = myShape2;
573     objMap[mySelName[Vertex3]->text()] = myShape3;
574     objMap[mySelName[Vertex4]->text()] = myShape4;
575     break;
576   case 1:
577     objMap[mySelName[Edge12]->text()] = myShape1;
578     objMap[mySelName[Edge22]->text()] = myShape2;
579     break;
580   case 2:
581     objMap[mySelName[Edge14]->text()] = myShape1;
582     objMap[mySelName[Edge24]->text()] = myShape2;
583     objMap[mySelName[Edge34]->text()] = myShape3;
584     objMap[mySelName[Edge44]->text()] = myShape4;
585     break;
586   }
587   addSubshapesToFather(objMap);
588 }