Gui: [skip ci] allow to unbind() an ExpressionBinding and automatically unbind it if the observed object has been deleted

For more details see: https://forum.freecadweb.org/viewtopic.php?f=8&t=56097
This commit is contained in:
wmayer
2021-02-28 12:37:50 +01:00
parent 2599d67c2b
commit 957eed7d2c
2 changed files with 27 additions and 5 deletions

View File

@@ -59,6 +59,13 @@ bool ExpressionBinding::isBound() const
return path.getDocumentObject() != 0;
}
void ExpressionBinding::unbind()
{
expressionchanged.disconnect();
objectdeleted.disconnect();
path = App::ObjectIdentifier();
}
void Gui::ExpressionBinding::setExpression(boost::shared_ptr<Expression> expr)
{
DocumentObject * docObj = path.getDocumentObject();
@@ -100,7 +107,11 @@ void ExpressionBinding::bind(const App::ObjectIdentifier &_path)
//connect to be informed about changes
DocumentObject * docObj = path.getDocumentObject();
connection = docObj->ExpressionEngine.expressionChanged.connect(boost::bind(&ExpressionBinding::expressionChange, this, bp::_1));
if (docObj) {
expressionchanged = docObj->ExpressionEngine.expressionChanged.connect(boost::bind(&ExpressionBinding::expressionChange, this, bp::_1));
App::Document* doc = docObj->getDocument();
objectdeleted = doc->signalDeletedObject.connect(boost::bind(&ExpressionBinding::objectDeleted, this, bp::_1));
}
}
void ExpressionBinding::bind(const Property &prop)
@@ -247,3 +258,11 @@ void ExpressionBinding::expressionChange(const ObjectIdentifier& id) {
if(id==path)
onChange();
}
void ExpressionBinding::objectDeleted(const App::DocumentObject& obj)
{
DocumentObject * docObj = path.getDocumentObject();
if (docObj == &obj) {
unbind();
}
}

View File

@@ -44,6 +44,7 @@ public:
virtual void bind(const App::ObjectIdentifier & _path);
virtual void bind(const App::Property & prop);
bool isBound() const;
void unbind();
virtual bool apply(const std::string &propName);
virtual bool apply();
bool hasExpression() const;
@@ -52,8 +53,8 @@ public:
//auto apply means that the python code is issued not only on apply() but
//also on setExpression
bool autoApply() const {return m_autoApply;};
void setAutoApply(bool value) {m_autoApply = value;};
bool autoApply() const {return m_autoApply;}
void setAutoApply(bool value) {m_autoApply = value;}
protected:
const App::ObjectIdentifier & getPath() const { return path; }
@@ -63,7 +64,7 @@ protected:
virtual void setExpression(boost::shared_ptr<App::Expression> expr);
//gets called when the bound expression is changed, either by this binding or any external action
virtual void onChange() {};
virtual void onChange() {}
private:
App::ObjectIdentifier path;
@@ -75,7 +76,9 @@ protected:
int iconHeight;
void expressionChange(const App::ObjectIdentifier& id);
boost::signals2::scoped_connection connection;
void objectDeleted(const App::DocumentObject&);
boost::signals2::scoped_connection expressionchanged;
boost::signals2::scoped_connection objectdeleted;
bool m_autoApply;
};