Salome HOME
Merge branch 'python_parametric_api' of https://git.salome-platform.org/git/modules...
[modules/shaper.git] / src / ModuleBase / ModuleBase_WidgetSelector.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        ModuleBase_WidgetSelector.cpp
4 // Created:     19 June 2015
5 // Author:      Natalia ERMOLAEVA
6
7 #include <ModuleBase_WidgetSelector.h>
8
9 #include <ModuleBase_ISelection.h>
10 #include <ModuleBase_IWorkshop.h>
11 #include <ModuleBase_Tools.h>
12
13 #include <ModelAPI_ResultConstruction.h>
14
15 #include <TopoDS_Iterator.hxx>
16
17 ModuleBase_WidgetSelector::ModuleBase_WidgetSelector(QWidget* theParent,
18                                                      ModuleBase_IWorkshop* theWorkshop,
19                                                      const Config_WidgetAPI* theData,
20                                                      const std::string& theParentId)
21  : ModuleBase_WidgetValidated(theParent, theWorkshop, theData, theParentId)
22 {
23 }
24
25 //********************************************************************
26 ModuleBase_WidgetSelector::~ModuleBase_WidgetSelector()
27 {
28 }
29
30 //********************************************************************
31 void ModuleBase_WidgetSelector::getGeomSelection(const ModuleBase_ViewerPrs& thePrs,
32                                                       ObjectPtr& theObject,
33                                                       GeomShapePtr& theShape)
34 {
35   ModuleBase_ISelection* aSelection = myWorkshop->selection();
36   theObject = aSelection->getResult(thePrs);
37   theShape = aSelection->getShape(thePrs);
38 }
39
40 //********************************************************************
41 void ModuleBase_WidgetSelector::onSelectionChanged()
42 {
43   clearAttribute();
44
45   QList<ModuleBase_ViewerPrs> aSelected = getFilteredSelected();
46
47   bool isDone = setSelection(aSelected, true/*false*/);
48   // "false" flag should be used here, it connects to the #26658 OCC bug, when the user click in 
49   // the same place repeatedly without mouse moved. In the case validation by filters is not
50   // perfromed, so an invalid object is selected. E.g. distance constraint, selection of a point.
51   // the 3rd click in the same point allow using this point.
52   emit valuesChanged();
53   // the updateObject method should be called to flush the updated sigal. The workshop listens it,
54   // calls validators for the feature and, as a result, updates the Apply button state.
55   updateObject(myFeature);
56
57   if (isDone)
58     updateFocus();
59 }
60
61 //********************************************************************
62 bool ModuleBase_WidgetSelector::acceptSubShape(const GeomShapePtr& theShape,
63                                                const ResultPtr& theResult) const
64 {
65   bool aValid = false;
66
67   GeomShapePtr aShape = theShape;
68
69   QIntList aShapeTypes = getShapeTypes();
70   if (aShapeTypes.empty()) {
71     aValid = true;
72     return aValid;
73   }
74   // when the SHAPE type is provided by XML, the hole result shape can be selected.
75   if (!aShape.get() && aShapeTypes.contains(TopAbs_SHAPE)) {
76     aValid = true;
77     return aValid;
78   }
79
80   if (!aShape.get() && theResult.get()) {
81     if (theResult.get())
82       aShape = theResult->shape();
83   }
84   TopAbs_ShapeEnum aShapeType = TopAbs_SHAPE;
85   if (aShape.get()) {
86     // Check that the selection corresponds to selection type
87     TopoDS_Shape aTopoShape = aShape->impl<TopoDS_Shape>();
88     aShapeType = aTopoShape.ShapeType();
89     // for compounds check sub-shapes: it may be compound of needed type:
90     // Booleans may produce compounds of Solids
91     if (aShapeType == TopAbs_COMPOUND) {
92       aShapeType = ModuleBase_Tools::getCompoundSubType(aTopoShape);
93     }
94   }
95
96   QIntList::const_iterator anIt = aShapeTypes.begin(), aLast = aShapeTypes.end();
97   for (; anIt != aLast; anIt++) {
98     if (aShapeType == *anIt)
99       aValid = true;
100     else if (*anIt == TopAbs_FACE) {
101       // try to process the construction shape only if there is no a selected shape in the viewer
102       if (!theShape.get() && theResult.get()) {
103         ResultConstructionPtr aCResult =
104                                 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(theResult);
105         aValid = aCResult.get() && aCResult->facesNum() > 0;
106       }
107     }
108   }
109   return aValid;
110 }
111
112 //********************************************************************
113 void ModuleBase_WidgetSelector::activateSelection(bool toActivate)
114 {
115   updateSelectionName();
116
117   if (toActivate) {
118     myWorkshop->activateSubShapesSelection(getShapeTypes());
119   } else {
120     myWorkshop->deactivateSubShapesSelection();
121   }
122 }
123
124 //********************************************************************
125 void ModuleBase_WidgetSelector::activateCustom()
126 {
127   connect(myWorkshop, SIGNAL(selectionChanged()), this,
128           SLOT(onSelectionChanged()), Qt::UniqueConnection);
129   
130   activateSelection(true);
131
132   // Restore selection in the viewer by the attribute selection list
133   myWorkshop->setSelected(getAttributeSelection());
134
135   activateFilters(true);
136 }
137
138 //********************************************************************
139 bool ModuleBase_WidgetSelector::isValidSelectionCustom(const ModuleBase_ViewerPrs& thePrs)
140 {
141   GeomShapePtr aShape = myWorkshop->selection()->getShape(thePrs);
142   ResultPtr aResult = myWorkshop->selection()->getResult(thePrs);
143   bool aValid = acceptSubShape(aShape, aResult);
144
145   if (aValid) {
146     // In order to avoid selection of the same object
147     ResultPtr aResult = myWorkshop->selection()->getResult(thePrs);
148     FeaturePtr aSelectedFeature = ModelAPI_Feature::feature(aResult);
149     aValid = aSelectedFeature != myFeature;
150   }
151   return aValid;
152 }
153
154 //********************************************************************
155 bool ModuleBase_WidgetSelector::setSelectionCustom(const ModuleBase_ViewerPrs& thePrs)
156 {
157   ObjectPtr anObject;
158   GeomShapePtr aShape;
159   getGeomSelection(thePrs, anObject, aShape);
160
161   setObject(anObject, aShape);
162   return true;
163 }
164
165 //********************************************************************
166 void ModuleBase_WidgetSelector::deactivate()
167 {
168   ModuleBase_ModelWidget::deactivate();
169   disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
170   activateSelection(false);
171   activateFilters(false);
172 }
173