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