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