Salome HOME
bc2765def472d818f3d640926e549d849955d7b8
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_Hypotheses.cxx
1 // SMESH SMESHGUI : GUI for SMESH component
2 //
3 // Copyright (C) 2003  CEA
4 //
5 // This library is free software; you can redistribute it and/or 
6 // modify it under the terms of the GNU Lesser General Public 
7 // License as published by the Free Software Foundation; either 
8 // version 2.1 of the License. 
9 //
10 // This library is distributed in the hope that it will be useful, 
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
13 // Lesser General Public License for more details. 
14 //
15 // You should have received a copy of the GNU Lesser General Public 
16 // License along with this library; if not, write to the Free Software 
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
18 //
19 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 //
21 // File   : SMESHGUI_Hypotheses.cxx
22 // Author : Julia DOROVSKIKH, Open CASCADE S.A.S.
23 //
24
25 // SMESH includes
26 #include "SMESHGUI_Hypotheses.h"
27
28 #include "SMESHGUI.h"
29 #include "SMESHGUI_HypothesesUtils.h"
30 #include "SMESHGUI_Utils.h"
31 #include "SMESHGUI_SpinBox.h"
32
33 // SALOME KERNEL includes
34 #include <SALOMEDSClient_Study.hxx>
35 #include <utilities.h>
36
37 // SALOME GUI includes
38 #include <QtxIntSpinBox.h>
39 #include <SUIT_Session.h>
40 #include <SUIT_MessageBox.h>
41 #include <SUIT_ResourceMgr.h>
42 #include <LightApp_Application.h>
43
44 // Qt includes
45 #include <QFrame>
46 #include <QLineEdit>
47 #include <QLabel>
48 #include <QGroupBox>
49 #include <QVBoxLayout>
50 #include <QEventLoop>
51
52 #define SPACING 6
53 #define MARGIN  11
54
55 SMESHGUI_GenericHypothesisCreator::SMESHGUI_GenericHypothesisCreator( const QString& theHypType )
56   : myHypType( theHypType ), myIsCreate( false ), myDlg( 0 ), myEventLoop( 0 )
57 {
58 }
59
60 SMESHGUI_GenericHypothesisCreator::~SMESHGUI_GenericHypothesisCreator()
61 {
62 }
63
64 void SMESHGUI_GenericHypothesisCreator::create( SMESH::SMESH_Hypothesis_ptr initParamsHyp,
65                                                 const QString& theHypName,
66                                                 QWidget* parent)
67 {
68   MESSAGE( "Creation of hypothesis with initial params" );
69
70   if ( !CORBA::is_nil( initParamsHyp ) && hypType() == initParamsHyp->GetName() )
71     myInitParamsHypo = SMESH::SMESH_Hypothesis::_duplicate( initParamsHyp );
72   create( false, theHypName, parent );
73 }
74
75 void SMESHGUI_GenericHypothesisCreator::create( bool isAlgo,
76                                                 const QString& theHypName,
77                                                 QWidget* theParent )
78 {
79   MESSAGE( "Creation of hypothesis" );
80
81   myIsCreate = true;
82
83   // Create hypothesis/algorithm
84   if (isAlgo)
85     SMESH::CreateHypothesis( hypType(), theHypName, isAlgo );
86   else
87   {
88     SMESH::SMESH_Hypothesis_var aHypothesis = 
89       SMESH::CreateHypothesis( hypType(), theHypName, false );
90     if( !editHypothesis( aHypothesis.in(), theHypName, theParent ) )
91     { //remove just created hypothesis
92       _PTR(SObject) aHypSObject = SMESH::FindSObject( aHypothesis.in() );
93       _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
94       if( aStudy && !aStudy->GetProperties()->IsLocked() )
95       {
96         _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
97         aBuilder->RemoveObjectWithChildren( aHypSObject );
98       }
99     }
100   }
101   SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 );
102 }
103
104 void SMESHGUI_GenericHypothesisCreator::edit( SMESH::SMESH_Hypothesis_ptr theHypothesis,
105                                               const QString& theHypName,
106                                               QWidget* theParent )
107 {
108   if( CORBA::is_nil( theHypothesis ) )
109     return;
110
111   MESSAGE("Edition of hypothesis");
112
113   myIsCreate = false;
114
115   if( !editHypothesis( theHypothesis, theHypName, theParent ) )
116     return;
117
118   SMESH::SObjectList listSOmesh = SMESH::GetMeshesUsingAlgoOrHypothesis( theHypothesis );
119   if( listSOmesh.size() > 0 )
120     for( int i = 0; i < listSOmesh.size(); i++ )
121     {
122       _PTR(SObject) submSO = listSOmesh[i];
123       SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( submSO );
124       SMESH::SMESH_subMesh_var aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>( submSO );
125       if( !aSubMesh->_is_nil() )
126         aMesh = aSubMesh->GetFather();
127       _PTR(SObject) meshSO = SMESH::FindSObject( aMesh );
128       SMESH::ModifiedMesh( meshSO, false, aMesh->NbNodes()==0);
129     }
130   SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 );
131 }
132
133 bool SMESHGUI_GenericHypothesisCreator::editHypothesis( SMESH::SMESH_Hypothesis_ptr h, 
134                                                         const QString& theHypName,
135                                                         QWidget* theParent )
136 {
137   if( CORBA::is_nil( h ) )
138     return false;
139
140   bool res = true;
141   myHypName = theHypName;
142   myHypo = SMESH::SMESH_Hypothesis::_duplicate( h );
143
144   SMESHGUI_HypothesisDlg* Dlg = new SMESHGUI_HypothesisDlg( this, theParent );
145   connect( Dlg, SIGNAL( finished( int ) ), this, SLOT( onDialogFinished( int ) ) );
146   myDlg = Dlg;
147   QFrame* fr = buildFrame();
148   if( fr )
149   {
150     Dlg->setCustomFrame( fr );
151     Dlg->setWindowTitle( caption() );
152     Dlg->setObjectName( theHypName );
153     Dlg->setHIcon( icon() );
154     Dlg->setType( type() );
155     retrieveParams();
156     Dlg->show();
157     if ( !myEventLoop )
158       myEventLoop = new QEventLoop( this );
159     myEventLoop->exec(); // make myDlg not modal
160     res = myDlg->result();
161     if( res ) {
162       QString paramValues = storeParams();
163       if ( !paramValues.isEmpty() ) {
164         if ( _PTR(SObject) SHyp = SMESH::FindSObject( myHypo ))
165           SMESH::SetValue( SHyp, paramValues );
166       }
167     }
168   }
169   delete Dlg; myDlg = 0;
170   changeWidgets().clear();
171   myHypo = SMESH::SMESH_Hypothesis::_nil();
172   myInitParamsHypo = SMESH::SMESH_Hypothesis::_nil();
173   return res;
174 }
175   
176 QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame()
177 {
178   if( CORBA::is_nil( hypothesis() ) )
179     return 0;
180
181   ListOfStdParams params;
182   if( !stdParams( params ) || params.isEmpty() )
183     return 0;
184
185   QFrame* fr = new QFrame( 0 );
186   QVBoxLayout* lay = new QVBoxLayout( fr );
187   lay->setMargin( 5 );
188   lay->setSpacing( 0 );
189
190   QGroupBox* GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), fr );
191   lay->addWidget( GroupC1 );
192
193   QGridLayout* GroupC1Layout = new QGridLayout( GroupC1 );
194   GroupC1Layout->setSpacing( SPACING );
195   GroupC1Layout->setMargin( MARGIN );
196
197   ListOfStdParams::const_iterator anIt = params.begin(), aLast = params.end();
198   for( int i=0; anIt!=aLast; anIt++, i++ )
199   {
200     QLabel* lab = new QLabel( (*anIt).myName, GroupC1 );
201     GroupC1Layout->addWidget( lab, i, 0 );
202
203     QWidget* w = getCustomWidget( *anIt, GroupC1, i );
204     if ( !w ) 
205       switch( (*anIt).myValue.type() )
206       {
207       case QVariant::Int:
208         {
209           QtxIntSpinBox* sb = new QtxIntSpinBox( GroupC1 );
210           sb->setObjectName( (*anIt).myName );
211           attuneStdWidget( sb, i );
212           sb->setValue( (*anIt).myValue.toInt() );
213           connect( sb, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) );
214           w = sb;
215         }
216         break;
217       case QVariant::Double:
218         {
219           QtxDoubleSpinBox* sb = new SMESHGUI_SpinBox( GroupC1 );
220           sb->setObjectName( (*anIt).myName );
221           attuneStdWidget( sb, i );
222           sb->setValue( (*anIt).myValue.toDouble() );
223           connect( sb, SIGNAL( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
224           w = sb;
225         }
226         break;
227       case QVariant::String:
228         {
229           QLineEdit* le = new QLineEdit( GroupC1 );
230           le->setObjectName( (*anIt).myName );
231           attuneStdWidget( le, i );
232           le->setText( (*anIt).myValue.toString() );
233           connect( le, SIGNAL( textChanged( const QString& ) ), this, SLOT( onValueChanged() ) );
234           w = le;
235         }
236         break;
237       }
238
239     if( w )
240     {
241       GroupC1Layout->addWidget( w, i, 1 );
242       changeWidgets().append( w );
243     }
244   }
245
246   return fr;
247 }
248
249 void SMESHGUI_GenericHypothesisCreator::onValueChanged()
250 {
251 }
252
253 void SMESHGUI_GenericHypothesisCreator::onDialogFinished( int /*result*/ )
254 {
255   if ( myEventLoop )
256     myEventLoop->exit();
257 }
258
259 bool SMESHGUI_GenericHypothesisCreator::stdParams( ListOfStdParams& ) const
260 {
261   return false;
262 }
263
264 bool SMESHGUI_GenericHypothesisCreator::getStdParamFromDlg( ListOfStdParams& params ) const
265 {
266   bool res = true;
267   StdParam item;
268   ListOfWidgets::const_iterator anIt = widgets().begin(), aLast = widgets().end();
269   for( ; anIt!=aLast; anIt++ )
270   {
271     item.myName = (*anIt)->objectName();
272     if( (*anIt)->inherits( "QtxIntSpinBox" ) )
273     {
274       QtxIntSpinBox* sb = ( QtxIntSpinBox* )( *anIt );
275       item.myValue = sb->value();
276       params.append( item );
277     }
278     
279     else if( (*anIt)->inherits( "QtxDoubleSpinBox" ) )
280     {
281       QtxDoubleSpinBox* sb = ( QtxDoubleSpinBox* )( *anIt );
282       item.myValue = sb->value();
283       params.append( item );
284     }
285
286     else if( (*anIt)->inherits( "QLineEdit" ) )
287     {
288       QLineEdit* line = ( QLineEdit* )( *anIt );
289       item.myValue = line->text();
290       params.append( item );
291     }
292
293     else if ( getParamFromCustomWidget( item, *anIt ))
294     {
295       params.append( item );
296     }
297
298     else
299       res = false;
300   }
301   return res;
302 }
303
304 QString SMESHGUI_GenericHypothesisCreator::stdParamValues( const ListOfStdParams& params)
305 {
306   QString valueStr = "";
307   ListOfStdParams::const_iterator param = params.begin(), aLast = params.end();
308   uint len0 = 0;
309   for( int i=0; param!=aLast; param++, i++ )
310   {
311     if ( valueStr.length() > len0 ) {
312       valueStr += "; ";
313       len0 = valueStr.length();
314     }
315     switch( (*param).myValue.type() )
316     {
317     case QVariant::Int:
318       valueStr += valueStr.number( (*param).myValue.toInt() );
319       break;
320     case QVariant::Double:
321       valueStr += valueStr.number( (*param).myValue.toDouble() );
322       break;
323     case QVariant::String:
324       valueStr += (*param).myValue.toString();
325       break;
326     default:
327       QVariant valCopy = (*param).myValue;
328       valueStr += valCopy.toString();
329     }
330   }
331   return valueStr;
332 }
333
334 SMESH::SMESH_Hypothesis_var SMESHGUI_GenericHypothesisCreator::hypothesis() const
335 {
336   return myHypo;
337 }
338
339 SMESH::SMESH_Hypothesis_var SMESHGUI_GenericHypothesisCreator::initParamsHypothesis() const
340 {
341   if ( CORBA::is_nil( myInitParamsHypo ))
342     return myHypo;
343   return myInitParamsHypo;
344 }
345
346 QString SMESHGUI_GenericHypothesisCreator::hypType() const
347 {
348   return myHypType;
349 }
350
351 QString SMESHGUI_GenericHypothesisCreator::hypName() const
352 {
353   return myHypName;
354 }
355
356 const SMESHGUI_GenericHypothesisCreator::ListOfWidgets& SMESHGUI_GenericHypothesisCreator::widgets() const
357 {
358   return myParamWidgets;
359 }
360
361 SMESHGUI_GenericHypothesisCreator::ListOfWidgets& SMESHGUI_GenericHypothesisCreator::changeWidgets()
362 {
363   return myParamWidgets;
364 }
365
366 QtxDialog* SMESHGUI_GenericHypothesisCreator:: dlg() const
367
368   return myDlg;
369 }
370
371 bool SMESHGUI_GenericHypothesisCreator::isCreation() const
372 {
373   return myIsCreate;
374 }
375
376 void SMESHGUI_GenericHypothesisCreator::attuneStdWidget( QWidget*, const int ) const
377 {
378 }
379
380 QString SMESHGUI_GenericHypothesisCreator::caption() const
381 {
382   return QString();
383 }
384
385 QPixmap SMESHGUI_GenericHypothesisCreator::icon() const
386 {
387   return QPixmap();
388 }
389
390 QString SMESHGUI_GenericHypothesisCreator::type() const
391 {
392   return QString();
393 }
394 QWidget* SMESHGUI_GenericHypothesisCreator::getCustomWidget( const StdParam & /*param*/,
395                                                              QWidget*   /*parent*/,
396                                                              const int  /*index*/) const
397 {
398   return 0;
399 }
400 bool SMESHGUI_GenericHypothesisCreator::getParamFromCustomWidget( StdParam&, QWidget* ) const
401 {
402   return false;
403 }
404
405 void SMESHGUI_GenericHypothesisCreator::onReject()
406 {
407 }
408
409 QString SMESHGUI_GenericHypothesisCreator::helpPage() const
410 {
411   QString aHypType = hypType();
412   QString aHelpFileName;
413   if ( aHypType == "LocalLength" )
414     aHelpFileName = "a1d_meshing_hypo_page.html#average_length_anchor";
415   else if ( aHypType == "Arithmetic1D")
416     aHelpFileName = "a1d_meshing_hypo_page.html#arithmetic_1d_anchor";
417   else if ( aHypType == "MaxElementArea")
418     aHelpFileName = "a2d_meshing_hypo_page.html#max_element_area_anchor";
419   else if ( aHypType == "MaxElementVolume")
420     aHelpFileName = "max_element_volume_hypo_page.html";
421   else if ( aHypType == "StartEndLength")
422     aHelpFileName = "a1d_meshing_hypo_page.html#start_and_end_length_anchor";
423   else if ( aHypType == "Deflection1D")
424     aHelpFileName = "a1d_meshing_hypo_page.html#deflection_1d_anchor";
425   else if ( aHypType == "AutomaticLength")
426     aHelpFileName = "a1d_meshing_hypo_page.html#automatic_length_anchor";
427   else if ( aHypType == "NumberOfSegments")
428     aHelpFileName = "a1d_meshing_hypo_page.html#number_of_segments_anchor";
429   else if ( aHypType == "ProjectionSource1D")
430     aHelpFileName = "projection_algos_page.html";
431   else if ( aHypType == "ProjectionSource2D")
432     aHelpFileName = "projection_algos_page.html";
433   else if ( aHypType == "ProjectionSource3D")
434     aHelpFileName = "projection_algos_page.html";
435   else if ( aHypType == "NumberOfLayers")
436     aHelpFileName = "radial_prism_algo_page.html";
437   else if ( aHypType == "LayerDistribution")
438     aHelpFileName = "radial_prism_algo_page.html";
439   else if ( aHypType == "SegmentLengthAroundVertex")
440     aHelpFileName = "segments_around_vertex_algo.html";
441   else
442     aHelpFileName = "";
443   return aHelpFileName;
444 }
445
446
447
448
449 SMESHGUI_HypothesisDlg::SMESHGUI_HypothesisDlg( SMESHGUI_GenericHypothesisCreator* creator, QWidget* parent )
450 : QtxDialog( parent, false, true ),
451   myCreator( creator )
452 {
453   setMinimumSize( 300, height() );
454 //  setFixedSize( 300, height() );
455   QVBoxLayout* topLayout = new QVBoxLayout( mainFrame() );
456   topLayout->setMargin( 0 );
457   topLayout->setSpacing( 0 );
458
459   QFrame* titFrame = new QFrame( mainFrame() );
460   QHBoxLayout* titLay = new QHBoxLayout( titFrame );
461   titLay->setMargin( 0 );
462   titLay->setSpacing( SPACING );
463   
464   myIconLabel = new QLabel( titFrame );
465   myIconLabel->setScaledContents( false );
466   myIconLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
467   myTypeLabel = new QLabel( titFrame );
468   if( creator )
469     myTypeLabel->setText( creator->hypType() );
470
471   titLay->addWidget( myIconLabel, 0 );
472   titLay->addWidget( myTypeLabel, 0 );
473   titLay->addStretch( 1 );
474
475   topLayout->addWidget( titFrame, 0 );
476
477   myHelpFileName = creator->helpPage();
478
479   connect( this, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) );
480 }
481
482 SMESHGUI_HypothesisDlg::~SMESHGUI_HypothesisDlg()
483 {
484 }
485
486 void SMESHGUI_HypothesisDlg::setCustomFrame( QFrame* f )
487 {
488   if( f )
489   {
490     f->setParent( mainFrame() );
491     qobject_cast<QVBoxLayout*>( mainFrame()->layout() )->insertWidget( 1, f, 1 );
492   }
493 }
494
495 void SMESHGUI_HypothesisDlg::accept()
496 {
497   if ( myCreator && !myCreator->checkParams() )
498     return;
499   QtxDialog::accept();
500 }
501
502 void SMESHGUI_HypothesisDlg::reject()
503 {
504   if ( myCreator ) myCreator->onReject();
505   QtxDialog::reject();
506 }
507
508 void SMESHGUI_HypothesisDlg::onHelp()
509 {
510   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
511   if (app) {
512     SMESHGUI* aSMESHGUI = dynamic_cast<SMESHGUI*>( app->activeModule() );
513     app->onHelpContextModule(aSMESHGUI ? app->moduleName(aSMESHGUI->moduleName()) : QString(""), myHelpFileName);
514   }
515   else {
516     QString platform;
517 #ifdef WIN32
518     platform = "winapplication";
519 #else
520     platform = "application";
521 #endif
522     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
523                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
524                              arg(app->resourceMgr()->stringValue("ExternalBrowser", 
525                                                                  platform)).
526                              arg(myHelpFileName));
527   }
528 }
529
530 void SMESHGUI_HypothesisDlg::setHIcon( const QPixmap& p )
531 {
532   myIconLabel->setPixmap( p );  
533 }
534
535 void SMESHGUI_HypothesisDlg::setType( const QString& t )
536 {
537   myTypeLabel->setText( t );
538 }
539
540 HypothesisData::HypothesisData( const QString& theTypeName,
541                                 const QString& thePluginName,
542                                 const QString& theServerLibName,
543                                 const QString& theClientLibName,
544                                 const QString& theLabel,
545                                 const QString& theIconId,
546                                 const QList<int>& theDim,
547                                 const bool theIsAux,
548                                 const QStringList& theNeededHypos,
549                                 const QStringList& theOptionalHypos,
550                                 const QStringList& theInputTypes,
551                                 const QStringList& theOutputTypes,
552                                 const bool theIsNeedGeometry,
553                                 const bool supportSub)
554   : TypeName( theTypeName ),
555     PluginName( thePluginName ),
556     ServerLibName( theServerLibName ),
557     ClientLibName( theClientLibName ),
558     Label( theLabel ),
559     IconId( theIconId ),
560     Dim( theDim ),
561     IsAux( theIsAux ),
562     NeededHypos( theNeededHypos ), 
563     OptionalHypos( theOptionalHypos ),
564     InputTypes( theInputTypes ),
565     OutputTypes( theOutputTypes ),
566     IsNeedGeometry( theIsNeedGeometry ),
567     IsSupportSubmeshes( supportSub )
568 {
569 }
570
571 HypothesesSet::HypothesesSet( const QString& theSetName ) 
572   : HypoSetName( theSetName )
573 {
574 }
575
576 HypothesesSet::HypothesesSet( const QString&     theSetName,
577                               const QStringList& theHypoList,
578                               const QStringList& theAlgoList )
579   : HypoSetName( theSetName ), 
580     HypoList( theHypoList ), 
581     AlgoList( theAlgoList )
582 {
583 }