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