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