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