Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/geom.git] / src / BlocksGUI / BlocksGUI_TrsfDlg.cxx
1 //  GEOM GEOMGUI : GUI for Geometry component
2 //
3 //  Copyright (C) 2003  CEA
4 //
5 //  This library is free software; you can redistribute it and/or
6 //  modify it under the terms of the GNU Lesser General Public
7 //  License as published by the Free Software Foundation; either
8 //  version 2.1 of the License.
9 //
10 //  This library is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 //  Lesser General Public License for more details.
14 //
15 //  You should have received a copy of the GNU Lesser General Public
16 //  License along with this library; if not, write to the Free Software
17 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 //
19 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 //
21 //
22 //
23 //  File   : BlocksGUI_TrsfDlg.cxx
24 //  Author : Julia DOROVSKIKH
25 //  Module : GEOM
26 //  $Header$
27
28 #include "BlocksGUI_TrsfDlg.h"
29
30 #include "DlgRef_SpinBox.h"
31
32 #include "SUIT_Session.h"
33 #include "SalomeApp_Application.h"
34 #include "LightApp_SelectionMgr.h"
35 #include "OCCViewer_ViewModel.h"
36
37 #include <TColStd_IndexedMapOfInteger.hxx>
38
39 #include <qlabel.h>
40
41 //=================================================================================
42 // class    : BlocksGUI_TrsfDlg()
43 // purpose  : Constructs a BlocksGUI_TrsfDlg which is a child of 'parent'.
44 //=================================================================================
45 BlocksGUI_TrsfDlg::BlocksGUI_TrsfDlg (GeometryGUI* theGeometryGUI, QWidget* parent, bool modal)
46      : GEOMBase_Skeleton(theGeometryGUI, parent, "TrsfDlg", modal,
47                          WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
48 {
49   SUIT_ResourceMgr* aResMgr = myGeomGUI->getApp()->resourceMgr();
50   QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_BLOCK_MULTITRSF_SIMPLE")));
51   QPixmap image2 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_BLOCK_MULTITRSF_DOUBLE")));
52   QPixmap imageS (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
53
54   setCaption(tr("GEOM_BLOCK_MULTITRSF_TITLE"));
55
56   /***************************************************************/
57   GroupConstructors->setTitle(tr("GEOM_BLOCK_MULTITRSF"));
58
59   RadioButton1->setPixmap(image1);
60   RadioButton2->setPixmap(image2);
61   RadioButton3->close(TRUE);
62
63   // Create first group
64   myGrp1 = new QGroupBox(1, Qt::Horizontal, tr("GEOM_BLOCK_MULTITRSF_SIMPLE"), this);
65
66   QGroupBox* aSelGrp1 = new QGroupBox(3, Qt::Horizontal, myGrp1);
67   aSelGrp1->setFrameStyle(QFrame::NoFrame);
68   aSelGrp1->setInsideMargin(0);
69
70   createSelWg(tr("GEOM_MAIN_OBJECT"), imageS, aSelGrp1, MainObj1);
71   createSelWg(tr("FACE_1"), imageS, aSelGrp1, Face1);
72   createSelWg(tr("FACE_2"), imageS, aSelGrp1, Face2);
73
74   QGroupBox* aSpinGrp1 = new QGroupBox(1, Qt::Vertical, myGrp1);
75   aSpinGrp1->setFrameStyle(QFrame::NoFrame);
76   aSpinGrp1->setInsideMargin(0);
77
78   new QLabel(tr("GEOM_NB_TIMES"), aSpinGrp1);
79   mySpinBox[SpinBox1] = new DlgRef_SpinBox(aSpinGrp1);
80
81   // Create second group
82   myGrp2 = new QGroupBox(1, Qt::Horizontal, tr("GEOM_BLOCK_MULTITRSF_DOUBLE"), this);
83
84   // U trsf
85   QGroupBox* aSelGrp2U = new QGroupBox(3, Qt::Horizontal, myGrp2);
86   aSelGrp2U->setFrameStyle(QFrame::NoFrame);
87   aSelGrp2U->setInsideMargin(0);
88
89   createSelWg(tr("GEOM_MAIN_OBJECT"), imageS, aSelGrp2U, MainObj2);
90   createSelWg(tr("FACE_1U"), imageS, aSelGrp2U, Face1U);
91   createSelWg(tr("FACE_2U"), imageS, aSelGrp2U, Face2U);
92
93   QGroupBox* aSpinGrp2U = new QGroupBox(1, Qt::Vertical, myGrp2);
94   aSpinGrp2U->setFrameStyle(QFrame::NoFrame);
95   aSpinGrp2U->setInsideMargin(0);
96
97   new QLabel(tr("GEOM_NB_TIMES_U"), aSpinGrp2U);
98   mySpinBox[SpinBox2U] = new DlgRef_SpinBox(aSpinGrp2U);
99
100   // V trsf
101   QGroupBox* aSelGrp2V = new QGroupBox(3, Qt::Horizontal, myGrp2);
102   aSelGrp2V->setFrameStyle(QFrame::NoFrame);
103   aSelGrp2V->setInsideMargin(0);
104
105   createSelWg(tr("FACE_1V"), imageS, aSelGrp2V, Face1V);
106   createSelWg(tr("FACE_2V"), imageS, aSelGrp2V, Face2V);
107
108   QGroupBox* aSpinGrp2V = new QGroupBox(1, Qt::Vertical, myGrp2);
109   aSpinGrp2V->setFrameStyle(QFrame::NoFrame);
110   aSpinGrp2V->setInsideMargin(0);
111
112   new QLabel(tr("GEOM_NB_TIMES_V"), aSpinGrp2V);
113   mySpinBox[SpinBox2V] = new DlgRef_SpinBox(aSpinGrp2V);
114
115   (new QLabel(myGrp2))->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
116
117   // Add groups to layout
118   Layout1->addWidget( myGrp1, 2, 0 );
119   Layout1->addWidget( myGrp2, 2, 0 );
120   /***************************************************************/
121
122   setHelpFileName("multi_transformation_operation_page.html");
123
124   Init();
125 }
126
127 //=================================================================================
128 // function : ~BlocksGUI_TrsfDlg()
129 // purpose  : Destroys the object and frees any allocated resources
130 //=================================================================================
131 BlocksGUI_TrsfDlg::~BlocksGUI_TrsfDlg()
132 {
133   // no need to delete child widgets, Qt does it all for us
134 }
135
136 //=================================================================================
137 // function : Init()
138 // purpose  :
139 //=================================================================================
140 void BlocksGUI_TrsfDlg::Init()
141 {
142   // Set range of spinboxes
143   double SpecificStep = 1.0;
144   QMap<int, DlgRef_SpinBox*>::iterator anIter;
145   for (anIter = mySpinBox.begin(); anIter != mySpinBox.end(); ++anIter) {
146     //anIter.data()->RangeStepAndValidator(1.0, 999.999, SpecificStep, 3);
147     anIter.data()->RangeStepAndValidator(1.0, MAX_NUMBER, SpecificStep, 3);
148   }
149
150   // signals and slots connections
151   connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()));
152   connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
153   connect(GroupConstructors, SIGNAL(clicked(int)), this, SLOT(ConstructorsClicked(int)));
154
155   QMap<int, QPushButton*>::iterator anIterBtn;
156   for (anIterBtn = mySelBtn.begin(); anIterBtn != mySelBtn.end(); ++anIterBtn)
157     connect(anIterBtn.data(), SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
158
159   QMap<int, DlgRef_SpinBox*>::iterator anIterSpin;
160   for (anIterSpin = mySpinBox.begin(); anIterSpin != mySpinBox.end(); ++anIterSpin)
161     connect(anIterSpin.data(), SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
162
163   connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(), 
164           SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())) ;
165
166   // init controls and fields
167   initName(tr("GEOM_BLOCK_MULTITRSF"));
168
169   myConstructorId = -1;
170   ConstructorsClicked(0);
171 }
172
173 //=================================================================================
174 // function : ConstructorsClicked()
175 // purpose  : Radio button management
176 //=================================================================================
177 void BlocksGUI_TrsfDlg::ConstructorsClicked (int constructorId)
178 {
179   if (myConstructorId == constructorId)
180     return;
181
182   myConstructorId = constructorId;
183
184   switch (constructorId) {
185   case 0:
186     myGrp2->hide();
187     myGrp1->show();
188     mySpinBox[SpinBox1]->SetValue(2.0);
189     myEditCurrentArgument = mySelName[MainObj1];
190     myFaces[Face1] = -1;
191     myFaces[Face2] = -1;
192     break;
193   case 1:
194     myGrp1->hide();
195     myGrp2->show();
196     mySpinBox[SpinBox2U]->SetValue(2.0);
197     mySpinBox[SpinBox2V]->SetValue(2.0);
198     myEditCurrentArgument = mySelName[MainObj2];
199     myFaces[Face1U] = -1;
200     myFaces[Face2U] = -1;
201     myFaces[Face1V] = -1;
202     myFaces[Face2V] = -1;
203     break;
204   default:
205     break;
206   }
207
208   // clear line edits
209   QMap<int, QLineEdit*>::iterator anIterLE;
210   for (anIterLE = mySelName.begin(); anIterLE != mySelName.end(); ++anIterLE)
211     anIterLE.data()->setText("");
212
213   // init fields
214   myShape = GEOM::GEOM_Object::_nil();
215
216   activateSelection();
217 //  enableWidgets();
218 //  displayPreview();
219 }
220
221 //=================================================================================
222 // function : ClickOnOk()
223 // purpose  :
224 //=================================================================================
225 void BlocksGUI_TrsfDlg::ClickOnOk()
226 {
227   if (ClickOnApply())
228     ClickOnCancel();
229 }
230
231 //=================================================================================
232 // function : ClickOnApply()
233 // purpose  :
234 //=================================================================================
235 bool BlocksGUI_TrsfDlg::ClickOnApply()
236 {
237   if (!onAccept())
238     return false;
239
240   initName();
241   return true;
242 }
243
244 //=================================================================================
245 // function : SelectionIntoArgument()
246 // purpose  : Called when selection has changed
247 //=================================================================================
248 void BlocksGUI_TrsfDlg::SelectionIntoArgument()
249 {
250   erasePreview();
251   myEditCurrentArgument->setText("");
252
253   // Get index of current selection focus
254   int aCurrFocus = -1;
255   QMap<int, QLineEdit*>::iterator anIter;
256   for (anIter = mySelName.begin(); anIter != mySelName.end(); ++anIter) {
257     if (myEditCurrentArgument == anIter.data()) {
258       aCurrFocus = anIter.key();
259       break;
260     }
261   }
262
263   // If selection of main object is activated
264   if (aCurrFocus == MainObj1 || aCurrFocus == MainObj2) {
265     if (IObjectCount() == 1) {
266       Standard_Boolean aResult = Standard_False;
267       GEOM::GEOM_Object_var anObj =
268         GEOMBase::ConvertIOinGEOMObject(firstIObject(), aResult);
269
270       if (aResult && !anObj->_is_nil() && GEOMBase::IsShape( anObj ) ) {
271         myShape = anObj;
272         mySelName[aCurrFocus]->setText(GEOMBase::GetName(anObj));
273         enableWidgets();
274         return;
275       }
276     }
277
278     myShape = GEOM::GEOM_Object::_nil();
279     enableWidgets();
280   }
281   // If face selection is activated
282   else if (aCurrFocus == Face1  || aCurrFocus == Face2  ||
283            aCurrFocus == Face1U || aCurrFocus == Face2U ||
284            aCurrFocus == Face1V || aCurrFocus == Face2V) {
285     if (IObjectCount() == 1) {
286       Standard_Boolean aResult = Standard_False;
287       GEOM::GEOM_Object_var anObj =
288         GEOMBase::ConvertIOinGEOMObject(firstIObject(), aResult);
289
290       if ( aResult && !anObj->_is_nil() && GEOMBase::IsShape( anObj ) ) {
291         TColStd_IndexedMapOfInteger anIndexes;
292         ((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr()->GetIndexes( firstIObject(), anIndexes );
293
294         if (anIndexes.Extent() == 1) {
295           int anIndex = anIndexes(1);
296           QString aFaceName = QString(GEOMBase::GetName(anObj)) + ":%1";
297           myEditCurrentArgument->setText(aFaceName.arg(anIndex));
298           myFaces[aCurrFocus] = anIndex;
299           displayPreview();
300           return;
301         }
302       }
303     }
304
305     myFaces[aCurrFocus] = -1;
306   }
307 }
308
309 //=================================================================================
310 // function : SetEditCurrentArgument()
311 // purpose  :
312 //=================================================================================
313 void BlocksGUI_TrsfDlg::SetEditCurrentArgument()
314 {
315   QPushButton* aSender = (QPushButton*)sender();
316
317   QMap<int, QPushButton*>::iterator anIter;
318   for (anIter = mySelBtn.begin(); anIter != mySelBtn.end(); ++anIter) {
319     if (anIter.data() == aSender) {
320       mySelName[anIter.key()]->setFocus();
321       myEditCurrentArgument = mySelName[anIter.key()];
322       break;
323     }
324   }
325
326   activateSelection();
327 }
328
329 //=================================================================================
330 // function : ActivateThisDialog()
331 // purpose  :
332 //=================================================================================
333 void BlocksGUI_TrsfDlg::ActivateThisDialog()
334 {
335   GEOMBase_Skeleton::ActivateThisDialog();
336   connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(), 
337           SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())) ;
338
339   activateSelection();
340   displayPreview();
341 }
342
343 //=================================================================================
344 // function : enterEvent()
345 // purpose  :
346 //=================================================================================
347 void BlocksGUI_TrsfDlg::enterEvent (QEvent* e)
348 {
349   if (!GroupConstructors->isEnabled())
350     this->ActivateThisDialog();
351 }
352
353 //=================================================================================
354 // function : ValueChangedInSpinBox()
355 // purpose  :
356 //=================================================================================
357 void BlocksGUI_TrsfDlg::ValueChangedInSpinBox (double newValue)
358 {
359   displayPreview();
360 }
361
362 //=================================================================================
363 // function : createSelWg()
364 // purpose  :
365 //=================================================================================
366 void BlocksGUI_TrsfDlg::createSelWg (const QString& theLbl,
367                                      QPixmap&       thePix,
368                                      QWidget*       theParent,
369                                      const int      theId)
370 {
371   new QLabel(theLbl, theParent);
372   mySelBtn[theId] = new QPushButton(theParent);
373   mySelBtn[theId]->setPixmap(thePix);
374   mySelName[theId] = new QLineEdit(theParent);
375   mySelName[theId]->setReadOnly(true);
376 }
377
378 //=================================================================================
379 // function : activateSelection
380 // purpose  : Activate selection in accordance with myEditCurrentArgument
381 //=================================================================================
382 void BlocksGUI_TrsfDlg::activateSelection()
383 {
384   if (!myShape->_is_nil() &&
385       (myEditCurrentArgument == mySelName[ Face1  ] ||
386        myEditCurrentArgument == mySelName[ Face2  ] ||
387        myEditCurrentArgument == mySelName[ Face1U ] ||
388        myEditCurrentArgument == mySelName[ Face2U ] ||
389        myEditCurrentArgument == mySelName[ Face1V ] ||
390        myEditCurrentArgument == mySelName[ Face2V ])) {
391
392     // Local selection is available only in the OCC Viewer
393     if (SUIT_Session::session()->activeApplication()->desktop()->activeWindow()->getViewManager()->getType() 
394         == OCCViewer_Viewer::Type()) {
395       localSelection(myShape, TopAbs_FACE);
396     } else {
397       return;
398     }
399   } else {
400     globalSelection( GEOM_ALLSHAPES );
401   }
402
403   SelectionIntoArgument();
404 }
405
406 //=================================================================================
407 // function : enableWidgets
408 // purpose  : Enable widgets of faces in accordance with value of main object
409 //=================================================================================
410 void BlocksGUI_TrsfDlg::enableWidgets()
411 {
412   int anId = getConstructorId();
413
414   bool toEnable = !myShape->_is_nil();
415
416   if (anId == 0) {
417     mySelName[Face1]->setEnabled(toEnable);
418     mySelName[Face2]->setEnabled(toEnable);
419     mySelBtn[Face1]->setEnabled(toEnable);
420     mySelBtn[Face2]->setEnabled(toEnable);
421
422     if (!toEnable) {
423       mySelName[Face1]->setText("");
424       mySelName[Face2]->setText("");
425       myFaces[Face1] = -1;
426       myFaces[Face2] = -1;
427     }
428   } else if (anId == 1) {
429     mySelName[Face1U]->setEnabled(toEnable);
430     mySelName[Face2U]->setEnabled(toEnable);
431     mySelName[Face1V]->setEnabled(toEnable);
432     mySelName[Face2V]->setEnabled(toEnable);
433     mySelBtn[Face1U]->setEnabled(toEnable);
434     mySelBtn[Face2U]->setEnabled(toEnable);
435     mySelBtn[Face1V]->setEnabled(toEnable);
436     mySelBtn[Face2V]->setEnabled(toEnable);
437
438     if (!toEnable) {
439       mySelName[Face1U]->setText("");
440       mySelName[Face2U]->setText("");
441       mySelName[Face1V]->setText("");
442       mySelName[Face2V]->setText("");
443       myFaces[Face1U] = -1;
444       myFaces[Face2U] = -1;
445       myFaces[Face1V] = -1;
446       myFaces[Face2V] = -1;
447     }
448   }
449 }
450
451 //=================================================================================
452 // function : createOperation
453 // purpose  :
454 //=================================================================================
455 GEOM::GEOM_IOperations_ptr BlocksGUI_TrsfDlg::createOperation()
456 {
457   return getGeomEngine()->GetIBlocksOperations(getStudyId());
458 }
459
460 //=================================================================================
461 // function : ClickOnApply()
462 // purpose  : Verify validity of input data
463 //=================================================================================
464 bool BlocksGUI_TrsfDlg::isValid (QString&)
465 {
466   switch (getConstructorId()) {
467     case 0:
468       return !myShape->_is_nil() && myFaces[Face1] > 0;
469     case 1:
470       return !myShape->_is_nil() && myFaces[Face1U] > 0 && myFaces[Face1V] > 0;
471     default:
472       return false;
473   }
474   return false;
475 }
476
477 //=================================================================================
478 // function : execute
479 // purpose  :
480 //=================================================================================
481 bool BlocksGUI_TrsfDlg::execute (ObjectList& objects)
482 {
483   bool res = false;
484
485   GEOM::GEOM_Object_var anObj;
486
487   switch (getConstructorId()) {
488     case 0:
489       anObj = GEOM::GEOM_IBlocksOperations::_narrow(getOperation())->MakeMultiTransformation1D
490         (myShape,
491          myFaces[Face1],
492          myFaces[Face2],
493          (int)mySpinBox[SpinBox1]->GetValue());
494       res = true;
495       break;
496     case 1:
497       anObj = GEOM::GEOM_IBlocksOperations::_narrow(getOperation())->MakeMultiTransformation2D
498         (myShape,
499          myFaces[Face1U],
500          myFaces[Face2U],
501          (int)mySpinBox[SpinBox2U]->GetValue(),
502          myFaces[Face1V],
503          myFaces[Face2V],
504          (int)mySpinBox[SpinBox2V]->GetValue());
505       res = true;
506       break;
507   }
508
509   if (!anObj->_is_nil())
510     objects.push_back(anObj._retn());
511
512   return res;
513 }