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