X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModuleBase%2FModuleBase_WidgetMultiSelector.cpp;h=11c502778c71fce36d3cd975b53af32620064191;hb=c155919c16327dae7e09cd1e6a5b6d166e844767;hp=096adeea6f096f82110a8aa576080ace3063d6b3;hpb=7c56b92e97952849c0e9002633ed6f871783ae5c;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 096adeea6..11c502778 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp @@ -1,20 +1,43 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -/* - * ModuleBase_WidgetMultiSelector.cpp - * - * Created on: Aug 28, 2014 - * Author: sbh - */ +// 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// 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 +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #include -#include + +#include + +#include +#include +#include +#include +#include #include -#include +#include +#include #include +#include +#include +#include #include -#include -#include +#include +#include +#include +#include #include #include @@ -22,9 +45,12 @@ #include #include #include +#include #include +#include + #include #include #include @@ -32,129 +58,150 @@ #include #include #include -#include #include #include #include +#include +#include +#include #include #include -const int ATTRIBUTE_SELECTION_INDEX_ROLE = Qt::UserRole + 1; +//#define DEBUG_UNDO_REDO -/** -* Customization of a List Widget to make it to be placed on full width of container -*/ -class CustomListWidget : public QListWidget +#ifdef DEBUG_UNDO_REDO +void printHistoryInfo(const QString& theMethodName, int theCurrentHistoryIndex, + QList > > theSelectedHistoryValues) { -public: - /// Constructor - /// \param theParent a parent widget - CustomListWidget( QWidget* theParent ) - : QListWidget( theParent ) - { - } + QStringList aSizes; + for (int i = 0; i < theSelectedHistoryValues.size(); i++) + aSizes.append(QString::number(theSelectedHistoryValues[i].size())); + + std::cout << theMethodName.toStdString() + << " current = " << theCurrentHistoryIndex + << " size(history) = " << theSelectedHistoryValues.size() + << " (" << aSizes.join(", ").toStdString() << ")" + << std::endl; +} +#endif - /// 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 ); +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; -#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) : ModuleBase_WidgetSelector(theParent, theWorkshop, theData), - mySelectionCount(0) + 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); - } - - 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); + if (myShapeTypes.size() <= 1 || !myIsUseChoice) { + myTypeCtrl->setVisible(false); + } + + QString aLabelText = translate(theData->getProperty("label")); + 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()); - myListControl = new CustomListWidget(this); QString anObjName = QString::fromStdString(attributeID()); - myListControl->setObjectName(anObjName); - myListControl->setToolTip(aToolTip); - myListControl->setSelectionMode(QAbstractItemView::ExtendedSelection); + 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(myListControl, 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())); + aMainLay->addWidget(myListView->getControl()); + connect(myTypeCtrl, SIGNAL(valueChanged(int)), this, SLOT(onSelectionTypeChanged())); - myCopyAction = new QAction(QIcon(":pictures/copy.png"), tr("Copy"), this); - myCopyAction->setShortcut(QKeySequence::Copy); - myCopyAction->setEnabled(false); - connect(myCopyAction, SIGNAL(triggered(bool)), SLOT(onCopyItem())); - myListControl->addAction(myCopyAction); + std::string aUseFilters = theData->getProperty("use_filters"); + if (aUseFilters.length() > 0) { + QWidget* aFltrWgt = new QWidget(this); + QHBoxLayout* aFltrLayout = new QHBoxLayout(aFltrWgt); - myDeleteAction = new QAction(QIcon(":pictures/delete.png"), tr("Delete"), this); - myDeleteAction->setEnabled(false); - connect(myDeleteAction, SIGNAL(triggered(bool)), SLOT(onDeleteItem())); - myListControl->addAction(myDeleteAction); + myFiltersWgt = new ModuleBase_FilterStarter(aUseFilters.c_str(), aFltrWgt, theWorkshop); + aFltrLayout->addWidget(myFiltersWgt); + + aFltrLayout->addStretch(); + + QPushButton* aShowBtn = new QPushButton(tr("Show only"), aFltrWgt); + connect(aShowBtn, SIGNAL(clicked(bool)), SLOT(onShowOnly())); + aFltrLayout->addWidget(aShowBtn); + + aMainLay->addWidget(aFltrWgt); + } - myListControl->setContextMenuPolicy(Qt::ActionsContextMenu); - connect(myListControl, SIGNAL(itemSelectionChanged()), SLOT(onListSelection())); + 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() @@ -168,6 +215,7 @@ void ModuleBase_WidgetMultiSelector::activateCustom() myWorkshop->module()->activateCustomPrs(myFeature, ModuleBase_IModule::CustomizeHighlightedObjects, true); + clearSelectedHistory(); } //******************************************************************** @@ -176,13 +224,28 @@ void ModuleBase_WidgetMultiSelector::deactivate() ModuleBase_WidgetSelector::deactivate(); myWorkshop->module()->deactivateCustomPrs(ModuleBase_IModule::CustomizeHighlightedObjects, true); + clearSelectedHistory(); +} + +//******************************************************************** +void ModuleBase_WidgetMultiSelector::updateAfterDeactivation() +{ + // restore previous Undo/Redo workshop state + myWorkshop->updateCommandStatus(); } //******************************************************************** -bool ModuleBase_WidgetMultiSelector::storeValueCustom() const +void ModuleBase_WidgetMultiSelector::updateAfterActivation() { - // the value is stored on the selection changed signal processing - // A rare case when plugin was not loaded. + // fill Undo/Redo actions with current information + myWorkshop->updateCommandStatus(); +} + +//******************************************************************** +bool ModuleBase_WidgetMultiSelector::storeValueCustom() +{ + // the value is stored on the selection changed signal processing + // A rare case when plugin was not loaded. if (!myFeature) return false; @@ -190,7 +253,12 @@ bool ModuleBase_WidgetMultiSelector::storeValueCustom() const 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; } @@ -198,111 +266,79 @@ bool ModuleBase_WidgetMultiSelector::storeValueCustom() const //******************************************************************** bool ModuleBase_WidgetMultiSelector::restoreValueCustom() { - // A rare case when plugin was not loaded. + // A rare case when plugin was not loaded. if (!myFeature) 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; } //******************************************************************** -void ModuleBase_WidgetMultiSelector::storeAttributeValue() -{ - ModuleBase_WidgetValidated::storeAttributeValue(); - - DataPtr aData = myFeature->data(); - AttributePtr anAttribute = aData->attribute(attributeID()); - std::string aType = anAttribute->attributeType(); - if (aType == ModelAPI_AttributeSelectionList::typeId()) { - AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(attributeID()); - mySelectionType = aSelectionListAttr->selectionType(); - mySelectionCount = aSelectionListAttr->size(); - } - else if (aType == ModelAPI_AttributeRefList::typeId()) { - AttributeRefListPtr aRefListAttr = aData->reflist(attributeID()); - mySelectionCount = aRefListAttr->size(); - } - else if (aType == ModelAPI_AttributeRefAttrList::typeId()) { - AttributeRefAttrListPtr aRefAttrListAttr = aData->refattrlist(attributeID()); - mySelectionCount = aRefAttrListAttr->size(); - } -} - -//******************************************************************** -void ModuleBase_WidgetMultiSelector::restoreAttributeValue(bool theValid) -{ - ModuleBase_WidgetValidated::restoreAttributeValue(theValid); - - DataPtr aData = myFeature->data(); - AttributePtr anAttribute = aData->attribute(attributeID()); - std::string aType = anAttribute->attributeType(); - if (aType == ModelAPI_AttributeSelectionList::typeId()) { - AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(attributeID()); - 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 = aData->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(); - } - else if (aType == ModelAPI_AttributeRefAttrList::typeId()) { - AttributeRefAttrListPtr aRefAttrListAttr = aData->refattrlist(attributeID()); - // restore objects in the attribute. Indeed there is only one stored object - int aCountAppened = aRefAttrListAttr->size() - mySelectionCount; - for (int i = 0; i < aCountAppened; i++) - aRefAttrListAttr->removeLast(); - } -} - -//******************************************************************** -void ModuleBase_WidgetMultiSelector::setObject(ObjectPtr theObject, - GeomShapePtr theShape) -{ - DataPtr aData = myFeature->data(); - ModuleBase_Tools::setObject(aData->attribute(attributeID()), theObject, theShape, - myWorkshop, myIsInValidate); -} - -//******************************************************************** -bool ModuleBase_WidgetMultiSelector::setSelection(QList& theValues, +bool ModuleBase_WidgetMultiSelector::setSelection(QList& theValues, const bool theToValidate) { - QList aSkippedValues; + if (myIsSetSelectionBlocked) + return false; + + AttributeSelectionListPtr aSelectionListAttr; + if (attribute()->attributeType() == ModelAPI_AttributeSelectionList::typeId()) + aSelectionListAttr = std::dynamic_pointer_cast(attribute()); + if (aSelectionListAttr.get()) + aSelectionListAttr->cashValues(true); /// remove unused objects from the model attribute. /// It should be performed before new attributes append. - removeUnusedAttributeObjects(theValues); + bool isDone = removeUnusedAttributeObjects(theValues); - QList::const_iterator anIt = theValues.begin(), aLast = theValues.end(); - bool isDone = false; + QList anInvalidValues; + QList anAttributeValues; + QList::const_iterator anIt = theValues.begin(), aLast = theValues.end(); for (; anIt != aLast; anIt++) { - ModuleBase_ViewerPrs aValue = *anIt; - bool aProcessed = false; - if (!theToValidate || isValidInFilters(aValue)) { - aProcessed = setSelectionCustom(aValue); + ModuleBase_ViewerPrsPtr aValue = *anIt; + // do not validate and append to attribute selection presentation if it exists in the attribute + ObjectPtr anObject; + GeomShapePtr aShape; + getGeomSelection(aValue, anObject, aShape); + if (ModuleBase_Tools::hasObject(attribute(), anObject, aShape, myWorkshop, myIsInValidate)) { + anAttributeValues.append(aValue); + continue; } - else - aSkippedValues.append(aValue); + if (theToValidate && !isValidInFilters(aValue)) + anInvalidValues.append(aValue); + } + bool aHasInvalidValues = anInvalidValues.size() > 0; + + for (anIt = theValues.begin(); anIt != aLast; anIt++) { + ModuleBase_ViewerPrsPtr aValue = *anIt; + bool aProcessed = false; + if ((aHasInvalidValues && anInvalidValues.contains(aValue)) || + anAttributeValues.contains(aValue)) + continue; + aProcessed = setSelectionCustom(aValue); /// it is not optimal as hasObject() is already checked // 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) { @@ -311,15 +347,22 @@ bool ModuleBase_WidgetMultiSelector::setSelection(QList& t //emit valuesChanged(); //} + if (aSelectionListAttr.get()) + aSelectionListAttr->cashValues(false); + theValues.clear(); - if (!aSkippedValues.empty()) - theValues.append(aSkippedValues); + if (!anInvalidValues.empty()) + theValues.append(anInvalidValues); + + if (isDone) // may be the feature's result is not displayed, but attributes should be + myWorkshop->module()->customizeObject(myFeature, ModuleBase_IModule::CustomizeArguments, + true);/// hope that something is redisplayed by object updated return isDone; } //******************************************************************** -void ModuleBase_WidgetMultiSelector::getHighlighted(QList& theValues) +void ModuleBase_WidgetMultiSelector::getHighlighted(QList& theValues) { std::set anAttributeIds; getSelectedAttributeIndices(anAttributeIds); @@ -328,19 +371,80 @@ void ModuleBase_WidgetMultiSelector::getHighlighted(QList& } //******************************************************************** -bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_ViewerPrs& thePrs) +bool ModuleBase_WidgetMultiSelector::canProcessAction(ModuleBase_ActionType theActionType, + bool& isActionEnabled) +{ + isActionEnabled = false; + bool aCanProcess = false; + switch (theActionType) { + case ActionUndo: + case ActionRedo: { + aCanProcess = true; + isActionEnabled = theActionType == ActionUndo ? myCurrentHistoryIndex > 0 + : (mySelectedHistoryValues.size() > 0 && + myCurrentHistoryIndex < mySelectedHistoryValues.size() - 1); + } + break; + default: + aCanProcess = ModuleBase_WidgetSelector::canProcessAction(theActionType, isActionEnabled); + break; + } + return aCanProcess; +} + +//******************************************************************** +bool ModuleBase_WidgetMultiSelector::processAction(ModuleBase_ActionType theActionType, + const ActionParamPtr& theParam) +{ + switch (theActionType) { + case ActionUndo: + case ActionRedo: { + ActionIntParamPtr aParam = + std::dynamic_pointer_cast(theParam); + int aNb = aParam->value(); + if (theActionType == ActionUndo) + myCurrentHistoryIndex -= aNb; + else + myCurrentHistoryIndex += aNb; + QList aSelected = mySelectedHistoryValues[myCurrentHistoryIndex]; + // equal vertices should not be used here + ModuleBase_ISelection::filterSelectionOnEqualPoints(aSelected); + bool isDone = setSelection(aSelected, + false /*need not validate because values already was in list*/); + updateOnSelectionChanged(isDone); + + myWorkshop->updateCommandStatus(); +#ifdef DEBUG_UNDO_REDO + printHistoryInfo(QString("processAction %1").arg(theActionType == ActionUndo ? "Undo" + : "Redo"), myCurrentHistoryIndex, mySelectedHistoryValues); +#endif + return true; + } + default: + return ModuleBase_ModelWidget::processAction(theActionType, theParam); + } +} + +//******************************************************************** +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) { // We can not select a result of our feature - const std::list& aResList = myFeature->results(); + std::list aResults; + ModelAPI_Tools::allResults(myFeature, aResults); std::list::const_iterator aIt; bool isSkipSelf = false; - for (aIt = aResList.cbegin(); aIt != aResList.cend(); ++aIt) { + for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) { if ((*aIt) == aResult) { isSkipSelf = true; break; @@ -357,10 +461,14 @@ bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_Vie //******************************************************************** bool ModuleBase_WidgetMultiSelector::processDelete() { + appendFirstSelectionInHistory(); + // find attribute indices to delete std::set anAttributeIds; getSelectedAttributeIndices(anAttributeIds); + QModelIndexList anIndices = myListView->getControl()->selectionModel()->selectedIndexes(); + // refill attribute by the items which indices are not in the list of ids bool aDone = false; DataPtr aData = myFeature->data(); @@ -389,36 +497,146 @@ bool ModuleBase_WidgetMultiSelector::processDelete() restoreValue(); myWorkshop->setSelected(getAttributeSelection()); + + // may be the feature's result is not displayed, but attributes should be + myWorkshop->module()->customizeObject(myFeature, ModuleBase_IModule::CustomizeArguments, + true); /// hope that something is redisplayed by object updated } - return aDone; + + // Restore selection + myListView->restoreSelection(anIndices); + + appendSelectionInHistory(); + return true/*aDone*/; // following #2438 Delete should be processed even if nothing is delete } //******************************************************************** QList ModuleBase_WidgetMultiSelector::getControls() const { QList result; - //result << myTypeCombo; - result << myListControl; + result << myListView->getControl(); return result; } //******************************************************************** void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged() { - 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); + // 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(); + + if (!myFeature) + return; + /// store the selected type + AttributePtr anAttribute = myFeature->data()->attribute(attributeID()); + std::string aType = anAttribute->attributeType(); + if (aType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); + aSelectionListAttr->setSelectionType(aSelectionType.toStdString()); + } + + // clear attribute values + DataPtr aData = myFeature->data(); + if (aType == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(attributeID()); + aSelectionListAttr->clear(); + } + else if (aType == ModelAPI_AttributeRefList::typeId()) { + AttributeRefListPtr aRefListAttr = aData->reflist(attributeID()); + aRefListAttr->clear(); + } + else if (aType == ModelAPI_AttributeRefAttrList::typeId()) { + AttributeRefAttrListPtr aRefAttrListAttr = aData->refattrlist(attributeID()); + aRefAttrListAttr->clear(); + } + + // 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()); + // may be the feature's result is not displayed, but attributes should be + myWorkshop->module()->customizeObject(myFeature, ModuleBase_IModule::CustomizeArguments, + 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); +} + +//******************************************************************** +bool ModuleBase_WidgetMultiSelector::processSelection() +{ + if (!myIsNeutralPointClear) { + QList aSelected = getFilteredSelected(); + // do not clear selected object + if (aSelected.size() == 0) { + if (!getAttributeSelection().empty()) { + // Restore selection in the viewer by the attribute selection list + // it should be postponed to exit from the selectionChanged processing + static Events_ID anEvent = Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION); + ModelAPI_EventCreator::get()->sendUpdated(myFeature, anEvent); + Events_Loop::loop()->flush(anEvent); + return true; + } + } + } + appendFirstSelectionInHistory(); + bool aDone = ModuleBase_WidgetSelector::processSelection(); + appendSelectionInHistory(); + return aDone; +} + +void ModuleBase_WidgetMultiSelector::appendFirstSelectionInHistory() +{ + if (mySelectedHistoryValues.empty()) { + myCurrentHistoryIndex++; + mySelectedHistoryValues.append(getAttributeSelection()); + +#ifdef DEBUG_UNDO_REDO + printHistoryInfo("appendSelectionInHistory", myCurrentHistoryIndex, mySelectedHistoryValues); +#endif + } +} + +void ModuleBase_WidgetMultiSelector::appendSelectionInHistory() +{ + while (myCurrentHistoryIndex != mySelectedHistoryValues.count() - 1) + mySelectedHistoryValues.removeLast(); + + QList aSelected = getFilteredSelected(); + myCurrentHistoryIndex++; + mySelectedHistoryValues.append(aSelected); + myWorkshop->updateCommandStatus(); + +#ifdef DEBUG_UNDO_REDO + printHistoryInfo("appendSelectionInHistory", myCurrentHistoryIndex, mySelectedHistoryValues); +#endif +} + +void ModuleBase_WidgetMultiSelector::clearSelectedHistory() +{ + mySelectedHistoryValues.clear(); + myCurrentHistoryIndex = -1; + myWorkshop->updateCommandStatus(); + +#ifdef DEBUG_UNDO_REDO + printHistoryInfo("clearSelectedHistory", myCurrentHistoryIndex, mySelectedHistoryValues); +#endif } void ModuleBase_WidgetMultiSelector::updateFocus() { - // Set focus to List control in order to make possible + // 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_Tools::setFocus(myListView->getControl(), "ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()"); } @@ -428,47 +646,67 @@ void ModuleBase_WidgetMultiSelector::updateSelectionName() } //******************************************************************** -QIntList ModuleBase_WidgetMultiSelector::getShapeTypes() const +void ModuleBase_WidgetMultiSelector::updateOnSelectionChanged(const bool theDone) +{ + if (myIsSetSelectionBlocked) + return; + ModuleBase_WidgetSelector::updateOnSelectionChanged(theDone); + + // according to #2154 we need to update OB selection when selection in the viewer happens + // it is important to flush sinchronize selection signal after flush of Update/Create/Delete. + // because we need that Object Browser has been already updated when synchronize happens. + + // Restore selection in the viewer by the attribute selection list + // it is possible that diring selection attribute filling, selection in Object Browser + // is changed(some items were removed/added) and as result, selection in the viewer + // differs from the selection come to this method. By next rows, we restore selection + // in the viewer according to content of selection attribute. Case is Edge selection in Group + myIsSetSelectionBlocked = true; + static Events_ID anEvent = Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION); + ModelAPI_EventCreator::get()->sendUpdated(myFeature, anEvent); + Events_Loop::loop()->flush(anEvent); + myIsSetSelectionBlocked = false; +} + +//******************************************************************** +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++) { - TopAbs_ShapeEnum aType = ModuleBase_Tools::shapeType(myTypeCombo->itemText(i)); - aShapeTypes.append(aType); - if (aType == TopAbs_SOLID) - aShapeTypes.append(TopAbs_COMPSOLID); + foreach (QString aType, myShapeTypes) { + aShapeTypes.append(ModuleBase_Tools::shapeType(aType)); } } return aShapeTypes; } //******************************************************************** -void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const TopAbs_ShapeEnum theShapeType) +void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const int theShapeType) { QString aShapeTypeName; - - for (int idx = 0; idx < myTypeCombo->count(); ++idx) { - aShapeTypeName = myTypeCombo->itemText(idx); - TopAbs_ShapeEnum aRefType = ModuleBase_Tools::shapeType(aShapeTypeName); - if(aRefType == theShapeType && idx != myTypeCombo->currentIndex()) { - bool aWasActivated = activateSelectionAndFilters(false); - bool isBlocked = myTypeCombo->blockSignals(true); - myTypeCombo->setCurrentIndex(idx); - myTypeCombo->blockSignals(isBlocked); - if (aWasActivated) - activateSelectionAndFilters(true); + + int idx = 0; + foreach (QString aShapeTypeName, myShapeTypes) { + int aRefType = ModuleBase_Tools::shapeType(aShapeTypeName); + if(aRefType == theShapeType && idx != myTypeCtrl->value()) { + updateSelectionModesAndFilters(false); + bool isBlocked = myTypeCtrl->blockSignals(true); + myTypeCtrl->setValue(idx); + myTypeCtrl->blockSignals(isBlocked); + updateSelectionModesAndFilters(true); break; } + idx++; } } -QList ModuleBase_WidgetMultiSelector::getAttributeSelection() const +QList ModuleBase_WidgetMultiSelector::getAttributeSelection() const { - QList aSelected; + QList aSelected; convertIndicesToViewerSelection(std::set(), aSelected); return aSelected; } @@ -476,7 +714,7 @@ QList ModuleBase_WidgetMultiSelector::getAttributeSelectio //******************************************************************** void ModuleBase_WidgetMultiSelector::updateSelectionList() { - myListControl->clear(); + myListView->getControl()->clear(); DataPtr aData = myFeature->data(); AttributePtr anAttribute = aData->attribute(attributeID()); @@ -485,9 +723,7 @@ void ModuleBase_WidgetMultiSelector::updateSelectionList() 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); + myListView->addItem(aAttr->namingName().c_str(), i); } } else if (aType == ModelAPI_AttributeRefList::typeId()) { @@ -495,10 +731,7 @@ void ModuleBase_WidgetMultiSelector::updateSelectionList() 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); + myListView->addItem(anObject->data()->name().c_str(), i); } } } @@ -508,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 { @@ -517,14 +750,12 @@ void ModuleBase_WidgetMultiSelector::updateSelectionList() aName = anObject->data()->name().c_str(); } } - QListWidgetItem* anItem = new QListWidgetItem(aName, myListControl); - anItem->setData(ATTRIBUTE_SELECTION_INDEX_ROLE, i); - myListControl->addItem(anItem); + myListView->addItem(aName, i); } } // We have to call repaint because sometimes the List control is not updated - myListControl->repaint(); + myListView->getControl()->repaint(); } //******************************************************************** @@ -545,19 +776,18 @@ std::string ModuleBase_WidgetMultiSelector::validatorType(const QString& theType } //******************************************************************** -void ModuleBase_WidgetMultiSelector::onCopyItem() +void ModuleBase_WidgetMultiSelector::clearSelection() { - QList aItems = myListControl->selectedItems(); - QString aRes; - foreach(QListWidgetItem* aItem, aItems) { - if (!aRes.isEmpty()) - aRes += "\n"; - aRes += aItem->text(); - } - if (!aRes.isEmpty()) { - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(aRes); - } + bool isClearInNeutralPoint = myIsNeutralPointClear; + myIsNeutralPointClear = true; + + QList anEmptyList; + // This method will call Selection changed event which will call onSelectionChanged + // To clear mySelection, myListView and storeValue() + // So, we don't need to call it + myWorkshop->setSelected(anEmptyList); + + myIsNeutralPointClear = isClearInNeutralPoint; } //******************************************************************** @@ -569,10 +799,6 @@ void ModuleBase_WidgetMultiSelector::onDeleteItem() //******************************************************************** void ModuleBase_WidgetMultiSelector::onListSelection() { - QList aItems = myListControl->selectedItems(); - myCopyAction->setEnabled(!aItems.isEmpty()); - myDeleteAction->setEnabled(!aItems.isEmpty()); - myWorkshop->module()->customizeObject(myFeature, ModuleBase_IModule::CustomizeHighlightedObjects, true); } @@ -580,16 +806,11 @@ void ModuleBase_WidgetMultiSelector::onListSelection() //******************************************************************** 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); - } + myListView->getSelectedIndices(theAttributeIds); } void ModuleBase_WidgetMultiSelector::convertIndicesToViewerSelection(std::set theAttributeIds, - QList& theValues) const + QList& theValues) const { if(myFeature.get() == NULL) return; @@ -604,9 +825,10 @@ void ModuleBase_WidgetMultiSelector::convertIndicesToViewerSelection(std::setvalue(i); - ResultPtr anObject = anAttr->context(); + ObjectPtr anObject = anAttr->contextObject(); if (anObject.get()) - theValues.append(ModuleBase_ViewerPrs(anObject, anAttr->value(), NULL)); + theValues.append(std::shared_ptr( + new ModuleBase_ViewerPrs(anObject, anAttr->value(), NULL))); } } else if (aType == ModelAPI_AttributeRefList::typeId()) { @@ -617,7 +839,8 @@ void ModuleBase_WidgetMultiSelector::convertIndicesToViewerSelection(std::setobject(i); if (anObject.get()) { - theValues.append(ModuleBase_ViewerPrs(anObject, GeomShapePtr(), NULL)); + theValues.append(std::shared_ptr( + new ModuleBase_ViewerPrs(anObject, GeomShapePtr(), NULL))); } } } @@ -633,52 +856,65 @@ void ModuleBase_WidgetMultiSelector::convertIndicesToViewerSelection(std::setattribute(i); if (anAttribute.get()) { - GeomShapePtr aGeomShape = myWorkshop->module()->findShape(anAttribute); - theValues.append(ModuleBase_ViewerPrs(anObject, aGeomShape, NULL)); + GeomShapePtr aGeomShape = ModuleBase_Tools::getShape(anAttribute, myWorkshop); + theValues.append(std::shared_ptr( + new ModuleBase_ViewerPrs(anObject, aGeomShape, NULL))); } } } } -void ModuleBase_WidgetMultiSelector::removeUnusedAttributeObjects - (QList& theValues) +bool ModuleBase_WidgetMultiSelector::removeUnusedAttributeObjects + (QList& theValues) { + bool isDone = false; + 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; + 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); - 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); +// } } - aSelectionListAttr->remove(anIndicesToBeRemoved); + isDone = anIndicesToBeRemoved.size() > 0; + if (isDone) + 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); + bool aFound = findInSelection(anObject, GeomShapePtr(), aGeomSelection, + myWorkshop); if (!aFound) anIndicesToBeRemoved.insert(i); } } + isDone = anIndicesToBeRemoved.size() > 0; aRefListAttr->remove(anIndicesToBeRemoved); } else if (aType == ModelAPI_AttributeRefAttrList::typeId()) { std::set anAttributes; - QList::const_iterator anIt = theValues.begin(), aLast = theValues.end(); + QList::const_iterator + anIt = theValues.begin(), aLast = theValues.end(); ObjectPtr anObject; GeomShapePtr aShape; for (; anIt != aLast; anIt++) { - ModuleBase_ViewerPrs aPrs = *anIt; + ModuleBase_ViewerPrsPtr aPrs = *anIt; getGeomSelection(aPrs, anObject, aShape); AttributePtr anAttr = myWorkshop->module()->findAttribute(anObject, aShape); if (anAttr.get() && anAttributes.find(anAttr) == anAttributes.end()) @@ -693,27 +929,31 @@ void ModuleBase_WidgetMultiSelector::removeUnusedAttributeObjects aFound = anAttributes.find(anAttribute) != anAttributes.end(); } else { - aFound = findInSelection(aRefAttrListAttr->object(i), GeomShapePtr(), aGeomSelection); + aFound = findInSelection(aRefAttrListAttr->object(i), GeomShapePtr(), aGeomSelection, + myWorkshop); } if (!aFound) anIndicesToBeRemoved.insert(i); } + isDone = anIndicesToBeRemoved.size() > 0; aRefAttrListAttr->remove(anIndicesToBeRemoved); } + + return isDone; } std::map > ModuleBase_WidgetMultiSelector::convertSelection - (QList& theValues) + (QList& theValues) { // convert prs list to objects map std::map > aGeomSelection; std::set aShapes; - QList::const_iterator anIt = theValues.begin(), aLast = theValues.end(); + QList::const_iterator anIt = theValues.begin(), aLast = theValues.end(); ObjectPtr anObject; GeomShapePtr aShape; GeomShapePtr anEmptyShape(new GeomAPI_Shape()); for (; anIt != aLast; anIt++) { - ModuleBase_ViewerPrs aPrs = *anIt; + ModuleBase_ViewerPrsPtr aPrs = *anIt; getGeomSelection(aPrs, anObject, aShape); aShapes.clear(); if (aGeomSelection.find(anObject) != aGeomSelection.end()) // found @@ -729,20 +969,127 @@ std::map > ModuleBase_WidgetMultiSelector::con } bool ModuleBase_WidgetMultiSelector::findInSelection(const ObjectPtr& theObject, - const GeomShapePtr& theShape, - const std::map >& theGeomSelection) + GeomShapePtr theShape, + 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()); - GeomShapePtr aShape = theShape.get() ? theShape : anEmptyShape; + 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(); + } 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); + { + // 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; } + +QList + ModuleBase_WidgetMultiSelector::actionsList(ModuleBase_ActionType theActionType) const +{ + QList aList; + if (myCurrentHistoryIndex > -1) { + int i = 0; + QString aTitle("Selection %1 items"); + QString aTit("Selection %1 item"); + QIcon aIcon(":pictures/selection.png"); + int aNb; + switch (theActionType) { + case ActionUndo: + i = 1; + while (i <= myCurrentHistoryIndex) { + aNb = mySelectedHistoryValues.at(i).count(); + if (aNb == 1) { + ActionInfo aInfo(aIcon, aTit.arg(aNb)); + aList.insert(0, aInfo); + } else { + ActionInfo aInfo(aIcon, aTitle.arg(aNb)); + aList.insert(0, aInfo); + } + i++; + } + break; + case ActionRedo: + i = mySelectedHistoryValues.length() - 1; + while (i > myCurrentHistoryIndex) { + aNb = mySelectedHistoryValues.at(i).count(); + if (aNb == 1) { + ActionInfo aInfo(aIcon, aTit.arg(mySelectedHistoryValues.at(i).count())); + aList.insert(0, aInfo); + } else { + ActionInfo aInfo(aIcon, aTitle.arg(mySelectedHistoryValues.at(i).count())); + aList.insert(0, aInfo); + } + i--; + } + break; + } + } + return aList; +} + + +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() +{ + +}