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