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