X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModuleBase%2FModuleBase_WidgetMultiSelector.cpp;h=98f45e37081cd3d54bb193b39feb7f3a44b59c44;hb=6944d6c94632a43f40f7929dffcc216c24917c3d;hp=bd9d0d702467c33eada8d0f03137d3989779e370;hpb=0a76161addf39a6d03b90308eb99abc3a8d10e74;p=modules%2Fshaper.git diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp index bd9d0d702..98f45e370 100644 --- 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 @@ -9,11 +9,13 @@ #include #include -#include #include #include #include #include +#include + +#include #include #include @@ -34,36 +36,82 @@ #include #include +//#define DEBUG_SHAPE_VALIDATION_PREVIOUS + +class CustomListWidget : public QListWidget +{ +public: + CustomListWidget( QWidget* theParent ) + : QListWidget( theParent ) + { + } + + virtual QSize sizeHint() const + { + int aHeight = 2*QFontMetrics( font() ).height(); + QSize aSize = QListWidget::sizeHint(); + return QSize( aSize.width(), aHeight ); + } + + virtual QSize minimumSizeHint() const + { + int aHeight = 2*QFontMetrics( font() ).height(); + QSize aSize = QListWidget::minimumSizeHint(); + return QSize( aSize.width(), aHeight ); + } +}; + ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop, const Config_WidgetAPI* theData, const std::string& theParentId) - : ModuleBase_ModelWidget(theParent, theData, theParentId), - myWorkshop(theWorkshop), myIsActive(false) + : ModuleBase_WidgetSelector(theParent, theWorkshop, theData, theParentId), + mySelectionType(""), mySelectionCount(0) { - myMainWidget = new QWidget(theParent); - QGridLayout* aMainLay = new QGridLayout(myMainWidget); + QGridLayout* aMainLay = new QGridLayout(this); ModuleBase_Tools::adjustMargins(aMainLay); - QLabel* aTypeLabel = new QLabel(tr("Type"), myMainWidget); + QLabel* aTypeLabel = new QLabel(tr("Type"), this); aMainLay->addWidget(aTypeLabel, 0, 0); - myTypeCombo = new QComboBox(myMainWidget); - // There is no sence to paramerize list of types while we can not parametrize selection mode - QString aTypesStr("Vertices Edges Faces Solids"); + myTypeCombo = new QComboBox(this); + // 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(' '); + + myIsUseChoice = theData->getBooleanAttribute("use_choice", true); + 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) { + aTypeLabel->setVisible(false); + myTypeCombo->setVisible(false); + } - QLabel* aListLabel = new QLabel(tr("Selected objects:"), myMainWidget); - aMainLay->addWidget(aListLabel, 1, 0, 1, -1); + 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 aLabelIcon = QString::fromStdString(theData->widgetIcon()); + if (!aLabelIcon.isEmpty()) { + QLabel* aSelectedLabel = new QLabel("", this); + aSelectedLabel->setPixmap(QPixmap(aLabelIcon)); + aMainLay->addWidget(aSelectedLabel, 1, 1); + } + aMainLay->setColumnStretch(2, 1); + } - myListControl = new QListWidget(myMainWidget); - aMainLay->addWidget(myListControl, 2, 0, 2, -1); + myListControl = new CustomListWidget(this); + aMainLay->addWidget(myListControl, 2, 0, 1, -1); aMainLay->setRowStretch(2, 1); - aMainLay->addWidget(new QLabel(myMainWidget)); - aMainLay->setRowMinimumHeight(3, 20); - myMainWidget->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); @@ -73,18 +121,16 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen myListControl->addAction(myCopyAction); myListControl->setContextMenuPolicy(Qt::ActionsContextMenu); connect(myListControl, SIGNAL(itemSelectionChanged()), SLOT(onListSelection())); - - activateSelection(true); } ModuleBase_WidgetMultiSelector::~ModuleBase_WidgetMultiSelector() { - activateSelection(false); } //******************************************************************** 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) return false; @@ -93,24 +139,16 @@ bool ModuleBase_WidgetMultiSelector::storeValueCustom() const std::dynamic_pointer_cast(aData->attribute(attributeID())); if (aSelectionListAttr) { - aSelectionListAttr->clear(); // Store shapes type - TopAbs_ShapeEnum aCurrentType = - ModuleBase_WidgetShapeSelector::shapeType(myTypeCombo->currentText()); - aSelectionListAttr->setSelectionType((int) aCurrentType); - // Store selection in the attribute - foreach (GeomSelection aSelec, mySelection) { - aSelectionListAttr->append(aSelec.first, aSelec.second); - } - //updateSelectionList(aSelectionListAttr); - updateObject(myFeature); - return true; - } - return false; + TopAbs_ShapeEnum aCurrentType = + ModuleBase_Tools::shapeType(myTypeCombo->currentText()); + 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) @@ -120,15 +158,9 @@ bool ModuleBase_WidgetMultiSelector::restoreValue() std::dynamic_pointer_cast(aData->attribute(attributeID())); if (aSelectionListAttr) { - mySelection.clear(); // Restore shape type - TopAbs_ShapeEnum aShapeType = (TopAbs_ShapeEnum) aSelectionListAttr->selectionType(); - setCurrentShapeType(aShapeType); - // Restore selection in the list - for (int i = 0; i < aSelectionListAttr->size(); i++) { - AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i); - mySelection.append(GeomSelection(aSelectAttr->context(), aSelectAttr->value())); - } + if (!aSelectionListAttr->selectionType().empty()) + setCurrentShapeType(ModuleBase_Tools::shapeType(aSelectionListAttr->selectionType().c_str())); updateSelectionList(aSelectionListAttr); return true; } @@ -136,105 +168,176 @@ bool ModuleBase_WidgetMultiSelector::restoreValue() } //******************************************************************** -QWidget* ModuleBase_WidgetMultiSelector::getControl() const +void ModuleBase_WidgetMultiSelector::storeAttributeValue() { - return myMainWidget; + DataPtr aData = myFeature->data(); + AttributeSelectionListPtr aSelectionListAttr = + std::dynamic_pointer_cast(aData->attribute(attributeID())); + if (aSelectionListAttr.get() == NULL) + return; + + mySelectionType = aSelectionListAttr->selectionType(); + mySelectionCount = aSelectionListAttr->size(); + + /*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())); + }*/ } //******************************************************************** -QList ModuleBase_WidgetMultiSelector::getControls() const +void ModuleBase_WidgetMultiSelector::clearAttribute() { - QList result; - //result << myTypeCombo; - result << myListControl; - return result; + DataPtr aData = myFeature->data(); + AttributeSelectionListPtr aSelectionListAttr = + std::dynamic_pointer_cast(aData->attribute(attributeID())); + aSelectionListAttr->clear(); } //******************************************************************** -bool ModuleBase_WidgetMultiSelector::eventFilter(QObject* theObj, QEvent* theEvent) +void ModuleBase_WidgetMultiSelector::setObject(ObjectPtr theSelectedObject, + GeomShapePtr theShape) { - //TODO: Remove maybe? - return ModuleBase_ModelWidget::eventFilter(theObj, theEvent); + 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::activateSelection(bool toActivate) +void ModuleBase_WidgetMultiSelector::restoreAttributeValue(bool/* theValid*/) { - myIsActive = toActivate; - if (myIsActive) { - connect(myWorkshop, SIGNAL(selectionChanged()), - this, SLOT(onSelectionChanged()), - Qt::UniqueConnection); - activateShapeSelection(); - } else { - disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); - myWorkshop->deactivateSubShapesSelection(); - - myWorkshop->viewer()->removeSelectionFilter(myEdgesTypeFilter); - } + //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); + //} + + //int aCountAppened = aSelectionListAttr->size() - mySelectionCount; + //for ( int i = 0; i < aCountAppened; i++) + // aSelectionListAttr->removeLast(); } //******************************************************************** -void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged() +bool ModuleBase_WidgetMultiSelector::setSelection(QList& theValues, + const bool theToValidate) { - activateShapeSelection(); - QObjectPtrList anEmptyList; - myWorkshop->setSelected(anEmptyList); - // Clear mySelection, myListControl and storeValue() - onSelectionChanged(); + QList aSkippedValues; + + QList::const_iterator anIt = theValues.begin(), aLast = theValues.end(); + bool isDone = false; + for (; anIt != aLast; anIt++) { + ModuleBase_ViewerPrs aValue = *anIt; + bool aProcessed = false; + 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; + } + // 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; } //******************************************************************** -void ModuleBase_WidgetMultiSelector::onSelectionChanged() +bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_ViewerPrs& thePrs) { - ModuleBase_ISelection* aSelection = myWorkshop->selection(); - NCollection_List aSelectedShapes; //, aFilteredShapes; - std::list aOwnersList; - aSelection->selectedShapes(aSelectedShapes, aOwnersList); - - mySelection.clear(); - std::list::const_iterator aIt; - NCollection_List::Iterator aShpIt(aSelectedShapes); - GeomShapePtr aShape; - for (aIt = aOwnersList.cbegin(); aIt != aOwnersList.cend(); aShpIt.Next(), aIt++) { - ResultPtr aResult = std::dynamic_pointer_cast(*aIt); - 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) - continue; } - aShape = std::shared_ptr(new GeomAPI_Shape()); - aShape->setImpl(new TopoDS_Shape(aShpIt.Value())); - mySelection.append(GeomSelection(aResult, aShape)); } - //updateSelectionList(); - emit valuesChanged(); + return aValid; } //******************************************************************** -void ModuleBase_WidgetMultiSelector::filterShapes(const NCollection_List& theShapesToFilter, - NCollection_List& theResult) +QList ModuleBase_WidgetMultiSelector::getControls() const { - if(myTypeCombo->count() == 0 || theShapesToFilter.IsEmpty()) - return; - TopAbs_ShapeEnum aReferenceType = - ModuleBase_WidgetShapeSelector::shapeType(myTypeCombo->currentText()); - NCollection_List::Iterator anIter(theShapesToFilter); - for (; anIter.More(); anIter.Next()) { - TopoDS_Shape aShape = anIter.Value(); - if (aShape.IsNull() || aShape.ShapeType() != aReferenceType) - continue; - theResult.Append(aShape); + QList result; + //result << myTypeCombo; + result << myListControl; + return result; +} + +//******************************************************************** +void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged() +{ + activateSelection(true); + activateFilters(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); + myListControl->setFocus(); +} + +//******************************************************************** +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++) { + aShapeTypes.append(ModuleBase_Tools::shapeType(myTypeCombo->itemText(i))); + } } + return aShapeTypes; } //******************************************************************** @@ -244,35 +347,45 @@ void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const TopAbs_ShapeEnum for (int idx = 0; idx < myTypeCombo->count(); ++idx) { aShapeTypeName = myTypeCombo->itemText(idx); - TopAbs_ShapeEnum aRefType = ModuleBase_WidgetShapeSelector::shapeType(aShapeTypeName); + TopAbs_ShapeEnum aRefType = ModuleBase_Tools::shapeType(aShapeTypeName); if(aRefType == theShapeType && idx != myTypeCombo->currentIndex()) { activateSelection(false); + activateFilters(false); bool isBlocked = myTypeCombo->blockSignals(true); myTypeCombo->setCurrentIndex(idx); myTypeCombo->blockSignals(isBlocked); + activateSelection(true); + activateFilters(true); break; } } } -void ModuleBase_WidgetMultiSelector::activateShapeSelection() +QList ModuleBase_WidgetMultiSelector::getAttributeSelection() const { - QString aNewType = myTypeCombo->currentText(); - QIntList aList; - aList.append(ModuleBase_WidgetShapeSelector::shapeType(aNewType)); - myWorkshop->activateSubShapesSelection(aList); - - // it is necessary to filter the selected edges to be non-degenerated - // it is not possible to build naming name for such edges - if (aNewType == "Edges") { - myEdgesTypeFilter = new ModuleBase_FilterNoDegeneratedEdge(); - ModuleBase_IViewer* aViewer = myWorkshop->viewer(); - aViewer->addSelectionFilter(myEdgesTypeFilter); - } - else { - myWorkshop->viewer()->removeSelectionFilter(myEdgesTypeFilter); + 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)); + } + } + } } + return aSelected; } //******************************************************************** @@ -283,6 +396,25 @@ void ModuleBase_WidgetMultiSelector::updateSelectionList(AttributeSelectionListP 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(); +} + +//******************************************************************** +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; } //******************************************************************** @@ -307,4 +439,3 @@ void ModuleBase_WidgetMultiSelector::onListSelection() QList aItems = myListControl->selectedItems(); myCopyAction->setEnabled(!aItems.isEmpty()); } -