Salome HOME
d8ec38847ab6cfb4e7077f98ed865474c07a697f
[modules/geom.git] / src / BlocksGUI / BlocksGUI_ExplodeDlg.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_ExplodeDlg.cxx
24 //  Author : Julia DOROVSKIKH
25 //  Module : GEOM
26 //  $Header$
27
28 #include "BlocksGUI_ExplodeDlg.h"
29
30 #include "DlgRef_SpinBox.h"
31
32 #include "GEOM_Displayer.h"
33
34 #include "SUIT_Session.h"
35 #include "SalomeApp_Application.h"
36 #include "LightApp_SelectionMgr.h"
37 #include "OCCViewer_ViewModel.h"
38 #include "SALOME_ListIteratorOfListIO.hxx"
39
40 #include "utilities.h"
41
42 #include <TColStd_IndexedMapOfInteger.hxx>
43
44 #include <qmessagebox.h>
45 #include <qtextedit.h>
46 #include <qcheckbox.h>
47 #include <qlabel.h>
48
49 //=================================================================================
50 // class    : BlocksGUI_ExplodeDlg()
51 // purpose  : Constructs a BlocksGUI_ExplodeDlg which is a child of 'parent'.
52 //=================================================================================
53 BlocksGUI_ExplodeDlg::BlocksGUI_ExplodeDlg (GeometryGUI* theGeometryGUI, QWidget* parent, bool modal)
54      : GEOMBase_Skeleton(theGeometryGUI, parent, "ExplodeDlg", modal,
55                          WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
56 {
57   QPixmap image1 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM",tr("ICON_DLG_BLOCK_EXPLODE")));
58   QPixmap imageS (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM",tr("ICON_SELECT")));
59
60   setCaption(tr("GEOM_BLOCK_EXPLODE_TITLE"));
61
62   /***************************************************************/
63   GroupConstructors->setTitle(tr("GEOM_BLOCK_EXPLODE"));
64
65   RadioButton1->setPixmap(image1);
66   RadioButton2->close(TRUE);
67   RadioButton3->close(TRUE);
68
69   // Create first group
70   myGrp1 = new QGroupBox(1, Qt::Horizontal, tr("GEOM_ARGUMENTS"), this);
71
72   QGroupBox* aSelGrp = new QGroupBox(3, Qt::Horizontal, myGrp1);
73   aSelGrp->setFrameStyle(QFrame::NoFrame);
74   aSelGrp->setInsideMargin(0);
75
76   new QLabel(tr("GEOM_MAIN_OBJECT"), aSelGrp);
77   mySelBtn = new QPushButton(aSelGrp);
78   mySelBtn->setPixmap(imageS);
79   mySelName = new QLineEdit(aSelGrp);
80   mySelName->setReadOnly(true);
81
82   QGroupBox* aSpinGrp = new QGroupBox(2, Qt::Horizontal, myGrp1);
83   aSpinGrp->setFrameStyle(QFrame::NoFrame);
84   aSpinGrp->setInsideMargin(0);
85
86   new QLabel(tr("NB_FACES_MIN"), aSpinGrp);
87   mySpinBoxMin = new DlgRef_SpinBox(aSpinGrp);
88
89   new QLabel(tr("NB_FACES_MAX"), aSpinGrp);
90   mySpinBoxMax = new DlgRef_SpinBox(aSpinGrp);
91
92   QGroupBox* anInfoGrp = new QGroupBox(2, Qt::Horizontal, myGrp1);
93   anInfoGrp->setFrameStyle(QFrame::NoFrame);
94   anInfoGrp->setInsideMargin(0);
95
96   myBlocksNb = new QTextEdit(anInfoGrp);
97   myBlocksNb->setReadOnly(true);
98
99   QGroupBox* aCheckGrp = new QGroupBox(3, Qt::Horizontal, myGrp1);
100   aCheckGrp->setFrameStyle(QFrame::NoFrame);
101   aCheckGrp->setInsideMargin(0);
102
103   myCheckBtn = new QCheckBox(aCheckGrp, "CheckButton1");
104   myCheckBtn->setText(tr("GEOM_SUBSHAPE_SELECT"));
105
106   // Add groups to layout
107   Layout1->addWidget(myGrp1, 1, 0);
108   /***************************************************************/
109
110   setHelpFileName("explode_on_blocks.htm");
111
112   Init();
113 }
114
115 //=================================================================================
116 // function : ~BlocksGUI_ExplodeDlg()
117 // purpose  : Destroys the object and frees any allocated resources
118 //=================================================================================
119 BlocksGUI_ExplodeDlg::~BlocksGUI_ExplodeDlg()
120 {
121   // no need to delete child widgets, Qt does it all for us
122   clearTemporary();
123 }
124
125 //=================================================================================
126 // function : Init()
127 // purpose  :
128 //=================================================================================
129 void BlocksGUI_ExplodeDlg::Init()
130 {
131   // Set range of spinboxes
132   double SpecificStep = 1.0;
133   mySpinBoxMin->RangeStepAndValidator(0.0, 999.0, SpecificStep, 3);
134   mySpinBoxMax->RangeStepAndValidator(0.0, 999.0, SpecificStep, 3);
135
136   if (SUIT_Session::session()->activeApplication()->desktop()->activeWindow()->getViewManager()->getType() 
137       != OCCViewer_Viewer::Type())
138     myCheckBtn->setEnabled(false);
139
140   // signals and slots connections
141   connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()));
142   connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
143
144   connect(mySelBtn, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
145
146   connect(mySpinBoxMin, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
147   connect(mySpinBoxMax, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
148
149   connect(myCheckBtn, SIGNAL(stateChanged(int)), this, SLOT(SubShapeToggled()));
150
151   connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(), 
152           SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())) ;
153
154   myConstructorId = -1;
155   ConstructorsClicked(0);
156 }
157
158 //=================================================================================
159 // function : ConstructorsClicked()
160 // purpose  : Radio button management
161 //=================================================================================
162 void BlocksGUI_ExplodeDlg::ConstructorsClicked (int constructorId)
163 {
164   if (myConstructorId == constructorId)
165     return;
166
167   myConstructorId = constructorId;
168
169   switch (constructorId) {
170   case 0:
171     myGrp1->show();
172     mySpinBoxMin->SetValue(6.0);
173     mySpinBoxMax->SetValue(6.0);
174     myCheckBtn->setChecked(FALSE);
175     break;
176   default:
177     break;
178   }
179
180   // init fields
181   myEditCurrentArgument = mySelName;
182   myObject = GEOM::GEOM_Object::_nil();
183
184   activateSelection();
185 }
186
187 //=================================================================================
188 // function : ClickOnOk()
189 // purpose  :
190 //=================================================================================
191 void BlocksGUI_ExplodeDlg::ClickOnOk()
192 {
193   if (ClickOnApply())
194     ClickOnCancel();
195 }
196
197 //=================================================================================
198 // function : ClickOnApply()
199 // purpose  :
200 //=================================================================================
201 bool BlocksGUI_ExplodeDlg::ClickOnApply()
202 {
203   SUIT_Session::session()->activeApplication()->putInfo(tr(""));
204
205   // Explode all sub shapes
206   if (isAllSubShapes()) {
207     // More than 30 subshapes : ask confirmation
208     if (myNbBlocks > 30) {
209       const QString caption = tr("GEOM_CONFIRM");
210       const QString text = tr("GEOM_CONFIRM_INFO").arg(myNbBlocks);
211       const QString button0 = tr("GEOM_BUT_EXPLODE");
212       const QString button1 = tr("GEOM_BUT_CANCEL");
213
214       if (QMessageBox::warning(this, caption, text, button0, button1) != 0)
215         return false;  /* aborted */
216     }
217   }
218
219   if (!onAccept())
220     return false;
221
222   activateSelection();
223
224   return true;
225 }
226
227 //=================================================================================
228 // function : SelectionIntoArgument()
229 // purpose  : Called when selection has changed
230 //=================================================================================
231 void BlocksGUI_ExplodeDlg::SelectionIntoArgument()
232 {
233   if (!isAllSubShapes())
234     return;
235
236   myObject = GEOM::GEOM_Object::_nil();
237   mySelName->setText("");
238
239   if (IObjectCount() == 1) {
240     Standard_Boolean aResult = Standard_False;
241     GEOM::GEOM_Object_var anObj =
242       GEOMBase::ConvertIOinGEOMObject(firstIObject(), aResult);
243
244     if ( aResult && !anObj->_is_nil() && GEOMBase::IsShape( anObj ) ) {
245       myObject = anObj;
246       mySelName->setText(GEOMBase::GetName(anObj));
247     }
248   }
249
250   updateButtonState();
251 }
252
253 //=================================================================================
254 // function : SetEditCurrentArgument()
255 // purpose  :
256 //=================================================================================
257 void BlocksGUI_ExplodeDlg::SetEditCurrentArgument()
258 {
259   QPushButton* aSender = (QPushButton*)sender();
260
261   if (mySelBtn == aSender) {
262     mySelName->setFocus();
263     myEditCurrentArgument = mySelName;
264     myCheckBtn->setChecked(FALSE);
265   }
266
267   activateSelection();
268 }
269
270 //=================================================================================
271 // function : ActivateThisDialog()
272 // purpose  :
273 //=================================================================================
274 void BlocksGUI_ExplodeDlg::ActivateThisDialog()
275 {
276   GEOMBase_Skeleton::ActivateThisDialog();
277   connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(), 
278           SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())) ;
279
280   activateSelection();
281 }
282
283 //=================================================================================
284 // function : enterEvent()
285 // purpose  :
286 //=================================================================================
287 void BlocksGUI_ExplodeDlg::enterEvent (QEvent* e)
288 {
289   if (!GroupConstructors->isEnabled())
290     this->ActivateThisDialog();
291 }
292
293 //=================================================================================
294 // function : ValueChangedInSpinBox()
295 // purpose  :
296 //=================================================================================
297 void BlocksGUI_ExplodeDlg::ValueChangedInSpinBox (double newValue)
298 {
299   if (!isAllSubShapes())
300     activateSelection();
301   else
302     updateButtonState();
303 }
304
305 //=================================================================================
306 // function : SubShapeToggled()
307 // purpose  : Allow user selection of all or only selected sub shapes
308 //          : Called when 'myCheckBtn' state change
309 //=================================================================================
310 void BlocksGUI_ExplodeDlg::SubShapeToggled()
311 {
312   activateSelection();
313 }
314
315 //=================================================================================
316 // function : activateSelection
317 // purpose  : Redisplay preview and Activate selection
318 //=================================================================================
319 void BlocksGUI_ExplodeDlg::activateSelection()
320 {
321   clearTemporary();
322   erasePreview(true);
323
324   if (isAllSubShapes()) { // Sub-shapes selection disabled
325     disconnect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(), 
326                SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())) ;
327     globalSelection( GEOM_ALLSHAPES );
328     if (myObject->_is_nil()) {
329       SelectionIntoArgument();
330     }
331     connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(), 
332             SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())) ;
333   } else {
334     displayPreview(true, true, false);
335     globalSelection(GEOM_PREVIEW);
336   }
337 }
338
339 //=================================================================================
340 // function : updateButtonState
341 // purpose  :
342 //=================================================================================
343 void BlocksGUI_ExplodeDlg::updateButtonState()
344 {
345   if (SUIT_Session::session()->activeApplication()->desktop()->activeWindow()->getViewManager()->getType() 
346       != OCCViewer_Viewer::Type() || myObject->_is_nil()) {
347     myCheckBtn->setChecked(FALSE);
348     myCheckBtn->setEnabled(FALSE);
349   } else {
350     myCheckBtn->setEnabled(TRUE);
351   }
352
353   myNbBlocks = 0;
354
355   if (myObject->_is_nil()) {
356     myBlocksNb->setText("");
357   } else {
358     bool isOnlyBlocks = GEOM::GEOM_IBlocksOperations::_narrow
359       (getOperation())->IsCompoundOfBlocks(myObject,
360                                            (int)mySpinBoxMin->GetValue(),
361                                            (int)mySpinBoxMax->GetValue(),
362                                            myNbBlocks);
363     if (isOnlyBlocks)
364       myBlocksNb->setText(tr("GEOM_NB_BLOCKS_NO_OTHERS").arg(myNbBlocks));
365     else
366       myBlocksNb->setText(tr("GEOM_NB_BLOCKS_SOME_OTHERS").arg(myNbBlocks));
367   }
368 }
369
370 //=================================================================================
371 // function : isAllSubShapes
372 // purpose  :
373 //=================================================================================
374 bool BlocksGUI_ExplodeDlg::isAllSubShapes() const
375 {
376   return !myCheckBtn->isChecked() || !myCheckBtn->isEnabled();
377 }
378
379 //=================================================================================
380 // function : createOperation
381 // purpose  :
382 //=================================================================================
383 GEOM::GEOM_IOperations_ptr BlocksGUI_ExplodeDlg::createOperation()
384 {
385   return getGeomEngine()->GetIBlocksOperations(getStudyId());
386 }
387
388 //=================================================================================
389 // function : isValid()
390 // purpose  : Verify validity of input data
391 //=================================================================================
392 bool BlocksGUI_ExplodeDlg::isValid (QString&)
393 {
394   switch (getConstructorId()) {
395   case 0:
396     if (IsPreview())
397       return !myObject->_is_nil();
398     else
399       return !myObject->_is_nil() && (isAllSubShapes() || IObjectCount());
400   default:
401     return false;
402   }
403
404   return false;
405 }
406
407 //=================================================================================
408 // function : execute
409 // purpose  :
410 //=================================================================================
411 bool BlocksGUI_ExplodeDlg::execute (ObjectList& objects)
412 {
413   GEOM::ListOfGO_var aList;
414
415   switch (getConstructorId()) {
416     case 0:
417       aList = GEOM::GEOM_IBlocksOperations::_narrow(getOperation())->ExplodeCompoundOfBlocks
418         (myObject,
419          (int)mySpinBoxMin->GetValue(),
420          (int)mySpinBoxMax->GetValue());
421       break;
422   }
423
424   if (!aList->length())
425     return false;
426
427   if (IsPreview()) {
428     clearTemporary();
429
430     // Store objects. They will be put in study when "Apply" is pressed
431     for (int i = 0, n = aList->length(); i < n; i++) {
432       objects.push_back(GEOM::GEOM_Object::_duplicate(aList[i]));
433       myTmpObjs.push_back(GEOM::GEOM_Object::_duplicate(aList[i]));
434     }
435
436     return objects.size() ? true : false;
437   }
438
439   // Throw away sub-shapes not selected by user if not in preview mode
440   // and manual selection is active
441   if (!isAllSubShapes())
442   {
443     QMap<QString, char> selected;
444
445     // Get names of selected objects
446     SALOME_ListIteratorOfListIO it (selectedIO());
447     for (; it.More(); it.Next()) {
448       selected.insert(it.Value()->getName(), 0);
449     }
450
451     // Iterate through result and select objects with names from selection
452     ObjectList toRemoveFromEnggine;
453     ObjectList::iterator anIter;
454     for (anIter = myTmpObjs.begin(); anIter != myTmpObjs.end(); ++anIter) {
455       if (selected.contains(myGeomGUI->getApp()->orb()->object_to_string(*anIter)))
456         objects.push_back(*anIter);
457       else
458         toRemoveFromEnggine.push_back(*anIter);
459     }
460
461     // Remove from engine useless objects
462     ObjectList::iterator anIter2 = toRemoveFromEnggine.begin();
463     for (; anIter2 != toRemoveFromEnggine.end(); ++anIter2)
464       getGeomEngine()->RemoveObject(*anIter2);
465
466     myTmpObjs.clear();
467
468   } else {
469     for (int i = 0, n = aList->length(); i < n; i++)
470       objects.push_back(GEOM::GEOM_Object::_duplicate(aList[i]));
471   }
472
473   return objects.size();
474 }
475
476 //=================================================================================
477 // function : clearTemporary
478 // purpose  : Remove temporary objects from engine
479 //=================================================================================
480 void BlocksGUI_ExplodeDlg::clearTemporary()
481 {
482   ObjectList::iterator anIter;
483   for (anIter = myTmpObjs.begin(); anIter != myTmpObjs.end(); ++anIter)
484     getGeomEngine()->RemoveObject(*anIter);
485
486   myTmpObjs.clear();
487 }
488
489 //================================================================
490 // Function : getFather
491 // Purpose  : Get father object for object to be added in study
492 //            ( called with addInStudy method )
493 //================================================================
494 GEOM::GEOM_Object_ptr BlocksGUI_ExplodeDlg::getFather (GEOM::GEOM_Object_ptr)
495 {
496   return myObject;
497 }
498
499 //================================================================
500 // Function : getNewObjectName
501 // Purpose  : Redefine this method to return proper name for a new object
502 //================================================================
503 const char* BlocksGUI_ExplodeDlg::getNewObjectName() const
504 {
505   return "";
506 }