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