diff --git a/src/App/Property.cpp b/src/App/Property.cpp index 8c0efdbaf3..a14d07b29a 100644 --- a/src/App/Property.cpp +++ b/src/App/Property.cpp @@ -247,10 +247,28 @@ void Property::destroy(Property* p) } } +bool Property::enableNotify(bool enable) +{ + bool isNotify = isNotifyEnabled(); + + if (enable) { + StatusBits.reset(DisableNotify); + } + else { + StatusBits.set(DisableNotify); + } + return isNotify; +} + +bool Property::isNotifyEnabled() const +{ + return !StatusBits.test(DisableNotify); +} + void Property::touch() { PropertyCleaner guard(this); - if (father) { + if (father && isNotifyEnabled()) { father->onEarlyChange(this); father->onChanged(this); } @@ -266,7 +284,9 @@ void Property::hasSetValue() { PropertyCleaner guard(this); if (father) { - father->onChanged(this); + if (isNotifyEnabled()) { + father->onChanged(this); + } if (!testStatus(Busy)) { Base::BitsetLocker guard(StatusBits, Busy); signalChanged(*this); diff --git a/src/App/Property.h b/src/App/Property.h index 02dc8b9de9..339cdc9b85 100644 --- a/src/App/Property.h +++ b/src/App/Property.h @@ -108,6 +108,8 @@ public: CopyOnChange = 16, /// Whether the property editor should create a button for user defined editing. UserEdit = 17, + /// Do not propagate changes of the property to its container + DisableNotify = 18, // The following bits are corresponding to PropertyType set when the // property added. These types are meant to be static, and cannot be @@ -354,11 +356,16 @@ public: */ virtual void onContainerRestored() {} - /** @name Property status handling - * @{ + /** Property status handling */ - - /// Set the property touched. + //@{ + /// This method sets whether notification will be propagated on changing + /// the value of the property. The old value of the setting is returned. + bool enableNotify(bool on); + /// This method returns whether notification of changes to the property value + /// are propagated to the container. + bool isNotifyEnabled() const; + /// Set the property touched void touch(); /** diff --git a/src/Mod/PartDesign/Gui/ViewProviderBody.cpp b/src/Mod/PartDesign/Gui/ViewProviderBody.cpp index 993f8e8072..66b6c0b5f0 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderBody.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderBody.cpp @@ -263,10 +263,23 @@ void ViewProviderBody::onChanged(const App::Property* prop) { // #0002559: Body becomes visible upon changing DisplayModeBody Visibility.touch(); } - else + else { unifyVisualProperty(prop); + } + + // When changing transparency then adjust the ShapeAppearance inside onChanged() + // of the base class but don't notify its container again. This breaks the chain of + // notification and avoids the call of onChanged() with the ShapeAppearance as argument + // This fixes issue https://github.com/FreeCAD/FreeCAD/issues/18075 + if (prop == &Transparency) { + ShapeAppearance.enableNotify(false); + } PartGui::ViewProviderPartExt::onChanged(prop); + + if (prop == &Transparency) { + ShapeAppearance.enableNotify(true); + } }