From 83a851858962e7cb250b2086ca43c8f0b2eaa787 Mon Sep 17 00:00:00 2001 From: vsv Date: Mon, 12 Oct 2015 17:18:04 +0300 Subject: [PATCH] Issue#1059: Consider operation state in selection validator --- src/ModuleBase/CMakeLists.txt | 1 - .../ModuleBase_SelectionValidator.cpp | 13 - .../ModuleBase_SelectionValidator.h | 13 +- src/PartSet/PartSet_Validators.cpp | 315 +++++++++++++----- src/PartSet/PartSet_Validators.h | 44 +-- src/XGUI/XGUI_ActionsMgr.cpp | 39 +-- 6 files changed, 272 insertions(+), 153 deletions(-) delete mode 100644 src/ModuleBase/ModuleBase_SelectionValidator.cpp diff --git a/src/ModuleBase/CMakeLists.txt b/src/ModuleBase/CMakeLists.txt index a0a85d709..3bd1fba4f 100644 --- a/src/ModuleBase/CMakeLists.txt +++ b/src/ModuleBase/CMakeLists.txt @@ -82,7 +82,6 @@ SET(PROJECT_SOURCES ModuleBase_ParamSpinBox.cpp ModuleBase_Preferences.cpp ModuleBase_ResultPrs.cpp - ModuleBase_SelectionValidator.cpp ModuleBase_ToolBox.cpp ModuleBase_Tools.cpp ModuleBase_ViewerFilters.cpp diff --git a/src/ModuleBase/ModuleBase_SelectionValidator.cpp b/src/ModuleBase/ModuleBase_SelectionValidator.cpp deleted file mode 100644 index 7c92d953d..000000000 --- a/src/ModuleBase/ModuleBase_SelectionValidator.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: ModuleBase_SelectionValidator.cpp -// Created: 8 Jul 2014 -// Author: Vitaly SMETANNIKOV - -#include - -bool ModuleBase_SelectionValidator::isValid(const ModuleBase_ISelection* theSelection, - const std::list& theArguments) const -{ - return isValid(theSelection); -} diff --git a/src/ModuleBase/ModuleBase_SelectionValidator.h b/src/ModuleBase/ModuleBase_SelectionValidator.h index 60d957400..64eafc112 100644 --- a/src/ModuleBase/ModuleBase_SelectionValidator.h +++ b/src/ModuleBase/ModuleBase_SelectionValidator.h @@ -9,6 +9,7 @@ #include "ModuleBase.h" #include "ModuleBase_ISelection.h" +#include "ModuleBase_Operation.h" #include @@ -21,17 +22,11 @@ */ class ModuleBase_SelectionValidator : public ModelAPI_Validator { - public: +public: /// Returns True if selection is valid /// \param theSelection selection instance - /// \param theArguments list of arguments - virtual MODULEBASE_EXPORT bool isValid(const ModuleBase_ISelection* theSelection, - const std::list& theArguments) const; - - protected: - /// Returns True if selection is valid - /// \param theSelection selection instance - virtual bool isValid(const ModuleBase_ISelection* theSelection) const = 0; + /// \param theOperation - current operation (can be 0) + virtual bool isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const = 0; }; #endif diff --git a/src/PartSet/PartSet_Validators.cpp b/src/PartSet/PartSet_Validators.cpp index 849efa383..5b985c891 100755 --- a/src/PartSet/PartSet_Validators.cpp +++ b/src/PartSet/PartSet_Validators.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -72,126 +73,274 @@ int shapesNbLines(const ModuleBase_ISelection* theSelection) return aCount; } -bool PartSet_DistanceSelection::isValid(const ModuleBase_ISelection* theSelection) const + +std::shared_ptr sketcherPlane(ModuleBase_Operation* theOperation) { - int aCount = shapesNbPoints(theSelection) + shapesNbLines(theSelection); - return (aCount > 0) && (aCount < 3); + std::shared_ptr aEmptyPln; + if (theOperation) { + ModuleBase_OperationFeature* aFeatureOp = dynamic_cast(theOperation); + if (aFeatureOp) { + CompositeFeaturePtr aFeature = + std::dynamic_pointer_cast(aFeatureOp->feature()); + if (aFeature && (aFeature->getKind() == SketchPlugin_Sketch::ID())) + return PartSet_Tools::sketchPlane(aFeature); + } + } + return aEmptyPln; } -bool PartSet_LengthSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_DistanceSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const { - int aCount = shapesNbLines(theSelection); - return (aCount == 1); + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + ModuleBase_OperationFeature* aFeatureOp = dynamic_cast(theOperation); + if (!aFeatureOp->isEditOperation()) { + return true; + } + std::shared_ptr aPlane = sketcherPlane(theOperation); + if (aPlane.get()) + return true; + else + return false; + } else { + int aCount = shapesNbPoints(theSelection) + shapesNbLines(theSelection); + return (aCount > 0) && (aCount < 3); + } } -bool PartSet_PerpendicularSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_LengthSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const { - int aCount = shapesNbLines(theSelection); - return (aCount > 0) && (aCount < 3); + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + ModuleBase_OperationFeature* aFeatureOp = dynamic_cast(theOperation); + if (!aFeatureOp->isEditOperation()) { + return true; + } + std::shared_ptr aPlane = sketcherPlane(theOperation); + if (aPlane.get()) + return true; + else + return false; + } else { + int aCount = shapesNbLines(theSelection); + return (aCount == 1); + } } -bool PartSet_ParallelSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_PerpendicularSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const { - int aCount = shapesNbLines(theSelection); - return (aCount > 0) && (aCount < 3); + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + ModuleBase_OperationFeature* aFeatureOp = dynamic_cast(theOperation); + if (!aFeatureOp->isEditOperation()) { + return true; + } + std::shared_ptr aPlane = sketcherPlane(theOperation); + if (aPlane.get()) + return true; + else + return false; + } else { + int aCount = shapesNbLines(theSelection); + return (aCount > 0) && (aCount < 3); + } } -bool PartSet_RadiusSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_ParallelSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const { - QList aList = theSelection->getSelected(ModuleBase_ISelection::Viewer); - ModuleBase_ViewerPrs aPrs; - int aCount = 0; - foreach (ModuleBase_ViewerPrs aPrs, aList) { - const TopoDS_Shape& aShape = aPrs.shape(); - if (!aShape.IsNull()) { - if (aShape.ShapeType() == TopAbs_EDGE) { - TopoDS_Edge aEdge = TopoDS::Edge(aShape); - Standard_Real aStart, aEnd; - Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge, aStart, aEnd); - GeomAdaptor_Curve aAdaptor(aCurve); - if (aAdaptor.GetType() == GeomAbs_Circle) - aCount++; + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + ModuleBase_OperationFeature* aFeatureOp = dynamic_cast(theOperation); + if (!aFeatureOp->isEditOperation()) { + return true; + } + std::shared_ptr aPlane = sketcherPlane(theOperation); + if (aPlane.get()) + return true; + else + return false; + } else { + int aCount = shapesNbLines(theSelection); + return (aCount > 0) && (aCount < 3); + } +} + +bool PartSet_RadiusSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const +{ + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + ModuleBase_OperationFeature* aFeatureOp = dynamic_cast(theOperation); + if (!aFeatureOp->isEditOperation()) { + return true; + } + std::shared_ptr aPlane = sketcherPlane(theOperation); + if (aPlane.get()) + return true; + else + return false; + } else { + QList aList = theSelection->getSelected(ModuleBase_ISelection::Viewer); + ModuleBase_ViewerPrs aPrs; + int aCount = 0; + foreach (ModuleBase_ViewerPrs aPrs, aList) { + const TopoDS_Shape& aShape = aPrs.shape(); + if (!aShape.IsNull()) { + if (aShape.ShapeType() == TopAbs_EDGE) { + TopoDS_Edge aEdge = TopoDS::Edge(aShape); + Standard_Real aStart, aEnd; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge, aStart, aEnd); + GeomAdaptor_Curve aAdaptor(aCurve); + if (aAdaptor.GetType() == GeomAbs_Circle) + aCount++; + } } } + return (aCount == 1); } - return (aCount == 1); } -bool PartSet_RigidSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_RigidSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const { - QList aList = theSelection->getSelected(ModuleBase_ISelection::Viewer); - return (aList.count() == 1); + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + ModuleBase_OperationFeature* aFeatureOp = dynamic_cast(theOperation); + if (!aFeatureOp->isEditOperation()) { + return true; + } + std::shared_ptr aPlane = sketcherPlane(theOperation); + if (aPlane.get()) + return true; + else + return false; + } else { + QList aList = theSelection->getSelected(ModuleBase_ISelection::Viewer); + return (aList.count() == 1); + } } -bool PartSet_CoincidentSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_CoincidentSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const { - // Coincident can be applied to points and to lines - int aCount = shapesNbPoints(theSelection); - aCount += shapesNbLines(theSelection); - return (aCount > 0) && (aCount < 3); + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + ModuleBase_OperationFeature* aFeatureOp = dynamic_cast(theOperation); + if (!aFeatureOp->isEditOperation()) { + return true; + } + std::shared_ptr aPlane = sketcherPlane(theOperation); + if (aPlane.get()) + return true; + else + return false; + } else { + // Coincident can be applied to points and to lines + int aCount = shapesNbPoints(theSelection); + aCount += shapesNbLines(theSelection); + return (aCount > 0) && (aCount < 3); + } } -bool PartSet_HVDirSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_HVDirSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const { - int aCount = shapesNbLines(theSelection); - return (aCount == 1); + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + ModuleBase_OperationFeature* aFeatureOp = dynamic_cast(theOperation); + if (!aFeatureOp->isEditOperation()) { + return true; + } + std::shared_ptr aPlane = sketcherPlane(theOperation); + if (aPlane.get()) + return true; + else + return false; + } else { + int aCount = shapesNbLines(theSelection); + return (aCount == 1); + } } -bool PartSet_FilletSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_FilletSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const { - int aCount = shapesNbLines(theSelection); - return (aCount > 0) && (aCount < 3); + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + ModuleBase_OperationFeature* aFeatureOp = dynamic_cast(theOperation); + if (!aFeatureOp->isEditOperation()) { + return true; + } + std::shared_ptr aPlane = sketcherPlane(theOperation); + if (aPlane.get()) + return true; + else + return false; + } else { + int aCount = shapesNbLines(theSelection); + return (aCount > 0) && (aCount < 3); + } } -bool PartSet_TangentSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_TangentSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const { - QList aList = theSelection->getSelected(ModuleBase_ISelection::Viewer); - if ((aList.size() == 0) || (aList.size() > 2)) - return false; - - ModuleBase_ViewerPrs aPrs = aList.first(); - const TopoDS_Shape& aShape = aPrs.shape(); - if (aShape.IsNull()) - return false; - - if (aShape.ShapeType() != TopAbs_EDGE) - return false; - - std::shared_ptr aShapePtr(new GeomAPI_Shape); - aShapePtr->setImpl(new TopoDS_Shape(aShape)); - GeomAPI_Edge aEdge1(aShapePtr); - - if (aEdge1.isLine() || aEdge1.isArc()) { - if (aList.size() == 2) { - // Check second selection - aPrs = aList.last(); - const TopoDS_Shape& aShape2 = aPrs.shape(); - if (aShape2.IsNull()) - return false; - - if (aShape2.ShapeType() != TopAbs_EDGE) - return false; - - std::shared_ptr aShapePtr2(new GeomAPI_Shape); - aShapePtr2->setImpl(new TopoDS_Shape(aShape2)); - GeomAPI_Edge aEdge2(aShapePtr2); - if (aEdge1.isLine() && aEdge2.isArc()) - return true; - else if (aEdge1.isArc() && aEdge2.isLine()) - return true; - else - return false; - } else + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + ModuleBase_OperationFeature* aFeatureOp = dynamic_cast(theOperation); + if (!aFeatureOp->isEditOperation()) { + return true; + } + std::shared_ptr aPlane = sketcherPlane(theOperation); + if (aPlane.get()) return true; + else + return false; + } else { + QList aList = theSelection->getSelected(ModuleBase_ISelection::Viewer); + if ((aList.size() == 0) || (aList.size() > 2)) + return false; + + ModuleBase_ViewerPrs aPrs = aList.first(); + const TopoDS_Shape& aShape = aPrs.shape(); + if (aShape.IsNull()) + return false; + + if (aShape.ShapeType() != TopAbs_EDGE) + return false; + + std::shared_ptr aShapePtr(new GeomAPI_Shape); + aShapePtr->setImpl(new TopoDS_Shape(aShape)); + GeomAPI_Edge aEdge1(aShapePtr); + + if (aEdge1.isLine() || aEdge1.isArc()) { + if (aList.size() == 2) { + // Check second selection + aPrs = aList.last(); + const TopoDS_Shape& aShape2 = aPrs.shape(); + if (aShape2.IsNull()) + return false; + + if (aShape2.ShapeType() != TopAbs_EDGE) + return false; + + std::shared_ptr aShapePtr2(new GeomAPI_Shape); + aShapePtr2->setImpl(new TopoDS_Shape(aShape2)); + GeomAPI_Edge aEdge2(aShapePtr2); + if (aEdge1.isLine() && aEdge2.isArc()) + return true; + else if (aEdge1.isArc() && aEdge2.isLine()) + return true; + else + return false; + } else + return true; + } + return false; } - return false; } -bool PartSet_AngleSelection::isValid(const ModuleBase_ISelection* theSelection) const +bool PartSet_AngleSelection::isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const { - int aCount = shapesNbLines(theSelection); - return (aCount > 0) && (aCount < 3); + if (theSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { + ModuleBase_OperationFeature* aFeatureOp = dynamic_cast(theOperation); + if (!aFeatureOp->isEditOperation()) { + return true; + } + std::shared_ptr aPlane = sketcherPlane(theOperation); + if (aPlane.get()) + return true; + else + return false; + } else { + int aCount = shapesNbLines(theSelection); + return (aCount > 0) && (aCount < 3); + } } std::string PartSet_DifferentObjectsValidator::errorMessage( diff --git a/src/PartSet/PartSet_Validators.h b/src/PartSet/PartSet_Validators.h index 23706f81c..fae29cec6 100644 --- a/src/PartSet/PartSet_Validators.h +++ b/src/PartSet/PartSet_Validators.h @@ -21,48 +21,48 @@ //! A class to validate a selection for Distance constraint operation class PartSet_DistanceSelection : public ModuleBase_SelectionValidator { - protected: - PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const; +public: + PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const; }; //! \ingroup Validators //! A class to validate a selection for Length constraint operation class PartSet_LengthSelection : public ModuleBase_SelectionValidator { - protected: - PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const; +public: + PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const; }; //! \ingroup Validators //! A class to validate a selection for Perpendicular constraint operation class PartSet_PerpendicularSelection : public ModuleBase_SelectionValidator { - protected: - PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const; +public: + PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const; }; //! \ingroup Validators //! A class to validate a selection for Parallel constraint operation class PartSet_ParallelSelection : public ModuleBase_SelectionValidator { - protected: - PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const; +public: + PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const; }; //! \ingroup Validators //! A class to validate a selection for Radius constraint operation class PartSet_RadiusSelection : public ModuleBase_SelectionValidator { - protected: - PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const; +public: + PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const; }; //! \ingroup Validators //! A class to validate a selection for Rigid constraint operation class PartSet_RigidSelection : public ModuleBase_SelectionValidator { - protected: - PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const; +public: + PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const; }; @@ -70,40 +70,40 @@ class PartSet_RigidSelection : public ModuleBase_SelectionValidator //! A class to validate a selection for coincedence constraint operation class PartSet_CoincidentSelection : public ModuleBase_SelectionValidator { - protected: - PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const; +public: + PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const; }; //! \ingroup Validators //! A class to validate a selection for Horizontal and Vertical constraints operation class PartSet_HVDirSelection : public ModuleBase_SelectionValidator { - protected: - PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const; +public: + PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const; }; //! \ingroup Validators //! A class to validate a selection for Tangential constraints operation class PartSet_TangentSelection : public ModuleBase_SelectionValidator { - protected: - PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const; +public: + PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const; }; //! \ingroup Validators //! A class to validate a selection for Fillet constraints operation class PartSet_FilletSelection : public ModuleBase_SelectionValidator { - protected: - PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const; +public: + PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const; }; //! \ingroup Validators //! A class to validate a selection for Angle constraints operation class PartSet_AngleSelection : public ModuleBase_SelectionValidator { - protected: - PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const; +public: + PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection, ModuleBase_Operation* theOperation) const; }; ////////////// Attribute validators //////////////// diff --git a/src/XGUI/XGUI_ActionsMgr.cpp b/src/XGUI/XGUI_ActionsMgr.cpp index 8b6fbadd1..b1b5f1cf5 100644 --- a/src/XGUI/XGUI_ActionsMgr.cpp +++ b/src/XGUI/XGUI_ActionsMgr.cpp @@ -140,34 +140,23 @@ void XGUI_ActionsMgr::updateOnViewSelection() if (aIdList.isEmpty()) return; + ModuleBase_Operation* theOperation = myOperationMgr->currentOperation(); //QString aFeatureId = QString::fromStdString(anActiveFeature->getKind()); XGUI_Selection* aSelection = myWorkshop->selector()->selection(); // only viewer selection is processed - if (aSelection->getSelected(ModuleBase_ISelection::Viewer).size() == 0) { - // it seems that this code is not nesessary anymore. It leads to incorrect case: - // sketch operation start, click in any place in the viewer. The result is all nested - // entities are enabled(but the sketch plane is not selected yet). Any sketch operation - // can be started but will be incorrect on preview build before it uses the sketch unset plane. - /*foreach(QString aFeatureId, aIdList) { - foreach(QString aId, nestedCommands(aFeatureId)) { - setActionEnabled(aId, true); - } - }*/ - } else { - SessionPtr aMgr = ModelAPI_Session::get(); - ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); - foreach(QString aFeatureId, aIdList) { - foreach(QString aId, nestedCommands(aFeatureId)) { - ModelAPI_ValidatorsFactory::Validators aValidators; - aFactory->validators(aId.toStdString(), aValidators); - ModelAPI_ValidatorsFactory::Validators::iterator aValidatorIt = aValidators.begin(); - for (; aValidatorIt != aValidators.end(); ++aValidatorIt) { - const ModuleBase_SelectionValidator* aSelValidator = - dynamic_cast(aFactory->validator(aValidatorIt->first)); - if (!aSelValidator) - continue; - setActionEnabled(aId, aSelValidator->isValid(aSelection, aValidatorIt->second)); - } + SessionPtr aMgr = ModelAPI_Session::get(); + ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); + foreach(QString aFeatureId, aIdList) { + foreach(QString aId, nestedCommands(aFeatureId)) { + ModelAPI_ValidatorsFactory::Validators aValidators; + aFactory->validators(aId.toStdString(), aValidators); + ModelAPI_ValidatorsFactory::Validators::iterator aValidatorIt = aValidators.begin(); + for (; aValidatorIt != aValidators.end(); ++aValidatorIt) { + const ModuleBase_SelectionValidator* aSelValidator = + dynamic_cast(aFactory->validator(aValidatorIt->first)); + if (!aSelValidator) + continue; + setActionEnabled(aId, aSelValidator->isValid(aSelection, theOperation)); } } } -- 2.39.2