Salome HOME
Update copyrights 2014.
[modules/geom.git] / src / RepairGUI / RepairGUI_SuppressFacesDlg.cxx
1 // Copyright (C) 2007-2014  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, or (at your option) any later version.
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 //  File   : RepairGUI_SuppressFacesDlg.cxx
23 //  Author : Lucien PIGNOLONI, Open CASCADE S.A.S.
24
25 #include "RepairGUI_SuppressFacesDlg.h"
26
27 #include <DlgRef.h>
28 #include <GeometryGUI.h>
29 #include <GEOMBase.h>
30
31 #include <SUIT_Session.h>
32 #include <SUIT_ResourceMgr.h>
33 #include <SalomeApp_Application.h>
34 #include <SalomeApp_Study.h>
35 #include <LightApp_SelectionMgr.h>
36 #include <SALOME_ListIteratorOfListIO.hxx>
37
38 // OCCT Includes
39 #include <TopAbs.hxx>
40 #include <TopExp.hxx>
41 #include <TopExp_Explorer.hxx>
42 #include <TopTools_IndexedMapOfShape.hxx>
43 #include <TColStd_MapOfInteger.hxx>
44 #include <TColStd_IndexedMapOfInteger.hxx>
45
46 #include <GEOMImpl_Types.hxx>
47
48 //=================================================================================
49 // class    : RepairGUI_SuppressFacesDlg()
50 // purpose  : Constructs a RepairGUI_SuppressFacesDlg  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 RepairGUI_SuppressFacesDlg::RepairGUI_SuppressFacesDlg (GeometryGUI* theGeometryGUI, QWidget* parent,
56                                                         bool modal)
57   : GEOMBase_Skeleton(theGeometryGUI, parent, modal)
58 {
59   QPixmap image0 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_SUPRESS_FACE")));
60   QPixmap image1 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
61
62   setWindowTitle(tr("GEOM_SUPRESSFACE_TITLE"));
63
64   /***************************************************************/
65   mainFrame()->GroupConstructors->setTitle(tr("GEOM_SUPRESSFACE"));
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   GroupArgs = new DlgRef_2Sel(centralWidget());
73   GroupArgs->GroupBox1->setTitle(tr("Faces to remove"));
74   GroupArgs->TextLabel1->setText(tr("GEOM_SELECTED_SHAPE"));
75   GroupArgs->PushButton1->setIcon(image1);
76   GroupArgs->LineEdit1->setReadOnly(true);
77
78   GroupArgs->TextLabel2->setText(tr("Faces to remove"));
79   GroupArgs->PushButton2->setIcon(image1);
80   GroupArgs->LineEdit2->setReadOnly(true);
81
82   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
83   layout->setMargin(0); layout->setSpacing(6);
84   layout->addWidget(GroupArgs);
85   /***************************************************************/
86
87   setHelpFileName("suppress_faces_operation_page.html");
88
89   Init();
90 }
91
92 //=================================================================================
93 // function : ~RepairGUI_SuppressFacesDlg()
94 // purpose  : Destroys the object and frees any allocated resources
95 //=================================================================================
96 RepairGUI_SuppressFacesDlg::~RepairGUI_SuppressFacesDlg()
97 {
98 }
99
100 //=================================================================================
101 // function : Init()
102 // purpose  :
103 //=================================================================================
104 void RepairGUI_SuppressFacesDlg::Init()
105 {
106   // init variables
107   GroupArgs->LineEdit1->clear();
108   GroupArgs->LineEdit2->clear();
109   myObject = GEOM::GEOM_Object::_nil();
110   myFacesInd = new GEOM::short_array();
111   myFacesInd->length(0);
112
113   mainFrame()->GroupBoxPublish->show();
114   //Hide preview checkbox
115   mainFrame()->CheckBoxPreview->hide();
116
117   // signals and slots connections
118   connect(buttonOk(),    SIGNAL(clicked()), this, SLOT(ClickOnOk()));
119   connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
120
121   connect(GroupArgs->PushButton1, SIGNAL(clicked()),       this, SLOT(SetEditCurrentArgument()));
122   connect(GroupArgs->PushButton2, SIGNAL(clicked()),       this, SLOT(SetEditCurrentArgument()));
123
124   connect(GroupArgs->LineEdit1,   SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
125   connect(GroupArgs->LineEdit2,   SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
126
127   initName(tr("SUPRESS_FACE_NEW_OBJ_NAME"));
128
129   GroupArgs->PushButton1->click();
130   SelectionIntoArgument();
131   resize(100,100);
132 }
133
134 //=================================================================================
135 // function : ClickOnOk()
136 // purpose  : Same than click on apply but close this dialog.
137 //=================================================================================
138 void RepairGUI_SuppressFacesDlg::ClickOnOk()
139 {
140   setIsApplyAndClose( true );
141   if (ClickOnApply())
142     ClickOnCancel();
143 }
144
145 //=================================================================================
146 // function : ClickOnApply()
147 // purpose  :
148 //=================================================================================
149 bool RepairGUI_SuppressFacesDlg::ClickOnApply()
150 {
151   if (!onAccept())
152     return false;
153
154   initName();
155   // activate first line edit
156   GroupArgs->PushButton1->click();
157   return true;
158 }
159
160 //=================================================================================
161 // function : SelectionIntoArgument()
162 // purpose  : Called when selection is changed or on dialog initialization or activation
163 //=================================================================================
164 void RepairGUI_SuppressFacesDlg::SelectionIntoArgument()
165 {
166   myEditCurrentArgument->setText("");
167   // the second argument depends on the first one
168   GroupArgs->LineEdit2->setText("");
169   myFacesInd->length(0);
170
171   if (myEditCurrentArgument == GroupArgs->LineEdit1)
172     myObject = GEOM::GEOM_Object::_nil();
173
174   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
175   SALOME_ListIO aSelList;
176   aSelMgr->selectedObjects(aSelList);
177
178   if (myEditCurrentArgument == GroupArgs->LineEdit1) {
179     if (aSelList.Extent() == 1) {
180       Handle(SALOME_InteractiveObject) anIO = aSelList.First();
181
182       myObject = GEOMBase::ConvertIOinGEOMObject( anIO );
183       if ( GEOMBase::IsShape(myObject) ) {
184         myEditCurrentArgument->setText(GEOMBase::GetName(myObject));
185         TopoDS_Shape aShape;
186         if (GEOMBase::GetShape(myObject, aShape, TopAbs_FACE))
187           GroupArgs->LineEdit2->setText(myEditCurrentArgument->text());
188
189         // clear selection
190         disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
191         myGeomGUI->getApp()->selectionMgr()->clearSelected();
192         connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
193                 this, SLOT(SelectionIntoArgument()));
194
195         GroupArgs->PushButton2->click();
196       }
197       else
198         myObject = GEOM::GEOM_Object::_nil();
199     }
200   }
201   else if (myEditCurrentArgument == GroupArgs->LineEdit2) {
202     TColStd_IndexedMapOfInteger aMap;
203
204     if (aSelList.Extent() == 1) {
205       Handle(SALOME_InteractiveObject) anIO = aSelList.First();
206       aSelMgr->GetIndexes(anIO, aMap);
207     }
208
209     if (aMap.IsEmpty() && aSelList.Extent() > 0) { // try to detect selected published sub-shape
210       TColStd_MapOfInteger anIds;
211
212       SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>(myGeomGUI->getApp()->activeStudy());
213       if (!appStudy) return;
214       _PTR(Study) aStudy = appStudy->studyDS();
215
216       TopTools_IndexedMapOfShape aMainMap;
217       TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myObject);
218       TopExp::MapShapes(aMainShape, aMainMap);
219
220       SALOME_ListIteratorOfListIO anIter (aSelList);
221       for (int i = 0; anIter.More(); anIter.Next(), i++) {
222         Handle(SALOME_InteractiveObject) anIO = anIter.Value();
223         QString anEntry = anIO->getEntry();
224
225         _PTR(SObject) aSObj (aStudy->FindObjectID(anEntry.toLatin1().constData()));
226         GEOM::GEOM_Object_var aGeomObj =
227           GEOM::GEOM_Object::_narrow(GeometryGUI::ClientSObjectToObject(aSObj));
228         TopoDS_Shape aShape;
229         if (GEOMBase::GetShape(aGeomObj, aShape)) {
230           if (aGeomObj->GetType() == GEOM_GROUP || aShape.ShapeType() == TopAbs_FACE) {
231             TopExp_Explorer anExp (aShape, TopAbs_FACE);
232             for (; anExp.More(); anExp.Next()) {
233               TopoDS_Shape aSubShape = anExp.Current();
234               int anIndex = aMainMap.FindIndex(aSubShape);
235               if (anIndex >= 0) {
236                 aMap.Add(anIndex);
237                 anIds.Add(anIndex);
238               }
239             }
240           }
241         }
242       }
243       if (!aMap.IsEmpty()) {
244         // highlight local faces, correspondent to OB selection
245         disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
246
247         aSelMgr->clearSelected();
248
249         QString objIOR = GEOMBase::GetIORFromObject(myObject);
250         Handle(GEOM_AISShape) aSh = GEOMBase::ConvertIORinGEOMAISShape( objIOR, true );
251         if ( aSh.IsNull() )
252           return;
253
254         aSelMgr->AddOrRemoveIndex(aSh->getIO(), anIds, false);
255
256         connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
257                 this, SLOT(SelectionIntoArgument()));
258       }
259     }
260
261     const int n = aMap.Extent();
262     myFacesInd->length(n);
263     for (int i = 1; i <= n; i++)
264       myFacesInd[i-1] = aMap(i);
265     if (n)
266       myEditCurrentArgument->setText(QString::number(n) + "_" + tr("GEOM_FACE") + tr("_S_"));
267   }
268 }
269
270 //=================================================================================
271 // function : SetEditCurrentArgument()
272 // purpose  :
273 //=================================================================================
274 void RepairGUI_SuppressFacesDlg::SetEditCurrentArgument()
275 {
276   QPushButton* send = (QPushButton*)sender();
277
278   bool isEffective = false;
279
280   if (send == GroupArgs->PushButton1) {
281     isEffective = true;
282     myEditCurrentArgument = GroupArgs->LineEdit1;
283
284     GroupArgs->PushButton2->setDown(false);
285     GroupArgs->LineEdit2->setEnabled(false);
286   }
287   else if (send == GroupArgs->PushButton2 && !myObject->_is_nil()) {
288     isEffective = true;
289     myEditCurrentArgument = GroupArgs->LineEdit2;
290
291     GroupArgs->PushButton1->setDown(false);
292     GroupArgs->LineEdit1->setEnabled(false);
293   }
294
295   if (isEffective) {
296     initSelection();
297
298     // enable line edit
299     myEditCurrentArgument->setEnabled(true);
300     myEditCurrentArgument->setFocus();
301     // after setFocus(), because it will be setDown(false) when loses focus
302     send->setDown(true);
303   }
304 }
305
306 //=================================================================================
307 // function : LineEditReturnPressed()
308 // purpose  :
309 //=================================================================================
310 void RepairGUI_SuppressFacesDlg::LineEditReturnPressed()
311 {
312   const QObject* send = sender();
313   if (send == GroupArgs->LineEdit1 || send == GroupArgs->LineEdit2) {
314     myEditCurrentArgument = (QLineEdit*)send;
315     GEOMBase_Skeleton::LineEditReturnPressed();
316   }
317 }
318
319 //=================================================================================
320 // function : ActivateThisDialog()
321 // purpose  :
322 //=================================================================================
323 void RepairGUI_SuppressFacesDlg::ActivateThisDialog()
324 {
325   GEOMBase_Skeleton::ActivateThisDialog();
326   connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),
327            this, SLOT( SelectionIntoArgument() ) );
328
329   myEditCurrentArgument = GroupArgs->LineEdit1;
330   myEditCurrentArgument->setText( "" );
331   GroupArgs->LineEdit2->setText( "" );
332   myObject = GEOM::GEOM_Object::_nil();
333   myFacesInd->length( 0 );
334
335   initSelection();
336 }
337
338 //=================================================================================
339 // function : enterEvent()
340 // purpose  : Mouse enter onto the dialog to activate it
341 //=================================================================================
342 void RepairGUI_SuppressFacesDlg::enterEvent (QEvent*)
343 {
344   if (!mainFrame()->GroupConstructors->isEnabled())
345     ActivateThisDialog();
346 }
347
348 //=================================================================================
349 // function : createOperation
350 // purpose  :
351 //=================================================================================
352 GEOM::GEOM_IOperations_ptr RepairGUI_SuppressFacesDlg::createOperation()
353 {
354   return getGeomEngine()->GetIHealingOperations(getStudyId());
355 }
356
357 //=================================================================================
358 // function : isValid
359 // purpose  :
360 //=================================================================================
361 bool RepairGUI_SuppressFacesDlg::isValid (QString&)
362 {
363   TopoDS_Shape aTmpShape;
364   return !myObject->_is_nil() && (myFacesInd->length() ||
365                                   GEOMBase::GetShape(myObject, aTmpShape, TopAbs_WIRE));
366 }
367
368 //=================================================================================
369 // function : execute
370 // purpose  :
371 //=================================================================================
372 bool RepairGUI_SuppressFacesDlg::execute (ObjectList& objects)
373 {
374   GEOM::GEOM_IHealingOperations_var anOper = GEOM::GEOM_IHealingOperations::_narrow(getOperation());
375   GEOM::GEOM_Object_var anObj = anOper->SuppressFaces(myObject, myFacesInd);
376
377   bool aResult = !anObj->_is_nil();
378   if (aResult)
379     objects.push_back(anObj._retn());
380
381   return aResult;
382 }
383
384 //=================================================================================
385 // function : initSelection
386 // purpose  :
387 //=================================================================================
388 void RepairGUI_SuppressFacesDlg::initSelection()
389 {
390   disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
391
392   if (myEditCurrentArgument == GroupArgs->LineEdit1) {
393     TColStd_MapOfInteger aTypes;
394     aTypes.Add(GEOM_COMPOUND);
395     aTypes.Add(GEOM_SOLID);
396     aTypes.Add(GEOM_SHELL);
397     aTypes.Add(GEOM_FACE);
398
399     globalSelection(aTypes);
400   }
401   else if (myEditCurrentArgument == GroupArgs->LineEdit2) {
402     localSelection(myObject, TopAbs_FACE);
403   }
404
405   connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
406           this, SLOT(SelectionIntoArgument()));
407 }
408
409 //=================================================================================
410 // function : restoreSubShapes
411 // purpose  :
412 //=================================================================================
413 void RepairGUI_SuppressFacesDlg::restoreSubShapes (SALOMEDS::Study_ptr   theStudy,
414                                                    SALOMEDS::SObject_ptr theSObject)
415 {
416   if (mainFrame()->CheckBoxRestoreSS->isChecked()) {
417     // empty list of arguments means that all arguments should be restored
418     getGeomEngine()->RestoreSubShapesSO(theStudy, theSObject, GEOM::ListOfGO(),
419                                         /*theFindMethod=*/GEOM::FSM_GetInPlace,
420                                         /*theInheritFirstArg=*/true,
421                                         mainFrame()->CheckBoxAddPrefix->isChecked());
422   }
423 }