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