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