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