Salome HOME
Issue #1037 Time performance on a big model: do not perform validating for objects...
[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   // the last flag is to be depending on hasObject is called before. To be corrected later
180   ModuleBase_Tools::setObject(attribute(), anObject, aShape, myWorkshop, myIsInValidate, true);
181   return true;
182 }
183
184 //********************************************************************
185 void ModuleBase_WidgetSelector::deactivate()
186 {
187   ModuleBase_ModelWidget::deactivate();
188   disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
189   activateSelectionAndFilters(false);
190   ModuleBase_ModelWidget::deactivate();
191 }
192
193 //********************************************************************
194 std::string ModuleBase_WidgetSelector::generateName(const AttributePtr& theAttribute,
195                                                     ModuleBase_IWorkshop* theWorkshop)
196 {
197   std::string aName;
198   if (theAttribute.get() != NULL) {
199     ModuleBase_Operation* anOperation = theWorkshop->currentOperation();
200
201     FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
202     if (aFeature.get()) {
203       std::string aXmlCfg, aDescription;
204       theWorkshop->module()->getXMLRepresentation(aFeature->getKind(), aXmlCfg, aDescription);
205
206       ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
207       std::string anAttributeTitle;
208       aFactory.getAttributeTitle(theAttribute->id(), anAttributeTitle);
209
210       std::stringstream aStreamName;
211       aStreamName << theAttribute->owner()->data()->name() << "/"<< anAttributeTitle.c_str();
212       aName = aStreamName.str();
213     }
214   }
215   return aName;
216 }