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