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