From e1aac64495c108d7e9b7a4e922f495b4e938c47e Mon Sep 17 00:00:00 2001 From: nds Date: Thu, 21 May 2015 08:05:59 +0300 Subject: [PATCH] An improvement to deselect a value in a shape selector control in the same way as it is realized in multi selector. The reason is the plane deselection in the extrusion operation. This leads to a modification in selection behavior e.g for sketch parallel constraint. After the first line is selected, the second control gets the focus, it is empty, so, the selection in the viewer is also empty. So, the first object is not selected anymore and the user can not see it. --- src/ModuleBase/ModuleBase_IWorkshop.h | 3 +- .../ModuleBase_WidgetMultiSelector.cpp | 27 ++++-- .../ModuleBase_WidgetShapeSelector.cpp | 96 ++++++++----------- .../ModuleBase_WidgetShapeSelector.h | 3 - src/PartSet/PartSet_WidgetShapeSelector.cpp | 2 +- src/XGUI/XGUI_Displayer.cpp | 51 ++++++++++ src/XGUI/XGUI_Displayer.h | 2 + src/XGUI/XGUI_ModuleConnector.cpp | 6 +- src/XGUI/XGUI_ModuleConnector.h | 2 +- 9 files changed, 117 insertions(+), 75 deletions(-) diff --git a/src/ModuleBase/ModuleBase_IWorkshop.h b/src/ModuleBase/ModuleBase_IWorkshop.h index 87da9de58..229b6e2e3 100644 --- a/src/ModuleBase/ModuleBase_IWorkshop.h +++ b/src/ModuleBase/ModuleBase_IWorkshop.h @@ -10,6 +10,7 @@ #include "ModuleBase.h" #include "ModuleBase_Definitions.h" #include +#include #include #include @@ -78,7 +79,7 @@ Q_OBJECT //! Select features clearing previous selection. //! If the list is empty then selection will be cleared - virtual void setSelected(const QObjectPtrList& theFeatures) = 0; + virtual void setSelected(const QList& theValues) = 0; signals: /// Signal selection chaged. diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp index 87de31d81..2e01ee941 100644 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp @@ -95,6 +95,7 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen ModuleBase_WidgetMultiSelector::~ModuleBase_WidgetMultiSelector() { activateShapeSelection(false); + activateFilters(myWorkshop, false); } //******************************************************************** @@ -106,8 +107,7 @@ void ModuleBase_WidgetMultiSelector::activateCustom() Qt::UniqueConnection); activateShapeSelection(true); - - QObjectPtrList anObjects; + QList aSelected; // Restore selection in the viewer by the attribute selection list if(myFeature) { DataPtr aData = myFeature->data(); @@ -117,12 +117,20 @@ void ModuleBase_WidgetMultiSelector::activateCustom() for (int i = 0; i < aListAttr->size(); i++) { AttributeSelectionPtr anAttr = aListAttr->value(i); ResultPtr anObject = anAttr->context(); - if (anObject.get()) - anObjects.append(anObject); + if (anObject.get()) { + TopoDS_Shape aShape; + std::shared_ptr aShapePtr = anAttr->value(); + if (aShapePtr.get()) { + aShape = aShapePtr->impl(); + } + aSelected.append(ModuleBase_ViewerPrs(anObject, aShape, NULL)); + } } } } - myWorkshop->setSelected(anObjects); + myWorkshop->setSelected(aSelected); + + activateFilters(myWorkshop, true); } //******************************************************************** @@ -130,6 +138,7 @@ void ModuleBase_WidgetMultiSelector::deactivate() { disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); activateShapeSelection(false); + activateFilters(myWorkshop, false); } //******************************************************************** @@ -316,7 +325,8 @@ bool ModuleBase_WidgetMultiSelector::eventFilter(QObject* theObj, QEvent* theEve void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged() { activateShapeSelection(true); - QObjectPtrList anEmptyList; + activateFilters(myWorkshop, true); + QList anEmptyList; // This method will call Selection changed event which will call onSelectionChanged // To clear mySelection, myListControl and storeValue() // So, we don't need to call it @@ -356,10 +366,13 @@ void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const TopAbs_ShapeEnum TopAbs_ShapeEnum aRefType = ModuleBase_Tools::shapeType(aShapeTypeName); if(aRefType == theShapeType && idx != myTypeCombo->currentIndex()) { activateShapeSelection(false); + activateFilters(myWorkshop, false); bool isBlocked = myTypeCombo->blockSignals(true); myTypeCombo->setCurrentIndex(idx); myTypeCombo->blockSignals(isBlocked); + activateShapeSelection(true); + activateFilters(myWorkshop, true); break; } } @@ -377,8 +390,6 @@ void ModuleBase_WidgetMultiSelector::activateShapeSelection(const bool isActivat } else { myWorkshop->deactivateSubShapesSelection(); } - - activateFilters(myWorkshop, isActivated); } //******************************************************************** diff --git a/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp b/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp index 73035992a..91cc1f01f 100644 --- a/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp @@ -71,7 +71,7 @@ ModuleBase_WidgetShapeSelector::ModuleBase_WidgetShapeSelector(QWidget* theParen const Config_WidgetAPI* theData, const std::string& theParentId) : ModuleBase_WidgetValidated(theParent, theData, theParentId), - myWorkshop(theWorkshop), myIsActive(false) + myWorkshop(theWorkshop) { QFormLayout* aLayout = new QFormLayout(this); ModuleBase_Tools::adjustMargins(aLayout); @@ -99,6 +99,7 @@ ModuleBase_WidgetShapeSelector::ModuleBase_WidgetShapeSelector(QWidget* theParen ModuleBase_WidgetShapeSelector::~ModuleBase_WidgetShapeSelector() { activateSelection(false); + activateFilters(myWorkshop, false); } //******************************************************************** @@ -186,61 +187,26 @@ QList ModuleBase_WidgetShapeSelector::getControls() const //******************************************************************** void ModuleBase_WidgetShapeSelector::onSelectionChanged() { - // In order to make reselection possible - // TODO: check with MPV clearAttribute(); + // In order to make reselection possible, set empty object and shape should be done + setObject(ObjectPtr(), std::shared_ptr(new GeomAPI_Shape())); + bool aHasObject = false; QList aSelectedPrs = getSelectedEntitiesOrObjects(myWorkshop->selection()); - if (aSelectedPrs.empty()) - return; - ModuleBase_ViewerPrs aPrs = aSelectedPrs.first(); - if (aPrs.isEmpty() || !isValidSelection(aPrs)) - return; - - if (!aPrs.isEmpty() && isValidSelection(aPrs)) { - setSelectionCustom(aPrs); - // 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 (theObj) { - // raisePanel(); - //} - //updateSelectionName(); - //emit valuesChanged(); - emit focusOutWidget(this); + if (!aSelectedPrs.empty()) { + ModuleBase_ViewerPrs aPrs = aSelectedPrs.first(); + if (!aPrs.isEmpty() && isValidSelection(aPrs)) { + setSelectionCustom(aPrs); + aHasObject = true; + } } - + // 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); + // the widget loses the focus only if the selected object is set + if (aHasObject) + emit focusOutWidget(this); } -//******************************************************************** -//bool ModuleBase_WidgetShapeSelector::acceptObjectShape(const ObjectPtr theResult) const -//{ -// ResultPtr aResult = std::dynamic_pointer_cast(theResult); -// -// // Check that the shape of necessary type -// std::shared_ptr aShapePtr = ModelAPI_Tools::shape(aResult); -// if (!aShapePtr) -// return false; -// TopoDS_Shape aShape = aShapePtr->impl(); -// if (aShape.IsNull()) -// return false; -// -// TopAbs_ShapeEnum aShapeType = aShape.ShapeType(); -// if (aShapeType == TopAbs_COMPOUND) { -// foreach (QString aType, -// myShapeTypes) { -// TopExp_Explorer aEx(aShape, shapeType(aType)); -// if (aEx.More()) -// return true; -// } -// } else { -// foreach (QString aType, myShapeTypes) { -// if (shapeType(aType) == aShapeType) -// return true; -// } -// } -// return false; -//} - //******************************************************************** bool ModuleBase_WidgetShapeSelector::acceptSubShape(std::shared_ptr theShape) const { @@ -296,7 +262,7 @@ void ModuleBase_WidgetShapeSelector::updateSelectionName() myTextLine->setText(QString::fromStdString(aName.str())); } } - else if (myIsActive) { + else { myTextLine->setText(""); } } @@ -307,12 +273,9 @@ void ModuleBase_WidgetShapeSelector::updateSelectionName() //******************************************************************** void ModuleBase_WidgetShapeSelector::activateSelection(bool toActivate) { - if (myIsActive == toActivate) - return; - myIsActive = toActivate; updateSelectionName(); - if (myIsActive) { + if (toActivate) { QIntList aList; foreach (QString aType, myShapeTypes) { aList.append(ModuleBase_Tools::shapeType(aType)); @@ -321,8 +284,6 @@ void ModuleBase_WidgetShapeSelector::activateSelection(bool toActivate) } else { myWorkshop->deactivateSubShapesSelection(); } - - activateFilters(myWorkshop, myIsActive); } //******************************************************************** @@ -347,6 +308,24 @@ void ModuleBase_WidgetShapeSelector::activateCustom() { connect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); activateSelection(true); + // Restore selection in the viewer by the attribute selection list + QList aSelected; + if(myFeature) { + DataPtr aData = myFeature->data(); + AttributePtr anAttribute = myFeature->attribute(attributeID()); + + ObjectPtr anObject = GeomValidators_Tools::getObject(anAttribute); + TopoDS_Shape aShape; + std::shared_ptr aShapePtr = getShape(); + if (aShapePtr.get()) { + aShape = aShapePtr->impl(); + } + ModuleBase_ViewerPrs aPrs(anObject, aShape, NULL); + aSelected.append(aPrs); + } + myWorkshop->setSelected(aSelected); + + activateFilters(myWorkshop, true); } //******************************************************************** @@ -438,5 +417,6 @@ bool ModuleBase_WidgetShapeSelector::setSelectionCustom(const ModuleBase_ViewerP void ModuleBase_WidgetShapeSelector::deactivate() { activateSelection(false); + activateFilters(myWorkshop, false); disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); } diff --git a/src/ModuleBase/ModuleBase_WidgetShapeSelector.h b/src/ModuleBase/ModuleBase_WidgetShapeSelector.h index bf0fb6800..86a7b7312 100644 --- a/src/ModuleBase/ModuleBase_WidgetShapeSelector.h +++ b/src/ModuleBase/ModuleBase_WidgetShapeSelector.h @@ -150,9 +150,6 @@ Q_OBJECT /// List of accepting shapes types QStringList myShapeTypes; - /// Active/inactive flag - bool myIsActive; - /// backup parameters of the model attribute. The class processes three types of attribute: /// Reference, RefAttr and Selection. Depending on the attribute type, only the attribute parameter /// values are reserved in the backup diff --git a/src/PartSet/PartSet_WidgetShapeSelector.cpp b/src/PartSet/PartSet_WidgetShapeSelector.cpp index bdd7bba7a..cea864a6a 100644 --- a/src/PartSet/PartSet_WidgetShapeSelector.cpp +++ b/src/PartSet/PartSet_WidgetShapeSelector.cpp @@ -102,7 +102,7 @@ void PartSet_WidgetShapeSelector::setPointAttribute(ObjectPtr theSelectedObject, // test case is - preselection for distance operation, which contains two points selected on lines if (aPntAttr) aRefAttr->setAttr(aPntAttr); - else if (theSelectedObject) + else aRefAttr->setObject(theSelectedObject); } } diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index 3ec1a2105..ce6aadefc 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -454,6 +454,57 @@ void XGUI_Displayer::setSelected(const QObjectPtrList& theResults, const bool is updateViewer(); } +void XGUI_Displayer::setSelected(const QList& theValues, bool isUpdateViewer) +{ + Handle(AIS_InteractiveContext) aContext = AISContext(); + if (aContext.IsNull()) + return; + if (aContext->HasOpenedContext()) { + aContext->UnhilightSelected(); + aContext->ClearSelected(); + //if (aSelected.size() > 0) { + foreach (ModuleBase_ViewerPrs aPrs, theValues) { + // if (isValidSelection(aPrs)) { + //foreach(ObjectPtr aResult, theResults) { + ObjectPtr anObject = aPrs.object(); + ResultPtr aResult = std::dynamic_pointer_cast(anObject); + if (aResult.get() && isVisible(aResult)) { + AISObjectPtr anObj = myResult2AISObjectMap[aResult]; + Handle(AIS_InteractiveObject) anAIS = anObj->impl(); + if (!anAIS.IsNull()) { + const TopoDS_Shape& aShape = aPrs.shape(); + if (!aShape.IsNull()) { + aContext->AddOrRemoveSelected(aShape, false); + } + else { + // The methods are replaced in order to provide multi-selection, e.g. restore selection + // by activating multi selector widget. It also gives an advantage that the multi + // selection in OB gives multi-selection in the viewer + //aContext->SetSelected(anAIS, false); + // The selection in the context was cleared, so the method sets the objects are selected + aContext->AddOrRemoveSelected(anAIS, false); + } + } + } + } + } else { + aContext->UnhilightCurrents(); + aContext->ClearCurrents(); + //foreach(ObjectPtr aResult, theResults) { + foreach (ModuleBase_ViewerPrs aPrs, theValues) { + ObjectPtr anObject = aPrs.object(); + ResultPtr aResult = std::dynamic_pointer_cast(anObject); + if (aResult.get() && isVisible(aResult)) { + AISObjectPtr anObj = myResult2AISObjectMap[aResult]; + Handle(AIS_InteractiveObject) anAIS = anObj->impl(); + if (!anAIS.IsNull()) + aContext->SetCurrentObject(anAIS, false); + } + } + } + if (isUpdateViewer) + updateViewer(); +} void XGUI_Displayer::clearSelected() { diff --git a/src/XGUI/XGUI_Displayer.h b/src/XGUI/XGUI_Displayer.h index 5ea7f0713..7c6660344 100644 --- a/src/XGUI/XGUI_Displayer.h +++ b/src/XGUI/XGUI_Displayer.h @@ -85,6 +85,8 @@ class XGUI_EXPORT XGUI_Displayer: public QObject */ void setSelected(const QObjectPtrList& theFeatures, bool isUpdateViewer = true); + void setSelected(const QList& theValues, bool isUpdateViewer = true); + /// Unselect all objects void clearSelected(); diff --git a/src/XGUI/XGUI_ModuleConnector.cpp b/src/XGUI/XGUI_ModuleConnector.cpp index b83edb4c8..1405ba5d6 100644 --- a/src/XGUI/XGUI_ModuleConnector.cpp +++ b/src/XGUI/XGUI_ModuleConnector.cpp @@ -111,13 +111,13 @@ ObjectPtr XGUI_ModuleConnector::findPresentedObject(const AISObjectPtr& theAIS) return aDisp->getObject(theAIS); } -void XGUI_ModuleConnector::setSelected(const QObjectPtrList& theFeatures) +void XGUI_ModuleConnector::setSelected(const QList& theValues) { XGUI_Displayer* aDisp = myWorkshop->displayer(); - if (theFeatures.isEmpty()) { + if (theValues.isEmpty()) { myWorkshop->selector()->clearSelection(); } else { - aDisp->setSelected(theFeatures); + aDisp->setSelected(theValues); } } diff --git a/src/XGUI/XGUI_ModuleConnector.h b/src/XGUI/XGUI_ModuleConnector.h index e78228378..d2348e101 100644 --- a/src/XGUI/XGUI_ModuleConnector.h +++ b/src/XGUI/XGUI_ModuleConnector.h @@ -63,7 +63,7 @@ Q_OBJECT //! Select features clearing previous selection. //! If the list is empty then selection will be cleared - virtual void setSelected(const QObjectPtrList& theFeatures); + virtual void setSelected(const QList& theValues); //! Returns workshop XGUI_Workshop* workshop() const { return myWorkshop; } -- 2.39.2