+// LCOV_EXCL_STOP
+
+bool Model_AttributeSelectionList::isGeometricalSelection() const
+{
+ return myLab.IsAttribute(kIS_GEOMETRICAL_SELECTION);
+}
+
+void Model_AttributeSelectionList::setGeometricalSelection(const bool theIsGeometricalSelection)
+{
+ if (isGeometricalSelection() == theIsGeometricalSelection)
+ return; // nothing to do
+ if (theIsGeometricalSelection) // store the state
+ TDataStd_UAttribute::Set(myLab, kIS_GEOMETRICAL_SELECTION);
+ else
+ myLab.ForgetAttribute(kIS_GEOMETRICAL_SELECTION);
+ std::set<int> anIndiciesToRemove; // Update list according to the flag
+ if (theIsGeometricalSelection) { // all objects with same geometry must be combined into single
+ std::list<AttributeSelectionPtr> anAttributes; // collect attributes with geometrical compounds
+ for(int anIndex = 0; anIndex < size(); anIndex++) {
+ AttributeSelectionPtr anAttr = value(anIndex);
+ if (!anAttr.get() || !anAttr->context().get())
+ continue;
+ anAttr->combineGeometrical();
+ if (!anAttr->value().get() || anAttr->value()->shapeType() != GeomAPI_Shape::COMPOUND)
+ continue;
+ // check it is equal to some other attribute already presented in the list
+ std::list<AttributeSelectionPtr>::iterator anAttrIter = anAttributes.begin();
+ for(; anAttrIter != anAttributes.end(); anAttrIter++) {
+ if (anAttr->context() == (*anAttrIter)->context() &&
+ anAttr->namingName() == (*anAttrIter)->namingName()) {
+ anIndiciesToRemove.insert(anIndex);
+ break;
+ }
+ }
+ if (anAttrIter == anAttributes.end()) // not removed, so, add to the compare-list
+ anAttributes.push_back(anAttr);
+ }
+ } else { // all objects with same geometry must be divided into separated sub-attributes
+ int anInitialSize = size();
+ for(int anIndex = 0; anIndex < anInitialSize; anIndex++) {
+ AttributeSelectionPtr anAttr = value(anIndex);
+ if (!anAttr.get() || !anAttr->context().get())
+ continue;
+ GeomShapePtr aValue = anAttr->value();
+ if (!aValue.get() || aValue->shapeType() != GeomAPI_Shape::COMPOUND)
+ continue;
+ for(GeomAPI_ShapeIterator anIter(aValue); anIter.more(); anIter.next()) {
+ append(anAttr->context(), anIter.current());
+ }
+ anIndiciesToRemove.insert(anIndex);
+ }
+ }
+ remove(anIndiciesToRemove);
+ myIsCashed = false;
+ myCash.clear(); // empty list as indicator that cash is not used
+ owner()->data()->sendAttributeUpdated(this);
+}