Toponaming: Transfer in getLinksTo
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/DocumentObserver.h>
|
||||
#include <Base/Reader.h>
|
||||
#include <Base/Tools.h>
|
||||
#include <Base/Writer.h>
|
||||
@@ -1079,3 +1080,46 @@ void PropertyExpressionEngine::onRelabeledDocument(const App::Document &doc)
|
||||
e.second.expression->visit(v);
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyExpressionEngine::getLinksTo(std::vector<App::ObjectIdentifier> &identifiers,
|
||||
App::DocumentObject *obj,
|
||||
const char *subname,
|
||||
bool all) const
|
||||
{
|
||||
Expression::DepOption option = all ? Expression::DepOption::DepAll
|
||||
: Expression::DepOption::DepNormal;
|
||||
|
||||
App::SubObjectT objT(obj, subname);
|
||||
auto sobj = objT.getSubObject();
|
||||
auto subElement = objT.getOldElementName();
|
||||
|
||||
for(auto &v : expressions) {
|
||||
const auto &deps = v.second.expression->getDeps(option);
|
||||
auto it = deps.find(obj);
|
||||
if(it==deps.end())
|
||||
continue;
|
||||
for(auto &dep : it->second) {
|
||||
if (!subname) {
|
||||
identifiers.push_back(v.first);
|
||||
break;
|
||||
}
|
||||
bool found = false;
|
||||
for (const auto &path : dep.second) {
|
||||
if (path.getSubObjectName() == subname) {
|
||||
identifiers.push_back(v.first);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
App::SubObjectT sobjT(obj, path.getSubObjectName().c_str());
|
||||
if (sobjT.getSubObject() == sobj
|
||||
&& sobjT.getOldElementName() == subElement) {
|
||||
identifiers.push_back(v.first);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,6 +160,11 @@ public:
|
||||
void afterRestore() override;
|
||||
void onContainerRestored() override;
|
||||
|
||||
virtual void getLinksTo(std::vector<App::ObjectIdentifier> &identifiers,
|
||||
App::DocumentObject *obj,
|
||||
const char *subname=nullptr,
|
||||
bool all=false) const override;
|
||||
|
||||
/* Python interface */
|
||||
PyObject *getPyObject() override;
|
||||
void setPyObject(PyObject *) override;
|
||||
|
||||
@@ -184,6 +184,19 @@ public:
|
||||
virtual void getLinks(std::vector<App::DocumentObject *> &objs,
|
||||
bool all=false, std::vector<std::string> *subs=nullptr, bool newStyle=true) const = 0;
|
||||
|
||||
/** Obtain identifiers from this link property that link to a give object
|
||||
* @param identifiers: holds the returned identifier to reference the given object
|
||||
* @param obj: the referenced object
|
||||
* @param subname: optional subname reference
|
||||
* @param all: if true, then return all the references regardless of
|
||||
* this LinkScope. If false, then return only if the LinkScope
|
||||
* is not hidden.
|
||||
*/
|
||||
virtual void getLinksTo(std::vector<App::ObjectIdentifier> &identifiers,
|
||||
App::DocumentObject *obj,
|
||||
const char *subname=nullptr,
|
||||
bool all=false) const = 0;
|
||||
|
||||
/** Called to reset this link property
|
||||
*
|
||||
* @param obj: reset link property if it is linked to this object
|
||||
@@ -631,6 +644,11 @@ public:
|
||||
void getLinks(std::vector<App::DocumentObject *> &objs,
|
||||
bool all=false, std::vector<std::string> *subs=nullptr, bool newStyle=true) const override;
|
||||
|
||||
void getLinksTo(std::vector<App::ObjectIdentifier> &identifiers,
|
||||
App::DocumentObject *obj,
|
||||
const char *subname=nullptr,
|
||||
bool all=false) const override;
|
||||
|
||||
void breakLink(App::DocumentObject *obj, bool clear) override;
|
||||
|
||||
bool adjustLink(const std::set<App::DocumentObject *> &inList) override;
|
||||
@@ -721,6 +739,11 @@ public:
|
||||
void getLinks(std::vector<App::DocumentObject *> &objs,
|
||||
bool all=false, std::vector<std::string> *subs=nullptr, bool newStyle=true) const override;
|
||||
|
||||
void getLinksTo(std::vector<App::ObjectIdentifier> &identifiers,
|
||||
App::DocumentObject *obj,
|
||||
const char *subname=nullptr,
|
||||
bool all=false) const override;
|
||||
|
||||
void breakLink(App::DocumentObject *obj, bool clear) override;
|
||||
|
||||
bool adjustLink(const std::set<App::DocumentObject *> &inList) override;
|
||||
@@ -862,6 +885,11 @@ public:
|
||||
void getLinks(std::vector<App::DocumentObject *> &objs,
|
||||
bool all=false, std::vector<std::string> *subs=nullptr, bool newStyle=true) const override;
|
||||
|
||||
void getLinksTo(std::vector<App::ObjectIdentifier> &identifiers,
|
||||
App::DocumentObject *obj,
|
||||
const char *subname=nullptr,
|
||||
bool all=false) const override;
|
||||
|
||||
void breakLink(App::DocumentObject *obj, bool clear) override;
|
||||
|
||||
bool adjustLink(const std::set<App::DocumentObject *> &inList) override;
|
||||
@@ -1009,6 +1037,11 @@ public:
|
||||
void getLinks(std::vector<App::DocumentObject *> &objs,
|
||||
bool all=false, std::vector<std::string> *subs=nullptr, bool newStyle=true) const override;
|
||||
|
||||
void getLinksTo(std::vector<App::ObjectIdentifier> &identifiers,
|
||||
App::DocumentObject *obj,
|
||||
const char *subname=nullptr,
|
||||
bool all=false) const override;
|
||||
|
||||
void breakLink(App::DocumentObject *obj, bool clear) override;
|
||||
|
||||
bool adjustLink(const std::set<App::DocumentObject *> &inList) override;
|
||||
@@ -1132,6 +1165,11 @@ public:
|
||||
void getLinks(std::vector<App::DocumentObject *> &objs,
|
||||
bool all=false, std::vector<std::string> *subs=nullptr, bool newStyle=true) const override;
|
||||
|
||||
void getLinksTo(std::vector<App::ObjectIdentifier> &identifiers,
|
||||
App::DocumentObject *obj,
|
||||
const char *subname=nullptr,
|
||||
bool all=false) const override;
|
||||
|
||||
bool adjustLink(const std::set<App::DocumentObject *> &inList) override;
|
||||
|
||||
const std::vector<std::string>& getSubValues() const {
|
||||
@@ -1302,6 +1340,11 @@ public:
|
||||
void getLinks(std::vector<App::DocumentObject *> &objs,
|
||||
bool all=false, std::vector<std::string> *subs=nullptr, bool newStyle=true) const override;
|
||||
|
||||
void getLinksTo(std::vector<App::ObjectIdentifier> &identifiers,
|
||||
App::DocumentObject *obj,
|
||||
const char *subname=nullptr,
|
||||
bool all=false) const override;
|
||||
|
||||
void breakLink(App::DocumentObject *obj, bool clear) override;
|
||||
|
||||
bool adjustLink(const std::set<App::DocumentObject *> &inList) override;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <Base/Writer.h>
|
||||
|
||||
#include "PropertyGeometryList.h"
|
||||
#include "GeometryMigrationExtension.h"
|
||||
#include "GeometryPy.h"
|
||||
#include "Part2DObject.h"
|
||||
|
||||
@@ -84,26 +85,55 @@ void PropertyGeometryList::setValue(const Geometry* lValue)
|
||||
void PropertyGeometryList::setValues(const std::vector<Geometry*>& lValue)
|
||||
{
|
||||
auto copy = lValue;
|
||||
for(auto &geo : copy) // copy of the individual geometry pointers
|
||||
geo = geo->clone();
|
||||
|
||||
setValues(std::move(copy));
|
||||
// for(auto &geo : copy) // copy of the individual geometry pointers
|
||||
// geo = geo->clone();
|
||||
//
|
||||
// setValues(std::move(copy));
|
||||
aboutToSetValue();
|
||||
std::sort(_lValueList.begin(), _lValueList.end());
|
||||
for (auto &v : copy) {
|
||||
auto range = std::equal_range(_lValueList.begin(), _lValueList.end(), v);
|
||||
// clone if the new entry does not exist in the original value list, or
|
||||
// else, simply reuse it (i.e. erase it so that it won't get deleted below).
|
||||
if (range.first == range.second)
|
||||
v = v->clone();
|
||||
else
|
||||
_lValueList.erase(range.first, range.second);
|
||||
}
|
||||
for (auto v : _lValueList)
|
||||
delete v;
|
||||
_lValueList = std::move(copy);
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
void PropertyGeometryList::setValues(std::vector<Geometry*> &&lValue)
|
||||
{
|
||||
// aboutToSetValue();
|
||||
// std::set<Geometry*> valueSet(_lValueList.begin(),_lValueList.end());
|
||||
// for(auto v : lValue)
|
||||
// valueSet.erase(v);
|
||||
// _lValueList = std::move(lValue);
|
||||
// for(auto v : valueSet)
|
||||
// delete v;
|
||||
// hasSetValue();
|
||||
// Unlike above, the moved version of setValues() indicates the caller want
|
||||
// us to manager the memory of the passed in values. So no need clone.
|
||||
aboutToSetValue();
|
||||
std::set<Geometry*> valueSet(_lValueList.begin(),_lValueList.end());
|
||||
for(auto v : lValue)
|
||||
valueSet.erase(v);
|
||||
_lValueList = std::move(lValue);
|
||||
for(auto v : valueSet)
|
||||
std::sort(_lValueList.begin(), _lValueList.end());
|
||||
for (auto v : lValue) {
|
||||
auto range = std::equal_range(_lValueList.begin(), _lValueList.end(), v);
|
||||
_lValueList.erase(range.first, range.second);
|
||||
}
|
||||
for (auto v : _lValueList)
|
||||
delete v;
|
||||
_lValueList = std::move(lValue);
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
void PropertyGeometryList::set1Value(int idx, std::unique_ptr<Geometry> &&lValue)
|
||||
{
|
||||
if (!lValue)
|
||||
return;
|
||||
if(idx>=(int)_lValueList.size())
|
||||
throw Base::IndexError("Index out of bound");
|
||||
aboutToSetValue();
|
||||
@@ -171,6 +201,12 @@ void PropertyGeometryList::trySaveGeometry(Geometry * geom, Base::Writer &writer
|
||||
// Not all geometry classes implement Save() and throw an exception instead
|
||||
try {
|
||||
geom->Save(writer);
|
||||
for( auto &e : geom->getExtensions() ) {
|
||||
auto ext = e.lock();
|
||||
auto gpe = freecad_dynamic_cast<GeometryMigrationPersistenceExtension>(ext.get());
|
||||
if (gpe)
|
||||
gpe->postSave(writer);
|
||||
}
|
||||
}
|
||||
catch (const Base::NotImplementedError& e) {
|
||||
Base::Console().Warning(std::string("PropertyGeometryList"), "Not yet implemented: %s\n", e.what());
|
||||
@@ -181,6 +217,17 @@ void PropertyGeometryList::tryRestoreGeometry(Geometry * geom, Base::XMLReader &
|
||||
{
|
||||
// Not all geometry classes implement Restore() and throw an exception instead
|
||||
try {
|
||||
if (!reader.getAttributeAsInteger("migrated") && reader.hasAttribute("id")) {
|
||||
auto ext = std::make_unique<GeometryMigrationExtension>();
|
||||
ext->setId(reader.getAttributeAsInteger("id"));
|
||||
if(reader.hasAttribute("ref")) {
|
||||
const char *ref = reader.getAttribute("ref");
|
||||
int index = reader.getAttributeAsInteger("refIndex");
|
||||
unsigned long flags = (unsigned long)reader.getAttributeAsUnsigned("flags");
|
||||
ext->setReference(ref, index, flags);
|
||||
}
|
||||
geom->setExtension(std::move(ext));
|
||||
}
|
||||
geom->Restore(reader);
|
||||
}
|
||||
catch (const Base::NotImplementedError& e) {
|
||||
@@ -193,8 +240,16 @@ void PropertyGeometryList::Save(Writer &writer) const
|
||||
writer.Stream() << writer.ind() << "<GeometryList count=\"" << getSize() <<"\">" << endl;
|
||||
writer.incInd();
|
||||
for (int i = 0; i < getSize(); i++) {
|
||||
writer.Stream() << writer.ind() << "<Geometry type=\""
|
||||
<< _lValueList[i]->getTypeId().getName() << "\">" << endl;;
|
||||
writer.Stream() << writer.ind() << "<Geometry type=\""
|
||||
<< _lValueList[i]->getTypeId().getName() << "\"";
|
||||
for( auto &e : _lValueList[i]->getExtensions() ) {
|
||||
auto ext = e.lock();
|
||||
auto gpe = freecad_dynamic_cast<GeometryMigrationPersistenceExtension>(ext.get());
|
||||
if (gpe)
|
||||
gpe->preSave(writer);
|
||||
}
|
||||
writer.Stream() << " migrated=\"1\">\n";
|
||||
|
||||
writer.incInd();
|
||||
trySaveGeometry(_lValueList[i], writer);
|
||||
writer.decInd();
|
||||
@@ -263,3 +318,10 @@ unsigned int PropertyGeometryList::getMemSize() const
|
||||
size += _lValueList[i]->getMemSize();
|
||||
return size;
|
||||
}
|
||||
|
||||
void PropertyGeometryList::moveValues(PropertyGeometryList &&other)
|
||||
{
|
||||
setValues(std::move(other._lValueList));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -64,8 +64,10 @@ public:
|
||||
void setValues(const std::vector<Geometry*>&);
|
||||
void setValues(std::vector<Geometry*>&&);
|
||||
|
||||
void moveValues(PropertyGeometryList &&other);
|
||||
|
||||
/// index operator
|
||||
const Geometry *operator[] (const int idx) const {
|
||||
Geometry *operator[] (const int idx) const {
|
||||
return _lValueList[idx];
|
||||
}
|
||||
|
||||
|
||||
@@ -303,8 +303,14 @@ void PropertyPartShape::Save (Base::Writer &writer) const
|
||||
writer.Stream() << " file=\""
|
||||
<< writer.addFile(getFileName(binary?".bin":".brp").c_str(), this)
|
||||
<< "\"/>\n";
|
||||
} else if(binary) {
|
||||
writer.Stream() << " binary=\"1\">\n";
|
||||
_Shape.exportBinary(writer.beginCharStream(Base::CharStreamFormat::Base64Encoded));
|
||||
writer.endCharStream() << writer.ind() << "</Part>\n";
|
||||
} else {
|
||||
writer.Stream() << "/>\n";
|
||||
writer.Stream() << " brep=\"1\">\n";
|
||||
_Shape.exportBrep(writer.beginCharStream(Base::CharStreamFormat::Raw)<<'\n');
|
||||
writer.endCharStream() << '\n' << writer.ind() << "</Part>\n";
|
||||
}
|
||||
|
||||
if(_SaveHasher) {
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/DocumentObserver.h>
|
||||
#include <App/Expression.h>
|
||||
#include <App/ExpressionParser.h>
|
||||
#include <App/ExpressionVisitors.h>
|
||||
@@ -2267,3 +2268,50 @@ bool PropertySheet::hasSpan() const
|
||||
{
|
||||
return !mergedCells.empty();
|
||||
}
|
||||
|
||||
void PropertySheet::getLinksTo(std::vector<App::ObjectIdentifier>& identifiers,
|
||||
App::DocumentObject* obj,
|
||||
const char* subname,
|
||||
bool all) const
|
||||
{
|
||||
Expression::DepOption option =
|
||||
all ? Expression::DepOption::DepAll : Expression::DepOption::DepNormal;
|
||||
|
||||
App::SubObjectT objT(obj, subname);
|
||||
auto sobj = objT.getSubObject();
|
||||
auto subElement = objT.getOldElementName();
|
||||
|
||||
auto owner = Base::freecad_dynamic_cast<App::DocumentObject>(getContainer());
|
||||
for (const auto& v : data) {
|
||||
if (auto expr = v.second->getExpression()) {
|
||||
const auto& deps = expr->getDeps(option);
|
||||
auto it = deps.find(obj);
|
||||
if (it == deps.end()) {
|
||||
continue;
|
||||
}
|
||||
for (auto& dep : it->second) {
|
||||
if (!subname) {
|
||||
identifiers.emplace_back(owner, v.first.toString().c_str());
|
||||
break;
|
||||
}
|
||||
bool found = false;
|
||||
for (const auto& path : dep.second) {
|
||||
if (path.getSubObjectName() == subname) {
|
||||
identifiers.emplace_back(owner, v.first.toString().c_str());
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
App::SubObjectT sobjT(obj, path.getSubObjectName().c_str());
|
||||
if (sobjT.getSubObject() == sobj && sobjT.getOldElementName() == subElement) {
|
||||
identifiers.emplace_back(owner, v.first.toString().c_str());
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,11 @@ public:
|
||||
|
||||
void Restore(Base::XMLReader& reader) override;
|
||||
|
||||
virtual void getLinksTo(std::vector<App::ObjectIdentifier>& identifiers,
|
||||
App::DocumentObject* obj,
|
||||
const char* subname = nullptr,
|
||||
bool all = false) const override;
|
||||
|
||||
void copyCells(Base::Writer& writer, const std::vector<App::Range>& ranges) const;
|
||||
|
||||
void pasteCells(Base::XMLReader& reader, App::Range dstRange);
|
||||
|
||||
Reference in New Issue
Block a user