Salome HOME
Issue 0020950: EDF 1506 SMESH: Change the color of several groups
[modules/smesh.git] / src / SMESHGUI / SMESHGUI.cxx
index fb0d7591750c7b921849c64ee4d555c5b2cb93ff..c0a9ba9be1750a0adcd217ebcff37dd8f3577c86 100644 (file)
 //
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+//  SMESH SMESHGUI : GUI for SMESH component
+//  File   : SMESHGUI.cxx
+//  Author : Nicolas REJNERI, Open CASCADE S.A.S.
 
-// SMESH SMESHGUI : GUI for SMESH component
-// File   : SMESHGUI.cxx
-// Author : Nicolas REJNERI, Open CASCADE S.A.S.
-// SMESH includes
-//
+//  SMESH includes
 #include "SMESHGUI.h"
 #include "SMESHGUI_AddMeshElementDlg.h"
 #include "SMESHGUI_AddQuadraticElementDlg.h"
@@ -35,7 +34,7 @@
 #include "SMESHGUI_CreatePolyhedralVolumeDlg.h"
 #include "SMESHGUI_DeleteGroupDlg.h"
 #include "SMESHGUI_Displayer.h"
-#include "SMESHGUI_EditMeshDlg.h"
+#include "SMESHGUI_MergeDlg.h"
 #include "SMESHGUI_ExtrusionAlongPathDlg.h"
 #include "SMESHGUI_ExtrusionDlg.h"
 #include "SMESHGUI_FileInfoDlg.h"
@@ -53,7 +52,6 @@
 #include "SMESHGUI_MeshOp.h"
 #include "SMESHGUI_MeshOrderOp.h"
 #include "SMESHGUI_MeshPatternDlg.h"
-#include "SMESHGUI_MoveNodesDlg.h"
 #include "SMESHGUI_MultiEditDlg.h"
 #include "SMESHGUI_NodesDlg.h"
 #include "SMESHGUI_Preferences_ColorDlg.h"
@@ -73,6 +71,7 @@
 #include "SMESHGUI_ScaleDlg.h"
 #include "SMESHGUI_TransparencyDlg.h"
 #include "SMESHGUI_WhatIsDlg.h"
+#include "SMESHGUI_DuplicateNodesDlg.h"
 
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_MeshUtils.h"
 #include <Standard_ErrorHandler.hxx>
 #include <NCollection_DataMap.hxx>
 
+//To disable automatic genericobj management, the following line should be commented.
+//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
+#define WITHGENERICOBJ
+
 //namespace{
   // Declarations
   //=============================================================
             aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" );
             if ( theCommandID == 112 ) // mesh names aren't taken from the file for UNV import
               SMESH::SetName( aMeshSO, QFileInfo(filename).fileName() );
+
+#ifdef WITHGENERICOBJ
+            // obj has been published in study. Its refcount has been incremented.
+            // It is safe to decrement its refcount
+            // so that it will be destroyed when the entry in study will be removed
+            aMeshes[i]->Destroy();
+#endif
           }
           else {
             isEmpty = true;
 
     // actually, the following condition can't be met (added for insurance)
     if( selected.Extent() == 0 ||
-        selected.Extent() > 1 && theCommandID != 122 && theCommandID != 125 )
+        ( selected.Extent() > 1 && theCommandID != 122 && theCommandID != 125 ) )
       return;
 
     bool hasDuplicatedMeshNames = false;
         SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
         (new SMESHGUI_TransparencyDlg( SMESHGUI::GetSMESHGUI() ))->show();
         return;
-      }}
-      SALOME_ListIteratorOfListIO It( selected );
-      for( ; It.More(); It.Next()){
-        Handle(SALOME_InteractiveObject) IObject = It.Value();
-        if(IObject->hasEntry()){
-          if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
-            switch(theCommandID){
-            case 211:
-              anActor->SetRepresentation(SMESH_Actor::eEdge);
-              break;
-            case 212:
-              anActor->SetRepresentation(SMESH_Actor::eSurface);
-              break;
-            case 213:
-              if(anActor->IsShrunk())
-                anActor->UnShrink();
-              else
-                anActor->SetShrink();
-              break;
-            case 215:
-              anActor->SetRepresentation(SMESH_Actor::ePoint);
-              break;
-            case 231:
-              if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eLines)
-                anActor->SetQuadratic2DRepresentation(SMESH_Actor::eLines);
-              break;
-            case 232:
-              if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eArcs)
-                anActor->SetQuadratic2DRepresentation(SMESH_Actor::eArcs);
-              break;
-            case 1132:{
+      }
+      case 1132:{
+        QColor c, e, b, n, c0D, o;
+        int size0D = 0;
+        int Edgewidth = 0;
+        vtkFloatingPointType Shrink = 0.0;
+        vtkFloatingPointType faces_orientation_scale = 0.0;
+        bool faces_orientation_3dvectors = false;
+
+        VTK::MarkerType aMarkerTypeCurrent = VTK::MT_NONE;
+        VTK::MarkerScale aMarkerScaleCurrent = VTK::MS_NONE;
+        int aMarkerTextureCurrent = 0;
+
+        SALOME_ListIteratorOfListIO It( selected );
+        for( ; It.More(); It.Next()){
+          Handle(SALOME_InteractiveObject) IObject = It.Value();
+          if(IObject->hasEntry()){
+            if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
               vtkFloatingPointType color[3];
               anActor->GetSufaceColor(color[0], color[1], color[2]);
               int c0 = int (color[0] * 255);
               int c1 = int (color[1] * 255);
               int c2 = int (color[2] * 255);
-              QColor c(c0, c1, c2);
+              c.setRgb(c0, c1, c2);
 
               vtkFloatingPointType edgecolor[3];
               anActor->GetEdgeColor(edgecolor[0], edgecolor[1], edgecolor[2]);
               c0 = int (edgecolor[0] * 255);
               c1 = int (edgecolor[1] * 255);
               c2 = int (edgecolor[2] * 255);
-              QColor e(c0, c1, c2);
+              e.setRgb(c0, c1, c2);
 
               vtkFloatingPointType backfacecolor[3];
               anActor->GetBackSufaceColor(backfacecolor[0], backfacecolor[1], backfacecolor[2]);
               c0 = int (backfacecolor[0] * 255);
               c1 = int (backfacecolor[1] * 255);
               c2 = int (backfacecolor[2] * 255);
-              QColor b(c0, c1, c2);
+              b.setRgb(c0, c1, c2);
 
               vtkFloatingPointType nodecolor[3];
               anActor->GetNodeColor(nodecolor[0], nodecolor[1], nodecolor[2]);
               c0 = int (nodecolor[0] * 255);
               c1 = int (nodecolor[1] * 255);
               c2 = int (nodecolor[2] * 255);
-              QColor n(c0, c1, c2);
+              n.setRgb(c0, c1, c2);
 
               vtkFloatingPointType color0D[3];
               anActor->Get0DColor(color0D[0], color0D[1], color0D[2]);
               c0 = int (color0D[0] * 255);
               c1 = int (color0D[1] * 255);
               c2 = int (color0D[2] * 255);
-              QColor c0D(c0, c1, c2);
+              c0D.setRgb(c0, c1, c2);
 
-              int size0D = (int)anActor->Get0DSize();
+              size0D = (int)anActor->Get0DSize();
               if(size0D == 0)
                 size0D = 1;
-              int Edgewidth = (int)anActor->GetLineWidth();
+              Edgewidth = (int)anActor->GetLineWidth();
               if(Edgewidth == 0)
                 Edgewidth = 1;
-              vtkFloatingPointType Shrink = anActor->GetShrinkFactor();
+              Shrink = anActor->GetShrinkFactor();
 
               vtkFloatingPointType faces_orientation_color[3];
               anActor->GetFacesOrientationColor(faces_orientation_color);
               c0 = int (faces_orientation_color[0] * 255);
               c1 = int (faces_orientation_color[1] * 255);
               c2 = int (faces_orientation_color[2] * 255);
-              QColor o(c0, c1, c2);
-
-              vtkFloatingPointType faces_orientation_scale = anActor->GetFacesOrientationScale();
-              bool faces_orientation_3dvectors = anActor->GetFacesOrientation3DVectors();
-
-              SMESHGUI_Preferences_ColorDlg *aDlg =
-                new SMESHGUI_Preferences_ColorDlg( SMESHGUI::GetSMESHGUI() );
-              aDlg->SetColor(1, c);
-              aDlg->SetColor(2, e);
-              aDlg->SetColor(3, n);
-              aDlg->SetColor(4, b);
-              aDlg->SetColor(5, c0D);
-              aDlg->SetColor(6, o);
-              aDlg->SetIntValue(1, Edgewidth);
-              aDlg->SetIntValue(2, int(Shrink*100.));
-              aDlg->SetIntValue(3, size0D);
-              aDlg->SetDoubleValue(1, faces_orientation_scale);
-              aDlg->SetBooleanValue(1, faces_orientation_3dvectors);
-
-              aDlg->setCustomMarkerMap( theMarkerMap[ aStudy->StudyId() ] );
-
-              VTK::MarkerType aMarkerTypeCurrent = anActor->GetMarkerType();
-              VTK::MarkerScale aMarkerScaleCurrent = anActor->GetMarkerScale();
-              int aMarkerTextureCurrent = anActor->GetMarkerTexture();
-              if( aMarkerTypeCurrent != VTK::MT_USER )
-                aDlg->setStandardMarker( aMarkerTypeCurrent, aMarkerScaleCurrent );
-              else
-                aDlg->setCustomMarker( aMarkerTextureCurrent );
-
-              if(aDlg->exec()){
-                QColor color = aDlg->GetColor(1);
-                QColor edgecolor = aDlg->GetColor(2);
-                QColor nodecolor = aDlg->GetColor(3);
-                QColor backfacecolor = aDlg->GetColor(4);
-                QColor color0D = aDlg->GetColor(5);
-                QColor faces_orientation_color = aDlg->GetColor(6);
+              o.setRgb(c0, c1, c2);
+
+              faces_orientation_scale = anActor->GetFacesOrientationScale();
+              faces_orientation_3dvectors = anActor->GetFacesOrientation3DVectors();
+
+              aMarkerTypeCurrent = anActor->GetMarkerType();
+              aMarkerScaleCurrent = anActor->GetMarkerScale();
+              aMarkerTextureCurrent = anActor->GetMarkerTexture();
+
+              // even if there are multiple objects in the selection,
+              // we need only the first one to get values for the dialog
+              break;
+            }
+          }
+        }
+
+        SMESHGUI_Preferences_ColorDlg *aDlg =
+          new SMESHGUI_Preferences_ColorDlg( SMESHGUI::GetSMESHGUI() );
+        aDlg->SetColor(1, c);
+        aDlg->SetColor(2, e);
+        aDlg->SetColor(3, n);
+        aDlg->SetColor(4, b);
+        aDlg->SetColor(5, c0D);
+        aDlg->SetColor(6, o);
+        aDlg->SetIntValue(1, Edgewidth);
+        aDlg->SetIntValue(2, int(Shrink*100.));
+        aDlg->SetIntValue(3, size0D);
+        aDlg->SetDoubleValue(1, faces_orientation_scale);
+        aDlg->SetBooleanValue(1, faces_orientation_3dvectors);
+        aDlg->setCustomMarkerMap( theMarkerMap[ aStudy->StudyId() ] );
+
+        if( aMarkerTypeCurrent != VTK::MT_USER )
+          aDlg->setStandardMarker( aMarkerTypeCurrent, aMarkerScaleCurrent );
+        else
+          aDlg->setCustomMarker( aMarkerTextureCurrent );
+
+        if(aDlg->exec()){
+          QColor color = aDlg->GetColor(1);
+          QColor edgecolor = aDlg->GetColor(2);
+          QColor nodecolor = aDlg->GetColor(3);
+          QColor backfacecolor = aDlg->GetColor(4);
+          QColor color0D = aDlg->GetColor(5);
+          QColor faces_orientation_color = aDlg->GetColor(6);
+
+          /* Point marker */
+          theMarkerMap[ aStudy->StudyId() ] = aDlg->getCustomMarkerMap();
+
+          SALOME_ListIteratorOfListIO It( selected );
+          for( ; It.More(); It.Next()){
+            Handle(SALOME_InteractiveObject) IObject = It.Value();
+            if(IObject->hasEntry()){
+              if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
                 /* actor color and backface color */
                 anActor->SetSufaceColor(vtkFloatingPointType (color.red()) / 255.,
                                         vtkFloatingPointType (color.green()) / 255.,
                 anActor->SetFacesOrientationScale(aDlg->GetDoubleValue(1));
                 anActor->SetFacesOrientation3DVectors(aDlg->GetBooleanValue(1));
 
-                /* Point marker */
-                theMarkerMap[ aStudy->StudyId() ] = aDlg->getCustomMarkerMap();
-
                 VTK::MarkerType aMarkerTypeNew = aDlg->getMarkerType();
                 VTK::MarkerScale aMarkerScaleNew = aDlg->getStandardMarkerScale();
                 int aMarkerTextureNew = aDlg->getCustomMarkerID();
                   aGroupColor.B = (float)aColor.blue() / 255.0;
                   aGroupObject->SetColor( aGroupColor );
                 }
-
-                delete aDlg;
               }
+            }
+          }
+          SMESH::RepaintCurrentView();
+        }
+        delete aDlg;
+        return;
+      }
+      }
+      SALOME_ListIteratorOfListIO It( selected );
+      for( ; It.More(); It.Next()){
+        Handle(SALOME_InteractiveObject) IObject = It.Value();
+        if(IObject->hasEntry()){
+          if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
+            switch(theCommandID){
+            case 211:
+              anActor->SetRepresentation(SMESH_Actor::eEdge);
+              break;
+            case 212:
+              anActor->SetRepresentation(SMESH_Actor::eSurface);
+              break;
+            case 213:
+              if(anActor->IsShrunk())
+                anActor->UnShrink();
+              else
+                anActor->SetShrink();
+              break;
+            case 215:
+              anActor->SetRepresentation(SMESH_Actor::ePoint);
+              break;
+            case 231:
+              if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eLines)
+                anActor->SetQuadratic2DRepresentation(SMESH_Actor::eLines);
+              break;
+            case 232:
+              if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eArcs)
+                anActor->SetQuadratic2DRepresentation(SMESH_Actor::eArcs);
               break;
-            }}
+            }
           }
         }
       }
@@ -1300,7 +1345,9 @@ LightApp_Module( "SMESH" )
 //=============================================================================
 SMESHGUI::~SMESHGUI()
 {
+#ifdef WITHGENERICOBJ
   SMESH::GetFilterManager()->Destroy();
+#endif
   SMESH::GetFilterManager() = SMESH::FilterManager::_nil();
 }
 
@@ -1483,6 +1530,22 @@ SalomeApp_Study* SMESHGUI::activeStudy()
     return NULL;
 }
 
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+void SMESHGUI::Modified( bool theIsUpdateActions )
+{
+  if( SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() ) ) {
+    if( SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() ) ) {
+      appStudy->Modified();
+      if( theIsUpdateActions )
+        app->updateActions();
+    }
+  }
+}
+
 //=============================================================================
 /*!
  *
@@ -1650,7 +1713,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case 232:
     ::SetDisplayMode(theCommandID, myMarkerMap);
   break;
-  
+
   // Display Entity
   case 216: // 0D elements
   case 217: // Edges
@@ -1757,7 +1820,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       }
       else
         aSel->setSelectedObjects( to_process );
-      
+
       break;
     }
 
@@ -1788,20 +1851,6 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     break;
   }
 
-  case 406:                                     // MOVE NODE
-    {
-      if ( !vtkwnd )
-      {
-        SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ),
-                                  tr( "NOT_A_VTK_VIEWER" ) );
-        break;
-      }
-
-      if(checkLock(aStudy)) break;
-      ( new SMESHGUI_MoveNodesDlg( this ) )->show();
-      break;
-    }
-
   case 701:                                     // COMPUTE MESH
   case 711:                                     // PRECOMPUTE MESH
   case 712:                                     // EVALUATE MESH
@@ -2553,6 +2602,44 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
     updateObjBrowser();
     break;
   }
+  case 4044:                                     // REMOVE ORPHAN NODES
+    {
+      if(checkLock(aStudy)) break;
+      SALOME_ListIO selected;
+      if( LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr() )
+        aSel->selectedObjects( selected );
+      if ( selected.Extent() == 1 ) {
+        Handle(SALOME_InteractiveObject) anIO = selected.First();
+        SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(anIO);
+        if ( !aMesh->_is_nil() ) {
+          bool confirm = SUIT_MessageBox::question( SMESHGUI::desktop(),
+                                                    tr( "SMESH_WARNING" ),
+                                                    tr( "REMOVE_ORPHAN_NODES_QUESTION"),
+                                                    SUIT_MessageBox::Yes |
+                                                    SUIT_MessageBox::No,
+                                                    SUIT_MessageBox::No ) == SUIT_MessageBox::Yes;
+          if( confirm ) {
+            try {
+              SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
+              int removed = aMeshEditor->RemoveOrphanNodes();
+              SUIT_MessageBox::information(SMESHGUI::desktop(),
+                                           tr("SMESH_INFORMATION"),
+                                           tr("NB_NODES_REMOVED").arg(removed));
+              if ( removed > 0 ) {
+                SMESH::UpdateView();
+                SMESHGUI::Modified();
+              }
+            }
+            catch (const SALOME::SALOME_Exception& S_ex) {
+              SalomeApp_Tools::QtCatchCorbaException(S_ex);
+            } 
+            catch (...) {
+            }
+          }
+        }
+      }
+      break;
+    }
   case 4051:                                    // RENUMBERING NODES
     {
       if(checkLock(aStudy)) break;
@@ -2638,7 +2725,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       if(checkLock(aStudy)) break;
       if(vtkwnd) {
         EmitSignalDeactivateDialog();
-        ( new SMESHGUI_EditMeshDlg( this, 0 ) )->show();
+        ( new SMESHGUI_MergeDlg( this, 0 ) )->show();
       }
       else {
         SUIT_MessageBox::warning(SMESHGUI::desktop(),
@@ -2651,7 +2738,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       if (checkLock(aStudy)) break;
       if (vtkwnd) {
         EmitSignalDeactivateDialog();
-        ( new SMESHGUI_EditMeshDlg( this, 1 ) )->show();
+        ( new SMESHGUI_MergeDlg( this, 1 ) )->show();
       } else {
         SUIT_MessageBox::warning(SMESHGUI::desktop(),
                                  tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
@@ -2677,6 +2764,20 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       break;
     }
 
+  case 4069: // DUPLICATE NODES
+    {
+      if(checkLock(aStudy)) break;
+      if ( vtkwnd ) {
+        EmitSignalDeactivateDialog();
+        ( new SMESHGUI_DuplicateNodesDlg( this ) )->show();
+      }
+      else {
+        SUIT_MessageBox::warning(SMESHGUI::desktop(),
+                                 tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"));
+      }
+      break;
+    }
+
   case 5105: // Library of selection filters
   {
     static QList<int> aTypes;
@@ -2761,8 +2862,9 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       LightApp_SelectionMgr* mgr = selectionMgr();
       SALOME_ListIO selected; mgr->selectedObjects( selected );
 
-      if (selected.Extent() == 1)       {
-        Handle(SALOME_InteractiveObject) anIObject = selected.First();
+      SALOME_ListIteratorOfListIO it(selected);
+      for( ; it.More(); it.Next()) {
+        Handle(SALOME_InteractiveObject) anIObject = it.Value();
         if(anIObject->hasEntry())
           if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){
             anActor->SetCellsLabeled( !anActor->GetCellsLabeled() );
@@ -2825,7 +2927,8 @@ void SMESHGUI::BuildPresentation( const Handle(SALOME_InteractiveObject) & theIO
 // function : createSMESHAction
 // purpose  :
 //=======================================================================
-void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QString& icon_id, const int key, const bool toggle  )
+void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QString& icon_id, 
+                                  const int key, const bool toggle, const QString& shortcutAction  )
 {
   QIcon icon;
   QWidget* parent = application()->desktop();
@@ -2842,7 +2945,8 @@ void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QStr
           menu       = tr( QString( "MEN_%1" ).arg( po_id ).toLatin1().data() ),
           status_bar = tr( QString( "STB_%1" ).arg( po_id ).toLatin1().data() );
 
-  createAction( id, tooltip, icon, menu, status_bar, key, parent, toggle, this, SLOT( OnGUIEvent() )  );
+  createAction( id, tooltip, icon, menu, status_bar, key, parent, 
+                toggle, this, SLOT( OnGUIEvent() ), shortcutAction );
 }
 
 //=======================================================================
@@ -2961,6 +3065,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( 4032, "HEXA",            "ICON_DLG_HEXAS" );
   createSMESHAction( 4041, "REMOVE_NODES",    "ICON_DLG_REM_NODE" );
   createSMESHAction( 4042, "REMOVE_ELEMENTS", "ICON_DLG_REM_ELEMENT" );
+  createSMESHAction( 4044, "REMOVE_ORPHAN_NODES", "ICON_DLG_REM_ORPHAN_NODES" );
   createSMESHAction( 4043, "CLEAR_MESH"    ,  "ICON_CLEAR_MESH" );
   createSMESHAction( 4051, "RENUM_NODES",     "ICON_DLG_RENUMBERING_NODES" );
   createSMESHAction( 4052, "RENUM_ELEMENTS",  "ICON_DLG_RENUMBERING_ELEMENTS" );
@@ -2970,9 +3075,9 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( 4064, "SEW",             "ICON_SMESH_SEWING_FREEBORDERS" );
   createSMESHAction( 4065, "MERGE",           "ICON_SMESH_MERGE_NODES" );
   createSMESHAction( 4066, "MERGE_ELEMENTS",  "ICON_DLG_MERGE_ELEMENTS" );
-  createSMESHAction( 4067, "MESH_THROU_POINT","ICON_DLG_MESH_THROU_POINT" );
+  createSMESHAction( 4067, "MESH_THROU_POINT","ICON_DLG_MOVE_NODE" );
   createSMESHAction( 4068, "SCALE",           "ICON_DLG_MESH_SCALE" );
-  createSMESHAction(  406, "MOVE",            "ICON_DLG_MOVE_NODE" );
+  createSMESHAction( 4069, "DUPLICATE_NODES", "ICON_SMESH_DUPLICATE_NODES" );
   createSMESHAction(  407, "INV",             "ICON_DLG_MESH_DIAGONAL" );
   createSMESHAction(  408, "UNION2",          "ICON_UNION2TRI" );
   createSMESHAction(  409, "ORIENT",          "ICON_DLG_MESH_ORIENTATION" );
@@ -3132,6 +3237,8 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   createMenu( 4041, removeId, -1 );
   createMenu( 4042, removeId, -1 );
+  createMenu( 4044, removeId, -1 );
+  createMenu( separator(), removeId, -1 );
   createMenu( 4043, removeId, -1 );
 
   createMenu( 4051, renumId, -1 );
@@ -3144,8 +3251,8 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 4065, transfId, -1 );
   createMenu( 4066, transfId, -1 );
   createMenu( 4068, transfId, -1 );
+  createMenu( 4069, transfId, -1 );
 
-  createMenu( 406, modifyId, -1 );
   createMenu( 4067,modifyId, -1 );
   createMenu( 407, modifyId, -1 );
   createMenu( 408, modifyId, -1 );
@@ -3232,6 +3339,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( separator(), addRemTb );
   createTool( 4041, addRemTb );
   createTool( 4042, addRemTb );
+  createTool( 4044, addRemTb );
   createTool( 4043, addRemTb );
   createTool( separator(), addRemTb );
   createTool( 4051, addRemTb );
@@ -3244,9 +3352,9 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( 4065, addRemTb );
   createTool( 4066, addRemTb );
   createTool( 4068, addRemTb );
+  createTool( 4069, addRemTb );
   createTool( separator(), addRemTb );
 
-  createTool( 406, modifyTb );
   createTool( 4067,modifyTb );
   createTool( 407, modifyTb );
   createTool( 408, modifyTb );
@@ -3440,12 +3548,12 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   //-------------------------------------------------
   // Representation of the 2D Quadratic elements
-  //-------------------------------------------------  
+  //-------------------------------------------------
   anId = popupMgr()->insert( tr( "MEN_QUADRATIC_REPRESENT" ), -1, -1 );
   popupMgr()->insert( action( 231 ), anId, -1 ); // LINE REPRESENTATION
   popupMgr()->setRule( action( 231 ), aMeshInVTK + "and isVisible",QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 231 ), "quadratic2DMode = 'eLines'", QtxPopupMgr::ToggleRule );
-  
+
   popupMgr()->insert( action( 232 ), anId, -1 ); // ARC REPRESENTATION
   popupMgr()->setRule( action( 232 ), aMeshInVTK + "and isVisible", QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 232 ), "quadratic2DMode = 'eArcs'", QtxPopupMgr::ToggleRule );
@@ -3487,7 +3595,7 @@ void SMESHGUI::initialize( CAM_Application* app )
     aMeshInVtkHasVolumes = aMeshInVTK + "&&" + hasVolumes;
 
   anId = popupMgr()->insert( tr( "MEN_CTRL" ), -1, -1 );
-  
+
   popupMgr()->insert( action( 200 ), anId, -1 ); // RESET
   popupMgr()->setRule( action( 200 ), aMeshInVTK + "&& controlMode <> 'eNone'", QtxPopupMgr::VisibleRule );
 
@@ -3568,7 +3676,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->setRule( action( 201 ), aMeshInVTK + "&& controlMode <> 'eNone'", QtxPopupMgr::VisibleRule );
 
   popupMgr()->insert( separator(), -1, -1 );
-  
+
   //-------------------------------------------------
   // Display / Erase
   //-------------------------------------------------
@@ -3618,7 +3726,7 @@ bool SMESHGUI::reusableOperation( const int id )
 {
   // compute, evaluate and precompute are not reusable operations
   return ( id == 701 || id == 711 || id == 712 ) ? false : SalomeApp_Module::reusableOperation( id );
-} 
+}
 
 bool SMESHGUI::activateModule( SUIT_Study* study )
 {
@@ -3791,8 +3899,8 @@ void SMESHGUI::createPreferences()
                               "SMESH", "max_angle" );
   setPreferenceProperty( maxAngle, "min", 1 );
   setPreferenceProperty( maxAngle, "max", 90 );
-  
-  
+
+
 
   int exportgroup = addPreference( tr( "PREF_GROUP_EXPORT" ), genTab );
   setPreferenceProperty( exportgroup, "columns", 2 );
@@ -3823,15 +3931,15 @@ void SMESHGUI::createPreferences()
                              "SMESH", "nb_segments_per_edge" );
   setPreferenceProperty( nbSeg, "min", 1 );
   setPreferenceProperty( nbSeg, "max", 10000000 );
-  
+
   // Quantities with individual precision settings
   int precGroup = addPreference( tr( "SMESH_PREF_GROUP_PRECISION" ), genTab );
   setPreferenceProperty( precGroup, "columns", 2 );
-  
+
   const int nbQuantities = 6;
   int precs[nbQuantities], ii = 0;
   precs[ii++] = addPreference( tr( "SMESH_PREF_length_precision" ), precGroup,
-                            LightApp_Preferences::IntSpin, "SMESH", "length_precision" );  
+                            LightApp_Preferences::IntSpin, "SMESH", "length_precision" );
   precs[ii++] = addPreference( tr( "SMESH_PREF_angle_precision" ), precGroup,
                             LightApp_Preferences::IntSpin, "SMESH", "angle_precision" );
   precs[ii++] = addPreference( tr( "SMESH_PREF_len_tol_precision" ), precGroup,
@@ -3841,14 +3949,14 @@ void SMESHGUI::createPreferences()
   precs[ii++] = addPreference( tr( "SMESH_PREF_area_precision" ), precGroup,
                             LightApp_Preferences::IntSpin, "SMESH", "area_precision" );
   precs[ii  ] = addPreference( tr( "SMESH_PREF_vol_precision" ), precGroup,
-                            LightApp_Preferences::IntSpin, "SMESH", "vol_precision" );  
-  
+                            LightApp_Preferences::IntSpin, "SMESH", "vol_precision" );
+
   // Set property for precision value for spinboxes
   for ( ii = 0; ii < nbQuantities; ii++ ){
-    setPreferenceProperty( precs[ii], "min", -10 );
-    setPreferenceProperty( precs[ii], "max", 10 );
+    setPreferenceProperty( precs[ii], "min", -14 );
+    setPreferenceProperty( precs[ii], "max", 14 );
     setPreferenceProperty( precs[ii], "precision", 2 );
-  }   
+  }
 
   // Mesh tab ------------------------------------------------------------------------
   int meshTab = addPreference( tr( "PREF_TAB_MESH" ) );
@@ -3890,6 +3998,11 @@ void SMESHGUI::createPreferences()
   addPreference( tr( "PREF_BACKFACE" ), elemGroup, LightApp_Preferences::Color, "SMESH", "backface_color" );
   addPreference( tr( "PREF_COLOR_0D" ), elemGroup, LightApp_Preferences::Color, "SMESH", "elem0d_color" );
 
+  int grpGroup = addPreference( tr( "PREF_GROUP_GROUPS" ), meshTab );
+  setPreferenceProperty( grpGroup, "columns", 2 );
+
+  addPreference( tr( "PREF_GRP_NAMES" ), grpGroup, LightApp_Preferences::Color, "SMESH", "group_name_color" );
+
   //int sp = addPreference( "", elemGroup, LightApp_Preferences::Space );
   //setPreferenceProperty( sp, "hstretch", 0 );
   //setPreferenceProperty( sp, "vstretch", 0 );
@@ -4847,7 +4960,7 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
 int SMESHGUI::addVtkFontPref( const QString& label, const int pId, const QString& param )
 {
   int tfont = addPreference( label, pId, LightApp_Preferences::Font, "VISU", param );
-  
+
   setPreferenceProperty( tfont, "mode", QtxFontEdit::Custom );
 
   QStringList fam;
@@ -4869,5 +4982,7 @@ int SMESHGUI::addVtkFontPref( const QString& label, const int pId, const QString
 */
 void SMESHGUI::onHypothesisEdit( int result )
 {
+  if( result == 1 )
+    SMESHGUI::Modified();
   updateObjBrowser( true );
 }