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