Salome HOME
Dump Python Extension
[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 <SUIT_Session.h>
39 #include <SUIT_MessageBox.h>
40 #include <SUIT_ResourceMgr.h>
41 #include <LightApp_Application.h>
42 #include <SalomeApp_IntSpinBox.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           SalomeApp_IntSpinBox* sb = new SalomeApp_IntSpinBox( 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( "SalomeApp_IntSpinBox" ) )
273     {
274       SalomeApp_IntSpinBox* sb = ( SalomeApp_IntSpinBox* )( *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
430     aHelpFileName = "";
431   return aHelpFileName;
432 }
433
434
435
436
437 SMESHGUI_HypothesisDlg::SMESHGUI_HypothesisDlg( SMESHGUI_GenericHypothesisCreator* creator, QWidget* parent )
438 : QtxDialog( parent, false, true ),
439   myCreator( creator )
440 {
441   setMinimumSize( 300, height() );
442 //  setFixedSize( 300, height() );
443   QVBoxLayout* topLayout = new QVBoxLayout( mainFrame() );
444   topLayout->setMargin( 0 );
445   topLayout->setSpacing( 0 );
446
447   QFrame* titFrame = new QFrame( mainFrame() );
448   QHBoxLayout* titLay = new QHBoxLayout( titFrame );
449   titLay->setMargin( 0 );
450   titLay->setSpacing( SPACING );
451   
452   myIconLabel = new QLabel( titFrame );
453   myIconLabel->setScaledContents( false );
454   myIconLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
455   myTypeLabel = new QLabel( titFrame );
456   if( creator )
457     myTypeLabel->setText( creator->hypType() );
458
459   titLay->addWidget( myIconLabel, 0 );
460   titLay->addWidget( myTypeLabel, 0 );
461   titLay->addStretch( 1 );
462
463   topLayout->addWidget( titFrame, 0 );
464
465   myHelpFileName = creator->helpPage();
466
467   connect( this, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) );
468 }
469
470 SMESHGUI_HypothesisDlg::~SMESHGUI_HypothesisDlg()
471 {
472 }
473
474 void SMESHGUI_HypothesisDlg::setCustomFrame( QFrame* f )
475 {
476   if( f )
477   {
478     f->setParent( mainFrame() );
479     qobject_cast<QVBoxLayout*>( mainFrame()->layout() )->insertWidget( 1, f, 1 );
480   }
481 }
482
483 void SMESHGUI_HypothesisDlg::accept()
484 {
485   if ( myCreator && !myCreator->checkParams() )
486     return;
487   QtxDialog::accept();
488 }
489
490 void SMESHGUI_HypothesisDlg::reject()
491 {
492   if ( myCreator ) myCreator->onReject();
493   QtxDialog::reject();
494 }
495
496 void SMESHGUI_HypothesisDlg::onHelp()
497 {
498   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
499   if (app) {
500     SMESHGUI* aSMESHGUI = dynamic_cast<SMESHGUI*>( app->activeModule() );
501     app->onHelpContextModule(aSMESHGUI ? app->moduleName(aSMESHGUI->moduleName()) : QString(""), myHelpFileName);
502   }
503   else {
504     QString platform;
505 #ifdef WIN32
506     platform = "winapplication";
507 #else
508     platform = "application";
509 #endif
510     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
511                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
512                              arg(app->resourceMgr()->stringValue("ExternalBrowser", 
513                                                                  platform)).
514                              arg(myHelpFileName));
515   }
516 }
517
518 void SMESHGUI_HypothesisDlg::setHIcon( const QPixmap& p )
519 {
520   myIconLabel->setPixmap( p );  
521 }
522
523 void SMESHGUI_HypothesisDlg::setType( const QString& t )
524 {
525   myTypeLabel->setText( t );
526 }
527
528 HypothesisData::HypothesisData( const QString& theTypeName,
529                                 const QString& thePluginName,
530                                 const QString& theServerLibName,
531                                 const QString& theClientLibName,
532                                 const QString& theLabel,
533                                 const QString& theIconId,
534                                 const QList<int>& theDim,
535                                 const bool theIsAux,
536                                 const QStringList& theNeededHypos,
537                                 const QStringList& theOptionalHypos,
538                                 const QStringList& theInputTypes,
539                                 const QStringList& theOutputTypes,
540                                 const bool theIsNeedGeometry,
541                                 const bool supportSub)
542   : TypeName( theTypeName ),
543     PluginName( thePluginName ),
544     ServerLibName( theServerLibName ),
545     ClientLibName( theClientLibName ),
546     Label( theLabel ),
547     IconId( theIconId ),
548     Dim( theDim ),
549     IsAux( theIsAux ),
550     NeededHypos( theNeededHypos ), 
551     OptionalHypos( theOptionalHypos ),
552     InputTypes( theInputTypes ),
553     OutputTypes( theOutputTypes ),
554     IsNeedGeometry( theIsNeedGeometry ),
555     IsSupportSubmeshes( supportSub )
556 {
557 }
558
559 HypothesesSet::HypothesesSet( const QString& theSetName ) 
560   : HypoSetName( theSetName )
561 {
562 }
563
564 HypothesesSet::HypothesesSet( const QString&     theSetName,
565                               const QStringList& theHypoList,
566                               const QStringList& theAlgoList )
567   : HypoSetName( theSetName ), 
568     HypoList( theHypoList ), 
569     AlgoList( theAlgoList )
570 {
571 }