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