Salome HOME
BUG: impossible to import a med file of size more than MAX_INT (~2.1 Gb)
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_HypothesesUtils.cxx
index 5f3500230d4617ab7c32b62fecc2828bdc845f3c..fc1f8c5e2b84acaffaf20d423ed597131efadbb3 100644 (file)
@@ -1,24 +1,25 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 // SMESH SMESHGUI : GUI for SMESH component
 // File   : SMESHGUI_HypothesesUtils.cxx
 // Author : Julia DOROVSKIKH, Open CASCADE S.A.S.
 
 // Qt includes
 #include <QMap>
+#include <QDir>
 //#include <QList>
 
+
 // Other includes
-#ifdef WNT
+#ifdef WIN32
 #include <windows.h>
 #else
 #include <dlfcn.h>
 #endif
 
-#ifdef WNT
+#ifdef WIN32
 #define LibHandle HMODULE
 #define LoadLib( name ) LoadLibrary( name )
 #define GetProc GetProcAddress
@@ -78,52 +81,101 @@ static int MYDEBUG = 0;
 
 namespace SMESH
 {
-  typedef QMap<QString,HypothesisData*> THypothesisDataMap;
+  typedef IMap<QString,HypothesisData*> THypothesisDataMap;
   THypothesisDataMap myHypothesesMap;
   THypothesisDataMap myAlgorithmsMap;
 
-  typedef QMap<QString,SMESHGUI_GenericHypothesisCreator*> THypCreatorMap;
-  THypCreatorMap myHypCreatorMap;
+  // BUG 0020378
+  //typedef QMap<QString,SMESHGUI_GenericHypothesisCreator*> THypCreatorMap;
+  //THypCreatorMap myHypCreatorMap;
 
   QList<HypothesesSet*> myListOfHypothesesSets;
 
-  void processHypothesisStatus(const int theHypStatus,
-                              SMESH::SMESH_Hypothesis_ptr theHyp,
-                              const bool theIsAddition)
+  void processHypothesisStatus(const int                   theHypStatus,
+                               SMESH::SMESH_Hypothesis_ptr theHyp,
+                               const bool                  theIsAddition,
+                               const char*                 theError = 0)
   {
     if (theHypStatus > SMESH::HYP_OK) {
       // get Hyp name
       QString aHypName ("NULL Hypothesis");
       if (!CORBA::is_nil(theHyp)) {
-       _PTR(SObject) Shyp = SMESH::FindSObject(theHyp);
-       if (Shyp)
-         // name in study
-         aHypName = Shyp->GetName().c_str();
-       else
-         // label in xml file
-         aHypName = GetHypothesisData(theHyp->GetName())->Label;
+        _PTR(SObject) Shyp = SMESH::FindSObject(theHyp);
+        if (Shyp) {
+          // name in study
+          aHypName = Shyp->GetName().c_str();
+        }
+        else {
+          // label in xml file
+          CORBA::String_var hypType = theHyp->GetName();
+          aHypName = GetHypothesisData( hypType.in() )->Label;
+        }
       }
 
       // message
       bool isFatal = (theHypStatus >= SMESH::HYP_UNKNOWN_FATAL);
       QString aMsg;
       if (theIsAddition)
-       aMsg = (isFatal ? "SMESH_CANT_ADD_HYP" : "SMESH_ADD_HYP_WRN");
+        aMsg = (isFatal ? "SMESH_CANT_ADD_HYP" : "SMESH_ADD_HYP_WRN");
       else
-       aMsg = (isFatal ? "SMESH_CANT_RM_HYP"  : "SMESH_RM_HYP_WRN");
+        aMsg = (isFatal ? "SMESH_CANT_RM_HYP"  : "SMESH_RM_HYP_WRN");
 
-      aMsg = QObject::tr(aMsg.toLatin1().data()).arg(aHypName) +
-       QObject::tr(QString("SMESH_HYP_%1").arg(theHypStatus).toLatin1().data());
+      aMsg = QObject::tr(aMsg.toLatin1().data()).arg(aHypName);
 
-      if ( theHypStatus == SMESH::HYP_HIDDEN_ALGO ) // PAL18501
-        aMsg = aMsg.arg( GetHypothesisData(theHyp->GetName())->Dim[0] );
+      if ( theError && theError[0] )
+      {
+        aMsg += theError;
+      }
+      else
+      {
+        aMsg += QObject::tr(QString("SMESH_HYP_%1").arg(theHypStatus).toLatin1().data());
 
+        if ( theHypStatus == SMESH::HYP_HIDDEN_ALGO ) { // PAL18501
+          CORBA::String_var hypType = theHyp->GetName();
+          if ( HypothesisData* hd = GetHypothesisData( hypType.in() ))
+            aMsg = aMsg.arg( hd->Dim[0] );
+        }
+      }
       SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                              QObject::tr("SMESH_WRN_WARNING"),
-                              aMsg);
+                               QObject::tr("SMESH_WRN_WARNING"),
+                               aMsg);
     }
   }
 
+  //================================================================================
+  /*!
+   * \brief Prepends dimension and appends '[custom]' to the name of hypothesis set
+   */
+  //================================================================================
+
+  static QString mangledHypoSetName(HypothesesSet* hypSet)
+  {
+    QString name = hypSet->name();
+
+    // prepend 'xD: '
+    int dim = hypSet->maxDim();
+    if ( dim > -1 )
+      name = QString("%1D: %2").arg(dim).arg(name);
+
+    // custom
+    if ( hypSet->getIsCustom() )
+      name = QString("%1 [custom]").arg(name);
+
+    return name;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Removes dimension and '[custom]' from the name of hypothesis set
+   */
+  //================================================================================
+
+  static QString demangledHypoSetName(QString name)
+  {
+    name.remove(QRegExp("[0-3]D: "));
+    name.remove(" [custom]");
+    return name;
+  }
 
   void InitAvailableHypotheses()
   {
@@ -137,135 +189,166 @@ namespace SMESH
       QString HypsXml;
       char* cenv = getenv("SMESH_MeshersList");
       if (cenv)
-       HypsXml.sprintf("%s", cenv);
+        HypsXml.sprintf("%s", cenv);
 
       QStringList HypsXmlList = HypsXml.split(":", QString::SkipEmptyParts);
       if (HypsXmlList.count() == 0) {
-       SUIT_MessageBox::critical(SMESHGUI::desktop(),
-                                 QObject::tr("SMESH_WRN_WARNING"),
-                                 QObject::tr("MESHERS_FILE_NO_VARIABLE"));
-       return;
+        SUIT_MessageBox::critical(SMESHGUI::desktop(),
+                                  QObject::tr("SMESH_WRN_WARNING"),
+                                  QObject::tr("MESHERS_FILE_NO_VARIABLE"));
+        return;
       }
-
-      // loop on files in HypsXml
-      QString aNoAccessFiles;
+      // get full names of xml files from HypsXmlList
+      QStringList xmlFiles;
+      xmlFiles.append( QDir::home().filePath("CustomMeshers.xml")); // may be inexistent
       for (int i = 0; i < HypsXmlList.count(); i++) {
-       QString HypsXml = HypsXmlList[ i ];
+        QString HypsXml = HypsXmlList[ i ];
 
-       // Find full path to the resource XML file
-       QString xmlFile = resMgr->path("resources", "SMESH", HypsXml + ".xml");
+        // Find full path to the resource XML file
+        QString xmlFile = resMgr->path("resources", "SMESH", HypsXml + ".xml");
         if ( xmlFile.isEmpty() ) // try PLUGIN resources
           xmlFile = resMgr->path("resources", HypsXml, HypsXml + ".xml");
-        
-       QFile file (xmlFile);
-       if (file.exists() && file.open(QIODevice::ReadOnly)) {
-         file.close();
-
-         SMESHGUI_XmlHandler* aXmlHandler = new SMESHGUI_XmlHandler();
-         ASSERT(aXmlHandler);
-
-         QXmlInputSource source (&file);
-         QXmlSimpleReader reader;
-         reader.setContentHandler(aXmlHandler);
-         reader.setErrorHandler(aXmlHandler);
-         bool ok = reader.parse(source);
-         file.close();
-         if (ok) {
-           myHypothesesMap.unite( aXmlHandler->myHypothesesMap );
-            myAlgorithmsMap.unite( aXmlHandler->myAlgorithmsMap );
-           QList<HypothesesSet*>::iterator it, pos = myListOfHypothesesSets.begin();
-           for ( it = aXmlHandler->myListOfHypothesesSets.begin(); 
-                 it != aXmlHandler->myListOfHypothesesSets.end();
-                 ++it ) {
-             myListOfHypothesesSets.insert( pos, *it );
-           }
-         }
-         else {
-           SUIT_MessageBox::critical(SMESHGUI::desktop(),
-                                     QObject::tr("INF_PARSE_ERROR"),
-                                     QObject::tr(aXmlHandler->errorProtocol().toLatin1().data()));
-         }
-       }
-       else {
-         if (aNoAccessFiles.isEmpty())
-           aNoAccessFiles = xmlFile;
-         else
-           aNoAccessFiles += ", " + xmlFile;
-       }
-      } // end loop
+        if ( !xmlFile.isEmpty() )
+          xmlFiles.append( xmlFile );
+      }
+
+      // loop on xmlFiles
+      QString aNoAccessFiles;
+      for (int i = 0; i < xmlFiles.count(); i++)
+      {
+        QString xmlFile = xmlFiles[ i ];
+        QFile file (xmlFile);
+        if (file.exists() && file.open(QIODevice::ReadOnly))
+        {
+          file.close();
+
+          SMESHGUI_XmlHandler* aXmlHandler = new SMESHGUI_XmlHandler();
+          ASSERT(aXmlHandler);
+
+          QXmlInputSource source (&file);
+          QXmlSimpleReader reader;
+          reader.setContentHandler(aXmlHandler);
+          reader.setErrorHandler(aXmlHandler);
+          bool ok = reader.parse(source);
+          file.close();
+          if (ok) {
+
+            THypothesisDataMap::ConstIterator it1 = aXmlHandler->myHypothesesMap.begin();
+
+            for( ;it1 != aXmlHandler->myHypothesesMap.end(); it1++)
+              myHypothesesMap.insert( it1.key(), it1.value() );
+
+            it1 = aXmlHandler->myAlgorithmsMap.begin();
+            for( ;it1 != aXmlHandler->myAlgorithmsMap.end(); it1++)
+              myAlgorithmsMap.insert( it1.key(), it1.value() );
+
+            QList<HypothesesSet*>::iterator it;
+            for ( it = aXmlHandler->myListOfHypothesesSets.begin();
+                  it != aXmlHandler->myListOfHypothesesSets.end();
+                  ++it )
+            {
+              (*it)->setIsCustom( i == 0 );
+              myListOfHypothesesSets.append( *it );
+            }
+          }
+          else {
+            SUIT_MessageBox::critical(SMESHGUI::desktop(),
+                                      QObject::tr("INF_PARSE_ERROR"),
+                                      QObject::tr(aXmlHandler->errorProtocol().toLatin1().data()));
+          }
+          delete aXmlHandler;
+        }
+        else if ( i > 0 ) { // 1st is ~/CustomMeshers.xml
+          if (aNoAccessFiles.isEmpty())
+            aNoAccessFiles = xmlFile;
+          else
+            aNoAccessFiles += ", " + xmlFile;
+        }
+      } // end loop on xmlFiles
 
 
       if (!aNoAccessFiles.isEmpty()) {
-       QString aMess = QObject::tr("MESHERS_FILE_CANT_OPEN") + " " + aNoAccessFiles + "\n";
-       aMess += QObject::tr("MESHERS_FILE_CHECK_VARIABLE");
-       wc.suspend();
-       SUIT_MessageBox::warning(SMESHGUI::desktop(),
-                                QObject::tr("SMESH_WRN_WARNING"),
-                                aMess);
-       wc.resume();
+        QString aMess = QObject::tr("MESHERS_FILE_CANT_OPEN") + " " + aNoAccessFiles + "\n";
+        aMess += QObject::tr("MESHERS_FILE_CHECK_VARIABLE");
+        wc.suspend();
+        SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                 QObject::tr("SMESH_WRN_WARNING"),
+                                 aMess);
+        wc.resume();
       }
     }
   }
 
 
-  QStringList GetAvailableHypotheses( const bool isAlgo, 
-                                      const int theDim,                          
+  QStringList GetAvailableHypotheses( const bool isAlgo,
+                                      const int  theDim,
                                       const bool isAux,
-                                      const bool isNeedGeometry)
+                                      const bool isNeedGeometry,
+                                      const bool isSubMesh)
   {
     QStringList aHypList;
 
     // Init list of available hypotheses, if needed
     InitAvailableHypotheses();
     bool checkGeometry = ( !isNeedGeometry && isAlgo );
+    const char* context = isSubMesh ? "LOCAL" : "GLOBAL";
     // fill list of hypotheses/algorithms
     THypothesisDataMap& pMap = isAlgo ? myAlgorithmsMap : myHypothesesMap;
-    THypothesisDataMap::iterator anIter;
-    for ( anIter = pMap.begin(); anIter != pMap.end(); anIter++ ) {
+    THypothesisDataMap::ConstIterator anIter;
+    for ( anIter = pMap.begin(); anIter != pMap.end(); anIter++ )
+    {
       HypothesisData* aData = anIter.value();
-      if ( ( theDim < 0 || aData->Dim.contains( theDim ) ) && aData->IsAux == isAux) {
-       if (checkGeometry) {
-         if (aData->IsNeedGeometry == isNeedGeometry)
-           aHypList.append(anIter.key());
-       }
-       else {
-         aHypList.append(anIter.key());
-       }
+      if (( aData && !aData->Label.isEmpty() ) &&
+          ( theDim < 0              || aData->Dim.contains( theDim )) &&
+          ( isAlgo                  || aData->IsAuxOrNeedHyp == isAux ) &&
+          ( aData->Context == "ANY" || aData->Context == context ) &&
+          ( !checkGeometry          || aData->IsNeedGeometry == isNeedGeometry ))
+      {
+        aHypList.append(anIter.key());
       }
     }
     return aHypList;
   }
 
 
-  QStringList GetHypothesesSets()
+  QStringList GetHypothesesSets(int maxDim)
   {
     QStringList aSetNameList;
 
     // Init list of available hypotheses, if needed
     InitAvailableHypotheses();
-
     QList<HypothesesSet*>::iterator hypoSet;
-    for ( hypoSet  = myListOfHypothesesSets.begin(); 
-         hypoSet != myListOfHypothesesSets.end();
-         ++hypoSet ) {
+    for ( hypoSet  = myListOfHypothesesSets.begin();
+        hypoSet != myListOfHypothesesSets.end();
+        ++hypoSet ) {
       HypothesesSet* aSet = *hypoSet;
-      if ( aSet && aSet->AlgoList.count() ) {
-       aSetNameList.append( aSet->HypoSetName );
+      if ( aSet && ( aSet->count( true ) || aSet->count( false )) &&
+          aSet->maxDim() <= maxDim)
+      {
+        aSetNameList.append( mangledHypoSetName( aSet ));
       }
     }
-    
-    return aSetNameList;
+    aSetNameList.removeDuplicates();
+    aSetNameList.sort();
+
+    //  reverse order of aSetNameList
+    QStringList reversedNames;
+    for ( int i = 0; i < aSetNameList.count(); ++i )
+      reversedNames.prepend( aSetNameList[i] );
+
+    return reversedNames;
   }
 
   HypothesesSet* GetHypothesesSet(const QString& theSetName)
   {
+    QString name = demangledHypoSetName( theSetName );
     QList<HypothesesSet*>::iterator hypoSet;
-    for ( hypoSet  = myListOfHypothesesSets.begin(); 
-         hypoSet != myListOfHypothesesSets.end();
-         ++hypoSet ) {
+    for ( hypoSet  = myListOfHypothesesSets.begin();
+          hypoSet != myListOfHypothesesSets.end();
+          ++hypoSet ) {
       HypothesesSet* aSet = *hypoSet;
-      if ( aSet && aSet->HypoSetName == theSetName )
-       return aSet;
+      if ( aSet && aSet->name() == name )
+        return aSet;
     }
     return 0;
   }
@@ -277,10 +360,10 @@ namespace SMESH
     // Init list of available hypotheses, if needed
     InitAvailableHypotheses();
 
-    if (myHypothesesMap.find(aHypType) != myHypothesesMap.end()) {
+    if (myHypothesesMap.contains(aHypType)) {
       aHypData = myHypothesesMap[aHypType];
     }
-    else if (myAlgorithmsMap.find(aHypType) != myAlgorithmsMap.end()) {
+    else if (myAlgorithmsMap.contains(aHypType)) {
       aHypData = myAlgorithmsMap[aHypType];
     }
     return aHypData;
@@ -293,9 +376,9 @@ namespace SMESH
     isAuxiliary = false;
     if ( !algoData )
       return false;
-    if ( algoData->NeededHypos.contains( hypType ))
+    if ( algoData->BasicHypos.contains( hypType ))
       return true;
-    if ( algoData->OptionalHypos.contains( hypType)) {
+    if ( algoData->OptionalHypos.contains( hypType )) {
       isAuxiliary = true;
       return true;
     }
@@ -326,63 +409,73 @@ namespace SMESH
     SMESHGUI_GenericHypothesisCreator* aCreator = 0;
 
     // check, if creator for this hypothesis type already exists
-    if (myHypCreatorMap.find(aHypType) != myHypCreatorMap.end()) {
-      aCreator = myHypCreatorMap[aHypType];
-    }
-    else {
+    // BUG 0020378
+    //if (myHypCreatorMap.find(aHypType) != myHypCreatorMap.end()) {
+    //  aCreator = myHypCreatorMap[aHypType];
+    //}
+    //else
+    {
       // 1. Init list of available hypotheses, if needed
       InitAvailableHypotheses();
 
       // 2. Get names of plugin libraries
       HypothesisData* aHypData = GetHypothesisData(aHypType);
-      if (!aHypData) 
+      if (!aHypData)
         return aCreator;
+
       QString aClientLibName = aHypData->ClientLibName;
       QString aServerLibName = aHypData->ServerLibName;
 
       // 3. Load Client Plugin Library
       try {
-       // load plugin library
-       if(MYDEBUG) MESSAGE("Loading client meshers plugin library ...");
-       LibHandle libHandle = LoadLib( aClientLibName.toLatin1().data() );
-       if (!libHandle) {
-         // report any error, if occured
-         if ( MYDEBUG ) {
+        // load plugin library
+        if(MYDEBUG) MESSAGE("Loading client meshers plugin library ...");
+        LibHandle libHandle = LoadLib( aClientLibName.toLatin1().data() );
+        if (!libHandle) {
+          // report any error, if occured
+          {
 #ifdef WIN32
-           const char* anError = "Can't load client meshers plugin library";
+            const char* anError = "Can't load client meshers plugin library";
 #else
-           const char* anError = dlerror();      
+            const char* anError = dlerror();
 #endif
-           MESSAGE(anError);
-         }
-       }
-       else {
-         // get method, returning hypothesis creator
-         if(MYDEBUG) MESSAGE("Find GetHypothesisCreator() method ...");
-         typedef SMESHGUI_GenericHypothesisCreator* (*GetHypothesisCreator) \
-           ( const QString& );
-         GetHypothesisCreator procHandle =
-           (GetHypothesisCreator)GetProc(libHandle, "GetHypothesisCreator");
-         if (!procHandle) {
-           if(MYDEBUG) MESSAGE("bad hypothesis client plugin library");
-           UnLoadLib(libHandle);
-         }
-         else {
-           // get hypothesis creator
-           if(MYDEBUG) MESSAGE("Get Hypothesis Creator for " << aHypType.toLatin1().data());
-           aCreator = procHandle( aHypType );
-           if (!aCreator) {
-             if(MYDEBUG) MESSAGE("no such a hypothesis in this plugin");
-           }
-           else {
-             // map hypothesis creator to a hypothesis name
-             myHypCreatorMap[aHypType] = aCreator;
-           }
-         }
-       }
+            INFOS(anError); // always display this kind of error !
+          }
+        }
+        else {
+          // get method, returning hypothesis creator
+          if(MYDEBUG) MESSAGE("Find GetHypothesisCreator() method ...");
+          typedef SMESHGUI_GenericHypothesisCreator* (*GetHypothesisCreator) \
+            ( const QString& );
+          GetHypothesisCreator procHandle =
+            (GetHypothesisCreator)GetProc(libHandle, "GetHypothesisCreator");
+          if (!procHandle) {
+            if(MYDEBUG) MESSAGE("bad hypothesis client plugin library");
+            UnLoadLib(libHandle);
+          }
+          else {
+            // get hypothesis creator
+            if(MYDEBUG) MESSAGE("Get Hypothesis Creator for " << aHypType.toLatin1().data());
+            aCreator = procHandle( aHypType );
+            if (!aCreator) {
+              if(MYDEBUG) MESSAGE("no such a hypothesis in this plugin");
+            }
+            else {
+              // map hypothesis creator to a hypothesis name
+              // BUG 0020378
+              //myHypCreatorMap[aHypType] = aCreator;
+
+              //rnv : This dynamic property of the QObject stores the name of the plugin.
+              //      It is used to obtain plugin root dir environment variable
+              //      in the SMESHGUI_HypothesisDlg class. Plugin root dir environment
+              //      variable is used to display documentation.
+              aCreator->setProperty(SMESH::Plugin_Name(),aHypData->PluginName);
+            }
+          }
+        }
       }
       catch (const SALOME::SALOME_Exception& S_ex) {
-       SalomeApp_Tools::QtCatchCorbaException(S_ex);
+        SalomeApp_Tools::QtCatchCorbaException(S_ex);
       }
     }
 
@@ -391,25 +484,26 @@ namespace SMESH
 
 
   SMESH::SMESH_Hypothesis_ptr CreateHypothesis(const QString& aHypType,
-                                              const QString& aHypName,
-                                              const bool isAlgo)
+                                               const QString& aHypName,
+                                               const bool isAlgo)
   {
-    if(MYDEBUG) MESSAGE("Create " << aHypType.toLatin1().data() << 
-                       " with name " << aHypName.toLatin1().data());
+    if(MYDEBUG) MESSAGE("Create " << aHypType.toLatin1().data() <<
+                        " with name " << aHypName.toLatin1().data());
     HypothesisData* aHypData = GetHypothesisData(aHypType);
     QString aServLib = aHypData->ServerLibName;
     try {
       SMESH::SMESH_Hypothesis_var aHypothesis;
       aHypothesis = SMESHGUI::GetSMESHGen()->CreateHypothesis(aHypType.toLatin1().data(),
-                                                             aServLib.toLatin1().data());
+                                                              aServLib.toLatin1().data());
       if (!aHypothesis->_is_nil()) {
-       _PTR(SObject) aHypSObject = SMESH::FindSObject(aHypothesis.in());
-       if (aHypSObject) {
-         if (!aHypName.isEmpty())
-           SMESH::SetName(aHypSObject, aHypName);
-         SMESHGUI::GetSMESHGUI()->updateObjBrowser();
-         return aHypothesis._retn();
-       }
+        _PTR(SObject) aHypSObject = SMESH::FindSObject(aHypothesis.in());
+        if (aHypSObject) {
+          if (!aHypName.isEmpty())
+            SMESH::SetName(aHypSObject, aHypName);
+          SMESHGUI::Modified();
+          SMESHGUI::GetSMESHGUI()->updateObjBrowser();
+          return aHypothesis._retn();
+        }
       }
     } catch (const SALOME::SALOME_Exception & S_ex) {
       SalomeApp_Tools::QtCatchCorbaException(S_ex);
@@ -418,6 +512,21 @@ namespace SMESH
     return SMESH::SMESH_Hypothesis::_nil();
   }
 
+  bool IsApplicable(const QString&        aHypType,
+                    GEOM::GEOM_Object_ptr theGeomObject,
+                    const bool            toCheckAll)
+  {
+    if ( getenv("NO_LIMIT_ALGO_BY_SHAPE")) // allow a workaround for a case if
+      return true;                         // IsApplicable() returns false due to a bug
+
+    HypothesisData* aHypData = GetHypothesisData(aHypType);
+    QString aServLib = aHypData->ServerLibName;
+    return SMESHGUI::GetSMESHGen()->IsApplicable( aHypType.toLatin1().data(),
+                                                  aServLib.toLatin1().data(),
+                                                  theGeomObject,
+                                                  toCheckAll);
+  }
+
 
   bool AddHypothesisOnMesh (SMESH::SMESH_Mesh_ptr aMesh, SMESH::SMESH_Hypothesis_ptr aHyp)
   {
@@ -429,23 +538,24 @@ namespace SMESH
       _PTR(SObject) SM = SMESH::FindSObject(aMesh);
       GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SM);
       try {
-       res = aMesh->AddHypothesis(aShapeObject, aHyp);
-       if (res < SMESH::HYP_UNKNOWN_FATAL) {
-         _PTR(SObject) aSH = SMESH::FindSObject(aHyp);
-         if (SM && aSH) {
-           SMESH::ModifiedMesh(SM, false, aMesh->NbNodes()==0);
-         }
-       }
-       if (res > SMESH::HYP_OK) {
-         wc.suspend();
-         processHypothesisStatus(res, aHyp, true);
-         wc.resume();
-       }
+        CORBA::String_var error;
+        res = aMesh->AddHypothesis(aShapeObject, aHyp, error.out());
+        if (res < SMESH::HYP_UNKNOWN_FATAL) {
+          _PTR(SObject) aSH = SMESH::FindSObject(aHyp);
+          if (SM && aSH) {
+            SMESH::ModifiedMesh(SM, false, aMesh->NbNodes()==0);
+          }
+        }
+        if (res > SMESH::HYP_OK) {
+          wc.suspend();
+          processHypothesisStatus(res, aHyp, true, error.in() );
+          wc.resume();
+        }
       }
       catch(const SALOME::SALOME_Exception& S_ex) {
-       wc.suspend();
-       SalomeApp_Tools::QtCatchCorbaException(S_ex);
-       res = SMESH::HYP_UNKNOWN_FATAL;
+        wc.suspend();
+        SalomeApp_Tools::QtCatchCorbaException(S_ex);
+        res = SMESH::HYP_UNKNOWN_FATAL;
       }
     }
     return res < SMESH::HYP_UNKNOWN_FATAL;
@@ -460,33 +570,35 @@ namespace SMESH
 
     if (!aSubMesh->_is_nil() && ! aHyp->_is_nil()) {
       try {
-       SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
-       _PTR(SObject) SsubM = SMESH::FindSObject(aSubMesh);
-       GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SsubM);
-       if (!aMesh->_is_nil() && SsubM && !aShapeObject->_is_nil()) {
-         res = aMesh->AddHypothesis(aShapeObject, aHyp);
-         if (res < SMESH::HYP_UNKNOWN_FATAL)  {
+        SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
+        _PTR(SObject) SsubM = SMESH::FindSObject(aSubMesh);
+        GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(SsubM);
+        if (!aMesh->_is_nil() && SsubM && !aShapeObject->_is_nil())
+        {
+          CORBA::String_var error;
+          res = aMesh->AddHypothesis( aShapeObject, aHyp, error.out() );
+          if (res < SMESH::HYP_UNKNOWN_FATAL)  {
             _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
             if (meshSO)
               SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);
-         }
-         if (res > SMESH::HYP_OK) {
-           wc.suspend();
-           processHypothesisStatus(res, aHyp, true);
-           wc.resume();
-         }
-       }
-       else {
-         SCRUTE(aHyp->_is_nil());
-         SCRUTE(aMesh->_is_nil());
-         SCRUTE(!SsubM);
-         SCRUTE(aShapeObject->_is_nil());
-       }
+          }
+          if (res > SMESH::HYP_OK) {
+            wc.suspend();
+            processHypothesisStatus( res, aHyp, true, error.in() );
+            wc.resume();
+          }
+        }
+        else {
+          SCRUTE(aHyp->_is_nil());
+          SCRUTE(aMesh->_is_nil());
+          SCRUTE(!SsubM);
+          SCRUTE(aShapeObject->_is_nil());
+        }
       }
       catch(const SALOME::SALOME_Exception& S_ex) {
-       wc.suspend();
-       SalomeApp_Tools::QtCatchCorbaException(S_ex);
-       res = SMESH::HYP_UNKNOWN_FATAL;
+        wc.suspend();
+        SalomeApp_Tools::QtCatchCorbaException(S_ex);
+        res = SMESH::HYP_UNKNOWN_FATAL;
       }
     }
     else {
@@ -505,50 +617,48 @@ namespace SMESH
       _PTR(Study) aStudy = GetActiveStudyDocument();
       _PTR(SObject) aHypObj = aStudy->FindObjectID( IObject->getEntry() );
       if( aHypObj )
-       {
-         _PTR(SObject) MorSM = SMESH::GetMeshOrSubmesh( aHypObj );
-         _PTR(SObject) aRealHypo;
-         if( aHypObj->ReferencedObject( aRealHypo ) )
-           {
-             SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aRealHypo ) );
-             RemoveHypothesisOrAlgorithmOnMesh( MorSM, hypo );
-           }
-         else
-           {
-             SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aHypObj ) );
-             SObjectList meshList = GetMeshesUsingAlgoOrHypothesis( hypo );
-             for( int i = 0; i < meshList.size(); i++ )
-               RemoveHypothesisOrAlgorithmOnMesh( meshList[ i ], hypo );
-           }
-       }
+        {
+          _PTR(SObject) MorSM = SMESH::GetMeshOrSubmesh( aHypObj );
+          _PTR(SObject) aRealHypo;
+          if( aHypObj->ReferencedObject( aRealHypo ) )
+            {
+              SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aRealHypo ) );
+              RemoveHypothesisOrAlgorithmOnMesh( MorSM, hypo );
+            }
+          else
+            {
+              SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aHypObj ) );
+              SObjectList meshList = GetMeshesUsingAlgoOrHypothesis( hypo );
+              for( size_t i = 0; i < meshList.size(); i++ )
+                RemoveHypothesisOrAlgorithmOnMesh( meshList[ i ], hypo );
+            }
+        }
     }
     catch(const SALOME::SALOME_Exception& S_ex)
       {
-       wc.suspend();
-       SalomeApp_Tools::QtCatchCorbaException(S_ex);
-       res = SMESH::HYP_UNKNOWN_FATAL;
+        wc.suspend();
+        SalomeApp_Tools::QtCatchCorbaException(S_ex);
+        res = SMESH::HYP_UNKNOWN_FATAL;
       }
     return res < SMESH::HYP_UNKNOWN_FATAL;
   }
 
-  bool RemoveHypothesisOrAlgorithmOnMesh (_PTR(SObject) MorSM,
+  bool RemoveHypothesisOrAlgorithmOnMesh (_PTR(SObject)               MorSM,
                                           SMESH::SMESH_Hypothesis_ptr anHyp)
   {
-    SALOMEDS::GenericAttribute_var anAttr;
-    SALOMEDS::AttributeIOR_var anIOR;
     int res = SMESH::HYP_UNKNOWN_FATAL;
     SUIT_OverrideCursor wc;
 
     if (MorSM) {
       try {
         GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh(MorSM);
-        SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>(MorSM);
-        SMESH::SMESH_subMesh_var aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>(MorSM);
-        
+        SMESH::SMESH_Mesh_var aMesh        = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>(MorSM);
+        SMESH::SMESH_subMesh_var aSubMesh  = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>(MorSM);
+
         if (!aSubMesh->_is_nil())
           aMesh = aSubMesh->GetFather();
-        
-        if (!aMesh->_is_nil()) {    
+
+        if (!aMesh->_is_nil()) {
           if (aMesh->HasShapeToMesh() && !aShapeObject->_is_nil()) {
             res = aMesh->RemoveHypothesis(aShapeObject, anHyp);
             if (res < SMESH::HYP_UNKNOWN_FATAL) {
@@ -556,14 +666,14 @@ namespace SMESH
               if (meshSO)
                 SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);
             }
-            
+
           }
           else if(!aMesh->HasShapeToMesh()){
             res = aMesh->RemoveHypothesis(aShapeObject, anHyp);
-           if (res < SMESH::HYP_UNKNOWN_FATAL) {
+            if (res < SMESH::HYP_UNKNOWN_FATAL) {
               _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
               if (meshSO)
-                SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);              
+                SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);
             }
           }
           if (res > SMESH::HYP_OK) {
@@ -573,9 +683,9 @@ namespace SMESH
           }
         }
       } catch(const SALOME::SALOME_Exception& S_ex) {
-       wc.suspend();
-       SalomeApp_Tools::QtCatchCorbaException(S_ex);
-       res = SMESH::HYP_UNKNOWN_FATAL;
+        wc.suspend();
+        SalomeApp_Tools::QtCatchCorbaException(S_ex);
+        res = SMESH::HYP_UNKNOWN_FATAL;
       }
     }
     return res < SMESH::HYP_UNKNOWN_FATAL;
@@ -590,25 +700,25 @@ namespace SMESH
     if (!AlgoOrHyp->_is_nil()) {
       _PTR(SObject) SO_Hypothesis = SMESH::FindSObject(AlgoOrHyp);
       if (SO_Hypothesis) {
-       SObjectList listSO =
-         SMESHGUI::activeStudy()->studyDS()->FindDependances(SO_Hypothesis);
-
-       if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency number ="<<listSO.size());
-       for (unsigned int i = 0; i < listSO.size(); i++) {
-         _PTR(SObject) SO = listSO[i];
-         if (SO) {
-           _PTR(SObject) aFather = SO->GetFather();
-           if (aFather) {
-             _PTR(SObject) SOfatherFather = aFather->GetFather();
-             if (SOfatherFather) {
-               if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency added to list");
-               index++;
-               listSOmesh.resize(index);
-               listSOmesh[index - 1] = SOfatherFather;
-             }
-           }
-         }
-       }
+        SObjectList listSO =
+          SMESHGUI::activeStudy()->studyDS()->FindDependances(SO_Hypothesis);
+
+        if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency number ="<<listSO.size());
+        for (unsigned int i = 0; i < listSO.size(); i++) {
+          _PTR(SObject) SO = listSO[i];
+          if (SO) {
+            _PTR(SObject) aFather = SO->GetFather();
+            if (aFather) {
+              _PTR(SObject) SOfatherFather = aFather->GetFather();
+              if (SOfatherFather) {
+                if(MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): dependency added to list");
+                index++;
+                listSOmesh.resize(index);
+                listSOmesh[index - 1] = SOfatherFather;
+              }
+            }
+          }
+        }
       }
     }
     if (MYDEBUG) MESSAGE("SMESHGUI::GetMeshesUsingAlgoOrHypothesis(): completed");
@@ -619,13 +729,13 @@ namespace SMESH
   QString GetMessageOnAlgoStateErrors(const algo_error_array& errors)
   {
     QString resMsg; // PAL14861 = QObject::tr("SMESH_WRN_MISSING_PARAMETERS") + ":\n";
-    for ( int i = 0; i < errors.length(); ++i ) {
+    for ( size_t i = 0; i < errors.length(); ++i ) {
       const SMESH::AlgoStateError & error = errors[ i ];
       const bool hasAlgo = ( strlen( error.algoName ) != 0 );
       QString msg;
       if ( !hasAlgo )
         msg = QObject::tr( "STATE_ALGO_MISSING" );
-      else 
+      else
         switch( error.state ) {
           CASE2MESSAGE( HYP_MISSING );
           CASE2MESSAGE( HYP_NOTCONFORM );