Salome HOME
Update copyright
[modules/geom.git] / src / RepairGUI / RepairGUI_ShapeProcessDlg.cxx
1 // Copyright (C) 2007-2011  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
23 // GEOM GEOMGUI : GUI for Geometry component
24 // File   : RepairGUI_ShapeProcessDlg.cxx
25 // Author : Lucien PIGNOLONI, Open CASCADE S.A.S.
26 //
27 #include "RepairGUI_ShapeProcessDlg.h"
28
29 #include <DlgRef.h>
30 #include <GeometryGUI.h>
31 #include <GEOMBase.h>
32 #include <GEOMImpl_Types.hxx>
33
34 #include <SalomeApp_Application.h>
35 #include <SalomeApp_DoubleSpinBox.h>
36 #include <SalomeApp_IntSpinBox.h>
37 #include <LightApp_SelectionMgr.h>
38 #include <SUIT_Session.h>
39 #include <SUIT_ResourceMgr.h>
40 #include <SUIT_MessageBox.h>
41 #include <SALOME_ListIteratorOfListIO.hxx>
42 #include <SALOME_ListIO.hxx>
43
44 #include <TCollection_AsciiString.hxx>
45 #include <TColStd_MapOfInteger.hxx>
46
47 #include <QListWidget>
48 #include <QStackedLayout>
49
50 //=================================================================================
51 // class    : RepairGUI_ShapeProcessDlg()
52 // purpose  : Constructs a RepairGUI_ShapeProcessDlg  which is a child of 'parent', with the
53 //            name 'name' and widget flags set to 'f'.
54 //            The dialog will by default be modeless, unless you set 'modal' to
55 //            TRUE to construct a modal dialog.
56 //=================================================================================
57 RepairGUI_ShapeProcessDlg::RepairGUI_ShapeProcessDlg( GeometryGUI* theGeometryGUI, QWidget* parent,
58                                                       bool modal )
59   : GEOMBase_Skeleton( theGeometryGUI, parent, modal )
60 {
61   setHelpFileName( "shape_processing_operation_page.html" );
62   init();
63 }
64
65 //=================================================================================
66 // function : ~RepairGUI_ShapeProcessDlg()
67 // purpose  : Destroys the object and frees any allocated resources
68 //=================================================================================
69 RepairGUI_ShapeProcessDlg::~RepairGUI_ShapeProcessDlg()
70 {
71 }
72
73 //=================================================================================
74 // function : Init()
75 // purpose  :
76 //=================================================================================
77 void RepairGUI_ShapeProcessDlg::init()
78 {
79   //myGeomGUI->SetState( 0 );
80
81   initParamsValues();
82   initSelection();
83         
84   setWindowTitle( tr( "GEOM_SHAPEPROCESS_TITLE" ) );
85
86   mainFrame()->GroupConstructors->hide();
87   
88   // select widget on the top 
89   mySelectWdgt = new DlgRef_1Sel( centralWidget() );
90   mySelectWdgt->GroupBox1->setTitle( tr( "GEOM_SHAPE" ) );
91   mySelectWdgt->TextLabel1->setText( tr( "GEOM_SELECTED_OBJECTS" ) );
92   mySelectWdgt->PushButton1->setIcon( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) );
93   mySelectWdgt->LineEdit1->setReadOnly( true );
94
95   // layout the two group boxes in the middle, add a list of operations
96   QGroupBox* anOperGr = new QGroupBox( tr( "GEOM_OPERATIONS" ), centralWidget() );
97
98   // operations list widget
99   myOpList = new QListWidget( anOperGr );
100   myOpList->setSortingEnabled( false );
101   myOpList->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
102
103   QVBoxLayout* aOperLay = new QVBoxLayout( anOperGr );
104   aOperLay->setMargin( 9 );
105   aOperLay->addWidget( myOpList );
106
107   QGroupBox* aParamsGr = new QGroupBox( tr( "GEOM_PARAMETERS" ), centralWidget() );
108
109   // add a widget stack to the parameters group box
110   QStackedLayout* aStack = new QStackedLayout( aParamsGr );
111
112   // continueties values..
113   QStringList aContinueties = QString( "C0,G1,C1,G2,C2,C3,CN" ).split( "," );
114
115   // fill in the widgets
116   for ( int i = 0; i < myOpLst.count(); i++ ) {
117     QListWidgetItem* item = new QListWidgetItem( myOpLst[i] );
118     item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable );
119     item->setCheckState( Qt::Unchecked );
120     myOpList->addItem( item );
121
122     QWidget* w;
123     if ( myOpLst[i] == "FixShape" ) {
124       // FixShape
125       w = new QWidget( aParamsGr );
126       QGridLayout* aLay = new QGridLayout( w );
127       aLay->setMargin( 9 ); aLay->setSpacing( 6 );
128       
129       myFixShapeTol3D = new SalomeApp_DoubleSpinBox( w );
130       initSpinBox( myFixShapeTol3D, 0., 100., 1e-7, "len_tol_precision" );
131       myFixShapeMaxTol3D = new SalomeApp_DoubleSpinBox( w );
132       initSpinBox( myFixShapeMaxTol3D, 0., 100., 1e-7, "len_tol_precision" );      
133       
134       aLay->addWidget( new QLabel( tr( "GEOM_3D_TOLERANCE" ), w ), 0, 0 );
135       aLay->addWidget( myFixShapeTol3D, 0, 1 );
136       aLay->addWidget( new QLabel( tr( "GEOM_MAX_3D_TOLERANCE" ), w ), 1, 0 );
137       aLay->addWidget( myFixShapeMaxTol3D, 1, 1 );
138       aLay->setRowStretch( aLay->rowCount(), 5 );
139     }
140     else if ( myOpLst[i] == "FixFaceSize" ) {
141       // FixFaceSize  
142       w = new QWidget( aParamsGr );
143       QGridLayout* aLay = new QGridLayout( w );
144       aLay->setMargin( 9 ); aLay->setSpacing( 6 );
145       
146       myFixFaceSizeTol = new SalomeApp_DoubleSpinBox( w );
147       initSpinBox( myFixFaceSizeTol, 0., 100., 1e-7, "len_tol_precision" );      
148       
149       aLay->addWidget( new QLabel( tr( "GEOM_TOLERANCE" ), w ), 0, 0 );
150       aLay->addWidget( myFixFaceSizeTol, 0, 1 );
151       aLay->setRowStretch( aLay->rowCount(), 5 );
152     }
153     else if ( myOpLst[i] == "DropSmallEdges" ) {
154       // DropSmallEdges
155       w = new QWidget( aParamsGr );
156       QGridLayout* aLay = new QGridLayout( w );
157       aLay->setMargin( 9 ); aLay->setSpacing( 6 );
158       
159       myDropSmallEdgesTol3D = new SalomeApp_DoubleSpinBox( w );
160       initSpinBox( myDropSmallEdgesTol3D, 0., 100., 1e-7, "len_tol_precision" );
161   
162       aLay->addWidget( new QLabel( tr( "GEOM_3D_TOLERANCE" ), w ), 0, 0 );
163       aLay->addWidget( myDropSmallEdgesTol3D, 0, 1 );
164       aLay->setRowStretch( aLay->rowCount(), 5 );
165     }
166     else if ( myOpLst[i] == "SplitAngle" ) {
167       // SplitAngle
168       w = new QWidget( aParamsGr );
169       QGridLayout* aLay = new QGridLayout( w );
170       aLay->setMargin( 9 ); aLay->setSpacing( 6 );
171       
172       mySplitAngleAngle = new SalomeApp_DoubleSpinBox( w );
173       initSpinBox( mySplitAngleAngle, 0, 360, 1, "angle_precision" );      
174       mySplitAngleMaxTol = new SalomeApp_DoubleSpinBox( w );
175       initSpinBox( mySplitAngleMaxTol, 0., 100., 1e-7, "ang_tol_precision" );      
176       
177       aLay->addWidget( new QLabel( tr( "GEOM_ANGLE_1" ), w ), 0, 0 );
178       aLay->addWidget( mySplitAngleAngle, 0, 1 );
179       aLay->addWidget( new QLabel( tr( "GEOM_MAX_TOLERANCE" ), w ), 1, 0 );
180       aLay->addWidget( mySplitAngleMaxTol, 1, 1 );
181       aLay->setRowStretch( aLay->rowCount(), 5 );
182     }
183     else if ( myOpLst[i] == "SplitClosedFaces" ) {
184       // SplitClosedFaces
185       w = new QWidget( aParamsGr );
186       QGridLayout* aLay = new QGridLayout( w );
187       aLay->setMargin( 9 ); aLay->setSpacing( 6 );
188       
189       mySplitClosedFacesNum = new SalomeApp_IntSpinBox( w );
190   
191       aLay->addWidget( new QLabel( tr( "GEOM_NUM_SPLIT_POINTS" ), w ), 0, 0 );
192       aLay->addWidget( mySplitClosedFacesNum, 0, 1 );
193       aLay->setRowStretch( aLay->rowCount(), 5 );
194     }      
195     else if ( myOpLst[i] == "SplitContinuity" ) {
196       // SplitContinuity
197       w = new QWidget( aParamsGr );
198       QGridLayout* aLay = new QGridLayout( w );
199       aLay->setMargin( 9 ); aLay->setSpacing( 6 );
200
201       mySplitContTol3D = new SalomeApp_DoubleSpinBox( w );
202       initSpinBox( mySplitContTol3D, 0., 100., 1e-7, "len_tol_precision" );
203       mySplitContSurfCont = new QComboBox( w );
204       mySplitContSurfCont->addItems( aContinueties );
205       mySplitContCurvCont = new QComboBox( w );
206       mySplitContCurvCont->addItems( aContinueties );
207       
208       aLay->addWidget( new QLabel( tr( "GEOM_3D_TOLERANCE" ), w ), 0, 0 );
209       aLay->addWidget( mySplitContTol3D, 0, 1 );
210       aLay->addWidget( new QLabel( tr( "GEOM_SURFACE_CONTINUTY" ), w ), 1, 0 );
211       aLay->addWidget( mySplitContSurfCont, 1, 1 );
212       aLay->addWidget( new QLabel( tr( "GEOM_CURVE_CONTINUTY" ), w ), 2, 0 );
213       aLay->addWidget( mySplitContCurvCont, 2, 1 );
214       aLay->setRowStretch( aLay->rowCount(), 5 );
215     }
216     else if ( myOpLst[i] == "BSplineRestriction" ) {
217       // BSplineRestriction
218       w = new QWidget( aParamsGr );
219       QGridLayout* aLay = new QGridLayout( w );
220       aLay->setMargin( 9 ); aLay->setSpacing( 6 );
221
222       myBSplineSurfModeChk = new QCheckBox( tr("GEOM_SURFACE_MODE"), w );
223       myBSpline3DCurveChk = new QCheckBox( tr("GEOM_3D_CURVE_MODE"), w );
224       myBSpline2DCurveChk = new QCheckBox( tr("GEOM_2D_CURVE_MODE"), w );
225
226       myBSplineTol3D = new SalomeApp_DoubleSpinBox( w );
227       initSpinBox( myBSplineTol3D, 0., 100., 1e-7, "len_tol_precision" );
228       
229       myBSplineTol2D = new SalomeApp_DoubleSpinBox( w );
230       initSpinBox( myBSplineTol2D, 0., 100., 1e-7, "param_tol_precision" );      
231
232       myBSplineDegree = new SalomeApp_IntSpinBox( w );
233       myBSplineSegments = new SalomeApp_IntSpinBox( w );
234       myBSpline2DCont = new QComboBox( w );
235       myBSpline2DCont->addItems( aContinueties );
236       myBSpline3DCont = new QComboBox( w );
237       myBSpline3DCont->addItems( aContinueties );
238       
239       myBSplineSurfModeChk->setChecked( true );
240       myBSpline3DCurveChk->setChecked( true );
241       myBSpline2DCurveChk->setChecked( true );
242
243       aLay->addWidget( myBSplineSurfModeChk, 0, 0 );
244       aLay->addWidget( myBSpline3DCurveChk,  1, 0 );
245       aLay->addWidget( myBSpline2DCurveChk,  2, 0 );
246       aLay->addWidget( new QLabel( tr( "GEOM_3D_TOLERANCE" ), w ), 3, 0 );
247       aLay->addWidget( myBSplineTol3D, 3, 1 );
248       aLay->addWidget( new QLabel( tr( "GEOM_2D_TOLERANCE" ), w ), 4, 0 );
249       aLay->addWidget( myBSplineTol2D, 4, 1 );
250       aLay->addWidget( new QLabel( tr( "GEOM_REQUIRED_DEGREE" ), w ), 5, 0 );
251       aLay->addWidget( myBSplineDegree, 5, 1 );
252       aLay->addWidget( new QLabel( tr( "GEOM_REQUIRED_NUM_SEGMENTS" ), w ), 6, 0 );
253       aLay->addWidget( myBSplineSegments, 6, 1 );
254       aLay->addWidget( new QLabel( tr( "GEOM_3D_CONTINUTY" ), w ), 7, 0 );
255       aLay->addWidget( myBSpline3DCont, 7, 1 );
256       aLay->addWidget( new QLabel( tr( "GEOM_2D_CONTINUTY" ), w ), 8, 0 );
257       aLay->addWidget( myBSpline2DCont, 8, 1 );
258       aLay->setRowStretch( aLay->rowCount(), 5 );
259     }
260     else if ( myOpLst[i] == "ToBezier" ) {
261       // ToBezier
262       w = new QWidget( aParamsGr );
263       QGridLayout* aLay = new QGridLayout( w );
264       aLay->setMargin( 9 ); aLay->setSpacing( 6 );
265
266       myToBezierSurfModeChk = new QCheckBox( tr("GEOM_SURFACE_MODE"), w );
267       myToBezier3DCurveChk = new QCheckBox( tr("GEOM_3D_CURVE_MODE"), w );
268       myToBezier2DCurveChk = new QCheckBox( tr("GEOM_2D_CURVE_MODE"), w );
269   
270       myToBezierMaxTol = new SalomeApp_DoubleSpinBox( w );
271       initSpinBox( myToBezierMaxTol, 0., 100., 1e-7, "len_tol_precision" );            
272
273       aLay->addWidget( myToBezierSurfModeChk, 0, 0 );
274       aLay->addWidget( myToBezier3DCurveChk, 1, 0 );
275       aLay->addWidget( myToBezier2DCurveChk, 2, 0 );
276       aLay->addWidget( new QLabel( tr( "GEOM_MAX_TOLERANCE" ), w ), 3, 0 );
277       aLay->addWidget( myToBezierMaxTol, 3, 1 );
278       aLay->setRowStretch( aLay->rowCount(), 5 );
279     }
280     else if ( myOpLst[i] == "SameParameter" ) {
281       // SameParameter
282       w = new QWidget( aParamsGr );
283       QGridLayout* aLay = new QGridLayout( w );
284       aLay->setMargin( 9 ); aLay->setSpacing( 6 );
285
286       mySameParameterTol3D = new SalomeApp_DoubleSpinBox( w );
287       initSpinBox( mySameParameterTol3D, 0., 100., 1e-7, "len_tol_precision" );            
288       
289       aLay->addWidget( new QLabel( tr( "GEOM_3D_TOLERANCE" ), w ), 0, 0 );
290       aLay->addWidget( mySameParameterTol3D, 0, 1 );
291       aLay->setRowStretch( aLay->rowCount(), 5 );
292     }
293     else {
294       w = new QWidget( aParamsGr ); // dumb widget
295     }
296     aStack->insertWidget( i, w );
297   }
298
299   QGridLayout* layout = new QGridLayout( centralWidget() );
300   layout->setMargin( 0 ); layout->setSpacing( 6 );
301   layout->addWidget( mySelectWdgt, 0, 0, 1, 2 );
302   layout->addWidget( anOperGr,     1, 0 );
303   layout->addWidget( aParamsGr,    1, 1 );
304
305   // signals and slots connections
306   connect( buttonOk(),    SIGNAL( clicked() ), this, SLOT( onOk() ) );
307   connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( onApply() ) );
308
309   connect( ( (SalomeApp_Application*)( SUIT_Session::session()->activeApplication() ) )->selectionMgr(),
310            SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) );
311
312   connect( mySelectWdgt->PushButton1, SIGNAL( clicked() ),       this, SLOT( selectClicked() ) );
313   connect( mySelectWdgt->LineEdit1,   SIGNAL( returnPressed() ), this, SLOT( lineEditReturnPressed() ) );
314
315   connect( myToBezierSurfModeChk,     SIGNAL( toggled( bool ) ), this, SLOT( advOptionToggled( bool ) ) );
316
317   connect( myOpList, SIGNAL( currentRowChanged( int ) ), aStack, SLOT( setCurrentIndex( int ) ) );
318
319   adjustSize();
320   loadDefaults(); // init dialog fields with values from resource file
321   //myOpList->setCurrentRow( myOpList->findItem( 0 );
322   reset();
323
324   initName( tr( "PROCESS_SHAPE_NEW_OBJ_NAME" ) );
325   selectionChanged();
326 }
327
328 //=================================================================================
329 // function : onOk()
330 // purpose  : Same than click on apply but close this dialog.
331 //=================================================================================
332 void RepairGUI_ShapeProcessDlg::onOk()
333 {
334   setIsApplyAndClose( true );
335   if ( onApply() )
336     ClickOnCancel();
337 }
338
339 //=================================================================================
340 // function : onApply()
341 // purpose  :
342 //=================================================================================
343 bool RepairGUI_ShapeProcessDlg::onApply()
344 {
345   if ( !onAccept() )
346     return false;
347
348   initName();
349
350   reset();
351   initSelection();
352   
353   return true;
354 }
355
356
357 //=================================================================================
358 // function : selectionChanged()
359 // purpose  : Called when selection as changed or other case
360 //          : used only by SelectButtonC1A1 (LineEditC1A1)
361 //=================================================================================
362 void RepairGUI_ShapeProcessDlg::selectionChanged()
363 {
364   reset();
365         
366   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
367   SALOME_ListIO aSelList;
368   aSelMgr->selectedObjects(aSelList);
369
370   int i = 0;
371   myObjects->length(aSelList.Extent());
372   for (SALOME_ListIteratorOfListIO anIt (aSelList); anIt.More(); anIt.Next()) {
373     GEOM::GEOM_Object_var aSelectedObject = GEOMBase::ConvertIOinGEOMObject( anIt.Value() );
374     if ( !CORBA::is_nil( aSelectedObject ) )
375       myObjects[i++] = aSelectedObject;
376   }
377   myObjects->length( i );
378   if ( i == 1 )
379     mySelectWdgt->LineEdit1->setText( GEOMBase::GetName( myObjects[0] ) );
380   else if ( i > 0 )
381     mySelectWdgt->LineEdit1->setText( QString::number( i ) + "_" + tr( "GEOM_OBJECTS" ) );
382 }
383
384
385 //=================================================================================
386 // function : selectClicked()
387 // purpose  :
388 //=================================================================================
389 void RepairGUI_ShapeProcessDlg::selectClicked()
390 {
391   myEditCurrentArgument = mySelectWdgt->LineEdit1;
392   mySelectWdgt->LineEdit1->setFocus();
393   selectionChanged();
394 }
395
396
397 //=================================================================================
398 // function : lineEditReturnPressed()
399 // purpose  :
400 //=================================================================================
401 void RepairGUI_ShapeProcessDlg::lineEditReturnPressed()
402 {
403   GEOMBase_Skeleton::LineEditReturnPressed();
404 }
405
406
407 //=================================================================================
408 // function : activate()
409 // purpose  :
410 //=================================================================================
411 void RepairGUI_ShapeProcessDlg::activate()
412 {
413   GEOMBase_Skeleton::ActivateThisDialog();
414   connect( ( (SalomeApp_Application*)( SUIT_Session::session()->activeApplication( ) ))->selectionMgr(),
415            SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) );
416         
417   reset();
418   //myGeomGUI->SetState( 0 );
419   initSelection();
420 }
421
422
423 //=================================================================================
424 // function : enterEvent()
425 // purpose  : Mouse enter onto the dialog to activate it
426 //=================================================================================
427 void RepairGUI_ShapeProcessDlg::enterEvent( QEvent* )
428 {
429   if ( !mainFrame()->GroupBoxName->isEnabled() )
430     activate();
431 }
432
433
434 //=================================================================================
435 // function : reset()
436 // purpose  : Completely reset the state of method including local context
437 //=================================================================================
438 void RepairGUI_ShapeProcessDlg::reset()
439 {
440   myObjects = new GEOM::ListOfGO();
441   myObjects->length( 0 );       
442   mySelectWdgt->LineEdit1->setText( "" );
443 }
444
445
446 //=================================================================================
447 // function : get_convert
448 // purpose  : conversion of angle values to radians (non-angle values are not converted)
449 //=================================================================================
450 const char* get_convert( const char* theParam, const QString& theValue )
451 {
452   if ( !strcmp( theParam, "SplitAngle.Angle" ) ) {
453     double doubleValue = theValue.toDouble() * PI / 180;
454     return CORBA::string_dup( QString::number( doubleValue ).toLatin1().constData() );
455   }
456   return CORBA::string_dup( theValue.toLatin1().constData() );
457 }
458
459 //=================================================================================
460 // function : set_convert
461 // purpose  : conversion of angle values to degrees (non-angle values are not converted)
462 //=================================================================================
463 const char* set_convert( const char* theParam, const char* theValue )
464 {
465   if ( !strcmp( theParam, "SplitAngle.Angle" ) ) {
466     double doubleValue = atof( theValue ) * 180 / PI;
467     TCollection_AsciiString str( doubleValue );
468     return CORBA::string_dup( str.ToCString() );
469   }
470   return CORBA::string_dup( theValue );
471 }
472
473 //=================================================================================
474 // function : loadDefaults()
475 // purpose  : initialize "values"-fields with default values retrieved from IHealingOperations
476 //=================================================================================
477 void RepairGUI_ShapeProcessDlg::loadDefaults()
478 {
479   GEOM::GEOM_IHealingOperations_var anOp = myGeomGUI->GetGeomGen()->GetIHealingOperations( getStudyId() );
480   GEOM::string_array_var anOperators, aParams, aValues;
481   anOp->GetShapeProcessParameters( anOperators, aParams, aValues );
482
483   // check the default items-operators
484   for ( int i = 0; i < anOperators->length(); i++ ) {
485     //MESSAGE("-->"<<(const char*)anOperators[i]);
486     QList<QListWidgetItem*> items = myOpList->findItems ( (const char*)anOperators[i], Qt::MatchFixedString );
487     if ( items.count() ) 
488       ( items[0] )->setCheckState( Qt::Checked );
489   }
490
491   // Retrieve default parameters for ALL operators
492   for ( int i = 0; i < myOpList->count(); i++ ) {
493     CORBA::String_var anOperator = CORBA::string_dup( myOpList->item( i )->text().toLatin1().constData() );
494     anOp->GetOperatorParameters( anOperator.in(), aParams, aValues );
495
496     // set default values of parameters
497     if ( aParams->length() != aValues->length() )
498       continue;
499
500     for ( int j = 0; j < aParams->length(); j++ ) {
501       QWidget* aCtrl = getControl( (const char*)aParams[j] );
502       const char* aValue = set_convert( (const char*)aParams[j], aValues[j] );
503       setValue( aCtrl, aValue );
504     }
505   }
506 }
507
508 //=================================================================================
509 // function : setValue()
510 // purpose  : set value in the proper way
511 //=================================================================================
512 void RepairGUI_ShapeProcessDlg::setValue( QWidget* theControl, const QString& theValue )
513 {
514   if ( theControl && !theValue.isNull() ) {
515     if ( qobject_cast<SalomeApp_DoubleSpinBox*>( theControl ) )
516       qobject_cast<SalomeApp_DoubleSpinBox*>( theControl )->setValue( theValue.toDouble() );
517     else if ( qobject_cast<SalomeApp_IntSpinBox*>( theControl ) )
518       qobject_cast<SalomeApp_IntSpinBox*>( theControl )->setValue( theValue.toInt() );
519     else if ( qobject_cast<QComboBox*>( theControl ) )
520       qobject_cast<QComboBox*>( theControl )->setEditText( theValue );
521     else if ( qobject_cast<QCheckBox*>( theControl ) )
522       qobject_cast<QCheckBox*>( theControl )->setChecked( theValue.toInt() != 0 );
523   }
524 }
525
526 //=================================================================================
527 // function : getValue()
528 // purpose  : get value in the proper way
529 //=================================================================================
530 QString RepairGUI_ShapeProcessDlg::getValue( QWidget* theControl ) const
531 {
532   if ( theControl ) {
533     if ( qobject_cast<SalomeApp_DoubleSpinBox*>( theControl ) )
534       return QString::number( qobject_cast<SalomeApp_DoubleSpinBox*>( theControl )->value() );
535     else if ( qobject_cast<SalomeApp_IntSpinBox*>( theControl ) )
536       return QString::number( qobject_cast<SalomeApp_IntSpinBox*>( theControl )->value() );
537     else if ( qobject_cast<QComboBox*>( theControl ) )
538       return qobject_cast<QComboBox*>( theControl )->currentText();
539     else if ( qobject_cast<QCheckBox*>( theControl ) )
540       return qobject_cast<QCheckBox*>( theControl )->isChecked() ? "1" : "0";
541   }   
542   return 0;
543 }
544
545 //=================================================================================
546 // function : getText()
547 // purpose  : get text in the proper way
548 //=================================================================================
549 QString RepairGUI_ShapeProcessDlg::getText( QWidget* theControl ) const
550 {
551   if ( theControl ) {
552     if ( qobject_cast<SalomeApp_DoubleSpinBox*>( theControl ) )
553       return qobject_cast<SalomeApp_DoubleSpinBox*>( theControl )->text();
554     else if ( qobject_cast<SalomeApp_IntSpinBox*>( theControl ) )
555       return qobject_cast<SalomeApp_IntSpinBox*>( theControl )->text();
556   }   
557   return QString::null;
558 }
559
560 //=================================================================================
561 // function : createOperation
562 // purpose  :
563 //=================================================================================
564 GEOM::GEOM_IOperations_ptr RepairGUI_ShapeProcessDlg::createOperation()
565 {
566   return getGeomEngine()->GetIHealingOperations( getStudyId() );
567 }
568
569 //=================================================================================
570 // function : isValid
571 // purpose  :
572 //=================================================================================
573 bool RepairGUI_ShapeProcessDlg::isValid( QString& msg )
574 {
575   bool ok = true;
576   QMapIterator<QString,QStringList> aMapIter( myValMap );
577   while( aMapIter.hasNext() ) {
578     aMapIter.next();
579     const QStringList& aList = aMapIter.value();
580     QListIterator<QString> aListIter( aList );
581     while( aListIter.hasNext() ) {
582       const QString& aParam = aListIter.next();
583       QWidget* aControl = getControl( aParam );
584       if ( qobject_cast<SalomeApp_DoubleSpinBox*>( aControl ) )
585         ok = qobject_cast<SalomeApp_DoubleSpinBox*>( aControl )->isValid( msg, !IsPreview() ) && ok;
586       else if ( qobject_cast<SalomeApp_IntSpinBox*>( aControl ) )
587         ok = qobject_cast<SalomeApp_IntSpinBox*>( aControl )->isValid( msg, !IsPreview() ) && ok;
588     }
589   }
590
591   bool error = false;
592   GEOM::string_array_var anOperators = getActiveOperators();
593   if ( !myObjects->length() ) {
594     msg += tr( "ERROR_NO_OBJECTS" );
595     error = true;
596   }
597   if ( !anOperators->length() ) {
598     if ( error ) 
599       msg += "\n";
600     msg += tr( "ERROR_NO_OPERATORS" );
601     error = true;
602   }
603   return !error && ok;
604 }
605
606 //=================================================================================
607 // function : execute
608 // purpose  :
609 //=================================================================================
610 bool RepairGUI_ShapeProcessDlg::execute( ObjectList& objects )
611 {
612   GEOM::string_array_var anOperators = getActiveOperators();
613   GEOM::string_array_var aParams = getParameters( anOperators );
614   GEOM::string_array_var aValues = getValues( aParams );
615
616   /*//-- check --
617   int z;
618         MESSAGE("Objects : ");
619         for ( z = 0; z < myObjects->length(); z++ )
620                 MESSAGE(myObjects[z]->GetName() << " ");
621         MESSAGE("\nOperators : ");
622         for ( z = 0; z < anOperators->length(); z++ )
623                 MESSAGE(anOperators[z] << " ");
624         MESSAGE("\nParameters : ");
625         for ( z = 0; z < aParams->length(); z++ )
626                 MESSAGE(aParams[z] << " ");
627         MESSAGE("\nValues : ");
628         for ( z = 0; z < aValues->length(); z ++ )
629                 MESSAGE(aValues[z] << " ");
630         MESSAGE("\n");
631   */// -----------
632
633   QStringList anErrorObjNames;
634   for ( int i = 0; i < myObjects->length(); i++ ) {
635     GEOM::GEOM_Object_var obj = myObjects[i];
636     GEOM::GEOM_IHealingOperations_var anOper = GEOM::GEOM_IHealingOperations::_narrow( getOperation() );
637     GEOM::GEOM_Object_var anObj = anOper->ProcessShape( obj, anOperators, aParams, aValues );
638     if ( anObj->_is_nil() )
639       anErrorObjNames << GEOMBase::GetName( obj );
640     else
641     {
642       if ( !IsPreview() )
643       {
644         QStringList aParameters;
645
646         for ( int i = 0; i < anOperators->length(); i++ )
647           aParameters << QString( anOperators[i] );
648
649         for ( int i = 0; i < aParams->length(); i++ )
650           aParameters << QString( aParams[i] );
651
652         aParameters << getTexts( aParams );
653         anObj->SetParameters(aParameters.join(":").toLatin1().constData());
654       }
655       objects.push_back( anObj._retn() );
656     }
657   }
658
659   if ( !anErrorObjNames.empty() )
660     MESSAGE( "ERRORS occured while processing the following objects: " << anErrorObjNames.join( " " ).toLatin1().data() );
661     
662   return anErrorObjNames.size() < myObjects->length(); // true if at least one object was OK, false if ALL objects were nil after Healing.
663 }
664
665 //=================================================================================
666 // function : getActiveOperators
667 // purpose  :
668 //=================================================================================
669 GEOM::string_array* RepairGUI_ShapeProcessDlg::getActiveOperators()
670 {
671   GEOM::string_array_var anOperators = new GEOM::string_array();
672   QStringList aCheckedList;
673
674   for ( int i = 0; i < myOpList->count(); i++ ) {
675     if ( myOpList->item( i )->checkState() == Qt::Checked )
676       aCheckedList << myOpList->item( i )->text();
677   }
678
679   anOperators->length( aCheckedList.count() );
680
681   for ( int i = 0; i < aCheckedList.count(); i++ )
682     anOperators[i] = CORBA::string_dup( aCheckedList[i].toLatin1().constData() );
683                  
684   return anOperators._retn();
685 }
686
687 //=================================================================================
688 // function : getcontrol
689 // purpose  :
690 //=================================================================================
691 QWidget* RepairGUI_ShapeProcessDlg::getControl( const QString& theParam )
692 {
693   if ( theParam == "SplitAngle.Angle" )                           return mySplitAngleAngle;
694   else if ( theParam == "SplitAngle.MaxTolerance" )               return mySplitAngleMaxTol;
695   else if ( theParam == "SplitClosedFaces.NbSplitPoints" )        return mySplitClosedFacesNum;
696   else if ( theParam == "FixFaceSize.Tolerance" )                 return myFixFaceSizeTol;
697   else if ( theParam == "DropSmallEdges.Tolerance3d" )            return myDropSmallEdgesTol3D;
698   else if ( theParam == "BSplineRestriction.SurfaceMode" )        return myBSplineSurfModeChk;
699   else if ( theParam == "BSplineRestriction.Curve3dMode" )        return myBSpline3DCurveChk;
700   else if ( theParam == "BSplineRestriction.Curve2dMode" )        return myBSpline2DCurveChk;
701   else if ( theParam == "BSplineRestriction.Tolerance3d" )        return myBSplineTol3D;
702   else if ( theParam == "BSplineRestriction.Tolerance2d" )        return myBSplineTol2D;
703   else if ( theParam == "BSplineRestriction.RequiredDegree" )     return myBSplineDegree;
704   else if ( theParam == "BSplineRestriction.RequiredNbSegments" ) return myBSplineSegments;
705   else if ( theParam == "BSplineRestriction.Continuity3d" )       return myBSpline3DCont;
706   else if ( theParam == "BSplineRestriction.Continuity2d" )       return myBSpline2DCont;
707   else if ( theParam == "SplitContinuity.Tolerance3d" )           return mySplitContTol3D;
708   else if ( theParam == "SplitContinuity.SurfaceContinuity" )     return mySplitContSurfCont;
709   else if ( theParam == "SplitContinuity.CurveContinuity" )       return mySplitContCurvCont;
710   else if ( theParam == "ToBezier.SurfaceMode" )                  return myToBezierSurfModeChk;
711   else if ( theParam == "ToBezier.Curve3dMode" )                  return myToBezier3DCurveChk;
712   else if ( theParam == "ToBezier.Curve2dMode" )                  return myToBezier2DCurveChk;
713   else if ( theParam == "ToBezier.MaxTolerance" )                 return myToBezierMaxTol;
714   else if ( theParam == "SameParameter.Tolerance3d" )             return mySameParameterTol3D;
715   else if ( theParam == "FixShape.Tolerance3d" )                  return myFixShapeTol3D;
716   else if ( theParam == "FixShape.MaxTolerance3d" )               return myFixShapeMaxTol3D;
717   return 0;
718 }
719
720 //=================================================================================
721 // function : getParameters
722 // purpose  :
723 //=================================================================================
724 void RepairGUI_ShapeProcessDlg::initParamsValues()
725 {
726   if ( myOpLst.count() )
727     return;  // already filled
728
729   myOpLst << "FixShape";
730   myValMap["FixShape"] << "FixShape.Tolerance3d";
731   myValMap["FixShape"] << "FixShape.MaxTolerance3d";
732
733   myOpLst << "FixFaceSize";
734   myValMap["FixFaceSize"] << "FixFaceSize.Tolerance";
735
736   myOpLst << "DropSmallEdges";
737   myValMap["DropSmallEdges"] << "DropSmallEdges.Tolerance3d";
738
739   myOpLst << "SplitAngle";
740   myValMap["SplitAngle"] << "SplitAngle.Angle";
741   myValMap["SplitAngle"] << "SplitAngle.MaxTolerance";
742
743   myOpLst << "SplitClosedFaces";
744   myValMap["SplitClosedFaces"] << "SplitClosedFaces.NbSplitPoints";
745
746   myOpLst << "SplitContinuity";
747   myValMap["SplitContinuity"] << "SplitContinuity.Tolerance3d";
748   myValMap["SplitContinuity"] << "SplitContinuity.SurfaceContinuity";
749   myValMap["SplitContinuity"] << "SplitContinuity.CurveContinuity";
750
751   myOpLst << "BSplineRestriction";
752   myValMap["BSplineRestriction"] << "BSplineRestriction.SurfaceMode";
753   myValMap["BSplineRestriction"] << "BSplineRestriction.Curve3dMode";
754   myValMap["BSplineRestriction"] << "BSplineRestriction.Curve2dMode";
755   myValMap["BSplineRestriction"] << "BSplineRestriction.Tolerance3d";
756   myValMap["BSplineRestriction"] << "BSplineRestriction.Tolerance2d";
757   myValMap["BSplineRestriction"] << "BSplineRestriction.RequiredDegree";
758   myValMap["BSplineRestriction"] << "BSplineRestriction.RequiredNbSegments";
759   myValMap["BSplineRestriction"] << "BSplineRestriction.Continuity3d";
760   myValMap["BSplineRestriction"] << "BSplineRestriction.Continuity2d";
761
762   myOpLst << "ToBezier";
763   myValMap["ToBezier"] << "ToBezier.SurfaceMode";
764   myValMap["ToBezier"] << "ToBezier.Curve3dMode";
765   myValMap["ToBezier"] << "ToBezier.Curve2dMode";
766   myValMap["ToBezier"] << "ToBezier.MaxTolerance";
767
768   myOpLst << "SameParameter";
769   myValMap["SameParameter"] << "SameParameter.Tolerance3d";
770 }
771
772 //=================================================================================
773 // function : getParameters
774 // purpose  :
775 //=================================================================================
776 GEOM::string_array* RepairGUI_ShapeProcessDlg::getParameters( const GEOM::string_array& theOperators )
777 {
778   GEOM::string_array_var aParams = new GEOM::string_array();
779   int i = 0, j = 0;
780
781   // calculate the length of parameters
782   for ( i = 0, j = 0; i < theOperators.length(); i++ )
783     j += myValMap[ QString( theOperators[i] ) ].size();
784   
785   // set the new length of paremeters
786   aParams->length( j );
787
788   // fill the parameters
789   for ( i = 0, j = 0; i < theOperators.length(); i++ ) {
790     QStringList aValLst = myValMap[ QString( theOperators[i] ) ];
791     for ( QStringList::Iterator it = aValLst.begin(); it != aValLst.end(); ++it )
792       aParams[j++] = CORBA::string_dup( (*it).toLatin1().constData() );
793   }
794
795   return aParams._retn();
796 }
797
798
799 //=================================================================================
800 // function : getValues
801 // purpose  :
802 //=================================================================================
803 GEOM::string_array* RepairGUI_ShapeProcessDlg::getValues( const GEOM::string_array& theParams )
804 {
805   GEOM::string_array_var aValues = new GEOM::string_array();
806   aValues->length( theParams.length() );
807     
808   for ( int i = 0; i < theParams.length(); i++ ) {
809     QWidget* aCtrl = getControl( (const char*)theParams[i] );
810     if ( aCtrl )
811       aValues[i] = get_convert( (const char*)theParams[i], getValue( aCtrl ) );
812   }
813     
814   return aValues._retn();
815 }
816
817 //=================================================================================
818 // function : getTexts
819 // purpose  :
820 //=================================================================================
821 QStringList RepairGUI_ShapeProcessDlg::getTexts( const GEOM::string_array& theParams )
822 {
823   QStringList aTexts;
824     
825   for ( int i = 0; i < theParams.length(); i++ ) {
826     QWidget* aCtrl = getControl( (const char*)theParams[i] );
827     if ( aCtrl )
828     {
829       QString aText = getText( aCtrl );
830       if( !aText.isNull() )
831         aTexts.append( aText );
832     }
833   }
834     
835   return aTexts;
836 }
837
838 //=================================================================================
839 // function : initSelection
840 // purpose  : set selection of ALL shape types except vertexes
841 //=================================================================================
842 void RepairGUI_ShapeProcessDlg::initSelection()
843 {
844   TColStd_MapOfInteger aTypes;
845   aTypes.Add( GEOM_COMPOUND );
846   aTypes.Add( GEOM_SOLID );
847   aTypes.Add( GEOM_SHELL );
848   aTypes.Add( GEOM_FACE );
849   aTypes.Add( GEOM_WIRE );
850   aTypes.Add( GEOM_EDGE );
851   globalSelection( aTypes );
852 }
853
854 //=================================================================================
855 // function : advOptionToggled
856 // purpose  : this slot is used to warn the user about possible consequences
857 //            of enabling some advanced options
858 //=================================================================================
859 void RepairGUI_ShapeProcessDlg::advOptionToggled( bool on )
860 {
861   QAbstractButton* btn = (QAbstractButton*)sender();
862   if ( on && btn->isCheckable() &&
863        SUIT_MessageBox::warning( this,
864                                  tr( "GEOM_WRN_WARNING" ), tr( "TIME_CONSUMING" ),
865                                  SUIT_MessageBox::Yes | SUIT_MessageBox::No ) == SUIT_MessageBox::No )
866     btn->toggle();
867 }