Salome HOME
8cd1ae6a7f99574d8473741db9b89e1adab5f17e
[modules/geom.git] / src / GroupGUI / GroupGUI_GroupDlg.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  GEOM GEOMGUI : GUI for Geometry component
24 //  File   : 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_ResourceMgr.h>
47 #include <SUIT_Desktop.h>
48 #include <SUIT_OverrideCursor.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
679     aDisplayer->EraseAll(/*forced = false, updateViewer = true*/);
680     aDisplayer->Display(aSelList, true);
681
682     // Mantis issue 0021421: do not hide main shape, if explode on VERTEX
683     if (getShapeType() == TopAbs_VERTEX && myIsHiddenMain) {
684       aDisplayer->Display(myMainObj);
685     }
686
687     // for the case when selected ids were not displayed in the viewer: Mantis issue 0021367
688     highlightSubShapes();
689   }
690 }
691
692 //=================================================================================
693 // function : getSelectedSubshapes
694 // purpose  :
695 //=================================================================================
696 int GroupGUI_GroupDlg::getSelectedSubshapes (TColStd_IndexedMapOfInteger& theMapIndex)
697 {
698   theMapIndex.Clear();
699
700   SalomeApp_Application* app = myGeomGUI->getApp();
701   if (!app || myMainObj->_is_nil())
702     return 0;
703
704   LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
705   SALOME_ListIO aSelList;
706   aSelMgr->selectedObjects(aSelList);
707
708   // try to find out and process the global selection
709   // (of not published objects and of published sub-shapes)
710   {
711     SALOME_ListIteratorOfListIO anIter (aSelList);
712     for (int i = 0; anIter.More(); anIter.Next(), i++)
713     {
714       Handle(SALOME_InteractiveObject) anIObj = anIter.Value();
715       QString anEntry = anIObj->getEntry();
716       QString str = "_";
717       int index = anEntry.lastIndexOf(str);
718       if (index > 0) // selection among special preview
719       {
720         anEntry.remove(0, index+1);
721         int anIndex = anEntry.toInt();
722         if (anIndex)
723         theMapIndex.Add(anIndex);
724       }
725       else // selection among published shapes
726       {
727         SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
728         if (!appStudy) return 0;
729         _PTR(Study) aStudy = appStudy->studyDS();
730
731         _PTR(SObject) aSObj (aStudy->FindObjectID(anEntry.toLatin1().constData()));
732         GEOM::GEOM_Object_var aGeomObj =
733           GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(aSObj));
734         TopoDS_Shape aShape;
735         if (GEOMBase::GetShape(aGeomObj, aShape)) {
736           if (aGeomObj->GetType() == GEOM_GROUP || aShape.ShapeType() == getShapeType()) {
737             TopTools_IndexedMapOfShape aMainMap;
738             TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj);
739             TopExp::MapShapes(aMainShape, aMainMap);
740
741             TopExp_Explorer anExp (aShape, getShapeType());
742             for (; anExp.More(); anExp.Next()) {
743               TopoDS_Shape aSubShape = anExp.Current();
744               int anIndex = aMainMap.FindIndex(aSubShape);
745               if (anIndex >= 0) {
746                 if (subSelectionWay() != ALL_SUBSHAPES &&
747                     !myMain2InPlaceIndices.IsBound(anIndex))
748                   continue;
749                 theMapIndex.Add(anIndex);
750               }
751             }
752           }
753         }
754       }
755     } // for aSelList
756   }
757
758   return theMapIndex.Extent();
759 }
760
761 //=================================================================================
762 // function : add
763 // purpose  :
764 //=================================================================================
765 void GroupGUI_GroupDlg::add()
766 {
767   TColStd_IndexedMapOfInteger aMapIndex;
768   int nbSel = getSelectedSubshapes(aMapIndex);
769
770   TColStd_MapOfInteger aMap;
771   for (int i = 0, n = myIdList->count(); i < n; i++)
772     aMap.Add(myIdList->item(i)->text().toInt());
773
774   if (nbSel > 0) {
775     bool isBlocked = myIdList->signalsBlocked();
776     myIdList->blockSignals(true);
777
778     for (int i = 1, n = aMapIndex.Extent(); i <= n; i++) {
779       if (aMap.Contains(aMapIndex(i)))
780         continue;
781
782       QListWidgetItem* anItem = new QListWidgetItem(QString("%1").arg(aMapIndex(i)));
783       anItem->setTextColor( myGroupIdList.contains( aMapIndex( i ) ) ? QColor( GROUP_IDLST_COLOR ) : QColor( GROUP_NEWIDLST_COLOR ) );
784       myIdList->addItem(anItem);
785       anItem->setSelected(true);
786     }
787
788     myIdList->blockSignals(isBlocked);
789   }
790
791   updateState();
792 }
793
794 //=================================================================================
795 // function : remove
796 // purpose  :
797 //=================================================================================
798 void GroupGUI_GroupDlg::remove()
799 {
800   bool isBlocked = myIdList->signalsBlocked();
801   myIdList->blockSignals(true);
802
803   QListIterator<QListWidgetItem*> it (myIdList->selectedItems());
804   while (it.hasNext())
805     delete it.next();
806
807   myIdList->blockSignals(isBlocked);
808
809   highlightSubShapes();
810 }
811
812 //=================================================================================
813 //function : subSelectionWay
814 //purpose  :
815 //=================================================================================
816 int GroupGUI_GroupDlg::subSelectionWay() const
817 {
818   return myRestrictGroup->checkedId();
819 }
820
821 //=================================================================================
822 // function : getShapeType()
823 // purpose  :
824 //=================================================================================
825 TopAbs_ShapeEnum GroupGUI_GroupDlg::getShapeType() const
826 {
827   switch (getConstructorId()) {
828   case 0:  return TopAbs_VERTEX;
829   case 1:  return TopAbs_EDGE;
830   case 2:  return TopAbs_FACE;
831   case 3:  return TopAbs_SOLID;
832   default: return TopAbs_SHAPE;
833   }
834 }
835
836 //=================================================================================
837 // function : setShapeType()
838 // purpose  :
839 //=================================================================================
840 void GroupGUI_GroupDlg::setShapeType(const TopAbs_ShapeEnum theType)
841 {
842   int anId = 0;
843   switch (theType) {
844   case TopAbs_VERTEX: anId = 0; break;
845   case TopAbs_EDGE:   anId = 1; break;
846   case TopAbs_FACE:   anId = 2; break;
847   case TopAbs_SOLID:  anId = 3; break;
848   }
849   setConstructorId(anId);
850   if (!myIsShapeType)
851   {
852     myIsShapeType = true;
853     // workaround to avoid set checked button 0
854     setConstructorId(anId);
855   }
856 }
857
858 //=================================================================================
859 // function : activateSelection
860 // purpose  : Activate selection in accordance with myEditCurrentArgument
861 //=================================================================================
862 void GroupGUI_GroupDlg::activateSelection()
863 {
864   bool isApply = ((QPushButton*)sender() == buttonApply());
865   if(!isApplyAndClose())
866     erasePreview(false);
867
868   // local selection
869   if (!myMainObj->_is_nil() &&
870       !myEditCurrentArgument &&
871       myIsShapeType) // check if shape type is already choosen by user
872   {
873     GEOM_Displayer* aDisplayer = getDisplayer();
874   
875     //display mode for main shape
876     if ( myDmMode == -1 ) {
877     SALOME_View* view = GEOM_Displayer::GetActiveView();
878       if (view) {
879         CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
880         Handle(SALOME_InteractiveObject) io =
881           new SALOME_InteractiveObject (aMainEntry.in(), "GEOM", "TEMP_IO");
882         if ( view->isVisible( io ) ) {
883           Handle(GEOM_AISShape) aSh = GEOMBase::ConvertIOinGEOMAISShape( io, true );
884           if(!aSh.IsNull()) {
885             myDmMode = aSh->isTopLevel() ? aSh->prevDisplayMode() : aSh->DisplayMode();
886           }
887           // Hide main shape, if explode on VERTEX
888           if(getShapeType() != TopAbs_VERTEX) {
889             aDisplayer->Erase(myMainObj, false, false);
890             myIsHiddenMain = true;
891           }
892         }
893         else
894           myDmMode = SUIT_Session::session()->resourceMgr()->integerValue( "Geometry", "display_mode" );
895       }
896     }
897     aDisplayer->SetDisplayMode(myDmMode);
898
899     // Mantis issue 0021421: do not hide main shape, if explode on VERTEX
900     if (getShapeType() == TopAbs_VERTEX) {
901       if (myIsHiddenMain)
902         aDisplayer->Display(myMainObj);
903     }
904     aDisplayer->Erase(myGroup, false, false);
905
906     QColor aColor = SUIT_Session::session()->resourceMgr()->colorValue( "Geometry", "editgroup_color" );
907     Quantity_NameOfColor aCol = SalomeApp_Tools::color( aColor ).Name();
908
909     if(!isApplyAndClose()) {
910       SUIT_ViewWindow* aViewWindow = 0;
911       SUIT_Study* activeStudy = SUIT_Session::session()->activeApplication()->activeStudy();
912       if (activeStudy)
913         aViewWindow = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
914       if (aViewWindow == 0) return;
915
916       SUIT_ViewManager* aViewManager = aViewWindow->getViewManager();
917       if (aViewManager->getType() != OCCViewer_Viewer::Type() &&
918           aViewManager->getType() != SVTK_Viewer::Type())
919         return;
920
921       SUIT_ViewModel* aViewModel = aViewManager->getViewModel();
922       SALOME_View* aView = dynamic_cast<SALOME_View*>(aViewModel);
923       if (aView == 0) return;
924
925       TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj);
926       TopoDS_Shape aRestrictionShape;
927
928       if (subSelectionWay() == ALL_SUBSHAPES) {
929         aRestrictionShape = aMainShape;
930
931         TopTools_IndexedMapOfShape aSubShapesMap;
932         TopExp::MapShapes(aMainShape, aSubShapesMap);
933         CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
934         QString anEntryBase = aMainEntry.in();
935
936         TopExp_Explorer anExp (aRestrictionShape, getShapeType());
937         for (; anExp.More(); anExp.Next()) {
938           TopoDS_Shape aSubShape = anExp.Current();
939           int index = aSubShapesMap.FindIndex(aSubShape);
940           QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index);
941           Handle(SALOME_InteractiveObject) io =
942             new SALOME_InteractiveObject(anEntry.toAscii(), "GEOM", "TEMP_IO");
943           if ( myGroupIdList.contains( index ) ) {
944             aDisplayer->SetColor( aCol );
945           }
946           else {
947             aDisplayer->UnsetColor();
948           }
949           SALOME_Prs* aPrs = aDisplayer->buildSubshapePresentation(aSubShape, anEntry, aView);
950           if (aPrs) {
951             displayPreview(aPrs, true, false); // append, do not update
952             // TODO: map or delete Prs
953           }
954         }
955       }
956       else if (!myInPlaceObj->_is_nil()) {
957         TopTools_IndexedMapOfShape aSubShapesMap;
958         TopExp::MapShapes(aMainShape, aSubShapesMap);
959         CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
960         QString anEntryBase = aMainEntry.in();
961
962         TColStd_DataMapIteratorOfDataMapOfIntegerInteger aM2IPit (myMain2InPlaceIndices);
963         for (; aM2IPit.More(); aM2IPit.Next()) {
964           int index = aM2IPit.Key();
965           TopoDS_Shape aSubShape = aSubShapesMap.FindKey(index);
966           QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index);
967
968           if ( myGroupIdList.contains( index ) ) {
969             aDisplayer->SetColor( aCol );
970           }
971           else {
972             aDisplayer->UnsetColor();
973           }
974
975           SALOME_Prs* aPrs = aDisplayer->buildSubshapePresentation(aSubShape, anEntry, aView);
976           if (aPrs) {
977             displayPreview(aPrs, true, false); // append, do not update
978           }
979         }
980       }
981       else ;
982       aDisplayer->UnsetDisplayMode();
983       aDisplayer->UnsetColor();
984       aDisplayer->UpdateViewer();
985     }
986   }
987
988   globalSelection(GEOM_ALLSHAPES);
989
990   SelectionIntoArgument();
991 }
992
993 //=================================================================================
994 // function : updateState
995 // purpose  :
996 //=================================================================================
997 void GroupGUI_GroupDlg::updateState (bool isAdd)
998 {
999   myAddBtn->setEnabled(!myEditCurrentArgument && !CORBA::is_nil(myMainObj) && isAdd);
1000   //myShowOnlyBtn->setEnabled(!myEditCurrentArgument && !CORBA::is_nil(myMainObj) && isAdd);
1001
1002   bool hasSel = myIdList->selectedItems().count() > 0;
1003
1004   myRemBtn->setEnabled(hasSel);
1005   myRestrictGroupBox->setEnabled(!CORBA::is_nil(myMainObj));
1006   mySelAllBtn->setEnabled(!CORBA::is_nil(myMainObj));
1007
1008   mySelBtn2->setEnabled(subSelectionWay() != ALL_SUBSHAPES);
1009   myShape2Name->setEnabled(subSelectionWay() != ALL_SUBSHAPES);
1010   if (subSelectionWay() == ALL_SUBSHAPES)
1011     setInPlaceObj(GEOM::GEOM_Object::_nil());
1012 }
1013
1014 //=================================================================================
1015 // function : selectionChanged
1016 // purpose  :
1017 //=================================================================================
1018 void GroupGUI_GroupDlg::selectionChanged()
1019 {
1020   highlightSubShapes();
1021 }
1022
1023 //=================================================================================
1024 // function : highlightSubShapes
1025 // purpose  :
1026 //=================================================================================
1027 void GroupGUI_GroupDlg::highlightSubShapes()
1028 {
1029   if (CORBA::is_nil(myMainObj))
1030     return;
1031
1032   TColStd_MapOfInteger anIds;
1033
1034   myBusy = true;
1035
1036   int ii = 0, nn = myIdList->count();
1037   for (; ii < nn; ii++)
1038   {
1039     if (myIdList->item(ii)->isSelected()) {
1040       int id = myIdList->item(ii)->text().toInt();
1041       if (subSelectionWay() != ALL_SUBSHAPES &&
1042           !myMain2InPlaceIndices.IsBound(id)) {
1043         //myIdList->item(ii)->setSelected(false);
1044       }
1045       else {
1046         anIds.Add(id);
1047       }
1048     }
1049   }
1050   SalomeApp_Application* app = myGeomGUI->getApp();
1051   LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
1052   aSelMgr->clearSelected();
1053
1054   SUIT_ViewWindow* aViewWindow = 0;
1055   SUIT_Study* activeStudy = app->activeStudy();
1056   if (activeStudy)
1057     aViewWindow = app->desktop()->activeWindow();
1058   if (aViewWindow == 0) return;
1059
1060   SUIT_ViewManager* aViewManager = aViewWindow->getViewManager();
1061   if (aViewManager->getType() != OCCViewer_Viewer::Type() &&
1062       aViewManager->getType() != SVTK_Viewer::Type())
1063     return;
1064
1065   SUIT_ViewModel* aViewModel = aViewManager->getViewModel();
1066   SALOME_View* aView = dynamic_cast<SALOME_View*>(aViewModel);
1067   if (aView == 0) return;
1068
1069   // TODO??: use here GEOMBase_Helper::myPreview instead of ic->DisplayedObjects()
1070
1071   OCCViewer_Viewer* v3d = ((OCCViewer_ViewManager*)aViewManager)->getOCCViewer();
1072   Handle(AIS_InteractiveContext) ic = v3d->getAISContext();
1073   AIS_ListOfInteractive List;
1074   //ic->DisplayedObjects(List);
1075   ic->ObjectsInside(List); // Mantis issue 0021367
1076
1077   SALOME_ListIO aSelList;
1078
1079   // To highlight the selected sub-shape in Object Browser, if it's already published under the main shape
1080   GEOM::GEOM_ILocalOperations_var aLocOp = getGeomEngine()->GetILocalOperations(getStudyId());
1081   QMap<int, QString> childsMap;
1082   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
1083   if (appStudy) {
1084     _PTR(Study) aStudy = appStudy->studyDS();
1085     CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
1086     QString anEntry = aMainEntry.in();
1087     _PTR(SObject) aSObj (aStudy->FindObjectID(anEntry.toLatin1().constData()));
1088     _PTR(ChildIterator) anIt (aStudy->NewChildIterator(aSObj));
1089     for (anIt->InitEx(true); anIt->More(); anIt->Next()) {
1090       GEOM::GEOM_Object_var aChild = GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(anIt->Value()));
1091       if (!CORBA::is_nil(aChild)) {
1092         int index = aLocOp->GetSubShapeIndex(myMainObj, aChild);
1093         CORBA::String_var aChildEntry = aChild->GetStudyEntry();
1094         QString anEntry = aChildEntry.in();
1095         childsMap.insert(index, anEntry);
1096       }
1097     }
1098   }
1099
1100   AIS_ListIteratorOfListOfInteractive ite (List);
1101   for (; ite.More(); ite.Next()) {
1102     if (ite.Value()->IsInstance(STANDARD_TYPE(GEOM_AISShape))) {
1103       Handle(GEOM_AISShape) aSh = Handle(GEOM_AISShape)::DownCast(ite.Value());
1104       if (aSh->hasIO()) {
1105         Handle(SALOME_InteractiveObject) anIO = aSh->getIO();
1106         QString anEntry = anIO->getEntry();
1107         int index = anEntry.lastIndexOf("_");
1108         anEntry.remove(0, index+1);
1109         int anIndex = anEntry.toInt();
1110         if (anIds.Contains(anIndex)) {
1111           aSelList.Append(anIO);
1112           if (childsMap.contains (anIndex)) {
1113             Handle(SALOME_InteractiveObject) tmpIO = new SALOME_InteractiveObject(childsMap.value(anIndex).toLatin1().constData(), "GEOM", "TEMP_IO");
1114             aSelList.Append(tmpIO);
1115           }
1116         }
1117       }
1118     }
1119   }
1120   aSelMgr->setSelectedObjects(aSelList);
1121
1122   myBusy = false;
1123
1124   if (nn < 3000)
1125     updateState(aSelList.Extent() > 0);
1126   else {
1127     myAddBtn->setEnabled(true);
1128     myAddBtn->setEnabled(true);
1129     myRemBtn->setEnabled(true);
1130   }
1131 }
1132
1133 //=================================================================================
1134 // function : createOperation
1135 // purpose  :
1136 //=================================================================================
1137 GEOM::GEOM_IOperations_ptr GroupGUI_GroupDlg::createOperation()
1138 {
1139   return getGeomEngine()->GetIGroupOperations(getStudyId());
1140 }
1141
1142 #define RETURN_WITH_MSG(a, b) \
1143   if (!(a)) { \
1144     theMessage += (b); \
1145     return false; \
1146   }
1147
1148 //=================================================================================
1149 // function : isValid()
1150 // purpose  : Verify validity of input data
1151 //=================================================================================
1152 bool GroupGUI_GroupDlg::isValid(QString& theMessage)
1153 {
1154   SalomeApp_Study* study = getStudy();
1155   ASSERT(study);
1156   RETURN_WITH_MSG  (!study->studyDS()->GetProperties()->IsLocked(), tr("GEOM_STUDY_LOCKED"))
1157
1158   if (myMode == CreateGroup) {
1159     RETURN_WITH_MSG(!CORBA::is_nil(myMainObj), tr("NO_MAIN_OBJ"))
1160   }
1161   else {
1162     RETURN_WITH_MSG(!CORBA::is_nil(myMainObj), tr("NO_GROUP"))
1163   }
1164
1165   QString aName (getNewObjectName());
1166   RETURN_WITH_MSG  (!aName.trimmed().isEmpty(), tr("EMPTY_NAME"))
1167
1168   RETURN_WITH_MSG  (myIdList->count(), tr("EMPTY_LIST"))
1169   return true;
1170 }
1171
1172 //=================================================================================
1173 // function : execute
1174 // purpose  :
1175 //=================================================================================
1176 bool GroupGUI_GroupDlg::execute(ObjectList& objects)
1177 {
1178   GEOM::GEOM_IGroupOperations_var anOper = GEOM::GEOM_IGroupOperations::_narrow(getOperation());
1179
1180   GEOM::GEOM_Object_var aGroup;
1181   if (myMode == CreateGroup)
1182     aGroup = anOper->CreateGroup(myMainObj, getShapeType());
1183   else if (myMode == EditGroup)
1184     aGroup = myGroup;
1185
1186   if (CORBA::is_nil(aGroup) || (myMode == CreateGroup && !anOper->IsDone()))
1187     return false;
1188
1189   GEOM::ListOfLong_var aCurrList = anOper->GetObjects(aGroup);
1190   if (!anOper->IsDone())
1191     return false;
1192
1193   if (aCurrList->length() > 0)
1194   {
1195     anOper->DifferenceIDs(aGroup, aCurrList);
1196     if (!anOper->IsDone())
1197       return false;
1198   }
1199
1200   int ii, nn = myIdList->count();
1201   if (nn > 0)
1202   {
1203     GEOM::ListOfLong_var aNewList = new GEOM::ListOfLong;
1204     aNewList->length(nn);
1205     for (ii = 0; ii < nn; ii++) {
1206       aNewList[ii] = myIdList->item(ii)->text().toInt();
1207     }
1208     anOper->UnionIDs(aGroup, aNewList);
1209     if (!anOper->IsDone())
1210       return false;
1211   }
1212
1213   SalomeApp_Study* study = getStudy();
1214   if (study) {
1215     QString objIOR = GEOMBase::GetIORFromObject(aGroup);
1216     if (objIOR != "") {
1217       _PTR(SObject) SO (study->studyDS()->FindObjectIOR(objIOR.toLatin1().constData()));
1218       if (SO) {
1219         _PTR(StudyBuilder) aBuilder (study->studyDS()->NewBuilder());
1220         aBuilder->SetName(SO, getNewObjectName().toLatin1().constData());
1221       }
1222     }
1223   }
1224
1225   objects.push_back(aGroup._retn());
1226
1227   return true;
1228 }
1229
1230 //================================================================
1231 // Function : getFather
1232 // Purpose  : Get father object for object to be added in study
1233 //            (called with addInStudy method)
1234 //================================================================
1235 GEOM::GEOM_Object_ptr GroupGUI_GroupDlg::getFather(GEOM::GEOM_Object_ptr theObj)
1236 {
1237   GEOM::GEOM_Object_var aFatherObj;
1238   if (theObj->GetType() == GEOM_GROUP) {
1239     GEOM::GEOM_IGroupOperations_var anOper = GEOM::GEOM_IGroupOperations::_narrow(getOperation());
1240     aFatherObj = anOper->GetMainShape(theObj);
1241   }
1242   return aFatherObj._retn();
1243 }