X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModuleBase%2FModuleBase_WidgetSelectionFilter.cpp;h=acfc5c633872fb86afd492e0c2ba19a153602538;hb=536461be8f9286797d416753e6bf137ea4d97f1c;hp=24e2783cd454a67ad7d3c434fcebab33c0a6fbce;hpb=13c2f8cf7ae73ffca8385e94526825aea23c8bd6;p=modules%2Fshaper.git diff --git a/src/ModuleBase/ModuleBase_WidgetSelectionFilter.cpp b/src/ModuleBase/ModuleBase_WidgetSelectionFilter.cpp index 24e2783cd..acfc5c633 100644 --- a/src/ModuleBase/ModuleBase_WidgetSelectionFilter.cpp +++ b/src/ModuleBase/ModuleBase_WidgetSelectionFilter.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2019 CEA/DEN, EDF R&D +// Copyright (C) 2014-2021 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 @@ -32,7 +32,11 @@ #include #include #include +#include +#include + #include +#include #include #include @@ -41,6 +45,7 @@ #include #include #include +#include #include #include @@ -50,9 +55,10 @@ #include #include #include +#include -static FeaturePtr SelectorFeature; -static std::string AttributeId; +FeaturePtr ModuleBase_WidgetSelectionFilter::SelectorFeature; +std::string ModuleBase_WidgetSelectionFilter::AttributeId; GeomAPI_Shape::ShapeType selectionType(const QString& theType) @@ -89,25 +95,17 @@ ModuleBase_FilterStarter::ModuleBase_FilterStarter(const std::string& theFeature ModuleBase_Tools::adjustMargins(aMainLayout); aMainLayout->addStretch(1); - QPushButton* aLaunchBtn = new QPushButton(tr("Selection by filters"), this); + QPushButton* aLaunchBtn = new QPushButton( + ModuleBase_Tools::translate("FiltersSelection", "Selection by filters"), this); connect(aLaunchBtn, SIGNAL(clicked()), SLOT(onFiltersLaunch())); aMainLayout->addWidget(aLaunchBtn); - - myFilterLbl = new QLabel(this); - myFilterLbl->setPixmap(QPixmap(":pictures/filter.png")); - aMainLayout->addWidget(myFilterLbl); - - myModifyLbl = new QLabel(this); - myModifyLbl->setPixmap(QPixmap(":pictures/plus_minus.png")); - aMainLayout->addWidget(myModifyLbl); - aMainLayout->addStretch(1); - - myFilterLbl->hide(); - myModifyLbl->hide(); } void ModuleBase_FilterStarter::onFiltersLaunch() { + static QString aHelpFileName = QString("FiltersPlugin") + QDir::separator() + + QString("FiltersPlugin.html"); + ModuleBase_Operation* aParentOp = myWorkshop->currentOperation(); ModuleBase_OperationFeature* aFeatureOp = dynamic_cast(aParentOp); if (aFeatureOp) @@ -123,12 +121,20 @@ void ModuleBase_FilterStarter::onFiltersLaunch() } if (!aSelector) return; - SelectorFeature = aSelector->feature(); - AttributeId = aSelector->attributeID(); + ModuleBase_WidgetSelectionFilter::SelectorFeature = aSelector->feature(); + ModuleBase_WidgetSelectionFilter::AttributeId = aSelector->attributeID(); // Launch Filters operation ModuleBase_OperationFeature* aFOperation = dynamic_cast (myWorkshop->module()->createOperation(myFeatureName)); + + AttributeSelectionListPtr aAttrList = + ModuleBase_WidgetSelectionFilter::SelectorFeature->selectionList( + ModuleBase_WidgetSelectionFilter::AttributeId); + FiltersFeaturePtr aFilters = aAttrList->filters(); + if (aFilters.get()) + aFOperation->setFeature(aFilters); + aFOperation->setHelpFileName(aHelpFileName); myWorkshop->processLaunchOperation(aFOperation); } @@ -140,11 +146,17 @@ ModuleBase_FilterItem::ModuleBase_FilterItem( : QWidget(theParent->filtersWidget()), myFilterID(theFilter), mySelection(std::dynamic_pointer_cast(theParent->feature())) { - std::string aXmlString = ModelAPI_Session::get()->filters()->filter(theFilter)->xmlRepresentation(); + FilterPtr aFilter = ModelAPI_Session::get()->filters()->filter(theFilter); + std::string aXmlString = aFilter->xmlRepresentation(); if (aXmlString.length() == 0) addItemRow(this); else { - ModuleBase_WidgetFactory aFactory(aXmlString, theParent->workshop()); + std::string anAttrPrefix; // this must be added to the attributes names for multiple filters + std::string aFilterKind = ModelAPI_Session::get()->filters()->id(aFilter); + if (theFilter != aFilterKind) { + anAttrPrefix = theFilter.substr(0, theFilter.size() - aFilterKind.size()); + } + ModuleBase_WidgetFactory aFactory(aXmlString, theParent->workshop(), anAttrPrefix); Config_ValidatorReader aValidatorReader(aXmlString, true); aValidatorReader.setFeatureId(mySelection->getKind()); aValidatorReader.readAll(); @@ -167,6 +179,8 @@ ModuleBase_FilterItem::ModuleBase_FilterItem( theParent, SIGNAL(focusInWidget(ModuleBase_ModelWidget*))); connect(aWidget, SIGNAL(focusOutWidget(ModuleBase_ModelWidget*)), theParent, SIGNAL(focusOutWidget(ModuleBase_ModelWidget*))); + connect(aWidget, SIGNAL(objectUpdated()), theParent, SLOT(onObjectUpdated())); + aWidget->enableFocusProcessing(); } aLayout->addWidget(aParamsWgt); } @@ -174,26 +188,31 @@ ModuleBase_FilterItem::ModuleBase_FilterItem( void ModuleBase_FilterItem::addItemRow(QWidget* theParent) { + std::string aContext = mySelection->getKind(); QHBoxLayout* aLayout = new QHBoxLayout(theParent); ModuleBase_Tools::zeroMargins(aLayout); // Reverse filter button myRevBtn = new QToolButton(theParent); myRevBtn->setCheckable(true); - myRevBtn->setChecked(false); + bool isReversed = mySelection->isReversed(myFilterID); + myRevBtn->setChecked(isReversed); myRevBtn->setAutoRaise(true); - myRevBtn->setIcon(QIcon(":pictures/add.png")); - myRevBtn->setToolTip(tr("Reverse the filter")); + if (isReversed) + myRevBtn->setIcon(QIcon(":pictures/reverce.png")); + else + myRevBtn->setIcon(QIcon(":pictures/add.png")); + myRevBtn->setToolTip(ModuleBase_Tools::translate(aContext, "Reverse the filter")); connect(myRevBtn, SIGNAL(toggled(bool)), SLOT(onReverse(bool))); aLayout->addWidget(myRevBtn); const std::string& aFilterName = ModelAPI_Session::get()->filters()->filter(myFilterID)->name(); - aLayout->addWidget(new QLabel(aFilterName.c_str(), theParent), 1); + aLayout->addWidget(new QLabel(ModuleBase_Tools::translate(aContext, aFilterName), theParent), 1); QToolButton* aDelBtn = new QToolButton(theParent); aDelBtn->setIcon(QIcon(":pictures/delete.png")); aDelBtn->setAutoRaise(true); - aDelBtn->setToolTip(tr("Delete the filter")); + aDelBtn->setToolTip(ModuleBase_Tools::translate(aContext, "Delete the filter")); connect(aDelBtn, SIGNAL(clicked(bool)), SLOT(onDelete())); aLayout->addWidget(aDelBtn); } @@ -213,41 +232,29 @@ void ModuleBase_FilterItem::onDelete() emit deleteItem(this); } -QList ModuleBase_FilterItem::getControls() const -{ - QList aWidgetsList; - foreach(ModuleBase_ModelWidget* aWgt, myWidgets) { - QList aSubList = aWgt->getControls(); - foreach(QWidget* aSub, aSubList) { - aWidgetsList.append(aSub); - } - } - return aWidgetsList; -} - //***************************************************************************** //***************************************************************************** //***************************************************************************** ModuleBase_WidgetSelectionFilter::ModuleBase_WidgetSelectionFilter(QWidget* theParent, - ModuleBase_IWorkshop* theWorkshop, const Config_WidgetAPI* theData) + ModuleBase_IWorkshop* theWorkshop, const Config_WidgetAPI* theData, bool theReadOnly) : ModuleBase_ModelWidget(theParent, theData), myWorkshop(theWorkshop), - mySelectorFeature(SelectorFeature), - mySelectorAttribute(AttributeId) + mySelectorFeature(ModuleBase_WidgetSelectionFilter::SelectorFeature), + mySelectorAttribute(ModuleBase_WidgetSelectionFilter::AttributeId) { // Clear Old selection - AttributePtr aAttr = SelectorFeature->attribute(AttributeId); - AttributeSelectionListPtr aSelListAttr = - std::dynamic_pointer_cast(aAttr); - mySelectionType = selectionType(aSelListAttr->selectionType().c_str()); - aSelListAttr->clear(); + AttributeSelectionListPtr aAttrList = mySelectorFeature->selectionList(mySelectorAttribute); + mySelectionType = selectionType(aAttrList->selectionType().c_str()); + if (!theReadOnly) { + aAttrList->clear(); + } // Define widgets QVBoxLayout* aMainLayout = new QVBoxLayout(this); ModuleBase_Tools::adjustMargins(aMainLayout); - QGroupBox* aFiltersGroup = new QGroupBox(tr("Filters"), this); + QGroupBox* aFiltersGroup = new QGroupBox(translate("Filters"), this); QVBoxLayout* aGroupLayout = new QVBoxLayout(aFiltersGroup); aGroupLayout->setContentsMargins(0, 0, 0, 0); aGroupLayout->setSpacing(0); @@ -258,15 +265,15 @@ ModuleBase_WidgetSelectionFilter::ModuleBase_WidgetSelectionFilter(QWidget* theP aGroupLayout->addWidget(myFiltersWgt); myFiltersCombo = new QComboBox(aFiltersGroup); - myFiltersCombo->addItem(tr("Add new filter...")); + myFiltersCombo->addItem(translate("Add new filter...")); SessionPtr aSession = ModelAPI_Session::get(); std::list allFilters = aSession->filters()->filters((GeomAPI_Shape::ShapeType) mySelectionType); + storeFilters(allFilters); QStringList aItems; std::list::const_iterator aIt; for (aIt = allFilters.cbegin(); aIt != allFilters.cend(); aIt++) { - aItems.push_back((*aIt)->name().c_str()); - myFilters.push_back(aSession->filters()->id(*aIt)); + aItems.push_back(translate((*aIt)->name().c_str())); } myFiltersCombo->addItems(aItems); connect(myFiltersCombo, SIGNAL(currentIndexChanged(int)), SLOT(onAddFilter(int))); @@ -281,7 +288,7 @@ ModuleBase_WidgetSelectionFilter::ModuleBase_WidgetSelectionFilter(QWidget* theP aBtnLayout->addStretch(1); - mySelectBtn = new QPushButton(tr("Select"), aBtnWgt); + mySelectBtn = new QPushButton(translate("Select"), aBtnWgt); connect(mySelectBtn, SIGNAL(clicked()), SLOT(onSelect())); aBtnLayout->addWidget(mySelectBtn); @@ -292,13 +299,13 @@ ModuleBase_WidgetSelectionFilter::ModuleBase_WidgetSelectionFilter(QWidget* theP QHBoxLayout* aLblLayout = new QHBoxLayout(aLblWgt); ModuleBase_Tools::zeroMargins(aLblLayout); - aLblLayout->addWidget(new QLabel(tr("Number of selected objects:"), aLblWgt)); + aLblLayout->addWidget(new QLabel(translate("Number of selected objects:"), aLblWgt)); myNbLbl = new QLabel("0", aLblWgt); aLblLayout->addWidget(myNbLbl); // Show only button - myShowBtn = new QCheckBox(tr("Show only"), this); + myShowBtn = new QCheckBox(translate("Show only"), this); connect(myShowBtn, SIGNAL(toggled(bool)), SLOT(onShowOnly(bool))); aLblLayout->addWidget(myShowBtn); @@ -307,6 +314,12 @@ ModuleBase_WidgetSelectionFilter::ModuleBase_WidgetSelectionFilter(QWidget* theP aMainLayout->addStretch(1); updateSelectBtn(); + if (theReadOnly) { + myFiltersCombo->hide(); + mySelectBtn->hide(); + aLblWgt->hide(); + myShowBtn->hide(); + } } ModuleBase_WidgetSelectionFilter::~ModuleBase_WidgetSelectionFilter() @@ -316,17 +329,23 @@ ModuleBase_WidgetSelectionFilter::~ModuleBase_WidgetSelectionFilter() Handle(AIS_InteractiveContext) aCtx = myWorkshop->viewer()->AISContext(); aCtx->Remove(myPreview, false); myPreview.Nullify(); - if (myShowBtn->isChecked()) { + if (myListIO.Size() > 0) { + aCtx = myWorkshop->viewer()->AISContext(); AIS_ListOfInteractive::const_iterator aIt; Handle(AIS_Shape) aShapeIO; for (aIt = myListIO.cbegin(); aIt != myListIO.cend(); aIt++) { aShapeIO = Handle(AIS_Shape)::DownCast(*aIt); if (!aShapeIO.IsNull()) { aCtx->Display(aShapeIO, false); + std::shared_ptr anAISObj = AISObjectPtr(new GeomAPI_AISObject()); + anAISObj->setImpl(new Handle(AIS_InteractiveObject)(aShapeIO)); + myWorkshop->applyCurrentSelectionModes(anAISObj); } } + myListIO.Clear(); + myShowBtn->setChecked(false); } - aCtx->UpdateCurrentViewer(); + myWorkshop->viewer()->update(); } SelectorFeature = FeaturePtr(); AttributeId = ""; @@ -337,34 +356,48 @@ void ModuleBase_WidgetSelectionFilter::onAddFilter(int theIndex) if (theIndex == 0) return; - std::list::iterator aIt; - int i; + ModelAPI_FiltersFactory* aFactory = ModelAPI_Session::get()->filters(); + FiltersFeaturePtr aFiltersFeature = + std::dynamic_pointer_cast(myFeature); + + std::string aText = myFiltersCombo->itemText(theIndex).toStdString(); + + std::list::iterator aIt; std::string aFilter; - for (aIt = myFilters.begin(), i = 0; aIt != myFilters.cend(); i++, aIt++) { - if (i == (theIndex - 1)) { - aFilter = (*aIt); - myFilters.erase(aIt); - break; - } - } - if (!aFilter.empty()) { - myUseFilters.push_back(aFilter); - ModuleBase_FilterItem* aItem = new ModuleBase_FilterItem(aFilter, this); - connect(aItem, SIGNAL(deleteItem(ModuleBase_FilterItem*)), - SLOT(onDeleteItem(ModuleBase_FilterItem*))); - connect(aItem, SIGNAL(reversedItem(ModuleBase_FilterItem*)), - SLOT(onReverseItem(ModuleBase_FilterItem*))); - myFiltersLayout->addWidget(aItem); - - FiltersFeaturePtr aFiltersFeature = - std::dynamic_pointer_cast(myFeature); - aFiltersFeature->addFilter(aFilter); + std::map::const_iterator aFound = myFilters.find(aText); + if (aFound == myFilters.end()) { + std::list aFilters = aFactory->filters((GeomAPI_Shape::ShapeType) mySelectionType); + storeFilters(aFilters); + aFound = myFilters.find(aText); } + if (aFound != myFilters.end()) + aFilter = aFactory->id(aFound->second); + + aFiltersFeature->addFilter(aFilter); + updateObject(myFeature); + + QList aList = itemsList(); + if (!aList.isEmpty() && (aList.last()->widgets().size() > 0)) + aList.last()->widgets().first()->emitFocusInWidget(); + else + emitFocusInWidget(); +} + +ModuleBase_FilterItem* ModuleBase_WidgetSelectionFilter::onAddFilter(const std::string& theFilter) +{ + if (theFilter.length() == 0) + return 0; + ModuleBase_FilterItem* aItem = new ModuleBase_FilterItem(theFilter, this); + connect(aItem, SIGNAL(deleteItem(ModuleBase_FilterItem*)), + SLOT(onDeleteItem(ModuleBase_FilterItem*))); + connect(aItem, SIGNAL(reversedItem(ModuleBase_FilterItem*)), + SLOT(onReverseItem(ModuleBase_FilterItem*))); + myFiltersLayout->addWidget(aItem); + updateSelectBtn(); clearCurrentSelection(true); updateNumberSelected(); - myFiltersCombo->setCurrentIndex(0); - myFiltersCombo->removeItem(theIndex); + return aItem; } void ModuleBase_WidgetSelectionFilter::onDeleteItem(ModuleBase_FilterItem* theItem) @@ -377,10 +410,11 @@ void ModuleBase_WidgetSelectionFilter::onDeleteItem(ModuleBase_FilterItem* theIt myFiltersLayout->removeWidget(theItem); theItem->deleteLater(); - myUseFilters.remove(aFilter); - myFilters.push_back(aFilter); - myFiltersCombo->addItem(ModelAPI_Session::get()->filters()->filter(aFilter)->name().c_str()); - + ModelAPI_FiltersFactory* aFactory = ModelAPI_Session::get()->filters(); + if (!aFactory->filter(aFilter)->isMultiple()) { + //myFilters.push_back(aFilter); + myFiltersCombo->addItem(ModelAPI_Session::get()->filters()->filter(aFilter)->name().c_str()); + } FiltersFeaturePtr aFiltersFeature = std::dynamic_pointer_cast(myFeature); aFiltersFeature->removeFilter(aFilter); @@ -393,6 +427,8 @@ void ModuleBase_WidgetSelectionFilter::onDeleteItem(ModuleBase_FilterItem* theIt myWorkshop->selectionActivate()->updateSelectionModes(); myWorkshop->selectionActivate()->updateSelectionFilters(); redisplayFeature(); + emitFocusInWidget(); + updateObject(myFeature); } @@ -412,8 +448,6 @@ void ModuleBase_WidgetSelectionFilter::onReverseItem(ModuleBase_FilterItem* theI void ModuleBase_WidgetSelectionFilter::onSelect() { - if (myUseFilters.size() == 0) - return; Handle(AIS_InteractiveContext) aCtx = myWorkshop->viewer()->AISContext(); if (aCtx.IsNull()) return; @@ -424,40 +458,63 @@ void ModuleBase_WidgetSelectionFilter::onSelect() TopoDS_Compound aComp; aBuilder.MakeCompound(aComp); - if (!myShowBtn->isChecked()) { - myListIO.Clear(); - aCtx->DisplayedObjects(AIS_KOI_Shape, -1, myListIO); - if (!myPreview.IsNull()) - myListIO.Remove(myPreview); - } - AIS_ListOfInteractive::const_iterator aIt; - Handle(ModuleBase_ResultPrs) aShapeIO; - for (aIt = myListIO.cbegin(); aIt != myListIO.cend(); aIt++) { - aShapeIO = Handle(ModuleBase_ResultPrs)::DownCast(*aIt); - if (!aShapeIO.IsNull()) { - GeomShapePtr aShape(new GeomAPI_Shape); - aShape->setImpl(new TopoDS_Shape(aShapeIO->Shape())); - std::list aSubShapes = - aShape->subShapes((GeomAPI_Shape::ShapeType)mySelectionType); - std::list::const_iterator aShapesIt; - for (aShapesIt = aSubShapes.cbegin(); aShapesIt != aSubShapes.cend(); aShapesIt++) { - GeomShapePtr aShape = (*aShapesIt); - SessionPtr aSession = ModelAPI_Session::get(); - bool isValid = aSession->filters()->isValid(myFeature, aShape); - if (isValid) { - TopoDS_Shape aTShape = aShape->impl(); - Handle(StdSelect_BRepOwner) aOwner = new StdSelect_BRepOwner(aTShape, aShapeIO, true); - aBuilder.Add(aComp, aTShape); - - ModuleBase_ViewerPrsPtr aValue(new ModuleBase_ViewerPrs(aShapeIO->getResult(), aShape, aOwner)); - myValues.append(aValue); + DocumentPtr aDoc = myFeature->document(); + int aNb = aDoc->size(ModelAPI_ResultBody::group()); + ObjectPtr aObj; + ResultBodyPtr aBody; + for (int i = 0; i < aNb; i++) { + aObj = aDoc->object(ModelAPI_ResultBody::group(), i); + aBody = std::dynamic_pointer_cast(aObj); + GeomShapePtr aShape = aBody->shape(); + std::list aSubShapes = + aShape->subShapes((GeomAPI_Shape::ShapeType)mySelectionType); + TopTools_MapOfShape alreadyThere; + std::list::const_iterator aShapesIt; + for (aShapesIt = aSubShapes.cbegin(); aShapesIt != aSubShapes.cend(); aShapesIt++) { + GeomShapePtr aSubShape = (*aShapesIt); + TopoDS_Shape aTShape = aSubShape->impl(); + if (!alreadyThere.Add(aTShape)) + continue; + + // degenerated edge is not valid selection + if ((GeomAPI_Shape::ShapeType)mySelectionType == GeomAPI_Shape::EDGE) + if (aSubShape->edge()->isDegenerated()) + continue; + + static SessionPtr aSession = ModelAPI_Session::get(); + bool isValid = aSession->filters()->isValid(myFeature, aBody, aSubShape); + + if (isValid) { + aBuilder.Add(aComp, aTShape); + // bos #24043: Naming on a compsolid works wrong. + // Find a simple sub-result for the ViewerPrs context: + ResultBodyPtr aContext = aBody; + bool isComposite = aContext->numberOfSubs() > 0; + while (isComposite) { + isComposite = false; + int nbSubs = aContext->numberOfSubs(); + for (int aSubIndex = 0; aSubIndex < nbSubs; aSubIndex++) { + ResultBodyPtr aSubResult = aContext->subResult(aSubIndex); + GeomShapePtr aSubResultShape = aSubResult->shape(); + if (aSubResultShape->isSubShape(aSubShape)) { + aContext = aSubResult; + isComposite = aContext->numberOfSubs() > 0; + break; + } + } } + ModuleBase_ViewerPrsPtr aValue(new ModuleBase_ViewerPrs(aContext, aSubShape)); + //ModuleBase_ViewerPrsPtr aValue(new ModuleBase_ViewerPrs(aObj, aSubShape)); + myValues.append(aValue); } } } + if (myValues.size() > 0) updatePreview(aComp); updateNumberSelected(); + updateObject(myFeature); + onShowOnly(myShowBtn->isChecked()); } void ModuleBase_WidgetSelectionFilter::updatePreview(const TopoDS_Shape& theShape) @@ -468,9 +525,16 @@ void ModuleBase_WidgetSelectionFilter::updatePreview(const TopoDS_Shape& theShap if (myPreview.IsNull()) { myPreview = new AIS_Shape(theShape); - //myPreview->SetDisplayMode(myShowBtn->isChecked()? AIS_Shaded : AIS_WireFrame); myPreview->SetDisplayMode(AIS_Shaded); myPreview->SetColor(Quantity_NOC_BLUE1); + Handle(Prs3d_Drawer) aDrawer = myPreview->Attributes(); + if (aDrawer->HasOwnPointAspect()) { + aDrawer->PointAspect()->SetTypeOfMarker(Aspect_TOM_O_STAR); + aDrawer->PointAspect()->SetColor(Quantity_NOC_BLUE1); + aDrawer->PointAspect()->SetScale(2.); + } + else + aDrawer->SetPointAspect(new Prs3d_PointAspect(Aspect_TOM_O_STAR, Quantity_NOC_BLUE1, 2.)); myPreview->SetTransparency(); aCtx->Display(myPreview, true); aCtx->Deactivate(myPreview); @@ -484,48 +548,69 @@ void ModuleBase_WidgetSelectionFilter::updatePreview(const TopoDS_Shape& theShap void ModuleBase_WidgetSelectionFilter::onShowOnly(bool theShow) { - if (myPreview.IsNull()) - return; Handle(AIS_InteractiveContext) aCtx = myWorkshop->viewer()->AISContext(); - if (theShow) { - myListIO.Clear(); - aCtx->DisplayedObjects(AIS_KOI_Shape, -1, myListIO); - myListIO.Remove(myPreview); + AIS_ListOfInteractive aList; + aCtx->DisplayedObjects(AIS_KOI_Shape, -1, aList); + if (!myPreview.IsNull()) + aList.Remove(myPreview); + if (aList.Size() > 0) + myListIO = aList; } AIS_ListOfInteractive::const_iterator aIt; Handle(AIS_Shape) aShapeIO; + bool isModified = false; for (aIt = myListIO.cbegin(); aIt != myListIO.cend(); aIt++) { aShapeIO = Handle(AIS_Shape)::DownCast(*aIt); if (!aShapeIO.IsNull()) { - if (theShow) - aCtx->Erase(aShapeIO, false); - else - aCtx->Display(aShapeIO, false); + if (theShow) { + if (aCtx->IsDisplayed(aShapeIO)) { + aCtx->Erase(aShapeIO, false); + isModified = true; + } + } + else { + if (!aCtx->IsDisplayed(aShapeIO)) { + aCtx->Display(aShapeIO, false); + std::shared_ptr anAISObj = AISObjectPtr(new GeomAPI_AISObject()); + anAISObj->setImpl(new Handle(AIS_InteractiveObject)(aShapeIO)); + myWorkshop->applyCurrentSelectionModes(anAISObj); + isModified = true; + } + } } } - aCtx->UpdateCurrentViewer(); + if (isModified) + myWorkshop->viewer()->update(); } void ModuleBase_WidgetSelectionFilter::updateSelectBtn() { - mySelectBtn->setEnabled(myUseFilters.size() > 0); + FiltersFeaturePtr aFiltersFeature = std::dynamic_pointer_cast(myFeature); + mySelectBtn->setEnabled(aFiltersFeature.get() && (aFiltersFeature->filters().size() > 0)); } void ModuleBase_WidgetSelectionFilter::updateNumberSelected() { - myNbLbl->setText(QString::number(myValues.size())); + int aNb = myValues.size(); + myNbLbl->setText(QString::number(aNb)); + if (aNb == 0) { + myFeature->setError(translate("Selection is empty").toStdString(), false, false); + myShowBtn->setChecked(false); + onShowOnly(false); + myShowBtn->setEnabled(false); + } + else { + myFeature->setError("", false, false); + myFeature->data()->execState(ModelAPI_StateDone); + myShowBtn->setEnabled(true); + } } + QList ModuleBase_WidgetSelectionFilter::getControls() const { QList aWidgets; - QList aItems = myFiltersWgt->findChildren(); - foreach(ModuleBase_FilterItem* aItem, aItems) { - QList aSubList = aItem->getControls(); - foreach(QWidget* aWgt, aSubList) { - aWidgets.append(aWgt); - } - } + aWidgets.append(myFiltersCombo); return aWidgets; } @@ -539,12 +624,60 @@ void ModuleBase_WidgetSelectionFilter::clearCurrentSelection(bool toUpdate) } } +void replaceSubShapesByResult(QList& theResults, int theShapeType) +{ + QMap> myResShapes; + // Sort sub-shapes by result + foreach (ModuleBase_ViewerPrsPtr aPrs, theResults) { + if (myResShapes.contains(aPrs->object())) + myResShapes[aPrs->object()].append(aPrs->shape()); + else { + QList aShapes; + aShapes << aPrs->shape(); + myResShapes[aPrs->object()] = aShapes; + } + } + // Find Results to replace by whole result + QList aShapes; + QList aToReplace; + std::list aSubShapes; + foreach(ObjectPtr aObj, myResShapes.keys()) { + aShapes = myResShapes[aObj]; + ResultPtr aRes = std::dynamic_pointer_cast(aObj); + TopTools_MapOfShape aShapesMap; + if (aRes.get()) { + GeomShapePtr aSubShape = aRes->shape(); + const TopoDS_Shape& aShape = aSubShape->impl(); + for (TopExp_Explorer anExp(aShape, (TopAbs_ShapeEnum)theShapeType); + anExp.More(); anExp.Next()) { + aShapesMap.Add(anExp.Current()); + } + } + if (aShapes.count() == aShapesMap.Size()) + aToReplace.append(aObj); + } + // Replace the found results + QList::iterator aIt; + foreach(ObjectPtr aObj, aToReplace) { + for (aIt = theResults.begin(); aIt != theResults.end(); aIt++) { + if ((*aIt)->object() == aObj) { + theResults.removeAll(*aIt); + aIt--; + } + } + ModuleBase_ViewerPrsPtr aValue(new ModuleBase_ViewerPrs(aObj)); + theResults.append(aValue); + } +} + void ModuleBase_WidgetSelectionFilter::onFeatureAccepted() { AttributePtr aAttr = mySelectorFeature->attribute(mySelectorAttribute); AttributeSelectionListPtr aSelListAttr = std::dynamic_pointer_cast(aAttr); aSelListAttr->clear(); + if (aSelListAttr->isWholeResultAllowed()) + replaceSubShapesByResult(myValues, selectionType(aSelListAttr->selectionType().c_str())); foreach(ModuleBase_ViewerPrsPtr aPrs, myValues) { aSelListAttr->append(aPrs->object(), aPrs->shape()); } @@ -552,13 +685,103 @@ void ModuleBase_WidgetSelectionFilter::onFeatureAccepted() bool ModuleBase_WidgetSelectionFilter::storeValueCustom() { + ModuleBase_ModelWidget* aActive = myWorkshop->propertyPanel()->activeWidget(); + if (aActive) + return aActive->storeValue(); + updateObject(myFeature); return true; } +QList ModuleBase_WidgetSelectionFilter::itemsList() const +{ + return myFiltersWgt->findChildren(); +} + + bool ModuleBase_WidgetSelectionFilter::restoreValueCustom() { - ModuleBase_ModelWidget* aActive = myWorkshop->propertyPanel()->activeWidget(); - if (aActive) - return aActive->restoreValue(); + ModelAPI_FiltersFactory* aFactory = ModelAPI_Session::get()->filters(); + FiltersFeaturePtr aFiltersFeature = std::dynamic_pointer_cast(myFeature); + + // Init filters member of the parent attribute + AttributeSelectionListPtr aAttrList = mySelectorFeature->selectionList(mySelectorAttribute); + if (aAttrList->filters() != aFiltersFeature) { + aAttrList->setFilters(aFiltersFeature); + } + + QList aItemsList = itemsList(); + std::list aFilters = aFiltersFeature->filters(); + + std::list::const_iterator aIt; + int i = 0; + int aNbItems = aItemsList.size(); + ModuleBase_FilterItem* aItem = 0; + bool isBlocked = myFiltersCombo->blockSignals(true); + for (aIt = aFilters.cbegin(); aIt != aFilters.cend(); aIt++, i++) { + std::string aStr = (*aIt); + aItem = 0; + if (i >= aNbItems) { + aItem = onAddFilter(aStr); + FilterPtr aFilterObj = aFactory->filter(aStr); + int aId = myFiltersCombo->findText(aFilterObj->name().c_str()); + if ((aId != -1) && !aFilterObj->isMultiple()) + myFiltersCombo->removeItem(aId); + if (aItem) { + QList aSubList = aItem->widgets(); + foreach(ModuleBase_ModelWidget* aWgt, aSubList) { + aWgt->restoreValue(); + } + } + } + } + myFiltersCombo->setCurrentIndex(0); + myFiltersCombo->blockSignals(isBlocked); return true; } + +QString ModuleBase_WidgetSelectionFilter::getError(const bool theValueStateChecked) const +{ + QString aErrorMsg = ModuleBase_ModelWidget::getError(theValueStateChecked); + if (aErrorMsg.isEmpty()) { + if (myValues.size() == 0) + aErrorMsg = translate("Selection is empty"); + } + return aErrorMsg; +} + +void ModuleBase_WidgetSelectionFilter::onObjectUpdated() +{ + myShowBtn->setChecked(false); + clearCurrentSelection(true); + updateNumberSelected(); + + QList aItemsList = itemsList(); + foreach(ModuleBase_FilterItem* aItem, aItemsList) { + QList aWidgetsList = aItem->widgets(); + foreach(ModuleBase_ModelWidget* aWidget, aWidgetsList) { + if (!aWidget->feature().get()) + aWidget->setFeature(myFeature); + aWidget->restoreValue(); + } + } + updateObject(myFeature); + + // Redisplay the feature on order to Customize presentations from filters with selectors + static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); + ModelAPI_EventCreator::get()->sendUpdated(myFeature, EVENT_DISP); + Events_Loop::loop()->flush(EVENT_DISP); +} + +void ModuleBase_WidgetSelectionFilter::storeFilters(const std::list& theFilters) +{ + for (std::list::const_iterator anIt = theFilters.begin(); + anIt != theFilters.end(); ++anIt) { + std::string aName = translate((*anIt)->name()).toStdString(); + myFilters[aName] = *anIt; + } +} + +QString ModuleBase_WidgetSelectionFilter::translate(const std::string& theString) const +{ + return ModuleBase_Tools::translate(myFeatureId, theString); +}