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