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