X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModuleBase%2FModuleBase_WidgetMultiSelector.cpp;h=40149e343af3eaa76486ab8e32c62541712a22ed;hb=8cd56d486b6e96b8814002f9f0f4acadd6cea11b;hp=c2e3138a534a37470800e452fb16f8edb031bdec;hpb=01d6bb2a163b2c89e86444bc8b4f1a24a58e4c2a;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 c2e3138a5..40149e343 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D /* * ModuleBase_WidgetMultiSelector.cpp @@ -13,9 +13,12 @@ #include #include #include +#include #include #include +#include +#include #include @@ -29,16 +32,58 @@ #include #include #include +#include #include #include +/** +* 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), myIsActive(false) + : ModuleBase_WidgetSelector(theParent, theWorkshop, theData, theParentId), + mySelectionCount(0) { QGridLayout* aMainLay = new QGridLayout(this); ModuleBase_Tools::adjustMargins(aMainLay); @@ -47,39 +92,47 @@ 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 + // 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); - myTypeCombo->addItems(aShapeTypes); + myIsUseChoice = theData->getBooleanAttribute("use_choice", true); + + 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) { + if (aShapeTypes.size() <= 1 || !myIsUseChoice) { aTypeLabel->setVisible(false); myTypeCombo->setVisible(false); } - QLabel* aListLabel = new QLabel(tr("Selected objects:"), this); + std::string aLabelText = theData->getProperty("label"); + QLabel* aListLabel = new QLabel(!aLabelText.empty() ? aLabelText.c_str() + : 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); + myListControl = new CustomListWidget(this); + QString anObjName = QString::fromStdString(attributeID()); + myListControl->setObjectName(anObjName); + + 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); @@ -93,28 +146,6 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen ModuleBase_WidgetMultiSelector::~ModuleBase_WidgetMultiSelector() { - myIsActive = false; - activateShapeSelection(); -} - -//******************************************************************** -void ModuleBase_WidgetMultiSelector::activateCustom() -{ - ModuleBase_IViewer* aViewer = myWorkshop->viewer(); - connect(myWorkshop, SIGNAL(selectionChanged()), - this, SLOT(onSelectionChanged()), - Qt::UniqueConnection); - - myIsActive = true; - activateShapeSelection(); -} - -//******************************************************************** -void ModuleBase_WidgetMultiSelector::deactivate() -{ - disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); - myIsActive = false; - activateShapeSelection(); } //******************************************************************** @@ -122,162 +153,158 @@ 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()); + + AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); + if (aSelectionListAttr.get()) { 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) { + AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); + if (aSelectionListAttr.get()) { // Restore shape type - setCurrentShapeType(ModuleBase_Tools::shapeType(aSelectionListAttr->selectionType().c_str())); - updateSelectionList(aSelectionListAttr); - return true; + if (!aSelectionListAttr->selectionType().empty()) + 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(); + + AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); + if (aSelectionListAttr.get()) { + mySelectionType = aSelectionListAttr->selectionType(); + mySelectionCount = aSelectionListAttr->size(); + } + else { + AttributeRefListPtr aRefListAttr = myFeature->data()->reflist(attributeID()); + mySelectionCount = aRefListAttr->size(); } } //******************************************************************** -void ModuleBase_WidgetMultiSelector::restoreAttributeValue(bool/* theValid*/) +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) { - aSelectionListAttr->append(aSelec.first, aSelec.second); + ModuleBase_WidgetValidated::restoreAttributeValue(theValid); + + // Store shape type + AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); + if (aSelectionListAttr.get()) { + 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 { + AttributeRefListPtr aRefListAttr = myFeature->data()->reflist(attributeID()); + // 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(); } } //******************************************************************** -bool ModuleBase_WidgetMultiSelector::setSelection(const QList& theValues, - int& thePosition) +void ModuleBase_WidgetMultiSelector::clearAttribute() { - if (thePosition < 0) - return false; + AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); + if (aSelectionListAttr.get()) + aSelectionListAttr->clear(); + else { + AttributeRefListPtr aRefListAttr = myFeature->data()->reflist(attributeID()); + aRefListAttr->clear(); + } +} + +//******************************************************************** +void ModuleBase_WidgetMultiSelector::setObject(ObjectPtr theSelectedObject, + GeomShapePtr theShape) +{ + AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); + if (aSelectionListAttr.get()) { + ResultPtr aResult = std::dynamic_pointer_cast(theSelectedObject); + aSelectionListAttr->append(aResult, theShape, myIsInValidate); + } + else { + AttributeRefListPtr aRefListAttr = myFeature->data()->reflist(attributeID()); + aRefListAttr->append(theSelectedObject); + } +} + +//******************************************************************** +bool ModuleBase_WidgetMultiSelector::setSelection(QList& theValues, + const bool theToValidate) +{ + QList aSkippedValues; QList::const_iterator anIt = theValues.begin(), aLast = theValues.end(); bool isDone = false; - for (int i = thePosition; i < theValues.size(); i++) { - ModuleBase_ViewerPrs aValue = theValues[i]; - thePosition++; + for (; anIt != aLast; anIt++) { + ModuleBase_ViewerPrs aValue = *anIt; bool aProcessed = false; - if (isValidSelection(aValue)) { + if (!theToValidate || isValidInFilters(aValue)) { aProcessed = setSelectionCustom(aValue); } + else + aSkippedValues.append(aValue); // if there is at least one set, the result is true isDone = isDone || aProcessed; - // when an object, which do not satisfy the validating process, stop set selection - if (!aProcessed) - break; - } - if (isDone) { - updateObject(myFeature); - emit valuesChanged(); } + // updateObject - to update/redisplay feature + // it is commented in order to perfom it outside the method + //if (isDone) { + //updateObject(myFeature); + // this emit is necessary to call store/restore method an restore type of selection + //emit valuesChanged(); + //} + theValues.clear(); + if (!aSkippedValues.empty()) + theValues.append(aSkippedValues); + return isDone; } //******************************************************************** -bool ModuleBase_WidgetMultiSelector::setSelectionCustom(const ModuleBase_ViewerPrs& thePrs) +bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_ViewerPrs& thePrs) { - TopoDS_Shape aShape = thePrs.shape(); - if ((myTypeCombo->count() > 1) && (!aShape.IsNull())) { - TopAbs_ShapeEnum aType = ModuleBase_Tools::shapeType(myTypeCombo->currentText()); - if (aShape.ShapeType() != aType) - return false; - } - ResultPtr aResult; - if (!thePrs.owner().IsNull()) { - ObjectPtr anObject = myWorkshop->selection()->getSelectableObject(thePrs.owner()); - aResult = std::dynamic_pointer_cast(anObject); - } - else { - aResult = std::dynamic_pointer_cast(thePrs.object()); - } - - - 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; + bool aValid = ModuleBase_WidgetSelector::isValidSelectionCustom(thePrs); + if (aValid) { + 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) - return false; - } - - // if the result has the similar shap as the parameter shape, just the context is set to the - // selection list attribute. - DataPtr aData = myFeature->data(); - AttributeSelectionListPtr aSelectionListAttr = - std::dynamic_pointer_cast(aData->attribute(attributeID())); - - const TopoDS_Shape& aTDSShape = thePrs.shape(); - // if only result is selected, an empty shape is set to the model - if (aTDSShape.IsNull()) { - aSelectionListAttr->append(aResult, GeomShapePtr()); } - else { - GeomShapePtr aShape(new GeomAPI_Shape()); - aShape->setImpl(new TopoDS_Shape(aTDSShape)); - // We can not select a result of our feature - if (aShape->isEqual(aResult->shape())) - aSelectionListAttr->append(aResult, GeomShapePtr()); - else - aSelectionListAttr->append(aResult, aShape); - } - return true; + return aValid; } //******************************************************************** @@ -289,45 +316,48 @@ QList ModuleBase_WidgetMultiSelector::getControls() const return result; } -//******************************************************************** -bool ModuleBase_WidgetMultiSelector::eventFilter(QObject* theObj, QEvent* theEvent) -{ - //TODO: Remove maybe? - return ModuleBase_ModelWidget::eventFilter(theObj, theEvent); -} - //******************************************************************** void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged() { - activateShapeSelection(); - QObjectPtrList 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::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); + ModuleBase_Tools::setFocus(myListControl, + "ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()"); +} + //******************************************************************** -void ModuleBase_WidgetMultiSelector::onSelectionChanged() +void ModuleBase_WidgetMultiSelector::updateSelectionName() { - QList aSelected = getSelectedEntitiesOrObjects(myWorkshop->selection()); +} - DataPtr aData = myFeature->data(); - AttributeSelectionListPtr aSelectionListAttr = - std::dynamic_pointer_cast(aData->attribute(attributeID())); +//******************************************************************** +QIntList ModuleBase_WidgetMultiSelector::getShapeTypes() const +{ + QIntList aShapeTypes; - aSelectionListAttr->clear(); - if (aSelected.size() > 0) { - foreach (ModuleBase_ViewerPrs aPrs, aSelected) { - if (isValidSelection(aPrs)) { - setSelectionCustom(aPrs); - } + 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); } } - 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); + return aShapeTypes; } //******************************************************************** @@ -339,46 +369,93 @@ void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const TopAbs_ShapeEnum aShapeTypeName = myTypeCombo->itemText(idx); TopAbs_ShapeEnum aRefType = ModuleBase_Tools::shapeType(aShapeTypeName); if(aRefType == theShapeType && idx != myTypeCombo->currentIndex()) { - myIsActive = false; - activateShapeSelection(); + activateSelectionAndFilters(false); bool isBlocked = myTypeCombo->blockSignals(true); myTypeCombo->setCurrentIndex(idx); - myIsActive = true; myTypeCombo->blockSignals(isBlocked); - activateShapeSelection(); + + activateSelectionAndFilters(true); break; } } } -void ModuleBase_WidgetMultiSelector::activateShapeSelection() +QList ModuleBase_WidgetMultiSelector::getAttributeSelection() const { - ModuleBase_IViewer* aViewer = myWorkshop->viewer(); - - if (myIsActive) { - QString aNewType = myTypeCombo->currentText(); - QIntList aList; - aList.append(ModuleBase_Tools::shapeType(aNewType)); - myWorkshop->activateSubShapesSelection(aList); - } else { - myWorkshop->deactivateSubShapesSelection(); + QList aSelected; + // Restore selection in the viewer by the attribute selection list + if(myFeature) { + AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); + if (aSelectionListAttr.get()) { + for (int i = 0; i < aSelectionListAttr->size(); i++) { + 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(); + } + aSelected.append(ModuleBase_ViewerPrs(anObject, aShape, NULL)); + } + } + } + else { + AttributeRefListPtr aRefListAttr = myFeature->data()->reflist(attributeID()); + if (aRefListAttr.get()) { + for (int i = 0; i < aRefListAttr->size(); i++) { + ObjectPtr anObject = aRefListAttr->object(i); + if (anObject.get()) { + aSelected.append(ModuleBase_ViewerPrs(anObject, TopoDS_Shape(), NULL)); + } + } + } + } } - - activateFilters(myWorkshop, myIsActive); + 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()); + + AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); + if (aSelectionListAttr.get()) { + for (int i = 0; i < aSelectionListAttr->size(); i++) { + AttributeSelectionPtr aAttr = aSelectionListAttr->value(i); + myListControl->addItem(aAttr->namingName().c_str()); + } + } + else { + AttributeRefListPtr aRefListAttr = myFeature->data()->reflist(attributeID()); + for (int i = 0; i < aRefListAttr->size(); i++) { + ObjectPtr anObject = aRefListAttr->object(i); + if (anObject.get()) + myListControl->addItem(anObject->data()->name().c_str()); + } } // We have to call repaint because sometimes the List control is not updated myListControl->repaint(); } +//******************************************************************** +std::string ModuleBase_WidgetMultiSelector::validatorType(const QString& theType) const +{ + std::string aType; + + if (theType == "Vertices") + aType = "vertex"; + else if (theType == "Edges") + aType = "edge"; + else if (theType == "Faces") + aType = "face"; + else if (theType == "Solids") + aType = "solid"; + + return aType; +} + //******************************************************************** void ModuleBase_WidgetMultiSelector::onCopyItem() { @@ -401,4 +478,3 @@ void ModuleBase_WidgetMultiSelector::onListSelection() QList aItems = myListControl->selectedItems(); myCopyAction->setEnabled(!aItems.isEmpty()); } -