App/Toponaming: import SubObjectT dependencies for SubShapeBinder

* Added SubObjectT methods normalize(), normalized(), hasSubObject() and hasSubElement()
 * Updated DocumentObject::getSubObjectList()
 * Applied modifications to make the code compile
This commit is contained in:
Zheng, Lei
2024-04-06 09:59:23 +02:00
committed by Chris Hennes
parent db22476450
commit 138417c2a2
4 changed files with 188 additions and 5 deletions

View File

@@ -30,6 +30,7 @@
#include "Document.h"
#include "DocumentObserver.h"
#include "GeoFeature.h"
#include "Link.h"
using namespace App;
namespace sp = std::placeholders;
@@ -341,6 +342,79 @@ bool SubObjectT::operator==(const SubObjectT &other) const {
&& subname == other.subname;
}
bool SubObjectT::normalize(NormalizeOptions options)
{
bool noElement = options.testFlag(NormalizeOption::NoElement);
bool flatten = !options.testFlag(NormalizeOption::NoFlatten);
bool keepSub = options.testFlag(NormalizeOption::KeepSubName);
bool convertIndex = options.testFlag(NormalizeOption::ConvertIndex);
std::ostringstream ss;
std::vector<int> subs;
auto obj = getObject();
if(!obj)
return false;
auto objs = obj->getSubObjectList(subname.c_str(), &subs, flatten);
if (objs.empty())
return false;
for (unsigned i=1; i<objs.size(); ++i) {
// Keep digit only subname, as it maybe an index to an array, which does
// not expand its elements as objects.
const char *end = subname.c_str() + subs[i];
const char *sub = end - 2;
for(;;--sub) {
if (sub < subname.c_str()) {
sub = subname.c_str();
break;
}
if (*sub == '.') {
++sub;
break;
}
}
bool _keepSub;
if (!std::isdigit(sub[0]))
_keepSub = keepSub;
else if (!convertIndex)
_keepSub = true;
else {
_keepSub = false;
if (auto ext = objs[i-1]->getExtensionByType<LinkBaseExtension>(true)) {
if (ext->getElementCountValue() && !ext->getShowElementValue()) {
// if the parent is a collapsed link array element, then we
// have to keep the index no matter what, because there is
// no sub-object corresponding to an array element.
_keepSub = true;
}
}
}
if (_keepSub)
ss << std::string(sub, end);
else
ss << objs[i]->getNameInDocument() << ".";
}
if (objs.size() > 1 && objs.front()->getSubObject(ss.str().c_str()) != objs.back()) {
// something went wrong
return false;
}
if (!noElement)
ss << getOldElementName();
std::string sub = ss.str();
if (objs.front() != obj || subname != sub) {
*this = objs.front();
subname = std::move(sub);
return true;
}
return false;
}
SubObjectT App::SubObjectT::normalized(NormalizeOptions options) const
{
SubObjectT res(*this);
res.normalize(options);
return res;
}
void SubObjectT::setSubName(const char *s) {
subname = s?s:"";
}
@@ -357,6 +431,15 @@ const char *SubObjectT::getElementName() const {
return Data::findElementName(subname.c_str());
}
bool SubObjectT::hasSubObject() const {
return Data::findElementName(subname.c_str()) != subname.c_str();
}
bool SubObjectT::hasSubElement() const {
auto element = getElementName();
return element && element[0];
}
std::string SubObjectT::getNewElementName() const {
std::pair<std::string, std::string> element;
auto obj = getObject();