]> SALOME platform Git repositories - modules/geom.git/blob - src/GroupGUI/GroupGUI_GroupDlg.cxx
Salome HOME
CurveCreator widget: mask detection mode, not implemented
[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 = qobject_cast<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     if ( send )
476       send->setDown(true);
477   }
478
479   updateState();
480 }
481
482 //=================================================================================
483 // function : onGetInPlace()
484 // purpose  :
485 //=================================================================================
486 void GroupGUI_GroupDlg::onGetInPlace()
487 {
488   setInPlaceObj(GEOM::GEOM_Object::_nil());
489   myEditCurrentArgument->setText("");
490
491   bool isBlocked = myIdList->signalsBlocked();
492   myIdList->blockSignals(true);
493   myIdList->clearSelection();
494   myIdList->blockSignals(isBlocked);
495
496   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
497   SALOME_ListIO aSelList;
498   aSelMgr->selectedObjects(aSelList);
499
500   if (aSelList.Extent() != 1)
501     return;
502
503   GEOM::GEOM_Object_var anObj =
504     GEOMBase::ConvertIOinGEOMObject(aSelList.First());
505   if (GEOMBase::IsShape(anObj)) {
506     if (!anObj->_is_equivalent(myMainObj) && !anObj->_is_equivalent(myGroup)) {
507       SUIT_OverrideCursor wc;
508       myEditCurrentArgument->setText(GEOMBase::GetName(anObj));
509       GEOM::GEOM_IShapesOperations_var aShapesOp =
510         getGeomEngine()->GetIShapesOperations(getStudyId());
511       if (subSelectionWay() == GET_IN_PLACE) {
512         GEOM::GEOM_Object_var aGetInPlaceObj = aShapesOp->GetInPlace(myMainObj, anObj);
513         setInPlaceObj(aGetInPlaceObj);
514       }
515       else {
516         bool isVisible = true;
517         if (SALOME_View* view = GEOM_Displayer::GetActiveView())
518           isVisible = view->isVisible(aSelList.First());
519         setInPlaceObj(anObj, isVisible);
520       }
521       myEditCurrentArgument = 0;
522       //myBusy = true; // just activate but do not select in the list
523       activateSelection();
524       //myBusy = false;
525     }
526   }
527 }
528
529 //=================================================================================
530 //function : setInPlaceObj
531 //purpose  : temporarily add an object to study and remove old InPlaceObj
532 //=================================================================================
533 void GroupGUI_GroupDlg::setInPlaceObj(GEOM::GEOM_Object_var theObj, const bool isVisible)
534 {
535   if (!myInPlaceObj->_is_equivalent(theObj))
536   {
537     myInPlaceObj = theObj;
538   }
539
540   // build map of indices
541   myMain2InPlaceIndices.Clear();
542   if (!myInPlaceObj->_is_nil()) {
543     GEOM::GEOM_IShapesOperations_var aShapesOp = getGeomEngine()->GetIShapesOperations(getStudyId());
544     GEOM::GEOM_ILocalOperations_var aLocOp = getGeomEngine()->GetILocalOperations(getStudyId());
545
546     GEOM::ListOfGO_var aSubObjects = aShapesOp->MakeExplode(myInPlaceObj, getShapeType(), false);
547     for ( int i = 0; i < aSubObjects->length(); i++ )
548     {
549       GEOM::ListOfLong_var aCurrList = aShapesOp->GetSameIDs( myMainObj, aSubObjects[i] );
550       if( aCurrList->length() > 1 ) {
551         //rnv : To Fix the 21561: EDF 2184 GEOM: Group with second shape restriction.
552         //      In case if GetSameIDs(...) method return more then one ID use 
553         //      GetSharedShapes(...) method to get sub-shapes of the second shape.
554         GEOM::ListOfGO_var aSubObjects2 = aShapesOp->GetSharedShapes( myMainObj, aSubObjects[i], getShapeType() );
555         for( int j = 0; j < aSubObjects2->length(); j++ ) {
556           CORBA::Long aMainIndex =  aLocOp->GetSubShapeIndex( myMainObj, aSubObjects2[j] );
557           CORBA::Long aPlaceIndex = aLocOp->GetSubShapeIndex( myInPlaceObj, aSubObjects[i]);
558           if ( aMainIndex >= 0 && aPlaceIndex > 0 ) {
559             myMain2InPlaceIndices.Bind( aMainIndex, aPlaceIndex );
560           }
561         }
562       } else if(aCurrList->length() > 0 ) {
563         CORBA::Long aMainIndex = aCurrList[0];
564         CORBA::Long aPlaceIndex = aLocOp->GetSubShapeIndex( myInPlaceObj, aSubObjects[i] );
565         if ( aMainIndex >= 0 && aPlaceIndex > 0) {
566           myMain2InPlaceIndices.Bind( aMainIndex, aPlaceIndex );
567         }
568       }
569     }
570   }
571   myInPlaceObjSelectState = subSelectionWay();
572   if (myInPlaceObjSelectState == SUBSHAPES_OF_SHAPE2 && !isVisible)
573     myInPlaceObjSelectState = SUBSHAPES_OF_INVISIBLE_SHAPE2;
574 }
575
576 //=================================================================================
577 // function : SelectionIntoArgument()
578 // purpose  : Called when selection has changed
579 //=================================================================================
580 void GroupGUI_GroupDlg::SelectionIntoArgument()
581 {
582   if (subSelectionWay() != ALL_SUBSHAPES && myEditCurrentArgument == myShape2Name) {
583     onGetInPlace();
584     if( !myInPlaceObj->_is_nil() ) {
585       mySelBtn2->setDown(false);
586     }
587     return;
588   }
589
590   if (myEditCurrentArgument == myMainName) {  // Selection of a main shape is active
591     myEditCurrentArgument->setText("");
592     myIdList->clear();
593
594     LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
595     SALOME_ListIO aSelList;
596     aSelMgr->selectedObjects(aSelList);
597     int nbSel = aSelList.Extent();
598
599     if (nbSel == 1) {
600       GEOM::GEOM_Object_var anObj =
601         GEOMBase::ConvertIOinGEOMObject(aSelList.First());
602
603       if (GEOMBase::IsShape(anObj)) {
604         if (myIsHiddenMain) {
605           GEOM_Displayer* aDisplayer = getDisplayer();
606           aDisplayer->Display(myMainObj);
607           myIsHiddenMain = false;
608         }
609         myMainObj = anObj;
610         if (!CORBA::is_nil(myMainObj)) {
611           mySelBtn->setDown(false);
612           SALOME_View* view = GEOM_Displayer::GetActiveView();
613           if (view) {
614             CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
615             Handle(SALOME_InteractiveObject) io =
616               new SALOME_InteractiveObject (aMainEntry.in(), "GEOM", "TEMP_IO");
617             if (view->isVisible(io)) myWasHiddenMain = false;
618           }
619         }
620         myEditCurrentArgument->setText(GEOMBase::GetName(anObj));
621         // activate sub-shapes selection by default
622         myEditCurrentArgument = 0;
623         activateSelection();
624         updateState();
625       }
626     }
627     else {
628       if (myIsHiddenMain) {
629         GEOM_Displayer* aDisplayer = getDisplayer();
630         aDisplayer->Display(myMainObj);
631         myIsHiddenMain = false;
632       }
633       myMainObj = GEOM::GEOM_Object::_nil();
634     }
635   }
636   else { // an attempt to synchronize list box selection with 3d viewer
637     if (myBusy || myMainObj->_is_nil()) {
638       return;
639     }
640
641     bool isBlocked = myIdList->signalsBlocked();
642     myIdList->blockSignals(true);
643     myIdList->clearSelection();
644
645     TColStd_IndexedMapOfInteger aMapIndex;
646     int nbSel = getSelectedSubshapes(aMapIndex);
647
648     if (nbSel) {
649       QMap<int, int> aMap;
650       for (int i = 0, n = myIdList->count(); i < n; i++)
651         aMap.insert(myIdList->item(i)->text().toInt(), i);
652
653       bool highlight = false;
654       for (int ii = 1, nn = aMapIndex.Extent(); ii <= nn; ii++) {
655         if (aMap.contains(aMapIndex(ii))) {
656           myIdList->item(aMap[aMapIndex(ii)])->setSelected(true);
657           highlight = true;
658         }
659       }
660       if (highlight)
661         highlightSubShapes();
662     }
663     myIdList->blockSignals(isBlocked);
664
665     updateState(nbSel);
666   }
667 }
668
669 //=================================================================================
670 // function : ConstructorsClicked()
671 // purpose  : Radio button management
672 //=================================================================================
673 void GroupGUI_GroupDlg::ConstructorsClicked(int constructorId)
674 {
675   if (getConstructorId() != constructorId)
676     setConstructorId(constructorId);
677
678   myIsShapeType = true;
679   myIdList->clear();
680   myEditCurrentArgument = 0;
681
682   setInPlaceObj(myInPlaceObj); // to rebuild myMain2InPlaceIndices
683   activateSelection();
684   updateState();
685 }
686
687 //=================================================================================
688 // function : selectAllSubShapes
689 // purpose  :
690 //=================================================================================
691 void GroupGUI_GroupDlg::selectAllSubShapes()
692 {
693   if (CORBA::is_nil(myMainObj) || !myIsShapeType)
694     return;
695
696   GEOM::ListOfLong_var aSubShapes;
697   GEOM::GEOM_IShapesOperations_var aShOp = getGeomEngine()->GetIShapesOperations(getStudyId());
698   aSubShapes = aShOp->SubShapeAllIDs(myMainObj, getShapeType(), false);
699   if (aSubShapes->length() > 0) {
700     if (subSelectionWay() == ALL_SUBSHAPES)
701     {
702 //      myIdList->clear(); // for sorted final list?
703
704       if (!aShOp->IsDone())
705         return;
706     }
707     else
708     {
709       aSubShapes = new GEOM::ListOfLong();
710       aSubShapes->length(myMain2InPlaceIndices.Extent());
711       TColStd_DataMapIteratorOfDataMapOfIntegerInteger m2ip (myMain2InPlaceIndices);
712       for (int i = 0; m2ip.More(); i++, m2ip.Next())
713         aSubShapes[i] = m2ip.Key();
714     }
715
716     bool isBlocked = myIdList->signalsBlocked();
717     myIdList->blockSignals(true);
718
719     for (int i = 0, n = aSubShapes->length(); i < n; i++) {
720       CORBA::Long anIndex = aSubShapes[i];
721       if (anIndex < 0)
722         continue;
723
724       QListWidgetItem* anItem = 0;
725       QString text = QString("%1").arg(anIndex);
726 //      if (!myInPlaceObj->_is_nil()) {
727         QList<QListWidgetItem*> found = myIdList->findItems(text, Qt::MatchExactly);
728         if (found.count()) anItem = found[0];
729 //      }
730       if (!anItem) {
731         anItem = new QListWidgetItem(text);
732         anItem->setTextColor( myGroupIdList.contains(anIndex) ? QColor( GROUP_IDLST_COLOR ) : QColor( GROUP_NEWIDLST_COLOR ) );
733         myIdList->addItem(anItem);
734       }
735       anItem->setSelected(true);
736     }
737
738     myIdList->blockSignals(isBlocked);
739     highlightSubShapes();
740   }
741 }
742
743 //=================================================================================
744 // function : showOnlySelected
745 // purpose  :
746 //=================================================================================
747 void GroupGUI_GroupDlg::showOnlySelected()
748 {
749   if (CORBA::is_nil(myMainObj) || !myIsShapeType)
750     return;
751
752   QPushButton* send = (QPushButton*)sender();
753   if (send == myShowAllBtn) {
754     activateSelection();
755     return;
756   }
757
758   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
759   SALOME_ListIO aSelList;
760   aSelMgr->selectedObjects(aSelList);
761
762   GEOM_Displayer* aDisplayer = getDisplayer();
763
764   if (send == myHideSelBtn) {
765     aDisplayer->Erase(aSelList, /*forced=*/false, /*updateViewer=*/true);
766   }
767   else {
768     // Mantis issue 0021421: do not hide main shape, if explode on VERTEX
769     SALOME_View* view = GEOM_Displayer::GetActiveView();
770     if (view) {
771       CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
772       Handle(SALOME_InteractiveObject) io =
773         new SALOME_InteractiveObject (aMainEntry.in(), "GEOM", "TEMP_IO");
774       if (view->isVisible(io)) myIsHiddenMain = true;
775       
776       //keep the selected entry and IO in the map for checking
777       std::map<QString, Handle(SALOME_InteractiveObject)> aSelEntriesMap;
778       SALOME_ListIteratorOfListIO aSelIt(aSelList);
779       for ( ; aSelIt.More(); aSelIt.Next() ) {
780         Handle(SALOME_InteractiveObject) anSelIO = aSelIt.Value();
781         aSelEntriesMap[anSelIO->getEntry()] = anSelIO;
782       }
783       //get the displayed sub-shapes
784       SALOME_ListIO displayed;
785       view->GetVisible(displayed);
786       // Erase all, except the selected sub-shapes
787       std::map<QString, Handle(SALOME_InteractiveObject)>::iterator 
788         aSelDispIter = aSelEntriesMap.end();
789       SALOME_ListIteratorOfListIO aDispIt( displayed );
790       for ( ; aDispIt.More(); aDispIt.Next() ) {
791         Handle(SALOME_InteractiveObject) anIO = aDispIt.Value();
792         aSelDispIter = aSelEntriesMap.find( anIO->getEntry() );
793         if ( aSelDispIter != aSelEntriesMap.end() ) {
794           //sub-shape is selected, so erase it's record from map to keep in it not displayed, but selected sub-shapes only
795           aSelEntriesMap.erase(aSelDispIter);
796         } else {
797           //sub-shape is not in the map of selected, then erase it from view
798           aDisplayer->Erase( anIO, /*forced = */false, /*updateViewer = */false );
799         }
800       }
801
802       if ( !aSelEntriesMap.empty() ) {
803         // Build a presentation of the selected, but not displayed sub-shapes
804         TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj);
805         TopTools_IndexedMapOfShape aSubShapesMap;
806         TopExp::MapShapes(aMainShape, aSubShapesMap);
807         QString anEntryBase = aMainEntry.in();
808
809         TopExp_Explorer anExp (aMainShape, getShapeType());
810         for (; anExp.More(); anExp.Next()) {
811           TopoDS_Shape aSubShape = anExp.Current();
812           int index = aSubShapesMap.FindIndex(aSubShape);
813           QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index);
814           if ( aSelEntriesMap.find( anEntry ) == aSelEntriesMap.end() ) {
815             //skip not selected sub-shapes
816             continue;
817           }
818           SALOME_Prs* aPrs = aDisplayer->buildSubshapePresentation(aSubShape, anEntry, view);
819           if (aPrs) {
820             displayPreview(aPrs, true, false); // append, do not update
821           }
822         }
823       }
824       aDisplayer->UpdateViewer();
825     }
826
827     // Mantis issue 0021421: do not hide main shape, if explode on VERTEX
828     if (getShapeType() == TopAbs_VERTEX && myIsHiddenMain) {
829       aDisplayer->Display(myMainObj);
830     }
831
832     // for the case when selected ids were not displayed in the viewer: Mantis issue 0021367
833     highlightSubShapes();
834   }
835 }
836
837 //=================================================================================
838 // function : getSelectedSubshapes
839 // purpose  :
840 //=================================================================================
841 int GroupGUI_GroupDlg::getSelectedSubshapes (TColStd_IndexedMapOfInteger& theMapIndex)
842 {
843   theMapIndex.Clear();
844
845   SalomeApp_Application* app = myGeomGUI->getApp();
846   if (!app || myMainObj->_is_nil())
847     return 0;
848
849   LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
850   SALOME_ListIO aSelList;
851   aSelMgr->selectedObjects(aSelList);
852
853   // try to find out and process the global selection
854   // (of not published objects and of published sub-shapes)
855   {
856     SALOME_ListIteratorOfListIO anIter (aSelList);
857     for (int i = 0; anIter.More(); anIter.Next(), i++)
858     {
859       Handle(SALOME_InteractiveObject) anIObj = anIter.Value();
860       QString anEntry = anIObj->getEntry();
861       QString str = "_";
862       int index = anEntry.lastIndexOf(str);
863       if (index > 0) // selection among special preview
864       {
865         anEntry.remove(0, index+1);
866         int anIndex = anEntry.toInt();
867         if (anIndex)
868           theMapIndex.Add(anIndex);
869       }
870       else // selection among published shapes
871       {
872         SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
873         if (!appStudy) return 0;
874         _PTR(Study) aStudy = appStudy->studyDS();
875
876         _PTR(SObject) aSObj (aStudy->FindObjectID(anEntry.toLatin1().constData()));
877         GEOM::GEOM_Object_var aGeomObj =
878           GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(aSObj));
879         TopoDS_Shape aShape;
880         if (GEOMBase::GetShape(aGeomObj, aShape)) {
881           if (aGeomObj->GetType() == GEOM_GROUP || aShape.ShapeType() == getShapeType()) {
882             TopTools_IndexedMapOfShape aMainMap;
883             TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj);
884             TopExp::MapShapes(aMainShape, aMainMap);
885
886             TopExp_Explorer anExp (aShape, getShapeType());
887             bool isShowWarning = true;
888             for (; anExp.More(); anExp.Next()) {
889               TopoDS_Shape aSubShape = anExp.Current();
890               int anIndex = aMainMap.FindIndex(aSubShape);
891               if (anIndex == 0) {
892                 if (isShowWarning) {
893                   SUIT_MessageBox::warning(app->desktop(), QObject::tr("WRN_WARNING"),
894                                          tr("WRN_NOT_SUBSHAPE"));
895                   isShowWarning = false;
896                 }
897               }
898               else {
899                 if (subSelectionWay() != ALL_SUBSHAPES &&
900                     !myMain2InPlaceIndices.IsBound(anIndex))
901                   continue;
902                 theMapIndex.Add(anIndex);
903               }
904             }
905           }
906         }
907       }
908     } // for aSelList
909   }
910
911   return theMapIndex.Extent();
912 }
913
914 //=================================================================================
915 // function : add
916 // purpose  :
917 //=================================================================================
918 void GroupGUI_GroupDlg::add()
919 {
920   TColStd_IndexedMapOfInteger aMapIndex;
921   int nbSel = getSelectedSubshapes(aMapIndex);
922
923   TColStd_MapOfInteger aMap;
924   for (int i = 0, n = myIdList->count(); i < n; i++)
925     aMap.Add(myIdList->item(i)->text().toInt());
926
927   if (nbSel > 0) {
928     bool isBlocked = myIdList->signalsBlocked();
929     myIdList->blockSignals(true);
930
931     for (int i = 1, n = aMapIndex.Extent(); i <= n; i++) {
932       if (aMap.Contains(aMapIndex(i)))
933         continue;
934
935       QListWidgetItem* anItem = new QListWidgetItem(QString("%1").arg(aMapIndex(i)));
936       anItem->setTextColor( myGroupIdList.contains( aMapIndex( i ) ) ? QColor( GROUP_IDLST_COLOR ) : QColor( GROUP_NEWIDLST_COLOR ) );
937       myIdList->addItem(anItem);
938       anItem->setSelected(true);
939     }
940
941     myIdList->blockSignals(isBlocked);
942   }
943
944   updateState();
945 }
946
947 //=================================================================================
948 // function : remove
949 // purpose  :
950 //=================================================================================
951 void GroupGUI_GroupDlg::remove()
952 {
953   bool isBlocked = myIdList->signalsBlocked();
954   myIdList->blockSignals(true);
955
956   QListIterator<QListWidgetItem*> it (myIdList->selectedItems());
957   while (it.hasNext())
958     delete it.next();
959
960   myIdList->blockSignals(isBlocked);
961
962   highlightSubShapes();
963 }
964
965 //=================================================================================
966 //function : subSelectionWay
967 //purpose  :
968 //=================================================================================
969 int GroupGUI_GroupDlg::subSelectionWay() const
970 {
971   return myRestrictGroup->checkedId();
972 }
973
974 //=================================================================================
975 // function : getShapeType()
976 // purpose  :
977 //=================================================================================
978 TopAbs_ShapeEnum GroupGUI_GroupDlg::getShapeType() const
979 {
980   switch (getConstructorId()) {
981   case 0:  return TopAbs_VERTEX;
982   case 1:  return TopAbs_EDGE;
983   case 2:  return TopAbs_FACE;
984   case 3:  return TopAbs_SOLID;
985   default: return TopAbs_SHAPE;
986   }
987 }
988
989 //=================================================================================
990 // function : setShapeType()
991 // purpose  :
992 //=================================================================================
993 void GroupGUI_GroupDlg::setShapeType(const TopAbs_ShapeEnum theType)
994 {
995   int anId = 0;
996   switch (theType) {
997   case TopAbs_VERTEX: anId = 0; break;
998   case TopAbs_EDGE:   anId = 1; break;
999   case TopAbs_FACE:   anId = 2; break;
1000   case TopAbs_SOLID:  anId = 3; break;
1001   }
1002   setConstructorId(anId);
1003   if (!myIsShapeType)
1004   {
1005     myIsShapeType = true;
1006     // workaround to avoid set checked button 0
1007     setConstructorId(anId);
1008   }
1009 }
1010
1011 //=================================================================================
1012 // function : activateSelection
1013 // purpose  : Activate selection in accordance with myEditCurrentArgument
1014 //=================================================================================
1015 void GroupGUI_GroupDlg::activateSelection()
1016 {
1017   bool isApply = ((QPushButton*)sender() == buttonApply());
1018   if(!isApplyAndClose())
1019     erasePreview(false);
1020
1021   // local selection
1022   if (!myMainObj->_is_nil() &&
1023       !myEditCurrentArgument &&
1024       myIsShapeType) // check if shape type is already choosen by user
1025   {
1026     GEOM_Displayer* aDisplayer = getDisplayer();
1027
1028     //display mode for main shape
1029     if ( myDmMode == -1 ) {
1030     SALOME_View* view = GEOM_Displayer::GetActiveView();
1031       if (view) {
1032         CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
1033         Handle(SALOME_InteractiveObject) io =
1034           new SALOME_InteractiveObject (aMainEntry.in(), "GEOM", "TEMP_IO");
1035         if ( view->isVisible( io ) ) {
1036           Handle(GEOM_AISShape) aSh = GEOMBase::ConvertIOinGEOMAISShape( io, true );
1037           if(!aSh.IsNull()) {
1038             myDmMode = aSh->isTopLevel() ? aSh->prevDisplayMode() : aSh->DisplayMode();
1039           }
1040         }
1041         else
1042           myDmMode = SUIT_Session::session()->resourceMgr()->integerValue( "Geometry", "display_mode" );
1043       }
1044     }
1045     aDisplayer->SetDisplayMode(myDmMode);
1046
1047     // Mantis issue 0021421: do not hide main shape, if explode on VERTEX
1048     if(getShapeType() != TopAbs_VERTEX) {
1049       aDisplayer->Erase(myMainObj, false, false);
1050       myIsHiddenMain = true;
1051     }
1052     else
1053       aDisplayer->Display(myMainObj);
1054
1055     aDisplayer->Erase(myGroup, false, false);
1056
1057     QColor aColor = SUIT_Session::session()->resourceMgr()->colorValue( "Geometry", "editgroup_color" );
1058     Quantity_NameOfColor aCol = SalomeApp_Tools::color( aColor ).Name();
1059
1060     if(!isApplyAndClose()) {
1061       SUIT_ViewWindow* aViewWindow = 0;
1062       SUIT_Study* activeStudy = SUIT_Session::session()->activeApplication()->activeStudy();
1063       if (activeStudy)
1064         aViewWindow = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
1065       if (aViewWindow == 0) return;
1066
1067       SUIT_ViewManager* aViewManager = aViewWindow->getViewManager();
1068       if (aViewManager->getType() != OCCViewer_Viewer::Type() &&
1069           aViewManager->getType() != SVTK_Viewer::Type())
1070         return;
1071
1072       SUIT_ViewModel* aViewModel = aViewManager->getViewModel();
1073       SALOME_View* aView = dynamic_cast<SALOME_View*>(aViewModel);
1074       if (aView == 0) return;
1075
1076       TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj);
1077       TopoDS_Shape aRestrictionShape;
1078
1079       if (subSelectionWay() == ALL_SUBSHAPES) {
1080         aRestrictionShape = aMainShape;
1081
1082         TopTools_IndexedMapOfShape aSubShapesMap;
1083         TopExp::MapShapes(aMainShape, aSubShapesMap);
1084         CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
1085         QString anEntryBase = aMainEntry.in();
1086
1087         TopExp_Explorer anExp (aRestrictionShape, getShapeType());
1088         for (; anExp.More(); anExp.Next()) {
1089           TopoDS_Shape aSubShape = anExp.Current();
1090           int index = aSubShapesMap.FindIndex(aSubShape);
1091           QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index);
1092           Handle(SALOME_InteractiveObject) io =
1093             new SALOME_InteractiveObject(anEntry.toAscii(), "GEOM", "TEMP_IO");
1094           if ( myGroupIdList.contains( index ) ) {
1095             aDisplayer->SetColor( aCol );
1096           }
1097           else {
1098             aDisplayer->UnsetColor();
1099           }
1100           SALOME_Prs* aPrs = aDisplayer->buildSubshapePresentation(aSubShape, anEntry, aView);
1101           if (aPrs) {
1102             displayPreview(aPrs, true, false); // append, do not update
1103             // TODO: map or delete Prs
1104           }
1105         }
1106       }
1107       else if (!myInPlaceObj->_is_nil()) {
1108         TopTools_IndexedMapOfShape aSubShapesMap;
1109         TopExp::MapShapes(aMainShape, aSubShapesMap);
1110         CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
1111         QString anEntryBase = aMainEntry.in();
1112
1113         TColStd_DataMapIteratorOfDataMapOfIntegerInteger aM2IPit (myMain2InPlaceIndices);
1114         for (; aM2IPit.More(); aM2IPit.Next()) {
1115           int index = aM2IPit.Key();
1116           TopoDS_Shape aSubShape = aSubShapesMap.FindKey(index);
1117           QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index);
1118
1119           if ( myGroupIdList.contains( index ) ) {
1120             aDisplayer->SetColor( aCol );
1121           }
1122           else {
1123             aDisplayer->UnsetColor();
1124           }
1125
1126           SALOME_Prs* aPrs = aDisplayer->buildSubshapePresentation(aSubShape, anEntry, aView);
1127           if (aPrs) {
1128             displayPreview(aPrs, true, false); // append, do not update
1129           }
1130         }
1131       }
1132       else ;
1133       aDisplayer->UnsetDisplayMode();
1134       aDisplayer->UnsetColor();
1135       aDisplayer->UpdateViewer();
1136     }
1137   }
1138
1139   globalSelection(GEOM_ALLSHAPES);
1140
1141   SelectionIntoArgument();
1142 }
1143
1144 //=================================================================================
1145 // function : updateState
1146 // purpose  :
1147 //=================================================================================
1148 void GroupGUI_GroupDlg::updateState (bool isAdd)
1149 {
1150   myAddBtn->setEnabled(!myEditCurrentArgument && !CORBA::is_nil(myMainObj) && isAdd);
1151   //myShowOnlyBtn->setEnabled(!myEditCurrentArgument && !CORBA::is_nil(myMainObj) && isAdd);
1152
1153   bool hasSel = myIdList->selectedItems().count() > 0;
1154
1155   myRemBtn->setEnabled(hasSel);
1156   myRestrictGroupBox->setEnabled(!CORBA::is_nil(myMainObj));
1157   mySelAllBtn->setEnabled(!CORBA::is_nil(myMainObj));
1158   
1159   mySelBtn2->setEnabled(subSelectionWay() != ALL_SUBSHAPES);
1160   myShape2Name->setEnabled(subSelectionWay() != ALL_SUBSHAPES);
1161   myFilterGrp->setEnabled(!CORBA::is_nil(myMainObj) &&
1162                           subSelectionWay() == ALL_SUBSHAPES &&
1163                           myIsShapeType &&
1164                           getShapeType() != TopAbs_VERTEX);
1165   // manage of 'Plot' button access
1166   GEOM::GEOM_IShapesOperations_var aShOp = getGeomEngine()->GetIShapesOperations( getStudyId() );
1167   GEOM::ListOfLong_var aSubShapes = aShOp->SubShapeAllIDs( myMainObj, getShapeType(), false );
1168   bool hasCurrentEntities = aSubShapes->length() > 0;
1169 #ifndef DISABLE_PLOT2DVIEWER
1170   myPlotDistributionButton->setEnabled( myFilterGrp->isEnabled() &&
1171                                         myIsShapeType &&
1172                                         ( getShapeType() == TopAbs_EDGE || 
1173                                           getShapeType() == TopAbs_FACE ||
1174                                           getShapeType() == TopAbs_SOLID ) &&
1175                                         hasCurrentEntities );
1176 #endif
1177   if (subSelectionWay() == ALL_SUBSHAPES)
1178     setInPlaceObj(GEOM::GEOM_Object::_nil());
1179 }
1180
1181 //=================================================================================
1182 // function : selectionChanged
1183 // purpose  :
1184 //=================================================================================
1185 void GroupGUI_GroupDlg::selectionChanged()
1186 {
1187   highlightSubShapes();
1188 }
1189
1190 //=================================================================================
1191 // function : highlightSubShapes
1192 // purpose  :
1193 //=================================================================================
1194 void GroupGUI_GroupDlg::highlightSubShapes()
1195 {
1196   if (CORBA::is_nil(myMainObj))
1197     return;
1198
1199   TColStd_MapOfInteger anIds;
1200
1201   myBusy = true;
1202
1203   int ii = 0, nn = myIdList->count();
1204   for (; ii < nn; ii++)
1205   {
1206     if (myIdList->item(ii)->isSelected()) {
1207       int id = myIdList->item(ii)->text().toInt();
1208       if (subSelectionWay() != ALL_SUBSHAPES &&
1209           !myMain2InPlaceIndices.IsBound(id)) {
1210         //myIdList->item(ii)->setSelected(false);
1211       }
1212       else {
1213         anIds.Add(id);
1214       }
1215     }
1216   }
1217   SalomeApp_Application* app = myGeomGUI->getApp();
1218   LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
1219   aSelMgr->clearSelected();
1220
1221   SUIT_ViewWindow* aViewWindow = 0;
1222   SUIT_Study* activeStudy = app->activeStudy();
1223   if (activeStudy)
1224     aViewWindow = app->desktop()->activeWindow();
1225   if (aViewWindow == 0) return;
1226
1227   SUIT_ViewManager* aViewManager = aViewWindow->getViewManager();
1228   if (aViewManager->getType() != OCCViewer_Viewer::Type() &&
1229       aViewManager->getType() != SVTK_Viewer::Type())
1230     return;
1231
1232   SUIT_ViewModel* aViewModel = aViewManager->getViewModel();
1233   SALOME_View* aView = dynamic_cast<SALOME_View*>(aViewModel);
1234   if (aView == 0) return;
1235
1236   // TODO??: use here GEOMBase_Helper::myPreview instead of ic->DisplayedObjects()
1237
1238   OCCViewer_Viewer* v3d = ((OCCViewer_ViewManager*)aViewManager)->getOCCViewer();
1239   Handle(AIS_InteractiveContext) ic = v3d->getAISContext();
1240   AIS_ListOfInteractive List;
1241   //ic->DisplayedObjects(List);
1242   ic->ObjectsInside(List); // Mantis issue 0021367
1243
1244   SALOME_ListIO aSelList;
1245
1246   // To highlight the selected sub-shape in Object Browser, if it's already published under the main shape
1247   GEOM::GEOM_ILocalOperations_var aLocOp = getGeomEngine()->GetILocalOperations(getStudyId());
1248   QMap<int, QString> childsMap;
1249   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
1250   if (appStudy) {
1251     _PTR(Study) aStudy = appStudy->studyDS();
1252     CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
1253     QString anEntry = aMainEntry.in();
1254     _PTR(SObject) aSObj (aStudy->FindObjectID(anEntry.toLatin1().constData()));
1255     _PTR(ChildIterator) anIt (aStudy->NewChildIterator(aSObj));
1256     for (anIt->InitEx(true); anIt->More(); anIt->Next()) {
1257       GEOM::GEOM_Object_var aChild = GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(anIt->Value()));
1258       if (!CORBA::is_nil(aChild)) {
1259         int index = aLocOp->GetSubShapeIndex(myMainObj, aChild);
1260         CORBA::String_var aChildEntry = aChild->GetStudyEntry();
1261         QString anEntry = aChildEntry.in();
1262         childsMap.insert(index, anEntry);
1263       }
1264     }
1265   }
1266
1267   AIS_ListIteratorOfListOfInteractive ite (List);
1268   for (; ite.More(); ite.Next()) {
1269     if (ite.Value()->IsInstance(STANDARD_TYPE(GEOM_AISShape))) {
1270       Handle(GEOM_AISShape) aSh = Handle(GEOM_AISShape)::DownCast(ite.Value());
1271       if (aSh->hasIO()) {
1272         Handle(SALOME_InteractiveObject) anIO = aSh->getIO();
1273         QString anEntry = anIO->getEntry();
1274         int index = anEntry.lastIndexOf("_");
1275         anEntry.remove(0, index+1);
1276         int anIndex = anEntry.toInt();
1277         if (anIds.Contains(anIndex)) {
1278           aSelList.Append(anIO);
1279           if (childsMap.contains (anIndex)) {
1280             Handle(SALOME_InteractiveObject) tmpIO = new SALOME_InteractiveObject(childsMap.value(anIndex).toLatin1().constData(), "GEOM", "TEMP_IO");
1281             aSelList.Append(tmpIO);
1282           }
1283         }
1284       }
1285     }
1286   }
1287   aSelMgr->setSelectedObjects(aSelList);
1288
1289   myBusy = false;
1290
1291   if (nn < 3000)
1292     updateState(aSelList.Extent() > 0);
1293   else {
1294     myAddBtn->setEnabled(true);
1295     myAddBtn->setEnabled(true);
1296     myRemBtn->setEnabled(true);
1297   }
1298 }
1299
1300 //=================================================================================
1301 // function : createOperation
1302 // purpose  :
1303 //=================================================================================
1304 GEOM::GEOM_IOperations_ptr GroupGUI_GroupDlg::createOperation()
1305 {
1306   return getGeomEngine()->GetIGroupOperations(getStudyId());
1307 }
1308
1309 #define RETURN_WITH_MSG(a, b) \
1310   if (!(a)) { \
1311     theMessage += (b); \
1312     return false; \
1313   }
1314
1315 //=================================================================================
1316 // function : isValid()
1317 // purpose  : Verify validity of input data
1318 //=================================================================================
1319 bool GroupGUI_GroupDlg::isValid(QString& theMessage)
1320 {
1321   SalomeApp_Study* study = getStudy();
1322   ASSERT(study);
1323   RETURN_WITH_MSG  (!study->studyDS()->GetProperties()->IsLocked(), tr("GEOM_STUDY_LOCKED"))
1324
1325   if (myMode == CreateGroup) {
1326     RETURN_WITH_MSG(!CORBA::is_nil(myMainObj), tr("NO_MAIN_OBJ"))
1327   }
1328   else {
1329     RETURN_WITH_MSG(!CORBA::is_nil(myMainObj), tr("NO_GROUP"))
1330   }
1331
1332   QString aName (getNewObjectName());
1333   RETURN_WITH_MSG  (!aName.trimmed().isEmpty(), tr("EMPTY_NAME"))
1334
1335   RETURN_WITH_MSG  (myIdList->count(), tr("EMPTY_LIST"))
1336   return true;
1337 }
1338
1339 //=================================================================================
1340 // function : execute
1341 // purpose  :
1342 //=================================================================================
1343 bool GroupGUI_GroupDlg::execute(ObjectList& objects)
1344 {
1345   GEOM::GEOM_IGroupOperations_var anOper = GEOM::GEOM_IGroupOperations::_narrow(getOperation());
1346
1347   GEOM::GEOM_Object_var aGroup;
1348   if (myMode == CreateGroup)
1349     aGroup = anOper->CreateGroup(myMainObj, getShapeType());
1350   else if (myMode == EditGroup)
1351     aGroup = myGroup;
1352
1353   if (CORBA::is_nil(aGroup) || (myMode == CreateGroup && !anOper->IsDone()))
1354     return false;
1355
1356   GEOM::ListOfLong_var aCurrList = anOper->GetObjects(aGroup);
1357   if (!anOper->IsDone())
1358     return false;
1359
1360   if (aCurrList->length() > 0)
1361   {
1362     anOper->DifferenceIDs(aGroup, aCurrList);
1363     if (!anOper->IsDone())
1364       return false;
1365   }
1366
1367   int ii, nn = myIdList->count();
1368   if (nn > 0)
1369   {
1370     GEOM::ListOfLong_var aNewList = new GEOM::ListOfLong;
1371     aNewList->length(nn);
1372     for (ii = 0; ii < nn; ii++) {
1373       aNewList[ii] = myIdList->item(ii)->text().toInt();
1374     }
1375     anOper->UnionIDs(aGroup, aNewList);
1376     if (!anOper->IsDone())
1377       return false;
1378   }
1379
1380   SalomeApp_Study* study = getStudy();
1381   if (study) {
1382     QString objIOR = GEOMBase::GetIORFromObject(aGroup);
1383     if (objIOR != "") {
1384       _PTR(SObject) SO (study->studyDS()->FindObjectIOR(objIOR.toLatin1().constData()));
1385       if (SO) {
1386         _PTR(StudyBuilder) aBuilder (study->studyDS()->NewBuilder());
1387         aBuilder->SetName(SO, getNewObjectName().toLatin1().constData());
1388       }
1389     }
1390   }
1391
1392   objects.push_back(aGroup._retn());
1393
1394   return true;
1395 }
1396
1397 //================================================================
1398 // Function : getFather
1399 // Purpose  : Get father object for object to be added in study
1400 //            (called with addInStudy method)
1401 //================================================================
1402 GEOM::GEOM_Object_ptr GroupGUI_GroupDlg::getFather(GEOM::GEOM_Object_ptr theObj)
1403 {
1404   GEOM::GEOM_Object_var aFatherObj;
1405   if (theObj->GetType() == GEOM_GROUP) {
1406     GEOM::GEOM_IGroupOperations_var anOper = GEOM::GEOM_IGroupOperations::_narrow(getOperation());
1407     aFatherObj = anOper->GetMainShape(theObj);
1408   }
1409   return aFatherObj._retn();
1410 }
1411
1412 void GroupGUI_GroupDlg::ClickOnOkFilter()
1413 {
1414   if (CORBA::is_nil(myMainObj) || subSelectionWay() != ALL_SUBSHAPES || !myIsShapeType || getShapeType() == TopAbs_VERTEX)
1415     return;
1416   
1417   TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj);
1418   TopTools_IndexedMapOfShape aSubShapesMap;
1419   TopExp::MapShapes(aMainShape, aSubShapesMap);
1420   SALOME_View* view = GEOM_Displayer::GetActiveView();
1421   getDisplayer()->Erase(myMainObj, false, false);
1422   CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
1423   QString anEntryBase = aMainEntry.in();
1424
1425   SALOME_ListIO toSelect;
1426
1427   TopExp_Explorer anExp (aMainShape, (TopAbs_ShapeEnum)getShapeType());
1428   for (; anExp.More(); anExp.Next())
1429   {
1430     TopoDS_Shape aSubShape = anExp.Current();
1431     int index = aSubShapesMap.FindIndex(aSubShape);
1432     QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index);
1433     if ( !getDisplayer()->IsDisplayed( anEntry ) )
1434       continue;
1435
1436     double factor = GEOMUtils::ShapeToDouble(aSubShape).second;
1437     double v1 = myLessFilterSpin->value();
1438     double v2 = myGreaterFilterSpin->value();
1439     bool isLess = myLessFilterCombo->itemData(myLessFilterCombo->currentIndex()).toInt() == Filter_LT ? factor < v1 : factor <= v1;
1440     bool isGreater = myGreaterFilterCombo->itemData(myGreaterFilterCombo->currentIndex()).toInt() == Filter_GT ? factor > v2 : factor >= v2;
1441     if ( ( myLessFilterCheck->isChecked() && myGreaterFilterCheck->isChecked() && isLess && isGreater ) ||
1442          ( myLessFilterCheck->isChecked() && !myGreaterFilterCheck->isChecked() && isLess ) ||
1443          ( myGreaterFilterCheck->isChecked() && !myLessFilterCheck->isChecked() && isGreater ) ) {
1444       Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject();
1445       io->setEntry( anEntry.toLatin1().constData() );
1446       toSelect.Append(io);
1447     }
1448   }
1449   if ( toSelect.Extent() > 0 ) {
1450     myGeomGUI->getApp()->selectionMgr()->setSelectedObjects(toSelect);
1451     SUIT_MessageBox::information( this,
1452                                   tr( "INF_INFO" ),
1453                                   tr( "GEOM_SOME_SHAPES_SELECTED").arg( toSelect.Extent() ),
1454                                   tr( "BUT_OK" ) );
1455   }
1456   else {
1457     SUIT_MessageBox::information( this,
1458                                   tr( "INF_INFO" ),
1459                                   tr( "GEOM_NO_SHAPES_SELECTED" ),
1460                                   tr( "BUT_OK" ) );
1461   }
1462   updateState(true);
1463 }
1464
1465 #ifndef DISABLE_PLOT2DVIEWER
1466 //=================================================================================
1467 // function : ClickOnPlot()
1468 // purpose  : opens "Shape Statistics" dialog box in order to plot sub-shapes distribution.
1469 //=================================================================================
1470 void GroupGUI_GroupDlg::ClickOnPlot()
1471 {
1472   TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj);
1473   QDialog* dlg = new MeasureGUI_ShapeStatisticsDlg( this, aMainShape, getShapeType() );
1474   if ( dlg ) {
1475     dlg->show();
1476   }
1477 }
1478 #endif
1479
1480 void GroupGUI_GroupDlg::MeasureToggled()
1481 {
1482   myLessFilterSpin->setEnabled(myLessFilterCheck->isChecked());
1483   myLessFilterCombo->setEnabled(myLessFilterCheck->isChecked());
1484   myGreaterFilterSpin->setEnabled(myGreaterFilterCheck->isChecked());
1485   myGreaterFilterCombo->setEnabled(myGreaterFilterCheck->isChecked());
1486   myApplyFilterButton->setEnabled(myLessFilterCheck->isChecked() || myGreaterFilterCheck->isChecked());
1487 }
1488
1489 //=================================================================================
1490 // function : getSourceObjects
1491 // purpose  : virtual method to get source objects
1492 //=================================================================================
1493 QList<GEOM::GeomObjPtr> GroupGUI_GroupDlg::getSourceObjects()
1494 {
1495   QList<GEOM::GeomObjPtr> res;
1496   GEOM::GeomObjPtr aGeomObjPtr1(myMainObj), aGeomObjPtr2(myInPlaceObj);
1497   res << aGeomObjPtr1 << aGeomObjPtr2;
1498   return res;
1499 }