Salome HOME
PR: synchro V6_main tag mergeto_V7_main_11Feb13
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_GroupDlg.cxx
index 2dbf37e6a2ca595da3aa57cf4372b26017ac6dfd..03ebc273151c28875f28c9e3f5530e38c877ec56 100644 (file)
@@ -1,23 +1,23 @@
-//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //  SMESH SMESHGUI : GUI for SMESH component
 #include <SMESH_TypeFilter.hxx>
 #include <SMESH_Actor.h>
 #include <SMESH_ActorUtils.h>
+#include <SMESH_LogicalFilter.hxx>
 
 // SALOME GEOM includes
 #include <GEOMBase.h>
 #include <GEOM_SelectionFilter.h>
+#include <GEOM_wrap.hxx>
 
 // SALOME GUI includes
 #include <QtxColorButton.h>
 enum grpSelectionMode {
   grpNoSelection       = -1,
   grpNodeSelection     = 0,
-  grpEdgeSelection     = 1,
-  grpFaceSelection     = 2,
-  grpVolumeSelection   = 3,
-  grpSubMeshSelection  = 4,
-  grpGroupSelection    = 5,
-  grpMeshSelection     = 6,
-  grpGeomSelection     = 7,
-  grpAllSelection      = 8,
+  grp0DSelection       = 1,
+  grpBallSelection     = 2,
+  grpEdgeSelection     = 3,
+  grpFaceSelection     = 4,
+  grpVolumeSelection   = 5,
+  grpSubMeshSelection  = 6,
+  grpGroupSelection    = 7,
+  grpMeshSelection     = 8,
+  grpGeomSelection     = 9,
+  grpAllSelection      = 10,
 };
 
 //=================================================================================
@@ -123,7 +127,9 @@ SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule,
     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
     mySelector( SMESH::GetViewWindow( theModule )->GetSelector() ),
     myIsBusy( false ),
-    myNameChanged( false )
+    myNameChanged( false ),
+    myIsApplyAndClose( false ),
+    myNbChangesOfContents(0)
 {
   initDialog( true );
   if ( !theMesh->_is_nil() )
@@ -149,7 +155,8 @@ SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule,
     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
     mySelector( SMESH::GetViewWindow( theModule )->GetSelector() ),
     myIsBusy( false ),
-    myNameChanged( false )
+    myNameChanged( false ),
+    myNbChangesOfContents(0) // just not to use uninitialized variable
 {
   initDialog( false );
   if ( !theGroup->_is_nil() )
@@ -209,6 +216,8 @@ void SMESHGUI_GroupDlg::initDialog( bool create)
 
   QStringList types;
   types.append( tr( "MESH_NODE" ) );
+  types.append( tr( "SMESH_ELEM0D" ) );
+  types.append( tr( "SMESH_BALL_ELEM" ) );
   types.append( tr( "SMESH_EDGE" ) );
   types.append( tr( "SMESH_FACE" ) );
   types.append( tr( "SMESH_VOLUME" ) );
@@ -236,10 +245,13 @@ void SMESHGUI_GroupDlg::initDialog( bool create)
 
   QRadioButton* rb1 = new QRadioButton( tr( "SMESH_GROUP_STANDALONE" ), aGrpTypeBox );
   QRadioButton* rb2 = new QRadioButton( tr( "SMESH_GROUP_GEOMETRY" ),   aGrpTypeBox );
+  QRadioButton* rb3 = new QRadioButton( tr( "SMESH_GROUP_FILTER" ),     aGrpTypeBox );
   myGrpTypeGroup->addButton( rb1, 0 );
   myGrpTypeGroup->addButton( rb2, 1 );
+  myGrpTypeGroup->addButton( rb3, 2 );
   aGrpTypeBoxLayout->addWidget( rb1 );
   aGrpTypeBoxLayout->addWidget( rb2 );
+  aGrpTypeBoxLayout->addWidget( rb3 );
   aGrpTypeBox->setEnabled( create );
   myGrpTypeId = -1;
 
@@ -247,31 +259,34 @@ void SMESHGUI_GroupDlg::initDialog( bool create)
   myWGStack = new QStackedWidget( this );
   QWidget* wg1 = new QWidget( myWGStack );
   QWidget* wg2 = new QWidget( myWGStack );
+  QWidget* wg3 = new QWidget( myWGStack );
 
   /***************************************************************/
-  QGroupBox* aContentBox = new QGroupBox( tr( "SMESH_CONTENT" ), wg1 );
+  QGroupBox* aContentBox         = new QGroupBox( tr( "SMESH_CONTENT" ), wg1 );
   QGridLayout* aContentBoxLayout = new QGridLayout( aContentBox );
   aContentBoxLayout->setMargin( MARGIN );
   aContentBoxLayout->setSpacing( SPACING );
 
-  mySelectAll = new QCheckBox( tr( "SELECT_ALL" ), aContentBox );
+  mySelectAll       = new QCheckBox( tr( "SELECT_ALL" ), aContentBox );
+  myAllowElemsModif = new QCheckBox( tr( "ALLOW_ELEM_LIST_MODIF" ), aContentBox );
 
   myElementsLab = new QLabel( tr( "SMESH_ID_ELEMENTS" ), aContentBox );
-  myElements = new QListWidget( aContentBox );
+  myElements    = new QListWidget( aContentBox );
   myElements->setSelectionMode( QListWidget::ExtendedSelection );
 
-  myFilter = new QPushButton( tr( "SMESH_BUT_FILTER" ), aContentBox );
-  myAddBtn = new QPushButton( tr( "SMESH_BUT_ADD" ), aContentBox );
+  myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), aContentBox );
+  myAddBtn    = new QPushButton( tr( "SMESH_BUT_ADD" ), aContentBox );
   myRemoveBtn = new QPushButton( tr( "SMESH_BUT_REMOVE" ), aContentBox );
-  mySortBtn = new QPushButton( tr( "SMESH_BUT_SORT" ), aContentBox );
+  mySortBtn   = new QPushButton( tr( "SMESH_BUT_SORT" ), aContentBox );
 
-  aContentBoxLayout->addWidget( mySelectAll,   0, 0 );
-  aContentBoxLayout->addWidget( myElementsLab, 1, 0 );
-  aContentBoxLayout->addWidget( myElements,    2, 0, 6, 1 );
-  aContentBoxLayout->addWidget( myFilter,      2, 1 );
-  aContentBoxLayout->addWidget( myAddBtn,      4, 1 );
-  aContentBoxLayout->addWidget( myRemoveBtn,   5, 1 );
-  aContentBoxLayout->addWidget( mySortBtn,     7, 1 );
+  aContentBoxLayout->addWidget( mySelectAll,       0, 0 );
+  aContentBoxLayout->addWidget( myAllowElemsModif, 1, 0 );
+  aContentBoxLayout->addWidget( myFilterBtn,       1, 1 );
+  aContentBoxLayout->addWidget( myElementsLab,     2, 0 );
+  aContentBoxLayout->addWidget( myElements,        3, 0, 6, 1 );
+  aContentBoxLayout->addWidget( myAddBtn,          3, 1 );
+  aContentBoxLayout->addWidget( myRemoveBtn,       4, 1 );
+  aContentBoxLayout->addWidget( mySortBtn,         8, 1 );
 
   aContentBoxLayout->setColumnStretch( 0, 1 );
   aContentBoxLayout->setRowStretch( 3, 1 );
@@ -327,15 +342,24 @@ void SMESHGUI_GroupDlg::initDialog( bool create)
   /***************************************************************/
   QGridLayout* wg2Layout = new QGridLayout( wg2 );
   wg2Layout->setMargin( 0 );
-  wg1Layout->setSpacing( SPACING );
+  wg2Layout->setSpacing( SPACING );
   wg2Layout->addWidget( geomObject,     0, 0 );
   wg2Layout->addWidget( myGeomGroupBtn, 0, 1 );
   wg2Layout->addWidget( myGeomGroupLine,0, 2 );
   wg2Layout->setRowStretch( 1, 5 );
 
+  /***************************************************************/
+  QPushButton * aFilter2 = new QPushButton( tr( "SMESH_BUT_FILTER" ), wg3 );
+  QGridLayout* wg3Layout = new QGridLayout( wg3 );
+  wg3Layout->setMargin( 0 );
+  wg3Layout->setSpacing( SPACING );
+  wg3Layout->addWidget( aFilter2, 0, 0 );
+  wg3Layout->setRowStretch( 1, 5 );
+
   /***************************************************************/
   myWGStack->insertWidget( 0, wg1 );
   myWGStack->insertWidget( 1, wg2 );
+  myWGStack->insertWidget( 2, wg3 );
 
   /***************************************************************/
   QGroupBox* aColorBox = new QGroupBox(tr( "SMESH_SET_COLOR" ), this);
@@ -397,8 +421,10 @@ void SMESHGUI_GroupDlg::initDialog( bool create)
   connect(myName,          SIGNAL(textChanged(const QString&)), this, SLOT(onNameChanged(const QString&)));
   connect(myElements,      SIGNAL(itemSelectionChanged()),      this, SLOT(onListSelectionChanged()));
 
-  connect(myFilter,        SIGNAL(clicked()),     this, SLOT(setFilters()));
+  connect(myFilterBtn,     SIGNAL(clicked()),     this, SLOT(setFilters()));
+  connect(aFilter2,        SIGNAL(clicked()),     this, SLOT(setFilters()));
   connect(mySelectAll,     SIGNAL(toggled(bool)), this, SLOT(onSelectAll()));
+  connect(myAllowElemsModif,SIGNAL(toggled(bool)), this, SLOT(onSelectAll()));
   connect(myAddBtn,        SIGNAL(clicked()),     this, SLOT(onAdd()));
   connect(myRemoveBtn,     SIGNAL(clicked()),     this, SLOT(onRemove()));
   connect(mySortBtn,       SIGNAL(clicked()),     this, SLOT(onSort()));
@@ -421,9 +447,13 @@ void SMESHGUI_GroupDlg::initDialog( bool create)
   mySMESHGUI->SetState(800);
 
   mySelectionMode = grpNoSelection;
-  myMeshFilter = new SMESH_TypeFilter(MESH);
-  mySubMeshFilter = new SMESH_TypeFilter(SUBMESH);
-  myGroupFilter = new SMESH_TypeFilter(GROUP);
+  myMeshFilter = new SMESH_TypeFilter(SMESH::MESH);
+  mySubMeshFilter = new SMESH_LogicalFilter(QList<SUIT_SelectionFilter*>(),
+                                            SMESH_LogicalFilter::LO_OR,
+                                            /*takeOwnership=*/true);
+  myGroupFilter = new SMESH_LogicalFilter(QList<SUIT_SelectionFilter*>(),
+                                          SMESH_LogicalFilter::LO_OR,
+                                          /*takeOwnership=*/true);
   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( mySMESHGUI->application()->activeStudy() );
   myGeomFilter = new GEOM_SelectionFilter( aStudy, true );
 
@@ -438,8 +468,7 @@ void SMESHGUI_GroupDlg::initDialog( bool create)
   if (myMesh->_is_nil() )
     myTypeGroup->button(0)->setChecked(true);
 
-  updateButtons();
-  //myName->setText(GetDefaultName(tr( "SMESH_GROUP" )));
+  onSelectAll(); //updateButtons();
 }
 
 //=================================================================================
@@ -453,6 +482,10 @@ SMESHGUI_GroupDlg::~SMESHGUI_GroupDlg()
     myFilterDlg->setParent( 0 );
     delete myFilterDlg;
   }
+  if ( myMeshFilter )    delete myMeshFilter;
+  if ( mySubMeshFilter ) delete mySubMeshFilter;
+  if ( myGroupFilter )   delete myGroupFilter;
+  if ( myGeomFilter )    delete myGeomFilter;
 }
 
 //=================================================================================
@@ -491,6 +524,22 @@ QString SMESHGUI_GroupDlg::GetDefaultName(const QString& theOperation)
   return aName;
 }
 
+void  SMESHGUI_GroupDlg::setDefaultName() const
+{
+  QString aResName;
+  _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+  int i=1;
+  QString aPrefix ="Group_";
+  _PTR(SObject) anObj;
+  do
+  {
+    aResName = aPrefix + QString::number( i++ );
+    anObj = aStudy->FindObject( aResName.toLatin1().data() );
+  }
+  while ( anObj );
+  myName->setText(aResName); 
+}
+
 //=================================================================================
 // function : Init()
 // purpose  :
@@ -505,6 +554,7 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_Mesh_ptr theMesh)
   setShowEntityMode();
   myGroup = SMESH::SMESH_Group::_nil();
   myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
+  myGroupOnFilter = SMESH::SMESH_GroupOnFilter::_nil();
 
   // NPAL19389: create a group with a selection in another group
   // set actor of myMesh, if it is visible, else try
@@ -512,6 +562,8 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_Mesh_ptr theMesh)
   SetAppropriateActor();
 
   setDefaultGroupColor();
+  setDefaultName();
+
 
   SALOME_ListIO aList;
   mySelectionMgr->selectedObjects( aList );
@@ -533,7 +585,7 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_Mesh_ptr theMesh)
 // purpose  :
 //=================================================================================
 void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
-                              const bool theIsConvert)
+                              const bool                 theIsConvert)
 {
   restoreShowEntityMode();
   myMesh = theGroup->GetMesh();
@@ -552,17 +604,21 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
 
   int aType = 0;
   switch(theGroup->GetType()) {
-  case SMESH::NODE: aType= 0; break;
-  case SMESH::EDGE: aType = 1; break;
-  case SMESH::FACE: aType = 2; break;
-  case SMESH::VOLUME: aType = 3; break;
+  case SMESH::NODE:   aType = grpNodeSelection;   break;
+  case SMESH::ELEM0D: aType = grp0DSelection;     break;
+  case SMESH::BALL:   aType = grpBallSelection;   break;
+  case SMESH::EDGE:   aType = grpEdgeSelection;   break;
+  case SMESH::FACE:   aType = grpFaceSelection;   break;
+  case SMESH::VOLUME: aType = grpVolumeSelection; break;
   }
   myTypeGroup->button(aType)->setChecked(true);
 
-  myGroup = SMESH::SMESH_Group::_narrow( theGroup );
-  myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow( theGroup );
+  myGroup         = SMESH::SMESH_Group::_narrow( theGroup );
+  myGroupOnGeom   = SMESH::SMESH_GroupOnGeom::_narrow( theGroup );
+  myGroupOnFilter = SMESH::SMESH_GroupOnFilter::_narrow( theGroup );
+  myFilter        = SMESH::Filter::_nil();
 
-  if (myGroup->_is_nil() && myGroupOnGeom->_is_nil())
+  if (myGroup->_is_nil() && myGroupOnGeom->_is_nil() && myGroupOnFilter->_is_nil() )
     return;
 
   // NPAL19389: create a group with a selection in another group
@@ -577,14 +633,16 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
     anActor = SMESH::FindActorByObject(theGroup);
   SMESH::SetPickable(anActor);*/
 
-  int grpType = (!myGroup->_is_nil() ? 0 : (theIsConvert ? 0 : 1));
+  int grpType = (!myGroup->_is_nil() ? 0 : (theIsConvert ? 0 : myGroupOnGeom->_is_nil() ? 2 : 1));
   myGrpTypeGroup->button(grpType)->setChecked(true);
   onGrpTypeChanged(grpType);
 
   myTypeId = aType;
-  if ( grpType == 0 ) {
+  if ( grpType == 0 ) { // standalone group
     myCurrentLineEdit = 0;
     myElements->clear();
+    myAllowElemsModif->setChecked( true );
+
     setSelectionMode(aType);
 
     setShowEntityMode(); // depends on myTypeId
@@ -600,7 +658,7 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
       myElements->selectAll();
     }
   }
-  else
+  else if ( grpType == 1 ) // group on geom
   {
     QString aShapeName( "" );
     _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
@@ -612,12 +670,26 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
         aShapeName = aGroupShapeSO->GetName().c_str();
     }
     myGeomGroupLine->setText( aShapeName );
+  }
+  else // group on filter
+  {
+    myFilter = myGroupOnFilter->GetFilter();
+    if ( !myFilter->_is_nil() ) {
+      SMESH::Predicate_var perdicate = myFilter->GetPredicate();
+      if ( perdicate->_is_nil() )
+        myFilter = SMESH::Filter::_nil();
+    }
+  }
+
+  if ( grpType != 0 )
+  {
     myNameChanged = true;
     myName->blockSignals(true);
     myName->setText(theGroup->GetName());
     myName->blockSignals(false);
   }
-  updateButtons();
+
+  onSelectAll(); //updateButtons();
 }
 
 //=================================================================================
@@ -627,17 +699,36 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup,
 void SMESHGUI_GroupDlg::updateButtons()
 {
   bool enable = !myName->text().trimmed().isEmpty();
-
-  if (myGrpTypeId == 0) {
-    enable = enable && (mySelectAll->isChecked() || myElements->count() > 0);
-    enable = enable && (!myGroup->_is_nil() || !myMesh->_is_nil());
-  }
-  else if (myGrpTypeId == 1) {
-    if (CORBA::is_nil(myGroupOnGeom)) { // creation mode
-      enable = enable && myGeomObjects->length() > 0 && !myMesh->_is_nil();
+  if ( enable )
+  {
+    if (myGrpTypeId == 0) { // standalone
+      if ( !mySelectAll->isChecked() )
+      {
+        if ( myAllowElemsModif->isChecked() )
+        {
+          enable = ( myElements->count() > 0 );
+        }
+        else if ((enable = !myFilter->_is_nil() ))
+        {
+          SMESH::array_of_ElementType_var types = myFilter->GetTypes();
+          enable = types->length();
+        }
+      }
+      enable = enable && (!myGroup->_is_nil() || !myMesh->_is_nil());
+    }
+    else if (myGrpTypeId == 1) // on geom
+    {
+      if (CORBA::is_nil(myGroupOnGeom)) // creation mode
+        enable = ( myGeomObjects->length() > 0 && !myMesh->_is_nil() );
+    }
+    else if (myGrpTypeId == 2) // on filter
+    {
+      if (( enable = !myFilter->_is_nil() ))
+        if (CORBA::is_nil(myGroupOnFilter) )  // creation mode
+          enable = !myMesh->_is_nil();
     }
   }
-  
+
   myOKBtn->setEnabled(enable);
   myApplyBtn->setEnabled(enable);
 }
@@ -661,9 +752,13 @@ void SMESHGUI_GroupDlg::onTypeChanged (int id)
 {
   if (myTypeId != id) {
     myElements->clear();
-    if (myCurrentLineEdit == 0)
-      setSelectionMode(id);
     myTypeId = id;
+    if ( myGrpTypeId == 0 && myCurrentLineEdit == 0)
+      setSelectionMode(id);
+    else
+      setSelectionMode( mySelectionMode++ ); // update according to mySelectionMode
+
+    onObjectSelectionChanged();
     setShowEntityMode();
   }
 }
@@ -675,13 +770,14 @@ void SMESHGUI_GroupDlg::onTypeChanged (int id)
 void SMESHGUI_GroupDlg::onGrpTypeChanged (int id)
 {
   if (myGrpTypeId != id) {
+    myGrpTypeId = id;
     myWGStack->setCurrentIndex( id );
     myName->blockSignals(true);
     myName->setText(myOldName);
     myName->blockSignals(false);
-    onSelectGeomGroup(id == 1);
+    onSelectGeomGroup(id != 0);
   }
-  myGrpTypeId = id;
+  updateButtons();
 }
 
 //=================================================================================
@@ -703,47 +799,85 @@ void SMESHGUI_GroupDlg::setSelectionMode (int theMode)
   if (myMesh->_is_nil())
     return;
   SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
-  bool isSelectAll = mySelectAll->isChecked();
+  bool isSelectAll = mySelectAll->isChecked() || !myAllowElemsModif->isChecked() || myGrpTypeId != 0;
   if (mySelectionMode != theMode) {
     // [PAL10408] mySelectionMgr->clearSelected();
     mySelectionMgr->clearFilters();
-    if (myActorsList.count() > 0) {
-      QListIterator<SMESH_Actor*> it( myActorsList );
-      while ( it.hasNext() )
+    SMESH::RemoveFilters();
+
+    if (myActorsList.count() > 0)
+      for (QListIterator<SMESH_Actor*> it( myActorsList ); it.hasNext(); )
         it.next()->SetPointRepresentation(false);
-    }
-    else {
+    else
       SMESH::SetPointRepresentation(false);
-    }
+
     switch (theMode) {
     case grpNodeSelection:
-      if (myActorsList.count() > 0) {
-        QListIterator<SMESH_Actor*> it( myActorsList );
-        while ( it.hasNext() )
-          it.next()->SetPointRepresentation(true);
-      }
-      else {
-        SMESH::SetPointRepresentation(true);
+      if ( myGrpTypeId == 0 ) // standalone
+      {
+        if (myActorsList.count() > 0)
+          for (QListIterator<SMESH_Actor*> it( myActorsList ); it.hasNext(); )
+            it.next()->SetPointRepresentation(true);
+        else
+          SMESH::SetPointRepresentation(true);
       }
       if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : NodeSelection);
       break;
     case grpEdgeSelection:
       if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : EdgeSelection);
       break;
+    case grpBallSelection:
+      if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : BallSelection);
+      break;
+    case grp0DSelection:
+      if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : Elem0DSelection);
+      break;
     case grpFaceSelection:
       if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : FaceSelection);
       break;
     case grpVolumeSelection:
       if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : VolumeSelection);
       break;
-    case grpSubMeshSelection:
-      mySelectionMgr->installFilter(mySubMeshFilter);
+    case grpSubMeshSelection: {
+
+      SMESH_TypeFilter* f = 0;
+      switch (myTypeId) {
+      case grpNodeSelection:   f = new SMESH_TypeFilter(SMESH::SUBMESH); break;
+      case grpEdgeSelection:   f = new SMESH_TypeFilter(SMESH::SUBMESH_EDGE); break;
+      case grpFaceSelection:   f = new SMESH_TypeFilter(SMESH::SUBMESH_FACE); break;
+      case grpVolumeSelection: f = new SMESH_TypeFilter(SMESH::SUBMESH_SOLID); break;
+      default:                 f = new SMESH_TypeFilter(SMESH::SUBMESH);
+      }
+      QList<SUIT_SelectionFilter*> filtList;
+      filtList.append( f );
+      filtList.append( new SMESH_TypeFilter(SMESH::SUBMESH_COMPOUND));
+      mySubMeshFilter->setFilters( filtList );
+
+      mySelectionMgr->installFilter( mySubMeshFilter );
+
       if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection);
       break;
-    case grpGroupSelection:
+    }
+    case grpGroupSelection: {
+
+      SMESH_TypeFilter* f = 0;
+      switch (myTypeId) {
+      case grpNodeSelection:   f = new SMESH_TypeFilter(SMESH::GROUP_NODE);   break;
+      case grp0DSelection:     f = new SMESH_TypeFilter(SMESH::GROUP_0D);     break;
+      case grpBallSelection:   f = new SMESH_TypeFilter(SMESH::GROUP_BALL);   break;
+      case grpEdgeSelection:   f = new SMESH_TypeFilter(SMESH::GROUP_EDGE);   break;
+      case grpFaceSelection:   f = new SMESH_TypeFilter(SMESH::GROUP_FACE);   break;
+      case grpVolumeSelection: f = new SMESH_TypeFilter(SMESH::GROUP_VOLUME); break;
+      default:                 f = new SMESH_TypeFilter(SMESH::GROUP);
+      }
+      QList<SUIT_SelectionFilter*> filtList;
+      filtList.append( f );
+      myGroupFilter->setFilters( filtList );
+
       mySelectionMgr->installFilter(myGroupFilter);
       if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection);
       break;
+    }
     case grpMeshSelection:
       mySelectionMgr->installFilter(myMeshFilter);
       if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection);
@@ -773,20 +907,41 @@ bool SMESHGUI_GroupDlg::onApply()
   if (myName->text().trimmed().isEmpty())
     return false;
 
-  if (myGrpTypeId == 0) { // on mesh elements
-    if (!mySelectAll->isChecked() && !myElements->count())
+  SMESH::ElementType aType = SMESH::ALL;
+  switch (myTypeId) {
+  case grpNodeSelection:   aType = SMESH::NODE;   break;
+  case grp0DSelection:     aType = SMESH::ELEM0D; break;
+  case grpBallSelection:   aType = SMESH::BALL;   break;
+  case grpEdgeSelection:   aType = SMESH::EDGE;   break;
+  case grpFaceSelection:   aType = SMESH::FACE;   break;
+  case grpVolumeSelection: aType = SMESH::VOLUME; break;
+  }
+
+  bool anIsOk = false;
+  QStringList anEntryList;
+
+  SMESH::SMESH_GroupBase_var resultGroup;
+  bool isCreation;
+    
+  if (myGrpTypeId == 0)  // standalone
+  {
+    if (!mySelectAll->isChecked() && !myElements->count() && myAllowElemsModif->isChecked())
       return false;
 
     mySelectionMgr->clearSelected();
 
     if (myGroup->_is_nil()) { // creation or conversion
       // check if group on geometry is not null
-      if (!CORBA::is_nil(myGroupOnGeom)) {
+      if (!myGroupOnGeom->_is_nil() || !myGroupOnFilter->_is_nil()) {
         if (myMesh->_is_nil())
           return false;
-        myGroup = myMesh->ConvertToStandalone( myGroupOnGeom );
-        // nullify pointer, because object become dead
+        if ( myGroupOnGeom->_is_nil() )
+          myGroup = myMesh->ConvertToStandalone( myGroupOnFilter );
+        else
+          myGroup = myMesh->ConvertToStandalone( myGroupOnGeom );
+
         myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
+        myGroupOnFilter = SMESH::SMESH_GroupOnFilter::_nil();
       }
     }
 
@@ -794,61 +949,40 @@ bool SMESHGUI_GroupDlg::onApply()
       if (myMesh->_is_nil())
         return false;
 
-      SMESH::ElementType aType = SMESH::ALL;
-      switch (myTypeId) {
-      case 0: aType = SMESH::NODE; break;
-      case 1: aType = SMESH::EDGE; break;
-      case 2: aType = SMESH::FACE; break;
-      case 3: aType = SMESH::VOLUME; break;
-      }
-
       myGroup = SMESH::AddGroup(myMesh, aType, myName->text());
 
+      resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroup );
+      isCreation = true;
+
       if ( mySelectAll->isChecked() ) {
         // select all
         myGroup->AddFrom(myMesh.in());
       }
       else {
         // select manually
-        SMESH::long_array_var anIdList = new SMESH::long_array;
-        int i, k = myElements->count();
-        anIdList->length(k);
-        for (i = 0; i < k; i++) {
-          anIdList[i] = myElements->item(i)->text().toInt();
+
+        if ( !myFilter->_is_nil() &&
+             ( myNbChangesOfContents == 1 || !myAllowElemsModif->isChecked()))
+        {
+          myGroup->AddFrom( myFilter );
+        }
+        else
+        {
+          SMESH::long_array_var anIdList = new SMESH::long_array;
+          int i, k = myElements->count();
+          anIdList->length(k);
+          for (i = 0; i < k; i++) {
+            anIdList[i] = myElements->item(i)->text().toInt();
+          }
+          myGroup->Add(anIdList.inout());
         }
-        
-        myGroup->Add(anIdList.inout());
       }
 
-      SALOMEDS::Color aColor = getGroupColor();
-      myGroup->SetColor(aColor);
-
-      _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroup);
-
-      //SMESH::setFileName ( aMeshGroupSO, QString::number(myColorSpinBox->value()) );
-      SMESH::setFileType ( aMeshGroupSO, "COULEURGROUP" );
-
-      /* init for next operation */
-      myName->setText( "" );
-      myElements->clear();
-      myGroup = SMESH::SMESH_Group::_nil();
 
     } else { // edition
-      myGroup->SetName(myName->text().toLatin1().data());
-
-      SALOMEDS::Color aColor = getGroupColor();
-      myGroup->SetColor(aColor);
-
-      _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroup);
-      if(SMESH_Actor *anActor = SMESH::FindActorByEntry(aMeshGroupSO->GetID().c_str())) {
-        anActor->setName(myName->text().toLatin1().data());
-        switch ( myTypeId ) {
-        case 0: anActor->SetNodeColor( aColor.R, aColor.G, aColor.B ); break;
-        case 1: anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B ); break;
-        case 2:
-        case 3: anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B ); break;
-        }
-      }
+
+      resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroup );
+      isCreation = false;
 
       if ( mySelectAll->isChecked() ) {
         // select all
@@ -891,28 +1025,15 @@ bool SMESHGUI_GroupDlg::onApply()
       }
     }
 
-    SMESHGUI::Modified();
-    mySMESHGUI->updateObjBrowser(true);
-    SMESH::UpdateView(); // asv: fix of BUG PAL5515
-    mySelectionMgr->clearSelected();
-    return true;
+    anIsOk = true;
   }
-  else if (myGrpTypeId == 1) { // on geom object
+  else if (myGrpTypeId == 1) // on geom object
+  {
     if (CORBA::is_nil(myGroupOnGeom)) { // creation
       if (myMesh->_is_nil() || !myGeomObjects->length())
         return false;
 
-      SMESH::ElementType aType = SMESH::ALL;
-      switch (myTypeId) {
-      case 0: aType = SMESH::NODE; break;
-      case 1: aType = SMESH::EDGE; break;
-      case 2: aType = SMESH::FACE; break;
-      case 3: aType = SMESH::VOLUME; break;
-      }
-
       _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
-      GEOM::GEOM_IGroupOperations_var aGroupOp =
-        SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
 
       if (myGeomObjects->length() == 1) {
         myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType,
@@ -931,8 +1052,7 @@ bool SMESHGUI_GroupDlg::onApply()
         if (geomGen->_is_nil() || !aStudy)
           return false;
 
-        GEOM::GEOM_IGroupOperations_var op =
-          geomGen->GetIGroupOperations(aStudy->StudyId());
+        GEOM::GEOM_IGroupOperations_wrap op = geomGen->GetIGroupOperations(aStudy->StudyId());
         if (op->_is_nil())
           return false;
 
@@ -949,8 +1069,8 @@ bool SMESHGUI_GroupDlg::onApply()
           }
         }
 
-        GEOM::GEOM_Object_var aMeshShape = myMesh->GetShapeToMesh();
-        GEOM::GEOM_Object_var aGroupVar = op->CreateGroup(aMeshShape, aGroupType);
+        GEOM::GEOM_Object_var  aMeshShape = myMesh->GetShapeToMesh();
+        GEOM::GEOM_Object_wrap aGroupVar = op->CreateGroup(aMeshShape, aGroupType);
         op->UnionList(aGroupVar, myGeomObjects);
 
         if (op->IsDone()) {
@@ -966,44 +1086,99 @@ bool SMESHGUI_GroupDlg::onApply()
                                                     myName->text().toLatin1().data(),
                                                     aGroupVar);
       }
+      resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnGeom );
+      isCreation = true;
+
+    }
+    else { // edition
 
-      SALOMEDS::Color aColor = getGroupColor();
-      myGroupOnGeom->SetColor(aColor);
+      resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnGeom );
+      isCreation = false;
+    }      
+    anIsOk = true;
+  }
+  if (myGrpTypeId == 2) // group on filter
+  {
+    if ( myFilter->_is_nil() ) return false;
 
-      _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroupOnGeom);
+    if (CORBA::is_nil(myGroupOnFilter)) { // creation
+      if (myMesh->_is_nil())
+        return false;
 
-      //SMESH::setFileName ( aMeshGroupSO, QString::number(myColorSpinBox->value()) );
-      SMESH::setFileType ( aMeshGroupSO,"COULEURGROUP" );
+      myGroupOnFilter = myMesh->CreateGroupFromFilter(aType,
+                                                      myName->text().toLatin1().data(),
+                                                      myFilter);
 
-      /* init for next operation */
-      myName->setText( "" );
-      myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
+      resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnFilter );
+      isCreation = true;
     }
-    else { // edition
-      myGroupOnGeom->SetName(myName->text().toLatin1().data());
-
-      SALOMEDS::Color aColor = getGroupColor();
-      myGroupOnGeom->SetColor(aColor);
-
-      _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroupOnGeom);
-      if(SMESH_Actor *anActor = SMESH::FindActorByEntry(aMeshGroupSO->GetID().c_str())) {
-        anActor->setName(myName->text().toLatin1().data());
-        switch ( myTypeId ) {
-        case 0: anActor->SetNodeColor( aColor.R, aColor.G, aColor.B ); break;
-        case 1: anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B ); break;
-        case 2:
-        case 3: anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B ); break;
-        }
-      }
+    else
+    {
+      myGroupOnFilter->SetFilter( myFilter );
+
+      resultGroup = SMESH::SMESH_GroupBase::_narrow( myGroupOnFilter );
+      isCreation = false;
     }
+    anIsOk = true;
+  }
 
+  if( anIsOk )
+  {
+    SALOMEDS::Color aColor = getGroupColor();
+    resultGroup->SetColor(aColor);
+
+    _PTR(SObject) aMeshGroupSO = SMESH::FindSObject( resultGroup );
+    if( aMeshGroupSO )
+      anEntryList.append( aMeshGroupSO->GetID().c_str() );
+
+    if ( isCreation )
+    {
+      SMESH::setFileType ( aMeshGroupSO, "COULEURGROUP" );
+
+      /* init for the next operation */
+      setDefaultName();
+      myElements->clear();
+      myGroup         = SMESH::SMESH_Group::_nil();
+      myGroupOnGeom   = SMESH::SMESH_GroupOnGeom::_nil();
+      myGroupOnFilter = SMESH::SMESH_GroupOnFilter::_nil();
+      myFilter        = SMESH::Filter::_nil();
+    }
+    else
+    {
+      resultGroup->SetName(myName->text().toLatin1().data());
+
+      if ( aMeshGroupSO )
+        if(SMESH_Actor *anActor = SMESH::FindActorByEntry(aMeshGroupSO->GetID().c_str())) {
+          anActor->setName(myName->text().toLatin1().data());
+          QColor c;
+          int delta;
+          switch ( myTypeId ) {
+          case grpNodeSelection:   anActor->SetNodeColor( aColor.R, aColor.G, aColor.B ); break;
+          case grp0DSelection:     anActor->Set0DColor  ( aColor.R, aColor.G, aColor.B ); break;
+          case grpBallSelection:   anActor->SetBallColor( aColor.R, aColor.G, aColor.B ); break;
+          case grpEdgeSelection:   anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B ); break;
+          case grpVolumeSelection: 
+              SMESH::GetColor("SMESH", "volume_color", c , delta, "255,0,170|-100");
+              anActor->SetVolumeColor( aColor.R, aColor.G, aColor.B, delta ); break;          
+              break;
+          case grpFaceSelection:   
+          default:
+              SMESH::GetColor("SMESH", "fill_color", c , delta, "0,170,255|-100");
+              anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B, delta ); break;          
+              break;
+          }
+        }
+    }
     SMESHGUI::Modified();
     mySMESHGUI->updateObjBrowser(true);
+    SMESH::UpdateView(); // asv: fix of BUG PAL5515
     mySelectionMgr->clearSelected();
-    return true;
-  }
 
-  return false;
+    if( LightApp_Application* anApp =
+        dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
+      myObjectToSelect = anApp->browseObjects( anEntryList, isApplyAndClose() );
+  }
+  return anIsOk;
 }
 
 //=================================================================================
@@ -1012,8 +1187,10 @@ bool SMESHGUI_GroupDlg::onApply()
 //=================================================================================
 void SMESHGUI_GroupDlg::onOK()
 {
+  setIsApplyAndClose( true );
   if ( onApply() )
     onClose();
+  setIsApplyAndClose( false );
 }
 
 //=================================================================================
@@ -1181,7 +1358,6 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
       myGeomObjects->length(aNbSel);
 
       GEOM::GEOM_Object_var aGeomGroup;
-      Standard_Boolean testResult;
       int i = 0;
 
       SALOME_ListIteratorOfListIO anIt (aList);
@@ -1195,31 +1371,31 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
 
         // Check if group constructed on the same shape as a mesh or on its child
         _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
-        GEOM::GEOM_IGroupOperations_var anOp =
-          SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
 
         // The main shape of the group
         GEOM::GEOM_Object_var aGroupMainShape;
-        if (aGeomGroup->GetType() == 37)
+        if (aGeomGroup->GetType() == 37) {
+          GEOM::GEOM_IGroupOperations_wrap anOp =
+            SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
           aGroupMainShape = anOp->GetMainShape(aGeomGroup);
-        else
-          aGroupMainShape = GEOM::GEOM_Object::_duplicate(aGeomGroup);
+          // aGroupMainShape is an existing servant => GEOM_Object_var not GEOM_Object_wrap
+        }
+        else {
+          aGroupMainShape = aGeomGroup;
+          aGroupMainShape->Register();
+        }
         _PTR(SObject) aGroupMainShapeSO =
-          //aStudy->FindObjectIOR(aStudy->ConvertObjectToIOR(aGroupMainShape));
           aStudy->FindObjectID(aGroupMainShape->GetStudyEntry());
 
         _PTR(SObject) anObj, aRef;
         bool isRefOrSubShape = false;
         if (aMeshSO->FindSubObject(1, anObj) &&  anObj->ReferencedObject(aRef)) {
-          //if (strcmp(aRef->GetID(), aGroupMainShapeSO->GetID()) == 0) {
           if (aRef->GetID() == aGroupMainShapeSO->GetID()) {
             isRefOrSubShape = true;
           } else {
             _PTR(SObject) aFather = aGroupMainShapeSO->GetFather();
             _PTR(SComponent) aComponent = aGroupMainShapeSO->GetFatherComponent();
-            //while (!isRefOrSubShape && strcmp(aFather->GetID(), aComponent->GetID()) != 0) {
             while (!isRefOrSubShape && aFather->GetID() != aComponent->GetID()) {
-              //if (strcmp(aRef->GetID(), aFather->GetID()) == 0)
               if (aRef->GetID() == aFather->GetID())
                 isRefOrSubShape = true;
               else
@@ -1375,21 +1551,26 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
 }
 
 //=================================================================================
-// function : onSelectSubMesh()
-// purpose  : Called when selection in 3D view or ObjectBrowser is changed
+// function : onSelectAll()
+// purpose  : Called when "Select all" is checked
 //=================================================================================
 void SMESHGUI_GroupDlg::onSelectAll()
 {
-  myElementsLab->setEnabled( !mySelectAll->isChecked() );
-  myElements->setEnabled( !mySelectAll->isChecked() );
-  myFilter->setEnabled( !mySelectAll->isChecked() );
-  myAddBtn->setEnabled( !mySelectAll->isChecked() );
-  myRemoveBtn->setEnabled( !mySelectAll->isChecked() );
-  mySortBtn->setEnabled( !mySelectAll->isChecked() );
-  mySelectBox->setEnabled( !mySelectAll->isChecked() );
-  int selMode = mySelectionMode;
+  bool noElemsModif = ( mySelectAll->isChecked() || !myAllowElemsModif->isChecked() );
+
+  myElementsLab->setEnabled( !noElemsModif );
+  myElements->setEnabled   ( !noElemsModif );
+  myFilterBtn->setEnabled  ( !mySelectAll->isChecked() );
+  myAddBtn->setEnabled     ( !noElemsModif );
+  myRemoveBtn->setEnabled  ( !noElemsModif );
+  mySortBtn->setEnabled    ( !noElemsModif );
+  mySelectBox->setEnabled  ( !noElemsModif );
+  myAllowElemsModif->setEnabled( !mySelectAll->isChecked() );
+
+  int selMode     = mySelectionMode;
   mySelectionMode = grpNoSelection;
   setSelectionMode( selMode );
+  updateButtons();
 }
 
 //=================================================================================
@@ -1445,7 +1626,7 @@ void SMESHGUI_GroupDlg::onSelectGroup(bool on)
 
 //=================================================================================
 // function : (onSelectGeomGroup)
-// purpose  : Called when selection in 3D view or ObjectBrowser is changed
+// purpose  : Called when group type changed. on == "on group" or "on filter"
 //=================================================================================
 void SMESHGUI_GroupDlg::onSelectGeomGroup(bool on)
 {
@@ -1456,8 +1637,13 @@ void SMESHGUI_GroupDlg::onSelectGeomGroup(bool on)
     else if (mySelectGroup->isChecked()) {
       mySelectGroup->setChecked(false);
     }
-    myCurrentLineEdit = myGeomGroupLine;
-    updateGeomPopup();
+    if ( myGrpTypeId == 1 ) { // on group
+      myCurrentLineEdit = myGeomGroupLine;
+      updateGeomPopup();
+    }
+    else { // on filter
+      myCurrentLineEdit = 0;
+    }
     setSelectionMode(grpAllSelection);
   }
   else {
@@ -1466,11 +1652,10 @@ void SMESHGUI_GroupDlg::onSelectGeomGroup(bool on)
     myGeomGroupLine->setText( "" );
     myCurrentLineEdit = 0;
     if (myTypeId != -1)
-      setSelectionMode(myTypeId);
+      setSelectionMode( myTypeId );
   }
 }
 
-
 //=================================================================================
 // function : setCurrentSelection()
 // purpose  :
@@ -1517,11 +1702,13 @@ void SMESHGUI_GroupDlg::setFilters()
   SMESH::ElementType aType = SMESH::ALL;
   switch ( myTypeId )
   {
-    case 0 : aType = SMESH::NODE; break;
-    case 1 : aType = SMESH::EDGE; break;
-    case 2 : aType = SMESH::FACE; break;
-    case 3 : aType = SMESH::VOLUME; break;
-    default: return;
+    case grpNodeSelection:   aType = SMESH::NODE;   break;
+    case grp0DSelection:     aType = SMESH::ELEM0D; break;
+    case grpBallSelection:   aType = SMESH::BALL;   break;
+    case grpEdgeSelection:   aType = SMESH::EDGE;   break;
+    case grpFaceSelection:   aType = SMESH::FACE;   break;
+    case grpVolumeSelection: aType = SMESH::VOLUME; break;
+    default:                 return;
   }
 
   if ( myFilterDlg == 0 )
@@ -1532,6 +1719,12 @@ void SMESHGUI_GroupDlg::setFilters()
   else
     myFilterDlg->Init( aType );
 
+  if ( !myGroupOnFilter->_is_nil() )
+  {
+    myFilterDlg->SetFilter( myFilter, aType );
+    myFilterDlg->Init( aType );
+  }
+
   myFilterDlg->SetSelection();
   myFilterDlg->SetMesh( myMesh );
   myFilterDlg->SetSourceWg( myElements, false );
@@ -1552,6 +1745,28 @@ void SMESHGUI_GroupDlg::onFilterAccepted()
     mySelectSubMesh->setChecked( false );
     mySelectGroup->setChecked( false );
   }
+  // get a filter from myFilterDlg
+  myFilter = myFilterDlg->GetFilter();
+  if ( !myFilter->_is_nil() ) {
+    SMESH::Predicate_var perdicate = myFilter->GetPredicate();
+    if ( perdicate->_is_nil() )
+      myFilter = SMESH::Filter::_nil();
+  }
+  // set mesh to myFilter
+  if ( !myFilter->_is_nil() ) {
+    SMESH::SMESH_Mesh_var mesh = myMesh;
+    if ( mesh->_is_nil() ) {
+      if ( !myGroup->_is_nil() )
+        mesh = myGroup->GetMesh();
+      else if ( !myGroupOnGeom->_is_nil() )
+        mesh = myGroupOnGeom->GetMesh();
+      else if ( !myGroupOnFilter->_is_nil() )
+        mesh = myGroupOnFilter->GetMesh();
+    }
+    myFilter->SetMesh( mesh );
+  }
+
+  updateButtons();
 }
 
 //=================================================================================
@@ -1568,22 +1783,31 @@ void SMESHGUI_GroupDlg::onAdd()
   if (aNbSel == 0 || myActorsList.count() == 0 || myMesh->_is_nil()) return;
 
   myIsBusy = true;
+  int sizeBefore = myElements->count();
 
   SMESH::ElementType aType = SMESH::ALL;
   switch(myTypeId) {
-  case 0:
+  case grpNodeSelection:
     aType = SMESH::NODE;
     mySelector->SetSelectionMode(NodeSelection);
     break;
-  case 1:
+  case grpBallSelection:
+    aType = SMESH::BALL;
+    mySelector->SetSelectionMode(BallSelection);
+    break;
+  case grp0DSelection:
+    aType = SMESH::ELEM0D;
+    mySelector->SetSelectionMode(Elem0DSelection);
+    break;
+  case grpEdgeSelection:
     aType = SMESH::EDGE;
     mySelector->SetSelectionMode(EdgeSelection);
     break;
-  case 2:
+  case grpFaceSelection:
     aType = SMESH::FACE;
     mySelector->SetSelectionMode(FaceSelection);
     break;
-  case 3:
+  case grpVolumeSelection:
     aType = SMESH::VOLUME;
     mySelector->SetSelectionMode(VolumeSelection);
     break;
@@ -1729,15 +1953,15 @@ void SMESHGUI_GroupDlg::onAdd()
 
   } else if (myCurrentLineEdit == myGeomGroupLine && myGeomObjects->length() == 1) {
     _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
-    GEOM::GEOM_IGroupOperations_var aGroupOp =
+    GEOM::GEOM_IGroupOperations_wrap aGroupOp =
       SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
 
     SMESH::ElementType aGroupType = SMESH::ALL;
     switch(aGroupOp->GetType(myGeomObjects[0])) {
-    case 7: aGroupType = SMESH::NODE; break;
-    case 6: aGroupType = SMESH::EDGE; break;
-    case 4: aGroupType = SMESH::FACE; break;
-    case 2: aGroupType = SMESH::VOLUME; break;
+    case TopAbs_VERTEX: aGroupType = SMESH::NODE; break;
+    case TopAbs_EDGE:   aGroupType = SMESH::EDGE; break;
+    case TopAbs_FACE:   aGroupType = SMESH::FACE; break;
+    case TopAbs_SOLID:  aGroupType = SMESH::VOLUME; break;
     default: myIsBusy = false; return;
     }
 
@@ -1748,7 +1972,7 @@ void SMESHGUI_GroupDlg::onAdd()
       // Construct filter
       SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
       SMESH::Filter_var aFilter = aFilterMgr->CreateFilter();
-      SMESH::BelongToGeom_var aBelongToGeom = aFilterMgr->CreateBelongToGeom();;
+      SMESH::BelongToGeom_var aBelongToGeom = aFilterMgr->CreateBelongToGeom();
       aBelongToGeom->SetGeom(myGeomObjects[0]);
       aBelongToGeom->SetShapeName(aGroupSO->GetName().c_str());
       aBelongToGeom->SetElementType(aType);
@@ -1785,6 +2009,8 @@ void SMESHGUI_GroupDlg::onAdd()
     onListSelectionChanged();
   }
   myIsBusy = false;
+  if ( sizeBefore < myElements->count() )
+    ++myNbChangesOfContents;
   //  mySelectionMgr->clearSelected();
   updateButtons();
 }
@@ -1796,6 +2022,8 @@ void SMESHGUI_GroupDlg::onAdd()
 void SMESHGUI_GroupDlg::onRemove()
 {
   myIsBusy = true;
+  int sizeBefore = myElements->count();
+
   if (myCurrentLineEdit == 0) {
     QList<QListWidgetItem*> selItems = myElements->selectedItems();
     QListWidgetItem* item;
@@ -1810,10 +2038,12 @@ void SMESHGUI_GroupDlg::onRemove()
 
     SMESH::ElementType aType = SMESH::ALL;
     switch(myTypeId) {
-    case 0: aType = SMESH::NODE; break;
-    case 1: aType = SMESH::EDGE; break;
-    case 2: aType = SMESH::FACE; break;
-    case 3: aType = SMESH::VOLUME; break;
+    case grpNodeSelection:   aType = SMESH::NODE;   break;
+    case grp0DSelection:     aType = SMESH::ELEM0D; break;
+    case grpBallSelection:   aType = SMESH::BALL;   break;
+    case grpEdgeSelection:   aType = SMESH::EDGE;   break;
+    case grpFaceSelection:   aType = SMESH::FACE;   break;
+    case grpVolumeSelection: aType = SMESH::VOLUME; break;
     }
 
     if (myCurrentLineEdit == mySubMeshLine) {
@@ -1887,6 +2117,8 @@ void SMESHGUI_GroupDlg::onRemove()
     }
   }
   myIsBusy = false;
+  if ( sizeBefore > myElements->count() )
+    myNbChangesOfContents += 2; // it's used to detect that "Add" was only once
   updateButtons();
 }
 
@@ -1964,7 +2196,13 @@ void SMESHGUI_GroupDlg::onClose()
     restoreShowEntityMode();
   }
 
-  mySelectionMgr->clearSelected();
+  if( isApplyAndClose() && !myObjectToSelect.isEmpty() ) {
+    SUIT_DataOwnerPtrList aList;
+    aList.append( new LightApp_DataOwner( myObjectToSelect ) );
+    mySelectionMgr->setSelected( aList );
+  }
+  else
+    mySelectionMgr->clearSelected();
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
     aViewWindow->SetSelectionMode(ActorSelection);
   mySelectionMgr->clearFilters();
@@ -2239,7 +2477,7 @@ void SMESHGUI_GroupDlg::setDefaultGroupColor()
   if( !isAutoColor )
   {
     int r = 0, g = 0, b = 0;
-    SMESH::GetColor( "SMESH", "fill_color", r, g, b, QColor( 0, 170, 255 ) );
+    SMESH::GetColor( "SMESH", "default_grp_color", r, g, b, QColor( 255, 170, 0 ) );
     aQColor.setRgb( r, g, b );
   }
   else
@@ -2362,10 +2600,12 @@ void SMESHGUI_GroupDlg::setShowEntityMode()
       if (!myStoredShownEntity)
         myStoredShownEntity = actor->GetEntityMode();
       switch ( myTypeId ) {
-      case 0: restoreShowEntityMode(); break;
-      case 1: actor->SetEntityMode( SMESH_Actor::eEdges ); break;
-      case 2: actor->SetEntityMode( SMESH_Actor::eFaces ); break;
-      case 3: actor->SetEntityMode( SMESH_Actor::eVolumes ); break;
+      case grpNodeSelection:   restoreShowEntityMode();                          break;
+      case grp0DSelection:     actor->SetEntityMode( SMESH_Actor::e0DElements ); break;
+      case grpBallSelection:   actor->SetEntityMode( SMESH_Actor::eBallElem );   break;
+      case grpEdgeSelection:   actor->SetEntityMode( SMESH_Actor::eEdges );      break;
+      case grpFaceSelection:   actor->SetEntityMode( SMESH_Actor::eFaces );      break;
+      case grpVolumeSelection: actor->SetEntityMode( SMESH_Actor::eVolumes );    break;
       }
     }
   }
@@ -2396,3 +2636,23 @@ bool SMESHGUI_GroupDlg::IsActorVisible( SMESH_Actor* theActor )
     return aViewWindow->isVisible(theActor->getIO());
   return false;
 }
+
+//================================================================
+//function : setIsApplyAndClose
+//purpose  : Set value of the flag indicating that the dialog is
+//           accepted by Apply & Close button
+//================================================================
+void SMESHGUI_GroupDlg::setIsApplyAndClose( const bool theFlag )
+{
+  myIsApplyAndClose = theFlag;
+}
+
+//================================================================
+//function : isApplyAndClose
+//purpose  : Get value of the flag indicating that the dialog is
+//           accepted by Apply & Close button
+//================================================================
+bool SMESHGUI_GroupDlg::isApplyAndClose() const
+{
+  return myIsApplyAndClose;
+}