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