Salome HOME
Merge from V5_1_4_BR 07/05/2010
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_EditMeshDlg.cxx
index 935f18bae88862690652cbe04a85b5119aa85f75..5405ec451a8753c244d31351b5d90df1b1217c3e 100644 (file)
+//  Copyright (C) 2007-2010  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
+//
+//  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 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
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
 
+// SMESH SMESHGUI : GUI for SMESH component
+// File   : SMESHGUI_EditMeshDlg.cxx
+// Author : Open CASCADE S.A.S.
+// SMESH includes
+//
 #include "SMESHGUI_EditMeshDlg.h"
 
 #include "SMESHGUI.h"
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_SpinBox.h"
 
-#include "SMESH_TypeFilter.hxx"
+#include <SMESH_Actor.h>
+#include <SMESH_TypeFilter.hxx>
+#include <SMESH_LogicalFilter.hxx>
+#include <SMDS_Mesh.hxx>
 
-#include "SUIT_Desktop.h"
-#include "SUIT_Session.h"
+// SALOME GUI includes
+#include <SUIT_Desktop.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
 
-#include "SALOME_ListIO.hxx"
+#include <LightApp_Application.h>
+#include <LightApp_SelectionMgr.h>
 
-#include "utilities.h"
+#include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
+#include <SALOME_ListIO.hxx>
 
-// QT Includes
-#include <qapplication.h>
-#include <qbuttongroup.h>
-#include <qgroupbox.h>
-#include <qlabel.h>
-#include <qlineedit.h>
-#include <qpushbutton.h>
-#include <qradiobutton.h>
-#include <qlayout.h>
-#include <qpixmap.h>
+// OCCT includes
+#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_MapIteratorOfMapOfInteger.hxx>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
+// VTK includes
+#include <vtkUnstructuredGrid.h>
+#include <vtkRenderer.h>
+#include <vtkActor2D.h>
+#include <vtkPoints.h>
+#include <vtkDataSetMapper.h>
+#include <vtkMaskPoints.h>
+#include <vtkSelectVisiblePoints.h>
+#include <vtkLabeledDataMapper.h>
+#include <vtkTextProperty.h>
+#include <vtkIntArray.h>
+#include <vtkProperty2D.h>
+#include <vtkPointData.h>
+#include <vtkConfigure.h>
+#if !defined(VTK_XVERSION)
+#define VTK_XVERSION (VTK_MAJOR_VERSION<<16)+(VTK_MINOR_VERSION<<8)+(VTK_BUILD_VERSION)
+#endif
+
+// Qt includes
+#include <QApplication>
+#include <QGroupBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QListWidget>
+#include <QPushButton>
+#include <QRadioButton>
+#include <QCheckBox>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QGridLayout>
+#include <QKeyEvent>
+#include <QButtonGroup>
+
+#define SPACING 6
+#define MARGIN  11
+
+namespace SMESH
+{
+  class TIdPreview
+  { // to display in the viewer IDs of the selected elements
+    SVTK_ViewWindow* myViewWindow;
+
+    vtkUnstructuredGrid* myIdGrid;
+    SALOME_Actor* myIdActor;
+
+    vtkUnstructuredGrid* myPointsNumDataSet;
+    vtkMaskPoints* myPtsMaskPoints;
+    vtkSelectVisiblePoints* myPtsSelectVisiblePoints;
+    vtkLabeledDataMapper* myPtsLabeledDataMapper;
+    vtkTextProperty* aPtsTextProp;
+    bool myIsPointsLabeled;
+    vtkActor2D* myPointLabels;
+
+    std::vector<int> myIDs;
+
+  public:
+    TIdPreview(SVTK_ViewWindow* theViewWindow):
+      myViewWindow(theViewWindow)
+    {
+      myIdGrid = vtkUnstructuredGrid::New();
+
+      // Create and display actor
+      vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
+      aMapper->SetInput( myIdGrid );
+
+      myIdActor = SALOME_Actor::New();
+      myIdActor->SetInfinitive(true);
+      myIdActor->VisibilityOff();
+      myIdActor->PickableOff();
+
+      myIdActor->SetMapper( aMapper );
+      aMapper->Delete();
+
+      myViewWindow->AddActor(myIdActor);
+
+      //Definition of points numbering pipeline
+      myPointsNumDataSet = vtkUnstructuredGrid::New();
+
+      myPtsMaskPoints = vtkMaskPoints::New();
+      myPtsMaskPoints->SetInput(myPointsNumDataSet);
+      myPtsMaskPoints->SetOnRatio(1);
+
+      myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New();
+      myPtsSelectVisiblePoints->SetInput(myPtsMaskPoints->GetOutput());
+      myPtsSelectVisiblePoints->SelectInvisibleOff();
+      myPtsSelectVisiblePoints->SetTolerance(0.1);
+    
+      myPtsLabeledDataMapper = vtkLabeledDataMapper::New();
+      myPtsLabeledDataMapper->SetInput(myPtsSelectVisiblePoints->GetOutput());
+#if (VTK_XVERSION < 0x050200)
+      myPtsLabeledDataMapper->SetLabelFormat("%g");
+#endif
+      myPtsLabeledDataMapper->SetLabelModeToLabelScalars();
+    
+      vtkTextProperty* aPtsTextProp = vtkTextProperty::New();
+      aPtsTextProp->SetFontFamilyToTimes();
+      static int aPointsFontSize = 12;
+      aPtsTextProp->SetFontSize(aPointsFontSize);
+      aPtsTextProp->SetBold(1);
+      aPtsTextProp->SetItalic(0);
+      aPtsTextProp->SetShadow(0);
+      myPtsLabeledDataMapper->SetLabelTextProperty(aPtsTextProp);
+      aPtsTextProp->Delete();
+  
+      myIsPointsLabeled = false;
+
+      myPointLabels = vtkActor2D::New();
+      myPointLabels->SetMapper(myPtsLabeledDataMapper);
+      myPointLabels->GetProperty()->SetColor(1,1,1);
+      myPointLabels->SetVisibility(myIsPointsLabeled);
+
+      AddToRender(myViewWindow->getRenderer());
+    }
+
+    void SetPointsData ( SMDS_Mesh* theMesh, 
+                         TColStd_MapOfInteger & theNodesIdMap )
+    {
+      vtkPoints* aPoints = vtkPoints::New();
+      aPoints->SetNumberOfPoints(theNodesIdMap.Extent());
+      myIDs.clear();
+      
+      TColStd_MapIteratorOfMapOfInteger idIter( theNodesIdMap );
+      for( int i = 0; idIter.More(); idIter.Next(), i++ ) {
+        const SMDS_MeshNode* aNode = theMesh->FindNode(idIter.Key());
+        aPoints->SetPoint( i, aNode->X(), aNode->Y(), aNode->Z() );
+        myIDs.push_back(idIter.Key());
+      }
+
+      myIdGrid->SetPoints(aPoints);
+
+      aPoints->Delete();
+
+      myIdActor->GetMapper()->Update();
+    }
+
+    void SetElemsData( TColStd_MapOfInteger & theElemsIdMap, 
+                       std::list<gp_XYZ> & aGrCentersXYZ )
+    {
+      vtkPoints* aPoints = vtkPoints::New();
+      aPoints->SetNumberOfPoints(theElemsIdMap.Extent());
+      myIDs.clear();
+      
+      TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
+      for( ; idIter.More(); idIter.Next() ) {
+        myIDs.push_back(idIter.Key());
+      }
+
+      gp_XYZ aXYZ;
+      std::list<gp_XYZ>::iterator coordIt = aGrCentersXYZ.begin();
+      for( int i = 0; coordIt != aGrCentersXYZ.end(); coordIt++, i++ ) {
+        aXYZ = *coordIt;
+        aPoints->SetPoint( i, aXYZ.X(), aXYZ.Y(), aXYZ.Z() );
+      }
+      myIdGrid->SetPoints(aPoints);
+      aPoints->Delete();
+      
+      myIdActor->GetMapper()->Update();
+    }
+
+    void AddToRender(vtkRenderer* theRenderer)
+    {
+      myIdActor->AddToRender(theRenderer);
+
+      myPtsSelectVisiblePoints->SetRenderer(theRenderer);
+      theRenderer->AddActor2D(myPointLabels);
+    }
+
+    void RemoveFromRender(vtkRenderer* theRenderer)
+    {
+      myIdActor->RemoveFromRender(theRenderer);
+
+      myPtsSelectVisiblePoints->SetRenderer(theRenderer);
+      theRenderer->RemoveActor(myPointLabels);
+    }
+
+    void SetPointsLabeled( bool theIsPointsLabeled, bool theIsActorVisible = true )
+    {
+      myIsPointsLabeled = theIsPointsLabeled && myIdGrid->GetNumberOfPoints();
+      
+      if ( myIsPointsLabeled ) {
+        myPointsNumDataSet->ShallowCopy(myIdGrid);
+        vtkDataSet *aDataSet = myPointsNumDataSet;
+        int aNbElem = myIDs.size();
+        vtkIntArray *anArray = vtkIntArray::New();
+        anArray->SetNumberOfValues( aNbElem );
+        for ( int i = 0; i < aNbElem; i++ )
+          anArray->SetValue( i, myIDs[i] );
+        aDataSet->GetPointData()->SetScalars( anArray );
+        anArray->Delete();
+        myPtsMaskPoints->SetInput( aDataSet );
+        myPointLabels->SetVisibility( theIsActorVisible );
+      }
+      else {
+        myPointLabels->SetVisibility( false );
+      }
+    }
+    
+    ~TIdPreview()
+    {
+      RemoveFromRender(myViewWindow->getRenderer());
+
+      myIdGrid->Delete();
+
+      myViewWindow->RemoveActor(myIdActor);
+      myIdActor->Delete();
+
+      //Deleting of points numbering pipeline
+      //---------------------------------------
+      myPointsNumDataSet->Delete();
+      
+      //myPtsLabeledDataMapper->RemoveAllInputs();        //vtk 5.0 porting
+      myPtsLabeledDataMapper->Delete();
+
+      //myPtsSelectVisiblePoints->UnRegisterAllOutputs(); //vtk 5.0 porting
+      myPtsSelectVisiblePoints->Delete();
+
+      //myPtsMaskPoints->UnRegisterAllOutputs();          //vtk 5.0 porting
+      myPtsMaskPoints->Delete();
+
+      myPointLabels->Delete();
+
+//       myTimeStamp->Delete();
+    }
+  };
+}
+
+static const char * IconFirst[] = {
+"18 10 2 1",
+"       g None",
+".      g #000000",
+"         .     .  ",
+"  ..    ..    ..  ",
+"  ..   ...   ...  ",
+"  ..  ....  ....  ",
+"  .. ..... .....  ",
+"  .. ..... .....  ",
+"  ..  ....  ....  ",
+"  ..   ...   ...  ",
+"  ..    ..    ..  ",
+"         .     .  "};
 
 //=================================================================================
 // class    : SMESHGUI_EditMeshDlg()
 // purpose  :
 //=================================================================================
-SMESHGUI_EditMeshDlg::SMESHGUI_EditMeshDlg (SMESHGUI* theModule,
-                                            const char* title, const char* icon,
+SMESHGUI_EditMeshDlg::SMESHGUI_EditMeshDlg (SMESHGUI* theModule, 
                                             int theAction)
-  : QDialog(SMESH::GetDesktop(theModule), "SMESHGUI_EditMeshDlg", false, WStyle_Customize |
-            WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | Qt::WDestructiveClose),
+  : QDialog(SMESH::GetDesktop(theModule)),
     mySMESHGUI(theModule),
     mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
     myAction(theAction)
 {
-  resize(303, 185);
-  setCaption(tr(title));
+  setModal(false);
+  setAttribute(Qt::WA_DeleteOnClose, true);
+  setWindowTitle(myAction == 1 ? tr("SMESH_MERGE_ELEMENTS") : tr("SMESH_MERGE_NODES"));
 
-  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
-  QPixmap image0 (aResMgr->loadPixmap("SMESH", tr(icon)));
-  QPixmap image1 (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT")));
+  myIdPreview = new SMESH::TIdPreview(SMESH::GetViewWindow( mySMESHGUI ));
 
-  setSizeGripEnabled(TRUE);
-  DlgLayout = new QGridLayout (this);
-  DlgLayout->setSpacing(6);
-  DlgLayout->setMargin(11);
+  SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI );
+  QPixmap IconMergeNodes (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_MERGE_NODES")));
+  QPixmap IconMergeElems (aResMgr->loadPixmap("SMESH", tr("ICON_DLG_MERGE_ELEMENTS")));
+  QPixmap IconSelect     (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT")));
+  QPixmap IconAdd        (aResMgr->loadPixmap("SMESH", tr("ICON_APPEND")));
+  QPixmap IconRemove     (aResMgr->loadPixmap("SMESH", tr("ICON_REMOVE")));
 
-  /***************************************************************/
-  GroupConstructors = new QButtonGroup (this, "GroupConstructors");
-  GroupConstructors->setExclusive(TRUE);
-  GroupConstructors->setColumnLayout(0, Qt::Vertical);
-  GroupConstructors->layout()->setSpacing(0);
-  GroupConstructors->layout()->setMargin(0);
-  GroupConstructorsLayout = new QGridLayout (GroupConstructors->layout());
-  GroupConstructorsLayout->setAlignment(Qt::AlignTop);
-  GroupConstructorsLayout->setSpacing(6);
-  GroupConstructorsLayout->setMargin(11);
-  Constructor1 = new QRadioButton (GroupConstructors, "Constructor1");
-  Constructor1->setText(tr(""));
-  Constructor1->setPixmap(image0);
-  Constructor1->setChecked(TRUE);
-  Constructor1->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)1,
-                                          (QSizePolicy::SizeType)0,
-                                          Constructor1->sizePolicy().hasHeightForWidth()));
-  Constructor1->setMinimumSize(QSize(50, 0));
-  GroupConstructorsLayout->addWidget(Constructor1, 0, 0);
-  QSpacerItem* spacer = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
-  GroupConstructorsLayout->addItem(spacer, 0, 1);
-  DlgLayout->addWidget(GroupConstructors, 0, 0);
+  setSizeGripEnabled(true);
+
+  QVBoxLayout* DlgLayout = new QVBoxLayout(this);
+  DlgLayout->setSpacing(SPACING);
+  DlgLayout->setMargin(MARGIN);
 
   /***************************************************************/
-  GroupButtons = new QGroupBox (this, "GroupButtons");
-  GroupButtons->setGeometry(QRect(10, 10, 281, 48));
-  GroupButtons->setTitle(tr("" ));
-  GroupButtons->setColumnLayout(0, Qt::Vertical);
-  GroupButtons->layout()->setSpacing(0);
-  GroupButtons->layout()->setMargin(0);
-  GroupButtonsLayout = new QGridLayout (GroupButtons->layout());
-  GroupButtonsLayout->setAlignment(Qt::AlignTop);
-  GroupButtonsLayout->setSpacing(6);
-  GroupButtonsLayout->setMargin(11);
-  buttonCancel = new QPushButton (GroupButtons, "buttonCancel");
-  buttonCancel->setText(tr("SMESH_BUT_CLOSE" ));
-  buttonCancel->setAutoDefault(TRUE);
-  GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
-  buttonApply = new QPushButton (GroupButtons, "buttonApply");
-  buttonApply->setText(tr("SMESH_BUT_APPLY" ));
-  buttonApply->setAutoDefault(TRUE);
-  GroupButtonsLayout->addWidget(buttonApply, 0, 1);
-  QSpacerItem* spacer_9 = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
-  GroupButtonsLayout->addItem(spacer_9, 0, 2);
-  buttonOk = new QPushButton (GroupButtons, "buttonOk");
-  buttonOk->setText(tr("SMESH_BUT_OK" ));
-  buttonOk->setAutoDefault(TRUE);
-  buttonOk->setDefault(TRUE);
-  GroupButtonsLayout->addWidget(buttonOk, 0, 0);
-  DlgLayout->addWidget(GroupButtons, 2, 0);
+  GroupConstructors = new QGroupBox(myAction == 1 ? 
+                                    tr("SMESH_MERGE_ELEMENTS") : 
+                                    tr("SMESH_MERGE_NODES"), 
+                                    this);
+
+  QButtonGroup* ButtonGroup = new QButtonGroup(this);
+  QHBoxLayout* GroupConstructorsLayout = new QHBoxLayout(GroupConstructors);
+  GroupConstructorsLayout->setSpacing(SPACING);
+  GroupConstructorsLayout->setMargin(MARGIN);
+
+  RadioButton = new QRadioButton(GroupConstructors);
+  RadioButton->setIcon(myAction == 1 ? IconMergeElems : IconMergeNodes);
+  RadioButton->setChecked(true);
+  GroupConstructorsLayout->addWidget(RadioButton);
+  ButtonGroup->addButton(RadioButton, 0);
 
   /***************************************************************/
-  GroupMesh = new QGroupBox (this, "GroupMesh");
-  GroupMesh->setTitle(tr("SMESH_MESH" ));
-  GroupMesh->setMinimumSize(QSize(0, 0));
-  GroupMesh->setFrameShape(QGroupBox::Box);
-  GroupMesh->setFrameShadow(QGroupBox::Sunken);
-  GroupMesh->setColumnLayout(0, Qt::Vertical);
-  GroupMesh->layout()->setSpacing(0);
-  GroupMesh->layout()->setMargin(0);
-  GroupMeshLayout = new QGridLayout (GroupMesh->layout());
-  GroupMeshLayout->setAlignment(Qt::AlignTop);
-  GroupMeshLayout->setSpacing(6);
-  GroupMeshLayout->setMargin(11);
-  TextLabelMesh = new QLabel (GroupMesh, "TextLabelMesh");
-  TextLabelMesh->setText(tr("SMESH_MESH"));
-  TextLabelMesh->setMinimumSize(QSize(50, 0));
-  TextLabelMesh->setFrameShape(QLabel::NoFrame);
-  TextLabelMesh->setFrameShadow(QLabel::Plain);
-  GroupMeshLayout->addWidget(TextLabelMesh, 0, 0);
-  SelectButton = new QPushButton (GroupMesh, "SelectButton");
-  SelectButton->setText(tr(""));
-  SelectButton->setPixmap(image1);
-  SelectButton->setToggleButton(FALSE);
-  GroupMeshLayout->addWidget(SelectButton, 0, 1);
-  LineEditMesh = new QLineEdit (GroupMesh, "LineEditMesh");
+  // Controls for mesh defining
+  GroupMesh = new QGroupBox(tr("SMESH_SELECT_WHOLE_MESH"), this);
+  QHBoxLayout* GroupMeshLayout = new QHBoxLayout(GroupMesh);
+  GroupMeshLayout->setSpacing(SPACING);
+  GroupMeshLayout->setMargin(MARGIN);
+
+  TextLabelName = new QLabel(tr("SMESH_NAME"), GroupMesh);
+  SelectMeshButton = new QPushButton(GroupMesh);
+  SelectMeshButton->setIcon(IconSelect);
+  LineEditMesh = new QLineEdit(GroupMesh);
   LineEditMesh->setReadOnly(true);
-  GroupMeshLayout->addWidget(LineEditMesh, 0, 2);
-  DlgLayout->addWidget(GroupMesh, 1, 0);
+
+  GroupMeshLayout->addWidget(TextLabelName);
+  GroupMeshLayout->addWidget(SelectMeshButton);
+  GroupMeshLayout->addWidget(LineEditMesh);
+
+  /***************************************************************/
+  // Controls for switch dialog behaviour
+
+  TypeBox = new QGroupBox( tr( "SMESH_MODE" ), this );
+  GroupType = new QButtonGroup( this );
+  QHBoxLayout* aTypeBoxLayout = new QHBoxLayout( TypeBox );
+  aTypeBoxLayout->setMargin( MARGIN );
+  aTypeBoxLayout->setSpacing( SPACING );
+
+  QRadioButton* rb1 = new QRadioButton( tr( "SMESH_AUTOMATIC" ), TypeBox );
+  QRadioButton* rb2 = new QRadioButton( tr( "SMESH_MANUAL" ),   TypeBox );
+  GroupType->addButton( rb1, 0 );
+  GroupType->addButton( rb2, 1 );
+  aTypeBoxLayout->addWidget( rb1 );
+  aTypeBoxLayout->addWidget( rb2 );
+
+  myTypeId = 0;
+
+  /***************************************************************/
+  // Controls for coincident elements detecting
+  GroupCoincident = new QGroupBox(myAction == 1 ? 
+                                  tr("COINCIDENT_ELEMENTS") : 
+                                  tr("COINCIDENT_NODES"), 
+                                  this);
+
+  QVBoxLayout* aCoincidentLayout = new QVBoxLayout(GroupCoincident);
+
+  GroupCoincident->setLayout(aCoincidentLayout);
+
+  QHBoxLayout* aSpinBoxLayout = new QHBoxLayout( GroupCoincident );
+  
+  if (myAction == 0) { // case merge nodes
+    TextLabelTolerance = new QLabel(tr("SMESH_TOLERANCE"), GroupCoincident);
+    SpinBoxTolerance = new SMESHGUI_SpinBox(GroupCoincident);
+    SpinBoxTolerance->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+
+    aSpinBoxLayout->addWidget(TextLabelTolerance);
+    aSpinBoxLayout->addWidget(SpinBoxTolerance);
+    aCoincidentLayout->addLayout(aSpinBoxLayout);
+  }
+  else {
+    TextLabelTolerance = 0;
+    SpinBoxTolerance = 0;
+  }
+
+  GroupCoincidentWidget = new QWidget(GroupCoincident);
+  QGridLayout* GroupCoincidentLayout = new QGridLayout(GroupCoincidentWidget);
+  GroupCoincidentLayout->setSpacing(SPACING);
+  GroupCoincidentLayout->setMargin(MARGIN);
+
+  ListCoincident = new QListWidget(GroupCoincidentWidget);
+  ListCoincident->setSelectionMode(QListWidget::ExtendedSelection);
+
+  DetectButton      = new QPushButton(tr("DETECT"),           GroupCoincidentWidget);
+  AddGroupButton    = new QPushButton(tr("SMESH_BUT_ADD"),    GroupCoincidentWidget);
+  RemoveGroupButton = new QPushButton(tr("SMESH_BUT_REMOVE"), GroupCoincidentWidget);
+
+  SelectAllCB = new QCheckBox(tr("SELECT_ALL"), GroupCoincidentWidget);
+
+  if (myAction == 0)
+    GroupCoincidentWidget->hide();
+  else
+    GroupCoincident->hide();
+
+  GroupCoincidentLayout->addWidget(ListCoincident,    0,   0, 4, 2);
+  GroupCoincidentLayout->addWidget(DetectButton,      0,   2);
+  GroupCoincidentLayout->addWidget(AddGroupButton,    2, 2);
+  GroupCoincidentLayout->addWidget(RemoveGroupButton, 3, 2);
+  GroupCoincidentLayout->addWidget(SelectAllCB,       4, 0, 1, 3);
+  GroupCoincidentLayout->setRowMinimumHeight(1, 10);
+  GroupCoincidentLayout->setRowStretch(1, 5);
+
+  aCoincidentLayout->addWidget(GroupCoincidentWidget);
+
+  /***************************************************************/
+  // Controls for editing the selected group
+  GroupEdit = new QGroupBox(tr("EDIT_SELECTED_GROUP"), this);
+  QGridLayout* GroupEditLayout = new QGridLayout(GroupEdit);
+  GroupEditLayout->setSpacing(SPACING);
+  GroupEditLayout->setMargin(MARGIN);
+
+  ListEdit = new QListWidget(GroupEdit);
+  //ListEdit->setRowMode(QListBox::FixedNumber);
+  //ListEdit->setHScrollBarMode(QScrollView::AlwaysOn);
+  //ListEdit->setVScrollBarMode(QScrollView::AlwaysOff);
+  ListEdit->setFlow( QListView::LeftToRight );
+  ListEdit->setSelectionMode(QListWidget::ExtendedSelection);
+
+  AddElemButton = new QPushButton(GroupEdit);
+  AddElemButton->setIcon(IconAdd);
+  RemoveElemButton = new QPushButton(GroupEdit);
+  RemoveElemButton->setIcon(IconRemove);
+  SetFirstButton = new QPushButton(GroupEdit);
+  SetFirstButton->setIcon(QPixmap(IconFirst));
+
+  GroupEditLayout->addWidget(ListEdit,         0, 0, 2, 1);
+  GroupEditLayout->addWidget(AddElemButton,    0, 1);
+  GroupEditLayout->addWidget(RemoveElemButton, 0, 2);
+  GroupEditLayout->addWidget(SetFirstButton,   1, 1, 1, 2);
+
+  GroupEdit->hide();
+
+  /***************************************************************/
+  GroupButtons = new QGroupBox(this);
+  QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
+  GroupButtonsLayout->setSpacing(SPACING);
+  GroupButtonsLayout->setMargin(MARGIN);
+
+  buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
+  buttonOk->setAutoDefault(true);
+  buttonOk->setDefault(true);
+  buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
+  buttonApply->setAutoDefault(true);
+  buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
+  buttonCancel->setAutoDefault(true);
+  buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
+  buttonHelp->setAutoDefault(true);
+
+  GroupButtonsLayout->addWidget(buttonOk);
+  GroupButtonsLayout->addSpacing(10);
+  GroupButtonsLayout->addWidget(buttonApply);
+  GroupButtonsLayout->addSpacing(10);
+  GroupButtonsLayout->addStretch();
+  GroupButtonsLayout->addWidget(buttonCancel);
+  GroupButtonsLayout->addWidget(buttonHelp);
+
+  /***************************************************************/
+  DlgLayout->addWidget(GroupConstructors);
+  DlgLayout->addWidget(GroupMesh);
+  DlgLayout->addWidget(TypeBox);
+  DlgLayout->addWidget(GroupCoincident);
+  DlgLayout->addWidget(GroupEdit);
+  DlgLayout->addWidget(GroupButtons);
+
+  this->resize(10,10);
 
   Init(); // Initialisations
 }
@@ -139,7 +511,7 @@ SMESHGUI_EditMeshDlg::SMESHGUI_EditMeshDlg (SMESHGUI* theModule,
 //=================================================================================
 SMESHGUI_EditMeshDlg::~SMESHGUI_EditMeshDlg()
 {
-  // no need to delete child widgets, Qt does it all for us
+  delete myIdPreview;
 }
 
 //=================================================================================
@@ -148,60 +520,160 @@ SMESHGUI_EditMeshDlg::~SMESHGUI_EditMeshDlg()
 //=================================================================================
 void SMESHGUI_EditMeshDlg::Init()
 {
-  GroupMesh->show();
-  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+  if (myAction == 0) {
+    SpinBoxTolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, "len_tol_precision");
+    SpinBoxTolerance->SetValue(1e-05);
+  }
+
+  RadioButton->setChecked(true);
+
+  GroupType->button(0)->setChecked(true);
 
-  myMesh = SMESH::SMESH_Mesh::_nil();
+  myEditCurrentArgument = (QWidget*)LineEditMesh; 
 
-  myMeshFilter = new SMESH_TypeFilter (MESH);
+  myActor = 0;
+  mySubMeshOrGroup = SMESH::SMESH_subMesh::_nil();
 
-  // signals and slots connections
-  connect(buttonOk    , SIGNAL(clicked()), this, SLOT(ClickOnOk()));
+  mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
+
+  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+  myIsBusy = false;
+  
+  /* signals and slots connections */
+  connect(buttonOk,     SIGNAL(clicked()), this, SLOT(ClickOnOk()));
   connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
-  connect(buttonApply , SIGNAL(clicked()), this, SLOT(ClickOnApply()));
+  connect(buttonApply,  SIGNAL(clicked()), this, SLOT(ClickOnApply()));
+  connect(buttonHelp,   SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
 
-  connect(SelectButton, SIGNAL(clicked()), this, SLOT(SelectionIntoArgument()));
+  connect(SelectMeshButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
+  connect(DetectButton, SIGNAL (clicked()), this, SLOT(onDetect()));
+  connect(ListCoincident, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectGroup()));
+  connect(AddGroupButton, SIGNAL (clicked()), this, SLOT(onAddGroup()));
+  connect(RemoveGroupButton, SIGNAL (clicked()), this, SLOT(onRemoveGroup()));
+  connect(SelectAllCB, SIGNAL(toggled(bool)), this, SLOT(onSelectAll(bool)));
+  connect(ListEdit, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectElementFromGroup()));
+  connect(AddElemButton, SIGNAL (clicked()), this, SLOT(onAddElement()));
+  connect(RemoveElemButton, SIGNAL (clicked()), this, SLOT(onRemoveElement()));
+  connect(SetFirstButton, SIGNAL( clicked() ), this, SLOT( onSetFirst() ) );
+  connect(GroupType, SIGNAL(buttonClicked(int)), this, SLOT(onTypeChanged(int)));
 
+  connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+  /* to close dialog if study change */
+  connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
 
-  connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
-  connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs())       , this, SLOT(ClickOnCancel()));
+  // Init Mesh field from selection
+  SelectionIntoArgument();
 
-  // Move widget on the bottom right corner of main widget
-  int x, y;
-  mySMESHGUI->DefineDlgPosition(this, x, y);
-  this->move(x, y);
-  this->show(); // displays Dialog
+  // Update Buttons
+  updateControls();
+  
+  if (myAction == 0)
+    myHelpFileName = "merging_nodes_page.html";
+  else
+    myHelpFileName = "merging_elements_page.html";
+}
 
-  LineEditMesh->setFocus();
-  mySelectionMgr->clearFilters();
-  mySelectionMgr->installFilter(myMeshFilter);
+//=================================================================================
+// function : FindGravityCenter()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap, 
+                                             std::list< gp_XYZ > & theGrCentersXYZ)
+{
+  if (!myActor)
+    return;
 
-  SelectionIntoArgument();
+  SMDS_Mesh* aMesh = 0;
+  aMesh = myActor->GetObject()->GetMesh();
+  if (!aMesh)
+    return;
+
+  int nbNodes;
+
+  TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
+  for( ; idIter.More(); idIter.Next() ) {
+    const SMDS_MeshElement* anElem = aMesh->FindElement(idIter.Key());
+    if ( !anElem )
+      continue;
+
+    gp_XYZ anXYZ(0., 0., 0.);
+    SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator();
+    for ( nbNodes = 0; nodeIt->more(); nbNodes++ ) {
+      const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+      anXYZ.Add( gp_XYZ( node->X(), node->Y(), node->Z() ) );
+    }
+    anXYZ.Divide( nbNodes );
+    
+    theGrCentersXYZ.push_back( anXYZ );
+  }
 }
 
 //=================================================================================
 // function : ClickOnApply()
 // purpose  :
 //=================================================================================
-void SMESHGUI_EditMeshDlg::ClickOnApply()
+bool SMESHGUI_EditMeshDlg::ClickOnApply()
 {
-  if (!myMesh->_is_nil()) {
-    try        {
-      QApplication::setOverrideCursor(Qt::waitCursor);
+  if (mySMESHGUI->isActiveStudyLocked() || myMesh->_is_nil())
+    return false;
 
-      if (myAction == 1) {
-        SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
-        aMeshEditor->MergeEqualElements();
-      }
+  try {
+    if (myTypeId == 0)
+      onDetect();
+
+    SUIT_OverrideCursor aWaitCursor;
+    SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+
+    SMESH::long_array_var anIds = new SMESH::long_array;
+    SMESH::array_of_long_array_var aGroupsOfElements = new SMESH::array_of_long_array;
 
-      QApplication::restoreOverrideCursor();
-    } catch(...) {
+    if ( ListCoincident->count() == 0) {
+      if (myAction == 0)
+        SUIT_MessageBox::warning(this,
+                                 tr("SMESH_WARNING"),
+                                 tr("SMESH_NO_NODES_DETECTED"));
+      else
+        SUIT_MessageBox::warning(this,
+                                 tr("SMESH_WARNING"),
+                                 tr("SMESH_NO_ELEMENTS_DETECTED"));
+      return false;
     }
 
-    mySelectionMgr->clearSelected();
-    SMESH::UpdateView();
+    aGroupsOfElements->length(ListCoincident->count());
+
+    int anArrayNum = 0;
+    for (int i = 0; i < ListCoincident->count(); i++) {
+      QStringList aListIds = ListCoincident->item(i)->text().split(" ", QString::SkipEmptyParts);
+
+      anIds->length(aListIds.count());
+      for (int i = 0; i < aListIds.count(); i++)
+        anIds[i] = aListIds[i].toInt();
+
+      aGroupsOfElements[anArrayNum++] = anIds.inout();
+    }
+
+    if( myAction == 0 )
+      aMeshEditor->MergeNodes (aGroupsOfElements.inout());
+    else
+      aMeshEditor->MergeElements (aGroupsOfElements.inout());
+
+    if ( myTypeId == 0 ) {
+      if (myAction ==0)
+        SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"),
+                                     tr("SMESH_MERGED_NODES").arg(QString::number(ListCoincident->count()).toLatin1().data()));
+      else
+        SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"),
+                                     tr("SMESH_MERGED_ELEMENTS").arg(QString::number(ListCoincident->count()).toLatin1().data()));
+    }
+      
+
+  } catch(...) {
   }
+  
+  SMESH::UpdateView();
+  
+  return true;
 }
 
 //=================================================================================
@@ -210,8 +682,8 @@ void SMESHGUI_EditMeshDlg::ClickOnApply()
 //=================================================================================
 void SMESHGUI_EditMeshDlg::ClickOnOk()
 {
-  ClickOnApply();
-  ClickOnCancel();
+  if (ClickOnApply())
+    ClickOnCancel();
 }
 
 //=================================================================================
@@ -220,44 +692,443 @@ void SMESHGUI_EditMeshDlg::ClickOnOk()
 //=================================================================================
 void SMESHGUI_EditMeshDlg::ClickOnCancel()
 {
-  mySelectionMgr->clearSelected();
-  mySelectionMgr->clearFilters();
+  myIdPreview->SetPointsLabeled(false);
+  SMESH::SetPointRepresentation(false);
   disconnect(mySelectionMgr, 0, this, 0);
+  disconnect(mySMESHGUI, 0, this, 0);
   mySMESHGUI->ResetState();
+
+  mySelectionMgr->clearFilters();
+  //mySelectionMgr->clearSelected();
+
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    aViewWindow->SetSelectionMode(ActorSelection);
+
   reject();
 }
 
 //=================================================================================
-// function : SelectionIntoArgument()
-// purpose  : Called when selection as changed or other case
+// function : ClickOnHelp()
+// purpose  :
 //=================================================================================
-void SMESHGUI_EditMeshDlg::SelectionIntoArgument()
+void SMESHGUI_EditMeshDlg::ClickOnHelp()
+{
+  LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
+  if (app) 
+    app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
+  else {
+    QString platform;
+#ifdef WIN32
+    platform = "winapplication";
+#else
+    platform = "application";
+#endif
+    SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", 
+                                                                 platform)).
+                             arg(myHelpFileName));
+  }
+}
+
+//=================================================================================
+// function : onEditGroup()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onEditGroup()
+{
+  QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
+  if ( selItems.count() != 1 ) {
+    ListEdit->clear();
+    return;
+  }
+
+  QStringList aNewIds;
+
+  for (int i = 0; i < ListEdit->count(); i++ )
+    aNewIds.append(ListEdit->item(i)->text());
+
+  ListCoincident->clearSelection();
+  selItems.first()->setText(aNewIds.join(" "));
+  selItems.first()->setSelected(true);
+}
+
+//=================================================================================
+// function : updateControls()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::updateControls()
+{
+  if (ListEdit->count() == 0)
+    SetFirstButton->setEnabled(false);
+  bool enable = !(myMesh->_is_nil()) && (ListCoincident->count() || (myTypeId == 0));
+  buttonOk->setEnabled(enable);
+  buttonApply->setEnabled(enable);
+}
+
+//=================================================================================
+// function : onDetect()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onDetect()
+{
+  if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() )
+    return;
+
+  try {
+    SUIT_OverrideCursor aWaitCursor;
+    SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+
+    ListCoincident->clear();
+    ListEdit->clear();
+
+    SMESH::array_of_long_array_var aGroupsArray;
+
+    switch (myAction) {
+    case 0 :
+      if(!mySubMeshOrGroup->_is_nil())
+        aMeshEditor->FindCoincidentNodesOnPart(mySubMeshOrGroup, SpinBoxTolerance->GetValue(), aGroupsArray);
+      else
+        aMeshEditor->FindCoincidentNodes(SpinBoxTolerance->GetValue(), aGroupsArray);
+      break;
+    case 1 :
+      if(!mySubMeshOrGroup->_is_nil())
+        aMeshEditor->FindEqualElements(mySubMeshOrGroup, aGroupsArray);
+      else
+        aMeshEditor->FindEqualElements(myMesh, aGroupsArray);
+      break;
+    }
+    
+    for (int i = 0; i < aGroupsArray->length(); i++) {
+      SMESH::long_array& aGroup = aGroupsArray[i];
+
+      QStringList anIDs;
+      for (int j = 0; j < aGroup.length(); j++)
+        anIDs.append(QString::number(aGroup[j]));
+
+      ListCoincident->addItem(anIDs.join(" "));
+    }
+   } catch(...) {
+  }
+
+  ListCoincident->selectAll();
+  updateControls();
+}
+
+//=================================================================================
+// function : onSelectGroup()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onSelectGroup()
 {
-  if (!GroupButtons->isEnabled()) // inactive
+  if (myIsBusy || !myActor)
     return;
+  myEditCurrentArgument = (QWidget*)ListCoincident;
+
+  ListEdit->clear();
+  
+  TColStd_MapOfInteger anIndices;
+  QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
+  QListWidgetItem* anItem;
+  QStringList aListIds;
 
-  QString aString = "";
+  ListEdit->clear();
 
+  foreach(anItem, selItems) {
+    aListIds = anItem->text().split(" ", QString::SkipEmptyParts);
+    for (int i = 0; i < aListIds.count(); i++)
+      anIndices.Add(aListIds[i].toInt());
+  }
+  
+  if (selItems.count() == 1) {
+    ListEdit->addItems(aListIds);
+    ListEdit->selectAll();
+  }
+
+  mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false);
   SALOME_ListIO aList;
-  mySelectionMgr->selectedObjects(aList);
-  int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
-
-  // mesh
-  if (nbSel != 1) {
-    myMesh = SMESH::SMESH_Mesh::_nil();
-    aString = "";
-  } else {
+  aList.Append(myActor->getIO());
+  mySelectionMgr->setSelectedObjects(aList,false);
+  
+  if (myAction == 0) {
+    myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices);
+    myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
+  }
+  else {
+    std::list< gp_XYZ > aGrCentersXYZ;
+    FindGravityCenter(anIndices, aGrCentersXYZ);
+    myIdPreview->SetElemsData( anIndices, aGrCentersXYZ);
+    myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
+  }
+
+  updateControls();
+}
+
+//=================================================================================
+// function : onSelectAll()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onSelectAll (bool isToggled)
+{
+  if ( isToggled )
+    ListCoincident->selectAll();
+  else
+    ListCoincident->clearSelection();
+}
+
+//=================================================================================
+// function : onSelectElementFromGroup()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onSelectElementFromGroup()
+{
+  if (myIsBusy || !myActor)
+    return;
+
+  TColStd_MapOfInteger anIndices;
+  QList<QListWidgetItem*> selItems = ListEdit->selectedItems();
+  QListWidgetItem* anItem;
+
+  foreach(anItem, selItems)
+    anIndices.Add(anItem->text().toInt());
+
+  SetFirstButton->setEnabled(selItems.count() == 1);
+
+  mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false);
+  SALOME_ListIO aList;
+  aList.Append(myActor->getIO());
+  mySelectionMgr->setSelectedObjects(aList);
+
+  if (myAction == 0) {
+    myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices);
+    myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
+  }
+  else {
+    std::list< gp_XYZ > aGrCentersXYZ;
+    FindGravityCenter(anIndices, aGrCentersXYZ);
+    myIdPreview->SetElemsData(anIndices, aGrCentersXYZ);
+    myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
+  }
+}
+
+//=================================================================================
+// function : onAddGroup()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onAddGroup()
+{
+  if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() )
+    return;
+
+  QString anIDs = "";
+  int aNbElements = 0;
+  aNbElements = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), anIDs);
+
+  if (aNbElements < 1)
+    return;
+  
+  ListCoincident->clearSelection();
+  ListCoincident->addItem(anIDs);
+  int nbGroups = ListCoincident->count();
+  if (nbGroups) {
+    ListCoincident->setCurrentRow(nbGroups-1);
+    ListCoincident->item(nbGroups-1)->setSelected(true);
+  }
+  else {
+    // VSR ? this code seems to be never executed!!!
+    ListCoincident->setCurrentRow(0);
+    //ListCoincident->setSelected(0, true); // VSR: no items - no selection
+  }
+
+  updateControls();
+}
+
+//=================================================================================
+// function : onRemoveGroup()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onRemoveGroup()
+{
+  if (myEditCurrentArgument != (QWidget*)ListCoincident)
+    return;
+  myIsBusy = true;
+
+  QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
+  QListWidgetItem* anItem;
+
+  foreach(anItem, selItems)
+    delete anItem;
+
+  ListEdit->clear();
+  updateControls();
+
+  myIsBusy = false;
+}
+
+//=================================================================================
+// function : onAddElement()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onAddElement()
+{
+  if (!myActor)
+    return;
+  myIsBusy = true;
+
+  QString aListStr = "";
+  int aNbNnodes = 0;
+
+  aNbNnodes = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr);
+  if (aNbNnodes < 1)
+    return;
+
+  QStringList aNodes = aListStr.split(" ", QString::SkipEmptyParts);
+
+  for (QStringList::iterator it = aNodes.begin(); it != aNodes.end(); ++it) {
+    QList<QListWidgetItem*> found = ListEdit->findItems(*it, Qt::MatchExactly);
+    if ( found.count() == 0 ) {
+      QListWidgetItem* anItem = new QListWidgetItem(*it);
+      ListEdit->addItem(anItem);
+      anItem->setSelected(true);
+    }
+    else {
+      QListWidgetItem* anItem;
+      foreach(anItem, found) anItem->setSelected(true);
+    }
+  }
+
+  myIsBusy = false;
+  onEditGroup();
+}
+
+//=================================================================================
+// function : onRemoveElement()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onRemoveElement()
+{
+  if (myEditCurrentArgument != (QWidget*)ListCoincident)
+    return;
+  myIsBusy = true;
+
+  QList<QListWidgetItem*> selItems = ListEdit->selectedItems();
+  QListWidgetItem* anItem;
+
+  foreach(anItem, selItems)
+    delete anItem;
+  
+  myIsBusy = false;
+  onEditGroup();
+}
+
+//=================================================================================
+// function : onSetFirst()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onSetFirst()
+{
+  if (myEditCurrentArgument != (QWidget*)ListCoincident)
+    return;
+  myIsBusy = true;
+  
+  QList<QListWidgetItem*> selItems = ListEdit->selectedItems();
+  QListWidgetItem* anItem;
+  
+  foreach(anItem, selItems) {
+    ListEdit->takeItem(ListEdit->row(anItem));
+    ListEdit->insertItem(0, anItem);
+  }
+
+  myIsBusy = false;
+  onEditGroup();
+}
+
+//=================================================================================
+// function : SetEditCurrentArgument()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::SetEditCurrentArgument()
+{
+  QPushButton* send = (QPushButton*)sender();
+
+  disconnect(mySelectionMgr, 0, this, 0);
+  mySelectionMgr->clearSelected();
+  mySelectionMgr->clearFilters();
+
+  if (send == SelectMeshButton) {
+    myEditCurrentArgument = (QWidget*)LineEditMesh;
+    SMESH::SetPointRepresentation(false);
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode(ActorSelection);
+    if (myTypeId == 1)
+      mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
+  }
+
+  myEditCurrentArgument->setFocus();
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose  : Called when selection as changed or other case
+//=================================================================================
+void SMESHGUI_EditMeshDlg::SelectionIntoArgument()
+{
+  if (myEditCurrentArgument == (QWidget*)LineEditMesh) {
+    QString aString = "";
+    LineEditMesh->setText(aString);
+    
+    ListCoincident->clear();
+    ListEdit->clear();
+    myActor = 0;
+    
+    int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
+    if (nbSel != 1) {
+      myIdPreview->SetPointsLabeled(false);
+      SMESH::SetPointRepresentation(false);
+      mySelectionMgr->clearFilters();
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+        aViewWindow->SetSelectionMode(ActorSelection);
+      return;
+    }
+
+    SALOME_ListIO aList;
+    mySelectionMgr->selectedObjects(aList);
+    
     Handle(SALOME_InteractiveObject) IO = aList.First();
-    myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
+    myMesh = SMESH::GetMeshByIO(IO);
+    
     if (myMesh->_is_nil())
-      aString = "";
-  }
+      return;
 
-  LineEditMesh->setText(aString);
+    LineEditMesh->setText(aString);
+    
+    myActor = SMESH::FindActorByEntry(IO->getEntry());
+    if (!myActor)
+      myActor = SMESH::FindActorByObject(myMesh);
+    
+    if ( myActor && myTypeId ==1 ) {
+      mySubMeshOrGroup = SMESH::SMESH_IDSource::_nil();
+      mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
+      
+      if ((!SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO)->_is_nil() || //SUBMESH OR GROUP
+           !SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO)->_is_nil()) &&
+          !SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO)->_is_nil())
+        mySubMeshOrGroup = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
+      
+      if (myAction == 0) {
+        SMESH::SetPointRepresentation(true);
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->SetSelectionMode(NodeSelection);
+      }
+      else
+        if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+          aViewWindow->SetSelectionMode(CellSelection);
+    }
 
-  bool isEnabled = (!myMesh->_is_nil());
-  buttonOk->setEnabled(isEnabled);
-  buttonApply->setEnabled(isEnabled);
+    updateControls();
+  }
 }
 
 //=================================================================================
@@ -268,11 +1139,17 @@ void SMESHGUI_EditMeshDlg::DeactivateActiveDialog()
 {
   if (GroupConstructors->isEnabled()) {
     GroupConstructors->setEnabled(false);
+    TypeBox->setEnabled(false);
     GroupMesh->setEnabled(false);
+    GroupCoincident->setEnabled(false);
+    GroupEdit->setEnabled(false);
     GroupButtons->setEnabled(false);
     mySMESHGUI->ResetState();
     mySMESHGUI->SetActiveDialogBox(0);
   }
+
+  mySelectionMgr->clearSelected();
+  disconnect(mySelectionMgr, 0, this, 0);
 }
 
 //=================================================================================
@@ -284,9 +1161,13 @@ void SMESHGUI_EditMeshDlg::ActivateThisDialog()
   /* Emit a signal to deactivate the active dialog */
   mySMESHGUI->EmitSignalDeactivateDialog();
   GroupConstructors->setEnabled(true);
+  TypeBox->setEnabled(true);
   GroupMesh->setEnabled(true);
+  GroupCoincident->setEnabled(true);
+  GroupEdit->setEnabled(true);
   GroupButtons->setEnabled(true);
 
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
   SelectionIntoArgument();
 }
@@ -295,29 +1176,104 @@ void SMESHGUI_EditMeshDlg::ActivateThisDialog()
 // function : enterEvent()
 // purpose  :
 //=================================================================================
-void SMESHGUI_EditMeshDlg::enterEvent(QEvent* e)
+void SMESHGUI_EditMeshDlg::enterEvent(QEvent*)
 {
-  if (GroupConstructors->isEnabled())
-    return;
-  ActivateThisDialog();
+  if (!GroupConstructors->isEnabled())
+    ActivateThisDialog();
 }
 
 //=================================================================================
 // function : closeEvent()
 // purpose  :
 //=================================================================================
-void SMESHGUI_EditMeshDlg::closeEvent(QCloseEvent* e)
+void SMESHGUI_EditMeshDlg::closeEvent(QCloseEvent*)
 {
   /* same than click on cancel button */
-  this->ClickOnCancel();
+  ClickOnCancel();
 }
 
 //=======================================================================
 //function : hideEvent
 //purpose  : caused by ESC key
 //=======================================================================
-void SMESHGUI_EditMeshDlg::hideEvent (QHideEvent * e)
+void SMESHGUI_EditMeshDlg::hideEvent (QHideEvent *)
 {
   if (!isMinimized())
     ClickOnCancel();
 }
+
+//=================================================================================
+// function : keyPressEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::keyPressEvent( QKeyEvent* e)
+{
+  QDialog::keyPressEvent( e );
+  if ( e->isAccepted() )
+    return;
+
+  if ( e->key() == Qt::Key_F1 ) {
+    e->accept();
+    ClickOnHelp();
+  }
+}
+
+//=================================================================================
+// function : onTypeChanged()
+// purpose  : the type radio button management
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onTypeChanged (int id)
+{
+  if (myTypeId == id)
+    return;
+
+  myTypeId = id;
+  switch (id) {
+  case 0:
+    myIdPreview->SetPointsLabeled(false);
+    SMESH::SetPointRepresentation(false);
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode(ActorSelection);
+    mySelectionMgr->clearFilters();
+    if (myAction == 0)
+      GroupCoincidentWidget->hide();
+    else
+      GroupCoincident->hide();
+    GroupEdit->hide();
+    break;
+  case 1:
+    SMESH::UpdateView();
+
+    // Costruction of the logical filter
+    SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
+    SMESH_TypeFilter* aSmeshGroupFilter    = new SMESH_TypeFilter (GROUP);
+    
+    QList<SUIT_SelectionFilter*> aListOfFilters;
+    if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
+    if (aSmeshGroupFilter)    aListOfFilters.append(aSmeshGroupFilter);
+    
+    myMeshOrSubMeshOrGroupFilter =
+      new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR);
+
+    if (myAction == 0) {
+      GroupCoincidentWidget->show();
+      SMESH::SetPointRepresentation(true);
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+        aViewWindow->SetSelectionMode(NodeSelection);
+    }
+    else {
+      GroupCoincident->show();
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+        aViewWindow->SetSelectionMode(CellSelection);
+    }
+    GroupEdit->show();
+    break;
+  }
+  updateControls();
+
+  qApp->processEvents();
+  updateGeometry();
+  resize(10,10);
+
+  SelectionIntoArgument();
+}