Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[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   h_data.myName = hypName();
255
256   h_data.myNbSeg = (int) h->GetNumberOfSegments();
257   int distr = (int) h->GetDistrType();
258   h_data.myDistrType = distr;
259   h_data.myScale = distr==1 ? h->GetScaleFactor() : 1.0;
260   if( distr==2 )
261   {
262     SMESH::double_array* a = h->GetTableFunction();
263     h_data.myTable = *a;
264     delete a;
265   }
266   else
267   {
268     SMESH::double_array& a = h_data.myTable;
269     // by default, constant table function f(t)=1
270     a.length( 4 );
271     a[0] = 0.0; a[1] = 1.0;
272     a[2] = 1.0; a[3] = 1.0; 
273   }
274
275   h_data.myExpr = distr==3 ? h->GetExpressionFunction() : "1";
276   h_data.myConv = distr==2 || distr==3 ? h->ConversionMode() : 1; /*cut negative by default*/
277
278   return true;
279 }
280
281 bool StdMeshersGUI_NbSegmentsCreator::storeParamsToHypo( const NbSegmentsHypothesisData& h_data ) const
282 {
283   StdMeshers::StdMeshers_NumberOfSegments_var h =
284     StdMeshers::StdMeshers_NumberOfSegments::_narrow( hypothesis() );
285
286   bool ok = true;
287   try
288   {
289     if( isCreation() )
290       SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.latin1() );
291
292     h->SetNumberOfSegments( h_data.myNbSeg );
293     int distr = h_data.myDistrType;
294     h->SetDistrType( distr );
295
296     if( distr==1 )
297       h->SetScaleFactor( h_data.myScale );
298
299     if( distr==2 || distr==3 )
300       h->SetConversionMode( h_data.myConv );
301
302     if( distr==2 )
303       h->SetTableFunction( h_data.myTable );
304
305     if( distr==3 )
306       h->SetExpressionFunction( h_data.myExpr.latin1() );
307     //setting of function must follow after setConversionMode, because otherwise
308     //the function will be checked with old conversion mode, so that it may occurs
309     //unexpected errors for user
310   }
311   catch(const SALOME::SALOME_Exception& ex)
312   {
313     SalomeApp_Tools::QtCatchCorbaException(ex);
314     ok = false;
315   }
316   return ok;
317 }
318
319 bool StdMeshersGUI_NbSegmentsCreator::readParamsFromWidgets( NbSegmentsHypothesisData& h_data ) const
320 {
321   h_data.myName      = myName ? myName->text() : "";
322   h_data.myNbSeg     = myNbSeg->value();
323   h_data.myDistrType = myDistr->currentItem();
324   h_data.myConv      = myConv->id( myConv->selected() );
325   h_data.myScale     = myScale->value();
326   myTable->table()->data( h_data.myTable );
327   h_data.myExpr      = myExpr->text();
328   return true;
329 }
330
331 void StdMeshersGUI_NbSegmentsCreator::onValueChanged()
332 {
333   int distr = myDistr->currentItem();
334
335 /*  if( distr==2 ) //table func
336     myCutNeg->setText( tr( "SMESH_NO_CONV" ) );
337   else if( distr==3 )
338     myCutNeg->setText( tr( "SMESH_CUT_NEG_MODE" ) );*/
339
340   if( distr==2 && sender()==myConv ) //table func
341   {
342     myTable->table()->funcValidator()->setBottom( myConv->id( myConv->selected() )==0 ? -1E20 : 0 );
343     SMESH::double_array arr;
344     myTable->table()->data( arr );
345     myTable->table()->setData( arr ); //update data in table
346   }
347
348   myScale->setShown( distr==1 );
349   myLScale->setShown( distr==1 );
350
351   bool isFunc = distr==2 || distr==3;
352   myPreview->setShown( isFunc );
353   myGroupLayout->setRowStretch( myPreviewRow, isFunc ? 1 : 0 );
354
355   myConv->setShown( isFunc );
356   myLConv->setShown( isFunc );
357
358   if( distr==2 )
359     myTable->show();
360   else
361     myTable->hide();
362   myLTable->setShown( distr==2 );
363   myGroupLayout->setRowStretch( myTableRow, distr==2 ? 1 : 0 );
364
365   myExpr->setShown( distr==3 );
366   myLExpr->setShown( distr==3 );
367   myInfo->setShown( isFunc );
368
369   //change of preview
370   int nbSeg = myNbSeg->value();
371   if( distr==2 ) //preview for table-described function
372   {
373     SMESH::double_array a;
374     myTable->table()->data( a );
375     myPreview->setParams( a, nbSeg, false );
376   }
377   else if( distr==3 ) //preview for analytic-described function
378     myPreview->setParams( myExpr->text(), nbSeg, 100, false );
379
380   if( isFunc )
381     myPreview->setConversion( StdMeshersGUI_DistrPreview::Conversion( myConv->id( myConv->selected() ) ) );
382 }