X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModuleBase%2FModuleBase_WidgetMultiSelector.cpp;h=57852847b4e8ade7e78ce1de95ae7deaec843eb8;hb=3b676e8f67d0b110ecee42985223b99fc181532b;hp=d4f209b15db5edd1993212b06e5fb206a42566d4;hpb=ad50208b9badd50c6c441f3fe20dcf2e03948e01;p=modules%2Fshaper.git diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp old mode 100644 new mode 100755 index d4f209b15..57852847b --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp @@ -14,11 +14,15 @@ #include #include #include - -#include +#include +#include #include #include +#include +#include +#include +#include #include @@ -32,18 +36,58 @@ #include #include #include +#include #include #include -//#define DEBUG_SHAPE_VALIDATION_PREVIOUS +const int ATTRIBUTE_SELECTION_INDEX_ROLE = Qt::UserRole + 1; + +/** +* Customization of a List Widget to make it to be placed on full width of container +*/ +class CustomListWidget : public QListWidget +{ +public: + /// Constructor + /// \param theParent a parent widget + CustomListWidget( QWidget* theParent ) + : QListWidget( theParent ) + { + } + + /// Redefinition of virtual method + virtual QSize sizeHint() const + { + int aHeight = 2*QFontMetrics( font() ).height(); + QSize aSize = QListWidget::sizeHint(); + return QSize( aSize.width(), aHeight ); + } + + /// Redefinition of virtual method + virtual QSize minimumSizeHint() const + { + int aHeight = 4/*2*/*QFontMetrics( font() ).height(); + QSize aSize = QListWidget::minimumSizeHint(); + return QSize( aSize.width(), aHeight ); + } + +#ifndef WIN32 +// The code is necessary only for Linux because +//it can not update viewport on widget resize +protected: + void resizeEvent(QResizeEvent* theEvent) + { + QListWidget::resizeEvent(theEvent); + QTimer::singleShot(5, viewport(), SLOT(repaint())); + } +#endif +}; ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(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_WidgetSelector(theParent, theWorkshop, theData) { QGridLayout* aMainLay = new QGridLayout(this); ModuleBase_Tools::adjustMargins(aMainLay); @@ -52,20 +96,19 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen aMainLay->addWidget(aTypeLabel, 0, 0); myTypeCombo = new QComboBox(this); - // There is no sence to paramerize list of types while we can not parametrize selection mode - - myShapeValidator = new GeomValidators_ShapeType(); + // There is no sense to parameterize list of types while we can not parameterize selection mode std::string aPropertyTypes = theData->getProperty("type_choice"); QString aTypesStr = aPropertyTypes.c_str(); - QStringList aShapeTypes = aTypesStr.split(' '); + QStringList aShapeTypes = aTypesStr.split(' ', QString::SkipEmptyParts); - //myIsUseChoice = theData->getBooleanAttribute("use_choice", true); + myIsUseChoice = theData->getBooleanAttribute("use_choice", false); - myTypeCombo->addItems(aShapeTypes); + if (!aShapeTypes.empty()) + myTypeCombo->addItems(aShapeTypes); aMainLay->addWidget(myTypeCombo, 0, 1); // if the xml definition contains one type, the controls to select a type should not be shown - if (aShapeTypes.size() == 1/* || !myIsUseChoice*/) { + if (aShapeTypes.size() <= 1 || !myIsUseChoice) { aTypeLabel->setVisible(false); myTypeCombo->setVisible(false); } @@ -75,22 +118,28 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen : tr("Selected objects:"), this); aMainLay->addWidget(aListLabel, 1, 0); // if the xml definition contains one type, an information label should be shown near to the latest - if (aShapeTypes.size() == 1) { - QString aLabelText = QString::fromStdString(theData->widgetLabel()); + if (aShapeTypes.size() <= 1) { QString aLabelIcon = QString::fromStdString(theData->widgetIcon()); - QLabel* aSelectedLabel = new QLabel(aLabelText, this); - if (!aLabelIcon.isEmpty()) + if (!aLabelIcon.isEmpty()) { + QLabel* aSelectedLabel = new QLabel("", this); aSelectedLabel->setPixmap(QPixmap(aLabelIcon)); - aMainLay->addWidget(aSelectedLabel, 1, 1); + aMainLay->addWidget(aSelectedLabel, 1, 1); + } aMainLay->setColumnStretch(2, 1); } - myListControl = new QListWidget(this); - aMainLay->addWidget(myListControl, 2, 0, 2, -1); + QString aToolTip = QString::fromStdString(theData->widgetTooltip()); + myListControl = new CustomListWidget(this); + QString anObjName = QString::fromStdString(attributeID()); + myListControl->setObjectName(anObjName); + myListControl->setToolTip(aToolTip); + myListControl->setSelectionMode(QAbstractItemView::ExtendedSelection); + + aMainLay->addWidget(myListControl, 2, 0, 1, -1); aMainLay->setRowStretch(2, 1); - aMainLay->addWidget(new QLabel(this)); //FIXME(sbh)??? - aMainLay->setRowMinimumHeight(3, 20); - this->setLayout(aMainLay); + //aMainLay->addWidget(new QLabel(this)); //FIXME(sbh)??? + //aMainLay->setRowMinimumHeight(3, 20); + //this->setLayout(aMainLay); connect(myTypeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onSelectionTypeChanged())); myCopyAction = new QAction(QIcon(":pictures/copy.png"), tr("Copy"), this); @@ -98,171 +147,90 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen myCopyAction->setEnabled(false); connect(myCopyAction, SIGNAL(triggered(bool)), SLOT(onCopyItem())); myListControl->addAction(myCopyAction); + + myDeleteAction = new QAction(QIcon(":pictures/delete.png"), tr("Delete"), this); + myDeleteAction->setEnabled(false); + connect(myDeleteAction, SIGNAL(triggered(bool)), SLOT(onDeleteItem())); + myListControl->addAction(myDeleteAction); + myListControl->setContextMenuPolicy(Qt::ActionsContextMenu); connect(myListControl, SIGNAL(itemSelectionChanged()), SLOT(onListSelection())); } ModuleBase_WidgetMultiSelector::~ModuleBase_WidgetMultiSelector() { - delete myShapeValidator; -} - -//TODO: nds stabilization hotfix -void ModuleBase_WidgetMultiSelector::disconnectSignals() -{ - disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); } //******************************************************************** void ModuleBase_WidgetMultiSelector::activateCustom() { - ModuleBase_IViewer* aViewer = myWorkshop->viewer(); - connect(myWorkshop, SIGNAL(selectionChanged()), - this, SLOT(onSelectionChanged()), - Qt::UniqueConnection); - - activateShapeSelection(true); - - // Restore selection in the viewer by the attribute selection list - myWorkshop->setSelected(getAttributeSelection()); + ModuleBase_WidgetSelector::activateCustom(); - activateFilters(myWorkshop, true); + myWorkshop->module()->activateCustomPrs(myFeature, + ModuleBase_IModule::CustomizeHighlightedObjects, true); } //******************************************************************** void ModuleBase_WidgetMultiSelector::deactivate() { - disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); - activateShapeSelection(false); - activateFilters(myWorkshop, false); + ModuleBase_WidgetSelector::deactivate(); + + myWorkshop->module()->deactivateCustomPrs(ModuleBase_IModule::CustomizeHighlightedObjects, true); } //******************************************************************** -bool ModuleBase_WidgetMultiSelector::storeValueCustom() const +bool ModuleBase_WidgetMultiSelector::storeValueCustom() { // the value is stored on the selection changed signal processing // A rare case when plugin was not loaded. - if(!myFeature) + if (!myFeature) return false; - DataPtr aData = myFeature->data(); - AttributeSelectionListPtr aSelectionListAttr = - std::dynamic_pointer_cast(aData->attribute(attributeID())); - - if (aSelectionListAttr) { - // Store shapes type - TopAbs_ShapeEnum aCurrentType = - ModuleBase_Tools::shapeType(myTypeCombo->currentText()); - aSelectionListAttr->setSelectionType(myTypeCombo->currentText().toStdString()); - } - return true; + + AttributePtr anAttribute = myFeature->data()->attribute(attributeID()); + std::string aType = anAttribute->attributeType(); + if (aType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); + aSelectionListAttr->setSelectionType(myTypeCombo->currentText().toStdString()); + } + return true; } //******************************************************************** -bool ModuleBase_WidgetMultiSelector::restoreValue() +bool ModuleBase_WidgetMultiSelector::restoreValueCustom() { // A rare case when plugin was not loaded. - if(!myFeature) + if (!myFeature) return false; - DataPtr aData = myFeature->data(); - AttributeSelectionListPtr aSelectionListAttr = - std::dynamic_pointer_cast(aData->attribute(attributeID())); - if (aSelectionListAttr) { + AttributePtr anAttribute = myFeature->data()->attribute(attributeID()); + std::string aType = anAttribute->attributeType(); + if (aType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); // Restore shape type - if (!aSelectionListAttr->selectionType().empty()) - setCurrentShapeType(ModuleBase_Tools::shapeType(aSelectionListAttr->selectionType().c_str())); - updateSelectionList(aSelectionListAttr); - return true; - } - return false; -} - -//******************************************************************** -void ModuleBase_WidgetMultiSelector::storeAttributeValue() -{ - DataPtr aData = myFeature->data(); - AttributeSelectionListPtr aSelectionListAttr = - std::dynamic_pointer_cast(aData->attribute(attributeID())); - if (aSelectionListAttr.get() == NULL) - return; - - mySelectionType = aSelectionListAttr->selectionType(); - mySelection.clear(); - int aSize = aSelectionListAttr->size(); - for (int i = 0; i < aSelectionListAttr->size(); i++) { - AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i); - mySelection.append(GeomSelection(aSelectAttr->context(), aSelectAttr->value())); - } -} - -//******************************************************************** -void ModuleBase_WidgetMultiSelector::setObject(ObjectPtr theSelectedObject, - GeomShapePtr theShape) -{ - DataPtr aData = myFeature->data(); - AttributeSelectionListPtr aSelectionListAttr = - std::dynamic_pointer_cast(aData->attribute(attributeID())); - - ResultPtr aResult = std::dynamic_pointer_cast(theSelectedObject); - aSelectionListAttr->append(aResult, theShape); -} - -//******************************************************************** -void ModuleBase_WidgetMultiSelector::restoreAttributeValue(bool/* theValid*/) -{ - DataPtr aData = myFeature->data(); - AttributeSelectionListPtr aSelectionListAttr = - std::dynamic_pointer_cast(aData->attribute(attributeID())); - if (aSelectionListAttr.get() == NULL) - return; - aSelectionListAttr->clear(); - - // Store shapes type - aSelectionListAttr->setSelectionType(mySelectionType); - - // Store selection in the attribute - int aSize = mySelection.size(); - foreach (GeomSelection aSelec, mySelection) { - setObject(aSelec.first, aSelec.second); + std::string aSelectionType = aSelectionListAttr->selectionType().c_str(); + if (!aSelectionType.empty()) + setCurrentShapeType(ModuleBase_Tools::shapeType(aSelectionType.c_str())); } + updateSelectionList(); + return true; } //******************************************************************** -bool ModuleBase_WidgetMultiSelector::acceptSubShape(const TopoDS_Shape& theShape) const +bool ModuleBase_WidgetMultiSelector::setSelection(QList& theValues, + const bool theToValidate) { - 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 - } - else { - aValid = false; - TopAbs_ShapeEnum aShapeType = theShape.ShapeType(); - if (myTypeCombo->count() > 1) { - TopAbs_ShapeEnum aType = ModuleBase_Tools::shapeType(myTypeCombo->currentText()); - aValid = aShapeType == aType; - } - else { - for(int i = 0, aCount = myTypeCombo->count(); i < aCount && !aValid; i++) { - TopAbs_ShapeEnum aType = ModuleBase_Tools::shapeType(myTypeCombo->itemText(i)); - aValid = aShapeType == aType; - } - } - } - return aValid; -} + QList aSkippedValues; -//******************************************************************** -bool ModuleBase_WidgetMultiSelector::setSelection(QList& theValues) -{ - QList aSkippedValues; + /// remove unused objects from the model attribute. + /// It should be performed before new attributes append. + removeUnusedAttributeObjects(theValues); - QList::const_iterator anIt = theValues.begin(), aLast = theValues.end(); + QList::const_iterator anIt = theValues.begin(), aLast = theValues.end(); bool isDone = false; for (; anIt != aLast; anIt++) { - ModuleBase_ViewerPrs aValue = *anIt; + ModuleBase_ViewerPrsPtr aValue = *anIt; bool aProcessed = false; - if (isValidSelection(aValue)) { + if (!theToValidate || isValidInFilters(aValue)) { aProcessed = setSelectionCustom(aValue); } else @@ -277,6 +245,7 @@ bool ModuleBase_WidgetMultiSelector::setSelection(QList& t // this emit is necessary to call store/restore method an restore type of selection //emit valuesChanged(); //} + theValues.clear(); if (!aSkippedValues.empty()) theValues.append(aSkippedValues); @@ -285,56 +254,78 @@ bool ModuleBase_WidgetMultiSelector::setSelection(QList& t } //******************************************************************** -bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_ViewerPrs& thePrs) +void ModuleBase_WidgetMultiSelector::getHighlighted(QList& theValues) { -#ifdef DEBUG_SHAPE_VALIDATION_PREVIOUS - return true; -#endif - GeomShapePtr aShape = myWorkshop->selection()->getShape(thePrs); - // if there is no result(the feature is presentable only), result is false - ResultPtr aResult = myWorkshop->selection()->getResult(thePrs); - bool aValid = aResult.get() != NULL; - if (aValid) { - // if there is no selected shape, the method returns true - if (!aShape.get()) - aValid = true; - else { - // Check that the selection corresponds to selection type - TopoDS_Shape aTopoShape = aShape->impl(); - aValid = acceptSubShape(aTopoShape); - } - } + std::set anAttributeIds; + getSelectedAttributeIndices(anAttributeIds); + if (!anAttributeIds.empty()) + convertIndicesToViewerSelection(anAttributeIds, theValues); +} +//******************************************************************** +bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& thePrs) +{ + bool aValid = ModuleBase_WidgetSelector::isValidSelectionCustom(thePrs); if (aValid) { - if (myFeature) { - // We can not select a result of our feature - const std::list& aResList = myFeature->results(); - std::list::const_iterator aIt; - bool isSkipSelf = false; - for (aIt = aResList.cbegin(); aIt != aResList.cend(); ++aIt) { - if ((*aIt) == aResult) { - isSkipSelf = true; - break; + ResultPtr aResult = myWorkshop->selection()->getResult(thePrs); + aValid = aResult.get() != NULL; + if (aValid) { + if (myFeature) { + // We can not select a result of our feature + const std::list& aResList = myFeature->results(); + std::list::const_iterator aIt; + bool isSkipSelf = false; + for (aIt = aResList.cbegin(); aIt != aResList.cend(); ++aIt) { + if ((*aIt) == aResult) { + isSkipSelf = true; + break; + } } + if (isSkipSelf) + aValid = false; } - if(isSkipSelf) - aValid = false; } } - return aValid; } //******************************************************************** -bool ModuleBase_WidgetMultiSelector::setSelectionCustom(const ModuleBase_ViewerPrs& thePrs) +bool ModuleBase_WidgetMultiSelector::processDelete() { - // DEBUG_THE_SAME_AS_SHAPE - ObjectPtr anObject; - GeomShapePtr aShape; - getGeomSelection(thePrs, anObject, aShape); + // find attribute indices to delete + std::set anAttributeIds; + getSelectedAttributeIndices(anAttributeIds); - setObject(anObject, aShape); - return true; + // refill attribute by the items which indices are not in the list of ids + bool aDone = false; + DataPtr aData = myFeature->data(); + AttributePtr anAttribute = aData->attribute(attributeID()); + std::string aType = anAttribute->attributeType(); + aDone = !anAttributeIds.empty(); + if (aType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(attributeID()); + aSelectionListAttr->remove(anAttributeIds); + + } + else if (aType == ModelAPI_AttributeRefList::typeId()) { + AttributeRefListPtr aRefListAttr = aData->reflist(attributeID()); + aRefListAttr->remove(anAttributeIds); + } + else if (aType == ModelAPI_AttributeRefAttrList::typeId()) { + AttributeRefAttrListPtr aRefAttrListAttr = aData->refattrlist(attributeID()); + aRefAttrListAttr->remove(anAttributeIds); + } + + if (aDone) { + // update object is necessary to flush update signal. It leads to objects references map update + // and the operation presentation will not contain deleted items visualized as parameters of + // the feature. + updateObject(myFeature); + + restoreValue(); + myWorkshop->setSelected(getAttributeSelection()); + } + return aDone; } //******************************************************************** @@ -349,36 +340,45 @@ QList ModuleBase_WidgetMultiSelector::getControls() const //******************************************************************** void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged() { - activateShapeSelection(true); - activateFilters(myWorkshop, true); - QList anEmptyList; + activateSelectionAndFilters(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 myWorkshop->setSelected(anEmptyList); } -//******************************************************************** -void ModuleBase_WidgetMultiSelector::onSelectionChanged() +void ModuleBase_WidgetMultiSelector::updateFocus() { - QList aSelected = myWorkshop->selection()->getSelected(ModuleBase_ISelection::AllControls); - - DataPtr aData = myFeature->data(); - AttributeSelectionListPtr aSelectionListAttr = - std::dynamic_pointer_cast(aData->attribute(attributeID())); - aSelectionListAttr->clear(); - - setSelection(aSelected); - - 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); - // Set focus to List control in order to make possible // to use Tab key for transfer the focus to next widgets myListControl->setCurrentRow(myListControl->model()->rowCount() - 1); - myListControl->setFocus(); + ModuleBase_Tools::setFocus(myListControl, + "ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()"); +} + +//******************************************************************** +void ModuleBase_WidgetMultiSelector::updateSelectionName() +{ +} + +//******************************************************************** +QIntList ModuleBase_WidgetMultiSelector::getShapeTypes() const +{ + QIntList aShapeTypes; + + if (myTypeCombo->count() > 1 && myIsUseChoice) { + aShapeTypes.append(ModuleBase_Tools::shapeType(myTypeCombo->currentText())); + } + else { + for (int i = 0, aCount = myTypeCombo->count(); i < aCount; i++) { + TopAbs_ShapeEnum aType = ModuleBase_Tools::shapeType(myTypeCombo->itemText(i)); + aShapeTypes.append(aType); + if (aType == TopAbs_SOLID) + aShapeTypes.append(TopAbs_COMPSOLID); + } + } + return aShapeTypes; } //******************************************************************** @@ -390,83 +390,74 @@ void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const TopAbs_ShapeEnum aShapeTypeName = myTypeCombo->itemText(idx); TopAbs_ShapeEnum aRefType = ModuleBase_Tools::shapeType(aShapeTypeName); if(aRefType == theShapeType && idx != myTypeCombo->currentIndex()) { - activateShapeSelection(false); - activateFilters(myWorkshop, false); + bool aWasActivated = activateSelectionAndFilters(false); bool isBlocked = myTypeCombo->blockSignals(true); myTypeCombo->setCurrentIndex(idx); myTypeCombo->blockSignals(isBlocked); - - activateShapeSelection(true); - activateFilters(myWorkshop, true); + if (aWasActivated) + activateSelectionAndFilters(true); break; } } } -void ModuleBase_WidgetMultiSelector::activateShapeSelection(const bool isActivated) +QList ModuleBase_WidgetMultiSelector::getAttributeSelection() const { - ModuleBase_IViewer* aViewer = myWorkshop->viewer(); + QList aSelected; + convertIndicesToViewerSelection(std::set(), aSelected); + return aSelected; +} - if (isActivated) { - QString aNewType = myTypeCombo->currentText(); - QIntList aList; - if (true /*myIsUseChoice*/) { - aList.append(ModuleBase_Tools::shapeType(aNewType)); +//******************************************************************** +void ModuleBase_WidgetMultiSelector::updateSelectionList() +{ + myListControl->clear(); + + 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++) { + AttributeSelectionPtr aAttr = aSelectionListAttr->value(i); + QListWidgetItem* anItem = new QListWidgetItem(aAttr->namingName().c_str(), myListControl); + anItem->setData(ATTRIBUTE_SELECTION_INDEX_ROLE, i); + myListControl->addItem(anItem); } - else { - for(int i = 0, aCount = myTypeCombo->count(); i < aCount; i++) - aList.append(ModuleBase_Tools::shapeType(myTypeCombo->itemText(i))); + } + 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()) { + QListWidgetItem* anItem = new QListWidgetItem(anObject->data()->name().c_str(), + myListControl); + anItem->setData(ATTRIBUTE_SELECTION_INDEX_ROLE, i); + myListControl->addItem(anItem); + } } - myWorkshop->activateSubShapesSelection(aList); - } else { - myWorkshop->deactivateSubShapesSelection(); } -} - -QList ModuleBase_WidgetMultiSelector::getAttributeSelection() const -{ - QList aSelected; - // Restore selection in the viewer by the attribute selection list - if(myFeature) { - DataPtr aData = myFeature->data(); - AttributeSelectionListPtr aListAttr = - std::dynamic_pointer_cast(aData->attribute(attributeID())); - if (aListAttr) { - for (int i = 0; i < aListAttr->size(); i++) { - AttributeSelectionPtr anAttr = aListAttr->value(i); - ResultPtr anObject = anAttr->context(); + else if (aType == ModelAPI_AttributeRefAttrList::typeId()) { + AttributeRefAttrListPtr aRefAttrListAttr = aData->refattrlist(attributeID()); + for (int i = 0; i < aRefAttrListAttr->size(); i++) { + AttributePtr anAttribute = aRefAttrListAttr->attribute(i); + QString aName; + if (anAttribute.get()) { + std::string anAttrName = generateName(anAttribute, myWorkshop); + aName = QString::fromStdString(anAttrName); + } + else { + ObjectPtr anObject = aRefAttrListAttr->object(i); 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)); + aName = anObject->data()->name().c_str(); } } + QListWidgetItem* anItem = new QListWidgetItem(aName, myListControl); + anItem->setData(ATTRIBUTE_SELECTION_INDEX_ROLE, i); + myListControl->addItem(anItem); } } - return aSelected; -} - -//******************************************************************** -void ModuleBase_WidgetMultiSelector::getGeomSelection(const ModuleBase_ViewerPrs& thePrs, - ObjectPtr& theObject, - GeomShapePtr& theShape) -{ - // DEBUG_THE_SAME_AS_SHAPE - theObject = myWorkshop->selection()->getResult(thePrs); - theShape = myWorkshop->selection()->getShape(thePrs); -} -//******************************************************************** -void ModuleBase_WidgetMultiSelector::updateSelectionList(AttributeSelectionListPtr theList) -{ - myListControl->clear(); - for (int i = 0; i < theList->size(); i++) { - AttributeSelectionPtr aAttr = theList->value(i); - myListControl->addItem(aAttr->namingName().c_str()); - } // We have to call repaint because sometimes the List control is not updated myListControl->repaint(); } @@ -504,10 +495,192 @@ void ModuleBase_WidgetMultiSelector::onCopyItem() } } +//******************************************************************** +void ModuleBase_WidgetMultiSelector::onDeleteItem() +{ + processDelete(); +} + //******************************************************************** void ModuleBase_WidgetMultiSelector::onListSelection() { QList aItems = myListControl->selectedItems(); myCopyAction->setEnabled(!aItems.isEmpty()); + myDeleteAction->setEnabled(!aItems.isEmpty()); + + myWorkshop->module()->customizeObject(myFeature, ModuleBase_IModule::CustomizeHighlightedObjects, + true); +} + +//******************************************************************** +void ModuleBase_WidgetMultiSelector::getSelectedAttributeIndices(std::set& theAttributeIds) +{ + QList aItems = myListControl->selectedItems(); + foreach(QListWidgetItem* anItem, aItems) { + int anIndex = anItem->data(ATTRIBUTE_SELECTION_INDEX_ROLE).toInt(); + if (theAttributeIds.find(anIndex) == theAttributeIds.end()) + theAttributeIds.insert(anIndex); + } } +void ModuleBase_WidgetMultiSelector::convertIndicesToViewerSelection(std::set theAttributeIds, + QList& 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( + 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( + 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( + new ModuleBase_ViewerPrs(anObject, aGeomShape, NULL))); + } + } + } +} + +void ModuleBase_WidgetMultiSelector::removeUnusedAttributeObjects + (QList& theValues) +{ + std::map > aGeomSelection = convertSelection(theValues); + DataPtr aData = myFeature->data(); + AttributePtr anAttribute = aData->attribute(attributeID()); + std::string aType = anAttribute->attributeType(); + std::set aShapes; + std::set 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); + if (!aFound) + anIndicesToBeRemoved.insert(i); + } + 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); + if (!aFound) + anIndicesToBeRemoved.insert(i); + } + } + aRefListAttr->remove(anIndicesToBeRemoved); + } + else if (aType == ModelAPI_AttributeRefAttrList::typeId()) { + std::set anAttributes; + QList::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); + } + if (!aFound) + anIndicesToBeRemoved.insert(i); + } + aRefAttrListAttr->remove(anIndicesToBeRemoved); + } +} + +std::map > ModuleBase_WidgetMultiSelector::convertSelection + (QList& theValues) +{ + // convert prs list to objects map + std::map > aGeomSelection; + std::set aShapes; + QList::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, + const GeomShapePtr& theShape, + const std::map >& theGeomSelection) +{ + bool aFound = false; + GeomShapePtr anEmptyShape(new GeomAPI_Shape()); + GeomShapePtr aShape = theShape.get() ? theShape : anEmptyShape; + if (theGeomSelection.find(theObject) != theGeomSelection.end()) {// found + const std::set& aShapes = theGeomSelection.at(theObject); + std::set::const_iterator anIt = aShapes.begin(), aLast = aShapes.end(); + for (; anIt != aLast && !aFound; anIt++) { + GeomShapePtr aCShape = *anIt; + if (aCShape.get()) + aFound = aCShape->isEqual(aShape); + } + } + return aFound; +}