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