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