Salome HOME
IPAL52933: Selection disappears in the "Move node" dialog
[modules/smesh.git] / src / SMESHGUI / SMESHGUI.cxx
index 6271fe8570a99a698d10945294a6dcfabc680713..a465cd3bec41d431b0c77ae3f81f83ca1d4dc47b 100644 (file)
 // OCCT includes
 #include <Standard_ErrorHandler.hxx>
 #include <NCollection_DataMap.hxx>
+#include <NCollection_DoubleMap.hxx>
 
 #include <Basics_Utils.hxx>
 
@@ -199,6 +200,8 @@ namespace
 
   void SetDisplayEntity(int theCommandID);
 
+  int ActionToControl( int theID, bool theReversed = false );
+
   void Control( int theCommandID );
 
   // Definitions
@@ -1173,7 +1176,7 @@ namespace
                   out << "# Control: " << functorToString( aFunctor ) << endl;
                   out << "#" << endl;
                   out.setFieldWidth( 10 );
-                  for ( int i = 0; i < qMin( nbEvents.size(), funValues.size()-1 ); i++ )
+                  for ( int i = 0; i < (int)qMin( nbEvents.size(), funValues.size()-1 ); i++ )
                     out << funValues[i] << "\t" << funValues[i+1] << "\t" << nbEvents[i] << endl;
                   f.close();
                 }
@@ -1580,89 +1583,43 @@ namespace
     }
   }
 
+  int ActionToControl( int theID, bool theReversed )
+  {
+    NCollection_DoubleMap<int,int> ActionControl;
+    ActionControl.Bind( 0,                                SMESH_Actor::eNone );
+    ActionControl.Bind( SMESHOp::OpFreeNode,              SMESH_Actor::eFreeNodes );
+    ActionControl.Bind( SMESHOp::OpEqualNode,             SMESH_Actor::eCoincidentNodes );
+    ActionControl.Bind( SMESHOp::OpFreeEdge,              SMESH_Actor::eFreeEdges );
+    ActionControl.Bind( SMESHOp::OpFreeBorder,            SMESH_Actor::eFreeBorders );
+    ActionControl.Bind( SMESHOp::OpLength,                SMESH_Actor::eLength );
+    ActionControl.Bind( SMESHOp::OpConnection,            SMESH_Actor::eMultiConnection );
+    ActionControl.Bind( SMESHOp::OpEqualEdge,             SMESH_Actor::eCoincidentElems1D );
+    ActionControl.Bind( SMESHOp::OpFreeFace,              SMESH_Actor::eFreeFaces );
+    ActionControl.Bind( SMESHOp::OpBareBorderFace,        SMESH_Actor::eBareBorderFace );
+    ActionControl.Bind( SMESHOp::OpOverConstrainedFace,   SMESH_Actor::eOverConstrainedFace );
+    ActionControl.Bind( SMESHOp::OpLength2D,              SMESH_Actor::eLength2D );
+    ActionControl.Bind( SMESHOp::OpConnection2D,          SMESH_Actor::eMultiConnection2D );
+    ActionControl.Bind( SMESHOp::OpArea,                  SMESH_Actor::eArea );
+    ActionControl.Bind( SMESHOp::OpTaper,                 SMESH_Actor::eTaper );
+    ActionControl.Bind( SMESHOp::OpAspectRatio,           SMESH_Actor::eAspectRatio );
+    ActionControl.Bind( SMESHOp::OpMinimumAngle,          SMESH_Actor::eMinimumAngle );
+    ActionControl.Bind( SMESHOp::OpWarpingAngle,          SMESH_Actor::eWarping );
+    ActionControl.Bind( SMESHOp::OpSkew,                  SMESH_Actor::eSkew );
+    ActionControl.Bind( SMESHOp::OpMaxElementLength2D,    SMESH_Actor::eMaxElementLength2D );
+    ActionControl.Bind( SMESHOp::OpEqualFace,             SMESH_Actor::eCoincidentElems2D );
+    ActionControl.Bind( SMESHOp::OpAspectRatio3D,         SMESH_Actor::eAspectRatio3D );
+    ActionControl.Bind( SMESHOp::OpVolume,                SMESH_Actor::eVolume3D );
+    ActionControl.Bind( SMESHOp::OpMaxElementLength3D,    SMESH_Actor::eMaxElementLength3D );
+    ActionControl.Bind( SMESHOp::OpBareBorderVolume,      SMESH_Actor::eBareBorderVolume );
+    ActionControl.Bind( SMESHOp::OpOverConstrainedVolume, SMESH_Actor::eOverConstrainedVolume );
+    ActionControl.Bind( SMESHOp::OpEqualVolume,           SMESH_Actor::eCoincidentElems3D );
+
+    return theReversed ? ActionControl.Find2( theID ) : ActionControl.Find1( theID );
+  }
+
   void Control( int theCommandID )
   {
-    SMESH_Actor::eControl aControl = SMESH_Actor::eNone;
-    switch ( theCommandID ){
-    case SMESHOp::OpFreeNode:
-      aControl = SMESH_Actor::eFreeNodes;
-      break;
-    case SMESHOp::OpEqualNode:
-      aControl = SMESH_Actor::eCoincidentNodes;
-      break;
-    case SMESHOp::OpFreeEdge:
-      aControl = SMESH_Actor::eFreeEdges;
-      break;
-    case SMESHOp::OpFreeBorder:
-      aControl = SMESH_Actor::eFreeBorders;
-      break;
-    case SMESHOp::OpLength:
-      aControl = SMESH_Actor::eLength;
-      break;
-    case SMESHOp::OpConnection:
-      aControl = SMESH_Actor::eMultiConnection;
-      break;
-    case SMESHOp::OpEqualEdge:
-      aControl = SMESH_Actor::eCoincidentElems1D;
-      break;
-    case SMESHOp::OpFreeFace:
-      aControl = SMESH_Actor::eFreeFaces;
-      break;
-    case SMESHOp::OpBareBorderFace:
-      aControl = SMESH_Actor::eBareBorderFace;
-      break;
-    case SMESHOp::OpOverConstrainedFace:
-      aControl = SMESH_Actor::eOverConstrainedFace;
-      break;
-    case SMESHOp::OpLength2D:
-      aControl = SMESH_Actor::eLength2D;
-      break;
-    case SMESHOp::OpConnection2D:
-      aControl = SMESH_Actor::eMultiConnection2D;
-      break;
-    case SMESHOp::OpArea:
-      aControl = SMESH_Actor::eArea;
-      break;
-    case SMESHOp::OpTaper:
-      aControl = SMESH_Actor::eTaper;
-      break;
-    case SMESHOp::OpAspectRatio:
-      aControl = SMESH_Actor::eAspectRatio;
-      break;
-    case SMESHOp::OpMinimumAngle:
-      aControl = SMESH_Actor::eMinimumAngle;
-      break;
-    case SMESHOp::OpWarpingAngle:
-      aControl = SMESH_Actor::eWarping;
-      break;
-    case SMESHOp::OpSkew:
-      aControl = SMESH_Actor::eSkew;
-      break;
-    case SMESHOp::OpMaxElementLength2D:
-      aControl = SMESH_Actor::eMaxElementLength2D;
-      break;
-    case SMESHOp::OpEqualFace:
-      aControl = SMESH_Actor:: eCoincidentElems2D;
-      break;
-    case SMESHOp::OpAspectRatio3D:
-      aControl = SMESH_Actor::eAspectRatio3D;
-      break;
-    case SMESHOp::OpVolume:
-      aControl = SMESH_Actor::eVolume3D;
-      break;
-    case SMESHOp::OpMaxElementLength3D:
-      aControl = SMESH_Actor::eMaxElementLength3D;
-      break;
-    case SMESHOp::OpBareBorderVolume:
-      aControl = SMESH_Actor::eBareBorderVolume;
-      break;
-    case SMESHOp::OpOverConstrainedVolume:
-      aControl = SMESH_Actor::eOverConstrainedVolume;
-      break;
-    case SMESHOp::OpEqualVolume:
-      aControl = SMESH_Actor::eCoincidentElems3D;
-      break;
-    }
+    SMESH_Actor::eControl aControl = SMESH_Actor::eControl( ActionToControl( theCommandID ) );
     _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
     LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
     SALOME_ListIO selected;
@@ -1677,7 +1634,7 @@ namespace
         if(!anIO.IsNull()){
           _PTR(SObject) SO = aStudy->FindObjectID( It.Value()->getEntry() );
           if ( SO ) {
-            CORBA::Object_var aObject = SMESH::SObjectToObject( SO );
+            CORBA::Object_var           aObject = SMESH::SObjectToObject( SO );
             SMESH::SMESH_Mesh_var      aMesh    = SMESH::SMESH_Mesh::_narrow( aObject );
             SMESH::SMESH_subMesh_var   aSubMesh = SMESH::SMESH_subMesh::_narrow( aObject );
             SMESH::SMESH_GroupBase_var aGroup   = SMESH::SMESH_GroupBase::_narrow( aObject );
@@ -2487,8 +2444,9 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       if( aSel )
         aSel->selectedObjects( selected );
 
-      if( selected.Extent() ) {
-        Handle(SALOME_InteractiveObject) anIO = selected.First();
+      SALOME_ListIteratorOfListIO it(selected);
+      for( ; it.More(); it.Next()) {
+        Handle(SALOME_InteractiveObject) anIO = it.Value();
         if( anIO->hasEntry() ) {
           if( SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() ) ) {
             anActor->SetControlMode( SMESH_Actor::eNone );
@@ -2498,6 +2456,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
           }
         }
       }
+      SMESH::UpdateView();
       break;
     }
   case SMESHOp::OpScalarBarProperties:
@@ -2625,8 +2584,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     {
       SMESH::EDisplaing anAction;
       switch (theCommandID) {
-      case SMESHOp::OpHide: anAction = SMESH::eErase; break;
-      case SMESHOp::OpShow: anAction = SMESH::eDisplay; break;
+      case SMESHOp::OpHide:     anAction = SMESH::eErase; break;
+      case SMESHOp::OpShow:     anAction = SMESH::eDisplay; break;
       case SMESHOp::OpShowOnly: anAction = SMESH::eDisplayOnly; break;
       }
 
@@ -2635,7 +2594,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       if (aSel)
         aSel->selectedObjects( sel_objects );
 
-      if( theCommandID==SMESHOp::OpShowOnly )
+      if ( theCommandID==SMESHOp::OpShowOnly )
       {
         MESSAGE("anAction = SMESH::eDisplayOnly");
         startOperation( myEraseAll );
@@ -2649,20 +2608,17 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 #endif
         if (vtkwnd) {
           SALOME_ListIteratorOfListIO It( to_process );
-          for ( ; It.More(); It.Next()) {
-            MESSAGE("---");
+          for ( ; It.More(); It.Next())
+          {
             Handle(SALOME_InteractiveObject) IOS = It.Value();
-            if (IOS->hasEntry()) {
-              MESSAGE("---");
-              if (!SMESH::UpdateView(anAction, IOS->getEntry())) {
+            if ( IOS->hasEntry() )
+            {
+              if ( !SMESH::UpdateView( anAction, IOS->getEntry() )) {
                 SMESHGUI::GetSMESHGUI()->EmitSignalVisibilityChanged();
                 break; // PAL16774 (Crash after display of many groups)
               }
               if (anAction == SMESH::eDisplayOnly)
-              {
-                MESSAGE("anAction = SMESH::eDisplayOnly");
                 anAction = SMESH::eDisplay;
-              }
             }
           }
         }
@@ -4029,12 +3985,14 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   createMenu( separator(), fileId );
 
+  QMenu* nodeMenu = new QMenu(); QMenu* edgeMenu = new QMenu();
+  QMenu* faceMenu = new QMenu(); QMenu* volumeMenu = new QMenu();
   int importId = createMenu( tr( "MEN_IMPORT" ), fileId, -1, 10 ),
       exportId = createMenu( tr( "MEN_EXPORT" ), fileId, -1, 10 ),
-      nodeId   = createMenu( tr( "MEN_NODE_CTRL" ), ctrlId, -1, 10 ),
-      edgeId   = createMenu( tr( "MEN_EDGE_CTRL" ), ctrlId, -1, 10 ),
-      faceId   = createMenu( tr( "MEN_FACE_CTRL" ), ctrlId, -1, 10 ),
-      volumeId = createMenu( tr( "MEN_VOLUME_CTRL" ), ctrlId, -1, 10 ),
+      nodeId   = createMenu( tr( "MEN_NODE_CTRL" ), ctrlId, -1, 10, -1, nodeMenu ),
+      edgeId   = createMenu( tr( "MEN_EDGE_CTRL" ), ctrlId, -1, 10, -1, edgeMenu ),
+      faceId   = createMenu( tr( "MEN_FACE_CTRL" ), ctrlId, -1, 10, -1, faceMenu ),
+      volumeId = createMenu( tr( "MEN_VOLUME_CTRL" ), ctrlId, -1, 10, -1, volumeMenu ),
       addId    = createMenu( tr( "MEN_ADD" ),    modifyId, 402 ),
       removeId = createMenu( tr( "MEN_REMOVE" ), modifyId, 403 ),
     //renumId  = createMenu( tr( "MEN_RENUM" ),  modifyId, 404 ),
@@ -4096,11 +4054,11 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   createMenu( SMESHOp::OpFreeNode,              nodeId,   -1 );
   createMenu( SMESHOp::OpEqualNode,             nodeId,   -1 );
-  createMenu( SMESHOp::OpFreeEdge,              edgeId,   -1 );
   createMenu( SMESHOp::OpFreeBorder,            edgeId,   -1 );
   createMenu( SMESHOp::OpLength,                edgeId,   -1 );
   createMenu( SMESHOp::OpConnection,            edgeId,   -1 );
   createMenu( SMESHOp::OpEqualEdge,             edgeId,   -1 );
+  createMenu( SMESHOp::OpFreeEdge,              faceId,   -1 );
   createMenu( SMESHOp::OpFreeFace,              faceId,   -1 );
   createMenu( SMESHOp::OpBareBorderFace,        faceId,   -1 );
   createMenu( SMESHOp::OpOverConstrainedFace,   faceId,   -1 );
@@ -4196,6 +4154,11 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( SMESHOp::OpPropertiesVolume, basicPropId, -1 );
   createMenu( SMESHOp::OpUpdate,           viewId,      -1 );
 
+  connect( nodeMenu, SIGNAL( aboutToShow() ), this, SLOT( onUpdateControlActions() ) );
+  connect( edgeMenu, SIGNAL( aboutToShow() ), this, SLOT( onUpdateControlActions() ) );
+  connect( faceMenu, SIGNAL( aboutToShow() ), this, SLOT( onUpdateControlActions() ) );
+  connect( volumeMenu, SIGNAL( aboutToShow() ), this, SLOT( onUpdateControlActions() ) );
+
   // ----- create toolbars --------------
   int meshTb       = createTool( tr( "TB_MESH" ),      QString( "SMESHMeshToolbar" ) ),
       info         = createTool( tr( "TB_INFO" ),      QString( "SMESHInformationToolbar" ) ),
@@ -4237,12 +4200,12 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( SMESHOp::OpFreeNode,  ctrl0dTb );
   createTool( SMESHOp::OpEqualNode, ctrl0dTb );
 
-  createTool( SMESHOp::OpFreeEdge,   ctrl1dTb );
   createTool( SMESHOp::OpFreeBorder, ctrl1dTb );
   createTool( SMESHOp::OpLength,     ctrl1dTb );
   createTool( SMESHOp::OpConnection, ctrl1dTb );
   createTool( SMESHOp::OpEqualEdge,  ctrl1dTb );
 
+  createTool( SMESHOp::OpFreeEdge,            ctrl2dTb );
   createTool( SMESHOp::OpFreeFace,            ctrl2dTb );
   createTool( SMESHOp::OpBareBorderFace,      ctrl2dTb );
   createTool( SMESHOp::OpOverConstrainedFace, ctrl2dTb );
@@ -4366,38 +4329,39 @@ void SMESHGUI::initialize( CAM_Application* app )
     hasElems0d("({'Elem0d'} in elemTypes)"),
     hasEdges("({'Edge'} in elemTypes)"),
     hasFaces("({'Face'} in elemTypes)"),
-    hasVolumes("({'Volume'} in elemTypes)");
+    hasVolumes("({'Volume'} in elemTypes)"),
+    hasFacesOrVolumes("(({'Face'} in elemTypes) || ({'Volume'} in elemTypes)) ");
 
   createPopupItem( SMESHOp::OpFileInformation,      OB, mesh, "&& selcount=1 && isImported" );
-  createPopupItem( SMESHOp::OpCreateSubMesh,        OB, mesh, "&& isComputable");
-  createPopupItem( SMESHOp::OpEditMeshOrSubMesh,    OB, mesh, "&& isComputable");
-  createPopupItem( SMESHOp::OpEditMeshOrSubMesh,    OB, subMesh, "&& isComputable" );
+  createPopupItem( SMESHOp::OpCreateSubMesh,        OB, mesh, "&& hasGeomReference");
+  createPopupItem( SMESHOp::OpEditMeshOrSubMesh,    OB, mesh );
+  createPopupItem( SMESHOp::OpEditMeshOrSubMesh,    OB, subMesh, "&& hasGeomReference" );
   createPopupItem( SMESHOp::OpEditGroup,            OB, group );
   createPopupItem( SMESHOp::OpEditGeomGroupAsGroup, OB, group, "&& groupType != 'Group'" );
 
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpCompute,                OB, mesh, "&& isComputable" );
-  createPopupItem( SMESHOp::OpPreCompute,             OB, mesh, "&& isComputable && isPreComputable" );
+  createPopupItem( SMESHOp::OpPreCompute,             OB, mesh, "&& isPreComputable" );
   createPopupItem( SMESHOp::OpEvaluate,               OB, mesh, "&& isComputable" );
-  createPopupItem( SMESHOp::OpMeshOrder,              OB, mesh, "&& isComputable" );
+  createPopupItem( SMESHOp::OpMeshOrder,              OB, mesh, "&& isComputable && hasGeomReference" );
   createPopupItem( SMESHOp::OpUpdate,                 OB, mesh_part );
   createPopupItem( SMESHOp::OpMeshInformation,        OB, mesh_part );
   createPopupItem( SMESHOp::OpFindElementByPoint,     OB, mesh_group );
   createPopupItem( SMESHOp::OpOverallMeshQuality,     OB, mesh_part );
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpCreateGroup,            OB, mesh );
-  createPopupItem( SMESHOp::OpCreateGeometryGroup,    OB, mesh );
+  createPopupItem( SMESHOp::OpCreateGeometryGroup,    OB, mesh, "&& hasGeomReference" );
   createPopupItem( SMESHOp::OpConstructGroup,         OB, subMesh );
   popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpEditHypothesis,         OB, hypo);
   createPopupItem( SMESHOp::OpUnassign,               OB, hyp_alg );     // REMOVE HYPOTHESIS / ALGORITHMS
   popupMgr()->insert( separator(), -1, 0 );
-  createPopupItem( SMESHOp::OpClearMesh,              OB, mesh );
-  popupMgr()->insert( separator(), -1, 0 );
   createPopupItem( SMESHOp::OpConvertMeshToQuadratic, OB, mesh + " " + subMesh );  // convert to quadratic
   createPopupItem( SMESHOp::OpCreateBoundaryElements, OB, mesh + " " + group,      // create 2D mesh from 3D
                    "&& dim>=2");
   popupMgr()->insert( separator(), -1, 0 );
+  createPopupItem( SMESHOp::OpClearMesh,              OB, mesh );
+  popupMgr()->insert( separator(), -1, 0 );
 
   QString only_one_non_empty = QString( " && %1=1 && numberOfNodes>0" ).arg( dc );
   QString multiple_non_empty = QString( " && %1>0 && numberOfNodes>0" ).arg( dc );
@@ -4577,12 +4541,8 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   aSubId = popupMgr()->insert( tr( "MEN_EDGE_CTRL" ), anId, -1 ); // EDGE CONTROLS
 
-  popupMgr()->insert( action( SMESHOp::OpFreeEdge ), aSubId, -1 );
-  popupMgr()->setRule( action( SMESHOp::OpFreeEdge ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
-  popupMgr()->setRule( action( SMESHOp::OpFreeEdge ), "controlMode = 'eFreeEdges'", QtxPopupMgr::ToggleRule );
-
   popupMgr()->insert( action( SMESHOp::OpFreeBorder ), aSubId, -1 );
-  popupMgr()->setRule( action( SMESHOp::OpFreeBorder ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( SMESHOp::OpFreeBorder ), aMeshInVTK + "&&" + hasEdges + "&&" + hasFacesOrVolumes, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( SMESHOp::OpFreeBorder ), "controlMode = 'eFreeBorders'", QtxPopupMgr::ToggleRule );
 
   popupMgr()->insert( action( SMESHOp::OpLength ), aSubId, -1 );
@@ -4598,6 +4558,10 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   aSubId = popupMgr()->insert( tr( "MEN_FACE_CTRL" ), anId, -1 ); // FACE CONTROLS
 
+  popupMgr()->insert( action( SMESHOp::OpFreeEdge ), aSubId, -1 );
+  popupMgr()->setRule( action( SMESHOp::OpFreeEdge ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( SMESHOp::OpFreeEdge ), "controlMode = 'eFreeEdges'", QtxPopupMgr::ToggleRule );
+
   popupMgr()->insert ( action( SMESHOp::OpFreeFace ), aSubId, -1 );
   popupMgr()->setRule( action( SMESHOp::OpFreeFace ), aMeshInVtkHasFaces /*aMeshInVtkHasVolumes*/,
                                        QtxPopupMgr::VisibleRule );
@@ -4937,7 +4901,7 @@ void SMESHGUI::ProcessEvents( vtkObject* theObject,
                               void* theCallData )
 {
   if( SMESHGUI* aSMESHGUI = reinterpret_cast<SMESHGUI*>( theClientData ) ) {
-    if( theObject && theEvent == SMESH::DeleteActorEvent ) {
+    if( theObject && (int) theEvent == SMESH::DeleteActorEvent ) {
       if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( theObject ) ) {
         SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = aSMESHGUI->getClippingPlaneInfoMap();
         SMESHGUI_ClippingPlaneInfoMap::iterator anIter1 = aClippingPlaneInfoMap.begin();
@@ -5341,79 +5305,92 @@ void SMESHGUI::createPreferences()
 
 void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
 {
-  if( sect=="SMESH" ) {
-    float sbX1,sbY1,sbW,sbH;
+  if ( sect=="SMESH" ) {
+    float sbX1 = 0.01, sbY1 = 0.01, sbW = 0.08, sbH = 0.08;
     float aTol = 1.00000009999999;
     std::string aWarning;
     SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr(this);
-    if( name=="selection_object_color" || name=="selection_element_color" ||
-        name=="highlight_color" ||
-        name=="selection_precision_node" || name=="selection_precision_element" ||
-        name=="selection_precision_object")
+
+    if ( name== "selection_object_color" ||
+         name=="selection_element_color" ||
+         name==        "highlight_color" ||
+         name=="selection_precision_node"    ||
+         name=="selection_precision_element" ||
+         name=="selection_precision_object"   )
+    {
       SMESH::UpdateSelectionProp( this );
-    else if (name == QString("scalar_bar_vertical_x") || name == QString("scalar_bar_vertical_width")){
-      sbX1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_x", sbX1);
-      sbW = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_width", sbW);
-      if(sbX1+sbW > aTol){
+    }
+    else if (name == "scalar_bar_vertical_x" || name == "scalar_bar_vertical_width")
+    {
+      sbX1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_x",     sbX1);
+      sbW  = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_width", sbW);
+      if ( sbX1+sbW > aTol ) {
         aWarning = "Origin and Size Vertical: X+Width > 1\n";
-        sbX1=0.01;
-        sbW=0.08;
-        aResourceMgr->setValue("SMESH", "scalar_bar_vertical_x", sbX1);
+        sbX1 = 0.01;
+        sbW  = 0.08;
+        aResourceMgr->setValue("SMESH", "scalar_bar_vertical_x",     sbX1);
         aResourceMgr->setValue("SMESH", "scalar_bar_vertical_width", sbW);
       }
     }
-    else if(name == QString("scalar_bar_vertical_y") || name == QString("scalar_bar_vertical_height")){
-      sbY1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_y", sbY1);
-      sbH = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_height",sbH);
-      if(sbY1+sbH > aTol){
+    else if (name == "scalar_bar_vertical_y" || name == "scalar_bar_vertical_height" )
+    {
+      sbY1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_y",     sbY1);
+      sbH  = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_height",sbH);
+      if ( sbY1 + sbH > aTol ) {
         aWarning = "Origin and Size Vertical: Y+Height > 1\n";
-        aResourceMgr->setValue("SMESH", "scalar_bar_vertical_y", sbY1);
+        aResourceMgr->setValue("SMESH", "scalar_bar_vertical_y",     sbY1);
         aResourceMgr->setValue("SMESH", "scalar_bar_vertical_height",sbH);
       }
     }
-    else if(name ==  QString("scalar_bar_horizontal_x") || name ==  QString("scalar_bar_horizontal_width")){
-      sbX1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_x", sbX1);
-      sbW = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_width", sbW);
-      if(sbX1+sbW > aTol){
+    else if (name == "scalar_bar_horizontal_x" || name ==  "scalar_bar_horizontal_width")
+    {
+      sbX1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_x",     sbX1);
+      sbW  = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_width", sbW);
+      if ( sbX1 + sbW > aTol ) {
         aWarning = "Origin and Size Horizontal: X+Width > 1\n";
         sbX1=0.1;
-        sbW=0.08;
+        sbW =0.08;
         aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_x", sbX1);
         aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_width", sbW);
       }
     }
-    else if(name ==  QString("scalar_bar_horizontal_y") || name ==  QString("scalar_bar_horizontal_height")){
-      sbY1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_y", sbY1);
-      sbH = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_height",sbH);
-      if(sbY1+sbH > aTol){
+    else if (name == "scalar_bar_horizontal_y" || name ==  "scalar_bar_horizontal_height")
+    {
+      sbY1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_y",     sbY1);
+      sbH  = aResourceMgr->doubleValue("SMESH", "scalar_bar_horizontal_height",sbH);
+      if ( sbY1 + sbH > aTol ) {
         aWarning = "Origin and Size Horizontal: Y+Height > 1\n";
         sbY1=0.01;
-        sbH=0.08;
+        sbH =0.08;
         aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_y", sbY1);
         aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_height",sbH);
       }
     }
-    else if ( name == "segmentation" ) {
+    else if ( name == "segmentation" )
+    {
       int nbSeg = aResourceMgr->integerValue( "SMESH", "segmentation", 10 );
       myComponentSMESH->SetBoundaryBoxSegmentation( nbSeg );
     }
-    else if ( name == "nb_segments_per_edge" ) {
+    else if ( name == "nb_segments_per_edge" )
+    {
       int nbSeg = aResourceMgr->integerValue( "SMESH", "nb_segments_per_edge", 15 );
       myComponentSMESH->SetDefaultNbSegments( nbSeg );
     }
-    else if ( name == "historical_python_dump" ||
-              name == "forget_mesh_on_hyp_modif") {
+    else if ( name == "historical_python_dump" || name == "forget_mesh_on_hyp_modif")
+    {
       QString val = aResourceMgr->stringValue( "SMESH", name );
       myComponentSMESH->SetOption( name.toLatin1().constData(), val.toLatin1().constData() );
     }
-    else if ( name == QString( "numbering_node_color" ) || name == QString( "numbering_node_font" ) ) {
-      SMESH::UpdateFontProp( this );    
+    else if ( name == "numbering_node_color" || name == "numbering_node_font" )
+    {
+      SMESH::UpdateFontProp( this );
     }
-    else if ( name == QString( "numbering_elem_color" ) || name == QString( "numbering_elem_font" ) ) {
+    else if ( name == "numbering_elem_color" || name == "numbering_elem_font" )
+    {
       SMESH::UpdateFontProp( this );
     }
 
-    if(aWarning.size() != 0){
+    if ( aWarning.size() != 0 ) {
       aWarning += "The default values are applied instead.";
       SUIT_MessageBox::warning(SMESHGUI::desktop(),
                                QObject::tr("SMESH_ERR_SCALARBAR_PARAMS"),
@@ -6848,6 +6825,47 @@ void SMESHGUI::onHypothesisEdit( int result )
   updateObjBrowser( true );
 }
 
+/*!
+  \brief Actions after choosing menu of control modes
+  Updates control mode actions according to current selection
+*/
+void SMESHGUI::onUpdateControlActions()
+{
+  LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
+  SALOME_ListIO selected;
+  if ( aSel )
+    aSel->selectedObjects( selected );
+
+  SMESH_Actor::eControl aControl = SMESH_Actor::eNone;
+  if ( selected.Extent() ) {
+    if ( selected.First()->hasEntry() ) {
+      aControl = SMESH::FindActorByEntry( selected.First()->getEntry() )->GetControlMode();
+      SALOME_ListIteratorOfListIO it(selected);
+      for ( ; it.More(); it.Next() ) {
+        Handle(SALOME_InteractiveObject) anIO = it.Value();
+        if ( anIO->hasEntry() ) {
+          if ( SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() ) ) {
+            if ( aControl != anActor->GetControlMode() ) {
+              aControl = SMESH_Actor::eNone;
+              break;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  int anAction = ActionToControl( aControl, true );
+  if ( anAction)
+    action( anAction )->setChecked( true );
+  else {
+    QMenu* send = (QMenu*)sender();
+    QList<QAction*> actions = send->actions();
+    for ( int i = 0; i < actions.size(); i++ )
+      actions[i]->setChecked( false );
+  }
+}
+
 
 /*!
   \brief Signal handler closing(SUIT_ViewWindow*) of a view