Salome HOME
aeb5f0b3ae7c9958c3e6f9d9346895aa865f0d62
[modules/geom.git] / src / OperationGUI / OperationGUI_FilletDlg.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 // File   : OperationGUI_FilletDlg.cxx
23 // Author : Damien COQUERET, Open CASCADE S.A.S.
24 //
25
26 #include "OperationGUI_FilletDlg.h"
27
28 #include <GEOM_DlgRef.h>
29 #include <GeometryGUI.h>
30 #include <GEOMBase.h>
31
32 #include <SUIT_Desktop.h>
33 #include <SUIT_Session.h>
34 #include <SUIT_ResourceMgr.h>
35 #include <SUIT_ViewWindow.h>
36 #include <SUIT_ViewManager.h>
37 #include <SalomeApp_Application.h>
38 #include <LightApp_SelectionMgr.h>
39 #include <OCCViewer_ViewModel.h>
40
41 #include <TColStd_MapOfInteger.hxx>
42 #include <TColStd_IndexedMapOfInteger.hxx>
43
44 #include <GEOMImpl_Types.hxx>
45
46 //=================================================================================
47 // class    : OperationGUI_FilletDlg()
48 // purpose  : Constructs a OperationGUI_FilletDlg which is a child of 'parent', with the 
49 //            name 'name' and widget flags set to 'f'.
50 //            The dialog will by default be modeless, unless you set 'modal' to
51 //            TRUE to construct a modal dialog.
52 //=================================================================================
53 OperationGUI_FilletDlg::OperationGUI_FilletDlg( GeometryGUI* theGeometryGUI, QWidget* parent )
54   : GEOMBase_Skeleton( theGeometryGUI, parent, false )
55 {
56   SUIT_ResourceMgr* aResMgr = myGeomGUI->getApp()->resourceMgr();
57   QPixmap image0( aResMgr->loadPixmap( "GEOM", tr( "ICON_DLG_FILLET_ALL" ) ) );
58   QPixmap image1( aResMgr->loadPixmap( "GEOM", tr( "ICON_DLG_FILLET_EDGE" ) ) );
59   QPixmap image2( aResMgr->loadPixmap( "GEOM", tr( "ICON_DLG_FILLET_FACE" ) ) );
60
61   QPixmap iconSelect( aResMgr->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) );
62
63   setWindowTitle( tr( "GEOM_FILLET_TITLE" ) );
64
65   /***************************************************************/
66   mainFrame()->GroupConstructors->setTitle( tr( "GEOM_FILLET" ) );
67   mainFrame()->RadioButton1->setIcon( image0 );
68   mainFrame()->RadioButton2->setIcon( image1 );
69   mainFrame()->RadioButton3->setIcon( image2 );
70
71   Group1 = new DlgRef_1Sel1Spin( centralWidget() );
72   Group1->GroupBox1->setTitle( tr( "GEOM_FILLET_ALL" ) );
73   Group1->TextLabel1->setText( tr( "GEOM_MAIN_OBJECT" ) );
74   Group1->TextLabel2->setText( tr( "GEOM_RADIUS" ) );
75   Group1->PushButton1->setIcon( iconSelect );
76   Group1->LineEdit1->setReadOnly( true );
77
78   Group2 = new DlgRef_2Sel1Spin( centralWidget() );
79   Group2->GroupBox1->setTitle( tr( "GEOM_FILLET_EDGES" ) );
80   Group2->TextLabel1->setText( tr( "GEOM_MAIN_OBJECT" ) );
81   Group2->TextLabel2->setText( tr( "SELECTED_EDGES" ) );
82   Group2->TextLabel3->setText( tr( "GEOM_RADIUS" ) );
83   Group2->PushButton1->setIcon( iconSelect );
84   Group2->PushButton2->setIcon( iconSelect );
85   Group2->LineEdit1->setReadOnly( true );
86   Group2->LineEdit2->setReadOnly( true );
87
88   Group3 = new DlgRef_2Sel1Spin( centralWidget() );
89   Group3->GroupBox1->setTitle( tr( "GEOM_FILLET_FACES" ) );
90   Group3->TextLabel1->setText( tr( "GEOM_MAIN_OBJECT" ) );
91   Group3->TextLabel2->setText( tr( "SELECTED_FACES" ) );
92   Group3->TextLabel3->setText( tr( "GEOM_RADIUS" ) );
93   Group3->PushButton1->setIcon( iconSelect );
94   Group3->PushButton2->setIcon( iconSelect );
95   Group3->LineEdit1->setReadOnly( true );
96   Group3->LineEdit2->setReadOnly( true );
97
98   QVBoxLayout* layout = new QVBoxLayout( centralWidget() );
99   layout->setMargin( 0 ); layout->setSpacing( 6 );
100   layout->addWidget( Group1 );
101   layout->addWidget( Group2 );
102   layout->addWidget( Group3 );
103   /***************************************************************/
104
105   double SpecificStep = 10.0;
106   initSpinBox( Group1->SpinBox_DX, 0.001, COORD_MAX, SpecificStep, 3 );
107   initSpinBox( Group2->SpinBox_DX, 0.001, COORD_MAX, SpecificStep, 3 );
108   initSpinBox( Group3->SpinBox_DX, 0.001, COORD_MAX, SpecificStep, 3 );
109
110   setHelpFileName( "fillet.htm" );
111
112   /* Initialisations */
113   Init();
114 }
115
116
117 //=================================================================================
118 // function : ~OperationGUI_FilletDlg()
119 // purpose  : Destroys the object and frees any allocated resources
120 //=================================================================================
121 OperationGUI_FilletDlg::~OperationGUI_FilletDlg()
122 {  
123 }
124
125
126 //=================================================================================
127 // function : Init()
128 // purpose  :
129 //=================================================================================
130 void OperationGUI_FilletDlg::Init()
131 {
132   myConstructorId = -1;
133   reset();
134
135   // main buttons
136   connect( buttonOk(),    SIGNAL( clicked() ), this, SLOT( ClickOnOk()    ) );
137   connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
138
139   // group box
140   connect( this,          SIGNAL( constructorsClicked( int ) ), this, SLOT( ConstructorsClicked( int ) ) );
141
142   // push buttons
143   connect( Group1->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
144   connect( Group2->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
145   connect( Group3->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
146   connect( Group2->PushButton2, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
147   connect( Group3->PushButton2, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
148
149   // line edits
150   connect( Group1->LineEdit1, SIGNAL( returnPressed() ), this, SLOT( LineEditReturnPressed() ) );
151   connect( Group2->LineEdit1, SIGNAL( returnPressed() ), this, SLOT( LineEditReturnPressed() ) );
152   connect( Group3->LineEdit1, SIGNAL( returnPressed() ), this, SLOT( LineEditReturnPressed() ) );
153
154   // spin boxes  
155   connect( Group1->SpinBox_DX, SIGNAL( valueChanged( double ) ), this, SLOT( ValueChangedInSpinBox( double ) ) );
156   connect( Group2->SpinBox_DX, SIGNAL( valueChanged( double ) ), this, SLOT( ValueChangedInSpinBox( double ) ) );
157   connect( Group3->SpinBox_DX, SIGNAL( valueChanged( double ) ), this, SLOT( ValueChangedInSpinBox( double ) ) );
158
159     // selection
160   connect( myGeomGUI->getApp()->selectionMgr(), 
161            SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
162
163   initName( tr( "GEOM_FILLET" ) );
164
165   ConstructorsClicked( 0 );
166 }
167
168
169 //=================================================================================
170 // function : ConstructorsClicked()
171 // purpose  : Radio button management
172 //=================================================================================
173 void OperationGUI_FilletDlg::ConstructorsClicked( int constructorId )
174 {
175   if ( SUIT_Session::session()->activeApplication()->desktop()->activeWindow()->getViewManager()->getType() 
176        != OCCViewer_Viewer::Type() ) {
177     mainFrame()->RadioButton1->setChecked( true );
178     return;
179   }
180
181   if ( myConstructorId == constructorId )
182     return;
183
184   // Get radius from previous widget
185   double R = 5;
186   if      ( myConstructorId == 0 ) R = Group1->SpinBox_DX->value();
187   else if ( myConstructorId == 1 ) R = Group2->SpinBox_DX->value();
188   else                             R = Group3->SpinBox_DX->value();
189
190   myConstructorId = constructorId;
191
192   switch ( constructorId ) {
193   case 0:
194     Group2->hide();
195     Group3->hide();
196     Group1->show();
197     Group1->SpinBox_DX->setValue( R );
198     break;
199   case 1:
200     Group1->hide();
201     Group3->hide();
202     Group2->show();
203     Group2->SpinBox_DX->setValue( R );
204     break;
205   case 2:
206     Group1->hide();
207     Group2->hide();
208     Group3->show();
209     Group3->SpinBox_DX->setValue( R );
210     break;
211   default:
212     break;
213   }
214
215   if      ( constructorId == 0 ) myEditCurrentArgument = Group1->LineEdit1;
216   else if ( constructorId == 1 ) myEditCurrentArgument = Group2->LineEdit1;
217   else                           myEditCurrentArgument = Group3->LineEdit1;
218
219   activateSelection();
220   enableWidgets();
221
222   if ( !myShape->_is_nil() ) {
223     myEditCurrentArgument->setText( GEOMBase::GetName( myShape ) );
224     GEOMBase_Skeleton::LineEditReturnPressed();
225   }
226   else
227     myEditCurrentArgument->setText( "" );
228
229   qApp->processEvents();
230   updateGeometry();
231   resize( minimumSize() );
232
233   displayPreview();  
234 }
235
236
237 //=================================================================================
238 // function : ClickOnOk()
239 // purpose  :
240 //=================================================================================
241 void OperationGUI_FilletDlg::ClickOnOk()
242 {
243   if ( ClickOnApply() )
244     ClickOnCancel();
245 }
246
247
248 //=================================================================================
249 // function : ClickOnApply()
250 // purpose  :
251 //=================================================================================
252 bool OperationGUI_FilletDlg::ClickOnApply()
253 {
254   if ( !onAccept() )
255     return false;
256
257   initName();
258   return true;
259 }
260
261 //=================================================================================
262 // function : SelectionIntoArgument()
263 // purpose  : Called when selection has changed
264 //=================================================================================
265 void OperationGUI_FilletDlg::SelectionIntoArgument()
266 {
267   erasePreview();
268   myEditCurrentArgument->setText( "" );
269
270   // If selection of main object is activated
271   if ( myEditCurrentArgument == Group1->LineEdit1 ||
272        myEditCurrentArgument == Group2->LineEdit1 ||
273        myEditCurrentArgument == Group3->LineEdit1 ) {
274     if ( IObjectCount() == 1 ) {
275       Standard_Boolean aResult = Standard_False;
276       GEOM::GEOM_Object_var anObj =
277         GEOMBase::ConvertIOinGEOMObject( firstIObject(), aResult );
278       
279       if ( aResult && !anObj->_is_nil() ) {
280         myShape = anObj;
281         myEditCurrentArgument->setText( GEOMBase::GetName( anObj ) );
282         displayPreview();
283         enableWidgets();
284         return;
285       }
286     }
287
288     myShape = GEOM::GEOM_Object::_nil();
289     enableWidgets();
290   }
291   // If face or edge selection is activated
292   else if ( myEditCurrentArgument == Group2->LineEdit2 ||
293             myEditCurrentArgument == Group3->LineEdit2 ) {
294     if ( IObjectCount() == 1 ) {
295       Standard_Boolean aResult = Standard_False;
296       GEOM::GEOM_Object_var anObj =
297         GEOMBase::ConvertIOinGEOMObject( firstIObject(), aResult );
298
299       if ( aResult && !anObj->_is_nil() ) {
300         TColStd_IndexedMapOfInteger anIndexes;
301         myGeomGUI->getApp()->selectionMgr()->GetIndexes( firstIObject(), anIndexes );
302
303         if ( anIndexes.Extent() > 0 ) {
304           QString aName;
305           if ( anIndexes.Extent() == 1 ) {
306             int anIndex = anIndexes( 1 );
307
308             aName = QString( GEOMBase::GetName( anObj ) ) + QString( ":%1" ).arg( anIndex );
309           }
310           else
311             aName = tr( "GEOM_MEN_POPUP_NAME" ).arg( anIndexes.Extent() );
312
313           myEditCurrentArgument->setText( aName );
314
315           if ( myConstructorId == 1 )
316             myEdges = anIndexes;
317           else
318             myFaces = anIndexes;
319
320           displayPreview();
321           return;
322         }
323       }
324     }
325     myFaces.Clear();
326   }
327 }
328
329
330 //=================================================================================
331 // function : LineEditReturnPressed()
332 // purpose  :
333 //=================================================================================
334 void OperationGUI_FilletDlg::LineEditReturnPressed()
335 {
336   QLineEdit* send = ( QLineEdit* )sender();
337   
338   if ( send == Group1->LineEdit1 )
339     myEditCurrentArgument = Group1->LineEdit1;
340   else if ( send == Group2->LineEdit1 )
341     myEditCurrentArgument = Group2->LineEdit1;
342   else if ( send == Group3->LineEdit1 )
343     myEditCurrentArgument = Group3->LineEdit1;
344   else
345     return;
346
347   GEOMBase_Skeleton::LineEditReturnPressed();
348 }
349
350
351 //=================================================================================
352 // function : SetEditCurrentArgument()
353 // purpose  :
354 //=================================================================================
355 void OperationGUI_FilletDlg::SetEditCurrentArgument()
356 {
357   QPushButton* send = (QPushButton*)sender();
358
359   if ( send == Group1->PushButton1 ) {
360     Group1->LineEdit1->setFocus();
361     myEditCurrentArgument = Group1->LineEdit1;
362   }
363   else if ( send == Group2->PushButton1 ) {
364     Group2->LineEdit1->setFocus();
365     myEditCurrentArgument = Group2->LineEdit1;
366   }
367   else if ( send == Group2->PushButton2 ) {
368     Group2->LineEdit2->setFocus();
369     myEditCurrentArgument = Group2->LineEdit2;
370   }
371   else if ( send == Group3->PushButton1 ) {
372     Group3->LineEdit1->setFocus();
373     myEditCurrentArgument = Group3->LineEdit1;
374   }
375   else if ( send == Group3->PushButton2 ) {
376     Group3->LineEdit1->setFocus();
377     myEditCurrentArgument = Group3->LineEdit2;
378   }
379
380   activateSelection();
381 }
382
383
384 //=================================================================================
385 // function : ActivateThisDialog()
386 // purpose  :
387 //=================================================================================
388 void OperationGUI_FilletDlg::ActivateThisDialog()
389 {
390   GEOMBase_Skeleton::ActivateThisDialog();
391
392   connect( myGeomGUI->getApp()->selectionMgr(), 
393            SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
394
395   activateSelection();
396   displayPreview();
397 }
398
399
400 //=================================================================================
401 // function : enterEvent()
402 // purpose  :
403 //=================================================================================
404 void OperationGUI_FilletDlg::enterEvent( QEvent* )
405 {
406   if ( !mainFrame()->GroupConstructors->isEnabled() )
407     this->ActivateThisDialog();
408 }
409
410 //=================================================================================
411 // function : ValueChangedInSpinBox()
412 // purpose  :
413 //=================================================================================
414 void OperationGUI_FilletDlg::ValueChangedInSpinBox( double )
415 {
416   displayPreview();
417 }
418
419 //=================================================================================
420 // function : reset()
421 // purpose  :
422 //=================================================================================
423 void OperationGUI_FilletDlg::reset()
424 {
425   // Set Initial values of spinboxes
426   Group1->SpinBox_DX->setValue( 5 );
427   Group2->SpinBox_DX->setValue( 5 );
428   Group3->SpinBox_DX->setValue( 5 );
429
430   Group1->LineEdit1->setText( "" );
431   Group2->LineEdit1->setText( "" );
432   Group2->LineEdit2->setText( "" );
433   Group3->LineEdit1->setText( "" );
434   Group3->LineEdit2->setText( "" );
435
436   // constructor id
437   int aConstructorId = getConstructorId();
438
439   if      ( aConstructorId == 0 ) myEditCurrentArgument = Group1->LineEdit1;
440   else if ( aConstructorId == 1 ) myEditCurrentArgument = Group2->LineEdit1;
441   else                            myEditCurrentArgument = Group3->LineEdit1;
442
443   myShape = GEOM::GEOM_Object::_nil();
444
445   myFaces.Clear();
446   myEdges.Clear();
447
448   erasePreview( true );
449
450   activateSelection();
451
452   enableWidgets();
453 }
454
455 //=================================================================================
456 // function : activateSelection
457 // purpose  : Activate selection in accordance with myEditCurrentArgument
458 //=================================================================================
459 void OperationGUI_FilletDlg::activateSelection()
460 {
461
462   if ( !myShape->_is_nil() && myEditCurrentArgument == Group2->LineEdit2 )
463     localSelection( myShape, TopAbs_EDGE );
464   else if ( !myShape->_is_nil() && myEditCurrentArgument == Group3->LineEdit2 )
465     localSelection( myShape, TopAbs_FACE );
466   else {
467     TColStd_MapOfInteger aMap;
468     aMap.Add( GEOM_SHELL );
469     aMap.Add( GEOM_SOLID );
470     aMap.Add( GEOM_COMPOUND );
471     globalSelection( aMap );
472   }
473
474   SelectionIntoArgument();
475 }
476
477 //=================================================================================
478 // function : enableWidgets
479 // purpose  : Enable widgets of faces in accordance with value of main object
480 //=================================================================================
481 void OperationGUI_FilletDlg::enableWidgets()
482 {
483   int anId = getConstructorId();
484
485   bool toEnable = !myShape->_is_nil();
486
487   if ( anId == 1 ) {
488     Group2->LineEdit2->setEnabled( toEnable );
489     Group2->PushButton2->setEnabled( toEnable );
490     
491     if ( !toEnable ) {
492       Group2->LineEdit2->setText( "" );
493       myEdges.Clear();
494     }
495   }
496   else if ( anId == 2 ) {
497     Group3->LineEdit2->setEnabled( toEnable );
498     Group3->PushButton2->setEnabled( toEnable );
499
500     if ( !toEnable ) {
501       Group3->LineEdit2->setText( "" );
502       myFaces.Clear();
503     }
504   }
505 }
506
507 //=================================================================================
508 // function : createOperation
509 // purpose  :
510 //=================================================================================
511 GEOM::GEOM_IOperations_ptr OperationGUI_FilletDlg::createOperation()
512 {
513   return getGeomEngine()->GetILocalOperations( getStudyId() );
514 }
515
516 //=================================================================================
517 // function : ClickOnApply()
518 // purpose  : Verify validity of input data
519 //=================================================================================
520 bool OperationGUI_FilletDlg::isValid( QString& )
521 {
522   switch ( getConstructorId() )
523   {
524     case 0: return !myShape->_is_nil();
525     case 1: return !myShape->_is_nil() && myEdges.Extent() > 0;
526     case 2: return !myShape->_is_nil() && myFaces.Extent() > 0;
527     default: return false;
528   }
529 }
530
531 //=================================================================================
532 // function : execute
533 // purpose  :
534 //=================================================================================
535 bool OperationGUI_FilletDlg::execute( ObjectList& objects )
536 {
537   GEOM::GEOM_Object_var anObj;
538
539   int anId = getConstructorId();
540   if ( anId == 0 )
541     anObj = GEOM::GEOM_ILocalOperations::_narrow(
542       getOperation() )->MakeFilletAll( myShape,
543                                        getRadius() );
544   else if ( anId == 1 ) {
545     GEOM::ListOfLong_var aList = new GEOM::ListOfLong;
546     aList->length( myEdges.Extent() );
547
548     for ( int i = 1, n = myEdges.Extent(); i <= n; i++ )
549       aList[ i - 1 ] = myEdges( i );
550
551     anObj = GEOM::GEOM_ILocalOperations::_narrow(
552       getOperation() )->MakeFilletEdges( myShape, getRadius(), aList );
553   }
554   else if ( anId == 2 ) {
555     GEOM::ListOfLong_var aList = new GEOM::ListOfLong;
556     aList->length( myFaces.Extent() );
557
558     for ( int i = 1, n = myFaces.Extent(); i <= n; i++ )
559       aList[ i - 1 ] = myFaces( i );
560
561     anObj = GEOM::GEOM_ILocalOperations::_narrow(
562       getOperation() )->MakeFilletFaces( myShape, getRadius(), aList );
563   }
564
565   if ( !anObj->_is_nil() )
566     objects.push_back( anObj._retn() );
567
568   return true;
569 }
570
571 //=================================================================================
572 // function : getRadius
573 // purpose  : Get radius     
574 //=================================================================================
575 double OperationGUI_FilletDlg::getRadius() const
576 {
577   int anId = getConstructorId();
578   if      ( anId == 0 ) return Group1->SpinBox_DX->value();
579   else if ( anId == 1 ) return Group2->SpinBox_DX->value();
580   else                  return Group3->SpinBox_DX->value();
581 }