Salome HOME
Merge remote-tracking branch 'remotes/origin/hydro/imps_2017_salome_83' into HEAD
[modules/geom.git] / src / GroupGUI / GroupGUI_GroupDlg.cxx
index 464bee9e5c1e5094ead4ff3f62d2fdcb0a31d6e1..a7ce624ec35f4e87a713f93b9ae5da102c363753 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  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
 #include <GEOMBase.h>
 #include <GeometryGUI.h>
 #include <GEOM_Displayer.h>
+#include <GEOMUtils.hxx>
+#ifndef DISABLE_PLOT2DVIEWER
+#include <MeasureGUI_ShapeStatisticsDlg.h>
+#endif
 
 #include <SalomeApp_Application.h>
 #include <SalomeApp_Study.h>
 #include <SalomeApp_Tools.h>
 
 #include <LightApp_SelectionMgr.h>
+#include "utilities.h"
 
 #include <OCCViewer_ViewModel.h>
 #include <OCCViewer_ViewManager.h>
 #include <SVTK_ViewModel.h>
 #include <SALOME_Prs.h>
-#include <SALOME_ListIteratorOfListIO.hxx>
+#include <SALOME_ListIO.hxx>
+#include "utilities.h"
 
 #include <SUIT_Desktop.h>
 #include <SUIT_MessageBox.h>
 #define GROUP_IDLST_COLOR Qt::blue // Specific color for the IDs of subShapes in the dialog box
 #define GROUP_NEWIDLST_COLOR Qt::red // Specific color for the new IDs of subShapes in the dialog box
 
-enum { ALL_SUBSHAPES = 0, GET_IN_PLACE, SUBSHAPES_OF_SHAPE2, SUBSHAPES_OF_INVISIBLE_SHAPE2 };
+namespace {
+  enum { ALL_SUBSHAPES = 0, GET_IN_PLACE, SUBSHAPES_OF_SHAPE2, SUBSHAPES_OF_INVISIBLE_SHAPE2 };
+  enum { Filter_LT, Filter_LE, Filter_GT, Filter_GE };
+}
 
 GroupGUI_GroupDlg::GroupGUI_GroupDlg (Mode mode, GeometryGUI* theGeometryGUI, QWidget* parent)
   : GEOMBase_Skeleton(theGeometryGUI, parent, false),
     myMode(mode),
     myBusy(false),
     myIsShapeType(false),
-    myIsHiddenMain(false)
+    myIsHiddenMain(false),
+    myWasHiddenMain(true),
+    myIsAccept(false)
 {
   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
 
@@ -179,9 +190,40 @@ GroupGUI_GroupDlg::GroupGUI_GroupDlg (Mode mode, GeometryGUI* theGeometryGUI, QW
   aMedLayout->setRowStretch(5, 5);
   aMedLayout->setRowStretch(8, 5);
 
+  //filter group
+
+  myFilterGrp = new QGroupBox(tr("GEOM_FILTER"), centralWidget());
+  myLessFilterCheck = new QCheckBox(myFilterGrp);
+  myLessFilterCombo = new QComboBox(myFilterGrp);
+  myLessFilterCombo->addItem( tr("GEOM_LESS_THAN"), Filter_LT );
+  myLessFilterCombo->addItem( tr("GEOM_LESSOREQUAL_THAN"), Filter_LE );
+  myGreaterFilterCheck = new QCheckBox(myFilterGrp);
+  myGreaterFilterCombo = new QComboBox(myFilterGrp);
+  myGreaterFilterCombo->addItem( tr("GEOM_GREAT_THAN"), Filter_GT );
+  myGreaterFilterCombo->addItem( tr("GEOM_GREATOREQUAL_THAN"), Filter_GE );
+  myLessFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp);
+  myGreaterFilterSpin = new SalomeApp_DoubleSpinBox(myFilterGrp);
+  myApplyFilterButton = new QPushButton(tr("GEOM_BUT_APPLY"), myFilterGrp);
+#ifndef DISABLE_PLOT2DVIEWER
+  myPlotDistributionButton = new QPushButton(tr("GEOM_PLOT_DISTRIBUTION"), myFilterGrp);
+#endif
+
+  QGridLayout* filterLayout = new QGridLayout(myFilterGrp);
+  filterLayout->addWidget(myLessFilterCheck,    0, 0);
+  filterLayout->addWidget(myLessFilterCombo,    0, 1);
+  filterLayout->addWidget(myLessFilterSpin,     0, 2);
+  filterLayout->addWidget(myGreaterFilterCheck, 1, 0);
+  filterLayout->addWidget(myGreaterFilterCombo, 1, 1);
+  filterLayout->addWidget(myGreaterFilterSpin,  1, 2);
+  filterLayout->addWidget(myApplyFilterButton,  0, 3);
+#ifndef DISABLE_PLOT2DVIEWER
+  filterLayout->addWidget(myPlotDistributionButton,  1, 3);
+#endif
+
   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
   layout->setMargin(0); layout->setSpacing(6);
   layout->addWidget(GroupMedium);
+  layout->addWidget(myFilterGrp);
 
   setHelpFileName("work_with_groups_page.html");
 
@@ -192,7 +234,12 @@ GroupGUI_GroupDlg::GroupGUI_GroupDlg (Mode mode, GeometryGUI* theGeometryGUI, QW
 GroupGUI_GroupDlg::~GroupGUI_GroupDlg()
 {
   GEOM_Displayer* aDisplayer = getDisplayer();
-  if (myIsHiddenMain) {
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+  bool isHideObjects = resMgr->booleanValue( "Geometry", "hide_input_object", true);
+  if (myWasHiddenMain || ( isHideObjects && myIsAccept ) ) {
+    myIsHiddenMain = true;
+  }
+  else {
     aDisplayer->Display(myMainObj);
     myIsHiddenMain = false;
   }
@@ -206,6 +253,16 @@ GroupGUI_GroupDlg::~GroupGUI_GroupDlg()
 //=================================================================================
 void GroupGUI_GroupDlg::Init()
 {
+  // Get setting of step value from file configuration
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+  double step = resMgr->doubleValue("Geometry", "SettingsGeomStep", 100);
+
+  // min, max, step and decimals for spin boxes
+  initSpinBox(myLessFilterSpin, 0., COORD_MAX, step, "length_precision" );
+  initSpinBox(myGreaterFilterSpin, 0., COORD_MAX, step, "length_precision" );
+  myLessFilterSpin->setValue( 0. );
+  myGreaterFilterSpin->setValue( 0. );
+
   myDmMode = -1;
   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
 
@@ -238,8 +295,16 @@ void GroupGUI_GroupDlg::Init()
 
         GEOM::GEOM_IGroupOperations_var anOper = GEOM::GEOM_IGroupOperations::_narrow(getOperation());
         myMainObj = anOper->GetMainShape(myGroup);
-        if (!CORBA::is_nil(myMainObj))
+        if (!CORBA::is_nil(myMainObj)) {
           myMainName->setText(GEOMBase::GetName(myMainObj));
+          SALOME_View* view = GEOM_Displayer::GetActiveView();
+          if (view) {
+            CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
+            Handle(SALOME_InteractiveObject) io =
+              new SALOME_InteractiveObject (aMainEntry.in(), "GEOM", "TEMP_IO");
+            if (view->isVisible(io)) myWasHiddenMain = false;
+          }
+        }
 
         setShapeType((TopAbs_ShapeEnum)anOper->GetType(myGroup));
 
@@ -270,11 +335,19 @@ void GroupGUI_GroupDlg::Init()
   connect(myShowAllBtn,    SIGNAL(clicked()),              this, SLOT(showOnlySelected()));
   connect(myIdList,        SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged()));
 
+  connect(myApplyFilterButton, SIGNAL(clicked()),         this, SLOT(ClickOnOkFilter()));
+#ifndef DISABLE_PLOT2DVIEWER
+  connect(myPlotDistributionButton, SIGNAL(clicked()),    this, SLOT(ClickOnPlot()));
+#endif
+  connect(myLessFilterCheck,   SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled()));
+  connect(myGreaterFilterCheck,   SIGNAL(stateChanged(int)), this, SLOT(MeasureToggled()));
+
   setInPlaceObj(GEOM::GEOM_Object::_nil());
 
   myBusy = true; // just activate but do not select in the list
   activateSelection();
   myBusy = false;
+  MeasureToggled();
 }
 
 //=================================================================================
@@ -309,6 +382,7 @@ void GroupGUI_GroupDlg::ClickOnOk()
   if (ClickOnApply())
     ClickOnCancel();
   setIsApplyAndClose(false);
+  getDisplayer()->UnsetDisplayMode();
 }
 
 //=================================================================================
@@ -322,7 +396,8 @@ bool GroupGUI_GroupDlg::ClickOnApply()
     setIsDisplayResult( false );
   }
     
-  if (!onAccept(myMode == CreateGroup, true, isApplyAndClose()))
+  myIsAccept = onAccept(myMode == CreateGroup, true, isApplyAndClose());
+  if (!myIsAccept)
     return false;
 
   if(!isApplyAndClose()) {
@@ -373,16 +448,22 @@ void GroupGUI_GroupDlg::ActivateThisDialog()
 //=================================================================================
 void GroupGUI_GroupDlg::SetEditCurrentArgument()
 {
-  QPushButton* send = (QPushButton*)sender();
+  QPushButton* send = qobject_cast<QPushButton*>( sender() );
 
   if (send == mySelBtn) {
     myEditCurrentArgument = myMainName;
     myShape2Name->setText("");
+    mySelBtn->setDown(true);
+    mySelBtn2->setDown(false);
   }
   else if (send == mySelBtn2 || sender() == myRestrictGroup) {
     setInPlaceObj(GEOM::GEOM_Object::_nil());
     myShape2Name->setText("");
-    if (subSelectionWay() != ALL_SUBSHAPES) {
+    if ( send == mySelBtn2 ) {
+      mySelBtn2->setDown(true);
+      mySelBtn->setDown(false);
+    }
+  if (subSelectionWay() != ALL_SUBSHAPES) {
       myEditCurrentArgument = myShape2Name;
     }
     else {
@@ -390,7 +471,12 @@ void GroupGUI_GroupDlg::SetEditCurrentArgument()
     }
   }
 
-  activateSelection();
+  //  activateSelection();
+  if(myEditCurrentArgument) {
+    myEditCurrentArgument->setFocus();
+    if ( send )
+      send->setDown(true);
+  }
 
   updateState();
 }
@@ -497,6 +583,9 @@ void GroupGUI_GroupDlg::SelectionIntoArgument()
 {
   if (subSelectionWay() != ALL_SUBSHAPES && myEditCurrentArgument == myShape2Name) {
     onGetInPlace();
+    if( !myInPlaceObj->_is_nil() ) {
+      mySelBtn2->setDown(false);
+    }
     return;
   }
 
@@ -520,6 +609,16 @@ void GroupGUI_GroupDlg::SelectionIntoArgument()
           myIsHiddenMain = false;
         }
         myMainObj = anObj;
+        if (!CORBA::is_nil(myMainObj)) {
+         mySelBtn->setDown(false);
+          SALOME_View* view = GEOM_Displayer::GetActiveView();
+          if (view) {
+            CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
+            Handle(SALOME_InteractiveObject) io =
+              new SALOME_InteractiveObject (aMainEntry.in(), "GEOM", "TEMP_IO");
+            if (view->isVisible(io)) myWasHiddenMain = false;
+          }
+        }
         myEditCurrentArgument->setText(GEOMBase::GetName(anObj));
         // activate sub-shapes selection by default
         myEditCurrentArgument = 0;
@@ -782,17 +881,27 @@ int GroupGUI_GroupDlg::getSelectedSubshapes (TColStd_IndexedMapOfInteger& theMap
         TopoDS_Shape aShape;
         if (GEOMBase::GetShape(aGeomObj, aShape)) {
           if (aGeomObj->GetType() == GEOM_GROUP || aShape.ShapeType() == getShapeType()) {
+            if (subSelectionWay() != ALL_SUBSHAPES &&
+                GEOMBase::GetName(aGeomObj) == myShape2Name->text()) {
+              // Skip selected in place object.
+              continue;
+            }
+
             TopTools_IndexedMapOfShape aMainMap;
             TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj);
             TopExp::MapShapes(aMainShape, aMainMap);
 
             TopExp_Explorer anExp (aShape, getShapeType());
+            bool isShowWarning = true;
             for (; anExp.More(); anExp.Next()) {
               TopoDS_Shape aSubShape = anExp.Current();
               int anIndex = aMainMap.FindIndex(aSubShape);
               if (anIndex == 0) {
-                SUIT_MessageBox::warning(app->desktop(), QObject::tr("WRN_WARNING"),
+                if (isShowWarning) {
+                  SUIT_MessageBox::warning(app->desktop(), QObject::tr("WRN_WARNING"),
                                          tr("WRN_NOT_SUBSHAPE"));
+                  isShowWarning = false;
+                }
               }
               else {
                 if (subSelectionWay() != ALL_SUBSHAPES &&
@@ -989,7 +1098,7 @@ void GroupGUI_GroupDlg::activateSelection()
           int index = aSubShapesMap.FindIndex(aSubShape);
           QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index);
           Handle(SALOME_InteractiveObject) io =
-            new SALOME_InteractiveObject(anEntry.toAscii(), "GEOM", "TEMP_IO");
+            new SALOME_InteractiveObject(anEntry.toLatin1(), "GEOM", "TEMP_IO");
           if ( myGroupIdList.contains( index ) ) {
             aDisplayer->SetColor( aCol );
           }
@@ -1054,9 +1163,25 @@ void GroupGUI_GroupDlg::updateState (bool isAdd)
   myRemBtn->setEnabled(hasSel);
   myRestrictGroupBox->setEnabled(!CORBA::is_nil(myMainObj));
   mySelAllBtn->setEnabled(!CORBA::is_nil(myMainObj));
-
+  
   mySelBtn2->setEnabled(subSelectionWay() != ALL_SUBSHAPES);
   myShape2Name->setEnabled(subSelectionWay() != ALL_SUBSHAPES);
+  myFilterGrp->setEnabled(!CORBA::is_nil(myMainObj) &&
+                          subSelectionWay() == ALL_SUBSHAPES &&
+                          myIsShapeType &&
+                          getShapeType() != TopAbs_VERTEX);
+  // manage of 'Plot' button access
+  GEOM::GEOM_IShapesOperations_var aShOp = getGeomEngine()->GetIShapesOperations( getStudyId() );
+  GEOM::ListOfLong_var aSubShapes = aShOp->SubShapeAllIDs( myMainObj, getShapeType(), false );
+  bool hasCurrentEntities = aSubShapes->length() > 0;
+#ifndef DISABLE_PLOT2DVIEWER
+  myPlotDistributionButton->setEnabled( myFilterGrp->isEnabled() &&
+                                       myIsShapeType &&
+                                       ( getShapeType() == TopAbs_EDGE || 
+                                         getShapeType() == TopAbs_FACE ||
+                                         getShapeType() == TopAbs_SOLID ) &&
+                                       hasCurrentEntities );
+#endif
   if (subSelectionWay() == ALL_SUBSHAPES)
     setInPlaceObj(GEOM::GEOM_Object::_nil());
 }
@@ -1291,3 +1416,92 @@ GEOM::GEOM_Object_ptr GroupGUI_GroupDlg::getFather(GEOM::GEOM_Object_ptr theObj)
   }
   return aFatherObj._retn();
 }
+
+void GroupGUI_GroupDlg::ClickOnOkFilter()
+{
+  if (CORBA::is_nil(myMainObj) || subSelectionWay() != ALL_SUBSHAPES || !myIsShapeType || getShapeType() == TopAbs_VERTEX)
+    return;
+  
+  TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj);
+  TopTools_IndexedMapOfShape aSubShapesMap;
+  TopExp::MapShapes(aMainShape, aSubShapesMap);
+  SALOME_View* view = GEOM_Displayer::GetActiveView();
+  getDisplayer()->Erase(myMainObj, false, false);
+  CORBA::String_var aMainEntry = myMainObj->GetStudyEntry();
+  QString anEntryBase = aMainEntry.in();
+
+  SALOME_ListIO toSelect;
+
+  TopExp_Explorer anExp (aMainShape, (TopAbs_ShapeEnum)getShapeType());
+  for (; anExp.More(); anExp.Next())
+  {
+    TopoDS_Shape aSubShape = anExp.Current();
+    int index = aSubShapesMap.FindIndex(aSubShape);
+    QString anEntry = QString( "TEMP_" ) + anEntryBase + QString("_%1").arg(index);
+    if ( !getDisplayer()->IsDisplayed( anEntry ) )
+      continue;
+
+    double factor = GEOMUtils::ShapeToDouble(aSubShape).second;
+    double v1 = myLessFilterSpin->value();
+    double v2 = myGreaterFilterSpin->value();
+    bool isLess = myLessFilterCombo->itemData(myLessFilterCombo->currentIndex()).toInt() == Filter_LT ? factor < v1 : factor <= v1;
+    bool isGreater = myGreaterFilterCombo->itemData(myGreaterFilterCombo->currentIndex()).toInt() == Filter_GT ? factor > v2 : factor >= v2;
+    if ( ( myLessFilterCheck->isChecked() && myGreaterFilterCheck->isChecked() && isLess && isGreater ) ||
+         ( myLessFilterCheck->isChecked() && !myGreaterFilterCheck->isChecked() && isLess ) ||
+         ( myGreaterFilterCheck->isChecked() && !myLessFilterCheck->isChecked() && isGreater ) ) {
+      Handle(SALOME_InteractiveObject) io = new SALOME_InteractiveObject();
+      io->setEntry( anEntry.toLatin1().constData() );
+      toSelect.Append(io);
+    }
+  }
+  if ( toSelect.Extent() > 0 ) {
+    myGeomGUI->getApp()->selectionMgr()->setSelectedObjects(toSelect);
+    SUIT_MessageBox::information( this,
+                                  tr( "INF_INFO" ),
+                                  tr( "GEOM_SOME_SHAPES_SELECTED").arg( toSelect.Extent() ),
+                                  tr( "BUT_OK" ) );
+  }
+  else {
+    SUIT_MessageBox::information( this,
+                                  tr( "INF_INFO" ),
+                                  tr( "GEOM_NO_SHAPES_SELECTED" ),
+                                  tr( "BUT_OK" ) );
+  }
+  updateState(true);
+}
+
+#ifndef DISABLE_PLOT2DVIEWER
+//=================================================================================
+// function : ClickOnPlot()
+// purpose  : opens "Shape Statistics" dialog box in order to plot sub-shapes distribution.
+//=================================================================================
+void GroupGUI_GroupDlg::ClickOnPlot()
+{
+  TopoDS_Shape aMainShape = GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), myMainObj);
+  QDialog* dlg = new MeasureGUI_ShapeStatisticsDlg( this, aMainShape, getShapeType() );
+  if ( dlg ) {
+    dlg->show();
+  }
+}
+#endif
+
+void GroupGUI_GroupDlg::MeasureToggled()
+{
+  myLessFilterSpin->setEnabled(myLessFilterCheck->isChecked());
+  myLessFilterCombo->setEnabled(myLessFilterCheck->isChecked());
+  myGreaterFilterSpin->setEnabled(myGreaterFilterCheck->isChecked());
+  myGreaterFilterCombo->setEnabled(myGreaterFilterCheck->isChecked());
+  myApplyFilterButton->setEnabled(myLessFilterCheck->isChecked() || myGreaterFilterCheck->isChecked());
+}
+
+//=================================================================================
+// function : getSourceObjects
+// purpose  : virtual method to get source objects
+//=================================================================================
+QList<GEOM::GeomObjPtr> GroupGUI_GroupDlg::getSourceObjects()
+{
+  QList<GEOM::GeomObjPtr> res;
+  GEOM::GeomObjPtr aGeomObjPtr1(myMainObj), aGeomObjPtr2(myInPlaceObj);
+  res << aGeomObjPtr1 << aGeomObjPtr2;
+  return res;
+}