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