Salome HOME
Dump Python Extension
[modules/smesh.git] / src / StdMeshersGUI / StdMeshersGUI_NbSegmentsCreator.cxx
1 // Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
3 //
4 // This library is free software; you can redistribute it and/or 
5 // modify it under the terms of the GNU Lesser General Public 
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License. 
8 //
9 // This library is distributed in the hope that it will be useful, 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details. 
13 //
14 // You should have received a copy of the GNU Lesser General Public 
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 // File   : StdMeshersGUI_NbSegmentsCreator.cxx
21 // Author : Open CASCADE S.A.S.
22 //
23
24 // SMESH includes
25 #include "StdMeshersGUI_NbSegmentsCreator.h"
26 #include "StdMeshersGUI_DistrTable.h"
27 #include "StdMeshersGUI_DistrPreview.h"
28
29 #include <SMESHGUI_Utils.h>
30 #include <SMESHGUI_HypothesesUtils.h>
31 #include <SMESHGUI_SpinBox.h>
32
33 // IDL includes
34 #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
35
36 // SALOME GUI includes
37 #include <SalomeApp_Tools.h>
38 #include <QtxIntSpinBox.h>
39 #include <QtxComboBox.h>
40
41 // Qt includes
42 #include <QLabel>
43 #include <QGroupBox>
44 #include <QFrame>
45 #include <QLineEdit>
46 #include <QButtonGroup>
47 #include <QRadioButton>
48 #include <QGridLayout>
49 #include <QVBoxLayout>
50 #include <QHBoxLayout>
51 #include <QApplication>
52
53 #define SPACING 6
54 #define MARGIN  11
55
56 StdMeshersGUI_NbSegmentsCreator::StdMeshersGUI_NbSegmentsCreator()
57 : StdMeshersGUI_StdHypothesisCreator( "NumberOfSegments" ),
58   myNbSeg( 0 ),
59   myDistr( 0 ),
60   myScale( 0 ),
61   myTable( 0 ),
62   myPreview( 0 ),
63   myExpr( 0 ),
64   myConvBox( 0 ),
65   myConv( 0 ),
66   myLScale( 0 ),
67   myLTable( 0 ),
68   myLExpr( 0 ),
69   myInfo( 0 ),
70   myGroupLayout( 0 ),
71   myTableRow( 0 ),
72   myPreviewRow( 0 )
73 {
74 }
75
76 StdMeshersGUI_NbSegmentsCreator::~StdMeshersGUI_NbSegmentsCreator()
77 {
78 }
79
80 bool StdMeshersGUI_NbSegmentsCreator::checkParams() const
81 {
82   if( !SMESHGUI_GenericHypothesisCreator::checkParams() )
83     return false;
84
85   NbSegmentsHypothesisData data_old, data_new;
86   readParamsFromHypo( data_old );
87   readParamsFromWidgets( data_new );
88   bool res = storeParamsToHypo( data_new );
89   storeParamsToHypo( data_old );
90   return res;
91 }
92
93 QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame()
94 {
95   QFrame* fr = new QFrame();
96
97   QVBoxLayout* lay = new QVBoxLayout( fr );
98   lay->setMargin( 0 );
99   lay->setSpacing( 0 );
100
101   QGroupBox* GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), fr );
102   lay->addWidget( GroupC1 );
103
104   StdMeshers::StdMeshers_NumberOfSegments_var h =
105     StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() );
106   myPreview = new StdMeshersGUI_DistrPreview( GroupC1, h.in() );
107
108   myGroupLayout = new QGridLayout( GroupC1 );
109   myGroupLayout->setSpacing( SPACING );
110   myGroupLayout->setMargin( MARGIN );
111   myGroupLayout->setColumnStretch( 0, 0 );
112   myGroupLayout->setColumnStretch( 1, 1 );
113
114   int row = 0;
115   // 0)  name
116   myName = 0;
117   if( isCreation() )
118   {
119     myName = new QLineEdit( GroupC1 );
120     myGroupLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), GroupC1 ), row, 0 );
121     myGroupLayout->addWidget( myName, row, 1 );
122     row++;
123   }
124
125   // 1)  number of segments
126   myGroupLayout->addWidget( new QLabel( tr( "SMESH_NB_SEGMENTS_PARAM" ), GroupC1 ), row, 0 );
127   myNbSeg = new QtxIntSpinBox( GroupC1 );
128   myNbSeg->setMinimum( 1 );
129   myNbSeg->setMaximum( 9999 );
130   myGroupLayout->addWidget( myNbSeg, row, 1 );
131   row++;
132
133   // 2)  type of distribution
134   myGroupLayout->addWidget( new QLabel( tr( "SMESH_DISTR_TYPE" ), GroupC1 ), row, 0 );
135   myDistr = new QtxComboBox( GroupC1 );
136   QStringList types;
137   types.append( tr( "SMESH_DISTR_REGULAR" ) );
138   types.append( tr( "SMESH_DISTR_SCALE"   ) );
139   types.append( tr( "SMESH_DISTR_TAB"     ) );
140   types.append( tr( "SMESH_DISTR_EXPR"    ) );
141   myDistr->addItems( types );
142   myGroupLayout->addWidget( myDistr, row, 1 );
143   row++;
144
145   // 3)  scale
146   myGroupLayout->addWidget( myLScale = new QLabel( tr( "SMESH_NB_SEGMENTS_SCALE_PARAM" ), GroupC1 ), row, 0 );
147   myScale = new SMESHGUI_SpinBox( GroupC1 );
148   myScale->RangeStepAndValidator( 1E-5, 1E+5, 0.1, 6 );
149   myGroupLayout->addWidget( myScale, row, 1 );
150   row++;
151
152   myInfo = new QLabel( tr( "SMESH_FUNC_DOMAIN" ), GroupC1 );
153   myGroupLayout->addWidget( myInfo, row, 0, 1, 2 );
154   row++;
155   
156   // 4)  table
157   myGroupLayout->addWidget( myLTable = new QLabel( tr( "SMESH_TAB_FUNC" ), GroupC1 ), row, 0 );
158   myTable = new StdMeshersGUI_DistrTableFrame( GroupC1 );
159   myGroupLayout->addWidget( myTable, row, 1 );
160   myGroupLayout->setRowStretch( row, 1 );
161   myTableRow = row;
162   row++;
163
164   // 5)  expression
165   myGroupLayout->addWidget( myLExpr = new QLabel( tr( "SMESH_EXPR_FUNC" ), GroupC1 ), row, 0 );
166   myExpr = new QLineEdit( GroupC1 );
167   myGroupLayout->addWidget( myExpr, row, 1 );
168   row++;
169
170   // 6)  conversion (radiogroup)
171   myConvBox = new QGroupBox( tr( "SMESH_CONV_MODE" ), GroupC1 );
172   myConv = new QButtonGroup( GroupC1 );
173
174   QHBoxLayout* convLay = new QHBoxLayout( myConvBox );
175   convLay->setMargin( MARGIN );
176   convLay->setSpacing( SPACING );
177
178   QRadioButton* rbExp = new QRadioButton( tr( "SMESH_EXP_MODE" ), myConvBox );
179   QRadioButton* myCutNeg = new QRadioButton( tr( "SMESH_CUT_NEG_MODE" ), myConvBox );
180
181   convLay->addWidget( rbExp );
182   convLay->addWidget( myCutNeg );
183   myConv->addButton( rbExp, 0 );
184   myConv->addButton( myCutNeg, 1 );
185
186   myGroupLayout->addWidget( myConvBox, row, 0, 1, 2 );
187   row++;
188
189   // 7) distribution preview
190   myGroupLayout->addWidget( myPreview, row, 0, 1, 2 );
191   myGroupLayout->setRowStretch( row, 1 );
192   myPreviewRow = row;
193   row++;
194
195   connect( myNbSeg, SIGNAL( valueChanged( const QString& ) ), this, SLOT( onValueChanged() ) );
196   connect( myDistr, SIGNAL( activated( int ) ), this, SLOT( onValueChanged() ) );
197   connect( myTable, SIGNAL( valueChanged( int, int ) ), this, SLOT( onValueChanged() ) );
198   connect( myExpr,  SIGNAL( textChanged( const QString& ) ), this, SLOT( onValueChanged() ) );
199   connect( myConv,  SIGNAL( cuttonClicked( int ) ), this, SLOT( onValueChanged() ) );
200
201   return fr;
202 }
203
204 void StdMeshersGUI_NbSegmentsCreator::retrieveParams() const
205 {
206   NbSegmentsHypothesisData data;
207   readParamsFromHypo( data );
208
209   if( myName )
210     myName->setText( data.myName );
211   myNbSeg->setValue( data.myNbSeg );
212   myDistr->setCurrentIndex( data.myDistrType );
213   myScale->setValue( data.myScale );
214   myConv->button( data.myConv )->setChecked( true );
215   myTable->setFuncMinValue(myConv->checkedId()==0 ? -1E20 : 0);
216   myTable->setData( data.myTable );
217   myExpr->setText( data.myExpr );
218
219   if ( dlg() )
220     dlg()->setMinimumSize( dlg()->minimumSizeHint().width(), dlg()->minimumSizeHint().height() );
221 }
222
223 QString StdMeshersGUI_NbSegmentsCreator::storeParams() const
224 {
225   NbSegmentsHypothesisData data;
226   readParamsFromWidgets( data );
227   storeParamsToHypo( data );
228
229   QString valStr = QString::number( data.myNbSeg ) += "; ";
230
231   enum DistrType
232   {
233     Regular, //!< equidistant distribution
234     Scale,   //!< scale distribution
235     TabFunc, //!< distribution with density function presented by table
236     ExprFunc //!< distribution with density function presented by expression
237   };
238   bool hasConv = false;
239   switch ( data.myDistrType ) {
240   case Regular :
241     valStr += tr("SMESH_DISTR_REGULAR");
242     break;
243   case Scale   :
244     valStr += tr("SMESH_NB_SEGMENTS_SCALE_PARAM") + " = " + QString::number( data.myScale );
245     break;
246   case TabFunc : {
247     //valStr += tr("SMESH_TAB_FUNC");
248     bool param = true;
249     for( int i=0; i < data.myTable.length(); i++, param = !param ) {
250       if ( param )
251         valStr += "[";
252       valStr += QString::number( data.myTable[ i ]);
253       valStr += ( param ? "," : "]" );
254     }
255     hasConv = true;
256     break;
257   }
258   case ExprFunc:
259     valStr += data.myExpr;
260     hasConv = true;
261     break;
262   }
263   if ( hasConv )
264     if ( data.myConv )
265       valStr += "; " + tr("SMESH_CUT_NEG_MODE");
266     else
267       valStr += "; " + tr("SMESH_EXP_MODE");
268
269   return valStr;
270 }
271
272 bool StdMeshersGUI_NbSegmentsCreator::readParamsFromHypo( NbSegmentsHypothesisData& h_data ) const
273 {
274   StdMeshers::StdMeshers_NumberOfSegments_var h =
275     StdMeshers::StdMeshers_NumberOfSegments::_narrow( initParamsHypothesis() );
276
277   h_data.myName = hypName();
278
279   h_data.myNbSeg = (int) h->GetNumberOfSegments();
280   int distr = (int) h->GetDistrType();
281   h_data.myDistrType = distr;
282   h_data.myScale = distr==1 ? h->GetScaleFactor() : 1.0;
283   if( distr==2 )
284   {
285     SMESH::double_array* a = h->GetTableFunction();
286     h_data.myTable = *a;
287     delete a;
288   }
289   else
290   {
291     SMESH::double_array& a = h_data.myTable;
292     // by default, constant table function f(t)=1
293     a.length( 4 );
294     a[0] = 0.0; a[1] = 1.0;
295     a[2] = 1.0; a[3] = 1.0; 
296   }
297
298   h_data.myExpr = distr==3 ? h->GetExpressionFunction() : "1";
299   h_data.myConv = distr==2 || distr==3 ? h->ConversionMode() : 1; /*cut negative by default*/
300
301   return true;
302 }
303
304 bool StdMeshersGUI_NbSegmentsCreator::storeParamsToHypo( const NbSegmentsHypothesisData& h_data ) const
305 {
306   StdMeshers::StdMeshers_NumberOfSegments_var h =
307     StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() );
308
309   bool ok = true;
310   try
311   {
312     if( isCreation() )
313       SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.toLatin1().data() );
314
315     h->SetNumberOfSegments( h_data.myNbSeg );
316     int distr = h_data.myDistrType;
317     h->SetDistrType( distr );
318
319     if( distr==1 )
320       h->SetScaleFactor( h_data.myScale );
321
322     if( distr==2 || distr==3 )
323       h->SetConversionMode( h_data.myConv );
324
325     if( distr==2 )
326       h->SetTableFunction( h_data.myTable );
327
328     if( distr==3 )
329       h->SetExpressionFunction( h_data.myExpr.toLatin1().data() );
330     //setting of function must follow after setConversionMode, because otherwise
331     //the function will be checked with old conversion mode, so that it may occurs
332     //unexpected errors for user
333   }
334   catch(const SALOME::SALOME_Exception& ex)
335   {
336     SalomeApp_Tools::QtCatchCorbaException(ex);
337     ok = false;
338   }
339   return ok;
340 }
341
342 bool StdMeshersGUI_NbSegmentsCreator::readParamsFromWidgets( NbSegmentsHypothesisData& h_data ) const
343 {
344   h_data.myName      = myName ? myName->text() : "";
345   h_data.myNbSeg     = myNbSeg->value();
346   h_data.myDistrType = myDistr->currentIndex();
347   h_data.myConv      = myConv->checkedId();
348   h_data.myScale     = myScale->value();
349   myTable->data( h_data.myTable );
350   h_data.myExpr      = myExpr->text();
351   return true;
352 }
353
354 void StdMeshersGUI_NbSegmentsCreator::onValueChanged()
355 {
356   int distr = myDistr->currentIndex();
357
358 /*  if( distr==2 ) //table func
359     myCutNeg->setText( tr( "SMESH_NO_CONV" ) );
360   else if( distr==3 )
361     myCutNeg->setText( tr( "SMESH_CUT_NEG_MODE" ) );*/
362
363   if( distr==2 && sender()==myConv ) //table func
364   {
365     myTable->setFuncMinValue( myConv->checkedId()==0 ? -1E20 : 0 );
366     SMESH::double_array arr;
367     myTable->data( arr );
368     myTable->setData( arr ); //update data in table
369   }
370
371   myScale->setShown( distr==1 );
372   myLScale->setShown( distr==1 );
373
374   bool isFunc = distr==2 || distr==3;
375   myPreview->setShown( isFunc );
376   myGroupLayout->setRowStretch( myPreviewRow, isFunc ? 1 : 0 );
377
378   myConvBox->setShown( isFunc );
379
380   if( distr==2 )
381     myTable->show();
382   else
383     myTable->hide();
384   myLTable->setShown( distr==2 );
385   myGroupLayout->setRowStretch( myTableRow, distr==2 ? 1 : 0 );
386
387   myExpr->setShown( distr==3 );
388   myLExpr->setShown( distr==3 );
389   myInfo->setShown( isFunc );
390
391   //change of preview
392   int nbSeg = myNbSeg->value();
393   if( distr==2 ) //preview for table-described function
394   {
395     SMESH::double_array a;
396     myTable->data( a );
397     myPreview->setParams( a, nbSeg, false );
398   }
399   else if( distr==3 ) //preview for analytic-described function
400     myPreview->setParams( myExpr->text(), nbSeg, 100, false );
401
402   if( isFunc )
403     myPreview->setConversion( StdMeshersGUI_DistrPreview::Conversion( myConv->checkedId() ) );
404
405   if ( (QtxComboBox*)sender() == myDistr && dlg() ) {
406     QApplication::instance()->processEvents();
407     dlg()->updateGeometry();
408     dlg()->setMinimumSize( dlg()->minimumSizeHint().width(), dlg()->minimumSizeHint().height() );
409     dlg()->resize( dlg()->minimumSize() );
410   }
411 }