]> SALOME platform Git repositories - modules/geom.git/blob - src/EntityGUI/EntityGUI_SubShapeDlg.cxx
Salome HOME
598d05de696a15242499b921f372e42b8046f7ea
[modules/geom.git] / src / EntityGUI / EntityGUI_SubShapeDlg.cxx
1 // Copyright (C) 2007-2015  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, or (at your option) any later version.
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   : EntityGUI_SubShapeDlg.cxx
25 // Author : Lucien PIGNOLONI, Open CASCADE S.A.S.
26
27 #include "EntityGUI_SubShapeDlg.h"
28
29 #include <DlgRef.h>
30 #include <GeometryGUI.h>
31 #include <GEOMBase.h>
32 #include <GEOMUtils.hxx>
33 #include <MeasureGUI_ShapeStatisticsDlg.h>
34
35 #include <OCCViewer_ViewModel.h>
36 #include <SVTK_ViewModel.h>
37 #include <SalomeApp_Study.h>
38 #include <SalomeApp_Application.h>
39 #include <LightApp_SelectionMgr.h>
40 #include <SALOME_ListIO.hxx>
41 #include <SUIT_MessageBox.h>
42
43 #include <SUIT_Desktop.h>
44 #include <SUIT_ResourceMgr.h>
45 #include <SUIT_Session.h>
46 #include <SUIT_ViewManager.h>
47 #include <SUIT_ViewWindow.h>
48
49 #include <TopExp.hxx>
50 #include <TopExp_Explorer.hxx>
51 #include <TopoDS_Iterator.hxx>
52 #include <TopTools_MapOfShape.hxx>
53 #include <TopTools_IndexedMapOfShape.hxx>
54
55 #include <TColStd_IndexedMapOfInteger.hxx>
56
57 #include <GEOMImpl_Types.hxx>
58
59 namespace
60 {
61   const char* const ShapeTypes [] = {
62     "Compound",
63     "Compsolid",
64     "Solid",
65     "Shell",
66     "Face",
67     "Wire",
68     "Edge",
69     "Vertex",
70     "Shape",
71     "Flat"
72   };
73
74   enum { Filter_LT, Filter_LE, Filter_GT, Filter_GE };
75
76   unsigned int NumberOfSubShapes(const TopoDS_Shape& S, const int shapeType, TopTools_MapOfShape& M)
77   {
78     unsigned int index = 0;
79
80     if (!S.IsNull()) {
81       if (S.ShapeType() == TopAbs_COMPOUND &&
82           (shapeType == TopAbs_SHAPE || shapeType == TopAbs_FLAT || shapeType == TopAbs_COMPOUND)) {
83         TopoDS_Iterator It(S, Standard_True, Standard_True);
84         for (; It.More(); It.Next()) {
85           TopoDS_Shape SS = It.Value();
86           if (M.Add(SS)) {
87             if (shapeType == TopAbs_FLAT) {
88               if (SS.ShapeType() != TopAbs_COMPOUND)
89                 index++;
90               else
91                 index += NumberOfSubShapes(SS, shapeType, M);
92             }
93             else if (shapeType == TopAbs_SHAPE || shapeType == SS.ShapeType()) {
94               index++;
95             }
96           }
97         }
98       }
99       else {
100         TopExp_Explorer Exp (S, TopAbs_ShapeEnum(shapeType));
101         for (; Exp.More(); Exp.Next()) {
102           if (M.Add(Exp.Current())) {
103             index++;
104           }
105         }
106       }
107     }
108     return index;
109   }
110   unsigned int NumberOfSubShapes(const TopoDS_Shape& S, const int shapeType)
111   {
112     TopTools_MapOfShape M;
113     return NumberOfSubShapes(S, shapeType, M);
114   }
115 }
116
117 //=================================================================================
118 // class    : EntityGUI_SubShapeDlg
119 // purpose  : Constructs a EntityGUI_SubShapeDlg which is a child of 'parent', with the
120 //            name 'name' and widget flags set to 'f'.
121 //            The dialog will by default be modeless, unless you set 'modal' to
122 //            TRUE to construct a modal dialog.
123 //=================================================================================
124 EntityGUI_SubShapeDlg::EntityGUI_SubShapeDlg(GeometryGUI* theGeometryGUI, QWidget* parent,
125                                               bool modal, Qt::WindowFlags fl)
126   : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl),
127     myDmMode( -1 ),
128     myIsHiddenMain(false)
129 {
130   QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_SUBSHAPE")));
131   QPixmap image1(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
132
133   setWindowTitle(tr("GEOM_SUBSHAPE_TITLE"));
134
135   /***************************************************************/
136   mainFrame()->GroupConstructors->setTitle(tr("GEOM_SUB_SHAPE"));
137   mainFrame()->RadioButton1->setIcon(image0);
138   mainFrame()->RadioButton2->setAttribute(Qt::WA_DeleteOnClose);
139   mainFrame()->RadioButton2->close();
140   mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose);
141   mainFrame()->RadioButton3->close();
142
143   GroupPoints = new DlgRef_1Sel1List1Check3Btn(centralWidget());
144
145   GroupPoints->GroupBox1->setTitle(tr("GEOM_ARGUMENTS"));
146   GroupPoints->TextLabel1->setText(tr("GEOM_MAIN_OBJECT"));
147   GroupPoints->TextLabel2->setText(tr("GEOM_SUBSHAPE_TYPE"));
148   GroupPoints->CheckButton1->setText(tr("GEOM_SUBSHAPE_SELECT"));
149   GroupPoints->PushButton1->setIcon(image1);
150   GroupPoints->PushButton2->setText(tr("SHOW_ONLY_SELECTED"));
151   GroupPoints->PushButton3->setText(tr("HIDE_SELECTED"));
152   GroupPoints->PushButton4->setText(tr("SHOW_ALL_SUB_SHAPES"));
153   GroupPoints->LineEdit1->setReadOnly(true);
154
155   //filter group
156
157   myFilterGrp = new QGroupBox(tr("GEOM_FILTER"), centralWidget());
158   myLessFilterCheck = new QCheckBox(myFilterGrp);
159   myLessFilterCombo = new QComboBox(myFilterGrp);
160   myLessFilterCombo->addItem( tr("GEOM_LESS_THAN"), Filter_LT );
161   myLessFilterCombo->addItem( tr("GEOM_LESSOREQUAL_THAN"), Filter_LE );
162   myGreaterFilterCheck = new QCheckBox(myFilterGrp);
163   myGreaterFilterCombo = new QComboBox(myFilterGrp);
164   myGreaterFilterCombo->addItem( tr("GEOM_GREAT_THAN"), Filter_GT );
165   myGreaterFilterCombo->addItem( tr("GEOM_GREATOREQUAL_THAN"), Filter_GE );
166   myLessFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp);
167   myGreaterFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp);
168   myApplyFilterButton = new QPushButton(tr("GEOM_BUT_APPLY"), myFilterGrp);
169   myPlotDistributionButton = new QPushButton(tr("GEOM_PLOT_DISTRIBUTION"), myFilterGrp);
170
171   QGridLayout* filterLayout = new QGridLayout(myFilterGrp);
172   filterLayout->addWidget(myLessFilterCheck,    0, 0);
173   filterLayout->addWidget(myLessFilterCombo,    0, 1);
174   filterLayout->addWidget(myLessFilterSpin,     0, 2);
175   filterLayout->addWidget(myGreaterFilterCheck, 1, 0);
176   filterLayout->addWidget(myGreaterFilterCombo, 1, 1);
177   filterLayout->addWidget(myGreaterFilterSpin,  1, 2);
178   filterLayout->addWidget(myApplyFilterButton,  0, 3);
179   filterLayout->addWidget(myPlotDistributionButton,  1, 3);
180
181   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
182   layout->setMargin(0); layout->setSpacing(6);
183   layout->addWidget(GroupPoints);
184   layout->addWidget(myFilterGrp);
185   /***************************************************************/
186
187   setIsOptimizedBrowsing(true);
188
189   setHelpFileName("create_explode_page.html");
190
191   mainFrame()->GroupBoxName->hide();
192
193   Init();
194 }
195
196 //=================================================================================
197 // function : ~EntityGUI_SubShapeDlg()
198 // purpose  : Destroys the object and frees any allocated resources
199 //=================================================================================
200 EntityGUI_SubShapeDlg::~EntityGUI_SubShapeDlg()
201 {
202   if (myIsHiddenMain) {
203     GEOM_Displayer* aDisplayer = getDisplayer();
204     aDisplayer->Display(myObject);
205     myIsHiddenMain = false;
206   }
207   myDmMode = -1;
208 }
209
210 //=================================================================================
211 // function : Init()
212 // purpose  :
213 //=================================================================================
214 void EntityGUI_SubShapeDlg::Init()
215 {
216   // Get setting of step value from file configuration
217   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
218   double step = resMgr->doubleValue("Geometry", "SettingsGeomStep", 100);
219
220   // min, max, step and decimals for spin boxes
221   initSpinBox(myLessFilterSpin, 0., COORD_MAX, step, "length_precision" );
222   initSpinBox(myGreaterFilterSpin, 0., COORD_MAX, step, "length_precision" );
223   myLessFilterSpin->setValue( 0. );
224   myGreaterFilterSpin->setValue( 0. );
225
226   /* init variables */
227   myDmMode = -1;
228   myEditCurrentArgument = GroupPoints->LineEdit1;
229   myObject = GEOM::GEOM_Object::_nil();
230
231   /* type for sub-shape selection */
232   for ( int i = 0; i <= (int)GEOM::FLAT; i++ )
233     GroupPoints->ComboBox1->addItem(ShapeTypes[i], i);
234
235   if (SUIT_Session::session()->activeApplication()->desktop()->activeWindow()->getViewManager()->getType()
236       != OCCViewer_Viewer::Type())
237     GroupPoints->CheckButton1->setEnabled(false);
238
239   /* signals and slots connections */
240   connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
241
242   connect(buttonOk(),    SIGNAL(clicked()), this, SLOT(ClickOnOk()));
243   connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
244
245   connect(GroupPoints->PushButton1,  SIGNAL(clicked()),       this, SLOT(SetEditCurrentArgument()));
246   connect(GroupPoints->LineEdit1,    SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
247
248   connect(GroupPoints->ComboBox1,    SIGNAL(activated(int)),    this, SLOT(ComboTextChanged()));
249   connect(GroupPoints->CheckButton1, SIGNAL(stateChanged(int)), this, SLOT(SubShapeToggled()));
250
251   connect(GroupPoints->PushButton2, SIGNAL(clicked()), this, SLOT(showOnlySelected()));
252   connect(GroupPoints->PushButton3, SIGNAL(clicked()), this, SLOT(showOnlySelected()));
253   connect(GroupPoints->PushButton4, SIGNAL(clicked()), this, SLOT(showOnlySelected()));
254
255   connect(myApplyFilterButton, SIGNAL(clicked()),         this, SLOT(ClickOnOkFilter()));
256   connect(myPlotDistributionButton, SIGNAL(clicked()),    this, SLOT(ClickOnPlot()));
257   connect(myLessFilterCheck,   SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled()));
258   connect(myGreaterFilterCheck,   SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled()));
259
260   connect(myGeomGUI->getApp()->selectionMgr(),
261           SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
262
263   updateButtonState();
264   resize(100,100);
265   SelectionIntoArgument();
266   SubShapeToggled();
267   MeasureToggled();
268 }
269
270 //=================================================================================
271 // function : enterEvent()
272 // purpose  :
273 //=================================================================================
274 void EntityGUI_SubShapeDlg::enterEvent(QEvent*)
275 {
276   if (!mainFrame()->GroupConstructors->isEnabled())
277     ActivateThisDialog();
278 }
279
280 //=================================================================================
281 // function : ActivateThisDialog()
282 // purpose  :
283 //=================================================================================
284 void EntityGUI_SubShapeDlg::ActivateThisDialog()
285 {
286   GEOMBase_Skeleton::ActivateThisDialog();
287   connect(myGeomGUI->getApp()->selectionMgr(),
288            SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
289   SubShapeToggled();
290   updateButtonState();
291 }
292
293 //=================================================================================
294 //function : closeEvent
295 //purpose  : remove temporary geom object
296 //=================================================================================
297 void EntityGUI_SubShapeDlg::closeEvent(QCloseEvent* e)
298 {
299   erasePreview(true);
300   GEOMBase_Skeleton::closeEvent(e);
301 }
302
303 //=================================================================================
304 // function : ClickOnOk()
305 // purpose  :
306 //=================================================================================
307 void EntityGUI_SubShapeDlg::ClickOnOk()
308 {
309   setIsApplyAndClose(true);
310
311   SUIT_Session::session()->activeApplication()->putInfo("");
312
313   /* Explode all sub-shapes */
314   bool isOk = true;
315   if (isAllSubShapes()) {
316     /* More than 30 sub-shapes : ask confirmation */
317     unsigned int nb = NumberOfSubShapes(myShape, shapeType());
318     if (nb > 30) {
319       if (SUIT_MessageBox::question( this,
320                                      tr("GEOM_CONFIRM"),
321                                      tr("GEOM_CONFIRM_INFO").arg(nb),
322                                      tr("GEOM_BUT_EXPLODE"),
323                                      tr("GEOM_BUT_CANCEL") ) != 0 )
324         isOk = false;  /* aborted */
325     }
326   }
327
328   if (isOk)
329     isOk = onAccept();
330
331   if (isOk)
332     ClickOnCancel();
333 }
334
335 //=================================================================================
336 // function : ClickOnApply()
337 // purpose  :
338 //=================================================================================
339 bool EntityGUI_SubShapeDlg::ClickOnApply()
340 {
341   SUIT_Session::session()->activeApplication()->putInfo("");
342
343   /* Explode all sub-shapes */
344   if (isAllSubShapes()) {
345     /* More than 30 sub-shapes : ask confirmation */
346     unsigned int nb = NumberOfSubShapes(myShape, shapeType());
347     if (nb > 30) {
348       if (SUIT_MessageBox::question( this,
349                                      tr("GEOM_CONFIRM"),
350                                      tr("GEOM_CONFIRM_INFO").arg(nb),
351                                      tr("GEOM_BUT_EXPLODE"),
352                                      tr("GEOM_BUT_CANCEL") ) != 0 )
353         return false;  /* aborted */
354     }
355   }
356   
357   setIsDisableBrowsing( true );
358   bool isOk = onAccept( true, true, false );
359   setIsDisableBrowsing( false );
360
361   // restore selection, corresponding to current selection mode
362   SubShapeToggled();
363
364   return isOk;
365 }
366
367 //=================================================================================
368 // function : SelectionIntoArgument()
369 // purpose  : Called when selection has changed or other case
370 //=================================================================================
371 void EntityGUI_SubShapeDlg::SelectionIntoArgument()
372 {
373   if (!isAllSubShapes())
374     return;
375
376   int currentType = GroupPoints->ComboBox1->itemData( GroupPoints->ComboBox1->currentIndex() ).toInt();
377
378   ResetStateOfDialog();
379
380   QString aString = ""; /* name of selection */
381
382   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
383   SALOME_ListIO aSelList;
384   aSelMgr->selectedObjects(aSelList);
385
386   int nbSel = GEOMBase::GetNameOfSelectedIObjects(aSelList, aString, true);
387   if (nbSel == 1) {
388     Handle(SALOME_InteractiveObject) IO = aSelList.First();
389     if (!IO->hasEntry()) {
390       SUIT_Session::session()->activeApplication()->putInfo(tr("GEOM_PRP_SHAPE_IN_STUDY"));
391     }
392     else {
393       TopoDS_Shape S = GEOMBase::GetTopoFromSelection(aSelList);
394       if (S.IsNull() || S.ShapeType() == TopAbs_VERTEX) {
395         myObject = GEOM::GEOM_Object::_nil();
396       }
397       else {
398         myObject = GEOMBase::ConvertIOinGEOMObject(IO);
399         if (!CORBA::is_nil(myObject)) {
400           myShape = S;
401           GroupPoints->LineEdit1->setText(aString);
402           int i = 0;
403           // Solving PAL5590
404           if (myShape.ShapeType() == TopAbs_COMPOUND) {
405             unsigned int nb = NumberOfSubShapes(myShape, TopAbs_COMPOUND);
406             if (nb > 0)
407               i++;
408           }
409           while (i <= myShape.ShapeType()) {
410             GroupPoints->ComboBox1->removeItem(0);
411             i++;
412           }
413           // remove Shape and Flat types for non-compound shapes
414           if (myShape.ShapeType() != TopAbs_COMPOUND) {
415             int idx = GroupPoints->ComboBox1->findData( (int)GEOM::SHAPE );
416             if ( idx != -1 ) GroupPoints->ComboBox1->removeItem( idx );
417             idx = GroupPoints->ComboBox1->findData( (int)GEOM::FLAT );
418             if ( idx != -1 ) GroupPoints->ComboBox1->removeItem( idx );
419           } // if (myShape.ShapeType() != TopAbs_COMPOUND)
420         } // if (!CORBA::is_nil(myObject))
421       } // if (S.IsNull() || S.ShapeType() == TopAbs_VERTEX)
422     } // if (!IO->hasEntry()) ... else
423   } // if (nbSel == 1)
424
425   int idx = GroupPoints->ComboBox1->findData( currentType );
426   if ( idx != -1 )
427     GroupPoints->ComboBox1->setCurrentIndex( idx );
428
429   updateButtonState();
430 }
431
432 //=================================================================================
433 // function : SetEditCurrentArgument()
434 // purpose  :
435 //=================================================================================
436 void EntityGUI_SubShapeDlg::SetEditCurrentArgument()
437 {
438   GroupPoints->LineEdit1->setFocus();
439   myEditCurrentArgument = GroupPoints->LineEdit1;
440
441   GroupPoints->CheckButton1->setChecked(false);
442   SubShapeToggled();
443   SelectionIntoArgument();
444 }
445
446 //=================================================================================
447 // function : LineEditReturnPressed()
448 // purpose  :
449 //=================================================================================
450 void EntityGUI_SubShapeDlg::LineEditReturnPressed()
451 {
452   QLineEdit* send = (QLineEdit*)sender();
453   if (send == GroupPoints->LineEdit1)
454     SetEditCurrentArgument();
455   else
456     return;
457
458   GEOMBase_Skeleton::LineEditReturnPressed();
459 }
460
461 //=================================================================================
462 // function : ResetStateOfDialog()
463 // purpose  : Completely reset the state of method including local context
464 //=================================================================================
465 void EntityGUI_SubShapeDlg::ResetStateOfDialog()
466 {
467   if (myIsHiddenMain) {
468     GEOM_Displayer* aDisplayer = getDisplayer();
469     aDisplayer->Display(myObject);
470     myIsHiddenMain = false;
471   }
472   myObject = GEOM::GEOM_Object::_nil();
473   myShape.Nullify();
474   myEditCurrentArgument->setText("");
475
476   /* type for sub-shape selection */
477   GroupPoints->ComboBox1->clear();
478   for ( int i = 0; i <= (int)GEOM::FLAT; i++ )
479     GroupPoints->ComboBox1->addItem(ShapeTypes[i], i);
480
481   updateButtonState();
482 }
483
484 //=================================================================================
485 // function : SubShapeToggled()
486 // purpose  : Allow user selection of all or only selected sub-shapes
487 //          : Called when 'CheckButton1' state change
488 //=================================================================================
489 void EntityGUI_SubShapeDlg::SubShapeToggled()
490 {
491   GroupPoints->PushButton2->setEnabled(!isAllSubShapes());
492   GroupPoints->PushButton3->setEnabled(!isAllSubShapes());
493   GroupPoints->PushButton4->setEnabled(!isAllSubShapes());
494   myFilterGrp->setEnabled(GroupPoints->CheckButton1->isEnabled() &&
495                           GroupPoints->CheckButton1->isChecked() &&
496                           shapeType() < GEOM::VERTEX);
497
498   myPlotDistributionButton->setEnabled( myFilterGrp->isEnabled() &&
499                                         ( shapeType() == TopAbs_EDGE || 
500                                           shapeType() == TopAbs_FACE ||
501                                           shapeType() == TopAbs_SOLID ) );
502
503   activateSelection();
504 }
505
506 //=================================================================================
507 // function : ComboTextChanged()
508 // purpose  :
509 //=================================================================================
510 void EntityGUI_SubShapeDlg::ComboTextChanged()
511 {
512   /* Select sub-shapes mode not checked */
513   updateButtonState();
514   SubShapeToggled();
515 }
516
517 //=================================================================================
518 // function : updateButtonState
519 // purpose  :
520 //=================================================================================
521 void EntityGUI_SubShapeDlg::updateButtonState()
522 {
523   bool viewOk = SUIT_Session::session()->activeApplication()->desktop()->activeWindow()->getViewManager()->getType() == OCCViewer_Viewer::Type();
524   bool shapeTypeOk = shapeType() != TopAbs_SHAPE && shapeType() != TopAbs_FLAT && shapeType() != TopAbs_COMPOUND;
525   bool objectOK = !CORBA::is_nil( myObject );
526
527   if ( viewOk && objectOK && shapeTypeOk ) {
528     GroupPoints->CheckButton1->setEnabled( true );
529   }
530   else {
531     GroupPoints->CheckButton1->setChecked( false );
532     GroupPoints->CheckButton1->setEnabled( false );
533   }
534   myFilterGrp->setEnabled(GroupPoints->CheckButton1->isEnabled() && GroupPoints->CheckButton1->isChecked());
535 }
536
537 //=================================================================================
538 // function : isAllSubShapes
539 // purpose  :
540 //=================================================================================
541 bool EntityGUI_SubShapeDlg::isAllSubShapes() const
542 {
543   return !GroupPoints->CheckButton1->isEnabled() || !GroupPoints->CheckButton1->isChecked();
544 }
545
546 //=================================================================================
547 // function : shapeType
548 // purpose  :
549 //=================================================================================
550 int EntityGUI_SubShapeDlg::shapeType() const
551 {
552   return GroupPoints->ComboBox1->itemData(GroupPoints->ComboBox1->currentIndex()).toInt();
553 }
554
555 //=================================================================================
556 // function : showOnlySelected
557 // purpose  :
558 //=================================================================================
559 void EntityGUI_SubShapeDlg::showOnlySelected()
560 {
561   if (CORBA::is_nil(myObject) || isAllSubShapes())
562     return;
563
564   QPushButton* send = (QPushButton*)sender();
565   if (send == GroupPoints->PushButton4) {
566     activateSelection();
567     return;
568   }
569
570   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
571   SALOME_ListIO aSelList;
572   aSelMgr->selectedObjects(aSelList);
573
574   GEOM_Displayer* aDisplayer = getDisplayer();
575
576   if (send == GroupPoints->PushButton3) {
577     aDisplayer->Erase(aSelList, /*forced=*/false, /*updateViewer=*/true);
578   }
579   else {
580     // Mantis issue 0021421: do not hide main shape, if explode on VERTEX
581     SALOME_View* view = GEOM_Displayer::GetActiveView();
582     if (view) {
583       CORBA::String_var aMainEntry = myObject->GetStudyEntry();
584       Handle(SALOME_InteractiveObject) io =
585         new SALOME_InteractiveObject (aMainEntry.in(), "GEOM", "TEMP_IO");
586       if (view->isVisible(io)) myIsHiddenMain = true;
587
588       //keep the selected entry and IO in the map for checking
589       std::map<QString, Handle(SALOME_InteractiveObject)> aSelEntriesMap;
590       SALOME_ListIteratorOfListIO aSelIt(aSelList);
591       for ( ; aSelIt.More(); aSelIt.Next() ) {
592         //fill map <entry, io>
593         Handle(SALOME_InteractiveObject) anSelIO = aSelIt.Value();
594         aSelEntriesMap[anSelIO->getEntry()] = anSelIO;
595       }
596       //get the displayed sub-shapes
597       SALOME_ListIO displayed;
598       view->GetVisible(displayed);
599       // Erase all, except the selected shapes
600       std::map<QString, Handle(SALOME_InteractiveObject)>::iterator 
601         aSelDispIter = aSelEntriesMap.end();
602       SALOME_ListIteratorOfListIO aDispIt( displayed );
603       for ( ; aDispIt.More(); aDispIt.Next() ) {
604         Handle(SALOME_InteractiveObject) anIO = aDispIt.Value();
605         aSelDispIter = aSelEntriesMap.find( anIO->getEntry() );
606         if ( aSelDispIter != aSelEntriesMap.end() ) {
607           //sub-shape is selected, so erase it's record from map to keep in it not displayed, but selected sub-shapes only
608           aSelEntriesMap.erase(aSelDispIter);
609         } else {
610           //sub-shape is not in the map of selected, then erase it from view
611           aDisplayer->Erase( anIO, /*forced = */false, /*updateViewer = */false );
612         }
613       }
614       
615       if ( !aSelEntriesMap.empty() ) {
616         // Build a presentation of the selected, but not displayed sub-shapes
617         TopTools_IndexedMapOfShape aSubShapesMap;
618         TopExp::MapShapes(myShape, aSubShapesMap);
619         QString anEntryBase = aMainEntry.in();
620
621         TopExp_Explorer anExp (myShape, (TopAbs_ShapeEnum)shapeType());
622         for (; anExp.More(); anExp.Next())
623         {
624           TopoDS_Shape aSubShape = anExp.Current();
625           int index = aSubShapesMap.FindIndex(aSubShape);
626           QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index);
627           if ( aSelEntriesMap.find( anEntry ) == aSelEntriesMap.end() ) {
628             //skip not selected sub-shapes
629             continue;
630           }
631           SALOME_Prs* aPrs = aDisplayer->buildSubshapePresentation(aSubShape, anEntry, view);
632           if (aPrs) {
633             displayPreview(aPrs, true, false); // append, do not update
634           }
635         }
636       }
637       aDisplayer->UpdateViewer();
638     }
639
640     // Mantis issue 0021421: do not hide main shape, if explode on VERTEX
641     if ((TopAbs_ShapeEnum)shapeType() == TopAbs_VERTEX && myIsHiddenMain) {
642       aDisplayer->Display(myObject);
643     }
644   }
645 }
646
647 //=================================================================================
648 // function : getSelectedSubshapes
649 // purpose  :
650 //=================================================================================
651 int EntityGUI_SubShapeDlg::getSelectedSubshapes (TColStd_IndexedMapOfInteger& theMapIndex)
652 {
653   theMapIndex.Clear();
654
655   SalomeApp_Application* app = myGeomGUI->getApp();
656   if (!app || myObject->_is_nil())
657     return 0;
658
659   LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
660   SALOME_ListIO aSelList;
661   aSelMgr->selectedObjects(aSelList);
662
663   // try to find out and process the global selection
664   // (of not published objects and of published sub-shapes)
665   {
666     SALOME_ListIteratorOfListIO anIter (aSelList);
667     for (int i = 0; anIter.More(); anIter.Next(), i++)
668     {
669       Handle(SALOME_InteractiveObject) anIObj = anIter.Value();
670       QString anEntry = anIObj->getEntry();
671       QString str = "_";
672       int index = anEntry.lastIndexOf(str);
673       if (index > 0) // selection among special preview
674       {
675         anEntry.remove(0, index+1);
676         int anIndex = anEntry.toInt();
677         if (anIndex)
678           theMapIndex.Add(anIndex);
679       }
680       else // selection among published shapes
681       {
682         SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
683         if (!appStudy) return 0;
684         _PTR(Study) aStudy = appStudy->studyDS();
685
686         _PTR(SObject) aSObj (aStudy->FindObjectID(anEntry.toLatin1().constData()));
687         GEOM::GEOM_Object_var aGeomObj =
688           GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(aSObj));
689         TopoDS_Shape aShape;
690         if (GEOMBase::GetShape(aGeomObj, aShape)) {
691           if (aGeomObj->GetType() == GEOM_GROUP || aShape.ShapeType() == (TopAbs_ShapeEnum)shapeType()) {
692             TopTools_IndexedMapOfShape aMainMap;
693             TopExp::MapShapes(myShape, aMainMap);
694
695             TopExp_Explorer anExp (aShape, (TopAbs_ShapeEnum)shapeType());
696             for (; anExp.More(); anExp.Next()) {
697               TopoDS_Shape aSubShape = anExp.Current();
698               int anIndex = aMainMap.FindIndex(aSubShape);
699               if (anIndex >= 0) {
700                 theMapIndex.Add(anIndex);
701               }
702             }
703           }
704         }
705       }
706     } // for aSelList
707   }
708
709   return theMapIndex.Extent();
710 }
711
712 //=================================================================================
713 // function : activateSelection
714 // purpose  : Activate selection in accordance with myEditCurrentArgument
715 //=================================================================================
716 void EntityGUI_SubShapeDlg::activateSelection()
717 {
718   bool isApply = ((QPushButton*)sender() == buttonApply());
719   
720   if(!isApply)
721     erasePreview(false);
722
723   // local selection
724   if (!myObject->_is_nil() && !isAllSubShapes())
725   {
726     GEOM_Displayer* aDisplayer = getDisplayer();
727
728     //display mode for main shape
729     if ( myDmMode == -1 ) {
730       SALOME_View* view = GEOM_Displayer::GetActiveView();
731       if (view) {
732         CORBA::String_var aMainEntry = myObject->GetStudyEntry();
733         Handle(SALOME_InteractiveObject) io =
734           new SALOME_InteractiveObject (aMainEntry.in(), "GEOM", "TEMP_IO");
735         if ( view->isVisible( io ) ) {
736           Handle(GEOM_AISShape) aSh = GEOMBase::ConvertIOinGEOMAISShape( io, true );
737           if(!aSh.IsNull())
738             myDmMode = aSh->isTopLevel() ? aSh->prevDisplayMode() : aSh->DisplayMode();
739         }
740         else
741           myDmMode = SUIT_Session::session()->resourceMgr()->integerValue( "Geometry", "display_mode" );
742       }
743     }
744     // Mantis issue 0021421: do not hide main shape, if explode on VERTEX
745     if (shapeType() != TopAbs_VERTEX) {
746       aDisplayer->Erase(myObject, false, false);
747       myIsHiddenMain = true;
748     }
749     else
750       aDisplayer->Display(myObject);
751
752     aDisplayer->SetDisplayMode(myDmMode);
753
754     if(!isApply) {
755       SUIT_ViewWindow* aViewWindow = 0;
756       SUIT_Study* activeStudy = SUIT_Session::session()->activeApplication()->activeStudy();
757       if (activeStudy)
758         aViewWindow = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
759       if (aViewWindow == 0) return;
760
761       SUIT_ViewManager* aViewManager = aViewWindow->getViewManager();
762       if (aViewManager->getType() != OCCViewer_Viewer::Type() &&
763           aViewManager->getType() != SVTK_Viewer::Type())
764         return;
765
766       SUIT_ViewModel* aViewModel = aViewManager->getViewModel();
767       SALOME_View* aView = dynamic_cast<SALOME_View*>(aViewModel);
768       if (aView == 0) return;
769
770       //TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myObject);
771
772       TopTools_IndexedMapOfShape aSubShapesMap;
773       TopExp::MapShapes(myShape, aSubShapesMap);
774       CORBA::String_var aMainEntry = myObject->GetStudyEntry();
775       QString anEntryBase = aMainEntry.in();
776
777       TopExp_Explorer anExp (myShape, (TopAbs_ShapeEnum)shapeType());
778       for (; anExp.More(); anExp.Next())
779       {
780         TopoDS_Shape aSubShape = anExp.Current();
781         int index = aSubShapesMap.FindIndex(aSubShape);
782         QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index);
783
784         SALOME_Prs* aPrs = aDisplayer->buildSubshapePresentation(aSubShape, anEntry, aView);
785         if (aPrs) {
786           displayPreview(aPrs, true, false); // append, do not update
787         }
788       }
789       aDisplayer->UnsetDisplayMode();
790       aDisplayer->UpdateViewer();
791     }
792   }
793
794   globalSelection(GEOM_ALLSHAPES);
795 }
796
797 //=================================================================================
798 // function : createOperation
799 // purpose  :
800 //=================================================================================
801 GEOM::GEOM_IOperations_ptr EntityGUI_SubShapeDlg::createOperation()
802 {
803   return getGeomEngine()->GetIShapesOperations(getStudyId());
804 }
805
806 //=================================================================================
807 // function : isValid
808 // purpose  :
809 //=================================================================================
810 bool EntityGUI_SubShapeDlg::isValid (QString& msg)
811 {
812   bool isOk = false;
813
814   if (myObject->_is_nil()) {
815     updateButtonState();
816     return isOk;
817   }
818
819   if (isAllSubShapes())
820     isOk = true;
821   else {
822     TColStd_IndexedMapOfInteger aMapIndex;
823     int nbSel = getSelectedSubshapes(aMapIndex);
824     isOk = nbSel > 0;
825
826     if (!isOk)
827       msg += tr("NO_SUBSHAPES_SELECTED");
828   }
829
830   return isOk;
831 }
832
833 //=================================================================================
834 // function : execute
835 // purpose  :
836 //=================================================================================
837 bool EntityGUI_SubShapeDlg::execute (ObjectList& objects)
838 {
839   GEOM::GEOM_IShapesOperations_var anOper = GEOM::GEOM_IShapesOperations::_narrow(getOperation());
840
841   if (!isAllSubShapes()) {
842     // manual selection
843     TColStd_IndexedMapOfInteger aMapIndex;
844     int nbSel = getSelectedSubshapes(aMapIndex);
845
846     if (nbSel > 0) {
847       int i;
848
849       GEOM::ListOfLong_var anArray = new GEOM::ListOfLong;
850       anArray->length(nbSel);
851
852       for (i = 1; i <= nbSel; i++)
853         anArray[i - 1] = aMapIndex.FindKey(i);
854
855       GEOM::ListOfGO_var aList = anOper->MakeSubShapes(myObject, anArray);
856       int n = aList->length();
857       for (i = 0; i < n; i++)
858         objects.push_back(GEOM::GEOM_Object::_duplicate(aList[i]));
859     }
860   }
861   else {
862     GEOM::ListOfGO_var aList = anOper->ExtractSubShapes(myObject, shapeType(), true);
863     if (!aList->length())
864       return false;
865     for (int i = 0, n = aList->length(); i < n; i++)
866       objects.push_back(GEOM::GEOM_Object::_duplicate(aList[i]));
867   }
868
869   return objects.size();
870 }
871
872 //================================================================
873 // Function : getFather
874 // Purpose  : Get father object for object to be added in study
875 //            (called with addInStudy method)
876 //================================================================
877 GEOM::GEOM_Object_ptr EntityGUI_SubShapeDlg::getFather(GEOM::GEOM_Object_ptr)
878 {
879   return myObject;
880 }
881
882 //================================================================
883 // Function : getNewObjectName
884 // Purpose  :
885 //================================================================
886 QString EntityGUI_SubShapeDlg::getNewObjectName (int) const
887 {
888   return QString::null;
889 }
890
891 //=================================================================================
892 // function : ClickOnOkFilter()
893 // purpose  : highlight and select entities which parameters (length, area or volume) are less than the value specified by the user
894 //=================================================================================
895 void EntityGUI_SubShapeDlg::ClickOnOkFilter()
896 {
897   if (CORBA::is_nil(myObject) || isAllSubShapes() || shapeType() >= GEOM::VERTEX)
898     return;
899   
900   TopTools_IndexedMapOfShape aSubShapesMap;
901   TopExp::MapShapes(myShape, aSubShapesMap);
902   SALOME_View* view = GEOM_Displayer::GetActiveView();
903   getDisplayer()->Erase(myObject, false, false);
904   CORBA::String_var aMainEntry = myObject->GetStudyEntry();
905   QString anEntryBase = aMainEntry.in();
906
907   SALOME_ListIO toSelect;
908
909   TopExp_Explorer anExp (myShape, (TopAbs_ShapeEnum)shapeType());
910   for (; anExp.More(); anExp.Next())
911   {
912     TopoDS_Shape aSubShape = anExp.Current();
913     int index = aSubShapesMap.FindIndex(aSubShape);
914     QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index);
915     if ( !getDisplayer()->IsDisplayed( anEntry ) )
916       continue;
917
918     double factor = GEOMUtils::ShapeToDouble(aSubShape).second;
919     double v1 = myLessFilterSpin->value();
920     double v2 = myGreaterFilterSpin->value();
921     bool isLess = myLessFilterCombo->itemData(myLessFilterCombo->currentIndex()).toInt() == Filter_LT ? factor < v1 : factor <= v1;
922     bool isGreater = myGreaterFilterCombo->itemData(myGreaterFilterCombo->currentIndex()).toInt() == Filter_GT ? factor > v2 : factor >= v2;
923     if ( ( myLessFilterCheck->isChecked() && myGreaterFilterCheck->isChecked() && isLess && isGreater ) ||
924          ( myLessFilterCheck->isChecked() && !myGreaterFilterCheck->isChecked() && isLess ) ||
925          ( myGreaterFilterCheck->isChecked() && !myLessFilterCheck->isChecked() && isGreater ) ) {
926       Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject();
927       io->setEntry( anEntry.toLatin1().constData() );
928       io->setName( myObject->GetName() );
929       toSelect.Append(io);
930     }
931   }
932   if ( toSelect.Extent() > 0 ) {
933     myGeomGUI->getApp()->selectionMgr()->setSelectedObjects(toSelect);
934     SUIT_MessageBox::information( this,
935                                   tr( "INF_INFO" ),
936                                   tr( "GEOM_SOME_SHAPES_SELECTED").arg( toSelect.Extent() ),
937                                   tr( "BUT_OK" ) );
938   }
939   else {
940     SUIT_MessageBox::information( this,
941                                   tr( "INF_INFO" ),
942                                   tr( "GEOM_NO_SHAPES_SELECTED" ),
943                                   tr( "BUT_OK" ) );
944   }
945   updateButtonState();
946 }
947
948 //=================================================================================
949 // function : ClickOnPlot()
950 // purpose  : opens "Shape Statistics" dialog box in order to plot sub-shapes distribution.
951 //=================================================================================
952 void EntityGUI_SubShapeDlg::ClickOnPlot()
953 {
954   QDialog* dlg = new MeasureGUI_ShapeStatisticsDlg( this, myShape, (TopAbs_ShapeEnum)shapeType() );
955   if ( dlg ) {
956     dlg->show();
957   }
958 }
959
960 //=================================================================================
961 // function : MeasureToggled()
962 // purpose  :
963 //          : Called when 'myLessFilterCheck' or 'myGreaterFilterCheck' state change
964 //=================================================================================
965 void EntityGUI_SubShapeDlg::MeasureToggled()
966 {
967   myLessFilterSpin->setEnabled(myLessFilterCheck->isChecked());
968   myLessFilterCombo->setEnabled(myLessFilterCheck->isChecked());
969   myGreaterFilterSpin->setEnabled(myGreaterFilterCheck->isChecked());
970   myGreaterFilterCombo->setEnabled(myGreaterFilterCheck->isChecked());
971   myApplyFilterButton->setEnabled(myLessFilterCheck->isChecked() || myGreaterFilterCheck->isChecked());
972 }
973
974 //=================================================================================
975 // function : getSourceObjects
976 // purpose  : virtual method to get source objects
977 //=================================================================================
978 QList<GEOM::GeomObjPtr> EntityGUI_SubShapeDlg::getSourceObjects()
979 {
980   QList<GEOM::GeomObjPtr> res;
981   GEOM::GeomObjPtr aGeomObjPtr(myObject);
982   res << aGeomObjPtr;
983   return res;
984 }