1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 #include <ModuleBase_WidgetValidated.h>
4 #include <ModuleBase_FilterFactory.h>
5 #include <ModuleBase_IViewer.h>
6 #include <ModuleBase_ISelection.h>
7 #include <ModuleBase_WidgetSelectorStore.h>
9 #include <ModelAPI_Session.h>
10 #include <ModelAPI_Validator.h>
11 #include <ModelAPI_AttributeValidator.h>
12 #include <ModelAPI_Events.h>
13 #include <ModelAPI_ResultCompSolid.h>
14 #include <ModelAPI_Tools.h>
16 #include <SelectMgr_ListIteratorOfListOfFilter.hxx>
17 #include <SelectMgr_EntityOwner.hxx>
18 #include <StdSelect_BRepOwner.hxx>
20 #include <Events_Loop.h>
24 //#define DEBUG_VALID_STATE
26 ModuleBase_WidgetValidated::ModuleBase_WidgetValidated(QWidget* theParent,
27 ModuleBase_IWorkshop* theWorkshop,
28 const Config_WidgetAPI* theData)
29 : ModuleBase_ModelWidget(theParent, theData),
30 myWorkshop(theWorkshop)
32 myAttributeStore = new ModuleBase_WidgetSelectorStore();
35 ModuleBase_WidgetValidated::~ModuleBase_WidgetValidated()
37 delete myAttributeStore;
40 //********************************************************************
41 ObjectPtr ModuleBase_WidgetValidated::findPresentedObject(const AISObjectPtr& theAIS) const
43 return myPresentedObject;
46 //********************************************************************
47 void ModuleBase_WidgetValidated::clearValidatedCash()
49 #ifdef DEBUG_VALID_STATE
50 qDebug("clearValidatedState");
56 //********************************************************************
57 void ModuleBase_WidgetValidated::storeAttributeValue()
59 myIsInValidate = true;
60 myAttributeStore->storeAttributeValue(attributeToValidate(), myWorkshop);
63 //********************************************************************
64 void ModuleBase_WidgetValidated::restoreAttributeValue(const bool theValid)
66 myIsInValidate = false;
67 myAttributeStore->restoreAttributeValue(attributeToValidate(), myWorkshop);
70 //********************************************************************
71 bool ModuleBase_WidgetValidated::isValidInFilters(const ModuleBase_ViewerPrs& thePrs)
74 Handle(SelectMgr_EntityOwner) anOwner = thePrs.owner();
76 // if an owner is null, the selection happens in the Object browser.
77 // creates a selection owner on the base of object shape and the object AIS object
78 if (anOwner.IsNull() && thePrs.owner().IsNull() && thePrs.object().get()) {
79 ResultPtr aResult = myWorkshop->selection()->getResult(thePrs);
80 if (aResult.get() && aResult->shape().get()) {
81 // some results have no shape, e.g. the parameter one. So, they should not be validated
82 GeomShapePtr aShape = aResult->shape();
83 const TopoDS_Shape aTDShape = aShape->impl<TopoDS_Shape>();
84 Handle(AIS_InteractiveObject) anIO = myWorkshop->selection()->getIO(thePrs);
85 anOwner = new StdSelect_BRepOwner(aTDShape, anIO);
86 myPresentedObject = aResult;
89 aValid = false; // only results with a shape can be filtered
91 // checks the owner by the AIS context activated filters
92 if (!anOwner.IsNull()) {
93 // the widget validator filter should be active, but during check by preselection
94 // it is not yet activated, so we need to activate/deactivate it manually
95 bool isActivated = isFilterActivated();
97 activateFilters(true);
99 Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
100 if (!aContext.IsNull()) {
101 const SelectMgr_ListOfFilter& aFilters = aContext->Filters();
102 SelectMgr_ListIteratorOfListOfFilter anIt(aFilters);
103 for (; anIt.More() && aValid; anIt.Next()) {
104 Handle(SelectMgr_Filter) aFilter = anIt.Value();
105 aValid = aFilter->IsOk(anOwner);
109 activateFilters(false);
112 // removes created owner
113 if (!anOwner.IsNull() && anOwner != thePrs.owner()) {
115 myPresentedObject = ObjectPtr();
120 //********************************************************************
121 AttributePtr ModuleBase_WidgetValidated::attributeToValidate() const
123 return myFeature->attribute(attributeID());
126 //********************************************************************
127 bool ModuleBase_WidgetValidated::isValidSelection(const ModuleBase_ViewerPrs& theValue)
130 if (getValidState(theValue, aValid)) {
134 aValid = isValidSelectionCustom(theValue);
136 storeValidState(theValue, aValid);
140 // stores the current values of the widget attribute
141 bool isFlushesActived, isAttributeSetInitializedBlocked;
143 blockAttribute(true, isFlushesActived, isAttributeSetInitializedBlocked);
145 storeAttributeValue();
147 // saves the owner value to the widget attribute
148 aValid = setSelectionCustom(theValue);
150 // checks the attribute validity
151 aValid = isValidAttribute();
153 // restores the current values of the widget attribute
154 restoreAttributeValue(aValid);
156 blockAttribute(false, isFlushesActived, isAttributeSetInitializedBlocked);
157 // In particular case the results are deleted and called as redisplayed inside of this
158 // highlight-selection, to they must be flushed as soon as possible.
159 // Example: selection of group-vertices subshapes with shift pressend on body. Without
160 // these 4 lines below the application crashes because of left presentations on
161 // removed results still in the viewer.
162 static Events_ID aDeletedEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);
163 static Events_ID aRedispEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY);
164 Events_Loop::loop()->flush(aDeletedEvent);
165 Events_Loop::loop()->flush(aRedispEvent);
167 storeValidState(theValue, aValid);
171 //********************************************************************
172 bool ModuleBase_WidgetValidated::isValidSelectionCustom(const ModuleBase_ViewerPrs& thePrs)
177 //********************************************************************
178 bool ModuleBase_WidgetValidated::isValidAttribute() const
180 SessionPtr aMgr = ModelAPI_Session::get();
181 ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
182 AttributePtr anAttribute = attributeToValidate();
183 std::string aValidatorID, anError;
184 return aFactory->validate(anAttribute, aValidatorID, anError);
187 bool ModuleBase_WidgetValidated::isFilterActivated() const
189 bool isActivated = false;
191 Handle(SelectMgr_Filter) aSelFilter = myWorkshop->validatorFilter();
192 ModuleBase_IViewer* aViewer = myWorkshop->viewer();
194 return aViewer->hasSelectionFilter(aSelFilter);
197 bool ModuleBase_WidgetValidated::activateFilters(const bool toActivate)
199 ModuleBase_IViewer* aViewer = myWorkshop->viewer();
201 Handle(SelectMgr_Filter) aSelFilter = myWorkshop->validatorFilter();
202 bool aHasSelectionFilter = aViewer->hasSelectionFilter(aSelFilter);
205 aViewer->addSelectionFilter(aSelFilter);
207 aViewer->removeSelectionFilter(aSelFilter);
208 clearValidatedCash();
211 return aHasSelectionFilter;
214 //********************************************************************
215 void ModuleBase_WidgetValidated::blockAttribute(const bool& theToBlock, bool& isFlushesActived,
216 bool& isAttributeSetInitializedBlocked)
218 Events_Loop* aLoop = Events_Loop::loop();
219 DataPtr aData = myFeature->data();
220 AttributePtr anAttribute = attributeToValidate();
222 // blocks the flush signals to avoid the temporary objects visualization in the viewer
223 // they should not be shown in order to do not lose highlight by erasing them
224 isFlushesActived = aLoop->activateFlushes(false);
226 aData->blockSendAttributeUpdated(true);
227 isAttributeSetInitializedBlocked = anAttribute->blockSetInitialized(true);
230 aData->blockSendAttributeUpdated(false);
231 anAttribute->blockSetInitialized(isAttributeSetInitializedBlocked);
232 aLoop->activateFlushes(isFlushesActived);
236 //********************************************************************
237 void ModuleBase_WidgetValidated::storeValidState(const ModuleBase_ViewerPrs& theValue, const bool theValid)
239 bool aValidPrs = myInvalidPrs.contains(theValue);
240 bool anInvalidPrs = myInvalidPrs.contains(theValue);
244 myValidPrs.append(theValue);
245 // the commented code will be useful when the valid state of the presentation
246 // will be changable between activate/deactivate. Currently it does not happen.
248 // myInvalidPrs.removeOne(theValue);
252 myInvalidPrs.append(theValue);
254 // myValidPrs.removeOne(theValue);
256 #ifdef DEBUG_VALID_STATE
257 qDebug(QString("storeValidState: myValidPrs.size() = %1, myInvalidPrs.size() = %2").arg(myValidPrs.count())
258 .arg(myInvalidPrs.count()).toStdString().c_str());
262 //********************************************************************
263 bool ModuleBase_WidgetValidated::getValidState(const ModuleBase_ViewerPrs& theValue, bool& theValid)
265 bool aValidPrs = myValidPrs.contains(theValue);
266 bool anInvalidPrs = myInvalidPrs.contains(theValue);
270 else if (anInvalidPrs)
273 return aValidPrs || anInvalidPrs;
276 //********************************************************************
277 QList<ModuleBase_ViewerPrs> ModuleBase_WidgetValidated::getFilteredSelected()
279 QList<ModuleBase_ViewerPrs> aSelected = myWorkshop->selection()->getSelected(
280 ModuleBase_ISelection::Viewer);
282 QList<ModuleBase_ViewerPrs> anOBSelected = myWorkshop->selection()->getSelected(
283 ModuleBase_ISelection::Browser);
284 // filter the OB presentations
285 filterPresentations(anOBSelected);
286 if (!anOBSelected.isEmpty())
287 ModuleBase_ISelection::appendSelected(anOBSelected, aSelected);
289 filterCompSolids(aSelected);
294 //********************************************************************
295 void ModuleBase_WidgetValidated::filterPresentations(QList<ModuleBase_ViewerPrs>& theValues)
297 QList<ModuleBase_ViewerPrs> aValidatedValues;
299 QList<ModuleBase_ViewerPrs>::const_iterator anIt = theValues.begin(), aLast = theValues.end();
301 for (; anIt != aLast; anIt++) {
302 if (isValidInFilters(*anIt))
303 aValidatedValues.append(*anIt);
305 if (aValidatedValues.size() != theValues.size()) {
307 theValues = aValidatedValues;
311 //********************************************************************
312 void ModuleBase_WidgetValidated::filterCompSolids(QList<ModuleBase_ViewerPrs>& theValues)
314 std::set<ResultCompSolidPtr> aCompSolids;
315 QList<ModuleBase_ViewerPrs> aValidatedValues;
317 // Collect compsolids.
318 QList<ModuleBase_ViewerPrs>::const_iterator anIt = theValues.begin(), aLast = theValues.end();
319 for (; anIt != aLast; anIt++) {
320 const ModuleBase_ViewerPrs& aViewerPrs = *anIt;
321 ObjectPtr anObject = aViewerPrs.object();
322 ResultCompSolidPtr aResultCompSolid = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(anObject);
323 if(aResultCompSolid.get()) {
324 aCompSolids.insert(aResultCompSolid);
328 // Filter sub-solids of compsolids.
329 anIt = theValues.begin();
330 for (; anIt != aLast; anIt++) {
331 const ModuleBase_ViewerPrs& aViewerPrs = *anIt;
332 ObjectPtr anObject = aViewerPrs.object();
333 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
334 ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aResult);
335 if(aResCompSolidPtr.get() && (aCompSolids.find(aResCompSolidPtr) != aCompSolids.end())) {
336 // Skip sub-solid of compsolid.
339 aValidatedValues.append(*anIt);
343 if (aValidatedValues.size() != theValues.size()) {
345 theValues = aValidatedValues;