App: change PropertyContainer::Restore()

Changes the way PropertyContainer handles existing property while
restoring. Previously it will first ask DynamicProperty to restore
if possible, then fallback to static property if else.

This patch looks up existing property first, and only fallback to
DynamicProperty if not found. This handles situation when an object
changes an originally dynamic property into a static one. With the
original code, it will add an auto renamed dynamic property that no
one knows its existence.
This commit is contained in:
Zheng, Lei
2020-02-05 20:01:32 +08:00
committed by Chris Hennes
parent 789d32f87b
commit e3cbc9fcfc

View File

@@ -332,21 +332,21 @@ void PropertyContainer::Restore(Base::XMLReader &reader)
reader.readElement("Property");
std::string PropName = reader.getAttribute("name");
std::string TypeName = reader.getAttribute("type");
auto prop = dynamicProps.restore(*this,PropName.c_str(),TypeName.c_str(),reader);
if(!prop)
prop = getPropertyByName(PropName.c_str());
decltype(Property::StatusBits) status;
if(reader.hasAttribute("status")) {
status = decltype(status)(reader.getAttributeAsUnsigned("status"));
if(prop)
prop->setStatusValue(status.to_ulong());
}
// NOTE: We must also check the type of the current property because a
// subclass of PropertyContainer might change the type of a property but
// not its name. In this case we would force to read-in a wrong property
// type and the behaviour would be undefined.
try {
auto prop = getPropertyByName(PropName.c_str());
if(!prop)
prop = dynamicProps.restore(*this,PropName.c_str(),TypeName.c_str(),reader);
decltype(Property::StatusBits) status;
if(reader.hasAttribute("status")) {
status = decltype(status)(reader.getAttributeAsUnsigned("status"));
if(prop)
prop->setStatusValue(status.to_ulong());
}
// name and type match
if (prop && strcmp(prop->getTypeId().getName(), TypeName.c_str()) == 0) {
if (!prop->testStatus(Property::Transient)