X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModuleBase%2FModuleBase_WidgetMultiSelector.cpp;h=00b13340261664da441ec695877efc0d5a66cfe2;hb=29dfb8a802f61cacf5f57fb79c62badee00ebcdf;hp=a0e85e14c2c0342d8722d39e45da41ce28945546;hpb=055d3c94f677cdf74eca05711fe9dcae89035d58;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 a0e85e14c..00b133402 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp @@ -14,11 +14,12 @@ #include #include #include - -#include +#include #include #include +#include +#include #include @@ -32,17 +33,60 @@ #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_WidgetSelector(theParent, theWorkshop, theData, theParentId) + : ModuleBase_WidgetSelector(theParent, theWorkshop, theData, theParentId), + mySelectionCount(0) { QGridLayout* aMainLay = new QGridLayout(this); ModuleBase_Tools::adjustMargins(aMainLay); @@ -55,14 +99,15 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen 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); - 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); } @@ -72,7 +117,7 @@ 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) { + if (aShapeTypes.size() <= 1) { QString aLabelIcon = QString::fromStdString(theData->widgetIcon()); if (!aLabelIcon.isEmpty()) { QLabel* aSelectedLabel = new QLabel("", this); @@ -82,12 +127,18 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen 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); @@ -95,6 +146,12 @@ 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())); } @@ -103,100 +160,140 @@ ModuleBase_WidgetMultiSelector::~ModuleBase_WidgetMultiSelector() { } +//******************************************************************** +void ModuleBase_WidgetMultiSelector::activateCustom() +{ + ModuleBase_WidgetSelector::activateCustom(); + + myWorkshop->module()->activateCustomPrs(myFeature, + ModuleBase_IModule::CustomizeHighlightedObjects, true); +} + +//******************************************************************** +void ModuleBase_WidgetMultiSelector::deactivate() +{ + ModuleBase_WidgetSelector::deactivate(); + + myWorkshop->module()->deactivateCustomPrs(ModuleBase_IModule::CustomizeHighlightedObjects, true); +} + //******************************************************************** bool ModuleBase_WidgetMultiSelector::storeValueCustom() const { // 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 = + std::dynamic_pointer_cast(anAttribute); + 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 = + std::dynamic_pointer_cast(anAttribute); // Restore shape type - if (!aSelectionListAttr->selectionType().empty()) - setCurrentShapeType(ModuleBase_Tools::shapeType(aSelectionListAttr->selectionType().c_str())); - updateSelectionList(aSelectionListAttr); - return true; + setCurrentShapeType(ModuleBase_Tools::shapeType(aSelectionListAttr->selectionType().c_str())); } - return false; + updateSelectionList(); + return true; } //******************************************************************** 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())); + ModuleBase_WidgetValidated::storeAttributeValue(); + + AttributePtr anAttribute = myFeature->data()->attribute(attributeID()); + std::string aType = anAttribute->attributeType(); + if (aType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aSelectionListAttr = + std::dynamic_pointer_cast(anAttribute); + mySelectionType = aSelectionListAttr->selectionType(); + mySelectionCount = aSelectionListAttr->size(); + } + else if (aType == ModelAPI_AttributeRefList::typeId()) { + AttributeRefListPtr aRefListAttr = + std::dynamic_pointer_cast(anAttribute); + mySelectionCount = aRefListAttr->size(); } } //******************************************************************** -void ModuleBase_WidgetMultiSelector::clearAttribute() +void ModuleBase_WidgetMultiSelector::restoreAttributeValue(bool theValid) { - DataPtr aData = myFeature->data(); - AttributeSelectionListPtr aSelectionListAttr = - std::dynamic_pointer_cast(aData->attribute(attributeID())); - aSelectionListAttr->clear(); + ModuleBase_WidgetValidated::restoreAttributeValue(theValid); + + AttributePtr anAttribute = myFeature->data()->attribute(attributeID()); + std::string aType = anAttribute->attributeType(); + if (aType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aSelectionListAttr = + std::dynamic_pointer_cast(anAttribute); + aSelectionListAttr->setSelectionType(mySelectionType); + + // restore selection in the attribute. Indeed there is only one stored object + int aCountAppened = aSelectionListAttr->size() - mySelectionCount; + for (int i = 0; i < aCountAppened; i++) + aSelectionListAttr->removeLast(); + } + else if (aType == ModelAPI_AttributeRefList::typeId()) { + AttributeRefListPtr aRefListAttr = + std::dynamic_pointer_cast(anAttribute); + // restore objects in the attribute. Indeed there is only one stored object + int aCountAppened = aRefListAttr->size() - mySelectionCount; + for (int i = 0; i < aCountAppened; i++) + aRefListAttr->removeLast(); + } } //******************************************************************** -void ModuleBase_WidgetMultiSelector::setObject(ObjectPtr theSelectedObject, - GeomShapePtr theShape) +void ModuleBase_WidgetMultiSelector::clearAttribute() { - DataPtr aData = myFeature->data(); - AttributeSelectionListPtr aSelectionListAttr = - std::dynamic_pointer_cast(aData->attribute(attributeID())); - - ResultPtr aResult = std::dynamic_pointer_cast(theSelectedObject); - aSelectionListAttr->append(aResult, theShape); + AttributePtr anAttribute = myFeature->data()->attribute(attributeID()); + std::string aType = anAttribute->attributeType(); + if (aType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aSelectionListAttr = + std::dynamic_pointer_cast(anAttribute); + aSelectionListAttr->clear(); + } + else if (aType == ModelAPI_AttributeRefList::typeId()) { + AttributeRefListPtr aRefListAttr = + std::dynamic_pointer_cast(anAttribute); + aRefListAttr->clear(); + } } //******************************************************************** -void ModuleBase_WidgetMultiSelector::restoreAttributeValue(bool/* theValid*/) +void ModuleBase_WidgetMultiSelector::setObject(ObjectPtr theSelectedObject, + GeomShapePtr theShape) { - clearAttribute(); - - // Store shape type - DataPtr aData = myFeature->data(); - AttributeSelectionListPtr aSelectionListAttr = - std::dynamic_pointer_cast(aData->attribute(attributeID())); - aSelectionListAttr->setSelectionType(mySelectionType); - - // Store selection in the attribute - int aSize = mySelection.size(); - foreach (GeomSelection aSelec, mySelection) { - setObject(aSelec.first, aSelec.second); + AttributePtr anAttribute = myFeature->data()->attribute(attributeID()); + std::string aType = anAttribute->attributeType(); + if (aType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aSelectionListAttr = + std::dynamic_pointer_cast(anAttribute); + ResultPtr aResult = std::dynamic_pointer_cast(theSelectedObject); + aSelectionListAttr->append(aResult, theShape, myIsInValidate); + } + else if (aType == ModelAPI_AttributeRefList::typeId()) { + AttributeRefListPtr aRefListAttr = + std::dynamic_pointer_cast(anAttribute); + aRefListAttr->append(theSelectedObject); } } @@ -233,6 +330,15 @@ bool ModuleBase_WidgetMultiSelector::setSelection(QList& t return isDone; } +//******************************************************************** +void ModuleBase_WidgetMultiSelector::getHighlighted(QList& theValues) +{ + std::set anAttributeIds; + getSelectedAttributeIndices(anAttributeIds); + if (!anAttributeIds.empty()) + convertIndicesToViewerSelection(anAttributeIds, theValues); +} + //******************************************************************** bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_ViewerPrs& thePrs) { @@ -260,6 +366,42 @@ bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_Vie return aValid; } +//******************************************************************** +bool ModuleBase_WidgetMultiSelector::processDelete() +{ + // find attribute indices to delete + std::set anAttributeIds; + getSelectedAttributeIndices(anAttributeIds); + + // refill attribute by the items which indices are not in the list of ids + bool aDone = false; + AttributePtr anAttribute = myFeature->data()->attribute(attributeID()); + std::string aType = anAttribute->attributeType(); + if (aType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aSelectionListAttr = + std::dynamic_pointer_cast(anAttribute); + aDone = !anAttributeIds.empty(); + aSelectionListAttr->remove(anAttributeIds); + + } + else if (aType == ModelAPI_AttributeRefList::typeId()) { + AttributeRefListPtr aRefListAttr = + std::dynamic_pointer_cast(anAttribute); + aDone = !anAttributeIds.empty(); + aRefListAttr->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; +} + //******************************************************************** QList ModuleBase_WidgetMultiSelector::getControls() const { @@ -272,8 +414,7 @@ QList ModuleBase_WidgetMultiSelector::getControls() const //******************************************************************** void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged() { - activateSelection(true); - activateFilters(true); + activateSelectionAndFilters(true); QList anEmptyList; // This method will call Selection changed event which will call onSelectionChanged // To clear mySelection, myListControl and storeValue() @@ -286,7 +427,8 @@ void ModuleBase_WidgetMultiSelector::updateFocus() // 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()"); } //******************************************************************** @@ -304,7 +446,10 @@ QIntList ModuleBase_WidgetMultiSelector::getShapeTypes() const } else { for (int i = 0, aCount = myTypeCombo->count(); i < aCount; i++) { - aShapeTypes.append(ModuleBase_Tools::shapeType(myTypeCombo->itemText(i))); + TopAbs_ShapeEnum aType = ModuleBase_Tools::shapeType(myTypeCombo->itemText(i)); + aShapeTypes.append(aType); + if (aType == TopAbs_SOLID) + aShapeTypes.append(TopAbs_COMPSOLID); } } return aShapeTypes; @@ -319,14 +464,12 @@ void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const TopAbs_ShapeEnum aShapeTypeName = myTypeCombo->itemText(idx); TopAbs_ShapeEnum aRefType = ModuleBase_Tools::shapeType(aShapeTypeName); if(aRefType == theShapeType && idx != myTypeCombo->currentIndex()) { - activateSelection(false); - activateFilters(false); + activateSelectionAndFilters(false); bool isBlocked = myTypeCombo->blockSignals(true); myTypeCombo->setCurrentIndex(idx); myTypeCombo->blockSignals(isBlocked); - activateSelection(true); - activateFilters(true); + activateSelectionAndFilters(true); break; } } @@ -335,37 +478,41 @@ void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const TopAbs_ShapeEnum 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(); - 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)); - } - } - } - } + convertIndicesToViewerSelection(std::set(), aSelected); return aSelected; } //******************************************************************** -void ModuleBase_WidgetMultiSelector::updateSelectionList(AttributeSelectionListPtr theList) +void ModuleBase_WidgetMultiSelector::updateSelectionList() { myListControl->clear(); - for (int i = 0; i < theList->size(); i++) { - AttributeSelectionPtr aAttr = theList->value(i); - myListControl->addItem(aAttr->namingName().c_str()); + + AttributePtr anAttribute = myFeature->data()->attribute(attributeID()); + std::string aType = anAttribute->attributeType(); + if (aType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aSelectionListAttr = + std::dynamic_pointer_cast(anAttribute); + 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 if (aType == ModelAPI_AttributeRefList::typeId()) { + AttributeRefListPtr aRefListAttr = + std::dynamic_pointer_cast(anAttribute); + 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); + } + } + } + // We have to call repaint because sometimes the List control is not updated myListControl->repaint(); } @@ -403,9 +550,72 @@ 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; + + AttributePtr anAttribute = myFeature->data()->attribute(attributeID()); + std::string aType = anAttribute->attributeType(); + if (aType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aSelectionListAttr = + std::dynamic_pointer_cast(anAttribute); + 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()) { + TopoDS_Shape aShape; + std::shared_ptr aShapePtr = anAttr->value(); + if (aShapePtr.get()) { + aShape = aShapePtr->impl(); + } + theValues.append(ModuleBase_ViewerPrs(anObject, aShape, NULL)); + } + } + } + else if (aType == ModelAPI_AttributeRefList::typeId()) { + AttributeRefListPtr aRefListAttr = + std::dynamic_pointer_cast(anAttribute); + 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(ModuleBase_ViewerPrs(anObject, TopoDS_Shape(), NULL)); + } + } + } }