App: allow multiple subname in PropertyXLink

PropertyXLink and PropertyXLinkSub now only differ in getPyObject().
This is to allow Link support of multiple sub-element
This commit is contained in:
Zheng, Lei
2019-09-01 19:39:41 +08:00
committed by wmayer
parent a03b847507
commit 4042d83362
2 changed files with 52 additions and 115 deletions

View File

@@ -2826,11 +2826,11 @@ void PropertyXLink::setSubName(const char *subname)
if(subname && subname[0])
subs.emplace_back(subname);
aboutToSetValue();
_setSubValues(std::move(subs));
setSubValues(std::move(subs));
hasSetValue();
}
void PropertyXLink::_setSubValues(std::vector<std::string> &&subs,
void PropertyXLink::setSubValues(std::vector<std::string> &&subs,
std::vector<ShadowSub> &&shadows)
{
_SubList = std::move(subs);
@@ -2851,7 +2851,7 @@ void PropertyXLink::setValue(App::DocumentObject * lValue, const char *subname)
std::vector<std::string> subs;
if(subname && subname[0])
subs.emplace_back(subname);
_setValue(lValue,std::move(subs));
setValue(lValue,std::move(subs));
}
void PropertyXLink::restoreLink(App::DocumentObject *lValue) {
@@ -2884,7 +2884,7 @@ void PropertyXLink::restoreLink(App::DocumentObject *lValue) {
}
}
void PropertyXLink::_setValue(App::DocumentObject *lValue,
void PropertyXLink::setValue(App::DocumentObject *lValue,
std::vector<std::string> &&subs, std::vector<ShadowSub> &&shadows)
{
if(_pcLink==lValue && _SubList==subs)
@@ -2938,15 +2938,15 @@ void PropertyXLink::_setValue(App::DocumentObject *lValue,
if(docInfo && docInfo->pcDoc)
stamp=docInfo->pcDoc->LastModifiedDate.getValue();
objectName = std::move(name);
_setSubValues(std::move(subs),std::move(shadows));
setSubValues(std::move(subs),std::move(shadows));
hasSetValue();
}
void PropertyXLink::_setValue(std::string &&filename, std::string &&name,
void PropertyXLink::setValue(std::string &&filename, std::string &&name,
std::vector<std::string> &&subs, std::vector<ShadowSub> &&shadows)
{
if(name.empty()) {
_setValue(0,std::move(subs),std::move(shadows));
setValue(0,std::move(subs),std::move(shadows));
return;
}
auto owner = dynamic_cast<DocumentObject*>(getContainer());
@@ -2963,7 +2963,7 @@ void PropertyXLink::_setValue(std::string &&filename, std::string &&name,
pObject = owner->getDocument()->getObject(name.c_str());
if(pObject) {
_setValue(pObject,std::move(subs),std::move(shadows));
setValue(pObject,std::move(subs),std::move(shadows));
return;
}
setFlag(LinkDetached,false);
@@ -2980,10 +2980,16 @@ void PropertyXLink::_setValue(std::string &&filename, std::string &&name,
if(docInfo && docInfo->pcDoc)
stamp=docInfo->pcDoc->LastModifiedDate.getValue();
objectName = std::move(name);
_setSubValues(std::move(subs),std::move(shadows));
setSubValues(std::move(subs),std::move(shadows));
hasSetValue();
}
void PropertyXLink::setValue(App::DocumentObject *link,
const std::vector<std::string> &subs, std::vector<ShadowSub> &&shadows)
{
setValue(link,std::vector<std::string>(subs),std::move(shadows));
}
App::Document *PropertyXLink::getDocument() const {
return docInfo?docInfo->pcDoc:0;
}
@@ -3258,9 +3264,9 @@ void PropertyXLink::Restore(Base::XMLReader &reader)
if(file.size() || (!object && name.size())) {
this->stamp = stamp;
_setValue(std::move(file),std::move(name),std::move(subs),std::move(shadows));
setValue(std::move(file),std::move(name),std::move(subs),std::move(shadows));
}else
_setValue(object,std::move(subs),std::move(shadows));
setValue(object,std::move(subs),std::move(shadows));
_mapped = std::move(mapped);
}
@@ -3356,9 +3362,9 @@ void PropertyXLink::Paste(const Property &from)
FC_WARN("Object '" << other.docName << '#' << other.objectName << "' not found");
return;
}
_setValue(obj,std::vector<std::string>(other._SubList));
setValue(obj,std::vector<std::string>(other._SubList));
} else
_setValue(std::string(other.filePath),std::string(other.objectName),
setValue(std::string(other.filePath),std::string(other.objectName),
std::vector<std::string>(other._SubList));
setFlag(LinkAllowPartial,other.testFlag(LinkAllowPartial));
}
@@ -3446,33 +3452,35 @@ void PropertyXLink::setPyObject(PyObject *value) {
Py::Sequence seq(value);
if(seq.size()!=2)
throw Base::ValueError("Expect input sequence of size 2");
std::string subname;
PyObject *pyObj = seq[0].ptr();
PyObject *pySub = seq[1].ptr();
if(pyObj == Py_None) {
std::vector<std::string> subs;
Py::Object pyObj(seq[0].ptr());
Py::Object pySub(seq[1].ptr());
if(pyObj.isNone()) {
setValue(0);
return;
} else if(!PyObject_TypeCheck(pyObj, &DocumentObjectPy::Type))
} else if(!PyObject_TypeCheck(pyObj.ptr(), &DocumentObjectPy::Type))
throw Base::TypeError("Expect the first element to be of 'DocumentObject'");
if (PyUnicode_Check(pySub)) {
#if PY_MAJOR_VERSION >= 3
subname = PyUnicode_AsUTF8(pySub);
#else
PyObject* unicode = PyUnicode_AsUTF8String(pySub);
subname = PyString_AsString(unicode);
Py_DECREF(unicode);
}else if (PyString_Check(pySub)) {
subname = PyString_AsString(pySub);
#endif
if(pySub.isString())
subs.push_back(pySub.as_string());
else if(pySub.isSequence()) {
Py::Sequence seq(pySub);
subs.reserve(seq.size());
for(size_t i=0;i<seq.size();++i) {
Py::Object sub(seq[i]);
if(!sub.isString())
throw Base::TypeError("Expect only string inside second argument");
subs.push_back(sub.as_string());
}
}else
throw Base::TypeError("Expect the second element to be a string");
setValue(static_cast<DocumentObjectPy*>(pyObj)->getDocumentObjectPtr(), subname.c_str());
throw Base::TypeError("Expect the second element to be a string or sequence of string");
setValue(static_cast<DocumentObjectPy*>(pyObj.ptr())->getDocumentObjectPtr(), std::move(subs));
} else if(PyObject_TypeCheck(value, &(DocumentObjectPy::Type))) {
setValue(static_cast<DocumentObjectPy*>(value)->getDocumentObjectPtr());
} else if (Py_None == value) {
setValue(0);
} else {
throw Base::TypeError("type must be 'DocumentObject', 'None', or '(DocumentObject, SubName)");
throw Base::TypeError("type must be 'DocumentObject', 'None', or '(DocumentObject, SubName)' or "
"'DocumentObject, [SubName..])");
}
}
@@ -3501,7 +3509,7 @@ bool PropertyXLink::adjustLink(const std::set<App::DocumentObject*> &inList) {
auto subs = _SubList;
auto link = adjustLinkSubs(this,inList,_pcLink,subs);
if(link) {
_setValue(link,std::move(subs));
setValue(link,std::move(subs));
return true;
}
return false;
@@ -3560,26 +3568,6 @@ PropertyXLinkSub::PropertyXLinkSub(bool allowPartial, PropertyLinkBase *parent)
PropertyXLinkSub::~PropertyXLinkSub() {
}
void PropertyXLinkSub::setValue(App::DocumentObject *link,
const std::vector<std::string> &subs, std::vector<ShadowSub> &&shadows)
{
_setValue(link,std::vector<std::string>(subs),std::move(shadows));
}
void PropertyXLinkSub::setValue(App::DocumentObject *link,
std::vector<std::string> &&subs, std::vector<ShadowSub> &&shadows)
{
_setValue(link,std::move(subs),std::move(shadows));
}
void PropertyXLinkSub::setSubValues(std::vector<std::string> &&subs,
std::vector<ShadowSub> &&shadows)
{
aboutToSetValue();
_setSubValues(std::move(subs),std::move(shadows));
hasSetValue();
}
PropertyXLink *PropertyXLinkSub::createInstance() const{
return new PropertyXLinkSub();
}
@@ -3615,43 +3603,6 @@ PyObject *PropertyXLinkSub::getPyObject(void)
return Py::new_reference_to(tup);
}
void PropertyXLinkSub::setPyObject(PyObject *value) {
if(PySequence_Check(value)) {
Py::Sequence seq(value);
if(seq.size()!=2)
throw Base::ValueError("Expect input sequence of size 2");
std::vector<std::string> subs;
Py::Object pyObj(seq[0].ptr());
Py::Object pySub(seq[1].ptr());
if(pyObj.isNone()) {
setValue(0);
return;
} else if(!PyObject_TypeCheck(pyObj.ptr(), &DocumentObjectPy::Type))
throw Base::TypeError("Expect the first element to be of 'DocumentObject'");
if(pySub.isString())
subs.push_back(pySub.as_string());
else if(pySub.isSequence()) {
Py::Sequence seq(pySub);
subs.reserve(seq.size());
for(size_t i=0;i<seq.size();++i) {
Py::Object sub(seq[i]);
if(!sub.isString())
throw Base::TypeError("Expect only string inside second argument");
subs.push_back(sub.as_string());
}
}else
throw Base::TypeError("Expect the second element to be a string or sequence of string");
setValue(static_cast<DocumentObjectPy*>(pyObj.ptr())->getDocumentObjectPtr(), std::move(subs));
} else if(PyObject_TypeCheck(value, &(DocumentObjectPy::Type))) {
setValue(static_cast<DocumentObjectPy*>(value)->getDocumentObjectPtr());
} else if (Py_None == value) {
setValue(0);
} else {
throw Base::TypeError("type must be 'DocumentObject', 'None', or '(DocumentObject, SubName)' or "
"'DocumentObject, [SubName..])");
}
}
//**************************************************************************
// PropertyXLinkSubList
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

View File

@@ -1055,6 +1055,18 @@ public:
void setValue(App::DocumentObject *) override;
void setValue(App::DocumentObject *, const char *subname);
void setValue(std::string &&filePath, std::string &&objectName, std::vector<std::string> &&SubList,
std::vector<ShadowSub> &&ShadowSubList = {});
void setValue(App::DocumentObject *,std::vector<std::string> &&SubList,
std::vector<ShadowSub> &&ShadowSubList = {});
void setValue(App::DocumentObject *,const std::vector<std::string> &SubList,
std::vector<ShadowSub > &&ShadowSubList={});
void setSubValues(std::vector<std::string> &&SubList,
std::vector<ShadowSub> &&ShadowSubList = {});
const char *getSubName(bool newStyle=true) const;
void setSubName(const char *subname);
@@ -1102,11 +1114,6 @@ public:
virtual bool adjustLink(const std::set<App::DocumentObject *> &inList) override;
// The following APIs are provided to be compatible with PropertyLinkSub.
// Note that although PropertyXLink is capable of holding multiple subnames,
// there no public APIs allowing user to set more that one subname. Multiple
// subname adding API is published in PropertyXLinkSub.
const std::vector<std::string>& getSubValues(void) const {
return _SubList;
}
@@ -1124,15 +1131,6 @@ protected:
void restoreLink(App::DocumentObject *);
void _setSubValues(std::vector<std::string> &&SubList,
std::vector<ShadowSub> &&ShadowSubList = {});
void _setValue(std::string &&filePath, std::string &&objectName, std::vector<std::string> &&SubList,
std::vector<ShadowSub> &&ShadowSubList = {});
void _setValue(App::DocumentObject *,std::vector<std::string> &&SubList,
std::vector<ShadowSub> &&ShadowSubList = {});
virtual PropertyXLink *createInstance() const;
virtual bool upgrade(Base::XMLReader &reader, const char *typeName);
@@ -1168,21 +1166,9 @@ public:
virtual ~PropertyXLinkSub();
using PropertyXLink::setValue;
void setValue(App::DocumentObject *,const std::vector<std::string> &SubList,
std::vector<ShadowSub > &&ShadowSubList={});
void setValue(App::DocumentObject *,std::vector<std::string> &&SubList,
std::vector<ShadowSub > &&ShadowSubList={});
void setSubValues(std::vector<std::string> &&SubList,
std::vector<ShadowSub> &&ShadowSubList={});
virtual bool upgrade(Base::XMLReader &reader, const char *typeName) override;
virtual PyObject *getPyObject(void) override;
virtual void setPyObject(PyObject *) override;
protected:
virtual PropertyXLink *createInstance() const override;