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