Salome HOME
Fix exception at Break Link after shaper group modification
[modules/smesh.git] / src / SMESHGUI / SMESHGUI.cxx
index c697a08ceb5512b6cc03aa84212d084c37d67923..fb1e7ad935186656edf292429984953583cf730f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2019  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
 #include <SALOMEDS_Study.hxx>
 #include <SALOMEDS_SObject.hxx>
 #include "utilities.h"
+#include <SALOME_LifeCycleCORBA.hxx>
 
 // OCCT includes
 #include <Standard_ErrorHandler.hxx>
@@ -1382,6 +1383,59 @@ namespace
     }
   }
 
+  // Break link with Shaper model
+  void breakShaperLink()
+  {
+    LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+    SALOME_ListIO selected;
+    if (aSel) {
+      aSel->selectedObjects(selected);
+      if (selected.Extent()) {
+        Handle(SALOME_InteractiveObject) anIObject = selected.First();
+        _PTR(Study) aStudy = SMESH::getStudy();
+        std::string aEntry = anIObject->getEntry();
+        _PTR(SObject) aSObj = aStudy->FindObjectID(aEntry);
+        if (aSObj) {
+          std::string aName = aSObj->GetName();
+          QMessageBox::StandardButton aRes = SUIT_MessageBox::warning(SMESHGUI::desktop(),
+            QObject::tr("SMESH_WRN_WARNING"),
+            QObject::tr("MSG_BREAK_SHAPER_LINK").arg(aName.c_str()),
+            SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::No);
+          if (aRes == SUIT_MessageBox::Yes) {
+            SUIT_DataOwnerPtrList aList;
+            aSel->selected(aList, "ObjectBrowser", true);
+            SUIT_DataOwner* aOwn = aList.first();
+            LightApp_DataOwner* sowner = dynamic_cast<LightApp_DataOwner*>(aOwn);
+            QString aREntry = sowner->entry();
+
+            static GEOM::GEOM_Gen_var geomGen;
+            if (CORBA::is_nil(geomGen)) {
+              SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
+                (SUIT_Session::session()->activeApplication());
+              if (app) {
+                SALOME_LifeCycleCORBA* ls = new SALOME_LifeCycleCORBA(app->namingService());
+                Engines::EngineComponent_var comp =
+                  ls->FindOrLoad_Component("FactoryServer", "SHAPERSTUDY");
+                geomGen = GEOM::GEOM_Gen::_narrow(comp);
+              }
+            }
+            if (!CORBA::is_nil(geomGen))
+            {
+              geomGen->BreakLink(aREntry.toStdString().c_str());
+              SMESHGUI::GetSMESHGUI()->updateObjBrowser();
+
+              // remove actors whose objects are removed by BreakLink()
+              QList<SUIT_ViewWindow*> wndList = SMESHGUI::desktop()->windows();
+              SUIT_ViewWindow* wnd;
+              foreach(wnd, wndList)
+                SMESH::UpdateActorsAfterUpdateStudy(wnd);
+            }
+          }
+        }
+      }
+    }
+  }
+
   void SetDisplayMode(int theCommandID, VTK::MarkerMap& theMarkerMap)
   {
     SALOME_ListIO selected;
@@ -1750,7 +1804,7 @@ namespace
                 int anEntitiesCount = anActor->GetNumberControlEntities();
                 if (anEntitiesCount >= 0)
                   functorName = functorName + ": " + QString::number(anEntitiesCount);
-                anActor->GetScalarBarActor()->SetTitle( functorName.toLatin1().constData() );
+                anActor->GetScalarBarActor()->SetTitle( functorName.toUtf8().constData() );
                 SMESH::RepaintCurrentView();
 #ifndef DISABLE_PLOT2DVIEWER
                 if ( anActor->GetPlot2Histogram() ) {
@@ -1920,8 +1974,8 @@ void SMESHGUI::OnEditDelete()
 
   SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
 
-  // Put the whole hierarchy of sub-objects of the selected SO's into a list and
-  // then treat them all starting from the deepest objects (at list back)
+  // Put one level of sub-objects of the selected SO's into a list
+  // in order to get objects inside folders like "Assigned Algorithms"
   std::list< _PTR(SObject) > listSO;
   SALOME_ListIteratorOfListIO It(selected);
   for( ; It.More(); It.Next()) // loop on selected IO's
@@ -1942,43 +1996,47 @@ void SMESHGUI::OnEditDelete()
         aSO = aRefSObject; // Delete main Object instead of reference
 
       listSO.push_back( aSO );
-      std::list< _PTR(SObject) >::iterator itSO = --listSO.end();
-      for ( ; itSO != listSO.end(); ++itSO ) {
-        _PTR(ChildIterator) it = aStudy->NewChildIterator( *itSO );
-        for (it->InitEx(false); it->More(); it->Next())
-          listSO.push_back( it->Value() );
-      }
+
+      _PTR(ChildIterator) it = aStudy->NewChildIterator( aSO );
+      for (it->InitEx(false); it->More(); it->Next())
+        listSO.push_back( it->Value() );
     }
   }
   // Check if none of objects to delete is referred from outside
   std::list< _PTR(SObject) >::reverse_iterator ritSO;
+  std::vector< _PTR(SObject) > subSO;
   for ( ritSO = listSO.rbegin(); ritSO != listSO.rend(); ++ritSO )
   {
     _PTR(SObject) SO = *ritSO;
     if ( !SO ) continue;
-    std::vector<_PTR(SObject)> aReferences = aStudy->FindDependances( *ritSO  );
-    for (size_t i = 0; i < aReferences.size(); i++) {
-      _PTR(SComponent) aComponent = aReferences[i]->GetFatherComponent();
-      std::string type = aComponent->ComponentDataType();
-      if ( type != "SMESH" )
-      {
-        SUIT_MessageBox::warning( anApp->desktop(),
-                                  QObject::tr("WRN_WARNING"),
-                                  QObject::tr("DEP_OBJECT") );
-        return; // outside SMESH, there is an object depending on a SMESH object
+
+    int nbChildren = SO->GetLastChildTag();
+    subSO.clear();
+    subSO.reserve( 1 + nbChildren );
+    subSO.push_back( SO );
+    if ( nbChildren > 0 )
+    {
+      _PTR(ChildIterator) it = aStudy->NewChildIterator( SO );
+      for ( it->InitEx( true ); it->More(); it->Next() )
+        subSO.push_back( it->Value() );
+    }
+    for ( size_t i = 0; i < subSO.size(); ++i )
+    {
+      std::vector<_PTR(SObject)> aReferences = aStudy->FindDependances( subSO[i] );
+      for ( size_t j = 0; j < aReferences.size(); j++ ) {
+        _PTR(SComponent) aComponent = aReferences[j]->GetFatherComponent();
+        std::string type = aComponent->ComponentDataType();
+        if ( type != "SMESH" )
+        {
+          SUIT_MessageBox::warning( anApp->desktop(),
+                                    QObject::tr("WRN_WARNING"),
+                                    QObject::tr("DEP_OBJECT") );
+          return; // outside SMESH, there is an object depending on a SMESH object
+        }
       }
     }
   }
 
-  // Call mesh->Clear() to prevent loading mesh from file caused by hypotheses removal
-  for( It.Initialize( selected ); It.More(); It.Next()) // loop on selected IO's
-  {
-    Handle(SALOME_InteractiveObject) IObject = It.Value();
-    SMESH::SMESH_Mesh_var mesh = SMESH::IObjectToInterface< SMESH::SMESH_Mesh >( IObject );
-    if ( !mesh->_is_nil() )
-      mesh->Clear();
-  }
-
   // Treat SO's in the list starting from the back
   aStudyBuilder->NewCommand();  // There is a transaction
   for ( ritSO = listSO.rbegin(); ritSO != listSO.rend(); ++ritSO )
@@ -1988,7 +2046,7 @@ void SMESHGUI::OnEditDelete()
     std::string anEntry = SO->GetID();
 
     /** Erase graphical object and remove all its data **/
-    if(SO->FindAttribute(anAttr, "AttributeIOR")) {
+    if ( SO->FindAttribute( anAttr, "AttributeIOR" )) {
       SMESH::RemoveVisualObjectWithActors( anEntry.c_str(), true);
     }
     /** Remove an object from data structures **/
@@ -3747,6 +3805,9 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case SMESHOp::OpSortChild:
     ::sortChildren();
     break;
+  case SMESHOp::OpBreakLink:
+    ::breakShaperLink();
+    break;
 
   }
 
@@ -4080,6 +4141,8 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   createSMESHAction( SMESHOp::OpSortChild, "SORT_CHILD_ITEMS" );
 
+  createSMESHAction( SMESHOp::OpBreakLink, "BREAK_SHAPER_LINK" );
+
   QList<int> aCtrlActions;
   aCtrlActions << SMESHOp::OpFreeNode << SMESHOp::OpEqualNode
                << SMESHOp::OpNodeConnectivityNb                                         // node controls
@@ -4853,6 +4916,9 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->setRule( action( SMESHOp::OpSortChild ), "$component={'SMESH'} and client='ObjectBrowser' and isContainer and nbChildren>1", QtxPopupMgr::VisibleRule );
   popupMgr()->insert( separator(), -1, -1 );
 
+  popupMgr()->insert( action( SMESHOp::OpBreakLink), -1, -1 );
+  popupMgr()->setRule( action( SMESHOp::OpBreakLink), "$component={'SHAPERSTUDY'} and client='ObjectBrowser' and canBreakLink", QtxPopupMgr::VisibleRule );
+
   connect( application(), SIGNAL( viewManagerActivated( SUIT_ViewManager* ) ),
            this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) );
 
@@ -4925,8 +4991,15 @@ bool SMESHGUI::activateModule( SUIT_Study* study )
   if ( aDesk ) {
     QList<SUIT_ViewWindow*> wndList = aDesk->windows();
     SUIT_ViewWindow* wnd;
-    foreach ( wnd, wndList )
-      connectView( wnd );
+    foreach(wnd, wndList)
+    {
+      connectView(wnd);
+
+      // remove actors whose objects are removed in GetSMESHGen()->UpdateStudy()
+      SMESH::UpdateActorsAfterUpdateStudy(wnd);
+
+      wnd->update();
+    }
   }
 
   Py_XDECREF(pluginsmanager);