Salome HOME
Issue 1299 Angle constraint: support of additional and complementary angles. Test...
[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 #include <ModuleBase_Operation.h>
13 #include <ModuleBase_OperationDescription.h>
14 #include <ModuleBase_WidgetFactory.h>
15 #include <ModuleBase_IModule.h>
16
17 #include <ModelAPI_ResultConstruction.h>
18
19 #include <TopoDS_Iterator.hxx>
20
21 ModuleBase_WidgetSelector::ModuleBase_WidgetSelector(QWidget* theParent,
22                                                      ModuleBase_IWorkshop* theWorkshop,
23                                                      const Config_WidgetAPI* theData)
24 : ModuleBase_WidgetValidated(theParent, theWorkshop, theData)
25 {
26 }
27
28 //********************************************************************
29 ModuleBase_WidgetSelector::~ModuleBase_WidgetSelector()
30 {
31 }
32
33 //********************************************************************
34 void ModuleBase_WidgetSelector::getGeomSelection(const ModuleBase_ViewerPrs& thePrs,
35                                                       ObjectPtr& theObject,
36                                                       GeomShapePtr& theShape)
37 {
38   ModuleBase_ISelection* aSelection = myWorkshop->selection();
39   theObject = aSelection->getResult(thePrs);
40   theShape = aSelection->getShape(thePrs);
41 }
42
43 //********************************************************************
44 void ModuleBase_WidgetSelector::onSelectionChanged()
45 {
46   QList<ModuleBase_ViewerPrs> aSelected = getFilteredSelected();
47
48   bool isDone = setSelection(aSelected, true/*false*/);
49   // "false" flag should be used here, it connects to the #26658 OCC bug, when the user click in 
50   // the same place repeatedly without mouse moved. In the case validation by filters is not
51   // perfromed, so an invalid object is selected. E.g. distance constraint, selection of a point.
52   // the 3rd click in the same point allow using this point.
53   emit valuesChanged();
54   // the updateObject method should be called to flush the updated sigal. The workshop listens it,
55   // calls validators for the feature and, as a result, updates the Apply button state.
56   updateObject(myFeature);
57
58   // we need to forget about previous validation result as the current selection can influence on it
59   clearValidatedCash();
60
61   if (isDone)
62     updateFocus();
63 }
64
65 //********************************************************************
66 bool ModuleBase_WidgetSelector::acceptSubShape(const GeomShapePtr& theShape,
67                                                const ResultPtr& theResult) const
68 {
69   bool aValid = false;
70
71   GeomShapePtr aShape = theShape;
72
73   QIntList aShapeTypes = getShapeTypes();
74   if (aShapeTypes.empty()) {
75     aValid = true;
76     return aValid;
77   }
78   // when the SHAPE type is provided by XML, the hole result shape can be selected.
79   if (!aShape.get() && aShapeTypes.contains(TopAbs_SHAPE)) {
80     aValid = true;
81     return aValid;
82   }
83
84   if (!aShape.get() && theResult.get()) {
85     if (theResult.get())
86       aShape = theResult->shape();
87   }
88   TopAbs_ShapeEnum aShapeType = TopAbs_SHAPE;
89   if (aShape.get()) {
90     // Check that the selection corresponds to selection type
91     TopoDS_Shape aTopoShape = aShape->impl<TopoDS_Shape>();
92     aShapeType = aTopoShape.ShapeType();
93     // for compounds check sub-shapes: it may be compound of needed type:
94     // Booleans may produce compounds of Solids
95     if (aShapeType == TopAbs_COMPOUND) {
96       aShapeType = ModuleBase_Tools::getCompoundSubType(aTopoShape);
97     }
98   }
99
100   QIntList::const_iterator anIt = aShapeTypes.begin(), aLast = aShapeTypes.end();
101   for (; anIt != aLast; anIt++) {
102     if (aShapeType == *anIt)
103       aValid = true;
104     else if (*anIt == TopAbs_FACE) {
105       // try to process the construction shape only if there is no a selected shape in the viewer
106       if (!theShape.get() && theResult.get()) {
107         ResultConstructionPtr aCResult =
108                                 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(theResult);
109         aValid = aCResult.get() && aCResult->facesNum() > 0;
110       }
111     }
112   }
113   return aValid;
114 }
115
116 //********************************************************************
117 bool ModuleBase_WidgetSelector::activateSelectionAndFilters(bool toActivate)
118 {
119   updateSelectionName();
120
121   if (toActivate) {
122     myWorkshop->activateSubShapesSelection(getShapeTypes());
123   } else {
124     myWorkshop->deactivateSubShapesSelection();
125   }
126   return activateFilters(toActivate);
127 }
128
129 //********************************************************************
130 void ModuleBase_WidgetSelector::activateCustom()
131 {
132   connect(myWorkshop, SIGNAL(selectionChanged()), this,
133           SLOT(onSelectionChanged()), Qt::UniqueConnection);
134   
135   activateSelectionAndFilters(true);
136
137   // Restore selection in the viewer by the attribute selection list
138   myWorkshop->setSelected(getAttributeSelection());
139 }
140
141 //********************************************************************
142 bool ModuleBase_WidgetSelector::isValidSelectionCustom(const ModuleBase_ViewerPrs& thePrs)
143 {
144   GeomShapePtr aShape = myWorkshop->selection()->getShape(thePrs);
145   ResultPtr aResult = myWorkshop->selection()->getResult(thePrs);
146   bool aValid = acceptSubShape(aShape, aResult);
147
148   if (aValid) {
149     // In order to avoid selection of the same object
150     ResultPtr aResult = myWorkshop->selection()->getResult(thePrs);
151     FeaturePtr aSelectedFeature = ModelAPI_Feature::feature(aResult);
152     aValid = aSelectedFeature != myFeature;
153   }
154   return aValid;
155 }
156
157 //********************************************************************
158 bool ModuleBase_WidgetSelector::setSelectionCustom(const ModuleBase_ViewerPrs& thePrs)
159 {
160   ObjectPtr anObject;
161   GeomShapePtr aShape;
162   getGeomSelection(thePrs, anObject, aShape);
163
164   setObject(anObject, aShape);
165   return true;
166 }
167
168 //********************************************************************
169 void ModuleBase_WidgetSelector::deactivate()
170 {
171   ModuleBase_ModelWidget::deactivate();
172   disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
173   activateSelectionAndFilters(false);
174   ModuleBase_ModelWidget::deactivate();
175 }
176
177 //********************************************************************
178 std::string ModuleBase_WidgetSelector::generateName(const AttributePtr& theAttribute,
179                                                     ModuleBase_IWorkshop* theWorkshop)
180 {
181   std::string aName;
182   if (theAttribute.get() != NULL) {
183     ModuleBase_Operation* anOperation = theWorkshop->currentOperation();
184
185     FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
186     if (aFeature.get()) {
187       std::string aXmlCfg, aDescription;
188       theWorkshop->module()->getXMLRepresentation(aFeature->getKind(), aXmlCfg, aDescription);
189
190       ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
191       std::string anAttributeTitle;
192       aFactory.getAttributeTitle(theAttribute->id(), anAttributeTitle);
193
194       std::stringstream aStreamName;
195       aStreamName << theAttribute->owner()->data()->name() << "/"<< anAttributeTitle.c_str();
196       aName = aStreamName.str();
197     }
198   }
199   return aName;
200 }