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