App: do not auto rename new dynamic property

Instead, throw exception in case of duplicate name. Use boolean
parameter 'Preferences/Document/AutoNameDynamicProperty' to get back
the old behavior.
This commit is contained in:
Zheng, Lei
2019-10-04 11:53:34 +08:00
committed by Chris Hennes
parent 049a34645b
commit 55d64d71c2

View File

@@ -37,7 +37,7 @@
#include <Base/Exception.h>
#include <Base/Tools.h>
FC_LOG_LEVEL_INIT("DynamicProperty",true,true)
FC_LOG_LEVEL_INIT("Property",true,true)
using namespace App;
@@ -149,23 +149,45 @@ const char* DynamicProperty::getPropertyDocumentation(const char *name) const
Property* DynamicProperty::addDynamicProperty(PropertyContainer &pc, const char* type,
const char* name, const char* group, const char* doc, short attr, bool ro, bool hidden)
{
if(!type)
type = "<null>";
std::string _name;
static ParameterGrp::handle hGrp = GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Document");
if(hGrp->GetBool("AutoNameDynamicProperty",false)) {
if(!name || !name[0])
name = type;
_name = getUniquePropertyName(pc,name);
if(_name != name) {
FC_WARN(pc.getFullName() << " rename dynamic property from '"
<< name << "' to '" << _name << "'");
}
name = _name.c_str();
} else if(!name)
name = "<null>"; // setting a bad name to trigger exception
auto prop = pc.getPropertyByName(name);
if(prop && prop->getContainer()==&pc)
FC_THROWM(Base::NameError, "Property " << pc.getFullName() << '.' << name << " already exists");
if(Base::Tools::getIdentifier(name) != name)
FC_THROWM(Base::NameError, "Invalid property name '" << name << "'");
Base::BaseClass* base = static_cast<Base::BaseClass*>(Base::Type::createInstanceByName(type,true));
if (!base)
return 0;
if (!base)
FC_THROWM(Base::RuntimeError, "Failed to create property "
<< pc.getFullName() << '.' << name << " of type " << type);
if (!base->getTypeId().isDerivedFrom(Property::getClassTypeId())) {
delete base;
std::stringstream str;
str << "'" << type << "' is not a property type";
throw Base::ValueError(str.str());
FC_THROWM(Base::ValueError, "Invalid type " << type << " for property " << pc.getFullName() << '.' << name);
}
// get unique name
Property* pcProperty = static_cast<Property*>(base);
if (!name || !name[0])
name = type;
auto res = props.get<0>().emplace(pcProperty,
getUniquePropertyName(pc,name), nullptr, group, doc, attr, ro, hidden);
auto res = props.get<0>().emplace(pcProperty,name, nullptr, group, doc, attr, ro, hidden);
pcProperty->setContainer(&pc);
pcProperty->myName = res.first->name.c_str();