Salome HOME
Revert "Synchronize adm files"
[modules/geom.git] / src / GroupGUI / GroupGUI_GroupDlg.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  GEOM GEOMGUI : GUI for Geometry component
24 //  File   : GroupGUI_GroupDlg.cxx
25 //  Author : Sergey ANIKIN, Open CASCADE S.A.S. (sergey.anikin@opencascade.com)
26
27 #include "GroupGUI_GroupDlg.h"
28
29 #include <DlgRef.h>
30 #include <GEOMBase.h>
31 #include <GeometryGUI.h>
32 #include <GEOM_Displayer.h>
33
34 #include <SalomeApp_Application.h>
35 #include <SalomeApp_Study.h>
36 #include <SalomeApp_Tools.h>
37
38 #include <LightApp_SelectionMgr.h>
39
40 #include <OCCViewer_ViewModel.h>
41 #include <OCCViewer_ViewManager.h>
42 #include <SVTK_ViewModel.h>
43 #include <SALOME_Prs.h>
44 #include <SALOME_ListIteratorOfListIO.hxx>
45
46 #include <SUIT_Desktop.h>
47 #include <SUIT_MessageBox.h>
48 #include <SUIT_OverrideCursor.h>
49 #include <SUIT_ResourceMgr.h>
50 #include <SUIT_Session.h>
51 #include <SUIT_ViewWindow.h>
52 #include <SUIT_ViewManager.h>
53
54 #include <QLabel>
55 #include <QListWidget>
56 #include <QLineEdit>
57 #include <QMap>
58
59 #include <AIS_ListOfInteractive.hxx>
60 #include <AIS_ListIteratorOfListOfInteractive.hxx>
61
62 #include <TopExp.hxx>
63 #include <TopExp_Explorer.hxx>
64 #include <TopTools_IndexedMapOfShape.hxx>
65 #include <TColStd_IndexedMapOfInteger.hxx>
66 #include <TColStd_MapOfInteger.hxx>
67 #include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
68
69 #include <GEOMImpl_Types.hxx>
70
71 #define GROUP_IDLST_COLOR Qt::blue // Specific color for the IDs of subShapes in the dialog box
72 #define GROUP_NEWIDLST_COLOR Qt::red // Specific color for the new IDs of subShapes in the dialog box
73
74 enum { ALL_SUBSHAPES = 0, GET_IN_PLACE, SUBSHAPES_OF_SHAPE2, SUBSHAPES_OF_INVISIBLE_SHAPE2 };
75
76 GroupGUI_GroupDlg::GroupGUI_GroupDlg (Mode mode, GeometryGUI* theGeometryGUI, QWidget* parent)
77   : GEOMBase_Skeleton(theGeometryGUI, parent, false),
78     myMode(mode),
79     myBusy(false),
80     myIsShapeType(false),
81     myIsHiddenMain(false),
82     myWasHiddenMain(true)
83 {
84   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
85
86   QPixmap image0     (resMgr->loadPixmap("GEOM", tr("ICON_OBJBROWSER_VERTEX")));
87   QPixmap image1     (resMgr->loadPixmap("GEOM", tr("ICON_OBJBROWSER_EDGE")));
88   QPixmap image2     (resMgr->loadPixmap("GEOM", tr("ICON_OBJBROWSER_FACE")));
89   QPixmap image3     (resMgr->loadPixmap("GEOM", tr("ICON_OBJBROWSER_SOLID")));
90   QPixmap iconSelect (resMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
91
92   setWindowTitle(myMode == CreateGroup ? tr("CREATE_GROUP_TITLE") : tr("EDIT_GROUP_TITLE"));
93
94   // Shape type button group
95   mainFrame()->GroupConstructors->setEnabled(myMode == CreateGroup);
96   mainFrame()->GroupConstructors->setTitle(tr("SHAPE_TYPE"));
97   mainFrame()->RadioButton1->setIcon(image0);
98   mainFrame()->RadioButton2->setIcon(image1);
99   mainFrame()->RadioButton3->setIcon(image2);
100   mainFrame()->RadioButton4->setIcon(image3);
101   mainFrame()->RadioButton4->show();
102
103   // Group name
104   mainFrame()->GroupBoxName->setTitle(tr("GROUP_NAME"));
105
106   // Main shape and sub-shapes
107   QGroupBox* GroupMedium = new QGroupBox(tr("MAIN_SUB_SHAPES"), centralWidget());
108   QGridLayout* aMedLayout = new QGridLayout(GroupMedium);
109   aMedLayout->setMargin(9);
110   aMedLayout->setSpacing(6);
111
112   QLabel* aMainLabel = new QLabel(tr("MAIN_SHAPE"), GroupMedium);
113
114   mySelBtn = new QPushButton(GroupMedium);
115   mySelBtn->setIcon(iconSelect);
116   mySelBtn->setEnabled(myMode == CreateGroup);
117
118   myMainName = new QLineEdit(GroupMedium);
119   myMainName->setReadOnly(true);
120   myMainName->setEnabled(myMode == CreateGroup);
121
122   myRestrictGroupBox = new QGroupBox(tr("SHAPE_SEL_RESTR"), GroupMedium);
123   myRestrictGroup = new QButtonGroup(myRestrictGroupBox);
124   QRadioButton* allSubs     = new QRadioButton(tr("NO_RESTR")            , myRestrictGroupBox);
125   QRadioButton* inPlaceSubs = new QRadioButton(tr("GEOM_PARTS_OF_SHAPE2"), myRestrictGroupBox);
126   QRadioButton* shape2Subs  = new QRadioButton(tr("SUBSHAPES_OF_SHAPE2") , myRestrictGroupBox);
127   QGridLayout* aRestrictLayout = new QGridLayout(myRestrictGroupBox);
128
129   QLabel* aSecondLabel = new QLabel(tr("SECOND_SHAPE"), myRestrictGroupBox);
130   mySelBtn2 = new QPushButton(myRestrictGroupBox);
131   mySelBtn2->setIcon(iconSelect);
132   mySelBtn2->setEnabled(false);
133   myShape2Name = new QLineEdit(myRestrictGroupBox);
134   myShape2Name->setReadOnly(true);
135   myShape2Name->setEnabled(false);
136
137   aRestrictLayout->setMargin(9);
138   aRestrictLayout->setSpacing(6);
139   aRestrictLayout->addWidget(allSubs,      0, 0, 1, 3);
140   aRestrictLayout->addWidget(inPlaceSubs,  1, 0, 1, 3);
141   aRestrictLayout->addWidget(shape2Subs,   2, 0, 1, 3);
142   aRestrictLayout->addWidget(aSecondLabel, 3, 0);
143   aRestrictLayout->addWidget(mySelBtn2,    3, 1);
144   aRestrictLayout->addWidget(myShape2Name, 3, 2);
145   myRestrictGroup->addButton(allSubs,      ALL_SUBSHAPES);
146   myRestrictGroup->addButton(inPlaceSubs,  GET_IN_PLACE);
147   myRestrictGroup->addButton(shape2Subs,   SUBSHAPES_OF_SHAPE2);
148   myRestrictGroupBox->setEnabled(!CORBA::is_nil(myMainObj));
149   allSubs->setChecked(true);
150
151   myShowOnlyBtn = new QPushButton(tr("SHOW_ONLY_SELECTED"), GroupMedium);
152   myHideSelBtn  = new QPushButton(tr("HIDE_SELECTED"), GroupMedium);
153   myShowAllBtn  = new QPushButton(tr("SHOW_ALL_SUB_SHAPES"), GroupMedium);
154
155   mySelAllBtn   = new QPushButton(tr("SELECT_ALL"), GroupMedium);
156   myAddBtn      = new QPushButton(tr("ADD"), GroupMedium);
157   myRemBtn      = new QPushButton(tr("REMOVE"), GroupMedium);
158
159   myIdList    = new QListWidget(GroupMedium);
160
161   myIdList->setSelectionMode(QAbstractItemView::ExtendedSelection);
162   myIdList->setFlow(QListView::TopToBottom);
163   myIdList->setWrapping(true);
164
165   aMedLayout->addWidget(aMainLabel,         0, 0);
166   aMedLayout->addWidget(mySelBtn,           0, 1);
167   aMedLayout->addWidget(myMainName,         0, 2, 1, 2);
168   aMedLayout->addWidget(myRestrictGroupBox, 1, 0, 4, 3);
169
170   aMedLayout->addWidget(myShowOnlyBtn,      1, 3);
171   aMedLayout->addWidget(myHideSelBtn,       2, 3);
172   aMedLayout->addWidget(myShowAllBtn,       3, 3);
173
174   aMedLayout->addWidget(myIdList,           5, 0, 4, 3);
175   aMedLayout->addWidget(mySelAllBtn,        5, 3);
176   aMedLayout->addWidget(myAddBtn,           6, 3);
177   aMedLayout->addWidget(myRemBtn,           7, 3);
178
179   aMedLayout->setColumnStretch(2, 5);
180   aMedLayout->setRowStretch(5, 5);
181   aMedLayout->setRowStretch(8, 5);
182
183   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
184   layout->setMargin(0); layout->setSpacing(6);
185   layout->addWidget(GroupMedium);
186
187   setHelpFileName("work_with_groups_page.html");
188
189   Init();
190   updateState();
191 }
192
193 GroupGUI_GroupDlg::~GroupGUI_GroupDlg()
194 {
195   GEOM_Displayer* aDisplayer = getDisplayer();
196   if (myWasHiddenMain) {
197     aDisplayer->Erase(myMainObj);
198     myIsHiddenMain = true;
199   } else {
200     aDisplayer->Display(myMainObj);
201     myIsHiddenMain = false;
202   }
203   aDisplayer->Display(myGroup);
204   myDmMode = -1;
205 }
206
207 //=================================================================================
208 // function : Init()
209 // purpose  :
210 //=================================================================================
211 void GroupGUI_GroupDlg::Init()
212 {
213   myDmMode = -1;
214   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
215
216   //unset shape type to avoid preparation of selection before exact user shape type selection
217   unsetConstructorId();
218   myIsShapeType = false;
219
220   if (myMode == CreateGroup) {
221     initName(tr("GROUP_PREFIX"));
222
223     // Get ready for main shape selection
224     myEditCurrentArgument = myMainName;
225
226     connect(this, SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int)));
227     connect(mySelBtn,         SIGNAL(clicked()),    this, SLOT(SetEditCurrentArgument()));
228     connect(mySelBtn2,        SIGNAL(clicked()),    this, SLOT(SetEditCurrentArgument()));
229   }
230   else if (myMode == EditGroup) {
231     SALOME_ListIO aSelList;
232     aSelMgr->selectedObjects(aSelList);
233
234     if (aSelList.Extent()) {
235       GEOM::GEOM_Object_var anObj =
236         GEOMBase::ConvertIOinGEOMObject(aSelList.First());
237
238       if (!CORBA::is_nil(anObj) && anObj->GetType() == GEOM_GROUP) {
239         myGroup = anObj;
240
241         mainFrame()->ResultName->setText(GEOMBase::GetName(myGroup));
242
243         GEOM::GEOM_IGroupOperations_var anOper = GEOM::GEOM_IGroupOperations::_narrow(getOperation());
244         myMainObj = anOper->GetMainShape(myGroup);
245         if (!CORBA::is_nil(myMainObj)) {
246           myMainName->setText(GEOMBase::GetName(myMainObj));
247           SALOME_View* view = GEOM_Displayer::GetActiveView();
248           if (view) {
249             CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
250             Handle(SALOME_InteractiveObject) io =
251               new SALOME_InteractiveObject (aMainEntry.in(), "GEOM", "TEMP_IO");
252             if (view->isVisible(io)) myWasHiddenMain = false;
253           }
254         }
255
256         setShapeType((TopAbs_ShapeEnum)anOper->GetType(myGroup));
257
258         GEOM::ListOfLong_var aCurrList = anOper->GetObjects(myGroup);
259         for (int i = 0, n = aCurrList->length(); i < n; i++) {
260           QListWidgetItem* itm = new QListWidgetItem( QString( "%1" ).arg( aCurrList[ i ] ) );
261           myGroupIdList.append( aCurrList[ i ] );
262           itm->setTextColor( QColor( GROUP_IDLST_COLOR ) );
263           myIdList->addItem( itm );
264         }
265         myEditCurrentArgument = 0;
266       }
267       connect(mySelBtn2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
268     }
269   }
270
271   connect(aSelMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
272
273   connect(buttonOk(),    SIGNAL(clicked()), this, SLOT(ClickOnOk()));
274   connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
275
276   connect(myRestrictGroup, SIGNAL(buttonClicked(int)),     this, SLOT(SetEditCurrentArgument()));
277   connect(mySelAllBtn,     SIGNAL(clicked()),              this, SLOT(selectAllSubShapes()));
278   connect(myAddBtn,        SIGNAL(clicked()),              this, SLOT(add()));
279   connect(myRemBtn,        SIGNAL(clicked()),              this, SLOT(remove()));
280   connect(myShowOnlyBtn,   SIGNAL(clicked()),              this, SLOT(showOnlySelected()));
281   connect(myHideSelBtn,    SIGNAL(clicked()),              this, SLOT(showOnlySelected()));
282   connect(myShowAllBtn,    SIGNAL(clicked()),              this, SLOT(showOnlySelected()));
283   connect(myIdList,        SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged()));
284
285   setInPlaceObj(GEOM::GEOM_Object::_nil());
286
287   myBusy = true; // just activate but do not select in the list
288   activateSelection();
289   myBusy = false;
290 }
291
292 //=================================================================================
293 // function : enterEvent()
294 // purpose  :
295 //=================================================================================
296 void GroupGUI_GroupDlg::enterEvent(QEvent* e)
297 {
298   if (!buttonCancel()->isEnabled())
299     ActivateThisDialog();
300 }
301
302 //=================================================================================
303 //function : closeEvent
304 //purpose  : remove temporary geom object
305 //=================================================================================
306 void GroupGUI_GroupDlg::closeEvent(QCloseEvent* e)
307 {
308   setInPlaceObj(GEOM::GEOM_Object::_nil());
309   erasePreview(true);
310
311   GEOMBase_Skeleton::closeEvent(e);
312 }
313
314 //=================================================================================
315 // function : ClickOnOk()
316 // purpose  :
317 //=================================================================================
318 void GroupGUI_GroupDlg::ClickOnOk()
319 {
320   setIsApplyAndClose(true);
321   if (ClickOnApply())
322     ClickOnCancel();
323   setIsApplyAndClose(false);
324   getDisplayer()->UnsetDisplayMode();
325 }
326
327 //=================================================================================
328 // function : ClickOnApply()
329 // purpose  :
330 //=================================================================================
331 bool GroupGUI_GroupDlg::ClickOnApply()
332 {
333   if(!isApplyAndClose()) {
334     setIsDisableBrowsing( true );
335     setIsDisplayResult( false );
336   }
337     
338   if (!onAccept(myMode == CreateGroup, true, isApplyAndClose()))
339     return false;
340
341   if(!isApplyAndClose()) {
342     setIsDisableBrowsing( false );
343     setIsDisplayResult( true );
344   }
345
346   if (myMode == CreateGroup)
347   {
348     initName();
349     myIdList->clear();
350     ConstructorsClicked(getConstructorId());
351   }
352   else
353   {
354     int n = myIdList->count();
355     myGroupIdList.clear();
356     if (n > 0)
357     {
358       for (int i = 0; i < n; i++) {
359         QListWidgetItem* anItem  = myIdList->item( i );
360         myGroupIdList.append( anItem->text().toInt() );
361         anItem->setTextColor( GROUP_IDLST_COLOR );
362       }
363     }
364     activateSelection();
365   }
366   return true;
367 }
368
369 //=================================================================================
370 // function : ActivateThisDialog()
371 // purpose  :
372 //=================================================================================
373 void GroupGUI_GroupDlg::ActivateThisDialog()
374 {
375   GEOMBase_Skeleton::ActivateThisDialog();
376
377   connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
378           this, SLOT(SelectionIntoArgument()));
379
380   activateSelection();
381 }
382
383 //=================================================================================
384 // function : SetEditCurrentArgument()
385 // purpose  :
386 //=================================================================================
387 void GroupGUI_GroupDlg::SetEditCurrentArgument()
388 {
389   QPushButton* send = (QPushButton*)sender();
390
391   if (send == mySelBtn) {
392     myEditCurrentArgument = myMainName;
393     myShape2Name->setText("");
394   }
395   else if (send == mySelBtn2 || sender() == myRestrictGroup) {
396     setInPlaceObj(GEOM::GEOM_Object::_nil());
397     myShape2Name->setText("");
398     if (subSelectionWay() != ALL_SUBSHAPES) {
399       myEditCurrentArgument = myShape2Name;
400     }
401     else {
402       myEditCurrentArgument = 0;
403     }
404   }
405
406   activateSelection();
407
408   updateState();
409 }
410
411 //=================================================================================
412 // function : onGetInPlace()
413 // purpose  :
414 //=================================================================================
415 void GroupGUI_GroupDlg::onGetInPlace()
416 {
417   setInPlaceObj(GEOM::GEOM_Object::_nil());
418   myEditCurrentArgument->setText("");
419
420   bool isBlocked = myIdList->signalsBlocked();
421   myIdList->blockSignals(true);
422   myIdList->clearSelection();
423   myIdList->blockSignals(isBlocked);
424
425   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
426   SALOME_ListIO aSelList;
427   aSelMgr->selectedObjects(aSelList);
428
429   if (aSelList.Extent() != 1)
430     return;
431
432   GEOM::GEOM_Object_var anObj =
433     GEOMBase::ConvertIOinGEOMObject(aSelList.First());
434   if (GEOMBase::IsShape(anObj)) {
435     if (!anObj->_is_equivalent(myMainObj) && !anObj->_is_equivalent(myGroup)) {
436       SUIT_OverrideCursor wc;
437       myEditCurrentArgument->setText(GEOMBase::GetName(anObj));
438       GEOM::GEOM_IShapesOperations_var aShapesOp =
439         getGeomEngine()->GetIShapesOperations(getStudyId());
440       if (subSelectionWay() == GET_IN_PLACE) {
441         GEOM::GEOM_Object_var aGetInPlaceObj = aShapesOp->GetInPlace(myMainObj, anObj);
442         setInPlaceObj(aGetInPlaceObj);
443       }
444       else {
445         bool isVisible = true;
446         if (SALOME_View* view = GEOM_Displayer::GetActiveView())
447           isVisible = view->isVisible(aSelList.First());
448         setInPlaceObj(anObj, isVisible);
449       }
450       myEditCurrentArgument = 0;
451       //myBusy = true; // just activate but do not select in the list
452       activateSelection();
453       //myBusy = false;
454     }
455   }
456 }
457
458 //=================================================================================
459 //function : setInPlaceObj
460 //purpose  : temporarily add an object to study and remove old InPlaceObj
461 //=================================================================================
462 void GroupGUI_GroupDlg::setInPlaceObj(GEOM::GEOM_Object_var theObj, const bool isVisible)
463 {
464   if (!myInPlaceObj->_is_equivalent(theObj))
465   {
466     myInPlaceObj = theObj;
467   }
468
469   // build map of indices
470   myMain2InPlaceIndices.Clear();
471   if (!myInPlaceObj->_is_nil()) {
472     GEOM::GEOM_IShapesOperations_var aShapesOp = getGeomEngine()->GetIShapesOperations(getStudyId());
473     GEOM::GEOM_ILocalOperations_var aLocOp = getGeomEngine()->GetILocalOperations(getStudyId());
474
475     GEOM::ListOfGO_var aSubObjects = aShapesOp->MakeExplode(myInPlaceObj, getShapeType(), false);
476     for ( int i = 0; i < aSubObjects->length(); i++ )
477     {
478       GEOM::ListOfLong_var aCurrList = aShapesOp->GetSameIDs( myMainObj, aSubObjects[i] );
479       if( aCurrList->length() > 1 ) {
480         //rnv : To Fix the 21561: EDF 2184 GEOM: Group with second shape restriction.
481         //      In case if GetSameIDs(...) method return more then one ID use 
482         //      GetSharedShapes(...) method to get sub-shapes of the second shape.
483         GEOM::ListOfGO_var aSubObjects2 = aShapesOp->GetSharedShapes( myMainObj, aSubObjects[i], getShapeType() );
484         for( int j = 0; j < aSubObjects2->length(); j++ ) {
485           CORBA::Long aMainIndex =  aLocOp->GetSubShapeIndex( myMainObj, aSubObjects2[j] );
486           CORBA::Long aPlaceIndex = aLocOp->GetSubShapeIndex( myInPlaceObj, aSubObjects[i]);
487           if ( aMainIndex >= 0 && aPlaceIndex > 0 ) {
488             myMain2InPlaceIndices.Bind( aMainIndex, aPlaceIndex );
489           }
490         }
491       } else if(aCurrList->length() > 0 ) {
492         CORBA::Long aMainIndex = aCurrList[0];
493         CORBA::Long aPlaceIndex = aLocOp->GetSubShapeIndex( myInPlaceObj, aSubObjects[i] );
494         if ( aMainIndex >= 0 && aPlaceIndex > 0) {
495           myMain2InPlaceIndices.Bind( aMainIndex, aPlaceIndex );
496         }
497       }
498     }
499   }
500   myInPlaceObjSelectState = subSelectionWay();
501   if (myInPlaceObjSelectState == SUBSHAPES_OF_SHAPE2 && !isVisible)
502     myInPlaceObjSelectState = SUBSHAPES_OF_INVISIBLE_SHAPE2;
503 }
504
505 //=================================================================================
506 // function : SelectionIntoArgument()
507 // purpose  : Called when selection has changed
508 //=================================================================================
509 void GroupGUI_GroupDlg::SelectionIntoArgument()
510 {
511   if (subSelectionWay() != ALL_SUBSHAPES && myEditCurrentArgument == myShape2Name) {
512     onGetInPlace();
513     return;
514   }
515
516   if (myEditCurrentArgument == myMainName) {  // Selection of a main shape is active
517     myEditCurrentArgument->setText("");
518     myIdList->clear();
519
520     LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
521     SALOME_ListIO aSelList;
522     aSelMgr->selectedObjects(aSelList);
523     int nbSel = aSelList.Extent();
524
525     if (nbSel == 1) {
526       GEOM::GEOM_Object_var anObj =
527         GEOMBase::ConvertIOinGEOMObject(aSelList.First());
528
529       if (GEOMBase::IsShape(anObj)) {
530         if (myIsHiddenMain) {
531           GEOM_Displayer* aDisplayer = getDisplayer();
532           aDisplayer->Display(myMainObj);
533           myIsHiddenMain = false;
534         }
535         myMainObj = anObj;
536         if (!CORBA::is_nil(myMainObj)) {
537           SALOME_View* view = GEOM_Displayer::GetActiveView();
538           if (view) {
539             CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
540             Handle(SALOME_InteractiveObject) io =
541               new SALOME_InteractiveObject (aMainEntry.in(), "GEOM", "TEMP_IO");
542             if (view->isVisible(io)) myWasHiddenMain = false;
543           }
544         }
545         myEditCurrentArgument->setText(GEOMBase::GetName(anObj));
546         // activate sub-shapes selection by default
547         myEditCurrentArgument = 0;
548         activateSelection();
549         updateState();
550       }
551     }
552     else {
553       if (myIsHiddenMain) {
554         GEOM_Displayer* aDisplayer = getDisplayer();
555         aDisplayer->Display(myMainObj);
556         myIsHiddenMain = false;
557       }
558       myMainObj = GEOM::GEOM_Object::_nil();
559     }
560   }
561   else { // an attempt to synchronize list box selection with 3d viewer
562     if (myBusy || myMainObj->_is_nil()) {
563       return;
564     }
565
566     bool isBlocked = myIdList->signalsBlocked();
567     myIdList->blockSignals(true);
568     myIdList->clearSelection();
569
570     TColStd_IndexedMapOfInteger aMapIndex;
571     int nbSel = getSelectedSubshapes(aMapIndex);
572
573     if (nbSel) {
574       QMap<int, int> aMap;
575       for (int i = 0, n = myIdList->count(); i < n; i++)
576         aMap.insert(myIdList->item(i)->text().toInt(), i);
577
578       bool highlight = false;
579       for (int ii = 1, nn = aMapIndex.Extent(); ii <= nn; ii++) {
580         if (aMap.contains(aMapIndex(ii))) {
581           myIdList->item(aMap[aMapIndex(ii)])->setSelected(true);
582           highlight = true;
583         }
584       }
585       if (highlight)
586         highlightSubShapes();
587     }
588     myIdList->blockSignals(isBlocked);
589
590     updateState(nbSel);
591   }
592 }
593
594 //=================================================================================
595 // function : ConstructorsClicked()
596 // purpose  : Radio button management
597 //=================================================================================
598 void GroupGUI_GroupDlg::ConstructorsClicked(int constructorId)
599 {
600   if (getConstructorId() != constructorId)
601     setConstructorId(constructorId);
602
603   myIsShapeType = true;
604   myIdList->clear();
605   myEditCurrentArgument = 0;
606
607   setInPlaceObj(myInPlaceObj); // to rebuild myMain2InPlaceIndices
608   activateSelection();
609   updateState();
610 }
611
612 //=================================================================================
613 // function : selectAllSubShapes
614 // purpose  :
615 //=================================================================================
616 void GroupGUI_GroupDlg::selectAllSubShapes()
617 {
618   if (CORBA::is_nil(myMainObj) || !myIsShapeType)
619     return;
620
621   GEOM::ListOfLong_var aSubShapes;
622   GEOM::GEOM_IShapesOperations_var aShOp = getGeomEngine()->GetIShapesOperations(getStudyId());
623   aSubShapes = aShOp->SubShapeAllIDs(myMainObj, getShapeType(), false);
624   if (aSubShapes->length() > 0) {
625     if (subSelectionWay() == ALL_SUBSHAPES)
626     {
627 //      myIdList->clear(); // for sorted final list?
628
629       if (!aShOp->IsDone())
630         return;
631     }
632     else
633     {
634       aSubShapes = new GEOM::ListOfLong();
635       aSubShapes->length(myMain2InPlaceIndices.Extent());
636       TColStd_DataMapIteratorOfDataMapOfIntegerInteger m2ip (myMain2InPlaceIndices);
637       for (int i = 0; m2ip.More(); i++, m2ip.Next())
638         aSubShapes[i] = m2ip.Key();
639     }
640
641     bool isBlocked = myIdList->signalsBlocked();
642     myIdList->blockSignals(true);
643
644     for (int i = 0, n = aSubShapes->length(); i < n; i++) {
645       CORBA::Long anIndex = aSubShapes[i];
646       if (anIndex < 0)
647         continue;
648
649       QListWidgetItem* anItem = 0;
650       QString text = QString("%1").arg(anIndex);
651 //      if (!myInPlaceObj->_is_nil()) {
652         QList<QListWidgetItem*> found = myIdList->findItems(text, Qt::MatchExactly);
653         if (found.count()) anItem = found[0];
654 //      }
655       if (!anItem) {
656         anItem = new QListWidgetItem(text);
657         anItem->setTextColor( myGroupIdList.contains(anIndex) ? QColor( GROUP_IDLST_COLOR ) : QColor( GROUP_NEWIDLST_COLOR ) );
658         myIdList->addItem(anItem);
659       }
660       anItem->setSelected(true);
661     }
662
663     myIdList->blockSignals(isBlocked);
664     highlightSubShapes();
665   }
666 }
667
668 //=================================================================================
669 // function : showOnlySelected
670 // purpose  :
671 //=================================================================================
672 void GroupGUI_GroupDlg::showOnlySelected()
673 {
674   if (CORBA::is_nil(myMainObj) || !myIsShapeType)
675     return;
676
677   QPushButton* send = (QPushButton*)sender();
678   if (send == myShowAllBtn) {
679     activateSelection();
680     return;
681   }
682
683   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
684   SALOME_ListIO aSelList;
685   aSelMgr->selectedObjects(aSelList);
686
687   GEOM_Displayer* aDisplayer = getDisplayer();
688
689   if (send == myHideSelBtn) {
690     aDisplayer->Erase(aSelList, /*forced=*/false, /*updateViewer=*/true);
691   }
692   else {
693     // Mantis issue 0021421: do not hide main shape, if explode on VERTEX
694     SALOME_View* view = GEOM_Displayer::GetActiveView();
695     if (view) {
696       CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
697       Handle(SALOME_InteractiveObject) io =
698         new SALOME_InteractiveObject (aMainEntry.in(), "GEOM", "TEMP_IO");
699       if (view->isVisible(io)) myIsHiddenMain = true;
700       
701       //keep the selected entry and IO in the map for checking
702       std::map<QString, Handle(SALOME_InteractiveObject)> aSelEntriesMap;
703       SALOME_ListIteratorOfListIO aSelIt(aSelList);
704       for ( ; aSelIt.More(); aSelIt.Next() ) {
705         Handle(SALOME_InteractiveObject) anSelIO = aSelIt.Value();
706         aSelEntriesMap[anSelIO->getEntry()] = anSelIO;
707       }
708       //get the displayed sub-shapes
709       SALOME_ListIO displayed;
710       view->GetVisible(displayed);
711       // Erase all, except the selected sub-shapes
712       std::map<QString, Handle(SALOME_InteractiveObject)>::iterator 
713         aSelDispIter = aSelEntriesMap.end();
714       SALOME_ListIteratorOfListIO aDispIt( displayed );
715       for ( ; aDispIt.More(); aDispIt.Next() ) {
716         Handle(SALOME_InteractiveObject) anIO = aDispIt.Value();
717         aSelDispIter = aSelEntriesMap.find( anIO->getEntry() );
718         if ( aSelDispIter != aSelEntriesMap.end() ) {
719           //sub-shape is selected, so erase it's record from map to keep in it not displayed, but selected sub-shapes only
720           aSelEntriesMap.erase(aSelDispIter);
721         } else {
722           //sub-shape is not in the map of selected, then erase it from view
723           aDisplayer->Erase( anIO, /*forced = */false, /*updateViewer = */false );
724         }
725       }
726
727       if ( !aSelEntriesMap.empty() ) {
728         // Build a presentation of the selected, but not displayed sub-shapes
729         TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj);
730         TopTools_IndexedMapOfShape aSubShapesMap;
731         TopExp::MapShapes(aMainShape, aSubShapesMap);
732         QString anEntryBase = aMainEntry.in();
733
734         TopExp_Explorer anExp (aMainShape, getShapeType());
735         for (; anExp.More(); anExp.Next()) {
736           TopoDS_Shape aSubShape = anExp.Current();
737           int index = aSubShapesMap.FindIndex(aSubShape);
738           QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index);
739           if ( aSelEntriesMap.find( anEntry ) == aSelEntriesMap.end() ) {
740             //skip not selected sub-shapes
741             continue;
742           }
743           SALOME_Prs* aPrs = aDisplayer->buildSubshapePresentation(aSubShape, anEntry, view);
744           if (aPrs) {
745             displayPreview(aPrs, true, false); // append, do not update
746           }
747         }
748       }
749       aDisplayer->UpdateViewer();
750     }
751
752     // Mantis issue 0021421: do not hide main shape, if explode on VERTEX
753     if (getShapeType() == TopAbs_VERTEX && myIsHiddenMain) {
754       aDisplayer->Display(myMainObj);
755     }
756
757     // for the case when selected ids were not displayed in the viewer: Mantis issue 0021367
758     highlightSubShapes();
759   }
760 }
761
762 //=================================================================================
763 // function : getSelectedSubshapes
764 // purpose  :
765 //=================================================================================
766 int GroupGUI_GroupDlg::getSelectedSubshapes (TColStd_IndexedMapOfInteger& theMapIndex)
767 {
768   theMapIndex.Clear();
769
770   SalomeApp_Application* app = myGeomGUI->getApp();
771   if (!app || myMainObj->_is_nil())
772     return 0;
773
774   LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
775   SALOME_ListIO aSelList;
776   aSelMgr->selectedObjects(aSelList);
777
778   // try to find out and process the global selection
779   // (of not published objects and of published sub-shapes)
780   {
781     SALOME_ListIteratorOfListIO anIter (aSelList);
782     for (int i = 0; anIter.More(); anIter.Next(), i++)
783     {
784       Handle(SALOME_InteractiveObject) anIObj = anIter.Value();
785       QString anEntry = anIObj->getEntry();
786       QString str = "_";
787       int index = anEntry.lastIndexOf(str);
788       if (index > 0) // selection among special preview
789       {
790         anEntry.remove(0, index+1);
791         int anIndex = anEntry.toInt();
792         if (anIndex)
793           theMapIndex.Add(anIndex);
794       }
795       else // selection among published shapes
796       {
797         SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
798         if (!appStudy) return 0;
799         _PTR(Study) aStudy = appStudy->studyDS();
800
801         _PTR(SObject) aSObj (aStudy->FindObjectID(anEntry.toLatin1().constData()));
802         GEOM::GEOM_Object_var aGeomObj =
803           GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(aSObj));
804         TopoDS_Shape aShape;
805         if (GEOMBase::GetShape(aGeomObj, aShape)) {
806           if (aGeomObj->GetType() == GEOM_GROUP || aShape.ShapeType() == getShapeType()) {
807             TopTools_IndexedMapOfShape aMainMap;
808             TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj);
809             TopExp::MapShapes(aMainShape, aMainMap);
810
811             TopExp_Explorer anExp (aShape, getShapeType());
812             bool isShowWarning = true;
813             for (; anExp.More(); anExp.Next()) {
814               TopoDS_Shape aSubShape = anExp.Current();
815               int anIndex = aMainMap.FindIndex(aSubShape);
816               if (anIndex == 0) {
817                 if (isShowWarning) {
818                   SUIT_MessageBox::warning(app->desktop(), QObject::tr("WRN_WARNING"),
819                                          tr("WRN_NOT_SUBSHAPE"));
820                   isShowWarning = false;
821                 }
822               }
823               else {
824                 if (subSelectionWay() != ALL_SUBSHAPES &&
825                     !myMain2InPlaceIndices.IsBound(anIndex))
826                   continue;
827                 theMapIndex.Add(anIndex);
828               }
829             }
830           }
831         }
832       }
833     } // for aSelList
834   }
835
836   return theMapIndex.Extent();
837 }
838
839 //=================================================================================
840 // function : add
841 // purpose  :
842 //=================================================================================
843 void GroupGUI_GroupDlg::add()
844 {
845   TColStd_IndexedMapOfInteger aMapIndex;
846   int nbSel = getSelectedSubshapes(aMapIndex);
847
848   TColStd_MapOfInteger aMap;
849   for (int i = 0, n = myIdList->count(); i < n; i++)
850     aMap.Add(myIdList->item(i)->text().toInt());
851
852   if (nbSel > 0) {
853     bool isBlocked = myIdList->signalsBlocked();
854     myIdList->blockSignals(true);
855
856     for (int i = 1, n = aMapIndex.Extent(); i <= n; i++) {
857       if (aMap.Contains(aMapIndex(i)))
858         continue;
859
860       QListWidgetItem* anItem = new QListWidgetItem(QString("%1").arg(aMapIndex(i)));
861       anItem->setTextColor( myGroupIdList.contains( aMapIndex( i ) ) ? QColor( GROUP_IDLST_COLOR ) : QColor( GROUP_NEWIDLST_COLOR ) );
862       myIdList->addItem(anItem);
863       anItem->setSelected(true);
864     }
865
866     myIdList->blockSignals(isBlocked);
867   }
868
869   updateState();
870 }
871
872 //=================================================================================
873 // function : remove
874 // purpose  :
875 //=================================================================================
876 void GroupGUI_GroupDlg::remove()
877 {
878   bool isBlocked = myIdList->signalsBlocked();
879   myIdList->blockSignals(true);
880
881   QListIterator<QListWidgetItem*> it (myIdList->selectedItems());
882   while (it.hasNext())
883     delete it.next();
884
885   myIdList->blockSignals(isBlocked);
886
887   highlightSubShapes();
888 }
889
890 //=================================================================================
891 //function : subSelectionWay
892 //purpose  :
893 //=================================================================================
894 int GroupGUI_GroupDlg::subSelectionWay() const
895 {
896   return myRestrictGroup->checkedId();
897 }
898
899 //=================================================================================
900 // function : getShapeType()
901 // purpose  :
902 //=================================================================================
903 TopAbs_ShapeEnum GroupGUI_GroupDlg::getShapeType() const
904 {
905   switch (getConstructorId()) {
906   case 0:  return TopAbs_VERTEX;
907   case 1:  return TopAbs_EDGE;
908   case 2:  return TopAbs_FACE;
909   case 3:  return TopAbs_SOLID;
910   default: return TopAbs_SHAPE;
911   }
912 }
913
914 //=================================================================================
915 // function : setShapeType()
916 // purpose  :
917 //=================================================================================
918 void GroupGUI_GroupDlg::setShapeType(const TopAbs_ShapeEnum theType)
919 {
920   int anId = 0;
921   switch (theType) {
922   case TopAbs_VERTEX: anId = 0; break;
923   case TopAbs_EDGE:   anId = 1; break;
924   case TopAbs_FACE:   anId = 2; break;
925   case TopAbs_SOLID:  anId = 3; break;
926   }
927   setConstructorId(anId);
928   if (!myIsShapeType)
929   {
930     myIsShapeType = true;
931     // workaround to avoid set checked button 0
932     setConstructorId(anId);
933   }
934 }
935
936 //=================================================================================
937 // function : activateSelection
938 // purpose  : Activate selection in accordance with myEditCurrentArgument
939 //=================================================================================
940 void GroupGUI_GroupDlg::activateSelection()
941 {
942   bool isApply = ((QPushButton*)sender() == buttonApply());
943   if(!isApplyAndClose())
944     erasePreview(false);
945
946   // local selection
947   if (!myMainObj->_is_nil() &&
948       !myEditCurrentArgument &&
949       myIsShapeType) // check if shape type is already choosen by user
950   {
951     GEOM_Displayer* aDisplayer = getDisplayer();
952
953     //display mode for main shape
954     if ( myDmMode == -1 ) {
955     SALOME_View* view = GEOM_Displayer::GetActiveView();
956       if (view) {
957         CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
958         Handle(SALOME_InteractiveObject) io =
959           new SALOME_InteractiveObject (aMainEntry.in(), "GEOM", "TEMP_IO");
960         if ( view->isVisible( io ) ) {
961           Handle(GEOM_AISShape) aSh = GEOMBase::ConvertIOinGEOMAISShape( io, true );
962           if(!aSh.IsNull()) {
963             myDmMode = aSh->isTopLevel() ? aSh->prevDisplayMode() : aSh->DisplayMode();
964           }
965         }
966         else
967           myDmMode = SUIT_Session::session()->resourceMgr()->integerValue( "Geometry", "display_mode" );
968       }
969     }
970     aDisplayer->SetDisplayMode(myDmMode);
971
972     // Mantis issue 0021421: do not hide main shape, if explode on VERTEX
973     if(getShapeType() != TopAbs_VERTEX) {
974       aDisplayer->Erase(myMainObj, false, false);
975       myIsHiddenMain = true;
976     }
977     else
978       aDisplayer->Display(myMainObj);
979
980     aDisplayer->Erase(myGroup, false, false);
981
982     QColor aColor = SUIT_Session::session()->resourceMgr()->colorValue( "Geometry", "editgroup_color" );
983     Quantity_NameOfColor aCol = SalomeApp_Tools::color( aColor ).Name();
984
985     if(!isApplyAndClose()) {
986       SUIT_ViewWindow* aViewWindow = 0;
987       SUIT_Study* activeStudy = SUIT_Session::session()->activeApplication()->activeStudy();
988       if (activeStudy)
989         aViewWindow = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
990       if (aViewWindow == 0) return;
991
992       SUIT_ViewManager* aViewManager = aViewWindow->getViewManager();
993       if (aViewManager->getType() != OCCViewer_Viewer::Type() &&
994           aViewManager->getType() != SVTK_Viewer::Type())
995         return;
996
997       SUIT_ViewModel* aViewModel = aViewManager->getViewModel();
998       SALOME_View* aView = dynamic_cast<SALOME_View*>(aViewModel);
999       if (aView == 0) return;
1000
1001       TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj);
1002       TopoDS_Shape aRestrictionShape;
1003
1004       if (subSelectionWay() == ALL_SUBSHAPES) {
1005         aRestrictionShape = aMainShape;
1006
1007         TopTools_IndexedMapOfShape aSubShapesMap;
1008         TopExp::MapShapes(aMainShape, aSubShapesMap);
1009         CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
1010         QString anEntryBase = aMainEntry.in();
1011
1012         TopExp_Explorer anExp (aRestrictionShape, getShapeType());
1013         for (; anExp.More(); anExp.Next()) {
1014           TopoDS_Shape aSubShape = anExp.Current();
1015           int index = aSubShapesMap.FindIndex(aSubShape);
1016           QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index);
1017           Handle(SALOME_InteractiveObject) io =
1018             new SALOME_InteractiveObject(anEntry.toAscii(), "GEOM", "TEMP_IO");
1019           if ( myGroupIdList.contains( index ) ) {
1020             aDisplayer->SetColor( aCol );
1021           }
1022           else {
1023             aDisplayer->UnsetColor();
1024           }
1025           SALOME_Prs* aPrs = aDisplayer->buildSubshapePresentation(aSubShape, anEntry, aView);
1026           if (aPrs) {
1027             displayPreview(aPrs, true, false); // append, do not update
1028             // TODO: map or delete Prs
1029           }
1030         }
1031       }
1032       else if (!myInPlaceObj->_is_nil()) {
1033         TopTools_IndexedMapOfShape aSubShapesMap;
1034         TopExp::MapShapes(aMainShape, aSubShapesMap);
1035         CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
1036         QString anEntryBase = aMainEntry.in();
1037
1038         TColStd_DataMapIteratorOfDataMapOfIntegerInteger aM2IPit (myMain2InPlaceIndices);
1039         for (; aM2IPit.More(); aM2IPit.Next()) {
1040           int index = aM2IPit.Key();
1041           TopoDS_Shape aSubShape = aSubShapesMap.FindKey(index);
1042           QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index);
1043
1044           if ( myGroupIdList.contains( index ) ) {
1045             aDisplayer->SetColor( aCol );
1046           }
1047           else {
1048             aDisplayer->UnsetColor();
1049           }
1050
1051           SALOME_Prs* aPrs = aDisplayer->buildSubshapePresentation(aSubShape, anEntry, aView);
1052           if (aPrs) {
1053             displayPreview(aPrs, true, false); // append, do not update
1054           }
1055         }
1056       }
1057       else ;
1058       aDisplayer->UnsetDisplayMode();
1059       aDisplayer->UnsetColor();
1060       aDisplayer->UpdateViewer();
1061     }
1062   }
1063
1064   globalSelection(GEOM_ALLSHAPES);
1065
1066   SelectionIntoArgument();
1067 }
1068
1069 //=================================================================================
1070 // function : updateState
1071 // purpose  :
1072 //=================================================================================
1073 void GroupGUI_GroupDlg::updateState (bool isAdd)
1074 {
1075   myAddBtn->setEnabled(!myEditCurrentArgument && !CORBA::is_nil(myMainObj) && isAdd);
1076   //myShowOnlyBtn->setEnabled(!myEditCurrentArgument && !CORBA::is_nil(myMainObj) && isAdd);
1077
1078   bool hasSel = myIdList->selectedItems().count() > 0;
1079
1080   myRemBtn->setEnabled(hasSel);
1081   myRestrictGroupBox->setEnabled(!CORBA::is_nil(myMainObj));
1082   mySelAllBtn->setEnabled(!CORBA::is_nil(myMainObj));
1083
1084   mySelBtn2->setEnabled(subSelectionWay() != ALL_SUBSHAPES);
1085   myShape2Name->setEnabled(subSelectionWay() != ALL_SUBSHAPES);
1086   if (subSelectionWay() == ALL_SUBSHAPES)
1087     setInPlaceObj(GEOM::GEOM_Object::_nil());
1088 }
1089
1090 //=================================================================================
1091 // function : selectionChanged
1092 // purpose  :
1093 //=================================================================================
1094 void GroupGUI_GroupDlg::selectionChanged()
1095 {
1096   highlightSubShapes();
1097 }
1098
1099 //=================================================================================
1100 // function : highlightSubShapes
1101 // purpose  :
1102 //=================================================================================
1103 void GroupGUI_GroupDlg::highlightSubShapes()
1104 {
1105   if (CORBA::is_nil(myMainObj))
1106     return;
1107
1108   TColStd_MapOfInteger anIds;
1109
1110   myBusy = true;
1111
1112   int ii = 0, nn = myIdList->count();
1113   for (; ii < nn; ii++)
1114   {
1115     if (myIdList->item(ii)->isSelected()) {
1116       int id = myIdList->item(ii)->text().toInt();
1117       if (subSelectionWay() != ALL_SUBSHAPES &&
1118           !myMain2InPlaceIndices.IsBound(id)) {
1119         //myIdList->item(ii)->setSelected(false);
1120       }
1121       else {
1122         anIds.Add(id);
1123       }
1124     }
1125   }
1126   SalomeApp_Application* app = myGeomGUI->getApp();
1127   LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
1128   aSelMgr->clearSelected();
1129
1130   SUIT_ViewWindow* aViewWindow = 0;
1131   SUIT_Study* activeStudy = app->activeStudy();
1132   if (activeStudy)
1133     aViewWindow = app->desktop()->activeWindow();
1134   if (aViewWindow == 0) return;
1135
1136   SUIT_ViewManager* aViewManager = aViewWindow->getViewManager();
1137   if (aViewManager->getType() != OCCViewer_Viewer::Type() &&
1138       aViewManager->getType() != SVTK_Viewer::Type())
1139     return;
1140
1141   SUIT_ViewModel* aViewModel = aViewManager->getViewModel();
1142   SALOME_View* aView = dynamic_cast<SALOME_View*>(aViewModel);
1143   if (aView == 0) return;
1144
1145   // TODO??: use here GEOMBase_Helper::myPreview instead of ic->DisplayedObjects()
1146
1147   OCCViewer_Viewer* v3d = ((OCCViewer_ViewManager*)aViewManager)->getOCCViewer();
1148   Handle(AIS_InteractiveContext) ic = v3d->getAISContext();
1149   AIS_ListOfInteractive List;
1150   //ic->DisplayedObjects(List);
1151   ic->ObjectsInside(List); // Mantis issue 0021367
1152
1153   SALOME_ListIO aSelList;
1154
1155   // To highlight the selected sub-shape in Object Browser, if it's already published under the main shape
1156   GEOM::GEOM_ILocalOperations_var aLocOp = getGeomEngine()->GetILocalOperations(getStudyId());
1157   QMap<int, QString> childsMap;
1158   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
1159   if (appStudy) {
1160     _PTR(Study) aStudy = appStudy->studyDS();
1161     CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
1162     QString anEntry = aMainEntry.in();
1163     _PTR(SObject) aSObj (aStudy->FindObjectID(anEntry.toLatin1().constData()));
1164     _PTR(ChildIterator) anIt (aStudy->NewChildIterator(aSObj));
1165     for (anIt->InitEx(true); anIt->More(); anIt->Next()) {
1166       GEOM::GEOM_Object_var aChild = GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(anIt->Value()));
1167       if (!CORBA::is_nil(aChild)) {
1168         int index = aLocOp->GetSubShapeIndex(myMainObj, aChild);
1169         CORBA::String_var aChildEntry = aChild->GetStudyEntry();
1170         QString anEntry = aChildEntry.in();
1171         childsMap.insert(index, anEntry);
1172       }
1173     }
1174   }
1175
1176   AIS_ListIteratorOfListOfInteractive ite (List);
1177   for (; ite.More(); ite.Next()) {
1178     if (ite.Value()->IsInstance(STANDARD_TYPE(GEOM_AISShape))) {
1179       Handle(GEOM_AISShape) aSh = Handle(GEOM_AISShape)::DownCast(ite.Value());
1180       if (aSh->hasIO()) {
1181         Handle(SALOME_InteractiveObject) anIO = aSh->getIO();
1182         QString anEntry = anIO->getEntry();
1183         int index = anEntry.lastIndexOf("_");
1184         anEntry.remove(0, index+1);
1185         int anIndex = anEntry.toInt();
1186         if (anIds.Contains(anIndex)) {
1187           aSelList.Append(anIO);
1188           if (childsMap.contains (anIndex)) {
1189             Handle(SALOME_InteractiveObject) tmpIO = new SALOME_InteractiveObject(childsMap.value(anIndex).toLatin1().constData(), "GEOM", "TEMP_IO");
1190             aSelList.Append(tmpIO);
1191           }
1192         }
1193       }
1194     }
1195   }
1196   aSelMgr->setSelectedObjects(aSelList);
1197
1198   myBusy = false;
1199
1200   if (nn < 3000)
1201     updateState(aSelList.Extent() > 0);
1202   else {
1203     myAddBtn->setEnabled(true);
1204     myAddBtn->setEnabled(true);
1205     myRemBtn->setEnabled(true);
1206   }
1207 }
1208
1209 //=================================================================================
1210 // function : createOperation
1211 // purpose  :
1212 //=================================================================================
1213 GEOM::GEOM_IOperations_ptr GroupGUI_GroupDlg::createOperation()
1214 {
1215   return getGeomEngine()->GetIGroupOperations(getStudyId());
1216 }
1217
1218 #define RETURN_WITH_MSG(a, b) \
1219   if (!(a)) { \
1220     theMessage += (b); \
1221     return false; \
1222   }
1223
1224 //=================================================================================
1225 // function : isValid()
1226 // purpose  : Verify validity of input data
1227 //=================================================================================
1228 bool GroupGUI_GroupDlg::isValid(QString& theMessage)
1229 {
1230   SalomeApp_Study* study = getStudy();
1231   ASSERT(study);
1232   RETURN_WITH_MSG  (!study->studyDS()->GetProperties()->IsLocked(), tr("GEOM_STUDY_LOCKED"))
1233
1234   if (myMode == CreateGroup) {
1235     RETURN_WITH_MSG(!CORBA::is_nil(myMainObj), tr("NO_MAIN_OBJ"))
1236   }
1237   else {
1238     RETURN_WITH_MSG(!CORBA::is_nil(myMainObj), tr("NO_GROUP"))
1239   }
1240
1241   QString aName (getNewObjectName());
1242   RETURN_WITH_MSG  (!aName.trimmed().isEmpty(), tr("EMPTY_NAME"))
1243
1244   RETURN_WITH_MSG  (myIdList->count(), tr("EMPTY_LIST"))
1245   return true;
1246 }
1247
1248 //=================================================================================
1249 // function : execute
1250 // purpose  :
1251 //=================================================================================
1252 bool GroupGUI_GroupDlg::execute(ObjectList& objects)
1253 {
1254   GEOM::GEOM_IGroupOperations_var anOper = GEOM::GEOM_IGroupOperations::_narrow(getOperation());
1255
1256   GEOM::GEOM_Object_var aGroup;
1257   if (myMode == CreateGroup)
1258     aGroup = anOper->CreateGroup(myMainObj, getShapeType());
1259   else if (myMode == EditGroup)
1260     aGroup = myGroup;
1261
1262   if (CORBA::is_nil(aGroup) || (myMode == CreateGroup && !anOper->IsDone()))
1263     return false;
1264
1265   GEOM::ListOfLong_var aCurrList = anOper->GetObjects(aGroup);
1266   if (!anOper->IsDone())
1267     return false;
1268
1269   if (aCurrList->length() > 0)
1270   {
1271     anOper->DifferenceIDs(aGroup, aCurrList);
1272     if (!anOper->IsDone())
1273       return false;
1274   }
1275
1276   int ii, nn = myIdList->count();
1277   if (nn > 0)
1278   {
1279     GEOM::ListOfLong_var aNewList = new GEOM::ListOfLong;
1280     aNewList->length(nn);
1281     for (ii = 0; ii < nn; ii++) {
1282       aNewList[ii] = myIdList->item(ii)->text().toInt();
1283     }
1284     anOper->UnionIDs(aGroup, aNewList);
1285     if (!anOper->IsDone())
1286       return false;
1287   }
1288
1289   SalomeApp_Study* study = getStudy();
1290   if (study) {
1291     QString objIOR = GEOMBase::GetIORFromObject(aGroup);
1292     if (objIOR != "") {
1293       _PTR(SObject) SO (study->studyDS()->FindObjectIOR(objIOR.toLatin1().constData()));
1294       if (SO) {
1295         _PTR(StudyBuilder) aBuilder (study->studyDS()->NewBuilder());
1296         aBuilder->SetName(SO, getNewObjectName().toLatin1().constData());
1297       }
1298     }
1299   }
1300
1301   objects.push_back(aGroup._retn());
1302
1303   return true;
1304 }
1305
1306 //================================================================
1307 // Function : getFather
1308 // Purpose  : Get father object for object to be added in study
1309 //            (called with addInStudy method)
1310 //================================================================
1311 GEOM::GEOM_Object_ptr GroupGUI_GroupDlg::getFather(GEOM::GEOM_Object_ptr theObj)
1312 {
1313   GEOM::GEOM_Object_var aFatherObj;
1314   if (theObj->GetType() == GEOM_GROUP) {
1315     GEOM::GEOM_IGroupOperations_var anOper = GEOM::GEOM_IGroupOperations::_narrow(getOperation());
1316     aFatherObj = anOper->GetMainShape(theObj);
1317   }
1318   return aFatherObj._retn();
1319 }