X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModuleBase%2FModuleBase_WidgetMultiSelector.cpp;h=11c502778c71fce36d3cd975b53af32620064191;hb=c155919c16327dae7e09cd1e6a5b6d166e844767;hp=b3884b4966c655063793b2451e9e1f2c364ecd72;hpb=b394e9c094d25b01f1d7b9b59b218807c5be087b;p=modules%2Fshaper.git diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp old mode 100755 new mode 100644 index b3884b496..11c502778 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2019 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -12,14 +12,15 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include +#include + #include #include #include @@ -27,12 +28,16 @@ #include #include #include +#include #include #include #include +#include #include #include #include +#include +#include #include #include @@ -44,6 +49,8 @@ #include +#include + #include #include #include @@ -55,6 +62,8 @@ #include #include #include +#include +#include #include #include @@ -77,49 +86,77 @@ void printHistoryInfo(const QString& theMethodName, int theCurrentHistoryIndex, } #endif + +QStringList getIconsList(const QStringList& theNames) +{ + QStringList aIcons; + foreach (QString aName, theNames) { + QString aUName = aName.toUpper(); + if ((aUName == "VERTICES") || (aUName == "VERTEX")) + aIcons << ":pictures/vertex32.png"; + else if ((aUName == "EDGES") || (aUName == "EDGE")) + aIcons << ":pictures/edge32.png"; + else if ((aUName == "FACES") || (aUName == "FACE")) + aIcons << ":pictures/face32.png"; + else if ((aUName == "SOLIDS") || (aUName == "SOLID")) + aIcons << ":pictures/solid32.png"; + } + return aIcons; +} + +/// Stores default values of selected option (selection mode) +/// It is used only in case if myTypeCtrl is used +static QMap defaultValues; + + ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop, const Config_WidgetAPI* theData) : ModuleBase_WidgetSelector(theParent, theWorkshop, theData), - myIsSetSelectionBlocked(false), myCurrentHistoryIndex(-1) + myIsSetSelectionBlocked(false), myCurrentHistoryIndex(-1), + myIsFirst(true), myFiltersWgt(0) { - QGridLayout* aMainLay = new QGridLayout(this); - ModuleBase_Tools::adjustMargins(aMainLay); - - QLabel* aTypeLabel = new QLabel(tr("Type"), this); - aMainLay->addWidget(aTypeLabel, 0, 0); - - 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(' ', QString::SkipEmptyParts); - + myShapeTypes = aTypesStr.split(' ', QString::SkipEmptyParts); myIsUseChoice = theData->getBooleanAttribute("use_choice", false); - if (!aShapeTypes.empty()) - myTypeCombo->addItems(aShapeTypes); - aMainLay->addWidget(myTypeCombo, 0, 1); + QVBoxLayout* aMainLay = new QVBoxLayout(this); + ModuleBase_Tools::adjustMargins(aMainLay); + + QStringList aIconsList = getIconsList(myShapeTypes); + myTypeCtrl = new ModuleBase_ChoiceCtrl(this, myShapeTypes, aIconsList); + myTypeCtrl->setLabel(tr("Type")); + myTypeCtrl->setValue(0); + aMainLay->addWidget(myTypeCtrl); + myDefMode = myShapeTypes.first().toStdString(); + + // There is no sense to parameterize list of types while we can not parameterize selection mode // 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); + if (myShapeTypes.size() <= 1 || !myIsUseChoice) { + myTypeCtrl->setVisible(false); } QString aLabelText = translate(theData->getProperty("label")); - QLabel* aListLabel = new QLabel(aLabelText, 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(ModuleBase_IconFactory::loadPixmap(aLabelIcon)); - aMainLay->addWidget(aSelectedLabel, 1, 1); + if (aLabelText.size() > 0) { + QWidget* aLabelWgt = new QWidget(this); + QHBoxLayout* aLabelLayout = new QHBoxLayout(aLabelWgt); + aLabelLayout->setContentsMargins(0, 0, 0, 0); + aMainLay->addWidget(aLabelWgt); + + QLabel* aListLabel = new QLabel(aLabelText, this); + aLabelLayout->addWidget(aListLabel); + // if the xml definition contains one type, an information label + // should be shown near to the latest + if (myShapeTypes.size() <= 1) { + QString aLabelIcon = QString::fromStdString(theData->widgetIcon()); + if (!aLabelIcon.isEmpty()) { + QLabel* aSelectedLabel = new QLabel("", this); + aSelectedLabel->setPixmap(ModuleBase_IconFactory::loadPixmap(aLabelIcon)); + aLabelLayout->addWidget(aSelectedLabel); + aLabelLayout->addStretch(1); + } } - aMainLay->setColumnStretch(2, 1); } QString aToolTip = QString::fromStdString(theData->widgetTooltip()); @@ -127,15 +164,44 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen myListView = new ModuleBase_ListView(this, anObjName, aToolTip); connect(myListView->getControl(), SIGNAL(itemSelectionChanged()), SLOT(onListSelection())); connect(myListView, SIGNAL(deleteActionClicked()), SLOT(onDeleteItem())); + connect(myListView, SIGNAL(listActivated()), SLOT(onListActivated())); + + aMainLay->addWidget(myListView->getControl()); + connect(myTypeCtrl, SIGNAL(valueChanged(int)), this, SLOT(onSelectionTypeChanged())); + + std::string aUseFilters = theData->getProperty("use_filters"); + if (aUseFilters.length() > 0) { + QWidget* aFltrWgt = new QWidget(this); + QHBoxLayout* aFltrLayout = new QHBoxLayout(aFltrWgt); + + myFiltersWgt = new ModuleBase_FilterStarter(aUseFilters.c_str(), aFltrWgt, theWorkshop); + aFltrLayout->addWidget(myFiltersWgt); - aMainLay->addWidget(myListView->getControl(), 2, 0, 1, -1); - aMainLay->setRowStretch(2, 1); - //aMainLay->addWidget(new QLabel(this)); //FIXME(sbh)??? - //aMainLay->setRowMinimumHeight(3, 20); - //this->setLayout(aMainLay); - connect(myTypeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onSelectionTypeChanged())); + aFltrLayout->addStretch(); + + QPushButton* aShowBtn = new QPushButton(tr("Show only"), aFltrWgt); + connect(aShowBtn, SIGNAL(clicked(bool)), SLOT(onShowOnly())); + aFltrLayout->addWidget(aShowBtn); + + aMainLay->addWidget(aFltrWgt); + } + + bool aSameTop = theData->getBooleanAttribute("same_topology", false); + if (aSameTop) { + myGeomCheck = new QCheckBox(tr("Add elements that share the same topology"), this); + aMainLay->addWidget(myGeomCheck); + connect(myGeomCheck, SIGNAL(toggled(bool)), SLOT(onSameTopology(bool))); + } + else + myGeomCheck = 0; myIsNeutralPointClear = theData->getBooleanAttribute("clear_in_neutral_point", true); + if (myShapeTypes.size() > 1 || myIsUseChoice) { + if (defaultValues.contains(myFeatureId + attributeID())) { + myDefMode = defaultValues[myFeatureId + attributeID()]; + myTypeCtrl->setValue(myDefMode.c_str()); + } + } } ModuleBase_WidgetMultiSelector::~ModuleBase_WidgetMultiSelector() @@ -150,7 +216,6 @@ void ModuleBase_WidgetMultiSelector::activateCustom() myWorkshop->module()->activateCustomPrs(myFeature, ModuleBase_IModule::CustomizeHighlightedObjects, true); clearSelectedHistory(); - myWorkshop->updateCommandStatus(); } //******************************************************************** @@ -160,6 +225,19 @@ void ModuleBase_WidgetMultiSelector::deactivate() myWorkshop->module()->deactivateCustomPrs(ModuleBase_IModule::CustomizeHighlightedObjects, true); clearSelectedHistory(); +} + +//******************************************************************** +void ModuleBase_WidgetMultiSelector::updateAfterDeactivation() +{ + // restore previous Undo/Redo workshop state + myWorkshop->updateCommandStatus(); +} + +//******************************************************************** +void ModuleBase_WidgetMultiSelector::updateAfterActivation() +{ + // fill Undo/Redo actions with current information myWorkshop->updateCommandStatus(); } @@ -175,7 +253,12 @@ bool ModuleBase_WidgetMultiSelector::storeValueCustom() std::string aType = anAttribute->attributeType(); if (aType == ModelAPI_AttributeSelectionList::typeId()) { AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); - aSelectionListAttr->setSelectionType(myTypeCombo->currentText().toStdString()); + std::string aMode = myTypeCtrl->textValue().toStdString(); + if (myTypeCtrl->isVisible() && myIsFirst && (!myDefMode.empty())) + aMode = myDefMode; + + aSelectionListAttr->setSelectionType(aMode); + myIsFirst = false; } return true; } @@ -188,14 +271,19 @@ bool ModuleBase_WidgetMultiSelector::restoreValueCustom() return false; AttributePtr anAttribute = myFeature->data()->attribute(attributeID()); + AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); std::string aType = anAttribute->attributeType(); if (aType == ModelAPI_AttributeSelectionList::typeId()) { - AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); // Restore shape type std::string aSelectionType = aSelectionListAttr->selectionType().c_str(); - if (!aSelectionType.empty()) + if (!aSelectionType.empty()) { setCurrentShapeType(ModuleBase_Tools::shapeType(aSelectionType.c_str())); + myDefMode = aSelectionType; + myIsFirst = false; + } } + if (myGeomCheck) + myGeomCheck->setChecked(aSelectionListAttr->isGeometricalSelection()); updateSelectionList(); return true; } @@ -245,6 +333,12 @@ bool ModuleBase_WidgetMultiSelector::setSelection(QList // if there is at least one set, the result is true isDone = isDone || aProcessed; } + // Check the selection with validators + QString aError = getError(); + if (aError.length() > 0) { + aSelectionListAttr->clear(); + isDone = false; + } // updateObject - to update/redisplay feature // it is commented in order to perfom it outside the method //if (isDone) { @@ -331,19 +425,17 @@ bool ModuleBase_WidgetMultiSelector::processAction(ModuleBase_ActionType theActi } } -//******************************************************************** -void ModuleBase_WidgetMultiSelector::updateSelectionModesAndFilters(bool toActivate) -{ - myWorkshop->updateCommandStatus(); // update enable state of Undo/Redo application actions - ModuleBase_WidgetSelector::updateSelectionModesAndFilters(toActivate); -} - //******************************************************************** bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& thePrs) { bool aValid = ModuleBase_WidgetSelector::isValidSelectionCustom(thePrs); if (aValid) { ResultPtr aResult = myWorkshop->selection()->getResult(thePrs); + if (!aResult.get()) { // In case if a feature was selected + FeaturePtr aFeature = std::dynamic_pointer_cast(thePrs->object()); + if (aFeature.get()) + aResult = aFeature->firstResult(); + } aValid = aResult.get() != NULL; if (aValid) { if (myFeature) { @@ -415,14 +507,13 @@ bool ModuleBase_WidgetMultiSelector::processDelete() myListView->restoreSelection(anIndices); appendSelectionInHistory(); - return aDone; + return true/*aDone*/; // following #2438 Delete should be processed even if nothing is delete } //******************************************************************** QList ModuleBase_WidgetMultiSelector::getControls() const { QList result; - //result << myTypeCombo; result << myListView->getControl(); return result; } @@ -430,6 +521,12 @@ QList ModuleBase_WidgetMultiSelector::getControls() const //******************************************************************** void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged() { + // Clear current selection in order to avoid updating of object browser with obsolete indexes + // which can appear because of results deletetion after changing a type of selection + QString aSelectionType = myTypeCtrl->textValue(); + QList aEmptyList; + myWorkshop->setSelected(aEmptyList); + updateSelectionModesAndFilters(true); myWorkshop->selectionActivate()->updateSelectionModes(); @@ -440,7 +537,7 @@ void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged() std::string aType = anAttribute->attributeType(); if (aType == ModelAPI_AttributeSelectionList::typeId()) { AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); - aSelectionListAttr->setSelectionType(myTypeCombo->currentText().toStdString()); + aSelectionListAttr->setSelectionType(aSelectionType.toStdString()); } // clear attribute values @@ -469,6 +566,9 @@ void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged() true); /// hope that something is redisplayed by object updated // clear history should follow after set selected to do not increase history by setSelected clearSelectedHistory(); + + if (myWorkshop->propertyPanel()->activeWidget() != this) + myWorkshop->propertyPanel()->activateWidget(this); } //******************************************************************** @@ -573,12 +673,13 @@ QIntList ModuleBase_WidgetMultiSelector::shapeTypes() const { QIntList aShapeTypes; - if (myTypeCombo->count() > 1 && myIsUseChoice) { - aShapeTypes.append(ModuleBase_Tools::shapeType(myTypeCombo->currentText())); + if (myShapeTypes.length() > 1 && myIsUseChoice) { + aShapeTypes.append(ModuleBase_Tools::shapeType(myTypeCtrl->textValue())); } else { - for (int i = 0, aCount = myTypeCombo->count(); i < aCount; i++) - aShapeTypes.append(ModuleBase_Tools::shapeType(myTypeCombo->itemText(i))); + foreach (QString aType, myShapeTypes) { + aShapeTypes.append(ModuleBase_Tools::shapeType(aType)); + } } return aShapeTypes; } @@ -588,17 +689,18 @@ void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const int theShapeType) { QString aShapeTypeName; - for (int idx = 0; idx < myTypeCombo->count(); ++idx) { - aShapeTypeName = myTypeCombo->itemText(idx); + int idx = 0; + foreach (QString aShapeTypeName, myShapeTypes) { int aRefType = ModuleBase_Tools::shapeType(aShapeTypeName); - if(aRefType == theShapeType && idx != myTypeCombo->currentIndex()) { + if(aRefType == theShapeType && idx != myTypeCtrl->value()) { updateSelectionModesAndFilters(false); - bool isBlocked = myTypeCombo->blockSignals(true); - myTypeCombo->setCurrentIndex(idx); - myTypeCombo->blockSignals(isBlocked); + bool isBlocked = myTypeCtrl->blockSignals(true); + myTypeCtrl->setValue(idx); + myTypeCtrl->blockSignals(isBlocked); updateSelectionModesAndFilters(true); break; } + idx++; } } @@ -639,7 +741,7 @@ void ModuleBase_WidgetMultiSelector::updateSelectionList() AttributePtr anAttribute = aRefAttrListAttr->attribute(i); QString aName; if (anAttribute.get()) { - std::string anAttrName = generateName(anAttribute, myWorkshop); + std::string anAttrName = ModuleBase_Tools::generateName(anAttribute, myWorkshop); aName = QString::fromStdString(anAttrName); } else { @@ -723,7 +825,7 @@ void ModuleBase_WidgetMultiSelector::convertIndicesToViewerSelection(std::setvalue(i); - ResultPtr anObject = anAttr->context(); + ObjectPtr anObject = anAttr->contextObject(); if (anObject.get()) theValues.append(std::shared_ptr( new ModuleBase_ViewerPrs(anObject, anAttr->value(), NULL))); @@ -773,18 +875,23 @@ bool ModuleBase_WidgetMultiSelector::removeUnusedAttributeObjects std::string aType = anAttribute->attributeType(); std::set aShapes; std::set anIndicesToBeRemoved; + FeaturePtr aFeature; 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, - myWorkshop); - if (!aFound) - anIndicesToBeRemoved.insert(i); + //aFeature = std::dynamic_pointer_cast(anAttr->contextObject()); + //if (!aFeature.get()) { // Feature can not be found as geometry selection + bool aFound = findInSelection( + anAttr->contextObject(), anAttr->value(), aGeomSelection, myWorkshop); + if (!aFound) + anIndicesToBeRemoved.insert(i); +// } } isDone = anIndicesToBeRemoved.size() > 0; - aSelectionListAttr->remove(anIndicesToBeRemoved); + if (isDone) + aSelectionListAttr->remove(anIndicesToBeRemoved); } else if (aType == ModelAPI_AttributeRefList::typeId()) { AttributeRefListPtr aRefListAttr = aData->reflist(attributeID()); @@ -866,28 +973,52 @@ bool ModuleBase_WidgetMultiSelector::findInSelection(const ObjectPtr& theObject, const std::map >& theGeomSelection, ModuleBase_IWorkshop* theWorkshop) { + if (!theObject.get()) + return false; // issue #2154: we should not remove from list objects hidden in the viewer if selection // was done with SHIFT button if (theWorkshop->hasSHIFTPressed() && !theObject->isDisplayed()) return true; bool aFound = false; - GeomShapePtr anEmptyShape(new GeomAPI_Shape()); - if (theShape.get()) { // treat shape equal to context as null: 2219, keep order of shapes in list - const ResultPtr aContext = std::dynamic_pointer_cast(theObject); - if (aContext.get() && aContext->shape()->isEqual(theShape)) - theShape.reset(); + GeomShapePtr aShape = theShape; + if (!aShape.get()) { + // #2429 (the preselection of a sketch is not taken into account) + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + if (aResult.get()) + aShape = aResult->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()) + { + // treat shape equal to context as null: 2219, keep order of shapes in list + if (aCShape->isNull()) { // in selection, shape of result is equal to selected shape + // if so, here we need to check shape of result + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + if (aResult.get()) + aCShape = aResult->shape(); + } aFound = aCShape->isSame(aShape); + } + } + } + + // issue #2903: (Possibility to hide faces) - check whether given shape is a hidden sub-shape + if (!aFound && theShape.get() && theWorkshop->hasSHIFTPressed() && theObject->isDisplayed()) { + AISObjectPtr anAIS = theWorkshop->findPresentation(theObject); + if (anAIS.get() != NULL) { + Handle(AIS_InteractiveObject) anAISIO = anAIS->impl(); + + Handle(ModuleBase_ResultPrs) aResultPrs = Handle(ModuleBase_ResultPrs)::DownCast(anAISIO); + if (!aResultPrs.IsNull() && aResultPrs->isSubShapeHidden(theShape->impl())) + return true; } } + return aFound; } @@ -933,4 +1064,32 @@ QList } } return aList; -} \ No newline at end of file +} + + +void ModuleBase_WidgetMultiSelector::onFeatureAccepted() +{ + defaultValues[myFeatureId + attributeID()] = myDefMode; +} + +void ModuleBase_WidgetMultiSelector::onListActivated() +{ + //focusTo(); + emitFocusInWidget(); +} + +void ModuleBase_WidgetMultiSelector::onSameTopology(bool theOn) +{ + AttributePtr anAttribute = myFeature->data()->attribute(attributeID()); + std::string aType = anAttribute->attributeType(); + if (aType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); + aSelectionListAttr->setGeometricalSelection(theOn); + updateObject(myFeature); + } +} + +void ModuleBase_WidgetMultiSelector::onShowOnly() +{ + +}