]> SALOME platform Git repositories - modules/shaper.git/blob - src/ModuleBase/ModuleBase_WidgetSelector.cpp
Salome HOME
Issue #1343 Improvement of Extrusion and Revolution operations: extrusion by preselection
[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_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   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_ViewerPrs> ModuleBase_WidgetSelector::getAttributeSelection() const
73 {
74   return QList<ModuleBase_ViewerPrs>();
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::setObject(ObjectPtr theObject,
145                                           GeomShapePtr theShape)
146 {
147   DataPtr aData = myFeature->data();
148   ModuleBase_Tools::setObject(aData->attribute(attributeID()), theObject, theShape,
149                               myWorkshop, myIsInValidate);
150 }
151
152 //********************************************************************
153 void ModuleBase_WidgetSelector::activateCustom()
154 {
155   connect(myWorkshop, SIGNAL(selectionChanged()), this,
156           SLOT(onSelectionChanged()), Qt::UniqueConnection);
157   
158   activateSelectionAndFilters(true);
159
160   // Restore selection in the viewer by the attribute selection list
161   myWorkshop->setSelected(getAttributeSelection());
162 }
163
164 //********************************************************************
165 bool ModuleBase_WidgetSelector::isValidSelectionCustom(const ModuleBase_ViewerPrs& thePrs)
166 {
167   GeomShapePtr aShape = myWorkshop->selection()->getShape(thePrs);
168   ResultPtr aResult = myWorkshop->selection()->getResult(thePrs);
169   bool aValid = acceptSubShape(aShape, aResult);
170
171   if (aValid) {
172     // In order to avoid selection of the same object
173     ResultPtr aResult = myWorkshop->selection()->getResult(thePrs);
174     FeaturePtr aSelectedFeature = ModelAPI_Feature::feature(aResult);
175     aValid = aSelectedFeature != myFeature;
176   }
177   return aValid;
178 }
179
180 //********************************************************************
181 bool ModuleBase_WidgetSelector::setSelectionCustom(const ModuleBase_ViewerPrs& thePrs)
182 {
183   ObjectPtr anObject;
184   GeomShapePtr aShape;
185   getGeomSelection(thePrs, anObject, aShape);
186
187   setObject(anObject, aShape);
188   return true;
189 }
190
191 //********************************************************************
192 void ModuleBase_WidgetSelector::deactivate()
193 {
194   ModuleBase_ModelWidget::deactivate();
195   disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
196   activateSelectionAndFilters(false);
197   ModuleBase_ModelWidget::deactivate();
198 }
199
200 //********************************************************************
201 std::string ModuleBase_WidgetSelector::generateName(const AttributePtr& theAttribute,
202                                                     ModuleBase_IWorkshop* theWorkshop)
203 {
204   std::string aName;
205   if (theAttribute.get() != NULL) {
206     ModuleBase_Operation* anOperation = theWorkshop->currentOperation();
207
208     FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
209     if (aFeature.get()) {
210       std::string aXmlCfg, aDescription;
211       theWorkshop->module()->getXMLRepresentation(aFeature->getKind(), aXmlCfg, aDescription);
212
213       ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
214       std::string anAttributeTitle;
215       aFactory.getAttributeTitle(theAttribute->id(), anAttributeTitle);
216
217       std::stringstream aStreamName;
218       aStreamName << theAttribute->owner()->data()->name() << "/"<< anAttributeTitle.c_str();
219       aName = aStreamName.str();
220     }
221   }
222   return aName;
223 }