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