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