Salome HOME
cc1224f7d87ec9a28b852cfc2eb1bc656c99e747
[modules/geom.git] / src / EntityGUI / EntityGUI_SubShapeDlg.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
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
33 #include <OCCViewer_ViewModel.h>
34 #include <SVTK_ViewModel.h>
35 #include <SalomeApp_Study.h>
36 #include <SalomeApp_Application.h>
37 #include <LightApp_SelectionMgr.h>
38 #include <SALOME_ListIteratorOfListIO.hxx>
39
40 #include <SUIT_Desktop.h>
41 #include <SUIT_ResourceMgr.h>
42 #include <SUIT_Session.h>
43 #include <SUIT_ViewManager.h>
44 #include <SUIT_ViewWindow.h>
45
46 #include <TopExp.hxx>
47 #include <TopExp_Explorer.hxx>
48 #include <TopoDS_Iterator.hxx>
49 #include <TopTools_MapOfShape.hxx>
50 #include <TopTools_IndexedMapOfShape.hxx>
51
52 #include <TColStd_IndexedMapOfInteger.hxx>
53
54 #include <QMessageBox>
55
56 #include <GEOMImpl_Types.hxx>
57
58 //=================================================================================
59 // class    : EntityGUI_SubShapeDlg
60 // purpose  : Constructs a EntityGUI_SubShapeDlg which is a child of 'parent', with the
61 //            name 'name' and widget flags set to 'f'.
62 //            The dialog will by default be modeless, unless you set 'modal' to
63 //            TRUE to construct a modal dialog.
64 //=================================================================================
65 EntityGUI_SubShapeDlg::EntityGUI_SubShapeDlg(GeometryGUI* theGeometryGUI, QWidget* parent,
66                                               bool modal, Qt::WindowFlags fl)
67   : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl),
68     myWithShape(true),
69     myIsHiddenMain(false)
70 {
71   QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_SUBSHAPE")));
72   QPixmap image1(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
73
74   setWindowTitle(tr("GEOM_SUBSHAPE_TITLE"));
75
76   /***************************************************************/
77   mainFrame()->GroupConstructors->setTitle(tr("GEOM_SUB_SHAPE"));
78   mainFrame()->RadioButton1->setIcon(image0);
79   mainFrame()->RadioButton2->setAttribute(Qt::WA_DeleteOnClose);
80   mainFrame()->RadioButton2->close();
81   mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose);
82   mainFrame()->RadioButton3->close();
83
84   GroupPoints = new DlgRef_1Sel1List1Check3Btn(centralWidget());
85
86   GroupPoints->GroupBox1->setTitle(tr("GEOM_ARGUMENTS"));
87   GroupPoints->TextLabel1->setText(tr("GEOM_MAIN_OBJECT"));
88   GroupPoints->TextLabel2->setText(tr("GEOM_SUBSHAPE_TYPE"));
89   GroupPoints->CheckButton1->setText(tr("GEOM_SUBSHAPE_SELECT"));
90   GroupPoints->PushButton1->setIcon(image1);
91   GroupPoints->PushButton2->setText(tr("SHOW_ONLY_SELECTED"));
92   GroupPoints->PushButton3->setText(tr("HIDE_SELECTED"));
93   GroupPoints->PushButton4->setText(tr("SHOW_ALL_SUB_SHAPES"));
94   GroupPoints->LineEdit1->setReadOnly(true);
95
96   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
97   layout->setMargin(0); layout->setSpacing(6);
98   layout->addWidget(GroupPoints);
99   /***************************************************************/
100
101   setIsOptimizedBrowsing(true);
102
103   setHelpFileName("create_explode_page.html");
104
105   mainFrame()->GroupBoxName->hide();
106
107   Init();
108 }
109
110 //=================================================================================
111 // function : ~EntityGUI_SubShapeDlg()
112 // purpose  : Destroys the object and frees any allocated resources
113 //=================================================================================
114 EntityGUI_SubShapeDlg::~EntityGUI_SubShapeDlg()
115 {
116   if (myIsHiddenMain) {
117     GEOM_Displayer* aDisplayer = getDisplayer();
118     aDisplayer->Display(myObject);
119     myIsHiddenMain = false;
120   }
121 }
122
123 //=================================================================================
124 // function : Init()
125 // purpose  :
126 //=================================================================================
127 void EntityGUI_SubShapeDlg::Init()
128 {
129   /* init variables */
130   myEditCurrentArgument = GroupPoints->LineEdit1;
131   myObject = GEOM::GEOM_Object::_nil();
132
133   myWithShape = true;
134
135   /* type for sub-shape selection */
136   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Compound");
137   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Compsolid");
138   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Solid");
139   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Shell");
140   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Face");
141   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Wire");
142   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Edge");
143   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Vertex");
144   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Shape");
145
146   if (SUIT_Session::session()->activeApplication()->desktop()->activeWindow()->getViewManager()->getType()
147       != OCCViewer_Viewer::Type())
148     GroupPoints->CheckButton1->setEnabled(false);
149
150   /* signals and slots connections */
151   connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
152
153   connect(buttonOk(),    SIGNAL(clicked()), this, SLOT(ClickOnOk()));
154   connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
155
156   connect(GroupPoints->PushButton1,  SIGNAL(clicked()),       this, SLOT(SetEditCurrentArgument()));
157   connect(GroupPoints->LineEdit1,    SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
158
159   connect(GroupPoints->ComboBox1,    SIGNAL(activated(int)),    this, SLOT(ComboTextChanged()));
160   connect(GroupPoints->CheckButton1, SIGNAL(stateChanged(int)), this, SLOT(SubShapeToggled()));
161
162   connect(GroupPoints->PushButton2, SIGNAL(clicked()), this, SLOT(showOnlySelected()));
163   connect(GroupPoints->PushButton3, SIGNAL(clicked()), this, SLOT(showOnlySelected()));
164   connect(GroupPoints->PushButton4, SIGNAL(clicked()), this, SLOT(showOnlySelected()));
165
166   connect(myGeomGUI->getApp()->selectionMgr(),
167           SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
168
169   updateButtonState();
170   resize(100,100);
171   SelectionIntoArgument();
172 }
173
174 //=================================================================================
175 // function : enterEvent()
176 // purpose  :
177 //=================================================================================
178 void EntityGUI_SubShapeDlg::enterEvent(QEvent*)
179 {
180   if (!mainFrame()->GroupConstructors->isEnabled())
181     ActivateThisDialog();
182 }
183
184 //=================================================================================
185 // function : ActivateThisDialog()
186 // purpose  :
187 //=================================================================================
188 void EntityGUI_SubShapeDlg::ActivateThisDialog()
189 {
190   GEOMBase_Skeleton::ActivateThisDialog();
191   connect(myGeomGUI->getApp()->selectionMgr(),
192            SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
193   SubShapeToggled();
194   updateButtonState();
195 }
196
197 //=================================================================================
198 //function : closeEvent
199 //purpose  : remove temporary geom object
200 //=================================================================================
201 void EntityGUI_SubShapeDlg::closeEvent(QCloseEvent* e)
202 {
203   erasePreview(true);
204   GEOMBase_Skeleton::closeEvent(e);
205 }
206
207 //=================================================================================
208 // function : ClickOnOk()
209 // purpose  :
210 //=================================================================================
211 void EntityGUI_SubShapeDlg::ClickOnOk()
212 {
213   setIsApplyAndClose(true);
214
215   SUIT_Session::session()->activeApplication()->putInfo("");
216
217   /* Explode all sub-shapes */
218   bool isOk = true;
219   if (isAllSubShapes()) {
220     /* More than 30 sub-shapes : ask confirmation */
221     unsigned int nb = NumberOfSubShapes(myShape, shapeType());
222     if (nb > 30) {
223       const QString caption = tr("GEOM_CONFIRM");
224       const QString text = tr("GEOM_CONFIRM_INFO").arg(nb);
225       const QString button0 = tr("GEOM_BUT_EXPLODE");
226       const QString button1 = tr("GEOM_BUT_CANCEL");
227
228       if (QMessageBox::warning(this, caption, text, button0, button1) != 0)
229         isOk = false;  /* aborted */
230     }
231   }
232
233   if (isOk)
234     isOk = onAccept();
235
236   if (isOk)
237     ClickOnCancel();
238 }
239
240 //=================================================================================
241 // function : ClickOnApply()
242 // purpose  :
243 //=================================================================================
244 bool EntityGUI_SubShapeDlg::ClickOnApply()
245 {
246   SUIT_Session::session()->activeApplication()->putInfo("");
247
248   /* Explode all sub-shapes */
249   if (isAllSubShapes()) {
250     /* More than 30 sub-shapes : ask confirmation */
251     unsigned int nb = NumberOfSubShapes(myShape, shapeType());
252     if (nb > 30) {
253       const QString caption = tr("GEOM_CONFIRM");
254       const QString text = tr("GEOM_CONFIRM_INFO").arg(nb);
255       const QString button0 = tr("GEOM_BUT_EXPLODE");
256       const QString button1 = tr("GEOM_BUT_CANCEL");
257
258       if (QMessageBox::warning(this, caption, text, button0, button1) != 0)
259         return false;  /* aborted */
260     }
261   }
262   
263   setIsDisableBrowsing( true );
264   bool isOk = onAccept( true, true, false );
265   setIsDisableBrowsing( false );
266
267   // restore selection, corresponding to current selection mode
268   SubShapeToggled();
269
270   return isOk;
271 }
272
273 //=================================================================================
274 // function : SelectionIntoArgument()
275 // purpose  : Called when selection has changed or other case
276 //=================================================================================
277 void EntityGUI_SubShapeDlg::SelectionIntoArgument()
278 {
279   if (!isAllSubShapes())
280     return;
281
282   ResetStateOfDialog();
283
284   QString aString = ""; /* name of selection */
285
286   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
287   SALOME_ListIO aSelList;
288   aSelMgr->selectedObjects(aSelList);
289
290   int nbSel = GEOMBase::GetNameOfSelectedIObjects(aSelList, aString, true);
291   if (nbSel != 1)
292     return;
293
294   Handle(SALOME_InteractiveObject) IO = aSelList.First();
295   if (!IO->hasEntry()) {
296     SUIT_Session::session()->activeApplication()->putInfo(tr("GEOM_PRP_SHAPE_IN_STUDY"));
297     updateButtonState();
298     return;
299   }
300
301   if (myIsHiddenMain) {
302     GEOM_Displayer* aDisplayer = getDisplayer();
303     aDisplayer->Display(myObject);
304     myIsHiddenMain = false;
305   }
306
307   TopoDS_Shape S = GEOMBase::GetTopoFromSelection(aSelList);
308   if (S.IsNull() || S.ShapeType() == TopAbs_VERTEX) {
309     myObject = GEOM::GEOM_Object::_nil();
310     updateButtonState();
311     return;
312   }
313
314   myObject = GEOMBase::ConvertIOinGEOMObject(IO);
315   if (myObject->_is_nil()) {
316     updateButtonState();
317     return;
318   }
319
320   myShape = S;
321   GroupPoints->LineEdit1->setText(aString);
322
323   int SelectedShapeType = GroupPoints->ComboBox1->currentIndex();
324   int count = GroupPoints->ComboBox1->count();
325
326   if (myWithShape)
327     count = count - 1;
328
329   int i = 0;
330   // Solving PAL5590
331   if (myShape.ShapeType() == TopAbs_COMPOUND) {
332     unsigned int nb = NumberOfSubShapes(myShape, TopAbs_COMPOUND);
333     if (nb > 0)
334       i++;
335   }
336   while (i <= myShape.ShapeType()) {
337     GroupPoints->ComboBox1->removeItem(0);
338     i++;
339   }
340
341   if (myShape.ShapeType() == TopAbs_COMPOUND) {
342     if (myWithShape == false) {
343       GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Shape");
344       myWithShape = true;
345     }
346   }
347   else {
348     if (myWithShape == true) {
349       GroupPoints->ComboBox1->removeItem(GroupPoints->ComboBox1->count() - 1);
350       myWithShape = false;
351     }
352   }
353
354   int count1 = GroupPoints->ComboBox1->count();
355   if (myWithShape)
356     count1 = count1 - 1;
357
358   if (SelectedShapeType > myShape.ShapeType()) {
359     if (SelectedShapeType == 8) {
360       if (myShape.ShapeType() != TopAbs_COMPOUND) {
361         GroupPoints->ComboBox1->setCurrentIndex(0);
362         ComboTextChanged();
363       }
364     }
365     else
366       GroupPoints->ComboBox1->setCurrentIndex(count1 - count + SelectedShapeType);
367   }
368   else {
369     GroupPoints->ComboBox1->setCurrentIndex(0);
370     ComboTextChanged();
371   }
372
373   updateButtonState();
374 }
375
376 //=================================================================================
377 // function : SetEditCurrentArgument()
378 // purpose  :
379 //=================================================================================
380 void EntityGUI_SubShapeDlg::SetEditCurrentArgument()
381 {
382   GroupPoints->LineEdit1->setFocus();
383   myEditCurrentArgument = GroupPoints->LineEdit1;
384
385   GroupPoints->CheckButton1->setChecked(false);
386   SubShapeToggled();
387   SelectionIntoArgument();
388 }
389
390 //=================================================================================
391 // function : LineEditReturnPressed()
392 // purpose  :
393 //=================================================================================
394 void EntityGUI_SubShapeDlg::LineEditReturnPressed()
395 {
396   QLineEdit* send = (QLineEdit*)sender();
397   if (send == GroupPoints->LineEdit1)
398     SetEditCurrentArgument();
399   else
400     return;
401
402   GEOMBase_Skeleton::LineEditReturnPressed();
403 }
404
405 //=================================================================================
406 // function : ResetStateOfDialog()
407 // purpose  : Completely reset the state of method including local context
408 //=================================================================================
409 void EntityGUI_SubShapeDlg::ResetStateOfDialog()
410 {
411   if (myIsHiddenMain) {
412     GEOM_Displayer* aDisplayer = getDisplayer();
413     aDisplayer->Display(myObject);
414     myIsHiddenMain = false;
415   }
416   myObject = GEOM::GEOM_Object::_nil();
417   myShape.Nullify();
418   myEditCurrentArgument->setText("");
419
420   int SelectedShapeType = GroupPoints->ComboBox1->currentIndex();
421   int count = GroupPoints->ComboBox1->count();
422   if (myWithShape)
423     count = count - 1;
424
425   /* type for sub-shape selection */
426   GroupPoints->ComboBox1->clear();
427   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Compound");
428   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Compsolid");
429   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Solid");
430   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Shell");
431   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Face");
432   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Wire");
433   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Edge");
434   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Vertex");
435   GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Shape");
436
437   myWithShape = true;
438
439   GroupPoints->ComboBox1->setCurrentIndex(8 - count + SelectedShapeType);
440
441   // to avoid recursion: SelectionIntoArgument->ResetStateOfDialog->ComboTextChanged->SubShapeToggled->activateSelection->(currentSelectionChanged)->SelectionIntoArgument
442   //ComboTextChanged();
443
444   updateButtonState();
445 }
446
447 //=================================================================================
448 // function : SubShapeToggled()
449 // purpose  : Allow user selection of all or only selected sub-shapes
450 //          : Called when 'CheckButton1' state change
451 //=================================================================================
452 void EntityGUI_SubShapeDlg::SubShapeToggled()
453 {
454   GroupPoints->PushButton2->setEnabled(!isAllSubShapes());
455   GroupPoints->PushButton3->setEnabled(!isAllSubShapes());
456   GroupPoints->PushButton4->setEnabled(!isAllSubShapes());
457
458   activateSelection();
459 }
460
461 //=================================================================================
462 // function : ComboTextChanged()
463 // purpose  :
464 //=================================================================================
465 void EntityGUI_SubShapeDlg::ComboTextChanged()
466 {
467   /* Select sub-shapes mode not checked */
468   updateButtonState();
469   SubShapeToggled();
470 }
471
472 //=================================================================================
473 // function : NumberOfSubShapes()
474 // purpose  :
475 //=================================================================================
476 unsigned int EntityGUI_SubShapeDlg::NumberOfSubShapes(const TopoDS_Shape& S,
477                                                       const int shapeType) const
478 {
479   if (S.IsNull())
480     return 0;
481
482   unsigned int index = 0;
483   TopTools_MapOfShape M;
484
485   if (S.ShapeType() == TopAbs_COMPOUND &&
486        (TopAbs_ShapeEnum(shapeType) == TopAbs_SHAPE ||
487          TopAbs_ShapeEnum(shapeType) == TopAbs_COMPSOLID ||
488          TopAbs_ShapeEnum(shapeType) == TopAbs_COMPOUND)) {
489     TopoDS_Iterator It(S, Standard_True, Standard_True);
490     for (; It.More(); It.Next()) {
491       if (M.Add(It.Value())) {
492         if (TopAbs_ShapeEnum(shapeType) == TopAbs_SHAPE ||
493              TopAbs_ShapeEnum(shapeType) == It.Value().ShapeType()) {
494           index++;
495         }
496       }
497     }
498   }
499   else {
500     TopExp_Explorer Exp (S, TopAbs_ShapeEnum(shapeType));
501     for (; Exp.More(); Exp.Next()) {
502       if (M.Add(Exp.Current())) {
503         index++;
504       }
505     }
506   }
507
508   M.Clear();
509   return index;
510 }
511
512 //=================================================================================
513 // function : updateButtonState
514 // purpose  :
515 //=================================================================================
516 void EntityGUI_SubShapeDlg::updateButtonState()
517 {
518   if (SUIT_Session::session()->activeApplication()->desktop()->activeWindow()->getViewManager()->getType() != OCCViewer_Viewer::Type() ||
519       myObject->_is_nil() || shapeType() == TopAbs_SHAPE || shapeType() == TopAbs_COMPOUND) {
520     GroupPoints->CheckButton1->setChecked(false);
521     GroupPoints->CheckButton1->setEnabled(false);
522   }
523   else
524     GroupPoints->CheckButton1->setEnabled(true);
525 }
526
527 //=================================================================================
528 // function : isAllSubShapes
529 // purpose  :
530 //=================================================================================
531 bool EntityGUI_SubShapeDlg::isAllSubShapes() const
532 {
533   return !GroupPoints->CheckButton1->isChecked() || !GroupPoints->CheckButton1->isEnabled();
534 }
535
536 //=================================================================================
537 // function : shapeType
538 // purpose  :
539 //=================================================================================
540 int EntityGUI_SubShapeDlg::shapeType() const
541 {
542   int type = GroupPoints->ComboBox1->currentIndex();
543
544   if (myObject->_is_nil())
545     return type;
546
547   // Solving PAL5590
548   type += myShape.ShapeType() + 1;
549   if (myShape.ShapeType() == TopAbs_COMPOUND &&
550       NumberOfSubShapes(myShape, TopAbs_COMPOUND) > 0) {
551     type--;
552   }
553
554   return type;
555 }
556
557 //=================================================================================
558 // function : showOnlySelected
559 // purpose  :
560 //=================================================================================
561 void EntityGUI_SubShapeDlg::showOnlySelected()
562 {
563   if (CORBA::is_nil(myObject) || isAllSubShapes())
564     return;
565
566   QPushButton* send = (QPushButton*)sender();
567   if (send == GroupPoints->PushButton4) {
568     activateSelection();
569     return;
570   }
571
572   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
573   SALOME_ListIO aSelList;
574   aSelMgr->selectedObjects(aSelList);
575
576   GEOM_Displayer* aDisplayer = getDisplayer();
577
578   if (send == GroupPoints->PushButton3) {
579     aDisplayer->Erase(aSelList, /*forced=*/false, /*updateViewer=*/true);
580   }
581   else {
582     // Mantis issue 0021421: do not hide main shape, if explode on VERTEX
583     SALOME_View* view = GEOM_Displayer::GetActiveView();
584     if (view) {
585       CORBA::String_var aMainEntry = myObject->GetStudyEntry();
586       Handle(SALOME_InteractiveObject) io =
587         new SALOME_InteractiveObject (aMainEntry.in(), "GEOM", "TEMP_IO");
588       if (view->isVisible(io)) myIsHiddenMain = true;
589     }
590
591     aDisplayer->EraseAll(/*forced = false, updateViewer = true*/);
592     aDisplayer->Display(aSelList, true);
593
594     // Mantis issue 0021421: do not hide main shape, if explode on VERTEX
595     if ((TopAbs_ShapeEnum)shapeType() == TopAbs_VERTEX && myIsHiddenMain) {
596       aDisplayer->Display(myObject);
597     }
598   }
599 }
600
601 //=================================================================================
602 // function : getSelectedSubshapes
603 // purpose  :
604 //=================================================================================
605 int EntityGUI_SubShapeDlg::getSelectedSubshapes (TColStd_IndexedMapOfInteger& theMapIndex)
606 {
607   theMapIndex.Clear();
608
609   SalomeApp_Application* app = myGeomGUI->getApp();
610   if (!app || myObject->_is_nil())
611     return 0;
612
613   LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
614   SALOME_ListIO aSelList;
615   aSelMgr->selectedObjects(aSelList);
616
617   // try to find out and process the global selection
618   // (of not published objects and of published sub-shapes)
619   {
620     SALOME_ListIteratorOfListIO anIter (aSelList);
621     for (int i = 0; anIter.More(); anIter.Next(), i++)
622     {
623       Handle(SALOME_InteractiveObject) anIObj = anIter.Value();
624       QString anEntry = anIObj->getEntry();
625       QString str = "_";
626       int index = anEntry.lastIndexOf(str);
627       if (index > 0) // selection among special preview
628       {
629         anEntry.remove(0, index+1);
630         int anIndex = anEntry.toInt();
631         if (anIndex)
632           theMapIndex.Add(anIndex);
633       }
634       else // selection among published shapes
635       {
636         SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
637         if (!appStudy) return 0;
638         _PTR(Study) aStudy = appStudy->studyDS();
639
640         _PTR(SObject) aSObj (aStudy->FindObjectID(anEntry.toLatin1().constData()));
641         GEOM::GEOM_Object_var aGeomObj =
642           GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(aSObj));
643         TopoDS_Shape aShape;
644         if (GEOMBase::GetShape(aGeomObj, aShape)) {
645           if (aGeomObj->GetType() == GEOM_GROUP || aShape.ShapeType() == (TopAbs_ShapeEnum)shapeType()) {
646             TopTools_IndexedMapOfShape aMainMap;
647             TopExp::MapShapes(myShape, aMainMap);
648
649             TopExp_Explorer anExp (aShape, (TopAbs_ShapeEnum)shapeType());
650             for (; anExp.More(); anExp.Next()) {
651               TopoDS_Shape aSubShape = anExp.Current();
652               int anIndex = aMainMap.FindIndex(aSubShape);
653               if (anIndex >= 0) {
654                 theMapIndex.Add(anIndex);
655               }
656             }
657           }
658         }
659       }
660     } // for aSelList
661   }
662
663   return theMapIndex.Extent();
664 }
665
666 //=================================================================================
667 // function : activateSelection
668 // purpose  : Activate selection in accordance with myEditCurrentArgument
669 //=================================================================================
670 void EntityGUI_SubShapeDlg::activateSelection()
671 {
672   bool isApply = ((QPushButton*)sender() == buttonApply());
673   
674   if(!isApply)
675     erasePreview(false);
676
677   // local selection
678   if (!myObject->_is_nil() && !isAllSubShapes())
679   {
680     GEOM_Displayer* aDisplayer = getDisplayer();
681
682     // Mantis issue 0021421: do not hide main shape, if explode on VERTEX
683     if ((TopAbs_ShapeEnum)shapeType() == TopAbs_VERTEX) {
684       if (myIsHiddenMain)
685         aDisplayer->Display(myObject);
686     }
687     else {
688       SALOME_View* view = GEOM_Displayer::GetActiveView();
689       if (view) {
690         CORBA::String_var aMainEntry = myObject->GetStudyEntry();
691         Handle(SALOME_InteractiveObject) io =
692           new SALOME_InteractiveObject (aMainEntry.in(), "GEOM", "TEMP_IO");
693         if (view->isVisible(io)) {
694           aDisplayer->Erase(myObject, false, false);
695           myIsHiddenMain = true;
696         }
697       }
698     }
699
700     if(!isApply) {
701       int prevDisplayMode = aDisplayer->SetDisplayMode(0);
702
703       SUIT_ViewWindow* aViewWindow = 0;
704       SUIT_Study* activeStudy = SUIT_Session::session()->activeApplication()->activeStudy();
705       if (activeStudy)
706         aViewWindow = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
707       if (aViewWindow == 0) return;
708
709       SUIT_ViewManager* aViewManager = aViewWindow->getViewManager();
710       if (aViewManager->getType() != OCCViewer_Viewer::Type() &&
711           aViewManager->getType() != SVTK_Viewer::Type())
712         return;
713
714       SUIT_ViewModel* aViewModel = aViewManager->getViewModel();
715       SALOME_View* aView = dynamic_cast<SALOME_View*>(aViewModel);
716       if (aView == 0) return;
717
718       //TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myObject);
719
720       TopTools_IndexedMapOfShape aSubShapesMap;
721       TopExp::MapShapes(myShape, aSubShapesMap);
722       CORBA::String_var aMainEntry = myObject->GetStudyEntry();
723       QString anEntryBase = aMainEntry.in();
724
725       TopExp_Explorer anExp (myShape, (TopAbs_ShapeEnum)shapeType());
726       for (; anExp.More(); anExp.Next())
727       {
728         TopoDS_Shape aSubShape = anExp.Current();
729         int index = aSubShapesMap.FindIndex(aSubShape);
730         QString anEntry = anEntryBase + QString("_%1").arg(index);
731
732         SALOME_Prs* aPrs = aDisplayer->buildSubshapePresentation(aSubShape, anEntry, aView);
733         if (aPrs) {
734           displayPreview(aPrs, true, false); // append, do not update
735         }
736       }
737       aDisplayer->UpdateViewer();
738       aDisplayer->SetDisplayMode(prevDisplayMode);
739     }
740   }
741
742   globalSelection(GEOM_ALLSHAPES);
743 }
744
745 //=================================================================================
746 // function : createOperation
747 // purpose  :
748 //=================================================================================
749 GEOM::GEOM_IOperations_ptr EntityGUI_SubShapeDlg::createOperation()
750 {
751   return getGeomEngine()->GetIShapesOperations(getStudyId());
752 }
753
754 //=================================================================================
755 // function : isValid
756 // purpose  :
757 //=================================================================================
758 bool EntityGUI_SubShapeDlg::isValid (QString& msg)
759 {
760   bool isOk = false;
761
762   if (myObject->_is_nil()) {
763     updateButtonState();
764     return isOk;
765   }
766
767   if (isAllSubShapes())
768     isOk = true;
769   else {
770     TColStd_IndexedMapOfInteger aMapIndex;
771     int nbSel = getSelectedSubshapes(aMapIndex);
772     isOk = nbSel > 0;
773
774     if (!isOk)
775       msg += tr("NO_SUBSHAPES_SELECTED");
776   }
777
778   return isOk;
779 }
780
781 //=================================================================================
782 // function : execute
783 // purpose  :
784 //=================================================================================
785 bool EntityGUI_SubShapeDlg::execute (ObjectList& objects)
786 {
787   GEOM::GEOM_IShapesOperations_var anOper = GEOM::GEOM_IShapesOperations::_narrow(getOperation());
788
789   if (!isAllSubShapes()) {
790     // manual selection
791     TColStd_IndexedMapOfInteger aMapIndex;
792     int nbSel = getSelectedSubshapes(aMapIndex);
793
794     if (nbSel > 0) {
795       int i;
796
797       GEOM::ListOfLong_var anArray = new GEOM::ListOfLong;
798       anArray->length(nbSel);
799
800       for (i = 1; i <= nbSel; i++)
801         anArray[i - 1] = aMapIndex.FindKey(i);
802
803       GEOM::ListOfGO_var aList = anOper->MakeSubShapes(myObject, anArray);
804       int n = aList->length();
805       for (i = 0; i < n; i++)
806         objects.push_back(GEOM::GEOM_Object::_duplicate(aList[i]));
807     }
808   }
809   else {
810     GEOM::ListOfGO_var aList = anOper->ExtractSubShapes(myObject, shapeType(), true);
811     if (!aList->length())
812       return false;
813     for (int i = 0, n = aList->length(); i < n; i++)
814       objects.push_back(GEOM::GEOM_Object::_duplicate(aList[i]));
815   }
816
817   return objects.size();
818 }
819
820 //================================================================
821 // Function : getFather
822 // Purpose  : Get father object for object to be added in study
823 //            (called with addInStudy method)
824 //================================================================
825 GEOM::GEOM_Object_ptr EntityGUI_SubShapeDlg::getFather(GEOM::GEOM_Object_ptr)
826 {
827   return myObject;
828 }
829
830 //================================================================
831 // Function : getNewObjectName
832 // Purpose  :
833 //================================================================
834 QString EntityGUI_SubShapeDlg::getNewObjectName (int) const
835 {
836   return QString::null;
837 }