Salome HOME
updated copyright message
[modules/shaper.git] / src / ModuleBase / ModuleBase_WidgetMultiSelector.cpp
index 349b61502e0921878fd37ddd801bddfe93520e27..64dc0d7307ccc220ca32c458da10a47b1d03d0ed 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2023  CEA, EDF
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -114,22 +114,47 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen
                                                                const Config_WidgetAPI* theData)
 : ModuleBase_WidgetSelector(theParent, theWorkshop, theData),
   myIsSetSelectionBlocked(false), myCurrentHistoryIndex(-1),
-  myIsFirst(true), myFiltersWgt(0)
+  myIsFirst(true), myFiltersWgt(0), myShowOnlyBtn(0)
 {
-  std::string aPropertyTypes = theData->getProperty("type_choice");
+  std::string aPropertyTypes = theData->getProperty("shape_types");
   QString aTypesStr = aPropertyTypes.c_str();
   myShapeTypes = aTypesStr.split(' ', QString::SkipEmptyParts);
   myIsUseChoice = theData->getBooleanAttribute("use_choice", false);
 
-  QVBoxLayout* aMainLay = new QVBoxLayout(this);
-  ModuleBase_Tools::adjustMargins(aMainLay);
+  QString aAllowedList(theData->getProperty("allow_objects").c_str());
+  if (!aAllowedList.isEmpty())
+    myAllowedObjects = aAllowedList.split(' ', QString::SkipEmptyParts);
+
+  myMainLayout = new QVBoxLayout(this);
+  ModuleBase_Tools::adjustMargins(myMainLayout);
+
+
+  QStringList aIconsList;
+  std::string aIcons = theData->getProperty("type_icons");
+  if (aIcons.size() > 0)
+    aIconsList = QString(aIcons.c_str()).split(' ', QString::SkipEmptyParts);
+
+  if (aIconsList.size() != myShapeTypes.size())
+    aIconsList = getIconsList(myShapeTypes);
 
-  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();
+  if (!myShapeTypes.empty()) {
+    std::string aDefType = theData->getProperty("default_type");
+    if (aDefType.size() > 0) {
+      bool aOk = false;
+      int aId = QString(aDefType.c_str()).toInt(&aOk);
+      if (aOk) {
+        myTypeCtrl->setValue(aId);
+        myDefMode = myShapeTypes.at(aId).toStdString();
+      }
+    }
+    if (myDefMode.size() == 0) {
+      myTypeCtrl->setValue(0);
+      myDefMode = myShapeTypes.first().toStdString();
+    }
+  }
+  myMainLayout->addWidget(myTypeCtrl);
 
   // 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
@@ -142,7 +167,7 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen
     QWidget* aLabelWgt = new QWidget(this);
     QHBoxLayout* aLabelLayout = new QHBoxLayout(aLabelWgt);
     aLabelLayout->setContentsMargins(0, 0, 0, 0);
-    aMainLay->addWidget(aLabelWgt);
+    myMainLayout->addWidget(aLabelWgt);
 
     QLabel* aListLabel = new QLabel(aLabelText, this);
     aLabelLayout->addWidget(aListLabel);
@@ -159,39 +184,39 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen
     }
   }
 
-  QString aToolTip = QString::fromStdString(theData->widgetTooltip());
+  QString aToolTip = translate(theData->widgetTooltip());
   QString anObjName = QString::fromStdString(attributeID());
   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());
+  myMainLayout->addWidget(myListView->getControl());
   connect(myTypeCtrl, SIGNAL(valueChanged(int)), this, SLOT(onSelectionTypeChanged()));
 
-  std::string aUseFilters = theData->getProperty("use_filters");
-  if (aUseFilters.length() > 0) {
+  myUseFilters = theData->getProperty("use_filters");
+  if (myUseFilters.length() > 0) {
     QWidget* aFltrWgt = new QWidget(this);
     QHBoxLayout* aFltrLayout = new QHBoxLayout(aFltrWgt);
 
-    myFiltersWgt = new ModuleBase_FilterStarter(aUseFilters.c_str(), aFltrWgt, theWorkshop);
+    myFiltersWgt = new ModuleBase_FilterStarter(myUseFilters, aFltrWgt, theWorkshop);
     aFltrLayout->addWidget(myFiltersWgt);
 
     aFltrLayout->addStretch();
 
-    QPushButton* aShowBtn = new QPushButton(tr("Show only"), aFltrWgt);
-    aShowBtn->setCheckable(true);
-    aShowBtn->setChecked(false);
-    connect(aShowBtn, SIGNAL(toggled(bool)), SLOT(onShowOnly(bool)));
-    aFltrLayout->addWidget(aShowBtn);
+    myShowOnlyBtn = new QPushButton(tr("Show only"), aFltrWgt);
+    myShowOnlyBtn->setCheckable(true);
+    myShowOnlyBtn->setChecked(false);
+    connect(myShowOnlyBtn, SIGNAL(toggled(bool)), SLOT(onShowOnly(bool)));
+    aFltrLayout->addWidget(myShowOnlyBtn);
 
-    aMainLay->addWidget(aFltrWgt);
+    myMainLayout->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);
+    myMainLayout->addWidget(myGeomCheck);
     connect(myGeomCheck, SIGNAL(toggled(bool)), SLOT(onSameTopology(bool)));
   }
   else
@@ -215,9 +240,26 @@ void ModuleBase_WidgetMultiSelector::activateCustom()
 {
   ModuleBase_WidgetSelector::activateCustom();
 
-  myWorkshop->module()->activateCustomPrs(myFeature,
+  ModuleBase_IModule* aModule = myWorkshop->module();
+  aModule->activateCustomPrs(myFeature,
                             ModuleBase_IModule::CustomizeHighlightedObjects, true);
   clearSelectedHistory();
+  if (myAllowedObjects.length() > 0) {
+    Handle(SelectMgr_Filter) aFilter = aModule->selectionFilter(SF_GlobalFilter);
+    if (!aFilter.IsNull()) {
+      Handle(ModuleBase_ShapeDocumentFilter) aDocFilter =
+        Handle(ModuleBase_ShapeDocumentFilter)::DownCast(aFilter);
+      if (!aDocFilter.IsNull()) {
+        QStringList aSelFilters = aDocFilter->nonSelectableTypes();
+        foreach(QString aType, aSelFilters) {
+          if (aSelFilters.contains(aType)) {
+            aDocFilter->removeNonSelectableType(aType);
+            myTmpAllowed.append(aType);
+          }
+        }
+      }
+    }
+  }
 }
 
 //********************************************************************
@@ -227,10 +269,24 @@ void ModuleBase_WidgetMultiSelector::deactivate()
 
   ModuleBase_WidgetSelector::deactivate();
   if (myVisibleObjects.size())
-    onShowOnly(false);
+    myShowOnlyBtn->setChecked(false);
 
   myWorkshop->module()->deactivateCustomPrs(ModuleBase_IModule::CustomizeHighlightedObjects, true);
   clearSelectedHistory();
+  if (myTmpAllowed.length() > 0) {
+    ModuleBase_IModule* aModule = myWorkshop->module();
+    Handle(SelectMgr_Filter) aFilter = aModule->selectionFilter(SF_GlobalFilter);
+    if (!aFilter.IsNull()) {
+      Handle(ModuleBase_ShapeDocumentFilter) aDocFilter =
+        Handle(ModuleBase_ShapeDocumentFilter)::DownCast(aFilter);
+      if (!aDocFilter.IsNull()) {
+        foreach(QString aType, myTmpAllowed) {
+          aDocFilter->addNonSelectableType(aType);
+        }
+      }
+    }
+    myTmpAllowed.clear();
+  }
 }
 
 //********************************************************************
@@ -259,12 +315,23 @@ bool ModuleBase_WidgetMultiSelector::storeValueCustom()
   std::string aType = anAttribute->attributeType();
   if (aType == ModelAPI_AttributeSelectionList::typeId()) {
     AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID());
-    std::string aMode = myTypeCtrl->textValue().toStdString();
-    if (myTypeCtrl->isVisible() && myIsFirst && (!myDefMode.empty()))
-      aMode = myDefMode;
+    if (myTypeCtrl->isVisible()) {
+      std::string aMode = myTypeCtrl->textValue().toStdString();
+      if (myIsFirst && (!myDefMode.empty()))
+        aMode = myDefMode;
 
-    aSelectionListAttr->setSelectionType(aMode);
-    myIsFirst = false;
+      aSelectionListAttr->setSelectionType(aMode);
+      myIsFirst = false;
+    } else { // no type, set the type as a first element of the list shape type when it is appeared
+      if (aSelectionListAttr->size()) {
+        AttributeSelectionPtr aSel = aSelectionListAttr->value(0);
+        GeomShapePtr aFirstVal = aSel->value();
+        if (!aFirstVal.get() && aSel->context().get())
+          aFirstVal = aSel->context()->shape();
+        if (aFirstVal.get() && !aFirstVal->isNull())
+          aSelectionListAttr->setSelectionType(aFirstVal->shapeTypeStr());
+      }
+    }
   }
   return true;
 }
@@ -282,8 +349,10 @@ bool ModuleBase_WidgetMultiSelector::restoreValueCustom()
   if (aType == ModelAPI_AttributeSelectionList::typeId()) {
     // Restore shape type
     std::string aSelectionType = aSelectionListAttr->selectionType().c_str();
-    if (!aSelectionType.empty()) {
-      setCurrentShapeType(ModuleBase_Tools::shapeType(aSelectionType.c_str()));
+    if (aSelectionType.empty())
+      aSelectionListAttr->setSelectionType(myDefMode);
+    else {
+      setCurrentShapeType(aSelectionType.c_str());
       myDefMode = aSelectionType;
       myIsFirst = false;
     }
@@ -361,7 +430,7 @@ bool ModuleBase_WidgetMultiSelector::setSelection(QList<ModuleBase_ViewerPrsPtr>
     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,
+    myWorkshop->module()->customizeFeature(myFeature, ModuleBase_IModule::CustomizeArguments,
                              true);/// hope that something is redisplayed by object updated
 
   return isDone;
@@ -505,7 +574,7 @@ bool ModuleBase_WidgetMultiSelector::processDelete()
     myWorkshop->setSelected(getAttributeSelection());
 
     // may be the feature's result is not displayed, but attributes should be
-    myWorkshop->module()->customizeObject(myFeature, ModuleBase_IModule::CustomizeArguments,
+    myWorkshop->module()->customizeFeature(myFeature, ModuleBase_IModule::CustomizeArguments,
                               true); /// hope that something is redisplayed by object updated
   }
 
@@ -520,6 +589,8 @@ bool ModuleBase_WidgetMultiSelector::processDelete()
 QList<QWidget*> ModuleBase_WidgetMultiSelector::getControls() const
 {
   QList<QWidget*> result;
+  if (myTypeCtrl->isVisible())
+    result << myTypeCtrl;
   result << myListView->getControl();
   return result;
 }
@@ -568,8 +639,9 @@ void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()
   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
+  // hope that something is redisplayed by object updated
+  myWorkshop->module()->customizeFeature(myFeature, ModuleBase_IModule::CustomizeArguments, false);
+  myWorkshop->module()->customizeFeature(myFeature, ModuleBase_IModule::CustomizeResults, true);
   // clear history should follow after set selected to do not increase history by setSelected
   clearSelectedHistory();
 
@@ -680,25 +752,30 @@ QIntList ModuleBase_WidgetMultiSelector::shapeTypes() const
   QIntList aShapeTypes;
 
   if (myShapeTypes.length() > 1 && myIsUseChoice) {
-    aShapeTypes.append(ModuleBase_Tools::shapeType(myTypeCtrl->textValue()));
+    QStringList aTypes = myTypeCtrl->textValue().split("|", QString::SkipEmptyParts);
+    for(QString aType: aTypes) {
+      aShapeTypes.append(ModuleBase_Tools::shapeType(aType));
+    }
   }
   else {
     foreach (QString aType, myShapeTypes) {
-      aShapeTypes.append(ModuleBase_Tools::shapeType(aType));
+      QStringList aSubTypes = aType.split("|", QString::SkipEmptyParts);
+      for(QString aSubType: aSubTypes) {
+        aShapeTypes.append(ModuleBase_Tools::shapeType(aSubType));
+      }
     }
   }
   return aShapeTypes;
 }
 
 //********************************************************************
-void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const int theShapeType)
+void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const QString& theShapeType)
 {
-  QString aShapeTypeName;
-
   int idx = 0;
+  GeomAPI_Shape::ShapeType aShapeType = GeomAPI_Shape::shapeTypeByStr(theShapeType.toStdString());
   foreach (QString aShapeTypeName, myShapeTypes) {
-    int aRefType = ModuleBase_Tools::shapeType(aShapeTypeName);
-    if(aRefType == theShapeType && idx != myTypeCtrl->value()) {
+    if(GeomAPI_Shape::shapeTypeByStr(aShapeTypeName.toStdString()) == aShapeType &&
+       idx != myTypeCtrl->value()) {
       updateSelectionModesAndFilters(false);
       bool isBlocked = myTypeCtrl->blockSignals(true);
       myTypeCtrl->setValue(idx);
@@ -729,7 +806,7 @@ void ModuleBase_WidgetMultiSelector::updateSelectionList()
     AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(attributeID());
     for (int i = 0; i < aSelectionListAttr->size(); i++) {
       AttributeSelectionPtr aAttr = aSelectionListAttr->value(i);
-      myListView->addItem(aAttr->namingName().c_str(), i);
+      myListView->addItem(QString::fromStdWString(aAttr->namingName()), i);
     }
   }
   else if (aType == ModelAPI_AttributeRefList::typeId()) {
@@ -737,23 +814,23 @@ void ModuleBase_WidgetMultiSelector::updateSelectionList()
     for (int i = 0; i < aRefListAttr->size(); i++) {
       ObjectPtr anObject = aRefListAttr->object(i);
       if (anObject.get()) {
-        myListView->addItem(anObject->data()->name().c_str(), i);
+        myListView->addItem(QString::fromStdWString(anObject->data()->name()), i);
       }
     }
   }
   else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
     AttributeRefAttrListPtr aRefAttrListAttr = aData->refattrlist(attributeID());
     for (int i = 0; i < aRefAttrListAttr->size(); i++) {
-      AttributePtr anAttribute = aRefAttrListAttr->attribute(i);
+      AttributePtr anAttr = aRefAttrListAttr->attribute(i);
       QString aName;
-      if (anAttribute.get()) {
-        std::string anAttrName = ModuleBase_Tools::generateName(anAttribute, myWorkshop);
-        aName = QString::fromStdString(anAttrName);
+      if (anAttr.get()) {
+        std::wstring anAttrName = ModuleBase_Tools::generateName(anAttr, myWorkshop);
+        aName = QString::fromStdWString(anAttrName);
       }
       else {
         ObjectPtr anObject = aRefAttrListAttr->object(i);
         if (anObject.get()) {
-          aName = anObject->data()->name().c_str();
+          aName = QString::fromStdWString(anObject->data()->name());
         }
       }
       myListView->addItem(aName, i);
@@ -761,7 +838,7 @@ void ModuleBase_WidgetMultiSelector::updateSelectionList()
   }
 
   // We have to call repaint because sometimes the List control is not updated
-  myListView->getControl()->repaint();
+  myListView->getControl()->update();
 }
 
 //********************************************************************
@@ -805,8 +882,8 @@ void ModuleBase_WidgetMultiSelector::onDeleteItem()
 //********************************************************************
 void ModuleBase_WidgetMultiSelector::onListSelection()
 {
-  myWorkshop->module()->customizeObject(myFeature, ModuleBase_IModule::CustomizeHighlightedObjects,
-                                        true);
+  myWorkshop->module()->customizeFeature(myFeature, ModuleBase_IModule::CustomizeHighlightedObjects,
+                                         true);
 }
 
 //********************************************************************
@@ -860,9 +937,9 @@ void ModuleBase_WidgetMultiSelector::convertIndicesToViewerSelection(std::set<in
       if (!anObject.get())
         continue;
       TopoDS_Shape aShape;
-      AttributePtr anAttribute = aRefAttrListAttr->attribute(i);
-      if (anAttribute.get()) {
-        GeomShapePtr aGeomShape = ModuleBase_Tools::getShape(anAttribute, myWorkshop);
+      AttributePtr anAttr = aRefAttrListAttr->attribute(i);
+      if (anAttr.get()) {
+        GeomShapePtr aGeomShape = ModuleBase_Tools::getShape(anAttr, myWorkshop);
         theValues.append(std::shared_ptr<ModuleBase_ViewerPrs>(
                new ModuleBase_ViewerPrs(anObject, aGeomShape, NULL)));
       }
@@ -887,13 +964,15 @@ bool ModuleBase_WidgetMultiSelector::removeUnusedAttributeObjects
     AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(attributeID());
     for (int i = 0; i < aSelectionListAttr->size(); i++) {
       AttributeSelectionPtr anAttr = aSelectionListAttr->value(i);
-      //aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(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);
-//      }
+      ObjectPtr aContextObject = anAttr->contextObject();
+      GeomShapePtr aShape;
+      aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aContextObject);
+      if (!aFeature.get())
+        aShape = anAttr->value();
+
+      bool aFound = findInSelection(aContextObject, aShape, aGeomSelection, myWorkshop);
+      if (!aFound)
+        anIndicesToBeRemoved.insert(i);
     }
     isDone = anIndicesToBeRemoved.size() > 0;
     if (isDone)
@@ -931,8 +1010,8 @@ bool ModuleBase_WidgetMultiSelector::removeUnusedAttributeObjects
     for (int i = 0; i < aRefAttrListAttr->size(); i++) {
       bool aFound = false;
       if (aRefAttrListAttr->isAttribute(i)) {
-        AttributePtr anAttribute = aRefAttrListAttr->attribute(i);
-        aFound = anAttributes.find(anAttribute) != anAttributes.end();
+        AttributePtr anAttr = aRefAttrListAttr->attribute(i);
+        aFound = anAttributes.find(anAttr) != anAttributes.end();
       }
       else {
         aFound = findInSelection(aRefAttrListAttr->object(i), GeomShapePtr(), aGeomSelection,
@@ -1067,6 +1146,8 @@ QList<ActionInfo>
         i--;
       }
       break;
+    default: // [to avoid compilation warning]
+      break;
     }
   }
   return aList;
@@ -1129,4 +1210,40 @@ void ModuleBase_WidgetMultiSelector::onShowOnly(bool theChecked)
     myVisibleObjects.clear();
   } else
     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+  myWorkshop->viewer()->update();
+}
+
+bool ModuleBase_WidgetMultiSelector::isModified() const
+{
+  return myListView->getControl()->count() > 0;
+}
+
+
+void ModuleBase_WidgetMultiSelector::setReadOnly(bool isReadOnly)
+{
+  ModuleBase_WidgetSelector::setReadOnly(isReadOnly);
+  if (myShowOnlyBtn)
+    myShowOnlyBtn->hide();
+  if (myFiltersWgt) {
+    myFiltersWgt->hide();
+
+    AttributeSelectionListPtr aAttrList = feature()->selectionList(attributeID());
+    if (aAttrList.get()) {
+      FiltersFeaturePtr aFilters = aAttrList->filters();
+      if (aFilters.get()) {
+        ModuleBase_WidgetSelectionFilter::SelectorFeature = feature();
+        ModuleBase_WidgetSelectionFilter::AttributeId = attributeID();
+
+        std::string aXmlCfg, aDescription;
+        myWorkshop->module()->getXMLRepresentation(myUseFilters, aXmlCfg, aDescription);
+
+        ModuleBase_WidgetSelectionFilter* aWgt =
+          new ModuleBase_WidgetSelectionFilter(this, myWorkshop,
+            new Config_WidgetAPI(aDescription), true);
+        aWgt->setFeature(aFilters);
+        aWgt->restoreValue();
+        myMainLayout->addWidget(aWgt);
+      }
+    }
+  }
 }