Salome HOME
b5d681c4ed492e842b34d92f37e392eb71fcdd6c
[modules/geom.git] / src / BlocksGUI / BlocksGUI_TrsfDlg.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_TrsfDlg.cxx
24 // Author : Julia DOROVSKIKH, Open CASCADE S.A.S. (julia.dorovskikh@opencascade.com)
25 //
26 #include "BlocksGUI_TrsfDlg.h"
27
28 #include <DlgRef.h>
29 #include <GeometryGUI.h>
30 #include <GEOMBase.h>
31
32 #include <SUIT_Session.h>
33 #include <SUIT_Desktop.h>
34 #include <SUIT_ResourceMgr.h>
35 #include <SUIT_ViewWindow.h>
36 #include <SUIT_ViewManager.h>
37 #include <SalomeApp_Application.h>
38 #include <LightApp_SelectionMgr.h>
39 #include <OCCViewer_ViewModel.h>
40
41 // OCCT Includes
42 #include <TColStd_IndexedMapOfInteger.hxx>
43
44 //=================================================================================
45 // class    : BlocksGUI_TrsfDlg()
46 // purpose  : Constructs a BlocksGUI_TrsfDlg which is a child of 'parent'.
47 //=================================================================================
48 BlocksGUI_TrsfDlg::BlocksGUI_TrsfDlg (GeometryGUI* theGeometryGUI, QWidget* parent)
49   : GEOMBase_Skeleton(theGeometryGUI, parent),
50     myInitial(true)
51 {
52   SUIT_ResourceMgr* aResMgr = myGeomGUI->getApp()->resourceMgr();
53   QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_BLOCK_MULTITRSF_SIMPLE")));
54   QPixmap image2 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_BLOCK_MULTITRSF_DOUBLE")));
55   QPixmap imageS (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
56
57   setWindowTitle(tr("GEOM_BLOCK_MULTITRSF_TITLE"));
58
59   /***************************************************************/
60   mainFrame()->GroupConstructors->setTitle(tr("GEOM_BLOCK_MULTITRSF"));
61
62   mainFrame()->RadioButton1->setIcon(image1);
63   mainFrame()->RadioButton2->setIcon(image2);
64   mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose);
65   mainFrame()->RadioButton3->close();
66
67   // Create first group
68   myGrp1 = new QGroupBox(tr("GEOM_BLOCK_MULTITRSF_SIMPLE"), centralWidget());
69
70   createSelWg(tr("GEOM_MAIN_OBJECT"), imageS, myGrp1, MainObj1);
71   createSelWg(tr("FACE_1"),           imageS, myGrp1, Face1);
72   createSelWg(tr("FACE_2"),           imageS, myGrp1, Face2);
73   createSpinWg(tr("GEOM_NB_TIMES"),           myGrp1, SpinBox1);
74
75   // Create second group
76   myGrp2 = new QGroupBox(tr("GEOM_BLOCK_MULTITRSF_DOUBLE"), centralWidget());
77
78   createSelWg(tr("GEOM_MAIN_OBJECT"), imageS, myGrp2, MainObj2);
79   createSelWg(tr("FACE_1U"),          imageS, myGrp2, Face1U);
80   createSelWg(tr("FACE_2U"),          imageS, myGrp2, Face2U);
81   createSpinWg(tr("GEOM_NB_TIMES_U"),         myGrp2, SpinBox2U);
82   createSelWg(tr("FACE_1V"),          imageS, myGrp2, Face1V);
83   createSelWg(tr("FACE_2V"),          imageS, myGrp2, Face2V);
84   createSpinWg(tr("GEOM_NB_TIMES_V"),         myGrp2, SpinBox2V);
85
86   // Add groups to layout
87   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
88   layout->setMargin(0); layout->setSpacing(6);
89   layout->addWidget(myGrp1);
90   layout->addWidget(myGrp2);
91   /***************************************************************/
92
93   setHelpFileName("multi_transformation_operation_page.html");
94
95   Init();
96 }
97
98 //=================================================================================
99 // function : ~BlocksGUI_TrsfDlg()
100 // purpose  : Destroys the object and frees any allocated resources
101 //=================================================================================
102 BlocksGUI_TrsfDlg::~BlocksGUI_TrsfDlg()
103 {
104   // no need to delete child widgets, Qt does it all for us
105 }
106
107 //=================================================================================
108 // function : Init()
109 // purpose  :
110 //=================================================================================
111 void BlocksGUI_TrsfDlg::Init()
112 {
113   // Set range of spinboxes
114   int SpecificStep = 1;
115   QMap<int, SalomeApp_IntSpinBox*>::iterator anIter;
116   for (anIter = mySpinBox.begin(); anIter != mySpinBox.end(); ++anIter) {
117     //anIter.data()->RangeStepAndValidator(1, 999, SpecificStep);
118     initSpinBox(anIter.value(), 1, 999, SpecificStep);
119   }
120
121   // signals and slots connections
122   connect(buttonOk(),    SIGNAL(clicked()), this, SLOT(ClickOnOk()));
123   connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
124
125   connect(this, SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int)));
126
127   QMap<int, QPushButton*>::iterator anIterBtn;
128   for (anIterBtn = mySelBtn.begin(); anIterBtn != mySelBtn.end(); ++anIterBtn)
129     connect(anIterBtn.value(), SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
130
131   QMap<int, SalomeApp_IntSpinBox*>::iterator anIterSpin;
132   for (anIterSpin = mySpinBox.begin(); anIterSpin != mySpinBox.end(); ++anIterSpin)
133     connect(anIterSpin.value(), SIGNAL(valueChanged(int)), this, SLOT(ValueChangedInSpinBox(int)));
134
135   // init controls and fields
136   initName(tr("GEOM_BLOCK_MULTITRSF"));
137
138   myConstructorId = -1;
139   ConstructorsClicked(0);
140 }
141
142 //=================================================================================
143 // function : ConstructorsClicked()
144 // purpose  : Radio button management
145 //=================================================================================
146 void BlocksGUI_TrsfDlg::ConstructorsClicked (int constructorId)
147 {
148   if (myConstructorId == constructorId)
149     return;
150
151   myConstructorId = constructorId;
152
153   // init fields
154   myShape = GEOM::GEOM_Object::_nil();
155   myFaces[Face1] = myFaces[Face2] = -1;
156   myFaces[Face1U] = myFaces[Face2U] = -1;
157   myFaces[Face1V] = myFaces[Face2V] = -1;
158
159   // clear line edits
160   QMap<int, QLineEdit*>::iterator anIterLE;
161   for (anIterLE = mySelName.begin(); anIterLE != mySelName.end(); ++anIterLE)
162     anIterLE.value()->setText("");
163
164   switch (constructorId) {
165   case 0:
166     myGrp2->hide();
167     myGrp1->show();
168     mySpinBox[SpinBox1]->setValue(2);
169     mySelBtn[MainObj1]->click();
170     break;
171   case 1:
172     myGrp1->hide();
173     myGrp2->show();
174     mySpinBox[SpinBox2U]->setValue(2);
175     mySpinBox[SpinBox2V]->setValue(2);
176     mySelBtn[MainObj2]->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_TrsfDlg::ClickOnOk()
195 {
196   if (ClickOnApply())
197     ClickOnCancel();
198 }
199
200 //=================================================================================
201 // function : ClickOnApply()
202 // purpose  :
203 //=================================================================================
204 bool BlocksGUI_TrsfDlg::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_TrsfDlg::SelectionIntoArgument()
218 {
219   erasePreview();
220   myEditCurrentArgument->setText("");
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   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
233   SALOME_ListIO aSelList;
234   aSelMgr->selectedObjects(aSelList);
235
236   QString aName;
237   GEOM::GEOM_Object_var anObj = GEOM::GEOM_Object::_nil();
238
239   if (aCurrFocus == MainObj1 || aCurrFocus == MainObj2)
240   {
241     // If selection of main object is activated
242     if (aSelList.Extent() == 1) {
243       Standard_Boolean aResult = Standard_False;
244       anObj = GEOMBase::ConvertIOinGEOMObject(aSelList.First(), aResult);
245
246       if (aResult && !anObj->_is_nil() && GEOMBase::IsShape(anObj)) {
247         aName = GEOMBase::GetName(anObj);
248       }
249     }
250     myEditCurrentArgument->setText(aName);
251     myShape = anObj;
252     enableWidgets();
253   }
254   else if (aCurrFocus == Face1  || aCurrFocus == Face2  ||
255            aCurrFocus == Face1U || aCurrFocus == Face2U ||
256            aCurrFocus == Face1V || aCurrFocus == Face2V) {
257     // If face selection is activated
258     int anIndex = -1;
259     if (aSelList.Extent() == 1) {
260       Standard_Boolean aResult = Standard_False;
261       anObj = GEOMBase::ConvertIOinGEOMObject(aSelList.First(), aResult);
262       if (aResult && !anObj->_is_nil() && GEOMBase::IsShape(anObj)) {
263         aName = GEOMBase::GetName(anObj);
264         TColStd_IndexedMapOfInteger anIndexes;
265         aSelMgr->GetIndexes(aSelList.First(), anIndexes);
266
267         if (anIndexes.Extent() == 1) {
268           anIndex = anIndexes(1);
269           aName += QString(":face_%1").arg(anIndex);
270         }
271       }
272     }
273     myEditCurrentArgument->setText(aName);
274     myFaces[aCurrFocus] = anIndex;
275     displayPreview();
276   }
277
278   switch (aCurrFocus) {
279     // 1D
280   case MainObj1:
281     if (!myShape->_is_nil() && myFaces[Face1] == -1)
282       mySelBtn[Face1]->click();
283     break;
284   case Face1:
285     if (myFaces[Face1] != -1 && myFaces[Face2] == -1)
286       mySelBtn[Face2]->click();
287     break;
288   case Face2:
289     if (myFaces[Face2] != -1 && myShape->_is_nil())
290       mySelBtn[MainObj1]->click();
291     break;
292
293     // 2D
294   case MainObj2:
295     if (!myShape->_is_nil() && myFaces[Face1U] == -1)
296       mySelBtn[Face1U]->click();
297     break;
298   case Face1U:
299     if (myFaces[Face1U] != -1 && myFaces[Face2U] == -1)
300       mySelBtn[Face2U]->click();
301     break;
302   case Face2U:
303     if (myFaces[Face2U] != -1 && myFaces[Face1V] == -1)
304       mySelBtn[Face1V]->click();
305     break;
306   case Face1V:
307     if (myFaces[Face1V] != -1 && myFaces[Face2V] == -1)
308       mySelBtn[Face2V]->click();
309     break;
310   case Face2V:
311     if (myFaces[Face2V] != -1 && myShape->_is_nil())
312       mySelBtn[MainObj1]->click();
313     break;
314
315   default:
316     break;
317   }
318 }
319
320 //=================================================================================
321 // function : SetEditCurrentArgument()
322 // purpose  :
323 //=================================================================================
324 void BlocksGUI_TrsfDlg::SetEditCurrentArgument()
325 {
326   QPushButton* aSender = (QPushButton*)sender();
327
328   // clear selection
329   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
330   if (myInitial)
331     myInitial = false;
332   else
333     myGeomGUI->getApp()->selectionMgr()->clearSelected();
334
335   // disable all
336   switch (myConstructorId) {
337   case 0:
338     mySelBtn[MainObj1]->setDown(false);
339     mySelBtn[Face1]->setDown(false);
340     mySelBtn[Face2]->setDown(false);
341
342     mySelName[MainObj1]->setEnabled(false);
343     mySelName[Face1]->setEnabled(false);
344     mySelName[Face2]->setEnabled(false);
345     break;
346   case 1:
347     mySelBtn[MainObj2]->setDown(false);
348     mySelBtn[Face1U]->setDown(false);
349     mySelBtn[Face2U]->setDown(false);
350     mySelBtn[Face1V]->setDown(false);
351     mySelBtn[Face2V]->setDown(false);
352
353     mySelName[MainObj2]->setEnabled(false);
354     mySelName[Face1U]->setEnabled(false);
355     mySelName[Face2U]->setEnabled(false);
356     mySelName[Face1V]->setEnabled(false);
357     mySelName[Face2V]->setEnabled(false);
358     break;
359   default:
360     break;
361   }
362
363   // set line edit as current argument
364   QMap<int, QPushButton*>::iterator anIter;
365   for (anIter = mySelBtn.begin(); anIter != mySelBtn.end(); ++anIter) {
366     if (anIter.value() == aSender) {
367       myEditCurrentArgument = mySelName[anIter.key()];
368       break;
369     }
370   }
371
372   // enable line edit
373   myEditCurrentArgument->setEnabled(true);
374   myEditCurrentArgument->setFocus();
375
376   // enable push button
377   // after setFocus(), because it will be setDown(false) when loses focus
378   aSender->setDown(true);
379
380   activateSelection();
381 }
382
383 //=================================================================================
384 // function : ActivateThisDialog()
385 // purpose  :
386 //=================================================================================
387 void BlocksGUI_TrsfDlg::ActivateThisDialog()
388 {
389   GEOMBase_Skeleton::ActivateThisDialog();
390   activateSelection();
391
392   // ??
393   displayPreview();
394 }
395
396 //=================================================================================
397 // function : enterEvent()
398 // purpose  :
399 //=================================================================================
400 void BlocksGUI_TrsfDlg::enterEvent (QEvent*)
401 {
402   if (!mainFrame()->GroupConstructors->isEnabled())
403     ActivateThisDialog();
404 }
405
406 //=================================================================================
407 // function : ValueChangedInSpinBox()
408 // purpose  :
409 //=================================================================================
410 void BlocksGUI_TrsfDlg::ValueChangedInSpinBox(int)
411 {
412   displayPreview();
413 }
414
415 //=================================================================================
416 // function : createSelWg()
417 // purpose  :
418 //=================================================================================
419 void BlocksGUI_TrsfDlg::createSelWg (const QString& theLbl,
420                                      QPixmap&       thePix,
421                                      QWidget*       theParent,
422                                      const int      theId)
423 {
424   QLabel* lab = new QLabel(theLbl, theParent);
425   mySelBtn[theId] = new QPushButton(theParent);
426   mySelBtn[theId]->setIcon(thePix);
427   mySelBtn[theId]->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
428   mySelName[theId] = new QLineEdit(theParent);
429   mySelName[theId]->setReadOnly(true);
430   QGridLayout* l = 0;
431   if (!theParent->layout()) {
432     l = new QGridLayout(theParent);
433     l->setMargin(9); l->setSpacing(6);
434   }
435   else {
436     l = qobject_cast<QGridLayout*>(theParent->layout());
437   }
438   int row = l->rowCount();
439   l->addWidget(lab,              row, 0);
440   l->addWidget(mySelBtn[theId],  row, 1);
441   l->addWidget(mySelName[theId], row, 2);
442 }
443
444 //=================================================================================
445 // function : createSpinWg()
446 // purpose  :
447 //=================================================================================
448 void BlocksGUI_TrsfDlg::createSpinWg (const QString& theLbl,
449                                       QWidget*       theParent,
450                                       const int      theId)
451 {
452   QLabel* lab = new QLabel(theLbl, theParent);
453   mySpinBox[theId] = new SalomeApp_IntSpinBox(theParent);
454   QGridLayout* l = 0;
455   if (!theParent->layout()) {
456     l = new QGridLayout(theParent);
457     l->setMargin(9); l->setSpacing(6);
458   }
459   else {
460     l = qobject_cast<QGridLayout*>(theParent->layout());
461   }
462   int row = l->rowCount();
463   l->addWidget(lab,              row, 0);
464   l->addWidget(mySpinBox[theId], row, 2);
465 }
466
467 //=================================================================================
468 // function : activateSelection
469 // purpose  : Activate selection in accordance with myEditCurrentArgument
470 //=================================================================================
471 void BlocksGUI_TrsfDlg::activateSelection()
472 {
473   globalSelection(GEOM_ALLSHAPES);
474   if (!myShape->_is_nil() &&
475       (myEditCurrentArgument == mySelName[Face1 ] ||
476        myEditCurrentArgument == mySelName[Face2 ] ||
477        myEditCurrentArgument == mySelName[Face1U] ||
478        myEditCurrentArgument == mySelName[Face2U] ||
479        myEditCurrentArgument == mySelName[Face1V] ||
480        myEditCurrentArgument == mySelName[Face2V]))
481   {
482     // Local selection is available only in the OCC Viewer
483     if (getDesktop()->activeWindow()->getViewManager()->getType() == OCCViewer_Viewer::Type()) {
484       localSelection(myShape, TopAbs_FACE);
485     }
486   }
487   connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
488           this, SLOT(SelectionIntoArgument()));
489 }
490
491 //=================================================================================
492 // function : enableWidgets
493 // purpose  : Enable widgets of faces in accordance with value of main object
494 //=================================================================================
495 void BlocksGUI_TrsfDlg::enableWidgets()
496 {
497   int anId = getConstructorId();
498
499   bool toEnable = !myShape->_is_nil();
500
501   if (anId == 0) {
502     //mySelName[Face1]->setEnabled(toEnable);
503     //mySelName[Face2]->setEnabled(toEnable);
504     //mySelBtn[Face1]->setEnabled(toEnable);
505     //mySelBtn[Face2]->setEnabled(toEnable);
506
507     if (!toEnable)  {
508       mySelName[Face1]->setText("");
509       mySelName[Face2]->setText("");
510       myFaces[Face1] = -1;
511       myFaces[Face2] = -1;
512     }
513   }
514   else if (anId == 1) {
515     //mySelName[Face1U]->setEnabled(toEnable);
516     //mySelName[Face2U]->setEnabled(toEnable);
517     //mySelName[Face1V]->setEnabled(toEnable);
518     //mySelName[Face2V]->setEnabled(toEnable);
519     //mySelBtn[Face1U]->setEnabled(toEnable);
520     //mySelBtn[Face2U]->setEnabled(toEnable);
521     //mySelBtn[Face1V]->setEnabled(toEnable);
522     //mySelBtn[Face2V]->setEnabled(toEnable);
523
524     if (!toEnable) {
525       mySelName[Face1U]->setText("");
526       mySelName[Face2U]->setText("");
527       mySelName[Face1V]->setText("");
528       mySelName[Face2V]->setText("");
529       myFaces[Face1U] = -1;
530       myFaces[Face2U] = -1;
531       myFaces[Face1V] = -1;
532       myFaces[Face2V] = -1;
533     }
534   }
535 }
536
537 //=================================================================================
538 // function : createOperation
539 // purpose  :
540 //=================================================================================
541 GEOM::GEOM_IOperations_ptr BlocksGUI_TrsfDlg::createOperation()
542 {
543   return getGeomEngine()->GetIBlocksOperations(getStudyId());
544 }
545
546 //=================================================================================
547 // function : isValid
548 // purpose  : Verify validity of input data
549 //=================================================================================
550 bool BlocksGUI_TrsfDlg::isValid (QString& msg)
551 {
552   bool ok = false, okSP = true;
553   switch (getConstructorId()) {
554   case 0:
555     ok = !myShape->_is_nil() && myFaces[Face1] > 0;
556     okSP = mySpinBox[SpinBox1]->isValid( msg, !IsPreview() );
557     break;
558   case 1:
559     ok = !myShape->_is_nil() && myFaces[Face1U] > 0 && myFaces[Face1V] > 0;
560     okSP = mySpinBox[SpinBox2U]->isValid( msg, !IsPreview() ) && okSP;
561     okSP = mySpinBox[SpinBox2V]->isValid( msg, !IsPreview() ) && okSP;
562     break;
563   default:
564     break;
565   }
566   return ok && okSP;
567 }
568
569 //=================================================================================
570 // function : execute
571 // purpose  :
572 //=================================================================================
573 bool BlocksGUI_TrsfDlg::execute (ObjectList& objects)
574 {
575   bool res = false;
576
577   GEOM::GEOM_Object_var anObj;
578
579   GEOM::GEOM_IBlocksOperations_var anOper = GEOM::GEOM_IBlocksOperations::_narrow(getOperation());
580
581   switch (getConstructorId()) {
582   case 0:
583     anObj = anOper->MakeMultiTransformation1D(myShape,
584                                               myFaces[Face1], myFaces[Face2],
585                                               mySpinBox[SpinBox1]->value());
586     if (!anObj->_is_nil() && !IsPreview())
587     {
588       QStringList aParameters;
589       aParameters << "" << "";
590       aParameters << mySpinBox[SpinBox1]->text();
591       anObj->SetParameters(aParameters.join(":").toLatin1().constData());
592     }
593     res = true;
594     break;
595   case 1:
596     anObj = anOper->MakeMultiTransformation2D (myShape,
597                                                myFaces[Face1U], myFaces[Face2U],
598                                                mySpinBox[SpinBox2U]->value(),
599                                                myFaces[Face1V], myFaces[Face2V],
600                                                mySpinBox[SpinBox2V]->value());
601     if (!anObj->_is_nil() && !IsPreview())
602     {
603       QStringList aParameters;
604       aParameters << "" << "";
605       aParameters << mySpinBox[SpinBox2U]->text();
606       aParameters << "" << "";
607       aParameters << mySpinBox[SpinBox2V]->text();
608       anObj->SetParameters(aParameters.join(":").toLatin1().constData());
609     }
610     res = true;
611     break;
612   default:
613     break;
614   }
615
616   if (!anObj->_is_nil())
617     objects.push_back(anObj._retn());
618
619   return res;
620 }