Salome HOME
Fix for the "0051573: TC6.6.0: Clipping - Select all check-box behavior is wrong...
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_DuplicateNodesDlg.cxx
index a2a0afd9c0a6c41e6d03ccd4661bec4f3e514f93..1ee5ab8c9af6dc321ffc7a2398c707d2932ed009 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
@@ -47,6 +47,7 @@
 
 #include <SVTK_ViewWindow.h>
 #include <SALOME_ListIO.hxx>
+#include <SALOME_ListIteratorOfListIO.hxx>
 
 // Qt includes
 #include <QApplication>
 #define SPACING 6
 #define MARGIN  11
 
+/*!
+  \class BusyLocker
+  \brief Simple 'busy state' flag locker.
+  \internal
+*/
+
+class BusyLocker
+{
+public:
+  //! Constructor. Sets passed boolean flag to \c true.
+  BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; }
+  //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false.
+  ~BusyLocker() { myBusy = false; }
+private:
+  bool& myBusy; //! External 'busy state' boolean flag
+};
 
 /*!
   \brief Constructor
@@ -138,7 +155,8 @@ SMESHGUI_DuplicateNodesDlg::SMESHGUI_DuplicateNodesDlg( SMESHGUI* theModule )
   myLineEdit3 = new QLineEdit(myGroupArguments);
   myLineEdit3->setReadOnly(true);
 
-  myCheckBoxNewGroup = new QCheckBox(tr("CONSTRUCT_NEW_GROUP_NODES"), myGroupArguments);
+  myCheckBoxNewElemGroup = new QCheckBox(tr("CONSTRUCT_NEW_GROUP_ELEMENTS"), myGroupArguments);
+  myCheckBoxNewNodeGroup = new QCheckBox(tr("CONSTRUCT_NEW_GROUP_NODES"), myGroupArguments);
 
   aGroupArgumentsLayout->addWidget(myTextLabel1,    0, 0);
   aGroupArgumentsLayout->addWidget(mySelectButton1, 0, 1);
@@ -149,8 +167,9 @@ SMESHGUI_DuplicateNodesDlg::SMESHGUI_DuplicateNodesDlg( SMESHGUI* theModule )
   aGroupArgumentsLayout->addWidget(myTextLabel3,    2, 0);
   aGroupArgumentsLayout->addWidget(mySelectButton3, 2, 1);
   aGroupArgumentsLayout->addWidget(myLineEdit3,     2, 2);
-  aGroupArgumentsLayout->addWidget(myCheckBoxNewGroup, 3, 0);
-  aGroupArgumentsLayout->setRowStretch(4, 1);
+  aGroupArgumentsLayout->addWidget(myCheckBoxNewElemGroup, 3, 0);
+  aGroupArgumentsLayout->addWidget(myCheckBoxNewNodeGroup, 4, 0);
+  aGroupArgumentsLayout->setRowStretch(5, 1);
   
   // Buttons
   QGroupBox* aGroupButtons = new QGroupBox(this);
@@ -218,17 +237,19 @@ SMESHGUI_DuplicateNodesDlg::~SMESHGUI_DuplicateNodesDlg()
 void SMESHGUI_DuplicateNodesDlg::Init()
 {
   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+  myCheckBoxNewElemGroup->setChecked(true);
+  myCheckBoxNewNodeGroup->setChecked(true);
 
   // Set initial parameters
   myBusy = false;
   myCurrentLineEdit = myLineEdit1;
 
-  myGroup1 =  SMESH::SMESH_GroupBase::_nil();
-  myGroup2 =  SMESH::SMESH_GroupBase::_nil();
-  myGroup3 =  SMESH::SMESH_GroupBase::_nil();
+  myGroups1.clear();
+  myGroups2.clear();
+  myGroups3.clear();
   
   // Set selection mode
-  mySelectionMgr->installFilter(new SMESH_TypeFilter(GROUP));
+  mySelectionMgr->installFilter(new SMESH_TypeFilter(SMESH::GROUP));
   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
     aViewWindow->SetSelectionMode(ActorSelection);
   
@@ -253,8 +274,9 @@ void SMESHGUI_DuplicateNodesDlg::onConstructorsClicked (int constructorId)
   myLineEdit2->clear();
   myLineEdit3->clear();
 
-  // Checkbox should be checked by default
-  myCheckBoxNewGroup->setChecked(true);
+  myGroups1.clear();
+  myGroups2.clear();
+  myGroups3.clear();
 
   // Set the first field as current
   myCurrentLineEdit = myLineEdit1;
@@ -268,8 +290,8 @@ void SMESHGUI_DuplicateNodesDlg::onConstructorsClicked (int constructorId)
       myTextLabel1->setText(tr("GROUP_NODES_TO_DUPLICATE"));
       myTextLabel2->setText(tr("GROUP_NODES_TO_REPLACE"));
 
-      // Set checkbox title
-      myCheckBoxNewGroup->setText(tr("CONSTRUCT_NEW_GROUP_NODES"));
+      myCheckBoxNewElemGroup->hide();
+      myCheckBoxNewNodeGroup->show();
       
       // Hide the third field
       myTextLabel3->hide();
@@ -286,8 +308,8 @@ void SMESHGUI_DuplicateNodesDlg::onConstructorsClicked (int constructorId)
       myTextLabel2->setText(tr("GROUP_NODES_NOT_DUPLICATE"));
       myTextLabel3->setText(tr("GROUP_ELEMS_TO_REPLACE"));
       
-      // Set checkbox title
-      myCheckBoxNewGroup->setText(tr("CONSTRUCT_NEW_GROUP_ELEMENTS"));
+      myCheckBoxNewElemGroup->show();
+      myCheckBoxNewNodeGroup->show();
 
       // Show the third field
       myTextLabel3->show();
@@ -307,12 +329,13 @@ void SMESHGUI_DuplicateNodesDlg::onConstructorsClicked (int constructorId)
 */
 bool SMESHGUI_DuplicateNodesDlg::onApply()
 {
-  if (mySMESHGUI->isActiveStudyLocked() || !isValid())
+  if ( mySMESHGUI->isActiveStudyLocked() || !isValid() )
     return false;
 
-  myBusy = true;
+  BusyLocker lock( myBusy );
  
-  bool toCreateGroup = myCheckBoxNewGroup->isChecked();
+  bool toCreateElemGroup = myCheckBoxNewElemGroup->isChecked();
+  bool toCreateNodeGroup = myCheckBoxNewNodeGroup->isChecked();
   int operationMode = myGroupConstructors->checkedId();
   
   // Apply changes
@@ -320,28 +343,51 @@ bool SMESHGUI_DuplicateNodesDlg::onApply()
   SUIT_OverrideCursor aWaitCursor;
 
   try {
-    SMESH::SMESH_Mesh_ptr aMesh =  myGroup1->GetMesh();
+    SMESH::SMESH_Mesh_var aMesh = myGroups1[0]->GetMesh();
     SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
 
-    if (operationMode == 0) {
-      if (toCreateGroup) {
-        SMESH::SMESH_GroupBase_ptr aNewGroup = 
-          aMeshEditor->DoubleNodeGroupNew(myGroup1, myGroup2);
-        if (!CORBA::is_nil(aNewGroup))
-      result = true;
+    if ( operationMode == 0 ) {
+      SMESH::ListOfGroups_var g1 = new SMESH::ListOfGroups();
+      g1->length( myGroups1.count() );
+      for ( int i = 0; i < myGroups1.count(); i++ )
+        g1[i] = myGroups1[i];
+      SMESH::ListOfGroups_var g2 = new SMESH::ListOfGroups();
+      g2->length( myGroups2.count() );
+      for ( int i = 0; i < myGroups2.count(); i++ )
+        g2[i] = myGroups2[i];
+
+      if ( toCreateNodeGroup ) {
+        SMESH::SMESH_GroupBase_var aNewGroup = 
+          aMeshEditor->DoubleNodeGroupsNew( g1.in(), g2.in() );
+        result = !CORBA::is_nil( aNewGroup );
+      }
+      else {
+        result = aMeshEditor->DoubleNodeGroups( g1.in(), g2.in() );
       }
-      else
-        result = aMeshEditor->DoubleNodeGroup(myGroup1, myGroup2);
     }
     else {
-      if (toCreateGroup) {
-        SMESH::SMESH_GroupBase_ptr aNewGroup = 
-          aMeshEditor->DoubleNodeElemGroupNew(myGroup1, myGroup2, myGroup3);
-        if (!CORBA::is_nil(aNewGroup))
-          result = true;
+      SMESH::ListOfGroups_var g1 = new SMESH::ListOfGroups();
+      g1->length( myGroups1.count() );
+      for ( int i = 0; i < myGroups1.count(); i++ )
+        g1[i] = myGroups1[i];
+      SMESH::ListOfGroups_var g2 = new SMESH::ListOfGroups();
+      g2->length( myGroups2.count() );
+      for ( int i = 0; i < myGroups2.count(); i++ )
+        g2[i] = myGroups2[i];
+      SMESH::ListOfGroups_var g3 = new SMESH::ListOfGroups();
+      g3->length( myGroups3.count() );
+
+      for ( int i = 0; i < myGroups3.count(); i++ )
+        g3[i] = myGroups3[i];
+      if ( toCreateElemGroup || toCreateNodeGroup ) {
+        SMESH::ListOfGroups_var aNewGroups = 
+          aMeshEditor->DoubleNodeElemGroups2New( g1.in(), g2.in(), g3.in(),
+                                                 toCreateElemGroup, toCreateNodeGroup );
+        result = ( aNewGroups[ !toCreateElemGroup ].in() );
+      }
+      else {
+        result = aMeshEditor->DoubleNodeElemGroups( g1.in(), g2.in(), g3.in() );
       }
-      else
-        result = aMeshEditor->DoubleNodeElemGroup(myGroup1, myGroup2, myGroup3);
     }
   }
   catch (const SALOME::SALOME_Exception& S_ex) {
@@ -358,7 +404,6 @@ bool SMESHGUI_DuplicateNodesDlg::onApply()
     SUIT_MessageBox::warning(this,
                              tr("SMESH_WRN_WARNING"),
                              tr("SMESH_OPERATION_FAILED"));
-    myBusy = false;
     return false;
   }
 
@@ -400,64 +445,68 @@ void SMESHGUI_DuplicateNodesDlg::onClose()
 */
 void SMESHGUI_DuplicateNodesDlg::onSelectionChanged()
 {
-  if (myBusy || !isEnabled()) return;
+  if ( myBusy || !isEnabled() ) return;
   
-  // Try to get selected group
+  int operationMode = myGroupConstructors->checkedId();
+
   SALOME_ListIO aList;
   mySelectionMgr->selectedObjects( aList );
-  int aNbSel = aList.Extent();
-
-  SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_nil();
-  if (aNbSel == 1) {
-    Handle(SALOME_InteractiveObject) IO = aList.First();
-    aGroup = SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO);
-
-    // Check group type
-    if (!CORBA::is_nil(aGroup)) {
-      int operationMode = myGroupConstructors->checkedId();
+  //int aNbSel = aList.Extent();
+
+  QList<SMESH::SMESH_GroupBase_var> aGroups;
+
+  SALOME_ListIteratorOfListIO anIter ( aList );
+  bool ok = true;
+  for ( ; anIter.More() && ok; anIter.Next()) {
+    SMESH::SMESH_GroupBase_var aGroup = SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>( anIter.Value() );
+    // check group is selected
+    ok = !CORBA::is_nil( aGroup );
+    // check groups of the same mesh are selected
+    if ( ok ) {
+      SMESH::SMESH_Mesh_var aMesh1;
+      if ( !aGroups.isEmpty() ) aMesh1 = aGroups[0]->GetMesh();
+      SMESH::SMESH_Mesh_var aMesh2 = aGroup->GetMesh();
+      ok = CORBA::is_nil( aMesh1 ) || aMesh1->_is_equivalent( aMesh2 );
+    }
+    // check group of proper type is selected
+    if ( ok ) {
       SMESH::ElementType aGroupType = aGroup->GetType();
-      bool isTypeValid = true;
-      
-      if (operationMode == 0) {
-        if ( (myCurrentLineEdit == myLineEdit1 && aGroupType != SMESH::NODE) ||
-             (myCurrentLineEdit == myLineEdit2 && aGroupType == SMESH::NODE) )
-          isTypeValid = false;
+      if ( operationMode == 0 ) {
+        ok = ( myCurrentLineEdit == myLineEdit1 && aGroupType == SMESH::NODE ) ||
+             ( myCurrentLineEdit == myLineEdit2 && aGroupType != SMESH::NODE );
       }
-      else if (operationMode == 1) {
-        if ( (myCurrentLineEdit == myLineEdit1 && aGroupType != SMESH::EDGE &&
-              aGroupType != SMESH::FACE) ||
-             (myCurrentLineEdit == myLineEdit2 && aGroupType != SMESH::NODE) || 
-             (myCurrentLineEdit == myLineEdit3 && aGroupType == SMESH::NODE) )
-          isTypeValid = false;
+      else {
+        ok = ( myCurrentLineEdit == myLineEdit1 && ( aGroupType == SMESH::EDGE ||
+                                                     aGroupType == SMESH::FACE ) ) ||
+             ( myCurrentLineEdit == myLineEdit2 && aGroupType == SMESH::NODE )     ||
+             ( myCurrentLineEdit == myLineEdit3 && aGroupType != SMESH::NODE );
       }
-    
-      if (!isTypeValid)
-        aGroup = SMESH::SMESH_GroupBase::_nil();
     }
+    if ( ok ) aGroups << aGroup;
   }
 
   // Clear current field
   myCurrentLineEdit->clear();
 
-  // Set corresponding SMESH group
-  if (myCurrentLineEdit == myLineEdit1) {
-    myGroup1 = SMESH::SMESH_Group::_narrow(aGroup);
-  }
-  else if (myCurrentLineEdit == myLineEdit2) {
-    myGroup2 = SMESH::SMESH_Group::_narrow(aGroup);
+  if ( ok && !aGroups.isEmpty() ) {
+    if      ( myCurrentLineEdit == myLineEdit1 ) myGroups1 = aGroups;
+    else if ( myCurrentLineEdit == myLineEdit2 ) myGroups2 = aGroups;
+    else if ( myCurrentLineEdit == myLineEdit3 ) myGroups3 = aGroups;
+    CORBA::String_var name = aGroups[0]->GetName();
+    myCurrentLineEdit->setText( aGroups.count() == 1 ? QString(name).trimmed() : 
+                                QObject::tr( "SMESH_OBJECTS_SELECTED" ).arg( aGroups.count() ) );
   }
-  else if (myCurrentLineEdit == myLineEdit3) {
-    myGroup3 = SMESH::SMESH_Group::_narrow(aGroup);
+  else {
+    if      ( myCurrentLineEdit == myLineEdit1 ) myGroups1.clear();
+    else if ( myCurrentLineEdit == myLineEdit2 ) myGroups2.clear();
+    else if ( myCurrentLineEdit == myLineEdit3 ) myGroups3.clear();
+    myCurrentLineEdit->clear();
   }
-  
-  // Set group name
-  if (!CORBA::is_nil(aGroup))
-    myCurrentLineEdit->setText(aGroup->GetName());
 
   // Enable/disable "Apply and Close" and "Apply" buttons
   bool isDataValid = isValid();
-  myButtonOk->setEnabled(isDataValid);
-  myButtonApply->setEnabled(isDataValid);
+  myButtonOk->setEnabled( isDataValid );
+  myButtonApply->setEnabled( isDataValid );
 }
 
 /*!
@@ -488,14 +537,9 @@ void SMESHGUI_DuplicateNodesDlg::onEditCurrentArgument()
 */
 bool SMESHGUI_DuplicateNodesDlg::isValid()
 {
-  // Only first group (nodes/elemets to duplicate) is mandatory
-  bool isValid = !CORBA::is_nil(myGroup1);
-  
-  // First (elements to duplicate) and last groups should be defined in the second operation mode
-  if (isValid && myGroupConstructors->checkedId() == 1)
-    isValid = !CORBA::is_nil(myGroup3);
-
-  return isValid;
+  return myGroupConstructors->checkedId() == 1 ?
+    ( !myGroups1.isEmpty() && !myGroups3.isEmpty()  ) :
+    ( !myGroups1.isEmpty() );
 }
 
 
@@ -527,7 +571,7 @@ void SMESHGUI_DuplicateNodesDlg::enterEvent (QEvent*)
     // Set selection mode
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
       aViewWindow->SetSelectionMode(ActorSelection);
-    mySelectionMgr->installFilter(new SMESH_TypeFilter (GROUP));
+    mySelectionMgr->installFilter(new SMESH_TypeFilter (SMESH::GROUP));
   }
 }