Salome HOME
Merge from OCC_development_generic_2006
[modules/smesh.git] / src / StdMeshersGUI / StdMeshersGUI_NbSegmentsCreator.cxx
1
2 #include "StdMeshersGUI_NbSegmentsCreator.h"
3 #include "StdMeshersGUI_DistrTable.h"
4 #include "StdMeshersGUI_DistrPreview.h"
5
6 #include <SMESHGUI_Utils.h>
7 #include <SMESHGUI_HypothesesUtils.h>
8
9 #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
10
11 #include <SalomeApp_Tools.h>
12
13 #include <QtxIntSpinBox.h>
14 #include <QtxComboBox.h>
15 #include <QtxDblValidator.h>
16 #include <SMESHGUI_SpinBox.h>
17
18 #include <qlabel.h>
19 #include <qgroupbox.h>
20 #include <qframe.h>
21 #include <qlayout.h>
22 #include <qlineedit.h>
23 #include <qbuttongroup.h>
24 #include <qradiobutton.h>
25
26 StdMeshersGUI_NbSegmentsCreator::StdMeshersGUI_NbSegmentsCreator()
27 : StdMeshersGUI_StdHypothesisCreator( "NumberOfSegments" ),
28   myNbSeg( 0 ),
29   myDistr( 0 ),
30   myScale( 0 ),
31   myTable( 0 ),
32   myPreview( 0 ),
33   myExpr( 0 ),
34   myConv( 0 ),
35   myLScale( 0 ),
36   myLTable( 0 ),
37   myLExpr( 0 ),
38   myLConv( 0 ),
39   myInfo( 0 ),
40   myGroupLayout( 0 ),
41   myTableRow( 0 ),
42   myPreviewRow( 0 )
43 {
44 }
45
46 StdMeshersGUI_NbSegmentsCreator::~StdMeshersGUI_NbSegmentsCreator()
47 {
48 }
49
50 bool StdMeshersGUI_NbSegmentsCreator::checkParams() const
51 {
52   NbSegmentsHypothesisData data_old, data_new;
53   readParamsFromHypo( data_old );
54   readParamsFromWidgets( data_new );
55   bool res = storeParamsToHypo( data_new );
56   storeParamsToHypo( data_old );
57   return res;
58 }
59
60 QFrame* StdMeshersGUI_NbSegmentsCreator::buildFrame()
61 {
62   QFrame* fr = new QFrame( 0, "myframe" );
63   QVBoxLayout* lay = new QVBoxLayout( fr, 5, 0 );
64
65   QGroupBox* GroupC1 = new QGroupBox( fr, "GroupC1" );
66   lay->addWidget( GroupC1 );
67
68   StdMeshers::StdMeshers_NumberOfSegments_var h =
69     StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() );
70   myPreview = new StdMeshersGUI_DistrPreview( GroupC1, h.in() );
71
72   GroupC1->setTitle( tr( "SMESH_ARGUMENTS"  ) );
73   GroupC1->setColumnLayout(0, Qt::Vertical );
74   GroupC1->layout()->setSpacing( 0 );
75   GroupC1->layout()->setMargin( 0 );
76   myGroupLayout = new QGridLayout( GroupC1->layout() );
77   myGroupLayout->setAlignment( Qt::AlignTop );
78   myGroupLayout->setSpacing( 6 );
79   myGroupLayout->setMargin( 11 );
80   myGroupLayout->setColStretch( 0, 0 );
81   myGroupLayout->setColStretch( 1, 1 );
82
83   int row = 0;
84   // 0)  name
85   myName = 0;
86   if( isCreation() )
87   {
88     myName = new QLineEdit( GroupC1 );
89     myGroupLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), GroupC1 ), row, 0 );
90     myGroupLayout->addWidget( myName, row, 1 );
91     row++;
92   }
93
94   // 1)  number of segments
95   myGroupLayout->addWidget( new QLabel( tr( "SMESH_NB_SEGMENTS_PARAM" ), GroupC1 ), row, 0 );
96   myNbSeg = new QtxIntSpinBox( GroupC1 );
97   myNbSeg->setMinValue( 1 );
98   myNbSeg->setMaxValue( 9999 );
99   myGroupLayout->addWidget( myNbSeg, row, 1 );
100   row++;
101
102   // 2)  type of distribution
103   myGroupLayout->addWidget( new QLabel( tr( "SMESH_DISTR_TYPE" ), GroupC1 ), row, 0 );
104   myDistr = new QtxComboBox( GroupC1 );
105   QStringList types;
106   types.append( QObject::tr( "SMESH_DISTR_REGULAR" ) );
107   types.append( QObject::tr( "SMESH_DISTR_SCALE"   ) );
108   types.append( QObject::tr( "SMESH_DISTR_TAB"     ) );
109   types.append( QObject::tr( "SMESH_DISTR_EXPR"    ) );
110   myDistr->insertStringList( types );
111   myGroupLayout->addWidget( myDistr, row, 1 );
112   row++;
113
114   // 3)  scale
115   myGroupLayout->addWidget( myLScale = new QLabel( tr( "SMESH_NB_SEGMENTS_SCALE_PARAM" ), GroupC1 ), row, 0 );
116   myScale = new SMESHGUI_SpinBox( GroupC1 );
117   myScale->RangeStepAndValidator( 1E-5, 1E+5, 0.1, 6 );
118   myGroupLayout->addWidget( myScale, row, 1 );
119   row++;
120
121   myInfo = new QLabel( tr( "SMESH_FUNC_DOMAIN" ), GroupC1 );
122   myGroupLayout->addMultiCellWidget( myInfo, row, row, 0, 1 );
123   row++;
124   
125   // 4)  table
126   myGroupLayout->addWidget( myLTable = new QLabel( tr( "SMESH_TAB_FUNC" ), GroupC1 ), row, 0 );
127   myTable = new StdMeshersGUI_DistrTableFrame( GroupC1 );
128   myGroupLayout->addWidget( myTable, row, 1 );
129   myGroupLayout->setRowStretch( row, 1 );
130   myTableRow = row;
131   row++;
132
133   // 5)  expression
134   myGroupLayout->addWidget( myLExpr = new QLabel( tr( "SMESH_EXPR_FUNC" ), GroupC1 ), row, 0 );
135   myExpr = new QLineEdit( GroupC1 );
136   myGroupLayout->addWidget( myExpr, row, 1 );
137   row++;
138
139   // 6)  conversion (radiogroup)
140   myGroupLayout->addWidget( myLConv = new QLabel( tr( "SMESH_CONV_MODE" ), GroupC1 ), row, 0 );
141   myConv = new QButtonGroup( GroupC1 );
142   myConv->setExclusive( true );
143   myConv->setColumnLayout( 0, Qt::Vertical );
144   QGridLayout* convLay = new QGridLayout( myConv->layout() );
145   convLay->addWidget( new QRadioButton( tr( "SMESH_EXP_MODE" ), myConv ), 0, 0 );
146   convLay->addWidget( myCutNeg = new QRadioButton( tr( "SMESH_CUT_NEG_MODE" ), myConv ), 1, 0 );
147   myGroupLayout->addWidget( myConv, row, 1 );
148   row++;
149
150   // 7) distribution preview
151   myGroupLayout->addMultiCellWidget( myPreview, row, row, 0, 1 );
152   myGroupLayout->setRowStretch( row, 1 );
153   myPreviewRow = row;
154   row++;
155
156   connect( myNbSeg, SIGNAL( valueChanged( const QString& ) ), this, SLOT( onValueChanged() ) );
157   connect( myDistr, SIGNAL( activated( int ) ), this, SLOT( onValueChanged() ) );
158   connect( myTable, SIGNAL( valueChanged( int, int ) ), this, SLOT( onValueChanged() ) );
159   connect( myExpr,  SIGNAL( textChanged( const QString& ) ), this, SLOT( onValueChanged() ) );
160   connect( myConv,  SIGNAL( clicked( int ) ), this, SLOT( onValueChanged() ) );
161
162   return fr;
163 }
164
165 void StdMeshersGUI_NbSegmentsCreator::retrieveParams() const
166 {
167   NbSegmentsHypothesisData data;
168   readParamsFromHypo( data );
169
170   if( myName )
171     myName->setText( data.myName );
172   myNbSeg->setValue( data.myNbSeg );
173   myDistr->setCurrentItem( data.myDistrType );
174   myScale->setValue( data.myScale );
175   myConv->setButton( data.myConv );
176   myTable->table()->setData( data.myTable );
177   myExpr->setText( data.myExpr );
178 }
179
180 QString StdMeshersGUI_NbSegmentsCreator::storeParams() const
181 {
182   NbSegmentsHypothesisData data;
183   readParamsFromWidgets( data );
184   storeParamsToHypo( data );
185
186   QString valStr = QString::number( data.myNbSeg ) += "; ";
187
188   enum DistrType
189   {
190     Regular, //!< equidistant distribution
191     Scale,   //!< scale distribution
192     TabFunc, //!< distribution with density function presented by table
193     ExprFunc //!< distribution with density function presented by expression
194   };
195   bool hasConv = false;
196   switch ( data.myDistrType ) {
197   case Regular :
198     valStr += tr("SMESH_DISTR_REGULAR");
199     break;
200   case Scale   :
201     valStr += tr("SMESH_NB_SEGMENTS_SCALE_PARAM") + " = " + QString::number( data.myScale );
202     break;
203   case TabFunc : {
204     //valStr += tr("SMESH_TAB_FUNC");
205     bool param = true;
206     for( int i=0; i < data.myTable.length(); i++, param = !param ) {
207       if ( param )
208         valStr += "[";
209       valStr += QString::number( data.myTable[ i ]);
210       valStr += ( param ? "," : "]" );
211     }
212     hasConv = true;
213     break;
214   }
215   case ExprFunc:
216     valStr += data.myExpr;
217     hasConv = true;
218     break;
219   }
220   if ( hasConv )
221     if ( data.myConv )
222       valStr += "; " + tr("SMESH_CUT_NEG_MODE");
223     else
224       valStr += "; " + tr("SMESH_EXP_MODE");
225
226   return valStr;
227 }
228
229 bool StdMeshersGUI_NbSegmentsCreator::readParamsFromHypo( NbSegmentsHypothesisData& h_data ) const
230 {
231   StdMeshers::StdMeshers_NumberOfSegments_var h =
232     StdMeshers::StdMeshers_NumberOfSegments::_narrow( initParamsHypothesis() );
233
234   HypothesisData* data = SMESH::GetHypothesisData( hypType() );
235   h_data.myName = isCreation() && data ? data->Label : "";
236
237   h_data.myNbSeg = (int) h->GetNumberOfSegments();
238   int distr = (int) h->GetDistrType();
239   h_data.myDistrType = distr;
240   h_data.myScale = distr==1 ? h->GetScaleFactor() : 1.0;
241   if( distr==2 )
242   {
243     SMESH::double_array* a = h->GetTableFunction();
244     h_data.myTable = *a;
245     delete a;
246   }
247   else
248   {
249     SMESH::double_array& a = h_data.myTable;
250     // by default, constant table function f(t)=1
251     a.length( 4 );
252     a[0] = 0.0; a[1] = 1.0;
253     a[2] = 1.0; a[3] = 1.0; 
254   }
255
256   h_data.myExpr = distr==3 ? h->GetExpressionFunction() : "1";
257   h_data.myConv = distr==2 || distr==3 ? h->ConversionMode() : 1; /*cut negative by default*/
258
259   return true;
260 }
261
262 bool StdMeshersGUI_NbSegmentsCreator::storeParamsToHypo( const NbSegmentsHypothesisData& h_data ) const
263 {
264   StdMeshers::StdMeshers_NumberOfSegments_var h =
265     StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() );
266
267   bool ok = true;
268   try
269   {
270     if( isCreation() )
271       SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.latin1() );
272
273     h->SetNumberOfSegments( h_data.myNbSeg );
274     int distr = h_data.myDistrType;
275     h->SetDistrType( distr );
276
277     if( distr==1 )
278       h->SetScaleFactor( h_data.myScale );
279
280     if( distr==2 || distr==3 )
281       h->SetConversionMode( h_data.myConv );
282
283     if( distr==2 )
284       h->SetTableFunction( h_data.myTable );
285
286     if( distr==3 )
287       h->SetExpressionFunction( h_data.myExpr.latin1() );
288     //setting of function must follow after setConversionMode, because otherwise
289     //the function will be checked with old conversion mode, so that it may occurs
290     //unexpected errors for user
291   }
292   catch(const SALOME::SALOME_Exception& ex)
293   {
294     SalomeApp_Tools::QtCatchCorbaException(ex);
295     ok = false;
296   }
297   return ok;
298 }
299
300 bool StdMeshersGUI_NbSegmentsCreator::readParamsFromWidgets( NbSegmentsHypothesisData& h_data ) const
301 {
302   h_data.myName      = myName ? myName->text() : "";
303   h_data.myNbSeg     = myNbSeg->value();
304   h_data.myDistrType = myDistr->currentItem();
305   h_data.myConv      = myConv->id( myConv->selected() );
306   h_data.myScale     = myScale->value();
307   myTable->table()->data( h_data.myTable );
308   h_data.myExpr      = myExpr->text();
309   return true;
310 }
311
312 void StdMeshersGUI_NbSegmentsCreator::onValueChanged()
313 {
314   int distr = myDistr->currentItem();
315
316 /*  if( distr==2 ) //table func
317     myCutNeg->setText( tr( "SMESH_NO_CONV" ) );
318   else if( distr==3 )
319     myCutNeg->setText( tr( "SMESH_CUT_NEG_MODE" ) );*/
320
321   if( distr==2 && sender()==myConv ) //table func
322   {
323     myTable->table()->funcValidator()->setBottom( myConv->id( myConv->selected() )==0 ? -1E20 : 0 );
324     SMESH::double_array arr;
325     myTable->table()->data( arr );
326     myTable->table()->setData( arr ); //update data in table
327   }
328
329   myScale->setShown( distr==1 );
330   myLScale->setShown( distr==1 );
331
332   bool isFunc = distr==2 || distr==3;
333   myPreview->setShown( isFunc );
334   myGroupLayout->setRowStretch( myPreviewRow, isFunc ? 1 : 0 );
335
336   myConv->setShown( isFunc );
337   myLConv->setShown( isFunc );
338
339   if( distr==2 )
340     myTable->show();
341   else
342     myTable->hide();
343   myLTable->setShown( distr==2 );
344   myGroupLayout->setRowStretch( myTableRow, distr==2 ? 1 : 0 );
345
346   myExpr->setShown( distr==3 );
347   myLExpr->setShown( distr==3 );
348   myInfo->setShown( isFunc );
349
350   //change of preview
351   int nbSeg = myNbSeg->value();
352   if( distr==2 ) //preview for table-described function
353   {
354     SMESH::double_array a;
355     myTable->table()->data( a );
356     myPreview->setParams( a, nbSeg, false );
357   }
358   else if( distr==3 ) //preview for analytic-described function
359     myPreview->setParams( myExpr->text(), nbSeg, 100, false );
360
361   if( isFunc )
362     myPreview->setConversion( StdMeshersGUI_DistrPreview::Conversion( myConv->id( myConv->selected() ) ) );
363 }