]> SALOME platform Git repositories - modules/geom.git/blob - src/GroupGUI/GroupGUI_GroupDlg.cxx
Salome HOME
IPAL21294 Change Orientation for Vector with "Create a Copy" creates an Edge.
[modules/geom.git] / src / GroupGUI / GroupGUI_GroupDlg.cxx
1 //  Copyright (C) 2007-2008  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.
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 // GEOM GEOMGUI : GUI for Geometry component
23 // File   : GroupGUI_GroupDlg.cxx
24 // Author : Sergey ANIKIN, Open CASCADE S.A.S. (sergey.anikin@opencascade.com)
25 //
26 #include "GroupGUI_GroupDlg.h"
27
28 #include <LightApp_SelectionMgr.h>
29 #include <SUIT_ResourceMgr.h>
30 #include <SUIT_Desktop.h>
31 #include <SUIT_OverrideCursor.h>
32 #include <SUIT_Session.h>
33 #include <SalomeApp_Application.h>
34 #include <SalomeApp_Study.h>
35
36 #include <DlgRef.h>
37 #include <GEOMBase.h>
38 #include <GeometryGUI.h>
39 #include <GEOMImpl_Types.hxx>
40 #include <GEOM_Displayer.h>
41
42 #include <QLabel>
43 #include <QListWidget>
44 #include <QLineEdit>
45 #include <QMap>
46
47 #include <TColStd_IndexedMapOfInteger.hxx>
48 #include <TColStd_MapOfInteger.hxx>
49 #include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
50
51 enum { ALL_SUBSHAPES = 0, GET_IN_PLACE, SUBSHAPES_OF_SHAPE2, SUBSHAPES_OF_INVISIBLE_SHAPE2 };
52
53 GroupGUI_GroupDlg::GroupGUI_GroupDlg( Mode mode, GeometryGUI* theGeometryGUI, QWidget* parent )
54   : GEOMBase_Skeleton( theGeometryGUI, parent, false ),
55     myMode( mode ),
56     myBusy( false ),
57     myIsShapeType( false )
58 {
59   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
60
61   QPixmap image0     ( resMgr->loadPixmap( "GEOM", tr( "ICON_OBJBROWSER_VERTEX" ) ) );
62   QPixmap image1     ( resMgr->loadPixmap( "GEOM", tr( "ICON_OBJBROWSER_EDGE" ) ) );
63   QPixmap image2     ( resMgr->loadPixmap( "GEOM", tr( "ICON_OBJBROWSER_FACE" ) ) );
64   QPixmap image3     ( resMgr->loadPixmap( "GEOM", tr( "ICON_OBJBROWSER_SOLID" ) ) );
65   QPixmap iconSelect ( resMgr->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) );
66
67   setWindowTitle( myMode == CreateGroup ? tr( "CREATE_GROUP_TITLE" ) : tr( "EDIT_GROUP_TITLE" ) );
68
69   // Shape type button group
70   mainFrame()->GroupConstructors->setEnabled( myMode == CreateGroup );
71   mainFrame()->GroupConstructors->setTitle( tr( "SHAPE_TYPE" ) );
72   mainFrame()->RadioButton1->setIcon( image0 );
73   mainFrame()->RadioButton2->setIcon( image1 );
74   mainFrame()->RadioButton3->setIcon( image2 );
75   mainFrame()->RadioButton4->setIcon( image3 );
76   mainFrame()->RadioButton4->show();
77
78   // Group name
79   mainFrame()->GroupBoxName->setTitle( tr( "GROUP_NAME" ) );
80
81   // Main shape and sub-shapes
82   QGroupBox* GroupMedium = new QGroupBox( tr( "MAIN_SUB_SHAPES" ), centralWidget() );
83   QGridLayout* aMedLayout = new QGridLayout( GroupMedium );
84   aMedLayout->setMargin( 9 );
85   aMedLayout->setSpacing( 6 );
86   
87   QLabel* aMainLabel = new QLabel( tr( "MAIN_SHAPE" ), GroupMedium );
88
89   mySelBtn = new QPushButton( GroupMedium );
90   mySelBtn->setIcon( iconSelect );
91   mySelBtn->setEnabled( myMode == CreateGroup );
92
93   myMainName = new QLineEdit( GroupMedium );
94   myMainName->setReadOnly( true );
95   myMainName->setEnabled( myMode == CreateGroup );
96
97   QLabel* aSecondLabel = new QLabel( tr( "SECOND_SHAPE" ), GroupMedium );
98
99   mySelBtn2 = new QPushButton( GroupMedium );
100   mySelBtn2->setIcon( iconSelect );
101   mySelBtn2->setEnabled( false );
102
103   myShape2Name = new QLineEdit( GroupMedium );
104   myShape2Name->setReadOnly( true );
105   myShape2Name->setEnabled( false );
106
107   mySelectionWayGroupBox = new QGroupBox( tr("SHAPE_SEL_RESTR"), GroupMedium );
108   mySelectionWayGroup = new QButtonGroup( mySelectionWayGroupBox );
109   QRadioButton* allSubs     = new QRadioButton( tr( "NO_RESTR" )            , mySelectionWayGroupBox );
110   QRadioButton* inPlaceSubs = new QRadioButton( tr( "GEOM_PARTS_OF_SHAPE2" ), mySelectionWayGroupBox );
111   QRadioButton* shape2Subs  = new QRadioButton( tr( "SUBSHAPES_OF_SHAPE2" ) , mySelectionWayGroupBox );
112   QVBoxLayout* mySelWayLayout = new QVBoxLayout( mySelectionWayGroupBox );
113   mySelWayLayout->setMargin( 9 );
114   mySelWayLayout->setSpacing( 6 );
115   mySelWayLayout->addWidget( allSubs );
116   mySelWayLayout->addWidget( inPlaceSubs );
117   mySelWayLayout->addWidget( shape2Subs );
118   mySelectionWayGroup->addButton( allSubs,     ALL_SUBSHAPES );
119   mySelectionWayGroup->addButton( inPlaceSubs, GET_IN_PLACE );
120   mySelectionWayGroup->addButton( shape2Subs,  SUBSHAPES_OF_SHAPE2 );
121   allSubs->setChecked( true );
122
123   mySelAllBtn = new QPushButton( tr( "SELECT_ALL" ), GroupMedium );
124   myAddBtn    = new QPushButton( tr( "ADD" ), GroupMedium );
125   myRemBtn    = new QPushButton( tr( "REMOVE" ), GroupMedium );
126   myIdList    = new QListWidget( GroupMedium );
127
128   myIdList->setSelectionMode( QAbstractItemView::ExtendedSelection );
129   myIdList->setFlow( QListView::TopToBottom );
130   myIdList->setWrapping( true );
131
132   aMedLayout->addWidget( aMainLabel,             0, 0 );
133   aMedLayout->addWidget( mySelBtn,               0, 1 );
134   aMedLayout->addWidget( myMainName,             0, 2, 1, 2 );
135   aMedLayout->addWidget( aSecondLabel,           1, 0 );
136   aMedLayout->addWidget( mySelBtn2,              1, 1 );
137   aMedLayout->addWidget( myShape2Name,           1, 2, 1, 2 );
138   aMedLayout->addWidget( mySelectionWayGroupBox, 2, 0, 3, 3 );
139   aMedLayout->addWidget( mySelAllBtn,            2, 3 );
140   aMedLayout->addWidget( myAddBtn,               3, 3 );
141   aMedLayout->addWidget( myRemBtn,               4, 3 );
142   aMedLayout->addWidget( myIdList,               5, 0, 1, 4 );
143   aMedLayout->setRowStretch( 5, 1 );
144
145   QVBoxLayout* layout = new QVBoxLayout( centralWidget() );
146   layout->setMargin( 0 ); layout->setSpacing( 6 );
147   layout->addWidget( GroupMedium );
148
149   setHelpFileName( "work_with_groups_page.html" );
150
151   Init();
152 }
153
154 GroupGUI_GroupDlg::~GroupGUI_GroupDlg()
155 {
156 }
157
158 //=================================================================================
159 // function : Init()
160 // purpose  :
161 //=================================================================================
162 void GroupGUI_GroupDlg::Init()
163 {
164   // san -- TODO: clear selected sub-shapes...
165   //mySelSubBtn->setChecked( true );
166   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
167
168   //unset shape type to avoid preparation of selection before exact user shape type selection
169   //setConstructorId( -1 ); //non valid shape type
170   unsetConstructorId();
171   myIsShapeType = false;
172
173   if ( myMode == CreateGroup ) {
174     initName( tr( "GROUP_PREFIX" ) );
175
176     // Get ready for main shape selection
177     myEditCurrentArgument = myMainName;
178
179     connect( this, SIGNAL( constructorsClicked( int ) ),  this, SLOT( ConstructorsClicked( int ) ) );
180     connect( mySelBtn,          SIGNAL( clicked() ),      this, SLOT( SetEditCurrentArgument() ) );
181     connect( mySelBtn2,         SIGNAL( clicked() ),      this, SLOT( SetEditCurrentArgument() ) );
182   }
183   else if (myMode == EditGroup) {
184     SALOME_ListIO aSelList;
185     aSelMgr->selectedObjects(aSelList);
186
187     if (aSelList.Extent()) {
188       Standard_Boolean aResult = Standard_False;
189       GEOM::GEOM_Object_var anObj =
190         GEOMBase::ConvertIOinGEOMObject(aSelList.First(), aResult);
191
192       if ( aResult && !CORBA::is_nil( anObj ) && anObj->GetType() == GEOM_GROUP ) {
193         myGroup = anObj;
194
195         mainFrame()->ResultName->setText( GEOMBase::GetName( myGroup ) );
196
197         GEOM::GEOM_IGroupOperations_var anOp = GEOM::GEOM_IGroupOperations::_narrow( getOperation() );
198         myMainObj = anOp->GetMainShape( myGroup );
199         if ( !CORBA::is_nil( myMainObj ) )
200           myMainName->setText( GEOMBase::GetName( myMainObj ) );
201
202         setShapeType( (TopAbs_ShapeEnum)anOp->GetType( myGroup ) );
203
204         GEOM::ListOfLong_var aCurrList = anOp->GetObjects( myGroup );
205         for ( int i = 0, n = aCurrList->length(); i < n; i++ )
206           myIdList->addItem( new QListWidgetItem( QString( "%1" ).arg( aCurrList[i] ) ) );
207
208         myEditCurrentArgument = 0;
209       }
210       connect( mySelBtn2, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
211     }
212   }
213
214   connect( aSelMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()) );
215
216   connect( buttonOk(),    SIGNAL( clicked() ), this, SLOT( ClickOnOk()    ) );
217   connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
218
219   connect( mySelectionWayGroup, SIGNAL( buttonClicked( int ) ), this, SLOT( SetEditCurrentArgument() ) );
220   connect( mySelAllBtn,         SIGNAL( clicked() ),            this, SLOT( SetEditCurrentArgument() ) );
221   connect( myAddBtn,            SIGNAL( clicked() ),            this, SLOT( add() ) );
222   connect( myRemBtn,            SIGNAL( clicked() ),            this, SLOT( remove() ) );
223   connect( myIdList,            SIGNAL( itemSelectionChanged() ),   this, SLOT( selectionChanged() ) );
224
225   setInPlaceObj(GEOM::GEOM_Object::_nil());
226
227   myBusy = true; // just activate but do not select in the list
228   activateSelection();
229   myBusy = false;
230 }
231
232 //=================================================================================
233 // function : enterEvent()
234 // purpose  :
235 //=================================================================================
236 void GroupGUI_GroupDlg::enterEvent( QEvent* e )
237 {
238   if ( !buttonCancel()->isEnabled() )
239     ActivateThisDialog();
240 }
241
242 //=======================================================================
243 //function : closeEvent
244 //purpose  : remove temporary geom object
245 //=======================================================================
246
247 void GroupGUI_GroupDlg::closeEvent( QCloseEvent* e )
248 {
249   setInPlaceObj( GEOM::GEOM_Object::_nil() );
250
251   GEOMBase_Skeleton::closeEvent( e );
252 }
253
254 //=================================================================================
255 // function : ClickOnOk()
256 // purpose  :
257 //=================================================================================
258 void GroupGUI_GroupDlg::ClickOnOk()
259 {
260   if ( ClickOnApply() )
261     ClickOnCancel();
262 }
263
264 //=================================================================================
265 // function : ClickOnApply()
266 // purpose  :
267 //=================================================================================
268 bool GroupGUI_GroupDlg::ClickOnApply()
269 {
270   if ( !onAccept( myMode == CreateGroup, true ) )
271     return false;
272
273   if ( myMode == CreateGroup )
274     {
275       initName();
276       myIdList->clear();
277       ConstructorsClicked( getConstructorId() );
278     }
279   else
280     activateSelection();
281   return true;
282 }
283
284 //=================================================================================
285 // function : ActivateThisDialog()
286 // purpose  :
287 //=================================================================================
288 void GroupGUI_GroupDlg::ActivateThisDialog()
289 {
290   GEOMBase_Skeleton::ActivateThisDialog();
291
292   connect( ((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(),
293            SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
294
295   activateSelection();
296 }
297
298 //=================================================================================
299 // function : LineEditReturnPressed()
300 // purpose  :
301 //=================================================================================
302 void GroupGUI_GroupDlg::LineEditReturnPressed()
303 {
304   QLineEdit* send = ( QLineEdit* )sender();
305
306   if ( send == myMainName && !myEditCurrentArgument ) {
307     myEditCurrentArgument = myMainName;
308     activateSelection();
309   }
310   else
311     GEOMBase_Skeleton::LineEditReturnPressed();
312
313   updateState();
314 }
315
316 //=================================================================================
317 // function : SetEditCurrentArgument()
318 // purpose  :
319 //=================================================================================
320 void GroupGUI_GroupDlg::SetEditCurrentArgument()
321 {
322   QPushButton* send = (QPushButton*)sender();
323
324   if ( send == mySelBtn ) {
325     myEditCurrentArgument = myMainName;
326     myShape2Name->setText( "" );
327   }
328   else if ( /*(QRadioButton*)sender() == mySelSubBtn ||*/ send == mySelAllBtn )
329     myEditCurrentArgument = 0;
330   else if ( send == mySelBtn2 || sender() == mySelectionWayGroup ) {
331     setInPlaceObj( GEOM::GEOM_Object::_nil() );
332     //if ( myPlaceCheckBox->isChecked() )
333     myShape2Name->setText( "" );
334     if ( subSelectionWay() != ALL_SUBSHAPES )
335     {
336       myEditCurrentArgument = myShape2Name;
337     }
338     else {
339       //myEditCurrentArgument = myMainName;
340       myEditCurrentArgument = 0;
341     }
342   }
343
344   activateSelection();
345
346   if ( send == mySelAllBtn ) {
347 //     myShape2Name->setText( "" );
348 //     myPlaceCheckBox->setChecked( false );
349 //     mySelBtn2->setEnabled( false );
350 //     myShape2Name->setEnabled( false );
351     selectAllSubShapes();
352   }
353   else
354     updateState();
355 }
356
357 //=================================================================================
358 // function : onGetInPlace()
359 // purpose  :
360 //=================================================================================
361 void GroupGUI_GroupDlg::onGetInPlace()
362 {
363   setInPlaceObj( GEOM::GEOM_Object::_nil() );
364   myEditCurrentArgument->setText( "" );
365
366   bool isBlocked = myIdList->signalsBlocked();
367   myIdList->blockSignals( true );
368   myIdList->clearSelection();
369   myIdList->blockSignals( isBlocked );
370
371   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
372   SALOME_ListIO aSelList;
373   aSelMgr->selectedObjects(aSelList);
374
375   if (aSelList.Extent() != 1)
376     return;
377
378   Standard_Boolean aResult = Standard_False;
379   GEOM::GEOM_Object_var anObj =
380     GEOMBase::ConvertIOinGEOMObject(aSelList.First(), aResult);
381   if (aResult && !anObj->_is_nil() && GEOMBase::IsShape(anObj)) {
382     if (!anObj->_is_equivalent(myMainObj) && !anObj->_is_equivalent(myGroup)) {
383       SUIT_OverrideCursor wc;
384       myEditCurrentArgument->setText(GEOMBase::GetName(anObj));
385       GEOM::GEOM_IShapesOperations_var aShapesOp =
386         getGeomEngine()->GetIShapesOperations(getStudyId());
387       if ( subSelectionWay() == GET_IN_PLACE ) {
388         GEOM::GEOM_Object_var aGetInPlaceObj = aShapesOp->GetInPlace(myMainObj, anObj);
389         setInPlaceObj( aGetInPlaceObj );
390       }
391       else {
392         bool isVisible = true;
393         if ( SALOME_View* view = GEOM_Displayer::GetActiveView() )
394           isVisible = view->isVisible( aSelList.First() );
395         setInPlaceObj( anObj, isVisible );
396       }
397       myEditCurrentArgument = 0;
398       //myBusy = true; // just activate but do not select in the list
399       activateSelection();
400       //myBusy = false;
401     }
402   }
403 }
404
405 //=======================================================================
406 //function : setInPlaceObj
407 //purpose  : temporarily add an object to study and remove old InPlaceObj
408 //=======================================================================
409
410 void GroupGUI_GroupDlg::setInPlaceObj( GEOM::GEOM_Object_var theObj, const bool isVisible )
411 {
412   if ( ! myInPlaceObj->_is_equivalent( theObj ) )
413   {
414     const char* tmpName = "__InPlaceObj__";
415     // remove old InPlaceObj
416     if ( !myInPlaceObj->_is_nil() ) {
417       if ( myInPlaceObjSelectState == GET_IN_PLACE ||
418            myInPlaceObjSelectState == SUBSHAPES_OF_INVISIBLE_SHAPE2 ) {
419         // hide temporary object or initially invisible shape 2 (issue 0014047)
420         GEOM_Displayer aDisplayer(getStudy());
421         aDisplayer.Erase( myInPlaceObj, true );
422       }
423       if (_PTR(SObject) SO = getStudy()->studyDS()->FindObject( tmpName )) {
424         getStudy()->studyDS()->NewBuilder()->RemoveObjectWithChildren( SO );
425         getGeomEngine()->RemoveObject(myInPlaceObj);
426       }
427     }
428     // publish InPlaceObj to enable localSelection(InPlaceObj)
429     if ( !theObj->_is_nil() && subSelectionWay() == GET_IN_PLACE ) {
430       SALOMEDS::Study_var aStudyDS = GeometryGUI::ClientStudyToStudy(getStudy()->studyDS());
431       SALOMEDS::SObject_var aSO =
432         getGeomEngine()->AddInStudy(aStudyDS, theObj, tmpName, myMainObj);
433     }
434     myInPlaceObj = theObj;
435   }
436   // build map of indices
437   myMain2InPlaceIndices.Clear();
438   if ( !myInPlaceObj->_is_nil() ) {
439     GEOM::GEOM_IShapesOperations_var aShapesOp = getGeomEngine()->GetIShapesOperations( getStudyId() );
440     GEOM::GEOM_ILocalOperations_var aLocOp = getGeomEngine()->GetILocalOperations( getStudyId() );
441
442     GEOM::ListOfGO_var aSubObjects = aShapesOp->MakeExplode( myInPlaceObj, getShapeType(), false);
443     for (int i = 0; i < aSubObjects->length(); i++)
444     {
445       CORBA::Long aMainIndex = aLocOp->GetSubShapeIndex( myMainObj, aSubObjects[i] );
446       CORBA::Long aPlaceIndex = aLocOp->GetSubShapeIndex( myInPlaceObj, aSubObjects[i] );
447       if ( aMainIndex >= 0 && aPlaceIndex > 0)
448         myMain2InPlaceIndices.Bind( aMainIndex, aPlaceIndex );
449     }
450   }
451   myInPlaceObjSelectState = subSelectionWay();
452   if ( myInPlaceObjSelectState == SUBSHAPES_OF_SHAPE2 && !isVisible )
453     myInPlaceObjSelectState = SUBSHAPES_OF_INVISIBLE_SHAPE2;
454 }
455
456 //=================================================================================
457 // function : SelectionIntoArgument()
458 // purpose  : Called when selection has changed
459 //=================================================================================
460 void GroupGUI_GroupDlg::SelectionIntoArgument()
461 {
462 //   if (myPlaceCheckBox->isChecked() && myEditCurrentArgument == myShape2Name )
463   if (subSelectionWay() != ALL_SUBSHAPES && myEditCurrentArgument == myShape2Name) {
464     onGetInPlace();
465     return;
466   }
467
468   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
469   SALOME_ListIO aSelList;
470   aSelMgr->selectedObjects(aSelList);
471
472   if (myEditCurrentArgument == myMainName) {  // Selection of a main shape is active
473     myEditCurrentArgument->setText("");
474     myIdList->clear();
475
476     if (aSelList.Extent() == 1) {
477       Standard_Boolean aResult = Standard_False;
478       GEOM::GEOM_Object_var anObj =
479         GEOMBase::ConvertIOinGEOMObject(aSelList.First(), aResult);
480
481       if ( aResult && !anObj->_is_nil() && GEOMBase::IsShape( anObj ) ) {
482         myMainObj = anObj;
483         myEditCurrentArgument->setText( GEOMBase::GetName( anObj ) );
484         // activate subshapes selection by default
485         myEditCurrentArgument = 0;
486         activateSelection();
487         updateState();
488         return;
489       }
490     }
491
492     myMainObj = GEOM::GEOM_Object::_nil();
493   }
494   else { // an attempt to synchronize list box selection with 3d viewer
495     if ( myBusy ) {
496       return;
497     }
498
499     bool isBlocked = myIdList->signalsBlocked();
500     myIdList->blockSignals( true );
501     myIdList->clearSelection();
502
503     TColStd_IndexedMapOfInteger aMapIndex;
504
505     LightApp_SelectionMgr::MapEntryOfMapOfInteger aMap;
506     aSelMgr->selectedSubOwners( aMap );
507     if ( aMap.Size() == 1 )
508       aMapIndex = LightApp_SelectionMgr::MapEntryOfMapOfInteger::Iterator( aMap ).Value();
509     bool subselected = aMapIndex.Extent();
510
511     // convert inPlace indices to main indices
512     //if ( subselected && myPlaceCheckBox->isChecked() )
513     if ( subselected && subSelectionWay() != ALL_SUBSHAPES )
514     {
515       TColStd_IndexedMapOfInteger aMapIndex2;
516       
517       TColStd_DataMapIteratorOfDataMapOfIntegerInteger m2ip( myMain2InPlaceIndices );
518       for ( ; m2ip.More(); m2ip.Next() ) {
519         int inPlaceId = m2ip.Value();
520         if ( aMapIndex.Contains( inPlaceId )) {
521           aMapIndex2.Add( m2ip.Key() );
522         }
523       }
524       aMapIndex = aMapIndex2;
525     }
526
527     // try to find out and process the object browser selection
528     if ( !subselected ) {
529       globalSelection( GEOM_ALLSHAPES );
530
531       GEOM::ListOfGO anObjects;
532       GEOMBase::ConvertListOfIOInListOfGO(aSelList, anObjects);
533
534       GEOM::GEOM_ILocalOperations_var aLocOp = getGeomEngine()->GetILocalOperations( getStudyId() );
535       GEOM::GEOM_IShapesOperations_var aShapesOp = getGeomEngine()->GetIShapesOperations( getStudyId() );
536
537       for (int i = 0; i < anObjects.length(); i++)
538       {
539         GEOM::GEOM_Object_var aGeomObj = anObjects[i];
540         GEOM::ListOfGO_var aSubObjects = new GEOM::ListOfGO();
541         TopoDS_Shape aShape;
542         if ( GEOMBase::GetShape(aGeomObj, aShape, getShapeType()) )
543         {
544           aSubObjects->length(1);
545           aSubObjects[0] = aGeomObj;
546         }
547         else if (aGeomObj->GetType() == GEOM_GROUP)
548           aSubObjects = aShapesOp->MakeExplode( aGeomObj, getShapeType(), false);
549         else
550           continue;
551
552         for (int i = 0; i < aSubObjects->length(); i++)
553         {
554           TopoDS_Shape aShape;
555           if ( GEOMBase::GetShape(aSubObjects[i], aShape, getShapeType()) )
556           {
557             CORBA::Long anIndex;
558             anIndex = aLocOp->GetSubShapeIndex( myMainObj, aSubObjects[i] );
559             if ( anIndex >= 0 ) {
560               //if ( myPlaceCheckBox->isChecked() && ! myMain2InPlaceIndices.IsBound( anIndex ))
561               if ( subSelectionWay() != ALL_SUBSHAPES &&
562                    ! myMain2InPlaceIndices.IsBound( anIndex ))
563                 continue;
564               aMapIndex.Add( anIndex );
565             }
566           }
567         }
568       }
569       if ( !myMainObj->_is_nil()  && myIsShapeType/*&& mySelSubBtn->isChecked()*/)
570         if ( subSelectionWay() == ALL_SUBSHAPES )
571           localSelection( myMainObj, getShapeType() );
572         else if ( !myInPlaceObj->_is_nil() )
573           localSelection( myInPlaceObj, getShapeType() );
574     }
575
576     if (aMapIndex.Extent() >= 1) {
577       QMap<int, int> aMap;
578       for ( int i = 0, n = myIdList->count(); i < n; i++ )
579         aMap.insert( myIdList->item( i )->text().toInt(), i );
580
581       for ( int ii = 1, nn = aMapIndex.Extent(); ii <= nn; ii++ ) {
582         if ( aMap.contains( aMapIndex( ii ) ) )
583           myIdList->item( aMap[aMapIndex( ii )])->setSelected( true );
584       }
585     }
586     myIdList->blockSignals( isBlocked );
587   }
588
589   updateState();
590 }
591
592 //=================================================================================
593 // function : ConstructorsClicked()
594 // purpose  : Radio button management
595 //=================================================================================
596 void GroupGUI_GroupDlg::ConstructorsClicked( int constructorId )
597 {
598   myIsShapeType = true;
599   myIdList->clear();
600   activateSelection();
601   updateState();
602   setInPlaceObj( myInPlaceObj ); // to rebuild myMain2InPlaceIndices
603 }
604
605 //=================================================================================
606 // function : selectAllSubShapes
607 // purpose  : 
608 //=================================================================================
609 void GroupGUI_GroupDlg::selectAllSubShapes()
610 {
611   if ( CORBA::is_nil( myMainObj ) )
612     return;
613
614   GEOM::ListOfLong_var aSubShapes;
615 //   if ( !myPlaceCheckBox->isChecked() )
616   if ( subSelectionWay() == ALL_SUBSHAPES )
617   {
618     if ( !myIsShapeType )
619       return;
620     myIdList->clear();
621     GEOM::GEOM_IShapesOperations_var aShOp = getGeomEngine()->GetIShapesOperations( getStudyId() );
622     aSubShapes = aShOp->SubShapeAllIDs(myMainObj, getShapeType(), false);
623
624     if ( !aShOp->IsDone() )
625       return;
626   }
627   else
628   {
629     aSubShapes = new GEOM::ListOfLong();
630     aSubShapes->length( myMain2InPlaceIndices.Extent() );
631     TColStd_DataMapIteratorOfDataMapOfIntegerInteger m2ip( myMain2InPlaceIndices );
632     for ( int i = 0; m2ip.More(); i++, m2ip.Next() )
633       aSubShapes[ i ] = m2ip.Key();
634   }
635   bool isBlocked = myIdList->signalsBlocked();
636   myIdList->blockSignals( true );
637
638   for ( int i = 0, n = aSubShapes->length(); i < n; i++ ) {
639     CORBA::Long anIndex = aSubShapes[i];
640     if ( anIndex < 0 )
641       continue;
642
643     QListWidgetItem* anItem = 0;
644     QString text = QString( "%1" ).arg( anIndex );
645     if ( !myInPlaceObj->_is_nil() ) {
646       QList<QListWidgetItem*> found = myIdList->findItems( text, Qt::MatchExactly );
647       if ( found.count() ) anItem = found[0];
648     }
649     if ( !anItem ) {
650       anItem = new QListWidgetItem( text );
651       myIdList->addItem( anItem );
652     }
653     anItem->setSelected( true );
654   }
655
656   myIdList->blockSignals( isBlocked );
657   highlightSubShapes();
658 }
659
660 //=================================================================================
661 // function : add
662 // purpose  : 
663 //=================================================================================
664 void GroupGUI_GroupDlg::add()
665 {
666   TColStd_MapOfInteger aMap;
667   for ( int i = 0, n = myIdList->count(); i < n; i++ )
668     aMap.Add( myIdList->item( i )->text().toInt() );
669
670   TColStd_IndexedMapOfInteger aMapIndex;
671
672   SALOME_ListIO aSelIOs;
673   SalomeApp_Application* app = myGeomGUI->getApp();
674   if ( app ) {
675     LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
676     if ( aSelMgr ) {
677       LightApp_SelectionMgr::MapEntryOfMapOfInteger aMap;
678       aSelMgr->selectedSubOwners( aMap );
679       if ( aMap.Size() == 1 )
680         aMapIndex = LightApp_SelectionMgr::MapEntryOfMapOfInteger::Iterator( aMap ).Value();
681     }
682   }
683   GEOM::ListOfGO anObjects;
684   // get selected sub-shapes of myInPlaceObj
685   if ( aMapIndex.Extent() > 0 && !myInPlaceObj->_is_nil() )
686   {
687     GEOM::GEOM_IShapesOperations_var aShapesOp = getGeomEngine()->GetIShapesOperations( getStudyId() );
688
689     anObjects.length( aMapIndex.Extent() );
690     for ( int i = 1; i <= aMapIndex.Extent(); i++ )
691       anObjects[ i-1 ] = aShapesOp->GetSubShape( myInPlaceObj, aMapIndex( i ));
692
693     aMapIndex.Clear();
694   }
695
696   // try to find out and process the object browser selection or InPlace sub-shapes
697   if ( !aMapIndex.Extent() )
698   {
699     if ( anObjects.length() == 0 )
700       GEOMBase::ConvertListOfIOInListOfGO(aSelIOs, anObjects);
701
702     GEOM::GEOM_ILocalOperations_var aLocOp = getGeomEngine()->GetILocalOperations( getStudyId() );
703     GEOM::GEOM_IShapesOperations_var aShapesOp = getGeomEngine()->GetIShapesOperations( getStudyId() );
704
705     for (int i = 0; i < anObjects.length(); i++)
706     {
707       GEOM::GEOM_Object_var aGeomObj = anObjects[i];
708       GEOM::ListOfGO_var aSubObjects  = new GEOM::ListOfGO();
709       TopoDS_Shape aShape;
710       if ( GEOMBase::GetShape(aGeomObj, aShape, getShapeType()) )
711       {
712         aSubObjects->length(1);
713         aSubObjects[0] = aGeomObj;
714       }
715       else if (aGeomObj->GetType() == GEOM_GROUP)
716         aSubObjects = aShapesOp->MakeExplode( aGeomObj, getShapeType(), false);
717       else
718         break;
719
720       for (int i = 0; i < aSubObjects->length(); i++)
721       {
722         TopoDS_Shape aShape;
723         if ( GEOMBase::GetShape(aSubObjects[i], aShape, getShapeType()) )
724         {
725           CORBA::Long anIndex;
726             anIndex = aLocOp->GetSubShapeIndex( myMainObj, aSubObjects[i] );
727           if ( anIndex >= 0 )
728             aMapIndex.Add( anIndex );
729         }
730       }
731     }
732   }
733
734   if ( aMapIndex.Extent() >= 1 ) {
735     bool isBlocked = myIdList->signalsBlocked();
736     myIdList->blockSignals( true );
737
738     for ( int i = 1, n = aMapIndex.Extent(); i <= n; i++ ) {
739       if ( aMap.Contains( aMapIndex( i ) ) )
740         continue;
741
742       QListWidgetItem* anItem = new QListWidgetItem( QString( "%1" ).arg( aMapIndex( i ) ) );
743       myIdList->addItem( anItem );
744       anItem->setSelected( true );
745     }
746
747     myIdList->blockSignals( isBlocked );
748   }
749
750   updateState();
751 }
752
753 //=================================================================================
754 // function : remove
755 // purpose  : 
756 //=================================================================================
757 void GroupGUI_GroupDlg::remove()
758 {
759   bool isBlocked = myIdList->signalsBlocked();
760   myIdList->blockSignals( true );
761
762   QListIterator<QListWidgetItem*> it( myIdList->selectedItems() );
763   while ( it.hasNext() )
764     delete it.next();
765
766   myIdList->blockSignals( isBlocked );
767
768   highlightSubShapes();
769 }
770
771 //=======================================================================
772 //function : subSelectionWay
773 //purpose  : 
774 //=======================================================================
775
776 int GroupGUI_GroupDlg::subSelectionWay() const
777 {
778   return mySelectionWayGroup->checkedId();
779 }
780
781 //=================================================================================
782 // function : getShapeType()
783 // purpose  :
784 //=================================================================================
785 TopAbs_ShapeEnum GroupGUI_GroupDlg::getShapeType() const
786 {
787   switch ( getConstructorId() ) {
788   case 0:  return TopAbs_VERTEX;
789   case 1:  return TopAbs_EDGE;
790   case 2:  return TopAbs_FACE;
791   case 3:  return TopAbs_SOLID;
792   default: return TopAbs_SHAPE;
793   }
794 }
795
796 //=================================================================================
797 // function : setShapeType()
798 // purpose  :
799 //=================================================================================
800 void GroupGUI_GroupDlg::setShapeType( const TopAbs_ShapeEnum theType )
801 {
802   int anId = 0;
803   switch ( theType ) {
804   case TopAbs_VERTEX: anId = 0; break;
805   case TopAbs_EDGE:   anId = 1; break;
806   case TopAbs_FACE:   anId = 2; break;
807   case TopAbs_SOLID:  anId = 3; break;
808   }
809   setConstructorId( anId );
810   myIsShapeType = true;
811 }
812
813
814 //=================================================================================
815 // function : activateSelection
816 // purpose  : Activate selection in accordance with myEditCurrentArgument
817 //=================================================================================
818 void GroupGUI_GroupDlg::activateSelection()
819 {
820   globalSelection( GEOM_ALLSHAPES );
821
822   // local selection
823   if ( !myMainObj->_is_nil() && !myEditCurrentArgument/* && mySelSubBtn->isChecked()*/
824        && myIsShapeType) { // check if shape type is already choosen by user
825   
826 //     if ( !myPlaceCheckBox->isChecked() )
827     if ( subSelectionWay() == ALL_SUBSHAPES )
828       localSelection( myMainObj, getShapeType() );
829     else if ( !myInPlaceObj->_is_nil() )
830       localSelection( myInPlaceObj, getShapeType() );
831   }
832
833   SelectionIntoArgument();
834 }
835
836 //=================================================================================
837 // function : updateState
838 // purpose  : 
839 //=================================================================================
840 void GroupGUI_GroupDlg::updateState()
841 {
842   bool isAdd = false;
843
844   TColStd_IndexedMapOfInteger aMapIndex;
845
846   SALOME_ListIO aSelIOs;
847   SalomeApp_Application* app = myGeomGUI->getApp();
848   if ( app ) {
849     LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
850     if ( aSelMgr ) {
851       LightApp_SelectionMgr::MapEntryOfMapOfInteger aMap;
852       aSelMgr->selectedSubOwners( aMap );
853       if ( aMap.Size() == 1 )
854         aMapIndex = LightApp_SelectionMgr::MapEntryOfMapOfInteger::Iterator( aMap ).Value();
855     }
856   }
857
858   // try to find out and process the object browser selection
859   if ( !aMapIndex.Extent() && !CORBA::is_nil( myMainObj ) ) {
860     GEOM::ListOfGO anObjects;
861     //GEOMBase::ConvertListOfIOInListOfGO(selectedIO(), anObjects);
862     GEOMBase::ConvertListOfIOInListOfGO(aSelIOs, anObjects);
863
864     GEOM::GEOM_ILocalOperations_var aLocOp = getGeomEngine()->GetILocalOperations( getStudyId() );
865     GEOM::GEOM_IShapesOperations_var aShapesOp = getGeomEngine()->GetIShapesOperations( getStudyId() );
866
867     isAdd = true;
868
869     for (int i = 0; i < anObjects.length(); i++)
870     {
871       GEOM::GEOM_Object_var aGeomObj = anObjects[i];
872       GEOM::ListOfGO_var aSubObjects = new GEOM::ListOfGO();
873       TopoDS_Shape aShape;
874       if ( GEOMBase::GetShape(aGeomObj, aShape, getShapeType()) ) {
875         aSubObjects->length(1);
876         aSubObjects[0] = aGeomObj;
877       }
878       else if (aGeomObj->GetType() == GEOM_GROUP) {
879         aSubObjects = aShapesOp->MakeExplode( aGeomObj, getShapeType(), false);
880       }
881       else {
882         aMapIndex.Clear();
883         break;
884       }
885
886       for (int i = 0; i < aSubObjects->length(); i++)
887       {
888         TopoDS_Shape aShape;
889         aSubObjects[i];
890         if ( GEOMBase::GetShape(aSubObjects[i], aShape, getShapeType()) )
891         {
892           CORBA::Long anIndex;
893           anIndex = aLocOp->GetSubShapeIndex( myMainObj, aSubObjects[i] );
894           if ( anIndex >= 0 )
895             aMapIndex.Add( anIndex );
896           else
897             isAdd = false;
898         }
899         else
900           isAdd = false;
901
902         if ( !isAdd ) {
903           aMapIndex.Clear();
904           break;
905         }
906       }
907       if ( !isAdd ) {
908         aMapIndex.Clear();
909         break;
910       }
911     }
912   }
913
914   isAdd = aMapIndex.Extent() > 0;
915
916   myAddBtn->setEnabled( !myEditCurrentArgument && !CORBA::is_nil( myMainObj ) && isAdd );
917   bool hasSel = myIdList->selectedItems().count() > 0;
918   myRemBtn->setEnabled( hasSel );
919   //mySelSubBtn->setEnabled( !CORBA::is_nil( myMainObj ) );
920   //myPlaceCheckBox->setEnabled( !CORBA::is_nil( myMainObj ) );
921   mySelectionWayGroupBox->setEnabled( !CORBA::is_nil( myMainObj ) );
922   mySelAllBtn->setEnabled( !CORBA::is_nil( myMainObj ) );
923 //   mySelBtn2->setEnabled( myPlaceCheckBox->isChecked() );
924 //   myShape2Name->setEnabled( myPlaceCheckBox->isChecked() );
925   mySelBtn2->setEnabled(    subSelectionWay() != ALL_SUBSHAPES );
926   myShape2Name->setEnabled( subSelectionWay() != ALL_SUBSHAPES );
927 //   if ( !myPlaceCheckBox->isChecked() )
928   if ( subSelectionWay() == ALL_SUBSHAPES )
929     setInPlaceObj( GEOM::GEOM_Object::_nil() );
930 }
931
932 //=================================================================================
933 // function : selectionChanged
934 // purpose  :
935 //=================================================================================
936 void GroupGUI_GroupDlg::selectionChanged()
937 {
938   highlightSubShapes();
939 }
940
941 //=================================================================================
942 // function : highlightSubShapes
943 // purpose  :
944 //=================================================================================
945 void GroupGUI_GroupDlg::highlightSubShapes()
946 {
947   if ( CORBA::is_nil( myMainObj ) )
948     return;
949
950   Standard_Boolean isOk;
951   char* objIOR;
952
953   if ( myInPlaceObj->_is_nil() )
954     objIOR = GEOMBase::GetIORFromObject( myMainObj );
955   else
956     objIOR = GEOMBase::GetIORFromObject( myInPlaceObj );
957
958   Handle(GEOM_AISShape) aSh = GEOMBase::ConvertIORinGEOMAISShape( objIOR, isOk, true );
959   free( objIOR );
960   if ( !isOk || aSh.IsNull() )
961     return;
962
963   TColStd_MapOfInteger anIds;
964
965   myBusy = true;
966
967   int ii = 0, nn = myIdList->count();
968   for ( ; ii < nn; ii++ )
969   {
970     if ( myIdList->item( ii )->isSelected() ) {
971       int id = myIdList->item( ii )->text().toInt();
972       //       if ( myPlaceCheckBox->isChecked() )
973       if ( subSelectionWay() != ALL_SUBSHAPES )
974       {
975         if ( myMain2InPlaceIndices.IsBound( id ) )
976           id = myMain2InPlaceIndices( id );
977         else {
978           myIdList->item( ii )->setSelected( false );
979           continue;
980         }
981       }
982       anIds.Add( id );
983     }
984   }
985   SalomeApp_Application* app = myGeomGUI->getApp();
986   LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
987   aSelMgr->clearSelected();
988
989   aSelMgr->AddOrRemoveIndex(aSh->getIO(), anIds, false);
990
991   myBusy = false;
992
993   if (nn < 3000)
994     updateState();
995   else {
996     myAddBtn->setEnabled( true );
997     myRemBtn->setEnabled( true );
998   }
999 }
1000
1001 //=================================================================================
1002 // function : createOperation
1003 // purpose  :
1004 //=================================================================================
1005 GEOM::GEOM_IOperations_ptr GroupGUI_GroupDlg::createOperation()
1006 {
1007   return getGeomEngine()->GetIGroupOperations( getStudyId() );
1008 }
1009
1010 #define RETURN_WITH_MSG(a, b) \
1011   if ( !(a) ) { \
1012     theMessage += (b); \
1013     return false; \
1014   }
1015
1016 //=================================================================================
1017 // function : isValid()
1018 // purpose  : Verify validity of input data
1019 //=================================================================================
1020 bool GroupGUI_GroupDlg::isValid( QString& theMessage )
1021 {
1022   SalomeApp_Study* study = getStudy();
1023   ASSERT(study);
1024   RETURN_WITH_MSG  ( !study->studyDS()->GetProperties()->IsLocked(), tr( "GEOM_STUDY_LOCKED" ) )
1025
1026   if ( myMode == CreateGroup ) {
1027     RETURN_WITH_MSG( !CORBA::is_nil( myMainObj ), tr( "NO_MAIN_OBJ" ) )
1028   }
1029   else {
1030     RETURN_WITH_MSG( !CORBA::is_nil( myMainObj ), tr( "NO_GROUP" ) )
1031   }
1032
1033   QString aName (getNewObjectName());
1034   RETURN_WITH_MSG  ( !aName.trimmed().isEmpty(), tr( "EMPTY_NAME" ) )
1035
1036   RETURN_WITH_MSG  ( myIdList->count(), tr( "EMPTY_LIST" ) )
1037   return true;
1038 }
1039
1040 //=================================================================================
1041 // function : execute
1042 // purpose  :
1043 //=================================================================================
1044 bool GroupGUI_GroupDlg::execute( ObjectList& objects )
1045 {
1046   setInPlaceObj( GEOM::GEOM_Object::_nil() );
1047
1048   GEOM::GEOM_IGroupOperations_var anOp = GEOM::GEOM_IGroupOperations::_narrow(getOperation());
1049
1050   GEOM::GEOM_Object_var aGroup;
1051   if (myMode == CreateGroup)
1052     aGroup = anOp->CreateGroup(myMainObj, getShapeType());
1053   else if (myMode == EditGroup)
1054     aGroup = myGroup;
1055
1056   if (CORBA::is_nil(aGroup) || (myMode == CreateGroup && !anOp->IsDone()))
1057     return false;
1058
1059   GEOM::ListOfLong_var aCurrList = anOp->GetObjects(aGroup);
1060   if (!anOp->IsDone())
1061     return false;
1062
1063   if (aCurrList->length() > 0)
1064   {
1065     anOp->DifferenceIDs(aGroup, aCurrList);
1066     if (!anOp->IsDone())
1067       return false;
1068   }
1069
1070   int ii, nn = myIdList->count();
1071   if (nn > 0)
1072   {
1073     GEOM::ListOfLong_var aNewList = new GEOM::ListOfLong;
1074     aNewList->length(nn);
1075     for (ii = 0; ii < nn; ii++) {
1076       aNewList[ii] = myIdList->item(ii)->text().toInt();
1077     }
1078     anOp->UnionIDs(aGroup, aNewList);
1079     if (!anOp->IsDone())
1080       return false;
1081   }
1082
1083   SalomeApp_Study* study = getStudy();
1084   if ( study ) {
1085     char* objIOR = GEOMBase::GetIORFromObject( aGroup );
1086     std::string IOR( objIOR );
1087     free( objIOR );
1088     if ( IOR != "" ) {
1089       _PTR(SObject) SO ( study->studyDS()->FindObjectIOR( IOR ) );
1090       if ( SO ) {
1091         _PTR(StudyBuilder) aBuilder (study->studyDS()->NewBuilder());
1092         aBuilder->SetName( SO, getNewObjectName().toLatin1().constData() );
1093       }
1094     }
1095   }
1096
1097   objects.push_back( aGroup._retn() );
1098
1099   return true;
1100 }
1101
1102 //================================================================
1103 // Function : getFather
1104 // Purpose  : Get father object for object to be added in study
1105 //            ( called with addInStudy method )
1106 //================================================================
1107 GEOM::GEOM_Object_ptr GroupGUI_GroupDlg::getFather( GEOM::GEOM_Object_ptr theObj )
1108 {
1109   GEOM::GEOM_Object_var aFatherObj;
1110   if ( theObj->GetType() == GEOM_GROUP ) {
1111     GEOM::GEOM_IGroupOperations_var anOp = GEOM::GEOM_IGroupOperations::_narrow( getOperation() );
1112     aFatherObj = anOp->GetMainShape( theObj );
1113   }
1114   return aFatherObj._retn();
1115 }