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