X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModuleBase%2FModuleBase_WidgetSelector.cpp;h=831fc4cb4c481ef3d1d188d3c4032d1dad688938;hb=374a366d81778aa27ed32cc080c0f95bdb03f1c5;hp=f4a4b456f80f83b9d491164624e8e65111f95fb5;hpb=c81e2807e1293d6f35262a4de66ceb61d0322fda;p=modules%2Fshaper.git diff --git a/src/ModuleBase/ModuleBase_WidgetSelector.cpp b/src/ModuleBase/ModuleBase_WidgetSelector.cpp old mode 100755 new mode 100644 index f4a4b456f..831fc4cb4 --- a/src/ModuleBase/ModuleBase_WidgetSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetSelector.cpp @@ -1,21 +1,54 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: ModuleBase_WidgetSelector.h -// Created: 19 June 2015 -// Author: Natalia ERMOLAEVA +// Copyright (C) 2014-2021 CEA/DEN, EDF R&D +// +// 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, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #include +#include +#include #include +#include #include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include ModuleBase_WidgetSelector::ModuleBase_WidgetSelector(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop, - const Config_WidgetAPI* theData, - const std::string& theParentId) - : ModuleBase_WidgetValidated(theParent, theData, theParentId), - myWorkshop(theWorkshop) + const Config_WidgetAPI* theData) +: ModuleBase_WidgetValidated(theParent, theWorkshop, theData), +myIsPointsFiltering(true) { + QString aFiltering = QString::fromStdString(theData->getProperty("filter_points")); + if (aFiltering.toLower() == "false") + myIsPointsFiltering = false; } //******************************************************************** @@ -23,106 +56,166 @@ ModuleBase_WidgetSelector::~ModuleBase_WidgetSelector() { } -//TODO: nds stabilization hotfix -void ModuleBase_WidgetSelector::disconnectSignals() -{ - disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); -} - //******************************************************************** -void ModuleBase_WidgetSelector::getGeomSelection(const ModuleBase_ViewerPrs& thePrs, +void ModuleBase_WidgetSelector::getGeomSelection(const ModuleBase_ViewerPrsPtr& thePrs, ObjectPtr& theObject, GeomShapePtr& theShape) { ModuleBase_ISelection* aSelection = myWorkshop->selection(); theObject = aSelection->getResult(thePrs); + if (!theObject.get()) + theObject = thePrs->object(); theShape = aSelection->getShape(thePrs); } //******************************************************************** -void ModuleBase_WidgetSelector::onSelectionChanged() +bool ModuleBase_WidgetSelector::processSelection() { - clearAttribute(); + QList aSelected = getFilteredSelected(); + // equal vertices should not be used here + if (myIsPointsFiltering) + ModuleBase_ISelection::filterSelectionOnEqualPoints(aSelected); - QList aSelected = myWorkshop->selection()->getSelected( - ModuleBase_ISelection::AllControls); - bool isDone = setSelection(aSelected); + bool isDone = setSelection(aSelected, true/*false*/); + updateOnSelectionChanged(isDone); + return isDone; +} + +//******************************************************************** +void ModuleBase_WidgetSelector::updateOnSelectionChanged(const bool theDone) +{ + // "false" flag should be used here, it connects to the #26658 OCC bug, when the user click in + // the same place repeatedly without mouse moved. In the case validation by filters is not + // perfromed, so an invalid object is selected. E.g. distance constraint, selection of a point. + // the 3rd click in the same point allow using this point. emit valuesChanged(); // the updateObject method should be called to flush the updated sigal. The workshop listens it, // calls validators for the feature and, as a result, updates the Apply button state. updateObject(myFeature); - if (isDone) + // we need to forget about previous validation result as the current selection can influence on it + clearValidatedCash(); + + if (theDone) updateFocus(); } //******************************************************************** -bool ModuleBase_WidgetSelector::acceptSubShape(const TopoDS_Shape& theShape) const +QIntList ModuleBase_WidgetSelector::getShapeTypes() const { - bool aValid = true; - if (theShape.IsNull()) { - aValid = true; // do not check the shape type if the shape is empty - // extrusion uses a sketch object selectected in Object browser + QIntList aShapeTypes = shapeTypes(); + // this type should be mentioned in XML, poor selection otherwise + if (/*aShapeTypes.contains(TopAbs_SOLID) ||*/ + aShapeTypes.contains(ModuleBase_ResultPrs::Sel_Result/*TopAbs_SHAPE*/)) { + // it should be selectable for both, "solids" and "objects" types + aShapeTypes.append(TopAbs_COMPSOLID); } - else { - aValid = false; - TopAbs_ShapeEnum aShapeType = theShape.ShapeType(); - QIntList aShapeTypes = getShapeTypes(); - - QIntList::const_iterator anIt = aShapeTypes.begin(), aLast = aShapeTypes.end(); - for (; anIt != aLast; anIt++) { - if (aShapeType == *anIt) - aValid = true; + return aShapeTypes; +} + +//******************************************************************** +QList ModuleBase_WidgetSelector::getAttributeSelection() const +{ + return QList(); +} + +//******************************************************************** +bool ModuleBase_WidgetSelector::acceptSubShape(const GeomShapePtr& theShape, + const ResultPtr& theResult) const +{ + bool aValid = false; + + GeomShapePtr aShape = theShape; + + QIntList aShapeTypes = getShapeTypes(); + if (aShapeTypes.empty()) { + aValid = true; + return aValid; + } + // when the SHAPE type is provided by XML as Object, the whole result shape should be selected. + //if (!aShape.get() && aShapeTypes.contains(ModuleBase_ResultPrs::Sel_Result)) { + // In case of selection of a feature aShape could be not NULL, but result has to be selected + if (aShapeTypes.contains(ModuleBase_ResultPrs::Sel_Result)) { + aValid = true; + return aValid; + } + + if (!aShape.get() && theResult.get()) { + if (theResult.get()) + aShape = theResult->shape(); + } + TopAbs_ShapeEnum aShapeType = TopAbs_SHAPE; + if (aShape.get()) { + // Check that the selection corresponds to selection type + TopoDS_Shape aTopoShape = aShape->impl(); + if (!aTopoShape.IsNull()) { + aShapeType = aTopoShape.ShapeType(); + // for compounds check sub-shapes: it may be compound of needed type: + // Booleans may produce compounds of Solids + if (aShapeType == TopAbs_COMPOUND) { + aShapeType = ModuleBase_Tools::getCompoundSubType(aTopoShape); + } + } + } + + QIntList::const_iterator anIt = aShapeTypes.begin(), aLast = aShapeTypes.end(); + for (; anIt != aLast && !aValid; anIt++) { + TopAbs_ShapeEnum aCurrentShapeType = (TopAbs_ShapeEnum)*anIt; + if (aShapeType == aCurrentShapeType) + aValid = true; + else if (aCurrentShapeType == TopAbs_FACE) { + // try to process the construction shape only if there is no a selected shape in the viewer + if (!theShape.get() && theResult.get()) { + ResultConstructionPtr aCResult = + std::dynamic_pointer_cast(theResult); + aValid = aCResult.get() && aCResult->facesNum() > 0; + } } } return aValid; } //******************************************************************** -void ModuleBase_WidgetSelector::activateSelection(bool toActivate) +void ModuleBase_WidgetSelector::selectionModes(int& theModuleSelectionModes, QIntList& theModes) +{ + theModuleSelectionModes = -1; + theModes.append(getShapeTypes()); +} + +//******************************************************************** +void ModuleBase_WidgetSelector::updateSelectionModesAndFilters(bool toActivate) { updateSelectionName(); - if (toActivate) { - myWorkshop->activateSubShapesSelection(getShapeTypes()); - } else { - myWorkshop->deactivateSubShapesSelection(); - } + myWorkshop->selectionActivate()->updateSelectionFilters(); + myWorkshop->selectionActivate()->updateSelectionModes(); + + if (!toActivate) + clearValidatedCash(); } //******************************************************************** void ModuleBase_WidgetSelector::activateCustom() { - connect(myWorkshop, SIGNAL(selectionChanged()), this, - SLOT(onSelectionChanged()), Qt::UniqueConnection); - - activateSelection(true); - // Restore selection in the viewer by the attribute selection list - myWorkshop->setSelected(getAttributeSelection()); - - activateFilters(myWorkshop, true); + // it should be postponed to have current widget as active to validate restored selection + static Events_ID anEvent = Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION); + ModelAPI_EventCreator::get()->sendUpdated(myFeature, anEvent); } //******************************************************************** -bool ModuleBase_WidgetSelector::isValidSelectionCustom(const ModuleBase_ViewerPrs& thePrs) +bool ModuleBase_WidgetSelector::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& thePrs) { GeomShapePtr aShape = myWorkshop->selection()->getShape(thePrs); - bool aValid = true; - if (!aShape.get()) { - ResultPtr aResult = myWorkshop->selection()->getResult(thePrs); - if (aResult.get()) - aShape = aResult->shape(); - } - if (aShape.get()) { - // Check that the selection corresponds to selection type - TopoDS_Shape aTopoShape = aShape->impl(); - aValid = acceptSubShape(aTopoShape); - } + ResultPtr aResult = myWorkshop->selection()->getResult(thePrs); + bool aValid = aResult.get(); + if (!isWholeResultAllowed()) + aValid = acceptSubShape(aShape, aResult); + if (aValid) { // In order to avoid selection of the same object - ResultPtr aResult = myWorkshop->selection()->getResult(thePrs); + aResult = myWorkshop->selection()->getResult(thePrs); FeaturePtr aSelectedFeature = ModelAPI_Feature::feature(aResult); aValid = aSelectedFeature != myFeature; } @@ -130,20 +223,47 @@ bool ModuleBase_WidgetSelector::isValidSelectionCustom(const ModuleBase_ViewerPr } //******************************************************************** -bool ModuleBase_WidgetSelector::setSelectionCustom(const ModuleBase_ViewerPrs& thePrs) +bool ModuleBase_WidgetSelector::setSelectionCustom(const ModuleBase_ViewerPrsPtr& thePrs) { ObjectPtr anObject; GeomShapePtr aShape; getGeomSelection(thePrs, anObject, aShape); - setObject(anObject, aShape); - return true; + // the last flag is to be depending on hasObject is called before. To be corrected later + return ModuleBase_Tools::setObject(attribute(), anObject, aShape, + myWorkshop, myIsInValidate, true); } //******************************************************************** void ModuleBase_WidgetSelector::deactivate() { - disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); - activateSelection(false); - activateFilters(myWorkshop, false); + ModuleBase_WidgetValidated::deactivate(); + /// clear temporary cash + AttributePtr anAttribute = attribute(); + if (!anAttribute.get()) + return; + std::string aType = anAttribute->attributeType(); + if (anAttribute->attributeType() == ModelAPI_AttributeSelection::typeId()) { + AttributeSelectionPtr aSelectAttr = + std::dynamic_pointer_cast(anAttribute); + aSelectAttr->removeTemporaryValues(); + } + else if (anAttribute->attributeType() == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aSelectAttr = + std::dynamic_pointer_cast(anAttribute); + aSelectAttr->removeTemporaryValues(); + } +} + +//******************************************************************** +bool ModuleBase_WidgetSelector::isWholeResultAllowed() const +{ + AttributePtr anAttribute = attribute(); + if (anAttribute.get()) { + AttributeSelectionListPtr aSelAttr = + std::dynamic_pointer_cast(anAttribute); + if (aSelAttr.get()) + return aSelAttr->isWholeResultAllowed(); + } + return false; }