+ myWorkshop->module()->customizeObject(myFeature, ModuleBase_IModule::CustomizeHighlightedObjects,
+ true);
+}
+
+//********************************************************************
+void ModuleBase_WidgetMultiSelector::getSelectedAttributeIndices(std::set<int>& theAttributeIds)
+{
+ myListView->getSelectedIndices(theAttributeIds);
+}
+
+void ModuleBase_WidgetMultiSelector::convertIndicesToViewerSelection(std::set<int> theAttributeIds,
+ QList<ModuleBase_ViewerPrsPtr>& theValues) const
+{
+ if(myFeature.get() == NULL)
+ return;
+
+ DataPtr aData = myFeature->data();
+ AttributePtr anAttribute = aData->attribute(attributeID());
+ std::string aType = anAttribute->attributeType();
+ if (aType == ModelAPI_AttributeSelectionList::typeId()) {
+ AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(attributeID());
+ for (int i = 0; i < aSelectionListAttr->size(); i++) {
+ // filter by attribute indices only if the container is not empty otherwise return all items
+ if (!theAttributeIds.empty() && theAttributeIds.find(i) == theAttributeIds.end())
+ continue;
+ AttributeSelectionPtr anAttr = aSelectionListAttr->value(i);
+ ResultPtr anObject = anAttr->context();
+ if (anObject.get())
+ theValues.append(std::shared_ptr<ModuleBase_ViewerPrs>(
+ new ModuleBase_ViewerPrs(anObject, anAttr->value(), NULL)));
+ }
+ }
+ else if (aType == ModelAPI_AttributeRefList::typeId()) {
+ AttributeRefListPtr aRefListAttr = aData->reflist(attributeID());
+ for (int i = 0; i < aRefListAttr->size(); i++) {
+ // filter by attribute indices only if the container is not empty otherwise return all items
+ if (!theAttributeIds.empty() && theAttributeIds.find(i) == theAttributeIds.end())
+ continue;
+ ObjectPtr anObject = aRefListAttr->object(i);
+ if (anObject.get()) {
+ theValues.append(std::shared_ptr<ModuleBase_ViewerPrs>(
+ new ModuleBase_ViewerPrs(anObject, GeomShapePtr(), NULL)));
+ }
+ }
+ }
+ else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
+ AttributeRefAttrListPtr aRefAttrListAttr = aData->refattrlist(attributeID());
+ for (int i = 0; i < aRefAttrListAttr->size(); i++) {
+ // filter by attribute indices only if the container is not empty otherwise return all items
+ if (!theAttributeIds.empty() && theAttributeIds.find(i) == theAttributeIds.end())
+ continue;
+ ObjectPtr anObject = aRefAttrListAttr->object(i);
+ if (!anObject.get())
+ continue;
+ TopoDS_Shape aShape;
+ AttributePtr anAttribute = aRefAttrListAttr->attribute(i);
+ if (anAttribute.get()) {
+ GeomShapePtr aGeomShape = ModuleBase_Tools::getShape(anAttribute, myWorkshop);
+ theValues.append(std::shared_ptr<ModuleBase_ViewerPrs>(
+ new ModuleBase_ViewerPrs(anObject, aGeomShape, NULL)));
+ }
+ }
+ }
+}
+
+bool ModuleBase_WidgetMultiSelector::removeUnusedAttributeObjects
+ (QList<ModuleBase_ViewerPrsPtr>& theValues)
+{
+ bool isDone = false;
+
+ std::map<ObjectPtr, std::set<GeomShapePtr> > aGeomSelection = convertSelection(theValues);
+ DataPtr aData = myFeature->data();
+ AttributePtr anAttribute = aData->attribute(attributeID());
+ std::string aType = anAttribute->attributeType();
+ std::set<GeomShapePtr> aShapes;
+ std::set<int> anIndicesToBeRemoved;
+ if (aType == ModelAPI_AttributeSelectionList::typeId()) {
+ // iteration through data model to find not selected elements to remove them
+ AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(attributeID());
+ for (int i = 0; i < aSelectionListAttr->size(); i++) {
+ AttributeSelectionPtr anAttr = aSelectionListAttr->value(i);
+ bool aFound = findInSelection(anAttr->context(), anAttr->value(), aGeomSelection,
+ myWorkshop);
+ if (!aFound)
+ anIndicesToBeRemoved.insert(i);
+ }
+ isDone = anIndicesToBeRemoved.size() > 0;
+ aSelectionListAttr->remove(anIndicesToBeRemoved);
+ }
+ else if (aType == ModelAPI_AttributeRefList::typeId()) {
+ AttributeRefListPtr aRefListAttr = aData->reflist(attributeID());
+ for (int i = 0; i < aRefListAttr->size(); i++) {
+ ObjectPtr anObject = aRefListAttr->object(i);
+ if (anObject.get()) {
+ bool aFound = findInSelection(anObject, GeomShapePtr(), aGeomSelection,
+ myWorkshop);
+ if (!aFound)
+ anIndicesToBeRemoved.insert(i);
+ }
+ }
+ isDone = anIndicesToBeRemoved.size() > 0;
+ aRefListAttr->remove(anIndicesToBeRemoved);
+ }
+ else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
+ std::set<AttributePtr> anAttributes;
+ QList<ModuleBase_ViewerPrsPtr>::const_iterator
+ anIt = theValues.begin(), aLast = theValues.end();
+ ObjectPtr anObject;
+ GeomShapePtr aShape;
+ for (; anIt != aLast; anIt++) {
+ ModuleBase_ViewerPrsPtr aPrs = *anIt;
+ getGeomSelection(aPrs, anObject, aShape);
+ AttributePtr anAttr = myWorkshop->module()->findAttribute(anObject, aShape);
+ if (anAttr.get() && anAttributes.find(anAttr) == anAttributes.end())
+ anAttributes.insert(anAttr);
+ }
+
+ AttributeRefAttrListPtr aRefAttrListAttr = aData->refattrlist(attributeID());
+ for (int i = 0; i < aRefAttrListAttr->size(); i++) {
+ bool aFound = false;
+ if (aRefAttrListAttr->isAttribute(i)) {
+ AttributePtr anAttribute = aRefAttrListAttr->attribute(i);
+ aFound = anAttributes.find(anAttribute) != anAttributes.end();
+ }
+ else {
+ aFound = findInSelection(aRefAttrListAttr->object(i), GeomShapePtr(), aGeomSelection,
+ myWorkshop);
+ }
+ if (!aFound)
+ anIndicesToBeRemoved.insert(i);
+ }
+ isDone = anIndicesToBeRemoved.size() > 0;
+ aRefAttrListAttr->remove(anIndicesToBeRemoved);
+ }
+
+ return isDone;
+}
+
+std::map<ObjectPtr, std::set<GeomShapePtr> > ModuleBase_WidgetMultiSelector::convertSelection
+ (QList<ModuleBase_ViewerPrsPtr>& theValues)
+{
+ // convert prs list to objects map
+ std::map<ObjectPtr, std::set<GeomShapePtr> > aGeomSelection;
+ std::set<GeomShapePtr> aShapes;
+ QList<ModuleBase_ViewerPrsPtr>::const_iterator anIt = theValues.begin(), aLast = theValues.end();
+ ObjectPtr anObject;
+ GeomShapePtr aShape;
+ GeomShapePtr anEmptyShape(new GeomAPI_Shape());
+ for (; anIt != aLast; anIt++) {
+ ModuleBase_ViewerPrsPtr aPrs = *anIt;
+ getGeomSelection(aPrs, anObject, aShape);
+ aShapes.clear();
+ if (aGeomSelection.find(anObject) != aGeomSelection.end()) // found
+ aShapes = aGeomSelection[anObject];
+ // we need to know if there was an empty shape in selection for the object
+ if (!aShape.get())
+ aShape = anEmptyShape;
+ if (aShape.get() && aShapes.find(aShape) == aShapes.end()) // not found
+ aShapes.insert(aShape);
+ aGeomSelection[anObject] = aShapes;
+ }
+ return aGeomSelection;
+}
+
+bool ModuleBase_WidgetMultiSelector::findInSelection(const ObjectPtr& theObject,
+ GeomShapePtr theShape,
+ const std::map<ObjectPtr, std::set<GeomShapePtr> >& theGeomSelection,
+ ModuleBase_IWorkshop* theWorkshop)
+{
+ // issue #2154: we should not remove from list objects hidden in the viewer if selection
+ // was done with SHIFT button
+ if (theWorkshop->hasSHIFTPressed() && !theObject->isDisplayed())
+ return true;
+
+ bool aFound = false;
+ if (theShape.get()) { // treat shape equal to context as null: 2219, keep order of shapes in list
+ const ResultPtr aContext = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+ if (aContext.get() && aContext->shape()->isEqual(theShape))
+ theShape.reset();
+ }
+
+ GeomShapePtr anEmptyShape(new GeomAPI_Shape());
+ GeomShapePtr aShape = theShape.get() ? theShape : anEmptyShape;
+ if (theGeomSelection.find(theObject) != theGeomSelection.end()) {// found
+ const std::set<GeomShapePtr>& aShapes = theGeomSelection.at(theObject);
+ std::set<GeomShapePtr>::const_iterator anIt = aShapes.begin(), aLast = aShapes.end();
+ for (; anIt != aLast && !aFound; anIt++) {
+ GeomShapePtr aCShape = *anIt;
+ if (aCShape.get())
+ aFound = aCShape->isSame(aShape);
+ }
+ }
+
+ // issue #2903: (Possibility to hide faces) - check whether given shape is a hidden sub-shape
+ if (!aFound && theWorkshop->hasSHIFTPressed() && theObject->isDisplayed()) {
+ AISObjectPtr anAIS = theWorkshop->findPresentation(theObject);
+ if (anAIS.get() != NULL) {
+ Handle(AIS_InteractiveObject) anAISIO = anAIS->impl<Handle(AIS_InteractiveObject)>();
+
+ Handle(ModuleBase_ResultPrs) aResultPrs = Handle(ModuleBase_ResultPrs)::DownCast(anAISIO);
+ if (!aResultPrs.IsNull() && aResultPrs->isSubShapeHidden(theShape->impl<TopoDS_Shape>()))
+ return true;
+ }
+ }
+
+ return aFound;
+}
+
+QList<ActionInfo>
+ ModuleBase_WidgetMultiSelector::actionsList(ModuleBase_ActionType theActionType) const
+{
+ QList<ActionInfo> aList;
+ if (myCurrentHistoryIndex > -1) {
+ int i = 0;
+ QString aTitle("Selection %1 items");
+ QString aTit("Selection %1 item");
+ QIcon aIcon(":pictures/selection.png");
+ int aNb;
+ switch (theActionType) {
+ case ActionUndo:
+ i = 1;
+ while (i <= myCurrentHistoryIndex) {
+ aNb = mySelectedHistoryValues.at(i).count();
+ if (aNb == 1) {
+ ActionInfo aInfo(aIcon, aTit.arg(aNb));
+ aList.insert(0, aInfo);
+ } else {
+ ActionInfo aInfo(aIcon, aTitle.arg(aNb));
+ aList.insert(0, aInfo);
+ }
+ i++;
+ }
+ break;
+ case ActionRedo:
+ i = mySelectedHistoryValues.length() - 1;
+ while (i > myCurrentHistoryIndex) {
+ aNb = mySelectedHistoryValues.at(i).count();
+ if (aNb == 1) {
+ ActionInfo aInfo(aIcon, aTit.arg(mySelectedHistoryValues.at(i).count()));
+ aList.insert(0, aInfo);
+ } else {
+ ActionInfo aInfo(aIcon, aTitle.arg(mySelectedHistoryValues.at(i).count()));
+ aList.insert(0, aInfo);
+ }
+ i--;
+ }
+ break;
+ }
+ }
+ return aList;
+}
+
+
+void ModuleBase_WidgetMultiSelector::onFeatureAccepted()
+{
+ defaultValues[myFeatureId + attributeID()] = myDefMode;