]> SALOME platform Git repositories - modules/shaper.git/blobdiff - src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp
Salome HOME
Make tests working on new results structure and selection of feature as argument
[modules/shaper.git] / src / ModuleBase / ModuleBase_WidgetMultiSelector.cpp
index b3884b4966c655063793b2451e9e1f2c364ecd72..2a60ec774d664b8b78b12ca86a4eac6130dad609 100755 (executable)
@@ -20,6 +20,8 @@
 
 #include <ModuleBase_WidgetMultiSelector.h>
 
+#include <GeomAPI_AISObject.h>
+
 #include <ModuleBase_ActionIntParameter.h>
 #include <ModuleBase_Definitions.h>
 #include <ModuleBase_Events.h>
 #include <ModuleBase_IModule.h>
 #include <ModuleBase_ISelection.h>
 #include <ModuleBase_ISelectionActivate.h>
+#include <ModuleBase_IPropertyPanel.h>
 #include <ModuleBase_IViewer.h>
 #include <ModuleBase_IWorkshop.h>
 #include <ModuleBase_ListView.h>
+#include <ModuleBase_ResultPrs.h>
 #include <ModuleBase_Tools.h>
 #include <ModuleBase_ViewerPrs.h>
 #include <ModuleBase_WidgetShapeSelector.h>
+#include <ModuleBase_ChoiceCtrl.h>
 
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Object.h>
@@ -44,6 +49,8 @@
 
 #include <Config_WidgetAPI.h>
 
+#include <AIS_InteractiveObject.hxx>
+
 #include <QGridLayout>
 #include <QLabel>
 #include <QListWidget>
@@ -77,34 +84,55 @@ void printHistoryInfo(const QString& theMethodName, int theCurrentHistoryIndex,
 }
 #endif
 
+
+QStringList getIconsList(const QStringList& theNames)
+{
+  QStringList aIcons;
+  foreach (QString aName, theNames) {
+    QString aUName = aName.toUpper();
+    if ((aUName == "VERTICES") || (aUName == "VERTEX"))
+      aIcons << ":pictures/vertex32.png";
+    else if ((aUName == "EDGES") || (aUName == "EDGE"))
+      aIcons << ":pictures/edge32.png";
+    else if ((aUName == "FACES") || (aUName == "FACE"))
+      aIcons << ":pictures/face32.png";
+    else if ((aUName == "SOLIDS") || (aUName == "SOLID"))
+      aIcons << ":pictures/solid32.png";
+  }
+  return aIcons;
+}
+
+/// Stores default values of selected option (selection mode)
+/// It is used only in case if myTypeCtrl is used
+static QMap<std::string, std::string> defaultValues;
+
+
 ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParent,
                                                                ModuleBase_IWorkshop* theWorkshop,
                                                                const Config_WidgetAPI* theData)
 : ModuleBase_WidgetSelector(theParent, theWorkshop, theData),
-  myIsSetSelectionBlocked(false), myCurrentHistoryIndex(-1)
+  myIsSetSelectionBlocked(false), myCurrentHistoryIndex(-1),
+  myIsFirst(true)
 {
+  std::string aPropertyTypes = theData->getProperty("type_choice");
+  QString aTypesStr = aPropertyTypes.c_str();
+  myShapeTypes = aTypesStr.split(' ', QString::SkipEmptyParts);
+  myIsUseChoice = theData->getBooleanAttribute("use_choice", false);
+
   QGridLayout* aMainLay = new QGridLayout(this);
   ModuleBase_Tools::adjustMargins(aMainLay);
 
-  QLabel* aTypeLabel = new QLabel(tr("Type"), this);
-  aMainLay->addWidget(aTypeLabel, 0, 0);
+  QStringList aIconsList = getIconsList(myShapeTypes);
+  myTypeCtrl = new ModuleBase_ChoiceCtrl(this, myShapeTypes, aIconsList);
+  myTypeCtrl->setLabel(tr("Type"));
+  myTypeCtrl->setValue(0);
+  aMainLay->addWidget(myTypeCtrl, 0, 0, 1, 2);
+  myDefMode = myShapeTypes.first().toStdString();
 
-  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);
-
-  myIsUseChoice = theData->getBooleanAttribute("use_choice", false);
-
-  if (!aShapeTypes.empty())
-    myTypeCombo->addItems(aShapeTypes);
-  aMainLay->addWidget(myTypeCombo, 0, 1);
   // if the xml definition contains one type, the controls to select a type should not be shown
-  if (aShapeTypes.size() <= 1 || !myIsUseChoice) {
-    aTypeLabel->setVisible(false);
-    myTypeCombo->setVisible(false);
+  if (myShapeTypes.size() <= 1 || !myIsUseChoice) {
+    myTypeCtrl->setVisible(false);
   }
 
   QString aLabelText = translate(theData->getProperty("label"));
@@ -112,7 +140,7 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen
   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) {
+  if (myShapeTypes.size() <= 1) {
     QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
     if (!aLabelIcon.isEmpty()) {
       QLabel* aSelectedLabel = new QLabel("", this);
@@ -127,15 +155,22 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen
   myListView = new ModuleBase_ListView(this, anObjName, aToolTip);
   connect(myListView->getControl(), SIGNAL(itemSelectionChanged()), SLOT(onListSelection()));
   connect(myListView, SIGNAL(deleteActionClicked()), SLOT(onDeleteItem()));
+  connect(myListView, SIGNAL(listActivated()), SLOT(onListActivated()));
 
   aMainLay->addWidget(myListView->getControl(), 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()));
+  connect(myTypeCtrl, SIGNAL(valueChanged(int)), this, SLOT(onSelectionTypeChanged()));
 
   myIsNeutralPointClear = theData->getBooleanAttribute("clear_in_neutral_point", true);
+  if (myShapeTypes.size() > 1 || myIsUseChoice) {
+    if (defaultValues.contains(myFeatureId + attributeID())) {
+      myDefMode = defaultValues[myFeatureId + attributeID()];
+      myTypeCtrl->setValue(myDefMode.c_str());
+    }
+  }
 }
 
 ModuleBase_WidgetMultiSelector::~ModuleBase_WidgetMultiSelector()
@@ -150,7 +185,6 @@ void ModuleBase_WidgetMultiSelector::activateCustom()
   myWorkshop->module()->activateCustomPrs(myFeature,
                             ModuleBase_IModule::CustomizeHighlightedObjects, true);
   clearSelectedHistory();
-  myWorkshop->updateCommandStatus();
 }
 
 //********************************************************************
@@ -160,6 +194,19 @@ void ModuleBase_WidgetMultiSelector::deactivate()
 
   myWorkshop->module()->deactivateCustomPrs(ModuleBase_IModule::CustomizeHighlightedObjects, true);
   clearSelectedHistory();
+}
+
+//********************************************************************
+void ModuleBase_WidgetMultiSelector::updateAfterDeactivation()
+{
+  // restore previous Undo/Redo workshop state
+  myWorkshop->updateCommandStatus();
+}
+
+//********************************************************************
+void ModuleBase_WidgetMultiSelector::updateAfterActivation()
+{
+  // fill Undo/Redo actions with current information
   myWorkshop->updateCommandStatus();
 }
 
@@ -175,7 +222,13 @@ bool ModuleBase_WidgetMultiSelector::storeValueCustom()
   std::string aType = anAttribute->attributeType();
   if (aType == ModelAPI_AttributeSelectionList::typeId()) {
     AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID());
-    aSelectionListAttr->setSelectionType(myTypeCombo->currentText().toStdString());
+
+    std::string aMode = myTypeCtrl->textValue().toStdString();
+    if (myTypeCtrl->isVisible() && myIsFirst && (!myDefMode.empty()))
+      aMode = myDefMode;
+
+    aSelectionListAttr->setSelectionType(aMode);
+    myIsFirst = false;
   }
   return true;
 }
@@ -193,8 +246,11 @@ bool ModuleBase_WidgetMultiSelector::restoreValueCustom()
     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;
+    }
   }
   updateSelectionList();
   return true;
@@ -331,13 +387,6 @@ bool ModuleBase_WidgetMultiSelector::processAction(ModuleBase_ActionType theActi
   }
 }
 
-//********************************************************************
-void ModuleBase_WidgetMultiSelector::updateSelectionModesAndFilters(bool toActivate)
-{
-  myWorkshop->updateCommandStatus(); // update enable state of Undo/Redo application actions
-  ModuleBase_WidgetSelector::updateSelectionModesAndFilters(toActivate);
-}
-
 //********************************************************************
 bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& thePrs)
 {
@@ -415,14 +464,13 @@ bool ModuleBase_WidgetMultiSelector::processDelete()
   myListView->restoreSelection(anIndices);
 
   appendSelectionInHistory();
-  return aDone;
+  return true/*aDone*/; // following #2438 Delete should be processed even if nothing is delete
 }
 
 //********************************************************************
 QList<QWidget*> ModuleBase_WidgetMultiSelector::getControls() const
 {
   QList<QWidget*> result;
-  //result << myTypeCombo;
   result << myListView->getControl();
   return result;
 }
@@ -430,6 +478,11 @@ QList<QWidget*> ModuleBase_WidgetMultiSelector::getControls() const
 //********************************************************************
 void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()
 {
+  // Clear current selection in order to avoid updating of object browser with obsolete indexes
+  // which can appear because of results deletetion after changing a type of selection
+  QList<ModuleBase_ViewerPrsPtr> aEmptyList;
+  myWorkshop->setSelected(aEmptyList);
+
   updateSelectionModesAndFilters(true);
   myWorkshop->selectionActivate()->updateSelectionModes();
 
@@ -440,7 +493,7 @@ void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()
   std::string aType = anAttribute->attributeType();
   if (aType == ModelAPI_AttributeSelectionList::typeId()) {
     AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID());
-    aSelectionListAttr->setSelectionType(myTypeCombo->currentText().toStdString());
+    aSelectionListAttr->setSelectionType(myTypeCtrl->textValue().toStdString());
   }
 
   // clear attribute values
@@ -469,6 +522,9 @@ void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()
                             true); /// hope that something is redisplayed by object updated
   // clear history should follow after set selected to do not increase history by setSelected
   clearSelectedHistory();
+
+  if (myWorkshop->propertyPanel()->activeWidget() != this)
+    myWorkshop->propertyPanel()->activateWidget(this);
 }
 
 //********************************************************************
@@ -573,12 +629,13 @@ QIntList ModuleBase_WidgetMultiSelector::shapeTypes() const
 {
   QIntList aShapeTypes;
 
-  if (myTypeCombo->count() > 1 && myIsUseChoice) {
-    aShapeTypes.append(ModuleBase_Tools::shapeType(myTypeCombo->currentText()));
+  if (myShapeTypes.length() > 1 && myIsUseChoice) {
+    aShapeTypes.append(ModuleBase_Tools::shapeType(myTypeCtrl->textValue()));
   }
   else {
-    for (int i = 0, aCount = myTypeCombo->count(); i < aCount; i++)
-      aShapeTypes.append(ModuleBase_Tools::shapeType(myTypeCombo->itemText(i)));
+    foreach (QString aType, myShapeTypes) {
+      aShapeTypes.append(ModuleBase_Tools::shapeType(aType));
+    }
   }
   return aShapeTypes;
 }
@@ -588,17 +645,18 @@ void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const int theShapeType)
 {
   QString aShapeTypeName;
 
-  for (int idx = 0; idx < myTypeCombo->count(); ++idx) {
-    aShapeTypeName = myTypeCombo->itemText(idx);
+  int idx = 0;
+  foreach (QString aShapeTypeName, myShapeTypes) {
     int aRefType = ModuleBase_Tools::shapeType(aShapeTypeName);
-    if(aRefType == theShapeType && idx != myTypeCombo->currentIndex()) {
+    if(aRefType == theShapeType && idx != myTypeCtrl->value()) {
       updateSelectionModesAndFilters(false);
-      bool isBlocked = myTypeCombo->blockSignals(true);
-      myTypeCombo->setCurrentIndex(idx);
-      myTypeCombo->blockSignals(isBlocked);
+      bool isBlocked = myTypeCtrl->blockSignals(true);
+      myTypeCtrl->setValue(idx);
+      myTypeCtrl->blockSignals(isBlocked);
       updateSelectionModesAndFilters(true);
       break;
     }
+    idx++;
   }
 }
 
@@ -639,7 +697,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 {
@@ -778,8 +836,8 @@ bool ModuleBase_WidgetMultiSelector::removeUnusedAttributeObjects
     AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(attributeID());
     for (int i = 0; i < aSelectionListAttr->size(); i++) {
       AttributeSelectionPtr anAttr = aSelectionListAttr->value(i);
-      bool aFound = findInSelection(anAttr->context(), anAttr->value(), aGeomSelection,
-                                    myWorkshop);
+      bool aFound = findInSelection(
+        anAttr->contextObject(), anAttr->value(), aGeomSelection, myWorkshop);
       if (!aFound)
         anIndicesToBeRemoved.insert(i);
     }
@@ -872,22 +930,44 @@ bool ModuleBase_WidgetMultiSelector::findInSelection(const ObjectPtr& theObject,
     return true;
 
   bool aFound = false;
-  GeomShapePtr anEmptyShape(new GeomAPI_Shape());
-  if (theShape.get()) { // treat shape equal to context as null: 2219, keep order of shapes in list
-    const ResultPtr aContext = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
-    if (aContext.get() && aContext->shape()->isEqual(theShape))
-      theShape.reset();
+  GeomShapePtr aShape = theShape;
+  if (!aShape.get()) {
+    // #2429 (the preselection of a sketch is not taken into account)
+    ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+    if (aResult.get())
+      aShape = aResult->shape();
   }
-  GeomShapePtr aShape = theShape.get() ? theShape : anEmptyShape;
   if (theGeomSelection.find(theObject) != theGeomSelection.end()) {// found
     const std::set<GeomShapePtr>& aShapes = theGeomSelection.at(theObject);
     std::set<GeomShapePtr>::const_iterator anIt = aShapes.begin(), aLast = aShapes.end();
     for (; anIt != aLast && !aFound; anIt++) {
       GeomShapePtr aCShape = *anIt;
       if (aCShape.get())
+      {
+        // treat shape equal to context as null: 2219, keep order of shapes in list
+        if (aCShape->isNull()) { // in selection, shape of result is equal to selected shape
+          // if so, here we need to check shape of result
+          ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(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(AIS_InteractiveObject)>();
+
+      Handle(ModuleBase_ResultPrs) aResultPrs = Handle(ModuleBase_ResultPrs)::DownCast(anAISIO);
+      if (!aResultPrs.IsNull() && aResultPrs->isSubShapeHidden(theShape->impl<TopoDS_Shape>()))
+        return true;
+    }
+  }
+
   return aFound;
 }
 
@@ -933,4 +1013,16 @@ QList<ActionInfo>
     }
   }
   return aList;
+}
+
+
+void ModuleBase_WidgetMultiSelector::onFeatureAccepted()
+{
+  defaultValues[myFeatureId + attributeID()] = myDefMode;
+}
+
+void ModuleBase_WidgetMultiSelector::onListActivated()
+{
+  //focusTo();
+  emitFocusInWidget();
 }
\ No newline at end of file