]> SALOME platform Git repositories - modules/geom.git/blob - src/EntityGUI/EntityGUI_SubShapeDlg.cxx
Salome HOME
Issue 0021055: EDF 1602 STUDY: Object browser reactualisation when creating an object
[modules/geom.git] / src / EntityGUI / EntityGUI_SubShapeDlg.cxx
1 //  Copyright (C) 2007-2010  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   : EntityGUI_SubShapeDlg.cxx
24 // Author : Lucien PIGNOLONI, Open CASCADE S.A.S.
25
26 #include "EntityGUI_SubShapeDlg.h"
27
28 #include <DlgRef.h>
29 #include <GeometryGUI.h>
30 #include <GEOMBase.h>
31
32 #include <SUIT_Desktop.h>
33 #include <SUIT_ResourceMgr.h>
34 #include <SUIT_Session.h>
35 #include <SUIT_ViewManager.h>
36 #include <SUIT_ViewWindow.h>
37 #include <OCCViewer_ViewModel.h>
38 #include <SalomeApp_Application.h>
39 #include <LightApp_SelectionMgr.h>
40
41 #include <TColStd_IndexedMapOfInteger.hxx>
42 #include <TopoDS_Iterator.hxx>
43 #include <TopExp_Explorer.hxx>
44 #include <TopTools_MapOfShape.hxx>
45
46 #include <QMessageBox>
47
48 //=================================================================================
49 // class    : EntityGUI_SubShapeDlg
50 // purpose  : Constructs a EntityGUI_SubShapeDlg which is a child of 'parent', with the
51 //            name 'name' and widget flags set to 'f'.
52 //            The dialog will by default be modeless, unless you set 'modal' to
53 //            TRUE to construct a modal dialog.
54 //=================================================================================
55 EntityGUI_SubShapeDlg::EntityGUI_SubShapeDlg( GeometryGUI* theGeometryGUI, QWidget* parent,
56                                               bool modal, Qt::WindowFlags fl )
57   : GEOMBase_Skeleton( theGeometryGUI, parent, modal, fl )
58 {
59   QPixmap image0( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_SUBSHAPE" ) ) );
60   QPixmap image1( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) );
61
62   setWindowTitle( tr( "GEOM_SUBSHAPE_TITLE" ) );
63
64   /***************************************************************/
65   mainFrame()->GroupConstructors->setTitle( tr( "GEOM_SUB_SHAPE" ) );
66   mainFrame()->RadioButton1->setIcon( image0 );
67   mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose );
68   mainFrame()->RadioButton2->close();
69   mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
70   mainFrame()->RadioButton3->close();
71
72   GroupPoints = new DlgRef_1Sel1Check1List( centralWidget() );
73
74   GroupPoints->GroupBox1->setTitle( tr( "GEOM_ARGUMENTS" ) );
75   GroupPoints->TextLabel1->setText( tr( "GEOM_MAIN_OBJECT" ) );
76   GroupPoints->TextLabel2->setText( tr( "GEOM_SUBSHAPE_TYPE" ) );
77   GroupPoints->CheckButton1->setText( tr( "GEOM_SUBSHAPE_SELECT" ) );
78   GroupPoints->PushButton1->setIcon( image1 );
79   GroupPoints->LineEdit1->setReadOnly( true );
80
81   QVBoxLayout* layout = new QVBoxLayout( centralWidget() );
82   layout->setMargin( 0 ); layout->setSpacing( 6 );
83   layout->addWidget( GroupPoints );
84   /***************************************************************/
85
86   setIsOptimizedBrowsing( true );
87
88   setHelpFileName( "create_explode_page.html" );
89
90   mainFrame()->GroupBoxName->hide();
91
92   Init();
93 }
94
95
96 //=================================================================================
97 // function : ~EntityGUI_SubShapeDlg()
98 // purpose  : Destroys the object and frees any allocated resources
99 //=================================================================================
100 EntityGUI_SubShapeDlg::~EntityGUI_SubShapeDlg()
101 {
102 }
103
104
105 //=================================================================================
106 // function : Init()
107 // purpose  :
108 //=================================================================================
109 void EntityGUI_SubShapeDlg::Init()
110 {
111   /* init variables */
112   myEditCurrentArgument = GroupPoints->LineEdit1;
113   myObject = GEOM::GEOM_Object::_nil();
114
115   myWithShape = true;
116
117   /* type for sub shape selection */
118   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Compound" );
119   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Compsolid" );
120   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Solid" );
121   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Shell" );
122   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Face" );
123   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Wire" );
124   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Edge" );
125   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Vertex" );
126   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Shape" );
127
128   if ( SUIT_Session::session()->activeApplication()->desktop()->activeWindow()->getViewManager()->getType() 
129        != OCCViewer_Viewer::Type() )
130     GroupPoints->CheckButton1->setEnabled( false );
131
132   /* signals and slots connections */
133   connect( myGeomGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) );
134
135   connect( buttonOk(),    SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
136   connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
137
138   connect( GroupPoints->PushButton1,  SIGNAL( clicked() ),       this, SLOT( SetEditCurrentArgument() ) );
139   connect( GroupPoints->LineEdit1,    SIGNAL( returnPressed() ), this, SLOT( LineEditReturnPressed() ) );
140
141   connect( GroupPoints->ComboBox1,    SIGNAL( activated( int ) ),    this, SLOT( ComboTextChanged() ) );
142   connect( GroupPoints->CheckButton1, SIGNAL( stateChanged( int ) ), this, SLOT( SubShapeToggled() ) );
143
144   connect( myGeomGUI->getApp()->selectionMgr(),
145            SIGNAL( currentSelectionChanged( )), this, SLOT( SelectionIntoArgument() ) );
146
147   updateButtonState();
148   resize(100,100);
149   SelectionIntoArgument();
150 }
151
152
153 //=================================================================================
154 // function : ClickOnOk()
155 // purpose  :
156 //=================================================================================
157 void EntityGUI_SubShapeDlg::ClickOnOk()
158 {
159   setIsApplyAndClose( true );
160   if ( ClickOnApply() )
161     ClickOnCancel();
162 }
163
164
165 //=================================================================================
166 // function : ClickOnApply()
167 // purpose  :
168 //=================================================================================
169 bool EntityGUI_SubShapeDlg::ClickOnApply()
170 {
171   SUIT_Session::session()->activeApplication()->putInfo( "" );
172     
173   /* Explode all sub shapes */
174   if ( isAllSubShapes() ) {
175     /* More than 30 subshapes : ask confirmation */
176     unsigned int nb = NumberOfSubShapes( myShape, shapeType() );
177     if ( nb > 30 ) {
178       const QString caption = tr( "GEOM_CONFIRM" );
179       const QString text = tr( "GEOM_CONFIRM_INFO" ).arg( nb );
180       const QString button0 = tr( "GEOM_BUT_EXPLODE" );
181       const QString button1 = tr( "GEOM_BUT_CANCEL" );
182
183       if ( QMessageBox::warning( this, caption, text, button0, button1 ) != 0 )
184         return false;  /* aborted */
185     }
186   }
187
188   bool isOk = onAccept();
189
190   // restore selection, corresponding to current selection mode
191   SubShapeToggled();
192
193   return isOk;
194 }
195
196
197 //=================================================================================
198 // function : SelectionIntoArgument()
199 // purpose  : Called when selection as changed or other case
200 //          : used only by SelectButtonC1A1 (LineEditC1A1)
201 //=================================================================================
202 void EntityGUI_SubShapeDlg::SelectionIntoArgument()
203 {
204   if (!isAllSubShapes())
205     return;
206
207   ResetStateOfDialog();
208
209   QString aString = ""; /* name of selection */
210
211   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
212   SALOME_ListIO aSelList;
213   aSelMgr->selectedObjects(aSelList);
214
215   int nbSel = GEOMBase::GetNameOfSelectedIObjects(aSelList, aString, true);
216   if (nbSel != 1)
217     return;
218
219   Handle(SALOME_InteractiveObject) IO = aSelList.First();
220   if ( !IO->hasEntry() ) {
221     SUIT_Session::session()->activeApplication()->putInfo( tr( "GEOM_PRP_SHAPE_IN_STUDY" ) );
222     updateButtonState();
223     return;
224   }
225
226   TopoDS_Shape S = GEOMBase::GetTopoFromSelection( aSelList );
227   if ( S.IsNull() || S.ShapeType() == TopAbs_VERTEX ) {
228     myObject = GEOM::GEOM_Object::_nil();
229     updateButtonState();
230     return;
231   }
232
233   myObject = GEOMBase::ConvertIOinGEOMObject( IO );
234   if ( myObject->_is_nil() ) {
235     updateButtonState();
236     return;
237   }
238
239   myShape = S;
240   GroupPoints->LineEdit1->setText(aString);
241
242   int SelectedShapeType = GroupPoints->ComboBox1->currentIndex();
243   int count = GroupPoints->ComboBox1->count();
244
245   if (myWithShape)
246     count = count - 1;
247
248   int i = 0;
249   // Solving PAL5590
250   if (myShape.ShapeType() == TopAbs_COMPOUND) {
251     unsigned int nb = NumberOfSubShapes(myShape, TopAbs_COMPOUND);
252     if ( nb > 0 )
253       i++;
254   }
255   while (i <= myShape.ShapeType()) {
256     GroupPoints->ComboBox1->removeItem(0);
257     i++;
258   }
259
260   if (myShape.ShapeType() == TopAbs_COMPOUND) {
261     if (myWithShape == false) {
262       GroupPoints->ComboBox1->insertItem(GroupPoints->ComboBox1->count(), "Shape");
263       myWithShape = true;
264     }
265   }
266   else {
267     if ( myWithShape == true ) {
268       GroupPoints->ComboBox1->removeItem( GroupPoints->ComboBox1->count() - 1 );
269       myWithShape = false;
270     }
271   }
272
273   int count1 = GroupPoints->ComboBox1->count();
274   if ( myWithShape )
275     count1 = count1 - 1;
276
277   if ( SelectedShapeType > myShape.ShapeType() ) {
278     if ( SelectedShapeType == 8 ) {
279       if ( myShape.ShapeType() != TopAbs_COMPOUND ) {
280         GroupPoints->ComboBox1->setCurrentIndex( 0 );
281         ComboTextChanged();
282       }
283     }
284     else
285       GroupPoints->ComboBox1->setCurrentIndex( count1 - count + SelectedShapeType );
286   }
287   else {
288     GroupPoints->ComboBox1->setCurrentIndex( 0 );
289     ComboTextChanged();
290   }
291
292   updateButtonState();
293 }
294
295
296 //=================================================================================
297 // function : SetEditCurrentArgument()
298 // purpose  :
299 //=================================================================================
300 void EntityGUI_SubShapeDlg::SetEditCurrentArgument()
301 {
302   GroupPoints->LineEdit1->setFocus();
303   myEditCurrentArgument = GroupPoints->LineEdit1;
304   
305   GroupPoints->CheckButton1->setChecked( false );
306   SubShapeToggled();
307   SelectionIntoArgument();
308 }
309
310
311 //=================================================================================
312 // function : LineEditReturnPressed()
313 // purpose  :
314 //=================================================================================
315 void EntityGUI_SubShapeDlg::LineEditReturnPressed()
316 {  
317   QLineEdit* send = (QLineEdit*)sender();
318   if ( send == GroupPoints->LineEdit1 )
319     SetEditCurrentArgument();
320   else
321     return;
322
323   GEOMBase_Skeleton::LineEditReturnPressed();
324 }
325
326
327 //=================================================================================
328 // function : DeactivateActiveDialog()
329 // purpose  :
330 //=================================================================================
331 void EntityGUI_SubShapeDlg::DeactivateActiveDialog()
332 {
333   if ( mainFrame()->GroupConstructors->isEnabled() ) {
334     GEOMBase_Skeleton::DeactivateActiveDialog();
335   }
336 }
337
338
339 //=================================================================================
340 // function : ActivateThisDialog()
341 // purpose  :
342 //=================================================================================
343 void EntityGUI_SubShapeDlg::ActivateThisDialog()
344 {
345   GEOMBase_Skeleton::ActivateThisDialog();
346   connect( myGeomGUI->getApp()->selectionMgr(),
347            SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
348   SubShapeToggled();
349   updateButtonState();
350 }
351
352
353 //=================================================================================
354 // function : enterEvent()
355 // purpose  :
356 //=================================================================================
357 void EntityGUI_SubShapeDlg::enterEvent( QEvent* )
358 {
359   if ( !mainFrame()->GroupConstructors->isEnabled() )
360     ActivateThisDialog();
361 }
362
363 //=================================================================================
364 // function : ResetStateOfDialog()
365 // purpose  : Completely reset the state of method including local context
366 //=================================================================================
367 void EntityGUI_SubShapeDlg::ResetStateOfDialog()
368 {
369   myObject = GEOM::GEOM_Object::_nil();
370   myShape.Nullify();
371   myEditCurrentArgument->setText( "" );
372
373   int SelectedShapeType = GroupPoints->ComboBox1->currentIndex();
374   int count = GroupPoints->ComboBox1->count();
375   if ( myWithShape )
376     count = count - 1;
377
378   /* type for sub shape selection */
379   GroupPoints->ComboBox1->clear();
380   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Compound" );
381   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Compsolid" );
382   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Solid" );
383   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Shell" );
384   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Face" );
385   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Wire" );
386   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Edge" );
387   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Vertex" );
388   GroupPoints->ComboBox1->insertItem( GroupPoints->ComboBox1->count(), "Shape" );
389   
390   myWithShape = true;
391   
392   GroupPoints->ComboBox1->setCurrentIndex( 8 - count + SelectedShapeType );
393   ComboTextChanged();
394
395   updateButtonState();
396 }
397
398
399 //=================================================================================
400 // function : SubShapeToggled()
401 // purpose  : Allow user selection of all or only selected sub shapes
402 //          : Called when 'CheckButton1' state change
403 //=================================================================================
404 void EntityGUI_SubShapeDlg::SubShapeToggled()
405 {
406   globalSelection( GEOM_ALLSHAPES );
407
408   if ( !isAllSubShapes() )
409     localSelection( myObject, shapeType() );
410 }
411
412
413 //=================================================================================
414 // function : ComboTextChanged()
415 // purpose  : 
416 //=================================================================================
417 void EntityGUI_SubShapeDlg::ComboTextChanged()
418 {
419   /* Select sub shapes mode not checked */
420   updateButtonState();
421   SubShapeToggled();    
422 }
423
424
425 //=================================================================================
426 // function : NumberOfSubShapes()
427 // purpose  :
428 //=================================================================================
429 unsigned int EntityGUI_SubShapeDlg::NumberOfSubShapes( const TopoDS_Shape& S,
430                                                        const int shapeType ) const
431 {
432   if ( S.IsNull() )
433     return 0;
434
435   unsigned int index = 0;
436   TopTools_MapOfShape M;
437
438   if ( S.ShapeType() == TopAbs_COMPOUND &&
439        ( TopAbs_ShapeEnum(shapeType) == TopAbs_SHAPE ||
440          TopAbs_ShapeEnum(shapeType) == TopAbs_COMPSOLID ||
441          TopAbs_ShapeEnum(shapeType) == TopAbs_COMPOUND ) ) {
442     TopoDS_Iterator It( S, Standard_True, Standard_True );
443     for ( ; It.More(); It.Next() ) {
444       if ( M.Add( It.Value() ) ) {
445         if ( TopAbs_ShapeEnum( shapeType ) == TopAbs_SHAPE ||
446              TopAbs_ShapeEnum( shapeType ) == It.Value().ShapeType() ) {
447           index++;
448         }
449       }
450     }
451   } 
452   else {
453     TopExp_Explorer Exp ( S, TopAbs_ShapeEnum( shapeType ) );
454     for ( ; Exp.More(); Exp.Next() ) {
455       if ( M.Add( Exp.Current() ) ) {
456         index++;
457       }
458     }
459   }
460
461   M.Clear();
462   return index;
463 }
464
465 //=================================================================================
466 // function : updateButtonState
467 // purpose  :
468 //=================================================================================
469 void EntityGUI_SubShapeDlg::updateButtonState()
470 {
471   if ( SUIT_Session::session()->activeApplication()->desktop()->activeWindow()->getViewManager()->getType() != OCCViewer_Viewer::Type() ||
472        myObject->_is_nil() || shapeType() == TopAbs_SHAPE || shapeType() == TopAbs_COMPOUND ) {
473     GroupPoints->CheckButton1->setChecked( false );
474     GroupPoints->CheckButton1->setEnabled( false );
475   }
476   else
477     GroupPoints->CheckButton1->setEnabled( true );
478 }
479
480 //=================================================================================
481 // function : isAllSubShapes
482 // purpose  :
483 //=================================================================================
484 bool EntityGUI_SubShapeDlg::isAllSubShapes() const
485 {
486   return !GroupPoints->CheckButton1->isChecked() || !GroupPoints->CheckButton1->isEnabled();
487 }
488
489 //=================================================================================
490 // function : shapeType
491 // purpose  :
492 //=================================================================================
493 int EntityGUI_SubShapeDlg::shapeType() const
494 {
495   int type = GroupPoints->ComboBox1->currentIndex();
496
497   if ( myObject->_is_nil() )
498     return type;
499
500   // Solving PAL5590
501   type += myShape.ShapeType() + 1;
502   if ( myShape.ShapeType() == TopAbs_COMPOUND &&
503        NumberOfSubShapes( myShape, TopAbs_COMPOUND ) > 0 ) {
504     type--;
505   }
506
507   return type;
508 }
509
510 //=================================================================================
511 // function : createOperation
512 // purpose  :
513 //=================================================================================
514 GEOM::GEOM_IOperations_ptr EntityGUI_SubShapeDlg::createOperation()
515 {
516   return getGeomEngine()->GetIShapesOperations( getStudyId() );
517 }
518
519 //=================================================================================
520 // function : isValid
521 // purpose  :
522 //=================================================================================
523 bool EntityGUI_SubShapeDlg::isValid (QString& msg)
524 {
525   bool isOk = false;
526
527   if (myObject->_is_nil()) {
528     updateButtonState();
529     return isOk;
530   }
531
532   if (isAllSubShapes())
533     isOk = true;
534   else {
535     LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
536     SALOME_ListIO aSelList;
537     aSelMgr->selectedObjects(aSelList);
538
539     if (aSelList.Extent() == 1) {
540       GEOM::GEOM_Object_var anObj = GEOMBase::ConvertIOinGEOMObject( aSelList.First() );
541       if ( !anObj->_is_nil() ) {
542         TColStd_IndexedMapOfInteger aMapIndex;
543         aSelMgr->GetIndexes(aSelList.First(), aMapIndex);
544         isOk = aMapIndex.Extent() > 0;
545         if (!isOk)
546           msg += tr("NO_SUBSHAPES_SELECTED");
547       }
548     }
549   }
550
551   return isOk;
552 }
553
554 //=================================================================================
555 // function : execute
556 // purpose  :
557 //=================================================================================
558 bool EntityGUI_SubShapeDlg::execute (ObjectList& objects)
559 {
560   GEOM::GEOM_IShapesOperations_var anOper = GEOM::GEOM_IShapesOperations::_narrow(getOperation());
561   GEOM::ListOfGO_var aList = anOper->ExtractSubShapes(myObject, shapeType(), true);
562
563   if (!aList->length())
564     return false;
565
566   // Throw away sub-shapes not selected by user if not in preview mode 
567   // and manual selection is active
568   if (!isAllSubShapes()) {
569     LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
570     SALOME_ListIO aSelList;
571     aSelMgr->selectedObjects(aSelList);
572
573     if (aSelList.Extent() == 1) {
574       GEOM::GEOM_Object_var anObj =
575         GEOMBase::ConvertIOinGEOMObject( aSelList.First() );
576
577       if ( !anObj->_is_nil() ) {
578         TColStd_IndexedMapOfInteger aMapIndex;
579         aSelMgr->GetIndexes(aSelList.First(), aMapIndex);
580
581         GEOM::GEOM_ILocalOperations_var aLocOp = 
582           getGeomEngine()->GetILocalOperations(getStudyId());
583
584         for (int i = 0, n = aList->length(); i < n; i++)
585           if (aMapIndex.Contains(aLocOp->GetSubShapeIndex(myObject, aList[i])))
586             objects.push_back(GEOM::GEOM_Object::_duplicate(aList[i]));
587       }
588     }
589   }
590   else
591     for (int i = 0, n = aList->length(); i < n; i++)
592       objects.push_back(GEOM::GEOM_Object::_duplicate(aList[i]));
593   
594   return objects.size();
595 }
596
597 //================================================================
598 // Function : getFather
599 // Purpose  : Get father object for object to be added in study
600 //            ( called with addInStudy method )
601 //================================================================
602 GEOM::GEOM_Object_ptr EntityGUI_SubShapeDlg::getFather( GEOM::GEOM_Object_ptr )
603 {
604   return myObject;
605 }
606
607 QString EntityGUI_SubShapeDlg::getNewObjectName() const
608 {
609   return QString::null;
610 }