Salome HOME
Porting SMESH module to Qt 4
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_HypothesesUtils.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_HypothesesUtils.cxx
22 // Author : Julia DOROVSKIKH, Open CASCADE S.A.S.
23 //
24
25 // SMESH includes
26 #include "SMESHGUI_HypothesesUtils.h"
27
28 #include "SMESHGUI.h"
29 #include "SMESHGUI_Hypotheses.h"
30 #include "SMESHGUI_XmlHandler.h"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_GEOMGenUtils.h"
33
34 // SALOME GUI includes
35 #include <SUIT_Desktop.h>
36 #include <SUIT_MessageBox.h>
37 #include <SUIT_OverrideCursor.h>
38 #include <SUIT_ResourceMgr.h>
39
40 #include <SalomeApp_Study.h>
41 #include <SalomeApp_Tools.h>
42
43 // SALOME KERNEL includes
44 #include <utilities.h>
45
46 // STL includes
47 #include <map>
48 #include <string>
49
50 // Other includes
51 #ifdef WNT
52 #include <windows.h>
53 #else
54 #include <dlfcn.h>
55 #endif
56
57 #ifdef WNT
58 #define LibHandle HMODULE
59 #define LoadLib( name ) LoadLibrary( name )
60 #define GetProc GetProcAddress
61 #define UnLoadLib( handle ) FreeLibrary( handle );
62 #else
63 #define LibHandle void*
64 #define LoadLib( name ) dlopen( name, RTLD_LAZY )
65 #define GetProc dlsym
66 #define UnLoadLib( handle ) dlclose( handle );
67 #endif
68
69 #ifdef _DEBUG_
70 static int MYDEBUG = 0;
71 #else
72 static int MYDEBUG = 0;
73 #endif
74
75 namespace SMESH
76 {
77   typedef std::map<std::string,HypothesisData*> THypothesisDataMap;
78   THypothesisDataMap myHypothesesMap;
79   THypothesisDataMap myAlgorithmsMap;
80
81   typedef std::map<std::string,SMESHGUI_GenericHypothesisCreator*> THypCreatorMap;
82   THypCreatorMap myHypCreatorMap;
83
84   std::list<HypothesesSet*> myListOfHypothesesSets;
85
86   void processHypothesisStatus(const int theHypStatus,
87                                SMESH::SMESH_Hypothesis_ptr theHyp,
88                                const bool theIsAddition)
89   {
90     if (theHypStatus > SMESH::HYP_OK) {
91
92       // get Hyp name
93       QString aHypName ("NULL Hypothesis");
94       if (!CORBA::is_nil(theHyp)) {
95         _PTR(SObject) Shyp = SMESH::FindSObject(theHyp);
96         if (Shyp)
97           // name in study
98           aHypName = Shyp->GetName().c_str();
99         else
100           // label in xml file
101           aHypName = GetHypothesisData(theHyp->GetName())->Label;
102       }
103
104       // message
105       bool isFatal = (theHypStatus >= SMESH::HYP_UNKNOWN_FATAL);
106       QString aMsg;
107       if (theIsAddition)
108         aMsg = (isFatal ? "SMESH_CANT_ADD_HYP" : "SMESH_ADD_HYP_WRN");
109       else
110         aMsg = (isFatal ? "SMESH_CANT_RM_HYP"  : "SMESH_RM_HYP_WRN");
111
112       aMsg = QObject::tr(aMsg.toLatin1().data()).arg(aHypName) +
113         QObject::tr(QString("SMESH_HYP_%1").arg(theHypStatus).toLatin1().data());
114
115       if ( theHypStatus == SMESH::HYP_HIDDEN_ALGO ) // PAL18501
116         aMsg = aMsg.arg( GetHypothesisData(theHyp->GetName())->Dim[0] );
117
118       SUIT_MessageBox::warning(SMESHGUI::desktop(),
119                                QObject::tr("SMESH_WRN_WARNING"),
120                                aMsg);
121     }
122   }
123
124
125   void InitAvailableHypotheses()
126   {
127     SUIT_OverrideCursor wc;
128     if (myHypothesesMap.empty() && myAlgorithmsMap.empty()) {
129       // Resource manager
130       SUIT_ResourceMgr* resMgr = SMESHGUI::resourceMgr();
131       if (!resMgr) return;
132
133       // Find name of a resource XML file ("SMESH_Meshers.xml");
134       QString HypsXml;
135       char* cenv = getenv("SMESH_MeshersList");
136       if (cenv)
137         HypsXml.sprintf("%s", cenv);
138
139       QStringList HypsXmlList = HypsXml.split(":", QString::SkipEmptyParts);
140       if (HypsXmlList.count() == 0)
141         {
142           SUIT_MessageBox::critical(SMESHGUI::desktop(),
143                                     QObject::tr("SMESH_WRN_WARNING"),
144                                     QObject::tr("MESHERS_FILE_NO_VARIABLE"));
145           return;
146         }
147
148       // loop on files in HypsXml
149       QString aNoAccessFiles;
150       for (int i = 0; i < HypsXmlList.count(); i++) {
151         QString HypsXml = HypsXmlList[ i ];
152
153         // Find full path to the resource XML file
154         QString xmlFile = resMgr->path("resources", "SMESH", HypsXml + ".xml");
155         if ( xmlFile.isEmpty() ) // try PLUGIN resources
156           xmlFile = resMgr->path("resources", HypsXml, HypsXml + ".xml");
157         
158         QFile file (xmlFile);
159         if (file.exists() && file.open(QIODevice::ReadOnly)) {
160           file.close();
161
162           SMESHGUI_XmlHandler* aXmlHandler = new SMESHGUI_XmlHandler();
163           ASSERT(aXmlHandler);
164
165           QXmlInputSource source (&file);
166           QXmlSimpleReader reader;
167           reader.setContentHandler(aXmlHandler);
168           reader.setErrorHandler(aXmlHandler);
169           bool ok = reader.parse(source);
170           file.close();
171           if (ok) {
172             myHypothesesMap.insert( aXmlHandler->myHypothesesMap.begin(),
173                                     aXmlHandler->myHypothesesMap.end() );
174             myAlgorithmsMap.insert( aXmlHandler->myAlgorithmsMap.begin(),
175                                     aXmlHandler->myAlgorithmsMap.end() );
176             myListOfHypothesesSets.splice( myListOfHypothesesSets.begin(),
177                                            aXmlHandler->myListOfHypothesesSets );
178           }
179           else {
180             SUIT_MessageBox::critical(SMESHGUI::desktop(),
181                                       QObject::tr("INF_PARSE_ERROR"),
182                                       QObject::tr(aXmlHandler->errorProtocol().toLatin1().data()));
183           }
184         }
185         else {
186           if (aNoAccessFiles.isEmpty())
187             aNoAccessFiles = xmlFile;
188           else
189             aNoAccessFiles += ", " + xmlFile;
190         }
191       } // end loop
192
193
194       if (!aNoAccessFiles.isEmpty()) {
195         QString aMess = QObject::tr("MESHERS_FILE_CANT_OPEN") + " " + aNoAccessFiles + "\n";
196         aMess += QObject::tr("MESHERS_FILE_CHECK_VARIABLE");
197         wc.suspend();
198         SUIT_MessageBox::warning(SMESHGUI::desktop(),
199                                  QObject::tr("SMESH_WRN_WARNING"),
200                                  aMess);
201         wc.resume();
202       }
203     }
204   }
205
206
207   QStringList GetAvailableHypotheses( const bool isAlgo, 
208                                       const int theDim,                          
209                                       const bool isAux,
210                                       const bool isNeedGeometry)
211   {
212     QStringList aHypList;
213
214     // Init list of available hypotheses, if needed
215     InitAvailableHypotheses();
216     bool checkGeometry = !isNeedGeometry;
217     // fill list of hypotheses/algorithms
218     THypothesisDataMap* pMap = isAlgo ? &myAlgorithmsMap : &myHypothesesMap;
219     THypothesisDataMap::iterator anIter;
220     for ( anIter = pMap->begin(); anIter != pMap->end(); anIter++ )
221       {
222         HypothesisData* aData = (*anIter).second;
223         if ( ( theDim < 0 || aData->Dim.contains( theDim ) ) && aData->IsAux == isAux)
224           if (checkGeometry){
225             if (aData->IsNeedGeometry == isNeedGeometry)
226               aHypList.append(((*anIter).first).c_str());
227           }
228           else
229             aHypList.append(((*anIter).first).c_str());
230       }
231     return aHypList;
232   }
233
234
235   QStringList GetHypothesesSets()
236   {
237     QStringList aSetNameList;
238
239     // Init list of available hypotheses, if needed
240     InitAvailableHypotheses();
241
242     list<HypothesesSet*>::iterator hypoSet = myListOfHypothesesSets.begin();
243     for ( ; hypoSet != myListOfHypothesesSets.end(); ++hypoSet )
244       {
245         HypothesesSet* aSet = *hypoSet;
246         if ( aSet && aSet->AlgoList.count() ) {
247           aSetNameList.append( aSet->HypoSetName );
248         }
249       }
250
251     return aSetNameList;
252   }
253
254   HypothesesSet* GetHypothesesSet(const QString& theSetName)
255   {
256     list<HypothesesSet*>::iterator hypoSet = myListOfHypothesesSets.begin();
257     for ( ; hypoSet != myListOfHypothesesSets.end(); ++hypoSet )
258       {
259         HypothesesSet* aSet = *hypoSet;
260         if ( aSet && aSet->HypoSetName == theSetName )
261           return aSet;
262       }
263     return 0;
264   }
265
266   HypothesisData* GetHypothesisData (const QString& aHypType)
267   {
268     HypothesisData* aHypData = 0;
269
270     // Init list of available hypotheses, if needed
271     InitAvailableHypotheses();
272
273     THypothesisDataMap::iterator type_data = myHypothesesMap.find(aHypType.toLatin1().data());
274     if (type_data != myHypothesesMap.end()) {
275       aHypData = type_data->second;
276     }
277     else {
278       type_data = myAlgorithmsMap.find(aHypType.toLatin1().data());
279       if (type_data != myAlgorithmsMap.end())
280         aHypData = type_data->second;
281     }
282     return aHypData;
283   }
284
285   bool IsAvailableHypothesis(const HypothesisData* algoData,
286                              const QString&        hypType,
287                              bool&                 isAuxiliary)
288   {
289     isAuxiliary = false;
290     if ( !algoData )
291       return false;
292     if ( algoData->NeededHypos.contains( hypType ))
293       return true;
294     if ( algoData->OptionalHypos.contains( hypType)) {
295       isAuxiliary = true;
296       return true;
297     }
298     return false;
299   }
300
301   bool IsCompatibleAlgorithm(const HypothesisData* algo1Data,
302                              const HypothesisData* algo2Data)
303   {
304     if ( !algo1Data || !algo2Data )
305       return false;
306     const HypothesisData* algoIn = algo1Data, *algoMain = algo2Data;
307     if ( algoIn->Dim.first() > algoMain->Dim.first() ) {
308       algoIn = algo2Data; algoMain = algo1Data;
309     }
310     // look for any output type of algoIn between input types of algoMain
311     QStringList::const_iterator inElemType = algoIn->OutputTypes.begin();
312     for ( ; inElemType != algoIn->OutputTypes.end(); ++inElemType )
313       if ( algoMain->InputTypes.contains( *inElemType ))
314         return true;
315     return false;
316   }
317
318   SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator(const QString& aHypType)
319   {
320     if(MYDEBUG) MESSAGE("Get HypothesisCreator for " << aHypType.toLatin1().data());
321
322     SMESHGUI_GenericHypothesisCreator* aCreator = 0;
323
324     // check, if creator for this hypothesis type already exists
325     if (myHypCreatorMap.find(aHypType.toLatin1().data()) != myHypCreatorMap.end()) {
326       aCreator = myHypCreatorMap[aHypType.toLatin1().data()];
327     }
328     else {
329       // 1. Init list of available hypotheses, if needed
330       InitAvailableHypotheses();
331
332       // 2. Get names of plugin libraries
333       HypothesisData* aHypData = GetHypothesisData(aHypType);
334       if (!aHypData) 
335         return aCreator;
336       QString aClientLibName = aHypData->ClientLibName;
337       QString aServerLibName = aHypData->ServerLibName;
338
339       // 3. Load Client Plugin Library
340       try {
341         // load plugin library
342         if(MYDEBUG) MESSAGE("Loading client meshers plugin library ...");
343         LibHandle libHandle = LoadLib( aClientLibName.toLatin1().data() );
344         if (!libHandle) {
345           // report any error, if occured
346           if ( MYDEBUG )
347             {
348 #ifdef WIN32
349               const char* anError = "Can't load client meshers plugin library";
350 #else
351               const char* anError = dlerror();    
352 #endif
353               MESSAGE(anError);
354             }
355         }
356         else {
357           // get method, returning hypothesis creator
358           if(MYDEBUG) MESSAGE("Find GetHypothesisCreator() method ...");
359           typedef SMESHGUI_GenericHypothesisCreator* (*GetHypothesisCreator) \
360             ( const QString& );
361           GetHypothesisCreator procHandle =
362             (GetHypothesisCreator)GetProc(libHandle, "GetHypothesisCreator");
363           if (!procHandle) {
364             if(MYDEBUG) MESSAGE("bad hypothesis client plugin library");
365             UnLoadLib(libHandle);
366           }
367           else {
368             // get hypothesis creator
369             if(MYDEBUG) MESSAGE("Get Hypothesis Creator for " << aHypType.toLatin1().data());
370             aCreator = procHandle( aHypType );
371             if (!aCreator) {
372               if(MYDEBUG) MESSAGE("no such a hypothesis in this plugin");
373             }
374             else {
375               // map hypothesis creator to a hypothesis name
376               myHypCreatorMap[aHypType.toLatin1().data()] = aCreator;
377             }
378           }
379         }
380       }
381       catch (const SALOME::SALOME_Exception& S_ex) {
382         SalomeApp_Tools::QtCatchCorbaException(S_ex);
383       }
384     }
385
386     return aCreator;
387   }
388
389
390   SMESH::SMESH_Hypothesis_ptr CreateHypothesis(const QString& aHypType,
391                                                const QString& aHypName,
392                                                const bool isAlgo)
393   {
394     if(MYDEBUG) MESSAGE("Create " << aHypType.toLatin1().data() << 
395                         " with name " << aHypName.toLatin1().data());
396     HypothesisData* aHypData = GetHypothesisData(aHypType);
397     QString aServLib = aHypData->ServerLibName;
398     try {
399       SMESH::SMESH_Hypothesis_var aHypothesis;
400       aHypothesis = SMESHGUI::GetSMESHGen()->CreateHypothesis(aHypType.toLatin1().data(),
401                                                               aServLib.toLatin1().data());
402       if (!aHypothesis->_is_nil()) {
403         _PTR(SObject) aHypSObject = SMESH::FindSObject(aHypothesis.in());
404         if (aHypSObject) {
405           if (!aHypName.isEmpty())
406             SMESH::SetName(aHypSObject, aHypName);
407           SMESHGUI::GetSMESHGUI()->updateObjBrowser();
408           return aHypothesis._retn();
409         }
410       }
411     } catch (const SALOME::SALOME_Exception & S_ex) {
412       SalomeApp_Tools::QtCatchCorbaException(S_ex);
413     }
414
415     return SMESH::SMESH_Hypothesis::_nil();
416   }
417
418
419   bool AddHypothesisOnMesh (SMESH::SMESH_Mesh_ptr aMesh, SMESH::SMESH_Hypothesis_ptr aHyp)
420   {
421     if(MYDEBUG) MESSAGE ("SMESHGUI::AddHypothesisOnMesh");
422     int res = SMESH::HYP_UNKNOWN_FATAL;
423     SUIT_OverrideCursor wc;
424
425     if (!aMesh->_is_nil()) {
426       _PTR(SObject) SM = SMESH::FindSObject(aMesh);
427       GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SM);
428       try {
429         res = aMesh->AddHypothesis(aShapeObject, aHyp);
430         if (res < SMESH::HYP_UNKNOWN_FATAL) {
431           _PTR(SObject) aSH = SMESH::FindSObject(aHyp);
432           if (SM && aSH) {
433             SMESH::ModifiedMesh(SM, false, aMesh->NbNodes()==0);
434           }
435         }
436         if (res > SMESH::HYP_OK) {
437           wc.suspend();
438           processHypothesisStatus(res, aHyp, true);
439           wc.resume();
440         }
441       }
442       catch(const SALOME::SALOME_Exception& S_ex) {
443         wc.suspend();
444         SalomeApp_Tools::QtCatchCorbaException(S_ex);
445         res = SMESH::HYP_UNKNOWN_FATAL;
446       }
447     }
448     return res < SMESH::HYP_UNKNOWN_FATAL;
449   }
450
451
452   bool AddHypothesisOnSubMesh (SMESH::SMESH_subMesh_ptr aSubMesh, SMESH::SMESH_Hypothesis_ptr aHyp)
453   {
454     if(MYDEBUG) MESSAGE("SMESHGUI::AddHypothesisOnSubMesh() ");
455     int res = SMESH::HYP_UNKNOWN_FATAL;
456     SUIT_OverrideCursor wc;
457
458     if (!aSubMesh->_is_nil() && ! aHyp->_is_nil()) {
459       try {
460         SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
461         _PTR(SObject) SsubM = SMESH::FindSObject(aSubMesh);
462         GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SsubM);
463         if (!aMesh->_is_nil() && SsubM && !aShapeObject->_is_nil()) {
464           res = aMesh->AddHypothesis(aShapeObject, aHyp);
465           if (res < SMESH::HYP_UNKNOWN_FATAL)  {
466             _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
467             if (meshSO)
468               SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);
469           }
470           if (res > SMESH::HYP_OK) {
471             wc.suspend();
472             processHypothesisStatus(res, aHyp, true);
473             wc.resume();
474           }
475         }
476         else {
477           SCRUTE(aHyp->_is_nil());
478           SCRUTE(aMesh->_is_nil());
479           SCRUTE(!SsubM);
480           SCRUTE(aShapeObject->_is_nil());
481         }
482       }
483       catch(const SALOME::SALOME_Exception& S_ex) {
484         wc.suspend();
485         SalomeApp_Tools::QtCatchCorbaException(S_ex);
486         res = SMESH::HYP_UNKNOWN_FATAL;
487       }
488     }
489     else {
490       SCRUTE(aSubMesh->_is_nil());
491       SCRUTE(aHyp->_is_nil());
492     }
493     return res < SMESH::HYP_UNKNOWN_FATAL;
494   }
495
496   bool RemoveHypothesisOrAlgorithmOnMesh (const Handle(SALOME_InteractiveObject)& IObject)
497   {
498     int res = SMESH::HYP_UNKNOWN_FATAL;
499     SUIT_OverrideCursor wc;
500
501     try {
502       _PTR(Study) aStudy = GetActiveStudyDocument();
503       _PTR(SObject) aHypObj = aStudy->FindObjectID( IObject->getEntry() );
504       if( aHypObj )
505         {
506           _PTR(SObject) MorSM = SMESH::GetMeshOrSubmesh( aHypObj );
507           _PTR(SObject) aRealHypo;
508           if( aHypObj->ReferencedObject( aRealHypo ) )
509             {
510               SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aRealHypo ) );
511               RemoveHypothesisOrAlgorithmOnMesh( MorSM, hypo );
512             }
513           else
514             {
515               SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aHypObj ) );
516               SObjectList meshList = GetMeshesUsingAlgoOrHypothesis( hypo );
517               for( int i = 0; i < meshList.size(); i++ )
518                 RemoveHypothesisOrAlgorithmOnMesh( meshList[ i ], hypo );
519             }
520         }
521     }
522     catch(const SALOME::SALOME_Exception& S_ex)
523       {
524         wc.suspend();
525         SalomeApp_Tools::QtCatchCorbaException(S_ex);
526         res = SMESH::HYP_UNKNOWN_FATAL;
527       }
528     return res < SMESH::HYP_UNKNOWN_FATAL;
529   }
530
531   bool RemoveHypothesisOrAlgorithmOnMesh (_PTR(SObject) MorSM,
532                                           SMESH::SMESH_Hypothesis_ptr anHyp)
533   {
534     SALOMEDS::GenericAttribute_var anAttr;
535     SALOMEDS::AttributeIOR_var anIOR;
536     int res = SMESH::HYP_UNKNOWN_FATAL;
537     SUIT_OverrideCursor wc;
538
539     if (MorSM) {
540       try {
541         GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(MorSM);
542         SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>(MorSM);
543         SMESH::SMESH_subMesh_var aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>(MorSM);
544         
545         if (!aSubMesh->_is_nil())
546           aMesh = aSubMesh->GetFather();
547         
548         if (!aMesh->_is_nil()) {    
549           if (aMesh->HasShapeToMesh() && !aShapeObject->_is_nil()) {
550             res = aMesh->RemoveHypothesis(aShapeObject, anHyp);
551             if (res < SMESH::HYP_UNKNOWN_FATAL) {
552               _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
553               if (meshSO)
554                 SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);
555             }
556             
557           }
558           else if(!aMesh->HasShapeToMesh()){
559             res = aMesh->RemoveHypothesis(aShapeObject, anHyp);
560             if (res < SMESH::HYP_UNKNOWN_FATAL) {
561               _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
562               if (meshSO)
563                 SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);              
564             }
565           }
566           if (res > SMESH::HYP_OK) {
567             wc.suspend();
568             processHypothesisStatus(res, anHyp, false);
569             wc.resume();
570           }
571         }
572       } catch(const SALOME::SALOME_Exception& S_ex) {
573         wc.suspend();
574         SalomeApp_Tools::QtCatchCorbaException(S_ex);
575         res = SMESH::HYP_UNKNOWN_FATAL;
576       }
577     }
578     return res < SMESH::HYP_UNKNOWN_FATAL;
579   }
580
581   SObjectList GetMeshesUsingAlgoOrHypothesis(SMESH::SMESH_Hypothesis_ptr AlgoOrHyp)
582   {
583     SObjectList listSOmesh;
584     listSOmesh.resize(0);
585
586     unsigned int index = 0;
587     if (!AlgoOrHyp->_is_nil()) {
588       _PTR(SObject) SO_Hypothesis = SMESH::FindSObject(AlgoOrHyp);
589       if (SO_Hypothesis) {
590         SObjectList listSO =
591           SMESHGUI::activeStudy()->studyDS()->FindDependances(SO_Hypothesis);
592
593         if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency number ="<<listSO.size());
594         for (unsigned int i = 0; i < listSO.size(); i++) {
595           _PTR(SObject) SO = listSO[i];
596           if (SO) {
597             _PTR(SObject) aFather = SO->GetFather();
598             if (aFather) {
599               _PTR(SObject) SOfatherFather = aFather->GetFather();
600               if (SOfatherFather) {
601                 if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency added to list");
602                 index++;
603                 listSOmesh.resize(index);
604                 listSOmesh[index - 1] = SOfatherFather;
605               }
606             }
607           }
608         }
609       }
610     }
611     if (MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): completed");
612     return listSOmesh;
613   }
614
615 #define CASE2MESSAGE(enum) case SMESH::enum: msg = QObject::tr( "STATE_" #enum ); break;
616   QString GetMessageOnAlgoStateErrors(const algo_error_array& errors)
617   {
618     QString resMsg; // PAL14861 = QObject::tr("SMESH_WRN_MISSING_PARAMETERS") + ":\n";
619     for ( int i = 0; i < errors.length(); ++i ) {
620       const SMESH::AlgoStateError & error = errors[ i ];
621       const bool hasAlgo = ( strlen( error.algoName ) != 0 );
622       QString msg;
623       if ( !hasAlgo )
624         msg = QObject::tr( "STATE_ALGO_MISSING" );
625       else 
626         switch( error.state ) {
627           CASE2MESSAGE( HYP_MISSING );
628           CASE2MESSAGE( HYP_NOTCONFORM );
629           CASE2MESSAGE( HYP_BAD_PARAMETER );
630           CASE2MESSAGE( HYP_BAD_GEOMETRY );
631         default: continue;
632         }
633       // apply args to message:
634       // %1 - algo name
635       if ( hasAlgo )
636         msg = msg.arg( error.algoName.in() );
637       // %2 - dimension
638       msg = msg.arg( error.algoDim );
639       // %3 - global/local
640       msg = msg.arg( QObject::tr( error.isGlobalAlgo ? "GLOBAL_ALGO" : "LOCAL_ALGO" ));
641       // %4 - hypothesis dim == algoDim
642       msg = msg.arg( error.algoDim );
643
644       if ( i ) resMsg += ";\n";
645       resMsg += msg;
646     }
647     return resMsg;
648   }
649 } // end of namespace SMESH